@onekeyfe/hwk-ledger-adapter 1.1.26-alpha.106 → 1.1.26-alpha.12
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 +275 -132
- package/dist/index.d.ts +275 -132
- package/dist/index.js +1682 -706
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1656 -685
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IHardwareWallet, IConnector, TransportType,
|
|
2
|
-
import {
|
|
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,30 +13,21 @@ 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
|
-
* - Integrates with IUiHandler for permission flows
|
|
25
|
-
*/
|
|
26
16
|
declare class LedgerAdapter implements IHardwareWallet {
|
|
27
17
|
readonly vendor: "ledger";
|
|
28
18
|
private readonly connector;
|
|
29
19
|
private readonly emitter;
|
|
30
|
-
private _uiHandler;
|
|
31
20
|
private readonly _handleSelectDevice;
|
|
32
21
|
private _discoveredDevices;
|
|
33
22
|
private _sessions;
|
|
34
23
|
private readonly _uiRegistry;
|
|
24
|
+
private _btcHighIndexConfirmedThisSession;
|
|
25
|
+
private readonly _jobQueue;
|
|
26
|
+
private _doConnectAbortController;
|
|
35
27
|
constructor(connector: IConnector, options?: LedgerAdapterOptions);
|
|
36
28
|
get activeTransport(): TransportType | null;
|
|
37
29
|
getAvailableTransports(): TransportType[];
|
|
38
30
|
switchTransport(_type: TransportType): Promise<void>;
|
|
39
|
-
setUiHandler(handler: Partial<IUiHandler>): void;
|
|
40
31
|
init(_config?: unknown): Promise<void>;
|
|
41
32
|
/**
|
|
42
33
|
* Clear cached device/session state without tearing down the adapter.
|
|
@@ -47,23 +38,20 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
47
38
|
dispose(): Promise<void>;
|
|
48
39
|
uiResponse(response: UiResponseEvent): void;
|
|
49
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;
|
|
50
45
|
connectDevice(connectId: string): Promise<Response<string>>;
|
|
51
46
|
disconnectDevice(connectId: string): Promise<void>;
|
|
52
47
|
getDeviceInfo(connectId: string, deviceId: string): Promise<Response<DeviceInfo>>;
|
|
53
48
|
getSupportedChains(): ChainCapability[];
|
|
54
49
|
private callChain;
|
|
55
|
-
/**
|
|
56
|
-
* Batch version of callChain — checks permission once,
|
|
57
|
-
* fingerprint is verified on the first call inside connectorCall.
|
|
58
|
-
*/
|
|
59
|
-
private callChainBatch;
|
|
60
50
|
evmGetAddress(connectId: string, deviceId: string, params: EvmGetAddressParams): Promise<Response<EvmAddress>>;
|
|
61
|
-
evmGetAddresses(connectId: string, deviceId: string, params: EvmGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<EvmAddress[]>>;
|
|
62
51
|
evmSignTransaction(connectId: string, deviceId: string, params: EvmSignTxParams): Promise<Response<EvmSignedTx>>;
|
|
63
52
|
evmSignMessage(connectId: string, deviceId: string, params: EvmSignMsgParams): Promise<Response<EvmSignature>>;
|
|
64
53
|
evmSignTypedData(connectId: string, deviceId: string, params: EvmSignTypedDataParams): Promise<Response<EvmSignature>>;
|
|
65
54
|
btcGetAddress(connectId: string, deviceId: string, params: BtcGetAddressParams): Promise<Response<BtcAddress>>;
|
|
66
|
-
btcGetAddresses(connectId: string, deviceId: string, params: BtcGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<BtcAddress[]>>;
|
|
67
55
|
btcGetPublicKey(connectId: string, deviceId: string, params: BtcGetPublicKeyParams): Promise<Response<BtcPublicKey>>;
|
|
68
56
|
btcSignTransaction(connectId: string, deviceId: string, params: BtcSignTxParams): Promise<Response<BtcSignedTx>>;
|
|
69
57
|
btcSignPsbt(connectId: string, deviceId: string, params: BtcSignPsbtParams): Promise<Response<BtcSignedPsbt>>;
|
|
@@ -72,18 +60,16 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
72
60
|
masterFingerprint: string;
|
|
73
61
|
}>>;
|
|
74
62
|
solGetAddress(connectId: string, deviceId: string, params: SolGetAddressParams): Promise<Response<SolAddress>>;
|
|
75
|
-
solGetAddresses(connectId: string, deviceId: string, params: SolGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<SolAddress[]>>;
|
|
76
63
|
solSignTransaction(connectId: string, deviceId: string, params: SolSignTxParams): Promise<Response<SolSignedTx>>;
|
|
77
64
|
solSignMessage(connectId: string, deviceId: string, params: SolSignMsgParams): Promise<Response<SolSignature>>;
|
|
78
65
|
tronGetAddress(connectId: string, deviceId: string, params: TronGetAddressParams): Promise<Response<TronAddress>>;
|
|
79
|
-
tronGetAddresses(connectId: string, deviceId: string, params: TronGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<TronAddress[]>>;
|
|
80
66
|
tronSignTransaction(connectId: string, deviceId: string, params: TronSignTxParams): Promise<Response<TronSignedTx>>;
|
|
81
67
|
tronSignMessage(connectId: string, deviceId: string, params: TronSignMsgParams): Promise<Response<TronSignature>>;
|
|
82
68
|
on<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
|
|
83
69
|
on(event: string, listener: DeviceEventListener): void;
|
|
84
70
|
off<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
|
|
85
71
|
off(event: string, listener: DeviceEventListener): void;
|
|
86
|
-
cancel(connectId
|
|
72
|
+
cancel(connectId?: string): void;
|
|
87
73
|
getChainFingerprint(connectId: string, deviceId: string, chain: ChainForFingerprint): Promise<Response<string>>;
|
|
88
74
|
/**
|
|
89
75
|
* Verify fingerprint using an existing sessionId directly.
|
|
@@ -112,12 +98,21 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
112
98
|
* - If ANY session exists (Ledger IDs are ephemeral), reuse it.
|
|
113
99
|
* - Otherwise: search → 1 device: auto-connect, multiple: ask user, 0: throw.
|
|
114
100
|
*/
|
|
115
|
-
private static readonly MAX_DEVICE_RETRY;
|
|
116
101
|
private _connectingPromise;
|
|
117
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;
|
|
118
112
|
private ensureConnected;
|
|
119
113
|
private _doConnect;
|
|
120
114
|
private _connectFirstOrSelect;
|
|
115
|
+
private _connectDeviceOrThrow;
|
|
121
116
|
private _chooseDeviceFromList;
|
|
122
117
|
/**
|
|
123
118
|
* Call the connector with automatic session resolution and disconnect retry.
|
|
@@ -128,13 +123,34 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
128
123
|
* 4. On disconnect error: clears stale session, re-connects, retries once
|
|
129
124
|
*/
|
|
130
125
|
private connectorCall;
|
|
131
|
-
/**
|
|
126
|
+
/**
|
|
127
|
+
* Race a promise against an abort signal. On abort, rejects with
|
|
128
|
+
* signal.reason → instance _lastCancelReason → generic Error('Aborted').
|
|
129
|
+
*/
|
|
130
|
+
private _abortable;
|
|
131
|
+
/** Throw an AbortError if signal is already aborted. */
|
|
132
|
+
private static _throwIfAborted;
|
|
133
|
+
/** Actual work done under the job queue — connection, fingerprint, call, and recovery. */
|
|
134
|
+
private _runConnectorCall;
|
|
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
|
+
*/
|
|
132
142
|
private _retryWithFreshConnection;
|
|
133
143
|
/**
|
|
134
|
-
* Ensure device permission before proceeding.
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
144
|
+
* Ensure OS-level device permission (Bluetooth / USB) before proceeding.
|
|
145
|
+
*
|
|
146
|
+
* Emits `REQUEST_DEVICE_PERMISSION` and awaits the consumer's
|
|
147
|
+
* `RECEIVE_DEVICE_PERMISSION` reply (60s budget covers "probe → system
|
|
148
|
+
* prompt → user tap" plus a generous margin). If the consumer never wires
|
|
149
|
+
* a handler or never replies, the wait times out and the operation fails
|
|
150
|
+
* fast so scanners/callers don't hang silently.
|
|
151
|
+
*
|
|
152
|
+
* - No connectId (searchDevices): environment-level permission
|
|
153
|
+
* - With connectId (business methods): device-level permission
|
|
138
154
|
*/
|
|
139
155
|
private _ensureDevicePermission;
|
|
140
156
|
/**
|
|
@@ -144,14 +160,107 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
144
160
|
private errorToFailure;
|
|
145
161
|
private deviceConnectHandler;
|
|
146
162
|
private deviceDisconnectHandler;
|
|
147
|
-
private
|
|
148
|
-
private uiEventHandler;
|
|
163
|
+
private uiEventForwarder;
|
|
149
164
|
private registerEventListeners;
|
|
150
165
|
private unregisterEventListeners;
|
|
151
|
-
private handleUiEvent;
|
|
152
166
|
private connectorDeviceToDeviceInfo;
|
|
153
|
-
|
|
154
|
-
|
|
167
|
+
}
|
|
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;
|
|
155
264
|
}
|
|
156
265
|
|
|
157
266
|
/**
|
|
@@ -188,15 +297,15 @@ declare class LedgerConnectorBase implements IConnector {
|
|
|
188
297
|
private readonly _eventHandlers;
|
|
189
298
|
private readonly _providedDmk;
|
|
190
299
|
private readonly _createTransport;
|
|
191
|
-
|
|
300
|
+
readonly connectionType: ConnectionType;
|
|
192
301
|
private _connectIdToPath;
|
|
193
302
|
private _pathToConnectId;
|
|
194
|
-
/** Register a connectId <-> path mapping from a device descriptor. */
|
|
195
|
-
private _registerDeviceId;
|
|
196
303
|
/** Get DMK path from external connectId. Falls back to connectId itself. */
|
|
197
304
|
private _getPathForConnectId;
|
|
198
305
|
/** Get external connectId from DMK path. Falls back to path itself. */
|
|
199
306
|
private _getConnectIdForPath;
|
|
307
|
+
private readonly _cancellers;
|
|
308
|
+
private readonly _sessionStateSubs;
|
|
200
309
|
/**
|
|
201
310
|
* Resolves a Ledger signer kit module by package name.
|
|
202
311
|
* Override via constructor to use CJS paths for Metro (React Native).
|
|
@@ -221,11 +330,31 @@ declare class LedgerConnectorBase implements IConnector {
|
|
|
221
330
|
* Override in subclasses to extract stable identifiers (e.g. BLE hex ID).
|
|
222
331
|
*/
|
|
223
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[]>;
|
|
224
339
|
searchDevices(): Promise<ConnectorDevice[]>;
|
|
225
340
|
connect(deviceId?: string): Promise<ConnectorSession>;
|
|
226
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;
|
|
227
355
|
call(sessionId: string, method: string, params: unknown): Promise<unknown>;
|
|
228
|
-
|
|
356
|
+
private _dispatch;
|
|
357
|
+
cancel(sessionId: string): Promise<void>;
|
|
229
358
|
uiResponse(_response: UiResponseEvent): void;
|
|
230
359
|
on<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;
|
|
231
360
|
off<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;
|
|
@@ -247,85 +376,49 @@ declare class LedgerConnectorBase implements IConnector {
|
|
|
247
376
|
*/
|
|
248
377
|
private _replaceSession;
|
|
249
378
|
/**
|
|
250
|
-
* Light reset: clear signer/session state but keep DMK
|
|
379
|
+
* Light reset: clear signer/session state but keep DMK and ID mapping alive.
|
|
251
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().
|
|
252
385
|
*/
|
|
253
386
|
private _resetSignersAndSessions;
|
|
254
387
|
private _resetAll;
|
|
255
388
|
protected _emit<K extends ConnectorEventType>(event: K, data: ConnectorEventMap[K]): void;
|
|
256
|
-
private _wrapError;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Manages device discovery, connection, and session tracking.
|
|
261
|
-
* Wraps DMK's Observable APIs into simpler imperative calls.
|
|
262
|
-
*/
|
|
263
|
-
declare class LedgerDeviceManager {
|
|
264
|
-
private readonly _dmk;
|
|
265
|
-
private readonly _discovered;
|
|
266
|
-
private readonly _sessions;
|
|
267
|
-
private readonly _sessionToDevice;
|
|
268
|
-
private _listenSub;
|
|
269
|
-
constructor(dmk: DeviceManagementKit);
|
|
270
|
-
/**
|
|
271
|
-
* One-shot enumeration: subscribe to listenToAvailableDevices,
|
|
272
|
-
* take the first emission, unsubscribe, return DeviceDescriptors.
|
|
273
|
-
*/
|
|
274
|
-
enumerate(): Promise<DeviceDescriptor[]>;
|
|
275
389
|
/**
|
|
276
|
-
*
|
|
390
|
+
* Return a per-call ctx with the chain's Ledger app name pre-bound to
|
|
391
|
+
* wrapError, so chain handlers don't need to repeat `{ defaultAppName: 'X' }`
|
|
392
|
+
* at every catch site. Falls through unchanged for unknown methods.
|
|
277
393
|
*/
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Trigger browser device selection (WebHID requestDevice).
|
|
282
|
-
* Starts discovery for a short period, then stops.
|
|
283
|
-
*/
|
|
284
|
-
/**
|
|
285
|
-
* Start BLE discovery if not already running.
|
|
286
|
-
* Does NOT stop — DMK keeps scanning in the background so that
|
|
287
|
-
* listenToAvailableDevices() always has fresh data.
|
|
288
|
-
*/
|
|
289
|
-
private _discoverySub;
|
|
290
|
-
requestDevice(): Promise<void>;
|
|
291
|
-
/** Connect to a previously discovered device. Returns sessionId. */
|
|
292
|
-
connect(deviceId: string): Promise<string>;
|
|
293
|
-
/** Disconnect a session. */
|
|
294
|
-
disconnect(sessionId: string): Promise<void>;
|
|
295
|
-
getSessionId(deviceId: string): string | undefined;
|
|
296
|
-
getDeviceId(sessionId: string): string | undefined;
|
|
297
|
-
/** Get the underlying DMK instance (needed by SignerManager). */
|
|
298
|
-
getDmk(): DeviceManagementKit;
|
|
299
|
-
stopDiscovery(): void;
|
|
300
|
-
dispose(): void;
|
|
394
|
+
private _ctxForMethod;
|
|
395
|
+
private _wrapError;
|
|
301
396
|
}
|
|
302
397
|
|
|
398
|
+
/** Optional context attached to the rejection when a canceller fires. */
|
|
399
|
+
interface CancelReason {
|
|
400
|
+
code?: number;
|
|
401
|
+
tag?: string;
|
|
402
|
+
message?: string;
|
|
403
|
+
}
|
|
303
404
|
/**
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*/
|
|
307
|
-
type DmkDiscoveredDevice = DiscoveredDevice;
|
|
308
|
-
/**
|
|
309
|
-
* 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.
|
|
310
407
|
*
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
*
|
|
318
|
-
*
|
|
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.
|
|
319
420
|
*/
|
|
320
|
-
|
|
321
|
-
/** ETH address result — re-exported from DMK for backward compatibility. */
|
|
322
|
-
type SignerEvmAddress = Address;
|
|
323
|
-
/** ETH signature result — re-exported from DMK for backward compatibility. */
|
|
324
|
-
type SignerEvmSignature = Signature;
|
|
325
|
-
/** BTC address result (WalletAddress not exported from DMK top-level). */
|
|
326
|
-
interface SignerBtcAddress {
|
|
327
|
-
address: string;
|
|
328
|
-
}
|
|
421
|
+
declare function deviceActionToPromise<T>(action: DeviceAction<T>, onInteraction?: (interaction: string) => void, timeoutMs?: number, onRegisterCanceller?: (cancel: (reason?: CancelReason) => void) => void): Promise<T>;
|
|
329
422
|
|
|
330
423
|
/**
|
|
331
424
|
* Wraps Ledger's SDK signer (Observable-based DeviceActions) into
|
|
@@ -335,6 +428,12 @@ declare class SignerEth {
|
|
|
335
428
|
private readonly _sdk;
|
|
336
429
|
onInteraction?: (interaction: string) => void;
|
|
337
430
|
constructor(_sdk: SignerEth$1);
|
|
431
|
+
/**
|
|
432
|
+
* Optional callback registered per-call so the caller can obtain a canceller
|
|
433
|
+
* for the underlying DeviceAction. Caller can invoke it to release DMK's
|
|
434
|
+
* IntentQueue slot and unsubscribe from the action's observable.
|
|
435
|
+
*/
|
|
436
|
+
onRegisterCanceller?: (cancel: (reason?: CancelReason) => void) => void;
|
|
338
437
|
getAddress(derivationPath: string, options?: {
|
|
339
438
|
checkOnDevice?: boolean;
|
|
340
439
|
}): Promise<SignerEvmAddress>;
|
|
@@ -352,16 +451,16 @@ type SignerEthBuilderFn = (args: {
|
|
|
352
451
|
build(): SignerEth$1;
|
|
353
452
|
}>;
|
|
354
453
|
/**
|
|
355
|
-
*
|
|
356
|
-
*
|
|
454
|
+
* Per-sessionId SignerEth factory. Builds fresh on every call — DMK signers
|
|
455
|
+
* hold DeviceAction state that isn't safe to reuse, so `invalidate` /
|
|
456
|
+
* `clearAll` are kept as no-op lifecycle hooks for callers.
|
|
357
457
|
*/
|
|
358
458
|
declare class SignerManager {
|
|
359
|
-
private readonly _cache;
|
|
360
459
|
private readonly _dmk;
|
|
361
460
|
private readonly _builderFn;
|
|
362
461
|
constructor(dmk: DeviceManagementKit, builderFn?: SignerEthBuilderFn);
|
|
363
462
|
getOrCreate(sessionId: string): Promise<SignerEth>;
|
|
364
|
-
invalidate(
|
|
463
|
+
invalidate(_sessionId: string): void;
|
|
365
464
|
clearAll(): void;
|
|
366
465
|
private static _defaultBuilder;
|
|
367
466
|
}
|
|
@@ -377,6 +476,7 @@ type BtcMessageOptions = Parameters<SignerBtc$1['signMessage']>[2];
|
|
|
377
476
|
declare class SignerBtc {
|
|
378
477
|
private readonly _sdk;
|
|
379
478
|
onInteraction?: (interaction: string) => void;
|
|
479
|
+
onRegisterCanceller?: (cancel: (reason?: CancelReason) => void) => void;
|
|
380
480
|
constructor(_sdk: SignerBtc$1);
|
|
381
481
|
getWalletAddress(wallet: BtcWallet, addressIndex: number, options?: {
|
|
382
482
|
checkOnDevice?: boolean;
|
|
@@ -422,6 +522,7 @@ type SolMsgOptions = Parameters<SignerSolana['signMessage']>[2];
|
|
|
422
522
|
declare class SignerSol {
|
|
423
523
|
private readonly _sdk;
|
|
424
524
|
onInteraction?: (interaction: string) => void;
|
|
525
|
+
onRegisterCanceller?: (cancel: (reason?: CancelReason) => void) => void;
|
|
425
526
|
constructor(_sdk: SignerSolana);
|
|
426
527
|
/**
|
|
427
528
|
* Get the Solana address (base58-encoded Ed25519 public key) at the given derivation path.
|
|
@@ -462,20 +563,6 @@ declare class DmkTransport extends Transport {
|
|
|
462
563
|
close(): Promise<void>;
|
|
463
564
|
}
|
|
464
565
|
|
|
465
|
-
/**
|
|
466
|
-
* Convert a DMK DeviceAction (Observable-based) into a Promise.
|
|
467
|
-
* Handles pending -> completed/error state transitions and interaction callbacks.
|
|
468
|
-
*
|
|
469
|
-
* Tracks the last DMK step observed (e.g. `signer.eth.steps.blindSignTransactionFallback`)
|
|
470
|
-
* and attaches it to the rejected error as a non-enumerable `_lastStep` property,
|
|
471
|
-
* so upstream error classifiers can distinguish failure contexts (e.g. Blind signing
|
|
472
|
-
* disabled vs. generic Invalid data).
|
|
473
|
-
*
|
|
474
|
-
* @param timeoutMs Timeout in ms. Resets each time the Observable emits (device is alive).
|
|
475
|
-
* Pass 0 to disable. Default: 30s.
|
|
476
|
-
*/
|
|
477
|
-
declare function deviceActionToPromise<T>(action: DeviceAction<T>, onInteraction?: (interaction: string) => void, timeoutMs?: number): Promise<T>;
|
|
478
|
-
|
|
479
566
|
interface AppManagerOptions {
|
|
480
567
|
waitMs?: number;
|
|
481
568
|
maxRetries?: number;
|
|
@@ -505,9 +592,16 @@ declare class AppManager {
|
|
|
505
592
|
* 5. Poll until the device confirms the target app is running.
|
|
506
593
|
*/
|
|
507
594
|
/**
|
|
508
|
-
* @param onConfirmOnDevice Called
|
|
509
|
-
*
|
|
510
|
-
*
|
|
595
|
+
* @param onConfirmOnDevice Called BEFORE OpenAppCommand is issued — the
|
|
596
|
+
* device is about to display "Open <app>" on screen and wait for the
|
|
597
|
+
* user's button press. UI consumers should show their "open app" prompt
|
|
598
|
+
* in response. NOT called when the target app is already open (no user
|
|
599
|
+
* interaction needed in that case).
|
|
600
|
+
*
|
|
601
|
+
* Important: OpenAppCommand is blocking. It does not resolve until the user
|
|
602
|
+
* has physically confirmed on the device, so anything that runs AFTER
|
|
603
|
+
* `await this._openApp(...)` lands AFTER the prompt is already gone.
|
|
604
|
+
* Hence the callback must fire BEFORE that await.
|
|
511
605
|
*/
|
|
512
606
|
ensureAppOpen(sessionId: string, targetAppName: string, onConfirmOnDevice?: () => void): Promise<void>;
|
|
513
607
|
private _getCurrentApp;
|
|
@@ -522,16 +616,65 @@ declare class AppManager {
|
|
|
522
616
|
private _wait;
|
|
523
617
|
}
|
|
524
618
|
|
|
525
|
-
|
|
619
|
+
type LedgerFailure = Omit<Failure, 'payload'> & {
|
|
620
|
+
payload: Failure['payload'] & {
|
|
621
|
+
appName?: string;
|
|
622
|
+
_tag?: string;
|
|
623
|
+
};
|
|
624
|
+
};
|
|
625
|
+
interface WrapErrorOptions {
|
|
626
|
+
/** Fallback when err has no `appName` (DMK signer errors don't carry it). */
|
|
627
|
+
defaultAppName?: string;
|
|
628
|
+
}
|
|
629
|
+
declare function ledgerFailure(code: HardwareErrorCode, error: string, appName?: string, tag?: string, params?: Record<string, unknown>): LedgerFailure;
|
|
526
630
|
declare function isDeviceLockedError(err: unknown): boolean;
|
|
527
631
|
/**
|
|
528
|
-
* Map a Ledger DMK error to a HardwareErrorCode and human-readable message
|
|
529
|
-
*
|
|
632
|
+
* Map a Ledger DMK error to a HardwareErrorCode and human-readable message.
|
|
633
|
+
* `opts.defaultAppName` fills `appName` when the raw error doesn't carry it
|
|
634
|
+
* (DMK signer errors don't).
|
|
530
635
|
*/
|
|
531
|
-
declare function mapLedgerError(err: unknown): {
|
|
636
|
+
declare function mapLedgerError(err: unknown, opts?: WrapErrorOptions): {
|
|
532
637
|
code: HardwareErrorCode;
|
|
533
638
|
message: string;
|
|
534
639
|
appName?: string;
|
|
535
640
|
};
|
|
536
641
|
|
|
537
|
-
|
|
642
|
+
/**
|
|
643
|
+
* SDK-global event bus. Per-runtime singleton — each process subscribes
|
|
644
|
+
* independently; cross-process hosts forward events over their own IPC.
|
|
645
|
+
*/
|
|
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;
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Extract the stable 4-digit HEX identifier from a Ledger BLE device name.
|
|
660
|
+
* e.g., "Nano X 123A" -> "123A", "Ledger Nano X AB12" -> "AB12"
|
|
661
|
+
* Returns undefined if no valid HEX suffix found.
|
|
662
|
+
*/
|
|
663
|
+
declare function extractBleHexId(name?: string): string | undefined;
|
|
664
|
+
|
|
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 };
|