diff options
Diffstat (limited to 'packages/testnet-faucets/src/ts/handler.ts')
-rw-r--r-- | packages/testnet-faucets/src/ts/handler.ts | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/packages/testnet-faucets/src/ts/handler.ts b/packages/testnet-faucets/src/ts/handler.ts new file mode 100644 index 000000000..4bf776264 --- /dev/null +++ b/packages/testnet-faucets/src/ts/handler.ts @@ -0,0 +1,93 @@ +import * as express from 'express'; +import * as _ from 'lodash'; +import ProviderEngine = require('web3-provider-engine'); +import HookedWalletSubprovider = require('web3-provider-engine/subproviders/hooked-wallet'); +import NonceSubprovider = require('web3-provider-engine/subproviders/nonce-tracker'); +import RpcSubprovider = require('web3-provider-engine/subproviders/rpc'); + +import { configs } from './configs'; +import { EtherRequestQueue } from './ether_request_queue'; +import { idManagement } from './id_management'; +import { utils } from './utils'; +import { ZRXRequestQueue } from './zrx_request_queue'; + +// HACK: web3 leaks XMLHttpRequest into the global scope and causes requests to hang +// because they are using the wrong XHR package. +// Filed issue: https://github.com/ethereum/web3.js/issues/844 +// tslint:disable-next-line:ordered-imports +import * as Web3 from 'web3'; + +export class Handler { + private _etherRequestQueue: EtherRequestQueue; + private _zrxRequestQueue: ZRXRequestQueue; + private _web3: Web3; + constructor() { + // Setup provider engine to talk with RPC node + const providerObj = this._createProviderEngine(configs.RPC_URL); + this._web3 = new Web3(providerObj); + + this._etherRequestQueue = new EtherRequestQueue(this._web3); + this._zrxRequestQueue = new ZRXRequestQueue(this._web3); + } + public dispenseEther(req: express.Request, res: express.Response) { + const recipientAddress = req.params.recipient; + if (_.isUndefined(recipientAddress) || !this._isValidEthereumAddress(recipientAddress)) { + res.status(400).send('INVALID_REQUEST'); + return; + } + const lowerCaseRecipientAddress = recipientAddress.toLowerCase(); + const didAddToQueue = this._etherRequestQueue.add(lowerCaseRecipientAddress); + if (!didAddToQueue) { + res.status(503).send('QUEUE_IS_FULL'); + return; + } + utils.consoleLog(`Added ${lowerCaseRecipientAddress} to the ETH queue`); + res.status(200).end(); + } + public dispenseZRX(req: express.Request, res: express.Response) { + const recipientAddress = req.params.recipient; + if (_.isUndefined(recipientAddress) || !this._isValidEthereumAddress(recipientAddress)) { + res.status(400).send('INVALID_REQUEST'); + return; + } + const lowerCaseRecipientAddress = recipientAddress.toLowerCase(); + const didAddToQueue = this._zrxRequestQueue.add(lowerCaseRecipientAddress); + if (!didAddToQueue) { + res.status(503).send('QUEUE_IS_FULL'); + return; + } + utils.consoleLog(`Added ${lowerCaseRecipientAddress} to the ZRX queue`); + res.status(200).end(); + } + public getQueueInfo(req: express.Request, res: express.Response) { + res.setHeader('Content-Type', 'application/json'); + const payload = JSON.stringify({ + ether: { + full: this._etherRequestQueue.isFull(), + size: this._etherRequestQueue.size(), + }, + zrx: { + full: this._zrxRequestQueue.isFull(), + size: this._zrxRequestQueue.size(), + }, + }); + res.status(200).send(payload); + } + // tslint:disable-next-line:prefer-function-over-method + private _createProviderEngine(rpcUrl: string) { + const engine = new ProviderEngine(); + engine.addProvider(new NonceSubprovider()); + engine.addProvider(new HookedWalletSubprovider(idManagement)); + engine.addProvider( + new RpcSubprovider({ + rpcUrl, + }), + ); + engine.start(); + return engine; + } + private _isValidEthereumAddress(address: string): boolean { + const lowercaseAddress = address.toLowerCase(); + return this._web3.isAddress(lowercaseAddress); + } +} |