Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.startale.com/llms.txt

Use this file to discover all available pages before exploring further.

The ERC-20 paymaster flow lets users pay gas in tokens like ASTR or USDC instead of holding native ETH. The Startale Token Paymaster quotes the cost in tokens, the user (or your dapp) approves the spend once, and every subsequent UserOperation charges the token directly.
Source: StartaleGroup/scs-aa-sdk. Token addresses for each network are listed in Supported networks.

How it works

1. Build the token-paymaster client

The client looks like the sponsored client, except paymasterContext.token replaces paymasterContext.paymasterId.
import { http } from "viem"
import {
  createSCSPaymasterClient,
  createSmartAccountClient,
} from "@startale-scs/aa-sdk"

const paymasterClient = createSCSPaymasterClient({
  transport: http(process.env.PAYMASTER_URL!),
})

const tokenAccountClient = createSmartAccountClient({
  account,
  transport: http(process.env.BUNDLER_URL!),
  client: publicClient,
  paymaster: paymasterClient,
  paymasterContext: {
    token: "0xfF0CBFbA43a1Ce2B8d72B2f3121558BcBd4B03a6", // USDC on Soneium Minato
  },
})
FieldTypeNotes
paymasterContext.tokenAddressThe ERC-20 used to pay gas. Must be one of the supported tokens on the target network.

2. Quote the cost in tokens

Before sending a UserOperation, ask the paymaster for the cost across the tokens you support. getTokenPaymasterQuotes returns one entry per token plus a list of unsupported addresses you passed in.
const quotes = await tokenAccountClient.getTokenPaymasterQuotes({
  userOp: {
    calls: [{ to: targetAddress, data: callData, value: 0n }],
  },
  tokens: [
    "0xfF0CBFbA43a1Ce2B8d72B2f3121558BcBd4B03a6", // USDC
    "0x26e6f7c7047252DdE3dcBF26AA492e6a264Db655", // ASTR
  ],
})

for (const quote of quotes.feeQuotes) {
  console.log(quote.symbol, quote.maxGasFee, quote.maxGasFeeUSD, quote.exchangeRate)
}
Field on each feeQuoteWhat it means
symbol, decimal, tokenAddress, logoUrlDisplay metadata for the token.
maxGasFeeMaximum cost in token base units (already factoring decimal).
maxGasFeeUSDThe same maximum, denominated in USD for display.
exchangeRateToken-to-native rate the paymaster used for the quote.
premiumPercentageSpread the paymaster adds on top of the raw conversion.
validUntilUnix timestamp; quote expires after this point.
Show the user a token picker built from feeQuotes. Disable the entries in quotes.unsupportedTokens so they cannot be selected.

3. Send the UserOperation

Once the user picks a token, send the UserOperation with the token-paymaster client. The SDK takes care of the approval flow and packing the token into paymasterAndData.
const hash = await tokenAccountClient.sendTokenPaymasterUserOp({
  calls: [
    {
      to: targetAddress,
      data: callData,
      value: 0n,
    },
  ],
  feeTokenAddress: chosenTokenAddress,
})

const receipt = await tokenAccountClient.waitForUserOperationReceipt({ hash })
SymbolSourceRole
sendTokenPaymasterUserOp@startale-scs/aa-sdkOne-shot helper that approves the token (if needed), prepares the UserOperation with the token paymaster, and submits it.
prepareTokenPaymasterUserOp@startale-scs/aa-sdkLower-level helper that returns the unsigned UserOperation if you need to inspect it before signing.

Common errors

ErrorLikely causeFix
unsupported tokenThe token is not listed for the network.Use one of the addresses in Supported networks.
insufficient allowanceThe smart account has not approved the paymaster to spend the token.Use sendTokenPaymasterUserOp, which inserts the approval automatically.
quote expiredThe user took longer than validUntil to sign.Re-quote and re-prompt.

Next steps

Sponsored paymaster

Compare token gas to a fully sponsored flow.

Supported tokens

Look up the exact token address for the network you target.

Contract interactions

Combine token gas with batched calls.

Smart sessions

Pair token gas with scoped sessions for high-frequency UX.