diff --git a/Makefile b/Makefile index f5fa919..a57682a 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ ifndef BUCKET endif run-relayer: check-relayer-env-variables - node scripts/relay.js \ + env PORT=$(PORT) node scripts/relay.js \ --endpoint=$(ENDPOINT) \ --account=$(KEYSTORES_PATH)/keystore.json \ --passfile=$(KEYSTORES_PATH)/keystore-passfile.txt \ diff --git a/scripts/README.md b/scripts/README.md index 34e3036..1d10307 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -81,10 +81,6 @@ The options are `--passfile`: the path to a file storing the password for the JSON encoded private key. Always used with --account. -`--bucket-list`: a file containing a list of bucket addresses one per line. Only transactions to these addresses will be accepted - -`--bucket`: same as above, but instead a single address is provided on the command line directly. - ### HTTP interface The http interface is very simple diff --git a/scripts/account.js b/scripts/account.js index b1f5c0f..b93e300 100644 --- a/scripts/account.js +++ b/scripts/account.js @@ -28,6 +28,9 @@ module.exports = class Account { return accounts[0]; } + address() { + return this.sender.address; + } loadAccount(account, passfile) { let json = fs.readFileSync(account, "utf-8"); diff --git a/scripts/create-redeemable.js b/scripts/create-redeemable.js index 8989ae5..9e34b7c 100644 --- a/scripts/create-redeemable.js +++ b/scripts/create-redeemable.js @@ -183,11 +183,15 @@ async function run() { const decimals = await getDecimals(argv["amount-decimals"], !argv["nft"]); let file = fs.readFileSync(argv["file"], 'utf8'); - keycards = file.split("\n").filter(line => line.trim() !== "").map((line) => processLine(line, decimals)); + keycards = file + .split("\n") + .filter(line => line.trim() !== "" && !/^#/.test(line.trim())) + .map((line) => processLine(line, decimals)); for (let keycard of keycards) { const create = argv["nft"] ? transferNFT : createRedeemable; await create(keycard); + console.log(`http://test-pn.keycard.cash/redeem/#/buckets/${bucket}/redeemables/${keycard.keycard}`) } } else if (!hasDoneSomething) { console.error("the --file option must be specified"); diff --git a/scripts/relay.js b/scripts/relay.js index e393abd..2f88e7e 100644 --- a/scripts/relay.js +++ b/scripts/relay.js @@ -16,8 +16,6 @@ const port = process.env.PORT || 3000; const app = express(); app.use(morgan('combined')) -let allowedBuckets = []; - async function redeem(bucket, message, sig) { Bucket.transactionConfirmationBlocks = 1; Bucket.options.address = bucket; @@ -37,15 +35,17 @@ function validateNumber(num) { return !isNaN(parseInt(num)); } -function validateBucket(bucket) { - return allowedBuckets.includes(bucket.toLowerCase()); +async function validateBucket(bucket) { + Bucket.options.address = bucket; + const owner = await Bucket.methods.owner().call(); + return account.address() === owner; } -function validateRequest(body) { +async function validateRequest(body) { if (!validateAddress(body.bucket)) { return "invalid bucket address"; - } else if (!validateBucket(body.bucket)) { - return "cannot send to this bucket"; + } else if (!await validateBucket(body.bucket)) { + return "invalid bucket owner"; } else if (body.message === undefined) { return "message must be specified"; } else if (!validateNumber(body.message.blockNumber)) { @@ -71,7 +71,7 @@ async function redeemRequest(req, res) { res.append("Access-Control-Allow-Origin", ["*"]); res.append("Access-Control-Allow-Headers", ["*"]); - let err = validateRequest(req.body); + let err = await validateRequest(req.body); if (err) { res.status(400).json({error: err}); } @@ -85,53 +85,12 @@ async function redeemRequest(req, res) { } } -function bucketRequest(req, res) { - if (validateBucket(req.params.address)) { - res.status(200).json({"allowed": true}); - } else { - res.status(404).json({"allowed": false}); - } -} - -function loadBucketList(path) { - let file = fs.readFileSync(path, 'utf8'); - allowedBuckets = file.split("\n").map((line) => line.toLowerCase().trim()); -} - -function checkBuckets() { - allowedBuckets = allowedBuckets.filter((line) => { - if (validateAddress(line)) { - return true; - } else { - console.warn(`${line} is an invalid bucket address, ignored`); - return false; - } - }); - - if (allowedBuckets.length == 0) { - console.error("no valid buckets, exiting"); - process.exit(1); - } -} - async function run() { - if (argv["bucket-list"]) { - loadBucketList(argv["bucket-list"]); - } else if (argv["bucket"]) { - allowedBuckets = [argv["bucket"].toLowerCase()]; - } else { - console.error("the either the --bucket or --bucket-list option must be specified"); - process.exit(1); - } - - checkBuckets(); - await account.init(argv); app.use(express.json()); app.post('/redeem', redeemRequest); app.options('/redeem', redeemOptions); - app.get('/bucket/:address', bucketRequest); app.listen(port, () => console.log(`Relayer listening at http://localhost:${port}`)); }