> For the complete documentation index, see [llms.txt](/llms.txt).

# Use an ERC-20 paymaster with Web3Auth

`embedded wallets` `account abstraction` `erc-20 paymaster` `erc-4337` `web3auth`MetaMask Developer Relations | October 29, 2024

Open in Claude

A paymaster is a vital component in the ERC-4337 standard, responsible for covering transaction costs on behalf of the user. There are various types of paymasters, such as gasless paymasters, ERC-20 paymasters, and more.

This guide demonstrates how to use Pimlico's ERC-20 Paymaster with an Embedded Wallets' account abstraction provider to allow your users to pay for their transactions using ERC-20 tokens.

tip

If you are looking to use sponsored paymaster, you can refer to the [sponsored paymaster guide](/tutorials/sending-gasless-transaction/).

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

- Pimlico Account: Since we'll be using the Pimlico paymaster, you'll need to have an API key from Pimlico. You can get a free API key from [Pimlico Dashboard](https://dashboard.pimlico.io/apikeys).
- Embedded Wallets account: If you haven't already, sign up on the [Embedded Wallets dashboard](https://developer.metamask.io/). It's free and gives you access to the base plan.

tip

See the documentation for detailed instructions on [setting up the Embedded Wallets dashboard](/embedded-wallets/dashboard/).

- Web3Auth PnP Web SDK: This guide assumes that you already know how to [integrate the Embedded Wallets SDK in your project](/embedded-wallets/sdk/react/).
- Ensure you have enough USDC balance in the wallet to pay the transaction fees. [Request faucet for USDC tokens](https://faucet.circle.com/).

## Step 1: Integrate `AccountAbstractionProvider`[​](#step-1-integrate-accountabstractionprovider "Direct link to step-1-integrate-accountabstractionprovider")

After you set up the Embedded Wallets dashboard and create a project, integrate the Embedded Wallets account abstraction provider into your web application. For this guide, use the [@web3auth/account-abstraction-provider](https://www.npmjs.com/package/@web3auth/account-abstraction-provider). This package manages the configuration for the account abstraction provider and bundler and prepares user operations.

If you are already using the Embedded Wallets SDK in your project, you just need to configure the `AccountAbstractionProvider` with the paymaster details, and pass it to Embedded Wallets' Web3Auth instance. No other changes are required.

### 1.1 Installation[​](#11-installation "Direct link to 1.1 Installation")

```
npm install --save @web3auth/account-abstraction-provider

```

### 1.2 Configure ERC-20 Paymaster[​](#12-configure-erc-20-paymaster "Direct link to 1.2 Configure ERC-20 Paymaster")

The `AccountAbstractionProvider` requires specific configurations to function correctly. One key configuration is the paymaster. Embedded Wallets supports custom paymaster configurations, allowing you to deploy your own paymaster and integrate it with the provider.

You can choose from a variety of paymaster services available in the ecosystem. In this guide, we'll be configuring the Pimlico's ERC-20 Paymaster. However, it's important to note that paymaster support is not limited to the Pimlico, giving you the flexibility to integrate any compatible paymaster service that suits your requirements.

To configure the ERC-20 Paymaster, you need to pass the `token` in the `paymasterContext` which allows you to specify the ERC-20 token that will be used to pay for the transaction. For this guide, we'll use the USDC token. [Find the USDC token address for your desired network](https://developers.circle.com/stablecoins/docs/usdc-on-test-networks).

For simplicity, we have only used `SafeSmartAccount`, but you choose your favorite smart account provider from the available ones. Learn how to [configure the smart account](/embedded-wallets/sdk/react/advanced/smart-accounts/).

```
import {
  AccountAbstractionProvider,
  SafeSmartAccount,
} from '@web3auth/account-abstraction-provider'

const chainConfig = {
  chainNamespace: CHAIN_NAMESPACES.EIP155,
  chainId: '0xaa36a7',
  rpcTarget: 'https://ethereum-sepolia.publicnode.com',
  displayName: 'Ethereum Sepolia Testnet',
  blockExplorerUrl: 'https://sepolia.etherscan.io',
  ticker: 'ETH',
  tickerName: 'Ethereum',
  logo: 'https://cryptologos.cc/logos/ethereum-eth-logo.png',
}

const accountAbstractionProvider = new AccountAbstractionProvider({
  config: {
    chainConfig,
    bundlerConfig: {
      // Get the pimlico API Key from dashboard.pimlico.io
      url: `https://api.pimlico.io/v2/${chainId}/rpc?apikey=${pimlicoAPIKey}`,
      paymasterContext: {
        // USDC address on Ethereum Sepolia
        token: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',
      },
    },
    smartAccountInit: new SafeSmartAccount(),
    paymasterConfig: {
      // Get the pimlico API Key from dashboard.pimlico.io
      url: `https://api.pimlico.io/v2/${chainId}/rpc?apikey=${pimlicoAPIKey}`,
    },
  },
})

```

## Step 2: Configure Embedded Wallets[​](#step-2-configure-embedded-wallets "Direct link to Step 2: Configure Embedded Wallets")

After you configure `AccountAbstractionProvider`, plug it into your Embedded Wallets modal or no-modal instance. If you use an external wallet such as MetaMask, set `useAAWithExternalWallet` in `IWeb3AuthCoreOptions` to control whether Web3Auth uses `AccountAbstractionProvider` or `EthereumPrivateKeyProvider`.

tip

For the generic web SDK setup, see the [JavaScript SDK guide](/embedded-wallets/sdk/js/).

If you are setting `useAAWithExternalWallet` to `true`, it'll create a new smart account for your user, where the signer/creator of the smart account would be the external wallet.

If you are setting `useAAWithExternalWallet` to `false`, it'll skip creating a new smart account, and directly use the external wallet to sign the transactions.

- PnP Modal SDK
- PnP No Modal SDK

```
import { EthereumPrivateKeyProvider } from "@web3auth/ethereum-provider";
import { Web3Auth } from "@web3auth/modal";

const privateKeyProvider = new EthereumPrivateKeyProvider({
  // Use the chain config we declared earlier
  config: { chainConfig },
});

const web3auth = new Web3Auth({
  clientId: "YOUR_WEB3AUTH_CLIENT_ID", // Pass your Web3Auth Client ID, ideally using an environment variable
  web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
  privateKeyProvider,
  // Use the account abstraction provider we configured earlier
  accountAbstractionProvider
  // This will allow you to use EthereumPrivateKeyProvider for
  // external wallets, while use the AccountAbstractionProvider
  // for Web3Auth embedded wallets.
  useAAWithExternalWallet: false,
});

```

```
import { Web3AuthNoModal } from "@web3auth/no-modal";
import { EthereumPrivateKeyProvider } from "@web3auth/ethereum-provider";
import { AuthAdapter } from "@web3auth/auth-adapter";

const privateKeyProvider = new EthereumPrivateKeyProvider({
  config: { chainConfig },
});

const web3auth = new Web3AuthNoModal({
  clientId: "YOUR_WEB3AUTH_CLIENT_ID", // Pass your Web3Auth Client ID, ideally using an environment variable
  web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
  privateKeyProvider,
  // Use the account abstraction provider we configured earlier
  accountAbstractionProvider
  // This will allow you to use EthereumPrivateKeyProvider for
  // external wallets, while use the AccountAbstractionProvider
  // for Web3Auth embedded wallets.
  useAAWithExternalWallet: false,
});

const authadapter = new AuthAdapter();
web3auth.configureAdapter(authadapter);

```

## Step 3: Send a transaction[​](#step-3-send-a-transaction "Direct link to Step 3: Send a transaction")

To submit the transaction using ERC-20 paymaster, we'll first need to approve an ERC-20 token to be used by the paymaster. Ideally, we should first check the token allowance, and only approve the allowance needed by the paymaster.

To modify the token allowance, you'll need to perform a write operation on the ERC-20 contract. In the example below, we're using Pimlico, but be sure to update the paymaster and ERC-20 token addresses according to your specific case.

Since, we want to perform the approval transaction and send transaction in a single call, we'll use batch transaction feature of the `AccountAbstractionProvider`. Performing a batch transaction differs slightly from the normal flow.

To execute a batch transaction, you'll need to use the `BundlerClient` generated by the `AccountAbstractionProvider`. Embedded Wallets' Web3Auth instance provider can't be used for this, as it's a proxy provider designed to ensure compatibility with your preferred signer package for basic operations.

important

Please make sure you have enough [USDC balance](#prerequisites).

```
// Use the same accountAbstractionProvider we created earlier.
const bundlerClient = accountAbstractionProvider.bundlerClient!
const smartAccount = accountAbstractionProvider.smartAccount!

// Pimlico's ERC-20 Paymaster address
const pimlicoPaymasterAddress = '0x0000000000000039cd5e8aE05257CE51C473ddd1'

// USDC address on Ethereum Sepolia
const usdcAddress = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238'

// 0.00001 ETH in WEI format
const amount = 10000000000000n

// 10 USDC in WEI format. Since USDC has 6 decimals, 10 * 10^6
const approvalAmount = 10000000n

const userOpHash = await bundlerClient.sendUserOperation({
  account: smartAccount,
  calls: [
    // Approve USDC on Sepolia chain for Pimlico's ERC 20 Paymaster
    {
      to: usdcAddress,
      abi: parseAbi(['function approve(address,uint)']),
      functionName: 'approve',
      args: [pimlicoPaymasterAddress, approvalAmount],
    },
    {
      to: 'DESTINATION_ADDRESS',
      value: amount,
      data: '0x',
    },
    {
      to: 'DESTINATION_ADDRESS',
      value: amount,
      data: '0x',
    },
  ],
})

// Retrieve user operation receipt
const receipt = await bundlerClient.waitForUserOperationReceipt({
  hash: userOpHash,
})

const transactionHash = receipt.receipt.transactionHash

```

Congratulations, you have successfully sent your first transaction using the Pimlico's ERC-20 paymaster with Embedded Wallets account abstraction provider.

## Next steps[​](#next-steps "Direct link to Next steps")

Learn more about advance features of the account abstraction provider like:

- Performing batch transactions:

- React
- JavaScript
- Vue

[React smart accounts: batch transactions](/embedded-wallets/sdk/react/advanced/smart-accounts/#send-batch-transaction)

[JS smart accounts: batch transactions](/embedded-wallets/sdk/js/advanced/smart-accounts/#send-batch-transaction)

[Vue smart accounts: batch transactions](/embedded-wallets/sdk/vue/advanced/smart-accounts/#send-batch-transaction)

- Using a sponsored paymaster:

- React
- JavaScript
- Vue

[React smart accounts: configure bundler and paymaster](/embedded-wallets/sdk/react/advanced/smart-accounts/#configure-bundler-and-paymaster)

[JS smart accounts: configure bundler and paymaster](/embedded-wallets/sdk/js/advanced/smart-accounts/#configure-bundler-and-paymaster)

[Vue smart accounts: configure bundler and paymaster](/embedded-wallets/sdk/vue/advanced/smart-accounts/#configure-bundler-and-paymaster)

[Share](https://www.facebook.com/sharer/sharer.php?https://metamask.io/tutorials/erc20-paymaster)[Tweet](http://twitter.com/share?text=Checkout Use an ERC-20 paymaster with Web3Auth published by @MetaMask&url=https://metamask.io/tutorials/erc20-paymaster)Copy

On this page
- [Prerequisites](#prerequisites)
- [Step 1: Integrate AccountAbstractionProvider](#step-1-integrate-accountabstractionprovider)
  - [1.1 Installation](#11-installation)
  - [1.2 Configure ERC-20 Paymaster](#12-configure-erc-20-paymaster)
- [Step 2: Configure Embedded Wallets](#step-2-configure-embedded-wallets)
- [Step 3: Send a transaction](#step-3-send-a-transaction)
- [Next steps](#next-steps)
