Users can pay gas in USDC, USDT, or any token with liquidity—no native ETH required. Perfect for DeFi users who hold stablecoins but not native tokens.
MEE Supersedes Token Paymasters: Traditional ERC-4337 token paymasters handle gas-in-tokens on a single chain. Biconomy’s MEE replaces this with universal gas abstraction—pay for gas on any chain using tokens from any other supported chain. One unified system instead of chain-by-chain paymaster configuration.
When to Use
Users have stablecoins but no ETH
DeFi applications where users already hold tokens
Cross-chain apps (pay from any chain)
You don’t want to sponsor gas
How It Works
User has 100 USDC, 0 ETH
↓
User initiates transaction
↓
Biconomy quotes: "This costs 0.50 USDC"
↓
User signs approval
↓
Biconomy:
- Deducts 0.50 USDC from user
- Pays native gas on their behalf
- Executes transaction
↓
User has 99.50 USDC, transaction complete
Implementation
import { createMeeClient, toMultichainNexusAccount } from "@biconomy/abstractjs";
const USDC = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
// 1. Setup
const account = await toMultichainNexusAccount({
signer: userWallet,
chainConfigurations: [
{ chain: base, transport: http(), version: getMEEVersion(MEEVersion.V2_1_0) }
]
});
const meeClient = await createMeeClient({ account });
// 2. Build instruction
const swapInstruction = await account.buildComposable({
type: "default",
data: {
chainId: base.id,
to: UNISWAP_ROUTER,
abi: UniswapAbi,
functionName: "exactInputSingle",
args: [swapParams]
}
});
// 3. Get quote with fee token
const quote = await meeClient.getQuote({
instructions: [swapInstruction],
feeToken: {
address: USDC,
chainId: base.id
}
});
// Show fee to user
console.log('Fee:', quote.paymentInfo.tokenAmount, 'USDC');
// 4. Execute
const { hash } = await meeClient.executeQuote({ quote });
const receipt = await meeClient.waitForSupertransactionReceipt({ hash });
Cross-Chain Gas Payment
Pay for transactions on one chain using tokens from another:
// Execute on Arbitrum, pay gas from Base USDC
const quote = await meeClient.getQuote({
instructions: [{
chainId: 42161, // Arbitrum
calls: [/* Arbitrum transaction */]
}],
feeToken: {
address: USDC_BASE,
chainId: 8453 // Pay from Base
}
});
Cross-chain gas requires Smart Account or EIP-7702 mode. Fusion (EOA) mode only supports same-chain gas payment.
Supported Tokens
Stablecoins
| Token | Chains |
|---|
| USDC | All |
| USDT | All |
| DAI | Ethereum, Optimism, Arbitrum, Polygon |
| FRAX | Ethereum, Arbitrum, Optimism |
Major Tokens
| Token | Chains |
|---|
| WETH | All |
| WBTC | Ethereum, Arbitrum, Optimism, Polygon |
| stETH/wstETH | Ethereum, Arbitrum, Optimism |
Yield-Bearing
| Token | Chains |
|---|
| aUSDC | Ethereum, Arbitrum, Optimism, Polygon |
| sDAI | Ethereum |
And 10,000+ More
Any token with DEX liquidity can be used. Biconomy’s solver network finds the best route to convert to native gas.
By Wallet Type
Smart Account
EIP-7702 (Embedded)
Fusion (EOA)
Most flexible—any token from any chain:const quote = await meeClient.getQuote({
instructions: [instruction],
feeToken: { address: USDC, chainId: base.id }
});
Same flexibility, requires delegation:const quote = await meeClient.getQuote({
instructions: [instruction],
delegate: true,
authorization,
feeToken: { address: USDC, chainId: base.id }
});
Fee token must match trigger token, same chain:const quote = await meeClient.getFusionQuote({
trigger: {
chainId: base.id,
tokenAddress: USDC,
amount: inputAmount
},
instructions: [instruction],
feeToken: { address: USDC, chainId: base.id } // Must match trigger
});
Showing Fees to Users
Always show the fee before asking for signature:
const quote = await meeClient.getQuote({
instructions: [...],
feeToken: { address: USDC, chainId: base.id }
});
// Display to user
const feeDisplay = `
Transaction Fee: ${formatUnits(quote.paymentInfo.tokenAmount, 6)} USDC
You will receive: ${formatUnits(outputAmount, 18)} WETH
`;
// Confirm before executing
if (await userConfirms(feeDisplay)) {
await meeClient.executeQuote({ quote });
}
Multiple Fee Tokens
Let users choose their preferred token:
// Get quotes for different tokens
const [usdcQuote, usdtQuote, daiQuote] = await Promise.all([
meeClient.getQuote({ instructions, feeToken: { address: USDC, chainId } }),
meeClient.getQuote({ instructions, feeToken: { address: USDT, chainId } }),
meeClient.getQuote({ instructions, feeToken: { address: DAI, chainId } }),
]);
// Show options to user
const options = [
{ token: 'USDC', fee: usdcQuote.paymentInfo.tokenAmount },
{ token: 'USDT', fee: usdtQuote.paymentInfo.tokenAmount },
{ token: 'DAI', fee: daiQuote.paymentInfo.tokenAmount },
];
Next Steps