WDK logoWDK documentation

Wallet EVM API Reference

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

This reference covers @tetherto/wdk-wallet-evm@1.0.0-beta.22.

Table of Contents

ClassDescriptionMethods
WalletManagerEvmMain class for managing EVM wallets. Extends WalletManager from @tetherto/wdk-wallet.Constructor, Methods
WalletAccountEvmIndividual EVM wallet account implementation. Extends WalletAccountReadOnlyEvm and implements IWalletAccount from @tetherto/wdk-wallet.Constructor, Methods, Properties
WalletAccountReadOnlyEvmRead-only EVM wallet account. Extends WalletAccountReadOnly from @tetherto/wdk-wallet.Constructor, Methods

WalletManagerEvm

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

Constructor

new WalletManagerEvm(seedOrSigner, config?)

Parameters:

  • seedOrSigner (string | Uint8Array | ISignerEvm): BIP-39 mnemonic seed phrase, seed bytes, or a derivable root signer
  • config (object, optional): Configuration object
    • provider (string | Provider | Eip1193Provider | Array<string | Provider | Eip1193Provider>, optional): RPC endpoint URL, ethers provider, EIP-1193 provider, or ordered failover list
    • retries (number, optional): Additional retry attempts when provider is an array
    • chainId (number, optional): Network chain ID. When provided, skips automatic chain ID detection.
    • transferMaxFee (number | bigint, optional): Maximum fee amount for transfer operations (in wei)
    • transactionMaxFee (number | bigint, optional): Execution-gas fee cap for sendTransaction() and provider-backed signTransaction() (in wei), including sends made by transfer() and approve()

The default signer must support derivation. Register non-derivable signers, such as private-key signers, with addSigner() and retrieve them by name.

The runtime and published configuration type accept an ethers Provider. The manager reuses one provider object across its accounts.

Throws:

  • ValueError if a string seed phrase is not a valid BIP-39 mnemonic.
  • InvalidSignerError if the default signer does not support account derivation.

Example:

const wallet = new WalletManagerEvm(seedPhrase, {
  provider: 'https://rpc.mevblocker.io/fast',
  transferMaxFee: 100000000000000, // Maximum ERC-20 transfer fee in wei
  transactionMaxFee: 100000000000000 // Execution-gas fee cap in wei
})

import { SeedSignerEvm } from '@tetherto/wdk-wallet-evm/signers'

const signer = new SeedSignerEvm(seedPhrase)
const signerWallet = new WalletManagerEvm(signer, {
  provider: 'https://rpc.mevblocker.io/fast'
})

Methods

MethodDescriptionReturnsThrows
getRandomSeedPhrase(wordCount?)(static) Returns a random BIP-39 seed phrasestring-
isValidSeedPhrase(seedPhrase)(static) Checks if a seed phrase is validboolean-
addSigner(signerName, signer)Registers a named signer on the managerWalletManagerEvmIf signerName is empty
getSigner(signerName?)Returns the default signer or a named signerISignerEvmIf the requested signer is unavailable
getSigners()Returns registered named signersRecord<string, ISignerEvm>-
getAccount(index?, options?)Returns a wallet account at the specified index, optionally from a named signerPromise<WalletAccountEvm>If the requested signer is unavailable or cannot derive
getAccount(signerName)Returns the account associated with a registered signerPromise<WalletAccountEvm>If the named signer is unavailable
getAccountByPath(path, options?)Returns a wallet account at the specified BIP-44 derivation path, optionally from a named signerPromise<WalletAccountEvm>If the requested signer is unavailable or cannot derive
getFeeRates()Returns current fee rates for transactionsPromise<{normal: bigint, fast: bigint}>ProviderRequiredError if no provider is set
dispose()Initiates cleanup of wallet accountsvoid-

Properties

PropertyTypeDescription
seedUint8ArrayThe wallet's seed 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 = WalletManagerEvm.getRandomSeedPhrase()
console.log('Seed phrase:', seedPhrase) // 12 words

const longSeedPhrase = WalletManagerEvm.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 = WalletManagerEvm.isValidSeedPhrase('abandon abandon abandon ...')
console.log('Valid:', isValid)

addSigner(signerName, signer)

Registers a signer under a name. Use this for external or non-default signers that should be retrieved explicitly.

Parameters:

  • signerName (string): Name used for lookup
  • signer (ISignerEvm): Signer instance

Returns: WalletManagerEvm - The wallet manager

Example:

import { PrivateKeySignerEvm } from '@tetherto/wdk-wallet-evm/signers'

wallet.addSigner('treasury', new PrivateKeySignerEvm(privateKey))

getSigner(signerName?)

Returns the default signer when called with no argument, or a registered named signer.

Parameters:

  • signerName (string, optional): Name registered with addSigner()

Returns: ISignerEvm - The signer

getSigners()

Returns a shallow copy of the named signers registered with addSigner(). The default signer is not included.

Returns: Record<string, ISignerEvm> - Registered named signers

getAccount(index?)

Returns a wallet account at the specified index following BIP-44 standard. Pass options.signerName to derive the account from a registered derivable signer.

Parameters:

  • index (number, optional): The index of the account to get (default: 0)
  • options.signerName (string, optional): Registered signer name

Returns: Promise<WalletAccountEvm> - The wallet account

Example:

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

// Get second account (index 1)
const account1 = await wallet.getAccount(1)

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

// Derive account 2 from a registered derivable signer
const signerAccount = await wallet.getAccount(2, { signerName: 'hardware-root' })

getAccount(signerName)

Returns an account wrapping the registered signer exactly at its current path, without deriving. This also applies to derivable named signers. Use the numeric or path overload with options.signerName to derive a child instead.

Parameters:

  • signerName (string): Name registered with addSigner()

Returns: Promise<WalletAccountEvm> - The signer-backed wallet account

Example:

const treasuryAccount = await wallet.getAccount('treasury')

getAccountByPath(path)

Returns a wallet account at the specified BIP-44 derivation path. Pass options.signerName to derive from a registered derivable signer.

Parameters:

  • path (string): The derivation path (e.g., "0'/0/0")
  • options.signerName (string, optional): Registered signer name

Returns: Promise<WalletAccountEvm> - The wallet account

Example:

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

// Custom path: m/44'/60'/0'/0/5
const customAccount = await wallet.getAccountByPath("0'/0/5")

const customSignerAccount = await wallet.getAccountByPath("0'/0/5", {
  signerName: 'hardware-root'
})

getFeeRates()

Returns current fee rates based on network conditions with predefined multipliers.

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

  • normal: Base fee × 1.1 (10% above base)
  • fast: Base fee × 2.0 (100% above base)

Throws: ProviderRequiredError if no provider is configured

Example:

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

// Use in transaction
const result = await account.sendTransaction({
  to: '0x...',
  value: 1000000000000000000n,
  maxFeePerGas: feeRates.fast
})

dispose()

Initiates cleanup of the seed-created default signer, then delegates to base-wallet beta.21. Cached accounts are disposed only when reading account.keyPair?.privateKey yields a truthy value. Derived external accounts without exposed private-key bytes are skipped; dispose them explicitly. A throwing key getter or disposal can interrupt later cleanup. App-supplied default and named signers remain app-owned.

Example:

// Clean up when done
wallet.dispose()

WalletAccountEvm

Represents an individual wallet account. Extends WalletAccountReadOnlyEvm and implements IWalletAccount from @tetherto/wdk-wallet.

Constructor

new WalletAccountEvm(seed, path, config?)
new WalletAccountEvm(seed, config?)
new WalletAccountEvm(signer, config?)

Parameters:

  • seed (string | Uint8Array): BIP-39 mnemonic seed phrase or seed bytes
  • path (string, optional for the seed overload): Path relative to m/44'/60', defaulting to 0'/0/0
  • signer (ISignerEvm): EVM signer; import the interface from @tetherto/wdk-wallet-evm/signers
  • config (object, optional): Configuration object
    • provider (string | Provider | Eip1193Provider | Array<string | Provider | Eip1193Provider>, optional): RPC endpoint URL, ethers provider, EIP-1193 provider, or ordered failover list
    • retries (number, optional): Additional retry attempts when provider is an array
    • chainId (number, optional): Network chain ID. When provided, skips automatic chain ID detection.
    • transferMaxFee (number | bigint, optional): Maximum fee amount for transfer operations (in wei)
    • transactionMaxFee (number | bigint, optional): Execution-gas fee cap for sendTransaction() and provider-backed signTransaction() (in wei), including sends made by transfer() and approve()
  • config.shouldWipeSignerOnDisposal (boolean, signer overload only): Dispose the supplied signer when the account is disposed. Defaults to false; seed-created and fromPrivateKey() accounts own their signers.

Throws:

  • ValueError if a string seed phrase is not a valid BIP-39 mnemonic.

Example:

const account = new WalletAccountEvm(seedPhrase, "0'/0/0", {
  provider: 'https://rpc.mevblocker.io/fast',
  transferMaxFee: 100000000000000,
  transactionMaxFee: 100000000000000
})

import { PrivateKeySignerEvm } from '@tetherto/wdk-wallet-evm/signers'

const signerAccount = new WalletAccountEvm(
  new PrivateKeySignerEvm(privateKey),
  { provider: 'https://rpc.mevblocker.io/fast' }
)

Static Methods

MethodDescriptionReturnsThrows
fromPrivateKey(privateKey, config?)Creates a standalone account from a raw private keyWalletAccountEvmIf the private key is invalid

Methods

MethodDescriptionReturnsThrows
getAddress()Returns the account's addressPromise<string>-
sign(message)Signs a message using the account's private keyPromise<string>-
signTypedData(typedData)Signs typed data according to EIP-712Promise<string>-
signTransaction(tx)Signs an EVM transaction without broadcasting itPromise<string>MaximumFeeExceededError or ValueError
verify(message, signature)Verifies a message signaturePromise<boolean>-
verifyTypedData(typedData, signature)Verifies a typed data signature (EIP-712)Promise<boolean>-
sendTransaction(tx)Sends an EVM transaction object or signed raw transactionPromise<{hash: string, fee: bigint}>ProviderRequiredError, MaximumFeeExceededError, or ValueError
quoteSendTransaction(tx)Estimates the fee for an EVM transaction object or serialized transactionPromise<{fee: bigint}>ProviderRequiredError or ValueError
transfer(options)Transfers ERC20 tokens to another addressPromise<{hash: string, fee: bigint}>ProviderRequiredError, MaximumFeeExceededError, or ValueError
quoteTransfer(options)Estimates the fee for an ERC20 transferPromise<{fee: bigint}>ProviderRequiredError or ValueError
getBalance()Returns the native token balance (in wei)Promise<bigint>ProviderRequiredError
getTokenBalance(tokenAddress)Returns the balance of a specific ERC20 tokenPromise<bigint>ProviderRequiredError
getTokenBalances(tokenAddresses)Returns balances for multiple ERC20 tokensPromise<Record<string, bigint>>ProviderRequiredError
approve(options)Approves a spender to spend tokensPromise<{hash: string, fee: bigint}>ProviderRequiredError or ValueError
getAllowance(token, spender)Returns current allowance for a spenderPromise<bigint>ProviderRequiredError
getTransactionReceipt(hash)Returns a native receipt; deprecated in favor of getTransaction()Promise<EvmTransactionReceipt | null>ProviderRequiredError
getTransaction(hash)Returns normalized finality and the native receiptPromise<TransactionReceipt & EvmTransactionDetails>ProviderRequiredError, ValueError, or NoSuchElementError
waitForTransaction(hash, options?)Waits for confirmed or final, or returns droppedPromise<TransactionReceipt & EvmTransactionDetails>TimeoutError
toReadOnlyAccount()Returns a read-only copy of the accountPromise<WalletAccountReadOnlyEvm>-
signAuthorization(auth)Signs an ERC-7702 authorization tuplePromise<Authorization>ProviderRequiredError or AssertionError
delegate(delegateAddress)Delegates the EOA to a contract through an ERC-7702 type 4 transactionPromise<{hash: string, fee: bigint}>ProviderRequiredError or AssertionError
revokeDelegation()Revokes active ERC-7702 delegation by delegating to the zero addressPromise<{hash: string, fee: bigint}>ProviderRequiredError or AssertionError
dispose()Initiates the account cleanup processvoid-

fromPrivateKey(privateKey, config?) (static)

Creates a standalone EVM account from a raw private key.

Parameters:

  • privateKey (string | Uint8Array): Raw private key, as a hex string with or without 0x, or 32 bytes
  • config (object, optional): EVM wallet configuration

Returns: WalletAccountEvm - The wallet account

Example:

const account = WalletAccountEvm.fromPrivateKey(privateKey, {
  provider: 'https://rpc.mevblocker.io/fast'
})

getAddress()

Returns the account's Ethereum address.

Returns: Promise<string> - Checksummed Ethereum address

Example:

const address = await account.getAddress()
console.log('Account address:', address) // 0x...

sign(message)

Signs a message using the account's private key.

Parameters:

  • message (string): The message to sign

Returns: Promise<string> - The message signature

Example:

const message = 'Hello, Ethereum!'
const signature = await account.sign(message)
console.log('Signature:', signature)

signTypedData(typedData)

Signs typed data according to EIP-712.

Parameters:

  • typedData (TypedData): The typed data to sign
    • domain (TypedDataDomain): The domain separator (name, version, chainId, verifyingContract)
    • types (Record<string, TypedDataField[]>): The type definitions
    • message (Record<string, unknown>): The message data

Returns: Promise<string> - The typed data signature

Example:

const typedData = {
  domain: {
    name: 'MyDApp',
    version: '1',
    chainId: 1,
    verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
  },
  types: {
    Mail: [
      { name: 'from', type: 'address' },
      { name: 'to', type: 'address' },
      { name: 'contents', type: 'string' }
    ]
  },
  message: {
    from: '0xAlice...',
    to: '0xBob...',
    contents: 'Hello Bob!'
  }
}
const signature = await account.signTypedData(typedData)
console.log('EIP-712 Signature:', signature)

signTransaction(tx)

Signs an EVM transaction and returns the signed raw transaction as a hex string. This method does not broadcast the transaction.

Parameters:

  • tx (EvmTransaction): The transaction object
    • to (string | null, optional): Recipient address; omit or pass null for contract creation
    • value (number | bigint): Amount in wei
    • data (string, optional): Transaction data in hex format
    • gasLimit (number | bigint, optional): Maximum gas units
    • gasPrice (number | bigint, optional): Legacy gas price in wei
    • maxFeePerGas (number | bigint, optional): EIP-1559 max fee per gas in wei
    • maxPriorityFeePerGas (number | bigint, optional): EIP-1559 max priority fee per gas in wei
    • type (number, optional): Transaction type, such as 4 for ERC-7702
    • nonce (number, optional): Transaction nonce
    • chainId (number | bigint, optional): Network chain ID
    • authorizationList (AuthorizationLike[], optional): ERC-7702 authorization list for type 4 transactions

Returns: Promise<string> - Signed raw transaction hex string

Throws: ValueError for type 3 or non-null blob fields; MaximumFeeExceededError if a provider is configured and the estimated transaction fee exceeds transactionMaxFee.

Example:

const signedTransaction = await account.signTransaction({
  to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  value: 1000000000000000000n,
  chainId: 1
})

console.log('Signed transaction:', signedTransaction)

verify(message, signature)

Verifies a message signature against the account's address.

Parameters:

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

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

Example:

const message = 'Hello, Ethereum!'
const signature = await account.sign(message)
const isValid = await account.verify(message, signature)
console.log('Signature valid:', isValid) // true

verifyTypedData(typedData, signature)

Verifies a typed data signature according to EIP-712.

Parameters:

  • typedData (TypedData): The typed data that was signed
  • signature (string): The signature to verify

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

Example:

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

sendTransaction(tx)

Builds, signs, and sends an EVM transaction object, or broadcasts a signed raw transaction, then returns its hash and quoted fee.

Parameters:

  • tx (EvmTransaction | string): A transaction object or signed raw transaction hex.
    • to (string | null, optional): Recipient address; omit or pass null for contract creation
    • value (number | bigint): Amount in wei
    • data (string, optional): Transaction data in hex format
    • gasLimit (number | bigint, optional): Maximum gas units
    • gasPrice (number | bigint, optional): Legacy gas price in wei
    • maxFeePerGas (number | bigint, optional): EIP-1559 max fee per gas in wei
    • maxPriorityFeePerGas (number | bigint, optional): EIP-1559 max priority fee per gas in wei
    • type (number, optional): Transaction type, such as 4 for ERC-7702
    • nonce (number, optional): Transaction nonce
    • chainId (number | bigint, optional): Network chain ID
    • authorizationList (AuthorizationLike[], optional): ERC-7702 authorization list for type 4 transactions

For a signed raw transaction string, the wallet checks transactionMaxFee against the encoded gas limit multiplied by the encoded maxFeePerGas (or gasPrice), then passes the exact supplied hex to eth_sendRawTransaction. It still simulates the transaction but does not repopulate or re-sign it. This checks execution gas, not transferred value. Blob transactions are rejected. Review the decoded recipient, value, data, chain ID, nonce, gas limit, and all fee fields before submitting externally supplied bytes.

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

Throws:

  • ProviderRequiredError if no provider is configured.
  • MaximumFeeExceededError if the quoted fee exceeds transactionMaxFee when configured.
  • ValueError if an object transaction mixes incompatible fee fields, an explicit or inferred type 4 transaction supplies gasPrice, or it has type 3 or any non-null blob field.

Example:

// EIP-1559 transaction
const result = await account.sendTransaction({
  to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  value: 1000000000000000000, // 1 ETH in wei
  maxFeePerGas: 30000000000,
  maxPriorityFeePerGas: 2000000000
})

// Legacy transaction
const legacyResult = await account.sendTransaction({
  to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  value: 1000000000000000000,
  gasPrice: 20000000000,
  gasLimit: 21000
})

console.log('Transaction hash:', result.hash)
console.log('Transaction fee:', result.fee, 'wei')

quoteSendTransaction(tx)

Estimates the fee for an EVM transaction without sending it.

Parameters:

  • tx (EvmTransaction | string): A transaction object or serialized transaction string

In the documented release, an object quote uses gasLimit when supplied, otherwise the estimated gas. It multiplies that by maxFeePerGas when supplied, otherwise gasPrice, otherwise the provider's current fee rate. For serialized bytes, it uses the encoded gas limit and encoded maxFeePerGas or gasPrice.

Both forms still simulate the transaction, so a revert can reject the quote even with an explicit gas limit. The result covers execution gas only: it excludes transferred value. Blob transactions are rejected. It is not the eventual fee paid. A quote does not lock unspecified fields; object transaction population or a later quote can use fresh estimates. See fee-cap limits.

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

Throws: ProviderRequiredError if no provider is configured; ValueError for incompatible fee fields or a type-3/blob request

Example:

const quote = await account.quoteSendTransaction({
  to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  value: 1000000000000000000
})
console.log('Estimated fee:', quote.fee, 'wei')

transfer(options)

Transfers ERC20 tokens to another address using the standard transfer function.

Parameters:

  • options (EvmTransferOptions): Transfer options
    • token (string): Token contract address
    • recipient (string): Recipient address
    • amount (number | bigint): Amount in token base units
    • gasLimit, gasPrice, maxFeePerGas, maxPriorityFeePerGas (number | bigint, optional): Gas overrides, available in beta.20
    • authorizationList (AuthorizationLike[], optional): ERC-7702 authorizations; do not combine with legacy gasPrice

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

Throws:

  • ProviderRequiredError if no provider is configured.
  • MaximumFeeExceededError if the fee exceeds transferMaxFee or transactionMaxFee when configured.
  • ValueError if gas overrides mix incompatible legacy, EIP-1559, or authorization fee fields.

Example:

const result = await account.transfer({
  token: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDt
  recipient: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  amount: 1000000 // 1 USDt (6 decimals)
})
console.log('Transfer hash:', result.hash)
console.log('Transfer fee:', result.fee, 'wei')

quoteTransfer(options)

Estimates the fee for an ERC20 token transfer.

Parameters:

  • options (EvmTransferOptions): Transfer options, including the same gas overrides and authorization list as transfer()

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

Throws: ProviderRequiredError if no provider is configured, or ValueError if gas overrides mix incompatible fee fields

Example:

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

getBalance()

Returns the native token balance (ETH, MATIC, BNB, etc.).

Returns: Promise<bigint> - Balance in wei

Throws: ProviderRequiredError if no provider is configured

Example:

const balance = await account.getBalance()
console.log('Balance:', balance, 'wei')
console.log('Balance in ETH:', balance / 1000000000000000000)

getTokenBalance(tokenAddress)

Returns the balance of a specific ERC20 token using the balanceOf function.

Parameters:

  • tokenAddress (string): The ERC20 token contract address

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

Throws: ProviderRequiredError if no provider is configured

Example:

// Get USDt balance
const usdtBalance = await account.getTokenBalance('0xdAC17F958D2ee523a2206206994597C13D831ec7')
console.log('USDt balance:', usdtBalance) // In 6 decimal places
console.log('USDt balance formatted:', usdtBalance / 1000000, 'USDt')

getTokenBalances(tokenAddresses)

Returns balances for multiple ERC20 tokens in one call.

Parameters:

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

Returns: Promise<Record<string, bigint>> - Object mapping each token address to its balance in base units

Throws: ProviderRequiredError if no provider is configured

Example:

const balances = await account.getTokenBalances([
  '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDt
  '0x68749665FF8D2d112Fa859AA293F07A622782F38'  // XAUt
])

console.log('USDt:', balances['0xdAC17F958D2ee523a2206206994597C13D831ec7'])
console.log('XAUt:', balances['0x68749665FF8D2d112Fa859AA293F07A622782F38'])

approve(options)

Approves a specific amount of tokens to a spender.

Parameters:

  • options (EvmApproveOptions): Approve options
    • token (string): Token contract address
    • spender (string): Spender address
    • amount (number | bigint): Amount to approve
    • gasLimit, gasPrice, maxFeePerGas, maxPriorityFeePerGas (number | bigint, optional): Gas overrides, available in beta.20

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

Throws:

  • ProviderRequiredError if no provider is configured.
  • ValueError if an Ethereum mainnet USD₮ allowance is already nonzero and the requested amount is also nonzero. Approve 0 first.

Example:

const result = await account.approve({
  token: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDt
  spender: '0xSpenderAddress...',
  amount: 1000000n
})
console.log('Approve 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

Throws: ProviderRequiredError if no provider is configured

Example:

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

getTransactionReceipt(hash)

Returns a native transaction receipt by hash. This method is deprecated; use getTransaction() and read its receipt property when native ethers fields are needed.

Parameters:

  • hash (string): The transaction hash

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

Throws: ProviderRequiredError if no provider is configured

Example:

const receipt = await account.getTransactionReceipt('0x...')
if (receipt) {
  console.log('Confirmed in block:', receipt.blockNumber)
  console.log('Status:', receipt.status) // 1 = success, 0 = failed
}

getTransaction(hash)

Returns normalized transaction finality for an exact 32-byte hexadecimal hash.

Throws:

  • ProviderRequiredError if no provider is configured.
  • ValueError if hash is not an exact 32-byte hexadecimal transaction hash.
  • NoSuchElementError if neither a transaction nor receipt is found for hash.
const receipt = await account.getTransaction(transactionHash)

console.log(receipt.finality)      // pending, confirmed, final, or dropped
console.log(receipt.success)       // true or false after execution
console.log(receipt.confirmations)
console.log(receipt.receipt)       // Native ethers receipt, or null

An unmined transaction is pending. It becomes dropped when the sender's latest mined nonce has advanced beyond that transaction's nonce, which indicates that nonce was replaced or otherwise consumed. A mined transaction is confirmed; it becomes final when its block is at or below the RPC's finalized block. Nodes that do not support the finalized tag leave mined transactions at confirmed.

success: false represents a mined transaction whose receipt status is 0. Reaching confirmed or final does not prove successful execution. Invalid hashes throw ValueError; unknown hashes throw NoSuchElementError.

waitForTransaction(hash, options?)

Polls getTransaction() until the target is reached or the transaction is classified as dropped. The default target is confirmed, the default interval is four seconds, and the EVM timeout is 120 seconds.

Throws: TimeoutError if the requested target is not reached before the timeout.

const receipt = await account.waitForTransaction(transactionHash, {
  target: 'final',
  timeout: 180000,
  interval: 4000,
  maxPollErrors: 3
})

if (receipt.finality === 'dropped') {
  console.log('The nonce was consumed by another transaction')
} else if (!receipt.success) {
  console.log('The transaction was included but reverted')
}

toReadOnlyAccount()

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

Returns: Promise<WalletAccountReadOnlyEvm> - 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 throw error

signAuthorization(auth)

Signs an ERC-7702 authorization tuple. Missing chainId or nonce is populated through the provider. A provider-reported chain ID of zero throws AssertionError; an explicit chainId: 0 opts into an authorization valid across chains.

Parameters:

  • auth (AuthorizationRequest): ERC-7702 authorization request

Returns: Promise<Authorization> - The signed authorization

Throws: ProviderRequiredError when a missing chain ID or nonce requires a provider; AssertionError when the provider supplies chain ID zero.

Example:

const authorization = await account.signAuthorization({
  chainId: 1,
  address: delegateContract,
  nonce: 0
})

delegate(delegateAddress)

Delegates the EOA to a smart contract through an ERC-7702 type 4 transaction.

Parameters:

  • delegateAddress (string): Contract address to delegate to

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

Throws: ProviderRequiredError if no provider is configured; AssertionError if the provider supplies chain ID zero during authorization.

revokeDelegation()

Revokes active ERC-7702 delegation by delegating to the zero address.

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

Throws: ProviderRequiredError if no provider is configured; AssertionError if the provider supplies chain ID zero during authorization.

dispose()

Initiates cleanup of the account-owned signer. A supplied signer is preserved unless the account was configured with shouldWipeSignerOnDisposal: true. See signer ownership.

Example:

// Clean up when done
account.dispose()

Properties

PropertyTypeDescription
pathstring | nullFull path for a seed signer; null for a private-key signer
keyPairKeyPair | nullThe account's key pair (⚠️ Contains sensitive data). The returned arrays are bound to the account — treat them as a read-only view and do not modify their contents. privateKey becomes null when its signer is disposed; disposing an account that preserves a supplied signer does not erase that signer.
addressstring | undefinedDeprecated synchronous address; use getAddress()

Example:

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

// ⚠️ SENSITIVE: Handle with care
const keys = account.keyPair
if (keys !== null) {
  console.log('Public key length:', keys.publicKey.length) // 65 bytes
}

⚠️ Security Note: The keyPair property contains sensitive cryptographic material. Never log, display, or expose the private key. The byte arrays are bound to the wallet account — do not modify their contents.

WalletAccountReadOnlyEvm

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

Constructor

new WalletAccountReadOnlyEvm(address, config?)

Parameters:

  • address (string): The account's Ethereum address
  • config (Omit<EvmWalletConfig, 'transferMaxFee' | 'transactionMaxFee'>, optional): Configuration object (same as EvmWalletConfig but without send-only fee caps, since read-only accounts cannot send transactions)
    • provider (string | Provider | Eip1193Provider | Array<string | Provider | Eip1193Provider>, optional): RPC endpoint URL, ethers provider, EIP-1193 provider, or ordered failover list
    • retries (number, optional): Additional retry attempts when provider is an array
    • chainId (number, optional): Network chain ID. When provided, skips automatic chain ID detection.

Example:

const readOnlyAccount = new WalletAccountReadOnlyEvm('0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6', {
  provider: 'https://rpc.mevblocker.io/fast'
})

Properties

PropertyTypeDescription
addressstring | undefinedDeprecated synchronous address; use getAddress()

Methods

MethodDescriptionReturnsThrows
getAddress()Returns the account's addressPromise<string>-
getBalance()Returns the native token balance (in wei)Promise<bigint>ProviderRequiredError
getTokenBalance(tokenAddress)Returns the balance of a specific ERC20 tokenPromise<bigint>ProviderRequiredError
getTokenBalances(tokenAddresses)Returns balances for multiple ERC20 tokensPromise<Record<string, bigint>>ProviderRequiredError
quoteSendTransaction(tx)Estimates the fee for an EVM transactionPromise<{fee: bigint}>ProviderRequiredError or ValueError
quoteTransfer(options)Estimates the fee for an ERC20 transferPromise<{fee: bigint}>ProviderRequiredError or ValueError
verify(message, signature)Verifies a message signaturePromise<boolean>-
verifyTypedData(typedData, signature)Verifies a typed data signature (EIP-712)Promise<boolean>-
getDelegation()Checks active ERC-7702 delegation statusPromise<DelegationInfo>ProviderRequiredError
getTransactionReceipt(hash)Returns a native receipt; deprecated in favor of getTransaction()Promise<EvmTransactionReceipt | null>ProviderRequiredError
getTransaction(hash)Returns normalized finality and the native receiptPromise<TransactionReceipt & EvmTransactionDetails>ProviderRequiredError, ValueError, or NoSuchElementError
waitForTransaction(hash, options?)Waits for confirmed or final, or returns droppedPromise<TransactionReceipt & EvmTransactionDetails>TimeoutError
getAllowance(token, spender)Returns current allowance for a spenderPromise<bigint>ProviderRequiredError

getAddress()

Returns the account's Ethereum address.

Returns: Promise<string> - Checksummed Ethereum address

Example:

const address = await readOnlyAccount.getAddress()
console.log('Account address:', address) // 0x...

getBalance()

Returns the account's native token balance.

Returns: Promise<bigint> - Balance in wei

Throws: ProviderRequiredError if no provider is configured

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

Throws: ProviderRequiredError if no provider is configured

Example:

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

getTokenBalances(tokenAddresses)

Returns balances for multiple ERC20 tokens.

Parameters:

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

Returns: Promise<Record<string, bigint>> - Object mapping each token address to its balance in base units

Throws: ProviderRequiredError if no provider is configured

Example:

const balances = await readOnlyAccount.getTokenBalances([
  '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDt
  '0x68749665FF8D2d112Fa859AA293F07A622782F38'  // XAUt
])
console.log('Balances:', balances)

quoteSendTransaction(tx)

Estimates the fee for an EVM transaction.

The read-only method uses the same object quote calculation: supplied gas and fee fields take precedence over provider estimates, while simulation still runs. Its result covers execution gas only and is not the eventual fee paid. This read-only method does not accept serialized transaction bytes.

Parameters:

  • tx (EvmTransaction): The transaction object

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

Throws: ProviderRequiredError if no provider is configured; ValueError for incompatible fee fields or a type-3/blob request

Example:

const quote = await readOnlyAccount.quoteSendTransaction({
  to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  value: 1000000000000000000
})
console.log('Estimated fee:', quote.fee, 'wei')

quoteTransfer(options)

Estimates the fee for an ERC20 token transfer.

Parameters:

  • options (EvmTransferOptions): Transfer options, including gas overrides and an optional authorization list

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

Throws: ProviderRequiredError if no provider is configured, or ValueError if gas overrides mix incompatible fee fields

Example:

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

verify(message, signature)

Verifies a message signature against the account's address.

Parameters:

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

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

Example:

const message = 'Hello, Ethereum!'
const signature = await account.sign(message)

const readOnlyAccount = new WalletAccountReadOnlyEvm('0x...', { provider: '...' })
const isValid = await readOnlyAccount.verify(message, signature)
console.log('Signature valid:', isValid) // true

verifyTypedData(typedData, signature)

Verifies a typed data signature according to EIP-712.

Parameters:

  • typedData (TypedData): The typed data that was signed
  • signature (string): The signature to verify

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

Example:

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

getDelegation()

Checks whether the account currently has an active ERC-7702 delegation.

Returns: Promise<DelegationInfo> - Delegation status and delegate address

Throws: ProviderRequiredError if no provider is configured.

Example:

const delegation = await readOnlyAccount.getDelegation()
console.log('Delegated:', delegation.isDelegated)
console.log('Delegate:', delegation.delegateAddress)

getTransactionReceipt(hash)

Returns a native receipt if the transaction has been mined. This method is deprecated; use getTransaction() for normalized finality.

Parameters:

  • hash (string): The transaction hash

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

Throws: ProviderRequiredError if no provider is configured

Example:

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

getTransaction(hash) and waitForTransaction(hash, options?)

Read-only accounts expose the same normalized transaction methods as owned accounts. getTransaction() returns TransactionReceipt & EvmTransactionDetails; it throws ProviderRequiredError without a provider, ValueError for an invalid hash, and NoSuchElementError for an unknown hash. waitForTransaction() uses a four-second interval and 120-second timeout by default and throws TimeoutError if the target is not reached. A dropped receipt means the sender's mined nonce advanced past the pending transaction's nonce. Always inspect success after inclusion because a confirmed or final transaction can have reverted.

getAllowance(token, spender)

Returns the current allowance for the given token and spender.

Parameters:

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

Returns: Promise<bigint> - The allowance

Throws: ProviderRequiredError if no provider is configured.

Example:

const allowance = await readOnlyAccount.getAllowance(
  '0xdAC17F958D2ee523a2206206994597C13D831ec7',
  '0xSpenderAddress...'
)
console.log('Allowance:', allowance)

Types

Normalized Transaction Types

type Finality = 'pending' | 'confirmed' | 'final' | 'dropped'
type WaitForTransactionTarget = 'confirmed' | 'final'

interface TransactionReceipt {
  hash: string
  finality: Finality
  success?: boolean
  block?: number
  fee?: bigint
}

interface WaitForTransactionOptions {
  target?: WaitForTransactionTarget // Default: 'confirmed'
  timeout?: number                  // Milliseconds; EVM default: 120,000
  interval?: number                 // Milliseconds; default: 4,000
  maxPollErrors?: number            // Default: 3
}

interface EvmTransactionDetails {
  confirmations: number
  receipt: EvmTransactionReceipt | null
}

The package re-exports these types.

EvmTransaction

interface EvmTransaction {
  to?: string | null;                       // Recipient address; omit or pass null for contract creation
  value: number | bigint;                    // The amount of ethers to send (in wei)
  data?: string;                             // The transaction's data in hex format (optional)
  gasLimit?: number | bigint;                // Maximum amount of gas this transaction can use (optional)
  gasPrice?: number | bigint;                // Legacy gas price in wei (optional)
  maxFeePerGas?: number | bigint;            // EIP-1559 max fee per gas in wei (optional)
  maxPriorityFeePerGas?: number | bigint;    // EIP-1559 priority fee in wei (optional)
  type?: number;                             // Transaction type, such as 4 for ERC-7702 (optional)
  nonce?: number;                            // Transaction nonce (optional)
  chainId?: number | bigint;                 // Network chain ID (optional)
  authorizationList?: AuthorizationLike[];   // ERC-7702 authorization list for type 4 transactions (optional)
}

Type 3 and any non-null blobs, blobVersionedHashes, or maxFeePerBlobGas field are rejected with ValueError, including in serialized transactions. These blob fields are absent from the current EvmTransaction declaration. Type 4 transactions, whether selected explicitly or inferred from authorizationList, use EIP-1559 fees and reject gasPrice. Missing EIP-1559 fee fields are populated from the provider.

EvmTransactionRequest

EvmTransactionRequest is a type-only alias for ethers TransactionRequest, exported in beta.20. WDK transaction methods still accept the narrower EvmTransaction documented above.

EvmGasOverrides

type EvmGasOverrides = Pick<
  EvmTransaction,
  'gasLimit' | 'gasPrice' | 'maxFeePerGas' | 'maxPriorityFeePerGas'
>

Beta.20 accepts these optional fields directly on transfer and approval options. Use either legacy gasPrice or EIP-1559 maxFeePerGas / maxPriorityFeePerGas, not both. Fee rates are in wei per gas; gasLimit is a gas-unit count. Quotes use supplied gas limits and fee rates but still simulate the transaction.

EvmTransferOptions

type EvmTransferOptions = TransferOptions & EvmGasOverrides &
  Pick<EvmTransaction, 'authorizationList'>

TransferOptions

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

TransactionResult

interface TransactionResult {
  hash: string;                      // Transaction hash
  fee: bigint;                       // Quoted execution-gas fee in wei
}

TransferResult

interface TransferResult {
  hash: string;                      // Transfer transaction hash
  fee: bigint;                       // Quoted execution-gas fee in wei
}

FeeRates

interface FeeRates {
  normal: bigint;                    // Normal priority fee rate (base fee × 1.1)
  fast: bigint;                      // Fast priority fee rate (base fee × 2.0)
}

KeyPair

interface KeyPair {
  privateKey: Uint8Array | null;     // Private key as Uint8Array (32 bytes, null after dispose)
  publicKey: Uint8Array;             // Public key as Uint8Array (65 bytes)
}

EVM Signers

Import the EVM signer interface and its transaction type from the signers subpath:

import type { ISignerEvm, TransactionLike } from '@tetherto/wdk-wallet-evm/signers'

ISignerEvm extends the base ISigner with signTransaction(tx: TransactionLike), signTypedData(), and signAuthorization(). ISigner is a root runtime export; ISignerEvm is a runtime export of @tetherto/wdk-wallet-evm/signers, alongside SeedSignerEvm and PrivateKeySignerEvm. The signers subpath supports Bare.

SeedSignerEvm(seed, absolutePath?) defaults to m/44'/60', supports self-relative derivation, and keeps independent keys for derived signers. PrivateKeySignerEvm copies a raw key and cannot derive; derive() throws UnsupportedOperationError. Neither exposes an index property. See signer migration for the changed constructors and cleanup rules.

TransactionLike

TransactionLike is a type-only export from @tetherto/wdk-wallet-evm/signers, backed by ethers. It replaces UnsignedEvmTransaction in signer method signatures. Object sends use ethers transaction population before signing. The account APIs retain the narrower EvmTransaction contract and reject blob transactions.

TypedData

interface TypedData {
  domain: TypedDataDomain;                           // The domain separator
  types: Record<string, TypedDataField[]>;           // The type definitions
  message: Record<string, unknown>;                  // The message data
}

TypedDataDomain

interface TypedDataDomain {
  name?: string;                     // The domain name (e.g., the DApp name)
  version?: string;                  // The domain version
  chainId?: number | bigint;         // The chain ID
  verifyingContract?: string;        // The verifying contract address
  salt?: string;                     // An optional salt
}

TypedDataField

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

EvmWalletConfig

interface EvmWalletConfig {
  provider?: string | Provider | Eip1193Provider | Array<string | Provider | Eip1193Provider>; // RPC URL, ethers/EIP-1193 provider, or ordered failover list
  retries?: number;                                                  // Additional retry attempts for provider arrays
  chainId?: number;                                                  // Network chain ID. Skips automatic detection when provided.
  transferMaxFee?: number | bigint;                                  // Maximum ERC-20 transfer fee in wei
  transactionMaxFee?: number | bigint;                               // Maximum native send/sign fee in wei
}

The published configuration type and runtime both accept an ethers Provider directly or inside the provider array.

DelegationInfo

interface DelegationInfo {
  isDelegated: boolean;              // Whether the account has an active ERC-7702 delegation
  delegateAddress: string | null;    // Delegate contract address, or null when not delegated
}

EvmApproveOptions

type EvmApproveOptions = ApproveOptions & EvmGasOverrides

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
}

EvmTransactionReceipt

interface EvmTransactionReceipt {
  to: string;                        // Recipient address
  from: string;                      // Sender address
  contractAddress: string | null;    // Contract address if contract creation
  transactionIndex: number;          // Transaction index in block
  gasUsed: bigint;                   // Gas actually used
  logsBloom: string;                 // Bloom filter for logs
  blockHash: string;                 // Block hash containing transaction
  transactionHash: string;           // Transaction hash
  logs: Array<Log>;                  // Event logs
  blockNumber: number;               // Block number
  confirmations: number;             // Number of confirmations
  cumulativeGasUsed: bigint;         // Cumulative gas used in block
  effectiveGasPrice: bigint;         // Effective gas price paid
  status: number;                    // Transaction status (1 = success, 0 = failed)
  type: number;                      // Transaction type (0 = legacy, 2 = EIP-1559)
}

Need Help?

On this page

Table of ContentsWalletManagerEvmConstructorMethodsPropertiesgetRandomSeedPhrase(wordCount?) (static)isValidSeedPhrase(seedPhrase) (static)addSigner(signerName, signer)getSigner(signerName?)getSigners()getAccount(index?)getAccount(signerName)getAccountByPath(path)getFeeRates()dispose()WalletAccountEvmConstructorStatic MethodsMethodsfromPrivateKey(privateKey, config?) (static)getAddress()sign(message)signTypedData(typedData)signTransaction(tx)verify(message, signature)verifyTypedData(typedData, signature)sendTransaction(tx)quoteSendTransaction(tx)transfer(options)quoteTransfer(options)getBalance()getTokenBalance(tokenAddress)getTokenBalances(tokenAddresses)approve(options)getAllowance(token, spender)getTransactionReceipt(hash)getTransaction(hash)waitForTransaction(hash, options?)toReadOnlyAccount()signAuthorization(auth)delegate(delegateAddress)revokeDelegation()dispose()PropertiesWalletAccountReadOnlyEvmConstructorPropertiesMethodsgetAddress()getBalance()getTokenBalance(tokenAddress)getTokenBalances(tokenAddresses)quoteSendTransaction(tx)quoteTransfer(options)verify(message, signature)verifyTypedData(typedData, signature)getDelegation()getTransactionReceipt(hash)getTransaction(hash) and waitForTransaction(hash, options?)getAllowance(token, spender)TypesNormalized Transaction TypesEvmTransactionEvmTransactionRequestEvmGasOverridesEvmTransferOptionsTransferOptionsTransactionResultTransferResultFeeRatesKeyPairEVM SignersTransactionLikeTypedDataTypedDataDomainTypedDataFieldEvmWalletConfigDelegationInfoEvmApproveOptionsApproveOptionsEvmTransactionReceiptNeed Help?