Overview
Users can pay gas fees directly with native tokens from their smart accounts. This provides a familiar payment method while still benefiting from the enhanced features of smart wallets.Implementations
- Using Gelato Gasless SDK
- Using Viem
- Using Permissionless
- Using API Endpoints
Gelato Gasless SDK
Copy
Ask AI
npm install @gelatocloud/gasless viem
Example: Gelato Smart Account
1
Import Dependencies
Copy
Ask AI
import { createGelatoBundlerClient, toGelatoSmartAccount, token } from '@gelatocloud/gasless';
import { baseSepolia } from "viem/chains";
import { createPublicClient, http } from 'viem';
import { privateKeyToAccount } from "viem/accounts";
2
Create Gelato Smart Account
Copy
Ask AI
const owner = privateKeyToAccount(process.env.PRIVATE_KEY);
const client = createPublicClient({
chain: baseSepolia,
transport: http(),
});
const account = await toGelatoSmartAccount({
client,
owner,
});
3
Create Gelato Bundler Client
Copy
Ask AI
const tokenAddress = "0x0000000000000000000000000000000000000000"; // Native
const bundler = await createGelatoBundlerClient({
account,
apiKey: process.env.GELATO_API_KEY,
client,
payment: token(tokenAddress),
pollingInterval: 100
});
4
Send User Operation
Copy
Ask AI
const hash = await bundler.sendUserOperation({
calls: [
{
data: '0xd09de08a',
to: '0xE27C1359cf02B49acC6474311Bd79d1f10b1f8De'
}
]
});
console.log(`User operation hash: ${hash}`);
const { receipt } = await bundler.waitForUserOperationReceipt({ hash });
console.log(`Transaction hash: ${receipt.transactionHash}`);
Viem
To start sending transactions while paying gas with native tokens using Viem, follow these steps:1
Create a API Key
Check out our How-To Guide for detailed instructions on generating a API key.
2
Import Dependencies
Copy
Ask AI
import { createPublicClient, http } from 'viem'
import { createBundlerClient, toSoladySmartAccount } from "viem/account-abstraction";
import { privateKeyToAccount } from "viem/accounts";
import { baseSepolia } from "viem/chains";
3
Setup Smart Account
Any smart account that implements viem’s
Account type can be used here.
Check out other available smart accounts here.Copy
Ask AI
const publicClient = createPublicClient({ chain: baseSepolia, transport: http() });
const signer = privateKeyToAccount(PRIVATE_KEY as any);
const account = await toSoladySmartAccount({
client: publicClient,
owner: signer,
});
4
Create a Bundler Client
Create a
BundlerClient with the account and publicClient. Use https://api.gelato.digital/bundlers as the bundler endpoint.Pass the API key as a query parameter. Learn more about Bundler Client here.Copy
Ask AI
const bundlerClient = createBundlerClient({
account,
client: publicClient,
transport: http(`https://api.gelato.digital/bundlers/${chainId}/rpc?apiKey=${process.env.GELATO_API_KEY}`),
userOperation: {
estimateFeesPerGas: async ({ bundlerClient }) => {
const gasPrices = await bundlerClient.request({
method: 'eth_getUserOperationGasPrice',
params: []
});
return {
maxFeePerGas: BigInt(gasPrices.maxFeePerGas),
maxPriorityFeePerGas: BigInt(gasPrices.maxPriorityFeePerGas)
};
}
}
});
5
Send a UserOperation
Send a
UserOperation with the bundlerClient. The smart account must hold native tokens (ETH) to pay for gas fees.Copy
Ask AI
const userOperationHash = await bundlerClient.sendUserOperation({
account,
calls: [{ to: account.address, value: 0n, data: "0x" }],
});
console.log("UserOperation Hash: ", userOperationHash);
const receipt = await bundlerClient.waitForUserOperationReceipt({ hash: userOperationHash });
console.log("Transaction Hash: ", receipt.receipt.transactionHash);
Permissionless
Copy
Ask AI
npm install permissionless viem
Basic Setup
1
Import Dependencies
Copy
Ask AI
import { createPublicClient, http } from "viem";
import { createBundlerClient, entryPoint07Address } from "viem/account-abstraction";
import { toKernelSmartAccount } from "permissionless/accounts";
import { privateKeyToAccount } from "viem/accounts";
import { baseSepolia } from "viem/chains";
2
Create Smart Account
Copy
Ask AI
const owner = privateKeyToAccount(process.env.PRIVATE_KEY);
const publicClient = createPublicClient({
chain: baseSepolia,
transport: http(),
});
const account = await toKernelSmartAccount({
client: publicClient,
owners: [owner],
entryPoint: {
address: entryPoint07Address,
version: "0.7",
},
version: "0.3.3",
});
3
Create Bundler Client with Gelato
Use
https://api.gelato.digital/bundlers as the bundler endpoint. Pass the API key as a query parameter.Learn more about Bundler Client here.Copy
Ask AI
const bundlerClient = createBundlerClient({
client: publicClient,
transport: http(`https://api.gelato.digital/bundlers/${chainId}/rpc?apiKey=${process.env.GELATO_API_KEY}`),
userOperation: {
estimateFeesPerGas: async ({ bundlerClient }) => {
const gasPrices = await bundlerClient.request({
method: 'eth_getUserOperationGasPrice',
params: []
});
return {
maxFeePerGas: BigInt(gasPrices.maxFeePerGas),
maxPriorityFeePerGas: BigInt(gasPrices.maxPriorityFeePerGas)
};
}
}
});
4
Send User Operation
The smart account must hold native tokens (ETH) to pay for gas fees.
Copy
Ask AI
const userOpHash = await bundlerClient.sendUserOperation({
account,
calls: [
{
to: "0xE27C1359cf02B49acC6474311Bd79d1f10b1f8De",
data: "0xd09de08a", // increment()
value: 0n,
},
],
});
console.log("UserOperation Hash: ", userOpHash);
const receipt = await bundlerClient.waitForUserOperationReceipt({
hash: userOpHash,
});
console.log(`Transaction successful: ${receipt.receipt.transactionHash}`);
Authentication
Usehttps://api.gelato.cloud for mainnets, or https://api.t.gelato.cloud for testnets.Pass the API key in the X-API-Key header.Basic Example
1
Send User Operation
Copy
Ask AI
const tokenAddress = "0x0000000000000000000000000000000000000000"; // Native
const response = await fetch(
`https://api.gelato.cloud/rpc/${chainId}?payment=token&token=${tokenAddress}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": process.env.GELATO_API_KEY
},
body: JSON.stringify({
jsonrpc: "2.0",
method: "eth_sendUserOperation",
params: [userOperation, entryPoint],
id: 1,
}),
}
);
const data = await response.json();
const userOpHash = data.result;
2
Estimate Gas
Copy
Ask AI
const tokenAddress = "0x0000000000000000000000000000000000000000"; // Native
const response = await fetch(
`https://api.gelato.cloud/rpc/${chainId}?payment=token&token=${tokenAddress}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": process.env.GELATO_API_KEY
},
body: JSON.stringify({
jsonrpc: "2.0",
method: "eth_estimateUserOperationGas",
params: [userOperation, entryPoint],
id: 1,
}),
}
);
const data = await response.json();
const gasEstimate = data.result;
3
Get User Operation Receipt
Copy
Ask AI
const response = await fetch(
`https://api.gelato.cloud/rpc/${chainId}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": process.env.GELATO_API_KEY
},
body: JSON.stringify({
jsonrpc: "2.0",
method: "eth_getUserOperationReceipt",
params: [userOpHash],
id: 1,
}),
}
);
const data = await response.json();
const receipt = data.result;
Available Endpoints
Additional Resources
- Supported Networks - Check network availability