{"id":51915720,"url":"https://github.com/tetherto/wdk-cli","last_synced_at":"2026-07-27T10:01:27.732Z","repository":{"id":370132140,"uuid":"1228761142","full_name":"tetherto/wdk-cli","owner":"tetherto","description":null,"archived":false,"fork":false,"pushed_at":"2026-07-08T08:16:17.000Z","size":882,"stargazers_count":0,"open_issues_count":1,"forks_count":3,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-08T10:08:01.469Z","etag":null,"topics":["cli","wdk"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tetherto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-04T10:54:40.000Z","updated_at":"2026-07-08T08:16:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tetherto/wdk-cli","commit_stats":null,"previous_names":["tetherto/wdk-cli"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/tetherto/wdk-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetherto%2Fwdk-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetherto%2Fwdk-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetherto%2Fwdk-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetherto%2Fwdk-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tetherto","download_url":"https://codeload.github.com/tetherto/wdk-cli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetherto%2Fwdk-cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35947061,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-27T02:00:06.776Z","response_time":101,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","wdk"],"created_at":"2026-07-27T10:01:27.072Z","updated_at":"2026-07-27T10:01:27.708Z","avatar_url":"https://github.com/tetherto.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @tetherto/wdk-cli\n\n[![npm version](https://img.shields.io/npm/v/%40tetherto%2Fwdk-cli?style=flat-square)](https://www.npmjs.com/package/@tetherto/wdk-cli)\n[![npm downloads](https://img.shields.io/npm/dw/%40tetherto%2Fwdk-cli?style=flat-square)](https://www.npmjs.com/package/@tetherto/wdk-cli)\n[![license](https://img.shields.io/npm/l/%40tetherto%2Fwdk-cli?style=flat-square)](https://github.com/tetherto/wdk-cli/blob/main/LICENSE)\n\nA multi-chain crypto wallet for AI agents, built on [Wallet Development Kit (WDK)](https://wallet.tether.io/). Designed to be operated by AI agents (e.g. Claude, ChatGPT, OpenClaw).\n\n\u003e **AI agents:** see [`SKILL.md`](./SKILL.md) for the complete operational guide — commands, workflows, error handling, and safety rules.\n\n## Architecture\n\n```\n┌───────────┐        ┌───────────────────────────────────┐\n│  wdk-cli  │──IPC──▶│          wdk-daemon               │\n│  (CLI)    │        │        (wallet daemon)             │\n└───────────┘        │                                   │\n                     │  Holds WDK instances in memory    │\n┌───────────┐        │  Handles all crypto operations:   │\n│  wdk-mcp  │──IPC──▶│  derivation, signing, balances    │\n│  (MCP)    │        │  Auto-locks after TTL expires     │\n└───────────┘        │                                   │\n                     │  Signs tx locally, then submits   │\n                     └───────────┬───────────────────────┘\n                                 │\n                                 │  submits signed tx\n                                 ▼\n                          ┌──────────────┐\n                          │  Blockchain  │\n                          │   (RPC/P2P)  │\n                          └──────────────┘\n```\n\n**wdk-daemon** (Wallet Daemon):\n- Starts empty — wallets unlocked individually via socket requests\n- Holds WDK instances in memory — owns all cryptographic operations\n- Listens on a Unix socket (`daemon.sock`, 0600 permissions)\n- Exposes: `unlock_wallet`, `lock_wallet`, `get_address`, `get_balance`, `estimate_fee`, `send`, `list_wallets`, `status`, `lock`\n- Per-wallet TTL — each wallet has its own timeout (default: 5 min, `--ttl 0` for unlimited)\n- Auto-exits when last wallet is locked\n\n**wdk-cli** (CLI):\n- Thin client — no crypto, no keys\n- Parses user commands, sends requests to daemon, formats and displays results\n- Only interface for passphrase-protected operations: unlock wallet, export seed, delete wallet\n\n**wdk-mcp** (MCP Server):\n- Thin client — no crypto, no keys\n- Exposes structured wallet tools to AI agents via [Model Context Protocol](https://modelcontextprotocol.io/)\n- Routes all operations through the daemon\n\n## Features\n\n- **Wallet** — Multiple named wallets with per-wallet passphrases and BIP-39 seed phrases, encrypted at rest with AES-256-GCM. Background daemon holds keys in memory after unlock, with per-wallet TTL\n- **Network** — Bitcoin, Ethereum, Polygon, Arbitrum, Base, BSC, Avalanche, Solana, Tron, Spark, Smart Account (ERC-4337) + testnets. Add custom networks with `network create`\n- **Token** — Built-in registry of tokens per network (symbol, decimals, address, indexer/MoonPay/Bitfinex mappings). Add your own with `token add`\n- **Get** — Derive wallet addresses, check balances, and view transaction history across all networks\n- **Send** — Native and token transfers with fee estimation and dry-run preview. Decimal amounts by default\n- **Buy/Sell** — On/off ramp via MoonPay (buy crypto with fiat, sell crypto for fiat)\n- **Config** — Per-network configuration with env var overrides\n\n## Requirements\n\n- Node.js \u003e= 22.18.0\n\n## Install\n\n```bash\nnpm install -g @tetherto/wdk-cli\n```\n\nFrom source:\n\n```bash\ngit clone https://github.com/tetherto/wdk-cli.git\ncd wdk-cli\nnpm install\nnpm link  # makes `wdk` available globally\n```\n\n## Quick Start\n\n```bash\n# Create wallets (each has its own passphrase)\nwdk wallet create --name trading --words 24\nwdk wallet create --name savings --words 12\n\n# List all wallets\nwdk wallet list\n\n# Unlock wallets individually (starts daemon on first unlock)\nwdk wallet unlock --name trading --ttl 0      # unlimited session\nwdk wallet unlock --name savings --ttl 60     # 60 min session\n\n# Set default wallet\nwdk wallet default --name trading\n\n# Get all wallet addresses across networks\nwdk get address --all\n\n# Get address for a specific network\nwdk get address --network ethereum\n\n# Use a specific wallet\nwdk get address --network ethereum --wallet trading\n\n# Check all balances across networks (with USD totals)\nwdk get balance --all\n\n# Check balance for a specific wallet\nwdk get balance --all --wallet savings\n\n# Send 1.23456 ETH (decimal default; add --base-units to send in wei)\nwdk send --to 0x000000000000000000000000000000000000dEaD --amount 1.23456 --network ethereum\n\n# Send 100.5 USDT (registered token ticker — see `wdk token list`)\nwdk send --to 0x... --amount 100.5 --token usdt --network ethereum --wallet trading\n\n# Show network details and config\nwdk network info --network ethereum\n\n# List supported networks\nwdk network list\n\n# Lock a single wallet\nwdk wallet lock --name trading\n\n# Lock all wallets when done\nwdk wallet lock --all\n```\n\n## Commands\n\n### Wallet\n\nWallet commands that require passphrase input (create, import, unlock, export, delete) are interactive by default. Set `WDK_PASSPHRASE` env var to skip the interactive prompt for automation and `--json` output.\n\n```bash\nwdk wallet create --name \u003cname\u003e [--words 12|24]       # Create a new wallet with a generated seed phrase\nwdk wallet import --name \u003cname\u003e                       # Import a wallet from an existing seed phrase\nwdk wallet export --name \u003cname\u003e                       # Display the seed phrase of an existing wallet\nwdk wallet list                                       # List all wallets with lock/default status\nwdk wallet unlock --name \u003cname\u003e [--ttl \u003cminutes\u003e]     # Unlock a wallet for signing transactions\nwdk wallet lock --name \u003cname\u003e                         # Lock a single wallet\nwdk wallet lock --all                                 # Lock all wallets (stops daemon)\nwdk wallet delete --name \u003cname\u003e                       # Delete a wallet (requires passphrase)\nwdk wallet default --name \u003cname\u003e                      # Set the default wallet\nwdk wallet rename --name \u003cold\u003e --new-name \u003cnew\u003e       # Rename a wallet\n```\n\nSupports **multiple named wallets** with **per-wallet passphrases**. Each wallet is stored as `~/.config/wdk-cli/wallets/\u003cname\u003e/seed.enc`. The first wallet created is auto-set as default. Use `--wallet \u003cname\u003e` on other commands to target a specific wallet (defaults to the default wallet).\n\nPassphrase is optional (empty for none). If provided, it encrypts the seed phrase with AES-256-GCM + scrypt.\n\n`wdk wallet unlock` unlocks a single wallet and starts the daemon if not running. Each wallet has its own TTL — use `--ttl 0` for unlimited session, ideal for AI agent environments. The daemon auto-exits when the last wallet is locked.\n\n### Networks\n\n```bash\nwdk network list              # List all networks (built-in + custom)\nwdk network list --testnet    # Show only testnets\nwdk network list --mainnet    # Show only mainnets\nwdk network info --network \u003cnetwork\u003e  # Show network details and config\nwdk network delete --name \u003cname\u003e      # Delete a custom network (requires unlocked wallet)\n```\n\n#### Adding Custom Networks\n\n`wdk network create \u003cdata\u003e` takes a single argument — either an inline JSON string or a path to a JSON file. Requires an unlocked wallet.\n\n```bash\n# Inline JSON\nwdk network create '{\"network\":\"optimism\",\"module\":\"@tetherto/wdk-wallet-evm\",\"indexerSlug\":\"ethereum\",\"config\":{\"provider\":\"https://mainnet.optimism.io\",\"chainId\":10}}'\n\n# Or from a file\nwdk network create ./optimism.json\n```\n\nExample spec file:\n\n```json\n{\n  \"network\": \"optimism\",\n  \"module\": \"@tetherto/wdk-wallet-evm\",\n  \"displayName\": \"Optimism\",\n  \"testnet\": false,\n  \"indexerSlug\": \"ethereum\",\n  \"config\": { \"provider\": \"https://mainnet.optimism.io\", \"chainId\": 10 },\n  \"tokens\": [\n    {\n      \"token\": \"eth\",\n      \"symbol\": \"ETH\",\n      \"decimals\": 18,\n      \"isNative\": true,\n      \"metadata\": { \"moonpaySlug\": \"eth\", \"bitfinexSlug\": \"tETHUSD\" }\n    },\n    {\n      \"token\": \"usdt\",\n      \"symbol\": \"USDT\",\n      \"decimals\": 6,\n      \"isNative\": false,\n      \"address\": \"0x...\",\n      \"metadata\": { \"indexerSlug\": \"usdt\", \"moonpaySlug\": \"usdt\", \"bitfinexSlug\": \"tUSTUSD\" }\n    }\n  ]\n}\n```\n\n**Spec fields:**\n\n| Field | Required | Description |\n|-------|----------|-------------|\n| `network` | Yes | Network identifier (lowercase, hyphens allowed) |\n| `module` | Yes | Wallet module: `@tetherto/wdk-wallet-evm`, `@tetherto/wdk-wallet-btc`, `@tetherto/wdk-wallet-solana`, `@tetherto/wdk-wallet-spark`, `@tetherto/wdk-wallet-tron`, `@tetherto/wdk-wallet-evm-erc-4337` |\n| `displayName` | No | Human-readable name (defaults to `network`) |\n| `testnet` | No | `true` to mark as a testnet |\n| `indexerSlug` | Required for indexer support | Chain slug used by the WDK indexer API (e.g. `ethereum`, `polygon`, `bitcoin`). If omitted, the indexer is disabled for this network and `wdk get history` will error with `NETWORK_NOT_SUPPORTED`. For most networks the slug equals the network name; smart-account / forked networks point at the underlying chain (e.g. `smart-account-ethereum` uses `\"indexerSlug\": \"ethereum\"`). |\n| `config` | No | SDK config object (provider URL, chainId, etc.). May be set later via `wdk config set --network \u003cname\u003e`. |\n| `tokens` | No | Token registry entries to register atomically with the network. At most one entry may have `isNative: true`. Each entry's shape matches the [Tokens](#tokens) spec. |\n\nThe spec is parsed and validated atomically: if any token in `tokens[]` fails validation, the network is not created (full rollback). Unknown top-level fields pass through silently (so you can annotate specs with comments, tags, owner, etc.).\n\nDeleting a custom network (`wdk network delete --name \u003cn\u003e`) also removes its registered tokens.\n\n### Tokens\n\nThe CLI ships with a registry (`wdk.tokens.json`) of all known tokens per network — symbol, decimals, contract address, and provider mappings (indexer code, MoonPay asset code, Bitfinex pair). The `--token` flag on `get balance` / `send` / `get history` / `buy` / `sell` resolves against this registry.\n\n```bash\nwdk token list                                                 # All tokens, grouped by network\nwdk token list --network ethereum                              # Filter to one network\nwdk token info --network ethereum --token usdt                 # Show full entry\n\n# Add a token from inline JSON or a file\nwdk token add '{\"network\":\"ethereum\",\"token\":\"dai\",\"symbol\":\"DAI\",\"decimals\":18,\"isNative\":false,\"address\":\"0x...\"}'\nwdk token add ./dai-on-ethereum.json\n\nwdk token delete --network \u003cn\u003e --token \u003ct\u003e                     # Remove a custom entry\n```\n\n`wdk token add \u003cdata\u003e` takes a single argument — inline JSON or a path to a JSON file.\n\n**Token entry fields — and why each one is needed:**\n\n| Field | Required | What the CLI does with it |\n|-------|----------|---------------------------|\n| `network` | Yes | Parent network the token belongs to. Must already exist. |\n| `token` | Yes | Registry key (lowercased) used by `--token \u003cticker\u003e` flags across the CLI. |\n| `symbol` | Yes | Display label shown in `get balance`, `send` previews, fee lines, and tables (e.g. `1.5 ETH`, `100 USDT`). |\n| `decimals` | Yes | Used to convert between the CLI's decimal `--amount` (e.g. `1.5`) and the SDK's base units (wei / satoshi / lamport). Integer 0–24. |\n| `isNative` | Yes | Routes transfers through the native-coin path (no contract call) vs the token-contract path. Each network can have **at most one** native entry. |\n| `address` | If `!isNative` | Contract / mint address used by the SDK to call `transfer` / `getBalance` on the right token. Required for ERC-20 / SPL / TRC-20; omit for native. |\n| `metadata.indexerSlug` | No | Asset slug sent to the WDK indexer (`/api/v1/{chain}/{indexerSlug}/{addr}/token-transfers`). Without it, this token is skipped by `wdk get history`. **Requires the network to also have `indexerSlug` set** — a token slug alone doesn't enable the indexer; the network's `indexerSlug` is what tells the CLI the indexer is available for that chain. |\n| `metadata.moonpaySlug` | No | MoonPay asset code used in the buy/sell URL. Without it, `wdk buy`/`wdk sell` rejects the token. |\n| `metadata.bitfinexSlug` | No | Bitfinex pair symbol used to fetch a USD price. Without it, `wdk get balance` shows the balance but no USD column for that token. |\n\nProvider mappings (`metadata.*Slug`) are all optional. Omit them when the integration doesn't apply — the rest of the CLI keeps working; only the specific feature is disabled for that token. Unknown top-level fields pass through silently so you can annotate entries with comments, tags, owner, etc.\n\nExample full entry (file or inline):\n\n```json\n{\n  \"network\": \"optimism\",\n  \"token\": \"usdt\",\n  \"symbol\": \"USDT\",\n  \"decimals\": 6,\n  \"isNative\": false,\n  \"address\": \"0x...\",\n  \"metadata\": {\n    \"indexerSlug\": \"usdt\",\n    \"moonpaySlug\": \"usdt\",\n    \"bitfinexSlug\": \"tUSTUSD\"\n  }\n}\n```\n\nCustom entries (added via `token add`) live under `customTokens.\u003cnetwork\u003e.\u003cticker\u003e` and survive `wdk config reset --all`. Built-in entries can be **overridden** by adding a custom entry with the same ticker — a yellow warning is shown when this happens. `token delete` only removes custom entries; the built-in falls through after deletion.\n\n### Get\n\n```bash\nwdk get address --network \u003cnetwork\u003e [--index \u003cn\u003e]              # Derive wallet address\nwdk get address --all                                           # All mainnet addresses\nwdk get address --all --testnet                                 # All addresses incl. testnets\nwdk get balance --network ethereum                              # Native ETH balance\nwdk get balance --network ethereum --token usdt                 # ERC-20 by registered ticker\nwdk get balance --all                                           # All mainnet balances with USD\nwdk get balance --all --testnet                                 # All balances incl. testnets\nwdk get history --network ethereum                                              # All supported tokens\nwdk get history --network ethereum --token xaut --limit 50                      # XAUT transfers, last 50\nwdk get history --network ethereum --from-date 2026-01-01 --to-date 2026-03-31  # Date range filter\n```\n\n`--token` accepts a registered token ticker (e.g. `usdt`, `eth`, `xaut`). See `wdk token list` for available tokens. Use `wdk token add` to register a new token.\n\nWallets are derived deterministically from your seed phrase using HD paths (BIP-84 for BTC, BIP-44 for EVM/Solana) — no local state is stored. `get address` works without a provider configured (local derivation only), while `get balance` requires a provider connection.\n\n`get history` uses the [WDK Indexer API](https://github.com/tetherto/wdk-indexer-http). Configure with `WDK_INDEXER_BASE_URL` / `WDK_INDEXER_API_KEY` env vars, or use `wdk config set` for `indexer.baseUrl` and `indexer.apiKey`. If using a proxy provider that includes the API key, only the base URL is needed.\n\n### Send\n\n```bash\nwdk send --to \u003caddress\u003e --amount \u003cdecimal\u003e --network \u003cnetwork\u003e                     # Native (decimal, e.g. 1.5)\nwdk send --to \u003caddress\u003e --amount \u003cdecimal\u003e --token \u003cticker\u003e --network ethereum     # ERC-20 by registered ticker\nwdk send --to \u003caddress\u003e --amount \u003cdecimal\u003e --token \u003cticker\u003e --network solana       # SPL by registered ticker\nwdk send --to \u003caddress\u003e --amount \u003cbaseUnits\u003e --base-units --network ethereum       # Opt-in: raw base units\nwdk send --to \u003caddress\u003e --amount \u003cdecimal\u003e --network ethereum --dry-run            # preview without sending\n```\n\n`--amount` is decimal by default (e.g. `1.5` for 1.5 ETH, `0.001` for 0.001 BTC, `1.23456789012345678` for full 18-decimal ETH precision). The CLI converts using the token's registered decimals. If the value has more decimal places than the token allows (e.g. `1.12345678` with 6-decimal USDT), it's rejected with `INVALID_AMOUNT`. Pass `--base-units` to interpret the value as raw base units (wei/satoshi/lamport) — useful for scripts that already have BigInt amounts. Fee estimation runs before confirmation; use `--dry-run` to preview the transaction with fee and USD estimates without sending.\n\n### Buy / Sell (On/Off Ramp)\n\n```bash\n# Buy crypto with fiat\nwdk buy --network ethereum --token usdt                          # Opens MoonPay widget\nwdk buy --network ethereum --token eth --fiat-amount 100         # Buy $100 of ETH\nwdk buy --network bitcoin --token btc --crypto-amount 0.05       # Buy 0.05 BTC\n\n# Sell crypto for fiat\nwdk sell --network ethereum --token usdt                         # Opens MoonPay sell widget\nwdk sell --network ethereum --token eth --fiat-amount 200        # Sell ETH for $200\nwdk sell --network polygon --token usdt --crypto-amount 50       # Sell 50 USDT on Polygon\n```\n\nUses MoonPay as the fiat provider. All three config values are required:\n\n```bash\nwdk config set --key ramp.moonpay.apiKey --value \u003cyour-publishable-key\u003e\nwdk config set --key ramp.moonpay.signUrl --value \u003cyour-sign-url\u003e\nwdk config set --key ramp.moonpay.environment --value sandbox    # or production\n```\n\n**Options:**\n\n| Flag | Description |\n|------|-------------|\n| `--network \u003cnetwork\u003e` | Blockchain network (required) |\n| `--token \u003ctoken\u003e` | Crypto asset code, e.g. `usdt`, `eth`, `btc` (required) |\n| `--module \u003cmodule\u003e` | Fiat provider (default: `moonpay`) |\n| `--fiat-currency \u003ccurrency\u003e` | Fiat currency code (default: `usd`) |\n| `--fiat-amount \u003cvalue\u003e` | Fiat amount (mutually exclusive with `--crypto-amount`) |\n| `--crypto-amount \u003cvalue\u003e` | Crypto amount (mutually exclusive with `--fiat-amount`) |\n\nSupported tokens are derived from the registry — any token with `metadata.moonpaySlug` set in `wdk.tokens.json` (or a custom token added via `wdk token add`). Environment validation prevents using production MoonPay with testnet networks (and vice versa).\n\nConfigure via `wdk config set --key ramp.moonpay.apiKey --value \u003ckey\u003e`, `ramp.moonpay.signUrl`, and `ramp.moonpay.environment`.\n\n### Configuration\n\nConfig read commands (`get`, `path`) work without a wallet. Write operations (`set`, `reset`) require an unlocked wallet. All config commands support `--json`.\n\n```bash\n# Get\nwdk config get --all                                            # Show all config\nwdk config get --key ramp.moonpay.apiKey                        # Show a specific value\nwdk config get --network ethereum                               # Show Ethereum config\nwdk config get --key provider --network ethereum                # Show a network-specific value\n\n# Set\nwdk config set --key ramp.moonpay.apiKey --value pk_test_...    # Set a value\nwdk config set --key provider --value \u003crpc-url\u003e --network ethereum              # Network-scoped value\nwdk config set --key ramp.moonpay --value '{\"apiKey\":\"...\",\"signUrl\":\"...\",\"environment\":\"sandbox\"}'  # JSON object\nwdk config set --value '{\"provider\":\"https://...\",\"transferMaxFee\":5000}' --network optimism    # Full network config\n\n# Reset\nwdk config reset --key provider --network ethereum              # Reset a key to default\nwdk config reset --all                                          # Reset everything to factory defaults\n                                                                # (preserves defaultWallet, customNetworks, customTokens)\n\n# Path\nwdk config path                                                 # Config file path\n```\n\nValues passed to `--value` support JSON — objects and arrays are parsed and stored as structured data. Use `--network` to scope config to a specific network. When `--key` is omitted with `--network`, the entire network config is set.\n\nNetwork configuration is passed directly to the wallet SDK. Refer to each [wallet module's documentation](https://docs.wdk.tether.io/sdk/wallet-modules) for supported config keys. Default values are in [`wdk.config.json`](wdk.config.json).\n\n### Global Flags\n\n| Flag | Description |\n|------|-------------|\n| `--index \u003cn\u003e` | Account index (default: 0) |\n| `--wallet \u003cname\u003e` | Wallet name (uses default wallet if omitted) |\n| `--json` | Machine-readable JSON output |\n| `--verbose` | Debug logging |\n\n## Supported Networks\n\nAll built-in networks are defined in [`wdk.config.json`](wdk.config.json). Run `wdk network list` to see all available networks.\n\nAdditional networks can be added with `wdk network create`. See [Adding Custom Networks](#adding-custom-networks).\n\n## Non-Interactive Mode\n\nAll commands support `--json` for machine-parseable output. Commands that require passphrase input (wallet create, import, unlock, export, delete, and config set/reset) can be run non-interactively by setting the `WDK_PASSPHRASE` environment variable.\n\n```bash\n# CI/CD: create and unlock a wallet without interactive prompts\nWDK_PASSPHRASE=mypass wdk wallet create --name ci-wallet --json\nWDK_PASSPHRASE=mypass wdk wallet unlock --name ci-wallet --ttl 0 --json\n\n# Docker: unlock at container start\nWDK_PASSPHRASE=$WALLET_PASS wdk wallet unlock --name default --ttl 0 --json\n\n# Scripting: check balance and parse output\nwdk get balance --network ethereum --json | jq '.balance'\n```\n\n## Environment Variables\n\n| Variable | Description |\n|----------|-------------|\n| `WDK_PASSPHRASE` | Wallet passphrase (skip interactive prompt) |\n| `WDK_INDEXER_API_KEY` | Indexer API key (avoids storing secrets in config file) |\n\n## Security\n\n- Seed phrases encrypted at rest (AES-256-GCM + scrypt), per-wallet passphrases with unique salt per wallet\n- Seeds and passphrases never accepted as CLI arguments\n- Private keys and seeds never leave the daemon process\n- Unix socket with 0600 permissions (same-user access only, like ssh-agent)\n- No telemetry, no analytics, no external data collection\n\n### Data flow\n\n1. **Unlock**: User unlocks a wallet by name → passphrase sent to daemon over Unix socket → daemon decrypts seed via scrypt + AES-256-GCM → initializes WDK instance in RAM → starts per-wallet TTL timer\n2. **Request**: CLI/MCP sends operation (e.g. `get_address`) with wallet name over Unix socket → daemon performs crypto operation → returns result only\n3. **Lock**: Individual wallet locked → WDK instance disposed and cleared. When last wallet locks → daemon exits\n\n### Encrypted wallet files\n\nEach wallet is stored in its own directory as `~/.config/wdk-cli/wallets/\u003cname\u003e/seed.enc`:\n\n```json\n{ \"version\": 1, \"salt\": \"...\", \"iv\": \"...\", \"tag\": \"...\", \"ciphertext\": \"...\" }\n```\n\nPer-wallet passphrase with unique random salt → unique derived key per wallet.\n\n## AI Agent Integration\n\nAI agents interact with wdk-wallet in two ways, depending on their environment:\n\n### MCP — for sandboxed AI models\n\nFor AI models that run as applications with limited system access (Claude Desktop, OpenClaw, etc.). The model can only interact with the wallet through structured MCP tools — it cannot run commands or access the filesystem.\n\n```bash\nwdk mcp setup --ai-tool claude-desktop    # Configure for Claude Desktop\nwdk mcp setup --ai-tool claude-code       # Configure for Claude Code\nwdk mcp setup --ai-tool openclaw          # Configure for OpenClaw\n\nwdk mcp remove --ai-tool claude-desktop   # Remove configuration\nwdk mcp verify-setup --ai-tool claude-code # Verify config and test MCP server\nwdk mcp list                               # Show status across all AI tools\n```\n\nSetup auto-detects the Node.js path, validates the MCP server, and writes the config. For Claude Code and OpenClaw, it uses their native CLI (`claude mcp add`, `openclaw mcp set`). For Claude Desktop, it writes the config file directly.\n\n**MCP Tools:**\n\n| Tool | Parameters | Description |\n|------|-----------|-------------|\n| `get_networks` | `testnet?`, `mainnet?` | List all supported blockchain networks |\n| `list_tokens` | `network?` | List registered tokens (omit network for every network) |\n| `get_token` | `network`, `token` | Get a single registered token entry (symbol, decimals, address, provider mappings) |\n| `get_address` | `network?`, `index?`, `testnet?`, `wallet?` | Get wallet address (omit network for all) |\n| `get_balance` | `network?`, `token?`, `index?`, `testnet?`, `wallet?` | Get balance with USD values (omit network for all). `token` is a registered ticker. |\n| `get_history` | `network`, `token?`, `limit?`, `index?`, `fromDate?`, `toDate?`, `wallet?` | Transaction history (requires indexer API) |\n| `send_token` | `to`, `amount`, `baseUnits?`, `network`, `token?`, `index?`, `dryRun?`, `wallet?` | Send tokens. `amount` is decimal by default; set `baseUnits=true` to interpret as base units. Returns dry-run preview by default; set `dryRun=false` to execute |\n| `buy_crypto` | `network`, `token`, `fiatCurrency?`, `fiatAmount?`, `cryptoAmount?`, `index?`, `wallet?` | Buy crypto with fiat. Returns a signed MoonPay URL. |\n| `sell_crypto` | `network`, `token`, `fiatCurrency?`, `fiatAmount?`, `cryptoAmount?`, `index?`, `wallet?` | Sell crypto for fiat. Returns a signed MoonPay URL. |\n\nAll wallet-dependent tools accept an optional `wallet` parameter (uses default wallet if omitted).\n\n**Important: `send_token` requires two calls.** The tool defaults to `dryRun=true` (preview mode). AI agents must:\n1. Call `send_token` first to get a fee/amount preview\n2. Show the preview to the user and wait for confirmation\n3. Call `send_token` again with `dryRun=false` only after the user confirms\n\nThe AI model interacts exclusively through these structured tools — it cannot run shell commands, access the filesystem, or read private keys. All operations route through the daemon over a Unix socket.\n\n### CLI — for local AI agents\n\nFor AI agents with full system access (Claude Code, OpenClaw, custom agents). The agent runs `wdk` commands directly with `--json` for machine-parseable output.\n\n```bash\nwdk get balance --network ethereum --json\nwdk send --to 0xRECIPIENT --amount 1.23456 --network ethereum --dry-run --json   # decimal accepted (up to token precision)\nwdk send --to 0xRECIPIENT --amount 100.5 --token usdt --network ethereum --json  # decimal USDT by ticker\n```\n\nThe `SKILL.md` file contains complete instructions for AI agents — commands, workflows, error handling, and amount conversions. Feed it as context to your agent.\n\n### Before using either mode\n\nCreate and unlock wallets first:\n```bash\nwdk wallet create --name default --words 24\nwdk wallet unlock --name default --ttl 0\n```\n\nBoth MCP and CLI route through the daemon — the agent never has access to keys or seeds.\n\n## Development\n\n```bash\nnpm test                  # Run unit tests\nnpm run test:integration  # Run integration tests (spawns CLI in isolated temp dir)\nnpm run format            # Format with Prettier\nnpm run format:check      # Check formatting\n```\n\nThis project is plain JavaScript (ESM) — no build step. Source under `src/` is run directly via the `bin/*.mjs` entry points.\n\n## License\n\nThis project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## Support\n\nFor support, please open an issue on the GitHub repository.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftetherto%2Fwdk-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftetherto%2Fwdk-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftetherto%2Fwdk-cli/lists"}