@rabbitio/ui-kit 1.0.0-beta.110 → 1.0.0-beta.112

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 (212) hide show
  1. package/.env +1 -1
  2. package/.env.example +1 -1
  3. package/coverage/clover.xml +1411 -1410
  4. package/coverage/coverage-final.json +18 -18
  5. package/coverage/index.html +17 -17
  6. package/coverage/ui-kit/index.html +1 -1
  7. package/coverage/ui-kit/index.js.html +1 -1
  8. package/coverage/ui-kit/src/common-apis/adapters/analyticsAdapters/googleAnalyticsAdapter.js.html +1 -1
  9. package/coverage/ui-kit/src/common-apis/adapters/analyticsAdapters/index.html +1 -1
  10. package/coverage/ui-kit/src/common-apis/adapters/analyticsAdapters/metrikaAdapter.js.html +1 -1
  11. package/coverage/ui-kit/src/common-apis/adapters/analyticsAdapters/mixpanelAdapter.js.html +1 -1
  12. package/coverage/ui-kit/src/common-apis/adapters/axiosAdapter.js.html +1 -1
  13. package/coverage/ui-kit/src/common-apis/adapters/index.html +1 -1
  14. package/coverage/ui-kit/src/common-apis/adapters/qrUtils.js.html +1 -1
  15. package/coverage/ui-kit/src/common-apis/external-apis/apiGroups.js.html +1 -1
  16. package/coverage/ui-kit/src/common-apis/external-apis/emailAPI.js.html +1 -1
  17. package/coverage/ui-kit/src/common-apis/external-apis/index.html +1 -1
  18. package/coverage/ui-kit/src/common-apis/external-apis/ipAddressProviders.js.html +1 -1
  19. package/coverage/ui-kit/src/common-apis/globalConstants.jsx.html +1 -1
  20. package/coverage/ui-kit/src/common-apis/index.html +1 -1
  21. package/coverage/ui-kit/src/common-apis/models/blockchain.js.html +4 -4
  22. package/coverage/ui-kit/src/common-apis/models/coin.js.html +221 -221
  23. package/coverage/ui-kit/src/common-apis/models/index.html +1 -1
  24. package/coverage/ui-kit/src/common-apis/models/protocol.js.html +3 -3
  25. package/coverage/ui-kit/src/common-apis/services/fiatCurrenciesService.js.html +1 -1
  26. package/coverage/ui-kit/src/common-apis/services/index.html +1 -1
  27. package/coverage/ui-kit/src/common-apis/utils/amountUtils.js.html +21 -21
  28. package/coverage/ui-kit/src/common-apis/utils/cache.js.html +6 -6
  29. package/coverage/ui-kit/src/common-apis/utils/errorUtils.js.html +13 -13
  30. package/coverage/ui-kit/src/common-apis/utils/index.html +1 -1
  31. package/coverage/ui-kit/src/common-apis/utils/logging/index.html +1 -1
  32. package/coverage/ui-kit/src/common-apis/utils/logging/logger.js.html +22 -22
  33. package/coverage/ui-kit/src/common-apis/utils/logging/logsStorage.js.html +3 -3
  34. package/coverage/ui-kit/src/common-apis/utils/postponeExecution.js.html +1 -1
  35. package/coverage/ui-kit/src/common-apis/utils/rabbitTicker.js.html +10 -10
  36. package/coverage/ui-kit/src/common-apis/utils/safeStringify.js.html +27 -27
  37. package/coverage/ui-kit/src/index.html +1 -1
  38. package/coverage/ui-kit/src/index.js.html +1 -1
  39. package/coverage/ui-kit/src/robust-api-caller/cacheAndConcurrentRequestsResolver.js.html +1 -1
  40. package/coverage/ui-kit/src/robust-api-caller/cachedRobustExternalApiCallerService.js.html +1 -1
  41. package/coverage/ui-kit/src/robust-api-caller/cancelProcessing.js.html +1 -1
  42. package/coverage/ui-kit/src/robust-api-caller/concurrentCalculationsMetadataHolder.js.html +1 -1
  43. package/coverage/ui-kit/src/robust-api-caller/externalApiProvider.js.html +1 -1
  44. package/coverage/ui-kit/src/robust-api-caller/externalServicesStatsCollector.js.html +1 -1
  45. package/coverage/ui-kit/src/robust-api-caller/index.html +1 -1
  46. package/coverage/ui-kit/src/robust-api-caller/robustExternalAPICallerService.js.html +1 -1
  47. package/coverage/ui-kit/src/swaps-lib/external-apis/exolixSwapProvider.js.html +66 -45
  48. package/coverage/ui-kit/src/swaps-lib/external-apis/goexmeSwapProvider.js.html +521 -545
  49. package/coverage/ui-kit/src/swaps-lib/external-apis/index.html +27 -27
  50. package/coverage/ui-kit/src/swaps-lib/external-apis/letsExchangeSwapProvider.js.html +1 -1
  51. package/coverage/ui-kit/src/swaps-lib/external-apis/swapProvider.js.html +328 -328
  52. package/coverage/ui-kit/src/swaps-lib/external-apis/swapspaceSwapProvider.js.html +76 -52
  53. package/coverage/ui-kit/src/swaps-lib/external-apis/utils.js.html +14 -14
  54. package/coverage/ui-kit/src/swaps-lib/models/baseSwapCreationInfo.js.html +1 -1
  55. package/coverage/ui-kit/src/swaps-lib/models/existingSwap.js.html +141 -141
  56. package/coverage/ui-kit/src/swaps-lib/models/existingSwapWithFiatData.js.html +1 -1
  57. package/coverage/ui-kit/src/swaps-lib/models/index.html +1 -1
  58. package/coverage/ui-kit/src/swaps-lib/models/partner.js.html +1 -1
  59. package/coverage/ui-kit/src/swaps-lib/models/swapProviderCoinInfo.js.html +73 -73
  60. package/coverage/ui-kit/src/swaps-lib/services/index.html +1 -1
  61. package/coverage/ui-kit/src/swaps-lib/services/publicSwapService.js.html +1 -1
  62. package/coverage/ui-kit/src/swaps-lib/utils/index.html +1 -1
  63. package/coverage/ui-kit/src/swaps-lib/utils/swapUtils.js.html +1 -1
  64. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/arrowIcon.jsx.html +1 -1
  65. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/arrowTosca.jsx.html +1 -1
  66. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/arrowWhite.jsx.html +1 -1
  67. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/darkRectangle.jsx.html +1 -1
  68. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/determinedError.jsx.html +1 -1
  69. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/failedValidationIcon.jsx.html +1 -1
  70. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/index.html +1 -1
  71. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/infoIcon.jsx.html +1 -1
  72. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/messageIcon.jsx.html +1 -1
  73. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/noticeQuestionIcon.jsx.html +1 -1
  74. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/successfulValidationIcon.jsx.html +1 -1
  75. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/supportDialogImage.jsx.html +1 -1
  76. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/walletIcon.jsx.html +1 -1
  77. package/coverage/ui-kit/src/ui-kit/components/atoms/AssetIcon/AssetIcon.jsx.html +1 -1
  78. package/coverage/ui-kit/src/ui-kit/components/atoms/AssetIcon/index.html +1 -1
  79. package/coverage/ui-kit/src/ui-kit/components/atoms/AssetSelection/AssetSelection.jsx.html +1 -1
  80. package/coverage/ui-kit/src/ui-kit/components/atoms/AssetSelection/index.html +1 -1
  81. package/coverage/ui-kit/src/ui-kit/components/atoms/BackgroundTitle/BackgroundTitle.jsx.html +1 -1
  82. package/coverage/ui-kit/src/ui-kit/components/atoms/BackgroundTitle/index.html +1 -1
  83. package/coverage/ui-kit/src/ui-kit/components/atoms/InformationMessage/InformationMessage.jsx.html +1 -1
  84. package/coverage/ui-kit/src/ui-kit/components/atoms/InformationMessage/index.html +1 -1
  85. package/coverage/ui-kit/src/ui-kit/components/atoms/Input/Input.jsx.html +1 -1
  86. package/coverage/ui-kit/src/ui-kit/components/atoms/Input/index.html +1 -1
  87. package/coverage/ui-kit/src/ui-kit/components/atoms/LoadingDots/LoadingDots.jsx.html +1 -1
  88. package/coverage/ui-kit/src/ui-kit/components/atoms/LoadingDots/index.html +1 -1
  89. package/coverage/ui-kit/src/ui-kit/components/atoms/NoticeIcon/NoticeIcon.jsx.html +1 -1
  90. package/coverage/ui-kit/src/ui-kit/components/atoms/NoticeIcon/index.html +1 -1
  91. package/coverage/ui-kit/src/ui-kit/components/atoms/QrCode/QrCode.jsx.html +7 -25
  92. package/coverage/ui-kit/src/ui-kit/components/atoms/QrCode/index.html +5 -5
  93. package/coverage/ui-kit/src/ui-kit/components/atoms/RateSelector/RateSelector.jsx.html +1 -1
  94. package/coverage/ui-kit/src/ui-kit/components/atoms/RateSelector/index.html +1 -1
  95. package/coverage/ui-kit/src/ui-kit/components/atoms/SupportChat/SupportChat.jsx.html +1 -1
  96. package/coverage/ui-kit/src/ui-kit/components/atoms/SupportChat/index.html +1 -1
  97. package/coverage/ui-kit/src/ui-kit/components/atoms/Textarea/Textarea.jsx.html +1 -1
  98. package/coverage/ui-kit/src/ui-kit/components/atoms/Textarea/index.html +1 -1
  99. package/coverage/ui-kit/src/ui-kit/components/atoms/TitleBox/TitleBox.jsx.html +1 -1
  100. package/coverage/ui-kit/src/ui-kit/components/atoms/TitleBox/index.html +1 -1
  101. package/coverage/ui-kit/src/ui-kit/components/atoms/Tooltip/Tooltip.jsx.html +1 -1
  102. package/coverage/ui-kit/src/ui-kit/components/atoms/Tooltip/index.html +1 -1
  103. package/coverage/ui-kit/src/ui-kit/components/atoms/TwoLinesOfText/LinesOfText.jsx.html +1 -1
  104. package/coverage/ui-kit/src/ui-kit/components/atoms/TwoLinesOfText/index.html +1 -1
  105. package/coverage/ui-kit/src/ui-kit/components/atoms/Validation/Validation.jsx.html +1 -1
  106. package/coverage/ui-kit/src/ui-kit/components/atoms/Validation/index.html +1 -1
  107. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/Button/Button.jsx.html +1 -1
  108. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/Button/index.html +1 -1
  109. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/Close/Close.jsx.html +1 -1
  110. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/Close/index.html +1 -1
  111. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/LinkButton/LinkButton.jsx.html +1 -1
  112. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/LinkButton/index.html +1 -1
  113. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/RadioButtonWithText/RadioButtonWithText.jsx.html +1 -1
  114. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/RadioButtonWithText/index.html +1 -1
  115. package/coverage/ui-kit/src/ui-kit/components/molecules/AmountInput/AmountInput.jsx.html +1 -1
  116. package/coverage/ui-kit/src/ui-kit/components/molecules/AmountInput/index.html +1 -1
  117. package/coverage/ui-kit/src/ui-kit/components/molecules/CoinPicker/CoinPicker.jsx.html +1 -1
  118. package/coverage/ui-kit/src/ui-kit/components/molecules/CoinPicker/index.html +1 -1
  119. package/coverage/ui-kit/src/ui-kit/components/molecules/ColoredNotice/ColoredNotice.jsx.html +1 -1
  120. package/coverage/ui-kit/src/ui-kit/components/molecules/ColoredNotice/index.html +1 -1
  121. package/coverage/ui-kit/src/ui-kit/components/molecules/LineWithIconLink/LineWithIconLink.jsx.html +1 -1
  122. package/coverage/ui-kit/src/ui-kit/components/molecules/LineWithIconLink/index.html +1 -1
  123. package/coverage/ui-kit/src/ui-kit/components/molecules/LogoCarousel/LogoCarousel.jsx.html +1 -1
  124. package/coverage/ui-kit/src/ui-kit/components/molecules/LogoCarousel/index.html +1 -1
  125. package/coverage/ui-kit/src/ui-kit/components/molecules/SearchableCoinsList/SearchableCoinsList.jsx.html +1 -1
  126. package/coverage/ui-kit/src/ui-kit/components/molecules/SearchableCoinsList/index.html +1 -1
  127. package/coverage/ui-kit/src/ui-kit/components/molecules/TitledLineWithIconLink/TitledLineWithIconLink.jsx.html +1 -1
  128. package/coverage/ui-kit/src/ui-kit/components/molecules/TitledLineWithIconLink/index.html +1 -1
  129. package/coverage/ui-kit/src/ui-kit/components/organisms/CoinPickerDialogStep/CoinPickerDialogStep.jsx.html +1 -1
  130. package/coverage/ui-kit/src/ui-kit/components/organisms/CoinPickerDialogStep/index.html +1 -1
  131. package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/Dialog.jsx.html +1 -1
  132. package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/DialogButtons/DialogButtons.jsx.html +1 -1
  133. package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/DialogButtons/index.html +1 -1
  134. package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/DialogStep/DialogStep.jsx.html +1 -1
  135. package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/DialogStep/index.html +1 -1
  136. package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/index.html +1 -1
  137. package/coverage/ui-kit/src/ui-kit/components/organisms/SwapForm/SwapForm.jsx.html +1 -1
  138. package/coverage/ui-kit/src/ui-kit/components/organisms/SwapForm/index.html +1 -1
  139. package/coverage/ui-kit/src/ui-kit/components/organisms/WaitlistSubscription/WaitlistSubscription.jsx.html +1 -1
  140. package/coverage/ui-kit/src/ui-kit/components/organisms/WaitlistSubscription/index.html +1 -1
  141. package/coverage/ui-kit/src/ui-kit/components/templates/DeterminedErrorDialogStep/DeterminedErrorDialogStep.jsx.html +1 -1
  142. package/coverage/ui-kit/src/ui-kit/components/templates/DeterminedErrorDialogStep/index.html +1 -1
  143. package/coverage/ui-kit/src/ui-kit/hooks/index.html +1 -1
  144. package/coverage/ui-kit/src/ui-kit/hooks/useCallHandlingErrors.js.html +1 -1
  145. package/coverage/ui-kit/src/ui-kit/hooks/useIsHydrated.js.html +1 -1
  146. package/coverage/ui-kit/src/ui-kit/hooks/useReferredState.js.html +1 -1
  147. package/coverage/ui-kit/src/ui-kit/utils/index.html +1 -1
  148. package/coverage/ui-kit/src/ui-kit/utils/inputValueProviders.js.html +1 -1
  149. package/coverage/ui-kit/src/ui-kit/utils/searchCoins.js.html +1 -1
  150. package/coverage/ui-kit/src/ui-kit/utils/textUtils.js.html +1 -1
  151. package/coverage/ui-kit/src/ui-kit/utils/uiUtils.js.html +1 -1
  152. package/coverage/ui-kit/src/ui-kit/utils/urlQueryUtils.js.html +1 -1
  153. package/coverage/ui-kit/stories/atoms/BackgroundTitle.stories.jsx.html +1 -1
  154. package/coverage/ui-kit/stories/atoms/LinesOfText.stories.jsx.html +1 -1
  155. package/coverage/ui-kit/stories/atoms/LoadingDots.stories.jsx.html +1 -1
  156. package/coverage/ui-kit/stories/atoms/QrCode.stories.jsx.html +1 -1
  157. package/coverage/ui-kit/stories/atoms/RateSelector.stories.jsx.html +1 -1
  158. package/coverage/ui-kit/stories/atoms/Validation.stories.jsx.html +1 -1
  159. package/coverage/ui-kit/stories/atoms/buttons/Button.stories.jsx.html +1 -1
  160. package/coverage/ui-kit/stories/atoms/buttons/Close.stories.jsx.html +1 -1
  161. package/coverage/ui-kit/stories/atoms/buttons/LinkButton.stories.jsx.html +1 -1
  162. package/coverage/ui-kit/stories/atoms/buttons/index.html +1 -1
  163. package/coverage/ui-kit/stories/atoms/index.html +1 -1
  164. package/coverage/ui-kit/stories/molecules/AmountInput.stories.jsx.html +1 -1
  165. package/coverage/ui-kit/stories/molecules/CoinPicker.stories.jsx.html +1 -1
  166. package/coverage/ui-kit/stories/molecules/ColoredNotice.stories.jsx.html +1 -1
  167. package/coverage/ui-kit/stories/molecules/LineWithIconLink.stories.jsx.html +1 -1
  168. package/coverage/ui-kit/stories/molecules/LogoCarousel.stories.jsx.html +1 -1
  169. package/coverage/ui-kit/stories/molecules/TitledLineWithIconLink.stories.jsx.html +1 -1
  170. package/coverage/ui-kit/stories/molecules/index.html +1 -1
  171. package/coverage/ui-kit/stories/organisms/Dialog/Dialog.stories.jsx.html +1 -1
  172. package/coverage/ui-kit/stories/organisms/Dialog/DialogButtons/DialogButtons.stories.jsx.html +1 -1
  173. package/coverage/ui-kit/stories/organisms/Dialog/DialogButtons/index.html +1 -1
  174. package/coverage/ui-kit/stories/organisms/Dialog/DialogStep/DialogStep.stories.jsx.html +1 -1
  175. package/coverage/ui-kit/stories/organisms/Dialog/DialogStep/index.html +1 -1
  176. package/coverage/ui-kit/stories/organisms/Dialog/index.html +1 -1
  177. package/coverage/ui-kit/stories/organisms/WaitlistSubscription.stories.jsx.html +1 -1
  178. package/coverage/ui-kit/stories/organisms/index.html +1 -1
  179. package/coverage/ui-kit/stories/stubs/coins.jsx.html +1 -1
  180. package/coverage/ui-kit/stories/stubs/exampleContent.jsx.html +1 -1
  181. package/coverage/ui-kit/stories/stubs/index.html +1 -1
  182. package/coverage/ui-kit/stories/templates/DeterminedErrorDialogStep.stories.jsx.html +1 -1
  183. package/coverage/ui-kit/stories/templates/index.html +1 -1
  184. package/dist/index.cjs +94 -92
  185. package/dist/index.cjs.map +1 -1
  186. package/dist/index.css +4 -12
  187. package/dist/index.css.map +1 -1
  188. package/dist/index.modern.js +82 -78
  189. package/dist/index.modern.js.map +1 -1
  190. package/dist/index.module.js +94 -92
  191. package/dist/index.module.js.map +1 -1
  192. package/dist/index.umd.js +94 -92
  193. package/dist/index.umd.js.map +1 -1
  194. package/package.json +1 -1
  195. package/src/common-apis/tests/integration/external-apis/ipAddressProviders/getClientIpAddress.test.js +9 -5
  196. package/src/swaps-lib/external-apis/exolixSwapProvider.js +46 -39
  197. package/src/swaps-lib/external-apis/goexmeSwapProvider.js +29 -37
  198. package/src/swaps-lib/external-apis/swapspaceSwapProvider.js +54 -46
  199. package/src/swaps-lib/models/existingSwap.js +1 -1
  200. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/_convertCurrencyMeta.test.js +80 -0
  201. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/_ensurePairsLoaded.test.js +77 -0
  202. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/_fetchSupportedCurrenciesIfNeeded.test.js +50 -123
  203. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/createSwap.test.js +184 -72
  204. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/getExistingSwapsDetailsAndStatus.test.js +151 -0
  205. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/getSwapInfo.test.js +155 -104
  206. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/helpers.test.js +26 -0
  207. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/integration/PairSupport.int.test.js +57 -57
  208. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/integration/_fetchSupportedCurrenciesIfNeeded.int.test.js +289 -126
  209. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/integration/createSwap.int.test.js +320 -225
  210. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/integration/getSwapInfo.int.test.js +138 -127
  211. package/src/ui-kit/components/atoms/QrCode/QrCode.jsx +2 -8
  212. package/src/ui-kit/components/atoms/QrCode/qr-code.module.scss +4 -11
@@ -1,5 +1,7 @@
1
1
  import "dotenv/config";
2
- import { describe, it, beforeEach, afterEach, expect, vi } from "vitest";
2
+ import sinon from "sinon";
3
+ import should from "should";
4
+ import { describe, it, beforeEach, afterEach } from "vitest";
3
5
  import axios from "axios";
4
6
  import BigNumber from "bignumber.js";
5
7
 
@@ -9,231 +11,324 @@ import { GoexmeSwapProvider } from "../../../../external-apis/goexmeSwapProvider
9
11
  const GOEXME_API_KEY = process.env.GOEXME_API_KEY?.trim?.() || "";
10
12
  const maybeDescribe = GOEXME_API_KEY ? describe : describe.skip;
11
13
 
12
- maybeDescribe("GoexmeSwapProvider#createSwap – live integration", () => {
13
- let provider;
14
- const axiosOriginalGet = axios.get;
15
-
16
- beforeEach(async () => {
17
- provider = new GoexmeSwapProvider("/", new Cache(), () => null, false, GOEXME_API_KEY);
18
- await provider._fetchSupportedCurrenciesIfNeeded();
19
- await provider._ensurePairsLoaded();
20
- });
21
-
22
- afterEach(() => {
23
- axios.get = axiosOriginalGet;
24
- });
25
-
26
- const byCode = code => provider._supportedCoins.find(c => c.code === code)?.coin || null;
27
- const hasPair = (from, to) =>
28
- provider._pairsCache?.[from.code]?.has(to.code) || provider._pairsCache?.[from]?.has(to);
29
-
30
- const pickAmount = async (from, to, fallback) => {
31
- const info = await provider.getSwapInfo(from, to, fallback);
32
- if (info.result) return fallback;
33
- if (info.reason === provider.constructor.NO_SWAPS_REASONS.TOO_LOW && info.smallestMin) {
34
- return new BigNumber(info.smallestMin).times(1.1).toFixed(from.digits);
35
- }
36
- throw new Error(`Unable to pick viable amount for ${from.ticker} → ${to.ticker}`);
37
- };
38
-
39
- it("creates FLOAT BTC ETH swap", async () => {
40
- const BTC = byCode("BTC");
41
- const ETH = byCode("ETH");
42
- if (!BTC || !ETH || !hasPair(BTC, ETH)) return;
43
-
44
- const amount = await pickAmount(BTC, ETH, "0.001");
45
- const dto = await provider.createSwap(
46
- BTC,
47
- ETH,
48
- amount,
49
- "bc1qw508d6qejxtdg4y5r3zarvaryvaxxpcs",
50
- "",
51
- null,
52
- null,
53
- false
54
- );
55
-
56
- expect(dto.result).toBe(true);
57
- expect(dto.fixed).toBe(false);
58
- expect(dto.swapId).toBeTruthy();
59
- });
60
-
61
- it("creates FIXED BTC → ETH swap", async () => {
62
- const BTC = byCode("BTC");
63
- const ETH = byCode("ETH");
64
- if (!BTC || !ETH || !hasPair(BTC, ETH)) return;
65
-
66
- const amount = await pickAmount(BTC, ETH, "0.002");
67
- const dto = await provider.createSwap(
68
- BTC,
69
- ETH,
70
- amount,
71
- "bc1qw508d6qejxtdg4y5r3zarvaryvaxxpcs",
72
- "",
73
- null,
74
- null,
75
- true
76
- );
77
-
78
- expect(dto.fixed).toBe(true);
79
- expect(provider._cache.get(`goexme_fixed_ttl_${dto.swapId}`)).toBe(true);
80
- });
81
-
82
- it("creates ETH → TRX swap", async () => {
83
- const ETH = byCode("ETH");
84
- const TRX = byCode("TRX");
85
- if (!ETH || !TRX || !hasPair(ETH, TRX)) return;
86
-
87
- const amount = await pickAmount(ETH, TRX, "0.05");
88
- const dto = await provider.createSwap(
89
- ETH,
90
- TRX,
91
- amount,
92
- "T123456789012345678901234567890123",
93
- "",
94
- null,
95
- null,
96
- false
97
- );
98
-
99
- expect(dto.result).toBe(true);
100
- expect(dto.fromCoin.ticker).toBe("ETH");
101
- expect(dto.toCoin.ticker).toBe("TRX");
102
- });
103
-
104
- it("creates XMR → BTC swap", async () => {
105
- const XMR = byCode("XMR");
106
- const BTC = byCode("BTC");
107
- if (!XMR || !BTC || !hasPair(XMR, BTC)) return;
108
-
109
- const amount = await pickAmount(XMR, BTC, "1");
110
- const dto = await provider.createSwap(
111
- XMR,
112
- BTC,
113
- amount,
114
- "bc1qw508d6qejxtdg4y5r3zarvaryvaxxpcs",
115
- "",
116
- null,
117
- null,
118
- false
119
- );
120
-
121
- expect(dto.result).toBe(true);
122
- expect(dto.fromCoin.ticker).toBe("XMR");
123
- expect(dto.toCoin.ticker).toBe("BTC");
124
- });
125
-
126
- it("creates USDT(TRC20) → ETH swap", async () => {
127
- const USDTTRC20 = byCode("USDTTRC20");
128
- const ETH = byCode("ETH");
129
- if (!USDTTRC20 || !ETH || !hasPair(USDTTRC20, ETH)) return;
130
-
131
- const amount = await pickAmount(USDTTRC20, ETH, "400");
132
- const dto = await provider.createSwap(
133
- USDTTRC20,
134
- ETH,
135
- amount,
136
- "0xAb5801a7D398351b8bE11C439e05C5b3259aec9B",
137
- "",
138
- null,
139
- null,
140
- false
141
- );
142
-
143
- expect(dto.result).toBe(true);
144
- expect(dto.fromCoin.ticker.toUpperCase()).toMatch(/USDT.*TRC20/);
145
- expect(dto.toCoin.ticker).toBe("ETH");
146
- });
147
-
148
- it("passes refund address to exchange-create call", async () => {
149
- const USDT = byCode("USDT");
150
- const BTC = byCode("BTC");
151
- if (!USDT || !BTC || !hasPair(USDT, BTC)) return;
152
-
153
- const refundAddr = "0xebb97aa373adec59b33959d2dd67da54dcc0ae00";
154
- let capturedParams = null;
155
-
156
- axios.get = async (url, cfg = {}) => {
157
- if (url.endsWith("/exchange-create")) capturedParams = cfg.params;
158
- return axiosOriginalGet(url, cfg);
159
- };
160
-
161
- const amount = await pickAmount(USDT, BTC, "1000");
162
- await provider.createSwap(
163
- USDT,
164
- BTC,
165
- amount,
166
- "bc1qw508d6qejxtdg4y5r3zarvaryvaxxpcs",
167
- refundAddr,
168
- null,
169
- null,
170
- false
171
- );
172
-
173
- expect(capturedParams?.refundAddress).toBe(refundAddr);
174
- });
175
-
176
- it("adds destinationTag when target coin requires it", async () => {
177
- const BTC = byCode("BTC");
178
- const XRP = byCode("XRP");
179
- if (!BTC || !XRP || !hasPair(BTC, XRP)) return;
180
-
181
- let capturedParams = null;
182
- axios.get = async (url, cfg = {}) => {
183
- if (url.endsWith("/exchange-create")) capturedParams = cfg.params;
184
- return axiosOriginalGet(url, cfg);
14
+ maybeDescribe("external-apis/goexmeSwapProvider integration", function () {
15
+ describe("createSwap (live)", function () {
16
+ let provider;
17
+ let axiosOriginalGet;
18
+
19
+ beforeEach(async () => {
20
+ provider = new GoexmeSwapProvider("/", new Cache(), () => null, false, GOEXME_API_KEY);
21
+ await provider._fetchSupportedCurrenciesIfNeeded();
22
+ await provider._ensurePairsLoaded();
23
+ axiosOriginalGet = axios.get;
24
+ });
25
+
26
+ afterEach(() => {
27
+ if (axios.get.restore) {
28
+ axios.get.restore();
29
+ } else {
30
+ axios.get = axiosOriginalGet;
31
+ }
32
+ });
33
+
34
+ const getCoinByCode = code => provider._supportedCoins.find(c => c.code === code)?.coin || null;
35
+ const pairSupported = (fromCoin, toCoin) =>
36
+ provider._pairsCache?.[fromCoin.code]?.has(toCoin.code) || provider._pairsCache?.[fromCoin]?.has(toCoin);
37
+
38
+ const pickValidAmount = async (fromCoin, toCoin, fallbackAmount) => {
39
+ const info = await provider.getSwapInfo(fromCoin, toCoin, fallbackAmount);
40
+ if (info.result) return fallbackAmount;
41
+ if (info.reason === provider.constructor.NO_SWAPS_REASONS.TOO_LOW && info.smallestMin) {
42
+ return new BigNumber(info.smallestMin).times(1.1).toFixed(fromCoin.digits);
43
+ }
44
+ throw new Error(`Unable to pick viable amount for ${fromCoin.ticker} → ${toCoin.ticker}`);
185
45
  };
186
46
 
187
- const amount = await pickAmount(BTC, XRP, "0.002");
188
- await provider.createSwap(
189
- BTC,
190
- XRP,
191
- amount,
192
- "rUpy3eEg8rqjqfUoLeBnZkscbKbfsPrgd",
193
- "",
194
- null,
195
- null,
196
- false,
197
- "MEMO123"
198
- );
199
-
200
- expect(capturedParams?.destinationTag).toBe("MEMO123");
201
- });
202
-
203
- it("omits destinationTag when target coin has no extraId", async () => {
204
- const BTC = byCode("BTC");
205
- const ETH = byCode("ETH");
206
- if (!BTC || !ETH || !hasPair(BTC, ETH)) return;
207
-
208
- let capturedParams = null;
209
- axios.get = async (url, cfg = {}) => {
210
- if (url.endsWith("/exchange-create")) capturedParams = cfg.params;
211
- return axiosOriginalGet(url, cfg);
212
- };
213
-
214
- const amount = await pickAmount(BTC, ETH, "0.001");
215
- await provider.createSwap(
216
- BTC,
217
- ETH,
218
- amount,
219
- "0xAb5801a7D398351b8bE11C439e05C5b3259aec9B",
220
- "",
221
- null,
222
- null,
223
- false
224
- );
225
-
226
- expect(capturedParams).not.toHaveProperty("destinationTag");
227
- });
228
-
229
- it("returns pairNotSupported for JOE → TRX", async () => {
230
- const JOE = byCode("JOE");
231
- const TRX = byCode("TRX");
232
- if (!JOE || !TRX) return;
233
-
234
- const info = await provider.getSwapInfo(JOE, TRX, "50");
235
-
236
- expect(info.result).toBe(false);
237
- expect(info.reason).toBe(provider.constructor.NO_SWAPS_REASONS.NOT_SUPPORTED);
47
+ it("Should create a FLOAT BTC→ETH swap", async () => {
48
+ const btcCoin = getCoinByCode("BTC");
49
+ const ethCoin = getCoinByCode("ETH");
50
+ if (!btcCoin || !ethCoin || !pairSupported(btcCoin, ethCoin)) return;
51
+
52
+ const amount = await pickValidAmount(btcCoin, ethCoin, "0.001");
53
+ const result = await provider.createSwap(
54
+ btcCoin,
55
+ ethCoin,
56
+ amount,
57
+ "bc1qw508d6qejxtdg4y5r3zarvaryvaxxpcs",
58
+ "",
59
+ null,
60
+ null,
61
+ false
62
+ );
63
+
64
+ result.result.should.be.true();
65
+ result.fixed.should.be.false();
66
+ should.exist(result.swapId);
67
+ });
68
+
69
+ it("Should create a FIXED BTC→ETH swap and cache TTL", async () => {
70
+ const btcCoin = getCoinByCode("BTC");
71
+ const ethCoin = getCoinByCode("ETH");
72
+ if (!btcCoin || !ethCoin || !pairSupported(btcCoin, ethCoin)) return;
73
+
74
+ const amount = await pickValidAmount(btcCoin, ethCoin, "0.002");
75
+ const result = await provider.createSwap(
76
+ btcCoin,
77
+ ethCoin,
78
+ amount,
79
+ "bc1qw508d6qejxtdg4y5r3zarvaryvaxxpcs",
80
+ "",
81
+ null,
82
+ null,
83
+ true
84
+ );
85
+
86
+ result.fixed.should.be.true();
87
+ provider._cache.get(`goexme_fixed_ttl_${result.swapId}`).should.be.true();
88
+ });
89
+
90
+ it("Should create an ETH→TRX swap", async () => {
91
+ const ethCoin = getCoinByCode("ETH");
92
+ const trxCoin = getCoinByCode("TRX");
93
+ if (!ethCoin || !trxCoin || !pairSupported(ethCoin, trxCoin)) return;
94
+
95
+ const amount = await pickValidAmount(ethCoin, trxCoin, "0.05");
96
+ const result = await provider.createSwap(
97
+ ethCoin,
98
+ trxCoin,
99
+ amount,
100
+ "T123456789012345678901234567890123",
101
+ "",
102
+ null,
103
+ null,
104
+ false
105
+ );
106
+
107
+ result.result.should.be.true();
108
+ result.fromCoin.ticker.should.equal("ETH");
109
+ result.toCoin.ticker.should.equal("TRX");
110
+ });
111
+
112
+ it("Should create an XMR→BTC swap", async () => {
113
+ const xmrCoin = getCoinByCode("XMR");
114
+ const btcCoin = getCoinByCode("BTC");
115
+ if (!xmrCoin || !btcCoin || !pairSupported(xmrCoin, btcCoin)) return;
116
+
117
+ const amount = await pickValidAmount(xmrCoin, btcCoin, "1");
118
+ const result = await provider.createSwap(
119
+ xmrCoin,
120
+ btcCoin,
121
+ amount,
122
+ "bc1qw508d6qejxtdg4y5r3zarvaryvaxxpcs",
123
+ "",
124
+ null,
125
+ null,
126
+ false
127
+ );
128
+
129
+ result.result.should.be.true();
130
+ result.fromCoin.ticker.should.equal("XMR");
131
+ result.toCoin.ticker.should.equal("BTC");
132
+ });
133
+
134
+ it("Should create a USDT(TRC20)→ETH swap", async () => {
135
+ const usdtTrc20Coin = getCoinByCode("USDTTRC20");
136
+ const ethCoin = getCoinByCode("ETH");
137
+ if (!usdtTrc20Coin || !ethCoin || !pairSupported(usdtTrc20Coin, ethCoin)) return;
138
+
139
+ const amount = await pickValidAmount(usdtTrc20Coin, ethCoin, "400");
140
+ const result = await provider.createSwap(
141
+ usdtTrc20Coin,
142
+ ethCoin,
143
+ amount,
144
+ "0xAb5801a7D398351b8bE11C439e05C5b3259aec9B",
145
+ "",
146
+ null,
147
+ null,
148
+ false
149
+ );
150
+
151
+ result.result.should.be.true();
152
+ result.fromCoin.ticker.toUpperCase().should.match(/USDT.*TRC20/);
153
+ result.toCoin.ticker.should.equal("ETH");
154
+ });
155
+
156
+ it("Should pass refund address to exchange‑create call", async () => {
157
+ const usdtCoin = getCoinByCode("USDT");
158
+ const btcCoin = getCoinByCode("BTC");
159
+ if (!usdtCoin || !btcCoin || !pairSupported(usdtCoin, btcCoin)) return;
160
+
161
+ const refundAddress = "0xebb97aa373adec59b33959d2dd67da54dcc0ae00";
162
+ let capturedParams = null;
163
+
164
+ const getStub = sinon.stub(axios, "get").callsFake((url, cfg = {}) => {
165
+ if (url.endsWith("/exchange-create")) capturedParams = cfg.params;
166
+ return axiosOriginalGet(url, cfg);
167
+ });
168
+
169
+ const amount = await pickValidAmount(usdtCoin, btcCoin, "1000");
170
+ await provider.createSwap(
171
+ usdtCoin,
172
+ btcCoin,
173
+ amount,
174
+ "bc1qw508d6qejxtdg4y5r3zarvaryvaxxpcs",
175
+ refundAddress,
176
+ null,
177
+ null,
178
+ false
179
+ );
180
+
181
+ capturedParams.should.have.property("refundAddress", refundAddress);
182
+ getStub.restore();
183
+ });
184
+
185
+ it("Should add destinationTag when target coin requires it", async () => {
186
+ const btcCoin = getCoinByCode("BTC");
187
+ const xrpCoin = getCoinByCode("XRP");
188
+ if (!btcCoin || !xrpCoin || !pairSupported(btcCoin, xrpCoin)) return;
189
+
190
+ let capturedParams = null;
191
+ const getStub = sinon.stub(axios, "get").callsFake((url, cfg = {}) => {
192
+ if (url.endsWith("/exchange-create")) capturedParams = cfg.params;
193
+ return axiosOriginalGet(url, cfg);
194
+ });
195
+
196
+ const amount = await pickValidAmount(btcCoin, xrpCoin, "0.002");
197
+ await provider.createSwap(
198
+ btcCoin,
199
+ xrpCoin,
200
+ amount,
201
+ "rUpy3eEg8rqjqfUoLeBnZkscbKbfsPrgd",
202
+ "",
203
+ null,
204
+ null,
205
+ false,
206
+ "MEMO123"
207
+ );
208
+
209
+ capturedParams.should.have.property("destinationTag", "MEMO123");
210
+ getStub.restore();
211
+ });
212
+
213
+ it("Should omit destinationTag when target coin has no extraId", async () => {
214
+ const btcCoin = getCoinByCode("BTC");
215
+ const ethCoin = getCoinByCode("ETH");
216
+ if (!btcCoin || !ethCoin || !pairSupported(btcCoin, ethCoin)) return;
217
+
218
+ let capturedParams = null;
219
+ const getStub = sinon.stub(axios, "get").callsFake((url, cfg = {}) => {
220
+ if (url.endsWith("/exchange-create")) capturedParams = cfg.params;
221
+ return axiosOriginalGet(url, cfg);
222
+ });
223
+
224
+ const amount = await pickValidAmount(btcCoin, ethCoin, "0.001");
225
+ await provider.createSwap(
226
+ btcCoin,
227
+ ethCoin,
228
+ amount,
229
+ "0xAb5801a7D398351b8bE11C439e05C5b3259aec9B",
230
+ "",
231
+ null,
232
+ null,
233
+ false
234
+ );
235
+
236
+ should(capturedParams).not.have.property("destinationTag");
237
+ getStub.restore();
238
+ });
239
+
240
+ it("Should throw when amountIsToReceive=true", async () => {
241
+ const btcCoin = getCoinByCode("BTC");
242
+ const ethCoin = getCoinByCode("ETH");
243
+ if (!btcCoin || !ethCoin || !pairSupported(btcCoin, ethCoin)) return;
244
+
245
+ const amount = await pickValidAmount(btcCoin, ethCoin, "0.001");
246
+ await provider
247
+ .createSwap(
248
+ btcCoin,
249
+ ethCoin,
250
+ amount,
251
+ "bc1qw508d6qejxtdg4y5r3zarvaryvaxxpcs",
252
+ "",
253
+ null,
254
+ null,
255
+ false,
256
+ "",
257
+ "",
258
+ true
259
+ )
260
+ .should.be.rejected();
261
+ });
262
+
263
+ it("Should throw when destinationTag is required but not provided", async () => {
264
+ const btcCoin = getCoinByCode("BTC");
265
+ const xrpCoin = getCoinByCode("XRP");
266
+ if (!btcCoin || !xrpCoin || !pairSupported(btcCoin, xrpCoin)) return;
267
+
268
+ const amount = await pickValidAmount(btcCoin, xrpCoin, "0.002");
269
+ await provider
270
+ .createSwap(btcCoin, xrpCoin, amount, "rUpy3eEg8rqjqfUoLeBnZkscbKbfsPrgd", "", null, null, false, "")
271
+ .should.be.rejected();
272
+ });
273
+
274
+ it("Should not include refundTag when source coin has no extraId", async () => {
275
+ const btcCoin = getCoinByCode("BTC");
276
+ const ethCoin = getCoinByCode("ETH");
277
+ if (!btcCoin || !ethCoin || !pairSupported(btcCoin, ethCoin)) return;
278
+
279
+ let capturedParams = null;
280
+ const getStub = sinon.stub(axios, "get").callsFake((url, cfg = {}) => {
281
+ if (url.endsWith("/exchange-create")) capturedParams = cfg.params;
282
+ return axiosOriginalGet(url, cfg);
283
+ });
284
+
285
+ const amount = await pickValidAmount(btcCoin, ethCoin, "0.001");
286
+ await provider.createSwap(
287
+ btcCoin,
288
+ ethCoin,
289
+ amount,
290
+ "bc1qw508d6qejxtdg4y5r3zarvaryvaxxpcs",
291
+ "1BitcoinRefundAddrxxxxxxxxxxxx",
292
+ null,
293
+ null,
294
+ false
295
+ );
296
+
297
+ should(capturedParams).not.have.property("refundTag");
298
+ getStub.restore();
299
+ });
300
+
301
+ it("Should compute toAmount from rate×amount when amountTo not returned", async () => {
302
+ const btcCoin = getCoinByCode("BTC");
303
+ const ethCoin = getCoinByCode("ETH");
304
+ if (!btcCoin || !ethCoin || !pairSupported(btcCoin, ethCoin)) return;
305
+
306
+ const amount = await pickValidAmount(btcCoin, ethCoin, "0.003");
307
+ const result = await provider.createSwap(
308
+ btcCoin,
309
+ ethCoin,
310
+ amount,
311
+ "bc1qw508d6qejxtdg4y5r3zarvaryvaxxpcs",
312
+ "",
313
+ null,
314
+ null,
315
+ false
316
+ );
317
+
318
+ const expected = new BigNumber(result.fromAmount)
319
+ .times(result.rate)
320
+ .decimalPlaces(result.toCoin.digits, BigNumber.ROUND_DOWN);
321
+ new BigNumber(result.toAmount).eq(expected).should.be.true();
322
+ });
323
+
324
+ it("Should return NOT_SUPPORTED for JOE→TRX pair", async () => {
325
+ const joeCoin = getCoinByCode("JOE");
326
+ const trxCoin = getCoinByCode("TRX");
327
+ if (!joeCoin || !trxCoin) return;
328
+
329
+ const info = await provider.getSwapInfo(joeCoin, trxCoin, "50");
330
+ info.result.should.be.false();
331
+ info.reason.should.equal(provider.constructor.NO_SWAPS_REASONS.NOT_SUPPORTED);
332
+ });
238
333
  });
239
334
  });