WDK logoWDK documentation

Wallet EVM ERC-4337 API Reference

Complete API documentation for @tetherto/wdk-wallet-evm-erc-4337

Table of Contents

ClassDescriptionMethods
WalletManagerEvmErc4337Main class for managing ERC-4337 EVM wallets. Extends WalletManager from @tetherto/wdk-wallet.Constructor, Methods
WalletAccountEvmErc4337Individual ERC-4337 wallet account implementation. Extends WalletAccountReadOnlyEvmErc4337 and implements IWalletAccount.Constructor, Methods, Properties
WalletAccountReadOnlyEvmErc4337Read-only ERC-4337 wallet account. Extends WalletAccountReadOnly from @tetherto/wdk-wallet.Constructor, Methods
ConfigurationErrorError thrown when the wallet configuration is invalid or has missing required fields.-

WalletManagerEvmErc4337

The main class for managing ERC-4337 EVM wallets. Extends WalletManager from @tetherto/wdk-wallet.

Fee Rate Behavior

Internally, getFeeRates() applies these multipliers to the base fee:

  • Normal: base fee × 110%
  • Fast: base fee × 200%

These multipliers are internal (protected static) and cannot be imported or overridden.

Constructor

new WalletManagerEvmErc4337(seed, config)

Parameters:

  • seed (string | Uint8Array): BIP-39 mnemonic seed phrase or seed bytes
  • config (EvmErc4337WalletConfig): Configuration object with common fields and a gas payment mode

Common config fields (required for all modes):

  • chainId (number): The blockchain's ID (e.g., 1 for Ethereum mainnet)
  • provider (string | Eip1193Provider): RPC endpoint URL or EIP-1193 provider instance
  • bundlerUrl (string): The URL of the bundler service
  • entryPointAddress (string): The address of the entry point smart contract
  • safeModulesVersion (string): The Safe modules version (e.g., '0.3.0')

Gas payment mode (one of the following):

Fees are paid using an ERC-20 token through a paymaster service.

  • paymasterUrl (string): The URL of the paymaster service
  • paymasterAddress (string): The address of the paymaster smart contract
  • paymasterToken (object): The paymaster token configuration
    • address (string): The address of the ERC-20 token used for fees
  • transferMaxFee (number | bigint, optional): Maximum fee limit in paymaster token units
const wallet = new WalletManagerEvmErc4337(seedPhrase, {
  chainId: 1,
  provider: 'https://rpc.mevblocker.io/fast',
  bundlerUrl: 'https://api.candide.dev/public/v3/ethereum',
  entryPointAddress: '0x0000000071727De22E5E9d8BAf0edAc6f37da032',
  safeModulesVersion: '0.3.0',
  // Paymaster token mode
  paymasterUrl: 'https://api.candide.dev/public/v3/ethereum',
  paymasterAddress: '0x8b1f6cb5d062aa2ce8d581942bbb960420d875ba',
  paymasterToken: {
    address: '0xdAC17F958D2ee523a2206206994597C13D831ec7' // USD₮
  },
  transferMaxFee: 100000 // Optional: max fee in token units
})

Methods

MethodDescriptionReturnsThrows
getRandomSeedPhrase(wordCount?)(static) Returns a random BIP-39 seed phrasestring-
isValidSeedPhrase(seedPhrase)(static) Checks if a seed phrase is validboolean-
getAccount(index?)Returns a wallet account at the specified indexPromise<WalletAccountEvmErc4337>-
getAccountByPath(path)Returns a wallet account at the specified BIP-44 derivation pathPromise<WalletAccountEvmErc4337>-
getFeeRates()Returns current fee rates for transactionsPromise<{normal: bigint, fast: bigint}>If no provider
dispose()Disposes all wallet accounts, clearing private keys from memoryvoid-

Properties

PropertyTypeDescription
seedUint8ArrayThe wallet's seed phrase as bytes

getRandomSeedPhrase(wordCount?) (static)

Returns a random BIP-39 seed phrase.

Parameters:

  • wordCount (12 | 24, optional): The number of words in the seed phrase (default: 12)

Returns: string - The seed phrase

Example:

const seedPhrase = WalletManagerEvmErc4337.getRandomSeedPhrase()
console.log('Seed phrase:', seedPhrase) // 12 words

const longSeedPhrase = WalletManagerEvmErc4337.getRandomSeedPhrase(24)
console.log('Long seed phrase:', longSeedPhrase) // 24 words

isValidSeedPhrase(seedPhrase) (static)

Checks if a seed phrase is valid.

Parameters:

  • seedPhrase (string): The seed phrase to validate

Returns: boolean - True if the seed phrase is valid

Example:

const isValid = WalletManagerEvmErc4337.isValidSeedPhrase('abandon abandon abandon ...')
console.log('Valid:', isValid)

getAccount(index)

Returns a wallet account at the specified index using BIP-44 derivation.

Parameters:

  • index (number, optional): The index of the account to get (default: 0)

Returns: Promise<WalletAccountEvmErc4337> - The wallet account

Example:

// Get first account (index 0)
const account = await wallet.getAccount(0)

// Get default account
const defaultAccount = await wallet.getAccount()

getAccountByPath(path)

Returns a wallet account at the specified BIP-44 derivation path.

Parameters:

  • path (string): The derivation path (e.g., "0'/0/0")

Returns: Promise<WalletAccountEvmErc4337> - The wallet account

Example:

// Full derivation path: m/44'/60'/0'/0/1
const account = await wallet.getAccountByPath("0'/0/1")

getFeeRates()

Returns current fee rates with ERC-4337 specific multipliers.

Returns: Promise<{normal: bigint, fast: bigint}> - Fee rates in wei

Throws: Error if no provider is configured

Example:

const feeRates = await wallet.getFeeRates()
console.log('Normal fee rate:', feeRates.normal, 'wei') // base fee × 1.1
console.log('Fast fee rate:', feeRates.fast, 'wei')     // base fee × 2.0

dispose()

Disposes all wallet accounts, clearing private keys from memory.

Example:

// Clean up when done
wallet.dispose()

WalletAccountEvmErc4337

Represents an individual ERC-4337 wallet account. Extends WalletAccountReadOnlyEvmErc4337 and implements IWalletAccount.

Constants

The following constant is used internally for Safe account address derivation:

// Internal: used by predictSafeAddress() for deterministic address generation
const SALT_NONCE = '0x69b348339eea4ed93f9d11931c3b894c8f9d8c7663a053024b11cb7eb4e5a1f6'

Note: This constant is not re-exported from the package entry point. Use predictSafeAddress() instead of referencing it directly.

Constructor

new WalletAccountEvmErc4337(seed, path, config)

Parameters:

  • seed (string | Uint8Array): BIP-39 mnemonic seed phrase or seed bytes
  • path (string): BIP-44 derivation path (e.g., "0'/0/0")
  • config (EvmErc4337WalletConfig): Configuration object (same as WalletManagerEvmErc4337)

Example:

const account = new WalletAccountEvmErc4337(seedPhrase, "0'/0/0", {
  chainId: 1,
  provider: 'https://rpc.mevblocker.io/fast',
  bundlerUrl: 'https://api.candide.dev/public/v3/ethereum',
  entryPointAddress: '0x0000000071727De22E5E9d8BAf0edAc6f37da032',
  safeModulesVersion: '0.3.0',
  paymasterUrl: 'https://api.candide.dev/public/v3/ethereum',
  paymasterAddress: '0x8b1f6cb5d062aa2ce8d581942bbb960420d875ba',
  paymasterToken: {
    address: '0xdAC17F958D2ee523a2206206994597C13D831ec7'
  }
})

Methods

MethodDescriptionReturnsThrows
predictSafeAddress(owner, config)(static) Predicts the Safe address for a given ownerstring-
getAddress()Returns the Safe account's addressPromise<string>-
sign(message)Signs a message using the account's private keyPromise<string>-
verify(message, signature)Verifies a message signaturePromise<boolean>-
sendTransaction(tx, config?)Sends a transaction via UserOperationPromise<{hash: string, fee: bigint}>If fee exceeds max
quoteSendTransaction(tx, config?)Estimates the fee for a UserOperationPromise<{fee: bigint}>-
transfer(options, config?)Transfers ERC20 tokens via UserOperationPromise<{hash: string, fee: bigint}>If fee exceeds max
quoteTransfer(options, config?)Estimates the fee for an ERC20 transferPromise<{fee: bigint}>-
approve(options)Approves a spender to spend ERC20 tokensPromise<{hash: string, fee: bigint}>-
getBalance()Returns the native token balance (in wei)Promise<bigint>-
getTokenBalance(tokenAddress)Returns the balance of a specific ERC20 tokenPromise<bigint>-
getPaymasterTokenBalance()Returns the paymaster token balancePromise<bigint>-
getAllowance(token, spender)Returns current token allowance for a spenderPromise<bigint>-
getTransactionReceipt(hash)Returns a transaction receiptPromise<EvmTransactionReceipt | null>-
getUserOperationReceipt(hash)Returns a UserOperation receiptPromise<UserOperationReceipt | null>-
signTypedData(typedData)Signs EIP-712 typed structured dataPromise<string>-
verifyTypedData(typedData, signature)Verifies an EIP-712 typed data signaturePromise<boolean>-
getTokenBalances(tokenAddresses)Returns balances for multiple ERC20 tokensPromise<Map<string, bigint>>-
toReadOnlyAccount()Returns a read-only copy of the accountPromise<WalletAccountReadOnlyEvmErc4337>-
dispose()Disposes the wallet account, clearing private keys from memoryvoid-
getAddress()

Returns the Safe smart contract wallet address (not the underlying EOA address).

Returns: Promise<string> - The Safe account's address

Example:

const address = await account.getAddress()
console.log('Safe account address:', address) // 0x... (Smart contract address)
sign(message)

Signs a message using the underlying EOA private key.

Parameters:

  • message (string): The message to sign

Returns: Promise<string> - The message signature

Example:

const message = 'Hello, ERC-4337!'
const signature = await account.sign(message)
console.log('Signature:', signature)
verify(message, signature)

Verifies a message signature against the underlying EOA address.

Parameters:

  • message (string): The original message
  • signature (string): The signature to verify

Returns: Promise<boolean> - True if signature is valid

Example:

const isValid = await account.verify(message, signature)
console.log('Signature valid:', isValid)
sendTransaction(tx, config?)

Sends a transaction via UserOperation through the bundler.

Parameters:

  • tx (EvmTransaction | EvmTransaction[]): Transaction object or array for batch transactions
    • to (string): Recipient address
    • value (number | bigint): Amount in wei
    • data (string, optional): Transaction data in hex format
  • config (optional): Per-call configuration override. Accepts a partial version of the gas payment mode fields (see Config Override).

Returns: Promise<{hash: string, fee: bigint}> - UserOperation hash and fee

Throws: Error if fee exceeds transferMaxFee

Example:

// Single transaction
const result = await account.sendTransaction({
  to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  value: 1000000000000000000n, // 1 ETH
  data: '0x'
})
console.log('UserOperation hash:', result.hash)
console.log('Fee paid:', result.fee)

// Batch transactions
const batchResult = await account.sendTransaction([
  { to: '0x...', value: 100000000000000000n },
  { to: '0x...', value: 200000000000000000n }
])

// With per-call config override
const customResult = await account.sendTransaction({
  to: '0x...',
  value: 1000000000000000000n
}, {
  paymasterToken: { address: '0xNewToken...' }
})
quoteSendTransaction(tx, config?)

Estimates the fee for a UserOperation without sending it.

Parameters:

  • tx (EvmTransaction | EvmTransaction[]): Transaction object or array (same as sendTransaction)
  • config (optional): Per-call configuration override (see Config Override)

Returns: Promise<{fee: bigint}> - Fee estimate

Example:

const quote = await account.quoteSendTransaction({
  to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  value: 1000000000000000000n
})
console.log('Estimated fee:', quote.fee)
transfer(options, config?)

Transfers ERC20 tokens via UserOperation.

Parameters:

  • options (TransferOptions): Transfer options
    • token (string): ERC20 token contract address
    • recipient (string): Recipient address
    • amount (number | bigint): Amount in token base units
  • config (optional): Per-call configuration override (see Config Override)

Returns: Promise<{hash: string, fee: bigint}> - UserOperation hash and fee

Throws:

  • Error if fee exceeds transferMaxFee
  • Error if insufficient token balance

Example:

const result = await account.transfer({
  token: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USD₮
  recipient: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  amount: 1000000 // 1 USD₮ (6 decimals)
}, {
  transferMaxFee: 50000 // Override max fee for this call
})
console.log('Transfer hash:', result.hash)
console.log('Transfer fee:', result.fee)
quoteTransfer(options, config?)

Estimates the fee for an ERC20 token transfer.

Parameters:

  • options (TransferOptions): Transfer options (same as transfer)
  • config (optional): Per-call configuration override (see Config Override)

Returns: Promise<{fee: bigint}> - Fee estimate

Example:

const quote = await account.quoteTransfer({
  token: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
  recipient: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  amount: 1000000
})
console.log('Transfer fee estimate:', quote.fee)
getBalance()

Returns the Safe account's native token balance.

Returns: Promise<bigint> - Balance in wei

Example:

const balance = await account.getBalance()
console.log('Native balance:', balance, 'wei')
getTokenBalance(tokenAddress)

Returns the balance of a specific ERC20 token in the Safe account.

Parameters:

  • tokenAddress (string): The ERC20 token contract address

Returns: Promise<bigint> - Token balance in base units

Example:

const tokenBalance = await account.getTokenBalance('0xdAC17F958D2ee523a2206206994597C13D831ec7')
console.log('USDT balance:', tokenBalance) // In 6 decimal units
getPaymasterTokenBalance()

Returns the balance of the configured paymaster token used for paying fees.

Returns: Promise<bigint> - Paymaster token balance in base units

Example:

const paymasterBalance = await account.getPaymasterTokenBalance()
console.log('Paymaster token balance:', paymasterBalance)

// Check if sufficient for transaction
if (paymasterBalance < 10000n) {
  console.warn('Low paymaster token balance - may not cover fees')
}
approve(options)

Approves a spender to spend ERC20 tokens on behalf of the Safe account.

Parameters:

  • options (ApproveOptions): Approve options
    • token (string): ERC20 token contract address
    • spender (string): The address allowed to spend the tokens
    • amount (number | bigint): Amount to approve in token base units

Returns: Promise<{hash: string, fee: bigint}> - Transaction result

Example:

const result = await account.approve({
  token: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
  spender: '0xSpenderContract...',
  amount: 1000000n // 1 USD₮
})
console.log('Approval hash:', result.hash)
getAllowance(token, spender)

Returns the current token allowance for the given spender.

Parameters:

  • token (string): ERC20 token contract address
  • spender (string): The spender's address

Returns: Promise<bigint> - The current allowance

Example:

const allowance = await account.getAllowance(
  '0xdAC17F958D2ee523a2206206994597C13D831ec7',
  '0xSpenderContract...'
)
console.log('Current allowance:', allowance)
getTransactionReceipt(hash)

Returns a transaction receipt by hash.

Parameters:

  • hash (string): The transaction hash

Returns: Promise<EvmTransactionReceipt | null> - Transaction receipt or null if not mined

Example:

const receipt = await account.getTransactionReceipt('0x...')
if (receipt) {
  console.log('Confirmed in block:', receipt.blockNumber)
}
getUserOperationReceipt(hash)

Returns a UserOperation receipt by hash.

Parameters:

  • hash (string): The UserOperation hash

Returns: Promise<UserOperationReceipt | null> - UserOperation receipt or null if not processed

Example:

const receipt = await account.getUserOperationReceipt('0x...')
if (receipt) {
  console.log('UserOp receipt:', receipt)
}
signTypedData(typedData)

Signs EIP-712 typed structured data using the underlying EOA private key.

Parameters:

  • typedData (TypedData): The typed data object containing domain, types, primaryType, and message

Returns: Promise<string> - The typed data signature

Example:

const typedData = {
  domain: {
    name: 'MyDApp',
    version: '1',
    chainId: 1,
    verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
  },
  types: {
    Transfer: [
      { name: 'to', type: 'address' },
      { name: 'amount', type: 'uint256' }
    ]
  },
  primaryType: 'Transfer',
  message: {
    to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
    amount: 1000000n
  }
}

const signature = await account.signTypedData(typedData)
console.log('Typed data signature:', signature)
verifyTypedData(typedData, signature)

Verifies an EIP-712 typed data signature against the underlying EOA address.

Parameters:

  • typedData (TypedData): The original typed data object
  • signature (string): The signature to verify

Returns: Promise<boolean> - True if the signature is valid

Example:

const isValid = await account.verifyTypedData(typedData, signature)
console.log('Typed data signature valid:', isValid)
getTokenBalances(tokenAddresses)

Returns balances for multiple ERC20 tokens in a single call.

Parameters:

  • tokenAddresses (string[]): Array of ERC20 token contract addresses

Returns: Promise<Map<string, bigint>> - Map of token address to balance in base units

Example:

const balances = await account.getTokenBalances([
  '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT
  '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'  // USDC
])
for (const [address, balance] of balances) {
  console.log(`Token ${address}: ${balance}`)
}
toReadOnlyAccount()

Creates a read-only copy of the account with the same Safe address and configuration.

Returns: Promise<WalletAccountReadOnlyEvmErc4337> - Read-only account instance

Example:

const readOnlyAccount = await account.toReadOnlyAccount()

// Can check balances but cannot send transactions
const balance = await readOnlyAccount.getBalance()
// readOnlyAccount.sendTransaction() // Would not be available
dispose()

Disposes the wallet account, clearing private keys from memory.

Example:

account.dispose()

Properties

PropertyTypeDescription
indexnumberThe derivation path's index of this account
pathstringThe full BIP-44 derivation path of this account
keyPair{privateKey: Uint8Array | null, publicKey: Uint8Array}The account's key pair (⚠️ Contains sensitive data)

Example:

console.log('Account index:', account.index) // 0, 1, 2, etc.
console.log('Account path:', account.path) // m/44'/60'/0'/0/0

// ⚠️ SENSITIVE: Handle with care
const { privateKey, publicKey } = account.keyPair
console.log('Public key length:', publicKey.length) // 65 bytes
console.log('Private key length:', privateKey?.length) // 32 bytes (null after dispose)

⚠️ Security Note: The keyPair property contains sensitive cryptographic material. Never log, display, or expose the private key.

WalletAccountReadOnlyEvmErc4337

Represents a read-only ERC-4337 wallet account that can query balances and estimate fees but cannot send transactions.

Constants

The following constant is used internally for Safe account address derivation:

// Internal: used by predictSafeAddress() for deterministic address generation
const SALT_NONCE = '0x69b348339eea4ed93f9d11931c3b894c8f9d8c7663a053024b11cb7eb4e5a1f6'

Note: This constant is not re-exported from the package entry point. Use predictSafeAddress() instead of referencing it directly.

Constructor

new WalletAccountReadOnlyEvmErc4337(address, config)

Parameters:

  • address (string): The EOA address (owner address)
  • config (Omit&lt;EvmErc4337WalletConfig, 'transferMaxFee'&gt;): Configuration object without transferMaxFee

Example:

const readOnlyAccount = new WalletAccountReadOnlyEvmErc4337('0x...', {
  chainId: 1,
  provider: 'https://rpc.mevblocker.io/fast',
  bundlerUrl: 'https://api.candide.dev/public/v3/ethereum',
  entryPointAddress: '0x0000000071727De22E5E9d8BAf0edAc6f37da032',
  safeModulesVersion: '0.3.0',
  paymasterUrl: 'https://api.candide.dev/public/v3/ethereum',
  paymasterAddress: '0x8b1f6cb5d062aa2ce8d581942bbb960420d875ba',
  paymasterToken: {
    address: '0xdAC17F958D2ee523a2206206994597C13D831ec7'
  }
})

Static Methods

MethodDescriptionReturns
predictSafeAddress(owner, config)Predicts the Safe address for a given owner without instantiating an accountstring

predictSafeAddress(owner, config) (static)

Predicts the address of a Safe account.

Parameters:

  • owner (string): The Safe owner's EOA address
  • config (object): Configuration with:
    • chainId (number): The blockchain ID
    • safeModulesVersion (string): The Safe modules version

Returns: string - The predicted Safe address

Example:

const safeAddress = WalletAccountReadOnlyEvmErc4337.predictSafeAddress(
  '0xOwnerEOA...',
  { chainId: 1, safeModulesVersion: '0.3.0' }
)
console.log('Predicted Safe address:', safeAddress)

// Also available on WalletAccountEvmErc4337 (inherited)
const sameAddress = WalletAccountEvmErc4337.predictSafeAddress(
  '0xOwnerEOA...',
  { chainId: 1, safeModulesVersion: '0.3.0' }
)

Methods

MethodDescriptionReturnsThrows
getAddress()Returns the Safe account's addressPromise<string>-
verify(message, signature)Verifies a message signaturePromise<boolean>-
getBalance()Returns the native token balance (in wei)Promise<bigint>-
getTokenBalance(tokenAddress)Returns the balance of a specific ERC20 tokenPromise<bigint>-
getPaymasterTokenBalance()Returns the paymaster token balancePromise<bigint>-
getAllowance(token, spender)Returns current token allowance for a spenderPromise<bigint>-
quoteSendTransaction(tx, config?)Estimates the fee for a UserOperationPromise<{fee: bigint}>If simulation fails
quoteTransfer(options, config?)Estimates the fee for an ERC20 transferPromise<{fee: bigint}>If simulation fails
getTransactionReceipt(hash)Returns a transaction receiptPromise<EvmTransactionReceipt | null>-
getUserOperationReceipt(hash)Returns a UserOperation receiptPromise<UserOperationReceipt | null>-
signTypedData(typedData)Signs EIP-712 typed structured dataPromise<string>-
verifyTypedData(typedData, signature)Verifies an EIP-712 typed data signaturePromise<boolean>-
getTokenBalances(tokenAddresses)Returns balances for multiple ERC20 tokensPromise<Map<string, bigint>>-
getAddress()

Returns the Safe smart contract wallet address.

Returns: Promise<string> - The Safe account's address

Example:

const address = await readOnlyAccount.getAddress()
console.log('Safe address:', address)
verify(message, signature)

Verifies a message signature against the underlying EOA address.

Parameters:

  • message (string): The original message
  • signature (string): The signature to verify

Returns: Promise<boolean> - True if signature is valid

Example:

const isValid = await readOnlyAccount.verify(message, signature)
console.log('Signature valid:', isValid)
getBalance()

Returns the Safe account's native token balance.

Returns: Promise<bigint> - Balance in wei

Example:

const balance = await readOnlyAccount.getBalance()
console.log('Balance:', balance, 'wei')
getTokenBalance(tokenAddress)

Returns the balance of a specific ERC20 token.

Parameters:

  • tokenAddress (string): The ERC20 token contract address

Returns: Promise<bigint> - Token balance in base units

Example:

const tokenBalance = await readOnlyAccount.getTokenBalance('0xdAC17F958D2ee523a2206206994597C13D831ec7')
console.log('USDT balance:', tokenBalance)
getPaymasterTokenBalance()

Returns the balance of the configured paymaster token.

Returns: Promise<bigint> - Paymaster token balance in base units

Example:

const paymasterBalance = await readOnlyAccount.getPaymasterTokenBalance()
console.log('Paymaster token balance:', paymasterBalance)
getAllowance(token, spender)

Returns the current token allowance for the given spender.

Parameters:

  • token (string): ERC20 token contract address
  • spender (string): The spender's address

Returns: Promise<bigint> - The current allowance

Example:

const allowance = await readOnlyAccount.getAllowance(
  '0xdAC17F958D2ee523a2206206994597C13D831ec7',
  '0xSpenderContract...'
)
console.log('Allowance:', allowance)
quoteSendTransaction(tx, config?)

Estimates the fee for a UserOperation.

Parameters:

  • tx (EvmTransaction | EvmTransaction[]): Transaction object or array
  • config (optional): Per-call configuration override (see Config Override)

Returns: Promise<{fee: bigint}> - Fee estimate

Throws: Error if simulation fails

Example:

try {
  const quote = await readOnlyAccount.quoteSendTransaction({
    to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
    value: 1000000000000000000n
  })
  console.log('Estimated fee:', quote.fee)
} catch (error) {
  if (error.message.includes('not enough funds')) {
    console.error('Insufficient paymaster token balance')
  }
}
quoteTransfer(options, config?)

Estimates the fee for an ERC20 token transfer.

Parameters:

  • options (TransferOptions): Transfer options
  • config (optional): Per-call configuration override (see Config Override)

Returns: Promise<{fee: bigint}> - Fee estimate

Example:

const quote = await readOnlyAccount.quoteTransfer({
  token: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
  recipient: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  amount: 1000000
})
console.log('Transfer fee estimate:', quote.fee)
getTransactionReceipt(hash)

Returns a transaction receipt by hash.

Parameters:

  • hash (string): The transaction hash

Returns: Promise<EvmTransactionReceipt | null> - Transaction receipt or null if not mined

Example:

const receipt = await readOnlyAccount.getTransactionReceipt('0x...')
if (receipt) {
  console.log('Transaction confirmed in block:', receipt.blockNumber)
  console.log('Status:', receipt.status) // 1 = success, 0 = failed
} else {
  console.log('Transaction not yet mined')
}
getUserOperationReceipt(hash)

Returns a UserOperation receipt by hash.

Parameters:

  • hash (string): The UserOperation hash

Returns: Promise<UserOperationReceipt | null> - UserOperation receipt or null if not processed

Example:

const receipt = await readOnlyAccount.getUserOperationReceipt('0x...')
if (receipt) {
  console.log('UserOp receipt:', receipt)
}
signTypedData(typedData)

Signs EIP-712 typed structured data using the underlying EOA address.

Parameters:

  • typedData (TypedData): The typed data object containing domain, types, primaryType, and message

Returns: Promise<string> - The typed data signature

Example:

const typedData = {
  domain: {
    name: 'MyDApp',
    version: '1',
    chainId: 1,
    verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
  },
  types: {
    Transfer: [
      { name: 'to', type: 'address' },
      { name: 'amount', type: 'uint256' }
    ]
  },
  primaryType: 'Transfer',
  message: {
    to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
    amount: 1000000n
  }
}

const signature = await readOnlyAccount.signTypedData(typedData)
console.log('Typed data signature:', signature)
verifyTypedData(typedData, signature)

Verifies an EIP-712 typed data signature against the underlying EOA address.

Parameters:

  • typedData (TypedData): The original typed data object
  • signature (string): The signature to verify

Returns: Promise<boolean> - True if the signature is valid

Example:

const isValid = await readOnlyAccount.verifyTypedData(typedData, signature)
console.log('Typed data signature valid:', isValid)
getTokenBalances(tokenAddresses)

Returns balances for multiple ERC20 tokens in a single call.

Parameters:

  • tokenAddresses (string[]): Array of ERC20 token contract addresses

Returns: Promise<Map<string, bigint>> - Map of token address to balance in base units

Example:

const balances = await readOnlyAccount.getTokenBalances([
  '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT
  '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'  // USDC
])
for (const [address, balance] of balances) {
  console.log(`Token ${address}: ${balance}`)
}

Types

EvmErc4337WalletConfig

The configuration is a union type combining common fields with one of three gas payment modes:

// Common fields (required for all modes)
interface EvmErc4337WalletCommonConfig {
  chainId: number;                          // Blockchain ID
  provider: string | Eip1193Provider;       // RPC provider
  bundlerUrl: string;                       // Bundler service URL
  entryPointAddress: string;                // EntryPoint contract address
  safeModulesVersion: string;               // Safe modules version (e.g., '0.3.0')
}

// Mode 1: Paymaster Token
interface EvmErc4337WalletPaymasterTokenConfig {
  isSponsored?: false;
  useNativeCoins?: false;
  paymasterUrl: string;                     // Paymaster service URL
  paymasterAddress: string;                 // Paymaster contract address
  paymasterToken: { address: string };      // ERC-20 token for fees
  transferMaxFee?: number | bigint;         // Maximum fee limit
}

// Mode 2: Sponsorship Policy
interface EvmErc4337WalletSponsorshipPolicyConfig {
  isSponsored: true;
  useNativeCoins?: false;
  paymasterUrl: string;                     // Paymaster service URL
  sponsorshipPolicyId?: string;             // Sponsorship policy ID
}

// Mode 3: Native Coins
interface EvmErc4337WalletNativeCoinsConfig {
  isSponsored?: false;
  useNativeCoins: true;
  transferMaxFee?: number | bigint;         // Maximum fee limit
}

// Full config type
type EvmErc4337WalletConfig = EvmErc4337WalletCommonConfig &
  (EvmErc4337WalletPaymasterTokenConfig |
   EvmErc4337WalletSponsorshipPolicyConfig |
   EvmErc4337WalletNativeCoinsConfig);

Config Override

The config parameter on sendTransaction, quoteSendTransaction, transfer, and quoteTransfer allows per-call overrides of gas payment settings:

type ConfigOverride = Partial<
  EvmErc4337WalletPaymasterTokenConfig |
  EvmErc4337WalletSponsorshipPolicyConfig |
  EvmErc4337WalletNativeCoinsConfig
>;

Available override fields:

  • isSponsored (boolean): Switch to sponsorship mode
  • useNativeCoins (boolean): Switch to native coin mode
  • paymasterUrl (string): Override paymaster URL
  • paymasterAddress (string): Override paymaster contract
  • paymasterToken ({address: string}): Override paymaster token
  • sponsorshipPolicyId (string): Set sponsorship policy
  • transferMaxFee (number | bigint): Override maximum fee

EvmTransaction

interface EvmTransaction {
  to: string;                               // Recipient address
  value: number | bigint;                   // Amount in wei
  data?: string;                            // Transaction data (optional)
  gasLimit?: number | bigint;               // Gas limit (optional)
  gasPrice?: number | bigint;               // Legacy gas price (optional)
  maxFeePerGas?: number | bigint;           // EIP-1559 max fee (optional)
  maxPriorityFeePerGas?: number | bigint;   // EIP-1559 priority fee (optional)
}

TransferOptions

interface TransferOptions {
  token: string;                            // ERC20 token contract address
  recipient: string;                        // Recipient address
  amount: number | bigint;                  // Amount in token base units
}

ApproveOptions

interface ApproveOptions {
  token: string;                            // ERC20 token contract address
  spender: string;                          // Address allowed to spend tokens
  amount: number | bigint;                  // Amount to approve in base units
}

TransactionResult

interface TransactionResult {
  hash: string;                             // UserOperation hash
  fee: bigint;                              // Fee paid
}

TransferResult

interface TransferResult {
  hash: string;                             // UserOperation hash
  fee: bigint;                              // Fee paid
}

TypedData

interface TypedData {
  domain: TypedDataDomain;                  // EIP-712 domain separator
  types: Record<string, TypedDataField[]>;  // Type definitions
  primaryType: string;                      // Primary type name
  message: Record<string, unknown>;         // Structured message data
}

TypedDataDomain

interface TypedDataDomain {
  name?: string;                            // DApp or protocol name
  version?: string;                         // Domain version
  chainId?: number;                         // Blockchain ID
  verifyingContract?: string;               // Contract address
  salt?: string;                            // Optional salt
}

TypedDataField

interface TypedDataField {
  name: string;                             // Field name
  type: string;                             // Solidity type (e.g., 'address', 'uint256')
}

UserOperationReceipt

interface UserOperationReceipt {
  userOpHash: string;                       // UserOperation hash
  sender: string;                           // Sender address
  nonce: bigint;                            // Nonce
  actualGasUsed: bigint;                    // Gas used
  actualGasCost: bigint;                    // Gas cost
  success: boolean;                         // Whether the operation succeeded
  receipt: EvmTransactionReceipt;           // The underlying transaction receipt
}

ConfigurationError

class ConfigurationError extends Error {
  // Thrown when the wallet configuration is invalid
  // e.g., missing required fields for the selected gas payment mode
}

FeeRates

interface FeeRates {
  normal: bigint;                             // Fee rate for normal priority
  fast: bigint;                               // Fee rate for fast priority
}

KeyPair

interface KeyPair {
  publicKey: Uint8Array;                      // The public key
  privateKey: Uint8Array | null;              // The private key (null after dispose)
}

Internal Constants

The following constants are used internally by the SDK and are not importable from the package entry point.

// Used by predictSafeAddress() for deterministic address generation
// Not re-exported from '@tetherto/wdk-wallet-evm-erc-4337'
const SALT_NONCE: string = '0x69b348339eea4ed93f9d11931c3b894c8f9d8c7663a053024b11cb7eb4e5a1f6';

// Fee rate multipliers (protected static on WalletManagerEvm)
// Applied internally by getFeeRates()
const _FEE_RATE_NORMAL_MULTIPLIER: bigint;  // ~110%
const _FEE_RATE_FAST_MULTIPLIER: bigint;    // ~200%

Need Help?

On this page