keycard-redeem/scripts/relay.js

98 lines
2.8 KiB
JavaScript
Raw Permalink Normal View History

2020-05-13 14:39:52 +00:00
const express = require('express');
const Web3 = require('web3');
const parseArgs = require('minimist');
const Account = require('./account.js');
const utils = require('./utils.js');
2020-05-14 10:14:16 +00:00
const fs = require('fs');
2020-05-25 12:15:19 +00:00
const morgan = require("morgan");
2020-05-13 14:39:52 +00:00
2020-05-14 10:39:26 +00:00
const argv = parseArgs(process.argv.slice(2), {string: ["sender", "bucket"], default: {"endpoint": "ws://127.0.0.1:8546"}});
2020-05-13 14:39:52 +00:00
const web3 = new Web3(argv["endpoint"]);
const account = new Account(web3);
const Bucket = utils.loadContract(web3, "Bucket");
2020-05-13 14:39:52 +00:00
2020-05-25 12:15:19 +00:00
const port = process.env.PORT || 3000;
2020-05-13 14:39:52 +00:00
const app = express();
2020-05-25 12:15:19 +00:00
app.use(morgan('combined'))
2020-05-25 12:38:19 +00:00
async function redeem(bucket, message, sig) {
2020-05-13 14:39:52 +00:00
Bucket.transactionConfirmationBlocks = 1;
Bucket.options.address = bucket;
2020-05-14 08:13:36 +00:00
let methodCall = Bucket.methods.redeem(message, sig);
2020-05-13 14:39:52 +00:00
return account.sendMethod(methodCall, Bucket.options.address);
}
2020-05-14 10:14:16 +00:00
function validateAddress(addr) {
return addr != null && addr.startsWith("0x") && addr.length == 42;
}
function validate32Bytes(data) {
return data != null && data.startsWith("0x") && data.length == 66;
}
function validateNumber(num) {
return !isNaN(parseInt(num));
}
async function validateBucket(bucket) {
Bucket.options.address = bucket;
const owner = await Bucket.methods.owner().call();
return account.address() === owner;
2020-05-14 10:14:16 +00:00
}
async function validateRequest(body) {
2020-05-14 10:14:16 +00:00
if (!validateAddress(body.bucket)) {
return "invalid bucket address";
} else if (!await validateBucket(body.bucket)) {
return "invalid bucket owner";
2020-05-25 12:15:19 +00:00
} else if (body.message === undefined) {
return "message must be specified";
2020-05-14 10:14:16 +00:00
} else if (!validateNumber(body.message.blockNumber)) {
return "invalid block number";
} else if (!validate32Bytes(body.message.blockHash)) {
return "invalid block hash";
} else if (!validateAddress(body.message.receiver)) {
return "invalid receiver address";
} else if (!validate32Bytes(body.message.code)) {
return "invalid code";
} else {
return null;
}
}
2020-05-25 12:15:19 +00:00
async function redeemOptions(req, res) {
res.append("Access-Control-Allow-Origin", ["*"]);
res.append("Access-Control-Allow-Headers", ["*"]);
res.json({message: "ok"})
}
2020-05-13 14:39:52 +00:00
async function redeemRequest(req, res) {
2020-05-25 12:15:19 +00:00
res.append("Access-Control-Allow-Origin", ["*"]);
res.append("Access-Control-Allow-Headers", ["*"]);
2020-05-14 10:14:16 +00:00
let err = await validateRequest(req.body);
2020-05-14 10:14:16 +00:00
if (err) {
res.status(400).json({error: err});
}
try {
let receipt = await redeem(req.body.bucket, req.body.message, req.body.sig);
res.json({tx: receipt.transactionHash});
} catch(e) {
2020-05-25 12:15:19 +00:00
console.error(e)
2020-05-14 10:14:16 +00:00
res.status(500).json({error: "Couldn't send tx"});
}
}
2020-05-13 14:39:52 +00:00
async function run() {
await account.init(argv);
2020-05-14 10:14:16 +00:00
2020-05-13 14:39:52 +00:00
app.use(express.json());
app.post('/redeem', redeemRequest);
2020-05-25 12:15:19 +00:00
app.options('/redeem', redeemOptions);
2020-05-13 14:39:52 +00:00
app.listen(port, () => console.log(`Relayer listening at http://localhost:${port}`));
}
2020-05-25 12:15:19 +00:00
run();