@onekeyfe/hwk-trezor-adapter 1.1.27-alpha.100

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.
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapter/TrezorAdapter.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 success,\n} from '@onekeyfe/hwk-adapter-core';\n\nimport type {\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 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 IConnector,\n IHardwareWallet,\n Response,\n SolAddress,\n SolGetAddressParams,\n SolSignMsgParams,\n SolSignTxParams,\n SolSignature,\n SolSignedTx,\n TransportType,\n TronAddress,\n TronGetAddressParams,\n TronSignMsgParams,\n TronSignTxParams,\n TronSignature,\n TronSignedTx,\n UiResponseEvent,\n} from '@onekeyfe/hwk-adapter-core';\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 // Passphrase application sessions, keyed by `${connectId}\u0000${XFP}` →\n // THP session id. The adapter owns the XFP↔sessionId mapping; the SDK session\n // only deals in opaque session ids. Multiple entries per connectId coexist\n // (one per passphrase wallet), mirroring the device's session slots. Cleared\n // when the channel drops (sessions die with it) or a session is evicted.\n private readonly _appSessions = new Map<string, string>();\n\n private readonly _connectingPromises = new Map<string, Promise<string>>();\n\n private readonly _uiRegistry = new UiRequestRegistry();\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 private static _appSessionKey(connectId: string, passphraseState: string): string {\n return `${connectId}\u0000${passphraseState}`;\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 _splitPassphraseState(params: unknown): {\n passphraseState?: string;\n rest: unknown;\n } {\n if (params && typeof params === 'object' && 'passphraseState' in params) {\n const { passphraseState, ...rest } = params as Record<string, unknown>;\n return {\n passphraseState: typeof passphraseState === 'string' ? passphraseState : undefined,\n rest,\n };\n }\n return { rest: params };\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 _clearAppSessions(connectId: string): void {\n const prefix = `${connectId}\u0000`;\n for (const key of [...this._appSessions.keys()]) {\n if (key.startsWith(prefix)) this._appSessions.delete(key);\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 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._appSessions.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._appSessions.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(): Promise<DeviceInfo[]> {\n await this._ensureDevicePermission();\n const scanned = await this._connector.searchDevices();\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 this._clearAppSessions(connectId);\n if (!sessionId) return;\n await this._connector.disconnect(sessionId);\n this._sessions.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 deferred (multi-step\n // TronContractRequest flow + rawTxHex decoding needs device testing).\n return ['btc', 'evm', 'sol', 'tron'];\n }\n\n getFeatures(connectId: string): Promise<Response<Record<string, unknown>>> {\n return this._call<Record<string, unknown>>(connectId, 'getFeatures', {});\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 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(\n HardwareErrorCode.UnknownError,\n 'Trezor features did not include a device_id'\n );\n }\n return success(liveDeviceId);\n }\n\n /**\n * Resolve the active passphrase wallet identity (master fingerprint / XFP).\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 signal => this._resolvePassphraseState(connectId, passphraseState, signal),\n {\n label: 'getPassphraseState',\n rejectIfBusy: true,\n busyError: TrezorAdapter._createDeviceBusyError('getPassphraseState'),\n }\n )\n .catch(error => this._errorToFailure(error));\n }\n\n evmGetAddress(connectId: string, _deviceId: string, params: EvmGetAddressParams) {\n return this._call<EvmAddress>(connectId, 'evmGetAddress', params);\n }\n\n evmSignTransaction(connectId: string, _deviceId: string, params: EvmSignTxParams) {\n return this._call<EvmSignedTx>(connectId, 'evmSignTransaction', params);\n }\n\n evmSignMessage(connectId: string, _deviceId: string, params: EvmSignMsgParams) {\n return this._call<EvmSignature>(connectId, 'evmSignMessage', params);\n }\n\n evmSignTypedData(connectId: string, _deviceId: string, params: EvmSignTypedDataParams) {\n return this._call<EvmSignature>(connectId, 'evmSignTypedData', params);\n }\n\n btcGetAddress(connectId: string, _deviceId: string, params: BtcGetAddressParams) {\n return this._call<BtcAddress>(connectId, 'btcGetAddress', params);\n }\n\n btcGetPublicKey(connectId: string, _deviceId: string, params: BtcGetPublicKeyParams) {\n return this._call<BtcPublicKey>(connectId, 'btcGetPublicKey', params);\n }\n\n btcSignTransaction(connectId: string, _deviceId: string, params: BtcSignTxParams) {\n return this._call<BtcSignedTx>(connectId, 'btcSignTransaction', params);\n }\n\n btcSignPsbt(connectId: string, _deviceId: string, params: BtcSignPsbtParams) {\n return this._call<BtcSignedPsbt>(connectId, 'btcSignPsbt', params);\n }\n\n btcSignMessage(connectId: string, _deviceId: string, params: BtcSignMsgParams) {\n return this._call<BtcSignature>(connectId, 'btcSignMessage', params);\n }\n\n btcGetMasterFingerprint(connectId: string, _deviceId: string) {\n return this._call<{ masterFingerprint: string }>(connectId, 'btcGetMasterFingerprint', {});\n }\n\n solGetAddress(connectId: string, _deviceId: string, params: SolGetAddressParams) {\n return this._call<SolAddress>(connectId, 'solGetAddress', params);\n }\n\n solSignTransaction(connectId: string, _deviceId: string, params: SolSignTxParams) {\n return this._call<SolSignedTx>(connectId, 'solSignTransaction', params);\n }\n\n solSignMessage(connectId: string, _deviceId: string, params: SolSignMsgParams) {\n return this._call<SolSignature>(connectId, 'solSignMessage', params);\n }\n\n tronGetAddress(connectId: string, _deviceId: string, params: TronGetAddressParams) {\n return this._call<TronAddress>(connectId, 'tronGetAddress', params);\n }\n\n tronSignTransaction(connectId: string, _deviceId: string, params: TronSignTxParams) {\n return this._call<TronSignedTx>(connectId, 'tronSignTransaction', params);\n }\n\n tronSignMessage(connectId: string, _deviceId: string, params: TronSignMsgParams) {\n return this._call<TronSignature>(connectId, 'tronSignMessage', params);\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 async _call<T>(connectId: string, method: string, params: unknown): Promise<Response<T>> {\n try {\n return await this._jobQueue.enqueue(\n connectId,\n signal => this._callWithRetry<T>(connectId, method, params, true, signal),\n {\n label: method,\n rejectIfBusy: true,\n busyError: TrezorAdapter._createDeviceBusyError(method),\n },\n );\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 return this._errorToFailure(error);\n }\n }\n\n private async _callWithRetry<T>(\n connectId: string,\n method: string,\n params: unknown,\n allowRetry: boolean,\n signal: AbortSignal\n ): Promise<Response<T>> {\n const { passphraseState, rest } = TrezorAdapter._splitPassphraseState(params);\n try {\n const sessionId = await TrezorAdapter._abortable(signal, this._ensureSession(connectId));\n // Pin the call to the requested passphrase wallet (THP only; v1 is a\n // no-op handled reactively by the device). Runs inside this queued job so\n // the select and the call can't be interleaved by another request.\n if (passphraseState) {\n await TrezorAdapter._abortable(\n signal,\n this._alignAppSession(connectId, sessionId, passphraseState, signal)\n );\n }\n const result = await TrezorAdapter._abortable(\n signal,\n this._connector.call(sessionId, method, 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 = (error as { code?: HardwareErrorCode | string }).code;\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 // Application sessions live on the channel — a fresh channel has none.\n this._clearAppSessions(connectId);\n return this._callWithRetry<T>(connectId, method, params, false, signal);\n }\n // The device evicted the passphrase session we selected. Drop the stale\n // mapping and retry once — the cache miss recreates it (re-prompts) and\n // re-verifies the XFP before the call.\n if (allowRetry && passphraseState && TrezorAdapter._isStaleSessionError(code)) {\n this._appSessions.delete(TrezorAdapter._appSessionKey(connectId, passphraseState));\n return this._callWithRetry<T>(connectId, method, params, false, signal);\n }\n return this._errorToFailure(error);\n }\n }\n\n private async _ensureSession(connectId: string): 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 const session = await this._connector.connect(connectId);\n this._sessions.set(connectId, session.sessionId);\n this._devices.set(connectId, session.deviceInfo);\n return session.sessionId;\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 THP session to `passphraseState` (the target\n * wallet's XFP) before a wallet-bound op. THP only — v1 devices report\n * `protocol: 'v1'` and this is a no-op (reactive passphrase).\n *\n * SECURITY: the XFP is ALWAYS re-derived and confirmed — the cache only saves\n * re-entering the passphrase, NEVER the verification. So even a cache hit\n * re-derives: if the device evicted/replaced that session slot the XFP won't\n * match, and we drop it and recreate rather than ever operating on the wrong\n * wallet. A fresh create whose XFP doesn't match the claimed state (wrong\n * passphrase entered) fails with `PassphraseStateMismatch`. This makes the\n * safety independent of the device's (unverified) eviction error code.\n */\n private async _alignAppSession(\n connectId: string,\n sessionId: string,\n passphraseState: string,\n signal: AbortSignal\n ): Promise<void> {\n const key = TrezorAdapter._appSessionKey(connectId, passphraseState);\n const cached = this._appSessions.get(key);\n if (cached) {\n const selected = (await TrezorAdapter._abortable(\n signal,\n this._connector.call(sessionId, '__thpSelectSession', { thpSessionId: cached })\n )) as { protocol?: string };\n // v1 device — no host-managed sessions; nothing to pin.\n if (selected?.protocol !== 'thp') return;\n // Re-derive even on a hit — never trust the cached mapping for a\n // wallet-bound op. Match → done; otherwise the slot is stale, recreate.\n if ((await this._deriveState(sessionId, signal)) === passphraseState) return;\n this._appSessions.delete(key);\n }\n const created = (await TrezorAdapter._abortable(\n signal,\n this._connector.call(sessionId, '__thpCreateSession', {})\n )) as { protocol?: string; thpSessionId?: string | null };\n // v1 device — reactive passphrase, no session to cache.\n if (created?.protocol !== 'thp' || !created.thpSessionId) 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._appSessions.set(key, created.thpSessionId);\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 this._connector.call(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(\n 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 TrezorAdapter._abortable(signal, this._ensureSession(connectId));\n if (passphraseState) {\n // Verify mode: align (which always re-derives + confirms the XFP) 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 XFP. 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 → hidden wallet → cache + return its\n // XFP. Otherwise → standard wallet → return null (no XFP tracked).\n const created = (await TrezorAdapter._abortable(\n signal,\n this._connector.call(sessionId, '__thpCreateSession', {})\n )) as { protocol?: string; thpSessionId?: string | null };\n const state = await this._deriveState(sessionId, signal);\n const features = (await TrezorAdapter._abortable(\n signal,\n this._connector.call(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 if (created?.protocol === 'thp' && created.thpSessionId) {\n // Overwrites any stale entry for the same state (clears conflicts).\n this._appSessions.set(TrezorAdapter._appSessionKey(connectId, state), created.thpSessionId);\n }\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._clearAppSessions(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 _onUiRequest = (data: { type: string; payload?: unknown }): void => {\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-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-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(\n HardwareErrorCode.ThpPairingFailed,\n typed.message ?? 'THP pairing failed'\n );\n }\n const code =\n typeof typed.code === 'number' ? typed.code : 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","export const TREZOR_SAFE_7_MODEL = 'T3W1';\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\n","import { TREZOR_SAFE_7_MODEL } 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 isTrezorSafe7BleDescriptor(descriptor: TrezorBleDescriptor): boolean {\n return descriptor.model === TREZOR_SAFE_7_MODEL || isTrezorSafe7BleName(descriptor.name);\n}\n\nexport function resolveTrezorBleConnectId(descriptor: TrezorBleDescriptor): string {\n return descriptor.id ?? descriptor.path ?? descriptor.deviceId ?? descriptor.name ?? '';\n}\n\n"],"mappings":"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","names":[]}
@@ -0,0 +1,200 @@
1
+ import { IHardwareWallet, IConnector, TransportType, DeviceInfo, Response, ChainCapability, UiResponseEvent, ChainForFingerprint, EvmGetAddressParams, EvmAddress, EvmSignTxParams, EvmSignedTx, EvmSignMsgParams, EvmSignature, EvmSignTypedDataParams, BtcGetAddressParams, BtcAddress, BtcGetPublicKeyParams, BtcPublicKey, BtcSignTxParams, BtcSignedTx, BtcSignPsbtParams, BtcSignedPsbt, BtcSignMsgParams, BtcSignature, SolGetAddressParams, SolAddress, SolSignTxParams, SolSignedTx, SolSignMsgParams, SolSignature, TronGetAddressParams, TronAddress, TronSignTxParams, TronSignedTx, TronSignMsgParams, TronSignature, HardwareEventMap, DeviceEventListener, ConnectorDevice } from '@onekeyfe/hwk-adapter-core';
2
+
3
+ declare class TrezorAdapter implements IHardwareWallet {
4
+ readonly vendor: "trezor";
5
+ private readonly _connector;
6
+ private readonly _emitter;
7
+ private readonly _devices;
8
+ private readonly _sessions;
9
+ private readonly _appSessions;
10
+ private readonly _connectingPromises;
11
+ private readonly _uiRegistry;
12
+ private readonly _jobQueue;
13
+ constructor(connector: IConnector);
14
+ private static _createDeviceBusyError;
15
+ private static _appSessionKey;
16
+ /**
17
+ * Split a Trezor-only `passphraseState` routing hint off the chain params so
18
+ * it never reaches the protobuf layer. The connector/firmware only sees the
19
+ * real op fields; the adapter uses `passphraseState` to align the session.
20
+ */
21
+ private static _splitPassphraseState;
22
+ /**
23
+ * Whether a device-side error code means the THP application session we
24
+ * selected is gone (the device evicted it from its limited slot pool). The
25
+ * caller drops the stale cache entry and recreates from scratch.
26
+ *
27
+ * NOTE: the exact eviction code still needs real-device confirmation — match
28
+ * conservatively so a genuine error isn't mistaken for an evicted session
29
+ * (which would silently re-prompt the passphrase).
30
+ */
31
+ private static _isStaleSessionError;
32
+ private _clearAppSessions;
33
+ /**
34
+ * Race a promise against an abort signal. Copied from LedgerAdapter:
35
+ * IConnector.call() can't actually be cancelled at the protocol level, but
36
+ * the caller gets the abort immediately and the underlying work completes
37
+ * uselessly in the background.
38
+ */
39
+ private static _abortable;
40
+ get activeTransport(): TransportType | null;
41
+ init(_config?: unknown): Promise<void>;
42
+ dispose(): Promise<void>;
43
+ /**
44
+ * Clear cached state without tearing down the adapter or unregistering
45
+ * listeners. Mirrors LedgerAdapter.resetState() — useful for retry-after-
46
+ * error flows. Aborts active jobs and releases UI waits.
47
+ */
48
+ resetState(): void;
49
+ getAvailableTransports(): TransportType[];
50
+ switchTransport(_type: TransportType): Promise<void>;
51
+ searchDevices(): Promise<DeviceInfo[]>;
52
+ connectDevice(connectId: string): Promise<Response<string>>;
53
+ disconnectDevice(connectId: string): Promise<void>;
54
+ getDeviceInfo(connectId: string, deviceId: string): Promise<Response<DeviceInfo>>;
55
+ getSupportedChains(): ChainCapability[];
56
+ getFeatures(connectId: string): Promise<Response<Record<string, unknown>>>;
57
+ cancel(connectId?: string): void;
58
+ /**
59
+ * Routes to BOTH the adapter's local UI registry (preemption decisions,
60
+ * future SELECT_DEVICE / DEVICE_PERMISSION) AND the connector's registry
61
+ * (THP pairing tag, PIN matrix). Each side ignores types it isn't waiting
62
+ * for, so double-routing is harmless.
63
+ */
64
+ uiResponse(response: UiResponseEvent): void;
65
+ /**
66
+ * Returns a stable per-seed identifier suitable for device-match verification.
67
+ *
68
+ * Trezor exposes `device_id` in Features — a server-generated UUID written
69
+ * during `wipe_device` and stable for the life of the seed. Unlike Ledger
70
+ * (no native id, so a per-chain address is hashed), Trezor's id is global
71
+ * across chains, so the `chain` argument is accepted for API parity but
72
+ * ignored. For unsupported chains we still surface the id (since it would
73
+ * be the same value anyway).
74
+ */
75
+ getChainFingerprint(connectId: string, _deviceId: string, _chain: ChainForFingerprint): Promise<Response<string>>;
76
+ /**
77
+ * Resolve the active passphrase wallet identity (master fingerprint / XFP).
78
+ * See {@link IHardwareWallet.getPassphraseState} for the discover/verify
79
+ * semantics. Returns `null` for a standard wallet (no passphrase protection) —
80
+ * there's nothing to pin. Serialized through the per-device job queue so it
81
+ * can't interleave with a chain call on the same device (which would desync
82
+ * the THP session selection).
83
+ */
84
+ getPassphraseState(connectId: string, passphraseState?: string): Promise<Response<string | null>>;
85
+ evmGetAddress(connectId: string, _deviceId: string, params: EvmGetAddressParams): Promise<Response<EvmAddress>>;
86
+ evmSignTransaction(connectId: string, _deviceId: string, params: EvmSignTxParams): Promise<Response<EvmSignedTx>>;
87
+ evmSignMessage(connectId: string, _deviceId: string, params: EvmSignMsgParams): Promise<Response<EvmSignature>>;
88
+ evmSignTypedData(connectId: string, _deviceId: string, params: EvmSignTypedDataParams): Promise<Response<EvmSignature>>;
89
+ btcGetAddress(connectId: string, _deviceId: string, params: BtcGetAddressParams): Promise<Response<BtcAddress>>;
90
+ btcGetPublicKey(connectId: string, _deviceId: string, params: BtcGetPublicKeyParams): Promise<Response<BtcPublicKey>>;
91
+ btcSignTransaction(connectId: string, _deviceId: string, params: BtcSignTxParams): Promise<Response<BtcSignedTx>>;
92
+ btcSignPsbt(connectId: string, _deviceId: string, params: BtcSignPsbtParams): Promise<Response<BtcSignedPsbt>>;
93
+ btcSignMessage(connectId: string, _deviceId: string, params: BtcSignMsgParams): Promise<Response<BtcSignature>>;
94
+ btcGetMasterFingerprint(connectId: string, _deviceId: string): Promise<Response<{
95
+ masterFingerprint: string;
96
+ }>>;
97
+ solGetAddress(connectId: string, _deviceId: string, params: SolGetAddressParams): Promise<Response<SolAddress>>;
98
+ solSignTransaction(connectId: string, _deviceId: string, params: SolSignTxParams): Promise<Response<SolSignedTx>>;
99
+ solSignMessage(connectId: string, _deviceId: string, params: SolSignMsgParams): Promise<Response<SolSignature>>;
100
+ tronGetAddress(connectId: string, _deviceId: string, params: TronGetAddressParams): Promise<Response<TronAddress>>;
101
+ tronSignTransaction(connectId: string, _deviceId: string, params: TronSignTxParams): Promise<Response<TronSignedTx>>;
102
+ tronSignMessage(connectId: string, _deviceId: string, params: TronSignMsgParams): Promise<Response<TronSignature>>;
103
+ on<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
104
+ on(event: string, listener: DeviceEventListener): void;
105
+ off<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
106
+ off(event: string, listener: DeviceEventListener): void;
107
+ private _call;
108
+ private _callWithRetry;
109
+ private _ensureSession;
110
+ /**
111
+ * Pin the device's active THP session to `passphraseState` (the target
112
+ * wallet's XFP) before a wallet-bound op. THP only — v1 devices report
113
+ * `protocol: 'v1'` and this is a no-op (reactive passphrase).
114
+ *
115
+ * SECURITY: the XFP is ALWAYS re-derived and confirmed — the cache only saves
116
+ * re-entering the passphrase, NEVER the verification. So even a cache hit
117
+ * re-derives: if the device evicted/replaced that session slot the XFP won't
118
+ * match, and we drop it and recreate rather than ever operating on the wrong
119
+ * wallet. A fresh create whose XFP doesn't match the claimed state (wrong
120
+ * passphrase entered) fails with `PassphraseStateMismatch`. This makes the
121
+ * safety independent of the device's (unverified) eviction error code.
122
+ */
123
+ private _alignAppSession;
124
+ /**
125
+ * Derive the active session's passphrase state — the wallet identity used to
126
+ * verify the right wallet is active: the compressed PUBLIC KEY at a fixed
127
+ * account path (m/44'/0'/0'). It comes from the SAME GetPublicKey that also
128
+ * carries the 4-byte fingerprint, but we use the FULL pubkey (not the truncated
129
+ * fingerprint) so it's collision-resistant — the address we return can never
130
+ * come from the wrong wallet — while avoiding OneKey's extra Testnet GetAddress.
131
+ * Non-interactive (also unlocks via PIN as a protected derivation).
132
+ */
133
+ private _deriveState;
134
+ private _resolvePassphraseState;
135
+ private _onDeviceConnect;
136
+ private _onDeviceDisconnect;
137
+ private _onUiRequest;
138
+ private _onUiEvent;
139
+ private _onThpCredentialsChanged;
140
+ private _registerConnectorEvents;
141
+ private _unregisterConnectorEvents;
142
+ private _connectorDeviceToDeviceInfo;
143
+ private _errorToFailure;
144
+ /**
145
+ * Emit `REQUEST_DEVICE_PERMISSION` and await the host's
146
+ * `RECEIVE_DEVICE_PERMISSION` reply (60s budget covers OS prompt + user
147
+ * tap). If the host doesn't wire a handler the wait times out and the
148
+ * operation fails fast.
149
+ *
150
+ * Mirrors LedgerAdapter._ensureDevicePermission so hosts can register a
151
+ * single handler that branches by `payload.transportType` (and optionally
152
+ * the active brand) instead of teaching every adapter its own contract.
153
+ *
154
+ * - no `connectId` → environment-level check (scan / picker)
155
+ * - with `connectId` → device-level check (per-call gating)
156
+ */
157
+ private _ensureDevicePermission;
158
+ }
159
+
160
+ declare const TREZOR_SAFE_7_MODEL = "T3W1";
161
+ declare const TREZOR_BLE_PACKET_SIZE = 244;
162
+ declare const TREZOR_BLE_UUIDS: {
163
+ readonly service: "8c000001-a59b-4d58-a9ad-073df69fa1b1";
164
+ readonly write: "8c000002-a59b-4d58-a9ad-073df69fa1b1";
165
+ readonly notify: "8c000003-a59b-4d58-a9ad-073df69fa1b1";
166
+ readonly push: "8c000004-a59b-4d58-a9ad-073df69fa1b1";
167
+ readonly batteryService: "0000180f-0000-1000-8000-00805f9b34fb";
168
+ };
169
+
170
+ interface TrezorBleDescriptor {
171
+ id?: string;
172
+ path?: string;
173
+ name?: string;
174
+ model?: string;
175
+ firmwareVersion?: string;
176
+ battery?: number;
177
+ deviceId?: string;
178
+ }
179
+ interface TrezorConnectedDevice extends TrezorBleDescriptor {
180
+ id: string;
181
+ }
182
+ interface TrezorBleTransport {
183
+ scan(): Promise<TrezorBleDescriptor[]>;
184
+ connect(connectId: string): Promise<TrezorConnectedDevice>;
185
+ disconnect(connectId: string): Promise<void>;
186
+ write?(connectId: string, data: Uint8Array): Promise<void>;
187
+ read?(connectId: string, timeoutMs?: number): Promise<Uint8Array>;
188
+ exchange?(connectId: string, data: Uint8Array, timeoutMs?: number): Promise<Uint8Array>;
189
+ onDisconnect?(connectId: string, handler: () => void): () => void;
190
+ cancel?(connectId: string): Promise<void>;
191
+ reset?(): void;
192
+ }
193
+ type TrezorBleTransportFactory = () => Promise<TrezorBleTransport>;
194
+ type TrezorConnectorDevice = ConnectorDevice;
195
+
196
+ declare function isTrezorSafe7BleName(name?: string): boolean;
197
+ declare function isTrezorSafe7BleDescriptor(descriptor: TrezorBleDescriptor): boolean;
198
+ declare function resolveTrezorBleConnectId(descriptor: TrezorBleDescriptor): string;
199
+
200
+ export { TREZOR_BLE_PACKET_SIZE, TREZOR_BLE_UUIDS, TREZOR_SAFE_7_MODEL, TrezorAdapter, type TrezorBleDescriptor, type TrezorBleTransport, type TrezorBleTransportFactory, type TrezorConnectedDevice, type TrezorConnectorDevice, isTrezorSafe7BleDescriptor, isTrezorSafe7BleName, resolveTrezorBleConnectId };
@@ -0,0 +1,200 @@
1
+ import { IHardwareWallet, IConnector, TransportType, DeviceInfo, Response, ChainCapability, UiResponseEvent, ChainForFingerprint, EvmGetAddressParams, EvmAddress, EvmSignTxParams, EvmSignedTx, EvmSignMsgParams, EvmSignature, EvmSignTypedDataParams, BtcGetAddressParams, BtcAddress, BtcGetPublicKeyParams, BtcPublicKey, BtcSignTxParams, BtcSignedTx, BtcSignPsbtParams, BtcSignedPsbt, BtcSignMsgParams, BtcSignature, SolGetAddressParams, SolAddress, SolSignTxParams, SolSignedTx, SolSignMsgParams, SolSignature, TronGetAddressParams, TronAddress, TronSignTxParams, TronSignedTx, TronSignMsgParams, TronSignature, HardwareEventMap, DeviceEventListener, ConnectorDevice } from '@onekeyfe/hwk-adapter-core';
2
+
3
+ declare class TrezorAdapter implements IHardwareWallet {
4
+ readonly vendor: "trezor";
5
+ private readonly _connector;
6
+ private readonly _emitter;
7
+ private readonly _devices;
8
+ private readonly _sessions;
9
+ private readonly _appSessions;
10
+ private readonly _connectingPromises;
11
+ private readonly _uiRegistry;
12
+ private readonly _jobQueue;
13
+ constructor(connector: IConnector);
14
+ private static _createDeviceBusyError;
15
+ private static _appSessionKey;
16
+ /**
17
+ * Split a Trezor-only `passphraseState` routing hint off the chain params so
18
+ * it never reaches the protobuf layer. The connector/firmware only sees the
19
+ * real op fields; the adapter uses `passphraseState` to align the session.
20
+ */
21
+ private static _splitPassphraseState;
22
+ /**
23
+ * Whether a device-side error code means the THP application session we
24
+ * selected is gone (the device evicted it from its limited slot pool). The
25
+ * caller drops the stale cache entry and recreates from scratch.
26
+ *
27
+ * NOTE: the exact eviction code still needs real-device confirmation — match
28
+ * conservatively so a genuine error isn't mistaken for an evicted session
29
+ * (which would silently re-prompt the passphrase).
30
+ */
31
+ private static _isStaleSessionError;
32
+ private _clearAppSessions;
33
+ /**
34
+ * Race a promise against an abort signal. Copied from LedgerAdapter:
35
+ * IConnector.call() can't actually be cancelled at the protocol level, but
36
+ * the caller gets the abort immediately and the underlying work completes
37
+ * uselessly in the background.
38
+ */
39
+ private static _abortable;
40
+ get activeTransport(): TransportType | null;
41
+ init(_config?: unknown): Promise<void>;
42
+ dispose(): Promise<void>;
43
+ /**
44
+ * Clear cached state without tearing down the adapter or unregistering
45
+ * listeners. Mirrors LedgerAdapter.resetState() — useful for retry-after-
46
+ * error flows. Aborts active jobs and releases UI waits.
47
+ */
48
+ resetState(): void;
49
+ getAvailableTransports(): TransportType[];
50
+ switchTransport(_type: TransportType): Promise<void>;
51
+ searchDevices(): Promise<DeviceInfo[]>;
52
+ connectDevice(connectId: string): Promise<Response<string>>;
53
+ disconnectDevice(connectId: string): Promise<void>;
54
+ getDeviceInfo(connectId: string, deviceId: string): Promise<Response<DeviceInfo>>;
55
+ getSupportedChains(): ChainCapability[];
56
+ getFeatures(connectId: string): Promise<Response<Record<string, unknown>>>;
57
+ cancel(connectId?: string): void;
58
+ /**
59
+ * Routes to BOTH the adapter's local UI registry (preemption decisions,
60
+ * future SELECT_DEVICE / DEVICE_PERMISSION) AND the connector's registry
61
+ * (THP pairing tag, PIN matrix). Each side ignores types it isn't waiting
62
+ * for, so double-routing is harmless.
63
+ */
64
+ uiResponse(response: UiResponseEvent): void;
65
+ /**
66
+ * Returns a stable per-seed identifier suitable for device-match verification.
67
+ *
68
+ * Trezor exposes `device_id` in Features — a server-generated UUID written
69
+ * during `wipe_device` and stable for the life of the seed. Unlike Ledger
70
+ * (no native id, so a per-chain address is hashed), Trezor's id is global
71
+ * across chains, so the `chain` argument is accepted for API parity but
72
+ * ignored. For unsupported chains we still surface the id (since it would
73
+ * be the same value anyway).
74
+ */
75
+ getChainFingerprint(connectId: string, _deviceId: string, _chain: ChainForFingerprint): Promise<Response<string>>;
76
+ /**
77
+ * Resolve the active passphrase wallet identity (master fingerprint / XFP).
78
+ * See {@link IHardwareWallet.getPassphraseState} for the discover/verify
79
+ * semantics. Returns `null` for a standard wallet (no passphrase protection) —
80
+ * there's nothing to pin. Serialized through the per-device job queue so it
81
+ * can't interleave with a chain call on the same device (which would desync
82
+ * the THP session selection).
83
+ */
84
+ getPassphraseState(connectId: string, passphraseState?: string): Promise<Response<string | null>>;
85
+ evmGetAddress(connectId: string, _deviceId: string, params: EvmGetAddressParams): Promise<Response<EvmAddress>>;
86
+ evmSignTransaction(connectId: string, _deviceId: string, params: EvmSignTxParams): Promise<Response<EvmSignedTx>>;
87
+ evmSignMessage(connectId: string, _deviceId: string, params: EvmSignMsgParams): Promise<Response<EvmSignature>>;
88
+ evmSignTypedData(connectId: string, _deviceId: string, params: EvmSignTypedDataParams): Promise<Response<EvmSignature>>;
89
+ btcGetAddress(connectId: string, _deviceId: string, params: BtcGetAddressParams): Promise<Response<BtcAddress>>;
90
+ btcGetPublicKey(connectId: string, _deviceId: string, params: BtcGetPublicKeyParams): Promise<Response<BtcPublicKey>>;
91
+ btcSignTransaction(connectId: string, _deviceId: string, params: BtcSignTxParams): Promise<Response<BtcSignedTx>>;
92
+ btcSignPsbt(connectId: string, _deviceId: string, params: BtcSignPsbtParams): Promise<Response<BtcSignedPsbt>>;
93
+ btcSignMessage(connectId: string, _deviceId: string, params: BtcSignMsgParams): Promise<Response<BtcSignature>>;
94
+ btcGetMasterFingerprint(connectId: string, _deviceId: string): Promise<Response<{
95
+ masterFingerprint: string;
96
+ }>>;
97
+ solGetAddress(connectId: string, _deviceId: string, params: SolGetAddressParams): Promise<Response<SolAddress>>;
98
+ solSignTransaction(connectId: string, _deviceId: string, params: SolSignTxParams): Promise<Response<SolSignedTx>>;
99
+ solSignMessage(connectId: string, _deviceId: string, params: SolSignMsgParams): Promise<Response<SolSignature>>;
100
+ tronGetAddress(connectId: string, _deviceId: string, params: TronGetAddressParams): Promise<Response<TronAddress>>;
101
+ tronSignTransaction(connectId: string, _deviceId: string, params: TronSignTxParams): Promise<Response<TronSignedTx>>;
102
+ tronSignMessage(connectId: string, _deviceId: string, params: TronSignMsgParams): Promise<Response<TronSignature>>;
103
+ on<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
104
+ on(event: string, listener: DeviceEventListener): void;
105
+ off<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
106
+ off(event: string, listener: DeviceEventListener): void;
107
+ private _call;
108
+ private _callWithRetry;
109
+ private _ensureSession;
110
+ /**
111
+ * Pin the device's active THP session to `passphraseState` (the target
112
+ * wallet's XFP) before a wallet-bound op. THP only — v1 devices report
113
+ * `protocol: 'v1'` and this is a no-op (reactive passphrase).
114
+ *
115
+ * SECURITY: the XFP is ALWAYS re-derived and confirmed — the cache only saves
116
+ * re-entering the passphrase, NEVER the verification. So even a cache hit
117
+ * re-derives: if the device evicted/replaced that session slot the XFP won't
118
+ * match, and we drop it and recreate rather than ever operating on the wrong
119
+ * wallet. A fresh create whose XFP doesn't match the claimed state (wrong
120
+ * passphrase entered) fails with `PassphraseStateMismatch`. This makes the
121
+ * safety independent of the device's (unverified) eviction error code.
122
+ */
123
+ private _alignAppSession;
124
+ /**
125
+ * Derive the active session's passphrase state — the wallet identity used to
126
+ * verify the right wallet is active: the compressed PUBLIC KEY at a fixed
127
+ * account path (m/44'/0'/0'). It comes from the SAME GetPublicKey that also
128
+ * carries the 4-byte fingerprint, but we use the FULL pubkey (not the truncated
129
+ * fingerprint) so it's collision-resistant — the address we return can never
130
+ * come from the wrong wallet — while avoiding OneKey's extra Testnet GetAddress.
131
+ * Non-interactive (also unlocks via PIN as a protected derivation).
132
+ */
133
+ private _deriveState;
134
+ private _resolvePassphraseState;
135
+ private _onDeviceConnect;
136
+ private _onDeviceDisconnect;
137
+ private _onUiRequest;
138
+ private _onUiEvent;
139
+ private _onThpCredentialsChanged;
140
+ private _registerConnectorEvents;
141
+ private _unregisterConnectorEvents;
142
+ private _connectorDeviceToDeviceInfo;
143
+ private _errorToFailure;
144
+ /**
145
+ * Emit `REQUEST_DEVICE_PERMISSION` and await the host's
146
+ * `RECEIVE_DEVICE_PERMISSION` reply (60s budget covers OS prompt + user
147
+ * tap). If the host doesn't wire a handler the wait times out and the
148
+ * operation fails fast.
149
+ *
150
+ * Mirrors LedgerAdapter._ensureDevicePermission so hosts can register a
151
+ * single handler that branches by `payload.transportType` (and optionally
152
+ * the active brand) instead of teaching every adapter its own contract.
153
+ *
154
+ * - no `connectId` → environment-level check (scan / picker)
155
+ * - with `connectId` → device-level check (per-call gating)
156
+ */
157
+ private _ensureDevicePermission;
158
+ }
159
+
160
+ declare const TREZOR_SAFE_7_MODEL = "T3W1";
161
+ declare const TREZOR_BLE_PACKET_SIZE = 244;
162
+ declare const TREZOR_BLE_UUIDS: {
163
+ readonly service: "8c000001-a59b-4d58-a9ad-073df69fa1b1";
164
+ readonly write: "8c000002-a59b-4d58-a9ad-073df69fa1b1";
165
+ readonly notify: "8c000003-a59b-4d58-a9ad-073df69fa1b1";
166
+ readonly push: "8c000004-a59b-4d58-a9ad-073df69fa1b1";
167
+ readonly batteryService: "0000180f-0000-1000-8000-00805f9b34fb";
168
+ };
169
+
170
+ interface TrezorBleDescriptor {
171
+ id?: string;
172
+ path?: string;
173
+ name?: string;
174
+ model?: string;
175
+ firmwareVersion?: string;
176
+ battery?: number;
177
+ deviceId?: string;
178
+ }
179
+ interface TrezorConnectedDevice extends TrezorBleDescriptor {
180
+ id: string;
181
+ }
182
+ interface TrezorBleTransport {
183
+ scan(): Promise<TrezorBleDescriptor[]>;
184
+ connect(connectId: string): Promise<TrezorConnectedDevice>;
185
+ disconnect(connectId: string): Promise<void>;
186
+ write?(connectId: string, data: Uint8Array): Promise<void>;
187
+ read?(connectId: string, timeoutMs?: number): Promise<Uint8Array>;
188
+ exchange?(connectId: string, data: Uint8Array, timeoutMs?: number): Promise<Uint8Array>;
189
+ onDisconnect?(connectId: string, handler: () => void): () => void;
190
+ cancel?(connectId: string): Promise<void>;
191
+ reset?(): void;
192
+ }
193
+ type TrezorBleTransportFactory = () => Promise<TrezorBleTransport>;
194
+ type TrezorConnectorDevice = ConnectorDevice;
195
+
196
+ declare function isTrezorSafe7BleName(name?: string): boolean;
197
+ declare function isTrezorSafe7BleDescriptor(descriptor: TrezorBleDescriptor): boolean;
198
+ declare function resolveTrezorBleConnectId(descriptor: TrezorBleDescriptor): string;
199
+
200
+ export { TREZOR_BLE_PACKET_SIZE, TREZOR_BLE_UUIDS, TREZOR_SAFE_7_MODEL, TrezorAdapter, type TrezorBleDescriptor, type TrezorBleTransport, type TrezorBleTransportFactory, type TrezorConnectedDevice, type TrezorConnectorDevice, isTrezorSafe7BleDescriptor, isTrezorSafe7BleName, resolveTrezorBleConnectId };
package/dist/index.js ADDED
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/adapter/TrezorAdapter.ts","../src/constants.ts","../src/utils/bleIdentity.ts"],"sourcesContent":["export { TrezorAdapter } from './adapter/TrezorAdapter';\nexport { TREZOR_BLE_PACKET_SIZE, TREZOR_BLE_UUIDS, TREZOR_SAFE_7_MODEL } from './constants';\nexport {\n isTrezorSafe7BleDescriptor,\n isTrezorSafe7BleName,\n resolveTrezorBleConnectId,\n} from './utils/bleIdentity';\nexport type {\n TrezorBleDescriptor,\n TrezorBleTransport,\n TrezorBleTransportFactory,\n TrezorConnectedDevice,\n TrezorConnectorDevice,\n} from './types';\n","import {\n DEVICE,\n DeviceJobQueue,\n HardwareErrorCode,\n TypedEventEmitter,\n UI_REQUEST,\n UI_RESPONSE,\n UiRequestRegistry,\n failure,\n success,\n} from '@onekeyfe/hwk-adapter-core';\n\nimport type {\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 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 IConnector,\n IHardwareWallet,\n Response,\n SolAddress,\n SolGetAddressParams,\n SolSignMsgParams,\n SolSignTxParams,\n SolSignature,\n SolSignedTx,\n TransportType,\n TronAddress,\n TronGetAddressParams,\n TronSignMsgParams,\n TronSignTxParams,\n TronSignature,\n TronSignedTx,\n UiResponseEvent,\n} from '@onekeyfe/hwk-adapter-core';\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 // Passphrase application sessions, keyed by `${connectId}\u0000${XFP}` →\n // THP session id. The adapter owns the XFP↔sessionId mapping; the SDK session\n // only deals in opaque session ids. Multiple entries per connectId coexist\n // (one per passphrase wallet), mirroring the device's session slots. Cleared\n // when the channel drops (sessions die with it) or a session is evicted.\n private readonly _appSessions = new Map<string, string>();\n\n private readonly _connectingPromises = new Map<string, Promise<string>>();\n\n private readonly _uiRegistry = new UiRequestRegistry();\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 private static _appSessionKey(connectId: string, passphraseState: string): string {\n return `${connectId}\u0000${passphraseState}`;\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 _splitPassphraseState(params: unknown): {\n passphraseState?: string;\n rest: unknown;\n } {\n if (params && typeof params === 'object' && 'passphraseState' in params) {\n const { passphraseState, ...rest } = params as Record<string, unknown>;\n return {\n passphraseState: typeof passphraseState === 'string' ? passphraseState : undefined,\n rest,\n };\n }\n return { rest: params };\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 _clearAppSessions(connectId: string): void {\n const prefix = `${connectId}\u0000`;\n for (const key of [...this._appSessions.keys()]) {\n if (key.startsWith(prefix)) this._appSessions.delete(key);\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 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._appSessions.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._appSessions.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(): Promise<DeviceInfo[]> {\n await this._ensureDevicePermission();\n const scanned = await this._connector.searchDevices();\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 this._clearAppSessions(connectId);\n if (!sessionId) return;\n await this._connector.disconnect(sessionId);\n this._sessions.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 deferred (multi-step\n // TronContractRequest flow + rawTxHex decoding needs device testing).\n return ['btc', 'evm', 'sol', 'tron'];\n }\n\n getFeatures(connectId: string): Promise<Response<Record<string, unknown>>> {\n return this._call<Record<string, unknown>>(connectId, 'getFeatures', {});\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 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(\n HardwareErrorCode.UnknownError,\n 'Trezor features did not include a device_id'\n );\n }\n return success(liveDeviceId);\n }\n\n /**\n * Resolve the active passphrase wallet identity (master fingerprint / XFP).\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 signal => this._resolvePassphraseState(connectId, passphraseState, signal),\n {\n label: 'getPassphraseState',\n rejectIfBusy: true,\n busyError: TrezorAdapter._createDeviceBusyError('getPassphraseState'),\n }\n )\n .catch(error => this._errorToFailure(error));\n }\n\n evmGetAddress(connectId: string, _deviceId: string, params: EvmGetAddressParams) {\n return this._call<EvmAddress>(connectId, 'evmGetAddress', params);\n }\n\n evmSignTransaction(connectId: string, _deviceId: string, params: EvmSignTxParams) {\n return this._call<EvmSignedTx>(connectId, 'evmSignTransaction', params);\n }\n\n evmSignMessage(connectId: string, _deviceId: string, params: EvmSignMsgParams) {\n return this._call<EvmSignature>(connectId, 'evmSignMessage', params);\n }\n\n evmSignTypedData(connectId: string, _deviceId: string, params: EvmSignTypedDataParams) {\n return this._call<EvmSignature>(connectId, 'evmSignTypedData', params);\n }\n\n btcGetAddress(connectId: string, _deviceId: string, params: BtcGetAddressParams) {\n return this._call<BtcAddress>(connectId, 'btcGetAddress', params);\n }\n\n btcGetPublicKey(connectId: string, _deviceId: string, params: BtcGetPublicKeyParams) {\n return this._call<BtcPublicKey>(connectId, 'btcGetPublicKey', params);\n }\n\n btcSignTransaction(connectId: string, _deviceId: string, params: BtcSignTxParams) {\n return this._call<BtcSignedTx>(connectId, 'btcSignTransaction', params);\n }\n\n btcSignPsbt(connectId: string, _deviceId: string, params: BtcSignPsbtParams) {\n return this._call<BtcSignedPsbt>(connectId, 'btcSignPsbt', params);\n }\n\n btcSignMessage(connectId: string, _deviceId: string, params: BtcSignMsgParams) {\n return this._call<BtcSignature>(connectId, 'btcSignMessage', params);\n }\n\n btcGetMasterFingerprint(connectId: string, _deviceId: string) {\n return this._call<{ masterFingerprint: string }>(connectId, 'btcGetMasterFingerprint', {});\n }\n\n solGetAddress(connectId: string, _deviceId: string, params: SolGetAddressParams) {\n return this._call<SolAddress>(connectId, 'solGetAddress', params);\n }\n\n solSignTransaction(connectId: string, _deviceId: string, params: SolSignTxParams) {\n return this._call<SolSignedTx>(connectId, 'solSignTransaction', params);\n }\n\n solSignMessage(connectId: string, _deviceId: string, params: SolSignMsgParams) {\n return this._call<SolSignature>(connectId, 'solSignMessage', params);\n }\n\n tronGetAddress(connectId: string, _deviceId: string, params: TronGetAddressParams) {\n return this._call<TronAddress>(connectId, 'tronGetAddress', params);\n }\n\n tronSignTransaction(connectId: string, _deviceId: string, params: TronSignTxParams) {\n return this._call<TronSignedTx>(connectId, 'tronSignTransaction', params);\n }\n\n tronSignMessage(connectId: string, _deviceId: string, params: TronSignMsgParams) {\n return this._call<TronSignature>(connectId, 'tronSignMessage', params);\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 async _call<T>(connectId: string, method: string, params: unknown): Promise<Response<T>> {\n try {\n return await this._jobQueue.enqueue(\n connectId,\n signal => this._callWithRetry<T>(connectId, method, params, true, signal),\n {\n label: method,\n rejectIfBusy: true,\n busyError: TrezorAdapter._createDeviceBusyError(method),\n },\n );\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 return this._errorToFailure(error);\n }\n }\n\n private async _callWithRetry<T>(\n connectId: string,\n method: string,\n params: unknown,\n allowRetry: boolean,\n signal: AbortSignal\n ): Promise<Response<T>> {\n const { passphraseState, rest } = TrezorAdapter._splitPassphraseState(params);\n try {\n const sessionId = await TrezorAdapter._abortable(signal, this._ensureSession(connectId));\n // Pin the call to the requested passphrase wallet (THP only; v1 is a\n // no-op handled reactively by the device). Runs inside this queued job so\n // the select and the call can't be interleaved by another request.\n if (passphraseState) {\n await TrezorAdapter._abortable(\n signal,\n this._alignAppSession(connectId, sessionId, passphraseState, signal)\n );\n }\n const result = await TrezorAdapter._abortable(\n signal,\n this._connector.call(sessionId, method, 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 = (error as { code?: HardwareErrorCode | string }).code;\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 // Application sessions live on the channel — a fresh channel has none.\n this._clearAppSessions(connectId);\n return this._callWithRetry<T>(connectId, method, params, false, signal);\n }\n // The device evicted the passphrase session we selected. Drop the stale\n // mapping and retry once — the cache miss recreates it (re-prompts) and\n // re-verifies the XFP before the call.\n if (allowRetry && passphraseState && TrezorAdapter._isStaleSessionError(code)) {\n this._appSessions.delete(TrezorAdapter._appSessionKey(connectId, passphraseState));\n return this._callWithRetry<T>(connectId, method, params, false, signal);\n }\n return this._errorToFailure(error);\n }\n }\n\n private async _ensureSession(connectId: string): 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 const session = await this._connector.connect(connectId);\n this._sessions.set(connectId, session.sessionId);\n this._devices.set(connectId, session.deviceInfo);\n return session.sessionId;\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 THP session to `passphraseState` (the target\n * wallet's XFP) before a wallet-bound op. THP only — v1 devices report\n * `protocol: 'v1'` and this is a no-op (reactive passphrase).\n *\n * SECURITY: the XFP is ALWAYS re-derived and confirmed — the cache only saves\n * re-entering the passphrase, NEVER the verification. So even a cache hit\n * re-derives: if the device evicted/replaced that session slot the XFP won't\n * match, and we drop it and recreate rather than ever operating on the wrong\n * wallet. A fresh create whose XFP doesn't match the claimed state (wrong\n * passphrase entered) fails with `PassphraseStateMismatch`. This makes the\n * safety independent of the device's (unverified) eviction error code.\n */\n private async _alignAppSession(\n connectId: string,\n sessionId: string,\n passphraseState: string,\n signal: AbortSignal\n ): Promise<void> {\n const key = TrezorAdapter._appSessionKey(connectId, passphraseState);\n const cached = this._appSessions.get(key);\n if (cached) {\n const selected = (await TrezorAdapter._abortable(\n signal,\n this._connector.call(sessionId, '__thpSelectSession', { thpSessionId: cached })\n )) as { protocol?: string };\n // v1 device — no host-managed sessions; nothing to pin.\n if (selected?.protocol !== 'thp') return;\n // Re-derive even on a hit — never trust the cached mapping for a\n // wallet-bound op. Match → done; otherwise the slot is stale, recreate.\n if ((await this._deriveState(sessionId, signal)) === passphraseState) return;\n this._appSessions.delete(key);\n }\n const created = (await TrezorAdapter._abortable(\n signal,\n this._connector.call(sessionId, '__thpCreateSession', {})\n )) as { protocol?: string; thpSessionId?: string | null };\n // v1 device — reactive passphrase, no session to cache.\n if (created?.protocol !== 'thp' || !created.thpSessionId) 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._appSessions.set(key, created.thpSessionId);\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 this._connector.call(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(\n 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 TrezorAdapter._abortable(signal, this._ensureSession(connectId));\n if (passphraseState) {\n // Verify mode: align (which always re-derives + confirms the XFP) 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 XFP. 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 → hidden wallet → cache + return its\n // XFP. Otherwise → standard wallet → return null (no XFP tracked).\n const created = (await TrezorAdapter._abortable(\n signal,\n this._connector.call(sessionId, '__thpCreateSession', {})\n )) as { protocol?: string; thpSessionId?: string | null };\n const state = await this._deriveState(sessionId, signal);\n const features = (await TrezorAdapter._abortable(\n signal,\n this._connector.call(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 if (created?.protocol === 'thp' && created.thpSessionId) {\n // Overwrites any stale entry for the same state (clears conflicts).\n this._appSessions.set(TrezorAdapter._appSessionKey(connectId, state), created.thpSessionId);\n }\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._clearAppSessions(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 _onUiRequest = (data: { type: string; payload?: unknown }): void => {\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-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-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(\n HardwareErrorCode.ThpPairingFailed,\n typed.message ?? 'THP pairing failed'\n );\n }\n const code =\n typeof typed.code === 'number' ? typed.code : 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","export const TREZOR_SAFE_7_MODEL = 'T3W1';\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\n","import { TREZOR_SAFE_7_MODEL } 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 isTrezorSafe7BleDescriptor(descriptor: TrezorBleDescriptor): boolean {\n return descriptor.model === TREZOR_SAFE_7_MODEL || isTrezorSafe7BleName(descriptor.name);\n}\n\nexport function resolveTrezorBleConnectId(descriptor: TrezorBleDescriptor): string {\n return descriptor.id ?? descriptor.path ?? descriptor.deviceId ?? descriptor.name ?? '';\n}\n\n"],"mappings":"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","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1,19 @@
1
+ import {
2
+ TREZOR_BLE_PACKET_SIZE,
3
+ TREZOR_BLE_UUIDS,
4
+ TREZOR_SAFE_7_MODEL,
5
+ TrezorAdapter,
6
+ isTrezorSafe7BleDescriptor,
7
+ isTrezorSafe7BleName,
8
+ resolveTrezorBleConnectId
9
+ } from "./chunk-QT23DMW5.mjs";
10
+ export {
11
+ TREZOR_BLE_PACKET_SIZE,
12
+ TREZOR_BLE_UUIDS,
13
+ TREZOR_SAFE_7_MODEL,
14
+ TrezorAdapter,
15
+ isTrezorSafe7BleDescriptor,
16
+ isTrezorSafe7BleName,
17
+ resolveTrezorBleConnectId
18
+ };
19
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/rn.d.mts ADDED
@@ -0,0 +1,2 @@
1
+ export { TREZOR_BLE_PACKET_SIZE, TREZOR_BLE_UUIDS, TREZOR_SAFE_7_MODEL, TrezorAdapter, TrezorBleDescriptor, TrezorBleTransport, TrezorBleTransportFactory, TrezorConnectedDevice, TrezorConnectorDevice, isTrezorSafe7BleDescriptor, isTrezorSafe7BleName, resolveTrezorBleConnectId } from './index.mjs';
2
+ import '@onekeyfe/hwk-adapter-core';
package/dist/rn.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { TREZOR_BLE_PACKET_SIZE, TREZOR_BLE_UUIDS, TREZOR_SAFE_7_MODEL, TrezorAdapter, TrezorBleDescriptor, TrezorBleTransport, TrezorBleTransportFactory, TrezorConnectedDevice, TrezorConnectorDevice, isTrezorSafe7BleDescriptor, isTrezorSafe7BleName, resolveTrezorBleConnectId } from './index.js';
2
+ import '@onekeyfe/hwk-adapter-core';
package/dist/rn.js ADDED
Binary file
package/dist/rn.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/rn.ts","../src/adapter/TrezorAdapter.ts","../src/constants.ts","../src/utils/bleIdentity.ts"],"sourcesContent":["export { TrezorAdapter } from './adapter/TrezorAdapter';\nexport { TREZOR_BLE_PACKET_SIZE, TREZOR_BLE_UUIDS, TREZOR_SAFE_7_MODEL } from './constants';\nexport {\n isTrezorSafe7BleDescriptor,\n isTrezorSafe7BleName,\n resolveTrezorBleConnectId,\n} from './utils/bleIdentity';\n\nexport type {\n TrezorBleDescriptor,\n TrezorBleTransport,\n TrezorBleTransportFactory,\n TrezorConnectedDevice,\n TrezorConnectorDevice,\n} from './types';\n","import {\n DEVICE,\n DeviceJobQueue,\n HardwareErrorCode,\n TypedEventEmitter,\n UI_REQUEST,\n UI_RESPONSE,\n UiRequestRegistry,\n failure,\n success,\n} from '@onekeyfe/hwk-adapter-core';\n\nimport type {\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 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 IConnector,\n IHardwareWallet,\n Response,\n SolAddress,\n SolGetAddressParams,\n SolSignMsgParams,\n SolSignTxParams,\n SolSignature,\n SolSignedTx,\n TransportType,\n TronAddress,\n TronGetAddressParams,\n TronSignMsgParams,\n TronSignTxParams,\n TronSignature,\n TronSignedTx,\n UiResponseEvent,\n} from '@onekeyfe/hwk-adapter-core';\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 // Passphrase application sessions, keyed by `${connectId}\u0000${XFP}` →\n // THP session id. The adapter owns the XFP↔sessionId mapping; the SDK session\n // only deals in opaque session ids. Multiple entries per connectId coexist\n // (one per passphrase wallet), mirroring the device's session slots. Cleared\n // when the channel drops (sessions die with it) or a session is evicted.\n private readonly _appSessions = new Map<string, string>();\n\n private readonly _connectingPromises = new Map<string, Promise<string>>();\n\n private readonly _uiRegistry = new UiRequestRegistry();\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 private static _appSessionKey(connectId: string, passphraseState: string): string {\n return `${connectId}\u0000${passphraseState}`;\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 _splitPassphraseState(params: unknown): {\n passphraseState?: string;\n rest: unknown;\n } {\n if (params && typeof params === 'object' && 'passphraseState' in params) {\n const { passphraseState, ...rest } = params as Record<string, unknown>;\n return {\n passphraseState: typeof passphraseState === 'string' ? passphraseState : undefined,\n rest,\n };\n }\n return { rest: params };\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 _clearAppSessions(connectId: string): void {\n const prefix = `${connectId}\u0000`;\n for (const key of [...this._appSessions.keys()]) {\n if (key.startsWith(prefix)) this._appSessions.delete(key);\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 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._appSessions.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._appSessions.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(): Promise<DeviceInfo[]> {\n await this._ensureDevicePermission();\n const scanned = await this._connector.searchDevices();\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 this._clearAppSessions(connectId);\n if (!sessionId) return;\n await this._connector.disconnect(sessionId);\n this._sessions.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 deferred (multi-step\n // TronContractRequest flow + rawTxHex decoding needs device testing).\n return ['btc', 'evm', 'sol', 'tron'];\n }\n\n getFeatures(connectId: string): Promise<Response<Record<string, unknown>>> {\n return this._call<Record<string, unknown>>(connectId, 'getFeatures', {});\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 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(\n HardwareErrorCode.UnknownError,\n 'Trezor features did not include a device_id'\n );\n }\n return success(liveDeviceId);\n }\n\n /**\n * Resolve the active passphrase wallet identity (master fingerprint / XFP).\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 signal => this._resolvePassphraseState(connectId, passphraseState, signal),\n {\n label: 'getPassphraseState',\n rejectIfBusy: true,\n busyError: TrezorAdapter._createDeviceBusyError('getPassphraseState'),\n }\n )\n .catch(error => this._errorToFailure(error));\n }\n\n evmGetAddress(connectId: string, _deviceId: string, params: EvmGetAddressParams) {\n return this._call<EvmAddress>(connectId, 'evmGetAddress', params);\n }\n\n evmSignTransaction(connectId: string, _deviceId: string, params: EvmSignTxParams) {\n return this._call<EvmSignedTx>(connectId, 'evmSignTransaction', params);\n }\n\n evmSignMessage(connectId: string, _deviceId: string, params: EvmSignMsgParams) {\n return this._call<EvmSignature>(connectId, 'evmSignMessage', params);\n }\n\n evmSignTypedData(connectId: string, _deviceId: string, params: EvmSignTypedDataParams) {\n return this._call<EvmSignature>(connectId, 'evmSignTypedData', params);\n }\n\n btcGetAddress(connectId: string, _deviceId: string, params: BtcGetAddressParams) {\n return this._call<BtcAddress>(connectId, 'btcGetAddress', params);\n }\n\n btcGetPublicKey(connectId: string, _deviceId: string, params: BtcGetPublicKeyParams) {\n return this._call<BtcPublicKey>(connectId, 'btcGetPublicKey', params);\n }\n\n btcSignTransaction(connectId: string, _deviceId: string, params: BtcSignTxParams) {\n return this._call<BtcSignedTx>(connectId, 'btcSignTransaction', params);\n }\n\n btcSignPsbt(connectId: string, _deviceId: string, params: BtcSignPsbtParams) {\n return this._call<BtcSignedPsbt>(connectId, 'btcSignPsbt', params);\n }\n\n btcSignMessage(connectId: string, _deviceId: string, params: BtcSignMsgParams) {\n return this._call<BtcSignature>(connectId, 'btcSignMessage', params);\n }\n\n btcGetMasterFingerprint(connectId: string, _deviceId: string) {\n return this._call<{ masterFingerprint: string }>(connectId, 'btcGetMasterFingerprint', {});\n }\n\n solGetAddress(connectId: string, _deviceId: string, params: SolGetAddressParams) {\n return this._call<SolAddress>(connectId, 'solGetAddress', params);\n }\n\n solSignTransaction(connectId: string, _deviceId: string, params: SolSignTxParams) {\n return this._call<SolSignedTx>(connectId, 'solSignTransaction', params);\n }\n\n solSignMessage(connectId: string, _deviceId: string, params: SolSignMsgParams) {\n return this._call<SolSignature>(connectId, 'solSignMessage', params);\n }\n\n tronGetAddress(connectId: string, _deviceId: string, params: TronGetAddressParams) {\n return this._call<TronAddress>(connectId, 'tronGetAddress', params);\n }\n\n tronSignTransaction(connectId: string, _deviceId: string, params: TronSignTxParams) {\n return this._call<TronSignedTx>(connectId, 'tronSignTransaction', params);\n }\n\n tronSignMessage(connectId: string, _deviceId: string, params: TronSignMsgParams) {\n return this._call<TronSignature>(connectId, 'tronSignMessage', params);\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 async _call<T>(connectId: string, method: string, params: unknown): Promise<Response<T>> {\n try {\n return await this._jobQueue.enqueue(\n connectId,\n signal => this._callWithRetry<T>(connectId, method, params, true, signal),\n {\n label: method,\n rejectIfBusy: true,\n busyError: TrezorAdapter._createDeviceBusyError(method),\n },\n );\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 return this._errorToFailure(error);\n }\n }\n\n private async _callWithRetry<T>(\n connectId: string,\n method: string,\n params: unknown,\n allowRetry: boolean,\n signal: AbortSignal\n ): Promise<Response<T>> {\n const { passphraseState, rest } = TrezorAdapter._splitPassphraseState(params);\n try {\n const sessionId = await TrezorAdapter._abortable(signal, this._ensureSession(connectId));\n // Pin the call to the requested passphrase wallet (THP only; v1 is a\n // no-op handled reactively by the device). Runs inside this queued job so\n // the select and the call can't be interleaved by another request.\n if (passphraseState) {\n await TrezorAdapter._abortable(\n signal,\n this._alignAppSession(connectId, sessionId, passphraseState, signal)\n );\n }\n const result = await TrezorAdapter._abortable(\n signal,\n this._connector.call(sessionId, method, 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 = (error as { code?: HardwareErrorCode | string }).code;\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 // Application sessions live on the channel — a fresh channel has none.\n this._clearAppSessions(connectId);\n return this._callWithRetry<T>(connectId, method, params, false, signal);\n }\n // The device evicted the passphrase session we selected. Drop the stale\n // mapping and retry once — the cache miss recreates it (re-prompts) and\n // re-verifies the XFP before the call.\n if (allowRetry && passphraseState && TrezorAdapter._isStaleSessionError(code)) {\n this._appSessions.delete(TrezorAdapter._appSessionKey(connectId, passphraseState));\n return this._callWithRetry<T>(connectId, method, params, false, signal);\n }\n return this._errorToFailure(error);\n }\n }\n\n private async _ensureSession(connectId: string): 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 const session = await this._connector.connect(connectId);\n this._sessions.set(connectId, session.sessionId);\n this._devices.set(connectId, session.deviceInfo);\n return session.sessionId;\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 THP session to `passphraseState` (the target\n * wallet's XFP) before a wallet-bound op. THP only — v1 devices report\n * `protocol: 'v1'` and this is a no-op (reactive passphrase).\n *\n * SECURITY: the XFP is ALWAYS re-derived and confirmed — the cache only saves\n * re-entering the passphrase, NEVER the verification. So even a cache hit\n * re-derives: if the device evicted/replaced that session slot the XFP won't\n * match, and we drop it and recreate rather than ever operating on the wrong\n * wallet. A fresh create whose XFP doesn't match the claimed state (wrong\n * passphrase entered) fails with `PassphraseStateMismatch`. This makes the\n * safety independent of the device's (unverified) eviction error code.\n */\n private async _alignAppSession(\n connectId: string,\n sessionId: string,\n passphraseState: string,\n signal: AbortSignal\n ): Promise<void> {\n const key = TrezorAdapter._appSessionKey(connectId, passphraseState);\n const cached = this._appSessions.get(key);\n if (cached) {\n const selected = (await TrezorAdapter._abortable(\n signal,\n this._connector.call(sessionId, '__thpSelectSession', { thpSessionId: cached })\n )) as { protocol?: string };\n // v1 device — no host-managed sessions; nothing to pin.\n if (selected?.protocol !== 'thp') return;\n // Re-derive even on a hit — never trust the cached mapping for a\n // wallet-bound op. Match → done; otherwise the slot is stale, recreate.\n if ((await this._deriveState(sessionId, signal)) === passphraseState) return;\n this._appSessions.delete(key);\n }\n const created = (await TrezorAdapter._abortable(\n signal,\n this._connector.call(sessionId, '__thpCreateSession', {})\n )) as { protocol?: string; thpSessionId?: string | null };\n // v1 device — reactive passphrase, no session to cache.\n if (created?.protocol !== 'thp' || !created.thpSessionId) 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._appSessions.set(key, created.thpSessionId);\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 this._connector.call(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(\n 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 TrezorAdapter._abortable(signal, this._ensureSession(connectId));\n if (passphraseState) {\n // Verify mode: align (which always re-derives + confirms the XFP) 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 XFP. 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 → hidden wallet → cache + return its\n // XFP. Otherwise → standard wallet → return null (no XFP tracked).\n const created = (await TrezorAdapter._abortable(\n signal,\n this._connector.call(sessionId, '__thpCreateSession', {})\n )) as { protocol?: string; thpSessionId?: string | null };\n const state = await this._deriveState(sessionId, signal);\n const features = (await TrezorAdapter._abortable(\n signal,\n this._connector.call(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 if (created?.protocol === 'thp' && created.thpSessionId) {\n // Overwrites any stale entry for the same state (clears conflicts).\n this._appSessions.set(TrezorAdapter._appSessionKey(connectId, state), created.thpSessionId);\n }\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._clearAppSessions(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 _onUiRequest = (data: { type: string; payload?: unknown }): void => {\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-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-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(\n HardwareErrorCode.ThpPairingFailed,\n typed.message ?? 'THP pairing failed'\n );\n }\n const code =\n typeof typed.code === 'number' ? typed.code : 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","export const TREZOR_SAFE_7_MODEL = 'T3W1';\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\n","import { TREZOR_SAFE_7_MODEL } 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 isTrezorSafe7BleDescriptor(descriptor: TrezorBleDescriptor): boolean {\n return descriptor.model === TREZOR_SAFE_7_MODEL || isTrezorSafe7BleName(descriptor.name);\n}\n\nexport function resolveTrezorBleConnectId(descriptor: TrezorBleDescriptor): string {\n return descriptor.id ?? descriptor.path ?? descriptor.deviceId ?? descriptor.name ?? '';\n}\n\n"],"mappings":"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","names":[]}
package/dist/rn.mjs ADDED
@@ -0,0 +1,19 @@
1
+ import {
2
+ TREZOR_BLE_PACKET_SIZE,
3
+ TREZOR_BLE_UUIDS,
4
+ TREZOR_SAFE_7_MODEL,
5
+ TrezorAdapter,
6
+ isTrezorSafe7BleDescriptor,
7
+ isTrezorSafe7BleName,
8
+ resolveTrezorBleConnectId
9
+ } from "./chunk-QT23DMW5.mjs";
10
+ export {
11
+ TREZOR_BLE_PACKET_SIZE,
12
+ TREZOR_BLE_UUIDS,
13
+ TREZOR_SAFE_7_MODEL,
14
+ TrezorAdapter,
15
+ isTrezorSafe7BleDescriptor,
16
+ isTrezorSafe7BleName,
17
+ resolveTrezorBleConnectId
18
+ };
19
+ //# sourceMappingURL=rn.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@onekeyfe/hwk-trezor-adapter",
3
+ "version": "1.1.27-alpha.100",
4
+ "description": "Trezor hardware wallet adapter primitives for OneKey",
5
+ "author": "OneKey",
6
+ "license": "MIT",
7
+ "main": "dist/index.js",
8
+ "module": "dist/index.mjs",
9
+ "types": "dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "import": {
13
+ "types": "./dist/index.d.mts",
14
+ "default": "./dist/index.mjs"
15
+ },
16
+ "require": {
17
+ "types": "./dist/index.d.ts",
18
+ "default": "./dist/index.js"
19
+ }
20
+ },
21
+ "./rn": {
22
+ "import": {
23
+ "types": "./dist/rn.d.mts",
24
+ "default": "./dist/rn.mjs"
25
+ },
26
+ "require": {
27
+ "types": "./dist/rn.d.ts",
28
+ "default": "./dist/rn.js"
29
+ }
30
+ }
31
+ },
32
+ "files": [
33
+ "dist"
34
+ ],
35
+ "scripts": {
36
+ "build": "tsup",
37
+ "dev": "tsup --watch",
38
+ "clean": "rimraf dist",
39
+ "test": "jest"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/OneKeyHQ/hardware-js-sdk.git",
47
+ "directory": "packages/hwk-trezor-adapter"
48
+ },
49
+ "keywords": [
50
+ "trezor",
51
+ "hardware-wallet",
52
+ "onekey",
53
+ "crypto"
54
+ ],
55
+ "dependencies": {
56
+ "@onekeyfe/hwk-adapter-core": "1.1.27-alpha.100",
57
+ "@onekeyfe/hwk-trezor-core": "1.1.27-alpha.100",
58
+ "tslib": "^2.6.2"
59
+ },
60
+ "devDependencies": {
61
+ "rimraf": "^5.0.0",
62
+ "tsup": "^8.0.0",
63
+ "typescript": "5.1.6"
64
+ },
65
+ "gitHead": "d67fe1a72b9fce9755ecb96172311c7e29738e95"
66
+ }