@onekeyfe/hwk-keystone-adapter 1.2.3-alpha.4 → 1.2.5-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/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;
@@ -258,52 +193,38 @@ interface KeystoneDeviceRecord {
258
193
  model?: string;
259
194
  deviceVersion?: string;
260
195
  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
- */
196
+ /** Connector session id while a live USB session exists; its presence routes calls over USB. */
267
197
  usbSessionId?: string;
268
198
  /**
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.
199
+ * Stays true after the USB session is lost, so only these wallets wait through the device's
200
+ * USB re-enumeration window.
272
201
  */
273
202
  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
- */
203
+ /** True after one QR round trip; on USB disconnect it decides demote-to-QR versus drop. */
280
204
  qrSynced?: boolean;
281
205
  }
282
206
  declare function deriveKeystoneWalletId(accounts: KeystoneParsedAccount[]): string;
283
207
  declare function createDeviceRecord(walletId: string, masterFingerprint: string): KeystoneDeviceRecord;
284
208
  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. */
209
+ /** Device row for a not-yet-synced wallet during a cold-start round trip. */
286
210
  declare function placeholderDeviceInfo(): DeviceInfo;
287
211
 
288
212
  /** Key material for one operation, keyed by `accountKey()`; never retained. */
289
213
  type AccountBook = Map<string, KeystoneAccountEntry>;
290
214
  interface ImportFromQrOptions {
291
215
  /**
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.
216
+ * 'request' asks the device for the identity xpub; 'scan' waits for whatever export it already
217
+ * shows. Only the wallet identity is learned either way.
296
218
  */
297
219
  mode?: 'request' | 'scan';
298
220
  }
299
221
  /**
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.
222
+ * QR and USB behind one `IHardwareWallet`, keyed by a wallet id derived from the identity xpub.
223
+ * Key material is fetched per operation and never retained.
304
224
  */
305
225
  declare class KeystoneAdapter implements IHardwareWallet {
306
226
  readonly vendor: "keystone";
227
+ readonly cancelCapability: "stops-waiting";
307
228
  private readonly urEngine;
308
229
  private readonly emitter;
309
230
  private readonly _operationRoutes;
@@ -314,17 +235,18 @@ declare class KeystoneAdapter implements IHardwareWallet {
314
235
  private readonly _searchDeviceTargets;
315
236
  private _activeSearchGeneration;
316
237
  private readonly _origin;
317
- /** 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. */
238
+ /** Host answer timeout for QR display/scan requests; undefined uses the registry default. */
318
239
  private readonly _qrTimeoutMs;
319
- /** 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. */
240
+ /** Host-supplied USB connector; undefined means QR-only. */
320
241
  private readonly _usbConnector;
321
242
  /** Serializes USB open/identity handshakes that run outside the job queue. */
322
243
  private _usbConnectTail;
323
244
  private readonly _unsettledUsbOperations;
324
245
  private readonly _usbIdleWaiters;
246
+ private _abandonedUsbConnects;
325
247
  private _usbTeardownTail;
326
248
  private _pendingUsbTeardowns;
327
- /** Explicit `switchTransport` pin. `undefined` means "auto": USB when a live session exists for the target wallet, else QR. */
249
+ /** `switchTransport` pin; undefined means USB when the wallet has a live session, else QR. */
328
250
  private _forcedTransport;
329
251
  private readonly _handleUsbDisconnect;
330
252
  private readonly _handleUsbUiEvent;
@@ -335,31 +257,24 @@ declare class KeystoneAdapter implements IHardwareWallet {
335
257
  });
336
258
  get activeTransport(): TransportType | null;
337
259
  getAvailableTransports(): TransportType[];
338
- /** 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. */
260
+ /** Pins calls to 'qr' or 'usb'; any other value clears the pin back to auto routing. */
339
261
  switchTransport(type: TransportType): Promise<void>;
340
262
  init(_config?: unknown): Promise<void>;
341
263
  dispose(): Promise<void>;
342
264
  /**
343
- * Unscoped discovery includes QR-synced wallets already known to this
344
- * adapter. Explicit QR discovery returns a virtual connection target because
345
- * there is no physical descriptor to enumerate. When a USB connector is
346
- * configured, its raw scan results are appended as-is: a USB descriptor has
347
- * no mfp until `connectDevice()` actually opens+claims it (see
348
- * `KeystoneUsbConnectorBase.searchDevices`), so these entries carry an
349
- * empty `deviceId` and exist purely so a host can list "plugged in, click
350
- * to connect" candidates.
265
+ * Returns known wallets plus USB scan results; USB entries have no mfp until `connectDevice()`
266
+ * claims them. Explicit QR discovery returns one virtual target.
351
267
  */
352
268
  searchDevices(options?: SearchDevicesOptions): Promise<DeviceInfo[]>;
353
269
  private _resetUsbSessions;
270
+ /** Best-effort disconnect; the session is retired either way so it cannot be selected again. */
271
+ private _retireUsbSession;
354
272
  searchDeviceTargets(options?: SearchDevicesOptions): Promise<DeviceSearchTarget[]>;
355
273
  listConnectionTargets(options?: SearchDevicesOptions): Promise<ConnectionTarget[]>;
356
274
  connectDevice(searchTargetId: string): Promise<Response<string>>;
357
275
  /**
358
- * QR has no persistent connection to tear down — the account cache
359
- * survives so a later call resumes without re-syncing. For a USB session,
360
- * this closes the connector session and either demotes the record back to
361
- * QR-only (if it was ever QR-synced) or removes it entirely (pure-USB
362
- * wallet that was never seen over QR) — see §4.2 of the design doc.
276
+ * QR has nothing to tear down. A USB session is closed, and the record is demoted to QR-only or
277
+ * removed if it was never QR-synced.
363
278
  */
364
279
  releaseOperation(operationId: string): Promise<void>;
365
280
  private _releaseOperationConnection;
@@ -373,40 +288,39 @@ declare class KeystoneAdapter implements IHardwareWallet {
373
288
  off(event: string, listener: DeviceEventListener): void;
374
289
  importFromQr(options?: ImportFromQrOptions): Promise<Response<DeviceInfo>>;
375
290
  allNetworkGetAddress: (connectId: string, deviceId: string, params: AllNetworkGetAddressParams) => Promise<Response<AllNetworkAddressResponse[]>>;
376
- evmGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<EvmGetAddressParams>>, book?: AccountBook): Promise<Response<EvmAddress>>;
377
- evmSignTransaction(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<EvmSignTxParams>>): Promise<Response<EvmSignedTx>>;
378
- evmSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<EvmSignMsgParams>>): Promise<Response<EvmSignature>>;
379
- evmSignTypedData(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<EvmSignTypedDataParams>>): Promise<Response<EvmSignature>>;
380
- btcGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<BtcGetAddressParams>>, book?: AccountBook): Promise<Response<BtcAddress>>;
291
+ evmGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<EvmGetAddressParams>>, book?: AccountBook): Promise<Response<EvmAddress>>;
292
+ evmSignTransaction(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<EvmSignTxParams>>): Promise<Response<EvmSignedTx>>;
293
+ evmSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<EvmSignMsgParams>>): Promise<Response<EvmSignature>>;
294
+ evmSignTypedData(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<EvmSignTypedDataParams>>): Promise<Response<EvmSignature>>;
295
+ btcGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<BtcGetAddressParams>>, book?: AccountBook): Promise<Response<BtcAddress>>;
381
296
  /**
382
- * Returns the account-level extended public key. `params.path` must be an
383
- * ACCOUNT path (`m/84'/0'/0'`), not a leaf — that is the level Keystone
384
- * actually syncs, and it is what a host needs to derive a whole account's
385
- * addresses offline. Unlike `btcGetAddress` this has no script-type
386
- * restriction: an xpub is script-type agnostic, so `86'` (taproot) works
387
- * here even though deriving a taproot ADDRESS still needs an EC library
388
- * this package doesn't wire in.
297
+ * `params.path` must be an account path (`m/84'/0'/0'`), the level Keystone syncs. An xpub is
298
+ * script-type agnostic, so `86'` works here even though `btcGetAddress` rejects it.
389
299
  */
390
- btcGetPublicKey(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<BtcGetPublicKeyParams>>, book?: AccountBook): Promise<Response<BtcPublicKey>>;
300
+ btcGetPublicKey(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<BtcGetPublicKeyParams>>, book?: AccountBook): Promise<Response<BtcPublicKey>>;
391
301
  btcSignTransaction(_connectId?: NullableCallArg<string>, _deviceId?: NullableCallArg<string>, _params?: NullableCallArg<IHardwareCallParams<BtcSignTxParams>>): Promise<Response<BtcSignedTx>>;
392
- btcSignPsbt(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<BtcSignPsbtParams>>): Promise<Response<BtcSignedPsbt>>;
393
- btcSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<BtcSignMsgParams>>): Promise<Response<BtcSignature>>;
302
+ btcSignPsbt(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<BtcSignPsbtParams>>): Promise<Response<BtcSignedPsbt>>;
303
+ btcSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<BtcSignMsgParams>>): Promise<Response<BtcSignature>>;
394
304
  btcGetMasterFingerprint(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCommonCallParams>): Promise<Response<{
395
305
  masterFingerprint: string;
396
306
  }>>;
397
- solGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<SolGetAddressParams>>, book?: AccountBook): Promise<Response<SolAddress>>;
398
- solSignTransaction(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<SolSignTxParams>>): Promise<Response<SolSignedTx>>;
399
- solSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<SolSignMsgParams>>): Promise<Response<SolSignature>>;
400
- tronGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<TronGetAddressParams>>, book?: AccountBook): Promise<Response<TronAddress>>;
401
- tronSignTransaction(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<TronSignTxParams>>): Promise<Response<TronSignedTx>>;
402
- tronSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, paramsArg?: NullableCallArg<IHardwareCallParams<TronSignMsgParams>>): Promise<Response<TronSignature>>;
403
- private _walletIdFromIdentifier;
307
+ solGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<SolGetAddressParams>>, book?: AccountBook): Promise<Response<SolAddress>>;
308
+ solSignTransaction(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<SolSignTxParams>>): Promise<Response<SolSignedTx>>;
309
+ solSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<SolSignMsgParams>>): Promise<Response<SolSignature>>;
310
+ tronGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<TronGetAddressParams>>, book?: AccountBook): Promise<Response<TronAddress>>;
311
+ tronSignTransaction(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<TronSignTxParams>>): Promise<Response<TronSignedTx>>;
312
+ tronSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>, params?: NullableCallArg<IHardwareCallParams<TronSignMsgParams>>): Promise<Response<TronSignature>>;
313
+ private _runJob;
314
+ private _fetchAccountXpub;
315
+ /**
316
+ * Signing needs only the wallet's mfp: the device re-derives the key from path+xfp, so no
317
+ * per-path account lookup happens here.
318
+ */
319
+ private _signWithWallet;
404
320
  private _allNetworkSyncSchema;
405
321
  /**
406
- * QR is an interactive batch transport: one account-creation action must
407
- * produce one request QR and one response scan, regardless of how many
408
- * chains or derivation paths the host bundled. USB keeps its proven
409
- * one-path-at-a-time export flow because the device limits that channel.
322
+ * QR answers the whole bundle with one request QR and one scan. USB exports one path per
323
+ * request because the device limits that channel.
410
324
  */
411
325
  private _prefetchAllNetworkAccounts;
412
326
  /**
@@ -416,70 +330,51 @@ declare class KeystoneAdapter implements IHardwareWallet {
416
330
  private _resolveTarget;
417
331
  private _assertParsedIdentity;
418
332
  /**
419
- * Folds a parsed account-response UR into the device table. `viaUsb`
420
- * (defaults false) says which channel actually carried this round trip —
421
- * `_resolveUr` routes a KeyDerivation sync over USB when the target record
422
- * already has a live session, so this must NOT unconditionally mark
423
- * `qrSynced`, or a USB-only wallet would wrongly survive a later USB
424
- * disconnect as a "QR-synced, demote to QR-only" entry instead of being
425
- * dropped outright (see `releaseOperation`).
333
+ * Folds a parsed account response into the device table. Only non-USB round trips mark
334
+ * `qrSynced`, so a USB-only wallet is dropped on disconnect.
426
335
  */
427
336
  private _upsertDeviceRecord;
428
337
  /**
429
- * Opens+claims whatever Keystone the USB connector currently has
430
- * permission for, learns its protocol mfp via `getAppConfig`, then requests
431
- * one fixed account-level xpub and derives the stable wallet id. A
432
- * QR-synced entry becomes
433
- * `{qr, usb}`-capable in place (one `device-changed`, not a second
434
- * `device-connect`); a wallet never seen before becomes a new USB-only
435
- * entry. See §4.2 of the design doc.
338
+ * Opens a permitted USB Keystone, reads its mfp, and derives the wallet id from the identity
339
+ * xpub. A known wallet gains USB in place (`device-changed`); an unseen one becomes USB-only.
436
340
  */
437
341
  private _connectUsb;
438
342
  private _connectUsbExclusive;
439
343
  /**
440
- * Probe already-authorized USB devices without opening a permission picker,
441
- * then attach and verify the requested wallet when one is present. This is
442
- * used both after an adapter restart and after a QR-only period, so plugging
443
- * USB back in affects the next business call without changing an in-flight
444
- * QR operation.
344
+ * Probes already-authorized USB devices without a permission picker, then attaches and verifies
345
+ * the requested wallet if present.
445
346
  */
446
347
  private _tryUsbAttach;
447
348
  /**
448
- * The one place that decides QR vs. USB for a UR round trip and carries it
449
- * out. `record` is the (possibly not-yet-existing, for a true cold start)
450
- * device row for the target wallet. USB is the preferred channel: a known
451
- * wallet record with no live session gets ONE best-effort re-attach here,
452
- * and anything that goes wrong just leaves the call on QR. A
453
- * `switchTransport('qr')` pin forces QR even for a USB-attached wallet;
454
- * `switchTransport('usb')` on a wallet with no live USB session fails
455
- * closed rather than silently falling back to QR.
349
+ * Decides QR vs USB for one UR round trip. A pinned 'usb' with no live session fails closed;
350
+ * otherwise a failed USB reattach leaves the call on QR.
456
351
  */
457
352
  private _resolveUr;
458
353
  private _resolveUrWithRoute;
354
+ /** Ends the operation as disconnected and returns the error to throw. */
355
+ private _endDisconnectedOperation;
459
356
  /**
460
- * Fetch one account's key material from the device for this operation only.
461
- * `book` lets earlier fetches of the same operation be reused; nothing is
462
- * retained on the record. A failed USB export ends this operation without
463
- * replaying the request or switching transports.
357
+ * Fetches one account's key material for this operation only; `book` reuses earlier fetches. A
358
+ * failed USB export ends the operation without replaying or switching transports.
464
359
  */
465
360
  private _fetchAccount;
466
361
  /**
467
- * Like `_fetchAccount`, but for operations (PSBT signing, master
468
- * fingerprint) that only need to know WHICH wallet is attached, not a
469
- * specific cached path. Syncs the account-level path for `chain` as a
470
- * throwaway probe when the wallet record isn't already known.
471
- *
472
- * `CHAIN_FINGERPRINT_PATHS[chain]` is a 5-segment LEAF path for `evm`
473
- * (`m/44'/60'/0'/0/0`) — sending that verbatim as a KeyDerivation request
474
- * asks Keystone for a non-standard path. Keystone's own docs
475
- * (dev.keyst.one's multichain KeyDerivation example) show the ETH
476
- * account-level path as `m/44'/60'/0'` (3 segments), same as what
477
- * `_fetchAccount` already requests — so
478
- * truncate through `splitAccountPath` here too instead of using the raw
479
- * fingerprint leaf path. `btc`/`sol` are already 3-segment account paths
480
- * and pass through unchanged.
362
+ * Resolves which wallet is attached, without a per-path account. `CHAIN_FINGERPRINT_PATHS.evm` is
363
+ * a leaf path, so it is cut to the account path Keystone expects.
481
364
  */
482
365
  private _ensureWalletKnown;
366
+ /**
367
+ * The operation owning the running job, so a mid-call UI request can name it. Unpinned jobs map
368
+ * through the operation route; a cold start returns undefined.
369
+ */
370
+ private _activeOperationId;
371
+ /** Routes are keyed by connectId; a job key may be the bare wallet id. */
372
+ private _operationRouteForIdentifier;
373
+ /**
374
+ * A QR prompt has no transport to interrupt; releasing the registry slot on abort is what lets
375
+ * a cancel reach the wait before the QR timeout.
376
+ */
377
+ private _awaitQrResponse;
483
378
  private _requestQrDisplayAndAwaitResponse;
484
379
  private _requestQrScanAndAwaitResponse;
485
380
  private _callUsbConnector;
@@ -496,26 +391,14 @@ declare class KeystoneAdapter implements IHardwareWallet {
496
391
  /** Always returns an `m/`-prefixed path, regardless of the input's casing/prefix. */
497
392
  declare function normalizePath(path: string): string;
498
393
  /**
499
- * Split a full BIP-44 leaf path (`purpose'/coin'/account'/change/index`, 5
500
- * segments) into its 3-segment account path and the relative `change/index`
501
- * path from that account to the leaf. Matches the OneKey Keystone air-gap
502
- * demo's `removePathLastSegment({removeCount: 2})` convention, which is
503
- * verified against real Keystone hardware.
504
- *
505
- * A path with 3 or fewer segments IS already an account path (or shorter) —
506
- * BIP-44's account level is exactly 3 hardened components — so there is
507
- * nothing to split off: `relativeDerivePath` is empty and `accountPath` is
508
- * the (normalized) input unchanged.
394
+ * Splits a 5-segment BIP-44 leaf path into the 3-segment account path and the relative
395
+ * `change/index`; a path of 3 or fewer segments is already an account path.
509
396
  */
510
397
  declare function splitAccountPath(path: string): {
511
398
  accountPath: string;
512
399
  relativeDerivePath: string;
513
400
  };
514
- /**
515
- * Standard BIP-44/49/84/86 purpose → script-type mapping. Returns `undefined`
516
- * for a path whose purpose isn't one of these four (or isn't parseable),
517
- * rather than guessing.
518
- */
401
+ /** BIP-44/49/84/86 purpose to script type; undefined for any other purpose. */
519
402
  declare function btcScriptTypeFromPath(path: string): BtcScriptType | undefined;
520
403
 
521
404
  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 };