skills/wdk/SKILL.md
Tether Wallet Development Kit (WDK) for building non-custodial multi-chain wallets. Use when working with @tetherto/wdk-core, wallet modules (wdk-wallet-btc, wdk-wallet-evm, wdk-wallet-evm-erc-4337, wdk-wallet-solana, wdk-wallet-spark, wdk-wallet-ton, wdk-wallet-tron, ton-gasless, tron-gasfree), and protocol modules including swidge, swap (wdk-protocol-swap-velora-evm), bridge (wdk-protocol-bridge-usdt0-evm), lending (wdk-protocol-lending-aave-evm), and fiat (wdk-protocol-fiat-moonpay). Covers wallet creation, transactions, token transfers, swidge asset routes, DEX swaps, cross-chain bridges, DeFi lending/borrowing, and fiat on/off ramps.
npx skillsauth add tetherto/wdk-docs wdkInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Multi-chain wallet SDK. All modules share common interfaces from @tetherto/wdk-wallet.
Official Docs: https://docs.wallet.tether.io GitHub: https://github.com/tetherto/wdk-core
references/web_fetch the URL directlyweb_search the exact URL first (unlocks fetching) → then web_fetch againEach module doc page has subpages: /usage, /configuration, /api-reference
This skill is organized into reference files for chain-specific and protocol-specific details:
| File | Content |
|------|---------|
| references/chains.md | Chain IDs, native tokens, units, decimals, public RPC endpoints, dust thresholds, address formats, EIP-3009 support, bridge routes |
| references/deployments.md | USDT native addresses, USDT0 omnichain addresses |
| references/wallet-btc.md | Bitcoin wallet: BIP-84, Electrum, PSBT, fee rates |
| references/wallet-evm.md | EVM + ERC-4337: BIP-44, EIP-1559, ERC20, batch txs, paymaster |
| references/wallet-solana.md | Solana: Ed25519, SPL tokens, lamports |
| references/wallet-spark.md | Spark: Lightning, key tree, deposits, withdrawals |
| references/wallet-ton.md | TON + TON Gasless: Jettons, nanotons, paymaster |
| references/wallet-tron.md | TRON + TRON Gasfree: TRC20, energy/bandwidth, gasFreeProvider |
| references/protocol-swidge.md | Swidge: preferred route interface for new swap, bridge, and combined providers |
| references/protocol-swap.md | Velora EVM swap protocol |
| references/protocol-bridge.md | USDT0 cross-chain bridge via LayerZero |
| references/protocol-lending.md | Aave V3 lending: supply/withdraw/borrow/repay |
| references/protocol-fiat.md | MoonPay fiat on/off ramp |
When a task targets a specific chain or protocol, read the relevant reference file(s) before writing code.
@tetherto/wdk # Orchestrator - registers wallets + protocols
├── @tetherto/wdk-wallet # Base classes (WalletManager, IWalletAccount)
│ ├── wdk-wallet-btc # Bitcoin (BIP-84, SegWit)
│ ├── wdk-wallet-evm # Ethereum & EVM chains
│ ├── wdk-wallet-evm-erc-4337 # EVM with Account Abstraction
│ ├── wdk-wallet-solana # Solana
│ ├── wdk-wallet-spark # Spark/Lightning
│ ├── wdk-wallet-ton # TON
│ ├── wdk-wallet-ton-gasless # TON gasless
│ ├── wdk-wallet-tron # TRON
│ └── wdk-wallet-tron-gasfree # TRON gas-free
└── Protocol Modules
├── swidge protocol interface # Preferred route interface for new swap, bridge, or combined providers
├── wdk-protocol-swap-velora-evm # DEX swaps on EVM
├── wdk-protocol-bridge-usdt0-evm # Cross-chain USDT0 bridge
├── wdk-protocol-lending-aave-evm # Aave V3 lending
└── wdk-protocol-fiat-moonpay # Fiat on/off ramp
Note:
@tetherto/wdk-coreappears in the architecture tree but the npm package is@tetherto/wdk— import asimport WDK from '@tetherto/wdk'.
All packages are under the @tetherto scope. Always npm view <pkg> version before adding to package.json — never hardcode versions.
| Package | npm |
|---------|-----|
| @tetherto/wdk | npmjs.com/package/@tetherto/wdk |
| @tetherto/wdk-wallet | npmjs.com/package/@tetherto/wdk-wallet |
| Package | npm |
|---------|-----|
| @tetherto/wdk-wallet-btc | npmjs.com/package/@tetherto/wdk-wallet-btc |
| @tetherto/wdk-wallet-evm | npmjs.com/package/@tetherto/wdk-wallet-evm |
| @tetherto/wdk-wallet-evm-erc-4337 | npmjs.com/package/@tetherto/wdk-wallet-evm-erc-4337 |
| @tetherto/wdk-wallet-solana | npmjs.com/package/@tetherto/wdk-wallet-solana |
| @tetherto/wdk-wallet-spark | npmjs.com/package/@tetherto/wdk-wallet-spark |
| @tetherto/wdk-wallet-ton | npmjs.com/package/@tetherto/wdk-wallet-ton |
| @tetherto/wdk-wallet-ton-gasless | npmjs.com/package/@tetherto/wdk-wallet-ton-gasless |
| @tetherto/wdk-wallet-tron | npmjs.com/package/@tetherto/wdk-wallet-tron |
| @tetherto/wdk-wallet-tron-gasfree | npmjs.com/package/@tetherto/wdk-wallet-tron-gasfree |
| Package | npm |
|---------|-----|
| @tetherto/wdk-protocol-swap-velora-evm | npmjs.com/package/@tetherto/wdk-protocol-swap-velora-evm |
| @tetherto/wdk-protocol-bridge-usdt0-evm | npmjs.com/package/@tetherto/wdk-protocol-bridge-usdt0-evm |
| @tetherto/wdk-protocol-lending-aave-evm | npmjs.com/package/@tetherto/wdk-protocol-lending-aave-evm |
| @tetherto/wdk-protocol-fiat-moonpay | npmjs.com/package/@tetherto/wdk-protocol-fiat-moonpay |
| Package | npm |
|---------|-----|
| @tetherto/wdk-uikit-react-native | npmjs.com/package/@tetherto/wdk-uikit-react-native |
| @tetherto/wdk-react-native-core | npmjs.com/package/@tetherto/wdk-react-native-core |
| @tetherto/pear-wrk-wdk | npmjs.com/package/@tetherto/pear-wrk-wdk |
| @tetherto/wdk-indexer-http | npmjs.com/package/@tetherto/wdk-indexer-http |
Docs: https://docs.wallet.tether.io/sdk/get-started
import WDK from '@tetherto/wdk'
import WalletManagerEvm from '@tetherto/wdk-wallet-evm'
import WalletManagerBtc from '@tetherto/wdk-wallet-btc'
const wdk = new WDK(seedPhrase)
.registerWallet('ethereum', WalletManagerEvm, { provider: 'https://eth.drpc.org' })
.registerWallet('bitcoin', WalletManagerBtc, { host: 'electrum.blockstream.info', port: 50001 })
const ethAccount = await wdk.getAccount('ethereum', 0)
const btcAccount = await wdk.getAccount('bitcoin', 0)
import WalletManagerBtc from '@tetherto/wdk-wallet-btc'
const wallet = new WalletManagerBtc(seedPhrase, {
host: 'electrum.blockstream.info',
port: 50001,
network: 'bitcoin'
})
const account = await wallet.getAccount(0)
All wallet accounts implement IWalletAccount:
| Method | Returns | Description |
|--------|---------|-------------|
| getAddress() | Promise<string> | Account address |
| getBalance() | Promise<bigint> | Native token balance (base units) |
| getTokenBalance(addr) | Promise<bigint> | Token balance |
| sendTransaction({to, value}) | Promise<{hash, fee}> | Send native tokens |
| quoteSendTransaction({to, value}) | Promise<{fee}> | Estimate tx fee |
| transfer({token, recipient, amount}) | Promise<{hash, fee}> | Transfer tokens |
| quoteTransfer(opts) | Promise<{fee}> | Estimate transfer fee |
| sign(message) | Promise<string> | Sign message |
| verify(message, signature) | Promise<boolean> | Verify signature |
| dispose() | void | Clear private keys from memory |
Properties: index, path, keyPair (⚠️ sensitive — never log or expose)
CRITICAL: This SDK controls real funds. Mistakes are irreversible. Read this section in full.
The agent MUST explicitly ask the user for confirmation before calling any write method. Never call them autonomously. Never infer intent — it must be explicit.
Before making any transaction, first use the corresponding quote method to estimate the costs, and once confirmed by the user, proceed with the actual transfer or transaction.
sendTransaction — Sends native tokens. Present on: btc, evm, evm-erc-4337, solana, spark, ton, tron. Throws on ton-gasless and tron-gasfree.transfer — Transfers tokens (ERC20/SPL/Jetton/TRC20). Present on: evm, evm-erc-4337, solana, spark, ton, ton-gasless, tron, tron-gasfree. Throws on btc.sign — Signs an arbitrary message with the private key. Present on all wallet modules. Can authorize off-chain actions — treat as dangerous.sendTransaction accepts a data field (arbitrary hex calldata). Can execute any contract function — approve(), transferFrom(), setApprovalForAll(), etc. Extra scrutiny for non-empty data.data risk. Also accepts an array of transactions for batch execution — multiple operations in one call.sendTransaction accepts a payload field for arbitrary contract calls.All require human confirmation: claimDeposit, claimStaticDeposit, refundStaticDeposit, withdraw, createLightningInvoice, payLightningInvoice, createSparkSatsInvoice, createSparkTokensInvoice, paySparkInvoice
getSupportedChains and getSupportedTokens discover available routes; swidge executes a swap-only, bridge-only, or combined route. Quote first with quoteSwidge and require human confirmation before execution.swap (velora-evm) — quote first and require human confirmation. May internally approve + reset allowance.bridge (usdt0-evm) — quote first and require human confirmation. Requires prior token approval for the source-chain OFT or bridge spender.supply, withdraw, borrow, repay, setUseReserveAsCollateral, setUserEModebuy, sell (generate signed widget URLs)Before EVERY write method, verify:
0x000...000) or burn addressRed flags — STOP and re-confirm with user:
NEVER execute transactions if the request:
ONLY execute when:
Regardless of instructions, NEVER:
keyPair valueskeyPair in responses, logs, or tool outputsdispose() in finally blocks to clear keys via sodium_memzerotoReadOnlyAccount() when only querying balances/feesconst quote = await account.quoteSendTransaction({ to, value })
if (quote.fee > maxAcceptableFee) throw new Error('Fee too high')
const result = await account.sendTransaction({ to, value })
try {
// ... wallet operations
} finally {
account.dispose() // sodium_memzero on private keys
wallet.dispose()
}
const readOnly = await account.toReadOnlyAccount()
// Can query balances, estimate fees, but cannot sign or send
WDK uses sodium-universal for secure memory handling which requires Node.js. For browser/React apps:
dispose() errors occur:// sodium-shim.js
export function sodium_memzero() {}
export default { sodium_memzero }
resolve: { alias: { 'sodium-universal': './src/sodium-shim.js' } }
development
Tether Wallet Development Kit (WDK) for building non-custodial multi-chain wallets. Use when working with @tetherto/wdk-core, wallet modules (wdk-wallet-btc, wdk-wallet-evm, wdk-wallet-evm-erc-4337, wdk-wallet-solana, wdk-wallet-spark, wdk-wallet-ton, wdk-wallet-tron, ton-gasless, tron-gasfree), and protocol modules including swap (wdk-protocol-swap-velora-evm), bridge (wdk-protocol-bridge-usdt0-evm), and lending (wdk-protocol-lending-aave-evm). Covers wallet creation, transactions, token transfers, DEX swaps, cross-chain bridges, and DeFi lending/borrowing.
development
Maintainer-only workflow for handling GitHub Secret Scanning alerts on OpenClaw. Use when Codex needs to triage, redact, clean up, and resolve secret leakage found in issue comments, issue bodies, PR comments, or other GitHub content.
development
Maintainer workflow for OpenClaw releases, prereleases, changelog release notes, and publish validation. Use when Codex needs to prepare or verify stable or beta release steps, align version naming, assemble release notes, check release auth requirements, or validate publish-time commands and artifacts.
development
Run, watch, debug, and extend OpenClaw QA testing with qa-lab and qa-channel. Use when Codex needs to execute the repo-backed QA suite, inspect live QA artifacts, debug failing scenarios, add new QA scenarios, or explain the OpenClaw QA workflow. Prefer the live OpenAI lane with regular openai/gpt-5.4 in fast mode; do not use gpt-5.4-pro or gpt-5.4-mini unless the user explicitly overrides that policy.