@rabbitio/ui-kit 1.0.0-beta.9 → 1.0.0-beta.91

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 (369) hide show
  1. package/.gitlab-ci.yml +29 -0
  2. package/.husky/commit-msg +19 -0
  3. package/.husky/pre-push +1 -0
  4. package/CHANGELOG.md +0 -0
  5. package/README.md +27 -18
  6. package/coverage/base.css +224 -0
  7. package/coverage/block-navigation.js +87 -0
  8. package/coverage/clover.xml +16765 -0
  9. package/coverage/coverage-final.json +116 -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 +148 -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 +169 -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 +250 -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 +352 -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 +1162 -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 +208 -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 +376 -0
  47. package/coverage/rabbit-ui-kit/src/robust-api-caller/cacheAndConcurrentRequestsResolver.js.html +1570 -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 +1825 -0
  56. package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/index.html +161 -0
  57. package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/letsExchangeSwapProvider.js.html +1618 -0
  58. package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/swapProvider.js.html +1819 -0
  59. package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/swapspaceSwapProvider.js.html +1861 -0
  60. package/coverage/rabbit-ui-kit/src/swaps-lib/models/baseSwapCreationInfo.js.html +319 -0
  61. package/coverage/rabbit-ui-kit/src/swaps-lib/models/existingSwap.js.html +514 -0
  62. package/coverage/rabbit-ui-kit/src/swaps-lib/models/existingSwapWithFiatData.js.html +529 -0
  63. package/coverage/rabbit-ui-kit/src/swaps-lib/models/index.html +176 -0
  64. package/coverage/rabbit-ui-kit/src/swaps-lib/models/partner.js.html +166 -0
  65. package/coverage/rabbit-ui-kit/src/swaps-lib/models/swapProviderCoinInfo.js.html +331 -0
  66. package/coverage/rabbit-ui-kit/src/swaps-lib/services/index.html +116 -0
  67. package/coverage/rabbit-ui-kit/src/swaps-lib/services/publicSwapService.js.html +1555 -0
  68. package/coverage/rabbit-ui-kit/src/swaps-lib/utils/index.html +116 -0
  69. package/coverage/rabbit-ui-kit/src/swaps-lib/utils/swapUtils.js.html +670 -0
  70. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/arrowIcon.jsx.html +124 -0
  71. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/arrowTosca.jsx.html +127 -0
  72. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/arrowWhite.jsx.html +127 -0
  73. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/darkRectangle.jsx.html +106 -0
  74. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/determinedError.jsx.html +439 -0
  75. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/failedValidationIcon.jsx.html +202 -0
  76. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/index.html +281 -0
  77. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/infoIcon.jsx.html +133 -0
  78. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/messageIcon.jsx.html +346 -0
  79. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/noticeQuestionIcon.jsx.html +247 -0
  80. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/successfulValidationIcon.jsx.html +163 -0
  81. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/supportDialogImage.jsx.html +268 -0
  82. package/coverage/rabbit-ui-kit/src/ui-kit/assets/wrappedImages/walletIcon.jsx.html +151 -0
  83. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/AssetIcon/AssetIcon.jsx.html +256 -0
  84. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/AssetIcon/index.html +116 -0
  85. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/AssetSelection/AssetSelection.jsx.html +289 -0
  86. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/AssetSelection/index.html +116 -0
  87. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/BackgroundTitle/BackgroundTitle.jsx.html +187 -0
  88. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/BackgroundTitle/index.html +116 -0
  89. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/InformationMessage/InformationMessage.jsx.html +238 -0
  90. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/InformationMessage/index.html +116 -0
  91. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Input/Input.jsx.html +634 -0
  92. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Input/index.html +116 -0
  93. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/LoadingDots/LoadingDots.jsx.html +196 -0
  94. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/LoadingDots/index.html +116 -0
  95. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/NoticeIcon/NoticeIcon.jsx.html +277 -0
  96. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/NoticeIcon/index.html +116 -0
  97. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/QrCode/QrCode.jsx.html +217 -0
  98. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/QrCode/index.html +116 -0
  99. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/RateSelector/RateSelector.jsx.html +175 -0
  100. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/RateSelector/index.html +116 -0
  101. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/SupportChat/SupportChat.jsx.html +217 -0
  102. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/SupportChat/index.html +116 -0
  103. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Textarea/Textarea.jsx.html +529 -0
  104. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Textarea/index.html +116 -0
  105. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/TitleBox/TitleBox.jsx.html +508 -0
  106. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/TitleBox/index.html +116 -0
  107. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Tooltip/Tooltip.jsx.html +316 -0
  108. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Tooltip/index.html +116 -0
  109. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/TwoLinesOfText/LinesOfText.jsx.html +313 -0
  110. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/TwoLinesOfText/index.html +116 -0
  111. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Validation/Validation.jsx.html +202 -0
  112. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/Validation/index.html +116 -0
  113. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/Button/Button.jsx.html +712 -0
  114. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/Button/index.html +116 -0
  115. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/Close/Close.jsx.html +259 -0
  116. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/Close/index.html +116 -0
  117. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/LinkButton/LinkButton.jsx.html +421 -0
  118. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/LinkButton/index.html +116 -0
  119. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/RadioButtonWithText/RadioButtonWithText.jsx.html +415 -0
  120. package/coverage/rabbit-ui-kit/src/ui-kit/components/atoms/buttons/RadioButtonWithText/index.html +116 -0
  121. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/AmountInput/AmountInput.jsx.html +1429 -0
  122. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/AmountInput/index.html +116 -0
  123. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/CoinPicker/CoinPicker.jsx.html +1474 -0
  124. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/CoinPicker/index.html +116 -0
  125. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/ColoredNotice/ColoredNotice.jsx.html +211 -0
  126. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/ColoredNotice/index.html +116 -0
  127. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/LineWithIconLink/LineWithIconLink.jsx.html +190 -0
  128. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/LineWithIconLink/index.html +116 -0
  129. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/LogoCarousel/LogoCarousel.jsx.html +307 -0
  130. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/LogoCarousel/index.html +116 -0
  131. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/SearchableCoinsList/SearchableCoinsList.jsx.html +496 -0
  132. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/SearchableCoinsList/index.html +116 -0
  133. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/TitledLineWithIconLink/TitledLineWithIconLink.jsx.html +181 -0
  134. package/coverage/rabbit-ui-kit/src/ui-kit/components/molecules/TitledLineWithIconLink/index.html +116 -0
  135. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/CoinPickerDialogStep/CoinPickerDialogStep.jsx.html +283 -0
  136. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/CoinPickerDialogStep/index.html +116 -0
  137. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/Dialog/Dialog.jsx.html +1567 -0
  138. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/Dialog/DialogButtons/DialogButtons.jsx.html +481 -0
  139. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/Dialog/DialogButtons/index.html +116 -0
  140. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/Dialog/DialogStep/DialogStep.jsx.html +1747 -0
  141. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/Dialog/DialogStep/index.html +116 -0
  142. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/Dialog/index.html +116 -0
  143. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/SwapForm/SwapForm.jsx.html +4207 -0
  144. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/SwapForm/index.html +116 -0
  145. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/WaitlistSubscription/WaitlistSubscription.jsx.html +559 -0
  146. package/coverage/rabbit-ui-kit/src/ui-kit/components/organisms/WaitlistSubscription/index.html +116 -0
  147. package/coverage/rabbit-ui-kit/src/ui-kit/components/templates/DeterminedErrorDialogStep/DeterminedErrorDialogStep.jsx.html +316 -0
  148. package/coverage/rabbit-ui-kit/src/ui-kit/components/templates/DeterminedErrorDialogStep/index.html +116 -0
  149. package/coverage/rabbit-ui-kit/src/ui-kit/hooks/index.html +146 -0
  150. package/coverage/rabbit-ui-kit/src/ui-kit/hooks/useCallHandlingErrors.js.html +151 -0
  151. package/coverage/rabbit-ui-kit/src/ui-kit/hooks/useIsHydrated.js.html +121 -0
  152. package/coverage/rabbit-ui-kit/src/ui-kit/hooks/useReferredState.js.html +157 -0
  153. package/coverage/rabbit-ui-kit/src/ui-kit/utils/index.html +161 -0
  154. package/coverage/rabbit-ui-kit/src/ui-kit/utils/inputValueProviders.js.html +235 -0
  155. package/coverage/rabbit-ui-kit/src/ui-kit/utils/textUtils.js.html +139 -0
  156. package/coverage/rabbit-ui-kit/src/ui-kit/utils/uiUtils.js.html +121 -0
  157. package/coverage/rabbit-ui-kit/src/ui-kit/utils/urlQueryUtils.js.html +271 -0
  158. package/coverage/rabbit-ui-kit/stories/atoms/BackgroundTitle.stories.jsx.html +202 -0
  159. package/coverage/rabbit-ui-kit/stories/atoms/LinesOfText.stories.jsx.html +283 -0
  160. package/coverage/rabbit-ui-kit/stories/atoms/LoadingDots.stories.jsx.html +226 -0
  161. package/coverage/rabbit-ui-kit/stories/atoms/QrCode.stories.jsx.html +175 -0
  162. package/coverage/rabbit-ui-kit/stories/atoms/RateSelector.stories.jsx.html +136 -0
  163. package/coverage/rabbit-ui-kit/stories/atoms/Validation.stories.jsx.html +178 -0
  164. package/coverage/rabbit-ui-kit/stories/atoms/buttons/Button.stories.jsx.html +883 -0
  165. package/coverage/rabbit-ui-kit/stories/atoms/buttons/Close.stories.jsx.html +211 -0
  166. package/coverage/rabbit-ui-kit/stories/atoms/buttons/LinkButton.stories.jsx.html +301 -0
  167. package/coverage/rabbit-ui-kit/stories/atoms/buttons/index.html +146 -0
  168. package/coverage/rabbit-ui-kit/stories/atoms/index.html +191 -0
  169. package/coverage/rabbit-ui-kit/stories/molecules/AmountInput.stories.jsx.html +289 -0
  170. package/coverage/rabbit-ui-kit/stories/molecules/CoinPicker.stories.jsx.html +322 -0
  171. package/coverage/rabbit-ui-kit/stories/molecules/ColoredNotice.stories.jsx.html +178 -0
  172. package/coverage/rabbit-ui-kit/stories/molecules/LineWithIconLink.stories.jsx.html +154 -0
  173. package/coverage/rabbit-ui-kit/stories/molecules/LogoCarousel.stories.jsx.html +235 -0
  174. package/coverage/rabbit-ui-kit/stories/molecules/TitledLineWithIconLink.stories.jsx.html +160 -0
  175. package/coverage/rabbit-ui-kit/stories/molecules/index.html +191 -0
  176. package/coverage/rabbit-ui-kit/stories/organisms/Dialog/Dialog.stories.jsx.html +523 -0
  177. package/coverage/rabbit-ui-kit/stories/organisms/Dialog/DialogButtons/DialogButtons.stories.jsx.html +328 -0
  178. package/coverage/rabbit-ui-kit/stories/organisms/Dialog/DialogButtons/index.html +116 -0
  179. package/coverage/rabbit-ui-kit/stories/organisms/Dialog/DialogStep/DialogStep.stories.jsx.html +337 -0
  180. package/coverage/rabbit-ui-kit/stories/organisms/Dialog/DialogStep/index.html +116 -0
  181. package/coverage/rabbit-ui-kit/stories/organisms/Dialog/index.html +116 -0
  182. package/coverage/rabbit-ui-kit/stories/organisms/WaitlistSubscription.stories.jsx.html +151 -0
  183. package/coverage/rabbit-ui-kit/stories/organisms/index.html +116 -0
  184. package/coverage/rabbit-ui-kit/stories/stubs/coins.jsx.html +6880 -0
  185. package/coverage/rabbit-ui-kit/stories/stubs/exampleContent.jsx.html +145 -0
  186. package/coverage/rabbit-ui-kit/stories/stubs/index.html +131 -0
  187. package/coverage/rabbit-ui-kit/stories/templates/DeterminedErrorDialogStep.stories.jsx.html +190 -0
  188. package/coverage/rabbit-ui-kit/stories/templates/index.html +116 -0
  189. package/coverage/sort-arrow-sprite.png +0 -0
  190. package/coverage/sorter.js +196 -0
  191. package/dist/global.css +197 -0
  192. package/dist/global.css.map +1 -0
  193. package/dist/index.cjs +12451 -25
  194. package/dist/index.cjs.map +1 -1
  195. package/dist/index.css +2339 -8491
  196. package/dist/index.css.map +1 -1
  197. package/dist/index.modern.js +9597 -26
  198. package/dist/index.modern.js.map +1 -1
  199. package/dist/index.module.js +12357 -27
  200. package/dist/index.module.js.map +1 -1
  201. package/dist/index.umd.js +12442 -29
  202. package/dist/index.umd.js.map +1 -1
  203. package/package.json +35 -9
  204. package/raw +1000 -0
  205. package/src/common-apis/adapters/analyticsAdapters/googleAnalyticsAdapter.js +21 -0
  206. package/src/common-apis/adapters/analyticsAdapters/metrikaAdapter.js +28 -0
  207. package/src/common-apis/adapters/analyticsAdapters/mixpanelAdapter.js +38 -0
  208. package/src/common-apis/adapters/axiosAdapter.js +35 -0
  209. package/src/common-apis/adapters/qrUtils.js +18 -0
  210. package/src/common-apis/external-apis/apiGroups.js +55 -0
  211. package/src/common-apis/external-apis/emailAPI.js +16 -0
  212. package/src/common-apis/external-apis/ipAddressProviders.js +89 -0
  213. package/src/common-apis/globalConstants.jsx +3 -0
  214. package/src/common-apis/models/blockchain.js +10 -0
  215. package/src/common-apis/models/coin.js +248 -0
  216. package/src/common-apis/models/protocol.js +5 -0
  217. package/src/{common → common-apis/services}/fiatCurrenciesService.js +4 -12
  218. package/src/common-apis/tests/integration/external-apis/ipAddressProviders/getClientIpAddress.test.js +12 -0
  219. package/src/common-apis/tests/units/utils/amountUtils/composeRateText.test.js +152 -0
  220. package/src/{common → common-apis/utils}/amountUtils.js +72 -136
  221. package/src/common-apis/utils/cache.js +242 -0
  222. package/src/{common → common-apis/utils}/errorUtils.js +15 -0
  223. package/src/common-apis/utils/logging/logger.js +41 -0
  224. package/src/common-apis/utils/logging/logsStorage.js +61 -0
  225. package/src/common-apis/utils/postponeExecution.js +11 -0
  226. package/src/common-apis/utils/rabbitTicker.js +24 -0
  227. package/src/common-apis/utils/safeStringify.js +50 -0
  228. package/src/index.js +96 -9
  229. package/src/robust-api-caller/cacheAndConcurrentRequestsResolver.js +495 -0
  230. package/src/robust-api-caller/cachedRobustExternalApiCallerService.js +147 -0
  231. package/src/robust-api-caller/cancelProcessing.js +29 -0
  232. package/src/robust-api-caller/concurrentCalculationsMetadataHolder.js +75 -0
  233. package/src/robust-api-caller/externalApiProvider.js +156 -0
  234. package/src/robust-api-caller/externalServicesStatsCollector.js +78 -0
  235. package/src/robust-api-caller/robustExternalAPICallerService.js +304 -0
  236. package/src/robust-api-caller/tests/robustExternalAPICallerService/robustExternalAPICallerService/callExternalAPI/_performCallAttempt.test.js +533 -0
  237. package/src/robust-api-caller/tests/robustExternalAPICallerService/robustExternalAPICallerService/callExternalAPI/callExternalAPI.test.js +532 -0
  238. package/src/robust-api-caller/tests/robustExternalAPICallerService/robustExternalAPICallerService/constructor.test.js +19 -0
  239. package/src/swaps-lib/external-apis/exolixSwapProvider.js +580 -0
  240. package/src/swaps-lib/external-apis/letsExchangeSwapProvider.js +511 -0
  241. package/src/swaps-lib/external-apis/swapProvider.js +578 -0
  242. package/src/swaps-lib/external-apis/swapspaceSwapProvider.js +592 -0
  243. package/src/swaps-lib/models/baseSwapCreationInfo.js +78 -0
  244. package/src/swaps-lib/models/existingSwap.js +143 -0
  245. package/src/swaps-lib/models/existingSwapWithFiatData.js +148 -0
  246. package/src/swaps-lib/models/partner.js +27 -0
  247. package/src/swaps-lib/models/swapProviderCoinInfo.js +82 -0
  248. package/src/swaps-lib/services/publicSwapService.js +490 -0
  249. package/src/swaps-lib/test/external-apis/exolixSwapProvider/_fetchSupportedCurrenciesIfNeeded.test.js +34 -0
  250. package/src/swaps-lib/test/external-apis/exolixSwapProvider/createSwap.test.js +1043 -0
  251. package/src/swaps-lib/test/external-apis/exolixSwapProvider/getSwapInfo.test.js +611 -0
  252. package/src/swaps-lib/test/external-apis/swapProvider/getAllSupportedCurrencies.test.js +63 -0
  253. package/src/swaps-lib/test/external-apis/swapProvider/getDepositCurrencies.test.js +73 -0
  254. package/src/swaps-lib/test/external-apis/swapProvider/getWithdrawalCurrencies.test.js +102 -0
  255. package/src/swaps-lib/test/external-apis/swapProvider/removeProtocolNameFromCoinName.test.js +152 -0
  256. package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/_fetchSupportedCurrenciesIfNeeded.test.js +536 -0
  257. package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/createSwap.test.js +1214 -0
  258. package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/getSwapInfo.test.js +1707 -0
  259. package/src/swaps-lib/test/utils/swapUtils/safeHandleRequestsLimitExceeding.test.js +80 -0
  260. package/src/swaps-lib/utils/swapUtils.js +195 -0
  261. package/{styles → src/ui-kit/assets/styles}/_functions.scss +5 -0
  262. package/{styles → src/ui-kit/assets/styles}/_mixins.scss +2 -2
  263. package/{styles → src/ui-kit/assets/styles}/_placeholder.scss +3 -3
  264. package/{styles → src/ui-kit/assets/styles}/_variables.scss +17 -15
  265. package/src/ui-kit/assets/styles/fonts/NunitoSans-Bold.ttf +0 -0
  266. package/src/ui-kit/assets/styles/fonts/NunitoSans-ExtraBold.ttf +0 -0
  267. package/src/ui-kit/assets/styles/fonts/NunitoSans-Light.ttf +0 -0
  268. package/src/ui-kit/assets/styles/fonts/NunitoSans-Regular.ttf +0 -0
  269. package/src/ui-kit/assets/styles/fonts/NunitoSans-SemiBold.ttf +0 -0
  270. package/src/ui-kit/assets/styles/global.scss +171 -0
  271. package/src/ui-kit/assets/styles/index.scss +10 -0
  272. package/src/ui-kit/assets/wrappedImages/arrowIcon.jsx +13 -0
  273. package/src/ui-kit/assets/wrappedImages/arrowTosca.jsx +14 -0
  274. package/src/ui-kit/assets/wrappedImages/arrowWhite.jsx +14 -0
  275. package/src/ui-kit/assets/wrappedImages/darkRectangle.jsx +7 -0
  276. package/src/ui-kit/assets/wrappedImages/determinedError.jsx +118 -0
  277. package/src/ui-kit/assets/wrappedImages/failedValidationIcon.jsx +39 -0
  278. package/src/ui-kit/assets/wrappedImages/infoIcon.jsx +16 -0
  279. package/src/ui-kit/assets/wrappedImages/messageIcon.jsx +87 -0
  280. package/src/ui-kit/assets/wrappedImages/noticeQuestionIcon.jsx +54 -0
  281. package/src/ui-kit/assets/wrappedImages/successfulValidationIcon.jsx +26 -0
  282. package/src/ui-kit/assets/wrappedImages/supportDialogImage.jsx +61 -0
  283. package/src/ui-kit/assets/wrappedImages/walletIcon.jsx +22 -0
  284. package/src/ui-kit/components/atoms/AssetIcon/AssetIcon.jsx +57 -0
  285. package/src/{components → ui-kit/components}/atoms/AssetIcon/asset-icon.module.scss +1 -1
  286. package/src/ui-kit/components/atoms/AssetSelection/AssetSelection.jsx +68 -0
  287. package/src/ui-kit/components/atoms/AssetSelection/asset-selection.module.scss +56 -0
  288. package/src/ui-kit/components/atoms/BackgroundTitle/BackgroundTitle.jsx +34 -0
  289. package/src/ui-kit/components/atoms/BackgroundTitle/background-title.module.scss +52 -0
  290. package/src/ui-kit/components/atoms/InformationMessage/InformationMessage.jsx +51 -0
  291. package/src/ui-kit/components/atoms/InformationMessage/information-message.module.scss +38 -0
  292. package/src/ui-kit/components/atoms/Input/Input.jsx +183 -0
  293. package/src/ui-kit/components/atoms/Input/input.module.scss +107 -0
  294. package/src/{components → ui-kit/components}/atoms/LoadingDots/LoadingDots.jsx +8 -28
  295. package/src/{components → ui-kit/components}/atoms/LoadingDots/LoadingDots.module.scss +3 -2
  296. package/src/ui-kit/components/atoms/NoticeIcon/NoticeIcon.jsx +64 -0
  297. package/src/ui-kit/components/atoms/NoticeIcon/notice-icon.module.scss +14 -0
  298. package/src/ui-kit/components/atoms/QrCode/QrCode.jsx +44 -0
  299. package/src/ui-kit/components/atoms/QrCode/qr-code.module.scss +15 -0
  300. package/src/ui-kit/components/atoms/RateSelector/RateSelector.jsx +30 -0
  301. package/src/ui-kit/components/atoms/RateSelector/rate-selector.module.scss +47 -0
  302. package/src/{components → ui-kit/components}/atoms/SupportChat/SupportChat.jsx +5 -1
  303. package/src/ui-kit/components/atoms/Textarea/Textarea.jsx +148 -0
  304. package/src/ui-kit/components/atoms/Textarea/textarea.module.scss +71 -0
  305. package/src/ui-kit/components/atoms/TitleBox/TitleBox.jsx +141 -0
  306. package/src/ui-kit/components/atoms/TitleBox/title-box.module.scss +32 -0
  307. package/src/ui-kit/components/atoms/Tooltip/Tooltip.jsx +77 -0
  308. package/src/ui-kit/components/atoms/Tooltip/tooltip.module.scss +237 -0
  309. package/src/ui-kit/components/atoms/TwoLinesOfText/LinesOfText.jsx +76 -0
  310. package/src/ui-kit/components/atoms/TwoLinesOfText/lines-of-text.module.scss +65 -0
  311. package/src/ui-kit/components/atoms/Validation/Validation.jsx +39 -0
  312. package/src/ui-kit/components/atoms/Validation/validation.module.scss +19 -0
  313. package/src/{components → ui-kit/components}/atoms/buttons/Button/Button.jsx +24 -50
  314. package/src/{components → ui-kit/components}/atoms/buttons/Button/Button.module.scss +1 -1
  315. package/src/ui-kit/components/atoms/buttons/Close/Close.jsx +58 -0
  316. package/src/ui-kit/components/atoms/buttons/Close/close.module.scss +75 -0
  317. package/src/ui-kit/components/atoms/buttons/LinkButton/LinkButton.jsx +112 -0
  318. package/src/ui-kit/components/atoms/buttons/LinkButton/link-button.module.scss +49 -0
  319. package/src/ui-kit/components/atoms/buttons/RadioButtonWithText/RadioButtonWithText.jsx +110 -0
  320. package/src/ui-kit/components/atoms/buttons/RadioButtonWithText/radio-button-with-text.module.scss +86 -0
  321. package/src/ui-kit/components/molecules/AmountInput/AmountInput.jsx +448 -0
  322. package/src/ui-kit/components/molecules/AmountInput/amount-input.module.scss +233 -0
  323. package/src/ui-kit/components/molecules/CoinPicker/CoinPicker.jsx +463 -0
  324. package/src/ui-kit/components/molecules/CoinPicker/coin-picker.module.scss +207 -0
  325. package/src/ui-kit/components/molecules/ColoredNotice/ColoredNotice.jsx +42 -0
  326. package/src/ui-kit/components/molecules/ColoredNotice/colored-notice.module.scss +20 -0
  327. package/src/ui-kit/components/molecules/LineWithIconLink/LineWithIconLink.jsx +35 -0
  328. package/src/ui-kit/components/molecules/LineWithIconLink/line-with-icon-link.module.scss +25 -0
  329. package/src/ui-kit/components/molecules/LogoCarousel/LogoCarousel.jsx +74 -0
  330. package/src/ui-kit/components/molecules/LogoCarousel/logo-carousel.module.scss +106 -0
  331. package/src/ui-kit/components/molecules/SearchableCoinsList/SearchableCoinsList.jsx +137 -0
  332. package/src/ui-kit/components/molecules/TitledLineWithIconLink/TitledLineWithIconLink.jsx +32 -0
  333. package/src/ui-kit/components/organisms/CoinPickerDialogStep/CoinPickerDialogStep.jsx +66 -0
  334. package/src/ui-kit/components/organisms/Dialog/Dialog.jsx +494 -0
  335. package/src/ui-kit/components/organisms/Dialog/DialogButtons/DialogButtons.jsx +132 -0
  336. package/src/ui-kit/components/organisms/Dialog/DialogButtons/dialog-buttons.module.scss +25 -0
  337. package/src/ui-kit/components/organisms/Dialog/DialogStep/DialogStep.jsx +554 -0
  338. package/src/ui-kit/components/organisms/Dialog/DialogStep/dialog-step.module.scss +381 -0
  339. package/src/ui-kit/components/organisms/Dialog/dialog.module.scss +226 -0
  340. package/src/ui-kit/components/organisms/SwapForm/SwapForm.jsx +1374 -0
  341. package/src/ui-kit/components/organisms/SwapForm/swap-form.module.scss +134 -0
  342. package/src/ui-kit/components/organisms/WaitlistSubscription/WaitlistSubscription.jsx +158 -0
  343. package/src/ui-kit/components/templates/DeterminedErrorDialogStep/DeterminedErrorDialogStep.jsx +77 -0
  344. package/src/ui-kit/hooks/useCallHandlingErrors.js +22 -0
  345. package/src/ui-kit/hooks/useIsHydrated.js +12 -0
  346. package/src/ui-kit/hooks/useReferredState.js +24 -0
  347. package/src/ui-kit/tests/utils/inputValueProviders/provideFormatOfFloatValueByInputString.test.js +146 -0
  348. package/src/ui-kit/tests/utils/urlQueryUtils/getQueryParameterValues.test.js +65 -0
  349. package/src/ui-kit/tests/utils/urlQueryUtils/saveQueryParameterAndValues.test.js +104 -0
  350. package/src/ui-kit/utils/inputValueProviders.js +50 -0
  351. package/src/ui-kit/utils/textUtils.js +18 -0
  352. package/src/ui-kit/utils/uiUtils.js +12 -0
  353. package/src/ui-kit/utils/urlQueryUtils.js +62 -0
  354. package/stories/font.scss +40 -0
  355. package/stories/stubs/coins.jsx +2266 -0
  356. package/stories/stubs/exampleContent.jsx +20 -0
  357. package/src/components/atoms/AssetIcon/AssetIcon.jsx +0 -55
  358. package/styles/_global-classes.scss +0 -433
  359. package/styles/fonts/NunitoSans-Bold.ttf +0 -0
  360. package/styles/fonts/NunitoSans-ExtraBold.ttf +0 -0
  361. package/styles/fonts/NunitoSans-Light.ttf +0 -0
  362. package/styles/fonts/NunitoSans-Regular.ttf +0 -0
  363. package/styles/fonts/NunitoSans-SemiBold.ttf +0 -0
  364. package/styles/global-styles-index.scss +0 -74
  365. package/styles/index.scss +0 -33
  366. /package/{styles → src/ui-kit/assets/styles}/colors/_light-colors.scss +0 -0
  367. /package/{styles → src/ui-kit/assets/styles}/colors/_solid-colors.scss +0 -0
  368. /package/{styles → src/ui-kit/assets/styles}/size/_margin-size.scss +0 -0
  369. /package/{styles → src/ui-kit/assets/styles}/size/_padding-size.scss +0 -0
@@ -0,0 +1,1374 @@
1
+ import { BigNumber } from "bignumber.js";
2
+ import React, { useEffect, useState } from "react";
3
+ import PropTypes from "prop-types";
4
+
5
+ import s from "./swap-form.module.scss";
6
+
7
+ import { useReferredState } from "../../../hooks/useReferredState.js";
8
+ import { useCallHandlingErrors } from "../../../hooks/useCallHandlingErrors.js";
9
+
10
+ import { AmountUtils } from "../../../../common-apis/utils/amountUtils.js";
11
+ import { TitleBox } from "../../atoms/TitleBox/TitleBox.jsx";
12
+ import { AmountInput } from "../../molecules/AmountInput/AmountInput.jsx";
13
+ import { Validation } from "../../atoms/Validation/Validation.jsx";
14
+ import { Button } from "../../atoms/buttons/Button/Button.jsx";
15
+ import { Textarea } from "../../atoms/Textarea/Textarea.jsx";
16
+ import { RateSelector } from "../../atoms/RateSelector/RateSelector.jsx";
17
+ import { TOOLTIP_POSITIONS } from "../../atoms/Tooltip/Tooltip.jsx";
18
+ import { useIsHydrated } from "../../../hooks/useIsHydrated.js";
19
+
20
+ /**
21
+ * This is the type definition of a function used inside SwapForm to compose the URL for the hero button.
22
+ *
23
+ * @function
24
+ * @name composeConfirmButtonTo
25
+ * @param {string} [fromTicker] - Ticker symbol of the asset being sent.
26
+ * @param {string} [toTicker] - Ticker symbol of the asset being received.
27
+ * @param {string} [fromAmount] - Amount of the asset being sent.
28
+ * @return {string} Full URL or relative URL that can be used for <a href="..." />.
29
+ */
30
+
31
+ /**
32
+ * Common click handler without parameters and return value, just your logic execution.
33
+ *
34
+ * @function
35
+ * @name handleClick
36
+ * @return {void}
37
+ */
38
+
39
+ /**
40
+ * Form executes this function when swap creation info retrieval is finished successfully.
41
+ *
42
+ * @function
43
+ * @name setSwapCreationEstimation
44
+ * @param {BaseSwapCreationInfo} details - Details of the swap creation estimation.
45
+ * @return {void}
46
+ */
47
+
48
+ /**
49
+ * Error handler for unexpected errors.
50
+ *
51
+ * @function
52
+ * @name handleUnexpectedError
53
+ * @param {Error} error - The unexpected error encountered.
54
+ * @return {void}
55
+ */
56
+
57
+ /**
58
+ * Should implement the logic with rotating assets (if you want "to" to become "from" and "from" to become "to").
59
+ *
60
+ * @function
61
+ * @name rotateAssets
62
+ * @param {string} sendingAssetTicker - Ticker symbol of the asset being sent.
63
+ * @param {string} receivingAssetTicker - Ticker symbol of the asset being received.
64
+ * @return {void}
65
+ */
66
+
67
+ /**
68
+ * Error handler for standard errors that we can recognize.
69
+ *
70
+ * @function
71
+ * @name handleSwapServiceError
72
+ * @param {string} errorCode - Error code returned as "reason" from your handlers.
73
+ * @param {function} setValidationContent - Function to set the validation error message on the form.
74
+ * @param {function} setBalanceValid - Function to set the balance validity, accepts a boolean.
75
+ * @param {function} setMinimalAmountValid - Function to set the minimal amount validity, accepts a boolean.
76
+ * @param {function} setMaximumAmountValid - Function to set the maximum amount validity, accepts a boolean.
77
+ * @param {function} setIsPairSupported - Function to set the pair support status, accepts a boolean.
78
+ * @param {function} setIsSameCoins - Function to set the status if the same coins are used, accepts a boolean.
79
+ * @return {void}
80
+ */
81
+
82
+ /**
83
+ * Handler for the confirm button click. You should implement error handling inside it.
84
+ *
85
+ * @function
86
+ * @name handleConfirmButtonClick
87
+ * @param {function} resetButtonLoader - Callback for resetting the confirm button loader.
88
+ * @param {function} setValidationContent - Function to set the validation error message on the form.
89
+ * @param {function} setBalanceValid - Function to set the balance validity, accepts a boolean.
90
+ * @param {function} setMinimalAmountValid - Function to set the minimal amount validity, accepts a boolean.
91
+ * @param {function} setMaximumAmountValid - Function to set the maximum amount validity, accepts a boolean.
92
+ * @param {function} setIsPairSupported - Function to set the pair support status, accepts a boolean.
93
+ * @param {function} setIsSameCoins - Function to set the status if the same coins are used, accepts a boolean.
94
+ * @param {string} recipientAddress - The address of the recipient.
95
+ * @param {string} recipientAddressExtraId - Additional identifier for the recipient address.
96
+ * @param {string} refundAddress - The address for refund.
97
+ * @param {string} refundAddressExtraId - Additional identifier for the refund address.
98
+ * @return {void}
99
+ */
100
+
101
+ /**
102
+ * Async function that retrieves swap creation info by given params.
103
+ *
104
+ * @function
105
+ * @name retrieveSwapDetails
106
+ * @param {string} sendingAssetTicker - Ticker symbol of the asset being sent.
107
+ * @param {string} receivingAssetTicker - Ticker symbol of the asset being received.
108
+ * @param {string} amount - Amount of the asset to be swapped.
109
+ * @param {boolean} [isSwapAll=false] - Indicates if the swap should use all available balance.
110
+ * @return {Promise<{
111
+ * result: false,
112
+ * reason: string,
113
+ * min: (string|null),
114
+ * max: (string|null),
115
+ * rate: (string|undefined),
116
+ * fiatMin: (number|null),
117
+ * fiatMax: (number|null)
118
+ * }|{
119
+ * result: true,
120
+ * swapCreationInfo: BaseSwapCreationInfo
121
+ * }>}
122
+ */
123
+
124
+ /**
125
+ * Async function that retrieves initial swap details for a pair like whether the pair is available, min/max swappable amounts, etc.
126
+ *
127
+ * @function
128
+ * @name retrieveInitialSwapData
129
+ * @param {string} sendingAssetTicker - Ticker symbol of the asset being sent.
130
+ * @param {string} receivingAssetTicker - Ticker symbol of the asset being received.
131
+ * @return {Promise<{
132
+ * result: true,
133
+ * min: string,
134
+ * fiatMin: (number|null),
135
+ * max: string,
136
+ * fiatMax: (number|null),
137
+ * rate: (string|null)
138
+ * }|{
139
+ * result: false,
140
+ * reason: string
141
+ * }>}
142
+ */
143
+
144
+ /**
145
+ * Function returning extraId name for asset if present.
146
+ * You must pass it if you use the form with addresses inputs.
147
+ *
148
+ * @function
149
+ * @name getExtraIdNameByTicker
150
+ * @param {string} ticker - Ticker symbol of the asset.
151
+ * @return {string|null}
152
+ */
153
+
154
+ /**
155
+ * Callback to handle isFixed flag change.
156
+ *
157
+ * @function
158
+ * @name onIsFixedChange
159
+ * @param {boolean} isFixedNewValue - new value
160
+ * @return {void}
161
+ */
162
+
163
+ /**
164
+ * Function validating addresses.
165
+ * By default, will treat any addresses as valid.
166
+ * You must pass it if you use the form with addresses inputs and want to validate addresses.
167
+ *
168
+ * @function
169
+ * @name validateAddressByTicker
170
+ * @param {string} ticker - Ticker symbol of the asset.
171
+ * @param {string} address - Address to be validated
172
+ * @param {boolean} isFixed - Is swap rate mode = fixed
173
+ * @param {function} setValidationContent - Function setting validation message text
174
+ * @return {Promise<boolean>}
175
+ */
176
+
177
+ /**
178
+ * Swap form provides basic functionality for entering to/from amounts both in crypto and fiat, switching assets,
179
+ * selecting assets, showing balance for assets. It gracefully handles unavailable fiat rates and can work
180
+ * both with and without a wallet environment (without balances).
181
+ *
182
+ * @param {object} props - Props object for SwapForm component.
183
+ * @param {string} props.sendingAssetTicker - Rabbit format of the ticker symbol for the asset being sent.
184
+ * @param {string} props.receivingAssetTicker - Rabbit format of the ticker symbol for the asset being received.
185
+ * @param {number} [props.sendingAssetDecimalCount=AmountUtils.significantDecimalCount] - Decimal count for the sending asset.
186
+ * @param {number} [props.receivingAssetDecimalCount=AmountUtils.significantDecimalCount] - Decimal count for the receiving asset.
187
+ * @param {string} props.sendingAssetTickerPrintable - Standard ticker symbol for the sending asset.
188
+ * @param {string} props.receivingAssetTickerPrintable - Standard ticker symbol for the receiving asset.
189
+ * @param {string} [props.sendingAssetProtocol] - Protocol name to be displayed in text on the change asset button.
190
+ * @param {string} [props.receivingAssetProtocol] - Protocol name to be displayed in text on the change asset button.
191
+ * @param {string} props.sendingAssetIconSrc - Source URL for the sending asset icon.
192
+ * @param {string} [props.sendingAssetProtocolIconSrc=null] - Optional source URL for the sending asset protocol icon.
193
+ * @param {string} props.receivingAssetIconSrc - Source URL for the receiving asset icon.
194
+ * @param {string} [props.receivingAssetProtocolIconSrc=null] - Optional source URL for the receiving asset protocol icon.
195
+ * @param {string} [props.fallBackAssetIconSrc=null] - Optional source URL for a fallback icon used when an icon fails to load.
196
+ * @param {string} [props.sendingAssetFeeCoinTickerPrintable] - Optional standard ticker symbol for the fee coin of the sending asset.
197
+ * @param {string} [props.sendingAssetBalance] - Balance of the sending asset.
198
+ * @param {string} [props.receivingAssetBalance] - Balance of the receiving asset.
199
+ * @param {handleClick} props.handleChangeSendingAssetClick - Function to handle clicking on the change sending asset button.
200
+ * @param {handleClick} props.handleChangeReceivingAssetClick - Function to handle clicking on the change receiving asset button.
201
+ * @param {handleConfirmButtonClick} props.handleConfirmButtonClick - Function to handle clicking on the confirm button.
202
+ * @param {composeConfirmButtonTo} props.composeConfirmButtonTo - Function to compose the URL for the confirm button.
203
+ * @param {setSwapCreationEstimation} props.setSwapCreationEstimation - Function to set the swap creation estimation.
204
+ * @param {handleUnexpectedError} props.handleUnexpectedError - Function to handle unexpected errors.
205
+ * @param {rotateAssets} props.rotateAssets - Function to rotate the assets (swap sending and receiving assets).
206
+ * @param {string} [props.preservedAmount=null] - Amount to be preserved.
207
+ * @param {handleSwapServiceError} props.handleSwapServiceError - Function to handle standard errors that we can recognize.
208
+ * @param {boolean} [props.formHasBalance] - Indicates if the form has balance information.
209
+ * @param {retrieveSwapDetails} props.retrieveSwapDetails - Function to retrieve swap details based on the given parameters.
210
+ * @param {retrieveInitialSwapData} props.retrieveInitialSwapData - Function to retrieve initial swap data for a given pair of assets.
211
+ * @param {number} props.triggerDataUpdateResetting - Number to reset interval updating the data periodically.
212
+ * @param {React.Ref} props.fromAssetSelectionButtonRef - Reference to the from asset selection button.
213
+ * @param {React.Ref} props.toAssetSelectionButtonRef - Reference to the to asset selection button.
214
+ * @param {number|string} [props.sendingAssetToFiatRate] - Rate for converting the sending asset to fiat.
215
+ * @param {number|string} [props.receivingAssetToFiatRate] - Rate for converting the receiving asset to fiat.
216
+ * @param {string} [props.fiatCurrencyCode] - Code for the fiat currency.
217
+ * @param {number} [props.fiatCurrencyDecimals] - Decimal places for the fiat currency.
218
+ * @param {boolean} [props.formHasFiat] - Indicates if the form supports fiat currency.
219
+ * @param {string|null} [props.termsOfUseUrl] - Terms of use URL, shown only if both terms & privacy policy passed.
220
+ * @param {string|null} [props.privacyPolicyUrl] - Privacy policy of use URL, shown only if both terms & privacy policy passed.
221
+ * @param {object} [props.translations] - Object containing translations, default English texts will be used if omitted.
222
+ * @param {string} props.swapSeparatorIconSrc - Source URL for the swap separator icon.
223
+ * @param {boolean} props.swapButtonAlwaysActive - Setting that allows the form state to proceed to the next step regardless of validity.
224
+ * @param {getExtraIdNameByTicker} props.getExtraIdNameByTicker - Function returning extraId name for asset
225
+ * @param {validateAddressByTicker} [props.validateAddressByTicker] - Function validating address
226
+ * @param {onIsFixedChange} [props.onIsFixedChange] - callback for changed isFixed
227
+ * @return {JSX.Element} Rendered SwapForm component.
228
+ * @constructor
229
+ */
230
+ export const SwapForm = ({
231
+ sendingAssetTicker,
232
+ receivingAssetTicker,
233
+ sendingAssetDecimalCount = AmountUtils.significantDecimalCount,
234
+ receivingAssetDecimalCount = AmountUtils.significantDecimalCount,
235
+ sendingAssetTickerPrintable,
236
+ receivingAssetTickerPrintable,
237
+ sendingAssetProtocol,
238
+ receivingAssetProtocol,
239
+ sendingAssetIconSrc,
240
+ sendingAssetProtocolIconSrc = null,
241
+ receivingAssetIconSrc,
242
+ receivingAssetProtocolIconSrc = null,
243
+ fallBackAssetIconSrc = null,
244
+ sendingAssetFeeCoinTickerPrintable,
245
+ sendingAssetBalance,
246
+ receivingAssetBalance,
247
+ handleChangeSendingAssetClick,
248
+ handleChangeReceivingAssetClick,
249
+ handleConfirmButtonClick = (
250
+ resetButtonLoader,
251
+ setValidationContent,
252
+ setBalanceValid,
253
+ setMinimalAmountValid,
254
+ setMaximumAmountValid,
255
+ setIsPairSupported,
256
+ setIsSameCoins,
257
+ recipientAddress,
258
+ recipientAddressExtraId,
259
+ refundAddress,
260
+ refundAddressExtraId
261
+ ) => {},
262
+ composeConfirmButtonTo = (fromTicker, toTicker, fromAmount) => "",
263
+ setSwapCreationEstimation = details => {},
264
+ handleUnexpectedError = error => {},
265
+ rotateAssets = (fromTicker, toTicker) => {},
266
+ preservedAmount = null,
267
+ handleSwapServiceError = (
268
+ errorCode,
269
+ setValidationContent,
270
+ setBalanceValid,
271
+ setMinimalAmountValid,
272
+ setMaximumAmountValid,
273
+ setIsPairSupported,
274
+ setIsSameCoins
275
+ ) => {},
276
+ formHasBalance = false,
277
+ retrieveSwapDetails = async (
278
+ sendingAssetTicker,
279
+ receivingAssetTicker,
280
+ amount,
281
+ isSwapAll = false,
282
+ isFixed = false,
283
+ amountIsToReceive = false
284
+ ) => {},
285
+ retrieveInitialSwapData = async (sendingAssetTicker, receivingAssetTicker) => {},
286
+ triggerDataUpdateResetting = 0,
287
+ fromAssetSelectionButtonRef = null,
288
+ toAssetSelectionButtonRef = null,
289
+ sendingAssetToFiatRate = null,
290
+ receivingAssetToFiatRate = null,
291
+ fiatCurrencyCode = null,
292
+ fiatCurrencyDecimals = null,
293
+ formHasFiat = true,
294
+ termsOfUseUrl = null,
295
+ privacyPolicyUrl = null,
296
+ getExtraIdNameByTicker = ticker => null,
297
+ validateAddressByTicker = () => false,
298
+ swapSeparatorIconSrc,
299
+ swapButtonAlwaysActive = false,
300
+ onIsFixedChange = () => {},
301
+ translations = {
302
+ swapAllButtonTitles: {
303
+ enable: "Swap all",
304
+ cancel: "Cancel",
305
+ },
306
+ input: {
307
+ fiatPlaceholder: "Enter fiat amount",
308
+ balanceLoaderText: "Loading balance...",
309
+ },
310
+ consents: {
311
+ consentText: 'By clicking "Swap" you agree with Rabbit Swap\'s',
312
+ termsOfUse: "Terms of Use",
313
+ and: "and",
314
+ privacyPolicy: "Privacy Policy",
315
+ },
316
+ informationBlock: {
317
+ minimumAmount: "Minimal amount: ",
318
+ maximumAmount: "Maximum amount: ",
319
+ transactionFee: "Network fee: ",
320
+ calculatingNetworkFee: "Calculating network fee..",
321
+ loadingMinimalAmount: "Loading minimal amount..",
322
+ swapRate: "Rate: ",
323
+ calculatingSwapRates: "Calculating swap rates..",
324
+ pairNotAvailable: "Pair is not available now. Please, try again later or choose another pair.",
325
+ },
326
+ addressFields: {
327
+ addressTitle: "Recepient address",
328
+ refundAddressTitle: "Refund address",
329
+ extraIdPlaceholder: "(optional)",
330
+ refundAddressExtraIdTitle: "Refund extra ID (MEMO):",
331
+ refundAddressExtraIdNotice:
332
+ "Please check if your address requires additional identifier (sometimes called a Memo, Destination Tag, Tag, ID, Label or Note). Including this identifier is crucial when required, as omitting or misentering it can result in lost assets.",
333
+ receivingAddressExtraIdTitle: "Destination extra ID (MEMO):",
334
+ receivingAddressExtraIdNotice:
335
+ "Please check if your address requires additional identifier (sometimes called a Memo, Destination Tag, Tag, ID, Label or Note). Including this identifier is crucial when required, as omitting or misentering it can result in lost assets.",
336
+ },
337
+ rateSelector: {
338
+ floatingRate: "Floating rate",
339
+ fixedRate: "Fixed rate",
340
+ },
341
+ confirmButtonText: "Swap",
342
+ },
343
+ }) => {
344
+ const DETAIL_REFRESH_INTERVAL_MS = 1.5 * 60000;
345
+ const IS_FIXED_BY_DEFAULT = false;
346
+
347
+ // Setting up an asyncronyous states, which can change during the function execution.
348
+ // This is done so that we can cancel the calculation update in case the selected asset changes.
349
+ const [sendingAssetTickerReferred, setSendingAssetTickerReferred] = useReferredState(null);
350
+ const [receivingAssetTickerReferred, setReceivingAssetTickerReferred] = useReferredState(null);
351
+
352
+ // eslint-disable-next-line react-hooks/exhaustive-deps
353
+ useEffect(() => setSendingAssetTickerReferred(sendingAssetTicker), [sendingAssetTicker]);
354
+
355
+ // eslint-disable-next-line react-hooks/exhaustive-deps
356
+ useEffect(() => setReceivingAssetTickerReferred(receivingAssetTicker), [receivingAssetTicker]);
357
+
358
+ // Updating the states below will insert the new value into the send or receive input field
359
+ const [updateSendInputTo, setUpdateSendInputTo] = useState(preservedAmount ?? null);
360
+ const [updateReceiveInputTo, setUpdateReceiveInputTo] = useState(null);
361
+
362
+ const [sendAssetAmount, setSendAssetAmount] = useReferredState(
363
+ preservedAmount == null || preservedAmount === "" ? null : preservedAmount
364
+ );
365
+ const [receiveAssetAmount, setReceiveAssetAmount] = useReferredState(null);
366
+
367
+ const [swapRate, setSwapRate] = useState();
368
+ const [minimalAmount, setMinimalAmount] = useReferredState(null);
369
+ const [maximumAmount, setMaximumAmount] = useReferredState(null);
370
+ const [validationContent, setValidationContent] = useState();
371
+
372
+ const [minimalAmountValid, setMinimalAmountValid] = useState(true); // Whether the amount is above the minimal amount
373
+ const [maximumAmountValid, setMaximumAmountValid] = useState(true);
374
+ const [isPairSupported, setIsPairSupported] = useState(true);
375
+ const [isSameCoins, setIsSameCoins] = useState(false);
376
+ const [isSwapCalculated, setIsSwapCalculated] = useState(false);
377
+ const [readyToSwap, setReadyToSwap] = useState(false); // Basically a param that enables/disables the "Next" button
378
+ // TODO: [refactoring, moderate] instead of handling preservedAmount at a lot of cases below, just
379
+ // write single useEffect setting sendAssetAmount to the=is passed value and simplify the logic below. task_id=6453251e49b04c5e88a3cc771479ffb5
380
+ const [isAmountZero, setIsAmountZero] = useState(preservedAmount == null || String(preservedAmount) === "0");
381
+ const [isLoading, setIsLoading] = useReferredState(false); // Whether the form is in the progress of loading some data (new rates, for example)
382
+ const [isFixedRate, setIsFixedRate] = useReferredState(null);
383
+ const [isLastEditedReceiving, setIsLastEditedReceiving] = useReferredState(false);
384
+
385
+ const [confirmButtonTo, setConfirmButtonTo] = useState(
386
+ composeConfirmButtonTo(sendingAssetTicker, receivingAssetTicker, preservedAmount)
387
+ );
388
+
389
+ const [transactionFee, setTransactionFee] = useState();
390
+ const [balanceValid, setBalanceValid] = useState(true); // Whether the amount is less than total balance
391
+ const [isSwapAll, setIsSwapAll] = useReferredState(null);
392
+ const [swapAllButtonLoaderReSetter, setSwapAllButtonLoaderReSetter] = useState([]);
393
+
394
+ const [dataUpdateTimeoutId, setDataUpdateTimeoutId] = useReferredState(null);
395
+ const [idleDataUpdateTimeoutId, setIdleDataUpdateTimeoutId] = useReferredState(null);
396
+
397
+ const [recipientAddress, setRecipientAddress] = useReferredState("");
398
+ const [recipientAddressExtraId, setRecipientAddressExtraId] = useReferredState("");
399
+ const [isRecipientAddressValid, setIsRecipientAddressValid] = useReferredState(false);
400
+ const [isRefundAddressRequired, setIsRefundAddressRequired] = useState(false);
401
+ const [refundAddress, setRefundAddress] = useReferredState("");
402
+ const [refundAddressExtraId, setRefundAddressExtraId] = useReferredState("");
403
+ const [isRefundAddressValid, setIsRefundAddressValid] = useReferredState(false);
404
+
405
+ const callHandlingErrors = useCallHandlingErrors();
406
+ const isHydrated = useIsHydrated();
407
+
408
+ const recalculationDelayOnTyping = 1000;
409
+
410
+ const isAddressFieldEnabled = !formHasBalance;
411
+ const displayRateSelector = !formHasBalance;
412
+
413
+ const handleSendAssetAmountChange = amount => {
414
+ setIsLastEditedReceiving(false);
415
+ let receiveAmount = "";
416
+ if (amount != null && amount !== "" && swapRate != null) {
417
+ receiveAmount = AmountUtils.trim(BigNumber(amount).times(swapRate), receivingAssetDecimalCount);
418
+ }
419
+ setReceiveAssetAmount(receiveAmount);
420
+ setUpdateReceiveInputTo(receiveAmount);
421
+ setSendAssetAmount(amount);
422
+ };
423
+
424
+ const handleReceiveAssetAmountChange = amount => {
425
+ setReceiveAssetAmount(amount);
426
+ if (isFixedRate.current) setIsLastEditedReceiving(true);
427
+ let sendAssetAmount = "";
428
+ if (amount != null && amount !== "" && swapRate != null) {
429
+ sendAssetAmount = AmountUtils.trim(BigNumber(amount).div(swapRate), sendingAssetDecimalCount);
430
+ }
431
+ setUpdateSendInputTo(sendAssetAmount);
432
+ setSendAssetAmount(sendAssetAmount);
433
+ };
434
+
435
+ const handleMinimalAmountClick = () => {
436
+ if (!minimalAmount.current) return;
437
+
438
+ if (isLastEditedReceiving.current) {
439
+ setUpdateReceiveInputTo(minimalAmount.current?.crypto);
440
+ handleReceiveAssetAmountChange(minimalAmount.current?.crypto);
441
+ } else {
442
+ setUpdateSendInputTo(minimalAmount.current?.crypto);
443
+ handleSendAssetAmountChange(minimalAmount.current?.crypto);
444
+ }
445
+ };
446
+
447
+ const handleMaximumAmountClick = () => {
448
+ if (!maximumAmount.current) return;
449
+
450
+ if (isLastEditedReceiving.current) {
451
+ setUpdateReceiveInputTo(maximumAmount.current?.crypto);
452
+ handleReceiveAssetAmountChange(maximumAmount.current?.crypto);
453
+ } else {
454
+ setUpdateSendInputTo(maximumAmount.current?.crypto);
455
+ handleSendAssetAmountChange(maximumAmount.current?.crypto);
456
+ }
457
+ };
458
+
459
+ const handleSwapAllClick = resetButtonLoader => {
460
+ setIsSwapAll(prev => {
461
+ if (prev) {
462
+ // Setting amount inputs to empty string if we are handling the disabling of previously enabled swap all
463
+ setUpdateSendInputTo("");
464
+ setUpdateReceiveInputTo("");
465
+ setSendAssetAmount(null);
466
+ setReceiveAssetAmount(null);
467
+ }
468
+ return !prev;
469
+ });
470
+ setSwapAllButtonLoaderReSetter([resetButtonLoader]);
471
+ };
472
+
473
+ const processMinMaxAmounts = amount => {
474
+ if (amount === null) return;
475
+
476
+ setMaximumAmountValid(
477
+ !maximumAmount.current || BigNumber(amount).eq("0") || BigNumber(amount).lte(maximumAmount.current.crypto)
478
+ );
479
+ setMinimalAmountValid(
480
+ !minimalAmount.current || BigNumber(amount).eq("0") || BigNumber(amount).gte(minimalAmount.current?.crypto)
481
+ );
482
+ };
483
+
484
+ const requestDataRefresh = (amount, immediately = false, isSwapAll = false, ignoreEmptyAmount = false) => {
485
+ try {
486
+ clearTimeout(dataUpdateTimeoutId.current);
487
+
488
+ if (isSwapAll) {
489
+ loadFullEstimation(null);
490
+ return;
491
+ }
492
+
493
+ if (!amount && !ignoreEmptyAmount) {
494
+ return;
495
+ }
496
+
497
+ if (BigNumber(amount).eq("0") || amount == null || amount === "") {
498
+ if (immediately) {
499
+ loadMinimalAmountAndSwapRate(true);
500
+ } else {
501
+ setDataUpdateTimeoutId(
502
+ setTimeout(() => loadMinimalAmountAndSwapRate(true), recalculationDelayOnTyping)
503
+ );
504
+ }
505
+ } else {
506
+ if (immediately) {
507
+ loadFullEstimation(amount, preservedAmount && String(preservedAmount) !== "0" ? true : undefined);
508
+ } else {
509
+ setDataUpdateTimeoutId(setTimeout(() => loadFullEstimation(amount), recalculationDelayOnTyping));
510
+ }
511
+ }
512
+ } catch (e) {
513
+ handleUnexpectedError(e);
514
+ }
515
+ };
516
+
517
+ const setAmountLimitsAndRate = details => {
518
+ setSwapRate(details?.rate ?? null);
519
+ if (!details?.rate) {
520
+ if (isLastEditedReceiving.current) {
521
+ setUpdateSendInputTo("");
522
+ setSendAssetAmount("");
523
+ } else {
524
+ setUpdateReceiveInputTo("");
525
+ setReceiveAssetAmount("");
526
+ }
527
+ }
528
+ setMinimalAmount(details.min == null ? null : { crypto: details.min, fiat: details.fiatMin });
529
+ setMaximumAmount(details.max == null ? null : { crypto: details.max, fiat: details.fiatMax });
530
+ if (details.feeCoins != null) {
531
+ setTransactionFee({
532
+ crypto: details.feeCoins,
533
+ fiat: details.feeFiat,
534
+ });
535
+ } else {
536
+ setTransactionFee(null);
537
+ }
538
+ };
539
+
540
+ const loadFullEstimation = (amount, isForPreserved = false) => {
541
+ (async () => {
542
+ try {
543
+ const dataMemento = {
544
+ rate: swapRate,
545
+ min: minimalAmount.current?.crypto,
546
+ max: maximumAmount.current?.crypto,
547
+ feeCoins: transactionFee?.crypto,
548
+ feeFiat: transactionFee?.fiat,
549
+ };
550
+ setIsLoading(true);
551
+ setMinimalAmount(null);
552
+ setMaximumAmount(null);
553
+ setTransactionFee(null);
554
+ setValidationContent(null);
555
+ setSwapCreationEstimation(null);
556
+ setIsSameCoins(false);
557
+ setIsPairSupported(true);
558
+ setIsSwapCalculated(false);
559
+
560
+ // Saving the selected coins at the moment, so we can cancel
561
+ // the processing if they get changed during the loading.
562
+ const currentSendingAssetTicker = sendingAssetTicker;
563
+ const currentReceivingAssetTicker = receivingAssetTicker;
564
+
565
+ const response = await retrieveSwapDetails(
566
+ currentSendingAssetTicker,
567
+ currentReceivingAssetTicker,
568
+ amount,
569
+ isSwapAll.current,
570
+ isFixedRate.current ?? IS_FIXED_BY_DEFAULT,
571
+ isFixedRate.current ? isLastEditedReceiving.current : false
572
+ );
573
+
574
+ if (
575
+ currentSendingAssetTicker !== sendingAssetTickerReferred.current ||
576
+ currentReceivingAssetTicker !== receivingAssetTickerReferred.current
577
+ ) {
578
+ // Cancelling the further processing in case the
579
+ // selected coins were changed during the loading.
580
+ return;
581
+ }
582
+
583
+ if (
584
+ !isSwapAll.current &&
585
+ String(amount) !==
586
+ String(
587
+ isForPreserved && sendAssetAmount.current == null && receiveAssetAmount.current == null
588
+ ? preservedAmount
589
+ : isFixedRate.current && isLastEditedReceiving.current
590
+ ? receiveAssetAmount.current
591
+ : sendAssetAmount.current
592
+ )
593
+ ) {
594
+ // Means amount changed and we no more need to do this exact calculation
595
+ return;
596
+ }
597
+
598
+ if (response.result) {
599
+ const swapCreationInfo = response?.swapCreationInfo;
600
+
601
+ if (isSwapAll.current) {
602
+ setIsAmountZero(BigNumber("0").eq(swapCreationInfo.fromAmountCoins));
603
+ }
604
+
605
+ setUpdateSendInputTo(swapCreationInfo.fromAmountCoins);
606
+ setUpdateReceiveInputTo(swapCreationInfo.toAmountCoins);
607
+
608
+ if (isLastEditedReceiving.current) {
609
+ setSendAssetAmount(swapCreationInfo.fromAmountCoins);
610
+ } else {
611
+ setReceiveAssetAmount(swapCreationInfo.toAmountCoins);
612
+ }
613
+
614
+ setAmountLimitsAndRate(swapCreationInfo);
615
+ setSwapCreationEstimation(swapCreationInfo);
616
+ setIsRefundAddressRequired(swapCreationInfo?.isRefundAddressRequired);
617
+ processMinMaxAmounts(isSwapAll.current ? swapCreationInfo.fromAmountCoins : amount);
618
+ setIsSwapCalculated(true);
619
+ } else {
620
+ handleSwapServiceError(
621
+ response.reason,
622
+ setValidationContent,
623
+ setBalanceValid,
624
+ setMinimalAmountValid,
625
+ setMaximumAmountValid,
626
+ setIsPairSupported,
627
+ setIsSameCoins
628
+ );
629
+ if (isSwapAll.current) {
630
+ /* We disable swap all if swap all details retrieval fails and set
631
+ * previous limits and rate. We set null to avoid triggering reloading of initial data.
632
+ */
633
+ setIsSwapAll(null);
634
+ setAmountLimitsAndRate(dataMemento);
635
+ } else {
636
+ /* We set returned amount limits and rate only if the failed details retrieval is not
637
+ * for the swap All case.
638
+ */
639
+ setAmountLimitsAndRate(response);
640
+ if (isLastEditedReceiving.current) {
641
+ setSendAssetAmount("");
642
+ } else {
643
+ setReceiveAssetAmount("");
644
+ }
645
+ }
646
+ }
647
+ setIsLoading(false);
648
+ } catch (e) {
649
+ handleUnexpectedError(e);
650
+ }
651
+ })();
652
+ };
653
+
654
+ const loadMinimalAmountAndSwapRate = (isCalledForClearedInput = false) => {
655
+ (async () => {
656
+ try {
657
+ setIsLoading(true);
658
+ setMinimalAmount(null);
659
+ setMaximumAmount(null);
660
+ setSwapRate(null);
661
+ setValidationContent(null);
662
+ setIsPairSupported(true);
663
+ setIsSwapCalculated(false);
664
+
665
+ const swapData = await retrieveInitialSwapData(sendingAssetTicker, receivingAssetTicker);
666
+
667
+ if (
668
+ (isFixedRate.current && isLastEditedReceiving.current
669
+ ? receiveAssetAmount.current != null
670
+ : sendAssetAmount.current != null) &&
671
+ !isCalledForClearedInput
672
+ ) {
673
+ // Means user already entered amount after starting the form initialization
674
+ return;
675
+ }
676
+
677
+ if (swapData.result === true) {
678
+ setAmountLimitsAndRate(swapData);
679
+ } else {
680
+ handleSwapServiceError(
681
+ swapData.reason,
682
+ setValidationContent,
683
+ setBalanceValid,
684
+ setMinimalAmountValid,
685
+ setMaximumAmountValid,
686
+ setIsPairSupported,
687
+ setIsSameCoins
688
+ );
689
+ }
690
+
691
+ setIsLoading(false);
692
+ } catch (e) {
693
+ handleUnexpectedError(e);
694
+ }
695
+ })();
696
+ };
697
+
698
+ const handleChangeAssetsIconClick = e => {
699
+ callHandlingErrors(() => {
700
+ if (!isLoading.current) {
701
+ setIsSwapAll(null);
702
+ setMaximumAmountValid(true);
703
+ setMinimalAmountValid(true);
704
+
705
+ const sendAssetAmountMemento = sendAssetAmount.current;
706
+ const receiveAssetAmountMemento = receiveAssetAmount.current;
707
+
708
+ if (isLastEditedReceiving.current) {
709
+ setSendAssetAmount("");
710
+ setUpdateSendInputTo("");
711
+
712
+ setReceiveAssetAmount(sendAssetAmountMemento);
713
+ setUpdateReceiveInputTo(sendAssetAmountMemento);
714
+ } else {
715
+ setSendAssetAmount(receiveAssetAmountMemento);
716
+ setUpdateSendInputTo(receiveAssetAmountMemento);
717
+
718
+ setReceiveAssetAmount("");
719
+ setUpdateReceiveInputTo("");
720
+ }
721
+
722
+ rotateAssets(sendingAssetTicker, receivingAssetTicker);
723
+ }
724
+ }, e);
725
+ };
726
+
727
+ const handleRateModeChanged = isFixed => {
728
+ setIsFixedRate(isFixed);
729
+ requestDataRefresh(
730
+ isLastEditedReceiving.current ? receiveAssetAmount.current : sendAssetAmount.current,
731
+ true,
732
+ null,
733
+ true
734
+ );
735
+ };
736
+
737
+ useEffect(() => {
738
+ if (isSwapAll.current === true) {
739
+ requestDataRefresh(undefined, true, true);
740
+ } else if (isSwapAll.current === false) {
741
+ loadMinimalAmountAndSwapRate();
742
+ }
743
+ // eslint-disable-next-line react-hooks/exhaustive-deps
744
+ }, [isSwapAll.current]);
745
+
746
+ useEffect(() => {
747
+ onIsFixedChange(isFixedRate.current);
748
+ if (!isFixedRate.current) setIsLastEditedReceiving(false);
749
+ // eslint-disable-next-line react-hooks/exhaustive-deps
750
+ }, [isFixedRate.current]);
751
+
752
+ useEffect(() => {
753
+ if (!sendingAssetTicker || !receivingAssetTicker) return;
754
+
755
+ const currentAmount = isLastEditedReceiving.current ? receiveAssetAmount.current : sendAssetAmount.current;
756
+
757
+ const isCurrentAmountNotZero = currentAmount && !BigNumber("0").eq(currentAmount);
758
+ if (isCurrentAmountNotZero) {
759
+ loadFullEstimation(currentAmount);
760
+ } else {
761
+ loadMinimalAmountAndSwapRate(true);
762
+ }
763
+
764
+ // eslint-disable-next-line react-hooks/exhaustive-deps
765
+ }, [sendingAssetTicker, receivingAssetTicker]);
766
+
767
+ useEffect(() => {
768
+ if (!minimalAmountValid || isAmountZero) {
769
+ setTransactionFee(null);
770
+ }
771
+ if (isAmountZero) {
772
+ clearTimeout(dataUpdateTimeoutId.current);
773
+ }
774
+
775
+ setReadyToSwap(
776
+ swapButtonAlwaysActive ||
777
+ ((balanceValid || !formHasBalance) &&
778
+ minimalAmountValid &&
779
+ !isAmountZero &&
780
+ isSwapCalculated &&
781
+ (!isSameCoins || !formHasBalance) &&
782
+ isPairSupported &&
783
+ (!isAddressFieldEnabled || isRecipientAddressValid.current) &&
784
+ (!isRefundAddressRequired || isRefundAddressValid.current))
785
+ );
786
+ // eslint-disable-next-line react-hooks/exhaustive-deps
787
+ }, [
788
+ balanceValid,
789
+ formHasBalance,
790
+ minimalAmountValid,
791
+ isAmountZero,
792
+ isSwapCalculated,
793
+ isSameCoins,
794
+ isPairSupported,
795
+ isAddressFieldEnabled,
796
+ isRecipientAddressValid.current,
797
+ isRefundAddressRequired,
798
+ isRefundAddressValid.current,
799
+ ]);
800
+
801
+ useEffect(() => {
802
+ setIsRecipientAddressValid(false);
803
+ setRecipientAddress("");
804
+ setRecipientAddressExtraId("");
805
+ // eslint-disable-next-line react-hooks/exhaustive-deps
806
+ }, [receivingAssetTicker]);
807
+
808
+ useEffect(() => {
809
+ setIsRefundAddressValid(false);
810
+ setRefundAddress("");
811
+ setRefundAddressExtraId("");
812
+ // eslint-disable-next-line react-hooks/exhaustive-deps
813
+ }, [sendingAssetTicker]);
814
+
815
+ useEffect(() => {
816
+ (async () => {
817
+ if (!receivingAssetTicker) return;
818
+ setValidationContent("");
819
+ setIsRecipientAddressValid(
820
+ recipientAddress.current === ""
821
+ ? false
822
+ : await validateAddressByTicker(
823
+ receivingAssetTicker,
824
+ recipientAddress.current,
825
+ isFixedRate.current,
826
+ setValidationContent
827
+ )
828
+ );
829
+ })();
830
+ // eslint-disable-next-line react-hooks/exhaustive-deps
831
+ }, [recipientAddress.current, recipientAddressExtraId.current, receivingAssetTicker]);
832
+
833
+ useEffect(() => {
834
+ (async () => {
835
+ if (!sendingAssetTicker || !isRefundAddressRequired) return;
836
+ setValidationContent("");
837
+ setIsRefundAddressValid(
838
+ refundAddress.current === ""
839
+ ? false
840
+ : await validateAddressByTicker(
841
+ sendingAssetTicker,
842
+ refundAddress.current,
843
+ isFixedRate.current,
844
+ setValidationContent
845
+ )
846
+ );
847
+ })();
848
+ // eslint-disable-next-line react-hooks/exhaustive-deps
849
+ }, [refundAddress.current, refundAddressExtraId.current, sendingAssetTicker, isRefundAddressRequired]);
850
+
851
+ useEffect(() => {
852
+ // Here we set up auto recalculations for the swap details if the form is ready to swap but is idle for some time
853
+ let timeoutId = null;
854
+ if (readyToSwap) {
855
+ timeoutId = setTimeout(
856
+ () =>
857
+ requestDataRefresh(
858
+ isLastEditedReceiving.current
859
+ ? receiveAssetAmount.current
860
+ : sendAssetAmount.current ?? preservedAmount,
861
+ true
862
+ ),
863
+ DETAIL_REFRESH_INTERVAL_MS
864
+ );
865
+ setIdleDataUpdateTimeoutId(timeoutId);
866
+ } else {
867
+ clearTimeout(idleDataUpdateTimeoutId.current);
868
+ setIdleDataUpdateTimeoutId(null);
869
+ }
870
+ return () => {
871
+ timeoutId != null && clearTimeout(timeoutId);
872
+ };
873
+ // eslint-disable-next-line react-hooks/exhaustive-deps
874
+ }, [readyToSwap]);
875
+
876
+ // TODO: [refactoring, critical] this code looks like a hack related to task_id=6e328d39063142b7b9fa01d497e616da
877
+ useEffect(() => {
878
+ if (triggerDataUpdateResetting) {
879
+ clearTimeout(dataUpdateTimeoutId.current);
880
+ setDataUpdateTimeoutId(null);
881
+
882
+ clearTimeout(idleDataUpdateTimeoutId.current);
883
+ setIdleDataUpdateTimeoutId(null);
884
+ }
885
+ // eslint-disable-next-line react-hooks/exhaustive-deps
886
+ }, [triggerDataUpdateResetting]);
887
+
888
+ // Resets the passed "set value to" param to null, so it can be used multiple times with any value
889
+ useEffect(() => {
890
+ if (!!updateSendInputTo) setUpdateSendInputTo(null);
891
+ if (!!updateReceiveInputTo) setUpdateReceiveInputTo(null);
892
+ // eslint-disable-next-line react-hooks/exhaustive-deps
893
+ }, [updateSendInputTo, updateReceiveInputTo]);
894
+
895
+ useEffect(() => {
896
+ if (
897
+ swapRate != null &&
898
+ (isLastEditedReceiving.current ? receiveAssetAmount.current : sendAssetAmount.current) != null
899
+ ) {
900
+ if (isLastEditedReceiving.current) {
901
+ setUpdateSendInputTo(
902
+ AmountUtils.trim(BigNumber(receiveAssetAmount.current).div(swapRate), sendingAssetDecimalCount)
903
+ );
904
+ } else {
905
+ setUpdateReceiveInputTo(
906
+ AmountUtils.trim(BigNumber(sendAssetAmount.current).times(swapRate), receivingAssetDecimalCount)
907
+ );
908
+ }
909
+ }
910
+ // eslint-disable-next-line react-hooks/exhaustive-deps
911
+ }, [swapRate]);
912
+
913
+ useEffect(() => {
914
+ if (isLoading.current === false && swapAllButtonLoaderReSetter?.length) {
915
+ swapAllButtonLoaderReSetter[0]();
916
+ setSwapAllButtonLoaderReSetter([]);
917
+ }
918
+ // eslint-disable-next-line react-hooks/exhaustive-deps
919
+ }, [isLoading.current, swapAllButtonLoaderReSetter]);
920
+
921
+ const handleAmountChange = amount => {
922
+ requestDataRefresh(amount);
923
+ processMinMaxAmounts(amount);
924
+ setIsAmountZero(BigNumber("0").eq(amount));
925
+ setIsSwapCalculated(false);
926
+ };
927
+
928
+ useEffect(() => {
929
+ if (isLastEditedReceiving.current)
930
+ handleAmountChange(receiveAssetAmount.current === "" ? "0" : receiveAssetAmount.current);
931
+ }, [receiveAssetAmount.current]);
932
+
933
+ useEffect(() => {
934
+ if (!isLastEditedReceiving.current)
935
+ handleAmountChange(sendAssetAmount.current === "" ? "0" : sendAssetAmount.current);
936
+ }, [sendAssetAmount.current]);
937
+
938
+ const recipientAddressExtraIdName = getExtraIdNameByTicker(receivingAssetTicker);
939
+ const refundAddressExtraIdName = getExtraIdNameByTicker(sendingAssetTicker);
940
+
941
+ return (
942
+ <div className={s["swap-form"]}>
943
+ <TitleBox
944
+ linkButtonClick={
945
+ BigNumber(sendingAssetBalance?.assetAmount).eq(0)
946
+ ? null
947
+ : resetButtonLoader => handleSwapAllClick(resetButtonLoader)
948
+ }
949
+ linkText={
950
+ !formHasBalance
951
+ ? ""
952
+ : isSwapAll.current
953
+ ? translations.swapAllButtonTitles.cancel
954
+ : translations.swapAllButtonTitles.enable
955
+ }
956
+ linkButtonLoader={true}
957
+ isLinkButtonDisabled={
958
+ isLoading.current ||
959
+ sendingAssetTicker === receivingAssetTicker ||
960
+ BigNumber(sendingAssetBalance?.assetAmount).eq(0)
961
+ }
962
+ >
963
+ {displayRateSelector ? (
964
+ <div className={s["swap-form-rate-selector"]}>
965
+ <RateSelector
966
+ isFixed={isFixedRate.current ?? IS_FIXED_BY_DEFAULT}
967
+ setIsFixed={handleRateModeChanged}
968
+ translations={translations.rateSelector}
969
+ />
970
+ </div>
971
+ ) : (
972
+ ""
973
+ )}
974
+
975
+ <div className={s["swap-form-inputs"]}>
976
+ <AmountInput
977
+ ticker={sendingAssetTicker}
978
+ tickerPrintable={sendingAssetTickerPrintable}
979
+ assetDecimalPlaces={sendingAssetDecimalCount}
980
+ assetBalance={sendingAssetBalance}
981
+ assetIconSrc={sendingAssetIconSrc}
982
+ assetIconProtocolSrc={sendingAssetProtocolIconSrc}
983
+ fallbackAssetIconSrc={fallBackAssetIconSrc}
984
+ disabled={isSwapAll.current || sendingAssetTicker === null || receivingAssetTicker === null}
985
+ handleCoinAmountChange={handleSendAssetAmountChange}
986
+ handleChangeAssetClick={handleChangeSendingAssetClick}
987
+ handleBalanceValidationChange={isValid => setBalanceValid(!isValid)}
988
+ updateAssetInputTo={updateSendInputTo}
989
+ showBalance={formHasBalance}
990
+ showBalanceValidation={formHasBalance}
991
+ showChangeAssetButton
992
+ changeAssetButtonProtocol={sendingAssetProtocol}
993
+ upperFormPosition
994
+ errorEncountered={
995
+ !isLastEditedReceiving.current && (!minimalAmountValid || !maximumAmountValid)
996
+ }
997
+ ref={fromAssetSelectionButtonRef}
998
+ isLoading={isLastEditedReceiving.current ? isLoading.current : false}
999
+ cryptoAssetToFiatRate={sendingAssetToFiatRate}
1000
+ fiatCurrencyCode={
1001
+ formHasFiat && (isLoading.current || sendingAssetToFiatRate != null)
1002
+ ? fiatCurrencyCode
1003
+ : null
1004
+ }
1005
+ fiatCurrencyDecimals={fiatCurrencyDecimals}
1006
+ balanceLoaderText={translations.input.balanceLoaderText}
1007
+ fiatInputPlaceholderText={translations.input.fiatPlaceholder}
1008
+ />
1009
+ <div
1010
+ className={
1011
+ s["swap-form-inputs-separator"] +
1012
+ " " +
1013
+ (isLoading.current || sendingAssetTicker === null || receivingAssetTicker === null
1014
+ ? s["disabled"]
1015
+ : "")
1016
+ }
1017
+ >
1018
+ <img
1019
+ src={swapSeparatorIconSrc}
1020
+ alt="swap icon"
1021
+ draggable={false}
1022
+ onClick={e => callHandlingErrors(handleChangeAssetsIconClick, e)}
1023
+ loading="lazy"
1024
+ />
1025
+ </div>
1026
+ <AmountInput
1027
+ ticker={receivingAssetTicker}
1028
+ tickerPrintable={receivingAssetTickerPrintable}
1029
+ assetDecimalPlaces={receivingAssetDecimalCount}
1030
+ assetBalance={receivingAssetBalance}
1031
+ assetIconSrc={receivingAssetIconSrc}
1032
+ assetIconProtocolSrc={receivingAssetProtocolIconSrc}
1033
+ fallbackAssetIconSrc={fallBackAssetIconSrc}
1034
+ disabled={isSwapAll.current || sendingAssetTicker === null || receivingAssetTicker === null}
1035
+ locked
1036
+ handleCoinAmountChange={handleReceiveAssetAmountChange}
1037
+ handleChangeAssetClick={handleChangeReceivingAssetClick}
1038
+ updateAssetInputTo={updateReceiveInputTo}
1039
+ showChangeAssetButton
1040
+ changeAssetButtonProtocol={receivingAssetProtocol}
1041
+ showBalance={formHasBalance}
1042
+ lowerFormPosition
1043
+ errorEncountered={isLastEditedReceiving.current && (!minimalAmountValid || !maximumAmountValid)}
1044
+ estimateAmount={!isFixedRate.current}
1045
+ ref={toAssetSelectionButtonRef}
1046
+ isLoading={isLastEditedReceiving.current ? false : isLoading.current}
1047
+ cryptoAssetToFiatRate={receivingAssetToFiatRate}
1048
+ fiatCurrencyCode={
1049
+ formHasFiat && (isLoading.current || receivingAssetToFiatRate != null)
1050
+ ? fiatCurrencyCode
1051
+ : null
1052
+ }
1053
+ fiatCurrencyDecimals={fiatCurrencyDecimals}
1054
+ balanceLoaderText={translations.input.balanceLoaderText}
1055
+ fiatInputPlaceholderText={translations.input.fiatPlaceholder}
1056
+ />
1057
+ </div>
1058
+ <div className={s["swap-form-information-field"]}>
1059
+ {/* TODO: [refactoring, moderate] Add flags calculation for each message to avoid this ugly cumbersome implicit unclear logic of message displaying. task_id=8bc31dbcd94d46a598346e8bfb505971 */}
1060
+ <p>
1061
+ {!isPairSupported ? (
1062
+ translations.informationBlock.pairNotAvailable
1063
+ ) : transactionFee && minimalAmountValid ? (
1064
+ <>
1065
+ {translations.informationBlock.transactionFee}
1066
+ <span>
1067
+ {AmountUtils.crypto(transactionFee?.crypto, sendingAssetFeeCoinTickerPrintable)}
1068
+ </span>
1069
+ {transactionFee?.fiat != null && transactionFee?.fiat !== "" ? (
1070
+ <span className={"semi-transparent"}>
1071
+ {" ~ " + AmountUtils.fiat(transactionFee?.fiat, fiatCurrencyCode)}
1072
+ </span>
1073
+ ) : (
1074
+ ""
1075
+ )}
1076
+ </>
1077
+ ) : !isLoading.current && (isSwapCalculated || (!minimalAmount.current && swapRate)) ? (
1078
+ <>
1079
+ {translations.informationBlock.swapRate}
1080
+ <span>
1081
+ {AmountUtils.composeRateText(
1082
+ sendingAssetTickerPrintable,
1083
+ receivingAssetTickerPrintable,
1084
+ swapRate,
1085
+ receivingAssetDecimalCount,
1086
+ isFixedRate.current ?? IS_FIXED_BY_DEFAULT
1087
+ )}
1088
+ </span>
1089
+ </>
1090
+ ) : minimalAmount.current || maximumAmount.current ? (
1091
+ !maximumAmountValid && maximumAmount.current != null ? (
1092
+ <>
1093
+ {translations.informationBlock.maximumAmount}
1094
+ <span
1095
+ className={s["interactable"] + " " + s["red"]}
1096
+ onClick={
1097
+ isLoading.current
1098
+ ? () => {}
1099
+ : e => callHandlingErrors(handleMaximumAmountClick, e)
1100
+ }
1101
+ >
1102
+ {AmountUtils.crypto(
1103
+ maximumAmount.current?.crypto,
1104
+ isLastEditedReceiving.current
1105
+ ? receivingAssetTickerPrintable
1106
+ : sendingAssetTickerPrintable
1107
+ )}
1108
+ </span>
1109
+ {maximumAmount.current?.fiat != null && maximumAmount.current?.fiat !== "" ? (
1110
+ <span className={"semi-transparent"}>
1111
+ {" ~ " + AmountUtils.fiat(maximumAmount.current.fiat, fiatCurrencyCode)}
1112
+ </span>
1113
+ ) : (
1114
+ ""
1115
+ )}
1116
+ </>
1117
+ ) : !minimalAmount.current ? (
1118
+ ""
1119
+ ) : (
1120
+ <>
1121
+ {translations.informationBlock.minimumAmount}
1122
+ <span
1123
+ className={s["interactable"] + " " + (!minimalAmountValid ? s["red"] : "")}
1124
+ onClick={
1125
+ isLoading.current
1126
+ ? () => {}
1127
+ : e => callHandlingErrors(handleMinimalAmountClick, e)
1128
+ }
1129
+ >
1130
+ {AmountUtils.crypto(
1131
+ minimalAmount.current.crypto,
1132
+ isLastEditedReceiving.current
1133
+ ? receivingAssetTickerPrintable
1134
+ : sendingAssetTickerPrintable
1135
+ )}
1136
+ </span>
1137
+ {minimalAmount.current?.fiat != null && minimalAmount.current.fiat !== "" ? (
1138
+ <span className={"semi-transparent"}>
1139
+ {" ~ " + AmountUtils.fiat(minimalAmount.current.fiat, fiatCurrencyCode)}
1140
+ </span>
1141
+ ) : (
1142
+ ""
1143
+ )}
1144
+ </>
1145
+ )
1146
+ ) : isLoading.current ? (
1147
+ sendAssetAmount.current || receiveAssetAmount.current || isSwapAll.current ? (
1148
+ translations.informationBlock[
1149
+ formHasBalance ? "calculatingNetworkFee" : "calculatingSwapRates"
1150
+ ]
1151
+ ) : (
1152
+ translations.informationBlock.loadingMinimalAmount
1153
+ )
1154
+ ) : (
1155
+ ""
1156
+ )}
1157
+ </p>
1158
+ </div>
1159
+
1160
+ {isAddressFieldEnabled ? (
1161
+ <div className={s["swap-form-address-field"]}>
1162
+ <TitleBox title={translations.addressFields.addressTitle}>
1163
+ <Textarea
1164
+ type={"text"}
1165
+ onChange={e => setRecipientAddress(e.target.value)}
1166
+ value={recipientAddress.current}
1167
+ adaptiveHeight={true}
1168
+ errorEncountered={recipientAddress.current !== "" && !isRecipientAddressValid.current}
1169
+ />
1170
+ </TitleBox>
1171
+ {isHydrated && recipientAddressExtraIdName ? (
1172
+ <TitleBox
1173
+ title={translations.addressFields.receivingAddressExtraIdTitle}
1174
+ titleNoticeText={translations.addressFields.receivingAddressExtraIdNotice}
1175
+ titleNoticePosition={TOOLTIP_POSITIONS.TOP_LEFT}
1176
+ >
1177
+ <Textarea
1178
+ type={"text"}
1179
+ onChange={e => setRecipientAddressExtraId(e.target.value)}
1180
+ value={recipientAddressExtraId.current}
1181
+ adaptiveHeight={true}
1182
+ placeholder={translations.addressFields.extraIdPlaceholder}
1183
+ />
1184
+ </TitleBox>
1185
+ ) : null}
1186
+ {isHydrated && isRefundAddressRequired ? (
1187
+ <>
1188
+ <TitleBox title={translations.addressFields.refundAddressTitle}>
1189
+ <Textarea
1190
+ type={"text"}
1191
+ onChange={e => setRefundAddress(e.target.value)}
1192
+ value={refundAddress.current}
1193
+ adaptiveHeight={true}
1194
+ errorEncountered={refundAddress.current !== "" && !isRefundAddressValid.current}
1195
+ />
1196
+ </TitleBox>
1197
+ {refundAddressExtraIdName ? (
1198
+ <TitleBox
1199
+ title={translations.addressFields.refundAddressExtraIdTitle}
1200
+ titleNoticeText={translations.addressFields.refundAddressExtraIdNotice}
1201
+ titleNoticePosition={TOOLTIP_POSITIONS.TOP_LEFT}
1202
+ >
1203
+ <Textarea
1204
+ type={"text"}
1205
+ onChange={e => setRefundAddressExtraId(e.target.value)}
1206
+ value={refundAddressExtraId.current}
1207
+ adaptiveHeight={true}
1208
+ placeholder={translations.addressFields.extraIdPlaceholder}
1209
+ />
1210
+ </TitleBox>
1211
+ ) : null}
1212
+ </>
1213
+ ) : null}
1214
+ </div>
1215
+ ) : null}
1216
+
1217
+ {validationContent ? (
1218
+ <div className={s["swap-form-validation-text"]}>
1219
+ <Validation text={validationContent} />
1220
+ </div>
1221
+ ) : (
1222
+ ""
1223
+ )}
1224
+ <div className={s["swap-form-button-container"]}>
1225
+ {!termsOfUseUrl || !privacyPolicyUrl ? null : (
1226
+ <p className={s["swap-form-button-container-consent-text"]}>
1227
+ {translations.consents.consentText + " "}
1228
+ <a
1229
+ href={termsOfUseUrl}
1230
+ className={s["swap-form-button-container-consent-text-link"]}
1231
+ target="_blank"
1232
+ >
1233
+ {translations.consents.termsOfUse}
1234
+ </a>
1235
+ {" " + translations.consents.and + " "}
1236
+ <a
1237
+ href={privacyPolicyUrl}
1238
+ className={s["swap-form-button-container-consent-text-link"]}
1239
+ target="_blank"
1240
+ >
1241
+ {translations.consents.privacyPolicy}
1242
+ </a>
1243
+ .
1244
+ </p>
1245
+ )}
1246
+ <Button
1247
+ size="lg"
1248
+ mode="primary"
1249
+ content={translations.confirmButtonText}
1250
+ onClick={resetButtonLoader =>
1251
+ handleConfirmButtonClick(
1252
+ resetButtonLoader,
1253
+ setValidationContent,
1254
+ setBalanceValid,
1255
+ setMinimalAmountValid,
1256
+ setMaximumAmountValid,
1257
+ setIsPairSupported,
1258
+ setIsSameCoins,
1259
+ recipientAddress.current,
1260
+ recipientAddressExtraId.current,
1261
+ refundAddress.current,
1262
+ refundAddressExtraId.current,
1263
+ isLastEditedReceiving.current
1264
+ )
1265
+ }
1266
+ fullWidthOnMobiles
1267
+ isDisabled={!readyToSwap}
1268
+ to={formHasBalance ? "" : confirmButtonTo}
1269
+ loader
1270
+ handleError={callHandlingErrors}
1271
+ />
1272
+ </div>
1273
+ </TitleBox>
1274
+ </div>
1275
+ );
1276
+ };
1277
+
1278
+ SwapForm.propTypes = {
1279
+ sendingAssetTicker: PropTypes.string.isRequired,
1280
+ receivingAssetTicker: PropTypes.string.isRequired,
1281
+ sendingAssetDecimalCount: PropTypes.number,
1282
+ receivingAssetDecimalCount: PropTypes.number,
1283
+ sendingAssetTickerPrintable: PropTypes.string.isRequired,
1284
+ receivingAssetTickerPrintable: PropTypes.string.isRequired,
1285
+ sendingAssetProtocol: PropTypes.string,
1286
+ receivingAssetProtocol: PropTypes.string,
1287
+ sendingAssetIconSrc: PropTypes.string.isRequired,
1288
+ sendingAssetProtocolIconSrc: PropTypes.oneOfType([PropTypes.string, null]),
1289
+ receivingAssetIconSrc: PropTypes.string.isRequired,
1290
+ receivingAssetProtocolIconSrc: PropTypes.oneOfType([PropTypes.string, null]),
1291
+ fallBackAssetIconSrc: PropTypes.oneOfType([PropTypes.string, null]),
1292
+ sendingAssetFeeCoinTickerPrintable: PropTypes.string,
1293
+ sendingAssetBalance: PropTypes.string,
1294
+ receivingAssetBalance: PropTypes.string,
1295
+ handleChangeSendingAssetClick: PropTypes.func.isRequired,
1296
+ handleChangeReceivingAssetClick: PropTypes.func.isRequired,
1297
+ handleConfirmButtonClick: PropTypes.func,
1298
+ composeConfirmButtonTo: PropTypes.func,
1299
+ setSwapCreationEstimation: PropTypes.func,
1300
+ handleUnexpectedError: PropTypes.func,
1301
+ rotateAssets: PropTypes.func,
1302
+ preservedAmount: PropTypes.oneOfType([PropTypes.string, null]),
1303
+ handleSwapServiceError: PropTypes.func.isRequired,
1304
+ formHasBalance: PropTypes.bool,
1305
+ retrieveSwapDetails: PropTypes.func.isRequired,
1306
+ retrieveInitialSwapData: PropTypes.func.isRequired,
1307
+ triggerDataUpdateResetting: PropTypes.number,
1308
+ fromAssetSelectionButtonRef: PropTypes.any,
1309
+ toAssetSelectionButtonRef: PropTypes.any,
1310
+ sendingAssetToFiatRate: PropTypes.oneOfType([PropTypes.number, PropTypes.string, null]),
1311
+ receivingAssetToFiatRate: PropTypes.oneOfType([PropTypes.number, PropTypes.string, null]),
1312
+ fiatCurrencyCode: PropTypes.oneOfType([PropTypes.string, null]),
1313
+ fiatCurrencyDecimals: PropTypes.oneOfType([PropTypes.number, null]),
1314
+ formHasFiat: PropTypes.bool,
1315
+ termsOfUseUrl: PropTypes.oneOfType([PropTypes.string, null]),
1316
+ privacyPolicyUrl: PropTypes.oneOfType([PropTypes.string, null]),
1317
+ getExtraIdNameByTicker: PropTypes.func,
1318
+ translations: PropTypes.object,
1319
+ validateAddressByTicker: PropTypes.func,
1320
+ swapSeparatorIconSrc: PropTypes.string.isRequired,
1321
+ swapButtonAlwaysActive: PropTypes.bool,
1322
+ onIsFixedChange: PropTypes.func,
1323
+ };
1324
+
1325
+ SwapForm.defaultProps = {
1326
+ sendingAssetDecimalCount: AmountUtils.significantDecimalCount,
1327
+ receivingAssetDecimalCount: AmountUtils.significantDecimalCount,
1328
+ sendingAssetProtocolIconSrc: null,
1329
+ receivingAssetProtocolIconSrc: null,
1330
+ fallBackAssetIconSrc: null,
1331
+ handleConfirmButtonClick: (
1332
+ resetButtonLoader,
1333
+ setValidationContent,
1334
+ setBalanceValid,
1335
+ setMinimalAmountValid,
1336
+ setMaximumAmountValid,
1337
+ setIsPairSupported,
1338
+ setIsSameCoins,
1339
+ recipientAddress,
1340
+ recipientAddressExtraId,
1341
+ refundAddress,
1342
+ refundAddressExtraId
1343
+ ) => {},
1344
+ composeConfirmButtonTo: (fromTicker, toTicker, fromAmount) => "",
1345
+ setSwapCreationEstimation: details => {},
1346
+ handleUnexpectedError: error => {},
1347
+ rotateAssets: (fromTicker, toTicker) => {},
1348
+ preservedAmount: null,
1349
+ handleSwapServiceError: (
1350
+ errorCode,
1351
+ setValidationContent,
1352
+ setBalanceValid,
1353
+ setMinimalAmountValid,
1354
+ setMaximumAmountValid,
1355
+ setIsPairSupported,
1356
+ setIsSameCoins
1357
+ ) => {},
1358
+ retrieveSwapDetails: async (sendingAssetTicker, receivingAssetTicker, amount, isSwapAll = false) => {},
1359
+ retrieveInitialSwapData: async (sendingAssetTicker, receivingAssetTicker) => {},
1360
+ triggerDataUpdateResetting: 0,
1361
+ fromAssetSelectionButtonRef: null,
1362
+ toAssetSelectionButtonRef: null,
1363
+ sendingAssetToFiatRate: null,
1364
+ receivingAssetToFiatRate: null,
1365
+ fiatCurrencyCode: null,
1366
+ fiatCurrencyDecimals: null,
1367
+ formHasFiat: true,
1368
+ termsOfUseUrl: null,
1369
+ privacyPolicyUrl: null,
1370
+ getExtraIdNameByTicker: ticker => null,
1371
+ validateAddressByTicker: ticker => false,
1372
+ swapButtonAlwaysActive: false,
1373
+ onIsFixedChange: () => {},
1374
+ };