@swapkit/toolboxes 1.0.0-beta.0 → 1.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-0f0249b1.js +3 -0
- package/dist/chunk-0f0249b1.js.map +10 -0
- package/dist/chunk-0h4xdrwz.js +4 -0
- package/dist/chunk-0h4xdrwz.js.map +10 -0
- package/dist/chunk-4yap1fvd.js +3 -0
- package/dist/chunk-4yap1fvd.js.map +10 -0
- package/dist/chunk-fjfxga2v.js +3 -0
- package/dist/chunk-fjfxga2v.js.map +10 -0
- package/dist/{chunk-tvrdndbw.js → chunk-p1kdg37m.js} +2 -2
- package/dist/{chunk-tvrdndbw.js.map → chunk-p1kdg37m.js.map} +1 -1
- package/dist/cosmos/index.cjs +2 -2
- package/dist/cosmos/index.cjs.map +10 -13
- package/dist/cosmos/index.js +2 -2
- package/dist/cosmos/index.js.map +10 -13
- package/dist/evm/index.cjs +2 -2
- package/dist/evm/index.cjs.map +10 -16
- package/dist/evm/index.js +2 -2
- package/dist/evm/index.js.map +10 -16
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +4 -3
- package/dist/index.js +2 -2
- package/dist/index.js.map +4 -3
- package/dist/radix/index.cjs +2 -2
- package/dist/radix/index.cjs.map +3 -3
- package/dist/radix/index.js +2 -2
- package/dist/radix/index.js.map +3 -3
- package/dist/ripple/index.cjs +3 -0
- package/dist/ripple/index.cjs.map +10 -0
- package/dist/ripple/index.js +3 -0
- package/dist/ripple/index.js.map +10 -0
- package/dist/solana/index.cjs +2 -2
- package/dist/solana/index.cjs.map +3 -3
- package/dist/solana/index.js +2 -2
- package/dist/solana/index.js.map +3 -3
- package/dist/substrate/index.cjs +2 -2
- package/dist/substrate/index.cjs.map +5 -6
- package/dist/substrate/index.js +2 -2
- package/dist/substrate/index.js.map +5 -6
- package/dist/utxo/index.cjs +2 -2
- package/dist/utxo/index.cjs.map +9 -11
- package/dist/utxo/index.js +2 -2
- package/dist/utxo/index.js.map +9 -11
- package/package.json +27 -23
- package/src/cosmos/index.ts +2 -9
- package/src/cosmos/thorchainUtils/addressFormat.ts +1 -2
- package/src/cosmos/thorchainUtils/index.ts +1 -1
- package/src/cosmos/thorchainUtils/messages.ts +74 -56
- package/src/cosmos/thorchainUtils/registry.ts +19 -26
- package/src/cosmos/thorchainUtils/types/{proto/MsgCompiled.ts → MsgCompiled.ts} +1 -3
- package/src/cosmos/thorchainUtils/types/client-types.ts +16 -23
- package/src/cosmos/toolbox/cosmos.ts +334 -0
- package/src/cosmos/toolbox/index.ts +33 -0
- package/src/cosmos/toolbox/thorchain.ts +125 -137
- package/src/cosmos/types.ts +37 -18
- package/src/cosmos/util.ts +24 -74
- package/src/evm/__tests__/ethereum.test.ts +110 -116
- package/src/evm/api.ts +11 -147
- package/src/evm/helpers.ts +111 -83
- package/src/evm/index.ts +1 -17
- package/src/evm/toolbox/baseEVMToolbox.ts +744 -0
- package/src/evm/toolbox/evm.ts +69 -0
- package/src/evm/toolbox/index.ts +36 -0
- package/src/evm/toolbox/op.ts +97 -143
- package/src/evm/types.ts +50 -28
- package/src/index.ts +235 -0
- package/src/radix/index.ts +18 -19
- package/src/ripple/index.ts +199 -0
- package/src/solana/index.ts +11 -5
- package/src/solana/toolbox.ts +227 -137
- package/src/substrate/index.ts +2 -3
- package/src/substrate/{toolbox/baseSubstrateToolbox.ts → substrate.ts} +104 -72
- package/src/substrate/types.ts +120 -0
- package/src/utils.ts +27 -0
- package/src/utxo/helpers/api.ts +27 -23
- package/src/utxo/helpers/bchaddrjs.ts +21 -21
- package/src/utxo/helpers/index.ts +0 -1
- package/src/utxo/helpers/txSize.ts +3 -4
- package/src/utxo/index.ts +3 -7
- package/src/utxo/toolbox/bitcoinCash.ts +165 -155
- package/src/utxo/toolbox/index.ts +63 -24
- package/src/utxo/toolbox/utxo.ts +376 -229
- package/src/utxo/types.ts +26 -39
- package/src/cosmos/thorchainUtils/types/proto/MsgCompiled.js +0 -2806
- package/src/cosmos/thorchainUtils/util.ts +0 -46
- package/src/cosmos/toolbox/BaseCosmosToolbox.ts +0 -254
- package/src/cosmos/toolbox/gaia.ts +0 -39
- package/src/cosmos/toolbox/getToolboxByChain.ts +0 -29
- package/src/cosmos/toolbox/kujira.ts +0 -61
- package/src/evm/provider.ts +0 -6
- package/src/evm/toolbox/EVMToolbox.ts +0 -662
- package/src/evm/toolbox/arb.ts +0 -61
- package/src/evm/toolbox/avax.ts +0 -36
- package/src/evm/toolbox/base.ts +0 -42
- package/src/evm/toolbox/bsc.ts +0 -34
- package/src/evm/toolbox/eth.ts +0 -44
- package/src/evm/toolbox/getToolboxByChain.ts +0 -42
- package/src/evm/toolbox/matic.ts +0 -42
- package/src/radix/toolbox.ts +0 -693
- package/src/substrate/toolbox/index.ts +0 -40
- package/src/substrate/types/index.ts +0 -2
- package/src/substrate/types/network.ts +0 -42
- package/src/substrate/types/wallet.ts +0 -78
- package/src/utxo/helpers/utils.ts +0 -45
package/src/index.ts
CHANGED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AssetValue,
|
|
3
|
+
Chain,
|
|
4
|
+
type CosmosChain,
|
|
5
|
+
type EVMChain,
|
|
6
|
+
FeeOption,
|
|
7
|
+
type GenericCreateTransactionParams,
|
|
8
|
+
type SubstrateChain,
|
|
9
|
+
type UTXOChain,
|
|
10
|
+
} from "@swapkit/helpers";
|
|
11
|
+
import type { getCosmosToolbox } from "@swapkit/toolboxes/cosmos";
|
|
12
|
+
|
|
13
|
+
import type { ETHToolbox, EVMCreateTransactionParams, getEvmToolbox } from "@swapkit/toolboxes/evm";
|
|
14
|
+
import type { RadixToolbox } from "@swapkit/toolboxes/radix";
|
|
15
|
+
import type { getRippleToolbox } from "@swapkit/toolboxes/ripple";
|
|
16
|
+
import type { SolanaCreateTransactionParams, getSolanaToolbox } from "@swapkit/toolboxes/solana";
|
|
17
|
+
import type { getSubstrateToolbox } from "@swapkit/toolboxes/substrate";
|
|
18
|
+
import type { getUtxoToolbox } from "@swapkit/toolboxes/utxo";
|
|
19
|
+
|
|
20
|
+
export async function getAddressValidator() {
|
|
21
|
+
const { match } = await import("ts-pattern");
|
|
22
|
+
const { cosmosValidateAddress } = await import("@swapkit/toolboxes/cosmos");
|
|
23
|
+
const { evmValidateAddress } = await import("@swapkit/toolboxes/evm");
|
|
24
|
+
const { substrateValidateAddress } = await import("@swapkit/toolboxes/substrate");
|
|
25
|
+
const { getUTXOAddressValidator } = await import("@swapkit/toolboxes/utxo");
|
|
26
|
+
const { getSolanaAddressValidator } = await import("@swapkit/toolboxes/solana");
|
|
27
|
+
const { rippleValidateAddress } = await import("@swapkit/toolboxes/ripple");
|
|
28
|
+
const { radixValidateAddress } = await import("@swapkit/toolboxes/radix");
|
|
29
|
+
|
|
30
|
+
const solanaValidateAddress = await getSolanaAddressValidator();
|
|
31
|
+
const utxoValidateAddress = await getUTXOAddressValidator();
|
|
32
|
+
|
|
33
|
+
return function validateAddress({ address, chain }: { address: string; chain: Chain }) {
|
|
34
|
+
const isValid = match(chain)
|
|
35
|
+
.with(
|
|
36
|
+
Chain.Arbitrum,
|
|
37
|
+
Chain.Avalanche,
|
|
38
|
+
Chain.Optimism,
|
|
39
|
+
Chain.BinanceSmartChain,
|
|
40
|
+
Chain.Base,
|
|
41
|
+
Chain.Polygon,
|
|
42
|
+
Chain.Ethereum,
|
|
43
|
+
() => evmValidateAddress({ address }),
|
|
44
|
+
)
|
|
45
|
+
.with(Chain.Litecoin, Chain.Dash, Chain.Dogecoin, Chain.BitcoinCash, Chain.Bitcoin, () =>
|
|
46
|
+
utxoValidateAddress({ address, chain: chain as UTXOChain }),
|
|
47
|
+
)
|
|
48
|
+
.with(Chain.Cosmos, Chain.Kujira, Chain.Maya, Chain.THORChain, () =>
|
|
49
|
+
cosmosValidateAddress({ address, chain: chain as CosmosChain }),
|
|
50
|
+
)
|
|
51
|
+
.with(Chain.Chainflip, Chain.Polkadot, () =>
|
|
52
|
+
substrateValidateAddress({ address, chain: chain as SubstrateChain }),
|
|
53
|
+
)
|
|
54
|
+
.with(Chain.Radix, () => radixValidateAddress(address))
|
|
55
|
+
.with(Chain.Ripple, () => rippleValidateAddress(address))
|
|
56
|
+
.with(Chain.Solana, () => solanaValidateAddress(address))
|
|
57
|
+
.otherwise(() => false);
|
|
58
|
+
|
|
59
|
+
return isValid;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export async function getFeeEstimator<T extends keyof CreateTransactionParams>(chain: T) {
|
|
64
|
+
const toolbox = await getToolbox(chain);
|
|
65
|
+
|
|
66
|
+
return async function estimateFee(params: CreateTransactionParams[T]) {
|
|
67
|
+
switch (chain) {
|
|
68
|
+
case Chain.Arbitrum:
|
|
69
|
+
case Chain.Avalanche:
|
|
70
|
+
case Chain.Optimism:
|
|
71
|
+
case Chain.BinanceSmartChain:
|
|
72
|
+
case Chain.Base:
|
|
73
|
+
case Chain.Polygon:
|
|
74
|
+
case Chain.Ethereum: {
|
|
75
|
+
const txObject = await (
|
|
76
|
+
toolbox as Awaited<ReturnType<typeof ETHToolbox>>
|
|
77
|
+
).createTransaction(params as EVMCreateTransactionParams);
|
|
78
|
+
return (toolbox as Awaited<ReturnType<typeof ETHToolbox>>).estimateTransactionFee({
|
|
79
|
+
...txObject,
|
|
80
|
+
feeOption: params.feeOptionKey || FeeOption.Fast,
|
|
81
|
+
chain,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
case Chain.Bitcoin:
|
|
85
|
+
case Chain.BitcoinCash:
|
|
86
|
+
case Chain.Dogecoin:
|
|
87
|
+
case Chain.Dash:
|
|
88
|
+
case Chain.Litecoin: {
|
|
89
|
+
return (toolbox as Awaited<ReturnType<typeof getUtxoToolbox>>).estimateTransactionFee(
|
|
90
|
+
params as CreateTransactionParams[Chain.Bitcoin],
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
case Chain.THORChain:
|
|
95
|
+
case Chain.Maya:
|
|
96
|
+
case Chain.Kujira:
|
|
97
|
+
case Chain.Cosmos: {
|
|
98
|
+
const { estimateTransactionFee } = await import("@swapkit/toolboxes/cosmos");
|
|
99
|
+
return estimateTransactionFee(params);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
case Chain.Polkadot: {
|
|
103
|
+
return (
|
|
104
|
+
toolbox as Awaited<ReturnType<typeof getSubstrateToolbox<Chain.Polkadot>>>
|
|
105
|
+
).estimateTransactionFee(params);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
case Chain.Solana: {
|
|
109
|
+
return (toolbox as Awaited<ReturnType<typeof getSolanaToolbox>>).estimateTransactionFee(
|
|
110
|
+
params as CreateTransactionParams[Chain.Solana],
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
default:
|
|
115
|
+
return AssetValue.from({ chain });
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
type Toolboxes = {
|
|
121
|
+
[key in EVMChain]: Awaited<ReturnType<typeof getEvmToolbox>>;
|
|
122
|
+
} & {
|
|
123
|
+
[key in UTXOChain]: Awaited<ReturnType<typeof getUtxoToolbox>>;
|
|
124
|
+
} & {
|
|
125
|
+
[key in CosmosChain]: Awaited<ReturnType<typeof getCosmosToolbox>>;
|
|
126
|
+
} & {
|
|
127
|
+
[key in SubstrateChain]: Awaited<ReturnType<typeof getSubstrateToolbox>>;
|
|
128
|
+
} & {
|
|
129
|
+
[Chain.Radix]: Awaited<ReturnType<typeof RadixToolbox>>;
|
|
130
|
+
[Chain.Ripple]: Awaited<ReturnType<typeof getRippleToolbox>>;
|
|
131
|
+
[Chain.Solana]: Awaited<ReturnType<typeof getSolanaToolbox>>;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
type ToolboxParams = { [key in EVMChain]: Parameters<typeof getEvmToolbox>[1] } & {
|
|
135
|
+
[key in UTXOChain]: undefined;
|
|
136
|
+
} & {
|
|
137
|
+
[key in CosmosChain]: Parameters<typeof getCosmosToolbox>[1];
|
|
138
|
+
} & {
|
|
139
|
+
[key in SubstrateChain]: Parameters<typeof getSubstrateToolbox>[1];
|
|
140
|
+
} & {
|
|
141
|
+
[Chain.Radix]: Parameters<typeof RadixToolbox>[0];
|
|
142
|
+
[Chain.Ripple]: Parameters<typeof getRippleToolbox>[0];
|
|
143
|
+
[Chain.Solana]: Parameters<typeof getSolanaToolbox>[0];
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
type CreateTransactionParams = { [key in EVMChain]: EVMCreateTransactionParams } & {
|
|
147
|
+
[key in UTXOChain]: GenericCreateTransactionParams;
|
|
148
|
+
} & {
|
|
149
|
+
[key in CosmosChain]: GenericCreateTransactionParams;
|
|
150
|
+
} & {
|
|
151
|
+
[key in SubstrateChain]: GenericCreateTransactionParams;
|
|
152
|
+
} & {
|
|
153
|
+
[Chain.Radix]: GenericCreateTransactionParams;
|
|
154
|
+
[Chain.Solana]: SolanaCreateTransactionParams;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export async function getToolbox<T extends keyof Toolboxes>(
|
|
158
|
+
chain: T,
|
|
159
|
+
params?: ToolboxParams[T],
|
|
160
|
+
): Promise<Toolboxes[T]> {
|
|
161
|
+
switch (chain) {
|
|
162
|
+
case Chain.Arbitrum:
|
|
163
|
+
case Chain.Avalanche:
|
|
164
|
+
case Chain.Optimism:
|
|
165
|
+
case Chain.BinanceSmartChain:
|
|
166
|
+
case Chain.Base:
|
|
167
|
+
case Chain.Polygon:
|
|
168
|
+
case Chain.Ethereum: {
|
|
169
|
+
const { getEvmToolbox } = await import("@swapkit/toolboxes/evm");
|
|
170
|
+
const evmToolbox = await getEvmToolbox(chain, params as Parameters<typeof getEvmToolbox>[1]);
|
|
171
|
+
return evmToolbox as Toolboxes[T];
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
case Chain.Litecoin:
|
|
175
|
+
case Chain.Dash:
|
|
176
|
+
case Chain.Dogecoin:
|
|
177
|
+
case Chain.BitcoinCash:
|
|
178
|
+
case Chain.Bitcoin: {
|
|
179
|
+
const { getUtxoToolbox } = await import("@swapkit/toolboxes/utxo");
|
|
180
|
+
const utxoToolbox = await getUtxoToolbox(
|
|
181
|
+
chain,
|
|
182
|
+
params as Parameters<typeof getUtxoToolbox>[1],
|
|
183
|
+
);
|
|
184
|
+
return utxoToolbox as Toolboxes[T];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
case Chain.Cosmos:
|
|
188
|
+
case Chain.Kujira:
|
|
189
|
+
case Chain.Maya:
|
|
190
|
+
case Chain.THORChain: {
|
|
191
|
+
const { getCosmosToolbox } = await import("@swapkit/toolboxes/cosmos");
|
|
192
|
+
const cosmosToolbox = await getCosmosToolbox(
|
|
193
|
+
chain,
|
|
194
|
+
params as Parameters<typeof getCosmosToolbox>[1],
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
return cosmosToolbox as Toolboxes[T];
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
case Chain.Chainflip:
|
|
201
|
+
case Chain.Polkadot: {
|
|
202
|
+
const { getSubstrateToolbox } = await import("@swapkit/toolboxes/substrate");
|
|
203
|
+
const substrateToolbox = await getSubstrateToolbox(
|
|
204
|
+
chain,
|
|
205
|
+
params as Parameters<typeof getSubstrateToolbox>[1],
|
|
206
|
+
);
|
|
207
|
+
return substrateToolbox as Toolboxes[T];
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
case Chain.Radix: {
|
|
211
|
+
const { RadixToolbox } = await import("@swapkit/toolboxes/radix");
|
|
212
|
+
const radixToolbox = await RadixToolbox(params as Parameters<typeof RadixToolbox>[0]);
|
|
213
|
+
return radixToolbox as Toolboxes[T];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
case Chain.Ripple: {
|
|
217
|
+
const { getRippleToolbox } = await import("@swapkit/toolboxes/ripple");
|
|
218
|
+
const rippleToolbox = await getRippleToolbox(
|
|
219
|
+
params as Parameters<typeof getRippleToolbox>[0],
|
|
220
|
+
);
|
|
221
|
+
return rippleToolbox as Toolboxes[T];
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
case Chain.Solana: {
|
|
225
|
+
const { getSolanaToolbox } = await import("@swapkit/toolboxes/solana");
|
|
226
|
+
const solanaToolbox = await getSolanaToolbox(
|
|
227
|
+
params as Parameters<typeof getSolanaToolbox>[0],
|
|
228
|
+
);
|
|
229
|
+
return solanaToolbox as Toolboxes[T];
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
default:
|
|
233
|
+
throw new Error(`Chain ${chain} is not supported`);
|
|
234
|
+
}
|
|
235
|
+
}
|
package/src/radix/index.ts
CHANGED
|
@@ -1,23 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import type {
|
|
2
|
+
FungibleResourcesCollectionItem,
|
|
3
3
|
GatewayApiClient,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
StateEntityDetailsVaultResponseItem,
|
|
5
|
+
StateEntityFungiblesPageRequest,
|
|
6
|
+
StateEntityFungiblesPageResponse,
|
|
7
7
|
} from "@radixdlt/babylon-gateway-api-sdk";
|
|
8
|
-
import {
|
|
9
|
-
import { AssetValue, Chain, type SKConfigIntegrations } from "@swapkit/helpers";
|
|
8
|
+
import { AssetValue, Chain, SKConfig, type SKConfigIntegrations } from "@swapkit/helpers";
|
|
10
9
|
|
|
11
|
-
export type
|
|
12
|
-
[Chain.Radix]: Awaited<ReturnType<typeof RadixToolbox>>;
|
|
13
|
-
};
|
|
10
|
+
export type RadixWallet = Awaited<ReturnType<typeof RadixToolbox>>;
|
|
14
11
|
|
|
15
12
|
type RadixGetBalanceParams = {
|
|
16
13
|
address: string;
|
|
17
14
|
networkApi: GatewayApiClient;
|
|
18
15
|
};
|
|
19
16
|
// Could not find anything sync in SDK, ask Radix team
|
|
20
|
-
export function
|
|
17
|
+
export function radixValidateAddress(address: string) {
|
|
21
18
|
return address.startsWith("account_rdx1") && address.length === 66;
|
|
22
19
|
}
|
|
23
20
|
|
|
@@ -129,21 +126,23 @@ async function currentStateVersion(networkApi: GatewayApiClient) {
|
|
|
129
126
|
|
|
130
127
|
export const RadixToolbox = async ({
|
|
131
128
|
dappConfig,
|
|
132
|
-
}: { dappConfig
|
|
129
|
+
}: { dappConfig?: SKConfigIntegrations["radix"] } = {}) => {
|
|
130
|
+
const { RadixDappToolkit } = await import("@radixdlt/radix-dapp-toolkit");
|
|
131
|
+
const { GatewayApiClient } = await import("@radixdlt/babylon-gateway-api-sdk");
|
|
132
|
+
const config = dappConfig || SKConfig.get("integrations").radix;
|
|
133
|
+
|
|
133
134
|
const radixToolkit = RadixDappToolkit({
|
|
134
|
-
...
|
|
135
|
-
networkId:
|
|
135
|
+
...config,
|
|
136
|
+
networkId: config.network?.networkId || 1,
|
|
136
137
|
});
|
|
137
138
|
|
|
138
139
|
const networkApi = GatewayApiClient.initialize(radixToolkit.gatewayApi.clientConfig);
|
|
139
140
|
|
|
140
141
|
return {
|
|
141
|
-
|
|
142
|
+
getAddress: () => "",
|
|
142
143
|
getBalance: getBalance({ networkApi }),
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
},
|
|
146
|
-
validateAddress,
|
|
144
|
+
networkApi,
|
|
145
|
+
validateAddress: radixValidateAddress,
|
|
147
146
|
signAndBroadcast: (() => {
|
|
148
147
|
throw new Error("Not implemented");
|
|
149
148
|
}) as (params: any) => Promise<string>,
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AssetValue,
|
|
3
|
+
BaseDecimal,
|
|
4
|
+
Chain,
|
|
5
|
+
type ChainSigner,
|
|
6
|
+
type GenericTransferParams,
|
|
7
|
+
SKConfig,
|
|
8
|
+
SwapKitError,
|
|
9
|
+
SwapKitNumber,
|
|
10
|
+
} from "@swapkit/helpers";
|
|
11
|
+
import type { Transaction } from "xrpl";
|
|
12
|
+
import { Client, type Payment, Wallet, isValidAddress, xrpToDrops } from "xrpl";
|
|
13
|
+
|
|
14
|
+
export type RippleWallet = Awaited<ReturnType<typeof getRippleToolbox>>;
|
|
15
|
+
|
|
16
|
+
// Note: Ripple seeds generate a single address, no derivation path/index support.
|
|
17
|
+
function createSigner(phrase: string): ChainSigner<Transaction, { tx_blob: string; hash: string }> {
|
|
18
|
+
const wallet = Wallet.fromMnemonic(phrase);
|
|
19
|
+
return {
|
|
20
|
+
// publicKey: wallet.publicKey,
|
|
21
|
+
// Address is sync, but interface requires async
|
|
22
|
+
getAddress: () => Promise.resolve(wallet.address),
|
|
23
|
+
// Signing is sync, but interface requires async
|
|
24
|
+
signTransaction: (tx: Transaction) => Promise.resolve(wallet.sign(tx as Transaction)), // Cast needed as Wallet.sign expects Transaction
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function rippleValidateAddress(address: string) {
|
|
29
|
+
return isValidAddress(address);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type RippleToolboxParams =
|
|
33
|
+
| { phrase: string }
|
|
34
|
+
| { signer: ChainSigner<Transaction, { tx_blob: string; hash: string }> }
|
|
35
|
+
| {};
|
|
36
|
+
|
|
37
|
+
export const getRippleToolbox = async (params: RippleToolboxParams = {}) => {
|
|
38
|
+
const signer =
|
|
39
|
+
"signer" in params && params.signer
|
|
40
|
+
? params.signer
|
|
41
|
+
: "phrase" in params && params.phrase
|
|
42
|
+
? createSigner(params.phrase)
|
|
43
|
+
: undefined;
|
|
44
|
+
|
|
45
|
+
const rpcUrl = SKConfig.get("rpcUrls")[Chain.Ripple];
|
|
46
|
+
if (!rpcUrl) {
|
|
47
|
+
throw new SwapKitError({
|
|
48
|
+
errorKey: "toolbox_ripple_rpc_not_configured",
|
|
49
|
+
info: { chain: Chain.Ripple },
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const client = new Client(rpcUrl);
|
|
54
|
+
await client.connect();
|
|
55
|
+
|
|
56
|
+
const getAddress = () => {
|
|
57
|
+
if (!signer) {
|
|
58
|
+
throw new SwapKitError({ errorKey: "toolbox_ripple_signer_not_found" });
|
|
59
|
+
}
|
|
60
|
+
return signer.getAddress();
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const getBalance = async (address?: string) => {
|
|
64
|
+
const addr = address || (await getAddress());
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
await client.connect();
|
|
68
|
+
const accountInfo = await client.request({
|
|
69
|
+
command: "account_info",
|
|
70
|
+
account: addr,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const balance = accountInfo.result.account_data.Balance;
|
|
74
|
+
|
|
75
|
+
return [
|
|
76
|
+
AssetValue.from({
|
|
77
|
+
chain: Chain.Ripple,
|
|
78
|
+
value: balance,
|
|
79
|
+
fromBaseDecimal: BaseDecimal[Chain.Ripple],
|
|
80
|
+
}),
|
|
81
|
+
];
|
|
82
|
+
} catch (error) {
|
|
83
|
+
// empty account
|
|
84
|
+
if ((error as any).data.error_code === 19) {
|
|
85
|
+
return [
|
|
86
|
+
AssetValue.from({
|
|
87
|
+
chain: Chain.Ripple,
|
|
88
|
+
value: 0,
|
|
89
|
+
}),
|
|
90
|
+
];
|
|
91
|
+
}
|
|
92
|
+
throw new SwapKitError("toolbox_ripple_get_balance_error", {
|
|
93
|
+
info: { address: addr, error },
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const estimateTransactionFee = async () => {
|
|
99
|
+
const feeResponse = await client.request({ command: "fee" });
|
|
100
|
+
const feeDrops = feeResponse.result.drops.open_ledger_fee; // Fee in drops
|
|
101
|
+
|
|
102
|
+
return AssetValue.from({
|
|
103
|
+
chain: Chain.Ripple,
|
|
104
|
+
value: SwapKitNumber.fromBigInt(BigInt(feeDrops), BaseDecimal[Chain.Ripple]),
|
|
105
|
+
});
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const createTransaction = async ({
|
|
109
|
+
assetValue,
|
|
110
|
+
recipient,
|
|
111
|
+
memo,
|
|
112
|
+
sender,
|
|
113
|
+
}: { assetValue: AssetValue; recipient: string; sender?: string; memo?: string }) => {
|
|
114
|
+
if (!rippleValidateAddress(recipient)) {
|
|
115
|
+
throw new SwapKitError({ errorKey: "core_transaction_invalid_recipient_address" });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const senderAddress = sender || (await getAddress());
|
|
119
|
+
|
|
120
|
+
if (!assetValue.isGasAsset || assetValue.chain !== Chain.Ripple) {
|
|
121
|
+
throw new SwapKitError({
|
|
122
|
+
errorKey: "toolbox_ripple_asset_not_supported",
|
|
123
|
+
info: { asset: assetValue.toString() },
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const transaction: Payment = {
|
|
128
|
+
TransactionType: "Payment",
|
|
129
|
+
Account: senderAddress,
|
|
130
|
+
Amount: xrpToDrops(assetValue.getValue("string")),
|
|
131
|
+
Destination: recipient,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
if (memo) {
|
|
135
|
+
transaction.Memos = [{ Memo: { MemoData: Buffer.from(memo).toString("hex") } }];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const preparedTx = await client.autofill(transaction);
|
|
139
|
+
return preparedTx;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const signTransaction = (tx: Transaction) => {
|
|
143
|
+
if (!signer) {
|
|
144
|
+
throw new SwapKitError({ errorKey: "toolbox_ripple_signer_not_found" });
|
|
145
|
+
}
|
|
146
|
+
return signer.signTransaction(tx);
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const broadcastTransaction = async (signedTxHex: string) => {
|
|
150
|
+
const submitResult = await client.submitAndWait(signedTxHex);
|
|
151
|
+
// Cast result to any to bypass potential type mismatches in xrpl.js definitions
|
|
152
|
+
const result: any = submitResult.result;
|
|
153
|
+
|
|
154
|
+
// Check engine_result directly on result
|
|
155
|
+
if (result.engine_result === "tesSUCCESS" || result.engine_result === "terQUEUED") {
|
|
156
|
+
// Access hash from tx_json if available, otherwise fallback to result.hash
|
|
157
|
+
return result.tx_json?.hash || result.hash;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const message = result.engine_result_message || "Unknown error";
|
|
161
|
+
const code = result.engine_result || "Unknown code";
|
|
162
|
+
|
|
163
|
+
throw new SwapKitError({
|
|
164
|
+
errorKey: "toolbox_ripple_broadcast_error",
|
|
165
|
+
info: { chain: Chain.Ripple, message, code, result },
|
|
166
|
+
// Remove explicit message when using object format
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const transfer = async (params: GenericTransferParams) => {
|
|
171
|
+
if (!signer) {
|
|
172
|
+
throw new SwapKitError({ errorKey: "toolbox_ripple_signer_not_found" });
|
|
173
|
+
}
|
|
174
|
+
const sender = await signer.getAddress();
|
|
175
|
+
const tx = await createTransaction({ ...params, sender });
|
|
176
|
+
const signedTx = await signTransaction(tx);
|
|
177
|
+
return broadcastTransaction(signedTx.tx_blob);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// Disconnect client on demand or handle elsewhere?
|
|
181
|
+
// For now, let's assume connection is managed outside or persists.
|
|
182
|
+
// const disconnect = () => client.disconnect();
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
// Signer related
|
|
186
|
+
signer, // Expose the signer instance if created/provided
|
|
187
|
+
createSigner, // Expose the helper
|
|
188
|
+
// Core methods
|
|
189
|
+
getAddress,
|
|
190
|
+
validateAddress: rippleValidateAddress,
|
|
191
|
+
getBalance,
|
|
192
|
+
createTransaction,
|
|
193
|
+
signTransaction,
|
|
194
|
+
broadcastTransaction,
|
|
195
|
+
transfer,
|
|
196
|
+
estimateTransactionFee,
|
|
197
|
+
// disconnect, // Optional: expose disconnect
|
|
198
|
+
};
|
|
199
|
+
};
|
package/src/solana/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PublicKey, SendOptions, Transaction, VersionedTransaction } from "@solana/web3.js";
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
2
|
+
import type { GenericCreateTransactionParams, GenericTransferParams } from "@swapkit/helpers";
|
|
3
|
+
import type { getSolanaToolbox } from "./toolbox";
|
|
4
4
|
|
|
5
5
|
type DisplayEncoding = "utf8" | "hex";
|
|
6
6
|
|
|
@@ -22,9 +22,7 @@ interface ConnectOpts {
|
|
|
22
22
|
|
|
23
23
|
export * from "./toolbox";
|
|
24
24
|
|
|
25
|
-
export type
|
|
26
|
-
[Chain.Solana]: ReturnType<typeof SOLToolbox>;
|
|
27
|
-
};
|
|
25
|
+
export type SolanaWallet = Awaited<ReturnType<typeof getSolanaToolbox>>;
|
|
28
26
|
|
|
29
27
|
export interface SolanaProvider {
|
|
30
28
|
connect: (opts?: Partial<ConnectOpts>) => Promise<{ publicKey: PublicKey }>;
|
|
@@ -47,3 +45,11 @@ export interface SolanaProvider {
|
|
|
47
45
|
transactions: T[],
|
|
48
46
|
) => Promise<T[]>;
|
|
49
47
|
}
|
|
48
|
+
|
|
49
|
+
export type SolanaCreateTransactionParams = Omit<GenericCreateTransactionParams, "feeRate"> & {
|
|
50
|
+
isProgramDerivedAddress?: boolean;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export type SolanaTransferParams = Omit<GenericTransferParams, "feeRate"> & {
|
|
54
|
+
isProgramDerivedAddress?: boolean;
|
|
55
|
+
};
|