Improve all the comments for the subproviders public methods
This commit is contained in:
@@ -24,7 +24,7 @@ export {
|
||||
|
||||
/**
|
||||
* A factory method for creating a LedgerEthereumClient usable in a browser context.
|
||||
* @return LedgerEthereumClient A browser client
|
||||
* @return LedgerEthereumClient A browser client for the LedgerSubprovider
|
||||
*/
|
||||
export async function ledgerEthereumBrowserClientFactoryAsync(): Promise<LedgerEthereumClient> {
|
||||
const ledgerConnection = await TransportU2F.create();
|
||||
|
||||
@@ -4,15 +4,14 @@ import { Callback, ErrorCallback } from '../types';
|
||||
|
||||
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
|
||||
/**
|
||||
* This class implements the [web3-provider-engine](https://github.com/MetaMask/provider-engine) subprovider interface.
|
||||
* It intercepts the `eth_accounts` JSON RPC requests and never returns any addresses when queried.
|
||||
*/
|
||||
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: Web3.JSONRPCRequestPayload, next: Callback, end: ErrorCallback) {
|
||||
// tslint:disable-next-line:prefer-function-over-method underscore-private-and-protected
|
||||
private handleRequest(payload: Web3.JSONRPCRequestPayload, next: Callback, end: ErrorCallback) {
|
||||
switch (payload.method) {
|
||||
case 'eth_accounts':
|
||||
end(null, []);
|
||||
|
||||
@@ -4,23 +4,28 @@ import { Callback, ErrorCallback } from '../types';
|
||||
|
||||
import { Subprovider } from './subprovider';
|
||||
|
||||
/*
|
||||
* This class implements the web3-provider-engine subprovider interface and returns
|
||||
* the constant gas estimate when queried.
|
||||
* HACK: We need this so that our tests don't use testrpc gas estimation which sometimes kills the node.
|
||||
* Source: https://github.com/trufflesuite/ganache-cli/issues/417
|
||||
* Source: https://github.com/trufflesuite/ganache-cli/issues/437
|
||||
* Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
|
||||
// HACK: We need this so that our tests don't use testrpc gas estimation which sometimes kills the node.
|
||||
// Source: https://github.com/trufflesuite/ganache-cli/issues/417
|
||||
// Source: https://github.com/trufflesuite/ganache-cli/issues/437
|
||||
// Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
|
||||
|
||||
/**
|
||||
* This class implements the [web3-provider-engine](https://github.com/MetaMask/provider-engine) subprovider interface.
|
||||
* It intercepts the `eth_estimateGas` JSON RPC call and always returns a constant gas amount when queried.
|
||||
*/
|
||||
export class FakeGasEstimateSubprovider extends Subprovider {
|
||||
private _constantGasAmount: number;
|
||||
/**
|
||||
* Instantiates an instance of the FakeGasEstimateSubprovider
|
||||
* @param constantGasAmount The constant gas amount you want returned
|
||||
*/
|
||||
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: Web3.JSONRPCRequestPayload, next: Callback, end: ErrorCallback) {
|
||||
// tslint:disable-next-line:prefer-function-over-method underscore-private-and-protected
|
||||
private handleRequest(payload: Web3.JSONRPCRequestPayload, next: Callback, end: ErrorCallback) {
|
||||
switch (payload.method) {
|
||||
case 'eth_estimateGas':
|
||||
end(null, this._constantGasAmount);
|
||||
|
||||
@@ -5,20 +5,23 @@ import { Callback, ErrorCallback } from '../types';
|
||||
|
||||
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
|
||||
/**
|
||||
* This class implements the [web3-provider-engine](https://github.com/MetaMask/provider-engine) subprovider interface.
|
||||
* It intercepts all JSON RPC requests and relays them to an in-process ganache instance.
|
||||
*/
|
||||
export class GanacheSubprovider extends Subprovider {
|
||||
private _ganacheProvider: Web3.Provider;
|
||||
/**
|
||||
* Instantiates a GanacheSubprovider
|
||||
* @param opts The desired opts with which to instantiate the Ganache 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: Callback, end: ErrorCallback) {
|
||||
// tslint:disable-next-line:prefer-function-over-method underscore-private-and-protected
|
||||
private handleRequest(payload: Web3.JSONRPCRequestPayload, next: Callback, end: ErrorCallback) {
|
||||
this._ganacheProvider.sendAsync(payload, (err: Error | null, result: any) => {
|
||||
end(err, result && result.result);
|
||||
});
|
||||
|
||||
@@ -5,19 +5,25 @@ import { Callback, ErrorCallback } from '../types';
|
||||
|
||||
import { Subprovider } from './subprovider';
|
||||
|
||||
/*
|
||||
* This class implements the web3-provider-engine subprovider interface and forwards
|
||||
* requests involving user accounts (getAccounts, sendTransaction, etc...) to the injected
|
||||
* provider instance in their browser.
|
||||
* Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
|
||||
/**
|
||||
* This class implements the [web3-provider-engine](https://github.com/MetaMask/provider-engine)
|
||||
* subprovider interface. It forwards JSON RPC requests involving user accounts (getAccounts,
|
||||
* sendTransaction, etc...) to the provider instance supplied at instantiation. All other requests
|
||||
* are passed onwards for subsequent subproviders to handle.
|
||||
*/
|
||||
export class InjectedWeb3Subprovider extends Subprovider {
|
||||
private _injectedWeb3: Web3;
|
||||
constructor(subprovider: Web3.Provider) {
|
||||
/**
|
||||
* Instantiates a new InjectedWeb3Subprovider
|
||||
* @param provider Web3 provider that should handle all user account related requests
|
||||
*/
|
||||
constructor(provider: Web3.Provider) {
|
||||
super();
|
||||
this._injectedWeb3 = new Web3(subprovider);
|
||||
this._injectedWeb3 = new Web3(provider);
|
||||
}
|
||||
public handleRequest(payload: Web3.JSONRPCRequestPayload, next: Callback, end: ErrorCallback) {
|
||||
// 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 underscore-private-and-protected
|
||||
private handleRequest(payload: Web3.JSONRPCRequestPayload, next: Callback, end: ErrorCallback) {
|
||||
switch (payload.method) {
|
||||
case 'web3_clientVersion':
|
||||
this._injectedWeb3.version.getNode(end);
|
||||
|
||||
@@ -24,6 +24,11 @@ const DEFAULT_NUM_ADDRESSES_TO_FETCH = 10;
|
||||
const ASK_FOR_ON_DEVICE_CONFIRMATION = false;
|
||||
const SHOULD_GET_CHAIN_CODE = true;
|
||||
|
||||
/**
|
||||
* Subprovider for interfacing with a user's [Ledger Nano S](https://www.ledgerwallet.com/products/ledger-nano-s).
|
||||
* This subprovider intercepts all account related RPC requests (e.g message/transaction signing, etc...) and
|
||||
* re-routes them to a Ledger device plugged into the users computer.
|
||||
*/
|
||||
export class LedgerSubprovider extends Subprovider {
|
||||
private _nonceLock = new Lock();
|
||||
private _connectionLock = new Lock();
|
||||
@@ -38,6 +43,11 @@ export class LedgerSubprovider extends Subprovider {
|
||||
throw new Error(LedgerSubproviderErrors.SenderInvalidOrNotSupplied);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Instantiates a LedgerSubprovider
|
||||
* @param config Several available configurations
|
||||
* @return LedgerSubprovider instance
|
||||
*/
|
||||
constructor(config: LedgerSubproviderConfigs) {
|
||||
super();
|
||||
this._networkId = config.networkId;
|
||||
@@ -50,18 +60,146 @@ export class LedgerSubprovider extends Subprovider {
|
||||
: ASK_FOR_ON_DEVICE_CONFIRMATION;
|
||||
this._derivationPathIndex = 0;
|
||||
}
|
||||
/**
|
||||
* Retrieve the set derivation path
|
||||
* @returns derivation path
|
||||
*/
|
||||
public getPath(): string {
|
||||
return this._derivationPath;
|
||||
}
|
||||
/**
|
||||
* Set a desired derivation path when computing the available user addresses
|
||||
* @param derivationPath The desired derivation path (e.g `44'/60'/0'`)
|
||||
*/
|
||||
public setPath(derivationPath: string) {
|
||||
this._derivationPath = derivationPath;
|
||||
}
|
||||
/**
|
||||
* Set the final derivation path index. If a user wishes to sign a message with the
|
||||
* 6th address in a derivation path, before calling `signPersonalMessageAsync`, you must
|
||||
* call this method with pathIndex `6`.
|
||||
* @param pathIndex Desired derivation path index
|
||||
*/
|
||||
public setPathIndex(pathIndex: number) {
|
||||
this._derivationPathIndex = pathIndex;
|
||||
}
|
||||
/**
|
||||
* Retrieve a users Ledger accounts. The accounts are derived from the derivationPath,
|
||||
* master public key and chainCode. Because of this, you can request as many accounts
|
||||
* as you wish and it only requires a single request to the Ledger device. This method
|
||||
* is automatically called when issuing a `eth_accounts` JSON RPC request via your providerEngine
|
||||
* instance.
|
||||
* @param numberOfAccounts Number of accounts to retrieve (default: 10)
|
||||
* @return An array of accounts
|
||||
*/
|
||||
public async getAccountsAsync(numberOfAccounts: number = DEFAULT_NUM_ADDRESSES_TO_FETCH): Promise<string[]> {
|
||||
this._ledgerClientIfExists = await this._createLedgerClientAsync();
|
||||
|
||||
let ledgerResponse;
|
||||
try {
|
||||
ledgerResponse = await this._ledgerClientIfExists.getAddress(
|
||||
this._derivationPath,
|
||||
this._shouldAlwaysAskForConfirmation,
|
||||
SHOULD_GET_CHAIN_CODE,
|
||||
);
|
||||
} finally {
|
||||
await this._destroyLedgerClientAsync();
|
||||
}
|
||||
|
||||
const hdKey = new HDNode();
|
||||
hdKey.publicKey = new Buffer(ledgerResponse.publicKey, 'hex');
|
||||
hdKey.chainCode = new Buffer(ledgerResponse.chainCode, 'hex');
|
||||
|
||||
const accounts: string[] = [];
|
||||
for (let i = 0; i < numberOfAccounts; i++) {
|
||||
const derivedHDNode = hdKey.derive(`m/${i + this._derivationPathIndex}`);
|
||||
const derivedPublicKey = derivedHDNode.publicKey;
|
||||
const shouldSanitizePublicKey = true;
|
||||
const ethereumAddressUnprefixed = ethUtil
|
||||
.publicToAddress(derivedPublicKey, shouldSanitizePublicKey)
|
||||
.toString('hex');
|
||||
const ethereumAddressPrefixed = ethUtil.addHexPrefix(ethereumAddressUnprefixed);
|
||||
accounts.push(ethereumAddressPrefixed.toLowerCase());
|
||||
}
|
||||
return accounts;
|
||||
}
|
||||
/**
|
||||
* Sign a transaction with the Ledger. If you've added the LedgerSubprovider to your
|
||||
* app's provider, you can simply send an `eth_sendTransaction` JSON RPC request, and
|
||||
* this method will be called auto-magically. If you are not using this via a ProviderEngine
|
||||
* instance, you can call it directly.
|
||||
* @param txParams Parameters of the transaction to sign
|
||||
* @return Signed transaction hex string
|
||||
*/
|
||||
public async signTransactionAsync(txParams: PartialTxParams): Promise<string> {
|
||||
this._ledgerClientIfExists = await this._createLedgerClientAsync();
|
||||
|
||||
const tx = new EthereumTx(txParams);
|
||||
|
||||
// Set the EIP155 bits
|
||||
tx.raw[6] = Buffer.from([this._networkId]); // v
|
||||
tx.raw[7] = Buffer.from([]); // r
|
||||
tx.raw[8] = Buffer.from([]); // s
|
||||
|
||||
const txHex = tx.serialize().toString('hex');
|
||||
try {
|
||||
const derivationPath = this._getDerivationPath();
|
||||
const result = await this._ledgerClientIfExists.signTransaction(derivationPath, txHex);
|
||||
// Store signature in transaction
|
||||
tx.r = Buffer.from(result.r, 'hex');
|
||||
tx.s = Buffer.from(result.s, 'hex');
|
||||
tx.v = Buffer.from(result.v, 'hex');
|
||||
|
||||
// EIP155: v should be chain_id * 2 + {35, 36}
|
||||
const signedChainId = Math.floor((tx.v[0] - 35) / 2);
|
||||
if (signedChainId !== this._networkId) {
|
||||
await this._destroyLedgerClientAsync();
|
||||
const err = new Error(LedgerSubproviderErrors.TooOldLedgerFirmware);
|
||||
throw err;
|
||||
}
|
||||
|
||||
const signedTxHex = `0x${tx.serialize().toString('hex')}`;
|
||||
await this._destroyLedgerClientAsync();
|
||||
return signedTxHex;
|
||||
} catch (err) {
|
||||
await this._destroyLedgerClientAsync();
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Sign a personal Ethereum signed message. The signing address will be to one
|
||||
* retrieved given a derivationPath and pathIndex set on the subprovider.
|
||||
* The Ledger adds the Ethereum signed message prefix on-device. If you've added
|
||||
* the LedgerSubprovider to your app's provider, you can simply send an `eth_sign`
|
||||
* or `personal_sign` JSON RPC request, and this method will be called auto-magically.
|
||||
* If you are not using this via a ProviderEngine instance, you can call it directly.
|
||||
* @param data Message to sign
|
||||
* @return Signature hex string (order: rsv)
|
||||
*/
|
||||
public async signPersonalMessageAsync(data: string): Promise<string> {
|
||||
this._ledgerClientIfExists = await this._createLedgerClientAsync();
|
||||
try {
|
||||
const derivationPath = this._getDerivationPath();
|
||||
const result = await this._ledgerClientIfExists.signPersonalMessage(
|
||||
derivationPath,
|
||||
ethUtil.stripHexPrefix(data),
|
||||
);
|
||||
const v = result.v - 27;
|
||||
let vHex = v.toString(16);
|
||||
if (vHex.length < 2) {
|
||||
vHex = `0${v}`;
|
||||
}
|
||||
const signature = `0x${result.r}${result.s}${vHex}`;
|
||||
await this._destroyLedgerClientAsync();
|
||||
return signature;
|
||||
} catch (err) {
|
||||
await this._destroyLedgerClientAsync();
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
// Required to implement this public interface which doesn't conform to our linting rule.
|
||||
// tslint:disable-next-line:async-suffix
|
||||
public async handleRequest(
|
||||
// tslint:disable-next-line:async-suffix underscore-private-and-protected
|
||||
private async handleRequest(
|
||||
payload: Web3.JSONRPCRequestPayload,
|
||||
next: Callback,
|
||||
end: (err: Error | null, result?: any) => void,
|
||||
@@ -128,93 +266,6 @@ export class LedgerSubprovider extends Subprovider {
|
||||
return;
|
||||
}
|
||||
}
|
||||
public async getAccountsAsync(numberOfAccounts: number = DEFAULT_NUM_ADDRESSES_TO_FETCH): Promise<string[]> {
|
||||
this._ledgerClientIfExists = await this._createLedgerClientAsync();
|
||||
|
||||
let ledgerResponse;
|
||||
try {
|
||||
ledgerResponse = await this._ledgerClientIfExists.getAddress(
|
||||
this._derivationPath,
|
||||
this._shouldAlwaysAskForConfirmation,
|
||||
SHOULD_GET_CHAIN_CODE,
|
||||
);
|
||||
} finally {
|
||||
await this._destroyLedgerClientAsync();
|
||||
}
|
||||
|
||||
const hdKey = new HDNode();
|
||||
hdKey.publicKey = new Buffer(ledgerResponse.publicKey, 'hex');
|
||||
hdKey.chainCode = new Buffer(ledgerResponse.chainCode, 'hex');
|
||||
|
||||
const accounts: string[] = [];
|
||||
for (let i = 0; i < numberOfAccounts; i++) {
|
||||
const derivedHDNode = hdKey.derive(`m/${i + this._derivationPathIndex}`);
|
||||
const derivedPublicKey = derivedHDNode.publicKey;
|
||||
const shouldSanitizePublicKey = true;
|
||||
const ethereumAddressUnprefixed = ethUtil
|
||||
.publicToAddress(derivedPublicKey, shouldSanitizePublicKey)
|
||||
.toString('hex');
|
||||
const ethereumAddressPrefixed = ethUtil.addHexPrefix(ethereumAddressUnprefixed);
|
||||
accounts.push(ethereumAddressPrefixed.toLowerCase());
|
||||
}
|
||||
return accounts;
|
||||
}
|
||||
public async signTransactionAsync(txParams: PartialTxParams): Promise<string> {
|
||||
this._ledgerClientIfExists = await this._createLedgerClientAsync();
|
||||
|
||||
const tx = new EthereumTx(txParams);
|
||||
|
||||
// Set the EIP155 bits
|
||||
tx.raw[6] = Buffer.from([this._networkId]); // v
|
||||
tx.raw[7] = Buffer.from([]); // r
|
||||
tx.raw[8] = Buffer.from([]); // s
|
||||
|
||||
const txHex = tx.serialize().toString('hex');
|
||||
try {
|
||||
const derivationPath = this._getDerivationPath();
|
||||
const result = await this._ledgerClientIfExists.signTransaction(derivationPath, txHex);
|
||||
// Store signature in transaction
|
||||
tx.r = Buffer.from(result.r, 'hex');
|
||||
tx.s = Buffer.from(result.s, 'hex');
|
||||
tx.v = Buffer.from(result.v, 'hex');
|
||||
|
||||
// EIP155: v should be chain_id * 2 + {35, 36}
|
||||
const signedChainId = Math.floor((tx.v[0] - 35) / 2);
|
||||
if (signedChainId !== this._networkId) {
|
||||
await this._destroyLedgerClientAsync();
|
||||
const err = new Error(LedgerSubproviderErrors.TooOldLedgerFirmware);
|
||||
throw err;
|
||||
}
|
||||
|
||||
const signedTxHex = `0x${tx.serialize().toString('hex')}`;
|
||||
await this._destroyLedgerClientAsync();
|
||||
return signedTxHex;
|
||||
} catch (err) {
|
||||
await this._destroyLedgerClientAsync();
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
public async signPersonalMessageAsync(data: string): Promise<string> {
|
||||
this._ledgerClientIfExists = await this._createLedgerClientAsync();
|
||||
try {
|
||||
const derivationPath = this._getDerivationPath();
|
||||
const result = await this._ledgerClientIfExists.signPersonalMessage(
|
||||
derivationPath,
|
||||
ethUtil.stripHexPrefix(data),
|
||||
);
|
||||
const v = result.v - 27;
|
||||
let vHex = v.toString(16);
|
||||
if (vHex.length < 2) {
|
||||
vHex = `0${v}`;
|
||||
}
|
||||
const signature = `0x${result.r}${result.s}${vHex}`;
|
||||
await this._destroyLedgerClientAsync();
|
||||
return signature;
|
||||
} catch (err) {
|
||||
await this._destroyLedgerClientAsync();
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
private _getDerivationPath() {
|
||||
const derivationPath = `${this.getPath()}/${this._derivationPathIndex}`;
|
||||
return derivationPath;
|
||||
|
||||
@@ -10,13 +10,13 @@ import { Callback, ErrorCallback, NextCallback, NonceSubproviderErrors } from '.
|
||||
|
||||
import { Subprovider } from './subprovider';
|
||||
|
||||
// We do not export this since this is not our error, and we do not throw this error
|
||||
const NONCE_TOO_LOW_ERROR_MESSAGE = 'Transaction nonce is too low';
|
||||
/*
|
||||
This class is heavily inspiried by the Web3ProviderEngine NonceSubprovider
|
||||
We have added the additional feature of clearing any nonce balues when an error message
|
||||
describes a nonce value being too low.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class implements the [web3-provider-engine](https://github.com/MetaMask/provider-engine) subprovider interface.
|
||||
* It is heavily inspired by the [NonceSubprovider](https://github.com/MetaMask/provider-engine/blob/master/subproviders/nonce-tracker.js).
|
||||
* We added the additional feature of clearing the cached nonce value when a `nonce value too low` error occurs.
|
||||
*/
|
||||
export class NonceTrackerSubprovider extends Subprovider {
|
||||
private _nonceCache: { [address: string]: string } = {};
|
||||
private static _reconstructTransaction(payload: Web3.JSONRPCRequestPayload): EthereumTx {
|
||||
@@ -47,8 +47,8 @@ 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(
|
||||
// tslint:disable-next-line:prefer-function-over-method underscore-private-and-protected
|
||||
private async handleRequest(
|
||||
payload: Web3.JSONRPCRequestPayload,
|
||||
next: NextCallback,
|
||||
end: ErrorCallback,
|
||||
|
||||
@@ -7,6 +7,11 @@ import { Callback } from '../types';
|
||||
|
||||
import { Subprovider } from './subprovider';
|
||||
|
||||
/**
|
||||
* This class implements the [web3-provider-engine](https://github.com/MetaMask/provider-engine) subprovider interface.
|
||||
* It attempts to handle each JSON RPC request by sequentially attempting to receive a valid response from one of a
|
||||
* set of JSON RPC endpoints.
|
||||
*/
|
||||
export class RedundantRPCSubprovider extends Subprovider {
|
||||
private _rpcs: RpcSubprovider[];
|
||||
private static async _firstSuccessAsync(
|
||||
@@ -28,6 +33,10 @@ export class RedundantRPCSubprovider extends Subprovider {
|
||||
throw lastErr;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Instantiates a new RedundantRPCSubprovider
|
||||
* @param endpoints JSON RPC endpoints to attempt. Attempts are made in the order of the endpoints.
|
||||
*/
|
||||
constructor(endpoints: string[]) {
|
||||
super();
|
||||
this._rpcs = _.map(endpoints, endpoint => {
|
||||
@@ -37,8 +46,8 @@ 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(
|
||||
// tslint:disable-next-line:prefer-function-over-method underscore-private-and-protected
|
||||
private async handleRequest(
|
||||
payload: Web3.JSONRPCRequestPayload,
|
||||
next: Callback,
|
||||
end: (err: Error | null, data?: any) => void,
|
||||
|
||||
@@ -2,10 +2,9 @@ import promisify = require('es6-promisify');
|
||||
import * as Web3 from 'web3';
|
||||
|
||||
import { JSONRPCRequestPayloadWithMethod } from '../types';
|
||||
/*
|
||||
* A version of the base class Subprovider found in providerEngine
|
||||
/**
|
||||
* A altered version of the base class Subprovider found in [web3-provider-engine](https://github.com/MetaMask/provider-engine).
|
||||
* This one has an async/await `emitPayloadAsync` and also defined types.
|
||||
* Altered version of: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
|
||||
*/
|
||||
export class Subprovider {
|
||||
private _engine: any;
|
||||
@@ -31,9 +30,13 @@ export class Subprovider {
|
||||
};
|
||||
return finalPayload;
|
||||
}
|
||||
public setEngine(engine: any): void {
|
||||
this._engine = engine;
|
||||
}
|
||||
/**
|
||||
* Emits a JSON RPC payload that will then be handled by the ProviderEngine instance
|
||||
* this subprovider is a part of. The payload will cascade down the subprovider middleware
|
||||
* stack until finding the responsible entity for handling the request.
|
||||
* @param payload JSON RPC payload
|
||||
* @returns JSON RPC response payload
|
||||
*/
|
||||
public async emitPayloadAsync(
|
||||
payload: Partial<JSONRPCRequestPayloadWithMethod>,
|
||||
): Promise<Web3.JSONRPCResponsePayload> {
|
||||
@@ -41,4 +44,12 @@ export class Subprovider {
|
||||
const response = await promisify(this._engine.sendAsync, this._engine)(finalPayload);
|
||||
return response;
|
||||
}
|
||||
/**
|
||||
* Set's the subprovider's engine to the ProviderEngine it is added to.
|
||||
* This is only called within the ProviderEngine source code
|
||||
*/
|
||||
// tslint:disable-next-line:underscore-private-and-protected
|
||||
private setEngine(engine: any): void {
|
||||
this._engine = engine;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user