feat: base config & validate withdawal & health check

This commit is contained in:
nikdementev 2021-07-21 13:37:08 +03:00
parent 79af9c7ce0
commit 0fcfdf4094
No known key found for this signature in database
GPG Key ID: 769B05D57CF16FE2
14 changed files with 132 additions and 297 deletions

View File

@ -7,6 +7,7 @@ PORT=8000
#commision for service
SERVICE_FEE=0.05
REWARD_ADDRESS=
# bull settings
REDIS_URL=redis://127.0.0.1:6379

View File

@ -39,8 +39,7 @@
"rimraf": "^3.0.2",
"rxjs": "^7.2.0",
"tx-manager": "^0.3.1",
"uuid": "^8.3.2",
"web3-utils": "^1.4.0"
"uuid": "^8.3.2"
},
"devDependencies": {
"@nestjs/cli": "^8.0.0",

View File

@ -1,6 +1,16 @@
import { Wallet } from 'ethers';
import { version } from '../../package.json';
export const baseConfig = () => ({
gasLimit: 600000,
serviceFee: process.env.SERVICE_FEE,
chainId: process.env.CHAIN_ID,
port: parseInt(process.env.PORT, 10) || 8080,
base: {
version,
gasLimit: 600000,
minimumBalance: 0.5,
chainId: process.env.CHAIN_ID,
serviceFee: process.env.SERVICE_FEE,
rewardAddress: process.env.REWARD_ADDRESS,
port: parseInt(process.env.PORT, 10) || 8080,
address: new Wallet(process.env.PRIVATE_KEY).address,
},
});

View File

@ -9,10 +9,10 @@ async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule, { cors: true });
const configService = app.get(ConfigService);
await app.listen(configService.get('port'));
await app.listen(configService.get('base.port'));
} catch (err) {
console.log('err', err.message)
console.log('err', err.message);
}
}
bootstrap()
bootstrap();

View File

@ -1,30 +1,42 @@
import { Controller, Body, Param, Get, Post } from '@nestjs/common';
import { Job } from 'bull';
import { Controller, Body, Param, Res, Get, Post, HttpStatus } from '@nestjs/common';
import { Response } from 'express';
import { ApiService } from './api.service';
import { validateWithdrawRequest } from './api.validator';
@Controller()
export class ApiController {
constructor(private readonly service: ApiService) {}
@Get('/api')
async status(): Promise<Health> {
@Get('/status')
async status(): Promise<Status> {
return await this.service.status();
}
@Get('/')
async main(): Promise<string> {
return this.service.main();
async root(): Promise<string> {
return this.service.root();
}
@Get('/job/:jobId')
async getJob(@Param('jobId') jobId: string): Promise<Job> {
return await this.service.getJob(jobId);
async getJob(@Res() res: Response, @Param('jobId') jobId: string) {
const job = await this.service.getJob(jobId);
if (!job) {
return res.status(HttpStatus.BAD_REQUEST).json({ error: "The job doesn't exist" });
}
return job;
}
@Post('/withdrawal')
async withdrawal(_, @Body() { body }: any): Promise<string> {
console.log('body', body);
async withdrawal(@Res() res: Response, @Body() { body }: any) {
const inputError = validateWithdrawRequest(body);
if (inputError) {
console.log('Invalid input:', inputError);
return res.status(HttpStatus.BAD_REQUEST).json({ error: inputError });
}
return await this.service.withdrawal(JSON.parse(body));
}

View File

@ -5,10 +5,11 @@ import { ApiService } from './api.service';
import { ApiController } from './api.controller';
import { QueueModule } from '@/modules';
import { ProviderService } from '@/services';
@Module({
imports: [ConfigModule, QueueModule],
providers: [ApiService],
providers: [ApiService, ProviderService],
controllers: [ApiController],
exports: [],
})

View File

@ -2,18 +2,32 @@ import { Queue, Job } from 'bull';
import { InjectQueue } from '@nestjs/bull';
import { Injectable } from '@nestjs/common';
import { ProviderService } from '@/services';
import { ConfigService } from '@nestjs/config';
@Injectable()
class ApiService {
constructor(@InjectQueue('withdrawal') private withdrawalQueue: Queue) {}
constructor(
private configService: ConfigService,
private providerService: ProviderService,
@InjectQueue('withdrawal') private withdrawalQueue: Queue,
) {}
async status(): Promise<Status> {
const { rewardAddress, version, chainId, serviceFee } = this.configService.get('base');
const health = await this.healthCheck();
async status(): Promise<Health> {
return {
status: '',
error: false,
health,
chainId,
version,
serviceFee,
rewardAddress,
};
}
main(): string {
root(): string {
return `This is <a href=https://tornado.cash>tornado.cash</a> Relayer service. Check the <a href=/status>/status</a> for settings`;
}
@ -23,9 +37,20 @@ class ApiService {
return String(job.id);
}
async getJob(id: string): Promise<Job> {
async getJob(id: string): Promise<Job | null> {
return await this.withdrawalQueue.getJob(id);
}
private async healthCheck(): Promise<Health> {
const status = await this.providerService.checkSenderBalance();
const minimumBalance = this.configService.get('base.minimumBalance');
return {
status,
error: status ? '' : `Not enough balance, less than ${minimumBalance} ETH`,
};
}
}
export { ApiService };

View File

@ -1,5 +1,5 @@
import Ajv, { ValidateFunction } from 'ajv';
import { isAddress, toChecksumAddress } from '@/utilities';
import { isAddress } from '@/utilities';
const ajv = new Ajv();
@ -11,69 +11,44 @@ ajv.addKeyword({
errors: true,
});
ajv.addKeyword({
keyword: 'isKnownContract',
validate: (schema: any, address: string) => {
try {
return address !== null;
} catch (e) {
return false;
}
},
errors: true,
});
ajv.addKeyword({
keyword: 'isFeeRecipient',
validate: (schema: any, address: string) => {
try {
return toChecksumAddress('') === toChecksumAddress(address);
} catch (e) {
return false;
}
},
errors: true,
});
const addressType = {
type: 'string',
pattern: '^0x[a-fA-F0-9]{40}$',
isAddress: true,
};
const proofType = { type: 'string', pattern: '^0x[a-fA-F0-9]{512}$' };
const bytes32Type = { type: 'string', pattern: '^0x[a-fA-F0-9]{64}$' };
const instanceType = { ...addressType, isKnownContract: true };
const relayerType = { ...addressType, isFeeRecipient: true };
const arrayType = { type: 'array', pattern: '^0x[a-fA-F0-9]{64}$' };
const tornadoWithdrawSchema = {
const recipientType = {
type: 'object',
properties: {
recipient: addressType,
relayer: addressType,
encryptedOutput1: bytes32Type,
encryptedOutput2: bytes32Type,
},
};
const withdrawSchema = {
type: 'object',
properties: {
proof: proofType,
contract: instanceType,
args: {
type: 'array',
maxItems: 6,
minItems: 6,
items: [
bytes32Type,
bytes32Type,
addressType,
relayerType,
bytes32Type,
bytes32Type,
],
maxItems: 9,
minItems: 9,
items: [bytes32Type, bytes32Type, arrayType, bytes32Type, bytes32Type, bytes32Type, bytes32Type, recipientType, bytes32Type],
},
},
additionalProperties: false,
required: ['proof', 'contract', 'args'],
required: ['proof', 'args'],
};
const validateTornadoWithdraw = ajv.compile(tornadoWithdrawSchema);
const validateTornadoWithdraw = ajv.compile(withdrawSchema);
function getInputError(
validator: ValidateFunction,
data: typeof tornadoWithdrawSchema,
) {
function getInputError(validator: ValidateFunction, data: typeof withdrawSchema) {
validator(data);
if (validator.errors) {
const [error] = validator.errors;
@ -82,7 +57,7 @@ function getInputError(
return null;
}
function validateWithdrawRequest(data: typeof tornadoWithdrawSchema) {
function validateWithdrawRequest(data: typeof withdrawSchema) {
return getInputError(validateTornadoWithdraw, data);
}

View File

@ -1,4 +1,12 @@
type Health = {
status: string;
error: boolean;
status: boolean;
error: string;
};
type Status = {
health: Health;
rewardAddress: string;
version: string;
serviceFee: number;
chainId: number;
};

View File

@ -91,14 +91,14 @@ export class WithdrawalProcessor extends BaseProcessor<Withdrawal> {
}
async prepareTransaction({ proof, args }) {
const chainId = this.configService.get<number>('chainId');
const chainId = this.configService.get('base.chainId');
const contract = this.providerService.getTornadoPool();
// @ts-ignore
const data = contract.interface.encodeFunctionData('transaction', [proof, ...args]);
let gasLimit = this.configService.get<BigNumber>('gasLimit');
let gasLimit = this.configService.get<BigNumber>('base.gasLimit');
// need because optimism has dynamic gas limit
if (chainId === ChainId.OPTIMISM) {
@ -122,7 +122,7 @@ export class WithdrawalProcessor extends BaseProcessor<Withdrawal> {
}
async checkFee({ fee, amount }) {
const { gasLimit, serviceFee } = this.configService.get('');
const { gasLimit, serviceFee } = this.configService.get('base');
const { fast } = await this.gasPriceService.getGasPrice();

View File

@ -13,7 +13,7 @@ export class GasPriceService {
private readonly chainId: number;
constructor(private configService: ConfigService) {
this.chainId = this.configService.get<number>('chainId');
this.chainId = this.configService.get<number>('base.chainId');
}
async getGasPrice(): Promise<GasPrice> {

View File

@ -8,13 +8,11 @@ import { TornadoPool__factory as TornadoPoolFactory } from '@/artifacts';
@Injectable()
export class ProviderService {
private readonly chainId: number;
public provider: ethers.providers.JsonRpcProvider;
constructor(private configService: ConfigService) {
this.chainId = this.configService.get<number>('chainId');
}
getProvider() {
return new ethers.providers.JsonRpcProvider(RPC_LIST[this.chainId]);
this.chainId = this.configService.get<number>('base.chainId');
this.provider = new ethers.providers.JsonRpcProvider(RPC_LIST[this.chainId]);
}
getProviderWithSigner() {
@ -24,4 +22,18 @@ export class ProviderService {
getTornadoPool() {
return TornadoPoolFactory.connect(CONTRACT_NETWORKS[this.chainId], this.getProviderWithSigner());
}
async checkSenderBalance() {
try {
const balance = await this.getBalance(this.configService.get<string>('base.address'));
return balance.gt(ethers.utils.parseEther(this.configService.get('base.minimumBalance')));
} catch {
return false;
}
}
async getBalance(address: string) {
return await this.provider.getBalance(address);
}
}

View File

@ -1,23 +1,13 @@
import { BigNumber, utils, BigNumberish } from 'ethers';
import {
toChecksumAddress as checksumAddress,
isAddress as checkAddress,
} from 'web3-utils';
import { numbers } from '@/constants';
// eslint-disable-next-line
export function isAddress(value: any): boolean {
try {
return checkAddress(value);
} catch {
return false;
}
export function isAddress(value: string): boolean {
return utils.isAddress(value);
}
// eslint-disable-next-line
export function toChecksumAddress(value: any): string {
return checksumAddress(value);
export function toChecksumAddress(value: string): string {
return utils.getAddress(value);
}
export function toWei(value: string, uintName = 'wei') {

202
yarn.lock
View File

@ -1887,12 +1887,7 @@ bl@^4.1.0:
inherits "^2.0.4"
readable-stream "^3.4.0"
bn.js@4.11.6:
version "4.11.6"
resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215"
integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU=
bn.js@^4.11.6, bn.js@^4.11.9:
bn.js@^4.11.9:
version "4.12.0"
resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
@ -1968,11 +1963,6 @@ buffer-from@1.x, buffer-from@^1.0.0:
resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
buffer-to-arraybuffer@^0.0.5:
version "0.0.5"
resolved "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a"
integrity sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=
buffer@^5.5.0:
version "5.7.1"
resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
@ -2390,18 +2380,6 @@ decimal.js@^10.2.1:
resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783"
integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==
decode-uri-component@^0.2.0:
version "0.2.0"
resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
decompress-response@^3.3.0:
version "3.3.0"
resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
dependencies:
mimic-response "^1.0.0"
dedent@^0.7.0:
version "0.7.0"
resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
@ -2493,11 +2471,6 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
dom-walk@^0.1.0:
version "0.1.2"
resolved "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==
domexception@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304"
@ -2525,7 +2498,7 @@ electron-to-chromium@^1.3.723:
resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.771.tgz#c4aa601e6420e11926095f75fe803956a1b4bd81"
integrity sha512-zHMomTqkpnAD9W5rhXE1aiU3ogGFrqWzdvM4C6222SREiqsWQb2w0S7P2Ii44qCaGimmAP1z+OydllM438uJyA==
elliptic@6.5.4, elliptic@^6.4.0:
elliptic@6.5.4:
version "6.5.4"
resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
@ -2793,22 +2766,6 @@ etag@~1.8.1:
resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
eth-lib@0.2.8:
version "0.2.8"
resolved "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8"
integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==
dependencies:
bn.js "^4.11.6"
elliptic "^6.4.0"
xhr-request-promise "^0.1.2"
ethereum-bloom-filters@^1.0.6:
version "1.0.10"
resolved "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a"
integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==
dependencies:
js-sha3 "^0.8.0"
ethers@^5.0.17, ethers@^5.4.1:
version "5.4.1"
resolved "https://registry.npmjs.org/ethers/-/ethers-5.4.1.tgz#bcff1e9f45bf1a061bf313ec04e8d9881d2d53f9"
@ -2845,14 +2802,6 @@ ethers@^5.0.17, ethers@^5.4.1:
"@ethersproject/web" "5.4.0"
"@ethersproject/wordlists" "5.4.0"
ethjs-unit@0.1.6:
version "0.1.6"
resolved "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699"
integrity sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=
dependencies:
bn.js "4.11.6"
number-to-bn "1.7.0"
eventemitter3@4.0.4:
version "4.0.4"
resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384"
@ -3256,14 +3205,6 @@ glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
once "^1.3.0"
path-is-absolute "^1.0.0"
global@~4.4.0:
version "4.4.0"
resolved "https://registry.npmjs.org/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406"
integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==
dependencies:
min-document "^2.19.0"
process "^0.11.10"
globals@^11.1.0:
version "11.12.0"
resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
@ -3587,11 +3528,6 @@ is-fullwidth-code-point@^3.0.0:
resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
is-function@^1.0.1:
version "1.0.2"
resolved "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08"
integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==
is-generator-fn@^2.0.0:
version "2.1.0"
resolved "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118"
@ -3604,11 +3540,6 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
dependencies:
is-extglob "^2.1.1"
is-hex-prefixed@1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554"
integrity sha1-fY035q135dEnFIkTxXPggtd39VQ=
is-interactive@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e"
@ -4492,18 +4423,6 @@ mimic-fn@^2.1.0:
resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
mimic-response@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
min-document@^2.19.0:
version "2.19.0"
resolved "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=
dependencies:
dom-walk "^0.1.0"
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
@ -4638,14 +4557,6 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1:
dependencies:
path-key "^3.0.0"
number-to-bn@1.7.0:
version "1.7.0"
resolved "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0"
integrity sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=
dependencies:
bn.js "4.11.6"
strip-hex-prefix "1.0.0"
nwsapi@^2.2.0:
version "2.2.0"
resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7"
@ -4838,11 +4749,6 @@ parent-module@^1.0.0:
dependencies:
callsites "^3.0.0"
parse-headers@^2.0.0:
version "2.0.3"
resolved "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz#5e8e7512383d140ba02f0c7aa9f49b4399c92515"
integrity sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==
parse-json@^5.0.0:
version "5.2.0"
resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
@ -4969,11 +4875,6 @@ process-nextick-args@~2.0.0:
resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
process@^0.11.10:
version "0.11.10"
resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
progress@^2.0.0:
version "2.0.3"
resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
@ -5034,15 +4935,6 @@ qs@^6.9.4:
dependencies:
side-channel "^1.0.4"
query-string@^5.0.1:
version "5.1.1"
resolved "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb"
integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==
dependencies:
decode-uri-component "^0.2.0"
object-assign "^4.1.0"
strict-uri-encode "^1.0.0"
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
@ -5372,20 +5264,6 @@ signal-exit@^3.0.2, signal-exit@^3.0.3:
resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
simple-concat@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
simple-get@^2.7.0:
version "2.8.1"
resolved "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d"
integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==
dependencies:
decompress-response "^3.3.0"
once "^1.3.1"
simple-concat "^1.0.0"
sisteransi@^1.0.5:
version "1.0.5"
resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
@ -5465,11 +5343,6 @@ streamsearch@0.1.2:
resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=
strict-uri-encode@^1.0.0:
version "1.1.0"
resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
string-length@^4.0.1:
version "4.0.2"
resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a"
@ -5559,13 +5432,6 @@ strip-final-newline@^2.0.0:
resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
strip-hex-prefix@1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f"
integrity sha1-DF8VX+8RUTczd96du1iNoFUA428=
dependencies:
is-hex-prefixed "1.0.0"
strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
version "3.1.1"
resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
@ -5718,11 +5584,6 @@ through@^2.3.6:
resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
timed-out@^4.0.1:
version "4.0.1"
resolved "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
@ -5967,11 +5828,6 @@ unbox-primitive@^1.0.1:
has-symbols "^1.0.2"
which-boxed-primitive "^1.0.2"
underscore@1.12.1:
version "1.12.1"
resolved "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz#7bb8cc9b3d397e201cf8553336d262544ead829e"
integrity sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==
universalify@^0.1.0, universalify@^0.1.2:
version "0.1.2"
resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
@ -5994,16 +5850,6 @@ uri-js@^4.2.2:
dependencies:
punycode "^2.1.0"
url-set-query@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339"
integrity sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=
utf8@3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1"
integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
@ -6097,20 +5943,6 @@ web3-core-promievent@^1.3.0:
dependencies:
eventemitter3 "4.0.4"
web3-utils@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/web3-utils/-/web3-utils-1.4.0.tgz#e8cb381c81b242dc1d4ecb397200356d404410e6"
integrity sha512-b8mEhwh/J928Xk+SQFjtqrR2EGPhpknWLcIt9aCpVPVRXiqjUGo/kpOHKz0azu9c6/onEJ9tWXZt0cVjmH0N5Q==
dependencies:
bn.js "^4.11.9"
eth-lib "0.2.8"
ethereum-bloom-filters "^1.0.6"
ethjs-unit "0.1.6"
number-to-bn "1.7.0"
randombytes "^2.1.0"
underscore "1.12.1"
utf8 "3.0.0"
webidl-conversions@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
@ -6248,36 +6080,6 @@ ws@^7.4.5:
resolved "https://registry.npmjs.org/ws/-/ws-7.5.2.tgz#09cc8fea3bec1bc5ed44ef51b42f945be36900f6"
integrity sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ==
xhr-request-promise@^0.1.2:
version "0.1.3"
resolved "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c"
integrity sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==
dependencies:
xhr-request "^1.1.0"
xhr-request@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed"
integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==
dependencies:
buffer-to-arraybuffer "^0.0.5"
object-assign "^4.1.1"
query-string "^5.0.1"
simple-get "^2.7.0"
timed-out "^4.0.1"
url-set-query "^1.0.0"
xhr "^2.0.4"
xhr@^2.0.4:
version "2.6.0"
resolved "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d"
integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==
dependencies:
global "~4.4.0"
is-function "^1.0.1"
parse-headers "^2.0.0"
xtend "^4.0.0"
xml-name-validator@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"