@onekeyfe/hwk-adapter-core 1.2.1 → 1.2.2-alpha.1

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
@@ -260,6 +260,16 @@ interface ConnectorSearchDevicesOptions {
260
260
  */
261
261
  waitForAll?: boolean;
262
262
  }
263
+ interface ConnectorConfig {
264
+ /**
265
+ * Optional OneKey-controlled WebSocket relay base used only for Ledger's
266
+ * genuine check. DMK appends its `/genuine` path and device query params.
267
+ *
268
+ * The value may contain a short-lived opaque relay token, so connectors must
269
+ * never log it. Passing `undefined` restores Ledger's official default.
270
+ */
271
+ ledgerGenuineCheckWebSocketUrl?: string;
272
+ }
263
273
  interface IConnector {
264
274
  /** Physical connection type this connector uses. Fixed at construction. */
265
275
  readonly connectionType: ConnectionType;
@@ -273,6 +283,12 @@ interface IConnector {
273
283
  on<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;
274
284
  off<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;
275
285
  reset(): void;
286
+ /**
287
+ * Reconfigure vendor-specific transport services before the next connect.
288
+ * Ledger uses this to rebuild DMK against a short-lived OneKey genuine-check
289
+ * relay. Vendors without runtime configuration may omit it.
290
+ */
291
+ configure?(config: ConnectorConfig): Promise<void> | void;
276
292
  setKnownCredentials?(credentials: unknown[]): Promise<void> | void;
277
293
  }
278
294
  interface IHardwareBridge {
@@ -305,6 +321,10 @@ interface IHardwareBridge {
305
321
  reset(params: {
306
322
  vendor: VendorType;
307
323
  }): void;
324
+ configure?(params: {
325
+ vendor: VendorType;
326
+ config: ConnectorConfig;
327
+ }): Promise<void> | void;
308
328
  /** Register an event handler for connector events forwarded across the bridge. */
309
329
  onEvent(params: {
310
330
  vendor: VendorType;
@@ -846,6 +866,54 @@ type TrezorBrightnessParams = {
846
866
  type TrezorChangePinParams = {
847
867
  remove?: boolean;
848
868
  };
869
+ type DeviceAuthenticityParams = {
870
+ /**
871
+ * 32-byte server nonce encoded as hex. Trezor signs the protocol-framed
872
+ * AuthenticateDevice payload containing these bytes with its factory
873
+ * attestation key. Omit only for local diagnostics where the SDK may generate
874
+ * a random nonce itself.
875
+ */
876
+ challenge?: string;
877
+ /**
878
+ * OneKey relay base returned by a short-lived backend challenge session.
879
+ * Ledger DMK connects to this URL instead of Ledger directly so the backend
880
+ * can witness the genuine-check transcript and issue a server-side receipt.
881
+ */
882
+ ledgerGenuineCheckWebSocketUrl?: string;
883
+ /**
884
+ * Trezor development/simulator roots. Production reward flows must never
885
+ * enable this.
886
+ */
887
+ dangerouslyAllowDebugKeys?: boolean;
888
+ };
889
+ type DeviceAuthenticityResult = {
890
+ vendor: 'trezor' | 'ledger';
891
+ verified: boolean;
892
+ deviceId?: string;
893
+ deviceCertPubKey?: string;
894
+ serialNumber?: string;
895
+ rootPubKey?: string;
896
+ caPubKey?: string;
897
+ usedDebugKey?: boolean;
898
+ error?: string;
899
+ /**
900
+ * Trezor-only server-verifiable envelope. The backend must verify this proof
901
+ * against the nonce stored for the challenge session; it must not trust the
902
+ * client's `verified` boolean.
903
+ */
904
+ trezorProof?: {
905
+ challenge: string;
906
+ deviceModel: string;
907
+ proof: {
908
+ optiga_certificates: string[];
909
+ optiga_signature: string;
910
+ tropic_certificates?: string[];
911
+ tropic_signature?: string;
912
+ mcu_certificates?: string[];
913
+ mcu_signature?: string;
914
+ };
915
+ };
916
+ };
849
917
  /**
850
918
  * Cross-chain / cross-vendor options passed alongside any chain method's
851
919
  * own params (the optional last argument). Holds operation-level switches
@@ -1210,6 +1278,9 @@ interface IDeviceManagerMethods {
1210
1278
  setBrightness?(connectId: string, params?: TrezorBrightnessParams): Promise<Response<Record<string, unknown>>>;
1211
1279
  changePin?(connectId: string, params?: TrezorChangePinParams): Promise<Response<Record<string, unknown>>>;
1212
1280
  wipeDevice?(connectId: string): Promise<Response<Record<string, unknown>>>;
1281
+ authenticateDevice?(connectId: string, params: {
1282
+ challenge: string;
1283
+ }): Promise<Response<Record<string, unknown>>>;
1213
1284
  }
1214
1285
  interface IWalletStateMethods {
1215
1286
  /**
@@ -1265,6 +1336,7 @@ interface IHardwareWallet<TConfig = unknown> extends IEvmMethods, IBtcMethods, I
1265
1336
  * especially for vendors with ephemeral connectId/deviceId.
1266
1337
  */
1267
1338
  getChainFingerprint(connectId: string, deviceId: string, chain: ChainForFingerprint): Promise<Response<string>>;
1339
+ verifyDeviceAuthenticity?(connectId: string, params?: DeviceAuthenticityParams): Promise<Response<DeviceAuthenticityResult>>;
1268
1340
  on<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
1269
1341
  on(event: string, listener: DeviceEventListener): void;
1270
1342
  off<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
@@ -1650,4 +1722,4 @@ declare function buildUnsupportedMethodResponse(item: AllNetworkAddressParams):
1650
1722
 
1651
1723
  declare const DEVICE_CONNECT_RETRY_DELAY_MS = 1000;
1652
1724
 
1653
- export { ALL_NETWORK_METHOD_NAMES, type ActiveJobInfo, type AllNetworkAddressParams, type AllNetworkAddressResponse, type AllNetworkAddressResponsePayload, type AllNetworkAttachIdentityContext, type AllNetworkCallItemContext, type AllNetworkGetAddressParams, type AllNetworkMethodName, type AllNetworkResponseContext, type BtcAddress, type BtcGetAddressParams, type BtcGetPublicKeyParams, type BtcPaymentRequest, type BtcPaymentRequestMemo, 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 ConnectorCallResult, type ConnectorDevice, type ConnectorErrorParams, type ConnectorEventMap, type ConnectorEventType, type ConnectorSerializedError, type ConnectorSession, type ConnectorUiEvent, DEVICE, DEVICE_CONNECT_RETRY_DELAY_MS, DEVICE_EVENT, type DetectableHardwareVendor, type DeviceCapabilities, type DeviceChangeEvent, type DeviceConnectEvent, type DeviceDescriptor, type DeviceDisconnectEvent, type DeviceEvent, type DeviceEventListener, type DeviceInfo, DeviceJobQueue, type DeviceTarget, EConnectorInteraction, type EIP712Domain, type EvmAddress, type EvmEthereumDefinitions, type EvmGetAddressParams, type EvmPaymentRequest, type EvmPaymentRequestMemo, type EvmSignMsgParams, type EvmSignTxLedgerParams, type EvmSignTxParams, type EvmSignTxTrezorParams, type EvmSignTypedDataFull, type EvmSignTypedDataHash, type EvmSignTypedDataParams, type EvmSignature, type EvmSignedTx, type Failure, HARDWARE_METHOD_CATALOG, type HardwareDeviceIdentityInput, HardwareErrorCode, type HardwareEvent, type HardwareEventMap, type HardwareMethodMetadata, type HardwareMethodName, type HardwareUiEvent, type IBtcMethods, type ICommonCallParams, type IConnector, type IDeviceManagerMethods, type IEvmMethods, type IHardwareBridge, type IHardwareCallParams, type IHardwareCommonCallParams, type IHardwareWallet, type IPassphraseCallParams, type ISolMethods, type ITronMethods, type IWalletStateMethods, type JobOptions, type NullableCallArg, type PassphraseResponse, type PassphraseStateAware, QrDisplayData, type Response, type RunAllNetworkGetAddressOptions, SDK, type SdkEvent, type SearchDevicesOptions, type SolAddress, type SolGetAddressParams, type SolSignMsgParams, type SolSignTxParams, type SolSignature, type SolSignedTx, type Success, type TransportType, type TrezorBrightnessParams, type TrezorChangePinParams, type TrezorDeviceSettingsParams, type TrezorDisplayRotation, type TrezorSafetyCheckLevel, type TronAddress, type TronContract, type TronFreezeBalanceV2Contract, type TronGetAddressParams, type TronResource, type TronSignMsgParams, type TronSignTxParams, type TronSignature, type TronSignedTx, type TronTransferContract, type TronTriggerSmartContract, type TronUnfreezeBalanceV2Contract, type TronVote, type TronVoteWitnessContract, type TronWithdrawExpireUnfreezeContract, TypedEventEmitter, UI_REQUEST, type UiRequestEvent, UiResponseEvent, type VendorType, batchCall, buildUnsupportedMethodResponse, bytesToHex, compareSemver, createBridgedConnector, createCombinedConnector, deriveDeviceFingerprint, detectHardwareVendorFromDescriptor, ensure0x, failure, getAllNetworkMethodChain, getHardwareMethodMetadata, hexToBytes, isAllNetworkMethodName, isKnownNonTargetHardwareVendor, padHex64, rehydrateConnectorError, runAllNetworkGetAddress, serializeConnectorError, stripHex, success };
1725
+ export { ALL_NETWORK_METHOD_NAMES, type ActiveJobInfo, type AllNetworkAddressParams, type AllNetworkAddressResponse, type AllNetworkAddressResponsePayload, type AllNetworkAttachIdentityContext, type AllNetworkCallItemContext, type AllNetworkGetAddressParams, type AllNetworkMethodName, type AllNetworkResponseContext, type BtcAddress, type BtcGetAddressParams, type BtcGetPublicKeyParams, type BtcPaymentRequest, type BtcPaymentRequestMemo, 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 ConnectorCallResult, type ConnectorConfig, type ConnectorDevice, type ConnectorErrorParams, type ConnectorEventMap, type ConnectorEventType, type ConnectorSerializedError, type ConnectorSession, type ConnectorUiEvent, DEVICE, DEVICE_CONNECT_RETRY_DELAY_MS, DEVICE_EVENT, type DetectableHardwareVendor, type DeviceAuthenticityParams, type DeviceAuthenticityResult, type DeviceCapabilities, type DeviceChangeEvent, type DeviceConnectEvent, type DeviceDescriptor, type DeviceDisconnectEvent, type DeviceEvent, type DeviceEventListener, type DeviceInfo, DeviceJobQueue, type DeviceTarget, EConnectorInteraction, type EIP712Domain, type EvmAddress, type EvmEthereumDefinitions, type EvmGetAddressParams, type EvmPaymentRequest, type EvmPaymentRequestMemo, type EvmSignMsgParams, type EvmSignTxLedgerParams, type EvmSignTxParams, type EvmSignTxTrezorParams, type EvmSignTypedDataFull, type EvmSignTypedDataHash, type EvmSignTypedDataParams, type EvmSignature, type EvmSignedTx, type Failure, HARDWARE_METHOD_CATALOG, type HardwareDeviceIdentityInput, HardwareErrorCode, type HardwareEvent, type HardwareEventMap, type HardwareMethodMetadata, type HardwareMethodName, type HardwareUiEvent, type IBtcMethods, type ICommonCallParams, type IConnector, type IDeviceManagerMethods, type IEvmMethods, type IHardwareBridge, type IHardwareCallParams, type IHardwareCommonCallParams, type IHardwareWallet, type IPassphraseCallParams, type ISolMethods, type ITronMethods, type IWalletStateMethods, type JobOptions, type NullableCallArg, type PassphraseResponse, type PassphraseStateAware, QrDisplayData, type Response, type RunAllNetworkGetAddressOptions, SDK, type SdkEvent, type SearchDevicesOptions, type SolAddress, type SolGetAddressParams, type SolSignMsgParams, type SolSignTxParams, type SolSignature, type SolSignedTx, type Success, type TransportType, type TrezorBrightnessParams, type TrezorChangePinParams, type TrezorDeviceSettingsParams, type TrezorDisplayRotation, type TrezorSafetyCheckLevel, type TronAddress, type TronContract, type TronFreezeBalanceV2Contract, type TronGetAddressParams, type TronResource, type TronSignMsgParams, type TronSignTxParams, type TronSignature, type TronSignedTx, type TronTransferContract, type TronTriggerSmartContract, type TronUnfreezeBalanceV2Contract, type TronVote, type TronVoteWitnessContract, type TronWithdrawExpireUnfreezeContract, TypedEventEmitter, UI_REQUEST, type UiRequestEvent, UiResponseEvent, type VendorType, batchCall, buildUnsupportedMethodResponse, bytesToHex, compareSemver, createBridgedConnector, createCombinedConnector, deriveDeviceFingerprint, detectHardwareVendorFromDescriptor, ensure0x, failure, getAllNetworkMethodChain, getHardwareMethodMetadata, hexToBytes, isAllNetworkMethodName, isKnownNonTargetHardwareVendor, padHex64, rehydrateConnectorError, runAllNetworkGetAddress, serializeConnectorError, stripHex, success };
package/dist/index.d.ts CHANGED
@@ -260,6 +260,16 @@ interface ConnectorSearchDevicesOptions {
260
260
  */
261
261
  waitForAll?: boolean;
262
262
  }
263
+ interface ConnectorConfig {
264
+ /**
265
+ * Optional OneKey-controlled WebSocket relay base used only for Ledger's
266
+ * genuine check. DMK appends its `/genuine` path and device query params.
267
+ *
268
+ * The value may contain a short-lived opaque relay token, so connectors must
269
+ * never log it. Passing `undefined` restores Ledger's official default.
270
+ */
271
+ ledgerGenuineCheckWebSocketUrl?: string;
272
+ }
263
273
  interface IConnector {
264
274
  /** Physical connection type this connector uses. Fixed at construction. */
265
275
  readonly connectionType: ConnectionType;
@@ -273,6 +283,12 @@ interface IConnector {
273
283
  on<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;
274
284
  off<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;
275
285
  reset(): void;
286
+ /**
287
+ * Reconfigure vendor-specific transport services before the next connect.
288
+ * Ledger uses this to rebuild DMK against a short-lived OneKey genuine-check
289
+ * relay. Vendors without runtime configuration may omit it.
290
+ */
291
+ configure?(config: ConnectorConfig): Promise<void> | void;
276
292
  setKnownCredentials?(credentials: unknown[]): Promise<void> | void;
277
293
  }
278
294
  interface IHardwareBridge {
@@ -305,6 +321,10 @@ interface IHardwareBridge {
305
321
  reset(params: {
306
322
  vendor: VendorType;
307
323
  }): void;
324
+ configure?(params: {
325
+ vendor: VendorType;
326
+ config: ConnectorConfig;
327
+ }): Promise<void> | void;
308
328
  /** Register an event handler for connector events forwarded across the bridge. */
309
329
  onEvent(params: {
310
330
  vendor: VendorType;
@@ -846,6 +866,54 @@ type TrezorBrightnessParams = {
846
866
  type TrezorChangePinParams = {
847
867
  remove?: boolean;
848
868
  };
869
+ type DeviceAuthenticityParams = {
870
+ /**
871
+ * 32-byte server nonce encoded as hex. Trezor signs the protocol-framed
872
+ * AuthenticateDevice payload containing these bytes with its factory
873
+ * attestation key. Omit only for local diagnostics where the SDK may generate
874
+ * a random nonce itself.
875
+ */
876
+ challenge?: string;
877
+ /**
878
+ * OneKey relay base returned by a short-lived backend challenge session.
879
+ * Ledger DMK connects to this URL instead of Ledger directly so the backend
880
+ * can witness the genuine-check transcript and issue a server-side receipt.
881
+ */
882
+ ledgerGenuineCheckWebSocketUrl?: string;
883
+ /**
884
+ * Trezor development/simulator roots. Production reward flows must never
885
+ * enable this.
886
+ */
887
+ dangerouslyAllowDebugKeys?: boolean;
888
+ };
889
+ type DeviceAuthenticityResult = {
890
+ vendor: 'trezor' | 'ledger';
891
+ verified: boolean;
892
+ deviceId?: string;
893
+ deviceCertPubKey?: string;
894
+ serialNumber?: string;
895
+ rootPubKey?: string;
896
+ caPubKey?: string;
897
+ usedDebugKey?: boolean;
898
+ error?: string;
899
+ /**
900
+ * Trezor-only server-verifiable envelope. The backend must verify this proof
901
+ * against the nonce stored for the challenge session; it must not trust the
902
+ * client's `verified` boolean.
903
+ */
904
+ trezorProof?: {
905
+ challenge: string;
906
+ deviceModel: string;
907
+ proof: {
908
+ optiga_certificates: string[];
909
+ optiga_signature: string;
910
+ tropic_certificates?: string[];
911
+ tropic_signature?: string;
912
+ mcu_certificates?: string[];
913
+ mcu_signature?: string;
914
+ };
915
+ };
916
+ };
849
917
  /**
850
918
  * Cross-chain / cross-vendor options passed alongside any chain method's
851
919
  * own params (the optional last argument). Holds operation-level switches
@@ -1210,6 +1278,9 @@ interface IDeviceManagerMethods {
1210
1278
  setBrightness?(connectId: string, params?: TrezorBrightnessParams): Promise<Response<Record<string, unknown>>>;
1211
1279
  changePin?(connectId: string, params?: TrezorChangePinParams): Promise<Response<Record<string, unknown>>>;
1212
1280
  wipeDevice?(connectId: string): Promise<Response<Record<string, unknown>>>;
1281
+ authenticateDevice?(connectId: string, params: {
1282
+ challenge: string;
1283
+ }): Promise<Response<Record<string, unknown>>>;
1213
1284
  }
1214
1285
  interface IWalletStateMethods {
1215
1286
  /**
@@ -1265,6 +1336,7 @@ interface IHardwareWallet<TConfig = unknown> extends IEvmMethods, IBtcMethods, I
1265
1336
  * especially for vendors with ephemeral connectId/deviceId.
1266
1337
  */
1267
1338
  getChainFingerprint(connectId: string, deviceId: string, chain: ChainForFingerprint): Promise<Response<string>>;
1339
+ verifyDeviceAuthenticity?(connectId: string, params?: DeviceAuthenticityParams): Promise<Response<DeviceAuthenticityResult>>;
1268
1340
  on<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
1269
1341
  on(event: string, listener: DeviceEventListener): void;
1270
1342
  off<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
@@ -1650,4 +1722,4 @@ declare function buildUnsupportedMethodResponse(item: AllNetworkAddressParams):
1650
1722
 
1651
1723
  declare const DEVICE_CONNECT_RETRY_DELAY_MS = 1000;
1652
1724
 
1653
- export { ALL_NETWORK_METHOD_NAMES, type ActiveJobInfo, type AllNetworkAddressParams, type AllNetworkAddressResponse, type AllNetworkAddressResponsePayload, type AllNetworkAttachIdentityContext, type AllNetworkCallItemContext, type AllNetworkGetAddressParams, type AllNetworkMethodName, type AllNetworkResponseContext, type BtcAddress, type BtcGetAddressParams, type BtcGetPublicKeyParams, type BtcPaymentRequest, type BtcPaymentRequestMemo, 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 ConnectorCallResult, type ConnectorDevice, type ConnectorErrorParams, type ConnectorEventMap, type ConnectorEventType, type ConnectorSerializedError, type ConnectorSession, type ConnectorUiEvent, DEVICE, DEVICE_CONNECT_RETRY_DELAY_MS, DEVICE_EVENT, type DetectableHardwareVendor, type DeviceCapabilities, type DeviceChangeEvent, type DeviceConnectEvent, type DeviceDescriptor, type DeviceDisconnectEvent, type DeviceEvent, type DeviceEventListener, type DeviceInfo, DeviceJobQueue, type DeviceTarget, EConnectorInteraction, type EIP712Domain, type EvmAddress, type EvmEthereumDefinitions, type EvmGetAddressParams, type EvmPaymentRequest, type EvmPaymentRequestMemo, type EvmSignMsgParams, type EvmSignTxLedgerParams, type EvmSignTxParams, type EvmSignTxTrezorParams, type EvmSignTypedDataFull, type EvmSignTypedDataHash, type EvmSignTypedDataParams, type EvmSignature, type EvmSignedTx, type Failure, HARDWARE_METHOD_CATALOG, type HardwareDeviceIdentityInput, HardwareErrorCode, type HardwareEvent, type HardwareEventMap, type HardwareMethodMetadata, type HardwareMethodName, type HardwareUiEvent, type IBtcMethods, type ICommonCallParams, type IConnector, type IDeviceManagerMethods, type IEvmMethods, type IHardwareBridge, type IHardwareCallParams, type IHardwareCommonCallParams, type IHardwareWallet, type IPassphraseCallParams, type ISolMethods, type ITronMethods, type IWalletStateMethods, type JobOptions, type NullableCallArg, type PassphraseResponse, type PassphraseStateAware, QrDisplayData, type Response, type RunAllNetworkGetAddressOptions, SDK, type SdkEvent, type SearchDevicesOptions, type SolAddress, type SolGetAddressParams, type SolSignMsgParams, type SolSignTxParams, type SolSignature, type SolSignedTx, type Success, type TransportType, type TrezorBrightnessParams, type TrezorChangePinParams, type TrezorDeviceSettingsParams, type TrezorDisplayRotation, type TrezorSafetyCheckLevel, type TronAddress, type TronContract, type TronFreezeBalanceV2Contract, type TronGetAddressParams, type TronResource, type TronSignMsgParams, type TronSignTxParams, type TronSignature, type TronSignedTx, type TronTransferContract, type TronTriggerSmartContract, type TronUnfreezeBalanceV2Contract, type TronVote, type TronVoteWitnessContract, type TronWithdrawExpireUnfreezeContract, TypedEventEmitter, UI_REQUEST, type UiRequestEvent, UiResponseEvent, type VendorType, batchCall, buildUnsupportedMethodResponse, bytesToHex, compareSemver, createBridgedConnector, createCombinedConnector, deriveDeviceFingerprint, detectHardwareVendorFromDescriptor, ensure0x, failure, getAllNetworkMethodChain, getHardwareMethodMetadata, hexToBytes, isAllNetworkMethodName, isKnownNonTargetHardwareVendor, padHex64, rehydrateConnectorError, runAllNetworkGetAddress, serializeConnectorError, stripHex, success };
1725
+ export { ALL_NETWORK_METHOD_NAMES, type ActiveJobInfo, type AllNetworkAddressParams, type AllNetworkAddressResponse, type AllNetworkAddressResponsePayload, type AllNetworkAttachIdentityContext, type AllNetworkCallItemContext, type AllNetworkGetAddressParams, type AllNetworkMethodName, type AllNetworkResponseContext, type BtcAddress, type BtcGetAddressParams, type BtcGetPublicKeyParams, type BtcPaymentRequest, type BtcPaymentRequestMemo, 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 ConnectorCallResult, type ConnectorConfig, type ConnectorDevice, type ConnectorErrorParams, type ConnectorEventMap, type ConnectorEventType, type ConnectorSerializedError, type ConnectorSession, type ConnectorUiEvent, DEVICE, DEVICE_CONNECT_RETRY_DELAY_MS, DEVICE_EVENT, type DetectableHardwareVendor, type DeviceAuthenticityParams, type DeviceAuthenticityResult, type DeviceCapabilities, type DeviceChangeEvent, type DeviceConnectEvent, type DeviceDescriptor, type DeviceDisconnectEvent, type DeviceEvent, type DeviceEventListener, type DeviceInfo, DeviceJobQueue, type DeviceTarget, EConnectorInteraction, type EIP712Domain, type EvmAddress, type EvmEthereumDefinitions, type EvmGetAddressParams, type EvmPaymentRequest, type EvmPaymentRequestMemo, type EvmSignMsgParams, type EvmSignTxLedgerParams, type EvmSignTxParams, type EvmSignTxTrezorParams, type EvmSignTypedDataFull, type EvmSignTypedDataHash, type EvmSignTypedDataParams, type EvmSignature, type EvmSignedTx, type Failure, HARDWARE_METHOD_CATALOG, type HardwareDeviceIdentityInput, HardwareErrorCode, type HardwareEvent, type HardwareEventMap, type HardwareMethodMetadata, type HardwareMethodName, type HardwareUiEvent, type IBtcMethods, type ICommonCallParams, type IConnector, type IDeviceManagerMethods, type IEvmMethods, type IHardwareBridge, type IHardwareCallParams, type IHardwareCommonCallParams, type IHardwareWallet, type IPassphraseCallParams, type ISolMethods, type ITronMethods, type IWalletStateMethods, type JobOptions, type NullableCallArg, type PassphraseResponse, type PassphraseStateAware, QrDisplayData, type Response, type RunAllNetworkGetAddressOptions, SDK, type SdkEvent, type SearchDevicesOptions, type SolAddress, type SolGetAddressParams, type SolSignMsgParams, type SolSignTxParams, type SolSignature, type SolSignedTx, type Success, type TransportType, type TrezorBrightnessParams, type TrezorChangePinParams, type TrezorDeviceSettingsParams, type TrezorDisplayRotation, type TrezorSafetyCheckLevel, type TronAddress, type TronContract, type TronFreezeBalanceV2Contract, type TronGetAddressParams, type TronResource, type TronSignMsgParams, type TronSignTxParams, type TronSignature, type TronSignedTx, type TronTransferContract, type TronTriggerSmartContract, type TronUnfreezeBalanceV2Contract, type TronVote, type TronVoteWitnessContract, type TronWithdrawExpireUnfreezeContract, TypedEventEmitter, UI_REQUEST, type UiRequestEvent, UiResponseEvent, type VendorType, batchCall, buildUnsupportedMethodResponse, bytesToHex, compareSemver, createBridgedConnector, createCombinedConnector, deriveDeviceFingerprint, detectHardwareVendorFromDescriptor, ensure0x, failure, getAllNetworkMethodChain, getHardwareMethodMetadata, hexToBytes, isAllNetworkMethodName, isKnownNonTargetHardwareVendor, padHex64, rehydrateConnectorError, runAllNetworkGetAddress, serializeConnectorError, stripHex, success };
package/dist/index.js CHANGED
@@ -218,6 +218,7 @@ function createBridgedConnector(vendor, connectionType, bridge) {
218
218
  if (inner.size === 0) handlerMap.delete(event);
219
219
  },
220
220
  reset: () => bridge.reset({ vendor }),
221
+ configure: bridge.configure ? (config) => _optionalChain([bridge, 'access', _3 => _3.configure, 'optionalCall', _4 => _4({ vendor, config })]) : void 0,
221
222
  setKnownCredentials: bridge.setKnownCredentials ? (credentials) => bridge.setKnownCredentials({ vendor, credentials }) : void 0
222
223
  };
223
224
  }
@@ -321,7 +322,7 @@ function createCombinedConnector(connectors) {
321
322
  };
322
323
  const broadcastCredentials = async () => {
323
324
  await Promise.all(
324
- connectors.map((child) => Promise.resolve(_optionalChain([child, 'access', _3 => _3.setKnownCredentials, 'optionalCall', _4 => _4(sharedCredentials)])))
325
+ connectors.map((child) => Promise.resolve(_optionalChain([child, 'access', _5 => _5.setKnownCredentials, 'optionalCall', _6 => _6(sharedCredentials)])))
325
326
  );
326
327
  };
327
328
  for (const child of connectors) {
@@ -423,7 +424,7 @@ function createCombinedConnector(connectors) {
423
424
  // Nominal value only — the per-device `connectionType` is authoritative
424
425
  // for a fused connector.
425
426
  connectionType: connectors[0].connectionType,
426
- searchDevices: (options) => searchDevices({ waitForAll: _optionalChain([options, 'optionalAccess', _5 => _5.waitForAll]) }),
427
+ searchDevices: (options) => searchDevices({ waitForAll: _optionalChain([options, 'optionalAccess', _7 => _7.waitForAll]) }),
427
428
  connect: async (deviceId) => {
428
429
  let owner;
429
430
  let session;
@@ -473,7 +474,7 @@ function createCombinedConnector(connectors) {
473
474
  },
474
475
  off: (event, handler) => {
475
476
  const inner = forwarders.get(event);
476
- const attached = _optionalChain([inner, 'optionalAccess', _6 => _6.get, 'call', _7 => _7(handler)]);
477
+ const attached = _optionalChain([inner, 'optionalAccess', _8 => _8.get, 'call', _9 => _9(handler)]);
477
478
  if (!attached || !inner) return;
478
479
  for (const { child, handler: forward } of attached) {
479
480
  child.off(event, forward);
@@ -487,6 +488,11 @@ function createCombinedConnector(connectors) {
487
488
  sessionOwner.clear();
488
489
  forwarders.clear();
489
490
  },
491
+ configure: connectors.some((c) => c.configure) ? async (config) => {
492
+ await Promise.all(connectors.map((child) => Promise.resolve(_optionalChain([child, 'access', _10 => _10.configure, 'optionalCall', _11 => _11(config)]))));
493
+ deviceOwner.clear();
494
+ sessionOwner.clear();
495
+ } : void 0,
490
496
  setKnownCredentials: connectors.some((c) => c.setKnownCredentials) ? async (credentials) => {
491
497
  sharedCredentials.length = 0;
492
498
  mergeShared(_nullishCoalesce(credentials, () => ( [])));
@@ -527,7 +533,7 @@ var TypedEventEmitter = class {
527
533
  }
528
534
  /** Number of listeners registered for `event`. 0 if none. */
529
535
  listenerCount(event) {
530
- return _nullishCoalesce(_optionalChain([this, 'access', _8 => _8._listeners, 'access', _9 => _9.get, 'call', _10 => _10(event), 'optionalAccess', _11 => _11.size]), () => ( 0));
536
+ return _nullishCoalesce(_optionalChain([this, 'access', _12 => _12._listeners, 'access', _13 => _13.get, 'call', _14 => _14(event), 'optionalAccess', _15 => _15.size]), () => ( 0));
531
537
  }
532
538
  };
533
539
 
@@ -566,7 +572,7 @@ function bytesToHex2(bytes) {
566
572
  var ONEKEY_BLE_SERVICE_UUID = "00000001-0000-1000-8000-00805f9b34fb";
567
573
  var TREZOR_BLE_SERVICE_UUID = "8c000001-a59b-4d58-a9ad-073df69fa1b1";
568
574
  var LEDGER_USB_VENDOR_ID = 11415;
569
- var lower = (value) => _nullishCoalesce(_optionalChain([value, 'optionalAccess', _12 => _12.trim, 'call', _13 => _13(), 'access', _14 => _14.toLowerCase, 'call', _15 => _15()]), () => ( ""));
575
+ var lower = (value) => _nullishCoalesce(_optionalChain([value, 'optionalAccess', _16 => _16.trim, 'call', _17 => _17(), 'access', _18 => _18.toLowerCase, 'call', _19 => _19()]), () => ( ""));
570
576
  var hasServiceUuid = (input, uuid) => {
571
577
  const expected = uuid.toLowerCase();
572
578
  const values = [
@@ -604,7 +610,7 @@ async function batchCall(params, callFn, onProgress) {
604
610
  return result;
605
611
  }
606
612
  results.push(result.payload);
607
- _optionalChain([onProgress, 'optionalCall', _16 => _16({ index: i, total: params.length })]);
613
+ _optionalChain([onProgress, 'optionalCall', _20 => _20({ index: i, total: params.length })]);
608
614
  }
609
615
  return { success: true, payload: results };
610
616
  }
@@ -660,7 +666,7 @@ async function runAllNetworkGetAddress({
660
666
  continue;
661
667
  }
662
668
  const method = item.methodName;
663
- const unsupportedNetwork = _optionalChain([buildUnsupportedNetworkResponse, 'optionalCall', _17 => _17(item, method)]);
669
+ const unsupportedNetwork = _optionalChain([buildUnsupportedNetworkResponse, 'optionalCall', _21 => _21(item, method)]);
664
670
  if (unsupportedNetwork) {
665
671
  responses.push(unsupportedNetwork);
666
672
  continue;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/hardware-js-sdk/hardware-js-sdk/packages/hwk-adapter-core/dist/index.js","../src/types/response.ts","../src/types/fingerprint.ts","../src/events/device.ts","../src/events/sdk.ts","../src/utils/DeviceJobQueue.ts","../src/types/connector.ts","../src/utils/TypedEventEmitter.ts","../src/utils/semver.ts","../src/utils/hex.ts","../src/utils/deviceIdentity.ts","../src/utils/batchCall.ts","../src/utils/methodCatalog.ts","../src/utils/allNetwork.ts","../src/constants.ts"],"names":["EConnectorInteraction"],"mappings":"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","file":"/home/runner/work/hardware-js-sdk/hardware-js-sdk/packages/hwk-adapter-core/dist/index.js","sourcesContent":[null,"import type { HardwareErrorCode } from './errors';\n\nexport interface Success<T> {\n success: true;\n payload: T;\n}\n\nexport interface Failure {\n success: false;\n payload: {\n error: string;\n code: HardwareErrorCode;\n params?: Record<string, unknown>;\n };\n}\n\nexport type Response<T> = Success<T> | Failure;\n\nexport function success<T>(payload: T): Success<T> {\n return { success: true, payload };\n}\n\nexport function failure(\n code: HardwareErrorCode,\n error: string,\n params?: Record<string, unknown>\n): Failure {\n return {\n success: false,\n payload: { error, code, ...(params ? { params } : {}) },\n };\n}\n","/**\n * Chain fingerprint utilities for device identity verification.\n *\n * Ledger devices have ephemeral IDs that change every session.\n * To verify that the same seed/device is connected, we derive an address\n * at a fixed path (account 0, index 0) and hash it into a stable \"chain fingerprint\".\n */\nimport { sha256 } from '@noble/hashes/sha256';\nimport { bytesToHex, utf8ToBytes } from '@noble/hashes/utils';\n\n/**\n * Fixed derivation paths used to generate chain fingerprints.\n * Uses standard index 0 — Ledger firmware shows device confirmation for\n * non-standard paths (e.g., index=100), which would interrupt wallet creation.\n * The address is hashed into a 16-char fingerprint, not exposed directly.\n * - EVM: cointype 60 (Ledger ETH App only supports 60)\n * - BTC: cointype 1 (testnet)\n * - SOL: cointype 501, standard 3-level hardened\n */\nexport const CHAIN_FINGERPRINT_PATHS: Record<ChainForFingerprint, string> = {\n evm: \"m/44'/60'/0'/0/0\",\n // BTC: account-level path (3 levels), mainnet cointype 0.\n // Cointype 1 (testnet) is rejected by some Ledger BTC App configurations.\n btc: \"m/44'/0'/0'\",\n sol: \"m/44'/501'/0'\",\n tron: \"m/44'/195'/0'/0/0\",\n};\n\nexport type ChainForFingerprint = 'evm' | 'btc' | 'sol' | 'tron';\n\n/**\n * 16-char SHA-256 fingerprint for device-identity verification.\n * Callers must canonicalize input (e.g. EVM address → lowercase) —\n * encoding variations otherwise cause false DeviceMismatch.\n */\nexport function deriveDeviceFingerprint(value: string): string {\n return bytesToHex(sha256(utf8ToBytes(value))).slice(0, 16);\n}\n","export const DEVICE_EVENT = 'DEVICE_EVENT';\n\n/** Events originating from the hardware device. */\nexport const DEVICE = {\n CONNECT: 'device-connect',\n DISCONNECT: 'device-disconnect',\n CHANGED: 'device-changed',\n FEATURES: 'features',\n /**\n * Trezor-only. Emitted after a successful THP handshake that minted or\n * refreshed pairing credentials. The host should persist `credentials`\n * keyed by `deviceId` and feed them back into the connector on the next\n * connect to skip the CodeEntry/QrCode/NFC pairing UX.\n *\n * The `TREZOR_` prefix mirrors `UI_REQUEST.REQUEST_TREZOR_THP_PAIRING` —\n * vendor-specific events live in the shared event taxonomy but are named\n * so hosts can ignore them when they don't drive Trezor hardware.\n */\n TREZOR_THP_CREDENTIALS_CHANGED: 'device-trezor-thp-credentials-changed',\n} as const;\n","/** Events generated by SDK internal detection (not from hardware directly). */\nexport const SDK = {\n DEVICE_STUCK: 'device-stuck',\n DEVICE_UNRESPONSIVE: 'device-unresponsive',\n DEVICE_RECOVERED: 'device-recovered',\n DEVICE_INTERACTION: 'device-interaction',\n} as const;\n","/**\n * Pure FIFO job queue. Every enqueue chains onto the tail; jobs run one at\n * a time across all devices. The queue is intentionally passive — it does\n * NOT decide whether to interrupt or ask the user. Those are application-\n * layer concerns owned by the caller (e.g. a UI button handler that wants\n * to ask \"device is busy, interrupt current?\" before submitting). The\n * queue exposes inspection (`getActiveJob`) and explicit cancellation\n * (`cancelActive` / `cancelAll`) so callers can implement those policies\n * synchronously, without racing against in-flight enqueues.\n */\n\nexport interface JobOptions {\n label?: string;\n rejectIfBusy?: boolean;\n busyError?: Error;\n}\n\nexport interface ActiveJobInfo {\n deviceId: string;\n label?: string;\n startedAt: number;\n}\n\ninterface ActiveJob {\n deviceId: string;\n label?: string;\n abortController: AbortController;\n startedAt: number;\n}\n\nexport class DeviceJobQueue {\n private _tail: Promise<unknown> = Promise.resolve();\n\n private _active: ActiveJob | null = null;\n\n private readonly _jobs = new Map<object, { deviceId: string }>();\n\n /** Incremented on clear() so queued-but-not-yet-running jobs detect invalidation. */\n private _generation = 0;\n\n private readonly _generationCancelReasons = new Map<number, Error>();\n\n /**\n * Enqueue a job. Runs after every previously-enqueued job has settled.\n * `deviceId` is a label only — used by inspection / cancellation routing.\n */\n async enqueue<T>(\n deviceId: string,\n job: (signal: AbortSignal) => Promise<T>,\n options: JobOptions = {}\n ): Promise<T> {\n if (options.rejectIfBusy && this._jobs.size > 0) {\n throw options.busyError ?? new Error('Device is busy');\n }\n\n const ac = new AbortController();\n const gen = this._generation;\n const prev = this._tail;\n const jobToken = {};\n const activeJob: ActiveJob = {\n deviceId,\n label: options.label,\n abortController: ac,\n startedAt: Date.now(),\n };\n this._jobs.set(jobToken, { deviceId });\n\n const next = prev\n .catch(() => {})\n .then(async () => {\n if (this._generation !== gen) {\n throw (\n this._generationCancelReasons.get(gen) ?? new Error('Job cancelled: queue was cleared')\n );\n }\n this._active = activeJob;\n try {\n return await job(ac.signal);\n } finally {\n // Identity guard: a previous job's deferred finally must not\n // null out a successor's `_active`.\n if (this._active === activeJob) {\n this._active = null;\n }\n }\n })\n .finally(() => {\n this._jobs.delete(jobToken);\n });\n\n this._tail = next.catch(() => {});\n return next;\n }\n\n /** Cancel the active job. If `deviceId` is given, only cancels when it matches. */\n cancelActive(deviceId?: string): boolean {\n if (!this._active) return false;\n if (deviceId && this._active.deviceId !== deviceId) return false;\n this._active.abortController.abort(new Error('Manually cancelled'));\n return true;\n }\n\n /** Force cancel the active job. `reason` becomes signal.reason. */\n forceCancelActive(deviceId?: string, reason?: Error): boolean {\n if (!this._active) return false;\n if (deviceId && this._active.deviceId !== deviceId) return false;\n this._active.abortController.abort(reason ?? new Error('Force cancelled for recovery'));\n return true;\n }\n\n /** Cancel the active job (alias for callers that previously needed multi-device cancel). */\n cancelAllActive(reason?: Error): void {\n if (!this._active) return;\n this._active.abortController.abort(reason ?? new Error('Cancelled by cancelAllActive'));\n }\n\n /** Cancel the active job and invalidate queued jobs that have not started. */\n cancelActiveAndPending(deviceId?: string, reason?: Error): boolean {\n if (deviceId && this._active && this._active.deviceId !== deviceId) {\n return false;\n }\n this.clear(reason ?? new Error('Cancelled by cancelActiveAndPending'));\n return true;\n }\n\n /** Get info about the currently active job, or null if idle. */\n getActiveJob(deviceId?: string): ActiveJobInfo | null {\n if (!this._active) return null;\n if (deviceId && this._active.deviceId !== deviceId) return null;\n return {\n deviceId: this._active.deviceId,\n label: this._active.label,\n startedAt: this._active.startedAt,\n };\n }\n\n /** True if any job is currently running. */\n isBusy(): boolean {\n return this._jobs.size > 0;\n }\n\n clear(reason?: Error): void {\n const cancelledGeneration = this._generation;\n this._generation++;\n const cancelReason = reason ?? new Error('Job cancelled: queue was cleared');\n this._generationCancelReasons.set(cancelledGeneration, cancelReason);\n for (const generation of this._generationCancelReasons.keys()) {\n if (generation < this._generation - 10) {\n this._generationCancelReasons.delete(generation);\n }\n }\n if (this._active) {\n this._active.abortController.abort(cancelReason);\n }\n }\n}\n","import { HardwareErrorCode, createHwkError } from './errors';\n\nimport type { ConnectionType, DeviceCapabilities, DeviceInfo, VendorType } from './device';\nimport type { UiResponseEvent } from '../events/ui-request';\n\n// =====================================================================\n// Connector types — transport-level abstraction for device communication\n// =====================================================================\n\n/**\n * Minimal device info returned during discovery (searchDevices).\n * At scan time, full DeviceInfo fields like firmwareVersion are not yet available.\n */\nexport interface ConnectorDevice {\n connectId: string;\n deviceId: string;\n name: string;\n /**\n * Physical transport this device was discovered on. Mirrors Trezor\n * Connect's `descriptor.apiType` — when several transports are fused behind\n * one connector (see `createCombinedConnector`), the merged device list\n * carries this so the host can tell a USB entry from a BLE one and route\n * `connect()` back to the owning transport. Single-transport connectors may\n * leave it undefined.\n */\n connectionType?: ConnectionType;\n /** Machine model id (e.g. \"nanoX\"). */\n model?: string;\n /** Human-readable model name (e.g. \"Ledger Nano X\"). */\n modelName?: string;\n /** BLE signal strength (BLE only). */\n rssi?: number | null;\n /** BLE connectable flag (BLE only). */\n isConnectable?: boolean | null;\n /** USB serial number (USB only). */\n serialNumber?: string;\n\n /** Device capabilities — available from scan time */\n capabilities?: DeviceCapabilities;\n\n /**\n * Vendor-specific raw blob from the transport descriptor (USB / BLE).\n * Populated by `descriptorToConnectorDevice` in each connector. Treat as\n * informational; promote any field consumed by the app layer onto the\n * typed surface above.\n */\n raw?: Record<string, unknown>;\n}\n\nexport interface ConnectorSession {\n sessionId: string;\n deviceInfo: DeviceInfo;\n}\n\n// =====================================================================\n// Connector call result — device errors travel as DATA, not exceptions\n//\n// `IConnector.call` never throws for device-level failures. It resolves a\n// discriminated result so the failure crosses any process boundary\n// (IHardwareBridge / extension offscreen↔SW) as plain `data`. This mirrors\n// the OneKey HD-SDK `IDeviceResponseResult` contract.\n//\n// WHY: when a thrown Error crosses the extension JsBridge it is run through\n// `toPlainError`, a fixed field whitelist that drops custom own-properties\n// (e.g. `appName`). Returning the failure as data keeps every field intact.\n//\n// Contract for `ConnectorSerializedError`: only `message` / `code` /\n// `errorCode` live at the top level; ALL other domain fields (`appName`,\n// `_tag`, `statusCode`, …) are nested under `params`.\n// =====================================================================\n\n/**\n * Vendor-agnostic bag of extra error fields. Known keys are documented for\n * discoverability; the index signature keeps it open so any connector can\n * carry vendor-specific data without losing it across the bridge.\n */\nexport interface ConnectorErrorParams {\n /** Vendor SDK error tag (e.g. Ledger DMK `_tag`). */\n _tag?: string;\n /** App involved, e.g. the Ledger app being opened/installed. */\n appName?: string;\n /** Transport / APDU status code (string or number depending on vendor). */\n statusCode?: unknown;\n /**\n * Shallow snapshot of a nested cause. A raw Error does not survive JSON\n * serialization (its `message`/`stack` are non-enumerable), so recovery\n * predicates that recurse into a cause get this plain-object copy instead.\n */\n originalError?: {\n message?: string;\n code?: number;\n errorCode?: string;\n statusCode?: unknown;\n _tag?: string;\n };\n [key: string]: unknown;\n}\n\nexport interface ConnectorSerializedError {\n message: string;\n code?: number;\n errorCode?: string;\n params?: ConnectorErrorParams;\n}\n\nexport type ConnectorCallResult =\n | { success: true; payload: unknown }\n | { success: false; error: ConnectorSerializedError };\n\nexport type ConnectorEventType =\n | 'device-connect'\n | 'device-disconnect'\n | 'features'\n | 'device-trezor-thp-credentials-changed'\n | 'ui-request'\n | 'ui-event';\n\n/**\n * Interaction event types emitted via 'ui-event'.\n * These map to user-facing prompts (confirm on device, open app, etc.).\n */\nexport enum EConnectorInteraction {\n /** Adapter is actively searching for the device (no session yet) */\n Searching = 'searching',\n /** Device requires user to open a specific app */\n ConfirmOpenApp = 'confirm-open-app',\n /** Device requires user to unlock */\n UnlockDevice = 'unlock-device',\n /** Device needs user to confirm on device (sign, verify, etc.) */\n ConfirmOnDevice = 'confirm-on-device',\n /** Previous interaction completed — clear UI prompt */\n InteractionComplete = 'interaction-complete',\n /**\n * OS-level Ledger app install progress. `progress` is a 0..1 fraction\n * reported by DMK's InstallOrUpdateAppsDeviceAction. Emitted from inside\n * the connector so the progress callback ref never has to cross the\n * IHardwareBridge boundary.\n */\n AppInstallProgress = 'app-install-progress',\n}\n\n// Discriminated union: most variants only carry `sessionId`, but\n// AppInstallProgress also carries `appName` + `progress`. Searching has no\n// session yet so it carries an empty `sessionId`.\nexport type ConnectorUiEvent =\n | { type: EConnectorInteraction.Searching; payload: { sessionId: string } }\n | { type: EConnectorInteraction.ConfirmOpenApp; payload: { sessionId: string } }\n | { type: EConnectorInteraction.UnlockDevice; payload: { sessionId: string } }\n | { type: EConnectorInteraction.ConfirmOnDevice; payload: { sessionId: string } }\n | { type: EConnectorInteraction.InteractionComplete; payload: { sessionId: string } }\n | {\n type: EConnectorInteraction.AppInstallProgress;\n payload: { sessionId: string; appName: string; progress: number };\n };\n\nexport interface ConnectorEventMap {\n 'device-connect': { device: ConnectorDevice };\n 'device-disconnect': { connectId: string };\n features: { device: ConnectorDevice & { features: Record<string, unknown> } };\n 'device-trezor-thp-credentials-changed': {\n connectId: string;\n deviceId?: string;\n credentials: Record<string, unknown>[];\n };\n 'ui-request': { type: string; payload?: unknown };\n 'ui-event': ConnectorUiEvent;\n}\n\nexport interface ConnectorSearchDevicesOptions {\n /**\n * Wait for every child transport in a fused connector. Default discovery can\n * return shortly after USB appears so BLE does not slow down USB flows;\n * binding pickers can opt in when they need BLE candidates too.\n */\n waitForAll?: boolean;\n}\n\nexport interface IConnector {\n /** Physical connection type this connector uses. Fixed at construction. */\n readonly connectionType: ConnectionType;\n\n searchDevices(options?: ConnectorSearchDevicesOptions): Promise<ConnectorDevice[]>;\n connect(deviceId?: string): Promise<ConnectorSession>;\n disconnect(sessionId: string): Promise<void>;\n // `call` resolves a discriminated result; device-level failures are returned\n // as data, never thrown (see ConnectorCallResult). Only `call` uses this\n // contract because it is the one method that carries rich, vendor-specific\n // domain errors across the IHardwareBridge boundary, where a thrown Error\n // would be stripped by the host bridge's error whitelist. The other methods\n // surface plain operational failures and still reject normally.\n call(sessionId: string, method: string, params: unknown): Promise<ConnectorCallResult>;\n cancel(sessionId: string): Promise<void>;\n\n /** Send a UI response (e.g. PIN, passphrase) to the device. */\n uiResponse(response: UiResponseEvent): void;\n\n on<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;\n off<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;\n\n reset(): void;\n\n // Vendor-specific opt-in: warm-load persisted credentials before the first\n // session. Trezor uses this for THP `knownCredentials` (host-stored pairing\n // credentials replayed in `ThpHandshakeInitRequest` to skip the CodeEntry /\n // QrCode / NFC pairing UX on every connect). Vendors without persistent\n // credentials (Ledger, etc.) simply don't implement it.\n setKnownCredentials?(credentials: unknown[]): Promise<void> | void;\n}\n\n// =====================================================================\n// Hardware bridge — generic forwarding interface for cross-boundary IConnector\n//\n// The same shape works across any process / context boundary that needs to\n// expose a multi-vendor backend behind a single-vendor IConnector facade:\n// - Electron (renderer ↔ preload/main via contextBridge)\n// - Browser Extension (popup/content ↔ background/offscreen via chrome.runtime)\n// - React Native (JS ↔ native module via NativeModules)\n// - Web Worker / iframe (postMessage)\n//\n// Each method takes a `vendor` discriminator so a single bridge implementation\n// can multiplex across vendors (ledger, trezor, ...).\n// =====================================================================\n\nexport interface IHardwareBridge {\n searchDevices(params: {\n vendor: VendorType;\n options?: ConnectorSearchDevicesOptions;\n }): Promise<ConnectorDevice[]>;\n connect(params: { vendor: VendorType; deviceId?: string }): Promise<ConnectorSession>;\n disconnect(params: { vendor: VendorType; sessionId: string }): Promise<void>;\n call(params: {\n vendor: VendorType;\n sessionId: string;\n method: string;\n callParams: unknown;\n }): Promise<ConnectorCallResult>;\n cancel(params: { vendor: VendorType; sessionId: string }): Promise<void>;\n uiResponse(params: { vendor: VendorType; response: UiResponseEvent }): void;\n reset(params: { vendor: VendorType }): void;\n\n /** Register an event handler for connector events forwarded across the bridge. */\n onEvent(\n params: { vendor: VendorType },\n handler: (event: { type: ConnectorEventType; data: unknown }) => void\n ): void;\n\n /** Unregister a previously registered event handler. */\n offEvent(\n params: { vendor: VendorType },\n handler: (event: { type: ConnectorEventType; data: unknown }) => void\n ): void;\n\n /**\n * Warm-load vendor-specific persisted credentials. Currently only Trezor\n * uses this (THP `knownCredentials`); the bridge implementation can\n * dispatch on `vendor` and route to the right connector instance.\n */\n setKnownCredentials?(params: {\n vendor: VendorType;\n credentials: unknown[];\n }): Promise<void> | void;\n}\n\n/**\n * Adapt an IHardwareBridge (multi-vendor backend) into a single-vendor IConnector.\n * Every IConnector method becomes a transparent forward to bridge.<method>({ vendor, ... }).\n * Events are forwarded via bridge.onEvent / offEvent.\n *\n * Use this anywhere the actual hardware lives behind a process / context boundary\n * (Electron main, extension background, native module, worker, iframe).\n */\nexport function createBridgedConnector(\n vendor: VendorType,\n connectionType: ConnectionType,\n bridge: IHardwareBridge\n): IConnector {\n // Keyed by (event, handler). A flat handler-only map would collide when the\n // same function is registered for multiple events — second .on() would\n // overwrite the first bridge handler reference, leaking it permanently.\n type UserHandler = (data: ConnectorEventMap[ConnectorEventType]) => void;\n type BridgeHandler = (event: { type: ConnectorEventType; data: unknown }) => void;\n const handlerMap = new Map<ConnectorEventType, Map<UserHandler, BridgeHandler>>();\n\n return {\n connectionType,\n searchDevices: options => bridge.searchDevices({ vendor, options }),\n connect: deviceId => bridge.connect({ vendor, deviceId }),\n disconnect: sessionId => bridge.disconnect({ vendor, sessionId }),\n call: (sessionId, method, callParams) => bridge.call({ vendor, sessionId, method, callParams }),\n cancel: sessionId => bridge.cancel({ vendor, sessionId }),\n uiResponse: response => bridge.uiResponse({ vendor, response }),\n on: (event, handler) => {\n const bridgeHandler: BridgeHandler = e => {\n if (e.type === event) {\n handler(e.data as ConnectorEventMap[typeof event]);\n }\n };\n let inner = handlerMap.get(event);\n if (!inner) {\n inner = new Map();\n handlerMap.set(event, inner);\n }\n inner.set(handler as UserHandler, bridgeHandler);\n bridge.onEvent({ vendor }, bridgeHandler);\n },\n off: (event, handler) => {\n const inner = handlerMap.get(event);\n const bridgeHandler = inner?.get(handler as UserHandler);\n if (!bridgeHandler || !inner) return;\n bridge.offEvent({ vendor }, bridgeHandler);\n inner.delete(handler as UserHandler);\n if (inner.size === 0) handlerMap.delete(event);\n },\n reset: () => bridge.reset({ vendor }),\n setKnownCredentials: bridge.setKnownCredentials\n ? credentials => bridge.setKnownCredentials!({ vendor, credentials })\n : undefined,\n };\n}\n\n// =====================================================================\n// ConnectorCallResult error (de)serialization — the canonical, vendor-agnostic\n// helpers every IConnector implementation / adapter should use, so the\n// \"errors as data\" contract is identical across vendors.\n// =====================================================================\n\nconst SERIALIZED_ERROR_TOP_LEVEL_KEYS = new Set([\n 'message',\n 'code',\n 'errorCode',\n 'stack',\n 'params',\n]);\n\n/**\n * Flatten a thrown error into the cross-boundary-safe `ConnectorSerializedError`\n * shape. `message`/`code`/`errorCode` are lifted to the top level; every other\n * own-enumerable field is copied into `params` so NO domain data is lost when\n * the result crosses a host bridge (which may run thrown errors through a\n * field whitelist). A nested `originalError` is shallow-snapshotted because a\n * raw Error does not survive JSON serialization.\n */\nexport function serializeConnectorError(err: unknown): ConnectorSerializedError {\n if (!err || typeof err !== 'object') {\n return { message: typeof err === 'string' ? err : 'Unknown error' };\n }\n const e = err as Record<string, unknown>;\n const message = typeof e.message === 'string' ? e.message : 'Unknown error';\n const code = typeof e.code === 'number' ? e.code : undefined;\n const errorCode = e.errorCode != null ? String(e.errorCode) : undefined;\n\n const params: ConnectorErrorParams = {};\n // Flatten an existing `params` bag, then copy every other own field (so\n // vendor-specific keys like `_tag` / `statusCode` / `appName` / step context\n // are preserved without being named here).\n if (e.params && typeof e.params === 'object') {\n Object.assign(params, e.params as Record<string, unknown>);\n }\n for (const key of Object.keys(e)) {\n if (!SERIALIZED_ERROR_TOP_LEVEL_KEYS.has(key)) {\n params[key] = e[key];\n }\n }\n const orig = e.originalError;\n if (orig && typeof orig === 'object') {\n const o = orig as Record<string, unknown>;\n params.originalError = {\n message: typeof o.message === 'string' ? o.message : undefined,\n code: typeof o.code === 'number' ? o.code : undefined,\n errorCode: o.errorCode != null ? String(o.errorCode) : undefined,\n statusCode: o.statusCode,\n _tag: typeof o._tag === 'string' ? o._tag : undefined,\n };\n }\n\n // The result crosses host bridges via JSON.stringify. Drop any single field\n // that isn't JSON-safe (circular ref / non-serializable) so a pathological\n // error degrades to \"one field missing\" instead of crashing the transport.\n for (const key of Object.keys(params)) {\n try {\n JSON.stringify(params[key]);\n } catch {\n delete params[key];\n }\n }\n\n return {\n message,\n ...(code !== undefined ? { code } : {}),\n ...(errorCode !== undefined ? { errorCode } : {}),\n ...(Object.keys(params).length ? { params } : {}),\n };\n}\n\n/**\n * Inverse of `serializeConnectorError`: rebuild a flat Error instance, lifting\n * `params.*` back to own-properties so existing throw-based classifiers/recovery\n * logic (which read `err._tag` / `err.code` / `err.appName` / …) keep working\n * unchanged. The Result shape stays confined to the connector boundary.\n */\nexport function rehydrateConnectorError(error: ConnectorSerializedError): Error {\n const { message, code, errorCode, params } = error;\n return Object.assign(new Error(message), {\n ...(code !== undefined ? { code } : {}),\n ...(errorCode !== undefined ? { errorCode } : {}),\n ...(params ?? {}),\n });\n}\n\n/**\n * Fuse several single-transport IConnectors (e.g. WebUSB + BLE for one\n * vendor) into one IConnector whose device list is the union of all of them.\n *\n * This mirrors how Trezor Connect's `DeviceList` keeps one `TransportManager`\n * per `apiType` running concurrently and merges their devices into a single\n * list: there is no \"switch\" between transports — both are always live, and\n * each discovered device carries its `connectionType` so the host knows which\n * channel it came in on. `connect()` routes back to the transport that owns\n * the chosen device; later calls route by `sessionId`.\n *\n * Notes / current limitations:\n * - `searchDevices()` fans out concurrently; a transport that throws while\n * scanning is treated as \"no devices\" so a dead/absent channel never sinks\n * the others.\n * - USB entries sort ahead of BLE ones (Trezor's `getPrioritizedDevices`).\n * - The same physical device reachable on two transports surfaces as two\n * entries with different `connectId`s — we do NOT dedup, so the host can\n * present (or pick) a channel explicitly.\n * - `uiResponse()` carries no sessionId, so it is broadcast to every child;\n * a child with no matching pending request ignores it.\n */\nfunction isDeviceUnavailableError(error: unknown): boolean {\n const typed = error as { code?: unknown };\n if (\n typed.code === HardwareErrorCode.DeviceNotFound ||\n typed.code === HardwareErrorCode.DeviceDisconnected\n ) {\n return true;\n }\n return false;\n}\n\nfunction combinedDeviceNotFoundError(message: string): Error {\n return createHwkError({\n code: HardwareErrorCode.DeviceNotFound,\n message,\n });\n}\n\nfunction combinedSessionNotFoundError(message: string): Error {\n return createHwkError({\n code: HardwareErrorCode.DeviceDisconnected,\n message,\n });\n}\n\nexport function createCombinedConnector(connectors: IConnector[]): IConnector {\n if (connectors.length === 0) {\n throw new Error('createCombinedConnector: at least one connector is required');\n }\n const SEARCH_SETTLE_AFTER_FIRST_DEVICE_MS = 250;\n\n // connectId -> the child connector that discovered it (set on searchDevices).\n const deviceOwner = new Map<string, IConnector>();\n // sessionId -> the child connector that owns the live session.\n const sessionOwner = new Map<string, IConnector>();\n // userHandler -> the per-child forwarders we attached, so off() can detach.\n type UserHandler = (data: ConnectorEventMap[ConnectorEventType]) => void;\n const forwarders = new Map<\n ConnectorEventType,\n Map<UserHandler, Array<{ child: IConnector; handler: UserHandler }>>\n >();\n\n // BLE ranks after USB — matches Trezor's getPrioritizedDevices().\n const rank = (device: ConnectorDevice): number => (device.connectionType === 'ble' ? 1 : 0);\n\n // Shared THP pairing credentials across all child transports. A credential is\n // keyed by the device's static public key (transport-agnostic, see\n // `findKnownPairingCredentials`), so a credential minted while pairing over\n // one transport (e.g. USB) must reach the sibling transports (e.g. BLE) or\n // they re-pair instead of autoconnecting. Each child keeps its OWN\n // knownCredentials array, so we maintain the union here and re-broadcast it to\n // every child whenever any child mints a fresh one.\n const sharedCredentials: Array<Record<string, unknown>> = [];\n const credentialKey = (c: Record<string, unknown>): string =>\n (c.credential as string) ?? JSON.stringify(c);\n const mergeShared = (incoming: ReadonlyArray<Record<string, unknown>>): boolean => {\n let changed = false;\n for (const cred of incoming) {\n const key = credentialKey(cred);\n if (!sharedCredentials.some(e => credentialKey(e) === key)) {\n sharedCredentials.push(cred);\n changed = true;\n }\n }\n return changed;\n };\n const broadcastCredentials = async (): Promise<void> => {\n await Promise.all(\n connectors.map(child => Promise.resolve(child.setKnownCredentials?.(sharedCredentials)))\n );\n };\n\n // Internal subscription (independent of user on()/off()): when any child mints\n // fresh pairing credentials, fold them into the shared union and push the\n // union down to every child so the next handshake on ANY transport\n // autoconnects rather than re-pairing.\n for (const child of connectors) {\n child.on('device-trezor-thp-credentials-changed', data => {\n if (mergeShared(data.credentials)) void broadcastCredentials();\n });\n }\n\n const searchDevices = async (\n options: { waitForAll?: boolean } = {}\n ): Promise<ConnectorDevice[]> => {\n const perConnector: Array<{\n index: number;\n devices: ConnectorDevice[];\n }> = [];\n\n await new Promise<void>(resolve => {\n let finished = false;\n let remaining = connectors.length;\n let settleTimer: ReturnType<typeof setTimeout> | undefined;\n\n const finish = () => {\n if (finished) return;\n finished = true;\n if (settleTimer) clearTimeout(settleTimer);\n resolve();\n };\n\n connectors.forEach((child, index) => {\n void child\n .searchDevices()\n .then(devices =>\n devices.map(device => ({\n ...device,\n connectionType: device.connectionType ?? child.connectionType,\n }))\n )\n .catch(\n () =>\n // A transport that can't scan (powered off, unauthorized, absent)\n // must not fail the whole fused search.\n [] as ConnectorDevice[]\n )\n .then(devices => {\n remaining -= 1;\n if (!finished) {\n perConnector.push({ index, devices });\n }\n if (remaining === 0) {\n finish();\n return;\n }\n const hasUsbDevice = devices.some(device => device.connectionType === 'usb');\n if (hasUsbDevice && !settleTimer && !options.waitForAll) {\n settleTimer = setTimeout(finish, SEARCH_SETTLE_AFTER_FIRST_DEVICE_MS);\n }\n });\n });\n });\n\n perConnector.sort((a, b) => a.index - b.index);\n\n deviceOwner.clear();\n const merged: ConnectorDevice[] = [];\n perConnector.forEach(({ index, devices }) => {\n for (const device of devices) {\n deviceOwner.set(device.connectId, connectors[index]);\n merged.push(device);\n }\n });\n return merged.sort((a, b) => rank(a) - rank(b));\n };\n\n const resolveOwner = async (\n deviceId?: string\n ): Promise<{ owner: IConnector; deviceId?: string }> => {\n if (deviceId && deviceOwner.has(deviceId)) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { owner: deviceOwner.get(deviceId)!, deviceId };\n }\n const devices = await searchDevices({ waitForAll: Boolean(deviceId) });\n if (deviceId) {\n const owner = deviceOwner.get(deviceId);\n if (!owner)\n throw combinedDeviceNotFoundError(`Combined connector: device not found: ${deviceId}`);\n return { owner, deviceId };\n }\n const first = devices[0];\n if (!first) throw combinedDeviceNotFoundError('Combined connector: no devices found');\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { owner: deviceOwner.get(first.connectId)!, deviceId: first.connectId };\n };\n\n const connectByExplicitId = async (\n deviceId: string\n ): Promise<{ session: ConnectorSession; owner: IConnector }> => {\n const cachedOwner = deviceOwner.get(deviceId);\n if (cachedOwner) {\n return { session: await cachedOwner.connect(deviceId), owner: cachedOwner };\n }\n\n let lastError: unknown;\n for (const child of connectors) {\n try {\n const session = await child.connect(deviceId);\n deviceOwner.set(deviceId, child);\n return { session, owner: child };\n } catch (error) {\n if (!isDeviceUnavailableError(error)) {\n throw error;\n }\n lastError = error;\n }\n }\n const message =\n lastError instanceof Error\n ? lastError.message\n : `Combined connector: device not found: ${deviceId}`;\n throw createHwkError({\n code: HardwareErrorCode.DeviceNotFound,\n message,\n });\n };\n\n return {\n // Nominal value only — the per-device `connectionType` is authoritative\n // for a fused connector.\n connectionType: connectors[0].connectionType,\n\n searchDevices: options => searchDevices({ waitForAll: options?.waitForAll }),\n\n connect: async deviceId => {\n let owner: IConnector;\n let session: ConnectorSession;\n if (deviceId) {\n ({ session, owner } = await connectByExplicitId(deviceId));\n } else {\n const resolved = await resolveOwner();\n owner = resolved.owner;\n session = await owner.connect(resolved.deviceId);\n }\n // Use the owner resolved during connect — re-deriving via\n // session.deviceInfo.connectId breaks for ephemeral-id transports (the id\n // can change on connect → missed lookup → orphaned session).\n sessionOwner.set(session.sessionId, owner);\n return session;\n },\n\n disconnect: async sessionId => {\n const owner = sessionOwner.get(sessionId);\n if (!owner) return;\n await owner.disconnect(sessionId);\n sessionOwner.delete(sessionId);\n },\n\n call: async (sessionId, method, params) => {\n const owner = sessionOwner.get(sessionId);\n if (!owner) {\n throw combinedSessionNotFoundError(`Combined connector: session not found: ${sessionId}`);\n }\n return owner.call(sessionId, method, params);\n },\n\n cancel: async sessionId => {\n const owner = sessionOwner.get(sessionId);\n if (!owner) return;\n await owner.cancel(sessionId);\n },\n\n uiResponse: response => {\n // No sessionId on the response — broadcast; children without a matching\n // pending request ignore it.\n for (const child of connectors) child.uiResponse(response);\n },\n\n on: (event, handler) => {\n const attached = connectors.map(child => {\n const forward: UserHandler = data => (handler as UserHandler)(data);\n child.on(event, forward as Parameters<IConnector['on']>[1]);\n return { child, handler: forward };\n });\n let inner = forwarders.get(event);\n if (!inner) {\n inner = new Map();\n forwarders.set(event, inner);\n }\n inner.set(handler as UserHandler, attached);\n },\n\n off: (event, handler) => {\n const inner = forwarders.get(event);\n const attached = inner?.get(handler as UserHandler);\n if (!attached || !inner) return;\n for (const { child, handler: forward } of attached) {\n child.off(event, forward as Parameters<IConnector['off']>[1]);\n }\n inner.delete(handler as UserHandler);\n if (inner.size === 0) forwarders.delete(event);\n },\n\n reset: () => {\n for (const child of connectors) child.reset();\n deviceOwner.clear();\n sessionOwner.clear();\n forwarders.clear();\n },\n\n setKnownCredentials: connectors.some(c => c.setKnownCredentials)\n ? async credentials => {\n // Seed the shared union from the host (warm-load) and fan out to all\n // children so every transport starts from the same credential set.\n sharedCredentials.length = 0;\n mergeShared((credentials ?? []) as Array<Record<string, unknown>>);\n await broadcastCredentials();\n }\n : undefined,\n };\n}\n","/**\n * Minimal typed event emitter using Map<string, Set<listener>>.\n * Each adapter uses this for device events (connect, disconnect, pin, etc.).\n *\n * TMap is a record mapping event name strings to their payload types.\n * Example:\n * type MyEvents = { 'connect': { id: string }; 'disconnect': { id: string } };\n * const emitter = new TypedEventEmitter<MyEvents>();\n * emitter.on('connect', (data) => { data.id }); // data is { id: string }\n *\n * For backward compatibility, TMap defaults to Record<string, any> so that\n * existing code using `new TypedEventEmitter<SomeUnionType>()` still compiles.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class TypedEventEmitter<TMap extends Record<string, any> = Record<string, any>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly _listeners = new Map<string, Set<(event: any) => void>>();\n\n on<K extends keyof TMap & string>(event: K, listener: (event: TMap[K]) => void): void;\n\n on(event: string, listener: (event: any) => void): void;\n\n on(event: string, listener: (event: any) => void): void {\n let set = this._listeners.get(event);\n if (!set) {\n set = new Set();\n this._listeners.set(event, set);\n }\n set.add(listener);\n }\n\n off<K extends keyof TMap & string>(event: K, listener: (event: TMap[K]) => void): void;\n\n off(event: string, listener: (event: any) => void): void;\n\n off(event: string, listener: (event: any) => void): void {\n const set = this._listeners.get(event);\n if (set) {\n set.delete(listener);\n if (set.size === 0) this._listeners.delete(event);\n }\n }\n\n emit<K extends keyof TMap & string>(event: K, data: TMap[K]): void;\n\n emit(event: string, data: unknown): void;\n\n emit(event: string, data: unknown): void {\n const set = this._listeners.get(event);\n if (set) {\n for (const listener of set) listener(data);\n }\n }\n\n removeAllListeners(): void {\n this._listeners.clear();\n }\n\n /** Number of listeners registered for `event`. 0 if none. */\n listenerCount(event: string): number {\n return this._listeners.get(event)?.size ?? 0;\n }\n}\n","/**\n * Compare two semver strings (e.g. \"2.1.0\" vs \"2.3.1\").\n * Returns -1 if a < b, 0 if equal, 1 if a > b.\n */\nexport function compareSemver(a: string, b: string): number {\n const pa = a.split('.').map(Number);\n const pb = b.split('.').map(Number);\n for (let i = 0; i < 3; i++) {\n const va = pa[i] ?? 0;\n const vb = pb[i] ?? 0;\n if (va < vb) return -1;\n if (va > vb) return 1;\n }\n return 0;\n}\n","import { bytesToHex as nobleBytesToHex, hexToBytes as nobleHexToBytes } from '@noble/hashes/utils';\n\n/** Ensure hex string has 0x prefix */\nexport function ensure0x(hex: string): string {\n return hex.startsWith('0x') ? hex : `0x${hex}`;\n}\n\n/** Strip 0x prefix from hex string */\nexport function stripHex(hex: string): string {\n return hex.startsWith('0x') ? hex.slice(2) : hex;\n}\n\n/** Pad hex to 64 chars (32 bytes) with 0x prefix */\nexport function padHex64(hex: string): string {\n return `0x${stripHex(hex).padStart(64, '0')}`;\n}\n\n/**\n * Convert a hex string (with or without 0x prefix) to a Uint8Array.\n * Throws on invalid hex (non-hex characters, odd length).\n */\nexport function hexToBytes(hex: string): Uint8Array {\n return nobleHexToBytes(stripHex(hex));\n}\n\n/** Convert a Uint8Array to a hex string (no 0x prefix). */\nexport function bytesToHex(bytes: Uint8Array): string {\n return nobleBytesToHex(bytes);\n}\n","export type DetectableHardwareVendor = 'onekey' | 'trezor' | 'ledger';\n\nexport type HardwareDeviceIdentityInput = {\n name?: string | null;\n localName?: string | null;\n bleName?: string | null;\n model?: string | null;\n modelName?: string | null;\n type?: string | null;\n productName?: string | null;\n manufacturerName?: string | null;\n vendor?: number | string | null;\n vendorId?: number | null;\n product?: number | string | null;\n productId?: number | null;\n label?: string | null;\n fw_vendor?: string | null;\n internal_model?: string | null;\n onekey_version?: string | null;\n onekey_device_type?: string | null;\n onekey_serial?: string | null;\n serviceUUIDs?: string[] | null;\n advertisedServiceUuids?: string[] | null;\n serviceUuids?: string[] | null;\n};\n\nconst ONEKEY_BLE_SERVICE_UUID = '00000001-0000-1000-8000-00805f9b34fb';\nconst TREZOR_BLE_SERVICE_UUID = '8c000001-a59b-4d58-a9ad-073df69fa1b1';\nconst LEDGER_USB_VENDOR_ID = 0x2c97;\n\nconst lower = (value?: string | null): string => value?.trim().toLowerCase() ?? '';\n\nconst hasServiceUuid = (input: HardwareDeviceIdentityInput, uuid: string): boolean => {\n const expected = uuid.toLowerCase();\n const values = [\n ...(input.serviceUUIDs ?? []),\n ...(input.advertisedServiceUuids ?? []),\n ...(input.serviceUuids ?? []),\n ];\n return values.some(value => value.toLowerCase() === expected);\n};\n\nexport function detectHardwareVendorFromDescriptor(\n input: HardwareDeviceIdentityInput\n): DetectableHardwareVendor | undefined {\n const manufacturerName = lower(input.manufacturerName);\n const fwVendor = lower(input.fw_vendor);\n\n if (\n hasServiceUuid(input, ONEKEY_BLE_SERVICE_UUID) ||\n manufacturerName.includes('onekey') ||\n fwVendor === 'onekey' ||\n input.onekey_version ||\n input.onekey_device_type ||\n input.onekey_serial\n ) {\n return 'onekey';\n }\n if (\n hasServiceUuid(input, TREZOR_BLE_SERVICE_UUID) ||\n manufacturerName.includes('trezor') ||\n fwVendor === 'trezor'\n ) {\n return 'trezor';\n }\n if (\n (typeof input.vendor === 'number' && input.vendor === LEDGER_USB_VENDOR_ID) ||\n input.vendorId === LEDGER_USB_VENDOR_ID ||\n manufacturerName.includes('ledger')\n ) {\n return 'ledger';\n }\n return undefined;\n}\n\nexport function isKnownNonTargetHardwareVendor(\n input: HardwareDeviceIdentityInput,\n targetVendor: DetectableHardwareVendor\n): boolean {\n const detectedVendor = detectHardwareVendorFromDescriptor(input);\n return detectedVendor !== undefined && detectedVendor !== targetVendor;\n}\n","import type { Response } from '../types/response';\n\n/**\n * Generic batch call with progress reporting.\n * If any single call fails, returns the failure immediately.\n */\nexport async function batchCall<TParam, TResult>(\n params: TParam[],\n callFn: (p: TParam) => Promise<Response<TResult>>,\n onProgress?: (progress: { index: number; total: number }) => void\n): Promise<Response<TResult[]>> {\n const results: TResult[] = [];\n for (let i = 0; i < params.length; i++) {\n const result = await callFn(params[i]);\n if (!result.success) {\n return result;\n }\n results.push(result.payload);\n onProgress?.({ index: i, total: params.length });\n }\n return { success: true, payload: results };\n}\n","import type { ChainForFingerprint } from '../types/fingerprint';\n\nexport type HardwareMethodMetadata = {\n chain: ChainForFingerprint;\n allNetwork: boolean;\n};\n\nexport const HARDWARE_METHOD_CATALOG = {\n evmGetAddress: { chain: 'evm', allNetwork: true },\n evmSignTransaction: { chain: 'evm', allNetwork: false },\n evmSignMessage: { chain: 'evm', allNetwork: false },\n evmSignTypedData: { chain: 'evm', allNetwork: false },\n btcGetAddress: { chain: 'btc', allNetwork: true },\n btcGetPublicKey: { chain: 'btc', allNetwork: true },\n btcSignTransaction: { chain: 'btc', allNetwork: false },\n btcSignPsbt: { chain: 'btc', allNetwork: false },\n btcSignMessage: { chain: 'btc', allNetwork: false },\n btcGetMasterFingerprint: { chain: 'btc', allNetwork: false },\n solGetAddress: { chain: 'sol', allNetwork: true },\n solSignTransaction: { chain: 'sol', allNetwork: false },\n solSignMessage: { chain: 'sol', allNetwork: false },\n tronGetAddress: { chain: 'tron', allNetwork: true },\n tronSignTransaction: { chain: 'tron', allNetwork: false },\n tronSignMessage: { chain: 'tron', allNetwork: false },\n} as const satisfies Record<string, HardwareMethodMetadata>;\n\nexport type HardwareMethodName = keyof typeof HARDWARE_METHOD_CATALOG;\n\nexport type AllNetworkMethodName = {\n [K in HardwareMethodName]: (typeof HARDWARE_METHOD_CATALOG)[K]['allNetwork'] extends true\n ? K\n : never;\n}[HardwareMethodName];\n\nexport const ALL_NETWORK_METHOD_NAMES = Object.entries(HARDWARE_METHOD_CATALOG)\n .filter(([, metadata]) => metadata.allNetwork)\n .map(([method]) => method) as AllNetworkMethodName[];\n\nconst ALL_NETWORK_METHOD_SET = new Set<string>(ALL_NETWORK_METHOD_NAMES);\n\nexport function getHardwareMethodMetadata(method: string): HardwareMethodMetadata | undefined {\n return HARDWARE_METHOD_CATALOG[method as HardwareMethodName];\n}\n\nexport function isAllNetworkMethodName(method: string): method is AllNetworkMethodName {\n return ALL_NETWORK_METHOD_SET.has(method);\n}\n\nexport function getAllNetworkMethodChain(method: AllNetworkMethodName): ChainForFingerprint {\n return HARDWARE_METHOD_CATALOG[method].chain;\n}\n","import { HardwareErrorCode } from '../types/errors';\nimport { failure, success } from '../types/response';\nimport { getAllNetworkMethodChain, isAllNetworkMethodName } from './methodCatalog';\n\nimport type { ChainForFingerprint } from '../types/fingerprint';\nimport type { Response } from '../types/response';\nimport type {\n AllNetworkAddressParams,\n AllNetworkAddressResponse,\n AllNetworkGetAddressParams,\n} from '../types/wallet';\nimport type { AllNetworkMethodName } from './methodCatalog';\n\nexport type AllNetworkCallItemContext = {\n connectId: string;\n deviceId: string;\n method: AllNetworkMethodName;\n chain: ChainForFingerprint;\n item: AllNetworkAddressParams;\n index: number;\n};\n\nexport type AllNetworkAttachIdentityContext = AllNetworkCallItemContext & {\n payload: Record<string, unknown>;\n};\n\nexport type AllNetworkResponseContext = AllNetworkCallItemContext & {\n response: AllNetworkAddressResponse;\n};\n\nexport type RunAllNetworkGetAddressOptions = {\n connectId: string;\n deviceId: string;\n params: AllNetworkGetAddressParams;\n getMethodChain?: (\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ) => ChainForFingerprint;\n normalizeItem?: (\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ) => AllNetworkAddressParams;\n buildUnsupportedNetworkResponse?: (\n item: AllNetworkAddressParams,\n method: AllNetworkMethodName\n ) => AllNetworkAddressResponse | undefined;\n callItem: (context: AllNetworkCallItemContext) => Promise<Response<unknown>>;\n attachIdentity: (context: AllNetworkAttachIdentityContext) => Promise<AllNetworkAddressResponse>;\n shouldAbortBundle?: (\n response: AllNetworkAddressResponse,\n context: AllNetworkResponseContext\n ) => boolean;\n buildTopLevelFailure?: (\n response: AllNetworkAddressResponse,\n context: AllNetworkResponseContext\n ) => Response<AllNetworkAddressResponse[]>;\n};\n\nexport async function runAllNetworkGetAddress({\n connectId,\n deviceId,\n params,\n getMethodChain = method => getAllNetworkMethodChain(method),\n normalizeItem = (_method, item) => item,\n buildUnsupportedNetworkResponse,\n callItem,\n attachIdentity,\n shouldAbortBundle = () => false,\n buildTopLevelFailure = defaultBuildTopLevelFailure,\n}: RunAllNetworkGetAddressOptions): Promise<Response<AllNetworkAddressResponse[]>> {\n const responses: AllNetworkAddressResponse[] = [];\n\n for (const [index, item] of params.bundle.entries()) {\n if (!isAllNetworkMethodName(String(item.methodName))) {\n responses.push(buildUnsupportedMethodResponse(item));\n continue;\n }\n\n const method = item.methodName;\n const unsupportedNetwork = buildUnsupportedNetworkResponse?.(item, method);\n if (unsupportedNetwork) {\n responses.push(unsupportedNetwork);\n continue;\n }\n\n const chain = getMethodChain(method, item);\n const normalizedItem = normalizeItem(method, item);\n const context: AllNetworkCallItemContext = {\n connectId,\n deviceId,\n method,\n chain,\n item: normalizedItem,\n index,\n };\n const response = await callItem(context);\n const itemResponse = response.success\n ? await attachIdentity({\n ...context,\n payload: response.payload as Record<string, unknown>,\n })\n : ({\n ...normalizedItem,\n success: false,\n payload: response.payload,\n } as AllNetworkAddressResponse);\n\n const responseContext = { ...context, response: itemResponse };\n if (!itemResponse.success && shouldAbortBundle(itemResponse, responseContext)) {\n return buildTopLevelFailure(itemResponse, responseContext);\n }\n responses.push(itemResponse);\n }\n\n return success(responses);\n}\n\nexport function buildUnsupportedMethodResponse(\n item: AllNetworkAddressParams\n): AllNetworkAddressResponse {\n return {\n ...item,\n success: false,\n payload: {\n code: HardwareErrorCode.InvalidParams,\n error: `Unsupported allNetwork method: ${String(item.methodName)}`,\n },\n };\n}\n\nfunction defaultBuildTopLevelFailure(\n response: AllNetworkAddressResponse\n): Response<AllNetworkAddressResponse[]> {\n const payload = response.payload ?? {};\n return failure(\n (payload.code as HardwareErrorCode | undefined) ?? HardwareErrorCode.DeviceMismatch,\n payload.error ?? 'All-network get-address aborted',\n normalizeFailureParams(payload.params)\n );\n}\n\nfunction normalizeFailureParams(params: unknown): Record<string, unknown> | undefined {\n return params && typeof params === 'object' ? (params as Record<string, unknown>) : undefined;\n}\n","export const DEVICE_CONNECT_RETRY_DELAY_MS = 1000;\n"]}
1
+ {"version":3,"sources":["/home/runner/work/hardware-js-sdk/hardware-js-sdk/packages/hwk-adapter-core/dist/index.js","../src/types/response.ts","../src/types/fingerprint.ts","../src/events/device.ts","../src/events/sdk.ts","../src/utils/DeviceJobQueue.ts","../src/types/connector.ts","../src/utils/TypedEventEmitter.ts","../src/utils/semver.ts","../src/utils/hex.ts","../src/utils/deviceIdentity.ts","../src/utils/batchCall.ts","../src/utils/methodCatalog.ts","../src/utils/allNetwork.ts","../src/constants.ts"],"names":["EConnectorInteraction"],"mappings":"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AACuC,IAAA;AAEd,IAAA;AAChB,MAAA;AACe,MAAA;AAEnB,IAAA;AACI,MAAA;AACM,MAAA;AACS,MAAA;AACpB,IAAA;AAEyD,IAAA;AACkB,IAAA;AACpB,MAAA;AAC3D,IAAA;AAC2B,IAAA;AAC7B,EAAA;AAEwB,EAAA;AAC1B;AAI6B;AACpB,EAAA;AACF,IAAA;AACM,IAAA;AACA,IAAA;AACP,MAAA;AACgE,MAAA;AAClE,IAAA;AACF,EAAA;AACF;AAIyC;AACF,EAAA;AAC9B,EAAA;AACI,qBAAA;AACQ,qBAAA;AACoB,IAAA;AACvC,EAAA;AACF;AAEsF;AACA,EAAA;AACtF;AbkkB4F;AACA;AcltB/C;AdotB+C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/hardware-js-sdk/hardware-js-sdk/packages/hwk-adapter-core/dist/index.js","sourcesContent":[null,"import type { HardwareErrorCode } from './errors';\n\nexport interface Success<T> {\n success: true;\n payload: T;\n}\n\nexport interface Failure {\n success: false;\n payload: {\n error: string;\n code: HardwareErrorCode;\n params?: Record<string, unknown>;\n };\n}\n\nexport type Response<T> = Success<T> | Failure;\n\nexport function success<T>(payload: T): Success<T> {\n return { success: true, payload };\n}\n\nexport function failure(\n code: HardwareErrorCode,\n error: string,\n params?: Record<string, unknown>\n): Failure {\n return {\n success: false,\n payload: { error, code, ...(params ? { params } : {}) },\n };\n}\n","/**\n * Chain fingerprint utilities for device identity verification.\n *\n * Ledger devices have ephemeral IDs that change every session.\n * To verify that the same seed/device is connected, we derive an address\n * at a fixed path (account 0, index 0) and hash it into a stable \"chain fingerprint\".\n */\nimport { sha256 } from '@noble/hashes/sha256';\nimport { bytesToHex, utf8ToBytes } from '@noble/hashes/utils';\n\n/**\n * Fixed derivation paths used to generate chain fingerprints.\n * Uses standard index 0 — Ledger firmware shows device confirmation for\n * non-standard paths (e.g., index=100), which would interrupt wallet creation.\n * The address is hashed into a 16-char fingerprint, not exposed directly.\n * - EVM: cointype 60 (Ledger ETH App only supports 60)\n * - BTC: cointype 1 (testnet)\n * - SOL: cointype 501, standard 3-level hardened\n */\nexport const CHAIN_FINGERPRINT_PATHS: Record<ChainForFingerprint, string> = {\n evm: \"m/44'/60'/0'/0/0\",\n // BTC: account-level path (3 levels), mainnet cointype 0.\n // Cointype 1 (testnet) is rejected by some Ledger BTC App configurations.\n btc: \"m/44'/0'/0'\",\n sol: \"m/44'/501'/0'\",\n tron: \"m/44'/195'/0'/0/0\",\n};\n\nexport type ChainForFingerprint = 'evm' | 'btc' | 'sol' | 'tron';\n\n/**\n * 16-char SHA-256 fingerprint for device-identity verification.\n * Callers must canonicalize input (e.g. EVM address → lowercase) —\n * encoding variations otherwise cause false DeviceMismatch.\n */\nexport function deriveDeviceFingerprint(value: string): string {\n return bytesToHex(sha256(utf8ToBytes(value))).slice(0, 16);\n}\n","export const DEVICE_EVENT = 'DEVICE_EVENT';\n\n/** Events originating from the hardware device. */\nexport const DEVICE = {\n CONNECT: 'device-connect',\n DISCONNECT: 'device-disconnect',\n CHANGED: 'device-changed',\n FEATURES: 'features',\n /**\n * Trezor-only. Emitted after a successful THP handshake that minted or\n * refreshed pairing credentials. The host should persist `credentials`\n * keyed by `deviceId` and feed them back into the connector on the next\n * connect to skip the CodeEntry/QrCode/NFC pairing UX.\n *\n * The `TREZOR_` prefix mirrors `UI_REQUEST.REQUEST_TREZOR_THP_PAIRING` —\n * vendor-specific events live in the shared event taxonomy but are named\n * so hosts can ignore them when they don't drive Trezor hardware.\n */\n TREZOR_THP_CREDENTIALS_CHANGED: 'device-trezor-thp-credentials-changed',\n} as const;\n","/** Events generated by SDK internal detection (not from hardware directly). */\nexport const SDK = {\n DEVICE_STUCK: 'device-stuck',\n DEVICE_UNRESPONSIVE: 'device-unresponsive',\n DEVICE_RECOVERED: 'device-recovered',\n DEVICE_INTERACTION: 'device-interaction',\n} as const;\n","/**\n * Pure FIFO job queue. Every enqueue chains onto the tail; jobs run one at\n * a time across all devices. The queue is intentionally passive — it does\n * NOT decide whether to interrupt or ask the user. Those are application-\n * layer concerns owned by the caller (e.g. a UI button handler that wants\n * to ask \"device is busy, interrupt current?\" before submitting). The\n * queue exposes inspection (`getActiveJob`) and explicit cancellation\n * (`cancelActive` / `cancelAll`) so callers can implement those policies\n * synchronously, without racing against in-flight enqueues.\n */\n\nexport interface JobOptions {\n label?: string;\n rejectIfBusy?: boolean;\n busyError?: Error;\n}\n\nexport interface ActiveJobInfo {\n deviceId: string;\n label?: string;\n startedAt: number;\n}\n\ninterface ActiveJob {\n deviceId: string;\n label?: string;\n abortController: AbortController;\n startedAt: number;\n}\n\nexport class DeviceJobQueue {\n private _tail: Promise<unknown> = Promise.resolve();\n\n private _active: ActiveJob | null = null;\n\n private readonly _jobs = new Map<object, { deviceId: string }>();\n\n /** Incremented on clear() so queued-but-not-yet-running jobs detect invalidation. */\n private _generation = 0;\n\n private readonly _generationCancelReasons = new Map<number, Error>();\n\n /**\n * Enqueue a job. Runs after every previously-enqueued job has settled.\n * `deviceId` is a label only — used by inspection / cancellation routing.\n */\n async enqueue<T>(\n deviceId: string,\n job: (signal: AbortSignal) => Promise<T>,\n options: JobOptions = {}\n ): Promise<T> {\n if (options.rejectIfBusy && this._jobs.size > 0) {\n throw options.busyError ?? new Error('Device is busy');\n }\n\n const ac = new AbortController();\n const gen = this._generation;\n const prev = this._tail;\n const jobToken = {};\n const activeJob: ActiveJob = {\n deviceId,\n label: options.label,\n abortController: ac,\n startedAt: Date.now(),\n };\n this._jobs.set(jobToken, { deviceId });\n\n const next = prev\n .catch(() => {})\n .then(async () => {\n if (this._generation !== gen) {\n throw (\n this._generationCancelReasons.get(gen) ?? new Error('Job cancelled: queue was cleared')\n );\n }\n this._active = activeJob;\n try {\n return await job(ac.signal);\n } finally {\n // Identity guard: a previous job's deferred finally must not\n // null out a successor's `_active`.\n if (this._active === activeJob) {\n this._active = null;\n }\n }\n })\n .finally(() => {\n this._jobs.delete(jobToken);\n });\n\n this._tail = next.catch(() => {});\n return next;\n }\n\n /** Cancel the active job. If `deviceId` is given, only cancels when it matches. */\n cancelActive(deviceId?: string): boolean {\n if (!this._active) return false;\n if (deviceId && this._active.deviceId !== deviceId) return false;\n this._active.abortController.abort(new Error('Manually cancelled'));\n return true;\n }\n\n /** Force cancel the active job. `reason` becomes signal.reason. */\n forceCancelActive(deviceId?: string, reason?: Error): boolean {\n if (!this._active) return false;\n if (deviceId && this._active.deviceId !== deviceId) return false;\n this._active.abortController.abort(reason ?? new Error('Force cancelled for recovery'));\n return true;\n }\n\n /** Cancel the active job (alias for callers that previously needed multi-device cancel). */\n cancelAllActive(reason?: Error): void {\n if (!this._active) return;\n this._active.abortController.abort(reason ?? new Error('Cancelled by cancelAllActive'));\n }\n\n /** Cancel the active job and invalidate queued jobs that have not started. */\n cancelActiveAndPending(deviceId?: string, reason?: Error): boolean {\n if (deviceId && this._active && this._active.deviceId !== deviceId) {\n return false;\n }\n this.clear(reason ?? new Error('Cancelled by cancelActiveAndPending'));\n return true;\n }\n\n /** Get info about the currently active job, or null if idle. */\n getActiveJob(deviceId?: string): ActiveJobInfo | null {\n if (!this._active) return null;\n if (deviceId && this._active.deviceId !== deviceId) return null;\n return {\n deviceId: this._active.deviceId,\n label: this._active.label,\n startedAt: this._active.startedAt,\n };\n }\n\n /** True if any job is currently running. */\n isBusy(): boolean {\n return this._jobs.size > 0;\n }\n\n clear(reason?: Error): void {\n const cancelledGeneration = this._generation;\n this._generation++;\n const cancelReason = reason ?? new Error('Job cancelled: queue was cleared');\n this._generationCancelReasons.set(cancelledGeneration, cancelReason);\n for (const generation of this._generationCancelReasons.keys()) {\n if (generation < this._generation - 10) {\n this._generationCancelReasons.delete(generation);\n }\n }\n if (this._active) {\n this._active.abortController.abort(cancelReason);\n }\n }\n}\n","import { HardwareErrorCode, createHwkError } from './errors';\n\nimport type { ConnectionType, DeviceCapabilities, DeviceInfo, VendorType } from './device';\nimport type { UiResponseEvent } from '../events/ui-request';\n\n// =====================================================================\n// Connector types — transport-level abstraction for device communication\n// =====================================================================\n\n/**\n * Minimal device info returned during discovery (searchDevices).\n * At scan time, full DeviceInfo fields like firmwareVersion are not yet available.\n */\nexport interface ConnectorDevice {\n connectId: string;\n deviceId: string;\n name: string;\n /**\n * Physical transport this device was discovered on. Mirrors Trezor\n * Connect's `descriptor.apiType` — when several transports are fused behind\n * one connector (see `createCombinedConnector`), the merged device list\n * carries this so the host can tell a USB entry from a BLE one and route\n * `connect()` back to the owning transport. Single-transport connectors may\n * leave it undefined.\n */\n connectionType?: ConnectionType;\n /** Machine model id (e.g. \"nanoX\"). */\n model?: string;\n /** Human-readable model name (e.g. \"Ledger Nano X\"). */\n modelName?: string;\n /** BLE signal strength (BLE only). */\n rssi?: number | null;\n /** BLE connectable flag (BLE only). */\n isConnectable?: boolean | null;\n /** USB serial number (USB only). */\n serialNumber?: string;\n\n /** Device capabilities — available from scan time */\n capabilities?: DeviceCapabilities;\n\n /**\n * Vendor-specific raw blob from the transport descriptor (USB / BLE).\n * Populated by `descriptorToConnectorDevice` in each connector. Treat as\n * informational; promote any field consumed by the app layer onto the\n * typed surface above.\n */\n raw?: Record<string, unknown>;\n}\n\nexport interface ConnectorSession {\n sessionId: string;\n deviceInfo: DeviceInfo;\n}\n\n// =====================================================================\n// Connector call result — device errors travel as DATA, not exceptions\n//\n// `IConnector.call` never throws for device-level failures. It resolves a\n// discriminated result so the failure crosses any process boundary\n// (IHardwareBridge / extension offscreen↔SW) as plain `data`. This mirrors\n// the OneKey HD-SDK `IDeviceResponseResult` contract.\n//\n// WHY: when a thrown Error crosses the extension JsBridge it is run through\n// `toPlainError`, a fixed field whitelist that drops custom own-properties\n// (e.g. `appName`). Returning the failure as data keeps every field intact.\n//\n// Contract for `ConnectorSerializedError`: only `message` / `code` /\n// `errorCode` live at the top level; ALL other domain fields (`appName`,\n// `_tag`, `statusCode`, …) are nested under `params`.\n// =====================================================================\n\n/**\n * Vendor-agnostic bag of extra error fields. Known keys are documented for\n * discoverability; the index signature keeps it open so any connector can\n * carry vendor-specific data without losing it across the bridge.\n */\nexport interface ConnectorErrorParams {\n /** Vendor SDK error tag (e.g. Ledger DMK `_tag`). */\n _tag?: string;\n /** App involved, e.g. the Ledger app being opened/installed. */\n appName?: string;\n /** Transport / APDU status code (string or number depending on vendor). */\n statusCode?: unknown;\n /**\n * Shallow snapshot of a nested cause. A raw Error does not survive JSON\n * serialization (its `message`/`stack` are non-enumerable), so recovery\n * predicates that recurse into a cause get this plain-object copy instead.\n */\n originalError?: {\n message?: string;\n code?: number;\n errorCode?: string;\n statusCode?: unknown;\n _tag?: string;\n };\n [key: string]: unknown;\n}\n\nexport interface ConnectorSerializedError {\n message: string;\n code?: number;\n errorCode?: string;\n params?: ConnectorErrorParams;\n}\n\nexport type ConnectorCallResult =\n | { success: true; payload: unknown }\n | { success: false; error: ConnectorSerializedError };\n\nexport type ConnectorEventType =\n | 'device-connect'\n | 'device-disconnect'\n | 'features'\n | 'device-trezor-thp-credentials-changed'\n | 'ui-request'\n | 'ui-event';\n\n/**\n * Interaction event types emitted via 'ui-event'.\n * These map to user-facing prompts (confirm on device, open app, etc.).\n */\nexport enum EConnectorInteraction {\n /** Adapter is actively searching for the device (no session yet) */\n Searching = 'searching',\n /** Device requires user to open a specific app */\n ConfirmOpenApp = 'confirm-open-app',\n /** Device requires user to unlock */\n UnlockDevice = 'unlock-device',\n /** Device needs user to confirm on device (sign, verify, etc.) */\n ConfirmOnDevice = 'confirm-on-device',\n /** Previous interaction completed — clear UI prompt */\n InteractionComplete = 'interaction-complete',\n /**\n * OS-level Ledger app install progress. `progress` is a 0..1 fraction\n * reported by DMK's InstallOrUpdateAppsDeviceAction. Emitted from inside\n * the connector so the progress callback ref never has to cross the\n * IHardwareBridge boundary.\n */\n AppInstallProgress = 'app-install-progress',\n}\n\n// Discriminated union: most variants only carry `sessionId`, but\n// AppInstallProgress also carries `appName` + `progress`. Searching has no\n// session yet so it carries an empty `sessionId`.\nexport type ConnectorUiEvent =\n | { type: EConnectorInteraction.Searching; payload: { sessionId: string } }\n | { type: EConnectorInteraction.ConfirmOpenApp; payload: { sessionId: string } }\n | { type: EConnectorInteraction.UnlockDevice; payload: { sessionId: string } }\n | { type: EConnectorInteraction.ConfirmOnDevice; payload: { sessionId: string } }\n | { type: EConnectorInteraction.InteractionComplete; payload: { sessionId: string } }\n | {\n type: EConnectorInteraction.AppInstallProgress;\n payload: { sessionId: string; appName: string; progress: number };\n };\n\nexport interface ConnectorEventMap {\n 'device-connect': { device: ConnectorDevice };\n 'device-disconnect': { connectId: string };\n features: { device: ConnectorDevice & { features: Record<string, unknown> } };\n 'device-trezor-thp-credentials-changed': {\n connectId: string;\n deviceId?: string;\n credentials: Record<string, unknown>[];\n };\n 'ui-request': { type: string; payload?: unknown };\n 'ui-event': ConnectorUiEvent;\n}\n\nexport interface ConnectorSearchDevicesOptions {\n /**\n * Wait for every child transport in a fused connector. Default discovery can\n * return shortly after USB appears so BLE does not slow down USB flows;\n * binding pickers can opt in when they need BLE candidates too.\n */\n waitForAll?: boolean;\n}\n\nexport interface ConnectorConfig {\n /**\n * Optional OneKey-controlled WebSocket relay base used only for Ledger's\n * genuine check. DMK appends its `/genuine` path and device query params.\n *\n * The value may contain a short-lived opaque relay token, so connectors must\n * never log it. Passing `undefined` restores Ledger's official default.\n */\n ledgerGenuineCheckWebSocketUrl?: string;\n}\n\nexport interface IConnector {\n /** Physical connection type this connector uses. Fixed at construction. */\n readonly connectionType: ConnectionType;\n\n searchDevices(options?: ConnectorSearchDevicesOptions): Promise<ConnectorDevice[]>;\n connect(deviceId?: string): Promise<ConnectorSession>;\n disconnect(sessionId: string): Promise<void>;\n // `call` resolves a discriminated result; device-level failures are returned\n // as data, never thrown (see ConnectorCallResult). Only `call` uses this\n // contract because it is the one method that carries rich, vendor-specific\n // domain errors across the IHardwareBridge boundary, where a thrown Error\n // would be stripped by the host bridge's error whitelist. The other methods\n // surface plain operational failures and still reject normally.\n call(sessionId: string, method: string, params: unknown): Promise<ConnectorCallResult>;\n cancel(sessionId: string): Promise<void>;\n\n /** Send a UI response (e.g. PIN, passphrase) to the device. */\n uiResponse(response: UiResponseEvent): void;\n\n on<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;\n off<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;\n\n reset(): void;\n\n /**\n * Reconfigure vendor-specific transport services before the next connect.\n * Ledger uses this to rebuild DMK against a short-lived OneKey genuine-check\n * relay. Vendors without runtime configuration may omit it.\n */\n configure?(config: ConnectorConfig): Promise<void> | void;\n\n // Vendor-specific opt-in: warm-load persisted credentials before the first\n // session. Trezor uses this for THP `knownCredentials` (host-stored pairing\n // credentials replayed in `ThpHandshakeInitRequest` to skip the CodeEntry /\n // QrCode / NFC pairing UX on every connect). Vendors without persistent\n // credentials (Ledger, etc.) simply don't implement it.\n setKnownCredentials?(credentials: unknown[]): Promise<void> | void;\n}\n\n// =====================================================================\n// Hardware bridge — generic forwarding interface for cross-boundary IConnector\n//\n// The same shape works across any process / context boundary that needs to\n// expose a multi-vendor backend behind a single-vendor IConnector facade:\n// - Electron (renderer ↔ preload/main via contextBridge)\n// - Browser Extension (popup/content ↔ background/offscreen via chrome.runtime)\n// - React Native (JS ↔ native module via NativeModules)\n// - Web Worker / iframe (postMessage)\n//\n// Each method takes a `vendor` discriminator so a single bridge implementation\n// can multiplex across vendors (ledger, trezor, ...).\n// =====================================================================\n\nexport interface IHardwareBridge {\n searchDevices(params: {\n vendor: VendorType;\n options?: ConnectorSearchDevicesOptions;\n }): Promise<ConnectorDevice[]>;\n connect(params: { vendor: VendorType; deviceId?: string }): Promise<ConnectorSession>;\n disconnect(params: { vendor: VendorType; sessionId: string }): Promise<void>;\n call(params: {\n vendor: VendorType;\n sessionId: string;\n method: string;\n callParams: unknown;\n }): Promise<ConnectorCallResult>;\n cancel(params: { vendor: VendorType; sessionId: string }): Promise<void>;\n uiResponse(params: { vendor: VendorType; response: UiResponseEvent }): void;\n reset(params: { vendor: VendorType }): void;\n configure?(params: { vendor: VendorType; config: ConnectorConfig }): Promise<void> | void;\n\n /** Register an event handler for connector events forwarded across the bridge. */\n onEvent(\n params: { vendor: VendorType },\n handler: (event: { type: ConnectorEventType; data: unknown }) => void\n ): void;\n\n /** Unregister a previously registered event handler. */\n offEvent(\n params: { vendor: VendorType },\n handler: (event: { type: ConnectorEventType; data: unknown }) => void\n ): void;\n\n /**\n * Warm-load vendor-specific persisted credentials. Currently only Trezor\n * uses this (THP `knownCredentials`); the bridge implementation can\n * dispatch on `vendor` and route to the right connector instance.\n */\n setKnownCredentials?(params: {\n vendor: VendorType;\n credentials: unknown[];\n }): Promise<void> | void;\n}\n\n/**\n * Adapt an IHardwareBridge (multi-vendor backend) into a single-vendor IConnector.\n * Every IConnector method becomes a transparent forward to bridge.<method>({ vendor, ... }).\n * Events are forwarded via bridge.onEvent / offEvent.\n *\n * Use this anywhere the actual hardware lives behind a process / context boundary\n * (Electron main, extension background, native module, worker, iframe).\n */\nexport function createBridgedConnector(\n vendor: VendorType,\n connectionType: ConnectionType,\n bridge: IHardwareBridge\n): IConnector {\n // Keyed by (event, handler). A flat handler-only map would collide when the\n // same function is registered for multiple events — second .on() would\n // overwrite the first bridge handler reference, leaking it permanently.\n type UserHandler = (data: ConnectorEventMap[ConnectorEventType]) => void;\n type BridgeHandler = (event: { type: ConnectorEventType; data: unknown }) => void;\n const handlerMap = new Map<ConnectorEventType, Map<UserHandler, BridgeHandler>>();\n\n return {\n connectionType,\n searchDevices: options => bridge.searchDevices({ vendor, options }),\n connect: deviceId => bridge.connect({ vendor, deviceId }),\n disconnect: sessionId => bridge.disconnect({ vendor, sessionId }),\n call: (sessionId, method, callParams) => bridge.call({ vendor, sessionId, method, callParams }),\n cancel: sessionId => bridge.cancel({ vendor, sessionId }),\n uiResponse: response => bridge.uiResponse({ vendor, response }),\n on: (event, handler) => {\n const bridgeHandler: BridgeHandler = e => {\n if (e.type === event) {\n handler(e.data as ConnectorEventMap[typeof event]);\n }\n };\n let inner = handlerMap.get(event);\n if (!inner) {\n inner = new Map();\n handlerMap.set(event, inner);\n }\n inner.set(handler as UserHandler, bridgeHandler);\n bridge.onEvent({ vendor }, bridgeHandler);\n },\n off: (event, handler) => {\n const inner = handlerMap.get(event);\n const bridgeHandler = inner?.get(handler as UserHandler);\n if (!bridgeHandler || !inner) return;\n bridge.offEvent({ vendor }, bridgeHandler);\n inner.delete(handler as UserHandler);\n if (inner.size === 0) handlerMap.delete(event);\n },\n reset: () => bridge.reset({ vendor }),\n configure: bridge.configure ? config => bridge.configure?.({ vendor, config }) : undefined,\n setKnownCredentials: bridge.setKnownCredentials\n ? credentials => bridge.setKnownCredentials!({ vendor, credentials })\n : undefined,\n };\n}\n\n// =====================================================================\n// ConnectorCallResult error (de)serialization — the canonical, vendor-agnostic\n// helpers every IConnector implementation / adapter should use, so the\n// \"errors as data\" contract is identical across vendors.\n// =====================================================================\n\nconst SERIALIZED_ERROR_TOP_LEVEL_KEYS = new Set([\n 'message',\n 'code',\n 'errorCode',\n 'stack',\n 'params',\n]);\n\n/**\n * Flatten a thrown error into the cross-boundary-safe `ConnectorSerializedError`\n * shape. `message`/`code`/`errorCode` are lifted to the top level; every other\n * own-enumerable field is copied into `params` so NO domain data is lost when\n * the result crosses a host bridge (which may run thrown errors through a\n * field whitelist). A nested `originalError` is shallow-snapshotted because a\n * raw Error does not survive JSON serialization.\n */\nexport function serializeConnectorError(err: unknown): ConnectorSerializedError {\n if (!err || typeof err !== 'object') {\n return { message: typeof err === 'string' ? err : 'Unknown error' };\n }\n const e = err as Record<string, unknown>;\n const message = typeof e.message === 'string' ? e.message : 'Unknown error';\n const code = typeof e.code === 'number' ? e.code : undefined;\n const errorCode = e.errorCode != null ? String(e.errorCode) : undefined;\n\n const params: ConnectorErrorParams = {};\n // Flatten an existing `params` bag, then copy every other own field (so\n // vendor-specific keys like `_tag` / `statusCode` / `appName` / step context\n // are preserved without being named here).\n if (e.params && typeof e.params === 'object') {\n Object.assign(params, e.params as Record<string, unknown>);\n }\n for (const key of Object.keys(e)) {\n if (!SERIALIZED_ERROR_TOP_LEVEL_KEYS.has(key)) {\n params[key] = e[key];\n }\n }\n const orig = e.originalError;\n if (orig && typeof orig === 'object') {\n const o = orig as Record<string, unknown>;\n params.originalError = {\n message: typeof o.message === 'string' ? o.message : undefined,\n code: typeof o.code === 'number' ? o.code : undefined,\n errorCode: o.errorCode != null ? String(o.errorCode) : undefined,\n statusCode: o.statusCode,\n _tag: typeof o._tag === 'string' ? o._tag : undefined,\n };\n }\n\n // The result crosses host bridges via JSON.stringify. Drop any single field\n // that isn't JSON-safe (circular ref / non-serializable) so a pathological\n // error degrades to \"one field missing\" instead of crashing the transport.\n for (const key of Object.keys(params)) {\n try {\n JSON.stringify(params[key]);\n } catch {\n delete params[key];\n }\n }\n\n return {\n message,\n ...(code !== undefined ? { code } : {}),\n ...(errorCode !== undefined ? { errorCode } : {}),\n ...(Object.keys(params).length ? { params } : {}),\n };\n}\n\n/**\n * Inverse of `serializeConnectorError`: rebuild a flat Error instance, lifting\n * `params.*` back to own-properties so existing throw-based classifiers/recovery\n * logic (which read `err._tag` / `err.code` / `err.appName` / …) keep working\n * unchanged. The Result shape stays confined to the connector boundary.\n */\nexport function rehydrateConnectorError(error: ConnectorSerializedError): Error {\n const { message, code, errorCode, params } = error;\n return Object.assign(new Error(message), {\n ...(code !== undefined ? { code } : {}),\n ...(errorCode !== undefined ? { errorCode } : {}),\n ...(params ?? {}),\n });\n}\n\n/**\n * Fuse several single-transport IConnectors (e.g. WebUSB + BLE for one\n * vendor) into one IConnector whose device list is the union of all of them.\n *\n * This mirrors how Trezor Connect's `DeviceList` keeps one `TransportManager`\n * per `apiType` running concurrently and merges their devices into a single\n * list: there is no \"switch\" between transports — both are always live, and\n * each discovered device carries its `connectionType` so the host knows which\n * channel it came in on. `connect()` routes back to the transport that owns\n * the chosen device; later calls route by `sessionId`.\n *\n * Notes / current limitations:\n * - `searchDevices()` fans out concurrently; a transport that throws while\n * scanning is treated as \"no devices\" so a dead/absent channel never sinks\n * the others.\n * - USB entries sort ahead of BLE ones (Trezor's `getPrioritizedDevices`).\n * - The same physical device reachable on two transports surfaces as two\n * entries with different `connectId`s — we do NOT dedup, so the host can\n * present (or pick) a channel explicitly.\n * - `uiResponse()` carries no sessionId, so it is broadcast to every child;\n * a child with no matching pending request ignores it.\n */\nfunction isDeviceUnavailableError(error: unknown): boolean {\n const typed = error as { code?: unknown };\n if (\n typed.code === HardwareErrorCode.DeviceNotFound ||\n typed.code === HardwareErrorCode.DeviceDisconnected\n ) {\n return true;\n }\n return false;\n}\n\nfunction combinedDeviceNotFoundError(message: string): Error {\n return createHwkError({\n code: HardwareErrorCode.DeviceNotFound,\n message,\n });\n}\n\nfunction combinedSessionNotFoundError(message: string): Error {\n return createHwkError({\n code: HardwareErrorCode.DeviceDisconnected,\n message,\n });\n}\n\nexport function createCombinedConnector(connectors: IConnector[]): IConnector {\n if (connectors.length === 0) {\n throw new Error('createCombinedConnector: at least one connector is required');\n }\n const SEARCH_SETTLE_AFTER_FIRST_DEVICE_MS = 250;\n\n // connectId -> the child connector that discovered it (set on searchDevices).\n const deviceOwner = new Map<string, IConnector>();\n // sessionId -> the child connector that owns the live session.\n const sessionOwner = new Map<string, IConnector>();\n // userHandler -> the per-child forwarders we attached, so off() can detach.\n type UserHandler = (data: ConnectorEventMap[ConnectorEventType]) => void;\n const forwarders = new Map<\n ConnectorEventType,\n Map<UserHandler, Array<{ child: IConnector; handler: UserHandler }>>\n >();\n\n // BLE ranks after USB — matches Trezor's getPrioritizedDevices().\n const rank = (device: ConnectorDevice): number => (device.connectionType === 'ble' ? 1 : 0);\n\n // Shared THP pairing credentials across all child transports. A credential is\n // keyed by the device's static public key (transport-agnostic, see\n // `findKnownPairingCredentials`), so a credential minted while pairing over\n // one transport (e.g. USB) must reach the sibling transports (e.g. BLE) or\n // they re-pair instead of autoconnecting. Each child keeps its OWN\n // knownCredentials array, so we maintain the union here and re-broadcast it to\n // every child whenever any child mints a fresh one.\n const sharedCredentials: Array<Record<string, unknown>> = [];\n const credentialKey = (c: Record<string, unknown>): string =>\n (c.credential as string) ?? JSON.stringify(c);\n const mergeShared = (incoming: ReadonlyArray<Record<string, unknown>>): boolean => {\n let changed = false;\n for (const cred of incoming) {\n const key = credentialKey(cred);\n if (!sharedCredentials.some(e => credentialKey(e) === key)) {\n sharedCredentials.push(cred);\n changed = true;\n }\n }\n return changed;\n };\n const broadcastCredentials = async (): Promise<void> => {\n await Promise.all(\n connectors.map(child => Promise.resolve(child.setKnownCredentials?.(sharedCredentials)))\n );\n };\n\n // Internal subscription (independent of user on()/off()): when any child mints\n // fresh pairing credentials, fold them into the shared union and push the\n // union down to every child so the next handshake on ANY transport\n // autoconnects rather than re-pairing.\n for (const child of connectors) {\n child.on('device-trezor-thp-credentials-changed', data => {\n if (mergeShared(data.credentials)) void broadcastCredentials();\n });\n }\n\n const searchDevices = async (\n options: { waitForAll?: boolean } = {}\n ): Promise<ConnectorDevice[]> => {\n const perConnector: Array<{\n index: number;\n devices: ConnectorDevice[];\n }> = [];\n\n await new Promise<void>(resolve => {\n let finished = false;\n let remaining = connectors.length;\n let settleTimer: ReturnType<typeof setTimeout> | undefined;\n\n const finish = () => {\n if (finished) return;\n finished = true;\n if (settleTimer) clearTimeout(settleTimer);\n resolve();\n };\n\n connectors.forEach((child, index) => {\n void child\n .searchDevices()\n .then(devices =>\n devices.map(device => ({\n ...device,\n connectionType: device.connectionType ?? child.connectionType,\n }))\n )\n .catch(\n () =>\n // A transport that can't scan (powered off, unauthorized, absent)\n // must not fail the whole fused search.\n [] as ConnectorDevice[]\n )\n .then(devices => {\n remaining -= 1;\n if (!finished) {\n perConnector.push({ index, devices });\n }\n if (remaining === 0) {\n finish();\n return;\n }\n const hasUsbDevice = devices.some(device => device.connectionType === 'usb');\n if (hasUsbDevice && !settleTimer && !options.waitForAll) {\n settleTimer = setTimeout(finish, SEARCH_SETTLE_AFTER_FIRST_DEVICE_MS);\n }\n });\n });\n });\n\n perConnector.sort((a, b) => a.index - b.index);\n\n deviceOwner.clear();\n const merged: ConnectorDevice[] = [];\n perConnector.forEach(({ index, devices }) => {\n for (const device of devices) {\n deviceOwner.set(device.connectId, connectors[index]);\n merged.push(device);\n }\n });\n return merged.sort((a, b) => rank(a) - rank(b));\n };\n\n const resolveOwner = async (\n deviceId?: string\n ): Promise<{ owner: IConnector; deviceId?: string }> => {\n if (deviceId && deviceOwner.has(deviceId)) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { owner: deviceOwner.get(deviceId)!, deviceId };\n }\n const devices = await searchDevices({ waitForAll: Boolean(deviceId) });\n if (deviceId) {\n const owner = deviceOwner.get(deviceId);\n if (!owner)\n throw combinedDeviceNotFoundError(`Combined connector: device not found: ${deviceId}`);\n return { owner, deviceId };\n }\n const first = devices[0];\n if (!first) throw combinedDeviceNotFoundError('Combined connector: no devices found');\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { owner: deviceOwner.get(first.connectId)!, deviceId: first.connectId };\n };\n\n const connectByExplicitId = async (\n deviceId: string\n ): Promise<{ session: ConnectorSession; owner: IConnector }> => {\n const cachedOwner = deviceOwner.get(deviceId);\n if (cachedOwner) {\n return { session: await cachedOwner.connect(deviceId), owner: cachedOwner };\n }\n\n let lastError: unknown;\n for (const child of connectors) {\n try {\n const session = await child.connect(deviceId);\n deviceOwner.set(deviceId, child);\n return { session, owner: child };\n } catch (error) {\n if (!isDeviceUnavailableError(error)) {\n throw error;\n }\n lastError = error;\n }\n }\n const message =\n lastError instanceof Error\n ? lastError.message\n : `Combined connector: device not found: ${deviceId}`;\n throw createHwkError({\n code: HardwareErrorCode.DeviceNotFound,\n message,\n });\n };\n\n return {\n // Nominal value only — the per-device `connectionType` is authoritative\n // for a fused connector.\n connectionType: connectors[0].connectionType,\n\n searchDevices: options => searchDevices({ waitForAll: options?.waitForAll }),\n\n connect: async deviceId => {\n let owner: IConnector;\n let session: ConnectorSession;\n if (deviceId) {\n ({ session, owner } = await connectByExplicitId(deviceId));\n } else {\n const resolved = await resolveOwner();\n owner = resolved.owner;\n session = await owner.connect(resolved.deviceId);\n }\n // Use the owner resolved during connect — re-deriving via\n // session.deviceInfo.connectId breaks for ephemeral-id transports (the id\n // can change on connect → missed lookup → orphaned session).\n sessionOwner.set(session.sessionId, owner);\n return session;\n },\n\n disconnect: async sessionId => {\n const owner = sessionOwner.get(sessionId);\n if (!owner) return;\n await owner.disconnect(sessionId);\n sessionOwner.delete(sessionId);\n },\n\n call: async (sessionId, method, params) => {\n const owner = sessionOwner.get(sessionId);\n if (!owner) {\n throw combinedSessionNotFoundError(`Combined connector: session not found: ${sessionId}`);\n }\n return owner.call(sessionId, method, params);\n },\n\n cancel: async sessionId => {\n const owner = sessionOwner.get(sessionId);\n if (!owner) return;\n await owner.cancel(sessionId);\n },\n\n uiResponse: response => {\n // No sessionId on the response — broadcast; children without a matching\n // pending request ignore it.\n for (const child of connectors) child.uiResponse(response);\n },\n\n on: (event, handler) => {\n const attached = connectors.map(child => {\n const forward: UserHandler = data => (handler as UserHandler)(data);\n child.on(event, forward as Parameters<IConnector['on']>[1]);\n return { child, handler: forward };\n });\n let inner = forwarders.get(event);\n if (!inner) {\n inner = new Map();\n forwarders.set(event, inner);\n }\n inner.set(handler as UserHandler, attached);\n },\n\n off: (event, handler) => {\n const inner = forwarders.get(event);\n const attached = inner?.get(handler as UserHandler);\n if (!attached || !inner) return;\n for (const { child, handler: forward } of attached) {\n child.off(event, forward as Parameters<IConnector['off']>[1]);\n }\n inner.delete(handler as UserHandler);\n if (inner.size === 0) forwarders.delete(event);\n },\n\n reset: () => {\n for (const child of connectors) child.reset();\n deviceOwner.clear();\n sessionOwner.clear();\n forwarders.clear();\n },\n\n configure: connectors.some(c => c.configure)\n ? async config => {\n await Promise.all(connectors.map(child => Promise.resolve(child.configure?.(config))));\n deviceOwner.clear();\n sessionOwner.clear();\n }\n : undefined,\n\n setKnownCredentials: connectors.some(c => c.setKnownCredentials)\n ? async credentials => {\n // Seed the shared union from the host (warm-load) and fan out to all\n // children so every transport starts from the same credential set.\n sharedCredentials.length = 0;\n mergeShared((credentials ?? []) as Array<Record<string, unknown>>);\n await broadcastCredentials();\n }\n : undefined,\n };\n}\n","/**\n * Minimal typed event emitter using Map<string, Set<listener>>.\n * Each adapter uses this for device events (connect, disconnect, pin, etc.).\n *\n * TMap is a record mapping event name strings to their payload types.\n * Example:\n * type MyEvents = { 'connect': { id: string }; 'disconnect': { id: string } };\n * const emitter = new TypedEventEmitter<MyEvents>();\n * emitter.on('connect', (data) => { data.id }); // data is { id: string }\n *\n * For backward compatibility, TMap defaults to Record<string, any> so that\n * existing code using `new TypedEventEmitter<SomeUnionType>()` still compiles.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class TypedEventEmitter<TMap extends Record<string, any> = Record<string, any>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly _listeners = new Map<string, Set<(event: any) => void>>();\n\n on<K extends keyof TMap & string>(event: K, listener: (event: TMap[K]) => void): void;\n\n on(event: string, listener: (event: any) => void): void;\n\n on(event: string, listener: (event: any) => void): void {\n let set = this._listeners.get(event);\n if (!set) {\n set = new Set();\n this._listeners.set(event, set);\n }\n set.add(listener);\n }\n\n off<K extends keyof TMap & string>(event: K, listener: (event: TMap[K]) => void): void;\n\n off(event: string, listener: (event: any) => void): void;\n\n off(event: string, listener: (event: any) => void): void {\n const set = this._listeners.get(event);\n if (set) {\n set.delete(listener);\n if (set.size === 0) this._listeners.delete(event);\n }\n }\n\n emit<K extends keyof TMap & string>(event: K, data: TMap[K]): void;\n\n emit(event: string, data: unknown): void;\n\n emit(event: string, data: unknown): void {\n const set = this._listeners.get(event);\n if (set) {\n for (const listener of set) listener(data);\n }\n }\n\n removeAllListeners(): void {\n this._listeners.clear();\n }\n\n /** Number of listeners registered for `event`. 0 if none. */\n listenerCount(event: string): number {\n return this._listeners.get(event)?.size ?? 0;\n }\n}\n","/**\n * Compare two semver strings (e.g. \"2.1.0\" vs \"2.3.1\").\n * Returns -1 if a < b, 0 if equal, 1 if a > b.\n */\nexport function compareSemver(a: string, b: string): number {\n const pa = a.split('.').map(Number);\n const pb = b.split('.').map(Number);\n for (let i = 0; i < 3; i++) {\n const va = pa[i] ?? 0;\n const vb = pb[i] ?? 0;\n if (va < vb) return -1;\n if (va > vb) return 1;\n }\n return 0;\n}\n","import { bytesToHex as nobleBytesToHex, hexToBytes as nobleHexToBytes } from '@noble/hashes/utils';\n\n/** Ensure hex string has 0x prefix */\nexport function ensure0x(hex: string): string {\n return hex.startsWith('0x') ? hex : `0x${hex}`;\n}\n\n/** Strip 0x prefix from hex string */\nexport function stripHex(hex: string): string {\n return hex.startsWith('0x') ? hex.slice(2) : hex;\n}\n\n/** Pad hex to 64 chars (32 bytes) with 0x prefix */\nexport function padHex64(hex: string): string {\n return `0x${stripHex(hex).padStart(64, '0')}`;\n}\n\n/**\n * Convert a hex string (with or without 0x prefix) to a Uint8Array.\n * Throws on invalid hex (non-hex characters, odd length).\n */\nexport function hexToBytes(hex: string): Uint8Array {\n return nobleHexToBytes(stripHex(hex));\n}\n\n/** Convert a Uint8Array to a hex string (no 0x prefix). */\nexport function bytesToHex(bytes: Uint8Array): string {\n return nobleBytesToHex(bytes);\n}\n","export type DetectableHardwareVendor = 'onekey' | 'trezor' | 'ledger';\n\nexport type HardwareDeviceIdentityInput = {\n name?: string | null;\n localName?: string | null;\n bleName?: string | null;\n model?: string | null;\n modelName?: string | null;\n type?: string | null;\n productName?: string | null;\n manufacturerName?: string | null;\n vendor?: number | string | null;\n vendorId?: number | null;\n product?: number | string | null;\n productId?: number | null;\n label?: string | null;\n fw_vendor?: string | null;\n internal_model?: string | null;\n onekey_version?: string | null;\n onekey_device_type?: string | null;\n onekey_serial?: string | null;\n serviceUUIDs?: string[] | null;\n advertisedServiceUuids?: string[] | null;\n serviceUuids?: string[] | null;\n};\n\nconst ONEKEY_BLE_SERVICE_UUID = '00000001-0000-1000-8000-00805f9b34fb';\nconst TREZOR_BLE_SERVICE_UUID = '8c000001-a59b-4d58-a9ad-073df69fa1b1';\nconst LEDGER_USB_VENDOR_ID = 0x2c97;\n\nconst lower = (value?: string | null): string => value?.trim().toLowerCase() ?? '';\n\nconst hasServiceUuid = (input: HardwareDeviceIdentityInput, uuid: string): boolean => {\n const expected = uuid.toLowerCase();\n const values = [\n ...(input.serviceUUIDs ?? []),\n ...(input.advertisedServiceUuids ?? []),\n ...(input.serviceUuids ?? []),\n ];\n return values.some(value => value.toLowerCase() === expected);\n};\n\nexport function detectHardwareVendorFromDescriptor(\n input: HardwareDeviceIdentityInput\n): DetectableHardwareVendor | undefined {\n const manufacturerName = lower(input.manufacturerName);\n const fwVendor = lower(input.fw_vendor);\n\n if (\n hasServiceUuid(input, ONEKEY_BLE_SERVICE_UUID) ||\n manufacturerName.includes('onekey') ||\n fwVendor === 'onekey' ||\n input.onekey_version ||\n input.onekey_device_type ||\n input.onekey_serial\n ) {\n return 'onekey';\n }\n if (\n hasServiceUuid(input, TREZOR_BLE_SERVICE_UUID) ||\n manufacturerName.includes('trezor') ||\n fwVendor === 'trezor'\n ) {\n return 'trezor';\n }\n if (\n (typeof input.vendor === 'number' && input.vendor === LEDGER_USB_VENDOR_ID) ||\n input.vendorId === LEDGER_USB_VENDOR_ID ||\n manufacturerName.includes('ledger')\n ) {\n return 'ledger';\n }\n return undefined;\n}\n\nexport function isKnownNonTargetHardwareVendor(\n input: HardwareDeviceIdentityInput,\n targetVendor: DetectableHardwareVendor\n): boolean {\n const detectedVendor = detectHardwareVendorFromDescriptor(input);\n return detectedVendor !== undefined && detectedVendor !== targetVendor;\n}\n","import type { Response } from '../types/response';\n\n/**\n * Generic batch call with progress reporting.\n * If any single call fails, returns the failure immediately.\n */\nexport async function batchCall<TParam, TResult>(\n params: TParam[],\n callFn: (p: TParam) => Promise<Response<TResult>>,\n onProgress?: (progress: { index: number; total: number }) => void\n): Promise<Response<TResult[]>> {\n const results: TResult[] = [];\n for (let i = 0; i < params.length; i++) {\n const result = await callFn(params[i]);\n if (!result.success) {\n return result;\n }\n results.push(result.payload);\n onProgress?.({ index: i, total: params.length });\n }\n return { success: true, payload: results };\n}\n","import type { ChainForFingerprint } from '../types/fingerprint';\n\nexport type HardwareMethodMetadata = {\n chain: ChainForFingerprint;\n allNetwork: boolean;\n};\n\nexport const HARDWARE_METHOD_CATALOG = {\n evmGetAddress: { chain: 'evm', allNetwork: true },\n evmSignTransaction: { chain: 'evm', allNetwork: false },\n evmSignMessage: { chain: 'evm', allNetwork: false },\n evmSignTypedData: { chain: 'evm', allNetwork: false },\n btcGetAddress: { chain: 'btc', allNetwork: true },\n btcGetPublicKey: { chain: 'btc', allNetwork: true },\n btcSignTransaction: { chain: 'btc', allNetwork: false },\n btcSignPsbt: { chain: 'btc', allNetwork: false },\n btcSignMessage: { chain: 'btc', allNetwork: false },\n btcGetMasterFingerprint: { chain: 'btc', allNetwork: false },\n solGetAddress: { chain: 'sol', allNetwork: true },\n solSignTransaction: { chain: 'sol', allNetwork: false },\n solSignMessage: { chain: 'sol', allNetwork: false },\n tronGetAddress: { chain: 'tron', allNetwork: true },\n tronSignTransaction: { chain: 'tron', allNetwork: false },\n tronSignMessage: { chain: 'tron', allNetwork: false },\n} as const satisfies Record<string, HardwareMethodMetadata>;\n\nexport type HardwareMethodName = keyof typeof HARDWARE_METHOD_CATALOG;\n\nexport type AllNetworkMethodName = {\n [K in HardwareMethodName]: (typeof HARDWARE_METHOD_CATALOG)[K]['allNetwork'] extends true\n ? K\n : never;\n}[HardwareMethodName];\n\nexport const ALL_NETWORK_METHOD_NAMES = Object.entries(HARDWARE_METHOD_CATALOG)\n .filter(([, metadata]) => metadata.allNetwork)\n .map(([method]) => method) as AllNetworkMethodName[];\n\nconst ALL_NETWORK_METHOD_SET = new Set<string>(ALL_NETWORK_METHOD_NAMES);\n\nexport function getHardwareMethodMetadata(method: string): HardwareMethodMetadata | undefined {\n return HARDWARE_METHOD_CATALOG[method as HardwareMethodName];\n}\n\nexport function isAllNetworkMethodName(method: string): method is AllNetworkMethodName {\n return ALL_NETWORK_METHOD_SET.has(method);\n}\n\nexport function getAllNetworkMethodChain(method: AllNetworkMethodName): ChainForFingerprint {\n return HARDWARE_METHOD_CATALOG[method].chain;\n}\n","import { HardwareErrorCode } from '../types/errors';\nimport { failure, success } from '../types/response';\nimport { getAllNetworkMethodChain, isAllNetworkMethodName } from './methodCatalog';\n\nimport type { ChainForFingerprint } from '../types/fingerprint';\nimport type { Response } from '../types/response';\nimport type {\n AllNetworkAddressParams,\n AllNetworkAddressResponse,\n AllNetworkGetAddressParams,\n} from '../types/wallet';\nimport type { AllNetworkMethodName } from './methodCatalog';\n\nexport type AllNetworkCallItemContext = {\n connectId: string;\n deviceId: string;\n method: AllNetworkMethodName;\n chain: ChainForFingerprint;\n item: AllNetworkAddressParams;\n index: number;\n};\n\nexport type AllNetworkAttachIdentityContext = AllNetworkCallItemContext & {\n payload: Record<string, unknown>;\n};\n\nexport type AllNetworkResponseContext = AllNetworkCallItemContext & {\n response: AllNetworkAddressResponse;\n};\n\nexport type RunAllNetworkGetAddressOptions = {\n connectId: string;\n deviceId: string;\n params: AllNetworkGetAddressParams;\n getMethodChain?: (\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ) => ChainForFingerprint;\n normalizeItem?: (\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ) => AllNetworkAddressParams;\n buildUnsupportedNetworkResponse?: (\n item: AllNetworkAddressParams,\n method: AllNetworkMethodName\n ) => AllNetworkAddressResponse | undefined;\n callItem: (context: AllNetworkCallItemContext) => Promise<Response<unknown>>;\n attachIdentity: (context: AllNetworkAttachIdentityContext) => Promise<AllNetworkAddressResponse>;\n shouldAbortBundle?: (\n response: AllNetworkAddressResponse,\n context: AllNetworkResponseContext\n ) => boolean;\n buildTopLevelFailure?: (\n response: AllNetworkAddressResponse,\n context: AllNetworkResponseContext\n ) => Response<AllNetworkAddressResponse[]>;\n};\n\nexport async function runAllNetworkGetAddress({\n connectId,\n deviceId,\n params,\n getMethodChain = method => getAllNetworkMethodChain(method),\n normalizeItem = (_method, item) => item,\n buildUnsupportedNetworkResponse,\n callItem,\n attachIdentity,\n shouldAbortBundle = () => false,\n buildTopLevelFailure = defaultBuildTopLevelFailure,\n}: RunAllNetworkGetAddressOptions): Promise<Response<AllNetworkAddressResponse[]>> {\n const responses: AllNetworkAddressResponse[] = [];\n\n for (const [index, item] of params.bundle.entries()) {\n if (!isAllNetworkMethodName(String(item.methodName))) {\n responses.push(buildUnsupportedMethodResponse(item));\n continue;\n }\n\n const method = item.methodName;\n const unsupportedNetwork = buildUnsupportedNetworkResponse?.(item, method);\n if (unsupportedNetwork) {\n responses.push(unsupportedNetwork);\n continue;\n }\n\n const chain = getMethodChain(method, item);\n const normalizedItem = normalizeItem(method, item);\n const context: AllNetworkCallItemContext = {\n connectId,\n deviceId,\n method,\n chain,\n item: normalizedItem,\n index,\n };\n const response = await callItem(context);\n const itemResponse = response.success\n ? await attachIdentity({\n ...context,\n payload: response.payload as Record<string, unknown>,\n })\n : ({\n ...normalizedItem,\n success: false,\n payload: response.payload,\n } as AllNetworkAddressResponse);\n\n const responseContext = { ...context, response: itemResponse };\n if (!itemResponse.success && shouldAbortBundle(itemResponse, responseContext)) {\n return buildTopLevelFailure(itemResponse, responseContext);\n }\n responses.push(itemResponse);\n }\n\n return success(responses);\n}\n\nexport function buildUnsupportedMethodResponse(\n item: AllNetworkAddressParams\n): AllNetworkAddressResponse {\n return {\n ...item,\n success: false,\n payload: {\n code: HardwareErrorCode.InvalidParams,\n error: `Unsupported allNetwork method: ${String(item.methodName)}`,\n },\n };\n}\n\nfunction defaultBuildTopLevelFailure(\n response: AllNetworkAddressResponse\n): Response<AllNetworkAddressResponse[]> {\n const payload = response.payload ?? {};\n return failure(\n (payload.code as HardwareErrorCode | undefined) ?? HardwareErrorCode.DeviceMismatch,\n payload.error ?? 'All-network get-address aborted',\n normalizeFailureParams(payload.params)\n );\n}\n\nfunction normalizeFailureParams(params: unknown): Record<string, unknown> | undefined {\n return params && typeof params === 'object' ? (params as Record<string, unknown>) : undefined;\n}\n","export const DEVICE_CONNECT_RETRY_DELAY_MS = 1000;\n"]}
package/dist/index.mjs CHANGED
@@ -218,6 +218,7 @@ function createBridgedConnector(vendor, connectionType, bridge) {
218
218
  if (inner.size === 0) handlerMap.delete(event);
219
219
  },
220
220
  reset: () => bridge.reset({ vendor }),
221
+ configure: bridge.configure ? (config) => bridge.configure?.({ vendor, config }) : void 0,
221
222
  setKnownCredentials: bridge.setKnownCredentials ? (credentials) => bridge.setKnownCredentials({ vendor, credentials }) : void 0
222
223
  };
223
224
  }
@@ -487,6 +488,11 @@ function createCombinedConnector(connectors) {
487
488
  sessionOwner.clear();
488
489
  forwarders.clear();
489
490
  },
491
+ configure: connectors.some((c) => c.configure) ? async (config) => {
492
+ await Promise.all(connectors.map((child) => Promise.resolve(child.configure?.(config))));
493
+ deviceOwner.clear();
494
+ sessionOwner.clear();
495
+ } : void 0,
490
496
  setKnownCredentials: connectors.some((c) => c.setKnownCredentials) ? async (credentials) => {
491
497
  sharedCredentials.length = 0;
492
498
  mergeShared(credentials ?? []);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/response.ts","../src/types/fingerprint.ts","../src/events/device.ts","../src/events/sdk.ts","../src/utils/DeviceJobQueue.ts","../src/types/connector.ts","../src/utils/TypedEventEmitter.ts","../src/utils/semver.ts","../src/utils/hex.ts","../src/utils/deviceIdentity.ts","../src/utils/batchCall.ts","../src/utils/methodCatalog.ts","../src/utils/allNetwork.ts","../src/constants.ts"],"sourcesContent":["import type { HardwareErrorCode } from './errors';\n\nexport interface Success<T> {\n success: true;\n payload: T;\n}\n\nexport interface Failure {\n success: false;\n payload: {\n error: string;\n code: HardwareErrorCode;\n params?: Record<string, unknown>;\n };\n}\n\nexport type Response<T> = Success<T> | Failure;\n\nexport function success<T>(payload: T): Success<T> {\n return { success: true, payload };\n}\n\nexport function failure(\n code: HardwareErrorCode,\n error: string,\n params?: Record<string, unknown>\n): Failure {\n return {\n success: false,\n payload: { error, code, ...(params ? { params } : {}) },\n };\n}\n","/**\n * Chain fingerprint utilities for device identity verification.\n *\n * Ledger devices have ephemeral IDs that change every session.\n * To verify that the same seed/device is connected, we derive an address\n * at a fixed path (account 0, index 0) and hash it into a stable \"chain fingerprint\".\n */\nimport { sha256 } from '@noble/hashes/sha256';\nimport { bytesToHex, utf8ToBytes } from '@noble/hashes/utils';\n\n/**\n * Fixed derivation paths used to generate chain fingerprints.\n * Uses standard index 0 — Ledger firmware shows device confirmation for\n * non-standard paths (e.g., index=100), which would interrupt wallet creation.\n * The address is hashed into a 16-char fingerprint, not exposed directly.\n * - EVM: cointype 60 (Ledger ETH App only supports 60)\n * - BTC: cointype 1 (testnet)\n * - SOL: cointype 501, standard 3-level hardened\n */\nexport const CHAIN_FINGERPRINT_PATHS: Record<ChainForFingerprint, string> = {\n evm: \"m/44'/60'/0'/0/0\",\n // BTC: account-level path (3 levels), mainnet cointype 0.\n // Cointype 1 (testnet) is rejected by some Ledger BTC App configurations.\n btc: \"m/44'/0'/0'\",\n sol: \"m/44'/501'/0'\",\n tron: \"m/44'/195'/0'/0/0\",\n};\n\nexport type ChainForFingerprint = 'evm' | 'btc' | 'sol' | 'tron';\n\n/**\n * 16-char SHA-256 fingerprint for device-identity verification.\n * Callers must canonicalize input (e.g. EVM address → lowercase) —\n * encoding variations otherwise cause false DeviceMismatch.\n */\nexport function deriveDeviceFingerprint(value: string): string {\n return bytesToHex(sha256(utf8ToBytes(value))).slice(0, 16);\n}\n","export const DEVICE_EVENT = 'DEVICE_EVENT';\n\n/** Events originating from the hardware device. */\nexport const DEVICE = {\n CONNECT: 'device-connect',\n DISCONNECT: 'device-disconnect',\n CHANGED: 'device-changed',\n FEATURES: 'features',\n /**\n * Trezor-only. Emitted after a successful THP handshake that minted or\n * refreshed pairing credentials. The host should persist `credentials`\n * keyed by `deviceId` and feed them back into the connector on the next\n * connect to skip the CodeEntry/QrCode/NFC pairing UX.\n *\n * The `TREZOR_` prefix mirrors `UI_REQUEST.REQUEST_TREZOR_THP_PAIRING` —\n * vendor-specific events live in the shared event taxonomy but are named\n * so hosts can ignore them when they don't drive Trezor hardware.\n */\n TREZOR_THP_CREDENTIALS_CHANGED: 'device-trezor-thp-credentials-changed',\n} as const;\n","/** Events generated by SDK internal detection (not from hardware directly). */\nexport const SDK = {\n DEVICE_STUCK: 'device-stuck',\n DEVICE_UNRESPONSIVE: 'device-unresponsive',\n DEVICE_RECOVERED: 'device-recovered',\n DEVICE_INTERACTION: 'device-interaction',\n} as const;\n","/**\n * Pure FIFO job queue. Every enqueue chains onto the tail; jobs run one at\n * a time across all devices. The queue is intentionally passive — it does\n * NOT decide whether to interrupt or ask the user. Those are application-\n * layer concerns owned by the caller (e.g. a UI button handler that wants\n * to ask \"device is busy, interrupt current?\" before submitting). The\n * queue exposes inspection (`getActiveJob`) and explicit cancellation\n * (`cancelActive` / `cancelAll`) so callers can implement those policies\n * synchronously, without racing against in-flight enqueues.\n */\n\nexport interface JobOptions {\n label?: string;\n rejectIfBusy?: boolean;\n busyError?: Error;\n}\n\nexport interface ActiveJobInfo {\n deviceId: string;\n label?: string;\n startedAt: number;\n}\n\ninterface ActiveJob {\n deviceId: string;\n label?: string;\n abortController: AbortController;\n startedAt: number;\n}\n\nexport class DeviceJobQueue {\n private _tail: Promise<unknown> = Promise.resolve();\n\n private _active: ActiveJob | null = null;\n\n private readonly _jobs = new Map<object, { deviceId: string }>();\n\n /** Incremented on clear() so queued-but-not-yet-running jobs detect invalidation. */\n private _generation = 0;\n\n private readonly _generationCancelReasons = new Map<number, Error>();\n\n /**\n * Enqueue a job. Runs after every previously-enqueued job has settled.\n * `deviceId` is a label only — used by inspection / cancellation routing.\n */\n async enqueue<T>(\n deviceId: string,\n job: (signal: AbortSignal) => Promise<T>,\n options: JobOptions = {}\n ): Promise<T> {\n if (options.rejectIfBusy && this._jobs.size > 0) {\n throw options.busyError ?? new Error('Device is busy');\n }\n\n const ac = new AbortController();\n const gen = this._generation;\n const prev = this._tail;\n const jobToken = {};\n const activeJob: ActiveJob = {\n deviceId,\n label: options.label,\n abortController: ac,\n startedAt: Date.now(),\n };\n this._jobs.set(jobToken, { deviceId });\n\n const next = prev\n .catch(() => {})\n .then(async () => {\n if (this._generation !== gen) {\n throw (\n this._generationCancelReasons.get(gen) ?? new Error('Job cancelled: queue was cleared')\n );\n }\n this._active = activeJob;\n try {\n return await job(ac.signal);\n } finally {\n // Identity guard: a previous job's deferred finally must not\n // null out a successor's `_active`.\n if (this._active === activeJob) {\n this._active = null;\n }\n }\n })\n .finally(() => {\n this._jobs.delete(jobToken);\n });\n\n this._tail = next.catch(() => {});\n return next;\n }\n\n /** Cancel the active job. If `deviceId` is given, only cancels when it matches. */\n cancelActive(deviceId?: string): boolean {\n if (!this._active) return false;\n if (deviceId && this._active.deviceId !== deviceId) return false;\n this._active.abortController.abort(new Error('Manually cancelled'));\n return true;\n }\n\n /** Force cancel the active job. `reason` becomes signal.reason. */\n forceCancelActive(deviceId?: string, reason?: Error): boolean {\n if (!this._active) return false;\n if (deviceId && this._active.deviceId !== deviceId) return false;\n this._active.abortController.abort(reason ?? new Error('Force cancelled for recovery'));\n return true;\n }\n\n /** Cancel the active job (alias for callers that previously needed multi-device cancel). */\n cancelAllActive(reason?: Error): void {\n if (!this._active) return;\n this._active.abortController.abort(reason ?? new Error('Cancelled by cancelAllActive'));\n }\n\n /** Cancel the active job and invalidate queued jobs that have not started. */\n cancelActiveAndPending(deviceId?: string, reason?: Error): boolean {\n if (deviceId && this._active && this._active.deviceId !== deviceId) {\n return false;\n }\n this.clear(reason ?? new Error('Cancelled by cancelActiveAndPending'));\n return true;\n }\n\n /** Get info about the currently active job, or null if idle. */\n getActiveJob(deviceId?: string): ActiveJobInfo | null {\n if (!this._active) return null;\n if (deviceId && this._active.deviceId !== deviceId) return null;\n return {\n deviceId: this._active.deviceId,\n label: this._active.label,\n startedAt: this._active.startedAt,\n };\n }\n\n /** True if any job is currently running. */\n isBusy(): boolean {\n return this._jobs.size > 0;\n }\n\n clear(reason?: Error): void {\n const cancelledGeneration = this._generation;\n this._generation++;\n const cancelReason = reason ?? new Error('Job cancelled: queue was cleared');\n this._generationCancelReasons.set(cancelledGeneration, cancelReason);\n for (const generation of this._generationCancelReasons.keys()) {\n if (generation < this._generation - 10) {\n this._generationCancelReasons.delete(generation);\n }\n }\n if (this._active) {\n this._active.abortController.abort(cancelReason);\n }\n }\n}\n","import { HardwareErrorCode, createHwkError } from './errors';\n\nimport type { ConnectionType, DeviceCapabilities, DeviceInfo, VendorType } from './device';\nimport type { UiResponseEvent } from '../events/ui-request';\n\n// =====================================================================\n// Connector types — transport-level abstraction for device communication\n// =====================================================================\n\n/**\n * Minimal device info returned during discovery (searchDevices).\n * At scan time, full DeviceInfo fields like firmwareVersion are not yet available.\n */\nexport interface ConnectorDevice {\n connectId: string;\n deviceId: string;\n name: string;\n /**\n * Physical transport this device was discovered on. Mirrors Trezor\n * Connect's `descriptor.apiType` — when several transports are fused behind\n * one connector (see `createCombinedConnector`), the merged device list\n * carries this so the host can tell a USB entry from a BLE one and route\n * `connect()` back to the owning transport. Single-transport connectors may\n * leave it undefined.\n */\n connectionType?: ConnectionType;\n /** Machine model id (e.g. \"nanoX\"). */\n model?: string;\n /** Human-readable model name (e.g. \"Ledger Nano X\"). */\n modelName?: string;\n /** BLE signal strength (BLE only). */\n rssi?: number | null;\n /** BLE connectable flag (BLE only). */\n isConnectable?: boolean | null;\n /** USB serial number (USB only). */\n serialNumber?: string;\n\n /** Device capabilities — available from scan time */\n capabilities?: DeviceCapabilities;\n\n /**\n * Vendor-specific raw blob from the transport descriptor (USB / BLE).\n * Populated by `descriptorToConnectorDevice` in each connector. Treat as\n * informational; promote any field consumed by the app layer onto the\n * typed surface above.\n */\n raw?: Record<string, unknown>;\n}\n\nexport interface ConnectorSession {\n sessionId: string;\n deviceInfo: DeviceInfo;\n}\n\n// =====================================================================\n// Connector call result — device errors travel as DATA, not exceptions\n//\n// `IConnector.call` never throws for device-level failures. It resolves a\n// discriminated result so the failure crosses any process boundary\n// (IHardwareBridge / extension offscreen↔SW) as plain `data`. This mirrors\n// the OneKey HD-SDK `IDeviceResponseResult` contract.\n//\n// WHY: when a thrown Error crosses the extension JsBridge it is run through\n// `toPlainError`, a fixed field whitelist that drops custom own-properties\n// (e.g. `appName`). Returning the failure as data keeps every field intact.\n//\n// Contract for `ConnectorSerializedError`: only `message` / `code` /\n// `errorCode` live at the top level; ALL other domain fields (`appName`,\n// `_tag`, `statusCode`, …) are nested under `params`.\n// =====================================================================\n\n/**\n * Vendor-agnostic bag of extra error fields. Known keys are documented for\n * discoverability; the index signature keeps it open so any connector can\n * carry vendor-specific data without losing it across the bridge.\n */\nexport interface ConnectorErrorParams {\n /** Vendor SDK error tag (e.g. Ledger DMK `_tag`). */\n _tag?: string;\n /** App involved, e.g. the Ledger app being opened/installed. */\n appName?: string;\n /** Transport / APDU status code (string or number depending on vendor). */\n statusCode?: unknown;\n /**\n * Shallow snapshot of a nested cause. A raw Error does not survive JSON\n * serialization (its `message`/`stack` are non-enumerable), so recovery\n * predicates that recurse into a cause get this plain-object copy instead.\n */\n originalError?: {\n message?: string;\n code?: number;\n errorCode?: string;\n statusCode?: unknown;\n _tag?: string;\n };\n [key: string]: unknown;\n}\n\nexport interface ConnectorSerializedError {\n message: string;\n code?: number;\n errorCode?: string;\n params?: ConnectorErrorParams;\n}\n\nexport type ConnectorCallResult =\n | { success: true; payload: unknown }\n | { success: false; error: ConnectorSerializedError };\n\nexport type ConnectorEventType =\n | 'device-connect'\n | 'device-disconnect'\n | 'features'\n | 'device-trezor-thp-credentials-changed'\n | 'ui-request'\n | 'ui-event';\n\n/**\n * Interaction event types emitted via 'ui-event'.\n * These map to user-facing prompts (confirm on device, open app, etc.).\n */\nexport enum EConnectorInteraction {\n /** Adapter is actively searching for the device (no session yet) */\n Searching = 'searching',\n /** Device requires user to open a specific app */\n ConfirmOpenApp = 'confirm-open-app',\n /** Device requires user to unlock */\n UnlockDevice = 'unlock-device',\n /** Device needs user to confirm on device (sign, verify, etc.) */\n ConfirmOnDevice = 'confirm-on-device',\n /** Previous interaction completed — clear UI prompt */\n InteractionComplete = 'interaction-complete',\n /**\n * OS-level Ledger app install progress. `progress` is a 0..1 fraction\n * reported by DMK's InstallOrUpdateAppsDeviceAction. Emitted from inside\n * the connector so the progress callback ref never has to cross the\n * IHardwareBridge boundary.\n */\n AppInstallProgress = 'app-install-progress',\n}\n\n// Discriminated union: most variants only carry `sessionId`, but\n// AppInstallProgress also carries `appName` + `progress`. Searching has no\n// session yet so it carries an empty `sessionId`.\nexport type ConnectorUiEvent =\n | { type: EConnectorInteraction.Searching; payload: { sessionId: string } }\n | { type: EConnectorInteraction.ConfirmOpenApp; payload: { sessionId: string } }\n | { type: EConnectorInteraction.UnlockDevice; payload: { sessionId: string } }\n | { type: EConnectorInteraction.ConfirmOnDevice; payload: { sessionId: string } }\n | { type: EConnectorInteraction.InteractionComplete; payload: { sessionId: string } }\n | {\n type: EConnectorInteraction.AppInstallProgress;\n payload: { sessionId: string; appName: string; progress: number };\n };\n\nexport interface ConnectorEventMap {\n 'device-connect': { device: ConnectorDevice };\n 'device-disconnect': { connectId: string };\n features: { device: ConnectorDevice & { features: Record<string, unknown> } };\n 'device-trezor-thp-credentials-changed': {\n connectId: string;\n deviceId?: string;\n credentials: Record<string, unknown>[];\n };\n 'ui-request': { type: string; payload?: unknown };\n 'ui-event': ConnectorUiEvent;\n}\n\nexport interface ConnectorSearchDevicesOptions {\n /**\n * Wait for every child transport in a fused connector. Default discovery can\n * return shortly after USB appears so BLE does not slow down USB flows;\n * binding pickers can opt in when they need BLE candidates too.\n */\n waitForAll?: boolean;\n}\n\nexport interface IConnector {\n /** Physical connection type this connector uses. Fixed at construction. */\n readonly connectionType: ConnectionType;\n\n searchDevices(options?: ConnectorSearchDevicesOptions): Promise<ConnectorDevice[]>;\n connect(deviceId?: string): Promise<ConnectorSession>;\n disconnect(sessionId: string): Promise<void>;\n // `call` resolves a discriminated result; device-level failures are returned\n // as data, never thrown (see ConnectorCallResult). Only `call` uses this\n // contract because it is the one method that carries rich, vendor-specific\n // domain errors across the IHardwareBridge boundary, where a thrown Error\n // would be stripped by the host bridge's error whitelist. The other methods\n // surface plain operational failures and still reject normally.\n call(sessionId: string, method: string, params: unknown): Promise<ConnectorCallResult>;\n cancel(sessionId: string): Promise<void>;\n\n /** Send a UI response (e.g. PIN, passphrase) to the device. */\n uiResponse(response: UiResponseEvent): void;\n\n on<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;\n off<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;\n\n reset(): void;\n\n // Vendor-specific opt-in: warm-load persisted credentials before the first\n // session. Trezor uses this for THP `knownCredentials` (host-stored pairing\n // credentials replayed in `ThpHandshakeInitRequest` to skip the CodeEntry /\n // QrCode / NFC pairing UX on every connect). Vendors without persistent\n // credentials (Ledger, etc.) simply don't implement it.\n setKnownCredentials?(credentials: unknown[]): Promise<void> | void;\n}\n\n// =====================================================================\n// Hardware bridge — generic forwarding interface for cross-boundary IConnector\n//\n// The same shape works across any process / context boundary that needs to\n// expose a multi-vendor backend behind a single-vendor IConnector facade:\n// - Electron (renderer ↔ preload/main via contextBridge)\n// - Browser Extension (popup/content ↔ background/offscreen via chrome.runtime)\n// - React Native (JS ↔ native module via NativeModules)\n// - Web Worker / iframe (postMessage)\n//\n// Each method takes a `vendor` discriminator so a single bridge implementation\n// can multiplex across vendors (ledger, trezor, ...).\n// =====================================================================\n\nexport interface IHardwareBridge {\n searchDevices(params: {\n vendor: VendorType;\n options?: ConnectorSearchDevicesOptions;\n }): Promise<ConnectorDevice[]>;\n connect(params: { vendor: VendorType; deviceId?: string }): Promise<ConnectorSession>;\n disconnect(params: { vendor: VendorType; sessionId: string }): Promise<void>;\n call(params: {\n vendor: VendorType;\n sessionId: string;\n method: string;\n callParams: unknown;\n }): Promise<ConnectorCallResult>;\n cancel(params: { vendor: VendorType; sessionId: string }): Promise<void>;\n uiResponse(params: { vendor: VendorType; response: UiResponseEvent }): void;\n reset(params: { vendor: VendorType }): void;\n\n /** Register an event handler for connector events forwarded across the bridge. */\n onEvent(\n params: { vendor: VendorType },\n handler: (event: { type: ConnectorEventType; data: unknown }) => void\n ): void;\n\n /** Unregister a previously registered event handler. */\n offEvent(\n params: { vendor: VendorType },\n handler: (event: { type: ConnectorEventType; data: unknown }) => void\n ): void;\n\n /**\n * Warm-load vendor-specific persisted credentials. Currently only Trezor\n * uses this (THP `knownCredentials`); the bridge implementation can\n * dispatch on `vendor` and route to the right connector instance.\n */\n setKnownCredentials?(params: {\n vendor: VendorType;\n credentials: unknown[];\n }): Promise<void> | void;\n}\n\n/**\n * Adapt an IHardwareBridge (multi-vendor backend) into a single-vendor IConnector.\n * Every IConnector method becomes a transparent forward to bridge.<method>({ vendor, ... }).\n * Events are forwarded via bridge.onEvent / offEvent.\n *\n * Use this anywhere the actual hardware lives behind a process / context boundary\n * (Electron main, extension background, native module, worker, iframe).\n */\nexport function createBridgedConnector(\n vendor: VendorType,\n connectionType: ConnectionType,\n bridge: IHardwareBridge\n): IConnector {\n // Keyed by (event, handler). A flat handler-only map would collide when the\n // same function is registered for multiple events — second .on() would\n // overwrite the first bridge handler reference, leaking it permanently.\n type UserHandler = (data: ConnectorEventMap[ConnectorEventType]) => void;\n type BridgeHandler = (event: { type: ConnectorEventType; data: unknown }) => void;\n const handlerMap = new Map<ConnectorEventType, Map<UserHandler, BridgeHandler>>();\n\n return {\n connectionType,\n searchDevices: options => bridge.searchDevices({ vendor, options }),\n connect: deviceId => bridge.connect({ vendor, deviceId }),\n disconnect: sessionId => bridge.disconnect({ vendor, sessionId }),\n call: (sessionId, method, callParams) => bridge.call({ vendor, sessionId, method, callParams }),\n cancel: sessionId => bridge.cancel({ vendor, sessionId }),\n uiResponse: response => bridge.uiResponse({ vendor, response }),\n on: (event, handler) => {\n const bridgeHandler: BridgeHandler = e => {\n if (e.type === event) {\n handler(e.data as ConnectorEventMap[typeof event]);\n }\n };\n let inner = handlerMap.get(event);\n if (!inner) {\n inner = new Map();\n handlerMap.set(event, inner);\n }\n inner.set(handler as UserHandler, bridgeHandler);\n bridge.onEvent({ vendor }, bridgeHandler);\n },\n off: (event, handler) => {\n const inner = handlerMap.get(event);\n const bridgeHandler = inner?.get(handler as UserHandler);\n if (!bridgeHandler || !inner) return;\n bridge.offEvent({ vendor }, bridgeHandler);\n inner.delete(handler as UserHandler);\n if (inner.size === 0) handlerMap.delete(event);\n },\n reset: () => bridge.reset({ vendor }),\n setKnownCredentials: bridge.setKnownCredentials\n ? credentials => bridge.setKnownCredentials!({ vendor, credentials })\n : undefined,\n };\n}\n\n// =====================================================================\n// ConnectorCallResult error (de)serialization — the canonical, vendor-agnostic\n// helpers every IConnector implementation / adapter should use, so the\n// \"errors as data\" contract is identical across vendors.\n// =====================================================================\n\nconst SERIALIZED_ERROR_TOP_LEVEL_KEYS = new Set([\n 'message',\n 'code',\n 'errorCode',\n 'stack',\n 'params',\n]);\n\n/**\n * Flatten a thrown error into the cross-boundary-safe `ConnectorSerializedError`\n * shape. `message`/`code`/`errorCode` are lifted to the top level; every other\n * own-enumerable field is copied into `params` so NO domain data is lost when\n * the result crosses a host bridge (which may run thrown errors through a\n * field whitelist). A nested `originalError` is shallow-snapshotted because a\n * raw Error does not survive JSON serialization.\n */\nexport function serializeConnectorError(err: unknown): ConnectorSerializedError {\n if (!err || typeof err !== 'object') {\n return { message: typeof err === 'string' ? err : 'Unknown error' };\n }\n const e = err as Record<string, unknown>;\n const message = typeof e.message === 'string' ? e.message : 'Unknown error';\n const code = typeof e.code === 'number' ? e.code : undefined;\n const errorCode = e.errorCode != null ? String(e.errorCode) : undefined;\n\n const params: ConnectorErrorParams = {};\n // Flatten an existing `params` bag, then copy every other own field (so\n // vendor-specific keys like `_tag` / `statusCode` / `appName` / step context\n // are preserved without being named here).\n if (e.params && typeof e.params === 'object') {\n Object.assign(params, e.params as Record<string, unknown>);\n }\n for (const key of Object.keys(e)) {\n if (!SERIALIZED_ERROR_TOP_LEVEL_KEYS.has(key)) {\n params[key] = e[key];\n }\n }\n const orig = e.originalError;\n if (orig && typeof orig === 'object') {\n const o = orig as Record<string, unknown>;\n params.originalError = {\n message: typeof o.message === 'string' ? o.message : undefined,\n code: typeof o.code === 'number' ? o.code : undefined,\n errorCode: o.errorCode != null ? String(o.errorCode) : undefined,\n statusCode: o.statusCode,\n _tag: typeof o._tag === 'string' ? o._tag : undefined,\n };\n }\n\n // The result crosses host bridges via JSON.stringify. Drop any single field\n // that isn't JSON-safe (circular ref / non-serializable) so a pathological\n // error degrades to \"one field missing\" instead of crashing the transport.\n for (const key of Object.keys(params)) {\n try {\n JSON.stringify(params[key]);\n } catch {\n delete params[key];\n }\n }\n\n return {\n message,\n ...(code !== undefined ? { code } : {}),\n ...(errorCode !== undefined ? { errorCode } : {}),\n ...(Object.keys(params).length ? { params } : {}),\n };\n}\n\n/**\n * Inverse of `serializeConnectorError`: rebuild a flat Error instance, lifting\n * `params.*` back to own-properties so existing throw-based classifiers/recovery\n * logic (which read `err._tag` / `err.code` / `err.appName` / …) keep working\n * unchanged. The Result shape stays confined to the connector boundary.\n */\nexport function rehydrateConnectorError(error: ConnectorSerializedError): Error {\n const { message, code, errorCode, params } = error;\n return Object.assign(new Error(message), {\n ...(code !== undefined ? { code } : {}),\n ...(errorCode !== undefined ? { errorCode } : {}),\n ...(params ?? {}),\n });\n}\n\n/**\n * Fuse several single-transport IConnectors (e.g. WebUSB + BLE for one\n * vendor) into one IConnector whose device list is the union of all of them.\n *\n * This mirrors how Trezor Connect's `DeviceList` keeps one `TransportManager`\n * per `apiType` running concurrently and merges their devices into a single\n * list: there is no \"switch\" between transports — both are always live, and\n * each discovered device carries its `connectionType` so the host knows which\n * channel it came in on. `connect()` routes back to the transport that owns\n * the chosen device; later calls route by `sessionId`.\n *\n * Notes / current limitations:\n * - `searchDevices()` fans out concurrently; a transport that throws while\n * scanning is treated as \"no devices\" so a dead/absent channel never sinks\n * the others.\n * - USB entries sort ahead of BLE ones (Trezor's `getPrioritizedDevices`).\n * - The same physical device reachable on two transports surfaces as two\n * entries with different `connectId`s — we do NOT dedup, so the host can\n * present (or pick) a channel explicitly.\n * - `uiResponse()` carries no sessionId, so it is broadcast to every child;\n * a child with no matching pending request ignores it.\n */\nfunction isDeviceUnavailableError(error: unknown): boolean {\n const typed = error as { code?: unknown };\n if (\n typed.code === HardwareErrorCode.DeviceNotFound ||\n typed.code === HardwareErrorCode.DeviceDisconnected\n ) {\n return true;\n }\n return false;\n}\n\nfunction combinedDeviceNotFoundError(message: string): Error {\n return createHwkError({\n code: HardwareErrorCode.DeviceNotFound,\n message,\n });\n}\n\nfunction combinedSessionNotFoundError(message: string): Error {\n return createHwkError({\n code: HardwareErrorCode.DeviceDisconnected,\n message,\n });\n}\n\nexport function createCombinedConnector(connectors: IConnector[]): IConnector {\n if (connectors.length === 0) {\n throw new Error('createCombinedConnector: at least one connector is required');\n }\n const SEARCH_SETTLE_AFTER_FIRST_DEVICE_MS = 250;\n\n // connectId -> the child connector that discovered it (set on searchDevices).\n const deviceOwner = new Map<string, IConnector>();\n // sessionId -> the child connector that owns the live session.\n const sessionOwner = new Map<string, IConnector>();\n // userHandler -> the per-child forwarders we attached, so off() can detach.\n type UserHandler = (data: ConnectorEventMap[ConnectorEventType]) => void;\n const forwarders = new Map<\n ConnectorEventType,\n Map<UserHandler, Array<{ child: IConnector; handler: UserHandler }>>\n >();\n\n // BLE ranks after USB — matches Trezor's getPrioritizedDevices().\n const rank = (device: ConnectorDevice): number => (device.connectionType === 'ble' ? 1 : 0);\n\n // Shared THP pairing credentials across all child transports. A credential is\n // keyed by the device's static public key (transport-agnostic, see\n // `findKnownPairingCredentials`), so a credential minted while pairing over\n // one transport (e.g. USB) must reach the sibling transports (e.g. BLE) or\n // they re-pair instead of autoconnecting. Each child keeps its OWN\n // knownCredentials array, so we maintain the union here and re-broadcast it to\n // every child whenever any child mints a fresh one.\n const sharedCredentials: Array<Record<string, unknown>> = [];\n const credentialKey = (c: Record<string, unknown>): string =>\n (c.credential as string) ?? JSON.stringify(c);\n const mergeShared = (incoming: ReadonlyArray<Record<string, unknown>>): boolean => {\n let changed = false;\n for (const cred of incoming) {\n const key = credentialKey(cred);\n if (!sharedCredentials.some(e => credentialKey(e) === key)) {\n sharedCredentials.push(cred);\n changed = true;\n }\n }\n return changed;\n };\n const broadcastCredentials = async (): Promise<void> => {\n await Promise.all(\n connectors.map(child => Promise.resolve(child.setKnownCredentials?.(sharedCredentials)))\n );\n };\n\n // Internal subscription (independent of user on()/off()): when any child mints\n // fresh pairing credentials, fold them into the shared union and push the\n // union down to every child so the next handshake on ANY transport\n // autoconnects rather than re-pairing.\n for (const child of connectors) {\n child.on('device-trezor-thp-credentials-changed', data => {\n if (mergeShared(data.credentials)) void broadcastCredentials();\n });\n }\n\n const searchDevices = async (\n options: { waitForAll?: boolean } = {}\n ): Promise<ConnectorDevice[]> => {\n const perConnector: Array<{\n index: number;\n devices: ConnectorDevice[];\n }> = [];\n\n await new Promise<void>(resolve => {\n let finished = false;\n let remaining = connectors.length;\n let settleTimer: ReturnType<typeof setTimeout> | undefined;\n\n const finish = () => {\n if (finished) return;\n finished = true;\n if (settleTimer) clearTimeout(settleTimer);\n resolve();\n };\n\n connectors.forEach((child, index) => {\n void child\n .searchDevices()\n .then(devices =>\n devices.map(device => ({\n ...device,\n connectionType: device.connectionType ?? child.connectionType,\n }))\n )\n .catch(\n () =>\n // A transport that can't scan (powered off, unauthorized, absent)\n // must not fail the whole fused search.\n [] as ConnectorDevice[]\n )\n .then(devices => {\n remaining -= 1;\n if (!finished) {\n perConnector.push({ index, devices });\n }\n if (remaining === 0) {\n finish();\n return;\n }\n const hasUsbDevice = devices.some(device => device.connectionType === 'usb');\n if (hasUsbDevice && !settleTimer && !options.waitForAll) {\n settleTimer = setTimeout(finish, SEARCH_SETTLE_AFTER_FIRST_DEVICE_MS);\n }\n });\n });\n });\n\n perConnector.sort((a, b) => a.index - b.index);\n\n deviceOwner.clear();\n const merged: ConnectorDevice[] = [];\n perConnector.forEach(({ index, devices }) => {\n for (const device of devices) {\n deviceOwner.set(device.connectId, connectors[index]);\n merged.push(device);\n }\n });\n return merged.sort((a, b) => rank(a) - rank(b));\n };\n\n const resolveOwner = async (\n deviceId?: string\n ): Promise<{ owner: IConnector; deviceId?: string }> => {\n if (deviceId && deviceOwner.has(deviceId)) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { owner: deviceOwner.get(deviceId)!, deviceId };\n }\n const devices = await searchDevices({ waitForAll: Boolean(deviceId) });\n if (deviceId) {\n const owner = deviceOwner.get(deviceId);\n if (!owner)\n throw combinedDeviceNotFoundError(`Combined connector: device not found: ${deviceId}`);\n return { owner, deviceId };\n }\n const first = devices[0];\n if (!first) throw combinedDeviceNotFoundError('Combined connector: no devices found');\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { owner: deviceOwner.get(first.connectId)!, deviceId: first.connectId };\n };\n\n const connectByExplicitId = async (\n deviceId: string\n ): Promise<{ session: ConnectorSession; owner: IConnector }> => {\n const cachedOwner = deviceOwner.get(deviceId);\n if (cachedOwner) {\n return { session: await cachedOwner.connect(deviceId), owner: cachedOwner };\n }\n\n let lastError: unknown;\n for (const child of connectors) {\n try {\n const session = await child.connect(deviceId);\n deviceOwner.set(deviceId, child);\n return { session, owner: child };\n } catch (error) {\n if (!isDeviceUnavailableError(error)) {\n throw error;\n }\n lastError = error;\n }\n }\n const message =\n lastError instanceof Error\n ? lastError.message\n : `Combined connector: device not found: ${deviceId}`;\n throw createHwkError({\n code: HardwareErrorCode.DeviceNotFound,\n message,\n });\n };\n\n return {\n // Nominal value only — the per-device `connectionType` is authoritative\n // for a fused connector.\n connectionType: connectors[0].connectionType,\n\n searchDevices: options => searchDevices({ waitForAll: options?.waitForAll }),\n\n connect: async deviceId => {\n let owner: IConnector;\n let session: ConnectorSession;\n if (deviceId) {\n ({ session, owner } = await connectByExplicitId(deviceId));\n } else {\n const resolved = await resolveOwner();\n owner = resolved.owner;\n session = await owner.connect(resolved.deviceId);\n }\n // Use the owner resolved during connect — re-deriving via\n // session.deviceInfo.connectId breaks for ephemeral-id transports (the id\n // can change on connect → missed lookup → orphaned session).\n sessionOwner.set(session.sessionId, owner);\n return session;\n },\n\n disconnect: async sessionId => {\n const owner = sessionOwner.get(sessionId);\n if (!owner) return;\n await owner.disconnect(sessionId);\n sessionOwner.delete(sessionId);\n },\n\n call: async (sessionId, method, params) => {\n const owner = sessionOwner.get(sessionId);\n if (!owner) {\n throw combinedSessionNotFoundError(`Combined connector: session not found: ${sessionId}`);\n }\n return owner.call(sessionId, method, params);\n },\n\n cancel: async sessionId => {\n const owner = sessionOwner.get(sessionId);\n if (!owner) return;\n await owner.cancel(sessionId);\n },\n\n uiResponse: response => {\n // No sessionId on the response — broadcast; children without a matching\n // pending request ignore it.\n for (const child of connectors) child.uiResponse(response);\n },\n\n on: (event, handler) => {\n const attached = connectors.map(child => {\n const forward: UserHandler = data => (handler as UserHandler)(data);\n child.on(event, forward as Parameters<IConnector['on']>[1]);\n return { child, handler: forward };\n });\n let inner = forwarders.get(event);\n if (!inner) {\n inner = new Map();\n forwarders.set(event, inner);\n }\n inner.set(handler as UserHandler, attached);\n },\n\n off: (event, handler) => {\n const inner = forwarders.get(event);\n const attached = inner?.get(handler as UserHandler);\n if (!attached || !inner) return;\n for (const { child, handler: forward } of attached) {\n child.off(event, forward as Parameters<IConnector['off']>[1]);\n }\n inner.delete(handler as UserHandler);\n if (inner.size === 0) forwarders.delete(event);\n },\n\n reset: () => {\n for (const child of connectors) child.reset();\n deviceOwner.clear();\n sessionOwner.clear();\n forwarders.clear();\n },\n\n setKnownCredentials: connectors.some(c => c.setKnownCredentials)\n ? async credentials => {\n // Seed the shared union from the host (warm-load) and fan out to all\n // children so every transport starts from the same credential set.\n sharedCredentials.length = 0;\n mergeShared((credentials ?? []) as Array<Record<string, unknown>>);\n await broadcastCredentials();\n }\n : undefined,\n };\n}\n","/**\n * Minimal typed event emitter using Map<string, Set<listener>>.\n * Each adapter uses this for device events (connect, disconnect, pin, etc.).\n *\n * TMap is a record mapping event name strings to their payload types.\n * Example:\n * type MyEvents = { 'connect': { id: string }; 'disconnect': { id: string } };\n * const emitter = new TypedEventEmitter<MyEvents>();\n * emitter.on('connect', (data) => { data.id }); // data is { id: string }\n *\n * For backward compatibility, TMap defaults to Record<string, any> so that\n * existing code using `new TypedEventEmitter<SomeUnionType>()` still compiles.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class TypedEventEmitter<TMap extends Record<string, any> = Record<string, any>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly _listeners = new Map<string, Set<(event: any) => void>>();\n\n on<K extends keyof TMap & string>(event: K, listener: (event: TMap[K]) => void): void;\n\n on(event: string, listener: (event: any) => void): void;\n\n on(event: string, listener: (event: any) => void): void {\n let set = this._listeners.get(event);\n if (!set) {\n set = new Set();\n this._listeners.set(event, set);\n }\n set.add(listener);\n }\n\n off<K extends keyof TMap & string>(event: K, listener: (event: TMap[K]) => void): void;\n\n off(event: string, listener: (event: any) => void): void;\n\n off(event: string, listener: (event: any) => void): void {\n const set = this._listeners.get(event);\n if (set) {\n set.delete(listener);\n if (set.size === 0) this._listeners.delete(event);\n }\n }\n\n emit<K extends keyof TMap & string>(event: K, data: TMap[K]): void;\n\n emit(event: string, data: unknown): void;\n\n emit(event: string, data: unknown): void {\n const set = this._listeners.get(event);\n if (set) {\n for (const listener of set) listener(data);\n }\n }\n\n removeAllListeners(): void {\n this._listeners.clear();\n }\n\n /** Number of listeners registered for `event`. 0 if none. */\n listenerCount(event: string): number {\n return this._listeners.get(event)?.size ?? 0;\n }\n}\n","/**\n * Compare two semver strings (e.g. \"2.1.0\" vs \"2.3.1\").\n * Returns -1 if a < b, 0 if equal, 1 if a > b.\n */\nexport function compareSemver(a: string, b: string): number {\n const pa = a.split('.').map(Number);\n const pb = b.split('.').map(Number);\n for (let i = 0; i < 3; i++) {\n const va = pa[i] ?? 0;\n const vb = pb[i] ?? 0;\n if (va < vb) return -1;\n if (va > vb) return 1;\n }\n return 0;\n}\n","import { bytesToHex as nobleBytesToHex, hexToBytes as nobleHexToBytes } from '@noble/hashes/utils';\n\n/** Ensure hex string has 0x prefix */\nexport function ensure0x(hex: string): string {\n return hex.startsWith('0x') ? hex : `0x${hex}`;\n}\n\n/** Strip 0x prefix from hex string */\nexport function stripHex(hex: string): string {\n return hex.startsWith('0x') ? hex.slice(2) : hex;\n}\n\n/** Pad hex to 64 chars (32 bytes) with 0x prefix */\nexport function padHex64(hex: string): string {\n return `0x${stripHex(hex).padStart(64, '0')}`;\n}\n\n/**\n * Convert a hex string (with or without 0x prefix) to a Uint8Array.\n * Throws on invalid hex (non-hex characters, odd length).\n */\nexport function hexToBytes(hex: string): Uint8Array {\n return nobleHexToBytes(stripHex(hex));\n}\n\n/** Convert a Uint8Array to a hex string (no 0x prefix). */\nexport function bytesToHex(bytes: Uint8Array): string {\n return nobleBytesToHex(bytes);\n}\n","export type DetectableHardwareVendor = 'onekey' | 'trezor' | 'ledger';\n\nexport type HardwareDeviceIdentityInput = {\n name?: string | null;\n localName?: string | null;\n bleName?: string | null;\n model?: string | null;\n modelName?: string | null;\n type?: string | null;\n productName?: string | null;\n manufacturerName?: string | null;\n vendor?: number | string | null;\n vendorId?: number | null;\n product?: number | string | null;\n productId?: number | null;\n label?: string | null;\n fw_vendor?: string | null;\n internal_model?: string | null;\n onekey_version?: string | null;\n onekey_device_type?: string | null;\n onekey_serial?: string | null;\n serviceUUIDs?: string[] | null;\n advertisedServiceUuids?: string[] | null;\n serviceUuids?: string[] | null;\n};\n\nconst ONEKEY_BLE_SERVICE_UUID = '00000001-0000-1000-8000-00805f9b34fb';\nconst TREZOR_BLE_SERVICE_UUID = '8c000001-a59b-4d58-a9ad-073df69fa1b1';\nconst LEDGER_USB_VENDOR_ID = 0x2c97;\n\nconst lower = (value?: string | null): string => value?.trim().toLowerCase() ?? '';\n\nconst hasServiceUuid = (input: HardwareDeviceIdentityInput, uuid: string): boolean => {\n const expected = uuid.toLowerCase();\n const values = [\n ...(input.serviceUUIDs ?? []),\n ...(input.advertisedServiceUuids ?? []),\n ...(input.serviceUuids ?? []),\n ];\n return values.some(value => value.toLowerCase() === expected);\n};\n\nexport function detectHardwareVendorFromDescriptor(\n input: HardwareDeviceIdentityInput\n): DetectableHardwareVendor | undefined {\n const manufacturerName = lower(input.manufacturerName);\n const fwVendor = lower(input.fw_vendor);\n\n if (\n hasServiceUuid(input, ONEKEY_BLE_SERVICE_UUID) ||\n manufacturerName.includes('onekey') ||\n fwVendor === 'onekey' ||\n input.onekey_version ||\n input.onekey_device_type ||\n input.onekey_serial\n ) {\n return 'onekey';\n }\n if (\n hasServiceUuid(input, TREZOR_BLE_SERVICE_UUID) ||\n manufacturerName.includes('trezor') ||\n fwVendor === 'trezor'\n ) {\n return 'trezor';\n }\n if (\n (typeof input.vendor === 'number' && input.vendor === LEDGER_USB_VENDOR_ID) ||\n input.vendorId === LEDGER_USB_VENDOR_ID ||\n manufacturerName.includes('ledger')\n ) {\n return 'ledger';\n }\n return undefined;\n}\n\nexport function isKnownNonTargetHardwareVendor(\n input: HardwareDeviceIdentityInput,\n targetVendor: DetectableHardwareVendor\n): boolean {\n const detectedVendor = detectHardwareVendorFromDescriptor(input);\n return detectedVendor !== undefined && detectedVendor !== targetVendor;\n}\n","import type { Response } from '../types/response';\n\n/**\n * Generic batch call with progress reporting.\n * If any single call fails, returns the failure immediately.\n */\nexport async function batchCall<TParam, TResult>(\n params: TParam[],\n callFn: (p: TParam) => Promise<Response<TResult>>,\n onProgress?: (progress: { index: number; total: number }) => void\n): Promise<Response<TResult[]>> {\n const results: TResult[] = [];\n for (let i = 0; i < params.length; i++) {\n const result = await callFn(params[i]);\n if (!result.success) {\n return result;\n }\n results.push(result.payload);\n onProgress?.({ index: i, total: params.length });\n }\n return { success: true, payload: results };\n}\n","import type { ChainForFingerprint } from '../types/fingerprint';\n\nexport type HardwareMethodMetadata = {\n chain: ChainForFingerprint;\n allNetwork: boolean;\n};\n\nexport const HARDWARE_METHOD_CATALOG = {\n evmGetAddress: { chain: 'evm', allNetwork: true },\n evmSignTransaction: { chain: 'evm', allNetwork: false },\n evmSignMessage: { chain: 'evm', allNetwork: false },\n evmSignTypedData: { chain: 'evm', allNetwork: false },\n btcGetAddress: { chain: 'btc', allNetwork: true },\n btcGetPublicKey: { chain: 'btc', allNetwork: true },\n btcSignTransaction: { chain: 'btc', allNetwork: false },\n btcSignPsbt: { chain: 'btc', allNetwork: false },\n btcSignMessage: { chain: 'btc', allNetwork: false },\n btcGetMasterFingerprint: { chain: 'btc', allNetwork: false },\n solGetAddress: { chain: 'sol', allNetwork: true },\n solSignTransaction: { chain: 'sol', allNetwork: false },\n solSignMessage: { chain: 'sol', allNetwork: false },\n tronGetAddress: { chain: 'tron', allNetwork: true },\n tronSignTransaction: { chain: 'tron', allNetwork: false },\n tronSignMessage: { chain: 'tron', allNetwork: false },\n} as const satisfies Record<string, HardwareMethodMetadata>;\n\nexport type HardwareMethodName = keyof typeof HARDWARE_METHOD_CATALOG;\n\nexport type AllNetworkMethodName = {\n [K in HardwareMethodName]: (typeof HARDWARE_METHOD_CATALOG)[K]['allNetwork'] extends true\n ? K\n : never;\n}[HardwareMethodName];\n\nexport const ALL_NETWORK_METHOD_NAMES = Object.entries(HARDWARE_METHOD_CATALOG)\n .filter(([, metadata]) => metadata.allNetwork)\n .map(([method]) => method) as AllNetworkMethodName[];\n\nconst ALL_NETWORK_METHOD_SET = new Set<string>(ALL_NETWORK_METHOD_NAMES);\n\nexport function getHardwareMethodMetadata(method: string): HardwareMethodMetadata | undefined {\n return HARDWARE_METHOD_CATALOG[method as HardwareMethodName];\n}\n\nexport function isAllNetworkMethodName(method: string): method is AllNetworkMethodName {\n return ALL_NETWORK_METHOD_SET.has(method);\n}\n\nexport function getAllNetworkMethodChain(method: AllNetworkMethodName): ChainForFingerprint {\n return HARDWARE_METHOD_CATALOG[method].chain;\n}\n","import { HardwareErrorCode } from '../types/errors';\nimport { failure, success } from '../types/response';\nimport { getAllNetworkMethodChain, isAllNetworkMethodName } from './methodCatalog';\n\nimport type { ChainForFingerprint } from '../types/fingerprint';\nimport type { Response } from '../types/response';\nimport type {\n AllNetworkAddressParams,\n AllNetworkAddressResponse,\n AllNetworkGetAddressParams,\n} from '../types/wallet';\nimport type { AllNetworkMethodName } from './methodCatalog';\n\nexport type AllNetworkCallItemContext = {\n connectId: string;\n deviceId: string;\n method: AllNetworkMethodName;\n chain: ChainForFingerprint;\n item: AllNetworkAddressParams;\n index: number;\n};\n\nexport type AllNetworkAttachIdentityContext = AllNetworkCallItemContext & {\n payload: Record<string, unknown>;\n};\n\nexport type AllNetworkResponseContext = AllNetworkCallItemContext & {\n response: AllNetworkAddressResponse;\n};\n\nexport type RunAllNetworkGetAddressOptions = {\n connectId: string;\n deviceId: string;\n params: AllNetworkGetAddressParams;\n getMethodChain?: (\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ) => ChainForFingerprint;\n normalizeItem?: (\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ) => AllNetworkAddressParams;\n buildUnsupportedNetworkResponse?: (\n item: AllNetworkAddressParams,\n method: AllNetworkMethodName\n ) => AllNetworkAddressResponse | undefined;\n callItem: (context: AllNetworkCallItemContext) => Promise<Response<unknown>>;\n attachIdentity: (context: AllNetworkAttachIdentityContext) => Promise<AllNetworkAddressResponse>;\n shouldAbortBundle?: (\n response: AllNetworkAddressResponse,\n context: AllNetworkResponseContext\n ) => boolean;\n buildTopLevelFailure?: (\n response: AllNetworkAddressResponse,\n context: AllNetworkResponseContext\n ) => Response<AllNetworkAddressResponse[]>;\n};\n\nexport async function runAllNetworkGetAddress({\n connectId,\n deviceId,\n params,\n getMethodChain = method => getAllNetworkMethodChain(method),\n normalizeItem = (_method, item) => item,\n buildUnsupportedNetworkResponse,\n callItem,\n attachIdentity,\n shouldAbortBundle = () => false,\n buildTopLevelFailure = defaultBuildTopLevelFailure,\n}: RunAllNetworkGetAddressOptions): Promise<Response<AllNetworkAddressResponse[]>> {\n const responses: AllNetworkAddressResponse[] = [];\n\n for (const [index, item] of params.bundle.entries()) {\n if (!isAllNetworkMethodName(String(item.methodName))) {\n responses.push(buildUnsupportedMethodResponse(item));\n continue;\n }\n\n const method = item.methodName;\n const unsupportedNetwork = buildUnsupportedNetworkResponse?.(item, method);\n if (unsupportedNetwork) {\n responses.push(unsupportedNetwork);\n continue;\n }\n\n const chain = getMethodChain(method, item);\n const normalizedItem = normalizeItem(method, item);\n const context: AllNetworkCallItemContext = {\n connectId,\n deviceId,\n method,\n chain,\n item: normalizedItem,\n index,\n };\n const response = await callItem(context);\n const itemResponse = response.success\n ? await attachIdentity({\n ...context,\n payload: response.payload as Record<string, unknown>,\n })\n : ({\n ...normalizedItem,\n success: false,\n payload: response.payload,\n } as AllNetworkAddressResponse);\n\n const responseContext = { ...context, response: itemResponse };\n if (!itemResponse.success && shouldAbortBundle(itemResponse, responseContext)) {\n return buildTopLevelFailure(itemResponse, responseContext);\n }\n responses.push(itemResponse);\n }\n\n return success(responses);\n}\n\nexport function buildUnsupportedMethodResponse(\n item: AllNetworkAddressParams\n): AllNetworkAddressResponse {\n return {\n ...item,\n success: false,\n payload: {\n code: HardwareErrorCode.InvalidParams,\n error: `Unsupported allNetwork method: ${String(item.methodName)}`,\n },\n };\n}\n\nfunction defaultBuildTopLevelFailure(\n response: AllNetworkAddressResponse\n): Response<AllNetworkAddressResponse[]> {\n const payload = response.payload ?? {};\n return failure(\n (payload.code as HardwareErrorCode | undefined) ?? HardwareErrorCode.DeviceMismatch,\n payload.error ?? 'All-network get-address aborted',\n normalizeFailureParams(payload.params)\n );\n}\n\nfunction normalizeFailureParams(params: unknown): Record<string, unknown> | undefined {\n return params && typeof params === 'object' ? (params as Record<string, unknown>) : undefined;\n}\n","export const DEVICE_CONNECT_RETRY_DELAY_MS = 1000;\n"],"mappings":"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","names":["EConnectorInteraction","bytesToHex"]}
1
+ {"version":3,"sources":["../src/types/response.ts","../src/types/fingerprint.ts","../src/events/device.ts","../src/events/sdk.ts","../src/utils/DeviceJobQueue.ts","../src/types/connector.ts","../src/utils/TypedEventEmitter.ts","../src/utils/semver.ts","../src/utils/hex.ts","../src/utils/deviceIdentity.ts","../src/utils/batchCall.ts","../src/utils/methodCatalog.ts","../src/utils/allNetwork.ts","../src/constants.ts"],"sourcesContent":["import type { HardwareErrorCode } from './errors';\n\nexport interface Success<T> {\n success: true;\n payload: T;\n}\n\nexport interface Failure {\n success: false;\n payload: {\n error: string;\n code: HardwareErrorCode;\n params?: Record<string, unknown>;\n };\n}\n\nexport type Response<T> = Success<T> | Failure;\n\nexport function success<T>(payload: T): Success<T> {\n return { success: true, payload };\n}\n\nexport function failure(\n code: HardwareErrorCode,\n error: string,\n params?: Record<string, unknown>\n): Failure {\n return {\n success: false,\n payload: { error, code, ...(params ? { params } : {}) },\n };\n}\n","/**\n * Chain fingerprint utilities for device identity verification.\n *\n * Ledger devices have ephemeral IDs that change every session.\n * To verify that the same seed/device is connected, we derive an address\n * at a fixed path (account 0, index 0) and hash it into a stable \"chain fingerprint\".\n */\nimport { sha256 } from '@noble/hashes/sha256';\nimport { bytesToHex, utf8ToBytes } from '@noble/hashes/utils';\n\n/**\n * Fixed derivation paths used to generate chain fingerprints.\n * Uses standard index 0 — Ledger firmware shows device confirmation for\n * non-standard paths (e.g., index=100), which would interrupt wallet creation.\n * The address is hashed into a 16-char fingerprint, not exposed directly.\n * - EVM: cointype 60 (Ledger ETH App only supports 60)\n * - BTC: cointype 1 (testnet)\n * - SOL: cointype 501, standard 3-level hardened\n */\nexport const CHAIN_FINGERPRINT_PATHS: Record<ChainForFingerprint, string> = {\n evm: \"m/44'/60'/0'/0/0\",\n // BTC: account-level path (3 levels), mainnet cointype 0.\n // Cointype 1 (testnet) is rejected by some Ledger BTC App configurations.\n btc: \"m/44'/0'/0'\",\n sol: \"m/44'/501'/0'\",\n tron: \"m/44'/195'/0'/0/0\",\n};\n\nexport type ChainForFingerprint = 'evm' | 'btc' | 'sol' | 'tron';\n\n/**\n * 16-char SHA-256 fingerprint for device-identity verification.\n * Callers must canonicalize input (e.g. EVM address → lowercase) —\n * encoding variations otherwise cause false DeviceMismatch.\n */\nexport function deriveDeviceFingerprint(value: string): string {\n return bytesToHex(sha256(utf8ToBytes(value))).slice(0, 16);\n}\n","export const DEVICE_EVENT = 'DEVICE_EVENT';\n\n/** Events originating from the hardware device. */\nexport const DEVICE = {\n CONNECT: 'device-connect',\n DISCONNECT: 'device-disconnect',\n CHANGED: 'device-changed',\n FEATURES: 'features',\n /**\n * Trezor-only. Emitted after a successful THP handshake that minted or\n * refreshed pairing credentials. The host should persist `credentials`\n * keyed by `deviceId` and feed them back into the connector on the next\n * connect to skip the CodeEntry/QrCode/NFC pairing UX.\n *\n * The `TREZOR_` prefix mirrors `UI_REQUEST.REQUEST_TREZOR_THP_PAIRING` —\n * vendor-specific events live in the shared event taxonomy but are named\n * so hosts can ignore them when they don't drive Trezor hardware.\n */\n TREZOR_THP_CREDENTIALS_CHANGED: 'device-trezor-thp-credentials-changed',\n} as const;\n","/** Events generated by SDK internal detection (not from hardware directly). */\nexport const SDK = {\n DEVICE_STUCK: 'device-stuck',\n DEVICE_UNRESPONSIVE: 'device-unresponsive',\n DEVICE_RECOVERED: 'device-recovered',\n DEVICE_INTERACTION: 'device-interaction',\n} as const;\n","/**\n * Pure FIFO job queue. Every enqueue chains onto the tail; jobs run one at\n * a time across all devices. The queue is intentionally passive — it does\n * NOT decide whether to interrupt or ask the user. Those are application-\n * layer concerns owned by the caller (e.g. a UI button handler that wants\n * to ask \"device is busy, interrupt current?\" before submitting). The\n * queue exposes inspection (`getActiveJob`) and explicit cancellation\n * (`cancelActive` / `cancelAll`) so callers can implement those policies\n * synchronously, without racing against in-flight enqueues.\n */\n\nexport interface JobOptions {\n label?: string;\n rejectIfBusy?: boolean;\n busyError?: Error;\n}\n\nexport interface ActiveJobInfo {\n deviceId: string;\n label?: string;\n startedAt: number;\n}\n\ninterface ActiveJob {\n deviceId: string;\n label?: string;\n abortController: AbortController;\n startedAt: number;\n}\n\nexport class DeviceJobQueue {\n private _tail: Promise<unknown> = Promise.resolve();\n\n private _active: ActiveJob | null = null;\n\n private readonly _jobs = new Map<object, { deviceId: string }>();\n\n /** Incremented on clear() so queued-but-not-yet-running jobs detect invalidation. */\n private _generation = 0;\n\n private readonly _generationCancelReasons = new Map<number, Error>();\n\n /**\n * Enqueue a job. Runs after every previously-enqueued job has settled.\n * `deviceId` is a label only — used by inspection / cancellation routing.\n */\n async enqueue<T>(\n deviceId: string,\n job: (signal: AbortSignal) => Promise<T>,\n options: JobOptions = {}\n ): Promise<T> {\n if (options.rejectIfBusy && this._jobs.size > 0) {\n throw options.busyError ?? new Error('Device is busy');\n }\n\n const ac = new AbortController();\n const gen = this._generation;\n const prev = this._tail;\n const jobToken = {};\n const activeJob: ActiveJob = {\n deviceId,\n label: options.label,\n abortController: ac,\n startedAt: Date.now(),\n };\n this._jobs.set(jobToken, { deviceId });\n\n const next = prev\n .catch(() => {})\n .then(async () => {\n if (this._generation !== gen) {\n throw (\n this._generationCancelReasons.get(gen) ?? new Error('Job cancelled: queue was cleared')\n );\n }\n this._active = activeJob;\n try {\n return await job(ac.signal);\n } finally {\n // Identity guard: a previous job's deferred finally must not\n // null out a successor's `_active`.\n if (this._active === activeJob) {\n this._active = null;\n }\n }\n })\n .finally(() => {\n this._jobs.delete(jobToken);\n });\n\n this._tail = next.catch(() => {});\n return next;\n }\n\n /** Cancel the active job. If `deviceId` is given, only cancels when it matches. */\n cancelActive(deviceId?: string): boolean {\n if (!this._active) return false;\n if (deviceId && this._active.deviceId !== deviceId) return false;\n this._active.abortController.abort(new Error('Manually cancelled'));\n return true;\n }\n\n /** Force cancel the active job. `reason` becomes signal.reason. */\n forceCancelActive(deviceId?: string, reason?: Error): boolean {\n if (!this._active) return false;\n if (deviceId && this._active.deviceId !== deviceId) return false;\n this._active.abortController.abort(reason ?? new Error('Force cancelled for recovery'));\n return true;\n }\n\n /** Cancel the active job (alias for callers that previously needed multi-device cancel). */\n cancelAllActive(reason?: Error): void {\n if (!this._active) return;\n this._active.abortController.abort(reason ?? new Error('Cancelled by cancelAllActive'));\n }\n\n /** Cancel the active job and invalidate queued jobs that have not started. */\n cancelActiveAndPending(deviceId?: string, reason?: Error): boolean {\n if (deviceId && this._active && this._active.deviceId !== deviceId) {\n return false;\n }\n this.clear(reason ?? new Error('Cancelled by cancelActiveAndPending'));\n return true;\n }\n\n /** Get info about the currently active job, or null if idle. */\n getActiveJob(deviceId?: string): ActiveJobInfo | null {\n if (!this._active) return null;\n if (deviceId && this._active.deviceId !== deviceId) return null;\n return {\n deviceId: this._active.deviceId,\n label: this._active.label,\n startedAt: this._active.startedAt,\n };\n }\n\n /** True if any job is currently running. */\n isBusy(): boolean {\n return this._jobs.size > 0;\n }\n\n clear(reason?: Error): void {\n const cancelledGeneration = this._generation;\n this._generation++;\n const cancelReason = reason ?? new Error('Job cancelled: queue was cleared');\n this._generationCancelReasons.set(cancelledGeneration, cancelReason);\n for (const generation of this._generationCancelReasons.keys()) {\n if (generation < this._generation - 10) {\n this._generationCancelReasons.delete(generation);\n }\n }\n if (this._active) {\n this._active.abortController.abort(cancelReason);\n }\n }\n}\n","import { HardwareErrorCode, createHwkError } from './errors';\n\nimport type { ConnectionType, DeviceCapabilities, DeviceInfo, VendorType } from './device';\nimport type { UiResponseEvent } from '../events/ui-request';\n\n// =====================================================================\n// Connector types — transport-level abstraction for device communication\n// =====================================================================\n\n/**\n * Minimal device info returned during discovery (searchDevices).\n * At scan time, full DeviceInfo fields like firmwareVersion are not yet available.\n */\nexport interface ConnectorDevice {\n connectId: string;\n deviceId: string;\n name: string;\n /**\n * Physical transport this device was discovered on. Mirrors Trezor\n * Connect's `descriptor.apiType` — when several transports are fused behind\n * one connector (see `createCombinedConnector`), the merged device list\n * carries this so the host can tell a USB entry from a BLE one and route\n * `connect()` back to the owning transport. Single-transport connectors may\n * leave it undefined.\n */\n connectionType?: ConnectionType;\n /** Machine model id (e.g. \"nanoX\"). */\n model?: string;\n /** Human-readable model name (e.g. \"Ledger Nano X\"). */\n modelName?: string;\n /** BLE signal strength (BLE only). */\n rssi?: number | null;\n /** BLE connectable flag (BLE only). */\n isConnectable?: boolean | null;\n /** USB serial number (USB only). */\n serialNumber?: string;\n\n /** Device capabilities — available from scan time */\n capabilities?: DeviceCapabilities;\n\n /**\n * Vendor-specific raw blob from the transport descriptor (USB / BLE).\n * Populated by `descriptorToConnectorDevice` in each connector. Treat as\n * informational; promote any field consumed by the app layer onto the\n * typed surface above.\n */\n raw?: Record<string, unknown>;\n}\n\nexport interface ConnectorSession {\n sessionId: string;\n deviceInfo: DeviceInfo;\n}\n\n// =====================================================================\n// Connector call result — device errors travel as DATA, not exceptions\n//\n// `IConnector.call` never throws for device-level failures. It resolves a\n// discriminated result so the failure crosses any process boundary\n// (IHardwareBridge / extension offscreen↔SW) as plain `data`. This mirrors\n// the OneKey HD-SDK `IDeviceResponseResult` contract.\n//\n// WHY: when a thrown Error crosses the extension JsBridge it is run through\n// `toPlainError`, a fixed field whitelist that drops custom own-properties\n// (e.g. `appName`). Returning the failure as data keeps every field intact.\n//\n// Contract for `ConnectorSerializedError`: only `message` / `code` /\n// `errorCode` live at the top level; ALL other domain fields (`appName`,\n// `_tag`, `statusCode`, …) are nested under `params`.\n// =====================================================================\n\n/**\n * Vendor-agnostic bag of extra error fields. Known keys are documented for\n * discoverability; the index signature keeps it open so any connector can\n * carry vendor-specific data without losing it across the bridge.\n */\nexport interface ConnectorErrorParams {\n /** Vendor SDK error tag (e.g. Ledger DMK `_tag`). */\n _tag?: string;\n /** App involved, e.g. the Ledger app being opened/installed. */\n appName?: string;\n /** Transport / APDU status code (string or number depending on vendor). */\n statusCode?: unknown;\n /**\n * Shallow snapshot of a nested cause. A raw Error does not survive JSON\n * serialization (its `message`/`stack` are non-enumerable), so recovery\n * predicates that recurse into a cause get this plain-object copy instead.\n */\n originalError?: {\n message?: string;\n code?: number;\n errorCode?: string;\n statusCode?: unknown;\n _tag?: string;\n };\n [key: string]: unknown;\n}\n\nexport interface ConnectorSerializedError {\n message: string;\n code?: number;\n errorCode?: string;\n params?: ConnectorErrorParams;\n}\n\nexport type ConnectorCallResult =\n | { success: true; payload: unknown }\n | { success: false; error: ConnectorSerializedError };\n\nexport type ConnectorEventType =\n | 'device-connect'\n | 'device-disconnect'\n | 'features'\n | 'device-trezor-thp-credentials-changed'\n | 'ui-request'\n | 'ui-event';\n\n/**\n * Interaction event types emitted via 'ui-event'.\n * These map to user-facing prompts (confirm on device, open app, etc.).\n */\nexport enum EConnectorInteraction {\n /** Adapter is actively searching for the device (no session yet) */\n Searching = 'searching',\n /** Device requires user to open a specific app */\n ConfirmOpenApp = 'confirm-open-app',\n /** Device requires user to unlock */\n UnlockDevice = 'unlock-device',\n /** Device needs user to confirm on device (sign, verify, etc.) */\n ConfirmOnDevice = 'confirm-on-device',\n /** Previous interaction completed — clear UI prompt */\n InteractionComplete = 'interaction-complete',\n /**\n * OS-level Ledger app install progress. `progress` is a 0..1 fraction\n * reported by DMK's InstallOrUpdateAppsDeviceAction. Emitted from inside\n * the connector so the progress callback ref never has to cross the\n * IHardwareBridge boundary.\n */\n AppInstallProgress = 'app-install-progress',\n}\n\n// Discriminated union: most variants only carry `sessionId`, but\n// AppInstallProgress also carries `appName` + `progress`. Searching has no\n// session yet so it carries an empty `sessionId`.\nexport type ConnectorUiEvent =\n | { type: EConnectorInteraction.Searching; payload: { sessionId: string } }\n | { type: EConnectorInteraction.ConfirmOpenApp; payload: { sessionId: string } }\n | { type: EConnectorInteraction.UnlockDevice; payload: { sessionId: string } }\n | { type: EConnectorInteraction.ConfirmOnDevice; payload: { sessionId: string } }\n | { type: EConnectorInteraction.InteractionComplete; payload: { sessionId: string } }\n | {\n type: EConnectorInteraction.AppInstallProgress;\n payload: { sessionId: string; appName: string; progress: number };\n };\n\nexport interface ConnectorEventMap {\n 'device-connect': { device: ConnectorDevice };\n 'device-disconnect': { connectId: string };\n features: { device: ConnectorDevice & { features: Record<string, unknown> } };\n 'device-trezor-thp-credentials-changed': {\n connectId: string;\n deviceId?: string;\n credentials: Record<string, unknown>[];\n };\n 'ui-request': { type: string; payload?: unknown };\n 'ui-event': ConnectorUiEvent;\n}\n\nexport interface ConnectorSearchDevicesOptions {\n /**\n * Wait for every child transport in a fused connector. Default discovery can\n * return shortly after USB appears so BLE does not slow down USB flows;\n * binding pickers can opt in when they need BLE candidates too.\n */\n waitForAll?: boolean;\n}\n\nexport interface ConnectorConfig {\n /**\n * Optional OneKey-controlled WebSocket relay base used only for Ledger's\n * genuine check. DMK appends its `/genuine` path and device query params.\n *\n * The value may contain a short-lived opaque relay token, so connectors must\n * never log it. Passing `undefined` restores Ledger's official default.\n */\n ledgerGenuineCheckWebSocketUrl?: string;\n}\n\nexport interface IConnector {\n /** Physical connection type this connector uses. Fixed at construction. */\n readonly connectionType: ConnectionType;\n\n searchDevices(options?: ConnectorSearchDevicesOptions): Promise<ConnectorDevice[]>;\n connect(deviceId?: string): Promise<ConnectorSession>;\n disconnect(sessionId: string): Promise<void>;\n // `call` resolves a discriminated result; device-level failures are returned\n // as data, never thrown (see ConnectorCallResult). Only `call` uses this\n // contract because it is the one method that carries rich, vendor-specific\n // domain errors across the IHardwareBridge boundary, where a thrown Error\n // would be stripped by the host bridge's error whitelist. The other methods\n // surface plain operational failures and still reject normally.\n call(sessionId: string, method: string, params: unknown): Promise<ConnectorCallResult>;\n cancel(sessionId: string): Promise<void>;\n\n /** Send a UI response (e.g. PIN, passphrase) to the device. */\n uiResponse(response: UiResponseEvent): void;\n\n on<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;\n off<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;\n\n reset(): void;\n\n /**\n * Reconfigure vendor-specific transport services before the next connect.\n * Ledger uses this to rebuild DMK against a short-lived OneKey genuine-check\n * relay. Vendors without runtime configuration may omit it.\n */\n configure?(config: ConnectorConfig): Promise<void> | void;\n\n // Vendor-specific opt-in: warm-load persisted credentials before the first\n // session. Trezor uses this for THP `knownCredentials` (host-stored pairing\n // credentials replayed in `ThpHandshakeInitRequest` to skip the CodeEntry /\n // QrCode / NFC pairing UX on every connect). Vendors without persistent\n // credentials (Ledger, etc.) simply don't implement it.\n setKnownCredentials?(credentials: unknown[]): Promise<void> | void;\n}\n\n// =====================================================================\n// Hardware bridge — generic forwarding interface for cross-boundary IConnector\n//\n// The same shape works across any process / context boundary that needs to\n// expose a multi-vendor backend behind a single-vendor IConnector facade:\n// - Electron (renderer ↔ preload/main via contextBridge)\n// - Browser Extension (popup/content ↔ background/offscreen via chrome.runtime)\n// - React Native (JS ↔ native module via NativeModules)\n// - Web Worker / iframe (postMessage)\n//\n// Each method takes a `vendor` discriminator so a single bridge implementation\n// can multiplex across vendors (ledger, trezor, ...).\n// =====================================================================\n\nexport interface IHardwareBridge {\n searchDevices(params: {\n vendor: VendorType;\n options?: ConnectorSearchDevicesOptions;\n }): Promise<ConnectorDevice[]>;\n connect(params: { vendor: VendorType; deviceId?: string }): Promise<ConnectorSession>;\n disconnect(params: { vendor: VendorType; sessionId: string }): Promise<void>;\n call(params: {\n vendor: VendorType;\n sessionId: string;\n method: string;\n callParams: unknown;\n }): Promise<ConnectorCallResult>;\n cancel(params: { vendor: VendorType; sessionId: string }): Promise<void>;\n uiResponse(params: { vendor: VendorType; response: UiResponseEvent }): void;\n reset(params: { vendor: VendorType }): void;\n configure?(params: { vendor: VendorType; config: ConnectorConfig }): Promise<void> | void;\n\n /** Register an event handler for connector events forwarded across the bridge. */\n onEvent(\n params: { vendor: VendorType },\n handler: (event: { type: ConnectorEventType; data: unknown }) => void\n ): void;\n\n /** Unregister a previously registered event handler. */\n offEvent(\n params: { vendor: VendorType },\n handler: (event: { type: ConnectorEventType; data: unknown }) => void\n ): void;\n\n /**\n * Warm-load vendor-specific persisted credentials. Currently only Trezor\n * uses this (THP `knownCredentials`); the bridge implementation can\n * dispatch on `vendor` and route to the right connector instance.\n */\n setKnownCredentials?(params: {\n vendor: VendorType;\n credentials: unknown[];\n }): Promise<void> | void;\n}\n\n/**\n * Adapt an IHardwareBridge (multi-vendor backend) into a single-vendor IConnector.\n * Every IConnector method becomes a transparent forward to bridge.<method>({ vendor, ... }).\n * Events are forwarded via bridge.onEvent / offEvent.\n *\n * Use this anywhere the actual hardware lives behind a process / context boundary\n * (Electron main, extension background, native module, worker, iframe).\n */\nexport function createBridgedConnector(\n vendor: VendorType,\n connectionType: ConnectionType,\n bridge: IHardwareBridge\n): IConnector {\n // Keyed by (event, handler). A flat handler-only map would collide when the\n // same function is registered for multiple events — second .on() would\n // overwrite the first bridge handler reference, leaking it permanently.\n type UserHandler = (data: ConnectorEventMap[ConnectorEventType]) => void;\n type BridgeHandler = (event: { type: ConnectorEventType; data: unknown }) => void;\n const handlerMap = new Map<ConnectorEventType, Map<UserHandler, BridgeHandler>>();\n\n return {\n connectionType,\n searchDevices: options => bridge.searchDevices({ vendor, options }),\n connect: deviceId => bridge.connect({ vendor, deviceId }),\n disconnect: sessionId => bridge.disconnect({ vendor, sessionId }),\n call: (sessionId, method, callParams) => bridge.call({ vendor, sessionId, method, callParams }),\n cancel: sessionId => bridge.cancel({ vendor, sessionId }),\n uiResponse: response => bridge.uiResponse({ vendor, response }),\n on: (event, handler) => {\n const bridgeHandler: BridgeHandler = e => {\n if (e.type === event) {\n handler(e.data as ConnectorEventMap[typeof event]);\n }\n };\n let inner = handlerMap.get(event);\n if (!inner) {\n inner = new Map();\n handlerMap.set(event, inner);\n }\n inner.set(handler as UserHandler, bridgeHandler);\n bridge.onEvent({ vendor }, bridgeHandler);\n },\n off: (event, handler) => {\n const inner = handlerMap.get(event);\n const bridgeHandler = inner?.get(handler as UserHandler);\n if (!bridgeHandler || !inner) return;\n bridge.offEvent({ vendor }, bridgeHandler);\n inner.delete(handler as UserHandler);\n if (inner.size === 0) handlerMap.delete(event);\n },\n reset: () => bridge.reset({ vendor }),\n configure: bridge.configure ? config => bridge.configure?.({ vendor, config }) : undefined,\n setKnownCredentials: bridge.setKnownCredentials\n ? credentials => bridge.setKnownCredentials!({ vendor, credentials })\n : undefined,\n };\n}\n\n// =====================================================================\n// ConnectorCallResult error (de)serialization — the canonical, vendor-agnostic\n// helpers every IConnector implementation / adapter should use, so the\n// \"errors as data\" contract is identical across vendors.\n// =====================================================================\n\nconst SERIALIZED_ERROR_TOP_LEVEL_KEYS = new Set([\n 'message',\n 'code',\n 'errorCode',\n 'stack',\n 'params',\n]);\n\n/**\n * Flatten a thrown error into the cross-boundary-safe `ConnectorSerializedError`\n * shape. `message`/`code`/`errorCode` are lifted to the top level; every other\n * own-enumerable field is copied into `params` so NO domain data is lost when\n * the result crosses a host bridge (which may run thrown errors through a\n * field whitelist). A nested `originalError` is shallow-snapshotted because a\n * raw Error does not survive JSON serialization.\n */\nexport function serializeConnectorError(err: unknown): ConnectorSerializedError {\n if (!err || typeof err !== 'object') {\n return { message: typeof err === 'string' ? err : 'Unknown error' };\n }\n const e = err as Record<string, unknown>;\n const message = typeof e.message === 'string' ? e.message : 'Unknown error';\n const code = typeof e.code === 'number' ? e.code : undefined;\n const errorCode = e.errorCode != null ? String(e.errorCode) : undefined;\n\n const params: ConnectorErrorParams = {};\n // Flatten an existing `params` bag, then copy every other own field (so\n // vendor-specific keys like `_tag` / `statusCode` / `appName` / step context\n // are preserved without being named here).\n if (e.params && typeof e.params === 'object') {\n Object.assign(params, e.params as Record<string, unknown>);\n }\n for (const key of Object.keys(e)) {\n if (!SERIALIZED_ERROR_TOP_LEVEL_KEYS.has(key)) {\n params[key] = e[key];\n }\n }\n const orig = e.originalError;\n if (orig && typeof orig === 'object') {\n const o = orig as Record<string, unknown>;\n params.originalError = {\n message: typeof o.message === 'string' ? o.message : undefined,\n code: typeof o.code === 'number' ? o.code : undefined,\n errorCode: o.errorCode != null ? String(o.errorCode) : undefined,\n statusCode: o.statusCode,\n _tag: typeof o._tag === 'string' ? o._tag : undefined,\n };\n }\n\n // The result crosses host bridges via JSON.stringify. Drop any single field\n // that isn't JSON-safe (circular ref / non-serializable) so a pathological\n // error degrades to \"one field missing\" instead of crashing the transport.\n for (const key of Object.keys(params)) {\n try {\n JSON.stringify(params[key]);\n } catch {\n delete params[key];\n }\n }\n\n return {\n message,\n ...(code !== undefined ? { code } : {}),\n ...(errorCode !== undefined ? { errorCode } : {}),\n ...(Object.keys(params).length ? { params } : {}),\n };\n}\n\n/**\n * Inverse of `serializeConnectorError`: rebuild a flat Error instance, lifting\n * `params.*` back to own-properties so existing throw-based classifiers/recovery\n * logic (which read `err._tag` / `err.code` / `err.appName` / …) keep working\n * unchanged. The Result shape stays confined to the connector boundary.\n */\nexport function rehydrateConnectorError(error: ConnectorSerializedError): Error {\n const { message, code, errorCode, params } = error;\n return Object.assign(new Error(message), {\n ...(code !== undefined ? { code } : {}),\n ...(errorCode !== undefined ? { errorCode } : {}),\n ...(params ?? {}),\n });\n}\n\n/**\n * Fuse several single-transport IConnectors (e.g. WebUSB + BLE for one\n * vendor) into one IConnector whose device list is the union of all of them.\n *\n * This mirrors how Trezor Connect's `DeviceList` keeps one `TransportManager`\n * per `apiType` running concurrently and merges their devices into a single\n * list: there is no \"switch\" between transports — both are always live, and\n * each discovered device carries its `connectionType` so the host knows which\n * channel it came in on. `connect()` routes back to the transport that owns\n * the chosen device; later calls route by `sessionId`.\n *\n * Notes / current limitations:\n * - `searchDevices()` fans out concurrently; a transport that throws while\n * scanning is treated as \"no devices\" so a dead/absent channel never sinks\n * the others.\n * - USB entries sort ahead of BLE ones (Trezor's `getPrioritizedDevices`).\n * - The same physical device reachable on two transports surfaces as two\n * entries with different `connectId`s — we do NOT dedup, so the host can\n * present (or pick) a channel explicitly.\n * - `uiResponse()` carries no sessionId, so it is broadcast to every child;\n * a child with no matching pending request ignores it.\n */\nfunction isDeviceUnavailableError(error: unknown): boolean {\n const typed = error as { code?: unknown };\n if (\n typed.code === HardwareErrorCode.DeviceNotFound ||\n typed.code === HardwareErrorCode.DeviceDisconnected\n ) {\n return true;\n }\n return false;\n}\n\nfunction combinedDeviceNotFoundError(message: string): Error {\n return createHwkError({\n code: HardwareErrorCode.DeviceNotFound,\n message,\n });\n}\n\nfunction combinedSessionNotFoundError(message: string): Error {\n return createHwkError({\n code: HardwareErrorCode.DeviceDisconnected,\n message,\n });\n}\n\nexport function createCombinedConnector(connectors: IConnector[]): IConnector {\n if (connectors.length === 0) {\n throw new Error('createCombinedConnector: at least one connector is required');\n }\n const SEARCH_SETTLE_AFTER_FIRST_DEVICE_MS = 250;\n\n // connectId -> the child connector that discovered it (set on searchDevices).\n const deviceOwner = new Map<string, IConnector>();\n // sessionId -> the child connector that owns the live session.\n const sessionOwner = new Map<string, IConnector>();\n // userHandler -> the per-child forwarders we attached, so off() can detach.\n type UserHandler = (data: ConnectorEventMap[ConnectorEventType]) => void;\n const forwarders = new Map<\n ConnectorEventType,\n Map<UserHandler, Array<{ child: IConnector; handler: UserHandler }>>\n >();\n\n // BLE ranks after USB — matches Trezor's getPrioritizedDevices().\n const rank = (device: ConnectorDevice): number => (device.connectionType === 'ble' ? 1 : 0);\n\n // Shared THP pairing credentials across all child transports. A credential is\n // keyed by the device's static public key (transport-agnostic, see\n // `findKnownPairingCredentials`), so a credential minted while pairing over\n // one transport (e.g. USB) must reach the sibling transports (e.g. BLE) or\n // they re-pair instead of autoconnecting. Each child keeps its OWN\n // knownCredentials array, so we maintain the union here and re-broadcast it to\n // every child whenever any child mints a fresh one.\n const sharedCredentials: Array<Record<string, unknown>> = [];\n const credentialKey = (c: Record<string, unknown>): string =>\n (c.credential as string) ?? JSON.stringify(c);\n const mergeShared = (incoming: ReadonlyArray<Record<string, unknown>>): boolean => {\n let changed = false;\n for (const cred of incoming) {\n const key = credentialKey(cred);\n if (!sharedCredentials.some(e => credentialKey(e) === key)) {\n sharedCredentials.push(cred);\n changed = true;\n }\n }\n return changed;\n };\n const broadcastCredentials = async (): Promise<void> => {\n await Promise.all(\n connectors.map(child => Promise.resolve(child.setKnownCredentials?.(sharedCredentials)))\n );\n };\n\n // Internal subscription (independent of user on()/off()): when any child mints\n // fresh pairing credentials, fold them into the shared union and push the\n // union down to every child so the next handshake on ANY transport\n // autoconnects rather than re-pairing.\n for (const child of connectors) {\n child.on('device-trezor-thp-credentials-changed', data => {\n if (mergeShared(data.credentials)) void broadcastCredentials();\n });\n }\n\n const searchDevices = async (\n options: { waitForAll?: boolean } = {}\n ): Promise<ConnectorDevice[]> => {\n const perConnector: Array<{\n index: number;\n devices: ConnectorDevice[];\n }> = [];\n\n await new Promise<void>(resolve => {\n let finished = false;\n let remaining = connectors.length;\n let settleTimer: ReturnType<typeof setTimeout> | undefined;\n\n const finish = () => {\n if (finished) return;\n finished = true;\n if (settleTimer) clearTimeout(settleTimer);\n resolve();\n };\n\n connectors.forEach((child, index) => {\n void child\n .searchDevices()\n .then(devices =>\n devices.map(device => ({\n ...device,\n connectionType: device.connectionType ?? child.connectionType,\n }))\n )\n .catch(\n () =>\n // A transport that can't scan (powered off, unauthorized, absent)\n // must not fail the whole fused search.\n [] as ConnectorDevice[]\n )\n .then(devices => {\n remaining -= 1;\n if (!finished) {\n perConnector.push({ index, devices });\n }\n if (remaining === 0) {\n finish();\n return;\n }\n const hasUsbDevice = devices.some(device => device.connectionType === 'usb');\n if (hasUsbDevice && !settleTimer && !options.waitForAll) {\n settleTimer = setTimeout(finish, SEARCH_SETTLE_AFTER_FIRST_DEVICE_MS);\n }\n });\n });\n });\n\n perConnector.sort((a, b) => a.index - b.index);\n\n deviceOwner.clear();\n const merged: ConnectorDevice[] = [];\n perConnector.forEach(({ index, devices }) => {\n for (const device of devices) {\n deviceOwner.set(device.connectId, connectors[index]);\n merged.push(device);\n }\n });\n return merged.sort((a, b) => rank(a) - rank(b));\n };\n\n const resolveOwner = async (\n deviceId?: string\n ): Promise<{ owner: IConnector; deviceId?: string }> => {\n if (deviceId && deviceOwner.has(deviceId)) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { owner: deviceOwner.get(deviceId)!, deviceId };\n }\n const devices = await searchDevices({ waitForAll: Boolean(deviceId) });\n if (deviceId) {\n const owner = deviceOwner.get(deviceId);\n if (!owner)\n throw combinedDeviceNotFoundError(`Combined connector: device not found: ${deviceId}`);\n return { owner, deviceId };\n }\n const first = devices[0];\n if (!first) throw combinedDeviceNotFoundError('Combined connector: no devices found');\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { owner: deviceOwner.get(first.connectId)!, deviceId: first.connectId };\n };\n\n const connectByExplicitId = async (\n deviceId: string\n ): Promise<{ session: ConnectorSession; owner: IConnector }> => {\n const cachedOwner = deviceOwner.get(deviceId);\n if (cachedOwner) {\n return { session: await cachedOwner.connect(deviceId), owner: cachedOwner };\n }\n\n let lastError: unknown;\n for (const child of connectors) {\n try {\n const session = await child.connect(deviceId);\n deviceOwner.set(deviceId, child);\n return { session, owner: child };\n } catch (error) {\n if (!isDeviceUnavailableError(error)) {\n throw error;\n }\n lastError = error;\n }\n }\n const message =\n lastError instanceof Error\n ? lastError.message\n : `Combined connector: device not found: ${deviceId}`;\n throw createHwkError({\n code: HardwareErrorCode.DeviceNotFound,\n message,\n });\n };\n\n return {\n // Nominal value only — the per-device `connectionType` is authoritative\n // for a fused connector.\n connectionType: connectors[0].connectionType,\n\n searchDevices: options => searchDevices({ waitForAll: options?.waitForAll }),\n\n connect: async deviceId => {\n let owner: IConnector;\n let session: ConnectorSession;\n if (deviceId) {\n ({ session, owner } = await connectByExplicitId(deviceId));\n } else {\n const resolved = await resolveOwner();\n owner = resolved.owner;\n session = await owner.connect(resolved.deviceId);\n }\n // Use the owner resolved during connect — re-deriving via\n // session.deviceInfo.connectId breaks for ephemeral-id transports (the id\n // can change on connect → missed lookup → orphaned session).\n sessionOwner.set(session.sessionId, owner);\n return session;\n },\n\n disconnect: async sessionId => {\n const owner = sessionOwner.get(sessionId);\n if (!owner) return;\n await owner.disconnect(sessionId);\n sessionOwner.delete(sessionId);\n },\n\n call: async (sessionId, method, params) => {\n const owner = sessionOwner.get(sessionId);\n if (!owner) {\n throw combinedSessionNotFoundError(`Combined connector: session not found: ${sessionId}`);\n }\n return owner.call(sessionId, method, params);\n },\n\n cancel: async sessionId => {\n const owner = sessionOwner.get(sessionId);\n if (!owner) return;\n await owner.cancel(sessionId);\n },\n\n uiResponse: response => {\n // No sessionId on the response — broadcast; children without a matching\n // pending request ignore it.\n for (const child of connectors) child.uiResponse(response);\n },\n\n on: (event, handler) => {\n const attached = connectors.map(child => {\n const forward: UserHandler = data => (handler as UserHandler)(data);\n child.on(event, forward as Parameters<IConnector['on']>[1]);\n return { child, handler: forward };\n });\n let inner = forwarders.get(event);\n if (!inner) {\n inner = new Map();\n forwarders.set(event, inner);\n }\n inner.set(handler as UserHandler, attached);\n },\n\n off: (event, handler) => {\n const inner = forwarders.get(event);\n const attached = inner?.get(handler as UserHandler);\n if (!attached || !inner) return;\n for (const { child, handler: forward } of attached) {\n child.off(event, forward as Parameters<IConnector['off']>[1]);\n }\n inner.delete(handler as UserHandler);\n if (inner.size === 0) forwarders.delete(event);\n },\n\n reset: () => {\n for (const child of connectors) child.reset();\n deviceOwner.clear();\n sessionOwner.clear();\n forwarders.clear();\n },\n\n configure: connectors.some(c => c.configure)\n ? async config => {\n await Promise.all(connectors.map(child => Promise.resolve(child.configure?.(config))));\n deviceOwner.clear();\n sessionOwner.clear();\n }\n : undefined,\n\n setKnownCredentials: connectors.some(c => c.setKnownCredentials)\n ? async credentials => {\n // Seed the shared union from the host (warm-load) and fan out to all\n // children so every transport starts from the same credential set.\n sharedCredentials.length = 0;\n mergeShared((credentials ?? []) as Array<Record<string, unknown>>);\n await broadcastCredentials();\n }\n : undefined,\n };\n}\n","/**\n * Minimal typed event emitter using Map<string, Set<listener>>.\n * Each adapter uses this for device events (connect, disconnect, pin, etc.).\n *\n * TMap is a record mapping event name strings to their payload types.\n * Example:\n * type MyEvents = { 'connect': { id: string }; 'disconnect': { id: string } };\n * const emitter = new TypedEventEmitter<MyEvents>();\n * emitter.on('connect', (data) => { data.id }); // data is { id: string }\n *\n * For backward compatibility, TMap defaults to Record<string, any> so that\n * existing code using `new TypedEventEmitter<SomeUnionType>()` still compiles.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class TypedEventEmitter<TMap extends Record<string, any> = Record<string, any>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly _listeners = new Map<string, Set<(event: any) => void>>();\n\n on<K extends keyof TMap & string>(event: K, listener: (event: TMap[K]) => void): void;\n\n on(event: string, listener: (event: any) => void): void;\n\n on(event: string, listener: (event: any) => void): void {\n let set = this._listeners.get(event);\n if (!set) {\n set = new Set();\n this._listeners.set(event, set);\n }\n set.add(listener);\n }\n\n off<K extends keyof TMap & string>(event: K, listener: (event: TMap[K]) => void): void;\n\n off(event: string, listener: (event: any) => void): void;\n\n off(event: string, listener: (event: any) => void): void {\n const set = this._listeners.get(event);\n if (set) {\n set.delete(listener);\n if (set.size === 0) this._listeners.delete(event);\n }\n }\n\n emit<K extends keyof TMap & string>(event: K, data: TMap[K]): void;\n\n emit(event: string, data: unknown): void;\n\n emit(event: string, data: unknown): void {\n const set = this._listeners.get(event);\n if (set) {\n for (const listener of set) listener(data);\n }\n }\n\n removeAllListeners(): void {\n this._listeners.clear();\n }\n\n /** Number of listeners registered for `event`. 0 if none. */\n listenerCount(event: string): number {\n return this._listeners.get(event)?.size ?? 0;\n }\n}\n","/**\n * Compare two semver strings (e.g. \"2.1.0\" vs \"2.3.1\").\n * Returns -1 if a < b, 0 if equal, 1 if a > b.\n */\nexport function compareSemver(a: string, b: string): number {\n const pa = a.split('.').map(Number);\n const pb = b.split('.').map(Number);\n for (let i = 0; i < 3; i++) {\n const va = pa[i] ?? 0;\n const vb = pb[i] ?? 0;\n if (va < vb) return -1;\n if (va > vb) return 1;\n }\n return 0;\n}\n","import { bytesToHex as nobleBytesToHex, hexToBytes as nobleHexToBytes } from '@noble/hashes/utils';\n\n/** Ensure hex string has 0x prefix */\nexport function ensure0x(hex: string): string {\n return hex.startsWith('0x') ? hex : `0x${hex}`;\n}\n\n/** Strip 0x prefix from hex string */\nexport function stripHex(hex: string): string {\n return hex.startsWith('0x') ? hex.slice(2) : hex;\n}\n\n/** Pad hex to 64 chars (32 bytes) with 0x prefix */\nexport function padHex64(hex: string): string {\n return `0x${stripHex(hex).padStart(64, '0')}`;\n}\n\n/**\n * Convert a hex string (with or without 0x prefix) to a Uint8Array.\n * Throws on invalid hex (non-hex characters, odd length).\n */\nexport function hexToBytes(hex: string): Uint8Array {\n return nobleHexToBytes(stripHex(hex));\n}\n\n/** Convert a Uint8Array to a hex string (no 0x prefix). */\nexport function bytesToHex(bytes: Uint8Array): string {\n return nobleBytesToHex(bytes);\n}\n","export type DetectableHardwareVendor = 'onekey' | 'trezor' | 'ledger';\n\nexport type HardwareDeviceIdentityInput = {\n name?: string | null;\n localName?: string | null;\n bleName?: string | null;\n model?: string | null;\n modelName?: string | null;\n type?: string | null;\n productName?: string | null;\n manufacturerName?: string | null;\n vendor?: number | string | null;\n vendorId?: number | null;\n product?: number | string | null;\n productId?: number | null;\n label?: string | null;\n fw_vendor?: string | null;\n internal_model?: string | null;\n onekey_version?: string | null;\n onekey_device_type?: string | null;\n onekey_serial?: string | null;\n serviceUUIDs?: string[] | null;\n advertisedServiceUuids?: string[] | null;\n serviceUuids?: string[] | null;\n};\n\nconst ONEKEY_BLE_SERVICE_UUID = '00000001-0000-1000-8000-00805f9b34fb';\nconst TREZOR_BLE_SERVICE_UUID = '8c000001-a59b-4d58-a9ad-073df69fa1b1';\nconst LEDGER_USB_VENDOR_ID = 0x2c97;\n\nconst lower = (value?: string | null): string => value?.trim().toLowerCase() ?? '';\n\nconst hasServiceUuid = (input: HardwareDeviceIdentityInput, uuid: string): boolean => {\n const expected = uuid.toLowerCase();\n const values = [\n ...(input.serviceUUIDs ?? []),\n ...(input.advertisedServiceUuids ?? []),\n ...(input.serviceUuids ?? []),\n ];\n return values.some(value => value.toLowerCase() === expected);\n};\n\nexport function detectHardwareVendorFromDescriptor(\n input: HardwareDeviceIdentityInput\n): DetectableHardwareVendor | undefined {\n const manufacturerName = lower(input.manufacturerName);\n const fwVendor = lower(input.fw_vendor);\n\n if (\n hasServiceUuid(input, ONEKEY_BLE_SERVICE_UUID) ||\n manufacturerName.includes('onekey') ||\n fwVendor === 'onekey' ||\n input.onekey_version ||\n input.onekey_device_type ||\n input.onekey_serial\n ) {\n return 'onekey';\n }\n if (\n hasServiceUuid(input, TREZOR_BLE_SERVICE_UUID) ||\n manufacturerName.includes('trezor') ||\n fwVendor === 'trezor'\n ) {\n return 'trezor';\n }\n if (\n (typeof input.vendor === 'number' && input.vendor === LEDGER_USB_VENDOR_ID) ||\n input.vendorId === LEDGER_USB_VENDOR_ID ||\n manufacturerName.includes('ledger')\n ) {\n return 'ledger';\n }\n return undefined;\n}\n\nexport function isKnownNonTargetHardwareVendor(\n input: HardwareDeviceIdentityInput,\n targetVendor: DetectableHardwareVendor\n): boolean {\n const detectedVendor = detectHardwareVendorFromDescriptor(input);\n return detectedVendor !== undefined && detectedVendor !== targetVendor;\n}\n","import type { Response } from '../types/response';\n\n/**\n * Generic batch call with progress reporting.\n * If any single call fails, returns the failure immediately.\n */\nexport async function batchCall<TParam, TResult>(\n params: TParam[],\n callFn: (p: TParam) => Promise<Response<TResult>>,\n onProgress?: (progress: { index: number; total: number }) => void\n): Promise<Response<TResult[]>> {\n const results: TResult[] = [];\n for (let i = 0; i < params.length; i++) {\n const result = await callFn(params[i]);\n if (!result.success) {\n return result;\n }\n results.push(result.payload);\n onProgress?.({ index: i, total: params.length });\n }\n return { success: true, payload: results };\n}\n","import type { ChainForFingerprint } from '../types/fingerprint';\n\nexport type HardwareMethodMetadata = {\n chain: ChainForFingerprint;\n allNetwork: boolean;\n};\n\nexport const HARDWARE_METHOD_CATALOG = {\n evmGetAddress: { chain: 'evm', allNetwork: true },\n evmSignTransaction: { chain: 'evm', allNetwork: false },\n evmSignMessage: { chain: 'evm', allNetwork: false },\n evmSignTypedData: { chain: 'evm', allNetwork: false },\n btcGetAddress: { chain: 'btc', allNetwork: true },\n btcGetPublicKey: { chain: 'btc', allNetwork: true },\n btcSignTransaction: { chain: 'btc', allNetwork: false },\n btcSignPsbt: { chain: 'btc', allNetwork: false },\n btcSignMessage: { chain: 'btc', allNetwork: false },\n btcGetMasterFingerprint: { chain: 'btc', allNetwork: false },\n solGetAddress: { chain: 'sol', allNetwork: true },\n solSignTransaction: { chain: 'sol', allNetwork: false },\n solSignMessage: { chain: 'sol', allNetwork: false },\n tronGetAddress: { chain: 'tron', allNetwork: true },\n tronSignTransaction: { chain: 'tron', allNetwork: false },\n tronSignMessage: { chain: 'tron', allNetwork: false },\n} as const satisfies Record<string, HardwareMethodMetadata>;\n\nexport type HardwareMethodName = keyof typeof HARDWARE_METHOD_CATALOG;\n\nexport type AllNetworkMethodName = {\n [K in HardwareMethodName]: (typeof HARDWARE_METHOD_CATALOG)[K]['allNetwork'] extends true\n ? K\n : never;\n}[HardwareMethodName];\n\nexport const ALL_NETWORK_METHOD_NAMES = Object.entries(HARDWARE_METHOD_CATALOG)\n .filter(([, metadata]) => metadata.allNetwork)\n .map(([method]) => method) as AllNetworkMethodName[];\n\nconst ALL_NETWORK_METHOD_SET = new Set<string>(ALL_NETWORK_METHOD_NAMES);\n\nexport function getHardwareMethodMetadata(method: string): HardwareMethodMetadata | undefined {\n return HARDWARE_METHOD_CATALOG[method as HardwareMethodName];\n}\n\nexport function isAllNetworkMethodName(method: string): method is AllNetworkMethodName {\n return ALL_NETWORK_METHOD_SET.has(method);\n}\n\nexport function getAllNetworkMethodChain(method: AllNetworkMethodName): ChainForFingerprint {\n return HARDWARE_METHOD_CATALOG[method].chain;\n}\n","import { HardwareErrorCode } from '../types/errors';\nimport { failure, success } from '../types/response';\nimport { getAllNetworkMethodChain, isAllNetworkMethodName } from './methodCatalog';\n\nimport type { ChainForFingerprint } from '../types/fingerprint';\nimport type { Response } from '../types/response';\nimport type {\n AllNetworkAddressParams,\n AllNetworkAddressResponse,\n AllNetworkGetAddressParams,\n} from '../types/wallet';\nimport type { AllNetworkMethodName } from './methodCatalog';\n\nexport type AllNetworkCallItemContext = {\n connectId: string;\n deviceId: string;\n method: AllNetworkMethodName;\n chain: ChainForFingerprint;\n item: AllNetworkAddressParams;\n index: number;\n};\n\nexport type AllNetworkAttachIdentityContext = AllNetworkCallItemContext & {\n payload: Record<string, unknown>;\n};\n\nexport type AllNetworkResponseContext = AllNetworkCallItemContext & {\n response: AllNetworkAddressResponse;\n};\n\nexport type RunAllNetworkGetAddressOptions = {\n connectId: string;\n deviceId: string;\n params: AllNetworkGetAddressParams;\n getMethodChain?: (\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ) => ChainForFingerprint;\n normalizeItem?: (\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ) => AllNetworkAddressParams;\n buildUnsupportedNetworkResponse?: (\n item: AllNetworkAddressParams,\n method: AllNetworkMethodName\n ) => AllNetworkAddressResponse | undefined;\n callItem: (context: AllNetworkCallItemContext) => Promise<Response<unknown>>;\n attachIdentity: (context: AllNetworkAttachIdentityContext) => Promise<AllNetworkAddressResponse>;\n shouldAbortBundle?: (\n response: AllNetworkAddressResponse,\n context: AllNetworkResponseContext\n ) => boolean;\n buildTopLevelFailure?: (\n response: AllNetworkAddressResponse,\n context: AllNetworkResponseContext\n ) => Response<AllNetworkAddressResponse[]>;\n};\n\nexport async function runAllNetworkGetAddress({\n connectId,\n deviceId,\n params,\n getMethodChain = method => getAllNetworkMethodChain(method),\n normalizeItem = (_method, item) => item,\n buildUnsupportedNetworkResponse,\n callItem,\n attachIdentity,\n shouldAbortBundle = () => false,\n buildTopLevelFailure = defaultBuildTopLevelFailure,\n}: RunAllNetworkGetAddressOptions): Promise<Response<AllNetworkAddressResponse[]>> {\n const responses: AllNetworkAddressResponse[] = [];\n\n for (const [index, item] of params.bundle.entries()) {\n if (!isAllNetworkMethodName(String(item.methodName))) {\n responses.push(buildUnsupportedMethodResponse(item));\n continue;\n }\n\n const method = item.methodName;\n const unsupportedNetwork = buildUnsupportedNetworkResponse?.(item, method);\n if (unsupportedNetwork) {\n responses.push(unsupportedNetwork);\n continue;\n }\n\n const chain = getMethodChain(method, item);\n const normalizedItem = normalizeItem(method, item);\n const context: AllNetworkCallItemContext = {\n connectId,\n deviceId,\n method,\n chain,\n item: normalizedItem,\n index,\n };\n const response = await callItem(context);\n const itemResponse = response.success\n ? await attachIdentity({\n ...context,\n payload: response.payload as Record<string, unknown>,\n })\n : ({\n ...normalizedItem,\n success: false,\n payload: response.payload,\n } as AllNetworkAddressResponse);\n\n const responseContext = { ...context, response: itemResponse };\n if (!itemResponse.success && shouldAbortBundle(itemResponse, responseContext)) {\n return buildTopLevelFailure(itemResponse, responseContext);\n }\n responses.push(itemResponse);\n }\n\n return success(responses);\n}\n\nexport function buildUnsupportedMethodResponse(\n item: AllNetworkAddressParams\n): AllNetworkAddressResponse {\n return {\n ...item,\n success: false,\n payload: {\n code: HardwareErrorCode.InvalidParams,\n error: `Unsupported allNetwork method: ${String(item.methodName)}`,\n },\n };\n}\n\nfunction defaultBuildTopLevelFailure(\n response: AllNetworkAddressResponse\n): Response<AllNetworkAddressResponse[]> {\n const payload = response.payload ?? {};\n return failure(\n (payload.code as HardwareErrorCode | undefined) ?? HardwareErrorCode.DeviceMismatch,\n payload.error ?? 'All-network get-address aborted',\n normalizeFailureParams(payload.params)\n );\n}\n\nfunction normalizeFailureParams(params: unknown): Record<string, unknown> | undefined {\n return params && typeof params === 'object' ? (params as Record<string, unknown>) : undefined;\n}\n","export const DEVICE_CONNECT_RETRY_DELAY_MS = 1000;\n"],"mappings":"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","names":["EConnectorInteraction","bytesToHex"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hwk-adapter-core",
3
- "version": "1.2.1",
3
+ "version": "1.2.2-alpha.1",
4
4
  "description": "Shared types and utilities for OneKey hardware wallet kit",
5
5
  "author": "OneKey",
6
6
  "license": "MIT",
@@ -70,5 +70,5 @@
70
70
  "tsup": "^8.0.0",
71
71
  "typescript": "^5.4.0"
72
72
  },
73
- "gitHead": "43d2856e593a93fbf056fdb334e0fe407a79cdc0"
73
+ "gitHead": "66f45610d36e06a46ac82cd49a4b0e1a128f19d4"
74
74
  }