Skip to content

Feat/ton sign data#778

Merged
ByteZhang1024 merged 18 commits intoonekeyfrom
feat/tonSignData
Apr 29, 2026
Merged

Feat/ton sign data#778
ByteZhang1024 merged 18 commits intoonekeyfrom
feat/tonSignData

Conversation

@ByteZhang1024
Copy link
Copy Markdown
Contributor

No description provided.

@revan-zhang
Copy link
Copy Markdown
Contributor

revan-zhang commented Apr 28, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

Comment thread packages/core/src/api/ton/TonSignData.ts Outdated
Comment thread packages/hwk-ledger-adapter/src/connector/LedgerConnectorBase.ts
- New `tonSignData` method dispatching firmware TonSignData/TonSignedData
  for text/binary/cell payload signing, mirroring the TonSignProof shape.
- Re-export TonSignDataType as a runtime value from @onekeyfe/hd-core so
  consumers can use the enum (previously only re-exported as a type, so
  `TonSignDataType.TEXT` threw at runtime).
- Map firmware Failure_PinMismatch to new HardwareErrorCode.PinMismatch
  (828); surfaced only in set/change-PIN flows, so not added to the
  session-release list.
- Regenerate hd-transport messages.ts and core messages.json from the
  updated firmware proto.
App-side now subscribes hardware UI events from a single hw.on(...) bus
instead of mixing connector.on('ui-event') with hw.on(UI_REQUEST.X).
LedgerAdapter forwards the connector 'ui-event' channel onto its own
emitter so the four EConnectorInteraction values (ConfirmOnDevice /
ConfirmOpenApp / UnlockDevice / InteractionComplete) reach consumers
through the same surface as REQUEST_DEVICE_PERMISSION etc. The dead
'ui-request_confirmation' → REQUEST_BUTTON path and its 'ui-request'
listener are removed.

Legacy-SDK chains (TRON today, future XRP/ADA/DOT) now go through a
single withLegacyChainCall wrapper that owns the full lifecycle:
pre-flight ensureAppOpen, ConfirmOnDevice/InteractionComplete pairing,
wrong-app retry, and symmetric UI cleanup on failure paths. TRON
handlers shrink ~40% and stop reimplementing the open-app boilerplate.

AppManager.ensureAppOpen invokes the onConfirmOnDevice callback BEFORE
issuing the blocking OpenAppCommand APDU; previously the prompt event
fired after the user had already confirmed on-device, so UI consumers
showed and immediately closed the "open app" toast. The fallback path
also closes any lingering ConfirmOpenApp prompt when ensureAppOpen
itself throws (e.g. 0x6807 app-not-installed).

mapLedgerError accepts an optional defaultAppName so DMK signer errors
(which lack appName) get a chain-bound fallback. LedgerConnectorBase
.dispatcher injects this once per call via _ctxForMethod, keeping
chain handlers' wrapError calls a single line. Downstream the App
layer's ThirdPartyAppNotInstalled toast can interpolate {appName}
across all chains, not just TRON.

Adds focused debug logs at points where, when bugs occur, no upstream
log can localize the failure: AppManager (currentApp / closeApp /
openApp statusCode / waitForApp exhausted), legacyChainCall decision
points (pre-flight failure / non-wrong-app / wrong-app retry /
retry failure / retry success), and BTC wallet template selection.
…ched labels

Two independent bugs combined to make a single physical Ledger appear as
two devices in the discovered list — one labelled with its real name and
one labelled "Ledger".

1. LedgerAdapter.searchDevices() accumulated entries instead of replacing
   them. DMK assigns ephemeral UUIDs as USB device paths (which we use as
   connectId), so each replug produced a fresh connectId while the prior
   connectId still sat in the cache pointing at a device DMK no longer
   recognized. Fix: clear the cache before writing this round's raw result
   so it always reflects current discovery state.

2. LedgerConnectorBase.connect() emitted 'device-connect' with a hardcoded
   `name: 'Ledger'` placeholder. The adapter's deviceConnectHandler then
   wrote that placeholder over the real label that searchDevices() had
   just stored. Fix: capture the searchDevices() return value at connect
   entry and emit the real name found by connectId; fall back to 'Ledger'
   only if the device isn't in this round's discovery.

Both fixes are required: clearing the cache without fixing the emit still
leaves the active device's label clobbered by the placeholder; fixing the
emit without clearing the cache still leaves stale connectId entries from
prior plug events.
…sink

Hosts now inject a typed logger callback instead of toggling a boolean
to switch console output on/off. Makes SDK debug output flow into the
host's existing logging pipeline (e.g. defaultLogger.hardware.sdkLog).

  setLogger((level, ...args) => { ... })  // host-supplied
  debugLog('[X]', value)  // routed through the injected sink

Removes setDebugEnabled / isDebugEnabled. SDK no longer holds a
console-output flag; not injecting a logger means the SDK is silent.

Cross-runtime note: this module's `logger` is a per-process singleton.
Hosts that span multiple runtimes (e.g. MV3 extensions where the SW
holds the adapter and an offscreen document holds the connector) must
call setLogger from each runtime — they don't share state.
Replaces the single-sink setLogger callback with a typed event bus,
matching the pattern OneKey's own hd-core uses (addHardwareGlobalEventListener).

  onSdkEvent((event) => {
    if (event.type === 'log') /* ... */
  })

`SdkEvent` is a discriminated union — currently `{ type: 'log', level,
message }`. Future variants (firmware progress, battery state, ...)
extend the union and host adapters dispatch via the same subscription.

Why this matters for cross-runtime integration: hosts that span SW ↔
offscreen (MV3 extensions) or main ↔ renderer (Electron) wire one IPC
channel that forwards the whole `SdkEvent` payload. Adding a new event
variant doesn't require a new IPC route, a new subscriber, or a new
host-side handler — the dispatch is data-driven on `event.type`.

debugLog/debugError now `emitSdkEvent({type: 'log', ...})` internally;
hosts that want logs subscribe and route to their logger pipeline.
With no subscribers the bus skips stringification, so the SDK has zero
overhead when nobody's listening.

Removes setLogger / Logger / LogLevel exports.
…Bus comments

Adds a single debugLog at each chain's signer.onInteraction site so the
raw DMK interaction string (verify-address / sign-transaction /
confirm-open-app / interaction-complete / unlock-device / ...) is
visible in the host's SDK log scope. Without it, the entire device-side
state machine between IO start and IO end is a black box — useful for
diagnosing UI-event timing questions like "did verify-address actually
fire on the device" or "where did app-switch insert itself".

Trims redundant prose from sdkEventBus.ts and debugLog.ts that the file
header / function name already conveys.
- TonSignData: restore getVersionRange(). With strictCheckDeviceSupport=true
  the core consults this method's version matrix; an empty range causes
  every device to be classified as unsupported and the TonSignData typedCall
  is rejected before run() ever fires. Aligned with TonSignMessage's
  getFixInitStateErrorVersionRange — bump when the firmware ships TonSignData.

- LedgerConnectorBase.call: stop logging full call params via
  JSON.stringify(params). Now that debugLog flows through onSdkEvent into
  the host's defaultLogger pipeline, sensitive payloads (serializedTx,
  psbt, rawTxHex, messageHex, typed data) would propagate to telemetry /
  persistent stores. Replaced with summarizeCallParams() which surfaces
  only path, length-of-payload, and harmless flags.
- TonSignData: drop strictCheckDeviceSupport (set to false) and remove
  getVersionRange(). Firmware version that ships TonSignData isn't decided
  yet; gating now would lock out every connected device. Re-enable both
  once the touch/classic1s min versions are known.

- LedgerConnectorBase.call: restore JSON.stringify(params) in debugLog.
  Log bus only feeds the host's local defaultLogger pipeline (no third-party
  telemetry forwarding), so full params are acceptable for now and useful
  for in-the-wild debugging.
@ByteZhang1024 ByteZhang1024 enabled auto-merge (squash) April 28, 2026 05:43
…scalation

Core fix
- LedgerConnectorBase subscribes to DMK getDeviceSessionState per active
  session and emits device-disconnect the moment DMK reports the device
  went to NOT_CONNECTED. Without this the upstream _sessions map kept
  dead entries until the next call hit DeviceSessionNotFound (the
  "empty connectId picks a stale session" bug after replug / process
  restart / abnormal teardown).
- _retryWithFreshConnection: when the inner fresh-session retry still
  fails with disconnect/timeout, escalate to connector.reset() to drop
  and rebuild DMK + transport, then retry once more. Covers DMK
  internal state wedge that normal retry can't recover from.

Diagnostic logging (validation paths)
- LedgerConnectorBase.searchDevices: entry/exit logs (count, ids, paths)
- LedgerConnectorBase: long-lived listenToAvailableDevices subscription
  that logs only (no behaviour) — used to verify that DMK proactively
  re-emits on USB unplug. Confirmed working in real-device repro.
- LedgerDeviceManager.enumerate: include device ids in raw count log
- LedgerAdapter.searchDevices: entry + return logs with cache size

Dead-code purge
- Drop unused batch APIs callChainBatch + evm/btc/sol/tronGetAddresses
  and matching interface declarations in hwk-adapter-core. Drop the
  now-orphan ProgressCallback type and re-export. Zero callers verified
  across OneKey app-monorepo and hwk-* packages.
…ecovery

- User clicks app cancel UI → signal.reason carries UserAborted (10005)
- Autonomous disconnect → canceller reason tags DeviceDisconnected (10101)
- Chain app stuck mid-step (UnknownDeviceExchangeError) → escalate to connector.reset()
All three names from @onekeyfe/hd-transport are used in type position
only (AlephiumSignedTx / AlephiumSignTx / TypedCall). Switching to
`import type` clears the consistent-type-imports warning that surfaces
in CI's full-repo `eslint .` scan. Pre-existing; not introduced by
this branch.
Add two HardwareErrorCodes — DeviceAppStuck (10107) for a wedged chain
app (e.g. Ledger BTC 0x6901) and ChainNotSupported (10108) for vendors
that don't support a chain at all.

LedgerConnectorBase.call now catches the stuck-app signal and rethrows
as a DeviceAppStuck error so the host app can prompt the user to exit
the app on-device. LedgerAdapter stops attempting silent retry-with-
reset for stuck state — only manual on-device exit recovers, so the
retry path was masking the real failure.
Firmware encodes the field as uint64; JS `number` loses precision on
values past 2^53-1. UintType (string|number union) matches the rest of
the protobuf-generated message types and lets callers pass a string
when needed.
isStuckAppStateError now also matches:
- _tag === 'AlreadySendingApduError': raised when a previous stuck call
  left DMK's IntentQueue slot held, so the next call fails synchronously.
- APDU 6901 anywhere in the wrapped error chain: caller-side wrappers
  sometimes hide the original _tag, so we fall back to the raw status.

Without these, the adapter misclassified post-stuck calls as generic
errors and skipped the DeviceAppStuck escalation.
@ByteZhang1024 ByteZhang1024 merged commit 3bb38cb into onekey Apr 29, 2026
9 checks passed
@ByteZhang1024 ByteZhang1024 deleted the feat/tonSignData branch April 29, 2026 07:42
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.

4 participants