@onekeyfe/hwk-trezor-adapter 1.1.29-alpha.7 → 1.1.29-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { IHardwareWallet, IConnector, TransportType, DeviceInfo, Response, ChainCapability, AllNetworkGetAddressParams, AllNetworkAddressResponse, TrezorDeviceSettingsParams, TrezorBrightnessParams, TrezorChangePinParams, UiResponseEvent, ChainForFingerprint, ICommonCallParams, EvmGetAddressParams, EvmAddress, EvmSignTxParams, EvmSignedTx, EvmSignMsgParams, EvmSignature, EvmSignTypedDataParams, BtcGetAddressParams, BtcAddress, BtcGetPublicKeyParams, BtcPublicKey, BtcSignTxParams, BtcSignedTx, BtcSignPsbtParams, BtcSignedPsbt, BtcSignMsgParams, BtcSignature, SolGetAddressParams, SolAddress, SolSignTxParams, SolSignedTx, SolSignMsgParams, SolSignature, TronGetAddressParams, TronAddress, TronSignTxParams, TronSignedTx, TronSignMsgParams, TronSignature, HardwareEventMap, DeviceEventListener, EvmEthereumDefinitions, ConnectorDevice } from '@onekeyfe/hwk-adapter-core';
1
+ import { IHardwareWallet, IConnector, TransportType, DeviceInfo, Response, ChainCapability, AllNetworkGetAddressParams, AllNetworkAddressResponse, TrezorDeviceSettingsParams, TrezorBrightnessParams, TrezorChangePinParams, UiResponseEvent, ChainForFingerprint, ICommonCallParams, EvmGetAddressParams, EvmAddress, EvmSignTxTrezorParams, EvmSignedTx, EvmSignMsgParams, EvmSignature, EvmSignTypedDataParams, BtcGetAddressParams, BtcAddress, BtcGetPublicKeyParams, BtcPublicKey, BtcSignTxParams, BtcSignedTx, BtcSignPsbtParams, BtcSignedPsbt, BtcSignMsgParams, BtcSignature, SolGetAddressParams, SolAddress, SolSignTxParams, SolSignedTx, SolSignMsgParams, SolSignature, TronGetAddressParams, TronAddress, TronSignTxParams, TronSignedTx, TronSignMsgParams, TronSignature, HardwareEventMap, DeviceEventListener, EvmEthereumDefinitions, ConnectorDevice } from '@onekeyfe/hwk-adapter-core';
2
2
 
3
3
  type TrezorPassphraseCallParams = {
4
4
  passphraseState?: string;
@@ -107,7 +107,7 @@ declare class TrezorAdapter implements IHardwareWallet {
107
107
  */
108
108
  getPassphraseState(connectId: string, passphraseState?: string): Promise<Response<string | null>>;
109
109
  evmGetAddress(connectId?: string | null, deviceId?: string | null, params?: TrezorCallParams<EvmGetAddressParams>): Promise<Response<EvmAddress>>;
110
- evmSignTransaction(connectId?: string | null, deviceId?: string | null, params?: TrezorCallParams<EvmSignTxParams>): Promise<Response<EvmSignedTx>>;
110
+ evmSignTransaction(connectId?: string | null, deviceId?: string | null, params?: TrezorCallParams<EvmSignTxTrezorParams>): Promise<Response<EvmSignedTx>>;
111
111
  evmSignMessage(connectId?: string | null, deviceId?: string | null, params?: TrezorCallParams<EvmSignMsgParams>): Promise<Response<EvmSignature>>;
112
112
  evmSignTypedData(connectId?: string | null, deviceId?: string | null, params?: TrezorCallParams<EvmSignTypedDataParams>): Promise<Response<EvmSignature>>;
113
113
  btcGetAddress(connectId?: string | null, deviceId?: string | null, params?: TrezorCallParams<BtcGetAddressParams>): Promise<Response<BtcAddress>>;
@@ -204,8 +204,8 @@ declare class TrezorAdapter implements IHardwareWallet {
204
204
  *
205
205
  * Cross-process note: `fetchImpl` is a FUNCTION and cannot be serialized across
206
206
  * an IPC / postMessage boundary. Call these helpers in a network-capable
207
- * process and send only the resulting bytes (ArrayBuffer/hex) to the process
208
- * that talks to the device. Use `baseUrl` (a string) to route through your own
207
+ * process and send only the resulting hex strings to the process that talks
208
+ * to the device. Use `baseUrl` (a string) to route through your own
209
209
  * controlled proxy instead of hitting data.trezor.io directly.
210
210
  */
211
211
  /** Default upstream (Trezor). Override with `baseUrl` to use your own proxy. */
@@ -249,7 +249,7 @@ declare function buildEthereumDefinitionsForSignTx({ path, chainId, to, data, ba
249
249
  * confirmation screen and signing still completes.
250
250
  *
251
251
  * `fetchImpl` is a function and must not cross an IPC boundary — fetch in a
252
- * network-capable process and pass only the resulting bytes.
252
+ * network-capable process and pass only the resulting hex string.
253
253
  */
254
254
  /** Default upstream (Trezor). Override with `baseUrl` to use your own proxy. */
255
255
  declare const DEFAULT_SOLANA_TOKEN_DEFINITION_BASE_URL = "https://data.trezor.io/firmware/definitions/solana/token";
@@ -258,7 +258,7 @@ type FetchSolanaTokenDefinitionParams = {
258
258
  baseUrl?: string;
259
259
  fetchImpl?: FetchLike;
260
260
  };
261
- declare function fetchSolanaTokenDefinition({ tokenMint, baseUrl, fetchImpl, }: FetchSolanaTokenDefinitionParams): Promise<ArrayBuffer | undefined>;
261
+ declare function fetchSolanaTokenDefinition({ tokenMint, baseUrl, fetchImpl, }: FetchSolanaTokenDefinitionParams): Promise<string | undefined>;
262
262
 
263
263
  /**
264
264
  * SDK-global event bus. Per-runtime singleton; hosts forward events over their
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { IHardwareWallet, IConnector, TransportType, DeviceInfo, Response, ChainCapability, AllNetworkGetAddressParams, AllNetworkAddressResponse, TrezorDeviceSettingsParams, TrezorBrightnessParams, TrezorChangePinParams, UiResponseEvent, ChainForFingerprint, ICommonCallParams, EvmGetAddressParams, EvmAddress, EvmSignTxParams, EvmSignedTx, EvmSignMsgParams, EvmSignature, EvmSignTypedDataParams, BtcGetAddressParams, BtcAddress, BtcGetPublicKeyParams, BtcPublicKey, BtcSignTxParams, BtcSignedTx, BtcSignPsbtParams, BtcSignedPsbt, BtcSignMsgParams, BtcSignature, SolGetAddressParams, SolAddress, SolSignTxParams, SolSignedTx, SolSignMsgParams, SolSignature, TronGetAddressParams, TronAddress, TronSignTxParams, TronSignedTx, TronSignMsgParams, TronSignature, HardwareEventMap, DeviceEventListener, EvmEthereumDefinitions, ConnectorDevice } from '@onekeyfe/hwk-adapter-core';
1
+ import { IHardwareWallet, IConnector, TransportType, DeviceInfo, Response, ChainCapability, AllNetworkGetAddressParams, AllNetworkAddressResponse, TrezorDeviceSettingsParams, TrezorBrightnessParams, TrezorChangePinParams, UiResponseEvent, ChainForFingerprint, ICommonCallParams, EvmGetAddressParams, EvmAddress, EvmSignTxTrezorParams, EvmSignedTx, EvmSignMsgParams, EvmSignature, EvmSignTypedDataParams, BtcGetAddressParams, BtcAddress, BtcGetPublicKeyParams, BtcPublicKey, BtcSignTxParams, BtcSignedTx, BtcSignPsbtParams, BtcSignedPsbt, BtcSignMsgParams, BtcSignature, SolGetAddressParams, SolAddress, SolSignTxParams, SolSignedTx, SolSignMsgParams, SolSignature, TronGetAddressParams, TronAddress, TronSignTxParams, TronSignedTx, TronSignMsgParams, TronSignature, HardwareEventMap, DeviceEventListener, EvmEthereumDefinitions, ConnectorDevice } from '@onekeyfe/hwk-adapter-core';
2
2
 
3
3
  type TrezorPassphraseCallParams = {
4
4
  passphraseState?: string;
@@ -107,7 +107,7 @@ declare class TrezorAdapter implements IHardwareWallet {
107
107
  */
108
108
  getPassphraseState(connectId: string, passphraseState?: string): Promise<Response<string | null>>;
109
109
  evmGetAddress(connectId?: string | null, deviceId?: string | null, params?: TrezorCallParams<EvmGetAddressParams>): Promise<Response<EvmAddress>>;
110
- evmSignTransaction(connectId?: string | null, deviceId?: string | null, params?: TrezorCallParams<EvmSignTxParams>): Promise<Response<EvmSignedTx>>;
110
+ evmSignTransaction(connectId?: string | null, deviceId?: string | null, params?: TrezorCallParams<EvmSignTxTrezorParams>): Promise<Response<EvmSignedTx>>;
111
111
  evmSignMessage(connectId?: string | null, deviceId?: string | null, params?: TrezorCallParams<EvmSignMsgParams>): Promise<Response<EvmSignature>>;
112
112
  evmSignTypedData(connectId?: string | null, deviceId?: string | null, params?: TrezorCallParams<EvmSignTypedDataParams>): Promise<Response<EvmSignature>>;
113
113
  btcGetAddress(connectId?: string | null, deviceId?: string | null, params?: TrezorCallParams<BtcGetAddressParams>): Promise<Response<BtcAddress>>;
@@ -204,8 +204,8 @@ declare class TrezorAdapter implements IHardwareWallet {
204
204
  *
205
205
  * Cross-process note: `fetchImpl` is a FUNCTION and cannot be serialized across
206
206
  * an IPC / postMessage boundary. Call these helpers in a network-capable
207
- * process and send only the resulting bytes (ArrayBuffer/hex) to the process
208
- * that talks to the device. Use `baseUrl` (a string) to route through your own
207
+ * process and send only the resulting hex strings to the process that talks
208
+ * to the device. Use `baseUrl` (a string) to route through your own
209
209
  * controlled proxy instead of hitting data.trezor.io directly.
210
210
  */
211
211
  /** Default upstream (Trezor). Override with `baseUrl` to use your own proxy. */
@@ -249,7 +249,7 @@ declare function buildEthereumDefinitionsForSignTx({ path, chainId, to, data, ba
249
249
  * confirmation screen and signing still completes.
250
250
  *
251
251
  * `fetchImpl` is a function and must not cross an IPC boundary — fetch in a
252
- * network-capable process and pass only the resulting bytes.
252
+ * network-capable process and pass only the resulting hex string.
253
253
  */
254
254
  /** Default upstream (Trezor). Override with `baseUrl` to use your own proxy. */
255
255
  declare const DEFAULT_SOLANA_TOKEN_DEFINITION_BASE_URL = "https://data.trezor.io/firmware/definitions/solana/token";
@@ -258,7 +258,7 @@ type FetchSolanaTokenDefinitionParams = {
258
258
  baseUrl?: string;
259
259
  fetchImpl?: FetchLike;
260
260
  };
261
- declare function fetchSolanaTokenDefinition({ tokenMint, baseUrl, fetchImpl, }: FetchSolanaTokenDefinitionParams): Promise<ArrayBuffer | undefined>;
261
+ declare function fetchSolanaTokenDefinition({ tokenMint, baseUrl, fetchImpl, }: FetchSolanaTokenDefinitionParams): Promise<string | undefined>;
262
262
 
263
263
  /**
264
264
  * SDK-global event bus. Per-runtime singleton; hosts forward events over their
package/dist/index.js CHANGED
@@ -453,6 +453,9 @@ var TrezorAdapter = class _TrezorAdapter {
453
453
  async allNetworkGetAddress(connectId, deviceId, params) {
454
454
  let liveDeviceId = "";
455
455
  const topLevelFailureIndexes = /* @__PURE__ */ new Set();
456
+ const isSingleNetworkBundle = params.bundle.every(
457
+ (item) => item.network === _optionalChain([params, 'access', _11 => _11.bundle, 'access', _12 => _12[0], 'optionalAccess', _13 => _13.network])
458
+ );
456
459
  const getLiveDeviceId = async () => {
457
460
  if (liveDeviceId) return _hwkadaptercore.success.call(void 0, liveDeviceId);
458
461
  const deviceIdResponse = await this._getTrezorDeviceId(connectId);
@@ -508,7 +511,12 @@ var TrezorAdapter = class _TrezorAdapter {
508
511
  }
509
512
  };
510
513
  },
511
- shouldAbortBundle: (_response, { index }) => topLevelFailureIndexes.has(index)
514
+ // One named boolean per abort reason.
515
+ shouldAbortBundle: (response, { index }) => {
516
+ const isSessionLevelFailure = topLevelFailureIndexes.has(index);
517
+ const isWholeChainForbidden = isSingleNetworkBundle && _optionalChain([response, 'access', _14 => _14.payload, 'optionalAccess', _15 => _15.code]) === _hwkadaptercore.HardwareErrorCode.DevicePathForbidden;
518
+ return isSessionLevelFailure || isWholeChainForbidden;
519
+ }
512
520
  });
513
521
  }
514
522
  getFeatures(connectId) {
@@ -844,7 +852,7 @@ var TrezorAdapter = class _TrezorAdapter {
844
852
  if (pending) return pending;
845
853
  const promise = (async () => {
846
854
  try {
847
- if (_optionalChain([signal, 'optionalAccess', _11 => _11.aborted])) {
855
+ if (_optionalChain([signal, 'optionalAccess', _16 => _16.aborted])) {
848
856
  throw Object.assign(new Error("Trezor connection aborted"), {
849
857
  code: _hwkadaptercore.HardwareErrorCode.UserAborted
850
858
  });
@@ -890,8 +898,8 @@ var TrezorAdapter = class _TrezorAdapter {
890
898
  passphraseMode: "prompt"
891
899
  })
892
900
  );
893
- if (_optionalChain([created, 'optionalAccess', _12 => _12.protocol]) === "thp" && !created.thpSessionId) return;
894
- if (_optionalChain([created, 'optionalAccess', _13 => _13.protocol]) !== "thp" && _optionalChain([created, 'optionalAccess', _14 => _14.protocol]) !== "v1") return;
901
+ if (_optionalChain([created, 'optionalAccess', _17 => _17.protocol]) === "thp" && !created.thpSessionId) return;
902
+ if (_optionalChain([created, 'optionalAccess', _18 => _18.protocol]) !== "thp" && _optionalChain([created, 'optionalAccess', _19 => _19.protocol]) !== "v1") return;
895
903
  const state = await this._deriveState(sessionId, signal);
896
904
  if (state !== passphraseState) {
897
905
  throw Object.assign(
@@ -905,13 +913,13 @@ var TrezorAdapter = class _TrezorAdapter {
905
913
  }
906
914
  _rememberVerifiedPassphraseSession(connectId, passphraseState, sessionId, created) {
907
915
  let session;
908
- if (_optionalChain([created, 'optionalAccess', _15 => _15.protocol]) === "thp" && typeof created.thpSessionId === "string") {
916
+ if (_optionalChain([created, 'optionalAccess', _20 => _20.protocol]) === "thp" && typeof created.thpSessionId === "string") {
909
917
  session = {
910
918
  sessionId,
911
919
  protocol: "thp",
912
920
  thpSessionId: created.thpSessionId
913
921
  };
914
- } else if (_optionalChain([created, 'optionalAccess', _16 => _16.protocol]) === "v1") {
922
+ } else if (_optionalChain([created, 'optionalAccess', _21 => _21.protocol]) === "v1") {
915
923
  session = {
916
924
  sessionId,
917
925
  protocol: "v1"
@@ -931,7 +939,7 @@ var TrezorAdapter = class _TrezorAdapter {
931
939
  }
932
940
  }
933
941
  async _reuseVerifiedPassphraseSession(connectId, sessionId, passphraseState, signal) {
934
- const cached = _optionalChain([this, 'access', _17 => _17._verifiedPassphraseSessionsByConnectId, 'access', _18 => _18.get, 'call', _19 => _19(connectId), 'optionalAccess', _20 => _20.get, 'call', _21 => _21(passphraseState)]);
942
+ const cached = _optionalChain([this, 'access', _22 => _22._verifiedPassphraseSessionsByConnectId, 'access', _23 => _23.get, 'call', _24 => _24(connectId), 'optionalAccess', _25 => _25.get, 'call', _26 => _26(passphraseState)]);
935
943
  if (!cached || cached.sessionId !== sessionId) {
936
944
  this._forgetVerifiedPassphraseSession(connectId, passphraseState);
937
945
  return false;
@@ -983,7 +991,7 @@ var TrezorAdapter = class _TrezorAdapter {
983
991
  showOnDevice: false
984
992
  })
985
993
  );
986
- const state = _optionalChain([derived, 'optionalAccess', _22 => _22.publicKey]);
994
+ const state = _optionalChain([derived, 'optionalAccess', _27 => _27.publicKey]);
987
995
  if (!state) {
988
996
  throw Object.assign(new Error("Failed to derive passphrase state (wallet public key)"), {
989
997
  code: _hwkadaptercore.HardwareErrorCode.UnknownError
@@ -1009,7 +1017,7 @@ var TrezorAdapter = class _TrezorAdapter {
1009
1017
  signal,
1010
1018
  _TrezorAdapter._callConnector(this._connector, sessionId, "getFeatures", { refresh: true })
1011
1019
  );
1012
- if (_optionalChain([features, 'optionalAccess', _23 => _23.passphrase_protection]) !== true) {
1020
+ if (_optionalChain([features, 'optionalAccess', _28 => _28.passphrase_protection]) !== true) {
1013
1021
  return _hwkadaptercore.success.call(void 0, null);
1014
1022
  }
1015
1023
  this._rememberVerifiedPassphraseSession(connectId, state, sessionId, created);
@@ -1121,12 +1129,12 @@ async function fetchEthereumDefinitions({
1121
1129
  const mode = chainId ? "chain-id" : "slip44";
1122
1130
  const id = _nullishCoalesce(chainId, () => ( slip44));
1123
1131
  const definitions = {};
1124
- const network = await fetchDefinition(`${baseUrl}/${mode}/${id}/network.dat`, fetchImpl);
1132
+ const network = await fetchDefinitionHex(`${baseUrl}/${mode}/${id}/network.dat`, fetchImpl);
1125
1133
  if (network) {
1126
1134
  definitions.encodedNetwork = network;
1127
1135
  }
1128
1136
  if (contractAddress) {
1129
- const token = await fetchDefinition(
1137
+ const token = await fetchDefinitionHex(
1130
1138
  `${baseUrl}/${mode}/${id}/token-${stripHexPrefix(contractAddress).toLowerCase()}.dat`,
1131
1139
  fetchImpl
1132
1140
  );
@@ -1167,17 +1175,20 @@ async function buildEthereumDefinitionsForSignTx({
1167
1175
  fetchImpl
1168
1176
  });
1169
1177
  }
1170
- async function fetchDefinition(url, fetchImpl) {
1178
+ async function fetchDefinitionHex(url, fetchImpl) {
1171
1179
  try {
1172
1180
  const response = await fetchImpl(url);
1173
1181
  if (response.status !== 200) {
1174
1182
  return void 0;
1175
1183
  }
1176
- return await response.arrayBuffer();
1184
+ return arrayBufferToHex(await response.arrayBuffer());
1177
1185
  } catch (e3) {
1178
1186
  return void 0;
1179
1187
  }
1180
1188
  }
1189
+ function arrayBufferToHex(value) {
1190
+ return Buffer.from(value).toString("hex");
1191
+ }
1181
1192
  function stripHexPrefix(value) {
1182
1193
  return value.startsWith("0x") || value.startsWith("0X") ? value.slice(2) : value;
1183
1194
  }
@@ -1197,7 +1208,7 @@ async function fetchSolanaTokenDefinition({
1197
1208
  if (response.status !== 200) {
1198
1209
  return void 0;
1199
1210
  }
1200
- return await response.arrayBuffer();
1211
+ return Buffer.from(await response.arrayBuffer()).toString("hex");
1201
1212
  } catch (e4) {
1202
1213
  return void 0;
1203
1214
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/hardware-js-sdk/hardware-js-sdk/packages/hwk-trezor-adapter/dist/index.js","../src/adapter/TrezorAdapter.ts","../src/utils/sdkEventBus.ts","../src/utils/debugLog.ts","../src/utils/ethereumDefinitions.ts","../src/utils/solanaTokenDefinition.ts","../src/constants.ts","../src/utils/bleIdentity.ts"],"names":[],"mappings":"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,IAAA;AACsB,IAAA;AAChB,EAAA;AACC,IAAA;AACT,EAAA;AACF;AAEwB;AACE,EAAA;AAC1B;AJygC0B;AACA;AKjpCb;AASS;AACpB,EAAA;AACU,EAAA;AACa,EAAA;AAC8C;AACrD,EAAA;AACP,IAAA;AACT,EAAA;AACI,EAAA;AACe,IAAA;AACJ,IAAA;AACJ,MAAA;AACT,IAAA;AACsB,IAAA;AAChB,EAAA;AACC,IAAA;AACT,EAAA;AACF;AL2oC0B;AACA;AMrrCS;AAEtB;AAEA;AAEmB;AACrB,EAAA;AACF,EAAA;AACC,EAAA;AACF,EAAA;AACU,EAAA;AAClB;ANorC0B;AACA;AO7rCV;AACI,EAAA;AACG,EAAA;AACvB;AAEgB;AACK,EAAA;AACK,EAAA;AAEtB,EAAA;AACoB,IAAA;AAEpB,EAAA;AAGJ;AAEgB;AACP,EAAA;AACT;AAEgB;AACM,EAAA;AACtB;AAEgB;AACP,EAAA;AACT;AAEgB;AACO,EAAA;AACJ,IAAA;AACA,IAAA;AACA,IAAA;AACjB,EAAA;AACoB,EAAA;AACtB;AAEgB;AACU,EAAA;AAC1B;APqrC0B;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-trezor-adapter/dist/index.js","sourcesContent":[null,"import {\n DEVICE,\n DeviceJobQueue,\n HardwareErrorCode,\n TypedEventEmitter,\n UI_REQUEST,\n UI_RESPONSE,\n UiRequestRegistry,\n failure,\n rehydrateConnectorError,\n runAllNetworkGetAddress,\n success,\n} from '@onekeyfe/hwk-adapter-core';\n\nimport { debugLog } from '../utils/debugLog';\n\nimport type {\n AllNetworkAddressParams,\n AllNetworkAddressResponse,\n AllNetworkGetAddressParams,\n AllNetworkMethodName,\n BtcAddress,\n BtcGetAddressParams,\n BtcGetPublicKeyParams,\n BtcPublicKey,\n BtcSignMsgParams,\n BtcSignPsbtParams,\n BtcSignTxParams,\n BtcSignature,\n BtcSignedPsbt,\n BtcSignedTx,\n ChainCapability,\n ChainForFingerprint,\n ConnectorCallResult,\n ConnectorDevice,\n ConnectorUiEvent,\n DeviceEventListener,\n DeviceInfo,\n EvmAddress,\n EvmGetAddressParams,\n EvmSignMsgParams,\n EvmSignTxParams,\n EvmSignTypedDataParams,\n EvmSignature,\n EvmSignedTx,\n HardwareEvent,\n HardwareEventMap,\n IBtcMethods,\n ICommonCallParams,\n IConnector,\n IDeviceManagerMethods,\n IEvmMethods,\n IHardwareWallet,\n ISolMethods,\n ITronMethods,\n Response,\n SolAddress,\n SolGetAddressParams,\n SolSignMsgParams,\n SolSignTxParams,\n SolSignature,\n SolSignedTx,\n TransportType,\n TrezorBrightnessParams,\n TrezorChangePinParams,\n TrezorDeviceSettingsParams,\n TronAddress,\n TronGetAddressParams,\n TronSignMsgParams,\n TronSignTxParams,\n TronSignature,\n TronSignedTx,\n UiResponseEvent,\n} from '@onekeyfe/hwk-adapter-core';\n\n// Valid HardwareErrorCode numbers. Used to reject foreign numeric `code`s (e.g.\n// a DOMException's `code: 20` on a WebUSB AbortError) that must NOT be trusted\n// as HardwareErrorCodes — otherwise they leak through as Unknown.\nconst KNOWN_HARDWARE_ERROR_CODES = new Set<number>(\n Object.values(HardwareErrorCode).filter((value): value is number => typeof value === 'number')\n);\n\ntype NullableCallArg<T> = T | null | undefined;\n\ntype TrezorPassphraseCallParams = {\n passphraseState?: string;\n useEmptyPassphrase?: boolean;\n};\n\ntype TrezorPassphraseRequestContext = {\n passphraseState?: string;\n useEmptyPassphrase?: boolean;\n};\n\ntype TrezorVerifiedPassphraseSession = {\n sessionId: string;\n protocol: 'thp' | 'v1';\n thpSessionId?: string;\n};\n\ntype TrezorCallParams<T> = (T & ICommonCallParams & TrezorPassphraseCallParams) | null | undefined;\n\ntype TrezorCommonParams = (ICommonCallParams & TrezorPassphraseCallParams) | null | undefined;\n\ntype AsyncMethodName<T> = Extract<\n {\n [K in keyof T]-?: NonNullable<T[K]> extends (\n ...args: infer _Args\n ) => Promise<Response<infer _Payload>>\n ? K\n : never;\n }[keyof T],\n string\n>;\n\ntype TrezorWalletMethods = IEvmMethods & IBtcMethods & ISolMethods & ITronMethods;\n\ntype TrezorWalletMethodName = AsyncMethodName<TrezorWalletMethods>;\n\ntype TrezorDeviceManagerMethodName = AsyncMethodName<IDeviceManagerMethods>;\n\ntype TrezorMethodName = TrezorWalletMethodName | TrezorDeviceManagerMethodName;\n\nconst TREZOR_BTC_NETWORK_COIN_MAP: Partial<Record<string, string>> = {\n btc: 'Bitcoin',\n bitcoin: 'Bitcoin',\n tbtc: 'Testnet',\n testnet: 'Testnet',\n sbtc: 'Signet',\n signet: 'Signet',\n ltc: 'Litecoin',\n litecoin: 'Litecoin',\n doge: 'Dogecoin',\n dogecoin: 'Dogecoin',\n bch: 'Bcash',\n bcash: 'Bcash',\n dash: 'Dash',\n};\n\nexport class TrezorAdapter implements IHardwareWallet {\n readonly vendor = 'trezor' as const;\n\n private readonly _connector: IConnector;\n\n private readonly _emitter = new TypedEventEmitter<HardwareEventMap>();\n\n private readonly _devices = new Map<string, DeviceInfo>();\n\n private readonly _sessions = new Map<string, string>();\n\n private readonly _connectingPromises = new Map<string, Promise<string>>();\n\n // connectIds disconnected mid-connect; the session they produce is torn down, not cached.\n private readonly _disconnectRequested = new Set<string>();\n\n private readonly _uiRegistry = new UiRequestRegistry();\n\n private readonly _passphraseRequestContextByConnectId = new Map<\n string,\n TrezorPassphraseRequestContext\n >();\n\n private readonly _verifiedPassphraseSessionsByConnectId = new Map<\n string,\n Map<string, TrezorVerifiedPassphraseSession>\n >();\n\n // Per-device queue with preemption + AbortSignal. Same-device chain calls\n // serialize (Trezor's protocol is single-request-response — interleaving\n // desyncs THP nonce). 'safe' read methods auto-cancel each other; 'confirm'\n // sign methods emit REQUEST_PREEMPTION so the consumer can decide.\n private readonly _jobQueue: DeviceJobQueue;\n\n constructor(connector: IConnector) {\n this._connector = connector;\n // Upstream DeviceJobQueue is now a global FIFO with no built-in\n // preemption — interruptibility lives at the application layer.\n this._jobQueue = new DeviceJobQueue();\n this._registerConnectorEvents();\n }\n\n private static _createDeviceBusyError(method: string): Error {\n // Our own queued request blocks this one → DeviceBusyInternal, not \"another app\".\n return Object.assign(new Error(`Trezor is busy with another request (${method})`), {\n code: HardwareErrorCode.DeviceBusyInternal,\n });\n }\n\n /**\n * Split a Trezor-only `passphraseState` routing hint off the chain params so\n * it never reaches the protobuf layer. The connector/firmware only sees the\n * real op fields; the adapter uses `passphraseState` to align the session.\n */\n private static _normalizeCallArgs(\n connectId: NullableCallArg<string>,\n deviceId: NullableCallArg<string>,\n params: NullableCallArg<unknown>\n ): {\n connectId: string;\n params: unknown;\n } {\n return {\n connectId: connectId || deviceId || '',\n params: params ?? {},\n };\n }\n\n private static _splitCommonParams(params: unknown): {\n passphraseState?: string;\n useEmptyPassphrase?: boolean;\n rest: unknown;\n } {\n if (params && typeof params === 'object') {\n const {\n passphraseState,\n autoInstallApp: _autoInstallApp,\n useEmptyPassphrase,\n ...rest\n } = params as Record<string, unknown>;\n return {\n passphraseState: typeof passphraseState === 'string' ? passphraseState : undefined,\n useEmptyPassphrase:\n typeof useEmptyPassphrase === 'boolean' ? useEmptyPassphrase : undefined,\n rest,\n };\n }\n return { rest: params ?? {} };\n }\n\n private static _withAllNetworkRequestCommonParams(\n item: AllNetworkAddressParams,\n commonParams: TrezorCommonParams\n ): AllNetworkAddressParams {\n const autoInstallApp = commonParams?.autoInstallApp;\n const passphraseState = commonParams?.passphraseState;\n const useEmptyPassphrase = commonParams?.useEmptyPassphrase;\n if (\n autoInstallApp === undefined &&\n passphraseState === undefined &&\n useEmptyPassphrase === undefined\n ) {\n return item;\n }\n return {\n ...item,\n ...(autoInstallApp !== undefined ? { autoInstallApp } : {}),\n ...(passphraseState !== undefined ? { passphraseState } : {}),\n ...(useEmptyPassphrase !== undefined ? { useEmptyPassphrase } : {}),\n };\n }\n\n private static _sanitizeForLog(value: unknown): unknown {\n if (!value || typeof value !== 'object') return value;\n if (Array.isArray(value)) {\n return value.map(item => TrezorAdapter._sanitizeForLog(item));\n }\n const sensitiveKeys = new Set([\n 'credential',\n 'credentials',\n 'host_static_key',\n 'passphrase',\n 'passphraseState',\n 'pin',\n 'trezor_static_public_key',\n ]);\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, item]) => [\n key,\n sensitiveKeys.has(key) ? '[redacted]' : TrezorAdapter._sanitizeForLog(item),\n ])\n );\n }\n\n private static _errorForLog(error: unknown): unknown {\n if (!error || typeof error !== 'object') return error;\n const typed = error as {\n code?: unknown;\n errorCode?: unknown;\n message?: unknown;\n name?: unknown;\n response?: unknown;\n statusCode?: unknown;\n };\n return TrezorAdapter._sanitizeForLog({\n name: typed.name,\n message: typed.message,\n code: typed.code,\n errorCode: typed.errorCode,\n statusCode: typed.statusCode,\n response: typed.response,\n });\n }\n\n private _setPassphraseRequestContext(\n connectId: string,\n context: TrezorPassphraseRequestContext\n ): () => void {\n const previous = this._passphraseRequestContextByConnectId.get(connectId);\n if (context.passphraseState !== undefined || context.useEmptyPassphrase !== undefined) {\n this._passphraseRequestContextByConnectId.set(connectId, context);\n } else {\n this._passphraseRequestContextByConnectId.delete(connectId);\n }\n return () => {\n if (previous) {\n this._passphraseRequestContextByConnectId.set(connectId, previous);\n } else {\n this._passphraseRequestContextByConnectId.delete(connectId);\n }\n };\n }\n\n private static _trezorFailureMessage(error: unknown): {\n code?: unknown;\n message?: unknown;\n } {\n const response = (error as { response?: unknown } | null | undefined)?.response;\n const message = (response as { message?: unknown } | null | undefined)?.message;\n if (!message || typeof message !== 'object') return {};\n const failureMessage = message as { code?: unknown; message?: unknown };\n return {\n code: failureMessage.code,\n message: failureMessage.message,\n };\n }\n\n private static _mapTrezorFailureCode(error: unknown): HardwareErrorCode | undefined {\n const directCode = (error as { code?: unknown } | null | undefined)?.code;\n if (directCode === 'Device_InitializeFailed') {\n return HardwareErrorCode.PinCancelled;\n }\n if (directCode === 'Failure_ActionCancelled') {\n return HardwareErrorCode.UserRejected;\n }\n if (directCode === 'ThpPairingRequired') {\n return HardwareErrorCode.ThpPairingRequired;\n }\n if (directCode === 'Failure_UnexpectedMessage') {\n return HardwareErrorCode.MethodNotSupported;\n }\n const message = (error as { message?: unknown } | null | undefined)?.message;\n if (\n typeof message === 'string' &&\n message.includes(\"Failed to execute 'transfer\") &&\n message.includes(\"on 'USBDevice'\")\n ) {\n return HardwareErrorCode.TransportError;\n }\n const failure = TrezorAdapter._trezorFailureMessage(error);\n if (failure.code === 'Failure_PinCancelled') {\n return HardwareErrorCode.PinCancelled;\n }\n if (failure.code === 'Failure_PinInvalid') {\n return HardwareErrorCode.PinInvalid;\n }\n if (failure.code === 'Failure_ActionCancelled') {\n return HardwareErrorCode.UserRejected;\n }\n if (failure.code === 'Failure_ProcessError' && failure.message === 'Unsupported script type') {\n return HardwareErrorCode.MethodNotSupported;\n }\n // Device rejected the derivation path (e.g. an index outside its allowed\n // range) — distinct path-specific surface, not a generic \"method\" error.\n if (failure.code === 'Failure_DataError' && failure.message === 'Forbidden key path') {\n return HardwareErrorCode.DevicePathForbidden;\n }\n // Firmware can't process this request (e.g. EIP-712 typed data the device\n // firmware doesn't support) → surface as \"method not supported\".\n if (failure.code === 'Failure_FirmwareError') {\n return HardwareErrorCode.MethodNotSupported;\n }\n // Device firmware doesn't recognize the message (e.g. an older device asked\n // for a coin/app it lacks) → \"method not supported\", not a generic unknown.\n if (failure.code === 'Failure_UnexpectedMessage') {\n return HardwareErrorCode.MethodNotSupported;\n }\n if (failure.code === 'Failure_NotInitialized') {\n return HardwareErrorCode.DeviceNotInitialized;\n }\n // Device busy with its own op, not another app → DeviceBusyInternal.\n if (failure.code === 'Failure_Busy' || failure.code === 'Failure_InProgress') {\n return HardwareErrorCode.DeviceBusyInternal;\n }\n return undefined;\n }\n\n /**\n * Whether a device-side error code means the THP application session we\n * selected is gone (the device evicted it from its limited slot pool). The\n * caller drops the stale cache entry and recreates from scratch.\n *\n * NOTE: the exact eviction code still needs real-device confirmation — match\n * conservatively so a genuine error isn't mistaken for an evicted session\n * (which would silently re-prompt the passphrase).\n */\n private static _isStaleSessionError(code: unknown): boolean {\n if (typeof code !== 'string') return false;\n return (\n code === 'ThpUnallocatedChannel' ||\n /invalid.?session|unallocated.?session|session.?not.?found/i.test(code)\n );\n }\n\n private static _errorCode(error: unknown): unknown {\n return (error as { code?: unknown }).code ?? TrezorAdapter._trezorFailureMessage(error).code;\n }\n\n private static _isConnectionUnavailableError(error: unknown): boolean {\n const { code } = error as { code?: unknown };\n return (\n code === HardwareErrorCode.DeviceNotFound || code === HardwareErrorCode.DeviceDisconnected\n );\n }\n\n /**\n * Race a promise against an abort signal. Copied from LedgerAdapter:\n * IConnector.call() can't actually be cancelled at the protocol level, but\n * the caller gets the abort immediately and the underlying work completes\n * uselessly in the background.\n */\n private static _abortable<T>(signal: AbortSignal, promise: Promise<T>): Promise<T> {\n if (signal.aborted) {\n return Promise.reject(\n (signal as AbortSignal & { reason?: unknown }).reason ?? new Error('Aborted')\n );\n }\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n reject((signal as AbortSignal & { reason?: unknown }).reason ?? new Error('Aborted'));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n value => {\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n err => {\n signal.removeEventListener('abort', onAbort);\n reject(err);\n }\n );\n });\n }\n\n private async _connectSession(connectId: string, signal?: AbortSignal): Promise<string> {\n const connectPromise = this._connector.connect(connectId);\n const session = await (async () => {\n if (!signal) return connectPromise;\n try {\n return await TrezorAdapter._abortable(signal, connectPromise);\n } catch (error) {\n // _abortable rejected (abort/failure) but the underlying connect keeps\n // running — tear down any session it still resolves so it isn't orphaned.\n void connectPromise.then(\n orphan => this._connector.disconnect(orphan.sessionId).catch(() => undefined),\n () => undefined\n );\n throw error;\n }\n })();\n // disconnectDevice() ran mid-connect: tear down the now-unwanted session\n // instead of caching it (else it leaks a limited THP slot).\n if (this._disconnectRequested.delete(connectId)) {\n await this._connector.disconnect(session.sessionId).catch(() => undefined);\n throw Object.assign(new Error('Trezor connection aborted'), {\n code: HardwareErrorCode.UserAborted,\n });\n }\n this._sessions.set(connectId, session.sessionId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n this._devices.set(connectId, session.deviceInfo);\n return session.sessionId;\n }\n\n get activeTransport(): TransportType | null {\n return this._connector.connectionType;\n }\n\n async init(_config?: unknown): Promise<void> {}\n\n async dispose(): Promise<void> {\n this._unregisterConnectorEvents();\n this._uiRegistry.reset();\n this._jobQueue.clear();\n this._connector.reset();\n this._devices.clear();\n this._sessions.clear();\n this._verifiedPassphraseSessionsByConnectId.clear();\n this._connectingPromises.clear();\n this._emitter.removeAllListeners();\n }\n\n /**\n * Clear cached state without tearing down the adapter or unregistering\n * listeners. Mirrors LedgerAdapter.resetState() — useful for retry-after-\n * error flows. Aborts active jobs and releases UI waits.\n */\n resetState(): void {\n this._uiRegistry.reset();\n this._jobQueue.clear();\n this._devices.clear();\n this._sessions.clear();\n this._verifiedPassphraseSessionsByConnectId.clear();\n this._connectingPromises.clear();\n }\n\n getAvailableTransports(): TransportType[] {\n return this.activeTransport ? [this.activeTransport] : [];\n }\n\n async switchTransport(_type: TransportType): Promise<void> {}\n\n async searchDevices(options?: { waitForAllTransports?: boolean }): Promise<DeviceInfo[]> {\n await this._ensureDevicePermission();\n const scanned = await this._connector.searchDevices(\n options?.waitForAllTransports ? { waitForAll: true } : undefined\n );\n const scannedIds = new Set(scanned.map(d => d.connectId));\n // A rescan that misses a currently-connected device shouldn't evict it —\n // otherwise getDeviceInfo would return DeviceNotFound for an active session.\n for (const connectId of [...this._devices.keys()]) {\n if (!scannedIds.has(connectId) && !this._sessions.has(connectId)) {\n this._devices.delete(connectId);\n }\n }\n for (const device of scanned) {\n const info = this._connectorDeviceToDeviceInfo(device);\n this._devices.set(info.connectId, info);\n }\n return Array.from(this._devices.values());\n }\n\n async connectDevice(connectId: string): Promise<Response<string>> {\n try {\n await this._ensureDevicePermission(connectId);\n await this._ensureSession(connectId);\n return success(connectId);\n } catch (error) {\n return this._errorToFailure(error);\n }\n }\n\n async disconnectDevice(connectId: string): Promise<void> {\n const connecting = this._connectingPromises.has(connectId);\n this._connectingPromises.delete(connectId);\n const sessionId = this._sessions.get(connectId);\n if (!sessionId) {\n // Connect may be in flight (session not recorded yet) — mark it so\n // _connectSession tears down the session it produces instead of caching it.\n if (connecting) this._disconnectRequested.add(connectId);\n return;\n }\n this._sessions.delete(connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n await this._connector.disconnect(sessionId);\n }\n\n async getDeviceInfo(connectId: string, deviceId: string): Promise<Response<DeviceInfo>> {\n const device =\n this._devices.get(connectId) ??\n Array.from(this._devices.values()).find(item => item.deviceId === deviceId);\n if (!device) return failure(HardwareErrorCode.DeviceNotFound, 'Trezor device not found');\n return success(device);\n }\n\n getSupportedChains(): ChainCapability[] {\n // Keep in sync with TrezorConnectorBase.call()'s switch.\n // Chain inclusion means \"at least one method wired\" — per-method gaps:\n // sol: signMessage is explicitly NotSupported (firmware doesn't ship it).\n // tron: signMessage same. signTransaction uses the multi-step\n // TronContractRequest flow.\n return ['btc', 'evm', 'sol', 'tron'];\n }\n\n async allNetworkGetAddress(\n connectId: string,\n deviceId: string,\n params: AllNetworkGetAddressParams\n ): Promise<Response<AllNetworkAddressResponse[]>> {\n let liveDeviceId = '';\n const topLevelFailureIndexes = new Set<number>();\n const getLiveDeviceId = async (): Promise<Response<string>> => {\n if (liveDeviceId) return success(liveDeviceId);\n const deviceIdResponse = await this._getTrezorDeviceId(connectId);\n if (deviceIdResponse.success) {\n liveDeviceId = deviceIdResponse.payload;\n }\n return deviceIdResponse;\n };\n\n return runAllNetworkGetAddress({\n connectId,\n deviceId,\n params,\n normalizeItem: TrezorAdapter._normalizeAllNetworkItem,\n callItem: async ({ method, item, index }) => {\n const expectedDeviceId = TrezorAdapter._getItemDeviceId(item) ?? deviceId;\n if (expectedDeviceId) {\n const fingerprint = await getLiveDeviceId();\n if (!fingerprint.success) {\n topLevelFailureIndexes.add(index);\n return fingerprint;\n }\n if (expectedDeviceId !== fingerprint.payload) {\n topLevelFailureIndexes.add(index);\n return failure(\n HardwareErrorCode.DeviceMismatch,\n `Wrong device: expected ${expectedDeviceId}, got ${fingerprint.payload}`,\n { expected: expectedDeviceId, actual: fingerprint.payload }\n );\n }\n }\n const callItem = TrezorAdapter._withAllNetworkRequestCommonParams(item, params);\n return this._callAllNetworkMethod(connectId, method, callItem);\n },\n attachIdentity: async ({ item, chain, payload }) => {\n if (!liveDeviceId) {\n const fingerprint = await getLiveDeviceId();\n if (!fingerprint.success) {\n return { ...item, success: false, payload: fingerprint.payload };\n }\n }\n return {\n ...item,\n success: true,\n payload: {\n ...payload,\n deviceIdentity: {\n vendor: 'trezor',\n type: 'deviceId',\n value: liveDeviceId,\n },\n chainFingerprint: liveDeviceId,\n chainFingerprintChain: chain,\n },\n };\n },\n shouldAbortBundle: (_response, { index }) => topLevelFailureIndexes.has(index),\n });\n }\n\n getFeatures(connectId: string): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>('getFeatures', connectId, {});\n }\n\n deviceSettings(\n connectId: string,\n params: TrezorDeviceSettingsParams\n ): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>(\n 'deviceSettings',\n connectId,\n params\n );\n }\n\n setBrightness(\n connectId: string,\n params: TrezorBrightnessParams = {}\n ): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>(\n 'setBrightness',\n connectId,\n params\n );\n }\n\n changePin(\n connectId: string,\n params: TrezorChangePinParams = {}\n ): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>('changePin', connectId, params);\n }\n\n wipeDevice(connectId: string): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>('wipeDevice', connectId, {});\n }\n\n private async _getTrezorDeviceId(connectId: string): Promise<Response<string>> {\n const features = await this.getFeatures(connectId);\n if (!features.success) return features;\n const liveDeviceId = features.payload.device_id;\n if (typeof liveDeviceId !== 'string' || liveDeviceId.length === 0) {\n return failure(HardwareErrorCode.UnknownError, 'Trezor features did not include a device_id');\n }\n return success(liveDeviceId);\n }\n\n cancel(connectId?: string): void {\n const userAbortReason = Object.assign(new Error('User aborted operation'), {\n code: HardwareErrorCode.UserAborted,\n });\n // Release adapter-level UI waits (preemption) and connector-level ones\n // (THP pairing / PIN matrix) — a single CANCEL clears whichever is open.\n this._uiRegistry.cancel();\n this._connector.uiResponse({ type: UI_RESPONSE.CANCEL });\n if (connectId) {\n this._jobQueue.forceCancelActive(connectId, userAbortReason);\n void this._connector.cancel(this._sessions.get(connectId) ?? connectId);\n return;\n }\n for (const cid of this._sessions.keys()) {\n this._jobQueue.forceCancelActive(cid, userAbortReason);\n }\n for (const sessionId of this._sessions.values()) {\n void this._connector.cancel(sessionId);\n }\n }\n\n /**\n * Routes to BOTH the adapter's local UI registry (preemption decisions,\n * future SELECT_DEVICE / DEVICE_PERMISSION) AND the connector's registry\n * (THP pairing tag, PIN matrix). Each side ignores types it isn't waiting\n * for, so double-routing is harmless.\n */\n uiResponse(response: UiResponseEvent): void {\n this._uiRegistry.resolve(response.type, response.payload);\n this._connector.uiResponse(response);\n }\n\n /**\n * Returns a stable per-seed identifier suitable for device-match verification.\n *\n * Trezor exposes `device_id` in Features — a server-generated UUID written\n * during `wipe_device` and stable for the life of the seed. Unlike Ledger\n * (no native id, so a per-chain address is hashed), Trezor's id is global\n * across chains, so the `chain` argument is accepted for API parity but\n * ignored. For unsupported chains we still surface the id (since it would\n * be the same value anyway).\n */\n async getChainFingerprint(\n connectId: string,\n _deviceId: string,\n _chain: ChainForFingerprint\n ): Promise<Response<string>> {\n return this._getTrezorDeviceId(connectId);\n }\n\n /**\n * Resolve the active passphrase wallet identity (`passphraseState`).\n * See {@link IHardwareWallet.getPassphraseState} for the discover/verify\n * semantics. Returns `null` for a standard wallet (no passphrase protection) —\n * there's nothing to pin. Serialized through the per-device job queue so it\n * can't interleave with a chain call on the same device (which would desync\n * the THP session selection).\n */\n getPassphraseState(\n connectId: string,\n passphraseState?: string\n ): Promise<Response<string | null>> {\n return this._jobQueue\n .enqueue(\n connectId,\n async signal => {\n const restorePassphraseRequestContext = this._setPassphraseRequestContext(connectId, {\n passphraseState,\n });\n try {\n return await this._resolvePassphraseState(connectId, passphraseState, signal);\n } finally {\n restorePassphraseRequestContext();\n }\n },\n {\n label: 'getPassphraseState',\n rejectIfBusy: true,\n busyError: TrezorAdapter._createDeviceBusyError('getPassphraseState'),\n }\n )\n .catch(error => this._errorToFailure(error));\n }\n\n evmGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmGetAddressParams>\n ) {\n return this._callWalletMethod<EvmAddress>('evmGetAddress', connectId, deviceId, params);\n }\n\n evmSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmSignTxParams>\n ) {\n return this._callWalletMethod<EvmSignedTx>('evmSignTransaction', connectId, deviceId, params);\n }\n\n evmSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmSignMsgParams>\n ) {\n return this._callWalletMethod<EvmSignature>('evmSignMessage', connectId, deviceId, params);\n }\n\n evmSignTypedData(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmSignTypedDataParams>\n ) {\n return this._callWalletMethod<EvmSignature>('evmSignTypedData', connectId, deviceId, params);\n }\n\n btcGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcGetAddressParams>\n ) {\n return this._callWalletMethod<BtcAddress>('btcGetAddress', connectId, deviceId, params);\n }\n\n btcGetPublicKey(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcGetPublicKeyParams>\n ) {\n return this._callWalletMethod<BtcPublicKey>('btcGetPublicKey', connectId, deviceId, params);\n }\n\n btcSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcSignTxParams>\n ) {\n return this._callWalletMethod<BtcSignedTx>('btcSignTransaction', connectId, deviceId, params);\n }\n\n btcSignPsbt(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcSignPsbtParams>\n ) {\n return this._callWalletMethod<BtcSignedPsbt>('btcSignPsbt', connectId, deviceId, params);\n }\n\n btcSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcSignMsgParams>\n ) {\n return this._callWalletMethod<BtcSignature>('btcSignMessage', connectId, deviceId, params);\n }\n\n btcGetMasterFingerprint(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCommonParams\n ) {\n return this._callWalletMethod<{ masterFingerprint: string }>(\n 'btcGetMasterFingerprint',\n connectId,\n deviceId,\n params\n );\n }\n\n solGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<SolGetAddressParams>\n ) {\n return this._callWalletMethod<SolAddress>('solGetAddress', connectId, deviceId, params);\n }\n\n solSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<SolSignTxParams>\n ) {\n return this._callWalletMethod<SolSignedTx>('solSignTransaction', connectId, deviceId, params);\n }\n\n solSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<SolSignMsgParams>\n ) {\n return this._callWalletMethod<SolSignature>('solSignMessage', connectId, deviceId, params);\n }\n\n tronGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<TronGetAddressParams>\n ) {\n return this._callWalletMethod<TronAddress>('tronGetAddress', connectId, deviceId, params);\n }\n\n tronSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<TronSignTxParams>\n ) {\n return this._callWalletMethod<TronSignedTx>('tronSignTransaction', connectId, deviceId, params);\n }\n\n tronSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<TronSignMsgParams>\n ) {\n return this._callWalletMethod<TronSignature>('tronSignMessage', connectId, deviceId, params);\n }\n\n private static _unwrapConnectorResult(result: unknown): unknown {\n if (\n result &&\n typeof result === 'object' &&\n 'success' in result &&\n (((result as ConnectorCallResult).success === true && 'payload' in result) ||\n ((result as ConnectorCallResult).success === false && 'error' in result))\n ) {\n const connectorResult = result as ConnectorCallResult;\n if (connectorResult.success) return connectorResult.payload;\n throw rehydrateConnectorError(connectorResult.error);\n }\n return result;\n }\n\n private static async _callConnector(\n connector: IConnector,\n sessionId: string,\n method: string,\n params: unknown,\n signal?: AbortSignal\n ): Promise<unknown> {\n const promise = connector.call(sessionId, method, params);\n const result = signal ? await TrezorAdapter._abortable(signal, promise) : await promise;\n return TrezorAdapter._unwrapConnectorResult(result);\n }\n\n private static _normalizeAllNetworkItem(\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ): AllNetworkAddressParams {\n if (method !== 'btcGetAddress' && method !== 'btcGetPublicKey') {\n return item;\n }\n\n const itemWithCoin = item as AllNetworkAddressParams & { coin?: unknown };\n if (itemWithCoin.coin) {\n return item;\n }\n\n const network = item.network.toLowerCase();\n return {\n ...item,\n coin: TREZOR_BTC_NETWORK_COIN_MAP[network] ?? item.network,\n };\n }\n\n private static _getItemDeviceId(item: AllNetworkAddressParams): string | undefined {\n const { deviceId } = item as { deviceId?: unknown };\n return typeof deviceId === 'string' && deviceId.length > 0 ? deviceId : undefined;\n }\n\n private _callAllNetworkMethod(\n connectId: string,\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ): Promise<Response<unknown>> {\n switch (method) {\n case 'evmGetAddress':\n return this.evmGetAddress(connectId, '', item);\n case 'btcGetAddress':\n return this.btcGetAddress(connectId, '', item);\n case 'btcGetPublicKey':\n return this.btcGetPublicKey(connectId, '', item);\n case 'solGetAddress':\n return this.solGetAddress(connectId, '', item);\n case 'tronGetAddress':\n return this.tronGetAddress(connectId, '', item);\n default:\n return Promise.resolve(\n failure(\n HardwareErrorCode.InvalidParams,\n `Unsupported allNetwork method: ${String(method)}`\n )\n );\n }\n }\n\n on<K extends keyof HardwareEventMap>(\n event: K,\n listener: (event: HardwareEventMap[K]) => void\n ): void;\n\n on(event: string, listener: DeviceEventListener): void;\n\n on(event: string, listener: (event: HardwareEvent) => void): void {\n this._emitter.on(event, listener);\n }\n\n off<K extends keyof HardwareEventMap>(\n event: K,\n listener: (event: HardwareEventMap[K]) => void\n ): void;\n\n off(event: string, listener: DeviceEventListener): void;\n\n off(event: string, listener: (event: HardwareEvent) => void): void {\n this._emitter.off(event, listener);\n }\n\n private _callWalletMethod<T>(\n methodName: TrezorWalletMethodName,\n connectId: NullableCallArg<string>,\n deviceId: NullableCallArg<string>,\n params: NullableCallArg<unknown>\n ): Promise<Response<T>> {\n return this._callMethod<T>(methodName, connectId, deviceId, params, true);\n }\n\n private _callDeviceManagerMethod<T>(\n methodName: TrezorDeviceManagerMethodName,\n connectId: NullableCallArg<string>,\n params: NullableCallArg<unknown>\n ): Promise<Response<T>> {\n return this._callMethod<T>(methodName, connectId, undefined, params, false);\n }\n\n private async _callMethod<T>(\n methodName: TrezorMethodName,\n connectId: NullableCallArg<string>,\n deviceId: NullableCallArg<string>,\n params: NullableCallArg<unknown>,\n requiresWalletIntent: boolean\n ): Promise<Response<T>> {\n const call = TrezorAdapter._normalizeCallArgs(connectId, deviceId, params);\n debugLog('[TrezorAdapter][REQ]', {\n method: methodName,\n connectId: call.connectId || '(empty)',\n deviceId: deviceId || undefined,\n params: TrezorAdapter._sanitizeForLog(call.params),\n });\n try {\n const response = await this._jobQueue.enqueue(\n call.connectId,\n signal =>\n this._callWithRetry<T>(\n call.connectId,\n methodName,\n call.params,\n requiresWalletIntent,\n true,\n signal\n ),\n {\n label: methodName,\n rejectIfBusy: true,\n busyError: TrezorAdapter._createDeviceBusyError(methodName),\n }\n );\n debugLog('[TrezorAdapter][RES]', {\n method: methodName,\n success: response.success,\n payload: TrezorAdapter._sanitizeForLog(response.payload),\n });\n return response;\n } catch (error) {\n // The only way a Promise rejects out of `enqueue` is the busy-reject —\n // _callWithRetry never throws, it returns Response.failure. Convert to\n // the Response shape so chain method callers stay uniform.\n const response = this._errorToFailure(error);\n debugLog('[TrezorAdapter][RES]', {\n method: methodName,\n success: false,\n payload: TrezorAdapter._sanitizeForLog(response.payload),\n });\n return response;\n }\n }\n\n private async _callWithRetry<T>(\n connectId: string,\n methodName: TrezorMethodName,\n params: unknown,\n requiresWalletIntent: boolean,\n allowRetry: boolean,\n signal: AbortSignal\n ): Promise<Response<T>> {\n const { passphraseState, useEmptyPassphrase, rest } = TrezorAdapter._splitCommonParams(params);\n const restorePassphraseRequestContext = this._setPassphraseRequestContext(connectId, {\n passphraseState,\n useEmptyPassphrase,\n });\n try {\n const sessionId = await this._ensureSession(connectId, signal);\n if (requiresWalletIntent && !passphraseState && useEmptyPassphrase !== true) {\n return failure(\n HardwareErrorCode.InvalidParams,\n `Trezor ${methodName} requires an explicit wallet intent: passphraseState or useEmptyPassphrase`\n );\n }\n // Pin the call to the requested passphrase wallet. For THP this creates\n // a new application session; for v1 it re-initializes the device session.\n // Runs inside this queued job so the session alignment and the call can't\n // be interleaved by another request.\n if (passphraseState) {\n await TrezorAdapter._abortable(\n signal,\n this._alignAppSession(connectId, sessionId, passphraseState, signal)\n );\n } else if (useEmptyPassphrase === true) {\n await TrezorAdapter._abortable(signal, this._createFreshAppSession(sessionId, signal));\n }\n const result = await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, methodName, rest)\n );\n return success(result as T);\n } catch (error) {\n // If we were aborted, surface as-is — don't take the retry/recovery path.\n if (signal.aborted) {\n return this._errorToFailure(error);\n }\n const code = TrezorAdapter._errorCode(error);\n // On a transient disconnect (BLE drop, \"device not connected\" race after\n // the device-disconnect event hasn't propagated yet), drop the stale\n // session and reconnect once. Matches Ledger's _retryWithFreshConnection.\n if (allowRetry && code === HardwareErrorCode.DeviceDisconnected) {\n this._sessions.delete(connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n return await this._callWithRetry<T>(\n connectId,\n methodName,\n params,\n requiresWalletIntent,\n false,\n signal\n );\n }\n // The device evicted the passphrase session created for this call. Retry\n // once and recreate the requested wallet context.\n if (\n allowRetry &&\n (passphraseState || useEmptyPassphrase === true) &&\n TrezorAdapter._isStaleSessionError(code)\n ) {\n if (passphraseState) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n }\n return await this._callWithRetry<T>(\n connectId,\n methodName,\n params,\n requiresWalletIntent,\n false,\n signal\n );\n }\n debugLog('[TrezorAdapter][ERROR]', {\n method: methodName,\n connectId,\n error: TrezorAdapter._errorForLog(error),\n });\n return this._errorToFailure(error);\n } finally {\n restorePassphraseRequestContext();\n }\n }\n\n private async _ensureSession(connectId: string, signal?: AbortSignal): Promise<string> {\n const existing = this._sessions.get(connectId);\n if (existing) return existing;\n\n const pending = this._connectingPromises.get(connectId);\n if (pending) return pending;\n\n const promise = (async () => {\n try {\n if (signal?.aborted) {\n throw Object.assign(new Error('Trezor connection aborted'), {\n code: HardwareErrorCode.UserAborted,\n });\n }\n // Fail fast: a single connect attempt. On an \"unavailable device\" error we\n // drop the cached session/passphrase state and rethrow (no retry loop).\n try {\n return await this._connectSession(connectId, signal);\n } catch (error) {\n if (TrezorAdapter._isConnectionUnavailableError(error)) {\n this._sessions.delete(connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n }\n throw error;\n }\n } finally {\n this._connectingPromises.delete(connectId);\n this._disconnectRequested.delete(connectId);\n }\n })();\n\n this._connectingPromises.set(connectId, promise);\n return promise;\n }\n\n /**\n * Pin the device's active wallet session to `passphraseState` (the target\n * wallet identity) before a wallet-bound op. THP has an app-session id; v1\n * does not, but it still binds passphrase to the device session, so the\n * connector re-initializes v1 before we derive and verify.\n *\n * SECURITY: a verified THP app session may be selected again, but the adapter\n * still derives and verifies the passphrase state before any chain method can\n * run. If the cache is stale, fall back to creating a fresh wallet context.\n */\n private async _alignAppSession(\n connectId: string,\n sessionId: string,\n passphraseState: string,\n signal: AbortSignal\n ): Promise<void> {\n const reused = await this._reuseVerifiedPassphraseSession(\n connectId,\n sessionId,\n passphraseState,\n signal\n );\n if (reused) return;\n\n const created = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpCreateSession', {\n passphraseMode: 'prompt',\n })\n )) as { protocol?: string; thpSessionId?: string | null };\n // v1 has no host-managed app-session id, but the connector has just\n // re-initialized a fresh device session; continue with reactive\n // passphrase-state verification.\n if (created?.protocol === 'thp' && !created.thpSessionId) return;\n if (created?.protocol !== 'thp' && created?.protocol !== 'v1') return;\n const state = await this._deriveState(sessionId, signal);\n if (state !== passphraseState) {\n throw Object.assign(\n new Error(\n `Passphrase produced wallet ${state}, expected ${passphraseState} (passphraseState mismatch)`\n ),\n { code: HardwareErrorCode.PassphraseStateMismatch }\n );\n }\n this._rememberVerifiedPassphraseSession(connectId, passphraseState, sessionId, created);\n }\n\n private _rememberVerifiedPassphraseSession(\n connectId: string,\n passphraseState: string,\n sessionId: string,\n created: { protocol?: string; thpSessionId?: string | null } | undefined\n ): void {\n let session: TrezorVerifiedPassphraseSession | undefined;\n if (created?.protocol === 'thp' && typeof created.thpSessionId === 'string') {\n session = {\n sessionId,\n protocol: 'thp',\n thpSessionId: created.thpSessionId,\n };\n } else if (created?.protocol === 'v1') {\n session = {\n sessionId,\n protocol: 'v1',\n };\n }\n if (!session) return;\n\n const sessions =\n this._verifiedPassphraseSessionsByConnectId.get(connectId) ??\n new Map<string, TrezorVerifiedPassphraseSession>();\n sessions.set(passphraseState, session);\n this._verifiedPassphraseSessionsByConnectId.set(connectId, sessions);\n }\n\n private _forgetVerifiedPassphraseSession(connectId: string, passphraseState: string): void {\n const sessions = this._verifiedPassphraseSessionsByConnectId.get(connectId);\n if (!sessions) return;\n sessions.delete(passphraseState);\n if (!sessions.size) {\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n }\n }\n\n private async _reuseVerifiedPassphraseSession(\n connectId: string,\n sessionId: string,\n passphraseState: string,\n signal: AbortSignal\n ): Promise<boolean> {\n const cached = this._verifiedPassphraseSessionsByConnectId.get(connectId)?.get(passphraseState);\n if (!cached || cached.sessionId !== sessionId) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n return false;\n }\n\n try {\n if (cached.protocol === 'thp') {\n if (!cached.thpSessionId) return false;\n await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpSelectSession', {\n thpSessionId: cached.thpSessionId,\n })\n );\n }\n const state = await this._deriveState(sessionId, signal);\n if (state !== passphraseState) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n return false;\n }\n return true;\n } catch (error) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n if (signal.aborted) throw error;\n return false;\n }\n }\n\n private async _createFreshAppSession(sessionId: string, signal: AbortSignal): Promise<void> {\n // Create a fresh standard-wallet context for this call. Empty passphrase is\n // enforced inside connector/core, not delegated to host UI handlers.\n await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpCreateSession', {\n passphraseMode: 'empty',\n })\n );\n }\n\n /**\n * Derive the active session's passphrase state — the wallet identity used to\n * verify the right wallet is active: the compressed PUBLIC KEY at a fixed\n * account path (m/44'/0'/0'). It comes from the SAME GetPublicKey that also\n * carries the 4-byte fingerprint, but we use the FULL pubkey (not the truncated\n * fingerprint) so it's collision-resistant — the address we return can never\n * come from the wrong wallet — while avoiding OneKey's extra Testnet GetAddress.\n * Non-interactive (also unlocks via PIN as a protected derivation).\n */\n private async _deriveState(sessionId: string, signal: AbortSignal): Promise<string> {\n const derived = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, 'btcGetPublicKey', {\n path: \"m/44'/0'/0'\",\n showOnDevice: false,\n })\n )) as { publicKey?: string };\n const state = derived?.publicKey;\n if (!state) {\n throw Object.assign(new Error('Failed to derive passphrase state (wallet public key)'), {\n code: HardwareErrorCode.UnknownError,\n });\n }\n return state;\n }\n\n private async _resolvePassphraseState(\n connectId: string,\n passphraseState: string | undefined,\n signal: AbortSignal\n ): Promise<Response<string | null>> {\n try {\n const sessionId = await this._ensureSession(connectId, signal);\n if (passphraseState) {\n // Verify mode: align (which always re-derives + confirms the state) so the\n // host can gate signing on the correct wallet being active.\n await this._alignAppSession(connectId, sessionId, passphraseState, signal);\n return success(passphraseState);\n }\n // Discover mode (OneKey-aligned). DON'T trust pre-read features — a LOCKED\n // device reports an unreliable `passphrase_protection`, and the connector's\n // plain getFeatures returns a CACHED blob, so checking `unlocked` up front\n // is meaningless. Instead derive first (which unlocks), then re-read fresh:\n // 1. Create a session + derive the state. This UNLOCKS the device (PIN) and,\n // for a passphrase wallet, prompts the passphrase (THP: proactively in\n // ThpCreateNewSession; v1: reactively).\n // 2. Re-read features FRESH from the device (now unlocked → trustworthy).\n // 3. passphrase_protection === true → return the current passphrase\n // state, even if the entered passphrase was empty. Otherwise →\n // standard wallet → return null (OneKey-aligned).\n const created = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpCreateSession', {\n passphraseMode: 'prompt',\n })\n )) as { protocol?: string; thpSessionId?: string | null };\n const state = await this._deriveState(sessionId, signal);\n const features = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, 'getFeatures', { refresh: true })\n )) as Record<string, unknown> | undefined;\n if (features?.passphrase_protection !== true) {\n // Standard wallet — discard the derived state, return null (OneKey convention).\n return success(null);\n }\n this._rememberVerifiedPassphraseSession(connectId, state, sessionId, created);\n return success(state);\n } catch (error) {\n return this._errorToFailure(error);\n }\n }\n\n private _onDeviceConnect = (data: { device: ConnectorDevice }): void => {\n const device = this._connectorDeviceToDeviceInfo(data.device);\n this._devices.set(device.connectId, device);\n this._emitter.emit(DEVICE.CONNECT, { type: DEVICE.CONNECT, payload: device });\n };\n\n private _onDeviceDisconnect = (data: { connectId: string }): void => {\n this._sessions.delete(data.connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(data.connectId);\n this._devices.delete(data.connectId);\n this._emitter.emit(DEVICE.DISCONNECT, {\n type: DEVICE.DISCONNECT,\n payload: { connectId: data.connectId },\n });\n };\n\n private _onSupportFeatures = (data: {\n device: ConnectorDevice & { features: Record<string, unknown> };\n }): void => {\n const device = {\n ...this._connectorDeviceToDeviceInfo(data.device),\n features: data.device.features,\n };\n this._emitter.emit(DEVICE.FEATURES, {\n type: DEVICE.FEATURES,\n device,\n payload: { device },\n });\n };\n\n private _onUiRequest = (data: { type: string; payload?: unknown }): void => {\n if (data.type === UI_REQUEST.REQUEST_PASSPHRASE) {\n const payload =\n data.payload && typeof data.payload === 'object'\n ? (data.payload as Record<string, unknown>)\n : {};\n const connectId = typeof payload.connectId === 'string' ? payload.connectId : undefined;\n const context = connectId\n ? this._passphraseRequestContextByConnectId.get(connectId)\n : undefined;\n this._emitter.emit(\n data.type as keyof HardwareEventMap,\n {\n ...data,\n payload: {\n ...payload,\n ...(context?.passphraseState !== undefined\n ? { passphraseState: context.passphraseState }\n : {}),\n ...(context?.useEmptyPassphrase !== undefined\n ? { useEmptyPassphrase: context.useEmptyPassphrase }\n : {}),\n },\n } as never\n );\n return;\n }\n this._emitter.emit(data.type as keyof HardwareEventMap, data as never);\n };\n\n private _onUiEvent = (data: ConnectorUiEvent): void => {\n this._emitter.emit('ui-event', data);\n };\n\n private _onThpCredentialsChanged = (data: {\n connectId: string;\n deviceId?: string;\n credentials: Record<string, unknown>[];\n }): void => {\n this._emitter.emit(DEVICE.TREZOR_THP_CREDENTIALS_CHANGED, {\n type: DEVICE.TREZOR_THP_CREDENTIALS_CHANGED,\n payload: data,\n });\n };\n\n private _registerConnectorEvents(): void {\n this._connector.on('device-connect', this._onDeviceConnect);\n this._connector.on('device-disconnect', this._onDeviceDisconnect);\n this._connector.on(DEVICE.FEATURES, this._onSupportFeatures);\n this._connector.on('device-trezor-thp-credentials-changed', this._onThpCredentialsChanged);\n this._connector.on('ui-request', this._onUiRequest);\n this._connector.on('ui-event', this._onUiEvent);\n }\n\n private _unregisterConnectorEvents(): void {\n this._connector.off('device-connect', this._onDeviceConnect);\n this._connector.off('device-disconnect', this._onDeviceDisconnect);\n this._connector.off(DEVICE.FEATURES, this._onSupportFeatures);\n this._connector.off('device-trezor-thp-credentials-changed', this._onThpCredentialsChanged);\n this._connector.off('ui-request', this._onUiRequest);\n this._connector.off('ui-event', this._onUiEvent);\n }\n\n private _connectorDeviceToDeviceInfo(device: ConnectorDevice): DeviceInfo {\n return {\n vendor: 'trezor',\n model: device.model ?? 'unknown',\n firmwareVersion: 'unknown',\n deviceId: device.deviceId,\n connectId: device.connectId,\n label: device.name,\n // The per-device transport is authoritative (a combined USB+BLE\n // connector tags each discovered device); the connector's own\n // connectionType is only a nominal value, so fall back to it for\n // single-transport connectors that don't tag each device.\n connectionType: device.connectionType ?? this._connector.connectionType,\n capabilities: device.capabilities,\n };\n }\n\n private _errorToFailure(error: unknown) {\n const typed = error as { code?: unknown; message?: string };\n // Map hwk-trezor-core's string markers to standard HardwareErrorCodes.\n // The core tags pairing-handshake rejections (e.g. mistyped CodeEntry code)\n // with `code: 'ThpPairingFailed'`; surface it as a proper code, not Unknown.\n if (typed.code === 'ThpPairingFailed') {\n return failure(HardwareErrorCode.ThpPairingFailed, typed.message ?? 'THP pairing failed');\n }\n // Only trust a numeric `code` if it is an actual HardwareErrorCode. A raw\n // WebUSB AbortError carries a DOMException `code: 20`, which is NOT one of\n // ours — fall through to message-based mapping (transferOut/USBDevice abort\n // → TransportError) so it surfaces as a recognizable, retryable transport\n // error instead of Unknown.\n const trustedNumericCode =\n typeof typed.code === 'number' && KNOWN_HARDWARE_ERROR_CODES.has(typed.code)\n ? typed.code\n : undefined;\n const code =\n trustedNumericCode ??\n TrezorAdapter._mapTrezorFailureCode(error) ??\n HardwareErrorCode.UnknownError;\n return failure(code, typed.message ?? String(error));\n }\n\n /**\n * Emit `REQUEST_DEVICE_PERMISSION` and await the host's\n * `RECEIVE_DEVICE_PERMISSION` reply (60s budget covers OS prompt + user\n * tap). If the host doesn't wire a handler the wait times out and the\n * operation fails fast.\n *\n * Mirrors LedgerAdapter._ensureDevicePermission so hosts can register a\n * single handler that branches by `payload.transportType` (and optionally\n * the active brand) instead of teaching every adapter its own contract.\n *\n * - no `connectId` → environment-level check (scan / picker)\n * - with `connectId` → device-level check (per-call gating)\n */\n private async _ensureDevicePermission(connectId?: string, deviceId?: string): Promise<void> {\n // No handler? Skip silently so non-permission-aware hosts (and our own\n // unit tests) keep working — Ledger's adapter has a 60s timeout but\n // hardware-wallet flows on web/desktop don't always have a registered\n // listener, and they shouldn't stall for a minute waiting on one.\n if (!this._emitter.listenerCount(UI_REQUEST.REQUEST_DEVICE_PERMISSION)) {\n return;\n }\n const transportType: TransportType = this.activeTransport ?? 'usb';\n\n const waitPromise = this._uiRegistry.wait<{ granted: boolean; reason?: string }>(\n UI_REQUEST.REQUEST_DEVICE_PERMISSION,\n { timeoutMs: 60_000 }\n );\n\n this._emitter.emit(UI_REQUEST.REQUEST_DEVICE_PERMISSION, {\n type: UI_REQUEST.REQUEST_DEVICE_PERMISSION,\n payload: { transportType, connectId, deviceId },\n });\n\n const { granted } = await waitPromise;\n if (!granted) {\n throw Object.assign(new Error('Device permission denied'), {\n code: HardwareErrorCode.DevicePermissionDenied,\n });\n }\n }\n}\n","/**\n * SDK-global event bus. Per-runtime singleton; hosts forward events over their\n * own IPC when the adapter runs in an offscreen/background split.\n */\n\nexport type SdkLogEvent = {\n type: 'log';\n level: 'debug' | 'info' | 'warn' | 'error';\n /** Pre-stringified payload. */\n message: string;\n};\n\nexport type SdkEvent = SdkLogEvent;\n\nexport type SdkEventListener = (event: SdkEvent) => void;\n\nconst listeners = new Set<SdkEventListener>();\n\nexport function onSdkEvent(listener: SdkEventListener): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\nexport function offSdkEvent(listener: SdkEventListener): void {\n listeners.delete(listener);\n}\n\nexport function emitSdkEvent(event: SdkEvent): void {\n if (listeners.size === 0) return;\n for (const listener of listeners) {\n try {\n listener(event);\n } catch {\n // Logging subscribers must not affect SDK execution.\n }\n }\n}\n\nexport function emitLog(level: SdkLogEvent['level'], ...args: unknown[]): void {\n if (listeners.size === 0) return;\n const message = args.map(a => (typeof a === 'string' ? a : safeStringify(a))).join(' ');\n emitSdkEvent({ type: 'log', level, message });\n}\n\nfunction safeStringify(value: unknown): string {\n if (value instanceof Error) {\n return value.stack ? `${value.message}\\n${value.stack}` : value.message;\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n","import { emitLog } from './sdkEventBus';\n\nexport function debugLog(...args: unknown[]): void {\n emitLog('debug', ...args);\n}\n\nexport function debugError(...args: unknown[]): void {\n emitLog('error', ...args);\n}\n","import type { EvmEthereumDefinitions } from '@onekeyfe/hwk-adapter-core';\n\n/**\n * Opt-in helpers for fetching Trezor Ethereum \"definitions\" — the SatoshiLabs-\n * signed network/token metadata a Trezor device uses to render friendly names\n * for chains and tokens that are NOT built into firmware.\n *\n * IMPORTANT — the SDK signing methods (evmSignTransaction / evmGetAddress / …)\n * NEVER call these. A local hardware operation must not silently become a\n * third-party network request (see PR #824 review). The caller decides whether,\n * when, and where to fetch, then passes the result into the sign params as\n * `ethereumDefinitions`. When omitted, the device falls back to a generic\n * confirmation screen and signing still completes.\n *\n * Cross-process note: `fetchImpl` is a FUNCTION and cannot be serialized across\n * an IPC / postMessage boundary. Call these helpers in a network-capable\n * process and send only the resulting bytes (ArrayBuffer/hex) to the process\n * that talks to the device. Use `baseUrl` (a string) to route through your own\n * controlled proxy instead of hitting data.trezor.io directly.\n */\n\n/** Default upstream (Trezor). Override with `baseUrl` to use your own proxy. */\nexport const DEFAULT_ETHEREUM_DEFINITIONS_BASE_URL =\n 'https://data.trezor.io/firmware/eth-definitions';\n\nexport type FetchLike = (url: string) => Promise<{\n status: number;\n arrayBuffer(): Promise<ArrayBuffer>;\n}>;\n\nexport type FetchEthereumDefinitionsParams = {\n chainId?: number;\n slip44?: number;\n contractAddress?: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\nexport type BuildEthereumDefinitionsForPathParams = {\n path: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\nexport type BuildEthereumDefinitionsForSignTxParams = {\n path: string;\n chainId: number;\n to?: string;\n data?: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\n/** Derive the SLIP-44 coin type (unhardened) from a BIP44-style path. */\nexport function getSlip44FromPath(path: string): number {\n const segments = path.trim().replace(/^m\\//i, '').split('/');\n const coinType = segments[1];\n const parsed = coinType === undefined ? NaN : Number(coinType.replace(/['hH]$/, ''));\n if (!Number.isFinite(parsed)) {\n throw new Error(`Cannot derive SLIP-44 coin type from path: ${path}`);\n }\n return parsed >= 0x80000000 ? parsed - 0x80000000 : parsed;\n}\n\nexport async function fetchEthereumDefinitions({\n chainId,\n slip44,\n contractAddress,\n baseUrl = DEFAULT_ETHEREUM_DEFINITIONS_BASE_URL,\n fetchImpl = globalThis.fetch,\n}: FetchEthereumDefinitionsParams): Promise<EvmEthereumDefinitions> {\n if (!chainId && !slip44) {\n throw new Error('fetchEthereumDefinitions requires chainId or slip44');\n }\n if (!fetchImpl) {\n return {};\n }\n\n const mode = chainId ? 'chain-id' : 'slip44';\n const id = chainId ?? slip44;\n const definitions: EvmEthereumDefinitions = {};\n\n const network = await fetchDefinition(`${baseUrl}/${mode}/${id}/network.dat`, fetchImpl);\n if (network) {\n definitions.encodedNetwork = network;\n }\n\n if (contractAddress) {\n const token = await fetchDefinition(\n `${baseUrl}/${mode}/${id}/token-${stripHexPrefix(contractAddress).toLowerCase()}.dat`,\n fetchImpl\n );\n if (token) {\n definitions.encodedToken = token;\n }\n }\n\n return definitions;\n}\n\nexport async function buildEthereumDefinitionsForPath({\n path,\n baseUrl,\n fetchImpl,\n}: BuildEthereumDefinitionsForPathParams): Promise<EvmEthereumDefinitions> {\n return fetchEthereumDefinitions({\n slip44: getSlip44FromPath(path),\n baseUrl,\n fetchImpl,\n });\n}\n\nexport async function buildEthereumDefinitionsForSignTx({\n path,\n chainId,\n to,\n data,\n baseUrl,\n fetchImpl,\n}: BuildEthereumDefinitionsForSignTxParams): Promise<EvmEthereumDefinitions | undefined> {\n const dataHex = stripHexPrefix(data ?? '');\n if (chainId === 1 && !dataHex) {\n return undefined;\n }\n return fetchEthereumDefinitions({\n chainId,\n slip44: getSlip44FromPath(path),\n contractAddress: dataHex && to ? to : undefined,\n baseUrl,\n fetchImpl,\n });\n}\n\nasync function fetchDefinition(\n url: string,\n fetchImpl: FetchLike\n): Promise<ArrayBuffer | undefined> {\n try {\n const response = await fetchImpl(url);\n if (response.status !== 200) {\n return undefined;\n }\n return await response.arrayBuffer();\n } catch {\n return undefined;\n }\n}\n\nfunction stripHexPrefix(value: string): string {\n return value.startsWith('0x') || value.startsWith('0X') ? value.slice(2) : value;\n}\n","import type { FetchLike } from './ethereumDefinitions';\n\n/**\n * Opt-in helper for fetching a Trezor Solana token definition. Same contract as\n * the Ethereum helpers (see ./ethereumDefinitions): the SDK signing path NEVER\n * calls this — the caller fetches (through its own `baseUrl` proxy if desired)\n * and passes the bytes into `solSignTransaction` params as\n * `additionalInfo.encodedToken`. When omitted the device shows a generic token\n * confirmation screen and signing still completes.\n *\n * `fetchImpl` is a function and must not cross an IPC boundary — fetch in a\n * network-capable process and pass only the resulting bytes.\n */\n\n/** Default upstream (Trezor). Override with `baseUrl` to use your own proxy. */\nexport const DEFAULT_SOLANA_TOKEN_DEFINITION_BASE_URL =\n 'https://data.trezor.io/firmware/definitions/solana/token';\n\nexport type FetchSolanaTokenDefinitionParams = {\n tokenMint: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\nexport async function fetchSolanaTokenDefinition({\n tokenMint,\n baseUrl = DEFAULT_SOLANA_TOKEN_DEFINITION_BASE_URL,\n fetchImpl = globalThis.fetch,\n}: FetchSolanaTokenDefinitionParams): Promise<ArrayBuffer | undefined> {\n if (!fetchImpl) {\n return undefined;\n }\n try {\n const response = await fetchImpl(`${baseUrl}/${tokenMint}.dat`);\n if (response.status !== 200) {\n return undefined;\n }\n return await response.arrayBuffer();\n } catch {\n return undefined;\n }\n}\n","export const TREZOR_SAFE_7_MODEL = 'T3W1';\n\nexport const TREZOR_BLE_SUPPORTED_MODELS = [TREZOR_SAFE_7_MODEL] as const;\n\nexport const TREZOR_BLE_PACKET_SIZE = 244;\n\nexport const TREZOR_BLE_UUIDS = {\n service: '8c000001-a59b-4d58-a9ad-073df69fa1b1',\n write: '8c000002-a59b-4d58-a9ad-073df69fa1b1',\n notify: '8c000003-a59b-4d58-a9ad-073df69fa1b1',\n push: '8c000004-a59b-4d58-a9ad-073df69fa1b1',\n batteryService: '0000180f-0000-1000-8000-00805f9b34fb',\n} as const;\n","import { TREZOR_BLE_SUPPORTED_MODELS, TREZOR_BLE_UUIDS } from '../constants';\n\nimport type { TrezorBleDescriptor } from '../types';\n\nexport function isTrezorSafe7BleName(name?: string): boolean {\n if (!name) return false;\n return /\\bTrezor\\b/i.test(name) && (/\\bSafe\\s*7\\b/i.test(name) || /\\bT3W1\\b/i.test(name));\n}\n\nexport function isTrezorBleSupportedModel(model?: string): boolean {\n if (!model) return false;\n const normalizedModel = model.trim().replace(/\\s+/g, ' ').toLowerCase();\n return (\n TREZOR_BLE_SUPPORTED_MODELS.some(\n supportedModel => supportedModel.toLowerCase() === normalizedModel\n ) ||\n normalizedModel === 'safe 7' ||\n normalizedModel === 'trezor safe 7'\n );\n}\n\nexport function isTrezorSafe7BleDescriptor(descriptor: TrezorBleDescriptor): boolean {\n return isTrezorBleDescriptor(descriptor);\n}\n\nexport function normalizeTrezorBleUuid(uuid: string): string {\n return uuid.replace(/-/g, '').toLowerCase();\n}\n\nexport function isTrezorBleServiceUuid(uuid: string): boolean {\n return normalizeTrezorBleUuid(uuid) === normalizeTrezorBleUuid(TREZOR_BLE_UUIDS.service);\n}\n\nexport function isTrezorBleDescriptor(descriptor: TrezorBleDescriptor): boolean {\n const serviceUuids = [\n ...(descriptor.serviceUUIDs ?? []),\n ...(descriptor.advertisedServiceUuids ?? []),\n ...(descriptor.serviceUuids ?? []),\n ];\n return serviceUuids.some(isTrezorBleServiceUuid);\n}\n\nexport function resolveTrezorBleConnectId(descriptor: TrezorBleDescriptor): string {\n return descriptor.id ?? descriptor.path ?? descriptor.deviceId ?? descriptor.name ?? '';\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/hardware-js-sdk/hardware-js-sdk/packages/hwk-trezor-adapter/dist/index.js","../src/adapter/TrezorAdapter.ts","../src/utils/sdkEventBus.ts","../src/utils/debugLog.ts","../src/utils/ethereumDefinitions.ts","../src/utils/solanaTokenDefinition.ts","../src/constants.ts","../src/utils/bleIdentity.ts"],"names":[],"mappings":"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AACA,IAAA;AACD,EAAA;AACH;AAEe;AACT,EAAA;AACe,IAAA;AACJ,IAAA;AACJ,MAAA;AACT,IAAA;AACO,IAAA;AACD,EAAA;AACC,IAAA;AACT,EAAA;AACF;AAE0B;AACA,EAAA;AAC1B;AAEwB;AACE,EAAA;AAC1B;AJmhC0B;AACA;AK5pCb;AASS;AACpB,EAAA;AACU,EAAA;AACa,EAAA;AACyC;AAChD,EAAA;AACP,IAAA;AACT,EAAA;AACI,EAAA;AACe,IAAA;AACJ,IAAA;AACJ,MAAA;AACT,IAAA;AACmB,IAAA;AACb,EAAA;AACC,IAAA;AACT,EAAA;AACF;ALspC0B;AACA;AMhsCS;AAEtB;AAEA;AAEmB;AACrB,EAAA;AACF,EAAA;AACC,EAAA;AACF,EAAA;AACU,EAAA;AAClB;AN+rC0B;AACA;AOxsCV;AACI,EAAA;AACG,EAAA;AACvB;AAEgB;AACK,EAAA;AACK,EAAA;AAEtB,EAAA;AACoB,IAAA;AAEpB,EAAA;AAGJ;AAEgB;AACP,EAAA;AACT;AAEgB;AACM,EAAA;AACtB;AAEgB;AACP,EAAA;AACT;AAEgB;AACO,EAAA;AACJ,IAAA;AACA,IAAA;AACA,IAAA;AACjB,EAAA;AACoB,EAAA;AACtB;AAEgB;AACU,EAAA;AAC1B;APgsC0B;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-trezor-adapter/dist/index.js","sourcesContent":[null,"import {\n DEVICE,\n DeviceJobQueue,\n HardwareErrorCode,\n TypedEventEmitter,\n UI_REQUEST,\n UI_RESPONSE,\n UiRequestRegistry,\n failure,\n rehydrateConnectorError,\n runAllNetworkGetAddress,\n success,\n} from '@onekeyfe/hwk-adapter-core';\n\nimport { debugLog } from '../utils/debugLog';\n\nimport type {\n AllNetworkAddressParams,\n AllNetworkAddressResponse,\n AllNetworkGetAddressParams,\n AllNetworkMethodName,\n BtcAddress,\n BtcGetAddressParams,\n BtcGetPublicKeyParams,\n BtcPublicKey,\n BtcSignMsgParams,\n BtcSignPsbtParams,\n BtcSignTxParams,\n BtcSignature,\n BtcSignedPsbt,\n BtcSignedTx,\n ChainCapability,\n ChainForFingerprint,\n ConnectorCallResult,\n ConnectorDevice,\n ConnectorUiEvent,\n DeviceEventListener,\n DeviceInfo,\n EvmAddress,\n EvmGetAddressParams,\n EvmSignMsgParams,\n EvmSignTxTrezorParams,\n EvmSignTypedDataParams,\n EvmSignature,\n EvmSignedTx,\n HardwareEvent,\n HardwareEventMap,\n IBtcMethods,\n ICommonCallParams,\n IConnector,\n IDeviceManagerMethods,\n IEvmMethods,\n IHardwareWallet,\n ISolMethods,\n ITronMethods,\n Response,\n SolAddress,\n SolGetAddressParams,\n SolSignMsgParams,\n SolSignTxParams,\n SolSignature,\n SolSignedTx,\n TransportType,\n TrezorBrightnessParams,\n TrezorChangePinParams,\n TrezorDeviceSettingsParams,\n TronAddress,\n TronGetAddressParams,\n TronSignMsgParams,\n TronSignTxParams,\n TronSignature,\n TronSignedTx,\n UiResponseEvent,\n} from '@onekeyfe/hwk-adapter-core';\n\n// Valid HardwareErrorCode numbers. Used to reject foreign numeric `code`s (e.g.\n// a DOMException's `code: 20` on a WebUSB AbortError) that must NOT be trusted\n// as HardwareErrorCodes — otherwise they leak through as Unknown.\nconst KNOWN_HARDWARE_ERROR_CODES = new Set<number>(\n Object.values(HardwareErrorCode).filter((value): value is number => typeof value === 'number')\n);\n\ntype NullableCallArg<T> = T | null | undefined;\n\ntype TrezorPassphraseCallParams = {\n passphraseState?: string;\n useEmptyPassphrase?: boolean;\n};\n\ntype TrezorPassphraseRequestContext = {\n passphraseState?: string;\n useEmptyPassphrase?: boolean;\n};\n\ntype TrezorVerifiedPassphraseSession = {\n sessionId: string;\n protocol: 'thp' | 'v1';\n thpSessionId?: string;\n};\n\ntype TrezorCallParams<T> = (T & ICommonCallParams & TrezorPassphraseCallParams) | null | undefined;\n\ntype TrezorCommonParams = (ICommonCallParams & TrezorPassphraseCallParams) | null | undefined;\n\ntype AsyncMethodName<T> = Extract<\n {\n [K in keyof T]-?: NonNullable<T[K]> extends (\n ...args: infer _Args\n ) => Promise<Response<infer _Payload>>\n ? K\n : never;\n }[keyof T],\n string\n>;\n\ntype TrezorWalletMethods = IEvmMethods & IBtcMethods & ISolMethods & ITronMethods;\n\ntype TrezorWalletMethodName = AsyncMethodName<TrezorWalletMethods>;\n\ntype TrezorDeviceManagerMethodName = AsyncMethodName<IDeviceManagerMethods>;\n\ntype TrezorMethodName = TrezorWalletMethodName | TrezorDeviceManagerMethodName;\n\nconst TREZOR_BTC_NETWORK_COIN_MAP: Partial<Record<string, string>> = {\n btc: 'Bitcoin',\n bitcoin: 'Bitcoin',\n tbtc: 'Testnet',\n testnet: 'Testnet',\n sbtc: 'Signet',\n signet: 'Signet',\n ltc: 'Litecoin',\n litecoin: 'Litecoin',\n doge: 'Dogecoin',\n dogecoin: 'Dogecoin',\n bch: 'Bcash',\n bcash: 'Bcash',\n dash: 'Dash',\n};\n\nexport class TrezorAdapter implements IHardwareWallet {\n readonly vendor = 'trezor' as const;\n\n private readonly _connector: IConnector;\n\n private readonly _emitter = new TypedEventEmitter<HardwareEventMap>();\n\n private readonly _devices = new Map<string, DeviceInfo>();\n\n private readonly _sessions = new Map<string, string>();\n\n private readonly _connectingPromises = new Map<string, Promise<string>>();\n\n // connectIds disconnected mid-connect; the session they produce is torn down, not cached.\n private readonly _disconnectRequested = new Set<string>();\n\n private readonly _uiRegistry = new UiRequestRegistry();\n\n private readonly _passphraseRequestContextByConnectId = new Map<\n string,\n TrezorPassphraseRequestContext\n >();\n\n private readonly _verifiedPassphraseSessionsByConnectId = new Map<\n string,\n Map<string, TrezorVerifiedPassphraseSession>\n >();\n\n // Per-device queue with preemption + AbortSignal. Same-device chain calls\n // serialize (Trezor's protocol is single-request-response — interleaving\n // desyncs THP nonce). 'safe' read methods auto-cancel each other; 'confirm'\n // sign methods emit REQUEST_PREEMPTION so the consumer can decide.\n private readonly _jobQueue: DeviceJobQueue;\n\n constructor(connector: IConnector) {\n this._connector = connector;\n // Upstream DeviceJobQueue is now a global FIFO with no built-in\n // preemption — interruptibility lives at the application layer.\n this._jobQueue = new DeviceJobQueue();\n this._registerConnectorEvents();\n }\n\n private static _createDeviceBusyError(method: string): Error {\n // Our own queued request blocks this one → DeviceBusyInternal, not \"another app\".\n return Object.assign(new Error(`Trezor is busy with another request (${method})`), {\n code: HardwareErrorCode.DeviceBusyInternal,\n });\n }\n\n /**\n * Split a Trezor-only `passphraseState` routing hint off the chain params so\n * it never reaches the protobuf layer. The connector/firmware only sees the\n * real op fields; the adapter uses `passphraseState` to align the session.\n */\n private static _normalizeCallArgs(\n connectId: NullableCallArg<string>,\n deviceId: NullableCallArg<string>,\n params: NullableCallArg<unknown>\n ): {\n connectId: string;\n params: unknown;\n } {\n return {\n connectId: connectId || deviceId || '',\n params: params ?? {},\n };\n }\n\n private static _splitCommonParams(params: unknown): {\n passphraseState?: string;\n useEmptyPassphrase?: boolean;\n rest: unknown;\n } {\n if (params && typeof params === 'object') {\n const {\n passphraseState,\n autoInstallApp: _autoInstallApp,\n useEmptyPassphrase,\n ...rest\n } = params as Record<string, unknown>;\n return {\n passphraseState: typeof passphraseState === 'string' ? passphraseState : undefined,\n useEmptyPassphrase:\n typeof useEmptyPassphrase === 'boolean' ? useEmptyPassphrase : undefined,\n rest,\n };\n }\n return { rest: params ?? {} };\n }\n\n private static _withAllNetworkRequestCommonParams(\n item: AllNetworkAddressParams,\n commonParams: TrezorCommonParams\n ): AllNetworkAddressParams {\n const autoInstallApp = commonParams?.autoInstallApp;\n const passphraseState = commonParams?.passphraseState;\n const useEmptyPassphrase = commonParams?.useEmptyPassphrase;\n if (\n autoInstallApp === undefined &&\n passphraseState === undefined &&\n useEmptyPassphrase === undefined\n ) {\n return item;\n }\n return {\n ...item,\n ...(autoInstallApp !== undefined ? { autoInstallApp } : {}),\n ...(passphraseState !== undefined ? { passphraseState } : {}),\n ...(useEmptyPassphrase !== undefined ? { useEmptyPassphrase } : {}),\n };\n }\n\n private static _sanitizeForLog(value: unknown): unknown {\n if (!value || typeof value !== 'object') return value;\n if (Array.isArray(value)) {\n return value.map(item => TrezorAdapter._sanitizeForLog(item));\n }\n const sensitiveKeys = new Set([\n 'credential',\n 'credentials',\n 'host_static_key',\n 'passphrase',\n 'passphraseState',\n 'pin',\n 'trezor_static_public_key',\n ]);\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, item]) => [\n key,\n sensitiveKeys.has(key) ? '[redacted]' : TrezorAdapter._sanitizeForLog(item),\n ])\n );\n }\n\n private static _errorForLog(error: unknown): unknown {\n if (!error || typeof error !== 'object') return error;\n const typed = error as {\n code?: unknown;\n errorCode?: unknown;\n message?: unknown;\n name?: unknown;\n response?: unknown;\n statusCode?: unknown;\n };\n return TrezorAdapter._sanitizeForLog({\n name: typed.name,\n message: typed.message,\n code: typed.code,\n errorCode: typed.errorCode,\n statusCode: typed.statusCode,\n response: typed.response,\n });\n }\n\n private _setPassphraseRequestContext(\n connectId: string,\n context: TrezorPassphraseRequestContext\n ): () => void {\n const previous = this._passphraseRequestContextByConnectId.get(connectId);\n if (context.passphraseState !== undefined || context.useEmptyPassphrase !== undefined) {\n this._passphraseRequestContextByConnectId.set(connectId, context);\n } else {\n this._passphraseRequestContextByConnectId.delete(connectId);\n }\n return () => {\n if (previous) {\n this._passphraseRequestContextByConnectId.set(connectId, previous);\n } else {\n this._passphraseRequestContextByConnectId.delete(connectId);\n }\n };\n }\n\n private static _trezorFailureMessage(error: unknown): {\n code?: unknown;\n message?: unknown;\n } {\n const response = (error as { response?: unknown } | null | undefined)?.response;\n const message = (response as { message?: unknown } | null | undefined)?.message;\n if (!message || typeof message !== 'object') return {};\n const failureMessage = message as { code?: unknown; message?: unknown };\n return {\n code: failureMessage.code,\n message: failureMessage.message,\n };\n }\n\n private static _mapTrezorFailureCode(error: unknown): HardwareErrorCode | undefined {\n const directCode = (error as { code?: unknown } | null | undefined)?.code;\n if (directCode === 'Device_InitializeFailed') {\n return HardwareErrorCode.PinCancelled;\n }\n if (directCode === 'Failure_ActionCancelled') {\n return HardwareErrorCode.UserRejected;\n }\n if (directCode === 'ThpPairingRequired') {\n return HardwareErrorCode.ThpPairingRequired;\n }\n if (directCode === 'Failure_UnexpectedMessage') {\n return HardwareErrorCode.MethodNotSupported;\n }\n const message = (error as { message?: unknown } | null | undefined)?.message;\n if (\n typeof message === 'string' &&\n message.includes(\"Failed to execute 'transfer\") &&\n message.includes(\"on 'USBDevice'\")\n ) {\n return HardwareErrorCode.TransportError;\n }\n const failure = TrezorAdapter._trezorFailureMessage(error);\n if (failure.code === 'Failure_PinCancelled') {\n return HardwareErrorCode.PinCancelled;\n }\n if (failure.code === 'Failure_PinInvalid') {\n return HardwareErrorCode.PinInvalid;\n }\n if (failure.code === 'Failure_ActionCancelled') {\n return HardwareErrorCode.UserRejected;\n }\n if (failure.code === 'Failure_ProcessError' && failure.message === 'Unsupported script type') {\n return HardwareErrorCode.MethodNotSupported;\n }\n // Device rejected the derivation path (e.g. an index outside its allowed\n // range) — distinct path-specific surface, not a generic \"method\" error.\n if (failure.code === 'Failure_DataError' && failure.message === 'Forbidden key path') {\n return HardwareErrorCode.DevicePathForbidden;\n }\n // Firmware can't process this request (e.g. EIP-712 typed data the device\n // firmware doesn't support) → surface as \"method not supported\".\n if (failure.code === 'Failure_FirmwareError') {\n return HardwareErrorCode.MethodNotSupported;\n }\n // Device firmware doesn't recognize the message (e.g. an older device asked\n // for a coin/app it lacks) → \"method not supported\", not a generic unknown.\n if (failure.code === 'Failure_UnexpectedMessage') {\n return HardwareErrorCode.MethodNotSupported;\n }\n if (failure.code === 'Failure_NotInitialized') {\n return HardwareErrorCode.DeviceNotInitialized;\n }\n // Device busy with its own op, not another app → DeviceBusyInternal.\n if (failure.code === 'Failure_Busy' || failure.code === 'Failure_InProgress') {\n return HardwareErrorCode.DeviceBusyInternal;\n }\n return undefined;\n }\n\n /**\n * Whether a device-side error code means the THP application session we\n * selected is gone (the device evicted it from its limited slot pool). The\n * caller drops the stale cache entry and recreates from scratch.\n *\n * NOTE: the exact eviction code still needs real-device confirmation — match\n * conservatively so a genuine error isn't mistaken for an evicted session\n * (which would silently re-prompt the passphrase).\n */\n private static _isStaleSessionError(code: unknown): boolean {\n if (typeof code !== 'string') return false;\n return (\n code === 'ThpUnallocatedChannel' ||\n /invalid.?session|unallocated.?session|session.?not.?found/i.test(code)\n );\n }\n\n private static _errorCode(error: unknown): unknown {\n return (error as { code?: unknown }).code ?? TrezorAdapter._trezorFailureMessage(error).code;\n }\n\n private static _isConnectionUnavailableError(error: unknown): boolean {\n const { code } = error as { code?: unknown };\n return (\n code === HardwareErrorCode.DeviceNotFound || code === HardwareErrorCode.DeviceDisconnected\n );\n }\n\n /**\n * Race a promise against an abort signal. Copied from LedgerAdapter:\n * IConnector.call() can't actually be cancelled at the protocol level, but\n * the caller gets the abort immediately and the underlying work completes\n * uselessly in the background.\n */\n private static _abortable<T>(signal: AbortSignal, promise: Promise<T>): Promise<T> {\n if (signal.aborted) {\n return Promise.reject(\n (signal as AbortSignal & { reason?: unknown }).reason ?? new Error('Aborted')\n );\n }\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n reject((signal as AbortSignal & { reason?: unknown }).reason ?? new Error('Aborted'));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n value => {\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n err => {\n signal.removeEventListener('abort', onAbort);\n reject(err);\n }\n );\n });\n }\n\n private async _connectSession(connectId: string, signal?: AbortSignal): Promise<string> {\n const connectPromise = this._connector.connect(connectId);\n const session = await (async () => {\n if (!signal) return connectPromise;\n try {\n return await TrezorAdapter._abortable(signal, connectPromise);\n } catch (error) {\n // _abortable rejected (abort/failure) but the underlying connect keeps\n // running — tear down any session it still resolves so it isn't orphaned.\n void connectPromise.then(\n orphan => this._connector.disconnect(orphan.sessionId).catch(() => undefined),\n () => undefined\n );\n throw error;\n }\n })();\n // disconnectDevice() ran mid-connect: tear down the now-unwanted session\n // instead of caching it (else it leaks a limited THP slot).\n if (this._disconnectRequested.delete(connectId)) {\n await this._connector.disconnect(session.sessionId).catch(() => undefined);\n throw Object.assign(new Error('Trezor connection aborted'), {\n code: HardwareErrorCode.UserAborted,\n });\n }\n this._sessions.set(connectId, session.sessionId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n this._devices.set(connectId, session.deviceInfo);\n return session.sessionId;\n }\n\n get activeTransport(): TransportType | null {\n return this._connector.connectionType;\n }\n\n async init(_config?: unknown): Promise<void> {}\n\n async dispose(): Promise<void> {\n this._unregisterConnectorEvents();\n this._uiRegistry.reset();\n this._jobQueue.clear();\n this._connector.reset();\n this._devices.clear();\n this._sessions.clear();\n this._verifiedPassphraseSessionsByConnectId.clear();\n this._connectingPromises.clear();\n this._emitter.removeAllListeners();\n }\n\n /**\n * Clear cached state without tearing down the adapter or unregistering\n * listeners. Mirrors LedgerAdapter.resetState() — useful for retry-after-\n * error flows. Aborts active jobs and releases UI waits.\n */\n resetState(): void {\n this._uiRegistry.reset();\n this._jobQueue.clear();\n this._devices.clear();\n this._sessions.clear();\n this._verifiedPassphraseSessionsByConnectId.clear();\n this._connectingPromises.clear();\n }\n\n getAvailableTransports(): TransportType[] {\n return this.activeTransport ? [this.activeTransport] : [];\n }\n\n async switchTransport(_type: TransportType): Promise<void> {}\n\n async searchDevices(options?: { waitForAllTransports?: boolean }): Promise<DeviceInfo[]> {\n await this._ensureDevicePermission();\n const scanned = await this._connector.searchDevices(\n options?.waitForAllTransports ? { waitForAll: true } : undefined\n );\n const scannedIds = new Set(scanned.map(d => d.connectId));\n // A rescan that misses a currently-connected device shouldn't evict it —\n // otherwise getDeviceInfo would return DeviceNotFound for an active session.\n for (const connectId of [...this._devices.keys()]) {\n if (!scannedIds.has(connectId) && !this._sessions.has(connectId)) {\n this._devices.delete(connectId);\n }\n }\n for (const device of scanned) {\n const info = this._connectorDeviceToDeviceInfo(device);\n this._devices.set(info.connectId, info);\n }\n return Array.from(this._devices.values());\n }\n\n async connectDevice(connectId: string): Promise<Response<string>> {\n try {\n await this._ensureDevicePermission(connectId);\n await this._ensureSession(connectId);\n return success(connectId);\n } catch (error) {\n return this._errorToFailure(error);\n }\n }\n\n async disconnectDevice(connectId: string): Promise<void> {\n const connecting = this._connectingPromises.has(connectId);\n this._connectingPromises.delete(connectId);\n const sessionId = this._sessions.get(connectId);\n if (!sessionId) {\n // Connect may be in flight (session not recorded yet) — mark it so\n // _connectSession tears down the session it produces instead of caching it.\n if (connecting) this._disconnectRequested.add(connectId);\n return;\n }\n this._sessions.delete(connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n await this._connector.disconnect(sessionId);\n }\n\n async getDeviceInfo(connectId: string, deviceId: string): Promise<Response<DeviceInfo>> {\n const device =\n this._devices.get(connectId) ??\n Array.from(this._devices.values()).find(item => item.deviceId === deviceId);\n if (!device) return failure(HardwareErrorCode.DeviceNotFound, 'Trezor device not found');\n return success(device);\n }\n\n getSupportedChains(): ChainCapability[] {\n // Keep in sync with TrezorConnectorBase.call()'s switch.\n // Chain inclusion means \"at least one method wired\" — per-method gaps:\n // sol: signMessage is explicitly NotSupported (firmware doesn't ship it).\n // tron: signMessage same. signTransaction uses the multi-step\n // TronContractRequest flow.\n return ['btc', 'evm', 'sol', 'tron'];\n }\n\n async allNetworkGetAddress(\n connectId: string,\n deviceId: string,\n params: AllNetworkGetAddressParams\n ): Promise<Response<AllNetworkAddressResponse[]>> {\n let liveDeviceId = '';\n const topLevelFailureIndexes = new Set<number>();\n const isSingleNetworkBundle = params.bundle.every(\n item => item.network === params.bundle[0]?.network\n );\n const getLiveDeviceId = async (): Promise<Response<string>> => {\n if (liveDeviceId) return success(liveDeviceId);\n const deviceIdResponse = await this._getTrezorDeviceId(connectId);\n if (deviceIdResponse.success) {\n liveDeviceId = deviceIdResponse.payload;\n }\n return deviceIdResponse;\n };\n\n return runAllNetworkGetAddress({\n connectId,\n deviceId,\n params,\n normalizeItem: TrezorAdapter._normalizeAllNetworkItem,\n callItem: async ({ method, item, index }) => {\n const expectedDeviceId = TrezorAdapter._getItemDeviceId(item) ?? deviceId;\n if (expectedDeviceId) {\n const fingerprint = await getLiveDeviceId();\n if (!fingerprint.success) {\n topLevelFailureIndexes.add(index);\n return fingerprint;\n }\n if (expectedDeviceId !== fingerprint.payload) {\n topLevelFailureIndexes.add(index);\n return failure(\n HardwareErrorCode.DeviceMismatch,\n `Wrong device: expected ${expectedDeviceId}, got ${fingerprint.payload}`,\n { expected: expectedDeviceId, actual: fingerprint.payload }\n );\n }\n }\n const callItem = TrezorAdapter._withAllNetworkRequestCommonParams(item, params);\n return this._callAllNetworkMethod(connectId, method, callItem);\n },\n attachIdentity: async ({ item, chain, payload }) => {\n if (!liveDeviceId) {\n const fingerprint = await getLiveDeviceId();\n if (!fingerprint.success) {\n return { ...item, success: false, payload: fingerprint.payload };\n }\n }\n return {\n ...item,\n success: true,\n payload: {\n ...payload,\n deviceIdentity: {\n vendor: 'trezor',\n type: 'deviceId',\n value: liveDeviceId,\n },\n chainFingerprint: liveDeviceId,\n chainFingerprintChain: chain,\n },\n };\n },\n // One named boolean per abort reason.\n shouldAbortBundle: (response, { index }) => {\n const isSessionLevelFailure = topLevelFailureIndexes.has(index);\n // Mixed bundles must not abort — other chains can still derive.\n const isWholeChainForbidden =\n isSingleNetworkBundle && response.payload?.code === HardwareErrorCode.DevicePathForbidden;\n return isSessionLevelFailure || isWholeChainForbidden;\n },\n });\n }\n\n getFeatures(connectId: string): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>('getFeatures', connectId, {});\n }\n\n deviceSettings(\n connectId: string,\n params: TrezorDeviceSettingsParams\n ): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>(\n 'deviceSettings',\n connectId,\n params\n );\n }\n\n setBrightness(\n connectId: string,\n params: TrezorBrightnessParams = {}\n ): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>(\n 'setBrightness',\n connectId,\n params\n );\n }\n\n changePin(\n connectId: string,\n params: TrezorChangePinParams = {}\n ): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>('changePin', connectId, params);\n }\n\n wipeDevice(connectId: string): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>('wipeDevice', connectId, {});\n }\n\n private async _getTrezorDeviceId(connectId: string): Promise<Response<string>> {\n const features = await this.getFeatures(connectId);\n if (!features.success) return features;\n const liveDeviceId = features.payload.device_id;\n if (typeof liveDeviceId !== 'string' || liveDeviceId.length === 0) {\n return failure(HardwareErrorCode.UnknownError, 'Trezor features did not include a device_id');\n }\n return success(liveDeviceId);\n }\n\n cancel(connectId?: string): void {\n const userAbortReason = Object.assign(new Error('User aborted operation'), {\n code: HardwareErrorCode.UserAborted,\n });\n // Release adapter-level UI waits (preemption) and connector-level ones\n // (THP pairing / PIN matrix) — a single CANCEL clears whichever is open.\n this._uiRegistry.cancel();\n this._connector.uiResponse({ type: UI_RESPONSE.CANCEL });\n if (connectId) {\n this._jobQueue.forceCancelActive(connectId, userAbortReason);\n void this._connector.cancel(this._sessions.get(connectId) ?? connectId);\n return;\n }\n for (const cid of this._sessions.keys()) {\n this._jobQueue.forceCancelActive(cid, userAbortReason);\n }\n for (const sessionId of this._sessions.values()) {\n void this._connector.cancel(sessionId);\n }\n }\n\n /**\n * Routes to BOTH the adapter's local UI registry (preemption decisions,\n * future SELECT_DEVICE / DEVICE_PERMISSION) AND the connector's registry\n * (THP pairing tag, PIN matrix). Each side ignores types it isn't waiting\n * for, so double-routing is harmless.\n */\n uiResponse(response: UiResponseEvent): void {\n this._uiRegistry.resolve(response.type, response.payload);\n this._connector.uiResponse(response);\n }\n\n /**\n * Returns a stable per-seed identifier suitable for device-match verification.\n *\n * Trezor exposes `device_id` in Features — a server-generated UUID written\n * during `wipe_device` and stable for the life of the seed. Unlike Ledger\n * (no native id, so a per-chain address is hashed), Trezor's id is global\n * across chains, so the `chain` argument is accepted for API parity but\n * ignored. For unsupported chains we still surface the id (since it would\n * be the same value anyway).\n */\n async getChainFingerprint(\n connectId: string,\n _deviceId: string,\n _chain: ChainForFingerprint\n ): Promise<Response<string>> {\n return this._getTrezorDeviceId(connectId);\n }\n\n /**\n * Resolve the active passphrase wallet identity (`passphraseState`).\n * See {@link IHardwareWallet.getPassphraseState} for the discover/verify\n * semantics. Returns `null` for a standard wallet (no passphrase protection) —\n * there's nothing to pin. Serialized through the per-device job queue so it\n * can't interleave with a chain call on the same device (which would desync\n * the THP session selection).\n */\n getPassphraseState(\n connectId: string,\n passphraseState?: string\n ): Promise<Response<string | null>> {\n return this._jobQueue\n .enqueue(\n connectId,\n async signal => {\n const restorePassphraseRequestContext = this._setPassphraseRequestContext(connectId, {\n passphraseState,\n });\n try {\n return await this._resolvePassphraseState(connectId, passphraseState, signal);\n } finally {\n restorePassphraseRequestContext();\n }\n },\n {\n label: 'getPassphraseState',\n rejectIfBusy: true,\n busyError: TrezorAdapter._createDeviceBusyError('getPassphraseState'),\n }\n )\n .catch(error => this._errorToFailure(error));\n }\n\n evmGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmGetAddressParams>\n ) {\n return this._callWalletMethod<EvmAddress>('evmGetAddress', connectId, deviceId, params);\n }\n\n evmSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmSignTxTrezorParams>\n ) {\n return this._callWalletMethod<EvmSignedTx>('evmSignTransaction', connectId, deviceId, params);\n }\n\n evmSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmSignMsgParams>\n ) {\n return this._callWalletMethod<EvmSignature>('evmSignMessage', connectId, deviceId, params);\n }\n\n evmSignTypedData(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmSignTypedDataParams>\n ) {\n return this._callWalletMethod<EvmSignature>('evmSignTypedData', connectId, deviceId, params);\n }\n\n btcGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcGetAddressParams>\n ) {\n return this._callWalletMethod<BtcAddress>('btcGetAddress', connectId, deviceId, params);\n }\n\n btcGetPublicKey(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcGetPublicKeyParams>\n ) {\n return this._callWalletMethod<BtcPublicKey>('btcGetPublicKey', connectId, deviceId, params);\n }\n\n btcSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcSignTxParams>\n ) {\n return this._callWalletMethod<BtcSignedTx>('btcSignTransaction', connectId, deviceId, params);\n }\n\n btcSignPsbt(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcSignPsbtParams>\n ) {\n return this._callWalletMethod<BtcSignedPsbt>('btcSignPsbt', connectId, deviceId, params);\n }\n\n btcSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcSignMsgParams>\n ) {\n return this._callWalletMethod<BtcSignature>('btcSignMessage', connectId, deviceId, params);\n }\n\n btcGetMasterFingerprint(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCommonParams\n ) {\n return this._callWalletMethod<{ masterFingerprint: string }>(\n 'btcGetMasterFingerprint',\n connectId,\n deviceId,\n params\n );\n }\n\n solGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<SolGetAddressParams>\n ) {\n return this._callWalletMethod<SolAddress>('solGetAddress', connectId, deviceId, params);\n }\n\n solSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<SolSignTxParams>\n ) {\n return this._callWalletMethod<SolSignedTx>('solSignTransaction', connectId, deviceId, params);\n }\n\n solSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<SolSignMsgParams>\n ) {\n return this._callWalletMethod<SolSignature>('solSignMessage', connectId, deviceId, params);\n }\n\n tronGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<TronGetAddressParams>\n ) {\n return this._callWalletMethod<TronAddress>('tronGetAddress', connectId, deviceId, params);\n }\n\n tronSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<TronSignTxParams>\n ) {\n return this._callWalletMethod<TronSignedTx>('tronSignTransaction', connectId, deviceId, params);\n }\n\n tronSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<TronSignMsgParams>\n ) {\n return this._callWalletMethod<TronSignature>('tronSignMessage', connectId, deviceId, params);\n }\n\n private static _unwrapConnectorResult(result: unknown): unknown {\n if (\n result &&\n typeof result === 'object' &&\n 'success' in result &&\n (((result as ConnectorCallResult).success === true && 'payload' in result) ||\n ((result as ConnectorCallResult).success === false && 'error' in result))\n ) {\n const connectorResult = result as ConnectorCallResult;\n if (connectorResult.success) return connectorResult.payload;\n throw rehydrateConnectorError(connectorResult.error);\n }\n return result;\n }\n\n private static async _callConnector(\n connector: IConnector,\n sessionId: string,\n method: string,\n params: unknown,\n signal?: AbortSignal\n ): Promise<unknown> {\n const promise = connector.call(sessionId, method, params);\n const result = signal ? await TrezorAdapter._abortable(signal, promise) : await promise;\n return TrezorAdapter._unwrapConnectorResult(result);\n }\n\n private static _normalizeAllNetworkItem(\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ): AllNetworkAddressParams {\n if (method !== 'btcGetAddress' && method !== 'btcGetPublicKey') {\n return item;\n }\n\n const itemWithCoin = item as AllNetworkAddressParams & { coin?: unknown };\n if (itemWithCoin.coin) {\n return item;\n }\n\n const network = item.network.toLowerCase();\n return {\n ...item,\n coin: TREZOR_BTC_NETWORK_COIN_MAP[network] ?? item.network,\n };\n }\n\n private static _getItemDeviceId(item: AllNetworkAddressParams): string | undefined {\n const { deviceId } = item as { deviceId?: unknown };\n return typeof deviceId === 'string' && deviceId.length > 0 ? deviceId : undefined;\n }\n\n private _callAllNetworkMethod(\n connectId: string,\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ): Promise<Response<unknown>> {\n switch (method) {\n case 'evmGetAddress':\n return this.evmGetAddress(connectId, '', item);\n case 'btcGetAddress':\n return this.btcGetAddress(connectId, '', item);\n case 'btcGetPublicKey':\n return this.btcGetPublicKey(connectId, '', item);\n case 'solGetAddress':\n return this.solGetAddress(connectId, '', item);\n case 'tronGetAddress':\n return this.tronGetAddress(connectId, '', item);\n default:\n return Promise.resolve(\n failure(\n HardwareErrorCode.InvalidParams,\n `Unsupported allNetwork method: ${String(method)}`\n )\n );\n }\n }\n\n on<K extends keyof HardwareEventMap>(\n event: K,\n listener: (event: HardwareEventMap[K]) => void\n ): void;\n\n on(event: string, listener: DeviceEventListener): void;\n\n on(event: string, listener: (event: HardwareEvent) => void): void {\n this._emitter.on(event, listener);\n }\n\n off<K extends keyof HardwareEventMap>(\n event: K,\n listener: (event: HardwareEventMap[K]) => void\n ): void;\n\n off(event: string, listener: DeviceEventListener): void;\n\n off(event: string, listener: (event: HardwareEvent) => void): void {\n this._emitter.off(event, listener);\n }\n\n private _callWalletMethod<T>(\n methodName: TrezorWalletMethodName,\n connectId: NullableCallArg<string>,\n deviceId: NullableCallArg<string>,\n params: NullableCallArg<unknown>\n ): Promise<Response<T>> {\n return this._callMethod<T>(methodName, connectId, deviceId, params, true);\n }\n\n private _callDeviceManagerMethod<T>(\n methodName: TrezorDeviceManagerMethodName,\n connectId: NullableCallArg<string>,\n params: NullableCallArg<unknown>\n ): Promise<Response<T>> {\n return this._callMethod<T>(methodName, connectId, undefined, params, false);\n }\n\n private async _callMethod<T>(\n methodName: TrezorMethodName,\n connectId: NullableCallArg<string>,\n deviceId: NullableCallArg<string>,\n params: NullableCallArg<unknown>,\n requiresWalletIntent: boolean\n ): Promise<Response<T>> {\n const call = TrezorAdapter._normalizeCallArgs(connectId, deviceId, params);\n debugLog('[TrezorAdapter][REQ]', {\n method: methodName,\n connectId: call.connectId || '(empty)',\n deviceId: deviceId || undefined,\n params: TrezorAdapter._sanitizeForLog(call.params),\n });\n try {\n const response = await this._jobQueue.enqueue(\n call.connectId,\n signal =>\n this._callWithRetry<T>(\n call.connectId,\n methodName,\n call.params,\n requiresWalletIntent,\n true,\n signal\n ),\n {\n label: methodName,\n rejectIfBusy: true,\n busyError: TrezorAdapter._createDeviceBusyError(methodName),\n }\n );\n debugLog('[TrezorAdapter][RES]', {\n method: methodName,\n success: response.success,\n payload: TrezorAdapter._sanitizeForLog(response.payload),\n });\n return response;\n } catch (error) {\n // The only way a Promise rejects out of `enqueue` is the busy-reject —\n // _callWithRetry never throws, it returns Response.failure. Convert to\n // the Response shape so chain method callers stay uniform.\n const response = this._errorToFailure(error);\n debugLog('[TrezorAdapter][RES]', {\n method: methodName,\n success: false,\n payload: TrezorAdapter._sanitizeForLog(response.payload),\n });\n return response;\n }\n }\n\n private async _callWithRetry<T>(\n connectId: string,\n methodName: TrezorMethodName,\n params: unknown,\n requiresWalletIntent: boolean,\n allowRetry: boolean,\n signal: AbortSignal\n ): Promise<Response<T>> {\n const { passphraseState, useEmptyPassphrase, rest } = TrezorAdapter._splitCommonParams(params);\n const restorePassphraseRequestContext = this._setPassphraseRequestContext(connectId, {\n passphraseState,\n useEmptyPassphrase,\n });\n try {\n const sessionId = await this._ensureSession(connectId, signal);\n if (requiresWalletIntent && !passphraseState && useEmptyPassphrase !== true) {\n return failure(\n HardwareErrorCode.InvalidParams,\n `Trezor ${methodName} requires an explicit wallet intent: passphraseState or useEmptyPassphrase`\n );\n }\n // Pin the call to the requested passphrase wallet. For THP this creates\n // a new application session; for v1 it re-initializes the device session.\n // Runs inside this queued job so the session alignment and the call can't\n // be interleaved by another request.\n if (passphraseState) {\n await TrezorAdapter._abortable(\n signal,\n this._alignAppSession(connectId, sessionId, passphraseState, signal)\n );\n } else if (useEmptyPassphrase === true) {\n await TrezorAdapter._abortable(signal, this._createFreshAppSession(sessionId, signal));\n }\n const result = await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, methodName, rest)\n );\n return success(result as T);\n } catch (error) {\n // If we were aborted, surface as-is — don't take the retry/recovery path.\n if (signal.aborted) {\n return this._errorToFailure(error);\n }\n const code = TrezorAdapter._errorCode(error);\n // On a transient disconnect (BLE drop, \"device not connected\" race after\n // the device-disconnect event hasn't propagated yet), drop the stale\n // session and reconnect once. Matches Ledger's _retryWithFreshConnection.\n if (allowRetry && code === HardwareErrorCode.DeviceDisconnected) {\n this._sessions.delete(connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n return await this._callWithRetry<T>(\n connectId,\n methodName,\n params,\n requiresWalletIntent,\n false,\n signal\n );\n }\n // The device evicted the passphrase session created for this call. Retry\n // once and recreate the requested wallet context.\n if (\n allowRetry &&\n (passphraseState || useEmptyPassphrase === true) &&\n TrezorAdapter._isStaleSessionError(code)\n ) {\n if (passphraseState) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n }\n return await this._callWithRetry<T>(\n connectId,\n methodName,\n params,\n requiresWalletIntent,\n false,\n signal\n );\n }\n debugLog('[TrezorAdapter][ERROR]', {\n method: methodName,\n connectId,\n error: TrezorAdapter._errorForLog(error),\n });\n return this._errorToFailure(error);\n } finally {\n restorePassphraseRequestContext();\n }\n }\n\n private async _ensureSession(connectId: string, signal?: AbortSignal): Promise<string> {\n const existing = this._sessions.get(connectId);\n if (existing) return existing;\n\n const pending = this._connectingPromises.get(connectId);\n if (pending) return pending;\n\n const promise = (async () => {\n try {\n if (signal?.aborted) {\n throw Object.assign(new Error('Trezor connection aborted'), {\n code: HardwareErrorCode.UserAborted,\n });\n }\n // Fail fast: a single connect attempt. On an \"unavailable device\" error we\n // drop the cached session/passphrase state and rethrow (no retry loop).\n try {\n return await this._connectSession(connectId, signal);\n } catch (error) {\n if (TrezorAdapter._isConnectionUnavailableError(error)) {\n this._sessions.delete(connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n }\n throw error;\n }\n } finally {\n this._connectingPromises.delete(connectId);\n this._disconnectRequested.delete(connectId);\n }\n })();\n\n this._connectingPromises.set(connectId, promise);\n return promise;\n }\n\n /**\n * Pin the device's active wallet session to `passphraseState` (the target\n * wallet identity) before a wallet-bound op. THP has an app-session id; v1\n * does not, but it still binds passphrase to the device session, so the\n * connector re-initializes v1 before we derive and verify.\n *\n * SECURITY: a verified THP app session may be selected again, but the adapter\n * still derives and verifies the passphrase state before any chain method can\n * run. If the cache is stale, fall back to creating a fresh wallet context.\n */\n private async _alignAppSession(\n connectId: string,\n sessionId: string,\n passphraseState: string,\n signal: AbortSignal\n ): Promise<void> {\n const reused = await this._reuseVerifiedPassphraseSession(\n connectId,\n sessionId,\n passphraseState,\n signal\n );\n if (reused) return;\n\n const created = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpCreateSession', {\n passphraseMode: 'prompt',\n })\n )) as { protocol?: string; thpSessionId?: string | null };\n // v1 has no host-managed app-session id, but the connector has just\n // re-initialized a fresh device session; continue with reactive\n // passphrase-state verification.\n if (created?.protocol === 'thp' && !created.thpSessionId) return;\n if (created?.protocol !== 'thp' && created?.protocol !== 'v1') return;\n const state = await this._deriveState(sessionId, signal);\n if (state !== passphraseState) {\n throw Object.assign(\n new Error(\n `Passphrase produced wallet ${state}, expected ${passphraseState} (passphraseState mismatch)`\n ),\n { code: HardwareErrorCode.PassphraseStateMismatch }\n );\n }\n this._rememberVerifiedPassphraseSession(connectId, passphraseState, sessionId, created);\n }\n\n private _rememberVerifiedPassphraseSession(\n connectId: string,\n passphraseState: string,\n sessionId: string,\n created: { protocol?: string; thpSessionId?: string | null } | undefined\n ): void {\n let session: TrezorVerifiedPassphraseSession | undefined;\n if (created?.protocol === 'thp' && typeof created.thpSessionId === 'string') {\n session = {\n sessionId,\n protocol: 'thp',\n thpSessionId: created.thpSessionId,\n };\n } else if (created?.protocol === 'v1') {\n session = {\n sessionId,\n protocol: 'v1',\n };\n }\n if (!session) return;\n\n const sessions =\n this._verifiedPassphraseSessionsByConnectId.get(connectId) ??\n new Map<string, TrezorVerifiedPassphraseSession>();\n sessions.set(passphraseState, session);\n this._verifiedPassphraseSessionsByConnectId.set(connectId, sessions);\n }\n\n private _forgetVerifiedPassphraseSession(connectId: string, passphraseState: string): void {\n const sessions = this._verifiedPassphraseSessionsByConnectId.get(connectId);\n if (!sessions) return;\n sessions.delete(passphraseState);\n if (!sessions.size) {\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n }\n }\n\n private async _reuseVerifiedPassphraseSession(\n connectId: string,\n sessionId: string,\n passphraseState: string,\n signal: AbortSignal\n ): Promise<boolean> {\n const cached = this._verifiedPassphraseSessionsByConnectId.get(connectId)?.get(passphraseState);\n if (!cached || cached.sessionId !== sessionId) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n return false;\n }\n\n try {\n if (cached.protocol === 'thp') {\n if (!cached.thpSessionId) return false;\n await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpSelectSession', {\n thpSessionId: cached.thpSessionId,\n })\n );\n }\n const state = await this._deriveState(sessionId, signal);\n if (state !== passphraseState) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n return false;\n }\n return true;\n } catch (error) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n if (signal.aborted) throw error;\n return false;\n }\n }\n\n private async _createFreshAppSession(sessionId: string, signal: AbortSignal): Promise<void> {\n // Create a fresh standard-wallet context for this call. Empty passphrase is\n // enforced inside connector/core, not delegated to host UI handlers.\n await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpCreateSession', {\n passphraseMode: 'empty',\n })\n );\n }\n\n /**\n * Derive the active session's passphrase state — the wallet identity used to\n * verify the right wallet is active: the compressed PUBLIC KEY at a fixed\n * account path (m/44'/0'/0'). It comes from the SAME GetPublicKey that also\n * carries the 4-byte fingerprint, but we use the FULL pubkey (not the truncated\n * fingerprint) so it's collision-resistant — the address we return can never\n * come from the wrong wallet — while avoiding OneKey's extra Testnet GetAddress.\n * Non-interactive (also unlocks via PIN as a protected derivation).\n */\n private async _deriveState(sessionId: string, signal: AbortSignal): Promise<string> {\n const derived = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, 'btcGetPublicKey', {\n path: \"m/44'/0'/0'\",\n showOnDevice: false,\n })\n )) as { publicKey?: string };\n const state = derived?.publicKey;\n if (!state) {\n throw Object.assign(new Error('Failed to derive passphrase state (wallet public key)'), {\n code: HardwareErrorCode.UnknownError,\n });\n }\n return state;\n }\n\n private async _resolvePassphraseState(\n connectId: string,\n passphraseState: string | undefined,\n signal: AbortSignal\n ): Promise<Response<string | null>> {\n try {\n const sessionId = await this._ensureSession(connectId, signal);\n if (passphraseState) {\n // Verify mode: align (which always re-derives + confirms the state) so the\n // host can gate signing on the correct wallet being active.\n await this._alignAppSession(connectId, sessionId, passphraseState, signal);\n return success(passphraseState);\n }\n // Discover mode (OneKey-aligned). DON'T trust pre-read features — a LOCKED\n // device reports an unreliable `passphrase_protection`, and the connector's\n // plain getFeatures returns a CACHED blob, so checking `unlocked` up front\n // is meaningless. Instead derive first (which unlocks), then re-read fresh:\n // 1. Create a session + derive the state. This UNLOCKS the device (PIN) and,\n // for a passphrase wallet, prompts the passphrase (THP: proactively in\n // ThpCreateNewSession; v1: reactively).\n // 2. Re-read features FRESH from the device (now unlocked → trustworthy).\n // 3. passphrase_protection === true → return the current passphrase\n // state, even if the entered passphrase was empty. Otherwise →\n // standard wallet → return null (OneKey-aligned).\n const created = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpCreateSession', {\n passphraseMode: 'prompt',\n })\n )) as { protocol?: string; thpSessionId?: string | null };\n const state = await this._deriveState(sessionId, signal);\n const features = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, 'getFeatures', { refresh: true })\n )) as Record<string, unknown> | undefined;\n if (features?.passphrase_protection !== true) {\n // Standard wallet — discard the derived state, return null (OneKey convention).\n return success(null);\n }\n this._rememberVerifiedPassphraseSession(connectId, state, sessionId, created);\n return success(state);\n } catch (error) {\n return this._errorToFailure(error);\n }\n }\n\n private _onDeviceConnect = (data: { device: ConnectorDevice }): void => {\n const device = this._connectorDeviceToDeviceInfo(data.device);\n this._devices.set(device.connectId, device);\n this._emitter.emit(DEVICE.CONNECT, { type: DEVICE.CONNECT, payload: device });\n };\n\n private _onDeviceDisconnect = (data: { connectId: string }): void => {\n this._sessions.delete(data.connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(data.connectId);\n this._devices.delete(data.connectId);\n this._emitter.emit(DEVICE.DISCONNECT, {\n type: DEVICE.DISCONNECT,\n payload: { connectId: data.connectId },\n });\n };\n\n private _onSupportFeatures = (data: {\n device: ConnectorDevice & { features: Record<string, unknown> };\n }): void => {\n const device = {\n ...this._connectorDeviceToDeviceInfo(data.device),\n features: data.device.features,\n };\n this._emitter.emit(DEVICE.FEATURES, {\n type: DEVICE.FEATURES,\n device,\n payload: { device },\n });\n };\n\n private _onUiRequest = (data: { type: string; payload?: unknown }): void => {\n if (data.type === UI_REQUEST.REQUEST_PASSPHRASE) {\n const payload =\n data.payload && typeof data.payload === 'object'\n ? (data.payload as Record<string, unknown>)\n : {};\n const connectId = typeof payload.connectId === 'string' ? payload.connectId : undefined;\n const context = connectId\n ? this._passphraseRequestContextByConnectId.get(connectId)\n : undefined;\n this._emitter.emit(\n data.type as keyof HardwareEventMap,\n {\n ...data,\n payload: {\n ...payload,\n ...(context?.passphraseState !== undefined\n ? { passphraseState: context.passphraseState }\n : {}),\n ...(context?.useEmptyPassphrase !== undefined\n ? { useEmptyPassphrase: context.useEmptyPassphrase }\n : {}),\n },\n } as never\n );\n return;\n }\n this._emitter.emit(data.type as keyof HardwareEventMap, data as never);\n };\n\n private _onUiEvent = (data: ConnectorUiEvent): void => {\n this._emitter.emit('ui-event', data);\n };\n\n private _onThpCredentialsChanged = (data: {\n connectId: string;\n deviceId?: string;\n credentials: Record<string, unknown>[];\n }): void => {\n this._emitter.emit(DEVICE.TREZOR_THP_CREDENTIALS_CHANGED, {\n type: DEVICE.TREZOR_THP_CREDENTIALS_CHANGED,\n payload: data,\n });\n };\n\n private _registerConnectorEvents(): void {\n this._connector.on('device-connect', this._onDeviceConnect);\n this._connector.on('device-disconnect', this._onDeviceDisconnect);\n this._connector.on(DEVICE.FEATURES, this._onSupportFeatures);\n this._connector.on('device-trezor-thp-credentials-changed', this._onThpCredentialsChanged);\n this._connector.on('ui-request', this._onUiRequest);\n this._connector.on('ui-event', this._onUiEvent);\n }\n\n private _unregisterConnectorEvents(): void {\n this._connector.off('device-connect', this._onDeviceConnect);\n this._connector.off('device-disconnect', this._onDeviceDisconnect);\n this._connector.off(DEVICE.FEATURES, this._onSupportFeatures);\n this._connector.off('device-trezor-thp-credentials-changed', this._onThpCredentialsChanged);\n this._connector.off('ui-request', this._onUiRequest);\n this._connector.off('ui-event', this._onUiEvent);\n }\n\n private _connectorDeviceToDeviceInfo(device: ConnectorDevice): DeviceInfo {\n return {\n vendor: 'trezor',\n model: device.model ?? 'unknown',\n firmwareVersion: 'unknown',\n deviceId: device.deviceId,\n connectId: device.connectId,\n label: device.name,\n // The per-device transport is authoritative (a combined USB+BLE\n // connector tags each discovered device); the connector's own\n // connectionType is only a nominal value, so fall back to it for\n // single-transport connectors that don't tag each device.\n connectionType: device.connectionType ?? this._connector.connectionType,\n capabilities: device.capabilities,\n };\n }\n\n private _errorToFailure(error: unknown) {\n const typed = error as { code?: unknown; message?: string };\n // Map hwk-trezor-core's string markers to standard HardwareErrorCodes.\n // The core tags pairing-handshake rejections (e.g. mistyped CodeEntry code)\n // with `code: 'ThpPairingFailed'`; surface it as a proper code, not Unknown.\n if (typed.code === 'ThpPairingFailed') {\n return failure(HardwareErrorCode.ThpPairingFailed, typed.message ?? 'THP pairing failed');\n }\n // Only trust a numeric `code` if it is an actual HardwareErrorCode. A raw\n // WebUSB AbortError carries a DOMException `code: 20`, which is NOT one of\n // ours — fall through to message-based mapping (transferOut/USBDevice abort\n // → TransportError) so it surfaces as a recognizable, retryable transport\n // error instead of Unknown.\n const trustedNumericCode =\n typeof typed.code === 'number' && KNOWN_HARDWARE_ERROR_CODES.has(typed.code)\n ? typed.code\n : undefined;\n const code =\n trustedNumericCode ??\n TrezorAdapter._mapTrezorFailureCode(error) ??\n HardwareErrorCode.UnknownError;\n return failure(code, typed.message ?? String(error));\n }\n\n /**\n * Emit `REQUEST_DEVICE_PERMISSION` and await the host's\n * `RECEIVE_DEVICE_PERMISSION` reply (60s budget covers OS prompt + user\n * tap). If the host doesn't wire a handler the wait times out and the\n * operation fails fast.\n *\n * Mirrors LedgerAdapter._ensureDevicePermission so hosts can register a\n * single handler that branches by `payload.transportType` (and optionally\n * the active brand) instead of teaching every adapter its own contract.\n *\n * - no `connectId` → environment-level check (scan / picker)\n * - with `connectId` → device-level check (per-call gating)\n */\n private async _ensureDevicePermission(connectId?: string, deviceId?: string): Promise<void> {\n // No handler? Skip silently so non-permission-aware hosts (and our own\n // unit tests) keep working — Ledger's adapter has a 60s timeout but\n // hardware-wallet flows on web/desktop don't always have a registered\n // listener, and they shouldn't stall for a minute waiting on one.\n if (!this._emitter.listenerCount(UI_REQUEST.REQUEST_DEVICE_PERMISSION)) {\n return;\n }\n const transportType: TransportType = this.activeTransport ?? 'usb';\n\n const waitPromise = this._uiRegistry.wait<{ granted: boolean; reason?: string }>(\n UI_REQUEST.REQUEST_DEVICE_PERMISSION,\n { timeoutMs: 60_000 }\n );\n\n this._emitter.emit(UI_REQUEST.REQUEST_DEVICE_PERMISSION, {\n type: UI_REQUEST.REQUEST_DEVICE_PERMISSION,\n payload: { transportType, connectId, deviceId },\n });\n\n const { granted } = await waitPromise;\n if (!granted) {\n throw Object.assign(new Error('Device permission denied'), {\n code: HardwareErrorCode.DevicePermissionDenied,\n });\n }\n }\n}\n","/**\n * SDK-global event bus. Per-runtime singleton; hosts forward events over their\n * own IPC when the adapter runs in an offscreen/background split.\n */\n\nexport type SdkLogEvent = {\n type: 'log';\n level: 'debug' | 'info' | 'warn' | 'error';\n /** Pre-stringified payload. */\n message: string;\n};\n\nexport type SdkEvent = SdkLogEvent;\n\nexport type SdkEventListener = (event: SdkEvent) => void;\n\nconst listeners = new Set<SdkEventListener>();\n\nexport function onSdkEvent(listener: SdkEventListener): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\nexport function offSdkEvent(listener: SdkEventListener): void {\n listeners.delete(listener);\n}\n\nexport function emitSdkEvent(event: SdkEvent): void {\n if (listeners.size === 0) return;\n for (const listener of listeners) {\n try {\n listener(event);\n } catch {\n // Logging subscribers must not affect SDK execution.\n }\n }\n}\n\nexport function emitLog(level: SdkLogEvent['level'], ...args: unknown[]): void {\n if (listeners.size === 0) return;\n const message = args.map(a => (typeof a === 'string' ? a : safeStringify(a))).join(' ');\n emitSdkEvent({ type: 'log', level, message });\n}\n\nfunction safeStringify(value: unknown): string {\n if (value instanceof Error) {\n return value.stack ? `${value.message}\\n${value.stack}` : value.message;\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n","import { emitLog } from './sdkEventBus';\n\nexport function debugLog(...args: unknown[]): void {\n emitLog('debug', ...args);\n}\n\nexport function debugError(...args: unknown[]): void {\n emitLog('error', ...args);\n}\n","import type { EvmEthereumDefinitions } from '@onekeyfe/hwk-adapter-core';\n\n/**\n * Opt-in helpers for fetching Trezor Ethereum \"definitions\" — the SatoshiLabs-\n * signed network/token metadata a Trezor device uses to render friendly names\n * for chains and tokens that are NOT built into firmware.\n *\n * IMPORTANT — the SDK signing methods (evmSignTransaction / evmGetAddress / …)\n * NEVER call these. A local hardware operation must not silently become a\n * third-party network request (see PR #824 review). The caller decides whether,\n * when, and where to fetch, then passes the result into the sign params as\n * `ethereumDefinitions`. When omitted, the device falls back to a generic\n * confirmation screen and signing still completes.\n *\n * Cross-process note: `fetchImpl` is a FUNCTION and cannot be serialized across\n * an IPC / postMessage boundary. Call these helpers in a network-capable\n * process and send only the resulting hex strings to the process that talks\n * to the device. Use `baseUrl` (a string) to route through your own\n * controlled proxy instead of hitting data.trezor.io directly.\n */\n\n/** Default upstream (Trezor). Override with `baseUrl` to use your own proxy. */\nexport const DEFAULT_ETHEREUM_DEFINITIONS_BASE_URL =\n 'https://data.trezor.io/firmware/eth-definitions';\n\nexport type FetchLike = (url: string) => Promise<{\n status: number;\n arrayBuffer(): Promise<ArrayBuffer>;\n}>;\n\nexport type FetchEthereumDefinitionsParams = {\n chainId?: number;\n slip44?: number;\n contractAddress?: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\nexport type BuildEthereumDefinitionsForPathParams = {\n path: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\nexport type BuildEthereumDefinitionsForSignTxParams = {\n path: string;\n chainId: number;\n to?: string;\n data?: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\n/** Derive the SLIP-44 coin type (unhardened) from a BIP44-style path. */\nexport function getSlip44FromPath(path: string): number {\n const segments = path.trim().replace(/^m\\//i, '').split('/');\n const coinType = segments[1];\n const parsed = coinType === undefined ? NaN : Number(coinType.replace(/['hH]$/, ''));\n if (!Number.isFinite(parsed)) {\n throw new Error(`Cannot derive SLIP-44 coin type from path: ${path}`);\n }\n return parsed >= 0x80000000 ? parsed - 0x80000000 : parsed;\n}\n\nexport async function fetchEthereumDefinitions({\n chainId,\n slip44,\n contractAddress,\n baseUrl = DEFAULT_ETHEREUM_DEFINITIONS_BASE_URL,\n fetchImpl = globalThis.fetch,\n}: FetchEthereumDefinitionsParams): Promise<EvmEthereumDefinitions> {\n if (!chainId && !slip44) {\n throw new Error('fetchEthereumDefinitions requires chainId or slip44');\n }\n if (!fetchImpl) {\n return {};\n }\n\n const mode = chainId ? 'chain-id' : 'slip44';\n const id = chainId ?? slip44;\n const definitions: EvmEthereumDefinitions = {};\n\n const network = await fetchDefinitionHex(`${baseUrl}/${mode}/${id}/network.dat`, fetchImpl);\n if (network) {\n definitions.encodedNetwork = network;\n }\n\n if (contractAddress) {\n const token = await fetchDefinitionHex(\n `${baseUrl}/${mode}/${id}/token-${stripHexPrefix(contractAddress).toLowerCase()}.dat`,\n fetchImpl\n );\n if (token) {\n definitions.encodedToken = token;\n }\n }\n\n return definitions;\n}\n\nexport async function buildEthereumDefinitionsForPath({\n path,\n baseUrl,\n fetchImpl,\n}: BuildEthereumDefinitionsForPathParams): Promise<EvmEthereumDefinitions> {\n return fetchEthereumDefinitions({\n slip44: getSlip44FromPath(path),\n baseUrl,\n fetchImpl,\n });\n}\n\nexport async function buildEthereumDefinitionsForSignTx({\n path,\n chainId,\n to,\n data,\n baseUrl,\n fetchImpl,\n}: BuildEthereumDefinitionsForSignTxParams): Promise<EvmEthereumDefinitions | undefined> {\n const dataHex = stripHexPrefix(data ?? '');\n if (chainId === 1 && !dataHex) {\n return undefined;\n }\n return fetchEthereumDefinitions({\n chainId,\n slip44: getSlip44FromPath(path),\n contractAddress: dataHex && to ? to : undefined,\n baseUrl,\n fetchImpl,\n });\n}\n\nasync function fetchDefinitionHex(url: string, fetchImpl: FetchLike): Promise<string | undefined> {\n try {\n const response = await fetchImpl(url);\n if (response.status !== 200) {\n return undefined;\n }\n return arrayBufferToHex(await response.arrayBuffer());\n } catch {\n return undefined;\n }\n}\n\nfunction arrayBufferToHex(value: ArrayBuffer): string {\n return Buffer.from(value).toString('hex');\n}\n\nfunction stripHexPrefix(value: string): string {\n return value.startsWith('0x') || value.startsWith('0X') ? value.slice(2) : value;\n}\n","import type { FetchLike } from './ethereumDefinitions';\n\n/**\n * Opt-in helper for fetching a Trezor Solana token definition. Same contract as\n * the Ethereum helpers (see ./ethereumDefinitions): the SDK signing path NEVER\n * calls this — the caller fetches (through its own `baseUrl` proxy if desired)\n * and passes the bytes into `solSignTransaction` params as\n * `additionalInfo.encodedToken`. When omitted the device shows a generic token\n * confirmation screen and signing still completes.\n *\n * `fetchImpl` is a function and must not cross an IPC boundary — fetch in a\n * network-capable process and pass only the resulting hex string.\n */\n\n/** Default upstream (Trezor). Override with `baseUrl` to use your own proxy. */\nexport const DEFAULT_SOLANA_TOKEN_DEFINITION_BASE_URL =\n 'https://data.trezor.io/firmware/definitions/solana/token';\n\nexport type FetchSolanaTokenDefinitionParams = {\n tokenMint: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\nexport async function fetchSolanaTokenDefinition({\n tokenMint,\n baseUrl = DEFAULT_SOLANA_TOKEN_DEFINITION_BASE_URL,\n fetchImpl = globalThis.fetch,\n}: FetchSolanaTokenDefinitionParams): Promise<string | undefined> {\n if (!fetchImpl) {\n return undefined;\n }\n try {\n const response = await fetchImpl(`${baseUrl}/${tokenMint}.dat`);\n if (response.status !== 200) {\n return undefined;\n }\n return Buffer.from(await response.arrayBuffer()).toString('hex');\n } catch {\n return undefined;\n }\n}\n","export const TREZOR_SAFE_7_MODEL = 'T3W1';\n\nexport const TREZOR_BLE_SUPPORTED_MODELS = [TREZOR_SAFE_7_MODEL] as const;\n\nexport const TREZOR_BLE_PACKET_SIZE = 244;\n\nexport const TREZOR_BLE_UUIDS = {\n service: '8c000001-a59b-4d58-a9ad-073df69fa1b1',\n write: '8c000002-a59b-4d58-a9ad-073df69fa1b1',\n notify: '8c000003-a59b-4d58-a9ad-073df69fa1b1',\n push: '8c000004-a59b-4d58-a9ad-073df69fa1b1',\n batteryService: '0000180f-0000-1000-8000-00805f9b34fb',\n} as const;\n","import { TREZOR_BLE_SUPPORTED_MODELS, TREZOR_BLE_UUIDS } from '../constants';\n\nimport type { TrezorBleDescriptor } from '../types';\n\nexport function isTrezorSafe7BleName(name?: string): boolean {\n if (!name) return false;\n return /\\bTrezor\\b/i.test(name) && (/\\bSafe\\s*7\\b/i.test(name) || /\\bT3W1\\b/i.test(name));\n}\n\nexport function isTrezorBleSupportedModel(model?: string): boolean {\n if (!model) return false;\n const normalizedModel = model.trim().replace(/\\s+/g, ' ').toLowerCase();\n return (\n TREZOR_BLE_SUPPORTED_MODELS.some(\n supportedModel => supportedModel.toLowerCase() === normalizedModel\n ) ||\n normalizedModel === 'safe 7' ||\n normalizedModel === 'trezor safe 7'\n );\n}\n\nexport function isTrezorSafe7BleDescriptor(descriptor: TrezorBleDescriptor): boolean {\n return isTrezorBleDescriptor(descriptor);\n}\n\nexport function normalizeTrezorBleUuid(uuid: string): string {\n return uuid.replace(/-/g, '').toLowerCase();\n}\n\nexport function isTrezorBleServiceUuid(uuid: string): boolean {\n return normalizeTrezorBleUuid(uuid) === normalizeTrezorBleUuid(TREZOR_BLE_UUIDS.service);\n}\n\nexport function isTrezorBleDescriptor(descriptor: TrezorBleDescriptor): boolean {\n const serviceUuids = [\n ...(descriptor.serviceUUIDs ?? []),\n ...(descriptor.advertisedServiceUuids ?? []),\n ...(descriptor.serviceUuids ?? []),\n ];\n return serviceUuids.some(isTrezorBleServiceUuid);\n}\n\nexport function resolveTrezorBleConnectId(descriptor: TrezorBleDescriptor): string {\n return descriptor.id ?? descriptor.path ?? descriptor.deviceId ?? descriptor.name ?? '';\n}\n"]}
package/dist/index.mjs CHANGED
@@ -453,6 +453,9 @@ var TrezorAdapter = class _TrezorAdapter {
453
453
  async allNetworkGetAddress(connectId, deviceId, params) {
454
454
  let liveDeviceId = "";
455
455
  const topLevelFailureIndexes = /* @__PURE__ */ new Set();
456
+ const isSingleNetworkBundle = params.bundle.every(
457
+ (item) => item.network === params.bundle[0]?.network
458
+ );
456
459
  const getLiveDeviceId = async () => {
457
460
  if (liveDeviceId) return success(liveDeviceId);
458
461
  const deviceIdResponse = await this._getTrezorDeviceId(connectId);
@@ -508,7 +511,12 @@ var TrezorAdapter = class _TrezorAdapter {
508
511
  }
509
512
  };
510
513
  },
511
- shouldAbortBundle: (_response, { index }) => topLevelFailureIndexes.has(index)
514
+ // One named boolean per abort reason.
515
+ shouldAbortBundle: (response, { index }) => {
516
+ const isSessionLevelFailure = topLevelFailureIndexes.has(index);
517
+ const isWholeChainForbidden = isSingleNetworkBundle && response.payload?.code === HardwareErrorCode.DevicePathForbidden;
518
+ return isSessionLevelFailure || isWholeChainForbidden;
519
+ }
512
520
  });
513
521
  }
514
522
  getFeatures(connectId) {
@@ -1121,12 +1129,12 @@ async function fetchEthereumDefinitions({
1121
1129
  const mode = chainId ? "chain-id" : "slip44";
1122
1130
  const id = chainId ?? slip44;
1123
1131
  const definitions = {};
1124
- const network = await fetchDefinition(`${baseUrl}/${mode}/${id}/network.dat`, fetchImpl);
1132
+ const network = await fetchDefinitionHex(`${baseUrl}/${mode}/${id}/network.dat`, fetchImpl);
1125
1133
  if (network) {
1126
1134
  definitions.encodedNetwork = network;
1127
1135
  }
1128
1136
  if (contractAddress) {
1129
- const token = await fetchDefinition(
1137
+ const token = await fetchDefinitionHex(
1130
1138
  `${baseUrl}/${mode}/${id}/token-${stripHexPrefix(contractAddress).toLowerCase()}.dat`,
1131
1139
  fetchImpl
1132
1140
  );
@@ -1167,17 +1175,20 @@ async function buildEthereumDefinitionsForSignTx({
1167
1175
  fetchImpl
1168
1176
  });
1169
1177
  }
1170
- async function fetchDefinition(url, fetchImpl) {
1178
+ async function fetchDefinitionHex(url, fetchImpl) {
1171
1179
  try {
1172
1180
  const response = await fetchImpl(url);
1173
1181
  if (response.status !== 200) {
1174
1182
  return void 0;
1175
1183
  }
1176
- return await response.arrayBuffer();
1184
+ return arrayBufferToHex(await response.arrayBuffer());
1177
1185
  } catch {
1178
1186
  return void 0;
1179
1187
  }
1180
1188
  }
1189
+ function arrayBufferToHex(value) {
1190
+ return Buffer.from(value).toString("hex");
1191
+ }
1181
1192
  function stripHexPrefix(value) {
1182
1193
  return value.startsWith("0x") || value.startsWith("0X") ? value.slice(2) : value;
1183
1194
  }
@@ -1197,7 +1208,7 @@ async function fetchSolanaTokenDefinition({
1197
1208
  if (response.status !== 200) {
1198
1209
  return void 0;
1199
1210
  }
1200
- return await response.arrayBuffer();
1211
+ return Buffer.from(await response.arrayBuffer()).toString("hex");
1201
1212
  } catch {
1202
1213
  return void 0;
1203
1214
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/adapter/TrezorAdapter.ts","../src/utils/sdkEventBus.ts","../src/utils/debugLog.ts","../src/utils/ethereumDefinitions.ts","../src/utils/solanaTokenDefinition.ts","../src/constants.ts","../src/utils/bleIdentity.ts"],"sourcesContent":["import {\n DEVICE,\n DeviceJobQueue,\n HardwareErrorCode,\n TypedEventEmitter,\n UI_REQUEST,\n UI_RESPONSE,\n UiRequestRegistry,\n failure,\n rehydrateConnectorError,\n runAllNetworkGetAddress,\n success,\n} from '@onekeyfe/hwk-adapter-core';\n\nimport { debugLog } from '../utils/debugLog';\n\nimport type {\n AllNetworkAddressParams,\n AllNetworkAddressResponse,\n AllNetworkGetAddressParams,\n AllNetworkMethodName,\n BtcAddress,\n BtcGetAddressParams,\n BtcGetPublicKeyParams,\n BtcPublicKey,\n BtcSignMsgParams,\n BtcSignPsbtParams,\n BtcSignTxParams,\n BtcSignature,\n BtcSignedPsbt,\n BtcSignedTx,\n ChainCapability,\n ChainForFingerprint,\n ConnectorCallResult,\n ConnectorDevice,\n ConnectorUiEvent,\n DeviceEventListener,\n DeviceInfo,\n EvmAddress,\n EvmGetAddressParams,\n EvmSignMsgParams,\n EvmSignTxParams,\n EvmSignTypedDataParams,\n EvmSignature,\n EvmSignedTx,\n HardwareEvent,\n HardwareEventMap,\n IBtcMethods,\n ICommonCallParams,\n IConnector,\n IDeviceManagerMethods,\n IEvmMethods,\n IHardwareWallet,\n ISolMethods,\n ITronMethods,\n Response,\n SolAddress,\n SolGetAddressParams,\n SolSignMsgParams,\n SolSignTxParams,\n SolSignature,\n SolSignedTx,\n TransportType,\n TrezorBrightnessParams,\n TrezorChangePinParams,\n TrezorDeviceSettingsParams,\n TronAddress,\n TronGetAddressParams,\n TronSignMsgParams,\n TronSignTxParams,\n TronSignature,\n TronSignedTx,\n UiResponseEvent,\n} from '@onekeyfe/hwk-adapter-core';\n\n// Valid HardwareErrorCode numbers. Used to reject foreign numeric `code`s (e.g.\n// a DOMException's `code: 20` on a WebUSB AbortError) that must NOT be trusted\n// as HardwareErrorCodes — otherwise they leak through as Unknown.\nconst KNOWN_HARDWARE_ERROR_CODES = new Set<number>(\n Object.values(HardwareErrorCode).filter((value): value is number => typeof value === 'number')\n);\n\ntype NullableCallArg<T> = T | null | undefined;\n\ntype TrezorPassphraseCallParams = {\n passphraseState?: string;\n useEmptyPassphrase?: boolean;\n};\n\ntype TrezorPassphraseRequestContext = {\n passphraseState?: string;\n useEmptyPassphrase?: boolean;\n};\n\ntype TrezorVerifiedPassphraseSession = {\n sessionId: string;\n protocol: 'thp' | 'v1';\n thpSessionId?: string;\n};\n\ntype TrezorCallParams<T> = (T & ICommonCallParams & TrezorPassphraseCallParams) | null | undefined;\n\ntype TrezorCommonParams = (ICommonCallParams & TrezorPassphraseCallParams) | null | undefined;\n\ntype AsyncMethodName<T> = Extract<\n {\n [K in keyof T]-?: NonNullable<T[K]> extends (\n ...args: infer _Args\n ) => Promise<Response<infer _Payload>>\n ? K\n : never;\n }[keyof T],\n string\n>;\n\ntype TrezorWalletMethods = IEvmMethods & IBtcMethods & ISolMethods & ITronMethods;\n\ntype TrezorWalletMethodName = AsyncMethodName<TrezorWalletMethods>;\n\ntype TrezorDeviceManagerMethodName = AsyncMethodName<IDeviceManagerMethods>;\n\ntype TrezorMethodName = TrezorWalletMethodName | TrezorDeviceManagerMethodName;\n\nconst TREZOR_BTC_NETWORK_COIN_MAP: Partial<Record<string, string>> = {\n btc: 'Bitcoin',\n bitcoin: 'Bitcoin',\n tbtc: 'Testnet',\n testnet: 'Testnet',\n sbtc: 'Signet',\n signet: 'Signet',\n ltc: 'Litecoin',\n litecoin: 'Litecoin',\n doge: 'Dogecoin',\n dogecoin: 'Dogecoin',\n bch: 'Bcash',\n bcash: 'Bcash',\n dash: 'Dash',\n};\n\nexport class TrezorAdapter implements IHardwareWallet {\n readonly vendor = 'trezor' as const;\n\n private readonly _connector: IConnector;\n\n private readonly _emitter = new TypedEventEmitter<HardwareEventMap>();\n\n private readonly _devices = new Map<string, DeviceInfo>();\n\n private readonly _sessions = new Map<string, string>();\n\n private readonly _connectingPromises = new Map<string, Promise<string>>();\n\n // connectIds disconnected mid-connect; the session they produce is torn down, not cached.\n private readonly _disconnectRequested = new Set<string>();\n\n private readonly _uiRegistry = new UiRequestRegistry();\n\n private readonly _passphraseRequestContextByConnectId = new Map<\n string,\n TrezorPassphraseRequestContext\n >();\n\n private readonly _verifiedPassphraseSessionsByConnectId = new Map<\n string,\n Map<string, TrezorVerifiedPassphraseSession>\n >();\n\n // Per-device queue with preemption + AbortSignal. Same-device chain calls\n // serialize (Trezor's protocol is single-request-response — interleaving\n // desyncs THP nonce). 'safe' read methods auto-cancel each other; 'confirm'\n // sign methods emit REQUEST_PREEMPTION so the consumer can decide.\n private readonly _jobQueue: DeviceJobQueue;\n\n constructor(connector: IConnector) {\n this._connector = connector;\n // Upstream DeviceJobQueue is now a global FIFO with no built-in\n // preemption — interruptibility lives at the application layer.\n this._jobQueue = new DeviceJobQueue();\n this._registerConnectorEvents();\n }\n\n private static _createDeviceBusyError(method: string): Error {\n // Our own queued request blocks this one → DeviceBusyInternal, not \"another app\".\n return Object.assign(new Error(`Trezor is busy with another request (${method})`), {\n code: HardwareErrorCode.DeviceBusyInternal,\n });\n }\n\n /**\n * Split a Trezor-only `passphraseState` routing hint off the chain params so\n * it never reaches the protobuf layer. The connector/firmware only sees the\n * real op fields; the adapter uses `passphraseState` to align the session.\n */\n private static _normalizeCallArgs(\n connectId: NullableCallArg<string>,\n deviceId: NullableCallArg<string>,\n params: NullableCallArg<unknown>\n ): {\n connectId: string;\n params: unknown;\n } {\n return {\n connectId: connectId || deviceId || '',\n params: params ?? {},\n };\n }\n\n private static _splitCommonParams(params: unknown): {\n passphraseState?: string;\n useEmptyPassphrase?: boolean;\n rest: unknown;\n } {\n if (params && typeof params === 'object') {\n const {\n passphraseState,\n autoInstallApp: _autoInstallApp,\n useEmptyPassphrase,\n ...rest\n } = params as Record<string, unknown>;\n return {\n passphraseState: typeof passphraseState === 'string' ? passphraseState : undefined,\n useEmptyPassphrase:\n typeof useEmptyPassphrase === 'boolean' ? useEmptyPassphrase : undefined,\n rest,\n };\n }\n return { rest: params ?? {} };\n }\n\n private static _withAllNetworkRequestCommonParams(\n item: AllNetworkAddressParams,\n commonParams: TrezorCommonParams\n ): AllNetworkAddressParams {\n const autoInstallApp = commonParams?.autoInstallApp;\n const passphraseState = commonParams?.passphraseState;\n const useEmptyPassphrase = commonParams?.useEmptyPassphrase;\n if (\n autoInstallApp === undefined &&\n passphraseState === undefined &&\n useEmptyPassphrase === undefined\n ) {\n return item;\n }\n return {\n ...item,\n ...(autoInstallApp !== undefined ? { autoInstallApp } : {}),\n ...(passphraseState !== undefined ? { passphraseState } : {}),\n ...(useEmptyPassphrase !== undefined ? { useEmptyPassphrase } : {}),\n };\n }\n\n private static _sanitizeForLog(value: unknown): unknown {\n if (!value || typeof value !== 'object') return value;\n if (Array.isArray(value)) {\n return value.map(item => TrezorAdapter._sanitizeForLog(item));\n }\n const sensitiveKeys = new Set([\n 'credential',\n 'credentials',\n 'host_static_key',\n 'passphrase',\n 'passphraseState',\n 'pin',\n 'trezor_static_public_key',\n ]);\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, item]) => [\n key,\n sensitiveKeys.has(key) ? '[redacted]' : TrezorAdapter._sanitizeForLog(item),\n ])\n );\n }\n\n private static _errorForLog(error: unknown): unknown {\n if (!error || typeof error !== 'object') return error;\n const typed = error as {\n code?: unknown;\n errorCode?: unknown;\n message?: unknown;\n name?: unknown;\n response?: unknown;\n statusCode?: unknown;\n };\n return TrezorAdapter._sanitizeForLog({\n name: typed.name,\n message: typed.message,\n code: typed.code,\n errorCode: typed.errorCode,\n statusCode: typed.statusCode,\n response: typed.response,\n });\n }\n\n private _setPassphraseRequestContext(\n connectId: string,\n context: TrezorPassphraseRequestContext\n ): () => void {\n const previous = this._passphraseRequestContextByConnectId.get(connectId);\n if (context.passphraseState !== undefined || context.useEmptyPassphrase !== undefined) {\n this._passphraseRequestContextByConnectId.set(connectId, context);\n } else {\n this._passphraseRequestContextByConnectId.delete(connectId);\n }\n return () => {\n if (previous) {\n this._passphraseRequestContextByConnectId.set(connectId, previous);\n } else {\n this._passphraseRequestContextByConnectId.delete(connectId);\n }\n };\n }\n\n private static _trezorFailureMessage(error: unknown): {\n code?: unknown;\n message?: unknown;\n } {\n const response = (error as { response?: unknown } | null | undefined)?.response;\n const message = (response as { message?: unknown } | null | undefined)?.message;\n if (!message || typeof message !== 'object') return {};\n const failureMessage = message as { code?: unknown; message?: unknown };\n return {\n code: failureMessage.code,\n message: failureMessage.message,\n };\n }\n\n private static _mapTrezorFailureCode(error: unknown): HardwareErrorCode | undefined {\n const directCode = (error as { code?: unknown } | null | undefined)?.code;\n if (directCode === 'Device_InitializeFailed') {\n return HardwareErrorCode.PinCancelled;\n }\n if (directCode === 'Failure_ActionCancelled') {\n return HardwareErrorCode.UserRejected;\n }\n if (directCode === 'ThpPairingRequired') {\n return HardwareErrorCode.ThpPairingRequired;\n }\n if (directCode === 'Failure_UnexpectedMessage') {\n return HardwareErrorCode.MethodNotSupported;\n }\n const message = (error as { message?: unknown } | null | undefined)?.message;\n if (\n typeof message === 'string' &&\n message.includes(\"Failed to execute 'transfer\") &&\n message.includes(\"on 'USBDevice'\")\n ) {\n return HardwareErrorCode.TransportError;\n }\n const failure = TrezorAdapter._trezorFailureMessage(error);\n if (failure.code === 'Failure_PinCancelled') {\n return HardwareErrorCode.PinCancelled;\n }\n if (failure.code === 'Failure_PinInvalid') {\n return HardwareErrorCode.PinInvalid;\n }\n if (failure.code === 'Failure_ActionCancelled') {\n return HardwareErrorCode.UserRejected;\n }\n if (failure.code === 'Failure_ProcessError' && failure.message === 'Unsupported script type') {\n return HardwareErrorCode.MethodNotSupported;\n }\n // Device rejected the derivation path (e.g. an index outside its allowed\n // range) — distinct path-specific surface, not a generic \"method\" error.\n if (failure.code === 'Failure_DataError' && failure.message === 'Forbidden key path') {\n return HardwareErrorCode.DevicePathForbidden;\n }\n // Firmware can't process this request (e.g. EIP-712 typed data the device\n // firmware doesn't support) → surface as \"method not supported\".\n if (failure.code === 'Failure_FirmwareError') {\n return HardwareErrorCode.MethodNotSupported;\n }\n // Device firmware doesn't recognize the message (e.g. an older device asked\n // for a coin/app it lacks) → \"method not supported\", not a generic unknown.\n if (failure.code === 'Failure_UnexpectedMessage') {\n return HardwareErrorCode.MethodNotSupported;\n }\n if (failure.code === 'Failure_NotInitialized') {\n return HardwareErrorCode.DeviceNotInitialized;\n }\n // Device busy with its own op, not another app → DeviceBusyInternal.\n if (failure.code === 'Failure_Busy' || failure.code === 'Failure_InProgress') {\n return HardwareErrorCode.DeviceBusyInternal;\n }\n return undefined;\n }\n\n /**\n * Whether a device-side error code means the THP application session we\n * selected is gone (the device evicted it from its limited slot pool). The\n * caller drops the stale cache entry and recreates from scratch.\n *\n * NOTE: the exact eviction code still needs real-device confirmation — match\n * conservatively so a genuine error isn't mistaken for an evicted session\n * (which would silently re-prompt the passphrase).\n */\n private static _isStaleSessionError(code: unknown): boolean {\n if (typeof code !== 'string') return false;\n return (\n code === 'ThpUnallocatedChannel' ||\n /invalid.?session|unallocated.?session|session.?not.?found/i.test(code)\n );\n }\n\n private static _errorCode(error: unknown): unknown {\n return (error as { code?: unknown }).code ?? TrezorAdapter._trezorFailureMessage(error).code;\n }\n\n private static _isConnectionUnavailableError(error: unknown): boolean {\n const { code } = error as { code?: unknown };\n return (\n code === HardwareErrorCode.DeviceNotFound || code === HardwareErrorCode.DeviceDisconnected\n );\n }\n\n /**\n * Race a promise against an abort signal. Copied from LedgerAdapter:\n * IConnector.call() can't actually be cancelled at the protocol level, but\n * the caller gets the abort immediately and the underlying work completes\n * uselessly in the background.\n */\n private static _abortable<T>(signal: AbortSignal, promise: Promise<T>): Promise<T> {\n if (signal.aborted) {\n return Promise.reject(\n (signal as AbortSignal & { reason?: unknown }).reason ?? new Error('Aborted')\n );\n }\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n reject((signal as AbortSignal & { reason?: unknown }).reason ?? new Error('Aborted'));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n value => {\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n err => {\n signal.removeEventListener('abort', onAbort);\n reject(err);\n }\n );\n });\n }\n\n private async _connectSession(connectId: string, signal?: AbortSignal): Promise<string> {\n const connectPromise = this._connector.connect(connectId);\n const session = await (async () => {\n if (!signal) return connectPromise;\n try {\n return await TrezorAdapter._abortable(signal, connectPromise);\n } catch (error) {\n // _abortable rejected (abort/failure) but the underlying connect keeps\n // running — tear down any session it still resolves so it isn't orphaned.\n void connectPromise.then(\n orphan => this._connector.disconnect(orphan.sessionId).catch(() => undefined),\n () => undefined\n );\n throw error;\n }\n })();\n // disconnectDevice() ran mid-connect: tear down the now-unwanted session\n // instead of caching it (else it leaks a limited THP slot).\n if (this._disconnectRequested.delete(connectId)) {\n await this._connector.disconnect(session.sessionId).catch(() => undefined);\n throw Object.assign(new Error('Trezor connection aborted'), {\n code: HardwareErrorCode.UserAborted,\n });\n }\n this._sessions.set(connectId, session.sessionId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n this._devices.set(connectId, session.deviceInfo);\n return session.sessionId;\n }\n\n get activeTransport(): TransportType | null {\n return this._connector.connectionType;\n }\n\n async init(_config?: unknown): Promise<void> {}\n\n async dispose(): Promise<void> {\n this._unregisterConnectorEvents();\n this._uiRegistry.reset();\n this._jobQueue.clear();\n this._connector.reset();\n this._devices.clear();\n this._sessions.clear();\n this._verifiedPassphraseSessionsByConnectId.clear();\n this._connectingPromises.clear();\n this._emitter.removeAllListeners();\n }\n\n /**\n * Clear cached state without tearing down the adapter or unregistering\n * listeners. Mirrors LedgerAdapter.resetState() — useful for retry-after-\n * error flows. Aborts active jobs and releases UI waits.\n */\n resetState(): void {\n this._uiRegistry.reset();\n this._jobQueue.clear();\n this._devices.clear();\n this._sessions.clear();\n this._verifiedPassphraseSessionsByConnectId.clear();\n this._connectingPromises.clear();\n }\n\n getAvailableTransports(): TransportType[] {\n return this.activeTransport ? [this.activeTransport] : [];\n }\n\n async switchTransport(_type: TransportType): Promise<void> {}\n\n async searchDevices(options?: { waitForAllTransports?: boolean }): Promise<DeviceInfo[]> {\n await this._ensureDevicePermission();\n const scanned = await this._connector.searchDevices(\n options?.waitForAllTransports ? { waitForAll: true } : undefined\n );\n const scannedIds = new Set(scanned.map(d => d.connectId));\n // A rescan that misses a currently-connected device shouldn't evict it —\n // otherwise getDeviceInfo would return DeviceNotFound for an active session.\n for (const connectId of [...this._devices.keys()]) {\n if (!scannedIds.has(connectId) && !this._sessions.has(connectId)) {\n this._devices.delete(connectId);\n }\n }\n for (const device of scanned) {\n const info = this._connectorDeviceToDeviceInfo(device);\n this._devices.set(info.connectId, info);\n }\n return Array.from(this._devices.values());\n }\n\n async connectDevice(connectId: string): Promise<Response<string>> {\n try {\n await this._ensureDevicePermission(connectId);\n await this._ensureSession(connectId);\n return success(connectId);\n } catch (error) {\n return this._errorToFailure(error);\n }\n }\n\n async disconnectDevice(connectId: string): Promise<void> {\n const connecting = this._connectingPromises.has(connectId);\n this._connectingPromises.delete(connectId);\n const sessionId = this._sessions.get(connectId);\n if (!sessionId) {\n // Connect may be in flight (session not recorded yet) — mark it so\n // _connectSession tears down the session it produces instead of caching it.\n if (connecting) this._disconnectRequested.add(connectId);\n return;\n }\n this._sessions.delete(connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n await this._connector.disconnect(sessionId);\n }\n\n async getDeviceInfo(connectId: string, deviceId: string): Promise<Response<DeviceInfo>> {\n const device =\n this._devices.get(connectId) ??\n Array.from(this._devices.values()).find(item => item.deviceId === deviceId);\n if (!device) return failure(HardwareErrorCode.DeviceNotFound, 'Trezor device not found');\n return success(device);\n }\n\n getSupportedChains(): ChainCapability[] {\n // Keep in sync with TrezorConnectorBase.call()'s switch.\n // Chain inclusion means \"at least one method wired\" — per-method gaps:\n // sol: signMessage is explicitly NotSupported (firmware doesn't ship it).\n // tron: signMessage same. signTransaction uses the multi-step\n // TronContractRequest flow.\n return ['btc', 'evm', 'sol', 'tron'];\n }\n\n async allNetworkGetAddress(\n connectId: string,\n deviceId: string,\n params: AllNetworkGetAddressParams\n ): Promise<Response<AllNetworkAddressResponse[]>> {\n let liveDeviceId = '';\n const topLevelFailureIndexes = new Set<number>();\n const getLiveDeviceId = async (): Promise<Response<string>> => {\n if (liveDeviceId) return success(liveDeviceId);\n const deviceIdResponse = await this._getTrezorDeviceId(connectId);\n if (deviceIdResponse.success) {\n liveDeviceId = deviceIdResponse.payload;\n }\n return deviceIdResponse;\n };\n\n return runAllNetworkGetAddress({\n connectId,\n deviceId,\n params,\n normalizeItem: TrezorAdapter._normalizeAllNetworkItem,\n callItem: async ({ method, item, index }) => {\n const expectedDeviceId = TrezorAdapter._getItemDeviceId(item) ?? deviceId;\n if (expectedDeviceId) {\n const fingerprint = await getLiveDeviceId();\n if (!fingerprint.success) {\n topLevelFailureIndexes.add(index);\n return fingerprint;\n }\n if (expectedDeviceId !== fingerprint.payload) {\n topLevelFailureIndexes.add(index);\n return failure(\n HardwareErrorCode.DeviceMismatch,\n `Wrong device: expected ${expectedDeviceId}, got ${fingerprint.payload}`,\n { expected: expectedDeviceId, actual: fingerprint.payload }\n );\n }\n }\n const callItem = TrezorAdapter._withAllNetworkRequestCommonParams(item, params);\n return this._callAllNetworkMethod(connectId, method, callItem);\n },\n attachIdentity: async ({ item, chain, payload }) => {\n if (!liveDeviceId) {\n const fingerprint = await getLiveDeviceId();\n if (!fingerprint.success) {\n return { ...item, success: false, payload: fingerprint.payload };\n }\n }\n return {\n ...item,\n success: true,\n payload: {\n ...payload,\n deviceIdentity: {\n vendor: 'trezor',\n type: 'deviceId',\n value: liveDeviceId,\n },\n chainFingerprint: liveDeviceId,\n chainFingerprintChain: chain,\n },\n };\n },\n shouldAbortBundle: (_response, { index }) => topLevelFailureIndexes.has(index),\n });\n }\n\n getFeatures(connectId: string): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>('getFeatures', connectId, {});\n }\n\n deviceSettings(\n connectId: string,\n params: TrezorDeviceSettingsParams\n ): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>(\n 'deviceSettings',\n connectId,\n params\n );\n }\n\n setBrightness(\n connectId: string,\n params: TrezorBrightnessParams = {}\n ): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>(\n 'setBrightness',\n connectId,\n params\n );\n }\n\n changePin(\n connectId: string,\n params: TrezorChangePinParams = {}\n ): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>('changePin', connectId, params);\n }\n\n wipeDevice(connectId: string): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>('wipeDevice', connectId, {});\n }\n\n private async _getTrezorDeviceId(connectId: string): Promise<Response<string>> {\n const features = await this.getFeatures(connectId);\n if (!features.success) return features;\n const liveDeviceId = features.payload.device_id;\n if (typeof liveDeviceId !== 'string' || liveDeviceId.length === 0) {\n return failure(HardwareErrorCode.UnknownError, 'Trezor features did not include a device_id');\n }\n return success(liveDeviceId);\n }\n\n cancel(connectId?: string): void {\n const userAbortReason = Object.assign(new Error('User aborted operation'), {\n code: HardwareErrorCode.UserAborted,\n });\n // Release adapter-level UI waits (preemption) and connector-level ones\n // (THP pairing / PIN matrix) — a single CANCEL clears whichever is open.\n this._uiRegistry.cancel();\n this._connector.uiResponse({ type: UI_RESPONSE.CANCEL });\n if (connectId) {\n this._jobQueue.forceCancelActive(connectId, userAbortReason);\n void this._connector.cancel(this._sessions.get(connectId) ?? connectId);\n return;\n }\n for (const cid of this._sessions.keys()) {\n this._jobQueue.forceCancelActive(cid, userAbortReason);\n }\n for (const sessionId of this._sessions.values()) {\n void this._connector.cancel(sessionId);\n }\n }\n\n /**\n * Routes to BOTH the adapter's local UI registry (preemption decisions,\n * future SELECT_DEVICE / DEVICE_PERMISSION) AND the connector's registry\n * (THP pairing tag, PIN matrix). Each side ignores types it isn't waiting\n * for, so double-routing is harmless.\n */\n uiResponse(response: UiResponseEvent): void {\n this._uiRegistry.resolve(response.type, response.payload);\n this._connector.uiResponse(response);\n }\n\n /**\n * Returns a stable per-seed identifier suitable for device-match verification.\n *\n * Trezor exposes `device_id` in Features — a server-generated UUID written\n * during `wipe_device` and stable for the life of the seed. Unlike Ledger\n * (no native id, so a per-chain address is hashed), Trezor's id is global\n * across chains, so the `chain` argument is accepted for API parity but\n * ignored. For unsupported chains we still surface the id (since it would\n * be the same value anyway).\n */\n async getChainFingerprint(\n connectId: string,\n _deviceId: string,\n _chain: ChainForFingerprint\n ): Promise<Response<string>> {\n return this._getTrezorDeviceId(connectId);\n }\n\n /**\n * Resolve the active passphrase wallet identity (`passphraseState`).\n * See {@link IHardwareWallet.getPassphraseState} for the discover/verify\n * semantics. Returns `null` for a standard wallet (no passphrase protection) —\n * there's nothing to pin. Serialized through the per-device job queue so it\n * can't interleave with a chain call on the same device (which would desync\n * the THP session selection).\n */\n getPassphraseState(\n connectId: string,\n passphraseState?: string\n ): Promise<Response<string | null>> {\n return this._jobQueue\n .enqueue(\n connectId,\n async signal => {\n const restorePassphraseRequestContext = this._setPassphraseRequestContext(connectId, {\n passphraseState,\n });\n try {\n return await this._resolvePassphraseState(connectId, passphraseState, signal);\n } finally {\n restorePassphraseRequestContext();\n }\n },\n {\n label: 'getPassphraseState',\n rejectIfBusy: true,\n busyError: TrezorAdapter._createDeviceBusyError('getPassphraseState'),\n }\n )\n .catch(error => this._errorToFailure(error));\n }\n\n evmGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmGetAddressParams>\n ) {\n return this._callWalletMethod<EvmAddress>('evmGetAddress', connectId, deviceId, params);\n }\n\n evmSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmSignTxParams>\n ) {\n return this._callWalletMethod<EvmSignedTx>('evmSignTransaction', connectId, deviceId, params);\n }\n\n evmSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmSignMsgParams>\n ) {\n return this._callWalletMethod<EvmSignature>('evmSignMessage', connectId, deviceId, params);\n }\n\n evmSignTypedData(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmSignTypedDataParams>\n ) {\n return this._callWalletMethod<EvmSignature>('evmSignTypedData', connectId, deviceId, params);\n }\n\n btcGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcGetAddressParams>\n ) {\n return this._callWalletMethod<BtcAddress>('btcGetAddress', connectId, deviceId, params);\n }\n\n btcGetPublicKey(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcGetPublicKeyParams>\n ) {\n return this._callWalletMethod<BtcPublicKey>('btcGetPublicKey', connectId, deviceId, params);\n }\n\n btcSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcSignTxParams>\n ) {\n return this._callWalletMethod<BtcSignedTx>('btcSignTransaction', connectId, deviceId, params);\n }\n\n btcSignPsbt(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcSignPsbtParams>\n ) {\n return this._callWalletMethod<BtcSignedPsbt>('btcSignPsbt', connectId, deviceId, params);\n }\n\n btcSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcSignMsgParams>\n ) {\n return this._callWalletMethod<BtcSignature>('btcSignMessage', connectId, deviceId, params);\n }\n\n btcGetMasterFingerprint(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCommonParams\n ) {\n return this._callWalletMethod<{ masterFingerprint: string }>(\n 'btcGetMasterFingerprint',\n connectId,\n deviceId,\n params\n );\n }\n\n solGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<SolGetAddressParams>\n ) {\n return this._callWalletMethod<SolAddress>('solGetAddress', connectId, deviceId, params);\n }\n\n solSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<SolSignTxParams>\n ) {\n return this._callWalletMethod<SolSignedTx>('solSignTransaction', connectId, deviceId, params);\n }\n\n solSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<SolSignMsgParams>\n ) {\n return this._callWalletMethod<SolSignature>('solSignMessage', connectId, deviceId, params);\n }\n\n tronGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<TronGetAddressParams>\n ) {\n return this._callWalletMethod<TronAddress>('tronGetAddress', connectId, deviceId, params);\n }\n\n tronSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<TronSignTxParams>\n ) {\n return this._callWalletMethod<TronSignedTx>('tronSignTransaction', connectId, deviceId, params);\n }\n\n tronSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<TronSignMsgParams>\n ) {\n return this._callWalletMethod<TronSignature>('tronSignMessage', connectId, deviceId, params);\n }\n\n private static _unwrapConnectorResult(result: unknown): unknown {\n if (\n result &&\n typeof result === 'object' &&\n 'success' in result &&\n (((result as ConnectorCallResult).success === true && 'payload' in result) ||\n ((result as ConnectorCallResult).success === false && 'error' in result))\n ) {\n const connectorResult = result as ConnectorCallResult;\n if (connectorResult.success) return connectorResult.payload;\n throw rehydrateConnectorError(connectorResult.error);\n }\n return result;\n }\n\n private static async _callConnector(\n connector: IConnector,\n sessionId: string,\n method: string,\n params: unknown,\n signal?: AbortSignal\n ): Promise<unknown> {\n const promise = connector.call(sessionId, method, params);\n const result = signal ? await TrezorAdapter._abortable(signal, promise) : await promise;\n return TrezorAdapter._unwrapConnectorResult(result);\n }\n\n private static _normalizeAllNetworkItem(\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ): AllNetworkAddressParams {\n if (method !== 'btcGetAddress' && method !== 'btcGetPublicKey') {\n return item;\n }\n\n const itemWithCoin = item as AllNetworkAddressParams & { coin?: unknown };\n if (itemWithCoin.coin) {\n return item;\n }\n\n const network = item.network.toLowerCase();\n return {\n ...item,\n coin: TREZOR_BTC_NETWORK_COIN_MAP[network] ?? item.network,\n };\n }\n\n private static _getItemDeviceId(item: AllNetworkAddressParams): string | undefined {\n const { deviceId } = item as { deviceId?: unknown };\n return typeof deviceId === 'string' && deviceId.length > 0 ? deviceId : undefined;\n }\n\n private _callAllNetworkMethod(\n connectId: string,\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ): Promise<Response<unknown>> {\n switch (method) {\n case 'evmGetAddress':\n return this.evmGetAddress(connectId, '', item);\n case 'btcGetAddress':\n return this.btcGetAddress(connectId, '', item);\n case 'btcGetPublicKey':\n return this.btcGetPublicKey(connectId, '', item);\n case 'solGetAddress':\n return this.solGetAddress(connectId, '', item);\n case 'tronGetAddress':\n return this.tronGetAddress(connectId, '', item);\n default:\n return Promise.resolve(\n failure(\n HardwareErrorCode.InvalidParams,\n `Unsupported allNetwork method: ${String(method)}`\n )\n );\n }\n }\n\n on<K extends keyof HardwareEventMap>(\n event: K,\n listener: (event: HardwareEventMap[K]) => void\n ): void;\n\n on(event: string, listener: DeviceEventListener): void;\n\n on(event: string, listener: (event: HardwareEvent) => void): void {\n this._emitter.on(event, listener);\n }\n\n off<K extends keyof HardwareEventMap>(\n event: K,\n listener: (event: HardwareEventMap[K]) => void\n ): void;\n\n off(event: string, listener: DeviceEventListener): void;\n\n off(event: string, listener: (event: HardwareEvent) => void): void {\n this._emitter.off(event, listener);\n }\n\n private _callWalletMethod<T>(\n methodName: TrezorWalletMethodName,\n connectId: NullableCallArg<string>,\n deviceId: NullableCallArg<string>,\n params: NullableCallArg<unknown>\n ): Promise<Response<T>> {\n return this._callMethod<T>(methodName, connectId, deviceId, params, true);\n }\n\n private _callDeviceManagerMethod<T>(\n methodName: TrezorDeviceManagerMethodName,\n connectId: NullableCallArg<string>,\n params: NullableCallArg<unknown>\n ): Promise<Response<T>> {\n return this._callMethod<T>(methodName, connectId, undefined, params, false);\n }\n\n private async _callMethod<T>(\n methodName: TrezorMethodName,\n connectId: NullableCallArg<string>,\n deviceId: NullableCallArg<string>,\n params: NullableCallArg<unknown>,\n requiresWalletIntent: boolean\n ): Promise<Response<T>> {\n const call = TrezorAdapter._normalizeCallArgs(connectId, deviceId, params);\n debugLog('[TrezorAdapter][REQ]', {\n method: methodName,\n connectId: call.connectId || '(empty)',\n deviceId: deviceId || undefined,\n params: TrezorAdapter._sanitizeForLog(call.params),\n });\n try {\n const response = await this._jobQueue.enqueue(\n call.connectId,\n signal =>\n this._callWithRetry<T>(\n call.connectId,\n methodName,\n call.params,\n requiresWalletIntent,\n true,\n signal\n ),\n {\n label: methodName,\n rejectIfBusy: true,\n busyError: TrezorAdapter._createDeviceBusyError(methodName),\n }\n );\n debugLog('[TrezorAdapter][RES]', {\n method: methodName,\n success: response.success,\n payload: TrezorAdapter._sanitizeForLog(response.payload),\n });\n return response;\n } catch (error) {\n // The only way a Promise rejects out of `enqueue` is the busy-reject —\n // _callWithRetry never throws, it returns Response.failure. Convert to\n // the Response shape so chain method callers stay uniform.\n const response = this._errorToFailure(error);\n debugLog('[TrezorAdapter][RES]', {\n method: methodName,\n success: false,\n payload: TrezorAdapter._sanitizeForLog(response.payload),\n });\n return response;\n }\n }\n\n private async _callWithRetry<T>(\n connectId: string,\n methodName: TrezorMethodName,\n params: unknown,\n requiresWalletIntent: boolean,\n allowRetry: boolean,\n signal: AbortSignal\n ): Promise<Response<T>> {\n const { passphraseState, useEmptyPassphrase, rest } = TrezorAdapter._splitCommonParams(params);\n const restorePassphraseRequestContext = this._setPassphraseRequestContext(connectId, {\n passphraseState,\n useEmptyPassphrase,\n });\n try {\n const sessionId = await this._ensureSession(connectId, signal);\n if (requiresWalletIntent && !passphraseState && useEmptyPassphrase !== true) {\n return failure(\n HardwareErrorCode.InvalidParams,\n `Trezor ${methodName} requires an explicit wallet intent: passphraseState or useEmptyPassphrase`\n );\n }\n // Pin the call to the requested passphrase wallet. For THP this creates\n // a new application session; for v1 it re-initializes the device session.\n // Runs inside this queued job so the session alignment and the call can't\n // be interleaved by another request.\n if (passphraseState) {\n await TrezorAdapter._abortable(\n signal,\n this._alignAppSession(connectId, sessionId, passphraseState, signal)\n );\n } else if (useEmptyPassphrase === true) {\n await TrezorAdapter._abortable(signal, this._createFreshAppSession(sessionId, signal));\n }\n const result = await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, methodName, rest)\n );\n return success(result as T);\n } catch (error) {\n // If we were aborted, surface as-is — don't take the retry/recovery path.\n if (signal.aborted) {\n return this._errorToFailure(error);\n }\n const code = TrezorAdapter._errorCode(error);\n // On a transient disconnect (BLE drop, \"device not connected\" race after\n // the device-disconnect event hasn't propagated yet), drop the stale\n // session and reconnect once. Matches Ledger's _retryWithFreshConnection.\n if (allowRetry && code === HardwareErrorCode.DeviceDisconnected) {\n this._sessions.delete(connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n return await this._callWithRetry<T>(\n connectId,\n methodName,\n params,\n requiresWalletIntent,\n false,\n signal\n );\n }\n // The device evicted the passphrase session created for this call. Retry\n // once and recreate the requested wallet context.\n if (\n allowRetry &&\n (passphraseState || useEmptyPassphrase === true) &&\n TrezorAdapter._isStaleSessionError(code)\n ) {\n if (passphraseState) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n }\n return await this._callWithRetry<T>(\n connectId,\n methodName,\n params,\n requiresWalletIntent,\n false,\n signal\n );\n }\n debugLog('[TrezorAdapter][ERROR]', {\n method: methodName,\n connectId,\n error: TrezorAdapter._errorForLog(error),\n });\n return this._errorToFailure(error);\n } finally {\n restorePassphraseRequestContext();\n }\n }\n\n private async _ensureSession(connectId: string, signal?: AbortSignal): Promise<string> {\n const existing = this._sessions.get(connectId);\n if (existing) return existing;\n\n const pending = this._connectingPromises.get(connectId);\n if (pending) return pending;\n\n const promise = (async () => {\n try {\n if (signal?.aborted) {\n throw Object.assign(new Error('Trezor connection aborted'), {\n code: HardwareErrorCode.UserAborted,\n });\n }\n // Fail fast: a single connect attempt. On an \"unavailable device\" error we\n // drop the cached session/passphrase state and rethrow (no retry loop).\n try {\n return await this._connectSession(connectId, signal);\n } catch (error) {\n if (TrezorAdapter._isConnectionUnavailableError(error)) {\n this._sessions.delete(connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n }\n throw error;\n }\n } finally {\n this._connectingPromises.delete(connectId);\n this._disconnectRequested.delete(connectId);\n }\n })();\n\n this._connectingPromises.set(connectId, promise);\n return promise;\n }\n\n /**\n * Pin the device's active wallet session to `passphraseState` (the target\n * wallet identity) before a wallet-bound op. THP has an app-session id; v1\n * does not, but it still binds passphrase to the device session, so the\n * connector re-initializes v1 before we derive and verify.\n *\n * SECURITY: a verified THP app session may be selected again, but the adapter\n * still derives and verifies the passphrase state before any chain method can\n * run. If the cache is stale, fall back to creating a fresh wallet context.\n */\n private async _alignAppSession(\n connectId: string,\n sessionId: string,\n passphraseState: string,\n signal: AbortSignal\n ): Promise<void> {\n const reused = await this._reuseVerifiedPassphraseSession(\n connectId,\n sessionId,\n passphraseState,\n signal\n );\n if (reused) return;\n\n const created = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpCreateSession', {\n passphraseMode: 'prompt',\n })\n )) as { protocol?: string; thpSessionId?: string | null };\n // v1 has no host-managed app-session id, but the connector has just\n // re-initialized a fresh device session; continue with reactive\n // passphrase-state verification.\n if (created?.protocol === 'thp' && !created.thpSessionId) return;\n if (created?.protocol !== 'thp' && created?.protocol !== 'v1') return;\n const state = await this._deriveState(sessionId, signal);\n if (state !== passphraseState) {\n throw Object.assign(\n new Error(\n `Passphrase produced wallet ${state}, expected ${passphraseState} (passphraseState mismatch)`\n ),\n { code: HardwareErrorCode.PassphraseStateMismatch }\n );\n }\n this._rememberVerifiedPassphraseSession(connectId, passphraseState, sessionId, created);\n }\n\n private _rememberVerifiedPassphraseSession(\n connectId: string,\n passphraseState: string,\n sessionId: string,\n created: { protocol?: string; thpSessionId?: string | null } | undefined\n ): void {\n let session: TrezorVerifiedPassphraseSession | undefined;\n if (created?.protocol === 'thp' && typeof created.thpSessionId === 'string') {\n session = {\n sessionId,\n protocol: 'thp',\n thpSessionId: created.thpSessionId,\n };\n } else if (created?.protocol === 'v1') {\n session = {\n sessionId,\n protocol: 'v1',\n };\n }\n if (!session) return;\n\n const sessions =\n this._verifiedPassphraseSessionsByConnectId.get(connectId) ??\n new Map<string, TrezorVerifiedPassphraseSession>();\n sessions.set(passphraseState, session);\n this._verifiedPassphraseSessionsByConnectId.set(connectId, sessions);\n }\n\n private _forgetVerifiedPassphraseSession(connectId: string, passphraseState: string): void {\n const sessions = this._verifiedPassphraseSessionsByConnectId.get(connectId);\n if (!sessions) return;\n sessions.delete(passphraseState);\n if (!sessions.size) {\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n }\n }\n\n private async _reuseVerifiedPassphraseSession(\n connectId: string,\n sessionId: string,\n passphraseState: string,\n signal: AbortSignal\n ): Promise<boolean> {\n const cached = this._verifiedPassphraseSessionsByConnectId.get(connectId)?.get(passphraseState);\n if (!cached || cached.sessionId !== sessionId) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n return false;\n }\n\n try {\n if (cached.protocol === 'thp') {\n if (!cached.thpSessionId) return false;\n await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpSelectSession', {\n thpSessionId: cached.thpSessionId,\n })\n );\n }\n const state = await this._deriveState(sessionId, signal);\n if (state !== passphraseState) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n return false;\n }\n return true;\n } catch (error) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n if (signal.aborted) throw error;\n return false;\n }\n }\n\n private async _createFreshAppSession(sessionId: string, signal: AbortSignal): Promise<void> {\n // Create a fresh standard-wallet context for this call. Empty passphrase is\n // enforced inside connector/core, not delegated to host UI handlers.\n await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpCreateSession', {\n passphraseMode: 'empty',\n })\n );\n }\n\n /**\n * Derive the active session's passphrase state — the wallet identity used to\n * verify the right wallet is active: the compressed PUBLIC KEY at a fixed\n * account path (m/44'/0'/0'). It comes from the SAME GetPublicKey that also\n * carries the 4-byte fingerprint, but we use the FULL pubkey (not the truncated\n * fingerprint) so it's collision-resistant — the address we return can never\n * come from the wrong wallet — while avoiding OneKey's extra Testnet GetAddress.\n * Non-interactive (also unlocks via PIN as a protected derivation).\n */\n private async _deriveState(sessionId: string, signal: AbortSignal): Promise<string> {\n const derived = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, 'btcGetPublicKey', {\n path: \"m/44'/0'/0'\",\n showOnDevice: false,\n })\n )) as { publicKey?: string };\n const state = derived?.publicKey;\n if (!state) {\n throw Object.assign(new Error('Failed to derive passphrase state (wallet public key)'), {\n code: HardwareErrorCode.UnknownError,\n });\n }\n return state;\n }\n\n private async _resolvePassphraseState(\n connectId: string,\n passphraseState: string | undefined,\n signal: AbortSignal\n ): Promise<Response<string | null>> {\n try {\n const sessionId = await this._ensureSession(connectId, signal);\n if (passphraseState) {\n // Verify mode: align (which always re-derives + confirms the state) so the\n // host can gate signing on the correct wallet being active.\n await this._alignAppSession(connectId, sessionId, passphraseState, signal);\n return success(passphraseState);\n }\n // Discover mode (OneKey-aligned). DON'T trust pre-read features — a LOCKED\n // device reports an unreliable `passphrase_protection`, and the connector's\n // plain getFeatures returns a CACHED blob, so checking `unlocked` up front\n // is meaningless. Instead derive first (which unlocks), then re-read fresh:\n // 1. Create a session + derive the state. This UNLOCKS the device (PIN) and,\n // for a passphrase wallet, prompts the passphrase (THP: proactively in\n // ThpCreateNewSession; v1: reactively).\n // 2. Re-read features FRESH from the device (now unlocked → trustworthy).\n // 3. passphrase_protection === true → return the current passphrase\n // state, even if the entered passphrase was empty. Otherwise →\n // standard wallet → return null (OneKey-aligned).\n const created = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpCreateSession', {\n passphraseMode: 'prompt',\n })\n )) as { protocol?: string; thpSessionId?: string | null };\n const state = await this._deriveState(sessionId, signal);\n const features = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, 'getFeatures', { refresh: true })\n )) as Record<string, unknown> | undefined;\n if (features?.passphrase_protection !== true) {\n // Standard wallet — discard the derived state, return null (OneKey convention).\n return success(null);\n }\n this._rememberVerifiedPassphraseSession(connectId, state, sessionId, created);\n return success(state);\n } catch (error) {\n return this._errorToFailure(error);\n }\n }\n\n private _onDeviceConnect = (data: { device: ConnectorDevice }): void => {\n const device = this._connectorDeviceToDeviceInfo(data.device);\n this._devices.set(device.connectId, device);\n this._emitter.emit(DEVICE.CONNECT, { type: DEVICE.CONNECT, payload: device });\n };\n\n private _onDeviceDisconnect = (data: { connectId: string }): void => {\n this._sessions.delete(data.connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(data.connectId);\n this._devices.delete(data.connectId);\n this._emitter.emit(DEVICE.DISCONNECT, {\n type: DEVICE.DISCONNECT,\n payload: { connectId: data.connectId },\n });\n };\n\n private _onSupportFeatures = (data: {\n device: ConnectorDevice & { features: Record<string, unknown> };\n }): void => {\n const device = {\n ...this._connectorDeviceToDeviceInfo(data.device),\n features: data.device.features,\n };\n this._emitter.emit(DEVICE.FEATURES, {\n type: DEVICE.FEATURES,\n device,\n payload: { device },\n });\n };\n\n private _onUiRequest = (data: { type: string; payload?: unknown }): void => {\n if (data.type === UI_REQUEST.REQUEST_PASSPHRASE) {\n const payload =\n data.payload && typeof data.payload === 'object'\n ? (data.payload as Record<string, unknown>)\n : {};\n const connectId = typeof payload.connectId === 'string' ? payload.connectId : undefined;\n const context = connectId\n ? this._passphraseRequestContextByConnectId.get(connectId)\n : undefined;\n this._emitter.emit(\n data.type as keyof HardwareEventMap,\n {\n ...data,\n payload: {\n ...payload,\n ...(context?.passphraseState !== undefined\n ? { passphraseState: context.passphraseState }\n : {}),\n ...(context?.useEmptyPassphrase !== undefined\n ? { useEmptyPassphrase: context.useEmptyPassphrase }\n : {}),\n },\n } as never\n );\n return;\n }\n this._emitter.emit(data.type as keyof HardwareEventMap, data as never);\n };\n\n private _onUiEvent = (data: ConnectorUiEvent): void => {\n this._emitter.emit('ui-event', data);\n };\n\n private _onThpCredentialsChanged = (data: {\n connectId: string;\n deviceId?: string;\n credentials: Record<string, unknown>[];\n }): void => {\n this._emitter.emit(DEVICE.TREZOR_THP_CREDENTIALS_CHANGED, {\n type: DEVICE.TREZOR_THP_CREDENTIALS_CHANGED,\n payload: data,\n });\n };\n\n private _registerConnectorEvents(): void {\n this._connector.on('device-connect', this._onDeviceConnect);\n this._connector.on('device-disconnect', this._onDeviceDisconnect);\n this._connector.on(DEVICE.FEATURES, this._onSupportFeatures);\n this._connector.on('device-trezor-thp-credentials-changed', this._onThpCredentialsChanged);\n this._connector.on('ui-request', this._onUiRequest);\n this._connector.on('ui-event', this._onUiEvent);\n }\n\n private _unregisterConnectorEvents(): void {\n this._connector.off('device-connect', this._onDeviceConnect);\n this._connector.off('device-disconnect', this._onDeviceDisconnect);\n this._connector.off(DEVICE.FEATURES, this._onSupportFeatures);\n this._connector.off('device-trezor-thp-credentials-changed', this._onThpCredentialsChanged);\n this._connector.off('ui-request', this._onUiRequest);\n this._connector.off('ui-event', this._onUiEvent);\n }\n\n private _connectorDeviceToDeviceInfo(device: ConnectorDevice): DeviceInfo {\n return {\n vendor: 'trezor',\n model: device.model ?? 'unknown',\n firmwareVersion: 'unknown',\n deviceId: device.deviceId,\n connectId: device.connectId,\n label: device.name,\n // The per-device transport is authoritative (a combined USB+BLE\n // connector tags each discovered device); the connector's own\n // connectionType is only a nominal value, so fall back to it for\n // single-transport connectors that don't tag each device.\n connectionType: device.connectionType ?? this._connector.connectionType,\n capabilities: device.capabilities,\n };\n }\n\n private _errorToFailure(error: unknown) {\n const typed = error as { code?: unknown; message?: string };\n // Map hwk-trezor-core's string markers to standard HardwareErrorCodes.\n // The core tags pairing-handshake rejections (e.g. mistyped CodeEntry code)\n // with `code: 'ThpPairingFailed'`; surface it as a proper code, not Unknown.\n if (typed.code === 'ThpPairingFailed') {\n return failure(HardwareErrorCode.ThpPairingFailed, typed.message ?? 'THP pairing failed');\n }\n // Only trust a numeric `code` if it is an actual HardwareErrorCode. A raw\n // WebUSB AbortError carries a DOMException `code: 20`, which is NOT one of\n // ours — fall through to message-based mapping (transferOut/USBDevice abort\n // → TransportError) so it surfaces as a recognizable, retryable transport\n // error instead of Unknown.\n const trustedNumericCode =\n typeof typed.code === 'number' && KNOWN_HARDWARE_ERROR_CODES.has(typed.code)\n ? typed.code\n : undefined;\n const code =\n trustedNumericCode ??\n TrezorAdapter._mapTrezorFailureCode(error) ??\n HardwareErrorCode.UnknownError;\n return failure(code, typed.message ?? String(error));\n }\n\n /**\n * Emit `REQUEST_DEVICE_PERMISSION` and await the host's\n * `RECEIVE_DEVICE_PERMISSION` reply (60s budget covers OS prompt + user\n * tap). If the host doesn't wire a handler the wait times out and the\n * operation fails fast.\n *\n * Mirrors LedgerAdapter._ensureDevicePermission so hosts can register a\n * single handler that branches by `payload.transportType` (and optionally\n * the active brand) instead of teaching every adapter its own contract.\n *\n * - no `connectId` → environment-level check (scan / picker)\n * - with `connectId` → device-level check (per-call gating)\n */\n private async _ensureDevicePermission(connectId?: string, deviceId?: string): Promise<void> {\n // No handler? Skip silently so non-permission-aware hosts (and our own\n // unit tests) keep working — Ledger's adapter has a 60s timeout but\n // hardware-wallet flows on web/desktop don't always have a registered\n // listener, and they shouldn't stall for a minute waiting on one.\n if (!this._emitter.listenerCount(UI_REQUEST.REQUEST_DEVICE_PERMISSION)) {\n return;\n }\n const transportType: TransportType = this.activeTransport ?? 'usb';\n\n const waitPromise = this._uiRegistry.wait<{ granted: boolean; reason?: string }>(\n UI_REQUEST.REQUEST_DEVICE_PERMISSION,\n { timeoutMs: 60_000 }\n );\n\n this._emitter.emit(UI_REQUEST.REQUEST_DEVICE_PERMISSION, {\n type: UI_REQUEST.REQUEST_DEVICE_PERMISSION,\n payload: { transportType, connectId, deviceId },\n });\n\n const { granted } = await waitPromise;\n if (!granted) {\n throw Object.assign(new Error('Device permission denied'), {\n code: HardwareErrorCode.DevicePermissionDenied,\n });\n }\n }\n}\n","/**\n * SDK-global event bus. Per-runtime singleton; hosts forward events over their\n * own IPC when the adapter runs in an offscreen/background split.\n */\n\nexport type SdkLogEvent = {\n type: 'log';\n level: 'debug' | 'info' | 'warn' | 'error';\n /** Pre-stringified payload. */\n message: string;\n};\n\nexport type SdkEvent = SdkLogEvent;\n\nexport type SdkEventListener = (event: SdkEvent) => void;\n\nconst listeners = new Set<SdkEventListener>();\n\nexport function onSdkEvent(listener: SdkEventListener): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\nexport function offSdkEvent(listener: SdkEventListener): void {\n listeners.delete(listener);\n}\n\nexport function emitSdkEvent(event: SdkEvent): void {\n if (listeners.size === 0) return;\n for (const listener of listeners) {\n try {\n listener(event);\n } catch {\n // Logging subscribers must not affect SDK execution.\n }\n }\n}\n\nexport function emitLog(level: SdkLogEvent['level'], ...args: unknown[]): void {\n if (listeners.size === 0) return;\n const message = args.map(a => (typeof a === 'string' ? a : safeStringify(a))).join(' ');\n emitSdkEvent({ type: 'log', level, message });\n}\n\nfunction safeStringify(value: unknown): string {\n if (value instanceof Error) {\n return value.stack ? `${value.message}\\n${value.stack}` : value.message;\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n","import { emitLog } from './sdkEventBus';\n\nexport function debugLog(...args: unknown[]): void {\n emitLog('debug', ...args);\n}\n\nexport function debugError(...args: unknown[]): void {\n emitLog('error', ...args);\n}\n","import type { EvmEthereumDefinitions } from '@onekeyfe/hwk-adapter-core';\n\n/**\n * Opt-in helpers for fetching Trezor Ethereum \"definitions\" — the SatoshiLabs-\n * signed network/token metadata a Trezor device uses to render friendly names\n * for chains and tokens that are NOT built into firmware.\n *\n * IMPORTANT — the SDK signing methods (evmSignTransaction / evmGetAddress / …)\n * NEVER call these. A local hardware operation must not silently become a\n * third-party network request (see PR #824 review). The caller decides whether,\n * when, and where to fetch, then passes the result into the sign params as\n * `ethereumDefinitions`. When omitted, the device falls back to a generic\n * confirmation screen and signing still completes.\n *\n * Cross-process note: `fetchImpl` is a FUNCTION and cannot be serialized across\n * an IPC / postMessage boundary. Call these helpers in a network-capable\n * process and send only the resulting bytes (ArrayBuffer/hex) to the process\n * that talks to the device. Use `baseUrl` (a string) to route through your own\n * controlled proxy instead of hitting data.trezor.io directly.\n */\n\n/** Default upstream (Trezor). Override with `baseUrl` to use your own proxy. */\nexport const DEFAULT_ETHEREUM_DEFINITIONS_BASE_URL =\n 'https://data.trezor.io/firmware/eth-definitions';\n\nexport type FetchLike = (url: string) => Promise<{\n status: number;\n arrayBuffer(): Promise<ArrayBuffer>;\n}>;\n\nexport type FetchEthereumDefinitionsParams = {\n chainId?: number;\n slip44?: number;\n contractAddress?: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\nexport type BuildEthereumDefinitionsForPathParams = {\n path: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\nexport type BuildEthereumDefinitionsForSignTxParams = {\n path: string;\n chainId: number;\n to?: string;\n data?: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\n/** Derive the SLIP-44 coin type (unhardened) from a BIP44-style path. */\nexport function getSlip44FromPath(path: string): number {\n const segments = path.trim().replace(/^m\\//i, '').split('/');\n const coinType = segments[1];\n const parsed = coinType === undefined ? NaN : Number(coinType.replace(/['hH]$/, ''));\n if (!Number.isFinite(parsed)) {\n throw new Error(`Cannot derive SLIP-44 coin type from path: ${path}`);\n }\n return parsed >= 0x80000000 ? parsed - 0x80000000 : parsed;\n}\n\nexport async function fetchEthereumDefinitions({\n chainId,\n slip44,\n contractAddress,\n baseUrl = DEFAULT_ETHEREUM_DEFINITIONS_BASE_URL,\n fetchImpl = globalThis.fetch,\n}: FetchEthereumDefinitionsParams): Promise<EvmEthereumDefinitions> {\n if (!chainId && !slip44) {\n throw new Error('fetchEthereumDefinitions requires chainId or slip44');\n }\n if (!fetchImpl) {\n return {};\n }\n\n const mode = chainId ? 'chain-id' : 'slip44';\n const id = chainId ?? slip44;\n const definitions: EvmEthereumDefinitions = {};\n\n const network = await fetchDefinition(`${baseUrl}/${mode}/${id}/network.dat`, fetchImpl);\n if (network) {\n definitions.encodedNetwork = network;\n }\n\n if (contractAddress) {\n const token = await fetchDefinition(\n `${baseUrl}/${mode}/${id}/token-${stripHexPrefix(contractAddress).toLowerCase()}.dat`,\n fetchImpl\n );\n if (token) {\n definitions.encodedToken = token;\n }\n }\n\n return definitions;\n}\n\nexport async function buildEthereumDefinitionsForPath({\n path,\n baseUrl,\n fetchImpl,\n}: BuildEthereumDefinitionsForPathParams): Promise<EvmEthereumDefinitions> {\n return fetchEthereumDefinitions({\n slip44: getSlip44FromPath(path),\n baseUrl,\n fetchImpl,\n });\n}\n\nexport async function buildEthereumDefinitionsForSignTx({\n path,\n chainId,\n to,\n data,\n baseUrl,\n fetchImpl,\n}: BuildEthereumDefinitionsForSignTxParams): Promise<EvmEthereumDefinitions | undefined> {\n const dataHex = stripHexPrefix(data ?? '');\n if (chainId === 1 && !dataHex) {\n return undefined;\n }\n return fetchEthereumDefinitions({\n chainId,\n slip44: getSlip44FromPath(path),\n contractAddress: dataHex && to ? to : undefined,\n baseUrl,\n fetchImpl,\n });\n}\n\nasync function fetchDefinition(\n url: string,\n fetchImpl: FetchLike\n): Promise<ArrayBuffer | undefined> {\n try {\n const response = await fetchImpl(url);\n if (response.status !== 200) {\n return undefined;\n }\n return await response.arrayBuffer();\n } catch {\n return undefined;\n }\n}\n\nfunction stripHexPrefix(value: string): string {\n return value.startsWith('0x') || value.startsWith('0X') ? value.slice(2) : value;\n}\n","import type { FetchLike } from './ethereumDefinitions';\n\n/**\n * Opt-in helper for fetching a Trezor Solana token definition. Same contract as\n * the Ethereum helpers (see ./ethereumDefinitions): the SDK signing path NEVER\n * calls this — the caller fetches (through its own `baseUrl` proxy if desired)\n * and passes the bytes into `solSignTransaction` params as\n * `additionalInfo.encodedToken`. When omitted the device shows a generic token\n * confirmation screen and signing still completes.\n *\n * `fetchImpl` is a function and must not cross an IPC boundary — fetch in a\n * network-capable process and pass only the resulting bytes.\n */\n\n/** Default upstream (Trezor). Override with `baseUrl` to use your own proxy. */\nexport const DEFAULT_SOLANA_TOKEN_DEFINITION_BASE_URL =\n 'https://data.trezor.io/firmware/definitions/solana/token';\n\nexport type FetchSolanaTokenDefinitionParams = {\n tokenMint: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\nexport async function fetchSolanaTokenDefinition({\n tokenMint,\n baseUrl = DEFAULT_SOLANA_TOKEN_DEFINITION_BASE_URL,\n fetchImpl = globalThis.fetch,\n}: FetchSolanaTokenDefinitionParams): Promise<ArrayBuffer | undefined> {\n if (!fetchImpl) {\n return undefined;\n }\n try {\n const response = await fetchImpl(`${baseUrl}/${tokenMint}.dat`);\n if (response.status !== 200) {\n return undefined;\n }\n return await response.arrayBuffer();\n } catch {\n return undefined;\n }\n}\n","export const TREZOR_SAFE_7_MODEL = 'T3W1';\n\nexport const TREZOR_BLE_SUPPORTED_MODELS = [TREZOR_SAFE_7_MODEL] as const;\n\nexport const TREZOR_BLE_PACKET_SIZE = 244;\n\nexport const TREZOR_BLE_UUIDS = {\n service: '8c000001-a59b-4d58-a9ad-073df69fa1b1',\n write: '8c000002-a59b-4d58-a9ad-073df69fa1b1',\n notify: '8c000003-a59b-4d58-a9ad-073df69fa1b1',\n push: '8c000004-a59b-4d58-a9ad-073df69fa1b1',\n batteryService: '0000180f-0000-1000-8000-00805f9b34fb',\n} as const;\n","import { TREZOR_BLE_SUPPORTED_MODELS, TREZOR_BLE_UUIDS } from '../constants';\n\nimport type { TrezorBleDescriptor } from '../types';\n\nexport function isTrezorSafe7BleName(name?: string): boolean {\n if (!name) return false;\n return /\\bTrezor\\b/i.test(name) && (/\\bSafe\\s*7\\b/i.test(name) || /\\bT3W1\\b/i.test(name));\n}\n\nexport function isTrezorBleSupportedModel(model?: string): boolean {\n if (!model) return false;\n const normalizedModel = model.trim().replace(/\\s+/g, ' ').toLowerCase();\n return (\n TREZOR_BLE_SUPPORTED_MODELS.some(\n supportedModel => supportedModel.toLowerCase() === normalizedModel\n ) ||\n normalizedModel === 'safe 7' ||\n normalizedModel === 'trezor safe 7'\n );\n}\n\nexport function isTrezorSafe7BleDescriptor(descriptor: TrezorBleDescriptor): boolean {\n return isTrezorBleDescriptor(descriptor);\n}\n\nexport function normalizeTrezorBleUuid(uuid: string): string {\n return uuid.replace(/-/g, '').toLowerCase();\n}\n\nexport function isTrezorBleServiceUuid(uuid: string): boolean {\n return normalizeTrezorBleUuid(uuid) === normalizeTrezorBleUuid(TREZOR_BLE_UUIDS.service);\n}\n\nexport function isTrezorBleDescriptor(descriptor: TrezorBleDescriptor): boolean {\n const serviceUuids = [\n ...(descriptor.serviceUUIDs ?? []),\n ...(descriptor.advertisedServiceUuids ?? []),\n ...(descriptor.serviceUuids ?? []),\n ];\n return serviceUuids.some(isTrezorBleServiceUuid);\n}\n\nexport function resolveTrezorBleConnectId(descriptor: TrezorBleDescriptor): string {\n return descriptor.id ?? descriptor.path ?? descriptor.deviceId ?? descriptor.name ?? '';\n}\n"],"mappings":"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","names":["failure"]}
1
+ {"version":3,"sources":["../src/adapter/TrezorAdapter.ts","../src/utils/sdkEventBus.ts","../src/utils/debugLog.ts","../src/utils/ethereumDefinitions.ts","../src/utils/solanaTokenDefinition.ts","../src/constants.ts","../src/utils/bleIdentity.ts"],"sourcesContent":["import {\n DEVICE,\n DeviceJobQueue,\n HardwareErrorCode,\n TypedEventEmitter,\n UI_REQUEST,\n UI_RESPONSE,\n UiRequestRegistry,\n failure,\n rehydrateConnectorError,\n runAllNetworkGetAddress,\n success,\n} from '@onekeyfe/hwk-adapter-core';\n\nimport { debugLog } from '../utils/debugLog';\n\nimport type {\n AllNetworkAddressParams,\n AllNetworkAddressResponse,\n AllNetworkGetAddressParams,\n AllNetworkMethodName,\n BtcAddress,\n BtcGetAddressParams,\n BtcGetPublicKeyParams,\n BtcPublicKey,\n BtcSignMsgParams,\n BtcSignPsbtParams,\n BtcSignTxParams,\n BtcSignature,\n BtcSignedPsbt,\n BtcSignedTx,\n ChainCapability,\n ChainForFingerprint,\n ConnectorCallResult,\n ConnectorDevice,\n ConnectorUiEvent,\n DeviceEventListener,\n DeviceInfo,\n EvmAddress,\n EvmGetAddressParams,\n EvmSignMsgParams,\n EvmSignTxTrezorParams,\n EvmSignTypedDataParams,\n EvmSignature,\n EvmSignedTx,\n HardwareEvent,\n HardwareEventMap,\n IBtcMethods,\n ICommonCallParams,\n IConnector,\n IDeviceManagerMethods,\n IEvmMethods,\n IHardwareWallet,\n ISolMethods,\n ITronMethods,\n Response,\n SolAddress,\n SolGetAddressParams,\n SolSignMsgParams,\n SolSignTxParams,\n SolSignature,\n SolSignedTx,\n TransportType,\n TrezorBrightnessParams,\n TrezorChangePinParams,\n TrezorDeviceSettingsParams,\n TronAddress,\n TronGetAddressParams,\n TronSignMsgParams,\n TronSignTxParams,\n TronSignature,\n TronSignedTx,\n UiResponseEvent,\n} from '@onekeyfe/hwk-adapter-core';\n\n// Valid HardwareErrorCode numbers. Used to reject foreign numeric `code`s (e.g.\n// a DOMException's `code: 20` on a WebUSB AbortError) that must NOT be trusted\n// as HardwareErrorCodes — otherwise they leak through as Unknown.\nconst KNOWN_HARDWARE_ERROR_CODES = new Set<number>(\n Object.values(HardwareErrorCode).filter((value): value is number => typeof value === 'number')\n);\n\ntype NullableCallArg<T> = T | null | undefined;\n\ntype TrezorPassphraseCallParams = {\n passphraseState?: string;\n useEmptyPassphrase?: boolean;\n};\n\ntype TrezorPassphraseRequestContext = {\n passphraseState?: string;\n useEmptyPassphrase?: boolean;\n};\n\ntype TrezorVerifiedPassphraseSession = {\n sessionId: string;\n protocol: 'thp' | 'v1';\n thpSessionId?: string;\n};\n\ntype TrezorCallParams<T> = (T & ICommonCallParams & TrezorPassphraseCallParams) | null | undefined;\n\ntype TrezorCommonParams = (ICommonCallParams & TrezorPassphraseCallParams) | null | undefined;\n\ntype AsyncMethodName<T> = Extract<\n {\n [K in keyof T]-?: NonNullable<T[K]> extends (\n ...args: infer _Args\n ) => Promise<Response<infer _Payload>>\n ? K\n : never;\n }[keyof T],\n string\n>;\n\ntype TrezorWalletMethods = IEvmMethods & IBtcMethods & ISolMethods & ITronMethods;\n\ntype TrezorWalletMethodName = AsyncMethodName<TrezorWalletMethods>;\n\ntype TrezorDeviceManagerMethodName = AsyncMethodName<IDeviceManagerMethods>;\n\ntype TrezorMethodName = TrezorWalletMethodName | TrezorDeviceManagerMethodName;\n\nconst TREZOR_BTC_NETWORK_COIN_MAP: Partial<Record<string, string>> = {\n btc: 'Bitcoin',\n bitcoin: 'Bitcoin',\n tbtc: 'Testnet',\n testnet: 'Testnet',\n sbtc: 'Signet',\n signet: 'Signet',\n ltc: 'Litecoin',\n litecoin: 'Litecoin',\n doge: 'Dogecoin',\n dogecoin: 'Dogecoin',\n bch: 'Bcash',\n bcash: 'Bcash',\n dash: 'Dash',\n};\n\nexport class TrezorAdapter implements IHardwareWallet {\n readonly vendor = 'trezor' as const;\n\n private readonly _connector: IConnector;\n\n private readonly _emitter = new TypedEventEmitter<HardwareEventMap>();\n\n private readonly _devices = new Map<string, DeviceInfo>();\n\n private readonly _sessions = new Map<string, string>();\n\n private readonly _connectingPromises = new Map<string, Promise<string>>();\n\n // connectIds disconnected mid-connect; the session they produce is torn down, not cached.\n private readonly _disconnectRequested = new Set<string>();\n\n private readonly _uiRegistry = new UiRequestRegistry();\n\n private readonly _passphraseRequestContextByConnectId = new Map<\n string,\n TrezorPassphraseRequestContext\n >();\n\n private readonly _verifiedPassphraseSessionsByConnectId = new Map<\n string,\n Map<string, TrezorVerifiedPassphraseSession>\n >();\n\n // Per-device queue with preemption + AbortSignal. Same-device chain calls\n // serialize (Trezor's protocol is single-request-response — interleaving\n // desyncs THP nonce). 'safe' read methods auto-cancel each other; 'confirm'\n // sign methods emit REQUEST_PREEMPTION so the consumer can decide.\n private readonly _jobQueue: DeviceJobQueue;\n\n constructor(connector: IConnector) {\n this._connector = connector;\n // Upstream DeviceJobQueue is now a global FIFO with no built-in\n // preemption — interruptibility lives at the application layer.\n this._jobQueue = new DeviceJobQueue();\n this._registerConnectorEvents();\n }\n\n private static _createDeviceBusyError(method: string): Error {\n // Our own queued request blocks this one → DeviceBusyInternal, not \"another app\".\n return Object.assign(new Error(`Trezor is busy with another request (${method})`), {\n code: HardwareErrorCode.DeviceBusyInternal,\n });\n }\n\n /**\n * Split a Trezor-only `passphraseState` routing hint off the chain params so\n * it never reaches the protobuf layer. The connector/firmware only sees the\n * real op fields; the adapter uses `passphraseState` to align the session.\n */\n private static _normalizeCallArgs(\n connectId: NullableCallArg<string>,\n deviceId: NullableCallArg<string>,\n params: NullableCallArg<unknown>\n ): {\n connectId: string;\n params: unknown;\n } {\n return {\n connectId: connectId || deviceId || '',\n params: params ?? {},\n };\n }\n\n private static _splitCommonParams(params: unknown): {\n passphraseState?: string;\n useEmptyPassphrase?: boolean;\n rest: unknown;\n } {\n if (params && typeof params === 'object') {\n const {\n passphraseState,\n autoInstallApp: _autoInstallApp,\n useEmptyPassphrase,\n ...rest\n } = params as Record<string, unknown>;\n return {\n passphraseState: typeof passphraseState === 'string' ? passphraseState : undefined,\n useEmptyPassphrase:\n typeof useEmptyPassphrase === 'boolean' ? useEmptyPassphrase : undefined,\n rest,\n };\n }\n return { rest: params ?? {} };\n }\n\n private static _withAllNetworkRequestCommonParams(\n item: AllNetworkAddressParams,\n commonParams: TrezorCommonParams\n ): AllNetworkAddressParams {\n const autoInstallApp = commonParams?.autoInstallApp;\n const passphraseState = commonParams?.passphraseState;\n const useEmptyPassphrase = commonParams?.useEmptyPassphrase;\n if (\n autoInstallApp === undefined &&\n passphraseState === undefined &&\n useEmptyPassphrase === undefined\n ) {\n return item;\n }\n return {\n ...item,\n ...(autoInstallApp !== undefined ? { autoInstallApp } : {}),\n ...(passphraseState !== undefined ? { passphraseState } : {}),\n ...(useEmptyPassphrase !== undefined ? { useEmptyPassphrase } : {}),\n };\n }\n\n private static _sanitizeForLog(value: unknown): unknown {\n if (!value || typeof value !== 'object') return value;\n if (Array.isArray(value)) {\n return value.map(item => TrezorAdapter._sanitizeForLog(item));\n }\n const sensitiveKeys = new Set([\n 'credential',\n 'credentials',\n 'host_static_key',\n 'passphrase',\n 'passphraseState',\n 'pin',\n 'trezor_static_public_key',\n ]);\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, item]) => [\n key,\n sensitiveKeys.has(key) ? '[redacted]' : TrezorAdapter._sanitizeForLog(item),\n ])\n );\n }\n\n private static _errorForLog(error: unknown): unknown {\n if (!error || typeof error !== 'object') return error;\n const typed = error as {\n code?: unknown;\n errorCode?: unknown;\n message?: unknown;\n name?: unknown;\n response?: unknown;\n statusCode?: unknown;\n };\n return TrezorAdapter._sanitizeForLog({\n name: typed.name,\n message: typed.message,\n code: typed.code,\n errorCode: typed.errorCode,\n statusCode: typed.statusCode,\n response: typed.response,\n });\n }\n\n private _setPassphraseRequestContext(\n connectId: string,\n context: TrezorPassphraseRequestContext\n ): () => void {\n const previous = this._passphraseRequestContextByConnectId.get(connectId);\n if (context.passphraseState !== undefined || context.useEmptyPassphrase !== undefined) {\n this._passphraseRequestContextByConnectId.set(connectId, context);\n } else {\n this._passphraseRequestContextByConnectId.delete(connectId);\n }\n return () => {\n if (previous) {\n this._passphraseRequestContextByConnectId.set(connectId, previous);\n } else {\n this._passphraseRequestContextByConnectId.delete(connectId);\n }\n };\n }\n\n private static _trezorFailureMessage(error: unknown): {\n code?: unknown;\n message?: unknown;\n } {\n const response = (error as { response?: unknown } | null | undefined)?.response;\n const message = (response as { message?: unknown } | null | undefined)?.message;\n if (!message || typeof message !== 'object') return {};\n const failureMessage = message as { code?: unknown; message?: unknown };\n return {\n code: failureMessage.code,\n message: failureMessage.message,\n };\n }\n\n private static _mapTrezorFailureCode(error: unknown): HardwareErrorCode | undefined {\n const directCode = (error as { code?: unknown } | null | undefined)?.code;\n if (directCode === 'Device_InitializeFailed') {\n return HardwareErrorCode.PinCancelled;\n }\n if (directCode === 'Failure_ActionCancelled') {\n return HardwareErrorCode.UserRejected;\n }\n if (directCode === 'ThpPairingRequired') {\n return HardwareErrorCode.ThpPairingRequired;\n }\n if (directCode === 'Failure_UnexpectedMessage') {\n return HardwareErrorCode.MethodNotSupported;\n }\n const message = (error as { message?: unknown } | null | undefined)?.message;\n if (\n typeof message === 'string' &&\n message.includes(\"Failed to execute 'transfer\") &&\n message.includes(\"on 'USBDevice'\")\n ) {\n return HardwareErrorCode.TransportError;\n }\n const failure = TrezorAdapter._trezorFailureMessage(error);\n if (failure.code === 'Failure_PinCancelled') {\n return HardwareErrorCode.PinCancelled;\n }\n if (failure.code === 'Failure_PinInvalid') {\n return HardwareErrorCode.PinInvalid;\n }\n if (failure.code === 'Failure_ActionCancelled') {\n return HardwareErrorCode.UserRejected;\n }\n if (failure.code === 'Failure_ProcessError' && failure.message === 'Unsupported script type') {\n return HardwareErrorCode.MethodNotSupported;\n }\n // Device rejected the derivation path (e.g. an index outside its allowed\n // range) — distinct path-specific surface, not a generic \"method\" error.\n if (failure.code === 'Failure_DataError' && failure.message === 'Forbidden key path') {\n return HardwareErrorCode.DevicePathForbidden;\n }\n // Firmware can't process this request (e.g. EIP-712 typed data the device\n // firmware doesn't support) → surface as \"method not supported\".\n if (failure.code === 'Failure_FirmwareError') {\n return HardwareErrorCode.MethodNotSupported;\n }\n // Device firmware doesn't recognize the message (e.g. an older device asked\n // for a coin/app it lacks) → \"method not supported\", not a generic unknown.\n if (failure.code === 'Failure_UnexpectedMessage') {\n return HardwareErrorCode.MethodNotSupported;\n }\n if (failure.code === 'Failure_NotInitialized') {\n return HardwareErrorCode.DeviceNotInitialized;\n }\n // Device busy with its own op, not another app → DeviceBusyInternal.\n if (failure.code === 'Failure_Busy' || failure.code === 'Failure_InProgress') {\n return HardwareErrorCode.DeviceBusyInternal;\n }\n return undefined;\n }\n\n /**\n * Whether a device-side error code means the THP application session we\n * selected is gone (the device evicted it from its limited slot pool). The\n * caller drops the stale cache entry and recreates from scratch.\n *\n * NOTE: the exact eviction code still needs real-device confirmation — match\n * conservatively so a genuine error isn't mistaken for an evicted session\n * (which would silently re-prompt the passphrase).\n */\n private static _isStaleSessionError(code: unknown): boolean {\n if (typeof code !== 'string') return false;\n return (\n code === 'ThpUnallocatedChannel' ||\n /invalid.?session|unallocated.?session|session.?not.?found/i.test(code)\n );\n }\n\n private static _errorCode(error: unknown): unknown {\n return (error as { code?: unknown }).code ?? TrezorAdapter._trezorFailureMessage(error).code;\n }\n\n private static _isConnectionUnavailableError(error: unknown): boolean {\n const { code } = error as { code?: unknown };\n return (\n code === HardwareErrorCode.DeviceNotFound || code === HardwareErrorCode.DeviceDisconnected\n );\n }\n\n /**\n * Race a promise against an abort signal. Copied from LedgerAdapter:\n * IConnector.call() can't actually be cancelled at the protocol level, but\n * the caller gets the abort immediately and the underlying work completes\n * uselessly in the background.\n */\n private static _abortable<T>(signal: AbortSignal, promise: Promise<T>): Promise<T> {\n if (signal.aborted) {\n return Promise.reject(\n (signal as AbortSignal & { reason?: unknown }).reason ?? new Error('Aborted')\n );\n }\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n reject((signal as AbortSignal & { reason?: unknown }).reason ?? new Error('Aborted'));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n value => {\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n err => {\n signal.removeEventListener('abort', onAbort);\n reject(err);\n }\n );\n });\n }\n\n private async _connectSession(connectId: string, signal?: AbortSignal): Promise<string> {\n const connectPromise = this._connector.connect(connectId);\n const session = await (async () => {\n if (!signal) return connectPromise;\n try {\n return await TrezorAdapter._abortable(signal, connectPromise);\n } catch (error) {\n // _abortable rejected (abort/failure) but the underlying connect keeps\n // running — tear down any session it still resolves so it isn't orphaned.\n void connectPromise.then(\n orphan => this._connector.disconnect(orphan.sessionId).catch(() => undefined),\n () => undefined\n );\n throw error;\n }\n })();\n // disconnectDevice() ran mid-connect: tear down the now-unwanted session\n // instead of caching it (else it leaks a limited THP slot).\n if (this._disconnectRequested.delete(connectId)) {\n await this._connector.disconnect(session.sessionId).catch(() => undefined);\n throw Object.assign(new Error('Trezor connection aborted'), {\n code: HardwareErrorCode.UserAborted,\n });\n }\n this._sessions.set(connectId, session.sessionId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n this._devices.set(connectId, session.deviceInfo);\n return session.sessionId;\n }\n\n get activeTransport(): TransportType | null {\n return this._connector.connectionType;\n }\n\n async init(_config?: unknown): Promise<void> {}\n\n async dispose(): Promise<void> {\n this._unregisterConnectorEvents();\n this._uiRegistry.reset();\n this._jobQueue.clear();\n this._connector.reset();\n this._devices.clear();\n this._sessions.clear();\n this._verifiedPassphraseSessionsByConnectId.clear();\n this._connectingPromises.clear();\n this._emitter.removeAllListeners();\n }\n\n /**\n * Clear cached state without tearing down the adapter or unregistering\n * listeners. Mirrors LedgerAdapter.resetState() — useful for retry-after-\n * error flows. Aborts active jobs and releases UI waits.\n */\n resetState(): void {\n this._uiRegistry.reset();\n this._jobQueue.clear();\n this._devices.clear();\n this._sessions.clear();\n this._verifiedPassphraseSessionsByConnectId.clear();\n this._connectingPromises.clear();\n }\n\n getAvailableTransports(): TransportType[] {\n return this.activeTransport ? [this.activeTransport] : [];\n }\n\n async switchTransport(_type: TransportType): Promise<void> {}\n\n async searchDevices(options?: { waitForAllTransports?: boolean }): Promise<DeviceInfo[]> {\n await this._ensureDevicePermission();\n const scanned = await this._connector.searchDevices(\n options?.waitForAllTransports ? { waitForAll: true } : undefined\n );\n const scannedIds = new Set(scanned.map(d => d.connectId));\n // A rescan that misses a currently-connected device shouldn't evict it —\n // otherwise getDeviceInfo would return DeviceNotFound for an active session.\n for (const connectId of [...this._devices.keys()]) {\n if (!scannedIds.has(connectId) && !this._sessions.has(connectId)) {\n this._devices.delete(connectId);\n }\n }\n for (const device of scanned) {\n const info = this._connectorDeviceToDeviceInfo(device);\n this._devices.set(info.connectId, info);\n }\n return Array.from(this._devices.values());\n }\n\n async connectDevice(connectId: string): Promise<Response<string>> {\n try {\n await this._ensureDevicePermission(connectId);\n await this._ensureSession(connectId);\n return success(connectId);\n } catch (error) {\n return this._errorToFailure(error);\n }\n }\n\n async disconnectDevice(connectId: string): Promise<void> {\n const connecting = this._connectingPromises.has(connectId);\n this._connectingPromises.delete(connectId);\n const sessionId = this._sessions.get(connectId);\n if (!sessionId) {\n // Connect may be in flight (session not recorded yet) — mark it so\n // _connectSession tears down the session it produces instead of caching it.\n if (connecting) this._disconnectRequested.add(connectId);\n return;\n }\n this._sessions.delete(connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n await this._connector.disconnect(sessionId);\n }\n\n async getDeviceInfo(connectId: string, deviceId: string): Promise<Response<DeviceInfo>> {\n const device =\n this._devices.get(connectId) ??\n Array.from(this._devices.values()).find(item => item.deviceId === deviceId);\n if (!device) return failure(HardwareErrorCode.DeviceNotFound, 'Trezor device not found');\n return success(device);\n }\n\n getSupportedChains(): ChainCapability[] {\n // Keep in sync with TrezorConnectorBase.call()'s switch.\n // Chain inclusion means \"at least one method wired\" — per-method gaps:\n // sol: signMessage is explicitly NotSupported (firmware doesn't ship it).\n // tron: signMessage same. signTransaction uses the multi-step\n // TronContractRequest flow.\n return ['btc', 'evm', 'sol', 'tron'];\n }\n\n async allNetworkGetAddress(\n connectId: string,\n deviceId: string,\n params: AllNetworkGetAddressParams\n ): Promise<Response<AllNetworkAddressResponse[]>> {\n let liveDeviceId = '';\n const topLevelFailureIndexes = new Set<number>();\n const isSingleNetworkBundle = params.bundle.every(\n item => item.network === params.bundle[0]?.network\n );\n const getLiveDeviceId = async (): Promise<Response<string>> => {\n if (liveDeviceId) return success(liveDeviceId);\n const deviceIdResponse = await this._getTrezorDeviceId(connectId);\n if (deviceIdResponse.success) {\n liveDeviceId = deviceIdResponse.payload;\n }\n return deviceIdResponse;\n };\n\n return runAllNetworkGetAddress({\n connectId,\n deviceId,\n params,\n normalizeItem: TrezorAdapter._normalizeAllNetworkItem,\n callItem: async ({ method, item, index }) => {\n const expectedDeviceId = TrezorAdapter._getItemDeviceId(item) ?? deviceId;\n if (expectedDeviceId) {\n const fingerprint = await getLiveDeviceId();\n if (!fingerprint.success) {\n topLevelFailureIndexes.add(index);\n return fingerprint;\n }\n if (expectedDeviceId !== fingerprint.payload) {\n topLevelFailureIndexes.add(index);\n return failure(\n HardwareErrorCode.DeviceMismatch,\n `Wrong device: expected ${expectedDeviceId}, got ${fingerprint.payload}`,\n { expected: expectedDeviceId, actual: fingerprint.payload }\n );\n }\n }\n const callItem = TrezorAdapter._withAllNetworkRequestCommonParams(item, params);\n return this._callAllNetworkMethod(connectId, method, callItem);\n },\n attachIdentity: async ({ item, chain, payload }) => {\n if (!liveDeviceId) {\n const fingerprint = await getLiveDeviceId();\n if (!fingerprint.success) {\n return { ...item, success: false, payload: fingerprint.payload };\n }\n }\n return {\n ...item,\n success: true,\n payload: {\n ...payload,\n deviceIdentity: {\n vendor: 'trezor',\n type: 'deviceId',\n value: liveDeviceId,\n },\n chainFingerprint: liveDeviceId,\n chainFingerprintChain: chain,\n },\n };\n },\n // One named boolean per abort reason.\n shouldAbortBundle: (response, { index }) => {\n const isSessionLevelFailure = topLevelFailureIndexes.has(index);\n // Mixed bundles must not abort — other chains can still derive.\n const isWholeChainForbidden =\n isSingleNetworkBundle && response.payload?.code === HardwareErrorCode.DevicePathForbidden;\n return isSessionLevelFailure || isWholeChainForbidden;\n },\n });\n }\n\n getFeatures(connectId: string): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>('getFeatures', connectId, {});\n }\n\n deviceSettings(\n connectId: string,\n params: TrezorDeviceSettingsParams\n ): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>(\n 'deviceSettings',\n connectId,\n params\n );\n }\n\n setBrightness(\n connectId: string,\n params: TrezorBrightnessParams = {}\n ): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>(\n 'setBrightness',\n connectId,\n params\n );\n }\n\n changePin(\n connectId: string,\n params: TrezorChangePinParams = {}\n ): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>('changePin', connectId, params);\n }\n\n wipeDevice(connectId: string): Promise<Response<Record<string, unknown>>> {\n return this._callDeviceManagerMethod<Record<string, unknown>>('wipeDevice', connectId, {});\n }\n\n private async _getTrezorDeviceId(connectId: string): Promise<Response<string>> {\n const features = await this.getFeatures(connectId);\n if (!features.success) return features;\n const liveDeviceId = features.payload.device_id;\n if (typeof liveDeviceId !== 'string' || liveDeviceId.length === 0) {\n return failure(HardwareErrorCode.UnknownError, 'Trezor features did not include a device_id');\n }\n return success(liveDeviceId);\n }\n\n cancel(connectId?: string): void {\n const userAbortReason = Object.assign(new Error('User aborted operation'), {\n code: HardwareErrorCode.UserAborted,\n });\n // Release adapter-level UI waits (preemption) and connector-level ones\n // (THP pairing / PIN matrix) — a single CANCEL clears whichever is open.\n this._uiRegistry.cancel();\n this._connector.uiResponse({ type: UI_RESPONSE.CANCEL });\n if (connectId) {\n this._jobQueue.forceCancelActive(connectId, userAbortReason);\n void this._connector.cancel(this._sessions.get(connectId) ?? connectId);\n return;\n }\n for (const cid of this._sessions.keys()) {\n this._jobQueue.forceCancelActive(cid, userAbortReason);\n }\n for (const sessionId of this._sessions.values()) {\n void this._connector.cancel(sessionId);\n }\n }\n\n /**\n * Routes to BOTH the adapter's local UI registry (preemption decisions,\n * future SELECT_DEVICE / DEVICE_PERMISSION) AND the connector's registry\n * (THP pairing tag, PIN matrix). Each side ignores types it isn't waiting\n * for, so double-routing is harmless.\n */\n uiResponse(response: UiResponseEvent): void {\n this._uiRegistry.resolve(response.type, response.payload);\n this._connector.uiResponse(response);\n }\n\n /**\n * Returns a stable per-seed identifier suitable for device-match verification.\n *\n * Trezor exposes `device_id` in Features — a server-generated UUID written\n * during `wipe_device` and stable for the life of the seed. Unlike Ledger\n * (no native id, so a per-chain address is hashed), Trezor's id is global\n * across chains, so the `chain` argument is accepted for API parity but\n * ignored. For unsupported chains we still surface the id (since it would\n * be the same value anyway).\n */\n async getChainFingerprint(\n connectId: string,\n _deviceId: string,\n _chain: ChainForFingerprint\n ): Promise<Response<string>> {\n return this._getTrezorDeviceId(connectId);\n }\n\n /**\n * Resolve the active passphrase wallet identity (`passphraseState`).\n * See {@link IHardwareWallet.getPassphraseState} for the discover/verify\n * semantics. Returns `null` for a standard wallet (no passphrase protection) —\n * there's nothing to pin. Serialized through the per-device job queue so it\n * can't interleave with a chain call on the same device (which would desync\n * the THP session selection).\n */\n getPassphraseState(\n connectId: string,\n passphraseState?: string\n ): Promise<Response<string | null>> {\n return this._jobQueue\n .enqueue(\n connectId,\n async signal => {\n const restorePassphraseRequestContext = this._setPassphraseRequestContext(connectId, {\n passphraseState,\n });\n try {\n return await this._resolvePassphraseState(connectId, passphraseState, signal);\n } finally {\n restorePassphraseRequestContext();\n }\n },\n {\n label: 'getPassphraseState',\n rejectIfBusy: true,\n busyError: TrezorAdapter._createDeviceBusyError('getPassphraseState'),\n }\n )\n .catch(error => this._errorToFailure(error));\n }\n\n evmGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmGetAddressParams>\n ) {\n return this._callWalletMethod<EvmAddress>('evmGetAddress', connectId, deviceId, params);\n }\n\n evmSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmSignTxTrezorParams>\n ) {\n return this._callWalletMethod<EvmSignedTx>('evmSignTransaction', connectId, deviceId, params);\n }\n\n evmSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmSignMsgParams>\n ) {\n return this._callWalletMethod<EvmSignature>('evmSignMessage', connectId, deviceId, params);\n }\n\n evmSignTypedData(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<EvmSignTypedDataParams>\n ) {\n return this._callWalletMethod<EvmSignature>('evmSignTypedData', connectId, deviceId, params);\n }\n\n btcGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcGetAddressParams>\n ) {\n return this._callWalletMethod<BtcAddress>('btcGetAddress', connectId, deviceId, params);\n }\n\n btcGetPublicKey(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcGetPublicKeyParams>\n ) {\n return this._callWalletMethod<BtcPublicKey>('btcGetPublicKey', connectId, deviceId, params);\n }\n\n btcSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcSignTxParams>\n ) {\n return this._callWalletMethod<BtcSignedTx>('btcSignTransaction', connectId, deviceId, params);\n }\n\n btcSignPsbt(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcSignPsbtParams>\n ) {\n return this._callWalletMethod<BtcSignedPsbt>('btcSignPsbt', connectId, deviceId, params);\n }\n\n btcSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<BtcSignMsgParams>\n ) {\n return this._callWalletMethod<BtcSignature>('btcSignMessage', connectId, deviceId, params);\n }\n\n btcGetMasterFingerprint(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCommonParams\n ) {\n return this._callWalletMethod<{ masterFingerprint: string }>(\n 'btcGetMasterFingerprint',\n connectId,\n deviceId,\n params\n );\n }\n\n solGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<SolGetAddressParams>\n ) {\n return this._callWalletMethod<SolAddress>('solGetAddress', connectId, deviceId, params);\n }\n\n solSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<SolSignTxParams>\n ) {\n return this._callWalletMethod<SolSignedTx>('solSignTransaction', connectId, deviceId, params);\n }\n\n solSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<SolSignMsgParams>\n ) {\n return this._callWalletMethod<SolSignature>('solSignMessage', connectId, deviceId, params);\n }\n\n tronGetAddress(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<TronGetAddressParams>\n ) {\n return this._callWalletMethod<TronAddress>('tronGetAddress', connectId, deviceId, params);\n }\n\n tronSignTransaction(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<TronSignTxParams>\n ) {\n return this._callWalletMethod<TronSignedTx>('tronSignTransaction', connectId, deviceId, params);\n }\n\n tronSignMessage(\n connectId?: string | null,\n deviceId?: string | null,\n params?: TrezorCallParams<TronSignMsgParams>\n ) {\n return this._callWalletMethod<TronSignature>('tronSignMessage', connectId, deviceId, params);\n }\n\n private static _unwrapConnectorResult(result: unknown): unknown {\n if (\n result &&\n typeof result === 'object' &&\n 'success' in result &&\n (((result as ConnectorCallResult).success === true && 'payload' in result) ||\n ((result as ConnectorCallResult).success === false && 'error' in result))\n ) {\n const connectorResult = result as ConnectorCallResult;\n if (connectorResult.success) return connectorResult.payload;\n throw rehydrateConnectorError(connectorResult.error);\n }\n return result;\n }\n\n private static async _callConnector(\n connector: IConnector,\n sessionId: string,\n method: string,\n params: unknown,\n signal?: AbortSignal\n ): Promise<unknown> {\n const promise = connector.call(sessionId, method, params);\n const result = signal ? await TrezorAdapter._abortable(signal, promise) : await promise;\n return TrezorAdapter._unwrapConnectorResult(result);\n }\n\n private static _normalizeAllNetworkItem(\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ): AllNetworkAddressParams {\n if (method !== 'btcGetAddress' && method !== 'btcGetPublicKey') {\n return item;\n }\n\n const itemWithCoin = item as AllNetworkAddressParams & { coin?: unknown };\n if (itemWithCoin.coin) {\n return item;\n }\n\n const network = item.network.toLowerCase();\n return {\n ...item,\n coin: TREZOR_BTC_NETWORK_COIN_MAP[network] ?? item.network,\n };\n }\n\n private static _getItemDeviceId(item: AllNetworkAddressParams): string | undefined {\n const { deviceId } = item as { deviceId?: unknown };\n return typeof deviceId === 'string' && deviceId.length > 0 ? deviceId : undefined;\n }\n\n private _callAllNetworkMethod(\n connectId: string,\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ): Promise<Response<unknown>> {\n switch (method) {\n case 'evmGetAddress':\n return this.evmGetAddress(connectId, '', item);\n case 'btcGetAddress':\n return this.btcGetAddress(connectId, '', item);\n case 'btcGetPublicKey':\n return this.btcGetPublicKey(connectId, '', item);\n case 'solGetAddress':\n return this.solGetAddress(connectId, '', item);\n case 'tronGetAddress':\n return this.tronGetAddress(connectId, '', item);\n default:\n return Promise.resolve(\n failure(\n HardwareErrorCode.InvalidParams,\n `Unsupported allNetwork method: ${String(method)}`\n )\n );\n }\n }\n\n on<K extends keyof HardwareEventMap>(\n event: K,\n listener: (event: HardwareEventMap[K]) => void\n ): void;\n\n on(event: string, listener: DeviceEventListener): void;\n\n on(event: string, listener: (event: HardwareEvent) => void): void {\n this._emitter.on(event, listener);\n }\n\n off<K extends keyof HardwareEventMap>(\n event: K,\n listener: (event: HardwareEventMap[K]) => void\n ): void;\n\n off(event: string, listener: DeviceEventListener): void;\n\n off(event: string, listener: (event: HardwareEvent) => void): void {\n this._emitter.off(event, listener);\n }\n\n private _callWalletMethod<T>(\n methodName: TrezorWalletMethodName,\n connectId: NullableCallArg<string>,\n deviceId: NullableCallArg<string>,\n params: NullableCallArg<unknown>\n ): Promise<Response<T>> {\n return this._callMethod<T>(methodName, connectId, deviceId, params, true);\n }\n\n private _callDeviceManagerMethod<T>(\n methodName: TrezorDeviceManagerMethodName,\n connectId: NullableCallArg<string>,\n params: NullableCallArg<unknown>\n ): Promise<Response<T>> {\n return this._callMethod<T>(methodName, connectId, undefined, params, false);\n }\n\n private async _callMethod<T>(\n methodName: TrezorMethodName,\n connectId: NullableCallArg<string>,\n deviceId: NullableCallArg<string>,\n params: NullableCallArg<unknown>,\n requiresWalletIntent: boolean\n ): Promise<Response<T>> {\n const call = TrezorAdapter._normalizeCallArgs(connectId, deviceId, params);\n debugLog('[TrezorAdapter][REQ]', {\n method: methodName,\n connectId: call.connectId || '(empty)',\n deviceId: deviceId || undefined,\n params: TrezorAdapter._sanitizeForLog(call.params),\n });\n try {\n const response = await this._jobQueue.enqueue(\n call.connectId,\n signal =>\n this._callWithRetry<T>(\n call.connectId,\n methodName,\n call.params,\n requiresWalletIntent,\n true,\n signal\n ),\n {\n label: methodName,\n rejectIfBusy: true,\n busyError: TrezorAdapter._createDeviceBusyError(methodName),\n }\n );\n debugLog('[TrezorAdapter][RES]', {\n method: methodName,\n success: response.success,\n payload: TrezorAdapter._sanitizeForLog(response.payload),\n });\n return response;\n } catch (error) {\n // The only way a Promise rejects out of `enqueue` is the busy-reject —\n // _callWithRetry never throws, it returns Response.failure. Convert to\n // the Response shape so chain method callers stay uniform.\n const response = this._errorToFailure(error);\n debugLog('[TrezorAdapter][RES]', {\n method: methodName,\n success: false,\n payload: TrezorAdapter._sanitizeForLog(response.payload),\n });\n return response;\n }\n }\n\n private async _callWithRetry<T>(\n connectId: string,\n methodName: TrezorMethodName,\n params: unknown,\n requiresWalletIntent: boolean,\n allowRetry: boolean,\n signal: AbortSignal\n ): Promise<Response<T>> {\n const { passphraseState, useEmptyPassphrase, rest } = TrezorAdapter._splitCommonParams(params);\n const restorePassphraseRequestContext = this._setPassphraseRequestContext(connectId, {\n passphraseState,\n useEmptyPassphrase,\n });\n try {\n const sessionId = await this._ensureSession(connectId, signal);\n if (requiresWalletIntent && !passphraseState && useEmptyPassphrase !== true) {\n return failure(\n HardwareErrorCode.InvalidParams,\n `Trezor ${methodName} requires an explicit wallet intent: passphraseState or useEmptyPassphrase`\n );\n }\n // Pin the call to the requested passphrase wallet. For THP this creates\n // a new application session; for v1 it re-initializes the device session.\n // Runs inside this queued job so the session alignment and the call can't\n // be interleaved by another request.\n if (passphraseState) {\n await TrezorAdapter._abortable(\n signal,\n this._alignAppSession(connectId, sessionId, passphraseState, signal)\n );\n } else if (useEmptyPassphrase === true) {\n await TrezorAdapter._abortable(signal, this._createFreshAppSession(sessionId, signal));\n }\n const result = await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, methodName, rest)\n );\n return success(result as T);\n } catch (error) {\n // If we were aborted, surface as-is — don't take the retry/recovery path.\n if (signal.aborted) {\n return this._errorToFailure(error);\n }\n const code = TrezorAdapter._errorCode(error);\n // On a transient disconnect (BLE drop, \"device not connected\" race after\n // the device-disconnect event hasn't propagated yet), drop the stale\n // session and reconnect once. Matches Ledger's _retryWithFreshConnection.\n if (allowRetry && code === HardwareErrorCode.DeviceDisconnected) {\n this._sessions.delete(connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n return await this._callWithRetry<T>(\n connectId,\n methodName,\n params,\n requiresWalletIntent,\n false,\n signal\n );\n }\n // The device evicted the passphrase session created for this call. Retry\n // once and recreate the requested wallet context.\n if (\n allowRetry &&\n (passphraseState || useEmptyPassphrase === true) &&\n TrezorAdapter._isStaleSessionError(code)\n ) {\n if (passphraseState) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n }\n return await this._callWithRetry<T>(\n connectId,\n methodName,\n params,\n requiresWalletIntent,\n false,\n signal\n );\n }\n debugLog('[TrezorAdapter][ERROR]', {\n method: methodName,\n connectId,\n error: TrezorAdapter._errorForLog(error),\n });\n return this._errorToFailure(error);\n } finally {\n restorePassphraseRequestContext();\n }\n }\n\n private async _ensureSession(connectId: string, signal?: AbortSignal): Promise<string> {\n const existing = this._sessions.get(connectId);\n if (existing) return existing;\n\n const pending = this._connectingPromises.get(connectId);\n if (pending) return pending;\n\n const promise = (async () => {\n try {\n if (signal?.aborted) {\n throw Object.assign(new Error('Trezor connection aborted'), {\n code: HardwareErrorCode.UserAborted,\n });\n }\n // Fail fast: a single connect attempt. On an \"unavailable device\" error we\n // drop the cached session/passphrase state and rethrow (no retry loop).\n try {\n return await this._connectSession(connectId, signal);\n } catch (error) {\n if (TrezorAdapter._isConnectionUnavailableError(error)) {\n this._sessions.delete(connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n }\n throw error;\n }\n } finally {\n this._connectingPromises.delete(connectId);\n this._disconnectRequested.delete(connectId);\n }\n })();\n\n this._connectingPromises.set(connectId, promise);\n return promise;\n }\n\n /**\n * Pin the device's active wallet session to `passphraseState` (the target\n * wallet identity) before a wallet-bound op. THP has an app-session id; v1\n * does not, but it still binds passphrase to the device session, so the\n * connector re-initializes v1 before we derive and verify.\n *\n * SECURITY: a verified THP app session may be selected again, but the adapter\n * still derives and verifies the passphrase state before any chain method can\n * run. If the cache is stale, fall back to creating a fresh wallet context.\n */\n private async _alignAppSession(\n connectId: string,\n sessionId: string,\n passphraseState: string,\n signal: AbortSignal\n ): Promise<void> {\n const reused = await this._reuseVerifiedPassphraseSession(\n connectId,\n sessionId,\n passphraseState,\n signal\n );\n if (reused) return;\n\n const created = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpCreateSession', {\n passphraseMode: 'prompt',\n })\n )) as { protocol?: string; thpSessionId?: string | null };\n // v1 has no host-managed app-session id, but the connector has just\n // re-initialized a fresh device session; continue with reactive\n // passphrase-state verification.\n if (created?.protocol === 'thp' && !created.thpSessionId) return;\n if (created?.protocol !== 'thp' && created?.protocol !== 'v1') return;\n const state = await this._deriveState(sessionId, signal);\n if (state !== passphraseState) {\n throw Object.assign(\n new Error(\n `Passphrase produced wallet ${state}, expected ${passphraseState} (passphraseState mismatch)`\n ),\n { code: HardwareErrorCode.PassphraseStateMismatch }\n );\n }\n this._rememberVerifiedPassphraseSession(connectId, passphraseState, sessionId, created);\n }\n\n private _rememberVerifiedPassphraseSession(\n connectId: string,\n passphraseState: string,\n sessionId: string,\n created: { protocol?: string; thpSessionId?: string | null } | undefined\n ): void {\n let session: TrezorVerifiedPassphraseSession | undefined;\n if (created?.protocol === 'thp' && typeof created.thpSessionId === 'string') {\n session = {\n sessionId,\n protocol: 'thp',\n thpSessionId: created.thpSessionId,\n };\n } else if (created?.protocol === 'v1') {\n session = {\n sessionId,\n protocol: 'v1',\n };\n }\n if (!session) return;\n\n const sessions =\n this._verifiedPassphraseSessionsByConnectId.get(connectId) ??\n new Map<string, TrezorVerifiedPassphraseSession>();\n sessions.set(passphraseState, session);\n this._verifiedPassphraseSessionsByConnectId.set(connectId, sessions);\n }\n\n private _forgetVerifiedPassphraseSession(connectId: string, passphraseState: string): void {\n const sessions = this._verifiedPassphraseSessionsByConnectId.get(connectId);\n if (!sessions) return;\n sessions.delete(passphraseState);\n if (!sessions.size) {\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\n }\n }\n\n private async _reuseVerifiedPassphraseSession(\n connectId: string,\n sessionId: string,\n passphraseState: string,\n signal: AbortSignal\n ): Promise<boolean> {\n const cached = this._verifiedPassphraseSessionsByConnectId.get(connectId)?.get(passphraseState);\n if (!cached || cached.sessionId !== sessionId) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n return false;\n }\n\n try {\n if (cached.protocol === 'thp') {\n if (!cached.thpSessionId) return false;\n await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpSelectSession', {\n thpSessionId: cached.thpSessionId,\n })\n );\n }\n const state = await this._deriveState(sessionId, signal);\n if (state !== passphraseState) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n return false;\n }\n return true;\n } catch (error) {\n this._forgetVerifiedPassphraseSession(connectId, passphraseState);\n if (signal.aborted) throw error;\n return false;\n }\n }\n\n private async _createFreshAppSession(sessionId: string, signal: AbortSignal): Promise<void> {\n // Create a fresh standard-wallet context for this call. Empty passphrase is\n // enforced inside connector/core, not delegated to host UI handlers.\n await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpCreateSession', {\n passphraseMode: 'empty',\n })\n );\n }\n\n /**\n * Derive the active session's passphrase state — the wallet identity used to\n * verify the right wallet is active: the compressed PUBLIC KEY at a fixed\n * account path (m/44'/0'/0'). It comes from the SAME GetPublicKey that also\n * carries the 4-byte fingerprint, but we use the FULL pubkey (not the truncated\n * fingerprint) so it's collision-resistant — the address we return can never\n * come from the wrong wallet — while avoiding OneKey's extra Testnet GetAddress.\n * Non-interactive (also unlocks via PIN as a protected derivation).\n */\n private async _deriveState(sessionId: string, signal: AbortSignal): Promise<string> {\n const derived = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, 'btcGetPublicKey', {\n path: \"m/44'/0'/0'\",\n showOnDevice: false,\n })\n )) as { publicKey?: string };\n const state = derived?.publicKey;\n if (!state) {\n throw Object.assign(new Error('Failed to derive passphrase state (wallet public key)'), {\n code: HardwareErrorCode.UnknownError,\n });\n }\n return state;\n }\n\n private async _resolvePassphraseState(\n connectId: string,\n passphraseState: string | undefined,\n signal: AbortSignal\n ): Promise<Response<string | null>> {\n try {\n const sessionId = await this._ensureSession(connectId, signal);\n if (passphraseState) {\n // Verify mode: align (which always re-derives + confirms the state) so the\n // host can gate signing on the correct wallet being active.\n await this._alignAppSession(connectId, sessionId, passphraseState, signal);\n return success(passphraseState);\n }\n // Discover mode (OneKey-aligned). DON'T trust pre-read features — a LOCKED\n // device reports an unreliable `passphrase_protection`, and the connector's\n // plain getFeatures returns a CACHED blob, so checking `unlocked` up front\n // is meaningless. Instead derive first (which unlocks), then re-read fresh:\n // 1. Create a session + derive the state. This UNLOCKS the device (PIN) and,\n // for a passphrase wallet, prompts the passphrase (THP: proactively in\n // ThpCreateNewSession; v1: reactively).\n // 2. Re-read features FRESH from the device (now unlocked → trustworthy).\n // 3. passphrase_protection === true → return the current passphrase\n // state, even if the entered passphrase was empty. Otherwise →\n // standard wallet → return null (OneKey-aligned).\n const created = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, '__thpCreateSession', {\n passphraseMode: 'prompt',\n })\n )) as { protocol?: string; thpSessionId?: string | null };\n const state = await this._deriveState(sessionId, signal);\n const features = (await TrezorAdapter._abortable(\n signal,\n TrezorAdapter._callConnector(this._connector, sessionId, 'getFeatures', { refresh: true })\n )) as Record<string, unknown> | undefined;\n if (features?.passphrase_protection !== true) {\n // Standard wallet — discard the derived state, return null (OneKey convention).\n return success(null);\n }\n this._rememberVerifiedPassphraseSession(connectId, state, sessionId, created);\n return success(state);\n } catch (error) {\n return this._errorToFailure(error);\n }\n }\n\n private _onDeviceConnect = (data: { device: ConnectorDevice }): void => {\n const device = this._connectorDeviceToDeviceInfo(data.device);\n this._devices.set(device.connectId, device);\n this._emitter.emit(DEVICE.CONNECT, { type: DEVICE.CONNECT, payload: device });\n };\n\n private _onDeviceDisconnect = (data: { connectId: string }): void => {\n this._sessions.delete(data.connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(data.connectId);\n this._devices.delete(data.connectId);\n this._emitter.emit(DEVICE.DISCONNECT, {\n type: DEVICE.DISCONNECT,\n payload: { connectId: data.connectId },\n });\n };\n\n private _onSupportFeatures = (data: {\n device: ConnectorDevice & { features: Record<string, unknown> };\n }): void => {\n const device = {\n ...this._connectorDeviceToDeviceInfo(data.device),\n features: data.device.features,\n };\n this._emitter.emit(DEVICE.FEATURES, {\n type: DEVICE.FEATURES,\n device,\n payload: { device },\n });\n };\n\n private _onUiRequest = (data: { type: string; payload?: unknown }): void => {\n if (data.type === UI_REQUEST.REQUEST_PASSPHRASE) {\n const payload =\n data.payload && typeof data.payload === 'object'\n ? (data.payload as Record<string, unknown>)\n : {};\n const connectId = typeof payload.connectId === 'string' ? payload.connectId : undefined;\n const context = connectId\n ? this._passphraseRequestContextByConnectId.get(connectId)\n : undefined;\n this._emitter.emit(\n data.type as keyof HardwareEventMap,\n {\n ...data,\n payload: {\n ...payload,\n ...(context?.passphraseState !== undefined\n ? { passphraseState: context.passphraseState }\n : {}),\n ...(context?.useEmptyPassphrase !== undefined\n ? { useEmptyPassphrase: context.useEmptyPassphrase }\n : {}),\n },\n } as never\n );\n return;\n }\n this._emitter.emit(data.type as keyof HardwareEventMap, data as never);\n };\n\n private _onUiEvent = (data: ConnectorUiEvent): void => {\n this._emitter.emit('ui-event', data);\n };\n\n private _onThpCredentialsChanged = (data: {\n connectId: string;\n deviceId?: string;\n credentials: Record<string, unknown>[];\n }): void => {\n this._emitter.emit(DEVICE.TREZOR_THP_CREDENTIALS_CHANGED, {\n type: DEVICE.TREZOR_THP_CREDENTIALS_CHANGED,\n payload: data,\n });\n };\n\n private _registerConnectorEvents(): void {\n this._connector.on('device-connect', this._onDeviceConnect);\n this._connector.on('device-disconnect', this._onDeviceDisconnect);\n this._connector.on(DEVICE.FEATURES, this._onSupportFeatures);\n this._connector.on('device-trezor-thp-credentials-changed', this._onThpCredentialsChanged);\n this._connector.on('ui-request', this._onUiRequest);\n this._connector.on('ui-event', this._onUiEvent);\n }\n\n private _unregisterConnectorEvents(): void {\n this._connector.off('device-connect', this._onDeviceConnect);\n this._connector.off('device-disconnect', this._onDeviceDisconnect);\n this._connector.off(DEVICE.FEATURES, this._onSupportFeatures);\n this._connector.off('device-trezor-thp-credentials-changed', this._onThpCredentialsChanged);\n this._connector.off('ui-request', this._onUiRequest);\n this._connector.off('ui-event', this._onUiEvent);\n }\n\n private _connectorDeviceToDeviceInfo(device: ConnectorDevice): DeviceInfo {\n return {\n vendor: 'trezor',\n model: device.model ?? 'unknown',\n firmwareVersion: 'unknown',\n deviceId: device.deviceId,\n connectId: device.connectId,\n label: device.name,\n // The per-device transport is authoritative (a combined USB+BLE\n // connector tags each discovered device); the connector's own\n // connectionType is only a nominal value, so fall back to it for\n // single-transport connectors that don't tag each device.\n connectionType: device.connectionType ?? this._connector.connectionType,\n capabilities: device.capabilities,\n };\n }\n\n private _errorToFailure(error: unknown) {\n const typed = error as { code?: unknown; message?: string };\n // Map hwk-trezor-core's string markers to standard HardwareErrorCodes.\n // The core tags pairing-handshake rejections (e.g. mistyped CodeEntry code)\n // with `code: 'ThpPairingFailed'`; surface it as a proper code, not Unknown.\n if (typed.code === 'ThpPairingFailed') {\n return failure(HardwareErrorCode.ThpPairingFailed, typed.message ?? 'THP pairing failed');\n }\n // Only trust a numeric `code` if it is an actual HardwareErrorCode. A raw\n // WebUSB AbortError carries a DOMException `code: 20`, which is NOT one of\n // ours — fall through to message-based mapping (transferOut/USBDevice abort\n // → TransportError) so it surfaces as a recognizable, retryable transport\n // error instead of Unknown.\n const trustedNumericCode =\n typeof typed.code === 'number' && KNOWN_HARDWARE_ERROR_CODES.has(typed.code)\n ? typed.code\n : undefined;\n const code =\n trustedNumericCode ??\n TrezorAdapter._mapTrezorFailureCode(error) ??\n HardwareErrorCode.UnknownError;\n return failure(code, typed.message ?? String(error));\n }\n\n /**\n * Emit `REQUEST_DEVICE_PERMISSION` and await the host's\n * `RECEIVE_DEVICE_PERMISSION` reply (60s budget covers OS prompt + user\n * tap). If the host doesn't wire a handler the wait times out and the\n * operation fails fast.\n *\n * Mirrors LedgerAdapter._ensureDevicePermission so hosts can register a\n * single handler that branches by `payload.transportType` (and optionally\n * the active brand) instead of teaching every adapter its own contract.\n *\n * - no `connectId` → environment-level check (scan / picker)\n * - with `connectId` → device-level check (per-call gating)\n */\n private async _ensureDevicePermission(connectId?: string, deviceId?: string): Promise<void> {\n // No handler? Skip silently so non-permission-aware hosts (and our own\n // unit tests) keep working — Ledger's adapter has a 60s timeout but\n // hardware-wallet flows on web/desktop don't always have a registered\n // listener, and they shouldn't stall for a minute waiting on one.\n if (!this._emitter.listenerCount(UI_REQUEST.REQUEST_DEVICE_PERMISSION)) {\n return;\n }\n const transportType: TransportType = this.activeTransport ?? 'usb';\n\n const waitPromise = this._uiRegistry.wait<{ granted: boolean; reason?: string }>(\n UI_REQUEST.REQUEST_DEVICE_PERMISSION,\n { timeoutMs: 60_000 }\n );\n\n this._emitter.emit(UI_REQUEST.REQUEST_DEVICE_PERMISSION, {\n type: UI_REQUEST.REQUEST_DEVICE_PERMISSION,\n payload: { transportType, connectId, deviceId },\n });\n\n const { granted } = await waitPromise;\n if (!granted) {\n throw Object.assign(new Error('Device permission denied'), {\n code: HardwareErrorCode.DevicePermissionDenied,\n });\n }\n }\n}\n","/**\n * SDK-global event bus. Per-runtime singleton; hosts forward events over their\n * own IPC when the adapter runs in an offscreen/background split.\n */\n\nexport type SdkLogEvent = {\n type: 'log';\n level: 'debug' | 'info' | 'warn' | 'error';\n /** Pre-stringified payload. */\n message: string;\n};\n\nexport type SdkEvent = SdkLogEvent;\n\nexport type SdkEventListener = (event: SdkEvent) => void;\n\nconst listeners = new Set<SdkEventListener>();\n\nexport function onSdkEvent(listener: SdkEventListener): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\nexport function offSdkEvent(listener: SdkEventListener): void {\n listeners.delete(listener);\n}\n\nexport function emitSdkEvent(event: SdkEvent): void {\n if (listeners.size === 0) return;\n for (const listener of listeners) {\n try {\n listener(event);\n } catch {\n // Logging subscribers must not affect SDK execution.\n }\n }\n}\n\nexport function emitLog(level: SdkLogEvent['level'], ...args: unknown[]): void {\n if (listeners.size === 0) return;\n const message = args.map(a => (typeof a === 'string' ? a : safeStringify(a))).join(' ');\n emitSdkEvent({ type: 'log', level, message });\n}\n\nfunction safeStringify(value: unknown): string {\n if (value instanceof Error) {\n return value.stack ? `${value.message}\\n${value.stack}` : value.message;\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n","import { emitLog } from './sdkEventBus';\n\nexport function debugLog(...args: unknown[]): void {\n emitLog('debug', ...args);\n}\n\nexport function debugError(...args: unknown[]): void {\n emitLog('error', ...args);\n}\n","import type { EvmEthereumDefinitions } from '@onekeyfe/hwk-adapter-core';\n\n/**\n * Opt-in helpers for fetching Trezor Ethereum \"definitions\" — the SatoshiLabs-\n * signed network/token metadata a Trezor device uses to render friendly names\n * for chains and tokens that are NOT built into firmware.\n *\n * IMPORTANT — the SDK signing methods (evmSignTransaction / evmGetAddress / …)\n * NEVER call these. A local hardware operation must not silently become a\n * third-party network request (see PR #824 review). The caller decides whether,\n * when, and where to fetch, then passes the result into the sign params as\n * `ethereumDefinitions`. When omitted, the device falls back to a generic\n * confirmation screen and signing still completes.\n *\n * Cross-process note: `fetchImpl` is a FUNCTION and cannot be serialized across\n * an IPC / postMessage boundary. Call these helpers in a network-capable\n * process and send only the resulting hex strings to the process that talks\n * to the device. Use `baseUrl` (a string) to route through your own\n * controlled proxy instead of hitting data.trezor.io directly.\n */\n\n/** Default upstream (Trezor). Override with `baseUrl` to use your own proxy. */\nexport const DEFAULT_ETHEREUM_DEFINITIONS_BASE_URL =\n 'https://data.trezor.io/firmware/eth-definitions';\n\nexport type FetchLike = (url: string) => Promise<{\n status: number;\n arrayBuffer(): Promise<ArrayBuffer>;\n}>;\n\nexport type FetchEthereumDefinitionsParams = {\n chainId?: number;\n slip44?: number;\n contractAddress?: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\nexport type BuildEthereumDefinitionsForPathParams = {\n path: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\nexport type BuildEthereumDefinitionsForSignTxParams = {\n path: string;\n chainId: number;\n to?: string;\n data?: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\n/** Derive the SLIP-44 coin type (unhardened) from a BIP44-style path. */\nexport function getSlip44FromPath(path: string): number {\n const segments = path.trim().replace(/^m\\//i, '').split('/');\n const coinType = segments[1];\n const parsed = coinType === undefined ? NaN : Number(coinType.replace(/['hH]$/, ''));\n if (!Number.isFinite(parsed)) {\n throw new Error(`Cannot derive SLIP-44 coin type from path: ${path}`);\n }\n return parsed >= 0x80000000 ? parsed - 0x80000000 : parsed;\n}\n\nexport async function fetchEthereumDefinitions({\n chainId,\n slip44,\n contractAddress,\n baseUrl = DEFAULT_ETHEREUM_DEFINITIONS_BASE_URL,\n fetchImpl = globalThis.fetch,\n}: FetchEthereumDefinitionsParams): Promise<EvmEthereumDefinitions> {\n if (!chainId && !slip44) {\n throw new Error('fetchEthereumDefinitions requires chainId or slip44');\n }\n if (!fetchImpl) {\n return {};\n }\n\n const mode = chainId ? 'chain-id' : 'slip44';\n const id = chainId ?? slip44;\n const definitions: EvmEthereumDefinitions = {};\n\n const network = await fetchDefinitionHex(`${baseUrl}/${mode}/${id}/network.dat`, fetchImpl);\n if (network) {\n definitions.encodedNetwork = network;\n }\n\n if (contractAddress) {\n const token = await fetchDefinitionHex(\n `${baseUrl}/${mode}/${id}/token-${stripHexPrefix(contractAddress).toLowerCase()}.dat`,\n fetchImpl\n );\n if (token) {\n definitions.encodedToken = token;\n }\n }\n\n return definitions;\n}\n\nexport async function buildEthereumDefinitionsForPath({\n path,\n baseUrl,\n fetchImpl,\n}: BuildEthereumDefinitionsForPathParams): Promise<EvmEthereumDefinitions> {\n return fetchEthereumDefinitions({\n slip44: getSlip44FromPath(path),\n baseUrl,\n fetchImpl,\n });\n}\n\nexport async function buildEthereumDefinitionsForSignTx({\n path,\n chainId,\n to,\n data,\n baseUrl,\n fetchImpl,\n}: BuildEthereumDefinitionsForSignTxParams): Promise<EvmEthereumDefinitions | undefined> {\n const dataHex = stripHexPrefix(data ?? '');\n if (chainId === 1 && !dataHex) {\n return undefined;\n }\n return fetchEthereumDefinitions({\n chainId,\n slip44: getSlip44FromPath(path),\n contractAddress: dataHex && to ? to : undefined,\n baseUrl,\n fetchImpl,\n });\n}\n\nasync function fetchDefinitionHex(url: string, fetchImpl: FetchLike): Promise<string | undefined> {\n try {\n const response = await fetchImpl(url);\n if (response.status !== 200) {\n return undefined;\n }\n return arrayBufferToHex(await response.arrayBuffer());\n } catch {\n return undefined;\n }\n}\n\nfunction arrayBufferToHex(value: ArrayBuffer): string {\n return Buffer.from(value).toString('hex');\n}\n\nfunction stripHexPrefix(value: string): string {\n return value.startsWith('0x') || value.startsWith('0X') ? value.slice(2) : value;\n}\n","import type { FetchLike } from './ethereumDefinitions';\n\n/**\n * Opt-in helper for fetching a Trezor Solana token definition. Same contract as\n * the Ethereum helpers (see ./ethereumDefinitions): the SDK signing path NEVER\n * calls this — the caller fetches (through its own `baseUrl` proxy if desired)\n * and passes the bytes into `solSignTransaction` params as\n * `additionalInfo.encodedToken`. When omitted the device shows a generic token\n * confirmation screen and signing still completes.\n *\n * `fetchImpl` is a function and must not cross an IPC boundary — fetch in a\n * network-capable process and pass only the resulting hex string.\n */\n\n/** Default upstream (Trezor). Override with `baseUrl` to use your own proxy. */\nexport const DEFAULT_SOLANA_TOKEN_DEFINITION_BASE_URL =\n 'https://data.trezor.io/firmware/definitions/solana/token';\n\nexport type FetchSolanaTokenDefinitionParams = {\n tokenMint: string;\n baseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\nexport async function fetchSolanaTokenDefinition({\n tokenMint,\n baseUrl = DEFAULT_SOLANA_TOKEN_DEFINITION_BASE_URL,\n fetchImpl = globalThis.fetch,\n}: FetchSolanaTokenDefinitionParams): Promise<string | undefined> {\n if (!fetchImpl) {\n return undefined;\n }\n try {\n const response = await fetchImpl(`${baseUrl}/${tokenMint}.dat`);\n if (response.status !== 200) {\n return undefined;\n }\n return Buffer.from(await response.arrayBuffer()).toString('hex');\n } catch {\n return undefined;\n }\n}\n","export const TREZOR_SAFE_7_MODEL = 'T3W1';\n\nexport const TREZOR_BLE_SUPPORTED_MODELS = [TREZOR_SAFE_7_MODEL] as const;\n\nexport const TREZOR_BLE_PACKET_SIZE = 244;\n\nexport const TREZOR_BLE_UUIDS = {\n service: '8c000001-a59b-4d58-a9ad-073df69fa1b1',\n write: '8c000002-a59b-4d58-a9ad-073df69fa1b1',\n notify: '8c000003-a59b-4d58-a9ad-073df69fa1b1',\n push: '8c000004-a59b-4d58-a9ad-073df69fa1b1',\n batteryService: '0000180f-0000-1000-8000-00805f9b34fb',\n} as const;\n","import { TREZOR_BLE_SUPPORTED_MODELS, TREZOR_BLE_UUIDS } from '../constants';\n\nimport type { TrezorBleDescriptor } from '../types';\n\nexport function isTrezorSafe7BleName(name?: string): boolean {\n if (!name) return false;\n return /\\bTrezor\\b/i.test(name) && (/\\bSafe\\s*7\\b/i.test(name) || /\\bT3W1\\b/i.test(name));\n}\n\nexport function isTrezorBleSupportedModel(model?: string): boolean {\n if (!model) return false;\n const normalizedModel = model.trim().replace(/\\s+/g, ' ').toLowerCase();\n return (\n TREZOR_BLE_SUPPORTED_MODELS.some(\n supportedModel => supportedModel.toLowerCase() === normalizedModel\n ) ||\n normalizedModel === 'safe 7' ||\n normalizedModel === 'trezor safe 7'\n );\n}\n\nexport function isTrezorSafe7BleDescriptor(descriptor: TrezorBleDescriptor): boolean {\n return isTrezorBleDescriptor(descriptor);\n}\n\nexport function normalizeTrezorBleUuid(uuid: string): string {\n return uuid.replace(/-/g, '').toLowerCase();\n}\n\nexport function isTrezorBleServiceUuid(uuid: string): boolean {\n return normalizeTrezorBleUuid(uuid) === normalizeTrezorBleUuid(TREZOR_BLE_UUIDS.service);\n}\n\nexport function isTrezorBleDescriptor(descriptor: TrezorBleDescriptor): boolean {\n const serviceUuids = [\n ...(descriptor.serviceUUIDs ?? []),\n ...(descriptor.advertisedServiceUuids ?? []),\n ...(descriptor.serviceUuids ?? []),\n ];\n return serviceUuids.some(isTrezorBleServiceUuid);\n}\n\nexport function resolveTrezorBleConnectId(descriptor: TrezorBleDescriptor): string {\n return descriptor.id ?? descriptor.path ?? descriptor.deviceId ?? descriptor.name ?? '';\n}\n"],"mappings":"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","names":["failure"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hwk-trezor-adapter",
3
- "version": "1.1.29-alpha.7",
3
+ "version": "1.1.29-alpha.8",
4
4
  "description": "Trezor hardware wallet adapter primitives for OneKey",
5
5
  "author": "OneKey",
6
6
  "license": "MIT",
@@ -43,8 +43,8 @@
43
43
  "crypto"
44
44
  ],
45
45
  "dependencies": {
46
- "@onekeyfe/hwk-adapter-core": "1.1.29-alpha.7",
47
- "@onekeyfe/hwk-trezor-core": "1.1.29-alpha.7",
46
+ "@onekeyfe/hwk-adapter-core": "1.1.29-alpha.8",
47
+ "@onekeyfe/hwk-trezor-core": "1.1.29-alpha.8",
48
48
  "tslib": "^2.6.2"
49
49
  },
50
50
  "devDependencies": {
@@ -52,5 +52,5 @@
52
52
  "tsup": "^8.0.0",
53
53
  "typescript": "5.1.6"
54
54
  },
55
- "gitHead": "c27884354d9a7303f12004ce9b5236c493738223"
55
+ "gitHead": "0b7d4aeb216806b1f60df0eebf73d1aad2bca600"
56
56
  }