WDK logoWDK documentation

Get Started

Install @tetherto/wdk-wallet-evm-7702-gasless and create an EIP-7702 gasless account.

Create an Ethereum EIP-7702 wallet with Candide or Pimlico. Choose sponsored gas or pay UserOperation gas fees in USD₮.

Install

Use Node.js 22 and npm for these examples. The package version below is pinned for this guide.

Install the wallet package
npm install @tetherto/wdk-wallet-evm-7702-gasless@1.0.0-beta.8

Choose a Bundler and Paymaster

Both providers below use Ethereum mainnet (chainId: 1) and EntryPoint v0.8. Your chain RPC remains separate from the bundler and paymaster endpoints.

This selection updates the setup and examples throughout this guide. Your chain RPC (provider) stays the same.

Candide

Create a runtime API key in the Candide dashboard and set CANDIDE_API_KEY. Use the unified authenticated endpoint for both bundler and paymaster requests.

Set EVM_7702_DELEGATION_ADDRESS to a smart-account implementation address you have verified for Ethereum and EntryPoint v0.8; review the delegation and EntryPoint prerequisites. The EOA delegates execution to this contract. To use v0.9 instead, configure a matching EntryPoint and delegation implementation and verify provider support and paymaster settings for that version.

Read WALLET_SEED_PHRASE from your application's secure seed storage. These Node.js examples read it from the environment. Keep seeds, API keys, and authenticated endpoint URLs out of source control and logs. Never use a publicly shared seed for real funds.

Choose one of the following payment modes. Each code block is a separate example; save your chosen block in a .mjs file and run it with node after setting its environment variables. Switching the dropdown changes both examples on this page; recreate your wallet with the new configuration if you change providers in your application.

Create a Sponsored Wallet

Candide

Create and fund an active Candide gas policy for Ethereum in the dashboard. Configure its allowed operations and limits, then set CANDIDE_SPONSORSHIP_POLICY_ID to the policy ID for your runtime API key.

Candide: sponsored EIP-7702 wallet
import WalletManagerEvm7702Gasless from '@tetherto/wdk-wallet-evm-7702-gasless'

const seedPhrase = process.env.WALLET_SEED_PHRASE
const apiKey = process.env.CANDIDE_API_KEY
const delegationAddress = process.env.EVM_7702_DELEGATION_ADDRESS
const sponsorshipPolicyId = process.env.CANDIDE_SPONSORSHIP_POLICY_ID

if (!seedPhrase || !apiKey || !delegationAddress || !sponsorshipPolicyId) {
  throw new Error('Set WALLET_SEED_PHRASE, CANDIDE_API_KEY, EVM_7702_DELEGATION_ADDRESS, CANDIDE_SPONSORSHIP_POLICY_ID before running this example')
}

const CHAIN_RPC = 'https://rpc.mevblocker.io/fast'
const endpoint = `https://api.candide.dev/api/v3/1/${encodeURIComponent(apiKey)}`

const wallet = new WalletManagerEvm7702Gasless(seedPhrase, {
  chainId: 1,
  provider: CHAIN_RPC,
  entryPointVersion: '0.8',
  delegationAddress,
  bundlerUrl: endpoint,
  paymasterUrl: endpoint,
  isSponsored: true,
  sponsorshipPolicyId
})

const account = await wallet.getAccount(0)
const address = await account.getAddress()
console.log('EOA address:', address)

getAddress() returns the EOA address without verifying sponsorship eligibility. Creating an account does not submit an EIP-7702 authorization; the module signs that authorization when building an operation if the account is not already delegated to the configured delegationAddress.

Use Paymaster-token Mode

If the user pays gas with an ERC-20 paymaster token, configure paymasterToken instead of isSponsored: true. Fund the EOA with enough USD₮ to cover the operation's fees before sending.

Confirm your selected endpoint supports Ethereum, EntryPoint v0.8, and Ethereum USD₮ at 0xdAC17F958D2ee523a2206206994597C13D831ec7. Check token availability and the expected paymaster contract for your API key before using the pin below. The module rejects a returned paymaster address that differs from the configured pin. See provider configuration.

Candide

Candide: EIP-7702 paymaster-token wallet
import WalletManagerEvm7702Gasless from '@tetherto/wdk-wallet-evm-7702-gasless'

const seedPhrase = process.env.WALLET_SEED_PHRASE
const apiKey = process.env.CANDIDE_API_KEY
const delegationAddress = process.env.EVM_7702_DELEGATION_ADDRESS

if (!seedPhrase || !apiKey || !delegationAddress) {
  throw new Error('Set WALLET_SEED_PHRASE, CANDIDE_API_KEY, EVM_7702_DELEGATION_ADDRESS before running this example')
}

const CHAIN_RPC = 'https://rpc.mevblocker.io/fast'
const endpoint = `https://api.candide.dev/api/v3/1/${encodeURIComponent(apiKey)}`
const USDT_ETHEREUM = '0xdAC17F958D2ee523a2206206994597C13D831ec7'
const CANDIDE_TOKEN_PAYMASTER = '0xa8151918eac3818deb713d3dbbb7930329fe86ed'

const wallet = new WalletManagerEvm7702Gasless(seedPhrase, {
  chainId: 1,
  provider: CHAIN_RPC,
  entryPointVersion: '0.8',
  delegationAddress,
  bundlerUrl: endpoint,
  paymasterUrl: endpoint,
  paymasterAddress: CANDIDE_TOKEN_PAYMASTER,
  paymasterToken: { address: USDT_ETHEREUM },
  transferMaxFee: 100000n // 0.1 USDt (6 decimals)
})

const account = await wallet.getAccount(0)
const address = await account.getAddress()
console.log('EOA address:', address)

transferMaxFee is in paymaster-token base units; 100000n is 0.1 USD₮ with 6 decimals. It applies to transfer(), rather than every wallet operation. See fee-mode configuration before sending.

Clean Up

After running either wallet example, call dispose() when the account and wallet manager are no longer needed.

Dispose account state
account.dispose()
wallet.dispose()

Next Steps

Need Help?

On this page