@swapkit/wallet-hardware 6.1.1 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/THIRD_PARTY_LICENSES.md +4 -4
- package/dist/{chunk-jzrytcrf.js → chunk-0k1b2ddn.js} +3 -3
- package/dist/{chunk-jzrytcrf.js.map → chunk-0k1b2ddn.js.map} +2 -2
- package/dist/{chunk-jewm2ag3.js → chunk-2tzsz8f3.js} +4 -4
- package/dist/{chunk-jewm2ag3.js.map → chunk-2tzsz8f3.js.map} +1 -1
- package/dist/{chunk-yrxe491r.js → chunk-410fpx61.js} +4 -4
- package/dist/{chunk-yrxe491r.js.map → chunk-410fpx61.js.map} +1 -1
- package/dist/chunk-8mkdjmw2.js +4 -0
- package/dist/chunk-8mkdjmw2.js.map +10 -0
- package/dist/{chunk-xmvg4cds.js → chunk-96p7njae.js} +3 -3
- package/dist/{chunk-xmvg4cds.js.map → chunk-96p7njae.js.map} +2 -2
- package/dist/chunk-97nsp4z6.js +5 -0
- package/dist/chunk-97nsp4z6.js.map +10 -0
- package/dist/{chunk-nhva847d.js → chunk-9a9gn4pb.js} +3 -3
- package/dist/{chunk-5p3ttw6y.js.map → chunk-9a9gn4pb.js.map} +1 -1
- package/dist/chunk-a39rm9nv.js +4 -0
- package/dist/{chunk-gr3eswf1.js.map → chunk-a39rm9nv.js.map} +5 -5
- package/dist/chunk-c8mwf9cn.js +4 -0
- package/dist/{chunk-k3thje6a.js.map → chunk-c8mwf9cn.js.map} +1 -1
- package/dist/{chunk-ds2m83jp.js → chunk-dhhmywmb.js} +4 -4
- package/dist/{chunk-ds2m83jp.js.map → chunk-dhhmywmb.js.map} +1 -1
- package/dist/{chunk-eenx3cv6.js → chunk-dsa641rq.js} +3 -3
- package/dist/{chunk-eenx3cv6.js.map → chunk-dsa641rq.js.map} +2 -2
- package/dist/{chunk-0arpsm5f.js → chunk-grj9nvte.js} +3 -3
- package/dist/{chunk-0arpsm5f.js.map → chunk-grj9nvte.js.map} +1 -1
- package/dist/{chunk-hg71hp4m.js → chunk-napm4102.js} +3 -3
- package/dist/{chunk-hg71hp4m.js.map → chunk-napm4102.js.map} +1 -1
- package/dist/{chunk-k3thje6a.js → chunk-nb08g045.js} +3 -3
- package/dist/{chunk-nhva847d.js.map → chunk-nb08g045.js.map} +1 -1
- package/dist/chunk-npe2r2ge.js +4 -0
- package/dist/{chunk-xx7cwpzq.js.map → chunk-npe2r2ge.js.map} +1 -1
- package/dist/chunk-p9mwkgye.js +4 -0
- package/dist/{chunk-09e51wma.js.map → chunk-p9mwkgye.js.map} +14 -12
- package/dist/{chunk-wfbg89d3.js → chunk-qjp8j8e5.js} +3 -3
- package/dist/{chunk-wfbg89d3.js.map → chunk-qjp8j8e5.js.map} +1 -1
- package/dist/{chunk-xn0fnag5.js → chunk-r1fk1sx9.js} +3 -3
- package/dist/{chunk-xn0fnag5.js.map → chunk-r1fk1sx9.js.map} +1 -1
- package/dist/{chunk-1amf58aq.js → chunk-ta7bqmy3.js} +3 -3
- package/dist/{chunk-1amf58aq.js.map → chunk-ta7bqmy3.js.map} +1 -1
- package/dist/{chunk-3t17wpjg.js → chunk-tgvgr630.js} +3 -3
- package/dist/{chunk-3t17wpjg.js.map → chunk-tgvgr630.js.map} +2 -2
- package/dist/chunk-v8x9ptxs.js +4 -0
- package/dist/chunk-v8x9ptxs.js.map +10 -0
- package/dist/{chunk-dptbnkzm.js → chunk-wm89desc.js} +20 -20
- package/dist/{chunk-dptbnkzm.js.map → chunk-wm89desc.js.map} +12 -10
- package/dist/{chunk-5c7b7z2d.js → chunk-wtyhjt5e.js} +3 -3
- package/dist/{chunk-5c7b7z2d.js.map → chunk-wtyhjt5e.js.map} +1 -1
- package/dist/{chunk-tm47brht.js → chunk-xskdbz15.js} +3 -3
- package/dist/{chunk-tm47brht.js.map → chunk-xskdbz15.js.map} +2 -2
- package/dist/{chunk-8m2sn76p.js → chunk-ytjqb1sd.js} +3 -3
- package/dist/{chunk-8m2sn76p.js.map → chunk-ytjqb1sd.js.map} +1 -1
- package/dist/{chunk-3h1f3hyp.js → chunk-zbesf7sy.js} +3 -3
- package/dist/{chunk-3h1f3hyp.js.map → chunk-zbesf7sy.js.map} +1 -1
- package/dist/keepkey/index.cjs +2 -2
- package/dist/keepkey/index.cjs.map +3 -3
- package/dist/keepkey/index.js +2 -2
- package/dist/keepkey/index.js.map +3 -3
- package/dist/ledger/index.cjs +30 -30
- package/dist/ledger/index.cjs.map +35 -27
- package/dist/ledger/index.js +2 -2
- package/dist/ledger/index.js.map +11 -8
- package/dist/trezor/index.cjs +2 -2
- package/dist/trezor/index.cjs.map +7 -5
- package/dist/trezor/index.js +2 -2
- package/dist/trezor/index.js.map +3 -3
- package/dist/types/helpers/cardano.d.ts +35 -0
- package/dist/types/helpers/cardano.d.ts.map +1 -0
- package/dist/types/keepkey/index.d.ts +1 -0
- package/dist/types/keepkey/index.d.ts.map +1 -1
- package/dist/types/ledger/clients/cardano.d.ts +24 -0
- package/dist/types/ledger/clients/cardano.d.ts.map +1 -0
- package/dist/types/ledger/clients/evm.d.ts +1 -0
- package/dist/types/ledger/clients/evm.d.ts.map +1 -1
- package/dist/types/ledger/clients/stellar.d.ts +13 -0
- package/dist/types/ledger/clients/stellar.d.ts.map +1 -0
- package/dist/types/ledger/clients/ton.d.ts +13 -0
- package/dist/types/ledger/clients/ton.d.ts.map +1 -0
- package/dist/types/ledger/clients/zcash.d.ts.map +1 -1
- package/dist/types/ledger/helpers/getLedgerAddress.d.ts.map +1 -1
- package/dist/types/ledger/helpers/getLedgerClient.d.ts +8 -1
- package/dist/types/ledger/helpers/getLedgerClient.d.ts.map +1 -1
- package/dist/types/ledger/index.d.ts +3 -2
- package/dist/types/ledger/index.d.ts.map +1 -1
- package/dist/types/ledger/types.d.ts +2 -2
- package/dist/types/ledger/types.d.ts.map +1 -1
- package/dist/types/trezor/cardanoSigner.d.ts.map +1 -1
- package/dist/types/trezor/hypercoreSigner.d.ts +22 -0
- package/dist/types/trezor/hypercoreSigner.d.ts.map +1 -0
- package/dist/types/trezor/index.d.ts +3 -2
- package/dist/types/trezor/index.d.ts.map +1 -1
- package/dist/types/trezor/stellarSigner.d.ts +1 -1
- package/package.json +25 -13
- package/src/helpers/cardano.ts +112 -0
- package/src/keepkey/index.ts +14 -14
- package/src/ledger/clients/cardano.ts +204 -0
- package/src/ledger/clients/evm.ts +4 -0
- package/src/ledger/clients/stellar.ts +83 -0
- package/src/ledger/clients/ton.ts +282 -0
- package/src/ledger/clients/zcash.ts +16 -6
- package/src/ledger/helpers/getLedgerAddress.ts +16 -0
- package/src/ledger/helpers/getLedgerClient.ts +13 -0
- package/src/ledger/index.ts +102 -30
- package/src/ledger/types.ts +2 -0
- package/src/trezor/cardanoSigner.ts +24 -80
- package/src/trezor/hypercoreSigner.ts +96 -0
- package/src/trezor/index.ts +153 -75
- package/dist/chunk-09e51wma.js +0 -4
- package/dist/chunk-5p3ttw6y.js +0 -4
- package/dist/chunk-gr3eswf1.js +0 -4
- package/dist/chunk-qjq7gvyx.js +0 -4
- package/dist/chunk-qjq7gvyx.js.map +0 -10
- package/dist/chunk-xx7cwpzq.js +0 -4
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Chain, SwapKitError, WalletOption } from "@swapkit/helpers";
|
|
2
2
|
|
|
3
|
+
import type { CardanoLedger } from "../clients/cardano";
|
|
3
4
|
import type { getNearLedgerClient } from "../clients/near";
|
|
5
|
+
import type { StellarLedger } from "../clients/stellar";
|
|
4
6
|
import type { SuiLedger } from "../clients/sui";
|
|
7
|
+
import type { TONLedger } from "../clients/ton";
|
|
5
8
|
import type { TronLedger } from "../clients/tron";
|
|
6
9
|
import type { XRPLedger } from "../clients/xrp";
|
|
7
10
|
import type { LEDGER_SUPPORTED_CHAINS } from "../index";
|
|
@@ -38,6 +41,7 @@ export const getLedgerAddress = async <
|
|
|
38
41
|
case Chain.Aurora:
|
|
39
42
|
case Chain.Gnosis:
|
|
40
43
|
case Chain.Monad:
|
|
44
|
+
case Chain.Robinhood:
|
|
41
45
|
case Chain.XLayer: {
|
|
42
46
|
return (ledgerClient as EVMLedgerClients).getAddress();
|
|
43
47
|
}
|
|
@@ -63,6 +67,14 @@ export const getLedgerAddress = async <
|
|
|
63
67
|
return (ledgerClient as Awaited<ReturnType<typeof XRPLedger>>).getAddress();
|
|
64
68
|
}
|
|
65
69
|
|
|
70
|
+
case Chain.Stellar: {
|
|
71
|
+
return (ledgerClient as Awaited<ReturnType<typeof StellarLedger>>).getAddress();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
case Chain.Cardano: {
|
|
75
|
+
return (ledgerClient as Awaited<ReturnType<typeof CardanoLedger>>).getAddress();
|
|
76
|
+
}
|
|
77
|
+
|
|
66
78
|
case Chain.Tron: {
|
|
67
79
|
return (ledgerClient as Awaited<ReturnType<typeof TronLedger>>).getAddress();
|
|
68
80
|
}
|
|
@@ -71,6 +83,10 @@ export const getLedgerAddress = async <
|
|
|
71
83
|
return (ledgerClient as Awaited<ReturnType<typeof SuiLedger>>).connect();
|
|
72
84
|
}
|
|
73
85
|
|
|
86
|
+
case Chain.Ton: {
|
|
87
|
+
return (ledgerClient as Awaited<ReturnType<typeof TONLedger>>).getAddress();
|
|
88
|
+
}
|
|
89
|
+
|
|
74
90
|
default:
|
|
75
91
|
throw new SwapKitError("wallet_chain_not_supported", { chain, wallet: WalletOption.LEDGER });
|
|
76
92
|
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
WalletOption,
|
|
10
10
|
} from "@swapkit/helpers";
|
|
11
11
|
import { BitcoinLedger } from "../clients/bitcoin";
|
|
12
|
+
import { CardanoLedger } from "../clients/cardano";
|
|
12
13
|
import { CosmosLedger } from "../clients/cosmos";
|
|
13
14
|
import {
|
|
14
15
|
ArbitrumLedger,
|
|
@@ -23,11 +24,14 @@ import {
|
|
|
23
24
|
MonadLedger,
|
|
24
25
|
OptimismLedger,
|
|
25
26
|
PolygonLedger,
|
|
27
|
+
RobinhoodLedger,
|
|
26
28
|
XLayerLedger,
|
|
27
29
|
} from "../clients/evm";
|
|
28
30
|
import { getNearLedgerClient } from "../clients/near";
|
|
31
|
+
import { StellarLedger } from "../clients/stellar";
|
|
29
32
|
import { SuiLedger } from "../clients/sui";
|
|
30
33
|
import { THORChainLedger } from "../clients/thorchain";
|
|
34
|
+
import { TONLedger } from "../clients/ton";
|
|
31
35
|
import { TronLedger } from "../clients/tron";
|
|
32
36
|
import { BitcoinCashLedger, DashLedger, DogecoinLedger, LitecoinLedger } from "../clients/utxo";
|
|
33
37
|
import { XRPLedger } from "../clients/xrp";
|
|
@@ -45,6 +49,7 @@ type LedgerSignerMap = {
|
|
|
45
49
|
[Chain.BinanceSmartChain]: ReturnType<typeof BinanceSmartChainLedger>;
|
|
46
50
|
[Chain.BitcoinCash]: ReturnType<typeof BitcoinCashLedger>;
|
|
47
51
|
[Chain.Bitcoin]: ReturnType<typeof BitcoinLedger>;
|
|
52
|
+
[Chain.Cardano]: ReturnType<typeof CardanoLedger>;
|
|
48
53
|
[Chain.Cosmos]: CosmosLedger;
|
|
49
54
|
[Chain.Dash]: ReturnType<typeof DashLedger>;
|
|
50
55
|
[Chain.Dogecoin]: ReturnType<typeof DogecoinLedger>;
|
|
@@ -56,8 +61,11 @@ type LedgerSignerMap = {
|
|
|
56
61
|
[Chain.Optimism]: ReturnType<typeof OptimismLedger>;
|
|
57
62
|
[Chain.Polygon]: ReturnType<typeof PolygonLedger>;
|
|
58
63
|
[Chain.Ripple]: ReturnType<typeof XRPLedger>;
|
|
64
|
+
[Chain.Robinhood]: ReturnType<typeof RobinhoodLedger>;
|
|
65
|
+
[Chain.Stellar]: ReturnType<typeof StellarLedger>;
|
|
59
66
|
[Chain.Sui]: ReturnType<typeof SuiLedger>;
|
|
60
67
|
[Chain.THORChain]: THORChainLedger;
|
|
68
|
+
[Chain.Ton]: ReturnType<typeof TONLedger>;
|
|
61
69
|
[Chain.Tron]: ReturnType<typeof TronLedger>;
|
|
62
70
|
[Chain.XLayer]: ReturnType<typeof XLayerLedger>;
|
|
63
71
|
[Chain.Zcash]: ReturnType<typeof ZcashLedger>;
|
|
@@ -114,8 +122,11 @@ export async function getLedgerClient<T extends LedgerSupportedChain>({
|
|
|
114
122
|
.with(Chain.Litecoin, () => Promise.resolve(LitecoinLedger(clientParams) as LedgerSignerMap[T]))
|
|
115
123
|
.with(Chain.Zcash, () => Promise.resolve(ZcashLedger(clientParams) as LedgerSignerMap[T]))
|
|
116
124
|
.with(Chain.Ripple, () => Promise.resolve(XRPLedger(clientParams) as LedgerSignerMap[T]))
|
|
125
|
+
.with(Chain.Stellar, () => Promise.resolve(StellarLedger(clientParams) as LedgerSignerMap[T]))
|
|
126
|
+
.with(Chain.Cardano, () => Promise.resolve(CardanoLedger(clientParams) as LedgerSignerMap[T]))
|
|
117
127
|
.with(Chain.Tron, () => Promise.resolve(TronLedger(clientParams) as LedgerSignerMap[T]))
|
|
118
128
|
.with(Chain.Sui, () => Promise.resolve(SuiLedger(clientParams) as LedgerSignerMap[T]))
|
|
129
|
+
.with(Chain.Ton, () => Promise.resolve(TONLedger(clientParams) as LedgerSignerMap[T]))
|
|
119
130
|
.with(Chain.Near, () => Promise.resolve(getNearLedgerClient(clientParams) as LedgerSignerMap[T]))
|
|
120
131
|
.with(
|
|
121
132
|
Chain.Arbitrum,
|
|
@@ -130,6 +141,7 @@ export async function getLedgerClient<T extends LedgerSupportedChain>({
|
|
|
130
141
|
Chain.Optimism,
|
|
131
142
|
Chain.Polygon,
|
|
132
143
|
Chain.Base,
|
|
144
|
+
Chain.Robinhood,
|
|
133
145
|
Chain.XLayer,
|
|
134
146
|
async () => {
|
|
135
147
|
const { getProvider } = await import("@swapkit/toolboxes/evm");
|
|
@@ -154,6 +166,7 @@ export async function getLedgerClient<T extends LedgerSupportedChain>({
|
|
|
154
166
|
.with(Chain.Aurora, () => AuroraLedger(params) as LedgerSignerMap[T])
|
|
155
167
|
.with(Chain.Gnosis, () => GnosisLedger(params) as LedgerSignerMap[T])
|
|
156
168
|
.with(Chain.Monad, () => MonadLedger(params) as LedgerSignerMap[T])
|
|
169
|
+
.with(Chain.Robinhood, () => RobinhoodLedger(params) as LedgerSignerMap[T])
|
|
157
170
|
.with(Chain.XLayer, () => XLayerLedger(params) as LedgerSignerMap[T])
|
|
158
171
|
.otherwise(() => EthereumLedger(params) as LedgerSignerMap[T]);
|
|
159
172
|
},
|
package/src/ledger/index.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type Transport from "@ledgerhq/hw-transport";
|
|
2
2
|
import { hex } from "@scure/base";
|
|
3
3
|
import {
|
|
4
|
-
|
|
4
|
+
AssetValue,
|
|
5
5
|
Chain,
|
|
6
6
|
type DerivationPathArray,
|
|
7
7
|
derivationPathToString,
|
|
8
8
|
FeeOption,
|
|
9
9
|
filterSupportedChains,
|
|
10
|
+
type GenericTransferParams,
|
|
10
11
|
getUTXOScriptTypeForPath,
|
|
11
12
|
NetworkDerivationPath,
|
|
12
13
|
SwapKitError,
|
|
@@ -14,6 +15,7 @@ import {
|
|
|
14
15
|
UTXOScriptType,
|
|
15
16
|
WalletOption,
|
|
16
17
|
} from "@swapkit/helpers";
|
|
18
|
+
import type { TONTransactionInput } from "@swapkit/toolboxes/ton";
|
|
17
19
|
import {
|
|
18
20
|
addInputsAndOutputs,
|
|
19
21
|
assertDerivationIndex,
|
|
@@ -92,6 +94,7 @@ const LEDGER_SUPPORTED_CHAINS_CONFIG = [
|
|
|
92
94
|
Chain.BinanceSmartChain,
|
|
93
95
|
Chain.Bitcoin,
|
|
94
96
|
Chain.BitcoinCash,
|
|
97
|
+
Chain.Cardano,
|
|
95
98
|
Chain.Cosmos,
|
|
96
99
|
Chain.Dash,
|
|
97
100
|
Chain.Dogecoin,
|
|
@@ -103,8 +106,11 @@ const LEDGER_SUPPORTED_CHAINS_CONFIG = [
|
|
|
103
106
|
Chain.Optimism,
|
|
104
107
|
Chain.Polygon,
|
|
105
108
|
Chain.Ripple,
|
|
109
|
+
Chain.Robinhood,
|
|
110
|
+
Chain.Stellar,
|
|
106
111
|
Chain.Sui,
|
|
107
112
|
Chain.THORChain,
|
|
113
|
+
Chain.Ton,
|
|
108
114
|
Chain.XLayer,
|
|
109
115
|
Chain.Tron,
|
|
110
116
|
Chain.Zcash,
|
|
@@ -134,6 +140,7 @@ const LEDGER_EVM_CHAINS = [
|
|
|
134
140
|
Chain.Aurora,
|
|
135
141
|
Chain.Gnosis,
|
|
136
142
|
Chain.Monad,
|
|
143
|
+
Chain.Robinhood,
|
|
137
144
|
Chain.XLayer,
|
|
138
145
|
] as const satisfies readonly LedgerSupportedChain[];
|
|
139
146
|
|
|
@@ -169,35 +176,26 @@ export const ledgerWallet = createWallet({
|
|
|
169
176
|
|
|
170
177
|
return true;
|
|
171
178
|
},
|
|
172
|
-
directSigningSupport: {
|
|
173
|
-
[Chain.Arbitrum]: true,
|
|
174
|
-
[Chain.Arc]: true,
|
|
175
|
-
[Chain.Aurora]: true,
|
|
176
|
-
[Chain.Avalanche]: true,
|
|
177
|
-
[Chain.Base]: true,
|
|
178
|
-
[Chain.Berachain]: true,
|
|
179
|
-
[Chain.BinanceSmartChain]: true,
|
|
180
|
-
[Chain.Ethereum]: true,
|
|
181
|
-
[Chain.Gnosis]: true,
|
|
182
|
-
[Chain.Monad]: true,
|
|
183
|
-
[Chain.Bitcoin]: true,
|
|
184
|
-
[Chain.BitcoinCash]: true,
|
|
185
|
-
[Chain.Cosmos]: true,
|
|
186
|
-
[Chain.Dash]: true,
|
|
187
|
-
[Chain.Dogecoin]: true,
|
|
188
|
-
[Chain.Litecoin]: true,
|
|
189
|
-
[Chain.Near]: true,
|
|
190
|
-
[Chain.Optimism]: true,
|
|
191
|
-
[Chain.Polygon]: true,
|
|
192
|
-
[Chain.Ripple]: true,
|
|
193
|
-
[Chain.Sui]: true,
|
|
194
|
-
[Chain.THORChain]: true,
|
|
195
|
-
[Chain.Tron]: true,
|
|
196
|
-
[Chain.XLayer]: true,
|
|
197
|
-
// ZEC transparent transfers use DSK, but route-level PCZT signing remains unsupported.
|
|
198
|
-
},
|
|
199
179
|
getExtendedPublicKey: getLedgerExtendedPublicKey,
|
|
200
180
|
name: "connectLedger",
|
|
181
|
+
signingSupport: {
|
|
182
|
+
...Object.fromEntries(LEDGER_EVM_CHAINS.map((chain) => [chain, { direct: true, typedData: true }])),
|
|
183
|
+
[Chain.Bitcoin]: { direct: true },
|
|
184
|
+
[Chain.BitcoinCash]: { direct: true },
|
|
185
|
+
[Chain.Cardano]: { direct: true },
|
|
186
|
+
[Chain.Cosmos]: { direct: true },
|
|
187
|
+
[Chain.Dash]: { direct: true },
|
|
188
|
+
[Chain.Dogecoin]: { direct: true },
|
|
189
|
+
[Chain.Litecoin]: { direct: true },
|
|
190
|
+
[Chain.Near]: { direct: true },
|
|
191
|
+
[Chain.Ripple]: { direct: true },
|
|
192
|
+
[Chain.Stellar]: { direct: true },
|
|
193
|
+
[Chain.Sui]: { direct: true },
|
|
194
|
+
[Chain.THORChain]: { direct: true },
|
|
195
|
+
[Chain.Ton]: { direct: true },
|
|
196
|
+
[Chain.Tron]: { direct: true },
|
|
197
|
+
// ZEC transparent transfers use DSK, but route-level PCZT signing remains unsupported.
|
|
198
|
+
},
|
|
201
199
|
supportedChains: [...LEDGER_SUPPORTED_CHAINS_CONFIG],
|
|
202
200
|
walletType: WalletOption.LEDGER,
|
|
203
201
|
});
|
|
@@ -219,8 +217,8 @@ function getLedgerAccountXpub({ chain, path, signer, xpubVersion }: LedgerAccoun
|
|
|
219
217
|
.exhaustive();
|
|
220
218
|
}
|
|
221
219
|
|
|
222
|
-
//
|
|
223
|
-
//
|
|
220
|
+
// Txids are looked up in display order, the order the UTXO API names transactions by. utxo-signer below 3.2
|
|
221
|
+
// parsed raw transactions with wire-order txids, so the reversed order is tried as a fallback. A txid and its
|
|
224
222
|
// byte reversal cannot both name real transactions, so the fallback cannot fetch an unrelated one.
|
|
225
223
|
function resolveZcashInputUtxos(transaction: ZcashTransaction): Promise<UTXOType[]> {
|
|
226
224
|
const zcashApi = getUtxoApi(Chain.Zcash);
|
|
@@ -649,6 +647,21 @@ async function getNearWalletMethods({
|
|
|
649
647
|
return { ...toolbox, address: accountId };
|
|
650
648
|
}
|
|
651
649
|
|
|
650
|
+
async function getCardanoWalletMethods({
|
|
651
|
+
chain,
|
|
652
|
+
derivationPath,
|
|
653
|
+
dmkSession,
|
|
654
|
+
onDeviceActionState,
|
|
655
|
+
transport,
|
|
656
|
+
}: WalletMethodsParams<Chain.Cardano>) {
|
|
657
|
+
const { getCardanoToolbox } = await import("@swapkit/toolboxes/cardano");
|
|
658
|
+
const signer = await getLedgerClient({ chain, derivationPath, dmkSession, onDeviceActionState, transport });
|
|
659
|
+
const address = signer.getAddress();
|
|
660
|
+
const toolbox = getCardanoToolbox({ signer });
|
|
661
|
+
|
|
662
|
+
return { ...toolbox, address };
|
|
663
|
+
}
|
|
664
|
+
|
|
652
665
|
async function getRippleWalletMethods({
|
|
653
666
|
chain,
|
|
654
667
|
derivationPath,
|
|
@@ -664,6 +677,21 @@ async function getRippleWalletMethods({
|
|
|
664
677
|
return { ...toolbox, address };
|
|
665
678
|
}
|
|
666
679
|
|
|
680
|
+
async function getStellarWalletMethods({
|
|
681
|
+
chain,
|
|
682
|
+
derivationPath,
|
|
683
|
+
dmkSession,
|
|
684
|
+
onDeviceActionState,
|
|
685
|
+
transport,
|
|
686
|
+
}: WalletMethodsParams<Chain.Stellar>) {
|
|
687
|
+
const { getStellarToolbox } = await import("@swapkit/toolboxes/stellar");
|
|
688
|
+
const signer = await getLedgerClient({ chain, derivationPath, dmkSession, onDeviceActionState, transport });
|
|
689
|
+
const address = await getLedgerAddress({ chain, ledgerClient: signer });
|
|
690
|
+
const toolbox = getStellarToolbox({ signer });
|
|
691
|
+
|
|
692
|
+
return { ...toolbox, address };
|
|
693
|
+
}
|
|
694
|
+
|
|
667
695
|
async function getTronWalletMethods({
|
|
668
696
|
chain,
|
|
669
697
|
derivationPath,
|
|
@@ -694,6 +722,47 @@ async function getSuiWalletMethods({
|
|
|
694
722
|
return { ...toolbox, address };
|
|
695
723
|
}
|
|
696
724
|
|
|
725
|
+
async function getTONWalletMethods({
|
|
726
|
+
chain,
|
|
727
|
+
derivationPath,
|
|
728
|
+
dmkSession,
|
|
729
|
+
onDeviceActionState,
|
|
730
|
+
transport,
|
|
731
|
+
}: WalletMethodsParams<Chain.Ton>) {
|
|
732
|
+
const { getTONToolbox } = await import("@swapkit/toolboxes/ton");
|
|
733
|
+
const signer = await getLedgerClient({ chain, derivationPath, dmkSession, onDeviceActionState, transport });
|
|
734
|
+
const address = await getLedgerAddress({ chain, ledgerClient: signer });
|
|
735
|
+
// Signerless toolbox: it builds messages and reads balances, the device signs the external message.
|
|
736
|
+
const toolbox = getTONToolbox();
|
|
737
|
+
|
|
738
|
+
const signAndBroadcastTransaction = async (transaction: TONTransactionInput) =>
|
|
739
|
+
toolbox.broadcastTransaction(await signer.signTransaction(transaction));
|
|
740
|
+
|
|
741
|
+
const transfer = async ({ assetValue, memo, recipient, sweep }: GenericTransferParams) =>
|
|
742
|
+
signAndBroadcastTransaction(
|
|
743
|
+
await toolbox.createTransaction({ assetValue, memo, recipient, sender: address, sweep }),
|
|
744
|
+
);
|
|
745
|
+
|
|
746
|
+
// Same budget as TON Connect: the signerless toolbox underestimates jetton fees
|
|
747
|
+
const estimateTransactionFee = ({ assetValue }: GenericTransferParams) =>
|
|
748
|
+
Promise.resolve(AssetValue.from({ chain: Chain.Ton, value: assetValue.isGasAsset ? "0.01" : "0.06" }));
|
|
749
|
+
|
|
750
|
+
const sign = () => {
|
|
751
|
+
throw new SwapKitError("wallet_ledger_method_not_supported", { method: "sign", wallet: WalletOption.LEDGER });
|
|
752
|
+
};
|
|
753
|
+
|
|
754
|
+
return {
|
|
755
|
+
...toolbox,
|
|
756
|
+
address,
|
|
757
|
+
estimateTransactionFee,
|
|
758
|
+
getAddress: () => address,
|
|
759
|
+
getBalance: () => toolbox.getBalance(address),
|
|
760
|
+
sign,
|
|
761
|
+
signAndBroadcastTransaction,
|
|
762
|
+
transfer,
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
|
|
697
766
|
function getWalletMethods(params: WalletMethodsParams) {
|
|
698
767
|
if (!isLedgerSupportedChain(params.chain)) {
|
|
699
768
|
throw new SwapKitError("wallet_ledger_chain_not_supported", { chain: params.chain });
|
|
@@ -706,8 +775,11 @@ function getWalletMethods(params: WalletMethodsParams) {
|
|
|
706
775
|
.with(Chain.THORChain, (chain) => getTHORChainWalletMethods({ ...params, chain }))
|
|
707
776
|
.with(Chain.Near, (chain) => getNearWalletMethods({ ...params, chain }))
|
|
708
777
|
.with(Chain.Ripple, (chain) => getRippleWalletMethods({ ...params, chain }))
|
|
778
|
+
.with(Chain.Stellar, (chain) => getStellarWalletMethods({ ...params, chain }))
|
|
779
|
+
.with(Chain.Cardano, (chain) => getCardanoWalletMethods({ ...params, chain }))
|
|
709
780
|
.with(Chain.Tron, (chain) => getTronWalletMethods({ ...params, chain }))
|
|
710
781
|
.with(Chain.Sui, (chain) => getSuiWalletMethods({ ...params, chain }))
|
|
782
|
+
.with(Chain.Ton, (chain) => getTONWalletMethods({ ...params, chain }))
|
|
711
783
|
.exhaustive();
|
|
712
784
|
}
|
|
713
785
|
|
package/src/ledger/types.ts
CHANGED
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
MonadLedger,
|
|
14
14
|
OptimismLedger,
|
|
15
15
|
PolygonLedger,
|
|
16
|
+
RobinhoodLedger,
|
|
16
17
|
XLayerLedger,
|
|
17
18
|
} from "./clients/evm";
|
|
18
19
|
import type { SuiLedger } from "./clients/sui";
|
|
@@ -42,6 +43,7 @@ export type EVMLedgerClients =
|
|
|
42
43
|
| ReturnType<typeof MonadLedger>
|
|
43
44
|
| ReturnType<typeof OptimismLedger>
|
|
44
45
|
| ReturnType<typeof PolygonLedger>
|
|
46
|
+
| ReturnType<typeof RobinhoodLedger>
|
|
45
47
|
| ReturnType<typeof XLayerLedger>;
|
|
46
48
|
export type TronLedgerClient = ReturnType<typeof TronLedger>;
|
|
47
49
|
export type SuiLedgerClient = ReturnType<typeof SuiLedger>;
|
|
@@ -8,13 +8,13 @@ import {
|
|
|
8
8
|
} from "@swapkit/toolboxes/cardano";
|
|
9
9
|
import type {
|
|
10
10
|
CardanoAssetGroup,
|
|
11
|
-
CardanoInput,
|
|
12
11
|
CardanoOutput,
|
|
13
12
|
CardanoSignedTxData,
|
|
14
13
|
CardanoSignTransaction,
|
|
15
|
-
PROTO,
|
|
16
14
|
} from "@trezor/connect-web";
|
|
17
15
|
|
|
16
|
+
import { type CardanoOutputFields, readCardanoBody } from "../helpers/cardano";
|
|
17
|
+
|
|
18
18
|
type CardanoAddressParams = { address: string; path: string; stakingPath: string };
|
|
19
19
|
export type TrezorConnectModule = typeof import("@trezor/connect-web");
|
|
20
20
|
|
|
@@ -26,9 +26,6 @@ function getConnectParams({ CARDANO, PROTO }: TrezorConnectModule) {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
const BODY = { AUXILIARY_DATA_HASH: 7, FEE: 2, INPUTS: 0, OUTPUTS: 1, TTL: 3, VALIDITY_INTERVAL_START: 8 } as const;
|
|
30
|
-
const SET_TAG = 258;
|
|
31
|
-
|
|
32
29
|
function notSupported(reason: string) {
|
|
33
30
|
return new SwapKitError({ errorKey: "wallet_trezor_method_not_supported", info: { chain: Chain.Cardano, reason } });
|
|
34
31
|
}
|
|
@@ -40,50 +37,12 @@ function signFailed(error: string) {
|
|
|
40
37
|
});
|
|
41
38
|
}
|
|
42
39
|
|
|
43
|
-
function toUint(value: unknown, field: string) {
|
|
44
|
-
const isBigNumber = typeof value === "object" && value !== null && "toFixed" in value;
|
|
45
|
-
const text = isBigNumber || Number.isSafeInteger(value) ? String((value as number).toFixed()) : "";
|
|
46
|
-
if (!/^\d+$/.test(text)) throw notSupported(`Invalid ${field} in Cardano transaction`);
|
|
47
|
-
return text;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function toTokenBundle(multiAsset: Map<Uint8Array, Map<Uint8Array, unknown>>): CardanoAssetGroup[] {
|
|
51
|
-
return [...multiAsset].map(([policyId, assets]) => ({
|
|
52
|
-
policyId: hex.encode(policyId),
|
|
53
|
-
tokenAmounts: [...assets].map(([assetName, amount]) => ({
|
|
54
|
-
amount: toUint(amount, "token amount"),
|
|
55
|
-
assetNameBytes: hex.encode(assetName),
|
|
56
|
-
})),
|
|
57
|
-
}));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
40
|
async function toTrezorOutput(
|
|
61
|
-
|
|
41
|
+
{ address, amount, format, tokenGroups }: CardanoOutputFields,
|
|
62
42
|
own: CardanoAddressParams,
|
|
63
43
|
proto: TrezorConnectModule["PROTO"],
|
|
64
44
|
): Promise<CardanoOutput> {
|
|
65
|
-
|
|
66
|
-
let value: unknown;
|
|
67
|
-
let format: PROTO.CardanoTxOutputSerializationFormat;
|
|
68
|
-
|
|
69
|
-
if (Array.isArray(output)) {
|
|
70
|
-
if (output.length !== 2) throw notSupported("Trezor cannot sign Cardano outputs with a datum");
|
|
71
|
-
[address, value] = output;
|
|
72
|
-
format = proto.CardanoTxOutputSerializationFormat.ARRAY_LEGACY;
|
|
73
|
-
} else if (output instanceof Map) {
|
|
74
|
-
if (output.has(2)) throw notSupported("Trezor cannot sign Cardano outputs with a datum");
|
|
75
|
-
if (output.has(3)) throw notSupported("Trezor cannot sign Cardano outputs with a reference script");
|
|
76
|
-
if (output.size !== 2) throw notSupported("Unsupported field in Cardano output");
|
|
77
|
-
address = output.get(0);
|
|
78
|
-
value = output.get(1);
|
|
79
|
-
format = proto.CardanoTxOutputSerializationFormat.MAP_BABBAGE;
|
|
80
|
-
} else {
|
|
81
|
-
throw notSupported("Invalid Cardano output");
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (Array.isArray(value) && value.length !== 2) throw notSupported("Invalid Cardano output value");
|
|
85
|
-
const [coin, multiAsset] = Array.isArray(value) ? value : [value];
|
|
86
|
-
const outputAddress = await getCardanoAddressFromBytes(address as Uint8Array);
|
|
45
|
+
const outputAddress = await getCardanoAddressFromBytes(address);
|
|
87
46
|
const destination =
|
|
88
47
|
outputAddress === own.address
|
|
89
48
|
? {
|
|
@@ -94,29 +53,22 @@ async function toTrezorOutput(
|
|
|
94
53
|
},
|
|
95
54
|
}
|
|
96
55
|
: { address: outputAddress };
|
|
56
|
+
const tokenBundle: CardanoAssetGroup[] | undefined = tokenGroups?.map(({ policyId, tokens }) => ({
|
|
57
|
+
policyId: hex.encode(policyId),
|
|
58
|
+
tokenAmounts: tokens.map(({ amount, assetName }) => ({ amount, assetNameBytes: hex.encode(assetName) })),
|
|
59
|
+
}));
|
|
97
60
|
|
|
98
61
|
return {
|
|
99
62
|
...destination,
|
|
100
|
-
amount
|
|
101
|
-
format
|
|
102
|
-
|
|
63
|
+
amount,
|
|
64
|
+
format:
|
|
65
|
+
format === "legacy"
|
|
66
|
+
? proto.CardanoTxOutputSerializationFormat.ARRAY_LEGACY
|
|
67
|
+
: proto.CardanoTxOutputSerializationFormat.MAP_BABBAGE,
|
|
68
|
+
...(tokenBundle === undefined ? {} : { tokenBundle }),
|
|
103
69
|
};
|
|
104
70
|
}
|
|
105
71
|
|
|
106
|
-
function toTrezorInputs(inputs: unknown, path: string) {
|
|
107
|
-
const isTagged =
|
|
108
|
-
typeof inputs === "object" && inputs !== null && "tag" in inputs && inputs.tag === SET_TAG && "value" in inputs;
|
|
109
|
-
const list = (isTagged ? inputs.value : inputs) as unknown[][];
|
|
110
|
-
|
|
111
|
-
const trezorInputs: CardanoInput[] = list.map((input) => {
|
|
112
|
-
if (input.length !== 2) throw notSupported("Invalid Cardano input");
|
|
113
|
-
const [txHash, index] = input as [Uint8Array, unknown];
|
|
114
|
-
return { path, prev_hash: hex.encode(txHash), prev_index: Number(toUint(index, "input index")) };
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
return { inputs: trezorInputs, tagCborSets: isTagged };
|
|
118
|
-
}
|
|
119
|
-
|
|
120
72
|
export async function toTrezorCardanoTransaction(
|
|
121
73
|
txHex: string,
|
|
122
74
|
own: CardanoAddressParams,
|
|
@@ -125,31 +77,23 @@ export async function toTrezorCardanoTransaction(
|
|
|
125
77
|
const { body } = await decodeCardanoTransaction(txHex);
|
|
126
78
|
const { derivationType, mainnet } = getConnectParams(connect);
|
|
127
79
|
const { PROTO: proto } = connect;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const outputs = body.get(BODY.OUTPUTS) as unknown[];
|
|
136
|
-
const auxiliaryDataHash = body.get(BODY.AUXILIARY_DATA_HASH) as Uint8Array | undefined;
|
|
137
|
-
|
|
138
|
-
const ttl = body.get(BODY.TTL);
|
|
139
|
-
const validityIntervalStart = body.get(BODY.VALIDITY_INTERVAL_START);
|
|
80
|
+
const { auxiliaryDataHash, fee, inputs, outputs, tagCborSets, ttl, validityIntervalStart } = readCardanoBody(
|
|
81
|
+
body,
|
|
82
|
+
"Trezor",
|
|
83
|
+
notSupported,
|
|
84
|
+
);
|
|
140
85
|
|
|
141
86
|
return {
|
|
142
|
-
|
|
87
|
+
inputs: inputs.map(({ index, txHash }) => ({ path: own.path, prev_hash: hex.encode(txHash), prev_index: index })),
|
|
88
|
+
tagCborSets,
|
|
143
89
|
...mainnet,
|
|
144
90
|
derivationType,
|
|
145
|
-
fee
|
|
91
|
+
fee,
|
|
146
92
|
outputs: await Promise.all(outputs.map((output) => toTrezorOutput(output, own, proto))),
|
|
147
93
|
signingMode: proto.CardanoTxSigningMode.ORDINARY_TRANSACTION,
|
|
148
94
|
...(auxiliaryDataHash ? { auxiliaryData: { hash: hex.encode(auxiliaryDataHash) } } : {}),
|
|
149
|
-
...(ttl === undefined ? {} : { ttl
|
|
150
|
-
...(validityIntervalStart === undefined
|
|
151
|
-
? {}
|
|
152
|
-
: { validityIntervalStart: toUint(validityIntervalStart, "validity interval start") }),
|
|
95
|
+
...(ttl === undefined ? {} : { ttl }),
|
|
96
|
+
...(validityIntervalStart === undefined ? {} : { validityIntervalStart }),
|
|
153
97
|
};
|
|
154
98
|
}
|
|
155
99
|
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Chain, type DerivationPathArray, derivationPathToString, SwapKitError } from "@swapkit/helpers";
|
|
2
|
+
import type { TypedDataDomain, TypedDataField } from "ethers";
|
|
3
|
+
|
|
4
|
+
type TypedDataTypes = Record<string, TypedDataField[]>;
|
|
5
|
+
type TypedDataValue = Record<string, unknown>;
|
|
6
|
+
|
|
7
|
+
function notSupported(reason: string) {
|
|
8
|
+
return new SwapKitError({ errorKey: "wallet_trezor_method_not_supported", info: { chain: Chain.Hype, reason } });
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function toTrezorHyperCoreTypedData(
|
|
12
|
+
domain: TypedDataDomain,
|
|
13
|
+
types: TypedDataTypes,
|
|
14
|
+
message: TypedDataValue,
|
|
15
|
+
) {
|
|
16
|
+
const { TypedDataEncoder } = await import("ethers");
|
|
17
|
+
const { EIP712Domain: _, ...structTypes } = types;
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
// ethers checks the domain, the type graph and every value; the device still gets the caller's own data
|
|
21
|
+
const payload: { primaryType: string; types: TypedDataTypes } = TypedDataEncoder.getPayload(
|
|
22
|
+
domain,
|
|
23
|
+
structTypes,
|
|
24
|
+
message,
|
|
25
|
+
);
|
|
26
|
+
return {
|
|
27
|
+
domain,
|
|
28
|
+
message,
|
|
29
|
+
primaryType: payload.primaryType,
|
|
30
|
+
types: { EIP712Domain: payload.types.EIP712Domain, ...structTypes },
|
|
31
|
+
};
|
|
32
|
+
} catch (error) {
|
|
33
|
+
throw notSupported(`Invalid HyperCore typed data: ${(error as Error).message}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function getHyperCoreSigner({
|
|
38
|
+
address: knownAddress,
|
|
39
|
+
derivationPath,
|
|
40
|
+
}: {
|
|
41
|
+
address?: string;
|
|
42
|
+
derivationPath: DerivationPathArray;
|
|
43
|
+
}) {
|
|
44
|
+
const path = derivationPathToString(derivationPath);
|
|
45
|
+
let address = knownAddress ?? "";
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
getAddress: async () => {
|
|
49
|
+
if (address) return address;
|
|
50
|
+
|
|
51
|
+
const TrezorConnect = (await import("@trezor/connect-web")).default;
|
|
52
|
+
const result = await TrezorConnect.ethereumGetAddress({ path, showOnTrezor: true });
|
|
53
|
+
|
|
54
|
+
if (!result.success) {
|
|
55
|
+
throw new SwapKitError({
|
|
56
|
+
errorKey: "wallet_trezor_failed_to_get_address",
|
|
57
|
+
info: { chain: Chain.Hype, derivationPath, error: result.payload.error },
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
address = result.payload.address;
|
|
62
|
+
return address;
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
// HyperCore has no transactions: every action goes through signTypedData
|
|
66
|
+
signTransaction: () => Promise.reject(notSupported("HyperCore actions are signed with signTypedData")),
|
|
67
|
+
|
|
68
|
+
signTypedData: async (domain: TypedDataDomain, types: TypedDataTypes, message: TypedDataValue) => {
|
|
69
|
+
const data = await toTrezorHyperCoreTypedData(domain, types, message);
|
|
70
|
+
const TrezorConnect = (await import("@trezor/connect-web")).default;
|
|
71
|
+
|
|
72
|
+
const result = await TrezorConnect.ethereumSignTypedData({
|
|
73
|
+
data: data as Parameters<typeof TrezorConnect.ethereumSignTypedData>[0]["data"],
|
|
74
|
+
metamask_v4_compat: true,
|
|
75
|
+
path,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if (!result.success) {
|
|
79
|
+
throw new SwapKitError({
|
|
80
|
+
errorKey: "wallet_trezor_failed_to_sign_transaction",
|
|
81
|
+
info: { chain: Chain.Hype, error: result.payload.error },
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Hyperliquid takes the account from the signature, so a stale known address would act from another account
|
|
86
|
+
if (result.payload.address.toLowerCase() !== address.toLowerCase()) {
|
|
87
|
+
throw new SwapKitError({
|
|
88
|
+
errorKey: "wallet_trezor_failed_to_sign_transaction",
|
|
89
|
+
info: { chain: Chain.Hype, error: "Trezor signed with a different address", signer: result.payload.address },
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return result.payload.signature.startsWith("0x") ? result.payload.signature : `0x${result.payload.signature}`;
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|