feat(pro2): add auto-detected Protocol V2 over WebUSB and BLE#773
feat(pro2): add auto-detected Protocol V2 over WebUSB and BLE#773wabicai wants to merge 31 commits into
Conversation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
The PR #773 lint job failed in `pinentry.test.ts` with `Cannot use import statement outside a module` because the hd-cli package was missing jest.config.js. Other workspaces (hd-transport, core, hwk-ledger-*) already inherit the root preset that wires up babel-jest + @babel/preset-typescript; hd-cli was the only one running plain Jest defaults, so any TS test file failed to parse. Mirror the existing pattern: preset → root jest.config.js, testEnvironment → node, ignore dist/. Local `yarn test` in hd-cli now passes 23/23 (pinentry parser tests). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…proto sources Pro2 ships a separate set of system messages (file ops, FirmwareUpdate, Reboot, Ping, Failure types) defined under `submodules/firmware-pro2/sys/protobuf/onekey_protocol/legacy/`. This adds a Pro2 branch to `protobuf-build.sh` that pulls those .proto files, strips the `Emmc` prefix from message names, splices in `Success`/`Failure` from messages_common.proto, appends the Pro2-only `Reboot` message (no .proto source), and emits `messages-pro2.json` next to the existing `messages.json`. Both the hd-transport bundle and the core SDK get a copy. Also adds `firmware-pro2` as a submodule so the build is reproducible without manual cloning. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…Pro2 Adds Protocol V2 (Pro2's 0x5A framing — formerly known as "Proto V0" / "Proto Link" on the firmware side) alongside the legacy 0x3F chunked Protocol V1, and introduces per-device protocol routing across every transport implementation. Wire format (`packages/hd-transport/src/serialization/protocol-v2/`): - 0x5A SOF, 2-byte little-endian length, CRC8 over header and full frame (init=0x30, poly=0x07), single-frame max 2200 bytes - Channel/packet-source bytes for the firmware's proto-link routing - `parseProtoV2Frame` decode + `buildPbFrame` encode helpers - Cohabits with the legacy V1 codec (renamed dir from `protocol/` → `protocol-v1/`); both are now siblings under `serialization/`. `protocols.ts` is a thin facade that picks the right schema (V1 default + V2 schema for sys-message IDs ≥ 60000). Transport interface (`Transport.getProtocolType(path)`): - Promoted from optional to required so the SDK can route per device without falling back to features-based heuristics. - `WebUsbTransport` detects per-path by USB PID (`PROTOCOL_V2_USB_PID = 0x53c1` shared with Classic/Mini/Pro/Touch for now — see TODO in constants.ts; awaiting Pro2-specific PID). - New `ElectronPro2BleTransport`: BLE GATT bridge for Pro2 over Noble, re-uses the V2 codec, sets `CHANNEL=BLE_UART (1)` and `packet_src=COMMAND (1)` because BLE goes through the BLE-coprocessor ↔ main-MCU UART bridge. Single Pro2 frame may arrive across multiple BLE notifications; reassembly is driven off the LEN field. - Single-protocol transports (Emulator / Http / Lowlevel / ReactNative / NodeUsb / ElectronBle) all return `'V1'`. Routing in `WebUsbTransport.call()`: - Dispatches to `callProtocolV2()` for V2 devices and the legacy 64-byte chunked path for V1 — chosen at acquire time and cached on the per-path `deviceProtocol` map. - Both schemas (`messages` for V1, `messagesV2` for V2) are loaded once on configure(); no mid-flight schema swap. - USB endpoints reach the main MCU directly so the V2 frame doesn't set channel/packet-src — only BLE does. Constants (`packages/hd-transport/src/constants.ts`): - `PROTOCOL_V2_USB_PID` (0x53c1, with TODO) - `PROTOCOL_V2_FRAME_MAX_BYTES` (2200) - `PROTOCOL_V2_FILE_CHUNK_SIZE` (2048) - `PROTOCOL_V2_CHANNEL_USB / BLE_UART / SOCKET` - `PROTOCOL_V2_PACKET_SRC_COMMAND` - `PROTOCOL_V2_SYS_MESSAGE_THRESHOLD` (60000) Auxiliary changes: - `packages/shared/src/constants.ts`: extend ONEKEY_WEBUSB_FILTER with Pro Boot/Touch Boot PIDs (`0x4f4a`, `0x4f4b`) so Pro2-era hardware in either mode is recognized. - `noble-ble-handler.ts`: discover all GATT services and characteristics without UUID filtering — needed because the Pro2 firmware-side BLE service UUIDs are still moving and the previous filter dropped the notify characteristic during scan. Scan timeouts extended for the Pro2 advertising interval. - `hd-common-connect-sdk`: route `desktop-web-ble-pro2` env to `ElectronPro2BleTransport`. This commit collapses 18 incremental WIP commits (initial Pro V0 framing, schema selection fixes, descriptor.protocolType propagation, debug logging, Initialize → Ping init flow iterations, BLE transport wiring, BLE scan tuning, Pro2 prefix removal, V1/V2 rename, lint fixes) into a single coherent change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…em API
Wires Pro2 (Protocol V2) into the core SDK as a first-class device
type and adds the SDK-level entry points for Pro2's filesystem and
firmware-update messages.
Device type:
- `EDeviceType.Pro2` added in `@onekeyfe/hd-shared` and recognized by
`getDeviceType()`. New `desktop-web-ble-pro2` settings env routes to
`ElectronPro2BleTransport`.
- `Device.initialize()` early-branches into `_initializePro2()` when
`descriptor.protocolType === 'V2'`. Pro2 doesn't support the legacy
`Initialize` handshake, so the SDK sends `Ping` to verify
connectivity and synthesizes the minimum `Features` shape downstream
code reads (vendor / onekey_device_type / device_id / unlocked /
initialized). `device_id` derives from the descriptor (path or BLE
UUID) so `getDeviceUUID(features)` stays defined for Pro2.
TransportManager:
- `reconfigure()` keeps only its features-based messageVersion swap
(the legitimate V1 use case for Touch classic vs latest schema).
The previous WIP carried a `protocolType` parameter that was being
used for cosmetic schema swaps the transport already handles
per-call; that's removed.
- Initial `configure()` loads V1 default schema and immediately calls
`configureProtocolV2Messages()` so the transport holds both
schemas; per-device routing happens at `call()` time via
`getProtocolType(path)`.
Pro2 reboot:
- `DeviceRebootToBootloader` and `DeviceRebootToBoardloader` branch on
Pro2 to send `Reboot { reboot_type: BootLoader (2) }` /
`{ Boardloader (1) }` instead of the V1 `RebootToBootloader` /
`RebootToBoardloader` messages.
Firmware update (`FirmwareUpdateV3`):
- V1 path (Pro1 / Touch / Mini / Classic) is unchanged. Same
`validateDeviceAndVersion` gates, same `enterBootloaderMode()`
+ `executeUpdate()` flow that was on `onekey`.
- New `runProtocolV2()` is reached via early-return in `run()` when
`descriptor.protocolType === 'V2'`. It:
1. Reuses the common binary-prep helpers
(`prepareResourceBinary`, `prepareFirmwareAndBleBinary`,
`prepareBootloaderBinary`).
2. Calls `pro2EnterBootloader()` — sends
`Reboot { reboot_type: BootLoader }` via the SDK's existing
`this.reboot()` helper (typedCall under the hood; the helper
already tolerates the device dropping USB during reboot).
1.5s settle wait is the placeholder for a reconnect/Ping
handshake that needs to land once Pro2 bootloader-mode is
finalized firmware-side.
3. Runs `executeUpdateProtocolV2()` — writes resources to
`vol1:res/`, bootloader to `vol1:bootloader.bin`, firmware
binaries to `vol1:${name}` (matches the pro2-debug script's
`vol1:` convention), then triggers
`FirmwareUpdate { targets[], reboot_on_success: true }`.
4. No GetFeatures completion polling — Pro2's V2 schema doesn't
expose it. The `FirmwareUpdate` Success response is itself
the install-complete signal (matches pro2-debug's synchronous
request/response usage with a long timeout).
Pro2 filesystem API (`packages/core/src/api/{DirList,DirMake,DirRemove,
FileDelete,FileRead,FileWrite,PathInfo}.ts` + `types/api/pro2.ts`):
- One BaseMethod-derived class per Pro2 system message. Exposed via
`inject.ts` so consumers call `HardwareSDK.dirList(connectId, ...)`
/ `fileWrite(...)` etc.
- Uses `typedCall('FileWrite' | 'DirList' | ..., 'File' | 'Dir' | 'Success' | ...)` —
the message names are now in the V1 MessageType union (the protobuf
build merges Pro2 system messages into the same protobuf root).
Misc:
- AlephiumSignTransaction.ts: typing tweak on the `bytecodeRequest`
branch — unrelated cleanup that drifted in.
This commit collapses the per-iteration core SDK changes (Pro2 device
type integration, multiple Initialize/Ping init iterations, firmware
update target_id and chunk-size fixes, DeviceReboot* Pro2 branches,
file-op API additions) into one coherent change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pro2 debug page (`expo-playground/app/routes/pro2-debug.tsx`):
- Wire-level testing tool that talks to Pro2 over WebUSB directly,
bypassing the SDK transport stack. Used to isolate protocol-frame
/ CRC / message-encoding bugs from the SDK plumbing.
- Four tabs:
* Ping — connection sanity check
* File System — DirList, PathInfoQuery, FileRead, FileWrite,
FileDelete, DirMake, DirRemove, FixPermission
* Firmware — single-target FirmwareUpdate with manual target_id /
path / reboot_on_success controls
* Reboot — sends Reboot { reboot_type: Normal/Boardloader/BootLoader }
- Carries its own minimal protobuf encoder/decoder for the Pro2
message subset; deliberately does not depend on the SDK so it
remains usable as a fault-isolation tool when the SDK is broken.
Static WebUSB test page (`expo-playground/public/webusb_test.html`):
- Single-file HTML harness for the same Pro2 protocol (predates the
React debug page). Kept under `public/` so Vercel serves it without
a route. Useful for cross-browser / cross-machine debugging where
setting up the playground app is overkill.
Vercel deployment:
- `vercel.json` at repo root; root `package.json` carries the build
glue. Lets us deploy the playground (including pro2-debug and
webusb_test.html) under a stable preview URL for the firmware team
to test against without local toolchain setup.
Sidebar + entry client tweaks add the pro2-debug route to the
playground navigation.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds Pro2 connection paths and firmware-update entry to the example app, so end-to-end Pro2 SDK flows can be exercised from a real UI (not just the wire-level pro2-debug page). - `deviceConnectAtoms.ts` / `hardwareInstance.ts`: track and route the new `desktop-web-ble-pro2` env alongside the existing webusb / desktop-web-ble options. Default to `desktop-web-ble-pro2` when running inside Electron so Pro2 BLE is the path most users land on. - `DeviceList.tsx` / `FirmwareScreen/index.tsx`: connection-type picker on both home and firmware-update screens; the picker triggers a transport switch that requires an app restart in some envs (the underlying transport instance is a singleton). Firmware-update screen shows the V3 entry for both Pro and Pro2; Pro2 path renders as "Firmware Update V3 (Pro2 Protocol V2)". - Minor cleanups in `passphraseTest/TestSessionCountView.tsx` and `views/SLIP39TestScreen.tsx` that drifted in alongside the Pro2 work. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- `docs/transport.md`: rewritten end to end. Side-by-side comparison of Protocol V1 (`##` header, 64-byte chunked, requires Initialize handshake) vs Protocol V2 (`0x5A` framing, single-frame up to 2200 bytes, no handshake, CRC8 validated). Wire format diagrams, schema selection rules, PID-based detection, architecture layers. - `docs/pro2-protocol.md`: new deep dive on Protocol V2 framing (Proto Link headers, channel/attr/seq fields, CRC8 algorithm), Pro2 message catalog (60000-series IDs), WebUSB and BLE I/O specifics including BLE notification reassembly and channel routing through the BLE coprocessor's UART bridge. - `OneKey_Pro2_Deep_Dive.md`: high-level Pro2 architecture notes (storage layout, secure-element targets, firmware partition map) for engineers onboarding to the Pro2 stack. - `CLAUDE.md`: minor refresh of repo-wide instructions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- `packages/hd-cli/jest.config.js`: add the workspace's missing jest config so unit tests can transform TypeScript. Mirrors the pattern used by hd-transport / core / hwk-ledger-* (preset → root jest.config.js, testEnvironment → node, ignore dist/). Fixes the PR #773 lint job, which was failing in `pinentry.test.ts` with `Cannot use import statement outside a module` because Jest was running with bare defaults. - `pinentry.ts` / `pinentry.test.ts`: small refactor to the Assuan parser surface — same observable behavior, less code. - `sdk.ts`: minor cleanup that drifted in alongside. - `hwk-adapter-core/src/__tests__/core-types.test.ts`: keep the Pro2 device-type addition compiling under the existing test expectations. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
312143a to
90bd1bd
Compare
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Summary
GetProtoVersionafter connect and fall back to Protocol V1 on timeout or failure.desktop-web-bleas the default Electron BLE entry.desktop-web-ble-pro2is now only a compatibility alias that maps to the same auto-detect transport.firmware-pro2soFilesystem*,DevFirmwareUpdate, andDevRebootare available through typed calls.DevFirmwareUpdate.targets.Architecture
Protocol split
Initialize -> Features.GetProtoVersionprobing andPing.Transport behavior
TransportManagerconfigures bothmessages.jsonandmessages-pro2.jsonwhen the transport supports Protocol V2.GetProtoVersiondevice response.Device.acquire()reads the detected protocol throughgetProtocolType()and stores it onoriginalDescriptor.protocolTypebefore initialization.Pro2 initialization and update
Initialize/GetFeatures; SDK verifies the link withPingand synthesizes minimalFeatureswith stabledevice_id,serial_no, andonekey_serial_no.FilesystemDirMake,FilesystemFileWrite,DevFirmwareUpdate, andDevRebootfrom the generated Pro2 type surface.DevFirmwareUpdate.targetsincludes resource, bootloader, and firmware targets explicitly.Review Findings Addressed
hd-transporttests now import Protocol V1 fromserialization/protocol-v1.MessageTypeunion.Firmware Pro2 Source
submodules/firmware-pro2origin/dev_romloader_split504b8752bba68c289769c320cf27d1a7bfcbfed42026-04-23 14:57:42 +0800main/devdo not currently provide the required latest Pro2 schema surface used here, especially theFilesystem*andDevFirmwareUpdatemessages.Docs
CLAUDE.md: Claude / Agent workflow entry, task routing, Pro2 caveats, and verification commands.docs/README.md: local documentation hierarchy and maintenance rules.docs/architecture.md: SDK layering, V1/V2 ownership, active protocol detection, Device/TransportManager responsibilities.docs/transport.md: WebUSB/BLE probing flow, schema routing, Pro2 firmware update flow, compatibility boundaries.docs/pro2-protocol.md: Protocol V2 frame format, protobuf payload, message IDs, WebUSB/BLE behavior, file write and firmware update messages.Test Plan
yarn prettier --write README.md docs/README.md CLAUDE.md docs/architecture.md docs/transport.md docs/pro2-protocol.mdyarn --cwd packages/hd-transport-web-device buildyarn --cwd packages/hd-common-connect-sdk buildyarn --cwd packages/hd-transport test --runInBandyarn --cwd packages/hd-transport buildyarn --cwd packages/core buildNODE_OPTIONS=--max-old-space-size=8192 yarn lint --quietgit diff --checkHardware Validation Still Needed
GetProtoVersion,Ping, file write, and firmware update.