@rabbitio/ui-kit 1.0.0-beta.11 → 1.0.0-beta.111

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 (381) hide show
  1. package/.env.example +1 -0
  2. package/.gitlab-ci.yml +29 -0
  3. package/.husky/commit-msg +19 -0
  4. package/.husky/pre-push +1 -0
  5. package/README.md +14 -4
  6. package/coverage/base.css +224 -0
  7. package/coverage/block-navigation.js +87 -0
  8. package/coverage/clover.xml +17666 -0
  9. package/coverage/coverage-final.json +119 -0
  10. package/coverage/favicon.png +0 -0
  11. package/coverage/index.html +1001 -0
  12. package/coverage/prettify.css +1 -0
  13. package/coverage/prettify.js +2 -0
  14. package/coverage/rabbit-ui-kit/index.html +116 -0
  15. package/coverage/rabbit-ui-kit/index.js.html +88 -0
  16. package/coverage/rabbit-ui-kit/src/common-apis/adapters/analyticsAdapters/googleAnalyticsAdapter.js.html +151 -0
  17. package/coverage/rabbit-ui-kit/src/common-apis/adapters/analyticsAdapters/index.html +146 -0
  18. package/coverage/rabbit-ui-kit/src/common-apis/adapters/analyticsAdapters/metrikaAdapter.js.html +172 -0
  19. package/coverage/rabbit-ui-kit/src/common-apis/adapters/analyticsAdapters/mixpanelAdapter.js.html +199 -0
  20. package/coverage/rabbit-ui-kit/src/common-apis/adapters/axiosAdapter.js.html +190 -0
  21. package/coverage/rabbit-ui-kit/src/common-apis/adapters/index.html +131 -0
  22. package/coverage/rabbit-ui-kit/src/common-apis/adapters/qrUtils.js.html +139 -0
  23. package/coverage/rabbit-ui-kit/src/common-apis/external-apis/apiGroups.js.html +253 -0
  24. package/coverage/rabbit-ui-kit/src/common-apis/external-apis/emailAPI.js.html +133 -0
  25. package/coverage/rabbit-ui-kit/src/common-apis/external-apis/index.html +146 -0
  26. package/coverage/rabbit-ui-kit/src/common-apis/external-apis/ipAddressProviders.js.html +391 -0
  27. package/coverage/rabbit-ui-kit/src/common-apis/globalConstants.jsx.html +94 -0
  28. package/coverage/rabbit-ui-kit/src/common-apis/index.html +116 -0
  29. package/coverage/rabbit-ui-kit/src/common-apis/models/blockchain.js.html +115 -0
  30. package/coverage/rabbit-ui-kit/src/common-apis/models/coin.js.html +829 -0
  31. package/coverage/rabbit-ui-kit/src/common-apis/models/index.html +146 -0
  32. package/coverage/rabbit-ui-kit/src/common-apis/models/protocol.js.html +100 -0
  33. package/coverage/rabbit-ui-kit/src/common-apis/services/fiatCurrenciesService.js.html +544 -0
  34. package/coverage/rabbit-ui-kit/src/common-apis/services/index.html +116 -0
  35. package/coverage/rabbit-ui-kit/src/common-apis/utils/amountUtils.js.html +1234 -0
  36. package/coverage/rabbit-ui-kit/src/common-apis/utils/cache.js.html +811 -0
  37. package/coverage/rabbit-ui-kit/src/common-apis/utils/errorUtils.js.html +211 -0
  38. package/coverage/rabbit-ui-kit/src/common-apis/utils/index.html +191 -0
  39. package/coverage/rabbit-ui-kit/src/common-apis/utils/logging/index.html +131 -0
  40. package/coverage/rabbit-ui-kit/src/common-apis/utils/logging/logger.js.html +211 -0
  41. package/coverage/rabbit-ui-kit/src/common-apis/utils/logging/logsStorage.js.html +268 -0
  42. package/coverage/rabbit-ui-kit/src/common-apis/utils/postponeExecution.js.html +118 -0
  43. package/coverage/rabbit-ui-kit/src/common-apis/utils/rabbitTicker.js.html +157 -0
  44. package/coverage/rabbit-ui-kit/src/common-apis/utils/safeStringify.js.html +235 -0
  45. package/coverage/rabbit-ui-kit/src/index.html +116 -0
  46. package/coverage/rabbit-ui-kit/src/index.js.html +382 -0
  47. package/coverage/rabbit-ui-kit/src/robust-api-caller/cacheAndConcurrentRequestsResolver.js.html +1660 -0
  48. package/coverage/rabbit-ui-kit/src/robust-api-caller/cachedRobustExternalApiCallerService.js.html +526 -0
  49. package/coverage/rabbit-ui-kit/src/robust-api-caller/cancelProcessing.js.html +172 -0
  50. package/coverage/rabbit-ui-kit/src/robust-api-caller/concurrentCalculationsMetadataHolder.js.html +310 -0
  51. package/coverage/rabbit-ui-kit/src/robust-api-caller/externalApiProvider.js.html +553 -0
  52. package/coverage/rabbit-ui-kit/src/robust-api-caller/externalServicesStatsCollector.js.html +319 -0
  53. package/coverage/rabbit-ui-kit/src/robust-api-caller/index.html +206 -0
  54. package/coverage/rabbit-ui-kit/src/robust-api-caller/robustExternalAPICallerService.js.html +997 -0
  55. package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/exolixSwapProvider.js.html +1891 -0
  56. package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/goexmeSwapProvider.js.html +2077 -0
  57. package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/index.html +191 -0
  58. package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/letsExchangeSwapProvider.js.html +1633 -0
  59. package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/swapProvider.js.html +1825 -0
  60. package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/swapspaceSwapProvider.js.html +1924 -0
  61. package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/utils.js.html +163 -0
  62. package/coverage/rabbit-ui-kit/src/swaps-lib/models/baseSwapCreationInfo.js.html +319 -0
  63. package/coverage/rabbit-ui-kit/src/swaps-lib/models/existingSwap.js.html +514 -0
  64. package/coverage/rabbit-ui-kit/src/swaps-lib/models/existingSwapWithFiatData.js.html +529 -0
  65. package/coverage/rabbit-ui-kit/src/swaps-lib/models/index.html +176 -0
  66. package/coverage/rabbit-ui-kit/src/swaps-lib/models/partner.js.html +166 -0
  67. package/coverage/rabbit-ui-kit/src/swaps-lib/models/swapProviderCoinInfo.js.html +331 -0
  68. package/coverage/rabbit-ui-kit/src/swaps-lib/services/index.html +116 -0
  69. package/coverage/rabbit-ui-kit/src/swaps-lib/services/publicSwapService.js.html +1570 -0
  70. package/coverage/rabbit-ui-kit/src/swaps-lib/utils/index.html +116 -0
  71. package/coverage/rabbit-ui-kit/src/swaps-lib/utils/swapUtils.js.html +706 -0
  72. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/arrowIcon.jsx.html +124 -0
  73. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/arrowTosca.jsx.html +127 -0
  74. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/arrowWhite.jsx.html +127 -0
  75. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/darkRectangle.jsx.html +106 -0
  76. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/determinedError.jsx.html +439 -0
  77. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/failedValidationIcon.jsx.html +202 -0
  78. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/index.html +281 -0
  79. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/infoIcon.jsx.html +133 -0
  80. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/messageIcon.jsx.html +346 -0
  81. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/noticeQuestionIcon.jsx.html +247 -0
  82. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/successfulValidationIcon.jsx.html +163 -0
  83. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/supportDialogImage.jsx.html +268 -0
  84. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/walletIcon.jsx.html +151 -0
  85. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/AssetIcon/AssetIcon.jsx.html +256 -0
  86. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/AssetIcon/index.html +116 -0
  87. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/AssetSelection/AssetSelection.jsx.html +289 -0
  88. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/AssetSelection/index.html +116 -0
  89. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/BackgroundTitle/BackgroundTitle.jsx.html +187 -0
  90. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/BackgroundTitle/index.html +116 -0
  91. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/InformationMessage/InformationMessage.jsx.html +238 -0
  92. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/InformationMessage/index.html +116 -0
  93. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Input/Input.jsx.html +634 -0
  94. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Input/index.html +116 -0
  95. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/LoadingDots/LoadingDots.jsx.html +196 -0
  96. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/LoadingDots/index.html +116 -0
  97. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/NoticeIcon/NoticeIcon.jsx.html +277 -0
  98. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/NoticeIcon/index.html +116 -0
  99. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/QrCode/QrCode.jsx.html +199 -0
  100. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/QrCode/index.html +116 -0
  101. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/RateSelector/RateSelector.jsx.html +175 -0
  102. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/RateSelector/index.html +116 -0
  103. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/SupportChat/SupportChat.jsx.html +217 -0
  104. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/SupportChat/index.html +116 -0
  105. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Textarea/Textarea.jsx.html +529 -0
  106. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Textarea/index.html +116 -0
  107. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/TitleBox/TitleBox.jsx.html +508 -0
  108. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/TitleBox/index.html +116 -0
  109. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Tooltip/Tooltip.jsx.html +316 -0
  110. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Tooltip/index.html +116 -0
  111. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/TwoLinesOfText/LinesOfText.jsx.html +313 -0
  112. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/TwoLinesOfText/index.html +116 -0
  113. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Validation/Validation.jsx.html +202 -0
  114. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Validation/index.html +116 -0
  115. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/Button/Button.jsx.html +733 -0
  116. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/Button/index.html +116 -0
  117. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/Close/Close.jsx.html +259 -0
  118. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/Close/index.html +116 -0
  119. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/LinkButton/LinkButton.jsx.html +433 -0
  120. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/LinkButton/index.html +116 -0
  121. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/RadioButtonWithText/RadioButtonWithText.jsx.html +415 -0
  122. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/RadioButtonWithText/index.html +116 -0
  123. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/AmountInput/AmountInput.jsx.html +1429 -0
  124. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/AmountInput/index.html +116 -0
  125. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/CoinPicker/CoinPicker.jsx.html +1474 -0
  126. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/CoinPicker/index.html +116 -0
  127. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/ColoredNotice/ColoredNotice.jsx.html +241 -0
  128. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/ColoredNotice/index.html +116 -0
  129. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/LineWithIconLink/LineWithIconLink.jsx.html +190 -0
  130. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/LineWithIconLink/index.html +116 -0
  131. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/LogoCarousel/LogoCarousel.jsx.html +307 -0
  132. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/LogoCarousel/index.html +116 -0
  133. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/SearchableCoinsList/SearchableCoinsList.jsx.html +427 -0
  134. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/SearchableCoinsList/index.html +116 -0
  135. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/TitledLineWithIconLink/TitledLineWithIconLink.jsx.html +181 -0
  136. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/TitledLineWithIconLink/index.html +116 -0
  137. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/CoinPickerDialogStep/CoinPickerDialogStep.jsx.html +283 -0
  138. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/CoinPickerDialogStep/index.html +116 -0
  139. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/Dialog/Dialog.jsx.html +1567 -0
  140. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/Dialog/DialogButtons/DialogButtons.jsx.html +481 -0
  141. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/Dialog/DialogButtons/index.html +116 -0
  142. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/Dialog/DialogStep/DialogStep.jsx.html +1747 -0
  143. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/Dialog/DialogStep/index.html +116 -0
  144. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/Dialog/index.html +116 -0
  145. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/SwapForm/SwapForm.jsx.html +4228 -0
  146. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/SwapForm/index.html +116 -0
  147. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/WaitlistSubscription/WaitlistSubscription.jsx.html +559 -0
  148. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/WaitlistSubscription/index.html +116 -0
  149. package/coverage/rabbit-ui-kit/src/ui-kit/components/templates/DeterminedErrorDialogStep/DeterminedErrorDialogStep.jsx.html +316 -0
  150. package/coverage/rabbit-ui-kit/src/ui-kit/components/templates/DeterminedErrorDialogStep/index.html +116 -0
  151. package/coverage/rabbit-ui-kit/src/ui-kit/hooks/index.html +146 -0
  152. package/coverage/rabbit-ui-kit/src/ui-kit/hooks/useCallHandlingErrors.js.html +166 -0
  153. package/coverage/rabbit-ui-kit/src/ui-kit/hooks/useIsHydrated.js.html +121 -0
  154. package/coverage/rabbit-ui-kit/src/ui-kit/hooks/useReferredState.js.html +157 -0
  155. package/coverage/rabbit-ui-kit/src/ui-kit/utils/index.html +176 -0
  156. package/coverage/rabbit-ui-kit/src/ui-kit/utils/inputValueProviders.js.html +235 -0
  157. package/coverage/rabbit-ui-kit/src/ui-kit/utils/searchCoins.js.html +259 -0
  158. package/coverage/rabbit-ui-kit/src/ui-kit/utils/textUtils.js.html +139 -0
  159. package/coverage/rabbit-ui-kit/src/ui-kit/utils/uiUtils.js.html +121 -0
  160. package/coverage/rabbit-ui-kit/src/ui-kit/utils/urlQueryUtils.js.html +271 -0
  161. package/coverage/rabbit-ui-kit/stories/atoms/BackgroundTitle.stories.jsx.html +202 -0
  162. package/coverage/rabbit-ui-kit/stories/atoms/LinesOfText.stories.jsx.html +283 -0
  163. package/coverage/rabbit-ui-kit/stories/atoms/LoadingDots.stories.jsx.html +226 -0
  164. package/coverage/rabbit-ui-kit/stories/atoms/QrCode.stories.jsx.html +175 -0
  165. package/coverage/rabbit-ui-kit/stories/atoms/RateSelector.stories.jsx.html +136 -0
  166. package/coverage/rabbit-ui-kit/stories/atoms/Validation.stories.jsx.html +178 -0
  167. package/coverage/rabbit-ui-kit/stories/atoms/buttons/Button.stories.jsx.html +883 -0
  168. package/coverage/rabbit-ui-kit/stories/atoms/buttons/Close.stories.jsx.html +211 -0
  169. package/coverage/rabbit-ui-kit/stories/atoms/buttons/LinkButton.stories.jsx.html +301 -0
  170. package/coverage/rabbit-ui-kit/stories/atoms/buttons/index.html +146 -0
  171. package/coverage/rabbit-ui-kit/stories/atoms/index.html +191 -0
  172. package/coverage/rabbit-ui-kit/stories/molecules/AmountInput.stories.jsx.html +289 -0
  173. package/coverage/rabbit-ui-kit/stories/molecules/CoinPicker.stories.jsx.html +322 -0
  174. package/coverage/rabbit-ui-kit/stories/molecules/ColoredNotice.stories.jsx.html +178 -0
  175. package/coverage/rabbit-ui-kit/stories/molecules/LineWithIconLink.stories.jsx.html +154 -0
  176. package/coverage/rabbit-ui-kit/stories/molecules/LogoCarousel.stories.jsx.html +235 -0
  177. package/coverage/rabbit-ui-kit/stories/molecules/TitledLineWithIconLink.stories.jsx.html +160 -0
  178. package/coverage/rabbit-ui-kit/stories/molecules/index.html +191 -0
  179. package/coverage/rabbit-ui-kit/stories/organisms/Dialog/Dialog.stories.jsx.html +523 -0
  180. package/coverage/rabbit-ui-kit/stories/organisms/Dialog/DialogButtons/DialogButtons.stories.jsx.html +328 -0
  181. package/coverage/rabbit-ui-kit/stories/organisms/Dialog/DialogButtons/index.html +116 -0
  182. package/coverage/rabbit-ui-kit/stories/organisms/Dialog/DialogStep/DialogStep.stories.jsx.html +337 -0
  183. package/coverage/rabbit-ui-kit/stories/organisms/Dialog/DialogStep/index.html +116 -0
  184. package/coverage/rabbit-ui-kit/stories/organisms/Dialog/index.html +116 -0
  185. package/coverage/rabbit-ui-kit/stories/organisms/WaitlistSubscription.stories.jsx.html +151 -0
  186. package/coverage/rabbit-ui-kit/stories/organisms/index.html +116 -0
  187. package/coverage/rabbit-ui-kit/stories/stubs/coins.jsx.html +6880 -0
  188. package/coverage/rabbit-ui-kit/stories/stubs/exampleContent.jsx.html +145 -0
  189. package/coverage/rabbit-ui-kit/stories/stubs/index.html +131 -0
  190. package/coverage/rabbit-ui-kit/stories/templates/DeterminedErrorDialogStep.stories.jsx.html +190 -0
  191. package/coverage/rabbit-ui-kit/stories/templates/index.html +116 -0
  192. package/coverage/sort-arrow-sprite.png +0 -0
  193. package/coverage/sorter.js +196 -0
  194. package/dist/global.css +197 -0
  195. package/dist/global.css.map +1 -0
  196. package/dist/index.cjs +13003 -1052
  197. package/dist/index.cjs.map +1 -1
  198. package/dist/index.css +2350 -8491
  199. package/dist/index.css.map +1 -1
  200. package/dist/index.modern.js +9951 -847
  201. package/dist/index.modern.js.map +1 -1
  202. package/dist/index.module.js +12930 -1066
  203. package/dist/index.module.js.map +1 -1
  204. package/dist/index.umd.js +12994 -1055
  205. package/dist/index.umd.js.map +1 -1
  206. package/package.json +35 -9
  207. package/raw +1000 -0
  208. package/src/common-apis/adapters/analyticsAdapters/googleAnalyticsAdapter.js +22 -0
  209. package/src/common-apis/adapters/analyticsAdapters/metrikaAdapter.js +29 -0
  210. package/src/common-apis/adapters/analyticsAdapters/mixpanelAdapter.js +38 -0
  211. package/src/common-apis/adapters/axiosAdapter.js +35 -0
  212. package/src/common-apis/adapters/qrUtils.js +18 -0
  213. package/src/common-apis/external-apis/apiGroups.js +56 -0
  214. package/src/common-apis/external-apis/emailAPI.js +16 -0
  215. package/src/common-apis/external-apis/ipAddressProviders.js +102 -0
  216. package/src/common-apis/globalConstants.jsx +3 -0
  217. package/src/{common → common-apis}/models/coin.js +98 -7
  218. package/src/{common → common-apis/services}/fiatCurrenciesService.js +4 -12
  219. package/src/common-apis/tests/integration/external-apis/ipAddressProviders/getClientIpAddress.test.js +18 -0
  220. package/src/common-apis/tests/units/utils/amountUtils/composeRateText.test.js +152 -0
  221. package/src/{common → common-apis/utils}/amountUtils.js +100 -140
  222. package/src/{common → common-apis}/utils/cache.js +15 -41
  223. package/src/{common → common-apis/utils}/errorUtils.js +15 -0
  224. package/src/{common → common-apis}/utils/logging/logger.js +7 -13
  225. package/src/common-apis/utils/postponeExecution.js +11 -0
  226. package/src/common-apis/utils/rabbitTicker.js +24 -0
  227. package/src/index.js +90 -14
  228. package/src/robust-api-caller/cacheAndConcurrentRequestsResolver.js +525 -0
  229. package/src/robust-api-caller/cachedRobustExternalApiCallerService.js +147 -0
  230. package/src/robust-api-caller/cancelProcessing.js +29 -0
  231. package/src/robust-api-caller/concurrentCalculationsMetadataHolder.js +75 -0
  232. package/src/robust-api-caller/externalApiProvider.js +156 -0
  233. package/src/robust-api-caller/externalServicesStatsCollector.js +78 -0
  234. package/src/robust-api-caller/robustExternalAPICallerService.js +304 -0
  235. package/src/robust-api-caller/tests/robustExternalAPICallerService/robustExternalAPICallerService/callExternalAPI/_performCallAttempt.test.js +533 -0
  236. package/src/robust-api-caller/tests/robustExternalAPICallerService/robustExternalAPICallerService/callExternalAPI/callExternalAPI.test.js +532 -0
  237. package/src/robust-api-caller/tests/robustExternalAPICallerService/robustExternalAPICallerService/constructor.test.js +19 -0
  238. package/src/swaps-lib/external-apis/exolixSwapProvider.js +602 -0
  239. package/src/swaps-lib/external-apis/goexmeSwapProvider.js +664 -0
  240. package/src/swaps-lib/external-apis/letsExchangeSwapProvider.js +516 -0
  241. package/src/swaps-lib/external-apis/swapProvider.js +435 -24
  242. package/src/swaps-lib/external-apis/swapspaceSwapProvider.js +613 -0
  243. package/src/swaps-lib/external-apis/utils.js +26 -0
  244. package/src/swaps-lib/models/baseSwapCreationInfo.js +78 -0
  245. package/src/swaps-lib/models/existingSwap.js +101 -16
  246. package/src/swaps-lib/models/existingSwapWithFiatData.js +148 -0
  247. package/src/swaps-lib/models/partner.js +27 -0
  248. package/src/swaps-lib/models/swapProviderCoinInfo.js +82 -0
  249. package/src/swaps-lib/services/publicSwapService.js +495 -0
  250. package/src/swaps-lib/test/external-apis/exolixSwapProvider/_fetchSupportedCurrenciesIfNeeded.test.js +34 -0
  251. package/src/swaps-lib/test/external-apis/exolixSwapProvider/createSwap.test.js +1043 -0
  252. package/src/swaps-lib/test/external-apis/exolixSwapProvider/getSwapInfo.test.js +611 -0
  253. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/_fetchSupportedCurrenciesIfNeeded.test.js +148 -0
  254. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/createSwap.test.js +115 -0
  255. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/getSwapInfo.test.js +149 -0
  256. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/integration/PairSupport.int.test.js +97 -0
  257. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/integration/_fetchSupportedCurrenciesIfNeeded.int.test.js +171 -0
  258. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/integration/createSwap.int.test.js +239 -0
  259. package/src/swaps-lib/test/external-apis/goexmeSwapProvider/integration/getSwapInfo.int.test.js +141 -0
  260. package/src/swaps-lib/test/external-apis/swapProvider/getAllSupportedCurrencies.test.js +63 -0
  261. package/src/swaps-lib/test/external-apis/swapProvider/getDepositCurrencies.test.js +73 -0
  262. package/src/swaps-lib/test/external-apis/swapProvider/getWithdrawalCurrencies.test.js +102 -0
  263. package/src/swaps-lib/test/external-apis/swapProvider/removeProtocolNameFromCoinName.test.js +152 -0
  264. package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/_fetchSupportedCurrenciesIfNeeded.test.js +536 -0
  265. package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/createSwap.test.js +1214 -0
  266. package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/getSwapInfo.test.js +1743 -0
  267. package/src/swaps-lib/test/utils/swapUtils/safeHandleRequestsLimitExceeding.test.js +80 -0
  268. package/src/swaps-lib/utils/swapUtils.js +207 -0
  269. package/{styles → src/ui-kit/assets/styles}/_functions.scss +5 -0
  270. package/{styles → src/ui-kit/assets/styles}/_mixins.scss +2 -2
  271. package/{styles → src/ui-kit/assets/styles}/_placeholder.scss +3 -3
  272. package/{styles → src/ui-kit/assets/styles}/_variables.scss +17 -15
  273. package/src/ui-kit/assets/styles/fonts/NunitoSans-Bold.ttf +0 -0
  274. package/src/ui-kit/assets/styles/fonts/NunitoSans-ExtraBold.ttf +0 -0
  275. package/src/ui-kit/assets/styles/fonts/NunitoSans-Light.ttf +0 -0
  276. package/src/ui-kit/assets/styles/fonts/NunitoSans-Regular.ttf +0 -0
  277. package/src/ui-kit/assets/styles/fonts/NunitoSans-SemiBold.ttf +0 -0
  278. package/src/ui-kit/assets/styles/global.scss +171 -0
  279. package/src/ui-kit/assets/styles/index.scss +10 -0
  280. package/src/ui-kit/assets/wrappedImages/arrowIcon.jsx +13 -0
  281. package/src/ui-kit/assets/wrappedImages/arrowTosca.jsx +14 -0
  282. package/src/ui-kit/assets/wrappedImages/arrowWhite.jsx +14 -0
  283. package/src/ui-kit/assets/wrappedImages/darkRectangle.jsx +7 -0
  284. package/src/ui-kit/assets/wrappedImages/determinedError.jsx +118 -0
  285. package/src/ui-kit/assets/wrappedImages/failedValidationIcon.jsx +39 -0
  286. package/src/ui-kit/assets/wrappedImages/infoIcon.jsx +16 -0
  287. package/src/ui-kit/assets/wrappedImages/messageIcon.jsx +87 -0
  288. package/src/ui-kit/assets/wrappedImages/noticeQuestionIcon.jsx +54 -0
  289. package/src/ui-kit/assets/wrappedImages/successfulValidationIcon.jsx +26 -0
  290. package/src/ui-kit/assets/wrappedImages/supportDialogImage.jsx +61 -0
  291. package/src/ui-kit/assets/wrappedImages/walletIcon.jsx +22 -0
  292. package/src/{components → ui-kit/components}/atoms/AssetIcon/AssetIcon.jsx +16 -14
  293. package/src/{components → ui-kit/components}/atoms/AssetIcon/asset-icon.module.scss +1 -1
  294. package/src/ui-kit/components/atoms/AssetSelection/AssetSelection.jsx +68 -0
  295. package/src/ui-kit/components/atoms/AssetSelection/asset-selection.module.scss +56 -0
  296. package/src/ui-kit/components/atoms/BackgroundTitle/BackgroundTitle.jsx +34 -0
  297. package/src/ui-kit/components/atoms/BackgroundTitle/background-title.module.scss +52 -0
  298. package/src/ui-kit/components/atoms/InformationMessage/InformationMessage.jsx +51 -0
  299. package/src/ui-kit/components/atoms/InformationMessage/information-message.module.scss +38 -0
  300. package/src/ui-kit/components/atoms/Input/Input.jsx +183 -0
  301. package/src/ui-kit/components/atoms/Input/input.module.scss +107 -0
  302. package/src/{components → ui-kit/components}/atoms/LoadingDots/LoadingDots.jsx +8 -28
  303. package/src/{components → ui-kit/components}/atoms/LoadingDots/LoadingDots.module.scss +3 -2
  304. package/src/ui-kit/components/atoms/NoticeIcon/NoticeIcon.jsx +64 -0
  305. package/src/ui-kit/components/atoms/NoticeIcon/notice-icon.module.scss +14 -0
  306. package/src/ui-kit/components/atoms/QrCode/QrCode.jsx +38 -0
  307. package/src/ui-kit/components/atoms/QrCode/qr-code.module.scss +8 -0
  308. package/src/ui-kit/components/atoms/RateSelector/RateSelector.jsx +30 -0
  309. package/src/ui-kit/components/atoms/RateSelector/rate-selector.module.scss +47 -0
  310. package/src/{components → ui-kit/components}/atoms/SupportChat/SupportChat.jsx +5 -1
  311. package/src/ui-kit/components/atoms/Textarea/Textarea.jsx +148 -0
  312. package/src/ui-kit/components/atoms/Textarea/textarea.module.scss +71 -0
  313. package/src/ui-kit/components/atoms/TitleBox/TitleBox.jsx +141 -0
  314. package/src/ui-kit/components/atoms/TitleBox/title-box.module.scss +32 -0
  315. package/src/ui-kit/components/atoms/Tooltip/Tooltip.jsx +77 -0
  316. package/src/ui-kit/components/atoms/Tooltip/tooltip.module.scss +237 -0
  317. package/src/ui-kit/components/atoms/TwoLinesOfText/LinesOfText.jsx +76 -0
  318. package/src/ui-kit/components/atoms/TwoLinesOfText/lines-of-text.module.scss +65 -0
  319. package/src/ui-kit/components/atoms/Validation/Validation.jsx +39 -0
  320. package/src/ui-kit/components/atoms/Validation/validation.module.scss +19 -0
  321. package/src/{components → ui-kit/components}/atoms/buttons/Button/Button.jsx +26 -45
  322. package/src/{components → ui-kit/components}/atoms/buttons/Button/Button.module.scss +1 -1
  323. package/src/ui-kit/components/atoms/buttons/Close/Close.jsx +58 -0
  324. package/src/ui-kit/components/atoms/buttons/Close/close.module.scss +75 -0
  325. package/src/ui-kit/components/atoms/buttons/LinkButton/LinkButton.jsx +116 -0
  326. package/src/ui-kit/components/atoms/buttons/LinkButton/link-button.module.scss +53 -0
  327. package/src/ui-kit/components/atoms/buttons/RadioButtonWithText/RadioButtonWithText.jsx +110 -0
  328. package/src/ui-kit/components/atoms/buttons/RadioButtonWithText/radio-button-with-text.module.scss +86 -0
  329. package/src/ui-kit/components/molecules/AmountInput/AmountInput.jsx +448 -0
  330. package/src/ui-kit/components/molecules/AmountInput/amount-input.module.scss +233 -0
  331. package/src/ui-kit/components/molecules/CoinPicker/CoinPicker.jsx +463 -0
  332. package/src/ui-kit/components/molecules/CoinPicker/coin-picker.module.scss +207 -0
  333. package/src/ui-kit/components/molecules/ColoredNotice/ColoredNotice.jsx +52 -0
  334. package/src/ui-kit/components/molecules/ColoredNotice/colored-notice.module.scss +36 -0
  335. package/src/ui-kit/components/molecules/LineWithIconLink/LineWithIconLink.jsx +35 -0
  336. package/src/ui-kit/components/molecules/LineWithIconLink/line-with-icon-link.module.scss +25 -0
  337. package/src/ui-kit/components/molecules/LogoCarousel/LogoCarousel.jsx +74 -0
  338. package/src/ui-kit/components/molecules/LogoCarousel/logo-carousel.module.scss +106 -0
  339. package/src/ui-kit/components/molecules/SearchableCoinsList/SearchableCoinsList.jsx +114 -0
  340. package/src/ui-kit/components/molecules/TitledLineWithIconLink/TitledLineWithIconLink.jsx +32 -0
  341. package/src/ui-kit/components/organisms/CoinPickerDialogStep/CoinPickerDialogStep.jsx +66 -0
  342. package/src/ui-kit/components/organisms/Dialog/Dialog.jsx +494 -0
  343. package/src/ui-kit/components/organisms/Dialog/DialogButtons/DialogButtons.jsx +132 -0
  344. package/src/ui-kit/components/organisms/Dialog/DialogButtons/dialog-buttons.module.scss +25 -0
  345. package/src/ui-kit/components/organisms/Dialog/DialogStep/DialogStep.jsx +554 -0
  346. package/src/ui-kit/components/organisms/Dialog/DialogStep/dialog-step.module.scss +382 -0
  347. package/src/ui-kit/components/organisms/Dialog/dialog.module.scss +226 -0
  348. package/src/ui-kit/components/organisms/SwapForm/SwapForm.jsx +1381 -0
  349. package/src/ui-kit/components/organisms/SwapForm/swap-form.module.scss +134 -0
  350. package/src/ui-kit/components/organisms/WaitlistSubscription/WaitlistSubscription.jsx +158 -0
  351. package/src/ui-kit/components/templates/DeterminedErrorDialogStep/DeterminedErrorDialogStep.jsx +77 -0
  352. package/src/ui-kit/hooks/useCallHandlingErrors.js +27 -0
  353. package/src/ui-kit/hooks/useIsHydrated.js +12 -0
  354. package/src/ui-kit/hooks/useReferredState.js +24 -0
  355. package/src/ui-kit/tests/utils/inputValueProviders/provideFormatOfFloatValueByInputString.test.js +146 -0
  356. package/src/ui-kit/tests/utils/urlQueryUtils/getQueryParameterValues.test.js +65 -0
  357. package/src/ui-kit/tests/utils/urlQueryUtils/saveQueryParameterAndValues.test.js +104 -0
  358. package/src/ui-kit/utils/inputValueProviders.js +50 -0
  359. package/src/ui-kit/utils/searchCoins.js +58 -0
  360. package/src/ui-kit/utils/textUtils.js +18 -0
  361. package/src/ui-kit/utils/uiUtils.js +12 -0
  362. package/src/ui-kit/utils/urlQueryUtils.js +62 -0
  363. package/stories/font.scss +40 -0
  364. package/stories/stubs/coins.jsx +2266 -0
  365. package/stories/stubs/exampleContent.jsx +20 -0
  366. package/styles/_global-classes.scss +0 -433
  367. package/styles/fonts/NunitoSans-Bold.ttf +0 -0
  368. package/styles/fonts/NunitoSans-ExtraBold.ttf +0 -0
  369. package/styles/fonts/NunitoSans-Light.ttf +0 -0
  370. package/styles/fonts/NunitoSans-Regular.ttf +0 -0
  371. package/styles/fonts/NunitoSans-SemiBold.ttf +0 -0
  372. package/styles/global-styles-index.scss +0 -74
  373. package/styles/index.scss +0 -33
  374. /package/src/{common → common-apis}/models/blockchain.js +0 -0
  375. /package/src/{common → common-apis}/models/protocol.js +0 -0
  376. /package/src/{common → common-apis}/utils/logging/logsStorage.js +0 -0
  377. /package/src/{common → common-apis}/utils/safeStringify.js +0 -0
  378. /package/{styles → src/ui-kit/assets/styles}/colors/_light-colors.scss +0 -0
  379. /package/{styles → src/ui-kit/assets/styles}/colors/_solid-colors.scss +0 -0
  380. /package/{styles → src/ui-kit/assets/styles}/size/_margin-size.scss +0 -0
  381. /package/{styles → src/ui-kit/assets/styles}/size/_padding-size.scss +0 -0
@@ -0,0 +1,148 @@
1
+ import sinon from "sinon";
2
+ import axios from "axios";
3
+ import should from "should";
4
+ import { describe, it, beforeEach, afterEach } from "vitest";
5
+
6
+ import { GoexmeSwapProvider } from "../../../external-apis/goexmeSwapProvider.js";
7
+ import { Cache } from "../../../../common-apis/utils/cache.js";
8
+ import { Coin } from "../../../../common-apis/models/coin.js";
9
+ import { Protocol } from "../../../../common-apis/models/protocol.js";
10
+
11
+ describe("goexmeSwapProvider::_fetchSupportedCurrenciesIfNeeded-stack", () => {
12
+ const apiOK = {
13
+ btc: { coinName: "Bitcoin", available: true, network: "", tagname: "", minamount: 0.001, maxamount: 10 },
14
+ eth: { coinName: "Ethereum", available: true, network: "erc20", tagname: "" },
15
+ usdt: { coinName: "Tether", available: false, network: "" },
16
+ };
17
+
18
+ let provider, axiosStub;
19
+ beforeEach(() => {
20
+ provider = new GoexmeSwapProvider("/", new Cache(), () => null, false);
21
+ axiosStub = sinon.stub(axios, "get");
22
+ });
23
+ afterEach(() => sinon.restore());
24
+
25
+ it("constructor sets direct URL when apiKey passed", () => {
26
+ const p = new GoexmeSwapProvider("/proxy", new Cache(), () => null, false, "key");
27
+ p._URL.should.equal("https://goexme.io/v1/api");
28
+ });
29
+
30
+ it("_convertCurrencyMeta returns null for restricted set", () => {
31
+ const restricted = new GoexmeSwapProvider("/", new Cache(), () => null, true);
32
+ should(restricted._convertCurrencyMeta("abc", { coinName: "Abc" }, new Set())).be.null();
33
+ });
34
+
35
+ it("_convertCurrencyMeta auto-constructs Coin when builder=null and unrestricted", () => {
36
+ const unrestricted = new GoexmeSwapProvider("/", new Cache(), null, false);
37
+ const info = unrestricted._convertCurrencyMeta(
38
+ "btc",
39
+ { coinName: "Bitcoin Test", network: "", available: true },
40
+ new Set()
41
+ );
42
+ info.should.have.properties({ code: "BTC", network: null });
43
+ info.coin.should.be.instanceOf(Coin);
44
+ if (info.coin.protocol) info.coin.protocol.should.be.instanceOf(Protocol);
45
+ });
46
+
47
+ it("fetches once per batch", async () => {
48
+ axiosStub.resolves({ status: 200, data: apiOK });
49
+ await provider._fetchSupportedCurrenciesIfNeeded();
50
+ await provider._fetchSupportedCurrenciesIfNeeded();
51
+ axiosStub.calledOnce.should.be.true();
52
+ provider._supportedCoins.length.should.equal(2);
53
+ provider._supportedCoins.forEach(i => i.coin.should.be.instanceOf(Coin));
54
+ });
55
+
56
+ it("skips coins with available false", async () => {
57
+ axiosStub.resolves({ status: 200, data: apiOK });
58
+ await provider._fetchSupportedCurrenciesIfNeeded();
59
+ provider._supportedCoins.some(i => i.code === "usdt").should.be.false();
60
+ });
61
+
62
+ it("throws on non-200 response", async () => {
63
+ axiosStub.resolves({ status: 500, data: {} });
64
+ await provider._fetchSupportedCurrenciesIfNeeded().should.be.rejected();
65
+ });
66
+
67
+ it("propagates axios error", async () => {
68
+ axiosStub.rejects(new Error("network"));
69
+ await provider._fetchSupportedCurrenciesIfNeeded().should.be.rejectedWith(/network/);
70
+ });
71
+ });
72
+
73
+ describe("goexmeSwapProvider::_ensurePairsLoaded", () => {
74
+ let provider, axiosStub;
75
+ beforeEach(() => {
76
+ provider = new GoexmeSwapProvider("/", new Cache(), () => null, false);
77
+ axiosStub = sinon
78
+ .stub(axios, "get")
79
+ .callsFake(url =>
80
+ url.includes("/pairs")
81
+ ? Promise.resolve({ status: 200, data: { BTC: ["ETH"] } })
82
+ : Promise.resolve({ status: 200, data: {} })
83
+ );
84
+ });
85
+ afterEach(() => sinon.restore());
86
+
87
+ it("loads pairs only once within TTL", async () => {
88
+ await provider._ensurePairsLoaded();
89
+ const calls = axiosStub.callCount;
90
+ await provider._ensurePairsLoaded();
91
+ axiosStub.callCount.should.equal(calls);
92
+ });
93
+
94
+ it("refreshes pairs after expiration", async () => {
95
+ await provider._ensurePairsLoaded();
96
+ provider._pairsCacheTimestamp -= provider.PAIRS_EXPIRATION_TIME_MS + 1000;
97
+ await provider._ensurePairsLoaded();
98
+ axiosStub.callCount.should.equal(2);
99
+ });
100
+
101
+ it("throws on non-200", async () => {
102
+ axiosStub.resetBehavior();
103
+ axiosStub.resolves({ status: 400, data: {} });
104
+ await provider._ensurePairsLoaded().should.be.rejectedWith(/Failed to load/);
105
+ });
106
+
107
+ it("stores upper-case tickers", async () => {
108
+ await provider._ensurePairsLoaded();
109
+ provider._pairsCache.should.have.property("BTC");
110
+ provider._pairsCache.BTC.has("ETH").should.be.true();
111
+ });
112
+ });
113
+
114
+ describe("goexmeSwapProvider::_fetchSupportedCurrenciesIfNeeded race", () => {
115
+ let provider, axiosStub;
116
+ beforeEach(() => {
117
+ provider = new GoexmeSwapProvider("/", new Cache(), () => null, false);
118
+ axiosStub = sinon.stub(axios, "get").resolves({
119
+ status: 200,
120
+ data: { btc: { coinName: "btc", available: true } },
121
+ });
122
+ });
123
+ afterEach(() => sinon.restore());
124
+
125
+ it("two parallel calls trigger two HTTP requests (no dedupe)", async () => {
126
+ await Promise.all([provider._fetchSupportedCurrenciesIfNeeded(), provider._fetchSupportedCurrenciesIfNeeded()]);
127
+ axiosStub.callCount.should.equal(2);
128
+ });
129
+ });
130
+
131
+ describe("goexmeSwapProvider::helpers", () => {
132
+ it("getSwapCreationInfoTtlMs returns 30 000 ms", () => {
133
+ const p = new GoexmeSwapProvider("/", new Cache());
134
+ p.getSwapCreationInfoTtlMs().should.equal(30000);
135
+ });
136
+
137
+ it("_parseGoexmeDate converts to epoch", () => {
138
+ const ts = GoexmeSwapProvider._parseGoexmeDate("01.02.2024 03:04:05");
139
+ ts.should.equal(Date.parse("2024-02-01T03:04:05Z"));
140
+ });
141
+
142
+ it("getPartnersList returns single partner", async () => {
143
+ const p = new GoexmeSwapProvider("/", new Cache());
144
+ const partners = await p.getPartnersList();
145
+ partners.should.have.length(1);
146
+ partners[0].should.have.property("name", "GoExme");
147
+ });
148
+ });
@@ -0,0 +1,115 @@
1
+ import sinon from "sinon";
2
+ import axios from "axios";
3
+ import should from "should";
4
+ import { describe, it, beforeEach, afterEach, expect } from "vitest";
5
+
6
+ import { GoexmeSwapProvider } from "../../../external-apis/goexmeSwapProvider.js";
7
+ import { Cache } from "../../../../common-apis/utils/cache.js";
8
+ import { SwapProvider } from "../../../external-apis/swapProvider.js";
9
+ import { Coin } from "../../../../common-apis/models/coin.js";
10
+ import { Blockchain } from "../../../../common-apis/models/blockchain.js";
11
+
12
+ const BTC = new Coin("Bitcoin", "BTC", "BTC", 8, null, "sat", null, null, 1, null, [], null, new Blockchain("Bitcoin"));
13
+ const ETH = new Coin(
14
+ "Ethereum",
15
+ "ETH",
16
+ "ETH",
17
+ 18,
18
+ null,
19
+ "wei",
20
+ null,
21
+ null,
22
+ 1,
23
+ null,
24
+ [],
25
+ null,
26
+ new Blockchain("Ethereum")
27
+ );
28
+
29
+ const ESTIMATION_STUB = { rate: "0.09143008", rawSwapData: { rate: "0.09143008" } };
30
+
31
+ describe("goexmeSwapProvider::createSwap", () => {
32
+ const apiOk = { result: true, id: "id1", depositAddress: "addr-in" };
33
+ let provider, axiosStub;
34
+
35
+ beforeEach(() => {
36
+ provider = new GoexmeSwapProvider("/", new Cache(), () => null, false);
37
+ provider._supportedCoins = [
38
+ { coin: BTC, code: "BTC", network: "BTC", hasExtraId: true },
39
+ { coin: ETH, code: "ETH", network: "ETH", hasExtraId: true },
40
+ ];
41
+ provider._pairsCache = { BTC: new Set(["ETH"]) };
42
+ provider._pairsCacheTimestamp = Date.now();
43
+
44
+ sinon.stub(provider, "_fetchSupportedCurrenciesIfNeeded").resolves();
45
+ axiosStub = sinon.stub(axios, "get").resolves({ status: 200, data: apiOk });
46
+ });
47
+
48
+ afterEach(() => sinon.restore());
49
+
50
+ it("fetches currencies first", async () => {
51
+ await provider.createSwap(BTC, ETH, "1", "dest", "", ESTIMATION_STUB, null, false, "memo");
52
+ provider._fetchSupportedCurrenciesIfNeeded.calledOnce.should.be.true();
53
+ });
54
+
55
+ it("sends correct query params", async () => {
56
+ await provider.createSwap(BTC, ETH, "0.2", "dest-addr", "", ESTIMATION_STUB, null, false, "memo");
57
+ const p = axiosStub.args[0][1].params;
58
+ p.should.match({
59
+ from: "BTC",
60
+ to: "ETH",
61
+ amount: "0.2",
62
+ destinationAddress: "dest-addr",
63
+ destinationTag: "memo",
64
+ });
65
+ });
66
+
67
+ it("adds fix param when fixed=true", async () => {
68
+ await provider.createSwap(BTC, ETH, "0.3", "dest", "", ESTIMATION_STUB, null, true, "memo");
69
+ axiosStub.args[0][1].params.should.have.property("fix", true);
70
+ });
71
+
72
+ it("passes refundAddress and refundTag", async () => {
73
+ await provider.createSwap(BTC, ETH, "1", "dest", "refundAddr", ESTIMATION_STUB, null, true, "memo", "123tag");
74
+ const p = axiosStub.args[0][1].params;
75
+ p.should.have.properties({ refundAddress: "refundAddr", refundTag: "123tag" });
76
+ });
77
+
78
+ it("handles 429", async () => {
79
+ axiosStub.rejects({ response: { status: 429 } });
80
+ const r = await provider.createSwap(BTC, ETH, "1", "dest", "", ESTIMATION_STUB, null, false, "memo");
81
+ r.reason.should.equal(SwapProvider.COMMON_ERRORS.REQUESTS_LIMIT_EXCEEDED);
82
+ });
83
+
84
+ it("throws internal error when API result=false", async () => {
85
+ axiosStub.resolves({ status: 200, data: { result: false } });
86
+ await expect(
87
+ provider.createSwap(BTC, ETH, "1", "dest", "", ESTIMATION_STUB, null, false, "memo")
88
+ ).rejects.toThrow(/Goexme createSwap failed/);
89
+ });
90
+
91
+ it("throws internal error when id/depositAddress missing", async () => {
92
+ axiosStub.resolves({ status: 200, data: { result: true } });
93
+ await expect(
94
+ provider.createSwap(BTC, ETH, "1", "dest", "", ESTIMATION_STUB, null, false, "memo")
95
+ ).rejects.toThrow(/Goexme createSwap failed/);
96
+ });
97
+
98
+ it("throws for unsupported coins or pairs", async () => {
99
+ provider._pairsCache = {};
100
+ await expect(
101
+ provider.createSwap(BTC, ETH, "1", "dest", "", ESTIMATION_STUB, null, false, "memo")
102
+ ).rejects.toThrow(/Unsupported pair/);
103
+ });
104
+
105
+ it("returns fully shaped DTO on success", async () => {
106
+ const r = await provider.createSwap(BTC, ETH, "1", "dest-addr", "", ESTIMATION_STUB, null, false, "memo");
107
+ r.should.match({
108
+ result: true,
109
+ swapId: "id1",
110
+ fromAddress: "addr-in",
111
+ toAddress: "dest-addr",
112
+ fixed: false,
113
+ });
114
+ });
115
+ });
@@ -0,0 +1,149 @@
1
+ import sinon from "sinon";
2
+ import axios from "axios";
3
+ import { describe, it, beforeEach, afterEach, expect } from "vitest";
4
+ import should from "should";
5
+
6
+ import { GoexmeSwapProvider } from "../../../external-apis/goexmeSwapProvider.js";
7
+ import { Cache } from "../../../../common-apis/utils/cache.js";
8
+ import { Coin } from "../../../../common-apis/models/coin.js";
9
+ import { Blockchain } from "../../../../common-apis/models/blockchain.js";
10
+ import { SwapProvider } from "../../../external-apis/swapProvider.js";
11
+
12
+ const BTC = new Coin("Bitcoin", "BTC", "BTC", 8, null, "sat", null, null, 1, null, [], null, new Blockchain("Bitcoin"));
13
+ const ETH = new Coin(
14
+ "Ethereum",
15
+ "ETH",
16
+ "ETH",
17
+ 18,
18
+ null,
19
+ "wei",
20
+ null,
21
+ null,
22
+ 1,
23
+ null,
24
+ [],
25
+ null,
26
+ new Blockchain("Ethereum")
27
+ );
28
+
29
+ describe("goexmeSwapProvider::getSwapInfo", () => {
30
+ const okRate = { result: true, rate: "15", minamount: "0.01", maxamount: "5" };
31
+ let provider, axiosStub;
32
+
33
+ beforeEach(() => {
34
+ provider = new GoexmeSwapProvider("/", new Cache(), () => null, false);
35
+ provider._supportedCoins = [
36
+ { coin: BTC, code: "BTC", network: "BTC" },
37
+ { coin: ETH, code: "ETH", network: "ETH" },
38
+ ];
39
+ provider._supportedCoinsLastUpdateTimestamp = Date.now();
40
+ sinon.stub(provider, "_fetchSupportedCurrenciesIfNeeded").resolves();
41
+ axiosStub = sinon.stub(axios, "get").callsFake(url => {
42
+ if (url.includes("/pairs")) return Promise.resolve({ status: 200, data: { BTC: ["ETH"] } });
43
+ if (url.includes("/rate")) return Promise.resolve({ status: 200, data: okRate });
44
+ return Promise.resolve({ status: 200, data: {} });
45
+ });
46
+ });
47
+
48
+ afterEach(() => sinon.restore());
49
+
50
+ it("returns NOT_SUPPORTED if pair absent", async () => {
51
+ axiosStub.withArgs(sinon.match(/\/pairs/)).resolves({ status: 200, data: { BTC: ["USDT"] } });
52
+ (await provider.getSwapInfo(BTC, ETH, "1")).reason.should.equal(SwapProvider.NO_SWAPS_REASONS.NOT_SUPPORTED);
53
+ });
54
+
55
+ it("returns TOO_LOW / TOO_HIGH against min/max", async () => {
56
+ (await provider.getSwapInfo(BTC, ETH, "0.001")).reason.should.equal(SwapProvider.NO_SWAPS_REASONS.TOO_LOW);
57
+ (await provider.getSwapInfo(BTC, ETH, "10")).reason.should.equal(SwapProvider.NO_SWAPS_REASONS.TOO_HIGH);
58
+ });
59
+
60
+ it("handles case with no min/max limits", async () => {
61
+ axiosStub.withArgs(sinon.match(/\/rate/)).resolves({ status: 200, data: { result: true, rate: "15" } });
62
+ const r = await provider.getSwapInfo(BTC, ETH, "1");
63
+ r.result.should.be.true();
64
+ });
65
+
66
+ it("maps 429 to REQUESTS_LIMIT_EXCEEDED", async () => {
67
+ axiosStub.withArgs(sinon.match(/\/rate/)).rejects({ response: { status: 429 } });
68
+ const r = await provider.getSwapInfo(BTC, ETH, "1");
69
+ r.reason.should.equal(SwapProvider.COMMON_ERRORS.REQUESTS_LIMIT_EXCEEDED);
70
+ });
71
+
72
+ it("returns valid structure on success", async () => {
73
+ const r = await provider.getSwapInfo(BTC, ETH, "1");
74
+ r.result.should.be.true();
75
+ parseFloat(r.rate).should.be.greaterThan(0);
76
+ });
77
+
78
+ it("sends proper params to /rate", async () => {
79
+ await provider.getSwapInfo(BTC, ETH, "1");
80
+ const p = axiosStub.args.find(a => a[0].includes("/rate"))[1].params;
81
+ p.should.match({ from: "BTC", to: "ETH", amount: "1" });
82
+ });
83
+
84
+ it("throws on non-Coin params", async () => {
85
+ await expect(provider.getSwapInfo({}, {}, "1")).rejects.toThrow();
86
+ });
87
+ });
88
+
89
+ describe("goexmeSwapProvider::status mapping & existing swaps", () => {
90
+ const raw = {
91
+ status: "success",
92
+ id: "swap1",
93
+ date: "21-07-2023 04:17:30",
94
+ from: "BTC",
95
+ to: "ETH",
96
+ depositAddress: "addr-in",
97
+ destinationAddress: "addr-out",
98
+ amountFrom: "1",
99
+ amountTo: "0.01",
100
+ result: true,
101
+ };
102
+ let provider, axiosStub;
103
+
104
+ beforeEach(() => {
105
+ provider = new GoexmeSwapProvider("/", new Cache(), () => null, false);
106
+ provider._supportedCoins = [
107
+ { coin: BTC, code: "BTC", network: "BTC" },
108
+ { coin: ETH, code: "ETH", network: "ETH" },
109
+ ];
110
+ sinon.stub(provider, "_fetchSupportedCurrenciesIfNeeded").resolves();
111
+ axiosStub = sinon.stub(axios, "get").resolves({ status: 200, data: raw });
112
+ });
113
+
114
+ afterEach(() => sinon.restore());
115
+
116
+ it("maps every status string", () => {
117
+ provider._mapGoexmeStatus("time_expired").should.equal(SwapProvider.SWAP_STATUSES.EXPIRED);
118
+ provider._mapGoexmeStatus("deposit_received").should.equal(SwapProvider.SWAP_STATUSES.PAYMENT_RECEIVED);
119
+ provider._mapGoexmeStatus("failed").should.equal(SwapProvider.SWAP_STATUSES.FAILED);
120
+ provider._mapGoexmeStatus("exchanging").should.equal(SwapProvider.SWAP_STATUSES.EXCHANGING);
121
+ provider._mapGoexmeStatus("reverted").should.equal(SwapProvider.SWAP_STATUSES.REFUNDED);
122
+ });
123
+
124
+ it("throws on unknown status", () => {
125
+ (() => provider._mapGoexmeStatus("weird")).should.throw(/Unknown Goexme status/);
126
+ });
127
+
128
+ it("skips 404 responses", async () => {
129
+ axiosStub.onFirstCall().resolves({ status: 404 });
130
+ axiosStub.onSecondCall().resolves({ status: 200, data: raw });
131
+ const res = await provider.getExistingSwapsDetailsAndStatus(["x", "swap1"]);
132
+ res.swaps.should.have.length(1);
133
+ res.swaps[0].swapId.should.equal("swap1");
134
+ });
135
+
136
+ it("filters out items when coins unsupported", async () => {
137
+ axiosStub.resetBehavior();
138
+ axiosStub.resolves({ status: 200, data: { ...raw, from: "LTC" } });
139
+ const res = await provider.getExistingSwapsDetailsAndStatus(["swapX"]);
140
+ res.swaps.should.eql([]);
141
+ });
142
+
143
+ it("propagates 429", async () => {
144
+ axiosStub.resetBehavior();
145
+ axiosStub.rejects({ response: { status: 429 } });
146
+ const r = await provider.getExistingSwapsDetailsAndStatus(["id"]);
147
+ r.reason.should.equal(SwapProvider.COMMON_ERRORS.REQUESTS_LIMIT_EXCEEDED);
148
+ });
149
+ });
@@ -0,0 +1,97 @@
1
+ import "dotenv/config";
2
+ import { describe, it, beforeAll, expect } from "vitest";
3
+ import { Cache } from "../../../../../common-apis/utils/cache.js";
4
+ import { GoexmeSwapProvider } from "../../../../external-apis/goexmeSwapProvider.js";
5
+
6
+ const GOEXME_API_KEY = process.env.GOEXME_API_KEY?.trim?.() || "";
7
+ const maybeDescribe = GOEXME_API_KEY ? describe : describe.skip;
8
+
9
+ /**
10
+ * ------------------------------------------------------------------
11
+ * Positive-case: every token below **must** be exchangable
12
+ * against a major counterpart (BTC, or ETH for BTC)
13
+ * ------------------------------------------------------------------
14
+ */
15
+ const ALLOWED_RABBIT_TICKERS = [
16
+ "BNBBEP20",
17
+ "BTC",
18
+ "DOGE",
19
+ "DOT",
20
+ "ETH",
21
+ // "GMTSOL",
22
+ "LTC",
23
+ "SOL",
24
+ "TRX",
25
+ "USDCERC20",
26
+ "USDTERC20",
27
+ // "USDTBEP20",
28
+ "USDTSOL",
29
+ "USDTTRC20",
30
+ "XMR",
31
+ "XRP",
32
+ ];
33
+
34
+ /**
35
+ * ------------------------------------------------------------------
36
+ * Negative-case: these tokens MUST NOT be supported by the adapter
37
+ * ------------------------------------------------------------------
38
+ */
39
+ const FORBIDDEN_TICKERS = ["ADA", "1INCH", "TRUMP"];
40
+
41
+ /**
42
+ * ------------------------------------------------------------------
43
+ * Helper – treat “pair supported” broadly:
44
+ * • response.result === true
45
+ * • OR response.reason is TOO_LOW / TOO_HIGH
46
+ * Any other outcome (NOT_SUPPORTED etc.) means the pair fails
47
+ * ------------------------------------------------------------------
48
+ */
49
+ function isPairSupported(resp, provider) {
50
+ const { TOO_LOW, TOO_HIGH } = provider.constructor.NO_SWAPS_REASONS;
51
+ return resp.result === true || [TOO_LOW, TOO_HIGH].includes(resp.reason);
52
+ }
53
+
54
+ maybeDescribe("GoexmeSwapProvider – pairs availability (live)", () => {
55
+ let provider;
56
+
57
+ beforeAll(async () => {
58
+ provider = new GoexmeSwapProvider("/", new Cache(), () => null, false, GOEXME_API_KEY);
59
+ await provider._fetchSupportedCurrenciesIfNeeded();
60
+ await provider._ensurePairsLoaded();
61
+ });
62
+
63
+ /* ------------------------------------------------------------------
64
+ * Positive tests – one per *allowed* Rabbit-ticker
65
+ * ---------------------------------------------------------------- */
66
+ ALLOWED_RABBIT_TICKERS.forEach(ticker => {
67
+ const fromTicker = ticker;
68
+ // Use BTC as the counterpart for every token except BTC itself.
69
+ const toTicker = ticker === "BTC" ? "ETH" : "BTC";
70
+
71
+ it(`supports swaps for ${fromTicker} → ${toTicker}`, async () => {
72
+ const fromCoin = provider.getCoinByTickerIfPresent(fromTicker);
73
+ const toCoin = provider.getCoinByTickerIfPresent(toTicker);
74
+
75
+ // Sanity: both coins must be known to the adapter
76
+ expect(fromCoin, "fromCoin missing").toBeTruthy();
77
+ expect(toCoin, "toCoin missing").toBeTruthy();
78
+
79
+ const resp = await provider.getSwapInfo(fromCoin, toCoin, "1", false);
80
+
81
+ expect(
82
+ isPairSupported(resp, provider),
83
+ `Pair ${fromTicker}/${toTicker} unexpectedly unsupported: ${JSON.stringify(resp)}`
84
+ ).toBe(true);
85
+ });
86
+ });
87
+
88
+ /* ------------------------------------------------------------------
89
+ * Negative tests – one per *forbidden* ticker
90
+ * ---------------------------------------------------------------- */
91
+ FORBIDDEN_TICKERS.forEach(ticker => {
92
+ it(`does NOT support swaps involving forbidden token ${ticker}`, async () => {
93
+ const coin = provider.getCoinByTickerIfPresent(ticker);
94
+ expect(coin).toBeNull();
95
+ });
96
+ });
97
+ });
@@ -0,0 +1,171 @@
1
+ import "dotenv/config";
2
+ import { describe, it, beforeEach, afterEach, expect, vi } from "vitest";
3
+ import axios from "axios";
4
+ import { Cache } from "../../../../../common-apis/utils/cache.js";
5
+ import { GoexmeSwapProvider } from "../../../../external-apis/goexmeSwapProvider.js";
6
+
7
+ const GOEXME_API_KEY = process.env.GOEXME_API_KEY?.trim?.() || "";
8
+ const maybeDescribe = GOEXME_API_KEY ? describe : describe.skip;
9
+
10
+ maybeDescribe("GoexmeSwapProvider – live integration tests", () => {
11
+ let provider;
12
+ const axiosOriginalGet = axios.get;
13
+
14
+ beforeEach(() => {
15
+ provider = new GoexmeSwapProvider("/", new Cache(), () => null, false, GOEXME_API_KEY);
16
+ });
17
+
18
+ afterEach(() => {
19
+ axios.get = axiosOriginalGet;
20
+ });
21
+
22
+ const fetchRawCurrencies = async () => {
23
+ const { data } = await axiosOriginalGet(`${provider._URL}/currencies`, {
24
+ params: { key: GOEXME_API_KEY },
25
+ });
26
+ return data;
27
+ };
28
+
29
+ it("filters out unavailable coins", async () => {
30
+ const raw = await fetchRawCurrencies();
31
+ await provider._fetchSupportedCurrenciesIfNeeded();
32
+
33
+ const providerCodes = new Set(provider._supportedCoins.map(c => c.code));
34
+ const unavailableCodes = Object.entries(raw)
35
+ .filter(([, meta]) => meta?.available === false)
36
+ .map(([code]) => code.toUpperCase());
37
+
38
+ unavailableCodes.forEach(code => expect(providerCodes.has(code)).toBe(false));
39
+ expect(providerCodes.size).toBeGreaterThan(0);
40
+ });
41
+
42
+ it("sets hasExtraId and extraIdName correctly", async () => {
43
+ const raw = await fetchRawCurrencies();
44
+ await provider._fetchSupportedCurrenciesIfNeeded();
45
+
46
+ const infoWithTag = provider._supportedCoins.find(i => i.hasExtraId);
47
+ expect(infoWithTag).toBeDefined();
48
+
49
+ const meta =
50
+ raw[infoWithTag.code] ??
51
+ Object.values(raw).find(m => (m.code ?? m.ticker ?? "").toUpperCase() === infoWithTag.code);
52
+ expect(meta).toBeDefined();
53
+ expect((meta.tagname ?? "").trim()).not.toBe("");
54
+
55
+ expect(infoWithTag.extraIdName).toBe(meta.tagname);
56
+ });
57
+
58
+ it("handles duplicate tickers across networks", async () => {
59
+ await provider._fetchSupportedCurrenciesIfNeeded();
60
+
61
+ const suffixRx = /(ERC20|TRC20|BEP20|BSC|AVALANCHEC|OPTIMISM|SOLANA|ARBITRUM)$/i;
62
+ const grouped = {};
63
+
64
+ provider._supportedCoins.forEach(i => {
65
+ const base = i.code.toUpperCase().replace(suffixRx, "");
66
+ grouped[base] = grouped[base] || [];
67
+ grouped[base].push(i);
68
+ });
69
+
70
+ const entry = Object.entries(grouped).find(([, arr]) => arr.length >= 2);
71
+ if (!entry) {
72
+ console.warn("No duplicate tickers among allowed coins – skipping duplicate assertion");
73
+ return;
74
+ }
75
+
76
+ const [, infos] = entry;
77
+ expect(infos.length).toBeGreaterThanOrEqual(2);
78
+
79
+ infos.forEach(info => {
80
+ expect(provider._findInfoByTicker(info.coin.ticker)).toBe(info);
81
+ });
82
+ });
83
+
84
+ it("uses currencies cache within TTL", async () => {
85
+ let calls = 0;
86
+ axios.get = async (...args) => {
87
+ if (args[0].includes("/currencies")) calls += 1;
88
+ return axiosOriginalGet(...args);
89
+ };
90
+
91
+ await provider._fetchSupportedCurrenciesIfNeeded();
92
+ provider._supportedCoinsLastUpdateTimestamp -= 4 * 60 * 1000;
93
+ await provider._fetchSupportedCurrenciesIfNeeded();
94
+
95
+ expect(calls).toBe(1);
96
+ });
97
+
98
+ it("reloads currencies cache after TTL expiry", async () => {
99
+ let calls = 0;
100
+ axios.get = async (...args) => {
101
+ if (args[0].includes("/currencies")) calls += 1;
102
+ return axiosOriginalGet(...args);
103
+ };
104
+
105
+ await provider._fetchSupportedCurrenciesIfNeeded();
106
+ provider._supportedCoinsLastUpdateTimestamp -= 10 * 60 * 1000;
107
+ await provider._fetchSupportedCurrenciesIfNeeded();
108
+
109
+ expect(calls).toBe(2);
110
+ });
111
+
112
+ it("uses pairs cache within TTL", async () => {
113
+ let calls = 0;
114
+ axios.get = async (...args) => {
115
+ if (args[0].includes("/pairs")) calls += 1;
116
+ return axiosOriginalGet(...args);
117
+ };
118
+
119
+ await provider._ensurePairsLoaded();
120
+ provider._pairsCacheTimestamp -= 4 * 60 * 1000;
121
+ await provider._ensurePairsLoaded();
122
+
123
+ expect(calls).toBe(1);
124
+ });
125
+
126
+ it("reloads pairs cache after TTL expiry", async () => {
127
+ let calls = 0;
128
+ axios.get = async (...args) => {
129
+ if (args[0].includes("/pairs")) calls += 1;
130
+ return axiosOriginalGet(...args);
131
+ };
132
+
133
+ await provider._ensurePairsLoaded();
134
+ provider._pairsCacheTimestamp -= 10 * 60 * 1000;
135
+ await provider._ensurePairsLoaded();
136
+
137
+ expect(calls).toBe(2);
138
+ });
139
+
140
+ it("throws on non-200 response", async () => {
141
+ axios.get = vi.fn((url, opts = {}) =>
142
+ url.endsWith("/currencies") ? Promise.resolve({ status: 500, data: {} }) : axiosOriginalGet(url, opts)
143
+ );
144
+ await expect(provider._fetchSupportedCurrenciesIfNeeded()).rejects.toThrow();
145
+ });
146
+
147
+ it("keeps cache consistent under concurrent calls", async () => {
148
+ await Promise.all([
149
+ provider._fetchSupportedCurrenciesIfNeeded(),
150
+ provider._fetchSupportedCurrenciesIfNeeded(),
151
+ provider._fetchSupportedCurrenciesIfNeeded(),
152
+ ]);
153
+
154
+ expect(provider._supportedCoins.length).toBeGreaterThan(0);
155
+ expect(provider._supportedCoinsLastUpdateTimestamp).toBeGreaterThan(0);
156
+ });
157
+
158
+ it("_mapGoexmeStatus maps every value", () => {
159
+ const m = provider._mapGoexmeStatus.bind(provider);
160
+ expect(m("new")).toBe(provider.constructor.SWAP_STATUSES.WAITING_FOR_PAYMENT);
161
+ expect(m("waiting_deposit")).toBe(provider.constructor.SWAP_STATUSES.CONFIRMING);
162
+ expect(m("deposit_received")).toBe(provider.constructor.SWAP_STATUSES.PAYMENT_RECEIVED);
163
+ expect(m("exchanging")).toBe(provider.constructor.SWAP_STATUSES.EXCHANGING);
164
+ expect(m("sending")).toBe(provider.constructor.SWAP_STATUSES.EXCHANGING);
165
+ expect(m("success")).toBe(provider.constructor.SWAP_STATUSES.COMPLETED);
166
+ expect(m("time_expired")).toBe(provider.constructor.SWAP_STATUSES.EXPIRED);
167
+ expect(m("failed")).toBe(provider.constructor.SWAP_STATUSES.FAILED);
168
+ expect(m("sending_failed")).toBe(provider.constructor.SWAP_STATUSES.FAILED);
169
+ expect(m("reverted")).toBe(provider.constructor.SWAP_STATUSES.REFUNDED);
170
+ });
171
+ });