UNPKG

ethers-tools

Version:

Contains tools for work with web3 contracts.

155 lines (141 loc) 4.29 kB
import { config } from '../config.js'; import { checkSignals, createTimeoutSignal } from '../utils/index.js'; /** * @param {import('ethers').Provider} provider * @param {import('ethers').Signer} signer * @param {import('ethers').Contract} contract * @param {string} method * @param {any[]} [args=[]] * @param {import('../../types/entities').PriorityCallOptions} [options={}] * @returns {Promise<import('ethers').TransactionResponse>} */ export const priorityCall = async ( provider, signer, contract, method, args = [], options = {} ) => { const txn = await formTx(provider, signer, contract, method, args, options); return signer.sendTransaction(txn); }; /** * @param {import('ethers').Provider} provider * @param {import('ethers').Signer} signer * @param {import('ethers').Contract} contract * @param {string} method * @param {any[]} [args=[]] * @param {import('../../types/entities').PriorityCallOptions} [options={}] * @returns {Promise<bigint>} */ export const priorityCallEstimate = async ( provider, signer, contract, method, args = [], options = {} ) => { const txn = await formTx(provider, signer, contract, method, args, options); return signer.estimateGas(txn); }; /** * @param {import('ethers').Provider} provider * @param {import('ethers').Signer} signer * @param {import('ethers').Contract} contract * @param {string} method * @param {any[]} [args=[]] * @param {import('../../types/entities').PriorityCallOptions} [options={}] * @returns {Promise<import('ethers').TransactionLike<string>>} */ const formTx = async ( provider, signer, contract, method, args = [], options = {} ) => { const localOptions = { multiplier: config.priorityCalls.multiplier, ...options, }; const localSignals = []; if (localOptions.signals) localSignals.push(...localOptions.signals); if (localOptions.timeoutMs) localSignals.push(createTimeoutSignal(localOptions.timeoutMs)); checkSignals(localSignals); const [originalFeeData, originalGasLimit] = await gatherOriginalData( provider, contract, method, args, localOptions.parallelFeeRequests, localSignals, localOptions.overrides ); const maxFeePerGas = Math.ceil( localOptions.multiplier * Number(originalFeeData.maxFeePerGas) ); const maxPriorityFeePerGas = Math.ceil( localOptions.multiplier * Number(originalFeeData.maxPriorityFeePerGas) ); const gasLimit = Math.ceil( localOptions.multiplier * Number(originalGasLimit) ); checkSignals(localSignals); const txn = await contract.getFunction(method).populateTransaction(...args, { ...(localOptions.overrides || {}), gasLimit, maxFeePerGas, maxPriorityFeePerGas, }); // Prevents conflicts when using signer.sendTransaction(txn), as the signer should determine the from address. // Avoids potential issues if from is incorrectly set or differs from the signer's address. delete txn.from; if (localOptions.autoDetectChainId) { checkSignals(localSignals); const network = await provider.getNetwork(); txn.chainId = network.chainId; } else { if (localOptions.chainId) txn.chainId = localOptions.chainId; } return txn; }; /** * @param {import('ethers').Provider} provider * @param {import('ethers').Contract} contract * @param {string} method * @param {any[]} [args] * @param {boolean} parallelFeeRequests * @param {AbortSignal[]} signals * @param {import('../../types/entities').Overrides} [overrides] * @returns {Promise<[import('ethers').FeeData, bigint]>} */ const gatherOriginalData = async ( provider, contract, method, args, parallelFeeRequests, signals, overrides ) => { const estimateArgs = overrides ? [...args, overrides] : args; let originalFeeData, originalGasLimit; checkSignals(signals); if (parallelFeeRequests) { [originalFeeData, originalGasLimit] = await Promise.all([ provider.getFeeData(), contract.getFunction(method).estimateGas(...estimateArgs), ]); return [originalFeeData, originalGasLimit]; } originalFeeData = await provider.getFeeData(); checkSignals(signals); originalGasLimit = await contract .getFunction(method) .estimateGas(...estimateArgs); return [originalFeeData, originalGasLimit]; };