Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.trails.build/llms.txt

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

Overview

Gasless transactions let users pay network fees using ERC-20 tokens (USDC, USDT) instead of requiring native gas (ETH, MATIC). This eliminates a major friction point—users don’t need to hold the native token on every chain.
BenefitHow It Works
No native gas requiredUsers pay fees in stablecoins or other ERC-20 tokens
Better UXNo “insufficient gas” errors for users with only stablecoins
Permit signaturesEIP-2612 permits enable gasless token approvals
Flexible fee optionsSDK shows available fee token options automatically

Basic Gasless Payment

When using the SDK, gasless fee options are automatically displayed if the user’s origin token supports permits:
import { Pay } from '0xtrails/widget'

export function GaslessPayment() {
  return (
    <Pay
      apiKey="YOUR_API_KEY"
      to={{
        recipient: "0xMERCHANT_ADDRESS",
        currency: "USDC",
        chain: "polygon",
        amount: "50",
      }}
      onPaymentSuccess={({ sessionId }) => {
        console.log('Payment complete:', sessionId)
      }}
    >
      <button>Pay $50</button>
    </Pay>
  )
}
When the user has USDC (a permit-compatible token), the SDK:
  1. Shows fee options including “Pay gas in USDC”
  2. Requests a permit signature (no approval transaction needed)
  3. Submits via relayer—user’s USDC covers the gas fee

USDC/USDT as Gas Fee Examples

Pay with USDC on Polygon

<Pay
  apiKey="YOUR_API_KEY"
  to={{
    recipient: "0xMERCHANT_ADDRESS",
    currency: "USDC",
    chain: "polygon",
    amount: "100",
  }}
  onPaymentSuccess={({ sessionId }) => {
    verifyPayment(sessionId)
  }}
>
  <button>Pay $100 (Gas in USDC)</button>
</Pay>
The user only needs USDC—no ETH required for gas.

Pay with USDT on Polygon

<Pay
  apiKey="YOUR_API_KEY"
  to={{
    recipient: "0xMERCHANT_ADDRESS",
    currency: "USDT",
    chain: "polygon",
    amount: "75",
  }}
  onPaymentSuccess={({ sessionId }) => {
    verifyPayment(sessionId)
  }}
>
  <button>Pay $75 (Gas in USDT)</button>
</Pay>

Cross-Chain Gasless

Even cross-chain payments can be gasless if the origin token supports permits:
<Pay
  apiKey="YOUR_API_KEY"
  to={{
    recipient: "0xMERCHANT_ADDRESS",
    currency: "USDC",
    chain: "polygon",
    amount: "200",
  }}
  onPaymentSuccess={({ sessionId }) => {
    verifyPayment(sessionId)
  }}
>
  <button>Pay $200</button>
</Pay>
User pays with USDC on Base → Trails bridges gaslessly → Merchant receives USDC on Polygon.

Permit-Compatible Tokens

Gasless transactions require tokens that implement EIP-2612 (permit):
TokenPermit SupportNotes
USDCNative Circle USDC on all supported chains
USDTMost chains (verify per-chain)
DAISupports permit on Ethereum, L2s
WETHWrapped ETH supports permit
Most ERC-20sVariesCheck if token has permit() function
Native tokens (ETH, MATIC, etc.) cannot be used for gasless since they don’t support permits. Users paying with native tokens will use standard gas.

How Fee Options Work

The SDK automatically fetches available fee options based on:
  • User’s token balances on the origin chain
  • Which tokens support permit signatures
  • Current gas prices and token exchange rates
Users see a “Gas Fee Options” dropdown with choices like:
  • ETH (native gas)
  • USDC ($0.12)
  • USDT ($0.12)
Selecting an ERC-20 option triggers the gasless flow.

Programmatic Fee Selection

You can listen to fee option events:
<Pay
  apiKey="YOUR_API_KEY"
  to={{
    recipient: "0xMERCHANT_ADDRESS",
    currency: "USDC",
    chain: "polygon",
    amount: "50",
  }}
  onPaymentStart={({ sessionId }) => {
    console.log('Payment started:', sessionId)
  }}
  onSignRequest={() => {
    console.log('Permit signature requested')
  }}
  onSign={() => {
    console.log('Permit signed—submitting to relayer')
  }}
  onPaymentSuccess={({ sessionId }) => {
    console.log('Gasless payment complete:', sessionId)
  }}
>
  <button>Pay</button>
</Pay>

Gasless Flow Details

  1. Quote Intent — SDK fetches quote including gasFeeOptions with available fee tokens
  2. User Selects Fee — User picks USDC, USDT, or native gas from dropdown
  3. Permit Signature — If ERC-20 fee selected, user signs EIP-2612 permit (no on-chain tx)
  4. Intent Signature — User signs the intent data
  5. Relayer Submits — Trails relayer executes the transaction, deducting fee from user’s balance
  6. Completion — User receives confirmation once destination transaction confirms

Limitations

Smart Contract Wallets: Gasless deposits via permit signatures require EOA (externally owned account) wallets. Smart contract wallets produce non-standard signatures that the current relayer doesn’t support.
// Gasless automatically falls back to native gas for smart contract wallets
<Pay
  apiKey="YOUR_API_KEY"
  to={{ recipient: "0x...", currency: "USDC", chain: "polygon", amount: "50" }}
/>
The SDK automatically detects smart contract wallets and falls back to native gas flow. Native Token Payments: Sending ETH, MATIC, or other native tokens cannot be gasless—you need native gas to send native gas.

Best Practices

Don’t force gasless. Some users prefer paying native gas (often cheaper at low congestion). The SDK shows both options by default.
Users might reject the permit signature. Handle this gracefully:
onSignReject={(error) => {
  console.log('User rejected signature:', error)
  // Show retry option or native gas alternative
}}
Not all ERC-20 tokens support permits. The SDK automatically filters to show only valid fee options, but for API integrations, check token contracts.

Troubleshooting

IssueCauseSolution
No ERC-20 fee options shownToken doesn’t support permitUser must pay native gas
”Smart contract wallets not supported”SC wallet detectedUse native gas flow
Permit signature failsToken permit implementation variesTry a different token or native gas

Next Steps

Pay Mode Reference

All Pay component options and examples

SDK Configuration

Full configuration reference

Supported Chains

Chains and token support