app.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. import 'dotenv/config'
  2. import fetch from "node-fetch"
  3. import express from "express"
  4. import bodyParser from "body-parser"
  5. const app = express();
  6. app.use(bodyParser.json());
  7. const CHAIN4ALL_SERVICE_PORT = process.env.CHAIN4ALL_SERVICE_PORT || 3000;
  8. const IROHA_API_HOST = process.env.IROHA_API_HOST || "http://localhost";
  9. const IROHA_API_PORT = process.env.IROHA_API_PORT || 5000;
  10. const IROHA_DOMAIN = process.env.IROHA_DOMAIN || "test";
  11. const IROHA_ASSET = process.env.IROHA_ASSET || "coin";
  12. const DATA_OWNER = process.env.DATA_OWNER || "admin"
  13. const PRICE_MODIFIER = process.env.PRICE_MODIFIER || 0.5;
  14. app.get("/", (req, res) => {
  15. res.send("Chain4All Blockchain service");
  16. });
  17. app.post("/price", (req, res) => {
  18. if (req.body && req.body.extent) {
  19. res.send({ price: getPrice(req.body.extent) });
  20. }
  21. else {
  22. res.status(400);
  23. throw Error(JSON.stringify({ error: { name: "Error, request has no body with \"extent\" property!" } }));
  24. }
  25. });
  26. app.get("/users/:userId/assets", async (req, res, next) => {
  27. try {
  28. let irohaResponse = await fetchUsersAssets(req.params.userId);
  29. res.status(irohaResponse.status);
  30. if (irohaResponse.headers.get("content-length") < 1) {
  31. res.send();
  32. }
  33. else {
  34. res.send(await irohaResponse.json());
  35. }
  36. }
  37. catch (err) {
  38. next(err);
  39. }
  40. });
  41. app.get("/users/:userId/assets/:assetId", async (req, res, next) => {
  42. try {
  43. let irohaResponse = await fetchUsersAssets(req.params.userId);
  44. let irohaResponseJson = await irohaResponse.json();
  45. let assets = irohaResponseJson.assets;
  46. let parsedAssetName = "";
  47. let i = 0;
  48. for (i; i < assets.length; i++) {
  49. parsedAssetName = assets[i].assetId.split('#')[0];
  50. if (parsedAssetName === req.params.assetId) {
  51. res.status(200);
  52. res.send(assets[i]);
  53. return;
  54. }
  55. }
  56. res.status(204);
  57. res.send();
  58. } catch (err) {
  59. next(err);
  60. }
  61. });
  62. app.post("/buy", async (req, res, next) => {
  63. try {
  64. if (!req.body) {
  65. res.status(400);
  66. throw Error(JSON.stringify({ error: { name: "Error, request has no body!" } }));
  67. }
  68. if (!req.body.extent) {
  69. res.status(400);
  70. throw Error(JSON.stringify({ error: { name: "Error, request body has no \"extent\" property!" } }));
  71. }
  72. if (!req.body.user) {
  73. res.status(400);
  74. throw Error(JSON.stringify({ error: { name: "Error, request body has no \"user\" property!" } }));
  75. }
  76. if (!req.body.privateKey) {
  77. res.status(400);
  78. throw Error(JSON.stringify({ error: { name: "Error, user must provide \"privateKey\" to sign transaction!" } }));
  79. }
  80. let price = getPrice(req.body.extent);
  81. // let irohaResponse = await forwardBuyRequest(
  82. // {
  83. // privateKey: req.body.privateKey,
  84. // transfers: [
  85. // {
  86. // asset: IROHA_ASSET + "#" + IROHA_DOMAIN,
  87. // source: req.body.user + "@" + IROHA_DOMAIN,
  88. // destination: DATA_OWNER + "@" + IROHA_DOMAIN,
  89. // description: "test", //TODO: compose uniform description
  90. // amount: price
  91. // }
  92. // ]
  93. // }
  94. // );
  95. let data = "https://gis.lesprojekt.cz/chain4all/raster_112233.tif"; //TODO implement data extraction
  96. // res.status(irohaResponse.status);
  97. // if (!irohaResponse.ok) {
  98. // res.send(await irohaResponse.json());
  99. // return;
  100. // }
  101. // let irohaResponseJson = await irohaResponse.json();
  102. res.send({
  103. dataUrl: data,
  104. transactionHash: "91edf4700823a82ee8f57889cb620094cd1f5bb68d1273b093b17d128e62a590"//irohaResponseJson.transactionHash
  105. });
  106. }
  107. catch (err) {
  108. next(err);
  109. }
  110. });
  111. async function forwardBuyRequest(body) {
  112. return await fetch(IROHA_API_HOST + ':' + IROHA_API_PORT + '/assets/transfer/',
  113. {
  114. method: 'POST',
  115. body: JSON.stringify(body),
  116. headers: { 'Content-Type': 'application/json' }
  117. }
  118. );
  119. }
  120. async function fetchUsersAssets(userId) {
  121. return await fetch(IROHA_API_HOST + ':' + IROHA_API_PORT + '/accounts/' + userId + '@' + IROHA_DOMAIN + '/assets/');
  122. }
  123. function getArea(extent) {
  124. let y1 = extent[0][1];
  125. let y4 = extent[3][1];
  126. let x1 = extent[0][0];
  127. let x2 = extent[1][0];
  128. let height = Math.abs(y1 - y4);
  129. let width = Math.abs(x1 - x2);
  130. return height * width;
  131. }
  132. function getPrice(extent) {
  133. return getArea(extent) * PRICE_MODIFIER;
  134. }
  135. function error(err, req, res, next) { //TODO: add custom Exception class
  136. console.log(err);
  137. res.status(500);
  138. res.send(err.message);
  139. }
  140. app.use(error);
  141. app.listen(CHAIN4ALL_SERVICE_PORT, () => {
  142. console.log(`Listening at http://localhost:${CHAIN4ALL_SERVICE_PORT}`)
  143. });