7.3 KiB
description, icon
| description | icon |
|---|---|
| Local, non-custodial multi-chain crypto wallet the agent can read balances from and send transfers with — keys stay in-core and never cross the wire. | wallet |
Wallet
A deliberately basic, non-custodial multi-chain crypto wallet owned by the Rust core. It manages one account per supported chain derived from a single recovery phrase, reads balances, and runs a strict prepare → confirm → execute flow for native sends and a small set of token transfers.
It is intentionally minimal: key/account management plus the primitive on-chain operations. Higher-level DeFi (swaps, bridges, generic contract/dapp calls) lives in a separate web3 module and is not part of the wallet's agent or RPC surface.
The most important property to understand: signing and broadcast happen entirely in-core from the decrypted recovery phrase. No private keys ever leave the device or cross the network. This is your money — the wallet is conservative by design.
Supported chains and token standards
Setup derives exactly one account per chain. EVM is a single account reused across six networks. Only the standards listed below are supported for transfers — anything else (swaps, arbitrary contract calls) is out of scope for the wallet.
| Chain | Networks | Native | Token standard | Notes |
|---|---|---|---|---|
| EVM | Ethereum, Base, Arbitrum, Optimism, Polygon, BNB Chain | ETH / BNB / etc. | ERC-20 (BEP-20 on BNB Chain) | One Evm account across all six; network selected per request, defaults to Ethereum mainnet. EIP-1559 / typed-tx signing. |
| Bitcoin | Mainnet | BTC | — | P2WPKH (native SegWit). Rejects token transfers. Esplora REST for balance/broadcast. |
| Solana | Mainnet / devnet (per RPC) | SOL | SPL | ed25519 signing; native + SPL token transfers. |
| Tron | Mainnet | TRX | TRC-20 | TronGrid REST for native + TRC-20 transfers. |
Built-in asset catalogs include the native asset plus common stablecoins per chain (e.g. USDC/USDT as ERC-20/BEP-20, USDC as SPL on Solana, USDT as TRC-20 on Tron).
Onboarding and the recovery phrase
Setup is a single, all-or-nothing operation: it persists a consent flag, the mnemonic word count, the setup source, exactly one derived account per supported chain, and the encrypted recovery phrase. Valid BIP-39 mnemonic word counts are 12, 15, 18, 21, or 24.
The recovery phrase is the only secret. The wallet stores the per-chain account addresses (safe to surface) separately from the secret material, and only the encrypted phrase can reconstruct private keys.
Key custody and security
The wallet is non-custodial and local — there is no server-side key escrow.
- The recovery phrase is always encrypted at rest. It is encrypted via the core
encryptiondomain before being persisted anywhere. - Preferred home: the OS keychain. The encrypted phrase lives in the operating system keychain under the key
wallet.mnemonic, scoped by a workspace-derived user id. Access is gated by the keyring consent policy. - Fallback: workspace JSON. When the keychain is unavailable (e.g. headless), the encrypted phrase falls back to
{workspace_dir}/state/wallet-state.json. On load, any JSON-resident secret is transparently migrated into the keychain when one becomes available, and stripped from the JSON. - Atomic, guarded writes.
wallet-state.jsonis written atomically (temp file + fsync + persist) under a process-wide lock. Corrupt or invalid state files are quarantined rather than trusted. - Decrypt only at signing time. Chain signers decrypt the phrase in-core only when deriving a key to sign a confirmed transaction. Plaintext keys are never persisted and never serialized over the wire.
See OS keyring & secret storage for how secrets are stored across platforms, and Privacy & security for the broader model.
Reading balances and chain info
Read-only surfaces require no confirmation:
- Status — onboarding state plus the safe per-chain account addresses.
- Balances — native-asset balances per account. Note: only EVM balances read live today (Ethereum mainnet); BTC, Solana, and Tron call their providers but fall back to a zero balance with a "provider missing" status on error.
- Network defaults / supported assets — per-chain RPC and explorer URLs, capability flags, and the built-in asset catalog.
- Chain status — per-chain readiness and the active RPC URL.
RPC endpoints are overridable per chain/network via OPENHUMAN_WALLET_RPC_* environment variables. URLs are redacted to scheme + host in logs.
Sending transfers: prepare → confirm → execute
Every write is a two-step, intentional flow — the wallet never sends in one shot.
- Prepare (
prepare_transfer) — validates the amount, destination address, and (for tokens) calldata, estimates fees, and returns a prepared quote with aquoteId. Quotes are held in an in-memory store with a 5-minute TTL, capped at 64, and are not persisted across restarts. - Confirm + execute (
execute_prepared) — requiresconfirmed: trueand a validquoteId. The quote is consumed atomically before broadcast so concurrent confirmations can't double-submit; on failure it's restored with a refreshed TTL so it stays retryable.
Quote-owner binding. Each quote is bound to the chat thread that prepared it. A quote can only be executed by the same owner that prepared it; a quoteId leaked into a shared channel returns an indistinguishable "not found" error rather than letting another session hijack it.
Transfers are limited to native sends and the token standards in the table above. Bitcoin rejects token transfers. Swaps, bridges, and generic contract calls are not available here.
Transaction status tracking
After broadcast, three read-only inspectors let the agent follow a transaction by hash:
tx_status— lifecycle state: pending / confirmed / failed / not found.tx_receipt— receipt details: success, fee, block.lookup_tx— the raw transaction payload.
Agent tools and approval safety
The agent reaches the wallet through six tools:
| Tool | Purpose |
|---|---|
wallet_status |
Onboarding status + account addresses. |
wallet_chain_status |
Per-chain readiness + active RPC. |
wallet_prepare_transfer |
Build a validated, fee-estimated quote. |
wallet_tx_status |
Transaction lifecycle state by hash. |
wallet_tx_receipt |
Transaction receipt by hash. |
wallet_lookup_tx |
Raw transaction lookup by hash. |
Notice there is no agent tool that executes a transfer. The agent can prepare a quote, but actually moving funds (execute_prepared) goes through the RPC surface, where it must be explicitly confirmed and pass the owner-binding check. Combined with the prepare-then-confirm flow and the per-thread quote binding, this keeps the agent from silently spending funds.
Because these are financial actions, they should be surfaced through the approval gate so a human confirms before money moves. Treat every transfer as a high-stakes action.