Skip to content

Commit 9d54507

Browse files
authored
feat: support rn ble demo (#604)
1 parent c489d0f commit 9d54507

File tree

11 files changed

+893
-19
lines changed

11 files changed

+893
-19
lines changed

.gitignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ build
3838
# iOS
3939
Pods
4040
.expo
41+
**/.expo
4142

4243
# Xcode user data
4344
*.xcodeproj/xcuserdata/
@@ -61,3 +62,17 @@ Pods
6162
.cxx
6263
local.properties
6364
.idea
65+
66+
# Expo / RN example prebuild outputs (ignore generated native folders under examples)
67+
packages/connect-examples/react-native-demo/android
68+
packages/connect-examples/react-native-demo/ios
69+
packages/connect-examples/expo-example/android
70+
packages/connect-examples/expo-example/ios
71+
packages/connect-examples/expo-example/web-build
72+
73+
# Metro cache
74+
.metro-cache
75+
**/.metro-cache
76+
77+
# Expo web export
78+
**/web-build
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# React Native BLE Demo (Expo Dev Client)
2+
3+
This demo shows how to use `@onekeyfe/hd-ble-sdk` in a React Native (Expo Dev Client) app to connect to a OneKey hardware device via BLE, including scanning, fetching features, getting addresses and signing, with realtime logs.
4+
5+
> Important: You must run a Dev Client built by `expo run:ios|android`. Expo Go does not include required native BLE modules.
6+
7+
## Install
8+
9+
```
10+
yarn
11+
```
12+
13+
Declared dependencies in `package.json`:
14+
15+
- `@onekeyfe/hd-ble-sdk` (SDK)
16+
- `@onekeyfe/hd-core` (events & types)
17+
- `@onekeyfe/react-native-ble-utils`, `react-native-ble-plx` (native BLE infrastructure)
18+
- Polyfills: `buffer`, `process`, `react-native-get-random-values`, `react-native-url-polyfill`
19+
20+
## Metro config
21+
22+
Map Node APIs and enable package exports in `metro.config.js`:
23+
24+
```js
25+
config.resolver.extraNodeModules = {
26+
buffer: require.resolve('buffer/'),
27+
crypto: require.resolve('crypto-browserify'),
28+
stream: require.resolve('stream-browserify'),
29+
process: require.resolve('process/browser'),
30+
events: require.resolve('events/'),
31+
http: require.resolve('http-browserify'),
32+
https: require.resolve('https-browserify'),
33+
zlib: require.resolve('browserify-zlib'),
34+
util: require.resolve('util/'),
35+
url: require.resolve('url/'),
36+
path: require.resolve('path-browserify'),
37+
};
38+
config.resolver.unstable_enablePackageExports = true; // enable @noble/hashes/blake2b
39+
```
40+
41+
## Minimal code snippet
42+
43+
Register RN transport side-effects before SDK init, set polyfills, then init the SDK:
44+
45+
```ts
46+
// Polyfills
47+
import 'react-native-get-random-values';
48+
import 'react-native-url-polyfill/auto';
49+
// @ts-ignore
50+
global.Buffer = global.Buffer || require('buffer').Buffer;
51+
// @ts-ignore
52+
global.process = global.process || require('process');
53+
54+
// Register RN transport
55+
import '@onekeyfe/hd-transport-react-native';
56+
57+
import HardwareSDK from '@onekeyfe/hd-ble-sdk';
58+
59+
await HardwareSDK.init({ env: 'react-native', debug: __DEV__, fetchConfig: true });
60+
```
61+
62+
## Permissions (Expo app.json)
63+
64+
Declared in `app.json`:
65+
66+
- iOS: `NSCameraUsageDescription`, `NSBluetoothAlwaysUsageDescription`, `NSBluetoothPeripheralUsageDescription`
67+
- Android: `BLUETOOTH_SCAN`, `BLUETOOTH_CONNECT`, `ACCESS_FINE_LOCATION`, `ACCESS_COARSE_LOCATION`, `CAMERA`
68+
69+
> Android 12+ requires the system Location toggle to be ON to scan BLE devices.
70+
71+
## Run on real devices (USB)
72+
73+
- iOS
74+
- Enable Developer Mode, connect via USB and trust the computer
75+
- Build Dev Client: `yarn ios` (alias of `expo run:ios --device`)
76+
- Start bundler: `yarn ios:devclient` (alias of `expo start --dev-client -c`)
77+
78+
- Android
79+
- Enable Developer Options and USB Debugging; verify with `adb devices`
80+
- Build Dev Client: `yarn android` (alias of `expo run:android --device`)
81+
- USB bundler (optional): `yarn android:usb` (runs `adb reverse` then launches Dev Client)
82+
83+
## Features in this demo
84+
85+
- `Init SDK`: Initialize BLE SDK (subscribe to UI/DEVICE/LOG events)
86+
- `Start Scan`: Scan devices (with permission & BLE state checks; 15s timeout + `sdk.cancel()`)
87+
- `Get Features`: Read device features (includes `device_id`)
88+
- `Get EVM Address`: Get EVM address
89+
- `Sign Message (EVM)`: Sign an EVM message
90+
- `Logs`: Realtime SDK & Transport logs
91+
92+
> Buttons are disabled during operations (scanning/busy) and automatically re-enabled when done.
93+
94+
## Troubleshooting
95+
96+
- `new NativeEventEmitter() requires a non-null argument`
97+
- Native BLE module is not compiled into the app. Build a Dev Client with `expo run:ios|android` (do not use Expo Go).
98+
99+
- Stuck in `Scanning…`
100+
- Android: System “Location” toggle must be ON, and permissions granted; ensure Bluetooth is ON
101+
- Ensure the device is advertising (not in bootloader-only mode)
102+
- This demo adds a 15s timeout with `sdk.cancel()`, you can retry

packages/connect-examples/react-native-demo/app.json

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,30 @@
99
"updates": {
1010
"fallbackToCacheTimeout": 0
1111
},
12-
"assetBundlePatterns": ["**/*"],
12+
"assetBundlePatterns": [
13+
"**/*"
14+
],
1315
"ios": {
1416
"supportsTablet": true,
1517
"infoPlist": {
16-
"NSCameraUsageDescription": "Camera access is required to scan the QR codes displayed on the hardware wallet."
17-
}
18+
"NSCameraUsageDescription": "Camera access is required to scan the QR codes displayed on the hardware wallet.",
19+
"NSBluetoothAlwaysUsageDescription": "Bluetooth is required to discover and connect to your OneKey hardware device.",
20+
"NSBluetoothPeripheralUsageDescription": "Bluetooth is required to discover and connect to your OneKey hardware device.",
21+
},
22+
"bundleIdentifier": "com.anonymous.react-native-demo",
23+
"appleTeamId": "CTK8P5SY9G"
1824
},
1925
"android": {
2026
"adaptiveIcon": {
2127
"backgroundColor": "#ffffff"
2228
},
23-
"permissions": ["CAMERA"]
29+
"permissions": [
30+
"CAMERA",
31+
"BLUETOOTH_SCAN",
32+
"BLUETOOTH_CONNECT",
33+
"ACCESS_FINE_LOCATION",
34+
"ACCESS_COARSE_LOCATION"
35+
]
2436
},
2537
"web": {
2638
"bundler": "metro",
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { FeatureDescriptor } from '../src/features/types';
2+
3+
import { BleDemoScreen } from './src/BleDemoScreen';
4+
5+
export const bleFeature: FeatureDescriptor = {
6+
id: 'BLE',
7+
title: 'BLE Connect Demo',
8+
description:
9+
'Scan devices, fetch device features, get address and sign messages via @onekeyfe/hd-ble-sdk with live logs.',
10+
keywords: ['bluetooth', 'ble', 'hardware', 'onekey'],
11+
Screen: BleDemoScreen,
12+
getSummary: () => 'BLE scan, select device, get features, address and sign.',
13+
};
14+
15+
export * from './src/BleDemoScreen';

0 commit comments

Comments
 (0)