@ethersproject/abstract-provider#TransactionReceipt TypeScript Examples
The following examples show how to use
@ethersproject/abstract-provider#TransactionReceipt.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: snapshot.ts From trident with GNU General Public License v3.0 | 6 votes |
export async function snapshotGasCost(
x:
| TransactionResponse
| Promise<TransactionResponse>
| ContractTransaction
| Promise<ContractTransaction>
| TransactionReceipt
| Promise<BigNumber>
| BigNumber
| Contract
| Promise<Contract>
): Promise<void> {
const resolved = await x;
if ("deployTransaction" in resolved) {
const receipt = await resolved.deployTransaction.wait();
expect(receipt.gasUsed.toNumber()).toMatchSnapshot();
} else if ("wait" in resolved) {
const waited = await resolved.wait();
expect(waited.gasUsed.toNumber()).toMatchSnapshot();
} else if (BigNumber.isBigNumber(resolved)) {
expect(resolved.toNumber()).toMatchSnapshot();
}
}
Example #2
Source File: Provider.ts From evm-provider.js with Apache License 2.0 | 6 votes |
/**
* Unimplemented, will always fail.
*/
async waitForTransaction(
transactionHash: string,
confirmations?: number,
timeout?: number
): Promise<TransactionReceipt> {
return this._fail('waitForTransaction');
}
Example #3
Source File: base-provider.ts From bodhi.js with Apache License 2.0 | 6 votes |
_getTxReceiptFromCache = async (txHash: string): Promise<TransactionReceipt | null> => {
const targetBlockNumber = this.localMode
? await runWithRetries(this._cache!.getBlockNumber.bind(this._cache!), [txHash])
: this._cache?.getBlockNumber(txHash);
if (!targetBlockNumber) return null;
const targetBlockHash = this.localMode
? await runWithRetries(async () => this.api.rpc.chain.getBlockHash(targetBlockNumber))
: await this.api.rpc.chain.getBlockHash(targetBlockNumber);
return this.getTransactionReceiptAtBlock(txHash, targetBlockHash.toHex());
};
Example #4
Source File: base-provider.ts From bodhi.js with Apache License 2.0 | 6 votes |
_getMinedTXReceipt = async (txHash: string): Promise<TransactionReceipt | TransactionReceiptGQL | null> => {
const txFromCache = await this._getTxReceiptFromCache(txHash);
if (txFromCache) return txFromCache;
const txFromSubql = await this.subql?.getTxReceiptByHash(txHash);
const res = txFromSubql || null;
if (res) {
res.blockNumber = +res.blockNumber;
res.transactionIndex = +res.transactionIndex;
res.gasUsed = BigNumber.from(res.gasUsed);
}
return res;
};
Example #5
Source File: DataProvider.ts From evm-provider.js with Apache License 2.0 | 6 votes |
/**
* Get the transaction receipt for a transaction.
* @param txHash The transaction hash to get the receipt for
* @param resolveBlockNumber The block the transaction was resolved
* @returns A promise resolving to the transaction's receipt
*/
abstract getTransactionReceipt(
txHash: string,
resolveBlockNumber: (
blockTag?: BlockTag | Promise<BlockTag>
) => Promise<number | undefined>
): Promise<TransactionReceipt>;
Example #6
Source File: eip1193-bridge.ts From bodhi.js with Apache License 2.0 | 6 votes |
/**
* Returns the receipt of a transaction by transaction hash. Note That the receipt is not available for pending transactions.
* @param DATA, 32 Bytes - hash of a transaction
* @returns TransactionReceipt, A transaction receipt object, or null when no receipt was found:
*/
async eth_getTransactionReceipt(params: any[]): Promise<TransactionReceipt | null> {
validate([{ type: 'blockHash' }], params);
const res = await this.#provider.getTXReceiptByHash(params[0]);
if (!res) return null;
// @ts-ignore
delete res.byzantium;
// @ts-ignore
delete res.confirmations;
return hexlifyRpcResult(res);
}
Example #7
Source File: DataProvider.ts From bodhi.js with Apache License 2.0 | 6 votes |
/**
* Get the transaction receipt for a transaction.
* @param txHash The transaction hash to get the receipt for
* @param resolveBlockNumber The block the transaction was resolved
* @returns A promise resolving to the transaction's receipt
*/
abstract getTransactionReceipt(
txHash: string,
resolveBlockNumber: (blockTag?: BlockTag | Promise<BlockTag>) => Promise<number | undefined>
): Promise<TransactionReceipt>;
Example #8
Source File: EthService.ts From sakeperp-arbitrageur with BSD 3-Clause "New" or "Revised" License | 5 votes |
static async supervise(
signer: Wallet,
tx: TransactionResponse,
timeout: number,
retry = 3,
): Promise<TransactionReceipt> {
return new Promise((resolve, reject) => {
// Set timeout for sending cancellation tx at double the gas price
const timeoutId = setTimeout(async () => {
const cancelTx = await signer.sendTransaction({
to: signer.address,
value: 0,
gasPrice: tx.gasPrice.mul(2), // TODO Make configurable?
nonce: tx.nonce,
})
await EthService.log.warn(
JSON.stringify({
event: "txCancelling",
params: {
tx: tx.hash,
txGasPrice: tx.gasPrice.toString(),
cancelTx: cancelTx.hash,
cancelTxGasPrice: cancelTx.gasPrice.toString(),
nonce: cancelTx.nonce,
},
}),
)
// Yo dawg I heard you like cancelling tx so
// we put a cancel in your cancel tx so you can supervise while you supervise
if (retry > 0) {
await EthService.supervise(signer, cancelTx, timeout, retry - 1)
} else {
await cancelTx.wait()
}
reject({
reason: "timeout",
tx: tx.hash,
cancelTx: cancelTx.hash,
})
}, timeout)
// Otherwise, resolve normally if the original tx is confirmed
tx.wait().then(result => {
clearTimeout(timeoutId)
resolve(result)
})
})
}
Example #9
Source File: Provider.ts From evm-provider.js with Apache License 2.0 | 5 votes |
async getTransactionReceipt(txHash: string): Promise<TransactionReceipt> {
if (!this.dataProvider) return this._fail('getTransactionReceipt');
return this.dataProvider.getTransactionReceipt(
txHash,
this._resolveBlockNumber
);
}
Example #10
Source File: transactionsUpdater.ts From mStable-apps with GNU Lesser General Public License v3.0 | 5 votes |
TransactionsUpdater = (): null => {
const account = useAccount()
const accountPrev = usePrevious(account)
const provider = useSignerOrProvider()
const blockNumber = useBlockNow()
const state = useTransactionsState()
const { check, finalize, reset } = useTransactionsDispatch()
/**
* Reset transactions state on account change
*/
useEffect(() => {
if (accountPrev !== account) {
reset()
}
}, [account, accountPrev, reset])
/**
* Check pending transaction status on new blocks, and finalize if possible.
*/
useEffect(
(): (() => void) | void => {
if (provider && blockNumber) {
let stale = false
Object.values(state)
.filter(tx => STATUS_NEEDS_CHECK.includes(tx.status) && tx.hash && tx.blockNumber !== blockNumber)
.forEach(tx => {
;(((provider as Signer).provider || provider) as Provider)
.getTransactionReceipt(tx.hash as string)
.then((receipt: TransactionReceipt) => {
if (!stale) {
if (!receipt) {
if (tx?.manifest?.id) {
check(tx.manifest.id, blockNumber)
}
} else {
finalize(tx.manifest, receipt)
}
}
})
.catch(() => {
if (tx?.manifest?.id) {
check(tx.manifest.id, blockNumber)
}
})
})
return () => {
stale = true
}
}
return undefined
},
// `blockNumber` and `provider` should be the only deps; otherwise it will
// check too often.
// eslint-disable-next-line react-hooks/exhaustive-deps
[blockNumber, provider],
)
return null
}
Example #11
Source File: contractCallOutOfGasMock.ts From useDApp with MIT License | 5 votes |
transferOutOfGasMock = (): TransactionResponse => {
return {
wait: (): Promise<TransactionReceipt> => {
return Promise.reject({ reason: 'out of gas' })
},
} as TransactionResponse
}
Example #12
Source File: base-provider.ts From bodhi.js with Apache License 2.0 | 5 votes |
waitForTransaction = (
transactionHash: string,
confirmations?: number,
timeout?: number
): Promise<TransactionReceipt> => throwNotImplemented('waitForTransaction');
Example #13
Source File: base-provider.ts From bodhi.js with Apache License 2.0 | 5 votes |
getTransactionReceipt = async (txHash: string): Promise<TransactionReceipt> => {
// @TODO
// @ts-ignore
return this.getTXReceiptByHash(txHash);
};
Example #14
Source File: base-provider.ts From bodhi.js with Apache License 2.0 | 5 votes |
// @TODO Testing
getTransactionReceiptAtBlock = async (
hashOrNumber: number | string | Promise<string>,
_blockTag: BlockTag | Promise<BlockTag>
): Promise<TransactionReceipt> => {
const blockTag = await this._ensureSafeModeBlockTagFinalization(_blockTag);
hashOrNumber = await hashOrNumber;
const header = await this._getBlockHeader(blockTag);
const blockHash = header.hash.toHex();
const blockNumber = header.number.toNumber();
const [block, blockEvents] = await Promise.all([
this.api.rpc.chain.getBlock(blockHash),
this.queryStorage<Vec<FrameSystemEventRecord>>('system.events', [], blockHash)
]);
const { transactionHash, transactionIndex, extrinsicIndex, isExtrinsicFailed } = getTransactionIndexAndHash(
hashOrNumber,
block.block.extrinsics,
blockEvents
);
const extrinsicEvents = blockEvents.filter(
(event) => event.phase.isApplyExtrinsic && event.phase.asApplyExtrinsic.toNumber() === extrinsicIndex
);
if (isExtrinsicFailed) {
const [dispatchError] = extrinsicEvents[extrinsicEvents.length - 1].event.data as any[];
let message = dispatchError.type;
if (dispatchError.isModule) {
try {
const mod = dispatchError.asModule;
const error = this.api.registry.findMetaError(new Uint8Array([mod.index.toNumber(), mod.error.toNumber()]));
message = `${error.section}.${error.name}: ${error.docs}`;
} catch (error) {
// swallow
}
}
return logger.throwError(`ExtrinsicFailed: ${message}`, Logger.errors.UNKNOWN_ERROR, {
hash: transactionHash,
blockHash
});
}
// @TODO
const evmEvent = findEvmEvent(extrinsicEvents);
if (!evmEvent) {
return logger.throwError(`evm event not found`, Logger.errors.UNKNOWN_ERROR, {
hash: transactionHash,
blockHash
});
}
const transactionInfo = { transactionIndex, blockHash, transactionHash, blockNumber };
const partialTransactionReceipt = getPartialTransactionReceipt(evmEvent);
// to and contractAddress may be undefined
return this.formatter.receipt({
confirmations: (await this._getBlockHeader('latest')).number.toNumber() - blockNumber,
...transactionInfo,
...partialTransactionReceipt,
logs: partialTransactionReceipt.logs.map((log) => ({
...transactionInfo,
...log
}))
}) as any;
};
Example #15
Source File: Provider.ts From evm-provider.js with Apache License 2.0 | 4 votes |
async _resolveTransactionReceipt(
transactionHash: string,
blockHash: string,
from: string
): Promise<TransactionReceipt> {
const detail = await this.scanner.getBlockDetail({
blockHash: blockHash
});
const blockNumber = detail.number;
const extrinsic = detail.extrinsics.find(
({ hash }) => hash === transactionHash
);
if (!extrinsic) {
return logger.throwError(`Transaction hash not found`);
}
const transactionIndex = extrinsic.index;
const events = detail.events.filter(
({ phaseIndex }) => phaseIndex === transactionIndex
);
const findCreated = events.find(
(x) =>
x.section.toUpperCase() === 'EVM' &&
x.method.toUpperCase() === 'CREATED'
);
const findExecuted = events.find(
(x) =>
x.section.toUpperCase() === 'EVM' &&
x.method.toUpperCase() === 'EXECUTED'
);
const result = events.find(
(x) =>
x.section.toUpperCase() === 'SYSTEM' &&
x.method.toUpperCase() === 'EXTRINSICSUCCESS'
);
if (!result) {
return logger.throwError(`Can't find event`);
}
const status = findCreated || findExecuted ? 1 : 0;
const contractAddress = findCreated ? findCreated.args[0] : null;
const to = findExecuted ? findExecuted.args[0] : null;
const logs = events
.filter((e) => {
return (
e.method.toUpperCase() === 'LOG' && e.section.toUpperCase() === 'EVM'
);
})
.map((log, index) => {
return {
transactionHash,
blockNumber,
blockHash,
transactionIndex,
removed: false,
address: log.args[0].address,
data: log.args[0].data,
topics: log.args[0].topics,
logIndex: index
};
});
const gasUsed = BigNumber.from(result.args[0].weight);
return {
to,
from,
contractAddress,
transactionIndex,
gasUsed,
logsBloom: '0x',
blockHash,
transactionHash,
logs,
blockNumber,
confirmations: 4,
cumulativeGasUsed: gasUsed,
byzantium: false,
status,
effectiveGasPrice: BigNumber.from('1'),
type: 0
};
}
Example #16
Source File: Signer.ts From evm-provider.js with Apache License 2.0 | 4 votes |
/**
*
* @param transaction
* @returns A promise that resolves to the transaction's response
*/
async sendTransaction(
_transaction: Deferrable<TransactionRequest>
): Promise<TransactionResponse> {
this._checkProvider('sendTransaction');
const signerAddress = await this.getSubstrateAddress();
const evmAddress = await this.getAddress();
// estimateResources requires the from parameter.
// However, when creating the contract, there is no from parameter in the tx
const transaction = {
from: evmAddress,
..._transaction
};
const resources = await this.provider.estimateResources(transaction);
// Multiply by 3.1
const gasLimit: BigNumber = resources.gas.mul(31).div(10);
let storageLimit: BigNumber;
// If the storage limit is supplied, override it from the estimateResources
if (transaction.customData) {
if ('storageLimit' in transaction.customData) {
storageLimit = transaction.customData.storageLimit;
if (isNumber(storageLimit)) {
storageLimit = BigNumber.from(storageLimit);
}
}
} else {
storageLimit = resources.storage.mul(31).div(10);
}
let totalLimit = await transaction.gasLimit;
if (totalLimit === null || totalLimit === undefined) {
totalLimit = gasLimit.add(storageLimit);
}
transaction.gasLimit = totalLimit;
const tx = await this.populateTransaction(transaction);
const data = tx.data;
const from = tx.from;
if (!data) {
return logger.throwError('Request data not found');
}
if (!from) {
return logger.throwError('Request from not found');
}
let extrinsic: SubmittableExtrinsic<'promise'>;
// @TODO create contract
if (!tx.to) {
extrinsic = this.provider.api.tx.evm.create(
tx.data,
toBN(tx.value),
toBN(gasLimit),
toBN(storageLimit.isNegative() ? 0 : storageLimit)
);
} else {
extrinsic = this.provider.api.tx.evm.call(
tx.to,
tx.data,
toBN(tx.value),
toBN(gasLimit),
toBN(storageLimit.isNegative() ? 0 : storageLimit)
);
}
await extrinsic.signAsync(signerAddress);
return new Promise((resolve, reject) => {
extrinsic
.send((result: SubmittableResult) => {
handleTxResponse(result, this.provider.api)
.then(() => {
resolve({
hash: extrinsic.hash.toHex(),
from: from || '',
confirmations: 0,
nonce: toBN(tx.nonce).toNumber(),
gasLimit: BigNumber.from(tx.gasLimit || '0'),
gasPrice: BigNumber.from(0),
data: dataToString(data),
value: BigNumber.from(tx.value || '0'),
chainId: 13939,
wait: (confirmations?: number): Promise<TransactionReceipt> => {
return this.provider._resolveTransactionReceipt(
extrinsic.hash.toHex(),
result.status.asInBlock.toHex(),
from
);
}
});
})
.catch(({ message, result }) => {
reject(message);
});
})
.catch((error) => {
reject(error && error.message);
});
});
}
Example #17
Source File: Signer.ts From bodhi.js with Apache License 2.0 | 4 votes |
/**
*
* @param transaction
* @returns A promise that resolves to the transaction's response
*/
async sendTransaction(_transaction: Deferrable<TransactionRequest>): Promise<TransactionResponse> {
this._checkProvider('sendTransaction');
const signerAddress = await this.getSubstrateAddress();
const evmAddress = await this.getAddress();
// estimateResources requires the from parameter.
// However, when creating the contract, there is no from parameter in the tx
const transaction = {
from: evmAddress,
..._transaction
};
const resources = await this.provider.estimateResources(transaction);
let gasLimit: BigNumber;
let storageLimit: BigNumber;
let totalLimit = await transaction.gasLimit;
if (totalLimit === null || totalLimit === undefined) {
gasLimit = resources.gas;
storageLimit = resources.storage;
totalLimit = resources.gas.add(resources.storage);
} else {
const estimateTotalLimit = resources.gas.add(resources.storage);
gasLimit = BigNumber.from(totalLimit).mul(resources.gas).div(estimateTotalLimit).add(1);
storageLimit = BigNumber.from(totalLimit).mul(resources.storage).div(estimateTotalLimit).add(1);
}
transaction.gasLimit = totalLimit;
const tx = await this.populateTransaction(transaction);
const data = tx.data;
const from = tx.from;
if (!data) {
return logger.throwError('Request data not found');
}
if (!from) {
return logger.throwError('Request from not found');
}
let extrinsic: SubmittableExtrinsic<'promise'>;
// @TODO create contract
if (!tx.to) {
extrinsic = this.provider.api.tx.evm.create(
tx.data,
toBN(tx.value),
toBN(gasLimit),
toBN(storageLimit.isNegative() ? 0 : storageLimit),
tx.accessList || []
);
} else {
extrinsic = this.provider.api.tx.evm.call(
tx.to,
tx.data,
toBN(tx.value),
toBN(gasLimit),
toBN(storageLimit.isNegative() ? 0 : storageLimit),
tx.accessList || []
);
}
await extrinsic.signAsync(signerAddress);
return new Promise((resolve, reject) => {
extrinsic
.send((result: SubmittableResult) => {
handleTxResponse(result, this.provider.api)
.then(() => {
resolve({
hash: extrinsic.hash.toHex(),
from: from || '',
confirmations: 0,
nonce: toBN(tx.nonce).toNumber(),
gasLimit: BigNumber.from(tx.gasLimit || '0'),
gasPrice: BigNumber.from(1),
data: dataToString(data),
value: BigNumber.from(tx.value || '0'),
chainId: +this.provider.api.consts.evmAccounts.chainId.toString(),
wait: (confirmations?: number): Promise<TransactionReceipt> => {
const hex = result.status.isInBlock
? result.status.asInBlock.toHex()
: result.status.asFinalized.toHex();
return this.provider.getTransactionReceiptAtBlock(extrinsic.hash.toHex(), hex);
}
});
})
.catch(reject);
})
.catch(reject);
});
}