@uswap/toolboxes 4.3.6

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 (275) hide show
  1. package/dist/src/cardano/index.cjs +4 -0
  2. package/dist/src/cardano/index.cjs.map +11 -0
  3. package/dist/src/cardano/index.js +4 -0
  4. package/dist/src/cardano/index.js.map +11 -0
  5. package/dist/src/cosmos/index.cjs +4 -0
  6. package/dist/src/cosmos/index.cjs.map +20 -0
  7. package/dist/src/cosmos/index.js +4 -0
  8. package/dist/src/cosmos/index.js.map +20 -0
  9. package/dist/src/evm/index.cjs +4 -0
  10. package/dist/src/evm/index.cjs.map +20 -0
  11. package/dist/src/evm/index.js +4 -0
  12. package/dist/src/evm/index.js.map +20 -0
  13. package/dist/src/index.cjs +5 -0
  14. package/dist/src/index.cjs.map +67 -0
  15. package/dist/src/index.js +5 -0
  16. package/dist/src/index.js.map +67 -0
  17. package/dist/src/near/index.cjs +4 -0
  18. package/dist/src/near/index.cjs.map +16 -0
  19. package/dist/src/near/index.js +4 -0
  20. package/dist/src/near/index.js.map +16 -0
  21. package/dist/src/radix/index.cjs +4 -0
  22. package/dist/src/radix/index.cjs.map +10 -0
  23. package/dist/src/radix/index.js +4 -0
  24. package/dist/src/radix/index.js.map +10 -0
  25. package/dist/src/ripple/index.cjs +4 -0
  26. package/dist/src/ripple/index.cjs.map +10 -0
  27. package/dist/src/ripple/index.js +4 -0
  28. package/dist/src/ripple/index.js.map +10 -0
  29. package/dist/src/solana/index.cjs +4 -0
  30. package/dist/src/solana/index.cjs.map +11 -0
  31. package/dist/src/solana/index.js +4 -0
  32. package/dist/src/solana/index.js.map +11 -0
  33. package/dist/src/substrate/index.cjs +4 -0
  34. package/dist/src/substrate/index.cjs.map +13 -0
  35. package/dist/src/substrate/index.js +4 -0
  36. package/dist/src/substrate/index.js.map +13 -0
  37. package/dist/src/sui/index.cjs +4 -0
  38. package/dist/src/sui/index.cjs.map +11 -0
  39. package/dist/src/sui/index.js +4 -0
  40. package/dist/src/sui/index.js.map +11 -0
  41. package/dist/src/ton/index.cjs +4 -0
  42. package/dist/src/ton/index.cjs.map +11 -0
  43. package/dist/src/ton/index.js +4 -0
  44. package/dist/src/ton/index.js.map +11 -0
  45. package/dist/src/tron/index.cjs +4 -0
  46. package/dist/src/tron/index.cjs.map +13 -0
  47. package/dist/src/tron/index.js +4 -0
  48. package/dist/src/tron/index.js.map +13 -0
  49. package/dist/src/utxo/index.cjs +5 -0
  50. package/dist/src/utxo/index.cjs.map +21 -0
  51. package/dist/src/utxo/index.js +5 -0
  52. package/dist/src/utxo/index.js.map +21 -0
  53. package/dist/types/cardano/index.d.ts +3 -0
  54. package/dist/types/cardano/index.d.ts.map +1 -0
  55. package/dist/types/cardano/toolbox.d.ts +34 -0
  56. package/dist/types/cardano/toolbox.d.ts.map +1 -0
  57. package/dist/types/cardano/types.d.ts +11 -0
  58. package/dist/types/cardano/types.d.ts.map +1 -0
  59. package/dist/types/cosmos/index.d.ts +5 -0
  60. package/dist/types/cosmos/index.d.ts.map +1 -0
  61. package/dist/types/cosmos/thorchainUtils/addressFormat.d.ts +5 -0
  62. package/dist/types/cosmos/thorchainUtils/addressFormat.d.ts.map +1 -0
  63. package/dist/types/cosmos/thorchainUtils/index.d.ts +5 -0
  64. package/dist/types/cosmos/thorchainUtils/index.d.ts.map +1 -0
  65. package/dist/types/cosmos/thorchainUtils/messages.d.ts +208 -0
  66. package/dist/types/cosmos/thorchainUtils/messages.d.ts.map +1 -0
  67. package/dist/types/cosmos/thorchainUtils/registry.d.ts +4 -0
  68. package/dist/types/cosmos/thorchainUtils/registry.d.ts.map +1 -0
  69. package/dist/types/cosmos/thorchainUtils/types/MsgCompiled.d.ts +2 -0
  70. package/dist/types/cosmos/thorchainUtils/types/MsgCompiled.d.ts.map +1 -0
  71. package/dist/types/cosmos/thorchainUtils/types/client-types.d.ts +63 -0
  72. package/dist/types/cosmos/thorchainUtils/types/client-types.d.ts.map +1 -0
  73. package/dist/types/cosmos/thorchainUtils/types/index.d.ts +2 -0
  74. package/dist/types/cosmos/thorchainUtils/types/index.d.ts.map +1 -0
  75. package/dist/types/cosmos/toolbox/cosmos.d.ts +62 -0
  76. package/dist/types/cosmos/toolbox/cosmos.d.ts.map +1 -0
  77. package/dist/types/cosmos/toolbox/index.d.ts +15 -0
  78. package/dist/types/cosmos/toolbox/index.d.ts.map +1 -0
  79. package/dist/types/cosmos/toolbox/thorchain.d.ts +158 -0
  80. package/dist/types/cosmos/toolbox/thorchain.d.ts.map +1 -0
  81. package/dist/types/cosmos/types.d.ts +49 -0
  82. package/dist/types/cosmos/types.d.ts.map +1 -0
  83. package/dist/types/cosmos/util.d.ts +74 -0
  84. package/dist/types/cosmos/util.d.ts.map +1 -0
  85. package/dist/types/evm/api.d.ts +8 -0
  86. package/dist/types/evm/api.d.ts.map +1 -0
  87. package/dist/types/evm/contracts/eth/multicall.d.ts +36 -0
  88. package/dist/types/evm/contracts/eth/multicall.d.ts.map +1 -0
  89. package/dist/types/evm/contracts/op/gasOracle.d.ts +40 -0
  90. package/dist/types/evm/contracts/op/gasOracle.d.ts.map +1 -0
  91. package/dist/types/evm/helpers.d.ts +6 -0
  92. package/dist/types/evm/helpers.d.ts.map +1 -0
  93. package/dist/types/evm/index.d.ts +5 -0
  94. package/dist/types/evm/index.d.ts.map +1 -0
  95. package/dist/types/evm/toolbox/baseEVMToolbox.d.ts +83 -0
  96. package/dist/types/evm/toolbox/baseEVMToolbox.d.ts.map +1 -0
  97. package/dist/types/evm/toolbox/evm.d.ts +767 -0
  98. package/dist/types/evm/toolbox/evm.d.ts.map +1 -0
  99. package/dist/types/evm/toolbox/index.d.ts +7 -0
  100. package/dist/types/evm/toolbox/index.d.ts.map +1 -0
  101. package/dist/types/evm/toolbox/op.d.ts +76 -0
  102. package/dist/types/evm/toolbox/op.d.ts.map +1 -0
  103. package/dist/types/evm/types.d.ts +108 -0
  104. package/dist/types/evm/types.d.ts.map +1 -0
  105. package/dist/types/index.d.ts +75 -0
  106. package/dist/types/index.d.ts.map +1 -0
  107. package/dist/types/near/helpers/core.d.ts +15 -0
  108. package/dist/types/near/helpers/core.d.ts.map +1 -0
  109. package/dist/types/near/helpers/gasEstimation.d.ts +41 -0
  110. package/dist/types/near/helpers/gasEstimation.d.ts.map +1 -0
  111. package/dist/types/near/helpers/nep141.d.ts +36 -0
  112. package/dist/types/near/helpers/nep141.d.ts.map +1 -0
  113. package/dist/types/near/index.d.ts +10 -0
  114. package/dist/types/near/index.d.ts.map +1 -0
  115. package/dist/types/near/toolbox.d.ts +32 -0
  116. package/dist/types/near/toolbox.d.ts.map +1 -0
  117. package/dist/types/near/types/contract.d.ts +38 -0
  118. package/dist/types/near/types/contract.d.ts.map +1 -0
  119. package/dist/types/near/types/nep141.d.ts +29 -0
  120. package/dist/types/near/types/nep141.d.ts.map +1 -0
  121. package/dist/types/near/types/toolbox.d.ts +51 -0
  122. package/dist/types/near/types/toolbox.d.ts.map +1 -0
  123. package/dist/types/near/types.d.ts +47 -0
  124. package/dist/types/near/types.d.ts.map +1 -0
  125. package/dist/types/radix/index.d.ts +14 -0
  126. package/dist/types/radix/index.d.ts.map +1 -0
  127. package/dist/types/ripple/index.d.ts +46 -0
  128. package/dist/types/ripple/index.d.ts.map +1 -0
  129. package/dist/types/solana/index.d.ts +23 -0
  130. package/dist/types/solana/index.d.ts.map +1 -0
  131. package/dist/types/solana/toolbox.d.ts +51 -0
  132. package/dist/types/solana/toolbox.d.ts.map +1 -0
  133. package/dist/types/substrate/balance.d.ts +17 -0
  134. package/dist/types/substrate/balance.d.ts.map +1 -0
  135. package/dist/types/substrate/index.d.ts +3 -0
  136. package/dist/types/substrate/index.d.ts.map +1 -0
  137. package/dist/types/substrate/substrate.d.ts +148 -0
  138. package/dist/types/substrate/substrate.d.ts.map +1 -0
  139. package/dist/types/substrate/types.d.ts +100 -0
  140. package/dist/types/substrate/types.d.ts.map +1 -0
  141. package/dist/types/sui/index.d.ts +3 -0
  142. package/dist/types/sui/index.d.ts.map +1 -0
  143. package/dist/types/sui/toolbox.d.ts +19 -0
  144. package/dist/types/sui/toolbox.d.ts.map +1 -0
  145. package/dist/types/sui/types.d.ts +16 -0
  146. package/dist/types/sui/types.d.ts.map +1 -0
  147. package/dist/types/ton/index.d.ts +3 -0
  148. package/dist/types/ton/index.d.ts.map +1 -0
  149. package/dist/types/ton/toolbox.d.ts +14 -0
  150. package/dist/types/ton/toolbox.d.ts.map +1 -0
  151. package/dist/types/ton/types.d.ts +22 -0
  152. package/dist/types/ton/types.d.ts.map +1 -0
  153. package/dist/types/tron/helpers/trc20.abi.d.ts +156 -0
  154. package/dist/types/tron/helpers/trc20.abi.d.ts.map +1 -0
  155. package/dist/types/tron/helpers/trongrid.d.ts +8 -0
  156. package/dist/types/tron/helpers/trongrid.d.ts.map +1 -0
  157. package/dist/types/tron/index.d.ts +6 -0
  158. package/dist/types/tron/index.d.ts.map +1 -0
  159. package/dist/types/tron/toolbox.d.ts +26 -0
  160. package/dist/types/tron/toolbox.d.ts.map +1 -0
  161. package/dist/types/tron/types.d.ts +103 -0
  162. package/dist/types/tron/types.d.ts.map +1 -0
  163. package/dist/types/types.d.ts +26 -0
  164. package/dist/types/types.d.ts.map +1 -0
  165. package/dist/types/utils.d.ts +4 -0
  166. package/dist/types/utils.d.ts.map +1 -0
  167. package/dist/types/utxo/helpers/api.d.ts +101 -0
  168. package/dist/types/utxo/helpers/api.d.ts.map +1 -0
  169. package/dist/types/utxo/helpers/bchaddrjs.d.ts +10 -0
  170. package/dist/types/utxo/helpers/bchaddrjs.d.ts.map +1 -0
  171. package/dist/types/utxo/helpers/coinselect.d.ts +17 -0
  172. package/dist/types/utxo/helpers/coinselect.d.ts.map +1 -0
  173. package/dist/types/utxo/helpers/index.d.ts +5 -0
  174. package/dist/types/utxo/helpers/index.d.ts.map +1 -0
  175. package/dist/types/utxo/helpers/txSize.d.ts +21 -0
  176. package/dist/types/utxo/helpers/txSize.d.ts.map +1 -0
  177. package/dist/types/utxo/index.d.ts +7 -0
  178. package/dist/types/utxo/index.d.ts.map +1 -0
  179. package/dist/types/utxo/toolbox/bitcoinCash.d.ts +93 -0
  180. package/dist/types/utxo/toolbox/bitcoinCash.d.ts.map +1 -0
  181. package/dist/types/utxo/toolbox/index.d.ts +28 -0
  182. package/dist/types/utxo/toolbox/index.d.ts.map +1 -0
  183. package/dist/types/utxo/toolbox/params.d.ts +32 -0
  184. package/dist/types/utxo/toolbox/params.d.ts.map +1 -0
  185. package/dist/types/utxo/toolbox/utxo.d.ts +103 -0
  186. package/dist/types/utxo/toolbox/utxo.d.ts.map +1 -0
  187. package/dist/types/utxo/toolbox/validators.d.ts +4 -0
  188. package/dist/types/utxo/toolbox/validators.d.ts.map +1 -0
  189. package/dist/types/utxo/toolbox/zcash.d.ts +72 -0
  190. package/dist/types/utxo/toolbox/zcash.d.ts.map +1 -0
  191. package/dist/types/utxo/types.d.ts +46 -0
  192. package/dist/types/utxo/types.d.ts.map +1 -0
  193. package/package.json +205 -0
  194. package/src/__tests__/address-validation-all-chains.test.ts +162 -0
  195. package/src/__tests__/addressValidator.test.ts +162 -0
  196. package/src/cardano/__tests__/toolbox.test.ts +48 -0
  197. package/src/cardano/index.ts +2 -0
  198. package/src/cardano/toolbox.ts +168 -0
  199. package/src/cardano/types.ts +10 -0
  200. package/src/cosmos/__tests__/toolbox.test.ts +91 -0
  201. package/src/cosmos/index.ts +4 -0
  202. package/src/cosmos/thorchainUtils/addressFormat.ts +22 -0
  203. package/src/cosmos/thorchainUtils/index.ts +4 -0
  204. package/src/cosmos/thorchainUtils/messages.ts +212 -0
  205. package/src/cosmos/thorchainUtils/registry.ts +43 -0
  206. package/src/cosmos/thorchainUtils/types/MsgCompiled.ts +2800 -0
  207. package/src/cosmos/thorchainUtils/types/client-types.ts +54 -0
  208. package/src/cosmos/thorchainUtils/types/index.ts +1 -0
  209. package/src/cosmos/toolbox/cosmos.ts +345 -0
  210. package/src/cosmos/toolbox/index.ts +35 -0
  211. package/src/cosmos/toolbox/thorchain.ts +249 -0
  212. package/src/cosmos/types.ts +48 -0
  213. package/src/cosmos/util.ts +214 -0
  214. package/src/evm/__tests__/address-validation.test.ts +84 -0
  215. package/src/evm/__tests__/ethereum.test.ts +137 -0
  216. package/src/evm/__tests__/signMessage.test.ts +60 -0
  217. package/src/evm/api.ts +10 -0
  218. package/src/evm/contracts/eth/multicall.ts +165 -0
  219. package/src/evm/contracts/op/gasOracle.ts +145 -0
  220. package/src/evm/helpers.ts +73 -0
  221. package/src/evm/index.ts +4 -0
  222. package/src/evm/toolbox/baseEVMToolbox.ts +695 -0
  223. package/src/evm/toolbox/evm.ts +67 -0
  224. package/src/evm/toolbox/index.ts +44 -0
  225. package/src/evm/toolbox/op.ts +156 -0
  226. package/src/evm/types.ts +146 -0
  227. package/src/index.ts +260 -0
  228. package/src/near/__tests__/core.test.ts +70 -0
  229. package/src/near/helpers/core.ts +85 -0
  230. package/src/near/helpers/gasEstimation.ts +96 -0
  231. package/src/near/helpers/nep141.ts +50 -0
  232. package/src/near/index.ts +21 -0
  233. package/src/near/toolbox.ts +421 -0
  234. package/src/near/types/contract.ts +32 -0
  235. package/src/near/types/nep141.ts +34 -0
  236. package/src/near/types/toolbox.ts +55 -0
  237. package/src/near/types.ts +44 -0
  238. package/src/radix/index.ts +132 -0
  239. package/src/ripple/index.ts +179 -0
  240. package/src/solana/index.ts +36 -0
  241. package/src/solana/toolbox.ts +415 -0
  242. package/src/substrate/balance.ts +88 -0
  243. package/src/substrate/index.ts +2 -0
  244. package/src/substrate/substrate.ts +281 -0
  245. package/src/substrate/types.ts +115 -0
  246. package/src/sui/__tests__/toolbox.test.ts +82 -0
  247. package/src/sui/index.ts +2 -0
  248. package/src/sui/toolbox.ts +165 -0
  249. package/src/sui/types.ts +11 -0
  250. package/src/ton/__tests__/toolbox.test.ts +63 -0
  251. package/src/ton/index.ts +2 -0
  252. package/src/ton/toolbox.ts +136 -0
  253. package/src/ton/types.ts +13 -0
  254. package/src/tron/__tests__/toolbox.test.ts +221 -0
  255. package/src/tron/helpers/trc20.abi.ts +107 -0
  256. package/src/tron/helpers/trongrid.ts +53 -0
  257. package/src/tron/index.ts +21 -0
  258. package/src/tron/toolbox.ts +585 -0
  259. package/src/tron/types.ts +83 -0
  260. package/src/types.ts +28 -0
  261. package/src/utils.ts +27 -0
  262. package/src/utxo/__tests__/zcash-integration.test.ts +97 -0
  263. package/src/utxo/helpers/api.ts +471 -0
  264. package/src/utxo/helpers/bchaddrjs.ts +166 -0
  265. package/src/utxo/helpers/coinselect.ts +92 -0
  266. package/src/utxo/helpers/index.ts +4 -0
  267. package/src/utxo/helpers/txSize.ts +137 -0
  268. package/src/utxo/index.ts +6 -0
  269. package/src/utxo/toolbox/bitcoinCash.ts +243 -0
  270. package/src/utxo/toolbox/index.ts +59 -0
  271. package/src/utxo/toolbox/params.ts +18 -0
  272. package/src/utxo/toolbox/utxo.ts +439 -0
  273. package/src/utxo/toolbox/validators.ts +36 -0
  274. package/src/utxo/toolbox/zcash.ts +245 -0
  275. package/src/utxo/types.ts +39 -0
@@ -0,0 +1,415 @@
1
+ import type {
2
+ Connection,
3
+ PublicKey,
4
+ Signer,
5
+ Transaction,
6
+ TransactionInstruction,
7
+ VersionedTransaction,
8
+ } from "@solana/web3.js";
9
+ import {
10
+ AssetValue,
11
+ Chain,
12
+ DerivationPath,
13
+ type DerivationPathArray,
14
+ derivationPathToString,
15
+ type GenericCreateTransactionParams,
16
+ getChainConfig,
17
+ getRPCUrl,
18
+ NetworkDerivationPath,
19
+ SwapKitError,
20
+ updateDerivationPath,
21
+ } from "@uswap/helpers";
22
+ import { match, P } from "ts-pattern";
23
+ import type { SolanaCreateTransactionParams, SolanaProvider, SolanaTransferParams } from "./index";
24
+
25
+ type SolanaSigner = SolanaProvider | Signer;
26
+
27
+ type TokenMetadata = {
28
+ name: string;
29
+ symbol: string;
30
+ decimals: number;
31
+ logoURI?: string;
32
+ tags?: string[];
33
+ daily_volume?: number;
34
+ id: string; // mint address
35
+ };
36
+
37
+ export async function fetchTokenMetaData(mintAddress: string): Promise<TokenMetadata | null> {
38
+ const assetValue = AssetValue.from({ address: mintAddress, chain: Chain.Solana });
39
+ if (assetValue.symbol !== "UNKNOWN") {
40
+ return {
41
+ decimals: assetValue.decimal || 0,
42
+ id: mintAddress,
43
+ logoURI: assetValue.getIconUrl(),
44
+ name: assetValue.symbol,
45
+ symbol: assetValue.ticker,
46
+ };
47
+ }
48
+
49
+ const url = `https://lite-api.jup.ag/tokens/v2/search?query=${encodeURIComponent(mintAddress)}`;
50
+
51
+ try {
52
+ const res = await fetch(url);
53
+ if (!res.ok) return null;
54
+
55
+ const arr = (await res.json()) as TokenMetadata[];
56
+ if (!Array.isArray(arr) || arr.length === 0) return null;
57
+
58
+ const exact = arr.find((t) => t.id === mintAddress);
59
+ return exact || null;
60
+ } catch {
61
+ return null;
62
+ }
63
+ }
64
+
65
+ async function getSolanaBalance(address: string) {
66
+ const connection = await getConnection();
67
+ const { PublicKey } = await import("@solana/web3.js");
68
+ const { TOKEN_PROGRAM_ID } = await import("@solana/spl-token");
69
+ const publicKey = new PublicKey(address);
70
+
71
+ const balances: AssetValue[] = [];
72
+
73
+ // Get SOL balance
74
+ 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
+
80
+ // Get token balances
81
+ const tokenAccounts = await connection.getParsedTokenAccountsByOwner(publicKey, { programId: TOKEN_PROGRAM_ID });
82
+
83
+ for (const { account } of tokenAccounts.value) {
84
+ const tokenInfo = account.data.parsed.info;
85
+ const mintAddress = tokenInfo.mint;
86
+ const amount = tokenInfo.tokenAmount.amount;
87
+
88
+ if (Number(amount) === 0) continue;
89
+
90
+ const metadata = await fetchTokenMetaData(mintAddress);
91
+ const ticker = metadata?.symbol || "UNKNOWN";
92
+ const decimals = metadata?.decimals || tokenInfo.tokenAmount.decimals;
93
+
94
+ balances.push(
95
+ AssetValue.from({ asset: `${Chain.Solana}.${ticker}-${mintAddress}`, fromBaseDecimal: decimals, value: amount }),
96
+ );
97
+ }
98
+
99
+ return balances;
100
+ }
101
+
102
+ export async function getSolanaAddressValidator() {
103
+ const { PublicKey } = await import("@solana/web3.js");
104
+
105
+ return (address: string) => {
106
+ try {
107
+ const pubkey = new PublicKey(address);
108
+ return PublicKey.isOnCurve(pubkey.toBytes());
109
+ } catch {
110
+ return false;
111
+ }
112
+ };
113
+ }
114
+
115
+ export async function getSolanaToolbox(
116
+ toolboxParams?: { signer?: SolanaSigner } | { phrase?: string; index?: number; derivationPath?: DerivationPathArray },
117
+ ) {
118
+ const index = toolboxParams && "index" in toolboxParams ? toolboxParams.index || 0 : 0;
119
+ const derivationPath = derivationPathToString(
120
+ toolboxParams && "derivationPath" in toolboxParams && toolboxParams.derivationPath
121
+ ? toolboxParams.derivationPath
122
+ : updateDerivationPath(NetworkDerivationPath[Chain.Solana], { index }),
123
+ );
124
+
125
+ const signer = await match(toolboxParams)
126
+ .with({ phrase: P.string }, ({ phrase }) => createKeysForPath({ derivationPath, phrase }))
127
+ .with({ signer: P.any }, ({ signer }) => signer)
128
+ .otherwise(() => undefined);
129
+
130
+ function getAddress() {
131
+ return signer?.publicKey ? getAddressFromPubKey(signer.publicKey) : "";
132
+ }
133
+
134
+ function getBalance(addressParam?: string) {
135
+ const address = addressParam || getAddress();
136
+ if (!address) throw new SwapKitError("core_wallet_connection_not_found");
137
+ return getSolanaBalance(address);
138
+ }
139
+
140
+ return {
141
+ broadcastTransaction: broadcastTransaction(getConnection),
142
+ createKeysForPath,
143
+ createTransaction: createTransaction(getConnection),
144
+ createTransactionFromInstructions,
145
+ estimateTransactionFee: estimateTransactionFee(getConnection),
146
+ getAddress,
147
+ getAddressFromPubKey,
148
+ getAddressValidator: getSolanaAddressValidator,
149
+ getBalance,
150
+ getConnection,
151
+ getPubkeyFromAddress,
152
+ signTransaction: signTransaction(getConnection, signer),
153
+ transfer: transfer(getConnection, signer),
154
+ };
155
+ }
156
+
157
+ function estimateTransactionFee(getConnection: () => Promise<Connection>) {
158
+ return async ({
159
+ recipient,
160
+ assetValue,
161
+ memo,
162
+ isProgramDerivedAddress,
163
+ sender,
164
+ }: Omit<GenericCreateTransactionParams, "feeRate"> & { isProgramDerivedAddress?: boolean }) => {
165
+ const connection = await getConnection();
166
+
167
+ const transaction = await createTransaction(getConnection)({
168
+ assetValue,
169
+ isProgramDerivedAddress,
170
+ memo,
171
+ recipient,
172
+ sender,
173
+ });
174
+
175
+ const message = transaction.compileMessage();
176
+ const feeInLamports = await connection.getFeeForMessage(message);
177
+
178
+ if (feeInLamports.value === null) {
179
+ throw new SwapKitError("toolbox_solana_fee_estimation_failed", "Could not estimate Solana fee.");
180
+ }
181
+
182
+ const { baseDecimal } = getChainConfig(Chain.Solana);
183
+
184
+ return AssetValue.from({ chain: Chain.Solana, fromBaseDecimal: baseDecimal, value: feeInLamports.value });
185
+ };
186
+ }
187
+
188
+ async function getConnection() {
189
+ const { Connection } = await import("@solana/web3.js");
190
+ const rpcUrl = await getRPCUrl(Chain.Solana);
191
+ return new Connection(rpcUrl, "confirmed");
192
+ }
193
+
194
+ function createAssetTransaction(getConnection: () => Promise<Connection>) {
195
+ return async ({ assetValue, recipient, sender, isProgramDerivedAddress }: SolanaCreateTransactionParams) => {
196
+ const connection = await getConnection();
197
+ const fromPubkey = await getPubkeyFromAddress(sender);
198
+
199
+ if (assetValue.isGasAsset) {
200
+ const { Transaction, SystemProgram, PublicKey } = await import("@solana/web3.js");
201
+
202
+ return new Transaction().add(
203
+ SystemProgram.transfer({
204
+ fromPubkey: fromPubkey,
205
+ lamports: assetValue.getBaseValue("number"),
206
+ toPubkey: new PublicKey(recipient),
207
+ }),
208
+ );
209
+ }
210
+
211
+ if (assetValue.address) {
212
+ return createSolanaTokenTransaction({
213
+ amount: assetValue.getBaseValue("number"),
214
+ connection,
215
+ decimals: assetValue.decimal as number,
216
+ from: fromPubkey,
217
+ isProgramDerivedAddress,
218
+ recipient,
219
+ tokenAddress: assetValue.address,
220
+ });
221
+ }
222
+
223
+ return undefined;
224
+ };
225
+ }
226
+
227
+ async function createSolanaTokenTransaction({
228
+ tokenAddress,
229
+ recipient,
230
+ from,
231
+ connection,
232
+ amount,
233
+ decimals,
234
+ isProgramDerivedAddress,
235
+ }: {
236
+ tokenAddress: string;
237
+ recipient: string;
238
+ from: PublicKey;
239
+ connection: Connection;
240
+ amount: number;
241
+ decimals: number;
242
+ isProgramDerivedAddress?: boolean;
243
+ }) {
244
+ const {
245
+ getAssociatedTokenAddress,
246
+ getAccount,
247
+ createAssociatedTokenAccountInstruction,
248
+ createTransferCheckedInstruction,
249
+ } = await import("@solana/spl-token");
250
+ const { Transaction, PublicKey } = await import("@solana/web3.js");
251
+
252
+ const transaction = new Transaction();
253
+ const tokenPublicKey = new PublicKey(tokenAddress);
254
+ const fromSPLAddress = await getAssociatedTokenAddress(tokenPublicKey, from);
255
+
256
+ const recipientPublicKey = new PublicKey(recipient);
257
+ const recipientSPLAddress = await getAssociatedTokenAddress(
258
+ tokenPublicKey,
259
+ recipientPublicKey,
260
+ isProgramDerivedAddress,
261
+ );
262
+
263
+ let recipientAccountExists = false;
264
+ try {
265
+ await getAccount(connection, recipientSPLAddress);
266
+ recipientAccountExists = true;
267
+ } catch {
268
+ // Recipient's associated token account doesn't exist
269
+ }
270
+
271
+ if (!recipientAccountExists) {
272
+ transaction.add(
273
+ createAssociatedTokenAccountInstruction(from, recipientSPLAddress, recipientPublicKey, tokenPublicKey),
274
+ );
275
+ }
276
+
277
+ transaction.add(
278
+ createTransferCheckedInstruction(fromSPLAddress, tokenPublicKey, recipientSPLAddress, from, amount, decimals),
279
+ );
280
+
281
+ return transaction;
282
+ }
283
+
284
+ function createTransaction(getConnection: () => Promise<Connection>) {
285
+ return async ({ recipient, assetValue, memo, isProgramDerivedAddress, sender }: SolanaCreateTransactionParams) => {
286
+ const { createMemoInstruction } = await import("@solana/spl-memo");
287
+
288
+ const fromPubkey = await getPubkeyFromAddress(sender);
289
+ const validateAddress = await getSolanaAddressValidator();
290
+
291
+ if (!(isProgramDerivedAddress || validateAddress(recipient))) {
292
+ throw new SwapKitError("core_transaction_invalid_recipient_address");
293
+ }
294
+
295
+ const connection = await getConnection();
296
+ const transaction = await createAssetTransaction(getConnection)({
297
+ assetValue,
298
+ isProgramDerivedAddress,
299
+ recipient,
300
+ sender,
301
+ });
302
+
303
+ if (!transaction) {
304
+ throw new SwapKitError("core_transaction_invalid_sender_address");
305
+ }
306
+
307
+ if (memo) transaction.add(createMemoInstruction(memo));
308
+
309
+ const blockHash = await connection.getLatestBlockhash();
310
+ transaction.recentBlockhash = blockHash.blockhash;
311
+ transaction.feePayer = fromPubkey;
312
+
313
+ return transaction;
314
+ };
315
+ }
316
+
317
+ async function createTransactionFromInstructions({
318
+ instructions,
319
+ }: {
320
+ instructions: TransactionInstruction[];
321
+ isProgramDerivedAddress?: boolean;
322
+ }) {
323
+ const { Transaction } = await import("@solana/web3.js");
324
+ const transaction = new Transaction().add(...instructions);
325
+
326
+ if (!transaction) {
327
+ throw new SwapKitError("core_transaction_invalid_sender_address");
328
+ }
329
+
330
+ return transaction;
331
+ }
332
+
333
+ function transfer(getConnection: () => Promise<Connection>, signer?: SolanaSigner) {
334
+ return async ({ recipient, assetValue, memo, isProgramDerivedAddress }: SolanaTransferParams) => {
335
+ if (!signer) {
336
+ throw new SwapKitError("core_transaction_invalid_sender_address");
337
+ }
338
+
339
+ const sender = signer.publicKey?.toString() ?? (await (signer as SolanaProvider).connect()).publicKey.toString();
340
+
341
+ const transaction = await createTransaction(getConnection)({
342
+ assetValue,
343
+ isProgramDerivedAddress,
344
+ memo,
345
+ recipient,
346
+ sender,
347
+ });
348
+
349
+ if ("signTransaction" in signer) {
350
+ const signedTransaction = await signer.signTransaction(transaction);
351
+ return broadcastTransaction(getConnection)(signedTransaction);
352
+ }
353
+
354
+ transaction.sign(signer);
355
+
356
+ return broadcastTransaction(getConnection)(transaction);
357
+ };
358
+ }
359
+
360
+ function broadcastTransaction(getConnection: () => Promise<Connection>) {
361
+ return async (transaction: Transaction | VersionedTransaction) => {
362
+ const connection = await getConnection();
363
+ return connection.sendRawTransaction(transaction.serialize());
364
+ };
365
+ }
366
+
367
+ function signTransaction(getConnection: () => Promise<Connection>, signer?: SolanaSigner) {
368
+ return async (transaction: Transaction | VersionedTransaction) => {
369
+ const { VersionedTransaction } = await import("@solana/web3.js");
370
+ if (!signer) {
371
+ throw new SwapKitError("toolbox_solana_no_signer");
372
+ }
373
+
374
+ if (!(transaction instanceof VersionedTransaction)) {
375
+ const connection = await getConnection();
376
+
377
+ const blockHash = await connection.getLatestBlockhash();
378
+ transaction.recentBlockhash = blockHash.blockhash;
379
+ transaction.feePayer = signer.publicKey || undefined;
380
+ }
381
+
382
+ if ("connect" in signer) {
383
+ const signedTransaction = await signer.signTransaction(transaction);
384
+ return signedTransaction;
385
+ }
386
+
387
+ await transaction.sign([signer] as Signer & Signer[]);
388
+ return transaction;
389
+ };
390
+ }
391
+
392
+ export async function createKeysForPath({
393
+ phrase,
394
+ derivationPath = DerivationPath.SOL,
395
+ }: {
396
+ phrase: string;
397
+ derivationPath?: string;
398
+ }) {
399
+ const { HDKey } = await import("micro-key-producer/slip10.js");
400
+ const { mnemonicToSeedSync } = await import("@scure/bip39");
401
+ const { Keypair } = await import("@solana/web3.js");
402
+ const seed = mnemonicToSeedSync(phrase);
403
+ const hdKey = HDKey.fromMasterSeed(seed);
404
+
405
+ return Keypair.fromSeed(hdKey.derive(derivationPath, true).privateKey);
406
+ }
407
+
408
+ function getAddressFromPubKey(publicKey: PublicKey) {
409
+ return publicKey.toString();
410
+ }
411
+
412
+ async function getPubkeyFromAddress(address: string) {
413
+ const { PublicKey } = await import("@solana/web3.js");
414
+ return new PublicKey(address);
415
+ }
@@ -0,0 +1,88 @@
1
+ import type { ApiPromise } from "@polkadot/api";
2
+ import { AssetValue, Chain, SwapKitNumber } from "@uswap/helpers";
3
+
4
+ /**
5
+ * Get balance for standard Substrate chains (Polkadot, etc.)
6
+ * Uses api.query.system.account to query free and reserved balances
7
+ */
8
+ export async function getSubstrateBalance(
9
+ api: ApiPromise,
10
+ gasAsset: AssetValue,
11
+ address: string,
12
+ ): Promise<AssetValue[]> {
13
+ try {
14
+ const account = await api.query.system?.account?.(address);
15
+
16
+ if (!account) {
17
+ return [gasAsset.set(0)];
18
+ }
19
+
20
+ const {
21
+ // @ts-expect-error
22
+ data: { free },
23
+ } = account;
24
+
25
+ // Convert the free balance to string using SwapKitNumber for proper decimal handling
26
+ const freeBalance = SwapKitNumber.fromBigInt(BigInt(free.toString()), gasAsset.decimal).getValue("string");
27
+
28
+ return [gasAsset.set(freeBalance)];
29
+ } catch (error) {
30
+ const errorMessage = error instanceof Error ? error.message : String(error);
31
+ console.error(`Error fetching substrate balance: ${errorMessage}`);
32
+ return [];
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Get balance for Chainflip chain
38
+ * Uses api.query.flip.account to query FLIP balances
39
+ */
40
+ export async function getChainflipBalance(
41
+ api: ApiPromise,
42
+ gasAsset: AssetValue,
43
+ address: string,
44
+ ): Promise<AssetValue[]> {
45
+ try {
46
+ // Chainflip uses a custom flip pallet for account balances
47
+ const flipAccount = await api.query.flip?.account?.(address);
48
+
49
+ if (!flipAccount) {
50
+ return [gasAsset.set(0)];
51
+ }
52
+
53
+ // Extract balance from the flip account structure
54
+ // The structure has a balance field directly
55
+ //@ts-expect-error
56
+ const balance = flipAccount.balance || flipAccount.data?.balance;
57
+
58
+ if (!balance || balance.isEmpty) {
59
+ return [gasAsset.set(0)];
60
+ }
61
+
62
+ // Convert balance to string using SwapKitNumber
63
+ const balanceStr = SwapKitNumber.fromBigInt(BigInt(balance.toString()), gasAsset.decimal).getValue("string");
64
+
65
+ return [gasAsset.set(balanceStr)];
66
+ } catch (error) {
67
+ const errorMessage = error instanceof Error ? error.message : String(error);
68
+ console.error(`Error fetching chainflip balance: ${errorMessage}`);
69
+ return [];
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Factory function to create chain-specific balance getter
75
+ */
76
+ export function createBalanceGetter(chain: Chain, api: ApiPromise) {
77
+ return function getBalance(address: string): Promise<AssetValue[]> {
78
+ const gasAsset = AssetValue.from({ chain });
79
+
80
+ switch (chain) {
81
+ case Chain.Chainflip:
82
+ return getChainflipBalance(api, gasAsset, address);
83
+
84
+ default:
85
+ return getSubstrateBalance(api, gasAsset, address);
86
+ }
87
+ };
88
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./substrate";
2
+ export * from "./types";