Skip to Content

Getting Started

This guide covers the complete flow for integrating OneKey hardware wallet: install the SDK, initialize, discover devices, handle UI prompts, and make your first signing call.

Transport Overview

USB integrations should use @onekeyfe/hd-common-connect-sdk; use @onekeyfe/hd-web-sdk only when the host mandates an iframe/plugin setup.

Connection Methods

MethodDescriptionSupported devices
USB / WebUSBWired USB; Web via WebUSB, native via low-level pluginAll OneKey devices
Bluetooth BLE (native)Native apps over BLE (not Web Bluetooth); requires OS Bluetooth & permissionOneKey Pro, Touch, Classic 1s / Classic 1s Pure; Mini does not support BLE
Air-Gap (QR)Offline QR signingOneKey Pro only

Choose Your Transport (aligned with overview)

PlatformTransportSDK PackageGuide
Web (Browser)WebUSB@onekeyfe/hd-common-connect-sdkWebUSB Connection Guide
React NativeBLE@onekeyfe/hd-ble-sdkReact Native BLE
Android (Native)BLE@onekeyfe/hd-common-connect-sdkAndroid BLE
iOS (Native)BLE@onekeyfe/hd-common-connect-sdkiOS BLE
FlutterBLE@onekeyfe/hd-common-connect-sdkFlutter BLE

Transport architecture

Low-level protocol and custom channels: Low-Level Transport Plugin & Protocol

Install SDK

Pick one entry by runtime:

Install as needed (pick one):

# Web / desktop WebUSB (recommended) npm i @onekeyfe/hd-common-connect-sdk # React Native BLE npm i @onekeyfe/hd-ble-sdk # Native host with low-level plugin (Android/iOS/Flutter bridge) npm i @onekeyfe/hd-common-connect-sdk # Plugin iframe host only (legacy) npm i @onekeyfe/hd-web-sdk

Transport details:

Initialize the SDK

Use the initialization method that matches your runtime—avoid mixing SDK entries.

Web / desktop WebUSB (@onekeyfe/hd-common-connect-sdk)

import HardwareSDK from '@onekeyfe/hd-common-connect-sdk'; await HardwareSDK.init({ env: 'webusb', debug: process.env.NODE_ENV !== 'production', fetchConfig: true, });

React Native BLE (@onekeyfe/hd-ble-sdk)

import HardwareSDK from '@onekeyfe/hd-ble-sdk'; await HardwareSDK.init({ debug: __DEV__, });

Native bridge / low-level (@onekeyfe/hd-common-connect-sdk)

import HardwareSDK from '@onekeyfe/hd-common-connect-sdk'; await HardwareSDK.init({ env: 'lowlevel', // 'webusb' | 'lowlevel' | 'react-native' | 'emulator' debug: process.env.NODE_ENV !== 'production', fetchConfig: true, });
EnvironmentUse Case
webusbBrowser WebUSB (no iframe)
lowlevelNative apps bridging JS via low-level adapter
react-nativeCustom RN bridge or Electron BLE
emulatorBuilt-in emulator transport

Plugin iframe host only (@onekeyfe/hd-web-sdk)

import { HardwareSDK } from '@onekeyfe/hd-web-sdk'; await HardwareSDK.init({ debug: process.env.NODE_ENV !== 'production', connectSrc: 'https://jssdk.onekey.so/1.1.19/', // iframe host });

Bind Events

Set up event listeners for device connection and UI prompts:

import { UI_EVENT, UI_REQUEST, DEVICE } from '@onekeyfe/hd-core'; HardwareSDK.on(UI_EVENT, async (message) => { switch (message.type) { case UI_REQUEST.REQUEST_PIN: // Handle PIN entry (see below) break; case UI_REQUEST.REQUEST_PASSPHRASE: // Handle passphrase entry (see below) break; } }); HardwareSDK.on(DEVICE.CONNECT, (payload) => console.log('Connected:', payload)); HardwareSDK.on(DEVICE.DISCONNECT, (payload) => console.log('Disconnected:', payload));

Discover Devices

WebUSB Authorization (Browser)

import { ONEKEY_WEBUSB_FILTER } from '@onekeyfe/hd-shared'; // Trigger browser's device chooser await navigator.usb.requestDevice({ filters: ONEKEY_WEBUSB_FILTER });

Search Devices

const result = await HardwareSDK.searchDevices(); if (!result.success) throw new Error(result.payload.error); const devices = result.payload; // [{ connectId, deviceId?, name, deviceType, ... }]

Get Device Features

Resolve device_id from connectId (required for BLE connections):

const features = await HardwareSDK.getFeatures(connectId); if (!features.success) throw new Error(features.payload.error); const deviceId = features.payload.device_id;

Important: Persist both connectId and device_id for subsequent API calls.

Handle PIN Entry

When a protected call is made and the device is locked, handle REQUEST_PIN:

import { UI_RESPONSE } from '@onekeyfe/hd-core'; // Option 1: Enter on device (recommended) await HardwareSDK.uiResponse({ type: UI_RESPONSE.RECEIVE_PIN, payload: '@@ONEKEY_INPUT_PIN_IN_DEVICE' }); // Option 2: Software blind PIN (not supported on Pro/Touch) await HardwareSDK.uiResponse({ type: UI_RESPONSE.RECEIVE_PIN, payload: userInputPin // e.g., '1234' });

Note: OneKey Pro and Touch devices only support on-device PIN entry.

Handle Passphrase

For hidden wallet access, handle REQUEST_PASSPHRASE:

// Option 1: Enter on device (most secure) await HardwareSDK.uiResponse({ type: UI_RESPONSE.RECEIVE_PASSPHRASE, payload: { passphraseOnDevice: true, value: '' } }); // Option 2: Software input with optional session cache await HardwareSDK.uiResponse({ type: UI_RESPONSE.RECEIVE_PASSPHRASE, payload: { value: userPassphrase, passphraseOnDevice: false, save: true } });

To force standard wallet (skip passphrase), add useEmptyPassphrase: true to any method call.

First Signing Call

Example: Sign an EVM message (EIP-191 personal_sign):

const message = 'Hello OneKey'; const messageHex = Buffer.from(message).toString('hex'); const res = await HardwareSDK.evmSignMessage(connectId, deviceId, { path: "m/44'/60'/0'", messageHex, chainId: 1, }); if (!res.success) throw new Error(res.payload.error); console.log('Address:', res.payload.address); console.log('Signature:', res.payload.signature);

Next Steps

Last updated on