Skip to Content
HardwareCore API Guide

Hardware SDK Core API Guide

Lifecycle how-to: init → search → events → first protected call → cleanup.

Parameter tables live in Common Params. Device and protocol differences live in Devices and Protocol V1 and V2.

Quick flow

  • Call shape: HardwareSDK.method(connectId, deviceId?, params) → Promise<{ success, payload }>; always guard on success before touching payload.
  • Identifiers: connectId from searchDevices; deviceId from getDeviceState (required for BLE, recommended for WebUSB). Refresh deviceId after reset/recovery. Full table: Identifiers.
  • UI contract: subscribe UI_EVENT once; only call uiResponse on input-type UI_REQUEST (PIN / Passphrase / Bootloader select). Route per device when several devices are connected.
  • Serialize calls per device. Reuse a hidden wallet by passing passphraseState on later methods (compatibility path: initSession + passphraseState). Do not call openWalletSession again for that.
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);

Interaction flow

Core identifiers & environments

IDPurposeObtain viaChanges when
connectIdWhich connectionsearchDevices()USB re-plug, BLE re-pair, transport switch
deviceIdWhich seed lifetimegetDeviceState (getFeatures is deprecated)Wipe, recovery, seed switch

USB and BLE connectId values for the same unit are different — cache them separately. See Identifiers and Disconnects and reconnection.

Runtime requirements

  • webusb — HTTPS + user gesture.
  • react-native — BLE entitlement + (commonly) location permission.
  • lowlevel — host BLE adapter forwarding raw notification chunks.
  • Firmware — some APIs fail in Bootloader.

Which identifiers are required?

RequirementDescriptionExample APIs
🟢 No identifiersSDK init, config, event managementinit on/off searchDevices getLogs dispose uiResponse
🟡 connectId onlyDevice management, status, firmware opsgetDeviceState openWalletSession cancel deviceSettings
🔵 connectId + deviceIdBlockchain signing, address, encryptionevmSignTransaction btcSignTransaction solSignMessage allNetworkGetAddress

init → search → getDeviceState → subscribe 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);

Serialize per device. Refresh getDeviceState after a device switch. Remove listeners on unmount. Call HardwareSDK.dispose() only when tearing down the transport — see Disconnects and reconnection.

Common params

The full table, transport matrix, combos, and HD paths moved to Common Params.

HD path examples: Common Params → HD path.

For PIN and passphrase UX see PIN and Passphrase. New wallet-open code should use Wallet Sessions.

Events & UI wiring

Subscribe once near app start. Only call uiResponse for input requests. Copy payload.responseCorrelation onto each response when present; it identifies the pending interaction. Invalidate modal callbacks after cancellation or a UI-close event, and cancel the selected connection when the user dismisses input. Do not log UI event payloads or input values.

UI requests that require uiResponse

UI_REQUESTWhen it firesRespond with
REQUEST_PINHost PIN input request; device-only prompts need no replyUI_RESPONSE.RECEIVE_PIN
REQUEST_PASSPHRASESelect host or device input (value: "", passphraseOnDevice: true for device input)UI_RESPONSE.RECEIVE_PASSPHRASE
REQUEST_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICEWeb Bootloader chooserUI_RESPONSE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE

UI notifications (no uiResponse)

UI_REQUESTPurpose
REQUEST_PASSPHRASE_ON_DEVICEEnter the passphrase on the device; notification only
REQUEST_BUTTONConfirm on device. Firmware update uses reason='firmware-update' — still no uiResponse
DEVICE_PROGRESSLong-running task progress
FIRMWARE_PROCESSING / FIRMWARE_PROGRESS / FIRMWARE_TIPFirmware upgrade states
BLUETOOTH_PERMISSION / LOCATION_PERMISSIONBLE permission prompts
BOOTLOADER / REQUIRE_MODE / NOT_INITIALIZE / FIRMWARE_NOT_SUPPORTEDMode or support hints

Device / firmware events

ChannelEventTypical handling
DEVICE.CONNECTdirect payloadRefresh device list
DEVICE.DISCONNECTdirect payloadInvalidate the connection; do not replay side-effecting calls. Reconnect
DEVICE.STATE / DEVICE.FEATURES / DEVICE.SUPPORT_FEATURESdirect payloadUpdate device state / features / supported features
FIRMWARE_EVENTRELEASE_INFO / BLE_RELEASE_INFOOffer upgrade when safe. Firmware Update
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);

Errors

GroupCommon causesRecommended actions
Device (101–118, 200)Wrong mode, busy, deviceId mismatch, not initializedConfirm mode, reconnect, re-run init + getDeviceState
IFrame (300–305)Init missing, load/timeout/blockedEnsure init succeeded; check CSP / iframe
Method/Firmware (400–418)Bad params, firmware required, forbidden pathValidate HD path; Firmware Update
Transport (600–603)Transport not configured, concurrent callCheck env, serialize calls
Bluetooth (700–722)Scan/permission/connect/timeoutPermission, proximity; do not loop on a stale bond
Runtime/Bridge (800–822)PIN cancelled, Bridge timeoutRespect cancellation; recover the connection without automatically replaying signing
Web device (901–902)WebUSB not authorizedHTTPS + user gesture

Map payload.code, not payload.error text. Definitions: HardwareError.ts.

Last updated on