protocol/packages/dev-utils/src/web3_factory.ts
2020-01-06 22:12:05 -08:00

95 lines
3.7 KiB
TypeScript

import {
EmptyWalletSubprovider,
FakeGasEstimateSubprovider,
GanacheSubprovider,
RPCSubprovider,
Web3ProviderEngine,
} from '@0x/subproviders';
import { providerUtils } from '@0x/utils';
import * as fs from 'fs';
import * as _ from 'lodash';
import { constants } from './constants';
import { env, EnvVars } from './env';
export interface Web3Config {
total_accounts?: number; // default: 10
hasAddresses?: boolean; // default: true
shouldUseInProcessGanache?: boolean; // default: false
shouldThrowErrorsOnGanacheRPCResponse?: boolean; // default: true
rpcUrl?: string; // default: localhost:8545
shouldUseFakeGasEstimate?: boolean; // default: true
ganacheDatabasePath?: string; // default: undefined, creates a tmp dir
shouldAllowUnlimitedContractSize?: boolean;
fork?: string;
blockTime?: number;
locked?: boolean;
unlocked_accounts?: string[];
hardfork?: string;
}
export const web3Factory = {
getRpcProvider(config: Web3Config = {}): Web3ProviderEngine {
const provider = new Web3ProviderEngine();
const hasAddresses = config.hasAddresses === undefined || config.hasAddresses;
const shouldUseFakeGasEstimate =
config.shouldUseFakeGasEstimate === undefined || config.shouldUseFakeGasEstimate;
if (!hasAddresses) {
provider.addProvider(new EmptyWalletSubprovider());
}
if (shouldUseFakeGasEstimate) {
provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_LIMIT));
}
const logger = {
log: (arg: any) => {
fs.appendFileSync('ganache.log', `${arg}\n`);
},
};
const shouldUseInProcessGanache = !!config.shouldUseInProcessGanache;
if (shouldUseInProcessGanache) {
if (config.rpcUrl !== undefined) {
throw new Error('Cannot use both GanacheSubprovider and RPCSubprovider');
}
if (config.ganacheDatabasePath !== undefined) {
const doesDatabaseAlreadyExist = fs.existsSync(config.ganacheDatabasePath);
if (!doesDatabaseAlreadyExist) {
// Working with local DB snapshot. Ganache requires this directory to exist
fs.mkdirSync(config.ganacheDatabasePath);
}
}
const shouldThrowErrorsOnGanacheRPCResponse =
config.shouldThrowErrorsOnGanacheRPCResponse === undefined ||
config.shouldThrowErrorsOnGanacheRPCResponse;
provider.addProvider(
new GanacheSubprovider({
total_accounts: config.total_accounts,
vmErrorsOnRPCResponse: shouldThrowErrorsOnGanacheRPCResponse,
db_path: config.ganacheDatabasePath,
allowUnlimitedContractSize: config.shouldAllowUnlimitedContractSize,
gasLimit: constants.GAS_LIMIT,
logger,
verbose: env.parseBoolean(EnvVars.VerboseGanache),
port: 8545,
network_id: 50,
mnemonic: 'concert load couple harbor equip island argue ramp clarify fence smart topic',
fork: config.fork,
blockTime: config.blockTime,
locked: config.locked,
unlocked_accounts: config.unlocked_accounts,
hardfork: config.hardfork,
} as any), // TODO remove any once types are merged in DefinitelyTyped
);
} else {
provider.addProvider(new RPCSubprovider(config.rpcUrl || constants.RPC_URL));
}
providerUtils.startProviderEngine(provider);
return provider;
},
};