Skip to Content
硬件接入概念标识符

标识符(Identifiers)

searchDevicesgetFeaturesgetPassphraseState 以及各链方法的响应里, 会出现若干个看起来都像”ID”的字段。这一页作为唯一权威参考,说明每个字段 到底代表什么、何时变化、在不同传输方式下格式差异是什么。

找的是传入 SDK 的参数passphraseStateinitSessionuseEmptyPassphrase 等)?请看 通用参数

四层标识符

每个标识符属于四类生命周期之一。知道它属于哪一类,就知道什么时候该刷新、什么 时候能长期缓存。

层级生命周期变化触发字段
物理硬件永久(跟硬件本体绑定)永不变化uuidonekey_serialserial_no
传输连接本次连接重新 searchDevices();换传输方式connectIdpathnamedeviceType
种子 / 钱包状态恢复出厂 / 擦除 / 恢复助记词之前恢复出厂、重新导入助记词、擦除device_id / deviceIdlabel
会话设备锁屏之前自动锁屏、手动锁、USB 断开session_idpassphraseState

哪些 ID 需要你传进去?

上面列的字段中只有 3 个 是你调用 SDK 时需要传进去的入参,其他全部只在响应里读。

ID需要传入?传在哪里什么时候必传?
connectId每个方法的第一个位置参数总是必传
deviceId签名 / 地址 / 加密类方法的第二个位置参数钱包级操作必传;设备管理操作可省
passphraseStateparams 对象里只在访问隐藏钱包(带 passphrase)时传
uuidonekey_serialdevice_idsession_idpathnamedeviceTypelabel❌ 仅响应字段

调用形态

// 设备级 —— 只要 connectId HardwareSDK.getFeatures(connectId); HardwareSDK.deviceLock(connectId, {}); HardwareSDK.getPassphraseState(connectId, { initSession: true }); // 钱包级(标准钱包)—— connectId + deviceId HardwareSDK.evmGetAddress(connectId, deviceId, { path: "m/44'/60'/0'/0/0", useEmptyPassphrase: true, }); // 钱包级(隐藏钱包)—— connectId + deviceId + passphraseState HardwareSDK.evmSignTransaction(connectId, deviceId, { path: "m/44'/60'/0'/0/0", transaction: { /* ... */ }, passphraseState, // 由 getPassphraseState 一次性获取 });

各方法的 ID 要求

类别适用场景代表方法
🟡 仅 connectId设备级操作(不触碰钱包状态)searchDevices · getFeatures · getPassphraseState · deviceLock · deviceUnlock · deviceWipe · deviceSettings · deviceVerify · cancel · checkFirmwareRelease · checkBootloaderRelease
🔵 connectId + deviceId钱包级:地址派生 / 签名 / 加密evmGetAddress · evmSignTransaction · evmSignMessage · btcGetAddress · btcSignTransaction · btcSignPsbt · solGetAddress · solSignMessage · nostrEncryptMessage · allNetworkGetAddress · 所有其他链方法
🟣 connectId + deviceId + passphraseState和 🔵 相同,但访问的是带 passphrase 的隐藏钱包🔵 里所有方法,params 里带非空 passphraseState

漏传 / 传错的后果

漏传 / 传错SDK 行为
connectId 缺失或未知DeviceNotFound —— SDK 不知道要路由到哪台设备
deviceId 不对(中途换了种子)DeviceCheckDeviceIdError —— SDK 拒绝在另一个种子上签名
访问隐藏钱包漏传 passphraseState⚠️ 返回标准钱包的结果,无任何报错 —— 地址 / 签名都是另一个钱包的
passphraseState 不匹配当前 session错误码 112(passphrase state mismatch)—— session 过期或隐藏钱包变了
passphraseStateuseEmptyPassphrase: true 同时传passphraseState 优先(走隐藏钱包)——useEmptyPassphrase 被忽略

⚠️ 第三行是最坑的:隐藏钱包调用时漏传 passphraseState,拿到的是标准钱包的地址/签名,完全没有报错。所以隐藏钱包场景里,getPassphraseState 拿一次 passphraseState 之后必须挂到后续所有钱包级调用上;如果明确就是要走标准钱包,就显式传 useEmptyPassphrase: true,别把它留空。

物理硬件标识符

不可变值,标识物理设备本体。重置、换种子、升级固件后都不变

字段来源格式说明
uuidsearchDevices()[].uuid依传输方式(见下)USB 传输时和 connectId 相同。BLE 上可能和 OS 层的 connectId 不同。
onekey_serial / onekey_serial_nogetFeatures().payloadCLB21J0013 这种格式出厂分配;印在设备 / 包装盒上

传输连接标识符

标识一次具体连接。同一台物理设备在 USB 和 BLE 下的 connectId 不一样, 不能互换使用。

connectId —— 路由用的 key

每次调用 SDK 方法都要把 connectId 作为第一个参数,SDK 据此判断请求发给哪台 设备 / 哪个连接。同传输下的多次 searchDevices() 返回相同值。

传输方式connectId 格式例子
WebUSB设备序列号PRC10J0017A
Bridge设备序列号PRC10J0017A
node-usb (CLI)设备序列号CLB21J0013
Android BLEMAC 地址AA:BB:CC:DD:EE:FF
iOS BLECoreBluetooth UUIDXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
Desktop BLE(Electron/Noble,macOS)32 位小写十六进制 UUID1f6dad0b8782aab31d2f7ae2b11e5b6c
Desktop BLE(Electron/Noble,Windows)12 位小写十六进制 MAC(无冒号)e4e65539cf33
Desktop BLE(Electron/Noble,Linux)MAC 地址AA:BB:CC:DD:EE:FF

⚠️ 如果你的应用同时支持 USB 和 BLE 连同一台设备,必须按传输分别缓存 connectId,两套值不能互用。

其他传输层字段

字段作用典型值说明
path底层总线路径USB: 设备路径或 device_id;BLE: undefined实现细节 —— 调用路由请始终用 connectId,不要用 path
name展示用的人类可读标签USB: 设备 label;BLE: 广播名仅用于 UI 展示,不参与路由。
deviceType设备型号classic / classic1s / classicpure / mini / touch / pro用于按型号分支能力(如按键机型才走 PIN matrix 流程)。取值来自 EDeviceType

种子 / 钱包状态标识符

deviceIdsearchDevices 响应里)和 device_idgetFeatures 响应里) 是同一个值,表示设备上当前加载的种子。

deviceId 会变deviceId 不变
恢复出厂重启
恢复助记词(换种子)锁 / 解锁
”Wipe” + 重新初始化重新插拔 USB
在测试 / 正式种子间切换(开发机)改 passphrase

用法

const { payload: features } = await HardwareSDK.getFeatures(connectId); const deviceId = features.device_id; // 每次签名调用都带上 deviceId —— SDK 用它检测过程中种子是否变了, // 变了就抛 `DeviceCheckDeviceIdError` 阻止签在错的种子上 await HardwareSDK.evmSignTransaction(connectId, deviceId, { ... });

遇到 DeviceCheckDeviceIdError 就重新 getFeatures(connectId) 并更新缓存 的 deviceId

会话标识符

两个会话层字段名字类似但作用不同。

session_id —— 短期会话 token

设备初始化 passphrase session 时临时生成的随机 token。 getPassphraseState 或任何触发 session 初始化的调用之后,会出现在 features.session_id 里。

  • 锁屏即失效(自动锁、手动锁、USB 断开)。
  • SDK 内部用它维持设备端缓存的 passphrase。
  • 一般不直接暴露给应用代码 —— 大多数应用只需要 passphraseState

passphraseState —— 隐藏钱包标识

和某个 passphrase 绑定的确定性隐藏钱包标识。getPassphraseState() 返 回。同一个种子 + 同一个 passphrase 永远产生同一个 passphraseState, 所以你可以用它来判断”这是不是同一个之前看到过的隐藏钱包”,而不必保存 passphrase 本身。

  • 作为 passphraseState 通用参数传给后续所有需要绑在这个隐藏钱包上的 SDK 调用。
  • 跨进程复用:持久化 (deviceId, passphraseState, session_id) 三元组,进程 启动时调 preloadSessionCache 恢复 session。
  • 清掉缓存的 passphraseState 不会让隐藏钱包失效 —— 用户再输一次同样的 passphrase 就能复现出相同的钱包。
session_idpassphraseState
生命周期锁屏前事实上永久(passphrase 不变就不变)
是否确定性每次会话随机按 passphrase 确定性
角色保持设备侧 session 有效指明”是哪一个隐藏钱包”

实例拼装

通过 USB(node-usb 传输)连接 Classic 1S 时,searchDevices() 返回:

{ "connectId": "CLB21J0013", // 传输层(USB 下 = 设备序列号) "uuid": "CLB21J0013", // 物理层(USB 下 = connectId) "deviceType": "classic1s", // 传输层 "deviceId": "399A2470958EDB3D9F3826C2", // 种子状态;重置后会变 "path": "399A2470958EDB3D9F3826C2", // 传输内部;各传输不一样 "name": "OneKey Classic 1S" // 展示标签 }

继续调 getFeatures(connectId) 会拿到:

{ "device_id": "399A2470958EDB3D9F3826C2", // 和上面 deviceId 相同 "onekey_serial": "CLB21J0013", // 物理;USB 下和 connectId 相同 "session_id": "80cb8aef933870e4…", // 短期;锁屏后重置 "passphrase_protection": true, "unlocked": true, "label": "OneKey Classic 1S" }

用户输完 passphrase 后,getPassphraseState(connectId) 返回:

{ "success": true, "payload": "abc123…" // passphraseState —— 后续调用带上它 }

常见混淆

connectId vs uuid

USB 下两者是同一个字符串(都是设备序列号)。BLE 下可能不一样: connectId 是 OS 层的连接句柄(MAC / CoreBluetooth UUID / …),uuid 则是 SDK 层暴露给应用用的稳定 ID。路由始终用 connectId;如果需要一个跨传输 稳定的 ID 做展示用途,再考虑 uuid

deviceId vs uuid / onekey_serial

  • deviceId —— 重置 / 换种子后会变。用来回答*“这还是同一个钱包吗?”*
  • uuid / onekey_serial —— 永不变化。用来回答*“这还是同一台物理设备 吗?“*

session_id vs passphraseState

  • session_id 锁屏即失效;passphraseState 不会。
  • passphraseState 标识是哪一个隐藏钱包session_id 标识这条还活着 的会话
  • 跨调用复用会话就一起持久化 (passphraseState, session_id);如果两次调用 之间设备锁屏了,就丢掉缓存的 session_id、强制重新解锁。

device_id(蛇形)vs deviceId(驼峰)

同一个值,两种上下文:

  • device_id 出现在 getFeatures().payload(固件层,蛇形命名)。
  • deviceId 出现在 searchDevices()[] 里以及大多数 SDK 方法的第二个位置参 数(JS 层,驼峰命名)。

参考

Last updated on