本页目录
硬件 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: true | UI_RESPONSE.RECEIVE_PASSPHRASE |
REQUEST_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE | Web 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_PERMISSION | BLE 权限 |
BOOTLOADER / REQUIRE_MODE / NOT_INITIALIZE / FIRMWARE_NOT_SUPPORTED | 模式 / 支持性提示 |
设备 / 固件事件
| 通道 | 事件 | 建议动作 |
|---|---|---|
DEVICE.CONNECT | 直接 payload | 刷新设备列表 |
DEVICE.DISCONNECT | 直接 payload | 连接作废;不要重放有副作用的调用。重连 |
DEVICE.STATE / DEVICE.FEATURES / DEVICE.SUPPORT_FEATURES | 直接 payload | 更新状态、features 或支持能力 |
FIRMWARE_EVENT | RELEASE_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。
相关链接
最后更新于