@bytezhang/ledger-adapter 0.0.20 → 0.0.21
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 +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/adapter/LedgerAdapter.ts","../src/errors.ts","../src/device/LedgerDeviceManager.ts","../src/signer/deviceActionToPromise.ts","../src/signer/SignerEth.ts","../src/signer/SignerManager.ts","../src/signer/SignerBtc.ts","../src/signer/SignerSol.ts","../src/signer/SignerTron.ts","../src/connector/LedgerConnectorBase.ts","../src/transport/registry.ts","../src/app/AppManager.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 { SignerTron } from './signer/SignerTron';\nexport { deviceActionToPromise } from './signer/deviceActionToPromise';\n\n// Transport registry\nexport { registerTransport, unregisterTransport, getTransportProvider, listRegisteredTransports, clearRegistry } from './transport/registry';\n\n// App management\nexport { AppManager } from './app/AppManager';\n\n// Types\nexport type { IDmk, DmkDiscoveredDevice, DeviceActionState, SignerEvmAddress, SignerEvmSignature, SignerBtcAddress, TransportProvider, TransportProviderInstance, TransportProviderOptions } from './types';\n\n// Errors\nexport { isDeviceLockedError, mapLedgerError } from './errors';\n","import type {\n IHardwareWallet,\n IUiHandler,\n IConnector,\n ConnectorDevice,\n DeviceInfo,\n HardwareEventMap,\n DeviceEventListener,\n TransportType,\n ConnectionType,\n Response,\n EvmGetAddressParams,\n EvmAddress,\n EvmGetPublicKeyParams,\n EvmPublicKey,\n EvmSignTxParams,\n EvmSignedTx,\n EvmSignMsgParams,\n EvmSignTypedDataParams,\n EvmSignature,\n ProgressCallback,\n BtcGetAddressParams,\n BtcAddress,\n BtcGetPublicKeyParams,\n BtcPublicKey,\n BtcSignTxParams,\n BtcSignedTx,\n BtcSignMsgParams,\n BtcSignature,\n SolGetAddressParams,\n SolAddress,\n SolGetPublicKeyParams,\n SolPublicKey,\n SolSignTxParams,\n SolSignedTx,\n SolSignMsgParams,\n SolSignature,\n TronGetAddressParams,\n TronAddress,\n TronSignTxParams,\n TronSignedTx,\n TronSignMsgParams,\n TronSignature,\n ChainCapability,\n ChainForFingerprint,\n} from '@bytezhang/hardware-wallet-core';\nimport {\n success,\n failure,\n HardwareErrorCode,\n TypedEventEmitter,\n DEVICE,\n UI_REQUEST,\n CHAIN_FINGERPRINT_PATHS,\n deriveDeviceFingerprint,\n} from '@bytezhang/hardware-wallet-core';\nimport { mapLedgerError, isDeviceDisconnectedError } from '../errors';\n\n/** Ensure a hex string has the `0x` prefix. */\nfunction ensure0x(hex: string): string {\n return hex.startsWith('0x') ? hex : `0x${hex}`;\n}\n\n/** Remove `0x` prefix from a hex string if present. */\nfunction stripHex(hex: string): string {\n return hex.startsWith('0x') ? hex.slice(2) : hex;\n}\n\n/** Ensure a hex string is `0x`-prefixed and zero-padded to 64 hex chars (32 bytes). */\nfunction padHex64(hex: string): string {\n return `0x${stripHex(hex).padStart(64, '0')}`;\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 * - Integrates with IUiHandler for permission flows\n */\nexport class LedgerAdapter implements IHardwareWallet {\n readonly vendor = 'ledger' as const;\n\n private readonly connector: IConnector;\n private readonly emitter = new TypedEventEmitter<HardwareEventMap>();\n\n private _uiHandler: Partial<IUiHandler> | null = null;\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 constructor(connector: IConnector) {\n this.connector = connector;\n this.registerEventListeners();\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 return 'hid';\n }\n\n getAvailableTransports(): TransportType[] {\n return ['hid'];\n }\n\n async switchTransport(_type: TransportType): Promise<void> {\n // Transport is fixed at connector creation time.\n // To switch transport, create a new LedgerAdapter with a different connector.\n }\n\n // ---------------------------------------------------------------------------\n // UI handler\n // ---------------------------------------------------------------------------\n\n setUiHandler(handler: Partial<IUiHandler>): void {\n this._uiHandler = handler;\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 async dispose(): Promise<void> {\n // Cancel any pending device-connect prompt\n this._deviceConnectResolve?.(true);\n this._deviceConnectResolve = null;\n\n this.unregisterEventListeners();\n this.connector.reset();\n this._uiHandler = null;\n this._discoveredDevices.clear();\n this._sessions.clear();\n this.emitter.removeAllListeners();\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 console.log('[DMK] adapter.searchDevices raw:', JSON.stringify(devices));\n\n for (const d of devices) {\n if (d.connectId && !this._discoveredDevices.has(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(\n connectId: string,\n deviceId: string,\n ): 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(\n (d) => d.deviceId === deviceId,\n );\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 // Events\n // ---------------------------------------------------------------------------\n\n on<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;\n on(event: string, listener: DeviceEventListener): void;\n on(event: string, listener: (event: any) => void): void {\n this.emitter.on(event, listener);\n }\n\n off<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;\n off(event: string, listener: DeviceEventListener): void;\n off(event: string, listener: (event: any) => void): void {\n this.emitter.off(event, listener);\n }\n\n cancel(connectId: string): void {\n const sessionId = this._sessions.get(connectId) ?? connectId;\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 await this._ensureDevicePermission(connectId, deviceId);\n try {\n const address = await this._deriveAddressForFingerprint(connectId, chain);\n return success(deriveDeviceFingerprint(address));\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n /**\n * Verify that the connected device matches the expected fingerprint.\n *\n * - If deviceId is empty, verification is skipped (returns true).\n * - deviceId is used here as the stored fingerprint to compare against.\n */\n private async _verifyDeviceFingerprint(\n connectId: string,\n deviceId: string,\n chain: ChainForFingerprint,\n ): Promise<boolean> {\n if (!deviceId) return true;\n\n try {\n const address = await this._deriveAddressForFingerprint(connectId, chain);\n const fingerprint = deriveDeviceFingerprint(address);\n return fingerprint === deviceId;\n } catch (err) {\n // \"App not open\" or \"wrong app\" errors are expected — skip verification\n const mapped = mapLedgerError(err);\n if (\n mapped.code === HardwareErrorCode.WrongApp ||\n mapped.code === HardwareErrorCode.DeviceLocked\n ) {\n return true;\n }\n // Transport/disconnect errors should propagate\n throw err;\n }\n }\n\n /**\n * Derive an address at the fixed testnet path for fingerprint generation.\n */\n private async _deriveAddressForFingerprint(\n connectId: string,\n chain: ChainForFingerprint,\n ): Promise<string> {\n const path = CHAIN_FINGERPRINT_PATHS[chain];\n\n if (chain === 'evm') {\n const result = await this.connectorCall(connectId, 'evmGetAddress', {\n path,\n showOnDevice: false,\n }) as { address: string };\n return result.address;\n }\n\n if (chain === 'btc') {\n const result = await this.connectorCall(connectId, 'btcGetAddress', {\n path,\n showOnDevice: false,\n coin: 'Testnet',\n }) as { address: string };\n return result.address;\n }\n\n if (chain === 'sol') {\n const result = await this.connectorCall(connectId, 'solGetAddress', {\n path,\n showOnDevice: false,\n }) as { address: string };\n return result.address;\n }\n\n throw new Error(`Unsupported chain for fingerprint: ${chain as string}`);\n }\n\n // ---------------------------------------------------------------------------\n // EVM methods\n // ---------------------------------------------------------------------------\n\n async evmGetAddress(\n connectId: string,\n _deviceId: string,\n params: EvmGetAddressParams,\n ): Promise<Response<EvmAddress>> {\n console.log('[DMK] adapter.evmGetAddress called:', { connectId, _deviceId, path: params.path, showOnDevice: params.showOnDevice, chainId: params.chainId });\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'evm'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'evmGetAddress', {\n path: params.path,\n showOnDevice: params.showOnDevice,\n chainId: params.chainId,\n }) as { address: string; publicKey?: string; path?: string };\n\n return success({\n address: result.address,\n path: params.path,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async evmGetAddresses(\n connectId: string,\n deviceId: string,\n params: EvmGetAddressParams[],\n onProgress?: ProgressCallback,\n ): Promise<Response<EvmAddress[]>> {\n return this.batchCall(\n params,\n (p) => this.evmGetAddress(connectId, deviceId, p),\n onProgress,\n );\n }\n\n async evmGetPublicKey(\n connectId: string,\n _deviceId: string,\n params: EvmGetPublicKeyParams,\n ): Promise<Response<EvmPublicKey>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'evm'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'evmGetAddress', {\n path: params.path,\n showOnDevice: params.showOnDevice,\n }) as { address: string; publicKey: string; path?: string };\n\n return success({\n publicKey: result.publicKey,\n path: params.path,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async evmSignTransaction(\n connectId: string,\n _deviceId: string,\n params: EvmSignTxParams,\n ): Promise<Response<EvmSignedTx>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'evm'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n if (!params.serializedTx) {\n return failure(\n HardwareErrorCode.InvalidParams,\n 'Ledger requires a pre-serialized transaction (serializedTx). Provide an RLP-encoded hex string.',\n );\n }\n\n const result = await this.connectorCall(connectId, 'evmSignTransaction', {\n path: params.path,\n serializedTx: params.serializedTx,\n }) as { v: string; r: string; s: string; serializedTx?: string };\n\n return success({\n v: ensure0x(result.v),\n r: padHex64(result.r),\n s: padHex64(result.s),\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async evmSignMessage(\n connectId: string,\n _deviceId: string,\n params: EvmSignMsgParams,\n ): Promise<Response<EvmSignature>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'evm'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'evmSignMessage', {\n path: params.path,\n message: params.message,\n }) as { signature: string; address?: string };\n\n return success({\n signature: ensure0x(result.signature),\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async evmSignTypedData(\n connectId: string,\n _deviceId: string,\n params: EvmSignTypedDataParams,\n ): Promise<Response<EvmSignature>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'evm'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n // Ledger requires full EIP-712 structure — hash mode is not supported.\n if (params.mode === 'hash') {\n return failure(\n HardwareErrorCode.MethodNotSupported,\n 'Ledger does not support hash-only EIP-712 signing. Use mode \"full\" with the complete typed data structure.',\n );\n }\n\n try {\n const result = await this.connectorCall(connectId, 'evmSignTypedData', {\n path: params.path,\n data: params.data,\n }) as { signature: string; address?: string };\n\n return success({\n signature: ensure0x(result.signature),\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // BTC methods\n // ---------------------------------------------------------------------------\n\n async btcGetAddress(\n connectId: string,\n _deviceId: string,\n params: BtcGetAddressParams,\n ): Promise<Response<BtcAddress>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'btc'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'btcGetAddress', {\n path: params.path,\n coin: params.coin,\n showOnDevice: params.showOnDevice,\n scriptType: params.scriptType,\n }) as { address: string; path: string };\n\n return success({\n address: result.address,\n path: params.path,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async btcGetAddresses(\n connectId: string,\n deviceId: string,\n params: BtcGetAddressParams[],\n onProgress?: ProgressCallback,\n ): Promise<Response<BtcAddress[]>> {\n return this.batchCall(\n params,\n (p) => this.btcGetAddress(connectId, deviceId, p),\n onProgress,\n );\n }\n\n async btcGetPublicKey(\n connectId: string,\n _deviceId: string,\n params: BtcGetPublicKeyParams,\n ): Promise<Response<BtcPublicKey>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'btc'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'btcGetPublicKey', {\n path: params.path,\n coin: params.coin,\n showOnDevice: params.showOnDevice,\n }) as {\n xpub: string;\n publicKey: string;\n fingerprint: number;\n chainCode: string;\n path: string;\n depth: number;\n };\n\n return success({\n xpub: result.xpub,\n publicKey: result.publicKey ?? '',\n fingerprint: result.fingerprint ?? 0,\n chainCode: result.chainCode ?? '',\n path: params.path,\n depth: result.depth ?? 0,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async btcSignTransaction(\n connectId: string,\n _deviceId: string,\n params: BtcSignTxParams,\n ): Promise<Response<BtcSignedTx>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'btc'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n if (!params.psbt) {\n return failure(\n HardwareErrorCode.InvalidParams,\n 'Ledger requires PSBT format for BTC transaction signing. Provide params.psbt.',\n );\n }\n try {\n // Extract account-level path from the first input if available\n const accountPath = params.inputs?.[0]?.path\n ? params.inputs[0].path.split('/').slice(0, 3).join('/')\n : undefined;\n\n const result = await this.connectorCall(connectId, 'btcSignTransaction', {\n psbt: params.psbt,\n coin: params.coin,\n path: accountPath,\n }) as { signedPsbt: string };\n\n return success({\n signatures: [],\n serializedTx: result.signedPsbt,\n signedPsbt: result.signedPsbt,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async btcSignMessage(\n connectId: string,\n _deviceId: string,\n params: BtcSignMsgParams,\n ): Promise<Response<BtcSignature>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'btc'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'btcSignMessage', {\n path: params.path,\n message: params.message,\n coin: params.coin,\n }) as { signature: string; address: string };\n\n return success({\n signature: result.signature,\n address: result.address || '',\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Device fingerprint\n // ---------------------------------------------------------------------------\n\n async btcGetMasterFingerprint(\n connectId: string,\n _deviceId: string,\n ): Promise<Response<{ masterFingerprint: string }>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'btc'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'btcGetMasterFingerprint', {}) as {\n masterFingerprint: string;\n };\n\n return success({ masterFingerprint: result.masterFingerprint });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Solana methods\n // ---------------------------------------------------------------------------\n\n async solGetAddress(\n connectId: string,\n _deviceId: string,\n params: SolGetAddressParams,\n ): Promise<Response<SolAddress>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'sol'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'solGetAddress', {\n path: params.path,\n showOnDevice: params.showOnDevice,\n }) as { address: string; path: string };\n\n return success({\n address: result.address,\n path: params.path,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async solGetAddresses(\n connectId: string,\n deviceId: string,\n params: SolGetAddressParams[],\n onProgress?: ProgressCallback,\n ): Promise<Response<SolAddress[]>> {\n return this.batchCall(\n params,\n (p) => this.solGetAddress(connectId, deviceId, p),\n onProgress,\n );\n }\n\n async solGetPublicKey(\n connectId: string,\n _deviceId: string,\n params: SolGetPublicKeyParams,\n ): Promise<Response<SolPublicKey>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'sol'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n // Solana uses Ed25519 — the public key IS the address (base58 encoded)\n const result = await this.connectorCall(connectId, 'solGetAddress', {\n path: params.path,\n showOnDevice: params.showOnDevice,\n }) as { address: string; path: string };\n\n return success({\n publicKey: result.address,\n path: params.path,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async solSignTransaction(\n connectId: string,\n _deviceId: string,\n params: SolSignTxParams,\n ): Promise<Response<SolSignedTx>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'sol'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'solSignTransaction', {\n path: params.path,\n serializedTx: params.serializedTx,\n }) as { signature: string };\n\n return success({ signature: result.signature });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async solSignMessage(\n connectId: string,\n _deviceId: string,\n params: SolSignMsgParams,\n ): Promise<Response<SolSignature>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'sol'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'solSignMessage', {\n path: params.path,\n message: params.message,\n }) as { signature: string };\n\n return success({ signature: result.signature });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // TRON methods\n // ---------------------------------------------------------------------------\n\n async tronGetAddress(\n connectId: string,\n _deviceId: string,\n params: TronGetAddressParams,\n ): Promise<Response<TronAddress>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n try {\n const result = await this.connectorCall(connectId, 'tronGetAddress', {\n path: params.path,\n showOnDevice: params.showOnDevice,\n }) as { address: string; publicKey: string; path: string };\n\n return success({\n address: result.address,\n path: params.path,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async tronGetAddresses(\n connectId: string,\n deviceId: string,\n params: TronGetAddressParams[],\n onProgress?: ProgressCallback,\n ): Promise<Response<TronAddress[]>> {\n return this.batchCall(\n params,\n (p) => this.tronGetAddress(connectId, deviceId, p),\n onProgress,\n );\n }\n\n async tronSignTransaction(\n connectId: string,\n _deviceId: string,\n params: TronSignTxParams,\n ): Promise<Response<TronSignedTx>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n try {\n if (!params.rawTxHex) {\n return failure(\n HardwareErrorCode.InvalidParams,\n 'TRON signing requires a protobuf-encoded raw transaction hex (rawTxHex).',\n );\n }\n\n const result = await this.connectorCall(connectId, 'tronSignTransaction', {\n path: params.path,\n rawTxHex: params.rawTxHex,\n }) as { signature: string };\n\n return success({ signature: result.signature });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async tronSignMessage(\n connectId: string,\n _deviceId: string,\n params: TronSignMsgParams,\n ): Promise<Response<TronSignature>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n try {\n const result = await this.connectorCall(connectId, 'tronSignMessage', {\n path: params.path,\n messageHex: params.message,\n }) as { signature: string };\n\n return success({ signature: result.signature });\n } catch (err) {\n return this.errorToFailure(err);\n }\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 // Pending device-connect resolve — set by _waitForDeviceConnect, resolved by uiResponse\n private _deviceConnectResolve: ((cancelled: boolean) => void) | null = null;\n\n // Mutex for ensureConnected — prevents concurrent calls from establishing duplicate connections\n private _connectingPromise: Promise<string> | null = null;\n\n private static readonly DEVICE_CONNECT_TIMEOUT_MS = 60_000;\n\n /**\n * Wait for user to connect and unlock device.\n * Emits 'ui-request' event via the adapter's own emitter.\n * The consumer (monorepo adapter wrapper) listens for this and shows UI.\n * When user confirms, they call adapter.deviceConnectResponse() which resolves this promise.\n * Times out after 60 seconds if no response is received.\n */\n private _waitForDeviceConnect(attempt: number): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n this._deviceConnectResolve = null;\n reject(new Error('Ledger device connect timed out after 60 seconds'));\n }\n }, LedgerAdapter.DEVICE_CONNECT_TIMEOUT_MS);\n\n this._deviceConnectResolve = (cancelled: boolean) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n this._deviceConnectResolve = null;\n if (cancelled) {\n reject(Object.assign(\n new Error('User cancelled Ledger connection'),\n { _tag: 'DeviceNotRecognizedError' },\n ));\n } else {\n resolve();\n }\n };\n\n // Emit ui-request event — consumer should show \"connect and unlock\" prompt\n this.emitter.emit('ui-request-device-connect' as any, {\n type: 'ui-request-device-connect',\n payload: {\n message: 'Please connect and unlock your Ledger device',\n retryCount: attempt,\n maxRetries: LedgerAdapter.MAX_DEVICE_RETRY,\n },\n });\n });\n }\n\n /**\n * Called by consumer to respond to ui-request-device-connect.\n * type='confirm' → retry search, type='cancel' → abort.\n */\n deviceConnectResponse(type: 'confirm' | 'cancel'): void {\n if (this._deviceConnectResolve) {\n this._deviceConnectResolve(type === 'cancel');\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 return this._sessions.keys().next().value!;\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(attempt + 1);\n }\n }\n\n throw Object.assign(\n new Error('No Ledger device found after multiple attempts. Please connect and unlock your device.'),\n { _tag: 'DeviceNotRecognizedError' },\n );\n }\n\n private async _connectFirstOrSelect(devices: DeviceInfo[]): Promise<string> {\n if (devices.length === 1) {\n const result = await this.connectDevice(devices[0].connectId);\n if (!result.success) {\n throw Object.assign(\n new Error(result.payload.error),\n { _tag: 'DeviceNotRecognizedError' },\n );\n }\n return devices[0].connectId;\n }\n\n // Multiple devices — ask user via UI handler\n if (this._uiHandler?.onSelectDevice) {\n const selectedConnectId = await this._uiHandler.onSelectDevice(devices);\n const result = await this.connectDevice(selectedConnectId);\n if (!result.success) {\n throw Object.assign(\n new Error(result.payload.error),\n { _tag: 'DeviceNotRecognizedError' },\n );\n }\n return selectedConnectId;\n }\n\n // No UI handler — fall back to first device\n const result = await this.connectDevice(devices[0].connectId);\n if (!result.success) {\n throw Object.assign(\n new Error(result.payload.error),\n { _tag: 'DeviceNotRecognizedError' },\n );\n }\n return devices[0].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 ): Promise<unknown> {\n const resolvedConnectId = await this.ensureConnected(connectId);\n const sessionId = this._sessions.get(resolvedConnectId);\n if (!sessionId) {\n throw Object.assign(\n new Error('Auto-connect succeeded but no session found'),\n { _tag: 'DeviceSessionNotFound' },\n );\n }\n\n try {\n return await this.connector.call(sessionId, method, params);\n } catch (err) {\n if (isDeviceDisconnectedError(err)) {\n // Clear stale session and retry with fresh connection\n this._sessions.delete(resolvedConnectId);\n this._discoveredDevices.clear();\n const retryConnectId = await this.ensureConnected();\n const retrySessionId = this._sessions.get(retryConnectId);\n if (!retrySessionId) {\n throw err;\n }\n return this.connector.call(retrySessionId, method, params);\n }\n throw err;\n }\n }\n\n /**\n * Ensure device permission before proceeding.\n * - No connectId (searchDevices): check environment-level permission\n * - With connectId (business methods): check device-level permission\n * If not granted, calls onDevicePermission so the consumer can request access.\n */\n private async _ensureDevicePermission(connectId?: string, deviceId?: string): Promise<void> {\n const transportType: TransportType = 'hid';\n let granted = false;\n let context: Record<string, unknown> | undefined;\n\n if (this._uiHandler?.checkDevicePermission) {\n try {\n const result = await this._uiHandler.checkDevicePermission({ transportType, connectId, deviceId });\n granted = result.granted;\n context = result.context;\n } catch {\n granted = false;\n }\n }\n\n if (!granted) {\n try {\n await this._uiHandler?.onDevicePermission?.({ transportType, context });\n } catch {\n // UI handler cancelled or failed\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 console.error('[LedgerAdapter] error:', err);\n const mapped = mapLedgerError(err);\n\n // Emit a UI event for locked-device so callers can prompt the user\n if (mapped.code === HardwareErrorCode.DeviceLocked) {\n this.emitter.emit(UI_REQUEST.REQUEST_BUTTON, {\n type: UI_REQUEST.REQUEST_BUTTON,\n payload: {\n device: this.unknownDevice(),\n code: 'ButtonRequest_Other',\n },\n });\n }\n\n return failure(mapped.code, mapped.message);\n }\n\n /**\n * Generic batch call with progress reporting.\n * If any single call fails, returns the failure immediately.\n */\n private async batchCall<TParam, TResult>(\n params: TParam[],\n callFn: (p: TParam) => Promise<Response<TResult>>,\n onProgress?: ProgressCallback,\n ): Promise<Response<TResult[]>> {\n const results: TResult[] = [];\n for (let i = 0; i < params.length; i++) {\n const result = await callFn(params[i]);\n if (!result.success) {\n return result;\n }\n results.push(result.payload);\n onProgress?.({ index: i, total: params.length });\n }\n return success(results);\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 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\n ? this.extractDeviceInfoFromPayload(payload)\n : 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 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: 'usb' as ConnectionType,\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 } from '@bytezhang/hardware-wallet-core';\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 */\nconst WRONG_APP_CODES = new Set(['6e00', '28160', '6d00', '27904']);\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 (typeof e.message === 'string' && /locked|device exchange error/i.test(e.message)) 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' && /wrong app|open the .* app|CLA not supported/i.test(e.message)) return true;\n if (hasStatusCode(err, WRONG_APP_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' && /disconnected|not found|no device|unplugged|session.*not.*found|timed out.*locked/i.test(e.message)) return true;\n return false;\n}\n\n/** Check for timeout errors. */\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.message === 'string' && /timeout|timed?\\s*out/i.test(e.message)) return true;\n if (e._tag === 'DeviceExchangeTimeoutError') 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): { code: HardwareErrorCode; message: string } {\n // Order matters: check more specific errors first\n\n if (isDeviceLockedError(err)) {\n return {\n code: HardwareErrorCode.DeviceLocked,\n message: 'Device is locked. Please unlock your Ledger device and try again.',\n };\n }\n\n if (isUserRejectedError(err)) {\n return {\n code: HardwareErrorCode.UserRejected,\n message: 'User rejected the request on the device.',\n };\n }\n\n if (isWrongAppError(err)) {\n return {\n code: HardwareErrorCode.WrongApp,\n message: 'Wrong app is open on the Ledger device. Please open the correct app (e.g. Ethereum) and try again.',\n };\n }\n\n if (isDeviceDisconnectedError(err)) {\n return {\n code: HardwareErrorCode.DeviceDisconnected,\n message: 'Ledger device was disconnected. Please reconnect the device and try again.',\n };\n }\n\n if (isTimeoutError(err)) {\n return {\n code: HardwareErrorCode.OperationTimeout,\n message: 'Operation timed out. Please ensure the Ledger device is connected and responsive.',\n };\n }\n\n // Fallback: extract whatever message we can\n let message = 'Unknown Ledger error';\n if (err instanceof Error) {\n message = err.message;\n } else if (err && typeof err === 'object') {\n const e = err as Record<string, unknown>;\n message = String(e.message ?? e._tag ?? e.type ?? JSON.stringify(err));\n }\n return { code: HardwareErrorCode.UnknownError, message };\n}\n","import type { DeviceDescriptor, DeviceChangeEvent } from '@bytezhang/hardware-wallet-core';\nimport type { IDmk, 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: IDmk;\n private readonly _discovered = new Map<string, DmkDiscoveredDevice>();\n private readonly _sessions = new Map<string, string>(); // deviceId → sessionId\n private readonly _sessionToDevice = new Map<string, string>(); // sessionId → deviceId\n private _listenSub: { unsubscribe: () => void } | null = null;\n\n constructor(dmk: IDmk) {\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 return new Promise<DeviceDescriptor[]>((resolve) => {\n let resolved = false;\n // BehaviorSubject fires next synchronously during subscribe(),\n // so 'sub' is not yet assigned when the callback runs.\n // Capture result synchronously, unsubscribe after assignment.\n let syncResult: { id: string; deviceModel: { id: string }; [k: string]: unknown }[] | 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 // Log raw DMK discovery data — everything the SDK returns\n console.log('[DMK] enumerate raw devices:', JSON.stringify(devices.map(d => ({\n id: d.id,\n deviceModel: d.deviceModel,\n transport: (d as any).transport,\n name: (d as any).name,\n rssi: (d as any).rssi,\n // Dump all keys to see what else is available\n _keys: Object.keys(d),\n }))));\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(devices.map(d => ({\n path: d.id,\n type: d.deviceModel.id,\n name: (d as any).name,\n transport: (d as any).transport,\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 { id: string; deviceModel: { id: string }; name?: string; transport?: string }[];\n resolve(devices.map(d => ({\n path: d.id,\n type: d.deviceModel.id,\n name: (d as any).name,\n transport: (d as any).transport,\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 console.log('[DMK] listen device:', JSON.stringify({\n id: d.id,\n deviceModel: d.deviceModel,\n name: (d as any).name,\n }));\n if (!previousIds.has(d.id)) {\n onChange({ type: 'device-connected', descriptor: {\n path: d.id,\n type: d.deviceModel.id,\n name: (d as any).name,\n transport: (d as any).transport,\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 requestDevice(timeoutMs = 3000): Promise<void> {\n return new Promise<void>((resolve) => {\n const sub = this._dmk.startDiscovering().subscribe({\n next: (d) => { this._discovered.set(d.id, d); },\n error: () => { sub.unsubscribe(); resolve(); },\n });\n setTimeout(() => {\n sub.unsubscribe();\n this._dmk.stopDiscovering();\n resolve();\n }, timeoutMs);\n });\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(): IDmk {\n return this._dmk;\n }\n\n dispose(): void {\n this.stopListening();\n this._discovered.clear();\n this._sessions.clear();\n this._sessionToDevice.clear();\n this._dmk.close?.();\n }\n}\n","/** DeviceAction state emitted by DMK signer operations. */\ninterface DeviceActionState<T> {\n status: 'pending' | 'completed' | 'error';\n output?: T;\n error?: unknown;\n intermediateValue?: {\n requiredUserInteraction?: string;\n [key: string]: unknown;\n };\n}\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 * @param timeoutMs Timeout in ms. Resets each time the Observable emits (device is alive).\n * Pass 0 to disable. Default: 30s.\n */\nexport function deviceActionToPromise<T>(\n action: {\n observable: {\n subscribe(observer: {\n next: (value: DeviceActionState<T>) => void;\n error?: (err: unknown) => void;\n complete?: () => void;\n }): { unsubscribe: () => void };\n };\n },\n onInteraction?: (interaction: string) => void,\n timeoutMs: number = DEFAULT_TIMEOUT_MS,\n): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n let settled = false;\n let sub: { unsubscribe: () => void };\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n const resetTimer = () => {\n if (timer) clearTimeout(timer);\n if (timeoutMs > 0) {\n timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n sub?.unsubscribe();\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 console.log('[DMK-Observable] subscribing to action.observable...');\n sub = action.observable.subscribe({\n next: (state) => {\n console.log('[DMK-Observable] next received');\n // Device is alive — reset timeout\n resetTimer();\n\n console.log('[DMK-Observable] state:', JSON.stringify({\n status: state.status,\n interaction: state.intermediateValue?.requiredUserInteraction,\n intermediateValue: state.intermediateValue,\n hasOutput: !!state.output,\n hasError: !!state.error,\n }));\n if (settled) return;\n if (state.status === 'completed') {\n settled = true;\n if (timer) clearTimeout(timer);\n onInteraction?.('interaction-complete');\n sub?.unsubscribe();\n resolve(state.output as T);\n } else if (state.status === 'error') {\n settled = true;\n if (timer) clearTimeout(timer);\n onInteraction?.('interaction-complete');\n sub?.unsubscribe();\n reject(state.error);\n } else if (state.status === 'pending' && onInteraction) {\n const interaction = state.intermediateValue?.requiredUserInteraction;\n if (interaction && interaction !== 'none') {\n onInteraction(interaction);\n } else if (interaction === 'none') {\n onInteraction('interaction-complete');\n }\n }\n },\n error: (err: unknown) => {\n if (!settled) {\n settled = true;\n if (timer) clearTimeout(timer);\n sub?.unsubscribe();\n reject(err);\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","import type { SignerEvmAddress, SignerEvmSignature } from '../types';\nimport { deviceActionToPromise } from './deviceActionToPromise';\n\n/**\n * SDK signer interface — duck-typed to avoid hard dependency on\n * @ledgerhq/device-signer-kit-ethereum.\n */\nexport interface ISdkSignerEth {\n getAddress(derivationPath: string, options?: { checkOnDevice?: boolean }): unknown;\n signTransaction(derivationPath: string, transaction: Uint8Array, options?: unknown): unknown;\n signMessage(derivationPath: string, message: string): unknown;\n signTypedData(derivationPath: string, data: unknown): unknown;\n}\n\n/** Convert hex string (with or without 0x) to Uint8Array. */\nfunction hexToBytes(hex: string): Uint8Array {\n const h = hex.startsWith('0x') ? hex.slice(2) : hex;\n const bytes = new Uint8Array(h.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(h.substring(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\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 constructor(private readonly _sdk: ISdkSignerEth) {}\n\n async getAddress(\n derivationPath: string,\n options?: { checkOnDevice?: boolean }\n ): Promise<SignerEvmAddress> {\n const checkOnDevice = options?.checkOnDevice ?? false;\n console.log('[DMK] getAddress → DMK:', { derivationPath, checkOnDevice });\n console.log('[DMK] signer instance id:', (this as any)._instanceId ?? 'none');\n const action = this._sdk.getAddress(derivationPath, {\n checkOnDevice,\n });\n console.log('[DMK] getAddress action created:', !!action, 'hasObservable:', !!(action as any)?.observable);\n // checkOnDevice needs user interaction → long timeout; otherwise default 30s\n const timeout = checkOnDevice ? INTERACTIVE_TIMEOUT_MS : undefined;\n return deviceActionToPromise<SignerEvmAddress>(action as any, this.onInteraction, timeout);\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>(action as any, this.onInteraction, INTERACTIVE_TIMEOUT_MS);\n }\n\n async signMessage(derivationPath: string, message: string): Promise<SignerEvmSignature> {\n const action = this._sdk.signMessage(derivationPath, message);\n return deviceActionToPromise<SignerEvmSignature>(action as any, this.onInteraction, INTERACTIVE_TIMEOUT_MS);\n }\n\n async signTypedData(derivationPath: string, data: unknown): Promise<SignerEvmSignature> {\n const action = this._sdk.signTypedData(derivationPath, data);\n return deviceActionToPromise<SignerEvmSignature>(action as any, this.onInteraction, INTERACTIVE_TIMEOUT_MS);\n }\n}\n","import type { IDmk } from '../types';\nimport { SignerEth } from './SignerEth';\n\ntype SignerEthBuilderFn = (args: { dmk: IDmk; sessionId: string }) => { build(): unknown } | Promise<{ build(): unknown }>;\n\n/**\n * Manages per-sessionId SignerEth instances.\n * Creates on demand, caches for reuse, invalidates on session change.\n */\nexport class SignerManager {\n private readonly _cache = new Map<string, SignerEth>();\n private readonly _dmk: IDmk;\n private readonly _builderFn: SignerEthBuilderFn;\n\n constructor(dmk: IDmk, builderFn?: SignerEthBuilderFn) {\n this._dmk = dmk;\n this._builderFn = builderFn ?? SignerManager._defaultBuilder();\n }\n\n async getOrCreate(sessionId: string): Promise<SignerEth> {\n const hadCached = this._cache.has(sessionId);\n // Always create a fresh signer — DMK signers may maintain internal DeviceAction\n // state that can prevent subsequent operations if reused.\n this._cache.delete(sessionId);\n\n console.log('[DMK] SignerManager.getOrCreate:', { sessionId, hadCached, creating: true });\n const builder = await this._builderFn({ dmk: this._dmk, sessionId });\n const sdkSigner = builder.build();\n console.log('[DMK] SignerManager: new signer built');\n const signer = new SignerEth(sdkSigner as any);\n this._cache.set(sessionId, signer);\n return signer;\n }\n\n invalidate(sessionId: string): void {\n this._cache.delete(sessionId);\n }\n\n clearAll(): void {\n this._cache.clear();\n }\n\n private static _defaultBuilder(): SignerEthBuilderFn {\n let BuilderClass: any = null;\n return async (args) => {\n if (!BuilderClass) {\n const mod = await import('@ledgerhq/device-signer-kit-ethereum');\n BuilderClass = mod.SignerEthBuilder;\n }\n return new BuilderClass(args);\n };\n }\n}\n","import type { SignerBtcAddress } from '../types';\nimport { deviceActionToPromise } from './deviceActionToPromise';\n\n/**\n * SDK BTC signer interface — duck-typed to avoid hard dependency on\n * @ledgerhq/device-signer-kit-bitcoin.\n */\nexport interface ISdkSignerBtc {\n getExtendedPublicKey(derivationPath: string, options?: { checkOnDevice?: boolean }): unknown;\n getWalletAddress(wallet: unknown, addressIndex: number, options?: { checkOnDevice?: boolean; change?: boolean }): unknown;\n getMasterFingerprint(options?: { skipOpenApp?: boolean }): unknown;\n signPsbt(wallet: unknown, psbt: unknown, options?: unknown): unknown;\n signTransaction(wallet: unknown, psbt: unknown, options?: unknown): unknown;\n signMessage(derivationPath: string, message: string, options?: unknown): unknown;\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 constructor(private readonly _sdk: ISdkSignerBtc) {}\n\n async getWalletAddress(\n wallet: unknown,\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>(action as any, this.onInteraction);\n }\n\n async getExtendedPublicKey(\n derivationPath: string,\n options?: { checkOnDevice?: boolean },\n ): Promise<string> {\n const action = this._sdk.getExtendedPublicKey(derivationPath, {\n checkOnDevice: options?.checkOnDevice ?? false,\n });\n return deviceActionToPromise<string>(action as any, this.onInteraction);\n }\n\n async getMasterFingerprint(\n options?: { skipOpenApp?: boolean },\n ): Promise<Uint8Array> {\n const action = this._sdk.getMasterFingerprint(options);\n const result = await deviceActionToPromise<{ masterFingerprint: Uint8Array }>(action as any, this.onInteraction);\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(\n wallet: unknown,\n psbt: unknown,\n options?: unknown,\n ): Promise<unknown[]> {\n const action = this._sdk.signPsbt(wallet, psbt, options);\n return deviceActionToPromise<unknown[]>(action as any, this.onInteraction, INTERACTIVE_TIMEOUT_MS);\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: unknown,\n psbt: unknown,\n options?: unknown,\n ): Promise<string> {\n const action = this._sdk.signTransaction(wallet, psbt, options);\n return deviceActionToPromise<string>(action as any, this.onInteraction, INTERACTIVE_TIMEOUT_MS);\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?: unknown,\n ): Promise<{ r: string; s: string; v: number }> {\n const action = this._sdk.signMessage(derivationPath, message, options);\n return deviceActionToPromise<{ r: string; s: string; v: number }>(action as any, this.onInteraction, INTERACTIVE_TIMEOUT_MS);\n }\n}\n","import { deviceActionToPromise } from './deviceActionToPromise';\n\n/**\n * SDK SOL signer interface — duck-typed to avoid hard dependency on\n * @ledgerhq/device-signer-kit-solana.\n */\nexport interface ISdkSignerSol {\n getAddress(derivationPath: string, options?: { checkOnDevice?: boolean }): unknown;\n signTransaction(derivationPath: string, transaction: Uint8Array, options?: unknown): unknown;\n signMessage(derivationPath: string, message: string | Uint8Array, options?: unknown): unknown;\n}\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 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(\n derivationPath: string,\n options?: { checkOnDevice?: boolean },\n ): Promise<string> {\n const action = this._sdk.getAddress(derivationPath, {\n checkOnDevice: options?.checkOnDevice ?? false,\n });\n return deviceActionToPromise<string>(action as any, this.onInteraction);\n }\n\n /**\n * Sign a Solana transaction.\n */\n async signTransaction(\n derivationPath: string,\n transaction: Uint8Array,\n options?: unknown,\n ): Promise<Uint8Array> {\n const action = this._sdk.signTransaction(derivationPath, transaction, options);\n return deviceActionToPromise<Uint8Array>(action as any, this.onInteraction);\n }\n\n /**\n * Sign a message with the Solana app.\n */\n async signMessage(\n derivationPath: string,\n message: string | Uint8Array,\n options?: unknown,\n ): Promise<Uint8Array> {\n const action = this._sdk.signMessage(derivationPath, message, options);\n return deviceActionToPromise<Uint8Array>(action as any, this.onInteraction);\n }\n}\n","/**\n * TRON Ledger signer — sends raw APDUs to the TRON app on the Ledger device.\n *\n * Unlike EVM/BTC/SOL which have dedicated DMK signer kits,\n * TRON requires direct APDU communication. This class builds and sends\n * the APDU packets according to the TRON Ledger app protocol.\n *\n * APDU Protocol Reference (Ledger hw-app-trx / PR #1284):\n * CLA = 0xE0\n * INS_ADDRESS = 0x02\n * INS_SIGN = 0x04\n * INS_VERSION = 0x06\n * INS_SIGN_MESSAGE = 0x08\n * CHUNK_SIZE = 250\n */\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst CLA = 0xe0;\nconst INS_ADDRESS = 0x02;\nconst INS_SIGN = 0x04;\nconst INS_SIGN_MESSAGE = 0x08;\nconst CHUNK_SIZE = 250;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Function to send a raw APDU to the Ledger device and receive the response.\n *\n * The raw APDU is `[CLA, INS, P1, P2, Lc, ...data]`.\n * The response is `{ statusCode: Uint8Array (2 bytes), data: Uint8Array }`.\n */\nexport type SendApduFn = (\n rawApdu: Uint8Array,\n) => Promise<{ statusCode: Uint8Array; data: Uint8Array }>;\n\nexport interface TronAddressResult {\n publicKey: string;\n address: string;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Convert hex string (with or without 0x) to Uint8Array. */\nfunction hexToBytes(hex: string): Uint8Array {\n const h = hex.startsWith('0x') ? hex.slice(2) : hex;\n const bytes = new Uint8Array(h.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(h.substring(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\n/** Convert Uint8Array to hex string (no 0x prefix). */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * Split a BIP-44 derivation path string into an array of 4-byte big-endian integers.\n * e.g. \"m/44'/195'/0'/0/0\" → [0x8000002C, 0x800000C3, 0x80000000, 0, 0]\n */\nfunction splitPath(path: string): number[] {\n const p = path.startsWith('m/') ? path.slice(2) : path;\n return p.split('/').map((component) => {\n const hardened = component.endsWith(\"'\");\n const index = parseInt(hardened ? component.slice(0, -1) : component, 10);\n return hardened ? index + 0x80000000 : index;\n });\n}\n\n/**\n * Serialize derivation path components into bytes:\n * pathCount (1 byte) + each component (4 bytes big-endian)\n */\nfunction serializePath(path: string): Uint8Array {\n const components = splitPath(path);\n const buf = new Uint8Array(1 + components.length * 4);\n buf[0] = components.length;\n for (let i = 0; i < components.length; i++) {\n const val = components[i];\n const offset = 1 + i * 4;\n buf[offset] = (val >>> 24) & 0xff;\n buf[offset + 1] = (val >>> 16) & 0xff;\n buf[offset + 2] = (val >>> 8) & 0xff;\n buf[offset + 3] = val & 0xff;\n }\n return buf;\n}\n\n/**\n * Build a raw APDU packet: [CLA, INS, P1, P2, Lc, ...data]\n */\nfunction buildApdu(\n cla: number,\n ins: number,\n p1: number,\n p2: number,\n data?: Uint8Array,\n): Uint8Array {\n const dataLen = data?.length ?? 0;\n const apdu = new Uint8Array(5 + dataLen);\n apdu[0] = cla;\n apdu[1] = ins;\n apdu[2] = p1;\n apdu[3] = p2;\n apdu[4] = dataLen;\n if (data && dataLen > 0) {\n apdu.set(data, 5);\n }\n return apdu;\n}\n\n/**\n * Check that the APDU response has a success status (0x9000).\n * Throws an error with the status code if not.\n */\nfunction checkStatusCode(statusCode: Uint8Array, context: string): void {\n if (statusCode.length < 2) {\n throw new Error(`${context}: invalid status code length`);\n }\n const sw = (statusCode[0] << 8) | statusCode[1];\n if (sw !== 0x9000) {\n throw Object.assign(\n new Error(`${context}: device returned error status 0x${sw.toString(16).padStart(4, '0')}`),\n { statusCode: sw.toString(16), errorCode: sw.toString() },\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// SignerTron\n// ---------------------------------------------------------------------------\n\n/**\n * TRON signer that communicates with the Ledger TRON app via raw APDUs.\n *\n * Implements getAddress, signTransaction, and signMessage using the\n * APDU protocol described in the Ledger TRON app documentation.\n */\nexport class SignerTron {\n constructor(private readonly _sendApdu: SendApduFn) {}\n\n /**\n * Get the TRON address at the given derivation path.\n *\n * APDU: CLA=0xE0, INS=0x02, P1=(showOnDevice?0x01:0x00), P2=0x00\n * Data: pathCount(1) + paths(4 bytes each, big-endian, hardened bit)\n * Response: pubKeyLen(1) + pubKey(pubKeyLen) + addrLen(1) + addr(addrLen, ASCII base58)\n */\n async getAddress(\n path: string,\n options?: { checkOnDevice?: boolean },\n ): Promise<TronAddressResult> {\n const showOnDevice = options?.checkOnDevice ?? false;\n const pathData = serializePath(path);\n\n const apdu = buildApdu(\n CLA,\n INS_ADDRESS,\n showOnDevice ? 0x01 : 0x00,\n 0x00,\n pathData,\n );\n\n const response = await this._sendApdu(apdu);\n checkStatusCode(response.statusCode, 'tronGetAddress');\n\n const data = response.data;\n let offset = 0;\n\n // Parse public key\n const pubKeyLen = data[offset];\n offset += 1;\n const publicKey = bytesToHex(data.slice(offset, offset + pubKeyLen));\n offset += pubKeyLen;\n\n // Parse address (ASCII base58)\n const addrLen = data[offset];\n offset += 1;\n const addressBytes = data.slice(offset, offset + addrLen);\n const address = new TextDecoder().decode(addressBytes);\n\n return { publicKey, address };\n }\n\n /**\n * Sign a TRON transaction (protobuf-encoded raw transaction).\n *\n * The transaction bytes are split into 250-byte chunks and sent sequentially.\n * First chunk includes the serialized derivation path prefix.\n *\n * P1 flags:\n * 0x10 = single chunk (entire tx fits in one APDU)\n * 0x00 = first chunk of multi-chunk\n * 0x80 = middle chunk (continuation)\n * 0x90 = last chunk (final continuation)\n *\n * Returns: 65-byte signature as hex string (no 0x prefix).\n */\n async signTransaction(path: string, rawTxHex: string): Promise<string> {\n const pathData = serializePath(path);\n const txBytes = hexToBytes(rawTxHex);\n\n // First chunk payload: path data + as many tx bytes as fit\n const firstChunkMaxTx = CHUNK_SIZE - pathData.length;\n const txForFirst = txBytes.slice(0, firstChunkMaxTx);\n const firstPayload = new Uint8Array(pathData.length + txForFirst.length);\n firstPayload.set(pathData, 0);\n firstPayload.set(txForFirst, pathData.length);\n\n const remaining = txBytes.slice(firstChunkMaxTx);\n\n // Build continuation chunks from remaining bytes\n const chunks: Uint8Array[] = [];\n let pos = 0;\n while (pos < remaining.length) {\n chunks.push(remaining.slice(pos, pos + CHUNK_SIZE));\n pos += CHUNK_SIZE;\n }\n\n const totalChunks = 1 + chunks.length;\n let response: { statusCode: Uint8Array; data: Uint8Array };\n\n if (totalChunks === 1) {\n // Single chunk: P1 = 0x10\n const apdu = buildApdu(CLA, INS_SIGN, 0x10, 0x00, firstPayload);\n response = await this._sendApdu(apdu);\n checkStatusCode(response.statusCode, 'tronSignTransaction');\n } else {\n // First chunk: P1 = 0x00\n const firstApdu = buildApdu(CLA, INS_SIGN, 0x00, 0x00, firstPayload);\n response = await this._sendApdu(firstApdu);\n checkStatusCode(response.statusCode, 'tronSignTransaction (first)');\n\n // Middle/last chunks\n for (let i = 0; i < chunks.length; i++) {\n const isLast = i === chunks.length - 1;\n const p1 = isLast ? 0x90 : 0x80;\n const apdu = buildApdu(CLA, INS_SIGN, p1, 0x00, chunks[i]);\n response = await this._sendApdu(apdu);\n checkStatusCode(response.statusCode, `tronSignTransaction (chunk ${i + 1})`);\n }\n }\n\n // Response from the last APDU: 65-byte signature\n return bytesToHex(response.data.slice(0, 65));\n }\n\n /**\n * Sign a personal message with the TRON app.\n *\n * First chunk: pathCount(1) + paths(4 bytes BE) + messageLength(4 bytes BE) + message bytes\n * Subsequent: continuation bytes\n * P1: 0x00 = first, 0x80 = continuation\n *\n * Returns: 65-byte signature as hex string (no 0x prefix).\n */\n async signMessage(path: string, messageHex: string): Promise<string> {\n const pathData = serializePath(path);\n const messageBytes = hexToBytes(messageHex);\n\n // Message length as 4 bytes big-endian\n const msgLenBuf = new Uint8Array(4);\n const msgLen = messageBytes.length;\n msgLenBuf[0] = (msgLen >>> 24) & 0xff;\n msgLenBuf[1] = (msgLen >>> 16) & 0xff;\n msgLenBuf[2] = (msgLen >>> 8) & 0xff;\n msgLenBuf[3] = msgLen & 0xff;\n\n // First chunk header: path + message length\n const header = new Uint8Array(pathData.length + 4);\n header.set(pathData, 0);\n header.set(msgLenBuf, pathData.length);\n\n // First chunk payload: header + as many message bytes as fit\n const firstChunkMaxMsg = CHUNK_SIZE - header.length;\n const msgForFirst = messageBytes.slice(0, firstChunkMaxMsg);\n const firstPayload = new Uint8Array(header.length + msgForFirst.length);\n firstPayload.set(header, 0);\n firstPayload.set(msgForFirst, header.length);\n\n const remaining = messageBytes.slice(firstChunkMaxMsg);\n\n // Build continuation chunks\n const chunks: Uint8Array[] = [];\n let pos = 0;\n while (pos < remaining.length) {\n chunks.push(remaining.slice(pos, pos + CHUNK_SIZE));\n pos += CHUNK_SIZE;\n }\n\n let response: { statusCode: Uint8Array; data: Uint8Array };\n\n // First chunk: P1 = 0x00\n const firstApdu = buildApdu(CLA, INS_SIGN_MESSAGE, 0x00, 0x00, firstPayload);\n response = await this._sendApdu(firstApdu);\n checkStatusCode(response.statusCode, 'tronSignMessage (first)');\n\n // Continuation chunks: P1 = 0x80\n for (let i = 0; i < chunks.length; i++) {\n const apdu = buildApdu(CLA, INS_SIGN_MESSAGE, 0x80, 0x00, chunks[i]);\n response = await this._sendApdu(apdu);\n checkStatusCode(response.statusCode, `tronSignMessage (chunk ${i + 1})`);\n }\n\n // Response from the last APDU: 65-byte signature\n return bytesToHex(response.data.slice(0, 65));\n }\n}\n","import type {\n IConnector,\n ConnectorDevice,\n ConnectorSession,\n ConnectorEventType,\n ConnectorEventMap,\n ConnectionType,\n DeviceDescriptor,\n} from '@bytezhang/hardware-wallet-core';\nimport type { IDmk, SignerEvmSignature } from '../types';\nimport { LedgerDeviceManager } from '../device/LedgerDeviceManager';\nimport { SignerManager } from '../signer/SignerManager';\nimport { SignerBtc } from '../signer/SignerBtc';\nimport { SignerSol } from '../signer/SignerSol';\nimport { SignerTron } from '../signer/SignerTron';\nimport { mapLedgerError } from '../errors';\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?: IDmk;\n}\n\n// ---------------------------------------------------------------------------\n// Internal types — call params\n// ---------------------------------------------------------------------------\n\ntype EventHandler<K extends ConnectorEventType> = (\n data: ConnectorEventMap[K],\n) => void;\n\n/** Parameters for evmGetAddress */\ninterface EvmGetAddressCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\n/** Parameters for evmSignTransaction */\ninterface EvmSignTransactionCallParams {\n path: string;\n /** RLP-serialized transaction hex (0x-prefixed or plain) */\n serializedTx: string;\n}\n\n/** Parameters for evmSignMessage */\ninterface EvmSignMessageCallParams {\n path: string;\n message: string;\n}\n\n/** Parameters for evmSignTypedData */\ninterface EvmSignTypedDataCallParams {\n path: string;\n data: unknown;\n}\n\n/** Parameters for btcGetAddress */\ninterface BtcGetAddressCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\n/** Parameters for btcGetPublicKey */\ninterface BtcGetPublicKeyCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\n/** Parameters for btcSignTransaction */\ninterface 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\n/** Parameters for btcSignMessage */\ninterface BtcSignMessageCallParams {\n path: string;\n message: string;\n coin?: string;\n}\n\n/** Parameters for solGetAddress */\ninterface SolGetAddressCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\n/** Parameters for solSignTransaction */\ninterface SolSignTransactionCallParams {\n path: string;\n /** Hex-encoded serialized transaction bytes (no 0x prefix) */\n serializedTx: string;\n}\n\n/** Parameters for solSignMessage */\ninterface SolSignMessageCallParams {\n path: string;\n /** Message bytes as hex string (no 0x prefix) */\n message: string;\n}\n\n/** Parameters for tronGetAddress */\ninterface TronGetAddressCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\n/** Parameters for tronSignTransaction */\ninterface TronSignTransactionCallParams {\n path: string;\n /** Protobuf-encoded raw transaction hex (no 0x prefix) */\n rawTxHex: string;\n}\n\n/** Parameters for tronSignMessage */\ninterface TronSignMessageCallParams {\n path: string;\n /** Message hex (no 0x prefix) */\n messageHex: string;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Strip the \"m/\" prefix from BIP-44 derivation paths. */\nfunction normalizePath(path: string): string {\n return path.startsWith('m/') ? path.slice(2) : path;\n}\n\n/** Remove `0x` prefix from a hex string if present. */\nfunction stripHex(hex: string): string {\n return hex.startsWith('0x') ? hex.slice(2) : hex;\n}\n\n/** Ensure a hex string is `0x`-prefixed and zero-padded to 64 hex chars (32 bytes). */\nfunction padHex64(hex: string): string {\n return `0x${stripHex(hex).padStart(64, '0')}`;\n}\n\n/** Convert a hex string (no 0x prefix) to a Uint8Array. */\nfunction hexToBytes(hex: string): Uint8Array {\n const clean = stripHex(hex);\n const bytes = new Uint8Array(clean.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\n/** Convert a Uint8Array to a hex string (no 0x prefix). */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\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), signer lifecycle, event emission,\n * and error handling.\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 private _signerManager: SignerManager | null = null;\n private _dmk: IDmk | null = null;\n\n private readonly _eventHandlers = new Map<\n ConnectorEventType,\n Set<EventHandler<ConnectorEventType>>\n >();\n\n private readonly _providedDmk: IDmk | undefined;\n private readonly _createTransport: TransportFactory;\n private readonly _connectionType: ConnectionType;\n\n constructor(\n createTransport: TransportFactory,\n options?: { connectionType?: ConnectionType; dmk?: IDmk },\n ) {\n this._createTransport = createTransport;\n this._connectionType = options?.connectionType ?? 'usb';\n this._providedDmk = options?.dmk;\n if (this._providedDmk) {\n this._initManagers(this._providedDmk);\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._resolveConnectId(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\n // Ensure we have fresh device list\n await this.searchDevices();\n\n let resolvedDeviceId = deviceId;\n\n // Empty or missing deviceId -- use first available device's DMK path\n if (!resolvedDeviceId) {\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${this._connectionType === 'ble' ? ' nearby with Bluetooth enabled' : ' via USB'} and unlocked.`,\n );\n }\n resolvedDeviceId = descriptors[0].path;\n }\n\n try {\n const sessionId = await dm.connect(resolvedDeviceId);\n\n const session: ConnectorSession = {\n sessionId,\n deviceInfo: {\n vendor: 'ledger',\n model: 'unknown',\n firmwareVersion: 'unknown',\n deviceId: resolvedDeviceId,\n connectId: resolvedDeviceId,\n connectionType: this._connectionType,\n capabilities: {\n persistentDeviceIdentity: false,\n },\n },\n };\n\n this._emit('device-connect', {\n device: {\n connectId: resolvedDeviceId,\n deviceId: resolvedDeviceId,\n name: 'Ledger',\n },\n });\n\n return session;\n } catch (err) {\n // Retry once: reset and re-discover\n this._resetManagers();\n const dm2 = await this._getDeviceManager();\n await this.searchDevices();\n\n const descriptors = await dm2.enumerate();\n const retryId = deviceId\n ? descriptors.find((d) => d.path === deviceId)?.path\n : descriptors[0]?.path;\n\n if (!retryId) {\n throw new Error(\n `No Ledger device found after retry. Make sure the device is connected${this._connectionType === 'ble' ? ' nearby with Bluetooth enabled' : ' via USB'} and unlocked.`,\n );\n }\n\n const sessionId = await dm2.connect(retryId);\n\n const session: ConnectorSession = {\n sessionId,\n deviceInfo: {\n vendor: 'ledger',\n model: 'unknown',\n firmwareVersion: 'unknown',\n deviceId: retryId,\n connectId: retryId,\n connectionType: this._connectionType,\n },\n };\n\n this._emit('device-connect', {\n device: {\n connectId: retryId,\n deviceId: retryId,\n name: 'Ledger',\n },\n });\n\n return session;\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(\n sessionId: string,\n method: string,\n params: unknown,\n ): Promise<unknown> {\n console.log('[DMK] call:', method, JSON.stringify(params));\n switch (method) {\n case 'evmGetAddress':\n return this._evmGetAddress(sessionId, params as EvmGetAddressCallParams);\n case 'evmSignTransaction':\n return this._evmSignTransaction(sessionId, params as EvmSignTransactionCallParams);\n case 'evmSignMessage':\n return this._evmSignMessage(sessionId, params as EvmSignMessageCallParams);\n case 'evmSignTypedData':\n return this._evmSignTypedData(sessionId, params as EvmSignTypedDataCallParams);\n case 'btcGetAddress':\n return this._btcGetAddress(sessionId, params as BtcGetAddressCallParams);\n case 'btcGetPublicKey':\n return this._btcGetPublicKey(sessionId, params as BtcGetPublicKeyCallParams);\n case 'btcSignTransaction':\n return this._btcSignTransaction(sessionId, params as BtcSignTransactionCallParams);\n case 'btcSignMessage':\n return this._btcSignMessage(sessionId, params as BtcSignMessageCallParams);\n case 'btcGetMasterFingerprint':\n return this._btcGetMasterFingerprint(sessionId, params as { skipOpenApp?: boolean } | undefined);\n case 'solGetAddress':\n return this._solGetAddress(sessionId, params as SolGetAddressCallParams);\n case 'solSignTransaction':\n return this._solSignTransaction(sessionId, params as SolSignTransactionCallParams);\n case 'solSignMessage':\n return this._solSignMessage(sessionId, params as SolSignMessageCallParams);\n case 'tronGetAddress':\n return this._tronGetAddress(sessionId, params as TronGetAddressCallParams);\n case 'tronSignTransaction':\n return this._tronSignTransaction(sessionId, params as TronSignTransactionCallParams);\n case 'tronSignMessage':\n return this._tronSignMessage(sessionId, params as TronSignMessageCallParams);\n default:\n throw new Error(`LedgerConnector: unknown method \"${method}\"`);\n }\n }\n\n async cancel(_sessionId: string): Promise<void> {\n // Ledger DMK doesn't expose a generic cancel mechanism\n }\n\n uiResponse(_response: { type: string; payload: unknown }): void {\n // Ledger does not use interactive UI responses (PIN/passphrase)\n }\n\n // ---------------------------------------------------------------------------\n // IConnector -- Events\n // ---------------------------------------------------------------------------\n\n on<K extends ConnectorEventType>(\n event: K,\n handler: (data: ConnectorEventMap[K]) => void,\n ): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers\n .get(event)!\n .add(handler as EventHandler<ConnectorEventType>);\n }\n\n off<K extends ConnectorEventType>(\n event: K,\n handler: (data: ConnectorEventMap[K]) => void,\n ): void {\n this._eventHandlers\n .get(event)\n ?.delete(handler as EventHandler<ConnectorEventType>);\n }\n\n // ---------------------------------------------------------------------------\n // IConnector -- Reset\n // ---------------------------------------------------------------------------\n\n reset(): void {\n this._resetManagers();\n }\n\n // ---------------------------------------------------------------------------\n // Private -- EVM methods\n // ---------------------------------------------------------------------------\n\n private async _evmGetAddress(\n sessionId: string,\n params: EvmGetAddressCallParams,\n ): Promise<{ address: string; publicKey?: string }> {\n const signer = await this._getEthSigner(sessionId);\n const path = normalizePath(params.path);\n const checkOnDevice = params.showOnDevice ?? false;\n console.log('[DMK] _evmGetAddress → signer.getAddress:', { path, checkOnDevice });\n\n try {\n const result = await signer.getAddress(path, {\n checkOnDevice,\n });\n return { address: result.address, publicKey: result.publicKey };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _evmSignTransaction(\n sessionId: string,\n params: EvmSignTransactionCallParams,\n ): Promise<{ v: string; r: string; s: string }> {\n const signer = await this._getEthSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const result: SignerEvmSignature = await signer.signTransaction(\n path,\n params.serializedTx,\n );\n return {\n v: `0x${result.v.toString(16)}`,\n r: padHex64(result.r),\n s: padHex64(result.s),\n };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _evmSignMessage(\n sessionId: string,\n params: EvmSignMessageCallParams,\n ): Promise<{ signature: string }> {\n const signer = await this._getEthSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const result: SignerEvmSignature = await signer.signMessage(\n path,\n params.message,\n );\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 this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _evmSignTypedData(\n sessionId: string,\n params: EvmSignTypedDataCallParams,\n ): Promise<{ signature: string }> {\n const signer = await this._getEthSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const result: SignerEvmSignature = await signer.signTypedData(\n path,\n params.data,\n );\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 this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private -- BTC methods\n // ---------------------------------------------------------------------------\n\n private async _btcGetAddress(\n sessionId: string,\n params: BtcGetAddressCallParams,\n ): Promise<{ address: string; path: string }> {\n const btcSigner = await this._createBtcSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const { DefaultWallet, DefaultDescriptorTemplate } = await import(\n '@ledgerhq/device-signer-kit-bitcoin'\n );\n const purpose = path.split('/')[0]?.replace(\"'\", '');\n let template = DefaultDescriptorTemplate.NATIVE_SEGWIT;\n if (purpose === '44') template = DefaultDescriptorTemplate.LEGACY;\n else if (purpose === '49')\n template = DefaultDescriptorTemplate.NESTED_SEGWIT;\n else if (purpose === '86') template = DefaultDescriptorTemplate.TAPROOT;\n const wallet = new DefaultWallet(path, template);\n\n const result = await btcSigner.getWalletAddress(wallet, 0, {\n checkOnDevice: params.showOnDevice ?? false,\n change: false,\n });\n return { address: result.address, path: params.path };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _btcGetPublicKey(\n sessionId: string,\n params: BtcGetPublicKeyCallParams,\n ): Promise<{ xpub: string; path: string }> {\n const btcSigner = await this._createBtcSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const xpub = await btcSigner.getExtendedPublicKey(path, {\n checkOnDevice: params.showOnDevice ?? false,\n });\n return { xpub, path: params.path };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _btcSignTransaction(\n sessionId: string,\n params: BtcSignTransactionCallParams,\n ): Promise<{ signedPsbt: string }> {\n const btcSigner = await this._createBtcSigner(sessionId);\n\n try {\n const { DefaultWallet, DefaultDescriptorTemplate } = await import(\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(\"'\", '');\n let template = DefaultDescriptorTemplate.NATIVE_SEGWIT;\n if (purpose === '44') template = DefaultDescriptorTemplate.LEGACY;\n else if (purpose === '49')\n template = DefaultDescriptorTemplate.NESTED_SEGWIT;\n else if (purpose === '86') template = DefaultDescriptorTemplate.TAPROOT;\n\n const wallet = new DefaultWallet(path, template);\n\n // signTransaction: signs the PSBT and returns the fully extracted raw tx hex\n const signedTxHex = await btcSigner.signTransaction(wallet, params.psbt!);\n\n return { signedPsbt: stripHex(signedTxHex) };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _btcSignMessage(\n sessionId: string,\n params: BtcSignMessageCallParams,\n ): Promise<{ signature: string; address: string }> {\n const btcSigner = await this._createBtcSigner(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 // Concatenate r + s + v into a single hex signature (65 bytes)\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\n return { signature: `${rHex}${sHex}${vHex}`, address: '' };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _btcGetMasterFingerprint(\n sessionId: string,\n params?: { skipOpenApp?: boolean },\n ): Promise<{ masterFingerprint: string }> {\n const btcSigner = await this._createBtcSigner(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 this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private -- SOL methods\n // ---------------------------------------------------------------------------\n\n private async _solGetAddress(\n sessionId: string,\n params: SolGetAddressCallParams,\n ): Promise<{ address: string; path: string }> {\n const solSigner = await this._createSolSigner(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 this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _solSignTransaction(\n sessionId: string,\n params: SolSignTransactionCallParams,\n ): Promise<{ signature: string }> {\n const solSigner = await this._createSolSigner(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 this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _solSignMessage(\n sessionId: string,\n params: SolSignMessageCallParams,\n ): Promise<{ signature: string }> {\n const solSigner = await this._createSolSigner(sessionId);\n const path = normalizePath(params.path);\n const messageBytes = hexToBytes(params.message);\n\n try {\n const result = await solSigner.signMessage(path, messageBytes);\n return { signature: bytesToHex(result) };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private -- TRON methods\n // ---------------------------------------------------------------------------\n\n private async _tronGetAddress(\n sessionId: string,\n params: TronGetAddressCallParams,\n ): Promise<{ address: string; publicKey: string; path: string }> {\n const tronSigner = await this._createTronSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const result = await tronSigner.getAddress(path, {\n checkOnDevice: params.showOnDevice ?? false,\n });\n return { address: result.address, publicKey: result.publicKey, path: params.path };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _tronSignTransaction(\n sessionId: string,\n params: TronSignTransactionCallParams,\n ): Promise<{ signature: string }> {\n const tronSigner = await this._createTronSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const signature = await tronSigner.signTransaction(path, params.rawTxHex);\n return { signature };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _tronSignMessage(\n sessionId: string,\n params: TronSignMessageCallParams,\n ): Promise<{ signature: string }> {\n const tronSigner = await this._createTronSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const signature = await tronSigner.signMessage(path, params.messageHex);\n return { signature };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\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<IDmk> {\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 import(\n '@ledgerhq/device-management-kit'\n );\n const transportFactory = await this._createTransport();\n\n this._dmk = new DeviceManagementKitBuilder()\n .addTransport(transportFactory as any)\n .build() as unknown as IDmk;\n\n return this._dmk;\n }\n\n private _initManagers(dmk: IDmk): void {\n this._dmk = dmk;\n this._deviceManager = new LedgerDeviceManager(dmk);\n this._signerManager = new SignerManager(dmk);\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 _getEthSigner(sessionId: string) {\n if (!this._signerManager) {\n const dmk = await this._getOrCreateDmk();\n this._initManagers(dmk);\n }\n const signer = await this._signerManager!.getOrCreate(sessionId);\n\n // Wire up interaction events (open-app, unlock, verify-address, sign, etc.)\n signer.onInteraction = (interaction: string) => {\n this._emit('ui-event', {\n type: interaction,\n payload: { sessionId },\n });\n };\n\n return signer;\n }\n\n private async _createBtcSigner(sessionId: string): Promise<SignerBtc> {\n const dmk = await this._getOrCreateDmk();\n const { SignerBtcBuilder } = await import(\n '@ledgerhq/device-signer-kit-bitcoin'\n );\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sdkSigner = new SignerBtcBuilder({\n dmk: dmk as any,\n sessionId,\n }).build();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const signer = new SignerBtc(sdkSigner as any);\n\n // Wire up interaction events (open-app, unlock, sign, etc.)\n signer.onInteraction = (interaction: string) => {\n this._emit('ui-event', {\n type: interaction,\n payload: { sessionId },\n });\n };\n\n return signer;\n }\n\n private async _createSolSigner(sessionId: string): Promise<SignerSol> {\n const dmk = await this._getOrCreateDmk();\n // Use direct CJS path — this package has no \"main\" field,\n // only \"exports\", which Metro (React Native) can't resolve.\n const { SignerSolanaBuilder } = await import(\n '@ledgerhq/device-signer-kit-solana/lib/cjs/index.js' as any\n );\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sdkSigner = new SignerSolanaBuilder({\n dmk: dmk as any,\n sessionId,\n }).build();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new SignerSol(sdkSigner as any);\n }\n\n private async _createTronSigner(sessionId: string): Promise<SignerTron> {\n const dmk = await this._getOrCreateDmk();\n // TRON has no dedicated DMK signer kit — communicate via raw APDUs\n const sendApdu = async (rawApdu: Uint8Array) => {\n const response = await dmk.sendApdu({ sessionId, apdu: rawApdu });\n return response;\n };\n return new SignerTron(sendApdu);\n }\n\n private _invalidateSession(sessionId: string): void {\n this._signerManager?.invalidate(sessionId);\n }\n\n private _resetManagers(): void {\n this._signerManager?.clearAll();\n this._deviceManager?.dispose();\n this._deviceManager = null;\n this._signerManager = null;\n this._dmk = null;\n }\n\n // ---------------------------------------------------------------------------\n // Private -- Events\n // ---------------------------------------------------------------------------\n\n private _emit<K extends ConnectorEventType>(\n event: K,\n data: ConnectorEventMap[K],\n ): 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 (error as any).code = mapped.code;\n return error;\n }\n}\n","import type { TransportProvider } from '../types';\n\nconst registry = new Map<string, TransportProvider>();\n\nfunction normalizeType(type: string): string {\n return type.trim().toLowerCase();\n}\n\nexport function registerTransport(type: string, provider: TransportProvider): void {\n const key = normalizeType(type);\n if (!key) throw new Error('Transport type must be a non-empty string');\n registry.set(key, provider);\n}\n\nexport function unregisterTransport(type: string): void {\n registry.delete(normalizeType(type));\n}\n\nexport function getTransportProvider(type: string): TransportProvider | null {\n return registry.get(normalizeType(type)) ?? null;\n}\n\nexport function listRegisteredTransports(): string[] {\n return Array.from(registry.keys());\n}\n\nexport function clearRegistry(): void {\n registry.clear();\n}\n","import type { IDmk } from '../types';\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: IDmk;\n private readonly _waitMs: number;\n private readonly _maxRetries: number;\n\n constructor(dmk: IDmk, 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 async ensureAppOpen(sessionId: string, targetAppName: string): 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\n await this._openApp(sessionId, targetAppName);\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: { type: 'get-app-and-version' },\n })) as { name: string };\n return result.name;\n }\n\n private async _openApp(sessionId: string, appName: string): Promise<void> {\n await this._dmk.sendCommand({\n sessionId,\n command: { type: 'open-app', appName },\n });\n }\n\n private async _closeCurrentApp(sessionId: string): Promise<void> {\n await this._dmk.sendCommand({\n sessionId,\n command: { type: 'close-app' },\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"],"mappings":"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","names":["import_hardware_wallet_core","result","INTERACTIVE_TIMEOUT_MS","hexToBytes","stripHex","padHex64","hexToBytes","bytesToHex"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/adapter/LedgerAdapter.ts","../src/errors.ts","../src/device/LedgerDeviceManager.ts","../src/signer/deviceActionToPromise.ts","../src/signer/SignerEth.ts","../src/signer/SignerManager.ts","../src/signer/SignerBtc.ts","../src/signer/SignerSol.ts","../src/signer/SignerTron.ts","../src/connector/LedgerConnectorBase.ts","../src/transport/registry.ts","../src/app/AppManager.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 { SignerTron } from './signer/SignerTron';\nexport { deviceActionToPromise } from './signer/deviceActionToPromise';\n\n// Transport registry\nexport { registerTransport, unregisterTransport, getTransportProvider, listRegisteredTransports, clearRegistry } from './transport/registry';\n\n// App management\nexport { AppManager } from './app/AppManager';\n\n// Types\nexport type { IDmk, DmkDiscoveredDevice, DeviceActionState, SignerEvmAddress, SignerEvmSignature, SignerBtcAddress, TransportProvider, TransportProviderInstance, TransportProviderOptions } from './types';\n\n// Errors\nexport { isDeviceLockedError, mapLedgerError } from './errors';\n","import type {\n IHardwareWallet,\n IUiHandler,\n IConnector,\n ConnectorDevice,\n DeviceInfo,\n HardwareEventMap,\n DeviceEventListener,\n TransportType,\n ConnectionType,\n Response,\n EvmGetAddressParams,\n EvmAddress,\n EvmGetPublicKeyParams,\n EvmPublicKey,\n EvmSignTxParams,\n EvmSignedTx,\n EvmSignMsgParams,\n EvmSignTypedDataParams,\n EvmSignature,\n ProgressCallback,\n BtcGetAddressParams,\n BtcAddress,\n BtcGetPublicKeyParams,\n BtcPublicKey,\n BtcSignTxParams,\n BtcSignedTx,\n BtcSignMsgParams,\n BtcSignature,\n SolGetAddressParams,\n SolAddress,\n SolGetPublicKeyParams,\n SolPublicKey,\n SolSignTxParams,\n SolSignedTx,\n SolSignMsgParams,\n SolSignature,\n TronGetAddressParams,\n TronAddress,\n TronSignTxParams,\n TronSignedTx,\n TronSignMsgParams,\n TronSignature,\n ChainCapability,\n ChainForFingerprint,\n} from '@bytezhang/hardware-wallet-core';\nimport {\n success,\n failure,\n HardwareErrorCode,\n TypedEventEmitter,\n DEVICE,\n UI_REQUEST,\n CHAIN_FINGERPRINT_PATHS,\n deriveDeviceFingerprint,\n} from '@bytezhang/hardware-wallet-core';\nimport { mapLedgerError, isDeviceDisconnectedError } from '../errors';\n\n/** Ensure a hex string has the `0x` prefix. */\nfunction ensure0x(hex: string): string {\n return hex.startsWith('0x') ? hex : `0x${hex}`;\n}\n\n/** Remove `0x` prefix from a hex string if present. */\nfunction stripHex(hex: string): string {\n return hex.startsWith('0x') ? hex.slice(2) : hex;\n}\n\n/** Ensure a hex string is `0x`-prefixed and zero-padded to 64 hex chars (32 bytes). */\nfunction padHex64(hex: string): string {\n return `0x${stripHex(hex).padStart(64, '0')}`;\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 * - Integrates with IUiHandler for permission flows\n */\nexport class LedgerAdapter implements IHardwareWallet {\n readonly vendor = 'ledger' as const;\n\n private readonly connector: IConnector;\n private readonly emitter = new TypedEventEmitter<HardwareEventMap>();\n\n private _uiHandler: Partial<IUiHandler> | null = null;\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 constructor(connector: IConnector) {\n this.connector = connector;\n this.registerEventListeners();\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 return 'hid';\n }\n\n getAvailableTransports(): TransportType[] {\n return ['hid'];\n }\n\n async switchTransport(_type: TransportType): Promise<void> {\n // Transport is fixed at connector creation time.\n // To switch transport, create a new LedgerAdapter with a different connector.\n }\n\n // ---------------------------------------------------------------------------\n // UI handler\n // ---------------------------------------------------------------------------\n\n setUiHandler(handler: Partial<IUiHandler>): void {\n this._uiHandler = handler;\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 async dispose(): Promise<void> {\n // Cancel any pending device-connect prompt\n this._deviceConnectResolve?.(true);\n this._deviceConnectResolve = null;\n\n this.unregisterEventListeners();\n this.connector.reset();\n this._uiHandler = null;\n this._discoveredDevices.clear();\n this._sessions.clear();\n this.emitter.removeAllListeners();\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 console.log('[DMK] adapter.searchDevices raw:', JSON.stringify(devices));\n\n for (const d of devices) {\n if (d.connectId && !this._discoveredDevices.has(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(\n connectId: string,\n deviceId: string,\n ): 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(\n (d) => d.deviceId === deviceId,\n );\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 // Events\n // ---------------------------------------------------------------------------\n\n on<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;\n on(event: string, listener: DeviceEventListener): void;\n on(event: string, listener: (event: any) => void): void {\n this.emitter.on(event, listener);\n }\n\n off<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;\n off(event: string, listener: DeviceEventListener): void;\n off(event: string, listener: (event: any) => void): void {\n this.emitter.off(event, listener);\n }\n\n cancel(connectId: string): void {\n const sessionId = this._sessions.get(connectId) ?? connectId;\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 await this._ensureDevicePermission(connectId, deviceId);\n try {\n const address = await this._deriveAddressForFingerprint(connectId, chain);\n return success(deriveDeviceFingerprint(address));\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n /**\n * Verify that the connected device matches the expected fingerprint.\n *\n * - If deviceId is empty, verification is skipped (returns true).\n * - deviceId is used here as the stored fingerprint to compare against.\n */\n private async _verifyDeviceFingerprint(\n connectId: string,\n deviceId: string,\n chain: ChainForFingerprint,\n ): Promise<boolean> {\n if (!deviceId) return true;\n\n try {\n const address = await this._deriveAddressForFingerprint(connectId, chain);\n const fingerprint = deriveDeviceFingerprint(address);\n return fingerprint === deviceId;\n } catch (err) {\n // \"App not open\" or \"wrong app\" errors are expected — skip verification\n const mapped = mapLedgerError(err);\n if (\n mapped.code === HardwareErrorCode.WrongApp ||\n mapped.code === HardwareErrorCode.DeviceLocked\n ) {\n return true;\n }\n // Transport/disconnect errors should propagate\n throw err;\n }\n }\n\n /**\n * Derive an address at the fixed testnet path for fingerprint generation.\n */\n private async _deriveAddressForFingerprint(\n connectId: string,\n chain: ChainForFingerprint,\n ): Promise<string> {\n const path = CHAIN_FINGERPRINT_PATHS[chain];\n\n if (chain === 'evm') {\n const result = await this.connectorCall(connectId, 'evmGetAddress', {\n path,\n showOnDevice: false,\n }) as { address: string };\n return result.address;\n }\n\n if (chain === 'btc') {\n const result = await this.connectorCall(connectId, 'btcGetAddress', {\n path,\n showOnDevice: false,\n coin: 'Testnet',\n }) as { address: string };\n return result.address;\n }\n\n if (chain === 'sol') {\n const result = await this.connectorCall(connectId, 'solGetAddress', {\n path,\n showOnDevice: false,\n }) as { address: string };\n return result.address;\n }\n\n throw new Error(`Unsupported chain for fingerprint: ${chain as string}`);\n }\n\n // ---------------------------------------------------------------------------\n // EVM methods\n // ---------------------------------------------------------------------------\n\n async evmGetAddress(\n connectId: string,\n _deviceId: string,\n params: EvmGetAddressParams,\n ): Promise<Response<EvmAddress>> {\n console.log('[DMK] adapter.evmGetAddress called:', { connectId, _deviceId, path: params.path, showOnDevice: params.showOnDevice, chainId: params.chainId });\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'evm'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'evmGetAddress', {\n path: params.path,\n showOnDevice: params.showOnDevice,\n chainId: params.chainId,\n }) as { address: string; publicKey?: string; path?: string };\n\n return success({\n address: result.address,\n path: params.path,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async evmGetAddresses(\n connectId: string,\n deviceId: string,\n params: EvmGetAddressParams[],\n onProgress?: ProgressCallback,\n ): Promise<Response<EvmAddress[]>> {\n return this.batchCall(\n params,\n (p) => this.evmGetAddress(connectId, deviceId, p),\n onProgress,\n );\n }\n\n async evmGetPublicKey(\n connectId: string,\n _deviceId: string,\n params: EvmGetPublicKeyParams,\n ): Promise<Response<EvmPublicKey>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'evm'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'evmGetAddress', {\n path: params.path,\n showOnDevice: params.showOnDevice,\n }) as { address: string; publicKey: string; path?: string };\n\n return success({\n publicKey: result.publicKey,\n path: params.path,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async evmSignTransaction(\n connectId: string,\n _deviceId: string,\n params: EvmSignTxParams,\n ): Promise<Response<EvmSignedTx>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'evm'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n if (!params.serializedTx) {\n return failure(\n HardwareErrorCode.InvalidParams,\n 'Ledger requires a pre-serialized transaction (serializedTx). Provide an RLP-encoded hex string.',\n );\n }\n\n const result = await this.connectorCall(connectId, 'evmSignTransaction', {\n path: params.path,\n serializedTx: params.serializedTx,\n }) as { v: string; r: string; s: string; serializedTx?: string };\n\n return success({\n v: ensure0x(result.v),\n r: padHex64(result.r),\n s: padHex64(result.s),\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async evmSignMessage(\n connectId: string,\n _deviceId: string,\n params: EvmSignMsgParams,\n ): Promise<Response<EvmSignature>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'evm'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'evmSignMessage', {\n path: params.path,\n message: params.message,\n }) as { signature: string; address?: string };\n\n return success({\n signature: ensure0x(result.signature),\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async evmSignTypedData(\n connectId: string,\n _deviceId: string,\n params: EvmSignTypedDataParams,\n ): Promise<Response<EvmSignature>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'evm'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n // Ledger requires full EIP-712 structure — hash mode is not supported.\n if (params.mode === 'hash') {\n return failure(\n HardwareErrorCode.MethodNotSupported,\n 'Ledger does not support hash-only EIP-712 signing. Use mode \"full\" with the complete typed data structure.',\n );\n }\n\n try {\n const result = await this.connectorCall(connectId, 'evmSignTypedData', {\n path: params.path,\n data: params.data,\n }) as { signature: string; address?: string };\n\n return success({\n signature: ensure0x(result.signature),\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // BTC methods\n // ---------------------------------------------------------------------------\n\n async btcGetAddress(\n connectId: string,\n _deviceId: string,\n params: BtcGetAddressParams,\n ): Promise<Response<BtcAddress>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'btc'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'btcGetAddress', {\n path: params.path,\n coin: params.coin,\n showOnDevice: params.showOnDevice,\n scriptType: params.scriptType,\n }) as { address: string; path: string };\n\n return success({\n address: result.address,\n path: params.path,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async btcGetAddresses(\n connectId: string,\n deviceId: string,\n params: BtcGetAddressParams[],\n onProgress?: ProgressCallback,\n ): Promise<Response<BtcAddress[]>> {\n return this.batchCall(\n params,\n (p) => this.btcGetAddress(connectId, deviceId, p),\n onProgress,\n );\n }\n\n async btcGetPublicKey(\n connectId: string,\n _deviceId: string,\n params: BtcGetPublicKeyParams,\n ): Promise<Response<BtcPublicKey>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'btc'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'btcGetPublicKey', {\n path: params.path,\n coin: params.coin,\n showOnDevice: params.showOnDevice,\n }) as {\n xpub: string;\n publicKey: string;\n fingerprint: number;\n chainCode: string;\n path: string;\n depth: number;\n };\n\n return success({\n xpub: result.xpub,\n publicKey: result.publicKey ?? '',\n fingerprint: result.fingerprint ?? 0,\n chainCode: result.chainCode ?? '',\n path: params.path,\n depth: result.depth ?? 0,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async btcSignTransaction(\n connectId: string,\n _deviceId: string,\n params: BtcSignTxParams,\n ): Promise<Response<BtcSignedTx>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'btc'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n if (!params.psbt) {\n return failure(\n HardwareErrorCode.InvalidParams,\n 'Ledger requires PSBT format for BTC transaction signing. Provide params.psbt.',\n );\n }\n try {\n // Extract account-level path from the first input if available\n const accountPath = params.inputs?.[0]?.path\n ? params.inputs[0].path.split('/').slice(0, 3).join('/')\n : undefined;\n\n const result = await this.connectorCall(connectId, 'btcSignTransaction', {\n psbt: params.psbt,\n coin: params.coin,\n path: accountPath,\n }) as { signedPsbt: string };\n\n return success({\n signatures: [],\n serializedTx: result.signedPsbt,\n signedPsbt: result.signedPsbt,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async btcSignMessage(\n connectId: string,\n _deviceId: string,\n params: BtcSignMsgParams,\n ): Promise<Response<BtcSignature>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'btc'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'btcSignMessage', {\n path: params.path,\n message: params.message,\n coin: params.coin,\n }) as { signature: string; address: string };\n\n return success({\n signature: result.signature,\n address: result.address || '',\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Device fingerprint\n // ---------------------------------------------------------------------------\n\n async btcGetMasterFingerprint(\n connectId: string,\n _deviceId: string,\n ): Promise<Response<{ masterFingerprint: string }>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'btc'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'btcGetMasterFingerprint', {}) as {\n masterFingerprint: string;\n };\n\n return success({ masterFingerprint: result.masterFingerprint });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Solana methods\n // ---------------------------------------------------------------------------\n\n async solGetAddress(\n connectId: string,\n _deviceId: string,\n params: SolGetAddressParams,\n ): Promise<Response<SolAddress>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'sol'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'solGetAddress', {\n path: params.path,\n showOnDevice: params.showOnDevice,\n }) as { address: string; path: string };\n\n return success({\n address: result.address,\n path: params.path,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async solGetAddresses(\n connectId: string,\n deviceId: string,\n params: SolGetAddressParams[],\n onProgress?: ProgressCallback,\n ): Promise<Response<SolAddress[]>> {\n return this.batchCall(\n params,\n (p) => this.solGetAddress(connectId, deviceId, p),\n onProgress,\n );\n }\n\n async solGetPublicKey(\n connectId: string,\n _deviceId: string,\n params: SolGetPublicKeyParams,\n ): Promise<Response<SolPublicKey>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'sol'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n // Solana uses Ed25519 — the public key IS the address (base58 encoded)\n const result = await this.connectorCall(connectId, 'solGetAddress', {\n path: params.path,\n showOnDevice: params.showOnDevice,\n }) as { address: string; path: string };\n\n return success({\n publicKey: result.address,\n path: params.path,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async solSignTransaction(\n connectId: string,\n _deviceId: string,\n params: SolSignTxParams,\n ): Promise<Response<SolSignedTx>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'sol'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'solSignTransaction', {\n path: params.path,\n serializedTx: params.serializedTx,\n }) as { signature: string };\n\n return success({ signature: result.signature });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async solSignMessage(\n connectId: string,\n _deviceId: string,\n params: SolSignMsgParams,\n ): Promise<Response<SolSignature>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n if (!(await this._verifyDeviceFingerprint(connectId, _deviceId, 'sol'))) {\n return failure(HardwareErrorCode.DeviceMismatch, 'Wrong device connected');\n }\n try {\n const result = await this.connectorCall(connectId, 'solSignMessage', {\n path: params.path,\n message: params.message,\n }) as { signature: string };\n\n return success({ signature: result.signature });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // TRON methods\n // ---------------------------------------------------------------------------\n\n async tronGetAddress(\n connectId: string,\n _deviceId: string,\n params: TronGetAddressParams,\n ): Promise<Response<TronAddress>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n try {\n const result = await this.connectorCall(connectId, 'tronGetAddress', {\n path: params.path,\n showOnDevice: params.showOnDevice,\n }) as { address: string; publicKey: string; path: string };\n\n return success({\n address: result.address,\n path: params.path,\n });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async tronGetAddresses(\n connectId: string,\n deviceId: string,\n params: TronGetAddressParams[],\n onProgress?: ProgressCallback,\n ): Promise<Response<TronAddress[]>> {\n return this.batchCall(\n params,\n (p) => this.tronGetAddress(connectId, deviceId, p),\n onProgress,\n );\n }\n\n async tronSignTransaction(\n connectId: string,\n _deviceId: string,\n params: TronSignTxParams,\n ): Promise<Response<TronSignedTx>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n try {\n if (!params.rawTxHex) {\n return failure(\n HardwareErrorCode.InvalidParams,\n 'TRON signing requires a protobuf-encoded raw transaction hex (rawTxHex).',\n );\n }\n\n const result = await this.connectorCall(connectId, 'tronSignTransaction', {\n path: params.path,\n rawTxHex: params.rawTxHex,\n }) as { signature: string };\n\n return success({ signature: result.signature });\n } catch (err) {\n return this.errorToFailure(err);\n }\n }\n\n async tronSignMessage(\n connectId: string,\n _deviceId: string,\n params: TronSignMsgParams,\n ): Promise<Response<TronSignature>> {\n await this._ensureDevicePermission(connectId, _deviceId);\n try {\n const result = await this.connectorCall(connectId, 'tronSignMessage', {\n path: params.path,\n messageHex: params.message,\n }) as { signature: string };\n\n return success({ signature: result.signature });\n } catch (err) {\n return this.errorToFailure(err);\n }\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 // Pending device-connect resolve — set by _waitForDeviceConnect, resolved by uiResponse\n private _deviceConnectResolve: ((cancelled: boolean) => void) | null = null;\n\n // Mutex for ensureConnected — prevents concurrent calls from establishing duplicate connections\n private _connectingPromise: Promise<string> | null = null;\n\n private static readonly DEVICE_CONNECT_TIMEOUT_MS = 60_000;\n\n /**\n * Wait for user to connect and unlock device.\n * Emits 'ui-request' event via the adapter's own emitter.\n * The consumer (monorepo adapter wrapper) listens for this and shows UI.\n * When user confirms, they call adapter.deviceConnectResponse() which resolves this promise.\n * Times out after 60 seconds if no response is received.\n */\n private _waitForDeviceConnect(attempt: number): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n this._deviceConnectResolve = null;\n reject(new Error('Ledger device connect timed out after 60 seconds'));\n }\n }, LedgerAdapter.DEVICE_CONNECT_TIMEOUT_MS);\n\n this._deviceConnectResolve = (cancelled: boolean) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n this._deviceConnectResolve = null;\n if (cancelled) {\n reject(Object.assign(\n new Error('User cancelled Ledger connection'),\n { _tag: 'DeviceNotRecognizedError' },\n ));\n } else {\n resolve();\n }\n };\n\n // Emit ui-request event — consumer should show \"connect and unlock\" prompt\n this.emitter.emit('ui-request-device-connect' as any, {\n type: 'ui-request-device-connect',\n payload: {\n message: 'Please connect and unlock your Ledger device',\n retryCount: attempt,\n maxRetries: LedgerAdapter.MAX_DEVICE_RETRY,\n },\n });\n });\n }\n\n /**\n * Called by consumer to respond to ui-request-device-connect.\n * type='confirm' → retry search, type='cancel' → abort.\n */\n deviceConnectResponse(type: 'confirm' | 'cancel'): void {\n if (this._deviceConnectResolve) {\n this._deviceConnectResolve(type === 'cancel');\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 return this._sessions.keys().next().value!;\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(attempt + 1);\n }\n }\n\n throw Object.assign(\n new Error('No Ledger device found after multiple attempts. Please connect and unlock your device.'),\n { _tag: 'DeviceNotRecognizedError' },\n );\n }\n\n private async _connectFirstOrSelect(devices: DeviceInfo[]): Promise<string> {\n if (devices.length === 1) {\n const result = await this.connectDevice(devices[0].connectId);\n if (!result.success) {\n throw Object.assign(\n new Error(result.payload.error),\n { _tag: 'DeviceNotRecognizedError' },\n );\n }\n return devices[0].connectId;\n }\n\n // Multiple devices — ask user via UI handler\n if (this._uiHandler?.onSelectDevice) {\n const selectedConnectId = await this._uiHandler.onSelectDevice(devices);\n const result = await this.connectDevice(selectedConnectId);\n if (!result.success) {\n throw Object.assign(\n new Error(result.payload.error),\n { _tag: 'DeviceNotRecognizedError' },\n );\n }\n return selectedConnectId;\n }\n\n // No UI handler — fall back to first device\n const result = await this.connectDevice(devices[0].connectId);\n if (!result.success) {\n throw Object.assign(\n new Error(result.payload.error),\n { _tag: 'DeviceNotRecognizedError' },\n );\n }\n return devices[0].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 ): Promise<unknown> {\n const resolvedConnectId = await this.ensureConnected(connectId);\n const sessionId = this._sessions.get(resolvedConnectId);\n if (!sessionId) {\n throw Object.assign(\n new Error('Auto-connect succeeded but no session found'),\n { _tag: 'DeviceSessionNotFound' },\n );\n }\n\n try {\n return await this.connector.call(sessionId, method, params);\n } catch (err) {\n if (isDeviceDisconnectedError(err)) {\n // Clear stale session and retry with fresh connection\n this._sessions.delete(resolvedConnectId);\n this._discoveredDevices.clear();\n const retryConnectId = await this.ensureConnected();\n const retrySessionId = this._sessions.get(retryConnectId);\n if (!retrySessionId) {\n throw err;\n }\n return this.connector.call(retrySessionId, method, params);\n }\n throw err;\n }\n }\n\n /**\n * Ensure device permission before proceeding.\n * - No connectId (searchDevices): check environment-level permission\n * - With connectId (business methods): check device-level permission\n * If not granted, calls onDevicePermission so the consumer can request access.\n */\n private async _ensureDevicePermission(connectId?: string, deviceId?: string): Promise<void> {\n const transportType: TransportType = 'hid';\n let granted = false;\n let context: Record<string, unknown> | undefined;\n\n if (this._uiHandler?.checkDevicePermission) {\n try {\n const result = await this._uiHandler.checkDevicePermission({ transportType, connectId, deviceId });\n granted = result.granted;\n context = result.context;\n } catch {\n granted = false;\n }\n }\n\n if (!granted) {\n try {\n await this._uiHandler?.onDevicePermission?.({ transportType, context });\n } catch {\n // UI handler cancelled or failed\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 console.error('[LedgerAdapter] error:', err);\n const mapped = mapLedgerError(err);\n\n // Emit a UI event for locked-device so callers can prompt the user\n if (mapped.code === HardwareErrorCode.DeviceLocked) {\n this.emitter.emit(UI_REQUEST.REQUEST_BUTTON, {\n type: UI_REQUEST.REQUEST_BUTTON,\n payload: {\n device: this.unknownDevice(),\n code: 'ButtonRequest_Other',\n },\n });\n }\n\n return failure(mapped.code, mapped.message);\n }\n\n /**\n * Generic batch call with progress reporting.\n * If any single call fails, returns the failure immediately.\n */\n private async batchCall<TParam, TResult>(\n params: TParam[],\n callFn: (p: TParam) => Promise<Response<TResult>>,\n onProgress?: ProgressCallback,\n ): Promise<Response<TResult[]>> {\n const results: TResult[] = [];\n for (let i = 0; i < params.length; i++) {\n const result = await callFn(params[i]);\n if (!result.success) {\n return result;\n }\n results.push(result.payload);\n onProgress?.({ index: i, total: params.length });\n }\n return success(results);\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 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\n ? this.extractDeviceInfoFromPayload(payload)\n : 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 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: 'usb' as ConnectionType,\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 } from '@bytezhang/hardware-wallet-core';\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 */\nconst WRONG_APP_CODES = new Set(['6e00', '28160', '6d00', '27904']);\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 (typeof e.message === 'string' && /locked|device exchange error/i.test(e.message)) 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' && /wrong app|open the .* app|CLA not supported/i.test(e.message)) return true;\n if (hasStatusCode(err, WRONG_APP_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' && /disconnected|not found|no device|unplugged|session.*not.*found|timed out.*locked/i.test(e.message)) return true;\n return false;\n}\n\n/** Check for timeout errors. */\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.message === 'string' && /timeout|timed?\\s*out/i.test(e.message)) return true;\n if (e._tag === 'DeviceExchangeTimeoutError') 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): { code: HardwareErrorCode; message: string } {\n // Order matters: check more specific errors first\n\n if (isDeviceLockedError(err)) {\n return {\n code: HardwareErrorCode.DeviceLocked,\n message: 'Device is locked. Please unlock your Ledger device and try again.',\n };\n }\n\n if (isUserRejectedError(err)) {\n return {\n code: HardwareErrorCode.UserRejected,\n message: 'User rejected the request on the device.',\n };\n }\n\n if (isWrongAppError(err)) {\n return {\n code: HardwareErrorCode.WrongApp,\n message: 'Wrong app is open on the Ledger device. Please open the correct app (e.g. Ethereum) and try again.',\n };\n }\n\n if (isDeviceDisconnectedError(err)) {\n return {\n code: HardwareErrorCode.DeviceDisconnected,\n message: 'Ledger device was disconnected. Please reconnect the device and try again.',\n };\n }\n\n if (isTimeoutError(err)) {\n return {\n code: HardwareErrorCode.OperationTimeout,\n message: 'Operation timed out. Please ensure the Ledger device is connected and responsive.',\n };\n }\n\n // Fallback: extract whatever message we can\n let message = 'Unknown Ledger error';\n if (err instanceof Error) {\n message = err.message;\n } else if (err && typeof err === 'object') {\n const e = err as Record<string, unknown>;\n message = String(e.message ?? e._tag ?? e.type ?? JSON.stringify(err));\n }\n return { code: HardwareErrorCode.UnknownError, message };\n}\n","import type { DeviceDescriptor, DeviceChangeEvent } from '@bytezhang/hardware-wallet-core';\nimport type { IDmk, 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: IDmk;\n private readonly _discovered = new Map<string, DmkDiscoveredDevice>();\n private readonly _sessions = new Map<string, string>(); // deviceId → sessionId\n private readonly _sessionToDevice = new Map<string, string>(); // sessionId → deviceId\n private _listenSub: { unsubscribe: () => void } | null = null;\n\n constructor(dmk: IDmk) {\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 return new Promise<DeviceDescriptor[]>((resolve) => {\n let resolved = false;\n // BehaviorSubject fires next synchronously during subscribe(),\n // so 'sub' is not yet assigned when the callback runs.\n // Capture result synchronously, unsubscribe after assignment.\n let syncResult: { id: string; deviceModel: { id: string }; [k: string]: unknown }[] | 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 // Log raw DMK discovery data — everything the SDK returns\n console.log('[DMK] enumerate raw devices:', JSON.stringify(devices.map(d => ({\n id: d.id,\n deviceModel: d.deviceModel,\n transport: (d as any).transport,\n name: (d as any).name,\n rssi: (d as any).rssi,\n // Dump all keys to see what else is available\n _keys: Object.keys(d),\n }))));\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(devices.map(d => ({\n path: d.id,\n type: d.deviceModel.id,\n name: (d as any).name,\n transport: (d as any).transport,\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 { id: string; deviceModel: { id: string }; name?: string; transport?: string }[];\n resolve(devices.map(d => ({\n path: d.id,\n type: d.deviceModel.id,\n name: (d as any).name,\n transport: (d as any).transport,\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 console.log('[DMK] listen device:', JSON.stringify({\n id: d.id,\n deviceModel: d.deviceModel,\n name: (d as any).name,\n }));\n if (!previousIds.has(d.id)) {\n onChange({ type: 'device-connected', descriptor: {\n path: d.id,\n type: d.deviceModel.id,\n name: (d as any).name,\n transport: (d as any).transport,\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 requestDevice(timeoutMs = 3000): Promise<void> {\n return new Promise<void>((resolve) => {\n const sub = this._dmk.startDiscovering().subscribe({\n next: (d) => { this._discovered.set(d.id, d); },\n error: () => { sub.unsubscribe(); resolve(); },\n });\n setTimeout(() => {\n sub.unsubscribe();\n this._dmk.stopDiscovering();\n resolve();\n }, timeoutMs);\n });\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(): IDmk {\n return this._dmk;\n }\n\n dispose(): void {\n this.stopListening();\n this._discovered.clear();\n this._sessions.clear();\n this._sessionToDevice.clear();\n this._dmk.close?.();\n }\n}\n","/** DeviceAction state emitted by DMK signer operations. */\ninterface DeviceActionState<T> {\n status: 'pending' | 'completed' | 'error';\n output?: T;\n error?: unknown;\n intermediateValue?: {\n requiredUserInteraction?: string;\n [key: string]: unknown;\n };\n}\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 * @param timeoutMs Timeout in ms. Resets each time the Observable emits (device is alive).\n * Pass 0 to disable. Default: 30s.\n */\nexport function deviceActionToPromise<T>(\n action: {\n observable: {\n subscribe(observer: {\n next: (value: DeviceActionState<T>) => void;\n error?: (err: unknown) => void;\n complete?: () => void;\n }): { unsubscribe: () => void };\n };\n },\n onInteraction?: (interaction: string) => void,\n timeoutMs: number = DEFAULT_TIMEOUT_MS,\n): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n let settled = false;\n let sub: { unsubscribe: () => void };\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n const resetTimer = () => {\n if (timer) clearTimeout(timer);\n if (timeoutMs > 0) {\n timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n sub?.unsubscribe();\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 console.log('[DMK-Observable] subscribing to action.observable...');\n sub = action.observable.subscribe({\n next: (state) => {\n console.log('[DMK-Observable] next received');\n // Device is alive — reset timeout\n resetTimer();\n\n console.log('[DMK-Observable] state:', JSON.stringify({\n status: state.status,\n interaction: state.intermediateValue?.requiredUserInteraction,\n intermediateValue: state.intermediateValue,\n hasOutput: !!state.output,\n hasError: !!state.error,\n }));\n if (settled) return;\n if (state.status === 'completed') {\n settled = true;\n if (timer) clearTimeout(timer);\n onInteraction?.('interaction-complete');\n sub?.unsubscribe();\n resolve(state.output as T);\n } else if (state.status === 'error') {\n settled = true;\n if (timer) clearTimeout(timer);\n onInteraction?.('interaction-complete');\n sub?.unsubscribe();\n reject(state.error);\n } else if (state.status === 'pending' && onInteraction) {\n const interaction = state.intermediateValue?.requiredUserInteraction;\n if (interaction && interaction !== 'none') {\n onInteraction(interaction);\n } else if (interaction === 'none') {\n onInteraction('interaction-complete');\n }\n }\n },\n error: (err: unknown) => {\n if (!settled) {\n settled = true;\n if (timer) clearTimeout(timer);\n sub?.unsubscribe();\n reject(err);\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","import type { SignerEvmAddress, SignerEvmSignature } from '../types';\nimport { deviceActionToPromise } from './deviceActionToPromise';\n\n/**\n * SDK signer interface — duck-typed to avoid hard dependency on\n * @ledgerhq/device-signer-kit-ethereum.\n */\nexport interface ISdkSignerEth {\n getAddress(derivationPath: string, options?: { checkOnDevice?: boolean }): unknown;\n signTransaction(derivationPath: string, transaction: Uint8Array, options?: unknown): unknown;\n signMessage(derivationPath: string, message: string): unknown;\n signTypedData(derivationPath: string, data: unknown): unknown;\n}\n\n/** Convert hex string (with or without 0x) to Uint8Array. */\nfunction hexToBytes(hex: string): Uint8Array {\n const h = hex.startsWith('0x') ? hex.slice(2) : hex;\n const bytes = new Uint8Array(h.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(h.substring(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\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 constructor(private readonly _sdk: ISdkSignerEth) {}\n\n async getAddress(\n derivationPath: string,\n options?: { checkOnDevice?: boolean }\n ): Promise<SignerEvmAddress> {\n const checkOnDevice = options?.checkOnDevice ?? false;\n console.log('[DMK] getAddress → DMK:', { derivationPath, checkOnDevice });\n console.log('[DMK] signer instance id:', (this as any)._instanceId ?? 'none');\n const action = this._sdk.getAddress(derivationPath, {\n checkOnDevice,\n });\n console.log('[DMK] getAddress action created:', !!action, 'hasObservable:', !!(action as any)?.observable);\n // checkOnDevice needs user interaction → long timeout; otherwise default 30s\n const timeout = checkOnDevice ? INTERACTIVE_TIMEOUT_MS : undefined;\n return deviceActionToPromise<SignerEvmAddress>(action as any, this.onInteraction, timeout);\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>(action as any, this.onInteraction, INTERACTIVE_TIMEOUT_MS);\n }\n\n async signMessage(derivationPath: string, message: string): Promise<SignerEvmSignature> {\n const action = this._sdk.signMessage(derivationPath, message);\n return deviceActionToPromise<SignerEvmSignature>(action as any, this.onInteraction, INTERACTIVE_TIMEOUT_MS);\n }\n\n async signTypedData(derivationPath: string, data: unknown): Promise<SignerEvmSignature> {\n const action = this._sdk.signTypedData(derivationPath, data);\n return deviceActionToPromise<SignerEvmSignature>(action as any, this.onInteraction, INTERACTIVE_TIMEOUT_MS);\n }\n}\n","import type { IDmk } from '../types';\nimport { SignerEth } from './SignerEth';\n\ntype SignerEthBuilderFn = (args: { dmk: IDmk; sessionId: string }) => { build(): unknown } | Promise<{ build(): unknown }>;\n\n/**\n * Manages per-sessionId SignerEth instances.\n * Creates on demand, caches for reuse, invalidates on session change.\n */\nexport class SignerManager {\n private readonly _cache = new Map<string, SignerEth>();\n private readonly _dmk: IDmk;\n private readonly _builderFn: SignerEthBuilderFn;\n\n constructor(dmk: IDmk, builderFn?: SignerEthBuilderFn) {\n this._dmk = dmk;\n this._builderFn = builderFn ?? SignerManager._defaultBuilder();\n }\n\n async getOrCreate(sessionId: string): Promise<SignerEth> {\n const hadCached = this._cache.has(sessionId);\n // Always create a fresh signer — DMK signers may maintain internal DeviceAction\n // state that can prevent subsequent operations if reused.\n this._cache.delete(sessionId);\n\n console.log('[DMK] SignerManager.getOrCreate:', { sessionId, hadCached, creating: true });\n const builder = await this._builderFn({ dmk: this._dmk, sessionId });\n const sdkSigner = builder.build();\n console.log('[DMK] SignerManager: new signer built');\n const signer = new SignerEth(sdkSigner as any);\n this._cache.set(sessionId, signer);\n return signer;\n }\n\n invalidate(sessionId: string): void {\n this._cache.delete(sessionId);\n }\n\n clearAll(): void {\n this._cache.clear();\n }\n\n private static _defaultBuilder(): SignerEthBuilderFn {\n let BuilderClass: any = null;\n return async (args) => {\n if (!BuilderClass) {\n const mod = await import('@ledgerhq/device-signer-kit-ethereum');\n BuilderClass = mod.SignerEthBuilder;\n }\n return new BuilderClass(args);\n };\n }\n}\n","import type { SignerBtcAddress } from '../types';\nimport { deviceActionToPromise } from './deviceActionToPromise';\n\n/**\n * SDK BTC signer interface — duck-typed to avoid hard dependency on\n * @ledgerhq/device-signer-kit-bitcoin.\n */\nexport interface ISdkSignerBtc {\n getExtendedPublicKey(derivationPath: string, options?: { checkOnDevice?: boolean }): unknown;\n getWalletAddress(wallet: unknown, addressIndex: number, options?: { checkOnDevice?: boolean; change?: boolean }): unknown;\n getMasterFingerprint(options?: { skipOpenApp?: boolean }): unknown;\n signPsbt(wallet: unknown, psbt: unknown, options?: unknown): unknown;\n signTransaction(wallet: unknown, psbt: unknown, options?: unknown): unknown;\n signMessage(derivationPath: string, message: string, options?: unknown): unknown;\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 constructor(private readonly _sdk: ISdkSignerBtc) {}\n\n async getWalletAddress(\n wallet: unknown,\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>(action as any, this.onInteraction);\n }\n\n async getExtendedPublicKey(\n derivationPath: string,\n options?: { checkOnDevice?: boolean },\n ): Promise<string> {\n const action = this._sdk.getExtendedPublicKey(derivationPath, {\n checkOnDevice: options?.checkOnDevice ?? false,\n });\n return deviceActionToPromise<string>(action as any, this.onInteraction);\n }\n\n async getMasterFingerprint(\n options?: { skipOpenApp?: boolean },\n ): Promise<Uint8Array> {\n const action = this._sdk.getMasterFingerprint(options);\n const result = await deviceActionToPromise<{ masterFingerprint: Uint8Array }>(action as any, this.onInteraction);\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(\n wallet: unknown,\n psbt: unknown,\n options?: unknown,\n ): Promise<unknown[]> {\n const action = this._sdk.signPsbt(wallet, psbt, options);\n return deviceActionToPromise<unknown[]>(action as any, this.onInteraction, INTERACTIVE_TIMEOUT_MS);\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: unknown,\n psbt: unknown,\n options?: unknown,\n ): Promise<string> {\n const action = this._sdk.signTransaction(wallet, psbt, options);\n return deviceActionToPromise<string>(action as any, this.onInteraction, INTERACTIVE_TIMEOUT_MS);\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?: unknown,\n ): Promise<{ r: string; s: string; v: number }> {\n const action = this._sdk.signMessage(derivationPath, message, options);\n return deviceActionToPromise<{ r: string; s: string; v: number }>(action as any, this.onInteraction, INTERACTIVE_TIMEOUT_MS);\n }\n}\n","import { deviceActionToPromise } from './deviceActionToPromise';\n\n/**\n * SDK SOL signer interface — duck-typed to avoid hard dependency on\n * @ledgerhq/device-signer-kit-solana.\n */\nexport interface ISdkSignerSol {\n getAddress(derivationPath: string, options?: { checkOnDevice?: boolean }): unknown;\n signTransaction(derivationPath: string, transaction: Uint8Array, options?: unknown): unknown;\n signMessage(derivationPath: string, message: string | Uint8Array, options?: unknown): unknown;\n}\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 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(\n derivationPath: string,\n options?: { checkOnDevice?: boolean },\n ): Promise<string> {\n const action = this._sdk.getAddress(derivationPath, {\n checkOnDevice: options?.checkOnDevice ?? false,\n });\n return deviceActionToPromise<string>(action as any, this.onInteraction);\n }\n\n /**\n * Sign a Solana transaction.\n */\n async signTransaction(\n derivationPath: string,\n transaction: Uint8Array,\n options?: unknown,\n ): Promise<Uint8Array> {\n const action = this._sdk.signTransaction(derivationPath, transaction, options);\n return deviceActionToPromise<Uint8Array>(action as any, this.onInteraction);\n }\n\n /**\n * Sign a message with the Solana app.\n */\n async signMessage(\n derivationPath: string,\n message: string | Uint8Array,\n options?: unknown,\n ): Promise<Uint8Array> {\n const action = this._sdk.signMessage(derivationPath, message, options);\n return deviceActionToPromise<Uint8Array>(action as any, this.onInteraction);\n }\n}\n","/**\n * TRON Ledger signer — sends raw APDUs to the TRON app on the Ledger device.\n *\n * Unlike EVM/BTC/SOL which have dedicated DMK signer kits,\n * TRON requires direct APDU communication. This class builds and sends\n * the APDU packets according to the TRON Ledger app protocol.\n *\n * APDU Protocol Reference (Ledger hw-app-trx / PR #1284):\n * CLA = 0xE0\n * INS_ADDRESS = 0x02\n * INS_SIGN = 0x04\n * INS_VERSION = 0x06\n * INS_SIGN_MESSAGE = 0x08\n * CHUNK_SIZE = 250\n */\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst CLA = 0xe0;\nconst INS_ADDRESS = 0x02;\nconst INS_SIGN = 0x04;\nconst INS_SIGN_MESSAGE = 0x08;\nconst CHUNK_SIZE = 250;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Function to send a raw APDU to the Ledger device and receive the response.\n *\n * The raw APDU is `[CLA, INS, P1, P2, Lc, ...data]`.\n * The response is `{ statusCode: Uint8Array (2 bytes), data: Uint8Array }`.\n */\nexport type SendApduFn = (\n rawApdu: Uint8Array,\n) => Promise<{ statusCode: Uint8Array; data: Uint8Array }>;\n\nexport interface TronAddressResult {\n publicKey: string;\n address: string;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Convert hex string (with or without 0x) to Uint8Array. */\nfunction hexToBytes(hex: string): Uint8Array {\n const h = hex.startsWith('0x') ? hex.slice(2) : hex;\n const bytes = new Uint8Array(h.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(h.substring(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\n/** Convert Uint8Array to hex string (no 0x prefix). */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * Split a BIP-44 derivation path string into an array of 4-byte big-endian integers.\n * e.g. \"m/44'/195'/0'/0/0\" → [0x8000002C, 0x800000C3, 0x80000000, 0, 0]\n */\nfunction splitPath(path: string): number[] {\n const p = path.startsWith('m/') ? path.slice(2) : path;\n return p.split('/').map((component) => {\n const hardened = component.endsWith(\"'\");\n const index = parseInt(hardened ? component.slice(0, -1) : component, 10);\n return hardened ? index + 0x80000000 : index;\n });\n}\n\n/**\n * Serialize derivation path components into bytes:\n * pathCount (1 byte) + each component (4 bytes big-endian)\n */\nfunction serializePath(path: string): Uint8Array {\n const components = splitPath(path);\n const buf = new Uint8Array(1 + components.length * 4);\n buf[0] = components.length;\n for (let i = 0; i < components.length; i++) {\n const val = components[i];\n const offset = 1 + i * 4;\n buf[offset] = (val >>> 24) & 0xff;\n buf[offset + 1] = (val >>> 16) & 0xff;\n buf[offset + 2] = (val >>> 8) & 0xff;\n buf[offset + 3] = val & 0xff;\n }\n return buf;\n}\n\n/**\n * Build a raw APDU packet: [CLA, INS, P1, P2, Lc, ...data]\n */\nfunction buildApdu(\n cla: number,\n ins: number,\n p1: number,\n p2: number,\n data?: Uint8Array,\n): Uint8Array {\n const dataLen = data?.length ?? 0;\n const apdu = new Uint8Array(5 + dataLen);\n apdu[0] = cla;\n apdu[1] = ins;\n apdu[2] = p1;\n apdu[3] = p2;\n apdu[4] = dataLen;\n if (data && dataLen > 0) {\n apdu.set(data, 5);\n }\n return apdu;\n}\n\n/**\n * Check that the APDU response has a success status (0x9000).\n * Throws an error with the status code if not.\n */\nfunction checkStatusCode(statusCode: Uint8Array, context: string): void {\n if (statusCode.length < 2) {\n throw new Error(`${context}: invalid status code length`);\n }\n const sw = (statusCode[0] << 8) | statusCode[1];\n if (sw !== 0x9000) {\n throw Object.assign(\n new Error(`${context}: device returned error status 0x${sw.toString(16).padStart(4, '0')}`),\n { statusCode: sw.toString(16), errorCode: sw.toString() },\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// SignerTron\n// ---------------------------------------------------------------------------\n\n/**\n * TRON signer that communicates with the Ledger TRON app via raw APDUs.\n *\n * Implements getAddress, signTransaction, and signMessage using the\n * APDU protocol described in the Ledger TRON app documentation.\n */\nexport class SignerTron {\n constructor(private readonly _sendApdu: SendApduFn) {}\n\n /**\n * Get the TRON address at the given derivation path.\n *\n * APDU: CLA=0xE0, INS=0x02, P1=(showOnDevice?0x01:0x00), P2=0x00\n * Data: pathCount(1) + paths(4 bytes each, big-endian, hardened bit)\n * Response: pubKeyLen(1) + pubKey(pubKeyLen) + addrLen(1) + addr(addrLen, ASCII base58)\n */\n async getAddress(\n path: string,\n options?: { checkOnDevice?: boolean },\n ): Promise<TronAddressResult> {\n const showOnDevice = options?.checkOnDevice ?? false;\n const pathData = serializePath(path);\n\n const apdu = buildApdu(\n CLA,\n INS_ADDRESS,\n showOnDevice ? 0x01 : 0x00,\n 0x00,\n pathData,\n );\n\n const response = await this._sendApdu(apdu);\n checkStatusCode(response.statusCode, 'tronGetAddress');\n\n const data = response.data;\n let offset = 0;\n\n // Parse public key\n const pubKeyLen = data[offset];\n offset += 1;\n const publicKey = bytesToHex(data.slice(offset, offset + pubKeyLen));\n offset += pubKeyLen;\n\n // Parse address (ASCII base58)\n const addrLen = data[offset];\n offset += 1;\n const addressBytes = data.slice(offset, offset + addrLen);\n const address = new TextDecoder().decode(addressBytes);\n\n return { publicKey, address };\n }\n\n /**\n * Sign a TRON transaction (protobuf-encoded raw transaction).\n *\n * The transaction bytes are split into 250-byte chunks and sent sequentially.\n * First chunk includes the serialized derivation path prefix.\n *\n * P1 flags:\n * 0x10 = single chunk (entire tx fits in one APDU)\n * 0x00 = first chunk of multi-chunk\n * 0x80 = middle chunk (continuation)\n * 0x90 = last chunk (final continuation)\n *\n * Returns: 65-byte signature as hex string (no 0x prefix).\n */\n async signTransaction(path: string, rawTxHex: string): Promise<string> {\n const pathData = serializePath(path);\n const txBytes = hexToBytes(rawTxHex);\n\n // First chunk payload: path data + as many tx bytes as fit\n const firstChunkMaxTx = CHUNK_SIZE - pathData.length;\n const txForFirst = txBytes.slice(0, firstChunkMaxTx);\n const firstPayload = new Uint8Array(pathData.length + txForFirst.length);\n firstPayload.set(pathData, 0);\n firstPayload.set(txForFirst, pathData.length);\n\n const remaining = txBytes.slice(firstChunkMaxTx);\n\n // Build continuation chunks from remaining bytes\n const chunks: Uint8Array[] = [];\n let pos = 0;\n while (pos < remaining.length) {\n chunks.push(remaining.slice(pos, pos + CHUNK_SIZE));\n pos += CHUNK_SIZE;\n }\n\n const totalChunks = 1 + chunks.length;\n let response: { statusCode: Uint8Array; data: Uint8Array };\n\n if (totalChunks === 1) {\n // Single chunk: P1 = 0x10\n const apdu = buildApdu(CLA, INS_SIGN, 0x10, 0x00, firstPayload);\n response = await this._sendApdu(apdu);\n checkStatusCode(response.statusCode, 'tronSignTransaction');\n } else {\n // First chunk: P1 = 0x00\n const firstApdu = buildApdu(CLA, INS_SIGN, 0x00, 0x00, firstPayload);\n response = await this._sendApdu(firstApdu);\n checkStatusCode(response.statusCode, 'tronSignTransaction (first)');\n\n // Middle/last chunks\n for (let i = 0; i < chunks.length; i++) {\n const isLast = i === chunks.length - 1;\n const p1 = isLast ? 0x90 : 0x80;\n const apdu = buildApdu(CLA, INS_SIGN, p1, 0x00, chunks[i]);\n response = await this._sendApdu(apdu);\n checkStatusCode(response.statusCode, `tronSignTransaction (chunk ${i + 1})`);\n }\n }\n\n // Response from the last APDU: 65-byte signature\n return bytesToHex(response.data.slice(0, 65));\n }\n\n /**\n * Sign a personal message with the TRON app.\n *\n * First chunk: pathCount(1) + paths(4 bytes BE) + messageLength(4 bytes BE) + message bytes\n * Subsequent: continuation bytes\n * P1: 0x00 = first, 0x80 = continuation\n *\n * Returns: 65-byte signature as hex string (no 0x prefix).\n */\n async signMessage(path: string, messageHex: string): Promise<string> {\n const pathData = serializePath(path);\n const messageBytes = hexToBytes(messageHex);\n\n // Message length as 4 bytes big-endian\n const msgLenBuf = new Uint8Array(4);\n const msgLen = messageBytes.length;\n msgLenBuf[0] = (msgLen >>> 24) & 0xff;\n msgLenBuf[1] = (msgLen >>> 16) & 0xff;\n msgLenBuf[2] = (msgLen >>> 8) & 0xff;\n msgLenBuf[3] = msgLen & 0xff;\n\n // First chunk header: path + message length\n const header = new Uint8Array(pathData.length + 4);\n header.set(pathData, 0);\n header.set(msgLenBuf, pathData.length);\n\n // First chunk payload: header + as many message bytes as fit\n const firstChunkMaxMsg = CHUNK_SIZE - header.length;\n const msgForFirst = messageBytes.slice(0, firstChunkMaxMsg);\n const firstPayload = new Uint8Array(header.length + msgForFirst.length);\n firstPayload.set(header, 0);\n firstPayload.set(msgForFirst, header.length);\n\n const remaining = messageBytes.slice(firstChunkMaxMsg);\n\n // Build continuation chunks\n const chunks: Uint8Array[] = [];\n let pos = 0;\n while (pos < remaining.length) {\n chunks.push(remaining.slice(pos, pos + CHUNK_SIZE));\n pos += CHUNK_SIZE;\n }\n\n let response: { statusCode: Uint8Array; data: Uint8Array };\n\n // First chunk: P1 = 0x00\n const firstApdu = buildApdu(CLA, INS_SIGN_MESSAGE, 0x00, 0x00, firstPayload);\n response = await this._sendApdu(firstApdu);\n checkStatusCode(response.statusCode, 'tronSignMessage (first)');\n\n // Continuation chunks: P1 = 0x80\n for (let i = 0; i < chunks.length; i++) {\n const apdu = buildApdu(CLA, INS_SIGN_MESSAGE, 0x80, 0x00, chunks[i]);\n response = await this._sendApdu(apdu);\n checkStatusCode(response.statusCode, `tronSignMessage (chunk ${i + 1})`);\n }\n\n // Response from the last APDU: 65-byte signature\n return bytesToHex(response.data.slice(0, 65));\n }\n}\n","import type {\n IConnector,\n ConnectorDevice,\n ConnectorSession,\n ConnectorEventType,\n ConnectorEventMap,\n ConnectionType,\n DeviceDescriptor,\n} from '@bytezhang/hardware-wallet-core';\nimport type { IDmk, SignerEvmSignature } from '../types';\nimport { LedgerDeviceManager } from '../device/LedgerDeviceManager';\nimport { SignerManager } from '../signer/SignerManager';\nimport { SignerBtc } from '../signer/SignerBtc';\nimport { SignerSol } from '../signer/SignerSol';\nimport { SignerTron } from '../signer/SignerTron';\nimport { mapLedgerError } from '../errors';\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?: IDmk;\n}\n\n// ---------------------------------------------------------------------------\n// Internal types — call params\n// ---------------------------------------------------------------------------\n\ntype EventHandler<K extends ConnectorEventType> = (\n data: ConnectorEventMap[K],\n) => void;\n\n/** Parameters for evmGetAddress */\ninterface EvmGetAddressCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\n/** Parameters for evmSignTransaction */\ninterface EvmSignTransactionCallParams {\n path: string;\n /** RLP-serialized transaction hex (0x-prefixed or plain) */\n serializedTx: string;\n}\n\n/** Parameters for evmSignMessage */\ninterface EvmSignMessageCallParams {\n path: string;\n message: string;\n}\n\n/** Parameters for evmSignTypedData */\ninterface EvmSignTypedDataCallParams {\n path: string;\n data: unknown;\n}\n\n/** Parameters for btcGetAddress */\ninterface BtcGetAddressCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\n/** Parameters for btcGetPublicKey */\ninterface BtcGetPublicKeyCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\n/** Parameters for btcSignTransaction */\ninterface 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\n/** Parameters for btcSignMessage */\ninterface BtcSignMessageCallParams {\n path: string;\n message: string;\n coin?: string;\n}\n\n/** Parameters for solGetAddress */\ninterface SolGetAddressCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\n/** Parameters for solSignTransaction */\ninterface SolSignTransactionCallParams {\n path: string;\n /** Hex-encoded serialized transaction bytes (no 0x prefix) */\n serializedTx: string;\n}\n\n/** Parameters for solSignMessage */\ninterface SolSignMessageCallParams {\n path: string;\n /** Message bytes as hex string (no 0x prefix) */\n message: string;\n}\n\n/** Parameters for tronGetAddress */\ninterface TronGetAddressCallParams {\n path: string;\n showOnDevice?: boolean;\n}\n\n/** Parameters for tronSignTransaction */\ninterface TronSignTransactionCallParams {\n path: string;\n /** Protobuf-encoded raw transaction hex (no 0x prefix) */\n rawTxHex: string;\n}\n\n/** Parameters for tronSignMessage */\ninterface TronSignMessageCallParams {\n path: string;\n /** Message hex (no 0x prefix) */\n messageHex: string;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Strip the \"m/\" prefix from BIP-44 derivation paths. */\nfunction normalizePath(path: string): string {\n return path.startsWith('m/') ? path.slice(2) : path;\n}\n\n/** Remove `0x` prefix from a hex string if present. */\nfunction stripHex(hex: string): string {\n return hex.startsWith('0x') ? hex.slice(2) : hex;\n}\n\n/** Ensure a hex string is `0x`-prefixed and zero-padded to 64 hex chars (32 bytes). */\nfunction padHex64(hex: string): string {\n return `0x${stripHex(hex).padStart(64, '0')}`;\n}\n\n/** Convert a hex string (no 0x prefix) to a Uint8Array. */\nfunction hexToBytes(hex: string): Uint8Array {\n const clean = stripHex(hex);\n const bytes = new Uint8Array(clean.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\n/** Convert a Uint8Array to a hex string (no 0x prefix). */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\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), signer lifecycle, event emission,\n * and error handling.\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 private _signerManager: SignerManager | null = null;\n private _dmk: IDmk | null = null;\n\n private readonly _eventHandlers = new Map<\n ConnectorEventType,\n Set<EventHandler<ConnectorEventType>>\n >();\n\n private readonly _providedDmk: IDmk | undefined;\n private readonly _createTransport: TransportFactory;\n private readonly _connectionType: ConnectionType;\n\n constructor(\n createTransport: TransportFactory,\n options?: { connectionType?: ConnectionType; dmk?: IDmk },\n ) {\n this._createTransport = createTransport;\n this._connectionType = options?.connectionType ?? 'usb';\n this._providedDmk = options?.dmk;\n if (this._providedDmk) {\n this._initManagers(this._providedDmk);\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._resolveConnectId(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\n // Ensure we have fresh device list\n await this.searchDevices();\n\n let resolvedDeviceId = deviceId;\n\n // Empty or missing deviceId -- use first available device's DMK path\n if (!resolvedDeviceId) {\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${this._connectionType === 'ble' ? ' nearby with Bluetooth enabled' : ' via USB'} and unlocked.`,\n );\n }\n resolvedDeviceId = descriptors[0].path;\n }\n\n try {\n const sessionId = await dm.connect(resolvedDeviceId);\n\n const session: ConnectorSession = {\n sessionId,\n deviceInfo: {\n vendor: 'ledger',\n model: 'unknown',\n firmwareVersion: 'unknown',\n deviceId: resolvedDeviceId,\n connectId: resolvedDeviceId,\n connectionType: this._connectionType,\n capabilities: {\n persistentDeviceIdentity: false,\n },\n },\n };\n\n this._emit('device-connect', {\n device: {\n connectId: resolvedDeviceId,\n deviceId: resolvedDeviceId,\n name: 'Ledger',\n },\n });\n\n return session;\n } catch (err) {\n // Retry once: reset and re-discover\n this._resetManagers();\n const dm2 = await this._getDeviceManager();\n await this.searchDevices();\n\n const descriptors = await dm2.enumerate();\n const retryId = deviceId\n ? descriptors.find((d) => d.path === deviceId)?.path\n : descriptors[0]?.path;\n\n if (!retryId) {\n throw new Error(\n `No Ledger device found after retry. Make sure the device is connected${this._connectionType === 'ble' ? ' nearby with Bluetooth enabled' : ' via USB'} and unlocked.`,\n );\n }\n\n const sessionId = await dm2.connect(retryId);\n\n const session: ConnectorSession = {\n sessionId,\n deviceInfo: {\n vendor: 'ledger',\n model: 'unknown',\n firmwareVersion: 'unknown',\n deviceId: retryId,\n connectId: retryId,\n connectionType: this._connectionType,\n },\n };\n\n this._emit('device-connect', {\n device: {\n connectId: retryId,\n deviceId: retryId,\n name: 'Ledger',\n },\n });\n\n return session;\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(\n sessionId: string,\n method: string,\n params: unknown,\n ): Promise<unknown> {\n console.log('[DMK] call:', method, JSON.stringify(params));\n switch (method) {\n case 'evmGetAddress':\n return this._evmGetAddress(sessionId, params as EvmGetAddressCallParams);\n case 'evmSignTransaction':\n return this._evmSignTransaction(sessionId, params as EvmSignTransactionCallParams);\n case 'evmSignMessage':\n return this._evmSignMessage(sessionId, params as EvmSignMessageCallParams);\n case 'evmSignTypedData':\n return this._evmSignTypedData(sessionId, params as EvmSignTypedDataCallParams);\n case 'btcGetAddress':\n return this._btcGetAddress(sessionId, params as BtcGetAddressCallParams);\n case 'btcGetPublicKey':\n return this._btcGetPublicKey(sessionId, params as BtcGetPublicKeyCallParams);\n case 'btcSignTransaction':\n return this._btcSignTransaction(sessionId, params as BtcSignTransactionCallParams);\n case 'btcSignMessage':\n return this._btcSignMessage(sessionId, params as BtcSignMessageCallParams);\n case 'btcGetMasterFingerprint':\n return this._btcGetMasterFingerprint(sessionId, params as { skipOpenApp?: boolean } | undefined);\n case 'solGetAddress':\n return this._solGetAddress(sessionId, params as SolGetAddressCallParams);\n case 'solSignTransaction':\n return this._solSignTransaction(sessionId, params as SolSignTransactionCallParams);\n case 'solSignMessage':\n return this._solSignMessage(sessionId, params as SolSignMessageCallParams);\n case 'tronGetAddress':\n return this._tronGetAddress(sessionId, params as TronGetAddressCallParams);\n case 'tronSignTransaction':\n return this._tronSignTransaction(sessionId, params as TronSignTransactionCallParams);\n case 'tronSignMessage':\n return this._tronSignMessage(sessionId, params as TronSignMessageCallParams);\n default:\n throw new Error(`LedgerConnector: unknown method \"${method}\"`);\n }\n }\n\n async cancel(_sessionId: string): Promise<void> {\n // Ledger DMK doesn't expose a generic cancel mechanism\n }\n\n uiResponse(_response: { type: string; payload: unknown }): void {\n // Ledger does not use interactive UI responses (PIN/passphrase)\n }\n\n // ---------------------------------------------------------------------------\n // IConnector -- Events\n // ---------------------------------------------------------------------------\n\n on<K extends ConnectorEventType>(\n event: K,\n handler: (data: ConnectorEventMap[K]) => void,\n ): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers\n .get(event)!\n .add(handler as EventHandler<ConnectorEventType>);\n }\n\n off<K extends ConnectorEventType>(\n event: K,\n handler: (data: ConnectorEventMap[K]) => void,\n ): void {\n this._eventHandlers\n .get(event)\n ?.delete(handler as EventHandler<ConnectorEventType>);\n }\n\n // ---------------------------------------------------------------------------\n // IConnector -- Reset\n // ---------------------------------------------------------------------------\n\n reset(): void {\n this._resetManagers();\n }\n\n // ---------------------------------------------------------------------------\n // Private -- EVM methods\n // ---------------------------------------------------------------------------\n\n private async _evmGetAddress(\n sessionId: string,\n params: EvmGetAddressCallParams,\n ): Promise<{ address: string; publicKey?: string }> {\n const signer = await this._getEthSigner(sessionId);\n const path = normalizePath(params.path);\n const checkOnDevice = params.showOnDevice ?? false;\n console.log('[DMK] _evmGetAddress → signer.getAddress:', { path, checkOnDevice });\n\n try {\n const result = await signer.getAddress(path, {\n checkOnDevice,\n });\n return { address: result.address, publicKey: result.publicKey };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _evmSignTransaction(\n sessionId: string,\n params: EvmSignTransactionCallParams,\n ): Promise<{ v: string; r: string; s: string }> {\n const signer = await this._getEthSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const result: SignerEvmSignature = await signer.signTransaction(\n path,\n params.serializedTx,\n );\n return {\n v: `0x${result.v.toString(16)}`,\n r: padHex64(result.r),\n s: padHex64(result.s),\n };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _evmSignMessage(\n sessionId: string,\n params: EvmSignMessageCallParams,\n ): Promise<{ signature: string }> {\n const signer = await this._getEthSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const result: SignerEvmSignature = await signer.signMessage(\n path,\n params.message,\n );\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 this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _evmSignTypedData(\n sessionId: string,\n params: EvmSignTypedDataCallParams,\n ): Promise<{ signature: string }> {\n const signer = await this._getEthSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const result: SignerEvmSignature = await signer.signTypedData(\n path,\n params.data,\n );\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 this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private -- BTC methods\n // ---------------------------------------------------------------------------\n\n private async _btcGetAddress(\n sessionId: string,\n params: BtcGetAddressCallParams,\n ): Promise<{ address: string; path: string }> {\n const btcSigner = await this._createBtcSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const { DefaultWallet, DefaultDescriptorTemplate } = await import(\n '@ledgerhq/device-signer-kit-bitcoin'\n );\n const purpose = path.split('/')[0]?.replace(\"'\", '');\n let template = DefaultDescriptorTemplate.NATIVE_SEGWIT;\n if (purpose === '44') template = DefaultDescriptorTemplate.LEGACY;\n else if (purpose === '49')\n template = DefaultDescriptorTemplate.NESTED_SEGWIT;\n else if (purpose === '86') template = DefaultDescriptorTemplate.TAPROOT;\n const wallet = new DefaultWallet(path, template);\n\n const result = await btcSigner.getWalletAddress(wallet, 0, {\n checkOnDevice: params.showOnDevice ?? false,\n change: false,\n });\n return { address: result.address, path: params.path };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _btcGetPublicKey(\n sessionId: string,\n params: BtcGetPublicKeyCallParams,\n ): Promise<{ xpub: string; path: string }> {\n const btcSigner = await this._createBtcSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const xpub = await btcSigner.getExtendedPublicKey(path, {\n checkOnDevice: params.showOnDevice ?? false,\n });\n return { xpub, path: params.path };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _btcSignTransaction(\n sessionId: string,\n params: BtcSignTransactionCallParams,\n ): Promise<{ signedPsbt: string }> {\n const btcSigner = await this._createBtcSigner(sessionId);\n\n try {\n const { DefaultWallet, DefaultDescriptorTemplate } = await import(\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(\"'\", '');\n let template = DefaultDescriptorTemplate.NATIVE_SEGWIT;\n if (purpose === '44') template = DefaultDescriptorTemplate.LEGACY;\n else if (purpose === '49')\n template = DefaultDescriptorTemplate.NESTED_SEGWIT;\n else if (purpose === '86') template = DefaultDescriptorTemplate.TAPROOT;\n\n const wallet = new DefaultWallet(path, template);\n\n // signTransaction: signs the PSBT and returns the fully extracted raw tx hex\n const signedTxHex = await btcSigner.signTransaction(wallet, params.psbt!);\n\n return { signedPsbt: stripHex(signedTxHex) };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _btcSignMessage(\n sessionId: string,\n params: BtcSignMessageCallParams,\n ): Promise<{ signature: string; address: string }> {\n const btcSigner = await this._createBtcSigner(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 // Concatenate r + s + v into a single hex signature (65 bytes)\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\n return { signature: `${rHex}${sHex}${vHex}`, address: '' };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _btcGetMasterFingerprint(\n sessionId: string,\n params?: { skipOpenApp?: boolean },\n ): Promise<{ masterFingerprint: string }> {\n const btcSigner = await this._createBtcSigner(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 this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private -- SOL methods\n // ---------------------------------------------------------------------------\n\n private async _solGetAddress(\n sessionId: string,\n params: SolGetAddressCallParams,\n ): Promise<{ address: string; path: string }> {\n const solSigner = await this._createSolSigner(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 this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _solSignTransaction(\n sessionId: string,\n params: SolSignTransactionCallParams,\n ): Promise<{ signature: string }> {\n const solSigner = await this._createSolSigner(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 this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _solSignMessage(\n sessionId: string,\n params: SolSignMessageCallParams,\n ): Promise<{ signature: string }> {\n const solSigner = await this._createSolSigner(sessionId);\n const path = normalizePath(params.path);\n const messageBytes = hexToBytes(params.message);\n\n try {\n const result = await solSigner.signMessage(path, messageBytes);\n return { signature: bytesToHex(result) };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private -- TRON methods\n // ---------------------------------------------------------------------------\n\n private async _tronGetAddress(\n sessionId: string,\n params: TronGetAddressCallParams,\n ): Promise<{ address: string; publicKey: string; path: string }> {\n const tronSigner = await this._createTronSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const result = await tronSigner.getAddress(path, {\n checkOnDevice: params.showOnDevice ?? false,\n });\n return { address: result.address, publicKey: result.publicKey, path: params.path };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _tronSignTransaction(\n sessionId: string,\n params: TronSignTransactionCallParams,\n ): Promise<{ signature: string }> {\n const tronSigner = await this._createTronSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const signature = await tronSigner.signTransaction(path, params.rawTxHex);\n return { signature };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\n }\n\n private async _tronSignMessage(\n sessionId: string,\n params: TronSignMessageCallParams,\n ): Promise<{ signature: string }> {\n const tronSigner = await this._createTronSigner(sessionId);\n const path = normalizePath(params.path);\n\n try {\n const signature = await tronSigner.signMessage(path, params.messageHex);\n return { signature };\n } catch (err) {\n this._invalidateSession(sessionId);\n throw this._wrapError(err);\n }\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<IDmk> {\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 import(\n '@ledgerhq/device-management-kit'\n );\n const transportFactory = await this._createTransport();\n\n this._dmk = new DeviceManagementKitBuilder()\n .addTransport(transportFactory as any)\n .build() as unknown as IDmk;\n\n return this._dmk;\n }\n\n private _initManagers(dmk: IDmk): void {\n this._dmk = dmk;\n this._deviceManager = new LedgerDeviceManager(dmk);\n this._signerManager = new SignerManager(dmk);\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 _getEthSigner(sessionId: string) {\n if (!this._signerManager) {\n const dmk = await this._getOrCreateDmk();\n this._initManagers(dmk);\n }\n const signer = await this._signerManager!.getOrCreate(sessionId);\n\n // Wire up interaction events (open-app, unlock, verify-address, sign, etc.)\n signer.onInteraction = (interaction: string) => {\n this._emit('ui-event', {\n type: interaction,\n payload: { sessionId },\n });\n };\n\n return signer;\n }\n\n private async _createBtcSigner(sessionId: string): Promise<SignerBtc> {\n const dmk = await this._getOrCreateDmk();\n const { SignerBtcBuilder } = await import(\n '@ledgerhq/device-signer-kit-bitcoin'\n );\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sdkSigner = new SignerBtcBuilder({\n dmk: dmk as any,\n sessionId,\n }).build();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const signer = new SignerBtc(sdkSigner as any);\n\n // Wire up interaction events (open-app, unlock, sign, etc.)\n signer.onInteraction = (interaction: string) => {\n this._emit('ui-event', {\n type: interaction,\n payload: { sessionId },\n });\n };\n\n return signer;\n }\n\n private async _createSolSigner(sessionId: string): Promise<SignerSol> {\n const dmk = await this._getOrCreateDmk();\n const { SignerSolanaBuilder } = await import(\n '@ledgerhq/device-signer-kit-solana'\n );\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sdkSigner = new SignerSolanaBuilder({\n dmk: dmk as any,\n sessionId,\n }).build();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new SignerSol(sdkSigner as any);\n }\n\n private async _createTronSigner(sessionId: string): Promise<SignerTron> {\n const dmk = await this._getOrCreateDmk();\n // TRON has no dedicated DMK signer kit — communicate via raw APDUs\n const sendApdu = async (rawApdu: Uint8Array) => {\n const response = await dmk.sendApdu({ sessionId, apdu: rawApdu });\n return response;\n };\n return new SignerTron(sendApdu);\n }\n\n private _invalidateSession(sessionId: string): void {\n this._signerManager?.invalidate(sessionId);\n }\n\n private _resetManagers(): void {\n this._signerManager?.clearAll();\n this._deviceManager?.dispose();\n this._deviceManager = null;\n this._signerManager = null;\n this._dmk = null;\n }\n\n // ---------------------------------------------------------------------------\n // Private -- Events\n // ---------------------------------------------------------------------------\n\n private _emit<K extends ConnectorEventType>(\n event: K,\n data: ConnectorEventMap[K],\n ): 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 (error as any).code = mapped.code;\n return error;\n }\n}\n","import type { TransportProvider } from '../types';\n\nconst registry = new Map<string, TransportProvider>();\n\nfunction normalizeType(type: string): string {\n return type.trim().toLowerCase();\n}\n\nexport function registerTransport(type: string, provider: TransportProvider): void {\n const key = normalizeType(type);\n if (!key) throw new Error('Transport type must be a non-empty string');\n registry.set(key, provider);\n}\n\nexport function unregisterTransport(type: string): void {\n registry.delete(normalizeType(type));\n}\n\nexport function getTransportProvider(type: string): TransportProvider | null {\n return registry.get(normalizeType(type)) ?? null;\n}\n\nexport function listRegisteredTransports(): string[] {\n return Array.from(registry.keys());\n}\n\nexport function clearRegistry(): void {\n registry.clear();\n}\n","import type { IDmk } from '../types';\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: IDmk;\n private readonly _waitMs: number;\n private readonly _maxRetries: number;\n\n constructor(dmk: IDmk, 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 async ensureAppOpen(sessionId: string, targetAppName: string): 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\n await this._openApp(sessionId, targetAppName);\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: { type: 'get-app-and-version' },\n })) as { name: string };\n return result.name;\n }\n\n private async _openApp(sessionId: string, appName: string): Promise<void> {\n await this._dmk.sendCommand({\n sessionId,\n command: { type: 'open-app', appName },\n });\n }\n\n private async _closeCurrentApp(sessionId: string): Promise<void> {\n await this._dmk.sendCommand({\n sessionId,\n command: { type: 'close-app' },\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"],"mappings":"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","names":["import_hardware_wallet_core","result","INTERACTIVE_TIMEOUT_MS","hexToBytes","stripHex","padHex64","hexToBytes","bytesToHex"]}
|