@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,162 @@
1
+ import { beforeAll, describe, expect, test } from "bun:test";
2
+ import { Chain } from "@uswap/helpers";
3
+ import { getAddressValidator } from "../index";
4
+
5
+ const context: { validateAddress: (params: { address: string; chain: Chain }) => boolean } = {} as any;
6
+
7
+ beforeAll(async () => {
8
+ context.validateAddress = await getAddressValidator();
9
+ });
10
+
11
+ describe("Address Validation - All Chains", () => {
12
+ describe("Valid addresses for each chain", () => {
13
+ const validAddresses = {
14
+ [Chain.Ethereum]: ["0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0"],
15
+ [Chain.Avalanche]: ["0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0"],
16
+ [Chain.Arbitrum]: ["0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0"],
17
+ [Chain.BinanceSmartChain]: ["0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0"],
18
+ [Chain.Optimism]: ["0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0"],
19
+ [Chain.Polygon]: ["0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0"],
20
+ [Chain.Base]: ["0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0"],
21
+ [Chain.Bitcoin]: ["bc1qjpmp8xvg9k4ysa7nvev3lw7qcclvxzt2ex75kr", "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"],
22
+ [Chain.BitcoinCash]: ["qzhcfqxrnhcw88c433tq0fjlw0uut8c0e5d3cf8566"],
23
+ [Chain.Dogecoin]: ["DPrKsuhVibyfMMYRmKP49US5PBQR8zq6v4"],
24
+ [Chain.Litecoin]: ["ltc1qs4h7p8x0kfhs88wazmq2d40t59dwdlxd6rlpjz"],
25
+ [Chain.Dash]: ["XoBBveBZv32rq9MMBt88QSVsUtdj9cMCLy"],
26
+ [Chain.Zcash]: ["t1Mh7QW9g1gK94CSRxniD49aLAJ67s6UerX"],
27
+ [Chain.Cosmos]: ["cosmos12d7d2rlxp7urkp8z0p8sft2fm07ewyjrfvul3f"],
28
+ [Chain.Kujira]: ["kujira12d7d2rlxp7urkp8z0p8sft2fm07ewyjrcy78ur"],
29
+ [Chain.Maya]: ["maya1hm0sdz9v2h5jwjuu0ssp8x98upvlc6py2t7e6j"],
30
+ [Chain.Noble]: ["noble12d7d2rlxp7urkp8z0p8sft2fm07ewyjrp0fhf8"],
31
+ [Chain.THORChain]: ["thor1hm0sdz9v2h5jwjuu0ssp8x98upvlc6py2uq4vz"],
32
+ [Chain.Polkadot]: ["16kQVedQo7yYoFSp2MnQ78zP39xWnFGePnZps2APEyt9K9KZ"],
33
+ [Chain.Chainflip]: ["cFPctKfXisvnrhss2eMV2VdiUNRm1F5pX4WfqkcT3ZrLKJXrS"],
34
+ [Chain.Cardano]: [
35
+ "addr1qxk2md7wufs2cas0dfxch0uu59079s7yc5k9pw8s49wpm25s8ynu4svqm7m4hd04d4jvm6e5vvyw7dm4gvpqyfklgn8qetu85s",
36
+ ],
37
+ [Chain.Near]: ["a03fafdf5f97d3c6be6bff9e55f057dda76fefbb7e149f5469248f41e812cb6e"],
38
+ [Chain.Ripple]: ["rhDQXdwWR2RstC7sLjLMbjCeWT3PuSAZVu"],
39
+ [Chain.Solana]: ["4UHWuPwyV3XCcnwrpEdWAEW3WLUP1RDMaK3ANNsRUjfM"],
40
+ [Chain.Sui]: ["0x57b861db681d8e47b586e6e9a92f6ed210dbbb440670b8122420848cf0e844fb"],
41
+ [Chain.Ton]: ["EQCC1GV4iL5EkQqICYshf3AF7ESbceCYhVK-go1SkOMOBTNE"],
42
+ [Chain.Radix]: [] as string[],
43
+ [Chain.Harbor]: [] as string[],
44
+ };
45
+
46
+ for (const [chain, addresses] of Object.entries(validAddresses)) {
47
+ if (addresses.length === 0) continue;
48
+
49
+ test(`should validate valid ${chain} addresses`, () => {
50
+ for (const address of addresses) {
51
+ const result = context.validateAddress({ address, chain: chain as Chain });
52
+ expect(result).toBe(true);
53
+ }
54
+ });
55
+ }
56
+ });
57
+
58
+ describe("Invalid addresses should be rejected", () => {
59
+ const invalidTestCases: Array<{ chain: Chain; addresses: string[] }> = [
60
+ {
61
+ addresses: [
62
+ "",
63
+ "invalid",
64
+ "0x123",
65
+ "0xG051176f5F0B7ccC8fA0376F08aaa28F316A38a2a0",
66
+ "THr473cZqHwBLEmTWUUR1WTotxijWWbRGD",
67
+ "bc1qjpmp8xvg9k4ysa7nvev3lw7qcclvxzt2ex75kr",
68
+ "cosmos12d7d2rlxp7urkp8z0p8sft2fm07ewyjrfvul3f",
69
+ ],
70
+ chain: Chain.Ethereum,
71
+ },
72
+ {
73
+ addresses: [
74
+ "",
75
+ "invalid",
76
+ "0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0",
77
+ "THr473cZqHwBLEmTWUUR1WTotxijWWbRGD",
78
+ "cosmos12d7d2rlxp7urkp8z0p8sft2fm07ewyjrfvul3f",
79
+ "qzhcfqxrnhcw88c433tq0fjlw0uut8c0e5d3cf8566",
80
+ ],
81
+ chain: Chain.Bitcoin,
82
+ },
83
+ {
84
+ addresses: [
85
+ "",
86
+ "invalid",
87
+ "0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0",
88
+ "bc1qjpmp8xvg9k4ysa7nvev3lw7qcclvxzt2ex75kr",
89
+ "thor1hm0sdz9v2h5jwjuu0ssp8x98upvlc6py2uq4vz",
90
+ "maya1hm0sdz9v2h5jwjuu0ssp8x98upvlc6py2t7e6j",
91
+ ],
92
+ chain: Chain.Cosmos,
93
+ },
94
+ {
95
+ addresses: [
96
+ "",
97
+ "invalid",
98
+ "0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0",
99
+ "4UHWuPwyV3XCcnwrpEdWAEW3WLUP1RDMaK3ANNsRUjfM123",
100
+ "123",
101
+ ],
102
+ chain: Chain.Solana,
103
+ },
104
+ { addresses: ["", "invalid!"], chain: Chain.Near },
105
+ {
106
+ addresses: [
107
+ "",
108
+ "invalid",
109
+ "0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0",
110
+ "bc1qjpmp8xvg9k4ysa7nvev3lw7qcclvxzt2ex75kr",
111
+ ],
112
+ chain: Chain.Cardano,
113
+ },
114
+ {
115
+ addresses: [
116
+ "",
117
+ "invalid",
118
+ "0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0",
119
+ "bc1qjpmp8xvg9k4ysa7nvev3lw7qcclvxzt2ex75kr",
120
+ ],
121
+ chain: Chain.Ripple,
122
+ },
123
+ ];
124
+
125
+ for (const { chain, addresses } of invalidTestCases) {
126
+ test(`should reject invalid ${chain} addresses`, () => {
127
+ for (const address of addresses) {
128
+ const result = context.validateAddress({ address, chain });
129
+ expect(result).toBe(false);
130
+ }
131
+ });
132
+ }
133
+ });
134
+
135
+ describe("Edge cases and type safety", () => {
136
+ test("should handle non-string inputs safely", () => {
137
+ const edgeCases = [null, undefined, 123, {}, [], true, false];
138
+
139
+ for (const testCase of edgeCases) {
140
+ expect(context.validateAddress({ address: testCase as any, chain: Chain.Ethereum })).toBe(false);
141
+ }
142
+ });
143
+
144
+ test("should reject cross-chain address usage", () => {
145
+ expect(
146
+ context.validateAddress({ address: "0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0", chain: Chain.Bitcoin }),
147
+ ).toBe(false);
148
+
149
+ expect(
150
+ context.validateAddress({ address: "bc1qjpmp8xvg9k4ysa7nvev3lw7qcclvxzt2ex75kr", chain: Chain.Ethereum }),
151
+ ).toBe(false);
152
+
153
+ expect(
154
+ context.validateAddress({ address: "cosmos12d7d2rlxp7urkp8z0p8sft2fm07ewyjrfvul3f", chain: Chain.Maya }),
155
+ ).toBe(false);
156
+
157
+ expect(context.validateAddress({ address: "THr473cZqHwBLEmTWUUR1WTotxijWWbRGD", chain: Chain.Ethereum })).toBe(
158
+ false,
159
+ );
160
+ });
161
+ });
162
+ });
@@ -0,0 +1,162 @@
1
+ import { beforeAll, describe, expect, test } from "bun:test";
2
+ import { Chain } from "@uswap/helpers";
3
+ import { getAddressValidator } from "../index";
4
+
5
+ const context: { validateAddress: (params: { address: string; chain: Chain }) => boolean } = {} as any;
6
+
7
+ beforeAll(async () => {
8
+ context.validateAddress = await getAddressValidator();
9
+ });
10
+
11
+ describe("Address Validation - All Chains", () => {
12
+ describe("Valid addresses for each chain", () => {
13
+ const validAddresses = {
14
+ [Chain.Ethereum]: ["0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0"],
15
+ [Chain.Avalanche]: ["0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0"],
16
+ [Chain.Arbitrum]: ["0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0"],
17
+ [Chain.BinanceSmartChain]: ["0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0"],
18
+ [Chain.Optimism]: ["0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0"],
19
+ [Chain.Polygon]: ["0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0"],
20
+ [Chain.Base]: ["0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0"],
21
+ [Chain.Bitcoin]: ["bc1qjpmp8xvg9k4ysa7nvev3lw7qcclvxzt2ex75kr", "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"],
22
+ [Chain.BitcoinCash]: ["qzhcfqxrnhcw88c433tq0fjlw0uut8c0e5d3cf8566"],
23
+ [Chain.Dogecoin]: ["DPrKsuhVibyfMMYRmKP49US5PBQR8zq6v4"],
24
+ [Chain.Litecoin]: ["ltc1qs4h7p8x0kfhs88wazmq2d40t59dwdlxd6rlpjz"],
25
+ [Chain.Dash]: ["XoBBveBZv32rq9MMBt88QSVsUtdj9cMCLy"],
26
+ [Chain.Zcash]: ["t1Mh7QW9g1gK94CSRxniD49aLAJ67s6UerX"],
27
+ [Chain.Cosmos]: ["cosmos12d7d2rlxp7urkp8z0p8sft2fm07ewyjrfvul3f"],
28
+ [Chain.Kujira]: ["kujira12d7d2rlxp7urkp8z0p8sft2fm07ewyjrcy78ur"],
29
+ [Chain.Maya]: ["maya1hm0sdz9v2h5jwjuu0ssp8x98upvlc6py2t7e6j"],
30
+ [Chain.Noble]: ["noble12d7d2rlxp7urkp8z0p8sft2fm07ewyjrp0fhf8"],
31
+ [Chain.THORChain]: ["thor1hm0sdz9v2h5jwjuu0ssp8x98upvlc6py2uq4vz"],
32
+ [Chain.Polkadot]: ["16kQVedQo7yYoFSp2MnQ78zP39xWnFGePnZps2APEyt9K9KZ"],
33
+ [Chain.Chainflip]: ["cFPctKfXisvnrhss2eMV2VdiUNRm1F5pX4WfqkcT3ZrLKJXrS"],
34
+ [Chain.Cardano]: [
35
+ "addr1qxk2md7wufs2cas0dfxch0uu59079s7yc5k9pw8s49wpm25s8ynu4svqm7m4hd04d4jvm6e5vvyw7dm4gvpqyfklgn8qetu85s",
36
+ ],
37
+ [Chain.Near]: ["a03fafdf5f97d3c6be6bff9e55f057dda76fefbb7e149f5469248f41e812cb6e"],
38
+ [Chain.Ripple]: ["rhDQXdwWR2RstC7sLjLMbjCeWT3PuSAZVu"],
39
+ [Chain.Solana]: ["4UHWuPwyV3XCcnwrpEdWAEW3WLUP1RDMaK3ANNsRUjfM"],
40
+ [Chain.Sui]: ["0x57b861db681d8e47b586e6e9a92f6ed210dbbb440670b8122420848cf0e844fb"],
41
+ [Chain.Ton]: ["EQCC1GV4iL5EkQqICYshf3AF7ESbceCYhVK-go1SkOMOBTNE"],
42
+ [Chain.Radix]: [] as string[],
43
+ [Chain.Harbor]: [] as string[],
44
+ };
45
+
46
+ for (const [chain, addresses] of Object.entries(validAddresses)) {
47
+ if (addresses.length === 0) continue;
48
+
49
+ test(`should validate valid ${chain} addresses`, () => {
50
+ for (const address of addresses) {
51
+ const result = context.validateAddress({ address, chain: chain as Chain });
52
+ expect(result).toBe(true);
53
+ }
54
+ });
55
+ }
56
+ });
57
+
58
+ describe("Invalid addresses should be rejected", () => {
59
+ const invalidTestCases: Array<{ chain: Chain; addresses: string[] }> = [
60
+ {
61
+ addresses: [
62
+ "",
63
+ "invalid",
64
+ "0x123",
65
+ "0xG051176f5F0B7ccC8fA0376F08aaa28F316A38a2a0",
66
+ "THr473cZqHwBLEmTWUUR1WTotxijWWbRGD",
67
+ "bc1qjpmp8xvg9k4ysa7nvev3lw7qcclvxzt2ex75kr",
68
+ "cosmos12d7d2rlxp7urkp8z0p8sft2fm07ewyjrfvul3f",
69
+ ],
70
+ chain: Chain.Ethereum,
71
+ },
72
+ {
73
+ addresses: [
74
+ "",
75
+ "invalid",
76
+ "0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0",
77
+ "THr473cZqHwBLEmTWUUR1WTotxijWWbRGD",
78
+ "cosmos12d7d2rlxp7urkp8z0p8sft2fm07ewyjrfvul3f",
79
+ "qzhcfqxrnhcw88c433tq0fjlw0uut8c0e5d3cf8566",
80
+ ],
81
+ chain: Chain.Bitcoin,
82
+ },
83
+ {
84
+ addresses: [
85
+ "",
86
+ "invalid",
87
+ "0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0",
88
+ "bc1qjpmp8xvg9k4ysa7nvev3lw7qcclvxzt2ex75kr",
89
+ "thor1hm0sdz9v2h5jwjuu0ssp8x98upvlc6py2uq4vz",
90
+ "maya1hm0sdz9v2h5jwjuu0ssp8x98upvlc6py2t7e6j",
91
+ ],
92
+ chain: Chain.Cosmos,
93
+ },
94
+ {
95
+ addresses: [
96
+ "",
97
+ "invalid",
98
+ "0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0",
99
+ "4UHWuPwyV3XCcnwrpEdWAEW3WLUP1RDMaK3ANNsRUjfM123",
100
+ "123",
101
+ ],
102
+ chain: Chain.Solana,
103
+ },
104
+ { addresses: ["", "invalid!"], chain: Chain.Near },
105
+ {
106
+ addresses: [
107
+ "",
108
+ "invalid",
109
+ "0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0",
110
+ "bc1qjpmp8xvg9k4ysa7nvev3lw7qcclvxzt2ex75kr",
111
+ ],
112
+ chain: Chain.Cardano,
113
+ },
114
+ {
115
+ addresses: [
116
+ "",
117
+ "invalid",
118
+ "0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0",
119
+ "bc1qjpmp8xvg9k4ysa7nvev3lw7qcclvxzt2ex75kr",
120
+ ],
121
+ chain: Chain.Ripple,
122
+ },
123
+ ];
124
+
125
+ for (const { chain, addresses } of invalidTestCases) {
126
+ test(`should reject invalid ${chain} addresses`, () => {
127
+ for (const address of addresses) {
128
+ const result = context.validateAddress({ address, chain });
129
+ expect(result).toBe(false);
130
+ }
131
+ });
132
+ }
133
+ });
134
+
135
+ describe("Edge cases and type safety", () => {
136
+ test("should handle non-string inputs safely", () => {
137
+ const edgeCases = [null, undefined, 123, {}, [], true, false];
138
+
139
+ for (const testCase of edgeCases) {
140
+ expect(context.validateAddress({ address: testCase as any, chain: Chain.Ethereum })).toBe(false);
141
+ }
142
+ });
143
+
144
+ test("should reject cross-chain address usage", () => {
145
+ expect(
146
+ context.validateAddress({ address: "0x51176f5F0B7ccC8fA0376F08aaa28F316A38a2a0", chain: Chain.Bitcoin }),
147
+ ).toBe(false);
148
+
149
+ expect(
150
+ context.validateAddress({ address: "bc1qjpmp8xvg9k4ysa7nvev3lw7qcclvxzt2ex75kr", chain: Chain.Ethereum }),
151
+ ).toBe(false);
152
+
153
+ expect(
154
+ context.validateAddress({ address: "cosmos12d7d2rlxp7urkp8z0p8sft2fm07ewyjrfvul3f", chain: Chain.Maya }),
155
+ ).toBe(false);
156
+
157
+ expect(context.validateAddress({ address: "THr473cZqHwBLEmTWUUR1WTotxijWWbRGD", chain: Chain.Ethereum })).toBe(
158
+ false,
159
+ );
160
+ });
161
+ });
162
+ });
@@ -0,0 +1,48 @@
1
+ import { beforeAll, describe, expect, test } from "bun:test";
2
+ import { Chain } from "@uswap/helpers";
3
+ import { getCardanoToolbox } from "../toolbox";
4
+
5
+ const TEST_PHRASE = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
6
+
7
+ const context: { toolbox: Awaited<ReturnType<typeof getCardanoToolbox>> } = {} as any;
8
+
9
+ beforeAll(async () => {
10
+ context.toolbox = await getCardanoToolbox({ phrase: TEST_PHRASE });
11
+ });
12
+
13
+ describe("Cardano Toolbox", () => {
14
+ test("should validate valid Cardano addresses", () => {
15
+ const validAddresses = [
16
+ "addr_test1qz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3n0d3vllmyqwsx5wktcd8cc3sq835lu7drv2xwl2wywfgs68faae",
17
+ ];
18
+
19
+ for (const address of validAddresses) {
20
+ expect(context.toolbox.validateAddress(address)).toBe(true);
21
+ }
22
+ });
23
+
24
+ test("should reject invalid Cardano addresses", () => {
25
+ const invalidAddresses = [
26
+ "",
27
+ "invalid",
28
+ "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
29
+ "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
30
+ "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
31
+ ];
32
+
33
+ for (const address of invalidAddresses) {
34
+ expect(context.toolbox.validateAddress(address)).toBe(false);
35
+ }
36
+ });
37
+
38
+ test("should generate valid Cardano address from phrase", () => {
39
+ const address = context.toolbox.getAddress();
40
+ expect(address.startsWith("addr")).toBe(true);
41
+ });
42
+
43
+ test("should estimate transaction fee", async () => {
44
+ const fee = await context.toolbox.estimateTransactionFee();
45
+ expect(fee.chain).toBe(Chain.Cardano);
46
+ expect(fee.getValue("number")).toBeGreaterThan(0);
47
+ });
48
+ });
@@ -0,0 +1,2 @@
1
+ export * from "./toolbox";
2
+ export * from "./types";
@@ -0,0 +1,168 @@
1
+ import { AssetValue, Chain, type DerivationPathArray, getChainConfig, SwapKitError } from "@uswap/helpers";
2
+ import { match, P } from "ts-pattern";
3
+ import type { CardanoProvider } from "./index";
4
+
5
+ type CardanoSigner = CardanoProvider | { address: string };
6
+
7
+ // TODO: this should done on BE side
8
+ async function getProvider() {
9
+ const { BlockfrostProvider } = await import("@meshsdk/core");
10
+ const apiKey = "mainnet3YT7XK6NidLPlkHxxyBB5V0WzXUOTIJS"; // TODO: TEST API KEY
11
+ return new BlockfrostProvider(apiKey);
12
+ }
13
+
14
+ const ADA_ID = "lovelace";
15
+
16
+ async function getCardanoBalance(address: string) {
17
+ try {
18
+ const { MeshWallet } = await import("@meshsdk/core");
19
+ const provider = await getProvider();
20
+
21
+ const wallet = new MeshWallet({ fetcher: provider, key: { address, type: "address" }, networkId: 1 });
22
+
23
+ await wallet.init();
24
+ const balance = await wallet.getBalance();
25
+
26
+ const balances: AssetValue[] = [];
27
+
28
+ for (const asset of balance) {
29
+ if (asset.unit === ADA_ID) {
30
+ const { baseDecimal } = getChainConfig(Chain.Cardano);
31
+ balances.push(AssetValue.from({ chain: Chain.Cardano, fromBaseDecimal: baseDecimal, value: asset.quantity }));
32
+ } else {
33
+ balances.push(AssetValue.from({ asset: `${Chain.Cardano}.${asset.unit}`, value: asset.quantity }));
34
+ }
35
+ }
36
+
37
+ if (balances.length === 0) {
38
+ return [AssetValue.from({ chain: Chain.Cardano })];
39
+ }
40
+
41
+ return balances;
42
+ } catch (error) {
43
+ const errorMessage = error instanceof Error ? error.message : String(error);
44
+ console.error(`Cardano balance fetch error: ${errorMessage}`);
45
+ return [AssetValue.from({ chain: Chain.Cardano })];
46
+ }
47
+ }
48
+
49
+ export async function getCardanoAddressValidator() {
50
+ const { deserializeAddress } = await import("@meshsdk/core");
51
+
52
+ return (address: string) => {
53
+ try {
54
+ deserializeAddress(address);
55
+ return true;
56
+ } catch {
57
+ return false;
58
+ }
59
+ };
60
+ }
61
+
62
+ export async function getCardanoToolbox(
63
+ toolboxParams?:
64
+ | { signer?: CardanoSigner }
65
+ | { phrase?: string; index?: number; derivationPath?: DerivationPathArray },
66
+ ) {
67
+ const validateAddress = await getCardanoAddressValidator();
68
+ const signer = await match(toolboxParams)
69
+ .with({ phrase: P.string }, async ({ phrase }) => {
70
+ const { MeshWallet } = await import("@meshsdk/core");
71
+ const provider = await getProvider();
72
+
73
+ const wallet = new MeshWallet({
74
+ fetcher: provider,
75
+ key: { type: "mnemonic", words: phrase.split(" ") },
76
+ networkId: 1,
77
+ submitter: provider,
78
+ });
79
+
80
+ await wallet.init();
81
+ return wallet;
82
+ })
83
+ .with({ signer: P.any }, ({ signer }) => signer)
84
+ .otherwise(() => undefined);
85
+
86
+ const signerAddress = signer && "getChangeAddress" in signer ? await signer.getChangeAddress() : "";
87
+
88
+ function getAddress() {
89
+ return signerAddress || "";
90
+ }
91
+
92
+ function getBalance(addressParam?: string) {
93
+ const address = addressParam || getAddress();
94
+ if (!address) throw new SwapKitError("core_wallet_connection_not_found");
95
+ return getCardanoBalance(address);
96
+ }
97
+
98
+ function estimateTransactionFee() {
99
+ return Promise.resolve(AssetValue.from({ chain: Chain.Cardano, value: "0.01" }));
100
+ }
101
+
102
+ async function createTransaction({
103
+ recipient,
104
+ assetValue,
105
+ memo,
106
+ }: {
107
+ recipient: string;
108
+ assetValue: AssetValue;
109
+ memo?: string;
110
+ }) {
111
+ if (!signer || !("getChangeAddress" in signer)) {
112
+ throw new SwapKitError("core_wallet_connection_not_found");
113
+ }
114
+ const { Transaction } = await import("@meshsdk/core");
115
+
116
+ const [, policyId] = assetValue.symbol.split("-");
117
+ if (!assetValue.isGasAsset && !policyId) throw new SwapKitError("core_wallet_connection_not_found");
118
+
119
+ const tx = new Transaction({ initiator: signer });
120
+ tx.sendAssets({ address: recipient }, [
121
+ { quantity: assetValue.getBaseValue("string"), unit: assetValue.isGasAsset ? "lovelace" : assetValue.symbol },
122
+ ]);
123
+
124
+ if (memo) tx.setMetadata(0, memo);
125
+
126
+ const unsignedTx = await tx.build();
127
+ return { tx, unsignedTx };
128
+ }
129
+
130
+ function signTransaction(txParams: string) {
131
+ if (!signer || !("getChangeAddress" in signer)) {
132
+ throw new SwapKitError("core_wallet_connection_not_found");
133
+ }
134
+
135
+ return signer.signTx(txParams);
136
+ }
137
+
138
+ async function transfer({
139
+ recipient,
140
+ assetValue,
141
+ memo,
142
+ }: {
143
+ recipient: string;
144
+ assetValue: AssetValue;
145
+ memo?: string;
146
+ }) {
147
+ if (!signer || !("getChangeAddress" in signer)) {
148
+ throw new SwapKitError("core_wallet_connection_not_found");
149
+ }
150
+
151
+ const { unsignedTx } = await createTransaction({ assetValue, memo, recipient });
152
+ const signedTx = await signTransaction(unsignedTx);
153
+ const provider = await getProvider();
154
+ const txHash = await provider.submitTx(signedTx);
155
+
156
+ return txHash;
157
+ }
158
+
159
+ return {
160
+ createTransaction,
161
+ estimateTransactionFee,
162
+ getAddress,
163
+ getBalance,
164
+ signTransaction,
165
+ transfer,
166
+ validateAddress,
167
+ };
168
+ }
@@ -0,0 +1,10 @@
1
+ import type { getCardanoToolbox } from "./toolbox";
2
+
3
+ export type CardanoWallet = Awaited<ReturnType<typeof getCardanoToolbox>>;
4
+
5
+ export interface CardanoProvider {
6
+ connect: () => Promise<{ address: string }>;
7
+ disconnect: () => Promise<void>;
8
+ address: string | null;
9
+ signTransaction: (transaction: any) => Promise<any>;
10
+ }
@@ -0,0 +1,91 @@
1
+ import { beforeAll, describe, expect, test } from "bun:test";
2
+ import { AssetValue, Chain } from "@uswap/helpers";
3
+ import { getCosmosToolbox } from "../toolbox";
4
+
5
+ const TEST_PHRASE = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
6
+ const KNOWN_COSMOS_ADDRESS = "cosmos1r5v5srda7xfth3hn2s26txvrcrntldjumt8mhl";
7
+
8
+ const context: { toolbox: Awaited<ReturnType<typeof getCosmosToolbox>> } = {} as any;
9
+
10
+ beforeAll(async () => {
11
+ context.toolbox = await getCosmosToolbox(Chain.Cosmos, { phrase: TEST_PHRASE });
12
+ });
13
+
14
+ describe("Cosmos Toolbox", () => {
15
+ test("should validate valid Cosmos addresses", () => {
16
+ const validAddresses = [
17
+ KNOWN_COSMOS_ADDRESS,
18
+ "cosmos12d7d2rlxp7urkp8z0p8sft2fm07ewyjrfvul3f",
19
+ "cosmos1xv9tklw7d82sezh9haa573wufgy59vmwe6xxe5",
20
+ ];
21
+
22
+ for (const address of validAddresses) {
23
+ expect(context.toolbox.validateAddress(address)).toBe(true);
24
+ }
25
+ });
26
+
27
+ test("should reject invalid Cosmos addresses", () => {
28
+ const invalidAddresses = [
29
+ "",
30
+ "invalid",
31
+ "thor1xv9tklw7d82sezh9haa573wufgy59vmwzp5v3k",
32
+ "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
33
+ "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
34
+ "cosmos1invalid",
35
+ ];
36
+
37
+ for (const address of invalidAddresses) {
38
+ expect(context.toolbox.validateAddress(address)).toBe(false);
39
+ }
40
+ });
41
+
42
+ test("should generate valid Cosmos address from phrase", async () => {
43
+ const address = await context.toolbox.getAddress();
44
+ if (address) {
45
+ expect(address.startsWith("cosmos1")).toBe(true);
46
+ expect(context.toolbox.validateAddress(address)).toBe(true);
47
+ }
48
+ });
49
+
50
+ test("should use 6 decimals for ATOM", () => {
51
+ const atomValue = AssetValue.from({ chain: Chain.Cosmos, value: 3.2 });
52
+
53
+ expect(atomValue.decimal).toBe(6);
54
+ expect(atomValue.getBaseValue("string")).toBe("3200000");
55
+ });
56
+
57
+ test("should convert ATOM amounts correctly with 6 decimals", () => {
58
+ const testCases = [
59
+ { amount: 0.1, expectedBase: "100000" },
60
+ { amount: 1, expectedBase: "1000000" },
61
+ { amount: 3.2, expectedBase: "3200000" },
62
+ { amount: 10.5, expectedBase: "10500000" },
63
+ { amount: 100, expectedBase: "100000000" },
64
+ { amount: 0.000001, expectedBase: "1" },
65
+ ];
66
+
67
+ for (const { amount, expectedBase } of testCases) {
68
+ const atomValue = AssetValue.from({ chain: Chain.Cosmos, value: amount });
69
+ expect(atomValue).toMatchObject({ decimal: 6 });
70
+ expect(atomValue.getBaseValue("string")).toBe(expectedBase);
71
+ }
72
+ });
73
+
74
+ test("should fetch balance for known address", async () => {
75
+ const balances = await context.toolbox.getBalance(KNOWN_COSMOS_ADDRESS);
76
+ expect(balances[0]).toMatchObject({ chain: Chain.Cosmos, decimal: 6, symbol: "ATOM" });
77
+ });
78
+
79
+ test("should not have 8 decimal bug (would be 100x too much)", () => {
80
+ const atomValue = AssetValue.from({ chain: Chain.Cosmos, value: 3.2 });
81
+ expect(Number.parseInt(atomValue.getBaseValue("string"), 10)).toBe(3200000);
82
+ });
83
+
84
+ test("should have minimum fee of 1000 uatom to meet network requirements", async () => {
85
+ const fees = await context.toolbox.getFees();
86
+
87
+ expect(fees.average.getBaseValue("number")).toBeGreaterThanOrEqual(1000);
88
+ expect(fees.fast.getBaseValue("number")).toBeGreaterThanOrEqual(1000);
89
+ expect(fees.fastest.getBaseValue("number")).toBeGreaterThanOrEqual(1000);
90
+ });
91
+ });
@@ -0,0 +1,4 @@
1
+ export * from "./thorchainUtils";
2
+ export * from "./toolbox";
3
+ export * from "./types";
4
+ export * from "./util";
@@ -0,0 +1,22 @@
1
+ import { base64, bech32 } from "@scure/base";
2
+ import { SwapKitError } from "@uswap/helpers";
3
+ import { fromByteArray, toByteArray } from "base64-js";
4
+
5
+ export function bech32ToBase64(address: string) {
6
+ return base64.encode(Uint8Array.from(bech32.fromWords(bech32.decode(address as `${string}1${string}`).words)));
7
+ }
8
+
9
+ export function base64ToBech32(address: string, prefix = "thor") {
10
+ return bech32.encode(prefix, bech32.toWords(base64.decode(address)));
11
+ }
12
+
13
+ export function toBase64(data: Uint8Array) {
14
+ return fromByteArray(data);
15
+ }
16
+
17
+ export function fromBase64(base64String: string) {
18
+ if (!base64String.match(/^[a-zA-Z0-9+/]*={0,2}$/)) {
19
+ throw new SwapKitError("toolbox_cosmos_invalid_params", { error: "Invalid base64 string format" });
20
+ }
21
+ return toByteArray(base64String);
22
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./addressFormat";
2
+ export * from "./messages";
3
+ export * from "./registry";
4
+ export * from "./types";