Set up the ERC-4337 environment

Before building the Paymaster Kit, you need a working ERC-4337 stack. This environment consists of the Bundler, which packages user operations into blocks, and the EntryPoint contract, which validates and executes them. Setting this up correctly ensures your paymaster can interact with the mempool and settle transactions on-chain.

The Paymaster Kit
1
Install the ERC-4337 SDK

Initialize your project directory and install the core SDKs. Run npm install @account-abstraction/contracts @account-abstraction/sdk to pull in the EntryPoint abstraction and the client libraries needed to construct UserOperations. These packages provide the type definitions and helper functions for encoding smart account data.

2
Configure the Bundler Connection

Select a bundler provider that supports ERC-4337. For local development, you can spin up a standalone bundler node. For testing, connect to a public bundler endpoint like those provided by Alchemy or Stackup. Ensure your configuration points to the correct chain ID, as the Bundler must match the network where your EntryPoint is deployed.

3
Deploy the EntryPoint Contract

Deploy the EntryPoint contract to your target network. This is the core contract that your Paymaster Kit will call to pay for gas. You can use the pre-compiled artifacts from the SDK or deploy via a standard deployment script. Mainnet deployment requires careful gas estimation and auditing, so start with a testnet like Sepolia or Base.

4
Verify Network Compatibility

Confirm that your chosen chain supports ERC-4337. Not all EVM chains have active bundler networks or EntryPoint deployments. Check the ERC-4337 documentation for a list of supported networks and their current bundler endpoints. This step prevents runtime errors when your Paymaster attempts to submit operations.

Deploy the Paymaster smart contract

This section walks you through writing and deploying the core Paymaster contract that implements the IPaymaster logic. We will build a minimal ERC-4337 compliant Paymaster that validates user operations and covers gas fees on a testnet.

The Paymaster Kit
1
Define the Paymaster interface

Start by implementing the IPaymaster interface from ERC-4337. Your contract must inherit from PaymasterBase (or implement validatePaymasterUserOp) to handle the pre- and post-operation logic. This interface defines how the bundler interacts with your contract to verify if a user operation should be included in a block.

2
Implement validation logic

Inside validatePaymasterStakeAndBeneficiary, define the rules for accepting transactions. For a basic gasless setup, you might allow any transaction up to a certain gas limit, or restrict it to specific contract calls. Ensure you return the correct context string if you need to execute custom logic during the postOp phase.

3
Handle fund deposits and withdrawals

Your Paymaster must hold funds to pay for gas. Implement a deposit() function that accepts ETH or ERC-20 tokens. Use the withdrawTo() function to move funds out when the balance is low. Without a funded account, the bundler will reject your operations, and users will see transaction failures.

4
Deploy to a testnet

Compile your contract using Hardhat or Foundry. Deploy it to a testnet like Sepolia or Holesky. Verify the source code on Etherscan to ensure transparency. Once deployed, note the contract address, as you will need it to configure your smart account factory and bundler.

Configure gas sponsorship rules

Define when your paymaster covers transaction costs. You can sponsor gas for all users, restrict it to specific wallets, or require users to pay with an ERC-20 token like USDC. The logic you choose balances user experience against your operational costs.

Native Gas Sponsorship

The simplest approach is to cover all gas fees using the native token (ETH, MATIC, etc.). This offers the smoothest experience for users, as they do not need to hold the native currency to transact. However, you must manage the funding of the paymaster account directly. If your paymaster runs out of native tokens, all sponsored transactions will fail.

ERC-20 Token Sponsorship

Allowing users to pay gas with stablecoins like USDC or DAI removes the need for them to acquire native tokens. As noted by Alchemy, ERC-4337 paymasters enable dApps to "pay for gas in ERC-20 tokens" and stablecoins, significantly lowering the barrier to entry for new users. MetaMask also provides tutorials for implementing ERC-20 paymasters with Smart Accounts, demonstrating how to swap user tokens for gas on-chain. This method requires a more complex setup, including a liquidity pool or on-chain swap mechanism to convert the ERC-20 into native gas.

Hybrid and Conditional Logic

You can also combine these methods. For example, sponsor gas for new users to encourage adoption, but require returning users to pay with an ERC-20 token. You can implement balance checks to ensure the user holds a minimum amount of your governance token before allowing free transactions. This approach prevents abuse while maintaining a cost-effective model.

Sponsorship TypeUser ExperienceOperational CostImplementation Complexity
Native GasSeamless (no token needed)High (dapp pays 100%)Low
ERC-20 TokenGood (requires token hold)Low (user pays)High
HybridFlexibleVariableMedium-High

Integrate the Paymaster with a Frontend Wallet

To enable gasless transactions, your frontend must be configured to route user operations through your deployed Paymaster contract. This process involves setting up a Smart Account provider that recognizes your Paymaster as a sponsor for specific transaction types. The most common implementation uses MetaMask Smart Accounts, which provides a standardized interface for ERC-4337 account abstraction.

1. Install the Required SDKs

Begin by installing the MetaMask Smart Account SDK and the appropriate bundler client. The SDK handles the signing and packaging of user operations, while the bundler client submits these operations to the EntryPoint contract. You will also need the Paymaster SDK to generate the necessary sponsorship data.

Shell
npm install @metamask/smart-account @account-abstraction/sdk @account-abstraction/contracts

2. Configure the Smart Account Provider

Initialize the Smart Account provider by connecting it to your RPC endpoint and specifying the Paymaster address. This configuration tells the wallet to attach your Paymaster’s signature to outgoing transactions. Ensure you are using the correct chain ID and EntryPoint address for your deployment.

JavaScript
import { createSmartAccountClient } from "@metamask/smart-account";
import { PaymasterClient } from "@account-abstraction/paymaster";

const paymasterClient = new PaymasterClient({
  paymasterAddress: "0xYourPaymasterAddress",
  bundlerUrl: "https://bundler.yourprovider.com",
});

const smartAccount = await createSmartAccountClient({
  signer: userWalletSigner,
  paymaster: paymasterClient,
  // ... other config
});

3. Execute a Gasless Transaction

Once configured, send transactions as you normally would. The Smart Account SDK automatically detects that the target contract or action qualifies for sponsorship and includes the Paymaster’s data in the UserOperation. The user will sign the transaction with their private key, but the gas fees will be paid by your Paymaster contract.

For detailed implementation examples, refer to the MetaMask ERC-20 Paymaster tutorial, which demonstrates how to handle specific token-based sponsorship logic.

4. Verify Transaction Success

Monitor the transaction receipt to ensure the Paymaster successfully covered the gas fees. If the transaction fails, check the bundler’s error logs for common issues such as insufficient Paymaster balance or invalid sponsorship data. Use a block explorer to verify that the Paymaster contract was called correctly.

The Paymaster Kit
1
Install SDKs

Install the MetaMask Smart Account SDK and Account Abstraction packages to handle user operations and Paymaster interactions.

2
Configure Provider

Initialize the Smart Account client with your Paymaster address and bundler URL to enable automatic sponsorship.

3
Execute Transaction

Send transactions normally; the SDK attaches Paymaster data to the UserOperation for gasless execution.

4
Verify Success

Check the transaction receipt and bundler logs to confirm the Paymaster covered the gas fees successfully.

Test for fraud and gas limits

A Paymaster that doesn’t cap costs or verify users is a liability. Without safeguards, your contract can be drained by spam or a single malicious actor consuming all available gas. You must implement strict limits on gas usage and enforce identity checks to prevent abuse.

Set maximum gas caps

Define a hard limit on the amount of gas your Paymaster will sponsor per transaction. This prevents a single user from executing a complex, gas-heavy operation that drains your treasury. Set this cap based on the average cost of a standard transaction on your target chain, adding a small buffer for network volatility.

Implement rate limiting

Apply rate limiting to your Paymaster endpoints. Restrict the number of sponsored transactions a single user address can submit within a specific time window (e.g., 10 transactions per hour). This stops automated bots from flooding the network and ensures fair access for genuine users.

Verify user eligibility

Before sponsoring a transaction, verify that the user meets your eligibility criteria. This could involve checking if they hold a specific token, have passed a KYC check, or are part of a specific community. Use a reliable oracle or on-chain verification method to confirm these conditions instantly.

Pre-deployment security checklist

  • Set gas cap per transaction
  • Apply rate limiting per user address
  • Verify user eligibility criteria
  • Test with spam transactions
  • Monitor gas consumption in real-time

Test your Paymaster against edge cases. Try submitting transactions with minimal gas, excessive gas, and invalid signatures. Monitor your contract’s gas consumption in real-time to ensure your caps are effective. Adjust limits based on observed usage patterns to balance security with user experience.

Frequently asked: what to check next