Skip to content
Alchemy Logo

Send parallel transactions

This guide explains how to send multiple parallel transactions. Note that you don't need to send parallel transactions for batching calls. This is for sending new transactions when, for example, there's already a transaction in the mempool for a certain account.

The nonceKey override must fit into a uint152!
@alchemy/wallet-apis (v5.x.x) is currently in beta but is the recommended replacement for @account-kit/wallet-client (v4.x.x). If you run into any issues, please reach out.

Use the nonceOverride capability on the smart wallet client's sendCalls or prepareCalls action.

You'll need the following env variables:

sendParallelCalls.ts
import { client, config } from "./client.ts";
 
const [
  { id: idOne },
  { id: idTwo },
] = await Promise.all([
  client.sendCalls({
    capabilities: {
      paymaster: {
        policyId: config.policyId,
      },
      nonceOverride: {
        nonceKey: "0x01",
      },
    },
    calls: [
      {
        to: "0x0000000000000000000000000000000000000000",
        value: BigInt(0),
        data: "0x",
      },
    ],
  }),
  client.sendCalls({
    capabilities: {
      paymaster: {
        policyId: config.policyId,
      },
      nonceOverride: {
        nonceKey: "0x02",
      },
    },
    calls: [
      {
        to: "0x0000000000000000000000000000000000000000",
        value: BigInt(0),
        data: "0x",
      },
    ],
  }),
]);
 
console.log("sendCalls result:", { idOne, idTwo });
 
const callStatusResults = await Promise.all([
  client.waitForCallsStatus({ id: idOne }),
  client.waitForCallsStatus({ id: idTwo }),
]);
 
console.log("Calls status results:", callStatusResults);
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 owner'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.
  • Owners 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?