@swapkit/wallet-hardware 4.9.13 → 4.9.15
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/src/trezor/index.ts
CHANGED
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
type UTXOToolboxes,
|
|
23
23
|
type UTXOType,
|
|
24
24
|
} from "@swapkit/toolboxes/utxo";
|
|
25
|
-
import type { BTCNetwork, PCZT, Transaction, ZcashTransaction } from "@swapkit/utxo-signer";
|
|
25
|
+
import type { BTCNetwork, PCZT, Transaction, ZcashPSBT, ZcashTransaction } from "@swapkit/utxo-signer";
|
|
26
26
|
import { BCHSigHash, NETWORKS, ZcashConsensusBranchId, ZcashVersionGroupId } from "@swapkit/utxo-signer";
|
|
27
27
|
import { createWallet, getWalletSupportedChains, type HardwareExtendedPublicKeyInfo } from "@swapkit/wallet-core";
|
|
28
28
|
|
|
@@ -30,6 +30,8 @@ type TrezorBip32Derivation = [Uint8Array, { fingerprint: number; path: number[]
|
|
|
30
30
|
type TrezorCoreMode = "auto" | "iframe" | "popup" | "suite-desktop" | "suite-web";
|
|
31
31
|
type TrezorTransport = "BridgeTransport" | "WebUsbTransport" | "NodeUsbTransport";
|
|
32
32
|
type ConnectTrezorOptions = { address?: string };
|
|
33
|
+
type TrezorAccountRefTransaction = { details: Record<string, never>; hex: string; txid: string };
|
|
34
|
+
type ZcashSignableTransaction = PCZT | ZcashPSBT | ZcashTransaction;
|
|
33
35
|
type TrezorExtendedPublicKeyInfo = {
|
|
34
36
|
accountIndex: number;
|
|
35
37
|
chainCode?: string;
|
|
@@ -274,7 +276,7 @@ function buildPCZTInputsForTrezor(
|
|
|
274
276
|
inputs.push({
|
|
275
277
|
address_n,
|
|
276
278
|
amount: input.value.toString(),
|
|
277
|
-
prev_hash: hexEncode.encode(
|
|
279
|
+
prev_hash: hexEncode.encode(input.txid),
|
|
278
280
|
prev_index: input.index,
|
|
279
281
|
script_type: "SPENDADDRESS" as const,
|
|
280
282
|
});
|
|
@@ -363,8 +365,8 @@ function buildZcashTxInputsForTrezor(
|
|
|
363
365
|
const utxoInfo = utxoInputs[i];
|
|
364
366
|
inputs.push({
|
|
365
367
|
address_n,
|
|
366
|
-
amount: utxoInfo?.value?.toString() || "0",
|
|
367
|
-
prev_hash: input.txid ? hexEncode.encode(
|
|
368
|
+
amount: utxoInfo?.value?.toString() || input.value?.toString() || "0",
|
|
369
|
+
prev_hash: input.txid ? hexEncode.encode(input.txid) : "",
|
|
368
370
|
prev_index: input.index ?? 0,
|
|
369
371
|
script_type: "SPENDADDRESS" as const,
|
|
370
372
|
});
|
|
@@ -465,6 +467,25 @@ function shouldUseTrezorSerializedSigner(chain: Chain) {
|
|
|
465
467
|
return chain === Chain.BitcoinCash || chain === Chain.Dash || chain === Chain.Dogecoin;
|
|
466
468
|
}
|
|
467
469
|
|
|
470
|
+
function buildTrezorRefTxs(chain: Chain, inputs: UTXOType[]): TrezorAccountRefTransaction[] | undefined {
|
|
471
|
+
if (chain !== Chain.Dash) return undefined;
|
|
472
|
+
|
|
473
|
+
const refs = new Map<string, TrezorAccountRefTransaction>();
|
|
474
|
+
|
|
475
|
+
for (const input of inputs) {
|
|
476
|
+
if (!input.txHex) {
|
|
477
|
+
throw new SwapKitError({
|
|
478
|
+
errorKey: "wallet_trezor_failed_to_sign_transaction",
|
|
479
|
+
info: { chain, error: `Missing previous transaction hex for ${input.hash}:${input.index}` },
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
refs.set(input.hash, { details: {}, hex: input.txHex, txid: input.hash });
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
return [...refs.values()];
|
|
487
|
+
}
|
|
488
|
+
|
|
468
489
|
async function getTrezorWallet<T extends Chain>({
|
|
469
490
|
address: providedAddress,
|
|
470
491
|
chain,
|
|
@@ -517,158 +538,115 @@ async function getTrezorWallet<T extends Chain>({
|
|
|
517
538
|
return payload.address;
|
|
518
539
|
};
|
|
519
540
|
|
|
520
|
-
const address = await getAddress();
|
|
521
|
-
|
|
522
|
-
const signer = {
|
|
523
|
-
getAddress: async () => address,
|
|
524
|
-
|
|
525
|
-
signPCZT: async (pczt: PCZT): Promise<PCZT> => {
|
|
526
|
-
const TrezorConnect = (await import("@trezor/connect-web")).default;
|
|
527
|
-
const { hex: hexEncode } = await import("@scure/base");
|
|
528
|
-
const address_n = hardenDerivationPath(derivationPath);
|
|
529
|
-
const global = pczt.getGlobal();
|
|
530
|
-
|
|
531
|
-
const inputs = buildPCZTInputsForTrezor(pczt, address_n, hexEncode);
|
|
532
|
-
const outputs = await buildPCZTOutputsForTrezor(pczt, address_n, address, chain);
|
|
533
|
-
|
|
534
|
-
const result = await TrezorConnect.signTransaction({
|
|
535
|
-
branchId: global.consensusBranchId,
|
|
536
|
-
coin: "zcash",
|
|
537
|
-
expiry: global.expiryHeight,
|
|
538
|
-
inputs,
|
|
539
|
-
locktime: global.lockTime,
|
|
540
|
-
outputs: outputs as any,
|
|
541
|
-
overwintered: true,
|
|
542
|
-
version: global.txVersion,
|
|
543
|
-
versionGroupId: global.versionGroupId,
|
|
544
|
-
});
|
|
545
|
-
|
|
546
|
-
if (!result.success) {
|
|
547
|
-
throw new SwapKitError({
|
|
548
|
-
errorKey: "wallet_trezor_failed_to_sign_transaction",
|
|
549
|
-
info: { chain, error: (result.payload as { error: string; code?: string }).error },
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
return extractSignaturesFromSignedTx(result.payload.serializedTx, pczt);
|
|
554
|
-
},
|
|
541
|
+
const address = providedAddress ?? (await getAddress());
|
|
555
542
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
const inputs = buildZcashTxInputsForTrezor(tx, utxoInputs, address_n, hexEncode);
|
|
562
|
-
const outputs = buildZcashTxOutputsForTrezor(tx, address_n, address, chain);
|
|
563
|
-
|
|
564
|
-
const result = await TrezorConnect.signTransaction({
|
|
565
|
-
branchId: ZcashConsensusBranchId.NU6,
|
|
566
|
-
coin: "zcash",
|
|
567
|
-
expiry: 0,
|
|
568
|
-
inputs,
|
|
569
|
-
locktime: 0,
|
|
570
|
-
outputs: outputs as any,
|
|
571
|
-
overwintered: true,
|
|
572
|
-
version: 4,
|
|
573
|
-
versionGroupId: ZcashVersionGroupId.SAPLING,
|
|
574
|
-
});
|
|
543
|
+
const signPCZTWithSerializedTx = async (pczt: PCZT) => {
|
|
544
|
+
const TrezorConnect = (await import("@trezor/connect-web")).default;
|
|
545
|
+
const { hex: hexEncode } = await import("@scure/base");
|
|
546
|
+
const address_n = hardenDerivationPath(derivationPath);
|
|
547
|
+
const global = pczt.getGlobal();
|
|
575
548
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
549
|
+
const inputs = buildPCZTInputsForTrezor(pczt, address_n, hexEncode);
|
|
550
|
+
const outputs = await buildPCZTOutputsForTrezor(pczt, address_n, address, chain);
|
|
551
|
+
const result = await TrezorConnect.signTransaction({
|
|
552
|
+
branchId: global.consensusBranchId,
|
|
553
|
+
coin: "zcash",
|
|
554
|
+
expiry: global.expiryHeight,
|
|
555
|
+
inputs,
|
|
556
|
+
locktime: global.lockTime,
|
|
557
|
+
outputs: outputs as any,
|
|
558
|
+
overwintered: true,
|
|
559
|
+
version: global.txVersion,
|
|
560
|
+
versionGroupId: global.versionGroupId,
|
|
561
|
+
});
|
|
579
562
|
|
|
563
|
+
if (!result.success) {
|
|
580
564
|
throw new SwapKitError({
|
|
581
565
|
errorKey: "wallet_trezor_failed_to_sign_transaction",
|
|
582
566
|
info: { chain, error: (result.payload as { error: string; code?: string }).error },
|
|
583
567
|
});
|
|
584
|
-
}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
return {
|
|
571
|
+
serializedTx: result.payload.serializedTx,
|
|
572
|
+
signedPczt: await extractSignaturesFromSignedTx(result.payload.serializedTx, pczt),
|
|
573
|
+
};
|
|
585
574
|
};
|
|
586
575
|
|
|
587
|
-
const
|
|
576
|
+
const parseSignedZcashTransaction = async (signedTxHex: string) => {
|
|
577
|
+
const { ZcashTransaction: ZcashTx } = await import("@swapkit/utxo-signer");
|
|
578
|
+
return ZcashTx.fromHex(signedTxHex, { allowUnknownOutputs: true });
|
|
579
|
+
};
|
|
588
580
|
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
info: { address, recipient: params.recipient, wallet: WalletOption.TREZOR },
|
|
594
|
-
});
|
|
595
|
-
}
|
|
581
|
+
const signZcashTransaction = async (tx: ZcashTransaction) => {
|
|
582
|
+
const TrezorConnect = (await import("@trezor/connect-web")).default;
|
|
583
|
+
const { hex: hexEncode } = await import("@scure/base");
|
|
584
|
+
const address_n = hardenDerivationPath(derivationPath);
|
|
596
585
|
|
|
597
|
-
const
|
|
586
|
+
const inputs = buildZcashTxInputsForTrezor(tx, [], address_n, hexEncode);
|
|
587
|
+
const outputs = buildZcashTxOutputsForTrezor(tx, address_n, address, chain);
|
|
598
588
|
|
|
599
|
-
const
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
589
|
+
const result = await TrezorConnect.signTransaction({
|
|
590
|
+
branchId: ZcashConsensusBranchId.NU6,
|
|
591
|
+
coin: "zcash",
|
|
592
|
+
expiry: 0,
|
|
593
|
+
inputs,
|
|
594
|
+
locktime: 0,
|
|
595
|
+
outputs: outputs as any,
|
|
596
|
+
overwintered: true,
|
|
597
|
+
version: 4,
|
|
598
|
+
versionGroupId: ZcashVersionGroupId.SAPLING,
|
|
604
599
|
});
|
|
605
600
|
|
|
606
|
-
|
|
607
|
-
|
|
601
|
+
if (result.success) {
|
|
602
|
+
return parseSignedZcashTransaction(result.payload.serializedTx);
|
|
603
|
+
}
|
|
608
604
|
|
|
609
|
-
|
|
605
|
+
throw new SwapKitError({
|
|
606
|
+
errorKey: "wallet_trezor_failed_to_sign_transaction",
|
|
607
|
+
info: { chain, error: (result.payload as { error: string; code?: string }).error },
|
|
608
|
+
});
|
|
610
609
|
};
|
|
611
610
|
|
|
612
|
-
const
|
|
613
|
-
|
|
614
|
-
throw new SwapKitError({
|
|
615
|
-
errorKey: "wallet_missing_params",
|
|
616
|
-
info: { address, recipient: params.recipient, wallet: WalletOption.TREZOR },
|
|
617
|
-
});
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
const { createPCZT, OutScript } = await import("@swapkit/utxo-signer");
|
|
621
|
-
const { hex: hexEncode } = await import("@scure/base");
|
|
622
|
-
const { getUtxoApi } = await import("@swapkit/toolboxes/utxo");
|
|
611
|
+
const signer = {
|
|
612
|
+
getAddress: async () => address,
|
|
623
613
|
|
|
624
|
-
|
|
614
|
+
signPCZT: async (pczt: PCZT): Promise<PCZT> => {
|
|
615
|
+
return (await signPCZTWithSerializedTx(pczt)).signedPczt;
|
|
616
|
+
},
|
|
625
617
|
|
|
626
|
-
|
|
618
|
+
signTransaction: async (tx: ZcashSignableTransaction): Promise<ZcashTransaction> => {
|
|
619
|
+
if ("toPCZT" in tx) {
|
|
620
|
+
const { serializedTx } = await signPCZTWithSerializedTx(tx.toPCZT());
|
|
621
|
+
return parseSignedZcashTransaction(serializedTx);
|
|
622
|
+
}
|
|
627
623
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
sender: address,
|
|
633
|
-
});
|
|
624
|
+
if ("getGlobal" in tx) {
|
|
625
|
+
const { serializedTx } = await signPCZTWithSerializedTx(tx);
|
|
626
|
+
return parseSignedZcashTransaction(serializedTx);
|
|
627
|
+
}
|
|
634
628
|
|
|
635
|
-
|
|
629
|
+
return signZcashTransaction(tx);
|
|
630
|
+
},
|
|
631
|
+
};
|
|
636
632
|
|
|
637
|
-
|
|
638
|
-
const utxo = utxos.find((u) => u.hash === utxoInput.hash && u.index === utxoInput.index);
|
|
639
|
-
const scriptPubkey = utxo?.witnessUtxo?.script
|
|
640
|
-
? new Uint8Array(utxo.witnessUtxo.script)
|
|
641
|
-
: OutScript.encode({ hash: hexEncode.decode((utxoInput as any).address || ""), type: "pkh" });
|
|
633
|
+
const toolbox = getUtxoToolbox(Chain.Zcash, { signer });
|
|
642
634
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
value: BigInt(utxoInput.value),
|
|
648
|
-
});
|
|
635
|
+
const signAndBroadcastTransaction = async (tx: ZcashSignableTransaction) => {
|
|
636
|
+
if ("toPCZT" in tx) {
|
|
637
|
+
const { serializedTx } = await signPCZTWithSerializedTx(tx.toPCZT());
|
|
638
|
+
return toolbox.broadcastTx(serializedTx);
|
|
649
639
|
}
|
|
650
640
|
|
|
651
|
-
|
|
652
|
-
const
|
|
653
|
-
|
|
641
|
+
if ("getGlobal" in tx) {
|
|
642
|
+
const { serializedTx } = await signPCZTWithSerializedTx(tx);
|
|
643
|
+
return toolbox.broadcastTx(serializedTx);
|
|
654
644
|
}
|
|
655
645
|
|
|
656
|
-
|
|
657
|
-
signedPczt.finalizeAllInputs();
|
|
658
|
-
const finalTx = signedPczt.extract();
|
|
659
|
-
const broadcastResult = await toolbox.broadcastTx(finalTx.toHex());
|
|
660
|
-
|
|
661
|
-
return broadcastResult;
|
|
646
|
+
return toolbox.signAndBroadcastTransaction(tx);
|
|
662
647
|
};
|
|
663
648
|
|
|
664
|
-
return {
|
|
665
|
-
...toolbox,
|
|
666
|
-
address,
|
|
667
|
-
signPCZT: signer.signPCZT,
|
|
668
|
-
signTransaction: signer.signTransaction,
|
|
669
|
-
transfer,
|
|
670
|
-
transferWithPCZT,
|
|
671
|
-
};
|
|
649
|
+
return { ...toolbox, address, signAndBroadcastTransaction, signPCZT: signer.signPCZT };
|
|
672
650
|
}
|
|
673
651
|
|
|
674
652
|
case Chain.Bitcoin:
|
|
@@ -739,7 +717,12 @@ async function getTrezorWallet<T extends Chain>({
|
|
|
739
717
|
script_type: resolvedScriptType.input,
|
|
740
718
|
}));
|
|
741
719
|
|
|
742
|
-
const result = await TrezorConnect.signTransaction({
|
|
720
|
+
const result = await TrezorConnect.signTransaction({
|
|
721
|
+
coin,
|
|
722
|
+
inputs: trezorInputs,
|
|
723
|
+
outputs,
|
|
724
|
+
refTxs: buildTrezorRefTxs(chain, inputs) as never,
|
|
725
|
+
});
|
|
743
726
|
|
|
744
727
|
if (result.success) {
|
|
745
728
|
return result.payload.serializedTx;
|
|
@@ -910,7 +893,14 @@ async function getTrezorWallet<T extends Chain>({
|
|
|
910
893
|
|
|
911
894
|
const signTransactionWithMultipleInputs = async (
|
|
912
895
|
tx: Transaction,
|
|
913
|
-
inputs: Array<{
|
|
896
|
+
inputs: Array<{
|
|
897
|
+
derivationIndex: number;
|
|
898
|
+
hash: string;
|
|
899
|
+
index: number;
|
|
900
|
+
isChange: boolean;
|
|
901
|
+
txHex?: string;
|
|
902
|
+
value: number;
|
|
903
|
+
}>,
|
|
914
904
|
memo = "",
|
|
915
905
|
) => {
|
|
916
906
|
const TrezorConnect = (await import("@trezor/connect-web")).default;
|
|
@@ -941,7 +931,12 @@ async function getTrezorWallet<T extends Chain>({
|
|
|
941
931
|
};
|
|
942
932
|
});
|
|
943
933
|
|
|
944
|
-
const result = await TrezorConnect.signTransaction({
|
|
934
|
+
const result = await TrezorConnect.signTransaction({
|
|
935
|
+
coin,
|
|
936
|
+
inputs: trezorInputs,
|
|
937
|
+
outputs,
|
|
938
|
+
refTxs: buildTrezorRefTxs(chain, inputs) as never,
|
|
939
|
+
});
|
|
945
940
|
|
|
946
941
|
if (result.success) {
|
|
947
942
|
return result.payload.serializedTx;
|
|
@@ -982,7 +977,7 @@ async function getTrezorWallet<T extends Chain>({
|
|
|
982
977
|
const { tx, inputs: selectedInputs } = await toolbox.createTransaction({
|
|
983
978
|
assetValue: assetValue as any,
|
|
984
979
|
feeRate: txFeeRate,
|
|
985
|
-
fetchTxHex:
|
|
980
|
+
fetchTxHex: chain === Chain.Dash,
|
|
986
981
|
memo,
|
|
987
982
|
recipient,
|
|
988
983
|
sender: address,
|
|
@@ -990,7 +985,12 @@ async function getTrezorWallet<T extends Chain>({
|
|
|
990
985
|
|
|
991
986
|
const inputsWithDerivation = selectedInputs.map((input: { hash: string; index: number; value: number }) => {
|
|
992
987
|
const utxoInfo = utxos.find((u) => u.hash === input.hash && u.index === input.index);
|
|
993
|
-
return {
|
|
988
|
+
return {
|
|
989
|
+
...input,
|
|
990
|
+
derivationIndex: utxoInfo?.derivationIndex ?? 0,
|
|
991
|
+
isChange: utxoInfo?.isChange ?? false,
|
|
992
|
+
txHex: utxoInfo?.txHex,
|
|
993
|
+
};
|
|
994
994
|
});
|
|
995
995
|
|
|
996
996
|
const signedTxHex = await signTransactionWithMultipleInputs(tx as Transaction, inputsWithDerivation, memo);
|
|
@@ -1020,7 +1020,7 @@ async function getTrezorWallet<T extends Chain>({
|
|
|
1020
1020
|
const { tx, inputs } = await createTxMethod({
|
|
1021
1021
|
...rest,
|
|
1022
1022
|
feeRate,
|
|
1023
|
-
fetchTxHex:
|
|
1023
|
+
fetchTxHex: chain === Chain.Dash,
|
|
1024
1024
|
memo,
|
|
1025
1025
|
recipient,
|
|
1026
1026
|
sender: address,
|
|
@@ -1041,6 +1041,8 @@ async function getTrezorWallet<T extends Chain>({
|
|
|
1041
1041
|
const signAndBroadcastTransaction = shouldUseTrezorSerializedSigner(chain)
|
|
1042
1042
|
? async (tx: Transaction) => baseToolbox.broadcastTx(await signSerializedTransaction(tx))
|
|
1043
1043
|
: toolbox.signAndBroadcastTransaction;
|
|
1044
|
+
const walletSignTransaction = shouldUseTrezorPsbtSigner(chain) ? toolbox.signTransaction : signTransaction;
|
|
1045
|
+
const walletTransfer = shouldUseTrezorPsbtSigner(chain) ? toolbox.transfer : transfer;
|
|
1044
1046
|
|
|
1045
1047
|
async function getExtendedPublicKeyInfo({ accountIndex }: { accountIndex?: number } = {}) {
|
|
1046
1048
|
const TrezorConnect = (await import("@trezor/connect-web")).default;
|
|
@@ -1200,9 +1202,9 @@ async function getTrezorWallet<T extends Chain>({
|
|
|
1200
1202
|
getExtendedPublicKey,
|
|
1201
1203
|
getExtendedPublicKeyInfo,
|
|
1202
1204
|
signAndBroadcastTransaction,
|
|
1203
|
-
signTransaction,
|
|
1205
|
+
signTransaction: walletSignTransaction,
|
|
1204
1206
|
signTransactionWithMultipleInputs,
|
|
1205
|
-
transfer,
|
|
1207
|
+
transfer: walletTransfer,
|
|
1206
1208
|
transferFromMultipleAddresses,
|
|
1207
1209
|
};
|
|
1208
1210
|
}
|
|
@@ -1217,14 +1219,14 @@ export async function getTrezorExtendedPublicKey(
|
|
|
1217
1219
|
derivationPath?: DerivationPathArray,
|
|
1218
1220
|
{ accountIndex }: { accountIndex?: number } = {},
|
|
1219
1221
|
): Promise<HardwareExtendedPublicKeyInfo | undefined> {
|
|
1220
|
-
if (![Chain.BitcoinCash, Chain.Bitcoin, Chain.Dash, Chain.Dogecoin, Chain.Litecoin].includes(chain)) {
|
|
1222
|
+
if (![Chain.BitcoinCash, Chain.Bitcoin, Chain.Dash, Chain.Dogecoin, Chain.Litecoin, Chain.Zcash].includes(chain)) {
|
|
1221
1223
|
throw new SwapKitError({ errorKey: "wallet_chain_not_supported", info: { chain, wallet: WalletOption.TREZOR } });
|
|
1222
1224
|
}
|
|
1223
1225
|
|
|
1224
1226
|
const { TrezorConnect } = await initTrezorConnect();
|
|
1225
1227
|
const utxoChain = chain as UTXOChain;
|
|
1226
1228
|
const resolvedDerivationPath = derivationPath ?? (NetworkDerivationPath[chain] as DerivationPathArray);
|
|
1227
|
-
const coin = chain.toLowerCase();
|
|
1229
|
+
const coin = chain === Chain.Zcash ? "zcash" : chain.toLowerCase();
|
|
1228
1230
|
|
|
1229
1231
|
const resolvedAccountPath = getUTXOAccountPath({
|
|
1230
1232
|
accountIndex,
|
|
@@ -1346,7 +1348,7 @@ export const trezorWallet = createWallet({
|
|
|
1346
1348
|
[Chain.Optimism]: true,
|
|
1347
1349
|
[Chain.Polygon]: true,
|
|
1348
1350
|
[Chain.XLayer]: true,
|
|
1349
|
-
|
|
1351
|
+
[Chain.Zcash]: true,
|
|
1350
1352
|
},
|
|
1351
1353
|
getExtendedPublicKey: getTrezorExtendedPublicKey,
|
|
1352
1354
|
name: "connectTrezor",
|