Send a gasless transaction
MetaMask Smart Accounts support gas sponsorship, which simplifies onboarding by abstracting gas fees away from end users. You can use any paymaster service provider, such as Pimlico or ZeroDev, or plug in your own custom paymaster.
Prerequisites
- Install and set up the Delegation Toolkit.
- Configure the Delegation Toolkit.
- Create a MetaMask smart account.
Send a gasless transaction
The following example demonstrates how to use Viem's Paymaster Client to send gasless transactions.
You can provide the paymaster client using the paymaster property in the sendUserOperation
method, or in the Bundler Client.
In this example, the paymaster client is passed to the sendUserOperation
method.
- example.ts
- config.ts
import { bundlerClient, smartAccount, paymasterClient } from "./config.ts";
import { parseEther } from "viem";
// Appropriate fee per gas must be determined for the specific bundler being used.
const maxFeePerGas = 1n;
const maxPriorityFeePerGas = 1n;
const userOperationHash = await bundlerClient.sendUserOperation({
account: smartAccount,
calls: [
{
to: "0x1234567890123456789012345678901234567890",
value: parseEther("1")
}
],
maxFeePerGas,
maxPriorityFeePerGas,
paymaster: paymasterClient,
});
import { createPublicClient, createPaymasterClient, http } from "viem";
import { createBundlerClient } from "viem/account-abstraction";
import { sepolia as chain } from "viem/chains";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import {
Implementation,
toMetaMaskSmartAccount,
} from "@metamask/delegation-toolkit";
const publicClient = createPublicClient({
chain,
transport: http()
});
const privateKey = generatePrivateKey();
const account = privateKeyToAccount(privateKey);
export const smartAccount = await toMetaMaskSmartAccount({
client: publicClient,
implementation: Implementation.Hybrid,
deployParams: [account.address, [], [], []],
deploySalt: "0x",
signatory: { account },
});
export const bundlerClient = createBundlerClient({
client: publicClient,
transport: http("https://api.pimlico.io/v2/11155111/rpc")
});
export const paymasterClient = createPaymasterClient({
// You can use the paymaster of your choice
transport: http("https://api.pimlico.io/v2/11155111/rpc")
});