Skip to content

feat: harden firmware upgrade pipeline - #12656

Merged
originalix merged 19 commits into
hotfix/v6.5.2from
codex/firmware-upgrade-app-minimal
Aug 8, 2026
Merged

feat: harden firmware upgrade pipeline#12656
originalix merged 19 commits into
hotfix/v6.5.2from
codex/firmware-upgrade-app-minimal

Conversation

@originalix

@originalix originalix commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Harden the existing ServiceFirmwareUpdate flow with App-managed remote manifests, bounded artifact preparation, and fail-closed prepared execution.
  • Keep the existing data.onekey.so/config.json and pre-config.json release contract: firmware URLs, versions, sizes, fingerprints, and ZIP entries are not bundled into the App.
  • Build directly on the IP Table/SNI hotfix prerequisite merged by fix: backport ip table resilience to hotfix #12778.

Hotfix Reparenting

#12778 was squash-merged into hotfix/v6.5.2. This branch was then rebased from the original prerequisite commit onto the merged hotfix commit.

  • base: hotfix/v6.5.2@bf98473ce9
  • head: codex/firmware-upgrade-app-minimal@5aed01704b
  • diff: 80 files, 9,998 insertions, 1,334 deletions
  • the merged prerequisite tree and the original prerequisite tree are identical (6e5b936717)
  • current firmware branch tree: 1019f8c03e

Intent & Context

On SNI-capable App clients, firmware and resource artifacts are downloaded by the App before the first device mutation and passed to the SDK through the artifact-reader contract. Prepared SDK execution cannot silently return to network fetching. Existing remote manifests remain the release source of truth, including releases that do not publish optional size, fingerprint, or ZIP-entry metadata.

Design Decisions

  • Keep remote manifest fetching and release selection in the App, with the last known-good snapshot as the stale-cache fallback.
  • Do not embed firmware release data or artifact admission catalogs in the App.
  • Verify optional size and SHA-256 metadata when the remote release provides it; accept the existing config shape when it does not.
  • Materialize resource ZIPs without requiring new top-level entry metadata that current manifests do not publish.
  • Require complete artifact preparation before device mutation and keep prepared execution fail-closed with no SDK network fallback.
  • Preserve the existing SDK-managed path only for platforms and legacy flows outside the App-managed SNI client path.
  • Use bounded streaming stores with short leases on Native and Desktop.
  • Keep transaction journaling, checkpoint recovery, and unified resume/reconcile orchestration out of scope.

Runtime Ownership

  • Gallery and onboarding UI run in the main JS runtime.
  • Firmware coordination, remote manifest handling, preparation, and validator execution run in bg JS.
  • Main and bg have isolated JS heaps and initialize independently.
  • Native artifact storage and download resources are process-shared native resources; JS objects are not shared between runtimes.
  • Desktop bg crosses IPC to the Electron main-process artifact store.

Review Follow-up

  • Removed the App-bundled firmware catalog, generated firmware/config snapshot, URL admission gate, and ZIP-entry pin set.
  • Restored compatibility with remote releases that omit optional size, fingerprint, and ZIP-entry metadata.
  • Added a regression assertion that an App-downloaded remote plan URL does not require an App-bundled catalog.
  • The cold-start manifest failure path is being reassessed separately so hardware SDK initialization can remain available without allowing SDK firmware networking or adding bundled firmware data.

Risk Assessment

  • Risk Level: High
  • Affected Platforms: Mobile / Desktop / Web / Extension
  • Risk Areas: Firmware download ownership, transport selection, pre-mutation ordering, artifact lease cleanup, bootloader reconnect behavior, Protocol V2 compatibility, and manifest availability.

Test Plan

  • Run 5 focused Jest suites on @onekeyfe/hd-core@1.2.0-alpha.68: 51 tests passed.
  • Verify remote plan URLs work without an App-bundled catalog.
  • Verify current config shapes work without optional integrity and ZIP-entry fields.
  • Run yarn agent:check --profile commit successfully.
  • Complete mainland block/timeout fault injection and real Pro hardware integration before production activation, including interrupted-install and recovery scenarios.

Prerequisite merged: #12778

@socket-security

socket-security Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​onekeyfe/​hwk-ledger-connector-webhid@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7771 +11006596 +1100
Updated@​onekeyfe/​hwk-ledger-connector-ble@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7772 +11006596 +1100
Updated@​onekeyfe/​hwk-trezor-connector-webusb@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7776 +11007096 +1100
Updated@​onekeyfe/​hwk-trezor-connector-rn-ble@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7777 +11007196 +1100
Updated@​onekeyfe/​hwk-trezor-connector-electron-ble@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7777 +110071 +196 +1100
Updated@​onekeyfe/​hwk-trezor-adapter@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7777 +110071 +196 +1100
Updated@​onekeyfe/​hd-transport-usb@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7777 +11007196 +1100
Updated@​onekeyfe/​hd-transport-electron@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7781 +110072 +196100
Updated@​onekeyfe/​hwk-adapter-core@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7778 +110072 +196 +1100
Updated@​onekeyfe/​hd-shared@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7784 +110073 +196100
Updated@​onekeyfe/​hwk-ledger-adapter@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7779 +11007396 +1100
Updated@​onekeyfe/​react-native-range-downloader@​3.0.78 ⏵ 3.0.81-alpha.1173 +210090 +196 +1100
Updated@​onekeyfe/​react-native-sni-connect@​3.0.78 ⏵ 3.0.81-alpha.97510010096 +2100
Updated@​onekeyfe/​hd-ble-sdk@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7780 +11008196100
Updated@​onekeyfe/​hd-common-connect-sdk@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7781 +11008196100
Updated@​onekeyfe/​hd-transport@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7786 +110083 +196100
Updated@​onekeyfe/​hd-web-sdk@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7786 +110086 +196100
Updated@​onekeyfe/​hd-core@​1.2.0-alpha.69 ⏵ 1.2.0-alpha.7787 +110086 +196100

View full report

@originalix
originalix force-pushed the codex/firmware-upgrade-app-minimal branch 3 times, most recently from 69e10df to 8069272 Compare July 28, 2026 10:48

@originalix originalix left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

三仓固件升级最小化加固 — 只读复审结论(app-monorepo 部分)

总体:方向基本统一,但存在阻塞问题。架构确实收敛到最小化范围(无 journal / checkpoint / coordinator / plan interpreter 残留,V2/V3/V4 状态机未被改写,mutation barrier 结构正确)。阻塞项是「新管线在出厂 pin 下不可达」+「一条已在跑的 Pro/Pro2 路径被改成硬失败」+「准入契约与线上 manifest 永远无法匹配」。

本 PR 上共 5 条行内意见:P0 ×2、P1 ×3。SDK 侧 4 条见 OneKeyHQ/hardware-js-sdk#850,native 侧 4 条见 OneKeyHQ/app-modules#79

已实跑:npx jest packages/kit-bg/src/services/ServiceFirmwareUpdate packages/shared/src/hardware packages/shared/src/utils/ipTableUtils packages/shared/src/request/helpers/ipTableAdapter packages/kit-bg/src/desktopApis packages/kit-bg/src/services/ServiceIpTable → 23 suites / 277 tests 全绿。问题不在于哪个测试挂了,而在于这些路径根本没有测试覆盖。

进入三端 E2E 前建议先修:本 PR 的 P0 ×2 + pin 两条;进入 Pro 真机前还需 #850 的 P0(devicePath)与身份绑定。

Comment thread packages/kit-bg/src/services/ServiceFirmwareUpdate/ServiceFirmwareUpdate.ts Outdated
Comment thread packages/kit-bg/src/services/ServiceFirmwareUpdate/FirmwareArtifactPreflight.ts Outdated
Comment thread package.json Outdated
Comment thread apps/mobile/package.json Outdated
Comment thread packages/kit-bg/src/services/ServiceFirmwareUpdate/FirmwareArtifactPreflight.ts Outdated
@originalix

Copy link
Copy Markdown
Collaborator Author

范围收敛:可确认为冗余/越界的代码(非缺陷,与前面 5 条行内意见分开看)

下面每条我都自己 grep 过调用链,不是感觉「代码多」。验收规则里说过「不得为了行数而删除必要的安全校验」,所以先声明:FirmwareArtifactPreflight.ts(686)、FirmwareArtifactAdapter.native.tsFirmwarePreparedArtifactController.tstrustedFirmwareCatalog.generated.tsartifactsByUrl(≈443KB)、desktopApiModuleAllowlist.* 都是承重的,不在下面这张表里。

1. development/scripts/firmware/generateFirmwareCatalog.test.mjs(77 行)—— 死测试,从未执行

jest.config.js 没有定义 testMatch,走 jest 29 默认值 ["**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[tj]s?(x)"]不匹配 .mjs。实测:npx jest --listTests 收集到 827 个测试文件,grep -c generateFirmwareCatalog = 0

catalog 生成器(574 行)是供应链准入白名单的来源,它的测试反而不跑,风险不对称。建议要么把文件改成 .test.js / 加进 testMatch,要么明确说明它是手动执行的脚本测试。

2. 自检脚手架(约 1490 行)—— 需要「修好」或「本轮摘出」二选一,不要以当前状态合入

涉及:FirmwareArtifactSelfTest.ts(696) + FirmwareArtifactSelfTestController.ts(248) + FirmwareArtifactSelfTest.test.ts(294) + FirmwareArtifactGallery.tsx(252) + 4 处路由/testID 注册(shared/src/routes/gallery.tsGallery/Components/index.tsxGallery/index.tsxDeveloper/testIDs.ts)。

可达性已确认:startFirmwareArtifactSelfTest / getFirmwareArtifactSelfTestStateServiceFirmwareUpdate.ts:184,195)的唯一调用方是 FirmwareArtifactGallery.tsx:150,172,即 Developer Gallery 里的 EGalleryRoutes.ComponentFirmwareArtifactFirmwareArtifactSelfTestController 只被 FirmwareUpdateRuntime.ts:40 实例化。它还硬编了 PRO_FIRMWARE_VERSION = '4.21.0'FirmwareArtifactSelfTest.ts:111)与 SDK_SELF_TEST_CONNECT_ID = '__firmware_sdk_self_test_no_device__':113)。

这条不是简单的「建议删」:按当前状态,本 PR 的三端 E2E 没有任何自动化载体(apps/desktop/e2e 只有 open-url,apps/mobile/e2e 无固件用例),这个自检就是唯一的验证工具。所以要么把它当作正式的验证载体保留并保证它能跑通、且明确它对生产 artifact store 与 SDK 全局 host-binding registry 的副作用边界,要么本轮先摘出去、E2E 用别的方式做。以「1490 行 dev-only、且没人能确认它跑得通」的状态合入是最差的选项。(我正在单独验证它当前是否真的能启动,结论会另发。)

3. trustedFirmwareCatalog.generated.tsstableConfig / preReleaseConfig 两个键

实测文件总 471797 字节,其中 stableConfig 约 24.6KB、preReleaseConfig 约 3.2KB(含 22 条 zh-CN/en-US changelog 全文),artifactsByUrl 约 443KB。

这两个 blob 的唯一消费者是 getTrustedFirmwareConfig,而它的调用方只有 FirmwareArtifactSelfTest.ts:139FirmwareArtifactSelfTestController.ts:117。生产准入路径只用 getTrustedFirmwareArtifact / artifactsByUrl。也就是说这 ~28KB 只服务于第 2 条的自检,随第 2 条的处置一起决定。

4. packages/shared/src/logger/base/logFn.tsmetadata.always 逃逸口(+2/−2)

diff 精确就是两处::80 if (!platformEnv.isWebEmbed && (shouldLog || metadata.always)):94 if (shouldLog || metadata.always)。这绕过了用户设置的日志等级门禁。

全仓 always: true 的生产调用点只有一个:packages/shared/src/logger/scopes/update/scenes/firmware.ts:13@LogToLocal({ always: true, level: 'info' })(另一处在 logFn.test.ts)。为一个 dev 自检埋点放宽了全局日志语义,代价与收益不成比例。建议要么回退这个逃逸口、让自检埋点走正常等级,要么把 always 的适用范围收敛到明确的白名单。

5. 两个只在本文件内被引用的新增 export

  • packages/kit-bg/src/services/ServiceFirmwareUpdate/FirmwareArtifactPreflight.ts:74 export type IFirmwareArtifactReader(仅 :101:275 引用)
  • packages/shared/src/utils/ipTableUtils.ts:42 export function isValidFirmwareUpdateRolloutRule(仅 :111 引用)

都是本轮新增的导出,去掉 export 关键字零风险,能让本次评审的 API 增量保持诚实。纯清洁度,优先级最低。


SDK 侧还有 3 个同类的「只在本文件内被引用的新增 export」,已单独评论在 OneKeyHQ/hardware-js-sdk#850。app-modules 侧没有发现此类冗余。

@originalix originalix left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 批次(经对抗验证后存活的 3 条)

补充说明流程:上一轮我一共产出 27 条候选,按优先级只有前 14 条进了对抗验证,剩下 14 条 P2 当时未验证、也未发布。这一轮把那 14 条去重成 11 条后全部送了双透镜(correctness + reachability)对抗验证,7 条存活、4 条被推翻。本 PR 上存活 3 条,均为 P2,不阻塞。

被推翻的 4 条也说明一下,避免以后有人重新提出来:

  • 「所有 prepared 调用点用 as unknown as 掩盖契约不匹配」→ 推翻。executePreparedFirmwareUpdateV4(FirmwarePreparedExecution.ts:291)根本没有 cast,pinned hd-core 的 FirmwareUpdateV4Params 声明了全部字段,主路径是端到端类型检查的;且它演示的那处 checkpointSink 不匹配只对 stale 的 npm 包成立,SDK PR head 的 FirmwareUpdateHostBinding 就是 { artifactReader }。它实际上只是「pin 落后」那条 P1 的另一种表述。
  • 「自检 gallery 因缺 $$devOnlyPassword 必然抛错」→ 推翻,详见我另一条评论的更正。
  • 「自检会劫持 SDK 全局 host-binding registry」→ 推翻(见更正评论)。
  • 「resource artifact 在 plan builder 与 V2/V3 executor 用了两套选择规则」→ 推翻。DataManager.getFirmwareLatestRelease(DataManager.ts:298-304,本 PR 未改)在最新 release 条目缺 resource 时会用 getSysResourcesLatestRelease 回填,与 executor 侧的 gate 是同一个查询,两条「规则」实际收敛到同一个 URL;验证者用 jest 构造了 Touch 4.9.0 + [4.10.0 有 resource / 4.11.0 无 resource] 的场景实跑确认。

另有 1 条(三端重定向策略分歧)我判断证据不足没有发布:catalog 生成器在构建期就用 redirect: 'error' 验证过 URL 是终态(generateFirmwareCatalog.mjs:99, :252),触发依赖未来的 CDN 配置变更,且部分已被 app-modules#79 上的 iOS 重定向 P1 覆盖。留作 pending。

本轮结论锚定 commit f30d1fe888

Comment thread packages/kit-bg/src/services/ServiceFirmwareUpdate/FirmwareArtifactPreflight.ts Outdated
Comment thread packages/kit-bg/src/services/ServiceFirmwareUpdate/FirmwareArtifactPreflight.ts Outdated
@originalix

Copy link
Copy Markdown
Collaborator Author

更正:自检脚手架能正常运行,我上一条评论里的存疑不成立

上一条「范围收敛」评论第 2 条结尾我写了「我正在单独验证它当前是否真的能启动,结论会另发」。结论:能跑,两个怀疑都被推翻。

怀疑一:@backgroundMethodForDev()$$devOnlyPassword 会让 gallery 调用必然抛错 → 不成立。

createBackgroundMethodDecoratorpackages/shared/src/background/backgroundDecorators.ts:96-108)把带密码校验的包装函数装在 target['INTERNAL_' + methodName] 上,并原样返回 descriptor——原始未包装的方法仍留在 prototype 上。而 BackgroundApiProxyBase.ts:220-224 的本地分发(desktop / web / native 都走它)只把 INTERNAL_ 名字当作存在性探测,实际调用的是不带前缀的方法:if (serviceApi[backgroundMethodNameLocal] && serviceApi[methodName]) { serviceApi[methodName].call(...) }。native 双 runtime 路径同理(:243-256 转发不带前缀的方法名到 bg 线程,apps/mobile/background.ts:118-124 重入后落到同一个本地调用)。只有 extension-UI 分支(:183-198)才把 INTERNAL_* 送过桥,那里密码校验才会触发——而 gallery 已经用 platformSupported = platformEnv.isNative || platformEnv.isDesktop 把非 native/desktop 的按钮禁掉了。验证者用 node 模拟了装饰器的实际实现确认:s.start({scenario}) 正常执行,只有 s.INTERNAL_start({scenario}) 会抛。

怀疑二:自检会劫持 SDK 的全局 host-binding registry、污染进行中的真实升级 → 不成立,但理由值得记录。

机制本身是真的:FirmwareHostBinding 只有一个 binding 字段,每次 register/unregister 都递增 generationresolve() 对旧 generation 抛 stale——所以第二次 register 确实会毒掉一个存活的 generation。它不成立是因为触发不可达:升级进行中时 FirmwareUpdateExitPrevent.ts:45-52 通过 useModalExitPreventusePreventRemove 拦住了导航,离开升级 modal 必须走确认对话框,而确认路径会调 serviceHardware.cancel({}) 把 workflow 拆掉并释放 binding。也就是说你没法在传输进行中绕到 Gallery 再回填一次自检。

需要说明的是:这条的两个验证者里,有一个是用「dev 密码会拦住」来推翻的,而那个前提恰好被上面怀疑一证伪了。真正成立的只有导航守卫这一条论据。所以这条的安全性依赖的是一个 UI 导航守卫,而不是架构边界。 如果以后 Gallery 的入口方式改变、或者自检被接到别的触发点上,这个风险会立刻回来。建议在保留自检时给它加一道显式的互斥(例如自检启动前检查 firmwareUpdateWorkflowRunningAtom,或让它使用独立的 SDK 实例而非共享的生产实例),把安全性从 UI 层挪到代码层。

对上一条评论的净影响:第 2 条的结论从「要么修好要么摘出」收敛为——它能跑,所以作为 dev 验证载体保留是合理的;剩下的只是「1490 行 dev-only 代码是否要随本次 PR 一起进主干」这个纯范围判断,以及上面建议的那道互斥。第 3 条(stableConfig / preReleaseConfig 两个 blob 只服务于自检)与第 4 条(logFnalways 逃逸口只有自检一个生产调用点)不受影响,仍然成立。

Copy link
Copy Markdown
Collaborator Author

针对“范围收敛”评论及后续更正,当前处理如下:

  • Gallery 固件 artifact 自检是本次明确要求的三端无真机验证载体,已确认可运行,因此保留;其 stableConfig / preReleaseConfig 仍是该自检的必要输入。
  • 新增 Jest wrapper,让原生 ESM 的 generateFirmwareCatalog.test.mjs 真正进入常规 Jest 收集并执行,而不是留下死测试。
  • 已撤回全局 logger 的 metadata.always 逃逸口,自检恢复使用正常 LogToLocal 等级语义。
  • 已去掉 IFirmwareArtifactReaderisValidFirmwareUpdateRolloutRule 两个仅文件内使用的 export
  • reviewer 已确认当前 UI 导航守卫使 host-binding 并发污染不可达;本次不再额外引入新的互斥状态机。若以后 Gallery 入口或触发方式改变,需要重新审计这一边界。

8 个行内线程均已分别回复;未发布依赖 pin 和线上 signed artifact exact-host 配置仍明确保持 open。

@originalix originalix left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

第二轮复核:修复确认 + 2 条新引入的问题 + 1 条待办事实纠正

逐条核到 b76f60afcd。实跑 npx jest packages/kit-bg/src/services/ServiceFirmwareUpdate packages/shared/src/hardware packages/shared/src/utils/ipTableUtils packages/shared/src/request/helpers/ipTableAdapter packages/kit-bg/src/desktopApis packages/shared/src/logger development/scripts/firmware32 suites / 306 tests 全绿

原 finding 判定
P0 getPlan 无条件抛错 FIXED(但见下方 R3)
P0 catalog 准入永不匹配 FIXED(干净)
P1 hd-* pin 落后 NOT-FIXED(见下方事实纠正)
P1 native pin 落后 NOT-FIXED(同上)
P1 iOS 重试分类器 PARTIALLY(只加了一个码)
P2 Bridge 绕过 rollout FIXED
P2 单次超时 = 总预算 PARTIALLY(见下方 R6)
P2 pinned 候选不可达 NOT-FIXED(确认是运维前置,代码侧无可指摘)

几处修得很干净:catalog 兜底的新用例是真的 delete plan.artifacts[0].expectedSize/expectedSha256 再断言 download 用了 catalog 的值,是行为断言不是 fixture 断言;assertReceipt 逐字未改,完整性锚点完好。Bridge 的两个 rollout 求值点(缓存期 :126-127、Bridge transaction 创建前 :291-296)都严格早于 execute,不存在「设备已开始变异后才求值灰度」的问题。metadata.always 逃逸口已完整回退,且回退后自检埋点在生产/预发构建里照常落盘(shouldLog 在非 dev 恒 true),只有 dev 构建未开对应场景时静默 —— 与其余 @LogToLocal 一致,是合理回退。generateFirmwareCatalog.test.js wrapper 确实被 jest 收录并通过,不是空壳。

一条必须纠正的事实:两条 pin 线程里写的「等待 GitHub Actions 发布」已经不成立 —— 两个包都已发布,且 gitHead 精确等于各自 PR head:

@onekeyfe/hd-core@1.2.0-alpha.23                gitHead 7cadb40c  ==  SDK #850 head
@onekeyfe/react-native-range-downloader@3.0.81-alpha.3  gitHead 1989d3f1  ==  app-modules #79 head
@onekeyfe/react-native-sni-connect@3.0.81-alpha.3       gitHead 1989d3f1  ==  同上

而本次修复 commit 未触碰任何 package.jsonnode_modules 里装的仍是 hd-core@1.1.34-alpha.33.0.81-alpha.1。后果不变:getExternalSdk() 恒返回 undefined、isFirmwareArtifactCapabilityReady() 恒 false ⇒ digest 恒缺失 ⇒ prepared 路径在当前 App 构建里整体不可达,SDK 与 native 侧这轮修的所有东西 App 一行都执行不到。升 pin 的阻碍已经没有了。

第二个 E2E 前置(代码侧已确认):即使升了 pin,只要线上签名 IP Table 里没有 firmware_rollout 段,selectConfig 第一分支 if (!config.firmware_rollout) 就会落到 bundled(enabled:false, percentageBps:0)→ getRuleReason 返回 'disabled'allowed:false → digest 仍恒缺失。所以要开有意义的三端 E2E,升 pin 与 ops 下发 firmware_rollout 两件事缺一不可;要测 pinned-IP 分支,还需同时下发 common.onekey-asset.com / web.onekey-asset.com 等 exact-host 条目(内置默认表只有 onekeycn.com/onekeytest.com,连 onekey-asset.com 根域条目都没有,所以加根域回落也救不了内置表)。

Comment thread packages/kit-bg/src/services/ServiceFirmwareUpdate/ServiceFirmwareUpdate.ts Outdated
Comment thread packages/kit-bg/src/services/ServiceFirmwareUpdate/FirmwareArtifactPreflight.ts Outdated
@originalix

Copy link
Copy Markdown
Collaborator Author

Downloader alpha.6 integration and native verification

Updated the App to @onekeyfe/react-native-range-downloader@3.0.81-alpha.6 and aligned SNI prerelease, including Yarn and iOS Pod locks.

Added a 50-cycle Pro firmware artifact bridge stress path in Gallery:
createLease -> download(cache hit) -> open -> read(4 KiB) -> close -> release.

Validation:

  • targeted firmware self-test Jest: 6/6
  • shared, kit-bg, and kit TypeScript checks
  • touched-scope lint/format
  • yarn agent:check --profile commit
  • iOS Pods ReactNativeRangeDownloader Release build under Xcode 26 succeeded

This is a native dependency change, so bundle-only delivery is not sufficient. A fresh iOS native build is running here:
https://github.com/OneKeyHQ/app-monorepo/actions/runs/30563954141

@originalix

Copy link
Copy Markdown
Collaborator Author

iOS native build result

Both EAS native builds for App head 2a0c3a8bc1673d615882f45653e219d17f678f72 finished successfully with error: null.

The production Release archive passed the Xcode path that previously crashed while compiling ReactNativeRangeDownloader.swift. The simulator log also confirms NitroModules remains on 0.33.2.

Note: the PR is currently conflicting with the latest x branch in four files. The rebase was not attempted because the 1Password SSH agent can list the GitHub key but currently fails signing requests; no unsigned or HTTPS fallback was used.

@originalix
originalix force-pushed the codex/firmware-upgrade-app-minimal branch from 2a0c3a8 to 8ce5825 Compare July 31, 2026 01:58
@originalix

Copy link
Copy Markdown
Collaborator Author

Rebased this branch onto current x (d71e6b7e7a). The new head is 8ce5825cda; GitHub reports it mergeable.

Conflict decisions:

  • kept current x HWK packages at 1.1.34-alpha.2; firmware HD packages remain 1.2.0-alpha.31
  • kept downloader/SNI at 3.0.81-alpha.6 and Nitro at 0.33.2
  • adapted the shipped Pro2 SDK type to the centralized device-name map and restored its existing Pro2Black.png avatar
  • all 31 branch commits are GitHub-verified SSH signatures

Validation:

  • yarn install --immutable
  • yarn agent:check --profile commit
  • 10 firmware/network suites, 115 tests passed
  • yarn agent:check --profile pr (local gates passed; active unresolved review threads: 0)

A fresh release-ios.yml run will be triggered against this exact head.

@originalix
originalix force-pushed the codex/firmware-upgrade-app-minimal branch from 09d8210 to e902b72 Compare August 2, 2026 10:11
Comment thread packages/kit/src/views/Onboardingv2/pages/CheckAndUpdate.tsx Outdated
Comment thread packages/kit-bg/src/services/ServiceFirmwareUpdate/trustedFirmwareCatalog.ts Outdated
Comment thread packages/shared/src/hardware/instance.ts Outdated
Comment thread packages/shared/src/hardware/firmwareConfigProvider.ts Outdated
Comment thread packages/shared/src/hardware/firmwareConfigProvider.ts
Comment thread packages/kit-bg/src/desktopApis/DesktopApiFirmwareArtifact.ts Outdated
Comment thread packages/kit/src/views/Onboardingv2/hooks/firmwareReconnectUtils.ts
Comment thread packages/kit-bg/src/desktopApis/DesktopApiFirmwareArtifact.ts Outdated
Comment thread apps/mobile/ios/Podfile.lock Outdated
@originalix
originalix marked this pull request as ready for review August 6, 2026 11:43
@originalix

originalix commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator Author

Automated code review found blocking issues

@originalix

Reviewed commit 53f35fef7c15. This report always reflects the latest reviewed changes.

Review summary

The PR moves native and desktop firmware delivery behind an application-managed background pipeline that fetches manifests, validates and leases artifacts, and passes prepared data into the hardware SDK; main-runtime onboarding and dialog state remain separate JavaScript state. Desktop Bridge V4 still forwards resource targets without preparing a resource payload, and Electron archive validation does not enforce its advertised entry-count cap. The onboarding recheck lifecycle also marks the firmware step in progress before its cancellable delay, leaving a blurred page unable to reschedule the check.

What needs attention: Verify that every Bridge target, archive resource, and post-update onboarding transition remains inside the verified handoff and can recover after cancellation.

Issues to address

  • P1 · Bridge V4 drops the resource payload while retaining the target
    • Impact: getBridgeBinaryPlanArtifacts() keeps only V4 artifacts with role component. A resource-only plan therefore returns no workflow artifact, and a mixed plan omits its resource bundle, while executePreparedFirmwareUpdateV4() still forwards the original resource target. The background runtime consequently provides no verified resource bytes to the SDK, allowing an out-of-bound refetch or a failed update.
    • Suggested action: Reject Desktop Bridge V4 plans containing resource until the Bridge handoff transports and validates a resource bundle end to end.
  • P1 · Archive validation does not enforce its entry-count limit
    • Impact: When production materialize() is called without expectedEntries, validateArchive() never checks MAX_ARCHIVE_ENTRIES. It retains every observed entry in multiple collections until byte limits are reached, so an archive containing many tiny files can consume excessive CPU and memory in Electron main. That process is shared by the desktop UI and background activity, so separate JavaScript heaps do not contain the failure.
    • Suggested action: Count observed entries inside validateArchive(), reject immediately above MAX_ARCHIVE_ENTRIES, and add a regression test for the path without expectedEntries.
  • P2 · A blurred post-update recheck cannot resume
    • Impact: The main runtime calls beginPostUpdateRecheck() before starting the cancellable delay, setting the firmware row to InProgress. If the page blurs during that delay, cleanup cancels only the timer; the next focus exits through the InProgress guard, leaving no timer or request while retry and continuation remain disabled. The independently initialized background runtime cannot repair this main-heap state.
    • Suggested action: Move beginPostUpdateRecheck() into the timer callback immediately before checkFirmwareUpdate() and add a focus-blur-focus regression test.

Validation gaps

  • git diff --check origin/hotfix/v6.5.2...HEAD completed successfully.
  • Targeted Jest execution was not available because this workspace has no node_modules or Yarn state file.
  • Live hardware, native downloader, iOS dialog handoff, and Electron archive behavior were not exercised.
  • Existing GitHub review/comment coverage could not be refreshed in this environment, so inline candidates require a duplicate-comment check before posting.

@originalix originalix left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@originalix

Automated code review found blocking issues

Reviewed commit 7d158a5f2d90.

  • P1 · Desktop Bridge V4 resource plans can execute without any resource payload
  • P2 · Android BLE precheck can block USB calls based on stale global transport state

View the full review report

@originalix originalix left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@originalix

Automated code review found blocking issues

Reviewed commit 0c5d913b9ad1.

  • P1 · Electron firmware IPC exposes private file and network helpers
  • P1 · Desktop Bridge V4 resource plans can execute without a resource payload
  • P2 · Android BLE precheck can block USB calls using stale transport state

View the full review report

@originalix

Copy link
Copy Markdown
Collaborator Author

Follow-up to the automated review of 0c5d913

Addressed in 92c99fb:

  1. Electron firmware IPC exposes private file and network helpers — fixed. The Electron main-process IPC boundary now applies an explicit public-method allowlist to firmwareArtifact. Private validation, download-locking, stream/file-write, promotion, and path-resolution helpers are rejected before dispatch. Regression tests cover every supported public method and representative private/inherited methods.

  2. Desktop Bridge V4 resource plans can execute without a resource payload — intentionally unchanged. Under the current App/SDK upgrade contract, a missing resource payload is an expected valid condition for this path. This PR therefore does not make resource payload presence mandatory and does not change the existing Bridge V4 execution contract.

  3. Android BLE precheck can block USB calls using stale transport state — fixed. The BLE readiness guard now receives the transport resolved for the current call. An explicit Android USB call no longer consults stale persisted BLE transport state, while an explicit BLE call still performs permission and Bluetooth-state checks.

Validation:

  • targeted Jest: 3 suites, 85 tests passed
  • yarn agent:check --profile commit: lint-worktree-ts, lint-staged, and tsc-staged passed
  • GitHub verifies the commit SSH signature

@originalix originalix left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@originalix

Automated code review found blocking issues

Reviewed commit a521b0c7bfb7.

  • P1 · Electron firmware IPC still exposes private file and network helpers
  • P1 · Desktop Bridge V4 still accepts resource targets without a resource payload
  • P2 · Android BLE precheck still runs before current-call transport resolution

View the full review report

@originalix originalix left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@originalix

Automated code review found blocking issues

Reviewed commit 92c99fb5db3e.

  • P1 · Bridge V4 can request a resource update after dropping its payload
  • P2 · A blurred post-update recheck cannot resume

View the full review report

@originalix originalix left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@originalix

Automated code review found blocking issues

Reviewed commit bfcfa009bb5e.

  • P1 · Bridge V4 can request a resource update after dropping its payload
  • P1 · Archive validation does not enforce its entry-count limit
  • P2 · A blurred post-update recheck cannot resume

View the full review report

@originalix originalix left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@originalix

Automated code review found blocking issues

Reviewed commit dba6f7ac0b7a.

  • P1 · Bridge V4 drops the resource payload while retaining the target
  • P1 · Archive validation does not enforce its entry-count limit
  • P2 · A blurred post-update recheck cannot resume

View the full review report

@originalix originalix left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@originalix

Automated code review found blocking issues

Reviewed commit d2576d4a3d20.

  • P1 · Bridge V4 drops the resource payload while retaining the target
  • P1 · Archive validation does not enforce its entry-count limit
  • P2 · A blurred post-update recheck cannot resume

View the full review report

wabicai
wabicai previously approved these changes Aug 8, 2026

@originalix originalix left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@originalix

Automated code review found blocking issues

Reviewed commit 53f35fef7c15.

  • P1 · Bridge V4 drops the resource payload while retaining the target
  • P1 · Archive validation does not enforce its entry-count limit
  • P2 · A blurred post-update recheck cannot resume

View the full review report

@originalix
originalix merged commit 649b882 into hotfix/v6.5.2 Aug 8, 2026
29 checks passed
@originalix
originalix deleted the codex/firmware-upgrade-app-minimal branch August 8, 2026 09:02
originalix added a commit that referenced this pull request Aug 22, 2026
* feat(hardware): add complete OneKey Pro 2 integration (#11814)

* feat(shared): add Pro 2 device foundations

Define canonical protocol V2 device state, connection and routing helpers, firmware config sources, portfolio payload/archive utilities, and Pro 2 media helpers shared across runtimes.

* feat(hardware): integrate Pro 2 background services

Persist canonical device state across main/background runtimes and add Pro 2 USB/BLE onboarding, hidden-wallet sessions, settings, firmware, portfolio sync, NFT transfer, network capability, and WalletConnect handling.

* feat(hardware): add Pro 2 wallet user flows

Expose Pro 2 onboarding, connection state, passphrase and hidden-wallet handling, device settings, brightness, wallpaper, firmware progress, portfolio display, NFT actions, and developer controls in the wallet UI.

* feat(cli): adapt hardware commands for Pro 2

Use the unified hardware SDK queue and device discovery/session data in CLI login and signing flows, with focused regression coverage.

* docs(hardware): document Pro 2 session and portfolio flows

Describe passphrase-wallet session semantics and the implemented portfolio packaging, synchronization, and upload pipeline.

* fix: address Pro 2 review findings

* fix: address remaining Pro 2 review findings

* fix: stabilize Pro 2 device management

* fix: avoid eager hardware SDK import

* fix: sync Pro 2 label validation feedback

* fix: avoid duplicate pin during hardware onboarding

* fix: address Pro 2 review feedback

* fix: prepare Pro 2 prerelease verification

* fix: preserve legacy hardware compatibility

* fix: use SDK Pro2 update targets

* fix: harden hardware device data handling

* fix: preserve hardware settings and safe logs

* fix: tighten Pro2 integration boundaries

* fix: harden Pro2 hardware security flows

* fix: address Pro2 review feedback

* fix: stabilize Pro2 onboarding and hardware sessions

* fix: stabilize hardware account creation

* fix: stabilize Pro2 hardware communication

* perf: lazy load hardware JPEG decoder

* fix: restore Pro2 hidden wallet entry

* fix: handle Pro2 Attach PIN onboarding

* fix: finalize Pro2 production support

* chore: exclude unrelated hotfix changes

* chore: upgrade hardware SDK to alpha.53

* fix: preserve Pro2 onboarding on hotfix

* fix: address Pro2 review feedback

* feat: improve Pro2 device and firmware update flows

* chore: update hardware sdk to 1.2.0-alpha.56

* fix: address Pro2 portfolio and lint review feedback

* fix: preserve hardware device compatibility

* fix: use local database schema version 20

* fix: close final Pro 2 compatibility gaps

* fix: bound firmware recheck wait

* feat(hardware): support Neo Protocol V2 devices (#12766)

* chore: update hardware SDK to alpha.69 (#12780)

* feat: harden firmware upgrade pipeline (#12656)

* feat: harden firmware upgrade pipeline

Stack the firmware-only changes on the hotfix IP Table prerequisite.

* chore: update hardware sdk prerelease

* fix: restore trusted firmware catalog

* fix: remove bundled firmware catalog

* fix: keep hardware available without firmware manifest

* fix: decouple firmware probe from IP routing

* chore: bump range downloader alpha

* fix: sync verified firmware artifact receipts

* chore: update hardware SDK to alpha.72

* chore: update hardware SDK to alpha.73

* chore: update hardware SDK to alpha.74

* chore: update SNI connect to alpha.9

* chore: update hardware SDK to alpha.76

* fix: harden firmware transport boundaries

* chore: update hardware SDK to alpha.77

* fix: serialize iOS hardware dialog transitions

* fix: serialize iOS bootloader dialog handoff

* fix: keep bootloader dialog interactive on iOS

* fix: load Protocol V2 resource archives (#12788)

* fix: clarify Pro2 firmware update workflow guard

* refactor: migrate desktop and webembed to rspack v2 (#12427)

* refactor: migrate desktop and webembed to rspack v2

* fix: unblock rspack migration checks

* fix: add jiti loader to desktop rspack workflows

* fix: strengthen web-embed compatibility checks

* fix: restore desktop rspack defaults

* fix: match spaced script end tags

* fix: harden web-embed script extraction

* fix: harden web-embed production finalization

* fix: finalize desktop production assets

* fix: align node engine with rspack

* fix: align web embed sentry release

* fix: align rspack production config with x

* fix: correct Pro2 portfolio currency conversion

* docs: translate firmware workflow comments

* fix: address Pro2 firmware workflow review feedback

* fix: keep switched firmware wallets manageable

* fix: support manifest-driven Pro2 resources

* fix: align Pro2 and Neo firmware update titles

* fix: sync locale translations

* fix: load protocol v2 resource archives

* fix: enable remote resource archive updates

* fix: address firmware update review feedback

* chore: align hardware sdk alpha versions

* fix: show protocol v2 update versions

* fix: mark resource archive download state

* fix: show protocol v2 component versions

* fix: harden protocol v2 firmware updates

* chore: remove unrelated locale changes

* chore: align locale with hotfix base

* fix: honor protocol v2 forced update targets

* fix: handle protocol v2 resource update overrides

* chore: update hardware sdk to 1.2.0-alpha.84

* refactor: route firmware artifacts through unified downloader

* fix: validate protocol v2 plan targets exactly

* fix: bind firmware host to prepared plan

* fix: allow current firmware artifact host

* fix: compare Protocol V2 resources by default

* chore: update hardware sdk to 1.2.0-alpha.86

* chore: update hardware sdk to 1.2.0-alpha.87

* fix: allow pre-release firmware artifact hosts in developer mode (#12800)

* fix: validate Protocol V2 firmware plans early

* chore: fix firmware artifact lint wording

* fix: consume prepared plans without duplicate inputs

* style: format prepared plan assertion

* fix: address protocol v2 firmware review

* chore: fix firmware UI test import order

* fix: support serial-less protocol v2 updates

* chore: update hardware sdk to 1.2.0-alpha.92

* chore: update hardware sdk to alpha.98

* chore: update hardware sdk to alpha.99

---------

Co-authored-by: huhuanming <huanming@onekey.so>
Co-authored-by: Leon <lixiao.dev@gmail.com>

* fix: pro2 bug fix (#12804)

* chore: update hardware sdk to alpha.100

* fix: align Pro2 device behavior

* fix: upgrade hardware SDK to 1.2.0-alpha.101 (#12808)

* Feat/hw fixes on hotfix652 OK-57549 OK-58650 OK-58579 (#12795)

* feat: offer a firmware update action on the generic hardware error toast

The UnknownHardwareError fallback toast tells users to keep hardware and app
up to date but gave them nothing to act on.

- UnknownHardwareError was the only hardware error class without its own
  `code`, so it fell back to the generic -99999 shared by every OneKey error
  and could not be matched. Give it ECustomOneKeyHardwareError.
  UnknownHardwareError (4033).
- Route that code to a new in-app firmware update action. The existing
  NeedFirmwareUpgradeFromWeb button stays on the web tool, which is what that
  error means.
- The SDK error payload never carries the device it came from, so stamp the
  connectId in withHardwareProcessing's catch and keep the raw payload on
  UnknownHardwareError (message resolution unchanged). Errors raised outside
  the wrapper still work: the ChangeLog page resolves the device itself.
- Add two ErrorToast gallery entries to trigger the toast manually.

* fix: move the device details danger zone below the routine settings

The danger zone sat between Security and Advanced, so a destructive wipe
action was surrounded by everyday settings and easy to hit by mistake. It is
now the last user-facing section, above only the Trezor debug block. Display
conditions are unchanged: still gated on device settings being shown and
still hidden for third-party vendors.

* chore: drop the yalc hardware SDK debug script

Local SDK work goes through the watcher in the SDK repo (dev:core to compile,
debug:watcher to copy dist into this repo's node_modules). This script drove the
older yalc flow, its package.json entry is long gone, and the publish:yalc side
it documents no longer exists either.

* feat: recognize the BLE pairing-cancelled code as a user cancel, not a connect failure

* fix: send a failed Trezor setup back to the device scan instead of retrying a dead address

* fix: keep the translated hardware error copy on the update toast

Passing `message` set normalizeErrorProps' `msg` up front, so its `!msg` i18n
branch never ran and the toast title fell back to the raw device string —
dropping the wallet_action_failed guidance the update button exists to act on.
Only `payload` is needed for the button to reach connectId.

Jest cannot catch this: the i18n branch is behind `!platformEnv.isJest`.

* feat: bridge the BLE release channel through the desktop preload

The keep-alive transport frees a link on a logical NOBLE_BLE_RELEASE signal;
without the preload bridge the idle countdown never starts and every operation
holds the device on the 10-minute busy backstop. keepSession rides the same
call so a mid-flow release keeps the long backstop. The SDK side ships in
1.2.0-alpha.101, already bumped on the base branch.

* fix: address the automated review on the firmware toast action and BLE channel list

Route CheckFirmwareUpdateButton through openChangeLogModal so the extension
popup/side-panel move to an expanded tab and device reachability is checked,
instead of pushing the modal into an ephemeral surface via rootNavigationRef.

Add NOBLE_BLE_RELEASE to the desktop cleanup list. alpha.75 self-clears its
handlers, so this is keeping the host list honest rather than a live fix.

* fix: handle onboarding device scan errors (#12830)

* fix: avoid legacy inputs in prepared firmware V3 (#12828)

* fix: avoid legacy inputs in prepared firmware V3

* test: align firmware self-test with prepared V3 inputs

---------

Co-authored-by: wabiwabo <68363074+wabicai@users.noreply.github.com>

* fix: harden Pro2/Neo recovery, BLE, and resource uploads (#12809)

* fix: refresh Pro2 and Neo state after firmware cancel

* fix: skip stale Pro2 portfolio sync OK-59765

* fix: consume normalized TON signing message

* style: translate firmware state comments to English

* fix: preserve binary payloads across offscreen bridge

* fix: satisfy offscreen lint rules

* fix: secure portfolio retries and BLE wallet creation

* fix: allow hidden-only devices in device management

* refactor: align BLE wallet creation with x branch

* fix: redact TON mismatch logs and cover device removal

* fix: route protocol v2 resource uploads through sdk

* chore: upgrade hardware sdk to alpha.104

* fix: persist selected hardware transport

* fix: resume post-update firmware recheck

* fix: add Pro2 and Neo bootloader minimum versions

* fix: harden firmware recheck and wallpaper uploads

* fix: use sdk auto shutdown options

* fix: defer wallet deprecation after device reset

* fix: handle onboarding device scan errors

* fix: allow sdk-managed protocol v2 firmware updates

* fix: reduce silent portfolio BLE sync

* fix: isolate stale device scan failures

* fix: prevent stale portfolio resume uploads

* fix: harden device scan error handling

* fix: preserve reset session on restarted scans

* fix: bind portfolio sync to connected device

* fix: defer Pro2 identity checks in bootloader

* chore: upgrade hardware sdk to 1.2.0-alpha.106

* fix: translate hardware comments to English

* fix: prevent stale portfolio identity cache reuse

* fix: NFT collect fixes (OK-59979 OK-59980) (#12836)

* fix: restore SDK NFT size lookup in getDeviceNftConfig

* fix: localize Pro2 NFT storage limit error message

* chore: sync translations from Lokalise

* chore: translate NFT storage limit message for all locales

* chore: upgrade sdk (#12838)

* fix: align firmware update device details (#12829)

* fix: close device setting select after change (#12841)

* fix: align prerelease firmware integrity validation (#12843)

* fix: restore Extension firmware update flow (#12851)

* fix: restore Extension firmware update route

* chore: upgrade hardware SDK to alpha.113

* chore: upgrade hardware SDK to alpha.116

* fix: avoid desktop sync IPC for time cache (#12853)

* fix: remove Pro 2 from USB connect device label (#12855)

* chore: upgrade hardware sdk to alpha.118 (#12856)

* chore: upgrade hardware sdk to alpha.119 (#12865)

* fix: skip ble pairing dialog for live ble session OK-60091 (#12861)

* fix: skip ble pairing dialog for live ble session OK-60091

* fix: silent ble bind probe uses silentMode and bounded timeout

* fix: gate silent ble bind behind recent live traffic evidence

* fix: read probe identity from both deviceId and device_id fields

* fix: invalidate live connectId evidence on device disconnect

* chore: add hardware lease and silent ble bind diagnostic logs

* fix: pin known protocol in silent ble bind probe

* test: align firmware detect assertions with ownerName param

* chore: remove hardware diagnostic logs from hotfix

* chore: restore firmware detect test assertions

---------

Co-authored-by: wabiwabo <68363074+wabicai@users.noreply.github.com>

* fix: correct Pro2 settings and label sync(OK-60188, OK-59745, OK-60258) (#12869)

* fix: correct Pro2 settings display

* fix: show Pro2 Bluetooth name

* fix: sync Pro2 device label with wallet name OK-60258

* test: cover Pro2 serial fallback OK-59745

* fix: separate alphabetic portfolio currency symbols OK-59745

* fix: persist Pro2 label through wallet sync OK-60258

* fix: align segmented slider marks OK-60188

* fix: persist Pro2 label after wallet creation OK-60258

* fix: align Pro2 brightness segment values OK-60188

* fix: correct SegmentSlider test import order

* fix: restore firmware-switch device management behavior (OK-60205) (#12877)

* fix: restore firmware-switch device management behavior (OK-60205)

* chore: upgrade hardware sdk to alpha.123 (OK-60205)

* fix: sync portfolio on idle desktop BLE links (#12845)

* fix: sync portfolio on idle desktop BLE links

* chore: upgrade hardware sdk to alpha.115

* chore: upgrade hardware sdk to alpha.117

* chore: upgrade hardware sdk to alpha.118

* fix: preserve desktop usb portfolio sync

* fix: address desktop portfolio review feedback

* fix: scope desktop portfolio transport guard

* fix: preserve hardware transport and portfolio lease

* fix: narrow background transport pinning

* fix: sync V1 device-side settings changes after device operations (OK-60121) (#12879)

* fix: sync V1 device-side settings changes after device operations (OK-60121)

* chore: gate hardware debug file logging behind showDeviceDebugLogs

* chore: route hardware logs through defaultLogger with dev production-parity switch

* chore: add persist-all-logs switch to dev settings

* fix: resolve Copy Log Path via desktopApi on desktop

* fix: address review feedback on log masking, read-back scope and timeout

* fix: harden v1 settings sync per second review round

---------

Co-authored-by: wabiwabo <68363074+wabicai@users.noreply.github.com>

* fix: support Pro2 and Neo BLE flows (#12871)

* fix: add Neo to hardware onboarding

* fix: handle bluetooth usb conflicts

* chore: upgrade hardware sdk to alpha.124

* chore: upgrade hardware sdk to alpha.125

* fix: preserve Pro QR wallet entry

* chore: upgrade hardware sdk to alpha.126

* fix: sync hardware connection status after reset(OK-60117) (#12892)

* fix: sync hardware connection status after reset OK-60117

* fix: clear and rebroadcast hardware connection identities on SDK reset OK-60117

* fix: remove redundant parens flagged by CI lint

* fix: use SDK dimensions for Pro2 images (#12894)

* chore: upgrade hardware SDK to alpha.129 (#12896)

* fix: sync Pro2 settings and send BLE cancel immediately (#12899)

* Fix/trezor ble row heal on hotfix652 OK-60092 (#12900)

* fix: mark ledger btc change outputs with bip32 derivation

Change outputs need bip32/tapBip32 derivation info so the device nets
them out of the confirmed amount instead of displaying them as a
separate recipient; recipient outputs are left untouched.

* chore: drop unused uuid hoisting override from mobile package.json

* fix: derive Ledger BTC Taproot tapInternalKey from xpub, not the address script

Change outputs and inputs on Taproot (BIP86) Ledger accounts previously
computed tapInternalKey by slicing bytes out of the destination address's
own (already-tweaked) output script, which bitcoinjs-lib rejects when
building PSBT outputs ("Script or address mismatch") and silently mis-fed
to the device for inputs. Derive the pre-tweak pubkey from the account's
xpub instead, matching the pattern already used in KeyringHardwareBtcBase
and this file's signPsbt method.

Also fixes a related landmine: xpubSegwit on Taproot accounts holds a
BIP380 descriptor string (tr([fp/path]xpub/<0;1>/*)), not a base58 xpub,
so the existing xpubSegwit-preferring fallback can't be reused for local
key derivation. Taproot branches now read xpub directly.

* Revert "chore: drop unused uuid hoisting override from mobile package.json"

This reverts commit 0818f25.

* fix: type PSBT input/output data precisely instead of any

Addresses PR review: replace inputData/outputData 'any' with the exact
parameter types of Psbt.addInput/addOutput (extracted via Parameters<>,
since bitcoinjs-lib doesn't export PsbtInputExtended/PsbtOutputExtended
by name), so field typos or shape mistakes on the BIP32/Taproot
derivation fields are caught at compile time instead of at Ledger
signing time.

* fix: align hardware errors, wallet state, and Pro2 workflows (#12905)

* fix: handle onboarding hardware errors across runtimes

* fix: handle reset hardware wallet state

* fix: surface hardware errors across workflows

* fix: align Pro2 QR and settings support

* fix: align portfolio token count

* fix: format portfolio token count

* fix: preserve hardware identity across native RPC

* fix: prevent transient empty portfolio sync

* fix: harden Pro2 firmware update flow

* fix: align hardware connection detection with x

* fix: exclude QR wallets from portfolio sync

* fix: keep Pro2 passphrase settings editable

* fix: complete cross-platform firmware update flow

* fix: preserve hardware connection state across runtimes

* chore: update hardware sdk to 1.2.0-alpha.141

* chore: update hardware sdk to 1.2.0-alpha.142

* fix: scope firmware USB preflight to selected device

* fix: order firmware utility imports

* fix: resolve third-party hardware wallet avatars per device model OK-60448 (#12912)

* fix: resolve third-party hardware wallet avatars per device model

Ledger and Trezor wallets all shared one generic placeholder image
regardless of physical model. Add a resolver that maps the device's
persisted vendorModel (SDK code) / vendorModelName to a per-model
avatar key, fix refillWalletInfo (which ran on every wallet read) to
stop forcing avatars back to the generic vendor key, and wire the
resolver through onboarding scan lists, BLE binding, and the Tray.

* chore: trim overlong comments in avatar resolver

* fix: keep neutral vendor fallback avatars for unrecognized devices

The ledger/trezor fallback keys pointed at the new Nano X / Safe 7
artwork, so an unrecognized or metadata-less device would render as
that specific model instead of a neutral placeholder. Restore the
original generic placeholder art for the two fallback keys and add a
regression test asserting they stay byte-distinct from any
specific-model asset.

* fix: seed canonical device state before hidden wallet passphrase session (OK-59992) (#12908)

* fix: seed canonical device state before hidden wallet passphrase session (OK-59992)

* fix: prefer persisted post-unlock device state in hidden wallet creation

* fix: guard post-unlock device state refresh against empty connect id and third-party vendors

* test: cover manifest-free Pro2 RESC archives (#12924)

* test: cover manifest-free RESC archives

* chore: update hardware sdk to 1.2.0-alpha.143

* chore: update hardware sdk to 1.2.0-alpha.144

* fix: correct Ledger Nano Gen5/Flex asset swap and legacy Trezor One code (#12926)

LedgerNanoGen5.png and LedgerFlex.png had their artwork swapped in the
original asset pack; corrected. Also add the legacy 'internal_model'-less
Trezor One firmware model code ('1', reported by pre-internal_model
firmware instead of 'T1B1') to the resolver, verified against a real
device settingsRaw.

* fix: let SDK own hardware Cancel and bump SDK 148 (#12917)

* fix: guide users to repair invalid BLE bonds

* fix: surface USB-priority errors during device verification

* fix: handle BLE USB-priority errors

* fix: align hardware portfolio count with home visible tokens

* fix: make Pro2 firmware dev setting switches toggle reliably

* fix: hide firmware update exit errors after device reconnect

Map updateTasksClear/exitUpdateWorkflow to a device-disconnected
message, and only exit the workflow after the last update page
actually leaves so remounts do not abort an in-progress install.

* fix: send hardware Cancel only for Pro2/Neo

Skip the device Cancel command when Bluetooth pairing or link setup fails, and never emit it on Classic/Mini/Pro1.

* fix: toast when passphrase toggle already matches device

* fix: resolve firmware update TypeScript lint errors

* chore: upgrade hardware SDK to alpha.146

* fix: skip silent portfolio sync while the device is locked

Only transfer when unlocked on USB and BLE. Firmware DeviceLocked
refusals stop the current attempt and do not retry automatically.

* fix: keep firmware cancel, resume locked portfolio, and bump SDK 147

* fix: let SDK own hardware Cancel and bump to alpha.148

* chore: upgrade hardware SDK to alpha.149

* chore: upgrade hardware SDK to alpha.150

* fix: address hardware review comments and iOS Pro2 switches

* fix: restore desktop usb routing OK-60693 (#12940)

* fix: cache the Earn banner list and keep rich text inline when clampe… (#12938)

* fix: cache the Earn banner list and keep rich text inline when clamped (OK-60299)

Signed-off-by: ezailWang <jelly@onekey.so>

* fix: harden the Earn banner request against staleness, failure and disk cost

Signed-off-by: ezailWang <jelly@onekey.so>

---------

Signed-off-by: ezailWang <jelly@onekey.so>

* fix: detect hardware disconnect on desktop USB and BLE (OK-60486) (#12942)

* fix: detect hardware disconnect on desktop USB and BLE (OK-60486)

The wallet-list connected dot reads the union of navigator.usb enumeration and
a background identity-key map. The map is only ever evicted per-device from the
DEVICE.DISCONNECT handler, and on desktop that event never fired, so once any
interaction had populated it the dot stayed lit until an SDK reset.

The missing event is fixed in hardware SDK 1.2.0-alpha.155; bump to it and pass
the new disconnect reason through the preload bridge.

Also guard refreshDevices with a request sequence: the usb disconnect event and
HardwareConnectionStateUpdate can fetch concurrently, and the slower response
could re-light a device that had already gone.

Log the eviction path, which was previously silent — a disconnect that never
arrived and one that left no trace looked identical in collected logs.

* chore: align hardware SDK version in the cli app

The root manifest was bumped to 1.2.0-alpha.155 but apps/cli was left on
alpha.150, which trips the repo's cross-manifest version-consistency check.

* fix: mask the connect id in the disconnect log and align reason comments

serviceHardwareUtils.hardwareLog reaches a @LogToLocal sink, so the raw
connectId would have shipped in exported logs; mask it like the other device
identifiers do.

The reason comments claimed to separate a real drop from a keep-alive
reclaim, which the transport deliberately does not do — every link drop is
reported. Describe what the field is actually for.

* fix: validate Electron update package before install (OK-59014, OK-58098, OK-53765, OK-45636) (#12700)

* fix: validate electron update package availability

* fix: harden electron update package recovery

* docs: explain native update confirmation boundary

* fix: rehydrate macOS updater before install

* fix: reuse cached macOS update package

* fix: handle macOS updater preparation

* fix: address app update recovery review

* fix: harden desktop update recovery

* fix: isolate app update recovery retries

* fix: prevent updater state rebind during install

* fix: rehydrate persisted desktop update packages

* fix: preserve prepared desktop update on check error

* fix: align Pro2/Neo firmware verify, homescreen and BLE name compatibility (#12933)

* fix: canonicalize Pro2 BLE names and bump SDK to alpha.152

Current Pro2 advertisements use "Pro 2 XXXX". Keep matching older
"Pro2 XXXX" names when repairing bleConnectId, and show the spaced
form in device display names.

* style: format Pro2 BLE name helper imports

* fix: enable normal firmware verify for pro2 neo

* fix(v2 firmware verify): align data/dataHex payload format

* fix(v2 firmware verify): restore wallet challenge format

* fix(verify): hash protocol v2 challenge for firmware verify

* fix(verify): use Pro-style challenge bytes for Pro2 and Neo

Keep wallet data as instanceId_timestamp_random and send the UTF-8
bytes to the device, matching Pro. Firmware must accept the variable-length
message instead of a 32-byte digest.

* fix: use native pro2 and neo device types for homescreen api

* fix: use native pro2 and neo labels and firmware detail types

* chore: upgrade hardware SDK to alpha.157

* fix: repair Pro 2 wallet names, labels, and homescreen fallback

Treat compact and spaced BLE names as the same wallet-name pollution,
keep the shared OneKey Pro onboarding copy, and fall back to Pro
homescreens when native Pro 2 or Neo resources are empty.

* fix: request native pro2 and neo homescreens without a Pro fallback

Dashboard should serve Protocol V2 wallpaper types directly.

* fix: keep unpublished Pro 2 and Neo USB copy as OneKey Pro

Connect-your-device still interpolates getDeviceLabel into the USB
prompt, and those products are not public yet.

* chore: upgrade hardware SDK to alpha.159

* fix: map BlePeerRemovedPairingInformation to DeviceBondError

* chore: upgrade hardware SDK to alpha.160

* fix: format bluetooth error test

* chore: upgrade hardware SDK to alpha.162

---------

Co-authored-by: Leon <lixiao.dev@gmail.com>

* fix: support iOS Fabric WebView navigation (#12947)

* fix: prevent iOS address list liquid glass blur (#12948)

* fix: prevent iOS address list liquid glass blur

* fix: harden iOS scroll edge effect binding

---------

Co-authored-by: huhuanming <huanming@onekey.so>

* fix: align Pro2 firmware and portfolio behavior (#12950)

* fix: surface firmware USB priority error

* fix: exclude zero-value tokens from portfolio other count

* chore: bump hardware sdk to 1.2.0-alpha.168

* chore: bump hardware sdk to 1.2.0-alpha.170

* chore: bump hardware sdk to 1.2.0-alpha.171

* chore: bump hardware sdk to 1.2.0-alpha.172

* fix: keep genuine-check verify dialog interactive on iOS retry (#12951)

* fix: keep genuine-check verify dialog interactive on iOS retry

* fix: gate verify dialog in-page host to iOS

---------

Co-authored-by: huhuanming <huanming@onekey.so>

* fix: keep Android browser content above toolbar(OK-60781) (#12955)

* fix: keep Android browser content above toolbar

* fix: keep Android browser dashboard interactive

* chore: upgrade hardware SDK to 1.2.0-alpha.176 (#12954)

* fix: show Protocol V2 custom wallpapers (#12956)

* fix: support Protocol V2 wallpapers

* fix: generate Protocol V2 wallpaper data on client

* refactor: clarify wallpaper upload routing

* fix: align Protocol V2 wallpaper resource type

* fix: reconcile hotfix/v6.5.2 sync residuals with x

* fix: resolve sync PR lint and unit test failures

* ci: raise startup budgets for 6.5.2 hardware SDK weight

* ci: allow eager HardwarePortfolioSync simpleDb entity in bundle architecture check

* fix: make hardwarePortfolioSync simpleDb getter lazy and add missing native-bundle:bg script

---------

Signed-off-by: ezailWang <jelly@onekey.so>
Co-authored-by: wabiwabo <68363074+wabicai@users.noreply.github.com>
Co-authored-by: huhuanming <huanming@onekey.so>
Co-authored-by: ByteZhang <ByteZhang@protonmail.com>
Co-authored-by: JellyWang <38491708+ezailWang@users.noreply.github.com>
Co-authored-by: limichange <limichange@hotmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants