A demonstration application showcasing Particle Network's Account Abstraction (AA) capabilities, specifically focusing on paying gas fees with ERC-20 tokens instead of native ETH on Base.
This application demonstrates how to use Particle Network's AA SDK to enable users to pay transaction gas fees using ERC-20 tokens (like USDC, DAI, etc.) instead of native ETH. This is a key feature of Account Abstraction that improves user experience by allowing users to transact without holding native tokens.
- Social Login: Sign in with Google, Twitter, GitHub, or Email using Particle Auth
- Smart Account Creation: Automatically creates a Biconomy v2 smart account
- ERC-20 Gas Payments: Pay transaction fees with any supported ERC-20 token
- Token Selection: Choose from available tokens with real-time balance checking
// Connect user with Particle Auth
const { connect, disconnect, connected } = useConnect();
await connect({});
// Get provider from Particle
const { provider } = useEthereum();
// Initialize Smart Account with Biconomy
const smartAccount = useMemo(
() =>
new SmartAccount(provider, {
projectId: process.env.NEXT_PUBLIC_PROJECT_ID!,
clientKey: process.env.NEXT_PUBLIC_CLIENT_KEY!,
appId: process.env.NEXT_PUBLIC_APP_ID!,
aaOptions: {
accountContracts: {
BICONOMY: [
{
version: "2.0.0",
chainIds: [base.id],
},
],
},
},
}),
[provider]
);
What happens:
- User authenticates via social login (no wallet needed)
- Particle creates a smart account (Biconomy v2) on Base
- The smart account address is retrieved and displayed
// Prepare the transaction
const tx = {
to: recipientAddress,
value: parseEther("0.00000001").toString(),
data: "0x",
};
// Get fee quotes for available tokens
const feeQuotesResult = await smartAccount.getFeeQuotes(tx);
const tokenFeeQuotes = feeQuotesResult?.tokenPaymaster?.feeQuotes || [];
What happens:
- The SDK calls
getFeeQuotes()
with the transaction details - Particle's Token Paymaster returns a list of supported ERC-20 tokens
- Each token includes:
- Token info (symbol, decimals, address)
- Gas fee amount in that token
- User's current balance
- Premium percentage
The app displays available tokens sorted by balance:
// Token data structure
{
tokenInfo: {
symbol: "USDC",
decimals: 6,
address: "0x..."
},
fee: "15470343840712", // Fee in token's smallest unit
balance: "1980499", // User's balance
premiumPercentage: "12" // Additional fee percentage
}
What happens:
- Tokens are sorted with highest balance first
- Users can only select tokens they have balance for
- Fee is displayed in human-readable format using
formatUnits()
// Get the selected token's fee quote
const selectedFeeQuote =
feeQuotesResult?.tokenPaymaster?.feeQuotes[selectedTokenIndex];
// Build UserOperation with the token fee quote
const { userOp, userOpHash } = await smartAccount.buildUserOperation({
tx,
feeQuote: selectedFeeQuote,
tokenPaymasterAddress: feeQuotesResult?.tokenPaymaster?.tokenPaymasterAddress,
});
// Send the UserOperation
const txHash = await smartAccount.sendUserOperation({
userOp,
userOpHash,
});
What happens:
-
buildUserOperation(): Creates a UserOperation that includes:
- The transaction data
- The selected token for gas payment
- Token Paymaster address for settlement
-
sendUserOperation(): Submits the UserOperation to the network:
- The smart account executes the transaction
- Gas fees are paid in the selected ERC-20 token
- The Token Paymaster handles the token → ETH conversion
- User receives the transaction hash
1. User logs in with social account
↓
2. Smart account is created/retrieved
↓
3. User enters recipient address
↓
4. App fetches available ERC-20 tokens for gas payment
↓
5. User selects a token they have balance in
↓
6. App builds UserOperation with selected token
↓
7. User confirms transaction
↓
8. Transaction executes, gas paid in ERC-20 token
↓
9. Transaction hash returned
Fetches available payment options for a transaction:
- Returns gasless options (if available)
- Returns native ETH payment option
- Returns ERC-20 token payment options with fees
Builds a UserOperation with specified payment method:
- Takes transaction, fee quote, and paymaster address
- Returns
userOp
anduserOpHash
Submits the UserOperation to the network:
- Executes the transaction through the smart account
- Returns transaction hash
- No Native Token Required: Users can transact without holding ETH
- Flexible Payment: Choose from multiple ERC-20 tokens
- Transparent Fees: See exact fee amount before confirming
- Social Login: No seed phrases or wallet management
- Seamless UX: Feels like a Web2 application
-
Clone the repository
-
Install dependencies:
npm install
-
Set up environment variables in
.env
:NEXT_PUBLIC_PROJECT_ID=your_particle_project_id NEXT_PUBLIC_CLIENT_KEY=your_particle_client_key NEXT_PUBLIC_APP_ID=your_particle_app_id
-
Run the development server:
npm run dev