@onekeyfe/hwk-keystone-adapter 1.2.3-alpha.8 → 1.2.5-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -7,15 +7,8 @@ declare enum TronSignType {
7
7
  }
8
8
 
9
9
  /**
10
- * A UR payload in the wire shape the reserved `QrDisplayData`/`QrResponseData`
11
- * (from `@onekeyfe/hwk-adapter-core`) already commit to: `urType` + `urData`.
12
- *
13
- * `urData` is the hex-encoded raw CBOR payload (equivalent to `ur.cbor.toString('hex')`),
14
- * NOT a `ur:type/…` bech32-style string and NOT a pre-fragmented animated-QR frame
15
- * list. Turning this into single- or multi-part QR frames is a rendering concern the
16
- * app/UI layer owns (via `@ngraveio/bc-ur`'s `UREncoder`), not something the engine
17
- * or the event payload should bake in — `QrDisplayData.animated` is only a hint that
18
- * the payload is large enough to need fragmenting.
10
+ * `urData` is the hex-encoded raw CBOR payload, not a `ur:` string or QR frame list; the UI layer
11
+ * owns fragmenting into animated QR frames.
19
12
  */
20
13
  interface KeystoneUr {
21
14
  urType: string;
@@ -36,9 +29,8 @@ interface KeystoneParsedMultiAccounts {
36
29
  /** Model string (e.g. "Keystone 3 Pro"), present on both channels but not unique per unit. */
37
30
  device?: string;
38
31
  /**
39
- * Hardware-derived id (sha256(sha256(serial))). Only populated in specific
40
- * wallet-branded QR sync menus — firmware omits it on the generic
41
- * KeyDerivation path USB uses. Enrichment only; never key identity on it.
32
+ * sha256(sha256(serial)), only sent by some QR sync menus and never on the KeyDerivation path.
33
+ * Enrichment only; never key identity on it.
42
34
  */
43
35
  deviceId?: string;
44
36
  deviceVersion?: string;
@@ -46,7 +38,7 @@ interface KeystoneParsedMultiAccounts {
46
38
  }
47
39
  interface KeystoneEthSignRequestInput {
48
40
  requestId: string;
49
- /** Hex, no 0x prefix — raw unsigned payload matching dataType. */
41
+ /** Hex, no 0x prefix, raw unsigned payload matching dataType. */
50
42
  unsignedTxHex: string;
51
43
  dataType: 'transaction' | 'typedTransaction' | 'personalMessage' | 'typedData';
52
44
  path: string;
@@ -67,12 +59,7 @@ interface KeystoneBtcSignRequestAccount {
67
59
  xfp: string;
68
60
  address?: string;
69
61
  }
70
- /**
71
- * Standard BIP-44/49/84/86 purpose → script-type mapping. `p2tr` is a
72
- * recognized value but `KeystoneUrEngine.deriveBtcAddressFromXpub` doesn't
73
- * support it yet — taproot output-key tweaking needs an elliptic-curve
74
- * library (`bitcoinjs-lib`'s `initEccLib`) this package doesn't wire in.
75
- */
62
+ /** Script types for purposes 44'/49'/84'/86'; `p2tr` address derivation is not supported yet. */
76
63
  type BtcScriptType = 'p2pkh' | 'p2sh-p2wpkh' | 'p2wpkh' | 'p2tr';
77
64
  interface KeystoneSolSignRequestInput {
78
65
  requestId: string;
@@ -95,7 +82,7 @@ interface KeystoneBtcSignatureResult {
95
82
  /** Hex, no 0x prefix. */
96
83
  signature: string;
97
84
  }
98
- /** SLIP-10 for secp256k1 (EVM/BTC) and ed25519 (SOL); Cardano-style BIP32-Ed25519 is out of scope. */
85
+ /** SLIP-10 secp256k1 (EVM/BTC) and ed25519 (SOL); Cardano BIP32-Ed25519 is out of scope. */
99
86
  type KeystoneDerivationCurve = 'secp256k1' | 'ed25519';
100
87
  interface KeystoneKeySchema {
101
88
  path: string;
@@ -108,9 +95,8 @@ interface KeystoneKeyDerivationRequestInput {
108
95
  interface KeystoneTronSignRequestInput {
109
96
  requestId: string;
110
97
  /**
111
- * Hex, no 0x prefix. For a transaction: the TRON protobuf `Transaction.raw`
112
- * bytes (same as `TronSignTxParams.rawTxHex`). For a personal message:
113
- * the raw message bytes; the device applies the TIP-191 prefix itself.
98
+ * Hex, no 0x prefix: protobuf `Transaction.raw` bytes, or raw message bytes (the device applies
99
+ * the TIP-191 prefix itself).
114
100
  */
115
101
  rawTxHex: string;
116
102
  path: string;
@@ -121,14 +107,13 @@ interface KeystoneTronSignRequestInput {
121
107
  }
122
108
  interface KeystoneTronSignatureResult {
123
109
  requestId?: string;
124
- /** Hex, no 0x prefix — 65-byte secp256k1 signature. */
110
+ /** Hex, no 0x prefix, 65-byte secp256k1 signature. */
125
111
  signature: string;
126
112
  }
127
113
 
128
114
  /**
129
- * Single touch point with `@keystonehq/keystone-sdk`; the same UR building
130
- * and parsing serves QR and USB. Uses the bare constructor, not
131
- * `KeystoneSDK.create()`, which fetches remote config at call time.
115
+ * Single touch point with `@keystonehq/keystone-sdk`, shared by QR and USB. Uses the bare
116
+ * constructor: `KeystoneSDK.create()` fetches remote config at call time.
132
117
  */
133
118
  declare class KeystoneUrEngine {
134
119
  private readonly sdk;
@@ -136,60 +121,22 @@ declare class KeystoneUrEngine {
136
121
  parseMultiAccounts(ur: KeystoneUr): KeystoneParsedMultiAccounts;
137
122
  parseHDKey(ur: KeystoneUr): KeystoneParsedAccount;
138
123
  /**
139
- * Build a `qr-hardware-call` (KeyDerivation) request: the host asks for
140
- * specific paths instead of waiting for whatever the device happens to be
141
- * showing. The device replies with a `crypto-multi-accounts` UR — parse it
142
- * with `parseMultiAccounts`. Used for the implicit "sync this wallet's xfp
143
- * before the first sign" round trip as well as an explicit account import.
144
- *
145
- * `version: V1` is required — verified against real Keystone hardware and
146
- * `keystone3-firmware`'s `CheckHardwareCallRequestIsLegal` source: an
147
- * unversioned/V0 request is validated as a legacy Cardano-only request
148
- * (`m/1852'/1815'/...`) and firmware rejects every other chain's path with
149
- * `PRS_PARSING_ERROR` (device-shown message: "路径不受支持" / "path not
150
- * supported"), regardless of the path's shape. V1 is what actually enables
151
- * the general per-chain path whitelist (includes `m/44'/60'` for ETH, the
152
- * standard BTC purposes, etc.). The SDK itself defaults to V0 unless a
153
- * truthy `version` is passed — omitting this silently produces a request
154
- * every non-Cardano device rejects.
124
+ * Builds a KeyDerivation request. `version: V1` is required: firmware validates V0 (the SDK
125
+ * default) as Cardano-only and rejects other paths with `PRS_PARSING_ERROR`.
155
126
  */
156
127
  buildKeyDerivationRequest(input: KeystoneKeyDerivationRequestInput): KeystoneUr;
157
128
  /**
158
- * Parse the response to a KeyDerivation request (or a device-initiated
159
- * account export): `crypto-multi-accounts` for a multi-schema request,
160
- * `crypto-hdkey` for a single-key response some firmware paths use instead.
161
- * Both are normalized to the same `KeystoneParsedMultiAccounts` shape — a
162
- * single `crypto-hdkey` becomes a one-entry account list, with its own
163
- * `origin.sourceFingerprint` promoted to `masterFingerprint` (correct for a
164
- * key derived directly from the seed, which every request this engine
165
- * builds asks for).
129
+ * Normalizes `crypto-multi-accounts` and the single-key `crypto-hdkey` some firmware returns. The
130
+ * hdkey source fingerprint is the mfp only because every request here derives from the seed.
166
131
  */
167
132
  parseAccountResponse(ur: KeystoneUr): KeystoneParsedMultiAccounts;
168
133
  buildEthSignRequest(input: KeystoneEthSignRequestInput): KeystoneUr;
169
134
  parseEthSignature(ur: KeystoneUr): KeystoneEthSignatureResult;
170
- /**
171
- * Derive one EVM address offline from an already-synced account xpub —
172
- * verified against the same `@keystonehq/bc-ur-registry-eth` helper the
173
- * Keystone-based OneKey air-gap demo uses in production
174
- * (`generateAddressFromXpub`), so no unverified assumption about what a
175
- * leaf-path KeyDerivation request would return. `relativeDerivePath` is
176
- * relative to the xpub's own depth, e.g. `'0/0'` for an account xpub.
177
- */
135
+ /** Derives an EVM address offline; `relativeDerivePath` is relative to the xpub, e.g. `'0/0'`. */
178
136
  deriveEvmAddressFromXpub(xpub: string, relativeDerivePath: string): string;
179
137
  /**
180
- * Derive one BTC address offline from an already-synced account xpub, the
181
- * same way `deriveEvmAddressFromXpub` does. Keystone's `CryptoHDKey`
182
- * always emits standard mainnet-xpub version bytes (`0488B21E`) regardless
183
- * of the account's purpose/script type (verified against
184
- * `@keystonehq/bc-ur-registry`'s `CryptoHDKey.getBip32Key`, which hardcodes
185
- * that version rather than switching to a SLIP-132 ypub/zpub prefix per
186
- * script type) — so `hdkey.fromExtendedKey` parses it correctly for every
187
- * `scriptType` without needing custom version bytes configured.
188
- *
189
- * `p2tr` is deliberately not handled: taproot output-key tweaking (BIP-341)
190
- * needs an elliptic-curve library wired via bitcoinjs-lib's `initEccLib`,
191
- * which this package doesn't set up yet — every other payment function
192
- * here needs no such library.
138
+ * `CryptoHDKey` always emits mainnet xpub version bytes (`0488B21E`), so `hdkey` parses it as is.
139
+ * `p2tr` needs an ECC lib for BIP-341 tweaking, not wired here.
193
140
  */
194
141
  deriveBtcAddressFromXpub(xpub: string, relativeDerivePath: string, scriptType: BtcScriptType): string;
195
142
  deriveBtcAddressFromPublicKey(publicKeyHex: string, scriptType: BtcScriptType): string;
@@ -213,23 +160,11 @@ declare class KeystoneUrEngine {
213
160
  buildTronSignRequest(input: KeystoneTronSignRequestInput): KeystoneUr;
214
161
  parseTronSignature(ur: KeystoneUr): KeystoneTronSignatureResult;
215
162
  /**
216
- * Derive one TRON address offline from an already-synced account xpub.
217
- * TRON reuses EVM's exact secp256k1-pubkey → keccak256 → last-20-bytes
218
- * derivation (verified against Keystone's own `formatAddress()` in
219
- * `keystone-sdk`'s TRON chain source) — only the final text encoding
220
- * differs (base58check with a `0x41` version byte, not checksummed hex).
221
- * Reusing `generateAddressFromXpub` here means no new hashing dependency:
222
- * strip its "0x" and re-encode the same 20 bytes.
163
+ * TRON uses the same 20 address bytes as EVM (Keystone's `formatAddress()`), re-encoded as
164
+ * base58check with the `0x41` version byte.
223
165
  */
224
166
  deriveTronAddressFromXpub(xpub: string, relativeDerivePath: string): string;
225
- /**
226
- * Split an account-level xpub back into the BIP-32 fields a host needs to
227
- * treat it as a real extended key (`BtcPublicKey`). Everything here is
228
- * carried inside the xpub's own serialization — depth, the PARENT key
229
- * fingerprint (not the seed's master fingerprint), the chain code and the
230
- * compressed public key — so this is a pure decode with no device round
231
- * trip; the xpub itself was already device-verified when it was synced.
232
- */
167
+ /** Decodes an xpub's BIP-32 fields; `parentFingerprint` is the parent key's, not the mfp. */
233
168
  parseXpubMeta(xpub: string): {
234
169
  publicKey: string;
235
170
  chainCode: string;
@@ -239,17 +174,15 @@ declare class KeystoneUrEngine {
239
174
  }
240
175
 
241
176
  declare const KEYSTONE_WALLET_CONNECT_ID_PREFIX = "keystone-wallet:";
242
- /** Fixed public source used to derive a collision-resistant wallet id. */
243
- declare const KEYSTONE_WALLET_ID_PATH = "m/44'/60'/0'";
244
- declare function walletConnectId(walletId: string): string;
177
+ /** Account a QR cold start requests when the caller named no path; any path returns the mfp. */
178
+ declare const KEYSTONE_COLD_START_PATH = "m/44'/60'/0'";
179
+ declare function walletConnectId(masterFingerprint: string): string;
245
180
  interface KeystoneAccountEntry extends KeystoneParsedAccount {
246
181
  hwkChain: ChainCapability;
247
182
  }
248
183
  declare function accountKey(hwkChain: ChainCapability, path: string): string;
249
184
  interface KeystoneDeviceRecord {
250
- /** SHA-256 id derived from the fixed account-level identity xpub. */
251
- walletId: string;
252
- /** Lowercase 8-char BIP32 fingerprint used by BC-UR as xfp, never as identity. */
185
+ /** Lowercase 8-char BIP32 master fingerprint: the wallet identity and the BC-UR xfp. */
253
186
  masterFingerprint: string;
254
187
  connectId: string;
255
188
  /** Optional physical-device id exposed by some Keystone QR export menus. */
@@ -258,49 +191,33 @@ interface KeystoneDeviceRecord {
258
191
  model?: string;
259
192
  deviceVersion?: string;
260
193
  importedAt: number;
261
- /**
262
- * Set to the connector's process-local `sessionId` once a live USB session exists for
263
- * this wallet. Cleared by `releaseOperation`. Presence of this field is
264
- * what `KeystoneAdapter._resolveUr` uses to route a call over USB instead
265
- * of QR.
266
- */
194
+ /** Connector session id while a live USB session exists; its presence routes calls over USB. */
267
195
  usbSessionId?: string;
268
196
  /**
269
- * Remains true after a live USB session is lost. It allows the adapter to
270
- * wait through the device's short USB re-enumeration window without making
271
- * wallets that have only ever used QR pay the same retry delay.
197
+ * Stays true after the USB session is lost, so only these wallets wait through the device's
198
+ * USB re-enumeration window.
272
199
  */
273
200
  hadUsbSession?: boolean;
274
- /**
275
- * True once this wallet has completed at least one QR round trip.
276
- * Distinguishes "USB session dropped but this wallet was also QR-synced —
277
- * fall back to a QR-only entry" from "this was a USB-only wallet that
278
- * never synced over QR — drop the entry entirely" on USB disconnect.
279
- */
201
+ /** True after one QR round trip; on USB disconnect it decides demote-to-QR versus drop. */
280
202
  qrSynced?: boolean;
281
203
  }
282
- declare function deriveKeystoneWalletId(accounts: KeystoneParsedAccount[]): string;
283
- declare function createDeviceRecord(walletId: string, masterFingerprint: string): KeystoneDeviceRecord;
204
+ declare function createDeviceRecord(masterFingerprint: string): KeystoneDeviceRecord;
284
205
  declare function toDeviceInfo(record: KeystoneDeviceRecord): DeviceInfo;
285
- /** A device row for a wallet the adapter hasn't synced yet — used while a cold-start round trip is in flight. */
206
+ /** Device row for a not-yet-synced wallet during a cold-start round trip. */
286
207
  declare function placeholderDeviceInfo(): DeviceInfo;
287
208
 
288
209
  /** Key material for one operation, keyed by `accountKey()`; never retained. */
289
210
  type AccountBook = Map<string, KeystoneAccountEntry>;
290
211
  interface ImportFromQrOptions {
291
212
  /**
292
- * 'request': ask the device for the fixed identity xpub via a
293
- * `qr-hardware-call` (KeyDerivation) UR. 'scan': just wait for whatever
294
- * multi-account/HD-key export the device is already showing. Either way
295
- * only the wallet identity is learned; key material is never retained.
213
+ * 'request' asks the device for one account; 'scan' waits for whatever export it already shows.
214
+ * Only the wallet's master fingerprint is learned either way.
296
215
  */
297
216
  mode?: 'request' | 'scan';
298
217
  }
299
218
  /**
300
- * Keystone adapter: QR and USB behind one `IHardwareWallet`, keyed by a
301
- * wallet id derived from the fixed identity xpub. `_resolveUr` picks the
302
- * channel per request (USB when a session exists, else QR). Key material
303
- * is fetched per operation and never retained on the wallet record.
219
+ * QR and USB behind one `IHardwareWallet`, keyed by the wallet's BIP32 master fingerprint.
220
+ * Key material is fetched per operation and never retained.
304
221
  */
305
222
  declare class KeystoneAdapter implements IHardwareWallet {
306
223
  readonly vendor: "keystone";
@@ -315,17 +232,18 @@ declare class KeystoneAdapter implements IHardwareWallet {
315
232
  private readonly _searchDeviceTargets;
316
233
  private _activeSearchGeneration;
317
234
  private readonly _origin;
318
- /** 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. */
235
+ /** Host answer timeout for QR display/scan requests; undefined uses the registry default. */
319
236
  private readonly _qrTimeoutMs;
320
- /** 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. */
237
+ /** Host-supplied USB connector; undefined means QR-only. */
321
238
  private readonly _usbConnector;
322
239
  /** Serializes USB open/identity handshakes that run outside the job queue. */
323
240
  private _usbConnectTail;
324
241
  private readonly _unsettledUsbOperations;
325
242
  private readonly _usbIdleWaiters;
243
+ private _abandonedUsbConnects;
326
244
  private _usbTeardownTail;
327
245
  private _pendingUsbTeardowns;
328
- /** Explicit `switchTransport` pin. `undefined` means "auto": USB when a live session exists for the target wallet, else QR. */
246
+ /** `switchTransport` pin; undefined means USB when the wallet has a live session, else QR. */
329
247
  private _forcedTransport;
330
248
  private readonly _handleUsbDisconnect;
331
249
  private readonly _handleUsbUiEvent;
@@ -336,31 +254,24 @@ declare class KeystoneAdapter implements IHardwareWallet {
336
254
  });
337
255
  get activeTransport(): TransportType | null;
338
256
  getAvailableTransports(): TransportType[];
339
- /** 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. */
257
+ /** Pins calls to 'qr' or 'usb'; any other value clears the pin back to auto routing. */
340
258
  switchTransport(type: TransportType): Promise<void>;
341
259
  init(_config?: unknown): Promise<void>;
342
260
  dispose(): Promise<void>;
343
261
  /**
344
- * Unscoped discovery includes QR-synced wallets already known to this
345
- * adapter. Explicit QR discovery returns a virtual connection target because
346
- * there is no physical descriptor to enumerate. When a USB connector is
347
- * configured, its raw scan results are appended as-is: a USB descriptor has
348
- * no mfp until `connectDevice()` actually opens+claims it (see
349
- * `KeystoneUsbConnectorBase.searchDevices`), so these entries carry an
350
- * empty `deviceId` and exist purely so a host can list "plugged in, click
351
- * to connect" candidates.
262
+ * Returns known wallets plus USB scan results; USB entries have no mfp until `connectDevice()`
263
+ * claims them. Explicit QR discovery returns one virtual target.
352
264
  */
353
265
  searchDevices(options?: SearchDevicesOptions): Promise<DeviceInfo[]>;
354
266
  private _resetUsbSessions;
267
+ /** Best-effort disconnect; the session is retired either way so it cannot be selected again. */
268
+ private _retireUsbSession;
355
269
  searchDeviceTargets(options?: SearchDevicesOptions): Promise<DeviceSearchTarget[]>;
356
270
  listConnectionTargets(options?: SearchDevicesOptions): Promise<ConnectionTarget[]>;
357
271
  connectDevice(searchTargetId: string): Promise<Response<string>>;
358
272
  /**
359
- * QR has no persistent connection to tear down — the account cache
360
- * survives so a later call resumes without re-syncing. For a USB session,
361
- * this closes the connector session and either demotes the record back to
362
- * QR-only (if it was ever QR-synced) or removes it entirely (pure-USB
363
- * wallet that was never seen over QR) — see §4.2 of the design doc.
273
+ * QR has nothing to tear down. A USB session is closed, and the record is demoted to QR-only or
274
+ * removed if it was never QR-synced.
364
275
  */
365
276
  releaseOperation(operationId: string): Promise<void>;
366
277
  private _releaseOperationConnection;
@@ -374,127 +285,88 @@ declare class KeystoneAdapter implements IHardwareWallet {
374
285
  off(event: string, listener: DeviceEventListener): void;
375
286
  importFromQr(options?: ImportFromQrOptions): Promise<Response<DeviceInfo>>;
376
287
  allNetworkGetAddress: (connectId: string, deviceId: string, params: AllNetworkGetAddressParams) => Promise<Response<AllNetworkAddressResponse[]>>;
377
- evmGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<EvmGetAddressParams>>, book?: AccountBook): Promise<Response<EvmAddress>>;
378
- evmSignTransaction(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<EvmSignTxParams>>): Promise<Response<EvmSignedTx>>;
379
- evmSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<EvmSignMsgParams>>): Promise<Response<EvmSignature>>;
380
- evmSignTypedData(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<EvmSignTypedDataParams>>): Promise<Response<EvmSignature>>;
381
- btcGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<BtcGetAddressParams>>, book?: AccountBook): Promise<Response<BtcAddress>>;
288
+ evmGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<EvmGetAddressParams>>, book?: AccountBook): Promise<Response<EvmAddress>>;
289
+ evmSignTransaction(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<EvmSignTxParams>>): Promise<Response<EvmSignedTx>>;
290
+ evmSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<EvmSignMsgParams>>): Promise<Response<EvmSignature>>;
291
+ evmSignTypedData(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<EvmSignTypedDataParams>>): Promise<Response<EvmSignature>>;
292
+ btcGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<BtcGetAddressParams>>, book?: AccountBook): Promise<Response<BtcAddress>>;
382
293
  /**
383
- * Returns the account-level extended public key. `params.path` must be an
384
- * ACCOUNT path (`m/84'/0'/0'`), not a leaf — that is the level Keystone
385
- * actually syncs, and it is what a host needs to derive a whole account's
386
- * addresses offline. Unlike `btcGetAddress` this has no script-type
387
- * restriction: an xpub is script-type agnostic, so `86'` (taproot) works
388
- * here even though deriving a taproot ADDRESS still needs an EC library
389
- * this package doesn't wire in.
294
+ * `params.path` must be an account path (`m/84'/0'/0'`), the level Keystone syncs. An xpub is
295
+ * script-type agnostic, so `86'` works here even though `btcGetAddress` rejects it.
390
296
  */
391
- btcGetPublicKey(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<BtcGetPublicKeyParams>>, book?: AccountBook): Promise<Response<BtcPublicKey>>;
297
+ btcGetPublicKey(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<BtcGetPublicKeyParams>>, book?: AccountBook): Promise<Response<BtcPublicKey>>;
392
298
  btcSignTransaction(_connectId?: NullableCallArg<string>, _deviceId?: NullableCallArg<string>, _params?: NullableCallArg<IHardwareCallParams<BtcSignTxParams>>): Promise<Response<BtcSignedTx>>;
393
- btcSignPsbt(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<BtcSignPsbtParams>>): Promise<Response<BtcSignedPsbt>>;
394
- btcSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<BtcSignMsgParams>>): Promise<Response<BtcSignature>>;
299
+ btcSignPsbt(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<BtcSignPsbtParams>>): Promise<Response<BtcSignedPsbt>>;
300
+ btcSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<BtcSignMsgParams>>): Promise<Response<BtcSignature>>;
395
301
  btcGetMasterFingerprint(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCommonCallParams>): Promise<Response<{
396
302
  masterFingerprint: string;
397
303
  }>>;
398
- solGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<SolGetAddressParams>>, book?: AccountBook): Promise<Response<SolAddress>>;
399
- solSignTransaction(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<SolSignTxParams>>): Promise<Response<SolSignedTx>>;
400
- solSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<SolSignMsgParams>>): Promise<Response<SolSignature>>;
401
- tronGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<TronGetAddressParams>>, book?: AccountBook): Promise<Response<TronAddress>>;
402
- tronSignTransaction(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<TronSignTxParams>>): Promise<Response<TronSignedTx>>;
403
- tronSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<TronSignMsgParams>>): Promise<Response<TronSignature>>;
404
- private _walletIdFromIdentifier;
405
- private _allNetworkSyncSchema;
304
+ solGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<SolGetAddressParams>>, book?: AccountBook): Promise<Response<SolAddress>>;
305
+ solSignTransaction(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<SolSignTxParams>>): Promise<Response<SolSignedTx>>;
306
+ solSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<SolSignMsgParams>>): Promise<Response<SolSignature>>;
307
+ tronGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<TronGetAddressParams>>, book?: AccountBook): Promise<Response<TronAddress>>;
308
+ tronSignTransaction(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<TronSignTxParams>>): Promise<Response<TronSignedTx>>;
309
+ tronSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<TronSignMsgParams>>): Promise<Response<TronSignature>>;
310
+ private _runJob;
311
+ private _fetchAccountXpub;
406
312
  /**
407
- * QR is an interactive batch transport: one account-creation action must
408
- * produce one request QR and one response scan, regardless of how many
409
- * chains or derivation paths the host bundled. USB keeps its proven
410
- * one-path-at-a-time export flow because the device limits that channel.
313
+ * Signing needs only the wallet's mfp: the device re-derives the key from path+xfp, so no
314
+ * per-path account lookup happens here.
411
315
  */
412
- private _prefetchAllNetworkAccounts;
316
+ private _signWithWallet;
317
+ private _allNetworkSyncSchema;
413
318
  /**
414
- * Resolve only the stable 64-hex wallet identity. The 8-hex BIP32 master
415
- * fingerprint is protocol metadata and is never accepted as a lookup key.
319
+ * QR answers the whole bundle with one request QR and one scan. USB exports one path per
320
+ * request because the device limits that channel.
416
321
  */
322
+ private _prefetchAllNetworkAccounts;
323
+ /** Resolve the wallet's master fingerprint from the connectId and/or deviceId the caller passed. */
417
324
  private _resolveTarget;
418
325
  private _assertParsedIdentity;
419
326
  /**
420
- * Folds a parsed account-response UR into the device table. `viaUsb`
421
- * (defaults false) says which channel actually carried this round trip —
422
- * `_resolveUr` routes a KeyDerivation sync over USB when the target record
423
- * already has a live session, so this must NOT unconditionally mark
424
- * `qrSynced`, or a USB-only wallet would wrongly survive a later USB
425
- * disconnect as a "QR-synced, demote to QR-only" entry instead of being
426
- * dropped outright (see `releaseOperation`).
327
+ * Folds a parsed account response into the device table. Only non-USB round trips mark
328
+ * `qrSynced`, so a USB-only wallet is dropped on disconnect.
427
329
  */
428
330
  private _upsertDeviceRecord;
429
331
  /**
430
- * Opens+claims whatever Keystone the USB connector currently has
431
- * permission for, learns its protocol mfp via `getAppConfig`, then requests
432
- * one fixed account-level xpub and derives the stable wallet id. A
433
- * QR-synced entry becomes
434
- * `{qr, usb}`-capable in place (one `device-changed`, not a second
435
- * `device-connect`); a wallet never seen before becomes a new USB-only
436
- * entry. See §4.2 of the design doc.
332
+ * Opens a permitted USB Keystone and takes its mfp as the wallet identity. A known wallet gains
333
+ * USB in place (`device-changed`); an unseen one becomes USB-only.
437
334
  */
438
335
  private _connectUsb;
439
336
  private _connectUsbExclusive;
440
337
  /**
441
- * Probe already-authorized USB devices without opening a permission picker,
442
- * then attach and verify the requested wallet when one is present. This is
443
- * used both after an adapter restart and after a QR-only period, so plugging
444
- * USB back in affects the next business call without changing an in-flight
445
- * QR operation.
338
+ * Probes already-authorized USB devices without a permission picker, then attaches and verifies
339
+ * the requested wallet if present.
446
340
  */
447
341
  private _tryUsbAttach;
448
342
  /**
449
- * The one place that decides QR vs. USB for a UR round trip and carries it
450
- * out. `record` is the (possibly not-yet-existing, for a true cold start)
451
- * device row for the target wallet. USB is the preferred channel: a known
452
- * wallet record with no live session gets ONE best-effort re-attach here,
453
- * and anything that goes wrong just leaves the call on QR. A
454
- * `switchTransport('qr')` pin forces QR even for a USB-attached wallet;
455
- * `switchTransport('usb')` on a wallet with no live USB session fails
456
- * closed rather than silently falling back to QR.
343
+ * Decides QR vs USB for one UR round trip. A pinned 'usb' with no live session fails closed;
344
+ * otherwise a failed USB reattach leaves the call on QR.
457
345
  */
458
346
  private _resolveUr;
459
347
  private _resolveUrWithRoute;
348
+ /** Ends the operation as disconnected and returns the error to throw. */
349
+ private _endDisconnectedOperation;
460
350
  /**
461
- * Fetch one account's key material from the device for this operation only.
462
- * `book` lets earlier fetches of the same operation be reused; nothing is
463
- * retained on the record. A failed USB export ends this operation without
464
- * replaying the request or switching transports.
351
+ * Fetches one account's key material for this operation only; `book` reuses earlier fetches. A
352
+ * failed USB export ends the operation without replaying or switching transports.
465
353
  */
466
354
  private _fetchAccount;
467
355
  /**
468
- * Like `_fetchAccount`, but for operations (PSBT signing, master
469
- * fingerprint) that only need to know WHICH wallet is attached, not a
470
- * specific cached path. Syncs the account-level path for `chain` as a
471
- * throwaway probe when the wallet record isn't already known.
472
- *
473
- * `CHAIN_FINGERPRINT_PATHS[chain]` is a 5-segment LEAF path for `evm`
474
- * (`m/44'/60'/0'/0/0`) — sending that verbatim as a KeyDerivation request
475
- * asks Keystone for a non-standard path. Keystone's own docs
476
- * (dev.keyst.one's multichain KeyDerivation example) show the ETH
477
- * account-level path as `m/44'/60'/0'` (3 segments), same as what
478
- * `_fetchAccount` already requests — so
479
- * truncate through `splitAccountPath` here too instead of using the raw
480
- * fingerprint leaf path. `btc`/`sol` are already 3-segment account paths
481
- * and pass through unchanged.
356
+ * Resolves which wallet is attached, without a per-path account. `CHAIN_FINGERPRINT_PATHS.evm` is
357
+ * a leaf path, so it is cut to the account path Keystone expects.
482
358
  */
483
359
  private _ensureWalletKnown;
484
360
  /**
485
- * The operation the running device job belongs to, so a UI request raised
486
- * mid-call can name it. A call pinned to an operation queues under its id
487
- * (`keystoneQueueKey`); a call without one queues under the wallet id or the
488
- * wallet connectId, and the live operation routed to that connection is still
489
- * the owner. Only a cold start comes back undefined.
361
+ * The operation owning the running job, so a mid-call UI request can name it. Unpinned jobs map
362
+ * through the operation route; a cold start returns undefined.
490
363
  */
491
364
  private _activeOperationId;
492
- /** Routes are keyed by connectId; a job key may be the bare wallet id. */
365
+ /** Routes are keyed by connectId; a job key may be the bare master fingerprint. */
493
366
  private _operationRouteForIdentifier;
494
367
  /**
495
- * A QR prompt has no transport to interrupt, so an aborted job would sit here
496
- * until the QR timeout. Releasing the registry slot on abort is what lets a
497
- * cancel reach the wait at all.
368
+ * A QR prompt has no transport to interrupt; releasing the registry slot on abort is what lets
369
+ * a cancel reach the wait before the QR timeout.
498
370
  */
499
371
  private _awaitQrResponse;
500
372
  private _requestQrDisplayAndAwaitResponse;
@@ -513,26 +385,14 @@ declare class KeystoneAdapter implements IHardwareWallet {
513
385
  /** Always returns an `m/`-prefixed path, regardless of the input's casing/prefix. */
514
386
  declare function normalizePath(path: string): string;
515
387
  /**
516
- * Split a full BIP-44 leaf path (`purpose'/coin'/account'/change/index`, 5
517
- * segments) into its 3-segment account path and the relative `change/index`
518
- * path from that account to the leaf. Matches the OneKey Keystone air-gap
519
- * demo's `removePathLastSegment({removeCount: 2})` convention, which is
520
- * verified against real Keystone hardware.
521
- *
522
- * A path with 3 or fewer segments IS already an account path (or shorter) —
523
- * BIP-44's account level is exactly 3 hardened components — so there is
524
- * nothing to split off: `relativeDerivePath` is empty and `accountPath` is
525
- * the (normalized) input unchanged.
388
+ * Splits a 5-segment BIP-44 leaf path into the 3-segment account path and the relative
389
+ * `change/index`; a path of 3 or fewer segments is already an account path.
526
390
  */
527
391
  declare function splitAccountPath(path: string): {
528
392
  accountPath: string;
529
393
  relativeDerivePath: string;
530
394
  };
531
- /**
532
- * Standard BIP-44/49/84/86 purpose → script-type mapping. Returns `undefined`
533
- * for a path whose purpose isn't one of these four (or isn't parseable),
534
- * rather than guessing.
535
- */
395
+ /** BIP-44/49/84/86 purpose to script type; undefined for any other purpose. */
536
396
  declare function btcScriptTypeFromPath(path: string): BtcScriptType | undefined;
537
397
 
538
- export { type BtcScriptType, type ImportFromQrOptions, KEYSTONE_WALLET_CONNECT_ID_PREFIX, KEYSTONE_WALLET_ID_PATH, type KeystoneAccountEntry, KeystoneAdapter, type KeystoneBtcSignRequestAccount, type KeystoneBtcSignatureResult, type KeystoneDerivationCurve, type KeystoneDeviceRecord, type KeystoneEthSignRequestInput, type KeystoneEthSignatureResult, type KeystoneKeyDerivationRequestInput, type KeystoneKeySchema, type KeystoneParsedAccount, type KeystoneParsedMultiAccounts, type KeystoneSolSignRequestInput, type KeystoneSolSignatureResult, type KeystoneTronSignRequestInput, type KeystoneTronSignatureResult, type KeystoneUr, KeystoneUrEngine, accountKey, btcScriptTypeFromPath, createDeviceRecord, deriveKeystoneWalletId, normalizePath, placeholderDeviceInfo, splitAccountPath, toDeviceInfo, walletConnectId };
398
+ export { type BtcScriptType, type ImportFromQrOptions, KEYSTONE_COLD_START_PATH, KEYSTONE_WALLET_CONNECT_ID_PREFIX, type KeystoneAccountEntry, KeystoneAdapter, type KeystoneBtcSignRequestAccount, type KeystoneBtcSignatureResult, type KeystoneDerivationCurve, type KeystoneDeviceRecord, type KeystoneEthSignRequestInput, type KeystoneEthSignatureResult, type KeystoneKeyDerivationRequestInput, type KeystoneKeySchema, type KeystoneParsedAccount, type KeystoneParsedMultiAccounts, type KeystoneSolSignRequestInput, type KeystoneSolSignatureResult, type KeystoneTronSignRequestInput, type KeystoneTronSignatureResult, type KeystoneUr, KeystoneUrEngine, accountKey, btcScriptTypeFromPath, createDeviceRecord, normalizePath, placeholderDeviceInfo, splitAccountPath, toDeviceInfo, walletConnectId };