Paymasters are smart contracts that pay for the gas fees of transactions on behalf of other accounts.

All paymasters must implement the IPaymaster interface. As outlined in the transaction flow, after the smart contract wallet validates and executes the transaction, it can optionally call prepareForPaymaster to delegate the payment of the gas fees to a paymaster set in the transaction, at which point the paymaster will validate and pay for the transaction.

Get Started with Paymasters

Use our example repositories to quickly get started building paymasters.

Or follow our video tutorial for a step-by-step guide to building a smart contract wallet.

YouTube Video: Build a Paymaster smart contract on Abstract

IPaymaster Interface

The IPaymaster interface defines the mandatory functions that a paymaster must implement to be compatible with Abstract. View source code ↗.

First, install the system contracts library:

Then, import and implement the IPaymaster interface in your smart contract:

import {IPaymaster} from "@matterlabs/zksync-contracts/l2/system-contracts/interfaces/IPaymaster.sol";

contract MyPaymaster is IPaymaster {
  // Implement the interface (see docs below)
    // validateAndPayForPaymasterTransaction
    // postTransaction
}

validateAndPayForPaymasterTransaction

This function is called to perform 2 actions:

  1. Validate (determine whether or not to sponsor the gas fees for) the transaction.
  2. Pay the gas fee to the bootloader for the transaction. This method must send at least tx.gasprice * tx.gasLimit to the bootloader. Learn more about gas fees and gas refunds.

To validate (i.e. agree to sponsor the gas fee for) a transaction, this function should return magic = PAYMASTER_VALIDATION_SUCCESS_MAGIC. Optionally, you can also provide context that is provided to the postTransaction function called after the transaction is executed.

function validateAndPayForPaymasterTransaction(
    bytes32 _txHash,
    bytes32 _suggestedSignedHash,
    Transaction calldata _transaction
) external payable returns (bytes4 magic, bytes memory context);

postTransaction

This function is optional and is called after the transaction is executed. There is no guarantee this method will be called if the transaction fails with out of gas error.

function postTransaction(
    bytes calldata _context,
    Transaction calldata _transaction,
    bytes32 _txHash,
    bytes32 _suggestedSignedHash,
    ExecutionResult _txResult,
    uint256 _maxRefundedGas
) external payable;

Sending Transactions with a Paymaster

Use EIP-712 formatted transactions to submit transactions with a paymaster set. You must specify a customData object containing a valid paymasterParams object.

Paymaster Flows

Below are two example flows for paymasters you can use as a reference to build your own paymaster:

  1. General Paymaster Flow: Showcases a minimal paymaster that sponsors all transactions.
  2. Approval-Based Paymaster Flow: Showcases how users can pay for gas fees with an ERC-20 token.

Smart Contract References