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
| Method | Description | Supported devices |
|---|---|---|
| USB / WebUSB | Wired USB; Web via WebUSB, native via low-level plugin | All OneKey devices |
| Bluetooth BLE (native) | Native apps over BLE (not Web Bluetooth); requires OS Bluetooth & permission | OneKey Pro, Touch, Classic 1s / Classic 1s Pure; Mini does not support BLE |
| Air-Gap (QR) | Offline QR signing | OneKey Pro only |
Choose Your Transport (aligned with overview)
| Platform | Transport | SDK Package | Guide |
|---|---|---|---|
| Web (Browser) | WebUSB | @onekeyfe/hd-common-connect-sdk | WebUSB Connection Guide |
| React Native | BLE | @onekeyfe/hd-ble-sdk | React Native BLE |
| Android (Native) | BLE | @onekeyfe/hd-common-connect-sdk | Android BLE |
| iOS (Native) | BLE | @onekeyfe/hd-common-connect-sdk | iOS BLE |
| Flutter | BLE | @onekeyfe/hd-common-connect-sdk | Flutter BLE |
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-sdkTransport details:
- WebUSB: WebUSB guide
- React Native BLE: BLE guide
- Native Android / iOS / Flutter: bridge JS calls through low-level transport plugins (see pages for examples).
- Custom channel & protocol: Low-Level Transport Plugin & Protocol
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,
});| Environment | Use Case |
|---|---|
webusb | Browser WebUSB (no iframe) |
lowlevel | Native apps bridging JS via low-level adapter |
react-native | Custom RN bridge or Electron BLE |
emulator | Built-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
connectIdanddevice_idfor 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
- Transport Setup: WebUSB | React Native BLE | Native BLE
- Chain APIs: Use the chain selector in the sidebar to find specific signing methods
- Reference: Common Params | Error Codes