import { getEntryPointVersion } from "permissionless" import type { SmartAccount } from "permissionless/accounts" import type { ENTRYPOINT_ADDRESS_V06_TYPE, ENTRYPOINT_ADDRESS_V07_TYPE, EntryPoint, GetEntryPointVersion, UserOperation } from "permissionless/types" import { deepHexlify } from "permissionless/utils" import type { Address, Chain, Client, Hex, Transport } from "viem" import type { CabPaymasterRpcScheme, GetRpcCabPaymasterStubDataReturnType, RepayTokenInfo, RepayTokens, UserOperationWithBigIntAsHex } from "../../types" import { cabPaymasterAddress } from "../../utils" export type GetCabPaymasterStubDataParameters = { userOperation: UserOperation> entryPoint: TEntryPoint sponsorChain: Chain repayTokens: RepayTokens cabPaymasterAddress?: Address } export type GetCabPaymasterStubDataReturnType = GetEntryPointVersion extends "v0.6" ? { paymasterAndData: Hex repayTokensInfo: RepayTokenInfo[] preVerificationGas?: bigint verificationGasLimit?: bigint callGasLimit?: bigint } : { paymaster: Hex paymasterData: Hex repayTokensInfo: RepayTokenInfo[] paymasterVerificationGasLimit?: bigint paymasterPostOpGasLimit?: bigint preVerificationGas?: bigint verificationGasLimit?: bigint callGasLimit?: bigint } export async function getCabPaymasterStubData< TEntryPoint extends EntryPoint, TChain extends Chain | undefined, TTransport extends Transport = Transport, TSmartAccount extends | SmartAccount | undefined = | SmartAccount | undefined >( client: Client< TTransport, TChain, TSmartAccount, CabPaymasterRpcScheme >, { userOperation, entryPoint, sponsorChain, repayTokens, cabPaymasterAddress: cabPaymasterAddress_ }: GetCabPaymasterStubDataParameters ): Promise> { const paymasterAddress = cabPaymasterAddress_ ?? cabPaymasterAddress const params: [ UserOperationWithBigIntAsHex>, TEntryPoint, number, RepayTokens, Address ] = [ deepHexlify(userOperation) as UserOperationWithBigIntAsHex< GetEntryPointVersion >, entryPoint, sponsorChain.id, repayTokens, paymasterAddress ] const response = await client.request({ method: "pm_getCabPaymasterStubData", params }) const entryPointVersion = getEntryPointVersion(entryPoint) if (entryPointVersion === "v0.6") { const responseV06 = response as GetRpcCabPaymasterStubDataReturnType return { paymasterAndData: responseV06.paymasterAndData, repayTokensInfo: responseV06.repayTokensInfo, preVerificationGas: responseV06.preVerificationGas ? BigInt(responseV06.preVerificationGas) : undefined, verificationGasLimit: responseV06.verificationGasLimit ? BigInt(responseV06.verificationGasLimit) : undefined, callGasLimit: responseV06.callGasLimit ? BigInt(responseV06.callGasLimit) : undefined } as GetCabPaymasterStubDataReturnType } const responseV07 = response as GetRpcCabPaymasterStubDataReturnType return { paymaster: responseV07.paymaster, paymasterData: responseV07.paymasterData, repayTokensInfo: responseV07.repayTokensInfo, preVerificationGas: responseV07.preVerificationGas ? BigInt(responseV07.preVerificationGas) : undefined, verificationGasLimit: responseV07.verificationGasLimit ? BigInt(responseV07.verificationGasLimit) : undefined, callGasLimit: responseV07.callGasLimit ? BigInt(responseV07.callGasLimit) : undefined, paymasterVerificationGasLimit: responseV07.paymasterVerificationGasLimit ? BigInt(responseV07.paymasterVerificationGasLimit) : undefined, paymasterPostOpGasLimit: responseV07.paymasterPostOpGasLimit ? BigInt(responseV07.paymasterPostOpGasLimit) : undefined } as GetCabPaymasterStubDataReturnType }