@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.
- package/.gitlab-ci.yml +29 -0
- package/.husky/commit-msg +19 -0
- package/.husky/pre-push +1 -0
- package/CHANGELOG.md +0 -0
- package/README.md +27 -18
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/clover.xml +16372 -0
- package/coverage/coverage-final.json +154 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +1151 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +196 -0
- package/coverage/ui-kit/index.html +116 -0
- package/coverage/ui-kit/index.js.html +88 -0
- package/coverage/ui-kit/src/common-apis/adapters/axiosAdapter.js.html +190 -0
- package/coverage/ui-kit/src/common-apis/adapters/index.html +131 -0
- package/coverage/ui-kit/src/common-apis/adapters/qrUtils.js.html +139 -0
- package/coverage/ui-kit/src/common-apis/amountUtils.js.html +1162 -0
- package/coverage/ui-kit/src/common-apis/errorUtils.js.html +211 -0
- package/coverage/ui-kit/src/common-apis/external-apis/apiGroups.js.html +250 -0
- package/coverage/ui-kit/src/common-apis/external-apis/index.html +131 -0
- package/coverage/ui-kit/src/common-apis/external-apis/ipAddressProviders.js.html +352 -0
- package/coverage/ui-kit/src/common-apis/fiatCurrenciesService.js.html +544 -0
- package/coverage/ui-kit/src/common-apis/globalConstants.jsx.html +94 -0
- package/coverage/ui-kit/src/common-apis/index.html +161 -0
- package/coverage/ui-kit/src/common-apis/models/blockchain.js.html +115 -0
- package/coverage/ui-kit/src/common-apis/models/coin.js.html +544 -0
- package/coverage/ui-kit/src/common-apis/models/index.html +146 -0
- package/coverage/ui-kit/src/common-apis/models/protocol.js.html +100 -0
- package/coverage/ui-kit/src/common-apis/utils/cache.js.html +811 -0
- package/coverage/ui-kit/src/common-apis/utils/emailAPI.js.html +133 -0
- package/coverage/ui-kit/src/common-apis/utils/index.html +161 -0
- package/coverage/ui-kit/src/common-apis/utils/logging/index.html +131 -0
- package/coverage/ui-kit/src/common-apis/utils/logging/logger.js.html +208 -0
- package/coverage/ui-kit/src/common-apis/utils/logging/logsStorage.js.html +268 -0
- package/coverage/ui-kit/src/common-apis/utils/postponeExecution.js.html +118 -0
- package/coverage/ui-kit/src/common-apis/utils/safeStringify.js.html +235 -0
- package/coverage/ui-kit/src/index.html +116 -0
- package/coverage/ui-kit/src/index.js.html +337 -0
- package/coverage/ui-kit/src/robust-api-caller/cacheAndConcurrentRequestsResolver.js.html +1570 -0
- package/coverage/ui-kit/src/robust-api-caller/cachedRobustExternalApiCallerService.js.html +526 -0
- package/coverage/ui-kit/src/robust-api-caller/cancelProcessing.js.html +172 -0
- package/coverage/ui-kit/src/robust-api-caller/concurrentCalculationsMetadataHolder.js.html +310 -0
- package/coverage/ui-kit/src/robust-api-caller/externalApiProvider.js.html +553 -0
- package/coverage/ui-kit/src/robust-api-caller/externalServicesStatsCollector.js.html +319 -0
- package/coverage/ui-kit/src/robust-api-caller/index.html +206 -0
- package/coverage/ui-kit/src/robust-api-caller/robustExternalAPICallerService.js.html +997 -0
- package/coverage/ui-kit/src/swaps-lib/external-apis/index.html +146 -0
- package/coverage/ui-kit/src/swaps-lib/external-apis/letsExchangeSwapProvider.js.html +1513 -0
- package/coverage/ui-kit/src/swaps-lib/external-apis/swapProvider.js.html +1558 -0
- package/coverage/ui-kit/src/swaps-lib/external-apis/swapspaceSwapProvider.js.html +1735 -0
- package/coverage/ui-kit/src/swaps-lib/models/baseSwapCreationInfo.js.html +223 -0
- package/coverage/ui-kit/src/swaps-lib/models/existingSwap.js.html +304 -0
- package/coverage/ui-kit/src/swaps-lib/models/existingSwapWithFiatData.js.html +469 -0
- package/coverage/ui-kit/src/swaps-lib/models/index.html +146 -0
- package/coverage/ui-kit/src/swaps-lib/services/index.html +116 -0
- package/coverage/ui-kit/src/swaps-lib/services/publicSwapService.js.html +2098 -0
- package/coverage/ui-kit/src/swaps-lib/utils/index.html +116 -0
- package/coverage/ui-kit/src/swaps-lib/utils/swapUtils.js.html +670 -0
- package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/arrowIcon.jsx.html +124 -0
- package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/arrowTosca.jsx.html +127 -0
- package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/arrowWhite.jsx.html +127 -0
- package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/darkRectangle.jsx.html +106 -0
- package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/determinedError.jsx.html +439 -0
- package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/failedValidationIcon.jsx.html +202 -0
- package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/index.html +251 -0
- package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/infoIcon.jsx.html +133 -0
- package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/noticeQuestionIcon.jsx.html +247 -0
- package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/successfulValidationIcon.jsx.html +163 -0
- package/coverage/ui-kit/src/ui-kit/assets/wrappedImages/walletIcon.jsx.html +151 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/AssetIcon/AssetIcon.jsx.html +256 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/AssetIcon/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/AssetSelection/AssetSelection.jsx.html +289 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/AssetSelection/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/BackgroundTitle/BackgroundTitle.jsx.html +187 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/BackgroundTitle/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/InformationMessage/InformationMessage.jsx.html +238 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/InformationMessage/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/Input/Input.jsx.html +634 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/Input/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/LoadingDots/LoadingDots.jsx.html +196 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/LoadingDots/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/NoticeIcon/NoticeIcon.jsx.html +277 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/NoticeIcon/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/QrCode/QrCode.jsx.html +235 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/QrCode/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/RateSelector/RateSelector.jsx.html +175 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/RateSelector/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/SupportChat/SupportChat.jsx.html +217 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/SupportChat/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/Textarea/Textarea.jsx.html +529 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/Textarea/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/TitleBox/TitleBox.jsx.html +508 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/TitleBox/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/Tooltip/Tooltip.jsx.html +316 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/Tooltip/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/TwoLinesOfText/LinesOfText.jsx.html +313 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/TwoLinesOfText/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/Validation/Validation.jsx.html +208 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/Validation/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/Button/Button.jsx.html +712 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/Button/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/Close/Close.jsx.html +259 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/Close/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/LinkButton/LinkButton.jsx.html +421 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/LinkButton/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/RadioButtonWithText/RadioButtonWithText.jsx.html +415 -0
- package/coverage/ui-kit/src/ui-kit/components/atoms/buttons/RadioButtonWithText/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/molecules/AmountInput/AmountInput.jsx.html +1060 -0
- package/coverage/ui-kit/src/ui-kit/components/molecules/AmountInput/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/molecules/CoinPicker/CoinPicker.jsx.html +1618 -0
- package/coverage/ui-kit/src/ui-kit/components/molecules/CoinPicker/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/molecules/LineWithIconLink/LineWithIconLink.jsx.html +190 -0
- package/coverage/ui-kit/src/ui-kit/components/molecules/LineWithIconLink/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/molecules/TitledLineWithIconLink/TitledLineWithIconLink.jsx.html +181 -0
- package/coverage/ui-kit/src/ui-kit/components/molecules/TitledLineWithIconLink/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/organisms/CoinPickerDialogStep/CoinPickerDialogStep.jsx.html +283 -0
- package/coverage/ui-kit/src/ui-kit/components/organisms/CoinPickerDialogStep/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/Dialog.jsx.html +1567 -0
- package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/DialogButtons/DialogButtons.jsx.html +451 -0
- package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/DialogButtons/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/DialogStep/DialogStep.jsx.html +1699 -0
- package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/DialogStep/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/organisms/Dialog/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/organisms/SwapForm/SwapForm.jsx.html +4075 -0
- package/coverage/ui-kit/src/ui-kit/components/organisms/SwapForm/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/components/templates/DeterminedErrorDialogStep/DeterminedErrorDialogStep.jsx.html +316 -0
- package/coverage/ui-kit/src/ui-kit/components/templates/DeterminedErrorDialogStep/index.html +116 -0
- package/coverage/ui-kit/src/ui-kit/hooks/index.html +146 -0
- package/coverage/ui-kit/src/ui-kit/hooks/useCallHandlingErrors.js.html +151 -0
- package/coverage/ui-kit/src/ui-kit/hooks/useIsHydrated.js.html +121 -0
- package/coverage/ui-kit/src/ui-kit/hooks/useReferredState.js.html +157 -0
- package/coverage/ui-kit/src/ui-kit/utils/index.html +161 -0
- package/coverage/ui-kit/src/ui-kit/utils/inputValueProviders.js.html +235 -0
- package/coverage/ui-kit/src/ui-kit/utils/textUtils.js.html +139 -0
- package/coverage/ui-kit/src/ui-kit/utils/uiUtils.js.html +121 -0
- package/coverage/ui-kit/src/ui-kit/utils/urlQueryUtils.js.html +271 -0
- package/coverage/ui-kit/stories/atoms/BackgroundTitle.stories.jsx.html +202 -0
- package/coverage/ui-kit/stories/atoms/LinesOfText.stories.jsx.html +283 -0
- package/coverage/ui-kit/stories/atoms/LoadingDots.stories.jsx.html +226 -0
- package/coverage/ui-kit/stories/atoms/QrCode.stories.jsx.html +175 -0
- package/coverage/ui-kit/stories/atoms/RateSelector.stories.jsx.html +136 -0
- package/coverage/ui-kit/stories/atoms/Validation.stories.jsx.html +178 -0
- package/coverage/ui-kit/stories/atoms/buttons/Button.stories.jsx.html +883 -0
- package/coverage/ui-kit/stories/atoms/buttons/Close.stories.jsx.html +211 -0
- package/coverage/ui-kit/stories/atoms/buttons/LinkButton.stories.jsx.html +301 -0
- package/coverage/ui-kit/stories/atoms/buttons/index.html +146 -0
- package/coverage/ui-kit/stories/atoms/index.html +191 -0
- package/coverage/ui-kit/stories/molecules/LineWithIconLink.stories.jsx.html +154 -0
- package/coverage/ui-kit/stories/molecules/TitledLineWithIconLink.stories.jsx.html +160 -0
- package/coverage/ui-kit/stories/molecules/index.html +131 -0
- package/coverage/ui-kit/stories/organisms/Dialog/Dialog.stories.jsx.html +523 -0
- package/coverage/ui-kit/stories/organisms/Dialog/DialogButtons/DialogButtons.stories.jsx.html +328 -0
- package/coverage/ui-kit/stories/organisms/Dialog/DialogButtons/index.html +116 -0
- package/coverage/ui-kit/stories/organisms/Dialog/DialogStep/DialogStep.stories.jsx.html +337 -0
- package/coverage/ui-kit/stories/organisms/Dialog/DialogStep/index.html +116 -0
- package/coverage/ui-kit/stories/organisms/Dialog/index.html +116 -0
- package/coverage/ui-kit/stories/stubs/exampleContent.jsx.html +145 -0
- package/coverage/ui-kit/stories/stubs/index.html +116 -0
- package/coverage/ui-kit/stories/templates/DeterminedErrorDialogStep.stories.jsx.html +190 -0
- package/coverage/ui-kit/stories/templates/index.html +116 -0
- package/coverage/ui-kit/storybook-static/138.56b7edc4.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/312.6f62bbd9.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/341.57a15f57.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/595.2e40d981.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/607.3ea32459.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/609.949af3f6.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/693.1acf0184.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/797.c87cdf19.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/862.c15e3c9c.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/87.0a1bfeb1.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/893.e21210d8.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/996.10688684.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/atoms-BackgroundTitle-stories.1a5386a1.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/atoms-LinesOfText-stories.7043a48b.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/atoms-LoadingDots-stories.662d6a83.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/atoms-QrCode-stories.e10363b6.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/atoms-RateSelector-stories.da7b9f1f.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/atoms-Validation-stories.d561b311.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/atoms-buttons-Button-stories.d336c1a5.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/atoms-buttons-Close-stories.0a902a7c.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/atoms-buttons-LinkButton-stories.ca93ab6b.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/index.html +536 -0
- package/coverage/ui-kit/storybook-static/main.75ff1c31.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/molecules-LineWithIconLink-stories.2d2d5753.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/molecules-TitledLineWithIconLink-stories.1383fe3f.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/organisms-Dialog-Dialog-stories.4e6da717.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/organisms-Dialog-DialogButtons-DialogButtons-stories.b79c32a3.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/organisms-Dialog-DialogStep-DialogStep-stories.74896048.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/@storybook/addon-backgrounds/dist/index.html +116 -0
- package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/@storybook/addon-backgrounds/dist/preview.js.html +118 -0
- package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/@storybook/components/dist/formatter-SWP5E3XI.mjs.html +118 -0
- package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/@storybook/components/dist/index.html +116 -0
- package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/buffer/index.html +116 -0
- package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/buffer/index.js.html +118 -0
- package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/markdown-to-jsx/dist/index.html +116 -0
- package/coverage/ui-kit/storybook-static/rabbitio/ui-kit/node_modules/markdown-to-jsx/dist/index.modern.js.html +118 -0
- package/coverage/ui-kit/storybook-static/runtime~main.b108a22d.iframe.bundle.js.html +85 -0
- package/coverage/ui-kit/storybook-static/sb-addons/actions-9/index.html +116 -0
- package/coverage/ui-kit/storybook-static/sb-addons/actions-9/manager-bundle.js.html +94 -0
- package/coverage/ui-kit/storybook-static/sb-addons/essentials-backgrounds-2/index.html +116 -0
- package/coverage/ui-kit/storybook-static/sb-addons/essentials-backgrounds-2/manager-bundle.js.html +121 -0
- package/coverage/ui-kit/storybook-static/sb-addons/essentials-controls-1/index.html +116 -0
- package/coverage/ui-kit/storybook-static/sb-addons/essentials-controls-1/manager-bundle.js.html +274 -0
- package/coverage/ui-kit/storybook-static/sb-addons/essentials-measure-4/index.html +116 -0
- package/coverage/ui-kit/storybook-static/sb-addons/essentials-measure-4/manager-bundle.js.html +94 -0
- package/coverage/ui-kit/storybook-static/sb-addons/essentials-outline-5/index.html +116 -0
- package/coverage/ui-kit/storybook-static/sb-addons/essentials-outline-5/manager-bundle.js.html +94 -0
- package/coverage/ui-kit/storybook-static/sb-addons/essentials-toolbars-3/index.html +116 -0
- package/coverage/ui-kit/storybook-static/sb-addons/essentials-toolbars-3/manager-bundle.js.html +94 -0
- package/coverage/ui-kit/storybook-static/sb-addons/interactions-7/index.html +116 -0
- package/coverage/ui-kit/storybook-static/sb-addons/interactions-7/manager-bundle.js.html +121 -0
- package/coverage/ui-kit/storybook-static/sb-addons/links-0/index.html +116 -0
- package/coverage/ui-kit/storybook-static/sb-addons/links-0/manager-bundle.js.html +94 -0
- package/coverage/ui-kit/storybook-static/sb-addons/onboarding-6/index.html +116 -0
- package/coverage/ui-kit/storybook-static/sb-addons/onboarding-6/manager-bundle.js.html +1588 -0
- package/coverage/ui-kit/storybook-static/sb-addons/viewport-8/index.html +116 -0
- package/coverage/ui-kit/storybook-static/sb-addons/viewport-8/manager-bundle.js.html +94 -0
- package/coverage/ui-kit/storybook-static/sb-manager/WithTooltip-V3YHNWJZ-LVYLGZW2.js.html +88 -0
- package/coverage/ui-kit/storybook-static/sb-manager/chunk-2IXBUOFS.js.html +106 -0
- package/coverage/ui-kit/storybook-static/sb-manager/chunk-INSKDKQB.js.html +1129 -0
- package/coverage/ui-kit/storybook-static/sb-manager/chunk-NGTUFCUO.js.html +112 -0
- package/coverage/ui-kit/storybook-static/sb-manager/chunk-UUEAOBSN.js.html +1303 -0
- package/coverage/ui-kit/storybook-static/sb-manager/chunk-ZEU7PDD3.js.html +88 -0
- package/coverage/ui-kit/storybook-static/sb-manager/formatter-SWP5E3XI-7BGIK6BL.js.html +553 -0
- package/coverage/ui-kit/storybook-static/sb-manager/globals-module-info.js.html +88 -0
- package/coverage/ui-kit/storybook-static/sb-manager/globals.js.html +88 -0
- package/coverage/ui-kit/storybook-static/sb-manager/index.html +281 -0
- package/coverage/ui-kit/storybook-static/sb-manager/index.js.html +88 -0
- package/coverage/ui-kit/storybook-static/sb-manager/runtime.js.html +88 -0
- package/coverage/ui-kit/storybook-static/sb-manager/syntaxhighlighter-V7JZZA35-DXZCI2WR.js.html +88 -0
- package/coverage/ui-kit/storybook-static/sb-preview/globals.js.html +88 -0
- package/coverage/ui-kit/storybook-static/sb-preview/index.html +131 -0
- package/coverage/ui-kit/storybook-static/sb-preview/runtime.js.html +421 -0
- package/coverage/ui-kit/storybook-static/templates-DeterminedErrorDialogStep-stories.3cc14214.iframe.bundle.js.html +85 -0
- package/dist/global.css +197 -0
- package/dist/global.css.map +1 -0
- package/dist/index.cjs +10864 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +2212 -8491
- package/dist/index.css.map +1 -1
- package/dist/index.modern.js +8354 -22
- package/dist/index.modern.js.map +1 -1
- package/dist/index.module.js +10784 -23
- package/dist/index.module.js.map +1 -1
- package/dist/index.umd.js +10855 -25
- package/dist/index.umd.js.map +1 -1
- package/index.js +1 -1
- package/package.json +36 -9
- package/src/common-apis/adapters/axiosAdapter.js +35 -0
- package/src/common-apis/adapters/qrUtils.js +18 -0
- package/src/common-apis/amountUtils.js +359 -0
- package/src/common-apis/errorUtils.js +42 -0
- package/src/common-apis/external-apis/apiGroups.js +55 -0
- package/src/common-apis/external-apis/ipAddressProviders.js +89 -0
- package/src/common-apis/fiatCurrenciesService.js +153 -0
- package/src/common-apis/globalConstants.jsx +3 -0
- package/src/common-apis/models/blockchain.js +10 -0
- package/src/common-apis/models/coin.js +153 -0
- package/src/common-apis/models/protocol.js +5 -0
- package/src/common-apis/tests/amountUtils/composeRateText.test.js +152 -0
- package/src/common-apis/tests/integration/external-apis/ipAddressProviders/getClientIpAddress.test.js +12 -0
- package/src/common-apis/utils/cache.js +242 -0
- package/src/common-apis/utils/emailAPI.js +16 -0
- package/src/common-apis/utils/logging/logger.js +41 -0
- package/src/common-apis/utils/logging/logsStorage.js +61 -0
- package/src/common-apis/utils/postponeExecution.js +11 -0
- package/src/common-apis/utils/safeStringify.js +50 -0
- package/src/index.js +84 -0
- package/src/robust-api-caller/cacheAndConcurrentRequestsResolver.js +495 -0
- package/src/robust-api-caller/cachedRobustExternalApiCallerService.js +147 -0
- package/src/robust-api-caller/cancelProcessing.js +29 -0
- package/src/robust-api-caller/concurrentCalculationsMetadataHolder.js +75 -0
- package/src/robust-api-caller/externalApiProvider.js +156 -0
- package/src/robust-api-caller/externalServicesStatsCollector.js +78 -0
- package/src/robust-api-caller/robustExternalAPICallerService.js +304 -0
- package/src/robust-api-caller/tests/robustExternalAPICallerService/robustExternalAPICallerService/callExternalAPI/_performCallAttempt.test.js +533 -0
- package/src/robust-api-caller/tests/robustExternalAPICallerService/robustExternalAPICallerService/callExternalAPI/callExternalAPI.test.js +532 -0
- package/src/robust-api-caller/tests/robustExternalAPICallerService/robustExternalAPICallerService/constructor.test.js +19 -0
- package/src/swaps-lib/external-apis/letsExchangeSwapProvider.js +476 -0
- package/src/swaps-lib/external-apis/swapProvider.js +491 -0
- package/src/swaps-lib/external-apis/swapspaceSwapProvider.js +550 -0
- package/src/swaps-lib/models/baseSwapCreationInfo.js +46 -0
- package/src/swaps-lib/models/existingSwap.js +73 -0
- package/src/swaps-lib/models/existingSwapWithFiatData.js +128 -0
- package/src/swaps-lib/services/publicSwapService.js +671 -0
- package/src/swaps-lib/test/external-apis/swapProvider/getAllSupportedCurrencies.test.js +63 -0
- package/src/swaps-lib/test/external-apis/swapProvider/getDepositCurrencies.test.js +73 -0
- package/src/swaps-lib/test/external-apis/swapProvider/getWithdrawalCurrencies.test.js +102 -0
- package/src/swaps-lib/test/external-apis/swapProvider/removeProtocolNameFromCoinName.test.js +152 -0
- package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/_fetchSupportedCurrenciesIfNeeded.test.js +538 -0
- package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/createSwap.test.js +1249 -0
- package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/getSwapInfo.test.js +1700 -0
- package/src/swaps-lib/test/utils/swapUtils/safeHandleRequestsLimitExceeding.test.js +80 -0
- package/src/swaps-lib/utils/swapUtils.js +195 -0
- package/{styles → src/ui-kit/assets/styles}/_functions.scss +5 -0
- package/{styles → src/ui-kit/assets/styles}/_mixins.scss +2 -2
- package/{styles → src/ui-kit/assets/styles}/_placeholder.scss +3 -3
- package/{styles → src/ui-kit/assets/styles}/_variables.scss +17 -15
- package/src/ui-kit/assets/styles/fonts/NunitoSans-Bold.ttf +0 -0
- package/src/ui-kit/assets/styles/fonts/NunitoSans-ExtraBold.ttf +0 -0
- package/src/ui-kit/assets/styles/fonts/NunitoSans-Light.ttf +0 -0
- package/src/ui-kit/assets/styles/fonts/NunitoSans-Regular.ttf +0 -0
- package/src/ui-kit/assets/styles/fonts/NunitoSans-SemiBold.ttf +0 -0
- package/src/ui-kit/assets/styles/global.scss +165 -0
- package/src/ui-kit/assets/styles/index.scss +10 -0
- package/src/ui-kit/assets/wrappedImages/arrowIcon.jsx +13 -0
- package/src/ui-kit/assets/wrappedImages/arrowTosca.jsx +14 -0
- package/src/ui-kit/assets/wrappedImages/arrowWhite.jsx +14 -0
- package/src/ui-kit/assets/wrappedImages/darkRectangle.jsx +7 -0
- package/src/ui-kit/assets/wrappedImages/determinedError.jsx +118 -0
- package/src/ui-kit/assets/wrappedImages/failedValidationIcon.jsx +39 -0
- package/src/ui-kit/assets/wrappedImages/infoIcon.jsx +16 -0
- package/src/ui-kit/assets/wrappedImages/noticeQuestionIcon.jsx +54 -0
- package/src/ui-kit/assets/wrappedImages/successfulValidationIcon.jsx +26 -0
- package/src/ui-kit/assets/wrappedImages/walletIcon.jsx +22 -0
- package/src/ui-kit/components/atoms/AssetIcon/AssetIcon.jsx +57 -0
- package/{stories → src/ui-kit/components}/atoms/AssetIcon/asset-icon.module.scss +1 -1
- package/src/ui-kit/components/atoms/AssetSelection/AssetSelection.jsx +68 -0
- package/src/ui-kit/components/atoms/AssetSelection/asset-selection.module.scss +56 -0
- package/src/ui-kit/components/atoms/BackgroundTitle/BackgroundTitle.jsx +34 -0
- package/src/ui-kit/components/atoms/BackgroundTitle/background-title.module.scss +52 -0
- package/src/ui-kit/components/atoms/InformationMessage/InformationMessage.jsx +51 -0
- package/src/ui-kit/components/atoms/InformationMessage/information-message.module.scss +38 -0
- package/src/ui-kit/components/atoms/Input/Input.jsx +183 -0
- package/src/ui-kit/components/atoms/Input/input.module.scss +107 -0
- package/{stories → src/ui-kit/components}/atoms/LoadingDots/LoadingDots.jsx +8 -28
- package/{stories → src/ui-kit/components}/atoms/LoadingDots/LoadingDots.module.scss +3 -2
- package/src/ui-kit/components/atoms/NoticeIcon/NoticeIcon.jsx +64 -0
- package/src/ui-kit/components/atoms/NoticeIcon/notice-icon.module.scss +14 -0
- package/src/ui-kit/components/atoms/QrCode/QrCode.jsx +50 -0
- package/src/ui-kit/components/atoms/QrCode/qr-code.module.scss +15 -0
- package/src/ui-kit/components/atoms/RateSelector/RateSelector.jsx +30 -0
- package/src/ui-kit/components/atoms/RateSelector/rate-selector.module.scss +47 -0
- package/{stories → src/ui-kit/components}/atoms/SupportChat/SupportChat.jsx +5 -1
- package/src/ui-kit/components/atoms/Textarea/Textarea.jsx +148 -0
- package/src/ui-kit/components/atoms/Textarea/textarea.module.scss +71 -0
- package/src/ui-kit/components/atoms/TitleBox/TitleBox.jsx +141 -0
- package/src/ui-kit/components/atoms/TitleBox/title-box.module.scss +32 -0
- package/src/ui-kit/components/atoms/Tooltip/Tooltip.jsx +77 -0
- package/src/ui-kit/components/atoms/Tooltip/tooltip.module.scss +237 -0
- package/src/ui-kit/components/atoms/TwoLinesOfText/LinesOfText.jsx +76 -0
- package/src/ui-kit/components/atoms/TwoLinesOfText/lines-of-text.module.scss +65 -0
- package/src/ui-kit/components/atoms/Validation/Validation.jsx +41 -0
- package/src/ui-kit/components/atoms/Validation/validation.module.scss +15 -0
- package/{stories → src/ui-kit/components}/atoms/buttons/Button/Button.jsx +24 -50
- package/{stories → src/ui-kit/components}/atoms/buttons/Button/Button.module.scss +1 -1
- package/src/ui-kit/components/atoms/buttons/Close/Close.jsx +58 -0
- package/src/ui-kit/components/atoms/buttons/Close/close.module.scss +75 -0
- package/src/ui-kit/components/atoms/buttons/LinkButton/LinkButton.jsx +112 -0
- package/src/ui-kit/components/atoms/buttons/LinkButton/link-button.module.scss +49 -0
- package/src/ui-kit/components/atoms/buttons/RadioButtonWithText/RadioButtonWithText.jsx +110 -0
- package/src/ui-kit/components/atoms/buttons/RadioButtonWithText/radio-button-with-text.module.scss +86 -0
- package/src/ui-kit/components/molecules/AmountInput/AmountInput.jsx +325 -0
- package/src/ui-kit/components/molecules/AmountInput/amount-input.module.scss +199 -0
- package/src/ui-kit/components/molecules/CoinPicker/CoinPicker.jsx +511 -0
- package/src/ui-kit/components/molecules/CoinPicker/coin-picker.module.scss +207 -0
- package/src/ui-kit/components/molecules/LineWithIconLink/LineWithIconLink.jsx +35 -0
- package/src/ui-kit/components/molecules/LineWithIconLink/line-with-icon-link.module.scss +25 -0
- package/src/ui-kit/components/molecules/TitledLineWithIconLink/TitledLineWithIconLink.jsx +32 -0
- package/src/ui-kit/components/organisms/CoinPickerDialogStep/CoinPickerDialogStep.jsx +66 -0
- package/src/ui-kit/components/organisms/Dialog/Dialog.jsx +494 -0
- package/src/ui-kit/components/organisms/Dialog/DialogButtons/DialogButtons.jsx +122 -0
- package/src/ui-kit/components/organisms/Dialog/DialogButtons/dialog-buttons.module.scss +25 -0
- package/src/ui-kit/components/organisms/Dialog/DialogStep/DialogStep.jsx +538 -0
- package/src/ui-kit/components/organisms/Dialog/DialogStep/dialog-step.module.scss +381 -0
- package/src/ui-kit/components/organisms/Dialog/dialog.module.scss +226 -0
- package/src/ui-kit/components/organisms/SwapForm/SwapForm.jsx +1330 -0
- package/src/ui-kit/components/organisms/SwapForm/swap-form.module.scss +134 -0
- package/src/ui-kit/components/templates/DeterminedErrorDialogStep/DeterminedErrorDialogStep.jsx +77 -0
- package/src/ui-kit/hooks/useCallHandlingErrors.js +22 -0
- package/src/ui-kit/hooks/useIsHydrated.js +12 -0
- package/src/ui-kit/hooks/useReferredState.js +24 -0
- package/src/ui-kit/tests/utils/inputValueProviders/provideFormatOfFloatValueByInputString.test.js +132 -0
- package/src/ui-kit/tests/utils/urlQueryUtils/getQueryParameterValues.test.js +65 -0
- package/src/ui-kit/tests/utils/urlQueryUtils/saveQueryParameterAndValues.test.js +104 -0
- package/src/ui-kit/utils/inputValueProviders.js +50 -0
- package/src/ui-kit/utils/textUtils.js +18 -0
- package/src/ui-kit/utils/uiUtils.js +12 -0
- package/src/ui-kit/utils/urlQueryUtils.js +62 -0
- package/stories/stubs/exampleContent.jsx +20 -0
- package/stories/atoms/AssetIcon/AssetIcon.jsx +0 -55
- package/stories/index.js +0 -4
- package/styles/_global-classes.scss +0 -433
- package/styles/fonts/NunitoSans-Bold.ttf +0 -0
- package/styles/fonts/NunitoSans-ExtraBold.ttf +0 -0
- package/styles/fonts/NunitoSans-Light.ttf +0 -0
- package/styles/fonts/NunitoSans-Regular.ttf +0 -0
- package/styles/fonts/NunitoSans-SemiBold.ttf +0 -0
- package/styles/global-styles-index.scss +0 -74
- package/styles/index.scss +0 -33
- /package/{styles → src/ui-kit/assets/styles}/colors/_light-colors.scss +0 -0
- /package/{styles → src/ui-kit/assets/styles}/colors/_solid-colors.scss +0 -0
- /package/{styles → src/ui-kit/assets/styles}/size/_margin-size.scss +0 -0
- /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
|
+
};
|