Solana CLI 使用 Ledger Nano 硬件钱包完整指南:keypair URL、转账签名与多设备管理
【免费下载链接】solanaWeb-Scale Blockchain for fast, secure, scalable, decentralized apps and marketplaces.项目地址: https://gitcode.com/GitHub_Trending/so/solana
本篇基于 Solana 官方文档docs/src/cli/wallets/hardware/ledger.md整理并扩充,讲解如何用 Solana CLI 在命令行中与 Ledger Nano S、Nano S Plus 或 Nano X 交互:如何配置设备状态、用usb://ledgerkeypair URL 派生并查看多个钱包地址、查询余额、由硬件设备离线签名完成 SOL 转账,以及使用resolve-signer管理同一台电脑上连接的多台 Ledger 设备。读完本文,你能独立完成硬件钱包地址的派生与使用、理解 URL 中各参数的含义,并能结合remote-wallet与clap-utils源码理解 CLI 背后的签名调用链。
开始之前的准备工作
使用前需完成两项准备(原文档 "Before You Begin" 部分):
- 按 Ledger 官方指引在 Nano 设备上安装并配置 Solana 应用;
- 安装 Solana 命令行工具,参见 安装文档。
设备侧要求与 Ledger Nano 文档 中 "Use Ledger Nano with Solana CLI" 一节一致:
- 确保 Ledger Live 应用已关闭(CLI 通过 USB HID 直接访问设备,Ledger Live 会占用设备通道);
- 将 Nano 通过 USB 插入电脑;
- 输入 PIN 解锁,并在设备上打开 Solana 应用;
- 确认设备屏幕显示 "Application is ready"。
从源码看,CLI 只识别 Ledger 的usb:类型远程钱包。clap-utils/src/keypair.rs 中parse_signer_source会把参数解析为 URI,仅当 scheme 为usb时构造SignerSourceKind::Usb(RemoteWalletLocator),且 remote-wallet/src/locator.rs 的Manufacturer枚举目前只有Ledger一种取值(对应字符串ledger),因此 keypair URL 的 host 部分只支持usb://ledger。
keypair URL 格式与 Wallet ID
Solana 定义了 keypair URL 格式来唯一定位硬件钱包上的密钥,完整格式(见 硬件钱包总览):
usb://<MANUFACTURER>[/<WALLET_ID>][?key=<DERIVATION_PATH>]WALLET_ID是设备级全局唯一标识,用于区分同时连接的多台设备;DERIVATION_PATH形式为<ACCOUNT>[/<CHANGE>],均为非负整数;- 所有派生路径隐含前缀
44'/501'(BIP44 规范,Solana 的 coin type 为 501),且由于 Solana 使用 Ed25519 密钥,派生全部为硬化派生,省略 hardened 符号是合法的。
查看 Wallet ID
在电脑上运行:
solana-keygen pubkey usb://ledger该命令用于确认 Ledger 设备连接正常且处于正确状态。它返回设备的唯一Wallet ID。若同一台电脑连接了多台 Nano,可用 Wallet ID 指定使用哪一台;如果每次只用一台,则无需携带 Wallet ID(参见下文"管理多台硬件钱包")。
usb://参数最终由RemoteWalletManager在 HID 层枚举设备。remote-wallet/src/ledger.rs 中硬编码了 Ledger 的厂商 ID 与各机型的产品 ID 白名单:
const LEDGER_VID: u16 = 0x2c97; const LEDGER_NANO_S_PIDS: [u16; 33] = [0x0001, 0x1000, 0x1001, /* ... */ 0x101f]; const LEDGER_NANO_X_PIDS: [u16; 33] = [0x0004, 0x4000, /* ... */ 0x401f]; const LEDGER_NANO_S_PLUS_PIDS: [u16; 33] = [0x0005, 0x5000, /* ... */ 0x501f];is_valid_ledger函数同时校验厂商 ID 与产品 ID,因此 Nano S、Nano X、Nano S Plus 均在支持列表内。
查看钱包地址(派生多个 keypair)
Nano 支持任意多个合法的钱包地址与签名者。查看任意地址的方式是用solana-keygen pubkey加一个合法的 keypair URL:
solana-keygen pubkey usb://ledger solana-keygen pubkey usb://ledger?key=0 solana-keygen pubkey usb://ledger?key=1 solana-keygen pubkey usb://ledger?key=2- 注意:在 zsh 下
keypair URL的参数会被忽略,解决方法见 故障排查。
key=后面可以取其他任意数值,这些命令显示的每个地址都是合法的 Solana 钱包地址,对应的私钥安全地保存在 Nano 内部,用于从该地址签名交易。要接收代币,只需记录用来派生该地址的 keypair URL。如果只打算使用一个地址,key=0是一个好记的默认选择:
solana-keygen pubkey usb://ledger?key=0得到地址后,可以公开分享地址作为收款地址,并把关联的 keypair URL 作为该地址交易的签名者。
URL 参数如何被解析
从源码看,?key=查询参数在 sdk/src/derivation_path.rs 的DerivationPath::from_uri_key_query中被解析为 BIP44 的 account/change 两级索引;而在 clap-utils/src/keypair.rs 的parse_signer_source中,usb://ledger?key=0/0会被拆成两部分:host 决定厂商(ledger),?key=决定派生路径,随后交给generate_remote_keypair完成设备选择与公钥读取(remote-wallet/src/remote_keypair.rs)。该函数生成的RemoteKeypair实现了Signer接口并声明is_interactive() == true,即每次签名都会触发设备端交互确认。
查看余额
查看任意账户余额(无论其使用哪个钱包),使用solana balance命令:
solana balance SOME_WALLET_ADDRESS例如,若你的地址是7cvkjYAkUYs4W8XcXsca7cBrEGFeSUjeZmKoNBvEwyri,则:
solana balance 7cvkjYAkUYs4W8XcXsca7cBrEGFeSUjeZmKoNBvEwyri也可以在浏览器端 Solana Explorer 的 Accounts 页面粘贴地址查看余额。
注意:余额为 0 SOL 的地址(比如刚在 Ledger 上新派生的地址)在 Explorer 中显示为 "Not Found"。在 Solana 中,空账户与不存在的账户是等同的;当账户中有 SOL 后,该现象会消失。
从 Nano 发送 SOL
要从 Nano 控制的地址发出转账,需要使用设备对交易进行签名,并沿用派生该地址时的同一个 keypair URL。操作前确认:Nano 已插入、已用 PIN 解锁、Ledger Live 未运行、Solana 应用处于 "Application is Ready" 状态。
solana transfer命令用于指定收款地址与转账数量,并通过--keypair参数指定签名者(也就是扣款方):
solana transfer RECIPIENT_ADDRESS AMOUNT --keypair KEYPAIR_URL_OF_SENDER完整示例:先查看某 keypair URL 对应的地址,再检查余额,最后执行转账 1 SOL:
~$ solana-keygen pubkey usb://ledger?key=42 CjeqzArkZt6xwdnZ9NZSf8D1CNJN1rjeFiyd8q7iLWAV ~$ solana balance CjeqzArkZt6xwdnZ9NZSf8D1CNJN1rjeFiyd8q7iLWAV 1.000005 SOL ~$ solana transfer 7cvkjYAkUYs4W8XcXsca7cBrEGFeSUjeZmKoNBvEwyri 1 --keypair usb://ledger?key=42 Waiting for your approval on Ledger hardware wallet usb://ledger/2JT2Xvy6T8hSmT8g6WdeDbHUgoeGdj6bE2VueCZUJmyN ✅ Approved Signature: kemu9jDEuPirKNRKiHan7ycybYsZp7pFefAdvWZRq5VRHCLgXTXaFVw3pfh87MQcWX4kQY4TjSBmESrwMApom1V按 Enter 执行 transfer 命令后,会在 Ledger 设备端弹出确认提示:在设备上用左右按键核对交易详情,若正确则在 "Approve" 界面同时按下两个按键,否则在 "Reject" 界面同时按下两个按键。
设备批准后,程序会打印交易签名,并等待最多 32 次确认(max number of confirmations)后返回,通常只需几秒,交易即最终确定。可以到浏览器端 Explorer 的 Transaction 页面粘贴签名查看详情。
签名过程在源码中的位置
"Waiting for your approval..." 与 "✅ Approved" 两行输出正是 remote-wallet/src/ledger.rs 中_send_apdu产生的:当 APDU 的 P1 为确认标志(P1_CONFIRM)且为最后一个分片时,CLI 会打印等待提示并在读取设备响应后打印批准标记。底层通过 HID 通道按 Ledger 传输协议分包发送 APDU(通信通道 ID + 命令 Tag + 序列号 + 负载),签名命令为SIGN_MESSAGE(INS0x06),读取公钥命令为GET_PUBKEY(INS0x05);对固件版本低于 0.2.0 的旧版 Solana 应用,会回退到已弃用的指令集(INS0x01/0x02/0x03,且负载头长度从 7 字节变为 8 字节)。较长的消息会按MAX_CHUNK_SIZE(255 字节)分片,用 P2 的MORE/EXTEND位标记续片,最后一帧清除MORE位,设备端据此完成整条消息的展示与签名。
高级操作:管理多台硬件钱包
有时需要用多台硬件钱包的密钥共同签名一笔交易。这要求使用fully qualified keypair URL(含 WALLET_ID)。当 URL 未完全限定(如仅写usb://ledger)时,Solana CLI 会交互提示:列出所有已连接硬件钱包的 fully qualified URL,让你为每个签名逐一选择设备。
若想跳过交互提示,可以用solanaCLI 的resolve-signer命令生成完全限定 URL。例如,将 Nano 连接 USB、用 PIN 解锁后运行:
solana resolve-signer usb://ledger?key=0/0输出类似:
usb://ledger/BsNsvfXqQTtJnagwFWdBS7FBXgnsK8VZ5CmuznN85swK?key=0/0其中BsNsvfXqQTtJnagwFWdBS7FBXgnsK8VZ5CmuznN85swK就是你的WALLET_ID。
拿到完全限定 URL 后,即可在同一台电脑连接多台硬件钱包,并唯一定位任意一台上的某个 keypair。把resolve-signer的输出用于任何接受<KEYPAIR>参数的solana命令位置,就能让该解析后的路径作为这笔交易中对应环节的签名者。
从源码看,resolve-signer在 cli/src/wallet.rs 中注册(描述为 "Checks that a signer is valid, and returns its specific path; useful for signers that may be specified generally, eg. usb://ledger"),其处理逻辑在 cli/src/cli.rs 中调用resolve_signer,最终走到 clap-utils/src/keypair.rs 的resolve_signer_from_path:对Usb类型的签名源,它会实际连接设备、按key=指定的派生路径生成RemoteKeypair,并返回keypair.path(形如usb://ledger/<WALLET_ID>?key=0/0)。设备选择逻辑在 remote-wallet/src/ledger.rs 的get_ledger_from_info中:当匹配到多台设备时,CLI 会弹出交互列表提示 "Multiple hardware wallets found. Please select a device for ...",这就是未限定 URL 时的交互选择来源。
故障排查
zsh 下 keypair URL 参数被忽略
问号字符在 zsh 中是特殊字符。如果不用该特性,可以在~/.zshrc中加入以下行把它当作普通字符处理:
unsetopt nomatch然后重启 shell 窗口或执行:
source ~/.zshrc如果不希望关闭 zsh 对问号的特殊处理,可以在 keypair URL 中用反斜杠显式转义,例如:
solana-keygen pubkey usb://ledger\?key=0其他常见现象速查
- 余额为 0 的地址在 Explorer 显示 "Not Found":属正常现象,空账户与不存在的账户在 Solana 中等同;
- 交易签名等待设备确认时:必须在设备端按键批准,设备端拒绝则交易不会发出;
- 设备识别失败时:从源码结构看,先确认设备厂商 ID 与产品 ID 是否在
remote-wallet/src/ledger.rs的白名单内,并确认 Solana 应用处于 "Application is ready" 状态。
延伸阅读
- 硬件钱包总览与 keypair URL 规范:URL 各字段(MANUFACTURER、WALLET_ID、DERIVATION_PATH)的完整定义与 BIP44 前缀说明;
- 安装 Solana 命令行工具:本文所有命令的前提;
- 发送与接收代币 和 委托质押:
solana命令中任何接受<KEYPAIR>的选项或参数,都可以直接填入你的 Ledger keypair URL; - 社区问答可参考 Solana StackExchange 上的相关讨论。
小结
本文以官方文档docs/src/cli/wallets/hardware/ledger.md为主线:从设备准备(关闭 Ledger Live、PIN 解锁、Application is ready)、solana-keygen pubkey usb://ledger查看 Wallet ID 与key=派生多个地址、solana balance查询余额、solana transfer --keypair usb://ledger?key=N设备端确认签名,到resolve-signer生成 fully qualified URL 管理多台设备,构成了硬件钱包在 Solana CLI 中的完整工作流。结合 remote-wallet 的 HID/APDU 协议实现与 clap-utils/src/keypair.rs 的签名源解析,可以确认:私钥始终留在 Ledger 设备内部,CLI 只负责发起 APDU 请求与读取签名结果,所有转账都必须在设备端人工批准。
【免费下载链接】solanaWeb-Scale Blockchain for fast, secure, scalable, decentralized apps and marketplaces.项目地址: https://gitcode.com/GitHub_Trending/so/solana
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考