Skip to Content

Hardware SDK Core API Guide

Single-page guide for integrators: happy path + params/events/safety/error handling in one place.

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 getFeatures (required for BLE, recommended for WebUSB). Refresh after reset/recovery.
  • UI contract: subscribe UI_EVENT once; only call uiResponse on input-type UI_REQUEST (PIN/Passphrase/Bootloader select). Route per device when multiple devices are connected.
  • Param hygiene: validate HD Path per chain; reuse hidden wallet with initSession + passphraseState; serialize calls per device to avoid deadlocks.
const res = await HardwareSDK.evmGetAddress(connectId, deviceId, { path: "m/44'/60'/0'/0/0", }); if (!res.success) throw new Error(res.payload.error); console.log(res.payload.address);

Interaction flow (visual)

Hardware SDK request/response flow

Core identifiers & environments

ItemPurposeHow to get/refreshNotes
connectIdConnection identifier; routes calls to a specific device/connectionsearchDevices()WebUSB/Bridge ≈ device serial; BLE = OS-level identifier (Android MAC / iOS UUID).
deviceIdCurrent seed/wallet-state identifiergetFeatures(connectId)Changes after wipe/recovery/seed switch; used to prevent signing on the wrong seed.
  • Cache connectId + deviceId as a pair; on DeviceCheckDeviceIdError or device switch, re-run getFeatures.
  • SDK set: @onekeyfe/hd-common-connect-sdk + @onekeyfe/hd-core + @onekeyfe/hd-shared; align versions with firmware/Bridge.
  • Runtime: webusb needs HTTPS + user gesture; react-native needs BLE + often location permission; lowlevel needs 64-byte frame adapter.
  • Device/firmware: stay on latest stable; some APIs fail in Bootloader; Bridge must run and keep port free.

Standard loop: init → search → getFeatures(connectId) → subscribe UI/DEVICE/FIRMWARE → call + uiResponse → cleanup

import HardwareSDK, { UI_EVENT, UI_REQUEST, UI_RESPONSE } from '@onekeyfe/hd-common-connect-sdk'; // 1) Idempotent init (do once at app entry) await HardwareSDK.init({ env: 'webusb', fetchConfig: true, debug: false }); // 2) Discover devices const devices = await HardwareSDK.searchDevices(); if (!devices.length) throw new Error('No device'); const [{ connectId }] = devices; // 3) Resolve deviceId (required for BLE; recommended for WebUSB) const features = await HardwareSDK.getFeatures(connectId); const deviceId = features?.payload?.device_id; // 4) Subscribe UI events; respond only on request HardwareSDK.on(UI_REQUEST.REQUEST_PIN, () => { // open UI, collect input, then call uiResponse }); HardwareSDK.on(UI_REQUEST.REQUEST_PASSPHRASE, () => {}); // 5) Make a chain call (EVM example) await HardwareSDK.evmSignTransaction(connectId, deviceId, { path: "m/44'/60'/0'/0/0", });

Concurrency/cleanup: serialize per device; refresh getFeatures when switching devices; remove listeners on unmount; call HardwareSDK.dispose() only when transport reset is needed.

Params & paths (essentials)

Common params

ParamPurposeTypical usage
initSession?: booleanForce a hardware session init; can pair with passphrase state retrievalPre-build session before first call to reduce prompts
passphraseState?: stringHidden wallet identifier; include to bind to that hidden walletRequired when using a hidden wallet to stay on the same one
useEmptyPassphrase?: booleanForce standard wallet (empty)Prevent accidental hidden wallet
deriveCardano?: booleanPre-derive CardanoFirst Cardano call in a session
retryCount? / pollIntervalTime? / timeout?Polling/timeout tuningBLE or flaky network scenarios
detectBootloaderDevice?: booleanFail fast in BootloaderAsk user to exit Bootloader
skipWebDevicePrompt?: booleanSkip WebUSB chooserReuse prior WebUSB authorization
keepSession?(Deprecated; avoid using)Use initSession + passphraseState instead

Common combo:

// Hidden wallet + multiple calls without repeated prompts const commonParams = { initSession: true, keepSession: true, passphraseState: 'hidden-wallet-id', }; await HardwareSDK.evmSignMessage(connectId, deviceId, { path: "m/44'/60'/0'/0/0", messageHex, ...commonParams, });

HD path quick ref

  • Rule: path: string | number[] follows BIP44; ed25519 chains (e.g., Solana, NEAR) must be fully hardened.
  • Common paths:
ChainExample pathNotes
EVMm/44'/60'/0'/0/0Standard EVM account
BTC (Nested SegWit)m/49'/0'/0'/0/0Use 84’ for Native SegWit
Solanam/44'/501'/0'/0'Fully hardened
NEARm/44'/397'/0'/0'/1'Fully hardened
Cardanom/1852'/1815'/0'/0/0Stake at .../2/0
TRONm/44'/195'/0'/0/0EVM-style path
  • Number array example: [(44 | 0x80000000) >>> 0, (0 | 0x80000000) >>> 0, 0x80000000, 0, 0]
  • Forbidden path errors: verify length/hardening per chain; see chain-specific pages in the sidebar.

Secure input (PIN & passphrase)

  • PIN: Pro/Touch require on-device input; others support blind PIN but prefer on-device input.
const BLIND_KEYBOARD_MAP = ['7', '8', '9', '4', '5', '6', '1', '2', '3']; HardwareSDK.uiResponse({ type: UI_RESPONSE.RECEIVE_PIN, payload: BLIND_KEYBOARD_MAP[label - 1], });
  • Passphrase: empty string = standard wallet; non-empty = hidden wallet (case-sensitive).
    • Safest: passphraseOnDevice: true
    • Software input: { value, passphraseOnDevice: false, save: true } is session-only; never persist plaintext.
    • Avoid accidental hidden wallet: add useEmptyPassphrase: true in method params.

Events & UI wiring

  • Channels: UI_EVENT (prompts), DEVICE_EVENT (connection/capability changes), FIRMWARE_EVENT (upgrade info). Subscribe once near app start; clean up on exit.
  • Only call uiResponse for input requests; use other notifications to drive UI hints; route per device when multiple devices are connected.

UI requests that require uiResponse

UI_REQUESTWhen it firesRespond with
REQUEST_PINProtected call on a locked deviceUI_RESPONSE.RECEIVE_PIN (payload is PIN value or blind PIN map)
REQUEST_PASSPHRASEHidden wallet selection via software inputUI_RESPONSE.RECEIVE_PASSPHRASE (value, passphraseOnDevice, attachPinOnDevice, save)
REQUEST_PASSPHRASE_ON_DEVICEHidden wallet selection on deviceUI_RESPONSE.RECEIVE_PASSPHRASE (passphraseOnDevice: true)
REQUEST_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICEWeb Bootloader device chooserUI_RESPONSE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE (deviceId)

UI notifications (no response needed)

UI_REQUESTPurpose
REQUEST_BUTTONAsk user to confirm on device
DEVICE_PROGRESSLong-running task progress
FIRMWARE_PROCESSING / FIRMWARE_PROGRESS / FIRMWARE_TIPFirmware upgrade/processing states
BLUETOOTH_PERMISSION / LOCATION_PERMISSIONSystem permission prompts for BLE
BOOTLOADER / REQUIRE_MODE / NOT_INITIALIZE / FIRMWARE_NOT_SUPPORTEDMode or support hints to display in UI

Device/Firmware events to observe

ChannelEventMeaningTypical handling
DEVICE_EVENTCONNECTDevice attached and availableRefresh device list, optionally auto-select
DEVICE_EVENTDISCONNECTDevice removed or BLE lostMark session invalid, prompt user to reconnect
DEVICE_EVENTACQUIRETransport session startedGate concurrent calls, mark device busy
DEVICE_EVENTRELEASETransport session endedAllow next queued request
DEVICE_EVENTCHANGEDFeatures changed (e.g., after unlock)Re-fetch getFeatures and refresh cached deviceId
DEVICE_EVENTUSED_ELSEWHERETransport conflict detectedAsk user to close other apps/bridges
DEVICE_EVENTUNREADABLEPermission or driver issuePrompt re-authorization or driver check
DEVICE_EVENTBUTTONDevice is waiting for confirmationShow “confirm on device” hint
DEVICE_EVENTPINDevice is waiting for PINKeep UI in PIN flow
DEVICE_EVENTPASSPHRASEDevice is waiting for software passphraseKeep UI in passphrase flow
DEVICE_EVENTPASSPHRASE_ON_DEVICEDevice is waiting for on-device passphraseShow device input hint
DEVICE_EVENTSELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICEBootloader selection in progressKeep chooser visible until resolved
DEVICE_EVENTFEATURESCapability snapshotCache capabilities for later checks
DEVICE_EVENTSUPPORT_FEATURESSupported capability snapshotCache support matrix
FIRMWARE_EVENTRELEASE_INFONew firmware infoOffer upgrade prompt when safe
FIRMWARE_EVENTBLE_RELEASE_INFONew BLE firmware infoOffer upgrade prompt when safe

Wiring template

import HardwareSDK, { UI_EVENT, UI_REQUEST, UI_RESPONSE } from '@onekeyfe/hd-common-connect-sdk'; const handleUiEvent = (msg: any) => { switch (msg.type) { case UI_REQUEST.REQUEST_PIN: openPinModal(({ value }) => HardwareSDK.uiResponse({ type: UI_RESPONSE.RECEIVE_PIN, payload: value }) ); return; case UI_REQUEST.REQUEST_PASSPHRASE: openPassphraseModal(({ value, onDevice, save }) => HardwareSDK.uiResponse({ type: UI_RESPONSE.RECEIVE_PASSPHRASE, payload: { value, passphraseOnDevice: onDevice, attachPinOnDevice: false, save }, }) ); return; case UI_REQUEST.REQUEST_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE: showDeviceList((deviceId: string) => HardwareSDK.uiResponse({ type: UI_RESPONSE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE, payload: { deviceId }, }) ); return; default: console.log('UI event', msg.type, msg.payload); } }; HardwareSDK.on(UI_EVENT, handleUiEvent);

Errors & checklist

GroupCommon causesRecommended actions
Device (101–118, 200)Wrong mode, busy, device_id mismatch, not initializedAsk user to confirm device mode, reconnect, re-run init + getFeatures
IFrame (300–305)Init missing, load/timeout/blockedEnsure init succeeded and CSP/iframe allow it
Method/Firmware (400–418)Bad params, firmware upgrade required, forbidden pathValidate params/HD path, prompt firmware upgrade
Transport (600–603)Transport not configured, concurrent call, protobuf errorCheck env/Bridge, serialize calls, align SDK version
Bluetooth (700–722)Scan/permission/connect/timeoutEnsure BLE/location permission, proximity/power, retry connect
Runtime/Bridge (800–821)PIN/action cancelled, Bridge permission/timeout, blind sign disabledRetry, ask to install/start Bridge, ensure signing mode
Web device (901–902)WebUSB/Bluetooth not authorized or chooser failureAsk user to re-authorize; ensure HTTPS + user gesture

More detail: see HardwareError.ts for exhaustive definitions and payload shapes.

Pattern: map error → user message + developer action; provide UI buttons for retry/check device/upgrade firmware.

Quick checklist

  1. Init once; confirm env/permissions/HTTPS; keep connectId + deviceId
  2. Subscribe UI/DEVICE/FIRMWARE; send uiResponse only after events
  3. Serialize per device; combine CommonParams (keepSession/passphraseState)
  4. Use valid HD paths; if errors, check chain docs and hardening rules
  5. Map error codes to user text and dev actions; prompt firmware/Bridge updates when needed

Related links

  • Getting Started (install + first call): quick start
  • Transports: WebUSB · React Native BLE · iOS/Android low-level adapters
  • Chain APIs: sidebar sign / getAddress method pages by chain
  • Legacy migration: bridge-to-common-connect/WebUSB migration guides
Last updated on