@onekeyfe/hwk-ledger-adapter 1.1.26-alpha.9 → 1.1.27-alpha.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { IHardwareWallet, IConnector, TransportType, UiResponseEvent, DeviceInfo, Response, ChainCapability, EvmGetAddressParams, EvmAddress, ProgressCallback, EvmSignTxParams, EvmSignedTx, EvmSignMsgParams, EvmSignature, EvmSignTypedDataParams, BtcGetAddressParams, BtcAddress, BtcGetPublicKeyParams, BtcPublicKey, BtcSignTxParams, BtcSignedTx, BtcSignPsbtParams, BtcSignedPsbt, BtcSignMsgParams, BtcSignature, SolGetAddressParams, SolAddress, SolSignTxParams, SolSignedTx, SolSignMsgParams, SolSignature, TronGetAddressParams, TronAddress, TronSignTxParams, TronSignedTx, TronSignMsgParams, TronSignature, HardwareEventMap, DeviceEventListener, ChainForFingerprint, ConnectionType, DeviceDescriptor, ConnectorDevice, ConnectorSession, ConnectorEventType, ConnectorEventMap, DeviceChangeEvent, Failure, HardwareErrorCode } from '@onekeyfe/hwk-adapter-core';
2
- import { DeviceManagementKit, DeviceActionState as DeviceActionState$1, DiscoveredDevice, ExecuteDeviceActionReturnType } from '@ledgerhq/device-management-kit';
1
+ import { IHardwareWallet, IConnector, TransportType, UiResponseEvent, DeviceInfo, Response, ChainCapability, EvmGetAddressParams, EvmAddress, EvmSignTxParams, EvmSignedTx, EvmSignMsgParams, EvmSignature, EvmSignTypedDataParams, BtcGetAddressParams, BtcAddress, BtcGetPublicKeyParams, BtcPublicKey, BtcSignTxParams, BtcSignedTx, BtcSignPsbtParams, BtcSignedPsbt, BtcSignMsgParams, BtcSignature, SolGetAddressParams, SolAddress, SolSignTxParams, SolSignedTx, SolSignMsgParams, SolSignature, TronGetAddressParams, TronAddress, TronSignTxParams, TronSignedTx, TronSignMsgParams, TronSignature, HardwareEventMap, DeviceEventListener, ChainForFingerprint, DeviceDescriptor, DeviceChangeEvent, ConnectionType, ConnectorDevice, ConnectorSession, ConnectorEventType, ConnectorEventMap, Failure, HardwareErrorCode } from '@onekeyfe/hwk-adapter-core';
2
+ import { DeviceActionState as DeviceActionState$1, DiscoveredDevice, ExecuteDeviceActionReturnType, DeviceManagementKit } from '@ledgerhq/device-management-kit';
3
3
  import { Address, Signature, SignerEth as SignerEth$1, TypedData } from '@ledgerhq/device-signer-kit-ethereum';
4
4
  import { SignerBtc as SignerBtc$1 } from '@ledgerhq/device-signer-kit-bitcoin';
5
5
  import { SignerSolana } from '@ledgerhq/device-signer-kit-solana';
@@ -13,16 +13,6 @@ interface LedgerAdapterOptions {
13
13
  */
14
14
  handleSelectDevice?: boolean;
15
15
  }
16
- /**
17
- * Ledger hardware wallet adapter that delegates to an IConnector.
18
- *
19
- * This is a thin translation layer that:
20
- * - Accepts a pre-configured IConnector (transport decisions are made at connector creation time)
21
- * - Translates IHardwareWallet method calls to connector.call() invocations
22
- * - Maps connector results/errors to our Response<T> format with enriched error messages
23
- * - Translates connector events to HardwareEventMap events
24
- * - Emits `REQUEST_DEVICE_PERMISSION` for OS-level permission checks
25
- */
26
16
  declare class LedgerAdapter implements IHardwareWallet {
27
17
  readonly vendor: "ledger";
28
18
  private readonly connector;
@@ -31,15 +21,10 @@ declare class LedgerAdapter implements IHardwareWallet {
31
21
  private _discoveredDevices;
32
22
  private _sessions;
33
23
  private readonly _uiRegistry;
24
+ private _btcHighIndexConfirmedThisSession;
34
25
  private readonly _jobQueue;
26
+ private _doConnectAbortController;
35
27
  constructor(connector: IConnector, options?: LedgerAdapterOptions);
36
- /**
37
- * Classify a method's interruptibility.
38
- * - Signing / typed data / transaction → 'confirm' (user may decide via preemption UI)
39
- * - Read-only queries (getAddress / getPublicKey / getMasterFingerprint) → 'safe'
40
- * (auto-cancels any pending read for the same device)
41
- */
42
- private static _getInterruptibility;
43
28
  get activeTransport(): TransportType | null;
44
29
  getAvailableTransports(): TransportType[];
45
30
  switchTransport(_type: TransportType): Promise<void>;
@@ -53,23 +38,20 @@ declare class LedgerAdapter implements IHardwareWallet {
53
38
  dispose(): Promise<void>;
54
39
  uiResponse(response: UiResponseEvent): void;
55
40
  searchDevices(): Promise<DeviceInfo[]>;
41
+ private static readonly MAX_BUSINESS_RETRY_BUDGET;
42
+ private static readonly MAX_DOCONNECT_CONFIRMS;
43
+ private _lastCancelReason;
44
+ private static _createDeviceBusyError;
56
45
  connectDevice(connectId: string): Promise<Response<string>>;
57
46
  disconnectDevice(connectId: string): Promise<void>;
58
47
  getDeviceInfo(connectId: string, deviceId: string): Promise<Response<DeviceInfo>>;
59
48
  getSupportedChains(): ChainCapability[];
60
49
  private callChain;
61
- /**
62
- * Batch version of callChain — checks permission once,
63
- * fingerprint is verified on the first call inside connectorCall.
64
- */
65
- private callChainBatch;
66
50
  evmGetAddress(connectId: string, deviceId: string, params: EvmGetAddressParams): Promise<Response<EvmAddress>>;
67
- evmGetAddresses(connectId: string, deviceId: string, params: EvmGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<EvmAddress[]>>;
68
51
  evmSignTransaction(connectId: string, deviceId: string, params: EvmSignTxParams): Promise<Response<EvmSignedTx>>;
69
52
  evmSignMessage(connectId: string, deviceId: string, params: EvmSignMsgParams): Promise<Response<EvmSignature>>;
70
53
  evmSignTypedData(connectId: string, deviceId: string, params: EvmSignTypedDataParams): Promise<Response<EvmSignature>>;
71
54
  btcGetAddress(connectId: string, deviceId: string, params: BtcGetAddressParams): Promise<Response<BtcAddress>>;
72
- btcGetAddresses(connectId: string, deviceId: string, params: BtcGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<BtcAddress[]>>;
73
55
  btcGetPublicKey(connectId: string, deviceId: string, params: BtcGetPublicKeyParams): Promise<Response<BtcPublicKey>>;
74
56
  btcSignTransaction(connectId: string, deviceId: string, params: BtcSignTxParams): Promise<Response<BtcSignedTx>>;
75
57
  btcSignPsbt(connectId: string, deviceId: string, params: BtcSignPsbtParams): Promise<Response<BtcSignedPsbt>>;
@@ -78,18 +60,16 @@ declare class LedgerAdapter implements IHardwareWallet {
78
60
  masterFingerprint: string;
79
61
  }>>;
80
62
  solGetAddress(connectId: string, deviceId: string, params: SolGetAddressParams): Promise<Response<SolAddress>>;
81
- solGetAddresses(connectId: string, deviceId: string, params: SolGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<SolAddress[]>>;
82
63
  solSignTransaction(connectId: string, deviceId: string, params: SolSignTxParams): Promise<Response<SolSignedTx>>;
83
64
  solSignMessage(connectId: string, deviceId: string, params: SolSignMsgParams): Promise<Response<SolSignature>>;
84
65
  tronGetAddress(connectId: string, deviceId: string, params: TronGetAddressParams): Promise<Response<TronAddress>>;
85
- tronGetAddresses(connectId: string, deviceId: string, params: TronGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<TronAddress[]>>;
86
66
  tronSignTransaction(connectId: string, deviceId: string, params: TronSignTxParams): Promise<Response<TronSignedTx>>;
87
67
  tronSignMessage(connectId: string, deviceId: string, params: TronSignMsgParams): Promise<Response<TronSignature>>;
88
68
  on<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
89
69
  on(event: string, listener: DeviceEventListener): void;
90
70
  off<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
91
71
  off(event: string, listener: DeviceEventListener): void;
92
- cancel(connectId: string): void;
72
+ cancel(connectId?: string): void;
93
73
  getChainFingerprint(connectId: string, deviceId: string, chain: ChainForFingerprint): Promise<Response<string>>;
94
74
  /**
95
75
  * Verify fingerprint using an existing sessionId directly.
@@ -118,12 +98,21 @@ declare class LedgerAdapter implements IHardwareWallet {
118
98
  * - If ANY session exists (Ledger IDs are ephemeral), reuse it.
119
99
  * - Otherwise: search → 1 device: auto-connect, multiple: ask user, 0: throw.
120
100
  */
121
- private static readonly MAX_DEVICE_RETRY;
122
101
  private _connectingPromise;
123
102
  private _waitForDeviceConnect;
103
+ /**
104
+ * Decide whether a BTC pubkey call needs `showOnDevice=true` because of
105
+ * the BTC App's account-index policy, asking the user once per session.
106
+ *
107
+ * Returns the params to pass through (with `showOnDevice` possibly
108
+ * promoted), or `null` if the user declined.
109
+ */
110
+ private _gateBtcHighIndex;
111
+ private _waitForBtcHighIndexConfirm;
124
112
  private ensureConnected;
125
113
  private _doConnect;
126
114
  private _connectFirstOrSelect;
115
+ private _connectDeviceOrThrow;
127
116
  private _chooseDeviceFromList;
128
117
  /**
129
118
  * Call the connector with automatic session resolution and disconnect retry.
@@ -135,16 +124,21 @@ declare class LedgerAdapter implements IHardwareWallet {
135
124
  */
136
125
  private connectorCall;
137
126
  /**
138
- * Race a promise against an abort signal. If the signal fires, rejects with the
139
- * signal's reason (or a generic Error). The underlying connector.call() cannot
140
- * actually be cancelled on Ledger DMK, but the caller gets the abort immediately.
127
+ * Race a promise against an abort signal. On abort, rejects with
128
+ * signal.reason instance _lastCancelReason → generic Error('Aborted').
141
129
  */
142
- private static _abortable;
130
+ private _abortable;
143
131
  /** Throw an AbortError if signal is already aborted. */
144
132
  private static _throwIfAborted;
145
133
  /** Actual work done under the job queue — connection, fingerprint, call, and recovery. */
146
134
  private _runConnectorCall;
147
- /** Clear stale session, reconnect, and retry the call. */
135
+ /**
136
+ * Clear stale session, reconnect, and retry the call.
137
+ *
138
+ * Timeout recovery starts with a full connector reset. After an APDU
139
+ * timeout, DMK/transport state may still emit malformed responses; retrying
140
+ * on the same DMK can poison the next chain switch.
141
+ */
148
142
  private _retryWithFreshConnection;
149
143
  /**
150
144
  * Ensure OS-level device permission (Bluetooth / USB) before proceeding.
@@ -172,6 +166,103 @@ declare class LedgerAdapter implements IHardwareWallet {
172
166
  private connectorDeviceToDeviceInfo;
173
167
  }
174
168
 
169
+ /**
170
+ * Re-export DMK types under local aliases for backward compatibility.
171
+ * These replace the previous duck-typed interfaces with the real SDK types.
172
+ */
173
+ type DmkDiscoveredDevice = DiscoveredDevice;
174
+ /**
175
+ * DMK DeviceAction — the Observable-based return type of all DMK signer methods.
176
+ *
177
+ * This is a permissive alias for `ExecuteDeviceActionReturnType` that accepts
178
+ * any Error and IntermediateValue generics. Signer wrapper code only cares about
179
+ * the Output type and the observable/cancel shape.
180
+ */
181
+ type DeviceAction<T> = ExecuteDeviceActionReturnType<T, any, any>;
182
+ /**
183
+ * DMK DeviceActionState — re-exported with permissive Error/IntermediateValue.
184
+ * The real type is a discriminated union on `status`.
185
+ */
186
+ type DeviceActionState<T> = DeviceActionState$1<T, any, any>;
187
+ /** ETH address result — re-exported from DMK for backward compatibility. */
188
+ type SignerEvmAddress = Address;
189
+ /** ETH signature result — re-exported from DMK for backward compatibility. */
190
+ type SignerEvmSignature = Signature;
191
+ /** BTC address result (WalletAddress not exported from DMK top-level). */
192
+ interface SignerBtcAddress {
193
+ address: string;
194
+ }
195
+
196
+ /**
197
+ * Manages device discovery, connection, and session tracking.
198
+ * Wraps DMK's Observable APIs into simpler imperative calls.
199
+ */
200
+ declare class LedgerDeviceManager {
201
+ private readonly _dmk;
202
+ private readonly _discovered;
203
+ private readonly _sessions;
204
+ private readonly _sessionToDevice;
205
+ private _listenSub;
206
+ constructor(dmk: DeviceManagementKit);
207
+ /**
208
+ * One-shot enumeration: subscribe to listenToAvailableDevices,
209
+ * take the first emission, unsubscribe, return DeviceDescriptors.
210
+ */
211
+ enumerate(): Promise<DeviceDescriptor[]>;
212
+ /**
213
+ * Continuous listening: tracks device connect/disconnect via diffing.
214
+ */
215
+ listen(onChange: (event: DeviceChangeEvent) => void): void;
216
+ stopListening(): void;
217
+ /**
218
+ * Resolve to the latest snapshot of advertising devices observed within
219
+ * `timeoutMs`. Rewrites `_discovered` so it tracks the live list.
220
+ *
221
+ * `listenToAvailableDevices` is a BehaviorSubject — it emits the cached
222
+ * list on subscribe and *only* re-emits when the list changes. A stable
223
+ * list of currently-advertising devices therefore produces only the
224
+ * subscription frame; treating that frame as "fossil to be discarded"
225
+ * caused devices to flicker in/out of the UI as searches alternated
226
+ * between "saw a change frame" and "saw only the cached frame".
227
+ *
228
+ * The window still gives a chance for the active scan to update the list
229
+ * (e.g. drop a peripheral that just stopped broadcasting), but if nothing
230
+ * changes we trust the snapshot — DMK silence on a stable list means
231
+ * "everything's still there".
232
+ */
233
+ getLiveDevices(timeoutMs?: number): Promise<DmkDiscoveredDevice[]>;
234
+ /**
235
+ * Trigger browser device selection (WebHID requestDevice).
236
+ * Starts discovery for a short period, then stops.
237
+ */
238
+ /**
239
+ * Start BLE discovery if not already running.
240
+ * Does NOT stop — DMK keeps scanning in the background so that
241
+ * listenToAvailableDevices() always has fresh data.
242
+ */
243
+ private _discoverySub;
244
+ requestDevice(): Promise<void>;
245
+ /** Lookup a previously-discovered device's display name. */
246
+ getDeviceName(deviceId: string): string | undefined;
247
+ /** Connect to a previously discovered device. Returns sessionId. */
248
+ connect(deviceId: string): Promise<string>;
249
+ /** Disconnect a session. */
250
+ disconnect(sessionId: string): Promise<void>;
251
+ getSessionId(deviceId: string): string | undefined;
252
+ getDeviceId(sessionId: string): string | undefined;
253
+ /** Get the underlying DMK instance (needed by SignerManager). */
254
+ getDmk(): DeviceManagementKit;
255
+ stopDiscovery(): void;
256
+ dispose(): void;
257
+ /**
258
+ * Tear down RxJS subscriptions and local state without closing the DMK.
259
+ * For light-reset paths that want to drop session state but keep the
260
+ * underlying transport alive for retry. Call this instead of orphaning
261
+ * the manager — bare null assignment leaks _listenSub / _discoverySub.
262
+ */
263
+ disposeKeepingDmk(): void;
264
+ }
265
+
175
266
  /**
176
267
  * A function that lazily loads and returns the transport factory
177
268
  * for the Ledger DMK builder (e.g. webHidTransportFactory, rnBleTransportFactory).
@@ -209,13 +300,12 @@ declare class LedgerConnectorBase implements IConnector {
209
300
  readonly connectionType: ConnectionType;
210
301
  private _connectIdToPath;
211
302
  private _pathToConnectId;
212
- /** Register a connectId <-> path mapping from a device descriptor. */
213
- private _registerDeviceId;
214
303
  /** Get DMK path from external connectId. Falls back to connectId itself. */
215
304
  private _getPathForConnectId;
216
305
  /** Get external connectId from DMK path. Falls back to path itself. */
217
306
  private _getConnectIdForPath;
218
307
  private readonly _cancellers;
308
+ private readonly _sessionStateSubs;
219
309
  /**
220
310
  * Resolves a Ledger signer kit module by package name.
221
311
  * Override via constructor to use CJS paths for Metro (React Native).
@@ -240,10 +330,30 @@ declare class LedgerConnectorBase implements IConnector {
240
330
  * Override in subclasses to extract stable identifiers (e.g. BLE hex ID).
241
331
  */
242
332
  protected _resolveConnectId(descriptor: DeviceDescriptor): string;
333
+ /**
334
+ * Authoritative discovery for this transport. Default = enumerate snapshot
335
+ * (USB/HID). BLE overrides to drive from a live scan window since DMK's
336
+ * enumerate() cache survives peripherals going offline.
337
+ */
338
+ protected _discoverDescriptors(dm: LedgerDeviceManager): Promise<DeviceDescriptor[]>;
243
339
  searchDevices(): Promise<ConnectorDevice[]>;
244
340
  connect(deviceId?: string): Promise<ConnectorSession>;
245
341
  disconnect(sessionId: string): Promise<void>;
342
+ /**
343
+ * Subscribe to DMK's per-session state observable so that any autonomous
344
+ * disconnect (USB unplug, BLE drop, device sleep, transport reset) is
345
+ * surfaced as a `device-disconnect` event — without this, the upstream
346
+ * `LedgerAdapter._sessions` map would hold a dead session entry until
347
+ * the next call hit `DeviceSessionNotFound`.
348
+ *
349
+ * Best-effort: any error subscribing is swallowed so a flaky DMK
350
+ * doesn't break the connect path.
351
+ */
352
+ private _watchSessionState;
353
+ private _unwatchSessionState;
354
+ private _handleAutonomousDisconnect;
246
355
  call(sessionId: string, method: string, params: unknown): Promise<unknown>;
356
+ private _dispatch;
247
357
  cancel(sessionId: string): Promise<void>;
248
358
  uiResponse(_response: UiResponseEvent): void;
249
359
  on<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;
@@ -266,8 +376,12 @@ declare class LedgerConnectorBase implements IConnector {
266
376
  */
267
377
  private _replaceSession;
268
378
  /**
269
- * Light reset: clear signer/session state but keep DMK, BLE scan, and ID mapping alive.
379
+ * Light reset: clear signer/session state but keep DMK and ID mapping alive.
270
380
  * Used by connect() retry — we want to re-discover with the same transport.
381
+ *
382
+ * Note: drops the device manager but tears down its RxJS subs first via
383
+ * disposeKeepingDmk(). Bare null-assignment would leak _listenSub /
384
+ * _discoverySub and double-scan after the next _initManagers().
271
385
  */
272
386
  private _resetSignersAndSessions;
273
387
  private _resetAll;
@@ -281,76 +395,30 @@ declare class LedgerConnectorBase implements IConnector {
281
395
  private _wrapError;
282
396
  }
283
397
 
284
- /**
285
- * Manages device discovery, connection, and session tracking.
286
- * Wraps DMK's Observable APIs into simpler imperative calls.
287
- */
288
- declare class LedgerDeviceManager {
289
- private readonly _dmk;
290
- private readonly _discovered;
291
- private readonly _sessions;
292
- private readonly _sessionToDevice;
293
- private _listenSub;
294
- constructor(dmk: DeviceManagementKit);
295
- /**
296
- * One-shot enumeration: subscribe to listenToAvailableDevices,
297
- * take the first emission, unsubscribe, return DeviceDescriptors.
298
- */
299
- enumerate(): Promise<DeviceDescriptor[]>;
300
- /**
301
- * Continuous listening: tracks device connect/disconnect via diffing.
302
- */
303
- listen(onChange: (event: DeviceChangeEvent) => void): void;
304
- stopListening(): void;
305
- /**
306
- * Trigger browser device selection (WebHID requestDevice).
307
- * Starts discovery for a short period, then stops.
308
- */
309
- /**
310
- * Start BLE discovery if not already running.
311
- * Does NOT stop — DMK keeps scanning in the background so that
312
- * listenToAvailableDevices() always has fresh data.
313
- */
314
- private _discoverySub;
315
- requestDevice(): Promise<void>;
316
- /** Connect to a previously discovered device. Returns sessionId. */
317
- connect(deviceId: string): Promise<string>;
318
- /** Disconnect a session. */
319
- disconnect(sessionId: string): Promise<void>;
320
- getSessionId(deviceId: string): string | undefined;
321
- getDeviceId(sessionId: string): string | undefined;
322
- /** Get the underlying DMK instance (needed by SignerManager). */
323
- getDmk(): DeviceManagementKit;
324
- stopDiscovery(): void;
325
- dispose(): void;
398
+ /** Optional context attached to the rejection when a canceller fires. */
399
+ interface CancelReason {
400
+ code?: number;
401
+ tag?: string;
402
+ message?: string;
326
403
  }
327
-
328
404
  /**
329
- * Re-export DMK types under local aliases for backward compatibility.
330
- * These replace the previous duck-typed interfaces with the real SDK types.
331
- */
332
- type DmkDiscoveredDevice = DiscoveredDevice;
333
- /**
334
- * DMK DeviceAction — the Observable-based return type of all DMK signer methods.
405
+ * Convert a DMK DeviceAction (Observable-based) into a Promise.
406
+ * Handles pending -> completed/error state transitions and interaction callbacks.
335
407
  *
336
- * This is a permissive alias for `ExecuteDeviceActionReturnType` that accepts
337
- * any Error and IntermediateValue generics. Signer wrapper code only cares about
338
- * the Output type and the observable/cancel shape.
339
- */
340
- type DeviceAction<T> = ExecuteDeviceActionReturnType<T, any, any>;
341
- /**
342
- * DMK DeviceActionState re-exported with permissive Error/IntermediateValue.
343
- * The real type is a discriminated union on `status`.
408
+ * Tracks the last DMK step observed (e.g. `signer.eth.steps.blindSignTransactionFallback`)
409
+ * and attaches it to the rejected error as a non-enumerable `_lastStep` property,
410
+ * so upstream error classifiers can distinguish failure contexts (e.g. Blind signing
411
+ * disabled vs. generic Invalid data).
412
+ *
413
+ * @param timeoutMs Idle watchdog ms. Re-armed on each emission, paused
414
+ * during interactive pending. 0 disables. Default 65s
415
+ * (covers DMK's 60s + margin; we're a backstop only).
416
+ * @param onRegisterCanceller Optional callback that receives a function which, when
417
+ * called, unsubscribes and cancels the underlying DeviceAction
418
+ * (releases DMK's IntentQueue slot). Caller is responsible
419
+ * for invoking the canceller on timeout/abort scenarios.
344
420
  */
345
- type DeviceActionState<T> = DeviceActionState$1<T, any, any>;
346
- /** ETH address result — re-exported from DMK for backward compatibility. */
347
- type SignerEvmAddress = Address;
348
- /** ETH signature result — re-exported from DMK for backward compatibility. */
349
- type SignerEvmSignature = Signature;
350
- /** BTC address result (WalletAddress not exported from DMK top-level). */
351
- interface SignerBtcAddress {
352
- address: string;
353
- }
421
+ declare function deviceActionToPromise<T>(action: DeviceAction<T>, onInteraction?: (interaction: string) => void, timeoutMs?: number, onRegisterCanceller?: (cancel: (reason?: CancelReason) => void) => void): Promise<T>;
354
422
 
355
423
  /**
356
424
  * Wraps Ledger's SDK signer (Observable-based DeviceActions) into
@@ -365,7 +433,7 @@ declare class SignerEth {
365
433
  * for the underlying DeviceAction. Caller can invoke it to release DMK's
366
434
  * IntentQueue slot and unsubscribe from the action's observable.
367
435
  */
368
- onRegisterCanceller?: (cancel: () => void) => void;
436
+ onRegisterCanceller?: (cancel: (reason?: CancelReason) => void) => void;
369
437
  getAddress(derivationPath: string, options?: {
370
438
  checkOnDevice?: boolean;
371
439
  }): Promise<SignerEvmAddress>;
@@ -408,7 +476,7 @@ type BtcMessageOptions = Parameters<SignerBtc$1['signMessage']>[2];
408
476
  declare class SignerBtc {
409
477
  private readonly _sdk;
410
478
  onInteraction?: (interaction: string) => void;
411
- onRegisterCanceller?: (cancel: () => void) => void;
479
+ onRegisterCanceller?: (cancel: (reason?: CancelReason) => void) => void;
412
480
  constructor(_sdk: SignerBtc$1);
413
481
  getWalletAddress(wallet: BtcWallet, addressIndex: number, options?: {
414
482
  checkOnDevice?: boolean;
@@ -454,7 +522,7 @@ type SolMsgOptions = Parameters<SignerSolana['signMessage']>[2];
454
522
  declare class SignerSol {
455
523
  private readonly _sdk;
456
524
  onInteraction?: (interaction: string) => void;
457
- onRegisterCanceller?: (cancel: () => void) => void;
525
+ onRegisterCanceller?: (cancel: (reason?: CancelReason) => void) => void;
458
526
  constructor(_sdk: SignerSolana);
459
527
  /**
460
528
  * Get the Solana address (base58-encoded Ed25519 public key) at the given derivation path.
@@ -495,24 +563,6 @@ declare class DmkTransport extends Transport {
495
563
  close(): Promise<void>;
496
564
  }
497
565
 
498
- /**
499
- * Convert a DMK DeviceAction (Observable-based) into a Promise.
500
- * Handles pending -> completed/error state transitions and interaction callbacks.
501
- *
502
- * Tracks the last DMK step observed (e.g. `signer.eth.steps.blindSignTransactionFallback`)
503
- * and attaches it to the rejected error as a non-enumerable `_lastStep` property,
504
- * so upstream error classifiers can distinguish failure contexts (e.g. Blind signing
505
- * disabled vs. generic Invalid data).
506
- *
507
- * @param timeoutMs Timeout in ms. Resets each time the Observable emits (device is alive).
508
- * Pass 0 to disable. Default: 30s.
509
- * @param onRegisterCanceller Optional callback that receives a function which, when
510
- * called, unsubscribes and cancels the underlying DeviceAction
511
- * (releases DMK's IntentQueue slot). Caller is responsible
512
- * for invoking the canceller on timeout/abort scenarios.
513
- */
514
- declare function deviceActionToPromise<T>(action: DeviceAction<T>, onInteraction?: (interaction: string) => void, timeoutMs?: number, onRegisterCanceller?: (cancel: () => void) => void): Promise<T>;
515
-
516
566
  interface AppManagerOptions {
517
567
  waitMs?: number;
518
568
  maxRetries?: number;
@@ -566,30 +616,17 @@ declare class AppManager {
566
616
  private _wait;
567
617
  }
568
618
 
569
- /**
570
- * Ledger-specific Failure: adds `appName` for "the currently-open app" — a
571
- * Ledger hardware concept not shared with other vendors, so it lives here
572
- * rather than in core's generic Failure.
573
- */
574
619
  type LedgerFailure = Omit<Failure, 'payload'> & {
575
620
  payload: Failure['payload'] & {
576
621
  appName?: string;
622
+ _tag?: string;
577
623
  };
578
624
  };
579
625
  interface WrapErrorOptions {
580
- /**
581
- * Fallback app name when the raw error doesn't carry `appName` itself
582
- * (DMK signer errors don't). Used by mapLedgerError so downstream
583
- * AppNotOpen / WrongApp / AppTooOld toasts can interpolate `{appName}`.
584
- */
626
+ /** Fallback when err has no `appName` (DMK signer errors don't carry it). */
585
627
  defaultAppName?: string;
586
628
  }
587
- /**
588
- * Structurally compatible with `Failure`; writes `appName` only when provided,
589
- * so `'appName' in payload` is a reliable "has info" signal for consumers.
590
- */
591
- declare function ledgerFailure(code: HardwareErrorCode, error: string, appName?: string): LedgerFailure;
592
- /** Check if an error (or any error in its chain) represents a locked Ledger device. */
629
+ declare function ledgerFailure(code: HardwareErrorCode, error: string, appName?: string, tag?: string, params?: Record<string, unknown>): LedgerFailure;
593
630
  declare function isDeviceLockedError(err: unknown): boolean;
594
631
  /**
595
632
  * Map a Ledger DMK error to a HardwareErrorCode and human-readable message.
@@ -603,14 +640,20 @@ declare function mapLedgerError(err: unknown, opts?: WrapErrorOptions): {
603
640
  };
604
641
 
605
642
  /**
606
- * Centralised debug logger for the Ledger adapter.
607
- *
608
- * Off by default. Toggle programmatically via `setDebugEnabled(true)`.
643
+ * SDK-global event bus. Per-runtime singleton each process subscribes
644
+ * independently; cross-process hosts forward events over their own IPC.
609
645
  */
610
- /** Enable or disable debug logging at runtime. */
611
- declare function setDebugEnabled(value: boolean): void;
612
- /** Returns the current debug-enabled state. */
613
- declare function isDebugEnabled(): boolean;
646
+ type SdkLogEvent = {
647
+ type: 'log';
648
+ level: 'debug' | 'error';
649
+ /** Pre-stringified payload. */
650
+ message: string;
651
+ };
652
+ /** Add new variants here; hosts dispatch on `event.type`. */
653
+ type SdkEvent = SdkLogEvent;
654
+ type SdkEventListener = (event: SdkEvent) => void;
655
+ declare function onSdkEvent(listener: SdkEventListener): () => void;
656
+ declare function offSdkEvent(listener: SdkEventListener): void;
614
657
 
615
658
  /**
616
659
  * Extract the stable 4-digit HEX identifier from a Ledger BLE device name.
@@ -619,4 +662,19 @@ declare function isDebugEnabled(): boolean;
619
662
  */
620
663
  declare function extractBleHexId(name?: string): string | undefined;
621
664
 
622
- export { AppManager, type DeviceActionState, type DmkDiscoveredDevice, DmkTransport, LedgerAdapter, LedgerConnectorBase, type LedgerConnectorBaseOptions, LedgerDeviceManager, type LedgerFailure, SignerBtc, type SignerBtcAddress, SignerEth, type SignerEvmAddress, type SignerEvmSignature, SignerManager, SignerSol, type TransportFactory, deviceActionToPromise, extractBleHexId, isDebugEnabled, isDeviceLockedError, ledgerFailure, mapLedgerError, setDebugEnabled };
665
+ /**
666
+ * Ledger DMK transport identifiers that represent BLE devices.
667
+ *
668
+ * Known today:
669
+ * - "BLE": generic/web BLE descriptors
670
+ * - "RN_BLE": @ledgerhq/device-transport-kit-react-native-ble
671
+ *
672
+ * Keep the suffix check here so future DMK BLE transports (for example
673
+ * "FOO_BLE") are handled in one place instead of scattering string checks.
674
+ */
675
+ declare function isLedgerDmkBleTransport(transport?: string): boolean;
676
+ declare function isLedgerBleConnectionType(connectionType?: ConnectionType): boolean;
677
+ declare function isLedgerBleDescriptor(connectionType: ConnectionType, descriptor: DeviceDescriptor): boolean;
678
+ declare function isValidLedgerBleConnectId(connectId?: string): boolean;
679
+
680
+ export { AppManager, type DeviceActionState, type DmkDiscoveredDevice, DmkTransport, LedgerAdapter, LedgerConnectorBase, type LedgerConnectorBaseOptions, LedgerDeviceManager, type LedgerFailure, type SdkEvent, type SdkEventListener, type SdkLogEvent, SignerBtc, type SignerBtcAddress, SignerEth, type SignerEvmAddress, type SignerEvmSignature, SignerManager, SignerSol, type TransportFactory, deviceActionToPromise, extractBleHexId, isDeviceLockedError, isLedgerBleConnectionType, isLedgerBleDescriptor, isLedgerDmkBleTransport, isValidLedgerBleConnectId, ledgerFailure, mapLedgerError, offSdkEvent, onSdkEvent };