@onekeyfe/hwk-trezor-adapter 1.1.29-alpha.1 → 1.1.29-alpha.3
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 +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +37 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +36 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -13,6 +13,7 @@ declare class TrezorAdapter implements IHardwareWallet {
|
|
|
13
13
|
private readonly _devices;
|
|
14
14
|
private readonly _sessions;
|
|
15
15
|
private readonly _connectingPromises;
|
|
16
|
+
private readonly _disconnectRequested;
|
|
16
17
|
private readonly _uiRegistry;
|
|
17
18
|
private readonly _passphraseRequestContextByConnectId;
|
|
18
19
|
private readonly _verifiedPassphraseSessionsByConnectId;
|
|
@@ -248,7 +249,9 @@ type TrezorConnectorDevice = ConnectorDevice;
|
|
|
248
249
|
declare function isTrezorSafe7BleName(name?: string): boolean;
|
|
249
250
|
declare function isTrezorBleSupportedModel(model?: string): boolean;
|
|
250
251
|
declare function isTrezorSafe7BleDescriptor(descriptor: TrezorBleDescriptor): boolean;
|
|
252
|
+
declare function normalizeTrezorBleUuid(uuid: string): string;
|
|
253
|
+
declare function isTrezorBleServiceUuid(uuid: string): boolean;
|
|
251
254
|
declare function isTrezorBleDescriptor(descriptor: TrezorBleDescriptor): boolean;
|
|
252
255
|
declare function resolveTrezorBleConnectId(descriptor: TrezorBleDescriptor): string;
|
|
253
256
|
|
|
254
|
-
export { type SdkEvent, type SdkEventListener, type SdkLogEvent, TREZOR_BLE_PACKET_SIZE, TREZOR_BLE_SUPPORTED_MODELS, TREZOR_BLE_UUIDS, TREZOR_SAFE_7_MODEL, TrezorAdapter, type TrezorBleDescriptor, type TrezorBleTransport, type TrezorBleTransportFactory, type TrezorConnectedDevice, type TrezorConnectorDevice, isTrezorBleDescriptor, isTrezorBleSupportedModel, isTrezorSafe7BleDescriptor, isTrezorSafe7BleName, offSdkEvent, onSdkEvent, resolveTrezorBleConnectId };
|
|
257
|
+
export { type SdkEvent, type SdkEventListener, type SdkLogEvent, TREZOR_BLE_PACKET_SIZE, TREZOR_BLE_SUPPORTED_MODELS, TREZOR_BLE_UUIDS, TREZOR_SAFE_7_MODEL, TrezorAdapter, type TrezorBleDescriptor, type TrezorBleTransport, type TrezorBleTransportFactory, type TrezorConnectedDevice, type TrezorConnectorDevice, isTrezorBleDescriptor, isTrezorBleServiceUuid, isTrezorBleSupportedModel, isTrezorSafe7BleDescriptor, isTrezorSafe7BleName, normalizeTrezorBleUuid, offSdkEvent, onSdkEvent, resolveTrezorBleConnectId };
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ declare class TrezorAdapter implements IHardwareWallet {
|
|
|
13
13
|
private readonly _devices;
|
|
14
14
|
private readonly _sessions;
|
|
15
15
|
private readonly _connectingPromises;
|
|
16
|
+
private readonly _disconnectRequested;
|
|
16
17
|
private readonly _uiRegistry;
|
|
17
18
|
private readonly _passphraseRequestContextByConnectId;
|
|
18
19
|
private readonly _verifiedPassphraseSessionsByConnectId;
|
|
@@ -248,7 +249,9 @@ type TrezorConnectorDevice = ConnectorDevice;
|
|
|
248
249
|
declare function isTrezorSafe7BleName(name?: string): boolean;
|
|
249
250
|
declare function isTrezorBleSupportedModel(model?: string): boolean;
|
|
250
251
|
declare function isTrezorSafe7BleDescriptor(descriptor: TrezorBleDescriptor): boolean;
|
|
252
|
+
declare function normalizeTrezorBleUuid(uuid: string): string;
|
|
253
|
+
declare function isTrezorBleServiceUuid(uuid: string): boolean;
|
|
251
254
|
declare function isTrezorBleDescriptor(descriptor: TrezorBleDescriptor): boolean;
|
|
252
255
|
declare function resolveTrezorBleConnectId(descriptor: TrezorBleDescriptor): string;
|
|
253
256
|
|
|
254
|
-
export { type SdkEvent, type SdkEventListener, type SdkLogEvent, TREZOR_BLE_PACKET_SIZE, TREZOR_BLE_SUPPORTED_MODELS, TREZOR_BLE_UUIDS, TREZOR_SAFE_7_MODEL, TrezorAdapter, type TrezorBleDescriptor, type TrezorBleTransport, type TrezorBleTransportFactory, type TrezorConnectedDevice, type TrezorConnectorDevice, isTrezorBleDescriptor, isTrezorBleSupportedModel, isTrezorSafe7BleDescriptor, isTrezorSafe7BleName, offSdkEvent, onSdkEvent, resolveTrezorBleConnectId };
|
|
257
|
+
export { type SdkEvent, type SdkEventListener, type SdkLogEvent, TREZOR_BLE_PACKET_SIZE, TREZOR_BLE_SUPPORTED_MODELS, TREZOR_BLE_UUIDS, TREZOR_SAFE_7_MODEL, TrezorAdapter, type TrezorBleDescriptor, type TrezorBleTransport, type TrezorBleTransportFactory, type TrezorConnectedDevice, type TrezorConnectorDevice, isTrezorBleDescriptor, isTrezorBleServiceUuid, isTrezorBleSupportedModel, isTrezorSafe7BleDescriptor, isTrezorSafe7BleName, normalizeTrezorBleUuid, offSdkEvent, onSdkEvent, resolveTrezorBleConnectId };
|
package/dist/index.js
CHANGED
|
@@ -78,6 +78,8 @@ var TrezorAdapter = class _TrezorAdapter {
|
|
|
78
78
|
this._devices = /* @__PURE__ */ new Map();
|
|
79
79
|
this._sessions = /* @__PURE__ */ new Map();
|
|
80
80
|
this._connectingPromises = /* @__PURE__ */ new Map();
|
|
81
|
+
// connectIds disconnected mid-connect; the session they produce is torn down, not cached.
|
|
82
|
+
this._disconnectRequested = /* @__PURE__ */ new Set();
|
|
81
83
|
this._uiRegistry = new (0, _hwkadaptercore.UiRequestRegistry)();
|
|
82
84
|
this._passphraseRequestContextByConnectId = /* @__PURE__ */ new Map();
|
|
83
85
|
this._verifiedPassphraseSessionsByConnectId = /* @__PURE__ */ new Map();
|
|
@@ -321,7 +323,24 @@ var TrezorAdapter = class _TrezorAdapter {
|
|
|
321
323
|
}
|
|
322
324
|
async _connectSession(connectId, signal) {
|
|
323
325
|
const connectPromise = this._connector.connect(connectId);
|
|
324
|
-
const session =
|
|
326
|
+
const session = await (async () => {
|
|
327
|
+
if (!signal) return connectPromise;
|
|
328
|
+
try {
|
|
329
|
+
return await _TrezorAdapter._abortable(signal, connectPromise);
|
|
330
|
+
} catch (error) {
|
|
331
|
+
void connectPromise.then(
|
|
332
|
+
(orphan) => this._connector.disconnect(orphan.sessionId).catch(() => void 0),
|
|
333
|
+
() => void 0
|
|
334
|
+
);
|
|
335
|
+
throw error;
|
|
336
|
+
}
|
|
337
|
+
})();
|
|
338
|
+
if (this._disconnectRequested.delete(connectId)) {
|
|
339
|
+
await this._connector.disconnect(session.sessionId).catch(() => void 0);
|
|
340
|
+
throw Object.assign(new Error("Trezor connection aborted"), {
|
|
341
|
+
code: _hwkadaptercore.HardwareErrorCode.UserAborted
|
|
342
|
+
});
|
|
343
|
+
}
|
|
325
344
|
this._sessions.set(connectId, session.sessionId);
|
|
326
345
|
this._verifiedPassphraseSessionsByConnectId.delete(connectId);
|
|
327
346
|
this._devices.set(connectId, session.deviceInfo);
|
|
@@ -388,12 +407,16 @@ var TrezorAdapter = class _TrezorAdapter {
|
|
|
388
407
|
}
|
|
389
408
|
}
|
|
390
409
|
async disconnectDevice(connectId) {
|
|
410
|
+
const connecting = this._connectingPromises.has(connectId);
|
|
391
411
|
this._connectingPromises.delete(connectId);
|
|
392
412
|
const sessionId = this._sessions.get(connectId);
|
|
393
|
-
if (!sessionId)
|
|
394
|
-
|
|
413
|
+
if (!sessionId) {
|
|
414
|
+
if (connecting) this._disconnectRequested.add(connectId);
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
395
417
|
this._sessions.delete(connectId);
|
|
396
418
|
this._verifiedPassphraseSessionsByConnectId.delete(connectId);
|
|
419
|
+
await this._connector.disconnect(sessionId);
|
|
397
420
|
}
|
|
398
421
|
async getDeviceInfo(connectId, deviceId) {
|
|
399
422
|
const device = _nullishCoalesce(this._devices.get(connectId), () => ( Array.from(this._devices.values()).find((item) => item.deviceId === deviceId)));
|
|
@@ -813,6 +836,7 @@ var TrezorAdapter = class _TrezorAdapter {
|
|
|
813
836
|
}
|
|
814
837
|
} finally {
|
|
815
838
|
this._connectingPromises.delete(connectId);
|
|
839
|
+
this._disconnectRequested.delete(connectId);
|
|
816
840
|
}
|
|
817
841
|
})();
|
|
818
842
|
this._connectingPromises.set(connectId, promise);
|
|
@@ -1072,14 +1096,19 @@ function isTrezorBleSupportedModel(model) {
|
|
|
1072
1096
|
function isTrezorSafe7BleDescriptor(descriptor) {
|
|
1073
1097
|
return isTrezorBleDescriptor(descriptor);
|
|
1074
1098
|
}
|
|
1099
|
+
function normalizeTrezorBleUuid(uuid) {
|
|
1100
|
+
return uuid.replace(/-/g, "").toLowerCase();
|
|
1101
|
+
}
|
|
1102
|
+
function isTrezorBleServiceUuid(uuid) {
|
|
1103
|
+
return normalizeTrezorBleUuid(uuid) === normalizeTrezorBleUuid(TREZOR_BLE_UUIDS.service);
|
|
1104
|
+
}
|
|
1075
1105
|
function isTrezorBleDescriptor(descriptor) {
|
|
1076
|
-
const target = TREZOR_BLE_UUIDS.service.toLowerCase();
|
|
1077
1106
|
const serviceUuids = [
|
|
1078
1107
|
..._nullishCoalesce(descriptor.serviceUUIDs, () => ( [])),
|
|
1079
1108
|
..._nullishCoalesce(descriptor.advertisedServiceUuids, () => ( [])),
|
|
1080
1109
|
..._nullishCoalesce(descriptor.serviceUuids, () => ( []))
|
|
1081
1110
|
];
|
|
1082
|
-
return serviceUuids.some(
|
|
1111
|
+
return serviceUuids.some(isTrezorBleServiceUuid);
|
|
1083
1112
|
}
|
|
1084
1113
|
function resolveTrezorBleConnectId(descriptor) {
|
|
1085
1114
|
return _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(descriptor.id, () => ( descriptor.path)), () => ( descriptor.deviceId)), () => ( descriptor.name)), () => ( ""));
|
|
@@ -1097,5 +1126,7 @@ function resolveTrezorBleConnectId(descriptor) {
|
|
|
1097
1126
|
|
|
1098
1127
|
|
|
1099
1128
|
|
|
1100
|
-
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
exports.TREZOR_BLE_PACKET_SIZE = TREZOR_BLE_PACKET_SIZE; exports.TREZOR_BLE_SUPPORTED_MODELS = TREZOR_BLE_SUPPORTED_MODELS; exports.TREZOR_BLE_UUIDS = TREZOR_BLE_UUIDS; exports.TREZOR_SAFE_7_MODEL = TREZOR_SAFE_7_MODEL; exports.TrezorAdapter = TrezorAdapter; exports.isTrezorBleDescriptor = isTrezorBleDescriptor; exports.isTrezorBleServiceUuid = isTrezorBleServiceUuid; exports.isTrezorBleSupportedModel = isTrezorBleSupportedModel; exports.isTrezorSafe7BleDescriptor = isTrezorSafe7BleDescriptor; exports.isTrezorSafe7BleName = isTrezorSafe7BleName; exports.normalizeTrezorBleUuid = normalizeTrezorBleUuid; exports.offSdkEvent = offSdkEvent; exports.onSdkEvent = onSdkEvent; exports.resolveTrezorBleConnectId = resolveTrezorBleConnectId;
|
|
1101
1132
|
//# sourceMappingURL=index.js.map
|
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/constants.ts","../src/utils/bleIdentity.ts"],"names":[],"mappings":"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","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\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 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 return Object.assign(new Error(`Trezor is busy with another request (${method})`), {\n code: HardwareErrorCode.DeviceBusy,\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 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 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 = signal\n ? await TrezorAdapter._abortable(signal, connectPromise)\n : await connectPromise;\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 // Drop the in-flight connect (if any) so a late resolution can't repopulate\n // _sessions after we've explicitly torn down.\n this._connectingPromises.delete(connectId);\n const sessionId = this._sessions.get(connectId);\n if (!sessionId) return;\n await this._connector.disconnect(sessionId);\n this._sessions.delete(connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\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 }\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 const code =\n typeof typed.code === 'number'\n ? typed.code\n : TrezorAdapter._mapTrezorFailureCode(error) ?? 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","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 isTrezorBleDescriptor(descriptor: TrezorBleDescriptor): boolean {\n const target = TREZOR_BLE_UUIDS.service.toLowerCase();\n const serviceUuids = [\n ...(descriptor.serviceUUIDs ?? []),\n ...(descriptor.advertisedServiceUuids ?? []),\n ...(descriptor.serviceUuids ?? []),\n ];\n return serviceUuids.some(uuid => uuid.toLowerCase() === target);\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/constants.ts","../src/utils/bleIdentity.ts"],"names":[],"mappings":"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","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\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 return Object.assign(new Error(`Trezor is busy with another request (${method})`), {\n code: HardwareErrorCode.DeviceBusy,\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 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 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 const code =\n typeof typed.code === 'number'\n ? typed.code\n : TrezorAdapter._mapTrezorFailureCode(error) ?? 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","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
|
@@ -78,6 +78,8 @@ var TrezorAdapter = class _TrezorAdapter {
|
|
|
78
78
|
this._devices = /* @__PURE__ */ new Map();
|
|
79
79
|
this._sessions = /* @__PURE__ */ new Map();
|
|
80
80
|
this._connectingPromises = /* @__PURE__ */ new Map();
|
|
81
|
+
// connectIds disconnected mid-connect; the session they produce is torn down, not cached.
|
|
82
|
+
this._disconnectRequested = /* @__PURE__ */ new Set();
|
|
81
83
|
this._uiRegistry = new UiRequestRegistry();
|
|
82
84
|
this._passphraseRequestContextByConnectId = /* @__PURE__ */ new Map();
|
|
83
85
|
this._verifiedPassphraseSessionsByConnectId = /* @__PURE__ */ new Map();
|
|
@@ -321,7 +323,24 @@ var TrezorAdapter = class _TrezorAdapter {
|
|
|
321
323
|
}
|
|
322
324
|
async _connectSession(connectId, signal) {
|
|
323
325
|
const connectPromise = this._connector.connect(connectId);
|
|
324
|
-
const session =
|
|
326
|
+
const session = await (async () => {
|
|
327
|
+
if (!signal) return connectPromise;
|
|
328
|
+
try {
|
|
329
|
+
return await _TrezorAdapter._abortable(signal, connectPromise);
|
|
330
|
+
} catch (error) {
|
|
331
|
+
void connectPromise.then(
|
|
332
|
+
(orphan) => this._connector.disconnect(orphan.sessionId).catch(() => void 0),
|
|
333
|
+
() => void 0
|
|
334
|
+
);
|
|
335
|
+
throw error;
|
|
336
|
+
}
|
|
337
|
+
})();
|
|
338
|
+
if (this._disconnectRequested.delete(connectId)) {
|
|
339
|
+
await this._connector.disconnect(session.sessionId).catch(() => void 0);
|
|
340
|
+
throw Object.assign(new Error("Trezor connection aborted"), {
|
|
341
|
+
code: HardwareErrorCode.UserAborted
|
|
342
|
+
});
|
|
343
|
+
}
|
|
325
344
|
this._sessions.set(connectId, session.sessionId);
|
|
326
345
|
this._verifiedPassphraseSessionsByConnectId.delete(connectId);
|
|
327
346
|
this._devices.set(connectId, session.deviceInfo);
|
|
@@ -388,12 +407,16 @@ var TrezorAdapter = class _TrezorAdapter {
|
|
|
388
407
|
}
|
|
389
408
|
}
|
|
390
409
|
async disconnectDevice(connectId) {
|
|
410
|
+
const connecting = this._connectingPromises.has(connectId);
|
|
391
411
|
this._connectingPromises.delete(connectId);
|
|
392
412
|
const sessionId = this._sessions.get(connectId);
|
|
393
|
-
if (!sessionId)
|
|
394
|
-
|
|
413
|
+
if (!sessionId) {
|
|
414
|
+
if (connecting) this._disconnectRequested.add(connectId);
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
395
417
|
this._sessions.delete(connectId);
|
|
396
418
|
this._verifiedPassphraseSessionsByConnectId.delete(connectId);
|
|
419
|
+
await this._connector.disconnect(sessionId);
|
|
397
420
|
}
|
|
398
421
|
async getDeviceInfo(connectId, deviceId) {
|
|
399
422
|
const device = this._devices.get(connectId) ?? Array.from(this._devices.values()).find((item) => item.deviceId === deviceId);
|
|
@@ -813,6 +836,7 @@ var TrezorAdapter = class _TrezorAdapter {
|
|
|
813
836
|
}
|
|
814
837
|
} finally {
|
|
815
838
|
this._connectingPromises.delete(connectId);
|
|
839
|
+
this._disconnectRequested.delete(connectId);
|
|
816
840
|
}
|
|
817
841
|
})();
|
|
818
842
|
this._connectingPromises.set(connectId, promise);
|
|
@@ -1072,14 +1096,19 @@ function isTrezorBleSupportedModel(model) {
|
|
|
1072
1096
|
function isTrezorSafe7BleDescriptor(descriptor) {
|
|
1073
1097
|
return isTrezorBleDescriptor(descriptor);
|
|
1074
1098
|
}
|
|
1099
|
+
function normalizeTrezorBleUuid(uuid) {
|
|
1100
|
+
return uuid.replace(/-/g, "").toLowerCase();
|
|
1101
|
+
}
|
|
1102
|
+
function isTrezorBleServiceUuid(uuid) {
|
|
1103
|
+
return normalizeTrezorBleUuid(uuid) === normalizeTrezorBleUuid(TREZOR_BLE_UUIDS.service);
|
|
1104
|
+
}
|
|
1075
1105
|
function isTrezorBleDescriptor(descriptor) {
|
|
1076
|
-
const target = TREZOR_BLE_UUIDS.service.toLowerCase();
|
|
1077
1106
|
const serviceUuids = [
|
|
1078
1107
|
...descriptor.serviceUUIDs ?? [],
|
|
1079
1108
|
...descriptor.advertisedServiceUuids ?? [],
|
|
1080
1109
|
...descriptor.serviceUuids ?? []
|
|
1081
1110
|
];
|
|
1082
|
-
return serviceUuids.some(
|
|
1111
|
+
return serviceUuids.some(isTrezorBleServiceUuid);
|
|
1083
1112
|
}
|
|
1084
1113
|
function resolveTrezorBleConnectId(descriptor) {
|
|
1085
1114
|
return descriptor.id ?? descriptor.path ?? descriptor.deviceId ?? descriptor.name ?? "";
|
|
@@ -1091,9 +1120,11 @@ export {
|
|
|
1091
1120
|
TREZOR_SAFE_7_MODEL,
|
|
1092
1121
|
TrezorAdapter,
|
|
1093
1122
|
isTrezorBleDescriptor,
|
|
1123
|
+
isTrezorBleServiceUuid,
|
|
1094
1124
|
isTrezorBleSupportedModel,
|
|
1095
1125
|
isTrezorSafe7BleDescriptor,
|
|
1096
1126
|
isTrezorSafe7BleName,
|
|
1127
|
+
normalizeTrezorBleUuid,
|
|
1097
1128
|
offSdkEvent,
|
|
1098
1129
|
onSdkEvent,
|
|
1099
1130
|
resolveTrezorBleConnectId
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapter/TrezorAdapter.ts","../src/utils/sdkEventBus.ts","../src/utils/debugLog.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\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 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 return Object.assign(new Error(`Trezor is busy with another request (${method})`), {\n code: HardwareErrorCode.DeviceBusy,\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 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 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 = signal\n ? await TrezorAdapter._abortable(signal, connectPromise)\n : await connectPromise;\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 // Drop the in-flight connect (if any) so a late resolution can't repopulate\n // _sessions after we've explicitly torn down.\n this._connectingPromises.delete(connectId);\n const sessionId = this._sessions.get(connectId);\n if (!sessionId) return;\n await this._connector.disconnect(sessionId);\n this._sessions.delete(connectId);\n this._verifiedPassphraseSessionsByConnectId.delete(connectId);\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 }\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 const code =\n typeof typed.code === 'number'\n ? typed.code\n : TrezorAdapter._mapTrezorFailureCode(error) ?? 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","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 isTrezorBleDescriptor(descriptor: TrezorBleDescriptor): boolean {\n const target = TREZOR_BLE_UUIDS.service.toLowerCase();\n const serviceUuids = [\n ...(descriptor.serviceUUIDs ?? []),\n ...(descriptor.advertisedServiceUuids ?? []),\n ...(descriptor.serviceUuids ?? []),\n ];\n return serviceUuids.some(uuid => uuid.toLowerCase() === target);\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/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\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 return Object.assign(new Error(`Trezor is busy with another request (${method})`), {\n code: HardwareErrorCode.DeviceBusy,\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 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 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 const code =\n typeof typed.code === 'number'\n ? typed.code\n : TrezorAdapter._mapTrezorFailureCode(error) ?? 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","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.
|
|
3
|
+
"version": "1.1.29-alpha.3",
|
|
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.
|
|
47
|
-
"@onekeyfe/hwk-trezor-core": "1.1.29-alpha.
|
|
46
|
+
"@onekeyfe/hwk-adapter-core": "1.1.29-alpha.3",
|
|
47
|
+
"@onekeyfe/hwk-trezor-core": "1.1.29-alpha.3",
|
|
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": "
|
|
55
|
+
"gitHead": "8bfaafd955401948065a944a4e3b92f7a72c6571"
|
|
56
56
|
}
|