@onekeyfe/hwk-keystone-adapter 1.2.2-alpha.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/urEngine/KeystoneUrEngine.ts","../src/urEngine/TronSignRequest.ts","../src/urEngine/TronSignature.ts","../src/adapter/KeystoneAdapter.ts","../src/adapter/pathUtils.ts","../src/adapter/deviceTable.ts"],"sourcesContent":["// UR engine (used by the QR event loop and the USB connector alike — both\n// channels carry the same UR payloads).\nexport { KeystoneUrEngine } from './urEngine/KeystoneUrEngine';\nexport type {\n BtcScriptType,\n KeystoneBtcSignatureResult,\n KeystoneBtcSignRequestAccount,\n KeystoneDerivationCurve,\n KeystoneEthSignatureResult,\n KeystoneEthSignRequestInput,\n KeystoneKeyDerivationRequestInput,\n KeystoneKeySchema,\n KeystoneParsedAccount,\n KeystoneParsedMultiAccounts,\n KeystoneSolSignatureResult,\n KeystoneSolSignRequestInput,\n KeystoneTronSignatureResult,\n KeystoneTronSignRequestInput,\n KeystoneUr,\n} from './urEngine/types';\n\n// Adapter\nexport { KeystoneAdapter } from './adapter/KeystoneAdapter';\nexport type { ImportFromQrOptions } from './adapter/KeystoneAdapter';\nexport {\n accountKey,\n createDeviceRecord,\n placeholderDeviceInfo,\n qrConnectId,\n toDeviceInfo,\n QR_CONNECT_ID_PREFIX,\n} from './adapter/deviceTable';\nexport type { KeystoneAccountEntry, KeystoneDeviceRecord } from './adapter/deviceTable';\nexport { btcScriptTypeFromPath, normalizePath, splitAccountPath } from './adapter/pathUtils';\n","import { generateAddressFromXpub } from '@keystonehq/bc-ur-registry-eth';\nimport { Curve, KeystoneSDK, QRHardwareCallVersion, UR } from '@keystonehq/keystone-sdk';\nimport bs58check from 'bs58check';\nimport * as bitcoin from 'bitcoinjs-lib';\nimport HDKey from 'hdkey';\nimport { parse as uuidParse, stringify as uuidStringify } from 'uuid';\n\nimport { TronSignRequest, TronSignType } from './TronSignRequest';\nimport { TronSignature } from './TronSignature';\n\nimport type {\n BtcScriptType,\n KeystoneBtcSignRequestAccount,\n KeystoneBtcSignatureResult,\n KeystoneEthSignRequestInput,\n KeystoneEthSignatureResult,\n KeystoneKeyDerivationRequestInput,\n KeystoneParsedAccount,\n KeystoneParsedMultiAccounts,\n KeystoneSolSignRequestInput,\n KeystoneSolSignatureResult,\n KeystoneTronSignRequestInput,\n KeystoneTronSignatureResult,\n KeystoneUr,\n} from './types';\n\n/** TRON's own address-version byte, prepended before base58check encoding. */\nconst TRON_ADDRESS_PREFIX = 0x41;\n\nfunction stripHexPrefix(hex: string): string {\n return hex.replace(/^0x/i, '');\n}\n\nconst ETH_DATA_TYPE = {\n transaction: 1,\n typedData: 2,\n personalMessage: 3,\n typedTransaction: 4,\n} as const;\n\nconst DERIVATION_CURVE = {\n secp256k1: Curve.secp256k1,\n ed25519: Curve.ed25519,\n} as const;\n\nfunction toSdkUr(ur: KeystoneUr): UR {\n return new UR(Buffer.from(ur.urData, 'hex'), ur.urType);\n}\n\nfunction fromSdkUr(ur: UR): KeystoneUr {\n return { urType: ur.type, urData: ur.cbor.toString('hex') };\n}\n\nfunction splitSignature65(hex: string): { r: string; s: string; v: string } {\n return { r: hex.slice(0, 64), s: hex.slice(64, 128), v: hex.slice(128) };\n}\n\n/**\n * Thin wrapper around `@keystonehq/keystone-sdk`. Owns every touch point with the\n * vendor SDK so the rest of the adapter never imports it directly: same UR\n * construction/parsing serves both the QR and USB channels (USB carries the\n * identical UR payloads inside EAPDU framing — see the Keystone USB SDK's\n * `sendURRequest`), so this engine has no channel awareness at all.\n *\n * Deliberately uses the bare constructor, never `KeystoneSDK.create()` — `create()`\n * fetches remote fragment-size config from keyst.one at call time, which this SDK\n * must not depend on.\n */\nexport class KeystoneUrEngine {\n private readonly sdk: KeystoneSDK;\n\n constructor(origin = 'OneKey') {\n this.sdk = new KeystoneSDK({ origin });\n }\n\n // --- Account sync (works for both a device-initiated QR export and a\n // wallet-initiated KeyDerivation request/response over either channel) ---\n\n parseMultiAccounts(ur: KeystoneUr): KeystoneParsedMultiAccounts {\n const parsed = this.sdk.parseMultiAccounts(toSdkUr(ur));\n return {\n masterFingerprint: parsed.masterFingerprint.toLowerCase(),\n device: parsed.device,\n deviceId: parsed.deviceId,\n deviceVersion: parsed.deviceVersion,\n accounts: parsed.keys.map(\n (key): KeystoneParsedAccount => ({\n chain: key.chain,\n path: key.path,\n publicKey: key.publicKey,\n extendedPublicKey: key.extendedPublicKey,\n xfp: key.xfp,\n name: key.name,\n })\n ),\n };\n }\n\n parseHDKey(ur: KeystoneUr): KeystoneParsedAccount {\n const key = this.sdk.parseHDKey(toSdkUr(ur));\n return {\n chain: key.chain,\n path: key.path,\n publicKey: key.publicKey,\n extendedPublicKey: key.extendedPublicKey,\n xfp: key.xfp,\n name: key.name,\n };\n }\n\n /**\n * Build a `qr-hardware-call` (KeyDerivation) request: the host asks for\n * specific paths instead of waiting for whatever the device happens to be\n * showing. The device replies with a `crypto-multi-accounts` UR — parse it\n * with `parseMultiAccounts`. Used for the implicit \"sync this wallet's xfp\n * before the first sign\" round trip as well as an explicit account import.\n *\n * `version: V1` is required — verified against real Keystone hardware and\n * `keystone3-firmware`'s `CheckHardwareCallRequestIsLegal` source: an\n * unversioned/V0 request is validated as a legacy Cardano-only request\n * (`m/1852'/1815'/...`) and firmware rejects every other chain's path with\n * `PRS_PARSING_ERROR` (device-shown message: \"路径不受支持\" / \"path not\n * supported\"), regardless of the path's shape. V1 is what actually enables\n * the general per-chain path whitelist (includes `m/44'/60'` for ETH, the\n * standard BTC purposes, etc.). The SDK itself defaults to V0 unless a\n * truthy `version` is passed — omitting this silently produces a request\n * every non-Cardano device rejects.\n */\n buildKeyDerivationRequest(input: KeystoneKeyDerivationRequestInput): KeystoneUr {\n const ur = this.sdk.generateKeyDerivationCall({\n schemas: input.schemas.map(schema => ({\n path: schema.path,\n curve: DERIVATION_CURVE[schema.curve ?? 'secp256k1'],\n })),\n origin: input.origin,\n version: QRHardwareCallVersion.V1,\n });\n return fromSdkUr(ur);\n }\n\n /**\n * Parse the response to a KeyDerivation request (or a device-initiated\n * account export): `crypto-multi-accounts` for a multi-schema request,\n * `crypto-hdkey` for a single-key response some firmware paths use instead.\n * Both are normalized to the same `KeystoneParsedMultiAccounts` shape — a\n * single `crypto-hdkey` becomes a one-entry account list, with its own\n * `origin.sourceFingerprint` promoted to `masterFingerprint` (correct for a\n * key derived directly from the seed, which every request this engine\n * builds asks for).\n */\n parseAccountResponse(ur: KeystoneUr): KeystoneParsedMultiAccounts {\n if (ur.urType === 'crypto-hdkey') {\n const account = this.parseHDKey(ur);\n if (!account.xfp) {\n throw new Error('Keystone crypto-hdkey response is missing its source fingerprint');\n }\n return { masterFingerprint: account.xfp.toLowerCase(), accounts: [account] };\n }\n return this.parseMultiAccounts(ur);\n }\n\n // --- EVM ---\n\n buildEthSignRequest(input: KeystoneEthSignRequestInput): KeystoneUr {\n const ur = this.sdk.eth.generateSignRequest({\n requestId: input.requestId,\n signData: input.unsignedTxHex,\n dataType: ETH_DATA_TYPE[input.dataType],\n path: input.path,\n xfp: input.xfp,\n chainId: input.chainId,\n address: input.address,\n origin: input.origin,\n });\n return fromSdkUr(ur);\n }\n\n parseEthSignature(ur: KeystoneUr): KeystoneEthSignatureResult {\n const signature = this.sdk.eth.parseSignature(toSdkUr(ur));\n return { requestId: signature.requestId, ...splitSignature65(signature.signature) };\n }\n\n /**\n * Derive one EVM address offline from an already-synced account xpub —\n * verified against the same `@keystonehq/bc-ur-registry-eth` helper the\n * Keystone-based OneKey air-gap demo uses in production\n * (`generateAddressFromXpub`), so no unverified assumption about what a\n * leaf-path KeyDerivation request would return. `relativeDerivePath` is\n * relative to the xpub's own depth, e.g. `'0/0'` for an account xpub.\n */\n deriveEvmAddressFromXpub(xpub: string, relativeDerivePath: string): string {\n return generateAddressFromXpub(xpub, `m/${relativeDerivePath.replace(/^m\\//i, '')}`);\n }\n\n // --- BTC (PSBT transaction signing + plain message signing) ---\n\n /**\n * Derive one BTC address offline from an already-synced account xpub, the\n * same way `deriveEvmAddressFromXpub` does. Keystone's `CryptoHDKey`\n * always emits standard mainnet-xpub version bytes (`0488B21E`) regardless\n * of the account's purpose/script type (verified against\n * `@keystonehq/bc-ur-registry`'s `CryptoHDKey.getBip32Key`, which hardcodes\n * that version rather than switching to a SLIP-132 ypub/zpub prefix per\n * script type) — so `hdkey.fromExtendedKey` parses it correctly for every\n * `scriptType` without needing custom version bytes configured.\n *\n * `p2tr` is deliberately not handled: taproot output-key tweaking (BIP-341)\n * needs an elliptic-curve library wired via bitcoinjs-lib's `initEccLib`,\n * which this package doesn't set up yet — every other payment function\n * here needs no such library.\n */\n deriveBtcAddressFromXpub(\n xpub: string,\n relativeDerivePath: string,\n scriptType: BtcScriptType\n ): string {\n const node = HDKey.fromExtendedKey(xpub).derive(`m/${relativeDerivePath.replace(/^m\\//i, '')}`);\n if (!node.publicKey) throw new Error('HDKey derivation did not produce a public key');\n const pubkey = Buffer.from(node.publicKey);\n const network = bitcoin.networks.bitcoin;\n\n switch (scriptType) {\n case 'p2pkh': {\n const { address } = bitcoin.payments.p2pkh({ pubkey, network });\n if (!address) throw new Error('Failed to derive a P2PKH address from this xpub');\n return address;\n }\n case 'p2sh-p2wpkh': {\n const { address } = bitcoin.payments.p2sh({\n redeem: bitcoin.payments.p2wpkh({ pubkey, network }),\n network,\n });\n if (!address) throw new Error('Failed to derive a P2SH-P2WPKH address from this xpub');\n return address;\n }\n case 'p2wpkh': {\n const { address } = bitcoin.payments.p2wpkh({ pubkey, network });\n if (!address) throw new Error('Failed to derive a P2WPKH address from this xpub');\n return address;\n }\n case 'p2tr':\n throw new Error(\n 'BTC P2TR (taproot) address derivation is not supported yet — needs an elliptic-curve library for BIP-341 tweaking'\n );\n default: {\n const exhaustive: never = scriptType;\n throw new Error(`Unsupported BTC script type: ${String(exhaustive)}`);\n }\n }\n }\n\n buildBtcPsbtRequest(unsignedPsbtHex: string): KeystoneUr {\n const ur = this.sdk.btc.generatePSBT(Buffer.from(unsignedPsbtHex, 'hex'));\n return fromSdkUr(ur);\n }\n\n /** Returns the hex-encoded (possibly still-unsigned-in-part) PSBT the device replied with. */\n parseBtcPsbt(ur: KeystoneUr): string {\n return this.sdk.btc.parsePSBT(toSdkUr(ur));\n }\n\n buildBtcMessageSignRequest(params: {\n requestId: string;\n /** Hex, no 0x prefix. */\n messageHex: string;\n accounts: KeystoneBtcSignRequestAccount[];\n origin?: string;\n }): KeystoneUr {\n const ur = this.sdk.btc.generateSignRequest({\n requestId: params.requestId,\n signData: params.messageHex,\n dataType: 1, // BtcSignRequest.DataType.message — PSBT signing never goes through this path.\n accounts: params.accounts,\n origin: params.origin,\n });\n return fromSdkUr(ur);\n }\n\n parseBtcSignature(ur: KeystoneUr): KeystoneBtcSignatureResult {\n const signature = this.sdk.btc.parseSignature(toSdkUr(ur));\n return {\n requestId: signature.requestId,\n publicKey: signature.publicKey,\n signature: signature.signature,\n };\n }\n\n // --- SOL ---\n\n buildSolSignRequest(input: KeystoneSolSignRequestInput): KeystoneUr {\n const ur = this.sdk.sol.generateSignRequest({\n requestId: input.requestId,\n signData: input.unsignedPayloadHex,\n dataType: input.dataType === 'transaction' ? 1 : 2,\n path: input.path,\n xfp: input.xfp,\n address: input.address,\n origin: input.origin,\n });\n return fromSdkUr(ur);\n }\n\n parseSolSignature(ur: KeystoneUr): KeystoneSolSignatureResult {\n const signature = this.sdk.sol.parseSignature(toSdkUr(ur));\n return { requestId: signature.requestId, signature: signature.signature };\n }\n\n // --- TRON ---\n\n /**\n * `@keystonehq/keystone-sdk`'s own bundled `sdk.tron` module is\n * deliberately NOT used here — see `TronSignRequest.ts`'s doc comment for\n * why: it's a different (gzip/protobuf) protocol with response semantics\n * this package has no way to verify, whereas `TronSignRequest`/\n * `TronSignature` are a direct port of OneKey's own already-proven\n * production QR-wallet TRON implementation (a plain CBOR-native\n * sign-request/signature pair, same shape as eth/sol). The device decodes\n * `rawTxHex` itself — no client-side contract-type pre-parsing or\n * `tokenInfo` needed, unlike the public SDK's module.\n */\n buildTronSignRequest(input: KeystoneTronSignRequestInput): KeystoneUr {\n const request = new TronSignRequest({\n requestId: Buffer.from(uuidParse(input.requestId) as Uint8Array),\n signData: Buffer.from(stripHexPrefix(input.rawTxHex), 'hex'),\n signType: TronSignType.Transaction,\n derivationPath: TronSignRequest.parsePath(input.path, input.xfp),\n origin: input.origin,\n });\n return fromSdkUr(request.toUR());\n }\n\n parseTronSignature(ur: KeystoneUr): KeystoneTronSignatureResult {\n if (ur.urType !== 'tron-signature') {\n throw new Error(`Expected a tron-signature UR, got ${ur.urType}`);\n }\n const signature = TronSignature.fromCBOR(Buffer.from(ur.urData, 'hex'));\n const requestId = signature.getRequestId();\n return {\n requestId: requestId ? uuidStringify(requestId) : undefined,\n signature: signature.getSignature().toString('hex'),\n };\n }\n\n /**\n * Derive one TRON address offline from an already-synced account xpub.\n * TRON reuses EVM's exact secp256k1-pubkey → keccak256 → last-20-bytes\n * derivation (verified against Keystone's own `formatAddress()` in\n * `keystone-sdk`'s TRON chain source) — only the final text encoding\n * differs (base58check with a `0x41` version byte, not checksummed hex).\n * Reusing `generateAddressFromXpub` here means no new hashing dependency:\n * strip its \"0x\" and re-encode the same 20 bytes.\n */\n deriveTronAddressFromXpub(xpub: string, relativeDerivePath: string): string {\n const evmStyleHex = generateAddressFromXpub(\n xpub,\n `m/${relativeDerivePath.replace(/^m\\//i, '')}`\n ) as string;\n const addressBytes = Buffer.concat([\n Buffer.from([TRON_ADDRESS_PREFIX]),\n Buffer.from(evmStyleHex.replace(/^0x/i, ''), 'hex'),\n ]);\n return bs58check.encode(addressBytes);\n }\n}\n","import {\n CryptoKeypath,\n DataItem,\n PathComponent,\n RegistryItem,\n RegistryType,\n RegistryTypes,\n extend,\n} from '@keystonehq/bc-ur-registry';\n\nimport type { DataItemMap } from '@keystonehq/bc-ur-registry';\n\nconst { decodeToDataItem } = extend;\n\n/**\n * `@keystonehq/keystone-sdk`'s own bundled `sdk.tron` module builds TRON\n * requests through a completely different, gzip-compressed protobuf\n * envelope (`KeystoneSignRequest`/`KeystoneSignResult`, registry type\n * `keystone-sign-result`) — no bare signature field, response semantics\n * unverified against real hardware. `packages/qr-wallet-sdk` (OneKey's own\n * production QR-wallet integration, in the separate app-monorepo — proven\n * against real Keystone devices) does NOT use that module at all: it rolls\n * its own minimal CBOR-native UR pair, `tron-sign-request`/`tron-signature`,\n * built directly on the same `@keystonehq/bc-ur-registry` primitives the\n * eth/sol sign-request classes use — same shape as everywhere else, with a\n * genuine bare `signature` field (see `TronSignature.ts`). This class is a\n * direct port of that proven implementation (registry type 5201 matches\n * exactly), not the public SDK's own (unverified) tron module.\n */\nconst TRON_SIGN_REQUEST_TYPE = new RegistryType('tron-sign-request', 5201);\n\nenum RequestKeys {\n requestId = 1,\n signData,\n derivationPath,\n address,\n origin,\n signType,\n}\n\nexport enum TronSignType {\n Transaction = 0,\n SignMessage = 1,\n SignMessageV2 = 2,\n}\n\ninterface TronSignRequestProps {\n requestId?: Buffer;\n signData: Buffer;\n signType: TronSignType;\n derivationPath: CryptoKeypath;\n address?: Buffer;\n origin?: string;\n}\n\nexport class TronSignRequest extends RegistryItem {\n private readonly requestId?: Buffer;\n\n private readonly signData: Buffer;\n\n private readonly signType: TronSignType;\n\n private readonly derivationPath: CryptoKeypath;\n\n private readonly address?: Buffer;\n\n private readonly origin?: string;\n\n getRegistryType = (): RegistryType => TRON_SIGN_REQUEST_TYPE;\n\n constructor(args: TronSignRequestProps) {\n super();\n this.requestId = args.requestId;\n this.signData = args.signData;\n this.derivationPath = args.derivationPath;\n this.address = args.address;\n this.origin = args.origin;\n this.signType = args.signType;\n }\n\n getRequestId = (): Buffer | undefined => this.requestId;\n\n getSignData = (): Buffer => this.signData;\n\n getSignType = (): TronSignType => this.signType;\n\n getDerivationPath = (): string => this.derivationPath.getPath();\n\n toDataItem = (): DataItem => {\n const map: DataItemMap = {};\n if (this.requestId) {\n map[RequestKeys.requestId] = new DataItem(this.requestId, RegistryTypes.UUID.getTag());\n }\n if (this.address) map[RequestKeys.address] = this.address;\n if (this.origin) map[RequestKeys.origin] = this.origin;\n map[RequestKeys.signData] = this.signData;\n map[RequestKeys.signType] = this.signType;\n const keyPath = this.derivationPath.toDataItem();\n keyPath.setTag(this.derivationPath.getRegistryType().getTag());\n map[RequestKeys.derivationPath] = keyPath;\n return new DataItem(map);\n };\n\n static fromDataItem(dataItem: DataItem): TronSignRequest {\n const map = dataItem.getData() as Record<number, unknown>;\n const signData = map[RequestKeys.signData] as Buffer;\n const derivationPath = CryptoKeypath.fromDataItem(map[RequestKeys.derivationPath] as DataItem);\n const address = map[RequestKeys.address] as Buffer | undefined;\n const requestIdItem = map[RequestKeys.requestId] as DataItem | undefined;\n const requestId = requestIdItem?.getData() as Buffer | undefined;\n const origin = map[RequestKeys.origin] as string | undefined;\n const signType = map[RequestKeys.signType] as TronSignType;\n return new TronSignRequest({ requestId, signData, derivationPath, address, origin, signType });\n }\n\n static fromCBOR(cborPayload: Buffer): TronSignRequest {\n return TronSignRequest.fromDataItem(decodeToDataItem(cborPayload));\n }\n\n static parsePath(path: string, xfp: string): CryptoKeypath {\n const segments = path.replace(/^[mM]\\//, '').split('/');\n const components = segments.map(segment => {\n const hardened = segment.endsWith(\"'\");\n return new PathComponent({\n index: parseInt(hardened ? segment.slice(0, -1) : segment, 10),\n hardened,\n });\n });\n return new CryptoKeypath(components, Buffer.from(xfp, 'hex'));\n }\n}\n","import {\n DataItem,\n RegistryItem,\n RegistryType,\n RegistryTypes,\n extend,\n} from '@keystonehq/bc-ur-registry';\n\nimport type { DataItemMap } from '@keystonehq/bc-ur-registry';\n\nconst { decodeToDataItem } = extend;\n\n/** See `TronSignRequest.ts`'s doc comment — same proven, CBOR-native pair (registry type 5202). */\nconst TRON_SIGNATURE_TYPE = new RegistryType('tron-signature', 5202);\n\nenum SignatureKeys {\n requestId = 1,\n signature,\n}\n\nexport class TronSignature extends RegistryItem {\n private readonly requestId?: Buffer;\n\n private readonly signatureBytes: Buffer;\n\n getRegistryType = (): RegistryType => TRON_SIGNATURE_TYPE;\n\n constructor(signature: Buffer, requestId?: Buffer) {\n super();\n this.signatureBytes = signature;\n this.requestId = requestId;\n }\n\n getRequestId = (): Buffer | undefined => this.requestId;\n\n getSignature = (): Buffer => this.signatureBytes;\n\n toDataItem = (): DataItem => {\n const map: DataItemMap = {};\n if (this.requestId) {\n map[SignatureKeys.requestId] = new DataItem(this.requestId, RegistryTypes.UUID.getTag());\n }\n map[SignatureKeys.signature] = this.signatureBytes;\n return new DataItem(map);\n };\n\n static fromDataItem(dataItem: DataItem): TronSignature {\n const map = dataItem.getData() as Record<number, unknown>;\n const signature = map[SignatureKeys.signature] as Buffer;\n const requestIdItem = map[SignatureKeys.requestId] as DataItem | undefined;\n const requestId = requestIdItem?.getData() as Buffer | undefined;\n return new TronSignature(signature, requestId);\n }\n\n static fromCBOR(cborPayload: Buffer): TronSignature {\n return TronSignature.fromDataItem(decodeToDataItem(cborPayload));\n }\n}\n","import bs58 from 'bs58';\nimport { v4 as uuidv4 } from 'uuid';\nimport {\n CHAIN_FINGERPRINT_PATHS,\n DEVICE,\n DeviceJobQueue,\n HardwareErrorCode,\n TypedEventEmitter,\n UI_REQUEST,\n UI_REQUEST_CANCELLED_TAG,\n UI_REQUEST_PREEMPTED_TAG,\n UI_REQUEST_TIMEOUT_TAG,\n UI_RESPONSE,\n UiRequestRegistry,\n createHwkError,\n deriveDeviceFingerprint,\n ensure0x,\n failure,\n rehydrateConnectorError,\n runAllNetworkGetAddress,\n stripHex,\n success,\n} from '@onekeyfe/hwk-adapter-core';\n\nimport { KeystoneUrEngine } from '../urEngine/KeystoneUrEngine';\nimport {\n QR_CONNECT_ID_PREFIX,\n accountKey,\n createDeviceRecord,\n placeholderDeviceInfo,\n toDeviceInfo,\n} from './deviceTable';\nimport { btcScriptTypeFromPath, normalizePath, splitAccountPath } from './pathUtils';\n\nimport type { KeystoneParsedMultiAccounts, KeystoneUr } from '../urEngine/types';\nimport type { KeystoneAccountEntry, KeystoneDeviceRecord } from './deviceTable';\nimport type {\n AllNetworkAddressResponse,\n AllNetworkGetAddressParams,\n BtcAddress,\n BtcGetAddressParams,\n BtcGetPublicKeyParams,\n BtcPublicKey,\n BtcSignMsgParams,\n BtcSignPsbtParams,\n BtcSignTxParams,\n BtcSignature,\n BtcSignedPsbt,\n BtcSignedTx,\n ChainCapability,\n ChainForFingerprint,\n ConnectorDevice,\n DeviceEventListener,\n DeviceInfo,\n EvmAddress,\n EvmGetAddressParams,\n EvmSignMsgParams,\n EvmSignTxParams,\n EvmSignTypedDataParams,\n EvmSignature,\n EvmSignedTx,\n HardwareEvent,\n HardwareEventMap,\n IConnector,\n IHardwareCallParams,\n IHardwareWallet,\n NullableCallArg,\n QrDisplayData,\n Response,\n SearchDevicesOptions,\n SolAddress,\n SolGetAddressParams,\n SolSignMsgParams,\n SolSignTxParams,\n SolSignature,\n SolSignedTx,\n TransportType,\n TronAddress,\n TronGetAddressParams,\n TronSignMsgParams,\n TronSignTxParams,\n TronSignature,\n TronSignedTx,\n UiResponseEvent,\n} from '@onekeyfe/hwk-adapter-core';\n\nconst COLD_START_JOB_LABEL = 'keystone-cold-start';\n\nconst BIP44_COIN_TYPE_TO_CHAIN: Record<number, ChainCapability> = {\n 60: 'evm',\n 0: 'btc',\n 501: 'sol',\n 195: 'tron',\n};\n\n/**\n * Classifies a returned account by its BIP44 COIN TYPE (2nd path segment),\n * not the purpose (1st segment, 44'/49'/84'/86'/…). Fixed from an earlier\n * version that matched purpose 44' literally, which would silently drop\n * ANY response entry using a different purpose — including\n * `DEFAULT_IMPORT_SCHEMAS`'s own 49'/84' BTC requests below, since this\n * function decides which hwkChain a returned account belongs to regardless\n * of what was explicitly asked for.\n */\nfunction inferHwkChainFromPath(path: string): ChainCapability | undefined {\n const match = normalizePath(path).match(/^m\\/\\d+'\\/(\\d+)'/);\n return match ? BIP44_COIN_TYPE_TO_CHAIN[Number(match[1])] : undefined;\n}\n\nconst DEFAULT_IMPORT_SCHEMAS: Array<{ hwkChain: ChainCapability; path: string }> = [\n { hwkChain: 'evm', path: CHAIN_FINGERPRINT_PATHS.evm.replace(/\\/0\\/0$/, '') },\n // The 3 BTC purposes this package can actually derive addresses for\n // (btcScriptTypeFromPath: 44'→P2PKH, 49'→P2SH-P2WPKH, 84'→P2WPKH) —\n // explicitly requested, not left to chance on whether the device\n // volunteers the others unprompted. Still one combined round trip: these\n // are 3 more entries in the same qr-hardware-call, not 3 more scans.\n // 86' (P2TR/taproot) deliberately excluded — `deriveBtcAddressFromXpub`\n // can't use it yet (needs an elliptic-curve library not wired in), and\n // unlike app-monorepo's own sync-all bundle (which also requests 86', but\n // to compute a \"full xfp\" — a need this adapter doesn't have, since its\n // mfp already comes for free from the response envelope), there's no\n // other use for that xpub here — so it stays out until P2TR is real.\n { hwkChain: 'btc', path: CHAIN_FINGERPRINT_PATHS.btc },\n { hwkChain: 'btc', path: \"m/49'/0'/0'\" },\n { hwkChain: 'btc', path: \"m/84'/0'/0'\" },\n { hwkChain: 'sol', path: CHAIN_FINGERPRINT_PATHS.sol },\n { hwkChain: 'tron', path: CHAIN_FINGERPRINT_PATHS.tron.replace(/\\/0\\/0$/, '') },\n];\n\nexport interface ImportFromQrOptions {\n /**\n * 'request': host asks for specific paths via a `qr-hardware-call`\n * (KeyDerivation) UR — precise, works regardless of what screen the device\n * is on. 'scan': just wait for whatever multi-account/HD-key export the\n * device is already showing. Defaults to 'request' with `paths`, or the\n * default EVM/BTC/SOL account set if `paths` is omitted.\n */\n mode?: 'request' | 'scan';\n paths?: Array<{ hwkChain: ChainCapability; path: string }>;\n}\n\n/**\n * Keystone hardware wallet adapter — QR and USB channels merged behind one\n * `IHardwareWallet` surface, keyed by the wallet's master fingerprint (mfp):\n * a caller sees the same `evmSignTransaction(...)` call regardless of which\n * channel actually carries it. Internally, a chain method's UR round trip\n * either drives one or two `REQUEST_QR_DISPLAY`/`REQUEST_QR_SCAN` UI events\n * (QR) or a direct `IConnector.call(sessionId, 'resolveUr', ur)` (USB) — see\n * `_resolveUr`.\n *\n * QR needs no physical enumeration or explicit connect step: a caller can\n * call any chain method with `connectId`/`deviceId` both null and the\n * adapter drives its own implicit cold-start sync. USB is the opposite —\n * WebUSB device pickers require a user gesture, so a USB session only comes\n * into existence via an explicit `searchDevices()` + `connectDevice()` (see\n * `_connectUsb`). Once a USB session exists for a wallet's mfp, later calls\n * for that same wallet route over USB automatically (unless pinned via\n * `switchTransport`) — matching docs/design/keystone-integration/README.md §4.3.\n */\nexport class KeystoneAdapter implements IHardwareWallet {\n readonly vendor = 'keystone' as const;\n\n private readonly urEngine: KeystoneUrEngine;\n\n private readonly emitter = new TypedEventEmitter<HardwareEventMap>();\n\n private readonly _uiRegistry = new UiRequestRegistry();\n\n private readonly _jobQueue: DeviceJobQueue;\n\n private readonly _devices = new Map<string, KeystoneDeviceRecord>();\n\n private readonly _origin: string;\n\n /** How long to wait for the app to answer a `REQUEST_QR_DISPLAY`/`REQUEST_QR_SCAN` before failing. Defaults to the registry's own 10-minute default. */\n private readonly _qrTimeoutMs: number | undefined;\n\n /** Optional USB `IConnector` — supplied by the host app (DI, same pattern as Trezor/Ledger), e.g. via `createKeystoneWebUsbConnector()` from `@onekeyfe/hwk-keystone-connector-usb`. Undefined means QR-only. */\n private readonly _usbConnector: IConnector | undefined;\n\n /** Explicit `switchTransport` pin. `undefined` means \"auto\": USB when a live session exists for the target wallet, else QR. */\n private _forcedTransport: 'qr' | 'usb' | undefined;\n\n constructor(options?: { origin?: string; qrTimeoutMs?: number; usbConnector?: IConnector }) {\n this._origin = options?.origin ?? 'OneKey';\n this._qrTimeoutMs = options?.qrTimeoutMs;\n this.urEngine = new KeystoneUrEngine(this._origin);\n this._jobQueue = new DeviceJobQueue();\n this._usbConnector = options?.usbConnector;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle / transport\n // ---------------------------------------------------------------------------\n\n get activeTransport(): TransportType | null {\n if (this._devices.size === 0) return null;\n const hasUsbSession = Array.from(this._devices.values()).some(r => r.usbSessionId);\n return hasUsbSession ? 'usb' : 'qr';\n }\n\n getAvailableTransports(): TransportType[] {\n return this._usbConnector ? ['qr', 'usb'] : ['qr'];\n }\n\n /** Pins subsequent calls to 'qr' or 'usb' (routing otherwise defaults to \"USB when the target wallet has a live session, else QR\" — see `_resolveUr`). Any other value clears the pin back to auto. */\n switchTransport(type: TransportType): Promise<void> {\n this._forcedTransport = type === 'qr' || type === 'usb' ? type : undefined;\n return Promise.resolve();\n }\n\n init(_config?: unknown): Promise<void> {\n return Promise.resolve();\n }\n\n dispose(): Promise<void> {\n this._uiRegistry.cancel();\n this._jobQueue.clear();\n this.emitter.removeAllListeners();\n this._devices.clear();\n this._usbConnector?.reset();\n return Promise.resolve();\n }\n\n // ---------------------------------------------------------------------------\n // Device table\n // ---------------------------------------------------------------------------\n\n /**\n * QR-synced wallets are always included (this instance's own state — no\n * enumeration exists for QR). When a USB connector is configured, its raw\n * scan results are appended as-is: a USB descriptor has no mfp until\n * `connectDevice()` actually opens+claims it (see\n * `KeystoneUsbConnectorBase.searchDevices`), so these entries carry an\n * empty `deviceId` and exist purely so a host can list \"plugged in, click\n * to connect\" candidates.\n */\n async searchDevices(_options?: SearchDevicesOptions): Promise<DeviceInfo[]> {\n const known = Array.from(this._devices.values()).map(toDeviceInfo);\n if (!this._usbConnector) return known;\n\n let usbDevices: ConnectorDevice[];\n try {\n usbDevices = await this._usbConnector.searchDevices();\n } catch {\n // A USB scan failing (no WebUSB support, permission not yet granted,\n // etc.) must not sink the QR-known devices this instance already has.\n return known;\n }\n const placeholders: DeviceInfo[] = usbDevices.map(d => ({\n vendor: 'keystone',\n model: d.model ?? 'unknown',\n modelName: d.modelName,\n firmwareVersion: '0.0.0',\n deviceId: d.deviceId,\n connectId: d.connectId,\n connectionType: 'usb',\n capabilities: d.capabilities ?? { persistentDeviceIdentity: true },\n }));\n return [...known, ...placeholders];\n }\n\n async connectDevice(connectId: string): Promise<Response<string>> {\n const existing = this._findByConnectId(connectId);\n if (existing) return success(existing.connectId);\n // Not a wallet this instance already knows about — the only other\n // legitimate case is a USB scan placeholder (see `searchDevices`), which\n // carries no usable mfp of its own; connecting always opens+claims\n // whatever the OS/browser currently has permission for, then merges by\n // whatever mfp comes back.\n if (!this._usbConnector) {\n return failure(HardwareErrorCode.DeviceNotFound, `Unknown Keystone connectId: ${connectId}`);\n }\n const result = await this._connectUsb();\n if (!result.success) return result;\n return success(result.payload.connectId);\n }\n\n /**\n * QR has no persistent connection to tear down — the account cache\n * survives so a later call resumes without re-syncing. For a USB session,\n * this closes the connector session and either demotes the record back to\n * QR-only (if it was ever QR-synced) or removes it entirely (pure-USB\n * wallet that was never seen over QR) — see §4.2 of the design doc.\n */\n async disconnectDevice(connectId: string): Promise<void> {\n const record = this._findByConnectId(connectId);\n if (!record?.usbSessionId) return;\n\n if (this._usbConnector) {\n try {\n await this._usbConnector.disconnect(record.usbSessionId);\n } catch {\n // Best-effort teardown — the record is dropped/demoted below either way.\n }\n }\n record.usbSessionId = undefined;\n\n if (record.qrSynced) {\n const info = toDeviceInfo(record);\n this.emitter.emit(DEVICE.CHANGED, { type: DEVICE.CHANGED, payload: info });\n } else {\n this._devices.delete(record.masterFingerprint);\n const info = toDeviceInfo(record);\n this.emitter.emit(DEVICE.DISCONNECT, { type: DEVICE.DISCONNECT, payload: info });\n }\n }\n\n getDeviceInfo(connectId: string, deviceId: string): Promise<Response<DeviceInfo>> {\n const record = this._findByConnectId(connectId) ?? this._devices.get(deviceId.toLowerCase());\n if (!record) {\n return Promise.resolve(\n failure(\n HardwareErrorCode.DeviceNotFound,\n `Unknown Keystone device: ${connectId || deviceId}`\n )\n );\n }\n return Promise.resolve(success(toDeviceInfo(record)));\n }\n\n getSupportedChains(): ChainCapability[] {\n return ['evm', 'btc', 'sol', 'tron'];\n }\n\n cancel(connectId?: string): void {\n const reason = createHwkError({\n code: HardwareErrorCode.UserAborted,\n message: 'User aborted operation',\n });\n this._uiRegistry.cancel();\n this._jobQueue.cancelActiveAndPending(connectId, reason);\n }\n\n getChainFingerprint(\n connectId: string,\n deviceId: string,\n chain: ChainForFingerprint\n ): Promise<Response<string>> {\n const mfp = deviceId ? deviceId.toLowerCase() : this._mfpFromConnectId(connectId);\n if (!mfp) {\n return Promise.resolve(failure(HardwareErrorCode.DeviceNotFound, 'Unknown Keystone device'));\n }\n // Unlike Ledger (ephemeral connectId, needs a derived address as a\n // stand-in identity), the mfp itself already IS Keystone's stable,\n // seed-level identity — no device round trip needed to re-derive it.\n // Still scoped per chain so the fingerprint format matches other vendors'.\n return Promise.resolve(success(deriveDeviceFingerprint(`keystone:${chain}:${mfp}`)));\n }\n\n uiResponse(response: UiResponseEvent): void {\n if (response.type === UI_RESPONSE.CANCEL) {\n this.cancel();\n return;\n }\n this._uiRegistry.resolve(response.type, response.payload);\n }\n\n on<K extends keyof HardwareEventMap>(\n event: K,\n listener: (event: HardwareEventMap[K]) => void\n ): void;\n\n on(event: string, listener: DeviceEventListener): void;\n\n on(event: string, listener: (event: HardwareEvent) => void): void {\n this.emitter.on(event, listener);\n }\n\n off<K extends keyof HardwareEventMap>(\n event: K,\n listener: (event: HardwareEventMap[K]) => void\n ): void;\n\n off(event: string, listener: DeviceEventListener): void;\n\n off(event: string, listener: (event: HardwareEvent) => void): void {\n this.emitter.off(event, listener);\n }\n\n // ---------------------------------------------------------------------------\n // Explicit account import — the recommended entry point before signing, so\n // signing calls don't each pay for their own cold-sync round trip.\n // ---------------------------------------------------------------------------\n\n async importFromQr(options: ImportFromQrOptions = {}): Promise<Response<DeviceInfo>> {\n try {\n return await this._jobQueue.enqueue(COLD_START_JOB_LABEL, async signal => {\n const displayDevice = placeholderDeviceInfo();\n let responseUr: KeystoneUr;\n let requestedChains: ChainCapability[] | undefined;\n\n if (options.mode === 'scan') {\n responseUr = await this._requestQrScanAndAwaitResponse(displayDevice);\n } else {\n const schemas = options.paths?.length ? options.paths : DEFAULT_IMPORT_SCHEMAS;\n requestedChains = schemas.map(s => s.hwkChain);\n const requestUr = this.urEngine.buildKeyDerivationRequest({\n schemas: schemas.map(s => ({\n path: s.path,\n curve: s.hwkChain === 'sol' ? 'ed25519' : 'secp256k1',\n })),\n origin: this._origin,\n });\n responseUr = await this._requestQrDisplayAndAwaitResponse(displayDevice, {\n ...requestUr,\n animated: false,\n });\n }\n KeystoneAdapter._throwIfAborted(signal);\n\n const parsed = this.urEngine.parseAccountResponse(responseUr);\n const record = this._upsertDeviceRecord(parsed);\n\n for (const account of parsed.accounts) {\n const hwkChain =\n requestedChains?.length === 1\n ? requestedChains[0]\n : inferHwkChainFromPath(account.path);\n if (hwkChain) {\n const entry: KeystoneAccountEntry = { ...account, hwkChain };\n record.accounts.set(accountKey(hwkChain, account.path), entry);\n }\n }\n\n return success(toDeviceInfo(record));\n });\n } catch (err) {\n return this._errorToFailure<DeviceInfo>(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // All-network bundle — dispatches to the same per-chain methods below, so\n // there's exactly one implementation of each chain's address logic.\n // ---------------------------------------------------------------------------\n\n allNetworkGetAddress = async (\n connectId: string,\n deviceId: string,\n params: AllNetworkGetAddressParams\n ): Promise<Response<AllNetworkAddressResponse[]>> => {\n try {\n return await runAllNetworkGetAddress({\n connectId,\n deviceId,\n params,\n callItem: async ({ chain, item }) => {\n const commonArgs = { path: item.path, showOnDevice: item.showOnDevice };\n switch (chain) {\n case 'evm':\n return this.evmGetAddress(connectId, deviceId, commonArgs);\n case 'btc':\n return this.btcGetAddress(connectId, deviceId, commonArgs);\n case 'sol':\n return this.solGetAddress(connectId, deviceId, commonArgs);\n case 'tron':\n return this.tronGetAddress(connectId, deviceId, commonArgs);\n default:\n return failure(HardwareErrorCode.MethodNotSupported, `Unsupported chain: ${chain}`);\n }\n },\n attachIdentity: context => {\n const mfp = deviceId ? deviceId.toLowerCase() : undefined;\n return Promise.resolve({\n ...context.item,\n success: true,\n payload: {\n ...context.payload,\n deviceIdentity: mfp\n ? { vendor: 'keystone' as const, type: 'masterFingerprint' as const, value: mfp }\n : undefined,\n },\n });\n },\n });\n } catch (err) {\n return this._errorToFailure<AllNetworkAddressResponse[]>(err);\n }\n };\n\n // ---------------------------------------------------------------------------\n // EVM\n // ---------------------------------------------------------------------------\n\n async evmGetAddress(\n connectIdArg?: NullableCallArg<string>,\n deviceIdArg?: NullableCallArg<string>,\n paramsArg?: NullableCallArg<IHardwareCallParams<EvmGetAddressParams>>\n ): Promise<Response<EvmAddress>> {\n const connectId = connectIdArg ?? undefined;\n const deviceId = deviceIdArg ?? undefined;\n const params = paramsArg;\n if (!params) return failure(HardwareErrorCode.InvalidParams, 'evmGetAddress requires params');\n if (!params.path)\n return failure(HardwareErrorCode.InvalidParams, 'evmGetAddress requires params.path');\n\n const { accountPath, relativeDerivePath } = splitAccountPath(params.path);\n if (!relativeDerivePath) {\n return failure(\n HardwareErrorCode.InvalidParams,\n \"evmGetAddress requires a full leaf path, e.g. m/44'/60'/0'/0/0\"\n );\n }\n\n try {\n return await this._jobQueue.enqueue(\n deviceId ?? connectId ?? COLD_START_JOB_LABEL,\n async signal => {\n const { account } = await this._ensureAccountSynced(\n connectId,\n deviceId,\n 'evm',\n accountPath,\n signal\n );\n KeystoneAdapter._throwIfAborted(signal);\n if (!account.extendedPublicKey) {\n throw createHwkError({\n code: HardwareErrorCode.MethodNotSupported,\n message: 'Keystone did not return an extended public key for this account path',\n });\n }\n // params.showOnDevice: Keystone on-device re-display/verification for\n // one leaf address isn't wired yet; the address itself is still\n // correct — it's derived offline from a device-verified xpub, just\n // not re-shown.\n const address = this.urEngine.deriveEvmAddressFromXpub(\n account.extendedPublicKey,\n relativeDerivePath\n );\n return success<EvmAddress>({ address, path: normalizePath(params.path) });\n }\n );\n } catch (err) {\n return this._errorToFailure<EvmAddress>(err);\n }\n }\n\n async evmSignTransaction(\n connectIdArg?: NullableCallArg<string>,\n deviceIdArg?: NullableCallArg<string>,\n paramsArg?: NullableCallArg<IHardwareCallParams<EvmSignTxParams>>\n ): Promise<Response<EvmSignedTx>> {\n const connectId = connectIdArg ?? undefined;\n const deviceId = deviceIdArg ?? undefined;\n const params = paramsArg;\n if (!params)\n return failure(HardwareErrorCode.InvalidParams, 'evmSignTransaction requires params');\n if (!params.path) {\n return failure(HardwareErrorCode.InvalidParams, 'evmSignTransaction requires params.path');\n }\n if (\n !('serializedTx' in params) ||\n typeof params.serializedTx !== 'string' ||\n !params.serializedTx\n ) {\n return failure(\n HardwareErrorCode.MethodNotSupported,\n 'Keystone only signs a fully RLP-serialized transaction (params.serializedTx) — structured-field signing is not supported'\n );\n }\n const rawTxHex = stripHex(params.serializedTx);\n const path = normalizePath(params.path);\n\n try {\n return await this._jobQueue.enqueue(\n deviceId ?? connectId ?? COLD_START_JOB_LABEL,\n async signal => {\n // Signing only needs the wallet's mfp (the device re-derives the\n // signing key itself from path+xfp) — not a cached xpub for this\n // exact path, so this must NOT key off the leaf path the way\n // evmGetAddress's account-xpub cache does, or a wallet imported at\n // the account level would never hit cache for a sign call.\n const { record } = await this._ensureMfpKnown(connectId, deviceId, 'evm', signal);\n KeystoneAdapter._throwIfAborted(signal);\n\n const requestId = uuidv4();\n // EIP-2718 typed-tx bytes always start with a type byte < 0x80; a\n // legacy RLP-encoded tx list always starts with a byte >= 0xc0 — the\n // standard disambiguation rule (that gap is exactly why EIP-2718\n // chose those type-byte values).\n const dataType =\n parseInt(rawTxHex.slice(0, 2), 16) < 0xc0 ? 'typedTransaction' : 'transaction';\n const requestUr = this.urEngine.buildEthSignRequest({\n requestId,\n unsignedTxHex: rawTxHex,\n dataType,\n path,\n xfp: record.masterFingerprint,\n chainId: params.chainId,\n });\n const responseUr = await this._resolveUr(record, requestUr, true);\n KeystoneAdapter._throwIfAborted(signal);\n\n const sig = this.urEngine.parseEthSignature(responseUr);\n KeystoneAdapter._assertRequestIdMatches(requestId, sig.requestId);\n return success<EvmSignedTx>({\n v: ensure0x(sig.v),\n r: ensure0x(sig.r),\n s: ensure0x(sig.s),\n });\n }\n );\n } catch (err) {\n return this._errorToFailure<EvmSignedTx>(err);\n }\n }\n\n async evmSignMessage(\n connectIdArg?: NullableCallArg<string>,\n deviceIdArg?: NullableCallArg<string>,\n paramsArg?: NullableCallArg<IHardwareCallParams<EvmSignMsgParams>>\n ): Promise<Response<EvmSignature>> {\n const connectId = connectIdArg ?? undefined;\n const deviceId = deviceIdArg ?? undefined;\n const params = paramsArg;\n if (!params) return failure(HardwareErrorCode.InvalidParams, 'evmSignMessage requires params');\n if (!params.path || params.message === undefined) {\n return failure(\n HardwareErrorCode.InvalidParams,\n 'evmSignMessage requires params.path and params.message'\n );\n }\n const messageHex = params.hex\n ? stripHex(params.message)\n : Buffer.from(params.message, 'utf8').toString('hex');\n const path = normalizePath(params.path);\n\n try {\n return await this._jobQueue.enqueue(\n deviceId ?? connectId ?? COLD_START_JOB_LABEL,\n async signal => {\n // Signing only needs the wallet's mfp (the device re-derives the\n // signing key itself from path+xfp) — not a cached xpub for this\n // exact path, so this must NOT key off the leaf path the way\n // evmGetAddress's account-xpub cache does, or a wallet imported at\n // the account level would never hit cache for a sign call.\n const { record } = await this._ensureMfpKnown(connectId, deviceId, 'evm', signal);\n KeystoneAdapter._throwIfAborted(signal);\n\n const requestId = uuidv4();\n const requestUr = this.urEngine.buildEthSignRequest({\n requestId,\n unsignedTxHex: messageHex,\n dataType: 'personalMessage',\n path,\n xfp: record.masterFingerprint,\n chainId: params.chainId,\n });\n const responseUr = await this._resolveUr(record, requestUr, true);\n KeystoneAdapter._throwIfAborted(signal);\n\n const sig = this.urEngine.parseEthSignature(responseUr);\n KeystoneAdapter._assertRequestIdMatches(requestId, sig.requestId);\n return success<EvmSignature>({ signature: ensure0x(sig.r + sig.s + sig.v) });\n }\n );\n } catch (err) {\n return this._errorToFailure<EvmSignature>(err);\n }\n }\n\n async evmSignTypedData(\n connectIdArg?: NullableCallArg<string>,\n deviceIdArg?: NullableCallArg<string>,\n paramsArg?: NullableCallArg<IHardwareCallParams<EvmSignTypedDataParams>>\n ): Promise<Response<EvmSignature>> {\n const connectId = connectIdArg ?? undefined;\n const deviceId = deviceIdArg ?? undefined;\n const params = paramsArg;\n if (!params)\n return failure(HardwareErrorCode.InvalidParams, 'evmSignTypedData requires params');\n if (!params.path) {\n return failure(HardwareErrorCode.InvalidParams, 'evmSignTypedData requires params.path');\n }\n if (params.mode === 'hash') {\n return failure(\n HardwareErrorCode.MethodNotSupported,\n 'Keystone always displays the full EIP-712 payload for on-device review — pre-hashed signing is not supported'\n );\n }\n // Matches the Keystone USB SDK's own `signEIP712Message` convention\n // (JSON.stringify of the typed-data object) — QR and USB share the same\n // sign-request format, so the wire convention is the same either way.\n const signDataHex = Buffer.from(JSON.stringify(params.data), 'utf8').toString('hex');\n const path = normalizePath(params.path);\n\n try {\n return await this._jobQueue.enqueue(\n deviceId ?? connectId ?? COLD_START_JOB_LABEL,\n async signal => {\n // Signing only needs the wallet's mfp (the device re-derives the\n // signing key itself from path+xfp) — not a cached xpub for this\n // exact path, so this must NOT key off the leaf path the way\n // evmGetAddress's account-xpub cache does, or a wallet imported at\n // the account level would never hit cache for a sign call.\n const { record } = await this._ensureMfpKnown(connectId, deviceId, 'evm', signal);\n KeystoneAdapter._throwIfAborted(signal);\n\n const requestId = uuidv4();\n const requestUr = this.urEngine.buildEthSignRequest({\n requestId,\n unsignedTxHex: signDataHex,\n dataType: 'typedData',\n path,\n xfp: record.masterFingerprint,\n chainId: params.chainId,\n });\n const responseUr = await this._resolveUr(record, requestUr, true);\n KeystoneAdapter._throwIfAborted(signal);\n\n const sig = this.urEngine.parseEthSignature(responseUr);\n KeystoneAdapter._assertRequestIdMatches(requestId, sig.requestId);\n return success<EvmSignature>({ signature: ensure0x(sig.r + sig.s + sig.v) });\n }\n );\n } catch (err) {\n return this._errorToFailure<EvmSignature>(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // BTC — PSBT signing and message signing only for now. Address/pubkey\n // derivation needs script-type-aware xpub decoding (P2WPKH/P2TR/…) this\n // phase doesn't wire in yet; structured-field tx signing needs host-side\n // PSBT construction. Both are real, bounded follow-ups, not silent gaps.\n // ---------------------------------------------------------------------------\n\n async btcGetAddress(\n connectIdArg?: NullableCallArg<string>,\n deviceIdArg?: NullableCallArg<string>,\n paramsArg?: NullableCallArg<IHardwareCallParams<BtcGetAddressParams>>\n ): Promise<Response<BtcAddress>> {\n const connectId = connectIdArg ?? undefined;\n const deviceId = deviceIdArg ?? undefined;\n const params = paramsArg;\n if (!params) return failure(HardwareErrorCode.InvalidParams, 'btcGetAddress requires params');\n if (!params.path)\n return failure(HardwareErrorCode.InvalidParams, 'btcGetAddress requires params.path');\n\n const scriptType = btcScriptTypeFromPath(params.path);\n if (!scriptType) {\n return failure(\n HardwareErrorCode.InvalidParams,\n \"btcGetAddress requires a path whose purpose is 44'/49'/84'/86' (P2PKH/P2SH-P2WPKH/P2WPKH/P2TR)\"\n );\n }\n if (scriptType === 'p2tr') {\n return this._unsupported(\n 'btcGetAddress',\n \"P2TR (purpose 86') needs an elliptic-curve library for BIP-341 tweaking, not yet wired in — 44'/49'/84' work\"\n );\n }\n\n const { accountPath, relativeDerivePath } = splitAccountPath(params.path);\n if (!relativeDerivePath) {\n return failure(\n HardwareErrorCode.InvalidParams,\n \"btcGetAddress requires a full leaf path, e.g. m/84'/0'/0'/0/0\"\n );\n }\n\n try {\n return await this._jobQueue.enqueue(\n deviceId ?? connectId ?? COLD_START_JOB_LABEL,\n async signal => {\n const { account } = await this._ensureAccountSynced(\n connectId,\n deviceId,\n 'btc',\n accountPath,\n signal\n );\n KeystoneAdapter._throwIfAborted(signal);\n if (!account.extendedPublicKey) {\n throw createHwkError({\n code: HardwareErrorCode.MethodNotSupported,\n message: 'Keystone did not return an extended public key for this account path',\n });\n }\n // Same on-device re-display caveat as evmGetAddress: the address is\n // still correct (derived offline from a device-verified xpub), it\n // just isn't re-shown on-device for this call yet.\n const address = this.urEngine.deriveBtcAddressFromXpub(\n account.extendedPublicKey,\n relativeDerivePath,\n scriptType\n );\n return success<BtcAddress>({ address, path: normalizePath(params.path) });\n }\n );\n } catch (err) {\n return this._errorToFailure<BtcAddress>(err);\n }\n }\n\n async btcGetPublicKey(\n _connectId?: NullableCallArg<string>,\n _deviceId?: NullableCallArg<string>,\n _params?: NullableCallArg<IHardwareCallParams<BtcGetPublicKeyParams>>\n ): Promise<Response<BtcPublicKey>> {\n return this._unsupported(\n 'btcGetPublicKey',\n 'not yet wired — the underlying synced xpub/chainCode data already exists in the device table'\n );\n }\n\n async btcSignTransaction(\n _connectId?: NullableCallArg<string>,\n _deviceId?: NullableCallArg<string>,\n _params?: NullableCallArg<IHardwareCallParams<BtcSignTxParams>>\n ): Promise<Response<BtcSignedTx>> {\n return this._unsupported(\n 'btcSignTransaction',\n 'use btcSignPsbt — structured input/output signing needs host-side PSBT construction, not yet wired in'\n );\n }\n\n async btcSignPsbt(\n connectIdArg?: NullableCallArg<string>,\n deviceIdArg?: NullableCallArg<string>,\n paramsArg?: NullableCallArg<IHardwareCallParams<BtcSignPsbtParams>>\n ): Promise<Response<BtcSignedPsbt>> {\n const connectId = connectIdArg ?? undefined;\n const deviceId = deviceIdArg ?? undefined;\n const params = paramsArg;\n if (!params) return failure(HardwareErrorCode.InvalidParams, 'btcSignPsbt requires params');\n if (!params.psbt)\n return failure(HardwareErrorCode.InvalidParams, 'btcSignPsbt requires params.psbt');\n\n try {\n return await this._jobQueue.enqueue(\n deviceId ?? connectId ?? COLD_START_JOB_LABEL,\n async signal => {\n // A PSBT can span multiple inputs/paths — there's no single leaf path\n // to scope a sync to, so this only needs the wallet's mfp to be known.\n const { record } = await this._ensureMfpKnown(connectId, deviceId, 'btc', signal);\n KeystoneAdapter._throwIfAborted(signal);\n\n const requestUr = this.urEngine.buildBtcPsbtRequest(stripHex(params.psbt));\n const responseUr = await this._resolveUr(record, requestUr, true);\n KeystoneAdapter._throwIfAborted(signal);\n\n const signedPsbt = this.urEngine.parseBtcPsbt(responseUr);\n return success<BtcSignedPsbt>({ signedPsbt });\n }\n );\n } catch (err) {\n return this._errorToFailure<BtcSignedPsbt>(err);\n }\n }\n\n async btcSignMessage(\n connectIdArg?: NullableCallArg<string>,\n deviceIdArg?: NullableCallArg<string>,\n paramsArg?: NullableCallArg<IHardwareCallParams<BtcSignMsgParams>>\n ): Promise<Response<BtcSignature>> {\n const connectId = connectIdArg ?? undefined;\n const deviceId = deviceIdArg ?? undefined;\n const params = paramsArg;\n if (!params) return failure(HardwareErrorCode.InvalidParams, 'btcSignMessage requires params');\n if (!params.path || params.message === undefined) {\n return failure(\n HardwareErrorCode.InvalidParams,\n 'btcSignMessage requires params.path and params.message'\n );\n }\n const messageHex = params.hex\n ? stripHex(params.message)\n : Buffer.from(params.message, 'utf8').toString('hex');\n const path = normalizePath(params.path);\n\n try {\n return await this._jobQueue.enqueue(\n deviceId ?? connectId ?? COLD_START_JOB_LABEL,\n async signal => {\n const { record } = await this._ensureMfpKnown(connectId, deviceId, 'btc', signal);\n KeystoneAdapter._throwIfAborted(signal);\n\n const requestId = uuidv4();\n const requestUr = this.urEngine.buildBtcMessageSignRequest({\n requestId,\n messageHex,\n accounts: [{ path, xfp: record.masterFingerprint }],\n });\n const responseUr = await this._resolveUr(record, requestUr, true);\n KeystoneAdapter._throwIfAborted(signal);\n\n const sig = this.urEngine.parseBtcSignature(responseUr);\n KeystoneAdapter._assertRequestIdMatches(requestId, sig.requestId);\n return success<BtcSignature>({ signature: sig.signature });\n }\n );\n } catch (err) {\n return this._errorToFailure<BtcSignature>(err);\n }\n }\n\n async btcGetMasterFingerprint(\n connectIdArg?: NullableCallArg<string>,\n deviceIdArg?: NullableCallArg<string>\n ): Promise<Response<{ masterFingerprint: string }>> {\n const connectId = connectIdArg ?? undefined;\n const deviceId = deviceIdArg ?? undefined;\n try {\n return await this._jobQueue.enqueue(\n deviceId ?? connectId ?? COLD_START_JOB_LABEL,\n async signal => {\n const { record } = await this._ensureMfpKnown(connectId, deviceId, 'btc', signal);\n return success({ masterFingerprint: record.masterFingerprint });\n }\n );\n } catch (err) {\n return this._errorToFailure<{ masterFingerprint: string }>(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // SOL\n // ---------------------------------------------------------------------------\n\n async solGetAddress(\n connectIdArg?: NullableCallArg<string>,\n deviceIdArg?: NullableCallArg<string>,\n paramsArg?: NullableCallArg<IHardwareCallParams<SolGetAddressParams>>\n ): Promise<Response<SolAddress>> {\n const connectId = connectIdArg ?? undefined;\n const deviceId = deviceIdArg ?? undefined;\n const params = paramsArg;\n if (!params) return failure(HardwareErrorCode.InvalidParams, 'solGetAddress requires params');\n if (!params.path)\n return failure(HardwareErrorCode.InvalidParams, 'solGetAddress requires params.path');\n const path = normalizePath(params.path);\n\n try {\n return await this._jobQueue.enqueue(\n deviceId ?? connectId ?? COLD_START_JOB_LABEL,\n async signal => {\n const { account } = await this._ensureAccountSynced(\n connectId,\n deviceId,\n 'sol',\n path,\n signal\n );\n KeystoneAdapter._throwIfAborted(signal);\n // Ed25519 public key IS the Solana address (base58) — no further\n // derivation, unlike EVM. params.showOnDevice: same on-device\n // re-display caveat as evmGetAddress.\n const address = bs58.encode(Buffer.from(account.publicKey, 'hex'));\n return success<SolAddress>({ address, path });\n }\n );\n } catch (err) {\n return this._errorToFailure<SolAddress>(err);\n }\n }\n\n async solSignTransaction(\n connectIdArg?: NullableCallArg<string>,\n deviceIdArg?: NullableCallArg<string>,\n paramsArg?: NullableCallArg<IHardwareCallParams<SolSignTxParams>>\n ): Promise<Response<SolSignedTx>> {\n const connectId = connectIdArg ?? undefined;\n const deviceId = deviceIdArg ?? undefined;\n const params = paramsArg;\n if (!params)\n return failure(HardwareErrorCode.InvalidParams, 'solSignTransaction requires params');\n if (!params.path || !params.serializedTx) {\n return failure(\n HardwareErrorCode.InvalidParams,\n 'solSignTransaction requires params.path and params.serializedTx'\n );\n }\n const path = normalizePath(params.path);\n\n try {\n return await this._jobQueue.enqueue(\n deviceId ?? connectId ?? COLD_START_JOB_LABEL,\n async signal => {\n // Same reasoning as evmSignTransaction — signing needs only the mfp.\n const { record } = await this._ensureMfpKnown(connectId, deviceId, 'sol', signal);\n KeystoneAdapter._throwIfAborted(signal);\n\n const requestId = uuidv4();\n const requestUr = this.urEngine.buildSolSignRequest({\n requestId,\n unsignedPayloadHex: stripHex(params.serializedTx),\n dataType: 'transaction',\n path,\n xfp: record.masterFingerprint,\n });\n const responseUr = await this._resolveUr(record, requestUr, true);\n KeystoneAdapter._throwIfAborted(signal);\n\n const sig = this.urEngine.parseSolSignature(responseUr);\n KeystoneAdapter._assertRequestIdMatches(requestId, sig.requestId);\n return success<SolSignedTx>({ signature: sig.signature });\n }\n );\n } catch (err) {\n return this._errorToFailure<SolSignedTx>(err);\n }\n }\n\n async solSignMessage(\n connectIdArg?: NullableCallArg<string>,\n deviceIdArg?: NullableCallArg<string>,\n paramsArg?: NullableCallArg<IHardwareCallParams<SolSignMsgParams>>\n ): Promise<Response<SolSignature>> {\n const connectId = connectIdArg ?? undefined;\n const deviceId = deviceIdArg ?? undefined;\n const params = paramsArg;\n if (!params) return failure(HardwareErrorCode.InvalidParams, 'solSignMessage requires params');\n if (!params.path || !params.message) {\n return failure(\n HardwareErrorCode.InvalidParams,\n 'solSignMessage requires params.path and params.message'\n );\n }\n const path = normalizePath(params.path);\n\n try {\n return await this._jobQueue.enqueue(\n deviceId ?? connectId ?? COLD_START_JOB_LABEL,\n async signal => {\n // Same reasoning as evmSignTransaction — signing needs only the mfp.\n const { record } = await this._ensureMfpKnown(connectId, deviceId, 'sol', signal);\n KeystoneAdapter._throwIfAborted(signal);\n\n const requestId = uuidv4();\n const requestUr = this.urEngine.buildSolSignRequest({\n requestId,\n unsignedPayloadHex: stripHex(params.message),\n dataType: 'message',\n path,\n xfp: record.masterFingerprint,\n });\n const responseUr = await this._resolveUr(record, requestUr, true);\n KeystoneAdapter._throwIfAborted(signal);\n\n const sig = this.urEngine.parseSolSignature(responseUr);\n KeystoneAdapter._assertRequestIdMatches(requestId, sig.requestId);\n return success<SolSignature>({ signature: sig.signature });\n }\n );\n } catch (err) {\n return this._errorToFailure<SolSignature>(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // TRON — routed through `TronSignRequest`/`TronSignature` (see\n // urEngine/TronSignRequest.ts), a port of OneKey's own already-proven\n // production TRON QR-wallet implementation — NOT keystone-sdk's own\n // bundled `sdk.tron` module (different, protobuf-based protocol with\n // unverified response semantics).\n // ---------------------------------------------------------------------------\n\n async tronGetAddress(\n connectIdArg?: NullableCallArg<string>,\n deviceIdArg?: NullableCallArg<string>,\n paramsArg?: NullableCallArg<IHardwareCallParams<TronGetAddressParams>>\n ): Promise<Response<TronAddress>> {\n const connectId = connectIdArg ?? undefined;\n const deviceId = deviceIdArg ?? undefined;\n const params = paramsArg;\n if (!params) return failure(HardwareErrorCode.InvalidParams, 'tronGetAddress requires params');\n if (!params.path)\n return failure(HardwareErrorCode.InvalidParams, 'tronGetAddress requires params.path');\n\n const { accountPath, relativeDerivePath } = splitAccountPath(params.path);\n if (!relativeDerivePath) {\n return failure(\n HardwareErrorCode.InvalidParams,\n \"tronGetAddress requires a full leaf path, e.g. m/44'/195'/0'/0/0\"\n );\n }\n\n try {\n return await this._jobQueue.enqueue(\n deviceId ?? connectId ?? COLD_START_JOB_LABEL,\n async signal => {\n const { account } = await this._ensureAccountSynced(\n connectId,\n deviceId,\n 'tron',\n accountPath,\n signal\n );\n KeystoneAdapter._throwIfAborted(signal);\n if (!account.extendedPublicKey) {\n throw createHwkError({\n code: HardwareErrorCode.MethodNotSupported,\n message: 'Keystone did not return an extended public key for this account path',\n });\n }\n const address = this.urEngine.deriveTronAddressFromXpub(\n account.extendedPublicKey,\n relativeDerivePath\n );\n return success<TronAddress>({ address, path: normalizePath(params.path) });\n }\n );\n } catch (err) {\n return this._errorToFailure<TronAddress>(err);\n }\n }\n\n async tronSignTransaction(\n connectIdArg?: NullableCallArg<string>,\n deviceIdArg?: NullableCallArg<string>,\n paramsArg?: NullableCallArg<IHardwareCallParams<TronSignTxParams>>\n ): Promise<Response<TronSignedTx>> {\n const connectId = connectIdArg ?? undefined;\n const deviceId = deviceIdArg ?? undefined;\n const params = paramsArg;\n if (!params)\n return failure(HardwareErrorCode.InvalidParams, 'tronSignTransaction requires params');\n if (!params.path) {\n return failure(HardwareErrorCode.InvalidParams, 'tronSignTransaction requires params.path');\n }\n if (!params.rawTxHex) {\n return failure(\n HardwareErrorCode.InvalidParams,\n 'Keystone only signs a fully protobuf-serialized TRON transaction (params.rawTxHex) — the Trezor-style structured contract fields have no equivalent here'\n );\n }\n const rawTxHex = stripHex(params.rawTxHex);\n const path = normalizePath(params.path);\n\n try {\n return await this._jobQueue.enqueue(\n deviceId ?? connectId ?? COLD_START_JOB_LABEL,\n async signal => {\n const { record } = await this._ensureMfpKnown(connectId, deviceId, 'tron', signal);\n KeystoneAdapter._throwIfAborted(signal);\n\n const requestId = uuidv4();\n const requestUr = this.urEngine.buildTronSignRequest({\n requestId,\n rawTxHex,\n path,\n xfp: record.masterFingerprint,\n });\n const responseUr = await this._resolveUr(record, requestUr, true);\n KeystoneAdapter._throwIfAborted(signal);\n\n const sig = this.urEngine.parseTronSignature(responseUr);\n KeystoneAdapter._assertRequestIdMatches(requestId, sig.requestId);\n // Keystone signs the exact rawTxHex bytes it was given and returns\n // only the bare signature — unlike EVM/BTC there's no host-side\n // re-encoding step, so `serializedTx` stays unset (the caller\n // already has the raw tx it sent in).\n return success<TronSignedTx>({ signature: sig.signature });\n }\n );\n } catch (err) {\n return this._errorToFailure<TronSignedTx>(err);\n }\n }\n\n async tronSignMessage(\n _connectId?: NullableCallArg<string>,\n _deviceId?: NullableCallArg<string>,\n _params?: NullableCallArg<IHardwareCallParams<TronSignMsgParams>>\n ): Promise<Response<TronSignature>> {\n // `TronSignRequest`'s `signType` field DOES have message-signing modes\n // (SignMessage / SignMessageV2, alongside Transaction) — this isn't a\n // protocol gap the way tronSignTransaction's rawTxHex requirement is.\n // Left unimplemented because which of the two message variants a real\n // device actually expects for a plain personal-message sign isn't\n // verified yet — picking the wrong one would silently produce a\n // signature over the wrong preimage. A real, bounded follow-up, not an\n // oversight.\n return this._unsupported(\n 'tronSignMessage',\n 'Keystone TRON message signing needs signType V1-vs-V2 verified against real hardware first — not wired in'\n );\n }\n\n // ---------------------------------------------------------------------------\n // Internals\n // ---------------------------------------------------------------------------\n\n private _mfpFromConnectId(connectId: string): string | undefined {\n return connectId?.startsWith(QR_CONNECT_ID_PREFIX)\n ? connectId.slice(QR_CONNECT_ID_PREFIX.length)\n : undefined;\n }\n\n /**\n * Handles both connectId shapes a caller might hand back: the QR-style\n * `keystone-qr:<mfp>` prefix, and a bare mfp — which is exactly what a\n * USB session's `sessionId`/`connectId` is (see `KeystoneUsbConnectorBase`\n * and `_connectUsb`).\n */\n private _findByConnectId(connectId: string): KeystoneDeviceRecord | undefined {\n const mfp = this._mfpFromConnectId(connectId) ?? connectId?.toLowerCase();\n return mfp ? this._devices.get(mfp) : undefined;\n }\n\n /**\n * Folds a parsed account-response UR into the device table. `viaUsb`\n * (defaults false) says which channel actually carried this round trip —\n * `_resolveUr` routes a KeyDerivation sync over USB when the target record\n * already has a live session, so this must NOT unconditionally mark\n * `qrSynced`, or a USB-only wallet would wrongly survive a later USB\n * disconnect as a \"QR-synced, demote to QR-only\" entry instead of being\n * dropped outright (see `disconnectDevice`).\n */\n private _upsertDeviceRecord(\n parsed: KeystoneParsedMultiAccounts,\n options?: { viaUsb?: boolean }\n ): KeystoneDeviceRecord {\n const mfp = parsed.masterFingerprint;\n let record = this._devices.get(mfp);\n const isNew = !record;\n if (!record) {\n record = createDeviceRecord(mfp);\n this._devices.set(mfp, record);\n }\n record.model = parsed.device ?? record.model;\n record.deviceVersion = parsed.deviceVersion ?? record.deviceVersion;\n if (!options?.viaUsb) record.qrSynced = true;\n\n const info = toDeviceInfo(record);\n const eventType = isNew ? DEVICE.CONNECT : DEVICE.CHANGED;\n this.emitter.emit(eventType, { type: eventType, payload: info });\n return record;\n }\n\n /**\n * Opens+claims whatever Keystone the USB connector currently has\n * permission for, learns its mfp via `getAppConfig`, and merges it into\n * the device table by that mfp — a QR-synced entry becomes\n * `{qr, usb}`-capable in place (one `device-changed`, not a second\n * `device-connect`); a wallet never seen before becomes a new USB-only\n * entry. See §4.2 of the design doc.\n */\n private async _connectUsb(): Promise<Response<DeviceInfo>> {\n if (!this._usbConnector) {\n return failure(\n HardwareErrorCode.TransportNotAvailable,\n 'No USB connector configured for this Keystone adapter'\n );\n }\n try {\n const session = await this._usbConnector.connect();\n const mfp = session.deviceInfo.deviceId.toLowerCase();\n let record = this._devices.get(mfp);\n const isNew = !record;\n if (!record) {\n record = createDeviceRecord(mfp);\n this._devices.set(mfp, record);\n }\n record.model = session.deviceInfo.modelName ?? session.deviceInfo.model ?? record.model;\n record.deviceVersion = session.deviceInfo.firmwareVersion ?? record.deviceVersion;\n record.usbSessionId = session.sessionId;\n\n const info = toDeviceInfo(record);\n const eventType = isNew ? DEVICE.CONNECT : DEVICE.CHANGED;\n this.emitter.emit(eventType, { type: eventType, payload: info });\n return success(info);\n } catch (err) {\n return this._errorToFailure<DeviceInfo>(err);\n }\n }\n\n /**\n * The one place that decides QR vs. USB for a UR round trip and carries it\n * out. `record` is the (possibly not-yet-existing, for a true cold start)\n * device row for the target wallet — USB is only used when `record`\n * already has a live `usbSessionId` (a session comes from an explicit\n * `connectDevice()`, never conjured mid-call — see the class doc). A\n * `switchTransport('qr')` pin forces QR even for a USB-attached wallet;\n * `switchTransport('usb')` on a wallet with no live USB session fails\n * closed rather than silently falling back to QR.\n */\n private async _resolveUr(\n record: KeystoneDeviceRecord | undefined,\n requestUr: KeystoneUr,\n animated: boolean\n ): Promise<KeystoneUr> {\n const wantUsb =\n this._forcedTransport === 'usb' ||\n (this._forcedTransport !== 'qr' && Boolean(record?.usbSessionId));\n\n if (wantUsb) {\n if (!record?.usbSessionId || !this._usbConnector) {\n throw createHwkError({\n code: HardwareErrorCode.TransportNotAvailable,\n message: 'USB channel is not connected for this Keystone wallet',\n });\n }\n const result = await this._usbConnector.call(record.usbSessionId, 'resolveUr', requestUr);\n if (!result.success) throw rehydrateConnectorError(result.error);\n return result.payload as KeystoneUr;\n }\n\n const displayDevice = record ? toDeviceInfo(record) : placeholderDeviceInfo();\n return this._requestQrDisplayAndAwaitResponse(displayDevice, { ...requestUr, animated });\n }\n\n /**\n * Resolve (syncing over QR if needed) the account cached for `hwkChain` at\n * `syncPath`. Drives the \"implicit account sync, then the real request\" two\n * hop flow the first time a wallet/path pair is seen; a cache hit skips\n * straight to the caller's own round trip.\n */\n private async _ensureAccountSynced(\n connectId: string | undefined,\n deviceId: string | undefined,\n hwkChain: ChainCapability,\n syncPath: string,\n signal: AbortSignal\n ): Promise<{ record: KeystoneDeviceRecord; account: KeystoneAccountEntry }> {\n const wantMfp = deviceId ? deviceId.toLowerCase() : this._mfpFromConnectId(connectId ?? '');\n const key = accountKey(hwkChain, syncPath);\n\n const existingRecord = wantMfp ? this._devices.get(wantMfp) : undefined;\n const cached = existingRecord?.accounts.get(key);\n if (existingRecord && cached) {\n return { record: existingRecord, account: cached };\n }\n\n const requestUr = this.urEngine.buildKeyDerivationRequest({\n schemas: [{ path: syncPath, curve: hwkChain === 'sol' ? 'ed25519' : 'secp256k1' }],\n origin: this._origin,\n });\n const responseUr = await this._resolveUr(existingRecord, requestUr, false);\n KeystoneAdapter._throwIfAborted(signal);\n\n const parsed = this.urEngine.parseAccountResponse(responseUr);\n if (wantMfp && parsed.masterFingerprint !== wantMfp) {\n throw createHwkError({\n code: HardwareErrorCode.DeviceMismatch,\n message: `Scanned Keystone wallet (mfp ${parsed.masterFingerprint}) does not match the requested device (${wantMfp})`,\n });\n }\n\n const record = this._upsertDeviceRecord(parsed, {\n viaUsb: Boolean(existingRecord?.usbSessionId),\n });\n const account = parsed.accounts.find(a => normalizePath(a.path) === syncPath);\n if (!account) {\n throw createHwkError({\n code: HardwareErrorCode.DeviceMismatch,\n message: `Keystone did not return the requested derivation path (${syncPath})`,\n });\n }\n const entry: KeystoneAccountEntry = { ...account, hwkChain };\n record.accounts.set(key, entry);\n return { record, account: entry };\n }\n\n /**\n * Like `_ensureAccountSynced`, but for operations (PSBT signing, master\n * fingerprint) that only need to know WHICH wallet is attached, not a\n * specific cached path. Syncs the account-level path for `chain` as a\n * throwaway probe when the mfp isn't already known.\n *\n * `CHAIN_FINGERPRINT_PATHS[chain]` is a 5-segment LEAF path for `evm`\n * (`m/44'/60'/0'/0/0`) — sending that verbatim as a KeyDerivation request\n * asks Keystone for a non-standard path. Keystone's own docs\n * (dev.keyst.one's multichain KeyDerivation example) show the ETH\n * account-level path as `m/44'/60'/0'` (3 segments), same as what\n * `DEFAULT_IMPORT_SCHEMAS`/`_ensureAccountSynced` already request — so\n * truncate through `splitAccountPath` here too instead of using the raw\n * fingerprint leaf path. `btc`/`sol` are already 3-segment account paths\n * and pass through unchanged.\n */\n private async _ensureMfpKnown(\n connectId: string | undefined,\n deviceId: string | undefined,\n chain: ChainForFingerprint,\n signal: AbortSignal\n ): Promise<{ record: KeystoneDeviceRecord }> {\n const wantMfp = deviceId ? deviceId.toLowerCase() : this._mfpFromConnectId(connectId ?? '');\n const existing = wantMfp ? this._devices.get(wantMfp) : undefined;\n if (existing) return { record: existing };\n\n // No existing record for this mfp (or the mfp isn't known yet at all) —\n // a USB session can only exist on a record already in `_devices`, so\n // there is nothing to route over USB here; this is always a QR round\n // trip (`_resolveUr(undefined, ...)` falls back to QR on its own).\n const { accountPath } = splitAccountPath(CHAIN_FINGERPRINT_PATHS[chain]);\n const requestUr = this.urEngine.buildKeyDerivationRequest({\n schemas: [{ path: accountPath, curve: chain === 'sol' ? 'ed25519' : 'secp256k1' }],\n origin: this._origin,\n });\n const responseUr = await this._resolveUr(undefined, requestUr, false);\n KeystoneAdapter._throwIfAborted(signal);\n\n const parsed = this.urEngine.parseAccountResponse(responseUr);\n if (wantMfp && parsed.masterFingerprint !== wantMfp) {\n throw createHwkError({\n code: HardwareErrorCode.DeviceMismatch,\n message: `Scanned Keystone wallet (mfp ${parsed.masterFingerprint}) does not match the requested device (${wantMfp})`,\n });\n }\n return { record: this._upsertDeviceRecord(parsed) };\n }\n\n private async _requestQrDisplayAndAwaitResponse(\n device: DeviceInfo,\n data: QrDisplayData\n ): Promise<KeystoneUr> {\n const waitPromise = this._uiRegistry.wait<{ urType: string; urData: string }>(\n UI_REQUEST.REQUEST_QR_DISPLAY,\n { timeoutMs: this._qrTimeoutMs }\n );\n this.emitter.emit(UI_REQUEST.REQUEST_QR_DISPLAY, {\n type: UI_REQUEST.REQUEST_QR_DISPLAY,\n payload: { device, data },\n });\n const response = await waitPromise;\n return { urType: response.urType, urData: response.urData };\n }\n\n private async _requestQrScanAndAwaitResponse(device: DeviceInfo): Promise<KeystoneUr> {\n const waitPromise = this._uiRegistry.wait<{ urType: string; urData: string }>(\n UI_REQUEST.REQUEST_QR_SCAN,\n { timeoutMs: this._qrTimeoutMs }\n );\n this.emitter.emit(UI_REQUEST.REQUEST_QR_SCAN, {\n type: UI_REQUEST.REQUEST_QR_SCAN,\n payload: { device },\n });\n const response = await waitPromise;\n return { urType: response.urType, urData: response.urData };\n }\n\n private static _throwIfAborted(signal: AbortSignal): void {\n if (signal.aborted) {\n throw signal.reason instanceof Error ? signal.reason : new Error('Operation aborted');\n }\n }\n\n private static _assertRequestIdMatches(expected: string, actual?: string): void {\n if (actual && actual.toLowerCase() !== expected.toLowerCase()) {\n throw createHwkError({\n code: HardwareErrorCode.DeviceMismatch,\n message:\n 'Keystone response requestId does not match the pending request — discarding a stale or unrelated scan',\n });\n }\n }\n\n private _unsupported<T>(method: string, reason: string): Promise<Response<T>> {\n return Promise.resolve(\n failure(\n HardwareErrorCode.MethodNotSupported,\n `KeystoneAdapter.${method} is not implemented yet: ${reason}`\n )\n );\n }\n\n private _errorToFailure<T>(err: unknown): Response<T> {\n if (err && typeof err === 'object') {\n const e = err as {\n code?: unknown;\n message?: string;\n params?: Record<string, unknown>;\n _tag?: string;\n };\n if (typeof e.code === 'number') {\n return failure(e.code as HardwareErrorCode, e.message ?? 'Unknown error', e.params);\n }\n if (e._tag === UI_REQUEST_CANCELLED_TAG || e._tag === UI_REQUEST_PREEMPTED_TAG) {\n return failure(\n HardwareErrorCode.UserAborted,\n e.message ?? 'Keystone QR interaction was cancelled'\n );\n }\n if (e._tag === UI_REQUEST_TIMEOUT_TAG) {\n return failure(\n HardwareErrorCode.OperationTimeout,\n e.message ?? 'Keystone QR interaction timed out'\n );\n }\n }\n const message = err instanceof Error ? err.message : String(err);\n // An unrecognized JS error (not a coded HwkError) reaching here is\n // usually a real bug, not a device/user condition — keep the stack so\n // the app/demo can surface it without needing a debugger attached.\n const params = err instanceof Error && err.stack ? { stack: err.stack } : undefined;\n return failure(HardwareErrorCode.UnknownError, message, params);\n }\n}\n","import type { BtcScriptType } from '../urEngine/types';\n\n/** Always returns an `m/`-prefixed path, regardless of the input's casing/prefix. */\nexport function normalizePath(path: string): string {\n const trimmed = path.trim();\n return /^m\\//i.test(trimmed) ? `m/${trimmed.slice(2)}` : `m/${trimmed}`;\n}\n\n/**\n * Split a full BIP-44 leaf path (`purpose'/coin'/account'/change/index`, 5\n * segments) into its 3-segment account path and the relative `change/index`\n * path from that account to the leaf. Matches the OneKey Keystone air-gap\n * demo's `removePathLastSegment({removeCount: 2})` convention, which is\n * verified against real Keystone hardware.\n *\n * A path with 3 or fewer segments IS already an account path (or shorter) —\n * BIP-44's account level is exactly 3 hardened components — so there is\n * nothing to split off: `relativeDerivePath` is empty and `accountPath` is\n * the (normalized) input unchanged.\n */\nexport function splitAccountPath(path: string): {\n accountPath: string;\n relativeDerivePath: string;\n} {\n const normalized = normalizePath(path);\n const segments = normalized.slice(2).split('/');\n if (segments.length <= 3) {\n return { accountPath: normalized, relativeDerivePath: '' };\n }\n const accountSegments = segments.slice(0, segments.length - 2);\n const relativeSegments = segments.slice(segments.length - 2);\n return {\n accountPath: `m/${accountSegments.join('/')}`,\n relativeDerivePath: relativeSegments.join('/'),\n };\n}\n\n/**\n * Standard BIP-44/49/84/86 purpose → script-type mapping. Returns `undefined`\n * for a path whose purpose isn't one of these four (or isn't parseable),\n * rather than guessing.\n */\nexport function btcScriptTypeFromPath(path: string): BtcScriptType | undefined {\n const match = normalizePath(path).match(/^m\\/(\\d+)'/);\n if (!match) return undefined;\n switch (Number(match[1])) {\n case 44:\n return 'p2pkh';\n case 49:\n return 'p2sh-p2wpkh';\n case 84:\n return 'p2wpkh';\n case 86:\n return 'p2tr';\n default:\n return undefined;\n }\n}\n","import { normalizePath } from './pathUtils';\n\nimport type { KeystoneParsedAccount } from '../urEngine/types';\nimport type { ChainCapability, DeviceCapabilities, DeviceInfo } from '@onekeyfe/hwk-adapter-core';\n\n/** `keystone-qr:<mfp>` is the QR-only connectId; a merged USB session gets its own (phase 4). */\nexport const QR_CONNECT_ID_PREFIX = 'keystone-qr:';\n\nexport function qrConnectId(masterFingerprint: string): string {\n return `${QR_CONNECT_ID_PREFIX}${masterFingerprint}`;\n}\n\nexport interface KeystoneAccountEntry extends KeystoneParsedAccount {\n hwkChain: ChainCapability;\n}\n\nexport function accountKey(hwkChain: ChainCapability, path: string): string {\n return `${hwkChain}:${normalizePath(path)}`;\n}\n\nexport interface KeystoneDeviceRecord {\n /** Lowercase hex BIP32 master fingerprint — the cross-channel wallet identity; doubles as `deviceId`. */\n masterFingerprint: string;\n connectId: string;\n /** Model string from the device (e.g. \"Keystone 3 Pro\"); not unique per unit. */\n model?: string;\n deviceVersion?: string;\n /** Keyed by `accountKey(hwkChain, path)`. Holds whatever was directly synced — usually account-level (3-segment) entries for EVM, exact leaf entries for SOL. */\n accounts: Map<string, KeystoneAccountEntry>;\n importedAt: number;\n /**\n * Set to the connector's `sessionId` (== this record's own mfp, per\n * `KeystoneUsbConnectorBase.connect`) once a live USB session exists for\n * this wallet. Cleared by `disconnectDevice`. Presence of this field is\n * what `KeystoneAdapter._resolveUr` uses to route a call over USB instead\n * of QR.\n */\n usbSessionId?: string;\n /**\n * True once this wallet has completed at least one QR round trip.\n * Distinguishes \"USB session dropped but this wallet was also QR-synced —\n * fall back to a QR-only entry\" from \"this was a USB-only wallet that\n * never synced over QR — drop the entry entirely\" on USB disconnect.\n */\n qrSynced?: boolean;\n}\n\nexport function createDeviceRecord(masterFingerprint: string): KeystoneDeviceRecord {\n return {\n masterFingerprint,\n connectId: qrConnectId(masterFingerprint),\n accounts: new Map(),\n importedAt: Date.now(),\n };\n}\n\nconst CAPABILITIES: DeviceCapabilities = { persistentDeviceIdentity: true };\n\nexport function toDeviceInfo(record: KeystoneDeviceRecord): DeviceInfo {\n // `connectionType` reflects the channel a call would currently be routed\n // over (USB preferred when live — see `KeystoneAdapter._resolveUr`), not\n // just \"however this record was first created\". `raw.availableChannels`\n // carries the full picture for a merged (QR + USB) wallet — see §4.2 of\n // docs/design/keystone-integration/README.md.\n let availableChannels: Array<'qr' | 'usb'> = ['qr'];\n if (record.usbSessionId) {\n availableChannels = record.qrSynced ? ['qr', 'usb'] : ['usb'];\n }\n return {\n vendor: 'keystone',\n model: record.model ?? 'unknown',\n modelName: record.model,\n firmwareVersion: record.deviceVersion ?? '0.0.0',\n deviceId: record.masterFingerprint,\n connectId: record.connectId,\n connectionType: record.usbSessionId ? 'usb' : 'qr',\n capabilities: CAPABILITIES,\n raw: { availableChannels },\n };\n}\n\n/** A device row for a wallet the adapter hasn't synced yet — used while a cold-start round trip is in flight. */\nexport function placeholderDeviceInfo(): DeviceInfo {\n return {\n vendor: 'keystone',\n model: 'unknown',\n firmwareVersion: '0.0.0',\n deviceId: '',\n connectId: '',\n connectionType: 'qr',\n capabilities: CAPABILITIES,\n };\n}\n"],"mappings":"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","names":["import_bc_ur_registry","decodeToDataItem","decodeToDataItem","HDKey","uuidParse","uuidStringify","bs58check","import_uuid","uuidv4","bs58"]}