UNPKG

@tevm/actions

Version:

A typesafe library for writing forge scripts in typescript

105 lines (98 loc) 3.67 kB
import { bytesToHex, getAddress, toHex } from '@tevm/utils' import { createEvmError } from '../internal/createEvmError.js' /** * @internal * Creates an CallHandler for handling call params with Ethereumjs EVM * @param {import('@tevm/vm').RunTxResult & import('@tevm/evm').EvmResult} evmResult * @param {import('@tevm/utils').Hex | undefined} txHash * @param {import('../common/TraceResult.js').TraceResult | undefined} trace * @param {Map<string, Set<string>> | undefined} accessList returned by the evm * @returns {import('./CallResult.js').CallResult} * @throws {never} any error means the input and output types were invalid or some invariant was broken */ export const callHandlerResult = (evmResult, txHash, trace, accessList) => { /** * @type {import('./CallResult.js').CallResult} */ const out = { rawData: bytesToHex(/** @type {any} */ (evmResult).execResult.returnValue), executionGasUsed: /** @type {any} */ (evmResult).execResult.executionGasUsed, } if (trace) { out.trace = trace } if (evmResult.totalGasSpent) { out.totalGasSpent = evmResult.totalGasSpent } if (evmResult.minerValue) { out.minerValue = evmResult.minerValue } if (evmResult.blobGasUsed) { out.blobGasUsed = evmResult.blobGasUsed } if (evmResult.amountSpent) { out.amountSpent = evmResult.amountSpent } if (accessList && evmResult.preimages) { out.preimages = Object.fromEntries( [...evmResult.preimages.entries()].map(([key, value]) => [key, bytesToHex(value)]), ) } if (accessList) { // this might break next ethjs release out.accessList = /** @type {Record<import('@tevm/utils').Address, Set<import('@tevm/utils').Hex>>} */ ( Object.fromEntries( [...accessList.entries()].map(([address, storageKeys]) => { const hexKeys = new Set([...storageKeys].map((key) => `0x${key}`)) return [`0x${address}`, hexKeys] }), ) ) } if (txHash) { out.txHash = txHash } if (/** @type {any} */ (evmResult).execResult.gasRefund) { out.gasRefund = evmResult.gasRefund ?? /** @type {any} */ (evmResult).execResult.gasRefund } if (/** @type {any} */ (evmResult).execResult.selfdestruct) { out.selfdestruct = new Set( [.../** @type {any} */ (evmResult).execResult.selfdestruct].map((address) => getAddress(address)), ) } if (/** @type {any} */ (evmResult).execResult.gas) { out.gas = /** @type {any} */ (evmResult).execResult.gas } if (/** @type {any} */ (evmResult).execResult.logs) { // type Log = [address: Address, topics: Hex[], data: Hex] out.logs = /** @type {any} */ (evmResult).execResult.logs.map( (/** @type {[Uint8Array, Uint8Array[], Uint8Array]} */ log) => { const [address, topics, data] = log return { address: getAddress(toHex(address)), topics: topics.map((/** @type {Uint8Array} */ topic) => toHex(topic)), data: toHex(data), } }, ) } if (/** @type {any} */ (evmResult).execResult.runState) { // don't do anything with runState atm } if (/** @type {any} */ (evmResult).execResult.blobGasUsed) { out.blobGasUsed = /** @type {any} */ (evmResult).execResult.blobGasUsed } if (/** @type {any} */ (evmResult).execResult.exceptionError) { if (out.errors === undefined) { out.errors = [] } out.errors.push(createEvmError(/** @type {any} */ (evmResult).execResult.exceptionError)) } if (/** @type {any} */ (evmResult).execResult.createdAddresses) { out.createdAddresses = new Set([.../** @type {any} */ (evmResult).execResult.createdAddresses].map(getAddress)) } if (/** @type {any} */ (evmResult).createdAddress) { out.createdAddress = getAddress(/** @type {any} */ (evmResult).createdAddress.toString()) } return out }