How OpenHuman's Web3 Multi-Chain Wallet Supports BTC, EVM, Solana, and Tron
OpenHuman's web3 multi-chain wallet unifies Bitcoin, EVM, Solana, and Tron support through a modular architecture where each chain implements a standardized interface in src/openhuman/web3/wallet/chains/, delegating cryptographic operations to an isolated wallet module while exposing a single JSON-RPC API to consumers.
The OpenHuman repository (tinyhumansai/openhuman) implements a Rust-based web3 wallet domain that treats heterogeneous blockchains as interchangeable backends. By abstracting chain-specific logic into dedicated modules and standardizing on common operations like native_balance, transaction execution, and status queries, the system enables agents and UI components to interact with BTC, EVM, Solana, and Tron through identical function signatures.
Unified Architecture with WalletChain Enum
At the core of the multi-chain support is the WalletChain enum defined in src/openhuman/web3/wallet/types.rs. This enumeration explicitly lists the supported networks—BTC, EVM, Solana, and Tron—and acts as a dispatch key throughout the wallet domain.
Rather than scattering chain logic across the codebase, OpenHuman consolidates implementations in src/openhuman/web3/wallet/chains/:
btc.rs– UTXO-based transaction construction and Esplora API integrationevm.rs– Account-based transfers and JSON-RPC interactionssolana.rs– Instruction-based message building and Solana RPC callstron.rs– Tron-specific contract calls and broadcast logic
Each module implements the same operational interface, allowing the higher-level wallet RPC to route calls dynamically based on the WalletChain variant specified in the request.
Chain-Specific Implementation Modules
Bitcoin (BTC) UTXO Management
The Bitcoin implementation in src/openhuman/web3/wallet/chains/btc.rs handles the UTXO model required by BTC. The native_balance(address) function queries the Esplora REST API at /address/{addr} to return confirmed and pending satoshi balances.
For transaction creation, execute_btc_quote constructs PSBT-style transactions by:
- Fetching available UTXOs via
fetch_utxos(address)(Esplora endpoint/address/{addr}/utxo) - Selecting inputs with
select_utxos - Estimating fees through
estimated_btc_fee_sats - Passing the transaction spec to
modules::wallet::sign_transaction_in_modulefor signing
Once signed, broadcast_raw_hex transmits the raw transaction via POST to /tx. Status monitoring uses tx_status, tx_receipt, and lookup_tx to normalize Esplora's /tx/:hash/status and /tx/:hash endpoints.
EVM Account-Based Transactions
EVM support in src/openhuman/web3/wallet/chains/evm.rs operates on the account-based model, eliminating UTXO complexity. The evm_balance(network, address) function calls eth_getBalance via JSON-RPC to retrieve Wei-denominated balances.
Transaction execution flows through execute_evm_quote, which:
- Builds raw transaction specs for native transfers or ERC-20 tokens
- Uses
sign_and_broadcastto submit signed payloads viaeth_sendRawTransaction - Monitors confirmation through
eth_getTransactionReceiptandeth_getTransactionByHashin the status functions
Address validation delegates to tinywallet_bus::address::evm through validate_evm_address.
Solana Program Instructions
Solana integration in src/openhuman/web3/wallet/chains/solana.rs manages the blockchain's instruction-based architecture. The solana_balance(address) function queries getBalance via Solana's RPC to return lamport balances.
The execute_solana_quote function assembles Solana messages containing instructions and recent blockhashes, then forwards them for signing. Broadcasting occurs through sign_and_broadcast_solana, which posts base64-encoded signed transactions to the sendTransaction RPC method. Status tracking wraps getSignatureStatuses and getTransaction responses via tx_status and tx_receipt.
Tron Contract Calls
Tron support in src/openhuman/web3/wallet/chains/tron.rs handles the network's distinct account and contract model. The tron_balance(address) function queries Tron's /v1/accounts/{addr} endpoint.
Transaction creation via execute_tron_quote builds Tron-specific payloads including contract calls and fee structures. The sign_and_broadcast_tron method posts signed transactions to /wallet/broadcasttransaction, while tx_status and tx_receipt interface with /wallet/gettransactioninfobyid for confirmation data.
Address validation uses validate_tron_address, delegating to tinywallet_bus::address::tron for base58 and hex format checking.
The Common Execution Pipeline
Despite chain-specific differences, all four networks follow a standardized four-phase pipeline defined in src/openhuman/web3/wallet/ops.rs and src/openhuman/web3/wallet/defaults.rs:
-
Configuration Resolution – RPC URLs resolve through
rpc_url_for_chainindefaults.rs, mapping eachWalletChainvariant to appropriate node endpoints and explorer URLs. -
Secret Material Access – The encrypted mnemonic retrieves via
secret_material(WalletChain::...)inops.rs, remaining encrypted until passed to the signing module. -
Module-Based Signing – Cryptographic operations execute inside the dynamic wallet module (
modules::wallet) throughsign_transaction_in_module. The core binary passes only the derivation path, mnemonic, and aTransactionSpecenum variant (e.g.,TransactionSpec::Btc,TransactionSpec::Evm), ensuring private keys never reside in the main application memory. -
Network Broadcast – Signed raw transactions transmit to chain-specific explorers or nodes using the broadcast functions detailed in each chain module.
This isolation allows the React frontend and autonomous agents to invoke openhuman.wallet_* JSON-RPC methods uniformly, regardless of the underlying chain mechanics.
Practical Code Examples
Query native balances across chains using the unified interface:
// Bitcoin balance in satoshis
let btc_balance = openhuman::web3::wallet::chains::btc::native_balance("bc1qw...").await?;
// EVM balance (Wei)
let evm_balance = openhuman::web3::wallet::chains::evm::evm_balance(
EvmNetwork::EthereumMainnet,
"0x111..."
).await?;
Execute transactions using identical quote structures:
// EVM native transfer (0.001 ETH)
let evm_quote = PreparedTransaction {
quote_id: "q1".into(),
kind: PreparedKind::NativeTransfer,
chain: WalletChain::Evm,
evm_network: Some(EvmNetwork::EthereumMainnet),
from_address: "0x111…".into(),
to_address: "0x222…".into(),
asset_symbol: "ETH".into(),
amount_raw: "1000000000000000".into(),
..Default::default()
};
let evm_result = openhuman::web3::wallet::chains::evm::execute_evm_quote(evm_quote).await?;
// Solana SPL-token transfer (5 tokens with 6 decimals)
let solana_quote = PreparedTransaction {
quote_id: "q2".into(),
kind: PreparedKind::TokenTransfer,
chain: WalletChain::Solana,
evm_network: None,
from_address: "F111…".into(),
to_address: "F222…".into(),
token_address: Some("So111…".into()),
amount_raw: "5000000".into(),
..Default::default()
};
let solana_res = openhuman::web3::wallet::chains::solana::execute_solana_quote(solana_quote).await?;
All functions expose through the core RPC façade (coreRpcClient), enabling frontend invocation via openhuman.wallet_* methods.
Summary
- Modular Design – Each chain (BTC, EVM, Solana, Tron) implements isolated logic in
src/openhuman/web3/wallet/chains/while conforming to a standard interface. - Unified Types – The
WalletChainenum intypes.rsprovides type-safe dispatch across heterogeneous networks. - UTXO vs. Account Models – Bitcoin uses UTXO selection and PSBT construction via Esplora APIs, while EVM, Solana, and Tron use account-based transaction formats.
- Secure Signing – Private keys remain confined to the dynamic wallet module (
modules::wallet), with the core passing onlyTransactionSpecvariants and derivation paths. - Consistent API – Consumers interact through a single JSON-RPC namespace regardless of underlying chain complexity.
Frequently Asked Questions
How does the wallet handle different address formats across chains?
The wallet delegates validation to chain-specific modules in tinywallet_bus::address. For Bitcoin, validate_btc_address handles Bech32 and legacy formats; EVM uses validate_evm_address for checksum validation; Solana and Tron implement their respective base58 and hex checks. This abstraction ensures the UI can validate user input before attempting transactions.
Where are the RPC endpoints configured for each blockchain?
Default RPC and explorer URLs reside in src/openhuman/web3/wallet/defaults.rs via the rpc_url_for_chain function. The system maps WalletChain variants to appropriate endpoints (Esplora for Bitcoin, standard JSON-RPC for EVM, Solana RPC nodes, and Tron full nodes), allowing centralized configuration updates without modifying chain logic.
How does the wallet keep private keys secure while supporting multiple chains?
Private key material never enters the core wallet domain directly. Instead, secret_material() in ops.rs retrieves encrypted mnemonics and passes them to sign_transaction_in_module within the dynamically loaded wallet module. This module isolation ensures cryptographic operations occur in an attested, isolated environment separate from the main application binary.
Can the wallet support additional chains beyond BTC, EVM, Solana, and Tron?
The architecture supports extension by implementing the standard interface in a new module under src/openhuman/web3/wallet/chains/. A developer would add the chain variant to the WalletChain enum in types.rs, implement native_balance, execute_*_quote, and broadcasting functions, then register RPC URLs in defaults.rs. The module-based signing system handles cryptographic diversity automatically.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →