@uswap/toolboxes 4.3.7 → 4.3.9

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 (149) hide show
  1. package/dist/src/cardano/index.cjs +2 -2
  2. package/dist/src/cardano/index.cjs.map +3 -3
  3. package/dist/src/cardano/index.js +2 -2
  4. package/dist/src/cardano/index.js.map +3 -3
  5. package/dist/src/cosmos/index.cjs +2 -2
  6. package/dist/src/cosmos/index.cjs.map +8 -8
  7. package/dist/src/cosmos/index.js +2 -2
  8. package/dist/src/cosmos/index.js.map +8 -8
  9. package/dist/src/evm/index.cjs +2 -2
  10. package/dist/src/evm/index.cjs.map +7 -7
  11. package/dist/src/evm/index.js +2 -2
  12. package/dist/src/evm/index.js.map +7 -7
  13. package/dist/src/index.cjs +3 -3
  14. package/dist/src/index.cjs.map +34 -34
  15. package/dist/src/index.js +3 -3
  16. package/dist/src/index.js.map +34 -34
  17. package/dist/src/near/index.cjs +2 -2
  18. package/dist/src/near/index.cjs.map +5 -5
  19. package/dist/src/near/index.js +2 -2
  20. package/dist/src/near/index.js.map +5 -5
  21. package/dist/src/radix/index.cjs +2 -2
  22. package/dist/src/radix/index.cjs.map +3 -3
  23. package/dist/src/radix/index.js +2 -2
  24. package/dist/src/radix/index.js.map +3 -3
  25. package/dist/src/ripple/index.cjs +2 -2
  26. package/dist/src/ripple/index.cjs.map +3 -3
  27. package/dist/src/ripple/index.js +2 -2
  28. package/dist/src/ripple/index.js.map +3 -3
  29. package/dist/src/solana/index.cjs +2 -2
  30. package/dist/src/solana/index.cjs.map +3 -3
  31. package/dist/src/solana/index.js +2 -2
  32. package/dist/src/solana/index.js.map +3 -3
  33. package/dist/src/substrate/index.cjs +2 -2
  34. package/dist/src/substrate/index.cjs.map +4 -4
  35. package/dist/src/substrate/index.js +2 -2
  36. package/dist/src/substrate/index.js.map +4 -4
  37. package/dist/src/sui/index.cjs +2 -2
  38. package/dist/src/sui/index.cjs.map +3 -3
  39. package/dist/src/sui/index.js +2 -2
  40. package/dist/src/sui/index.js.map +3 -3
  41. package/dist/src/ton/index.cjs +2 -2
  42. package/dist/src/ton/index.cjs.map +3 -3
  43. package/dist/src/ton/index.js +2 -2
  44. package/dist/src/ton/index.js.map +3 -3
  45. package/dist/src/tron/index.cjs +2 -2
  46. package/dist/src/tron/index.cjs.map +4 -4
  47. package/dist/src/tron/index.js +2 -2
  48. package/dist/src/tron/index.js.map +4 -4
  49. package/dist/src/utxo/index.cjs +3 -3
  50. package/dist/src/utxo/index.cjs.map +11 -11
  51. package/dist/src/utxo/index.js +3 -3
  52. package/dist/src/utxo/index.js.map +11 -11
  53. package/dist/types/cardano/toolbox.d.ts +5 -0
  54. package/dist/types/cardano/toolbox.d.ts.map +1 -1
  55. package/dist/types/cosmos/thorchainUtils/addressFormat.d.ts +5 -0
  56. package/dist/types/cosmos/thorchainUtils/addressFormat.d.ts.map +1 -1
  57. package/dist/types/cosmos/thorchainUtils/messages.d.ts +5 -0
  58. package/dist/types/cosmos/thorchainUtils/messages.d.ts.map +1 -1
  59. package/dist/types/cosmos/toolbox/cosmos.d.ts +5 -0
  60. package/dist/types/cosmos/toolbox/cosmos.d.ts.map +1 -1
  61. package/dist/types/cosmos/toolbox/index.d.ts +5 -0
  62. package/dist/types/cosmos/toolbox/index.d.ts.map +1 -1
  63. package/dist/types/cosmos/toolbox/thorchain.d.ts +5 -0
  64. package/dist/types/cosmos/toolbox/thorchain.d.ts.map +1 -1
  65. package/dist/types/cosmos/util.d.ts +5 -0
  66. package/dist/types/cosmos/util.d.ts.map +1 -1
  67. package/dist/types/evm/helpers.d.ts +1 -1
  68. package/dist/types/evm/helpers.d.ts.map +1 -1
  69. package/dist/types/evm/toolbox/baseEVMToolbox.d.ts +7 -0
  70. package/dist/types/evm/toolbox/baseEVMToolbox.d.ts.map +1 -1
  71. package/dist/types/evm/toolbox/evm.d.ts +38 -38
  72. package/dist/types/evm/toolbox/evm.d.ts.map +1 -1
  73. package/dist/types/evm/toolbox/op.d.ts +7 -14
  74. package/dist/types/evm/toolbox/op.d.ts.map +1 -1
  75. package/dist/types/index.d.ts +5 -0
  76. package/dist/types/index.d.ts.map +1 -1
  77. package/dist/types/near/helpers/core.d.ts +5 -0
  78. package/dist/types/near/helpers/core.d.ts.map +1 -1
  79. package/dist/types/near/toolbox.d.ts +5 -0
  80. package/dist/types/near/toolbox.d.ts.map +1 -1
  81. package/dist/types/radix/index.d.ts +5 -0
  82. package/dist/types/radix/index.d.ts.map +1 -1
  83. package/dist/types/ripple/index.d.ts +5 -0
  84. package/dist/types/ripple/index.d.ts.map +1 -1
  85. package/dist/types/solana/toolbox.d.ts +5 -0
  86. package/dist/types/solana/toolbox.d.ts.map +1 -1
  87. package/dist/types/substrate/substrate.d.ts +5 -0
  88. package/dist/types/substrate/substrate.d.ts.map +1 -1
  89. package/dist/types/sui/toolbox.d.ts +5 -0
  90. package/dist/types/sui/toolbox.d.ts.map +1 -1
  91. package/dist/types/ton/toolbox.d.ts +5 -0
  92. package/dist/types/ton/toolbox.d.ts.map +1 -1
  93. package/dist/types/tron/helpers/trongrid.d.ts +5 -0
  94. package/dist/types/tron/helpers/trongrid.d.ts.map +1 -1
  95. package/dist/types/tron/toolbox.d.ts +5 -0
  96. package/dist/types/tron/toolbox.d.ts.map +1 -1
  97. package/dist/types/utils.d.ts.map +1 -1
  98. package/dist/types/utxo/helpers/api.d.ts +5 -0
  99. package/dist/types/utxo/helpers/api.d.ts.map +1 -1
  100. package/dist/types/utxo/helpers/bchaddrjs.d.ts +5 -0
  101. package/dist/types/utxo/helpers/bchaddrjs.d.ts.map +1 -1
  102. package/dist/types/utxo/helpers/coinselect.d.ts +5 -0
  103. package/dist/types/utxo/helpers/coinselect.d.ts.map +1 -1
  104. package/dist/types/utxo/helpers/txSize.d.ts +5 -0
  105. package/dist/types/utxo/helpers/txSize.d.ts.map +1 -1
  106. package/dist/types/utxo/toolbox/bitcoinCash.d.ts +5 -0
  107. package/dist/types/utxo/toolbox/bitcoinCash.d.ts.map +1 -1
  108. package/dist/types/utxo/toolbox/index.d.ts +5 -0
  109. package/dist/types/utxo/toolbox/index.d.ts.map +1 -1
  110. package/dist/types/utxo/toolbox/utxo.d.ts +5 -0
  111. package/dist/types/utxo/toolbox/utxo.d.ts.map +1 -1
  112. package/dist/types/utxo/toolbox/zcash.d.ts +6 -1
  113. package/dist/types/utxo/toolbox/zcash.d.ts.map +1 -1
  114. package/package.json +4 -4
  115. package/src/cardano/toolbox.ts +12 -6
  116. package/src/cosmos/__tests__/toolbox.test.ts +8 -4
  117. package/src/cosmos/thorchainUtils/addressFormat.ts +8 -2
  118. package/src/cosmos/thorchainUtils/messages.ts +8 -2
  119. package/src/cosmos/toolbox/cosmos.ts +11 -5
  120. package/src/cosmos/toolbox/index.ts +8 -2
  121. package/src/cosmos/toolbox/thorchain.ts +9 -3
  122. package/src/cosmos/util.ts +9 -3
  123. package/src/evm/helpers.ts +7 -9
  124. package/src/evm/toolbox/baseEVMToolbox.ts +34 -26
  125. package/src/evm/toolbox/evm.ts +2 -3
  126. package/src/evm/toolbox/op.ts +10 -17
  127. package/src/index.ts +8 -2
  128. package/src/near/helpers/core.ts +8 -2
  129. package/src/near/toolbox.ts +21 -15
  130. package/src/radix/index.ts +15 -3
  131. package/src/ripple/index.ts +15 -12
  132. package/src/solana/toolbox.ts +16 -16
  133. package/src/substrate/balance.ts +2 -2
  134. package/src/substrate/substrate.ts +17 -11
  135. package/src/sui/__tests__/toolbox.test.ts +9 -5
  136. package/src/sui/toolbox.ts +18 -11
  137. package/src/ton/__tests__/toolbox.test.ts +9 -5
  138. package/src/ton/toolbox.ts +14 -8
  139. package/src/tron/helpers/trongrid.ts +8 -2
  140. package/src/tron/toolbox.ts +21 -15
  141. package/src/utils.ts +8 -1
  142. package/src/utxo/helpers/api.ts +15 -9
  143. package/src/utxo/helpers/bchaddrjs.ts +9 -3
  144. package/src/utxo/helpers/coinselect.ts +8 -2
  145. package/src/utxo/helpers/txSize.ts +8 -2
  146. package/src/utxo/toolbox/bitcoinCash.ts +13 -7
  147. package/src/utxo/toolbox/index.ts +8 -2
  148. package/src/utxo/toolbox/utxo.ts +16 -10
  149. package/src/utxo/toolbox/zcash.ts +24 -21
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Based on code from SwapKit (https://github.com/swapkit/SwapKit),
3
+ * licensed under the Apache License 2.0.
4
+ * Modifications © 2025 Horizontal Systems.
5
+ */
6
+
1
7
  import type {
2
8
  Connection,
3
9
  PublicKey,
@@ -16,7 +22,7 @@ import {
16
22
  getChainConfig,
17
23
  getRPCUrl,
18
24
  NetworkDerivationPath,
19
- SwapKitError,
25
+ USwapError,
20
26
  updateDerivationPath,
21
27
  } from "@uswap/helpers";
22
28
  import { match, P } from "ts-pattern";
@@ -67,17 +73,11 @@ async function getSolanaBalance(address: string) {
67
73
  const { PublicKey } = await import("@solana/web3.js");
68
74
  const { TOKEN_PROGRAM_ID } = await import("@solana/spl-token");
69
75
  const publicKey = new PublicKey(address);
76
+ const { baseDecimal } = getChainConfig(Chain.Solana);
70
77
 
71
- const balances: AssetValue[] = [];
72
-
73
- // Get SOL balance
74
78
  const solBalance = await connection.getBalance(publicKey);
75
- if (solBalance > 0) {
76
- const { baseDecimal } = getChainConfig(Chain.Solana);
77
- balances.push(AssetValue.from({ chain: Chain.Solana, fromBaseDecimal: baseDecimal, value: solBalance }));
78
- }
79
+ const balances = [AssetValue.from({ chain: Chain.Solana, fromBaseDecimal: baseDecimal, value: solBalance || 0 })];
79
80
 
80
- // Get token balances
81
81
  const tokenAccounts = await connection.getParsedTokenAccountsByOwner(publicKey, { programId: TOKEN_PROGRAM_ID });
82
82
 
83
83
  for (const { account } of tokenAccounts.value) {
@@ -133,7 +133,7 @@ export async function getSolanaToolbox(
133
133
 
134
134
  function getBalance(addressParam?: string) {
135
135
  const address = addressParam || getAddress();
136
- if (!address) throw new SwapKitError("core_wallet_connection_not_found");
136
+ if (!address) throw new USwapError("core_wallet_connection_not_found");
137
137
  return getSolanaBalance(address);
138
138
  }
139
139
 
@@ -176,7 +176,7 @@ function estimateTransactionFee(getConnection: () => Promise<Connection>) {
176
176
  const feeInLamports = await connection.getFeeForMessage(message);
177
177
 
178
178
  if (feeInLamports.value === null) {
179
- throw new SwapKitError("toolbox_solana_fee_estimation_failed", "Could not estimate Solana fee.");
179
+ throw new USwapError("toolbox_solana_fee_estimation_failed", "Could not estimate Solana fee.");
180
180
  }
181
181
 
182
182
  const { baseDecimal } = getChainConfig(Chain.Solana);
@@ -289,7 +289,7 @@ function createTransaction(getConnection: () => Promise<Connection>) {
289
289
  const validateAddress = await getSolanaAddressValidator();
290
290
 
291
291
  if (!(isProgramDerivedAddress || validateAddress(recipient))) {
292
- throw new SwapKitError("core_transaction_invalid_recipient_address");
292
+ throw new USwapError("core_transaction_invalid_recipient_address");
293
293
  }
294
294
 
295
295
  const connection = await getConnection();
@@ -301,7 +301,7 @@ function createTransaction(getConnection: () => Promise<Connection>) {
301
301
  });
302
302
 
303
303
  if (!transaction) {
304
- throw new SwapKitError("core_transaction_invalid_sender_address");
304
+ throw new USwapError("core_transaction_invalid_sender_address");
305
305
  }
306
306
 
307
307
  if (memo) transaction.add(createMemoInstruction(memo));
@@ -324,7 +324,7 @@ async function createTransactionFromInstructions({
324
324
  const transaction = new Transaction().add(...instructions);
325
325
 
326
326
  if (!transaction) {
327
- throw new SwapKitError("core_transaction_invalid_sender_address");
327
+ throw new USwapError("core_transaction_invalid_sender_address");
328
328
  }
329
329
 
330
330
  return transaction;
@@ -333,7 +333,7 @@ async function createTransactionFromInstructions({
333
333
  function transfer(getConnection: () => Promise<Connection>, signer?: SolanaSigner) {
334
334
  return async ({ recipient, assetValue, memo, isProgramDerivedAddress }: SolanaTransferParams) => {
335
335
  if (!signer) {
336
- throw new SwapKitError("core_transaction_invalid_sender_address");
336
+ throw new USwapError("core_transaction_invalid_sender_address");
337
337
  }
338
338
 
339
339
  const sender = signer.publicKey?.toString() ?? (await (signer as SolanaProvider).connect()).publicKey.toString();
@@ -368,7 +368,7 @@ function signTransaction(getConnection: () => Promise<Connection>, signer?: Sola
368
368
  return async (transaction: Transaction | VersionedTransaction) => {
369
369
  const { VersionedTransaction } = await import("@solana/web3.js");
370
370
  if (!signer) {
371
- throw new SwapKitError("toolbox_solana_no_signer");
371
+ throw new USwapError("toolbox_solana_no_signer");
372
372
  }
373
373
 
374
374
  if (!(transaction instanceof VersionedTransaction)) {
@@ -29,7 +29,7 @@ export async function getSubstrateBalance(
29
29
  } catch (error) {
30
30
  const errorMessage = error instanceof Error ? error.message : String(error);
31
31
  console.error(`Error fetching substrate balance: ${errorMessage}`);
32
- return [];
32
+ return [gasAsset.set(0)];
33
33
  }
34
34
  }
35
35
 
@@ -66,7 +66,7 @@ export async function getChainflipBalance(
66
66
  } catch (error) {
67
67
  const errorMessage = error instanceof Error ? error.message : String(error);
68
68
  console.error(`Error fetching chainflip balance: ${errorMessage}`);
69
- return [];
69
+ return [gasAsset.set(0)];
70
70
  }
71
71
  }
72
72
 
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Based on code from SwapKit (https://github.com/swapkit/SwapKit),
3
+ * licensed under the Apache License 2.0.
4
+ * Modifications © 2025 Horizontal Systems.
5
+ */
6
+
1
7
  import type { ApiPromise } from "@polkadot/api";
2
8
  import type { SubmittableExtrinsic } from "@polkadot/api/types";
3
9
  import type { KeyringPair } from "@polkadot/keyring/types";
@@ -11,8 +17,8 @@ import {
11
17
  type GenericCreateTransactionParams,
12
18
  getRPCUrl,
13
19
  type SubstrateChain,
14
- SwapKitError,
15
20
  SwapKitNumber,
21
+ USwapError,
16
22
  } from "@uswap/helpers";
17
23
 
18
24
  import { match, P } from "ts-pattern";
@@ -43,7 +49,7 @@ export function getSubstrateToolbox<T extends SubstrateChain>(chain: T, params?:
43
49
  return PolkadotToolbox(params);
44
50
  }
45
51
  default:
46
- throw new SwapKitError("toolbox_substrate_not_supported", { chain });
52
+ throw new USwapError("toolbox_substrate_not_supported", { chain });
47
53
  }
48
54
  }
49
55
 
@@ -82,12 +88,12 @@ const transfer = async (
82
88
  { recipient, assetValue, sender }: SubstrateTransferParams,
83
89
  ) => {
84
90
  const transfer = createTransaction(api, { assetValue, recipient });
85
- if (!transfer) throw new SwapKitError("toolbox_substrate_transfer_error");
91
+ if (!transfer) throw new USwapError("toolbox_substrate_transfer_error");
86
92
 
87
93
  const isKeyring = isKeyringPair(signer);
88
94
 
89
95
  const address = isKeyring ? (signer as IKeyringPair).address : sender;
90
- if (!address) throw new SwapKitError("core_transaction_invalid_sender_address");
96
+ if (!address) throw new USwapError("core_transaction_invalid_sender_address");
91
97
 
92
98
  const nonce = await getNonce(api, address);
93
99
 
@@ -199,23 +205,23 @@ export const BaseSubstrateToolbox = ({
199
205
  decodeAddress,
200
206
  encodeAddress,
201
207
  estimateTransactionFee: (params: SubstrateTransferParams) => {
202
- if (!signer) throw new SwapKitError("core_wallet_not_keypair_wallet");
208
+ if (!signer) throw new USwapError("core_wallet_not_keypair_wallet");
203
209
  return estimateTransactionFee(api, signer, gasAsset, params);
204
210
  },
205
211
  gasAsset,
206
212
  getAddress: (keyring?: IKeyringPair | Signer) => {
207
213
  const keyringPair = keyring || signer;
208
- if (!keyringPair) throw new SwapKitError("core_wallet_not_keypair_wallet");
214
+ if (!keyringPair) throw new USwapError("core_wallet_not_keypair_wallet");
209
215
 
210
216
  return isKeyringPair(keyringPair) ? keyringPair.address : undefined;
211
217
  },
212
218
  getBalance: createBalanceGetter(chain || Chain.Polkadot, api),
213
219
  network,
214
220
  sign: (tx: SubmittableExtrinsic<"promise">) => {
215
- if (!signer) throw new SwapKitError("core_wallet_not_keypair_wallet");
221
+ if (!signer) throw new USwapError("core_wallet_not_keypair_wallet");
216
222
  if (isKeyringPair(signer)) return sign(signer, tx);
217
223
 
218
- throw new SwapKitError(
224
+ throw new USwapError(
219
225
  "core_wallet_not_keypair_wallet",
220
226
  "Signer does not have keyring pair capabilities required for signing.",
221
227
  );
@@ -229,20 +235,20 @@ export const BaseSubstrateToolbox = ({
229
235
  callback?: Callback<ISubmittableResult>;
230
236
  address?: string;
231
237
  }) => {
232
- if (!signer) throw new SwapKitError("core_wallet_not_keypair_wallet");
238
+ if (!signer) throw new USwapError("core_wallet_not_keypair_wallet");
233
239
  if (isKeyringPair(signer)) return signAndBroadcastKeyring(signer, tx, callback);
234
240
 
235
241
  if (address) {
236
242
  return signAndBroadcast({ address, api, callback, signer, tx });
237
243
  }
238
244
 
239
- throw new SwapKitError(
245
+ throw new USwapError(
240
246
  "core_wallet_not_keypair_wallet",
241
247
  "Signer does not have keyring pair capabilities required for signing.",
242
248
  );
243
249
  },
244
250
  transfer: (params: SubstrateTransferParams) => {
245
- if (!signer) throw new SwapKitError("core_wallet_not_keypair_wallet");
251
+ if (!signer) throw new USwapError("core_wallet_not_keypair_wallet");
246
252
  return transfer(api, signer, params);
247
253
  },
248
254
  validateAddress: (address: string) => validateAddress(address, network.prefix),
@@ -42,11 +42,15 @@ describe("Sui Toolbox", () => {
42
42
  }
43
43
  });
44
44
 
45
- test("should fetch balance for known address", async () => {
46
- const balances = await context.toolbox.getBalance(KNOWN_SUI_ADDRESS);
47
- expect(balances[0]?.chain).toBe(Chain.Sui);
48
- expect(balances[0]?.symbol).toBe("SUI");
49
- });
45
+ test(
46
+ "should fetch balance for known address",
47
+ async () => {
48
+ const balances = await context.toolbox.getBalance(KNOWN_SUI_ADDRESS);
49
+ expect(balances[0]?.chain).toBe(Chain.Sui);
50
+ expect(balances[0]?.symbol).toBe("SUI");
51
+ },
52
+ { retry: 3, timeout: 10000 },
53
+ );
50
54
 
51
55
  test("should estimate transaction fee", async () => {
52
56
  const fee = await context.toolbox.estimateTransactionFee();
@@ -1,4 +1,10 @@
1
- import { AssetValue, Chain, getChainConfig, SwapKitError } from "@uswap/helpers";
1
+ /**
2
+ * Based on code from SwapKit (https://github.com/swapkit/SwapKit),
3
+ * licensed under the Apache License 2.0.
4
+ * Modifications © 2025 Horizontal Systems.
5
+ */
6
+
7
+ import { AssetValue, Chain, getChainConfig, USwapError } from "@uswap/helpers";
2
8
  import { match, P } from "ts-pattern";
3
9
  import type { SuiCreateTransactionParams, SuiToolboxParams, SuiTransferParams } from "./types";
4
10
 
@@ -37,13 +43,14 @@ export async function getSuiToolbox({ provider: providerParam, ...signerParams }
37
43
  async function getBalance(targetAddress?: string) {
38
44
  const addressToQuery = targetAddress || getAddress();
39
45
  if (!addressToQuery) {
40
- throw new SwapKitError("toolbox_sui_address_required" as any);
46
+ throw new USwapError("toolbox_sui_address_required" as any);
41
47
  }
42
48
 
49
+ const { baseDecimal: fromBaseDecimal, chain } = getChainConfig(Chain.Sui);
50
+
43
51
  try {
44
52
  const suiClient = await getSuiClient();
45
53
  const { totalBalance } = await suiClient.getBalance({ owner: addressToQuery });
46
- const { baseDecimal: fromBaseDecimal, chain } = getChainConfig(Chain.Sui);
47
54
 
48
55
  const suiBalances = [AssetValue.from({ chain, fromBaseDecimal, value: totalBalance })];
49
56
 
@@ -60,8 +67,8 @@ export async function getSuiToolbox({ provider: providerParam, ...signerParams }
60
67
  }
61
68
 
62
69
  return suiBalances;
63
- } catch (error) {
64
- throw new SwapKitError("toolbox_sui_balance_error" as any, { error });
70
+ } catch {
71
+ return [AssetValue.from({ chain })];
65
72
  }
66
73
  }
67
74
 
@@ -93,7 +100,7 @@ export async function getSuiToolbox({ provider: providerParam, ...signerParams }
93
100
  const senderAddress = sender || getAddress();
94
101
 
95
102
  if (!senderAddress) {
96
- throw new SwapKitError("toolbox_sui_no_sender");
103
+ throw new USwapError("toolbox_sui_no_sender");
97
104
  }
98
105
 
99
106
  try {
@@ -104,7 +111,7 @@ export async function getSuiToolbox({ provider: providerParam, ...signerParams }
104
111
  const [suiCoin] = tx.splitCoins(tx.gas, [assetValue.getBaseValue("string")]);
105
112
  tx.transferObjects([suiCoin], recipient);
106
113
  } else {
107
- throw new SwapKitError("toolbox_sui_custom_token_transfer_not_implemented" as any);
114
+ throw new USwapError("toolbox_sui_custom_token_transfer_not_implemented" as any);
108
115
  }
109
116
 
110
117
  if (gasBudget) {
@@ -116,7 +123,7 @@ export async function getSuiToolbox({ provider: providerParam, ...signerParams }
116
123
 
117
124
  return { tx, txBytes };
118
125
  } catch (error) {
119
- throw new SwapKitError("toolbox_sui_transaction_creation_error" as any, { error });
126
+ throw new USwapError("toolbox_sui_transaction_creation_error" as any, { error });
120
127
  }
121
128
  }
122
129
 
@@ -124,7 +131,7 @@ export async function getSuiToolbox({ provider: providerParam, ...signerParams }
124
131
  params: Uint8Array<ArrayBuffer> | SuiCreateTransactionParams | Awaited<ReturnType<typeof createTransaction>>,
125
132
  ) {
126
133
  if (!signer) {
127
- throw new SwapKitError("toolbox_sui_no_signer");
134
+ throw new USwapError("toolbox_sui_no_signer");
128
135
  }
129
136
 
130
137
  if (params instanceof Uint8Array) {
@@ -138,12 +145,12 @@ export async function getSuiToolbox({ provider: providerParam, ...signerParams }
138
145
 
139
146
  async function transfer({ assetValue, gasBudget, recipient }: SuiTransferParams) {
140
147
  if (!signer) {
141
- throw new SwapKitError("toolbox_sui_no_signer" as any);
148
+ throw new USwapError("toolbox_sui_no_signer" as any);
142
149
  }
143
150
 
144
151
  const sender = signer.toSuiAddress() || getAddress();
145
152
  if (!sender) {
146
- throw new SwapKitError("toolbox_sui_no_sender");
153
+ throw new USwapError("toolbox_sui_no_sender");
147
154
  }
148
155
 
149
156
  const { txBytes } = await createTransaction({ assetValue, gasBudget, recipient, sender });
@@ -39,11 +39,15 @@ describe("TON Toolbox", () => {
39
39
  expect(context.toolbox.validateAddress(address)).toBe(true);
40
40
  });
41
41
 
42
- test("should fetch balance for known address", async () => {
43
- const balances = await context.toolbox.getBalance(KNOWN_TON_ADDRESS);
44
- expect(balances[0]?.chain).toBe(Chain.Ton);
45
- expect(balances[0]?.symbol).toBe("TON");
46
- });
42
+ test(
43
+ "should fetch balance for known address",
44
+ async () => {
45
+ const balances = await context.toolbox.getBalance(KNOWN_TON_ADDRESS);
46
+ expect(balances[0]?.chain).toBe(Chain.Ton);
47
+ expect(balances[0]?.symbol).toBe("TON");
48
+ },
49
+ { retry: 3, timeout: 10000 },
50
+ );
47
51
 
48
52
  test("should estimate transaction fee", async () => {
49
53
  const fee = await context.toolbox.estimateTransactionFee();
@@ -1,5 +1,11 @@
1
+ /**
2
+ * Based on code from SwapKit (https://github.com/swapkit/SwapKit),
3
+ * licensed under the Apache License 2.0.
4
+ * Modifications © 2025 Horizontal Systems.
5
+ */
6
+
1
7
  import type { Cell, OpenedContract, TonClient, WalletContractV4 } from "@ton/ton";
2
- import { AssetValue, Chain, getChainConfig, SwapKitError, SwapKitNumber } from "@uswap/helpers";
8
+ import { AssetValue, Chain, getChainConfig, SwapKitNumber, USwapError } from "@uswap/helpers";
3
9
  import { match, P } from "ts-pattern";
4
10
 
5
11
  import type { TONSigner, TONToolboxParams, TONTransferParams } from "./types";
@@ -33,7 +39,7 @@ export async function getTONToolbox(toolboxParams: TONToolboxParams = {}) {
33
39
  const walletSigner = paramSigner || signer;
34
40
 
35
41
  if (!walletSigner) {
36
- throw new SwapKitError("core_wallet_connection_not_found");
42
+ throw new USwapError("core_wallet_connection_not_found");
37
43
  }
38
44
 
39
45
  const walletContract = WalletContractV4.create({ publicKey: walletSigner.publicKey, workchain: 0 });
@@ -52,15 +58,15 @@ export async function getTONToolbox(toolboxParams: TONToolboxParams = {}) {
52
58
  try {
53
59
  const balance = await client.getBalance(Address.parse(address));
54
60
  return [AssetValue.from({ chain: Chain.Ton, value: SwapKitNumber.fromBigInt(balance, baseDecimal) })];
55
- } catch (error) {
56
- throw new SwapKitError("core_wallet_connection_not_found", { error });
61
+ } catch {
62
+ return [AssetValue.from({ chain: Chain.Ton })];
57
63
  }
58
64
  }
59
65
 
60
66
  async function createTransaction({ assetValue, recipient, memo }: TONTransferParams) {
61
67
  const wallet = getWallet();
62
68
  if (!wallet || !signer) {
63
- throw new SwapKitError("core_wallet_connection_not_found");
69
+ throw new USwapError("core_wallet_connection_not_found");
64
70
  }
65
71
 
66
72
  const { toNano, comment, internal } = await import("@ton/ton");
@@ -80,7 +86,7 @@ export async function getTONToolbox(toolboxParams: TONToolboxParams = {}) {
80
86
  async function transfer({ assetValue, recipient, memo }: TONTransferParams) {
81
87
  const wallet = getWallet();
82
88
  if (!wallet || !signer) {
83
- throw new SwapKitError("core_wallet_connection_not_found");
89
+ throw new USwapError("core_wallet_connection_not_found");
84
90
  }
85
91
 
86
92
  const transfer = await createTransaction({ assetValue, memo, recipient });
@@ -92,14 +98,14 @@ export async function getTONToolbox(toolboxParams: TONToolboxParams = {}) {
92
98
  async function sendTransaction(transferCell: Cell) {
93
99
  const wallet = getWallet();
94
100
  if (!wallet) {
95
- throw new SwapKitError("core_wallet_connection_not_found");
101
+ throw new USwapError("core_wallet_connection_not_found");
96
102
  }
97
103
 
98
104
  try {
99
105
  await wallet.send(transferCell);
100
106
  return transferCell.hash().toString("hex");
101
107
  } catch (error) {
102
- throw new SwapKitError("core_wallet_connection_not_found", { error });
108
+ throw new USwapError("core_wallet_connection_not_found", { error });
103
109
  }
104
110
  }
105
111
 
@@ -1,4 +1,10 @@
1
- import { SwapKitError } from "@uswap/helpers";
1
+ /**
2
+ * Based on code from SwapKit (https://github.com/swapkit/SwapKit),
3
+ * licensed under the Apache License 2.0.
4
+ * Modifications © 2025 Horizontal Systems.
5
+ */
6
+
7
+ import { USwapError } from "@uswap/helpers";
2
8
  import type { TronGridAccountResponse } from "../types";
3
9
 
4
10
  const TRONGRID_API_BASE = "https://api.trongrid.io";
@@ -45,7 +51,7 @@ export async function fetchAccountFromTronGrid(address: string) {
45
51
  // Return simplified object with balance and trc20 array
46
52
  return { balance: account.balance, trc20: account.trc20 || [] };
47
53
  } catch (error) {
48
- throw new SwapKitError("toolbox_tron_trongrid_api_error", {
54
+ throw new USwapError("toolbox_tron_trongrid_api_error", {
49
55
  address,
50
56
  message: error instanceof Error ? error.message : "Unknown error",
51
57
  });
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Based on code from SwapKit (https://github.com/swapkit/SwapKit),
3
+ * licensed under the Apache License 2.0.
4
+ * Modifications © 2025 Horizontal Systems.
5
+ */
6
+
1
7
  import {
2
8
  AssetValue,
3
9
  BaseDecimal,
@@ -5,7 +11,7 @@ import {
5
11
  derivationPathToString,
6
12
  getRPCUrl,
7
13
  NetworkDerivationPath,
8
- SwapKitError,
14
+ USwapError,
9
15
  updateDerivationPath,
10
16
  warnOnce,
11
17
  } from "@uswap/helpers";
@@ -65,7 +71,7 @@ export async function getTronPrivateKeyFromMnemonic({
65
71
  const derived = hdKey.derive(derivationPathToUse);
66
72
 
67
73
  if (!derived.privateKey) {
68
- throw new SwapKitError("toolbox_tron_no_signer");
74
+ throw new USwapError("toolbox_tron_no_signer");
69
75
  }
70
76
 
71
77
  return Buffer.from(derived.privateKey).toString("hex");
@@ -88,7 +94,7 @@ async function createKeysForPath({
88
94
  const derived = hdKey.derive(derivationPath);
89
95
 
90
96
  if (!derived.privateKey) {
91
- throw new SwapKitError("toolbox_tron_no_signer");
97
+ throw new USwapError("toolbox_tron_no_signer");
92
98
  }
93
99
 
94
100
  // Convert private key to hex string for TronWeb
@@ -147,7 +153,7 @@ export const createTronToolbox = async (
147
153
  .otherwise(() => Promise.resolve(undefined));
148
154
 
149
155
  const getAddress = async () => {
150
- if (!signer) throw new SwapKitError("toolbox_tron_no_signer");
156
+ if (!signer) throw new USwapError("toolbox_tron_no_signer");
151
157
  return await signer.getAddress();
152
158
  };
153
159
 
@@ -338,7 +344,7 @@ export const createTronToolbox = async (
338
344
  };
339
345
 
340
346
  const transfer = async ({ recipient, assetValue, memo, expiration }: TronTransferParams) => {
341
- if (!signer) throw new SwapKitError("toolbox_tron_no_signer");
347
+ if (!signer) throw new USwapError("toolbox_tron_no_signer");
342
348
 
343
349
  const from = await getAddress();
344
350
  tronWeb.setAddress(from);
@@ -348,7 +354,7 @@ export const createTronToolbox = async (
348
354
  const { txid } = await tronWeb.trx.sendRawTransaction(signedTx);
349
355
 
350
356
  if (!txid) {
351
- throw new SwapKitError("toolbox_tron_token_transfer_failed");
357
+ throw new USwapError("toolbox_tron_token_transfer_failed");
352
358
  }
353
359
 
354
360
  return txid;
@@ -422,7 +428,7 @@ export const createTronToolbox = async (
422
428
  }`,
423
429
  });
424
430
 
425
- throw new SwapKitError("toolbox_tron_fee_estimation_failed", { error });
431
+ throw new USwapError("toolbox_tron_fee_estimation_failed", { error });
426
432
  }
427
433
  };
428
434
 
@@ -464,7 +470,7 @@ export const createTronToolbox = async (
464
470
  tronWeb.setAddress(sender);
465
471
  const contractAddress = assetValue.address;
466
472
  if (!contractAddress) {
467
- throw new SwapKitError("toolbox_tron_invalid_token_identifier", { identifier: assetValue.toString() });
473
+ throw new USwapError("toolbox_tron_invalid_token_identifier", { identifier: assetValue.toString() });
468
474
  }
469
475
 
470
476
  try {
@@ -487,7 +493,7 @@ export const createTronToolbox = async (
487
493
  const txWithData = addTxData({ expiration, memo, transaction });
488
494
  return txWithData;
489
495
  } catch (error) {
490
- throw new SwapKitError("toolbox_tron_transaction_creation_failed", {
496
+ throw new USwapError("toolbox_tron_transaction_creation_failed", {
491
497
  message: "Failed to create TRC20 transaction.",
492
498
  originalError: error instanceof Error ? error.message : String(error),
493
499
  });
@@ -495,7 +501,7 @@ export const createTronToolbox = async (
495
501
  };
496
502
 
497
503
  const signTransaction = async (transaction: TronTransaction) => {
498
- if (!signer) throw new SwapKitError("toolbox_tron_no_signer");
504
+ if (!signer) throw new USwapError("toolbox_tron_no_signer");
499
505
  return await signer.signTransaction(transaction);
500
506
  };
501
507
 
@@ -509,14 +515,14 @@ export const createTronToolbox = async (
509
515
  const contract = tronWeb.contract(trc20ABI, assetAddress);
510
516
 
511
517
  if (!contract.methods?.allowance) {
512
- throw new SwapKitError("toolbox_tron_invalid_token_contract");
518
+ throw new USwapError("toolbox_tron_invalid_token_contract");
513
519
  }
514
520
 
515
521
  const [allowance] = await contract.methods.allowance(from, spenderAddress).call();
516
522
 
517
523
  return allowance ? (typeof allowance === "bigint" ? allowance : BigInt(allowance)) : 0n;
518
524
  } catch (error) {
519
- throw new SwapKitError("toolbox_tron_allowance_check_failed", { error });
525
+ throw new USwapError("toolbox_tron_allowance_check_failed", { error });
520
526
  }
521
527
  };
522
528
 
@@ -532,7 +538,7 @@ export const createTronToolbox = async (
532
538
  };
533
539
 
534
540
  const approve = async ({ assetAddress, spenderAddress, amount, from }: TronApproveParams) => {
535
- if (!signer) throw new SwapKitError("toolbox_tron_no_signer");
541
+ if (!signer) throw new USwapError("toolbox_tron_no_signer");
536
542
 
537
543
  const fromAddress = from || (await getAddress());
538
544
  const approvalAmount = amount !== undefined ? BigInt(amount).toString() : MAX_APPROVAL;
@@ -559,12 +565,12 @@ export const createTronToolbox = async (
559
565
  const { txid } = await tronWeb.trx.sendRawTransaction(signedTx);
560
566
 
561
567
  if (!txid) {
562
- throw new SwapKitError("toolbox_tron_approve_failed");
568
+ throw new USwapError("toolbox_tron_approve_failed");
563
569
  }
564
570
 
565
571
  return txid;
566
572
  } catch (error) {
567
- throw new SwapKitError("toolbox_tron_approve_failed", { error });
573
+ throw new USwapError("toolbox_tron_approve_failed", { error });
568
574
  }
569
575
  };
570
576
 
package/src/utils.ts CHANGED
@@ -20,8 +20,15 @@ export function getBalance<T extends Chain>(chain: T) {
20
20
  return async function getBalance(address: string, scamFilter = true) {
21
21
  const balances = await SwapKitApi.getChainBalance({ address, chain, scamFilter });
22
22
  const { baseDecimal } = getChainConfig(chain);
23
- return balances.map(({ identifier, value, decimal }) => {
23
+ const assetValues = balances.map(({ identifier, value, decimal }) => {
24
24
  return new AssetValue({ decimal: decimal || baseDecimal, identifier, value });
25
25
  });
26
+
27
+ const hasNativeAsset = assetValues.some((asset) => asset.isGasAsset);
28
+ if (!hasNativeAsset) {
29
+ return [AssetValue.from({ chain }), ...assetValues];
30
+ }
31
+
32
+ return assetValues;
26
33
  };
27
34
  }
@@ -1,5 +1,11 @@
1
+ /**
2
+ * Based on code from SwapKit (https://github.com/swapkit/SwapKit),
3
+ * licensed under the Apache License 2.0.
4
+ * Modifications © 2025 Horizontal Systems.
5
+ */
6
+
1
7
  import { networks as zcashNetworks } from "@bitgo/utxo-lib";
2
- import { Chain, getRPCUrl, RequestClient, SKConfig, SwapKitError, type UTXOChain, warnOnce } from "@uswap/helpers";
8
+ import { Chain, getRPCUrl, RequestClient, SKConfig, USwapError, type UTXOChain, warnOnce } from "@uswap/helpers";
3
9
  import { networks } from "bitcoinjs-lib";
4
10
  // @ts-expect-error
5
11
  import coininfo from "coininfo";
@@ -26,7 +32,7 @@ async function broadcastUTXOTx({ chain, txHash }: { chain: Chain; txHash: string
26
32
  }>(url, { body, headers: { "Content-Type": "application/json" } });
27
33
 
28
34
  if (response.context.code !== 200) {
29
- throw new SwapKitError("toolbox_utxo_broadcast_failed", {
35
+ throw new USwapError("toolbox_utxo_broadcast_failed", {
30
36
  error: response.context.error || "Transaction broadcast failed",
31
37
  });
32
38
  }
@@ -45,11 +51,11 @@ async function broadcastUTXOTx({ chain, txHash }: { chain: Chain; txHash: string
45
51
  }>(rpcUrl, { body: rpcBody, headers: { "Content-Type": "application/json" } });
46
52
 
47
53
  if (rpcResponse.error) {
48
- throw new SwapKitError("toolbox_utxo_broadcast_failed", { error: rpcResponse.error?.message });
54
+ throw new USwapError("toolbox_utxo_broadcast_failed", { error: rpcResponse.error?.message });
49
55
  }
50
56
 
51
57
  if (rpcResponse.result.includes('"code":-26')) {
52
- throw new SwapKitError("toolbox_utxo_invalid_transaction", { error: "Transaction amount was too low" });
58
+ throw new USwapError("toolbox_utxo_invalid_transaction", { error: "Transaction amount was too low" });
53
59
  }
54
60
 
55
61
  return rpcResponse.result;
@@ -121,13 +127,13 @@ async function blockchairRequest<T>(url: string, apiKey?: string): Promise<T> {
121
127
  );
122
128
 
123
129
  if (!response || response.context.code !== 200)
124
- throw new SwapKitError("toolbox_utxo_api_error", { error: `Failed to query ${url}` });
130
+ throw new USwapError("toolbox_utxo_api_error", { error: `Failed to query ${url}` });
125
131
 
126
132
  return response.data as T;
127
133
  }
128
134
 
129
135
  async function getAddressData({ address, chain, apiKey }: BlockchairParams<{ address?: string }>) {
130
- if (!address) throw new SwapKitError("toolbox_utxo_invalid_params", { error: "Address is required" });
136
+ if (!address) throw new USwapError("toolbox_utxo_invalid_params", { error: "Address is required" });
131
137
 
132
138
  try {
133
139
  const response = await blockchairRequest<BlockchairAddressResponse>(
@@ -148,7 +154,7 @@ async function getUnconfirmedBalance({ address, chain, apiKey }: BlockchairParam
148
154
  }
149
155
 
150
156
  async function getRawTx({ chain, apiKey, txHash }: BlockchairParams<{ txHash?: string }>) {
151
- if (!txHash) throw new SwapKitError("toolbox_utxo_invalid_params", { error: "TxHash is required" });
157
+ if (!txHash) throw new USwapError("toolbox_utxo_invalid_params", { error: "TxHash is required" });
152
158
 
153
159
  try {
154
160
  const rawTxResponse = await blockchairRequest<BlockchairRawTransactionResponse>(
@@ -223,7 +229,7 @@ async function getUnspentUtxos({
223
229
  offset = 0,
224
230
  limit = 30,
225
231
  }: BlockchairFetchUnspentUtxoParams): Promise<Awaited<ReturnType<typeof fetchUtxosBatch>>> {
226
- if (!address) throw new SwapKitError("toolbox_utxo_invalid_params", { error: "Address is required" });
232
+ if (!address) throw new USwapError("toolbox_utxo_invalid_params", { error: "Address is required" });
227
233
 
228
234
  try {
229
235
  const utxos = await fetchUtxosBatch({ address, apiKey, chain, limit, offset, targetValue });
@@ -340,7 +346,7 @@ export function getUtxoNetwork() {
340
346
  }
341
347
 
342
348
  default:
343
- throw new SwapKitError("toolbox_utxo_not_supported", { chain });
349
+ throw new USwapError("toolbox_utxo_not_supported", { chain });
344
350
  }
345
351
  };
346
352
  }