import 'dotenv/config' import grpc from "grpc" import express from "express" import bodyParser from "body-parser" import basicAuth from "express-basic-auth" import { CommandService_v1Client as CommandService, QueryService_v1Client as QueryService } from 'iroha-helpers/lib/proto/endpoint_grpc_pb' import { queries } from 'iroha-helpers' const app = express(); app.use(bodyParser.json()); app.use(basicAuth({ users: { admin: 'superPasswd' }, challenge: true })); const IROHA_ADMIN_PRIV = "f101537e319568c765b2cc89698325604991dca57b9716b58016b253506cab70"; const IROHA_ADMIN = "admin@test"; const IROHA_ADDRESS = "localhost:50051"; const commandService = new CommandService(IROHA_ADDRESS, grpc.credentials.createInsecure()); const queryService = new QueryService(IROHA_ADDRESS, grpc.credentials.createInsecure()); const CHAIN4ALL_SERVICE_PORT = process.env.CHAIN4ALL_SERVICE_PORT || 3000; const IROHA_API_HOST = process.env.IROHA_API_HOST || "http://localhost"; const IROHA_API_PORT = process.env.IROHA_API_PORT || 5000; const IROHA_DOMAIN = process.env.IROHA_DOMAIN || "test"; const IROHA_ASSET = process.env.IROHA_ASSET || "coin"; const DATA_OWNER = process.env.DATA_OWNER || "admin" const PRICE_MODIFIER: number = parseFloat(process.env.PRICE_MODIFIER || "0.5"); app.get("/", (req, res) => { res.send("Chain4All Blockchain service"); }); app.post("/price", (req, res) => { if (req.body && req.body.extent) { res.send({ price: getPrice(req.body.extent) }); } else { res.status(400); throw Error(JSON.stringify({ error: { name: "Error, request has no body with \"extent\" property!" } })); } }); app.post("/buy", async (req, res, next) => { try { if (!req.body) { res.status(400); throw Error(JSON.stringify({ error: { name: "Error, request has no body!" } })); } if (!req.body.txHash) { res.status(400); throw Error(JSON.stringify({ error: { name: "Error, request body has no \"txHash\" property!" } })); } //TODO load from http headers, or something like that?? if (!req.body.user) { res.status(400); throw Error(JSON.stringify({ error: { name: "Error, request body has no \"user\" property!" } })); } let txDetail = await getTransactionDetail(req.body.txHash, req.body.user); res.send(txDetail); } catch (err) { next(err); } }); async function getTransactionDetail(txHash: string, user: string) { let quer: any = await queries.getAccountTransactions({ privateKey: IROHA_ADMIN_PRIV, creatorAccountId: 'admin@test', queryService, timeoutLimit: 5000 }, { accountId: user, pageSize: 10, firstTxHash: txHash, ordering: { field: undefined, direction: undefined }, firstTxTime: undefined, lastTxTime: undefined, firstTxHeight: 1, lastTxHeight: 3 }); //TODO find better way to look for transferAssets command in transaction return quer.transactionsList[0].payload.reducedPayload.commandsList[0].transferAsset; } function getArea(extent: Array>): number { let y1 = extent[0][1]; let y4 = extent[3][1]; let x1 = extent[0][0]; let x2 = extent[1][0]; let height = Math.abs(y1 - y4); let width = Math.abs(x1 - x2); return height * width; } function getPrice(extent: Array>): number { return getArea(extent) * PRICE_MODIFIER; } function errorMiddleware(err: any, req: any, res: any, next: any): void { //TODO: add custom Exception class console.log(err); res.status(500); res.send(err.message); } app.use(errorMiddleware); app.listen(CHAIN4ALL_SERVICE_PORT, () => { console.log(`Listening at http://localhost:${CHAIN4ALL_SERVICE_PORT}`) });