🚧

Expect breaking changes to the SDK. We will be quickly iterating the SDK based on user feedback and will likely be pushing breaking changes. It might be useful to either lock down a specific version of the SDK you are using in your project, or to be prepared to update the interfaces.

Installation

You can download the ERC20 paymaster with the following command:

# using npm
npm install @pimlico/erc20-paymaster
 
# using yarn
yarn add @pimlico/erc20-paymaster
 
# using pnpm
pnpm install @pimlico/erc20-paymaster

Functions

getERC20Paymaster

Get an instance of the custom ERC20Paymaster object that you can use for the utility functions provided by this SDK

Usage

import { getERC20Paymaster } from "@pimlico/erc20-paymaster"
import { StaticJsonRpcProvider } from "@ethersproject/providers";
 
const provider = new StaticJsonRpcProvider("https://polygon-rpc.com")
 
const erc20Paymaster = await getERC20Paymaster(provider, "USDC")

Parameters

provider

  • Type: ethers.providers.Provider

The provider that will be used to fetch the chainId that will be used to determine the canonical oracle and token addresses that will produce the deterministic PimlicoERC20Paymaster address.

erc20

  • Type: "USDC" | "DAI" | "USDT"

The enum string that is used to fetch the PimlicoERC20Paymaster which uses the specified token as the ERC20 token to take from the user.

options (optional)

  • entrypoint(default: 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789)

The EntryPoint address the PimlicoERC20Paymaster uses

  • nativeAssetOracle (default: the canonical Chainlink Native Asset to USD oracle)

The oracle tracking the Native Asset to USD price corresponding to the Chainlink interface

  • tokenAddress (default: the address of the erc20 token on the provider's chain)

The address of the ERC20 Token used by the PimlicoERC20Paymaster

  • tokenOracle (default: the canonical Chainlink ERC20 Token to USD oracle)

The oracle tracking the ERC20 Token to USD price corresponding to the Chainlink interface

  • owner (default: 0x4337000c2828f5260d8921fd25829f606b9e8680 — Pimlico's address)

The owner of the paymaster

ERC20Paymaster.generatePaymasterAndData

Generates the paymasterAndData that can be placed in the UserOperation object asking the PimlicoERC20Paymaster to sponsor the UserOperation in exchange for ERC20 tokens from the sender.

This function also specifies a sensible maximum token amount the sender the user is willing to pay, specifying in effect the maximum slippage the user is willing to incur.

Usage

import { getERC20Paymaster } from "@pimlico/erc20-paymaster"
import { StaticJsonRpcProvider } from "@ethersproject/providers";
 
const provider = new StaticJsonRpcProvider("https://polygon-rpc.com")
 
const erc20Paymaster = await getERC20Paymaster(provider, "USDC")
 
const userOperation = {
  sender: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
  nonce: hexlify(0),
  initCode: "0x",
  callData: "0x",
  callGasLimit: hexlify(100_000),
  verificationGasLimit: hexlify(400_000),
  preVerificationGas: hexlify(50_000),
  maxFeePerGas: hexlify(1_000_000_000),
  maxPriorityFeePerGas: hexlify(1_000_000_000),
  paymasterAndData: "0x",
  signature: "0x"
}
 
const paymasterAndData = await erc20Paymaster.generatePaymasterAndData(userOperation)
 
userOperation.paymasterAndData = paymasterAndData

Parameters

UserOperation

  • Type: UserOperation

The UserOperation whose sender, gas prices, and gas limits are used to generate the paymasterAndData that can be added to delegate on-chain gas paymaster to the PimlicoERC20Paymaster.

ERC20Paymaster.verifyTokenApproval

Verifies that the UserOperation's sender has enough ERC20 tokens approved to the paymaster for the UserOperation to succeed. Throws an ERC20ApprovalError otherwise.

Usage

import { getERC20Paymaster } from "@pimlico/erc20-paymaster"
import { StaticJsonRpcProvider } from "@ethersproject/providers";
 
const provider = new StaticJsonRpcProvider("https://polygon-rpc.com")
 
const erc20Paymaster = await getERC20Paymaster(provider, "USDC")
 
const userOperation = {
  sender: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
  nonce: hexlify(0),
  initCode: "0x",
  callData: "0x",
  callGasLimit: hexlify(100_000),
  verificationGasLimit: hexlify(400_000),
  preVerificationGas: hexlify(50_000),
  maxFeePerGas: hexlify(1_000_000_000),
  maxPriorityFeePerGas: hexlify(1_000_000_000),
  paymasterAndData: "0x",
  signature: "0x"
}
 
// returns void if enough USDC is approved, throws otherwise
await erc20Paymaster.verifyTokenApproval(userOperation)

Parameters

UserOperation

  • Type: UserOperation

The UserOperation whose sender, gas prices, and gas limits are used to determine whether the sender has approved enough ERC20 tokens to the paymaster to succeed on-chain.

ERC20Paymaster.calculateTokenAmount

Calculates an upper bound (based on the current cached price in the paymaster) for the amount of ERC20 tokens that can be taken by the paymaster in exchange for the execution of the UserOperation. This function is used under the hood for calculateTokenAmount and verifyTokenApproval.

import { getERC20Paymaster } from "@pimlico/erc20-paymaster"
import { StaticJsonRpcProvider } from "@ethersproject/providers";
 
const provider = new StaticJsonRpcProvider("https://polygon-rpc.com")
 
const erc20Paymaster = await getERC20Paymaster(provider, "USDC")
 
const userOperation = {
  sender: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
  nonce: hexlify(0),
  initCode: "0x",
  callData: "0x",
  callGasLimit: hexlify(100_000),
  verificationGasLimit: hexlify(400_000),
  preVerificationGas: hexlify(50_000),
  maxFeePerGas: hexlify(1_000_000_000),
  maxPriorityFeePerGas: hexlify(1_000_000_000),
  paymasterAndData: "0x",
  signature: "0x"
}
 
const maxTokenAmount = await erc20Paymaster.calculateTokenAmount(userOperation)

Parameters

UserOperation

  • Type: UserOperation

The UserOperation whose sender, gas prices, and gas limits are used to calculate the maximum amount of ERC20 tokens that can be withdrawn by the paymaster for the current on-chain cached price.