@swapkit/toolboxes 1.0.0-beta.0 → 1.0.0-beta.2

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 +30 -24
  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 +16 -23
  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 +118 -131
  54. package/src/cosmos/types.ts +37 -18
  55. package/src/cosmos/util.ts +21 -71
  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 +742 -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 +203 -0
  68. package/src/solana/index.ts +11 -5
  69. package/src/solana/toolbox.ts +223 -133
  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 +164 -154
  80. package/src/utxo/toolbox/index.ts +63 -24
  81. package/src/utxo/toolbox/utxo.ts +376 -229
  82. package/src/utxo/types.ts +24 -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
@@ -1,16 +1,32 @@
1
- import type { TokenInfo } from "@solana/spl-token-registry";
2
- import type { Connection, Keypair, PublicKey, Transaction } from "@solana/web3.js";
1
+ import type {
2
+ Connection,
3
+ PublicKey,
4
+ Signer,
5
+ Transaction,
6
+ TransactionInstruction,
7
+ VersionedTransaction,
8
+ } from "@solana/web3.js";
3
9
  import {
4
10
  AssetValue,
11
+ BaseDecimal,
5
12
  Chain,
6
13
  DerivationPath,
14
+ type DerivationPathArray,
15
+ type GenericCreateTransactionParams,
16
+ NetworkDerivationPath,
7
17
  SKConfig,
8
18
  SwapKitError,
9
- SwapKitNumber,
10
- type WalletTxParams,
19
+ derivationPathToString,
20
+ updateDerivationPath,
11
21
  } from "@swapkit/helpers";
22
+ import { P } from "ts-pattern";
23
+ import { match } from "ts-pattern";
24
+ import type { SolanaCreateTransactionParams, SolanaProvider, SolanaTransferParams } from ".";
25
+ import { getBalance } from "../utils";
12
26
 
13
- export async function getAddressValidator() {
27
+ type SolanaSigner = SolanaProvider | Signer;
28
+
29
+ export async function getSolanaAddressValidator() {
14
30
  const { PublicKey } = await import("@solana/web3.js");
15
31
 
16
32
  return (address: string) => {
@@ -23,13 +39,132 @@ export async function getAddressValidator() {
23
39
  };
24
40
  }
25
41
 
26
- export async function createSolanaTokenTransaction({
42
+ export async function getSolanaToolbox(
43
+ toolboxParams?:
44
+ | { signer?: SolanaSigner }
45
+ | { phrase?: string; index?: number; derivationPath?: DerivationPathArray },
46
+ ) {
47
+ const index = toolboxParams && "index" in toolboxParams ? toolboxParams.index || 0 : 0;
48
+ const derivationPath = derivationPathToString(
49
+ toolboxParams && "derivationPath" in toolboxParams && toolboxParams.derivationPath
50
+ ? toolboxParams.derivationPath
51
+ : updateDerivationPath(NetworkDerivationPath[Chain.Solana], { index }),
52
+ );
53
+
54
+ const signer = await match(toolboxParams)
55
+ .with({ phrase: P.string }, ({ phrase }) => createKeysForPath({ phrase, derivationPath }))
56
+ .with({ signer: P.any }, ({ signer }) => signer)
57
+ .otherwise(() => undefined);
58
+
59
+ function getAddress() {
60
+ return signer?.publicKey ? getAddressFromPubKey(signer.publicKey) : "";
61
+ }
62
+
63
+ return {
64
+ getConnection,
65
+ getAddress,
66
+ createKeysForPath,
67
+ getAddressFromPubKey,
68
+ getPubkeyFromAddress,
69
+ createTransaction: createTransaction(getConnection),
70
+ createTransactionFromInstructions,
71
+ getBalance: getBalance(Chain.Solana),
72
+ transfer: transfer(getConnection, signer),
73
+ broadcastTransaction: broadcastTransaction(getConnection),
74
+ getAddressValidator: getSolanaAddressValidator,
75
+ signTransaction: signTransaction(getConnection, signer),
76
+ estimateTransactionFee: estimateTransactionFee(getConnection),
77
+ };
78
+ }
79
+
80
+ function estimateTransactionFee(getConnection: () => Promise<Connection>) {
81
+ return async ({
82
+ recipient,
83
+ assetValue,
84
+ memo,
85
+ isProgramDerivedAddress,
86
+ sender,
87
+ }: Omit<GenericCreateTransactionParams, "feeRate"> & {
88
+ isProgramDerivedAddress?: boolean;
89
+ }) => {
90
+ const connection = await getConnection();
91
+
92
+ const transaction = await createTransaction(getConnection)({
93
+ recipient,
94
+ assetValue,
95
+ memo,
96
+ isProgramDerivedAddress,
97
+ sender,
98
+ });
99
+
100
+ const message = transaction.compileMessage();
101
+ const feeInLamports = await connection.getFeeForMessage(message);
102
+
103
+ if (feeInLamports.value === null) {
104
+ throw new SwapKitError(
105
+ "toolbox_solana_fee_estimation_failed",
106
+ "Could not estimate Solana fee.",
107
+ );
108
+ }
109
+
110
+ return AssetValue.from({
111
+ chain: Chain.Solana,
112
+ value: feeInLamports.value,
113
+ fromBaseDecimal: BaseDecimal[Chain.Solana],
114
+ });
115
+ };
116
+ }
117
+
118
+ async function getConnection() {
119
+ const { Connection } = await import("@solana/web3.js");
120
+ return new Connection(SKConfig.get("rpcUrls").SOL, "confirmed");
121
+ }
122
+
123
+ function createAssetTransaction(getConnection: () => Promise<Connection>) {
124
+ return async ({
125
+ assetValue,
126
+ recipient,
127
+ sender,
128
+ isProgramDerivedAddress,
129
+ }: SolanaCreateTransactionParams) => {
130
+ const connection = await getConnection();
131
+ const fromPubkey = await getPubkeyFromAddress(sender);
132
+
133
+ if (assetValue.isGasAsset) {
134
+ const { Transaction, SystemProgram, PublicKey } = await import("@solana/web3.js");
135
+
136
+ return new Transaction().add(
137
+ SystemProgram.transfer({
138
+ fromPubkey: fromPubkey,
139
+ lamports: assetValue.getBaseValue("number"),
140
+ toPubkey: new PublicKey(recipient),
141
+ }),
142
+ );
143
+ }
144
+ if (assetValue.address) {
145
+ return createSolanaTokenTransaction({
146
+ amount: assetValue.getBaseValue("number"),
147
+ connection,
148
+ decimals: assetValue.decimal as number,
149
+ from: fromPubkey,
150
+ recipient,
151
+ tokenAddress: assetValue.address,
152
+ isProgramDerivedAddress,
153
+ });
154
+ }
155
+
156
+ return undefined;
157
+ };
158
+ }
159
+
160
+ async function createSolanaTokenTransaction({
27
161
  tokenAddress,
28
162
  recipient,
29
163
  from,
30
164
  connection,
31
165
  amount,
32
166
  decimals,
167
+ isProgramDerivedAddress,
33
168
  }: {
34
169
  tokenAddress: string;
35
170
  recipient: string;
@@ -37,6 +172,7 @@ export async function createSolanaTokenTransaction({
37
172
  connection: Connection;
38
173
  amount: number;
39
174
  decimals: number;
175
+ isProgramDerivedAddress?: boolean;
40
176
  }) {
41
177
  const {
42
178
  getAssociatedTokenAddress,
@@ -51,7 +187,11 @@ export async function createSolanaTokenTransaction({
51
187
  const fromSPLAddress = await getAssociatedTokenAddress(tokenPublicKey, from);
52
188
 
53
189
  const recipientPublicKey = new PublicKey(recipient);
54
- const recipientSPLAddress = await getAssociatedTokenAddress(tokenPublicKey, recipientPublicKey);
190
+ const recipientSPLAddress = await getAssociatedTokenAddress(
191
+ tokenPublicKey,
192
+ recipientPublicKey,
193
+ isProgramDerivedAddress,
194
+ );
55
195
 
56
196
  let recipientAccountExists = false;
57
197
  try {
@@ -86,64 +226,30 @@ export async function createSolanaTokenTransaction({
86
226
  return transaction;
87
227
  }
88
228
 
89
- export const SOLToolbox = () => {
90
- async function getConnection() {
91
- const { Connection } = await import("@solana/web3.js");
92
- return new Connection(SKConfig.get("rpcUrls").SOL, "confirmed");
93
- }
94
-
95
- return {
96
- getConnection,
97
- createKeysForPath,
98
- getAddressFromKeys,
99
- createSolanaTransaction: createSolanaTransaction(getConnection),
100
- getBalance: getBalance(getConnection),
101
- transfer: transfer(getConnection),
102
- broadcastTransaction: broadcastTransaction(getConnection),
103
- getAddressValidator,
104
- };
105
- };
106
-
107
- function createSolanaTransaction(getConnection: () => Promise<Connection>) {
229
+ function createTransaction(getConnection: () => Promise<Connection>) {
108
230
  return async ({
109
231
  recipient,
110
232
  assetValue,
111
- fromPublicKey,
112
233
  memo,
113
234
  isProgramDerivedAddress,
114
- }: WalletTxParams & {
115
- assetValue: AssetValue;
116
- fromPublicKey: PublicKey;
117
- isProgramDerivedAddress?: boolean;
118
- }) => {
235
+ sender,
236
+ }: SolanaCreateTransactionParams) => {
119
237
  const { createMemoInstruction } = await import("@solana/spl-memo");
120
- const { Transaction, PublicKey, SystemProgram } = await import("@solana/web3.js");
121
- const validateAddress = await getAddressValidator();
238
+
239
+ const fromPubkey = await getPubkeyFromAddress(sender);
240
+ const validateAddress = await getSolanaAddressValidator();
122
241
 
123
242
  if (!(isProgramDerivedAddress || validateAddress(recipient))) {
124
243
  throw new SwapKitError("core_transaction_invalid_recipient_address");
125
244
  }
126
245
 
127
246
  const connection = await getConnection();
128
-
129
- const transaction = assetValue.isGasAsset
130
- ? new Transaction().add(
131
- SystemProgram.transfer({
132
- fromPubkey: fromPublicKey,
133
- lamports: assetValue.getBaseValue("number"),
134
- toPubkey: new PublicKey(recipient),
135
- }),
136
- )
137
- : assetValue.address
138
- ? await createSolanaTokenTransaction({
139
- amount: assetValue.getBaseValue("number"),
140
- connection,
141
- decimals: assetValue.decimal as number,
142
- from: fromPublicKey,
143
- recipient,
144
- tokenAddress: assetValue.address,
145
- })
146
- : undefined;
247
+ const transaction = await createAssetTransaction(getConnection)({
248
+ assetValue,
249
+ recipient,
250
+ sender,
251
+ isProgramDerivedAddress,
252
+ });
147
253
 
148
254
  if (!transaction) {
149
255
  throw new SwapKitError("core_transaction_invalid_sender_address");
@@ -153,47 +259,87 @@ function createSolanaTransaction(getConnection: () => Promise<Connection>) {
153
259
 
154
260
  const blockHash = await connection.getLatestBlockhash();
155
261
  transaction.recentBlockhash = blockHash.blockhash;
156
- transaction.feePayer = fromPublicKey;
262
+ transaction.feePayer = fromPubkey;
157
263
 
158
264
  return transaction;
159
265
  };
160
266
  }
161
267
 
162
- function transfer(getConnection: () => Promise<Connection>) {
163
- return async ({
164
- recipient,
165
- assetValue,
166
- fromKeypair,
167
- memo,
168
- isProgramDerivedAddress,
169
- }: WalletTxParams & {
170
- assetValue: AssetValue;
171
- fromKeypair: Keypair;
172
- isProgramDerivedAddress?: boolean;
173
- }) => {
174
- const { sendAndConfirmTransaction } = await import("@solana/web3.js");
175
- const connection = await getConnection();
268
+ async function createTransactionFromInstructions({
269
+ instructions,
270
+ }: { instructions: TransactionInstruction[]; isProgramDerivedAddress?: boolean }) {
271
+ const { Transaction } = await import("@solana/web3.js");
272
+ const transaction = new Transaction().add(...instructions);
273
+
274
+ if (!transaction) {
275
+ throw new SwapKitError("core_transaction_invalid_sender_address");
276
+ }
277
+
278
+ return transaction;
279
+ }
280
+
281
+ function transfer(getConnection: () => Promise<Connection>, signer?: SolanaSigner) {
282
+ return async ({ recipient, assetValue, memo, isProgramDerivedAddress }: SolanaTransferParams) => {
283
+ if (!signer) {
284
+ throw new SwapKitError("core_transaction_invalid_sender_address");
285
+ }
286
+
287
+ const sender =
288
+ signer.publicKey?.toString() ??
289
+ (await (signer as SolanaProvider).connect()).publicKey.toString();
176
290
 
177
- const transaction = await createSolanaTransaction(getConnection)({
291
+ const transaction = await createTransaction(getConnection)({
178
292
  recipient,
179
293
  assetValue,
180
294
  memo,
181
- fromPublicKey: fromKeypair.publicKey,
182
295
  isProgramDerivedAddress,
296
+ sender,
183
297
  });
184
298
 
185
- return sendAndConfirmTransaction(connection, transaction, [fromKeypair]);
299
+ if ("connect" in signer) {
300
+ const signedTransaction = await signer.signTransaction(transaction);
301
+ return broadcastTransaction(getConnection)(signedTransaction);
302
+ }
303
+
304
+ transaction.sign(signer);
305
+
306
+ return broadcastTransaction(getConnection)(transaction);
186
307
  };
187
308
  }
188
309
 
189
310
  function broadcastTransaction(getConnection: () => Promise<Connection>) {
190
- return async (transaction: Transaction) => {
311
+ return async (transaction: Transaction | VersionedTransaction) => {
191
312
  const connection = await getConnection();
192
313
  return connection.sendRawTransaction(transaction.serialize());
193
314
  };
194
315
  }
195
316
 
196
- async function createKeysForPath({
317
+ function signTransaction(getConnection: () => Promise<Connection>, signer?: SolanaSigner) {
318
+ return async (transaction: Transaction | VersionedTransaction) => {
319
+ const { VersionedTransaction } = await import("@solana/web3.js");
320
+ if (!signer) {
321
+ throw new SwapKitError("toolbox_solana_no_signer");
322
+ }
323
+
324
+ if (!(transaction instanceof VersionedTransaction)) {
325
+ const connection = await getConnection();
326
+
327
+ const blockHash = await connection.getLatestBlockhash();
328
+ transaction.recentBlockhash = blockHash.blockhash;
329
+ transaction.feePayer = signer.publicKey || undefined;
330
+ }
331
+
332
+ if ("connect" in signer) {
333
+ const signedTransaction = await signer.signTransaction(transaction);
334
+ return signedTransaction;
335
+ }
336
+
337
+ await transaction.sign([signer] as Signer & Signer[]);
338
+ return transaction;
339
+ };
340
+ }
341
+
342
+ export async function createKeysForPath({
197
343
  phrase,
198
344
  derivationPath = DerivationPath.SOL,
199
345
  }: { phrase: string; derivationPath?: string }) {
@@ -206,67 +352,11 @@ async function createKeysForPath({
206
352
  return Keypair.fromSeed(hdKey.derive(derivationPath, true).privateKey);
207
353
  }
208
354
 
209
- function getAddressFromKeys(keypair: Keypair) {
210
- return keypair.publicKey.toString();
355
+ function getAddressFromPubKey(publicKey: PublicKey) {
356
+ return publicKey.toString();
211
357
  }
212
358
 
213
- async function getTokenBalances({
214
- connection,
215
- address,
216
- }: { connection: Connection; address: string }) {
359
+ async function getPubkeyFromAddress(address: string) {
217
360
  const { PublicKey } = await import("@solana/web3.js");
218
- const { TOKEN_PROGRAM_ID } = await import("@solana/spl-token");
219
- const { TokenListProvider } = await import("@solana/spl-token-registry");
220
-
221
- const tokenAccounts = await connection.getParsedTokenAccountsByOwner(new PublicKey(address), {
222
- programId: TOKEN_PROGRAM_ID,
223
- });
224
- const tokenListProvider = new TokenListProvider();
225
- const tokenListContainer = await tokenListProvider.resolve();
226
- const tokenList = tokenListContainer.filterByChainId(101).getList();
227
-
228
- // Group token balances by mint address
229
- const tokenBalanceMap = new Map<string, { amount: bigint; decimal: number; symbol: string }>();
230
-
231
- for await (const tokenAccountInfo of tokenAccounts.value) {
232
- const accountInfo = tokenAccountInfo.account.data.parsed.info;
233
- const mintAddress = accountInfo.mint;
234
- const decimal = accountInfo.tokenAmount.decimals;
235
- const amount = BigInt(accountInfo.tokenAmount.amount);
236
-
237
- if (amount <= BigInt(0)) continue;
238
-
239
- const tokenInfo = tokenList.find((token: TokenInfo) => token.address === mintAddress);
240
- const tokenSymbol = tokenInfo?.symbol ?? "UNKNOWN";
241
- const existing = tokenBalanceMap.get(mintAddress);
242
-
243
- tokenBalanceMap.set(mintAddress, {
244
- amount: existing ? existing.amount + amount : amount,
245
- decimal,
246
- symbol: tokenSymbol,
247
- });
248
- }
249
-
250
- // Convert grouped balances to AssetValue array
251
- const tokenBalances: AssetValue[] = Array.from(tokenBalanceMap.entries()).map(
252
- ([mintAddress, { amount, decimal, symbol }]) =>
253
- new AssetValue({
254
- value: SwapKitNumber.fromBigInt(amount, decimal),
255
- decimal,
256
- identifier: `${Chain.Solana}.${symbol}${mintAddress ? `-${mintAddress.toString()}` : ""}`,
257
- }),
258
- );
259
-
260
- return tokenBalances;
261
- }
262
-
263
- function getBalance(getConnection: () => Promise<Connection>) {
264
- return async (address: string) => {
265
- const { PublicKey } = await import("@solana/web3.js");
266
- const connection = await getConnection();
267
- const SOLBalance = await connection.getBalance(new PublicKey(address));
268
- const tokenBalances = await getTokenBalances({ connection, address });
269
-
270
- return [AssetValue.from({ chain: Chain.Solana, value: BigInt(SOLBalance) }), ...tokenBalances];
271
- };
361
+ return new PublicKey(address);
272
362
  }
@@ -1,3 +1,2 @@
1
- export * from "./toolbox/baseSubstrateToolbox";
2
- export * from "./toolbox";
3
- export * from "./types/index";
1
+ export * from "./substrate";
2
+ export * from "./types";