Skip to Content
硬件接入开发指南

硬件 SDK 核心接口指南

本指南按生命周期介绍:初始化 → 发现设备 → 事件处理 → 第一次受保护调用 → 清理。

参数表在 通用参数。机型和协议差异在 设备 和 Protocol V1 与 V2。

快速流程

  • 方法签名:HardwareSDK.method(connectId, deviceId?, params) → Promise<{ success, payload }>,先判断 success 再读 payload
  • 标识:connectId 来自 searchDevices;deviceId 来自 getDeviceState(BLE 必填,WebUSB 建议带)。擦除 / 恢复后刷新 deviceId。完整表:标识符
  • 事件:入口订一次 UI_EVENT,只对输入类 UI_REQUEST(PIN / Passphrase / Bootloader 选择)调用 uiResponse
  • 同一设备串行调用。隐藏钱包之后带 passphraseState 即可(兼容路径用 initSession + passphraseState)。不要为此再调一次 openWalletSession。
const res = await HardwareSDK.evmGetAddress(connectId, deviceId, { path: "m/44'/60'/0'/0/0", useEmptyPassphrase: true, }); if (!res.success) throw new Error(res.payload.error); console.log(res.payload.address);

交互流程

核心标识与环境

标识作用获取来源何时变化
connectId哪条连接searchDevices()USB 重插、BLE 重新配对、切换传输
deviceId哪一次种子生命周期getDeviceState(getFeatures 已废弃)擦除、恢复、换种子

同一台设备的 USB 和 BLE connectId 不同,要分开缓存。见 标识符 和 断线与重连。

运行时要求

  • webusb — HTTPS + 用户手势
  • react-native — 系统蓝牙权限;位置权限取决于 Android 版本和扫描用途
  • lowlevel — 宿主侧 BLE 适配器,转发原始通知数据块
  • 固件 — Bootloader 下部分 API 会失败

哪些标识是必填的?

要求说明示例 API
🟢 不需要标识初始化、配置、事件init on/off searchDevices getLogs dispose uiResponse
🟡 只要 connectId设备管理、状态、固件getDeviceState openWalletSession cancel deviceSettings
🔵 connectId + deviceId链上签名、地址、加密evmSignTransaction btcSignTransaction solSignMessage allNetworkGetAddress

标准生命周期

init → search → getDeviceState → 订阅 UI/DEVICE/FIRMWARE → call + uiResponse → cleanup

import HardwareSDK from '@onekeyfe/hd-common-connect-sdk'; import { UI_EVENT, UI_REQUEST, UI_RESPONSE } from '@onekeyfe/hd-core'; const initialized = await HardwareSDK.init({ env: 'webusb', fetchConfig: true, debug: false }); if (!initialized) throw new Error('SDK initialization failed'); const devices = await HardwareSDK.searchDevices(); if (!devices.success || !devices.payload.length) throw new Error('No device'); // Select explicitly in the application when more than one device is available. if (devices.payload.length !== 1) throw new Error('Select exactly one device before continuing'); const { connectId } = devices.payload[0]; if (!connectId) throw new Error("Missing connectId"); const state = await HardwareSDK.getDeviceState(connectId); if (!state.success) throw new Error(state.payload.error); const deviceId = state.payload.identity.deviceId; if (!deviceId) throw new Error("Device has no wallet identity"); // Register the UI_EVENT handler shown below before any protected call. HardwareSDK.on(UI_EVENT, handleUiEvent); const address = await HardwareSDK.evmGetAddress(connectId, deviceId, { path: "m/44'/60'/0'/0/0", useEmptyPassphrase: true, }); if (!address.success) throw new Error(address.payload.error);

同一设备串行。切换设备后重新读取 getDeviceState。卸载时移除监听。只有拆除传输时才 HardwareSDK.dispose() —— 见 断线与重连。

通用参数

完整表格、传输差异、组合和 HD Path 已移到 通用参数。

HD Path 示例:通用参数 → HD Path。

PIN / passphrase 交互见 PIN 和 Passphrase。新的开钱包代码用 钱包会话。

事件处理

在应用入口订阅一次。只对输入请求调用 uiResponse。请求包含 payload.responseCorrelation 时,将其中字段展开到每次响应顶层,用于关联待处理交互。取消或 UI 关闭后使弹窗回调失效;用户取消输入时取消所选连接上的操作。不要记录 UI 事件 payload 或输入值。

需要 uiResponse 的 UI 请求

UI_REQUEST触发时机应答
REQUEST_PIN请求宿主输入 PIN;设备输入提示无需回复UI_RESPONSE.RECEIVE_PIN
REQUEST_PASSPHRASE选择软件或设备输入;设备输入回复 value: ""、passphraseOnDevice: trueUI_RESPONSE.RECEIVE_PASSPHRASE
REQUEST_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICEWeb Bootloader 选择UI_RESPONSE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE

仅展示(不要 uiResponse)

UI_REQUEST作用
REQUEST_PASSPHRASE_ON_DEVICE在设备输入 passphrase,仅通知,无需回复
REQUEST_BUTTON请在设备确认。固件升级的 reason='firmware-update' 同样不要 uiResponse
DEVICE_PROGRESS长耗时进度
FIRMWARE_PROCESSING / FIRMWARE_PROGRESS / FIRMWARE_TIP固件升级状态
BLUETOOTH_PERMISSION / LOCATION_PERMISSIONBLE 权限
BOOTLOADER / REQUIRE_MODE / NOT_INITIALIZE / FIRMWARE_NOT_SUPPORTED模式 / 支持性提示

设备 / 固件事件

通道事件建议动作
DEVICE.CONNECT直接 payload刷新设备列表
DEVICE.DISCONNECT直接 payload连接作废;不要重放有副作用的调用。重连
DEVICE.STATE / DEVICE.FEATURES / DEVICE.SUPPORT_FEATURES直接 payload更新状态、features 或支持能力
FIRMWARE_EVENTRELEASE_INFO / BLE_RELEASE_INFO安全时机提示升级。固件升级
import HardwareSDK from '@onekeyfe/hd-common-connect-sdk'; import { UI_EVENT, UI_REQUEST, UI_RESPONSE } from '@onekeyfe/hd-core'; import type { UiEventMessage } from '@onekeyfe/hd-core'; // These modal functions are provided by your application's UI. declare function openPinModal(submit: (input: { value: string }) => void): void; declare function openPassphraseModal(submit: (input: { value: string; onDevice: boolean; save: boolean }) => void): void; const handleUiEvent = (msg: UiEventMessage) => { switch (msg.type) { case UI_REQUEST.REQUEST_PIN: if (msg.payload.deviceOnly || msg.payload.type === 'ButtonRequest_PinEntry' || msg.payload.type === 'ButtonRequest_AttachPin') { // Display an on-device prompt; no uiResponse is needed. return; } openPinModal(({ value }) => HardwareSDK.uiResponse({ ...msg.payload.responseCorrelation, type: UI_RESPONSE.RECEIVE_PIN, payload: value }) ); return; case UI_REQUEST.REQUEST_PASSPHRASE: if (msg.payload.deviceOnly) { HardwareSDK.uiResponse({ ...msg.payload.responseCorrelation, type: UI_RESPONSE.RECEIVE_PASSPHRASE, payload: { value: '', passphraseOnDevice: true, save: false }, }); return; } openPassphraseModal(({ value, onDevice, save }) => HardwareSDK.uiResponse({ ...msg.payload.responseCorrelation, type: UI_RESPONSE.RECEIVE_PASSPHRASE, payload: { value: onDevice ? "" : value, passphraseOnDevice: onDevice, attachPinOnDevice: false, save }, }) ); return; default: break; } }; HardwareSDK.on(UI_EVENT, handleUiEvent);

错误处理

分组常见原因建议动作
Device (101–118, 200)模式错误、忙、deviceId 不匹配、未初始化确认模式,重连后 init + getDeviceState
IFrame (300–305)未 init、加载/超时/拦截确认 init 成功;检查 CSP / iframe
Method/Firmware (400–418)参数错误、必须升级、forbidden path校验 HD Path;固件升级
Transport (600–603)传输未配置、并发调用检查 env,串行调用
Bluetooth (700–722)扫描/权限/连接/超时权限与距离;绑定过期不要死循环
Runtime/Bridge (800–822)PIN 取消、Bridge 超时尊重取消结果;恢复连接时不自动重放签名
Web device (901–902)WebUSB 未授权HTTPS + 用户手势

认 payload.code,不要解析 payload.error 文案。定义见 HardwareError.ts。

相关链接

最后更新于