Implement gasless transactions using paymasters with various AA providers
Enable gasless transactions for users with Para’s AA infrastructure and paymasters.
You need a Para-enabled smart account client and paymaster configuration from your AA provider.
import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy";
import type { WalletClient } from "viem";
async function setupPaymaster(
apiKey: string,
policyId: string,
chain: any,
paraWalletClient: WalletClient // Para-enabled viem client from setup
) {
const client = await createModularAccountAlchemyClient({
apiKey,
chain,
signer: paraWalletClient, // Para wallet client as signer
gasManagerConfig: {
policyId
}
});
console.log("Gas Manager Policy:", policyId);
console.log("Gasless transactions enabled!");
return client;
}
async function sendGaslessTransaction(
alchemyClient: any, // Para-enabled Alchemy client from setupPaymaster
to: string,
value: bigint,
data?: string
) {
try {
const { hash } = await alchemyClient.sendUserOperation({
uo: {
target: to,
data: data || "0x",
value
}
});
console.log("Gasless UserOp sent:", hash);
const receipt = await alchemyClient.waitForUserOperationReceipt({
hash
});
console.log("Transaction mined:", receipt.receipt.transactionHash);
console.log("Gas sponsored by paymaster!");
return receipt;
} catch (error) {
console.error("Gasless transaction failed:", error);
throw error;
}
}
import { createKernelAccountClient, createZeroDevPaymasterClient } from "@zerodev/sdk";
async function setupERC20Paymaster(
kernelAccount: any, // Para-enabled kernel account
chain: any,
bundlerUrl: string,
paymasterUrl: string,
gasToken: string
) {
const paymasterClient = createZeroDevPaymasterClient({
chain,
transport: http(paymasterUrl),
paymentMode: {
mode: "ERC20",
token: gasToken,
maxAllowance: parseEther("100")
}
});
const kernelClient = createKernelAccountClient({
account: kernelAccount, // Para account
chain,
bundlerTransport: http(bundlerUrl),
paymaster: paymasterClient
});
console.log("ERC20 Paymaster enabled");
console.log("Gas token:", gasToken);
return kernelClient;
}
async function setupConditionalSponsorship(
apiKey: string,
chain: any,
paraWalletClient: any, // Para-enabled viem client
sponsorshipRules: {
allowlist?: string[];
blocklist?: string[];
maxSpend?: string;
requestsPerDay?: number;
}
) {
const policyId = await createGasPolicy({
apiKey,
rules: sponsorshipRules
});
const client = await createModularAccountAlchemyClient({
apiKey,
chain,
signer: paraWalletClient, // Para wallet as signer
gasManagerConfig: {
policyId,
validationOptions: {
preVerificationGas: 100000n,
verificationGasLimit: 1000000n,
callGasLimit: 2000000n
}
}
});
console.log("Conditional sponsorship enabled");
console.log("Rules:", sponsorshipRules);
return client;
}
async function createGasPolicy(params: any) {
const response = await fetch(
"https://api.g.alchemy.com/v1/gas-manager/policies",
{
method: "POST",
headers: {
"Authorization": `Bearer ${params.apiKey}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
rules: params.rules,
name: "Custom Para Policy",
description: "Conditional gas sponsorship"
})
}
);
const { policyId } = await response.json();
return policyId;
}
async function getPaymasterStats(
apiKey: string,
policyId: string
) {
const response = await fetch(
`https://api.g.alchemy.com/v1/gas-manager/policies/${policyId}/stats`,
{
headers: {
"Authorization": `Bearer ${apiKey}`
}
}
);
const stats = await response.json();
console.log("Policy Stats:");
console.log("- Total sponsored:", stats.totalSponsored);
console.log("- UserOps count:", stats.userOpsCount);
console.log("- Average gas cost:", stats.averageGasCost);
console.log("- Total spent:", formatEther(stats.totalSpentWei), "ETH");
return stats;
}