Skip to content
Alchemy Logo

Bundler Sponsored Operations

Advanced gas sponsorship. BSOs cover gas for your users' transactions with up to 30% faster execution and automatic retries built in.

Bundler Sponsored Operations (BSO) are the advanced way to cover gas fees for your users' transactions. It's the recommended integration for gas sponsorship: BSO lands transactions faster and retries them automatically and removes the need for an onchain paymaster.

  • Faster execution — up to 30% faster execution vs. standard sponsorship. Improvement varies by chain and network conditions.
  • Automatic retries — transactions are retried automatically to handle gas fluctuation, with no extra integration work. Just tell us how much you're willing to spend per transaction and we will guarantee submission up to that limit.
  • No onchain contracts — no dependency on onchain paymaster infrastructure.
  • Multi-chain — the same policy type works across every supported chain.
  • Centralized control — manage spend limits and rules from the dashboard.

BSOs are supported on every chain where Alchemy offers gas sponsorship, except MegaETH.

See the full Wallet APIs supported chains doc to confirm which chains qualify.

Traditional ERC-4337 sponsorship relies on onchain paymaster contracts, which must be deployed on every network, add onchain verification overhead, and require per-chain balance management.

BSOs instead operate at the bundler level: they use your Gas Manager policy to control spend and remove paymaster contract calls.

We recommend BSO for all teams. Use an onchain paymaster only if you need one for technical reasons or want to let users pay gas with ERC-20 tokens. Onchain paymaster sponsorship and ERC-20 gas payments are available on testnets for all teams. On mainnet they are currently only available to Enterprise teams, with limited exceptions. Email [email protected] to request access.

For low-level ERC-4337 integrations that send user operations with eth_sendUserOperation, the two sponsorship types differ in when the Gas Manager policy is checked:

Paymaster sponsorshipBSO
Policy checkedWhen you request paymaster data, before the user signsWhen the bundler receives the signed user operation (eth_sendUserOperation)
User operation contentsAlready contains the Gas Manager's paymaster signatureGas fee fields are zeroed, and the bundler fills them in
Sponsorship expiryThe paymaster signature expires, so the user operation must be sent within the policy's sponsorship expiry period of when the paymaster data was generatedThe policy's sponsorship expiry period starts when the bundler accepts the user operation, and it must be included in a bundle within that period

With paymaster sponsorship, a call can be approved up front and still be dropped if it is sent after the signature expires. With BSO, eligibility is only decided at send time, so a policy limit that is reached before the user operation is sent causes the send to fail. Once the bundler accepts a BSO user operation, the sponsorship expiry period still applies: if the user operation has not been bundled by then, the bundler drops it.

This table describes user operations. In the Wallet APIs EIP-7702 flow, prepareCalls returns an authorization for the user to sign instead of a user operation, so what the user signs differs from the table above.

  1. Create a BSO Gas Manager policy in your dashboard. Configure:
  • Policy Type: select Bundler Sponsored Operations
  • Max Spend Per UO: the maximum spend per transaction - we will retry up to this limit
  1. Include the policy ID in your requests when sending transactions.

Pass your BSO policy ID as the paymaster option on the smart wallet client. Every call routed through the client is sponsored under that policy, and the SDK takes care of the rest. See sponsorship documentation for more information.

client.ts
import type { Hex } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { baseSepolia } from "viem/chains";
import { createSmartWalletClient, alchemyWalletTransport } from "@alchemy/wallet-apis";
 
export const client = createSmartWalletClient({
  transport: alchemyWalletTransport({
    apiKey: "YOUR_API_KEY",
  }),
  chain: baseSepolia,
  signer: privateKeyToAccount("0xYOUR_PRIVATE_KEY" as Hex),
  // BSO policy for gas sponsorship
  paymaster: { policyId: "YOUR_BSO_POLICY_ID" },
});
 
// Every call routed through the client is sponsored under the BSO policy.
const { id } = await client.sendCalls({
  calls: [{ to: "0x000000000000000000000000000000000000dEaD", data: "0x" }],
});
 
const status = await client.waitForCallsStatus({ id });
console.log(status);

You can also pass the policy ID per-call via capabilities:

const { id } = await client.sendCalls({
  calls: [{ to: "0x000000000000000000000000000000000000dEaD", data: "0x" }],
  capabilities: {
    paymaster: { policyId: "YOUR_BSO_POLICY_ID" },
  },
});

See the Bundler API Quickstart for full examples. Two extra steps are required:

  • Set the x-alchemy-policy-id header on the bundler transport (via fetchOptions.headers).
  • Zero out maxFeePerGas, maxPriorityFeePerGas, and preVerificationGas on the user operation. All three must be zero, the bundler treats that as the signal to cover gas under the BSO policy and fills in the actual values server-side.

No createPaymasterClient is needed, BSOs do not use a paymaster contract.

import { createClient, type Hex } from "viem";
import { createBundlerClient } from "viem/account-abstraction";
import { privateKeyToAccount } from "viem/accounts";
import { worldchain } from "viem/chains";
import { alchemyTransport } from "@alchemy/common";
import { toModularAccountV2 } from "@alchemy/smart-accounts";
import { estimateFeesPerGas } from "@alchemy/aa-infra";
 
const ALCHEMY_API_KEY = process.env.ALCHEMY_API_KEY!;
const POLICY_ID = process.env.POLICY_ID!;
const PRIVATE_KEY = process.env.PRIVATE_KEY! as Hex;
 
// The policy ID rides on the transport's fetch options.
const transport = alchemyTransport({
  apiKey: ALCHEMY_API_KEY,
  fetchOptions: {
    headers: { "x-alchemy-policy-id": POLICY_ID },
  },
});
 
const rpcClient = createClient({ chain: worldchain, transport });
 
const account = await toModularAccountV2({
  client: rpcClient,
  owner: privateKeyToAccount(PRIVATE_KEY),
});
 
const bundlerClient = createBundlerClient({
  account,
  client: rpcClient,
  chain: worldchain,
  transport,
  userOperation: { estimateFeesPerGas },
});
 
// Zero ALL three gas fields, the bundler fills them in.
const hash = await bundlerClient.sendUserOperation({
  calls: [{ to: "0x000000000000000000000000000000000000dEaD", data: "0x" }],
  maxFeePerGas: 0n,
  maxPriorityFeePerGas: 0n,
  preVerificationGas: 0n,
});
 
const receipt = await bundlerClient.waitForUserOperationReceipt({ hash });
console.log("Tx:", receipt.receipt.transactionHash);

When using bundler sponsorship with eth_sendUserOperation:

ConfigurationCU Cost
With BSO sponsorship (x-alchemy-policy-id)3000
Standard (without sponsorship)1000

For more details, see the Compute Unit Costs documentation.

BSO gas is priced as the onchain settlement cost plus a BSO service fee for advanced, prioritized bundling and faster inclusion.

  • A valid API key with Bundler API access
  • A configured Gas Manager policy of type Bundler Sponsored Operations with Max Spend Per UO set
  • Wallet APIs SDK or equivalent setup for creating and signing transactions

Make sure your account has enough sponsorship credits in the Gas Manager dashboard and that Max Spend Per UO is set appropriately. If credits run out or a transaction exceeds Max Spend Per UO, sponsorship fails.

Was this page helpful?