> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abs.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Paymasters

> Learn how paymasters are built following the IPaymaster standard on Abstract.

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

All paymasters must implement the
[IPaymaster](#ipaymaster-interface) interface. As outlined in the [transaction flow](/how-abstract-works/native-account-abstraction/transaction-flow),
after the [smart contract wallet](/how-abstract-works/native-account-abstraction/smart-contract-wallets) 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](#validateandpayforpaymastertransaction).

## Get Started with Paymasters

Use our [example repositories](https://github.com/Abstract-Foundation/examples)
to quickly get started building paymasters.

<CardGroup cols={1}>
  <Card title="Paymasters Example Repo" icon="github" href="https://github.com/Abstract-Foundation/examples/tree/main/paymasters">
    Use our example repository to quickly get started building paymasters on
    Abstract.
  </Card>
</CardGroup>

Or follow our [video tutorial](https://www.youtube.com/watch?v=oolgV2M8ZUI) for a step-by-step guide to building a smart contract wallet.

<Card title="YouTube Video: Build a Paymaster smart contract on Abstract" icon="youtube" href="https://www.youtube.com/watch?v=oolgV2M8ZUI" />

## IPaymaster Interface

The `IPaymaster` interface defines the mandatory functions that a paymaster must implement to be
compatible with Abstract. [View source code ↗](https://github.com/matter-labs/era-contracts/blob/main/system-contracts/contracts/interfaces/IPaymaster.sol).

First, install the [system contracts library](/how-abstract-works/system-contracts/using-system-contracts#installing-system-contracts):

<CodeGroup>
  ```bash Hardhat theme={null}
  npm install @matterlabs/zksync-contracts
  ```

  ```bash Foundry theme={null}
  forge install matter-labs/era-contracts
  ```
</CodeGroup>

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

```solidity theme={null}
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](/how-abstract-works/evm-differences/gas-fees).

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.

```solidity theme={null}
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.

```solidity theme={null}
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](https://eips.ethereum.org/EIPS/eip-712) formatted transactions to submit transactions with a paymaster set.
You must specify a `customData` object containing a valid `paymasterParams` object.

<Accordion title="View example zksync-ethers script">
  ```typescript theme={null}
  import { Provider, Wallet } from "zksync-ethers";
  import { getApprovalBasedPaymasterInput, getGeneralPaymasterInput, getPaymasterParams } from "zksync-ethers/build/paymaster-utils";

  // Address of the deployed paymaster contract
  const CONTRACT_ADDRESS = "YOUR-PAYMASTER-CONTRACT-ADDRESS";

  // An example of a script to interact with the contract
  export default async function () {
    const provider = new Provider("https://api.testnet.abs.xyz");
    const wallet = new Wallet(privateKey ?? process.env.WALLET_PRIVATE_KEY!, provider);
    const type = "General"; // We're using a general flow in this example

    // Create the object: You can use the helper functions that are imported!
    const paymasterParams = getPaymasterParams(
      CONTRACT_ADDRESS,
      {
        type,
        innerInput: getGeneralPaymasterInput({
          type,
          innerInput: "0x", // Any additional info to send to the paymaster. We leave it empty here.
        })
      }
    );

    // Submit tx, as an example, send a message to another wallet.
    const tx = await wallet.sendTransaction({
      to: "0x8e729E23CDc8bC21c37a73DA4bA9ebdddA3C8B6d", // Example, send message to some other wallet
      data: "0x1337", // Example, some arbitrary data
      customData: {
        paymasterParams, // Provide the paymaster params object here!
      }
    })

    const res = await tx.wait();
  }
  ```
</Accordion>

## Paymaster Flows

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

1. [General Paymaster Flow](#general-paymaster-flow): Showcases a minimal paymaster that sponsors all transactions.
2. [Approval-Based Paymaster Flow](#approval-based-paymaster-flow): Showcases how users can pay for gas fees with an ERC-20 token.

<CardGroup cols={2}>
  <Card title="General Paymaster Implementation" icon="code" href="https://github.com/matter-labs/zksync-contract-templates/blob/main/templates/hardhat/solidity/contracts/paymasters/GeneralPaymaster.sol">
    View the source code for an example general paymaster flow implementation.
  </Card>

  <Card title="Approval Paymaster Implementation" icon="code" href="https://github.com/matter-labs/zksync-contract-templates/blob/main/templates/hardhat/solidity/contracts/paymasters/ApprovalPaymaster.sol">
    View the source code for an example approval-based paymaster flow
    implementation.
  </Card>
</CardGroup>

## Smart Contract References

<CardGroup cols={2}>
  <Card title="IPaymaster interface" icon="code" href="https://github.com/matter-labs/era-contracts/blob/main/system-contracts/contracts/interfaces/IPaymaster.sol">
    View the source code for the IPaymaster interface.
  </Card>

  <Card title="TransactionHelper library" icon="code" href="https://github.com/matter-labs/era-contracts/blob/main/system-contracts/contracts/libraries/TransactionHelper.sol">
    View the source code for the TransactionHelper library.
  </Card>
</CardGroup>
