feat: integrate OneKey hardware wallet over BLE (hd-ble-sdk)#6900
Open
wabicai wants to merge 61 commits intoKeeperCommunity:sprintfrom
Open
feat: integrate OneKey hardware wallet over BLE (hd-ble-sdk)#6900wabicai wants to merge 61 commits intoKeeperCommunity:sprintfrom
wabicai wants to merge 61 commits intoKeeperCommunity:sprintfrom
Conversation
…ssage signing - P0: Add device fingerprint verification before PSBT signing - P0: Fix passphrase handling (passphraseOnDevice: true) - P0: Fix SDK init race condition (only clear promise on failure) - P0: Fix root_fingerprint overflow with unsigned 32-bit conversion - P1: Replace all hardcoded Chinese strings with i18n keys - P1: Extract shared OneKeyDeviceScanner component to eliminate duplication - P1: Add proper TypeScript types for route params - P2: Remove hardcoded color values, use theme tokens - P2: Add BLE scan timeout protection (15s) - feat: Add address verification via btcGetAddress(showOnOneKey: true) - feat: Add message signing via btcSignMessage over BLE - feat: Add OneKey to AddressVerifiableSigners in ReceiveScreen - feat: Add OneKey BLE option in SignMessageScreen medium selector Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove dependencies that are not actually required by @onekeyfe/hd-core or its transitive deps in React Native context: - http-browserify, https-browserify, browserify-zlib - crypto-browserify, util, react-native-url-polyfill - ripple-keypairs (already declared in hd-core's own deps) - Remove all extraNodeModules from metro.config (SDK only uses buffer, which is already polyfilled by the project) - Remove unused react-native-url-polyfill/auto import from index.js Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Use official OneKey brand SVG icons instead of placeholder KeeperApp icons 2. Fix passphrase error (code 114 "Device opened passphrase") by passing useEmptyPassphrase: true to all BTC SDK calls 3. Include device label (e.g. "Pro A471") in signer description via signerDescription field from getFeatures response 4. Remove duplicate loading indicator - keep only button spinner, remove ActivityIndicator from device list during scan Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Redesign the device scanner interaction to match OneKey app-monorepo patterns while keeping Bitcoin Keeper's native styling: - Auto-scan on screen mount (no manual "Scan Devices" button needed) - Tap device to directly connect and execute action (no "Proceed" step) - Add Instruction bullets for user guidance on each screen - Status bar with device count + "Rescan" link replaces scan button - Green dot indicator for available devices - Consistent layout across all 4 screens (connect, verify, sign msg, sign tx) - Remove unused Buttons import and selectedDevice state from action screens Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… to English
- SignerModals.tsx: OneKey signing modal was using <LedgerContent />
(copy-paste from Ledger), replaced with Content={() => null}
- HardwareModalMap.tsx: translate all Chinese UI strings to English
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove type, Illustration, Instructions, subTitle params that are not part of ConnectOneKeyBleParams type definition. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…nt automatically Health check / identification mode no longer requires user to manually select a device from the scan list. Instead it auto-scans, connects to each found device, and matches by masterFingerprint. Shows a dedicated "Verifying..." UI with status updates instead of the device picker. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ix OneKey icons - SignWithOneKeyBle: auto-scan, match device by fingerprint, sign PSBT without requiring manual device selection - VerifyAddressOneKeyBle: same auto-scan + fingerprint match pattern - Fix onekey_icon_light.svg to use white fill (matching other HW icons) - Add onekey-green-light/dark.svg for SDColoredIcons consistency - Use green variants in SDColoredIcons instead of reusing ONEKEYICON Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Copy classic-new-device.svg (130x120) as onekey_illustration.svg - Register in ThemedIcons.js as onekey_illustration - Replace external_Key_illustration with onekey_illustration in HardwareModalMap for OneKey signer type Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use the OneKey Classic device with hand interaction illustration (360x280, static, no CSS animations/filters) instead of the classic-new-device which was too small and looked like a plain icon. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rebuild onekey_illustration.svg using the same design framework as ColdCard/Ledger/Jade illustrations: - Green gradient decorative circles (background) - Beige card with dark border + dashed inner frame - OneKey device body with screen, 4 buttons - Green OneKey logo (from onekey_icon.svg) displayed on device screen Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All variants now use the same OneKey logo shape (green squircle with "1" + key symbol) from onekey_icon.svg, only changing fill colors: - onekey_icon_light.svg: all white fill (for dark backgrounds) - onekey-green-light.svg: #2F4F4F bg + #F6F2ED symbols (light mode) - onekey-green-dark.svg: #41594C bg + #F1F1F1 symbols (dark mode) - onekey_illustration.svg: OneKey logo scaled 2.8x centered on the standard Bitcoin Keeper illustration card with green decorations Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove the custom onekey_illustration.svg and point ThemedIcons to onekey-green-dark.svg instead — cleaner and more consistent. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- onekey_icon_light.svg: change background squircle from white fill to white stroke outline, so the "1" + key symbols remain visible on colored card backgrounds - Add SignerType.ONEKEY to hardwareSigners array in SignerContent so OneKey appears in the Hardware Keys category Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ONEKEYICON SVG had no fixed width/height, causing it to fill the entire parent container and create a large white overlay covering other devices in the list. Replace with a Text-based logo (same pattern as Mobile Key, Other signer, etc.) until a proper OneKey word-mark logo SVG is available. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add onekey_logo.svg (black, 62x28) and onekey_logo_white.svg (white) from app-monorepo's onekey-text-only.svg. Use them in SDIcons Logo with dark/light mode support, matching the pattern of other hardware wallets (Ledger, Trezor, etc.). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. ensureOneKeyBLEReady: wait for BleManager state to settle when it returns 'Unknown' (happens on first use after BleManager creation). Uses onStateChange listener with 2s timeout instead of returning BLE_OFF immediately. 2. ConnectOneKeyBle: add a translucent modal overlay during device connection showing progress messages (Connecting → Reading device info → Importing keys) so users know the app isn't frozen and can see prompts to confirm on the OneKey device. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. HardwareModalMap: Remove Bluetooth option button from OneKey modal. Now shows illustration + instructions + Proceed button directly (same pattern as Ledger/Trezor). No intermediate selection step. 2. ensureOneKeyBLEReady: Replace state() + manual retry with a proper onStateChange listener that waits for a definitive BLE state (PoweredOn/PoweredOff/Unauthorized), filtering out transient Unknown/Resetting states. 3s timeout fallback. This fixes the false "turn on Bluetooth" error on first entry. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add device images (Classic, Classic Pure, Mini, Touch, Pro) from app-monorepo and display them in OneKeyDeviceScanner based on SearchDevice.deviceType. Also shows device type label and a human-readable device name. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a 125x138 onekey_illustration.svg with the standard Bitcoin Keeper decoration pattern (circles + dots) and a centered OneKey green logo (scaled 2.7x). Update ThemedIcons to point to this instead of the 24x24 onekey-green-dark.svg icon. Now the "Setting up OneKey" modal shows the illustration properly, matching Portal/ColdCard/etc. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace ScrollView with FlatList for proper scrolling and virtualization of the device list - Consolidate to a single ActivityIndicator in the empty state (removed the duplicate spinner from the status row) - Rescan button stays visible but disabled during scan - Fallback icon: green "OK" badge when deviceType is unknown instead of a tiny green dot - Better empty state messaging Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. OneKeyDeviceScanner:
- Distinguish Pro Black vs White based on serial number
(ends with 'B' = white, per app-monorepo logic)
- Show only device name (e.g. "Pro 04DD") without connectId,
matching app-monorepo's display style
- Remove subtitle line with connectId for cleaner look
- Header text: "Looking for devices..." / "Select your device"
2. onekey_illustration.svg: Redesign to show an actual OneKey Classic
device shape (body + screen + 4 buttons + green logo on screen)
with dashed border frame and decoration circles, matching the
visual style of Portal/Satochip illustrations.
3. Keys page: already shows device serial as subtitle via
signerDescription (set during setup from deviceLabel).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the custom device outline with the official OneKey welcome SVG from app-monorepo (green logo + "onekey" wordmark + TM). Rendered at 150x120 with viewBox preserved at 360x280. Colors: logo stays #44D62C green, text changed to #2F4F4F to blend with Bitcoin Keeper's palette. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. SVG: move decoration circles inside viewBox bounds so they don't get clipped (reduced radii & adjusted positions) 2. OneKeyDeviceScanner: only one state shown at a time: - Scanning: centered "Looking for devices..." + spinner (no header) - No results: centered message + Rescan button - Devices found: "Select your device" header + Rescan + device list 3. Rescan clears device list first, returning to the centered loading state for consistent UX flow Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. onekey_illustration.svg: Remove green logo circle, keep only "OneKey" wordmark centered with BK decoration background. 2. onekey_icon.svg, onekey-green-dark/light.svg: Change from filled circle background to outline stroke style (matching Ledger/Trezor pattern). Won't blend into dark card background. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add serialNo to OneKeyDeviceInfo (from features.serial_no) - Use serialNo as signerDescription (shown on Keys page subtitle) instead of deviceLabel, falling back to deviceLabel if empty This ensures the Keys page shows the hardware serial number (e.g. "PRA471B") rather than the BLE name. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add OneKey Pro shop link (onekey.so/zh_CN/products/onekey-pro/) to HardwareReferralLinks - Add OneKey card to HardwareDevices with text logo and Hong Kong as country Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use onekey_serial_no || onekey_serial || serial_no fallback chain matching the official SDK logic in hardware-js-sdk. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously health check would auto-scan and try to pair with EVERY scanned device to check fingerprints. Now it: 1. Shows the same device scanner UI as normal setup 2. User selects which device to verify 3. Only connects/pairs to the selected device 4. Checks fingerprint match and reports success/failure This avoids unwanted pairing dialogs with unrelated devices and gives the user control over which device to verify. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Store bleConnectId in signer.extraData during setup 2. Health check flow: - Try stored connectId first (direct connect, no scan) - If no stored connectId, fall back to scan + match fingerprint - Only connects to the specific matching device - Shows loading screen with progress messages, no device list 3. Add bleConnectId field to SignerExtraData type This matches app-monorepo's pattern: after initial setup, subsequent connections use the stored connectId without requiring user to re-select the device. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. onekey_icon.svg: Restore original green filled logo (#44D62C). The outline style was wrong — this icon is used everywhere (Keys page, Hardware list, etc.) and should keep the brand green. 2. onekey-green-dark/light.svg: Restore filled background versions (#41594C / #2F4F4F) for SDColoredIcons. 3. onekey_illustration.svg: Crop viewBox to exactly fit the "OneKey" wordmark (viewBox="90 108 240 70"), eliminating clipping and centering issues. Decoration circles repositioned within bounds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the text logo SVG with the actual OneKey Pro White product photo (PNG) in the Shop for Hardware Wallets page. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. onekey_illustration.svg: expand viewBox from (90,108,240,70) to
(85,105,250,80) so decoration circles aren't clipped at edges
2. Health check: remove fallback scan-and-match-all logic. Now:
- Has stored connectId → brief scan (BLE requires peripheral
discovery) → direct connect via stored connectId → verify
- No stored connectId → immediate error "re-add device"
- No more iterating/pairing every scanned device
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Use BLE device name (e.g. "Pro 04DD") as signerName on Keys page instead of generic "OneKey". Serial number stays as description. 2. onekey_icon_light.svg: restore green filled logo (#44D62C) so Keys page shows the recognizable OneKey brand icon on all background colors. 3. Add REQUEST_BUTTON handler to UI event listener — acknowledges device button confirmation requests without blocking the flow. May help with the pairing code loop issue. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. New OneKeyBleModal component:
- Self-contained modal for setup and health check
- Phases: scan → connecting → sdk-prompt → done
- Device list with images, BLE name display
- Stores BLE name as signerName, serial as description,
connectId in extraData
2. SDK UI event emitter (onekeyBle/index.ts):
- onekeyUIEmitter: EventEmitter for UI events
- PIN request → shows "Please enter PIN on device"
- Button request → shows "Please confirm on device"
- Passphrase → shows "Please enter passphrase on device"
3. HardwareModalMap integration:
- OneKey Proceed button opens OneKeyBleModal instead of
navigating to ConnectOneKeyBle page
- Health check also uses modal mode
- onSignerAdded callback handles navigation after success
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract OnekeyDevice component for the PNG image, matching the SVG component pattern used by BitBox, ColdCard, Ledger, etc. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace Node.js 'events' module (not available in RN) with React Native's DeviceEventEmitter - Use addListener/remove pattern instead of on/off - Remove useCallback wrapper for ModalContent (causes stale closure issues with KeeperModal's <Content /> pattern) - Add early return when not visible to prevent rendering errors Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Use UI_REQUEST.REQUEST_PIN/BUTTON/PASSPHRASE from @onekeyfe/hd-core as event values instead of custom strings 2. Health check mode: skip scan UI entirely, go straight to connecting phase with stored connectId. Shows "Connecting..." and "Verifying..." loading states. No device list shown. 3. SVG illustration: expand viewBox to (80,100,260,95) to prevent clipping of "OneKey" text and decoration circles Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. onekey_illustration.svg: expand viewBox to (75,95,270,115) for more vertical space, preventing text clipping 2. Signer naming on Keys page: - Title (signerName): device type e.g. "OneKey Pro", "OneKey Classic 1S" - Subtitle (signerDescription): BLE name e.g. "Pro 04DD" - No longer shows serial number (meaningless to users) Updated in both OneKeyBleModal and ConnectOneKeyBle. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After getOneKeyDeviceInfo/fetchOneKeySignerData returns, reset phase back to 'connecting' with updated status message. This clears stale "Please enter PIN" / "Please confirm" prompts once the user has completed the interaction on the device. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace shop image with the black Pro dual-device angled render (transparent PNG). Clean up all other test images. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Simplified Bauhinia flower on red background, matching the 18x12 SVG format used by other country flags. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Japan flag SVG (18x12, white with red circle). OneKey card now shows both flags with "Hong Kong & Japan" as country. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove simplified Hong Kong and Japan flag SVGs. OneKey shop card now shows "Hong Kong & Japan" as text only without flag icons, avoiding layout overflow. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use full-detail flag SVGs (renamed to flag-hongkong.svg and flag-japan.svg). Both rendered at 18x12 to match other flags. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Shorten country text to "HK & Japan" - Reduce flagContainer gap from 8 to 4 - Add flexWrap and flex:1 to flagContainer for overflow safety Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Without viewBox, the 900x600 SVGs rendered at 18x12 only showed the top-left corner (solid color). Adding viewBox="0 0 900 600" enables proper scaling. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. OneKeyBleModal: add 'verify-address' mode - Direct connect via stored connectId (same as health-check) - Shows address on device, compares with expected - 30s timeout on all BLE operations - Success: updates vault key registration + health check status 2. ReceiveScreen: open OneKeyBleModal instead of navigating to VerifyAddressOneKeyBle page 3. Delete VerifyAddressOneKeyBle.tsx and remove from navigation 4. Add BLE_OPERATION_TIMEOUT_MS (30s) to health-check flow too Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Map SDK error codes to user-friendly messages: - Code 801 / "Pin invalid" → "PIN is incorrect. Please try again" - Code 802 / "Pin cancelled" → "PIN entry was cancelled" - "Failure_ActionCancelled" → "Action was cancelled on the device" These show as toast messages when the operation fails due to PIN errors, instead of raw SDK error strings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Delete ConnectOneKeyBle.tsx (376 lines) — fully replaced by OneKeyBleModal. Remove from Navigator and types. 2. Delete OneKeyDeviceScanner.tsx (228 lines) — only used by deleted ConnectOneKeyBle. OneKeyBleModal has its own inline UI. 3. Remove dead navigateToSetupWithOneKeyBLE function from HardwareModalMap.tsx. 4. Extract shared device constants to onekeyBle/deviceConstants.ts: - DEVICE_IMAGES, DEVICE_TYPE_NAMES - getDeviceImage(), getDeviceDisplayName(), getDeviceTypeName() OneKeyBleModal and SignMessageOneKeyBle now import from here. 5. Fix features serial_no access — inline (as any) for untyped fields only, instead of casting entire payload. 6. Rewrite SignMessageOneKeyBle to use shared constants directly instead of deleted OneKeyDeviceScanner. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Like health check and verify-address, message signing now: - Uses stored bleConnectId for direct connection (no scan UI) - Shows loading + SDK prompt states (PIN, confirm, passphrase) - Has 30s timeout on all BLE operations - Auto-runs on mount, goes back on success/failure SignMessageScreen updated to pass signer object (for bleConnectId). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. SignWithOneKeyBle: rewrite to use stored bleConnectId for direct connection instead of scan-and-iterate. Now consistent with health check, verify-address, and sign-message flows. - 30s timeout on all BLE operations - SDK UI event prompts (PIN, confirm, passphrase) - Cleaner loading UI without instruction text 2. Remove unused getOneKeyDeviceId export from onekeyBle service. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add OneKey hardware wallet support via Bluetooth Low Energy (BLE) for Bitcoin Keeper.
Architecture
Modal-based Interaction (OneKeyBleModal)
All primary OneKey flows use OneKeyBleModal - a self-contained modal component:
Dedicated Screens (transaction flows)
SignWithOneKeyBle- PSBT signing (auto-connects via stored connectId)SignMessageOneKeyBle- Message signing (auto-connects via stored connectId)SDK UI Event System
onekeyUIEmitter(DeviceEventEmitter) forwards SDK UI events to componentsDevice Reconnection
bleConnectIdstored insigner.extraDataduring setupDependencies
@onekeyfe/hd-ble-sdk- BLE transport for React Native@onekeyfe/hd-core- SDK core (UI_EVENT, UI_REQUEST, UI_RESPONSE)@onekeyfe/hd-shared- Shared types and error codes@onekeyfe/hd-transport-react-native- RN transport layerSigner Naming
signerName: Device type (e.g. "OneKey Pro")signerDescription: BLE name (e.g. "Pro 04DD")extraData.bleConnectId: Stored for reconnectionError Handling
Smoke Test Checklist
Setup
Health Check
Address Verification
Transaction Signing
Message Signing
Shop Page
Error Cases