WDK logoWDK documentation

Get Started

Install and create your first ERC-4337 smart account wallet.

Create an Ethereum smart account with Candide or Pimlico and pay UserOperation gas fees in USD₮.

1. Install the Package

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-erc-4337@1.0.0-beta.21

2. Choose a Bundler and Paymaster

The examples use Ethereum mainnet (chainId: 1), Safe modules 0.3.0, and EntryPoint v0.7. Your chain RPC must serve Ethereum; the dropdown selects the bundler and paymaster configuration separately.

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.

Before sending, confirm your selected endpoint supports EntryPoint v0.7 and Ethereum USD₮ at 0xdAC17F958D2ee523a2206206994597C13D831ec7. Check the current token and paymaster contract with your provider: availability can depend on the API key. Use Candide’s pm_supportedERC20Tokens or Pimlico’s pimlico_getTokenQuotes, and review paymaster configuration.

3. Create a Wallet

Read WALLET_SEED_PHRASE from your application's secure seed storage. The Node.js examples below read it from the environment. Keep seeds and API keys out of source control and logs; an authenticated endpoint URL contains your API key. Never use a publicly shared seed for real funds.

Copy the complete example for your selected provider into a .mjs file and run it with node after setting its environment variables. Switching the dropdown changes the examples on this page; recreate your wallet with the new configuration if you change providers in your application.

Candide

Candide: ERC-4337 wallet
import WalletManagerEvmErc4337 from '@tetherto/wdk-wallet-evm-erc-4337'

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

if (!seedPhrase || !apiKey) {
  throw new Error('Set WALLET_SEED_PHRASE, CANDIDE_API_KEY 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 = '0x8b1f6cb5d062aa2ce8d581942bbb960420d875ba'

const wallet = new WalletManagerEvmErc4337(seedPhrase, {
  chainId: 1,
  provider: CHAIN_RPC,
  safeModulesVersion: '0.3.0',
  bundlerUrl: endpoint,
  paymasterUrl: endpoint,
  paymasterAddress: CANDIDE_TOKEN_PAYMASTER,
  paymasterToken: { address: USDT_ETHEREUM }
})

Creating the wallet does not deploy or fund the smart account. Before submitting a token-paid operation, fund the smart account with enough USD₮ to cover its fees. The module includes the paymaster allowance in the UserOperation and rejects a returned paymaster address that differs from the configured pin.

The chain RPC must serve the configured chainId. A mismatch throws when the account first builds a UserOperation; account creation alone does not establish that the RPC matches. Review chain validation before sending.

For test tokens instead of real funds, use the testnet configuration with the corresponding chain, token, and paymaster settings.

4. Get Your First Account

Retrieve a smart account at a given index using wallet.getAccount():

Get your smart account address
const account = await wallet.getAccount(0)
const address = await account.getAddress()
console.log('Smart account address:', address)

5. Convert to Read-Only (Optional)

Convert an owned account using account.toReadOnlyAccount():

Convert to read-only
const readOnlyAccount = await account.toReadOnlyAccount()

Next Steps

Need Help?

On this page