UNPKG

viem

Version:

TypeScript Interface for Ethereum

249 lines • 10.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.prepareUserOperation = prepareUserOperation; const parseAccount_js_1 = require("../../../accounts/utils/parseAccount.js"); const estimateFeesPerGas_js_1 = require("../../../actions/public/estimateFeesPerGas.js"); const getChainId_js_1 = require("../../../actions/public/getChainId.js"); const account_js_1 = require("../../../errors/account.js"); const encodeFunctionData_js_1 = require("../../../utils/abi/encodeFunctionData.js"); const concat_js_1 = require("../../../utils/data/concat.js"); const getAction_js_1 = require("../../../utils/getAction.js"); const getPaymasterData_js_1 = require("../paymaster/getPaymasterData.js"); const getPaymasterStubData_js_1 = require("../paymaster/getPaymasterStubData.js"); const estimateUserOperationGas_js_1 = require("./estimateUserOperationGas.js"); const defaultParameters = [ 'factory', 'fees', 'gas', 'paymaster', 'nonce', 'signature', ]; async function prepareUserOperation(client, parameters_) { const parameters = parameters_; const { account: account_ = client.account, parameters: properties = defaultParameters, stateOverride, } = parameters; if (!account_) throw new account_js_1.AccountNotFoundError(); const account = (0, parseAccount_js_1.parseAccount)(account_); const bundlerClient = client; const paymaster = parameters.paymaster ?? bundlerClient?.paymaster; const paymasterAddress = typeof paymaster === 'string' ? paymaster : undefined; const { getPaymasterStubData, getPaymasterData } = (() => { if (paymaster === true) return { getPaymasterStubData: (parameters) => (0, getAction_js_1.getAction)(bundlerClient, getPaymasterStubData_js_1.getPaymasterStubData, 'getPaymasterStubData')(parameters), getPaymasterData: (parameters) => (0, getAction_js_1.getAction)(bundlerClient, getPaymasterData_js_1.getPaymasterData, 'getPaymasterData')(parameters), }; if (typeof paymaster === 'object') { const { getPaymasterStubData, getPaymasterData } = paymaster; return { getPaymasterStubData: (getPaymasterData && getPaymasterStubData ? getPaymasterStubData : getPaymasterData), getPaymasterData: getPaymasterData && getPaymasterStubData ? getPaymasterData : undefined, }; } return { getPaymasterStubData: undefined, getPaymasterData: undefined, }; })(); const paymasterContext = parameters.paymasterContext ? parameters.paymasterContext : bundlerClient?.paymasterContext; let request = { ...parameters, paymaster: paymasterAddress, sender: account.address, }; const [callData, factory, fees, nonce] = await Promise.all([ (async () => { if (parameters.calls) return account.encodeCalls(parameters.calls.map((call_) => { const call = call_; if (call.abi) return { data: (0, encodeFunctionData_js_1.encodeFunctionData)(call), to: call.to, value: call.value, }; return call; })); return parameters.callData; })(), (async () => { if (!properties.includes('factory')) return undefined; if (parameters.initCode) return { initCode: parameters.initCode }; if (parameters.factory && parameters.factoryData) { return { factory: parameters.factory, factoryData: parameters.factoryData, }; } const { factory, factoryData } = await account.getFactoryArgs(); if (account.entryPoint.version === '0.6') return { initCode: factory && factoryData ? (0, concat_js_1.concat)([factory, factoryData]) : undefined, }; return { factory, factoryData, }; })(), (async () => { if (!properties.includes('fees')) return undefined; if (typeof parameters.maxFeePerGas === 'bigint' && typeof parameters.maxPriorityFeePerGas === 'bigint') return request; if (bundlerClient?.userOperation?.estimateFeesPerGas) { const fees = await bundlerClient.userOperation.estimateFeesPerGas({ account, bundlerClient, userOperation: request, }); return { ...request, ...fees, }; } try { const client_ = bundlerClient.client ?? client; const fees = await (0, getAction_js_1.getAction)(client_, estimateFeesPerGas_js_1.estimateFeesPerGas, 'estimateFeesPerGas')({ chain: client_.chain, type: 'eip1559', }); return { maxFeePerGas: typeof parameters.maxFeePerGas === 'bigint' ? parameters.maxFeePerGas : BigInt(2n * fees.maxFeePerGas), maxPriorityFeePerGas: typeof parameters.maxPriorityFeePerGas === 'bigint' ? parameters.maxPriorityFeePerGas : BigInt(2n * fees.maxPriorityFeePerGas), }; } catch { return undefined; } })(), (async () => { if (!properties.includes('nonce')) return undefined; if (typeof parameters.nonce === 'bigint') return parameters.nonce; return account.getNonce(); })(), ]); if (typeof callData !== 'undefined') request.callData = callData; if (typeof factory !== 'undefined') request = { ...request, ...factory }; if (typeof fees !== 'undefined') request = { ...request, ...fees }; if (typeof nonce !== 'undefined') request.nonce = nonce; if (properties.includes('signature')) { if (typeof parameters.signature !== 'undefined') request.signature = parameters.signature; else request.signature = await account.getStubSignature(request); } if (account.entryPoint.version === '0.6' && !request.initCode) request.initCode = '0x'; let chainId; async function getChainId() { if (chainId) return chainId; if (client.chain) return client.chain.id; const chainId_ = await (0, getAction_js_1.getAction)(client, getChainId_js_1.getChainId, 'getChainId')({}); chainId = chainId_; return chainId; } let isPaymasterPopulated = false; if (properties.includes('paymaster') && getPaymasterStubData && !paymasterAddress && !parameters.paymasterAndData) { const { isFinal = false, sponsor, ...paymasterArgs } = await getPaymasterStubData({ chainId: await getChainId(), entryPointAddress: account.entryPoint.address, context: paymasterContext, ...request, }); isPaymasterPopulated = isFinal; request = { ...request, ...paymasterArgs, }; } if (account.entryPoint.version === '0.6' && !request.paymasterAndData) request.paymasterAndData = '0x'; if (properties.includes('gas')) { if (account.userOperation?.estimateGas) { const gas = await account.userOperation.estimateGas(request); request = { ...request, ...gas, }; } if (typeof request.callGasLimit === 'undefined' || typeof request.preVerificationGas === 'undefined' || typeof request.verificationGasLimit === 'undefined' || (request.paymaster && typeof request.paymasterPostOpGasLimit === 'undefined') || (request.paymaster && typeof request.paymasterVerificationGasLimit === 'undefined')) { const gas = await (0, getAction_js_1.getAction)(bundlerClient, estimateUserOperationGas_js_1.estimateUserOperationGas, 'estimateUserOperationGas')({ account, callGasLimit: 0n, preVerificationGas: 0n, verificationGasLimit: 0n, stateOverride, ...(request.paymaster ? { paymasterPostOpGasLimit: 0n, paymasterVerificationGasLimit: 0n, } : {}), ...request, }); request = { ...request, callGasLimit: request.callGasLimit ?? gas.callGasLimit, preVerificationGas: request.preVerificationGas ?? gas.preVerificationGas, verificationGasLimit: request.verificationGasLimit ?? gas.verificationGasLimit, paymasterPostOpGasLimit: request.paymasterPostOpGasLimit ?? gas.paymasterPostOpGasLimit, paymasterVerificationGasLimit: request.paymasterVerificationGasLimit ?? gas.paymasterVerificationGasLimit, }; } } if (properties.includes('paymaster') && getPaymasterData && !paymasterAddress && !parameters.paymasterAndData && !isPaymasterPopulated) { const paymaster = await getPaymasterData({ chainId: await getChainId(), entryPointAddress: account.entryPoint.address, context: paymasterContext, ...request, }); request = { ...request, ...paymaster, }; } delete request.calls; delete request.parameters; delete request.paymasterContext; if (typeof request.paymaster !== 'string') delete request.paymaster; return request; } //# sourceMappingURL=prepareUserOperation.js.map