@onekeyfe/hwk-trezor-connector 1.1.27-alpha.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,1671 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ TrezorConnectorBase: () => TrezorConnectorBase
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+
27
+ // src/chains/btc.ts
28
+ var import_hwk_adapter_core = require("@onekeyfe/hwk-adapter-core");
29
+
30
+ // src/chains/utils.ts
31
+ function parseBip32Path(path) {
32
+ const normalized = path.trim();
33
+ const parts = normalized.startsWith("m/") ? normalized.slice(2).split("/") : normalized === "m" ? [] : normalized.split("/");
34
+ if (parts.length === 0 || parts.some((part) => part.length === 0)) {
35
+ throw new Error(`Invalid BIP32 path: ${path}`);
36
+ }
37
+ return parts.map((part) => {
38
+ const match = part.match(/^(\d+)(['hH]?)$/);
39
+ if (!match) {
40
+ throw new Error(`Invalid BIP32 path segment: ${part}`);
41
+ }
42
+ const index = Number(match[1]);
43
+ if (!Number.isSafeInteger(index) || index < 0 || index > 2147483647) {
44
+ throw new Error(`BIP32 path segment out of range: ${part}`);
45
+ }
46
+ return match[2] ? index + 2147483648 : index;
47
+ });
48
+ }
49
+ function readString(value, key) {
50
+ const candidate = value[key];
51
+ return typeof candidate === "string" ? candidate : void 0;
52
+ }
53
+ function readNumber(value, key) {
54
+ const candidate = value[key];
55
+ return typeof candidate === "number" ? candidate : void 0;
56
+ }
57
+
58
+ // src/chains/btc.ts
59
+ var BTC_SCRIPT_TYPE_MAP = {
60
+ p2pkh: "SPENDADDRESS",
61
+ p2sh: "SPENDP2SHWITNESS",
62
+ p2wpkh: "SPENDWITNESS",
63
+ p2wsh: "SPENDWITNESS",
64
+ p2tr: "SPENDTAPROOT"
65
+ };
66
+ var BTC_CHANGE_OUTPUT_SCRIPT_TYPE_MAP = {
67
+ p2pkh: "PAYTOADDRESS",
68
+ p2sh: "PAYTOP2SHWITNESS",
69
+ p2wpkh: "PAYTOWITNESS",
70
+ p2wsh: "PAYTOWITNESS",
71
+ p2tr: "PAYTOTAPROOT"
72
+ };
73
+ var BTC_COIN_NAME_ALIASES = {
74
+ btc: "Bitcoin",
75
+ bitcoin: "Bitcoin",
76
+ test: "Testnet",
77
+ tbtc: "Testnet",
78
+ testnet: "Testnet",
79
+ sbtc: "Signet",
80
+ signet: "Signet",
81
+ ltc: "Litecoin",
82
+ litecoin: "Litecoin",
83
+ doge: "Dogecoin",
84
+ dogecoin: "Dogecoin",
85
+ bch: "Bcash",
86
+ bcash: "Bcash",
87
+ dash: "Dash"
88
+ };
89
+ function normalizeBtcCoin(coin) {
90
+ if (!coin) return "Bitcoin";
91
+ return BTC_COIN_NAME_ALIASES[coin.toLowerCase()] ?? coin;
92
+ }
93
+ function deriveScriptTypeFromPath(path) {
94
+ if (path.includes("86'")) return "p2tr";
95
+ if (path.includes("84'")) return "p2wpkh";
96
+ if (path.includes("49'")) return "p2sh";
97
+ if (path.includes("44'")) return "p2pkh";
98
+ return "p2wpkh";
99
+ }
100
+ async function btcGetAddress(ctx, params) {
101
+ const request = readBtcGetAddressParams(params);
102
+ const response = await ctx.deviceSession.call("GetAddress", {
103
+ address_n: parseBip32Path(request.path),
104
+ coin_name: normalizeBtcCoin(request.coin),
105
+ show_display: request.showOnDevice ?? false,
106
+ script_type: BTC_SCRIPT_TYPE_MAP[request.scriptType ?? deriveScriptTypeFromPath(request.path)]
107
+ });
108
+ if (response.type !== "Address") {
109
+ throw new Error(`Expected Address response, received ${response.type}`);
110
+ }
111
+ const message = response.message;
112
+ const address = readString(message, "address");
113
+ if (!address) {
114
+ throw new Error("Address response did not include an address");
115
+ }
116
+ return {
117
+ address,
118
+ path: request.path
119
+ };
120
+ }
121
+ async function btcGetPublicKey(ctx, params) {
122
+ const request = readBtcGetPublicKeyParams(params);
123
+ const response = await ctx.deviceSession.call("GetPublicKey", {
124
+ address_n: parseBip32Path(request.path),
125
+ coin_name: normalizeBtcCoin(request.coin),
126
+ show_display: request.showOnDevice ?? false
127
+ });
128
+ if (response.type !== "PublicKey") {
129
+ throw new Error(`Expected PublicKey response, received ${response.type}`);
130
+ }
131
+ return mapPublicKey(response.message, request.path);
132
+ }
133
+ async function btcSignMessage(ctx, params) {
134
+ const request = readBtcSignMessageParams(params);
135
+ const response = await ctx.deviceSession.call("SignMessage", {
136
+ address_n: parseBip32Path(request.path),
137
+ message: request.message,
138
+ coin_name: normalizeBtcCoin(request.coin)
139
+ });
140
+ if (response.type !== "MessageSignature") {
141
+ throw new Error(`Expected MessageSignature response, received ${response.type}`);
142
+ }
143
+ const msg = response.message;
144
+ const signature = readString(msg, "signature");
145
+ if (!signature) {
146
+ throw new Error("MessageSignature response did not include a signature");
147
+ }
148
+ return {
149
+ signature,
150
+ address: readString(msg, "address")
151
+ };
152
+ }
153
+ async function btcGetMasterFingerprint(ctx) {
154
+ const response = await ctx.deviceSession.call("GetPublicKey", {
155
+ address_n: parseBip32Path("m/44'/0'/0'"),
156
+ coin_name: "Bitcoin",
157
+ show_display: false
158
+ });
159
+ if (response.type !== "PublicKey") {
160
+ throw new Error(`Expected PublicKey response, received ${response.type}`);
161
+ }
162
+ const root = readNumber(response.message, "root_fingerprint");
163
+ if (root === void 0) {
164
+ throw new Error(
165
+ "btcGetMasterFingerprint: Trezor PublicKey response omitted root_fingerprint \u2014 firmware too old?"
166
+ );
167
+ }
168
+ return { masterFingerprint: root.toString(16).padStart(8, "0") };
169
+ }
170
+ async function btcSignTransaction(ctx, params) {
171
+ const request = readBtcSignTxParams(params);
172
+ const { inputs, outputs } = request;
173
+ const refTxs = indexRefTxs(request.refTxs ?? []);
174
+ const serializedParts = [];
175
+ const signatures = [];
176
+ const initial = {
177
+ coin_name: normalizeBtcCoin(request.coin),
178
+ inputs_count: inputs.length,
179
+ outputs_count: outputs.length,
180
+ version: request.version ?? 1
181
+ };
182
+ if (request.locktime !== void 0) {
183
+ initial.lock_time = request.locktime;
184
+ }
185
+ let response = await ctx.deviceSession.call("SignTx", initial);
186
+ const maxRounds = (inputs.length + outputs.length + 1) * 8 + 64;
187
+ for (let round = 0; round < maxRounds; round += 1) {
188
+ if (response.type !== "TxRequest") {
189
+ throw new Error(`Expected TxRequest during SignTx, received ${response.type}`);
190
+ }
191
+ const txRequest = response.message;
192
+ saveTxSignatures(txRequest.serialized, serializedParts, signatures);
193
+ const requestType = readString(txRequest, "request_type");
194
+ if (requestType === "TXFINISHED") {
195
+ return { serializedTx: serializedParts.join(""), signatures };
196
+ }
197
+ const details = txRequest.details ?? {};
198
+ const requestIndex = readNumber(details, "request_index") ?? 0;
199
+ const txHash = readString(details, "tx_hash");
200
+ response = await sendTxAck(
201
+ ctx,
202
+ requestType,
203
+ requestIndex,
204
+ txHash,
205
+ inputs,
206
+ outputs,
207
+ refTxs
208
+ );
209
+ }
210
+ throw new Error("btcSignTransaction: device exceeded the expected number of TxRequest rounds");
211
+ }
212
+ function saveTxSignatures(serialized, serializedParts, signatures) {
213
+ if (!serialized || typeof serialized !== "object") return;
214
+ const s = serialized;
215
+ const chunk = readString(s, "serialized_tx");
216
+ if (chunk) serializedParts.push(chunk);
217
+ const index = readNumber(s, "signature_index");
218
+ const signature = readString(s, "signature");
219
+ if (index !== void 0 && signature) {
220
+ signatures[index] = signature;
221
+ }
222
+ }
223
+ async function sendTxAck(ctx, requestType, requestIndex, txHash, inputs, outputs, refTxs) {
224
+ switch (requestType) {
225
+ case "TXINPUT": {
226
+ if (txHash) {
227
+ const prev = lookupRefTx(refTxs, txHash);
228
+ const input2 = prev.inputs[requestIndex];
229
+ if (!input2) {
230
+ throw new Error(`SignTx requested prev input ${requestIndex} missing in ${txHash}`);
231
+ }
232
+ return ctx.deviceSession.call("TxAckPrevInput", {
233
+ tx: {
234
+ input: {
235
+ prev_hash: input2.prevHash,
236
+ prev_index: input2.prevIndex,
237
+ script_sig: input2.script,
238
+ sequence: input2.sequence
239
+ }
240
+ }
241
+ });
242
+ }
243
+ const input = inputs[requestIndex];
244
+ if (!input) throw new Error(`SignTx requested input ${requestIndex} out of range`);
245
+ return ctx.deviceSession.call("TxAckInput", {
246
+ tx: { input: inputToTrezor(input) }
247
+ });
248
+ }
249
+ case "TXOUTPUT": {
250
+ if (txHash) {
251
+ const prev = lookupRefTx(refTxs, txHash);
252
+ const output2 = prev.outputs[requestIndex];
253
+ if (!output2) {
254
+ throw new Error(`SignTx requested prev output ${requestIndex} missing in ${txHash}`);
255
+ }
256
+ return ctx.deviceSession.call("TxAckPrevOutput", {
257
+ tx: { output: { amount: output2.amount, script_pubkey: output2.scriptPubKey } }
258
+ });
259
+ }
260
+ const output = outputs[requestIndex];
261
+ if (!output) throw new Error(`SignTx requested output ${requestIndex} out of range`);
262
+ return ctx.deviceSession.call("TxAckOutput", {
263
+ tx: { output: outputToTrezor(output) }
264
+ });
265
+ }
266
+ case "TXMETA": {
267
+ if (!txHash) throw new Error("SignTx TXMETA request missing tx_hash");
268
+ const prev = lookupRefTx(refTxs, txHash);
269
+ return ctx.deviceSession.call("TxAckPrevMeta", {
270
+ tx: {
271
+ version: prev.version,
272
+ lock_time: prev.locktime,
273
+ inputs_count: prev.inputs.length,
274
+ outputs_count: prev.outputs.length
275
+ }
276
+ });
277
+ }
278
+ case "TXEXTRADATA":
279
+ throw Object.assign(
280
+ new Error(
281
+ "btcSignTransaction: device requested extra_data, but the adapter params carry none (Zcash/Dash not supported)"
282
+ ),
283
+ { code: import_hwk_adapter_core.HardwareErrorCode.MethodNotSupported }
284
+ );
285
+ default:
286
+ throw new Error(`btcSignTransaction: unsupported TxRequest type "${requestType}"`);
287
+ }
288
+ }
289
+ function inputToTrezor(input) {
290
+ const result = {
291
+ address_n: parseBip32Path(input.path),
292
+ prev_hash: input.prevHash,
293
+ prev_index: input.prevIndex,
294
+ amount: input.amount,
295
+ script_type: BTC_SCRIPT_TYPE_MAP[input.scriptType ?? deriveScriptTypeFromPath(input.path)]
296
+ };
297
+ if (input.sequence !== void 0) result.sequence = input.sequence;
298
+ return result;
299
+ }
300
+ function outputToTrezor(output) {
301
+ if (output.address) {
302
+ return {
303
+ address: output.address,
304
+ amount: output.amount,
305
+ script_type: "PAYTOADDRESS"
306
+ };
307
+ }
308
+ if (output.path) {
309
+ return {
310
+ address_n: parseBip32Path(output.path),
311
+ amount: output.amount,
312
+ script_type: BTC_CHANGE_OUTPUT_SCRIPT_TYPE_MAP[output.scriptType ?? deriveScriptTypeFromPath(output.path)]
313
+ };
314
+ }
315
+ throw new Error("btcSignTransaction output requires either an address or a change path");
316
+ }
317
+ function indexRefTxs(refTxs) {
318
+ const map = /* @__PURE__ */ new Map();
319
+ for (const tx of refTxs) {
320
+ map.set(tx.hash.toLowerCase(), tx);
321
+ }
322
+ return map;
323
+ }
324
+ function lookupRefTx(map, txHash) {
325
+ const tx = map.get(txHash.toLowerCase());
326
+ if (!tx) {
327
+ throw new Error(`btcSignTransaction: device requested unknown previous tx ${txHash}`);
328
+ }
329
+ return tx;
330
+ }
331
+ function readBtcSignTxParams(params) {
332
+ if (!params || typeof params !== "object") {
333
+ throw new Error("btcSignTransaction params must be an object");
334
+ }
335
+ const p = params;
336
+ if (!Array.isArray(p.inputs) || p.inputs.length === 0) {
337
+ throw new Error("btcSignTransaction requires a non-empty inputs array");
338
+ }
339
+ if (!Array.isArray(p.outputs) || p.outputs.length === 0) {
340
+ throw new Error("btcSignTransaction requires a non-empty outputs array");
341
+ }
342
+ return p;
343
+ }
344
+ async function btcSignPsbt(_ctx, _params) {
345
+ throw Object.assign(
346
+ new Error(
347
+ "btcSignPsbt is not wired for Trezor \u2014 stock Trezor firmware has no SignPsbt message; PSBT signing requires host-side decode \u2192 SignTx \u2192 re-embed (not yet implemented)"
348
+ ),
349
+ { code: import_hwk_adapter_core.HardwareErrorCode.MethodNotSupported }
350
+ );
351
+ }
352
+ function readBtcGetPublicKeyParams(params) {
353
+ if (!params || typeof params !== "object") {
354
+ throw new Error("btcGetPublicKey params must be an object");
355
+ }
356
+ const path = params.path;
357
+ if (typeof path !== "string" || path.trim().length === 0) {
358
+ throw new Error("btcGetPublicKey requires a non-empty path");
359
+ }
360
+ const coin = params.coin;
361
+ if (coin !== void 0 && typeof coin !== "string") {
362
+ throw new Error("btcGetPublicKey coin must be a string when provided");
363
+ }
364
+ const showOnDevice = params.showOnDevice;
365
+ if (showOnDevice !== void 0 && typeof showOnDevice !== "boolean") {
366
+ throw new Error("btcGetPublicKey showOnDevice must be a boolean when provided");
367
+ }
368
+ return { path, coin, showOnDevice };
369
+ }
370
+ function readBtcSignMessageParams(params) {
371
+ if (!params || typeof params !== "object") {
372
+ throw new Error("btcSignMessage params must be an object");
373
+ }
374
+ const path = params.path;
375
+ if (typeof path !== "string" || path.trim().length === 0) {
376
+ throw new Error("btcSignMessage requires a non-empty path");
377
+ }
378
+ const message = params.message;
379
+ if (typeof message !== "string") {
380
+ throw new Error("btcSignMessage requires message as a string");
381
+ }
382
+ const coin = params.coin;
383
+ if (coin !== void 0 && typeof coin !== "string") {
384
+ throw new Error("btcSignMessage coin must be a string when provided");
385
+ }
386
+ return { path, message, coin };
387
+ }
388
+ function mapPublicKey(msg, path) {
389
+ const xpub = readString(msg, "xpub");
390
+ if (!xpub) {
391
+ throw new Error("PublicKey response did not include xpub");
392
+ }
393
+ const node = msg.node;
394
+ if (!node || typeof node !== "object") {
395
+ throw new Error("PublicKey response did not include a node");
396
+ }
397
+ const publicKey = readString(node, "public_key");
398
+ const chainCode = readString(node, "chain_code");
399
+ const fingerprint = readNumber(node, "fingerprint");
400
+ const depth = readNumber(node, "depth");
401
+ if (!publicKey || !chainCode || fingerprint === void 0 || depth === void 0) {
402
+ throw new Error("PublicKey node missing required fields (public_key / chain_code / fingerprint / depth)");
403
+ }
404
+ return {
405
+ xpub,
406
+ publicKey,
407
+ fingerprint,
408
+ chainCode,
409
+ path,
410
+ depth
411
+ };
412
+ }
413
+ function readBtcGetAddressParams(params) {
414
+ if (!params || typeof params !== "object") {
415
+ throw new Error("btcGetAddress params must be an object");
416
+ }
417
+ const path = params.path;
418
+ if (typeof path !== "string" || path.trim().length === 0) {
419
+ throw new Error("btcGetAddress requires a non-empty path");
420
+ }
421
+ const coin = params.coin;
422
+ if (coin !== void 0 && typeof coin !== "string") {
423
+ throw new Error("btcGetAddress coin must be a string when provided");
424
+ }
425
+ const showOnDevice = params.showOnDevice;
426
+ if (showOnDevice !== void 0 && typeof showOnDevice !== "boolean") {
427
+ throw new Error("btcGetAddress showOnDevice must be a boolean when provided");
428
+ }
429
+ const scriptType = params.scriptType;
430
+ if (scriptType !== void 0 && typeof scriptType !== "string") {
431
+ throw new Error("btcGetAddress scriptType must be a string when provided");
432
+ }
433
+ if (scriptType !== void 0 && !Object.prototype.hasOwnProperty.call(BTC_SCRIPT_TYPE_MAP, scriptType)) {
434
+ throw new Error("btcGetAddress scriptType is unsupported");
435
+ }
436
+ return {
437
+ path,
438
+ coin,
439
+ showOnDevice,
440
+ scriptType
441
+ };
442
+ }
443
+
444
+ // src/chains/eip712.ts
445
+ var import_buffer = require("buffer");
446
+ var EthereumDataType = {
447
+ UINT: 1,
448
+ INT: 2,
449
+ BYTES: 3,
450
+ STRING: 4,
451
+ BOOL: 5,
452
+ ADDRESS: 6,
453
+ ARRAY: 7,
454
+ STRUCT: 8
455
+ };
456
+ var paramTypeArray = /^(.*)\[([0-9]*)\]$/;
457
+ var paramTypeBytes = /^bytes([0-9]*)$/;
458
+ var paramTypeNumber = /^(u?int)([0-9]*)$/;
459
+ var simpleTypesMap = {
460
+ string: EthereumDataType.STRING,
461
+ bool: EthereumDataType.BOOL,
462
+ address: EthereumDataType.ADDRESS
463
+ };
464
+ function parseArrayType(arrayTypeName) {
465
+ const match = paramTypeArray.exec(arrayTypeName);
466
+ if (!match) {
467
+ throw new Error(`Type ${arrayTypeName} is not an EIP-712 array`);
468
+ }
469
+ const [, entryTypeName, arraySize] = match;
470
+ return {
471
+ entryTypeName,
472
+ arraySize: parseInt(arraySize, 10) || null
473
+ };
474
+ }
475
+ function getFieldType(typeName, types) {
476
+ const arrayMatch = paramTypeArray.exec(typeName);
477
+ if (arrayMatch) {
478
+ const [, entryTypeName, arraySize] = arrayMatch;
479
+ return {
480
+ data_type: EthereumDataType.ARRAY,
481
+ size: parseInt(arraySize, 10) || void 0,
482
+ entry_type: getFieldType(entryTypeName, types)
483
+ };
484
+ }
485
+ const numberMatch = paramTypeNumber.exec(typeName);
486
+ if (numberMatch) {
487
+ const [, intType, bits] = numberMatch;
488
+ return {
489
+ data_type: intType === "uint" ? EthereumDataType.UINT : EthereumDataType.INT,
490
+ size: Math.floor(parseInt(bits, 10) / 8)
491
+ };
492
+ }
493
+ const bytesMatch = paramTypeBytes.exec(typeName);
494
+ if (bytesMatch) {
495
+ const [, size] = bytesMatch;
496
+ return {
497
+ data_type: EthereumDataType.BYTES,
498
+ size: parseInt(size, 10) || void 0
499
+ };
500
+ }
501
+ const simple = simpleTypesMap[typeName];
502
+ if (simple !== void 0) {
503
+ return { data_type: simple };
504
+ }
505
+ if (typeName in types) {
506
+ return {
507
+ data_type: EthereumDataType.STRUCT,
508
+ size: types[typeName].length,
509
+ struct_name: typeName
510
+ };
511
+ }
512
+ throw new Error(`EIP-712: type "${typeName}" is not defined`);
513
+ }
514
+ function encodeData(typeName, value) {
515
+ if (paramTypeBytes.test(typeName) || typeName === "address") {
516
+ if (typeof value !== "string") {
517
+ throw new Error(`EIP-712 encodeData ${typeName}: expected hex string`);
518
+ }
519
+ return formatHex(value);
520
+ }
521
+ if (typeName === "string") {
522
+ if (typeof value !== "string") {
523
+ throw new Error("EIP-712 encodeData string: expected string value");
524
+ }
525
+ return import_buffer.Buffer.from(value, "utf-8").toString("hex");
526
+ }
527
+ const numberMatch = paramTypeNumber.exec(typeName);
528
+ if (numberMatch) {
529
+ const [, intType, bits] = numberMatch;
530
+ const bytes = Math.ceil(parseInt(bits, 10) / 8);
531
+ return intToHex(value, bytes, intType === "int");
532
+ }
533
+ if (typeName === "bool") {
534
+ return value ? "01" : "00";
535
+ }
536
+ throw new Error(`EIP-712 encodeData: unsupported atomic type "${typeName}"`);
537
+ }
538
+ function formatHex(value) {
539
+ let v = value.startsWith("0x") || value.startsWith("0X") ? value.slice(2) : value;
540
+ if (v.length % 2 !== 0) v = `0${v}`;
541
+ return v;
542
+ }
543
+ function intToHex(value, bytes, signed) {
544
+ let bn;
545
+ if (typeof value === "bigint") {
546
+ bn = value;
547
+ } else if (typeof value === "number") {
548
+ if (!Number.isFinite(value)) throw new Error(`EIP-712 intToHex: invalid number ${value}`);
549
+ bn = BigInt(Math.trunc(value));
550
+ } else if (typeof value === "boolean") {
551
+ bn = BigInt(value ? 1 : 0);
552
+ } else if (typeof value === "string") {
553
+ bn = BigInt(value);
554
+ } else {
555
+ throw new Error(`EIP-712 intToHex: cannot encode value of type ${typeof value}`);
556
+ }
557
+ const range = 1n << BigInt(bytes * 8);
558
+ if (signed) {
559
+ const halfRange = range >> 1n;
560
+ if (bn < -halfRange || bn >= halfRange) {
561
+ throw new Error(
562
+ `EIP-712 intToHex: value out of range for ${bytes * 8}-bit int`
563
+ );
564
+ }
565
+ if (bn < 0n) {
566
+ bn = range + bn;
567
+ }
568
+ } else if (bn < 0n || bn >= range) {
569
+ throw new Error(`EIP-712 intToHex: value out of range for ${bytes * 8}-bit uint`);
570
+ }
571
+ return bn.toString(16).padStart(bytes * 2, "0");
572
+ }
573
+
574
+ // src/chains/evm.ts
575
+ var MAX_DATA_CHUNK_BYTES = 1024;
576
+ async function evmGetAddress(ctx, params) {
577
+ const request = readEvmGetAddressParams(params);
578
+ const response = await ctx.deviceSession.call("EthereumGetAddress", {
579
+ address_n: parseBip32Path(request.path),
580
+ show_display: request.showOnDevice ?? false
581
+ });
582
+ if (response.type !== "EthereumAddress") {
583
+ throw new Error(`Expected EthereumAddress response, received ${response.type}`);
584
+ }
585
+ const message = response.message;
586
+ const address = readString(message, "address");
587
+ if (!address) {
588
+ throw new Error("EthereumAddress response did not include an address");
589
+ }
590
+ return {
591
+ address,
592
+ path: request.path
593
+ };
594
+ }
595
+ async function evmSignTransaction(ctx, params) {
596
+ const tx = readEvmSignTxParams(params);
597
+ const addressN = parseBip32Path(tx.path);
598
+ const isEip1559 = tx.maxFeePerGas !== void 0 || tx.maxPriorityFeePerGas !== void 0;
599
+ if (isEip1559) {
600
+ return signEip1559(ctx, addressN, tx);
601
+ }
602
+ return signLegacy(ctx, addressN, tx);
603
+ }
604
+ async function signLegacy(ctx, addressN, tx) {
605
+ if (tx.chainId === void 0) {
606
+ throw new Error("evmSignTransaction: chainId is required for legacy transactions");
607
+ }
608
+ const dataHex = stripHexPrefix(tx.data ?? "");
609
+ const dataByteLength = dataHex.length / 2;
610
+ const [firstChunk, rest] = sliceHex(dataHex, MAX_DATA_CHUNK_BYTES * 2);
611
+ const message = {
612
+ address_n: addressN,
613
+ nonce: trezorHexAmount(tx.nonce),
614
+ gas_price: trezorHexAmount(tx.gasPrice),
615
+ gas_limit: trezorHexAmount(tx.gasLimit),
616
+ to: tx.to ?? "",
617
+ value: trezorHexAmount(tx.value),
618
+ chain_id: tx.chainId
619
+ };
620
+ if (dataByteLength > 0) {
621
+ message.data_length = dataByteLength;
622
+ message.data_initial_chunk = firstChunk;
623
+ }
624
+ const initial = await ctx.deviceSession.call("EthereumSignTx", message);
625
+ return processTxRequest(ctx, initial, rest, tx.chainId);
626
+ }
627
+ async function signEip1559(ctx, addressN, tx) {
628
+ if (tx.chainId === void 0) {
629
+ throw new Error("evmSignTransaction: chainId is required for EIP-1559 transactions");
630
+ }
631
+ if (tx.maxFeePerGas === void 0 || tx.maxPriorityFeePerGas === void 0) {
632
+ throw new Error(
633
+ "evmSignTransaction: EIP-1559 requires both maxFeePerGas and maxPriorityFeePerGas"
634
+ );
635
+ }
636
+ const dataHex = stripHexPrefix(tx.data ?? "");
637
+ const dataByteLength = dataHex.length / 2;
638
+ const [firstChunk, rest] = sliceHex(dataHex, MAX_DATA_CHUNK_BYTES * 2);
639
+ const message = {
640
+ address_n: addressN,
641
+ nonce: trezorHexAmount(tx.nonce),
642
+ max_gas_fee: trezorHexAmount(tx.maxFeePerGas),
643
+ max_priority_fee: trezorHexAmount(tx.maxPriorityFeePerGas),
644
+ gas_limit: trezorHexAmount(tx.gasLimit),
645
+ to: tx.to ?? "",
646
+ value: trezorHexAmount(tx.value),
647
+ data_length: dataByteLength,
648
+ data_initial_chunk: firstChunk,
649
+ chain_id: tx.chainId,
650
+ access_list: (tx.accessList ?? []).map((entry) => ({
651
+ address: entry.address,
652
+ storage_keys: entry.storageKeys
653
+ }))
654
+ };
655
+ const initial = await ctx.deviceSession.call("EthereumSignTxEIP1559", message);
656
+ return processTxRequest(ctx, initial, rest, void 0);
657
+ }
658
+ async function processTxRequest(ctx, initialResponse, remainingData, chainIdForLegacyV) {
659
+ let response = initialResponse;
660
+ let remaining = remainingData;
661
+ while (true) {
662
+ if (response.type !== "EthereumTxRequest") {
663
+ throw new Error(`Expected EthereumTxRequest, received ${response.type}`);
664
+ }
665
+ const req = response.message;
666
+ const dataLength = readNumber(req, "data_length");
667
+ if (!dataLength) {
668
+ return buildSignedTx(req, chainIdForLegacyV);
669
+ }
670
+ const [chunk, nextRest] = sliceHex(remaining, dataLength * 2);
671
+ response = await ctx.deviceSession.call("EthereumTxAck", { data_chunk: chunk });
672
+ remaining = nextRest;
673
+ }
674
+ }
675
+ function buildSignedTx(req, chainIdForLegacyV) {
676
+ let v = readNumber(req, "signature_v");
677
+ const r = readString(req, "signature_r");
678
+ const s = readString(req, "signature_s");
679
+ if (v === void 0 || r === void 0 || s === void 0) {
680
+ throw new Error("EthereumTxRequest missing signature fields (v, r, or s)");
681
+ }
682
+ if (chainIdForLegacyV !== void 0 && v <= 1) {
683
+ v += 2 * chainIdForLegacyV + 35;
684
+ }
685
+ return {
686
+ v: `0x${v.toString(16)}`,
687
+ r: `0x${r}`,
688
+ s: `0x${s}`
689
+ };
690
+ }
691
+ function readEvmSignTxParams(params) {
692
+ if (!params || typeof params !== "object") {
693
+ throw new Error("evmSignTransaction params must be an object");
694
+ }
695
+ const path = params.path;
696
+ if (typeof path !== "string" || path.trim().length === 0) {
697
+ throw new Error("evmSignTransaction requires a non-empty path");
698
+ }
699
+ return params;
700
+ }
701
+ function stripHexPrefix(value) {
702
+ return value.startsWith("0x") || value.startsWith("0X") ? value.slice(2) : value;
703
+ }
704
+ function trezorHexAmount(value) {
705
+ if (value === void 0) return "";
706
+ let v = stripHexPrefix(value);
707
+ while (v.startsWith("00")) v = v.slice(2);
708
+ return v;
709
+ }
710
+ function sliceHex(hex, charsInFirstChunk) {
711
+ if (hex.length <= charsInFirstChunk) return [hex, ""];
712
+ return [hex.slice(0, charsInFirstChunk), hex.slice(charsInFirstChunk)];
713
+ }
714
+ async function evmSignTypedData(ctx, params) {
715
+ const request = readEvmSignTypedDataParams(params);
716
+ if (request.mode === "hash") {
717
+ return signTypedHash(ctx, request);
718
+ }
719
+ return signTypedDataFull(ctx, request);
720
+ }
721
+ async function signTypedDataFull(ctx, request) {
722
+ const addressN = parseBip32Path(request.path);
723
+ const { types, primaryType, domain, message } = request.data;
724
+ const typedTypes = types;
725
+ const metamaskV4Compat = request.metamaskV4Compat ?? true;
726
+ let response = await ctx.deviceSession.call("EthereumSignTypedData", {
727
+ address_n: addressN,
728
+ primary_type: primaryType,
729
+ metamask_v4_compat: metamaskV4Compat
730
+ });
731
+ while (response.type === "EthereumTypedDataStructRequest") {
732
+ const reqMsg = response.message;
733
+ const typeName = readString(reqMsg, "name");
734
+ if (!typeName) {
735
+ throw new Error("EthereumTypedDataStructRequest missing `name`");
736
+ }
737
+ const typeDef = typedTypes[typeName];
738
+ if (!typeDef) {
739
+ throw new Error(`EIP-712: type "${typeName}" requested by device but not in types`);
740
+ }
741
+ response = await ctx.deviceSession.call("EthereumTypedDataStructAck", {
742
+ members: typeDef.map(({ name, type }) => ({
743
+ name,
744
+ type: getFieldType(type, typedTypes)
745
+ }))
746
+ });
747
+ }
748
+ while (response.type === "EthereumTypedDataValueRequest") {
749
+ const reqMsg = response.message;
750
+ const memberPath = reqMsg.member_path;
751
+ if (!Array.isArray(memberPath) || memberPath.length === 0) {
752
+ throw new Error("EthereumTypedDataValueRequest missing member_path");
753
+ }
754
+ let memberData;
755
+ let memberTypeName;
756
+ const [rootIndex, ...nested] = memberPath;
757
+ if (rootIndex === 0) {
758
+ memberData = domain;
759
+ memberTypeName = "EIP712Domain";
760
+ } else if (rootIndex === 1) {
761
+ memberData = message;
762
+ memberTypeName = primaryType;
763
+ } else {
764
+ throw new Error(`EIP-712 member_path root index must be 0 or 1, got ${rootIndex}`);
765
+ }
766
+ for (const index of nested) {
767
+ if (Array.isArray(memberData)) {
768
+ memberTypeName = parseArrayType(memberTypeName).entryTypeName;
769
+ memberData = memberData[index];
770
+ } else if (memberData !== null && typeof memberData === "object") {
771
+ const def = typedTypes[memberTypeName]?.[index];
772
+ if (!def) {
773
+ throw new Error(
774
+ `EIP-712 member_path: no member at index ${index} of type "${memberTypeName}"`
775
+ );
776
+ }
777
+ memberTypeName = def.type;
778
+ memberData = memberData[def.name];
779
+ } else {
780
+ throw new Error("EIP-712 member_path: cannot traverse into a leaf value");
781
+ }
782
+ }
783
+ const value = Array.isArray(memberData) ? encodeData("uint16", memberData.length) : encodeData(memberTypeName, memberData);
784
+ response = await ctx.deviceSession.call("EthereumTypedDataValueAck", { value });
785
+ }
786
+ if (response.type !== "EthereumTypedDataSignature") {
787
+ throw new Error(`Expected EthereumTypedDataSignature, received ${response.type}`);
788
+ }
789
+ const msg = response.message;
790
+ const signature = readString(msg, "signature");
791
+ if (!signature) {
792
+ throw new Error("EthereumTypedDataSignature response did not include a signature");
793
+ }
794
+ return {
795
+ signature: signature.startsWith("0x") ? signature : `0x${signature}`,
796
+ address: readString(msg, "address")
797
+ };
798
+ }
799
+ async function signTypedHash(ctx, params) {
800
+ const response = await ctx.deviceSession.call("EthereumSignTypedHash", {
801
+ address_n: parseBip32Path(params.path),
802
+ domain_separator_hash: stripHexPrefix(params.domainSeparatorHash),
803
+ message_hash: stripHexPrefix(params.messageHash)
804
+ });
805
+ if (response.type !== "EthereumTypedDataSignature") {
806
+ throw new Error(
807
+ `Expected EthereumTypedDataSignature response, received ${response.type}`
808
+ );
809
+ }
810
+ const message = response.message;
811
+ const signature = readString(message, "signature");
812
+ if (!signature) {
813
+ throw new Error("EthereumTypedDataSignature response did not include a signature");
814
+ }
815
+ return {
816
+ signature: signature.startsWith("0x") ? signature : `0x${signature}`,
817
+ address: readString(message, "address")
818
+ };
819
+ }
820
+ function readEvmSignTypedDataParams(params) {
821
+ if (!params || typeof params !== "object") {
822
+ throw new Error("evmSignTypedData params must be an object");
823
+ }
824
+ const path = params.path;
825
+ if (typeof path !== "string" || path.trim().length === 0) {
826
+ throw new Error("evmSignTypedData requires a non-empty path");
827
+ }
828
+ const mode = params.mode;
829
+ if (mode === "hash") {
830
+ const dsh = params.domainSeparatorHash;
831
+ const mh = params.messageHash;
832
+ if (typeof dsh !== "string") {
833
+ throw new Error("evmSignTypedData (mode 'hash') requires domainSeparatorHash");
834
+ }
835
+ if (typeof mh !== "string") {
836
+ throw new Error("evmSignTypedData (mode 'hash') requires messageHash");
837
+ }
838
+ return { path, mode: "hash", domainSeparatorHash: dsh, messageHash: mh };
839
+ }
840
+ return params;
841
+ }
842
+ async function evmSignMessage(ctx, params) {
843
+ const request = readEvmSignMessageParams(params);
844
+ const response = await ctx.deviceSession.call("EthereumSignMessage", {
845
+ address_n: parseBip32Path(request.path),
846
+ message: normalizeEthMessage(request.message, request.hex ?? false)
847
+ });
848
+ if (response.type !== "EthereumMessageSignature") {
849
+ throw new Error(`Expected EthereumMessageSignature response, received ${response.type}`);
850
+ }
851
+ const message = response.message;
852
+ const signature = readString(message, "signature");
853
+ if (!signature) {
854
+ throw new Error("EthereumMessageSignature response did not include a signature");
855
+ }
856
+ return {
857
+ signature: signature.startsWith("0x") ? signature : `0x${signature}`,
858
+ address: readString(message, "address")
859
+ };
860
+ }
861
+ function readEvmGetAddressParams(params) {
862
+ if (!params || typeof params !== "object") {
863
+ throw new Error("evmGetAddress params must be an object");
864
+ }
865
+ const path = params.path;
866
+ if (typeof path !== "string" || path.trim().length === 0) {
867
+ throw new Error("evmGetAddress requires a non-empty path");
868
+ }
869
+ const showOnDevice = params.showOnDevice;
870
+ if (showOnDevice !== void 0 && typeof showOnDevice !== "boolean") {
871
+ throw new Error("evmGetAddress showOnDevice must be a boolean when provided");
872
+ }
873
+ return {
874
+ path,
875
+ showOnDevice
876
+ };
877
+ }
878
+ function readEvmSignMessageParams(params) {
879
+ if (!params || typeof params !== "object") {
880
+ throw new Error("evmSignMessage params must be an object");
881
+ }
882
+ const path = params.path;
883
+ if (typeof path !== "string" || path.trim().length === 0) {
884
+ throw new Error("evmSignMessage requires a non-empty path");
885
+ }
886
+ const message = params.message;
887
+ if (typeof message !== "string") {
888
+ throw new Error("evmSignMessage requires message as a string");
889
+ }
890
+ const hex = params.hex;
891
+ if (hex !== void 0 && typeof hex !== "boolean") {
892
+ throw new Error("evmSignMessage hex must be a boolean when provided");
893
+ }
894
+ return { path, message, hex };
895
+ }
896
+ function normalizeEthMessage(message, isHex) {
897
+ if (!isHex) return message;
898
+ let stripped = message.startsWith("0x") || message.startsWith("0X") ? message.slice(2) : message;
899
+ if (stripped.length % 2 !== 0) stripped = `0${stripped}`;
900
+ if (!/^[0-9a-fA-F]*$/.test(stripped)) {
901
+ throw new Error("evmSignMessage: hex message contains non-hex characters");
902
+ }
903
+ return stripped;
904
+ }
905
+
906
+ // src/chains/sol.ts
907
+ var import_hwk_adapter_core2 = require("@onekeyfe/hwk-adapter-core");
908
+ async function solGetAddress(ctx, params) {
909
+ const request = readSolGetAddressParams(params);
910
+ const response = await ctx.deviceSession.call("SolanaGetAddress", {
911
+ address_n: parseBip32Path(request.path),
912
+ show_display: request.showOnDevice ?? false
913
+ });
914
+ if (response.type !== "SolanaAddress") {
915
+ throw new Error(`Expected SolanaAddress response, received ${response.type}`);
916
+ }
917
+ const address = readString(response.message, "address");
918
+ if (!address) {
919
+ throw new Error("SolanaAddress response did not include an address");
920
+ }
921
+ return { address, path: request.path };
922
+ }
923
+ async function solSignTransaction(ctx, params) {
924
+ const request = readSolSignTxParams(params);
925
+ const data = {
926
+ address_n: parseBip32Path(request.path),
927
+ serialized_tx: stripHexPrefix2(request.serializedTx)
928
+ };
929
+ if (request.additionalInfo?.tokenAccountsInfos?.length) {
930
+ data.additional_info = {
931
+ token_accounts_infos: request.additionalInfo.tokenAccountsInfos.map((info) => ({
932
+ base_address: info.baseAddress,
933
+ token_program: info.tokenProgram,
934
+ token_mint: info.tokenMint,
935
+ token_account: info.tokenAccount
936
+ }))
937
+ };
938
+ }
939
+ const response = await ctx.deviceSession.call("SolanaSignTx", data);
940
+ if (response.type !== "SolanaTxSignature") {
941
+ throw new Error(`Expected SolanaTxSignature response, received ${response.type}`);
942
+ }
943
+ const signature = readString(response.message, "signature");
944
+ if (!signature) {
945
+ throw new Error("SolanaTxSignature response did not include a signature");
946
+ }
947
+ return { signature };
948
+ }
949
+ async function solSignMessage(_ctx, _params) {
950
+ throw Object.assign(
951
+ new Error(
952
+ "Trezor firmware does not support Solana message signing \u2014 only solSignTransaction is available"
953
+ ),
954
+ { code: import_hwk_adapter_core2.HardwareErrorCode.MethodNotSupported }
955
+ );
956
+ }
957
+ function readSolGetAddressParams(params) {
958
+ if (!params || typeof params !== "object") {
959
+ throw new Error("solGetAddress params must be an object");
960
+ }
961
+ const path = params.path;
962
+ if (typeof path !== "string" || path.trim().length === 0) {
963
+ throw new Error("solGetAddress requires a non-empty path");
964
+ }
965
+ const showOnDevice = params.showOnDevice;
966
+ if (showOnDevice !== void 0 && typeof showOnDevice !== "boolean") {
967
+ throw new Error("solGetAddress showOnDevice must be a boolean when provided");
968
+ }
969
+ return { path, showOnDevice };
970
+ }
971
+ function readSolSignTxParams(params) {
972
+ if (!params || typeof params !== "object") {
973
+ throw new Error("solSignTransaction params must be an object");
974
+ }
975
+ const path = params.path;
976
+ if (typeof path !== "string" || path.trim().length === 0) {
977
+ throw new Error("solSignTransaction requires a non-empty path");
978
+ }
979
+ const serializedTx = params.serializedTx;
980
+ if (typeof serializedTx !== "string" || serializedTx.length === 0) {
981
+ throw new Error("solSignTransaction requires serializedTx as a hex string");
982
+ }
983
+ return params;
984
+ }
985
+ function stripHexPrefix2(value) {
986
+ return value.startsWith("0x") || value.startsWith("0X") ? value.slice(2) : value;
987
+ }
988
+
989
+ // src/chains/tron.ts
990
+ var import_hwk_adapter_core3 = require("@onekeyfe/hwk-adapter-core");
991
+ var import_hwk_trezor_protobuf = require("@onekeyfe/hwk-trezor-protobuf");
992
+ async function tronGetAddress(ctx, params) {
993
+ const request = readTronGetAddressParams(params);
994
+ const response = await ctx.deviceSession.call("TronGetAddress", {
995
+ address_n: parseBip32Path(request.path),
996
+ show_display: request.showOnDevice ?? false
997
+ });
998
+ if (response.type !== "TronAddress") {
999
+ throw new Error(`Expected TronAddress response, received ${response.type}`);
1000
+ }
1001
+ const address = readString(response.message, "address");
1002
+ if (!address) {
1003
+ throw new Error("TronAddress response did not include an address");
1004
+ }
1005
+ return { address, path: request.path };
1006
+ }
1007
+ async function tronSignTransaction(ctx, params) {
1008
+ const request = readTronSignTxParams(params);
1009
+ const ownerAddress = normalizeTronAddress(request.ownerAddress, "ownerAddress");
1010
+ const { messageName, value } = buildContractMessage(request.contract, ownerAddress);
1011
+ const header = {
1012
+ address_n: parseBip32Path(request.path),
1013
+ ref_block_bytes: request.refBlockBytes,
1014
+ ref_block_hash: request.refBlockHash,
1015
+ expiration: request.expiration,
1016
+ timestamp: request.timestamp
1017
+ };
1018
+ if (request.feeLimit !== void 0) {
1019
+ header.fee_limit = assertSafeInt(request.feeLimit, "feeLimit");
1020
+ }
1021
+ if (request.data !== void 0) header.data = stripHexPrefix3(request.data);
1022
+ const ack = await ctx.deviceSession.call("TronSignTx", header);
1023
+ if (ack.type !== "TronContractRequest") {
1024
+ throw new Error(`Expected TronContractRequest, received ${ack.type}`);
1025
+ }
1026
+ const response = await ctx.deviceSession.call(messageName, value);
1027
+ if (response.type !== "TronSignature") {
1028
+ throw new Error(`Expected TronSignature, received ${response.type}`);
1029
+ }
1030
+ const signature = readString(response.message, "signature");
1031
+ if (!signature) {
1032
+ throw new Error("TronSignature response did not include a signature");
1033
+ }
1034
+ const serializedTx = reconstructTronRawData(request, messageName, value);
1035
+ return serializedTx ? { signature, serializedTx } : { signature };
1036
+ }
1037
+ var TRON_RAW_CONTRACT = {
1038
+ TronTransferContract: {
1039
+ typeValue: 1,
1040
+ typeUrl: "type.googleapis.com/protocol.TransferContract",
1041
+ includeFeeLimit: false
1042
+ },
1043
+ TronTriggerSmartContract: {
1044
+ typeValue: 31,
1045
+ typeUrl: "type.googleapis.com/protocol.TriggerSmartContract",
1046
+ includeFeeLimit: true
1047
+ }
1048
+ };
1049
+ function reconstructTronRawData(request, contractMessageName, contractValue) {
1050
+ const info = TRON_RAW_CONTRACT[contractMessageName];
1051
+ if (!info) return void 0;
1052
+ const innerBytes = import_hwk_trezor_protobuf.protobufManager.encode(contractMessageName, contractValue).message;
1053
+ const rawData = {
1054
+ ref_block_bytes: request.refBlockBytes,
1055
+ ref_block_hash: request.refBlockHash,
1056
+ expiration: request.expiration,
1057
+ timestamp: request.timestamp,
1058
+ contract: [
1059
+ {
1060
+ type: info.typeValue,
1061
+ parameter: { type_url: info.typeUrl, value: innerBytes.toString("hex") }
1062
+ }
1063
+ ]
1064
+ };
1065
+ if (info.includeFeeLimit && request.feeLimit !== void 0) {
1066
+ rawData.fee_limit = request.feeLimit;
1067
+ }
1068
+ if (request.data) {
1069
+ rawData.data = stripHexPrefix3(request.data);
1070
+ }
1071
+ return import_hwk_trezor_protobuf.protobufManager.encode("TronRawTransaction", rawData).message.toString("hex");
1072
+ }
1073
+ async function tronSignMessage(_ctx, _params) {
1074
+ throw Object.assign(
1075
+ new Error(
1076
+ "Trezor firmware does not support TRON message signing \u2014 only tronGetAddress is available"
1077
+ ),
1078
+ { code: import_hwk_adapter_core3.HardwareErrorCode.MethodNotSupported }
1079
+ );
1080
+ }
1081
+ function buildContractMessage(contract, ownerAddress) {
1082
+ if (contract.transferContract) {
1083
+ const c = contract.transferContract;
1084
+ return {
1085
+ messageName: "TronTransferContract",
1086
+ value: {
1087
+ owner_address: ownerAddress,
1088
+ to_address: normalizeTronAddress(c.toAddress, "transferContract.toAddress"),
1089
+ amount: toUintString(c.amount, "transferContract.amount")
1090
+ }
1091
+ };
1092
+ }
1093
+ if (contract.triggerSmartContract) {
1094
+ const c = contract.triggerSmartContract;
1095
+ return {
1096
+ messageName: "TronTriggerSmartContract",
1097
+ value: {
1098
+ owner_address: ownerAddress,
1099
+ contract_address: normalizeTronAddress(
1100
+ c.contractAddress,
1101
+ "triggerSmartContract.contractAddress"
1102
+ ),
1103
+ data: stripHexPrefix3(c.data)
1104
+ }
1105
+ };
1106
+ }
1107
+ if (contract.freezeBalanceV2Contract) {
1108
+ const c = contract.freezeBalanceV2Contract;
1109
+ const value = {
1110
+ owner_address: ownerAddress,
1111
+ balance: assertSafeInt(c.balance, "freezeBalanceV2Contract.balance")
1112
+ };
1113
+ if (c.resource !== void 0) value.resource = c.resource;
1114
+ return { messageName: "TronFreezeBalanceV2Contract", value };
1115
+ }
1116
+ if (contract.unfreezeBalanceV2Contract) {
1117
+ const c = contract.unfreezeBalanceV2Contract;
1118
+ const value = {
1119
+ owner_address: ownerAddress,
1120
+ balance: assertSafeInt(c.balance, "unfreezeBalanceV2Contract.balance")
1121
+ };
1122
+ if (c.resource !== void 0) value.resource = c.resource;
1123
+ return { messageName: "TronUnfreezeBalanceV2Contract", value };
1124
+ }
1125
+ if (contract.voteWitnessContract) {
1126
+ const c = contract.voteWitnessContract;
1127
+ return {
1128
+ messageName: "TronVoteWitnessContract",
1129
+ value: {
1130
+ owner_address: ownerAddress,
1131
+ votes: c.votes.map((vote, i) => ({
1132
+ address: normalizeTronAddress(vote.voteAddress, `voteWitnessContract.votes[${i}]`),
1133
+ count: assertSafeInt(vote.voteCount, `voteWitnessContract.votes[${i}].voteCount`)
1134
+ }))
1135
+ }
1136
+ };
1137
+ }
1138
+ if (contract.withdrawExpireUnfreezeContract) {
1139
+ return { messageName: "TronWithdrawUnfreeze", value: { owner_address: ownerAddress } };
1140
+ }
1141
+ throw new Error(
1142
+ "tronSignTransaction: contract must specify exactly one supported contract type (transfer / triggerSmart / freezeBalanceV2 / unfreezeBalanceV2 / voteWitness / withdrawExpireUnfreeze)"
1143
+ );
1144
+ }
1145
+ function normalizeTronAddress(address, field) {
1146
+ if (typeof address !== "string") {
1147
+ throw new Error(`tronSignTransaction: ${field} must be a string`);
1148
+ }
1149
+ const hex = stripHexPrefix3(address);
1150
+ if (!/^41[0-9a-fA-F]{40}$/.test(hex)) {
1151
+ throw new Error(
1152
+ `tronSignTransaction: ${field} must be hex 0x41-prefixed (41 + 20 bytes), got "${address}"`
1153
+ );
1154
+ }
1155
+ return hex.toLowerCase();
1156
+ }
1157
+ function stripHexPrefix3(value) {
1158
+ return value.startsWith("0x") || value.startsWith("0X") ? value.slice(2) : value;
1159
+ }
1160
+ function toUintString(value, field) {
1161
+ if (typeof value === "string") {
1162
+ if (!/^\d+$/.test(value)) {
1163
+ throw new Error(`tronSignTransaction: ${field} must be a non-negative decimal string`);
1164
+ }
1165
+ return value;
1166
+ }
1167
+ if (typeof value === "number") {
1168
+ if (!Number.isSafeInteger(value) || value < 0) {
1169
+ throw new Error(
1170
+ `tronSignTransaction: ${field}=${value} is not a safe integer \u2014 pass it as a decimal string to avoid precision loss`
1171
+ );
1172
+ }
1173
+ return String(value);
1174
+ }
1175
+ throw new Error(`tronSignTransaction: ${field} must be a string or number`);
1176
+ }
1177
+ function assertSafeInt(value, field) {
1178
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
1179
+ throw new Error(
1180
+ `tronSignTransaction: ${field}=${value} must be a non-negative safe integer (< 2^53)`
1181
+ );
1182
+ }
1183
+ return value;
1184
+ }
1185
+ function readTronGetAddressParams(params) {
1186
+ if (!params || typeof params !== "object") {
1187
+ throw new Error("tronGetAddress params must be an object");
1188
+ }
1189
+ const path = params.path;
1190
+ if (typeof path !== "string" || path.trim().length === 0) {
1191
+ throw new Error("tronGetAddress requires a non-empty path");
1192
+ }
1193
+ const showOnDevice = params.showOnDevice;
1194
+ if (showOnDevice !== void 0 && typeof showOnDevice !== "boolean") {
1195
+ throw new Error("tronGetAddress showOnDevice must be a boolean when provided");
1196
+ }
1197
+ return { path, showOnDevice };
1198
+ }
1199
+ function readTronSignTxParams(params) {
1200
+ if (!params || typeof params !== "object") {
1201
+ throw new Error("tronSignTransaction params must be an object");
1202
+ }
1203
+ const p = params;
1204
+ if (typeof p.path !== "string" || p.path.trim().length === 0) {
1205
+ throw new Error("tronSignTransaction requires a non-empty path");
1206
+ }
1207
+ if (typeof p.ownerAddress !== "string" || p.ownerAddress.length === 0) {
1208
+ throw new Error("tronSignTransaction requires ownerAddress (hex 0x41-prefixed)");
1209
+ }
1210
+ if (typeof p.refBlockBytes !== "string" || typeof p.refBlockHash !== "string") {
1211
+ throw new Error("tronSignTransaction requires refBlockBytes and refBlockHash as hex strings");
1212
+ }
1213
+ if (typeof p.expiration !== "number" || typeof p.timestamp !== "number") {
1214
+ throw new Error("tronSignTransaction requires numeric expiration and timestamp");
1215
+ }
1216
+ if (!p.contract || typeof p.contract !== "object") {
1217
+ throw new Error("tronSignTransaction requires a contract object");
1218
+ }
1219
+ return p;
1220
+ }
1221
+
1222
+ // src/index.ts
1223
+ var import_hwk_adapter_core4 = require("@onekeyfe/hwk-adapter-core");
1224
+ var import_hwk_trezor_core = require("@onekeyfe/hwk-trezor-core");
1225
+ var TrezorConnectorBase = class {
1226
+ connectionType;
1227
+ chunkSize;
1228
+ thp;
1229
+ // Single owned array — passed by reference into every TrezorThpSession via
1230
+ // `createThpOptions`. setKnownCredentials() and the auto-merge inside
1231
+ // onPairingCredentialsChanged both mutate this array in-place so the next
1232
+ // handshake sees fresh credentials without a connector rebuild.
1233
+ knownCredentials = [];
1234
+ deviceSessionFactory;
1235
+ eventHandlers = /* @__PURE__ */ new Map();
1236
+ uiRequests = new import_hwk_adapter_core4.UiRequestRegistry();
1237
+ devices = /* @__PURE__ */ new Map();
1238
+ sessions = /* @__PURE__ */ new Map();
1239
+ constructor(options = {}) {
1240
+ this.connectionType = options.connectionType ?? "usb";
1241
+ this.chunkSize = options.chunkSize ?? 64;
1242
+ this.thp = options.thp;
1243
+ if (options.thp?.knownCredentials?.length) {
1244
+ this.knownCredentials.push(...options.thp.knownCredentials);
1245
+ }
1246
+ this.deviceSessionFactory = options.deviceSessionFactory ?? ((params) => new import_hwk_trezor_core.TrezorDeviceSession({
1247
+ transport: params.transport,
1248
+ connectionType: params.connectionType,
1249
+ chunkSize: params.chunkSize,
1250
+ thp: params.thp
1251
+ }));
1252
+ }
1253
+ /**
1254
+ * Replace the in-memory THP pairing credential list. Caller (host) reads
1255
+ * persisted credentials from storage and pushes them in here before the
1256
+ * first connect; the device sees them via `ThpHandshakeInitRequest` and
1257
+ * routes through the autoconnect path instead of CodeEntry.
1258
+ *
1259
+ * Empty list = "no credentials known" = fresh pairing on next connect.
1260
+ * The internal array is reused so any in-flight TrezorThpSession picks up
1261
+ * the change too — we mutate, not replace.
1262
+ */
1263
+ setKnownCredentials(credentials) {
1264
+ this.knownCredentials.length = 0;
1265
+ if (credentials?.length) {
1266
+ this.knownCredentials.push(...credentials);
1267
+ }
1268
+ }
1269
+ /**
1270
+ * Push new credentials minted during pairing into the in-memory array.
1271
+ * Deduplicates by the device-minted `credential` blob — the host has no
1272
+ * other stable identity for a credential.
1273
+ */
1274
+ mergeKnownCredentials(incoming) {
1275
+ for (const cred of incoming) {
1276
+ const blob = cred.credential;
1277
+ if (!blob) continue;
1278
+ const exists = this.knownCredentials.some(
1279
+ (existing) => existing.credential === blob
1280
+ );
1281
+ if (!exists) this.knownCredentials.push(cred);
1282
+ }
1283
+ }
1284
+ resolveUnlistedDevice(_deviceId) {
1285
+ return void 0;
1286
+ }
1287
+ async searchDevices() {
1288
+ this.log("info", "connector.search.start");
1289
+ const devices = await this.enumerateDevices();
1290
+ this.devices.clear();
1291
+ for (const device of devices) {
1292
+ this.devices.set(device.connectId, device);
1293
+ }
1294
+ this.log("info", "connector.search.done", {
1295
+ count: devices.length,
1296
+ devices: devices.map((device) => ({
1297
+ connectId: device.connectId,
1298
+ deviceId: device.deviceId,
1299
+ name: device.name,
1300
+ model: device.model
1301
+ }))
1302
+ });
1303
+ for (const device of devices) {
1304
+ const source = device.connectionType ?? this.connectionType;
1305
+ this.log("info", `[TREZOR_VERIFY][${source}] scan.device`, {
1306
+ source,
1307
+ connectionType: source,
1308
+ connectId: device.connectId,
1309
+ deviceId: device.deviceId,
1310
+ serialNumber: device.serialNumber,
1311
+ name: device.name,
1312
+ model: device.model,
1313
+ rssi: device.rssi,
1314
+ isConnectable: device.isConnectable,
1315
+ raw: device.raw
1316
+ });
1317
+ }
1318
+ return devices;
1319
+ }
1320
+ async connect(deviceId) {
1321
+ this.log("info", "connector.connect.start", { deviceId });
1322
+ const device = await this.resolveDevice(deviceId);
1323
+ this.log("info", "connector.connect.deviceResolved", {
1324
+ connectId: device.connectId,
1325
+ deviceId: device.deviceId,
1326
+ name: device.name,
1327
+ model: device.model
1328
+ });
1329
+ let transport;
1330
+ try {
1331
+ this.log("info", "connector.connect.transport.start", { connectId: device.connectId });
1332
+ transport = await this.createByteTransport(device);
1333
+ this.log("info", "connector.connect.transport.done", { connectId: device.connectId });
1334
+ } catch (error) {
1335
+ this.log("error", "connector.connect.transport.error", {
1336
+ connectId: device.connectId,
1337
+ error: errorToLog(error)
1338
+ });
1339
+ throw error;
1340
+ }
1341
+ const deviceSession = this.deviceSessionFactory({
1342
+ transport,
1343
+ connectionType: this.connectionType,
1344
+ chunkSize: this.chunkSize,
1345
+ thp: this.createThpOptions(device)
1346
+ });
1347
+ let features;
1348
+ try {
1349
+ this.log("info", "connector.connect.sessionInitialize.start", { connectId: device.connectId });
1350
+ features = await deviceSession.initialize();
1351
+ this.log("info", "connector.connect.sessionInitialize.done", {
1352
+ connectId: device.connectId,
1353
+ featureKeys: Object.keys(features)
1354
+ });
1355
+ } catch (error) {
1356
+ this.log("error", "connector.connect.sessionInitialize.error", {
1357
+ connectId: device.connectId,
1358
+ error: errorToLog(error)
1359
+ });
1360
+ await transport.close?.().catch(() => void 0);
1361
+ throw error;
1362
+ }
1363
+ const sessionId = device.connectId;
1364
+ const session = {
1365
+ sessionId,
1366
+ device,
1367
+ transport,
1368
+ deviceSession,
1369
+ features
1370
+ };
1371
+ this.sessions.set(sessionId, session);
1372
+ session.unsubscribeDisconnect = transport.onDisconnect?.(() => {
1373
+ if (this.sessions.get(sessionId) !== session) return;
1374
+ this.sessions.delete(sessionId);
1375
+ session.unsubscribeDisconnect?.();
1376
+ this.emit("device-disconnect", { connectId: device.connectId });
1377
+ });
1378
+ const connectorSession = {
1379
+ sessionId,
1380
+ deviceInfo: {
1381
+ vendor: "trezor",
1382
+ connectId: device.connectId,
1383
+ deviceId: readString(features, "device_id") ?? device.deviceId,
1384
+ model: readString(features, "model") ?? device.model ?? "unknown",
1385
+ firmwareVersion: buildFirmwareVersion(features),
1386
+ label: readString(features, "label") ?? device.name,
1387
+ connectionType: this.connectionType,
1388
+ serialNumber: device.serialNumber,
1389
+ capabilities: device.capabilities,
1390
+ raw: {
1391
+ features,
1392
+ discoveryRaw: device.raw
1393
+ }
1394
+ }
1395
+ };
1396
+ this.emit("device-connect", { device: connectorSessionToDevice(connectorSession) });
1397
+ this.log("info", `[TREZOR_VERIFY][${this.connectionType}] connect.device`, {
1398
+ source: this.connectionType,
1399
+ connectionType: this.connectionType,
1400
+ scanConnectId: device.connectId,
1401
+ scanDeviceId: device.deviceId,
1402
+ scanSerialNumber: device.serialNumber,
1403
+ featuresDeviceId: readString(features, "device_id"),
1404
+ deviceInfo: connectorSession.deviceInfo
1405
+ });
1406
+ this.log("info", "connector.connect.done", { sessionId });
1407
+ return connectorSession;
1408
+ }
1409
+ async disconnect(sessionId) {
1410
+ const session = this.sessions.get(sessionId);
1411
+ if (!session) return;
1412
+ session.unsubscribeDisconnect?.();
1413
+ this.sessions.delete(sessionId);
1414
+ await session.transport.close?.();
1415
+ this.emit("device-disconnect", { connectId: session.device.connectId });
1416
+ }
1417
+ async call(sessionId, method, params) {
1418
+ const session = this.sessions.get(sessionId);
1419
+ if (!session) {
1420
+ throw new Error(`Trezor session not found: ${sessionId}`);
1421
+ }
1422
+ const ctx = { deviceSession: session.deviceSession };
1423
+ switch (method) {
1424
+ case "getFeatures": {
1425
+ const p = params ?? {};
1426
+ if (p.refresh) {
1427
+ await session.deviceSession.call("GetFeatures", {});
1428
+ }
1429
+ return session.deviceSession.features ?? session.features;
1430
+ }
1431
+ // --- THP application-session control (Trezor-specific, driven by the
1432
+ // adapter to align the active passphrase session before a chain call).
1433
+ // The session deals only in session ids; the adapter owns the
1434
+ // XFP↔sessionId map. For v1 devices these are no-ops that report
1435
+ // `protocol: 'v1'` so the adapter falls back to the reactive flow.
1436
+ case "__thpCreateSession": {
1437
+ if (!session.deviceSession.isThp) {
1438
+ return { protocol: "v1", thpSessionId: null };
1439
+ }
1440
+ const p = params ?? {};
1441
+ const thpSessionId = await session.deviceSession.createThpAppSession(p.deriveCardano);
1442
+ return { protocol: "thp", thpSessionId };
1443
+ }
1444
+ case "__thpSelectSession": {
1445
+ if (!session.deviceSession.isThp) {
1446
+ return { protocol: "v1", thpSessionId: null };
1447
+ }
1448
+ const p = params ?? {};
1449
+ if (!p.thpSessionId) {
1450
+ throw new Error("__thpSelectSession requires a thpSessionId");
1451
+ }
1452
+ session.deviceSession.selectThpAppSession(p.thpSessionId);
1453
+ return { protocol: "thp", thpSessionId: p.thpSessionId };
1454
+ }
1455
+ case "__thpActiveSession":
1456
+ return {
1457
+ protocol: session.deviceSession.isThp ? "thp" : "v1",
1458
+ thpSessionId: session.deviceSession.getThpAppSessionId() ?? null
1459
+ };
1460
+ case "btcGetAddress":
1461
+ return btcGetAddress(ctx, params);
1462
+ case "btcGetPublicKey":
1463
+ return btcGetPublicKey(ctx, params);
1464
+ case "btcSignMessage":
1465
+ return btcSignMessage(ctx, params);
1466
+ case "btcSignTransaction":
1467
+ return btcSignTransaction(ctx, params);
1468
+ case "btcSignPsbt":
1469
+ return btcSignPsbt(ctx, params);
1470
+ case "btcGetMasterFingerprint":
1471
+ return btcGetMasterFingerprint(ctx);
1472
+ case "evmGetAddress":
1473
+ return evmGetAddress(ctx, params);
1474
+ case "evmSignMessage":
1475
+ return evmSignMessage(ctx, params);
1476
+ case "evmSignTransaction":
1477
+ return evmSignTransaction(ctx, params);
1478
+ case "evmSignTypedData":
1479
+ return evmSignTypedData(ctx, params);
1480
+ case "solGetAddress":
1481
+ return solGetAddress(ctx, params);
1482
+ case "solSignTransaction":
1483
+ return solSignTransaction(ctx, params);
1484
+ case "solSignMessage":
1485
+ return solSignMessage(ctx, params);
1486
+ case "tronGetAddress":
1487
+ return tronGetAddress(ctx, params);
1488
+ case "tronSignTransaction":
1489
+ return tronSignTransaction(ctx, params);
1490
+ case "tronSignMessage":
1491
+ return tronSignMessage(ctx, params);
1492
+ default:
1493
+ throw Object.assign(
1494
+ new Error(`TrezorConnector: method "${method}" is not implemented`),
1495
+ { code: import_hwk_adapter_core4.HardwareErrorCode.MethodNotSupported }
1496
+ );
1497
+ }
1498
+ }
1499
+ async cancel(_sessionId) {
1500
+ }
1501
+ uiResponse(_response) {
1502
+ if (_response.type === import_hwk_adapter_core4.UI_RESPONSE.CANCEL) {
1503
+ this.uiRequests.cancel();
1504
+ return;
1505
+ }
1506
+ this.uiRequests.resolve(_response.type, _response.payload);
1507
+ }
1508
+ on(event, handler) {
1509
+ if (!this.eventHandlers.has(event)) {
1510
+ this.eventHandlers.set(event, /* @__PURE__ */ new Set());
1511
+ }
1512
+ this.eventHandlers.get(event).add(handler);
1513
+ }
1514
+ off(event, handler) {
1515
+ this.eventHandlers.get(event)?.delete(handler);
1516
+ }
1517
+ reset() {
1518
+ for (const session of this.sessions.values()) {
1519
+ void session.transport.close?.();
1520
+ }
1521
+ this.sessions.clear();
1522
+ this.devices.clear();
1523
+ this.uiRequests.reset();
1524
+ this.eventHandlers.clear();
1525
+ }
1526
+ emit(event, data) {
1527
+ for (const handler of this.eventHandlers.get(event) ?? []) {
1528
+ handler(data);
1529
+ }
1530
+ }
1531
+ async resolveDevice(deviceId) {
1532
+ if (deviceId && this.devices.has(deviceId)) {
1533
+ return this.devices.get(deviceId);
1534
+ }
1535
+ const devices = await this.searchDevices();
1536
+ const device = deviceId ? devices.find((d) => d.connectId === deviceId || d.deviceId === deviceId) : devices[0];
1537
+ if (device) {
1538
+ return device;
1539
+ }
1540
+ if (deviceId) {
1541
+ const unlistedDevice = this.resolveUnlistedDevice(deviceId);
1542
+ if (unlistedDevice) {
1543
+ this.devices.set(unlistedDevice.connectId, unlistedDevice);
1544
+ return unlistedDevice;
1545
+ }
1546
+ }
1547
+ if (!device) {
1548
+ throw new Error(deviceId ? `Trezor device not found: ${deviceId}` : "No Trezor device found");
1549
+ }
1550
+ return device;
1551
+ }
1552
+ createThpOptions(device) {
1553
+ if (this.connectionType !== "ble" && !this.thp) return this.thp;
1554
+ return {
1555
+ ...this.thp,
1556
+ // Override caller's knownCredentials (if any) with our managed array.
1557
+ // The session reads .length and individual entries at handshake-time,
1558
+ // so mutating this array between sessions is sufficient — no rebuild.
1559
+ knownCredentials: this.knownCredentials,
1560
+ onPairingRequest: async (payload) => {
1561
+ if (this.thp?.onPairingRequest) {
1562
+ return this.thp.onPairingRequest(payload);
1563
+ }
1564
+ this.emit("ui-request", {
1565
+ type: import_hwk_adapter_core4.UI_REQUEST.REQUEST_TREZOR_THP_PAIRING,
1566
+ payload: {
1567
+ connectId: device.connectId,
1568
+ availableMethods: payload.availableMethods,
1569
+ selectedMethod: payload.selectedMethod,
1570
+ nfcData: payload.nfcData
1571
+ }
1572
+ });
1573
+ return this.uiRequests.wait(import_hwk_adapter_core4.UI_REQUEST.REQUEST_TREZOR_THP_PAIRING);
1574
+ },
1575
+ onButtonRequest: async (payload) => {
1576
+ await this.thp?.onButtonRequest?.(payload);
1577
+ this.emit("ui-request", {
1578
+ type: import_hwk_adapter_core4.UI_REQUEST.REQUEST_BUTTON,
1579
+ payload: {
1580
+ connectId: device.connectId,
1581
+ ...payload
1582
+ }
1583
+ });
1584
+ },
1585
+ onPinMatrixRequest: async (payload) => {
1586
+ if (this.thp?.onPinMatrixRequest) {
1587
+ return this.thp.onPinMatrixRequest(payload);
1588
+ }
1589
+ this.emit("ui-request", {
1590
+ type: import_hwk_adapter_core4.UI_REQUEST.REQUEST_PIN,
1591
+ payload: {
1592
+ connectId: device.connectId,
1593
+ type: payload.type
1594
+ }
1595
+ });
1596
+ return this.uiRequests.wait(import_hwk_adapter_core4.UI_REQUEST.REQUEST_PIN);
1597
+ },
1598
+ onPassphraseRequest: async (payload) => {
1599
+ if (this.thp?.onPassphraseRequest) {
1600
+ return this.thp.onPassphraseRequest(payload);
1601
+ }
1602
+ const passphrasePromise = this.uiRequests.wait(import_hwk_adapter_core4.UI_REQUEST.REQUEST_PASSPHRASE);
1603
+ this.emit("ui-request", {
1604
+ type: import_hwk_adapter_core4.UI_REQUEST.REQUEST_PASSPHRASE,
1605
+ payload: {
1606
+ connectId: device.connectId,
1607
+ ...payload
1608
+ }
1609
+ });
1610
+ const res = await passphrasePromise;
1611
+ return res?.passphraseOnDevice ? { on_device: true } : { passphrase: res?.value ?? "" };
1612
+ },
1613
+ onPairingCredentialsChanged: async (payload) => {
1614
+ this.mergeKnownCredentials(payload.credentials);
1615
+ await this.thp?.onPairingCredentialsChanged?.(payload);
1616
+ this.emit("device-trezor-thp-credentials-changed", {
1617
+ connectId: device.connectId,
1618
+ deviceId: device.deviceId,
1619
+ credentials: payload.credentials
1620
+ });
1621
+ }
1622
+ };
1623
+ }
1624
+ log(level, event, data) {
1625
+ try {
1626
+ this.thp?.logger?.({ level, scope: "trezor-connector", event, data });
1627
+ } catch {
1628
+ }
1629
+ }
1630
+ };
1631
+ function connectorSessionToDevice(session) {
1632
+ return {
1633
+ connectId: session.deviceInfo.connectId,
1634
+ deviceId: session.deviceInfo.deviceId,
1635
+ name: session.deviceInfo.label ?? "Trezor",
1636
+ model: session.deviceInfo.model,
1637
+ serialNumber: session.deviceInfo.serialNumber,
1638
+ capabilities: session.deviceInfo.capabilities,
1639
+ raw: session.deviceInfo.raw
1640
+ };
1641
+ }
1642
+ function buildFirmwareVersion(features) {
1643
+ const major = readNumber(features, "major_version");
1644
+ const minor = readNumber(features, "minor_version");
1645
+ const patch = readNumber(features, "patch_version");
1646
+ if (major === void 0 || minor === void 0 || patch === void 0) {
1647
+ return "";
1648
+ }
1649
+ return `${major}.${minor}.${patch}`;
1650
+ }
1651
+ function errorToLog(error) {
1652
+ if (error instanceof Error) {
1653
+ const extra = {};
1654
+ const maybeError = error;
1655
+ if (maybeError.errorCode !== void 0) extra.errorCode = maybeError.errorCode;
1656
+ if (maybeError.reason !== void 0) extra.reason = maybeError.reason;
1657
+ if (maybeError.attErrorCode !== void 0) extra.attErrorCode = maybeError.attErrorCode;
1658
+ return {
1659
+ name: error.name,
1660
+ message: error.message,
1661
+ stack: error.stack,
1662
+ ...extra
1663
+ };
1664
+ }
1665
+ return String(error);
1666
+ }
1667
+ // Annotate the CommonJS export names for ESM import in node:
1668
+ 0 && (module.exports = {
1669
+ TrezorConnectorBase
1670
+ });
1671
+ //# sourceMappingURL=index.js.map