@onekeyfe/hwk-adapter-core 1.1.26-alpha.11 → 1.1.26-alpha.13

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
@@ -51,10 +51,19 @@ declare enum HardwareErrorCode {
51
51
  * permission" toast and let the user retry manually.
52
52
  */
53
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,
54
62
  PinInvalid = 10400,
55
63
  PinCancelled = 10401,
56
64
  PassphraseRejected = 10402,
57
- AppNotOpen = 10500,
65
+ /** Chain app NOT INSTALLED on device. User must install via Ledger Live. */
66
+ AppNotInstalled = 10500,
58
67
  WrongApp = 10501,
59
68
  /** 0x911c Command code not supported — app predates current SDK. */
60
69
  AppTooOld = 10502,
@@ -80,6 +89,18 @@ declare enum HardwareErrorCode {
80
89
  /** 0xb007 Aborted due to unexpected state (malformed PSBT / missing UTXO). */
81
90
  BtcUnexpectedState = 11301
82
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[];
83
104
 
84
105
  interface Success<T> {
85
106
  success: true;
@@ -90,11 +111,12 @@ interface Failure {
90
111
  payload: {
91
112
  error: string;
92
113
  code: HardwareErrorCode;
114
+ params?: Record<string, unknown>;
93
115
  };
94
116
  }
95
117
  type Response<T> = Success<T> | Failure;
96
118
  declare function success<T>(payload: T): Success<T>;
97
- declare function failure(code: HardwareErrorCode, error: string): Failure;
119
+ declare function failure(code: HardwareErrorCode, error: string, params?: Record<string, unknown>): Failure;
98
120
 
99
121
  type VendorType = 'trezor' | 'ledger';
100
122
  type ConnectionType = 'usb' | 'ble';
@@ -436,90 +458,6 @@ declare const DEVICE: {
436
458
  readonly CHANGED: "device-changed";
437
459
  };
438
460
 
439
- /** 10 min — every UI request is human-in-the-loop; bias toward "wait long". */
440
- declare const UI_REQUEST_DEFAULT_TIMEOUT_MS = 600000;
441
- declare const UI_REQUEST_PREEMPTED_TAG = "UiRequestPreempted";
442
- declare const UI_REQUEST_CANCELLED_TAG = "UiRequestCancelled";
443
- declare const UI_REQUEST_TIMEOUT_TAG = "UiRequestTimeout";
444
- /**
445
- * Per-type single-slot registry for adapter-level UI requests. A new `wait`
446
- * of the same type preempts (rejects) the prior one. Unknown response types
447
- * are dropped silently so the public `uiResponse` entry never throws.
448
- */
449
- declare class UiRequestRegistry {
450
- private pending;
451
- wait<T = unknown>(requestType: string, options?: {
452
- timeoutMs?: number;
453
- }): Promise<T>;
454
- resolve(responseType: string, payload: unknown): void;
455
- cancel(requestType?: string): void;
456
- reset(): void;
457
- hasPending(requestType?: string): boolean;
458
- }
459
-
460
- /**
461
- * Per-device serial job queue with preemption support and stuck recovery.
462
- * Ensures that only one operation runs at a time per device, with intelligent
463
- * handling of conflicting operations.
464
- *
465
- * The 'confirm' level uses the standard UI request/response flow:
466
- * emits REQUEST_PREEMPTION → waits for RECEIVE_PREEMPTION via UiRequestRegistry.
467
- */
468
-
469
- type Interruptibility = 'none' | 'safe' | 'confirm';
470
- type PreemptionDecision = 'cancel-current' | 'wait' | 'reject-new';
471
- interface JobOptions {
472
- interruptibility?: Interruptibility;
473
- label?: string;
474
- }
475
- interface ActiveJobInfo {
476
- label?: string;
477
- interruptibility: Interruptibility;
478
- startedAt: number;
479
- }
480
- interface PreemptionEvent {
481
- deviceId: string;
482
- currentJob: ActiveJobInfo;
483
- newJob: {
484
- label?: string;
485
- interruptibility: Interruptibility;
486
- };
487
- }
488
- interface DeviceJobQueueDeps {
489
- /** Emit a UI request event to the frontend. */
490
- emit: (event: string, data: unknown) => void;
491
- /** Registry for waiting on UI responses. */
492
- uiRegistry: UiRequestRegistry;
493
- }
494
- declare class DeviceJobQueue {
495
- private readonly _queues;
496
- private readonly _active;
497
- private readonly _deps;
498
- /** Incremented on clear() so stale queued jobs can detect invalidation. */
499
- private _generation;
500
- constructor(deps?: DeviceJobQueueDeps);
501
- /**
502
- * Enqueue a job for a specific device.
503
- * If a job is already running for this device, behavior depends on interruptibility:
504
- * - 'none': new job queues silently (no preemption possible)
505
- * - 'safe': current job is auto-cancelled, new job runs immediately after
506
- * - 'confirm': emits REQUEST_PREEMPTION and waits for UI response
507
- */
508
- enqueue<T>(deviceId: string, job: (signal: AbortSignal) => Promise<T>, options?: JobOptions): Promise<T>;
509
- /** Manually cancel the active job on a device. Returns false if job is non-interruptible. */
510
- cancelActive(deviceId: string): boolean;
511
- /** Force cancel regardless of interruptibility. `reason` becomes signal.reason. */
512
- forceCancelActive(deviceId: string, reason?: Error): boolean;
513
- /** Get info about the currently active job for a device, or null if idle. */
514
- getActiveJob(deviceId: string): ActiveJobInfo | null;
515
- clear(): void;
516
- /**
517
- * Request preemption decision via UI request/response flow.
518
- * Falls back to 'wait' if deps are not provided.
519
- */
520
- private _requestPreemptionDecision;
521
- }
522
-
523
461
  declare const UI_EVENT = "UI_EVENT";
524
462
  declare const UI_REQUEST: {
525
463
  readonly REQUEST_PIN: "ui-request-pin";
@@ -531,7 +469,7 @@ declare const UI_REQUEST: {
531
469
  readonly REQUEST_DEVICE_PERMISSION: "ui-request-device-permission";
532
470
  readonly REQUEST_SELECT_DEVICE: "ui-request-select-device";
533
471
  readonly REQUEST_DEVICE_CONNECT: "ui-request-device-connect";
534
- readonly REQUEST_PREEMPTION: "ui-request-preemption";
472
+ readonly REQUEST_BTC_HIGH_INDEX_CONFIRM: "ui-request-btc-high-index-confirm";
535
473
  readonly CLOSE_UI_WINDOW: "ui-close";
536
474
  readonly DEVICE_PROGRESS: "ui-device_progress";
537
475
  readonly FIRMWARE_PROGRESS: "ui-firmware-progress";
@@ -545,9 +483,15 @@ declare const UI_RESPONSE: {
545
483
  readonly RECEIVE_SELECT_DEVICE: "receive-select-device";
546
484
  readonly RECEIVE_DEVICE_CONNECT: "receive-device-connect";
547
485
  readonly RECEIVE_DEVICE_PERMISSION: "receive-device-permission";
548
- readonly RECEIVE_PREEMPTION: "receive-preemption";
486
+ readonly RECEIVE_BTC_HIGH_INDEX_CONFIRM: "receive-btc-high-index-confirm";
549
487
  readonly CANCEL: "cancel";
550
488
  };
489
+ type DevicePermissionDeniedReason = 'bluetoothTurnedOff' | 'permissionDenied' | (string & Record<never, never>);
490
+ type DevicePermissionResponse = {
491
+ granted: boolean;
492
+ reason?: DevicePermissionDeniedReason;
493
+ message?: string;
494
+ };
551
495
  type UiResponseEvent = {
552
496
  type: typeof UI_RESPONSE.RECEIVE_PIN;
553
497
  payload: string;
@@ -576,13 +520,11 @@ type UiResponseEvent = {
576
520
  };
577
521
  } | {
578
522
  type: typeof UI_RESPONSE.RECEIVE_DEVICE_PERMISSION;
579
- payload: {
580
- granted: boolean;
581
- };
523
+ payload: DevicePermissionResponse;
582
524
  } | {
583
- type: typeof UI_RESPONSE.RECEIVE_PREEMPTION;
525
+ type: typeof UI_RESPONSE.RECEIVE_BTC_HIGH_INDEX_CONFIRM;
584
526
  payload: {
585
- decision: PreemptionDecision;
527
+ confirmed: boolean;
586
528
  };
587
529
  } | {
588
530
  type: typeof UI_RESPONSE.CANCEL;
@@ -619,6 +561,8 @@ type ConnectorEventType = 'device-connect' | 'device-disconnect' | 'ui-request'
619
561
  * These map to user-facing prompts (confirm on device, open app, etc.).
620
562
  */
621
563
  declare enum EConnectorInteraction {
564
+ /** Adapter is actively searching for the device (no session yet) */
565
+ Searching = "searching",
622
566
  /** Device requires user to open a specific app */
623
567
  ConfirmOpenApp = "confirm-open-app",
624
568
  /** Device requires user to unlock */
@@ -629,6 +573,11 @@ declare enum EConnectorInteraction {
629
573
  InteractionComplete = "interaction-complete"
630
574
  }
631
575
  type ConnectorUiEvent = {
576
+ type: EConnectorInteraction.Searching;
577
+ payload: {
578
+ sessionId: string;
579
+ };
580
+ } | {
632
581
  type: EConnectorInteraction.ConfirmOpenApp;
633
582
  payload: {
634
583
  sessionId: string;
@@ -795,18 +744,23 @@ type UiRequestEvent = {
795
744
  } | {
796
745
  type: typeof UI_REQUEST.REQUEST_DEVICE_CONNECT;
797
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
+ */
798
762
  message: string;
799
763
  };
800
- } | {
801
- type: typeof UI_REQUEST.REQUEST_PREEMPTION;
802
- payload: {
803
- deviceId: string;
804
- currentJob: ActiveJobInfo;
805
- newJob: {
806
- label?: string;
807
- interruptibility: Interruptibility;
808
- };
809
- };
810
764
  } | {
811
765
  type: typeof UI_REQUEST.CLOSE_UI_WINDOW;
812
766
  payload: Record<string, never>;
@@ -912,18 +866,17 @@ interface HardwareEventMap {
912
866
  [UI_REQUEST.REQUEST_DEVICE_CONNECT]: {
913
867
  type: typeof UI_REQUEST.REQUEST_DEVICE_CONNECT;
914
868
  payload: {
869
+ vendor: string;
870
+ reason: string;
915
871
  message: string;
916
872
  };
917
873
  };
918
- [UI_REQUEST.REQUEST_PREEMPTION]: {
919
- type: typeof UI_REQUEST.REQUEST_PREEMPTION;
874
+ [UI_REQUEST.REQUEST_BTC_HIGH_INDEX_CONFIRM]: {
875
+ type: typeof UI_REQUEST.REQUEST_BTC_HIGH_INDEX_CONFIRM;
920
876
  payload: {
921
- deviceId: string;
922
- currentJob: ActiveJobInfo;
923
- newJob: {
924
- label?: string;
925
- interruptibility: Interruptibility;
926
- };
877
+ vendor: string;
878
+ path: string;
879
+ accountIndex: number;
927
880
  };
928
881
  };
929
882
  [UI_REQUEST.CLOSE_UI_WINDOW]: {
@@ -1001,10 +954,16 @@ interface DeviceDescriptor {
1001
954
  vendor?: number;
1002
955
  /** Device type/model identifier */
1003
956
  type?: string;
1004
- /** BLE device name (e.g., "Nano X 123A") — contains stable 4-digit HEX suffix */
957
+ /** Human-readable display name from the transport layer. */
1005
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;
1006
963
  /** Transport identifier (e.g., 'WEB-HID', 'BLE') */
1007
964
  transport?: string;
965
+ /** BLE RSSI when provided by the transport scanner. */
966
+ rssi?: number | null;
1008
967
  }
1009
968
  interface DeviceConnectEvent {
1010
969
  type: 'device-connected';
@@ -1016,6 +975,53 @@ interface DeviceDisconnectEvent {
1016
975
  }
1017
976
  type DeviceChangeEvent = DeviceConnectEvent | DeviceDisconnectEvent;
1018
977
 
978
+ /**
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.
987
+ */
988
+ interface JobOptions {
989
+ label?: string;
990
+ rejectIfBusy?: boolean;
991
+ busyError?: Error;
992
+ }
993
+ interface ActiveJobInfo {
994
+ deviceId: string;
995
+ label?: string;
996
+ startedAt: number;
997
+ }
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;
1023
+ }
1024
+
1019
1025
  /**
1020
1026
  * Minimal typed event emitter using Map<string, Set<listener>>.
1021
1027
  * Each adapter uses this for device events (connect, disconnect, pin, etc.).
@@ -1040,6 +1046,32 @@ declare class TypedEventEmitter<TMap extends Record<string, any> = Record<string
1040
1046
  removeAllListeners(): void;
1041
1047
  }
1042
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
+
1043
1075
  /**
1044
1076
  * Compare two semver strings (e.g. "2.1.0" vs "2.3.1").
1045
1077
  * Returns -1 if a < b, 0 if equal, 1 if a > b.
@@ -1075,4 +1107,4 @@ declare function batchCall<TParam, TResult>(params: TParam[], callFn: (p: TParam
1075
1107
  total: number;
1076
1108
  }) => void): Promise<Response<TResult[]>>;
1077
1109
 
1078
- 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 DeviceJobQueueDeps, 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 Interruptibility, type JobOptions, type PassphraseResponse, type PreemptionDecision, type PreemptionEvent, 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 };
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 };