Skip to content
Alchemy Logo

Transaction SDK Quickstart

Learn to interact with Wallet APIs

This quickstart shows you how to prepare and send a User Operation (UO) in minutes.

To use this guide, you'll need:

Don't have an API key?

Start using the Alchemy Wallets API today! Get started for free.

@alchemy/wallet-apis (v5.x.x) is the recommended SDK and is currently in beta. If you're still on v4.x.x, see the migration guide.

You're going to need @alchemy/wallet-apis and viem.

npm install @alchemy/wallet-apis viem

This quickstart uses a local private key signer as an example. You can use any viem-compatible signer, including providers like Privy and Turnkey.

import { createSmartWalletClient, alchemyWalletTransport } from "@alchemy/wallet-apis";
import { arbitrumSepolia } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
 
const client = createSmartWalletClient({
  transport: alchemyWalletTransport({
    apiKey: "YOUR_API_KEY",
  }),
  chain: arbitrumSepolia,
  signer: privateKeyToAccount("0xYOUR_PRIVATE_KEY" as const),
  paymaster: {
    policyId: "YOUR_POLICY_ID",
  },
});

The client defaults to EIP-7702, so your EOA will be delegated to a smart account to enable gas sponsorship, batching, and more. The SDK handles delegation automatically on the first transaction.

import { zeroAddress } from "viem";
 
const { id } = await client.sendCalls({
  calls: [{ to: zeroAddress, value: BigInt(0) }],
});

const status = await client.waitForCallsStatus({ id });
const txHash = status.receipts?.[0]?.transactionHash;
console.log(`Explorer: https://sepolia.arbiscan.io/tx/${txHash}`);
Using @account-kit/wallet-client (v4.x.x)?

The examples on this page use @alchemy/wallet-apis (v5.x.x). If you're using @account-kit/wallet-client (v4.x.x), the client setup looks like this:

client.ts (v4.x.x)
import { LocalAccountSigner } from "@aa-sdk/core";
import { createSmartWalletClient } from "@account-kit/wallet-client";
import { alchemy, sepolia } from "@account-kit/infra";
 
const signer = LocalAccountSigner.privateKeyToAccountSigner("0xYOUR_PRIVATE_KEY" as const);
 
export const client = createSmartWalletClient({
  transport: alchemy({ apiKey: "YOUR_API_KEY" }),
  chain: sepolia,
  signer,
  account: signer.address, // can also be passed per action as `from` or `account`
  // Optional: sponsor gas for your users (see "Sponsor gas" guide)
  policyId: "YOUR_POLICY_ID", 
});

Key v4.x.x differences:

  • Account address must be specified on the client or per action (from or account). In v5.x.x, the client automatically uses the signer's address as the account address via EIP-7702.
  • Chain imports come directly from @account-kit/infra instead of viem/chains.
  • Numeric values use hex strings: value: "0x0" instead of value: BigInt(0).
  • In v4.x.x, the paymaster capability on prepareCalls or sendCalls is called paymasterService instead of paymaster, or you can set the policyId directly on the client.
  • Signers use LocalAccountSigner / WalletClientSigner from @aa-sdk/core. In v5.x.x, a viem LocalAccount or WalletClient is used directly.

See the full migration guide for a complete cheat sheet.

Was this page helpful?