diff options
Diffstat (limited to 'packages/testnet-faucets')
-rw-r--r-- | packages/testnet-faucets/package.json | 2 | ||||
-rw-r--r-- | packages/testnet-faucets/src/ts/dispense_asset_tasks.ts | 35 | ||||
-rw-r--r-- | packages/testnet-faucets/src/ts/handler.ts | 110 | ||||
-rw-r--r-- | packages/testnet-faucets/src/ts/rpc_urls.ts | 1 | ||||
-rw-r--r-- | packages/testnet-faucets/src/ts/tokens.ts | 44 |
5 files changed, 134 insertions, 58 deletions
diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json index ed6dddb41..a2d107f58 100644 --- a/packages/testnet-faucets/package.json +++ b/packages/testnet-faucets/package.json @@ -17,7 +17,7 @@ "author": "Fabio Berger", "license": "Apache-2.0", "dependencies": { - "0x.js": "0.38.5", + "0x.js": "1.0.1", "@0xproject/subproviders": "^2.0.2", "@0xproject/typescript-typings": "^2.0.0", "@0xproject/utils": "^1.0.8", diff --git a/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts b/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts index 3af5ca747..fa63ab63e 100644 --- a/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts +++ b/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts @@ -1,13 +1,14 @@ -import { ZeroEx } from '0x.js'; +import { ERC20TokenWrapper } from '0x.js'; import { BigNumber, logUtils } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; import { configs } from './configs'; +import { TOKENS_BY_NETWORK } from './tokens'; const DISPENSE_AMOUNT_ETHER = 0.1; -const DISPENSE_AMOUNT_TOKEN = 0.1; -const DISPENSE_MAX_AMOUNT_TOKEN = 2; +const DISPENSE_AMOUNT_TOKEN = 1; +const DISPENSE_MAX_AMOUNT_TOKEN = 100; const DISPENSE_MAX_AMOUNT_ETHER = 2; type AsyncTask = () => Promise<void>; @@ -32,19 +33,27 @@ export const dispenseAssetTasks = { logUtils.log(`Sent ${DISPENSE_AMOUNT_ETHER} ETH to ${recipientAddress} tx: ${txHash}`); }; }, - dispenseTokenTask(recipientAddress: string, tokenSymbol: string, zeroEx: ZeroEx): AsyncTask { + dispenseTokenTask( + recipientAddress: string, + tokenSymbol: string, + networkId: number, + erc20TokenWrapper: ERC20TokenWrapper, + ): AsyncTask { return async () => { logUtils.log(`Processing ${tokenSymbol} ${recipientAddress}`); const amountToDispense = new BigNumber(DISPENSE_AMOUNT_TOKEN); - const token = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync(tokenSymbol); - if (_.isUndefined(token)) { + const tokenIfExists = _.get(TOKENS_BY_NETWORK, [networkId, tokenSymbol]); + if (_.isUndefined(tokenIfExists)) { throw new Error(`Unsupported asset type: ${tokenSymbol}`); } - const baseUnitAmount = ZeroEx.toBaseUnitAmount(amountToDispense, token.decimals); - const userBalanceBaseUnits = await zeroEx.token.getBalanceAsync(token.address, recipientAddress); - const maxAmountBaseUnits = ZeroEx.toBaseUnitAmount( + const baseUnitAmount = Web3Wrapper.toBaseUnitAmount(amountToDispense, tokenIfExists.decimals); + const userBalanceBaseUnits = await erc20TokenWrapper.getBalanceAsync( + tokenIfExists.address, + recipientAddress, + ); + const maxAmountBaseUnits = Web3Wrapper.toBaseUnitAmount( new BigNumber(DISPENSE_MAX_AMOUNT_TOKEN), - token.decimals, + tokenIfExists.decimals, ); if (userBalanceBaseUnits.greaterThanOrEqualTo(maxAmountBaseUnits)) { logUtils.log( @@ -52,13 +61,13 @@ export const dispenseAssetTasks = { ); return; } - const txHash = await zeroEx.token.transferAsync( - token.address, + const txHash = await erc20TokenWrapper.transferAsync( + tokenIfExists.address, configs.DISPENSER_ADDRESS, recipientAddress, baseUnitAmount, ); - logUtils.log(`Sent ${amountToDispense} ZRX to ${recipientAddress} tx: ${txHash}`); + logUtils.log(`Sent ${amountToDispense} ${tokenSymbol} to ${recipientAddress} tx: ${txHash}`); }; }, }; diff --git a/packages/testnet-faucets/src/ts/handler.ts b/packages/testnet-faucets/src/ts/handler.ts index 3749bc70b..82e9a9494 100644 --- a/packages/testnet-faucets/src/ts/handler.ts +++ b/packages/testnet-faucets/src/ts/handler.ts @@ -1,27 +1,35 @@ -import { Order, ZeroEx } from '0x.js'; -import { BigNumber, logUtils } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import { Provider } from 'ethereum-types'; -import * as express from 'express'; -import * as _ from 'lodash'; - import { - NonceTrackerSubprovider, - PrivateKeyWalletSubprovider, + assetDataUtils, + BigNumber, + ContractWrappers, + generatePseudoRandomSalt, + Order, + orderHashUtils, + Provider, RPCSubprovider, + signatureUtils, + SignedOrder, + SignerType, Web3ProviderEngine, -} from '@0xproject/subproviders'; +} from '0x.js'; +import { NonceTrackerSubprovider, PrivateKeyWalletSubprovider } from '@0xproject/subproviders'; +import { logUtils } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as express from 'express'; +import * as _ from 'lodash'; import { configs } from './configs'; import { constants } from './constants'; import { DispatchQueue } from './dispatch_queue'; import { dispenseAssetTasks } from './dispense_asset_tasks'; import { rpcUrls } from './rpc_urls'; +import { TOKENS_BY_NETWORK } from './tokens'; interface NetworkConfig { dispatchQueue: DispatchQueue; web3Wrapper: Web3Wrapper; - zeroEx: ZeroEx; + contractWrappers: ContractWrappers; + networkId: number; } interface ItemByNetworkId<T> { @@ -35,6 +43,9 @@ enum RequestedAssetType { } const FIVE_DAYS_IN_MS = 4.32e8; // TODO: make this configurable +const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'; +const ZERO = new BigNumber(0); +const ASSET_AMOUNT = new BigNumber(0.1); export class Handler { private readonly _networkConfigByNetworkId: ItemByNetworkId<NetworkConfig> = {}; @@ -50,18 +61,18 @@ export class Handler { return engine; } constructor() { - _.forIn(rpcUrls, (rpcUrl: string, networkId: string) => { + _.forIn(rpcUrls, (rpcUrl: string, networkIdString: string) => { const providerObj = Handler._createProviderEngine(rpcUrl); const web3Wrapper = new Web3Wrapper(providerObj); - const zeroExConfig = { - networkId: +networkId, - }; - const zeroEx = new ZeroEx(providerObj, zeroExConfig); + // tslint:disable-next-line:custom-no-magic-numbers + const networkId = parseInt(networkIdString, 10); + const contractWrappers = new ContractWrappers(providerObj, { networkId }); const dispatchQueue = new DispatchQueue(); this._networkConfigByNetworkId[networkId] = { dispatchQueue, web3Wrapper, - zeroEx, + contractWrappers, + networkId, }; }); } @@ -96,7 +107,11 @@ export class Handler { private _dispenseAsset(req: express.Request, res: express.Response, requestedAssetType: RequestedAssetType): void { const networkId = req.params.networkId; const recipient = req.params.recipient; - const networkConfig = this._networkConfigByNetworkId[networkId]; + const networkConfig = _.get(this._networkConfigByNetworkId, networkId); + if (_.isUndefined(networkConfig)) { + res.status(constants.BAD_REQUEST_STATUS).send('UNSUPPORTED_NETWORK_ID'); + return; + } let dispenserTask; switch (requestedAssetType) { case RequestedAssetType.ETH: @@ -107,7 +122,8 @@ export class Handler { dispenserTask = dispenseAssetTasks.dispenseTokenTask( recipient, requestedAssetType, - networkConfig.zeroEx, + networkConfig.networkId, + networkConfig.contractWrappers.erc20Token, ); break; default: @@ -131,39 +147,47 @@ export class Handler { res.status(constants.BAD_REQUEST_STATUS).send('UNSUPPORTED_NETWORK_ID'); return; } - const zeroEx = networkConfig.zeroEx; res.setHeader('Content-Type', 'application/json'); - const makerToken = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync(requestedAssetType); - if (_.isUndefined(makerToken)) { + const makerTokenIfExists = _.get(TOKENS_BY_NETWORK, [networkConfig.networkId, requestedAssetType]); + if (_.isUndefined(makerTokenIfExists)) { throw new Error(`Unsupported asset type: ${requestedAssetType}`); } const takerTokenSymbol = requestedAssetType === RequestedAssetType.WETH ? RequestedAssetType.ZRX : RequestedAssetType.WETH; - const takerToken = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync(takerTokenSymbol); - if (_.isUndefined(takerToken)) { - throw new Error(`Unsupported asset type: ${requestedAssetType}`); + const takerTokenIfExists = _.get(TOKENS_BY_NETWORK, [networkConfig.networkId, takerTokenSymbol]); + if (_.isUndefined(takerTokenIfExists)) { + throw new Error(`Unsupported asset type: ${takerTokenSymbol}`); } - const makerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(0.1), makerToken.decimals); - const takerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(0.1), takerToken.decimals); + const makerAssetAmount = Web3Wrapper.toBaseUnitAmount(ASSET_AMOUNT, makerTokenIfExists.decimals); + const takerAssetAmount = Web3Wrapper.toBaseUnitAmount(ASSET_AMOUNT, takerTokenIfExists.decimals); + const makerAssetData = assetDataUtils.encodeERC20AssetData(makerTokenIfExists.address); + const takerAssetData = assetDataUtils.encodeERC20AssetData(takerTokenIfExists.address); const order: Order = { - maker: configs.DISPENSER_ADDRESS, - taker: req.params.recipient, - makerFee: new BigNumber(0), - takerFee: new BigNumber(0), - makerTokenAmount, - takerTokenAmount, - makerTokenAddress: makerToken.address, - takerTokenAddress: takerToken.address, - salt: ZeroEx.generatePseudoRandomSalt(), - exchangeContractAddress: zeroEx.exchange.getContractAddress(), - feeRecipient: ZeroEx.NULL_ADDRESS, - expirationUnixTimestampSec: new BigNumber(Date.now() + FIVE_DAYS_IN_MS), + makerAddress: configs.DISPENSER_ADDRESS, + takerAddress: req.params.recipient as string, + makerFee: ZERO, + takerFee: ZERO, + makerAssetAmount, + takerAssetAmount, + makerAssetData, + takerAssetData, + salt: generatePseudoRandomSalt(), + exchangeAddress: networkConfig.contractWrappers.exchange.getContractAddress(), + feeRecipientAddress: NULL_ADDRESS, + senderAddress: NULL_ADDRESS, + // tslint:disable-next-line:custom-no-magic-numbers + expirationTimeSeconds: new BigNumber(Date.now() + FIVE_DAYS_IN_MS).div(1000).floor(), }; - const orderHash = ZeroEx.getOrderHashHex(order); - const signature = await zeroEx.signOrderHashAsync(orderHash, configs.DISPENSER_ADDRESS, false); - const signedOrder = { + const orderHash = orderHashUtils.getOrderHashHex(order); + const signature = await signatureUtils.ecSignOrderHashAsync( + networkConfig.web3Wrapper.getProvider(), + orderHash, + configs.DISPENSER_ADDRESS, + SignerType.Default, + ); + const signedOrder: SignedOrder = { ...order, - ecSignature: signature, + signature, }; const payload = JSON.stringify(signedOrder); logUtils.log(`Dispensed signed order: ${payload}`); diff --git a/packages/testnet-faucets/src/ts/rpc_urls.ts b/packages/testnet-faucets/src/ts/rpc_urls.ts index f8a57e171..d31908257 100644 --- a/packages/testnet-faucets/src/ts/rpc_urls.ts +++ b/packages/testnet-faucets/src/ts/rpc_urls.ts @@ -2,7 +2,6 @@ import { configs } from './configs'; const productionRpcUrls = { '3': `https://ropsten.infura.io/${configs.INFURA_API_KEY}`, - '4': `https://rinkeby.infura.io/${configs.INFURA_API_KEY}`, '42': `https://kovan.infura.io/${configs.INFURA_API_KEY}`, }; diff --git a/packages/testnet-faucets/src/ts/tokens.ts b/packages/testnet-faucets/src/ts/tokens.ts new file mode 100644 index 000000000..4ffb03df4 --- /dev/null +++ b/packages/testnet-faucets/src/ts/tokens.ts @@ -0,0 +1,44 @@ +interface TokensByNetwork { + [networkId: number]: { [tokenSymbol: string]: { address: string; decimals: number } }; +} + +export const tokens = { + ZRX: { + decimals: 18, + }, + WETH: { + decimals: 18, + }, +}; +export const TOKENS_BY_NETWORK: TokensByNetwork = { + 3: { + ZRX: { + ...tokens.ZRX, + address: '0xff67881f8d12f372d91baae9752eb3631ff0ed00', + }, + WETH: { + ...tokens.WETH, + address: '0xc778417e063141139fce010982780140aa0cd5ab', + }, + }, + 42: { + ZRX: { + ...tokens.ZRX, + address: '0x2002d3812f58e35f0ea1ffbf80a75a38c32175fa', + }, + WETH: { + ...tokens.WETH, + address: '0xd0a1e359811322d97991e03f863a0c30c2cf029c', + }, + }, + 50: { + ZRX: { + ...tokens.ZRX, + address: '0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c', + }, + WETH: { + ...tokens.WETH, + address: '0x0b1ba0af832d7c05fd64161e0db78e85978e8082', + }, + }, +}; |