import 'dotenv/config' import fetch from "node-fetch" import express from "express" import bodyParser from "body-parser" const app = express(); app.use(bodyParser.json()); 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 = 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.get("/users/:userId/assets", async (req, res) => { let irohaResponse = await fetchUsersAssets(req.params.userId); res.status(irohaResponse.status); if (irohaResponse.headers.get("content-length") < 1) { res.send(); } else { res.send(await irohaResponse.json()); } }); app.get("/users/:userId/assets/:assetId", async (req, res) => { let assets = (await fetchUsersAssets(req.params.userId)).assets; let parsedAssetName = ""; let i = 0; for (i; i < assets.length; i++) { parsedAssetName = assets[i].assetId.split('#')[0]; if (parsedAssetName === req.params.assetId) { res.status(200); res.send(assets[i]); return; } } res.status(204); res.send(); }); app.post("/buy", async (req, res) => { if (!req.body) { res.status(400); throw Error(JSON.stringify({ error: { name: "Error, request has no body!" } })); } if (!req.body.extent) { res.status(400); throw Error(JSON.stringify({ error: { name: "Error, request body has no \"extent\" property!" } })); } if (!req.body.user) { res.status(400); throw Error(JSON.stringify({ error: { name: "Error, request body has no \"user\" property!" } })); } let price = getPrice(req.body.extent); let irohaResponse = await forwardBuyRequest( { transfers: [ { asset: IROHA_ASSET + "#" + IROHA_DOMAIN, source: req.body.user + "@" + IROHA_DOMAIN, destination: DATA_OWNER + "@" + IROHA_DOMAIN, description: "test", //TODO: compose uniform description amount: price } ] } ); let data = "test - to be implemented"; //TODO implement data extraction res.status(irohaResponse.status); if(!irohaResponse.ok){ res.send(irohaResponse); } let irohaResponseJson = await irohaResponse.json(); console.log("tx hash: " + irohaResponseJson.transactionHash); res.send({ data : data, transactionHash : irohaResponseJson.transactionHash }); }); async function forwardBuyRequest(body) { return await fetch(IROHA_API_HOST + ':' + IROHA_API_PORT + '/assets/transfer/', { method: 'POST', body: JSON.stringify(body), headers: { 'Content-Type': 'application/json' } } ); } async function fetchUsersAssets(userId) { return await fetch(IROHA_API_HOST + ':' + IROHA_API_PORT + '/accounts/' + userId + '@' + IROHA_DOMAIN + '/assets/'); } function getArea(extent) { 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) { return getArea(extent) * PRICE_MODIFIER; } function error(err, req, res, next) { //TODO: add custom Exception class console.log(err); if (!res.status) { res.status(500); } res.send(err.message); } app.use(error); app.listen(CHAIN4ALL_SERVICE_PORT, () => { console.log(`Listening at http://localhost:${CHAIN4ALL_SERVICE_PORT}`) });