@onekeyfe/hwk-adapter-core 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 +382 -339
- package/dist/index.d.ts +382 -339
- package/dist/index.js +195 -184
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +194 -184
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -1,38 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HWK HardwareErrorCode — independent namespace from the legacy
|
|
3
|
+
* `@onekeyfe/shared` HardwareErrorCode (which occupies 0-902).
|
|
4
|
+
*
|
|
5
|
+
* All HWK codes are 5-digit (>= 10000) so the two tables never collide
|
|
6
|
+
* even if either side grows. Each sub-category gets a 100-slot block.
|
|
7
|
+
*
|
|
8
|
+
* 10000-10099 Generic / cross-cutting primitives
|
|
9
|
+
* 10100-10199 Device state
|
|
10
|
+
* 10200-10299 Firmware
|
|
11
|
+
* 10300-10399 Transport + OS-level permission
|
|
12
|
+
* 10400-10499 PIN / Passphrase
|
|
13
|
+
* 10500-10599 App lifecycle (wrong app, not open, too old)
|
|
14
|
+
* 10600-10999 RESERVED — future adapter-level categories
|
|
15
|
+
*
|
|
16
|
+
* 11000-11099 EVM APDU (reactive mapping)
|
|
17
|
+
* 11100-11199 Solana APDU
|
|
18
|
+
* 11200-11299 Tron APDU
|
|
19
|
+
* 11300-11399 BTC APDU
|
|
20
|
+
* 11400-11999 RESERVED — future chain APDU blocks (100 per chain)
|
|
21
|
+
*
|
|
22
|
+
* 12000-99999 RESERVED — future major categories
|
|
23
|
+
*/
|
|
1
24
|
declare enum HardwareErrorCode {
|
|
2
|
-
UnknownError =
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
UnknownError = 10000,
|
|
26
|
+
UserRejected = 10001,
|
|
27
|
+
InvalidParams = 10002,
|
|
28
|
+
OperationTimeout = 10003,
|
|
29
|
+
MethodNotSupported = 10004,
|
|
30
|
+
/** User dismissed in-app cancel UI. Distinct from UserRejected (on-device). */
|
|
31
|
+
UserAborted = 10005,
|
|
32
|
+
DeviceNotFound = 10100,
|
|
33
|
+
DeviceDisconnected = 10101,
|
|
34
|
+
DeviceBusy = 10102,
|
|
35
|
+
DeviceLocked = 10103,
|
|
36
|
+
DeviceNotInitialized = 10104,
|
|
37
|
+
DeviceInBootloader = 10105,
|
|
38
|
+
DeviceMismatch = 10106,
|
|
39
|
+
/** Chain app wedged (e.g. Ledger BTC 0x6901). User must exit app on device. */
|
|
40
|
+
DeviceAppStuck = 10107,
|
|
41
|
+
/** Vendor (Ledger / Trezor) doesn't support the chain at all. */
|
|
42
|
+
ChainNotSupported = 10108,
|
|
43
|
+
FirmwareTooOld = 10200,
|
|
44
|
+
FirmwareUpdateRequired = 10201,
|
|
45
|
+
TransportError = 10300,
|
|
46
|
+
BridgeNotFound = 10301,
|
|
47
|
+
TransportNotAvailable = 10302,
|
|
48
|
+
/**
|
|
49
|
+
* OS-level permission (Bluetooth / USB / etc.) — denied, blocked,
|
|
50
|
+
* unavailable, or dismissed. Consumers surface a single "please grant
|
|
51
|
+
* permission" toast and let the user retry manually.
|
|
52
|
+
*/
|
|
53
|
+
DevicePermissionDenied = 10303,
|
|
54
|
+
/**
|
|
55
|
+
* BLE SMP pairing did not complete within the GATT bonding window.
|
|
56
|
+
* GATT connected but the device didn't acknowledge SMP — typically
|
|
57
|
+
* because the user didn't confirm the passkey on the device, or the
|
|
58
|
+
* device went out of range mid-pairing. Distinct from OperationTimeout
|
|
59
|
+
* (generic) and from DeviceLocked (Secure Element actually locked).
|
|
60
|
+
*/
|
|
61
|
+
BlePairingTimeout = 10304,
|
|
62
|
+
PinInvalid = 10400,
|
|
63
|
+
PinCancelled = 10401,
|
|
64
|
+
PassphraseRejected = 10402,
|
|
65
|
+
/** Chain app NOT INSTALLED on device. User must install via Ledger Live. */
|
|
66
|
+
AppNotInstalled = 10500,
|
|
67
|
+
WrongApp = 10501,
|
|
68
|
+
/** 0x911c Command code not supported — app predates current SDK. */
|
|
69
|
+
AppTooOld = 10502,
|
|
24
70
|
/** 0x6a80 Invalid data — observed on blindSignTransactionFallback when the
|
|
25
71
|
* user has not enabled Blind signing on the device. */
|
|
26
|
-
EvmBlindSigningRequired =
|
|
72
|
+
EvmBlindSigningRequired = 11000,
|
|
27
73
|
/** 0x6984 Plugin not installed */
|
|
28
|
-
EvmClearSignPluginMissing =
|
|
74
|
+
EvmClearSignPluginMissing = 11001,
|
|
29
75
|
/** 0x6a84 Insufficient memory (typical on Nano S with large calldata) */
|
|
30
|
-
EvmDataTooLarge =
|
|
76
|
+
EvmDataTooLarge = 11002,
|
|
31
77
|
/** 0x6501 TransactionType not supported (app too old for EIP-1559 / blob / 7702) */
|
|
32
|
-
EvmTxTypeNotSupported =
|
|
33
|
-
/**
|
|
34
|
-
|
|
78
|
+
EvmTxTypeNotSupported = 11003,
|
|
79
|
+
/** 0x6808 Blind signing disabled for this instruction. */
|
|
80
|
+
SolanaBlindSigningRequired = 11100,
|
|
81
|
+
/** 0x6a8d Custom Contracts setting disabled (blocks TRC-20 etc.). */
|
|
82
|
+
TronCustomContractRequired = 11200,
|
|
83
|
+
/** 0x6a8b Transactions Data setting disabled. */
|
|
84
|
+
TronDataSigningRequired = 11201,
|
|
85
|
+
/** 0x6a8c Sign by Hash setting disabled (hash-signing fallback). */
|
|
86
|
+
TronSignByHashRequired = 11202,
|
|
87
|
+
/** 0xb008 Wallet policy HMAC mismatch or not registered. */
|
|
88
|
+
BtcWalletPolicyHmacMismatch = 11300,
|
|
89
|
+
/** 0xb007 Aborted due to unexpected state (malformed PSBT / missing UTXO). */
|
|
90
|
+
BtcUnexpectedState = 11301
|
|
35
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Device-level failures the SDK cannot self-recover from — affect the entire
|
|
94
|
+
* batch (vs per-chain failures like AppNotInstalled / WrongApp which soft-
|
|
95
|
+
* skip in onboarding). Combined with `accounts.length === 0`, signals
|
|
96
|
+
* genuine orphan. Also reused as the batch-abort whitelist for HWK.
|
|
97
|
+
* Single source of truth.
|
|
98
|
+
*
|
|
99
|
+
* UserRejected (device-side reject) is included: pressing reject is an
|
|
100
|
+
* explicit "I don't consent" — continuing the batch to ask again on the
|
|
101
|
+
* next chain is harassment, not helpful.
|
|
102
|
+
*/
|
|
103
|
+
declare const ORPHAN_ELIGIBLE_ERROR_CODES: number[];
|
|
36
104
|
|
|
37
105
|
interface Success<T> {
|
|
38
106
|
success: true;
|
|
@@ -43,12 +111,12 @@ interface Failure {
|
|
|
43
111
|
payload: {
|
|
44
112
|
error: string;
|
|
45
113
|
code: HardwareErrorCode;
|
|
46
|
-
|
|
114
|
+
params?: Record<string, unknown>;
|
|
47
115
|
};
|
|
48
116
|
}
|
|
49
117
|
type Response<T> = Success<T> | Failure;
|
|
50
118
|
declare function success<T>(payload: T): Success<T>;
|
|
51
|
-
declare function failure(code: HardwareErrorCode, error: string,
|
|
119
|
+
declare function failure(code: HardwareErrorCode, error: string, params?: Record<string, unknown>): Failure;
|
|
52
120
|
|
|
53
121
|
type VendorType = 'trezor' | 'ledger';
|
|
54
122
|
type ConnectionType = 'usb' | 'ble';
|
|
@@ -171,13 +239,8 @@ interface EvmSignature {
|
|
|
171
239
|
signature: string;
|
|
172
240
|
address?: string;
|
|
173
241
|
}
|
|
174
|
-
type ProgressCallback = (progress: {
|
|
175
|
-
index: number;
|
|
176
|
-
total: number;
|
|
177
|
-
}) => void;
|
|
178
242
|
interface IEvmMethods {
|
|
179
243
|
evmGetAddress(connectId: string, deviceId: string, params: EvmGetAddressParams): Promise<Response<EvmAddress>>;
|
|
180
|
-
evmGetAddresses(connectId: string, deviceId: string, params: EvmGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<EvmAddress[]>>;
|
|
181
244
|
evmSignTransaction(connectId: string, deviceId: string, params: EvmSignTxParams): Promise<Response<EvmSignedTx>>;
|
|
182
245
|
evmSignMessage(connectId: string, deviceId: string, params: EvmSignMsgParams): Promise<Response<EvmSignature>>;
|
|
183
246
|
evmSignTypedData(connectId: string, deviceId: string, params: EvmSignTypedDataParams): Promise<Response<EvmSignature>>;
|
|
@@ -250,10 +313,10 @@ interface BtcRefTransaction {
|
|
|
250
313
|
locktime: number;
|
|
251
314
|
}
|
|
252
315
|
interface BtcSignedTx {
|
|
253
|
-
signatures: string[];
|
|
254
316
|
serializedTx: string;
|
|
317
|
+
/** Present when the wallet returns per-input sigs separately (e.g. Trezor). */
|
|
318
|
+
signatures?: string[];
|
|
255
319
|
txid?: string;
|
|
256
|
-
signedPsbt?: string;
|
|
257
320
|
}
|
|
258
321
|
interface BtcSignPsbtParams {
|
|
259
322
|
psbt: string;
|
|
@@ -271,11 +334,11 @@ interface BtcSignMsgParams {
|
|
|
271
334
|
}
|
|
272
335
|
interface BtcSignature {
|
|
273
336
|
signature: string;
|
|
274
|
-
|
|
337
|
+
/** Optional — not all adapters return it (e.g. Ledger DMK). Derive via btcGetAddress if needed. */
|
|
338
|
+
address?: string;
|
|
275
339
|
}
|
|
276
340
|
interface IBtcMethods {
|
|
277
341
|
btcGetAddress(connectId: string, deviceId: string, params: BtcGetAddressParams): Promise<Response<BtcAddress>>;
|
|
278
|
-
btcGetAddresses(connectId: string, deviceId: string, params: BtcGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<BtcAddress[]>>;
|
|
279
342
|
btcGetPublicKey(connectId: string, deviceId: string, params: BtcGetPublicKeyParams): Promise<Response<BtcPublicKey>>;
|
|
280
343
|
btcSignTransaction(connectId: string, deviceId: string, params: BtcSignTxParams): Promise<Response<BtcSignedTx>>;
|
|
281
344
|
btcSignPsbt(connectId: string, deviceId: string, params: BtcSignPsbtParams): Promise<Response<BtcSignedPsbt>>;
|
|
@@ -322,7 +385,6 @@ interface SolSignature {
|
|
|
322
385
|
}
|
|
323
386
|
interface ISolMethods {
|
|
324
387
|
solGetAddress(connectId: string, deviceId: string, params: SolGetAddressParams): Promise<Response<SolAddress>>;
|
|
325
|
-
solGetAddresses(connectId: string, deviceId: string, params: SolGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<SolAddress[]>>;
|
|
326
388
|
solSignTransaction(connectId: string, deviceId: string, params: SolSignTxParams): Promise<Response<SolSignedTx>>;
|
|
327
389
|
solSignMessage(connectId: string, deviceId: string, params: SolSignMsgParams): Promise<Response<SolSignature>>;
|
|
328
390
|
}
|
|
@@ -356,7 +418,6 @@ interface TronSignature {
|
|
|
356
418
|
}
|
|
357
419
|
interface ITronMethods {
|
|
358
420
|
tronGetAddress(connectId: string, deviceId: string, params: TronGetAddressParams): Promise<Response<TronAddress>>;
|
|
359
|
-
tronGetAddresses(connectId: string, deviceId: string, params: TronGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<TronAddress[]>>;
|
|
360
421
|
tronSignTransaction(connectId: string, deviceId: string, params: TronSignTxParams): Promise<Response<TronSignedTx>>;
|
|
361
422
|
tronSignMessage(connectId: string, deviceId: string, params: TronSignMsgParams): Promise<Response<TronSignature>>;
|
|
362
423
|
}
|
|
@@ -383,94 +444,19 @@ interface QrResponseData {
|
|
|
383
444
|
declare const CHAIN_FINGERPRINT_PATHS: Record<ChainForFingerprint, string>;
|
|
384
445
|
type ChainForFingerprint = 'evm' | 'btc' | 'sol' | 'tron';
|
|
385
446
|
/**
|
|
386
|
-
*
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
* device identity matching. Not used for security decisions.
|
|
390
|
-
*/
|
|
391
|
-
declare function deriveDeviceFingerprint(address: string): string;
|
|
392
|
-
|
|
393
|
-
/** 10 min — every UI request is human-in-the-loop; bias toward "wait long". */
|
|
394
|
-
declare const UI_REQUEST_DEFAULT_TIMEOUT_MS = 600000;
|
|
395
|
-
declare const UI_REQUEST_PREEMPTED_TAG = "UiRequestPreempted";
|
|
396
|
-
declare const UI_REQUEST_CANCELLED_TAG = "UiRequestCancelled";
|
|
397
|
-
declare const UI_REQUEST_TIMEOUT_TAG = "UiRequestTimeout";
|
|
398
|
-
/**
|
|
399
|
-
* Per-type single-slot registry for adapter-level UI requests. A new `wait`
|
|
400
|
-
* of the same type preempts (rejects) the prior one. Unknown response types
|
|
401
|
-
* are dropped silently so the public `uiResponse` entry never throws.
|
|
447
|
+
* 16-char SHA-256 fingerprint for device-identity verification.
|
|
448
|
+
* Callers must canonicalize input (e.g. EVM address → lowercase) —
|
|
449
|
+
* encoding variations otherwise cause false DeviceMismatch.
|
|
402
450
|
*/
|
|
403
|
-
declare
|
|
404
|
-
private pending;
|
|
405
|
-
wait<T = unknown>(requestType: string, options?: {
|
|
406
|
-
timeoutMs?: number;
|
|
407
|
-
}): Promise<T>;
|
|
408
|
-
resolve(responseType: string, payload: unknown): void;
|
|
409
|
-
cancel(requestType?: string): void;
|
|
410
|
-
reset(): void;
|
|
411
|
-
hasPending(requestType: string): boolean;
|
|
412
|
-
}
|
|
451
|
+
declare function deriveDeviceFingerprint(value: string): string;
|
|
413
452
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
*/
|
|
422
|
-
|
|
423
|
-
type Interruptibility = 'none' | 'safe' | 'confirm';
|
|
424
|
-
type PreemptionDecision = 'cancel-current' | 'wait' | 'reject-new';
|
|
425
|
-
interface JobOptions {
|
|
426
|
-
interruptibility?: Interruptibility;
|
|
427
|
-
label?: string;
|
|
428
|
-
}
|
|
429
|
-
interface ActiveJobInfo {
|
|
430
|
-
label?: string;
|
|
431
|
-
interruptibility: Interruptibility;
|
|
432
|
-
startedAt: number;
|
|
433
|
-
}
|
|
434
|
-
interface PreemptionEvent {
|
|
435
|
-
deviceId: string;
|
|
436
|
-
currentJob: ActiveJobInfo;
|
|
437
|
-
newJob: {
|
|
438
|
-
label?: string;
|
|
439
|
-
interruptibility: Interruptibility;
|
|
440
|
-
};
|
|
441
|
-
}
|
|
442
|
-
interface DeviceJobQueueDeps {
|
|
443
|
-
/** Emit a UI request event to the frontend. */
|
|
444
|
-
emit: (event: string, data: unknown) => void;
|
|
445
|
-
/** Registry for waiting on UI responses. */
|
|
446
|
-
uiRegistry: UiRequestRegistry;
|
|
447
|
-
}
|
|
448
|
-
declare class DeviceJobQueue {
|
|
449
|
-
private readonly _queues;
|
|
450
|
-
private readonly _active;
|
|
451
|
-
private readonly _deps;
|
|
452
|
-
constructor(deps?: DeviceJobQueueDeps);
|
|
453
|
-
/**
|
|
454
|
-
* Enqueue a job for a specific device.
|
|
455
|
-
* If a job is already running for this device, behavior depends on interruptibility:
|
|
456
|
-
* - 'none': new job queues silently (no preemption possible)
|
|
457
|
-
* - 'safe': current job is auto-cancelled, new job runs immediately after
|
|
458
|
-
* - 'confirm': emits REQUEST_PREEMPTION and waits for UI response
|
|
459
|
-
*/
|
|
460
|
-
enqueue<T>(deviceId: string, job: (signal: AbortSignal) => Promise<T>, options?: JobOptions): Promise<T>;
|
|
461
|
-
/** Manually cancel the active job on a device. Returns false if job is non-interruptible. */
|
|
462
|
-
cancelActive(deviceId: string): boolean;
|
|
463
|
-
/** Force cancel regardless of interruptibility. Use for device stuck recovery. */
|
|
464
|
-
forceCancelActive(deviceId: string): boolean;
|
|
465
|
-
/** Get info about the currently active job for a device, or null if idle. */
|
|
466
|
-
getActiveJob(deviceId: string): ActiveJobInfo | null;
|
|
467
|
-
clear(): void;
|
|
468
|
-
/**
|
|
469
|
-
* Request preemption decision via UI request/response flow.
|
|
470
|
-
* Falls back to 'wait' if deps are not provided.
|
|
471
|
-
*/
|
|
472
|
-
private _requestPreemptionDecision;
|
|
473
|
-
}
|
|
453
|
+
declare const DEVICE_EVENT = "DEVICE_EVENT";
|
|
454
|
+
/** Events originating from the hardware device. */
|
|
455
|
+
declare const DEVICE: {
|
|
456
|
+
readonly CONNECT: "device-connect";
|
|
457
|
+
readonly DISCONNECT: "device-disconnect";
|
|
458
|
+
readonly CHANGED: "device-changed";
|
|
459
|
+
};
|
|
474
460
|
|
|
475
461
|
declare const UI_EVENT = "UI_EVENT";
|
|
476
462
|
declare const UI_REQUEST: {
|
|
@@ -483,7 +469,7 @@ declare const UI_REQUEST: {
|
|
|
483
469
|
readonly REQUEST_DEVICE_PERMISSION: "ui-request-device-permission";
|
|
484
470
|
readonly REQUEST_SELECT_DEVICE: "ui-request-select-device";
|
|
485
471
|
readonly REQUEST_DEVICE_CONNECT: "ui-request-device-connect";
|
|
486
|
-
readonly
|
|
472
|
+
readonly REQUEST_BTC_HIGH_INDEX_CONFIRM: "ui-request-btc-high-index-confirm";
|
|
487
473
|
readonly CLOSE_UI_WINDOW: "ui-close";
|
|
488
474
|
readonly DEVICE_PROGRESS: "ui-device_progress";
|
|
489
475
|
readonly FIRMWARE_PROGRESS: "ui-firmware-progress";
|
|
@@ -496,9 +482,16 @@ declare const UI_RESPONSE: {
|
|
|
496
482
|
readonly RECEIVE_QR_RESPONSE: "receive-qr-response";
|
|
497
483
|
readonly RECEIVE_SELECT_DEVICE: "receive-select-device";
|
|
498
484
|
readonly RECEIVE_DEVICE_CONNECT: "receive-device-connect";
|
|
499
|
-
readonly
|
|
485
|
+
readonly RECEIVE_DEVICE_PERMISSION: "receive-device-permission";
|
|
486
|
+
readonly RECEIVE_BTC_HIGH_INDEX_CONFIRM: "receive-btc-high-index-confirm";
|
|
500
487
|
readonly CANCEL: "cancel";
|
|
501
488
|
};
|
|
489
|
+
type DevicePermissionDeniedReason = 'bluetoothTurnedOff' | 'permissionDenied' | (string & Record<never, never>);
|
|
490
|
+
type DevicePermissionResponse = {
|
|
491
|
+
granted: boolean;
|
|
492
|
+
reason?: DevicePermissionDeniedReason;
|
|
493
|
+
message?: string;
|
|
494
|
+
};
|
|
502
495
|
type UiResponseEvent = {
|
|
503
496
|
type: typeof UI_RESPONSE.RECEIVE_PIN;
|
|
504
497
|
payload: string;
|
|
@@ -526,27 +519,18 @@ type UiResponseEvent = {
|
|
|
526
519
|
confirmed: boolean;
|
|
527
520
|
};
|
|
528
521
|
} | {
|
|
529
|
-
type: typeof UI_RESPONSE.
|
|
522
|
+
type: typeof UI_RESPONSE.RECEIVE_DEVICE_PERMISSION;
|
|
523
|
+
payload: DevicePermissionResponse;
|
|
524
|
+
} | {
|
|
525
|
+
type: typeof UI_RESPONSE.RECEIVE_BTC_HIGH_INDEX_CONFIRM;
|
|
530
526
|
payload: {
|
|
531
|
-
|
|
527
|
+
confirmed: boolean;
|
|
532
528
|
};
|
|
533
529
|
} | {
|
|
534
530
|
type: typeof UI_RESPONSE.CANCEL;
|
|
535
531
|
payload?: undefined;
|
|
536
532
|
};
|
|
537
533
|
|
|
538
|
-
declare const DEVICE_EVENT = "DEVICE_EVENT";
|
|
539
|
-
/** Events originating from the hardware device. */
|
|
540
|
-
declare const DEVICE: {
|
|
541
|
-
readonly CONNECT: "device-connect";
|
|
542
|
-
readonly DISCONNECT: "device-disconnect";
|
|
543
|
-
readonly CHANGED: "device-changed";
|
|
544
|
-
readonly ACQUIRE: "device-acquire";
|
|
545
|
-
readonly RELEASE: "device-release";
|
|
546
|
-
readonly FEATURES: "features";
|
|
547
|
-
readonly SUPPORT_FEATURES: "support_features";
|
|
548
|
-
};
|
|
549
|
-
|
|
550
534
|
/** Events generated by SDK internal detection (not from hardware directly). */
|
|
551
535
|
declare const SDK: {
|
|
552
536
|
readonly DEVICE_STUCK: "device-stuck";
|
|
@@ -555,6 +539,146 @@ declare const SDK: {
|
|
|
555
539
|
readonly DEVICE_INTERACTION: "device-interaction";
|
|
556
540
|
};
|
|
557
541
|
|
|
542
|
+
/**
|
|
543
|
+
* Minimal device info returned during discovery (searchDevices).
|
|
544
|
+
* At scan time, full DeviceInfo fields like firmwareVersion are not yet available.
|
|
545
|
+
*/
|
|
546
|
+
interface ConnectorDevice {
|
|
547
|
+
connectId: string;
|
|
548
|
+
deviceId: string;
|
|
549
|
+
name: string;
|
|
550
|
+
model?: string;
|
|
551
|
+
/** Device capabilities — available from scan time */
|
|
552
|
+
capabilities?: DeviceCapabilities;
|
|
553
|
+
}
|
|
554
|
+
interface ConnectorSession {
|
|
555
|
+
sessionId: string;
|
|
556
|
+
deviceInfo: DeviceInfo;
|
|
557
|
+
}
|
|
558
|
+
type ConnectorEventType = 'device-connect' | 'device-disconnect' | 'ui-request' | 'ui-event';
|
|
559
|
+
/**
|
|
560
|
+
* Interaction event types emitted via 'ui-event'.
|
|
561
|
+
* These map to user-facing prompts (confirm on device, open app, etc.).
|
|
562
|
+
*/
|
|
563
|
+
declare enum EConnectorInteraction {
|
|
564
|
+
/** Adapter is actively searching for the device (no session yet) */
|
|
565
|
+
Searching = "searching",
|
|
566
|
+
/** Device requires user to open a specific app */
|
|
567
|
+
ConfirmOpenApp = "confirm-open-app",
|
|
568
|
+
/** Device requires user to unlock */
|
|
569
|
+
UnlockDevice = "unlock-device",
|
|
570
|
+
/** Device needs user to confirm on device (sign, verify, etc.) */
|
|
571
|
+
ConfirmOnDevice = "confirm-on-device",
|
|
572
|
+
/** Previous interaction completed — clear UI prompt */
|
|
573
|
+
InteractionComplete = "interaction-complete"
|
|
574
|
+
}
|
|
575
|
+
type ConnectorUiEvent = {
|
|
576
|
+
type: EConnectorInteraction.Searching;
|
|
577
|
+
payload: {
|
|
578
|
+
sessionId: string;
|
|
579
|
+
};
|
|
580
|
+
} | {
|
|
581
|
+
type: EConnectorInteraction.ConfirmOpenApp;
|
|
582
|
+
payload: {
|
|
583
|
+
sessionId: string;
|
|
584
|
+
};
|
|
585
|
+
} | {
|
|
586
|
+
type: EConnectorInteraction.UnlockDevice;
|
|
587
|
+
payload: {
|
|
588
|
+
sessionId: string;
|
|
589
|
+
};
|
|
590
|
+
} | {
|
|
591
|
+
type: EConnectorInteraction.ConfirmOnDevice;
|
|
592
|
+
payload: {
|
|
593
|
+
sessionId: string;
|
|
594
|
+
};
|
|
595
|
+
} | {
|
|
596
|
+
type: EConnectorInteraction.InteractionComplete;
|
|
597
|
+
payload: {
|
|
598
|
+
sessionId: string;
|
|
599
|
+
};
|
|
600
|
+
};
|
|
601
|
+
interface ConnectorEventMap {
|
|
602
|
+
'device-connect': {
|
|
603
|
+
device: ConnectorDevice;
|
|
604
|
+
};
|
|
605
|
+
'device-disconnect': {
|
|
606
|
+
connectId: string;
|
|
607
|
+
};
|
|
608
|
+
'ui-request': {
|
|
609
|
+
type: string;
|
|
610
|
+
payload?: unknown;
|
|
611
|
+
};
|
|
612
|
+
'ui-event': ConnectorUiEvent;
|
|
613
|
+
}
|
|
614
|
+
interface IConnector {
|
|
615
|
+
/** Physical connection type this connector uses. Fixed at construction. */
|
|
616
|
+
readonly connectionType: ConnectionType;
|
|
617
|
+
searchDevices(): Promise<ConnectorDevice[]>;
|
|
618
|
+
connect(deviceId?: string): Promise<ConnectorSession>;
|
|
619
|
+
disconnect(sessionId: string): Promise<void>;
|
|
620
|
+
call(sessionId: string, method: string, params: unknown): Promise<unknown>;
|
|
621
|
+
cancel(sessionId: string): Promise<void>;
|
|
622
|
+
/** Send a UI response (e.g. PIN, passphrase) to the device. */
|
|
623
|
+
uiResponse(response: UiResponseEvent): void;
|
|
624
|
+
on<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;
|
|
625
|
+
off<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;
|
|
626
|
+
reset(): void;
|
|
627
|
+
}
|
|
628
|
+
interface IHardwareBridge {
|
|
629
|
+
searchDevices(params: {
|
|
630
|
+
vendor: VendorType;
|
|
631
|
+
}): Promise<ConnectorDevice[]>;
|
|
632
|
+
connect(params: {
|
|
633
|
+
vendor: VendorType;
|
|
634
|
+
deviceId?: string;
|
|
635
|
+
}): Promise<ConnectorSession>;
|
|
636
|
+
disconnect(params: {
|
|
637
|
+
vendor: VendorType;
|
|
638
|
+
sessionId: string;
|
|
639
|
+
}): Promise<void>;
|
|
640
|
+
call(params: {
|
|
641
|
+
vendor: VendorType;
|
|
642
|
+
sessionId: string;
|
|
643
|
+
method: string;
|
|
644
|
+
callParams: unknown;
|
|
645
|
+
}): Promise<unknown>;
|
|
646
|
+
cancel(params: {
|
|
647
|
+
vendor: VendorType;
|
|
648
|
+
sessionId: string;
|
|
649
|
+
}): Promise<void>;
|
|
650
|
+
uiResponse(params: {
|
|
651
|
+
vendor: VendorType;
|
|
652
|
+
response: UiResponseEvent;
|
|
653
|
+
}): void;
|
|
654
|
+
reset(params: {
|
|
655
|
+
vendor: VendorType;
|
|
656
|
+
}): void;
|
|
657
|
+
/** Register an event handler for connector events forwarded across the bridge. */
|
|
658
|
+
onEvent(params: {
|
|
659
|
+
vendor: VendorType;
|
|
660
|
+
}, handler: (event: {
|
|
661
|
+
type: ConnectorEventType;
|
|
662
|
+
data: unknown;
|
|
663
|
+
}) => void): void;
|
|
664
|
+
/** Unregister a previously registered event handler. */
|
|
665
|
+
offEvent(params: {
|
|
666
|
+
vendor: VendorType;
|
|
667
|
+
}, handler: (event: {
|
|
668
|
+
type: ConnectorEventType;
|
|
669
|
+
data: unknown;
|
|
670
|
+
}) => void): void;
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Adapt an IHardwareBridge (multi-vendor backend) into a single-vendor IConnector.
|
|
674
|
+
* Every IConnector method becomes a transparent forward to bridge.<method>({ vendor, ... }).
|
|
675
|
+
* Events are forwarded via bridge.onEvent / offEvent.
|
|
676
|
+
*
|
|
677
|
+
* Use this anywhere the actual hardware lives behind a process / context boundary
|
|
678
|
+
* (Electron main, extension background, native module, worker, iframe).
|
|
679
|
+
*/
|
|
680
|
+
declare function createBridgedConnector(vendor: VendorType, connectionType: ConnectionType, bridge: IHardwareBridge): IConnector;
|
|
681
|
+
|
|
558
682
|
type ChainCapability = 'evm' | 'btc' | 'sol' | 'tron';
|
|
559
683
|
interface PassphraseResponse {
|
|
560
684
|
passphrase: string;
|
|
@@ -607,7 +731,11 @@ type UiRequestEvent = {
|
|
|
607
731
|
};
|
|
608
732
|
} | {
|
|
609
733
|
type: typeof UI_REQUEST.REQUEST_DEVICE_PERMISSION;
|
|
610
|
-
payload:
|
|
734
|
+
payload: {
|
|
735
|
+
transportType: TransportType;
|
|
736
|
+
connectId?: string;
|
|
737
|
+
deviceId?: string;
|
|
738
|
+
};
|
|
611
739
|
} | {
|
|
612
740
|
type: typeof UI_REQUEST.REQUEST_SELECT_DEVICE;
|
|
613
741
|
payload: {
|
|
@@ -616,19 +744,22 @@ type UiRequestEvent = {
|
|
|
616
744
|
} | {
|
|
617
745
|
type: typeof UI_REQUEST.REQUEST_DEVICE_CONNECT;
|
|
618
746
|
payload: {
|
|
747
|
+
/** Vendor that emitted the request, e.g. 'ledger', 'trezor'. */
|
|
748
|
+
vendor: string;
|
|
749
|
+
/**
|
|
750
|
+
* Why the SDK is asking for a reconnect. Lets the app render
|
|
751
|
+
* vendor-aware copy without inspecting message strings.
|
|
752
|
+
* - 'device-not-found': search returned 0 / device not reachable.
|
|
753
|
+
* Future values can be added (e.g. 'pairing-failed') as new fallback
|
|
754
|
+
* causes are surfaced.
|
|
755
|
+
*/
|
|
756
|
+
reason: string;
|
|
757
|
+
/**
|
|
758
|
+
* Best-effort English fallback. Apps should prefer rendering via
|
|
759
|
+
* `vendor` + `reason` for i18n; fall back to this if the combination
|
|
760
|
+
* isn't recognized.
|
|
761
|
+
*/
|
|
619
762
|
message: string;
|
|
620
|
-
retryCount: number;
|
|
621
|
-
maxRetries: number;
|
|
622
|
-
};
|
|
623
|
-
} | {
|
|
624
|
-
type: typeof UI_REQUEST.REQUEST_PREEMPTION;
|
|
625
|
-
payload: {
|
|
626
|
-
deviceId: string;
|
|
627
|
-
currentJob: ActiveJobInfo;
|
|
628
|
-
newJob: {
|
|
629
|
-
label?: string;
|
|
630
|
-
interruptibility: Interruptibility;
|
|
631
|
-
};
|
|
632
763
|
};
|
|
633
764
|
} | {
|
|
634
765
|
type: typeof UI_REQUEST.CLOSE_UI_WINDOW;
|
|
@@ -656,7 +787,7 @@ type SdkEvent = {
|
|
|
656
787
|
connectId: string;
|
|
657
788
|
};
|
|
658
789
|
};
|
|
659
|
-
type HardwareEvent = DeviceEvent | UiRequestEvent | SdkEvent;
|
|
790
|
+
type HardwareEvent = DeviceEvent | UiRequestEvent | SdkEvent | ConnectorUiEvent;
|
|
660
791
|
type DeviceEventListener = (event: HardwareEvent) => void;
|
|
661
792
|
/**
|
|
662
793
|
* Type-safe event map for IHardwareWallet.on / .off.
|
|
@@ -665,6 +796,7 @@ type DeviceEventListener = (event: HardwareEvent) => void;
|
|
|
665
796
|
* and the value is the narrowed event object the listener will receive.
|
|
666
797
|
*/
|
|
667
798
|
interface HardwareEventMap {
|
|
799
|
+
'ui-event': ConnectorUiEvent;
|
|
668
800
|
[DEVICE.CONNECT]: {
|
|
669
801
|
type: typeof DEVICE.CONNECT;
|
|
670
802
|
payload: DeviceInfo;
|
|
@@ -719,7 +851,11 @@ interface HardwareEventMap {
|
|
|
719
851
|
};
|
|
720
852
|
[UI_REQUEST.REQUEST_DEVICE_PERMISSION]: {
|
|
721
853
|
type: typeof UI_REQUEST.REQUEST_DEVICE_PERMISSION;
|
|
722
|
-
payload:
|
|
854
|
+
payload: {
|
|
855
|
+
transportType: TransportType;
|
|
856
|
+
connectId?: string;
|
|
857
|
+
deviceId?: string;
|
|
858
|
+
};
|
|
723
859
|
};
|
|
724
860
|
[UI_REQUEST.REQUEST_SELECT_DEVICE]: {
|
|
725
861
|
type: typeof UI_REQUEST.REQUEST_SELECT_DEVICE;
|
|
@@ -730,20 +866,17 @@ interface HardwareEventMap {
|
|
|
730
866
|
[UI_REQUEST.REQUEST_DEVICE_CONNECT]: {
|
|
731
867
|
type: typeof UI_REQUEST.REQUEST_DEVICE_CONNECT;
|
|
732
868
|
payload: {
|
|
869
|
+
vendor: string;
|
|
870
|
+
reason: string;
|
|
733
871
|
message: string;
|
|
734
|
-
retryCount: number;
|
|
735
|
-
maxRetries: number;
|
|
736
872
|
};
|
|
737
873
|
};
|
|
738
|
-
[UI_REQUEST.
|
|
739
|
-
type: typeof UI_REQUEST.
|
|
874
|
+
[UI_REQUEST.REQUEST_BTC_HIGH_INDEX_CONFIRM]: {
|
|
875
|
+
type: typeof UI_REQUEST.REQUEST_BTC_HIGH_INDEX_CONFIRM;
|
|
740
876
|
payload: {
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
label?: string;
|
|
745
|
-
interruptibility: Interruptibility;
|
|
746
|
-
};
|
|
877
|
+
vendor: string;
|
|
878
|
+
path: string;
|
|
879
|
+
accountIndex: number;
|
|
747
880
|
};
|
|
748
881
|
};
|
|
749
882
|
[UI_REQUEST.CLOSE_UI_WINDOW]: {
|
|
@@ -776,47 +909,6 @@ interface HardwareEventMap {
|
|
|
776
909
|
};
|
|
777
910
|
};
|
|
778
911
|
}
|
|
779
|
-
/**
|
|
780
|
-
* Same-process callbacks for prompts and OS-level permission.
|
|
781
|
-
* Cross-process flows use events + `uiResponse` + `UiRequestRegistry` instead.
|
|
782
|
-
*/
|
|
783
|
-
interface IUiHandler {
|
|
784
|
-
onPinRequest(device: DeviceInfo): Promise<string>;
|
|
785
|
-
onPassphraseRequest(device: DeviceInfo): Promise<string | PassphraseResponse>;
|
|
786
|
-
onQrDisplay(device: DeviceInfo, data: QrDisplayData): Promise<QrResponseData>;
|
|
787
|
-
/**
|
|
788
|
-
* Check if device access permission is already granted.
|
|
789
|
-
* Returns { granted, context? }.
|
|
790
|
-
* - granted: true → skip onDevicePermission
|
|
791
|
-
* - granted: false → adapter calls onDevicePermission with the context
|
|
792
|
-
* - context: consumer-defined data passed through to onDevicePermission
|
|
793
|
-
*
|
|
794
|
-
* When connectId/deviceId are undefined (searchDevices), check environment-level
|
|
795
|
-
* permissions (USB: any paired device exists; BLE: bluetooth on + location permission).
|
|
796
|
-
* When connectId/deviceId are provided (business methods), check device-level
|
|
797
|
-
* permissions (USB: target device authorized; BLE: bluetooth on + device connected).
|
|
798
|
-
*/
|
|
799
|
-
checkDevicePermission?(params: {
|
|
800
|
-
transportType: TransportType;
|
|
801
|
-
connectId?: string;
|
|
802
|
-
deviceId?: string;
|
|
803
|
-
}): Promise<{
|
|
804
|
-
granted: boolean;
|
|
805
|
-
context?: Record<string, unknown>;
|
|
806
|
-
}>;
|
|
807
|
-
/**
|
|
808
|
-
* Request device access permission from the user.
|
|
809
|
-
* Only called when checkDevicePermission returns granted: false (or is not set).
|
|
810
|
-
*
|
|
811
|
-
* The handler decides what to do based on transportType + context:
|
|
812
|
-
* - usb/hid: open pairing page or call requestWebUSBDevice
|
|
813
|
-
* - ble: enable bluetooth, request location permission, start scanning
|
|
814
|
-
*/
|
|
815
|
-
onDevicePermission(params: {
|
|
816
|
-
transportType: TransportType;
|
|
817
|
-
context?: Record<string, unknown>;
|
|
818
|
-
}): Promise<void>;
|
|
819
|
-
}
|
|
820
912
|
interface IHardwareWallet<TConfig = unknown> extends IEvmMethods, IBtcMethods, ISolMethods, ITronMethods {
|
|
821
913
|
readonly vendor: string;
|
|
822
914
|
readonly activeTransport: TransportType | null;
|
|
@@ -829,7 +921,8 @@ interface IHardwareWallet<TConfig = unknown> extends IEvmMethods, IBtcMethods, I
|
|
|
829
921
|
disconnectDevice(connectId: string): Promise<void>;
|
|
830
922
|
getDeviceInfo(connectId: string, deviceId: string): Promise<Response<DeviceInfo>>;
|
|
831
923
|
getSupportedChains(): ChainCapability[];
|
|
832
|
-
|
|
924
|
+
/** Abort the in-flight call. Omit connectId to cancel whatever is active. */
|
|
925
|
+
cancel(connectId?: string): void;
|
|
833
926
|
/** Respond to any pending `ui-request-*`. */
|
|
834
927
|
uiResponse(response: UiResponseEvent): void;
|
|
835
928
|
/**
|
|
@@ -842,7 +935,6 @@ interface IHardwareWallet<TConfig = unknown> extends IEvmMethods, IBtcMethods, I
|
|
|
842
935
|
* especially for vendors with ephemeral connectId/deviceId.
|
|
843
936
|
*/
|
|
844
937
|
getChainFingerprint(connectId: string, deviceId: string, chain: ChainForFingerprint): Promise<Response<string>>;
|
|
845
|
-
setUiHandler(handler: Partial<IUiHandler>): void;
|
|
846
938
|
on<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
|
|
847
939
|
on(event: string, listener: DeviceEventListener): void;
|
|
848
940
|
off<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
|
|
@@ -862,10 +954,16 @@ interface DeviceDescriptor {
|
|
|
862
954
|
vendor?: number;
|
|
863
955
|
/** Device type/model identifier */
|
|
864
956
|
type?: string;
|
|
865
|
-
/**
|
|
957
|
+
/** Human-readable display name from the transport layer. */
|
|
866
958
|
name?: string;
|
|
959
|
+
/** Stable Ledger BLE identifier from the raw RN BLE `Device.name` field. */
|
|
960
|
+
bleName?: string;
|
|
961
|
+
/** User-visible Ledger BLE local name from the raw RN BLE `Device.localName` field. */
|
|
962
|
+
localName?: string;
|
|
867
963
|
/** Transport identifier (e.g., 'WEB-HID', 'BLE') */
|
|
868
964
|
transport?: string;
|
|
965
|
+
/** BLE RSSI when provided by the transport scanner. */
|
|
966
|
+
rssi?: number | null;
|
|
869
967
|
}
|
|
870
968
|
interface DeviceConnectEvent {
|
|
871
969
|
type: 'device-connected';
|
|
@@ -878,135 +976,51 @@ interface DeviceDisconnectEvent {
|
|
|
878
976
|
type DeviceChangeEvent = DeviceConnectEvent | DeviceDisconnectEvent;
|
|
879
977
|
|
|
880
978
|
/**
|
|
881
|
-
*
|
|
882
|
-
*
|
|
979
|
+
* Pure FIFO job queue. Every enqueue chains onto the tail; jobs run one at
|
|
980
|
+
* a time across all devices. The queue is intentionally passive — it does
|
|
981
|
+
* NOT decide whether to interrupt or ask the user. Those are application-
|
|
982
|
+
* layer concerns owned by the caller (e.g. a UI button handler that wants
|
|
983
|
+
* to ask "device is busy, interrupt current?" before submitting). The
|
|
984
|
+
* queue exposes inspection (`getActiveJob`) and explicit cancellation
|
|
985
|
+
* (`cancelActive` / `cancelAll`) so callers can implement those policies
|
|
986
|
+
* synchronously, without racing against in-flight enqueues.
|
|
883
987
|
*/
|
|
884
|
-
interface
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
model?: string;
|
|
889
|
-
/** Device capabilities — available from scan time */
|
|
890
|
-
capabilities?: DeviceCapabilities;
|
|
891
|
-
}
|
|
892
|
-
interface ConnectorSession {
|
|
893
|
-
sessionId: string;
|
|
894
|
-
deviceInfo: DeviceInfo;
|
|
895
|
-
}
|
|
896
|
-
type ConnectorEventType = 'device-connect' | 'device-disconnect' | 'ui-request' | 'ui-event';
|
|
897
|
-
/**
|
|
898
|
-
* Interaction event types emitted via 'ui-event'.
|
|
899
|
-
* These map to user-facing prompts (confirm on device, open app, etc.).
|
|
900
|
-
*/
|
|
901
|
-
declare enum EConnectorInteraction {
|
|
902
|
-
/** Device requires user to open a specific app */
|
|
903
|
-
ConfirmOpenApp = "confirm-open-app",
|
|
904
|
-
/** Device requires user to unlock */
|
|
905
|
-
UnlockDevice = "unlock-device",
|
|
906
|
-
/** Device needs user to confirm on device (sign, verify, etc.) */
|
|
907
|
-
ConfirmOnDevice = "confirm-on-device",
|
|
908
|
-
/** Previous interaction completed — clear UI prompt */
|
|
909
|
-
InteractionComplete = "interaction-complete"
|
|
910
|
-
}
|
|
911
|
-
type ConnectorUiEvent = {
|
|
912
|
-
type: EConnectorInteraction.ConfirmOpenApp;
|
|
913
|
-
payload: {
|
|
914
|
-
sessionId: string;
|
|
915
|
-
};
|
|
916
|
-
} | {
|
|
917
|
-
type: EConnectorInteraction.UnlockDevice;
|
|
918
|
-
payload: {
|
|
919
|
-
sessionId: string;
|
|
920
|
-
};
|
|
921
|
-
} | {
|
|
922
|
-
type: EConnectorInteraction.ConfirmOnDevice;
|
|
923
|
-
payload: {
|
|
924
|
-
sessionId: string;
|
|
925
|
-
};
|
|
926
|
-
} | {
|
|
927
|
-
type: EConnectorInteraction.InteractionComplete;
|
|
928
|
-
payload: {
|
|
929
|
-
sessionId: string;
|
|
930
|
-
};
|
|
931
|
-
};
|
|
932
|
-
interface ConnectorEventMap {
|
|
933
|
-
'device-connect': {
|
|
934
|
-
device: ConnectorDevice;
|
|
935
|
-
};
|
|
936
|
-
'device-disconnect': {
|
|
937
|
-
connectId: string;
|
|
938
|
-
};
|
|
939
|
-
'ui-request': {
|
|
940
|
-
type: string;
|
|
941
|
-
payload?: unknown;
|
|
942
|
-
};
|
|
943
|
-
'ui-event': ConnectorUiEvent;
|
|
988
|
+
interface JobOptions {
|
|
989
|
+
label?: string;
|
|
990
|
+
rejectIfBusy?: boolean;
|
|
991
|
+
busyError?: Error;
|
|
944
992
|
}
|
|
945
|
-
interface
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
call(sessionId: string, method: string, params: unknown): Promise<unknown>;
|
|
950
|
-
cancel(sessionId: string): Promise<void>;
|
|
951
|
-
/** Send a UI response (e.g. PIN, passphrase) to the device. */
|
|
952
|
-
uiResponse(response: UiResponseEvent): void;
|
|
953
|
-
on<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;
|
|
954
|
-
off<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;
|
|
955
|
-
reset(): void;
|
|
993
|
+
interface ActiveJobInfo {
|
|
994
|
+
deviceId: string;
|
|
995
|
+
label?: string;
|
|
996
|
+
startedAt: number;
|
|
956
997
|
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
}): void;
|
|
983
|
-
reset(params: {
|
|
984
|
-
vendor: VendorType;
|
|
985
|
-
}): void;
|
|
986
|
-
/** Register an event handler for connector events forwarded across the bridge. */
|
|
987
|
-
onEvent(params: {
|
|
988
|
-
vendor: VendorType;
|
|
989
|
-
}, handler: (event: {
|
|
990
|
-
type: ConnectorEventType;
|
|
991
|
-
data: unknown;
|
|
992
|
-
}) => void): void;
|
|
993
|
-
/** Unregister a previously registered event handler. */
|
|
994
|
-
offEvent(params: {
|
|
995
|
-
vendor: VendorType;
|
|
996
|
-
}, handler: (event: {
|
|
997
|
-
type: ConnectorEventType;
|
|
998
|
-
data: unknown;
|
|
999
|
-
}) => void): void;
|
|
998
|
+
declare class DeviceJobQueue {
|
|
999
|
+
private _tail;
|
|
1000
|
+
private _active;
|
|
1001
|
+
private readonly _jobs;
|
|
1002
|
+
/** Incremented on clear() so queued-but-not-yet-running jobs detect invalidation. */
|
|
1003
|
+
private _generation;
|
|
1004
|
+
private readonly _generationCancelReasons;
|
|
1005
|
+
/**
|
|
1006
|
+
* Enqueue a job. Runs after every previously-enqueued job has settled.
|
|
1007
|
+
* `deviceId` is a label only — used by inspection / cancellation routing.
|
|
1008
|
+
*/
|
|
1009
|
+
enqueue<T>(deviceId: string, job: (signal: AbortSignal) => Promise<T>, options?: JobOptions): Promise<T>;
|
|
1010
|
+
/** Cancel the active job. If `deviceId` is given, only cancels when it matches. */
|
|
1011
|
+
cancelActive(deviceId?: string): boolean;
|
|
1012
|
+
/** Force cancel the active job. `reason` becomes signal.reason. */
|
|
1013
|
+
forceCancelActive(deviceId?: string, reason?: Error): boolean;
|
|
1014
|
+
/** Cancel the active job (alias for callers that previously needed multi-device cancel). */
|
|
1015
|
+
cancelAllActive(reason?: Error): void;
|
|
1016
|
+
/** Cancel the active job and invalidate queued jobs that have not started. */
|
|
1017
|
+
cancelActiveAndPending(deviceId?: string, reason?: Error): boolean;
|
|
1018
|
+
/** Get info about the currently active job, or null if idle. */
|
|
1019
|
+
getActiveJob(deviceId?: string): ActiveJobInfo | null;
|
|
1020
|
+
/** True if any job is currently running. */
|
|
1021
|
+
isBusy(): boolean;
|
|
1022
|
+
clear(reason?: Error): void;
|
|
1000
1023
|
}
|
|
1001
|
-
/**
|
|
1002
|
-
* Adapt an IHardwareBridge (multi-vendor backend) into a single-vendor IConnector.
|
|
1003
|
-
* Every IConnector method becomes a transparent forward to bridge.<method>({ vendor, ... }).
|
|
1004
|
-
* Events are forwarded via bridge.onEvent / offEvent.
|
|
1005
|
-
*
|
|
1006
|
-
* Use this anywhere the actual hardware lives behind a process / context boundary
|
|
1007
|
-
* (Electron main, extension background, native module, worker, iframe).
|
|
1008
|
-
*/
|
|
1009
|
-
declare function createBridgedConnector(vendor: VendorType, bridge: IHardwareBridge): IConnector;
|
|
1010
1024
|
|
|
1011
1025
|
/**
|
|
1012
1026
|
* Minimal typed event emitter using Map<string, Set<listener>>.
|
|
@@ -1032,6 +1046,32 @@ declare class TypedEventEmitter<TMap extends Record<string, any> = Record<string
|
|
|
1032
1046
|
removeAllListeners(): void;
|
|
1033
1047
|
}
|
|
1034
1048
|
|
|
1049
|
+
/** 10 min — every UI request is human-in-the-loop; bias toward "wait long". */
|
|
1050
|
+
declare const UI_REQUEST_DEFAULT_TIMEOUT_MS = 600000;
|
|
1051
|
+
declare const UI_REQUEST_PREEMPTED_TAG = "UiRequestPreempted";
|
|
1052
|
+
declare const UI_REQUEST_CANCELLED_TAG = "UiRequestCancelled";
|
|
1053
|
+
declare const UI_REQUEST_TIMEOUT_TAG = "UiRequestTimeout";
|
|
1054
|
+
/**
|
|
1055
|
+
* Per-type single-slot registry for adapter-level UI requests. A new `wait`
|
|
1056
|
+
* of the same type supersedes (rejects) the prior pending entry. With the
|
|
1057
|
+
* job queue running globally serially, cross-type collisions don't occur in
|
|
1058
|
+
* normal flow — same-type preemption is a defensive measure for callers
|
|
1059
|
+
* that fire the same request twice without waiting on the first.
|
|
1060
|
+
*
|
|
1061
|
+
* Unknown response types are dropped silently so the public `uiResponse`
|
|
1062
|
+
* entry never throws.
|
|
1063
|
+
*/
|
|
1064
|
+
declare class UiRequestRegistry {
|
|
1065
|
+
private pending;
|
|
1066
|
+
wait<T = unknown>(requestType: string, options?: {
|
|
1067
|
+
timeoutMs?: number;
|
|
1068
|
+
}): Promise<T>;
|
|
1069
|
+
resolve(responseType: string, payload: unknown): void;
|
|
1070
|
+
cancel(requestType?: string): void;
|
|
1071
|
+
reset(): void;
|
|
1072
|
+
hasPending(requestType?: string): boolean;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1035
1075
|
/**
|
|
1036
1076
|
* Compare two semver strings (e.g. "2.1.0" vs "2.3.1").
|
|
1037
1077
|
* Returns -1 if a < b, 0 if equal, 1 if a > b.
|
|
@@ -1044,7 +1084,10 @@ declare function ensure0x(hex: string): string;
|
|
|
1044
1084
|
declare function stripHex(hex: string): string;
|
|
1045
1085
|
/** Pad hex to 64 chars (32 bytes) with 0x prefix */
|
|
1046
1086
|
declare function padHex64(hex: string): string;
|
|
1047
|
-
/**
|
|
1087
|
+
/**
|
|
1088
|
+
* Convert a hex string (with or without 0x prefix) to a Uint8Array.
|
|
1089
|
+
* Throws on invalid hex (non-hex characters, odd length).
|
|
1090
|
+
*/
|
|
1048
1091
|
declare function hexToBytes(hex: string): Uint8Array;
|
|
1049
1092
|
/** Convert a Uint8Array to a hex string (no 0x prefix). */
|
|
1050
1093
|
declare function bytesToHex(bytes: Uint8Array): string;
|
|
@@ -1064,4 +1107,4 @@ declare function batchCall<TParam, TResult>(params: TParam[], callFn: (p: TParam
|
|
|
1064
1107
|
total: number;
|
|
1065
1108
|
}) => void): Promise<Response<TResult[]>>;
|
|
1066
1109
|
|
|
1067
|
-
export { type ActiveJobInfo, type BtcAddress, type BtcGetAddressParams, type BtcGetPublicKeyParams, type BtcPublicKey, type BtcRefTransaction, type BtcSignMsgParams, type BtcSignPsbtParams, type BtcSignTxParams, type BtcSignature, type BtcSignedPsbt, type BtcSignedTx, type BtcTxInput, type BtcTxOutput, CHAIN_FINGERPRINT_PATHS, type ChainCapability, type ChainForFingerprint, type ConnectionType, type ConnectorDevice, type ConnectorEventMap, type ConnectorEventType, type ConnectorSession, DEVICE, DEVICE_EVENT, type DeviceCapabilities, type DeviceChangeEvent, type DeviceConnectEvent, type DeviceDescriptor, type DeviceDisconnectEvent, type DeviceEvent, type DeviceEventListener, type DeviceInfo, DeviceJobQueue, type
|
|
1110
|
+
export { type ActiveJobInfo, type BtcAddress, type BtcGetAddressParams, type BtcGetPublicKeyParams, type BtcPublicKey, type BtcRefTransaction, type BtcSignMsgParams, type BtcSignPsbtParams, type BtcSignTxParams, type BtcSignature, type BtcSignedPsbt, type BtcSignedTx, type BtcTxInput, type BtcTxOutput, CHAIN_FINGERPRINT_PATHS, type ChainCapability, type ChainForFingerprint, type ConnectionType, type ConnectorDevice, type ConnectorEventMap, type ConnectorEventType, type ConnectorSession, type ConnectorUiEvent, DEVICE, DEVICE_EVENT, type DeviceCapabilities, type DeviceChangeEvent, type DeviceConnectEvent, type DeviceDescriptor, type DeviceDisconnectEvent, type DeviceEvent, type DeviceEventListener, type DeviceInfo, DeviceJobQueue, type DevicePermissionDeniedReason, type DevicePermissionResponse, type DeviceTarget, EConnectorInteraction, type EIP712Domain, type EvmAddress, type EvmGetAddressParams, type EvmSignMsgParams, type EvmSignTxParams, type EvmSignTypedDataFull, type EvmSignTypedDataHash, type EvmSignTypedDataParams, type EvmSignature, type EvmSignedTx, type Failure, HardwareErrorCode, type HardwareEvent, type HardwareEventMap, type IBtcMethods, type IConnector, type IEvmMethods, type IHardwareBridge, type IHardwareWallet, type ISolMethods, type ITronMethods, type JobOptions, ORPHAN_ELIGIBLE_ERROR_CODES, type PassphraseResponse, type QrDisplayData, type QrResponseData, type Response, SDK, type SdkEvent, type SolAddress, type SolGetAddressParams, type SolSignMsgParams, type SolSignTxParams, type SolSignature, type SolSignedTx, type Success, type TransportType, type TronAddress, type TronGetAddressParams, type TronSignMsgParams, type TronSignTxParams, type TronSignature, type TronSignedTx, TypedEventEmitter, UI_EVENT, UI_REQUEST, UI_REQUEST_CANCELLED_TAG, UI_REQUEST_DEFAULT_TIMEOUT_MS, UI_REQUEST_PREEMPTED_TAG, UI_REQUEST_TIMEOUT_TAG, UI_RESPONSE, type UiRequestEvent, UiRequestRegistry, type UiResponseEvent, type VendorType, batchCall, bytesToHex, compareSemver, createBridgedConnector, deriveDeviceFingerprint, enrichErrorMessage, ensure0x, failure, hexToBytes, padHex64, stripHex, success };
|