@onekeyfe/hwk-adapter-core 1.1.26-alpha.10
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 +1079 -0
- package/dist/index.d.ts +1079 -0
- package/dist/index.js +606 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +552 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +54 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,1079 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HWK HardwareErrorCode — independent namespace from the legacy
|
|
3
|
+
* `@onekeyfe/shared` HardwareErrorCode (which occupies 0-902).
|
|
4
|
+
*
|
|
5
|
+
* All HWK codes are 5-digit (>= 10000) so the two tables never collide
|
|
6
|
+
* even if either side grows. Each sub-category gets a 100-slot block.
|
|
7
|
+
*
|
|
8
|
+
* 10000-10099 Generic / cross-cutting primitives
|
|
9
|
+
* 10100-10199 Device state
|
|
10
|
+
* 10200-10299 Firmware
|
|
11
|
+
* 10300-10399 Transport + OS-level permission
|
|
12
|
+
* 10400-10499 PIN / Passphrase
|
|
13
|
+
* 10500-10599 App lifecycle (wrong app, not open, too old)
|
|
14
|
+
* 10600-10999 RESERVED — future adapter-level categories
|
|
15
|
+
*
|
|
16
|
+
* 11000-11099 EVM APDU (reactive mapping)
|
|
17
|
+
* 11100-11199 Solana APDU
|
|
18
|
+
* 11200-11299 Tron APDU
|
|
19
|
+
* 11300-11399 BTC APDU
|
|
20
|
+
* 11400-11999 RESERVED — future chain APDU blocks (100 per chain)
|
|
21
|
+
*
|
|
22
|
+
* 12000-99999 RESERVED — future major categories
|
|
23
|
+
*/
|
|
24
|
+
declare enum HardwareErrorCode {
|
|
25
|
+
UnknownError = 10000,
|
|
26
|
+
UserRejected = 10001,
|
|
27
|
+
InvalidParams = 10002,
|
|
28
|
+
OperationTimeout = 10003,
|
|
29
|
+
MethodNotSupported = 10004,
|
|
30
|
+
DeviceNotFound = 10100,
|
|
31
|
+
DeviceDisconnected = 10101,
|
|
32
|
+
DeviceBusy = 10102,
|
|
33
|
+
DeviceLocked = 10103,
|
|
34
|
+
DeviceNotInitialized = 10104,
|
|
35
|
+
DeviceInBootloader = 10105,
|
|
36
|
+
DeviceMismatch = 10106,
|
|
37
|
+
FirmwareTooOld = 10200,
|
|
38
|
+
FirmwareUpdateRequired = 10201,
|
|
39
|
+
TransportError = 10300,
|
|
40
|
+
BridgeNotFound = 10301,
|
|
41
|
+
TransportNotAvailable = 10302,
|
|
42
|
+
/**
|
|
43
|
+
* OS-level permission (Bluetooth / USB / etc.) — denied, blocked,
|
|
44
|
+
* unavailable, or dismissed. Consumers surface a single "please grant
|
|
45
|
+
* permission" toast and let the user retry manually.
|
|
46
|
+
*/
|
|
47
|
+
DevicePermissionDenied = 10303,
|
|
48
|
+
PinInvalid = 10400,
|
|
49
|
+
PinCancelled = 10401,
|
|
50
|
+
PassphraseRejected = 10402,
|
|
51
|
+
AppNotOpen = 10500,
|
|
52
|
+
WrongApp = 10501,
|
|
53
|
+
/** 0x911c Command code not supported — app predates current SDK. */
|
|
54
|
+
AppTooOld = 10502,
|
|
55
|
+
/** 0x6a80 Invalid data — observed on blindSignTransactionFallback when the
|
|
56
|
+
* user has not enabled Blind signing on the device. */
|
|
57
|
+
EvmBlindSigningRequired = 11000,
|
|
58
|
+
/** 0x6984 Plugin not installed */
|
|
59
|
+
EvmClearSignPluginMissing = 11001,
|
|
60
|
+
/** 0x6a84 Insufficient memory (typical on Nano S with large calldata) */
|
|
61
|
+
EvmDataTooLarge = 11002,
|
|
62
|
+
/** 0x6501 TransactionType not supported (app too old for EIP-1559 / blob / 7702) */
|
|
63
|
+
EvmTxTypeNotSupported = 11003,
|
|
64
|
+
/** 0x6808 Blind signing disabled for this instruction. */
|
|
65
|
+
SolanaBlindSigningRequired = 11100,
|
|
66
|
+
/** 0x6a8d Custom Contracts setting disabled (blocks TRC-20 etc.). */
|
|
67
|
+
TronCustomContractRequired = 11200,
|
|
68
|
+
/** 0x6a8b Transactions Data setting disabled. */
|
|
69
|
+
TronDataSigningRequired = 11201,
|
|
70
|
+
/** 0x6a8c Sign by Hash setting disabled (hash-signing fallback). */
|
|
71
|
+
TronSignByHashRequired = 11202,
|
|
72
|
+
/** 0xb008 Wallet policy HMAC mismatch or not registered. */
|
|
73
|
+
BtcWalletPolicyHmacMismatch = 11300,
|
|
74
|
+
/** 0xb007 Aborted due to unexpected state (malformed PSBT / missing UTXO). */
|
|
75
|
+
BtcUnexpectedState = 11301
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
interface Success<T> {
|
|
79
|
+
success: true;
|
|
80
|
+
payload: T;
|
|
81
|
+
}
|
|
82
|
+
interface Failure {
|
|
83
|
+
success: false;
|
|
84
|
+
payload: {
|
|
85
|
+
error: string;
|
|
86
|
+
code: HardwareErrorCode;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
type Response<T> = Success<T> | Failure;
|
|
90
|
+
declare function success<T>(payload: T): Success<T>;
|
|
91
|
+
declare function failure(code: HardwareErrorCode, error: string): Failure;
|
|
92
|
+
|
|
93
|
+
type VendorType = 'trezor' | 'ledger';
|
|
94
|
+
type ConnectionType = 'usb' | 'ble';
|
|
95
|
+
type TransportType = 'usb' | 'ble' | 'hid' | 'bridge';
|
|
96
|
+
/**
|
|
97
|
+
* Device capabilities — describes what a specific device/connection
|
|
98
|
+
* combination can or cannot do. Varies by vendor, model, and connection type.
|
|
99
|
+
*
|
|
100
|
+
* This enables business logic to check capabilities instead of hard-coding
|
|
101
|
+
* vendor-specific conditions (e.g., `if (vendor === 'ledger')`).
|
|
102
|
+
*/
|
|
103
|
+
interface DeviceCapabilities {
|
|
104
|
+
/**
|
|
105
|
+
* Whether connectId/deviceId persist across sessions.
|
|
106
|
+
*
|
|
107
|
+
* - `true`: IDs are stable (e.g., OneKey USB, Trezor USB).
|
|
108
|
+
* Business logic can match devices by stored connectId/deviceId.
|
|
109
|
+
* - `false`: IDs are ephemeral, regenerated each session (e.g., Ledger WebHID).
|
|
110
|
+
* Business logic should NOT rely on stored connectId/deviceId for matching.
|
|
111
|
+
*/
|
|
112
|
+
persistentDeviceIdentity: boolean;
|
|
113
|
+
}
|
|
114
|
+
interface DeviceInfo {
|
|
115
|
+
vendor: VendorType;
|
|
116
|
+
model: string;
|
|
117
|
+
firmwareVersion: string;
|
|
118
|
+
deviceId: string;
|
|
119
|
+
connectId: string;
|
|
120
|
+
label?: string;
|
|
121
|
+
connectionType: ConnectionType;
|
|
122
|
+
battery?: number;
|
|
123
|
+
/** Device capabilities — varies by vendor, model, and connection type */
|
|
124
|
+
capabilities?: DeviceCapabilities;
|
|
125
|
+
}
|
|
126
|
+
interface DeviceTarget {
|
|
127
|
+
connectId: string;
|
|
128
|
+
deviceId: string;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
interface EvmGetAddressParams {
|
|
132
|
+
path: string;
|
|
133
|
+
showOnDevice?: boolean;
|
|
134
|
+
chainId?: number;
|
|
135
|
+
}
|
|
136
|
+
interface EvmAddress {
|
|
137
|
+
address: string;
|
|
138
|
+
path: string;
|
|
139
|
+
/** Device-reported secp256k1 public key; populated when the transport exposes it. */
|
|
140
|
+
publicKey?: string;
|
|
141
|
+
}
|
|
142
|
+
interface EvmSignTxParams {
|
|
143
|
+
path: string;
|
|
144
|
+
/**
|
|
145
|
+
* RLP-serialized transaction hex (0x-prefixed or plain).
|
|
146
|
+
* When provided, the connector uses this directly instead of individual fields.
|
|
147
|
+
* Required for Ledger; Trezor may use individual fields instead.
|
|
148
|
+
*/
|
|
149
|
+
serializedTx?: string;
|
|
150
|
+
/** Contract address or recipient. Optional for contract deployment transactions. */
|
|
151
|
+
to?: string;
|
|
152
|
+
value?: string;
|
|
153
|
+
chainId?: number;
|
|
154
|
+
nonce?: string;
|
|
155
|
+
gasLimit?: string;
|
|
156
|
+
gasPrice?: string;
|
|
157
|
+
maxFeePerGas?: string;
|
|
158
|
+
maxPriorityFeePerGas?: string;
|
|
159
|
+
accessList?: Array<{
|
|
160
|
+
address: string;
|
|
161
|
+
storageKeys: string[];
|
|
162
|
+
}>;
|
|
163
|
+
data?: string;
|
|
164
|
+
}
|
|
165
|
+
interface EvmSignedTx {
|
|
166
|
+
/** Recovery id as `0x`-prefixed hex string. */
|
|
167
|
+
v: string;
|
|
168
|
+
/** ECDSA `r` value as `0x`-prefixed, zero-padded 64-char hex string (32 bytes). */
|
|
169
|
+
r: string;
|
|
170
|
+
/** ECDSA `s` value as `0x`-prefixed, zero-padded 64-char hex string (32 bytes). */
|
|
171
|
+
s: string;
|
|
172
|
+
serializedTx?: string;
|
|
173
|
+
}
|
|
174
|
+
interface EvmSignMsgParams {
|
|
175
|
+
path: string;
|
|
176
|
+
message: string;
|
|
177
|
+
hex?: boolean;
|
|
178
|
+
}
|
|
179
|
+
type EvmSignTypedDataParams = EvmSignTypedDataFull | EvmSignTypedDataHash;
|
|
180
|
+
interface EvmSignTypedDataFull {
|
|
181
|
+
path: string;
|
|
182
|
+
/** Defaults to `'full'` when omitted. */
|
|
183
|
+
mode?: 'full';
|
|
184
|
+
data: {
|
|
185
|
+
domain: EIP712Domain;
|
|
186
|
+
types: Record<string, Array<{
|
|
187
|
+
name: string;
|
|
188
|
+
type: string;
|
|
189
|
+
}>>;
|
|
190
|
+
primaryType: string;
|
|
191
|
+
message: Record<string, unknown>;
|
|
192
|
+
};
|
|
193
|
+
metamaskV4Compat?: boolean;
|
|
194
|
+
}
|
|
195
|
+
interface EvmSignTypedDataHash {
|
|
196
|
+
path: string;
|
|
197
|
+
mode: 'hash';
|
|
198
|
+
domainSeparatorHash: string;
|
|
199
|
+
messageHash: string;
|
|
200
|
+
}
|
|
201
|
+
interface EIP712Domain {
|
|
202
|
+
name?: string;
|
|
203
|
+
version?: string;
|
|
204
|
+
chainId?: number;
|
|
205
|
+
verifyingContract?: string;
|
|
206
|
+
salt?: string;
|
|
207
|
+
[key: string]: unknown;
|
|
208
|
+
}
|
|
209
|
+
interface EvmSignature {
|
|
210
|
+
/** `0x`-prefixed hex string (r + s + v). */
|
|
211
|
+
signature: string;
|
|
212
|
+
address?: string;
|
|
213
|
+
}
|
|
214
|
+
type ProgressCallback = (progress: {
|
|
215
|
+
index: number;
|
|
216
|
+
total: number;
|
|
217
|
+
}) => void;
|
|
218
|
+
interface IEvmMethods {
|
|
219
|
+
evmGetAddress(connectId: string, deviceId: string, params: EvmGetAddressParams): Promise<Response<EvmAddress>>;
|
|
220
|
+
evmGetAddresses(connectId: string, deviceId: string, params: EvmGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<EvmAddress[]>>;
|
|
221
|
+
evmSignTransaction(connectId: string, deviceId: string, params: EvmSignTxParams): Promise<Response<EvmSignedTx>>;
|
|
222
|
+
evmSignMessage(connectId: string, deviceId: string, params: EvmSignMsgParams): Promise<Response<EvmSignature>>;
|
|
223
|
+
evmSignTypedData(connectId: string, deviceId: string, params: EvmSignTypedDataParams): Promise<Response<EvmSignature>>;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
interface BtcGetAddressParams {
|
|
227
|
+
path: string;
|
|
228
|
+
coin?: string;
|
|
229
|
+
showOnDevice?: boolean;
|
|
230
|
+
scriptType?: 'p2pkh' | 'p2sh' | 'p2wpkh' | 'p2wsh' | 'p2tr';
|
|
231
|
+
addressIndex?: number;
|
|
232
|
+
change?: boolean;
|
|
233
|
+
}
|
|
234
|
+
interface BtcAddress {
|
|
235
|
+
address: string;
|
|
236
|
+
path: string;
|
|
237
|
+
}
|
|
238
|
+
interface BtcGetPublicKeyParams {
|
|
239
|
+
path: string;
|
|
240
|
+
coin?: string;
|
|
241
|
+
showOnDevice?: boolean;
|
|
242
|
+
}
|
|
243
|
+
interface BtcPublicKey {
|
|
244
|
+
xpub: string;
|
|
245
|
+
publicKey: string;
|
|
246
|
+
/** Parent key fingerprint (BIP-32), not the master fingerprint. */
|
|
247
|
+
fingerprint: number;
|
|
248
|
+
chainCode: string;
|
|
249
|
+
path: string;
|
|
250
|
+
depth: number;
|
|
251
|
+
}
|
|
252
|
+
interface BtcSignTxParams {
|
|
253
|
+
psbt?: string;
|
|
254
|
+
inputs?: BtcTxInput[];
|
|
255
|
+
outputs?: BtcTxOutput[];
|
|
256
|
+
refTxs?: BtcRefTransaction[];
|
|
257
|
+
coin: string;
|
|
258
|
+
locktime?: number;
|
|
259
|
+
version?: number;
|
|
260
|
+
/** Account-level derivation path (e.g. "84'/0'/0'") for wallet template. */
|
|
261
|
+
path?: string;
|
|
262
|
+
}
|
|
263
|
+
interface BtcTxInput {
|
|
264
|
+
path: string;
|
|
265
|
+
prevHash: string;
|
|
266
|
+
prevIndex: number;
|
|
267
|
+
amount: string;
|
|
268
|
+
scriptType?: 'p2pkh' | 'p2sh' | 'p2wpkh' | 'p2wsh' | 'p2tr';
|
|
269
|
+
sequence?: number;
|
|
270
|
+
}
|
|
271
|
+
interface BtcTxOutput {
|
|
272
|
+
address?: string;
|
|
273
|
+
path?: string;
|
|
274
|
+
amount: string;
|
|
275
|
+
scriptType?: 'p2pkh' | 'p2sh' | 'p2wpkh' | 'p2wsh' | 'p2tr';
|
|
276
|
+
}
|
|
277
|
+
interface BtcRefTransaction {
|
|
278
|
+
hash: string;
|
|
279
|
+
version: number;
|
|
280
|
+
inputs: Array<{
|
|
281
|
+
prevHash: string;
|
|
282
|
+
prevIndex: number;
|
|
283
|
+
script: string;
|
|
284
|
+
sequence: number;
|
|
285
|
+
}>;
|
|
286
|
+
outputs: Array<{
|
|
287
|
+
amount: string;
|
|
288
|
+
scriptPubKey: string;
|
|
289
|
+
}>;
|
|
290
|
+
locktime: number;
|
|
291
|
+
}
|
|
292
|
+
interface BtcSignedTx {
|
|
293
|
+
serializedTx: string;
|
|
294
|
+
/** Present when the wallet returns per-input sigs separately (e.g. Trezor). */
|
|
295
|
+
signatures?: string[];
|
|
296
|
+
txid?: string;
|
|
297
|
+
}
|
|
298
|
+
interface BtcSignPsbtParams {
|
|
299
|
+
psbt: string;
|
|
300
|
+
coin?: string;
|
|
301
|
+
/** Account-level derivation path (e.g. "84'/0'/0'") for wallet template. */
|
|
302
|
+
path?: string;
|
|
303
|
+
}
|
|
304
|
+
interface BtcSignedPsbt {
|
|
305
|
+
signedPsbt: string;
|
|
306
|
+
}
|
|
307
|
+
interface BtcSignMsgParams {
|
|
308
|
+
path: string;
|
|
309
|
+
message: string;
|
|
310
|
+
coin?: string;
|
|
311
|
+
}
|
|
312
|
+
interface BtcSignature {
|
|
313
|
+
signature: string;
|
|
314
|
+
/** Optional — not all adapters return it (e.g. Ledger DMK). Derive via btcGetAddress if needed. */
|
|
315
|
+
address?: string;
|
|
316
|
+
}
|
|
317
|
+
interface IBtcMethods {
|
|
318
|
+
btcGetAddress(connectId: string, deviceId: string, params: BtcGetAddressParams): Promise<Response<BtcAddress>>;
|
|
319
|
+
btcGetAddresses(connectId: string, deviceId: string, params: BtcGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<BtcAddress[]>>;
|
|
320
|
+
btcGetPublicKey(connectId: string, deviceId: string, params: BtcGetPublicKeyParams): Promise<Response<BtcPublicKey>>;
|
|
321
|
+
btcSignTransaction(connectId: string, deviceId: string, params: BtcSignTxParams): Promise<Response<BtcSignedTx>>;
|
|
322
|
+
btcSignPsbt(connectId: string, deviceId: string, params: BtcSignPsbtParams): Promise<Response<BtcSignedPsbt>>;
|
|
323
|
+
btcSignMessage(connectId: string, deviceId: string, params: BtcSignMsgParams): Promise<Response<BtcSignature>>;
|
|
324
|
+
btcGetMasterFingerprint(connectId: string, deviceId: string): Promise<Response<{
|
|
325
|
+
masterFingerprint: string;
|
|
326
|
+
}>>;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
interface SolGetAddressParams {
|
|
330
|
+
path: string;
|
|
331
|
+
showOnDevice?: boolean;
|
|
332
|
+
}
|
|
333
|
+
interface SolAddress {
|
|
334
|
+
/** Base58-encoded Solana address — this is also the Ed25519 public key. */
|
|
335
|
+
address: string;
|
|
336
|
+
path: string;
|
|
337
|
+
}
|
|
338
|
+
interface SolSignTxParams {
|
|
339
|
+
path: string;
|
|
340
|
+
/** Hex-encoded serialized transaction bytes (no 0x prefix) */
|
|
341
|
+
serializedTx: string;
|
|
342
|
+
additionalInfo?: {
|
|
343
|
+
tokenAccountsInfos?: Array<{
|
|
344
|
+
baseAddress: string;
|
|
345
|
+
tokenProgram: string;
|
|
346
|
+
tokenMint: string;
|
|
347
|
+
tokenAccount: string;
|
|
348
|
+
}>;
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
interface SolSignedTx {
|
|
352
|
+
/** Hex-encoded Ed25519 signature (no 0x prefix) */
|
|
353
|
+
signature: string;
|
|
354
|
+
}
|
|
355
|
+
interface SolSignMsgParams {
|
|
356
|
+
path: string;
|
|
357
|
+
/** Message bytes as hex string (no 0x prefix) */
|
|
358
|
+
message: string;
|
|
359
|
+
}
|
|
360
|
+
interface SolSignature {
|
|
361
|
+
/** Hex-encoded Ed25519 signature (no 0x prefix) */
|
|
362
|
+
signature: string;
|
|
363
|
+
}
|
|
364
|
+
interface ISolMethods {
|
|
365
|
+
solGetAddress(connectId: string, deviceId: string, params: SolGetAddressParams): Promise<Response<SolAddress>>;
|
|
366
|
+
solGetAddresses(connectId: string, deviceId: string, params: SolGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<SolAddress[]>>;
|
|
367
|
+
solSignTransaction(connectId: string, deviceId: string, params: SolSignTxParams): Promise<Response<SolSignedTx>>;
|
|
368
|
+
solSignMessage(connectId: string, deviceId: string, params: SolSignMsgParams): Promise<Response<SolSignature>>;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
interface TronGetAddressParams {
|
|
372
|
+
path: string;
|
|
373
|
+
showOnDevice?: boolean;
|
|
374
|
+
}
|
|
375
|
+
interface TronAddress {
|
|
376
|
+
/** Base58check-encoded TRON address (starts with 'T') */
|
|
377
|
+
address: string;
|
|
378
|
+
path: string;
|
|
379
|
+
}
|
|
380
|
+
interface TronSignTxParams {
|
|
381
|
+
path: string;
|
|
382
|
+
/** Protobuf-encoded raw transaction hex (no 0x prefix) */
|
|
383
|
+
rawTxHex: string;
|
|
384
|
+
}
|
|
385
|
+
interface TronSignedTx {
|
|
386
|
+
/** 65-byte hex-encoded signature (no 0x prefix) */
|
|
387
|
+
signature: string;
|
|
388
|
+
}
|
|
389
|
+
interface TronSignMsgParams {
|
|
390
|
+
path: string;
|
|
391
|
+
/** Message hex (no 0x prefix) */
|
|
392
|
+
messageHex: string;
|
|
393
|
+
}
|
|
394
|
+
interface TronSignature {
|
|
395
|
+
/** 65-byte hex-encoded signature (no 0x prefix) */
|
|
396
|
+
signature: string;
|
|
397
|
+
}
|
|
398
|
+
interface ITronMethods {
|
|
399
|
+
tronGetAddress(connectId: string, deviceId: string, params: TronGetAddressParams): Promise<Response<TronAddress>>;
|
|
400
|
+
tronGetAddresses(connectId: string, deviceId: string, params: TronGetAddressParams[], onProgress?: ProgressCallback): Promise<Response<TronAddress[]>>;
|
|
401
|
+
tronSignTransaction(connectId: string, deviceId: string, params: TronSignTxParams): Promise<Response<TronSignedTx>>;
|
|
402
|
+
tronSignMessage(connectId: string, deviceId: string, params: TronSignMsgParams): Promise<Response<TronSignature>>;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
interface QrDisplayData {
|
|
406
|
+
urType: string;
|
|
407
|
+
urData: string;
|
|
408
|
+
animated: boolean;
|
|
409
|
+
}
|
|
410
|
+
interface QrResponseData {
|
|
411
|
+
urType: string;
|
|
412
|
+
urData: string;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Fixed derivation paths used to generate chain fingerprints.
|
|
417
|
+
* Uses standard index 0 — Ledger firmware shows device confirmation for
|
|
418
|
+
* non-standard paths (e.g., index=100), which would interrupt wallet creation.
|
|
419
|
+
* The address is hashed into a 16-char fingerprint, not exposed directly.
|
|
420
|
+
* - EVM: cointype 60 (Ledger ETH App only supports 60)
|
|
421
|
+
* - BTC: cointype 1 (testnet)
|
|
422
|
+
* - SOL: cointype 501, standard 3-level hardened
|
|
423
|
+
*/
|
|
424
|
+
declare const CHAIN_FINGERPRINT_PATHS: Record<ChainForFingerprint, string>;
|
|
425
|
+
type ChainForFingerprint = 'evm' | 'btc' | 'sol' | 'tron';
|
|
426
|
+
/**
|
|
427
|
+
* 16-char SHA-256 fingerprint for device-identity verification.
|
|
428
|
+
* Callers must canonicalize input (e.g. EVM address → lowercase) —
|
|
429
|
+
* encoding variations otherwise cause false DeviceMismatch.
|
|
430
|
+
*/
|
|
431
|
+
declare function deriveDeviceFingerprint(value: string): string;
|
|
432
|
+
|
|
433
|
+
declare const DEVICE_EVENT = "DEVICE_EVENT";
|
|
434
|
+
/** Events originating from the hardware device. */
|
|
435
|
+
declare const DEVICE: {
|
|
436
|
+
readonly CONNECT: "device-connect";
|
|
437
|
+
readonly DISCONNECT: "device-disconnect";
|
|
438
|
+
readonly CHANGED: "device-changed";
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
/** 10 min — every UI request is human-in-the-loop; bias toward "wait long". */
|
|
442
|
+
declare const UI_REQUEST_DEFAULT_TIMEOUT_MS = 600000;
|
|
443
|
+
declare const UI_REQUEST_PREEMPTED_TAG = "UiRequestPreempted";
|
|
444
|
+
declare const UI_REQUEST_CANCELLED_TAG = "UiRequestCancelled";
|
|
445
|
+
declare const UI_REQUEST_TIMEOUT_TAG = "UiRequestTimeout";
|
|
446
|
+
/**
|
|
447
|
+
* Per-type single-slot registry for adapter-level UI requests. A new `wait`
|
|
448
|
+
* of the same type preempts (rejects) the prior one. Unknown response types
|
|
449
|
+
* are dropped silently so the public `uiResponse` entry never throws.
|
|
450
|
+
*/
|
|
451
|
+
declare class UiRequestRegistry {
|
|
452
|
+
private pending;
|
|
453
|
+
wait<T = unknown>(requestType: string, options?: {
|
|
454
|
+
timeoutMs?: number;
|
|
455
|
+
}): Promise<T>;
|
|
456
|
+
resolve(responseType: string, payload: unknown): void;
|
|
457
|
+
cancel(requestType?: string): void;
|
|
458
|
+
reset(): void;
|
|
459
|
+
hasPending(requestType: string): boolean;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Per-device serial job queue with preemption support and stuck recovery.
|
|
464
|
+
* Ensures that only one operation runs at a time per device, with intelligent
|
|
465
|
+
* handling of conflicting operations.
|
|
466
|
+
*
|
|
467
|
+
* The 'confirm' level uses the standard UI request/response flow:
|
|
468
|
+
* emits REQUEST_PREEMPTION → waits for RECEIVE_PREEMPTION via UiRequestRegistry.
|
|
469
|
+
*/
|
|
470
|
+
|
|
471
|
+
type Interruptibility = 'none' | 'safe' | 'confirm';
|
|
472
|
+
type PreemptionDecision = 'cancel-current' | 'wait' | 'reject-new';
|
|
473
|
+
interface JobOptions {
|
|
474
|
+
interruptibility?: Interruptibility;
|
|
475
|
+
label?: string;
|
|
476
|
+
}
|
|
477
|
+
interface ActiveJobInfo {
|
|
478
|
+
label?: string;
|
|
479
|
+
interruptibility: Interruptibility;
|
|
480
|
+
startedAt: number;
|
|
481
|
+
}
|
|
482
|
+
interface PreemptionEvent {
|
|
483
|
+
deviceId: string;
|
|
484
|
+
currentJob: ActiveJobInfo;
|
|
485
|
+
newJob: {
|
|
486
|
+
label?: string;
|
|
487
|
+
interruptibility: Interruptibility;
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
interface DeviceJobQueueDeps {
|
|
491
|
+
/** Emit a UI request event to the frontend. */
|
|
492
|
+
emit: (event: string, data: unknown) => void;
|
|
493
|
+
/** Registry for waiting on UI responses. */
|
|
494
|
+
uiRegistry: UiRequestRegistry;
|
|
495
|
+
}
|
|
496
|
+
declare class DeviceJobQueue {
|
|
497
|
+
private readonly _queues;
|
|
498
|
+
private readonly _active;
|
|
499
|
+
private readonly _deps;
|
|
500
|
+
/** Incremented on clear() so stale queued jobs can detect invalidation. */
|
|
501
|
+
private _generation;
|
|
502
|
+
constructor(deps?: DeviceJobQueueDeps);
|
|
503
|
+
/**
|
|
504
|
+
* Enqueue a job for a specific device.
|
|
505
|
+
* If a job is already running for this device, behavior depends on interruptibility:
|
|
506
|
+
* - 'none': new job queues silently (no preemption possible)
|
|
507
|
+
* - 'safe': current job is auto-cancelled, new job runs immediately after
|
|
508
|
+
* - 'confirm': emits REQUEST_PREEMPTION and waits for UI response
|
|
509
|
+
*/
|
|
510
|
+
enqueue<T>(deviceId: string, job: (signal: AbortSignal) => Promise<T>, options?: JobOptions): Promise<T>;
|
|
511
|
+
/** Manually cancel the active job on a device. Returns false if job is non-interruptible. */
|
|
512
|
+
cancelActive(deviceId: string): boolean;
|
|
513
|
+
/** Force cancel regardless of interruptibility. Use for device stuck recovery. */
|
|
514
|
+
forceCancelActive(deviceId: string): boolean;
|
|
515
|
+
/** Get info about the currently active job for a device, or null if idle. */
|
|
516
|
+
getActiveJob(deviceId: string): ActiveJobInfo | null;
|
|
517
|
+
clear(): void;
|
|
518
|
+
/**
|
|
519
|
+
* Request preemption decision via UI request/response flow.
|
|
520
|
+
* Falls back to 'wait' if deps are not provided.
|
|
521
|
+
*/
|
|
522
|
+
private _requestPreemptionDecision;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
declare const UI_EVENT = "UI_EVENT";
|
|
526
|
+
declare const UI_REQUEST: {
|
|
527
|
+
readonly REQUEST_PIN: "ui-request-pin";
|
|
528
|
+
readonly REQUEST_PASSPHRASE: "ui-request-passphrase";
|
|
529
|
+
readonly REQUEST_PASSPHRASE_ON_DEVICE: "ui-request-passphrase-on-device";
|
|
530
|
+
readonly REQUEST_BUTTON: "ui-request-button";
|
|
531
|
+
readonly REQUEST_QR_DISPLAY: "ui-request-qr-display";
|
|
532
|
+
readonly REQUEST_QR_SCAN: "ui-request-qr-scan";
|
|
533
|
+
readonly REQUEST_DEVICE_PERMISSION: "ui-request-device-permission";
|
|
534
|
+
readonly REQUEST_SELECT_DEVICE: "ui-request-select-device";
|
|
535
|
+
readonly REQUEST_DEVICE_CONNECT: "ui-request-device-connect";
|
|
536
|
+
readonly REQUEST_PREEMPTION: "ui-request-preemption";
|
|
537
|
+
readonly CLOSE_UI_WINDOW: "ui-close";
|
|
538
|
+
readonly DEVICE_PROGRESS: "ui-device_progress";
|
|
539
|
+
readonly FIRMWARE_PROGRESS: "ui-firmware-progress";
|
|
540
|
+
readonly FIRMWARE_TIP: "ui-firmware-tip";
|
|
541
|
+
};
|
|
542
|
+
declare const UI_RESPONSE: {
|
|
543
|
+
readonly RECEIVE_PIN: "receive-pin";
|
|
544
|
+
readonly RECEIVE_PASSPHRASE: "receive-passphrase";
|
|
545
|
+
readonly RECEIVE_PASSPHRASE_ON_DEVICE: "receive-passphrase-on-device";
|
|
546
|
+
readonly RECEIVE_QR_RESPONSE: "receive-qr-response";
|
|
547
|
+
readonly RECEIVE_SELECT_DEVICE: "receive-select-device";
|
|
548
|
+
readonly RECEIVE_DEVICE_CONNECT: "receive-device-connect";
|
|
549
|
+
readonly RECEIVE_DEVICE_PERMISSION: "receive-device-permission";
|
|
550
|
+
readonly RECEIVE_PREEMPTION: "receive-preemption";
|
|
551
|
+
readonly CANCEL: "cancel";
|
|
552
|
+
};
|
|
553
|
+
type UiResponseEvent = {
|
|
554
|
+
type: typeof UI_RESPONSE.RECEIVE_PIN;
|
|
555
|
+
payload: string;
|
|
556
|
+
} | {
|
|
557
|
+
type: typeof UI_RESPONSE.RECEIVE_PASSPHRASE;
|
|
558
|
+
payload: {
|
|
559
|
+
value: string;
|
|
560
|
+
passphraseOnDevice?: boolean;
|
|
561
|
+
save?: boolean;
|
|
562
|
+
};
|
|
563
|
+
} | {
|
|
564
|
+
type: typeof UI_RESPONSE.RECEIVE_PASSPHRASE_ON_DEVICE;
|
|
565
|
+
payload?: undefined;
|
|
566
|
+
} | {
|
|
567
|
+
type: typeof UI_RESPONSE.RECEIVE_QR_RESPONSE;
|
|
568
|
+
payload: QrResponseData;
|
|
569
|
+
} | {
|
|
570
|
+
type: typeof UI_RESPONSE.RECEIVE_SELECT_DEVICE;
|
|
571
|
+
payload: {
|
|
572
|
+
sdkConnectId: string;
|
|
573
|
+
};
|
|
574
|
+
} | {
|
|
575
|
+
type: typeof UI_RESPONSE.RECEIVE_DEVICE_CONNECT;
|
|
576
|
+
payload: {
|
|
577
|
+
confirmed: boolean;
|
|
578
|
+
};
|
|
579
|
+
} | {
|
|
580
|
+
type: typeof UI_RESPONSE.RECEIVE_DEVICE_PERMISSION;
|
|
581
|
+
payload: {
|
|
582
|
+
granted: boolean;
|
|
583
|
+
};
|
|
584
|
+
} | {
|
|
585
|
+
type: typeof UI_RESPONSE.RECEIVE_PREEMPTION;
|
|
586
|
+
payload: {
|
|
587
|
+
decision: PreemptionDecision;
|
|
588
|
+
};
|
|
589
|
+
} | {
|
|
590
|
+
type: typeof UI_RESPONSE.CANCEL;
|
|
591
|
+
payload?: undefined;
|
|
592
|
+
};
|
|
593
|
+
|
|
594
|
+
/** Events generated by SDK internal detection (not from hardware directly). */
|
|
595
|
+
declare const SDK: {
|
|
596
|
+
readonly DEVICE_STUCK: "device-stuck";
|
|
597
|
+
readonly DEVICE_UNRESPONSIVE: "device-unresponsive";
|
|
598
|
+
readonly DEVICE_RECOVERED: "device-recovered";
|
|
599
|
+
readonly DEVICE_INTERACTION: "device-interaction";
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Minimal device info returned during discovery (searchDevices).
|
|
604
|
+
* At scan time, full DeviceInfo fields like firmwareVersion are not yet available.
|
|
605
|
+
*/
|
|
606
|
+
interface ConnectorDevice {
|
|
607
|
+
connectId: string;
|
|
608
|
+
deviceId: string;
|
|
609
|
+
name: string;
|
|
610
|
+
model?: string;
|
|
611
|
+
/** Device capabilities — available from scan time */
|
|
612
|
+
capabilities?: DeviceCapabilities;
|
|
613
|
+
}
|
|
614
|
+
interface ConnectorSession {
|
|
615
|
+
sessionId: string;
|
|
616
|
+
deviceInfo: DeviceInfo;
|
|
617
|
+
}
|
|
618
|
+
type ConnectorEventType = 'device-connect' | 'device-disconnect' | 'ui-request' | 'ui-event';
|
|
619
|
+
/**
|
|
620
|
+
* Interaction event types emitted via 'ui-event'.
|
|
621
|
+
* These map to user-facing prompts (confirm on device, open app, etc.).
|
|
622
|
+
*/
|
|
623
|
+
declare enum EConnectorInteraction {
|
|
624
|
+
/** Device requires user to open a specific app */
|
|
625
|
+
ConfirmOpenApp = "confirm-open-app",
|
|
626
|
+
/** Device requires user to unlock */
|
|
627
|
+
UnlockDevice = "unlock-device",
|
|
628
|
+
/** Device needs user to confirm on device (sign, verify, etc.) */
|
|
629
|
+
ConfirmOnDevice = "confirm-on-device",
|
|
630
|
+
/** Previous interaction completed — clear UI prompt */
|
|
631
|
+
InteractionComplete = "interaction-complete"
|
|
632
|
+
}
|
|
633
|
+
type ConnectorUiEvent = {
|
|
634
|
+
type: EConnectorInteraction.ConfirmOpenApp;
|
|
635
|
+
payload: {
|
|
636
|
+
sessionId: string;
|
|
637
|
+
};
|
|
638
|
+
} | {
|
|
639
|
+
type: EConnectorInteraction.UnlockDevice;
|
|
640
|
+
payload: {
|
|
641
|
+
sessionId: string;
|
|
642
|
+
};
|
|
643
|
+
} | {
|
|
644
|
+
type: EConnectorInteraction.ConfirmOnDevice;
|
|
645
|
+
payload: {
|
|
646
|
+
sessionId: string;
|
|
647
|
+
};
|
|
648
|
+
} | {
|
|
649
|
+
type: EConnectorInteraction.InteractionComplete;
|
|
650
|
+
payload: {
|
|
651
|
+
sessionId: string;
|
|
652
|
+
};
|
|
653
|
+
};
|
|
654
|
+
interface ConnectorEventMap {
|
|
655
|
+
'device-connect': {
|
|
656
|
+
device: ConnectorDevice;
|
|
657
|
+
};
|
|
658
|
+
'device-disconnect': {
|
|
659
|
+
connectId: string;
|
|
660
|
+
};
|
|
661
|
+
'ui-request': {
|
|
662
|
+
type: string;
|
|
663
|
+
payload?: unknown;
|
|
664
|
+
};
|
|
665
|
+
'ui-event': ConnectorUiEvent;
|
|
666
|
+
}
|
|
667
|
+
interface IConnector {
|
|
668
|
+
/** Physical connection type this connector uses. Fixed at construction. */
|
|
669
|
+
readonly connectionType: ConnectionType;
|
|
670
|
+
searchDevices(): Promise<ConnectorDevice[]>;
|
|
671
|
+
connect(deviceId?: string): Promise<ConnectorSession>;
|
|
672
|
+
disconnect(sessionId: string): Promise<void>;
|
|
673
|
+
call(sessionId: string, method: string, params: unknown): Promise<unknown>;
|
|
674
|
+
cancel(sessionId: string): Promise<void>;
|
|
675
|
+
/** Send a UI response (e.g. PIN, passphrase) to the device. */
|
|
676
|
+
uiResponse(response: UiResponseEvent): void;
|
|
677
|
+
on<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;
|
|
678
|
+
off<K extends ConnectorEventType>(event: K, handler: (data: ConnectorEventMap[K]) => void): void;
|
|
679
|
+
reset(): void;
|
|
680
|
+
}
|
|
681
|
+
interface IHardwareBridge {
|
|
682
|
+
searchDevices(params: {
|
|
683
|
+
vendor: VendorType;
|
|
684
|
+
}): Promise<ConnectorDevice[]>;
|
|
685
|
+
connect(params: {
|
|
686
|
+
vendor: VendorType;
|
|
687
|
+
deviceId?: string;
|
|
688
|
+
}): Promise<ConnectorSession>;
|
|
689
|
+
disconnect(params: {
|
|
690
|
+
vendor: VendorType;
|
|
691
|
+
sessionId: string;
|
|
692
|
+
}): Promise<void>;
|
|
693
|
+
call(params: {
|
|
694
|
+
vendor: VendorType;
|
|
695
|
+
sessionId: string;
|
|
696
|
+
method: string;
|
|
697
|
+
callParams: unknown;
|
|
698
|
+
}): Promise<unknown>;
|
|
699
|
+
cancel(params: {
|
|
700
|
+
vendor: VendorType;
|
|
701
|
+
sessionId: string;
|
|
702
|
+
}): Promise<void>;
|
|
703
|
+
uiResponse(params: {
|
|
704
|
+
vendor: VendorType;
|
|
705
|
+
response: UiResponseEvent;
|
|
706
|
+
}): void;
|
|
707
|
+
reset(params: {
|
|
708
|
+
vendor: VendorType;
|
|
709
|
+
}): void;
|
|
710
|
+
/** Register an event handler for connector events forwarded across the bridge. */
|
|
711
|
+
onEvent(params: {
|
|
712
|
+
vendor: VendorType;
|
|
713
|
+
}, handler: (event: {
|
|
714
|
+
type: ConnectorEventType;
|
|
715
|
+
data: unknown;
|
|
716
|
+
}) => void): void;
|
|
717
|
+
/** Unregister a previously registered event handler. */
|
|
718
|
+
offEvent(params: {
|
|
719
|
+
vendor: VendorType;
|
|
720
|
+
}, handler: (event: {
|
|
721
|
+
type: ConnectorEventType;
|
|
722
|
+
data: unknown;
|
|
723
|
+
}) => void): void;
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* Adapt an IHardwareBridge (multi-vendor backend) into a single-vendor IConnector.
|
|
727
|
+
* Every IConnector method becomes a transparent forward to bridge.<method>({ vendor, ... }).
|
|
728
|
+
* Events are forwarded via bridge.onEvent / offEvent.
|
|
729
|
+
*
|
|
730
|
+
* Use this anywhere the actual hardware lives behind a process / context boundary
|
|
731
|
+
* (Electron main, extension background, native module, worker, iframe).
|
|
732
|
+
*/
|
|
733
|
+
declare function createBridgedConnector(vendor: VendorType, connectionType: ConnectionType, bridge: IHardwareBridge): IConnector;
|
|
734
|
+
|
|
735
|
+
type ChainCapability = 'evm' | 'btc' | 'sol' | 'tron';
|
|
736
|
+
interface PassphraseResponse {
|
|
737
|
+
passphrase: string;
|
|
738
|
+
/** If true, passphrase will be entered on the device. `passphrase` field is ignored. */
|
|
739
|
+
onDevice?: boolean;
|
|
740
|
+
}
|
|
741
|
+
type DeviceEvent = {
|
|
742
|
+
type: typeof DEVICE.CONNECT;
|
|
743
|
+
payload: DeviceInfo;
|
|
744
|
+
} | {
|
|
745
|
+
type: typeof DEVICE.DISCONNECT;
|
|
746
|
+
payload: {
|
|
747
|
+
connectId: string;
|
|
748
|
+
};
|
|
749
|
+
} | {
|
|
750
|
+
type: typeof DEVICE.CHANGED;
|
|
751
|
+
payload: DeviceInfo;
|
|
752
|
+
};
|
|
753
|
+
type UiRequestEvent = {
|
|
754
|
+
type: typeof UI_REQUEST.REQUEST_PIN;
|
|
755
|
+
payload: {
|
|
756
|
+
device: DeviceInfo;
|
|
757
|
+
};
|
|
758
|
+
} | {
|
|
759
|
+
type: typeof UI_REQUEST.REQUEST_PASSPHRASE;
|
|
760
|
+
payload: {
|
|
761
|
+
device: DeviceInfo;
|
|
762
|
+
};
|
|
763
|
+
} | {
|
|
764
|
+
type: typeof UI_REQUEST.REQUEST_PASSPHRASE_ON_DEVICE;
|
|
765
|
+
payload: {
|
|
766
|
+
device: DeviceInfo;
|
|
767
|
+
};
|
|
768
|
+
} | {
|
|
769
|
+
type: typeof UI_REQUEST.REQUEST_BUTTON;
|
|
770
|
+
payload: {
|
|
771
|
+
device: DeviceInfo;
|
|
772
|
+
code?: string;
|
|
773
|
+
};
|
|
774
|
+
} | {
|
|
775
|
+
type: typeof UI_REQUEST.REQUEST_QR_DISPLAY;
|
|
776
|
+
payload: {
|
|
777
|
+
device: DeviceInfo;
|
|
778
|
+
data: QrDisplayData;
|
|
779
|
+
};
|
|
780
|
+
} | {
|
|
781
|
+
type: typeof UI_REQUEST.REQUEST_QR_SCAN;
|
|
782
|
+
payload: {
|
|
783
|
+
device: DeviceInfo;
|
|
784
|
+
};
|
|
785
|
+
} | {
|
|
786
|
+
type: typeof UI_REQUEST.REQUEST_DEVICE_PERMISSION;
|
|
787
|
+
payload: {
|
|
788
|
+
transportType: TransportType;
|
|
789
|
+
connectId?: string;
|
|
790
|
+
deviceId?: string;
|
|
791
|
+
};
|
|
792
|
+
} | {
|
|
793
|
+
type: typeof UI_REQUEST.REQUEST_SELECT_DEVICE;
|
|
794
|
+
payload: {
|
|
795
|
+
devices: DeviceInfo[];
|
|
796
|
+
};
|
|
797
|
+
} | {
|
|
798
|
+
type: typeof UI_REQUEST.REQUEST_DEVICE_CONNECT;
|
|
799
|
+
payload: {
|
|
800
|
+
message: string;
|
|
801
|
+
};
|
|
802
|
+
} | {
|
|
803
|
+
type: typeof UI_REQUEST.REQUEST_PREEMPTION;
|
|
804
|
+
payload: {
|
|
805
|
+
deviceId: string;
|
|
806
|
+
currentJob: ActiveJobInfo;
|
|
807
|
+
newJob: {
|
|
808
|
+
label?: string;
|
|
809
|
+
interruptibility: Interruptibility;
|
|
810
|
+
};
|
|
811
|
+
};
|
|
812
|
+
} | {
|
|
813
|
+
type: typeof UI_REQUEST.CLOSE_UI_WINDOW;
|
|
814
|
+
payload: Record<string, never>;
|
|
815
|
+
};
|
|
816
|
+
type SdkEvent = {
|
|
817
|
+
type: typeof SDK.DEVICE_INTERACTION;
|
|
818
|
+
payload: {
|
|
819
|
+
connectId: string;
|
|
820
|
+
action: string;
|
|
821
|
+
};
|
|
822
|
+
} | {
|
|
823
|
+
type: typeof SDK.DEVICE_STUCK;
|
|
824
|
+
payload: {
|
|
825
|
+
connectId: string;
|
|
826
|
+
};
|
|
827
|
+
} | {
|
|
828
|
+
type: typeof SDK.DEVICE_UNRESPONSIVE;
|
|
829
|
+
payload: {
|
|
830
|
+
connectId: string;
|
|
831
|
+
};
|
|
832
|
+
} | {
|
|
833
|
+
type: typeof SDK.DEVICE_RECOVERED;
|
|
834
|
+
payload: {
|
|
835
|
+
connectId: string;
|
|
836
|
+
};
|
|
837
|
+
};
|
|
838
|
+
type HardwareEvent = DeviceEvent | UiRequestEvent | SdkEvent | ConnectorUiEvent;
|
|
839
|
+
type DeviceEventListener = (event: HardwareEvent) => void;
|
|
840
|
+
/**
|
|
841
|
+
* Type-safe event map for IHardwareWallet.on / .off.
|
|
842
|
+
*
|
|
843
|
+
* Each key is a concrete event string (e.g. DEVICE.CONNECT = 'device-connect'),
|
|
844
|
+
* and the value is the narrowed event object the listener will receive.
|
|
845
|
+
*/
|
|
846
|
+
interface HardwareEventMap {
|
|
847
|
+
'ui-event': ConnectorUiEvent;
|
|
848
|
+
[DEVICE.CONNECT]: {
|
|
849
|
+
type: typeof DEVICE.CONNECT;
|
|
850
|
+
payload: DeviceInfo;
|
|
851
|
+
};
|
|
852
|
+
[DEVICE.DISCONNECT]: {
|
|
853
|
+
type: typeof DEVICE.DISCONNECT;
|
|
854
|
+
payload: {
|
|
855
|
+
connectId: string;
|
|
856
|
+
};
|
|
857
|
+
};
|
|
858
|
+
[DEVICE.CHANGED]: {
|
|
859
|
+
type: typeof DEVICE.CHANGED;
|
|
860
|
+
payload: DeviceInfo;
|
|
861
|
+
};
|
|
862
|
+
[UI_REQUEST.REQUEST_PIN]: {
|
|
863
|
+
type: typeof UI_REQUEST.REQUEST_PIN;
|
|
864
|
+
payload: {
|
|
865
|
+
device: DeviceInfo;
|
|
866
|
+
};
|
|
867
|
+
};
|
|
868
|
+
[UI_REQUEST.REQUEST_PASSPHRASE]: {
|
|
869
|
+
type: typeof UI_REQUEST.REQUEST_PASSPHRASE;
|
|
870
|
+
payload: {
|
|
871
|
+
device: DeviceInfo;
|
|
872
|
+
};
|
|
873
|
+
};
|
|
874
|
+
[UI_REQUEST.REQUEST_PASSPHRASE_ON_DEVICE]: {
|
|
875
|
+
type: typeof UI_REQUEST.REQUEST_PASSPHRASE_ON_DEVICE;
|
|
876
|
+
payload: {
|
|
877
|
+
device: DeviceInfo;
|
|
878
|
+
};
|
|
879
|
+
};
|
|
880
|
+
[UI_REQUEST.REQUEST_BUTTON]: {
|
|
881
|
+
type: typeof UI_REQUEST.REQUEST_BUTTON;
|
|
882
|
+
payload: {
|
|
883
|
+
device: DeviceInfo;
|
|
884
|
+
code?: string;
|
|
885
|
+
};
|
|
886
|
+
};
|
|
887
|
+
[UI_REQUEST.REQUEST_QR_DISPLAY]: {
|
|
888
|
+
type: typeof UI_REQUEST.REQUEST_QR_DISPLAY;
|
|
889
|
+
payload: {
|
|
890
|
+
device: DeviceInfo;
|
|
891
|
+
data: QrDisplayData;
|
|
892
|
+
};
|
|
893
|
+
};
|
|
894
|
+
[UI_REQUEST.REQUEST_QR_SCAN]: {
|
|
895
|
+
type: typeof UI_REQUEST.REQUEST_QR_SCAN;
|
|
896
|
+
payload: {
|
|
897
|
+
device: DeviceInfo;
|
|
898
|
+
};
|
|
899
|
+
};
|
|
900
|
+
[UI_REQUEST.REQUEST_DEVICE_PERMISSION]: {
|
|
901
|
+
type: typeof UI_REQUEST.REQUEST_DEVICE_PERMISSION;
|
|
902
|
+
payload: {
|
|
903
|
+
transportType: TransportType;
|
|
904
|
+
connectId?: string;
|
|
905
|
+
deviceId?: string;
|
|
906
|
+
};
|
|
907
|
+
};
|
|
908
|
+
[UI_REQUEST.REQUEST_SELECT_DEVICE]: {
|
|
909
|
+
type: typeof UI_REQUEST.REQUEST_SELECT_DEVICE;
|
|
910
|
+
payload: {
|
|
911
|
+
devices: DeviceInfo[];
|
|
912
|
+
};
|
|
913
|
+
};
|
|
914
|
+
[UI_REQUEST.REQUEST_DEVICE_CONNECT]: {
|
|
915
|
+
type: typeof UI_REQUEST.REQUEST_DEVICE_CONNECT;
|
|
916
|
+
payload: {
|
|
917
|
+
message: string;
|
|
918
|
+
};
|
|
919
|
+
};
|
|
920
|
+
[UI_REQUEST.REQUEST_PREEMPTION]: {
|
|
921
|
+
type: typeof UI_REQUEST.REQUEST_PREEMPTION;
|
|
922
|
+
payload: {
|
|
923
|
+
deviceId: string;
|
|
924
|
+
currentJob: ActiveJobInfo;
|
|
925
|
+
newJob: {
|
|
926
|
+
label?: string;
|
|
927
|
+
interruptibility: Interruptibility;
|
|
928
|
+
};
|
|
929
|
+
};
|
|
930
|
+
};
|
|
931
|
+
[UI_REQUEST.CLOSE_UI_WINDOW]: {
|
|
932
|
+
type: typeof UI_REQUEST.CLOSE_UI_WINDOW;
|
|
933
|
+
payload: Record<string, never>;
|
|
934
|
+
};
|
|
935
|
+
[SDK.DEVICE_INTERACTION]: {
|
|
936
|
+
type: typeof SDK.DEVICE_INTERACTION;
|
|
937
|
+
payload: {
|
|
938
|
+
connectId: string;
|
|
939
|
+
action: string;
|
|
940
|
+
};
|
|
941
|
+
};
|
|
942
|
+
[SDK.DEVICE_STUCK]: {
|
|
943
|
+
type: typeof SDK.DEVICE_STUCK;
|
|
944
|
+
payload: {
|
|
945
|
+
connectId: string;
|
|
946
|
+
};
|
|
947
|
+
};
|
|
948
|
+
[SDK.DEVICE_UNRESPONSIVE]: {
|
|
949
|
+
type: typeof SDK.DEVICE_UNRESPONSIVE;
|
|
950
|
+
payload: {
|
|
951
|
+
connectId: string;
|
|
952
|
+
};
|
|
953
|
+
};
|
|
954
|
+
[SDK.DEVICE_RECOVERED]: {
|
|
955
|
+
type: typeof SDK.DEVICE_RECOVERED;
|
|
956
|
+
payload: {
|
|
957
|
+
connectId: string;
|
|
958
|
+
};
|
|
959
|
+
};
|
|
960
|
+
}
|
|
961
|
+
interface IHardwareWallet<TConfig = unknown> extends IEvmMethods, IBtcMethods, ISolMethods, ITronMethods {
|
|
962
|
+
readonly vendor: string;
|
|
963
|
+
readonly activeTransport: TransportType | null;
|
|
964
|
+
init(config: TConfig): Promise<void>;
|
|
965
|
+
dispose(): Promise<void>;
|
|
966
|
+
getAvailableTransports(): TransportType[];
|
|
967
|
+
switchTransport(type: TransportType): Promise<void>;
|
|
968
|
+
searchDevices(): Promise<DeviceInfo[]>;
|
|
969
|
+
connectDevice(connectId: string): Promise<Response<string>>;
|
|
970
|
+
disconnectDevice(connectId: string): Promise<void>;
|
|
971
|
+
getDeviceInfo(connectId: string, deviceId: string): Promise<Response<DeviceInfo>>;
|
|
972
|
+
getSupportedChains(): ChainCapability[];
|
|
973
|
+
cancel(connectId: string): void;
|
|
974
|
+
/** Respond to any pending `ui-request-*`. */
|
|
975
|
+
uiResponse(response: UiResponseEvent): void;
|
|
976
|
+
/**
|
|
977
|
+
* Derive a chain-specific fingerprint for the connected device.
|
|
978
|
+
*
|
|
979
|
+
* For Ledger: derives an address at a fixed testnet path and hashes it.
|
|
980
|
+
* For Trezor: returns the hardware device_id from firmware features.
|
|
981
|
+
*
|
|
982
|
+
* Used to verify that the same seed/device is connected across sessions,
|
|
983
|
+
* especially for vendors with ephemeral connectId/deviceId.
|
|
984
|
+
*/
|
|
985
|
+
getChainFingerprint(connectId: string, deviceId: string, chain: ChainForFingerprint): Promise<Response<string>>;
|
|
986
|
+
on<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
|
|
987
|
+
on(event: string, listener: DeviceEventListener): void;
|
|
988
|
+
off<K extends keyof HardwareEventMap>(event: K, listener: (event: HardwareEventMap[K]) => void): void;
|
|
989
|
+
off(event: string, listener: DeviceEventListener): void;
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
/**
|
|
993
|
+
* Low-level device descriptor from Transport layer.
|
|
994
|
+
* Represents a physical device detected by USB/BLE scanning.
|
|
995
|
+
*/
|
|
996
|
+
interface DeviceDescriptor {
|
|
997
|
+
/** Unique device path (USB serial number, BLE address, etc.) */
|
|
998
|
+
path: string;
|
|
999
|
+
/** USB product ID */
|
|
1000
|
+
product?: number;
|
|
1001
|
+
/** USB vendor ID */
|
|
1002
|
+
vendor?: number;
|
|
1003
|
+
/** Device type/model identifier */
|
|
1004
|
+
type?: string;
|
|
1005
|
+
/** BLE device name (e.g., "Nano X 123A") — contains stable 4-digit HEX suffix */
|
|
1006
|
+
name?: string;
|
|
1007
|
+
/** Transport identifier (e.g., 'WEB-HID', 'BLE') */
|
|
1008
|
+
transport?: string;
|
|
1009
|
+
}
|
|
1010
|
+
interface DeviceConnectEvent {
|
|
1011
|
+
type: 'device-connected';
|
|
1012
|
+
descriptor: DeviceDescriptor;
|
|
1013
|
+
}
|
|
1014
|
+
interface DeviceDisconnectEvent {
|
|
1015
|
+
type: 'device-disconnected';
|
|
1016
|
+
descriptor: DeviceDescriptor;
|
|
1017
|
+
}
|
|
1018
|
+
type DeviceChangeEvent = DeviceConnectEvent | DeviceDisconnectEvent;
|
|
1019
|
+
|
|
1020
|
+
/**
|
|
1021
|
+
* Minimal typed event emitter using Map<string, Set<listener>>.
|
|
1022
|
+
* Each adapter uses this for device events (connect, disconnect, pin, etc.).
|
|
1023
|
+
*
|
|
1024
|
+
* TMap is a record mapping event name strings to their payload types.
|
|
1025
|
+
* Example:
|
|
1026
|
+
* type MyEvents = { 'connect': { id: string }; 'disconnect': { id: string } };
|
|
1027
|
+
* const emitter = new TypedEventEmitter<MyEvents>();
|
|
1028
|
+
* emitter.on('connect', (data) => { data.id }); // data is { id: string }
|
|
1029
|
+
*
|
|
1030
|
+
* For backward compatibility, TMap defaults to Record<string, any> so that
|
|
1031
|
+
* existing code using `new TypedEventEmitter<SomeUnionType>()` still compiles.
|
|
1032
|
+
*/
|
|
1033
|
+
declare class TypedEventEmitter<TMap extends Record<string, any> = Record<string, any>> {
|
|
1034
|
+
private readonly _listeners;
|
|
1035
|
+
on<K extends keyof TMap & string>(event: K, listener: (event: TMap[K]) => void): void;
|
|
1036
|
+
on(event: string, listener: (event: any) => void): void;
|
|
1037
|
+
off<K extends keyof TMap & string>(event: K, listener: (event: TMap[K]) => void): void;
|
|
1038
|
+
off(event: string, listener: (event: any) => void): void;
|
|
1039
|
+
emit<K extends keyof TMap & string>(event: K, data: TMap[K]): void;
|
|
1040
|
+
emit(event: string, data: unknown): void;
|
|
1041
|
+
removeAllListeners(): void;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
/**
|
|
1045
|
+
* Compare two semver strings (e.g. "2.1.0" vs "2.3.1").
|
|
1046
|
+
* Returns -1 if a < b, 0 if equal, 1 if a > b.
|
|
1047
|
+
*/
|
|
1048
|
+
declare function compareSemver(a: string, b: string): number;
|
|
1049
|
+
|
|
1050
|
+
/** Ensure hex string has 0x prefix */
|
|
1051
|
+
declare function ensure0x(hex: string): string;
|
|
1052
|
+
/** Strip 0x prefix from hex string */
|
|
1053
|
+
declare function stripHex(hex: string): string;
|
|
1054
|
+
/** Pad hex to 64 chars (32 bytes) with 0x prefix */
|
|
1055
|
+
declare function padHex64(hex: string): string;
|
|
1056
|
+
/**
|
|
1057
|
+
* Convert a hex string (with or without 0x prefix) to a Uint8Array.
|
|
1058
|
+
* Throws on invalid hex (non-hex characters, odd length).
|
|
1059
|
+
*/
|
|
1060
|
+
declare function hexToBytes(hex: string): Uint8Array;
|
|
1061
|
+
/** Convert a Uint8Array to a hex string (no 0x prefix). */
|
|
1062
|
+
declare function bytesToHex(bytes: Uint8Array): string;
|
|
1063
|
+
|
|
1064
|
+
/**
|
|
1065
|
+
* Enrich a hardware error message with actionable recovery hints.
|
|
1066
|
+
* Shared across adapters (Ledger, Trezor, etc.).
|
|
1067
|
+
*/
|
|
1068
|
+
declare function enrichErrorMessage(code: HardwareErrorCode, originalMessage: string): string;
|
|
1069
|
+
|
|
1070
|
+
/**
|
|
1071
|
+
* Generic batch call with progress reporting.
|
|
1072
|
+
* If any single call fails, returns the failure immediately.
|
|
1073
|
+
*/
|
|
1074
|
+
declare function batchCall<TParam, TResult>(params: TParam[], callFn: (p: TParam) => Promise<Response<TResult>>, onProgress?: (progress: {
|
|
1075
|
+
index: number;
|
|
1076
|
+
total: number;
|
|
1077
|
+
}) => void): Promise<Response<TResult[]>>;
|
|
1078
|
+
|
|
1079
|
+
export { type ActiveJobInfo, type BtcAddress, type BtcGetAddressParams, type BtcGetPublicKeyParams, type BtcPublicKey, type BtcRefTransaction, type BtcSignMsgParams, type BtcSignPsbtParams, type BtcSignTxParams, type BtcSignature, type BtcSignedPsbt, type BtcSignedTx, type BtcTxInput, type BtcTxOutput, CHAIN_FINGERPRINT_PATHS, type ChainCapability, type ChainForFingerprint, type ConnectionType, type ConnectorDevice, type ConnectorEventMap, type ConnectorEventType, type ConnectorSession, type ConnectorUiEvent, DEVICE, DEVICE_EVENT, type DeviceCapabilities, type DeviceChangeEvent, type DeviceConnectEvent, type DeviceDescriptor, type DeviceDisconnectEvent, type DeviceEvent, type DeviceEventListener, type DeviceInfo, DeviceJobQueue, type DeviceJobQueueDeps, type DeviceTarget, EConnectorInteraction, type EIP712Domain, type EvmAddress, type EvmGetAddressParams, type EvmSignMsgParams, type EvmSignTxParams, type EvmSignTypedDataFull, type EvmSignTypedDataHash, type EvmSignTypedDataParams, type EvmSignature, type EvmSignedTx, type Failure, HardwareErrorCode, type HardwareEvent, type HardwareEventMap, type IBtcMethods, type IConnector, type IEvmMethods, type IHardwareBridge, type IHardwareWallet, type ISolMethods, type ITronMethods, type Interruptibility, type JobOptions, type PassphraseResponse, type PreemptionDecision, type PreemptionEvent, type ProgressCallback, type QrDisplayData, type QrResponseData, type Response, SDK, type SdkEvent, type SolAddress, type SolGetAddressParams, type SolSignMsgParams, type SolSignTxParams, type SolSignature, type SolSignedTx, type Success, type TransportType, type TronAddress, type TronGetAddressParams, type TronSignMsgParams, type TronSignTxParams, type TronSignature, type TronSignedTx, TypedEventEmitter, UI_EVENT, UI_REQUEST, UI_REQUEST_CANCELLED_TAG, UI_REQUEST_DEFAULT_TIMEOUT_MS, UI_REQUEST_PREEMPTED_TAG, UI_REQUEST_TIMEOUT_TAG, UI_RESPONSE, type UiRequestEvent, UiRequestRegistry, type UiResponseEvent, type VendorType, batchCall, bytesToHex, compareSemver, createBridgedConnector, deriveDeviceFingerprint, enrichErrorMessage, ensure0x, failure, hexToBytes, padHex64, stripHex, success };
|