Skip to main content
This page is for app and agent developers who want users to transact without holding CELO, through an ERC-4337 smart account whose gas a paymaster pays. Pimlico runs a bundler and paymasters on Celo mainnet and Celo Sepolia. If your users already have an externally owned account and you only want them to pay gas in a stablecoin, you do not need a bundler at all: use fee abstraction.

Prerequisites

  • A Pimlico API key from the Pimlico dashboard. Sponsoring on mainnet needs a Pimlico paid plan with a card or balance; on Celo Sepolia sponsorship is free. A sponsorship policy is optional and only caps what you sponsor.
  • Node.js 18 or later and a TypeScript project set up as an ES module: set "type": "module" in package.json or save the script as .mts, because the example uses top-level await.
  • permissionless and viem:

How it works

Your app builds a user operation for a smart account, sends it to Pimlico’s bundler, and attaches Pimlico’s paymaster so the paymaster deposit covers the gas instead of the account. The bundler submits the user operation to the EntryPoint contract on Celo. Pimlico supports EntryPoint v0.6 and v0.7 on both Celo networks; the example below uses v0.7, which is the current default in permissionless.js. The bundler and paymaster URL is the same for both networks, with the chain in the path:

Send a sponsored transaction

The script creates a smart account owned by a private key, then sends a transaction whose gas Pimlico pays. The smart account is deployed with its first user operation; the owner never needs CELO.
OWNER_PRIVATE_KEY is the key that controls the smart account; keep it in an environment variable, never in source. The owner address needs no balance. To use a Safe smart account instead of the reference SimpleAccount, replace toSimpleSmartAccount with toSafeSmartAccount from permissionless/accounts and pass owners: [privateKeyToAccount(...)] and version: "1.4.1". Safe 1.4.1 and the Safe 4337 module are deployed on both Celo networks.

Let users pay gas in USDC or USDâ‚®

Pimlico’s ERC-20 paymaster charges the smart account in a token instead of sponsoring. It is available on Celo mainnet only, not on Celo Sepolia, and on Pimlico’s custom plan: Pimlico’s pricing includes the ERC-20 paymaster on pay-as-you-go only for USDC on Ethereum, Polygon, Base, Optimism and Arbitrum. Contact Pimlico to enable it for Celo tokens such as USDC and USD₮; see Pimlico’s supported tokens for the current list and addresses. Follow Pimlico’s ERC-20 paymaster guide and set the Celo chain in the URL as above. This is the smart-account equivalent of fee abstraction, which does the same for externally owned accounts at the protocol level.

Troubleshooting

  • AA21 didn't pay prefund or a similar insufficient-funds error: the paymaster was not attached. Check that paymaster: pimlicoClient is set. On mainnet, check that your Pimlico plan has a balance or card attached. If you created a sponsorship policy and pass its ID, check that it covers the chain.
  • chain not supported from the Pimlico endpoint: the chain in the URL is wrong. Use 42220 or celo for mainnet and 11142220 or celo-sepolia for the testnet.
  • Gas estimation reverts on the first transaction: the smart account is deployed in that same user operation, so the to contract must accept calls from a fresh address. Test with a zero-value call to your own contract first.
  • The transaction hash does not appear on the explorer: the bundler returns the user operation hash first. sendTransaction in permissionless waits for inclusion and returns the on-chain transaction hash; if you call sendUserOperation directly, wait with waitForUserOperationReceipt.

Resources