From 647b867af2166634d09a4992f2dae22a9de554d3 Mon Sep 17 00:00:00 2001 From: Michael Feng Date: Thu, 12 Nov 2020 16:07:53 -0800 Subject: [PATCH 1/6] (feat) fixes #2557: makes ETH routes non Balancer specific --- src/index.js | 4 ++-- src/routes/eth.route.js | 29 ++++++++--------------------- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/src/index.js b/src/index.js index 3ded6f3..ab5b30d 100644 --- a/src/index.js +++ b/src/index.js @@ -19,7 +19,7 @@ if (result.error) { const env = process.env.NODE_ENV const port = process.env.PORT const certPassphrase = process.env.CERT_PASSPHRASE -const balancerNetwork = process.env.BALANCER_NETWORK +const ethereumChain = process.env.BALANCER_NETWORK let certPath = process.env.CERT_PATH if ((typeof certPath === 'undefined' && certPath == null) || certPath === '') { @@ -79,4 +79,4 @@ server.listen(port) server.on('error', onError) server.on('listening', onListening) -console.log('server: gateway-api | port:', port, '| balancer-network:', balancerNetwork); +console.log('server: gateway-api | port:', port, '| ethereum-chain:', ethereumChain); diff --git a/src/routes/eth.route.js b/src/routes/eth.route.js index 4208e13..4c378d2 100644 --- a/src/routes/eth.route.js +++ b/src/routes/eth.route.js @@ -1,15 +1,12 @@ -import BigNumber from 'bignumber.js'; import { ethers } from 'ethers'; import express from 'express'; import { getParamData, latency, reportConnectionError, statusMessages } from '../services/utils'; import Ethereum from '../services/eth'; -import Balancer from '../services/balancer'; const router = express.Router() const eth = new Ethereum(process.env.BALANCER_NETWORK) -const balancer = new Balancer(process.env.BALANCER_NETWORK) -const seperator = ',' +const separator = ',' const debug = require('debug')('router') @@ -38,7 +35,7 @@ router.post('/balances', async (req, res) => { } let tokenAddressList if (paramData.tokenAddressList) { - tokenAddressList = paramData.tokenAddressList.split(seperator) + tokenAddressList = paramData.tokenAddressList.split(separator) } debug(tokenAddressList) @@ -72,6 +69,7 @@ router.post('/allowances', async (req, res) => { x-www-form-urlencoded: { privateKey:{{privateKey}} tokenAddressList:{{tokenAddressList}} + spenderAddress:"0x....." } */ const initTime = Date.now() @@ -89,12 +87,12 @@ router.post('/allowances', async (req, res) => { }) return } - const spender = balancer.exchangeProxy let tokenAddressList if (paramData.tokenAddressList) { - tokenAddressList = paramData.tokenAddressList.split(seperator) + tokenAddressList = paramData.tokenAddressList.split(separator) } debug(tokenAddressList) + const spender = paramData.spenderAddress const approvals = {} try { @@ -125,13 +123,13 @@ router.post('/approve', async (req, res) => { /* POST: /approve x-www-form-urlencoded: { - tokenAddress:"0x....." privateKey:{{privateKey}} + tokenAddress:"0x....." + spenderAddress:"0x....." amount:{{amount}} } */ const initTime = Date.now() - // params: privateKey (required), tokenAddress (required), amount (optional), gasPrice (required) const paramData = getParamData(req.body) const privateKey = paramData.privateKey let wallet @@ -147,7 +145,7 @@ router.post('/approve', async (req, res) => { return } const tokenAddress = paramData.tokenAddress - const spender = balancer.exchangeProxy + const spender = paramData.spenderAddress let amount paramData.amount ? amount = ethers.utils.parseEther(paramData.amount) : amount = ethers.utils.parseEther('1000000000') // approve for 1 billion units if no amount specified @@ -191,7 +189,6 @@ router.post('/get-weth', async (req, res) => { } */ const initTime = Date.now() - // params: primaryKey (required), amount (required), gasPrice (optional) const paramData = getParamData(req.body) const privateKey = paramData.privateKey let wallet @@ -232,16 +229,6 @@ router.post('/get-weth', async (req, res) => { message: err }) } - - // When Balancer gives us the faucet ABI, we can use this faucet to get all Kovan tokens - // const contract = new ethers.Contract(abi.KovanFaucetAddress, abi.KovanFaucetAbi, provider) - // contract.drip(wallet.address, tokenAddress).then((response) => { - // res.status(200).json({ - // network: network, - // timestamp: initTime, - // result: response - // }) - // }) }) module.exports = router; From 991f0201013ca0ae9771c3038e4ce101e0e8a152 Mon Sep 17 00:00:00 2001 From: Michael Feng Date: Sun, 15 Nov 2020 19:55:54 -0800 Subject: [PATCH 2/6] (fix) add approve and allowances to balancer routes --- src/routes/balancer.route.js | 114 +++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/src/routes/balancer.route.js b/src/routes/balancer.route.js index 8880861..4a1ef10 100644 --- a/src/routes/balancer.route.js +++ b/src/routes/balancer.route.js @@ -16,6 +16,7 @@ const eth = new Ethereum(process.env.BALANCER_NETWORK) const denomMultiplier = 1e18 const swapMoreThanMaxPriceError = 'Swap price exceeds maxPrice' const swapLessThanMaxPriceError = 'Swap price lower than maxPrice' +const separator = ',' router.use((req, res, next) => { const cert = req.connection.getPeerCertificate() @@ -313,4 +314,117 @@ router.post('/buy', async (req, res) => { } }) +router.post('/allowances', async (req, res) => { + /* + POST: /allowances + x-www-form-urlencoded: { + privateKey:{{privateKey}} + tokenAddressList:{{tokenAddressList}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + let wallet + try { + wallet = new ethers.Wallet(privateKey, eth.provider) + } catch (err) { + let reason + err.reason ? reason = err.reason : reason = 'Error getting wallet' + res.status(500).json({ + error: reason, + message: err + }) + return + } + let tokenAddressList + if (paramData.tokenAddressList) { + tokenAddressList = paramData.tokenAddressList.split(separator) + } + debug(tokenAddressList) + const spender = balancer.exchangeProxy + + const approvals = {} + try { + Promise.all( + tokenAddressList.map(async (key) => + approvals[key] = await eth.getERC20Allowance(wallet, spender, key) + )).then(() => { + res.status(200).json({ + network: eth.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + spender: spender, + approvals: approvals, + }) + } + ) + } catch (err) { + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/approve', async (req, res) => { + /* + POST: /approve + x-www-form-urlencoded: { + privateKey:{{privateKey}} + tokenAddress:"0x....." + amount:{{amount}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + let wallet + try { + wallet = new ethers.Wallet(privateKey, eth.provider) + } catch (err) { + let reason + err.reason ? reason = err.reason : reason = 'Error getting wallet' + res.status(500).json({ + error: reason, + message: err + }) + return + } + const tokenAddress = paramData.tokenAddress + const spender = balancer.exchangeProxy + let amount + paramData.amount ? amount = ethers.utils.parseEther(paramData.amount) + : amount = ethers.utils.parseEther('1000000000') // approve for 1 billion units if no amount specified + let gasPrice + if (paramData.gasPrice) { + gasPrice = parseFloat(paramData.gasPrice) + } + + try { + // call approve function + const approval = await eth.approveERC20(wallet, spender, tokenAddress, amount, gasPrice) + + // submit response + res.status(200).json({ + network: eth.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + tokenAddress: tokenAddress, + spender: spender, + amount: amount / 1e18.toString(), + approval: approval + }) + } catch (err) { + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + export default router; From 32f886304464146a3b158f754d723b94f1ec8441 Mon Sep 17 00:00:00 2001 From: vic-en Date: Wed, 18 Nov 2020 14:30:26 +0100 Subject: [PATCH 3/6] (cleanup) remove additions to balancer.routes --- src/routes/balancer.route.js | 116 +---------------------------------- 1 file changed, 1 insertion(+), 115 deletions(-) diff --git a/src/routes/balancer.route.js b/src/routes/balancer.route.js index 4a1ef10..593d7ee 100644 --- a/src/routes/balancer.route.js +++ b/src/routes/balancer.route.js @@ -16,7 +16,6 @@ const eth = new Ethereum(process.env.BALANCER_NETWORK) const denomMultiplier = 1e18 const swapMoreThanMaxPriceError = 'Swap price exceeds maxPrice' const swapLessThanMaxPriceError = 'Swap price lower than maxPrice' -const separator = ',' router.use((req, res, next) => { const cert = req.connection.getPeerCertificate() @@ -187,7 +186,7 @@ router.post('/sell', async (req, res) => { amount, ) - const price = expectedOut / amount + const price = expectedOut / amount debug(`Price: ${price.toString()}`) if (!maxPrice || price >= maxPrice) { // pass swaps to exchange-proxy to complete trade @@ -314,117 +313,4 @@ router.post('/buy', async (req, res) => { } }) -router.post('/allowances', async (req, res) => { - /* - POST: /allowances - x-www-form-urlencoded: { - privateKey:{{privateKey}} - tokenAddressList:{{tokenAddressList}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet - try { - wallet = new ethers.Wallet(privateKey, eth.provider) - } catch (err) { - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' - res.status(500).json({ - error: reason, - message: err - }) - return - } - let tokenAddressList - if (paramData.tokenAddressList) { - tokenAddressList = paramData.tokenAddressList.split(separator) - } - debug(tokenAddressList) - const spender = balancer.exchangeProxy - - const approvals = {} - try { - Promise.all( - tokenAddressList.map(async (key) => - approvals[key] = await eth.getERC20Allowance(wallet, spender, key) - )).then(() => { - res.status(200).json({ - network: eth.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - spender: spender, - approvals: approvals, - }) - } - ) - } catch (err) { - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.post('/approve', async (req, res) => { - /* - POST: /approve - x-www-form-urlencoded: { - privateKey:{{privateKey}} - tokenAddress:"0x....." - amount:{{amount}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet - try { - wallet = new ethers.Wallet(privateKey, eth.provider) - } catch (err) { - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' - res.status(500).json({ - error: reason, - message: err - }) - return - } - const tokenAddress = paramData.tokenAddress - const spender = balancer.exchangeProxy - let amount - paramData.amount ? amount = ethers.utils.parseEther(paramData.amount) - : amount = ethers.utils.parseEther('1000000000') // approve for 1 billion units if no amount specified - let gasPrice - if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) - } - - try { - // call approve function - const approval = await eth.approveERC20(wallet, spender, tokenAddress, amount, gasPrice) - - // submit response - res.status(200).json({ - network: eth.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - tokenAddress: tokenAddress, - spender: spender, - amount: amount / 1e18.toString(), - approval: approval - }) - } catch (err) { - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - export default router; From 90ddf3b6194c52e61740d855e09f556970160093 Mon Sep 17 00:00:00 2001 From: vic-en Date: Wed, 18 Nov 2020 14:42:39 +0100 Subject: [PATCH 4/6] (feat) rename BALANCER_NETWORK to ETHEREUM_CHAIN and make eth routes none balancer specific --- src/index.js | 2 +- src/routes/eth.route.js | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/index.js b/src/index.js index ab5b30d..083fbb5 100644 --- a/src/index.js +++ b/src/index.js @@ -19,7 +19,7 @@ if (result.error) { const env = process.env.NODE_ENV const port = process.env.PORT const certPassphrase = process.env.CERT_PASSPHRASE -const ethereumChain = process.env.BALANCER_NETWORK +const ethereumChain = process.env.ETHEREUM_CHAIN let certPath = process.env.CERT_PATH if ((typeof certPath === 'undefined' && certPath == null) || certPath === '') { diff --git a/src/routes/eth.route.js b/src/routes/eth.route.js index 4c378d2..abcf6e6 100644 --- a/src/routes/eth.route.js +++ b/src/routes/eth.route.js @@ -5,8 +5,10 @@ import { getParamData, latency, reportConnectionError, statusMessages } from '.. import Ethereum from '../services/eth'; const router = express.Router() -const eth = new Ethereum(process.env.BALANCER_NETWORK) +const eth = new Ethereum(process.env.ETHEREUM_CHAIN) const separator = ',' +const spenders = { balancer: process.env.EXCHANGE_PROXY, + uniswap: process.env.UNISWAP_ROUTER } const debug = require('debug')('router') @@ -69,12 +71,13 @@ router.post('/allowances', async (req, res) => { x-www-form-urlencoded: { privateKey:{{privateKey}} tokenAddressList:{{tokenAddressList}} - spenderAddress:"0x....." + spenderAddress:"0x....." } */ const initTime = Date.now() const paramData = getParamData(req.body) const privateKey = paramData.privateKey + const spender = spenders[paramData.connector] let wallet try { wallet = new ethers.Wallet(privateKey, eth.provider) @@ -91,8 +94,6 @@ router.post('/allowances', async (req, res) => { if (paramData.tokenAddressList) { tokenAddressList = paramData.tokenAddressList.split(separator) } - debug(tokenAddressList) - const spender = paramData.spenderAddress const approvals = {} try { @@ -125,13 +126,14 @@ router.post('/approve', async (req, res) => { x-www-form-urlencoded: { privateKey:{{privateKey}} tokenAddress:"0x....." - spenderAddress:"0x....." + spenderAddress:"0x....." amount:{{amount}} } */ const initTime = Date.now() const paramData = getParamData(req.body) const privateKey = paramData.privateKey + const spender = spenders[paramData.connector] let wallet try { wallet = new ethers.Wallet(privateKey, eth.provider) @@ -145,10 +147,11 @@ router.post('/approve', async (req, res) => { return } const tokenAddress = paramData.tokenAddress - const spender = paramData.spenderAddress - let amount - paramData.amount ? amount = ethers.utils.parseEther(paramData.amount) - : amount = ethers.utils.parseEther('1000000000') // approve for 1 billion units if no amount specified + let amount, decimals + paramData.decimals ? decimals = paramData.decimals + : decimals = 18 + paramData.amount ? amount = ethers.utils.parseUnits(paramData.amount, decimals) + : amount = ethers.utils.parseUnits('1000000000', decimals) // approve for 1 billion units if no amount specified let gasPrice if (paramData.gasPrice) { gasPrice = parseFloat(paramData.gasPrice) From feee7b6a4b77d33dfbec809b319aeb3a5f2ff0c0 Mon Sep 17 00:00:00 2001 From: vic-en Date: Wed, 18 Nov 2020 14:48:39 +0100 Subject: [PATCH 5/6] (feat) update argument description for approval related routes --- src/routes/eth.route.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/eth.route.js b/src/routes/eth.route.js index abcf6e6..939be62 100644 --- a/src/routes/eth.route.js +++ b/src/routes/eth.route.js @@ -71,7 +71,7 @@ router.post('/allowances', async (req, res) => { x-www-form-urlencoded: { privateKey:{{privateKey}} tokenAddressList:{{tokenAddressList}} - spenderAddress:"0x....." + connector:{{connector_name}}" } */ const initTime = Date.now() @@ -126,7 +126,7 @@ router.post('/approve', async (req, res) => { x-www-form-urlencoded: { privateKey:{{privateKey}} tokenAddress:"0x....." - spenderAddress:"0x....." + connector:{{connector_name}}" amount:{{amount}} } */ From b192023b819bb5e85781eade0da1ff0604f7c972 Mon Sep 17 00:00:00 2001 From: vic-en Date: Wed, 18 Nov 2020 14:51:48 +0100 Subject: [PATCH 6/6] (feat) update argument description for approval related routes 2 --- src/routes/eth.route.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/routes/eth.route.js b/src/routes/eth.route.js index 939be62..ba72c37 100644 --- a/src/routes/eth.route.js +++ b/src/routes/eth.route.js @@ -71,7 +71,7 @@ router.post('/allowances', async (req, res) => { x-www-form-urlencoded: { privateKey:{{privateKey}} tokenAddressList:{{tokenAddressList}} - connector:{{connector_name}}" + connector:{{connector_name}} } */ const initTime = Date.now() @@ -126,7 +126,8 @@ router.post('/approve', async (req, res) => { x-www-form-urlencoded: { privateKey:{{privateKey}} tokenAddress:"0x....." - connector:{{connector_name}}" + decimals: {{token_decimals}} + connector:{{connector_name}} amount:{{amount}} } */