@rabbitio/ui-kit 1.0.0-beta.8 → 1.0.0-beta.80

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 (398) 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 +16372 -0
  9. package/coverage/coverage-final.json +154 -0
  10. package/coverage/favicon.png +0 -0
  11. package/coverage/index.html +1151 -0
  12. package/coverage/prettify.css +1 -0
  13. package/coverage/prettify.js +2 -0
  14. package/coverage/sort-arrow-sprite.png +0 -0
  15. package/coverage/sorter.js +196 -0
  16. package/coverage/ui-kit/index.html +116 -0
  17. package/coverage/ui-kit/index.js.html +88 -0
  18. package/coverage/ui-kit/src/common-apis/adapters/axiosAdapter.js.html +190 -0
  19. package/coverage/ui-kit/src/common-apis/adapters/index.html +131 -0
  20. package/coverage/ui-kit/src/common-apis/adapters/qrUtils.js.html +139 -0
  21. package/coverage/ui-kit/src/common-apis/amountUtils.js.html +1162 -0
  22. package/coverage/ui-kit/src/common-apis/errorUtils.js.html +211 -0
  23. package/coverage/ui-kit/src/common-apis/external-apis/apiGroups.js.html +250 -0
  24. package/coverage/ui-kit/src/common-apis/external-apis/index.html +131 -0
  25. package/coverage/ui-kit/src/common-apis/external-apis/ipAddressProviders.js.html +352 -0
  26. package/coverage/ui-kit/src/common-apis/fiatCurrenciesService.js.html +544 -0
  27. package/coverage/ui-kit/src/common-apis/globalConstants.jsx.html +94 -0
  28. package/coverage/ui-kit/src/common-apis/index.html +161 -0
  29. package/coverage/ui-kit/src/common-apis/models/blockchain.js.html +115 -0
  30. package/coverage/ui-kit/src/common-apis/models/coin.js.html +544 -0
  31. package/coverage/ui-kit/src/common-apis/models/index.html +146 -0
  32. package/coverage/ui-kit/src/common-apis/models/protocol.js.html +100 -0
  33. package/coverage/ui-kit/src/common-apis/utils/cache.js.html +811 -0
  34. package/coverage/ui-kit/src/common-apis/utils/emailAPI.js.html +133 -0
  35. package/coverage/ui-kit/src/common-apis/utils/index.html +161 -0
  36. package/coverage/ui-kit/src/common-apis/utils/logging/index.html +131 -0
  37. package/coverage/ui-kit/src/common-apis/utils/logging/logger.js.html +208 -0
  38. package/coverage/ui-kit/src/common-apis/utils/logging/logsStorage.js.html +268 -0
  39. package/coverage/ui-kit/src/common-apis/utils/postponeExecution.js.html +118 -0
  40. package/coverage/ui-kit/src/common-apis/utils/safeStringify.js.html +235 -0
  41. package/coverage/ui-kit/src/index.html +116 -0
  42. package/coverage/ui-kit/src/index.js.html +337 -0
  43. package/coverage/ui-kit/src/robust-api-caller/cacheAndConcurrentRequestsResolver.js.html +1570 -0
  44. package/coverage/ui-kit/src/robust-api-caller/cachedRobustExternalApiCallerService.js.html +526 -0
  45. package/coverage/ui-kit/src/robust-api-caller/cancelProcessing.js.html +172 -0
  46. package/coverage/ui-kit/src/robust-api-caller/concurrentCalculationsMetadataHolder.js.html +310 -0
  47. package/coverage/ui-kit/src/robust-api-caller/externalApiProvider.js.html +553 -0
  48. package/coverage/ui-kit/src/robust-api-caller/externalServicesStatsCollector.js.html +319 -0
  49. package/coverage/ui-kit/src/robust-api-caller/index.html +206 -0
  50. package/coverage/ui-kit/src/robust-api-caller/robustExternalAPICallerService.js.html +997 -0
  51. package/coverage/ui-kit/src/swaps-lib/external-apis/index.html +146 -0
  52. package/coverage/ui-kit/src/swaps-lib/external-apis/letsExchangeSwapProvider.js.html +1513 -0
  53. package/coverage/ui-kit/src/swaps-lib/external-apis/swapProvider.js.html +1558 -0
  54. package/coverage/ui-kit/src/swaps-lib/external-apis/swapspaceSwapProvider.js.html +1735 -0
  55. package/coverage/ui-kit/src/swaps-lib/models/baseSwapCreationInfo.js.html +223 -0
  56. package/coverage/ui-kit/src/swaps-lib/models/existingSwap.js.html +304 -0
  57. package/coverage/ui-kit/src/swaps-lib/models/existingSwapWithFiatData.js.html +469 -0
  58. package/coverage/ui-kit/src/swaps-lib/models/index.html +146 -0
  59. package/coverage/ui-kit/src/swaps-lib/services/index.html +116 -0
  60. package/coverage/ui-kit/src/swaps-lib/services/publicSwapService.js.html +2098 -0
  61. package/coverage/ui-kit/src/swaps-lib/utils/index.html +116 -0
  62. package/coverage/ui-kit/src/swaps-lib/utils/swapUtils.js.html +670 -0
  63. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/arrowIcon.jsx.html +124 -0
  64. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/arrowTosca.jsx.html +127 -0
  65. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/arrowWhite.jsx.html +127 -0
  66. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/darkRectangle.jsx.html +106 -0
  67. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/determinedError.jsx.html +439 -0
  68. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/failedValidationIcon.jsx.html +202 -0
  69. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/index.html +251 -0
  70. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/infoIcon.jsx.html +133 -0
  71. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/noticeQuestionIcon.jsx.html +247 -0
  72. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/successfulValidationIcon.jsx.html +163 -0
  73. package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/walletIcon.jsx.html +151 -0
  74. package/coverage/ui-kit/src/ui-kit/components/atoms/AssetIcon/AssetIcon.jsx.html +256 -0
  75. package/coverage/ui-kit/src/ui-kit/components/atoms/AssetIcon/index.html +116 -0
  76. package/coverage/ui-kit/src/ui-kit/components/atoms/AssetSelection/AssetSelection.jsx.html +289 -0
  77. package/coverage/ui-kit/src/ui-kit/components/atoms/AssetSelection/index.html +116 -0
  78. package/coverage/ui-kit/src/ui-kit/components/atoms/BackgroundTitle/BackgroundTitle.jsx.html +187 -0
  79. package/coverage/ui-kit/src/ui-kit/components/atoms/BackgroundTitle/index.html +116 -0
  80. package/coverage/ui-kit/src/ui-kit/components/atoms/InformationMessage/InformationMessage.jsx.html +238 -0
  81. package/coverage/ui-kit/src/ui-kit/components/atoms/InformationMessage/index.html +116 -0
  82. package/coverage/ui-kit/src/ui-kit/components/atoms/Input/Input.jsx.html +634 -0
  83. package/coverage/ui-kit/src/ui-kit/components/atoms/Input/index.html +116 -0
  84. package/coverage/ui-kit/src/ui-kit/components/atoms/LoadingDots/LoadingDots.jsx.html +196 -0
  85. package/coverage/ui-kit/src/ui-kit/components/atoms/LoadingDots/index.html +116 -0
  86. package/coverage/ui-kit/src/ui-kit/components/atoms/NoticeIcon/NoticeIcon.jsx.html +277 -0
  87. package/coverage/ui-kit/src/ui-kit/components/atoms/NoticeIcon/index.html +116 -0
  88. package/coverage/ui-kit/src/ui-kit/components/atoms/QrCode/QrCode.jsx.html +235 -0
  89. package/coverage/ui-kit/src/ui-kit/components/atoms/QrCode/index.html +116 -0
  90. package/coverage/ui-kit/src/ui-kit/components/atoms/RateSelector/RateSelector.jsx.html +175 -0
  91. package/coverage/ui-kit/src/ui-kit/components/atoms/RateSelector/index.html +116 -0
  92. package/coverage/ui-kit/src/ui-kit/components/atoms/SupportChat/SupportChat.jsx.html +217 -0
  93. package/coverage/ui-kit/src/ui-kit/components/atoms/SupportChat/index.html +116 -0
  94. package/coverage/ui-kit/src/ui-kit/components/atoms/Textarea/Textarea.jsx.html +529 -0
  95. package/coverage/ui-kit/src/ui-kit/components/atoms/Textarea/index.html +116 -0
  96. package/coverage/ui-kit/src/ui-kit/components/atoms/TitleBox/TitleBox.jsx.html +508 -0
  97. package/coverage/ui-kit/src/ui-kit/components/atoms/TitleBox/index.html +116 -0
  98. package/coverage/ui-kit/src/ui-kit/components/atoms/Tooltip/Tooltip.jsx.html +316 -0
  99. package/coverage/ui-kit/src/ui-kit/components/atoms/Tooltip/index.html +116 -0
  100. package/coverage/ui-kit/src/ui-kit/components/atoms/TwoLinesOfText/LinesOfText.jsx.html +313 -0
  101. package/coverage/ui-kit/src/ui-kit/components/atoms/TwoLinesOfText/index.html +116 -0
  102. package/coverage/ui-kit/src/ui-kit/components/atoms/Validation/Validation.jsx.html +208 -0
  103. package/coverage/ui-kit/src/ui-kit/components/atoms/Validation/index.html +116 -0
  104. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/Button/Button.jsx.html +712 -0
  105. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/Button/index.html +116 -0
  106. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/Close/Close.jsx.html +259 -0
  107. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/Close/index.html +116 -0
  108. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/LinkButton/LinkButton.jsx.html +421 -0
  109. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/LinkButton/index.html +116 -0
  110. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/RadioButtonWithText/RadioButtonWithText.jsx.html +415 -0
  111. package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/RadioButtonWithText/index.html +116 -0
  112. package/coverage/ui-kit/src/ui-kit/components/molecules/AmountInput/AmountInput.jsx.html +1060 -0
  113. package/coverage/ui-kit/src/ui-kit/components/molecules/AmountInput/index.html +116 -0
  114. package/coverage/ui-kit/src/ui-kit/components/molecules/CoinPicker/CoinPicker.jsx.html +1618 -0
  115. package/coverage/ui-kit/src/ui-kit/components/molecules/CoinPicker/index.html +116 -0
  116. package/coverage/ui-kit/src/ui-kit/components/molecules/LineWithIconLink/LineWithIconLink.jsx.html +190 -0
  117. package/coverage/ui-kit/src/ui-kit/components/molecules/LineWithIconLink/index.html +116 -0
  118. package/coverage/ui-kit/src/ui-kit/components/molecules/TitledLineWithIconLink/TitledLineWithIconLink.jsx.html +181 -0
  119. package/coverage/ui-kit/src/ui-kit/components/molecules/TitledLineWithIconLink/index.html +116 -0
  120. package/coverage/ui-kit/src/ui-kit/components/organisms/CoinPickerDialogStep/CoinPickerDialogStep.jsx.html +283 -0
  121. package/coverage/ui-kit/src/ui-kit/components/organisms/CoinPickerDialogStep/index.html +116 -0
  122. package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/Dialog.jsx.html +1567 -0
  123. package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/DialogButtons/DialogButtons.jsx.html +451 -0
  124. package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/DialogButtons/index.html +116 -0
  125. package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/DialogStep/DialogStep.jsx.html +1699 -0
  126. package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/DialogStep/index.html +116 -0
  127. package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/index.html +116 -0
  128. package/coverage/ui-kit/src/ui-kit/components/organisms/SwapForm/SwapForm.jsx.html +4075 -0
  129. package/coverage/ui-kit/src/ui-kit/components/organisms/SwapForm/index.html +116 -0
  130. package/coverage/ui-kit/src/ui-kit/components/templates/DeterminedErrorDialogStep/DeterminedErrorDialogStep.jsx.html +316 -0
  131. package/coverage/ui-kit/src/ui-kit/components/templates/DeterminedErrorDialogStep/index.html +116 -0
  132. package/coverage/ui-kit/src/ui-kit/hooks/index.html +146 -0
  133. package/coverage/ui-kit/src/ui-kit/hooks/useCallHandlingErrors.js.html +151 -0
  134. package/coverage/ui-kit/src/ui-kit/hooks/useIsHydrated.js.html +121 -0
  135. package/coverage/ui-kit/src/ui-kit/hooks/useReferredState.js.html +157 -0
  136. package/coverage/ui-kit/src/ui-kit/utils/index.html +161 -0
  137. package/coverage/ui-kit/src/ui-kit/utils/inputValueProviders.js.html +235 -0
  138. package/coverage/ui-kit/src/ui-kit/utils/textUtils.js.html +139 -0
  139. package/coverage/ui-kit/src/ui-kit/utils/uiUtils.js.html +121 -0
  140. package/coverage/ui-kit/src/ui-kit/utils/urlQueryUtils.js.html +271 -0
  141. package/coverage/ui-kit/stories/atoms/BackgroundTitle.stories.jsx.html +202 -0
  142. package/coverage/ui-kit/stories/atoms/LinesOfText.stories.jsx.html +283 -0
  143. package/coverage/ui-kit/stories/atoms/LoadingDots.stories.jsx.html +226 -0
  144. package/coverage/ui-kit/stories/atoms/QrCode.stories.jsx.html +175 -0
  145. package/coverage/ui-kit/stories/atoms/RateSelector.stories.jsx.html +136 -0
  146. package/coverage/ui-kit/stories/atoms/Validation.stories.jsx.html +178 -0
  147. package/coverage/ui-kit/stories/atoms/buttons/Button.stories.jsx.html +883 -0
  148. package/coverage/ui-kit/stories/atoms/buttons/Close.stories.jsx.html +211 -0
  149. package/coverage/ui-kit/stories/atoms/buttons/LinkButton.stories.jsx.html +301 -0
  150. package/coverage/ui-kit/stories/atoms/buttons/index.html +146 -0
  151. package/coverage/ui-kit/stories/atoms/index.html +191 -0
  152. package/coverage/ui-kit/stories/molecules/LineWithIconLink.stories.jsx.html +154 -0
  153. package/coverage/ui-kit/stories/molecules/TitledLineWithIconLink.stories.jsx.html +160 -0
  154. package/coverage/ui-kit/stories/molecules/index.html +131 -0
  155. package/coverage/ui-kit/stories/organisms/Dialog/Dialog.stories.jsx.html +523 -0
  156. package/coverage/ui-kit/stories/organisms/Dialog/DialogButtons/DialogButtons.stories.jsx.html +328 -0
  157. package/coverage/ui-kit/stories/organisms/Dialog/DialogButtons/index.html +116 -0
  158. package/coverage/ui-kit/stories/organisms/Dialog/DialogStep/DialogStep.stories.jsx.html +337 -0
  159. package/coverage/ui-kit/stories/organisms/Dialog/DialogStep/index.html +116 -0
  160. package/coverage/ui-kit/stories/organisms/Dialog/index.html +116 -0
  161. package/coverage/ui-kit/stories/stubs/exampleContent.jsx.html +145 -0
  162. package/coverage/ui-kit/stories/stubs/index.html +116 -0
  163. package/coverage/ui-kit/stories/templates/DeterminedErrorDialogStep.stories.jsx.html +190 -0
  164. package/coverage/ui-kit/stories/templates/index.html +116 -0
  165. package/coverage/ui-kit/storybook-static/138.56b7edc4.iframe.bundle.js.html +85 -0
  166. package/coverage/ui-kit/storybook-static/312.6f62bbd9.iframe.bundle.js.html +85 -0
  167. package/coverage/ui-kit/storybook-static/341.57a15f57.iframe.bundle.js.html +85 -0
  168. package/coverage/ui-kit/storybook-static/595.2e40d981.iframe.bundle.js.html +85 -0
  169. package/coverage/ui-kit/storybook-static/607.3ea32459.iframe.bundle.js.html +85 -0
  170. package/coverage/ui-kit/storybook-static/609.949af3f6.iframe.bundle.js.html +85 -0
  171. package/coverage/ui-kit/storybook-static/693.1acf0184.iframe.bundle.js.html +85 -0
  172. package/coverage/ui-kit/storybook-static/797.c87cdf19.iframe.bundle.js.html +85 -0
  173. package/coverage/ui-kit/storybook-static/862.c15e3c9c.iframe.bundle.js.html +85 -0
  174. package/coverage/ui-kit/storybook-static/87.0a1bfeb1.iframe.bundle.js.html +85 -0
  175. package/coverage/ui-kit/storybook-static/893.e21210d8.iframe.bundle.js.html +85 -0
  176. package/coverage/ui-kit/storybook-static/996.10688684.iframe.bundle.js.html +85 -0
  177. package/coverage/ui-kit/storybook-static/atoms-BackgroundTitle-stories.1a5386a1.iframe.bundle.js.html +85 -0
  178. package/coverage/ui-kit/storybook-static/atoms-LinesOfText-stories.7043a48b.iframe.bundle.js.html +85 -0
  179. package/coverage/ui-kit/storybook-static/atoms-LoadingDots-stories.662d6a83.iframe.bundle.js.html +85 -0
  180. package/coverage/ui-kit/storybook-static/atoms-QrCode-stories.e10363b6.iframe.bundle.js.html +85 -0
  181. package/coverage/ui-kit/storybook-static/atoms-RateSelector-stories.da7b9f1f.iframe.bundle.js.html +85 -0
  182. package/coverage/ui-kit/storybook-static/atoms-Validation-stories.d561b311.iframe.bundle.js.html +85 -0
  183. package/coverage/ui-kit/storybook-static/atoms-buttons-Button-stories.d336c1a5.iframe.bundle.js.html +85 -0
  184. package/coverage/ui-kit/storybook-static/atoms-buttons-Close-stories.0a902a7c.iframe.bundle.js.html +85 -0
  185. package/coverage/ui-kit/storybook-static/atoms-buttons-LinkButton-stories.ca93ab6b.iframe.bundle.js.html +85 -0
  186. package/coverage/ui-kit/storybook-static/index.html +536 -0
  187. package/coverage/ui-kit/storybook-static/main.75ff1c31.iframe.bundle.js.html +85 -0
  188. package/coverage/ui-kit/storybook-static/molecules-LineWithIconLink-stories.2d2d5753.iframe.bundle.js.html +85 -0
  189. package/coverage/ui-kit/storybook-static/molecules-TitledLineWithIconLink-stories.1383fe3f.iframe.bundle.js.html +85 -0
  190. package/coverage/ui-kit/storybook-static/organisms-Dialog-Dialog-stories.4e6da717.iframe.bundle.js.html +85 -0
  191. package/coverage/ui-kit/storybook-static/organisms-Dialog-DialogButtons-DialogButtons-stories.b79c32a3.iframe.bundle.js.html +85 -0
  192. package/coverage/ui-kit/storybook-static/organisms-Dialog-DialogStep-DialogStep-stories.74896048.iframe.bundle.js.html +85 -0
  193. package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/@storybook/addon-backgrounds/dist/index.html +116 -0
  194. package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/@storybook/addon-backgrounds/dist/preview.js.html +118 -0
  195. package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/@storybook/components/dist/formatter-SWP5E3XI.mjs.html +118 -0
  196. package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/@storybook/components/dist/index.html +116 -0
  197. package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/buffer/index.html +116 -0
  198. package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/buffer/index.js.html +118 -0
  199. package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/markdown-to-jsx/dist/index.html +116 -0
  200. package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/markdown-to-jsx/dist/index.modern.js.html +118 -0
  201. package/coverage/ui-kit/storybook-static/runtime~main.b108a22d.iframe.bundle.js.html +85 -0
  202. package/coverage/ui-kit/storybook-static/sb-addons/actions-9/index.html +116 -0
  203. package/coverage/ui-kit/storybook-static/sb-addons/actions-9/manager-bundle.js.html +94 -0
  204. package/coverage/ui-kit/storybook-static/sb-addons/essentials-backgrounds-2/index.html +116 -0
  205. package/coverage/ui-kit/storybook-static/sb-addons/essentials-backgrounds-2/manager-bundle.js.html +121 -0
  206. package/coverage/ui-kit/storybook-static/sb-addons/essentials-controls-1/index.html +116 -0
  207. package/coverage/ui-kit/storybook-static/sb-addons/essentials-controls-1/manager-bundle.js.html +274 -0
  208. package/coverage/ui-kit/storybook-static/sb-addons/essentials-measure-4/index.html +116 -0
  209. package/coverage/ui-kit/storybook-static/sb-addons/essentials-measure-4/manager-bundle.js.html +94 -0
  210. package/coverage/ui-kit/storybook-static/sb-addons/essentials-outline-5/index.html +116 -0
  211. package/coverage/ui-kit/storybook-static/sb-addons/essentials-outline-5/manager-bundle.js.html +94 -0
  212. package/coverage/ui-kit/storybook-static/sb-addons/essentials-toolbars-3/index.html +116 -0
  213. package/coverage/ui-kit/storybook-static/sb-addons/essentials-toolbars-3/manager-bundle.js.html +94 -0
  214. package/coverage/ui-kit/storybook-static/sb-addons/interactions-7/index.html +116 -0
  215. package/coverage/ui-kit/storybook-static/sb-addons/interactions-7/manager-bundle.js.html +121 -0
  216. package/coverage/ui-kit/storybook-static/sb-addons/links-0/index.html +116 -0
  217. package/coverage/ui-kit/storybook-static/sb-addons/links-0/manager-bundle.js.html +94 -0
  218. package/coverage/ui-kit/storybook-static/sb-addons/onboarding-6/index.html +116 -0
  219. package/coverage/ui-kit/storybook-static/sb-addons/onboarding-6/manager-bundle.js.html +1588 -0
  220. package/coverage/ui-kit/storybook-static/sb-addons/viewport-8/index.html +116 -0
  221. package/coverage/ui-kit/storybook-static/sb-addons/viewport-8/manager-bundle.js.html +94 -0
  222. package/coverage/ui-kit/storybook-static/sb-manager/WithTooltip-V3YHNWJZ-LVYLGZW2.js.html +88 -0
  223. package/coverage/ui-kit/storybook-static/sb-manager/chunk-2IXBUOFS.js.html +106 -0
  224. package/coverage/ui-kit/storybook-static/sb-manager/chunk-INSKDKQB.js.html +1129 -0
  225. package/coverage/ui-kit/storybook-static/sb-manager/chunk-NGTUFCUO.js.html +112 -0
  226. package/coverage/ui-kit/storybook-static/sb-manager/chunk-UUEAOBSN.js.html +1303 -0
  227. package/coverage/ui-kit/storybook-static/sb-manager/chunk-ZEU7PDD3.js.html +88 -0
  228. package/coverage/ui-kit/storybook-static/sb-manager/formatter-SWP5E3XI-7BGIK6BL.js.html +553 -0
  229. package/coverage/ui-kit/storybook-static/sb-manager/globals-module-info.js.html +88 -0
  230. package/coverage/ui-kit/storybook-static/sb-manager/globals.js.html +88 -0
  231. package/coverage/ui-kit/storybook-static/sb-manager/index.html +281 -0
  232. package/coverage/ui-kit/storybook-static/sb-manager/index.js.html +88 -0
  233. package/coverage/ui-kit/storybook-static/sb-manager/runtime.js.html +88 -0
  234. package/coverage/ui-kit/storybook-static/sb-manager/syntaxhighlighter-V7JZZA35-DXZCI2WR.js.html +88 -0
  235. package/coverage/ui-kit/storybook-static/sb-preview/globals.js.html +88 -0
  236. package/coverage/ui-kit/storybook-static/sb-preview/index.html +131 -0
  237. package/coverage/ui-kit/storybook-static/sb-preview/runtime.js.html +421 -0
  238. package/coverage/ui-kit/storybook-static/templates-DeterminedErrorDialogStep-stories.3cc14214.iframe.bundle.js.html +85 -0
  239. package/dist/global.css +197 -0
  240. package/dist/global.css.map +1 -0
  241. package/dist/index.cjs +10864 -21
  242. package/dist/index.cjs.map +1 -1
  243. package/dist/index.css +2212 -8491
  244. package/dist/index.css.map +1 -1
  245. package/dist/index.modern.js +8354 -22
  246. package/dist/index.modern.js.map +1 -1
  247. package/dist/index.module.js +10784 -23
  248. package/dist/index.module.js.map +1 -1
  249. package/dist/index.umd.js +10855 -25
  250. package/dist/index.umd.js.map +1 -1
  251. package/index.js +1 -1
  252. package/package.json +36 -9
  253. package/src/common-apis/adapters/axiosAdapter.js +35 -0
  254. package/src/common-apis/adapters/qrUtils.js +18 -0
  255. package/src/common-apis/amountUtils.js +359 -0
  256. package/src/common-apis/errorUtils.js +42 -0
  257. package/src/common-apis/external-apis/apiGroups.js +55 -0
  258. package/src/common-apis/external-apis/ipAddressProviders.js +89 -0
  259. package/src/common-apis/fiatCurrenciesService.js +153 -0
  260. package/src/common-apis/globalConstants.jsx +3 -0
  261. package/src/common-apis/models/blockchain.js +10 -0
  262. package/src/common-apis/models/coin.js +153 -0
  263. package/src/common-apis/models/protocol.js +5 -0
  264. package/src/common-apis/tests/amountUtils/composeRateText.test.js +152 -0
  265. package/src/common-apis/tests/integration/external-apis/ipAddressProviders/getClientIpAddress.test.js +12 -0
  266. package/src/common-apis/utils/cache.js +242 -0
  267. package/src/common-apis/utils/emailAPI.js +16 -0
  268. package/src/common-apis/utils/logging/logger.js +41 -0
  269. package/src/common-apis/utils/logging/logsStorage.js +61 -0
  270. package/src/common-apis/utils/postponeExecution.js +11 -0
  271. package/src/common-apis/utils/safeStringify.js +50 -0
  272. package/src/index.js +84 -0
  273. package/src/robust-api-caller/cacheAndConcurrentRequestsResolver.js +495 -0
  274. package/src/robust-api-caller/cachedRobustExternalApiCallerService.js +147 -0
  275. package/src/robust-api-caller/cancelProcessing.js +29 -0
  276. package/src/robust-api-caller/concurrentCalculationsMetadataHolder.js +75 -0
  277. package/src/robust-api-caller/externalApiProvider.js +156 -0
  278. package/src/robust-api-caller/externalServicesStatsCollector.js +78 -0
  279. package/src/robust-api-caller/robustExternalAPICallerService.js +304 -0
  280. package/src/robust-api-caller/tests/robustExternalAPICallerService/robustExternalAPICallerService/callExternalAPI/_performCallAttempt.test.js +533 -0
  281. package/src/robust-api-caller/tests/robustExternalAPICallerService/robustExternalAPICallerService/callExternalAPI/callExternalAPI.test.js +532 -0
  282. package/src/robust-api-caller/tests/robustExternalAPICallerService/robustExternalAPICallerService/constructor.test.js +19 -0
  283. package/src/swaps-lib/external-apis/letsExchangeSwapProvider.js +476 -0
  284. package/src/swaps-lib/external-apis/swapProvider.js +491 -0
  285. package/src/swaps-lib/external-apis/swapspaceSwapProvider.js +550 -0
  286. package/src/swaps-lib/models/baseSwapCreationInfo.js +46 -0
  287. package/src/swaps-lib/models/existingSwap.js +73 -0
  288. package/src/swaps-lib/models/existingSwapWithFiatData.js +128 -0
  289. package/src/swaps-lib/services/publicSwapService.js +671 -0
  290. package/src/swaps-lib/test/external-apis/swapProvider/getAllSupportedCurrencies.test.js +63 -0
  291. package/src/swaps-lib/test/external-apis/swapProvider/getDepositCurrencies.test.js +73 -0
  292. package/src/swaps-lib/test/external-apis/swapProvider/getWithdrawalCurrencies.test.js +102 -0
  293. package/src/swaps-lib/test/external-apis/swapProvider/removeProtocolNameFromCoinName.test.js +152 -0
  294. package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/_fetchSupportedCurrenciesIfNeeded.test.js +538 -0
  295. package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/createSwap.test.js +1249 -0
  296. package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/getSwapInfo.test.js +1700 -0
  297. package/src/swaps-lib/test/utils/swapUtils/safeHandleRequestsLimitExceeding.test.js +80 -0
  298. package/src/swaps-lib/utils/swapUtils.js +195 -0
  299. package/{styles → src/ui-kit/assets/styles}/_functions.scss +5 -0
  300. package/{styles → src/ui-kit/assets/styles}/_mixins.scss +2 -2
  301. package/{styles → src/ui-kit/assets/styles}/_placeholder.scss +3 -3
  302. package/{styles → src/ui-kit/assets/styles}/_variables.scss +17 -15
  303. package/src/ui-kit/assets/styles/fonts/NunitoSans-Bold.ttf +0 -0
  304. package/src/ui-kit/assets/styles/fonts/NunitoSans-ExtraBold.ttf +0 -0
  305. package/src/ui-kit/assets/styles/fonts/NunitoSans-Light.ttf +0 -0
  306. package/src/ui-kit/assets/styles/fonts/NunitoSans-Regular.ttf +0 -0
  307. package/src/ui-kit/assets/styles/fonts/NunitoSans-SemiBold.ttf +0 -0
  308. package/src/ui-kit/assets/styles/global.scss +165 -0
  309. package/src/ui-kit/assets/styles/index.scss +10 -0
  310. package/src/ui-kit/assets/wrappedImages/arrowIcon.jsx +13 -0
  311. package/src/ui-kit/assets/wrappedImages/arrowTosca.jsx +14 -0
  312. package/src/ui-kit/assets/wrappedImages/arrowWhite.jsx +14 -0
  313. package/src/ui-kit/assets/wrappedImages/darkRectangle.jsx +7 -0
  314. package/src/ui-kit/assets/wrappedImages/determinedError.jsx +118 -0
  315. package/src/ui-kit/assets/wrappedImages/failedValidationIcon.jsx +39 -0
  316. package/src/ui-kit/assets/wrappedImages/infoIcon.jsx +16 -0
  317. package/src/ui-kit/assets/wrappedImages/noticeQuestionIcon.jsx +54 -0
  318. package/src/ui-kit/assets/wrappedImages/successfulValidationIcon.jsx +26 -0
  319. package/src/ui-kit/assets/wrappedImages/walletIcon.jsx +22 -0
  320. package/src/ui-kit/components/atoms/AssetIcon/AssetIcon.jsx +57 -0
  321. package/{stories → src/ui-kit/components}/atoms/AssetIcon/asset-icon.module.scss +1 -1
  322. package/src/ui-kit/components/atoms/AssetSelection/AssetSelection.jsx +68 -0
  323. package/src/ui-kit/components/atoms/AssetSelection/asset-selection.module.scss +56 -0
  324. package/src/ui-kit/components/atoms/BackgroundTitle/BackgroundTitle.jsx +34 -0
  325. package/src/ui-kit/components/atoms/BackgroundTitle/background-title.module.scss +52 -0
  326. package/src/ui-kit/components/atoms/InformationMessage/InformationMessage.jsx +51 -0
  327. package/src/ui-kit/components/atoms/InformationMessage/information-message.module.scss +38 -0
  328. package/src/ui-kit/components/atoms/Input/Input.jsx +183 -0
  329. package/src/ui-kit/components/atoms/Input/input.module.scss +107 -0
  330. package/{stories → src/ui-kit/components}/atoms/LoadingDots/LoadingDots.jsx +8 -28
  331. package/{stories → src/ui-kit/components}/atoms/LoadingDots/LoadingDots.module.scss +3 -2
  332. package/src/ui-kit/components/atoms/NoticeIcon/NoticeIcon.jsx +64 -0
  333. package/src/ui-kit/components/atoms/NoticeIcon/notice-icon.module.scss +14 -0
  334. package/src/ui-kit/components/atoms/QrCode/QrCode.jsx +50 -0
  335. package/src/ui-kit/components/atoms/QrCode/qr-code.module.scss +15 -0
  336. package/src/ui-kit/components/atoms/RateSelector/RateSelector.jsx +30 -0
  337. package/src/ui-kit/components/atoms/RateSelector/rate-selector.module.scss +47 -0
  338. package/{stories → src/ui-kit/components}/atoms/SupportChat/SupportChat.jsx +5 -1
  339. package/src/ui-kit/components/atoms/Textarea/Textarea.jsx +148 -0
  340. package/src/ui-kit/components/atoms/Textarea/textarea.module.scss +71 -0
  341. package/src/ui-kit/components/atoms/TitleBox/TitleBox.jsx +141 -0
  342. package/src/ui-kit/components/atoms/TitleBox/title-box.module.scss +32 -0
  343. package/src/ui-kit/components/atoms/Tooltip/Tooltip.jsx +77 -0
  344. package/src/ui-kit/components/atoms/Tooltip/tooltip.module.scss +237 -0
  345. package/src/ui-kit/components/atoms/TwoLinesOfText/LinesOfText.jsx +76 -0
  346. package/src/ui-kit/components/atoms/TwoLinesOfText/lines-of-text.module.scss +65 -0
  347. package/src/ui-kit/components/atoms/Validation/Validation.jsx +41 -0
  348. package/src/ui-kit/components/atoms/Validation/validation.module.scss +15 -0
  349. package/{stories → src/ui-kit/components}/atoms/buttons/Button/Button.jsx +24 -50
  350. package/{stories → src/ui-kit/components}/atoms/buttons/Button/Button.module.scss +1 -1
  351. package/src/ui-kit/components/atoms/buttons/Close/Close.jsx +58 -0
  352. package/src/ui-kit/components/atoms/buttons/Close/close.module.scss +75 -0
  353. package/src/ui-kit/components/atoms/buttons/LinkButton/LinkButton.jsx +112 -0
  354. package/src/ui-kit/components/atoms/buttons/LinkButton/link-button.module.scss +49 -0
  355. package/src/ui-kit/components/atoms/buttons/RadioButtonWithText/RadioButtonWithText.jsx +110 -0
  356. package/src/ui-kit/components/atoms/buttons/RadioButtonWithText/radio-button-with-text.module.scss +86 -0
  357. package/src/ui-kit/components/molecules/AmountInput/AmountInput.jsx +325 -0
  358. package/src/ui-kit/components/molecules/AmountInput/amount-input.module.scss +199 -0
  359. package/src/ui-kit/components/molecules/CoinPicker/CoinPicker.jsx +511 -0
  360. package/src/ui-kit/components/molecules/CoinPicker/coin-picker.module.scss +207 -0
  361. package/src/ui-kit/components/molecules/LineWithIconLink/LineWithIconLink.jsx +35 -0
  362. package/src/ui-kit/components/molecules/LineWithIconLink/line-with-icon-link.module.scss +25 -0
  363. package/src/ui-kit/components/molecules/TitledLineWithIconLink/TitledLineWithIconLink.jsx +32 -0
  364. package/src/ui-kit/components/organisms/CoinPickerDialogStep/CoinPickerDialogStep.jsx +66 -0
  365. package/src/ui-kit/components/organisms/Dialog/Dialog.jsx +494 -0
  366. package/src/ui-kit/components/organisms/Dialog/DialogButtons/DialogButtons.jsx +122 -0
  367. package/src/ui-kit/components/organisms/Dialog/DialogButtons/dialog-buttons.module.scss +25 -0
  368. package/src/ui-kit/components/organisms/Dialog/DialogStep/DialogStep.jsx +538 -0
  369. package/src/ui-kit/components/organisms/Dialog/DialogStep/dialog-step.module.scss +381 -0
  370. package/src/ui-kit/components/organisms/Dialog/dialog.module.scss +226 -0
  371. package/src/ui-kit/components/organisms/SwapForm/SwapForm.jsx +1330 -0
  372. package/src/ui-kit/components/organisms/SwapForm/swap-form.module.scss +134 -0
  373. package/src/ui-kit/components/templates/DeterminedErrorDialogStep/DeterminedErrorDialogStep.jsx +77 -0
  374. package/src/ui-kit/hooks/useCallHandlingErrors.js +22 -0
  375. package/src/ui-kit/hooks/useIsHydrated.js +12 -0
  376. package/src/ui-kit/hooks/useReferredState.js +24 -0
  377. package/src/ui-kit/tests/utils/inputValueProviders/provideFormatOfFloatValueByInputString.test.js +132 -0
  378. package/src/ui-kit/tests/utils/urlQueryUtils/getQueryParameterValues.test.js +65 -0
  379. package/src/ui-kit/tests/utils/urlQueryUtils/saveQueryParameterAndValues.test.js +104 -0
  380. package/src/ui-kit/utils/inputValueProviders.js +50 -0
  381. package/src/ui-kit/utils/textUtils.js +18 -0
  382. package/src/ui-kit/utils/uiUtils.js +12 -0
  383. package/src/ui-kit/utils/urlQueryUtils.js +62 -0
  384. package/stories/stubs/exampleContent.jsx +20 -0
  385. package/stories/atoms/AssetIcon/AssetIcon.jsx +0 -55
  386. package/stories/index.js +0 -4
  387. package/styles/_global-classes.scss +0 -433
  388. package/styles/fonts/NunitoSans-Bold.ttf +0 -0
  389. package/styles/fonts/NunitoSans-ExtraBold.ttf +0 -0
  390. package/styles/fonts/NunitoSans-Light.ttf +0 -0
  391. package/styles/fonts/NunitoSans-Regular.ttf +0 -0
  392. package/styles/fonts/NunitoSans-SemiBold.ttf +0 -0
  393. package/styles/global-styles-index.scss +0 -74
  394. package/styles/index.scss +0 -33
  395. /package/{styles → src/ui-kit/assets/styles}/colors/_light-colors.scss +0 -0
  396. /package/{styles → src/ui-kit/assets/styles}/colors/_solid-colors.scss +0 -0
  397. /package/{styles → src/ui-kit/assets/styles}/size/_margin-size.scss +0 -0
  398. /package/{styles → src/ui-kit/assets/styles}/size/_padding-size.scss +0 -0
@@ -0,0 +1,1330 @@
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/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
+ * @return {Promise<boolean>}
174
+ */
175
+
176
+ /**
177
+ * Swap form provides basic functionality for entering to/from amounts both in crypto and fiat, switching assets,
178
+ * selecting assets, showing balance for assets. It gracefully handles unavailable fiat rates and can work
179
+ * both with and without a wallet environment (without balances).
180
+ *
181
+ * @param {object} props - Props object for SwapForm component.
182
+ * @param {string} props.sendingAssetTicker - Rabbit format of the ticker symbol for the asset being sent.
183
+ * @param {string} props.receivingAssetTicker - Rabbit format of the ticker symbol for the asset being received.
184
+ * @param {number} [props.sendingAssetDecimalCount=AmountUtils.significantDecimalCount] - Decimal count for the sending asset.
185
+ * @param {number} [props.receivingAssetDecimalCount=AmountUtils.significantDecimalCount] - Decimal count for the receiving asset.
186
+ * @param {string} props.sendingAssetTickerPrintable - Standard ticker symbol for the sending asset.
187
+ * @param {string} props.receivingAssetTickerPrintable - Standard ticker symbol for the receiving asset.
188
+ * @param {string} [props.sendingAssetProtocol] - Protocol name to be displayed in text on the change asset button.
189
+ * @param {string} [props.receivingAssetProtocol] - Protocol name to be displayed in text on the change asset button.
190
+ * @param {string} props.sendingAssetIconSrc - Source URL for the sending asset icon.
191
+ * @param {string} [props.sendingAssetProtocolIconSrc=null] - Optional source URL for the sending asset protocol icon.
192
+ * @param {string} props.receivingAssetIconSrc - Source URL for the receiving asset icon.
193
+ * @param {string} [props.receivingAssetProtocolIconSrc=null] - Optional source URL for the receiving asset protocol icon.
194
+ * @param {string} [props.fallBackAssetIconSrc=null] - Optional source URL for a fallback icon used when an icon fails to load.
195
+ * @param {string} [props.sendingAssetFeeCoinTickerPrintable] - Optional standard ticker symbol for the fee coin of the sending asset.
196
+ * @param {string} [props.sendingAssetBalance] - Balance of the sending asset.
197
+ * @param {string} [props.receivingAssetBalance] - Balance of the receiving asset.
198
+ * @param {handleClick} props.handleChangeSendingAssetClick - Function to handle clicking on the change sending asset button.
199
+ * @param {handleClick} props.handleChangeReceivingAssetClick - Function to handle clicking on the change receiving asset button.
200
+ * @param {handleConfirmButtonClick} props.handleConfirmButtonClick - Function to handle clicking on the confirm button.
201
+ * @param {composeConfirmButtonTo} props.composeConfirmButtonTo - Function to compose the URL for the confirm button.
202
+ * @param {setSwapCreationEstimation} props.setSwapCreationEstimation - Function to set the swap creation estimation.
203
+ * @param {handleUnexpectedError} props.handleUnexpectedError - Function to handle unexpected errors.
204
+ * @param {rotateAssets} props.rotateAssets - Function to rotate the assets (swap sending and receiving assets).
205
+ * @param {string} [props.preservedAmount=null] - Amount to be preserved.
206
+ * @param {handleSwapServiceError} props.handleSwapServiceError - Function to handle standard errors that we can recognize.
207
+ * @param {boolean} [props.formHasBalance] - Indicates if the form has balance information.
208
+ * @param {retrieveSwapDetails} props.retrieveSwapDetails - Function to retrieve swap details based on the given parameters.
209
+ * @param {retrieveInitialSwapData} props.retrieveInitialSwapData - Function to retrieve initial swap data for a given pair of assets.
210
+ * @param {number} props.triggerDataUpdateResetting - Number to reset interval updating the data periodically.
211
+ * @param {React.Ref} props.fromAssetSelectionButtonRef - Reference to the from asset selection button.
212
+ * @param {React.Ref} props.toAssetSelectionButtonRef - Reference to the to asset selection button.
213
+ * @param {number|string} [props.sendingAssetToFiatRate] - Rate for converting the sending asset to fiat.
214
+ * @param {number|string} [props.receivingAssetToFiatRate] - Rate for converting the receiving asset to fiat.
215
+ * @param {string} [props.fiatCurrencyCode] - Code for the fiat currency.
216
+ * @param {number} [props.fiatCurrencyDecimals] - Decimal places for the fiat currency.
217
+ * @param {boolean} [props.formHasFiat] - Indicates if the form supports fiat currency.
218
+ * @param {string|null} [props.termsOfUseUrl] - Terms of use URL, shown only if both terms & privacy policy passed.
219
+ * @param {string|null} [props.privacyPolicyUrl] - Privacy policy of use URL, shown only if both terms & privacy policy passed.
220
+ * @param {string} props.recipientAddressExtraIdName - Extra ID name for the recipient address.
221
+ * @param {string} props.refundAddressExtraIdName - Extra ID name for the refund address.
222
+ * @param {object} [props.translations] - Object containing translations, default English texts will be used if omitted.
223
+ * @param {string} props.swapSeparatorIconSrc - Source URL for the swap separator icon.
224
+ * @param {boolean} props.swapButtonAlwaysActive - Setting that allows the form state to proceed to the next step regardless of validity.
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
+ // recipientAddressExtraIdName,
302
+ // refundAddressExtraIdName,
303
+ translations = {
304
+ swapAllButtonTitles: {
305
+ enable: "Swap all",
306
+ cancel: "Cancel",
307
+ },
308
+ input: {
309
+ fiatPlaceholder: "Enter fiat amount",
310
+ balanceLoaderText: "Loading balance...",
311
+ },
312
+ consents: {
313
+ consentText: 'By clicking "Swap" you agree with Rabbit Swap\'s',
314
+ termsOfUse: "Terms of Use",
315
+ and: "and",
316
+ privacyPolicy: "Privacy Policy",
317
+ },
318
+ informationBlock: {
319
+ minimumAmount: "Minimal amount: ",
320
+ maximumAmount: "Maximum amount: ",
321
+ transactionFee: "Network fee: ",
322
+ calculatingNetworkFee: "Calculating network fee..",
323
+ loadingMinimalAmount: "Loading minimal amount..",
324
+ swapRate: "Rate: ",
325
+ calculatingSwapRates: "Calculating swap rates..",
326
+ pairNotAvailable: "Pair is not available now. Please, try again later or choose another pair.",
327
+ },
328
+ addressFields: {
329
+ addressTitle: "Recepient address",
330
+ refundAddressTitle: "Refund address",
331
+ extraIdPlaceholder: "(optional)",
332
+ refundAddressExtraIdTitle: "Refund extra ID (MEMO):",
333
+ refundAddressExtraIdNotice:
334
+ "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.",
335
+ receivingAddressExtraIdTitle: "Destination extra ID (MEMO):",
336
+ receivingAddressExtraIdNotice:
337
+ "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.",
338
+ },
339
+ rateSelector: {
340
+ floatingRate: "Floating rate",
341
+ fixedRate: "Fixed rate",
342
+ },
343
+ confirmButtonText: "Swap",
344
+ },
345
+ }) => {
346
+ const DETAIL_REFRESH_INTERVAL_MS = 1.5 * 60000;
347
+ const IS_FIXED_BY_DEFAULT = false;
348
+
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) => {
485
+ try {
486
+ clearTimeout(dataUpdateTimeoutId.current);
487
+
488
+ if (isSwapAll) {
489
+ loadFullEstimation(null);
490
+ return;
491
+ }
492
+
493
+ if (!amount) {
494
+ return;
495
+ }
496
+
497
+ if (BigNumber(amount).eq("0")) {
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
+ const currentSendingAssetTicker = sendingAssetTicker;
561
+ const currentReceivingAssetTicker = receivingAssetTicker;
562
+
563
+ const response = await retrieveSwapDetails(
564
+ currentSendingAssetTicker,
565
+ currentReceivingAssetTicker,
566
+ amount,
567
+ isSwapAll.current,
568
+ isFixedRate.current ?? IS_FIXED_BY_DEFAULT,
569
+ isFixedRate.current ? isLastEditedReceiving.current : false
570
+ );
571
+
572
+ if (
573
+ currentSendingAssetTicker !== sendingAssetTickerReferred.current ||
574
+ currentReceivingAssetTicker !== receivingAssetTickerReferred.current
575
+ ) {
576
+ return;
577
+ }
578
+
579
+ if (
580
+ !isSwapAll.current &&
581
+ String(amount) !==
582
+ String(
583
+ isForPreserved && sendAssetAmount.current == null && receiveAssetAmount.current == null
584
+ ? preservedAmount
585
+ : isFixedRate.current && isLastEditedReceiving.current
586
+ ? receiveAssetAmount.current
587
+ : sendAssetAmount.current
588
+ )
589
+ ) {
590
+ // Means amount changed and we no more need to do this exact calculation
591
+ return;
592
+ }
593
+
594
+ const swapCreationInfo = response?.swapCreationInfo;
595
+
596
+ if (response.result) {
597
+ if (isSwapAll.current) {
598
+ setIsAmountZero(BigNumber("0").eq(swapCreationInfo.fromAmountCoins));
599
+ }
600
+
601
+ setUpdateSendInputTo(swapCreationInfo.fromAmountCoins);
602
+ setUpdateReceiveInputTo(swapCreationInfo.toAmountCoins);
603
+
604
+ if (isLastEditedReceiving.current) {
605
+ setSendAssetAmount(swapCreationInfo.fromAmountCoins);
606
+ } else {
607
+ setReceiveAssetAmount(swapCreationInfo.toAmountCoins);
608
+ }
609
+
610
+ setAmountLimitsAndRate(swapCreationInfo);
611
+ setSwapCreationEstimation(swapCreationInfo);
612
+ setIsRefundAddressRequired(swapCreationInfo?.isRefundAddressRequired);
613
+ processMinMaxAmounts(isSwapAll.current ? swapCreationInfo.fromAmountCoins : amount);
614
+ setIsSwapCalculated(true);
615
+ } else {
616
+ handleSwapServiceError(
617
+ response.reason,
618
+ setValidationContent,
619
+ setBalanceValid,
620
+ setMinimalAmountValid,
621
+ setMaximumAmountValid,
622
+ setIsPairSupported,
623
+ setIsSameCoins
624
+ );
625
+ if (isSwapAll.current) {
626
+ /* We disable swap all if swap all details retrieval fails and set
627
+ * previous limits and rate. We set null to avoid triggering reloading of initial data.
628
+ */
629
+ setIsSwapAll(null);
630
+ setAmountLimitsAndRate(dataMemento);
631
+ } else {
632
+ /* We set returned amount limits and rate only if the failed details retrieval is not
633
+ * for the swap All case.
634
+ */
635
+ setAmountLimitsAndRate(response);
636
+ if (isLastEditedReceiving.current) {
637
+ setSendAssetAmount("");
638
+ } else {
639
+ setReceiveAssetAmount("");
640
+ }
641
+ }
642
+ }
643
+ setIsLoading(false);
644
+ } catch (e) {
645
+ handleUnexpectedError(e);
646
+ }
647
+ })();
648
+ };
649
+
650
+ const loadMinimalAmountAndSwapRate = (isCalledForClearedInput = false) => {
651
+ (async () => {
652
+ try {
653
+ setIsLoading(true);
654
+ setMinimalAmount(null);
655
+ setMaximumAmount(null);
656
+ setSwapRate(null);
657
+ setValidationContent(null);
658
+ setIsPairSupported(true);
659
+ setIsSwapCalculated(false);
660
+
661
+ const swapData = await retrieveInitialSwapData(sendingAssetTicker, receivingAssetTicker);
662
+
663
+ if (sendAssetAmount.current != null && !isCalledForClearedInput) {
664
+ // Means user already entered amount after starting the form initialization
665
+ return;
666
+ }
667
+
668
+ if (swapData.result === true) {
669
+ setAmountLimitsAndRate(swapData);
670
+ } else {
671
+ handleSwapServiceError(
672
+ swapData.reason,
673
+ setValidationContent,
674
+ setBalanceValid,
675
+ setMinimalAmountValid,
676
+ setMaximumAmountValid,
677
+ setIsPairSupported,
678
+ setIsSameCoins
679
+ );
680
+ }
681
+
682
+ setIsLoading(false);
683
+ } catch (e) {
684
+ handleUnexpectedError(e);
685
+ }
686
+ })();
687
+ };
688
+
689
+ const handleChangeAssetsIconClick = e => {
690
+ callHandlingErrors(() => {
691
+ if (!isLoading.current) {
692
+ setIsSwapAll(null);
693
+ setMaximumAmountValid(true);
694
+ setMinimalAmountValid(true);
695
+
696
+ const sendAssetAmountMemento = sendAssetAmount.current;
697
+ const receiveAssetAmountMemento = receiveAssetAmount.current;
698
+
699
+ if (isLastEditedReceiving.current) {
700
+ setSendAssetAmount("");
701
+ setUpdateSendInputTo("");
702
+
703
+ setReceiveAssetAmount(sendAssetAmountMemento);
704
+ setUpdateReceiveInputTo(sendAssetAmountMemento);
705
+ } else {
706
+ setSendAssetAmount(receiveAssetAmountMemento);
707
+ setUpdateSendInputTo(receiveAssetAmountMemento);
708
+
709
+ setReceiveAssetAmount("");
710
+ setUpdateReceiveInputTo("");
711
+ }
712
+
713
+ rotateAssets(sendingAssetTicker, receivingAssetTicker);
714
+ }
715
+ }, e);
716
+ };
717
+
718
+ const handleRateModeChanged = isFixed => {
719
+ setIsFixedRate(isFixed);
720
+ requestDataRefresh(isLastEditedReceiving.current ? receiveAssetAmount.current : sendAssetAmount.current, true);
721
+ };
722
+
723
+ useEffect(() => {
724
+ if (isSwapAll.current === true) {
725
+ requestDataRefresh(undefined, true, true);
726
+ } else if (isSwapAll.current === false) {
727
+ loadMinimalAmountAndSwapRate();
728
+ }
729
+ // eslint-disable-next-line react-hooks/exhaustive-deps
730
+ }, [isSwapAll.current]);
731
+
732
+ useEffect(() => {
733
+ onIsFixedChange(isFixedRate.current);
734
+ if (!isFixedRate.current) setIsLastEditedReceiving(false);
735
+ // eslint-disable-next-line react-hooks/exhaustive-deps
736
+ }, [isFixedRate.current]);
737
+
738
+ useEffect(() => {
739
+ if (!sendingAssetTicker || !receivingAssetTicker) return;
740
+
741
+ const isCurrentAmountNotZero = sendAssetAmount.current && !BigNumber("0").eq(sendAssetAmount.current);
742
+ if (isCurrentAmountNotZero) {
743
+ loadFullEstimation(isLastEditedReceiving.current ? receiveAssetAmount.current : sendAssetAmount.current);
744
+ } else {
745
+ loadMinimalAmountAndSwapRate(true);
746
+ }
747
+
748
+ // eslint-disable-next-line react-hooks/exhaustive-deps
749
+ }, [sendingAssetTicker, receivingAssetTicker]);
750
+
751
+ useEffect(() => {
752
+ if (!minimalAmountValid || isAmountZero) {
753
+ setTransactionFee(null);
754
+ }
755
+ if (isAmountZero) {
756
+ clearTimeout(dataUpdateTimeoutId.current);
757
+ }
758
+
759
+ setReadyToSwap(
760
+ swapButtonAlwaysActive ||
761
+ ((balanceValid || !formHasBalance) &&
762
+ minimalAmountValid &&
763
+ !isAmountZero &&
764
+ isSwapCalculated &&
765
+ (!isSameCoins || !formHasBalance) &&
766
+ isPairSupported &&
767
+ (!isAddressFieldEnabled || isRecipientAddressValid.current) &&
768
+ (!isRefundAddressRequired || isRefundAddressValid.current))
769
+ );
770
+ // eslint-disable-next-line react-hooks/exhaustive-deps
771
+ }, [
772
+ balanceValid,
773
+ formHasBalance,
774
+ minimalAmountValid,
775
+ isAmountZero,
776
+ isSwapCalculated,
777
+ isSameCoins,
778
+ isPairSupported,
779
+ isAddressFieldEnabled,
780
+ isRecipientAddressValid.current,
781
+ isRefundAddressRequired,
782
+ isRefundAddressValid.current,
783
+ ]);
784
+
785
+ useEffect(() => {
786
+ setIsRecipientAddressValid(false);
787
+ setRecipientAddress("");
788
+ setRecipientAddressExtraId("");
789
+ // eslint-disable-next-line react-hooks/exhaustive-deps
790
+ }, [receivingAssetTicker]);
791
+
792
+ useEffect(() => {
793
+ setIsRefundAddressValid(false);
794
+ setRefundAddress("");
795
+ setRefundAddressExtraId("");
796
+ // eslint-disable-next-line react-hooks/exhaustive-deps
797
+ }, [sendingAssetTicker]);
798
+
799
+ useEffect(() => {
800
+ (async () => {
801
+ if (!receivingAssetTicker) return;
802
+ setIsRecipientAddressValid(
803
+ recipientAddress.current === ""
804
+ ? false
805
+ : await validateAddressByTicker(receivingAssetTicker, recipientAddress.current, isFixedRate.current)
806
+ );
807
+ })();
808
+ // eslint-disable-next-line react-hooks/exhaustive-deps
809
+ }, [recipientAddress.current, recipientAddressExtraId.current, receivingAssetTicker]);
810
+
811
+ useEffect(() => {
812
+ (async () => {
813
+ if (!sendingAssetTicker || !isRefundAddressRequired) return;
814
+ setIsRefundAddressValid(
815
+ refundAddress.current === ""
816
+ ? false
817
+ : await validateAddressByTicker(sendingAssetTicker, refundAddress.current, isFixedRate.current)
818
+ );
819
+ })();
820
+ // eslint-disable-next-line react-hooks/exhaustive-deps
821
+ }, [refundAddress.current, refundAddressExtraId.current, sendingAssetTicker, isRefundAddressRequired]);
822
+
823
+ useEffect(() => {
824
+ // Here we set up auto recalculations for the swap details if the form is ready to swap but is idle for some time
825
+ let timeoutId = null;
826
+ if (readyToSwap) {
827
+ timeoutId = setTimeout(
828
+ () =>
829
+ requestDataRefresh(
830
+ isLastEditedReceiving.current
831
+ ? receiveAssetAmount.current
832
+ : sendAssetAmount.current ?? preservedAmount,
833
+ true
834
+ ),
835
+ DETAIL_REFRESH_INTERVAL_MS
836
+ );
837
+ setIdleDataUpdateTimeoutId(timeoutId);
838
+ } else {
839
+ clearTimeout(idleDataUpdateTimeoutId.current);
840
+ setIdleDataUpdateTimeoutId(null);
841
+ }
842
+ return () => {
843
+ timeoutId != null && clearTimeout(timeoutId);
844
+ };
845
+ // eslint-disable-next-line react-hooks/exhaustive-deps
846
+ }, [readyToSwap]);
847
+
848
+ useEffect(() => {
849
+ if (triggerDataUpdateResetting) {
850
+ clearTimeout(dataUpdateTimeoutId.current);
851
+ setDataUpdateTimeoutId(null);
852
+
853
+ clearTimeout(idleDataUpdateTimeoutId.current);
854
+ setIdleDataUpdateTimeoutId(null);
855
+ }
856
+ // eslint-disable-next-line react-hooks/exhaustive-deps
857
+ }, [triggerDataUpdateResetting]);
858
+
859
+ useEffect(() => {
860
+ if (!!updateSendInputTo) setUpdateSendInputTo(null);
861
+ if (!!updateReceiveInputTo) setUpdateReceiveInputTo(null);
862
+ // eslint-disable-next-line react-hooks/exhaustive-deps
863
+ }, [updateSendInputTo, updateReceiveInputTo]);
864
+
865
+ useEffect(() => {
866
+ if (swapRate != null && sendAssetAmount.current != null) {
867
+ if (isLastEditedReceiving.current) {
868
+ setUpdateSendInputTo(
869
+ AmountUtils.trim(BigNumber(receiveAssetAmount.current).div(swapRate), sendingAssetDecimalCount)
870
+ );
871
+ } else {
872
+ setUpdateReceiveInputTo(
873
+ AmountUtils.trim(BigNumber(sendAssetAmount.current).times(swapRate), receivingAssetDecimalCount)
874
+ );
875
+ }
876
+ }
877
+ // eslint-disable-next-line react-hooks/exhaustive-deps
878
+ }, [swapRate]);
879
+
880
+ useEffect(() => {
881
+ if (isLoading.current === false && swapAllButtonLoaderReSetter?.length) {
882
+ swapAllButtonLoaderReSetter[0]();
883
+ setSwapAllButtonLoaderReSetter([]);
884
+ }
885
+ // eslint-disable-next-line react-hooks/exhaustive-deps
886
+ }, [isLoading.current, swapAllButtonLoaderReSetter]);
887
+
888
+ const handleAmountChange = amount => {
889
+ requestDataRefresh(amount);
890
+ processMinMaxAmounts(amount);
891
+ setIsAmountZero(BigNumber("0").eq(amount));
892
+ setIsSwapCalculated(false);
893
+ };
894
+
895
+ useEffect(() => {
896
+ if (!isLastEditedReceiving.current) return;
897
+ handleAmountChange(receiveAssetAmount.current === "" ? "0" : receiveAssetAmount.current);
898
+ }, [receiveAssetAmount.current]);
899
+
900
+ useEffect(() => {
901
+ if (isLastEditedReceiving.current) return;
902
+ handleAmountChange(sendAssetAmount.current === "" ? "0" : sendAssetAmount.current);
903
+ }, [sendAssetAmount.current]);
904
+
905
+ const recipientAddressExtraIdName = getExtraIdNameByTicker(receivingAssetTicker);
906
+ const refundAddressExtraIdName = getExtraIdNameByTicker(sendingAssetTicker);
907
+
908
+ return (
909
+ <div className={s["swap-form"]}>
910
+ <TitleBox
911
+ linkButtonClick={
912
+ BigNumber(sendingAssetBalance?.assetAmount).eq(0)
913
+ ? null
914
+ : resetButtonLoader => handleSwapAllClick(resetButtonLoader)
915
+ }
916
+ linkText={
917
+ !formHasBalance
918
+ ? ""
919
+ : isSwapAll.current
920
+ ? translations.swapAllButtonTitles.cancel
921
+ : translations.swapAllButtonTitles.enable
922
+ }
923
+ linkButtonLoader={true}
924
+ isLinkButtonDisabled={
925
+ isLoading.current ||
926
+ sendingAssetTicker === receivingAssetTicker ||
927
+ BigNumber(sendingAssetBalance?.assetAmount).eq(0)
928
+ }
929
+ >
930
+ {displayRateSelector ? (
931
+ <div className={s["swap-form-rate-selector"]}>
932
+ <RateSelector
933
+ isFixed={isFixedRate.current ?? IS_FIXED_BY_DEFAULT}
934
+ setIsFixed={handleRateModeChanged}
935
+ translations={translations.rateSelector}
936
+ />
937
+ </div>
938
+ ) : (
939
+ ""
940
+ )}
941
+
942
+ <div className={s["swap-form-inputs"]}>
943
+ <AmountInput
944
+ ticker={sendingAssetTicker}
945
+ tickerPrintable={sendingAssetTickerPrintable}
946
+ assetDecimalPlaces={sendingAssetDecimalCount}
947
+ assetBalance={sendingAssetBalance}
948
+ assetIconSrc={sendingAssetIconSrc}
949
+ assetIconProtocolSrc={sendingAssetProtocolIconSrc}
950
+ fallbackAssetIconSrc={fallBackAssetIconSrc}
951
+ disabled={isSwapAll.current || sendingAssetTicker === null || receivingAssetTicker === null}
952
+ handleCoinAmountChange={handleSendAssetAmountChange}
953
+ handleChangeAssetClick={handleChangeSendingAssetClick}
954
+ handleBalanceValidationChange={isValid => setBalanceValid(!isValid)}
955
+ updateAssetInputTo={updateSendInputTo}
956
+ showBalance={formHasBalance}
957
+ showBalanceValidation={formHasBalance}
958
+ showChangeAssetButton
959
+ changeAssetButtonProtocol={sendingAssetProtocol}
960
+ upperFormPosition
961
+ errorEncountered={
962
+ !isLastEditedReceiving.current && (!minimalAmountValid || !maximumAmountValid)
963
+ }
964
+ ref={fromAssetSelectionButtonRef}
965
+ isLoading={isLastEditedReceiving.current ? isLoading.current : false}
966
+ cryptoAssetToFiatRate={sendingAssetToFiatRate}
967
+ fiatCurrencyCode={formHasFiat ? fiatCurrencyCode : null}
968
+ fiatCurrencyDecimals={fiatCurrencyDecimals}
969
+ balanceLoaderText={translations.input.balanceLoaderText}
970
+ fiatInputPlaceholderText={translations.input.fiatPlaceholder}
971
+ />
972
+ <div
973
+ className={
974
+ s["swap-form-inputs-separator"] +
975
+ " " +
976
+ (isLoading.current || sendingAssetTicker === null || receivingAssetTicker === null
977
+ ? s["disabled"]
978
+ : "")
979
+ }
980
+ >
981
+ <img
982
+ src={swapSeparatorIconSrc}
983
+ alt="swap icon"
984
+ draggable={false}
985
+ onClick={e => callHandlingErrors(handleChangeAssetsIconClick, e)}
986
+ loading="lazy"
987
+ />
988
+ </div>
989
+ <AmountInput
990
+ ticker={receivingAssetTicker}
991
+ tickerPrintable={receivingAssetTickerPrintable}
992
+ assetDecimalPlaces={receivingAssetDecimalCount}
993
+ assetBalance={receivingAssetBalance}
994
+ assetIconSrc={receivingAssetIconSrc}
995
+ assetIconProtocolSrc={receivingAssetProtocolIconSrc}
996
+ fallbackAssetIconSrc={fallBackAssetIconSrc}
997
+ disabled={isSwapAll.current || sendingAssetTicker === null || receivingAssetTicker === null}
998
+ locked={!formHasBalance && !isFixedRate.current}
999
+ handleCoinAmountChange={handleReceiveAssetAmountChange}
1000
+ handleChangeAssetClick={handleChangeReceivingAssetClick}
1001
+ updateAssetInputTo={updateReceiveInputTo}
1002
+ showChangeAssetButton
1003
+ changeAssetButtonProtocol={receivingAssetProtocol}
1004
+ showBalance={formHasBalance}
1005
+ lowerFormPosition
1006
+ errorEncountered={isLastEditedReceiving.current && (!minimalAmountValid || !maximumAmountValid)}
1007
+ estimateAmount={!isFixedRate.current}
1008
+ ref={toAssetSelectionButtonRef}
1009
+ isLoading={isLastEditedReceiving.current ? false : isLoading.current}
1010
+ cryptoAssetToFiatRate={receivingAssetToFiatRate}
1011
+ fiatCurrencyCode={formHasFiat ? fiatCurrencyCode : null}
1012
+ fiatCurrencyDecimals={fiatCurrencyDecimals}
1013
+ balanceLoaderText={translations.input.balanceLoaderText}
1014
+ fiatInputPlaceholderText={translations.input.fiatPlaceholder}
1015
+ />
1016
+ </div>
1017
+ <div className={s["swap-form-information-field"]}>
1018
+ <p>
1019
+ {!isPairSupported ? (
1020
+ translations.informationBlock.pairNotAvailable
1021
+ ) : transactionFee && minimalAmountValid ? (
1022
+ <>
1023
+ {translations.informationBlock.transactionFee}
1024
+ <span>
1025
+ {AmountUtils.crypto(transactionFee?.crypto, sendingAssetFeeCoinTickerPrintable)}
1026
+ </span>
1027
+ {transactionFee?.fiat != null && transactionFee?.fiat !== "" ? (
1028
+ <span className={"semi-transparent"}>
1029
+ {" ~ " + AmountUtils.fiat(transactionFee?.fiat, fiatCurrencyCode)}
1030
+ </span>
1031
+ ) : (
1032
+ ""
1033
+ )}
1034
+ </>
1035
+ ) : !isLoading.current && (isSwapCalculated || (!minimalAmount.current && swapRate)) ? (
1036
+ <>
1037
+ {translations.informationBlock.swapRate}
1038
+ <span>
1039
+ {AmountUtils.composeRateText(
1040
+ sendingAssetTickerPrintable,
1041
+ receivingAssetTickerPrintable,
1042
+ swapRate,
1043
+ receivingAssetDecimalCount,
1044
+ isFixedRate.current ?? IS_FIXED_BY_DEFAULT
1045
+ )}
1046
+ </span>
1047
+ </>
1048
+ ) : minimalAmount.current || maximumAmount.current ? (
1049
+ !maximumAmountValid && maximumAmount.current != null ? (
1050
+ <>
1051
+ {translations.informationBlock.maximumAmount}
1052
+ <span
1053
+ className={s["interactable"] + " " + s["red"]}
1054
+ onClick={
1055
+ isLoading.current
1056
+ ? () => {}
1057
+ : e => callHandlingErrors(handleMaximumAmountClick, e)
1058
+ }
1059
+ >
1060
+ {AmountUtils.crypto(
1061
+ maximumAmount.current?.crypto,
1062
+ isLastEditedReceiving.current
1063
+ ? receivingAssetTickerPrintable
1064
+ : sendingAssetTickerPrintable
1065
+ )}
1066
+ </span>
1067
+ {maximumAmount.current?.fiat != null && maximumAmount.current?.fiat !== "" ? (
1068
+ <span className={"semi-transparent"}>
1069
+ {" ~ " + AmountUtils.fiat(maximumAmount.current.fiat, fiatCurrencyCode)}
1070
+ </span>
1071
+ ) : (
1072
+ ""
1073
+ )}
1074
+ </>
1075
+ ) : !minimalAmount.current ? (
1076
+ ""
1077
+ ) : (
1078
+ <>
1079
+ {translations.informationBlock.minimumAmount}
1080
+ <span
1081
+ className={s["interactable"] + " " + (!minimalAmountValid ? s["red"] : "")}
1082
+ onClick={
1083
+ isLoading.current
1084
+ ? () => {}
1085
+ : e => callHandlingErrors(handleMinimalAmountClick, e)
1086
+ }
1087
+ >
1088
+ {AmountUtils.crypto(
1089
+ minimalAmount.current.crypto,
1090
+ isLastEditedReceiving.current
1091
+ ? receivingAssetTickerPrintable
1092
+ : sendingAssetTickerPrintable
1093
+ )}
1094
+ </span>
1095
+ {minimalAmount.current?.fiat != null && minimalAmount.current.fiat !== "" ? (
1096
+ <span className={"semi-transparent"}>
1097
+ {" ~ " + AmountUtils.fiat(minimalAmount.current.fiat, fiatCurrencyCode)}
1098
+ </span>
1099
+ ) : (
1100
+ ""
1101
+ )}
1102
+ </>
1103
+ )
1104
+ ) : isLoading.current ? (
1105
+ sendAssetAmount.current || isSwapAll.current ? (
1106
+ translations.informationBlock[
1107
+ formHasBalance ? "calculatingNetworkFee" : "calculatingSwapRates"
1108
+ ]
1109
+ ) : (
1110
+ translations.informationBlock.loadingMinimalAmount
1111
+ )
1112
+ ) : (
1113
+ ""
1114
+ )}
1115
+ </p>
1116
+ </div>
1117
+
1118
+ {isAddressFieldEnabled ? (
1119
+ <div className={s["swap-form-address-field"]}>
1120
+ <TitleBox title={translations.addressFields.addressTitle}>
1121
+ <Textarea
1122
+ type={"text"}
1123
+ onChange={e => setRecipientAddress(e.target.value)}
1124
+ value={recipientAddress.current}
1125
+ adaptiveHeight={true}
1126
+ errorEncountered={recipientAddress.current !== "" && !isRecipientAddressValid.current}
1127
+ />
1128
+ </TitleBox>
1129
+ {isHydrated && recipientAddressExtraIdName ? (
1130
+ <TitleBox
1131
+ title={translations.addressFields.receivingAddressExtraIdTitle}
1132
+ titleNoticeText={translations.addressFields.receivingAddressExtraIdNotice}
1133
+ titleNoticePosition={TOOLTIP_POSITIONS.TOP_LEFT}
1134
+ >
1135
+ <Textarea
1136
+ type={"text"}
1137
+ onChange={e => setRecipientAddressExtraId(e.target.value)}
1138
+ value={recipientAddressExtraId.current}
1139
+ adaptiveHeight={true}
1140
+ placeholder={translations.addressFields.extraIdPlaceholder}
1141
+ />
1142
+ </TitleBox>
1143
+ ) : null}
1144
+ {isHydrated && isRefundAddressRequired ? (
1145
+ <>
1146
+ <TitleBox title={translations.addressFields.refundAddressTitle}>
1147
+ <Textarea
1148
+ type={"text"}
1149
+ onChange={e => setRefundAddress(e.target.value)}
1150
+ value={refundAddress.current}
1151
+ adaptiveHeight={true}
1152
+ errorEncountered={refundAddress.current !== "" && !isRefundAddressValid.current}
1153
+ />
1154
+ </TitleBox>
1155
+ {refundAddressExtraIdName ? (
1156
+ <TitleBox
1157
+ title={translations.addressFields.refundAddressExtraIdTitle}
1158
+ titleNoticeText={translations.addressFields.refundAddressExtraIdNotice}
1159
+ titleNoticePosition={TOOLTIP_POSITIONS.TOP_LEFT}
1160
+ >
1161
+ <Textarea
1162
+ type={"text"}
1163
+ onChange={e => setRefundAddressExtraId(e.target.value)}
1164
+ value={refundAddressExtraId.current}
1165
+ adaptiveHeight={true}
1166
+ placeholder={translations.addressFields.extraIdPlaceholder}
1167
+ />
1168
+ </TitleBox>
1169
+ ) : null}
1170
+ </>
1171
+ ) : null}
1172
+ </div>
1173
+ ) : null}
1174
+
1175
+ {validationContent ? (
1176
+ <div className={s["swap-form-validation-text"]}>
1177
+ <Validation text={validationContent} />
1178
+ </div>
1179
+ ) : (
1180
+ ""
1181
+ )}
1182
+ <div className={s["swap-form-button-container"]}>
1183
+ {!termsOfUseUrl || !privacyPolicyUrl ? null : (
1184
+ <p className={s["swap-form-button-container-consent-text"]}>
1185
+ {translations.consents.consentText + " "}
1186
+ <a
1187
+ href={termsOfUseUrl}
1188
+ className={s["swap-form-button-container-consent-text-link"]}
1189
+ target="_blank"
1190
+ >
1191
+ {translations.consents.termsOfUse}
1192
+ </a>
1193
+ {" " + translations.consents.and + " "}
1194
+ <a
1195
+ href={privacyPolicyUrl}
1196
+ className={s["swap-form-button-container-consent-text-link"]}
1197
+ target="_blank"
1198
+ >
1199
+ {translations.consents.privacyPolicy}
1200
+ </a>
1201
+ .
1202
+ </p>
1203
+ )}
1204
+ <Button
1205
+ size="lg"
1206
+ mode="primary"
1207
+ content={translations.confirmButtonText}
1208
+ onClick={resetButtonLoader =>
1209
+ handleConfirmButtonClick(
1210
+ resetButtonLoader,
1211
+ setValidationContent,
1212
+ setBalanceValid,
1213
+ setMinimalAmountValid,
1214
+ setMaximumAmountValid,
1215
+ setIsPairSupported,
1216
+ setIsSameCoins,
1217
+ recipientAddress.current,
1218
+ recipientAddressExtraId.current,
1219
+ refundAddress.current,
1220
+ refundAddressExtraId.current,
1221
+ isLastEditedReceiving.current
1222
+ )
1223
+ }
1224
+ fullWidthOnMobiles
1225
+ isDisabled={!readyToSwap}
1226
+ to={formHasBalance ? "" : confirmButtonTo}
1227
+ loader
1228
+ handleError={callHandlingErrors}
1229
+ />
1230
+ </div>
1231
+ </TitleBox>
1232
+ </div>
1233
+ );
1234
+ };
1235
+
1236
+ SwapForm.propTypes = {
1237
+ sendingAssetTicker: PropTypes.string.isRequired,
1238
+ receivingAssetTicker: PropTypes.string.isRequired,
1239
+ sendingAssetDecimalCount: PropTypes.number,
1240
+ receivingAssetDecimalCount: PropTypes.number,
1241
+ sendingAssetTickerPrintable: PropTypes.string.isRequired,
1242
+ receivingAssetTickerPrintable: PropTypes.string.isRequired,
1243
+ sendingAssetProtocol: PropTypes.string,
1244
+ receivingAssetProtocol: PropTypes.string,
1245
+ sendingAssetIconSrc: PropTypes.string.isRequired,
1246
+ sendingAssetProtocolIconSrc: PropTypes.oneOfType([PropTypes.string, null]),
1247
+ receivingAssetIconSrc: PropTypes.string.isRequired,
1248
+ receivingAssetProtocolIconSrc: PropTypes.oneOfType([PropTypes.string, null]),
1249
+ fallBackAssetIconSrc: PropTypes.oneOfType([PropTypes.string, null]),
1250
+ sendingAssetFeeCoinTickerPrintable: PropTypes.string,
1251
+ sendingAssetBalance: PropTypes.string,
1252
+ receivingAssetBalance: PropTypes.string,
1253
+ handleChangeSendingAssetClick: PropTypes.func.isRequired,
1254
+ handleChangeReceivingAssetClick: PropTypes.func.isRequired,
1255
+ handleConfirmButtonClick: PropTypes.func,
1256
+ composeConfirmButtonTo: PropTypes.func,
1257
+ setSwapCreationEstimation: PropTypes.func,
1258
+ handleUnexpectedError: PropTypes.func,
1259
+ rotateAssets: PropTypes.func,
1260
+ preservedAmount: PropTypes.oneOfType([PropTypes.string, null]),
1261
+ handleSwapServiceError: PropTypes.func.isRequired,
1262
+ formHasBalance: PropTypes.bool,
1263
+ retrieveSwapDetails: PropTypes.func.isRequired,
1264
+ retrieveInitialSwapData: PropTypes.func.isRequired,
1265
+ triggerDataUpdateResetting: PropTypes.number,
1266
+ fromAssetSelectionButtonRef: PropTypes.any,
1267
+ toAssetSelectionButtonRef: PropTypes.any,
1268
+ sendingAssetToFiatRate: PropTypes.oneOfType([PropTypes.number, PropTypes.string, null]),
1269
+ receivingAssetToFiatRate: PropTypes.oneOfType([PropTypes.number, PropTypes.string, null]),
1270
+ fiatCurrencyCode: PropTypes.oneOfType([PropTypes.string, null]),
1271
+ fiatCurrencyDecimals: PropTypes.oneOfType([PropTypes.number, null]),
1272
+ formHasFiat: PropTypes.bool,
1273
+ termsOfUseUrl: PropTypes.oneOfType([PropTypes.string, null]),
1274
+ privacyPolicyUrl: PropTypes.oneOfType([PropTypes.string, null]),
1275
+ recipientAddressExtraIdName: PropTypes.string,
1276
+ refundAddressExtraIdName: PropTypes.string,
1277
+ translations: PropTypes.object,
1278
+ validateAddressByTicker: PropTypes.func,
1279
+ swapSeparatorIconSrc: PropTypes.string.isRequired,
1280
+ swapButtonAlwaysActive: PropTypes.bool,
1281
+ };
1282
+
1283
+ SwapForm.defaultProps = {
1284
+ sendingAssetDecimalCount: AmountUtils.significantDecimalCount,
1285
+ receivingAssetDecimalCount: AmountUtils.significantDecimalCount,
1286
+ sendingAssetProtocolIconSrc: null,
1287
+ receivingAssetProtocolIconSrc: null,
1288
+ fallBackAssetIconSrc: null,
1289
+ handleConfirmButtonClick: (
1290
+ resetButtonLoader,
1291
+ setValidationContent,
1292
+ setBalanceValid,
1293
+ setMinimalAmountValid,
1294
+ setMaximumAmountValid,
1295
+ setIsPairSupported,
1296
+ setIsSameCoins,
1297
+ recipientAddress,
1298
+ recipientAddressExtraId,
1299
+ refundAddress,
1300
+ refundAddressExtraId
1301
+ ) => {},
1302
+ composeConfirmButtonTo: (fromTicker, toTicker, fromAmount) => "",
1303
+ setSwapCreationEstimation: details => {},
1304
+ handleUnexpectedError: error => {},
1305
+ rotateAssets: (fromTicker, toTicker) => {},
1306
+ preservedAmount: null,
1307
+ handleSwapServiceError: (
1308
+ errorCode,
1309
+ setValidationContent,
1310
+ setBalanceValid,
1311
+ setMinimalAmountValid,
1312
+ setMaximumAmountValid,
1313
+ setIsPairSupported,
1314
+ setIsSameCoins
1315
+ ) => {},
1316
+ retrieveSwapDetails: async (sendingAssetTicker, receivingAssetTicker, amount, isSwapAll = false) => {},
1317
+ retrieveInitialSwapData: async (sendingAssetTicker, receivingAssetTicker) => {},
1318
+ triggerDataUpdateResetting: 0,
1319
+ fromAssetSelectionButtonRef: null,
1320
+ toAssetSelectionButtonRef: null,
1321
+ sendingAssetToFiatRate: null,
1322
+ receivingAssetToFiatRate: null,
1323
+ fiatCurrencyCode: null,
1324
+ fiatCurrencyDecimals: null,
1325
+ formHasFiat: true,
1326
+ termsOfUseUrl: null,
1327
+ privacyPolicyUrl: null,
1328
+ validateAddressByTicker: ticker => false,
1329
+ swapButtonAlwaysActive: false,
1330
+ };