diff options
Diffstat (limited to 'packages/web3-wrapper/src/web3_wrapper.ts')
-rw-r--r-- | packages/web3-wrapper/src/web3_wrapper.ts | 69 |
1 files changed, 63 insertions, 6 deletions
diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index 559bf3ea9..5d2eedcb3 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -2,6 +2,7 @@ import { AbiDecoder, addressUtils, BigNumber, intervalUtils, promisify } from '@ import { BlockParam, BlockWithoutTransactionData, + BlockWithTransactionData, CallData, ContractAbi, FilterObject, @@ -10,8 +11,10 @@ import { LogEntry, Provider, RawLogEntry, + TraceParams, TransactionReceipt, TransactionReceiptWithDecodedLogs, + TransactionTrace, TxData, } from 'ethereum-types'; import * as _ from 'lodash'; @@ -187,12 +190,34 @@ export class Web3Wrapper { * @returns Whether or not contract code was found at the supplied address */ public async doesContractExistAtAddressAsync(address: string): Promise<boolean> { - const code = await promisify<string>(this._web3.eth.getCode)(address); + const code = await this.getContractCodeAsync(address); // Regex matches 0x0, 0x00, 0x in order to accommodate poorly implemented clients const isCodeEmpty = /^0x0{0,40}$/i.test(code); return !isCodeEmpty; } /** + * Gets the contract code by address + * @param address Address of the contract + * @return Code of the contract + */ + public async getContractCodeAsync(address: string): Promise<string> { + const code = await promisify<string>(this._web3.eth.getCode)(address); + return code; + } + /** + * Gets the debug trace of a transaction + * @param txHash Hash of the transactuon to get a trace for + * @param traceParams Config object allowing you to specify if you need memory/storage/stack traces. + * @return Transaction trace + */ + public async getTransactionTraceAsync(txHash: string, traceParams: TraceParams): Promise<TransactionTrace> { + const trace = await this._sendRawPayloadAsync<TransactionTrace>({ + method: 'debug_traceTransaction', + params: [txHash, traceParams], + }); + return trace; + } + /** * Sign a message with a specific address's private key (`eth_sign`) * @param address Address of signer * @param message Message to sign @@ -211,13 +236,30 @@ export class Web3Wrapper { return blockNumber; } /** - * Fetch a specific Ethereum block + * Fetch a specific Ethereum block without transaction data * @param blockParam The block you wish to fetch (blockHash, blockNumber or blockLiteral) * @returns The requested block without transaction data */ public async getBlockAsync(blockParam: string | BlockParam): Promise<BlockWithoutTransactionData> { - const block = await promisify<BlockWithoutTransactionData>(this._web3.eth.getBlock)(blockParam); - return block; + const shouldIncludeTransactionData = false; + const blockWithoutTransactionData = await promisify<BlockWithoutTransactionData>(this._web3.eth.getBlock)( + blockParam, + shouldIncludeTransactionData, + ); + return blockWithoutTransactionData; + } + /** + * Fetch a specific Ethereum block with transaction data + * @param blockParam The block you wish to fetch (blockHash, blockNumber or blockLiteral) + * @returns The requested block with transaction data + */ + public async getBlockWithTransactionDataAsync(blockParam: string | BlockParam): Promise<BlockWithTransactionData> { + const shouldIncludeTransactionData = true; + const blockWithTransactionData = await promisify<BlockWithTransactionData>(this._web3.eth.getBlock)( + blockParam, + shouldIncludeTransactionData, + ); + return blockWithTransactionData; } /** * Fetch a block's timestamp @@ -360,6 +402,21 @@ export class Web3Wrapper { pollingIntervalMs: number = 1000, timeoutMs?: number, ): Promise<TransactionReceiptWithDecodedLogs> { + // Immediately check if the transaction has already been mined. + let transactionReceipt = await this.getTransactionReceiptAsync(txHash); + if (!_.isNull(transactionReceipt)) { + const logsWithDecodedArgs = _.map( + transactionReceipt.logs, + this.abiDecoder.tryToDecodeLogOrNoop.bind(this.abiDecoder), + ); + const transactionReceiptWithDecodedLogArgs: TransactionReceiptWithDecodedLogs = { + ...transactionReceipt, + logs: logsWithDecodedArgs, + }; + return transactionReceiptWithDecodedLogArgs; + } + + // Otherwise, check again every pollingIntervalMs. let wasTimeoutExceeded = false; if (timeoutMs) { setTimeout(() => (wasTimeoutExceeded = true), timeoutMs); @@ -374,7 +431,7 @@ export class Web3Wrapper { return reject(Web3WrapperErrors.TransactionMiningTimeout); } - const transactionReceipt = await this.getTransactionReceiptAsync(txHash); + transactionReceipt = await this.getTransactionReceiptAsync(txHash); if (!_.isNull(transactionReceipt)) { intervalUtils.clearAsyncExcludingInterval(intervalId); const logsWithDecodedArgs = _.map( @@ -469,4 +526,4 @@ export class Web3Wrapper { const decimal = this._web3.toDecimal(hex); return decimal; } -} +} // tslint:disable-line:max-file-line-count |