@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.
Files changed (103) hide show
  1. package/dist/chunk-0f0249b1.js +3 -0
  2. package/dist/chunk-0f0249b1.js.map +10 -0
  3. package/dist/chunk-0h4xdrwz.js +4 -0
  4. package/dist/chunk-0h4xdrwz.js.map +10 -0
  5. package/dist/chunk-4yap1fvd.js +3 -0
  6. package/dist/chunk-4yap1fvd.js.map +10 -0
  7. package/dist/chunk-fjfxga2v.js +3 -0
  8. package/dist/chunk-fjfxga2v.js.map +10 -0
  9. package/dist/{chunk-tvrdndbw.js → chunk-p1kdg37m.js} +2 -2
  10. package/dist/{chunk-tvrdndbw.js.map → chunk-p1kdg37m.js.map} +1 -1
  11. package/dist/cosmos/index.cjs +2 -2
  12. package/dist/cosmos/index.cjs.map +10 -13
  13. package/dist/cosmos/index.js +2 -2
  14. package/dist/cosmos/index.js.map +10 -13
  15. package/dist/evm/index.cjs +2 -2
  16. package/dist/evm/index.cjs.map +10 -16
  17. package/dist/evm/index.js +2 -2
  18. package/dist/evm/index.js.map +10 -16
  19. package/dist/index.cjs +2 -2
  20. package/dist/index.cjs.map +4 -3
  21. package/dist/index.js +2 -2
  22. package/dist/index.js.map +4 -3
  23. package/dist/radix/index.cjs +2 -2
  24. package/dist/radix/index.cjs.map +3 -3
  25. package/dist/radix/index.js +2 -2
  26. package/dist/radix/index.js.map +3 -3
  27. package/dist/ripple/index.cjs +3 -0
  28. package/dist/ripple/index.cjs.map +10 -0
  29. package/dist/ripple/index.js +3 -0
  30. package/dist/ripple/index.js.map +10 -0
  31. package/dist/solana/index.cjs +2 -2
  32. package/dist/solana/index.cjs.map +3 -3
  33. package/dist/solana/index.js +2 -2
  34. package/dist/solana/index.js.map +3 -3
  35. package/dist/substrate/index.cjs +2 -2
  36. package/dist/substrate/index.cjs.map +5 -6
  37. package/dist/substrate/index.js +2 -2
  38. package/dist/substrate/index.js.map +5 -6
  39. package/dist/utxo/index.cjs +2 -2
  40. package/dist/utxo/index.cjs.map +9 -11
  41. package/dist/utxo/index.js +2 -2
  42. package/dist/utxo/index.js.map +9 -11
  43. package/package.json +27 -23
  44. package/src/cosmos/index.ts +2 -9
  45. package/src/cosmos/thorchainUtils/addressFormat.ts +1 -2
  46. package/src/cosmos/thorchainUtils/index.ts +1 -1
  47. package/src/cosmos/thorchainUtils/messages.ts +74 -56
  48. package/src/cosmos/thorchainUtils/registry.ts +19 -26
  49. package/src/cosmos/thorchainUtils/types/{proto/MsgCompiled.ts → MsgCompiled.ts} +1 -3
  50. package/src/cosmos/thorchainUtils/types/client-types.ts +16 -23
  51. package/src/cosmos/toolbox/cosmos.ts +334 -0
  52. package/src/cosmos/toolbox/index.ts +33 -0
  53. package/src/cosmos/toolbox/thorchain.ts +125 -137
  54. package/src/cosmos/types.ts +37 -18
  55. package/src/cosmos/util.ts +24 -74
  56. package/src/evm/__tests__/ethereum.test.ts +110 -116
  57. package/src/evm/api.ts +11 -147
  58. package/src/evm/helpers.ts +111 -83
  59. package/src/evm/index.ts +1 -17
  60. package/src/evm/toolbox/baseEVMToolbox.ts +744 -0
  61. package/src/evm/toolbox/evm.ts +69 -0
  62. package/src/evm/toolbox/index.ts +36 -0
  63. package/src/evm/toolbox/op.ts +97 -143
  64. package/src/evm/types.ts +50 -28
  65. package/src/index.ts +235 -0
  66. package/src/radix/index.ts +18 -19
  67. package/src/ripple/index.ts +199 -0
  68. package/src/solana/index.ts +11 -5
  69. package/src/solana/toolbox.ts +227 -137
  70. package/src/substrate/index.ts +2 -3
  71. package/src/substrate/{toolbox/baseSubstrateToolbox.ts → substrate.ts} +104 -72
  72. package/src/substrate/types.ts +120 -0
  73. package/src/utils.ts +27 -0
  74. package/src/utxo/helpers/api.ts +27 -23
  75. package/src/utxo/helpers/bchaddrjs.ts +21 -21
  76. package/src/utxo/helpers/index.ts +0 -1
  77. package/src/utxo/helpers/txSize.ts +3 -4
  78. package/src/utxo/index.ts +3 -7
  79. package/src/utxo/toolbox/bitcoinCash.ts +165 -155
  80. package/src/utxo/toolbox/index.ts +63 -24
  81. package/src/utxo/toolbox/utxo.ts +376 -229
  82. package/src/utxo/types.ts +26 -39
  83. package/src/cosmos/thorchainUtils/types/proto/MsgCompiled.js +0 -2806
  84. package/src/cosmos/thorchainUtils/util.ts +0 -46
  85. package/src/cosmos/toolbox/BaseCosmosToolbox.ts +0 -254
  86. package/src/cosmos/toolbox/gaia.ts +0 -39
  87. package/src/cosmos/toolbox/getToolboxByChain.ts +0 -29
  88. package/src/cosmos/toolbox/kujira.ts +0 -61
  89. package/src/evm/provider.ts +0 -6
  90. package/src/evm/toolbox/EVMToolbox.ts +0 -662
  91. package/src/evm/toolbox/arb.ts +0 -61
  92. package/src/evm/toolbox/avax.ts +0 -36
  93. package/src/evm/toolbox/base.ts +0 -42
  94. package/src/evm/toolbox/bsc.ts +0 -34
  95. package/src/evm/toolbox/eth.ts +0 -44
  96. package/src/evm/toolbox/getToolboxByChain.ts +0 -42
  97. package/src/evm/toolbox/matic.ts +0 -42
  98. package/src/radix/toolbox.ts +0 -693
  99. package/src/substrate/toolbox/index.ts +0 -40
  100. package/src/substrate/types/index.ts +0 -2
  101. package/src/substrate/types/network.ts +0 -42
  102. package/src/substrate/types/wallet.ts +0 -78
  103. 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
+ }
@@ -1,23 +1,20 @@
1
- import {
2
- type FungibleResourcesCollectionItem,
1
+ import type {
2
+ FungibleResourcesCollectionItem,
3
3
  GatewayApiClient,
4
- type StateEntityDetailsVaultResponseItem,
5
- type StateEntityFungiblesPageRequest,
6
- type StateEntityFungiblesPageResponse,
4
+ StateEntityDetailsVaultResponseItem,
5
+ StateEntityFungiblesPageRequest,
6
+ StateEntityFungiblesPageResponse,
7
7
  } from "@radixdlt/babylon-gateway-api-sdk";
8
- import { RadixDappToolkit } from "@radixdlt/radix-dapp-toolkit";
9
- import { AssetValue, Chain, type SKConfigIntegrations } from "@swapkit/helpers";
8
+ import { AssetValue, Chain, SKConfig, type SKConfigIntegrations } from "@swapkit/helpers";
10
9
 
11
- export type RadixWallets = {
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 validateAddress(address: string) {
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: SKConfigIntegrations["radix"] }) => {
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
- ...dappConfig,
135
- networkId: dappConfig.network?.networkId || 1,
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
- networkApi,
142
+ getAddress: () => "",
142
143
  getBalance: getBalance({ networkApi }),
143
- getAddress: () => {
144
- return "";
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
+ };
@@ -1,6 +1,6 @@
1
1
  import type { PublicKey, SendOptions, Transaction, VersionedTransaction } from "@solana/web3.js";
2
- import { Chain } from "@swapkit/helpers";
3
- import type { SOLToolbox } from "./toolbox";
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 SolanaWallets = {
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
+ };