@onekeyfe/hwk-adapter-core 1.1.29 → 1.1.31-alpha.0
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/chunk-BAGEFFFY.js +151 -0
- package/dist/chunk-BAGEFFFY.js.map +1 -0
- package/dist/chunk-FT3SZP2W.js +149 -0
- package/dist/chunk-FT3SZP2W.js.map +1 -0
- package/dist/chunk-U63HTLGJ.mjs +151 -0
- package/dist/chunk-U63HTLGJ.mjs.map +1 -0
- package/dist/chunk-XGIIA4A4.mjs +149 -0
- package/dist/chunk-XGIIA4A4.mjs.map +1 -0
- package/dist/errors.d.mts +197 -0
- package/dist/errors.d.ts +197 -0
- package/dist/errors.js +13 -0
- package/dist/errors.js.map +1 -0
- package/dist/errors.mjs +13 -0
- package/dist/errors.mjs.map +1 -0
- package/dist/index.d.mts +634 -299
- package/dist/index.d.ts +634 -299
- package/dist/index.js +452 -368
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +400 -258
- package/dist/index.mjs.map +1 -1
- package/dist/ui-events-Cb7haAeE.d.mts +128 -0
- package/dist/ui-events-Cb7haAeE.d.ts +128 -0
- package/dist/ui-events.d.mts +1 -0
- package/dist/ui-events.d.ts +1 -0
- package/dist/ui-events.js +21 -0
- package/dist/ui-events.js.map +1 -0
- package/dist/ui-events.mjs +21 -0
- package/dist/ui-events.mjs.map +1 -0
- package/package.json +22 -2
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types/errors.ts","../src/types/response.ts","../src/types/fingerprint.ts","../src/events/device.ts","../src/events/ui-request.ts","../src/events/sdk.ts","../src/utils/DeviceJobQueue.ts","../src/types/connector.ts","../src/utils/TypedEventEmitter.ts","../src/utils/UiRequestRegistry.ts","../src/utils/semver.ts","../src/utils/hex.ts","../src/utils/errorMessages.ts","../src/utils/batchCall.ts"],"sourcesContent":["/**\n * HWK HardwareErrorCode — independent namespace from the legacy\n * `@onekeyfe/shared` HardwareErrorCode (which occupies 0-902).\n *\n * All HWK codes are 5-digit (>= 10000) so the two tables never collide\n * even if either side grows. Each sub-category gets a 100-slot block.\n *\n * 10000-10099 Generic / cross-cutting primitives\n * 10100-10199 Device state\n * 10200-10299 Firmware\n * 10300-10399 Transport + OS-level permission\n * 10400-10499 PIN / Passphrase\n * 10500-10599 App lifecycle (wrong app, not open, too old)\n * 10600-10999 RESERVED — future adapter-level categories\n *\n * 11000-11099 EVM APDU (reactive mapping)\n * 11100-11199 Solana APDU\n * 11200-11299 Tron APDU\n * 11300-11399 BTC APDU\n * 11400-11999 RESERVED — future chain APDU blocks (100 per chain)\n *\n * 12000-99999 RESERVED — future major categories\n */\nexport enum HardwareErrorCode {\n // --- 10000s Generic ---\n UnknownError = 10000,\n UserRejected = 10001,\n InvalidParams = 10002,\n OperationTimeout = 10003,\n MethodNotSupported = 10004,\n /** User dismissed in-app cancel UI. Distinct from UserRejected (on-device). */\n UserAborted = 10005,\n\n // --- 10100s Device state ---\n DeviceNotFound = 10100,\n DeviceDisconnected = 10101,\n DeviceBusy = 10102,\n DeviceLocked = 10103,\n DeviceNotInitialized = 10104,\n DeviceInBootloader = 10105,\n DeviceMismatch = 10106,\n /** Chain app wedged (e.g. Ledger BTC 0x6901). User must exit app on device. */\n DeviceAppStuck = 10107,\n /** Vendor (Ledger / Trezor) doesn't support the chain at all. */\n ChainNotSupported = 10108,\n /** Current operation supports only one connected device. */\n DeviceOneDeviceOnly = 10109,\n\n // --- 10200s Firmware ---\n FirmwareTooOld = 10200,\n FirmwareUpdateRequired = 10201,\n\n // --- 10300s Transport + permission ---\n TransportError = 10300,\n BridgeNotFound = 10301,\n TransportNotAvailable = 10302,\n /**\n * OS-level permission (Bluetooth / USB / etc.) — denied, blocked,\n * unavailable, or dismissed. Consumers surface a single \"please grant\n * permission\" toast and let the user retry manually.\n */\n DevicePermissionDenied = 10303,\n /**\n * BLE SMP pairing did not complete within the GATT bonding window.\n * GATT connected but the device didn't acknowledge SMP — typically\n * because the user didn't confirm the passkey on the device, or the\n * device went out of range mid-pairing. Distinct from OperationTimeout\n * (generic) and from DeviceLocked (Secure Element actually locked).\n */\n BlePairingTimeout = 10304,\n /** Remote network failure reaching a vendor's servers (HTTP/WS). Distinct from TransportError (local USB/BLE link). */\n NetworkError = 10305,\n\n // --- 10400s PIN / Passphrase ---\n PinInvalid = 10400,\n PinCancelled = 10401,\n PassphraseRejected = 10402,\n\n // --- 10500s App lifecycle ---\n /** Chain app NOT INSTALLED on device. User must install via Ledger Live. */\n AppNotInstalled = 10500,\n WrongApp = 10501,\n /** 0x911c Command code not supported — app predates current SDK. */\n AppTooOld = 10502,\n /** Not enough free storage for install/update; user must uninstall apps first. */\n DeviceOutOfMemory = 10503,\n\n // --- 11000s EVM (Ledger Ethereum App) APDU-specific ---\n /** 0x6a80 Invalid data — observed on blindSignTransactionFallback when the\n * user has not enabled Blind signing on the device. */\n EvmBlindSigningRequired = 11000,\n /** 0x6984 Plugin not installed */\n EvmClearSignPluginMissing = 11001,\n /** 0x6a84 Insufficient memory (typical on Nano S with large calldata) */\n EvmDataTooLarge = 11002,\n /** 0x6501 TransactionType not supported (app too old for EIP-1559 / blob / 7702) */\n EvmTxTypeNotSupported = 11003,\n\n // --- 11100s Solana ---\n /** 0x6808 Blind signing disabled for this instruction. */\n SolanaBlindSigningRequired = 11100,\n\n // --- 11200s Tron ---\n /** 0x6a8d Custom Contracts setting disabled (blocks TRC-20 etc.). */\n TronCustomContractRequired = 11200,\n /** 0x6a8b Transactions Data setting disabled. */\n TronDataSigningRequired = 11201,\n /** 0x6a8c Sign by Hash setting disabled (hash-signing fallback). */\n TronSignByHashRequired = 11202,\n\n // --- 11300s BTC ---\n /** 0xb008 Wallet policy HMAC mismatch or not registered. */\n BtcWalletPolicyHmacMismatch = 11300,\n /** 0xb007 Aborted due to unexpected state (malformed PSBT / missing UTXO). */\n BtcUnexpectedState = 11301,\n}\n\n/**\n * Device-level failures the SDK cannot self-recover from — affect the entire\n * batch (vs per-chain failures like AppNotInstalled / WrongApp which soft-\n * skip in onboarding). Combined with `accounts.length === 0`, signals\n * genuine orphan. Also reused as the batch-abort whitelist for HWK.\n * Single source of truth.\n *\n * UserRejected (device-side reject) is included: pressing reject is an\n * explicit \"I don't consent\" — continuing the batch to ask again on the\n * next chain is harassment, not helpful.\n */\nexport const ORPHAN_ELIGIBLE_ERROR_CODES: number[] = [\n HardwareErrorCode.UserAborted,\n HardwareErrorCode.UserRejected,\n HardwareErrorCode.DeviceNotFound,\n HardwareErrorCode.DeviceDisconnected,\n HardwareErrorCode.DeviceMismatch,\n HardwareErrorCode.DeviceAppStuck,\n HardwareErrorCode.DeviceOneDeviceOnly,\n HardwareErrorCode.TransportError,\n HardwareErrorCode.DevicePermissionDenied,\n HardwareErrorCode.BlePairingTimeout,\n];\n\n// ---------------------------------------------------------------------------\n// Standard throwable for HWK adapters\n// ---------------------------------------------------------------------------\n\nexport interface IHwkErrorPayload {\n code: HardwareErrorCode;\n message: string;\n appName?: string;\n _tag?: string;\n params?: Record<string, unknown>;\n}\n\nexport type HwkError = Error & {\n code: HardwareErrorCode;\n appName?: string;\n _tag?: string;\n params?: Record<string, unknown>;\n};\n\n/**\n * Canonical throwable for HWK adapters. Plain Error + canonical extra fields,\n * shape-compatible with `rehydrateConnectorError` so locally-thrown and\n * cross-boundary errors are indistinguishable to downstream classifiers\n * (`err.code` / `err._tag` / `err.appName`). Do NOT mutate caught errors\n * with `Object.assign` — construct a fresh one via this factory.\n */\nexport function createHwkError(payload: IHwkErrorPayload): HwkError {\n return Object.assign(new Error(payload.message), {\n code: payload.code,\n ...(payload._tag !== undefined && { _tag: payload._tag }),\n ...(payload.appName !== undefined && { appName: payload.appName }),\n ...(payload.params !== undefined && { params: payload.params }),\n });\n}\n","import type { HardwareErrorCode } from './errors';\n\nexport interface Success<T> {\n success: true;\n payload: T;\n}\n\nexport interface Failure {\n success: false;\n payload: {\n error: string;\n code: HardwareErrorCode;\n params?: Record<string, unknown>;\n };\n}\n\nexport type Response<T> = Success<T> | Failure;\n\nexport function success<T>(payload: T): Success<T> {\n return { success: true, payload };\n}\n\nexport function failure(\n code: HardwareErrorCode,\n error: string,\n params?: Record<string, unknown>\n): Failure {\n return {\n success: false,\n payload: { error, code, ...(params ? { params } : {}) },\n };\n}\n","/**\n * Chain fingerprint utilities for device identity verification.\n *\n * Ledger devices have ephemeral IDs that change every session.\n * To verify that the same seed/device is connected, we derive an address\n * at a fixed path (account 0, index 0) and hash it into a stable \"chain fingerprint\".\n */\nimport { sha256 } from '@noble/hashes/sha256';\nimport { bytesToHex, utf8ToBytes } from '@noble/hashes/utils';\n\n/**\n * Fixed derivation paths used to generate chain fingerprints.\n * Uses standard index 0 — Ledger firmware shows device confirmation for\n * non-standard paths (e.g., index=100), which would interrupt wallet creation.\n * The address is hashed into a 16-char fingerprint, not exposed directly.\n * - EVM: cointype 60 (Ledger ETH App only supports 60)\n * - BTC: cointype 1 (testnet)\n * - SOL: cointype 501, standard 3-level hardened\n */\nexport const CHAIN_FINGERPRINT_PATHS: Record<ChainForFingerprint, string> = {\n evm: \"m/44'/60'/0'/0/0\",\n // BTC: account-level path (3 levels), mainnet cointype 0.\n // Cointype 1 (testnet) is rejected by some Ledger BTC App configurations.\n btc: \"m/44'/0'/0'\",\n sol: \"m/44'/501'/0'\",\n tron: \"m/44'/195'/0'/0/0\",\n};\n\nexport type ChainForFingerprint = 'evm' | 'btc' | 'sol' | 'tron';\n\n/**\n * 16-char SHA-256 fingerprint for device-identity verification.\n * Callers must canonicalize input (e.g. EVM address → lowercase) —\n * encoding variations otherwise cause false DeviceMismatch.\n */\nexport function deriveDeviceFingerprint(value: string): string {\n return bytesToHex(sha256(utf8ToBytes(value))).slice(0, 16);\n}\n","export const DEVICE_EVENT = 'DEVICE_EVENT';\n\n/** Events originating from the hardware device. */\nexport const DEVICE = {\n CONNECT: 'device-connect',\n DISCONNECT: 'device-disconnect',\n CHANGED: 'device-changed',\n} as const;\n","import type { QrResponseData } from '../types/qr';\n\nexport const UI_EVENT = 'UI_EVENT';\n\nexport const UI_REQUEST = {\n REQUEST_PIN: 'ui-request-pin',\n REQUEST_PASSPHRASE: 'ui-request-passphrase',\n REQUEST_PASSPHRASE_ON_DEVICE: 'ui-request-passphrase-on-device',\n REQUEST_BUTTON: 'ui-request-button',\n REQUEST_QR_DISPLAY: 'ui-request-qr-display',\n REQUEST_QR_SCAN: 'ui-request-qr-scan',\n REQUEST_DEVICE_PERMISSION: 'ui-request-device-permission',\n REQUEST_SELECT_DEVICE: 'ui-request-select-device',\n REQUEST_DEVICE_CONNECT: 'ui-request-device-connect',\n // Ledger BTC App: account index >= 100 requires display=true. Adapter asks\n // the user once per session before promoting the call.\n REQUEST_BTC_HIGH_INDEX_CONFIRM: 'ui-request-btc-high-index-confirm',\n // Required app is not installed; with autoInstallApp on, ask the user\n // whether to install it before retrying the operation.\n REQUEST_INSTALL_APP: 'ui-request-install-app',\n CLOSE_UI_WINDOW: 'ui-close',\n DEVICE_PROGRESS: 'ui-device_progress',\n FIRMWARE_PROGRESS: 'ui-firmware-progress',\n FIRMWARE_TIP: 'ui-firmware-tip',\n} as const;\n\nexport const UI_RESPONSE = {\n RECEIVE_PIN: 'receive-pin',\n RECEIVE_PASSPHRASE: 'receive-passphrase',\n RECEIVE_PASSPHRASE_ON_DEVICE: 'receive-passphrase-on-device',\n RECEIVE_QR_RESPONSE: 'receive-qr-response',\n RECEIVE_SELECT_DEVICE: 'receive-select-device',\n RECEIVE_DEVICE_CONNECT: 'receive-device-connect',\n RECEIVE_DEVICE_PERMISSION: 'receive-device-permission',\n RECEIVE_BTC_HIGH_INDEX_CONFIRM: 'receive-btc-high-index-confirm',\n RECEIVE_INSTALL_APP: 'receive-install-app',\n CANCEL: 'cancel',\n} as const;\n\nexport type DevicePermissionDeniedReason =\n | 'bluetoothTurnedOff'\n | 'permissionDenied'\n | (string & Record<never, never>);\n\nexport type DevicePermissionResponse = {\n granted: boolean;\n reason?: DevicePermissionDeniedReason;\n message?: string;\n};\n\nexport type UiResponseEvent =\n | {\n type: typeof UI_RESPONSE.RECEIVE_PIN;\n payload: string;\n }\n | {\n type: typeof UI_RESPONSE.RECEIVE_PASSPHRASE;\n payload: {\n value: string;\n passphraseOnDevice?: boolean;\n save?: boolean;\n };\n }\n | {\n type: typeof UI_RESPONSE.RECEIVE_PASSPHRASE_ON_DEVICE;\n payload?: undefined;\n }\n | {\n type: typeof UI_RESPONSE.RECEIVE_QR_RESPONSE;\n payload: QrResponseData;\n }\n | {\n // sdkConnectId echoes one of the DeviceInfo.connectId values emitted in\n // the REQUEST_SELECT_DEVICE event's `devices` list. Scope is the current\n // search session; may be ephemeral (e.g. Ledger USB DMK UUID).\n type: typeof UI_RESPONSE.RECEIVE_SELECT_DEVICE;\n payload: { sdkConnectId: string };\n }\n | {\n type: typeof UI_RESPONSE.RECEIVE_DEVICE_CONNECT;\n payload: { confirmed: boolean };\n }\n | {\n type: typeof UI_RESPONSE.RECEIVE_DEVICE_PERMISSION;\n payload: DevicePermissionResponse;\n }\n | {\n type: typeof UI_RESPONSE.RECEIVE_BTC_HIGH_INDEX_CONFIRM;\n payload: { confirmed: boolean };\n }\n | {\n type: typeof UI_RESPONSE.RECEIVE_INSTALL_APP;\n payload: { confirmed: boolean };\n }\n | {\n type: typeof UI_RESPONSE.CANCEL;\n payload?: undefined;\n };\n","/** Events generated by SDK internal detection (not from hardware directly). */\nexport const SDK = {\n DEVICE_STUCK: 'device-stuck',\n DEVICE_UNRESPONSIVE: 'device-unresponsive',\n DEVICE_RECOVERED: 'device-recovered',\n DEVICE_INTERACTION: 'device-interaction',\n} as const;\n","/**\n * Pure FIFO job queue. Every enqueue chains onto the tail; jobs run one at\n * a time across all devices. The queue is intentionally passive — it does\n * NOT decide whether to interrupt or ask the user. Those are application-\n * layer concerns owned by the caller (e.g. a UI button handler that wants\n * to ask \"device is busy, interrupt current?\" before submitting). The\n * queue exposes inspection (`getActiveJob`) and explicit cancellation\n * (`cancelActive` / `cancelAll`) so callers can implement those policies\n * synchronously, without racing against in-flight enqueues.\n */\n\nexport interface JobOptions {\n label?: string;\n rejectIfBusy?: boolean;\n busyError?: Error;\n}\n\nexport interface ActiveJobInfo {\n deviceId: string;\n label?: string;\n startedAt: number;\n}\n\ninterface ActiveJob {\n deviceId: string;\n label?: string;\n abortController: AbortController;\n startedAt: number;\n}\n\nexport class DeviceJobQueue {\n private _tail: Promise<unknown> = Promise.resolve();\n\n private _active: ActiveJob | null = null;\n\n private readonly _jobs = new Map<object, { deviceId: string }>();\n\n /** Incremented on clear() so queued-but-not-yet-running jobs detect invalidation. */\n private _generation = 0;\n\n private readonly _generationCancelReasons = new Map<number, Error>();\n\n /**\n * Enqueue a job. Runs after every previously-enqueued job has settled.\n * `deviceId` is a label only — used by inspection / cancellation routing.\n */\n async enqueue<T>(\n deviceId: string,\n job: (signal: AbortSignal) => Promise<T>,\n options: JobOptions = {}\n ): Promise<T> {\n if (options.rejectIfBusy && this._jobs.size > 0) {\n throw options.busyError ?? new Error('Device is busy');\n }\n\n const ac = new AbortController();\n const gen = this._generation;\n const prev = this._tail;\n const jobToken = {};\n const activeJob: ActiveJob = {\n deviceId,\n label: options.label,\n abortController: ac,\n startedAt: Date.now(),\n };\n this._jobs.set(jobToken, { deviceId });\n\n const next = prev\n .catch(() => {})\n .then(async () => {\n if (this._generation !== gen) {\n throw (\n this._generationCancelReasons.get(gen) ?? new Error('Job cancelled: queue was cleared')\n );\n }\n this._active = activeJob;\n try {\n return await job(ac.signal);\n } finally {\n // Identity guard: a previous job's deferred finally must not\n // null out a successor's `_active`.\n if (this._active === activeJob) {\n this._active = null;\n }\n }\n })\n .finally(() => {\n this._jobs.delete(jobToken);\n });\n\n this._tail = next.catch(() => {});\n return next;\n }\n\n /** Cancel the active job. If `deviceId` is given, only cancels when it matches. */\n cancelActive(deviceId?: string): boolean {\n if (!this._active) return false;\n if (deviceId && this._active.deviceId !== deviceId) return false;\n this._active.abortController.abort(new Error('Manually cancelled'));\n return true;\n }\n\n /** Force cancel the active job. `reason` becomes signal.reason. */\n forceCancelActive(deviceId?: string, reason?: Error): boolean {\n if (!this._active) return false;\n if (deviceId && this._active.deviceId !== deviceId) return false;\n this._active.abortController.abort(reason ?? new Error('Force cancelled for recovery'));\n return true;\n }\n\n /** Cancel the active job (alias for callers that previously needed multi-device cancel). */\n cancelAllActive(reason?: Error): void {\n if (!this._active) return;\n this._active.abortController.abort(reason ?? new Error('Cancelled by cancelAllActive'));\n }\n\n /** Cancel the active job and invalidate queued jobs that have not started. */\n cancelActiveAndPending(deviceId?: string, reason?: Error): boolean {\n if (deviceId && this._active && this._active.deviceId !== deviceId) {\n return false;\n }\n this.clear(reason ?? new Error('Cancelled by cancelActiveAndPending'));\n return true;\n }\n\n /** Get info about the currently active job, or null if idle. */\n getActiveJob(deviceId?: string): ActiveJobInfo | null {\n if (!this._active) return null;\n if (deviceId && this._active.deviceId !== deviceId) return null;\n return {\n deviceId: this._active.deviceId,\n label: this._active.label,\n startedAt: this._active.startedAt,\n };\n }\n\n /** True if any job is currently running. */\n isBusy(): boolean {\n return this._jobs.size > 0;\n }\n\n clear(reason?: Error): void {\n const cancelledGeneration = this._generation;\n this._generation++;\n const cancelReason = reason ?? new Error('Job cancelled: queue was cleared');\n this._generationCancelReasons.set(cancelledGeneration, cancelReason);\n for (const generation of this._generationCancelReasons.keys()) {\n if (generation < this._generation - 10) {\n this._generationCancelReasons.delete(generation);\n }\n }\n if (this._active) {\n this._active.abortController.abort(cancelReason);\n }\n }\n}\n","import type { ConnectionType, DeviceCapabilities, DeviceInfo, VendorType } from './device';\nimport type { UiResponseEvent } from '../events/ui-request';\n\n// =====================================================================\n// Connector types — transport-level abstraction for device communication\n// =====================================================================\n\n/**\n * Minimal device info returned during discovery (searchDevices).\n * At scan time, full DeviceInfo fields like firmwareVersion are not yet available.\n */\nexport interface ConnectorDevice {\n connectId: string;\n deviceId: string;\n name: string;\n /** Machine model id (e.g. \"nanoX\"). */\n model?: string;\n /** Human-readable model name (e.g. \"Ledger Nano X\"). */\n modelName?: string;\n /** BLE signal strength (BLE only). */\n rssi?: number | null;\n /** BLE connectable flag (BLE only). */\n isConnectable?: boolean | null;\n /** USB serial number (USB only). */\n serialNumber?: string;\n\n /** Device capabilities — available from scan time */\n capabilities?: DeviceCapabilities;\n}\n\nexport interface ConnectorSession {\n sessionId: string;\n deviceInfo: DeviceInfo;\n}\n\n// =====================================================================\n// Connector call result — device errors travel as DATA, not exceptions\n//\n// `IConnector.call` never throws for device-level failures. It resolves a\n// discriminated result so the failure crosses any process boundary\n// (IHardwareBridge / extension offscreen↔SW) as plain `data`. This mirrors\n// the OneKey HD-SDK `IDeviceResponseResult` contract.\n//\n// WHY: when a thrown Error crosses the extension JsBridge it is run through\n// `toPlainError`, a fixed field whitelist that drops custom own-properties\n// (e.g. `appName`). Returning the failure as data keeps every field intact.\n//\n// Contract for `ConnectorSerializedError`: only `message` / `code` /\n// `errorCode` live at the top level; ALL other domain fields (`appName`,\n// `_tag`, `statusCode`, …) are nested under `params`.\n// =====================================================================\n\n/**\n * Vendor-agnostic bag of extra error fields. Known keys are documented for\n * discoverability; the index signature keeps it open so any connector can\n * carry vendor-specific data without losing it across the bridge.\n */\nexport interface ConnectorErrorParams {\n /** Vendor SDK error tag (e.g. Ledger DMK `_tag`). */\n _tag?: string;\n /** App involved, e.g. the Ledger app being opened/installed. */\n appName?: string;\n /** Transport / APDU status code (string or number depending on vendor). */\n statusCode?: unknown;\n /**\n * Shallow snapshot of a nested cause. A raw Error does not survive JSON\n * serialization (its `message`/`stack` are non-enumerable), so recovery\n * predicates that recurse into a cause get this plain-object copy instead.\n */\n originalError?: {\n message?: string;\n code?: number;\n errorCode?: string;\n statusCode?: unknown;\n _tag?: string;\n };\n [key: string]: unknown;\n}\n\nexport interface ConnectorSerializedError {\n message: string;\n code?: number;\n errorCode?: string;\n params?: ConnectorErrorParams;\n}\n\nexport type ConnectorCallResult =\n | { success: true; payload: unknown }\n | { success: false; error: ConnectorSerializedError };\n\nexport type ConnectorEventType = 'device-connect' | 'device-disconnect' | 'ui-request' | 'ui-event';\n\n/**\n * Interaction event types emitted via 'ui-event'.\n * These map to user-facing prompts (confirm on device, open app, etc.).\n */\nexport enum EConnectorInteraction {\n /** Adapter is actively searching for the device (no session yet) */\n Searching = 'searching',\n /** Device requires user to open a specific app */\n ConfirmOpenApp = 'confirm-open-app',\n /** Device requires user to unlock */\n UnlockDevice = 'unlock-device',\n /** Device needs user to confirm on device (sign, verify, etc.) */\n ConfirmOnDevice = 'confirm-on-device',\n /** Previous interaction completed — clear UI prompt */\n InteractionComplete = 'interaction-complete',\n /**\n * OS-level Ledger app install progress. `progress` is a 0..1 fraction\n * reported by DMK's InstallOrUpdateAppsDeviceAction. Emitted from inside\n * the connector so the progress callback ref never has to cross the\n * IHardwareBridge boundary.\n */\n AppInstallProgress = 'app-install-progress',\n}\n\n// Discriminated union: most variants only carry `sessionId`, but\n// AppInstallProgress also carries `appName` + `progress`. Searching has no\n// session yet so it carries an empty `sessionId`.\nexport type ConnectorUiEvent =\n | { type: EConnectorInteraction.Searching; payload: { sessionId: string } }\n | { type: EConnectorInteraction.ConfirmOpenApp; payload: { sessionId: string } }\n | { type: EConnectorInteraction.UnlockDevice; payload: { sessionId: string } }\n | { type: EConnectorInteraction.ConfirmOnDevice; payload: { sessionId: string } }\n | { type: EConnectorInteraction.InteractionComplete; payload: { sessionId: string } }\n | {\n type: EConnectorInteraction.AppInstallProgress;\n payload: { sessionId: string; appName: string; progress: number };\n };\n\nexport interface ConnectorEventMap {\n 'device-connect': { device: ConnectorDevice };\n 'device-disconnect': { connectId: string };\n 'ui-request': { type: string; payload?: unknown };\n 'ui-event': ConnectorUiEvent;\n}\n\nexport interface IConnector {\n /** Physical connection type this connector uses. Fixed at construction. */\n readonly connectionType: ConnectionType;\n\n searchDevices(): Promise<ConnectorDevice[]>;\n connect(deviceId?: string): Promise<ConnectorSession>;\n disconnect(sessionId: string): Promise<void>;\n // `call` resolves a discriminated result; device-level failures are returned\n // as data, never thrown (see ConnectorCallResult). Only `call` uses this\n // contract because it is the one method that carries rich, vendor-specific\n // domain errors across the IHardwareBridge boundary, where a thrown Error\n // would be stripped by the host bridge's error whitelist. The other methods\n // surface plain operational failures and still reject normally.\n call(sessionId: string, method: string, params: unknown): Promise<ConnectorCallResult>;\n cancel(sessionId: string): Promise<void>;\n\n /** Send a UI response (e.g. PIN, passphrase) to the device. */\n uiResponse(response: UiResponseEvent): void;\n\n on<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;\n off<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;\n\n reset(): void;\n}\n\n// =====================================================================\n// Hardware bridge — generic forwarding interface for cross-boundary IConnector\n//\n// The same shape works across any process / context boundary that needs to\n// expose a multi-vendor backend behind a single-vendor IConnector facade:\n// - Electron (renderer ↔ preload/main via contextBridge)\n// - Browser Extension (popup/content ↔ background/offscreen via chrome.runtime)\n// - React Native (JS ↔ native module via NativeModules)\n// - Web Worker / iframe (postMessage)\n//\n// Each method takes a `vendor` discriminator so a single bridge implementation\n// can multiplex across vendors (ledger, trezor, ...).\n// =====================================================================\n\nexport interface IHardwareBridge {\n searchDevices(params: { vendor: VendorType }): Promise<ConnectorDevice[]>;\n connect(params: { vendor: VendorType; deviceId?: string }): Promise<ConnectorSession>;\n disconnect(params: { vendor: VendorType; sessionId: string }): Promise<void>;\n call(params: {\n vendor: VendorType;\n sessionId: string;\n method: string;\n callParams: unknown;\n }): Promise<ConnectorCallResult>;\n cancel(params: { vendor: VendorType; sessionId: string }): Promise<void>;\n uiResponse(params: { vendor: VendorType; response: UiResponseEvent }): void;\n reset(params: { vendor: VendorType }): void;\n\n /** Register an event handler for connector events forwarded across the bridge. */\n onEvent(\n params: { vendor: VendorType },\n handler: (event: { type: ConnectorEventType; data: unknown }) => void\n ): void;\n\n /** Unregister a previously registered event handler. */\n offEvent(\n params: { vendor: VendorType },\n handler: (event: { type: ConnectorEventType; data: unknown }) => void\n ): void;\n}\n\n/**\n * Adapt an IHardwareBridge (multi-vendor backend) into a single-vendor IConnector.\n * Every IConnector method becomes a transparent forward to bridge.<method>({ vendor, ... }).\n * Events are forwarded via bridge.onEvent / offEvent.\n *\n * Use this anywhere the actual hardware lives behind a process / context boundary\n * (Electron main, extension background, native module, worker, iframe).\n */\nexport function createBridgedConnector(\n vendor: VendorType,\n connectionType: ConnectionType,\n bridge: IHardwareBridge\n): IConnector {\n // Keyed by (event, handler). A flat handler-only map would collide when the\n // same function is registered for multiple events — second .on() would\n // overwrite the first bridge handler reference, leaking it permanently.\n type UserHandler = (data: ConnectorEventMap[ConnectorEventType]) => void;\n type BridgeHandler = (event: { type: ConnectorEventType; data: unknown }) => void;\n const handlerMap = new Map<ConnectorEventType, Map<UserHandler, BridgeHandler>>();\n\n return {\n connectionType,\n searchDevices: () => bridge.searchDevices({ vendor }),\n connect: deviceId => bridge.connect({ vendor, deviceId }),\n disconnect: sessionId => bridge.disconnect({ vendor, sessionId }),\n call: (sessionId, method, callParams) => bridge.call({ vendor, sessionId, method, callParams }),\n cancel: sessionId => bridge.cancel({ vendor, sessionId }),\n uiResponse: response => bridge.uiResponse({ vendor, response }),\n on: (event, handler) => {\n const bridgeHandler: BridgeHandler = e => {\n if (e.type === event) {\n handler(e.data as ConnectorEventMap[typeof event]);\n }\n };\n let inner = handlerMap.get(event);\n if (!inner) {\n inner = new Map();\n handlerMap.set(event, inner);\n }\n inner.set(handler as UserHandler, bridgeHandler);\n bridge.onEvent({ vendor }, bridgeHandler);\n },\n off: (event, handler) => {\n const inner = handlerMap.get(event);\n const bridgeHandler = inner?.get(handler as UserHandler);\n if (!bridgeHandler || !inner) return;\n bridge.offEvent({ vendor }, bridgeHandler);\n inner.delete(handler as UserHandler);\n if (inner.size === 0) handlerMap.delete(event);\n },\n reset: () => bridge.reset({ vendor }),\n };\n}\n\n// =====================================================================\n// ConnectorCallResult error (de)serialization — the canonical, vendor-agnostic\n// helpers every IConnector implementation / adapter should use, so the\n// \"errors as data\" contract is identical across vendors.\n// =====================================================================\n\nconst SERIALIZED_ERROR_TOP_LEVEL_KEYS = new Set([\n 'message',\n 'code',\n 'errorCode',\n 'stack',\n 'params',\n]);\n\n/**\n * Flatten a thrown error into the cross-boundary-safe `ConnectorSerializedError`\n * shape. `message`/`code`/`errorCode` are lifted to the top level; every other\n * own-enumerable field is copied into `params` so NO domain data is lost when\n * the result crosses a host bridge (which may run thrown errors through a\n * field whitelist). A nested `originalError` is shallow-snapshotted because a\n * raw Error does not survive JSON serialization.\n */\nexport function serializeConnectorError(err: unknown): ConnectorSerializedError {\n if (!err || typeof err !== 'object') {\n return { message: typeof err === 'string' ? err : 'Unknown error' };\n }\n const e = err as Record<string, unknown>;\n const message = typeof e.message === 'string' ? e.message : 'Unknown error';\n const code = typeof e.code === 'number' ? e.code : undefined;\n const errorCode = e.errorCode != null ? String(e.errorCode) : undefined;\n\n const params: ConnectorErrorParams = {};\n // Flatten an existing `params` bag, then copy every other own field (so\n // vendor-specific keys like `_tag` / `statusCode` / `appName` / step context\n // are preserved without being named here).\n if (e.params && typeof e.params === 'object') {\n Object.assign(params, e.params as Record<string, unknown>);\n }\n for (const key of Object.keys(e)) {\n if (!SERIALIZED_ERROR_TOP_LEVEL_KEYS.has(key)) {\n params[key] = e[key];\n }\n }\n const orig = e.originalError;\n if (orig && typeof orig === 'object') {\n const o = orig as Record<string, unknown>;\n params.originalError = {\n message: typeof o.message === 'string' ? o.message : undefined,\n code: typeof o.code === 'number' ? o.code : undefined,\n errorCode: o.errorCode != null ? String(o.errorCode) : undefined,\n statusCode: o.statusCode,\n _tag: typeof o._tag === 'string' ? o._tag : undefined,\n };\n }\n\n // The result crosses host bridges via JSON.stringify. Drop any single field\n // that isn't JSON-safe (circular ref / non-serializable) so a pathological\n // error degrades to \"one field missing\" instead of crashing the transport.\n for (const key of Object.keys(params)) {\n try {\n JSON.stringify(params[key]);\n } catch {\n delete params[key];\n }\n }\n\n return {\n message,\n ...(code !== undefined ? { code } : {}),\n ...(errorCode !== undefined ? { errorCode } : {}),\n ...(Object.keys(params).length ? { params } : {}),\n };\n}\n\n/**\n * Inverse of `serializeConnectorError`: rebuild a flat Error instance, lifting\n * `params.*` back to own-properties so existing throw-based classifiers/recovery\n * logic (which read `err._tag` / `err.code` / `err.appName` / …) keep working\n * unchanged. The Result shape stays confined to the connector boundary.\n */\nexport function rehydrateConnectorError(error: ConnectorSerializedError): Error {\n const { message, code, errorCode, params } = error;\n return Object.assign(new Error(message), {\n ...(code !== undefined ? { code } : {}),\n ...(errorCode !== undefined ? { errorCode } : {}),\n ...(params ?? {}),\n });\n}\n","/**\n * Minimal typed event emitter using Map<string, Set<listener>>.\n * Each adapter uses this for device events (connect, disconnect, pin, etc.).\n *\n * TMap is a record mapping event name strings to their payload types.\n * Example:\n * type MyEvents = { 'connect': { id: string }; 'disconnect': { id: string } };\n * const emitter = new TypedEventEmitter<MyEvents>();\n * emitter.on('connect', (data) => { data.id }); // data is { id: string }\n *\n * For backward compatibility, TMap defaults to Record<string, any> so that\n * existing code using `new TypedEventEmitter<SomeUnionType>()` still compiles.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class TypedEventEmitter<TMap extends Record<string, any> = Record<string, any>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly _listeners = new Map<string, Set<(event: any) => void>>();\n\n on<K extends keyof TMap & string>(event: K, listener: (event: TMap[K]) => void): void;\n\n on(event: string, listener: (event: any) => void): void;\n\n on(event: string, listener: (event: any) => void): void {\n let set = this._listeners.get(event);\n if (!set) {\n set = new Set();\n this._listeners.set(event, set);\n }\n set.add(listener);\n }\n\n off<K extends keyof TMap & string>(event: K, listener: (event: TMap[K]) => void): void;\n\n off(event: string, listener: (event: any) => void): void;\n\n off(event: string, listener: (event: any) => void): void {\n const set = this._listeners.get(event);\n if (set) {\n set.delete(listener);\n if (set.size === 0) this._listeners.delete(event);\n }\n }\n\n emit<K extends keyof TMap & string>(event: K, data: TMap[K]): void;\n\n emit(event: string, data: unknown): void;\n\n emit(event: string, data: unknown): void {\n const set = this._listeners.get(event);\n if (set) {\n for (const listener of set) listener(data);\n }\n }\n\n removeAllListeners(): void {\n this._listeners.clear();\n }\n}\n","import { UI_REQUEST, UI_RESPONSE } from '../events/ui-request';\n\n/** 10 min — every UI request is human-in-the-loop; bias toward \"wait long\". */\nexport const UI_REQUEST_DEFAULT_TIMEOUT_MS = 600_000;\n\nconst RESPONSE_TO_REQUEST: Record<string, string> = {\n [UI_RESPONSE.RECEIVE_PIN]: UI_REQUEST.REQUEST_PIN,\n [UI_RESPONSE.RECEIVE_PASSPHRASE]: UI_REQUEST.REQUEST_PASSPHRASE,\n [UI_RESPONSE.RECEIVE_PASSPHRASE_ON_DEVICE]: UI_REQUEST.REQUEST_PASSPHRASE_ON_DEVICE,\n [UI_RESPONSE.RECEIVE_SELECT_DEVICE]: UI_REQUEST.REQUEST_SELECT_DEVICE,\n [UI_RESPONSE.RECEIVE_DEVICE_CONNECT]: UI_REQUEST.REQUEST_DEVICE_CONNECT,\n [UI_RESPONSE.RECEIVE_DEVICE_PERMISSION]: UI_REQUEST.REQUEST_DEVICE_PERMISSION,\n [UI_RESPONSE.RECEIVE_BTC_HIGH_INDEX_CONFIRM]: UI_REQUEST.REQUEST_BTC_HIGH_INDEX_CONFIRM,\n [UI_RESPONSE.RECEIVE_INSTALL_APP]: UI_REQUEST.REQUEST_INSTALL_APP,\n // RECEIVE_QR_RESPONSE maps to QR_DISPLAY or QR_SCAN — resolved dynamically below.\n};\n\nexport const UI_REQUEST_PREEMPTED_TAG = 'UiRequestPreempted';\nexport const UI_REQUEST_CANCELLED_TAG = 'UiRequestCancelled';\nexport const UI_REQUEST_TIMEOUT_TAG = 'UiRequestTimeout';\n\ntype PendingEntry = {\n resolve: (payload: unknown) => void;\n reject: (error: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n};\n\n/**\n * Per-type single-slot registry for adapter-level UI requests. A new `wait`\n * of the same type supersedes (rejects) the prior pending entry. With the\n * job queue running globally serially, cross-type collisions don't occur in\n * normal flow — same-type preemption is a defensive measure for callers\n * that fire the same request twice without waiting on the first.\n *\n * Unknown response types are dropped silently so the public `uiResponse`\n * entry never throws.\n */\nexport class UiRequestRegistry {\n private pending = new Map<string, PendingEntry>();\n\n wait<T = unknown>(requestType: string, options?: { timeoutMs?: number }): Promise<T> {\n const existing = this.pending.get(requestType);\n if (existing) {\n clearTimeout(existing.timer);\n this.pending.delete(requestType);\n existing.reject(\n Object.assign(new Error(`UI request '${requestType}' was superseded by a new request`), {\n _tag: UI_REQUEST_PREEMPTED_TAG,\n })\n );\n }\n\n const timeoutMs = options?.timeoutMs ?? UI_REQUEST_DEFAULT_TIMEOUT_MS;\n\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n if (this.pending.get(requestType)?.timer === timer) {\n this.pending.delete(requestType);\n reject(\n Object.assign(new Error(`UI request '${requestType}' timed out after ${timeoutMs}ms`), {\n _tag: UI_REQUEST_TIMEOUT_TAG,\n })\n );\n }\n }, timeoutMs);\n\n this.pending.set(requestType, {\n resolve: resolve as (payload: unknown) => void,\n reject,\n timer,\n });\n });\n }\n\n resolve(responseType: string, payload: unknown): void {\n let requestType = RESPONSE_TO_REQUEST[responseType];\n if (responseType === UI_RESPONSE.RECEIVE_QR_RESPONSE) {\n if (this.pending.has(UI_REQUEST.REQUEST_QR_DISPLAY)) {\n requestType = UI_REQUEST.REQUEST_QR_DISPLAY;\n } else if (this.pending.has(UI_REQUEST.REQUEST_QR_SCAN)) {\n requestType = UI_REQUEST.REQUEST_QR_SCAN;\n }\n }\n if (!requestType) return;\n\n const entry = this.pending.get(requestType);\n if (!entry) return;\n\n clearTimeout(entry.timer);\n this.pending.delete(requestType);\n entry.resolve(payload);\n }\n\n cancel(requestType?: string): void {\n if (requestType) {\n const entry = this.pending.get(requestType);\n if (!entry) return;\n clearTimeout(entry.timer);\n this.pending.delete(requestType);\n entry.reject(\n Object.assign(new Error(`UI request '${requestType}' was cancelled`), {\n _tag: UI_REQUEST_CANCELLED_TAG,\n })\n );\n return;\n }\n\n for (const [type, entry] of this.pending) {\n clearTimeout(entry.timer);\n entry.reject(\n Object.assign(new Error(`UI request '${type}' was cancelled`), {\n _tag: UI_REQUEST_CANCELLED_TAG,\n })\n );\n }\n this.pending.clear();\n }\n\n reset(): void {\n this.cancel();\n }\n\n hasPending(requestType?: string): boolean {\n if (requestType) return this.pending.has(requestType);\n return this.pending.size > 0;\n }\n}\n","/**\n * Compare two semver strings (e.g. \"2.1.0\" vs \"2.3.1\").\n * Returns -1 if a < b, 0 if equal, 1 if a > b.\n */\nexport function compareSemver(a: string, b: string): number {\n const pa = a.split('.').map(Number);\n const pb = b.split('.').map(Number);\n for (let i = 0; i < 3; i++) {\n const va = pa[i] ?? 0;\n const vb = pb[i] ?? 0;\n if (va < vb) return -1;\n if (va > vb) return 1;\n }\n return 0;\n}\n","import { bytesToHex as nobleBytesToHex, hexToBytes as nobleHexToBytes } from '@noble/hashes/utils';\n\n/** Ensure hex string has 0x prefix */\nexport function ensure0x(hex: string): string {\n return hex.startsWith('0x') ? hex : `0x${hex}`;\n}\n\n/** Strip 0x prefix from hex string */\nexport function stripHex(hex: string): string {\n return hex.startsWith('0x') ? hex.slice(2) : hex;\n}\n\n/** Pad hex to 64 chars (32 bytes) with 0x prefix */\nexport function padHex64(hex: string): string {\n return `0x${stripHex(hex).padStart(64, '0')}`;\n}\n\n/**\n * Convert a hex string (with or without 0x prefix) to a Uint8Array.\n * Throws on invalid hex (non-hex characters, odd length).\n */\nexport function hexToBytes(hex: string): Uint8Array {\n return nobleHexToBytes(stripHex(hex));\n}\n\n/** Convert a Uint8Array to a hex string (no 0x prefix). */\nexport function bytesToHex(bytes: Uint8Array): string {\n return nobleBytesToHex(bytes);\n}\n","import { HardwareErrorCode } from '../types/errors';\n\n/**\n * Enrich a hardware error message with actionable recovery hints.\n * Shared across adapters (Ledger, Trezor, etc.).\n */\nexport function enrichErrorMessage(code: HardwareErrorCode, originalMessage: string): string {\n switch (code) {\n case HardwareErrorCode.PinInvalid:\n return `${originalMessage}. Please re-enter your PIN.`;\n case HardwareErrorCode.PinCancelled:\n return `${originalMessage}. PIN entry was cancelled.`;\n case HardwareErrorCode.DeviceBusy:\n return `${originalMessage}. The device is in use by another application. Close other wallet apps and try again.`;\n case HardwareErrorCode.DeviceDisconnected:\n return `${originalMessage}. Please reconnect the device and try again.`;\n case HardwareErrorCode.DeviceLocked:\n return `${originalMessage}. Please unlock your device and try again.`;\n case HardwareErrorCode.DeviceOneDeviceOnly:\n return `${originalMessage}. Disconnect the extra device and try again.`;\n case HardwareErrorCode.UserRejected:\n return `${originalMessage}. The request was rejected on the device.`;\n case HardwareErrorCode.WrongApp:\n return `${originalMessage}. Please open the correct app on your device.`;\n case HardwareErrorCode.AppNotInstalled:\n return `${originalMessage}. The required app is not installed on the device.`;\n case HardwareErrorCode.DeviceOutOfMemory:\n return `${originalMessage}. Not enough free space on the device. Please uninstall some apps and try again.`;\n case HardwareErrorCode.TransportNotAvailable:\n return `${originalMessage}. Ensure the device bridge/transport is available and running.`;\n case HardwareErrorCode.NetworkError:\n return `${originalMessage}. Network error — check your internet connection and try again.`;\n case HardwareErrorCode.FirmwareTooOld:\n return `${originalMessage}. Please update your device firmware.`;\n case HardwareErrorCode.DeviceNotInitialized:\n return `${originalMessage}. The device may need to be set up first.`;\n case HardwareErrorCode.OperationTimeout:\n return `${originalMessage}. The operation timed out. Please try again.`;\n case HardwareErrorCode.EvmBlindSigningRequired:\n return 'Ledger: Blind signing not enabled in Ethereum app.';\n case HardwareErrorCode.EvmClearSignPluginMissing:\n return 'Ledger: Required plugin not installed (install via Ledger Live).';\n case HardwareErrorCode.EvmDataTooLarge:\n return 'Ledger: Transaction data too large for device memory.';\n case HardwareErrorCode.EvmTxTypeNotSupported:\n return 'Ledger: Transaction type not supported by current Ethereum app.';\n case HardwareErrorCode.AppTooOld:\n return 'Ledger: App out of date (update via Ledger Live).';\n case HardwareErrorCode.SolanaBlindSigningRequired:\n return 'Blind signing disabled in the Solana app.';\n case HardwareErrorCode.TronCustomContractRequired:\n return 'Custom Contracts setting disabled in the Tron app.';\n case HardwareErrorCode.TronDataSigningRequired:\n return 'Transactions Data setting disabled in the Tron app.';\n case HardwareErrorCode.TronSignByHashRequired:\n return 'Sign by Hash setting disabled in the Tron app.';\n case HardwareErrorCode.BtcWalletPolicyHmacMismatch:\n return 'Wallet policy not registered or HMAC mismatch.';\n case HardwareErrorCode.BtcUnexpectedState:\n return 'Signing aborted due to unexpected device state.';\n default:\n return originalMessage;\n }\n}\n","import type { Response } from '../types/response';\n\n/**\n * Generic batch call with progress reporting.\n * If any single call fails, returns the failure immediately.\n */\nexport async function batchCall<TParam, TResult>(\n params: TParam[],\n callFn: (p: TParam) => Promise<Response<TResult>>,\n onProgress?: (progress: { index: number; total: number }) => void\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: true, payload: results };\n}\n"],"mappings":"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","names":["HardwareErrorCode","EConnectorInteraction","bytesToHex"]}
|
|
1
|
+
{"version":3,"sources":["../src/types/response.ts","../src/types/fingerprint.ts","../src/events/device.ts","../src/events/sdk.ts","../src/utils/DeviceJobQueue.ts","../src/types/connector.ts","../src/utils/TypedEventEmitter.ts","../src/utils/semver.ts","../src/utils/hex.ts","../src/utils/deviceIdentity.ts","../src/utils/batchCall.ts","../src/utils/methodCatalog.ts","../src/utils/allNetwork.ts","../src/constants.ts"],"sourcesContent":["import type { HardwareErrorCode } from './errors';\n\nexport interface Success<T> {\n success: true;\n payload: T;\n}\n\nexport interface Failure {\n success: false;\n payload: {\n error: string;\n code: HardwareErrorCode;\n params?: Record<string, unknown>;\n };\n}\n\nexport type Response<T> = Success<T> | Failure;\n\nexport function success<T>(payload: T): Success<T> {\n return { success: true, payload };\n}\n\nexport function failure(\n code: HardwareErrorCode,\n error: string,\n params?: Record<string, unknown>\n): Failure {\n return {\n success: false,\n payload: { error, code, ...(params ? { params } : {}) },\n };\n}\n","/**\n * Chain fingerprint utilities for device identity verification.\n *\n * Ledger devices have ephemeral IDs that change every session.\n * To verify that the same seed/device is connected, we derive an address\n * at a fixed path (account 0, index 0) and hash it into a stable \"chain fingerprint\".\n */\nimport { sha256 } from '@noble/hashes/sha256';\nimport { bytesToHex, utf8ToBytes } from '@noble/hashes/utils';\n\n/**\n * Fixed derivation paths used to generate chain fingerprints.\n * Uses standard index 0 — Ledger firmware shows device confirmation for\n * non-standard paths (e.g., index=100), which would interrupt wallet creation.\n * The address is hashed into a 16-char fingerprint, not exposed directly.\n * - EVM: cointype 60 (Ledger ETH App only supports 60)\n * - BTC: cointype 1 (testnet)\n * - SOL: cointype 501, standard 3-level hardened\n */\nexport const CHAIN_FINGERPRINT_PATHS: Record<ChainForFingerprint, string> = {\n evm: \"m/44'/60'/0'/0/0\",\n // BTC: account-level path (3 levels), mainnet cointype 0.\n // Cointype 1 (testnet) is rejected by some Ledger BTC App configurations.\n btc: \"m/44'/0'/0'\",\n sol: \"m/44'/501'/0'\",\n tron: \"m/44'/195'/0'/0/0\",\n};\n\nexport type ChainForFingerprint = 'evm' | 'btc' | 'sol' | 'tron';\n\n/**\n * 16-char SHA-256 fingerprint for device-identity verification.\n * Callers must canonicalize input (e.g. EVM address → lowercase) —\n * encoding variations otherwise cause false DeviceMismatch.\n */\nexport function deriveDeviceFingerprint(value: string): string {\n return bytesToHex(sha256(utf8ToBytes(value))).slice(0, 16);\n}\n","export const DEVICE_EVENT = 'DEVICE_EVENT';\n\n/** Events originating from the hardware device. */\nexport const DEVICE = {\n CONNECT: 'device-connect',\n DISCONNECT: 'device-disconnect',\n CHANGED: 'device-changed',\n FEATURES: 'features',\n /**\n * Trezor-only. Emitted after a successful THP handshake that minted or\n * refreshed pairing credentials. The host should persist `credentials`\n * keyed by `deviceId` and feed them back into the connector on the next\n * connect to skip the CodeEntry/QrCode/NFC pairing UX.\n *\n * The `TREZOR_` prefix mirrors `UI_REQUEST.REQUEST_TREZOR_THP_PAIRING` —\n * vendor-specific events live in the shared event taxonomy but are named\n * so hosts can ignore them when they don't drive Trezor hardware.\n */\n TREZOR_THP_CREDENTIALS_CHANGED: 'device-trezor-thp-credentials-changed',\n} as const;\n","/** Events generated by SDK internal detection (not from hardware directly). */\nexport const SDK = {\n DEVICE_STUCK: 'device-stuck',\n DEVICE_UNRESPONSIVE: 'device-unresponsive',\n DEVICE_RECOVERED: 'device-recovered',\n DEVICE_INTERACTION: 'device-interaction',\n} as const;\n","/**\n * Pure FIFO job queue. Every enqueue chains onto the tail; jobs run one at\n * a time across all devices. The queue is intentionally passive — it does\n * NOT decide whether to interrupt or ask the user. Those are application-\n * layer concerns owned by the caller (e.g. a UI button handler that wants\n * to ask \"device is busy, interrupt current?\" before submitting). The\n * queue exposes inspection (`getActiveJob`) and explicit cancellation\n * (`cancelActive` / `cancelAll`) so callers can implement those policies\n * synchronously, without racing against in-flight enqueues.\n */\n\nexport interface JobOptions {\n label?: string;\n rejectIfBusy?: boolean;\n busyError?: Error;\n}\n\nexport interface ActiveJobInfo {\n deviceId: string;\n label?: string;\n startedAt: number;\n}\n\ninterface ActiveJob {\n deviceId: string;\n label?: string;\n abortController: AbortController;\n startedAt: number;\n}\n\nexport class DeviceJobQueue {\n private _tail: Promise<unknown> = Promise.resolve();\n\n private _active: ActiveJob | null = null;\n\n private readonly _jobs = new Map<object, { deviceId: string }>();\n\n /** Incremented on clear() so queued-but-not-yet-running jobs detect invalidation. */\n private _generation = 0;\n\n private readonly _generationCancelReasons = new Map<number, Error>();\n\n /**\n * Enqueue a job. Runs after every previously-enqueued job has settled.\n * `deviceId` is a label only — used by inspection / cancellation routing.\n */\n async enqueue<T>(\n deviceId: string,\n job: (signal: AbortSignal) => Promise<T>,\n options: JobOptions = {}\n ): Promise<T> {\n if (options.rejectIfBusy && this._jobs.size > 0) {\n throw options.busyError ?? new Error('Device is busy');\n }\n\n const ac = new AbortController();\n const gen = this._generation;\n const prev = this._tail;\n const jobToken = {};\n const activeJob: ActiveJob = {\n deviceId,\n label: options.label,\n abortController: ac,\n startedAt: Date.now(),\n };\n this._jobs.set(jobToken, { deviceId });\n\n const next = prev\n .catch(() => {})\n .then(async () => {\n if (this._generation !== gen) {\n throw (\n this._generationCancelReasons.get(gen) ?? new Error('Job cancelled: queue was cleared')\n );\n }\n this._active = activeJob;\n try {\n return await job(ac.signal);\n } finally {\n // Identity guard: a previous job's deferred finally must not\n // null out a successor's `_active`.\n if (this._active === activeJob) {\n this._active = null;\n }\n }\n })\n .finally(() => {\n this._jobs.delete(jobToken);\n });\n\n this._tail = next.catch(() => {});\n return next;\n }\n\n /** Cancel the active job. If `deviceId` is given, only cancels when it matches. */\n cancelActive(deviceId?: string): boolean {\n if (!this._active) return false;\n if (deviceId && this._active.deviceId !== deviceId) return false;\n this._active.abortController.abort(new Error('Manually cancelled'));\n return true;\n }\n\n /** Force cancel the active job. `reason` becomes signal.reason. */\n forceCancelActive(deviceId?: string, reason?: Error): boolean {\n if (!this._active) return false;\n if (deviceId && this._active.deviceId !== deviceId) return false;\n this._active.abortController.abort(reason ?? new Error('Force cancelled for recovery'));\n return true;\n }\n\n /** Cancel the active job (alias for callers that previously needed multi-device cancel). */\n cancelAllActive(reason?: Error): void {\n if (!this._active) return;\n this._active.abortController.abort(reason ?? new Error('Cancelled by cancelAllActive'));\n }\n\n /** Cancel the active job and invalidate queued jobs that have not started. */\n cancelActiveAndPending(deviceId?: string, reason?: Error): boolean {\n if (deviceId && this._active && this._active.deviceId !== deviceId) {\n return false;\n }\n this.clear(reason ?? new Error('Cancelled by cancelActiveAndPending'));\n return true;\n }\n\n /** Get info about the currently active job, or null if idle. */\n getActiveJob(deviceId?: string): ActiveJobInfo | null {\n if (!this._active) return null;\n if (deviceId && this._active.deviceId !== deviceId) return null;\n return {\n deviceId: this._active.deviceId,\n label: this._active.label,\n startedAt: this._active.startedAt,\n };\n }\n\n /** True if any job is currently running. */\n isBusy(): boolean {\n return this._jobs.size > 0;\n }\n\n clear(reason?: Error): void {\n const cancelledGeneration = this._generation;\n this._generation++;\n const cancelReason = reason ?? new Error('Job cancelled: queue was cleared');\n this._generationCancelReasons.set(cancelledGeneration, cancelReason);\n for (const generation of this._generationCancelReasons.keys()) {\n if (generation < this._generation - 10) {\n this._generationCancelReasons.delete(generation);\n }\n }\n if (this._active) {\n this._active.abortController.abort(cancelReason);\n }\n }\n}\n","import { HardwareErrorCode, createHwkError } from './errors';\n\nimport type { ConnectionType, DeviceCapabilities, DeviceInfo, VendorType } from './device';\nimport type { UiResponseEvent } from '../events/ui-request';\n\n// =====================================================================\n// Connector types — transport-level abstraction for device communication\n// =====================================================================\n\n/**\n * Minimal device info returned during discovery (searchDevices).\n * At scan time, full DeviceInfo fields like firmwareVersion are not yet available.\n */\nexport interface ConnectorDevice {\n connectId: string;\n deviceId: string;\n name: string;\n /**\n * Physical transport this device was discovered on. Mirrors Trezor\n * Connect's `descriptor.apiType` — when several transports are fused behind\n * one connector (see `createCombinedConnector`), the merged device list\n * carries this so the host can tell a USB entry from a BLE one and route\n * `connect()` back to the owning transport. Single-transport connectors may\n * leave it undefined.\n */\n connectionType?: ConnectionType;\n /** Machine model id (e.g. \"nanoX\"). */\n model?: string;\n /** Human-readable model name (e.g. \"Ledger Nano X\"). */\n modelName?: string;\n /** BLE signal strength (BLE only). */\n rssi?: number | null;\n /** BLE connectable flag (BLE only). */\n isConnectable?: boolean | null;\n /** USB serial number (USB only). */\n serialNumber?: string;\n\n /** Device capabilities — available from scan time */\n capabilities?: DeviceCapabilities;\n\n /**\n * Vendor-specific raw blob from the transport descriptor (USB / BLE).\n * Populated by `descriptorToConnectorDevice` in each connector. Treat as\n * informational; promote any field consumed by the app layer onto the\n * typed surface above.\n */\n raw?: Record<string, unknown>;\n}\n\nexport interface ConnectorSession {\n sessionId: string;\n deviceInfo: DeviceInfo;\n}\n\n// =====================================================================\n// Connector call result — device errors travel as DATA, not exceptions\n//\n// `IConnector.call` never throws for device-level failures. It resolves a\n// discriminated result so the failure crosses any process boundary\n// (IHardwareBridge / extension offscreen↔SW) as plain `data`. This mirrors\n// the OneKey HD-SDK `IDeviceResponseResult` contract.\n//\n// WHY: when a thrown Error crosses the extension JsBridge it is run through\n// `toPlainError`, a fixed field whitelist that drops custom own-properties\n// (e.g. `appName`). Returning the failure as data keeps every field intact.\n//\n// Contract for `ConnectorSerializedError`: only `message` / `code` /\n// `errorCode` live at the top level; ALL other domain fields (`appName`,\n// `_tag`, `statusCode`, …) are nested under `params`.\n// =====================================================================\n\n/**\n * Vendor-agnostic bag of extra error fields. Known keys are documented for\n * discoverability; the index signature keeps it open so any connector can\n * carry vendor-specific data without losing it across the bridge.\n */\nexport interface ConnectorErrorParams {\n /** Vendor SDK error tag (e.g. Ledger DMK `_tag`). */\n _tag?: string;\n /** App involved, e.g. the Ledger app being opened/installed. */\n appName?: string;\n /** Transport / APDU status code (string or number depending on vendor). */\n statusCode?: unknown;\n /**\n * Shallow snapshot of a nested cause. A raw Error does not survive JSON\n * serialization (its `message`/`stack` are non-enumerable), so recovery\n * predicates that recurse into a cause get this plain-object copy instead.\n */\n originalError?: {\n message?: string;\n code?: number;\n errorCode?: string;\n statusCode?: unknown;\n _tag?: string;\n };\n [key: string]: unknown;\n}\n\nexport interface ConnectorSerializedError {\n message: string;\n code?: number;\n errorCode?: string;\n params?: ConnectorErrorParams;\n}\n\nexport type ConnectorCallResult =\n | { success: true; payload: unknown }\n | { success: false; error: ConnectorSerializedError };\n\nexport type ConnectorEventType =\n | 'device-connect'\n | 'device-disconnect'\n | 'features'\n | 'device-trezor-thp-credentials-changed'\n | 'ui-request'\n | 'ui-event';\n\n/**\n * Interaction event types emitted via 'ui-event'.\n * These map to user-facing prompts (confirm on device, open app, etc.).\n */\nexport enum EConnectorInteraction {\n /** Adapter is actively searching for the device (no session yet) */\n Searching = 'searching',\n /** Device requires user to open a specific app */\n ConfirmOpenApp = 'confirm-open-app',\n /** Device requires user to unlock */\n UnlockDevice = 'unlock-device',\n /** Device needs user to confirm on device (sign, verify, etc.) */\n ConfirmOnDevice = 'confirm-on-device',\n /** Previous interaction completed — clear UI prompt */\n InteractionComplete = 'interaction-complete',\n /**\n * OS-level Ledger app install progress. `progress` is a 0..1 fraction\n * reported by DMK's InstallOrUpdateAppsDeviceAction. Emitted from inside\n * the connector so the progress callback ref never has to cross the\n * IHardwareBridge boundary.\n */\n AppInstallProgress = 'app-install-progress',\n}\n\n// Discriminated union: most variants only carry `sessionId`, but\n// AppInstallProgress also carries `appName` + `progress`. Searching has no\n// session yet so it carries an empty `sessionId`.\nexport type ConnectorUiEvent =\n | { type: EConnectorInteraction.Searching; payload: { sessionId: string } }\n | { type: EConnectorInteraction.ConfirmOpenApp; payload: { sessionId: string } }\n | { type: EConnectorInteraction.UnlockDevice; payload: { sessionId: string } }\n | { type: EConnectorInteraction.ConfirmOnDevice; payload: { sessionId: string } }\n | { type: EConnectorInteraction.InteractionComplete; payload: { sessionId: string } }\n | {\n type: EConnectorInteraction.AppInstallProgress;\n payload: { sessionId: string; appName: string; progress: number };\n };\n\nexport interface ConnectorEventMap {\n 'device-connect': { device: ConnectorDevice };\n 'device-disconnect': { connectId: string };\n features: { device: ConnectorDevice & { features: Record<string, unknown> } };\n 'device-trezor-thp-credentials-changed': {\n connectId: string;\n deviceId?: string;\n credentials: Record<string, unknown>[];\n };\n 'ui-request': { type: string; payload?: unknown };\n 'ui-event': ConnectorUiEvent;\n}\n\nexport interface ConnectorSearchDevicesOptions {\n /**\n * Wait for every child transport in a fused connector. Default discovery can\n * return shortly after USB appears so BLE does not slow down USB flows;\n * binding pickers can opt in when they need BLE candidates too.\n */\n waitForAll?: boolean;\n}\n\nexport interface IConnector {\n /** Physical connection type this connector uses. Fixed at construction. */\n readonly connectionType: ConnectionType;\n\n searchDevices(options?: ConnectorSearchDevicesOptions): Promise<ConnectorDevice[]>;\n connect(deviceId?: string): Promise<ConnectorSession>;\n disconnect(sessionId: string): Promise<void>;\n // `call` resolves a discriminated result; device-level failures are returned\n // as data, never thrown (see ConnectorCallResult). Only `call` uses this\n // contract because it is the one method that carries rich, vendor-specific\n // domain errors across the IHardwareBridge boundary, where a thrown Error\n // would be stripped by the host bridge's error whitelist. The other methods\n // surface plain operational failures and still reject normally.\n call(sessionId: string, method: string, params: unknown): Promise<ConnectorCallResult>;\n cancel(sessionId: string): Promise<void>;\n\n /** Send a UI response (e.g. PIN, passphrase) to the device. */\n uiResponse(response: UiResponseEvent): void;\n\n on<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;\n off<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;\n\n reset(): void;\n\n // Vendor-specific opt-in: warm-load persisted credentials before the first\n // session. Trezor uses this for THP `knownCredentials` (host-stored pairing\n // credentials replayed in `ThpHandshakeInitRequest` to skip the CodeEntry /\n // QrCode / NFC pairing UX on every connect). Vendors without persistent\n // credentials (Ledger, etc.) simply don't implement it.\n setKnownCredentials?(credentials: unknown[]): Promise<void> | void;\n}\n\n// =====================================================================\n// Hardware bridge — generic forwarding interface for cross-boundary IConnector\n//\n// The same shape works across any process / context boundary that needs to\n// expose a multi-vendor backend behind a single-vendor IConnector facade:\n// - Electron (renderer ↔ preload/main via contextBridge)\n// - Browser Extension (popup/content ↔ background/offscreen via chrome.runtime)\n// - React Native (JS ↔ native module via NativeModules)\n// - Web Worker / iframe (postMessage)\n//\n// Each method takes a `vendor` discriminator so a single bridge implementation\n// can multiplex across vendors (ledger, trezor, ...).\n// =====================================================================\n\nexport interface IHardwareBridge {\n searchDevices(params: {\n vendor: VendorType;\n options?: ConnectorSearchDevicesOptions;\n }): Promise<ConnectorDevice[]>;\n connect(params: { vendor: VendorType; deviceId?: string }): Promise<ConnectorSession>;\n disconnect(params: { vendor: VendorType; sessionId: string }): Promise<void>;\n call(params: {\n vendor: VendorType;\n sessionId: string;\n method: string;\n callParams: unknown;\n }): Promise<ConnectorCallResult>;\n cancel(params: { vendor: VendorType; sessionId: string }): Promise<void>;\n uiResponse(params: { vendor: VendorType; response: UiResponseEvent }): void;\n reset(params: { vendor: VendorType }): void;\n\n /** Register an event handler for connector events forwarded across the bridge. */\n onEvent(\n params: { vendor: VendorType },\n handler: (event: { type: ConnectorEventType; data: unknown }) => void\n ): void;\n\n /** Unregister a previously registered event handler. */\n offEvent(\n params: { vendor: VendorType },\n handler: (event: { type: ConnectorEventType; data: unknown }) => void\n ): void;\n\n /**\n * Warm-load vendor-specific persisted credentials. Currently only Trezor\n * uses this (THP `knownCredentials`); the bridge implementation can\n * dispatch on `vendor` and route to the right connector instance.\n */\n setKnownCredentials?(params: {\n vendor: VendorType;\n credentials: unknown[];\n }): Promise<void> | void;\n}\n\n/**\n * Adapt an IHardwareBridge (multi-vendor backend) into a single-vendor IConnector.\n * Every IConnector method becomes a transparent forward to bridge.<method>({ vendor, ... }).\n * Events are forwarded via bridge.onEvent / offEvent.\n *\n * Use this anywhere the actual hardware lives behind a process / context boundary\n * (Electron main, extension background, native module, worker, iframe).\n */\nexport function createBridgedConnector(\n vendor: VendorType,\n connectionType: ConnectionType,\n bridge: IHardwareBridge\n): IConnector {\n // Keyed by (event, handler). A flat handler-only map would collide when the\n // same function is registered for multiple events — second .on() would\n // overwrite the first bridge handler reference, leaking it permanently.\n type UserHandler = (data: ConnectorEventMap[ConnectorEventType]) => void;\n type BridgeHandler = (event: { type: ConnectorEventType; data: unknown }) => void;\n const handlerMap = new Map<ConnectorEventType, Map<UserHandler, BridgeHandler>>();\n\n return {\n connectionType,\n searchDevices: options => bridge.searchDevices({ vendor, options }),\n connect: deviceId => bridge.connect({ vendor, deviceId }),\n disconnect: sessionId => bridge.disconnect({ vendor, sessionId }),\n call: (sessionId, method, callParams) => bridge.call({ vendor, sessionId, method, callParams }),\n cancel: sessionId => bridge.cancel({ vendor, sessionId }),\n uiResponse: response => bridge.uiResponse({ vendor, response }),\n on: (event, handler) => {\n const bridgeHandler: BridgeHandler = e => {\n if (e.type === event) {\n handler(e.data as ConnectorEventMap[typeof event]);\n }\n };\n let inner = handlerMap.get(event);\n if (!inner) {\n inner = new Map();\n handlerMap.set(event, inner);\n }\n inner.set(handler as UserHandler, bridgeHandler);\n bridge.onEvent({ vendor }, bridgeHandler);\n },\n off: (event, handler) => {\n const inner = handlerMap.get(event);\n const bridgeHandler = inner?.get(handler as UserHandler);\n if (!bridgeHandler || !inner) return;\n bridge.offEvent({ vendor }, bridgeHandler);\n inner.delete(handler as UserHandler);\n if (inner.size === 0) handlerMap.delete(event);\n },\n reset: () => bridge.reset({ vendor }),\n setKnownCredentials: bridge.setKnownCredentials\n ? credentials => bridge.setKnownCredentials!({ vendor, credentials })\n : undefined,\n };\n}\n\n// =====================================================================\n// ConnectorCallResult error (de)serialization — the canonical, vendor-agnostic\n// helpers every IConnector implementation / adapter should use, so the\n// \"errors as data\" contract is identical across vendors.\n// =====================================================================\n\nconst SERIALIZED_ERROR_TOP_LEVEL_KEYS = new Set([\n 'message',\n 'code',\n 'errorCode',\n 'stack',\n 'params',\n]);\n\n/**\n * Flatten a thrown error into the cross-boundary-safe `ConnectorSerializedError`\n * shape. `message`/`code`/`errorCode` are lifted to the top level; every other\n * own-enumerable field is copied into `params` so NO domain data is lost when\n * the result crosses a host bridge (which may run thrown errors through a\n * field whitelist). A nested `originalError` is shallow-snapshotted because a\n * raw Error does not survive JSON serialization.\n */\nexport function serializeConnectorError(err: unknown): ConnectorSerializedError {\n if (!err || typeof err !== 'object') {\n return { message: typeof err === 'string' ? err : 'Unknown error' };\n }\n const e = err as Record<string, unknown>;\n const message = typeof e.message === 'string' ? e.message : 'Unknown error';\n const code = typeof e.code === 'number' ? e.code : undefined;\n const errorCode = e.errorCode != null ? String(e.errorCode) : undefined;\n\n const params: ConnectorErrorParams = {};\n // Flatten an existing `params` bag, then copy every other own field (so\n // vendor-specific keys like `_tag` / `statusCode` / `appName` / step context\n // are preserved without being named here).\n if (e.params && typeof e.params === 'object') {\n Object.assign(params, e.params as Record<string, unknown>);\n }\n for (const key of Object.keys(e)) {\n if (!SERIALIZED_ERROR_TOP_LEVEL_KEYS.has(key)) {\n params[key] = e[key];\n }\n }\n const orig = e.originalError;\n if (orig && typeof orig === 'object') {\n const o = orig as Record<string, unknown>;\n params.originalError = {\n message: typeof o.message === 'string' ? o.message : undefined,\n code: typeof o.code === 'number' ? o.code : undefined,\n errorCode: o.errorCode != null ? String(o.errorCode) : undefined,\n statusCode: o.statusCode,\n _tag: typeof o._tag === 'string' ? o._tag : undefined,\n };\n }\n\n // The result crosses host bridges via JSON.stringify. Drop any single field\n // that isn't JSON-safe (circular ref / non-serializable) so a pathological\n // error degrades to \"one field missing\" instead of crashing the transport.\n for (const key of Object.keys(params)) {\n try {\n JSON.stringify(params[key]);\n } catch {\n delete params[key];\n }\n }\n\n return {\n message,\n ...(code !== undefined ? { code } : {}),\n ...(errorCode !== undefined ? { errorCode } : {}),\n ...(Object.keys(params).length ? { params } : {}),\n };\n}\n\n/**\n * Inverse of `serializeConnectorError`: rebuild a flat Error instance, lifting\n * `params.*` back to own-properties so existing throw-based classifiers/recovery\n * logic (which read `err._tag` / `err.code` / `err.appName` / …) keep working\n * unchanged. The Result shape stays confined to the connector boundary.\n */\nexport function rehydrateConnectorError(error: ConnectorSerializedError): Error {\n const { message, code, errorCode, params } = error;\n return Object.assign(new Error(message), {\n ...(code !== undefined ? { code } : {}),\n ...(errorCode !== undefined ? { errorCode } : {}),\n ...(params ?? {}),\n });\n}\n\n/**\n * Fuse several single-transport IConnectors (e.g. WebUSB + BLE for one\n * vendor) into one IConnector whose device list is the union of all of them.\n *\n * This mirrors how Trezor Connect's `DeviceList` keeps one `TransportManager`\n * per `apiType` running concurrently and merges their devices into a single\n * list: there is no \"switch\" between transports — both are always live, and\n * each discovered device carries its `connectionType` so the host knows which\n * channel it came in on. `connect()` routes back to the transport that owns\n * the chosen device; later calls route by `sessionId`.\n *\n * Notes / current limitations:\n * - `searchDevices()` fans out concurrently; a transport that throws while\n * scanning is treated as \"no devices\" so a dead/absent channel never sinks\n * the others.\n * - USB entries sort ahead of BLE ones (Trezor's `getPrioritizedDevices`).\n * - The same physical device reachable on two transports surfaces as two\n * entries with different `connectId`s — we do NOT dedup, so the host can\n * present (or pick) a channel explicitly.\n * - `uiResponse()` carries no sessionId, so it is broadcast to every child;\n * a child with no matching pending request ignores it.\n */\nfunction isDeviceUnavailableError(error: unknown): boolean {\n const typed = error as { code?: unknown };\n if (\n typed.code === HardwareErrorCode.DeviceNotFound ||\n typed.code === HardwareErrorCode.DeviceDisconnected\n ) {\n return true;\n }\n return false;\n}\n\nfunction combinedDeviceNotFoundError(message: string): Error {\n return createHwkError({\n code: HardwareErrorCode.DeviceNotFound,\n message,\n });\n}\n\nfunction combinedSessionNotFoundError(message: string): Error {\n return createHwkError({\n code: HardwareErrorCode.DeviceDisconnected,\n message,\n });\n}\n\nexport function createCombinedConnector(connectors: IConnector[]): IConnector {\n if (connectors.length === 0) {\n throw new Error('createCombinedConnector: at least one connector is required');\n }\n const SEARCH_SETTLE_AFTER_FIRST_DEVICE_MS = 250;\n\n // connectId -> the child connector that discovered it (set on searchDevices).\n const deviceOwner = new Map<string, IConnector>();\n // sessionId -> the child connector that owns the live session.\n const sessionOwner = new Map<string, IConnector>();\n // userHandler -> the per-child forwarders we attached, so off() can detach.\n type UserHandler = (data: ConnectorEventMap[ConnectorEventType]) => void;\n const forwarders = new Map<\n ConnectorEventType,\n Map<UserHandler, Array<{ child: IConnector; handler: UserHandler }>>\n >();\n\n // BLE ranks after USB — matches Trezor's getPrioritizedDevices().\n const rank = (device: ConnectorDevice): number => (device.connectionType === 'ble' ? 1 : 0);\n\n // Shared THP pairing credentials across all child transports. A credential is\n // keyed by the device's static public key (transport-agnostic, see\n // `findKnownPairingCredentials`), so a credential minted while pairing over\n // one transport (e.g. USB) must reach the sibling transports (e.g. BLE) or\n // they re-pair instead of autoconnecting. Each child keeps its OWN\n // knownCredentials array, so we maintain the union here and re-broadcast it to\n // every child whenever any child mints a fresh one.\n const sharedCredentials: Array<Record<string, unknown>> = [];\n const credentialKey = (c: Record<string, unknown>): string =>\n (c.credential as string) ?? JSON.stringify(c);\n const mergeShared = (incoming: ReadonlyArray<Record<string, unknown>>): boolean => {\n let changed = false;\n for (const cred of incoming) {\n const key = credentialKey(cred);\n if (!sharedCredentials.some(e => credentialKey(e) === key)) {\n sharedCredentials.push(cred);\n changed = true;\n }\n }\n return changed;\n };\n const broadcastCredentials = async (): Promise<void> => {\n await Promise.all(\n connectors.map(child => Promise.resolve(child.setKnownCredentials?.(sharedCredentials)))\n );\n };\n\n // Internal subscription (independent of user on()/off()): when any child mints\n // fresh pairing credentials, fold them into the shared union and push the\n // union down to every child so the next handshake on ANY transport\n // autoconnects rather than re-pairing.\n for (const child of connectors) {\n child.on('device-trezor-thp-credentials-changed', data => {\n if (mergeShared(data.credentials)) void broadcastCredentials();\n });\n }\n\n const searchDevices = async (\n options: { waitForAll?: boolean } = {}\n ): Promise<ConnectorDevice[]> => {\n const perConnector: Array<{\n index: number;\n devices: ConnectorDevice[];\n }> = [];\n\n await new Promise<void>(resolve => {\n let finished = false;\n let remaining = connectors.length;\n let settleTimer: ReturnType<typeof setTimeout> | undefined;\n\n const finish = () => {\n if (finished) return;\n finished = true;\n if (settleTimer) clearTimeout(settleTimer);\n resolve();\n };\n\n connectors.forEach((child, index) => {\n void child\n .searchDevices()\n .then(devices =>\n devices.map(device => ({\n ...device,\n connectionType: device.connectionType ?? child.connectionType,\n }))\n )\n .catch(\n () =>\n // A transport that can't scan (powered off, unauthorized, absent)\n // must not fail the whole fused search.\n [] as ConnectorDevice[]\n )\n .then(devices => {\n remaining -= 1;\n if (!finished) {\n perConnector.push({ index, devices });\n }\n if (remaining === 0) {\n finish();\n return;\n }\n const hasUsbDevice = devices.some(device => device.connectionType === 'usb');\n if (hasUsbDevice && !settleTimer && !options.waitForAll) {\n settleTimer = setTimeout(finish, SEARCH_SETTLE_AFTER_FIRST_DEVICE_MS);\n }\n });\n });\n });\n\n perConnector.sort((a, b) => a.index - b.index);\n\n deviceOwner.clear();\n const merged: ConnectorDevice[] = [];\n perConnector.forEach(({ index, devices }) => {\n for (const device of devices) {\n deviceOwner.set(device.connectId, connectors[index]);\n merged.push(device);\n }\n });\n return merged.sort((a, b) => rank(a) - rank(b));\n };\n\n const resolveOwner = async (\n deviceId?: string\n ): Promise<{ owner: IConnector; deviceId?: string }> => {\n if (deviceId && deviceOwner.has(deviceId)) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { owner: deviceOwner.get(deviceId)!, deviceId };\n }\n const devices = await searchDevices({ waitForAll: Boolean(deviceId) });\n if (deviceId) {\n const owner = deviceOwner.get(deviceId);\n if (!owner)\n throw combinedDeviceNotFoundError(`Combined connector: device not found: ${deviceId}`);\n return { owner, deviceId };\n }\n const first = devices[0];\n if (!first) throw combinedDeviceNotFoundError('Combined connector: no devices found');\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { owner: deviceOwner.get(first.connectId)!, deviceId: first.connectId };\n };\n\n const connectByExplicitId = async (\n deviceId: string\n ): Promise<{ session: ConnectorSession; owner: IConnector }> => {\n const cachedOwner = deviceOwner.get(deviceId);\n if (cachedOwner) {\n return { session: await cachedOwner.connect(deviceId), owner: cachedOwner };\n }\n\n let lastError: unknown;\n for (const child of connectors) {\n try {\n const session = await child.connect(deviceId);\n deviceOwner.set(deviceId, child);\n return { session, owner: child };\n } catch (error) {\n if (!isDeviceUnavailableError(error)) {\n throw error;\n }\n lastError = error;\n }\n }\n const message =\n lastError instanceof Error\n ? lastError.message\n : `Combined connector: device not found: ${deviceId}`;\n throw createHwkError({\n code: HardwareErrorCode.DeviceNotFound,\n message,\n });\n };\n\n return {\n // Nominal value only — the per-device `connectionType` is authoritative\n // for a fused connector.\n connectionType: connectors[0].connectionType,\n\n searchDevices: options => searchDevices({ waitForAll: options?.waitForAll }),\n\n connect: async deviceId => {\n let owner: IConnector;\n let session: ConnectorSession;\n if (deviceId) {\n ({ session, owner } = await connectByExplicitId(deviceId));\n } else {\n const resolved = await resolveOwner();\n owner = resolved.owner;\n session = await owner.connect(resolved.deviceId);\n }\n // Use the owner resolved during connect — re-deriving via\n // session.deviceInfo.connectId breaks for ephemeral-id transports (the id\n // can change on connect → missed lookup → orphaned session).\n sessionOwner.set(session.sessionId, owner);\n return session;\n },\n\n disconnect: async sessionId => {\n const owner = sessionOwner.get(sessionId);\n if (!owner) return;\n await owner.disconnect(sessionId);\n sessionOwner.delete(sessionId);\n },\n\n call: async (sessionId, method, params) => {\n const owner = sessionOwner.get(sessionId);\n if (!owner) {\n throw combinedSessionNotFoundError(`Combined connector: session not found: ${sessionId}`);\n }\n return owner.call(sessionId, method, params);\n },\n\n cancel: async sessionId => {\n const owner = sessionOwner.get(sessionId);\n if (!owner) return;\n await owner.cancel(sessionId);\n },\n\n uiResponse: response => {\n // No sessionId on the response — broadcast; children without a matching\n // pending request ignore it.\n for (const child of connectors) child.uiResponse(response);\n },\n\n on: (event, handler) => {\n const attached = connectors.map(child => {\n const forward: UserHandler = data => (handler as UserHandler)(data);\n child.on(event, forward as Parameters<IConnector['on']>[1]);\n return { child, handler: forward };\n });\n let inner = forwarders.get(event);\n if (!inner) {\n inner = new Map();\n forwarders.set(event, inner);\n }\n inner.set(handler as UserHandler, attached);\n },\n\n off: (event, handler) => {\n const inner = forwarders.get(event);\n const attached = inner?.get(handler as UserHandler);\n if (!attached || !inner) return;\n for (const { child, handler: forward } of attached) {\n child.off(event, forward as Parameters<IConnector['off']>[1]);\n }\n inner.delete(handler as UserHandler);\n if (inner.size === 0) forwarders.delete(event);\n },\n\n reset: () => {\n for (const child of connectors) child.reset();\n deviceOwner.clear();\n sessionOwner.clear();\n forwarders.clear();\n },\n\n setKnownCredentials: connectors.some(c => c.setKnownCredentials)\n ? async credentials => {\n // Seed the shared union from the host (warm-load) and fan out to all\n // children so every transport starts from the same credential set.\n sharedCredentials.length = 0;\n mergeShared((credentials ?? []) as Array<Record<string, unknown>>);\n await broadcastCredentials();\n }\n : undefined,\n };\n}\n","/**\n * Minimal typed event emitter using Map<string, Set<listener>>.\n * Each adapter uses this for device events (connect, disconnect, pin, etc.).\n *\n * TMap is a record mapping event name strings to their payload types.\n * Example:\n * type MyEvents = { 'connect': { id: string }; 'disconnect': { id: string } };\n * const emitter = new TypedEventEmitter<MyEvents>();\n * emitter.on('connect', (data) => { data.id }); // data is { id: string }\n *\n * For backward compatibility, TMap defaults to Record<string, any> so that\n * existing code using `new TypedEventEmitter<SomeUnionType>()` still compiles.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class TypedEventEmitter<TMap extends Record<string, any> = Record<string, any>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly _listeners = new Map<string, Set<(event: any) => void>>();\n\n on<K extends keyof TMap & string>(event: K, listener: (event: TMap[K]) => void): void;\n\n on(event: string, listener: (event: any) => void): void;\n\n on(event: string, listener: (event: any) => void): void {\n let set = this._listeners.get(event);\n if (!set) {\n set = new Set();\n this._listeners.set(event, set);\n }\n set.add(listener);\n }\n\n off<K extends keyof TMap & string>(event: K, listener: (event: TMap[K]) => void): void;\n\n off(event: string, listener: (event: any) => void): void;\n\n off(event: string, listener: (event: any) => void): void {\n const set = this._listeners.get(event);\n if (set) {\n set.delete(listener);\n if (set.size === 0) this._listeners.delete(event);\n }\n }\n\n emit<K extends keyof TMap & string>(event: K, data: TMap[K]): void;\n\n emit(event: string, data: unknown): void;\n\n emit(event: string, data: unknown): void {\n const set = this._listeners.get(event);\n if (set) {\n for (const listener of set) listener(data);\n }\n }\n\n removeAllListeners(): void {\n this._listeners.clear();\n }\n\n /** Number of listeners registered for `event`. 0 if none. */\n listenerCount(event: string): number {\n return this._listeners.get(event)?.size ?? 0;\n }\n}\n","/**\n * Compare two semver strings (e.g. \"2.1.0\" vs \"2.3.1\").\n * Returns -1 if a < b, 0 if equal, 1 if a > b.\n */\nexport function compareSemver(a: string, b: string): number {\n const pa = a.split('.').map(Number);\n const pb = b.split('.').map(Number);\n for (let i = 0; i < 3; i++) {\n const va = pa[i] ?? 0;\n const vb = pb[i] ?? 0;\n if (va < vb) return -1;\n if (va > vb) return 1;\n }\n return 0;\n}\n","import { bytesToHex as nobleBytesToHex, hexToBytes as nobleHexToBytes } from '@noble/hashes/utils';\n\n/** Ensure hex string has 0x prefix */\nexport function ensure0x(hex: string): string {\n return hex.startsWith('0x') ? hex : `0x${hex}`;\n}\n\n/** Strip 0x prefix from hex string */\nexport function stripHex(hex: string): string {\n return hex.startsWith('0x') ? hex.slice(2) : hex;\n}\n\n/** Pad hex to 64 chars (32 bytes) with 0x prefix */\nexport function padHex64(hex: string): string {\n return `0x${stripHex(hex).padStart(64, '0')}`;\n}\n\n/**\n * Convert a hex string (with or without 0x prefix) to a Uint8Array.\n * Throws on invalid hex (non-hex characters, odd length).\n */\nexport function hexToBytes(hex: string): Uint8Array {\n return nobleHexToBytes(stripHex(hex));\n}\n\n/** Convert a Uint8Array to a hex string (no 0x prefix). */\nexport function bytesToHex(bytes: Uint8Array): string {\n return nobleBytesToHex(bytes);\n}\n","export type DetectableHardwareVendor = 'onekey' | 'trezor' | 'ledger';\n\nexport type HardwareDeviceIdentityInput = {\n name?: string | null;\n localName?: string | null;\n bleName?: string | null;\n model?: string | null;\n modelName?: string | null;\n type?: string | null;\n productName?: string | null;\n manufacturerName?: string | null;\n vendor?: number | string | null;\n vendorId?: number | null;\n product?: number | string | null;\n productId?: number | null;\n label?: string | null;\n fw_vendor?: string | null;\n internal_model?: string | null;\n onekey_version?: string | null;\n onekey_device_type?: string | null;\n onekey_serial?: string | null;\n serviceUUIDs?: string[] | null;\n advertisedServiceUuids?: string[] | null;\n serviceUuids?: string[] | null;\n};\n\nconst ONEKEY_BLE_SERVICE_UUID = '00000001-0000-1000-8000-00805f9b34fb';\nconst TREZOR_BLE_SERVICE_UUID = '8c000001-a59b-4d58-a9ad-073df69fa1b1';\nconst LEDGER_USB_VENDOR_ID = 0x2c97;\n\nconst lower = (value?: string | null): string => value?.trim().toLowerCase() ?? '';\n\nconst hasServiceUuid = (input: HardwareDeviceIdentityInput, uuid: string): boolean => {\n const expected = uuid.toLowerCase();\n const values = [\n ...(input.serviceUUIDs ?? []),\n ...(input.advertisedServiceUuids ?? []),\n ...(input.serviceUuids ?? []),\n ];\n return values.some(value => value.toLowerCase() === expected);\n};\n\nexport function detectHardwareVendorFromDescriptor(\n input: HardwareDeviceIdentityInput\n): DetectableHardwareVendor | undefined {\n const manufacturerName = lower(input.manufacturerName);\n const fwVendor = lower(input.fw_vendor);\n\n if (\n hasServiceUuid(input, ONEKEY_BLE_SERVICE_UUID) ||\n manufacturerName.includes('onekey') ||\n fwVendor === 'onekey' ||\n input.onekey_version ||\n input.onekey_device_type ||\n input.onekey_serial\n ) {\n return 'onekey';\n }\n if (\n hasServiceUuid(input, TREZOR_BLE_SERVICE_UUID) ||\n manufacturerName.includes('trezor') ||\n fwVendor === 'trezor'\n ) {\n return 'trezor';\n }\n if (\n (typeof input.vendor === 'number' && input.vendor === LEDGER_USB_VENDOR_ID) ||\n input.vendorId === LEDGER_USB_VENDOR_ID ||\n manufacturerName.includes('ledger')\n ) {\n return 'ledger';\n }\n return undefined;\n}\n\nexport function isKnownNonTargetHardwareVendor(\n input: HardwareDeviceIdentityInput,\n targetVendor: DetectableHardwareVendor\n): boolean {\n const detectedVendor = detectHardwareVendorFromDescriptor(input);\n return detectedVendor !== undefined && detectedVendor !== targetVendor;\n}\n","import type { Response } from '../types/response';\n\n/**\n * Generic batch call with progress reporting.\n * If any single call fails, returns the failure immediately.\n */\nexport async function batchCall<TParam, TResult>(\n params: TParam[],\n callFn: (p: TParam) => Promise<Response<TResult>>,\n onProgress?: (progress: { index: number; total: number }) => void\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: true, payload: results };\n}\n","import type { ChainForFingerprint } from '../types/fingerprint';\n\nexport type HardwareMethodMetadata = {\n chain: ChainForFingerprint;\n allNetwork: boolean;\n};\n\nexport const HARDWARE_METHOD_CATALOG = {\n evmGetAddress: { chain: 'evm', allNetwork: true },\n evmSignTransaction: { chain: 'evm', allNetwork: false },\n evmSignMessage: { chain: 'evm', allNetwork: false },\n evmSignTypedData: { chain: 'evm', allNetwork: false },\n btcGetAddress: { chain: 'btc', allNetwork: true },\n btcGetPublicKey: { chain: 'btc', allNetwork: true },\n btcSignTransaction: { chain: 'btc', allNetwork: false },\n btcSignPsbt: { chain: 'btc', allNetwork: false },\n btcSignMessage: { chain: 'btc', allNetwork: false },\n btcGetMasterFingerprint: { chain: 'btc', allNetwork: false },\n solGetAddress: { chain: 'sol', allNetwork: true },\n solSignTransaction: { chain: 'sol', allNetwork: false },\n solSignMessage: { chain: 'sol', allNetwork: false },\n tronGetAddress: { chain: 'tron', allNetwork: true },\n tronSignTransaction: { chain: 'tron', allNetwork: false },\n tronSignMessage: { chain: 'tron', allNetwork: false },\n} as const satisfies Record<string, HardwareMethodMetadata>;\n\nexport type HardwareMethodName = keyof typeof HARDWARE_METHOD_CATALOG;\n\nexport type AllNetworkMethodName = {\n [K in HardwareMethodName]: (typeof HARDWARE_METHOD_CATALOG)[K]['allNetwork'] extends true\n ? K\n : never;\n}[HardwareMethodName];\n\nexport const ALL_NETWORK_METHOD_NAMES = Object.entries(HARDWARE_METHOD_CATALOG)\n .filter(([, metadata]) => metadata.allNetwork)\n .map(([method]) => method) as AllNetworkMethodName[];\n\nconst ALL_NETWORK_METHOD_SET = new Set<string>(ALL_NETWORK_METHOD_NAMES);\n\nexport function getHardwareMethodMetadata(method: string): HardwareMethodMetadata | undefined {\n return HARDWARE_METHOD_CATALOG[method as HardwareMethodName];\n}\n\nexport function isAllNetworkMethodName(method: string): method is AllNetworkMethodName {\n return ALL_NETWORK_METHOD_SET.has(method);\n}\n\nexport function getAllNetworkMethodChain(method: AllNetworkMethodName): ChainForFingerprint {\n return HARDWARE_METHOD_CATALOG[method].chain;\n}\n","import { HardwareErrorCode } from '../types/errors';\nimport { failure, success } from '../types/response';\nimport { getAllNetworkMethodChain, isAllNetworkMethodName } from './methodCatalog';\n\nimport type { ChainForFingerprint } from '../types/fingerprint';\nimport type { Response } from '../types/response';\nimport type {\n AllNetworkAddressParams,\n AllNetworkAddressResponse,\n AllNetworkGetAddressParams,\n} from '../types/wallet';\nimport type { AllNetworkMethodName } from './methodCatalog';\n\nexport type AllNetworkCallItemContext = {\n connectId: string;\n deviceId: string;\n method: AllNetworkMethodName;\n chain: ChainForFingerprint;\n item: AllNetworkAddressParams;\n index: number;\n};\n\nexport type AllNetworkAttachIdentityContext = AllNetworkCallItemContext & {\n payload: Record<string, unknown>;\n};\n\nexport type AllNetworkResponseContext = AllNetworkCallItemContext & {\n response: AllNetworkAddressResponse;\n};\n\nexport type RunAllNetworkGetAddressOptions = {\n connectId: string;\n deviceId: string;\n params: AllNetworkGetAddressParams;\n getMethodChain?: (\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ) => ChainForFingerprint;\n normalizeItem?: (\n method: AllNetworkMethodName,\n item: AllNetworkAddressParams\n ) => AllNetworkAddressParams;\n buildUnsupportedNetworkResponse?: (\n item: AllNetworkAddressParams,\n method: AllNetworkMethodName\n ) => AllNetworkAddressResponse | undefined;\n callItem: (context: AllNetworkCallItemContext) => Promise<Response<unknown>>;\n attachIdentity: (context: AllNetworkAttachIdentityContext) => Promise<AllNetworkAddressResponse>;\n shouldAbortBundle?: (\n response: AllNetworkAddressResponse,\n context: AllNetworkResponseContext\n ) => boolean;\n buildTopLevelFailure?: (\n response: AllNetworkAddressResponse,\n context: AllNetworkResponseContext\n ) => Response<AllNetworkAddressResponse[]>;\n};\n\nexport async function runAllNetworkGetAddress({\n connectId,\n deviceId,\n params,\n getMethodChain = method => getAllNetworkMethodChain(method),\n normalizeItem = (_method, item) => item,\n buildUnsupportedNetworkResponse,\n callItem,\n attachIdentity,\n shouldAbortBundle = () => false,\n buildTopLevelFailure = defaultBuildTopLevelFailure,\n}: RunAllNetworkGetAddressOptions): Promise<Response<AllNetworkAddressResponse[]>> {\n const responses: AllNetworkAddressResponse[] = [];\n\n for (const [index, item] of params.bundle.entries()) {\n if (!isAllNetworkMethodName(String(item.methodName))) {\n responses.push(buildUnsupportedMethodResponse(item));\n continue;\n }\n\n const method = item.methodName;\n const unsupportedNetwork = buildUnsupportedNetworkResponse?.(item, method);\n if (unsupportedNetwork) {\n responses.push(unsupportedNetwork);\n continue;\n }\n\n const chain = getMethodChain(method, item);\n const normalizedItem = normalizeItem(method, item);\n const context: AllNetworkCallItemContext = {\n connectId,\n deviceId,\n method,\n chain,\n item: normalizedItem,\n index,\n };\n const response = await callItem(context);\n const itemResponse = response.success\n ? await attachIdentity({\n ...context,\n payload: response.payload as Record<string, unknown>,\n })\n : ({\n ...normalizedItem,\n success: false,\n payload: response.payload,\n } as AllNetworkAddressResponse);\n\n const responseContext = { ...context, response: itemResponse };\n if (!itemResponse.success && shouldAbortBundle(itemResponse, responseContext)) {\n return buildTopLevelFailure(itemResponse, responseContext);\n }\n responses.push(itemResponse);\n }\n\n return success(responses);\n}\n\nexport function buildUnsupportedMethodResponse(\n item: AllNetworkAddressParams\n): AllNetworkAddressResponse {\n return {\n ...item,\n success: false,\n payload: {\n code: HardwareErrorCode.InvalidParams,\n error: `Unsupported allNetwork method: ${String(item.methodName)}`,\n },\n };\n}\n\nfunction defaultBuildTopLevelFailure(\n response: AllNetworkAddressResponse\n): Response<AllNetworkAddressResponse[]> {\n const payload = response.payload ?? {};\n return failure(\n (payload.code as HardwareErrorCode | undefined) ?? HardwareErrorCode.DeviceMismatch,\n payload.error ?? 'All-network get-address aborted',\n normalizeFailureParams(payload.params)\n );\n}\n\nfunction normalizeFailureParams(params: unknown): Record<string, unknown> | undefined {\n return params && typeof params === 'object' ? (params as Record<string, unknown>) : undefined;\n}\n","export const DEVICE_CONNECT_RETRY_DELAY_MS = 1000;\n"],"mappings":"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","names":["EConnectorInteraction","bytesToHex"]}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
interface QrDisplayData {
|
|
2
|
+
urType: string;
|
|
3
|
+
urData: string;
|
|
4
|
+
animated: boolean;
|
|
5
|
+
}
|
|
6
|
+
interface QrResponseData {
|
|
7
|
+
urType: string;
|
|
8
|
+
urData: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
declare const UI_EVENT = "UI_EVENT";
|
|
12
|
+
declare const UI_REQUEST: {
|
|
13
|
+
readonly REQUEST_PIN: "ui-request-pin";
|
|
14
|
+
readonly REQUEST_PASSPHRASE: "ui-request-passphrase";
|
|
15
|
+
readonly REQUEST_PASSPHRASE_ON_DEVICE: "ui-request-passphrase-on-device";
|
|
16
|
+
readonly REQUEST_BUTTON: "ui-request-button";
|
|
17
|
+
readonly REQUEST_QR_DISPLAY: "ui-request-qr-display";
|
|
18
|
+
readonly REQUEST_QR_SCAN: "ui-request-qr-scan";
|
|
19
|
+
readonly REQUEST_DEVICE_PERMISSION: "ui-request-device-permission";
|
|
20
|
+
readonly REQUEST_SELECT_DEVICE: "ui-request-select-device";
|
|
21
|
+
readonly REQUEST_DEVICE_CONNECT: "ui-request-device-connect";
|
|
22
|
+
readonly REQUEST_BTC_HIGH_INDEX_CONFIRM: "ui-request-btc-high-index-confirm";
|
|
23
|
+
readonly REQUEST_INSTALL_APP: "ui-request-install-app";
|
|
24
|
+
readonly REQUEST_PREEMPTION: "ui-request-preemption";
|
|
25
|
+
readonly REQUEST_TREZOR_THP_PAIRING: "ui-request-trezor-thp-pairing";
|
|
26
|
+
readonly CLOSE_UI_WINDOW: "ui-close";
|
|
27
|
+
readonly DEVICE_PROGRESS: "ui-device_progress";
|
|
28
|
+
readonly FIRMWARE_PROGRESS: "ui-firmware-progress";
|
|
29
|
+
readonly FIRMWARE_TIP: "ui-firmware-tip";
|
|
30
|
+
};
|
|
31
|
+
declare const UI_RESPONSE: {
|
|
32
|
+
readonly RECEIVE_PIN: "receive-pin";
|
|
33
|
+
readonly RECEIVE_PASSPHRASE: "receive-passphrase";
|
|
34
|
+
readonly RECEIVE_QR_RESPONSE: "receive-qr-response";
|
|
35
|
+
readonly RECEIVE_SELECT_DEVICE: "receive-select-device";
|
|
36
|
+
readonly RECEIVE_DEVICE_CONNECT: "receive-device-connect";
|
|
37
|
+
readonly RECEIVE_DEVICE_PERMISSION: "receive-device-permission";
|
|
38
|
+
readonly RECEIVE_BTC_HIGH_INDEX_CONFIRM: "receive-btc-high-index-confirm";
|
|
39
|
+
readonly RECEIVE_INSTALL_APP: "receive-install-app";
|
|
40
|
+
readonly RECEIVE_PREEMPTION: "receive-preemption";
|
|
41
|
+
readonly RECEIVE_TREZOR_THP_PAIRING: "receive-trezor-thp-pairing";
|
|
42
|
+
readonly CANCEL: "cancel";
|
|
43
|
+
};
|
|
44
|
+
type DevicePermissionDeniedReason = 'bluetoothTurnedOff' | 'permissionDenied' | (string & Record<never, never>);
|
|
45
|
+
type DevicePermissionResponse = {
|
|
46
|
+
granted: boolean;
|
|
47
|
+
reason?: DevicePermissionDeniedReason;
|
|
48
|
+
message?: string;
|
|
49
|
+
};
|
|
50
|
+
type UiResponseEvent = {
|
|
51
|
+
type: typeof UI_RESPONSE.RECEIVE_PIN;
|
|
52
|
+
payload: string;
|
|
53
|
+
} | {
|
|
54
|
+
type: typeof UI_RESPONSE.RECEIVE_PASSPHRASE;
|
|
55
|
+
payload: {
|
|
56
|
+
value: string;
|
|
57
|
+
passphraseOnDevice?: boolean;
|
|
58
|
+
save?: boolean;
|
|
59
|
+
};
|
|
60
|
+
} | {
|
|
61
|
+
type: typeof UI_RESPONSE.RECEIVE_QR_RESPONSE;
|
|
62
|
+
payload: QrResponseData;
|
|
63
|
+
} | {
|
|
64
|
+
type: typeof UI_RESPONSE.RECEIVE_SELECT_DEVICE;
|
|
65
|
+
payload: {
|
|
66
|
+
sdkConnectId: string;
|
|
67
|
+
};
|
|
68
|
+
} | {
|
|
69
|
+
type: typeof UI_RESPONSE.RECEIVE_DEVICE_CONNECT;
|
|
70
|
+
payload: {
|
|
71
|
+
confirmed: boolean;
|
|
72
|
+
};
|
|
73
|
+
} | {
|
|
74
|
+
type: typeof UI_RESPONSE.RECEIVE_DEVICE_PERMISSION;
|
|
75
|
+
payload: DevicePermissionResponse;
|
|
76
|
+
} | {
|
|
77
|
+
type: typeof UI_RESPONSE.RECEIVE_BTC_HIGH_INDEX_CONFIRM;
|
|
78
|
+
payload: {
|
|
79
|
+
confirmed: boolean;
|
|
80
|
+
};
|
|
81
|
+
} | {
|
|
82
|
+
type: typeof UI_RESPONSE.RECEIVE_INSTALL_APP;
|
|
83
|
+
payload: {
|
|
84
|
+
confirmed: boolean;
|
|
85
|
+
};
|
|
86
|
+
} | {
|
|
87
|
+
type: typeof UI_RESPONSE.RECEIVE_PREEMPTION;
|
|
88
|
+
payload: {
|
|
89
|
+
confirmed: boolean;
|
|
90
|
+
};
|
|
91
|
+
} | {
|
|
92
|
+
type: typeof UI_RESPONSE.RECEIVE_TREZOR_THP_PAIRING;
|
|
93
|
+
payload: {
|
|
94
|
+
selectedMethod?: number | string;
|
|
95
|
+
tag?: string;
|
|
96
|
+
};
|
|
97
|
+
} | {
|
|
98
|
+
type: typeof UI_RESPONSE.CANCEL;
|
|
99
|
+
payload?: undefined;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/** 10 min — every UI request is human-in-the-loop; bias toward "wait long". */
|
|
103
|
+
declare const UI_REQUEST_DEFAULT_TIMEOUT_MS = 600000;
|
|
104
|
+
declare const UI_REQUEST_PREEMPTED_TAG = "UiRequestPreempted";
|
|
105
|
+
declare const UI_REQUEST_CANCELLED_TAG = "UiRequestCancelled";
|
|
106
|
+
declare const UI_REQUEST_TIMEOUT_TAG = "UiRequestTimeout";
|
|
107
|
+
/**
|
|
108
|
+
* Per-type single-slot registry for adapter-level UI requests. A new `wait`
|
|
109
|
+
* of the same type supersedes (rejects) the prior pending entry. With the
|
|
110
|
+
* job queue running globally serially, cross-type collisions don't occur in
|
|
111
|
+
* normal flow — same-type preemption is a defensive measure for callers
|
|
112
|
+
* that fire the same request twice without waiting on the first.
|
|
113
|
+
*
|
|
114
|
+
* Unknown response types are dropped silently so the public `uiResponse`
|
|
115
|
+
* entry never throws.
|
|
116
|
+
*/
|
|
117
|
+
declare class UiRequestRegistry {
|
|
118
|
+
private pending;
|
|
119
|
+
wait<T = unknown>(requestType: string, options?: {
|
|
120
|
+
timeoutMs?: number;
|
|
121
|
+
}): Promise<T>;
|
|
122
|
+
resolve(responseType: string, payload: unknown): void;
|
|
123
|
+
cancel(requestType?: string): void;
|
|
124
|
+
reset(): void;
|
|
125
|
+
hasPending(requestType?: string): boolean;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export { type DevicePermissionDeniedReason as D, type QrDisplayData as Q, type UiResponseEvent as U, UI_REQUEST as a, type DevicePermissionResponse as b, type QrResponseData as c, UI_EVENT as d, UI_REQUEST_CANCELLED_TAG as e, UI_REQUEST_DEFAULT_TIMEOUT_MS as f, UI_REQUEST_PREEMPTED_TAG as g, UI_REQUEST_TIMEOUT_TAG as h, UI_RESPONSE as i, UiRequestRegistry as j };
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
interface QrDisplayData {
|
|
2
|
+
urType: string;
|
|
3
|
+
urData: string;
|
|
4
|
+
animated: boolean;
|
|
5
|
+
}
|
|
6
|
+
interface QrResponseData {
|
|
7
|
+
urType: string;
|
|
8
|
+
urData: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
declare const UI_EVENT = "UI_EVENT";
|
|
12
|
+
declare const UI_REQUEST: {
|
|
13
|
+
readonly REQUEST_PIN: "ui-request-pin";
|
|
14
|
+
readonly REQUEST_PASSPHRASE: "ui-request-passphrase";
|
|
15
|
+
readonly REQUEST_PASSPHRASE_ON_DEVICE: "ui-request-passphrase-on-device";
|
|
16
|
+
readonly REQUEST_BUTTON: "ui-request-button";
|
|
17
|
+
readonly REQUEST_QR_DISPLAY: "ui-request-qr-display";
|
|
18
|
+
readonly REQUEST_QR_SCAN: "ui-request-qr-scan";
|
|
19
|
+
readonly REQUEST_DEVICE_PERMISSION: "ui-request-device-permission";
|
|
20
|
+
readonly REQUEST_SELECT_DEVICE: "ui-request-select-device";
|
|
21
|
+
readonly REQUEST_DEVICE_CONNECT: "ui-request-device-connect";
|
|
22
|
+
readonly REQUEST_BTC_HIGH_INDEX_CONFIRM: "ui-request-btc-high-index-confirm";
|
|
23
|
+
readonly REQUEST_INSTALL_APP: "ui-request-install-app";
|
|
24
|
+
readonly REQUEST_PREEMPTION: "ui-request-preemption";
|
|
25
|
+
readonly REQUEST_TREZOR_THP_PAIRING: "ui-request-trezor-thp-pairing";
|
|
26
|
+
readonly CLOSE_UI_WINDOW: "ui-close";
|
|
27
|
+
readonly DEVICE_PROGRESS: "ui-device_progress";
|
|
28
|
+
readonly FIRMWARE_PROGRESS: "ui-firmware-progress";
|
|
29
|
+
readonly FIRMWARE_TIP: "ui-firmware-tip";
|
|
30
|
+
};
|
|
31
|
+
declare const UI_RESPONSE: {
|
|
32
|
+
readonly RECEIVE_PIN: "receive-pin";
|
|
33
|
+
readonly RECEIVE_PASSPHRASE: "receive-passphrase";
|
|
34
|
+
readonly RECEIVE_QR_RESPONSE: "receive-qr-response";
|
|
35
|
+
readonly RECEIVE_SELECT_DEVICE: "receive-select-device";
|
|
36
|
+
readonly RECEIVE_DEVICE_CONNECT: "receive-device-connect";
|
|
37
|
+
readonly RECEIVE_DEVICE_PERMISSION: "receive-device-permission";
|
|
38
|
+
readonly RECEIVE_BTC_HIGH_INDEX_CONFIRM: "receive-btc-high-index-confirm";
|
|
39
|
+
readonly RECEIVE_INSTALL_APP: "receive-install-app";
|
|
40
|
+
readonly RECEIVE_PREEMPTION: "receive-preemption";
|
|
41
|
+
readonly RECEIVE_TREZOR_THP_PAIRING: "receive-trezor-thp-pairing";
|
|
42
|
+
readonly CANCEL: "cancel";
|
|
43
|
+
};
|
|
44
|
+
type DevicePermissionDeniedReason = 'bluetoothTurnedOff' | 'permissionDenied' | (string & Record<never, never>);
|
|
45
|
+
type DevicePermissionResponse = {
|
|
46
|
+
granted: boolean;
|
|
47
|
+
reason?: DevicePermissionDeniedReason;
|
|
48
|
+
message?: string;
|
|
49
|
+
};
|
|
50
|
+
type UiResponseEvent = {
|
|
51
|
+
type: typeof UI_RESPONSE.RECEIVE_PIN;
|
|
52
|
+
payload: string;
|
|
53
|
+
} | {
|
|
54
|
+
type: typeof UI_RESPONSE.RECEIVE_PASSPHRASE;
|
|
55
|
+
payload: {
|
|
56
|
+
value: string;
|
|
57
|
+
passphraseOnDevice?: boolean;
|
|
58
|
+
save?: boolean;
|
|
59
|
+
};
|
|
60
|
+
} | {
|
|
61
|
+
type: typeof UI_RESPONSE.RECEIVE_QR_RESPONSE;
|
|
62
|
+
payload: QrResponseData;
|
|
63
|
+
} | {
|
|
64
|
+
type: typeof UI_RESPONSE.RECEIVE_SELECT_DEVICE;
|
|
65
|
+
payload: {
|
|
66
|
+
sdkConnectId: string;
|
|
67
|
+
};
|
|
68
|
+
} | {
|
|
69
|
+
type: typeof UI_RESPONSE.RECEIVE_DEVICE_CONNECT;
|
|
70
|
+
payload: {
|
|
71
|
+
confirmed: boolean;
|
|
72
|
+
};
|
|
73
|
+
} | {
|
|
74
|
+
type: typeof UI_RESPONSE.RECEIVE_DEVICE_PERMISSION;
|
|
75
|
+
payload: DevicePermissionResponse;
|
|
76
|
+
} | {
|
|
77
|
+
type: typeof UI_RESPONSE.RECEIVE_BTC_HIGH_INDEX_CONFIRM;
|
|
78
|
+
payload: {
|
|
79
|
+
confirmed: boolean;
|
|
80
|
+
};
|
|
81
|
+
} | {
|
|
82
|
+
type: typeof UI_RESPONSE.RECEIVE_INSTALL_APP;
|
|
83
|
+
payload: {
|
|
84
|
+
confirmed: boolean;
|
|
85
|
+
};
|
|
86
|
+
} | {
|
|
87
|
+
type: typeof UI_RESPONSE.RECEIVE_PREEMPTION;
|
|
88
|
+
payload: {
|
|
89
|
+
confirmed: boolean;
|
|
90
|
+
};
|
|
91
|
+
} | {
|
|
92
|
+
type: typeof UI_RESPONSE.RECEIVE_TREZOR_THP_PAIRING;
|
|
93
|
+
payload: {
|
|
94
|
+
selectedMethod?: number | string;
|
|
95
|
+
tag?: string;
|
|
96
|
+
};
|
|
97
|
+
} | {
|
|
98
|
+
type: typeof UI_RESPONSE.CANCEL;
|
|
99
|
+
payload?: undefined;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/** 10 min — every UI request is human-in-the-loop; bias toward "wait long". */
|
|
103
|
+
declare const UI_REQUEST_DEFAULT_TIMEOUT_MS = 600000;
|
|
104
|
+
declare const UI_REQUEST_PREEMPTED_TAG = "UiRequestPreempted";
|
|
105
|
+
declare const UI_REQUEST_CANCELLED_TAG = "UiRequestCancelled";
|
|
106
|
+
declare const UI_REQUEST_TIMEOUT_TAG = "UiRequestTimeout";
|
|
107
|
+
/**
|
|
108
|
+
* Per-type single-slot registry for adapter-level UI requests. A new `wait`
|
|
109
|
+
* of the same type supersedes (rejects) the prior pending entry. With the
|
|
110
|
+
* job queue running globally serially, cross-type collisions don't occur in
|
|
111
|
+
* normal flow — same-type preemption is a defensive measure for callers
|
|
112
|
+
* that fire the same request twice without waiting on the first.
|
|
113
|
+
*
|
|
114
|
+
* Unknown response types are dropped silently so the public `uiResponse`
|
|
115
|
+
* entry never throws.
|
|
116
|
+
*/
|
|
117
|
+
declare class UiRequestRegistry {
|
|
118
|
+
private pending;
|
|
119
|
+
wait<T = unknown>(requestType: string, options?: {
|
|
120
|
+
timeoutMs?: number;
|
|
121
|
+
}): Promise<T>;
|
|
122
|
+
resolve(responseType: string, payload: unknown): void;
|
|
123
|
+
cancel(requestType?: string): void;
|
|
124
|
+
reset(): void;
|
|
125
|
+
hasPending(requestType?: string): boolean;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export { type DevicePermissionDeniedReason as D, type QrDisplayData as Q, type UiResponseEvent as U, UI_REQUEST as a, type DevicePermissionResponse as b, type QrResponseData as c, UI_EVENT as d, UI_REQUEST_CANCELLED_TAG as e, UI_REQUEST_DEFAULT_TIMEOUT_MS as f, UI_REQUEST_PREEMPTED_TAG as g, UI_REQUEST_TIMEOUT_TAG as h, UI_RESPONSE as i, UiRequestRegistry as j };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { D as DevicePermissionDeniedReason, b as DevicePermissionResponse, d as UI_EVENT, a as UI_REQUEST, e as UI_REQUEST_CANCELLED_TAG, f as UI_REQUEST_DEFAULT_TIMEOUT_MS, g as UI_REQUEST_PREEMPTED_TAG, h as UI_REQUEST_TIMEOUT_TAG, i as UI_RESPONSE, j as UiRequestRegistry, U as UiResponseEvent } from './ui-events-Cb7haAeE.mjs';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { D as DevicePermissionDeniedReason, b as DevicePermissionResponse, d as UI_EVENT, a as UI_REQUEST, e as UI_REQUEST_CANCELLED_TAG, f as UI_REQUEST_DEFAULT_TIMEOUT_MS, g as UI_REQUEST_PREEMPTED_TAG, h as UI_REQUEST_TIMEOUT_TAG, i as UI_RESPONSE, j as UiRequestRegistry, U as UiResponseEvent } from './ui-events-Cb7haAeE.js';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
var _chunkBAGEFFFYjs = require('./chunk-BAGEFFFY.js');
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
exports.UI_EVENT = _chunkBAGEFFFYjs.UI_EVENT; exports.UI_REQUEST = _chunkBAGEFFFYjs.UI_REQUEST; exports.UI_REQUEST_CANCELLED_TAG = _chunkBAGEFFFYjs.UI_REQUEST_CANCELLED_TAG; exports.UI_REQUEST_DEFAULT_TIMEOUT_MS = _chunkBAGEFFFYjs.UI_REQUEST_DEFAULT_TIMEOUT_MS; exports.UI_REQUEST_PREEMPTED_TAG = _chunkBAGEFFFYjs.UI_REQUEST_PREEMPTED_TAG; exports.UI_REQUEST_TIMEOUT_TAG = _chunkBAGEFFFYjs.UI_REQUEST_TIMEOUT_TAG; exports.UI_RESPONSE = _chunkBAGEFFFYjs.UI_RESPONSE; exports.UiRequestRegistry = _chunkBAGEFFFYjs.UiRequestRegistry;
|
|
21
|
+
//# sourceMappingURL=ui-events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/hardware-js-sdk/hardware-js-sdk/packages/hwk-adapter-core/dist/ui-events.js"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,sDAA4B;AAC5B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,ihBAAC","file":"/home/runner/work/hardware-js-sdk/hardware-js-sdk/packages/hwk-adapter-core/dist/ui-events.js"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
UI_EVENT,
|
|
3
|
+
UI_REQUEST,
|
|
4
|
+
UI_REQUEST_CANCELLED_TAG,
|
|
5
|
+
UI_REQUEST_DEFAULT_TIMEOUT_MS,
|
|
6
|
+
UI_REQUEST_PREEMPTED_TAG,
|
|
7
|
+
UI_REQUEST_TIMEOUT_TAG,
|
|
8
|
+
UI_RESPONSE,
|
|
9
|
+
UiRequestRegistry
|
|
10
|
+
} from "./chunk-U63HTLGJ.mjs";
|
|
11
|
+
export {
|
|
12
|
+
UI_EVENT,
|
|
13
|
+
UI_REQUEST,
|
|
14
|
+
UI_REQUEST_CANCELLED_TAG,
|
|
15
|
+
UI_REQUEST_DEFAULT_TIMEOUT_MS,
|
|
16
|
+
UI_REQUEST_PREEMPTED_TAG,
|
|
17
|
+
UI_REQUEST_TIMEOUT_TAG,
|
|
18
|
+
UI_RESPONSE,
|
|
19
|
+
UiRequestRegistry
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=ui-events.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|