UNPKG

@owlprotocol/contracts-account-abstraction

Version:

ERC4337 Account Abstraction support for deploying relevant smart contracts and interacting with UserOps.

75 lines (67 loc) 2.77 kB
import { Client, Transport, Chain, Account } from "viem"; import { getAction } from "viem/utils"; import { writeContract, simulateContract, getChainId } from "viem/actions"; import { SendUserOperationReturnType, UserOperation, getUserOperationHash } from "viem/account-abstraction"; import { getSupportedEntryPoints } from "./getSupportedEntryPoints.js"; import { handleOps, errors as IEntryPointErrors } from "../../artifacts/IEntryPoint.js"; import { toPackedUserOperation } from "../../models/PackedUserOperation.js"; import { encodeUserOp } from "../../models/UserOperation.js"; /** * Broadcasts a User Operation to the Bundler. * * - Docs: https://viem.sh/actions/bundler/sendUserOperation * * @param client - Client to use * @param parameters - {@link SendUserOperationParameters} * @returns The User Operation hash. {@link SendUserOperationReturnType} * * @example * import { createBundlerClient, http, parseEther } from 'viem' * import { mainnet } from 'viem/chains' * import { toSmartAccount } from 'viem/accounts' * import { sendUserOperation } from 'viem/actions' * * const account = await toSmartAccount({ ... }) * * const bundlerClient = createBundlerClient({ * chain: mainnet, * transport: http(), * }) * * const values = await sendUserOperation(bundlerClient, { * account, * calls: [{ to: '0x...', value: parseEther('1') }], * }) */ export async function sendUserOperation( client: Client<Transport, Chain | undefined, Account>, parameters: UserOperation<"0.7">, ): Promise<SendUserOperationReturnType> { const chainId = client.chain?.id ?? (await getAction(client, getChainId, "getChainId")({})); const supportedEntryPoints = await getAction(client, getSupportedEntryPoints, "getSupportedEntryPoints")({}); const entryPointAddress = supportedEntryPoints[0]; const userOperation = parameters; const userOpPacked = toPackedUserOperation(encodeUserOp(userOperation)); //types seem to be inferred as [never[], Address] const handleOpsArgs = [[userOpPacked] as any[], client.account.address] as const; const { request } = await getAction( client, simulateContract, "simulateContract", )({ account: client.account, address: entryPointAddress, abi: [handleOps, ...IEntryPointErrors], functionName: "handleOps", args: handleOpsArgs, }); //Submit userOp in background getAction(client, writeContract, "writeContract")({ ...(request as any), abi: [handleOps, ...IEntryPointErrors] }); const userOpHash = getUserOperationHash({ userOperation: userOperation, entryPointAddress: entryPointAddress, entryPointVersion: "0.7", chainId, }); return userOpHash; }