Reference@t402/wdk

@t402/wdk

Tether Wallet Development Kit integration for T402, enabling self-custodial multi-chain wallets with USDT0 payments and cross-chain bridging.

Installation

pnpm add @t402/wdk @tetherto/wdk @tetherto/wdk-wallet-evm

Quick Start

import WDK from '@tetherto/wdk';
import WalletManagerEvm from '@tetherto/wdk-wallet-evm';
import { T402WDK } from '@t402/wdk';
 
// Register WDK modules (once at app startup)
T402WDK.registerWDK(WDK, WalletManagerEvm);
 
// Create wallet
const seedPhrase = T402WDK.generateSeedPhrase();
const wallet = new T402WDK(seedPhrase, {
  arbitrum: 'https://arb1.arbitrum.io/rpc',
  base: 'https://mainnet.base.org'
});
 
// Get signer for T402 payments
const signer = await wallet.getSigner('arbitrum');
const address = await wallet.getAddress('arbitrum');

One-Step Setup with create()

import WDK from '@tetherto/wdk';
import WalletManagerEvm from '@tetherto/wdk-wallet-evm';
import BridgeUsdt0Evm from '@tetherto/wdk-protocol-bridge-usdt0-evm';
import { T402WDK } from '@t402/wdk';
 
// Create a fully configured wallet in one call
const wallet = T402WDK.create(WDK, {
  seedPhrase: 'your twelve word seed phrase ...',
  chains: {
    arbitrum: 'https://arb1.arbitrum.io/rpc',
    base: 'https://mainnet.base.org',
    ethereum: 'https://eth.llamarpc.com',
  },
  modules: {
    wallets: { evm: WalletManagerEvm },
    protocols: { bridgeUsdt0Evm: BridgeUsdt0Evm },
  },
});
 
// Get all signers at once for multi-chain HTTP client
const signers = await wallet.getAllSigners();
const client = createT402HTTPClient({ signers });

Multi-Chain Registration

import WDK from '@tetherto/wdk';
import WalletManagerEvm from '@tetherto/wdk-wallet-evm';
import WalletManagerTon from '@tetherto/wdk-wallet-ton';
import WalletManagerSolana from '@tetherto/wdk-wallet-solana';
import WalletManagerTron from '@tetherto/wdk-wallet-tron';
import { T402WDK } from '@t402/wdk';
 
// Register all chain wallet modules at once
T402WDK.registerWDK(WDK, {
  wallets: {
    evm: WalletManagerEvm,
    ton: WalletManagerTon,
    solana: WalletManagerSolana,
    tron: WalletManagerTron,
  },
  protocols: {
    bridgeUsdt0Evm: BridgeUsdt0Evm,
    swapVeloraEvm: SwapVeloraEvm,
  }
});
 
const wallet = new T402WDK(seedPhrase, {
  arbitrum: 'https://arb1.arbitrum.io/rpc'
});
 
// Get signers for different chains
const evmSigner = await wallet.getSigner('arbitrum');
const tonSigner = await wallet.getTonSigner();
const svmSigner = await wallet.getSvmSigner();
const tronSigner = await wallet.getTronSigner();

Wrap an Existing WDK Instance

import { T402WDK } from '@t402/wdk';
 
// If you already have a configured @tetherto/wdk instance
const wallet = T402WDK.fromWDK(existingWdkInstance, {
  arbitrum: 'https://arb1.arbitrum.io/rpc',
});

T402WDK Class

Constructor

const wallet = new T402WDK(seedPhrase, chainConfig, options?);
ParameterTypeDescription
seedPhrasestringBIP-39 seed phrase
chainConfigEvmChainConfigRPC endpoints per chain
optionsT402WDKOptionsOptional configuration

Options

interface T402WDKOptions {
  /** Cache configuration */
  cache?: T402BalanceCacheConfig;
 
  /** Auto-refresh balances */
  autoRefresh?: boolean;
 
  /** Refresh interval (ms) */
  refreshInterval?: number;
}

Static Methods

create

One-step factory: register modules + create wallet.

const wallet = T402WDK.create(WDK, {
  seedPhrase: '...',
  chains: { arbitrum: 'https://arb1.arbitrum.io/rpc' },
  modules: { wallets: { evm: WalletManagerEvm } },
});

fromWDK

Wrap a pre-configured @tetherto/wdk instance.

const wallet = T402WDK.fromWDK(wdkInstance, chainConfig);

registerWDK

Register WDK modules (required before creating instances).

// Legacy (EVM-only)
T402WDK.registerWDK(WDK, WalletManagerEvm);
 
// Unified (multi-chain)
T402WDK.registerWDK(WDK, {
  wallets: { evm: WalletManagerEvm, ton: WalletManagerTon },
  protocols: { bridgeUsdt0Evm: BridgeUsdt0Evm },
});

generateSeedPhrase

Generate a new BIP-39 seed phrase.

const seedPhrase = T402WDK.generateSeedPhrase();
// "word1 word2 word3 ... word12"

Instance Methods

getAllSigners

Get all signers as an array for T402 HTTP clients.

const signers = await wallet.getAllSigners();
// Returns: Array<{ scheme, network, signer, family }>
 
const client = createT402HTTPClient({ signers });

Options:

  • accountIndex - HD wallet account index (default: 0)
  • schemes - Payment schemes (default: ["exact"])
  • includeNonEvm - Include TON/Solana/TRON signers (default: true)

getAddress

Get wallet address for a chain.

const address = await wallet.getAddress('arbitrum');
// '0x...'

getSigner

Get a T402-compatible signer for payments.

const signer = await wallet.getSigner('arbitrum');
 
// Use with T402 HTTP client
const client = createT402HTTPClient({
  signers: [{ scheme: 'exact', signer }]
});

getUsdt0Balance

Get USDT0 balance on a specific chain.

const balance = await wallet.getUsdt0Balance('arbitrum');
// 1000000n (1 USDT0)

getUsdcBalance

Get USDC balance on a specific chain.

const balance = await wallet.getUsdcBalance('base');

getAggregatedBalances

Get balances across all configured chains.

const balances = await wallet.getAggregatedBalances();
 
console.log('Total USDT0:', balances.totalUsdt0);
console.log('Total USDC:', balances.totalUsdc);
console.log('By chain:', balances.byChain);
// {
//   arbitrum: { usdt0: 500000n, usdc: 0n },
//   base: { usdt0: 500000n, usdc: 1000000n }
// }

findBestChainForPayment

Find the best chain for a payment amount.

const best = await wallet.findBestChainForPayment(1000000n);
 
if (best) {
  console.log('Chain:', best.chain);   // 'arbitrum'
  console.log('Token:', best.token);   // 'USDT0'
  console.log('Balance:', best.balance); // 5000000n
}

bridgeUsdt0

Bridge USDT0 between chains via LayerZero.

const result = await wallet.bridgeUsdt0({
  fromChain: 'ethereum',
  toChain: 'arbitrum',
  amount: 100000000n // 100 USDT0
});
 
console.log('Tx hash:', result.txHash);
console.log('Message GUID:', result.messageGuid);

WDKSigner

Low-level signer for T402 payments.

createWDKSigner

import { createWDKSigner } from '@t402/wdk';
 
const signer = createWDKSigner(wdkAccount, chainId);

MockWDKSigner

For testing without real WDK.

import { MockWDKSigner } from '@t402/wdk';
 
const mockSigner = new MockWDKSigner('0x...address', 8453);

Chain Configuration

Default Chains

import { DEFAULT_CHAINS, DEFAULT_RPC_ENDPOINTS } from '@t402/wdk';
 
// Supported chains
// ['ethereum', 'arbitrum', 'base', 'optimism', 'polygon', 'ink', 'berachain', 'unichain']
 
// Default RPC endpoints (use your own for production)
// {
//   ethereum: 'https://eth.llamarpc.com',
//   arbitrum: 'https://arb1.arbitrum.io/rpc',
//   base: 'https://mainnet.base.org',
//   ...
// }

Token Addresses

import { USDT0_ADDRESSES, USDC_ADDRESSES, CHAIN_TOKENS } from '@t402/wdk';
 
// USDT0 on Arbitrum
const usdt0 = USDT0_ADDRESSES['arbitrum'];
 
// All tokens available on a chain
const tokens = CHAIN_TOKENS['base'];
// ['USDT0', 'USDC']

Utility Functions

import {
  getNetworkFromChain,
  getChainFromNetwork,
  getChainId,
  getUsdt0Chains,
  getPreferredToken
} from '@t402/wdk';
 
// Chain to CAIP-2 network
getNetworkFromChain('arbitrum'); // 'eip155:42161'
 
// CAIP-2 to chain name
getChainFromNetwork('eip155:8453'); // 'base'
 
// Get chain ID
getChainId('arbitrum'); // 42161
 
// Chains with USDT0
getUsdt0Chains(); // ['ethereum', 'arbitrum', 'base', ...]
 
// Get preferred token for chain
getPreferredToken('base'); // 'USDT0'

Caching

TTLCache

Generic TTL-based cache.

import { TTLCache } from '@t402/wdk';
 
const cache = new TTLCache<string>({
  ttl: 60000, // 1 minute
  maxSize: 100
});
 
cache.set('key', 'value');
const value = cache.get('key');

BalanceCache

Specialized cache for token balances.

import { BalanceCache, DEFAULT_BALANCE_CACHE_CONFIG } from '@t402/wdk';
 
const balanceCache = new BalanceCache(DEFAULT_BALANCE_CACHE_CONFIG);
 
// Cache balance
balanceCache.setBalance('arbitrum', '0x...', 'USDT0', 1000000n);
 
// Get cached balance
const balance = balanceCache.getBalance('arbitrum', '0x...', 'USDT0');
 
// Get stats
const stats = balanceCache.getStats();
console.log('Hit rate:', stats.hitRate);

Error Handling

Error Classes

import {
  WDKError,
  WDKInitializationError,
  ChainError,
  SignerError,
  SigningError,
  BalanceError,
  TransactionError,
  BridgeError,
  RPCError
} from '@t402/wdk';
 
try {
  await wallet.getUsdt0Balance('invalid-chain');
} catch (error) {
  if (error instanceof ChainError) {
    console.log('Chain not supported:', error.chain);
  }
}

Error Codes

import { WDKErrorCode, hasErrorCode } from '@t402/wdk';
 
// WDKErrorCode enum values:
// NOT_INITIALIZED, INVALID_SEED_PHRASE, CHAIN_NOT_CONFIGURED,
// SIGNER_NOT_AVAILABLE, SIGNING_FAILED, BALANCE_FETCH_FAILED,
// TRANSACTION_FAILED, BRIDGE_FAILED, RPC_ERROR
 
if (hasErrorCode(error, WDKErrorCode.BALANCE_FETCH_FAILED)) {
  // Handle balance fetch error
}

Utilities

import { wrapError, isWDKError, withRetry, withTimeout } from '@t402/wdk';
 
// Wrap unknown errors
const wdkError = wrapError(unknownError, WDKErrorCode.RPC_ERROR);
 
// Check if WDK error
if (isWDKError(error)) {
  console.log('Error code:', error.code);
}
 
// Retry with exponential backoff
const result = await withRetry(
  () => fetchBalance(),
  { maxRetries: 3, initialDelay: 1000 }
);
 
// Timeout wrapper
const result = await withTimeout(
  slowOperation(),
  5000 // 5 second timeout
);

Bridge Integration

WdkBridge

High-level bridge for WDK wallets.

import { WdkBridge } from '@t402/wdk';
 
const bridge = new WdkBridge(wallet, 'arbitrum');
 
// Get quote
const quote = await bridge.quote({
  toChain: 'base',
  amount: 50000000n
});
 
// Execute bridge
const result = await bridge.execute({
  toChain: 'base',
  amount: 50000000n
});

createDirectBridge

Create a bridge without full WDK wrapper.

import { createDirectBridge } from '@t402/wdk';
 
const bridge = createDirectBridge(signer, 'arbitrum');

Types

T402WDKConfig

interface T402WDKConfig {
  /** Seed phrase */
  seedPhrase: string;
 
  /** Chain RPC endpoints */
  chains: EvmChainConfig;
 
  /** Optional settings */
  options?: T402WDKOptions;
}

EvmChainConfig

type EvmChainConfig = {
  [chain: string]: string; // chain name -> RPC URL
};
 
// Example
const config: EvmChainConfig = {
  arbitrum: 'https://arb1.arbitrum.io/rpc',
  base: 'https://mainnet.base.org'
};

TokenBalance

interface TokenBalance {
  chain: string;
  token: string;
  balance: bigint;
  address: string;
}

AggregatedBalance

interface AggregatedBalance {
  totalUsdt0: bigint;
  totalUsdc: bigint;
  byChain: {
    [chain: string]: {
      usdt0: bigint;
      usdc: bigint;
    };
  };
}

BridgeParams

interface BridgeParams {
  fromChain: string;
  toChain: string;
  amount: bigint;
  recipient?: string; // Defaults to same address
}

BridgeResult

interface BridgeResult {
  txHash: string;
  messageGuid: string;
  fromChain: string;
  toChain: string;
  amount: bigint;
  estimatedTime: number;
}

Swap Integration (Velora)

Swap any ERC-20 token to USDT0 using Tether’s Velora protocol.

import SwapVeloraEvm from '@tetherto/wdk-protocol-swap-velora-evm';
 
T402WDK.registerWDK(WDK, {
  wallets: { evm: WalletManagerEvm },
  protocols: { swapVeloraEvm: SwapVeloraEvm },
});
 
const wallet = new T402WDK(seedPhrase, { arbitrum: '...' });
 
// Check availability
wallet.canSwap(); // true
 
// Get a quote
const quote = await wallet.getSwapQuote(
  'arbitrum',
  '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', // WETH
  100000000000000000n // 0.1 WETH
);
 
// Execute swap to USDT0
const result = await wallet.swapAndPay({
  chain: 'arbitrum',
  fromToken: '0x82aF...', // WETH
  amount: 100000000000000000n,
  maxSlippage: 0.005, // 0.5%
});

Version Compatibility

@tetherto/wdk Core

VersionStatusNotes
1.0.0-beta.3Tested
1.0.0-beta.4Tested+swapProtocol
1.0.0-beta.5TestedLatest tested

@tetherto/wdk-wallet-evm

VersionStatus
1.0.0-beta.5Tested
2.0.0-rc.1Tested

Wallet Module Minimum Versions

ModuleMin Version
wdk-wallet-evm1.0.0-beta.5
wdk-wallet-ton1.0.0-beta.7
wdk-wallet-solana1.0.0-beta.5
wdk-wallet-tron1.0.0-beta.4
wdk-wallet-btc1.0.0-beta.5
wdk-wallet-spark1.0.0-beta.6
import { checkWdkCompatibility, checkWalletEvmCompatibility } from '@t402/wdk';
 
const result = checkWdkCompatibility('1.0.0-beta.5');
if (!result.compatible) {
  console.error('Incompatible version');
}
result.warnings.forEach(w => console.warn(w));

Supported Chains

ChainUSDT0USDCBridge
EthereumYesYesYes
ArbitrumYesYesYes
BaseYesYesYes
OptimismYesYesNo
PolygonYesYesNo
InkYesNoYes
BerachainYesNoYes
UnichainYesNoYes