SenShaMart/wallet/wallet-app.js

287 lines
No EOL
7.1 KiB
JavaScript

//WALLET
const express = require('express');
const bodyParser = require('body-parser');
const P2pServer = require('../p2p-server');
const N3 = require('n3');
const Wallet = require('./wallet');
const Config = require('../config');
const ChainUtil = require('../chain-util');
const QueryEngine = require('@comunica/query-sparql-rdfjs').QueryEngine;
const Blockchain = require('../blockchain/blockchain');
const {
DEFAULT_PORT_WALLET_API,
DEFAULT_PORT_WALLET_CHAIN,
DEFAULT_PORT_MINER_CHAIN
} = require('../constants');
'use strict';
const CONFIGS_STORAGE_LOCATION = "./settings.json";
const config = new Config(CONFIGS_STORAGE_LOCATION);
const wallet = new Wallet(config.get({
key: "wallet-keypair",
default: ChainUtil.genKeyPair(),
transform: ChainUtil.deserializeKeyPair
}));
const apiPort = config.get({
key: "wallet-api-port",
default: DEFAULT_PORT_WALLET_API
});
const blockchainLocation = config.get({
key: "wallet-blockchain-location",
default: "./wallet_blockchain.json"
});
const chainServerPort = config.get({
key: "wallet-chain-server-port",
default: DEFAULT_PORT_WALLET_CHAIN
});
const chainServerPeers = config.get({
key: "wallet-chain-server-peers",
default: ["ws://127.0.0.1:" + DEFAULT_PORT_MINER_CHAIN]
});
const blockchain = Blockchain.loadFromDisk(blockchainLocation);
function onChainServerRecv(data) {
const replaceResult = blockchain.replaceChain(Blockchain.deserialize(data));
if (!replaceResult.result) {
console.log(`Failed to replace chain: ${replaceResult.reason}`);
//failed to replace
return;
}
blockchain.saveToDisk(blockchainLocation);
}
const chainServer = new P2pServer("Chain-server");
chainServer.start(chainServerPort, chainServerPeers, (_) => { }, onChainServerRecv);
const app = express();
app.use(bodyParser.json());
app.listen(apiPort, () => console.log(`Listening on port ${apiPort}`));
app.get('/ChainServer/sockets', (req, res) => {
res.json(chainServer.sockets);
});
app.post('/ChainServer/connect', (req, res) => {
chainServer.connect(req.body.url);
res.json("Connecting");
});
app.get('/public-key', (req, res) => {
res.json(wallet.publicKey);
});
app.get('/key-pair', (req, res) => {
res.json(ChainUtil.serializeKeyPair(wallet.keyPair));
});
app.get('/MyBalance', (req, res) => {
res.json(blockchain.getBalanceCopy(wallet.publicKey));
});
app.get('/Balance', (req, res) => {
const balance = blockchain.getBalanceCopy(req.body.publicKey);
res.json(balance);
});
app.get('/Balances', (req, res) => {
const balances = blockchain.balances;
res.json(balances);
});
app.post('/Payment', (req, res) => {
res.json(wallet.createPayment(
req.body.rewardAmount,
req.body.outputs,
blockchain));
});
app.post('/Integration', (req, res) => {
res.json(wallet.createIntegration(
req.body.rewardAmount,
req.body.outputs,
blockchain));
});
function extToRdf(triples, sensorId, parentString, obj) {
for (const key in obj) {
const value = obj[key];
const type = typeof value;
switch (typeof value) {
case "string":
triples.push({
s: sensorId,
p: parentString + key,
o: value
});
break;
case "object":
extToRdf(triples, sensorId, parentString + key + '/', value);
break;
default:
console.log("Unsupported value type: " + type);
break;
}
}
}
const brokerRegistrationValidators = {
ssnMetadata: ChainUtil.validateIsString,
rewardAmount: ChainUtil.createValidateIsIntegerWithMin(0),
extMetadata: ChainUtil.validateIsObject
};
app.post('/BrokerRegistration', (req, res) => {
const validateRes = ChainUtil.validateObject(req.body, brokerRegistrationValidators);
if (!validateRes.result) {
res.json(validateRes.reason);
return;
}
const brokers = [];
const triples = [];
const parser = new N3.Parser();
parser.parse(
req.body.ssnMetadata,
(error, quad, prefixes) => {
if (error) {
res.json(error);
return;
}
if (quad) {
triples.push({
s: quad.subject.id,
p: quad.predicate.id,
o: quad.object.id
});
if (quad.predicate.id === "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
&& quad.object.id === "SSM/Broker") {
brokers.push(quad.subject.id);
}
return;
}
//quad is null, we come here, and we are finished parsing
if (brokers.length === 0) {
res.json("Couldn't find a defined broker");
return;
} else if (brokers.length > 1) {
res.json("Found multiple defined brokers");
return;
}
extToRdf(triples, brokers[0], "", req.body.extMetadata);
try {
res.json(wallet.createBrokerRegistration(
triples,
req.body.rewardAmount,
blockchain));
} catch (err) {
console.log(err);
res.json(err.message);
}
});
});
const sensorRegistrationValidators = {
ssnMetadata: ChainUtil.validateIsString,
rewardAmount: ChainUtil.createValidateIsIntegerWithMin(0),
extMetadata: ChainUtil.validateIsObject
};
app.post('/SensorRegistration', (req, res) => {
const validateRes = ChainUtil.validateObject(req.body, sensorRegistrationValidators);
if (!validateRes.result) {
res.json(validateRes.reason);
return;
}
const sensors = [];
const triples = [];
const parser = new N3.Parser();
parser.parse(
req.body.ssnMetadata,
(error, quad, prefixes) => {
if (error) {
res.json(error);
return;
}
if (quad) {
triples.push({
s: quad.subject.id,
p: quad.predicate.id,
o: quad.object.id
});
if (quad.predicate.id === "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
&& quad.object.id === "http://www.w3.org/ns/sosa/Sensor") {
sensors.push(quad.subject.id);
}
return;
}
//quad is null, we come here, and we are finished parsing
if (sensors.length === 0) {
res.json("Couldn't find a defined sensor");
return;
} else if (sensors.length > 1) {
res.json("Found multiple defined sensors");
return;
}
extToRdf(triples, sensors[0], "", req.body.extMetadata);
try {
res.json(wallet.createSensorRegistration(
triples,
req.body.rewardAmount,
blockchain));
} catch (err) {
console.log(err);
res.json(err.message);
}
});
});
const myEngine = new QueryEngine();
app.post('/sparql', (req, res) => {
const start = async function () {
try {
let result = [];
const bindingsStream = await myEngine.queryBindings(
req.body.query,
{
readOnly: true,
sources: blockchain.stores
});
bindingsStream.on('data', (binding) => {
result.push(binding);
});
bindingsStream.on('end', () => {
res.json(JSON.stringify(result));
});
bindingsStream.on('error', (err) => {
console.error(err);
});
} catch (err) {
console.error(err);
res.json("Error occured while querying");
}
};
start()
});