diff --git a/config.js b/config.js index d8deff1..e5a96d3 100644 --- a/config.js +++ b/config.js @@ -4,6 +4,7 @@ module.exports = { netId: Number(process.env.NET_ID) || 42, rpcUrl: process.env.RPC_URL || 'https://kovan.infura.io/v3/a3f4d001c1fc4a359ea70dd27fd9cb51', privateKey: process.env.PRIVATE_KEY, + nonce: 0, mixers: { netId1: { dai: { diff --git a/src/Fetcher.js b/src/Fetcher.js index fba18bb..00d0546 100644 --- a/src/Fetcher.js +++ b/src/Fetcher.js @@ -3,6 +3,7 @@ const fetch = require('node-fetch') const { toWei } = require('web3-utils') const { gasOracleUrls, defaultGasPrice } = require('../config') const { getMainnetTokens } = require('./utils') +const config = require ('../config') class Fetcher { @@ -62,6 +63,9 @@ class Fetcher { setTimeout(() => this.fetchGasPrice({ oracleIndex }), 15000) } } + async fetchNonce() { + config.nonce = await this.web3.eth.getTransactionCount(this.web3.eth.defaultAccount) + } } module.exports = Fetcher diff --git a/src/index.js b/src/index.js index b22179d..f505d50 100644 --- a/src/index.js +++ b/src/index.js @@ -39,6 +39,7 @@ app.listen(port || 8000) console.log('Gas price oracle started.') fetcher.fetchGasPrice() fetcher.fetchPrices() +fetcher.fetchNonce() console.log('Relayer started on port', port || 8000) console.log(`relayerAddress: ${web3.eth.defaultAccount}`) diff --git a/src/relayController.js b/src/relayController.js index 70b9f1f..3f88ae6 100644 --- a/src/relayController.js +++ b/src/relayController.js @@ -1,8 +1,9 @@ const { numberToHex, toWei, toHex, toBN, toChecksumAddress } = require('web3-utils') -const mixerABI = require('../abis/mixerABI.json') +const mixerABI = require('../abis/mixerABI.json') const { isValidProof, isValidArgs, isKnownContract, isEnoughFee } = require('./utils') +const config = require('../config') const { web3, fetcher } = require('./instances') @@ -57,16 +58,7 @@ async function relay (req, resp) { return resp.status(400).json({ error: 'The merkle root is too old or invalid.' }) } - const withdrawArgs = [ - proof, - root, - nullifierHash, - recipient, - relayer, - fee.toString(), - refund.toString() - ] - let gas = await mixer.methods.withdraw(...withdrawArgs).estimateGas({ + let gas = await mixer.methods.withdraw(proof, ...args).estimateGas({ from: web3.eth.defaultAccount, value: refund }) @@ -79,22 +71,31 @@ async function relay (req, resp) { return resp.status(400).json({ error: reason }) } - const result = mixer.methods.withdraw(...withdrawArgs).send({ + const data = mixer.methods.withdraw(proof, ...args).encodeABI() + const tx = { from: web3.eth.defaultAccount, - value: refund, + value: numberToHex(refund), gas: numberToHex(gas), gasPrice: toHex(toWei(gasPrices.fast.toString(), 'gwei')), - // TODO: nonce - }) + to: mixer._address, + netId: config.netId, + data, + nonce: config.nonce + } + config.nonce++ + let signedTx = await web3.eth.accounts.signTransaction(tx, config.privateKey) + let result = web3.eth.sendSignedTransaction(signedTx.rawTransaction) + result.once('transactionHash', function(txHash){ resp.json({ txHash }) - console.log(`A new successfuly sent tx ${txHash} for the ${recipient}`) + console.log(`A new successfully sent tx ${txHash} for the ${recipient}`) }).on('error', function(e){ + config.nonce-- console.log(e) return resp.status(400).json({ error: 'Proof is malformed.' }) }) } catch (e) { - console.error(e.message, 'estimate gas failed') + console.error(e, 'estimate gas failed') return resp.status(400).json({ error: 'Proof is malformed or spent.' }) } }