aboutsummaryrefslogtreecommitdiffstats
path: root/packages/subproviders/src
diff options
context:
space:
mode:
authorFabio Berger <me@fabioberger.com>2018-03-14 21:16:08 +0800
committerFabio Berger <me@fabioberger.com>2018-03-14 21:16:08 +0800
commit009b70f5b218a1ccb154034936256308131b7d9c (patch)
treecd9642a8d3323c9e80da54ac4e8fc40ade9f9020 /packages/subproviders/src
parentf7c1e10b5ac112866ee55e7fededdb37c890d30f (diff)
parent3f3e8be004818ddaa1921b3dff12bdd46052278b (diff)
downloaddexon-sol-tools-009b70f5b218a1ccb154034936256308131b7d9c.tar
dexon-sol-tools-009b70f5b218a1ccb154034936256308131b7d9c.tar.gz
dexon-sol-tools-009b70f5b218a1ccb154034936256308131b7d9c.tar.bz2
dexon-sol-tools-009b70f5b218a1ccb154034936256308131b7d9c.tar.lz
dexon-sol-tools-009b70f5b218a1ccb154034936256308131b7d9c.tar.xz
dexon-sol-tools-009b70f5b218a1ccb154034936256308131b7d9c.tar.zst
dexon-sol-tools-009b70f5b218a1ccb154034936256308131b7d9c.zip
Merge branch 'development' into convertScriptsToTs
* development: (71 commits) Transform input data before encoding for callAsync and getABIEncodedTransactionData Update coverage badge to show development coverage Configure post build hook Notify coveralls after all tasks have finished Address feedback Revert "Report all coverage reports together" Separate published packages and typescript typings on README Report all coverage reports together Add other statement types Properly and consistently parse ENV vars Add forgotten file Start using solidity-parser-antlr Fix the default always overriding to address Submit a TD PR Add an explanatory comment for making ranges unique Fix a typo in handling env variables Introduce TESTRPC_FIRST_ADDRESS Make BlockchainLifecycle accept only web3Wrapper Fix comments Fix deployer CHANGELOG ... # Conflicts: # README.md # packages/deployer/package.json # packages/subproviders/src/globals.d.ts # yarn.lock
Diffstat (limited to 'packages/subproviders/src')
-rw-r--r--packages/subproviders/src/globals.d.ts25
-rw-r--r--packages/subproviders/src/index.ts3
-rw-r--r--packages/subproviders/src/subproviders/empty_wallet_subprovider.ts17
-rw-r--r--packages/subproviders/src/subproviders/fake_gas_estimate_subprovider.ts18
-rw-r--r--packages/subproviders/src/subproviders/ganache.ts28
-rw-r--r--packages/subproviders/src/subproviders/injected_web3.ts14
-rw-r--r--packages/subproviders/src/subproviders/ledger.ts36
-rw-r--r--packages/subproviders/src/subproviders/nonce_tracker.ts24
-rw-r--r--packages/subproviders/src/subproviders/redundant_rpc.ts7
-rw-r--r--packages/subproviders/src/subproviders/subprovider.ts12
-rw-r--r--packages/subproviders/src/types.ts9
11 files changed, 114 insertions, 79 deletions
diff --git a/packages/subproviders/src/globals.d.ts b/packages/subproviders/src/globals.d.ts
index e51801b5c..b3dcd4ed3 100644
--- a/packages/subproviders/src/globals.d.ts
+++ b/packages/subproviders/src/globals.d.ts
@@ -67,16 +67,6 @@ declare module '@ledgerhq/hw-transport-node-hid' {
}
}
-// Semaphore-async-await declarations
-declare module 'semaphore-async-await' {
- class Semaphore {
- constructor(permits: number);
- public wait(): Promise<void>;
- public signal(): void;
- }
- export default Semaphore;
-}
-
// web3-provider-engine declarations
declare module 'web3-provider-engine/subproviders/subprovider' {
class Subprovider {}
@@ -141,3 +131,18 @@ declare module '*.json' {
export default json;
/* tslint:enable */
}
+
+// ganache-core declarations
+declare module 'ganache-core' {
+ import * as Web3 from 'web3';
+ export interface GanacheOpts {
+ verbose: boolean;
+ logger: {
+ log(msg: string): void;
+ };
+ port: number;
+ networkId: number;
+ mnemonic: string;
+ }
+ export function provider(opts: GanacheOpts): Web3.Provider;
+}
diff --git a/packages/subproviders/src/index.ts b/packages/subproviders/src/index.ts
index e22b6f5f3..cafb50fe5 100644
--- a/packages/subproviders/src/index.ts
+++ b/packages/subproviders/src/index.ts
@@ -2,12 +2,15 @@ import Eth from '@ledgerhq/hw-app-eth';
import TransportU2F from '@ledgerhq/hw-transport-u2f';
import { LedgerEthereumClient } from './types';
+export { Callback, NextCallback } from './types';
export { EmptyWalletSubprovider } from './subproviders/empty_wallet_subprovider';
export { FakeGasEstimateSubprovider } from './subproviders/fake_gas_estimate_subprovider';
export { InjectedWeb3Subprovider } from './subproviders/injected_web3';
export { RedundantRPCSubprovider } from './subproviders/redundant_rpc';
export { LedgerSubprovider } from './subproviders/ledger';
+export { GanacheSubprovider } from './subproviders/ganache';
+export { Subprovider } from './subproviders/subprovider';
export { NonceTrackerSubprovider } from './subproviders/nonce_tracker';
export { ECSignature, LedgerWalletSubprovider, LedgerCommunicationClient, NonceSubproviderErrors } from './types';
diff --git a/packages/subproviders/src/subproviders/empty_wallet_subprovider.ts b/packages/subproviders/src/subproviders/empty_wallet_subprovider.ts
index 8c1fdfdb2..f5983dd9b 100644
--- a/packages/subproviders/src/subproviders/empty_wallet_subprovider.ts
+++ b/packages/subproviders/src/subproviders/empty_wallet_subprovider.ts
@@ -1,14 +1,20 @@
-import { JSONRPCPayload } from '@0xproject/types';
+import * as Web3 from 'web3';
+
+import { Subprovider } from './subprovider';
/*
* This class implements the web3-provider-engine subprovider interface and returns
* that the provider has no addresses when queried.
* Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
*/
-export class EmptyWalletSubprovider {
+export class EmptyWalletSubprovider extends Subprovider {
// This method needs to be here to satisfy the interface but linter wants it to be static.
// tslint:disable-next-line:prefer-function-over-method
- public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error | null, result: any) => void) {
+ public handleRequest(
+ payload: Web3.JSONRPCRequestPayload,
+ next: () => void,
+ end: (err: Error | null, result: any) => void,
+ ) {
switch (payload.method) {
case 'eth_accounts':
end(null, []);
@@ -19,9 +25,4 @@ export class EmptyWalletSubprovider {
return;
}
}
- // Required to implement this method despite not needing it for this subprovider
- // tslint:disable-next-line:prefer-function-over-method
- public setEngine(engine: any) {
- // noop
- }
}
diff --git a/packages/subproviders/src/subproviders/fake_gas_estimate_subprovider.ts b/packages/subproviders/src/subproviders/fake_gas_estimate_subprovider.ts
index b455a0ed7..2421dcd02 100644
--- a/packages/subproviders/src/subproviders/fake_gas_estimate_subprovider.ts
+++ b/packages/subproviders/src/subproviders/fake_gas_estimate_subprovider.ts
@@ -1,4 +1,6 @@
-import { JSONRPCPayload } from '@0xproject/types';
+import * as Web3 from 'web3';
+
+import { Subprovider } from './subprovider';
/*
* This class implements the web3-provider-engine subprovider interface and returns
@@ -8,14 +10,19 @@ import { JSONRPCPayload } from '@0xproject/types';
* Source: https://github.com/trufflesuite/ganache-cli/issues/437
* Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
*/
-export class FakeGasEstimateSubprovider {
+export class FakeGasEstimateSubprovider extends Subprovider {
private _constantGasAmount: number;
constructor(constantGasAmount: number) {
+ super();
this._constantGasAmount = constantGasAmount;
}
// This method needs to be here to satisfy the interface but linter wants it to be static.
// tslint:disable-next-line:prefer-function-over-method
- public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error | null, result: any) => void) {
+ public handleRequest(
+ payload: Web3.JSONRPCRequestPayload,
+ next: () => void,
+ end: (err: Error | null, result: any) => void,
+ ) {
switch (payload.method) {
case 'eth_estimateGas':
end(null, this._constantGasAmount);
@@ -26,9 +33,4 @@ export class FakeGasEstimateSubprovider {
return;
}
}
- // Required to implement this method despite not needing it for this subprovider
- // tslint:disable-next-line:prefer-function-over-method
- public setEngine(engine: any) {
- // noop
- }
}
diff --git a/packages/subproviders/src/subproviders/ganache.ts b/packages/subproviders/src/subproviders/ganache.ts
new file mode 100644
index 000000000..a979aecf4
--- /dev/null
+++ b/packages/subproviders/src/subproviders/ganache.ts
@@ -0,0 +1,28 @@
+import * as Ganache from 'ganache-core';
+import * as Web3 from 'web3';
+
+import { Subprovider } from './subprovider';
+
+/*
+ * This class implements the web3-provider-engine subprovider interface and returns
+ * the provider connected to a in-process ganache.
+ * Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
+ */
+export class GanacheSubprovider extends Subprovider {
+ private _ganacheProvider: Web3.Provider;
+ constructor(opts: any) {
+ super();
+ this._ganacheProvider = Ganache.provider(opts);
+ }
+ // This method needs to be here to satisfy the interface but linter wants it to be static.
+ // tslint:disable-next-line:prefer-function-over-method
+ public handleRequest(
+ payload: Web3.JSONRPCRequestPayload,
+ next: () => void,
+ end: (err: Error | null, result: any) => void,
+ ) {
+ this._ganacheProvider.sendAsync(payload, (err: Error | null, result: any) => {
+ end(err, result && result.result);
+ });
+ }
+}
diff --git a/packages/subproviders/src/subproviders/injected_web3.ts b/packages/subproviders/src/subproviders/injected_web3.ts
index 0d70180c4..6d4e2b27b 100644
--- a/packages/subproviders/src/subproviders/injected_web3.ts
+++ b/packages/subproviders/src/subproviders/injected_web3.ts
@@ -1,5 +1,7 @@
import * as _ from 'lodash';
-import Web3 = require('web3');
+import * as Web3 from 'web3';
+
+import { Subprovider } from './subprovider';
/*
* This class implements the web3-provider-engine subprovider interface and forwards
@@ -7,9 +9,10 @@ import Web3 = require('web3');
* provider instance in their browser.
* Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
*/
-export class InjectedWeb3Subprovider {
+export class InjectedWeb3Subprovider extends Subprovider {
private _injectedWeb3: Web3;
constructor(subprovider: Web3.Provider) {
+ super();
this._injectedWeb3 = new Web3(subprovider);
}
public handleRequest(
@@ -40,11 +43,4 @@ export class InjectedWeb3Subprovider {
return;
}
}
- // Required to implement this method despite not needing it for this subprovider
- // The engine argument type should be Web3ProviderEngine, but we've decided to keep it as type any
- // to remove the provider engine depdency given this method is a noop
- // tslint:disable-next-line:prefer-function-over-method
- public setEngine(engine: any) {
- // noop
- }
}
diff --git a/packages/subproviders/src/subproviders/ledger.ts b/packages/subproviders/src/subproviders/ledger.ts
index 0a84caae3..b67b49bee 100644
--- a/packages/subproviders/src/subproviders/ledger.ts
+++ b/packages/subproviders/src/subproviders/ledger.ts
@@ -4,8 +4,8 @@ import EthereumTx = require('ethereumjs-tx');
import ethUtil = require('ethereumjs-util');
import HDNode = require('hdkey');
import * as _ from 'lodash';
-import Semaphore from 'semaphore-async-await';
-import Web3 = require('web3');
+import { Lock } from 'semaphore-async-await';
+import * as Web3 from 'web3';
import {
LedgerEthereumClient,
@@ -24,8 +24,8 @@ const ASK_FOR_ON_DEVICE_CONFIRMATION = false;
const SHOULD_GET_CHAIN_CODE = true;
export class LedgerSubprovider extends Subprovider {
- private _nonceLock: Semaphore;
- private _connectionLock: Semaphore;
+ private _nonceLock = new Lock();
+ private _connectionLock = new Lock();
private _networkId: number;
private _derivationPath: string;
private _derivationPathIndex: number;
@@ -39,8 +39,6 @@ export class LedgerSubprovider extends Subprovider {
}
constructor(config: LedgerSubproviderConfigs) {
super();
- this._nonceLock = new Semaphore(1);
- this._connectionLock = new Semaphore(1);
this._networkId = config.networkId;
this._ledgerEthereumClientFactoryAsync = config.ledgerEthereumClientFactoryAsync;
this._derivationPath = config.derivationPath || DEFAULT_DERIVATION_PATH;
@@ -147,7 +145,7 @@ export class LedgerSubprovider extends Subprovider {
hdKey.publicKey = new Buffer(ledgerResponse.publicKey, 'hex');
hdKey.chainCode = new Buffer(ledgerResponse.chainCode, 'hex');
- const accounts = [];
+ const accounts: string[] = [];
for (let i = 0; i < numberOfAccounts; i++) {
const derivedHDNode = hdKey.derive(`m/${i + this._derivationPathIndex}`);
const derivedPublicKey = derivedHDNode.publicKey;
@@ -221,27 +219,27 @@ export class LedgerSubprovider extends Subprovider {
return derivationPath;
}
private async _createLedgerClientAsync(): Promise<LedgerEthereumClient> {
- await this._connectionLock.wait();
+ await this._connectionLock.acquire();
if (!_.isUndefined(this._ledgerClientIfExists)) {
- this._connectionLock.signal();
+ this._connectionLock.release();
throw new Error(LedgerSubproviderErrors.MultipleOpenConnectionsDisallowed);
}
const ledgerEthereumClient = await this._ledgerEthereumClientFactoryAsync();
- this._connectionLock.signal();
+ this._connectionLock.release();
return ledgerEthereumClient;
}
private async _destroyLedgerClientAsync() {
- await this._connectionLock.wait();
+ await this._connectionLock.acquire();
if (_.isUndefined(this._ledgerClientIfExists)) {
- this._connectionLock.signal();
+ this._connectionLock.release();
return;
}
await this._ledgerClientIfExists.transport.close();
this._ledgerClientIfExists = undefined;
- this._connectionLock.signal();
+ this._connectionLock.release();
}
private async _sendTransactionAsync(txParams: PartialTxParams): Promise<string> {
- await this._nonceLock.wait();
+ await this._nonceLock.acquire();
try {
// fill in the extras
const filledParams = await this._populateMissingTxParamsAsync(txParams);
@@ -253,29 +251,29 @@ export class LedgerSubprovider extends Subprovider {
params: [signedTx],
};
const result = await this.emitPayloadAsync(payload);
- this._nonceLock.signal();
+ this._nonceLock.release();
return result.result;
} catch (err) {
- this._nonceLock.signal();
+ this._nonceLock.release();
throw err;
}
}
private async _signTransactionWithoutSendingAsync(txParams: PartialTxParams): Promise<ResponseWithTxParams> {
- await this._nonceLock.wait();
+ await this._nonceLock.acquire();
try {
// fill in the extras
const filledParams = await this._populateMissingTxParamsAsync(txParams);
// sign it
const signedTx = await this.signTransactionAsync(filledParams);
- this._nonceLock.signal();
+ this._nonceLock.release();
const result = {
raw: signedTx,
tx: txParams,
};
return result;
} catch (err) {
- this._nonceLock.signal();
+ this._nonceLock.release();
throw err;
}
}
diff --git a/packages/subproviders/src/subproviders/nonce_tracker.ts b/packages/subproviders/src/subproviders/nonce_tracker.ts
index d967d40f2..82eab4a9a 100644
--- a/packages/subproviders/src/subproviders/nonce_tracker.ts
+++ b/packages/subproviders/src/subproviders/nonce_tracker.ts
@@ -1,12 +1,12 @@
import * as _ from 'lodash';
+import { BlockParamLiteral } from '@0xproject/types';
import EthereumTx = require('ethereumjs-tx');
import ethUtil = require('ethereumjs-util');
+import * as Web3 from 'web3';
import providerEngineUtils = require('web3-provider-engine/util/rpc-cache-utils');
-import { BlockParamLiteral } from '@0xproject/types';
-
-import { ErrorCallback, JSONRPCPayload, NonceSubproviderErrors, OptionalNextCallback } from '../types';
+import { Callback, ErrorCallback, NextCallback, NonceSubproviderErrors } from '../types';
import { Subprovider } from './subprovider';
@@ -19,7 +19,7 @@ const NONCE_TOO_LOW_ERROR_MESSAGE = 'Transaction nonce is too low';
*/
export class NonceTrackerSubprovider extends Subprovider {
private _nonceCache: { [address: string]: string } = {};
- private static _reconstructTransaction(payload: JSONRPCPayload): EthereumTx {
+ private static _reconstructTransaction(payload: Web3.JSONRPCRequestPayload): EthereumTx {
const raw = payload.params[0];
if (_.isUndefined(raw)) {
throw new Error(NonceSubproviderErrors.EmptyParametersFound);
@@ -28,7 +28,7 @@ export class NonceTrackerSubprovider extends Subprovider {
const transaction = new EthereumTx(rawData);
return transaction;
}
- private static _determineAddress(payload: JSONRPCPayload): string {
+ private static _determineAddress(payload: Web3.JSONRPCRequestPayload): string {
let address: string;
switch (payload.method) {
case 'eth_getTransactionCount':
@@ -48,7 +48,11 @@ export class NonceTrackerSubprovider extends Subprovider {
}
// Required to implement this public interface which doesn't conform to our linting rule.
// tslint:disable-next-line:async-suffix
- public async handleRequest(payload: JSONRPCPayload, next: OptionalNextCallback, end: ErrorCallback): Promise<void> {
+ public async handleRequest(
+ payload: Web3.JSONRPCRequestPayload,
+ next: NextCallback,
+ end: ErrorCallback,
+ ): Promise<void> {
switch (payload.method) {
case 'eth_getTransactionCount':
const requestDefaultBlock = providerEngineUtils.blockTagForPayload(payload);
@@ -58,7 +62,7 @@ export class NonceTrackerSubprovider extends Subprovider {
if (!_.isUndefined(cachedResult)) {
return end(null, cachedResult);
} else {
- return next((requestError: Error | null, requestResult: any, cb: any) => {
+ return next((requestError: Error | null, requestResult: any, cb: Callback) => {
if (_.isNull(requestError)) {
this._nonceCache[address] = requestResult as string;
}
@@ -69,7 +73,7 @@ export class NonceTrackerSubprovider extends Subprovider {
return next();
}
case 'eth_sendRawTransaction':
- return next((sendTransactionError: Error | null, txResult: any, cb: any) => {
+ return next((sendTransactionError: Error | null, txResult: any, cb: Callback) => {
if (_.isNull(sendTransactionError)) {
this._handleSuccessfulTransaction(payload);
} else {
@@ -81,7 +85,7 @@ export class NonceTrackerSubprovider extends Subprovider {
return next();
}
}
- private _handleSuccessfulTransaction(payload: JSONRPCPayload): void {
+ private _handleSuccessfulTransaction(payload: Web3.JSONRPCRequestPayload): void {
const address = NonceTrackerSubprovider._determineAddress(payload);
const transaction = NonceTrackerSubprovider._reconstructTransaction(payload);
// Increment the nonce from the previous successfully submitted transaction
@@ -94,7 +98,7 @@ export class NonceTrackerSubprovider extends Subprovider {
const nextPrefixedHexNonce = `0x${nextHexNonce}`;
this._nonceCache[address] = nextPrefixedHexNonce;
}
- private _handleSendTransactionError(payload: JSONRPCPayload, err: Error): void {
+ private _handleSendTransactionError(payload: Web3.JSONRPCRequestPayload, err: Error): void {
const address = NonceTrackerSubprovider._determineAddress(payload);
if (this._nonceCache[address] && _.includes(err.message, NONCE_TOO_LOW_ERROR_MESSAGE)) {
delete this._nonceCache[address];
diff --git a/packages/subproviders/src/subproviders/redundant_rpc.ts b/packages/subproviders/src/subproviders/redundant_rpc.ts
index 5a94f93d7..0df2f91f4 100644
--- a/packages/subproviders/src/subproviders/redundant_rpc.ts
+++ b/packages/subproviders/src/subproviders/redundant_rpc.ts
@@ -1,16 +1,15 @@
import { promisify } from '@0xproject/utils';
import * as _ from 'lodash';
+import * as Web3 from 'web3';
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
-import { JSONRPCPayload } from '../types';
-
import { Subprovider } from './subprovider';
export class RedundantRPCSubprovider extends Subprovider {
private _rpcs: RpcSubprovider[];
private static async _firstSuccessAsync(
rpcs: RpcSubprovider[],
- payload: JSONRPCPayload,
+ payload: Web3.JSONRPCRequestPayload,
next: () => void,
): Promise<any> {
let lastErr: Error | undefined;
@@ -38,7 +37,7 @@ export class RedundantRPCSubprovider extends Subprovider {
// Required to implement this public interface which doesn't conform to our linting rule.
// tslint:disable-next-line:async-suffix
public async handleRequest(
- payload: JSONRPCPayload,
+ payload: Web3.JSONRPCRequestPayload,
next: () => void,
end: (err: Error | null, data?: any) => void,
): Promise<void> {
diff --git a/packages/subproviders/src/subproviders/subprovider.ts b/packages/subproviders/src/subproviders/subprovider.ts
index 6435c9f65..d4e0de67a 100644
--- a/packages/subproviders/src/subproviders/subprovider.ts
+++ b/packages/subproviders/src/subproviders/subprovider.ts
@@ -1,7 +1,5 @@
import promisify = require('es6-promisify');
-import Web3 = require('web3');
-
-import { JSONRPCPayload } from '../types';
+import * as Web3 from 'web3';
/*
* A version of the base class Subprovider found in providerEngine
* This one has an async/await `emitPayloadAsync` and also defined types.
@@ -19,7 +17,9 @@ export class Subprovider {
// 16 digits
return datePart + extraPart;
}
- private static _createFinalPayload(payload: JSONRPCPayload): Web3.JSONRPCRequestPayload {
+ private static _createFinalPayload(
+ payload: Partial<Web3.JSONRPCRequestPayload> & { method: string },
+ ): Web3.JSONRPCRequestPayload {
const finalPayload = {
// defaults
id: Subprovider._getRandomId(),
@@ -32,7 +32,9 @@ export class Subprovider {
public setEngine(engine: any): void {
this._engine = engine;
}
- public async emitPayloadAsync(payload: JSONRPCPayload): Promise<any> {
+ public async emitPayloadAsync(
+ payload: Partial<Web3.JSONRPCRequestPayload> & { method: string },
+ ): Promise<Web3.JSONRPCResponsePayload> {
const finalPayload = Subprovider._createFinalPayload(payload);
const response = await promisify(this._engine.sendAsync, this._engine)(finalPayload);
return response;
diff --git a/packages/subproviders/src/types.ts b/packages/subproviders/src/types.ts
index f49ac6107..543da5947 100644
--- a/packages/subproviders/src/types.ts
+++ b/packages/subproviders/src/types.ts
@@ -91,11 +91,6 @@ export interface PartialTxParams {
export type DoneCallback = (err?: Error) => void;
-export interface JSONRPCPayload {
- params: any[];
- method: string;
-}
-
export interface LedgerCommunication {
close_async: () => Promise<void>;
}
@@ -118,5 +113,7 @@ export enum NonceSubproviderErrors {
CannotDetermineAddressFromPayload = 'CANNOT_DETERMINE_ADDRESS_FROM_PAYLOAD',
}
-export type OptionalNextCallback = (callback?: (err: Error | null, result: any, cb: any) => void) => void;
export type ErrorCallback = (err: Error | null, data?: any) => void;
+export type Callback = () => void;
+export type OnNextCompleted = (err: Error | null, result: any, cb: Callback) => void;
+export type NextCallback = (callback?: OnNextCompleted) => void;