news 2026/9/10 4:43:06

OpenHuman 本地多链加密钱包模块解析:密钥托管、prepare-confirm-execute 转账流与 Agent 工具面

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenHuman 本地多链加密钱包模块解析:密钥托管、prepare-confirm-execute 转账流与 Agent 工具面

OpenHuman 本地多链加密钱包模块解析:密钥托管、prepare-confirm-execute 转账流与 Agent 工具面

【免费下载链接】openhumanOpenHuman is an open source personal AI for Mac, Windows and Linux — local-first memory, agent orchestration, and deep research.项目地址: https://gitcode.com/GitHub_Trending/op/openhuman

本文深入解析 OpenHuman(本地优先的开源个人 AI 助手)中由核心层自有的多链加密钱包模块 ——src/openhuman/web3/wallet。该模块承担密钥/账户管理与最基础的链上原语操作(原生转账与 ERC20/SPL/TRC20/BEP20 代币转账),是 swap、bridge、dapp 等高层 DeFi 能力的地基。读完本文,你将掌握该钱包的持久化与密钥托管机制、跨 EVM/BTC/Solana/Tron 四类链的 prepare→confirm→execute 转账流程、12+1 个 RPC 控制器与 6 个 Agent 工具的完整调用面,以及 quote 防劫持的线程归属设计原理。

模块定位:刻意保持"基础"的核心自有钱包

wallet是 OpenHuman 核心层直接拥有的本地多链加密钱包,其设计哲学是刻意基础(deliberately basic):只管密钥/账户管理加最原始的在链操作,不包含 swap、bridge 或通用合约调用等高层 DeFi 能力。这些高层能力由独立的web3模块提供,它构建在钱包的crate 内部签名原语sign_and_broadcast_evm/sign_and_broadcast_solana之上,并不属于钱包的 Agent / RPC 暴露面。

钱包覆盖的能力边界包括:

  • 密钥/账户管理:加密恢复短语(recovery phrase)在 OS keychain 或 workspace JSON 中静态加密存储;
  • 面向 Agent 的只读面:地址与余额查询、网络/资产目录、链就绪状态;
  • 面向 Agent 的写操作:prepare→confirm→execute 三步式原生转账与代币转账;
  • 交易广播与只读交易检查:状态(status)、回执(receipt)、原始交易查询(lookup);
  • 链覆盖:EVM(Ethereum + Base/Arbitrum/Optimism/Polygon/BNB Chain)、Bitcoin(P2WPKH)、Solana(原生 + SPL)、Tron(原生 + TRC20)。

签名的安全边界非常明确:签名与广播都发生在核心进程内,由解密后的恢复短语派生密钥完成,任何私钥都不经过网络传输

编译期特性门控(web3feature)

从 mod.rs 的模块结构可以看到,pub mod wallet;始终编译的 facade,真正的实现子模块全部由默认开启的web3Cargo feature 门控(与openhuman::web3openhuman::web3::x402共享同一特性开关)。当特性关闭时,stub接管并暴露相同签名的 no-op / 禁用错误实现,保证cargo check --no-default-features时调用方代码不漂移。

职责全景

README 明确列出该模块的 11 项核心职责,对应源码实现均可验证:

  1. 持久化 onboarding 状态:consent 标记、助记词词数、设置来源(生成/导入)、每条链恰好一个派生账户,以及加密恢复短语;
  2. 密钥托管优先级:加密助记词优先存 OS keychain,加载/保存时自动把秘密从wallet-state.json迁入 keychain,无 keychain 的无头环境回退到 JSON;
  3. 只读钱包信息:状态、各账户原生余额(EVM 实时读取,其余链由 provider 门控)、支持资产目录、各网络默认值(RPC/浏览器/能力标记)、逐链就绪状态;
  4. 预构建转账报价:经过校验、费用预估、带 TTL 的 prepared-quote,必须显式确认才能执行;
  5. 签名与广播:按链签名并广播已确认的 quote;失败时恢复 quote 并刷新 TTL 以保持可重试;
  6. quote 线程绑定:把每个 quote 绑定到发起它的聊天线程,防止共享频道中泄露的quote_id被其他 Agent 会话劫持;
  7. 双接口暴露:6 个 Agent 工具(wallet_statuswallet_chain_statuswallet_prepare_transferwallet_tx_statuswallet_tx_receiptwallet_lookup_tx)与 12 个wallet.*RPC 控制器;
  8. crate 内部签名原语sign_and_broadcast_evm/sign_and_broadcast_solanaweb3层签名广播外部构造的未签名交易,不暴露给 Agent / RPC 面。

关键文件地图

文件职责
mod.rs面向导出的模块根:模块文档、mod/pub use重导出、特性门控 facade
ops.rs(实现拆分于 ops_part_01.rs / ops_part_02.rs)Onboarding 元数据 + 密钥持久化:WalletChain/WalletAccount/WalletStatus类型、setup/statuswallet-state.json原子写(临时文件 + fsync)、损坏状态隔离、keychain 加载/保存/迁移、validate_setup、crate 内部secret_material
execution.rs(实现拆分于 execution_part_01.rs / execution_part_02.rs)执行面:余额/网络默认值/支持资产/链状态读取、prepare_transfer/execute_preparedtx_status/tx_receipt/lookup_tx、crate 内部sign_and_broadcast_evm/sign_and_broadcast_solana、内存 quote 存储(TTL、上限 64)、QuoteOwner聊天线程绑定、金额/地址/calldata 校验、费用预估、hex/u256 工具
defaults.rsEvmNetwork枚举(chain id、默认 RPC、浏览器基址、环境变量)、BTC/Solana/Tron 默认 RPC/REST URL、环境变量覆盖解析、逐链/逐网络资产目录
abi.rsencode_erc20_transfer—— 通过tinywallet_bus::abi编码transfer(address,uint256)calldata
schemas.rsRPC 控制器 schema +handle_*分发器,委托给ops/executionall_wallet_controller_schemas/all_wallet_registered_controllers
rpc.rs网络传输层(非 RPC 控制器):共享reqwest::Client、JSON-RPC POST(rpc_callevm_rpc_callrpc_call_to)、REST GET/POST 助手、日志 URL 脱敏
transport.rs钱包原语Transport接缝的主机侧:端点解析、故障转移与 URL 脱敏
tools.rs重导出tools/下的三个 Agent 工具结构体
tools/status.rsWalletStatusToolwallet_status
tools/chain_status.rsWalletChainStatusToolwallet_chain_status
tools/prepare_transfer.rsWalletPrepareTransferToolwallet_prepare_transfer
tools/tx_query.rsWalletTxStatusTool/WalletTxReceiptTool/WalletLookupTxTool
chains/mod.rs逐链执行器命名空间,定义每链小型面(execute_*_quotenative_balancevalidate_*_address
chains/evm.rsEVM 密钥派生(BIP-39)、EIP-1559/typed-tx 签名、eth_*余额/gas/广播
chains/btc.rsBitcoin P2WPKH 派生/签名(bitcoincrate、secp256k1、BIP-32)+ Esplora REST 余额/广播
chains/solana.rsSolana ed25519 派生、原生 + SPL 转账、JSON-RPC 余额/广播(手写 wire format,不引入solana-sdk
chains/tron.rsTron 派生/签名 + TronGrid REST 原生 + TRC20 转账
test_support.rs#[cfg(test)]共享设施:TEST_LOCKsetup_wallet_in(确定性 "abandon … about" 助记词)、逐链样本地址

密钥与状态持久化:keychain 优先、JSON 兜底

钱包的持久化状态分三处,各有明确职责:

wallet-state.json(非秘密元数据)

路径为{workspace_dir}/state/wallet-state.json,对应源码中的wallet_state_path()(ops_part_01.rs)。内容为StoredWalletStateconsent_grantedsourcemnemonic_word_countaccountsupdated_at_ms,以及仅作为兜底encrypted_mnemonic字段。

写入采用严格的原子策略(save_stored_wallet_state_unlocked):

  1. 在目标目录创建NamedTempFile
  2. write_all写入序列化 JSON,随后sync_all刷盘;
  3. sync_parent_dir对父目录执行sync_all(确保目录项落盘);
  4. temp_file.persist(&path)原子替换;
  5. 再次sync_parent_dir

整个过程由进程级全局锁WALLET_STATE_FILE_LOCK保护,防止多任务并发读写竞态。当文件不可读、JSON 解析失败或校验不通过时,文件会被**隔离(quarantine)**重命名为wallet-state.json.corrupted.<timestamp>(见quarantine_corrupted_wallet_state),而不是静默丢弃数据。

OS keychain(加密助记词的首选归宿)

keychain 条目键为wallet.mnemonic,并通过wallet_user_id()(取 workspace 目录的父目录名,兜底用 FNV-1a 哈希)按 workspace 作用域隔离(ops_part_01.rs)。加载与保存都会先检查 keyring 可用性与 keyring 同意策略(keyring_consent::policy::check_secret_access),不可用时优雅降级。

keychain 与 JSON 之间存在自动双向迁移逻辑(load_stored_wallet_state_unlocked步骤 3):

  • keychain 有助记词且 JSON 仍带encrypted_mnemonic→ 清除 JSON 字段并重写;
  • keychain 不可用但 JSON 带助记词 → 尝试提升(promote)到 keychain,成功则从 JSON 剥离,内存中保留值以便校验通过;
  • 加载时还会重新探测(re-probe)一次 keychain,兼容并发任务写入尚未可见的场景。

保存路径同理:keychain 可用时助记词只写 keychain,JSON 中剥离秘密字段(save_stored_wallet_state_unlocked开头部分)。

内存 quote 存储(不跨重启)

PreparedTransaction存放在 execution_part_01.rs 的进程内QUOTE_STORELazy<Mutex<Vec<PreparedTransaction>>>),TTL 为 5 分钟(QUOTE_TTL_MS = 5 * 60 * 1000),容量上限 64(QUOTE_STORE_CAP = 64),访问时惰性清理过期项。不持久化,进程重启后清空。

校验规则(validate_setup

setup成功前必须通过严格校验(validate_setup):

  • consent_granted必须为true(显式同意,无默认值);
  • 助记词词数必须是12/15/18/21/24之一;
  • encrypted_mnemonic非空(本地可签名钱包的硬性要求);
  • 每个账户的addressderivation_path非空;
  • 每条链恰好一个账户(EVM、BTC、Solana、Tron 各一)。

setup还有幂等保护:已配置钱包再次 setup 必须显式传force=true,否则报 "wallet is already configured; pass force=true to overwrite"。WalletSetupParams.force默认false,前端需二次确认后才可置真,防止静默覆盖。

四链一 EVM:网络、资产与派生路径

EVM 六网络的参数化

EVM 是单个WalletChain::Evm变体,覆盖 6 条网络,由EvmNetwork枚举选择(默认ethereum_mainnet),其他链忽略evmNetwork字段。从 defaults.rs 可得到完整参数表:

EvmNetwork变体chain id默认 RPC浏览器 tx 基址环境变量覆盖
EthereumMainnet1https://ethereum-rpc.publicnode.cometherscan.io/txOPENHUMAN_WALLET_RPC_EVM
BaseMainnet8453https://mainnet.base.orgbasescan.org/txOPENHUMAN_WALLET_RPC_BASE
ArbitrumOne42161https://arb1.arbitrum.io/rpcarbiscan.io/txOPENHUMAN_WALLET_RPC_ARBITRUM
OptimismMainnet10https://mainnet.optimism.iooptimistic.etherscan.io/txOPENHUMAN_WALLET_RPC_OPTIMISM
PolygonMainnet137https://polygon-rpc.compolygonscan.com/txOPENHUMAN_WALLET_RPC_POLYGON
BscMainnet56https://bsc-dataseed.binance.orgbscscan.com/txOPENHUMAN_WALLET_RPC_BSC

RPC 解析逻辑(EvmNetwork::rpc_url()):优先读对应环境变量,非空则用之,否则回落默认 URL,并以RpcSource::EnvOverride/RpcSource::Default标注来源。这正是测试用 axum mock 指向自定义端点的机制。

BTC / Solana / Tron 默认端点

  • BTC:Esplora RESThttps://blockstream.info/api(可被OPENHUMAN_WALLET_RPC_BTC覆盖);
  • Solana:JSON-RPChttps://api.mainnet-beta.solana.com(devnet 为https://api.devnet.solana.com);
  • Tron:TronGrid RESThttps://api.trongrid.io(可被OPENHUMAN_WALLET_RPC_TRON覆盖)。

Solana 还支持集群选择:环境变量OPENHUMAN_SOLANA_CLUSTER=devnet切到 Devnet(SolanaCluster::Devnet),同时驱动 RPC 端点与 USDC SPL mint 地址 —— mainnet mint 为EPjFWdd5...TDt1v,devnet mint 为4zMMC9s...ncDU,确保 devnet 上的 x402 支付挑战落链到正确的 mint。

派生路径(每条链一个确定性地址)

从 test_support.rs 的样本账户可确认各链的标准 BIP 派生路径:

路径说明
EVMm/44'/60'/0'/0/0BIP-44,Ethereum 币种号 60,六条 EVM 网络共享同一地址
Bitcoinm/84'/0'/0'/0/0BIP-84,原生隔离见证 P2WPKH(bc1q…
Solanam/44'/501'/0'/0'SLIP-0010 ed25519
Tronm/44'/195'/0'/0/0BIP-44,币种号 195

注意余额读取时的特例:EVM_BALANCE_NETWORKS常量(execution_part_02.rs)只把 Ethereum、Base、BNB Chain 三条网络作为独立余额行展示,单一派生 EVM 地址在这三条网络上分别读取原生资产(ETH/ETH/BNB)。

资产目录

内置资产目录按链/网络组织:每条 EVM 网络有默认 ERC-20 目录(含 BEP20),BTC/Solana/Tron 各有原生资产目录。supported_assets汇总输出,find_asset_for_network按链+网络+符号解析资产(asset_symbol缺省时取该链/网络的原生资产)。

执行面:prepare → confirm → execute 三步转账流

所有写操作遵循"先 prepare 报价、再显式确认执行"的安全模式。这是 execution.rs 的核心设计:任何写操作必须先 prepare,再显式 confirm;秘密材料始终保持加密静态存储。

第一步:prepare_transfer(报价)

PrepareTransferParams(camelCase JSON 反序列化):

{ "chain": "evm | btc | solana | tron", "toAddress": "目标地址", "amountRaw": "链最小单位整数(EVM 为 wei)", "assetSymbol": "可选,资产符号(缺省为原生资产)", "evmNetwork": "可选,仅 chain='evm' 时有效,缺省 ethereum_mainnet" }

Agent 工具 prepare_transfer.rs 的参数 schema 与之一一对应,evmNetwork的枚举值为ethereum_mainnet/base_mainnet/arbitrum_one/optimism_mainnet/polygon_mainnet/bsc_mainnet

预处理校验(execution_part_01.rs):

  • validate_address:按链校验目标地址,委托给 vendoredtinywallet_buscrate 的四种地址格式;
  • validate_amount:解析为非负 u128 整数,拒绝 0 金额;
  • BTC 拒绝代币转账(token transfers are not supported on Bitcoin);
  • 解析资产(native 或 token),生成PreparedKind::NativeTransfer/TokenTransfer

报价的estimated_fee_raw按链/类型估算(estimated_fee_raw,execution_part_01.rs):

链 × 类型预估费用
EVM 原生转账21,000 gas × 30 Gwei = 630,000,000,000,000 wei
EVM 代币转账65,000 gas × 30 Gwei
BTC5,000 sats
Solana5,000 lamports
Tron 原生1,000,000 SUN
Tron TRC2015,000,000 SUN

(BTC 的实际费率常量在 btc.rs:DEFAULT_FEE_RATE_SAT_VB = 20sat/vB ×TYPICAL_TX_VBYTES = 141vbytes(单输入双输出 P2WPKH)。)

报价对象PreparedTransactionquote_id(格式q_<毫秒时间戳>_<自增序号>)、created_at_msexpires_at_ms(prepare 时刻 + 5 分钟)、owner(内部门控数据,不序列化上线)。

第二步:execute_prepared(确认 + 广播)

ExecutePreparedParams只有两个字段:quote_idconfirmed。执行前强制要求confirmed: true,否则直接报 "execute_prepared requiresconfirmed: true"。

执行路径的关键设计(execution_part_02.rs):

  1. 通过current_owner()读取调用方的APPROVAL_CHAT_CONTEXT
  2. 原子取走 quotetake_quote_for):在广播前先从存储中移除,使两个并发确认不可能同时通过get_quote造成重复提交(double-submit);
  3. 按链分发到execute_evm_quote/execute_btc_quote/execute_solana_quote/execute_tron_quote
  4. 失败时恢复 quote 并刷新 TTLexpires_at_ms = now + QUOTE_TTL_MS),避免慢链调用(网络超时)耗尽原 5 分钟预算后交回一个立即过期的 quote;用户可修复原因后重试;
  5. 成功则回填实际费用、置状态为Broadcasted,若链执行器未返回 explorer URL 则用explorer_tx_url兜底生成。

第三步:链上执行器(四链签名广播)

EVM(chains/evm.rs)的签名广播流程完整可循:

  1. eth_chainId读取链 ID,与目标EvmNetwork.chain_id()比对,不一致直接拒绝(防止 RPC 端点配置错误导致跨链误发);
  2. eth_getTransactionCount(状态"pending")取 nonce,避免连续两次确认时 nonce 碰撞;
  3. eth_estimateGas预估 gas,eth_gasPrice取 gas price;
  4. 把交易规格与解密后的助记词交给modules::wallet::sign_transaction_in_module在独立钱包模块中派生、编码、签名、组装;
  5. eth_sendRawTransaction广播,返回 tx hash 与模拟费用(gas × gasPrice)。

原生转账直接value=amount, data=空;ERC20 代币转账则value=0data=encode_erc20_transfer(recipient, amount)(由 abi.rs 委托tinywallet_bus::abi编码 4 字节选择器 + 两个 32 字节字)。链 ID 校验失败时给出的错误形如EVM RPC chain_id mismatch: rpc reported X but network Y expects Z,具备明确的可诊断性。

Bitcoin(chains/btc.rs):Esplora REST 做 UTXO 发现(/address/{addr}/utxo)与余额(/address/{addr},confirmed + mempool 余额),/txPOST 广播原始交易。收款地址允许任意合法主网地址(P2WPKH/P2TR/P2SH 均可编码),但发送方地址强制 P2WPKHvalidate_btc_sender_address),因为只支持 native segwit 派生签名。

Solana(chains/solana.rs):手写 wire format 组装交易(System Program 转账或 SPL token 转账,含 ATA 程序与 Token 程序 ID),不引入solana-sdk(其传递依赖约 150 个 crate)。余额走getBalanceJSON-RPC。

Tron(chains/tron.rs):TronGrid REST 的wallet/createtransaction(原生)与wallet/triggersmartcontract(TRC20),wallet/broadcasttransaction广播。TRC20 固定fee_limit15,000,000 SUN(TRC20_FEE_LIMIT_SUN)。节点返回的交易会经tinywallet_bus::tx::tron::verify_contract结构化校验并重算 txid 后才交给签名模块。

crate 内部签名原语(web3 层的地基)

sign_and_broadcast_evm/sign_and_broadcast_solana是钱包提供给web3模块的 crate 内部原语:对外部构造的未签名交易(如 deBridge swap/bridge 的 unsigned tx、dapp 的 calldata)做签名+广播。EVM 版本签名(to, data, value),Solana 版本签名 hex 编码的VersionedTransaction。它们不出现在 Agent 工具或 RPC 控制器中,从而保证私钥永不离开钱包域。

交易只读查询:tx_status / tx_receipt / lookup_tx

三个只读查询覆盖交易的全生命周期:

  • tx_status(chain, evmNetwork?, hash)TxStatusInfo,归一化出四种TxState(execution_part_01.rs):
    • Pending:节点已见但未打包;
    • Confirmed:已打包且成功;
    • Failed:已打包但回滚/失败;
    • NotFound:节点无此 hash 记录。
    • EVM 实现区分逻辑(chains/evm.rs):先查eth_getTransactionReceipt,receipt 为 null 时再用eth_getTransactionByHash区分 Pending 与 NotFound;有回执时读status字段判断成功与否,并用eth_blockNumber计算确认数。
  • tx_receipt(chain, evmNetwork?, hash)TxReceiptInfo:成功标志、区块号、gas used、费用(fee_raw)、以及 provider 原始回执(raw透传)。
  • lookup_tx(chain, evmNetwork?, hash)TxLookupInfo:按 hash 查原始交易负载(raw透传)。

RPC 控制器与 Agent 工具:双面接口

RPC 命名空间wallet(方法形式openhuman.wallet_<function>

README 列出 12 个控制器;当前 schemas.rs 实际注册了13 个(含reveal_recovery_phrase):

函数用途
statusOnboarding 状态 + 安全账户元数据(地址)
setup持久化 consent + 派生账户 + 加密助记词(全部输入必填)
balances各账户原生资产余额(EVM 实时;其他链 provider 门控)
network_defaults逐链 RPC/浏览器/能力标记 + 资产目录
supported_assets内置资产目录(含默认 EVM ERC-20 / BEP20)
encode_erc20_transfer编码transfer(address,uint256)calldata(仅 EVM)
chain_status逐链就绪状态 + 生效中 RPC URL
prepare_transfer报价原生/代币转账(四条链)
execute_preparedconfirmed: true确认并执行quoteId(发交易)
tx_status查询交易生命周期状态(pending/confirmed/failed/not_found)
tx_receipt查询交易回执(成功、费用、区块)
lookup_tx按 hash 查询原始交易负载
reveal_recovery_phrase向用户披露恢复短语(RevealRecoveryPhraseResult

控制器通过all_wallet_registered_controllers注册,并在 src/core/all.rs 中接入注册表(含 schema 与 capability 描述)。

Agent 工具(6 个)

工具实现位于 tools/,由 tools.rs 重导出,全部实现crate::openhuman::tools::traits::Tool并委托给同名wallet::*函数:

  • WalletStatusToolwallet_status
  • WalletChainStatusToolwallet_chain_status
  • WalletPrepareTransferToolwallet_prepare_transfer
  • WalletTxStatusToolwallet_tx_status
  • WalletTxReceiptToolwallet_tx_receipt
  • WalletLookupTxToolwallet_lookup_tx

注意:这里没有execute_prepared的 Agent 工具 —— 执行面仅通过 RPC 到达,Agent 只能准备/查询,不能绕过确认直接发交易。

工具的注册链路:src/openhuman/tools/ops.rs注册三个钱包工具,src/openhuman/agent/agents/loader.rs组装 Agent 工具集时引用,src/openhuman/test_support/introspect.rs在测试中做内省。此外 toolpacks/registry.rs 将 6 个钱包工具归入Web3域组,可被工具包(toolpack)按需 withhold 或授予。

Quote 归属绑定:防劫持设计

这是本模块最值得关注的安全设计。quote_id会随 prepared-tx 摘要回到共享聊天频道中,同频道的其他调用方可能读到别人的quote_id并尝试驱动其执行。为此:

  • prepare 时通过current_owner()(execution_part_01.rs)从 task-local 的APPROVAL_CHAT_CONTEXT读取thread_id+client_id,盖在 quote 的owner字段上;
  • execute_prepared时再次读取调用方 owner,交给take_quote_for强制与 prepare 时 owner 相等(take_quote_for);
  • owner 不匹配时返回字节级相同quote '…' not found错误,与真正的未命中不可区分 —— 不存在枚举 oracle,泄露的quote_id无法被探测;
  • owner 检查先于状态/过期检查,且移除 quote 只发生在检查通过之后,误匹配的调用方无法"毒化"存储消费他人 quote;
  • 非聊天调用方(CLI / 直接 JSON-RPC / 后台 cron)owner 为None,只能执行同样无聊天上下文时准备的 quote —— 防止后台流程"捡走"交互用户的 quote 造成权限跌落。

对应测试在 execution_tests.rs:execute_prepared_rejects_cross_owner_execution验证跨 owner 拒绝且错误形如 not found;execute_prepared_owner_mismatch_error_matches_not_found_shape显式断言两种错误字节一致。

实现警示(README 明确标注):current_owner()依赖web_chat::run_chat_task内联.await链。tokio::task_local!能跨.await传播但不跨tokio::spawn—— 若聊天路径把工具循环拆到新 spawn 任务且未重新 scopeAPPROVAL_CHAT_CONTEXT,该门控会静默失效。

密钥安全边界与签名委托

  • 恢复短语在 rest 态加密存储(keychain 或 JSON),派生前经security::encryption::rpc::decrypt_secret解密;
  • 解密后的助记词交给钱包模块modules::wallet::attested_proxy(构建设置固定的工件代理)签名,核心进程本身不持有待发交易的私钥;
  • EVM 广播前做eth_chainId一致性校验,杜绝 RPC 端点错配造成的跨链误发;
  • 日志中的 RPC URL 统一脱敏为 scheme+host(rpc.rs的 URL redaction);
  • 未配置钱包时的错误信息统一为常量WALLET_NOT_CONFIGURED_MESSAGE = "wallet is not configured; run wallet setup first",下游边界把它归类为expected_user_state,不进 Sentry。

依赖关系与协作模块

  • crate::openhuman::configConfigconfig::rpc::load_config_with_timeout):解析 workspace 目录与配置,用于状态路径、keychain user id 与解密;
  • crate::openhuman::security::keyringis_available/get/set):OS keychain 存储加密助记词;
  • crate::openhuman::security::encryption::rpcencrypt_secret/decrypt_secret):链签名器派生前解密恢复短语;
  • crate::openhuman::security::approval::APPROVAL_CHAT_CONTEXT:task-local 聊天 owner(thread_id/client_id),用于 quote 线程绑定;
  • crate::openhuman::tools::traitsTool/ToolResult/ToolCallOptions
  • crate::core::allcrate::core:RPC 控制器注册表接线;
  • crate::rpc::RpcOutcome:标准 RPC 返回形态;
  • 外部 crate:ethers_core/ethers_signers/coins_bip39(EVM + ABI + BIP-39)、bitcoin+secp256k1(BTC)、ed25519_dalek(Solana)、sha2hexreqwestserde/serde_jsontempfileparking_lotonce_cell

被引用方:src/openhuman/tools/ops.rs(注册 Agent 工具)、src/openhuman/agent/agents/loader.rs(组装工具集)、src/core/all.rs(接线控制器)、src/openhuman/test_support/introspect.rs(测试内省)。

测试与验证

  • test_support.rs 提供确定性助记词"abandon × 11 + about"(BIP-39 标准测试词),四条链各自派生出固定地址,配合setup_wallet_in在临时目录写入已配置钱包状态,所有链签名器测试可复现;
  • 逐链测试文件:evm_tests.rsbtc_tests.rssolana_tests.rstron_tests.rsabi_tests.rsdefaults_tests.rsrpc_tests.rstransport_tests.rsops_tests.rsexecution_tests.rsschemas_tests.rsstub_tests.rs
  • 测试通过OPENHUMAN_WALLET_RPC_*环境变量把链端点指向 axum mock,验证余额、广播与错误路径。

已知约束与注意事项(gotchas)

  1. rpc.rs是网络传输而非 RPC 控制器—— RPC 控制器在schemas.rs。这是对仓库"rpc.rs= 域 API"惯例的唯一例外,阅读代码时务必区分;
  2. quote 原子消费take_quote_for在广播前移除 quote 防并发重复提交;失败恢复并刷新 TTL;
  3. setup 强约束:恰好每链一个账户、词数 12/15/18/21/24、consent 必真、助记词非空;
  4. EVM 是 6 网络单变体EvmNetwork默认ethereum_mainnet,其他链忽略evmNetwork;BTC 拒绝代币转账;swap/bridge/合约调用不在钱包内,位于web3模块;
  5. RPC 端点可覆盖:逐链/逐网络OPENHUMAN_WALLET_RPC_*环境变量(测试借此指向 mock),日志 URL 脱敏为 scheme+host;
  6. balances的 provider 门控:仅 EVM(Ethereum mainnet)实时读取;BTC/Solana/Tron 调用 provider 失败时回退零值并标ProviderStatus::Missing
  7. 事件面为空:模块不发布/订阅任何DomainEvent,无bus.rs;聊天上下文耦合通过 task-localAPPROVAL_CHAT_CONTEXT完成,而非事件总线;
  8. reveal_recovery_phrase的敏感性:披露恢复短语是高风险操作,README 未展开其授权细节,从代码看它返回RevealRecoveryPhraseResult { phrase, word_count },应在理解其风险边界后再接入上层 UI。

小结

src/openhuman/web3/wallet是一个刻意克制、安全边界清晰的核心层多链钱包:keychain 优先的密钥托管、原子化的状态持久化、prepare→confirm→execute 的强制两步确认流、quote 线程归属绑定防劫持、以及"Agent 只能准备/查询、执行仅走 RPC"的接口分工。它不追求 DeFi 功能的广度,而是把"密钥安全 + 转账原语 + 可审计的只读查询"做到扎实,并向上层web3模块提供 crate 内部签名原语,构成 OpenHuman 链上能力的信任地基。

【免费下载链接】openhumanOpenHuman is an open source personal AI for Mac, Windows and Linux — local-first memory, agent orchestration, and deep research.项目地址: https://gitcode.com/GitHub_Trending/op/openhuman

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 4:39:38

CANN/GE GNode属性获取API

GetAttr 【免费下载链接】ge GE&#xff08;Graph Engine&#xff09;是面向昇腾的图编译器和执行器&#xff0c;提供了计算图优化、多流并行、内存复用和模型下沉等技术手段&#xff0c;加速模型执行效率&#xff0c;减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前端的…

作者头像 李华
网站建设 2026/9/10 4:38:48

AutoHedge:面向Swarm的LLM服务语义健康网关

1. AutoHedge 是什么&#xff1f;它解决的不是“自动对冲”&#xff0c;而是工程协同失效的根因问题 AutoHedge 这个名字乍看像金融风控里的高频术语——自动对冲&#xff08;Automatic Hedging&#xff09;&#xff0c;但结合热搜词 Swarm、API、OpenAI、Python&#xff0c;再…

作者头像 李华
网站建设 2026/9/10 4:36:29

Happy-LLM 教程导读:从零开始构建大模型的学习路线与实践指南

Happy-LLM 教程导读&#xff1a;从零开始构建大模型的学习路线与实践指南 【免费下载链接】happy-llm &#x1f4da; 从零开始构建大模型 项目地址: https://gitcode.com/GitHub_Trending/ha/happy-llm 本篇文章是 Datawhale 开源项目 Happy-LLM&#xff08;仓库路径 doc…

作者头像 李华