React Native BLE (hd-ble-sdk)
This guide shows how to use the pure React Native BLE stack with @onekeyfe/hd-ble-sdk and @onekeyfe/hd-transport-react-native. No WebView or low-level adapter is required. The chain API usage stays the same as in Quick Start.
Install
We recommend installing the RN-native dependencies at the app layer so that autolinking includes the native modules in your Dev Client build:
npm i @onekeyfe/hd-ble-sdk @onekeyfe/hd-transport-react-native \
@onekeyfe/react-native-ble-utils react-native-ble-plx \
buffer process react-native-get-random-values react-native-url-polyfillIn your app entry (e.g., index.js or App.tsx):
// Polyfills (adjust to your project needs)
import 'react-native-get-random-values';
import 'react-native-url-polyfill/auto';
// @ts-ignore
global.Buffer = global.Buffer || require('buffer').Buffer;
// @ts-ignore
global.process = global.process || require('process');
// Register RN transport side-effects before SDK init
import '@onekeyfe/hd-transport-react-native';
import HardwareSDK from '@onekeyfe/hd-ble-sdk';Android setup
Add permissions in AndroidManifest.xml (Android 12+):
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>At runtime, request BLUETOOTH_SCAN and BLUETOOTH_CONNECT (and location on Android 12+). Ensure the system Location toggle is ON.
iOS setup
Add to Info.plist:
NSBluetoothAlwaysUsageDescription(required)Optionally
NSBluetoothPeripheralUsageDescriptionfor older iOS versionsIf your app uses the camera (e.g. QR scanning), add
NSCameraUsageDescription
If using Expo, you can declare these in app.json under expo.ios.infoPlist and expo.android.permissions.
Metro config (polyfills & exports)
Map Node core APIs and enable package exports for subpath imports like @noble/hashes/blake2b:
// metro.config.js
config.resolver.extraNodeModules = {
buffer: require.resolve('buffer/'),
crypto: require.resolve('crypto-browserify'),
stream: require.resolve('stream-browserify'),
process: require.resolve('process/browser'),
events: require.resolve('events/'),
http: require.resolve('http-browserify'),
https: require.resolve('https-browserify'),
zlib: require.resolve('browserify-zlib'),
util: require.resolve('util/'),
url: require.resolve('url/'),
path: require.resolve('path-browserify'),
};
config.resolver.unstable_enablePackageExports = true;Build Dev Client (real devices)
Expo Go does not include your native BLE modules. Build a Dev Client:
# iOS
expo run:ios --device
# Android
expo run:android --device
# Start bundler for Dev Client
expo start --dev-client -cInitialize and subscribe to events
export async function setupBle() {
await HardwareSDK.init({
env: 'react-native', // React Native BLE transport
debug: __DEV__,
fetchConfig: true,
});
// Subscribe to UI events (PIN / Passphrase / confirmations)
// import { UI_EVENT, UI_REQUEST, UI_RESPONSE } from '@onekeyfe/hd-core'
// HardwareSDK.on(UI_EVENT, (msg) => { /* open dialogs and reply via HardwareSDK.uiResponse(...) */ });
}Discover devices and identify device_id
const devices = await HardwareSDK.searchDevices();
if (!devices.success) throw new Error(devices.payload.error);
// BLE returns id + name; fetch features to obtain device_id
const candidate = devices.payload[0];
const connectId = candidate.connectId;
const features = await HardwareSDK.getFeatures(connectId);
if (!features.success) throw new Error(features.payload.error);
const deviceId = features.payload.device_id;Persist connectId and deviceId (most chain APIs require both).
First call example (BTC address)
const res = await HardwareSDK.btcGetAddress(connectId, deviceId, {
path: "m/44'/0'/0'/0/0",
coin: 'btc',
showOnOneKey: false,
});
if (res.success) {
console.log('BTC address:', res.payload.address);
} else {
console.error('Error:', res.payload.error, res.payload.code);
}Tips
Always subscribe early to
UI_EVENTso PIN/Passphrase/confirmations do not stall requests. See Config Event.Keep BLE permissions in sync with the OS version. Test on physical devices.
For additional examples, check: react-native-demo
Continue
Protocol framing (64 bytes, for reference only): OneKey Message Protocol
Last updated
Was this helpful?