Skip to content
Alchemy Logo

Third Party Paymasters

You can sponsor user operations with any paymaster by passing a paymaster option to viem's bundler client. Two approaches:

  • Custom paymaster object — supply your own getPaymasterData / getPaymasterStubData callbacks that call your provider's API.
  • ERC-7677 paymaster — if your provider speaks the ERC-7677 RPC, use viem's createPaymasterClient directly.

import { createBundlerClient } from "viem/account-abstraction";
import { createClient, http } from "viem";
import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
import { sepolia } from "viem/chains";
import { toLightAccount } from "@alchemy/smart-accounts";
 
const rpcClient = createClient({ chain: sepolia, transport: http() });
const owner = privateKeyToAccount(generatePrivateKey());
const account = await toLightAccount({
  client: rpcClient,
  owner,
  version: "v2.0.0",
});
 
const bundlerClient = createBundlerClient({
  account,
  client: rpcClient,
  chain: sepolia,
  transport: http("https://your-bundler.example.com"),
  paymaster: {
    async getPaymasterData(_parameters) {
      // Call your third-party paymaster's API here.
      return {
        paymaster: "0xabc123...",
        paymasterData: "0x",
        paymasterVerificationGasLimit: 100000n,
        paymasterPostOpGasLimit: 50000n,
      };
    },
    async getPaymasterStubData(_parameters) {
      // Stub values used during gas estimation; same shape as above.
      return {
        paymaster: "0xabc123...",
        paymasterData: "0x",
        paymasterVerificationGasLimit: 100000n,
        paymasterPostOpGasLimit: 50000n,
      };
    },
  },
});
 
const hash = await bundlerClient.sendUserOperation({
  calls: [{ to: "0x0000000000000000000000000000000000000000", value: 0n, data: "0x" }],
});

import { createBundlerClient, createPaymasterClient } from "viem/account-abstraction";
import { createClient, http } from "viem";
import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
import { sepolia } from "viem/chains";
import { toLightAccount } from "@alchemy/smart-accounts";
 
const rpcClient = createClient({ chain: sepolia, transport: http() });
const owner = privateKeyToAccount(generatePrivateKey());
const account = await toLightAccount({
  client: rpcClient,
  owner,
  version: "v2.0.0",
});
 
const paymasterClient = createPaymasterClient({
  transport: http("https://your-erc7677-paymaster.example.com"),
});
 
const bundlerClient = createBundlerClient({
  account,
  client: rpcClient,
  chain: sepolia,
  transport: http("https://your-bundler.example.com"),
  paymaster: paymasterClient,
});
 
const hash = await bundlerClient.sendUserOperation({
  calls: [{ to: "0x0000000000000000000000000000000000000000", value: 0n, data: "0x" }],
});
Was this page helpful?