` - The fee rates in base units
**Example:**
```javascript title="Get Fee Rates"
const feeRates = await wdk.getFeeRates()
console.log('Fee rates:', feeRates)
```
##### `dispose(blockchains?)`
Disposes all registered wallets when called without arguments, or only the wallets for the named blockchains when you pass a string array.
**Parameters:**
* `blockchains` (string\[], optional): The blockchain identifiers to dispose. Omit this parameter to dispose every registered wallet.
**Example:**
```javascript title="Dispose WDK"
// Clean up all sensitive data
wdk.dispose()
// Dispose only one registered wallet
wdk.dispose(['ethereum'])
```
### Static Methods
| Method | Description | Returns |
| --------------------------------- | ---------------------------------------------------- | --------- |
| `getRandomSeedPhrase(wordCount?)` | Returns a random BIP-39 seed phrase (12 or 24 words) | `string` |
| `isValidSeedPhrase(seedPhrase)` | Checks if a seed phrase is valid | `boolean` |
##### `getRandomSeedPhrase(wordCount?)`
Returns a random BIP-39 seed phrase. Supports both 12-word (128-bit entropy) and 24-word (256-bit entropy) seed phrases.
**Parameters:**
* `wordCount` (12 | 24, optional): The number of words in the seed phrase. Defaults to 12.
**Returns:** `string` - The seed phrase
**Example:**
```javascript title="Generate Random Seed"
// Generate 12-word seed phrase (default)
const seedPhrase12 = WDK.getRandomSeedPhrase()
console.log('Generated 12-word seed:', seedPhrase12)
// Output: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
// Generate 24-word seed phrase (higher security)
const seedPhrase24 = WDK.getRandomSeedPhrase(24)
console.log('Generated 24-word seed:', seedPhrase24)
// Output: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art"
```
##### `isValidSeedPhrase(seedPhrase)`
Checks if a seed phrase is valid according to BIP-39 standards.
**Parameters:**
* `seedPhrase` (string): The seed phrase to validate
**Returns:** `boolean` - True if the seed phrase is valid
**Example:**
```javascript title="Validate Seed Phrase"
const isValid = WDK.isValidSeedPhrase('abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about')
console.log('Seed phrase valid:', isValid) // true
const isInvalid = WDK.isValidSeedPhrase('invalid seed phrase')
console.log('Seed phrase valid:', isInvalid) // false
```
## IWalletAccountWithProtocols
Extended wallet account interface that supports protocol registration and access. Extends `IWalletAccount` from `@tetherto/wdk-wallet`.
### Methods
| Method | Description | Returns | Throws |
| ------------------------------------------- | ------------------------------------------------- | ----------------------------- | --------------------- |
| `registerProtocol(label, protocol, config)` | Registers a protocol for this specific account | `IWalletAccountWithProtocols` | - |
| `getSwapProtocol(label)` | Returns the swap protocol with the given label | `ISwapProtocol` | If protocol not found |
| `getBridgeProtocol(label)` | Returns the bridge protocol with the given label | `IBridgeProtocol` | If protocol not found |
| `getLendingProtocol(label)` | Returns the lending protocol with the given label | `ILendingProtocol` | If protocol not found |
##### `registerProtocol(label, protocol, config)`
Registers a new protocol for this specific account.
**Type Parameters:**
* `P`: `typeof SwapProtocol | typeof BridgeProtocol | typeof LendingProtocol` - A class that extends one of the `@tetherto/wdk-wallet/protocol`'s classes
**Parameters:**
* `label` (string): Unique label for the protocol (must be unique per account and protocol type)
* `protocol` (P): The protocol class
* `config` (`ConstructorParameters[1]`): The protocol configuration
**Returns:** `IWalletAccountWithProtocols` - The account instance (supports method chaining)
**Example:**
```javascript title="Register Protocol for Account"
import Usdt0ProtocolEvm from '@tetherto/wdk-protocol-bridge-usdt0-evm'
const account = await wdk.getAccount('ethereum', 0)
// Register protocol for this specific account
account.registerProtocol('usdt0', Usdt0ProtocolEvm, {
apiKey: 'YOUR_API_KEY'
})
// Method chaining
const account2 = await wdk.getAccount('ethereum', 1)
.registerProtocol('usdt0', Usdt0ProtocolEvm, usdt0ProtocolConfig)
```
##### `getSwapProtocol(label)`
Returns the swap protocol with the given label.
**Parameters:**
* `label` (string): The protocol label
**Returns:** `ISwapProtocol` - The swap protocol instance
**Throws:** Error if no swap protocol with the given label has been registered
**Example:**
```javascript title="Get Swap Protocol"
import veloraProtocolEvm from '@tetherto/wdk-protocol-swap-velora-evm'
// Register swap protocol
account.registerProtocol('velora', veloraProtocolEvm, veloraProtocolConfig)
// Get swap protocol
const velora = account.getSwapProtocol('velora')
// Use the protocol
const swapResult = await velora.swap({
tokenIn: '0x...',
tokenOut: '0x...',
tokenInAmount: 1000000n
})
// This will throw an error
// try {
// const uniswap = account.getSwapProtocol('uniswap')
// } catch (error) {
// console.error('No swap protocol with label "uniswap" found')
// }
```
##### `getBridgeProtocol(label)`
Returns the bridge protocol with the given label.
**Parameters:**
* `label` (string): The protocol label
**Returns:** `IBridgeProtocol` - The bridge protocol instance
**Throws:** Error if no bridge protocol with the given label has been registered
**Example:**
```javascript title="Get Bridge Protocol"
import Usdt0ProtocolEvm from '@tetherto/wdk-protocol-bridge-usdt0-evm'
// Register bridge protocol
account.registerProtocol('usdt0', Usdt0ProtocolEvm)
// Get bridge protocol
const usdt0 = account.getBridgeProtocol('usdt0')
// Use the protocol
const bridgeResult = await usdt0.bridge({
targetChain: 'arbitrum',
recipient: '0x...',
token: '0x...',
amount: 1000000n
})
```
##### `getLendingProtocol(label)`
Returns the lending protocol with the given label.
**Parameters:**
* `label` (string): The protocol label
**Returns:** `ILendingProtocol` - The lending protocol instance
**Throws:** Error if no lending protocol with the given label has been registered
**Example:**
```javascript title="Get Lending Protocol"
import AaveProtocolEvm from '@tetherto/wdk-protocol-lending-aave-evm'
// Register lending protocol
account.registerProtocol('aave', AaveProtocolEvm, aaveProtocolConfig)
// Get lending protocol
const aave = account.getLendingProtocol('aave')
// Use the protocol
const supplyResult = await aave.supply({
token: '0x...',
amount: 1000000n
})
```
## Complete Example
```javascript title="Complete WDK Flow"
import WDK from '@tetherto/wdk'
import WalletManagerEvm from '@tetherto/wdk-wallet-evm'
import WalletManagerTon from '@tetherto/wdk-wallet-ton'
import veloraProtocolEvm from '@tetherto/wdk-protocol-swap-velora-evm'
import Usdt0ProtocolEvm from '@tetherto/wdk-protocol-bridge-usdt0-evm'
// Initialize WDK Manager
const wdk = new WDK(seedPhrase)
.registerWallet('ethereum', WalletManagerEvm, {
provider: 'https://eth.drpc.org'
})
.registerWallet('ton', WalletManagerTon, {
tonApiKey: 'YOUR_TON_API_KEY',
tonApiEndpoint: 'https://tonapi.io'
})
.registerProtocol('ethereum', 'velora', veloraProtocolEvm, {
apiKey: 'YOUR_velora_API_KEY'
})
.registerProtocol('ethereum', 'usdt0', Usdt0ProtocolEvm)
// Get accounts
const accountEth = await wdk.getAccount('ethereum', 3)
const accountTon = await wdk.getAccountByPath('ton', "1'/2/3")
// Use wallet account methods
const { hash, fee } = await accountEth.sendTransaction({
to: '0x...',
value: 1000000000000000000n // 1 ETH
})
// Use protocols
const velora = accountEth.getSwapProtocol('velora')
const swapResult = await velora.swap(swapOptions)
const usdt0 = accountEth.getBridgeProtocol('usdt0')
const bridgeResult = await usdt0.bridge(bridgeOptions)
// Clean up
wdk.dispose()
```
## Types
### FeeRates
```typescript title="Type: FeeRates"
interface FeeRates {
[blockchain: string]: {
normal: number;
fast: number;
};
}
```
### Middleware Function
```typescript title="Type: MiddlewareFunction"
type MiddlewareFunction = (
account: A
) => Promise;
```
### Protocol Types
```typescript title="Types: Protocol Interfaces"
// Swap Protocol
interface ISwapProtocol {
swap(options: SwapOptions): Promise;
}
// Bridge Protocol
interface IBridgeProtocol {
bridge(options: BridgeOptions): Promise;
}
// Lending Protocol
interface ILendingProtocol {
supply(options: LendingOptions): Promise;
withdraw(options: LendingOptions): Promise;
borrow(options: LendingOptions): Promise;
repay(options: LendingOptions): Promise;
}
```
***
## Next Steps
Get started with WDK's configuration
Get started with WDK's Usage
Explore blockchain-specific wallet modules
Cross-chain USD₮0 bridges
***
### Need Help?
# WDK Core Configuration (/sdk/core-module/configuration)
# Configuration
## WDK Manager Configuration
```javascript title="Create WDK Instance"
import WDK from '@tetherto/wdk'
const wdk = new WDK(seedPhrase)
```
The WDK Manager itself only requires a seed phrase for initialization. Configuration is done through the registration of wallets and protocols.
## Wallet Registration Configuration
```javascript title="Register WDK Wallet"
import WDK from '@tetherto/wdk'
import WalletManagerEvm from '@tetherto/wdk-wallet-evm'
import WalletManagerTon from '@tetherto/wdk-wallet-ton'
const wdk = new WDK(seedPhrase)
.registerWallet('ethereum', WalletManagerEvm, {
provider: 'https://eth.drpc.org'
})
.registerWallet('ton', WalletManagerTon, {
tonApiKey: 'YOUR_TON_API_KEY',
tonApiEndpoint: 'https://tonapi.io'
})
```
## Protocol Registration Configuration
```javascript title="Register WDK Protocol"
import veloraProtocolEvm from '@tetherto/wdk-protocol-swap-velora-evm'
const wdk = new WDK(seedPhrase)
.registerProtocol('ethereum', 'velora', veloraProtocolEvm, {
apiKey: 'YOUR_velora_API_KEY'
})
```
## Configuration Options
### Wallet Configuration
Each wallet manager requires its own configuration object when registered. The configuration depends on the specific wallet module being used.
#### EVM Wallet Configuration
```javascript title="Ethereum WDK Wallet Configuration"
const ethereumWalletConfig = {
provider: 'https://eth.drpc.org', // RPC endpoint
// Additional EVM-specific configuration options
}
wdk.registerWallet('ethereum', WalletManagerEvm, ethereumWalletConfig)
```
#### TON Wallet Configuration
```javascript title="TON WDK Wallet Configuration"
const tonWalletConfig = {
tonClient: {
secretKey: 'YOUR_TON_API_KEY',
url: 'https://toncenter.com/api/v2/jsonRPC'
}
}
wdk.registerWallet('ton', WalletManagerTon, tonWalletConfig)
```
### Protocol Configuration
Protocols also require their own configuration objects when registered.
#### Swap Protocol Configuration
```javascript title="Swap WDK Protocol Configuration"
const veloraProtocolConfig = {
apiKey: 'YOUR_velora_API_KEY',
baseUrl: 'https://apiv5.velora.io'
}
wdk.registerProtocol('ethereum', 'velora', veloraProtocolEvm, veloraProtocolConfig)
```
### Middleware Configuration
Middleware functions can be registered to enhance account functionality.
```javascript title="Middleware WDK Protocol Configuration"
// Simple logging middleware
wdk.registerMiddleware('ethereum', async (account) => {
console.log('New account created:', await account.getAddress())
})
```
## Environment Variables
For production applications, consider using environment variables for sensitive configuration:
```javascript title="WDK environment variables Configuration"
const wdk = new WDK(process.env.SEED_PHRASE)
.registerWallet('ethereum', WalletManagerEvm, {
provider: process.env.ETHEREUM_RPC_URL
})
.registerProtocol('ethereum', 'velora', veloraProtocolEvm, {
apiKey: process.env.velora_API_KEY
})
```
## Configuration Validation
The WDK Manager will validate configurations when wallets and protocols are registered:
* **Wallet Registration**: Ensures the wallet class extends the required base class
* **Protocol Registration**: Validates that protocol labels are unique per blockchain and protocol type
* **Middleware Registration**: Validates that middleware functions have the correct signature
## Error Handling
Configuration errors will be thrown during registration:
```javascript title="Configuration errors"
try {
wdk.registerWallet('ethereum', InvalidWalletClass, config)
} catch (error) {
console.error('Wallet registration failed:', error.message)
}
try {
wdk.registerProtocol('ethereum', 'velora', veloraProtocolEvm, invalidConfig)
} catch (error) {
console.error('Protocol registration failed:', error.message)
}
```
***
## Next Steps
Get started with WDK's usage
Get started with WDK's API
Explore blockchain-specific wallet modules
Cross-chain USD₮0 bridges
***
### Need Help?
# WDK Core (/sdk/core-module)
This package serves as the main entry point and **orchestrator for all WDK wallet and protocol modules**, allowing you to register and manage different blockchain wallets through a single, unified interface.
## Next Steps
Get started with WDK in a Node.js environment
Get started with WDK's configuration
Get started with WDK's API
Get started with WDK's usage
***
## Need Help?
# Usage (/sdk/core-module/usage)
The WDK Core module is the central orchestrator for your wallet interactions.
Install and instantiate the WDK.
Connect specific blockchains (Ethereum, TON, etc.).
Retrieve accounts and check balances.
Transfer native tokens.
Use Swap, Bridge, and Lending protocols.
Add logging and failover protection.
Best practices for security and stability.
# Fiat Modules Overview (/sdk/fiat-modules)
The Wallet Development Kit (WDK) provides fiat modules that enable on-ramp and off-ramp functionality, allowing users to seamlessly convert between fiat currencies and cryptocurrencies within your application.
## Fiat Protocol Modules
On-ramp and off-ramp functionality for fiat currency integration:
| Module | Provider | Status | Documentation |
| ---------------------------------------------------------------------------------------------- | -------- | ------- | -------------------------------- |
| [`@tetherto/wdk-protocol-fiat-moonpay`](https://github.com/tetherto/wdk-protocol-fiat-moonpay) | MoonPay | ✅ Ready | [Documentation](./fiat-moonpay/) |
## Features
Fiat modules provide:
* **On-Ramp**: Allow users to purchase cryptocurrency using fiat currencies (credit card, bank transfer, etc.)
* **Off-Ramp**: Enable users to sell cryptocurrency and receive fiat currencies
* **Multiple Payment Methods**: Support for various payment options depending on the provider
* **KYC Integration**: Built-in Know Your Customer verification flows
* **Multi-Currency Support**: Support for multiple fiat and cryptocurrencies
## Next Steps
To get started with WDK fiat modules, follow these steps:
1. Get up and running quickly with our [Quickstart Guide](../../start-building/nodejs-bare-quickstart)
2. Choose the fiat module that best fits your needs from the table above
3. Check specific documentation for the module you wish to use
You can also:
* Learn about key concepts in our [Concepts](../../resources/concepts) page
* Explore [wallet modules](../wallet-modules/) to manage user wallets
* Check our [examples](../../examples-and-starters/react-native-starter) for production-ready implementations
# Lending Modules Overview (/sdk/lending-modules)
The Wallet Development Kit (WDK) provides a set of modules that support connection with lending protocols on different blockchain networks. All modules share a common interface, ensuring consistent behavior across different blockchain implementations.
## Lending & Borrowing Protocol Modules
DeFi lending functionality for different lending & borrowing protocols
| Module | Route | Status | Documentation |
| ------------------------------------------------------------------------------------------------------ | ----- | ------- | ------------------------------------ |
| [`@tetherto/wdk-protocol-lending-aave-evm`](https://github.com/tetherto/wdk-protocol-lending-aave-evm) | EVM | ✅ Ready | [Documentation](./lending-aave-evm/) |
## Next Steps
To get started with WDK modules, follow these steps:
Get started with WDK in a Node.js environment
Build mobile wallets with React Native Expo
Manage wallet and protocol modules
***
## Need Help?
# Swap Modules Overview (/sdk/swap-modules)
The Swap Development Kit (WDK) provides a set of modules that support swap on top of multiple blockchain networks. All modules share a common interface, ensuring consistent behavior across different blockchain implementations.
## Swap Protocol Modules
DeFi swap functionality for token exchanges across different DEXs:
| Module | Blockchain | Status | Documentation |
| ---------------------------------------------------------------------------------------------------- | ---------- | ----------- | ----------------------------------- |
| [`@tetherto/wdk-protocol-swap-velora-evm`](https://github.com/tetherto/wdk-protocol-swap-velora-evm) | EVM | ✅ Ready | [Documentation](./swap-velora-evm/) |
| `@tetherto/wdk-protocol-swap-stonfi-ton` | TON | In progress | Coming soon |
## Next steps
To get started with WDK modules, follow these steps:
1. Get up and running quickly with our [Quickstart Guide](../../start-building/nodejs-bare-quickstart)
2. Choose the modules that best fit your needs from the tables above
3. Check specific documentation for modules you wish to use
You can also:
* Learn about key concepts like [Account Abstraction](../../resources/concepts#account-abstraction) and other important definitions
* Use one of our ready-to-use examples to be production ready
# Wallet Modules Overview (/sdk/wallet-modules)
The Wallet Development Kit (WDK) provides a set of modules that support multiple blockchain networks. All modules share a common interface, ensuring consistent behavior across different blockchain implementations.
## Supported Networks
This package works with multiple blockchain networks through wallet registration.
Bitcoin Mainnet
Ethereum, Sepolia Testnet, L2s, etc.
Tron Mainnet
TON Mainnet
Solana Mainnet
Spark Mainnet
## Classic Wallet Modules
Standard wallet implementations that use native blockchain tokens for transaction fees:
| Module | Blockchain | Status | Documentation |
| ------------------------------------------------------------------------------ | ---------- | ----------- | -------------------------------- |
| [`@tetherto/wdk-wallet-evm`](https://github.com/tetherto/wdk-wallet-evm) | EVM | ✅ Ready | [Documentation](./wallet-evm) |
| [`@tetherto/wdk-wallet-ton`](https://github.com/tetherto/wdk-wallet-ton) | TON | ✅ Ready | [Documentation](./wallet-ton) |
| [`@tetherto/wdk-wallet-btc`](https://github.com/tetherto/wdk-wallet-btc) | Bitcoin | ✅ Ready | [Documentation](./wallet-btc) |
| [`@tetherto/wdk-wallet-spark`](https://github.com/tetherto/wdk-wallet-spark) | Spark | ✅ Ready | [Documentation](./wallet-spark) |
| [`@tetherto/wdk-wallet-tron`](https://github.com/tetherto/wdk-wallet-tron) | TRON | ✅ Ready | [Documentation](./wallet-tron) |
| [`@tetherto/wdk-wallet-solana`](https://github.com/tetherto/wdk-wallet-solana) | Solana | ✅ Ready | [Documentation](./wallet-solana) |
| `@tetherto/wdk-wallet-ark` | Ark | In progress | - |
## Account Abstraction Wallet Modules
Wallet implementations that support [Account Abstraction](../../resources/concepts#account-abstraction) for gasless transactions using paymaster tokens like USD₮:
| Module | Blockchain | Status | Documentation |
| ------------------------------------------------------------------------------------------ | ---------- | ----------- | -------------------------------------- |
| [`@tetherto/wdk-wallet-evm-erc4337`](https://github.com/tetherto/wdk-wallet-evm-erc-4337) | EVM | ✅ Ready | [Documentation](./wallet-evm-erc-4337) |
| [`@tetherto/wdk-wallet-ton-gasless`](https://github.com/tetherto/wdk-wallet-ton-gasless) | TON | ✅ Ready | [Documentation](./wallet-ton-gasless) |
| [`@tetherto/wdk-wallet-tron-gasfree`](https://github.com/tetherto/wdk-wallet-tron-gasfree) | TRON | ✅ Ready | [Documentation](./wallet-tron-gasfree) |
| `@tetherto/wdk-wallet-solana-jupiterz` | Solana | In progress | - |
## Community Wallet Modules
Wallet modules developed by the community. See the [Community Modules](../community-modules/) page for more details.
Community modules are developed and maintained independently. Use your own judgment and proceed at your own risk.
| Module | Blockchain | Description | Repository |
| ----------------------- | ------------- | ----------------------------------------------------------------- | ---------------------------------------------------------- |
| `@utexo/wdk-wallet-rgb` | Bitcoin (RGB) | RGB protocol wallet integration for Bitcoin-based smart contracts | [GitHub](https://github.com/UTEXO-Protocol/wdk-wallet-rgb) |
## Next Steps
To get started with WDK modules, follow these steps:
1. Get up and running quickly with our [Quickstart Guide](../../start-building/nodejs-bare-quickstart)
2. Choose the modules that best fit your needs from the tables above
3. Check specific documentation for modules you wish to use
You can also:
* Learn about key concepts like [Account Abstraction](../../resources/concepts#account-abstraction) and other important definitions
* Use one of our ready-to-use examples to be production ready
# Bridge USD₮0 EVM API Reference (/sdk/bridge-modules/bridge-usdt0-evm/api-reference)
## Table of Contents
| Class | Description | Methods |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------ |
| [Usdt0ProtocolEvm](#usdt0protocolevm) | Main class for bridging USD₮0 tokens across blockchains. Extends `BridgeProtocol` from `@tetherto/wdk-wallet/protocols`. | [Constructor](#constructor), [Methods](#methods) |
## Usdt0ProtocolEvm
The main class for bridging USD₮0 tokens across different blockchains using the LayerZero protocol.
Extends `BridgeProtocol` from `@tetherto/wdk-wallet/protocols`.
### Constructor
```javascript
new Usdt0ProtocolEvm(account, config?)
```
**Parameters:**
* `account` (WalletAccountEvm | WalletAccountEvmErc4337 | WalletAccountReadOnlyEvm | WalletAccountReadOnlyEvmErc4337): The wallet account to use for bridge operations
* `config` (BridgeProtocolConfig, optional): Configuration object
* `bridgeMaxFee` (bigint, optional): Maximum total bridge cost in wei
**Example:**
```javascript
import Usdt0ProtocolEvm from '@tetherto/wdk-protocol-bridge-usdt0-evm'
import { WalletAccountEvm } from '@tetherto/wdk-wallet-evm'
const account = new WalletAccountEvm(seedPhrase, {
provider: 'https://eth-mainnet.g.alchemy.com/v2/your-api-key'
})
const bridgeProtocol = new Usdt0ProtocolEvm(account, {
bridgeMaxFee: 1000000000000000n
})
```
### Methods
| Method | Description | Returns | Throws |
| ------------------------------- | ---------------------------------------- | ---------------------------------------------------------- | --------------------------------- |
| `bridge(options, config?)` | Bridges tokens to another blockchain | `Promise\` | If no provider or fee exceeds max |
| `quoteBridge(options, config?)` | Estimates the cost of a bridge operation | `Promise\\>` | If no provider |
#### `bridge(options, config?)`
Bridges tokens to a different blockchain using the USD₮0 protocol.
**Parameters:**
* `options` (BridgeOptions): Bridge operation options
* `targetChain` (string): Destination chain name
* `recipient` (string): Address that will receive the bridged tokens
* `token` (string): Token contract address on source chain
* `amount` (bigint): Amount to bridge in token base units
* `oftContractAddress` (string, optional): Override the default OFT contract address
* `dstEid` (number, optional): Override the default LayerZero destination endpoint ID
* `config` (`Pick & Pick`, optional): Override configuration for ERC-4337 accounts
* `paymasterToken` (string, optional): Token to use for paying gas fees
* `bridgeMaxFee` (bigint, optional): Override maximum bridge fee
**Returns:** `Promise\` - Bridge operation result
**Throws:**
* Error if account is read-only
* Error if no provider is configured
* Error if bridge fee exceeds maximum allowed
**Example:**
```javascript
// Standard EVM account
const result = await bridgeProtocol.bridge({
targetChain: 'arbitrum',
recipient: '0x...',
token: '0x...',
amount: 1000000000000000000n
})
console.log('Bridge hash:', result.hash)
console.log('Approve hash:', result.approveHash)
console.log('Reset allowance hash:', result.resetAllowanceHash)
console.log('Total fee:', result.fee)
console.log('Bridge fee:', result.bridgeFee)
// ERC-4337 account
const result2 = await bridgeProtocol.bridge({
targetChain: 'arbitrum',
recipient: '0x...',
token: '0x...',
amount: 1000000000000000000n
}, {
paymasterToken: '0x...',
bridgeMaxFee: 1000000000000000n
})
console.log('Bridge hash:', result2.hash)
console.log('Total fee:', result2.fee)
console.log('Bridge fee:', result2.bridgeFee)
// Non-EVM destination with overrides
const result3 = await bridgeProtocol.bridge({
targetChain: 'solana',
recipient: 'SolanaRecipientAddress...',
token: '0x...',
amount: 1000000000000000000n,
oftContractAddress: '0x...',
dstEid: 30168
})
```
#### `quoteBridge(options, config?)`
Estimates the cost of a bridge operation without executing it.
**Parameters:**
* `options` (BridgeOptions): Bridge operation options (same as bridge method)
* `config` (`Pick`, optional): Override configuration for ERC-4337 accounts
* `paymasterToken` (string, optional): Token to use for paying gas fees
**Returns:** `Promise\\>` - Bridge cost estimate
**Throws:** Error if no provider is configured
**Example:**
```javascript
const quote = await bridgeProtocol.quoteBridge({
targetChain: 'polygon',
recipient: '0x...',
token: '0x...',
amount: 1000000000000000000n
})
console.log('Estimated fee:', quote.fee, 'wei')
console.log('Bridge fee:', quote.bridgeFee, 'wei')
if (quote.fee + quote.bridgeFee > 1000000000000000n) {
console.log('Bridge fees too high')
} else {
const result = await bridgeProtocol.bridge({
targetChain: 'polygon',
recipient: '0x...',
token: '0x...',
amount: 1000000000000000000n
})
}
```
## Types
### BridgeOptions
```typescript
interface BridgeOptions {
targetChain: string;
recipient: string;
token: string;
amount: bigint;
oftContractAddress?: string; // Override OFT contract address
dstEid?: number; // Override LayerZero destination endpoint ID
}
```
### BridgeResult
```typescript
interface BridgeResult {
hash: string;
fee: bigint;
bridgeFee: bigint;
approveHash?: string;
resetAllowanceHash?: string;
}
```
### BridgeProtocolConfig
```typescript
interface BridgeProtocolConfig {
bridgeMaxFee?: bigint;
}
```
### EvmErc4337WalletConfig
```typescript
interface EvmErc4337WalletConfig {
paymasterToken?: string;
}
```
### Supported Chains
The bridge protocol supports the following chains:
**Source Chains (EVM):**
| Chain | Chain ID |
| -------------- | -------- |
| Ethereum | 1 |
| Arbitrum | 42161 |
| Optimism | 10 |
| Polygon | 137 |
| Berachain | 80094 |
| Ink | 57073 |
| Plasma | 9745 |
| Conflux eSpace | 1030 |
| Corn | 21000000 |
| Avalanche | 43114 |
| Celo | 42220 |
| Flare | 14 |
| HyperEVM | 999 |
| Mantle | 5000 |
| MegaETH | 4326 |
| Monad | 143 |
| Morph | 2818 |
| Rootstock | 30 |
| Sei | 1329 |
| Stable | 988 |
| Unichain | 130 |
| XLayer | 196 |
**Destination Chains:**
All source chains above, plus:
| Chain | Endpoint ID (EID) |
| ------ | ----------------- |
| Solana | 30168 |
| TON | 30343 |
| TRON | 30420 |
## Error Handling
The bridge protocol throws specific errors for different failure cases:
```javascript
try {
const result = await bridgeProtocol.bridge({
targetChain: 'arbitrum',
recipient: '0x...',
token: '0x...',
amount: 1000000000000000000n
})
} catch (error) {
if (error.message.includes('not supported')) {
console.error('Chain or token not supported')
}
if (error.message.includes('Exceeded maximum fee')) {
console.error('Bridge fee too high')
}
if (error.message.includes('must be connected to a provider')) {
console.error('Wallet not connected to blockchain')
}
if (error.message.includes('requires the protocol to be initialized with a non read-only account')) {
console.error('Cannot bridge with read-only account')
}
if (error.message.includes('cannot be equal to the source chain')) {
console.error('Cannot bridge to the same chain')
}
}
```
## Usage Examples
### Basic Bridge Operation
```javascript
import Usdt0ProtocolEvm from '@tetherto/wdk-protocol-bridge-usdt0-evm'
import { WalletAccountEvm } from '@tetherto/wdk-wallet-evm'
async function bridgeTokens() {
const account = new WalletAccountEvm(seedPhrase, {
provider: 'https://eth-mainnet.g.alchemy.com/v2/your-api-key'
})
const bridgeProtocol = new Usdt0ProtocolEvm(account, {
bridgeMaxFee: 1000000000000000n
})
const quote = await bridgeProtocol.quoteBridge({
targetChain: 'arbitrum',
recipient: '0x...',
token: '0x...',
amount: 1000000000000000000n
})
console.log('Bridge quote:', quote)
const result = await bridgeProtocol.bridge({
targetChain: 'arbitrum',
recipient: '0x...',
token: '0x...',
amount: 1000000000000000000n
})
console.log('Bridge result:', result)
return result
}
```
### Multi-Chain Bridge
```javascript
async function bridgeToMultipleChains(bridgeProtocol) {
const chains = ['arbitrum', 'polygon', 'ethereum']
const token = '0x...'
const amount = 1000000000000000000n
const recipient = '0x...'
const results = []
for (const chain of chains) {
try {
const quote = await bridgeProtocol.quoteBridge({
targetChain: chain,
recipient,
token,
amount
})
console.log(`Bridge to ${chain}:`, quote)
const result = await bridgeProtocol.bridge({
targetChain: chain,
recipient,
token,
amount
})
results.push({ chain, result })
console.log(`Bridge to ${chain} successful:`, result.hash)
} catch (error) {
console.error(`Bridge to ${chain} failed:`, error.message)
}
}
return results
}
```
### ERC-4337 Gasless Bridge
```javascript
import { WalletAccountEvmErc4337 } from '@tetherto/wdk-wallet-evm-erc-4337'
async function gaslessBridge() {
const account = new WalletAccountEvmErc4337(seedPhrase, {
provider: 'https://arb1.arbitrum.io/rpc',
paymasterToken: '0x...'
})
const bridgeProtocol = new Usdt0ProtocolEvm(account, {
bridgeMaxFee: 1000000000000000n
})
const result = await bridgeProtocol.bridge({
targetChain: 'polygon',
recipient: '0x...',
token: '0x...',
amount: 1000000000000000000n
}, {
paymasterToken: '0x...'
})
console.log('Gasless bridge result:', result)
return result
}
```
Get started with WDK in a Node.js environment
Configure the Bridge USD₮0 EVM Protocol
Installation, quick start, and usage examples
***
## Need Help?
# Bridge USD₮0 EVM Configuration (/sdk/bridge-modules/bridge-usdt0-evm/configuration)
## Bridge Protocol Configuration
The `Usdt0ProtocolEvm` accepts a configuration object that defines how the bridge protocol works:
```javascript
import Usdt0ProtocolEvm from '@tetherto/wdk-protocol-bridge-usdt0-evm'
import { WalletAccountEvm } from '@tetherto/wdk-wallet-evm'
const account = new WalletAccountEvm(seedPhrase, {
provider: 'https://eth-mainnet.g.alchemy.com/v2/your-api-key'
})
const bridgeProtocol = new Usdt0ProtocolEvm(account, {
bridgeMaxFee: 1000000000000000n
})
```
## Account Configuration
The bridge protocol uses the wallet account's configuration for blockchain access:
```javascript
import { WalletAccountEvm, WalletAccountReadOnlyEvm } from '@tetherto/wdk-wallet-evm'
// Full access account
const account = new WalletAccountEvm(
seedPhrase,
"0'/0/0",
{
provider: 'https://eth-mainnet.g.alchemy.com/v2/your-api-key',
transferMaxFee: 100000000000000
}
)
// Read-only account
const readOnlyAccount = new WalletAccountReadOnlyEvm(
'0x...',
{
provider: 'https://eth-mainnet.g.alchemy.com/v2/your-api-key'
}
)
const bridgeProtocol = new Usdt0ProtocolEvm(account, {
bridgeMaxFee: 1000000000000000n
})
```
## Configuration Options
### Bridge Max Fee
The `bridgeMaxFee` option sets a maximum limit for total bridge costs to prevent unexpectedly high fees.
**Type:** `bigint` (optional)
**Unit:** Wei (1 ETH = 1000000000000000000 Wei)
**Examples:**
```javascript
const config = {
bridgeMaxFee: 1000000000000000n,
}
try {
const result = await bridgeProtocol.bridge({
targetChain: 'arbitrum',
recipient: '0x...',
token: '0x...',
amount: 1000000000000000000n
})
} catch (error) {
if (error.message.includes('Exceeded maximum fee')) {
console.error('Bridge cancelled: Fee too high')
}
}
```
### Provider
The `provider` option comes from the wallet account configuration and specifies how to connect to the blockchain.
**Type:** `string | Eip1193Provider`
**Examples:**
```javascript
// Option 1: Using RPC URL
const account = new WalletAccountEvm(seedPhrase, {
provider: 'https://eth-mainnet.g.alchemy.com/v2/your-api-key'
})
// Option 2: Using browser provider (e.g., MetaMask)
const account = new WalletAccountEvm(seedPhrase, {
provider: window.ethereum
})
// Option 3: Using custom JsonRpcProvider
import { JsonRpcProvider } from 'ethers'
const account = new WalletAccountEvm(seedPhrase, {
provider: new JsonRpcProvider('https://eth-mainnet.g.alchemy.com/v2/your-api-key')
})
```
## ERC-4337 Configuration
When using ERC-4337 accounts, you can override configuration options during bridge operations:
```javascript
const result = await bridgeProtocol.bridge({
targetChain: 'arbitrum',
recipient: '0x...',
token: '0x...',
amount: 1000000000000000000n
}, {
paymasterToken: '0x...',
bridgeMaxFee: 1000000000000000n
})
```
### Paymaster Token
The `paymasterToken` option specifies which token to use for paying gas fees in ERC-4337 accounts.
**Type:** `string` (optional)
**Format:** Token contract address
**Example:**
```javascript
const result = await bridgeProtocol.bridge({
targetChain: 'arbitrum',
recipient: '0x...',
token: '0x...',
amount: 1000000000000000000n
}, {
paymasterToken: '0x...'
})
```
## Network Support
The bridge protocol works with EVM-compatible networks. Change the provider URL in the wallet account configuration:
```javascript
// Ethereum Mainnet
const ethereumAccount = new WalletAccountEvm(seedPhrase, {
provider: 'https://eth-mainnet.g.alchemy.com/v2/your-api-key'
})
// Arbitrum
const arbitrumAccount = new WalletAccountEvm(seedPhrase, {
provider: 'https://arb1.arbitrum.io/rpc'
})
// Polygon
const polygonAccount = new WalletAccountEvm(seedPhrase, {
provider: 'https://polygon-rpc.com'
})
```
## Bridge Options
When calling the bridge method, you need to provide bridge options:
```javascript
const bridgeOptions = {
targetChain: 'arbitrum',
recipient: '0x...',
token: '0x...',
amount: 1000000000000000000n,
oftContractAddress: '0x...', // Optional: custom OFT contract
dstEid: 30110 // Optional: custom destination endpoint ID
}
const result = await bridgeProtocol.bridge(bridgeOptions)
```
### Target Chain
The `targetChain` option specifies which blockchain to bridge tokens to.
**Type:** `string`
**Supported values:** `'ethereum'`, `'arbitrum'`, `'optimism'`, `'polygon'`, `'berachain'`, `'ink'`, `'plasma'`, `'conflux'`, `'corn'`, `'avalanche'`, `'celo'`, `'flare'`, `'hyperevm'`, `'mantle'`, `'megaeth'`, `'monad'`, `'morph'`, `'rootstock'`, `'sei'`, `'stable'`, `'unichain'`, `'xlayer'`, `'solana'`, `'ton'`, `'tron'`
### Recipient
The `recipient` option specifies the address that will receive the bridged tokens.
**Type:** `string`
**Format:** Valid address for the target chain
### Token
The `token` option specifies which token contract to bridge.
**Type:** `string`
**Format:** Token contract address on the source chain
### Amount
The `amount` option specifies how many tokens to bridge.
**Type:** `bigint`
**Unit:** Base units of the token (e.g., for USD₮: 1 USD₮ = 1000000n)
### OFT Contract Address
The `oftContractAddress` option overrides the default OFT (Omnichain Fungible Token) contract address used for the bridge operation.
**Type:** `string` (optional)
**Format:** Contract address on the source chain
**Example:**
```javascript
const result = await bridgeProtocol.bridge({
targetChain: 'arbitrum',
recipient: '0x...',
token: '0x...',
amount: 1000000000000000000n,
oftContractAddress: '0x1234...' // Custom OFT contract
})
```
### Destination Endpoint ID
The `dstEid` option overrides the default LayerZero destination endpoint ID for the target chain.
**Type:** `number` (optional)
**Example:**
```javascript
const result = await bridgeProtocol.bridge({
targetChain: 'solana',
recipient: 'SolanaRecipientAddress...',
token: '0x...',
amount: 1000000000000000000n,
dstEid: 30168 // Solana endpoint ID
})
```
## Error Handling
The bridge protocol will throw errors for invalid configurations:
```javascript
try {
const result = await bridgeProtocol.bridge({
targetChain: 'invalid-chain',
recipient: '0x...',
token: '0x...',
amount: 1000000000000000000n
})
} catch (error) {
if (error.message.includes('not supported')) {
console.error('Chain or token not supported')
}
if (error.message.includes('Exceeded maximum fee')) {
console.error('Bridge fee too high')
}
if (error.message.includes('must be connected to a provider')) {
console.error('Wallet not connected to blockchain')
}
}
```
Get started with WDK in a Node.js environment
Complete API documentation for the bridge protocol
Installation, quick start, and usage examples
***
## Need Help?
# Bridge USD₮0 EVM Overview (/sdk/bridge-modules/bridge-usdt0-evm)
A simple package that lets EVM wallet accounts bridge USD₮0 tokens across different blockchains. This package provides a clean API for moving tokens between chains using the LayerZero protocol and USD₮0 bridge system.
## Features
* **Cross-Chain Bridge**: Move USD₮0 tokens between supported blockchains
* **LayerZero Integration**: Uses LayerZero protocol for secure cross-chain transfers
* **Expanded Multi-Chain Support**: Bridge across 25+ networks including all major EVM chains
* **Non-EVM Destinations**: Bridge to Solana, TON, and TRON from any supported EVM chain
* **Account Abstraction**: Works with both standard EVM wallets and ERC-4337 smart accounts
* **Fee Management**: Built-in fee calculation and bridge cost estimation
* **Token Support**: Supports USD₮0 and XAU₮0 ecosystem tokens
* **Route Overrides**: Custom OFT contract addresses and destination endpoint IDs
* **TypeScript Support**: Full TypeScript definitions included
* **Memory Safety**: Secure transaction handling with proper error management
* **Provider Flexibility**: Works with JSON-RPC URLs and EIP-1193 browser providers
## Supported Networks
### Source Chains (EVM)
| Chain | Chain ID |
| -------------- | -------- |
| Ethereum | 1 |
| Arbitrum | 42161 |
| Optimism | 10 |
| Polygon | 137 |
| Berachain | 80094 |
| Ink | 57073 |
| Plasma | 9745 |
| Conflux eSpace | 1030 |
| Corn | 21000000 |
| Avalanche | 43114 |
| Celo | 42220 |
| Flare | 14 |
| HyperEVM | 999 |
| Mantle | 5000 |
| MegaETH | 4326 |
| Monad | 143 |
| Morph | 2818 |
| Rootstock | 30 |
| Sei | 1329 |
| Stable | 988 |
| Unichain | 130 |
| XLayer | 196 |
### Destination Chains
All source chains above, plus:
| Chain | Endpoint ID (EID) |
| ------ | ----------------- |
| Solana | 30168 |
| TON | 30343 |
| TRON | 30420 |
Token support is determined by the contracts deployed on each chain. The protocol checks for `oftContract`, `legacyMeshContract`, and `xautOftContract` to determine available tokens.
## Next Steps
Get started with WDK in a Node.js environment
Configure the Bridge USD₮0 EVM Protocol
Complete API documentation for the bridge protocol
Installation, quick start, and usage examples
***
## Need Help?
# Bridge USD₮0 EVM Usage (/sdk/bridge-modules/bridge-usdt0-evm/usage)
# Usage
The [@tetherto/wdk-protocol-bridge-usdt0-evm](https://www.npmjs.com/package/@tetherto/wdk-protocol-bridge-usdt0-evm) package bridges USD₮0 across EVM and selected non-EVM networks. Use the guides below for setup, standard and gasless bridging, cross-ecosystem recipients, and error handling.
Install the package, attach WalletAccountEvm, and review supported chains.
EVM-to-EVM bridges, quotes, fee caps, and optional OFT or endpoint overrides.
Gasless bridging with WalletAccountEvmErc4337 and paymaster options.
Send toward Solana, TON, or TRON recipients from EVM.
Interpret bridge failures and dispose of signing material safely.
Get started with WDK in a Node.js environment
Configure RPC, fees, and protocol options for this bridge
Constructor, methods, types, and error behavior
***
# Fiat MoonPay API Reference (/sdk/fiat-modules/fiat-moonpay/api-reference)
# API Reference
Complete API documentation for the `@tetherto/wdk-protocol-fiat-moonpay` module.
## Constructor
### `new MoonPayProtocol(account, config)`
Creates a new MoonPayProtocol instance.
**Parameters:**
| Name | Type | Description |
| --------- | ----------------------------------------------------------- | ------------------------------- |
| `account` | `IWalletAccount` \| `IWalletAccountReadOnly` \| `undefined` | Wallet account for transactions |
| `config` | `MoonPayProtocolConfig` | Configuration object |
**Config Options:**
| Name | Type | Required | Default | Description |
| ------------- | --------------------------- | -------- | ------------ | ------------------------------------------------------------------------ |
| `apiKey` | string | Yes | - | Your MoonPay publishable API key |
| `signUrl` | function | No | - | Callback used to sign buy and sell widget URLs through a trusted backend |
| `cacheTime` | number | No | `600000` | Cache duration for currencies (ms) |
| `environment` | `'production' \| 'sandbox'` | No | `production` | MoonPay widget URL endpoint set |
**Example:**
```typescript
import MoonPayProtocol from '@tetherto/wdk-protocol-fiat-moonpay';
const moonpay = new MoonPayProtocol(walletAccount, {
apiKey: 'pk_live_xxxxx',
signUrl: async (urlForSignature) => urlForSignature,
environment: 'production',
});
```
***
## Methods
### `buy(options)`
Generates a MoonPay widget URL for purchasing cryptocurrency. If `signUrl` is configured, the URL is signed through that callback before being returned.
**Parameters:**
| Name | Type | Required | Description |
| ---------------------- | ---------------- | -------- | ----------------------------------------------------- |
| `options.cryptoAsset` | string | Yes | Cryptocurrency code (e.g., 'eth', 'btc') |
| `options.fiatCurrency` | string | Yes | Fiat currency code (e.g., 'usd', 'eur') |
| `options.cryptoAmount` | number \| bigint | No\* | Amount in smallest crypto units |
| `options.fiatAmount` | number \| bigint | No\* | Amount in smallest fiat units (cents) |
| `options.recipient` | string | No | Wallet address (uses account address if not provided) |
| `options.config` | MoonPayBuyParams | No | Widget configuration options |
\*Either `cryptoAmount` or `fiatAmount` must be provided, but not both.
**Returns:** `Promise\<{ buyUrl: string }\>`
***
### `sell(options)`
Generates a MoonPay widget URL for selling cryptocurrency. If `signUrl` is configured, the URL is signed through that callback before being returned.
**Parameters:**
| Name | Type | Required | Description |
| ----------------------- | ----------------- | -------- | ------------------------------- |
| `options.cryptoAsset` | string | Yes | Cryptocurrency code |
| `options.fiatCurrency` | string | Yes | Fiat currency code |
| `options.cryptoAmount` | number \| bigint | No\* | Amount in smallest crypto units |
| `options.fiatAmount` | number \| bigint | No\* | Amount in smallest fiat units |
| `options.refundAddress` | string | No | Refund wallet address |
| `options.config` | MoonPaySellParams | No | Widget configuration options |
**Returns:** `Promise\<{ sellUrl: string }\>`
***
### `quoteBuy(options)`
Gets a price quote for a cryptocurrency purchase.
**Parameters:**
| Name | Type | Required | Description |
| ---------------------- | --------------------- | -------- | ------------------------------- |
| `options.cryptoAsset` | string | Yes | Cryptocurrency code |
| `options.fiatCurrency` | string | Yes | Fiat currency code |
| `options.cryptoAmount` | number \| bigint | No\* | Amount in smallest crypto units |
| `options.fiatAmount` | number \| bigint | No\* | Amount in smallest fiat units |
| `options.config` | MoonPayQuoteBuyParams | No | Quote parameters |
**Returns:** `Promise\`
```typescript
{
cryptoAmount: bigint, // Crypto amount you'll receive
fiatAmount: bigint, // Fiat amount to pay
fee: bigint, // Total fee amount
rate: string, // Exchange rate
metadata: MoonPayBuyQuoteMetadata
}
```
***
### `quoteSell(options)`
Gets a price quote for selling cryptocurrency.
**Parameters:**
| Name | Type | Required | Description |
| ---------------------- | ---------------------- | -------- | ------------------------------- |
| `options.cryptoAsset` | string | Yes | Cryptocurrency code |
| `options.fiatCurrency` | string | Yes | Fiat currency code |
| `options.cryptoAmount` | number \| bigint | Yes | Amount in smallest crypto units |
| `options.config` | MoonPayQuoteSellParams | No | Quote parameters |
**Returns:** `Promise\`
```typescript
{
cryptoAmount: bigint, // Crypto amount to sell
fiatAmount: bigint, // Fiat amount you'll receive
fee: bigint, // Total fee amount
rate: string, // Exchange rate
metadata: MoonPaySellQuoteMetadata
}
```
***
### `getSupportedCryptoAssets()`
Fetches the list of supported cryptocurrencies. Results are cached.
**Returns:** `Promise\`
```typescript
{
code: string, // Currency code (e.g., 'eth')
decimals: number, // Decimal places
networkCode: string, // Network identifier
name: string, // Display name
metadata: MoonPayCryptoCurrencyDetails
}
```
***
### `getSupportedFiatCurrencies()`
Fetches the list of supported fiat currencies. Results are cached.
**Returns:** `Promise\`
```typescript
{
code: string, // Currency code (e.g., 'usd')
decimals: number, // Decimal places
name: string, // Display name
metadata: MoonPayFiatCurrencyDetails
}
```
***
### `getSupportedCountries()`
Fetches the list of supported countries.
**Returns:** `Promise\`
```typescript
{
code: string, // ISO country code
name: string, // Country name
isBuyAllowed: boolean, // Buy operations allowed
isSellAllowed: boolean,// Sell operations allowed
metadata: MoonPayCountryDetail
}
```
***
### `getTransactionDetail(txId, direction?)`
Retrieves details of a specific transaction.
**Parameters:**
| Name | Type | Required | Default | Description |
| ----------- | ----------------- | -------- | ------- | ---------------------- |
| `txId` | string | Yes | - | MoonPay transaction ID |
| `direction` | `'buy' \| 'sell'` | No | `'buy'` | Transaction type |
**Returns:** `Promise\`
```typescript
{
status: 'completed' | 'failed' | 'in_progress',
cryptoAsset: string,
fiatCurrency: string,
metadata: MoonPayBuyTransaction | MoonPaySellTransaction
}
```
***
## Types
### `MoonPayProtocolConfig`
```typescript
interface MoonPayProtocolConfig {
apiKey: string;
signUrl?: (urlForSignature: string) => Promise;
cacheTime?: number;
environment?: 'production' | 'sandbox';
}
```
### `MoonPayBuyParams`
Widget configuration options for `buy()` operations:
```typescript
interface MoonPayBuyParams {
// UI options (shared with MoonPaySellParams)
colorCode?: string;
theme?: 'dark' | 'light';
themeId?: string;
language?: string;
showAllCurrencies?: boolean;
showOnlyCurrencies?: string;
showWalletAddressForm?: boolean;
redirectURL?: string;
unsupportedRegionRedirectUrl?: string;
skipUnsupportedRegionScreen?: boolean;
// Buy-specific options
defaultCurrencyCode?: string;
walletAddress?: string;
walletAddressTag?: string;
walletAddresses?: string;
walletAddressTags?: string;
contractAddress?: string;
networkCode?: string;
lockAmount?: boolean;
email?: string;
externalTransactionId?: string;
externalCustomerId?: string;
paymentMethod?: string;
}
```
### `MoonPaySellParams`
Widget configuration options for `sell()` operations:
```typescript
interface MoonPaySellParams {
// UI options (shared with MoonPayBuyParams)
colorCode?: string;
theme?: 'dark' | 'light';
themeId?: string;
language?: string;
showAllCurrencies?: boolean;
showOnlyCurrencies?: string;
showWalletAddressForm?: boolean;
redirectURL?: string;
unsupportedRegionRedirectUrl?: string;
skipUnsupportedRegionScreen?: boolean;
// Sell-specific options
defaultBaseCurrencyCode?: string;
refundWalletAddresses?: string;
lockAmount?: boolean;
email?: string;
externalTransactionId?: string;
externalCustomerId?: string;
paymentMethod?: string;
}
```
### `MoonPayQuoteBuyParams`
```typescript
interface MoonPayQuoteBuyParams {
extraFeePercentage?: number; // 0-10%
paymentMethod?: string;
areFeesIncluded?: boolean;
walletAddress?: string;
}
```
### `MoonPayQuoteSellParams`
```typescript
interface MoonPayQuoteSellParams {
extraFeePercentage?: number; // 0-10%
payoutMethod?: string;
}
```
***
## Next Steps
* [Configuration](./configuration) - Setup and configuration options
* [Usage Guide](./usage) - Common usage patterns
# Fiat MoonPay Configuration (/sdk/fiat-modules/fiat-moonpay/configuration)
# Configuration
This page covers all configuration options for the MoonPay fiat module, including optional URL signing and environment selection.
## Prerequisites
Before using this module, you need:
1. A MoonPay developer account - [Create an account on MoonPay Dashboard](https://dashboard.moonpay.com/signup)
2. A publishable API key from your dashboard
3. If you want signed widget URLs, a trusted backend signing endpoint for the `signUrl` callback
## Installation
```bash
npm install @tetherto/wdk-protocol-fiat-moonpay
```
## Basic Configuration
```typescript
import MoonPayProtocol from '@tetherto/wdk-protocol-fiat-moonpay';
const moonpay = new MoonPayProtocol(walletAccount, {
apiKey: 'pk_live_xxxxx', // Your MoonPay publishable API key
signUrl: async (urlForSignature) => {
const response = await fetch('/api/moonpay/sign-url', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ urlForSignature }),
});
if (!response.ok) {
throw new Error(`Failed to sign MoonPay URL: ${response.status} ${response.statusText}`);
}
const { signedUrl } = await response.json();
return signedUrl;
},
environment: 'sandbox',
});
```
## Configuration Options
| Option | Type | Required | Default | Description |
| ------------- | --------------------------- | -------- | ----------------- | ------------------------------------------------------------------------ |
| `apiKey` | string | Yes | - | Your MoonPay publishable API key |
| `signUrl` | function | No | - | Callback used to sign buy and sell widget URLs through a trusted backend |
| `cacheTime` | number | No | `600000` (10 min) | Duration in milliseconds to cache supported currencies |
| `environment` | `'production' \| 'sandbox'` | No | `production` | MoonPay widget URL endpoint set |
## Constructor Overloads
The `MoonPayProtocol` class supports three constructor patterns:
```typescript
// Without account (for public read operations like fetching supported currencies)
const moonpay = new MoonPayProtocol(undefined, config);
// With read-only account
const moonpay = new MoonPayProtocol(readOnlyAccount, config);
// With full wallet account (for buy/sell operations)
const moonpay = new MoonPayProtocol(walletAccount, config);
```
## Environment Configuration
### Sandbox (Testing)
Use sandbox endpoints for development and testing:
```typescript
const moonpay = new MoonPayProtocol(walletAccount, {
apiKey: 'pk_test_xxxxx',
signUrl: async (urlForSignature) => {
const response = await fetch('/api/moonpay/sign-url', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ urlForSignature }),
});
return (await response.json()).signedUrl;
},
environment: 'sandbox',
});
```
In sandbox mode:
* No real transactions are processed
* Use test card numbers provided by MoonPay
* KYC verification is simulated
If you do not need signed URLs, omit `signUrl` and the protocol returns unsigned widget URLs directly.
### Production
For production deployments, use live API keys and the production endpoint set:
```typescript
const moonpay = new MoonPayProtocol(walletAccount, {
apiKey: 'pk_live_xxxxx',
signUrl: async (urlForSignature) => {
const response = await fetch('/api/moonpay/sign-url', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ urlForSignature }),
});
return (await response.json()).signedUrl;
},
environment: 'production',
});
```
## Widget Customization
When calling `buy()` or `sell()`, you can customize the MoonPay widget appearance:
```typescript
const result = await moonpay.buy({
cryptoAsset: 'eth',
fiatCurrency: 'usd',
fiatAmount: 10000n, // $100.00 in cents
config: {
colorCode: '#3B82F6', // Your brand color (hex)
theme: 'dark', // 'dark' or 'light'
language: 'en', // ISO 639-1 language code
redirectURL: 'https://yourapp.com/callback',
},
});
```
### Available Buy Widget Options
| Option | Type | Description |
| ------------------------------ | ------------------- | ------------------------------------------------------- |
| `colorCode` | string | Hexadecimal color for widget accent |
| `theme` | `'dark' \| 'light'` | Widget appearance theme |
| `themeId` | string | ID of a custom theme |
| `language` | string | ISO 639-1 language code |
| `showAllCurrencies` | boolean | Show all supported cryptocurrencies |
| `showOnlyCurrencies` | string | Comma-separated currency codes to display |
| `showWalletAddressForm` | boolean | Show wallet address input form |
| `redirectURL` | string | URL to redirect after completion |
| `unsupportedRegionRedirectUrl` | string | URL for unsupported regions |
| `skipUnsupportedRegionScreen` | boolean | Skip unsupported region screen |
| `defaultCurrencyCode` | string | Pre-selected cryptocurrency code |
| `walletAddress` | string | Pre-filled wallet address |
| `walletAddressTag` | string | Wallet address memo/tag (for EOS, XRP, etc.) |
| `walletAddresses` | string | JSON string of wallet addresses for multiple currencies |
| `walletAddressTags` | string | JSON string of address tags for multiple currencies |
| `contractAddress` | string | Token contract address (DeFi Buy only) |
| `networkCode` | string | Network for the token contract (DeFi Buy only) |
| `lockAmount` | boolean | Prevent user from changing amount |
| `email` | string | Pre-fill customer email |
| `externalTransactionId` | string | Your transaction identifier |
| `externalCustomerId` | string | Your customer identifier |
| `paymentMethod` | string | Pre-select payment method |
### Available Sell Widget Options
For `sell()`, the widget config uses `MoonPaySellParams` with different options:
| Option | Type | Description |
| ------------------------------ | --------------------- | ------------------------------------------- |
| `colorCode` | string | Hexadecimal color for widget accent |
| `theme` | `'dark'` \| `'light'` | Widget appearance theme |
| `themeId` | string | ID of a custom theme |
| `language` | string | ISO 639-1 language code |
| `showAllCurrencies` | boolean | Show all supported cryptocurrencies |
| `showOnlyCurrencies` | string | Comma-separated currency codes to display |
| `showWalletAddressForm` | boolean | Show wallet address input form |
| `redirectURL` | string | URL to redirect after completion |
| `unsupportedRegionRedirectUrl` | string | URL for unsupported regions |
| `skipUnsupportedRegionScreen` | boolean | Skip unsupported region screen |
| `defaultBaseCurrencyCode` | string | Pre-selected cryptocurrency to sell |
| `refundWalletAddresses` | string | JSON string of wallet addresses for refunds |
| `lockAmount` | boolean | Prevent user from changing amount |
| `email` | string | Pre-fill customer email |
| `externalTransactionId` | string | Your transaction identifier |
| `externalCustomerId` | string | Your customer identifier |
| `paymentMethod` | string | Pre-select payout method |
## Next Steps
* [Usage Guide](./usage) - Learn how to integrate MoonPay
* [API Reference](./api-reference) - Complete API documentation
# Fiat MoonPay Overview (/sdk/fiat-modules/fiat-moonpay)
# @tetherto/wdk-protocol-fiat-moonpay Overview
A WDK module for integrating MoonPay's fiat on-ramp and off-ramp services. This module generates signed or unsigned widget URLs that allow users to buy and sell cryptocurrency using fiat currencies directly within your application. Provide a `signUrl` callback if you want the protocol to return signed URLs from a trusted backend, or omit it to use the unsigned widget URLs directly.
Get started by reading the [Usage](./usage) guide.
This module requires a MoonPay developer account. [Create your account here](https://dashboard.moonpay.com/signup).
If you want MoonPay to sign the widget URLs before they are returned, provide a `signUrl` callback that talks to a trusted backend signer. If you omit `signUrl`, the protocol returns unsigned widget URLs directly.
## Features
* **Fiat On-Ramp**: Generate signed or unsigned widget URLs for users to buy cryptocurrency with fiat
* **Fiat Off-Ramp**: Generate signed or unsigned widget URLs for users to sell cryptocurrency with fiat
* **Price Quotes**: Get real-time quotes for buy and sell operations
* **Transaction Tracking**: Retrieve transaction status and details
* **Currency Support**: Query supported cryptocurrencies, fiat currencies, and countries
* **Customizable Widget**: Configure colors, themes, language, and behavior
## Supported Payment Methods
* Credit and debit cards (Visa, Mastercard, etc.)
* Bank transfers (ACH, SEPA, etc.)
* Apple Pay and Google Pay
* Local payment methods (varies by region)
For the full list of supported payment methods by country, see [MoonPay's Supported Payment Methods](https://support.moonpay.com/en/articles/380823-moonpay-s-supported-payment-methods).
## Supported Cryptocurrencies
This module supports purchasing and selling cryptocurrencies on networks compatible with WDK wallet modules, including:
* Ethereum and EVM-compatible chains (ETH, USD₮, etc.)
* Bitcoin (BTC)
* TRON (TRX, USD₮)
* TON
* Solana (SOL, USD₮)
## Next Steps
Set up your MoonPay API key, optional signing callback, and environment
Learn how to integrate MoonPay in your application
Complete API documentation for the module
***
### MoonPay Resources
* [MoonPay Dashboard](https://dashboard.moonpay.com/signup) - Create your developer account
* [MoonPay Support Center](https://support.moonpay.com/) - Official MoonPay documentation and support
* [Supported Payment Methods](https://support.moonpay.com/en/articles/380823-moonpay-s-supported-payment-methods) - Full list by country
***
### Need Help?
# Fiat MoonPay Usage (/sdk/fiat-modules/fiat-moonpay/usage)
# Usage
The [@tetherto/wdk-protocol-fiat-moonpay](https://www.npmjs.com/package/@tetherto/wdk-protocol-fiat-moonpay) module builds signed MoonPay widget URLs and quotes for on-ramp and off-ramp flows. Use the guides below for setup, trading, and transaction follow-up.
Install the package and initialize MoonPayProtocol.
On-ramp, off-ramp, quotes, supported assets, widget options, recipients.
Check status and load transaction details from MoonPay.
Get started with WDK in a Node.js environment
API keys, caching, and MoonPay configuration options
Constructor, methods, and types for MoonPayProtocol
# Manage Accounts (/sdk/core-module/guides/account-management)
This guide explains how to access accounts from your registered wallets. An "Account" object in WDK is your interface for inspecting balances and sending transactions on a specific blockchain.
## Retrieve Accounts
You can retrieve an account using a simple index or a custom derivation path.
### By Index (Recommended)
The simplest way to get an account is by its index (starting at `0`). This uses the default derivation path for the specified blockchain.
```typescript title="Get Account by Index"
// Get the first account (index 0) for Ethereum and TON
const ethAccount = await wdk.getAccount('ethereum', 0)
const tonAccount = await wdk.getAccount('ton', 0)
```
### By Derivation Path (Advanced)
If you need a specific hierarchy, you can request an account by its unique derivation path.
```typescript title="Get Account by Path"
// Custom path for Ethereum
const customEthAccount = await wdk.getAccountByPath('ethereum', "0'/0/1")
```
The WDK instance caches accounts. If you call `getAccount` twice using the same index, the function will return the same `Account` object instance.
**Network Mismatch Warning**
Ensure your WDK instance configuration matches your account environment.
* If using **Testnet** keys, ensure you registered the wallet with a **Testnet RPC** (e.g., `https://sepolia.drpc.org` for ETH, `https://testnet.toncenter.com/api/v2/jsonRPC` for TON).
* If using **Mainnet** keys, ensure you registered the wallet with a **Mainnet RPC** (e.g., `https://eth.drpc.org` for ETH, `https://toncenter.com/api/v2/jsonRPC` for TON).
Using a Mainnet key on a Testnet RPC (or vice versa) will result in "Network not allowed" or zero balance errors.
## View Addresses
Once you have an account object, you can retrieve its public blockchain address using the `getAddress` function.
```typescript title="Get Addresses"
const ethAddress = await ethAccount.getAddress()
console.log('Ethereum address:', ethAddress)
```
## Check Balances
You can check the native token balance of any account (e.g., ETH on Ethereum, TON on TON) by using the `getBalance()` function.
```typescript title="Get Balance"
try {
const balance = await ethAccount.getBalance()
console.log('Balance:', balance)
} catch (error) {
console.error('Failed to fetch balance:', error)
}
```
### Multi-Chain Balance Check
Because WDK offers a unified interface, you can easily iterate through multiple chains to fetch balances.
The following example:
1. Iterates over an array of user defined chains.
2. Retrieves the first account using the respective chain's `getAccount(index)` function.
3. Retrieves the first account's balance using the `getBalance()` function.
4. Logs the balance to the console.
```typescript title="Check All Balances"
const chains = ['ethereum', 'ton', 'bitcoin']
for (const chain of chains) {
try {
const account = await wdk.getAccount(chain, 0)
const balance = await account.getBalance()
console.log(`${chain} balance:`, balance)
} catch (error) {
console.log(`${chain}: Wallet not registered or unavailable`)
}
}
```
## Next Steps
Now that you can access your accounts, learn how to [send transactions](./transactions).
# Error Handling (/sdk/core-module/guides/error-handling)
# Error Handling & Best Practices
This guide covers recommended patterns for error handling and security when using the WDK.
## Handling Common Errors
When interacting with multiple chains and protocols, various runtime issues may occur.
### Missing Registration
The most common error is attempting to access a wallet or protocol that hasn't been registered.
```typescript title="Check Registration Pattern"
try {
// This will throw if 'tron' was never registered via .registerWallet()
const tronAccount = await wdk.getAccount('tron', 0)
} catch (error) {
console.error('Tron wallet not available:', error.message)
}
```
Always use `try/catch` blocks when initializing sessions or accessing dynamic features.
## Memory Management
For security, clear sensitive data from memory when a session is complete. The WDK provides [`dispose()`](../api-reference) for this purpose.
### Disposing the Instance
You can clear every registered wallet using [`dispose()`](../api-reference):
```typescript title="Dispose WDK"
function endSession(wdk) {
// 1. Clean up sensitive data
wdk.dispose()
// 2. Modify app state to reflect logged-out status
// ...
console.log('Session ended, wallet data cleared.')
}
```
### Disposing Specific Wallets
You can dispose only the wallets you no longer need using [`dispose()`](../api-reference):
```typescript title="Dispose Specific Wallets"
// Keep the TON wallet registered, but dispose the Ethereum wallet
wdk.dispose(['ethereum'])
```
**After Disposal:** Once a wallet is disposed, any later call that depends on that wallet registration will fail until you register it again. If you call `wdk.dispose()` without arguments, you must instantiate a new WDK instance or register fresh wallets before resuming operations.
## Security Best Practices
### Environment Variables
Never hardcode API keys or seed phrases in your source code. Use environment variables (e.g., `process.env.TON_API_KEY`).
### Secure Storage
If you persist a session, never store the raw seed phrase in local storage. Use secure operating system storage (like Keychain on macOS or Keystore on Android).
# Getting Started (/sdk/core-module/guides/getting-started)
This guide explains how to install the [`@tetherto/wdk`](https://www.npmjs.com/package/@tetherto/wdk) package and create a new instance to start managing your wallets.
## 1. Installation
### Prerequisites
Before you begin, ensure you have the following installed:
* **[Node.js](https://nodejs.org/)**: version 18 or higher.
* **[npm](https://www.npmjs.com/)**: usually comes with Node.js.
### Install Package
To install the WDK Core package, run the following command in your terminal:
```bash
npm install @tetherto/wdk
```
This package allows you to manage different blockchain wallets and protocols through a single interface.
## 2. Instantiation
To use WDK, you must create an instance of the `WDK` class. This instance acts as the central manager for all your wallets and protocols.
### Import the Module
First, import the `WDK` class from the package:
```typescript title="Import WDK Core"
import WDK from '@tetherto/wdk'
```
### Initialize WDK
You can initialize `WDK` in two ways: with a [new seed phrase](#generate-a-new-wallet) or an [existing one](#restore-an-existing-wallet).
#### Generate a New Wallet
If you are creating a fresh wallet for a user, use the static `getRandomSeedPhrase()` method to generate a secure mnemonic.
```typescript title="Create new WDK Instance"
// 1. Generate a secure random seed phrase
// Generate 24-word seed phrase for higher security
const seedPhrase = WDK.getRandomSeedPhrase(24)
// Or use 12-word seed phrase (default)
// const seedPhrase = WDK.getRandomSeedPhrase()
// 2. Initialize the WDK instance with the new seed
const wdk = new WDK(seedPhrase)
```
**Secure the Seed Phrase:** You must securely store this seed phrase immediately. If it is lost, the user will permanently lose access to their funds.
#### Restore an Existing Wallet
If a user already has a seed phrase (e.g., from a previous session or another wallet), you can pass it directly to the constructor.
```typescript title="Restore WDK Instance"
// Replace this string with the user's actual seed phrase
const existingSeed = 'witch collapse practice feed shame open despair creek road again ice ...'
const wdk = new WDK(existingSeed)
```
## Next Steps
With your WDK instance ready, you can now [register wallet modules](./wallet-registration) to interact with specific blockchains like [Ethereum](../../wallet-modules/wallet-evm/), [TON](../../wallet-modules/wallet-ton/), or [Bitcoin](../../wallet-modules/wallet-btc/).
# Configure Middleware (/sdk/core-module/guides/middleware)
Middleware allows you to intercept wallet operations. You can use this to add [logging](#logging), implement retry logic, or handle [failovers for RPC providers](#failover-protection-with-provider-failover).
## Register Middleware
When registering middleware, you should reference a specific chain. The middleware function runs every time an account is instantiated or an operation is performed, depending on the implementation.
### Logging
This simple middleware logs a message whenever a new account is accessed.
```typescript title="Logging Middleware"
wdk.registerMiddleware('ethereum', async (account) => {
const address = await account.getAddress()
console.log('Accessed Ethereum account:', address)
// You can also attach custom properties or wrap methods here
})
```
## Failover Protection with Provider Failover
The [`@tetherto/wdk-provider-failover`](https://www.npmjs.com/package/@tetherto/wdk-provider-failover) package provides a resilient wrapper for wallet instances. Unlike standard middleware, you wrap your wallet class instantiation directly.
### Install `@tetherto/wdk-provider-failover`
You can install the `@tetherto/wdk-provider-failover` using npm with the following command:
```bash
npm install @tetherto/wdk-provider-failover
```
### Use `createFallbackWallet`
You can import the `createFallbackWallet` function to ensure that if your primary RPC fails, the wallet automatically retries with the fallback providers.
With this configuration, if `sendTransaction` fails due to a network error, the WDK will automatically retry using the fallback providers without throwing an error to your application.
```typescript title="Failover Wrapper Usage"
import { createFallbackWallet } from '@tetherto/wdk-provider-failover'
import { WalletAccountReadOnlyEvm } from '@tetherto/wdk-wallet-evm'
const wallet = createFallbackWallet(
WalletAccountReadOnlyEvm,
['0x...'], // constructor args
{
primary: { provider: 'https://mainnet.infura.io/v3/YOUR_KEY' },
fallbacks: [
{ provider: 'https://eth.llamarpc.com' },
{ provider: 'https://ethereum.publicnode.com' }
]
}
)
// Use the wallet instance directly
const balance = await wallet.getBalance()
```
## Next Steps
Learn about [error handling and best practices](./error-handling) to ensure your application is robust and secure.
# Integrate Protocols (/sdk/core-module/guides/protocol-integration)
The WDK Core module supports registering external protocols. This allows you to extend the basic wallet functionality with advanced features like [token swapping](#swapping-tokens), [cross-chain bridging](#bridging-assets), and lending, all through a unified interface.
## Register Protocols
You can register protocols globally (for all new accounts).
### Global Registration (Recommended)
Global registration ensures that every account you retrieve already has the protocol ready to use. You can do this by chaining a call to `.registerProtocol()` on the WDK instance.
### 1. Install Protocol Modules
Install the [`@tetherto/wdk-protocol-swap-velora-evm`](https://www.npmjs.com/package/@tetherto/wdk-protocol-swap-velora-evm) and [`@tetherto/wdk-protocol-bridge-usdt0-evm`](https://www.npmjs.com/package/@tetherto/wdk-protocol-bridge-usdt0-evm) packages:
```bash
npm install @tetherto/wdk-protocol-swap-velora-evm && npm install @tetherto/wdk-protocol-bridge-usdt0-evm
```
### 2. Register in Code
Now, import the protocol modules and register them with your WDK instance. This makes the protocol methods available to any account derived from that instance.
First, import the necessary modules:
```typescript title="Import Protocols"
import veloraProtocolEvm from '@tetherto/wdk-protocol-swap-velora-evm'
import usdt0ProtocolEvm from '@tetherto/wdk-protocol-bridge-usdt0-evm'
```
Then, register the protocols for the specific chains they support:
```typescript title="Register Protocols"
// Register protocols for specific chains
const wdk = new WDK(seedPhrase)
.registerWallet('ethereum', WalletManagerEvm, ethConfig)
// Register Velora Swap for Ethereum
.registerProtocol('ethereum', 'velora', veloraProtocolEvm, {
apiKey: 'YOUR_API_KEY'
})
// Register USDT0 Bridge for Ethereum
.registerProtocol('ethereum', 'usdt0', usdt0ProtocolEvm, {
ethereumRpcUrl: 'https://eth.drpc.org' // Configuration depends on the module
})
```
## Use Protocols
Once [registered](#register-protocols), you can access the protocol instance using the specific getter methods: `getSwapProtocol`, `getBridgeProtocol`, or `getLendingProtocol`.
### Swapping Tokens
Use `getSwapProtocol` to access registered swap services on any wallet account.
```typescript title="Swap Tokens"
const ethAccount = await wdk.getAccount('ethereum', 0)
const velora = ethAccount.getSwapProtocol('velora')
const result = await velora.swap({
tokenIn: '0x...', // Address of token to sell
tokenOut: '0x...', // Address of token to buy
tokenInAmount: 1000000n // Amount to swap
})
```
### Bridging Assets
1. Use `getBridgeProtocol` to access cross-chain bridges.
2. Call `bridge` from the bridge protocol to send tokens from one protocol to another.
```typescript title="Bridge Assets"
const ethAccount = await wdk.getAccount('ethereum', 0)
const usdt0 = ethAccount.getBridgeProtocol('usdt0')
const result = await usdt0.bridge({
targetChain: 'ton',
recipient: 'UQBla...', // TON address
token: '0x...', // ERC20 Token Address
amount: 1000000n
})
```
**Protocol Availability:** If you try to access a protocol that hasn't been registered (e.g., `getSwapProtocol('uniswap')`), the SDK will throw an error. Always ensure registration matches the ID you request.
## Next Steps
Learn how to [configure middleware](./middleware) to add logging or failover protection to your wallet interactions.
# Send Transactions (/sdk/core-module/guides/transactions)
You can send native tokens (like ETH, TON, or BTC) from any of your wallet accounts to another address.
**Get Testnet Funds:** To test these transactions without spending real money, ensure you are on a testnet and have obtained funds. See [Testnet Funds & Faucets](../../../resources/concepts#testnet-funds--faucets) for a list of available faucets.
**BigInt Usage:** Always use `BigInt` (the `n` suffix) for monetary values to avoid precision loss with large numbers.
## Send Native Tokens
The `sendTransaction` method allows you to transfer value. It accepts a unified configuration object, though specific parameters (like `value` formatting) may vary slightly depending on the blockchain.
### Ethereum Example
On EVM chains, values are typically expressed in Wei (1 ETH = 10^18 Wei).
The following example will:
1. Retrieve the first Ethereum account (see [Manage Accounts](./account-management))
2. Send 0.001 ETH (1000000000000000 wei) to an account using `sendTransaction`.
```typescript title="Send ETH"
const ethAccount = await wdk.getAccount('ethereum', 0)
const result = await ethAccount.sendTransaction({
to: '0x71C7656EC7ab88b098defB751B7401B5f6d8976F',
value: 1000000000000000n // 0.001 ETH (in Wei)
})
console.log('Transaction sent! Hash:', result.hash)
```
### TON Example
On TON, values are expressed in Nanotons (1 TON = 10^9 Nanotons).
The following example will:
1. Retrieve the first TON account
2. Send 1 TON (1000000000 nton) to an account using `sendTransaction`.
```typescript title="Send TON"
// Send TON transaction
const tonAccount = await wdk.getAccount('ton', 0)
const tonResult = await tonAccount.sendTransaction({
to: 'UQCz5ON7jjK32HnqPushubsHxgsXgeSZDZPvh8P__oqol90r',
value: 1000000000n // 1 TON (in nanotons)
})
console.log('TON transaction:', tonResult.hash)
```
## Handling Responses
The `sendTransaction` method returns a [transaction result object](../api-reference). The most important field is typically `hash`, which represents the transaction ID on the blockchain. You can use this hash to track the status of your payment on a block explorer.
## Multi-Chain Transactions
You can orchestrate payments across different chains in a single function by acting on multiple account objects sequentially.
The following example will:
1. Retrieve an ETH and ton account using the `getAccount()` method.
2. Send ETH and `await` the transaction.
3. Send TON and `await` the transaction.
```typescript title="Multi-Chain Payment"
async function sendCrossChainPayments(wdk) {
const ethAccount = await wdk.getAccount('ethereum', 0)
const tonAccount = await wdk.getAccount('ton', 0)
// 1. Send ETH
await ethAccount.sendTransaction({
to: '0x...',
value: 1000000000000000000n
})
// 2. Send TON
await tonAccount.sendTransaction({
to: 'EQ...',
value: 1000000000n
})
}
```
## Next Steps
For more complex interactions like swapping tokens or bridging assets, learn how to [integrate protocols](./protocol-integration).
# Register Wallets (/sdk/core-module/guides/wallet-registration)
This guide explains how to register wallet modules with your WDK instance. The WDK Core module itself doesn't contain blockchain-specific logic; instead, you register separate modules for each chain you want to support (e.g., Ethereum, TON, Bitcoin).
## How it works
The WDK uses a builder pattern, allowing you to chain `.registerWallet()` calls. Each call connects a blockchain-specific manager to your central WDK instance.
### Parameters
The `registerWallet` method (see [API Reference](../api-reference)) requires three arguments:
1. **Symbol**: A unique string identifier for the chain (e.g., `'ethereum'`, `'ton'`). You will use this ID later to retrieve accounts.
2. **Manager Class**: The wallet manager class imported from the specific module (e.g., `WalletManagerEvm`).
3. **Configuration**: An object containing the chain-specific settings (e.g., RPC providers, API keys).
## Installation
Install the [wallet managers](../../wallet-modules/) for the blockchains you want to support:
```bash
npm install @tetherto/wdk-wallet-evm @tetherto/wdk-wallet-tron @tetherto/wdk-wallet-btc
```
## Example: Registering Multiple Wallets
### Import the Wallet Manager Packages
First, import the necessary wallet manager packages:
```typescript title="Import Modules"
import WalletManagerEvm from '@tetherto/wdk-wallet-evm'
import WalletManagerTron from '@tetherto/wdk-wallet-tron'
import WalletManagerBtc from '@tetherto/wdk-wallet-btc'
```
### Register the Wallets
Then, [instantiate WDK](./getting-started#initialize-wdk) and chain the registration calls:
```typescript title="Register Wallets"
const wdk = new WDK(seedPhrase)
// 1. Register Ethereum
.registerWallet('ethereum', WalletManagerEvm, {
provider: 'https://eth.drpc.org'
})
// 2. Register TRON
.registerWallet('tron', WalletManagerTron, {
provider: 'https://api.trongrid.io'
})
// 3. Register Bitcoin
.registerWallet('bitcoin', WalletManagerBtc, {
provider: 'https://blockstream.info/api'
})
```
**RPC Providers:** The examples use public RPC endpoints for demonstration. We do not endorse any specific provider.
* **Testnets:** You can find public RPCs for Ethereum and other EVM chains on [Chainlist](https://chainlist.org).
* **Mainnet:** For production environments, we recommend using reliable, paid RPC providers to ensure stability.
**TRON Networks:** Choose the correct provider for your environment.
* **Mainnet:** `https://api.trongrid.io`
* **Shasta (Testnet):** `https://api.shasta.trongrid.io`
## Next Steps
Once your wallets are registered, you can [manage accounts and specific addresses](./account-management).
# Lending Aave EVM API Reference (/sdk/lending-modules/lending-aave-evm/api-reference)
# API Reference
## Class: AaveProtocolEvm
Main class for Aave V3 lending on EVM.
### Constructor
```javascript
new AaveProtocolEvm(account)
```
Parameters:
* `account`: `WalletAccountEvm | WalletAccountReadOnlyEvm | WalletAccountEvmErc4337 | WalletAccountReadOnlyEvmErc4337`
Example:
```javascript
const aave = new AaveProtocolEvm(account)
```
### Methods
| Method | Description | Returns |
| ------------------------------------------------ | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `supply(options, config?)` | Add tokens to the pool | `Promise<{hash: string, fee: bigint, approveHash?: string, resetAllowanceHash?: string}>` |
| `quoteSupply(options, config?)` | Estimate cost to add tokens | `Promise<{fee: bigint}>` |
| `withdraw(options, config?)` | Remove tokens from the pool | `Promise<{hash: string, fee: bigint}>` |
| `quoteWithdraw(options, config?)` | Estimate cost to withdraw | `Promise<{fee: bigint}>` |
| `borrow(options, config?)` | Borrow tokens | `Promise<{hash: string, fee: bigint}>` |
| `quoteBorrow(options, config?)` | Estimate borrowing cost | `Promise<{fee: bigint}>` |
| `repay(options, config?)` | Repay borrowed tokens | `Promise<{hash: string, fee: bigint}>` |
| `quoteRepay(options, config?)` | Estimate repayment cost | `Promise<{fee: bigint}>` |
| `setUseReserveAsCollateral(token, use, config?)` | Toggle token as collateral | `Promise<{hash: string, fee: bigint}>` |
| `setUserEMode(categoryId, config?)` | Set user eMode | `Promise<{hash: string, fee: bigint}>` |
| `getAccountData(account?)` | Read account stats | `Promise<{ totalCollateralBase: bigint, totalDebtBase: bigint, availableBorrowsBase: bigint, currentLiquidationThreshold: bigint, ltv: bigint, healthFactor: bigint }>` |
***
When `AaveProtocolEvm` is initialized with an ERC‑4337 smart account, the optional `config` argument on mutating and quote methods accepts the same gas-payment override families documented in [`@tetherto/wdk-wallet-evm-erc-4337`](../../wallet-modules/wallet-evm-erc-4337/api-reference): paymaster token, sponsorship policy, and native coins.
### `supply(options, config?)`
Add tokens to the pool.
Options:
* `token` (`string`): token address
* `amount` (`number | bigint`): amount in base units
* `onBehalfOf` (`string`, optional)
Returns:
* May include `approveHash` and `resetAllowanceHash` for standard accounts (e.g., USD₮ allowance reset on Ethereum mainnet)
Example:
```javascript
const res = await aave.supply({ token: 'TOKEN_ADDRESS', amount: 1000000n })
```
***
### `quoteSupply(options, config?)`
Estimate fee to add tokens.
```javascript
const q = await aave.quoteSupply({ token: 'TOKEN_ADDRESS', amount: 1000000n })
```
***
### `withdraw(options, config?)`
Remove tokens from the pool.
Options:
* `token` (`string`)
* `amount` (`number | bigint`)
* `to` (`string`, optional)
```javascript
const tx = await aave.withdraw({ token: 'TOKEN_ADDRESS', amount: 1000000n })
```
***
### `quoteWithdraw(options, config?)`
Estimate fee to withdraw tokens.
```javascript
const q = await aave.quoteWithdraw({ token: 'TOKEN_ADDRESS', amount: 1000000n })
```
***
### `borrow(options, config?)`
Borrow tokens.
Options:
* `token` (`string`)
* `amount` (`number | bigint`)
* `onBehalfOf` (`string`, optional)
```javascript
const tx = await aave.borrow({ token: 'TOKEN_ADDRESS', amount: 1000000n })
```
***
### `quoteBorrow(options, config?)`
Estimate fee to borrow tokens.
```javascript
const q = await aave.quoteBorrow({ token: 'TOKEN_ADDRESS', amount: 1000000n })
```
***
### `repay(options, config?)`
Repay borrowed tokens.
Options:
* `token` (`string`)
* `amount` (`number | bigint`)
* `onBehalfOf` (`string`, optional)
```javascript
const tx = await aave.repay({ token: 'TOKEN_ADDRESS', amount: 1000000n })
```
Returns:
* For standard accounts, may include `approveHash` / `resetAllowanceHash` when applicable.
***
### `quoteRepay(options, config?)`
Estimate fee to repay borrowed tokens.
```javascript
const q = await aave.quoteRepay({ token: 'TOKEN_ADDRESS', amount: 1000000n })
```
***
### `setUseReserveAsCollateral(token, use, config?)`
Toggle token as collateral for the user.
```javascript
const tx = await aave.setUseReserveAsCollateral('TOKEN_ADDRESS', true)
```
***
### `setUserEMode(categoryId, config?)`
Set user eMode category.
```javascript
const tx = await aave.setUserEMode(1)
```
***
### `getAccountData(account?)`
Read account stats like total collateral, debt, and health.
```javascript
const data = await aave.getAccountData()
```
Returns the following structure:
```javascript
{
totalCollateralBase: bigint,
totalDebtBase: bigint,
availableBorrowsBase: bigint,
currentLiquidationThreshold: bigint,
ltv: bigint,
healthFactor: bigint
}
```
***
## ERC‑4337 Config Override (optional)
When the protocol uses `WalletAccountEvmErc4337` or `WalletAccountReadOnlyEvmErc4337`, the optional `config` argument on `supply`, `quoteSupply`, `withdraw`, `quoteWithdraw`, `borrow`, `quoteBorrow`, `repay`, `quoteRepay`, `setUseReserveAsCollateral`, and `setUserEMode` accepts the wallet module's per-call gas-payment overrides.
* **Paymaster token mode**: `paymasterUrl`, `paymasterAddress`, `paymasterToken`, `transferMaxFee`
* **Sponsorship policy mode**: `isSponsored`, `paymasterUrl`, `sponsorshipPolicyId`
* **Native coin mode**: `useNativeCoins`, `transferMaxFee`
Example:
```javascript
const res = await aave.supply(
{ token: '0xdAC17F958D2ee523a2206206994597C13D831ec7', amount: 1000000n },
{
paymasterToken: {
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7'
}
}
)
```
## Rules & Notes
* `token` must be a valid (non‑zero) address
* `amount` > 0 and in token base units (use BigInt)
* `onBehalfOf`/`to` (if set) must be valid, non‑zero addresses
* A provider is required to read/send transactions
* For USD₮ on mainnet, allowance may be reset to 0 then set again before actions
Get started with WDK in a Node.js environment
Get started with WDK's Lending Aave EVM Protocol configuration
Get started with WDK's Lending Aave EVM Protocol usage
***
### Need Help?
# Lending Aave EVM Configuration (/sdk/lending-modules/lending-aave-evm/configuration)
# Configuration
## Service Setup
```javascript
import AaveProtocolEvm from '@tetherto/wdk-protocol-lending-aave-evm'
import { WalletAccountEvm } from '@tetherto/wdk-wallet-evm'
// Create wallet account first
const account = new WalletAccountEvm(seedPhrase, "0'/0/0", {
provider: 'https://ethereum-rpc.publicnode.com'
})
// Create lending service
const aave = new AaveProtocolEvm(account)
```
## Account Configuration
The service uses the wallet account configuration to connect to the target network and sign transactions.
```javascript
import { WalletAccountEvm, WalletAccountReadOnlyEvm } from '@tetherto/wdk-wallet-evm'
// Full access account
const account = new WalletAccountEvm(seedPhrase, "0'/0/0", {
provider: 'https://ethereum-rpc.publicnode.com'
})
// Read-only account (quotes, reads)
const readOnly = new WalletAccountReadOnlyEvm('0xYourAddress', {
provider: 'https://ethereum-rpc.publicnode.com'
})
const aave = new AaveProtocolEvm(account)
```
## ERC‑4337 (Account Abstraction)
When using ERC‑4337 smart accounts, every mutating method and quote helper accepts an optional `config` override. In `v1.0.0-beta.4`, that override matches the three gas-payment families exposed by [`@tetherto/wdk-wallet-evm-erc-4337`](../../wallet-modules/wallet-evm-erc-4337/configuration): paymaster token, sponsorship policy, or native coins.
Use the fields that match the gas-payment mode you want for that call. For the full field-level definitions, see the [`@tetherto/wdk-wallet-evm-erc-4337` configuration docs](../../wallet-modules/wallet-evm-erc-4337/configuration) and [`Config Override`](../../wallet-modules/wallet-evm-erc-4337/api-reference) reference.
```javascript
import { WalletAccountEvmErc4337 } from '@tetherto/wdk-wallet-evm-erc-4337'
const aa = new WalletAccountEvmErc4337(seedPhrase, "0'/0/0", {
chainId: 1,
provider: 'https://arb1.arbitrum.io/rpc',
bundlerUrl: 'YOUR_BUNDLER_URL',
paymasterUrl: 'YOUR_PAYMASTER_URL'
})
const aaveAA = new AaveProtocolEvm(aa)
const result = await aaveAA.supply({ token: '0xdAC17F...ec7', amount: 1000000n }, {
paymasterToken: {
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7'
}
})
```
### Supported Override Families
* **Paymaster token mode**: `paymasterUrl`, `paymasterAddress`, `paymasterToken`, `transferMaxFee`
* **Sponsorship policy mode**: `isSponsored`, `paymasterUrl`, `sponsorshipPolicyId`
* **Native coin mode**: `useNativeCoins`, `transferMaxFee`
## Network Support
Aave V3 spans multiple EVM chains (Ethereum, Arbitrum, Base, Optimism, Polygon, Avalanche, BNB, Celo, Gnosis, Linea, Scroll, Soneium, Sonic, ZkSync, Metis). Ensure the correct RPC and token addresses for the target chain.
```javascript
// Ethereum Mainnet
const eth = new WalletAccountEvm(seedPhrase, "0'/0/0", {
provider: 'https://ethereum-rpc.publicnode.com'
})
// Arbitrum
const arb = new WalletAccountEvm(seedPhrase, "0'/0/0", {
provider: 'https://arb1.arbitrum.io/rpc'
})
```
## Operation Options
Each operation accepts a simple options object:
```javascript
// Supply
await aave.supply({ token: 'TOKEN_ADDRESS', amount: 1000000n })
// Withdraw
await aave.withdraw({ token: 'TOKEN_ADDRESS', amount: 1000000n })
// Borrow
await aave.borrow({ token: 'TOKEN_ADDRESS', amount: 1000000n })
// Repay
await aave.repay({ token: 'TOKEN_ADDRESS', amount: 1000000n })
```
### Common Parameters
* `token` (`string`): ERC‑20 token address
* `amount` (`number | bigint`): token amount in base units
* `onBehalfOf` (`string`, optional): another address to act for (supply/borrow/repay)
* `to` (`string`, optional): destination address (withdraw)
> Note: `amount` must be > 0. Addresses must be valid/non‑zero. A provider is required for any write.
Get started with WDK in a Node.js environment
Get started with WDK's Lending Aave EVM Protocol API
Get started with WDK's Lending Aave EVM Protocol usage
***
### Need Help?
# Lending Aave EVM Overview (/sdk/lending-modules/lending-aave-evm)
A lightweight package that lets EVM wallet accounts interact with Aave V3: supply, withdraw, borrow, repay, and read account data. It works with both standard EVM wallets and ERC‑4337 smart accounts.
## Features
* **Supply/Withdraw**: Add and remove supported assets from Aave pools
* **Borrow/Repay**: Borrow assets and repay debt
* **Account Data**: Read collateral, debt, health factor, and more
* **Quote System**: Estimate fees before sending transactions
* **AA Support**: Works with standard EVM and ERC‑4337 smart accounts
* **TypeScript Support**: Full TypeScript definitions
## Supported Networks
Works on Aave V3 supported EVM networks (e.g., Ethereum, Arbitrum, Base, Optimism, Polygon, Avalanche, BNB, Celo, Gnosis, Linea, Scroll, Soneium, Sonic, ZkSync, Metis). A working RPC provider and correct token addresses are required.
## Wallet Compatibility
* **Standard EVM Wallets**: `@tetherto/wdk-wallet-evm`
* **ERC‑4337 Smart Accounts**: `@tetherto/wdk-wallet-evm-erc-4337`
* **Read‑Only Accounts**: For quoting and reading account data without sending transactions
## Key Components
* **Aave V3 Integration**: Supply, withdraw, borrow, repay primitives
* **Quote Helpers**: `quoteSupply`, `quoteWithdraw`, `quoteBorrow`, `quoteRepay`
* **Collateral Controls**: Toggle collateral usage; set user eMode
## Next Steps
How to supply, withdraw, borrow and repay with Aave
Service setup, account config, ERC‑4337 options
Full API for Aave Protocol Evm methods and types
# Lending Aave EVM Guides (/sdk/lending-modules/lending-aave-evm/usage)
# Usage
The [@tetherto/wdk-protocol-lending-aave-evm](https://www.npmjs.com/package/@tetherto/wdk-protocol-lending-aave-evm) module exposes Aave V3 supply, borrow, and repayment flows for EVM accounts. Follow the guides below for setup, day-to-day operations, and error handling.
Install the package, create AaveProtocolEvm, and review prerequisites.
Supply, withdraw, borrow, repay, quotes, ERC-4337, and account data.
Handle failures and dispose wallet secrets when finished.
Get started with WDK in a Node.js environment
Networks and deployment settings for the Aave lending protocol
Methods and parameters for AaveProtocolEvm
# API Reference (/sdk/swap-modules/swap-velora-evm/api-reference)
## Class: VeloraProtocolEvm
Main class for velora token swaps on EVM.
### Constructor
```javascript
new VeloraProtocolEvm(account, config?)
```
Parameters:
* `account`: `WalletAccountEvm | WalletAccountReadOnlyEvm | WalletAccountEvmErc4337 | WalletAccountReadOnlyEvmErc4337`
* `config` (optional):
* `swapMaxFee` (`bigint`): maximum total gas fee allowed (wei)
Example:
```javascript
const swap = new VeloraProtocolEvm(account, { swapMaxFee: 200000000000000n })
```
### Methods
| Method | Description | Returns |
| ----------------------------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `swap(options, config?)` | Perform a token swap | `Promise<{hash: string, fee: bigint, tokenInAmount: bigint, tokenOutAmount: bigint, approveHash?: string, resetAllowanceHash?: string}>` |
| `quoteSwap(options, config?)` | Get estimated fee and amounts | `Promise<{fee: bigint, tokenInAmount: bigint, tokenOutAmount: bigint}>` |
***
### `swap(options, config?)`
Execute a swap via velora.
Options:
* `tokenIn` (`string`): Address of the ERC‑20 token to sell
* `tokenOut` (`string`): Address of the ERC‑20 token to buy
* `tokenInAmount` (`bigint`, optional): Exact input amount (base units)
* `tokenOutAmount` (`bigint`, optional): Exact output amount (base units)
* `to` (`string`, optional): Recipient address (defaults to account address)
Config (ERC‑4337 only):
* `paymasterToken` (`string`, optional): Token symbol/address for fee sponsorship
* `swapMaxFee` (`bigint`, optional): Per‑swap fee cap (wei)
Returns:
* Standard account: `{ hash, fee, tokenInAmount, tokenOutAmount, approveHash?, resetAllowanceHash? }`
* ERC‑4337 account: `{ hash, fee, tokenInAmount, tokenOutAmount }` (approve may be bundled)
Notes:
* On Ethereum mainnet, selling USD₮ may first set allowance to 0, then approve.
* Requires a provider; requires a non read‑only account to send transactions.
Example:
```javascript
const tx = await swap.swap({
tokenIn: '0xdAC17F...ec7', // USD₮
tokenOut: '0xC02a...6Cc2', // WETH
tokenInAmount: 1000000n
})
```
***
### `quoteSwap(options, config?)`
Get estimated fee and token in/out amounts.
Options are the same as `swap`.
Returns: `{ fee, tokenInAmount, tokenOutAmount }`
Config (ERC‑4337 only):
* `paymasterToken` (`string`, optional): Token symbol/address for fee sponsorship
Works with read‑only accounts.
Example:
```javascript
const quote = await swap.quoteSwap({
tokenIn: '0xdAC17F...ec7', // USD₮
tokenOut: '0xC02a...6Cc2', // WETH
tokenOutAmount: 500000000000000000n // 0.5 WETH
})
```
***
## Errors
Common errors include:
* Insufficient liquidity / no route for pair
* Fee exceeds `swapMaxFee`
* Read‑only account cannot send swaps
* Provider/RPC errors (invalid endpoint, network mismatch)
***
## Types
* `swapMaxFee: bigint` — Upper bound for gas fees (wei)
* `tokenInAmount/tokenOutAmount: bigint` — ERC‑20 base units
* `paymasterToken: string` — token symbol or address (AA only)
Get started with WDK in a Node.js environment
Get started with WDK's Swap velora EVM Protocol configuration
Get started with WDK's Swap velora EVM Protocol usage
***
## Need Help?
# Configuration (/sdk/swap-modules/swap-velora-evm/configuration)
## Swap Service Configuration
The `VeloraProtocolEvm` accepts a configuration object that defines fee controls and behavior:
```javascript
import VeloraProtocolEvm from '@tetherto/wdk-protocol-swap-velora-evm'
import { WalletAccountEvm } from '@tetherto/wdk-wallet-evm'
// Create wallet account first
const account = new WalletAccountEvm(seedPhrase, "0'/0/0", {
provider: 'https://ethereum-rpc.publicnode.com'
})
// Create swap service with configuration
const swapProtocol = new VeloraProtocolEvm(account, {
swapMaxFee: 200000000000000n // Optional: Max swap fee in wei
})
```
## Account Configuration
The swap service uses the wallet account configuration for network access and signing:
```javascript
import { WalletAccountEvm, WalletAccountReadOnlyEvm } from '@tetherto/wdk-wallet-evm'
// Full access account
const account = new WalletAccountEvm(
seedPhrase,
"0'/0/0",
{
provider: 'https://ethereum-rpc.publicnode.com'
}
)
// Read-only account (quotes only)
const readOnly = new WalletAccountReadOnlyEvm(
'0xYourAddress',
{
provider: 'https://ethereum-rpc.publicnode.com'
}
)
// Create swap service
const swapProtocol = new VeloraProtocolEvm(account, {
swapMaxFee: 200000000000000n
})
```
## Configuration Options
### Swap Max Fee
The `swapMaxFee` option sets an upper bound for total gas costs to prevent excessive fees.
**Type:** `bigint` (optional)\
**Unit:** Wei
**Examples:**
```javascript
const config = {
// Cap total gas fee to 0.0002 ETH (in wei)
swapMaxFee: 200000000000000n,
}
// Usage example
try {
const result = await swapProtocol.swap({
tokenIn: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USD₮ (6 decimals)
tokenOut: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH (18 decimals)
tokenInAmount: 1000000n
})
} catch (error) {
if (error.message.includes('max fee')) {
console.error('Swap stopped: Fee too high')
}
}
```
## ERC‑4337 (Account Abstraction) Configuration
When using ERC‑4337 smart accounts (`@tetherto/wdk-wallet-evm-erc-4337`), you can override fee behavior per swap and specify a paymaster token:
```javascript
import { WalletAccountEvmErc4337 } from '@tetherto/wdk-wallet-evm-erc-4337'
const aa = new WalletAccountEvmErc4337(seedPhrase, "0'/0/0", {
chainId: 1,
provider: 'https://arb1.arbitrum.io/rpc',
bundlerUrl: 'YOUR_BUNDLER_URL',
paymasterUrl: 'YOUR_PAYMASTER_URL'
})
const swapAA = new VeloraProtocolEvm(aa, { swapMaxFee: 200000000000000n })
const result = await swapAA.swap({
tokenIn: '0xTokenIn',
tokenOut: '0xTokenOut',
tokenInAmount: 1000000n
}, {
paymasterToken: 'USDT', // Token used to pay for gas
swapMaxFee: 200000000000000n // Per‑swap override
})
```
### Paymaster Token (ERC‑4337)
The `paymasterToken` option indicates which token the paymaster should use to sponsor gas.
**Type:** `string` (optional)\
**Format:** Token symbol or address
**Example:**
```javascript
const result = await swapAA.swap({
tokenIn: '0xdAC17F...ec7',
tokenOut: '0xC02a...6Cc2', // WETH
tokenInAmount: 1000000n
}, {
paymasterToken: 'USDT'
})
```
## Network Support
velora supports multiple EVM networks (e.g., Ethereum, Polygon, Arbitrum). Ensure your account is configured with a valid provider for the target network.
```javascript
// Ethereum Mainnet
const eth = new WalletAccountEvm(seedPhrase, "0'/0/0", {
provider: 'https://ethereum-rpc.publicnode.com'
})
// Polygon
const polygon = new WalletAccountEvm(seedPhrase, "0'/0/0", {
provider: 'https://polygon-bor-rpc.publicnode.com'
})
```
## Swap Options
When calling `swap`, provide the swap parameters:
```javascript
const swapOptions = {
tokenIn: '0xTokenIn', // ERC‑20 to sell
tokenOut: '0xTokenOut', // ERC‑20 to buy
tokenInAmount: 1000000n, // exact input (base units)
// OR
// tokenOutAmount: 1000000n, // exact output (base units)
to: '0xRecipient' // optional recipient (defaults to your address)
}
const result = await swapProtocol.swap(swapOptions)
```
### Parameters
* `tokenIn` (`string`): ERC‑20 address to sell
* `tokenOut` (`string`): ERC‑20 address to buy
* `tokenInAmount` (`bigint`, optional): exact input amount in token base units
* `tokenOutAmount` (`bigint`, optional): exact output amount in token base units
* `to` (`string`, optional): recipient address (defaults to account address)
> Note: Use either `tokenInAmount` OR `tokenOutAmount`, not both.
Get started with WDK in a Node.js environment
Get started with WDK's velora Swap Protocol API
Get started with WDK's velora Swap Protocol usage
***
## Need Help?
# Swap velora EVM Overview (/sdk/swap-modules/swap-velora-evm)
A lightweight package that lets EVM wallet accounts swap tokens using the velora aggregator. It provides a clean SDK for token swaps on EVM chains and works with both standard wallets and ERC‑4337 smart accounts.
## Features
* **Token Swapping**: Execute token swaps through velora on supported EVM networks
* **Account Abstraction**: Compatible with standard EVM accounts and ERC‑4337 smart accounts
* **Fee Controls**: Optional `swapMaxFee` to cap gas costs
* **Allowance Safety**: Handles USD₮ mainnet pattern (reset allowance to 0 before approve)
* **Provider Flexibility**: Works with JSON‑RPC URLs and EIP‑1193 providers
* **TypeScript Support**: Full TypeScript definitions included
## Supported Networks
Works with EVM networks supported by velora (e.g., Ethereum, Polygon, Arbitrum, etc.). A working RPC provider is required.
## Wallet Compatibility
The swap service supports multiple EVM wallet types:
* **Standard EVM Wallets**: `@tetherto/wdk-wallet-evm` accounts
* **ERC‑4337 Smart Accounts**: `@tetherto/wdk-wallet-evm-erc-4337` accounts with bundler/paymaster
* **Read‑Only Accounts**: For quoting swaps without sending transactions
## Key Components
* **velora Integration**: Uses velora aggregator for routing and quotes
* **Quote System**: Pre‑transaction fee and amount estimation via `quoteSwap`
* **AA Integration**: Optional paymaster token and fee cap overrides when using ERC‑4337
* **Allowance Management**: Approve flow handled automatically when required
## Next Steps
Get started with WDK in a Node.js environment
Get started with WDK's velora Swap Protocol configuration
Get started with WDK's velora Swap Protocol API
Get started with WDK's velora Swap Protocol usage
***
## Need Help?
# Swap velora EVM Guides (/sdk/swap-modules/swap-velora-evm/usage)
# Usage
The [@tetherto/wdk-protocol-swap-velora-evm](https://www.npmjs.com/package/@tetherto/wdk-protocol-swap-velora-evm) module routes ERC-20 swaps on EVM chains through Velora. Use the guides below for setup, execution, quotes, and error handling.
Install the package, create VeloraProtocolEvm, and review supported networks.
Exact-input and exact-output swaps, including ERC-4337 smart accounts.
Quote before swapping and compare fees to your max fee cap.
Handle swap and quote failures and dispose wallet state safely.
Get started with WDK in a Node.js environment
RPC, fee limits, and environment settings for the Velora swap protocol
Methods, options, and error notes for VeloraProtocolEvm
# Wallet BTC API Reference (/sdk/wallet-modules/wallet-btc/api-reference)
# API Reference
## Table of Contents
| Class | Description | Methods |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| [WalletManagerBtc](#walletmanagerbtc) | Main class for managing Bitcoin wallets. Extends `WalletManager` from `@tetherto/wdk-wallet`. | [Constructor](#constructor), [Methods](#methods) |
| [WalletAccountBtc](#walletaccountbtc) | Individual Bitcoin wallet account implementation. Implements `IWalletAccount`. | [Constructor](#constructor-1), [Methods](#methods-1), [Properties](#properties) |
| [WalletAccountReadOnlyBtc](#walletaccountreadonlybtc) | Read-only Bitcoin wallet account. Extends `WalletAccountReadOnly` from `@tetherto/wdk-wallet`. | [Constructor](#constructor-2), [Methods](#methods-2) |
| [ElectrumTcp](#electrumtcp) | Standard TCP Electrum client. Implements `IElectrumClient`. | [Constructor](#constructor-3) |
| [ElectrumTls](#electrumtls) | TLS Electrum client. Implements `IElectrumClient`. | [Constructor](#constructor-4) |
| [ElectrumSsl](#electrumssl) | SSL Electrum client. Implements `IElectrumClient`. | [Constructor](#constructor-5) |
| [ElectrumWs](#electrumws) | WebSocket Electrum client for browser environments. Implements `IElectrumClient`. | [Constructor](#constructor-6), [Methods](#methods-3) |
## WalletManagerBtc
The main class for managing Bitcoin wallets.\
Extends `WalletManager` from `@tetherto/wdk-wallet`.
#### Constructor
```javascript
new WalletManagerBtc(seed, config)
```
**Parameters:**
* `seed` (string | Uint8Array): BIP-39 mnemonic seed phrase or seed bytes
* `config` (BtcWalletConfig, optional): Configuration object
* `client` (IElectrumClient, optional): Electrum client instance. If provided, host/port/protocol are ignored.
* `host` (string, optional): Electrum server hostname (default: "electrum.blockstream.info"). Ignored if client is provided.
* `port` (number, optional): Electrum server port (default: 50001). Ignored if client is provided.
* `protocol` (string, optional): Transport protocol - "tcp", "tls", or "ssl" (default: "tcp"). Ignored if client is provided.
* `network` (string, optional): "bitcoin", "testnet", or "regtest" (default: "bitcoin")
* `bip` (number, optional): BIP address type - 44 (legacy) or 84 (native SegWit) (default: 84)
### Methods
| Method | Description | Returns |
| ------------------------ | --------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| `getAccount(index)` | Returns a wallet account at the specified index | `Promise\` |
| `getAccountByPath(path)` | Returns a wallet account at the specified derivation path | `Promise\` |
| `getFeeRates()` | Returns current fee rates for transactions | `Promise\<{normal: bigint, fast: bigint}\>` |
| `dispose()` | Disposes all wallet accounts, clearing private keys from memory and closing internal Electrum connections | `void` |
##### `getAccount(index)`
Returns a wallet account at the specified index using BIP-84 (default) or BIP-44 derivation.
**Parameters:**
* `index` (number, optional): The index of the account to get (default: 0)
**Returns:** `Promise\` - The wallet account
**Example:**
```javascript
// Returns the account with derivation path:
// For mainnet (bitcoin): m/84'/0'/0'/0/1
// For testnet or regtest: m/84'/1'/0'/0/1
const account = await wallet.getAccount(1)
```
##### `getAccountByPath(path)`
Returns a wallet account at the specified derivation path.
**Parameters:**
* `path` (string): The derivation path (e.g., "0'/0/0")
**Returns:** `Promise\` - The wallet account
**Example:**
```javascript
// Returns the account with derivation path:
// For mainnet (bitcoin): m/84'/0'/0'/0/1
// For testnet or regtest: m/84'/1'/0'/0/1
const account = await wallet.getAccountByPath("0'/0/1")
```
##### `getFeeRates()`
Returns current fee rates from mempool.space API.
**Returns:** `Promise\<{normal: bigint, fast: bigint}\>` - Object containing fee rates in sat/vB
* `normal`: Standard fee rate for confirmation within \~1 hour
* `fast`: Higher fee rate for faster confirmation
**Example:**
```javascript
const feeRates = await wallet.getFeeRates()
console.log('Normal fee rate:', feeRates.normal, 'sat/vB')
console.log('Fast fee rate:', feeRates.fast, 'sat/vB')
```
##### `dispose()`
Disposes all wallet accounts, clears sensitive data from memory, and closes internal Electrum connections.
**Returns:** `void`
**Example:**
```javascript
wallet.dispose()
```
## WalletAccountBtc
Represents an individual Bitcoin wallet account. Extends `WalletAccountReadOnlyBtc` and implements `IWalletAccount` from `@tetherto/wdk-wallet`.
#### Constructor
```javascript
new WalletAccountBtc(seed, path, config)
```
**Parameters:**
* `seed` (string | Uint8Array): BIP-39 mnemonic seed phrase or seed bytes
* `path` (string): Derivation path suffix (e.g., "0'/0/0")
* `config` (BtcWalletConfig, optional): Configuration object
* `client` (IElectrumClient, optional): Electrum client instance. If provided, host/port/protocol are ignored.
* `host` (string, optional): Electrum server hostname (default: "electrum.blockstream.info"). Ignored if client is provided.
* `port` (number, optional): Electrum server port (default: 50001). Ignored if client is provided.
* `protocol` (string, optional): Transport protocol - "tcp", "tls", or "ssl" (default: "tcp"). Ignored if client is provided.
* `network` (string, optional): "bitcoin", "testnet", or "regtest" (default: "bitcoin")
* `bip` (number, optional): BIP address type - 44 (legacy) or 84 (native SegWit) (default: 84)
### Methods
| Method | Description | Returns |
| -------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| `getAddress()` | Returns the account's Bitcoin address | `Promise\` |
| `getBalance()` | Returns the total account balance in satoshis, including unconfirmed funds when present | `Promise\` |
| `sendTransaction(options, timeoutMs?)` | Sends a Bitcoin transaction and optionally polls until spent inputs disappear from unspent outputs | `Promise\<{hash: string, fee: bigint}\>` |
| `quoteSendTransaction(options)` | Estimates the fee for a transaction | `Promise\<{fee: bigint}\>` |
| `getTransfers(options?)` | Returns the account's transfer history | `Promise\` |
| `getTransactionReceipt(hash)` | Returns a transaction's receipt | `Promise\` |
| `getMaxSpendable()` | Returns the maximum spendable amount | `Promise\` |
| `sign(message)` | Signs a message with the account's private key | `Promise\` |
| `verify(message, signature)` | Verifies a message signature | `Promise\` |
| `toReadOnlyAccount()` | Creates a read-only version of this account | `Promise\` |
| `dispose()` | Disposes the wallet account, clearing private keys from memory | `void` |
##### `getAddress()`
Returns the account's Bitcoin address (Native SegWit bech32 by default, or legacy if using BIP-44).
**Returns:** `Promise\` - The Bitcoin address
**Example:**
```javascript
const address = await account.getAddress()
console.log('Address:', address) // bc1q... (BIP-84) or 1... (BIP-44)
```
##### `getBalance()`
Returns the account's total balance in satoshis, including unconfirmed funds when present.
**Returns:** `Promise\` - Balance in satoshis
**Example:**
```javascript
const balance = await account.getBalance()
console.log('Balance:', balance, 'satoshis')
```
##### `sendTransaction(options, timeoutMs?)`
Sends a Bitcoin transaction to a single recipient and optionally polls after broadcast until spent inputs disappear from the unspent-output set.
**Parameters:**
* `options` (BtcTransaction): Transaction options
* `to` (string): Recipient's Bitcoin address
* `value` (number | bigint): Amount in satoshis
* `feeRate` (number | bigint, optional): Fee rate in sat/vB. If provided, overrides the fee rate estimated from the blockchain.
* `confirmationTarget` (number, optional): Target blocks for confirmation (default: 1)
* `timeoutMs` (number, optional): Maximum milliseconds to poll after broadcast before returning (default: 10000)
**Returns:** `Promise\<{hash: string, fee: bigint}\>`
* `hash`: Transaction hash
* `fee`: Transaction fee in satoshis
**Example:**
```javascript
const result = await account.sendTransaction({
to: 'bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh',
value: 50000n
})
console.log('Transaction hash:', result.hash)
console.log('Fee:', result.fee, 'satoshis')
```
##### `quoteSendTransaction(options)`
Estimates the fee for a transaction without broadcasting it.
**Parameters:**
* `options` (BtcTransaction): Same as sendTransaction options
* `to` (string): Recipient's Bitcoin address
* `value` (number | bigint): Amount in satoshis
* `feeRate` (number | bigint, optional): Fee rate in sat/vB. If provided, overrides the fee rate estimated from the blockchain.
* `confirmationTarget` (number, optional): Target blocks for confirmation (default: 1)
**Returns:** `Promise\<{fee: bigint}\>`
* `fee`: Estimated transaction fee in satoshis
**Example:**
```javascript
const quote = await account.quoteSendTransaction({
to: 'bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh',
value: 50000n
})
console.log('Estimated fee:', quote.fee, 'satoshis')
```
##### `getTransfers(options?)`
Returns the account's transfer history with detailed transaction information.
**Parameters:**
* `options` (object, optional): Filter options
* `direction` (string, optional): 'incoming', 'outgoing', or 'all' (default: 'all')
* `limit` (number, optional): Maximum number of transfers (default: 10)
* `skip` (number, optional): Number of transfers to skip (default: 0)
**Returns:** `Promise\` - Array of transfer objects
* `txid`: Transaction ID
* `address`: Account's own address
* `vout`: Output index in the transaction
* `height`: Block height (0 if unconfirmed)
* `value`: Transfer value in satoshis (bigint)
* `direction`: 'incoming' or 'outgoing'
* `fee`: Transaction fee in satoshis (bigint, for outgoing transfers)
* `recipient`: Receiving address (for outgoing transfers)
**Example:**
```javascript
const transfers = await account.getTransfers({
direction: 'incoming',
limit: 5
})
console.log('Recent incoming transfers:', transfers)
```
##### `getTransactionReceipt(hash)`
Returns a transaction's receipt if it has been included in a block.
**Parameters:**
* `hash` (string): The transaction hash (64 hex characters)
**Returns:** `Promise\` - The receipt, or null if the transaction has not been included in a block yet.
**Example:**
```javascript
const receipt = await account.getTransactionReceipt('abc123...')
if (receipt) {
console.log('Transaction confirmed')
}
```
##### `getMaxSpendable()`
Returns the maximum spendable amount that can be sent in a single transaction. The maximum spendable amount can differ from the wallet's total balance for several reasons:
* **Transaction fees**: Fees are subtracted from the total balance
* **Uneconomic UTXOs**: Small UTXOs where the fee to spend them exceeds their value are excluded
* **UTXO limit**: A transaction can include at most 200 inputs. Wallets with more UTXOs cannot spend their full balance in a single transaction.
* **Dust limit**: Outputs below the dust threshold (294 sats for SegWit, 546 sats for legacy) cannot be created
**Returns:** `Promise\` - Maximum spendable result
* `amount`: Maximum spendable amount in satoshis (bigint)
* `fee`: Estimated network fee in satoshis (bigint)
* `changeValue`: Estimated change value in satoshis (bigint)
**Example:**
```javascript
const { amount, fee } = await account.getMaxSpendable()
console.log('Max spendable:', amount, 'satoshis')
console.log('Estimated fee:', fee, 'satoshis')
```
##### `sign(message)`
Signs a message using the account's private key.
**Parameters:**
* `message` (string): Message to sign
**Returns:** `Promise\` - Signature as base64 string
**Example:**
```javascript
const signature = await account.sign('Hello Bitcoin!')
console.log('Signature:', signature)
```
##### `verify(message, signature)`
Verifies a message signature using the account's public key.
**Parameters:**
* `message` (string): Original message
* `signature` (string): Signature as base64 string
**Returns:** `Promise\` - True if signature is valid
**Example:**
```javascript
const isValid = await account.verify('Hello Bitcoin!', signature)
console.log('Signature valid:', isValid)
```
##### `toReadOnlyAccount()`
Creates a read-only version of this account that can query balances and transactions but cannot sign or send transactions.
**Returns:** `Promise\` - Read-only account instance
**Example:**
```javascript
const readOnlyAccount = await account.toReadOnlyAccount()
const balance = await readOnlyAccount.getBalance()
```
##### `dispose()`
Disposes the wallet account, securely erasing the private key from memory and closing the Electrum connection.
**Returns:** `void`
**Example:**
```javascript
account.dispose()
// Private key is now securely wiped from memory
```
#### Properties
| Property | Type | Description |
| --------- | --------- | ------------------------------------------- |
| `index` | `number` | The derivation path's index of this account |
| `path` | `string` | The full derivation path of this account |
| `keyPair` | `KeyPair` | The account's public and private key pair |
## WalletAccountReadOnlyBtc
Represents a read-only Bitcoin wallet account. Extends `WalletAccountReadOnly` from `@tetherto/wdk-wallet`.
#### Constructor
```javascript
new WalletAccountReadOnlyBtc(address, config)
```
**Parameters:**
* `address` (string): The account's Bitcoin address
* `config` (object, optional): Configuration object (same as BtcWalletConfig but without `bip`)
* `client` (IElectrumClient, optional): Electrum client instance. If provided, host/port/protocol are ignored.
* `host` (string, optional): Electrum server hostname (default: "electrum.blockstream.info"). Ignored if client is provided.
* `port` (number, optional): Electrum server port (default: 50001). Ignored if client is provided.
* `protocol` (string, optional): Transport protocol - "tcp", "tls", or "ssl" (default: "tcp"). Ignored if client is provided.
* `network` (string, optional): "bitcoin", "testnet", or "regtest" (default: "bitcoin")
### Methods
| Method | Description | Returns |
| ------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------ |
| `getAddress()` | Returns the account's Bitcoin address | `Promise\` |
| `getBalance()` | Returns the total account balance in satoshis, including unconfirmed funds when present | `Promise\` |
| `quoteSendTransaction(options)` | Estimates the fee for a transaction | `Promise\<{fee: bigint}\>` |
| `getTransactionReceipt(hash)` | Returns a transaction's receipt | `Promise\` |
| `getMaxSpendable()` | Returns the maximum spendable amount | `Promise\` |
| `verify(message, signature)` | Verifies a message signature | `Promise\` |
| `dispose()` | Closes any internal Electrum connection | `void` |
##### `getAddress()`
Returns the account's Bitcoin address.
**Returns:** `Promise\` - The Bitcoin address
**Example:**
```javascript
const address = await readOnlyAccount.getAddress()
console.log('Address:', address)
```
##### `getBalance()`
Returns the account's confirmed balance in satoshis.
**Returns:** `Promise\` - Balance in satoshis
**Example:**
```javascript
const balance = await readOnlyAccount.getBalance()
console.log('Balance:', balance, 'satoshis')
```
##### `quoteSendTransaction(options)`
Estimates the fee for a transaction without broadcasting it.
**Parameters:**
* `options` (BtcTransaction): Transaction options
* `to` (string): Recipient's Bitcoin address
* `value` (number | bigint): Amount in satoshis
* `feeRate` (number | bigint, optional): Fee rate in sat/vB
* `confirmationTarget` (number, optional): Target blocks for confirmation (default: 1)
**Returns:** `Promise\<{fee: bigint}\>` - Estimated fee in satoshis
**Example:**
```javascript
const quote = await readOnlyAccount.quoteSendTransaction({
to: 'bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh',
value: 50000n
})
console.log('Estimated fee:', quote.fee, 'satoshis')
```
##### `getTransactionReceipt(hash)`
Returns a transaction's receipt if it has been included in a block.
**Parameters:**
* `hash` (string): The transaction hash
**Returns:** `Promise\` - The receipt, or null if not yet included
**Example:**
```javascript
const receipt = await readOnlyAccount.getTransactionReceipt('abc123...')
if (receipt) {
console.log('Transaction confirmed')
}
```
##### `getMaxSpendable()`
Returns the maximum spendable amount that can be sent in a single transaction.
**Returns:** `Promise\` - Maximum spendable result
* `amount`: Maximum spendable amount in satoshis (bigint)
* `fee`: Estimated network fee in satoshis (bigint)
* `changeValue`: Estimated change value in satoshis (bigint)
**Example:**
```javascript
const { amount, fee } = await readOnlyAccount.getMaxSpendable()
console.log('Max spendable:', amount, 'satoshis')
```
##### `verify(message, signature)`
Verifies a message signature using the account's public key.
**Parameters:**
* `message` (string): Original message
* `signature` (string): Signature as base64 string
**Returns:** `Promise\` - True if signature is valid
**Example:**
```javascript
const isValid = await readOnlyAccount.verify('Hello Bitcoin!', signature)
console.log('Signature valid:', isValid)
```
##### `dispose()`
Closes any internal Electrum connection owned by this account. If a [`client`](/sdk/wallet-modules/wallet-btc/configuration#client) was provided via config, the connection is left open (the caller manages its lifecycle).
**Returns:** `void`
**Example:**
```javascript
readOnlyAccount.dispose()
```
## ElectrumTcp
Electrum client using TCP transport. Standard for command-line and server-side environments.
Implements `IElectrumClient`.
#### Constructor
```javascript
new ElectrumTcp(config)
```
**Parameters:**
* `config` (`Omit`): Configuration options
* `host` (string): Electrum server hostname
* `port` (number): Electrum server port
## ElectrumTls
Electrum client using TLS transport.
Implements `IElectrumClient`.
#### Constructor
```javascript
new ElectrumTls(config)
```
**Parameters:**
* `config` (`Omit`): Configuration options
* `host` (string): Electrum server hostname
* `port` (number): Electrum server port
## ElectrumSsl
Electrum client using SSL transport.
Implements `IElectrumClient`.
#### Constructor
```javascript
new ElectrumSsl(config)
```
**Parameters:**
* `config` (`Omit`): Configuration options
* `host` (string): Electrum server hostname
* `port` (number): Electrum server port
## ElectrumWs
Electrum client using WebSocket transport. Compatible with browser environments where TCP sockets are not available.
Implements `IElectrumClient`.
#### Constructor
```javascript
new ElectrumWs(config)
```
**Parameters:**
* `config` (ElectrumWsConfig): Configuration options
* `url` (string): The WebSocket URL (e.g., 'wss\://electrum.example.com:50004')
### Methods
| Method | Description | Returns |
| ------------------------- | ------------------------------------------------------------- | ---------------------------------- |
| `connect()` | Establishes connection to Electrum server | `Promise\` |
| `close()` | Closes the connection | `Promise\` |
| `reconnect()` | Recreates the underlying socket and reinitializes the session | `Promise\` |
| `getBalance(scripthash)` | Returns balance for a script hash | `Promise\` |
| `listUnspent(scripthash)` | Returns UTXOs for a script hash | `Promise\` |
| `getHistory(scripthash)` | Returns transaction history | `Promise\` |
| `getTransaction(txHash)` | Returns raw transaction hex | `Promise\` |
| `broadcast(rawTx)` | Broadcasts raw transaction | `Promise\` |
| `estimateFee(blocks)` | Returns estimated fee rate | `Promise\` |
## Types
### BtcTransaction
```typescript
interface BtcTransaction {
to: string // The transaction's recipient
value: number | bigint // The amount of bitcoins to send to the recipient (in satoshis)
confirmationTarget?: number // Optional confirmation target in blocks (default: 1)
feeRate?: number | bigint // Optional fee rate in satoshis per virtual byte
}
```
### TransactionResult
```typescript
interface TransactionResult {
hash: string // Transaction hash/ID
fee: bigint // Transaction fee in satoshis
}
```
### FeeRates
```typescript
interface FeeRates {
normal: bigint // Standard fee rate (sat/vB) for ~1 hour confirmation
fast: bigint // Higher fee rate (sat/vB) for faster confirmation
}
```
### BtcTransfer
```typescript
interface BtcTransfer {
txid: string // The transaction's ID
address: string // The user's own address
vout: number // The index of the output in the transaction
height: number // The block height (if unconfirmed, 0)
value: bigint // The value of the transfer (in satoshis)
direction: 'incoming' | 'outgoing' // The direction of the transfer
fee?: bigint // The fee paid for the full transaction (in satoshis)
recipient?: string // The receiving address for outgoing transfers
}
```
### BtcMaxSpendableResult
```typescript
interface BtcMaxSpendableResult {
amount: bigint // The maximum spendable amount in satoshis
fee: bigint // The estimated network fee in satoshis
changeValue: bigint // The estimated change value in satoshis
}
```
### KeyPair
```typescript
interface KeyPair {
publicKey: Uint8Array // Public key bytes
privateKey: Uint8Array | null // Private key bytes (null after dispose)
}
```
### BtcWalletConfig
```typescript
interface BtcWalletConfig {
client?: IElectrumClient // Electrum client instance. If provided, host/port/protocol are ignored.
host?: string // Electrum server hostname (default: "electrum.blockstream.info")
port?: number // Electrum server port (default: 50001)
protocol?: 'tcp' | 'tls' | 'ssl' // Transport protocol (default: "tcp")
network?: 'bitcoin' | 'testnet' | 'regtest' // Network to use (default: "bitcoin")
bip?: 44 | 84 // BIP address type - 44 (legacy) or 84 (native SegWit) (default: 84)
}
```
### IElectrumClient
Interface for implementing custom Electrum clients.
```typescript
interface IElectrumClient {
connect(): Promise
close(): Promise
reconnect(): Promise
getBalance(scripthash: string): Promise
listUnspent(scripthash: string): Promise
getHistory(scripthash: string): Promise
getTransaction(txHash: string): Promise
broadcast(rawTx: string): Promise
estimateFee(blocks: number): Promise
}
```
### ElectrumBalance
```typescript
interface ElectrumBalance {
confirmed: number // Confirmed balance in satoshis
unconfirmed?: number // Unconfirmed balance in satoshis
}
```
### ElectrumUtxo
```typescript
interface ElectrumUtxo {
tx_hash: string // The transaction hash containing this UTXO
tx_pos: number // The output index within the transaction
value: number // The UTXO value in satoshis
height?: number // The block height (0 if unconfirmed)
}
```
### ElectrumHistoryItem
```typescript
interface ElectrumHistoryItem {
tx_hash: string // The transaction hash
height: number // The block height (0 or negative if unconfirmed)
}
```
### MempoolElectrumConfig
```typescript
interface MempoolElectrumConfig {
host: string // Electrum server hostname
port: number // Electrum server port
protocol?: 'tcp' | 'ssl' | 'tls' // Transport protocol (default: 'tcp')
maxRetry?: number // Maximum reconnection attempts (default: 2)
retryPeriod?: number // Delay between reconnection attempts in ms (default: 1000)
pingPeriod?: number // Delay between keep-alive pings in ms (default: 120000)
callback?: (err: Error | null) => void // Called when all retries are exhausted
}
```
Get started with WDK in a Node.js environment
Build mobile wallets with React Native Expo
Get started with WDK's Bitcoin Wallet Usage
Get started with WDK's Bitcoin Wallet Configuration
***
### Need Help?
# Configuration (/sdk/wallet-modules/wallet-btc/configuration)
## Wallet Configuration
```javascript
import WalletManagerBtc, { ElectrumTcp } from '@tetherto/wdk-wallet-btc'
const client = new ElectrumTcp({
host: 'electrum.blockstream.info',
port: 50001
})
const wallet = new WalletManagerBtc(seedPhrase, {
client,
network: 'bitcoin'
})
```
## Account Creation
```javascript
// WalletAccountBtc is created by the WalletManagerBtc
// It takes the same configuration as the manager
const account = await wallet.getAccount(0) // Get account at index 0
const customAccount = await wallet.getAccountByPath("0'/0/5") // Custom path
```
## Configuration Options
### Client
The `client` option specifies an Electrum client instance to use for blockchain data. When provided, the `host`, `port`, and `protocol` options are ignored.
**Type:** `IElectrumClient`
**Default:** None (falls back to host/port/protocol configuration)
**Example:**
```javascript
import { ElectrumTcp } from '@tetherto/wdk-wallet-btc'
const config = {
client: new ElectrumTcp({ host: 'fulcrum.frznode.com', port: 50001 })
}
```
#### Built-in Transport Clients
The package provides four built-in transport clients:
```javascript
import {
ElectrumTcp, // TCP transport (default, port 50001)
ElectrumTls, // TLS transport (port 50002)
ElectrumSsl, // SSL transport (port 50002)
ElectrumWs // WebSocket transport (port 50003)
} from '@tetherto/wdk-wallet-btc'
// TCP (default)
const tcpClient = new ElectrumTcp({ host: 'electrum.blockstream.info', port: 50001 })
// TLS
const tlsClient = new ElectrumTls({ host: 'electrum.blockstream.info', port: 50002 })
// SSL
const sslClient = new ElectrumSsl({ host: 'electrum.blockstream.info', port: 50002 })
// WebSocket
const wsClient = new ElectrumWs({ host: 'electrum.blockstream.info', port: 50003 })
```
#### Custom Electrum Client
You can implement your own client by extending `IElectrumClient`:
```javascript
import { IElectrumClient } from '@tetherto/wdk-wallet-btc'
class MyCustomElectrumClient implements IElectrumClient {
// Implement the required interface methods
}
const wallet = new WalletManagerBtc(seedPhrase, {
client: new MyCustomElectrumClient(params),
network: 'bitcoin'
})
```
### Host
The `host` option specifies the Electrum server hostname to connect to for blockchain data. Ignored if `client` is provided.
**Type:** `string`
**Default:** `"electrum.blockstream.info"`
**Recommended:** Configure your own Electrum server for production use. Public servers can be 10-300x slower and may fail for addresses with many transactions.
**Example:**
```javascript
const config = {
host: 'fulcrum.frznode.com' // Alternative public server
}
```
### Port
The `port` option specifies the Electrum server port to connect to. Ignored if `client` is provided.
**Type:** `number`
**Default:** `50001`
**Common Ports:**
* `50001` - TCP (default)
* `50002` - TLS/SSL
* `50003` - WebSocket
**Example:**
```javascript
const config = {
port: 50001
}
```
### Protocol
The `protocol` option specifies the transport protocol to use. Ignored if `client` is provided.
**Type:** `string`
**Values:**
* `"tcp"` - TCP transport (default)
* `"tls"` - TLS transport
* `"ssl"` - SSL transport
**Default:** `"tcp"`
**Example:**
```javascript
const config = {
host: 'electrum.blockstream.info',
port: 50002,
protocol: 'tls'
}
```
### Network
The `network` option specifies which Bitcoin network to use.
**Type:** `string`
**Values:**
* `"bitcoin"` - Bitcoin [mainnet](../../../resources/concepts#mainnet) (production)
* `"testnet"` - Bitcoin [testnet](../../../resources/concepts#testnet) (development)
* `"regtest"` - Bitcoin [regtest](../../../resources/concepts#regtest) (local testing)
**Default:** `"bitcoin"`
**Example:**
```javascript
const config = {
network: 'testnet' // Use testnet for development
}
```
### BIP
The `bip` option specifies the address type derivation standard to use.
**Type:** `number`
**Values:**
* `84` - [BIP-84](../../../resources/concepts#bip-84-native-segwit) (P2WPKH / Native SegWit) - addresses start with `bc1` (mainnet) or `tb1` (testnet)
* `44` - [BIP-44](../../../resources/concepts#bip-44-multi-account-hierarchy) (P2PKH / Legacy) - addresses start with `1` (mainnet) or `m`/`n` (testnet)
**Default:** `84`
**Example:**
```javascript
// Use legacy addresses
const config = {
bip: 44
}
```
## Electrum Server Configuration
**Important**: While the package defaults to `electrum.blockstream.info:50001` for convenience, **we strongly recommend configuring your own Electrum server** for production use.
### Recommended Approach
**For Production:**
* Set up your own Fulcrum server for optimal performance and reliability
* Use recent Fulcrum versions that support pagination for high-transaction addresses
**For Development/Testing:**
* `fulcrum.frznode.com:50001` - Generally faster than default
* `electrum.blockstream.info:50001` - Default fallback
### Configuration Examples
```javascript
import { ElectrumTcp, ElectrumTls } from '@tetherto/wdk-wallet-btc'
// Production with custom Fulcrum server
const productionClient = new ElectrumTls({
host: 'your-fulcrum-server.com',
port: 50002
})
const productionWallet = new WalletManagerBtc(seedPhrase, {
client: productionClient,
network: 'bitcoin'
})
// Development with alternative public server
const developmentClient = new ElectrumTcp({
host: 'fulcrum.frznode.com',
port: 50001
})
const developmentWallet = new WalletManagerBtc(seedPhrase, {
client: developmentClient,
network: 'bitcoin'
})
```
### Network-Specific Configuration
#### Bitcoin Mainnet
```javascript
import { ElectrumTcp } from '@tetherto/wdk-wallet-btc'
const client = new ElectrumTcp({
host: 'electrum.blockstream.info', // Or your own server
port: 50001
})
const wallet = new WalletManagerBtc(seedPhrase, {
client,
network: 'bitcoin'
})
```
#### Bitcoin Testnet
```javascript
import { ElectrumTcp } from '@tetherto/wdk-wallet-btc'
const client = new ElectrumTcp({
host: 'testnet.hsmiths.com', // Example testnet server
port: 53011
})
const wallet = new WalletManagerBtc(seedPhrase, {
client,
network: 'testnet'
})
```
#### Bitcoin Regtest
```javascript
import { ElectrumTcp } from '@tetherto/wdk-wallet-btc'
const client = new ElectrumTcp({
host: 'localhost', // Local regtest node
port: 50001
})
const wallet = new WalletManagerBtc(seedPhrase, {
client,
network: 'regtest'
})
```
## Derivation Paths
Bitcoin wallet addresses are derived using BIP-32 hierarchical deterministic paths:
### BIP-84 (Native SegWit) - Default
* `m/84'/0'/0'/0/0` for mainnet account 0, address 0
* `m/84'/1'/0'/0/0` for testnet/regtest account 0, address 0
Addresses start with `bc1` (mainnet) or `tb1` (testnet).
### BIP-44 (Legacy)
* `m/44'/0'/0'/0/0` for mainnet account 0, address 0
* `m/44'/1'/0'/0/0` for testnet/regtest account 0, address 0
Addresses start with `1` (mainnet) or `m`/`n` (testnet).
**Default Derivation Path Change in v1.0.0-beta.4+**
The default derivation path was updated in v1.0.0-beta.4 to use BIP-84 (Native SegWit) instead of BIP-44 (Legacy):
* **Previous path** (\<= v1.0.0-beta.3): `m/44'/0'/0'/0/{index}` (Legacy addresses)
* **Current path** (v1.0.0-beta.4+): `m/84'/0'/0'/0/{index}` (Native SegWit addresses)
If you're upgrading from an earlier version, existing wallets created with the old path will generate different addresses. Make sure to migrate any existing wallets or use the old path explicitly if needed for compatibility.
Use [`getAccountByPath`](./api-reference) to supply an explicit derivation path when importing or recreating legacy wallets.
## Complete Configuration Example
```javascript
import WalletManagerBtc, { ElectrumTls } from '@tetherto/wdk-wallet-btc'
// Create Electrum client
const client = new ElectrumTls({
host: 'your-electrum-server.com', // Replace with your server
port: 50002
})
// Create wallet manager with configuration
const wallet = new WalletManagerBtc(seedPhrase, {
client,
network: 'bitcoin',
bip: 84 // Native SegWit (default)
})
// Get accounts (inherit configuration from manager)
const account0 = await wallet.getAccount(0)
const account1 = await wallet.getAccount(1)
const customAccount = await wallet.getAccountByPath("0'/0/5")
// Clean up when done
wallet.dispose()
```
## Performance Considerations
**Electrum Server Performance:**
* Public servers like Blockstream's can be significantly slower
* Addresses with many transactions may cause timeouts
* Custom Fulcrum servers provide better performance and reliability
* Consider server location and network latency
**Configuration Tips:**
* Use `fulcrum.frznode.com` for better development performance
* Set up your own Fulcrum server for production
* Monitor connection stability and implement retry logic
* Consider using multiple backup servers
Get started with WDK in a Node.js environment
Build mobile wallets with React Native Expo
Get started with WDK's BTC Wallet Usage
Get started with WDK's BTC Wallet API
***
## Need Help?
# Wallet BTC Overview (/sdk/wallet-modules/wallet-btc)
A simple and secure package to manage BIP-84 (SegWit) and BIP-44 (Legacy) wallets for the Bitcoin blockchain. This package provides a clean API for creating, managing, and interacting with Bitcoin wallets using BIP-39 seed phrases and Bitcoin-specific derivation paths.
**Default Derivation Path Change in v1.0.0-beta.4+**
The default derivation path was updated in v1.0.0-beta.4 to use BIP-84 (Native SegWit) instead of BIP-44 (Legacy):
* **Previous path** (\<= v1.0.0-beta.3): `m/44'/0'/0'/0/{index}` (Legacy addresses)
* **Current path** (v1.0.0-beta.4+): `m/84'/0'/0'/0/{index}` (Native SegWit addresses)
If you're upgrading from an earlier version, existing wallets created with the old path will generate different addresses. Make sure to migrate any existing wallets or use the old path explicitly if needed for compatibility.
Use [`getAccountByPath`](./api-reference) to supply an explicit derivation path when importing or recreating legacy wallets.
## Features
* **BIP-39 Seed Phrase Support**: Generate and validate BIP-39 mnemonic seed phrases
* **Bitcoin Derivation Paths**: Support for BIP-84 (Native SegWit, default) and BIP-44 (Legacy) derivation paths
* **Multi-Account Management**: Create and manage multiple accounts from a single seed phrase
* **Address Types Support**: Generate Native SegWit (P2WPKH) addresses by default, with Legacy (P2PKH) support via configuration
* **UTXO Management**: Track and manage unspent transaction outputs
* **Transaction Management**: Create, sign, and broadcast Bitcoin transactions (single recipient per transaction)
* **Fee Estimation**: Dynamic fee calculation via mempool.space API
* **Electrum Support**: Connect to Electrum servers for network interaction
* **TypeScript Support**: Full TypeScript definitions included
* **Memory Safety**: Secure private key management with memory-safe implementation
* **Network Flexibility**: Support for mainnet, testnet, and regtest
## Supported Networks
This package works with Bitcoin networks:
* **Bitcoin Mainnet** (`"bitcoin"`)
* **Bitcoin Testnet** (`"testnet"`)
* **Bitcoin Regtest** (`"regtest"`)
### Electrum Server Configuration
**Important**: While the package defaults to `electrum.blockstream.info:50001` for convenience, **we strongly recommend configuring your own Electrum server** for production use.
#### Recommended Approach:
**For Production:**
* Set up your own Fulcrum server for optimal performance and reliability
* Use recent Fulcrum versions that support pagination for high-transaction addresses
**For Development/Testing:**
* `fulcrum.frznode.com:50001` - Generally faster than default
* `electrum.blockstream.info:50001` - Default fallback
## Next Steps
Get started with WDK in a Node.js environment
Get started with WDK's Bitcoin Wallet configuration
Get started with WDK's Bitcoin Wallet API
Get started with WDK's Bitcoin Wallet usage
***
## Need Help?
# Wallet BTC Usage (/sdk/wallet-modules/wallet-btc/usage)
# Usage
The `@tetherto/wdk-wallet-btc` module provides wallet management for the Bitcoin blockchain.
Install the package and create your first wallet.
Work with multiple accounts and custom derivation paths.
Query native BTC balances for owned and read-only accounts.
Send Bitcoin and estimate transaction fees.
Retrieve and filter transfer history.
Sign messages and verify signatures.
Handle errors, manage fees, and dispose of sensitive data.
Get started with WDK in a Node.js environment
Build mobile wallets with React Native Expo
Get started with WDK's Bitcoin Wallet Configuration
Get started with WDK's Bitcoin Wallet API
***
### Need Help?
# Wallet EVM API Reference (/sdk/wallet-modules/wallet-evm/api-reference)
## Table of Contents
| Class | Description | Methods |
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| [WalletManagerEvm](#walletmanagerevm) | Main class for managing EVM wallets. Extends `WalletManager` from `@tetherto/wdk-wallet`. | [Constructor](#constructor), [Methods](#methods) |
| [WalletAccountEvm](#walletaccountevm) | Individual EVM wallet account implementation. Extends `WalletAccountReadOnlyEvm` and implements `IWalletAccount` from `@tetherto/wdk-wallet`. | [Constructor](#constructor-1), [Methods](#methods-1), [Properties](#properties) |
| [WalletAccountReadOnlyEvm](#walletaccountreadonlyevm) | Read-only EVM wallet account. Extends `WalletAccountReadOnly` from `@tetherto/wdk-wallet`. | [Constructor](#constructor-2), [Methods](#methods-2) |
## WalletManagerEvm
The main class for managing EVM wallets.\
Extends `WalletManager` from `@tetherto/wdk-wallet`.
### Constructor
```javascript
new WalletManagerEvm(seed, config?)
```
**Parameters:**
* `seed` (string | Uint8Array): BIP-39 mnemonic seed phrase or seed bytes
* `config` (object, optional): Configuration object
* `provider` (string | Eip1193Provider, optional): RPC endpoint URL or EIP-1193 provider instance
* `transferMaxFee` (number | bigint, optional): Maximum fee amount for transfer operations (in wei)
**Example:**
```javascript
const wallet = new WalletManagerEvm(seedPhrase, {
provider: 'https://rpc.mevblocker.io/fast',
transferMaxFee: 100000000000000 // Maximum fee in wei
})
```
### Methods
| Method | Description | Returns | Throws |
| --------------------------------- | ---------------------------------------------------------------- | ------------------------------------------- | --------------------- |
| `getRandomSeedPhrase(wordCount?)` | (static) Returns a random BIP-39 seed phrase | `string` | - |
| `isValidSeedPhrase(seedPhrase)` | (static) Checks if a seed phrase is valid | `boolean` | - |
| `getAccount(index?)` | Returns a wallet account at the specified index | `Promise\` | - |
| `getAccountByPath(path)` | Returns a wallet account at the specified BIP-44 derivation path | `Promise\` | - |
| `getFeeRates()` | Returns current fee rates for transactions | `Promise\<{normal: bigint, fast: bigint}\>` | If no provider is set |
| `dispose()` | Disposes all wallet accounts, clearing private keys from memory | `void` | - |
### Properties
| Property | Type | Description |
| -------- | ------------ | ----------------------- |
| `seed` | `Uint8Array` | The 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:**
```javascript
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:**
```javascript
const isValid = WalletManagerEvm.isValidSeedPhrase('abandon abandon abandon ...')
console.log('Valid:', isValid)
```
#### `getAccount(index?)`
Returns a wallet account at the specified index following BIP-44 standard.
**Parameters:**
* `index` (number, optional): The index of the account to get (default: 0)
**Returns:** `Promise\` - The wallet account
**Example:**
```javascript
// 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()
```
#### `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\` - The wallet account
**Example:**
```javascript
// 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")
```
#### `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:** Error if no provider is configured
**Example:**
```javascript
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()`
Disposes all wallet accounts, clearing private keys from memory.
**Example:**
```javascript
// Clean up when done
wallet.dispose()
```
## WalletAccountEvm
Represents an individual wallet account. Extends `WalletAccountReadOnlyEvm` and implements `IWalletAccount` from `@tetherto/wdk-wallet`.
### Constructor
```javascript
new WalletAccountEvm(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` (object, optional): Configuration object
* `provider` (string | Eip1193Provider, optional): RPC endpoint URL or EIP-1193 provider instance
* `transferMaxFee` (number | bigint, optional): Maximum fee amount for transfer operations (in wei)
**Throws:**
* Error if seed phrase is invalid (BIP-39 validation fails)
**Example:**
```javascript
const account = new WalletAccountEvm(seedPhrase, "0'/0/0", {
provider: 'https://rpc.mevblocker.io/fast',
transferMaxFee: 100000000000000
})
```
### Methods
| Method | Description | Returns | Throws |
| --------------------------------------- | -------------------------------------------------------------- | ------------------------------------------ | --------------------------------- |
| `getAddress()` | Returns the account's address | `Promise\` | - |
| `sign(message)` | Signs a message using the account's private key | `Promise\` | - |
| `signTypedData(typedData)` | Signs typed data according to EIP-712 | `Promise\` | - |
| `verify(message, signature)` | Verifies a message signature | `Promise\` | - |
| `verifyTypedData(typedData, signature)` | Verifies a typed data signature (EIP-712) | `Promise\` | - |
| `sendTransaction(tx)` | Sends an EVM transaction | `Promise\<{hash: string, fee: bigint}\>` | If no provider |
| `quoteSendTransaction(tx)` | Estimates the fee for an EVM transaction | `Promise\<{fee: bigint}\>` | If no provider |
| `transfer(options)` | Transfers ERC20 tokens to another address | `Promise\<{hash: string, fee: bigint}\>` | If no provider or fee exceeds max |
| `quoteTransfer(options)` | Estimates the fee for an ERC20 transfer | `Promise\<{fee: bigint}\>` | If no provider |
| `getBalance()` | Returns the native token balance (in wei) | `Promise\` | If no provider |
| `getTokenBalance(tokenAddress)` | Returns the balance of a specific ERC20 token | `Promise\` | If no provider |
| `getTokenBalances(tokenAddresses)` | Returns the balances of multiple ERC20 tokens in a single call | `Promise\` | If no provider |
| `approve(options)` | Approves a spender to spend tokens | `Promise\<{hash: string, fee: bigint}\>` | If no provider |
| `getAllowance(token, spender)` | Returns current allowance for a spender | `Promise\` | If no provider |
| `getTransactionReceipt(hash)` | Returns a transaction's receipt | `Promise\` | If no provider |
| `toReadOnlyAccount()` | Returns a read-only copy of the account | `Promise\` | - |
| `dispose()` | Disposes the wallet account, clearing private keys from memory | `void` | - |
#### `getAddress()`
Returns the account's Ethereum address.
**Returns:** `Promise\` - Checksummed Ethereum address
**Example:**
```javascript
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\` - The message signature
**Example:**
```javascript
const message = 'Hello, Ethereum!'
const signature = await account.sign(message)
console.log('Signature:', signature)
```
#### `signTypedData(typedData)`
Signs typed data according to [EIP-712](https://eips.ethereum.org/EIPS/eip-712).
**Parameters:**
* `typedData` (TypedData): The typed data to sign
* `domain` (TypedDataDomain): The domain separator (name, version, chainId, verifyingContract)
* `types` (`Record`): The type definitions
* `message` (`Record`): The message data
**Returns:** `Promise\` - The typed data signature
**Example:**
```javascript
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)
```
#### `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\` - True if signature is valid
**Example:**
```javascript
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](https://eips.ethereum.org/EIPS/eip-712).
**Parameters:**
* `typedData` (TypedData): The typed data that was signed
* `signature` (string): The signature to verify
**Returns:** `Promise\` - True if signature is valid
**Example:**
```javascript
const isValid = await account.verifyTypedData(typedData, signature)
console.log('Typed data signature valid:', isValid) // true
```
#### `sendTransaction(tx)`
Sends an EVM transaction and returns the result with hash and fee.
**Parameters:**
* `tx` (EvmTransaction): The transaction object
* `to` (string): Recipient address
* `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
**Returns:** `Promise\<{hash: string, fee: bigint}\>` - Transaction result
**Throws:** Error if no provider is configured
**Example:**
```javascript
// 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): The transaction object (same format as sendTransaction)
**Returns:** `Promise\<{fee: bigint}\>` - Fee estimate in wei
**Throws:** Error if no provider is configured
**Example:**
```javascript
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` (TransferOptions): Transfer options
* `token` (string): Token contract address
* `recipient` (string): Recipient address
* `amount` (number | bigint): Amount in token base units
**Returns:** `Promise\<{hash: string, fee: bigint}\>` - Transfer result
**Throws:**
* Error if no provider is configured
* Error if fee exceeds `transferMaxFee` (if configured)
**Example:**
```javascript
const result = await account.transfer({
token: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USD₮
recipient: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
amount: 1000000 // 1 USD₮ (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` (TransferOptions): Transfer options (same as transfer)
**Returns:** `Promise\<{fee: bigint}\>` - Fee estimate in wei
**Throws:** Error if no provider is configured
**Example:**
```javascript
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\` - Balance in wei
**Throws:** Error if no provider is configured
**Example:**
```javascript
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\` - Token balance in base units
**Throws:** Error if no provider is configured
**Example:**
```javascript
// Get USD₮ 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 the balances of multiple ERC20 tokens in a single call. More efficient than calling `getTokenBalance` for each token individually.
**Parameters:**
* `tokenAddresses` (string\[]): Array of ERC20 token contract addresses
**Returns:** `Promise\` - Array of token balances in base units, in the same order as the input addresses
**Throws:** Error if no provider is configured
**Example:**
```javascript
const balances = await account.getTokenBalances([
'0xdAC17F958D2ee523a2206206994597C13D831ec7', // USD₮
'0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
'0x6B175474E89094C44Da98b954EedeAC495271d0F' // DAI
])
console.log('USDT balance:', balances[0])
console.log('USDC balance:', balances[1])
console.log('DAI balance:', balances[2])
```
#### `approve(options)`
Approves a specific amount of tokens to a spender.
**Parameters:**
* `options` (ApproveOptions): Approve options
* `token` (string): Token contract address
* `spender` (string): Spender address
* `amount` (number | bigint): Amount to approve
**Returns:** `Promise\<{hash: string, fee: bigint}\>` - Transaction result
**Throws:**
* Error if no provider is configured
* Error if trying to re-approve USDT on Ethereum without resetting to 0 first
**Example:**
```javascript
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\` - The current allowance
**Throws:** Error if no provider is configured
**Example:**
```javascript
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\` - Transaction receipt or null if not mined
**Throws:** Error if no provider is configured
**Example:**
```javascript
const receipt = await account.getTransactionReceipt('0x...')
if (receipt) {
console.log('Confirmed in block:', receipt.blockNumber)
console.log('Status:', receipt.status) // 1 = success, 0 = failed
}
```
#### `toReadOnlyAccount()`
Creates a read-only copy of the account with the same configuration.
**Returns:** `Promise\` - Read-only account instance
**Example:**
```javascript
const readOnlyAccount = await account.toReadOnlyAccount()
// Can check balances but cannot send transactions
const balance = await readOnlyAccount.getBalance()
// readOnlyAccount.sendTransaction() // Would throw error
```
#### `dispose()`
Disposes the wallet account, erasing the private key from memory.
**Example:**
```javascript
// Clean up when done
account.dispose()
```
### Properties
| Property | Type | Description |
| --------- | --------------------------------------------------------- | -------------------------------------------------------------------------- |
| `index` | `number` | The derivation path's index of this account |
| `path` | `string` | The full BIP-44 derivation path of this account |
| `keyPair` | `{privateKey: Uint8Array \| null, publicKey: Uint8Array}` | The account's key pair (⚠️ Contains sensitive data) |
| `address` | `string` | The account's Ethereum address (inherited from `WalletAccountReadOnlyEvm`) |
**Example:**
```javascript
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
```
⚠️ **Security Note**: The `keyPair` property contains sensitive cryptographic material. Never log, display, or expose the private key.
## WalletAccountReadOnlyEvm
Represents a read-only wallet account that can query balances and estimate fees but cannot send transactions.
### Constructor
```javascript
new WalletAccountReadOnlyEvm(address, config?)
```
**Parameters:**
* `address` (string): The account's Ethereum address
* `config` (`Omit`, optional): Configuration object (same as `EvmWalletConfig` but without `transferMaxFee`, since read-only accounts cannot send transactions)
* `provider` (string | Eip1193Provider, optional): RPC endpoint URL or EIP-1193 provider instance
**Example:**
```javascript
const readOnlyAccount = new WalletAccountReadOnlyEvm('0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6', {
provider: 'https://rpc.mevblocker.io/fast'
})
```
### Properties
| Property | Type | Description |
| --------- | -------- | ------------------------------ |
| `address` | `string` | The account's Ethereum address |
### Methods
| Method | Description | Returns | Throws |
| --------------------------------------- | -------------------------------------------------------------- | ------------------------------------------ | -------------- |
| `getAddress()` | Returns the account's address | `Promise\` | - |
| `getBalance()` | Returns the native token balance (in wei) | `Promise\` | If no provider |
| `getTokenBalance(tokenAddress)` | Returns the balance of a specific ERC20 token | `Promise\` | If no provider |
| `getTokenBalances(tokenAddresses)` | Returns the balances of multiple ERC20 tokens in a single call | `Promise\` | If no provider |
| `quoteSendTransaction(tx)` | Estimates the fee for an EVM transaction | `Promise\<{fee: bigint}\>` | If no provider |
| `quoteTransfer(options)` | Estimates the fee for an ERC20 transfer | `Promise\<{fee: bigint}\>` | If no provider |
| `verify(message, signature)` | Verifies a message signature | `Promise\` | - |
| `verifyTypedData(typedData, signature)` | Verifies a typed data signature (EIP-712) | `Promise\` | - |
| `getTransactionReceipt(hash)` | Returns a transaction's receipt | `Promise\` | If no provider |
| `getAllowance(token, spender)` | Returns current allowance for a spender | `Promise\` | If no provider |
#### `getAddress()`
Returns the account's Ethereum address.
**Returns:** `Promise\` - Checksummed Ethereum address
**Example:**
```javascript
const address = await readOnlyAccount.getAddress()
console.log('Account address:', address) // 0x...
```
#### `getBalance()`
Returns the account's native token balance.
**Returns:** `Promise\` - Balance in wei
**Throws:** Error if no provider is configured
**Example:**
```javascript
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\` - Token balance in base units
**Throws:** Error if no provider is configured
**Example:**
```javascript
const tokenBalance = await readOnlyAccount.getTokenBalance('0xdAC17F958D2ee523a2206206994597C13D831ec7')
console.log('USDT balance:', tokenBalance)
```
#### `getTokenBalances(tokenAddresses)`
Returns the balances of multiple ERC20 tokens in a single call. More efficient than calling `getTokenBalance` for each token individually.
**Parameters:**
* `tokenAddresses` (string\[]): Array of ERC20 token contract addresses
**Returns:** `Promise\` - Array of token balances in base units, in the same order as the input addresses
**Throws:** Error if no provider is configured
**Example:**
```javascript
const balances = await readOnlyAccount.getTokenBalances([
'0xdAC17F958D2ee523a2206206994597C13D831ec7', // USD₮
'0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' // USDC
])
console.log('USDT balance:', balances[0])
console.log('USDC balance:', balances[1])
```
#### `quoteSendTransaction(tx)`
Estimates the fee for an EVM transaction.
**Parameters:**
* `tx` (EvmTransaction): The transaction object
**Returns:** `Promise\<{fee: bigint}\>` - Fee estimate in wei
**Throws:** Error if no provider is configured
**Example:**
```javascript
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` (TransferOptions): Transfer options
**Returns:** `Promise\<{fee: bigint}\>` - Fee estimate in wei
**Throws:** Error if no provider is configured
**Example:**
```javascript
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\` - True if signature is valid
**Example:**
```javascript
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](https://eips.ethereum.org/EIPS/eip-712).
**Parameters:**
* `typedData` (TypedData): The typed data that was signed
* `signature` (string): The signature to verify
**Returns:** `Promise\` - True if signature is valid
**Example:**
```javascript
const isValid = await readOnlyAccount.verifyTypedData(typedData, signature)
console.log('Typed data signature valid:', isValid) // true
```
#### `getTransactionReceipt(hash)`
Returns a transaction's receipt if it has been mined.
**Parameters:**
* `hash` (string): The transaction hash
**Returns:** `Promise\` - Transaction receipt or null if not yet mined
**Throws:** Error if no provider is configured
**Example:**
```javascript
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')
}
```
#### `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\` - The allowance
**Example:**
```javascript
const allowance = await readOnlyAccount.getAllowance(
'0xdAC17F958D2ee523a2206206994597C13D831ec7',
'0xSpenderAddress...'
)
console.log('Allowance:', allowance)
```
## Types
### EvmTransaction
```typescript
interface EvmTransaction {
to: string; // The transaction's recipient address
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)
}
```
### TransferOptions
```typescript
interface TransferOptions {
token: string; // ERC20 token contract address
recipient: string; // Recipient's Ethereum address
amount: number | bigint; // Amount in token's base units
}
```
### TransactionResult
```typescript
interface TransactionResult {
hash: string; // Transaction hash
fee: bigint; // Transaction fee paid in wei
}
```
### TransferResult
```typescript
interface TransferResult {
hash: string; // Transfer transaction hash
fee: bigint; // Transfer fee paid in wei
}
```
### FeeRates
```typescript
interface FeeRates {
normal: bigint; // Normal priority fee rate (base fee × 1.1)
fast: bigint; // Fast priority fee rate (base fee × 2.0)
}
```
### KeyPair
```typescript
interface KeyPair {
privateKey: Uint8Array | null; // Private key as Uint8Array (32 bytes, null after dispose)
publicKey: Uint8Array; // Public key as Uint8Array (65 bytes)
}
```
### TypedData
```typescript
interface TypedData {
domain: TypedDataDomain; // The domain separator
types: Record; // The type definitions
message: Record; // The message data
}
```
### TypedDataDomain
```typescript
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
```typescript
interface TypedDataField {
name: string; // The field name
type: string; // The field type (e.g., 'address', 'uint256', 'string')
}
```
### EvmWalletConfig
```typescript
interface EvmWalletConfig {
provider?: string | Eip1193Provider; // RPC URL or EIP-1193 provider instance
transferMaxFee?: number | bigint; // Maximum fee for transfers in wei
}
```
### ApproveOptions
```typescript
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
```typescript
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; // 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)
}
```
Get started with WDK in a Node.js environment
Build mobile wallets with React Native Expo
Get started with WDK's EVM Wallet Usage
Get started with WDK's EVM Wallet Configuration
***
## Need Help?
# Configuration (/sdk/wallet-modules/wallet-evm/configuration)
## Wallet Configuration
The `WalletManagerEvm` accepts a configuration object that defines how the wallet interacts with the blockchain:
```javascript
import WalletManagerEvm from '@tetherto/wdk-wallet-evm'
const config = {
// Recommended: RPC endpoint URL or EIP-1193 provider (required for blockchain operations)
provider: 'https://eth-mainnet.g.alchemy.com/v2/your-api-key',
// Optional: Maximum fee for transfer operations (in wei)
transferMaxFee: 100000000000000 // 0.0001 ETH
}
const wallet = new WalletManagerEvm(seedPhrase, config)
```
## Account Configuration
Both `WalletAccountEvm` and `WalletAccountReadOnlyEvm` share similar configuration options:
```javascript
import { WalletAccountEvm, WalletAccountReadOnlyEvm } from '@tetherto/wdk-wallet-evm'
// Full access account
const account = new WalletAccountEvm(
seedPhrase,
"0'/0/0", // BIP-44 derivation path
{
provider: 'https://eth-mainnet.g.alchemy.com/v2/your-api-key',
transferMaxFee: 100000000000000
}
)
// Read-only account
const readOnlyAccount = new WalletAccountReadOnlyEvm(
'0x...', // Ethereum address
{
provider: 'https://eth-mainnet.g.alchemy.com/v2/your-api-key'
}
)
```
## Configuration Options
### Provider
The `provider` option specifies how to connect to the blockchain. It can be either a URL string or an EIP-1193 compatible provider instance.
**Type:** `string | Eip1193Provider`
**Examples:**
```javascript
// Option 1: Using RPC URL
const config = {
provider: 'https://eth-mainnet.g.alchemy.com/v2/your-api-key'
}
// Option 2: Using browser provider (e.g., MetaMask)
const config = {
provider: window.ethereum
}
// Option 3: Using a custom EIP-1193 provider
// Works in Node.js, Bare, and browsers - zero external dependencies
function createFetchProvider(rpcUrl) {
let requestId = 0
return {
request: async ({ method, params }) => {
const response = await fetch(rpcUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
id: ++requestId,
method,
params: params || []
})
})
const data = await response.json()
if (data.error) throw new Error(data.error.message)
return data.result
}
}
}
const config = {
provider: createFetchProvider('https://eth-mainnet.g.alchemy.com/v2/your-api-key')
}
```
### Transfer Max Fee
The `transferMaxFee` option sets a maximum limit for transaction fees to prevent unexpectedly high costs.
**Type:** `number | bigint` (optional)\
**Unit:** Wei (1 ETH = 1000000000000000000 Wei)
**Examples:**
```javascript
const config = {
// Set maximum fee to 0.0001 ETH
transferMaxFee: 100000000000000n,
}
// Usage example
try {
const result = await account.transfer({
token: '0x...', // ERC20 address
recipient: '0x...',
amount: 1000000n
})
} catch (error) {
if (error.message.includes('Exceeded maximum fee')) {
console.error('Transfer cancelled: Fee too high')
}
}
```
### Fee Rate Multipliers
The wallet manager uses predefined multipliers for fee calculations:
```javascript
// Normal fee rate = base fee × 1.1
const normalFee = await wallet.getFeeRates()
console.log('Normal fee:', normalFee.normal)
// Fast fee rate = base fee × 2.0
const fastFee = await wallet.getFeeRates()
console.log('Fast fee:', fastFee.fast)
```
## Network Support
The configuration works with any EVM-compatible network. Just change the provider URL:
```javascript
// Ethereum Mainnet
const mainnetConfig = {
provider: 'https://eth-mainnet.g.alchemy.com/v2/your-api-key'
}
// Polygon (Matic)
const polygonConfig = {
provider: 'https://polygon-rpc.com'
}
// Arbitrum
const arbitrumConfig = {
provider: 'https://arb1.arbitrum.io/rpc'
}
// BSC (Binance Smart Chain)
const bscConfig = {
provider: 'https://bsc-dataseed.binance.org'
}
// Avalanche C-Chain
const avalancheConfig = {
provider: 'https://avalanche-c-chain-rpc.publicnode.com',
}
// Plasma
const plasmaConfig = {
provider: 'https://plasma.drpc.org',
}
// Stable (uses USD₮ as native gas token)
// No need for ERC-4337 paymaster/bundler setup.
const stableConfig = {
provider: 'https://rpc.stable.xyz',
}
// Sepolia Testnet
const sepoliaConfig = {
provider: 'https://sepolia.drpc.org',
}
```
## Next Steps
Get started with WDK in a Node.js environment
Build mobile wallets with React Native Expo
Get started with WDK's EVM Wallet Usage
Get started with WDK's EVM Wallet API
***
## Need Help?
# Wallet EVM Overview (/sdk/wallet-modules/wallet-evm)
A simple and secure package to manage BIP-44 wallets for EVM (Ethereum Virtual Machine) blockchains. This package provides a clean API for creating, managing, and interacting with Ethereum-compatible wallets using BIP-39 seed phrases and BIP-44 derivation paths.
## Features
* **BIP-39 Seed Phrase Support**: Generate and validate BIP-39 mnemonic seed phrases
* **EVM Derivation Paths**: Support for BIP-44 standard derivation paths for Ethereum (m/44'/60')
* **Multi-Account Management**: Create and manage multiple accounts from a single seed phrase
* **EVM Address Support**: Generate and manage Ethereum-compatible addresses using ethers.js
* **Message Signing**: Sign and verify messages using EVM cryptography
* **Transaction Management**: Send transactions and get fee estimates with EIP-1559 support
* **ERC20 Support**: Query native token and ERC20 token balances using smart contract interactions
* **Batch Token Balance Queries**: Query multiple ERC20 token balances in a single call with `getTokenBalances`
* **TypeScript Support**: Full TypeScript definitions included
* **Memory Safety**: Secure private key management with memory-safe HDNodeWallet implementation
* **Provider Flexibility**: Support for both JSON-RPC URLs and EIP-1193 browser providers
* **Gas Optimization**: Support for EIP-1559 maxFeePerGas and maxPriorityFeePerGas
* **Fee Estimation**: Dynamic fee calculation with normal (1.1x) and fast (2.0x) multipliers
## Supported Networks
This package works with any EVM-compatible blockchain, including:
* **Ethereum**: Mainnet, Sepolia
* **Polygon**: Mainnet, Amoy
* **Binance Smart Chain (BSC)**: Mainnet, Testnet
* **Arbitrum**: One, Nova
* **Optimism**: Mainnet, Sepolia
* **Avalanche C-Chain**: Mainnet, Fuji
* **And many more...**
## Next Steps
Get started with WDK in a Node.js environment
Get started with WDK's EVM Wallet configuration
Get started with WDK's EVM Wallet API
Get started with WDK's EVM Wallet usage
***
## Need Help?
# Usage (/sdk/wallet-modules/wallet-evm/usage)
The `@tetherto/wdk-wallet-evm` module provides wallet management for Ethereum and EVM-compatible blockchains.
Install the package and create your first wallet.
Work with multiple accounts and custom derivation paths.
Query native and ERC-20 token balances.
Send native tokens with EIP-1559 or legacy gas settings.
Transfer ERC-20 tokens and estimate fees.
Sign messages and verify signatures.
Handle errors, manage fees, and dispose of sensitive data.
Get started with WDK in a Node.js environment
Build mobile wallets with React Native Expo
Get started with WDK's EVM Wallet Configuration
Get started with WDK's EVM Wallet API
***
### Need Help?
# Wallet EVM ERC-4337 API Reference (/sdk/wallet-modules/wallet-evm-erc-4337/api-reference)
## Table of Contents
| Class | Description | Methods |
| ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| [WalletManagerEvmErc4337](#walletmanagerevmerc4337) | Main class for managing ERC-4337 EVM wallets. Extends `WalletManager` from `@tetherto/wdk-wallet`. | [Constructor](#constructor), [Methods](#methods) |
| [WalletAccountEvmErc4337](#walletaccountevmerc4337) | Individual ERC-4337 wallet account implementation. Extends `WalletAccountReadOnlyEvmErc4337` and implements `IWalletAccount`. | [Constructor](#constructor-1), [Methods](#methods-1), [Properties](#properties) |
| [WalletAccountReadOnlyEvmErc4337](#walletaccountreadonlyevmerc4337) | Read-only ERC-4337 wallet account. Extends `WalletAccountReadOnly` from `@tetherto/wdk-wallet`. | [Constructor](#constructor-2), [Methods](#methods-2) |
| [ConfigurationError](#configurationerror) | Error 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
```javascript
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
```javascript
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
})
```
Fees are sponsored by a third party via a sponsorship policy.
* `isSponsored` (true): Enables sponsorship mode
* `paymasterUrl` (string): The URL of the paymaster service
* `sponsorshipPolicyId` (string, optional): The sponsorship policy ID
```javascript
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',
// Sponsorship mode
isSponsored: true,
paymasterUrl: 'https://api.candide.dev/public/v3/ethereum',
sponsorshipPolicyId: 'your-policy-id' // Optional
})
```
Fees are paid using the chain's native token (e.g., ETH).
* `useNativeCoins` (true): Enables native coin fee payment
* `transferMaxFee` (number | bigint, optional): Maximum fee limit in native token units
```javascript
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',
// Native coins mode
useNativeCoins: true,
transferMaxFee: 100000000000000n // Optional: max fee in wei
})
```
### Methods
| Method | Description | Returns | Throws |
| --------------------------------- | ---------------------------------------------------------------- | ------------------------------------------- | -------------- |
| `getRandomSeedPhrase(wordCount?)` | (static) Returns a random BIP-39 seed phrase | `string` | - |
| `isValidSeedPhrase(seedPhrase)` | (static) Checks if a seed phrase is valid | `boolean` | - |
| `getAccount(index?)` | Returns a wallet account at the specified index | `Promise\` | - |
| `getAccountByPath(path)` | Returns a wallet account at the specified BIP-44 derivation path | `Promise\` | - |
| `getFeeRates()` | Returns current fee rates for transactions | `Promise\<{normal: bigint, fast: bigint}\>` | If no provider |
| `dispose()` | Disposes all wallet accounts, clearing private keys from memory | `void` | - |
### Properties
| Property | Type | Description |
| -------- | ------------ | --------------------------------- |
| `seed` | `Uint8Array` | The 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:**
```javascript
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:**
```javascript
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\` - The wallet account
**Example:**
```javascript
// 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\` - The wallet account
**Example:**
```javascript
// 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:**
```javascript
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:**
```javascript
// 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:
```javascript
// 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
```javascript
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](#constructor))
**Example:**
```javascript
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
| Method | Description | Returns | Throws |
| --------------------------------------- | -------------------------------------------------------------- | -------------------------------------------- | ------------------ |
| `predictSafeAddress(owner, config)` | (static) Predicts the Safe address for a given owner | `string` | - |
| `getAddress()` | Returns the Safe account's address | `Promise\` | - |
| `sign(message)` | Signs a message using the account's private key | `Promise\` | - |
| `verify(message, signature)` | Verifies a message signature | `Promise\` | - |
| `sendTransaction(tx, config?)` | Sends a transaction via UserOperation | `Promise\<{hash: string, fee: bigint}\>` | If fee exceeds max |
| `quoteSendTransaction(tx, config?)` | Estimates the fee for a UserOperation | `Promise\<{fee: bigint}\>` | - |
| `transfer(options, config?)` | Transfers ERC20 tokens via UserOperation | `Promise\<{hash: string, fee: bigint}\>` | If fee exceeds max |
| `quoteTransfer(options, config?)` | Estimates the fee for an ERC20 transfer | `Promise\<{fee: bigint}\>` | - |
| `approve(options)` | Approves a spender to spend ERC20 tokens | `Promise\<{hash: string, fee: bigint}\>` | - |
| `getBalance()` | Returns the native token balance (in wei) | `Promise\` | - |
| `getTokenBalance(tokenAddress)` | Returns the balance of a specific ERC20 token | `Promise\` | - |
| `getPaymasterTokenBalance()` | Returns the paymaster token balance | `Promise\` | - |
| `getAllowance(token, spender)` | Returns current token allowance for a spender | `Promise\` | - |
| `getTransactionReceipt(hash)` | Returns a transaction receipt | `Promise\` | - |
| `getUserOperationReceipt(hash)` | Returns a UserOperation receipt | `Promise\` | - |
| `signTypedData(typedData)` | Signs EIP-712 typed structured data | `Promise\` | - |
| `verifyTypedData(typedData, signature)` | Verifies an EIP-712 typed data signature | `Promise\` | - |
| `getTokenBalances(tokenAddresses)` | Returns balances for multiple ERC20 tokens | `Promise\