Die Oberfläche ist lokalisiert; Skill-Beschreibungen und -Dokumente werden per KI automatisch in Ihre Sprache übersetzt. Code, Befehle, Pfade und Fachbegriffe bleiben im Original, maßgeblich ist das Dokument des Autors.
Skills entdecken
Produktivität · SKILL.md

fee-abstraction

fee-abstraction

Pay gas fees with ERC-20 tokens on Celo. Covers supported tokens, implementation, and wallet compatibility.

Independent GitHub snapshot · Automated classification · Original documentation governs

Ccelo-org / agent-skillsApache-2.0

Skill-Dokumentation

GitHub

name: fee-abstraction description: Pay gas fees with ERC-20 tokens on Celo. Covers supported tokens, implementation, and wallet compatibility. license: Apache-2.0 metadata: author: celo-org version: "1.1.0"

Fee Abstraction on Celo

This skill covers Celo's native fee abstraction feature that allows gas fees to be paid in ERC-20 tokens.

When to Use

  • Paying gas fees with stablecoins (USDC, USDT, cUSD)
  • Building user-friendly dApps where users don't need CELO
  • MiniPay integrations
  • Any Celo transaction where users prefer stablecoin gas

Overview

Celo's native fee abstraction allows gas fees to be paid in ERC-20 tokens without Account Abstraction, Paymasters, or Relay Services. Wallets simply add a feeCurrency field to transaction objects.

Source: https://docs.celo.org/developer/fee-currency

Supported Fee Currencies

Mainnet (Chain ID: 42220)

TokenToken AddressAdapter AddressUse in feeCurrency
USDC0xcebA9300f2b948710d2653dD7B07f33A8B32118C0x2F25deB3848C207fc8E0c34035B3Ba7fC157602BAdapter
USDT0x48065fbbe25f71c9282ddf5e1cd6d6a887483d5e0x0e2a3e05bc9a16f5292a6170456a710cb89c6f72Adapter
cUSD0x765DE816845861e75A25fCA122bb6898B8B1282a-Token
cEUR0xD8763CBa276a3738E6DE85b4b3bF5FDed6D6cA73-Token
cREAL0xe8537a3d056DA446677B9E9d6c5dB704EaAb4787-Token

Celo Sepolia Testnet (Chain ID: 11142220)

TokenToken AddressAdapter AddressUse in feeCurrency
USDC0x2F25deB3848C207fc8E0c34035B3Ba7fC157602B0x4822e58de6f5e485eF90df51C41CE01721331dC0Adapter

Important: Use adapter addresses for 6-decimal tokens (USDC, USDT). Use token addresses directly for 18-decimal tokens (cUSD, cEUR, cREAL).

Wallet Support

WalletFee Abstraction SupportNotes
MiniPayFullNative support, recommended for mobile
ValoraFullNative Celo wallet
MetaMaskNoUses Ethereum tx format without feeCurrency field
Coinbase WalletNoStandard EVM format
Other EVM WalletsNoRequire custom dApp implementation

MetaMask and standard EVM wallets don't support fee abstraction because they use Ethereum-compatible transaction formats that don't include the feeCurrency field.

Library Support

LibraryfeeCurrency Support
viemSupported
ethers.jsNot supported
web3.jsNot supported

viem is required for fee abstraction in dApps.

Basic Implementation

Send Transaction with Fee Currency

import { createWalletClient, custom, parseEther } from "viem";
import { celo } from "viem/chains";

// Use adapter address for USDC (6 decimals)
const USDC_ADAPTER = "0x2F25deB3848C207fc8E0c34035B3Ba7fC157602B";

const walletClient = createWalletClient({
  chain: celo,
  transport: custom(window.ethereum),
});

const [address] = await walletClient.getAddresses();

const hash = await walletClient.sendTransaction({
  account: address,
  to: "0xRecipientAddress",
  value: parseEther("0.01"),
  feeCurrency: USDC_ADAPTER, // Pay gas in USDC
});

console.log("Transaction hash:", hash);

Estimate Gas Price in Fee Currency

import { createPublicClient, http } from "viem";
import { celo } from "viem/chains";

const USDC_ADAPTER = "0x2F25deB3848C207fc8E0c34035B3Ba7fC157602B";

const publicClient = createPublicClient({
  chain: celo,
  transport: http("https://forno.celo.org"),
});

// Get gas price in USDC
const priceHex = await publicClient.request({
  method: "eth_gasPrice",
  params: [USDC_ADAPTER],
});

const gasPrice = BigInt(priceHex);
console.log("Gas price in USDC:", gasPrice);

Serialize Transaction (CIP-64)

import { serializeTransaction } from "viem/celo";
import { parseGwei, parseEther } from "viem";

const USDC_ADAPTER = "0x2F25deB3848C207fc8E0c34035B3Ba7fC157602B";

const serialized = serializeTransaction({
  chainId: 42220,
  gas: 21000n,
  feeCurrency: USDC_ADAPTER,
  maxFeePerGas: parseGwei("20"),
  maxPriorityFeePerGas: parseGwei("2"),
  nonce: 1,
  to: "0xRecipientAddress",
  value: parseEther("0.01"),
});

Key Concepts

Transaction Type

Fee currency transactions use CIP-64 type 0x7b (123 decimal). This is a Celo-specific transaction type.

Gas Overhead

Paying the network fee in a stablecoin costs meaningfully more gas than paying in CELO, and the overhead is not a constant — it depends on the token, because 6-decimal tokens route through an adapter.

Measured over 2,600 consecutive Celo mainnet blocks (ending block 77,155,261), comparing gasUsed of ERC-20 transfer calls paid in CELO against identical transfers that set feeCurrency:

Fee currencyPaid in CELOPaid in the tokenOverheadSamples (token / CELO)
USDm (18-dec, no adapter)39,79980,499≈ +40,7001 / 1
USDT (6-dec, adapter)43,801115,501≈ +71,7006,970 / 3,143
USDC (6-dec, adapter)45,047159,759≈ +114,7127 / 100

Medians; distributions are tight (USDT p25 = p75 = 115,501).

Budget ~2.5–3.5× the gas of an equivalent CELO-paid transaction, not a flat number — set gas limits from the fee-currency figures or estimation will fail. The USDT row is measured across ~10,000 transactions; USDm and USDC fee-currency samples are small because almost nobody pays fees in them (6,970 of 6,978 fee-currency transfers in the window were USDT), so treat those two rows as indicative.

Adapters vs Token Addresses

  • 6-decimal tokens (USDC, USDT): Must use adapter address
  • 18-decimal tokens (cUSD, cEUR, cREAL): Use token address directly

Adapters normalize decimals since Celo's gas calculations use 18 decimals internally.

Querying Available Currencies

Using celocli:

celocli network:whitelist --node https://forno.celo.org

Using FeeCurrencyDirectory contract:

import { createPublicClient, http } from "viem";
import { celo } from "viem/chains";

const FEE_CURRENCY_DIRECTORY = "0x9212Fb72ae65367A7c887eC4Ad9bE310BAC611BF";

const publicClient = createPublicClient({
  chain: celo,
  transport: http("https://forno.celo.org"),
});

const currencies = await publicClient.readContract({
  address: FEE_CURRENCY_DIRECTORY,
  abi: [{
    name: "getCurrencies",
    type: "function",
    stateMutability: "view",
    inputs: [],
    outputs: [{ type: "address[]" }],
  }],
  functionName: "getCurrencies",
});

console.log("Allowed fee currencies:", currencies);

Limitations

  1. Wallet Dependency: Only works with Celo-native wallets (MiniPay, Valora) or custom dApp implementations
  2. Library Dependency: Requires viem (ethers.js/web3.js don't support feeCurrency)
  3. Gas Overhead: ~50k additional gas for non-CELO currencies
  4. Balance Requirements: User must have sufficient balance in the chosen fee currency

Advanced: Custom Fee Currency Selector UI

Build a UI that lets users choose their gas payment token:

import { useState } from "react";
import { useAccount, useBalance } from "wagmi";
import { celo } from "viem/chains";

const FEE_CURRENCIES = [
  { symbol: "CELO", address: null, adapter: null },
  {
    symbol: "USDC",
    address: "0xcebA9300f2b948710d2653dD7B07f33A8B32118C",
    adapter: "0x2F25deB3848C207fc8E0c34035B3Ba7fC157602B",
  },
  {
    symbol: "USDT",
    address: "0x48065fbbe25f71c9282ddf5e1cd6d6a887483d5e",
    adapter: "0x0e2a3e05bc9a16f5292a6170456a710cb89c6f72",
  },
  {
    symbol: "cUSD",
    address: "0x765DE816845861e75A25fCA122bb6898B8B1282a",
    adapter: null,
  },
];

interface FeeCurrency {
  symbol: string;
  address: string | null;
  adapter: string | null;
}

function FeeCurrencySelector({
  onSelect,
}: {
  onSelect: (currency: FeeCurrency) => void;
}) {
  const { address } = useAccount();
  const [selected, setSelected] = useState(0);

  const handleChange = (index: number) => {
    setSelected(index);
    onSelect(FEE_CURRENCIES[index]);
  };

  return (
    <div>
      <label>Pay gas with:</label>
      <select
        value={selected}
        onChange={(e) => handleChange(Number(e.target.value))}
      >
        {FEE_CURRENCIES.map((currency, i) => (
          <option key={currency.symbol} value={i}>
            {currency.symbol}
          </option>
        ))}
      </select>
    </div>
  );
}

// Usage in transaction
function useFeeCurrencyTransaction() {
  const [feeCurrency, setFeeCurrency] = useState<FeeCurrency>(FEE_CURRENCIES[0]);

  const getFeeCurrencyAddress = () => {
    if (!feeCurrency.address) return undefined; // CELO native
    return feeCurrency.adapter || feeCurrency.address;
  };

  return { feeCurrency, setFeeCurrency, getFeeCurrencyAddress };
}

Advanced: Server-Side Transaction Building

Build fee currency transactions server-side for gasless or sponsored transactions:

import { createWalletClient, http, parseEther } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { celo } from "viem/chains";

const USDC_ADAPTER = "0x2F25deB3848C207fc8E0c34035B3Ba7fC157602B";

async function buildSponsoredTransaction(
  recipientAddress: `0x${string}`,
  amount: bigint
) {
  // Sponsor account pays gas in USDC
  const sponsorAccount = privateKeyToAccount(
    process.env.SPONSOR_PRIVATE_KEY as `0x${string}`
  );

  const walletClient = createWalletClient({
    account: sponsorAccount,
    chain: celo,
    transport: http("https://forno.celo.org"),
  });

  const hash = await walletClient.sendTransaction({
    to: recipientAddress,
    value: amount,
    feeCurrency: USDC_ADAPTER,
  });

  return hash;
}

// Example: sponsor a user's transaction
async function sponsorUserTransfer() {
  const hash = await buildSponsoredTransaction(
    "0xUserAddress",
    parseEther("1")
  );
  console.log("Sponsored transaction:", hash);
}

Additional Resources


Source of truth: Celopedia

These skills are focused, task-level references. For anything broader — verified contract addresses, ecosystem and protocol data, listing requirements, grants, governance, migration guides, or cross-cutting Celo questions — Celopedia is the canonical source and is kept current. Where this skill and Celopedia disagree, Celopedia wins.

npx skills add celo-org/celopedia-skills
Gespeicherte Skills