@onekeyfe/hwk-ledger-adapter 1.1.26-alpha.7 → 1.1.26-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/adapter/LedgerAdapter.ts","../src/errors.ts","../src/utils/debugLog.ts","../src/device/LedgerDeviceManager.ts","../src/signer/SignerManager.ts","../src/signer/SignerEth.ts","../src/signer/deviceActionToPromise.ts","../src/connector/chains/evm.ts","../src/connector/chains/utils.ts","../src/connector/chains/btc.ts","../src/signer/SignerBtc.ts","../src/connector/chains/sol.ts","../src/signer/SignerSol.ts","../src/connector/chains/tron.ts","../src/connector/chains/legacyAppRetry.ts","../src/app/AppManager.ts","../src/transport/DmkTransport.ts","../src/connector/LedgerConnectorBase.ts","../src/utils/bleIdentity.ts"],"sourcesContent":["// Adapter\nexport { LedgerAdapter } from './adapter/LedgerAdapter';\n\n// Connector base class (used by connector packages)\nexport { LedgerConnectorBase } from './connector/LedgerConnectorBase';\nexport type { TransportFactory, LedgerConnectorBaseOptions } from './connector/LedgerConnectorBase';\n\n// Device management (used by connectors)\nexport { LedgerDeviceManager } from './device/LedgerDeviceManager';\n\n// Signer (used by connectors)\nexport { SignerManager } from './signer/SignerManager';\nexport { SignerEth } from './signer/SignerEth';\nexport { SignerBtc } from './signer/SignerBtc';\nexport { SignerSol } from './signer/SignerSol';\nexport { DmkTransport } from './transport/DmkTransport';\nexport { deviceActionToPromise } from './signer/deviceActionToPromise';\n\n// App management\nexport { AppManager } from './app/AppManager';\n\n// Types\nexport type {\n DmkDiscoveredDevice,\n DeviceActionState,\n SignerEvmAddress,\n SignerEvmSignature,\n SignerBtcAddress,\n} from './types';\n\n// Errors\nexport { isDeviceLockedError, ledgerFailure, mapLedgerError } from './errors';\nexport type { LedgerFailure } from './errors';\n\n// Debug logging (opt-in)\nexport { setDebugEnabled, isDebugEnabled } from './utils/debugLog';\n\n// BLE utilities (shared by connector packages)\nexport { extractBleHexId } from './utils/bleIdentity';\n","import {\n CHAIN_FINGERPRINT_PATHS,\n DEVICE,\n DeviceJobQueue,\n HardwareErrorCode,\n TypedEventEmitter,\n UI_REQUEST,\n UiRequestRegistry,\n deriveDeviceFingerprint,\n failure,\n success,\n} from '@onekeyfe/hwk-adapter-core';\n\nimport {\n isDeviceDisconnectedError,\n isDeviceLockedError,\n isTimeoutError,\n ledgerFailure,\n mapLedgerError,\n} from '../errors';\nimport { debugError, debugLog } from '../utils/debugLog';\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 ConnectionType,\n ConnectorDevice,\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 Interruptibility,\n ProgressCallback,\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';\n\nexport interface LedgerAdapterOptions {\n /**\n * `true` — emit `REQUEST_SELECT_DEVICE` on multi-device discovery and await\n * `uiResponse({ type: RECEIVE_SELECT_DEVICE, payload: { sdkConnectId } })`.\n * `false` (default) — silently pick the first device.\n */\n handleSelectDevice?: boolean;\n}\n\n/**\n * Result of `_verifyDeviceFingerprint`.\n *\n * On mismatch carries both the stored (expected) fingerprint and the\n * live (actual) one derived from the physically connected device.\n * Callers turn this into a `DeviceMismatch` failure via `formatDeviceMismatchError`.\n */\ntype IFingerprintVerifyResult =\n | { success: true }\n | { success: false; expected: string; actual: string };\n\n/**\n * Single source of truth for the `DeviceMismatch` error message.\n * Both fingerprints are 16-char deterministic hashes of fixed-path\n * testnet addresses — not secrets — so they're safe to surface in logs.\n */\nfunction formatDeviceMismatchError(expected: string, actual: string): string {\n return `Wrong device: expected ${expected}, got ${actual}`;\n}\n\n/**\n * Ledger hardware wallet adapter that delegates to an IConnector.\n *\n * This is a thin translation layer that:\n * - Accepts a pre-configured IConnector (transport decisions are made at connector creation time)\n * - Translates IHardwareWallet method calls to connector.call() invocations\n * - Maps connector results/errors to our Response<T> format with enriched error messages\n * - Translates connector events to HardwareEventMap events\n * - Emits `REQUEST_DEVICE_PERMISSION` for OS-level permission checks\n */\nexport class LedgerAdapter implements IHardwareWallet {\n readonly vendor = 'ledger' as const;\n\n private readonly connector: IConnector;\n\n private readonly emitter = new TypedEventEmitter<HardwareEventMap>();\n\n private readonly _handleSelectDevice: boolean;\n\n // Device cache: tracks discovered devices from connector events\n private _discoveredDevices = new Map<string, DeviceInfo>();\n\n // Session tracking: maps connectId -> sessionId\n private _sessions = new Map<string, string>();\n\n private readonly _uiRegistry = new UiRequestRegistry();\n\n // Per-device serial job queue. Operations for the same device run sequentially;\n // conflicting ops are dispatched per `interruptibility` (see _getInterruptibility).\n private readonly _jobQueue: DeviceJobQueue;\n\n constructor(connector: IConnector, options?: LedgerAdapterOptions) {\n this.connector = connector;\n this._handleSelectDevice = options?.handleSelectDevice ?? false;\n this._jobQueue = new DeviceJobQueue({\n emit: (event, data) => this.emitter.emit(event, data),\n uiRegistry: this._uiRegistry,\n });\n this.registerEventListeners();\n }\n\n /**\n * Classify a method's interruptibility.\n * - Signing / typed data / transaction → 'confirm' (user may decide via preemption UI)\n * - Read-only queries (getAddress / getPublicKey / getMasterFingerprint) → 'safe'\n * (auto-cancels any pending read for the same device)\n */\n private static _getInterruptibility(method: string): Interruptibility {\n if (method.toLowerCase().includes('sign')) return 'confirm';\n return 'safe';\n }\n\n // ---------------------------------------------------------------------------\n // Transport\n // ---------------------------------------------------------------------------\n // Transport is decided at connector creation time. These methods\n // satisfy the IHardwareWallet interface with sensible defaults.\n\n get activeTransport(): TransportType | null {\n // Ledger all-current-models use USB-HID for wired connection.\n return this.connector.connectionType === 'ble' ? 'ble' : 'hid';\n }\n\n getAvailableTransports(): TransportType[] {\n return this.activeTransport ? [this.activeTransport] : [];\n }\n\n async switchTransport(_type: TransportType): Promise<void> {\n // Ledger binds a single connector (transport) at construction time.\n // To use a different transport, create a new adapter with a different connector.\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n async init(_config?: unknown): Promise<void> {\n // Connector is injected via constructor, already initialized.\n // Nothing to do here.\n }\n\n /**\n * Clear cached device/session state without tearing down the adapter.\n * Call before retrying after errors or when the device state may be stale.\n * The next operation will re-discover and re-connect automatically.\n */\n resetState(): void {\n this._discoveredDevices.clear();\n this._sessions.clear();\n this._connectingPromise = null;\n this._uiRegistry.reset();\n this._jobQueue.clear();\n }\n\n async dispose(): Promise<void> {\n this._uiRegistry.reset();\n this._jobQueue.clear();\n this.unregisterEventListeners();\n this.connector.reset();\n this._discoveredDevices.clear();\n this._sessions.clear();\n this.emitter.removeAllListeners();\n }\n\n uiResponse(response: UiResponseEvent): void {\n this._uiRegistry.resolve(response.type, response.payload);\n }\n\n // ---------------------------------------------------------------------------\n // Device management\n // ---------------------------------------------------------------------------\n\n async searchDevices(): Promise<DeviceInfo[]> {\n await this._ensureDevicePermission();\n\n const devices = await this.connector.searchDevices();\n debugLog('[DMK] adapter.searchDevices raw:', JSON.stringify(devices));\n\n // Update cache with scan results. connectId is now consistent\n // (BLE: \"A58F\" from _resolveConnectId, USB: DMK path) across all write points.\n for (const d of devices) {\n if (d.connectId) {\n this._discoveredDevices.set(d.connectId, this.connectorDeviceToDeviceInfo(d));\n }\n }\n\n // If no devices found, ensure permission (no connectId = search context)\n if (this._discoveredDevices.size === 0) {\n await this._ensureDevicePermission();\n }\n\n return Array.from(this._discoveredDevices.values());\n }\n\n async connectDevice(connectId: string): Promise<Response<string>> {\n await this._ensureDevicePermission(connectId);\n try {\n const session = await this.connector.connect(connectId);\n this._sessions.set(connectId, session.sessionId);\n\n // Update device cache with richer info from session\n if (session.deviceInfo) {\n this._discoveredDevices.set(connectId, session.deviceInfo);\n }\n\n return success(connectId);\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async disconnectDevice(connectId: string): Promise<void> {\n const sessionId = this._sessions.get(connectId);\n if (sessionId) {\n await this.connector.disconnect(sessionId);\n this._sessions.delete(connectId);\n }\n }\n\n async getDeviceInfo(connectId: string, deviceId: string): Promise<Response<DeviceInfo>> {\n await this._ensureDevicePermission(connectId, deviceId);\n\n // Look up the device in the cache populated by event handlers / searchDevices.\n // Try connectId first (the USB path), then fall back to scanning by deviceId.\n const cached =\n this._discoveredDevices.get(connectId) ??\n Array.from(this._discoveredDevices.values()).find(d => d.deviceId === deviceId);\n\n if (cached) {\n return success(cached);\n }\n\n return failure(\n HardwareErrorCode.DeviceNotFound,\n 'Device not found in cache. Call searchDevices() or wait for a device-connected event first.'\n );\n }\n\n getSupportedChains(): ChainCapability[] {\n return ['evm', 'btc', 'sol', 'tron'];\n }\n\n // ---------------------------------------------------------------------------\n // Chain call helper\n // ---------------------------------------------------------------------------\n\n private async callChain<T>(\n connectId: string,\n deviceId: string,\n chain: string,\n method: string,\n params: unknown,\n skipFingerprint = false\n ): Promise<Response<T>> {\n await this._ensureDevicePermission(connectId, deviceId);\n try {\n const result = await this.connectorCall(connectId, method, params, {\n chain: chain as ChainForFingerprint,\n deviceId,\n skipFingerprint,\n });\n return success(result as T);\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n /**\n * Batch version of callChain — checks permission once,\n * fingerprint is verified on the first call inside connectorCall.\n */\n private async callChainBatch<TParam, TResult>(\n connectId: string,\n deviceId: string,\n chain: string,\n method: string,\n params: TParam[],\n onProgress?: ProgressCallback,\n skipFingerprint = false\n ): Promise<Response<TResult[]>> {\n await this._ensureDevicePermission(connectId, deviceId);\n const results: TResult[] = [];\n for (let i = 0; i < params.length; i++) {\n try {\n const result = await this.connectorCall(connectId, method, params[i], {\n chain: chain as ChainForFingerprint,\n deviceId,\n // Only verify fingerprint on the first call in the batch\n skipFingerprint: skipFingerprint || i > 0,\n });\n results.push(result as TResult);\n onProgress?.({ index: i, total: params.length });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n return success(results);\n }\n\n // ---------------------------------------------------------------------------\n // EVM chain methods\n // ---------------------------------------------------------------------------\n\n evmGetAddress(connectId: string, deviceId: string, params: EvmGetAddressParams) {\n return this.callChain<EvmAddress>(connectId, deviceId, 'evm', 'evmGetAddress', params);\n }\n\n evmGetAddresses(\n connectId: string,\n deviceId: string,\n params: EvmGetAddressParams[],\n onProgress?: ProgressCallback\n ) {\n return this.callChainBatch<EvmGetAddressParams, EvmAddress>(\n connectId,\n deviceId,\n 'evm',\n 'evmGetAddress',\n params,\n onProgress\n );\n }\n\n evmSignTransaction(connectId: string, deviceId: string, params: EvmSignTxParams) {\n return this.callChain<EvmSignedTx>(connectId, deviceId, 'evm', 'evmSignTransaction', params);\n }\n\n evmSignMessage(connectId: string, deviceId: string, params: EvmSignMsgParams) {\n return this.callChain<EvmSignature>(connectId, deviceId, 'evm', 'evmSignMessage', params);\n }\n\n evmSignTypedData(connectId: string, deviceId: string, params: EvmSignTypedDataParams) {\n return this.callChain<EvmSignature>(connectId, deviceId, 'evm', 'evmSignTypedData', params);\n }\n\n // ---------------------------------------------------------------------------\n // BTC chain methods\n // ---------------------------------------------------------------------------\n\n btcGetAddress(connectId: string, deviceId: string, params: BtcGetAddressParams) {\n return this.callChain<BtcAddress>(connectId, deviceId, 'btc', 'btcGetAddress', params);\n }\n\n btcGetAddresses(\n connectId: string,\n deviceId: string,\n params: BtcGetAddressParams[],\n onProgress?: ProgressCallback\n ) {\n return this.callChainBatch<BtcGetAddressParams, BtcAddress>(\n connectId,\n deviceId,\n 'btc',\n 'btcGetAddress',\n params,\n onProgress\n );\n }\n\n btcGetPublicKey(connectId: string, deviceId: string, params: BtcGetPublicKeyParams) {\n return this.callChain<BtcPublicKey>(connectId, deviceId, 'btc', 'btcGetPublicKey', params);\n }\n\n btcSignTransaction(connectId: string, deviceId: string, params: BtcSignTxParams) {\n return this.callChain<BtcSignedTx>(connectId, deviceId, 'btc', 'btcSignTransaction', params);\n }\n\n btcSignPsbt(connectId: string, deviceId: string, params: BtcSignPsbtParams) {\n return this.callChain<BtcSignedPsbt>(connectId, deviceId, 'btc', 'btcSignPsbt', params);\n }\n\n btcSignMessage(connectId: string, deviceId: string, params: BtcSignMsgParams) {\n return this.callChain<BtcSignature>(connectId, deviceId, 'btc', 'btcSignMessage', params);\n }\n\n btcGetMasterFingerprint(connectId: string, deviceId: string) {\n return this.callChain<{ masterFingerprint: string }>(\n connectId,\n deviceId,\n 'btc',\n 'btcGetMasterFingerprint',\n {}\n );\n }\n\n // ---------------------------------------------------------------------------\n // SOL chain methods\n // ---------------------------------------------------------------------------\n\n solGetAddress(connectId: string, deviceId: string, params: SolGetAddressParams) {\n return this.callChain<SolAddress>(connectId, deviceId, 'sol', 'solGetAddress', params);\n }\n\n solGetAddresses(\n connectId: string,\n deviceId: string,\n params: SolGetAddressParams[],\n onProgress?: ProgressCallback\n ) {\n return this.callChainBatch<SolGetAddressParams, SolAddress>(\n connectId,\n deviceId,\n 'sol',\n 'solGetAddress',\n params,\n onProgress\n );\n }\n\n solSignTransaction(connectId: string, deviceId: string, params: SolSignTxParams) {\n return this.callChain<SolSignedTx>(connectId, deviceId, 'sol', 'solSignTransaction', params);\n }\n\n solSignMessage(connectId: string, deviceId: string, params: SolSignMsgParams) {\n return this.callChain<SolSignature>(connectId, deviceId, 'sol', 'solSignMessage', params);\n }\n\n // ---------------------------------------------------------------------------\n // TRON chain methods\n // ---------------------------------------------------------------------------\n\n tronGetAddress(connectId: string, deviceId: string, params: TronGetAddressParams) {\n return this.callChain<TronAddress>(connectId, deviceId, 'tron', 'tronGetAddress', params, true);\n }\n\n tronGetAddresses(\n connectId: string,\n deviceId: string,\n params: TronGetAddressParams[],\n onProgress?: ProgressCallback\n ) {\n return this.callChainBatch<TronGetAddressParams, TronAddress>(\n connectId,\n deviceId,\n 'tron',\n 'tronGetAddress',\n params,\n onProgress,\n true\n );\n }\n\n tronSignTransaction(connectId: string, deviceId: string, params: TronSignTxParams) {\n return this.callChain<TronSignedTx>(\n connectId,\n deviceId,\n 'tron',\n 'tronSignTransaction',\n params,\n true\n );\n }\n\n tronSignMessage(connectId: string, deviceId: string, params: TronSignMsgParams) {\n return this.callChain<TronSignature>(\n connectId,\n deviceId,\n 'tron',\n 'tronSignMessage',\n params,\n true\n );\n }\n\n // ---------------------------------------------------------------------------\n // Events\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 cancel(connectId: string): void {\n const sessionId = this._sessions.get(connectId) ?? connectId;\n // Force-cancel the active job so in-flight signer work aborts even if it's\n // marked non-interruptible; queue.clear would kill queued follow-ups too.\n this._jobQueue.forceCancelActive(connectId || '__ledger_default__');\n void this.connector.cancel(sessionId);\n }\n\n // ---------------------------------------------------------------------------\n // Chain fingerprint\n // ---------------------------------------------------------------------------\n\n async getChainFingerprint(\n connectId: string,\n deviceId: string,\n chain: ChainForFingerprint\n ): Promise<Response<string>> {\n debugLog(\n '[LedgerAdapter] getChainFingerprint called, chain:',\n chain,\n 'connectId:',\n connectId || '(empty)',\n 'sessions:',\n this._sessions.size\n );\n await this._ensureDevicePermission(connectId, deviceId);\n debugLog('[LedgerAdapter] getChainFingerprint permission ok, computing fingerprint');\n try {\n const fingerprint = await this._computeChainFingerprint(chain, (method, params) =>\n this.connectorCall(connectId, method, params)\n );\n debugLog('[LedgerAdapter] getChainFingerprint result:', fingerprint?.substring(0, 20));\n return success(fingerprint);\n } catch (err) {\n debugError('[LedgerAdapter] getChainFingerprint error:', chain, err);\n return this.errorToFailure(err);\n }\n }\n\n /**\n * Verify fingerprint using an existing sessionId directly.\n * Safe to call inside connectorCall without causing queue deadlock.\n */\n private async _verifyDeviceFingerprintWithSession(\n sessionId: string,\n deviceId: string,\n chain: ChainForFingerprint\n ): Promise<IFingerprintVerifyResult> {\n if (!deviceId) return { success: true };\n\n try {\n const fingerprint = await this._computeChainFingerprint(chain, (method, params) =>\n this.connector.call(sessionId, method, params)\n );\n if (fingerprint === deviceId) {\n return { success: true };\n }\n return { success: false, expected: deviceId, actual: fingerprint };\n } catch (err) {\n const mapped = mapLedgerError(err);\n if (\n mapped.code === HardwareErrorCode.WrongApp ||\n mapped.code === HardwareErrorCode.DeviceLocked\n ) {\n return { success: true };\n }\n throw err;\n }\n }\n\n /**\n * Compute the chain fingerprint via a caller-supplied call strategy.\n *\n * Chains with a native device-side identity primitive (BTC → BIP32 master\n * fingerprint) short-circuit at the top and return it verbatim, so the value\n * stays reusable for higher-level use (BIP380 descriptors, PSBT signing).\n *\n * All other chains derive a fixed-path address and run it through\n * `deriveDeviceFingerprint` to produce an opaque seed identifier.\n *\n * The two callers (`getChainFingerprint` / `_verifyDeviceFingerprintWithSession`)\n * differ only in the underlying call mechanism, which is injected as `callMethod`\n * to avoid queue deadlocks when running inside `connectorCall`.\n */\n private async _computeChainFingerprint(\n chain: ChainForFingerprint,\n callMethod: (method: string, params: unknown) => Promise<unknown>\n ): Promise<string> {\n // BTC: dedicated device call returns the BIP32 master fingerprint already\n // in the canonical 8-hex form — no further hashing.\n if (chain === 'btc') {\n const result = (await callMethod('btcGetMasterFingerprint', {})) as {\n masterFingerprint: string;\n };\n return result.masterFingerprint;\n }\n\n const path = CHAIN_FINGERPRINT_PATHS[chain];\n let address: string;\n if (chain === 'evm') {\n // Lowercase per deriveDeviceFingerprint's canonical-form contract.\n address = (\n (await callMethod('evmGetAddress', { path, showOnDevice: false })) as {\n address: string;\n }\n ).address.toLowerCase();\n } else if (chain === 'sol') {\n address = (\n (await callMethod('solGetAddress', { path, showOnDevice: false })) as {\n address: string;\n }\n ).address;\n } else if (chain === 'tron') {\n address = (\n (await callMethod('tronGetAddress', { path, showOnDevice: false })) as {\n address: string;\n }\n ).address;\n } else {\n throw new Error(`Unsupported chain for fingerprint: ${chain as string}`);\n }\n\n return deriveDeviceFingerprint(address);\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Ensure at least one device is connected and return a valid connectId.\n *\n * - If a session already exists for the given connectId, reuse it.\n * - If ANY session exists (Ledger IDs are ephemeral), reuse it.\n * - Otherwise: search → 1 device: auto-connect, multiple: ask user, 0: throw.\n */\n private static readonly MAX_DEVICE_RETRY = 3;\n\n // Mutex for ensureConnected — prevents concurrent calls from establishing duplicate connections\n private _connectingPromise: Promise<string> | null = null;\n\n // Ledger WebUSB won't expose a locked device, so we can't auto-detect unlock.\n // The user must press Confirm after unlocking, which triggers a search retry.\n // If `signal` is provided, an abort cancels the pending UI request so the\n // registry slot is released and a stale RECEIVE_DEVICE_CONNECT won't land in\n // a future request.\n private async _waitForDeviceConnect(signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) {\n LedgerAdapter._throwIfAborted(signal);\n }\n\n this.emitter.emit(UI_REQUEST.REQUEST_DEVICE_CONNECT, {\n type: UI_REQUEST.REQUEST_DEVICE_CONNECT,\n payload: {\n message: 'Please connect and unlock your Ledger device',\n },\n });\n\n const waitPromise = this._uiRegistry.wait<{ confirmed: boolean }>(\n UI_REQUEST.REQUEST_DEVICE_CONNECT\n );\n\n let payload: { confirmed: boolean } | undefined;\n if (signal) {\n const onAbort = () => {\n this._uiRegistry.cancel(UI_REQUEST.REQUEST_DEVICE_CONNECT);\n };\n signal.addEventListener('abort', onAbort, { once: true });\n try {\n payload = await waitPromise;\n } finally {\n signal.removeEventListener('abort', onAbort);\n }\n } else {\n payload = await waitPromise;\n }\n\n if (!payload?.confirmed) {\n throw Object.assign(new Error('User cancelled Ledger connection'), {\n _tag: 'DeviceNotRecognizedError',\n });\n }\n }\n\n private async ensureConnected(connectId?: string): Promise<string> {\n // 1. Exact match — no mutex needed\n if (connectId && this._sessions.has(connectId)) {\n return connectId;\n }\n\n // 2. Any existing session (Ledger IDs are temporary, any session is fine)\n if (this._sessions.size > 0) {\n // size > 0 guarantees .next().value is defined\n const firstKey = this._sessions.keys().next().value as string;\n return firstKey;\n }\n\n // 3. No session — use mutex to prevent concurrent connection attempts\n if (this._connectingPromise) {\n return this._connectingPromise;\n }\n\n this._connectingPromise = this._doConnect();\n try {\n return await this._connectingPromise;\n } finally {\n this._connectingPromise = null;\n }\n }\n\n private async _doConnect(): Promise<string> {\n for (let attempt = 0; attempt < LedgerAdapter.MAX_DEVICE_RETRY; attempt++) {\n const devices = await this.searchDevices();\n\n if (devices.length > 0) {\n // Found device(s), continue to connection below\n return this._connectFirstOrSelect(devices);\n }\n\n // No device found — prompt user (except on last attempt)\n if (attempt < LedgerAdapter.MAX_DEVICE_RETRY - 1) {\n await this._waitForDeviceConnect();\n }\n }\n\n throw Object.assign(\n new Error(\n 'No Ledger device found after multiple attempts. Please connect and unlock your device.'\n ),\n { _tag: 'DeviceNotRecognizedError' }\n );\n }\n\n private async _connectFirstOrSelect(devices: DeviceInfo[]): Promise<string> {\n const chosenConnectId =\n devices.length === 1 ? devices[0].connectId : await this._chooseDeviceFromList(devices);\n\n const result = await this.connectDevice(chosenConnectId);\n if (!result.success) {\n throw Object.assign(new Error(result.payload.error), {\n _tag: 'DeviceNotRecognizedError',\n });\n }\n return chosenConnectId;\n }\n\n private async _chooseDeviceFromList(devices: DeviceInfo[]): Promise<string> {\n if (!this._handleSelectDevice) {\n debugLog(\n `[DMK] Multiple Ledger devices found (${devices.length}); handleSelectDevice=false, picking first (${devices[0].connectId}).`\n );\n return devices[0].connectId;\n }\n\n this.emitter.emit(UI_REQUEST.REQUEST_SELECT_DEVICE, {\n type: UI_REQUEST.REQUEST_SELECT_DEVICE,\n payload: { devices },\n });\n\n const response = await this._uiRegistry.wait<{ sdkConnectId: string }>(\n UI_REQUEST.REQUEST_SELECT_DEVICE\n );\n\n const chosen = devices.find(d => d.connectId === response?.sdkConnectId);\n if (!chosen) {\n throw Object.assign(\n new Error(`Selected sdkConnectId '${response?.sdkConnectId}' not in discovered list`),\n { _tag: 'DeviceNotRecognizedError' }\n );\n }\n return chosen.connectId;\n }\n\n /**\n * Call the connector with automatic session resolution and disconnect retry.\n *\n * 1. Resolves a valid connectId via ensureConnected()\n * 2. Looks up sessionId from _sessions\n * 3. Calls connector.call()\n * 4. On disconnect error: clears stale session, re-connects, retries once\n */\n private async connectorCall(\n connectId: string,\n method: string,\n params: unknown,\n fingerprint?: {\n chain: ChainForFingerprint;\n deviceId: string;\n skipFingerprint: boolean;\n }\n ): Promise<unknown> {\n debugLog('[LedgerAdapter] connectorCall:', method, 'connectId:', connectId || '(empty)');\n\n // Queue key: prefer the supplied connectId; fall back to a shared bucket so that\n // calls made before any session exists still serialize (Ledger only has one active device).\n const queueKey = connectId || '__ledger_default__';\n const interruptibility = LedgerAdapter._getInterruptibility(method);\n\n return this._jobQueue.enqueue(\n queueKey,\n async signal => this._runConnectorCall(connectId, method, params, signal, fingerprint),\n { interruptibility, label: method }\n );\n }\n\n /**\n * Race a promise against an abort signal. If the signal fires, rejects with the\n * signal's reason (or a generic Error). The underlying connector.call() cannot\n * actually be cancelled on Ledger DMK, but the caller gets the abort immediately.\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 /** Throw an AbortError if signal is already aborted. */\n private static _throwIfAborted(signal: AbortSignal): void {\n if (signal.aborted) {\n throw (signal as AbortSignal & { reason?: unknown }).reason ?? new Error('Aborted');\n }\n }\n\n /** Actual work done under the job queue — connection, fingerprint, call, and recovery. */\n private async _runConnectorCall(\n connectId: string,\n method: string,\n params: unknown,\n signal: AbortSignal,\n fingerprint?: {\n chain: ChainForFingerprint;\n deviceId: string;\n skipFingerprint: boolean;\n }\n ): Promise<unknown> {\n LedgerAdapter._throwIfAborted(signal);\n // Wrap ensureConnected in _abortable so an abort during device discovery /\n // user-connect UI wait rejects this caller immediately. The underlying\n // _doConnect / _connectingPromise is shared across callers and continues\n // running — other concurrent callers aren't affected.\n const resolvedConnectId = await LedgerAdapter._abortable(\n signal,\n this.ensureConnected(connectId)\n );\n LedgerAdapter._throwIfAborted(signal);\n const sessionId = this._sessions.get(resolvedConnectId);\n debugLog(\n '[LedgerAdapter] connectorCall resolved:',\n method,\n 'resolvedConnectId:',\n resolvedConnectId,\n 'sessionId:',\n sessionId\n );\n if (!sessionId) {\n throw Object.assign(new Error('Auto-connect succeeded but no session found'), {\n _tag: 'DeviceSessionNotFound',\n });\n }\n\n // Fingerprint verification inside the session — atomic with the actual call\n if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId) {\n const fp = await LedgerAdapter._abortable(\n signal,\n this._verifyDeviceFingerprintWithSession(sessionId, fingerprint.deviceId, fingerprint.chain)\n );\n if (!fp.success) {\n throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {\n code: HardwareErrorCode.DeviceMismatch,\n });\n }\n }\n\n try {\n return await LedgerAdapter._abortable(signal, this.connector.call(sessionId, method, params));\n } catch (err) {\n // If the abort fired, surface it directly — skip recovery paths.\n if (signal.aborted) throw err;\n const errObj = err as Record<string, unknown> | null | undefined;\n debugLog('[LedgerAdapter] connectorCall error:', method, {\n message: errObj?.message,\n _tag: errObj?._tag,\n errorCode: errObj?.errorCode,\n statusCode: errObj?.statusCode,\n isDisconnected: isDeviceDisconnectedError(err),\n isLocked: isDeviceLockedError(err),\n });\n if (isDeviceDisconnectedError(err)) {\n debugLog('[LedgerAdapter] disconnected, retrying with fresh connection...');\n this._discoveredDevices.clear();\n return this._retryWithFreshConnection(resolvedConnectId, method, params, signal, err);\n }\n if (isDeviceLockedError(err)) {\n await this._waitForDeviceConnect(signal);\n LedgerAdapter._throwIfAborted(signal);\n return LedgerAdapter._abortable(signal, this.connector.call(sessionId, method, params));\n }\n if (isTimeoutError(err)) {\n debugLog('[LedgerAdapter] timeout, retrying with fresh connection...');\n this._discoveredDevices.delete(resolvedConnectId);\n return this._retryWithFreshConnection(resolvedConnectId, method, params, signal, err);\n }\n throw err;\n }\n }\n\n /** Clear stale session, reconnect, and retry the call. */\n private async _retryWithFreshConnection(\n resolvedConnectId: string,\n method: string,\n params: unknown,\n signal: AbortSignal,\n originalErr: unknown\n ): Promise<unknown> {\n this._sessions.delete(resolvedConnectId);\n LedgerAdapter._throwIfAborted(signal);\n const retryConnectId = await this.ensureConnected();\n LedgerAdapter._throwIfAborted(signal);\n const retrySessionId = this._sessions.get(retryConnectId);\n if (!retrySessionId) {\n throw originalErr;\n }\n return LedgerAdapter._abortable(signal, this.connector.call(retrySessionId, method, params));\n }\n\n /**\n * Ensure OS-level device permission (Bluetooth / USB) before proceeding.\n *\n * Emits `REQUEST_DEVICE_PERMISSION` and awaits the consumer's\n * `RECEIVE_DEVICE_PERMISSION` reply (60s budget covers \"probe → system\n * prompt → user tap\" plus a generous margin). If the consumer never wires\n * a handler or never replies, the wait times out and the operation fails\n * fast so scanners/callers don't hang silently.\n *\n * - No connectId (searchDevices): environment-level permission\n * - With connectId (business methods): device-level permission\n */\n private async _ensureDevicePermission(connectId?: string, deviceId?: string): Promise<void> {\n const transportType: TransportType = this.activeTransport ?? 'hid';\n\n // Register the wait before emitting — a synchronous listener that replies\n // immediately (e.g. in tests or a same-process consumer) would otherwise\n // resolve before any pending entry exists and the response would drop.\n const waitPromise = this._uiRegistry.wait<{ granted: boolean }>(\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\n if (!granted) {\n throw Object.assign(new Error('Device permission denied'), {\n code: HardwareErrorCode.DevicePermissionDenied,\n });\n }\n }\n\n /**\n * Convert a thrown error to a Response failure.\n * Uses mapLedgerError to parse Ledger DMK error codes into HardwareErrorCode values.\n */\n private errorToFailure<T>(err: unknown): Response<T> {\n debugError('[LedgerAdapter] error:', err);\n\n // If the error carries an explicit HardwareErrorCode (e.g. validation errors\n // thrown by connector chain methods), use it directly.\n if (\n err &&\n typeof err === 'object' &&\n 'code' in err &&\n typeof (err as { code: unknown }).code === 'number'\n ) {\n const e = err as { code: number; message?: string; appName?: string };\n return ledgerFailure(e.code, e.message ?? 'Unknown error', e.appName);\n }\n\n const mapped = mapLedgerError(err);\n\n // DeviceLocked is handled by connectorCall retry logic (_waitForDeviceConnect).\n // Do NOT emit UI events here — it would show UI and return error simultaneously.\n\n return ledgerFailure(mapped.code, mapped.message, mapped.appName);\n }\n\n // ---------------------------------------------------------------------------\n // Event translation\n // ---------------------------------------------------------------------------\n\n private deviceConnectHandler = (data: { device: ConnectorDevice }): void => {\n const deviceInfo = this.connectorDeviceToDeviceInfo(data.device);\n this._discoveredDevices.set(deviceInfo.connectId, deviceInfo);\n // Clear any stale session for this connectId so ensureConnected() does a fresh connect.\n // This handles the case where the connector reconnected internally (e.g. TRON app switch).\n this._sessions.delete(deviceInfo.connectId);\n this.emitter.emit(DEVICE.CONNECT, {\n type: DEVICE.CONNECT,\n payload: deviceInfo,\n });\n };\n\n private deviceDisconnectHandler = (data: { connectId: string }): void => {\n this._discoveredDevices.delete(data.connectId);\n this._sessions.delete(data.connectId);\n this.emitter.emit(DEVICE.DISCONNECT, {\n type: DEVICE.DISCONNECT,\n payload: { connectId: data.connectId },\n });\n };\n\n private uiRequestHandler = (data: { type: string; payload?: unknown }): void => {\n this.handleUiEvent(data);\n };\n\n private uiEventHandler = (data: { type: string; payload?: unknown }): void => {\n this.handleUiEvent(data);\n };\n\n private registerEventListeners(): void {\n this.connector.on('device-connect', this.deviceConnectHandler);\n this.connector.on('device-disconnect', this.deviceDisconnectHandler);\n this.connector.on('ui-request', this.uiRequestHandler);\n this.connector.on('ui-event', this.uiEventHandler);\n }\n\n private unregisterEventListeners(): void {\n this.connector.off('device-connect', this.deviceConnectHandler);\n this.connector.off('device-disconnect', this.deviceDisconnectHandler);\n this.connector.off('ui-request', this.uiRequestHandler);\n this.connector.off('ui-event', this.uiEventHandler);\n }\n\n private handleUiEvent(event: { type: string; payload?: unknown }): void {\n if (!event.type) return;\n\n const payload = event.payload as Record<string, unknown> | undefined;\n const deviceInfo = payload ? this.extractDeviceInfoFromPayload(payload) : this.unknownDevice();\n\n switch (event.type) {\n case 'ui-request_confirmation':\n this.emitter.emit(UI_REQUEST.REQUEST_BUTTON, {\n type: UI_REQUEST.REQUEST_BUTTON,\n payload: { device: deviceInfo },\n });\n break;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Device info mapping\n // ---------------------------------------------------------------------------\n\n private connectorDeviceToDeviceInfo(device: ConnectorDevice): DeviceInfo {\n // BLE connectId is a stable 4-digit HEX (e.g. \"A58F\") from device name.\n // USB connectId is an ephemeral UUID. Use this to infer connectionType.\n const isBle = device.connectId && /^[0-9A-Fa-f]{4}$/.test(device.connectId);\n\n return {\n vendor: 'ledger',\n model: device.model ?? 'unknown',\n firmwareVersion: '',\n deviceId: device.deviceId,\n connectId: device.connectId,\n label: device.name,\n connectionType: isBle ? 'ble' : 'usb',\n capabilities: device.capabilities,\n };\n }\n\n private extractDeviceInfoFromPayload(payload: Record<string, unknown>): DeviceInfo {\n return {\n vendor: 'ledger',\n model: (payload.model as string) ?? 'unknown',\n firmwareVersion: '',\n deviceId: (payload.deviceId as string) ?? (payload.id as string) ?? '',\n connectId: (payload.connectId as string) ?? (payload.path as string) ?? '',\n label: payload.label as string,\n connectionType: 'usb' as ConnectionType,\n };\n }\n\n private unknownDevice(): DeviceInfo {\n return {\n vendor: 'ledger',\n model: 'unknown',\n firmwareVersion: '',\n deviceId: '',\n connectId: '',\n connectionType: 'usb',\n };\n }\n}\n","import { HardwareErrorCode, enrichErrorMessage } from '@onekeyfe/hwk-adapter-core';\n\nimport type { Failure } from '@onekeyfe/hwk-adapter-core';\n\n/**\n * Ledger-specific Failure: adds `appName` for \"the currently-open app\" — a\n * Ledger hardware concept not shared with other vendors, so it lives here\n * rather than in core's generic Failure.\n */\nexport type LedgerFailure = Omit<Failure, 'payload'> & {\n payload: Failure['payload'] & { appName?: string };\n};\n\n/**\n * Structurally compatible with `Failure`; writes `appName` only when provided,\n * so `'appName' in payload` is a reliable \"has info\" signal for consumers.\n */\nexport function ledgerFailure(\n code: HardwareErrorCode,\n error: string,\n appName?: string\n): LedgerFailure {\n const payload: LedgerFailure['payload'] = { error, code };\n if (appName !== undefined) payload.appName = appName;\n return { success: false, payload };\n}\n\n/**\n * DMK locked device status codes:\n * 0x5515 (21781) — primary locked response\n * 0x6982 (27010) — security status not satisfied\n * 0x5303 (21251) — tertiary locked response\n */\nconst LOCKED_ERROR_CODES = new Set(['5515', '21781', '6982', '27010', '5303', '21251']);\n\n/**\n * DMK user-rejected status codes:\n * 0x6985 (27013) — conditions of use not satisfied (user denied on device)\n */\nconst USER_REJECTED_CODES = new Set(['6985', '27013']);\n\n/**\n * DMK wrong-app / CLA-not-supported status codes:\n * 0x6e00 (28160) — CLA not supported (wrong app open)\n * 0x6d00 (27904) — INS not supported (wrong app or outdated app)\n * 0x6a83 (27267) — Referenced data not found (wrong app for raw APDU, e.g. TRON)\n */\nconst WRONG_APP_CODES = new Set(['6e00', '28160', '6d00', '27904', '6a83', '27267']);\n\n/**\n * DMK app-not-installed status codes:\n * 0x6807 (26631) — Unknown application name (app not installed on device)\n */\nconst APP_NOT_INSTALLED_CODES = new Set(['6807', '26631']);\n\n/**\n * DMK step value emitted just before a blind-sign failure.\n * Used to distinguish APDU 0x6a80 (\"Invalid data\") caused by disabled\n * Blind signing vs. a genuinely malformed transaction.\n */\nconst STEP_BLIND_SIGN_FALLBACK = 'signer.eth.steps.blindSignTransactionFallback';\n\n/**\n * Read the Ledger Ethereum App APDU error code from a DMK error object.\n * Returns the code in lowercase (e.g. \"6a80\") or `null` if not present.\n */\nfunction getEthAppErrorCode(err: unknown): string | null {\n if (!err || typeof err !== 'object') return null;\n const e = err as Record<string, unknown>;\n if (e._tag === 'EthAppCommandError' && typeof e.errorCode === 'string') {\n return e.errorCode.toLowerCase();\n }\n const orig = e.originalError as Record<string, unknown> | undefined;\n if (orig?._tag === 'EthAppCommandError' && typeof orig.errorCode === 'string') {\n return orig.errorCode.toLowerCase();\n }\n return null;\n}\n\n/**\n * Extract an APDU status word in lowercase hex. Handles DMK's hex-string\n * `errorCode`, legacy TransportStatusError's numeric `statusCode`, and\n * recurses through `originalError` for wrapped errors.\n */\nfunction extractApduHex(err: unknown): string | null {\n if (!err || typeof err !== 'object') return null;\n const e = err as Record<string, unknown>;\n if (typeof e.errorCode === 'string' && /^[0-9a-f]+$/i.test(e.errorCode)) {\n return e.errorCode.toLowerCase();\n }\n if (typeof e.statusCode === 'number' && Number.isFinite(e.statusCode)) {\n return e.statusCode.toString(16).padStart(4, '0');\n }\n if (typeof e.statusCode === 'string' && /^[0-9a-f]+$/i.test(e.statusCode)) {\n return e.statusCode.toLowerCase();\n }\n if (e.originalError != null) {\n const nested = extractApduHex(e.originalError);\n if (nested) return nested;\n }\n if (e.error != null && typeof e._tag === 'string') {\n const nested = extractApduHex(e.error);\n if (nested) return nested;\n }\n return null;\n}\n\n/** Solana APDU → code. 0x6808 arrives as a plain DeviceExchangeError,\n * not wrapped in SolanaAppCommandError, so match by code only. */\nfunction mapSolanaAppError(hex: string): HardwareErrorCode | null {\n switch (hex) {\n case '6808':\n return HardwareErrorCode.SolanaBlindSigningRequired;\n default:\n return null;\n }\n}\n\n/** Tron APDU → code. Source: app-tron/src/app_errors.h (E_MISSING_SETTING_*). */\nfunction mapTronAppError(hex: string): HardwareErrorCode | null {\n switch (hex) {\n case '6a8d':\n return HardwareErrorCode.TronCustomContractRequired;\n case '6a8b':\n return HardwareErrorCode.TronDataSigningRequired;\n case '6a8c':\n return HardwareErrorCode.TronSignByHashRequired;\n default:\n return null;\n }\n}\n\n/** BTC APDU → code. 0xb000 range is disjoint from other apps' 0x6xxx. */\nfunction mapBtcAppError(hex: string): HardwareErrorCode | null {\n switch (hex) {\n case 'b008':\n return HardwareErrorCode.BtcWalletPolicyHmacMismatch;\n case 'b007':\n return HardwareErrorCode.BtcUnexpectedState;\n default:\n return null;\n }\n}\n\n/**\n * Map a Ledger Ethereum App APDU status word to a HardwareErrorCode.\n * `lastStep` (attached by `deviceActionToPromise`) is used only to refine\n * ambiguous codes like 0x6a80.\n */\nfunction mapEthAppError(ethCode: string, lastStep: string | undefined): HardwareErrorCode | null {\n switch (ethCode) {\n case '6a80':\n // \"Invalid data\". If DMK had just fallen back to blind signing, the\n // only plausible cause is that Blind signing is disabled on the device.\n if (lastStep === STEP_BLIND_SIGN_FALLBACK) {\n return HardwareErrorCode.EvmBlindSigningRequired;\n }\n // Other call sites (e.g. clear-sign with malformed context) — keep\n // unknown so the raw message surfaces and the bug can be diagnosed.\n return null;\n case '6984':\n return HardwareErrorCode.EvmClearSignPluginMissing;\n case '6a84':\n return HardwareErrorCode.EvmDataTooLarge;\n case '6501':\n return HardwareErrorCode.EvmTxTypeNotSupported;\n case '911c':\n return HardwareErrorCode.AppTooOld;\n default:\n return null;\n }\n}\n\n/** Check if an error (or any error in its chain) represents a locked Ledger device. */\nexport function isDeviceLockedError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as Record<string, unknown>;\n if (e.errorCode != null && LOCKED_ERROR_CODES.has(String(e.errorCode))) return true;\n if (e.statusCode != null && LOCKED_ERROR_CODES.has(String(e.statusCode))) return true;\n if (e._tag === 'DeviceLockedError') return true;\n if (e.originalError != null && isDeviceLockedError(e.originalError)) return true;\n if (e.error != null && e._tag && isDeviceLockedError(e.error)) return true;\n return false;\n}\n\n/** Check if a status/error code exists in the given set, crawling the error chain. */\nfunction hasStatusCode(err: unknown, codeSet: Set<string>): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as Record<string, unknown>;\n if (e.errorCode != null && codeSet.has(String(e.errorCode))) return true;\n if (e.statusCode != null && codeSet.has(String(e.statusCode))) return true;\n if (e.originalError != null && hasStatusCode(e.originalError, codeSet)) return true;\n if (e.error != null && e._tag && hasStatusCode(e.error, codeSet)) return true;\n return false;\n}\n\n/** Check for user rejection (denied on device). */\nexport function isUserRejectedError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as Record<string, unknown>;\n if (e._tag === 'UserRefusedOnDevice') return true;\n if (typeof e.message === 'string' && /denied|rejected|refused/i.test(e.message)) return true;\n if (hasStatusCode(err, USER_REJECTED_CODES)) return true;\n return false;\n}\n\n/** Check for wrong app open on the device. */\nexport function isWrongAppError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as Record<string, unknown>;\n if (e._tag === 'WrongAppOpenedError' || e._tag === 'InvalidStatusWordError') {\n if (hasStatusCode(err, WRONG_APP_CODES)) return true;\n }\n if (typeof e.message === 'string') {\n const msg = e.message.toLowerCase();\n if (msg.includes('wrong app') || msg.includes('open the') || msg.includes('cla not supported'))\n return true;\n }\n if (hasStatusCode(err, WRONG_APP_CODES)) return true;\n return false;\n}\n\n/** Check for app not installed on device (OpenAppCommand returns 0x6807). */\nexport function isAppNotInstalledError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as Record<string, unknown>;\n if (e._tag === 'OpenAppCommandError') return true;\n if (typeof e.message === 'string' && /unknown application/i.test(e.message)) return true;\n if (hasStatusCode(err, APP_NOT_INSTALLED_CODES)) return true;\n return false;\n}\n\n/** Check for device disconnected errors. */\nexport function isDeviceDisconnectedError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as Record<string, unknown>;\n if (e._tag === 'DeviceNotRecognizedError' || e._tag === 'DeviceSessionNotFound') return true;\n if (typeof e.message === 'string') {\n const msg = e.message.toLowerCase();\n if (\n msg.includes('disconnected') ||\n msg.includes('not found') ||\n msg.includes('no device') ||\n msg.includes('unplugged')\n )\n return true;\n }\n return false;\n}\n\n/**\n * DMK timeout error _tag values.\n * These are the concrete error classes from @ledgerhq/device-management-kit.\n */\nconst TIMEOUT_TAGS = new Set([\n 'DeviceExchangeTimeoutError',\n 'SendApduTimeoutError',\n 'SendCommandTimeoutError',\n]);\n\n/** Check for timeout errors using DMK's _tag identifiers or wrapped error code. */\nexport function isTimeoutError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as Record<string, unknown>;\n if (typeof e._tag === 'string' && TIMEOUT_TAGS.has(e._tag)) return true;\n if (e.code === HardwareErrorCode.OperationTimeout) return true;\n return false;\n}\n\n/**\n * Map a Ledger DMK error to a HardwareErrorCode and human-readable message\n * with actionable recovery information for the caller.\n */\nexport function mapLedgerError(err: unknown): {\n code: HardwareErrorCode;\n message: string;\n appName?: string;\n} {\n // Order matters: check more specific errors first\n\n // Extract the original message for fallback / enrichment\n let originalMessage = 'Unknown Ledger error';\n if (err instanceof Error) {\n originalMessage = err.message;\n } else if (err && typeof err === 'object') {\n const e = err as Record<string, unknown>;\n originalMessage = String(e.message ?? e._tag ?? e.type ?? JSON.stringify(err));\n }\n\n let code: HardwareErrorCode;\n\n if (isDeviceLockedError(err)) {\n code = HardwareErrorCode.DeviceLocked;\n } else if (isUserRejectedError(err)) {\n // User rejection (0x6985) must win over EthAppError mapping — a user-cancelled\n // blind-sign is not a \"please enable Blind signing\" situation.\n code = HardwareErrorCode.UserRejected;\n } else if (isWrongAppError(err)) {\n code = HardwareErrorCode.WrongApp;\n } else if (isAppNotInstalledError(err)) {\n code = HardwareErrorCode.AppNotOpen;\n } else if (isDeviceDisconnectedError(err)) {\n code = HardwareErrorCode.DeviceDisconnected;\n } else if (isTimeoutError(err)) {\n code = HardwareErrorCode.OperationTimeout;\n } else {\n // Ethereum App APDU-specific classification (uses _lastStep attached by\n // deviceActionToPromise to disambiguate 0x6a80).\n const ethCode = getEthAppErrorCode(err);\n const lastStep =\n err && typeof err === 'object'\n ? ((err as Record<string, unknown>)._lastStep as string | undefined)\n : undefined;\n const ethMapped = ethCode ? mapEthAppError(ethCode, lastStep) : null;\n\n // Solana / Tron / BTC APDU codes — disjoint from EVM's table, single-pass lookup.\n const apduHex = ethMapped ? null : extractApduHex(err);\n const chainMapped = apduHex\n ? mapSolanaAppError(apduHex) ?? mapTronAppError(apduHex) ?? mapBtcAppError(apduHex)\n : null;\n\n code = ethMapped ?? chainMapped ?? HardwareErrorCode.UnknownError;\n }\n\n const appName =\n err && typeof err === 'object'\n ? ((err as Record<string, unknown>).appName as string | undefined)\n : undefined;\n\n return { code, message: enrichErrorMessage(code, originalMessage), appName };\n}\n","/**\n * Centralised debug logger for the Ledger adapter.\n *\n * Off by default. Toggle programmatically via `setDebugEnabled(true)`.\n */\n\nlet enabled = false;\n\n/** Enable or disable debug logging at runtime. */\nexport function setDebugEnabled(value: boolean): void {\n enabled = value;\n}\n\n/** Returns the current debug-enabled state. */\nexport function isDebugEnabled(): boolean {\n return enabled;\n}\n\nexport function debugLog(...args: unknown[]): void {\n if (enabled) {\n // eslint-disable-next-line no-console\n console.debug(...args);\n }\n}\n\nexport function debugError(...args: unknown[]): void {\n if (enabled) {\n // eslint-disable-next-line no-console\n console.error(...args);\n }\n}\n","import { debugError, debugLog } from '../utils/debugLog';\n\nimport type { DeviceChangeEvent, DeviceDescriptor } from '@onekeyfe/hwk-adapter-core';\nimport type { DeviceManagementKit } from '@ledgerhq/device-management-kit';\nimport type { DmkDiscoveredDevice } from '../types';\n\n/**\n * Manages device discovery, connection, and session tracking.\n * Wraps DMK's Observable APIs into simpler imperative calls.\n */\nexport class LedgerDeviceManager {\n private readonly _dmk: DeviceManagementKit;\n\n private readonly _discovered = new Map<string, DmkDiscoveredDevice>();\n\n private readonly _sessions = new Map<string, string>(); // deviceId → sessionId\n\n private readonly _sessionToDevice = new Map<string, string>(); // sessionId → deviceId\n\n private _listenSub: { unsubscribe: () => void } | null = null;\n\n constructor(dmk: DeviceManagementKit) {\n this._dmk = dmk;\n }\n\n /**\n * One-shot enumeration: subscribe to listenToAvailableDevices,\n * take the first emission, unsubscribe, return DeviceDescriptors.\n */\n enumerate(): Promise<DeviceDescriptor[]> {\n debugLog('[DMK] enumerate() called, dmk exists:', !!this._dmk);\n return new Promise<DeviceDescriptor[]>(resolve => {\n let resolved = false;\n let syncResult: DmkDiscoveredDevice[] | null = null;\n let sub: { unsubscribe: () => void } | null = null;\n\n sub = this._dmk.listenToAvailableDevices({}).subscribe({\n next: devices => {\n if (resolved) return;\n resolved = true;\n this._discovered.clear();\n debugLog('[DMK] enumerate raw devices:', devices.length);\n for (const d of devices) {\n this._discovered.set(d.id, d);\n }\n // If sub is already assigned (async emission), resolve and unsubscribe immediately\n if (sub) {\n sub.unsubscribe();\n resolve(\n devices.map(d => ({\n path: d.id,\n type: d.deviceModel.model,\n name: d.name,\n transport: d.transport,\n }))\n );\n } else {\n // Synchronous emission — sub not yet assigned, defer to after subscribe()\n syncResult = devices;\n }\n },\n error: () => {\n if (!resolved) {\n resolved = true;\n resolve([]);\n }\n },\n });\n\n // If BehaviorSubject fired synchronously, sub is now assigned\n if (syncResult !== null) {\n sub.unsubscribe();\n const devices = syncResult as DmkDiscoveredDevice[];\n resolve(\n devices.map(d => ({\n path: d.id,\n type: d.deviceModel.model,\n name: d.name,\n transport: d.transport,\n }))\n );\n }\n });\n }\n\n /**\n * Continuous listening: tracks device connect/disconnect via diffing.\n */\n listen(onChange: (event: DeviceChangeEvent) => void): void {\n this.stopListening();\n let previousIds = new Set<string>();\n\n this._listenSub = this._dmk.listenToAvailableDevices({}).subscribe({\n next: devices => {\n const currentIds = new Set(devices.map(d => d.id));\n\n for (const d of devices) {\n this._discovered.set(d.id, d);\n debugLog('[DMK] listen device:', d.id, d.name);\n if (!previousIds.has(d.id)) {\n onChange({\n type: 'device-connected',\n descriptor: {\n path: d.id,\n type: d.deviceModel.model,\n name: d.name,\n transport: d.transport,\n },\n });\n }\n }\n for (const id of previousIds) {\n if (!currentIds.has(id)) {\n this._discovered.delete(id);\n onChange({ type: 'device-disconnected', descriptor: { path: id } });\n }\n }\n previousIds = currentIds;\n },\n });\n }\n\n stopListening(): void {\n this._listenSub?.unsubscribe();\n this._listenSub = null;\n }\n\n /**\n * Trigger browser device selection (WebHID requestDevice).\n * Starts discovery for a short period, then stops.\n */\n /**\n * Start BLE discovery if not already running.\n * Does NOT stop — DMK keeps scanning in the background so that\n * listenToAvailableDevices() always has fresh data.\n */\n private _discoverySub: { unsubscribe: () => void } | null = null;\n\n requestDevice(): Promise<void> {\n if (this._discoverySub) {\n // Already scanning\n return Promise.resolve();\n }\n debugLog('[DMK] requestDevice() starting persistent BLE scan');\n this._discoverySub = this._dmk.startDiscovering({}).subscribe({\n next: d => {\n debugLog('[DMK] BLE discovered:', d.name || d.id);\n this._discovered.set(d.id, d);\n },\n error: err => {\n debugError('[DMK] BLE scan error:', err);\n this._discoverySub = null;\n },\n });\n return Promise.resolve();\n }\n\n /** Connect to a previously discovered device. Returns sessionId. */\n async connect(deviceId: string): Promise<string> {\n const device = this._discovered.get(deviceId);\n if (!device) {\n throw new Error(`Device \"${deviceId}\" not found. Call enumerate() or listen() first.`);\n }\n const sessionId = await this._dmk.connect({ device });\n this._sessions.set(deviceId, sessionId);\n this._sessionToDevice.set(sessionId, deviceId);\n return sessionId;\n }\n\n /** Disconnect a session. */\n async disconnect(sessionId: string): Promise<void> {\n await this._dmk.disconnect({ sessionId });\n const deviceId = this._sessionToDevice.get(sessionId);\n if (deviceId) this._sessions.delete(deviceId);\n this._sessionToDevice.delete(sessionId);\n }\n\n getSessionId(deviceId: string): string | undefined {\n return this._sessions.get(deviceId);\n }\n\n getDeviceId(sessionId: string): string | undefined {\n return this._sessionToDevice.get(sessionId);\n }\n\n /** Get the underlying DMK instance (needed by SignerManager). */\n getDmk(): DeviceManagementKit {\n return this._dmk;\n }\n\n stopDiscovery(): void {\n if (this._discoverySub) {\n this._discoverySub.unsubscribe();\n this._discoverySub = null;\n this._dmk.stopDiscovering();\n }\n }\n\n dispose(): void {\n this.stopListening();\n this.stopDiscovery();\n this._discovered.clear();\n this._sessions.clear();\n this._sessionToDevice.clear();\n this._dmk.close();\n }\n}\n","import { SignerEthBuilder } from '@ledgerhq/device-signer-kit-ethereum';\nimport { ContextModuleBuilder } from '@ledgerhq/context-module';\n\nimport { SignerEth } from './SignerEth';\nimport { debugLog } from '../utils/debugLog';\n\nimport type { DeviceManagementKit } from '@ledgerhq/device-management-kit';\nimport type { SignerEth as ISdkSignerEth } from '@ledgerhq/device-signer-kit-ethereum';\n\ntype SignerEthBuilderFn = (args: {\n dmk: DeviceManagementKit;\n sessionId: string;\n}) => { build(): ISdkSignerEth } | Promise<{ build(): ISdkSignerEth }>;\n\n/**\n * Per-sessionId SignerEth factory. Builds fresh on every call — DMK signers\n * hold DeviceAction state that isn't safe to reuse, so `invalidate` /\n * `clearAll` are kept as no-op lifecycle hooks for callers.\n */\nexport class SignerManager {\n private readonly _dmk: DeviceManagementKit;\n\n private readonly _builderFn: SignerEthBuilderFn;\n\n constructor(dmk: DeviceManagementKit, builderFn?: SignerEthBuilderFn) {\n this._dmk = dmk;\n this._builderFn = builderFn ?? SignerManager._defaultBuilder();\n }\n\n async getOrCreate(sessionId: string): Promise<SignerEth> {\n debugLog('[DMK] SignerManager.getOrCreate:', { sessionId });\n const builder = await this._builderFn({ dmk: this._dmk, sessionId });\n return new SignerEth(builder.build());\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, class-methods-use-this\n invalidate(_sessionId: string): void {}\n\n // eslint-disable-next-line class-methods-use-this\n clearAll(): void {}\n\n private static _defaultBuilder(): SignerEthBuilderFn {\n return args => {\n const contextModule = new ContextModuleBuilder({}).removeDefaultLoaders().build();\n return new SignerEthBuilder(args).withContextModule(contextModule);\n };\n }\n}\n","import { hexToBytes } from '@onekeyfe/hwk-adapter-core';\n\nimport { deviceActionToPromise } from './deviceActionToPromise';\nimport { debugLog } from '../utils/debugLog';\n\nimport type { SignerEth as ISdkSignerEth, TypedData } from '@ledgerhq/device-signer-kit-ethereum';\nimport type { SignerEvmAddress, SignerEvmSignature } from '../types';\n\n/** Timeout for user-interactive operations (verify address, sign). */\nconst INTERACTIVE_TIMEOUT_MS = 5 * 60_000;\n\n/**\n * Wraps Ledger's SDK signer (Observable-based DeviceActions) into\n * a simple async interface returning plain serializable data.\n */\nexport class SignerEth {\n onInteraction?: (interaction: string) => void;\n\n // eslint-disable-next-line no-useless-constructor, no-empty-function\n constructor(private readonly _sdk: ISdkSignerEth) {}\n\n /**\n * Optional callback registered per-call so the caller can obtain a canceller\n * for the underlying DeviceAction. Caller can invoke it to release DMK's\n * IntentQueue slot and unsubscribe from the action's observable.\n */\n onRegisterCanceller?: (cancel: () => void) => void;\n\n async getAddress(\n derivationPath: string,\n options?: { checkOnDevice?: boolean }\n ): Promise<SignerEvmAddress> {\n const checkOnDevice = options?.checkOnDevice ?? false;\n debugLog('[DMK] getAddress → DMK:', { derivationPath, checkOnDevice });\n const action = this._sdk.getAddress(derivationPath, {\n checkOnDevice,\n });\n // checkOnDevice needs user interaction → long timeout; otherwise default 30s\n const timeout = checkOnDevice ? INTERACTIVE_TIMEOUT_MS : undefined;\n return deviceActionToPromise<SignerEvmAddress>(\n action,\n this.onInteraction,\n timeout,\n this.onRegisterCanceller\n );\n }\n\n async signTransaction(\n derivationPath: string,\n serializedTxHex: string\n ): Promise<SignerEvmSignature> {\n const action = this._sdk.signTransaction(derivationPath, hexToBytes(serializedTxHex));\n return deviceActionToPromise<SignerEvmSignature>(\n action,\n this.onInteraction,\n INTERACTIVE_TIMEOUT_MS,\n this.onRegisterCanceller\n );\n }\n\n async signMessage(derivationPath: string, message: string): Promise<SignerEvmSignature> {\n // DMK treats string as ASCII text (addAsciiStringToData), but we receive\n // hex-encoded message bytes. Decode to Uint8Array so DMK uses\n // addBufferToData — matching the OneKey SDK's behavior.\n const action = this._sdk.signMessage(derivationPath, hexToBytes(message));\n return deviceActionToPromise<SignerEvmSignature>(\n action,\n this.onInteraction,\n INTERACTIVE_TIMEOUT_MS,\n this.onRegisterCanceller\n );\n }\n\n async signTypedData(derivationPath: string, data: TypedData): Promise<SignerEvmSignature> {\n const action = this._sdk.signTypedData(derivationPath, data);\n return deviceActionToPromise<SignerEvmSignature>(\n action,\n this.onInteraction,\n INTERACTIVE_TIMEOUT_MS,\n this.onRegisterCanceller\n );\n }\n}\n","import { DeviceActionStatus } from '@ledgerhq/device-management-kit';\n\nimport { debugLog } from '../utils/debugLog';\n\nimport type { DeviceAction, DeviceActionState } from '../types';\n\n/** Default timeout for non-interactive operations (e.g. getAddress without showOnDevice). */\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/**\n * Convert a DMK DeviceAction (Observable-based) into a Promise.\n * Handles pending -> completed/error state transitions and interaction callbacks.\n *\n * Tracks the last DMK step observed (e.g. `signer.eth.steps.blindSignTransactionFallback`)\n * and attaches it to the rejected error as a non-enumerable `_lastStep` property,\n * so upstream error classifiers can distinguish failure contexts (e.g. Blind signing\n * disabled vs. generic Invalid data).\n *\n * @param timeoutMs Timeout in ms. Resets each time the Observable emits (device is alive).\n * Pass 0 to disable. Default: 30s.\n * @param onRegisterCanceller Optional callback that receives a function which, when\n * called, unsubscribes and cancels the underlying DeviceAction\n * (releases DMK's IntentQueue slot). Caller is responsible\n * for invoking the canceller on timeout/abort scenarios.\n */\nexport function deviceActionToPromise<T>(\n action: DeviceAction<T>,\n onInteraction?: (interaction: string) => void,\n timeoutMs: number = DEFAULT_TIMEOUT_MS,\n onRegisterCanceller?: (cancel: () => void) => void\n): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n let settled = false;\n let lastStep: string | undefined;\n // eslint-disable-next-line prefer-const -- assigned once after declaration, but must be declared before use in cleanup\n let sub: { unsubscribe: () => void };\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n /** Fully tear down this action: unsubscribe + release DMK intent queue slot. */\n const cancelAction = () => {\n try {\n sub?.unsubscribe();\n } catch {\n // subscription may already be closed; ignore\n }\n try {\n action.cancel();\n } catch {\n // DMK action may already be settled; ignore\n }\n };\n\n const resetTimer = () => {\n if (timer) clearTimeout(timer);\n if (timeoutMs > 0) {\n timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n cancelAction();\n reject(new Error('Device action timed out — device may be locked or disconnected'));\n }\n }, timeoutMs);\n }\n };\n\n // Start initial timer\n resetTimer();\n\n // Expose a canceller for external abort (release DMK queue slot + unsubscribe).\n if (onRegisterCanceller) {\n onRegisterCanceller(() => {\n if (settled) return;\n settled = true;\n if (timer) clearTimeout(timer);\n cancelAction();\n reject(new Error('Device action cancelled'));\n });\n }\n\n debugLog('[DMK-Observable] subscribing to action.observable...');\n sub = action.observable.subscribe({\n next: (state: DeviceActionState<T>) => {\n // Drop late emissions post-cancel; otherwise resetTimer re-arms an unclearable timer.\n if (settled) return;\n resetTimer(); // device is alive → reset timeout\n\n // Track last DMK step so caller can disambiguate failure contexts\n // (e.g. 0x6a80 during blindSignTransactionFallback = Blind signing disabled)\n const step = (state as { intermediateValue?: { step?: string } })?.intermediateValue?.step;\n if (step) lastStep = step;\n\n debugLog(\n '[DMK-Observable] state:',\n JSON.stringify({\n status: state.status,\n intermediateValue:\n state.status === DeviceActionStatus.Pending ? state.intermediateValue : undefined,\n hasOutput: state.status === DeviceActionStatus.Completed,\n hasError: state.status === DeviceActionStatus.Error,\n })\n );\n if (state.status === DeviceActionStatus.Completed) {\n settled = true;\n if (timer) clearTimeout(timer);\n onInteraction?.('interaction-complete');\n sub?.unsubscribe();\n resolve(state.output);\n } else if (state.status === DeviceActionStatus.Error) {\n settled = true;\n if (timer) clearTimeout(timer);\n onInteraction?.('interaction-complete');\n sub?.unsubscribe();\n rejectWithLastStep(state.error, lastStep, reject);\n } else if (state.status === DeviceActionStatus.Pending && onInteraction) {\n const interaction = state.intermediateValue?.requiredUserInteraction;\n if (interaction && interaction !== 'none') {\n onInteraction(String(interaction));\n }\n }\n },\n error: (err: unknown) => {\n if (!settled) {\n settled = true;\n if (timer) clearTimeout(timer);\n sub?.unsubscribe();\n rejectWithLastStep(err, lastStep, reject);\n }\n },\n complete: () => {\n if (!settled) {\n settled = true;\n if (timer) clearTimeout(timer);\n reject(new Error('Device action completed without result'));\n }\n },\n });\n });\n}\n\n/**\n * Reject with the DMK error after annotating the last step observed before\n * failure. The step is attached as a non-enumerable property so it doesn't\n * pollute JSON.stringify / log output, but classifiers can still read it via\n * `(err as any)._lastStep`.\n */\nfunction rejectWithLastStep(\n err: unknown,\n lastStep: string | undefined,\n reject: (reason: unknown) => void\n): void {\n if (err && typeof err === 'object' && lastStep) {\n try {\n Object.defineProperty(err, '_lastStep', {\n value: lastStep,\n configurable: true,\n enumerable: false,\n writable: true,\n });\n } catch {\n // Frozen error objects — give up, classifier will fall back.\n }\n }\n reject(err);\n}\n","import { HardwareErrorCode, padHex64, stripHex } from '@onekeyfe/hwk-adapter-core';\n\nimport { collapseSignerInteraction, normalizePath } from './utils';\nimport { debugLog } from '../../utils/debugLog';\n\nimport type { TypedData } from '@ledgerhq/device-signer-kit-ethereum';\nimport type { SignerEvmSignature } from '../../types';\nimport type { ConnectorContext } from './types';\n\n// ---------------------------------------------------------------------------\n// Call param types\n// ---------------------------------------------------------------------------\n\nexport interface EvmGetAddressCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\nexport interface EvmSignTransactionCallParams {\n path: string;\n /** RLP-serialized transaction hex (0x-prefixed or plain) */\n serializedTx?: string;\n}\n\nexport interface EvmSignMessageCallParams {\n path: string;\n message: string;\n}\n\nexport interface EvmSignTypedDataCallParams {\n path: string;\n data: TypedData;\n mode?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Handler\n// ---------------------------------------------------------------------------\n\nexport async function evmGetAddress(\n ctx: ConnectorContext,\n sessionId: string,\n params: EvmGetAddressCallParams\n): Promise<{ address: string; publicKey?: string }> {\n const signer = await _getEthSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n const checkOnDevice = params.showOnDevice ?? false;\n debugLog('[DMK] evmGetAddress -> signer.getAddress:', { path, checkOnDevice });\n\n try {\n const result = await signer.getAddress(path, { checkOnDevice });\n return { address: result.address, publicKey: result.publicKey };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function evmSignTransaction(\n ctx: ConnectorContext,\n sessionId: string,\n params: EvmSignTransactionCallParams\n): Promise<{ v: string; r: string; s: string }> {\n if (!params.serializedTx) {\n throw Object.assign(\n new Error(\n 'Ledger requires a pre-serialized transaction (serializedTx). Provide an RLP-encoded hex string.'\n ),\n { code: HardwareErrorCode.InvalidParams }\n );\n }\n\n const signer = await _getEthSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n\n try {\n const result: SignerEvmSignature = await signer.signTransaction(path, params.serializedTx);\n return {\n v: `0x${result.v.toString(16)}`,\n r: padHex64(result.r),\n s: padHex64(result.s),\n };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function evmSignMessage(\n ctx: ConnectorContext,\n sessionId: string,\n params: EvmSignMessageCallParams\n): Promise<{ signature: string }> {\n const signer = await _getEthSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n\n try {\n const result: SignerEvmSignature = await signer.signMessage(path, params.message);\n const rHex = stripHex(result.r).padStart(64, '0');\n const sHex = stripHex(result.s).padStart(64, '0');\n const vHex = result.v.toString(16).padStart(2, '0');\n return { signature: `0x${rHex}${sHex}${vHex}` };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function evmSignTypedData(\n ctx: ConnectorContext,\n sessionId: string,\n params: EvmSignTypedDataCallParams\n): Promise<{ signature: string }> {\n if (params.mode === 'hash') {\n throw Object.assign(\n new Error(\n 'Ledger does not support hash-only EIP-712 signing. Use mode \"full\" with the complete typed data structure.'\n ),\n { code: HardwareErrorCode.MethodNotSupported }\n );\n }\n\n const signer = await _getEthSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n\n try {\n const result: SignerEvmSignature = await signer.signTypedData(path, params.data);\n const rHex = stripHex(result.r).padStart(64, '0');\n const sHex = stripHex(result.s).padStart(64, '0');\n const vHex = result.v.toString(16).padStart(2, '0');\n return { signature: `0x${rHex}${sHex}${vHex}` };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal — ETH signer creation\n// ---------------------------------------------------------------------------\n\nasync function _getEthSigner(ctx: ConnectorContext, sessionId: string) {\n const signerManager = await ctx.getSignerManager();\n const signer = await signerManager.getOrCreate(sessionId);\n\n // Wire up interaction events (open-app, unlock, verify-address, sign, etc.)\n // DMK-specific values (verify-address, sign-transaction, sign-typed-data,\n // sign-personal-message) collapse to ConfirmOnDevice via the helper.\n signer.onInteraction = (interaction: string) => {\n ctx.emit('ui-event', {\n type: collapseSignerInteraction(interaction),\n payload: { sessionId },\n });\n };\n\n // Expose DeviceAction canceller to the connector so that cancel(sessionId)\n // can release DMK's intent queue slot and unsubscribe cleanly.\n signer.onRegisterCanceller = (cancel: () => void) => {\n ctx.registerCanceller(sessionId, cancel);\n };\n\n return signer;\n}\n","import { EConnectorInteraction } from '@onekeyfe/hwk-adapter-core';\n\n/**\n * Strip the \"m/\" prefix from BIP-44 derivation paths.\n * Ledger DMK requires paths without the \"m/\" prefix.\n */\nexport function normalizePath(path: string): string {\n return path.startsWith('m/') ? path.slice(2) : path;\n}\n\n/**\n * Collapse Ledger DMK's raw `requiredUserInteraction` strings into the\n * 4-value EConnectorInteraction union exported by this SDK.\n *\n * DMK emits chain-signer-specific strings like \"verify-address\",\n * \"sign-transaction\", \"sign-typed-data\", \"sign-personal-message\" — they\n * all mean \"the user must act on the device screen\", i.e. ConfirmOnDevice\n * per the public ConnectorUiEvent type contract. Leaking raw DMK strings\n * out of the SDK would break consumers that switch on EConnectorInteraction.\n */\nexport function collapseSignerInteraction(interaction: string): EConnectorInteraction {\n switch (interaction) {\n case 'confirm-open-app':\n return EConnectorInteraction.ConfirmOpenApp;\n case 'unlock-device':\n return EConnectorInteraction.UnlockDevice;\n case 'interaction-complete':\n return EConnectorInteraction.InteractionComplete;\n default:\n return EConnectorInteraction.ConfirmOnDevice;\n }\n}\n","import { HardwareErrorCode, stripHex } from '@onekeyfe/hwk-adapter-core';\nimport { Psbt } from 'bitcoinjs-lib';\n\nimport { collapseSignerInteraction, normalizePath } from './utils';\nimport { SignerBtc } from '../../signer/SignerBtc';\nimport { debugError, debugLog } from '../../utils/debugLog';\n\nimport type { ConnectorContext } from './types';\n\n// ---------------------------------------------------------------------------\n// Call param types\n// ---------------------------------------------------------------------------\n\nexport interface BtcGetAddressCallParams {\n /** Account-level derivation path (3 levels, e.g. \"m/86'/0'/0'\") */\n path: string;\n showOnDevice?: boolean;\n /** Address index within the account (default: 0) */\n addressIndex?: number;\n /** Whether this is a change address (default: false) */\n change?: boolean;\n}\n\nexport interface BtcGetPublicKeyCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\nexport interface BtcSignTransactionCallParams {\n psbt?: string;\n coin: string;\n /** Account-level derivation path for wallet template determination (e.g. \"84'/0'/0'\"). */\n path?: string;\n}\n\nexport interface BtcSignPsbtCallParams {\n psbt: string;\n coin?: string;\n path?: string;\n}\n\nexport interface BtcSignMessageCallParams {\n path: string;\n message: string;\n coin?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Internal -- BIP-44 purpose → Ledger wallet template\n// ---------------------------------------------------------------------------\n\n/**\n * BIP-44 purpose → Ledger descriptor template. Throws on unknown —\n * silent NATIVE_SEGWIT fallback would yield wrong addresses for\n * multisig (m/48') / legacy BIP-45 accounts. DDT is injected because\n * it comes from a runtime `importLedgerKit`.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction _purposeToTemplate(purpose: string | undefined, DDT: any): any {\n switch (purpose) {\n case '44':\n return DDT.LEGACY;\n case '49':\n return DDT.NESTED_SEGWIT;\n case '84':\n return DDT.NATIVE_SEGWIT;\n case '86':\n return DDT.TAPROOT;\n default:\n throw Object.assign(new Error(`Unsupported BTC purpose: m/${purpose ?? '<undefined>'}'`), {\n code: HardwareErrorCode.InvalidParams,\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Handlers\n// ---------------------------------------------------------------------------\n\nexport async function btcGetAddress(\n ctx: ConnectorContext,\n sessionId: string,\n params: BtcGetAddressCallParams\n): Promise<{ address: string; path: string }> {\n const btcSigner = await _createBtcSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n\n try {\n const { DefaultWallet, DefaultDescriptorTemplate } = await ctx.importLedgerKit(\n '@ledgerhq/device-signer-kit-bitcoin'\n );\n const purpose = path.split('/')[0]?.replace(/'/g, '');\n const template = _purposeToTemplate(purpose, DefaultDescriptorTemplate);\n const wallet = new DefaultWallet(path, template);\n\n debugLog('[LedgerConnector] btcGetAddress params:', {\n path,\n purpose,\n template,\n addressIndex: params.addressIndex,\n change: params.change,\n showOnDevice: params.showOnDevice,\n });\n\n const result = await btcSigner.getWalletAddress(wallet, params.addressIndex ?? 0, {\n checkOnDevice: params.showOnDevice ?? false,\n change: params.change ?? false,\n });\n return { address: result.address, path: params.path };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function btcGetPublicKey(\n ctx: ConnectorContext,\n sessionId: string,\n params: BtcGetPublicKeyCallParams\n): Promise<{ xpub: string; path: string }> {\n const btcSigner = await _createBtcSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n\n debugLog('[LedgerConnector] btcGetPublicKey called, path:', path, 'sessionId:', sessionId);\n try {\n const xpub = await btcSigner.getExtendedPublicKey(path, {\n checkOnDevice: params.showOnDevice ?? false,\n });\n debugLog('[LedgerConnector] btcGetPublicKey success, xpub:', `${xpub?.substring(0, 20)}...`);\n return { xpub, path: params.path };\n } catch (err) {\n debugError('[LedgerConnector] btcGetPublicKey error, path:', path, 'err:', err);\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function btcSignTransaction(\n ctx: ConnectorContext,\n sessionId: string,\n params: BtcSignTransactionCallParams\n): Promise<{ serializedTx: string }> {\n if (!params.psbt) {\n throw Object.assign(\n new Error('Ledger requires PSBT format for BTC transaction signing. Provide params.psbt.'),\n { code: HardwareErrorCode.InvalidParams }\n );\n }\n\n const btcSigner = await _createBtcSigner(ctx, sessionId);\n\n try {\n const { DefaultWallet, DefaultDescriptorTemplate } = await ctx.importLedgerKit(\n '@ledgerhq/device-signer-kit-bitcoin'\n );\n\n // Determine wallet template from the account-level derivation path\n const path = normalizePath(params.path || \"84'/0'/0'\");\n const purpose = path.split('/')[0]?.replace(/'/g, '');\n const template = _purposeToTemplate(purpose, DefaultDescriptorTemplate);\n\n const wallet = new DefaultWallet(path, template);\n\n const signedTxHex = await btcSigner.signTransaction(wallet, params.psbt);\n\n return { serializedTx: stripHex(signedTxHex) };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function btcSignPsbt(\n ctx: ConnectorContext,\n sessionId: string,\n params: BtcSignPsbtCallParams\n): Promise<{ signedPsbt: string }> {\n if (!params.psbt) {\n throw Object.assign(new Error('btcSignPsbt requires params.psbt'), {\n code: HardwareErrorCode.InvalidParams,\n });\n }\n\n const btcSigner = await _createBtcSigner(ctx, sessionId);\n\n try {\n const { DefaultWallet, DefaultDescriptorTemplate } = await ctx.importLedgerKit(\n '@ledgerhq/device-signer-kit-bitcoin'\n );\n\n const path = normalizePath(params.path || \"84'/0'/0'\");\n const purpose = path.split('/')[0]?.replace(/'/g, '');\n const template = _purposeToTemplate(purpose, DefaultDescriptorTemplate);\n\n const wallet = new DefaultWallet(path, template);\n\n const signatures = (await btcSigner.signPsbt(wallet, params.psbt)) as Array<{\n inputIndex: number;\n pubkey: Uint8Array;\n signature: Uint8Array;\n tapleafHash?: Uint8Array;\n }>;\n\n const signedPsbtHex = _applySignaturesToPsbt(params.psbt, signatures);\n return { signedPsbt: signedPsbtHex };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function btcSignMessage(\n ctx: ConnectorContext,\n sessionId: string,\n params: BtcSignMessageCallParams\n): Promise<{ signature: string; address?: string }> {\n const btcSigner = await _createBtcSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n\n try {\n // signMessage returns { r: HexaString, s: HexaString, v: number }\n const result = await btcSigner.signMessage(path, params.message);\n\n // BIP-137: signature = v(1) + r(32) + s(32); returned as hex (OneKey SDK style).\n const vHex = result.v.toString(16).padStart(2, '0');\n const rHex = stripHex(result.r).padStart(64, '0');\n const sHex = stripHex(result.s).padStart(64, '0');\n\n return { signature: `${vHex}${rHex}${sHex}` };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function btcGetMasterFingerprint(\n ctx: ConnectorContext,\n sessionId: string,\n params?: { skipOpenApp?: boolean }\n): Promise<{ masterFingerprint: string }> {\n const btcSigner = await _createBtcSigner(ctx, sessionId);\n\n try {\n const fingerprint: Uint8Array = await btcSigner.getMasterFingerprint({\n skipOpenApp: params?.skipOpenApp,\n });\n // Convert Uint8Array to hex string\n const hex = Array.from(fingerprint)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('');\n return { masterFingerprint: hex };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal -- BTC signer creation\n// ---------------------------------------------------------------------------\n\nasync function _createBtcSigner(ctx: ConnectorContext, sessionId: string): Promise<SignerBtc> {\n const dmk = await ctx.getOrCreateDmk();\n const { SignerBtcBuilder } = await ctx.importLedgerKit('@ledgerhq/device-signer-kit-bitcoin');\n const sdkSigner = new SignerBtcBuilder({ dmk, sessionId }).build();\n const signer = new SignerBtc(sdkSigner);\n\n // Wire up interaction events (open-app, unlock, sign, etc.)\n // DMK-specific values (sign-transaction, sign-personal-message,\n // verify-address) collapse to ConfirmOnDevice via the helper.\n signer.onInteraction = (interaction: string) => {\n ctx.emit('ui-event', {\n type: collapseSignerInteraction(interaction),\n payload: { sessionId },\n });\n };\n\n signer.onRegisterCanceller = (cancel: () => void) => {\n ctx.registerCanceller(sessionId, cancel);\n };\n\n return signer;\n}\n\n// ---------------------------------------------------------------------------\n// Internal -- Apply partial signatures to PSBT\n// ---------------------------------------------------------------------------\n\ntype PsbtInput = Psbt['data']['inputs'][number];\n\nfunction _isTaprootInput(input: PsbtInput): boolean {\n if (\n input.tapInternalKey ||\n input.tapKeySig ||\n input.tapLeafScript ||\n input.tapMerkleRoot ||\n input.tapBip32Derivation ||\n input.tapScriptSig\n )\n return true;\n // P2TR scriptPubKey: OP_1 (0x51) + PUSH32 (0x20) + <32B x-only>\n const script = input.witnessUtxo?.script;\n return !!(script && script.length === 34 && script[0] === 0x51 && script[1] === 0x20);\n}\n\nfunction _isScriptPathInput(input: PsbtInput): boolean {\n return !!(input.tapLeafScript && input.tapLeafScript.length > 0);\n}\n\n/**\n * Dispatch DMK-returned signatures to the correct PSBT field using the\n * input's scriptPubKey as authoritative signal; throws on shape violations.\n */\nexport function _applySignaturesToPsbt(\n psbtHex: string,\n signatures: Array<{\n inputIndex: number;\n pubkey: Uint8Array;\n signature: Uint8Array;\n tapleafHash?: Uint8Array;\n }>\n): string {\n const psbt = Psbt.fromHex(psbtHex);\n for (const sig of signatures) {\n const input = psbt.data.inputs[sig.inputIndex];\n if (!input) {\n throw new Error(`_applySignaturesToPsbt: no PSBT input at index ${sig.inputIndex}`);\n }\n const taproot = _isTaprootInput(input);\n const scriptPath = taproot && _isScriptPathInput(input);\n const hasLeafHash = !!(sig.tapleafHash && sig.tapleafHash.length > 0);\n\n if (scriptPath) {\n if (sig.pubkey.length !== 32)\n throw new Error(\n `input ${sig.inputIndex}: taproot script-path pubkey must be 32B, got ${sig.pubkey.length}`\n );\n if (!hasLeafHash)\n throw new Error(\n `input ${sig.inputIndex}: taproot script-path signature missing tapleafHash`\n );\n psbt.updateInput(sig.inputIndex, {\n tapScriptSig: [\n { pubkey: sig.pubkey, leafHash: sig.tapleafHash!, signature: sig.signature },\n ],\n });\n } else if (taproot) {\n if (sig.pubkey.length !== 32)\n throw new Error(\n `input ${sig.inputIndex}: taproot key-path pubkey must be 32B, got ${sig.pubkey.length}`\n );\n if (hasLeafHash)\n throw new Error(\n `input ${sig.inputIndex}: taproot key-path signature must not carry tapleafHash`\n );\n psbt.updateInput(sig.inputIndex, { tapKeySig: sig.signature });\n } else {\n if (sig.pubkey.length !== 33 && sig.pubkey.length !== 65)\n throw new Error(\n `input ${sig.inputIndex}: ECDSA pubkey must be 33B or 65B, got ${sig.pubkey.length}`\n );\n if (hasLeafHash)\n throw new Error(`input ${sig.inputIndex}: ECDSA signature must not carry tapleafHash`);\n psbt.updateInput(sig.inputIndex, {\n partialSig: [{ pubkey: sig.pubkey, signature: sig.signature }],\n });\n }\n }\n return psbt.toHex();\n}\n","import { hexToBytes } from '@onekeyfe/hwk-adapter-core';\n\nimport { deviceActionToPromise } from './deviceActionToPromise';\nimport { debugError, debugLog } from '../utils/debugLog';\n\nimport type { SignerBtc as ISdkSignerBtc } from '@ledgerhq/device-signer-kit-bitcoin';\nimport type { SignerBtcAddress } from '../types';\n\n// Extract parameter types from the real SignerBtc interface to avoid deep path imports.\ntype BtcWallet = Parameters<ISdkSignerBtc['getWalletAddress']>[0];\ntype BtcPsbt = Parameters<ISdkSignerBtc['signPsbt']>[1];\ntype BtcPsbtOptions = Parameters<ISdkSignerBtc['signPsbt']>[2];\ntype BtcMessageOptions = Parameters<ISdkSignerBtc['signMessage']>[2];\n\n/** Decode hex string (with or without 0x prefix) to UTF-8 text. */\nfunction hexToUtf8(hex: string): string {\n return new TextDecoder().decode(hexToBytes(hex));\n}\n\n/** Timeout for user-interactive operations (sign, verify). */\nconst INTERACTIVE_TIMEOUT_MS = 5 * 60_000;\n\n/**\n * Wraps Ledger's BTC SDK signer (Observable-based DeviceActions) into\n * a simple async interface returning plain serializable data.\n */\nexport class SignerBtc {\n onInteraction?: (interaction: string) => void;\n\n onRegisterCanceller?: (cancel: () => void) => void;\n\n // eslint-disable-next-line no-useless-constructor, no-empty-function\n constructor(private readonly _sdk: ISdkSignerBtc) {}\n\n async getWalletAddress(\n wallet: BtcWallet,\n addressIndex: number,\n options?: { checkOnDevice?: boolean; change?: boolean }\n ): Promise<SignerBtcAddress> {\n const action = this._sdk.getWalletAddress(wallet, addressIndex, {\n checkOnDevice: options?.checkOnDevice ?? false,\n change: options?.change ?? false,\n });\n return deviceActionToPromise<SignerBtcAddress>(\n action,\n this.onInteraction,\n undefined,\n this.onRegisterCanceller\n );\n }\n\n async getExtendedPublicKey(\n derivationPath: string,\n options?: { checkOnDevice?: boolean }\n ): Promise<string> {\n debugLog(\n '[SignerBtc] getExtendedPublicKey called, path:',\n derivationPath,\n 'options:',\n JSON.stringify(options)\n );\n const action = this._sdk.getExtendedPublicKey(derivationPath, {\n checkOnDevice: options?.checkOnDevice ?? false,\n });\n try {\n // DMK returns { extendedPublicKey: string }, unwrap it\n const result = await deviceActionToPromise<string | { extendedPublicKey: string }>(\n action,\n this.onInteraction,\n undefined,\n this.onRegisterCanceller\n );\n debugLog(\n '[SignerBtc] getExtendedPublicKey result type:',\n typeof result,\n 'value:',\n typeof result === 'string'\n ? `${result.substring(0, 20)}...`\n : JSON.stringify(result).substring(0, 50)\n );\n if (typeof result === 'string') return result;\n return result.extendedPublicKey;\n } catch (err) {\n debugError('[SignerBtc] getExtendedPublicKey error:', err);\n throw err;\n }\n }\n\n async getMasterFingerprint(options?: { skipOpenApp?: boolean }): Promise<Uint8Array> {\n const action = this._sdk.getMasterFingerprint(options);\n const result = await deviceActionToPromise<{ masterFingerprint: Uint8Array }>(\n action,\n this.onInteraction,\n undefined,\n this.onRegisterCanceller\n );\n return result.masterFingerprint;\n }\n\n /**\n * Sign a PSBT and return the array of partial signatures.\n * The `wallet` param is a DefaultWallet or WalletPolicy instance.\n * The `psbt` param can be a hex string, base64 string, or Uint8Array.\n */\n async signPsbt(wallet: BtcWallet, psbt: BtcPsbt, options?: BtcPsbtOptions): Promise<unknown[]> {\n const action = this._sdk.signPsbt(wallet, psbt, options);\n return deviceActionToPromise<unknown[]>(\n action,\n this.onInteraction,\n INTERACTIVE_TIMEOUT_MS,\n this.onRegisterCanceller\n );\n }\n\n /**\n * Sign a PSBT and return the fully extracted raw transaction as a hex string.\n * Like signPsbt, but also finalises the PSBT and extracts the transaction.\n */\n async signTransaction(\n wallet: BtcWallet,\n psbt: BtcPsbt,\n options?: BtcPsbtOptions\n ): Promise<string> {\n const action = this._sdk.signTransaction(wallet, psbt, options);\n return deviceActionToPromise<string>(\n action,\n this.onInteraction,\n INTERACTIVE_TIMEOUT_MS,\n this.onRegisterCanceller\n );\n }\n\n /**\n * Sign a message with the BTC app (BIP-137 / \"Bitcoin Signed Message\").\n * Returns `{ r, s, v }` signature object.\n */\n async signMessage(\n derivationPath: string,\n message: string,\n options?: BtcMessageOptions\n ): Promise<{ r: string; s: string; v: number }> {\n // DMK uses TextEncoder to convert message string to bytes.\n // We receive hex-encoded message, so decode hex -> UTF-8 text first.\n const action = this._sdk.signMessage(derivationPath, hexToUtf8(message), options);\n return deviceActionToPromise<{ r: string; s: string; v: number }>(\n action,\n this.onInteraction,\n INTERACTIVE_TIMEOUT_MS,\n this.onRegisterCanceller\n );\n }\n}\n","import { bytesToHex, hexToBytes } from '@onekeyfe/hwk-adapter-core';\n\nimport { collapseSignerInteraction, normalizePath } from './utils';\nimport { SignerSol } from '../../signer/SignerSol';\n\nimport type { ConnectorContext } from './types';\n\n// ---------------------------------------------------------------------------\n// Call param types\n// ---------------------------------------------------------------------------\n\nexport interface SolGetAddressCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\nexport interface SolSignTransactionCallParams {\n path: string;\n /** Hex-encoded serialized transaction bytes (no 0x prefix) */\n serializedTx: string;\n}\n\nexport interface SolSignMessageCallParams {\n path: string;\n /** Message bytes as hex string (no 0x prefix) */\n message: string;\n}\n\n// ---------------------------------------------------------------------------\n// Handlers\n// ---------------------------------------------------------------------------\n\nexport async function solGetAddress(\n ctx: ConnectorContext,\n sessionId: string,\n params: SolGetAddressCallParams\n): Promise<{ address: string; path: string }> {\n const solSigner = await _createSolSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n\n try {\n // Ledger Solana signer returns a base58-encoded Ed25519 public key (= Solana address)\n const publicKey = await solSigner.getAddress(path, {\n checkOnDevice: params.showOnDevice ?? false,\n });\n return { address: publicKey, path: params.path };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function solSignTransaction(\n ctx: ConnectorContext,\n sessionId: string,\n params: SolSignTransactionCallParams\n): Promise<{ signature: string }> {\n const solSigner = await _createSolSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n const txBytes = hexToBytes(params.serializedTx);\n\n try {\n const result = await solSigner.signTransaction(path, txBytes);\n return { signature: bytesToHex(result) };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function solSignMessage(\n ctx: ConnectorContext,\n sessionId: string,\n params: SolSignMessageCallParams\n): Promise<{ signature: string }> {\n const solSigner = await _createSolSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n const messageBytes = hexToBytes(params.message);\n\n try {\n // DMK signMessage returns { signature: string }, not raw Uint8Array\n const result = await solSigner.signMessage(path, messageBytes);\n return { signature: result.signature };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal -- SOL signer creation\n// ---------------------------------------------------------------------------\n\nasync function _createSolSigner(ctx: ConnectorContext, sessionId: string): Promise<SignerSol> {\n const dmk = await ctx.getOrCreateDmk();\n const { ContextModuleBuilder } = await ctx.importLedgerKit('@ledgerhq/context-module');\n const { SignerSolanaBuilder } = await ctx.importLedgerKit('@ledgerhq/device-signer-kit-solana');\n const contextModule = new ContextModuleBuilder({}).removeDefaultLoaders().build();\n const sdkSigner = new SignerSolanaBuilder({ dmk, sessionId })\n .withContextModule(contextModule)\n .build();\n const signer = new SignerSol(sdkSigner);\n\n // Wire up interaction events (verify-address, sign, etc.)\n // DMK-specific values (verify-address, sign-transaction, sign-personal-message)\n // collapse to ConfirmOnDevice via the helper.\n signer.onInteraction = (interaction: string) => {\n ctx.emit('ui-event', {\n type: collapseSignerInteraction(interaction),\n payload: { sessionId },\n });\n };\n\n signer.onRegisterCanceller = (cancel: () => void) => {\n ctx.registerCanceller(sessionId, cancel);\n };\n\n return signer;\n}\n","import { deviceActionToPromise } from './deviceActionToPromise';\n\nimport type { SignerSolana as ISdkSignerSol } from '@ledgerhq/device-signer-kit-solana';\n\n// Extract parameter types from the real SignerSolana interface to avoid deep path imports.\ntype SolTxOptions = Parameters<ISdkSignerSol['signTransaction']>[2];\ntype SolMsgOptions = Parameters<ISdkSignerSol['signMessage']>[2];\n\n/**\n * Wraps Ledger's Solana SDK signer (Observable-based DeviceActions) into\n * a simple async interface returning plain serializable data.\n *\n * The Solana signer's `getAddress` returns a base58-encoded Ed25519 public key,\n * which is also the Solana address.\n */\nexport class SignerSol {\n onInteraction?: (interaction: string) => void;\n\n onRegisterCanceller?: (cancel: () => void) => void;\n\n // eslint-disable-next-line no-useless-constructor, no-empty-function\n constructor(private readonly _sdk: ISdkSignerSol) {}\n\n /**\n * Get the Solana address (base58-encoded Ed25519 public key) at the given derivation path.\n */\n async getAddress(derivationPath: string, options?: { checkOnDevice?: boolean }): Promise<string> {\n const action = this._sdk.getAddress(derivationPath, {\n checkOnDevice: options?.checkOnDevice ?? false,\n });\n return deviceActionToPromise<string>(\n action,\n this.onInteraction,\n undefined,\n this.onRegisterCanceller\n );\n }\n\n /**\n * Sign a Solana transaction.\n */\n async signTransaction(\n derivationPath: string,\n transaction: Uint8Array,\n options?: SolTxOptions\n ): Promise<Uint8Array> {\n const action = this._sdk.signTransaction(derivationPath, transaction, options);\n return deviceActionToPromise<Uint8Array>(\n action,\n this.onInteraction,\n undefined,\n this.onRegisterCanceller\n );\n }\n\n /**\n * Sign a message with the Solana app.\n * DMK returns { signature: string } for signMessage (unlike signTransaction which returns Uint8Array).\n */\n async signMessage(\n derivationPath: string,\n message: string | Uint8Array,\n options?: SolMsgOptions\n ): Promise<{ signature: string }> {\n const action = this._sdk.signMessage(derivationPath, message, options);\n return deviceActionToPromise<{ signature: string }>(\n action,\n this.onInteraction,\n undefined,\n this.onRegisterCanceller\n );\n }\n}\n","import { EConnectorInteraction, HardwareErrorCode } from '@onekeyfe/hwk-adapter-core';\nimport Trx from '@ledgerhq/hw-app-trx';\n\nimport { normalizePath } from './utils';\nimport { withLegacyAppRetry } from './legacyAppRetry';\nimport { AppManager } from '../../app/AppManager';\nimport { DmkTransport } from '../../transport/DmkTransport';\n\nimport type { ConnectorContext } from './types';\n\n// ---------------------------------------------------------------------------\n// Call param types\n// ---------------------------------------------------------------------------\n\nexport interface TronGetAddressCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\nexport interface TronSignTransactionCallParams {\n path: string;\n /** Protobuf-encoded raw transaction hex (no 0x prefix) */\n rawTxHex: string;\n /**\n * TRC token metadata for Ledger clear-signing. Omit → TRC-20 transfers\n * fall back to blind-signing (user sees only raw bytes on-device).\n */\n tokenSignatures?: string[];\n}\n\nexport interface TronSignMessageCallParams {\n path: string;\n /** Message hex (no 0x prefix) */\n messageHex: string;\n}\n\n// ---------------------------------------------------------------------------\n// Handlers\n// ---------------------------------------------------------------------------\n\nexport async function tronGetAddress(\n ctx: ConnectorContext,\n sessionId: string,\n params: TronGetAddressCallParams\n): Promise<{ address: string; publicKey: string; path: string }> {\n const path = normalizePath(params.path);\n await _ensureTronAppOpen(ctx, sessionId);\n return withLegacyAppRetry(ctx, sessionId, 'Tron', async sid => {\n const trx = await _createTrx(ctx, sid);\n if (params.showOnDevice) {\n ctx.emit('ui-event', {\n type: EConnectorInteraction.ConfirmOnDevice,\n payload: { sessionId: sid },\n });\n }\n const result = await trx.getAddress(path, params.showOnDevice ?? false);\n ctx.emit('ui-event', {\n type: EConnectorInteraction.InteractionComplete,\n payload: { sessionId: sid },\n });\n return { address: result.address, publicKey: result.publicKey, path: params.path };\n });\n}\n\nexport async function tronSignTransaction(\n ctx: ConnectorContext,\n sessionId: string,\n params: TronSignTransactionCallParams\n): Promise<{ signature: string }> {\n if (!params.rawTxHex) {\n throw Object.assign(\n new Error('TRON signing requires a protobuf-encoded raw transaction hex (rawTxHex).'),\n { code: HardwareErrorCode.InvalidParams }\n );\n }\n\n const path = normalizePath(params.path);\n await _ensureTronAppOpen(ctx, sessionId);\n return withLegacyAppRetry(ctx, sessionId, 'Tron', async sid => {\n const trx = await _createTrx(ctx, sid);\n ctx.emit('ui-event', {\n type: EConnectorInteraction.ConfirmOnDevice,\n payload: { sessionId: sid },\n });\n const signature = await trx.signTransaction(\n path,\n params.rawTxHex,\n params.tokenSignatures ?? []\n );\n ctx.emit('ui-event', {\n type: EConnectorInteraction.InteractionComplete,\n payload: { sessionId: sid },\n });\n return { signature };\n });\n}\n\nexport async function tronSignMessage(\n ctx: ConnectorContext,\n sessionId: string,\n params: TronSignMessageCallParams\n): Promise<{ signature: string }> {\n const path = normalizePath(params.path);\n await _ensureTronAppOpen(ctx, sessionId);\n return withLegacyAppRetry(ctx, sessionId, 'Tron', async sid => {\n const trx = await _createTrx(ctx, sid);\n ctx.emit('ui-event', {\n type: EConnectorInteraction.ConfirmOnDevice,\n payload: { sessionId: sid },\n });\n const signature = await trx.signPersonalMessage(path, params.messageHex);\n ctx.emit('ui-event', {\n type: EConnectorInteraction.InteractionComplete,\n payload: { sessionId: sid },\n });\n return { signature };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Internal\n// ---------------------------------------------------------------------------\n\nasync function _createTrx(ctx: ConnectorContext, sessionId: string): Promise<Trx> {\n const dmk = await ctx.getOrCreateDmk();\n return new Trx(new DmkTransport(dmk, sessionId));\n}\n\n/**\n * Proactively switch to the Tron app before sending a TRX APDU.\n *\n * Official DMK Signer kits (SignerEth / SignerBtc / SignerSol) get this for\n * free via DMK's DeviceAction pipeline — it calls `getDeviceStatus` + emits\n * `confirm-open-app` before sending any chain command. TRON can't use that\n * pipeline yet because `@ledgerhq/device-signer-kit-tron` doesn't exist; we\n * bridge `@ledgerhq/hw-app-trx` straight to `DmkTransport.exchange`, which\n * bypasses the pre-flight check.\n *\n * Without this, a TRX APDU fired while e.g. the Ethereum app is still open\n * gets answered by Ethereum (same CLA/INS, different data layout) with an\n * app-specific SW like 0x6A15. That SW is not in `WRONG_APP_CODES`, so\n * `withLegacyAppRetry` never triggers the auto-switch path and the user\n * sees \"UNKNOWN_ERROR (0x6a15)\".\n *\n * Remove this once Ledger ships `device-signer-kit-tron` and we can route\n * TRON through the same SignerManager DeviceAction flow as the other chains.\n */\nasync function _ensureTronAppOpen(\n ctx: ConnectorContext,\n sessionId: string\n): Promise<void> {\n const dmk = await ctx.getOrCreateDmk();\n const appManager = new AppManager(dmk);\n await appManager.ensureAppOpen(sessionId, 'Tron', () => {\n ctx.emit('ui-event', {\n type: EConnectorInteraction.ConfirmOpenApp,\n payload: { sessionId },\n });\n });\n}\n","import { EConnectorInteraction } from '@onekeyfe/hwk-adapter-core';\n\nimport { isWrongAppError } from '../../errors';\nimport { AppManager } from '../../app/AppManager';\n\nimport type { ConnectorContext } from './types';\n\n/**\n * Wrong-app detection for legacy SDKs. Wraps isWrongAppError so callers don't\n * depend on the shared function directly.\n *\n * Prior versions also treated \"any 4-hex code not in a per-app allowlist\" as\n * wrong-app, to catch cases where the message format hid the real status.\n * That was too aggressive: legacy hw-app-* throws TransportStatusError with a\n * numeric `statusCode` that isWrongAppError already handles via hasStatusCode,\n * so the regex path was dead weight for real errors and only fired on\n * unanticipated message shapes (random hex in logs, new firmware SWs) —\n * producing spurious app close→reopen cycles. `appName` is kept on the\n * signature for future per-app extension points.\n */\nexport function isLegacyWrongAppError(err: unknown, _appName: string): boolean {\n return isWrongAppError(err);\n}\n\n/**\n * Execute an action with automatic wrong-app retry for legacy SDK chains.\n *\n * 1. Try the action.\n * 2. If wrong-app error, use AppManager to switch to the target app.\n * 3. Retry once with the same session (session survives app switch).\n *\n * Works for any chain that uses a legacy hw-app-* SDK via DmkTransport.\n */\nexport async function withLegacyAppRetry<T>(\n ctx: ConnectorContext,\n sessionId: string,\n appName: string,\n action: (sid: string) => Promise<T>\n): Promise<T> {\n try {\n return await action(sessionId);\n } catch (err) {\n ctx.emit('ui-event', {\n type: EConnectorInteraction.InteractionComplete,\n payload: { sessionId },\n });\n if (isLegacyWrongAppError(err, appName)) {\n const dmk = await ctx.getOrCreateDmk();\n const appManager = new AppManager(dmk);\n try {\n await appManager.ensureAppOpen(sessionId, appName, () => {\n // Device is showing the confirm prompt — now it's safe to notify UI\n ctx.emit('ui-event', {\n type: EConnectorInteraction.ConfirmOpenApp,\n payload: { sessionId },\n });\n });\n } catch (switchErr) {\n ctx.emit('ui-event', {\n type: EConnectorInteraction.InteractionComplete,\n payload: { sessionId },\n });\n throw ctx.wrapError(switchErr);\n }\n ctx.clearAllSigners();\n ctx.emit('ui-event', {\n type: EConnectorInteraction.InteractionComplete,\n payload: { sessionId },\n });\n return await action(sessionId);\n }\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n }\n}\n","import {\n CloseAppCommand,\n type DeviceManagementKit,\n GetAppAndVersionCommand,\n OpenAppCommand,\n isSuccessCommandResult,\n} from '@ledgerhq/device-management-kit';\n\n/**\n * Map of chain ticker symbols to the Ledger app name\n * that must be open to sign transactions for that chain.\n */\nexport const APP_NAME_MAP: Record<string, string> = {\n ETH: 'Ethereum',\n BTC: 'Bitcoin',\n SOL: 'Solana',\n TRX: 'Tron',\n XRP: 'XRP',\n ADA: 'Cardano',\n DOT: 'Polkadot',\n ATOM: 'Cosmos',\n};\n\n/** The name reported by the Ledger when it sits on the home screen. */\nconst DASHBOARD_APP_NAME = 'BOLOS';\n\ninterface AppManagerOptions {\n waitMs?: number;\n maxRetries?: number;\n}\n\n/**\n * Orchestrates opening / closing Ledger on-device apps so that the\n * correct signer application is running before any signing call.\n */\nexport class AppManager {\n private readonly _dmk: DeviceManagementKit;\n\n private readonly _waitMs: number;\n\n private readonly _maxRetries: number;\n\n constructor(dmk: DeviceManagementKit, options?: AppManagerOptions) {\n this._dmk = dmk;\n this._waitMs = options?.waitMs ?? 1000;\n this._maxRetries = options?.maxRetries ?? 10;\n }\n\n /**\n * Return the Ledger app name for a given chain ticker,\n * or undefined if the chain is not supported.\n */\n static getAppName(chain: string): string | undefined {\n return APP_NAME_MAP[chain];\n }\n\n /**\n * Ensure the target app is open on the device identified by `sessionId`.\n *\n * Flow:\n * 1. Check the currently running app.\n * 2. If it is already the target, return immediately.\n * 3. If a different app is running (not dashboard), close it first.\n * 4. Open the target app.\n * 5. Poll until the device confirms the target app is running.\n */\n /**\n * @param onConfirmOnDevice Called after OpenAppCommand succeeds —\n * the device is now showing a confirmation prompt to the user.\n * NOT called if the app is already open or if the app is not installed.\n */\n async ensureAppOpen(\n sessionId: string,\n targetAppName: string,\n onConfirmOnDevice?: () => void\n ): Promise<void> {\n const currentApp = await this._getCurrentApp(sessionId);\n\n if (currentApp === targetAppName) {\n return;\n }\n\n // If we're not on the dashboard, close the current app first\n if (!this._isDashboard(currentApp)) {\n await this._closeCurrentApp(sessionId);\n // Wait for dashboard to become active\n await this._waitForApp(sessionId, DASHBOARD_APP_NAME);\n }\n\n // Open the target app — throws if not installed (0x6807)\n await this._openApp(sessionId, targetAppName);\n\n // Device is now showing the confirm prompt\n onConfirmOnDevice?.();\n\n // Poll until the target app is confirmed open\n await this._waitForApp(sessionId, targetAppName);\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private async _getCurrentApp(sessionId: string): Promise<string> {\n const result = await this._dmk.sendCommand({\n sessionId,\n command: new GetAppAndVersionCommand(),\n });\n if (isSuccessCommandResult(result)) {\n return result.data.name;\n }\n throw new Error('Failed to get current app from device');\n }\n\n private async _openApp(sessionId: string, appName: string): Promise<void> {\n const result = await this._dmk.sendCommand({\n sessionId,\n command: new OpenAppCommand({ appName }),\n });\n if (!isSuccessCommandResult(result)) {\n const { statusCode } = result as Record<string, unknown>;\n throw Object.assign(new Error(`Failed to open \"${appName}\"`), {\n _tag: 'OpenAppCommandError',\n errorCode: String(statusCode ?? ''),\n statusCode,\n appName,\n });\n }\n }\n\n private async _closeCurrentApp(sessionId: string): Promise<void> {\n await this._dmk.sendCommand({\n sessionId,\n command: new CloseAppCommand(),\n });\n }\n\n /**\n * Poll the device until the expected app is reported as running,\n * or throw after `_maxRetries` attempts.\n */\n private async _waitForApp(sessionId: string, expectedAppName: string): Promise<void> {\n for (let i = 0; i < this._maxRetries; i++) {\n await this._wait();\n const current = await this._getCurrentApp(sessionId);\n if (current === expectedAppName) {\n return;\n }\n }\n throw new Error(\n `Ledger: failed to open \"${expectedAppName}\" after ${this._maxRetries} retries`\n );\n }\n\n private _isDashboard(appName: string): boolean {\n return appName === DASHBOARD_APP_NAME;\n }\n\n private _wait(): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, this._waitMs));\n }\n}\n","import Transport from '@ledgerhq/hw-transport';\n\nimport type { DeviceManagementKit } from '@ledgerhq/device-management-kit';\n\n/**\n * Transport adapter that bridges Ledger's legacy hw-app-* SDKs to DMK's sendApdu.\n *\n * Legacy SDKs (hw-app-trx, hw-app-xrp, etc.) require a Transport instance.\n * This adapter wraps DMK's session-based sendApdu so legacy SDKs can run\n * over DMK's transport layer without a separate USB/HID connection.\n *\n * Usage:\n * const transport = new DmkTransport(dmk, sessionId);\n * const trx = new Trx(transport);\n * const address = await trx.getAddress(\"44'/195'/0'/0/0\");\n */\nexport class DmkTransport extends Transport {\n private _dmk: DeviceManagementKit;\n\n private _sessionId: string;\n\n constructor(dmk: DeviceManagementKit, sessionId: string) {\n super();\n this._dmk = dmk;\n this._sessionId = sessionId;\n }\n\n async exchange(apdu: Buffer): Promise<Buffer> {\n const response = await this._dmk.sendApdu({\n sessionId: this._sessionId,\n apdu: new Uint8Array(apdu),\n });\n\n // Legacy format: data + statusCode (2 bytes) concatenated\n const { data, statusCode } = response;\n const result = Buffer.alloc(data.length + 2);\n if (data.length > 0) {\n result.set(data, 0);\n }\n result.set(statusCode, data.length);\n return result;\n }\n\n async close(): Promise<void> {\n // DMK manages session lifecycle\n }\n}\n","import { LedgerDeviceManager } from '../device/LedgerDeviceManager';\nimport { SignerManager } from '../signer/SignerManager';\nimport { mapLedgerError } from '../errors';\nimport { debugLog } from '../utils/debugLog';\nimport {\n btcGetAddress,\n btcGetMasterFingerprint,\n btcGetPublicKey,\n btcSignMessage,\n btcSignPsbt,\n btcSignTransaction,\n evmGetAddress,\n evmSignMessage,\n evmSignTransaction,\n evmSignTypedData,\n solGetAddress,\n solSignMessage,\n solSignTransaction,\n tronGetAddress,\n tronSignMessage,\n tronSignTransaction,\n} from './chains';\n\nimport type { ConnectorContext } from './chains/types';\nimport type { DeviceManagementKit } from '@ledgerhq/device-management-kit';\nimport type {\n ConnectionType,\n ConnectorDevice,\n ConnectorEventMap,\n ConnectorEventType,\n ConnectorSession,\n DeviceDescriptor,\n IConnector,\n TronSignMsgParams,\n UiResponseEvent,\n} from '@onekeyfe/hwk-adapter-core';\nimport type {\n BtcGetAddressCallParams,\n BtcGetPublicKeyCallParams,\n BtcSignMessageCallParams,\n BtcSignPsbtCallParams,\n BtcSignTransactionCallParams,\n EvmGetAddressCallParams,\n EvmSignMessageCallParams,\n EvmSignTransactionCallParams,\n EvmSignTypedDataCallParams,\n SolGetAddressCallParams,\n SolSignMessageCallParams,\n SolSignTransactionCallParams,\n TronGetAddressCallParams,\n TronSignMessageCallParams,\n TronSignTransactionCallParams,\n} from './chains';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * A function that lazily loads and returns the transport factory\n * for the Ledger DMK builder (e.g. webHidTransportFactory, rnBleTransportFactory).\n */\nexport type TransportFactory = () => Promise<unknown>;\n\nexport interface LedgerConnectorBaseOptions {\n /**\n * Pre-built DMK instance. If not provided, a DMK will be created\n * lazily on first use via the transport factory.\n */\n dmk?: DeviceManagementKit;\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ntype EventHandler<K extends ConnectorEventType> = (data: ConnectorEventMap[K]) => void;\n\n// ---------------------------------------------------------------------------\n// Default signer kit importer (webpack/rspack — uses \"exports\" field)\n// ---------------------------------------------------------------------------\n\n/**\n * Default importer for Ledger signer kit packages.\n * Uses bare module specifiers — works with bundlers that support \"exports\".\n * Metro (React Native) can't resolve these; pass a custom importer that\n * uses CJS paths (e.g. `@ledgerhq/device-signer-kit-ethereum/lib/cjs/index.js`).\n */\nasync function defaultLedgerKitImporter(pkg: string): Promise<any> {\n switch (pkg) {\n case '@ledgerhq/device-management-kit':\n return import('@ledgerhq/device-management-kit');\n case '@ledgerhq/device-signer-kit-ethereum':\n return import('@ledgerhq/device-signer-kit-ethereum');\n case '@ledgerhq/device-signer-kit-bitcoin':\n return import('@ledgerhq/device-signer-kit-bitcoin');\n case '@ledgerhq/device-signer-kit-solana':\n return import('@ledgerhq/device-signer-kit-solana');\n case '@ledgerhq/context-module':\n return import('@ledgerhq/context-module');\n default:\n throw new Error(`Unknown Ledger kit package: ${pkg}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// LedgerConnectorBase\n// ---------------------------------------------------------------------------\n\n/**\n * Shared base class for Ledger IConnector implementations.\n *\n * Encapsulates all shared logic: device discovery, connection management,\n * method dispatch (EVM / BTC / SOL / TRON), signer lifecycle, event emission,\n * and error handling.\n *\n * Chain-specific method implementations live in `./chains/` and receive\n * a ConnectorContext that exposes shared helpers.\n *\n * Subclasses only need to:\n * 1. Supply a transport factory via the constructor.\n * 2. Optionally override `_resolveConnectId()` for transport-specific\n * device identity resolution (e.g. BLE hex ID extraction).\n */\nexport class LedgerConnectorBase implements IConnector {\n private _deviceManager: LedgerDeviceManager | null = null;\n\n private _signerManager: SignerManager | null = null;\n\n private _dmk: DeviceManagementKit | null = null;\n\n private readonly _eventHandlers = new Map<\n ConnectorEventType,\n Set<EventHandler<ConnectorEventType>>\n >();\n\n private readonly _providedDmk: DeviceManagementKit | undefined;\n\n private readonly _createTransport: TransportFactory;\n\n public readonly connectionType: ConnectionType;\n\n // ---------------------------------------------------------------------------\n // ConnectId <-> DMK path mapping\n //\n // DMK uses internal paths (BLE MAC, USB UUID) that may change across sessions.\n // _resolveConnectId() maps these to stable external IDs (BLE: \"A58F\", USB: same).\n // This bidirectional map is the SINGLE SOURCE OF TRUTH for all connectId usage.\n // ---------------------------------------------------------------------------\n private _connectIdToPath = new Map<string, string>(); // \"A58F\" -> \"D5:75:7D:4B:51:E8\"\n\n private _pathToConnectId = new Map<string, string>(); // \"D5:75:7D:4B:51:E8\" -> \"A58F\"\n\n /** Register a connectId <-> path mapping from a device descriptor. */\n private _registerDeviceId(descriptor: DeviceDescriptor): string {\n const connectId = this._resolveConnectId(descriptor);\n this._connectIdToPath.set(connectId, descriptor.path);\n this._pathToConnectId.set(descriptor.path, connectId);\n return connectId;\n }\n\n /** Get DMK path from external connectId. Falls back to connectId itself. */\n private _getPathForConnectId(connectId: string): string {\n return this._connectIdToPath.get(connectId) ?? connectId;\n }\n\n /** Get external connectId from DMK path. Falls back to path itself. */\n private _getConnectIdForPath(path: string): string {\n return this._pathToConnectId.get(path) ?? path;\n }\n\n // ---------------------------------------------------------------------------\n // Per-session DeviceAction cancellers\n //\n // Each chain handler registers its active DeviceAction's canceller via\n // ctx.registerCanceller(sessionId, cancel) and clears it on completion.\n // IConnector.cancel(sessionId) invokes the registered canceller, which\n // unsubscribes the observable and releases DMK's IntentQueue slot.\n // ---------------------------------------------------------------------------\n private readonly _cancellers = new Map<string, () => void>();\n\n /**\n * Resolves a Ledger signer kit module by package name.\n * Override via constructor to use CJS paths for Metro (React Native).\n * Default: dynamic import with bare specifier (webpack/rspack).\n */\n protected _importLedgerKit: (pkg: string) => Promise<any>;\n\n /** Context object passed to per-chain handler functions. */\n private readonly _ctx: ConnectorContext;\n\n constructor(\n createTransport: TransportFactory,\n options?: {\n connectionType?: ConnectionType;\n dmk?: DeviceManagementKit;\n /**\n * Override how `@ledgerhq/device-signer-kit-*` packages are imported.\n * Default: `(pkg) => import(pkg)` — works with webpack/rspack.\n * For Metro (React Native): pass a resolver that uses CJS paths.\n */\n importLedgerKit?: (pkg: string) => Promise<any>;\n }\n ) {\n this._createTransport = createTransport;\n this.connectionType = options?.connectionType ?? 'usb';\n this._providedDmk = options?.dmk;\n this._importLedgerKit = options?.importLedgerKit ?? defaultLedgerKitImporter;\n if (this._providedDmk) {\n this._initManagers(this._providedDmk);\n }\n\n // Build the context that chain handlers use\n this._ctx = {\n emit: <K extends ConnectorEventType>(event: K, data: ConnectorEventMap[K]) =>\n this._emit(event, data),\n invalidateSession: sid => this._invalidateSession(sid),\n wrapError: err => this._wrapError(err),\n getOrCreateDmk: () => this._getOrCreateDmk(),\n getDeviceManager: () => this._getDeviceManager(),\n getSignerManager: () => this._getSignerManager(),\n clearAllSigners: () => this._signerManager?.clearAll(),\n replaceSession: (oldSid, newSid) => this._replaceSession(oldSid, newSid),\n registerCanceller: (sid, cancel) => this._cancellers.set(sid, cancel),\n clearCanceller: sid => this._cancellers.delete(sid),\n importLedgerKit: this._importLedgerKit,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Protected — hooks for subclasses\n // ---------------------------------------------------------------------------\n\n /**\n * Resolve the connectId for a discovered device descriptor.\n * Default: use the DMK path (ephemeral UUID).\n * Override in subclasses to extract stable identifiers (e.g. BLE hex ID).\n */\n protected _resolveConnectId(descriptor: DeviceDescriptor): string {\n return descriptor.path;\n }\n\n // ---------------------------------------------------------------------------\n // IConnector -- Device discovery\n // ---------------------------------------------------------------------------\n\n async searchDevices(): Promise<ConnectorDevice[]> {\n const dm = await this._getDeviceManager();\n\n let descriptors = await dm.enumerate();\n\n // If no devices found, trigger permission dialog / BLE scanning via startDiscovering\n if (descriptors.length === 0) {\n try {\n await dm.requestDevice();\n } catch {\n // User may cancel the permission dialog -- that's OK\n }\n descriptors = await dm.enumerate();\n }\n\n const result: ConnectorDevice[] = descriptors.map(d => {\n const connectId = this._registerDeviceId(d);\n return {\n connectId,\n deviceId: d.path,\n name: d.name || d.type || 'Ledger',\n model: d.type,\n };\n });\n return result;\n }\n\n // ---------------------------------------------------------------------------\n // IConnector -- Connection\n // ---------------------------------------------------------------------------\n\n async connect(deviceId?: string): Promise<ConnectorSession> {\n const dm = await this._getDeviceManager();\n await this.searchDevices();\n\n // Resolve external connectId -> DMK path via mapping table\n const dmkPath = deviceId ? this._getPathForConnectId(deviceId) : undefined;\n\n // If no path found, pick first available device\n let targetPath = dmkPath;\n if (!targetPath) {\n const descriptors = await dm.enumerate();\n if (descriptors.length === 0) {\n throw new Error(\n `No Ledger device found. Make sure the device is connected${\n this.connectionType === 'ble' ? ' nearby with Bluetooth enabled' : ' via USB'\n } and unlocked.`\n );\n }\n targetPath = descriptors[0].path;\n }\n\n // External connectId for session/events — always use the mapped ID\n const externalConnectId = this._getConnectIdForPath(targetPath);\n\n const doConnect = async (path: string): Promise<ConnectorSession> => {\n const sessionId = await dm.connect(path);\n const session: ConnectorSession = {\n sessionId,\n deviceInfo: {\n vendor: 'ledger',\n model: 'unknown',\n firmwareVersion: 'unknown',\n deviceId: path,\n connectId: externalConnectId,\n connectionType: this.connectionType,\n capabilities: { persistentDeviceIdentity: false },\n },\n };\n this._emit('device-connect', {\n device: {\n connectId: externalConnectId,\n deviceId: path,\n name: 'Ledger',\n },\n });\n return session;\n };\n\n try {\n return await doConnect(targetPath);\n } catch {\n // Retry once: clear signer state but keep DMK (and BLE scan) alive\n this._resetSignersAndSessions();\n const dm2 = await this._getDeviceManager();\n await this.searchDevices();\n\n // Re-resolve path — device may have been re-discovered with new DMK path\n const retryPath = this._getPathForConnectId(externalConnectId);\n if (!retryPath || retryPath === externalConnectId) {\n // Mapping not found — try first available\n const descriptors = await dm2.enumerate();\n if (descriptors.length === 0) {\n throw new Error(\n `No Ledger device found after retry. Make sure the device is connected${\n this.connectionType === 'ble' ? ' nearby with Bluetooth enabled' : ' via USB'\n } and unlocked.`\n );\n }\n return doConnect(descriptors[0].path);\n }\n return doConnect(retryPath);\n }\n }\n\n async disconnect(sessionId: string): Promise<void> {\n if (!this._deviceManager) return;\n\n const deviceId = this._deviceManager.getDeviceId(sessionId);\n this._signerManager?.invalidate(sessionId);\n await this._deviceManager.disconnect(sessionId);\n\n if (deviceId) {\n this._emit('device-disconnect', { connectId: deviceId });\n }\n }\n\n // ---------------------------------------------------------------------------\n // IConnector -- Method dispatch\n // ---------------------------------------------------------------------------\n\n async call(sessionId: string, method: string, params: unknown): Promise<unknown> {\n debugLog('[DMK] call:', method, JSON.stringify(params));\n switch (method) {\n // EVM\n case 'evmGetAddress':\n return evmGetAddress(this._ctx, sessionId, params as EvmGetAddressCallParams);\n case 'evmSignTransaction':\n return evmSignTransaction(this._ctx, sessionId, params as EvmSignTransactionCallParams);\n case 'evmSignMessage':\n return evmSignMessage(this._ctx, sessionId, params as EvmSignMessageCallParams);\n case 'evmSignTypedData':\n return evmSignTypedData(this._ctx, sessionId, params as EvmSignTypedDataCallParams);\n // BTC\n case 'btcGetAddress':\n return btcGetAddress(this._ctx, sessionId, params as BtcGetAddressCallParams);\n case 'btcGetPublicKey':\n return btcGetPublicKey(this._ctx, sessionId, params as BtcGetPublicKeyCallParams);\n case 'btcSignTransaction':\n return btcSignTransaction(this._ctx, sessionId, params as BtcSignTransactionCallParams);\n case 'btcSignPsbt':\n return btcSignPsbt(this._ctx, sessionId, params as BtcSignPsbtCallParams);\n case 'btcSignMessage':\n return btcSignMessage(this._ctx, sessionId, params as BtcSignMessageCallParams);\n case 'btcGetMasterFingerprint':\n return btcGetMasterFingerprint(\n this._ctx,\n sessionId,\n params as { skipOpenApp?: boolean } | undefined\n );\n // SOL\n case 'solGetAddress':\n return solGetAddress(this._ctx, sessionId, params as SolGetAddressCallParams);\n case 'solSignTransaction':\n return solSignTransaction(this._ctx, sessionId, params as SolSignTransactionCallParams);\n case 'solSignMessage':\n return solSignMessage(this._ctx, sessionId, params as SolSignMessageCallParams);\n // TRON\n case 'tronGetAddress':\n return tronGetAddress(this._ctx, sessionId, params as TronGetAddressCallParams);\n case 'tronSignTransaction':\n return tronSignTransaction(this._ctx, sessionId, params as TronSignTransactionCallParams);\n case 'tronSignMessage': {\n // Explicit public→internal mapping so a field-name drift fails at\n // compile time, not silently at runtime (see bug: public `messageHex`\n // vs internal `messageHex` field name enforcement).\n const p = params as TronSignMsgParams;\n const internalParams: TronSignMessageCallParams = {\n path: p.path,\n messageHex: p.messageHex,\n };\n return tronSignMessage(this._ctx, sessionId, internalParams);\n }\n default:\n throw new Error(`LedgerConnector: unknown method \"${method}\"`);\n }\n }\n\n async cancel(sessionId: string): Promise<void> {\n // Invoke the active DeviceAction canceller (registered by the chain handler).\n // This unsubscribes the observable and releases DMK's IntentQueue slot so\n // the next call on this session isn't blocked behind an orphaned intent.\n //\n // Note: Ledger devices have no hardware-level APDU abort. If the user has\n // an on-device confirmation prompt pending, it will remain until the user\n // presses Reject or the device times out.\n const cancel = this._cancellers.get(sessionId);\n if (cancel) {\n this._cancellers.delete(sessionId);\n try {\n cancel();\n } catch {\n // canceller may have already been invoked; ignore\n }\n }\n }\n\n uiResponse(_response: UiResponseEvent): void {\n // Ledger does not use interactive UI responses (PIN/passphrase)\n }\n\n // ---------------------------------------------------------------------------\n // IConnector -- Events\n // ---------------------------------------------------------------------------\n\n on<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler as EventHandler<ConnectorEventType>);\n }\n\n off<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void {\n this._eventHandlers.get(event)?.delete(handler as EventHandler<ConnectorEventType>);\n }\n\n // ---------------------------------------------------------------------------\n // IConnector -- Reset\n // ---------------------------------------------------------------------------\n\n reset(): void {\n this._resetAll();\n }\n\n // ---------------------------------------------------------------------------\n // Private -- DMK / Manager lifecycle\n // ---------------------------------------------------------------------------\n\n /**\n * Lazily create or return the DMK instance.\n * If a DMK was provided via constructor, it is used directly.\n * Otherwise, one is created via the transport factory.\n */\n protected async _getOrCreateDmk(): Promise<DeviceManagementKit> {\n debugLog(\n '[DMK] _getOrCreateDmk called, _dmk exists:',\n !!this._dmk,\n '_providedDmk exists:',\n !!this._providedDmk\n );\n if (this._dmk) return this._dmk;\n\n if (this._providedDmk) {\n this._dmk = this._providedDmk;\n return this._dmk;\n }\n\n const { DeviceManagementKitBuilder } = await this._importLedgerKit(\n '@ledgerhq/device-management-kit'\n );\n const transportFactory = await this._createTransport();\n\n debugLog('[DMK] _getOrCreateDmk: transportFactory type:', typeof transportFactory);\n\n const dmk: DeviceManagementKit = new DeviceManagementKitBuilder()\n .addTransport(transportFactory)\n .build();\n this._dmk = dmk;\n\n debugLog('[DMK] _getOrCreateDmk: DMK created');\n\n return dmk;\n }\n\n private _initManagers(dmk: DeviceManagementKit): void {\n this._dmk = dmk;\n this._deviceManager = new LedgerDeviceManager(dmk);\n\n // Pass a custom ETH signer builder that uses _importLedgerKit,\n // so the BLE connector's CJS override applies to ETH too.\n const importKit = this._importLedgerKit;\n this._signerManager = new SignerManager(dmk, async args => {\n const mod = await importKit('@ledgerhq/device-signer-kit-ethereum');\n return new mod.SignerEthBuilder(args);\n });\n }\n\n private async _getDeviceManager(): Promise<LedgerDeviceManager> {\n if (this._deviceManager) return this._deviceManager;\n\n const dmk = await this._getOrCreateDmk();\n this._initManagers(dmk);\n return this._deviceManager!;\n }\n\n private async _getSignerManager(): Promise<SignerManager> {\n if (!this._signerManager) {\n const dmk = await this._getOrCreateDmk();\n this._initManagers(dmk);\n }\n return this._signerManager!;\n }\n\n private _invalidateSession(sessionId: string): void {\n this._signerManager?.invalidate(sessionId);\n }\n\n /**\n * Replace an old session with a new one after app switch.\n * Updates the connectId→path mapping so subsequent calls() use the new session,\n * and emits device-connect so the adapter updates its _sessions Map.\n */\n private _replaceSession(oldSessionId: string, _newSessionId: string): void {\n // Find the connectId that was mapped to the old session's device path\n const dm = this._deviceManager;\n if (!dm) return;\n\n const oldDeviceId = dm.getDeviceId(oldSessionId);\n const connectId = oldDeviceId ? this._pathToConnectId.get(oldDeviceId) : undefined;\n\n // Invalidate old signer cache\n this._signerManager?.invalidate(oldSessionId);\n\n // Emit device-connect so the adapter picks up the new session\n if (connectId) {\n this._emit('device-connect', {\n device: {\n connectId,\n deviceId: connectId,\n name: 'Ledger',\n },\n });\n }\n }\n\n /**\n * Light reset: clear signer/session state but keep DMK, BLE scan, and ID mapping alive.\n * Used by connect() retry — we want to re-discover with the same transport.\n */\n private _resetSignersAndSessions(): void {\n debugLog('[DMK] _resetSignersAndSessions called');\n this._signerManager?.clearAll();\n this._signerManager = null;\n this._deviceManager = null;\n }\n\n private _resetAll(): void {\n debugLog('[DMK] _resetAll called');\n // Cancel any in-flight DeviceActions so their observables unsubscribe\n // and DMK's intent queues don't keep orphaned slots alive.\n for (const cancel of this._cancellers.values()) {\n try {\n cancel();\n } catch {\n // already cancelled / settled — ignore\n }\n }\n this._cancellers.clear();\n this._signerManager?.clearAll();\n this._deviceManager?.dispose();\n this._deviceManager = null;\n this._signerManager = null;\n this._dmk = null;\n this._connectIdToPath.clear();\n this._pathToConnectId.clear();\n }\n\n // ---------------------------------------------------------------------------\n // Private -- Events\n // ---------------------------------------------------------------------------\n\n protected _emit<K extends ConnectorEventType>(event: K, data: ConnectorEventMap[K]): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n for (const handler of handlers) {\n try {\n handler(data);\n } catch {\n // Don't let listener errors break the connector\n }\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private -- Error handling\n // ---------------------------------------------------------------------------\n\n private _wrapError(err: unknown): Error {\n const mapped = mapLedgerError(err);\n const error = new Error(mapped.message);\n const src = (err && typeof err === 'object' ? err : {}) as Record<string, unknown>;\n // Preserve DMK / EthAppCommandError fields so downstream classifiers\n // (including cross-layer `wrapError` → caller re-classification) can still\n // key on APDU code and step context attached by deviceActionToPromise.\n Object.assign(error, {\n code: mapped.code,\n appName: mapped.appName,\n _tag: src._tag,\n errorCode: src.errorCode,\n _lastStep: src._lastStep,\n });\n // Non-enumerable: DMK errors can carry APDU payloads / signing\n // intermediates that shouldn't leak into JSON.stringify / log transports.\n Object.defineProperty(error, 'originalError', {\n value: err,\n configurable: true,\n enumerable: false,\n writable: true,\n });\n return error;\n }\n}\n","/**\n * Extract the stable 4-digit HEX identifier from a Ledger BLE device name.\n * e.g., \"Nano X 123A\" -> \"123A\", \"Ledger Nano X AB12\" -> \"AB12\"\n * Returns undefined if no valid HEX suffix found.\n */\nexport function extractBleHexId(name?: string): string | undefined {\n if (!name) return undefined;\n const match = name.match(/\\b([0-9A-Fa-f]{4})$/);\n return match ? match[1].toUpperCase() : undefined;\n}\n"],"mappings":"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","names":["import_hwk_adapter_core","import_hwk_adapter_core","import_hwk_adapter_core","import_hwk_adapter_core","import_hwk_adapter_core","import_hwk_adapter_core","INTERACTIVE_TIMEOUT_MS","import_hwk_adapter_core","ContextModuleBuilder","import_hwk_adapter_core","import_hwk_adapter_core","import_device_management_kit","Transport","Trx"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/adapter/LedgerAdapter.ts","../src/errors.ts","../src/utils/debugLog.ts","../src/device/LedgerDeviceManager.ts","../src/signer/SignerManager.ts","../src/signer/SignerEth.ts","../src/signer/deviceActionToPromise.ts","../src/connector/chains/evm.ts","../src/connector/chains/utils.ts","../src/connector/chains/btc.ts","../src/signer/SignerBtc.ts","../src/connector/chains/sol.ts","../src/signer/SignerSol.ts","../src/connector/chains/tron.ts","../src/connector/chains/legacyAppRetry.ts","../src/app/AppManager.ts","../src/transport/DmkTransport.ts","../src/connector/LedgerConnectorBase.ts","../src/utils/bleIdentity.ts"],"sourcesContent":["// Adapter\nexport { LedgerAdapter } from './adapter/LedgerAdapter';\n\n// Connector base class (used by connector packages)\nexport { LedgerConnectorBase } from './connector/LedgerConnectorBase';\nexport type { TransportFactory, LedgerConnectorBaseOptions } from './connector/LedgerConnectorBase';\n\n// Device management (used by connectors)\nexport { LedgerDeviceManager } from './device/LedgerDeviceManager';\n\n// Signer (used by connectors)\nexport { SignerManager } from './signer/SignerManager';\nexport { SignerEth } from './signer/SignerEth';\nexport { SignerBtc } from './signer/SignerBtc';\nexport { SignerSol } from './signer/SignerSol';\nexport { DmkTransport } from './transport/DmkTransport';\nexport { deviceActionToPromise } from './signer/deviceActionToPromise';\n\n// App management\nexport { AppManager } from './app/AppManager';\n\n// Types\nexport type {\n DmkDiscoveredDevice,\n DeviceActionState,\n SignerEvmAddress,\n SignerEvmSignature,\n SignerBtcAddress,\n} from './types';\n\n// Errors\nexport { isDeviceLockedError, ledgerFailure, mapLedgerError } from './errors';\nexport type { LedgerFailure } from './errors';\n\n// Debug logging (opt-in)\nexport { setDebugEnabled, isDebugEnabled } from './utils/debugLog';\n\n// BLE utilities (shared by connector packages)\nexport { extractBleHexId } from './utils/bleIdentity';\n","import {\n CHAIN_FINGERPRINT_PATHS,\n DEVICE,\n DeviceJobQueue,\n HardwareErrorCode,\n TypedEventEmitter,\n UI_REQUEST,\n UiRequestRegistry,\n deriveDeviceFingerprint,\n failure,\n success,\n} from '@onekeyfe/hwk-adapter-core';\n\nimport {\n isDeviceDisconnectedError,\n isDeviceLockedError,\n isTimeoutError,\n ledgerFailure,\n mapLedgerError,\n} from '../errors';\nimport { debugError, debugLog } from '../utils/debugLog';\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 ConnectionType,\n ConnectorDevice,\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 Interruptibility,\n ProgressCallback,\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';\n\nexport interface LedgerAdapterOptions {\n /**\n * `true` — emit `REQUEST_SELECT_DEVICE` on multi-device discovery and await\n * `uiResponse({ type: RECEIVE_SELECT_DEVICE, payload: { sdkConnectId } })`.\n * `false` (default) — silently pick the first device.\n */\n handleSelectDevice?: boolean;\n}\n\n/**\n * Result of `_verifyDeviceFingerprint`.\n *\n * On mismatch carries both the stored (expected) fingerprint and the\n * live (actual) one derived from the physically connected device.\n * Callers turn this into a `DeviceMismatch` failure via `formatDeviceMismatchError`.\n */\ntype IFingerprintVerifyResult =\n | { success: true }\n | { success: false; expected: string; actual: string };\n\n/**\n * Single source of truth for the `DeviceMismatch` error message.\n * Both fingerprints are 16-char deterministic hashes of fixed-path\n * testnet addresses — not secrets — so they're safe to surface in logs.\n */\nfunction formatDeviceMismatchError(expected: string, actual: string): string {\n return `Wrong device: expected ${expected}, got ${actual}`;\n}\n\n/**\n * Ledger hardware wallet adapter that delegates to an IConnector.\n *\n * This is a thin translation layer that:\n * - Accepts a pre-configured IConnector (transport decisions are made at connector creation time)\n * - Translates IHardwareWallet method calls to connector.call() invocations\n * - Maps connector results/errors to our Response<T> format with enriched error messages\n * - Translates connector events to HardwareEventMap events\n * - Emits `REQUEST_DEVICE_PERMISSION` for OS-level permission checks\n */\nexport class LedgerAdapter implements IHardwareWallet {\n readonly vendor = 'ledger' as const;\n\n private readonly connector: IConnector;\n\n private readonly emitter = new TypedEventEmitter<HardwareEventMap>();\n\n private readonly _handleSelectDevice: boolean;\n\n // Device cache: tracks discovered devices from connector events\n private _discoveredDevices = new Map<string, DeviceInfo>();\n\n // Session tracking: maps connectId -> sessionId\n private _sessions = new Map<string, string>();\n\n private readonly _uiRegistry = new UiRequestRegistry();\n\n // Per-device serial job queue. Operations for the same device run sequentially;\n // conflicting ops are dispatched per `interruptibility` (see _getInterruptibility).\n private readonly _jobQueue: DeviceJobQueue;\n\n constructor(connector: IConnector, options?: LedgerAdapterOptions) {\n this.connector = connector;\n this._handleSelectDevice = options?.handleSelectDevice ?? false;\n this._jobQueue = new DeviceJobQueue({\n emit: (event, data) => this.emitter.emit(event, data),\n uiRegistry: this._uiRegistry,\n });\n this.registerEventListeners();\n }\n\n /**\n * Classify a method's interruptibility.\n * - Signing / typed data / transaction → 'confirm' (user may decide via preemption UI)\n * - Read-only queries (getAddress / getPublicKey / getMasterFingerprint) → 'safe'\n * (auto-cancels any pending read for the same device)\n */\n private static _getInterruptibility(method: string): Interruptibility {\n if (method.toLowerCase().includes('sign')) return 'confirm';\n return 'safe';\n }\n\n // ---------------------------------------------------------------------------\n // Transport\n // ---------------------------------------------------------------------------\n // Transport is decided at connector creation time. These methods\n // satisfy the IHardwareWallet interface with sensible defaults.\n\n get activeTransport(): TransportType | null {\n // Ledger all-current-models use USB-HID for wired connection.\n return this.connector.connectionType === 'ble' ? 'ble' : 'hid';\n }\n\n getAvailableTransports(): TransportType[] {\n return this.activeTransport ? [this.activeTransport] : [];\n }\n\n async switchTransport(_type: TransportType): Promise<void> {\n // Ledger binds a single connector (transport) at construction time.\n // To use a different transport, create a new adapter with a different connector.\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n async init(_config?: unknown): Promise<void> {\n // Connector is injected via constructor, already initialized.\n // Nothing to do here.\n }\n\n /**\n * Clear cached device/session state without tearing down the adapter.\n * Call before retrying after errors or when the device state may be stale.\n * The next operation will re-discover and re-connect automatically.\n */\n resetState(): void {\n this._discoveredDevices.clear();\n this._sessions.clear();\n this._connectingPromise = null;\n this._uiRegistry.reset();\n this._jobQueue.clear();\n }\n\n async dispose(): Promise<void> {\n this._uiRegistry.reset();\n this._jobQueue.clear();\n this.unregisterEventListeners();\n this.connector.reset();\n this._discoveredDevices.clear();\n this._sessions.clear();\n this.emitter.removeAllListeners();\n }\n\n uiResponse(response: UiResponseEvent): void {\n this._uiRegistry.resolve(response.type, response.payload);\n }\n\n // ---------------------------------------------------------------------------\n // Device management\n // ---------------------------------------------------------------------------\n\n async searchDevices(): Promise<DeviceInfo[]> {\n await this._ensureDevicePermission();\n\n const devices = await this.connector.searchDevices();\n debugLog('[DMK] adapter.searchDevices raw:', JSON.stringify(devices));\n\n // Update cache with scan results. connectId is now consistent\n // (BLE: \"A58F\" from _resolveConnectId, USB: DMK path) across all write points.\n for (const d of devices) {\n if (d.connectId) {\n this._discoveredDevices.set(d.connectId, this.connectorDeviceToDeviceInfo(d));\n }\n }\n\n // If no devices found, ensure permission (no connectId = search context)\n if (this._discoveredDevices.size === 0) {\n await this._ensureDevicePermission();\n }\n\n return Array.from(this._discoveredDevices.values());\n }\n\n async connectDevice(connectId: string): Promise<Response<string>> {\n await this._ensureDevicePermission(connectId);\n try {\n const session = await this.connector.connect(connectId);\n this._sessions.set(connectId, session.sessionId);\n\n // Update device cache with richer info from session\n if (session.deviceInfo) {\n this._discoveredDevices.set(connectId, session.deviceInfo);\n }\n\n return success(connectId);\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async disconnectDevice(connectId: string): Promise<void> {\n const sessionId = this._sessions.get(connectId);\n if (sessionId) {\n await this.connector.disconnect(sessionId);\n this._sessions.delete(connectId);\n }\n }\n\n async getDeviceInfo(connectId: string, deviceId: string): Promise<Response<DeviceInfo>> {\n await this._ensureDevicePermission(connectId, deviceId);\n\n // Look up the device in the cache populated by event handlers / searchDevices.\n // Try connectId first (the USB path), then fall back to scanning by deviceId.\n const cached =\n this._discoveredDevices.get(connectId) ??\n Array.from(this._discoveredDevices.values()).find(d => d.deviceId === deviceId);\n\n if (cached) {\n return success(cached);\n }\n\n return failure(\n HardwareErrorCode.DeviceNotFound,\n 'Device not found in cache. Call searchDevices() or wait for a device-connected event first.'\n );\n }\n\n getSupportedChains(): ChainCapability[] {\n return ['evm', 'btc', 'sol', 'tron'];\n }\n\n // ---------------------------------------------------------------------------\n // Chain call helper\n // ---------------------------------------------------------------------------\n\n private async callChain<T>(\n connectId: string,\n deviceId: string,\n chain: string,\n method: string,\n params: unknown,\n skipFingerprint = false\n ): Promise<Response<T>> {\n await this._ensureDevicePermission(connectId, deviceId);\n try {\n const result = await this.connectorCall(connectId, method, params, {\n chain: chain as ChainForFingerprint,\n deviceId,\n skipFingerprint,\n });\n return success(result as T);\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n /**\n * Batch version of callChain — checks permission once,\n * fingerprint is verified on the first call inside connectorCall.\n */\n private async callChainBatch<TParam, TResult>(\n connectId: string,\n deviceId: string,\n chain: string,\n method: string,\n params: TParam[],\n onProgress?: ProgressCallback,\n skipFingerprint = false\n ): Promise<Response<TResult[]>> {\n await this._ensureDevicePermission(connectId, deviceId);\n const results: TResult[] = [];\n for (let i = 0; i < params.length; i++) {\n try {\n const result = await this.connectorCall(connectId, method, params[i], {\n chain: chain as ChainForFingerprint,\n deviceId,\n // Only verify fingerprint on the first call in the batch\n skipFingerprint: skipFingerprint || i > 0,\n });\n results.push(result as TResult);\n onProgress?.({ index: i, total: params.length });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n return success(results);\n }\n\n // ---------------------------------------------------------------------------\n // EVM chain methods\n // ---------------------------------------------------------------------------\n\n evmGetAddress(connectId: string, deviceId: string, params: EvmGetAddressParams) {\n return this.callChain<EvmAddress>(connectId, deviceId, 'evm', 'evmGetAddress', params);\n }\n\n evmGetAddresses(\n connectId: string,\n deviceId: string,\n params: EvmGetAddressParams[],\n onProgress?: ProgressCallback\n ) {\n return this.callChainBatch<EvmGetAddressParams, EvmAddress>(\n connectId,\n deviceId,\n 'evm',\n 'evmGetAddress',\n params,\n onProgress\n );\n }\n\n evmSignTransaction(connectId: string, deviceId: string, params: EvmSignTxParams) {\n return this.callChain<EvmSignedTx>(connectId, deviceId, 'evm', 'evmSignTransaction', params);\n }\n\n evmSignMessage(connectId: string, deviceId: string, params: EvmSignMsgParams) {\n return this.callChain<EvmSignature>(connectId, deviceId, 'evm', 'evmSignMessage', params);\n }\n\n evmSignTypedData(connectId: string, deviceId: string, params: EvmSignTypedDataParams) {\n return this.callChain<EvmSignature>(connectId, deviceId, 'evm', 'evmSignTypedData', params);\n }\n\n // ---------------------------------------------------------------------------\n // BTC chain methods\n // ---------------------------------------------------------------------------\n\n btcGetAddress(connectId: string, deviceId: string, params: BtcGetAddressParams) {\n return this.callChain<BtcAddress>(connectId, deviceId, 'btc', 'btcGetAddress', params);\n }\n\n btcGetAddresses(\n connectId: string,\n deviceId: string,\n params: BtcGetAddressParams[],\n onProgress?: ProgressCallback\n ) {\n return this.callChainBatch<BtcGetAddressParams, BtcAddress>(\n connectId,\n deviceId,\n 'btc',\n 'btcGetAddress',\n params,\n onProgress\n );\n }\n\n btcGetPublicKey(connectId: string, deviceId: string, params: BtcGetPublicKeyParams) {\n return this.callChain<BtcPublicKey>(connectId, deviceId, 'btc', 'btcGetPublicKey', params);\n }\n\n btcSignTransaction(connectId: string, deviceId: string, params: BtcSignTxParams) {\n return this.callChain<BtcSignedTx>(connectId, deviceId, 'btc', 'btcSignTransaction', params);\n }\n\n btcSignPsbt(connectId: string, deviceId: string, params: BtcSignPsbtParams) {\n return this.callChain<BtcSignedPsbt>(connectId, deviceId, 'btc', 'btcSignPsbt', params);\n }\n\n btcSignMessage(connectId: string, deviceId: string, params: BtcSignMsgParams) {\n return this.callChain<BtcSignature>(connectId, deviceId, 'btc', 'btcSignMessage', params);\n }\n\n btcGetMasterFingerprint(connectId: string, deviceId: string) {\n return this.callChain<{ masterFingerprint: string }>(\n connectId,\n deviceId,\n 'btc',\n 'btcGetMasterFingerprint',\n {}\n );\n }\n\n // ---------------------------------------------------------------------------\n // SOL chain methods\n // ---------------------------------------------------------------------------\n\n solGetAddress(connectId: string, deviceId: string, params: SolGetAddressParams) {\n return this.callChain<SolAddress>(connectId, deviceId, 'sol', 'solGetAddress', params);\n }\n\n solGetAddresses(\n connectId: string,\n deviceId: string,\n params: SolGetAddressParams[],\n onProgress?: ProgressCallback\n ) {\n return this.callChainBatch<SolGetAddressParams, SolAddress>(\n connectId,\n deviceId,\n 'sol',\n 'solGetAddress',\n params,\n onProgress\n );\n }\n\n solSignTransaction(connectId: string, deviceId: string, params: SolSignTxParams) {\n return this.callChain<SolSignedTx>(connectId, deviceId, 'sol', 'solSignTransaction', params);\n }\n\n solSignMessage(connectId: string, deviceId: string, params: SolSignMsgParams) {\n return this.callChain<SolSignature>(connectId, deviceId, 'sol', 'solSignMessage', params);\n }\n\n // ---------------------------------------------------------------------------\n // TRON chain methods\n // ---------------------------------------------------------------------------\n\n tronGetAddress(connectId: string, deviceId: string, params: TronGetAddressParams) {\n return this.callChain<TronAddress>(connectId, deviceId, 'tron', 'tronGetAddress', params, true);\n }\n\n tronGetAddresses(\n connectId: string,\n deviceId: string,\n params: TronGetAddressParams[],\n onProgress?: ProgressCallback\n ) {\n return this.callChainBatch<TronGetAddressParams, TronAddress>(\n connectId,\n deviceId,\n 'tron',\n 'tronGetAddress',\n params,\n onProgress,\n true\n );\n }\n\n tronSignTransaction(connectId: string, deviceId: string, params: TronSignTxParams) {\n return this.callChain<TronSignedTx>(\n connectId,\n deviceId,\n 'tron',\n 'tronSignTransaction',\n params,\n true\n );\n }\n\n tronSignMessage(connectId: string, deviceId: string, params: TronSignMsgParams) {\n return this.callChain<TronSignature>(\n connectId,\n deviceId,\n 'tron',\n 'tronSignMessage',\n params,\n true\n );\n }\n\n // ---------------------------------------------------------------------------\n // Events\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 cancel(connectId: string): void {\n const sessionId = this._sessions.get(connectId) ?? connectId;\n // Force-cancel the active job so in-flight signer work aborts even if it's\n // marked non-interruptible; queue.clear would kill queued follow-ups too.\n this._jobQueue.forceCancelActive(connectId || '__ledger_default__');\n void this.connector.cancel(sessionId);\n }\n\n // ---------------------------------------------------------------------------\n // Chain fingerprint\n // ---------------------------------------------------------------------------\n\n async getChainFingerprint(\n connectId: string,\n deviceId: string,\n chain: ChainForFingerprint\n ): Promise<Response<string>> {\n debugLog(\n '[LedgerAdapter] getChainFingerprint called, chain:',\n chain,\n 'connectId:',\n connectId || '(empty)',\n 'sessions:',\n this._sessions.size\n );\n await this._ensureDevicePermission(connectId, deviceId);\n debugLog('[LedgerAdapter] getChainFingerprint permission ok, computing fingerprint');\n try {\n const fingerprint = await this._computeChainFingerprint(chain, (method, params) =>\n this.connectorCall(connectId, method, params)\n );\n debugLog('[LedgerAdapter] getChainFingerprint result:', fingerprint?.substring(0, 20));\n return success(fingerprint);\n } catch (err) {\n debugError('[LedgerAdapter] getChainFingerprint error:', chain, err);\n return this.errorToFailure(err);\n }\n }\n\n /**\n * Verify fingerprint using an existing sessionId directly.\n * Safe to call inside connectorCall without causing queue deadlock.\n */\n private async _verifyDeviceFingerprintWithSession(\n sessionId: string,\n deviceId: string,\n chain: ChainForFingerprint\n ): Promise<IFingerprintVerifyResult> {\n if (!deviceId) return { success: true };\n\n try {\n const fingerprint = await this._computeChainFingerprint(chain, (method, params) =>\n this.connector.call(sessionId, method, params)\n );\n if (fingerprint === deviceId) {\n return { success: true };\n }\n return { success: false, expected: deviceId, actual: fingerprint };\n } catch (err) {\n const mapped = mapLedgerError(err);\n if (\n mapped.code === HardwareErrorCode.WrongApp ||\n mapped.code === HardwareErrorCode.DeviceLocked\n ) {\n return { success: true };\n }\n throw err;\n }\n }\n\n /**\n * Compute the chain fingerprint via a caller-supplied call strategy.\n *\n * Chains with a native device-side identity primitive (BTC → BIP32 master\n * fingerprint) short-circuit at the top and return it verbatim, so the value\n * stays reusable for higher-level use (BIP380 descriptors, PSBT signing).\n *\n * All other chains derive a fixed-path address and run it through\n * `deriveDeviceFingerprint` to produce an opaque seed identifier.\n *\n * The two callers (`getChainFingerprint` / `_verifyDeviceFingerprintWithSession`)\n * differ only in the underlying call mechanism, which is injected as `callMethod`\n * to avoid queue deadlocks when running inside `connectorCall`.\n */\n private async _computeChainFingerprint(\n chain: ChainForFingerprint,\n callMethod: (method: string, params: unknown) => Promise<unknown>\n ): Promise<string> {\n // BTC: dedicated device call returns the BIP32 master fingerprint already\n // in the canonical 8-hex form — no further hashing.\n if (chain === 'btc') {\n const result = (await callMethod('btcGetMasterFingerprint', {})) as {\n masterFingerprint: string;\n };\n return result.masterFingerprint;\n }\n\n const path = CHAIN_FINGERPRINT_PATHS[chain];\n let address: string;\n if (chain === 'evm') {\n // Lowercase per deriveDeviceFingerprint's canonical-form contract.\n address = (\n (await callMethod('evmGetAddress', { path, showOnDevice: false })) as {\n address: string;\n }\n ).address.toLowerCase();\n } else if (chain === 'sol') {\n address = (\n (await callMethod('solGetAddress', { path, showOnDevice: false })) as {\n address: string;\n }\n ).address;\n } else if (chain === 'tron') {\n address = (\n (await callMethod('tronGetAddress', { path, showOnDevice: false })) as {\n address: string;\n }\n ).address;\n } else {\n throw new Error(`Unsupported chain for fingerprint: ${chain as string}`);\n }\n\n return deriveDeviceFingerprint(address);\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Ensure at least one device is connected and return a valid connectId.\n *\n * - If a session already exists for the given connectId, reuse it.\n * - If ANY session exists (Ledger IDs are ephemeral), reuse it.\n * - Otherwise: search → 1 device: auto-connect, multiple: ask user, 0: throw.\n */\n private static readonly MAX_DEVICE_RETRY = 3;\n\n // Mutex for ensureConnected — prevents concurrent calls from establishing duplicate connections\n private _connectingPromise: Promise<string> | null = null;\n\n // Ledger WebUSB won't expose a locked device, so we can't auto-detect unlock.\n // The user must press Confirm after unlocking, which triggers a search retry.\n // If `signal` is provided, an abort cancels the pending UI request so the\n // registry slot is released and a stale RECEIVE_DEVICE_CONNECT won't land in\n // a future request.\n private async _waitForDeviceConnect(signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) {\n LedgerAdapter._throwIfAborted(signal);\n }\n\n this.emitter.emit(UI_REQUEST.REQUEST_DEVICE_CONNECT, {\n type: UI_REQUEST.REQUEST_DEVICE_CONNECT,\n payload: {\n message: 'Please connect and unlock your Ledger device',\n },\n });\n\n const waitPromise = this._uiRegistry.wait<{ confirmed: boolean }>(\n UI_REQUEST.REQUEST_DEVICE_CONNECT\n );\n\n let payload: { confirmed: boolean } | undefined;\n if (signal) {\n const onAbort = () => {\n this._uiRegistry.cancel(UI_REQUEST.REQUEST_DEVICE_CONNECT);\n };\n signal.addEventListener('abort', onAbort, { once: true });\n try {\n payload = await waitPromise;\n } finally {\n signal.removeEventListener('abort', onAbort);\n }\n } else {\n payload = await waitPromise;\n }\n\n if (!payload?.confirmed) {\n throw Object.assign(new Error('User cancelled Ledger connection'), {\n _tag: 'DeviceNotRecognizedError',\n });\n }\n }\n\n private async ensureConnected(connectId?: string): Promise<string> {\n // 1. Exact match — no mutex needed\n if (connectId && this._sessions.has(connectId)) {\n return connectId;\n }\n\n // 2. Any existing session (Ledger IDs are temporary, any session is fine)\n if (this._sessions.size > 0) {\n // size > 0 guarantees .next().value is defined\n const firstKey = this._sessions.keys().next().value as string;\n return firstKey;\n }\n\n // 3. No session — use mutex to prevent concurrent connection attempts\n if (this._connectingPromise) {\n return this._connectingPromise;\n }\n\n this._connectingPromise = this._doConnect();\n try {\n return await this._connectingPromise;\n } finally {\n this._connectingPromise = null;\n }\n }\n\n private async _doConnect(): Promise<string> {\n for (let attempt = 0; attempt < LedgerAdapter.MAX_DEVICE_RETRY; attempt++) {\n const devices = await this.searchDevices();\n\n if (devices.length > 0) {\n // Found device(s), continue to connection below\n return this._connectFirstOrSelect(devices);\n }\n\n // No device found — prompt user (except on last attempt)\n if (attempt < LedgerAdapter.MAX_DEVICE_RETRY - 1) {\n await this._waitForDeviceConnect();\n }\n }\n\n throw Object.assign(\n new Error(\n 'No Ledger device found after multiple attempts. Please connect and unlock your device.'\n ),\n { _tag: 'DeviceNotRecognizedError' }\n );\n }\n\n private async _connectFirstOrSelect(devices: DeviceInfo[]): Promise<string> {\n const chosenConnectId =\n devices.length === 1 ? devices[0].connectId : await this._chooseDeviceFromList(devices);\n\n const result = await this.connectDevice(chosenConnectId);\n if (!result.success) {\n throw Object.assign(new Error(result.payload.error), {\n _tag: 'DeviceNotRecognizedError',\n });\n }\n return chosenConnectId;\n }\n\n private async _chooseDeviceFromList(devices: DeviceInfo[]): Promise<string> {\n if (!this._handleSelectDevice) {\n debugLog(\n `[DMK] Multiple Ledger devices found (${devices.length}); handleSelectDevice=false, picking first (${devices[0].connectId}).`\n );\n return devices[0].connectId;\n }\n\n this.emitter.emit(UI_REQUEST.REQUEST_SELECT_DEVICE, {\n type: UI_REQUEST.REQUEST_SELECT_DEVICE,\n payload: { devices },\n });\n\n const response = await this._uiRegistry.wait<{ sdkConnectId: string }>(\n UI_REQUEST.REQUEST_SELECT_DEVICE\n );\n\n const chosen = devices.find(d => d.connectId === response?.sdkConnectId);\n if (!chosen) {\n throw Object.assign(\n new Error(`Selected sdkConnectId '${response?.sdkConnectId}' not in discovered list`),\n { _tag: 'DeviceNotRecognizedError' }\n );\n }\n return chosen.connectId;\n }\n\n /**\n * Call the connector with automatic session resolution and disconnect retry.\n *\n * 1. Resolves a valid connectId via ensureConnected()\n * 2. Looks up sessionId from _sessions\n * 3. Calls connector.call()\n * 4. On disconnect error: clears stale session, re-connects, retries once\n */\n private async connectorCall(\n connectId: string,\n method: string,\n params: unknown,\n fingerprint?: {\n chain: ChainForFingerprint;\n deviceId: string;\n skipFingerprint: boolean;\n }\n ): Promise<unknown> {\n debugLog('[LedgerAdapter] connectorCall:', method, 'connectId:', connectId || '(empty)');\n\n // Queue key: prefer the supplied connectId; fall back to a shared bucket so that\n // calls made before any session exists still serialize (Ledger only has one active device).\n const queueKey = connectId || '__ledger_default__';\n const interruptibility = LedgerAdapter._getInterruptibility(method);\n\n return this._jobQueue.enqueue(\n queueKey,\n async signal => this._runConnectorCall(connectId, method, params, signal, fingerprint),\n { interruptibility, label: method }\n );\n }\n\n /**\n * Race a promise against an abort signal. If the signal fires, rejects with the\n * signal's reason (or a generic Error). The underlying connector.call() cannot\n * actually be cancelled on Ledger DMK, but the caller gets the abort immediately.\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 /** Throw an AbortError if signal is already aborted. */\n private static _throwIfAborted(signal: AbortSignal): void {\n if (signal.aborted) {\n throw (signal as AbortSignal & { reason?: unknown }).reason ?? new Error('Aborted');\n }\n }\n\n /** Actual work done under the job queue — connection, fingerprint, call, and recovery. */\n private async _runConnectorCall(\n connectId: string,\n method: string,\n params: unknown,\n signal: AbortSignal,\n fingerprint?: {\n chain: ChainForFingerprint;\n deviceId: string;\n skipFingerprint: boolean;\n }\n ): Promise<unknown> {\n LedgerAdapter._throwIfAborted(signal);\n // Wrap ensureConnected in _abortable so an abort during device discovery /\n // user-connect UI wait rejects this caller immediately. The underlying\n // _doConnect / _connectingPromise is shared across callers and continues\n // running — other concurrent callers aren't affected.\n const resolvedConnectId = await LedgerAdapter._abortable(\n signal,\n this.ensureConnected(connectId)\n );\n LedgerAdapter._throwIfAborted(signal);\n const sessionId = this._sessions.get(resolvedConnectId);\n debugLog(\n '[LedgerAdapter] connectorCall resolved:',\n method,\n 'resolvedConnectId:',\n resolvedConnectId,\n 'sessionId:',\n sessionId\n );\n if (!sessionId) {\n throw Object.assign(new Error('Auto-connect succeeded but no session found'), {\n _tag: 'DeviceSessionNotFound',\n });\n }\n\n // Fingerprint verification inside the session — atomic with the actual call\n if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId) {\n const fp = await LedgerAdapter._abortable(\n signal,\n this._verifyDeviceFingerprintWithSession(sessionId, fingerprint.deviceId, fingerprint.chain)\n );\n if (!fp.success) {\n throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {\n code: HardwareErrorCode.DeviceMismatch,\n });\n }\n }\n\n try {\n return await LedgerAdapter._abortable(signal, this.connector.call(sessionId, method, params));\n } catch (err) {\n // If the abort fired, surface it directly — skip recovery paths.\n if (signal.aborted) throw err;\n const errObj = err as Record<string, unknown> | null | undefined;\n debugLog('[LedgerAdapter] connectorCall error:', method, {\n message: errObj?.message,\n _tag: errObj?._tag,\n errorCode: errObj?.errorCode,\n statusCode: errObj?.statusCode,\n isDisconnected: isDeviceDisconnectedError(err),\n isLocked: isDeviceLockedError(err),\n });\n if (isDeviceDisconnectedError(err)) {\n debugLog('[LedgerAdapter] disconnected, retrying with fresh connection...');\n this._discoveredDevices.clear();\n return this._retryWithFreshConnection(resolvedConnectId, method, params, signal, err);\n }\n if (isDeviceLockedError(err)) {\n await this._waitForDeviceConnect(signal);\n LedgerAdapter._throwIfAborted(signal);\n return LedgerAdapter._abortable(signal, this.connector.call(sessionId, method, params));\n }\n if (isTimeoutError(err)) {\n debugLog('[LedgerAdapter] timeout, retrying with fresh connection...');\n this._discoveredDevices.delete(resolvedConnectId);\n return this._retryWithFreshConnection(resolvedConnectId, method, params, signal, err);\n }\n throw err;\n }\n }\n\n /** Clear stale session, reconnect, and retry the call. */\n private async _retryWithFreshConnection(\n resolvedConnectId: string,\n method: string,\n params: unknown,\n signal: AbortSignal,\n originalErr: unknown\n ): Promise<unknown> {\n this._sessions.delete(resolvedConnectId);\n LedgerAdapter._throwIfAborted(signal);\n const retryConnectId = await this.ensureConnected();\n LedgerAdapter._throwIfAborted(signal);\n const retrySessionId = this._sessions.get(retryConnectId);\n if (!retrySessionId) {\n throw originalErr;\n }\n return LedgerAdapter._abortable(signal, this.connector.call(retrySessionId, method, params));\n }\n\n /**\n * Ensure OS-level device permission (Bluetooth / USB) before proceeding.\n *\n * Emits `REQUEST_DEVICE_PERMISSION` and awaits the consumer's\n * `RECEIVE_DEVICE_PERMISSION` reply (60s budget covers \"probe → system\n * prompt → user tap\" plus a generous margin). If the consumer never wires\n * a handler or never replies, the wait times out and the operation fails\n * fast so scanners/callers don't hang silently.\n *\n * - No connectId (searchDevices): environment-level permission\n * - With connectId (business methods): device-level permission\n */\n private async _ensureDevicePermission(connectId?: string, deviceId?: string): Promise<void> {\n const transportType: TransportType = this.activeTransport ?? 'hid';\n\n // Register the wait before emitting — a synchronous listener that replies\n // immediately (e.g. in tests or a same-process consumer) would otherwise\n // resolve before any pending entry exists and the response would drop.\n const waitPromise = this._uiRegistry.wait<{ granted: boolean }>(\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\n if (!granted) {\n throw Object.assign(new Error('Device permission denied'), {\n code: HardwareErrorCode.DevicePermissionDenied,\n });\n }\n }\n\n /**\n * Convert a thrown error to a Response failure.\n * Uses mapLedgerError to parse Ledger DMK error codes into HardwareErrorCode values.\n */\n private errorToFailure<T>(err: unknown): Response<T> {\n debugError('[LedgerAdapter] error:', err);\n\n // If the error carries an explicit HardwareErrorCode (e.g. validation errors\n // thrown by connector chain methods), use it directly.\n if (\n err &&\n typeof err === 'object' &&\n 'code' in err &&\n typeof (err as { code: unknown }).code === 'number'\n ) {\n const e = err as { code: number; message?: string; appName?: string };\n return ledgerFailure(e.code, e.message ?? 'Unknown error', e.appName);\n }\n\n const mapped = mapLedgerError(err);\n\n // DeviceLocked is handled by connectorCall retry logic (_waitForDeviceConnect).\n // Do NOT emit UI events here — it would show UI and return error simultaneously.\n\n return ledgerFailure(mapped.code, mapped.message, mapped.appName);\n }\n\n // ---------------------------------------------------------------------------\n // Event translation\n // ---------------------------------------------------------------------------\n\n private deviceConnectHandler = (data: { device: ConnectorDevice }): void => {\n const deviceInfo = this.connectorDeviceToDeviceInfo(data.device);\n this._discoveredDevices.set(deviceInfo.connectId, deviceInfo);\n // Clear any stale session for this connectId so ensureConnected() does a fresh connect.\n // This handles the case where the connector reconnected internally (e.g. TRON app switch).\n this._sessions.delete(deviceInfo.connectId);\n this.emitter.emit(DEVICE.CONNECT, {\n type: DEVICE.CONNECT,\n payload: deviceInfo,\n });\n };\n\n private deviceDisconnectHandler = (data: { connectId: string }): void => {\n this._discoveredDevices.delete(data.connectId);\n this._sessions.delete(data.connectId);\n this.emitter.emit(DEVICE.DISCONNECT, {\n type: DEVICE.DISCONNECT,\n payload: { connectId: data.connectId },\n });\n };\n\n private uiRequestHandler = (data: { type: string; payload?: unknown }): void => {\n this.handleUiEvent(data);\n };\n\n private uiEventHandler = (data: { type: string; payload?: unknown }): void => {\n this.handleUiEvent(data);\n };\n\n private registerEventListeners(): void {\n this.connector.on('device-connect', this.deviceConnectHandler);\n this.connector.on('device-disconnect', this.deviceDisconnectHandler);\n this.connector.on('ui-request', this.uiRequestHandler);\n this.connector.on('ui-event', this.uiEventHandler);\n }\n\n private unregisterEventListeners(): void {\n this.connector.off('device-connect', this.deviceConnectHandler);\n this.connector.off('device-disconnect', this.deviceDisconnectHandler);\n this.connector.off('ui-request', this.uiRequestHandler);\n this.connector.off('ui-event', this.uiEventHandler);\n }\n\n private handleUiEvent(event: { type: string; payload?: unknown }): void {\n if (!event.type) return;\n\n const payload = event.payload as Record<string, unknown> | undefined;\n const deviceInfo = payload ? this.extractDeviceInfoFromPayload(payload) : this.unknownDevice();\n\n switch (event.type) {\n case 'ui-request_confirmation':\n this.emitter.emit(UI_REQUEST.REQUEST_BUTTON, {\n type: UI_REQUEST.REQUEST_BUTTON,\n payload: { device: deviceInfo },\n });\n break;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Device info mapping\n // ---------------------------------------------------------------------------\n\n private connectorDeviceToDeviceInfo(device: ConnectorDevice): DeviceInfo {\n // BLE connectId is a stable 4-digit HEX (e.g. \"A58F\") from device name.\n // USB connectId is an ephemeral UUID. Use this to infer connectionType.\n const isBle = device.connectId && /^[0-9A-Fa-f]{4}$/.test(device.connectId);\n\n return {\n vendor: 'ledger',\n model: device.model ?? 'unknown',\n firmwareVersion: '',\n deviceId: device.deviceId,\n connectId: device.connectId,\n label: device.name,\n connectionType: isBle ? 'ble' : 'usb',\n capabilities: device.capabilities,\n };\n }\n\n private extractDeviceInfoFromPayload(payload: Record<string, unknown>): DeviceInfo {\n return {\n vendor: 'ledger',\n model: (payload.model as string) ?? 'unknown',\n firmwareVersion: '',\n deviceId: (payload.deviceId as string) ?? (payload.id as string) ?? '',\n connectId: (payload.connectId as string) ?? (payload.path as string) ?? '',\n label: payload.label as string,\n connectionType: 'usb' as ConnectionType,\n };\n }\n\n private unknownDevice(): DeviceInfo {\n return {\n vendor: 'ledger',\n model: 'unknown',\n firmwareVersion: '',\n deviceId: '',\n connectId: '',\n connectionType: 'usb',\n };\n }\n}\n","import { HardwareErrorCode, enrichErrorMessage } from '@onekeyfe/hwk-adapter-core';\n\nimport type { Failure } from '@onekeyfe/hwk-adapter-core';\n\n/**\n * Ledger-specific Failure: adds `appName` for \"the currently-open app\" — a\n * Ledger hardware concept not shared with other vendors, so it lives here\n * rather than in core's generic Failure.\n */\nexport type LedgerFailure = Omit<Failure, 'payload'> & {\n payload: Failure['payload'] & { appName?: string };\n};\n\n/**\n * Structurally compatible with `Failure`; writes `appName` only when provided,\n * so `'appName' in payload` is a reliable \"has info\" signal for consumers.\n */\nexport function ledgerFailure(\n code: HardwareErrorCode,\n error: string,\n appName?: string\n): LedgerFailure {\n const payload: LedgerFailure['payload'] = { error, code };\n if (appName !== undefined) payload.appName = appName;\n return { success: false, payload };\n}\n\n/**\n * DMK locked device status codes:\n * 0x5515 (21781) — primary locked response\n * 0x6982 (27010) — security status not satisfied\n * 0x5303 (21251) — tertiary locked response\n */\nconst LOCKED_ERROR_CODES = new Set(['5515', '21781', '6982', '27010', '5303', '21251']);\n\n/**\n * DMK user-rejected status codes:\n * 0x6985 (27013) — conditions of use not satisfied (user denied on device)\n */\nconst USER_REJECTED_CODES = new Set(['6985', '27013']);\n\n/**\n * DMK wrong-app / CLA-not-supported status codes:\n * 0x6e00 (28160) — CLA not supported (wrong app open)\n * 0x6d00 (27904) — INS not supported (wrong app or outdated app)\n * 0x6a83 (27267) — Referenced data not found (wrong app for raw APDU, e.g. TRON)\n */\nconst WRONG_APP_CODES = new Set(['6e00', '28160', '6d00', '27904', '6a83', '27267']);\n\n/**\n * DMK app-not-installed status codes:\n * 0x6807 (26631) — Unknown application name (app not installed on device)\n */\nconst APP_NOT_INSTALLED_CODES = new Set(['6807', '26631']);\n\n/**\n * DMK step value emitted just before a blind-sign failure.\n * Used to distinguish APDU 0x6a80 (\"Invalid data\") caused by disabled\n * Blind signing vs. a genuinely malformed transaction.\n */\nconst STEP_BLIND_SIGN_FALLBACK = 'signer.eth.steps.blindSignTransactionFallback';\n\n/**\n * Read the Ledger Ethereum App APDU error code from a DMK error object.\n * Returns the code in lowercase (e.g. \"6a80\") or `null` if not present.\n */\nfunction getEthAppErrorCode(err: unknown): string | null {\n if (!err || typeof err !== 'object') return null;\n const e = err as Record<string, unknown>;\n if (e._tag === 'EthAppCommandError' && typeof e.errorCode === 'string') {\n return e.errorCode.toLowerCase();\n }\n const orig = e.originalError as Record<string, unknown> | undefined;\n if (orig?._tag === 'EthAppCommandError' && typeof orig.errorCode === 'string') {\n return orig.errorCode.toLowerCase();\n }\n return null;\n}\n\n/**\n * Extract an APDU status word in lowercase hex. Handles DMK's hex-string\n * `errorCode`, legacy TransportStatusError's numeric `statusCode`, and\n * recurses through `originalError` for wrapped errors.\n */\nfunction extractApduHex(err: unknown): string | null {\n if (!err || typeof err !== 'object') return null;\n const e = err as Record<string, unknown>;\n if (typeof e.errorCode === 'string' && /^[0-9a-f]+$/i.test(e.errorCode)) {\n return e.errorCode.toLowerCase();\n }\n if (typeof e.statusCode === 'number' && Number.isFinite(e.statusCode)) {\n return e.statusCode.toString(16).padStart(4, '0');\n }\n if (typeof e.statusCode === 'string' && /^[0-9a-f]+$/i.test(e.statusCode)) {\n return e.statusCode.toLowerCase();\n }\n if (e.originalError != null) {\n const nested = extractApduHex(e.originalError);\n if (nested) return nested;\n }\n if (e.error != null && typeof e._tag === 'string') {\n const nested = extractApduHex(e.error);\n if (nested) return nested;\n }\n return null;\n}\n\n/** Solana APDU → code. 0x6808 arrives as a plain DeviceExchangeError,\n * not wrapped in SolanaAppCommandError, so match by code only. */\nfunction mapSolanaAppError(hex: string): HardwareErrorCode | null {\n switch (hex) {\n case '6808':\n return HardwareErrorCode.SolanaBlindSigningRequired;\n default:\n return null;\n }\n}\n\n/** Tron APDU → code. Source: app-tron/src/app_errors.h (E_MISSING_SETTING_*). */\nfunction mapTronAppError(hex: string): HardwareErrorCode | null {\n switch (hex) {\n case '6a8d':\n return HardwareErrorCode.TronCustomContractRequired;\n case '6a8b':\n return HardwareErrorCode.TronDataSigningRequired;\n case '6a8c':\n return HardwareErrorCode.TronSignByHashRequired;\n default:\n return null;\n }\n}\n\n/** BTC APDU → code. 0xb000 range is disjoint from other apps' 0x6xxx. */\nfunction mapBtcAppError(hex: string): HardwareErrorCode | null {\n switch (hex) {\n case 'b008':\n return HardwareErrorCode.BtcWalletPolicyHmacMismatch;\n case 'b007':\n return HardwareErrorCode.BtcUnexpectedState;\n default:\n return null;\n }\n}\n\n/**\n * Map a Ledger Ethereum App APDU status word to a HardwareErrorCode.\n * `lastStep` (attached by `deviceActionToPromise`) is used only to refine\n * ambiguous codes like 0x6a80.\n */\nfunction mapEthAppError(ethCode: string, lastStep: string | undefined): HardwareErrorCode | null {\n switch (ethCode) {\n case '6a80':\n // \"Invalid data\". If DMK had just fallen back to blind signing, the\n // only plausible cause is that Blind signing is disabled on the device.\n if (lastStep === STEP_BLIND_SIGN_FALLBACK) {\n return HardwareErrorCode.EvmBlindSigningRequired;\n }\n // Other call sites (e.g. clear-sign with malformed context) — keep\n // unknown so the raw message surfaces and the bug can be diagnosed.\n return null;\n case '6984':\n return HardwareErrorCode.EvmClearSignPluginMissing;\n case '6a84':\n return HardwareErrorCode.EvmDataTooLarge;\n case '6501':\n return HardwareErrorCode.EvmTxTypeNotSupported;\n case '911c':\n return HardwareErrorCode.AppTooOld;\n default:\n return null;\n }\n}\n\n/** Check if an error (or any error in its chain) represents a locked Ledger device. */\nexport function isDeviceLockedError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as Record<string, unknown>;\n if (e.errorCode != null && LOCKED_ERROR_CODES.has(String(e.errorCode))) return true;\n if (e.statusCode != null && LOCKED_ERROR_CODES.has(String(e.statusCode))) return true;\n if (e._tag === 'DeviceLockedError') return true;\n if (e.originalError != null && isDeviceLockedError(e.originalError)) return true;\n if (e.error != null && e._tag && isDeviceLockedError(e.error)) return true;\n return false;\n}\n\n/** Check if a status/error code exists in the given set, crawling the error chain. */\nfunction hasStatusCode(err: unknown, codeSet: Set<string>): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as Record<string, unknown>;\n if (e.errorCode != null && codeSet.has(String(e.errorCode))) return true;\n if (e.statusCode != null && codeSet.has(String(e.statusCode))) return true;\n if (e.originalError != null && hasStatusCode(e.originalError, codeSet)) return true;\n if (e.error != null && e._tag && hasStatusCode(e.error, codeSet)) return true;\n return false;\n}\n\n/** Check for user rejection (denied on device). */\nexport function isUserRejectedError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as Record<string, unknown>;\n if (e._tag === 'UserRefusedOnDevice') return true;\n if (typeof e.message === 'string' && /denied|rejected|refused/i.test(e.message)) return true;\n if (hasStatusCode(err, USER_REJECTED_CODES)) return true;\n return false;\n}\n\n/** Check for wrong app open on the device. */\nexport function isWrongAppError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as Record<string, unknown>;\n if (e._tag === 'WrongAppOpenedError' || e._tag === 'InvalidStatusWordError') {\n if (hasStatusCode(err, WRONG_APP_CODES)) return true;\n }\n if (typeof e.message === 'string') {\n const msg = e.message.toLowerCase();\n if (msg.includes('wrong app') || msg.includes('open the') || msg.includes('cla not supported'))\n return true;\n }\n if (hasStatusCode(err, WRONG_APP_CODES)) return true;\n return false;\n}\n\n/** Check for app not installed on device (OpenAppCommand returns 0x6807). */\nexport function isAppNotInstalledError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as Record<string, unknown>;\n if (e._tag === 'OpenAppCommandError') return true;\n if (typeof e.message === 'string' && /unknown application/i.test(e.message)) return true;\n if (hasStatusCode(err, APP_NOT_INSTALLED_CODES)) return true;\n return false;\n}\n\n/** Check for device disconnected errors. */\nexport function isDeviceDisconnectedError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as Record<string, unknown>;\n if (e._tag === 'DeviceNotRecognizedError' || e._tag === 'DeviceSessionNotFound') return true;\n if (typeof e.message === 'string') {\n const msg = e.message.toLowerCase();\n if (\n msg.includes('disconnected') ||\n msg.includes('not found') ||\n msg.includes('no device') ||\n msg.includes('unplugged')\n )\n return true;\n }\n return false;\n}\n\n/**\n * DMK timeout error _tag values.\n * These are the concrete error classes from @ledgerhq/device-management-kit.\n */\nconst TIMEOUT_TAGS = new Set([\n 'DeviceExchangeTimeoutError',\n 'SendApduTimeoutError',\n 'SendCommandTimeoutError',\n]);\n\n/** Check for timeout errors using DMK's _tag identifiers or wrapped error code. */\nexport function isTimeoutError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as Record<string, unknown>;\n if (typeof e._tag === 'string' && TIMEOUT_TAGS.has(e._tag)) return true;\n if (e.code === HardwareErrorCode.OperationTimeout) return true;\n return false;\n}\n\n/**\n * Map a Ledger DMK error to a HardwareErrorCode and human-readable message\n * with actionable recovery information for the caller.\n */\nexport function mapLedgerError(err: unknown): {\n code: HardwareErrorCode;\n message: string;\n appName?: string;\n} {\n // Order matters: check more specific errors first\n\n // Extract the original message for fallback / enrichment\n let originalMessage = 'Unknown Ledger error';\n if (err instanceof Error) {\n originalMessage = err.message;\n } else if (err && typeof err === 'object') {\n const e = err as Record<string, unknown>;\n originalMessage = String(e.message ?? e._tag ?? e.type ?? JSON.stringify(err));\n }\n\n let code: HardwareErrorCode;\n\n if (isDeviceLockedError(err)) {\n code = HardwareErrorCode.DeviceLocked;\n } else if (isUserRejectedError(err)) {\n // User rejection (0x6985) must win over EthAppError mapping — a user-cancelled\n // blind-sign is not a \"please enable Blind signing\" situation.\n code = HardwareErrorCode.UserRejected;\n } else if (isWrongAppError(err)) {\n code = HardwareErrorCode.WrongApp;\n } else if (isAppNotInstalledError(err)) {\n code = HardwareErrorCode.AppNotOpen;\n } else if (isDeviceDisconnectedError(err)) {\n code = HardwareErrorCode.DeviceDisconnected;\n } else if (isTimeoutError(err)) {\n code = HardwareErrorCode.OperationTimeout;\n } else {\n // Ethereum App APDU-specific classification (uses _lastStep attached by\n // deviceActionToPromise to disambiguate 0x6a80).\n const ethCode = getEthAppErrorCode(err);\n const lastStep =\n err && typeof err === 'object'\n ? ((err as Record<string, unknown>)._lastStep as string | undefined)\n : undefined;\n const ethMapped = ethCode ? mapEthAppError(ethCode, lastStep) : null;\n\n // Solana / Tron / BTC APDU codes — disjoint from EVM's table, single-pass lookup.\n const apduHex = ethMapped ? null : extractApduHex(err);\n const chainMapped = apduHex\n ? mapSolanaAppError(apduHex) ?? mapTronAppError(apduHex) ?? mapBtcAppError(apduHex)\n : null;\n\n code = ethMapped ?? chainMapped ?? HardwareErrorCode.UnknownError;\n }\n\n const appName =\n err && typeof err === 'object'\n ? ((err as Record<string, unknown>).appName as string | undefined)\n : undefined;\n\n return { code, message: enrichErrorMessage(code, originalMessage), appName };\n}\n","/**\n * Centralised debug logger for the Ledger adapter.\n *\n * Off by default. Toggle programmatically via `setDebugEnabled(true)`.\n */\n\nlet enabled = false;\n\n/** Enable or disable debug logging at runtime. */\nexport function setDebugEnabled(value: boolean): void {\n enabled = value;\n}\n\n/** Returns the current debug-enabled state. */\nexport function isDebugEnabled(): boolean {\n return enabled;\n}\n\nexport function debugLog(...args: unknown[]): void {\n if (enabled) {\n // eslint-disable-next-line no-console\n console.debug(...args);\n }\n}\n\nexport function debugError(...args: unknown[]): void {\n if (enabled) {\n // eslint-disable-next-line no-console\n console.error(...args);\n }\n}\n","import { debugError, debugLog } from '../utils/debugLog';\n\nimport type { DeviceChangeEvent, DeviceDescriptor } from '@onekeyfe/hwk-adapter-core';\nimport type { DeviceManagementKit } from '@ledgerhq/device-management-kit';\nimport type { DmkDiscoveredDevice } from '../types';\n\n/**\n * Manages device discovery, connection, and session tracking.\n * Wraps DMK's Observable APIs into simpler imperative calls.\n */\nexport class LedgerDeviceManager {\n private readonly _dmk: DeviceManagementKit;\n\n private readonly _discovered = new Map<string, DmkDiscoveredDevice>();\n\n private readonly _sessions = new Map<string, string>(); // deviceId → sessionId\n\n private readonly _sessionToDevice = new Map<string, string>(); // sessionId → deviceId\n\n private _listenSub: { unsubscribe: () => void } | null = null;\n\n constructor(dmk: DeviceManagementKit) {\n this._dmk = dmk;\n }\n\n /**\n * One-shot enumeration: subscribe to listenToAvailableDevices,\n * take the first emission, unsubscribe, return DeviceDescriptors.\n */\n enumerate(): Promise<DeviceDescriptor[]> {\n debugLog('[DMK] enumerate() called, dmk exists:', !!this._dmk);\n return new Promise<DeviceDescriptor[]>(resolve => {\n let resolved = false;\n let syncResult: DmkDiscoveredDevice[] | null = null;\n let sub: { unsubscribe: () => void } | null = null;\n\n sub = this._dmk.listenToAvailableDevices({}).subscribe({\n next: devices => {\n if (resolved) return;\n resolved = true;\n this._discovered.clear();\n debugLog('[DMK] enumerate raw devices:', devices.length);\n for (const d of devices) {\n this._discovered.set(d.id, d);\n }\n // If sub is already assigned (async emission), resolve and unsubscribe immediately\n if (sub) {\n sub.unsubscribe();\n resolve(\n devices.map(d => ({\n path: d.id,\n type: d.deviceModel.model,\n name: d.name,\n transport: d.transport,\n }))\n );\n } else {\n // Synchronous emission — sub not yet assigned, defer to after subscribe()\n syncResult = devices;\n }\n },\n error: () => {\n if (!resolved) {\n resolved = true;\n resolve([]);\n }\n },\n });\n\n // If BehaviorSubject fired synchronously, sub is now assigned\n if (syncResult !== null) {\n sub.unsubscribe();\n const devices = syncResult as DmkDiscoveredDevice[];\n resolve(\n devices.map(d => ({\n path: d.id,\n type: d.deviceModel.model,\n name: d.name,\n transport: d.transport,\n }))\n );\n }\n });\n }\n\n /**\n * Continuous listening: tracks device connect/disconnect via diffing.\n */\n listen(onChange: (event: DeviceChangeEvent) => void): void {\n this.stopListening();\n let previousIds = new Set<string>();\n\n this._listenSub = this._dmk.listenToAvailableDevices({}).subscribe({\n next: devices => {\n const currentIds = new Set(devices.map(d => d.id));\n\n for (const d of devices) {\n this._discovered.set(d.id, d);\n debugLog('[DMK] listen device:', d.id, d.name);\n if (!previousIds.has(d.id)) {\n onChange({\n type: 'device-connected',\n descriptor: {\n path: d.id,\n type: d.deviceModel.model,\n name: d.name,\n transport: d.transport,\n },\n });\n }\n }\n for (const id of previousIds) {\n if (!currentIds.has(id)) {\n this._discovered.delete(id);\n onChange({ type: 'device-disconnected', descriptor: { path: id } });\n }\n }\n previousIds = currentIds;\n },\n });\n }\n\n stopListening(): void {\n this._listenSub?.unsubscribe();\n this._listenSub = null;\n }\n\n /**\n * Trigger browser device selection (WebHID requestDevice).\n * Starts discovery for a short period, then stops.\n */\n /**\n * Start BLE discovery if not already running.\n * Does NOT stop — DMK keeps scanning in the background so that\n * listenToAvailableDevices() always has fresh data.\n */\n private _discoverySub: { unsubscribe: () => void } | null = null;\n\n requestDevice(): Promise<void> {\n if (this._discoverySub) {\n // Already scanning\n return Promise.resolve();\n }\n debugLog('[DMK] requestDevice() starting persistent BLE scan');\n this._discoverySub = this._dmk.startDiscovering({}).subscribe({\n next: d => {\n debugLog('[DMK] BLE discovered:', d.name || d.id);\n this._discovered.set(d.id, d);\n },\n error: err => {\n debugError('[DMK] BLE scan error:', err);\n this._discoverySub = null;\n },\n });\n return Promise.resolve();\n }\n\n /** Connect to a previously discovered device. Returns sessionId. */\n async connect(deviceId: string): Promise<string> {\n const device = this._discovered.get(deviceId);\n if (!device) {\n throw new Error(`Device \"${deviceId}\" not found. Call enumerate() or listen() first.`);\n }\n const sessionId = await this._dmk.connect({ device });\n this._sessions.set(deviceId, sessionId);\n this._sessionToDevice.set(sessionId, deviceId);\n return sessionId;\n }\n\n /** Disconnect a session. */\n async disconnect(sessionId: string): Promise<void> {\n await this._dmk.disconnect({ sessionId });\n const deviceId = this._sessionToDevice.get(sessionId);\n if (deviceId) this._sessions.delete(deviceId);\n this._sessionToDevice.delete(sessionId);\n }\n\n getSessionId(deviceId: string): string | undefined {\n return this._sessions.get(deviceId);\n }\n\n getDeviceId(sessionId: string): string | undefined {\n return this._sessionToDevice.get(sessionId);\n }\n\n /** Get the underlying DMK instance (needed by SignerManager). */\n getDmk(): DeviceManagementKit {\n return this._dmk;\n }\n\n stopDiscovery(): void {\n if (this._discoverySub) {\n this._discoverySub.unsubscribe();\n this._discoverySub = null;\n this._dmk.stopDiscovering();\n }\n }\n\n dispose(): void {\n this.stopListening();\n this.stopDiscovery();\n this._discovered.clear();\n this._sessions.clear();\n this._sessionToDevice.clear();\n this._dmk.close();\n }\n}\n","import { SignerEthBuilder } from '@ledgerhq/device-signer-kit-ethereum';\nimport { ContextModuleBuilder } from '@ledgerhq/context-module';\n\nimport { SignerEth } from './SignerEth';\nimport { debugLog } from '../utils/debugLog';\n\nimport type { DeviceManagementKit } from '@ledgerhq/device-management-kit';\nimport type { SignerEth as ISdkSignerEth } from '@ledgerhq/device-signer-kit-ethereum';\n\ntype SignerEthBuilderFn = (args: {\n dmk: DeviceManagementKit;\n sessionId: string;\n}) => { build(): ISdkSignerEth } | Promise<{ build(): ISdkSignerEth }>;\n\n/**\n * Per-sessionId SignerEth factory. Builds fresh on every call — DMK signers\n * hold DeviceAction state that isn't safe to reuse, so `invalidate` /\n * `clearAll` are kept as no-op lifecycle hooks for callers.\n */\nexport class SignerManager {\n private readonly _dmk: DeviceManagementKit;\n\n private readonly _builderFn: SignerEthBuilderFn;\n\n constructor(dmk: DeviceManagementKit, builderFn?: SignerEthBuilderFn) {\n this._dmk = dmk;\n this._builderFn = builderFn ?? SignerManager._defaultBuilder();\n }\n\n async getOrCreate(sessionId: string): Promise<SignerEth> {\n debugLog('[DMK] SignerManager.getOrCreate:', { sessionId });\n const builder = await this._builderFn({ dmk: this._dmk, sessionId });\n return new SignerEth(builder.build());\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, class-methods-use-this\n invalidate(_sessionId: string): void {}\n\n // eslint-disable-next-line class-methods-use-this\n clearAll(): void {}\n\n private static _defaultBuilder(): SignerEthBuilderFn {\n return args => {\n const contextModule = new ContextModuleBuilder({}).removeDefaultLoaders().build();\n return new SignerEthBuilder(args).withContextModule(contextModule);\n };\n }\n}\n","import { hexToBytes } from '@onekeyfe/hwk-adapter-core';\n\nimport { deviceActionToPromise } from './deviceActionToPromise';\nimport { debugLog } from '../utils/debugLog';\n\nimport type { SignerEth as ISdkSignerEth, TypedData } from '@ledgerhq/device-signer-kit-ethereum';\nimport type { SignerEvmAddress, SignerEvmSignature } from '../types';\n\n/** Timeout for user-interactive operations (verify address, sign). */\nconst INTERACTIVE_TIMEOUT_MS = 5 * 60_000;\n\n/**\n * Wraps Ledger's SDK signer (Observable-based DeviceActions) into\n * a simple async interface returning plain serializable data.\n */\nexport class SignerEth {\n onInteraction?: (interaction: string) => void;\n\n // eslint-disable-next-line no-useless-constructor, no-empty-function\n constructor(private readonly _sdk: ISdkSignerEth) {}\n\n /**\n * Optional callback registered per-call so the caller can obtain a canceller\n * for the underlying DeviceAction. Caller can invoke it to release DMK's\n * IntentQueue slot and unsubscribe from the action's observable.\n */\n onRegisterCanceller?: (cancel: () => void) => void;\n\n async getAddress(\n derivationPath: string,\n options?: { checkOnDevice?: boolean }\n ): Promise<SignerEvmAddress> {\n const checkOnDevice = options?.checkOnDevice ?? false;\n debugLog('[DMK] getAddress → DMK:', { derivationPath, checkOnDevice });\n const action = this._sdk.getAddress(derivationPath, {\n checkOnDevice,\n });\n // checkOnDevice needs user interaction → long timeout; otherwise default 30s\n const timeout = checkOnDevice ? INTERACTIVE_TIMEOUT_MS : undefined;\n return deviceActionToPromise<SignerEvmAddress>(\n action,\n this.onInteraction,\n timeout,\n this.onRegisterCanceller\n );\n }\n\n async signTransaction(\n derivationPath: string,\n serializedTxHex: string\n ): Promise<SignerEvmSignature> {\n const action = this._sdk.signTransaction(derivationPath, hexToBytes(serializedTxHex));\n return deviceActionToPromise<SignerEvmSignature>(\n action,\n this.onInteraction,\n INTERACTIVE_TIMEOUT_MS,\n this.onRegisterCanceller\n );\n }\n\n async signMessage(derivationPath: string, message: string): Promise<SignerEvmSignature> {\n // DMK treats string as ASCII text (addAsciiStringToData), but we receive\n // hex-encoded message bytes. Decode to Uint8Array so DMK uses\n // addBufferToData — matching the OneKey SDK's behavior.\n const action = this._sdk.signMessage(derivationPath, hexToBytes(message));\n return deviceActionToPromise<SignerEvmSignature>(\n action,\n this.onInteraction,\n INTERACTIVE_TIMEOUT_MS,\n this.onRegisterCanceller\n );\n }\n\n async signTypedData(derivationPath: string, data: TypedData): Promise<SignerEvmSignature> {\n const action = this._sdk.signTypedData(derivationPath, data);\n return deviceActionToPromise<SignerEvmSignature>(\n action,\n this.onInteraction,\n INTERACTIVE_TIMEOUT_MS,\n this.onRegisterCanceller\n );\n }\n}\n","import { DeviceActionStatus } from '@ledgerhq/device-management-kit';\n\nimport { debugLog } from '../utils/debugLog';\n\nimport type { DeviceAction, DeviceActionState } from '../types';\n\n/** Default timeout for non-interactive operations (e.g. getAddress without showOnDevice). */\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/**\n * Convert a DMK DeviceAction (Observable-based) into a Promise.\n * Handles pending -> completed/error state transitions and interaction callbacks.\n *\n * Tracks the last DMK step observed (e.g. `signer.eth.steps.blindSignTransactionFallback`)\n * and attaches it to the rejected error as a non-enumerable `_lastStep` property,\n * so upstream error classifiers can distinguish failure contexts (e.g. Blind signing\n * disabled vs. generic Invalid data).\n *\n * @param timeoutMs Timeout in ms. Resets each time the Observable emits (device is alive).\n * Pass 0 to disable. Default: 30s.\n * @param onRegisterCanceller Optional callback that receives a function which, when\n * called, unsubscribes and cancels the underlying DeviceAction\n * (releases DMK's IntentQueue slot). Caller is responsible\n * for invoking the canceller on timeout/abort scenarios.\n */\nexport function deviceActionToPromise<T>(\n action: DeviceAction<T>,\n onInteraction?: (interaction: string) => void,\n timeoutMs: number = DEFAULT_TIMEOUT_MS,\n onRegisterCanceller?: (cancel: () => void) => void\n): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n let settled = false;\n let lastStep: string | undefined;\n // eslint-disable-next-line prefer-const -- assigned once after declaration, but must be declared before use in cleanup\n let sub: { unsubscribe: () => void };\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n /** Fully tear down this action: unsubscribe + release DMK intent queue slot. */\n const cancelAction = () => {\n try {\n sub?.unsubscribe();\n } catch {\n // subscription may already be closed; ignore\n }\n try {\n action.cancel();\n } catch {\n // DMK action may already be settled; ignore\n }\n };\n\n const resetTimer = () => {\n if (timer) clearTimeout(timer);\n if (timeoutMs > 0) {\n timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n cancelAction();\n reject(new Error('Device action timed out — device may be locked or disconnected'));\n }\n }, timeoutMs);\n }\n };\n\n // Start initial timer\n resetTimer();\n\n // Expose a canceller for external abort (release DMK queue slot + unsubscribe).\n if (onRegisterCanceller) {\n onRegisterCanceller(() => {\n if (settled) return;\n settled = true;\n if (timer) clearTimeout(timer);\n cancelAction();\n reject(new Error('Device action cancelled'));\n });\n }\n\n debugLog('[DMK-Observable] subscribing to action.observable...');\n sub = action.observable.subscribe({\n next: (state: DeviceActionState<T>) => {\n // Drop late emissions post-cancel; otherwise resetTimer re-arms an unclearable timer.\n if (settled) return;\n resetTimer(); // device is alive → reset timeout\n\n // Track last DMK step so caller can disambiguate failure contexts\n // (e.g. 0x6a80 during blindSignTransactionFallback = Blind signing disabled)\n const step = (state as { intermediateValue?: { step?: string } })?.intermediateValue?.step;\n if (step) lastStep = step;\n\n debugLog(\n '[DMK-Observable] state:',\n JSON.stringify({\n status: state.status,\n intermediateValue:\n state.status === DeviceActionStatus.Pending ? state.intermediateValue : undefined,\n hasOutput: state.status === DeviceActionStatus.Completed,\n hasError: state.status === DeviceActionStatus.Error,\n })\n );\n if (state.status === DeviceActionStatus.Completed) {\n settled = true;\n if (timer) clearTimeout(timer);\n onInteraction?.('interaction-complete');\n sub?.unsubscribe();\n resolve(state.output);\n } else if (state.status === DeviceActionStatus.Error) {\n settled = true;\n if (timer) clearTimeout(timer);\n onInteraction?.('interaction-complete');\n sub?.unsubscribe();\n rejectWithLastStep(state.error, lastStep, reject);\n } else if (state.status === DeviceActionStatus.Pending && onInteraction) {\n const interaction = state.intermediateValue?.requiredUserInteraction;\n if (interaction && interaction !== 'none') {\n onInteraction(String(interaction));\n }\n }\n },\n error: (err: unknown) => {\n if (!settled) {\n settled = true;\n if (timer) clearTimeout(timer);\n sub?.unsubscribe();\n rejectWithLastStep(err, lastStep, reject);\n }\n },\n complete: () => {\n if (!settled) {\n settled = true;\n if (timer) clearTimeout(timer);\n reject(new Error('Device action completed without result'));\n }\n },\n });\n });\n}\n\n/**\n * Reject with the DMK error after annotating the last step observed before\n * failure. The step is attached as a non-enumerable property so it doesn't\n * pollute JSON.stringify / log output, but classifiers can still read it via\n * `(err as any)._lastStep`.\n */\nfunction rejectWithLastStep(\n err: unknown,\n lastStep: string | undefined,\n reject: (reason: unknown) => void\n): void {\n if (err && typeof err === 'object' && lastStep) {\n try {\n Object.defineProperty(err, '_lastStep', {\n value: lastStep,\n configurable: true,\n enumerable: false,\n writable: true,\n });\n } catch {\n // Frozen error objects — give up, classifier will fall back.\n }\n }\n reject(err);\n}\n","import { HardwareErrorCode, padHex64, stripHex } from '@onekeyfe/hwk-adapter-core';\n\nimport { collapseSignerInteraction, normalizePath } from './utils';\nimport { debugLog } from '../../utils/debugLog';\n\nimport type { TypedData } from '@ledgerhq/device-signer-kit-ethereum';\nimport type { SignerEvmSignature } from '../../types';\nimport type { ConnectorContext } from './types';\n\n// ---------------------------------------------------------------------------\n// Call param types\n// ---------------------------------------------------------------------------\n\nexport interface EvmGetAddressCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\nexport interface EvmSignTransactionCallParams {\n path: string;\n /** RLP-serialized transaction hex (0x-prefixed or plain) */\n serializedTx?: string;\n}\n\nexport interface EvmSignMessageCallParams {\n path: string;\n message: string;\n}\n\nexport interface EvmSignTypedDataCallParams {\n path: string;\n data: TypedData;\n mode?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Handler\n// ---------------------------------------------------------------------------\n\nexport async function evmGetAddress(\n ctx: ConnectorContext,\n sessionId: string,\n params: EvmGetAddressCallParams\n): Promise<{ address: string; publicKey?: string }> {\n const signer = await _getEthSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n const checkOnDevice = params.showOnDevice ?? false;\n debugLog('[DMK] evmGetAddress -> signer.getAddress:', { path, checkOnDevice });\n\n try {\n const result = await signer.getAddress(path, { checkOnDevice });\n return { address: result.address, publicKey: result.publicKey };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function evmSignTransaction(\n ctx: ConnectorContext,\n sessionId: string,\n params: EvmSignTransactionCallParams\n): Promise<{ v: string; r: string; s: string }> {\n if (!params.serializedTx) {\n throw Object.assign(\n new Error(\n 'Ledger requires a pre-serialized transaction (serializedTx). Provide an RLP-encoded hex string.'\n ),\n { code: HardwareErrorCode.InvalidParams }\n );\n }\n\n const signer = await _getEthSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n\n try {\n const result: SignerEvmSignature = await signer.signTransaction(path, params.serializedTx);\n return {\n v: `0x${result.v.toString(16)}`,\n r: padHex64(result.r),\n s: padHex64(result.s),\n };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function evmSignMessage(\n ctx: ConnectorContext,\n sessionId: string,\n params: EvmSignMessageCallParams\n): Promise<{ signature: string }> {\n const signer = await _getEthSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n\n try {\n const result: SignerEvmSignature = await signer.signMessage(path, params.message);\n const rHex = stripHex(result.r).padStart(64, '0');\n const sHex = stripHex(result.s).padStart(64, '0');\n const vHex = result.v.toString(16).padStart(2, '0');\n return { signature: `0x${rHex}${sHex}${vHex}` };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function evmSignTypedData(\n ctx: ConnectorContext,\n sessionId: string,\n params: EvmSignTypedDataCallParams\n): Promise<{ signature: string }> {\n if (params.mode === 'hash') {\n throw Object.assign(\n new Error(\n 'Ledger does not support hash-only EIP-712 signing. Use mode \"full\" with the complete typed data structure.'\n ),\n { code: HardwareErrorCode.MethodNotSupported }\n );\n }\n\n const signer = await _getEthSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n\n try {\n const result: SignerEvmSignature = await signer.signTypedData(path, params.data);\n const rHex = stripHex(result.r).padStart(64, '0');\n const sHex = stripHex(result.s).padStart(64, '0');\n const vHex = result.v.toString(16).padStart(2, '0');\n return { signature: `0x${rHex}${sHex}${vHex}` };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal — ETH signer creation\n// ---------------------------------------------------------------------------\n\nasync function _getEthSigner(ctx: ConnectorContext, sessionId: string) {\n const signerManager = await ctx.getSignerManager();\n const signer = await signerManager.getOrCreate(sessionId);\n\n // Wire up interaction events (open-app, unlock, verify-address, sign, etc.)\n // DMK-specific values (verify-address, sign-transaction, sign-typed-data,\n // sign-personal-message) collapse to ConfirmOnDevice via the helper.\n signer.onInteraction = (interaction: string) => {\n ctx.emit('ui-event', {\n type: collapseSignerInteraction(interaction),\n payload: { sessionId },\n });\n };\n\n // Expose DeviceAction canceller to the connector so that cancel(sessionId)\n // can release DMK's intent queue slot and unsubscribe cleanly.\n signer.onRegisterCanceller = (cancel: () => void) => {\n ctx.registerCanceller(sessionId, cancel);\n };\n\n return signer;\n}\n","import { EConnectorInteraction } from '@onekeyfe/hwk-adapter-core';\n\n/**\n * Strip the \"m/\" prefix from BIP-44 derivation paths.\n * Ledger DMK requires paths without the \"m/\" prefix.\n */\nexport function normalizePath(path: string): string {\n return path.startsWith('m/') ? path.slice(2) : path;\n}\n\n/**\n * Collapse Ledger DMK's raw `requiredUserInteraction` strings into the\n * 4-value EConnectorInteraction union exported by this SDK.\n *\n * DMK emits chain-signer-specific strings like \"verify-address\",\n * \"sign-transaction\", \"sign-typed-data\", \"sign-personal-message\" — they\n * all mean \"the user must act on the device screen\", i.e. ConfirmOnDevice\n * per the public ConnectorUiEvent type contract. Leaking raw DMK strings\n * out of the SDK would break consumers that switch on EConnectorInteraction.\n */\nexport function collapseSignerInteraction(interaction: string): EConnectorInteraction {\n switch (interaction) {\n case 'confirm-open-app':\n return EConnectorInteraction.ConfirmOpenApp;\n case 'unlock-device':\n return EConnectorInteraction.UnlockDevice;\n case 'interaction-complete':\n return EConnectorInteraction.InteractionComplete;\n default:\n return EConnectorInteraction.ConfirmOnDevice;\n }\n}\n","import { HardwareErrorCode, stripHex } from '@onekeyfe/hwk-adapter-core';\nimport { Psbt } from 'bitcoinjs-lib';\n\nimport { collapseSignerInteraction, normalizePath } from './utils';\nimport { SignerBtc } from '../../signer/SignerBtc';\nimport { debugError, debugLog } from '../../utils/debugLog';\n\nimport type { ConnectorContext } from './types';\n\n// ---------------------------------------------------------------------------\n// Call param types\n// ---------------------------------------------------------------------------\n\nexport interface BtcGetAddressCallParams {\n /** Account-level derivation path (3 levels, e.g. \"m/86'/0'/0'\") */\n path: string;\n showOnDevice?: boolean;\n /** Address index within the account (default: 0) */\n addressIndex?: number;\n /** Whether this is a change address (default: false) */\n change?: boolean;\n}\n\nexport interface BtcGetPublicKeyCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\nexport interface BtcSignTransactionCallParams {\n psbt?: string;\n coin: string;\n /** Account-level derivation path for wallet template determination (e.g. \"84'/0'/0'\"). */\n path?: string;\n}\n\nexport interface BtcSignPsbtCallParams {\n psbt: string;\n coin?: string;\n path?: string;\n}\n\nexport interface BtcSignMessageCallParams {\n path: string;\n message: string;\n coin?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Internal -- BIP-44 purpose → Ledger wallet template\n// ---------------------------------------------------------------------------\n\n/**\n * BIP-44 purpose → Ledger descriptor template. Throws on unknown —\n * silent NATIVE_SEGWIT fallback would yield wrong addresses for\n * multisig (m/48') / legacy BIP-45 accounts. DDT is injected because\n * it comes from a runtime `importLedgerKit`.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction _purposeToTemplate(purpose: string | undefined, DDT: any): any {\n switch (purpose) {\n case '44':\n return DDT.LEGACY;\n case '49':\n return DDT.NESTED_SEGWIT;\n case '84':\n return DDT.NATIVE_SEGWIT;\n case '86':\n return DDT.TAPROOT;\n default:\n throw Object.assign(new Error(`Unsupported BTC purpose: m/${purpose ?? '<undefined>'}'`), {\n code: HardwareErrorCode.InvalidParams,\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Handlers\n// ---------------------------------------------------------------------------\n\nexport async function btcGetAddress(\n ctx: ConnectorContext,\n sessionId: string,\n params: BtcGetAddressCallParams\n): Promise<{ address: string; path: string }> {\n const btcSigner = await _createBtcSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n\n try {\n const { DefaultWallet, DefaultDescriptorTemplate } = await ctx.importLedgerKit(\n '@ledgerhq/device-signer-kit-bitcoin'\n );\n const purpose = path.split('/')[0]?.replace(/'/g, '');\n const template = _purposeToTemplate(purpose, DefaultDescriptorTemplate);\n const wallet = new DefaultWallet(path, template);\n\n debugLog('[LedgerConnector] btcGetAddress params:', {\n path,\n purpose,\n template,\n addressIndex: params.addressIndex,\n change: params.change,\n showOnDevice: params.showOnDevice,\n });\n\n const result = await btcSigner.getWalletAddress(wallet, params.addressIndex ?? 0, {\n checkOnDevice: params.showOnDevice ?? false,\n change: params.change ?? false,\n });\n return { address: result.address, path: params.path };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function btcGetPublicKey(\n ctx: ConnectorContext,\n sessionId: string,\n params: BtcGetPublicKeyCallParams\n): Promise<{ xpub: string; path: string }> {\n const btcSigner = await _createBtcSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n\n debugLog('[LedgerConnector] btcGetPublicKey called, path:', path, 'sessionId:', sessionId);\n try {\n const xpub = await btcSigner.getExtendedPublicKey(path, {\n checkOnDevice: params.showOnDevice ?? false,\n });\n debugLog('[LedgerConnector] btcGetPublicKey success, xpub:', `${xpub?.substring(0, 20)}...`);\n return { xpub, path: params.path };\n } catch (err) {\n debugError('[LedgerConnector] btcGetPublicKey error, path:', path, 'err:', err);\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function btcSignTransaction(\n ctx: ConnectorContext,\n sessionId: string,\n params: BtcSignTransactionCallParams\n): Promise<{ serializedTx: string }> {\n if (!params.psbt) {\n throw Object.assign(\n new Error('Ledger requires PSBT format for BTC transaction signing. Provide params.psbt.'),\n { code: HardwareErrorCode.InvalidParams }\n );\n }\n\n const btcSigner = await _createBtcSigner(ctx, sessionId);\n\n try {\n const { DefaultWallet, DefaultDescriptorTemplate } = await ctx.importLedgerKit(\n '@ledgerhq/device-signer-kit-bitcoin'\n );\n\n // Determine wallet template from the account-level derivation path\n const path = normalizePath(params.path || \"84'/0'/0'\");\n const purpose = path.split('/')[0]?.replace(/'/g, '');\n const template = _purposeToTemplate(purpose, DefaultDescriptorTemplate);\n\n const wallet = new DefaultWallet(path, template);\n\n const signedTxHex = await btcSigner.signTransaction(wallet, params.psbt);\n\n return { serializedTx: stripHex(signedTxHex) };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function btcSignPsbt(\n ctx: ConnectorContext,\n sessionId: string,\n params: BtcSignPsbtCallParams\n): Promise<{ signedPsbt: string }> {\n if (!params.psbt) {\n throw Object.assign(new Error('btcSignPsbt requires params.psbt'), {\n code: HardwareErrorCode.InvalidParams,\n });\n }\n\n const btcSigner = await _createBtcSigner(ctx, sessionId);\n\n try {\n const { DefaultWallet, DefaultDescriptorTemplate } = await ctx.importLedgerKit(\n '@ledgerhq/device-signer-kit-bitcoin'\n );\n\n const path = normalizePath(params.path || \"84'/0'/0'\");\n const purpose = path.split('/')[0]?.replace(/'/g, '');\n const template = _purposeToTemplate(purpose, DefaultDescriptorTemplate);\n\n const wallet = new DefaultWallet(path, template);\n\n const signatures = (await btcSigner.signPsbt(wallet, params.psbt)) as Array<{\n inputIndex: number;\n pubkey: Uint8Array;\n signature: Uint8Array;\n tapleafHash?: Uint8Array;\n }>;\n\n const signedPsbtHex = _applySignaturesToPsbt(params.psbt, signatures);\n return { signedPsbt: signedPsbtHex };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function btcSignMessage(\n ctx: ConnectorContext,\n sessionId: string,\n params: BtcSignMessageCallParams\n): Promise<{ signature: string; address?: string }> {\n const btcSigner = await _createBtcSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n\n try {\n // signMessage returns { r: HexaString, s: HexaString, v: number }\n const result = await btcSigner.signMessage(path, params.message);\n\n // BIP-137: signature = v(1) + r(32) + s(32); returned as hex (OneKey SDK style).\n const vHex = result.v.toString(16).padStart(2, '0');\n const rHex = stripHex(result.r).padStart(64, '0');\n const sHex = stripHex(result.s).padStart(64, '0');\n\n return { signature: `${vHex}${rHex}${sHex}` };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function btcGetMasterFingerprint(\n ctx: ConnectorContext,\n sessionId: string,\n params?: { skipOpenApp?: boolean }\n): Promise<{ masterFingerprint: string }> {\n const btcSigner = await _createBtcSigner(ctx, sessionId);\n\n try {\n const fingerprint: Uint8Array = await btcSigner.getMasterFingerprint({\n skipOpenApp: params?.skipOpenApp,\n });\n // Convert Uint8Array to hex string\n const hex = Array.from(fingerprint)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('');\n return { masterFingerprint: hex };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal -- BTC signer creation\n// ---------------------------------------------------------------------------\n\nasync function _createBtcSigner(ctx: ConnectorContext, sessionId: string): Promise<SignerBtc> {\n const dmk = await ctx.getOrCreateDmk();\n const { SignerBtcBuilder } = await ctx.importLedgerKit('@ledgerhq/device-signer-kit-bitcoin');\n const sdkSigner = new SignerBtcBuilder({ dmk, sessionId }).build();\n const signer = new SignerBtc(sdkSigner);\n\n // Wire up interaction events (open-app, unlock, sign, etc.)\n // DMK-specific values (sign-transaction, sign-personal-message,\n // verify-address) collapse to ConfirmOnDevice via the helper.\n signer.onInteraction = (interaction: string) => {\n ctx.emit('ui-event', {\n type: collapseSignerInteraction(interaction),\n payload: { sessionId },\n });\n };\n\n signer.onRegisterCanceller = (cancel: () => void) => {\n ctx.registerCanceller(sessionId, cancel);\n };\n\n return signer;\n}\n\n// ---------------------------------------------------------------------------\n// Internal -- Apply partial signatures to PSBT\n// ---------------------------------------------------------------------------\n\ntype PsbtInput = Psbt['data']['inputs'][number];\n\nfunction _isTaprootInput(input: PsbtInput): boolean {\n if (\n input.tapInternalKey ||\n input.tapKeySig ||\n input.tapLeafScript ||\n input.tapMerkleRoot ||\n input.tapBip32Derivation ||\n input.tapScriptSig\n )\n return true;\n // P2TR scriptPubKey: OP_1 (0x51) + PUSH32 (0x20) + <32B x-only>\n const script = input.witnessUtxo?.script;\n return !!(script && script.length === 34 && script[0] === 0x51 && script[1] === 0x20);\n}\n\nfunction _isScriptPathInput(input: PsbtInput): boolean {\n return !!(input.tapLeafScript && input.tapLeafScript.length > 0);\n}\n\n/**\n * Dispatch DMK-returned signatures to the correct PSBT field using the\n * input's scriptPubKey as authoritative signal; throws on shape violations.\n */\nexport function _applySignaturesToPsbt(\n psbtHex: string,\n signatures: Array<{\n inputIndex: number;\n pubkey: Uint8Array;\n signature: Uint8Array;\n tapleafHash?: Uint8Array;\n }>\n): string {\n const psbt = Psbt.fromHex(psbtHex);\n for (const sig of signatures) {\n const input = psbt.data.inputs[sig.inputIndex];\n if (!input) {\n throw new Error(`_applySignaturesToPsbt: no PSBT input at index ${sig.inputIndex}`);\n }\n const taproot = _isTaprootInput(input);\n const scriptPath = taproot && _isScriptPathInput(input);\n const hasLeafHash = !!(sig.tapleafHash && sig.tapleafHash.length > 0);\n\n if (scriptPath) {\n if (sig.pubkey.length !== 32)\n throw new Error(\n `input ${sig.inputIndex}: taproot script-path pubkey must be 32B, got ${sig.pubkey.length}`\n );\n if (!hasLeafHash)\n throw new Error(\n `input ${sig.inputIndex}: taproot script-path signature missing tapleafHash`\n );\n psbt.updateInput(sig.inputIndex, {\n tapScriptSig: [\n { pubkey: sig.pubkey, leafHash: sig.tapleafHash!, signature: sig.signature },\n ],\n });\n } else if (taproot) {\n if (sig.pubkey.length !== 32)\n throw new Error(\n `input ${sig.inputIndex}: taproot key-path pubkey must be 32B, got ${sig.pubkey.length}`\n );\n if (hasLeafHash)\n throw new Error(\n `input ${sig.inputIndex}: taproot key-path signature must not carry tapleafHash`\n );\n psbt.updateInput(sig.inputIndex, { tapKeySig: sig.signature });\n } else {\n if (sig.pubkey.length !== 33 && sig.pubkey.length !== 65)\n throw new Error(\n `input ${sig.inputIndex}: ECDSA pubkey must be 33B or 65B, got ${sig.pubkey.length}`\n );\n if (hasLeafHash)\n throw new Error(`input ${sig.inputIndex}: ECDSA signature must not carry tapleafHash`);\n psbt.updateInput(sig.inputIndex, {\n partialSig: [{ pubkey: sig.pubkey, signature: sig.signature }],\n });\n }\n }\n return psbt.toHex();\n}\n","import { hexToBytes } from '@onekeyfe/hwk-adapter-core';\n\nimport { deviceActionToPromise } from './deviceActionToPromise';\nimport { debugError, debugLog } from '../utils/debugLog';\n\nimport type { SignerBtc as ISdkSignerBtc } from '@ledgerhq/device-signer-kit-bitcoin';\nimport type { SignerBtcAddress } from '../types';\n\n// Extract parameter types from the real SignerBtc interface to avoid deep path imports.\ntype BtcWallet = Parameters<ISdkSignerBtc['getWalletAddress']>[0];\ntype BtcPsbt = Parameters<ISdkSignerBtc['signPsbt']>[1];\ntype BtcPsbtOptions = Parameters<ISdkSignerBtc['signPsbt']>[2];\ntype BtcMessageOptions = Parameters<ISdkSignerBtc['signMessage']>[2];\n\n/** Decode hex string (with or without 0x prefix) to UTF-8 text. */\nfunction hexToUtf8(hex: string): string {\n return new TextDecoder().decode(hexToBytes(hex));\n}\n\n/** Timeout for user-interactive operations (sign, verify). */\nconst INTERACTIVE_TIMEOUT_MS = 5 * 60_000;\n\n/**\n * Wraps Ledger's BTC SDK signer (Observable-based DeviceActions) into\n * a simple async interface returning plain serializable data.\n */\nexport class SignerBtc {\n onInteraction?: (interaction: string) => void;\n\n onRegisterCanceller?: (cancel: () => void) => void;\n\n // eslint-disable-next-line no-useless-constructor, no-empty-function\n constructor(private readonly _sdk: ISdkSignerBtc) {}\n\n async getWalletAddress(\n wallet: BtcWallet,\n addressIndex: number,\n options?: { checkOnDevice?: boolean; change?: boolean }\n ): Promise<SignerBtcAddress> {\n const action = this._sdk.getWalletAddress(wallet, addressIndex, {\n checkOnDevice: options?.checkOnDevice ?? false,\n change: options?.change ?? false,\n });\n return deviceActionToPromise<SignerBtcAddress>(\n action,\n this.onInteraction,\n undefined,\n this.onRegisterCanceller\n );\n }\n\n async getExtendedPublicKey(\n derivationPath: string,\n options?: { checkOnDevice?: boolean }\n ): Promise<string> {\n debugLog(\n '[SignerBtc] getExtendedPublicKey called, path:',\n derivationPath,\n 'options:',\n JSON.stringify(options)\n );\n const action = this._sdk.getExtendedPublicKey(derivationPath, {\n checkOnDevice: options?.checkOnDevice ?? false,\n });\n try {\n // DMK returns { extendedPublicKey: string }, unwrap it\n const result = await deviceActionToPromise<string | { extendedPublicKey: string }>(\n action,\n this.onInteraction,\n undefined,\n this.onRegisterCanceller\n );\n debugLog(\n '[SignerBtc] getExtendedPublicKey result type:',\n typeof result,\n 'value:',\n typeof result === 'string'\n ? `${result.substring(0, 20)}...`\n : JSON.stringify(result).substring(0, 50)\n );\n if (typeof result === 'string') return result;\n return result.extendedPublicKey;\n } catch (err) {\n debugError('[SignerBtc] getExtendedPublicKey error:', err);\n throw err;\n }\n }\n\n async getMasterFingerprint(options?: { skipOpenApp?: boolean }): Promise<Uint8Array> {\n const action = this._sdk.getMasterFingerprint(options);\n const result = await deviceActionToPromise<{ masterFingerprint: Uint8Array }>(\n action,\n this.onInteraction,\n undefined,\n this.onRegisterCanceller\n );\n return result.masterFingerprint;\n }\n\n /**\n * Sign a PSBT and return the array of partial signatures.\n * The `wallet` param is a DefaultWallet or WalletPolicy instance.\n * The `psbt` param can be a hex string, base64 string, or Uint8Array.\n */\n async signPsbt(wallet: BtcWallet, psbt: BtcPsbt, options?: BtcPsbtOptions): Promise<unknown[]> {\n const action = this._sdk.signPsbt(wallet, psbt, options);\n return deviceActionToPromise<unknown[]>(\n action,\n this.onInteraction,\n INTERACTIVE_TIMEOUT_MS,\n this.onRegisterCanceller\n );\n }\n\n /**\n * Sign a PSBT and return the fully extracted raw transaction as a hex string.\n * Like signPsbt, but also finalises the PSBT and extracts the transaction.\n */\n async signTransaction(\n wallet: BtcWallet,\n psbt: BtcPsbt,\n options?: BtcPsbtOptions\n ): Promise<string> {\n const action = this._sdk.signTransaction(wallet, psbt, options);\n return deviceActionToPromise<string>(\n action,\n this.onInteraction,\n INTERACTIVE_TIMEOUT_MS,\n this.onRegisterCanceller\n );\n }\n\n /**\n * Sign a message with the BTC app (BIP-137 / \"Bitcoin Signed Message\").\n * Returns `{ r, s, v }` signature object.\n */\n async signMessage(\n derivationPath: string,\n message: string,\n options?: BtcMessageOptions\n ): Promise<{ r: string; s: string; v: number }> {\n // DMK uses TextEncoder to convert message string to bytes.\n // We receive hex-encoded message, so decode hex -> UTF-8 text first.\n const action = this._sdk.signMessage(derivationPath, hexToUtf8(message), options);\n return deviceActionToPromise<{ r: string; s: string; v: number }>(\n action,\n this.onInteraction,\n INTERACTIVE_TIMEOUT_MS,\n this.onRegisterCanceller\n );\n }\n}\n","import { bytesToHex, hexToBytes } from '@onekeyfe/hwk-adapter-core';\n\nimport { collapseSignerInteraction, normalizePath } from './utils';\nimport { SignerSol } from '../../signer/SignerSol';\n\nimport type { ConnectorContext } from './types';\n\n// ---------------------------------------------------------------------------\n// Call param types\n// ---------------------------------------------------------------------------\n\nexport interface SolGetAddressCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\nexport interface SolSignTransactionCallParams {\n path: string;\n /** Hex-encoded serialized transaction bytes (no 0x prefix) */\n serializedTx: string;\n}\n\nexport interface SolSignMessageCallParams {\n path: string;\n /** Message bytes as hex string (no 0x prefix) */\n message: string;\n}\n\n// ---------------------------------------------------------------------------\n// Handlers\n// ---------------------------------------------------------------------------\n\nexport async function solGetAddress(\n ctx: ConnectorContext,\n sessionId: string,\n params: SolGetAddressCallParams\n): Promise<{ address: string; path: string }> {\n const solSigner = await _createSolSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n\n try {\n // Ledger Solana signer returns a base58-encoded Ed25519 public key (= Solana address)\n const publicKey = await solSigner.getAddress(path, {\n checkOnDevice: params.showOnDevice ?? false,\n });\n return { address: publicKey, path: params.path };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function solSignTransaction(\n ctx: ConnectorContext,\n sessionId: string,\n params: SolSignTransactionCallParams\n): Promise<{ signature: string }> {\n const solSigner = await _createSolSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n const txBytes = hexToBytes(params.serializedTx);\n\n try {\n const result = await solSigner.signTransaction(path, txBytes);\n return { signature: bytesToHex(result) };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\nexport async function solSignMessage(\n ctx: ConnectorContext,\n sessionId: string,\n params: SolSignMessageCallParams\n): Promise<{ signature: string }> {\n const solSigner = await _createSolSigner(ctx, sessionId);\n const path = normalizePath(params.path);\n const messageBytes = hexToBytes(params.message);\n\n try {\n // DMK signMessage returns { signature: string }, not raw Uint8Array\n const result = await solSigner.signMessage(path, messageBytes);\n return { signature: result.signature };\n } catch (err) {\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n } finally {\n ctx.clearCanceller(sessionId);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal -- SOL signer creation\n// ---------------------------------------------------------------------------\n\nasync function _createSolSigner(ctx: ConnectorContext, sessionId: string): Promise<SignerSol> {\n const dmk = await ctx.getOrCreateDmk();\n const { ContextModuleBuilder } = await ctx.importLedgerKit('@ledgerhq/context-module');\n const { SignerSolanaBuilder } = await ctx.importLedgerKit('@ledgerhq/device-signer-kit-solana');\n const contextModule = new ContextModuleBuilder({}).removeDefaultLoaders().build();\n const sdkSigner = new SignerSolanaBuilder({ dmk, sessionId })\n .withContextModule(contextModule)\n .build();\n const signer = new SignerSol(sdkSigner);\n\n // Wire up interaction events (verify-address, sign, etc.)\n // DMK-specific values (verify-address, sign-transaction, sign-personal-message)\n // collapse to ConfirmOnDevice via the helper.\n signer.onInteraction = (interaction: string) => {\n ctx.emit('ui-event', {\n type: collapseSignerInteraction(interaction),\n payload: { sessionId },\n });\n };\n\n signer.onRegisterCanceller = (cancel: () => void) => {\n ctx.registerCanceller(sessionId, cancel);\n };\n\n return signer;\n}\n","import { deviceActionToPromise } from './deviceActionToPromise';\n\nimport type { SignerSolana as ISdkSignerSol } from '@ledgerhq/device-signer-kit-solana';\n\n// Extract parameter types from the real SignerSolana interface to avoid deep path imports.\ntype SolTxOptions = Parameters<ISdkSignerSol['signTransaction']>[2];\ntype SolMsgOptions = Parameters<ISdkSignerSol['signMessage']>[2];\n\n/**\n * Wraps Ledger's Solana SDK signer (Observable-based DeviceActions) into\n * a simple async interface returning plain serializable data.\n *\n * The Solana signer's `getAddress` returns a base58-encoded Ed25519 public key,\n * which is also the Solana address.\n */\nexport class SignerSol {\n onInteraction?: (interaction: string) => void;\n\n onRegisterCanceller?: (cancel: () => void) => void;\n\n // eslint-disable-next-line no-useless-constructor, no-empty-function\n constructor(private readonly _sdk: ISdkSignerSol) {}\n\n /**\n * Get the Solana address (base58-encoded Ed25519 public key) at the given derivation path.\n */\n async getAddress(derivationPath: string, options?: { checkOnDevice?: boolean }): Promise<string> {\n const action = this._sdk.getAddress(derivationPath, {\n checkOnDevice: options?.checkOnDevice ?? false,\n });\n return deviceActionToPromise<string>(\n action,\n this.onInteraction,\n undefined,\n this.onRegisterCanceller\n );\n }\n\n /**\n * Sign a Solana transaction.\n */\n async signTransaction(\n derivationPath: string,\n transaction: Uint8Array,\n options?: SolTxOptions\n ): Promise<Uint8Array> {\n const action = this._sdk.signTransaction(derivationPath, transaction, options);\n return deviceActionToPromise<Uint8Array>(\n action,\n this.onInteraction,\n undefined,\n this.onRegisterCanceller\n );\n }\n\n /**\n * Sign a message with the Solana app.\n * DMK returns { signature: string } for signMessage (unlike signTransaction which returns Uint8Array).\n */\n async signMessage(\n derivationPath: string,\n message: string | Uint8Array,\n options?: SolMsgOptions\n ): Promise<{ signature: string }> {\n const action = this._sdk.signMessage(derivationPath, message, options);\n return deviceActionToPromise<{ signature: string }>(\n action,\n this.onInteraction,\n undefined,\n this.onRegisterCanceller\n );\n }\n}\n","import { EConnectorInteraction, HardwareErrorCode } from '@onekeyfe/hwk-adapter-core';\nimport Trx from '@ledgerhq/hw-app-trx';\n\nimport { normalizePath } from './utils';\nimport { withLegacyAppRetry } from './legacyAppRetry';\nimport { AppManager } from '../../app/AppManager';\nimport { DmkTransport } from '../../transport/DmkTransport';\n\nimport type { ConnectorContext } from './types';\n\n// ---------------------------------------------------------------------------\n// Call param types\n// ---------------------------------------------------------------------------\n\nexport interface TronGetAddressCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\nexport interface TronSignTransactionCallParams {\n path: string;\n /** Protobuf-encoded raw transaction hex (no 0x prefix) */\n rawTxHex: string;\n /**\n * TRC token metadata for Ledger clear-signing. Omit → TRC-20 transfers\n * fall back to blind-signing (user sees only raw bytes on-device).\n */\n tokenSignatures?: string[];\n}\n\nexport interface TronSignMessageCallParams {\n path: string;\n /** Message hex (no 0x prefix) */\n messageHex: string;\n}\n\n// ---------------------------------------------------------------------------\n// Handlers\n// ---------------------------------------------------------------------------\n\nexport async function tronGetAddress(\n ctx: ConnectorContext,\n sessionId: string,\n params: TronGetAddressCallParams\n): Promise<{ address: string; publicKey: string; path: string }> {\n const path = normalizePath(params.path);\n await _ensureTronAppOpen(ctx, sessionId);\n return withLegacyAppRetry(ctx, sessionId, 'Tron', async sid => {\n const trx = await _createTrx(ctx, sid);\n if (params.showOnDevice) {\n ctx.emit('ui-event', {\n type: EConnectorInteraction.ConfirmOnDevice,\n payload: { sessionId: sid },\n });\n }\n const result = await trx.getAddress(path, params.showOnDevice ?? false);\n ctx.emit('ui-event', {\n type: EConnectorInteraction.InteractionComplete,\n payload: { sessionId: sid },\n });\n return { address: result.address, publicKey: result.publicKey, path: params.path };\n });\n}\n\nexport async function tronSignTransaction(\n ctx: ConnectorContext,\n sessionId: string,\n params: TronSignTransactionCallParams\n): Promise<{ signature: string }> {\n if (!params.rawTxHex) {\n throw Object.assign(\n new Error('TRON signing requires a protobuf-encoded raw transaction hex (rawTxHex).'),\n { code: HardwareErrorCode.InvalidParams }\n );\n }\n\n const path = normalizePath(params.path);\n await _ensureTronAppOpen(ctx, sessionId);\n return withLegacyAppRetry(ctx, sessionId, 'Tron', async sid => {\n const trx = await _createTrx(ctx, sid);\n ctx.emit('ui-event', {\n type: EConnectorInteraction.ConfirmOnDevice,\n payload: { sessionId: sid },\n });\n const signature = await trx.signTransaction(\n path,\n params.rawTxHex,\n params.tokenSignatures ?? []\n );\n ctx.emit('ui-event', {\n type: EConnectorInteraction.InteractionComplete,\n payload: { sessionId: sid },\n });\n return { signature };\n });\n}\n\nexport async function tronSignMessage(\n ctx: ConnectorContext,\n sessionId: string,\n params: TronSignMessageCallParams\n): Promise<{ signature: string }> {\n const path = normalizePath(params.path);\n await _ensureTronAppOpen(ctx, sessionId);\n return withLegacyAppRetry(ctx, sessionId, 'Tron', async sid => {\n const trx = await _createTrx(ctx, sid);\n ctx.emit('ui-event', {\n type: EConnectorInteraction.ConfirmOnDevice,\n payload: { sessionId: sid },\n });\n const signature = await trx.signPersonalMessage(path, params.messageHex);\n ctx.emit('ui-event', {\n type: EConnectorInteraction.InteractionComplete,\n payload: { sessionId: sid },\n });\n return { signature };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Internal\n// ---------------------------------------------------------------------------\n\nasync function _createTrx(ctx: ConnectorContext, sessionId: string): Promise<Trx> {\n const dmk = await ctx.getOrCreateDmk();\n return new Trx(new DmkTransport(dmk, sessionId));\n}\n\n/**\n * Proactively switch to the Tron app before sending a TRX APDU.\n *\n * Official DMK Signer kits (SignerEth / SignerBtc / SignerSol) get this for\n * free via DMK's DeviceAction pipeline — it calls `getDeviceStatus` + emits\n * `confirm-open-app` before sending any chain command. TRON can't use that\n * pipeline yet because `@ledgerhq/device-signer-kit-tron` doesn't exist; we\n * bridge `@ledgerhq/hw-app-trx` straight to `DmkTransport.exchange`, which\n * bypasses the pre-flight check.\n *\n * Without this, a TRX APDU fired while e.g. the Ethereum app is still open\n * gets answered by Ethereum (same CLA/INS, different data layout) with an\n * app-specific SW like 0x6A15. That SW is not in `WRONG_APP_CODES`, so\n * `withLegacyAppRetry` never triggers the auto-switch path and the user\n * sees \"UNKNOWN_ERROR (0x6a15)\".\n *\n * Remove this once Ledger ships `device-signer-kit-tron` and we can route\n * TRON through the same SignerManager DeviceAction flow as the other chains.\n */\nasync function _ensureTronAppOpen(ctx: ConnectorContext, sessionId: string): Promise<void> {\n const dmk = await ctx.getOrCreateDmk();\n const appManager = new AppManager(dmk);\n await appManager.ensureAppOpen(sessionId, 'Tron', () => {\n ctx.emit('ui-event', {\n type: EConnectorInteraction.ConfirmOpenApp,\n payload: { sessionId },\n });\n });\n}\n","import { EConnectorInteraction } from '@onekeyfe/hwk-adapter-core';\n\nimport { isWrongAppError } from '../../errors';\nimport { AppManager } from '../../app/AppManager';\n\nimport type { ConnectorContext } from './types';\n\n/**\n * Wrong-app detection for legacy SDKs. Wraps isWrongAppError so callers don't\n * depend on the shared function directly.\n *\n * Prior versions also treated \"any 4-hex code not in a per-app allowlist\" as\n * wrong-app, to catch cases where the message format hid the real status.\n * That was too aggressive: legacy hw-app-* throws TransportStatusError with a\n * numeric `statusCode` that isWrongAppError already handles via hasStatusCode,\n * so the regex path was dead weight for real errors and only fired on\n * unanticipated message shapes (random hex in logs, new firmware SWs) —\n * producing spurious app close→reopen cycles. `appName` is kept on the\n * signature for future per-app extension points.\n */\nexport function isLegacyWrongAppError(err: unknown, _appName: string): boolean {\n return isWrongAppError(err);\n}\n\n/**\n * Execute an action with automatic wrong-app retry for legacy SDK chains.\n *\n * 1. Try the action.\n * 2. If wrong-app error, use AppManager to switch to the target app.\n * 3. Retry once with the same session (session survives app switch).\n *\n * Works for any chain that uses a legacy hw-app-* SDK via DmkTransport.\n */\nexport async function withLegacyAppRetry<T>(\n ctx: ConnectorContext,\n sessionId: string,\n appName: string,\n action: (sid: string) => Promise<T>\n): Promise<T> {\n try {\n return await action(sessionId);\n } catch (err) {\n ctx.emit('ui-event', {\n type: EConnectorInteraction.InteractionComplete,\n payload: { sessionId },\n });\n if (isLegacyWrongAppError(err, appName)) {\n const dmk = await ctx.getOrCreateDmk();\n const appManager = new AppManager(dmk);\n try {\n await appManager.ensureAppOpen(sessionId, appName, () => {\n // Device is showing the confirm prompt — now it's safe to notify UI\n ctx.emit('ui-event', {\n type: EConnectorInteraction.ConfirmOpenApp,\n payload: { sessionId },\n });\n });\n } catch (switchErr) {\n ctx.emit('ui-event', {\n type: EConnectorInteraction.InteractionComplete,\n payload: { sessionId },\n });\n throw ctx.wrapError(switchErr);\n }\n ctx.clearAllSigners();\n ctx.emit('ui-event', {\n type: EConnectorInteraction.InteractionComplete,\n payload: { sessionId },\n });\n return await action(sessionId);\n }\n ctx.invalidateSession(sessionId);\n throw ctx.wrapError(err);\n }\n}\n","import {\n CloseAppCommand,\n type DeviceManagementKit,\n GetAppAndVersionCommand,\n OpenAppCommand,\n isSuccessCommandResult,\n} from '@ledgerhq/device-management-kit';\n\n/**\n * Map of chain ticker symbols to the Ledger app name\n * that must be open to sign transactions for that chain.\n */\nexport const APP_NAME_MAP: Record<string, string> = {\n ETH: 'Ethereum',\n BTC: 'Bitcoin',\n SOL: 'Solana',\n TRX: 'Tron',\n XRP: 'XRP',\n ADA: 'Cardano',\n DOT: 'Polkadot',\n ATOM: 'Cosmos',\n};\n\n/** The name reported by the Ledger when it sits on the home screen. */\nconst DASHBOARD_APP_NAME = 'BOLOS';\n\ninterface AppManagerOptions {\n waitMs?: number;\n maxRetries?: number;\n}\n\n/**\n * Orchestrates opening / closing Ledger on-device apps so that the\n * correct signer application is running before any signing call.\n */\nexport class AppManager {\n private readonly _dmk: DeviceManagementKit;\n\n private readonly _waitMs: number;\n\n private readonly _maxRetries: number;\n\n constructor(dmk: DeviceManagementKit, options?: AppManagerOptions) {\n this._dmk = dmk;\n this._waitMs = options?.waitMs ?? 1000;\n this._maxRetries = options?.maxRetries ?? 10;\n }\n\n /**\n * Return the Ledger app name for a given chain ticker,\n * or undefined if the chain is not supported.\n */\n static getAppName(chain: string): string | undefined {\n return APP_NAME_MAP[chain];\n }\n\n /**\n * Ensure the target app is open on the device identified by `sessionId`.\n *\n * Flow:\n * 1. Check the currently running app.\n * 2. If it is already the target, return immediately.\n * 3. If a different app is running (not dashboard), close it first.\n * 4. Open the target app.\n * 5. Poll until the device confirms the target app is running.\n */\n /**\n * @param onConfirmOnDevice Called after OpenAppCommand succeeds —\n * the device is now showing a confirmation prompt to the user.\n * NOT called if the app is already open or if the app is not installed.\n */\n async ensureAppOpen(\n sessionId: string,\n targetAppName: string,\n onConfirmOnDevice?: () => void\n ): Promise<void> {\n const currentApp = await this._getCurrentApp(sessionId);\n\n if (currentApp === targetAppName) {\n return;\n }\n\n // If we're not on the dashboard, close the current app first\n if (!this._isDashboard(currentApp)) {\n await this._closeCurrentApp(sessionId);\n // Wait for dashboard to become active\n await this._waitForApp(sessionId, DASHBOARD_APP_NAME);\n }\n\n // Open the target app — throws if not installed (0x6807)\n await this._openApp(sessionId, targetAppName);\n\n // Device is now showing the confirm prompt\n onConfirmOnDevice?.();\n\n // Poll until the target app is confirmed open\n await this._waitForApp(sessionId, targetAppName);\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private async _getCurrentApp(sessionId: string): Promise<string> {\n const result = await this._dmk.sendCommand({\n sessionId,\n command: new GetAppAndVersionCommand(),\n });\n if (isSuccessCommandResult(result)) {\n return result.data.name;\n }\n throw new Error('Failed to get current app from device');\n }\n\n private async _openApp(sessionId: string, appName: string): Promise<void> {\n const result = await this._dmk.sendCommand({\n sessionId,\n command: new OpenAppCommand({ appName }),\n });\n if (!isSuccessCommandResult(result)) {\n const { statusCode } = result as Record<string, unknown>;\n throw Object.assign(new Error(`Failed to open \"${appName}\"`), {\n _tag: 'OpenAppCommandError',\n errorCode: String(statusCode ?? ''),\n statusCode,\n appName,\n });\n }\n }\n\n private async _closeCurrentApp(sessionId: string): Promise<void> {\n await this._dmk.sendCommand({\n sessionId,\n command: new CloseAppCommand(),\n });\n }\n\n /**\n * Poll the device until the expected app is reported as running,\n * or throw after `_maxRetries` attempts.\n */\n private async _waitForApp(sessionId: string, expectedAppName: string): Promise<void> {\n for (let i = 0; i < this._maxRetries; i++) {\n await this._wait();\n const current = await this._getCurrentApp(sessionId);\n if (current === expectedAppName) {\n return;\n }\n }\n throw new Error(\n `Ledger: failed to open \"${expectedAppName}\" after ${this._maxRetries} retries`\n );\n }\n\n private _isDashboard(appName: string): boolean {\n return appName === DASHBOARD_APP_NAME;\n }\n\n private _wait(): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, this._waitMs));\n }\n}\n","import Transport from '@ledgerhq/hw-transport';\n\nimport type { DeviceManagementKit } from '@ledgerhq/device-management-kit';\n\n/**\n * Transport adapter that bridges Ledger's legacy hw-app-* SDKs to DMK's sendApdu.\n *\n * Legacy SDKs (hw-app-trx, hw-app-xrp, etc.) require a Transport instance.\n * This adapter wraps DMK's session-based sendApdu so legacy SDKs can run\n * over DMK's transport layer without a separate USB/HID connection.\n *\n * Usage:\n * const transport = new DmkTransport(dmk, sessionId);\n * const trx = new Trx(transport);\n * const address = await trx.getAddress(\"44'/195'/0'/0/0\");\n */\nexport class DmkTransport extends Transport {\n private _dmk: DeviceManagementKit;\n\n private _sessionId: string;\n\n constructor(dmk: DeviceManagementKit, sessionId: string) {\n super();\n this._dmk = dmk;\n this._sessionId = sessionId;\n }\n\n async exchange(apdu: Buffer): Promise<Buffer> {\n const response = await this._dmk.sendApdu({\n sessionId: this._sessionId,\n apdu: new Uint8Array(apdu),\n });\n\n // Legacy format: data + statusCode (2 bytes) concatenated\n const { data, statusCode } = response;\n const result = Buffer.alloc(data.length + 2);\n if (data.length > 0) {\n result.set(data, 0);\n }\n result.set(statusCode, data.length);\n return result;\n }\n\n async close(): Promise<void> {\n // DMK manages session lifecycle\n }\n}\n","import { LedgerDeviceManager } from '../device/LedgerDeviceManager';\nimport { SignerManager } from '../signer/SignerManager';\nimport { mapLedgerError } from '../errors';\nimport { debugLog } from '../utils/debugLog';\nimport {\n btcGetAddress,\n btcGetMasterFingerprint,\n btcGetPublicKey,\n btcSignMessage,\n btcSignPsbt,\n btcSignTransaction,\n evmGetAddress,\n evmSignMessage,\n evmSignTransaction,\n evmSignTypedData,\n solGetAddress,\n solSignMessage,\n solSignTransaction,\n tronGetAddress,\n tronSignMessage,\n tronSignTransaction,\n} from './chains';\n\nimport type { ConnectorContext } from './chains/types';\nimport type { DeviceManagementKit } from '@ledgerhq/device-management-kit';\nimport type {\n ConnectionType,\n ConnectorDevice,\n ConnectorEventMap,\n ConnectorEventType,\n ConnectorSession,\n DeviceDescriptor,\n IConnector,\n TronSignMsgParams,\n UiResponseEvent,\n} from '@onekeyfe/hwk-adapter-core';\nimport type {\n BtcGetAddressCallParams,\n BtcGetPublicKeyCallParams,\n BtcSignMessageCallParams,\n BtcSignPsbtCallParams,\n BtcSignTransactionCallParams,\n EvmGetAddressCallParams,\n EvmSignMessageCallParams,\n EvmSignTransactionCallParams,\n EvmSignTypedDataCallParams,\n SolGetAddressCallParams,\n SolSignMessageCallParams,\n SolSignTransactionCallParams,\n TronGetAddressCallParams,\n TronSignMessageCallParams,\n TronSignTransactionCallParams,\n} from './chains';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * A function that lazily loads and returns the transport factory\n * for the Ledger DMK builder (e.g. webHidTransportFactory, rnBleTransportFactory).\n */\nexport type TransportFactory = () => Promise<unknown>;\n\nexport interface LedgerConnectorBaseOptions {\n /**\n * Pre-built DMK instance. If not provided, a DMK will be created\n * lazily on first use via the transport factory.\n */\n dmk?: DeviceManagementKit;\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ntype EventHandler<K extends ConnectorEventType> = (data: ConnectorEventMap[K]) => void;\n\n// ---------------------------------------------------------------------------\n// Default signer kit importer (webpack/rspack — uses \"exports\" field)\n// ---------------------------------------------------------------------------\n\n/**\n * Default importer for Ledger signer kit packages.\n * Uses bare module specifiers — works with bundlers that support \"exports\".\n * Metro (React Native) can't resolve these; pass a custom importer that\n * uses CJS paths (e.g. `@ledgerhq/device-signer-kit-ethereum/lib/cjs/index.js`).\n */\nasync function defaultLedgerKitImporter(pkg: string): Promise<any> {\n switch (pkg) {\n case '@ledgerhq/device-management-kit':\n return import('@ledgerhq/device-management-kit');\n case '@ledgerhq/device-signer-kit-ethereum':\n return import('@ledgerhq/device-signer-kit-ethereum');\n case '@ledgerhq/device-signer-kit-bitcoin':\n return import('@ledgerhq/device-signer-kit-bitcoin');\n case '@ledgerhq/device-signer-kit-solana':\n return import('@ledgerhq/device-signer-kit-solana');\n case '@ledgerhq/context-module':\n return import('@ledgerhq/context-module');\n default:\n throw new Error(`Unknown Ledger kit package: ${pkg}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// LedgerConnectorBase\n// ---------------------------------------------------------------------------\n\n/**\n * Shared base class for Ledger IConnector implementations.\n *\n * Encapsulates all shared logic: device discovery, connection management,\n * method dispatch (EVM / BTC / SOL / TRON), signer lifecycle, event emission,\n * and error handling.\n *\n * Chain-specific method implementations live in `./chains/` and receive\n * a ConnectorContext that exposes shared helpers.\n *\n * Subclasses only need to:\n * 1. Supply a transport factory via the constructor.\n * 2. Optionally override `_resolveConnectId()` for transport-specific\n * device identity resolution (e.g. BLE hex ID extraction).\n */\nexport class LedgerConnectorBase implements IConnector {\n private _deviceManager: LedgerDeviceManager | null = null;\n\n private _signerManager: SignerManager | null = null;\n\n private _dmk: DeviceManagementKit | null = null;\n\n private readonly _eventHandlers = new Map<\n ConnectorEventType,\n Set<EventHandler<ConnectorEventType>>\n >();\n\n private readonly _providedDmk: DeviceManagementKit | undefined;\n\n private readonly _createTransport: TransportFactory;\n\n public readonly connectionType: ConnectionType;\n\n // ---------------------------------------------------------------------------\n // ConnectId <-> DMK path mapping\n //\n // DMK uses internal paths (BLE MAC, USB UUID) that may change across sessions.\n // _resolveConnectId() maps these to stable external IDs (BLE: \"A58F\", USB: same).\n // This bidirectional map is the SINGLE SOURCE OF TRUTH for all connectId usage.\n // ---------------------------------------------------------------------------\n private _connectIdToPath = new Map<string, string>(); // \"A58F\" -> \"D5:75:7D:4B:51:E8\"\n\n private _pathToConnectId = new Map<string, string>(); // \"D5:75:7D:4B:51:E8\" -> \"A58F\"\n\n /** Register a connectId <-> path mapping from a device descriptor. */\n private _registerDeviceId(descriptor: DeviceDescriptor): string {\n const connectId = this._resolveConnectId(descriptor);\n this._connectIdToPath.set(connectId, descriptor.path);\n this._pathToConnectId.set(descriptor.path, connectId);\n return connectId;\n }\n\n /** Get DMK path from external connectId. Falls back to connectId itself. */\n private _getPathForConnectId(connectId: string): string {\n return this._connectIdToPath.get(connectId) ?? connectId;\n }\n\n /** Get external connectId from DMK path. Falls back to path itself. */\n private _getConnectIdForPath(path: string): string {\n return this._pathToConnectId.get(path) ?? path;\n }\n\n // ---------------------------------------------------------------------------\n // Per-session DeviceAction cancellers\n //\n // Each chain handler registers its active DeviceAction's canceller via\n // ctx.registerCanceller(sessionId, cancel) and clears it on completion.\n // IConnector.cancel(sessionId) invokes the registered canceller, which\n // unsubscribes the observable and releases DMK's IntentQueue slot.\n // ---------------------------------------------------------------------------\n private readonly _cancellers = new Map<string, () => void>();\n\n /**\n * Resolves a Ledger signer kit module by package name.\n * Override via constructor to use CJS paths for Metro (React Native).\n * Default: dynamic import with bare specifier (webpack/rspack).\n */\n protected _importLedgerKit: (pkg: string) => Promise<any>;\n\n /** Context object passed to per-chain handler functions. */\n private readonly _ctx: ConnectorContext;\n\n constructor(\n createTransport: TransportFactory,\n options?: {\n connectionType?: ConnectionType;\n dmk?: DeviceManagementKit;\n /**\n * Override how `@ledgerhq/device-signer-kit-*` packages are imported.\n * Default: `(pkg) => import(pkg)` — works with webpack/rspack.\n * For Metro (React Native): pass a resolver that uses CJS paths.\n */\n importLedgerKit?: (pkg: string) => Promise<any>;\n }\n ) {\n this._createTransport = createTransport;\n this.connectionType = options?.connectionType ?? 'usb';\n this._providedDmk = options?.dmk;\n this._importLedgerKit = options?.importLedgerKit ?? defaultLedgerKitImporter;\n if (this._providedDmk) {\n this._initManagers(this._providedDmk);\n }\n\n // Build the context that chain handlers use\n this._ctx = {\n emit: <K extends ConnectorEventType>(event: K, data: ConnectorEventMap[K]) =>\n this._emit(event, data),\n invalidateSession: sid => this._invalidateSession(sid),\n wrapError: err => this._wrapError(err),\n getOrCreateDmk: () => this._getOrCreateDmk(),\n getDeviceManager: () => this._getDeviceManager(),\n getSignerManager: () => this._getSignerManager(),\n clearAllSigners: () => this._signerManager?.clearAll(),\n replaceSession: (oldSid, newSid) => this._replaceSession(oldSid, newSid),\n registerCanceller: (sid, cancel) => this._cancellers.set(sid, cancel),\n clearCanceller: sid => this._cancellers.delete(sid),\n importLedgerKit: this._importLedgerKit,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Protected — hooks for subclasses\n // ---------------------------------------------------------------------------\n\n /**\n * Resolve the connectId for a discovered device descriptor.\n * Default: use the DMK path (ephemeral UUID).\n * Override in subclasses to extract stable identifiers (e.g. BLE hex ID).\n */\n protected _resolveConnectId(descriptor: DeviceDescriptor): string {\n return descriptor.path;\n }\n\n // ---------------------------------------------------------------------------\n // IConnector -- Device discovery\n // ---------------------------------------------------------------------------\n\n async searchDevices(): Promise<ConnectorDevice[]> {\n const dm = await this._getDeviceManager();\n\n let descriptors = await dm.enumerate();\n\n // If no devices found, trigger permission dialog / BLE scanning via startDiscovering\n if (descriptors.length === 0) {\n try {\n await dm.requestDevice();\n } catch {\n // User may cancel the permission dialog -- that's OK\n }\n descriptors = await dm.enumerate();\n }\n\n const result: ConnectorDevice[] = descriptors.map(d => {\n const connectId = this._registerDeviceId(d);\n return {\n connectId,\n deviceId: d.path,\n name: d.name || d.type || 'Ledger',\n model: d.type,\n };\n });\n return result;\n }\n\n // ---------------------------------------------------------------------------\n // IConnector -- Connection\n // ---------------------------------------------------------------------------\n\n async connect(deviceId?: string): Promise<ConnectorSession> {\n const dm = await this._getDeviceManager();\n await this.searchDevices();\n\n // Resolve external connectId -> DMK path via mapping table\n const dmkPath = deviceId ? this._getPathForConnectId(deviceId) : undefined;\n\n // If no path found, pick first available device\n let targetPath = dmkPath;\n if (!targetPath) {\n const descriptors = await dm.enumerate();\n if (descriptors.length === 0) {\n throw new Error(\n `No Ledger device found. Make sure the device is connected${\n this.connectionType === 'ble' ? ' nearby with Bluetooth enabled' : ' via USB'\n } and unlocked.`\n );\n }\n targetPath = descriptors[0].path;\n }\n\n // External connectId for session/events — always use the mapped ID\n const externalConnectId = this._getConnectIdForPath(targetPath);\n\n const doConnect = async (path: string): Promise<ConnectorSession> => {\n const sessionId = await dm.connect(path);\n const session: ConnectorSession = {\n sessionId,\n deviceInfo: {\n vendor: 'ledger',\n model: 'unknown',\n firmwareVersion: 'unknown',\n deviceId: path,\n connectId: externalConnectId,\n connectionType: this.connectionType,\n capabilities: { persistentDeviceIdentity: false },\n },\n };\n this._emit('device-connect', {\n device: {\n connectId: externalConnectId,\n deviceId: path,\n name: 'Ledger',\n },\n });\n return session;\n };\n\n try {\n return await doConnect(targetPath);\n } catch {\n // Retry once: clear signer state but keep DMK (and BLE scan) alive\n this._resetSignersAndSessions();\n const dm2 = await this._getDeviceManager();\n await this.searchDevices();\n\n // Re-resolve path — device may have been re-discovered with new DMK path\n const retryPath = this._getPathForConnectId(externalConnectId);\n if (!retryPath || retryPath === externalConnectId) {\n // Mapping not found — try first available\n const descriptors = await dm2.enumerate();\n if (descriptors.length === 0) {\n throw new Error(\n `No Ledger device found after retry. Make sure the device is connected${\n this.connectionType === 'ble' ? ' nearby with Bluetooth enabled' : ' via USB'\n } and unlocked.`\n );\n }\n return doConnect(descriptors[0].path);\n }\n return doConnect(retryPath);\n }\n }\n\n async disconnect(sessionId: string): Promise<void> {\n if (!this._deviceManager) return;\n\n const deviceId = this._deviceManager.getDeviceId(sessionId);\n this._signerManager?.invalidate(sessionId);\n await this._deviceManager.disconnect(sessionId);\n\n if (deviceId) {\n this._emit('device-disconnect', { connectId: deviceId });\n }\n }\n\n // ---------------------------------------------------------------------------\n // IConnector -- Method dispatch\n // ---------------------------------------------------------------------------\n\n async call(sessionId: string, method: string, params: unknown): Promise<unknown> {\n debugLog('[DMK] call:', method, JSON.stringify(params));\n switch (method) {\n // EVM\n case 'evmGetAddress':\n return evmGetAddress(this._ctx, sessionId, params as EvmGetAddressCallParams);\n case 'evmSignTransaction':\n return evmSignTransaction(this._ctx, sessionId, params as EvmSignTransactionCallParams);\n case 'evmSignMessage':\n return evmSignMessage(this._ctx, sessionId, params as EvmSignMessageCallParams);\n case 'evmSignTypedData':\n return evmSignTypedData(this._ctx, sessionId, params as EvmSignTypedDataCallParams);\n // BTC\n case 'btcGetAddress':\n return btcGetAddress(this._ctx, sessionId, params as BtcGetAddressCallParams);\n case 'btcGetPublicKey':\n return btcGetPublicKey(this._ctx, sessionId, params as BtcGetPublicKeyCallParams);\n case 'btcSignTransaction':\n return btcSignTransaction(this._ctx, sessionId, params as BtcSignTransactionCallParams);\n case 'btcSignPsbt':\n return btcSignPsbt(this._ctx, sessionId, params as BtcSignPsbtCallParams);\n case 'btcSignMessage':\n return btcSignMessage(this._ctx, sessionId, params as BtcSignMessageCallParams);\n case 'btcGetMasterFingerprint':\n return btcGetMasterFingerprint(\n this._ctx,\n sessionId,\n params as { skipOpenApp?: boolean } | undefined\n );\n // SOL\n case 'solGetAddress':\n return solGetAddress(this._ctx, sessionId, params as SolGetAddressCallParams);\n case 'solSignTransaction':\n return solSignTransaction(this._ctx, sessionId, params as SolSignTransactionCallParams);\n case 'solSignMessage':\n return solSignMessage(this._ctx, sessionId, params as SolSignMessageCallParams);\n // TRON\n case 'tronGetAddress':\n return tronGetAddress(this._ctx, sessionId, params as TronGetAddressCallParams);\n case 'tronSignTransaction':\n return tronSignTransaction(this._ctx, sessionId, params as TronSignTransactionCallParams);\n case 'tronSignMessage': {\n // Explicit public→internal mapping so a field-name drift fails at\n // compile time, not silently at runtime (see bug: public `messageHex`\n // vs internal `messageHex` field name enforcement).\n const p = params as TronSignMsgParams;\n const internalParams: TronSignMessageCallParams = {\n path: p.path,\n messageHex: p.messageHex,\n };\n return tronSignMessage(this._ctx, sessionId, internalParams);\n }\n default:\n throw new Error(`LedgerConnector: unknown method \"${method}\"`);\n }\n }\n\n async cancel(sessionId: string): Promise<void> {\n // Invoke the active DeviceAction canceller (registered by the chain handler).\n // This unsubscribes the observable and releases DMK's IntentQueue slot so\n // the next call on this session isn't blocked behind an orphaned intent.\n //\n // Note: Ledger devices have no hardware-level APDU abort. If the user has\n // an on-device confirmation prompt pending, it will remain until the user\n // presses Reject or the device times out.\n const cancel = this._cancellers.get(sessionId);\n if (cancel) {\n this._cancellers.delete(sessionId);\n try {\n cancel();\n } catch {\n // canceller may have already been invoked; ignore\n }\n }\n }\n\n uiResponse(_response: UiResponseEvent): void {\n // Ledger does not use interactive UI responses (PIN/passphrase)\n }\n\n // ---------------------------------------------------------------------------\n // IConnector -- Events\n // ---------------------------------------------------------------------------\n\n on<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler as EventHandler<ConnectorEventType>);\n }\n\n off<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void {\n this._eventHandlers.get(event)?.delete(handler as EventHandler<ConnectorEventType>);\n }\n\n // ---------------------------------------------------------------------------\n // IConnector -- Reset\n // ---------------------------------------------------------------------------\n\n reset(): void {\n this._resetAll();\n }\n\n // ---------------------------------------------------------------------------\n // Private -- DMK / Manager lifecycle\n // ---------------------------------------------------------------------------\n\n /**\n * Lazily create or return the DMK instance.\n * If a DMK was provided via constructor, it is used directly.\n * Otherwise, one is created via the transport factory.\n */\n protected async _getOrCreateDmk(): Promise<DeviceManagementKit> {\n debugLog(\n '[DMK] _getOrCreateDmk called, _dmk exists:',\n !!this._dmk,\n '_providedDmk exists:',\n !!this._providedDmk\n );\n if (this._dmk) return this._dmk;\n\n if (this._providedDmk) {\n this._dmk = this._providedDmk;\n return this._dmk;\n }\n\n const { DeviceManagementKitBuilder } = await this._importLedgerKit(\n '@ledgerhq/device-management-kit'\n );\n const transportFactory = await this._createTransport();\n\n debugLog('[DMK] _getOrCreateDmk: transportFactory type:', typeof transportFactory);\n\n const dmk: DeviceManagementKit = new DeviceManagementKitBuilder()\n .addTransport(transportFactory)\n .build();\n this._dmk = dmk;\n\n debugLog('[DMK] _getOrCreateDmk: DMK created');\n\n return dmk;\n }\n\n private _initManagers(dmk: DeviceManagementKit): void {\n this._dmk = dmk;\n this._deviceManager = new LedgerDeviceManager(dmk);\n\n // Pass a custom ETH signer builder that uses _importLedgerKit,\n // so the BLE connector's CJS override applies to ETH too.\n const importKit = this._importLedgerKit;\n this._signerManager = new SignerManager(dmk, async args => {\n const mod = await importKit('@ledgerhq/device-signer-kit-ethereum');\n return new mod.SignerEthBuilder(args);\n });\n }\n\n private async _getDeviceManager(): Promise<LedgerDeviceManager> {\n if (this._deviceManager) return this._deviceManager;\n\n const dmk = await this._getOrCreateDmk();\n this._initManagers(dmk);\n return this._deviceManager!;\n }\n\n private async _getSignerManager(): Promise<SignerManager> {\n if (!this._signerManager) {\n const dmk = await this._getOrCreateDmk();\n this._initManagers(dmk);\n }\n return this._signerManager!;\n }\n\n private _invalidateSession(sessionId: string): void {\n this._signerManager?.invalidate(sessionId);\n }\n\n /**\n * Replace an old session with a new one after app switch.\n * Updates the connectId→path mapping so subsequent calls() use the new session,\n * and emits device-connect so the adapter updates its _sessions Map.\n */\n private _replaceSession(oldSessionId: string, _newSessionId: string): void {\n // Find the connectId that was mapped to the old session's device path\n const dm = this._deviceManager;\n if (!dm) return;\n\n const oldDeviceId = dm.getDeviceId(oldSessionId);\n const connectId = oldDeviceId ? this._pathToConnectId.get(oldDeviceId) : undefined;\n\n // Invalidate old signer cache\n this._signerManager?.invalidate(oldSessionId);\n\n // Emit device-connect so the adapter picks up the new session\n if (connectId) {\n this._emit('device-connect', {\n device: {\n connectId,\n deviceId: connectId,\n name: 'Ledger',\n },\n });\n }\n }\n\n /**\n * Light reset: clear signer/session state but keep DMK, BLE scan, and ID mapping alive.\n * Used by connect() retry — we want to re-discover with the same transport.\n */\n private _resetSignersAndSessions(): void {\n debugLog('[DMK] _resetSignersAndSessions called');\n this._signerManager?.clearAll();\n this._signerManager = null;\n this._deviceManager = null;\n }\n\n private _resetAll(): void {\n debugLog('[DMK] _resetAll called');\n // Cancel any in-flight DeviceActions so their observables unsubscribe\n // and DMK's intent queues don't keep orphaned slots alive.\n for (const cancel of this._cancellers.values()) {\n try {\n cancel();\n } catch {\n // already cancelled / settled — ignore\n }\n }\n this._cancellers.clear();\n this._signerManager?.clearAll();\n this._deviceManager?.dispose();\n this._deviceManager = null;\n this._signerManager = null;\n this._dmk = null;\n this._connectIdToPath.clear();\n this._pathToConnectId.clear();\n }\n\n // ---------------------------------------------------------------------------\n // Private -- Events\n // ---------------------------------------------------------------------------\n\n protected _emit<K extends ConnectorEventType>(event: K, data: ConnectorEventMap[K]): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n for (const handler of handlers) {\n try {\n handler(data);\n } catch {\n // Don't let listener errors break the connector\n }\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private -- Error handling\n // ---------------------------------------------------------------------------\n\n private _wrapError(err: unknown): Error {\n const mapped = mapLedgerError(err);\n const error = new Error(mapped.message);\n const src = (err && typeof err === 'object' ? err : {}) as Record<string, unknown>;\n // Preserve DMK / EthAppCommandError fields so downstream classifiers\n // (including cross-layer `wrapError` → caller re-classification) can still\n // key on APDU code and step context attached by deviceActionToPromise.\n Object.assign(error, {\n code: mapped.code,\n appName: mapped.appName,\n _tag: src._tag,\n errorCode: src.errorCode,\n _lastStep: src._lastStep,\n });\n // Non-enumerable: DMK errors can carry APDU payloads / signing\n // intermediates that shouldn't leak into JSON.stringify / log transports.\n Object.defineProperty(error, 'originalError', {\n value: err,\n configurable: true,\n enumerable: false,\n writable: true,\n });\n return error;\n }\n}\n","/**\n * Extract the stable 4-digit HEX identifier from a Ledger BLE device name.\n * e.g., \"Nano X 123A\" -> \"123A\", \"Ledger Nano X AB12\" -> \"AB12\"\n * Returns undefined if no valid HEX suffix found.\n */\nexport function extractBleHexId(name?: string): string | undefined {\n if (!name) return undefined;\n const match = name.match(/\\b([0-9A-Fa-f]{4})$/);\n return match ? match[1].toUpperCase() : undefined;\n}\n"],"mappings":"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","names":["import_hwk_adapter_core","import_hwk_adapter_core","import_hwk_adapter_core","import_hwk_adapter_core","import_hwk_adapter_core","import_hwk_adapter_core","INTERACTIVE_TIMEOUT_MS","import_hwk_adapter_core","ContextModuleBuilder","import_hwk_adapter_core","import_hwk_adapter_core","import_device_management_kit","Transport","Trx"]}