|
| 1 | +<Info>**Required SDK version**: ^v4.59.1</Info> |
| 2 | + |
| 3 | +## Using the `@account-kit/infra` Library for UserOperation Management |
| 4 | + |
| 5 | +The `@account-kit/infra` library enables direct interaction with Alchemy's ERC-4337 bundler for advanced UserOperation management. The `alchemyFeeEstimator` function leverages underlying APIs, including `rundler_maxPriorityFeePerGas` and `eth_estimateUserOperation`, to estimate gas fees for UserOperations. Below are examples demonstrating how to estimate and send a UserOperation and how to retrieve a UserOperation by its hash using low-level Bundler APIs. |
| 6 | + |
| 7 | +<CodeBlocks> |
| 8 | + |
| 9 | +```ts twoslash title="config.ts" |
| 10 | +import { alchemy, sepolia } from "@account-kit/infra"; |
| 11 | + |
| 12 | +const YOUR_API_KEY = "<YOUR_API_KEY>"; |
| 13 | +export const YOUR_PRIVATE_KEY = "<YOUR_PRIVATE_KEY>"; |
| 14 | +export const chain = sepolia; |
| 15 | + |
| 16 | +export const transport = alchemy({ |
| 17 | + apiKey: YOUR_API_KEY, |
| 18 | +}); |
| 19 | +``` |
| 20 | + |
| 21 | +```ts twoslash title="estimateAndSendUserOperation.ts" |
| 22 | +import { alchemyFeeEstimator } from "@account-kit/infra"; |
| 23 | +import { createModularAccountV2Client } from "@account-kit/smart-contracts"; |
| 24 | +import { LocalAccountSigner } from "@aa-sdk/core"; |
| 25 | +import { entryPoint07Address } from "viem/account-abstraction"; |
| 26 | +import { |
| 27 | + chain, |
| 28 | + transport |
| 29 | + YOUR_PRIVATE_KEY, |
| 30 | +} from "./config.ts"; |
| 31 | + |
| 32 | +export async function estimateAndSendUserOperation() { |
| 33 | + const client = await createModularAccountV2Client({ |
| 34 | + signer: LocalAccountSigner.privateKeyToAccountSigner(YOUR_PRIVATE_KEY), |
| 35 | + chain, |
| 36 | + transport, |
| 37 | + feeEstimator: alchemyFeeEstimator(transport), |
| 38 | + }); |
| 39 | + |
| 40 | + try { |
| 41 | + let uo = await client.buildUserOperation({ |
| 42 | + uo: { |
| 43 | + data: "0x", |
| 44 | + target: "0x0000000000000000000000000000000000000000", |
| 45 | + }, |
| 46 | + }); |
| 47 | + const uoWithSig = await client.signUserOperation({ uoStruct: uo }); |
| 48 | + const sendResult = await client.sendRawUserOperation( |
| 49 | + uoWithSig, |
| 50 | + entryPoint07Address, |
| 51 | + ); |
| 52 | + await client.waitForUserOperationTransaction({ |
| 53 | + hash: sendResult, |
| 54 | + retries: { |
| 55 | + intervalMs: 100, |
| 56 | + maxRetries: 600, |
| 57 | + multiplier: 0, |
| 58 | + }, |
| 59 | + }); |
| 60 | + const receipt = await client.getUserOperationReceipt(sendResult); |
| 61 | + console.log("UserOperation receipt:", receipt); |
| 62 | + } catch (error) { |
| 63 | + console.error("Error processing UserOperation:", error); |
| 64 | + } |
| 65 | +} |
| 66 | +``` |
| 67 | + |
| 68 | +```ts twoslash title="getUserOperationByHash.ts" |
| 69 | +import { createAlchemyPublicRpcClient } from "@account-kit/infra"; |
| 70 | +import { chain, transport } from "./config.ts"; |
| 71 | +import type { Hash } from "viem"; |
| 72 | + |
| 73 | +export async function getUserOperationByHash(uoHash: Hash) { |
| 74 | + const client = createAlchemyPublicRpcClient({ |
| 75 | + chain, |
| 76 | + transport, |
| 77 | + }); |
| 78 | + try { |
| 79 | + let userOp = await client.getUserOperationByHash(uoHash); |
| 80 | + console.log("User Operation: ", userOp); |
| 81 | + } catch (error) { |
| 82 | + console.error("Error processing UserOperation:", error); |
| 83 | + } |
| 84 | +} |
| 85 | +``` |
| 86 | + |
| 87 | +</CodeBlocks> |
| 88 | + |
| 89 | +<Info> |
| 90 | + Make sure that you environment is set with your correct `ALCHEMY_API_KEY` and |
| 91 | + `PRIVATE_KEY`. These examples assume familiarity with ERC-4337 and proper |
| 92 | + configuration of the EntryPoint contract (`entryPoint07Address`). |
| 93 | +</Info> |
0 commit comments