本页目录
React Native BLE (hd-ble-sdk)
注意: 演示:React Native / Expo 示例 → react-native-demo
本指南展示如何使用纯 React Native BLE 堆栈与 @onekeyfe/hd-ble-sdk 和 @onekeyfe/hd-transport-react-native。无需 WebView 或底层适配器。链 API 的使用方式与快速开始中相同。
安装
我们建议在应用层安装 RN 原生依赖,以便自动链接将原生模块包含在您的 Dev Client 构建中:
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-polyfill在您的应用入口(例如 index.js 或 App.tsx):
// Polyfills(根据项目需要调整)
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');
// 在 SDK 初始化之前注册 RN transport 副作用
import '@onekeyfe/hd-transport-react-native';
import HardwareSDK from '@onekeyfe/hd-ble-sdk';Android 设置
下面的声明适用于不通过 BLE 扫描推断位置的客户端。只有应用确实满足该条件时,才使用 neverForLocation:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30"/>
<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"/>Android 12+ 在运行时请求 BLUETOOTH_SCAN 和 BLUETOOTH_CONNECT。是否需要位置权限取决于目标 SDK、应用是否推断位置以及 BLE 库配置,并非所有 Android 12+ 应用都需要。旧版 Android 使用对应的旧版蓝牙与位置权限。参见 Android 权限指南 。
iOS 设置
添加到 Info.plist:
NSBluetoothAlwaysUsageDescription(必需)- 可选的
NSBluetoothPeripheralUsageDescription用于旧版 iOS - 如果您的应用使用相机(例如二维码扫描),添加
NSCameraUsageDescription
如果使用 Expo,您可以在 app.json 中的 expo.ios.infoPlist 和 expo.android.permissions 下声明这些。
Metro 配置(polyfills 和 exports)
如果 Metro 报告缺少 Node 核心 API,只映射依赖树实际需要的模块。先安装每个 require.resolve 引用的包,再将条目合并进现有 resolver,不要覆盖框架默认配置。下面只是可选的映射片段,不是完整 Metro 配置:
// 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;构建 Dev Client(真实设备)
Expo Go 不包含您的原生 BLE 模块。构建 Dev Client:
# iOS
expo run:ios --device
# Android
expo run:android --device
# 为 Dev Client 启动 bundler
expo start --dev-client -c初始化并订阅事件
export async function setupBle() {
const initialized = await HardwareSDK.init({
env: 'react-native', // React Native BLE transport
debug: false,
fetchConfig: true,
});
if (!initialized) throw new Error('SDK initialization failed');
// 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(...) */ });
}发现设备并识别 device_id
const devices = await HardwareSDK.searchDevices();
if (!devices.success) throw new Error(devices.payload.error);
// BLE 返回 id + name;用 getDeviceState 读 identity
// 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 candidate = devices.payload[0];
const connectId = candidate?.connectId;
if (!connectId) throw new Error("No device connection");
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");保存 connectId 和 deviceId(大多数链 API 都需要两者)。
第一个调用示例(BTC 地址)
const res = await HardwareSDK.btcGetAddress(connectId, deviceId, {
path: "m/44'/0'/0'/0/0",
coin: 'btc',
showOnOneKey: true,
useEmptyPassphrase: true,
});
if (res.success) {
console.log('BTC address:', res.payload.address);
} else {
console.error('Error:', res.payload.error, res.payload.code);
}提示
- 始终尽早订阅
UI_EVENT,以免 PIN/密码短语/确认阻塞请求。参见 配置事件。 - 保持 BLE 权限与操作系统版本同步。在物理设备上测试。
- 更多示例请查看:react-native-demo