@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 +96 -236
- package/dist/index.d.ts +96 -236
- package/dist/index.js +762 -1084
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +595 -916
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -7,15 +7,8 @@ declare enum TronSignType {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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
|
-
*
|
|
40
|
-
*
|
|
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
|
|
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
|
|
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
|
|
112
|
-
*
|
|
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
|
|
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
|
|
130
|
-
*
|
|
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
|
-
*
|
|
140
|
-
*
|
|
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
|
-
*
|
|
159
|
-
*
|
|
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
|
-
*
|
|
181
|
-
*
|
|
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
|
-
*
|
|
217
|
-
*
|
|
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
|
-
/**
|
|
243
|
-
declare const
|
|
244
|
-
declare function walletConnectId(
|
|
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
|
-
/**
|
|
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
|
-
*
|
|
270
|
-
*
|
|
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
|
|
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
|
-
/**
|
|
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'
|
|
293
|
-
*
|
|
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
|
-
*
|
|
301
|
-
*
|
|
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
|
-
/**
|
|
235
|
+
/** Host answer timeout for QR display/scan requests; undefined uses the registry default. */
|
|
319
236
|
private readonly _qrTimeoutMs;
|
|
320
|
-
/**
|
|
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
|
-
/**
|
|
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
|
|
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
|
-
*
|
|
345
|
-
*
|
|
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
|
|
360
|
-
*
|
|
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>,
|
|
378
|
-
evmSignTransaction(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>,
|
|
379
|
-
evmSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>,
|
|
380
|
-
evmSignTypedData(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>,
|
|
381
|
-
btcGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>,
|
|
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
|
-
*
|
|
384
|
-
*
|
|
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>,
|
|
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>,
|
|
394
|
-
btcSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>,
|
|
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>,
|
|
399
|
-
solSignTransaction(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>,
|
|
400
|
-
solSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>,
|
|
401
|
-
tronGetAddress(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>,
|
|
402
|
-
tronSignTransaction(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>,
|
|
403
|
-
tronSignMessage(connectIdArg?: NullableCallArg<string>, deviceIdArg?: NullableCallArg<string>,
|
|
404
|
-
private
|
|
405
|
-
private
|
|
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
|
-
*
|
|
408
|
-
*
|
|
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
|
|
316
|
+
private _signWithWallet;
|
|
317
|
+
private _allNetworkSyncSchema;
|
|
413
318
|
/**
|
|
414
|
-
*
|
|
415
|
-
*
|
|
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
|
|
421
|
-
*
|
|
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
|
|
431
|
-
*
|
|
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
|
-
*
|
|
442
|
-
*
|
|
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
|
-
*
|
|
450
|
-
*
|
|
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
|
-
*
|
|
462
|
-
*
|
|
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
|
-
*
|
|
469
|
-
*
|
|
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
|
|
486
|
-
*
|
|
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
|
|
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
|
|
496
|
-
*
|
|
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
|
-
*
|
|
517
|
-
*
|
|
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,
|
|
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 };
|