viem-tracer
Version:
[![npm package][npm-img]][npm-url] [![Build Status][build-img]][build-url] [![Downloads][downloads-img]][downloads-url] [![Issues][issues-img]][issues-url] [![Commitizen Friendly][commitizen-img]][commitizen-url] [![Semantic Release][semantic-release-img]
94 lines (93 loc) • 3.77 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.traceCall = traceCall;
const viem_1 = require("viem");
const accounts_1 = require("viem/accounts");
const actions_1 = require("viem/actions");
const experimental_1 = require("viem/experimental");
const utils_1 = require("viem/utils");
/**
* Traces a call.
*
* - JSON-RPC Methods: [`debug_traceCall`](https://www.quicknode.com/docs/ethereum/debug_traceCall)
*
* @param client - Client to use
* @param parameters - {@link TraceCallParameters}
* @returns The call trace. {@link RpcCallTrace}
*
* @example
* import { createPublicClient, http, parseEther } from 'viem'
* import { mainnet } from 'viem/chains'
* import { traceCall } from 'viem-tracer'
*
* const client = createPublicClient({
* chain: mainnet,
* transport: http(),
* })
* const gasEstimate = await traceCall(client, {
* account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* value: parseEther('1'),
* })
*/
async function traceCall(client, { tracer = "callTracer", tracerConfig, ...args }) {
const account_ = args.account ?? client.account;
const account = account_ ? (0, accounts_1.parseAccount)(account_) : null;
try {
const { accessList, authorizationList, blobs, blobVersionedHashes, blockNumber, blockTag = "latest", data, gas, gasPrice, maxFeePerBlobGas, maxFeePerGas, maxPriorityFeePerGas, nonce, value, ...tx } = (await (0, actions_1.prepareTransactionRequest)(client, {
// biome-ignore lint/suspicious/noExplicitAny: not inferred correctly
...args,
parameters: ["blobVersionedHashes", "chainId", "fees", "nonce", "type"],
}));
const blockNumberHex = blockNumber ? (0, viem_1.numberToHex)(blockNumber) : undefined;
const block = blockNumberHex || blockTag;
const to = await (async () => {
// If `to` exists on the parameters, use that.
if (tx.to)
return tx.to;
// If no `to` exists, and we are sending a EIP-7702 transaction, use the
// address of the first authorization in the list.
if (authorizationList && authorizationList.length > 0)
return await (0, experimental_1.recoverAuthorizationAddress)({
authorization: authorizationList[0],
}).catch(() => {
throw new viem_1.BaseError("`to` is required. Could not infer from `authorizationList`");
});
// Otherwise, we are sending a deployment transaction.
return undefined;
})();
(0, viem_1.assertRequest)(args);
const chainFormat = client.chain?.formatters?.transactionRequest?.format;
const format = chainFormat || viem_1.formatTransactionRequest;
const request = format({
// Pick out extra data that might exist on the chain's transaction request type.
...(0, utils_1.extract)(tx, { format: chainFormat }),
from: account?.address,
accessList,
authorizationList,
blobs,
blobVersionedHashes,
data,
gas,
gasPrice,
maxFeePerBlobGas,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
to,
value,
});
const trace = await client.request({
method: "debug_traceCall",
params: [request, block, { tracer, tracerConfig }],
}, { retryCount: 0 });
return trace;
}
catch (err) {
throw (0, utils_1.getTransactionError)(err, {
...args,
account,
chain: client.chain,
});
}
}