@aurora-is-near/intents-swap-widget 3.18.1 → 3.18.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/dist/components/Accordion.js +34 -35
  2. package/dist/components/Accordion.js.map +1 -1
  3. package/dist/components/Banner.js +33 -19
  4. package/dist/components/Banner.js.map +1 -1
  5. package/dist/components/BlockingError.js +11 -16
  6. package/dist/components/BlockingError.js.map +1 -1
  7. package/dist/components/Button.d.ts +10 -2
  8. package/dist/components/Button.js +53 -43
  9. package/dist/components/Button.js.map +1 -1
  10. package/dist/components/CloseButton.js +6 -6
  11. package/dist/components/CloseButton.js.map +1 -1
  12. package/dist/components/CopyButton.d.ts +5 -2
  13. package/dist/components/CopyButton.js +11 -7
  14. package/dist/components/CopyButton.js.map +1 -1
  15. package/dist/components/DirectionSwitcher.js +12 -11
  16. package/dist/components/DirectionSwitcher.js.map +1 -1
  17. package/dist/components/Input.d.ts +5 -3
  18. package/dist/components/Input.js +16 -16
  19. package/dist/components/Input.js.map +1 -1
  20. package/dist/components/Notes.js +1 -1
  21. package/dist/components/Notes.js.map +1 -1
  22. package/dist/components/StatusWidget.js +8 -21
  23. package/dist/components/StatusWidget.js.map +1 -1
  24. package/dist/{config-DJObWR7Z.js → config-BMvXuF1-.js} +692 -673
  25. package/dist/config-BMvXuF1-.js.map +1 -0
  26. package/dist/config.js +21 -6
  27. package/dist/config.js.map +1 -1
  28. package/dist/errors.js +1 -1
  29. package/dist/ext/alchemy/index.js +1 -1
  30. package/dist/ext/index.js +1 -1
  31. package/dist/features/BalanceRpcLoader/TokenBalanceLoader.js +1 -1
  32. package/dist/features/BalanceRpcLoader/index.js +1 -1
  33. package/dist/features/BalanceRpcLoader/useTokenBalanceRpc.js +1 -1
  34. package/dist/features/ChainsDropdown/AllNetworksIcon.js +3 -3
  35. package/dist/features/ChainsDropdown/AllNetworksIcon.js.map +1 -1
  36. package/dist/features/ChainsDropdown/ChainItem.js +7 -7
  37. package/dist/features/ChainsDropdown/ChainItem.js.map +1 -1
  38. package/dist/features/ChainsDropdown/index.js +45 -33
  39. package/dist/features/ChainsDropdown/index.js.map +1 -1
  40. package/dist/features/DepositMethodSwitcher.js +18 -17
  41. package/dist/features/DepositMethodSwitcher.js.map +1 -1
  42. package/dist/features/ErrorBoundary.js +1 -1
  43. package/dist/features/ExternalDeposit.js +22 -15
  44. package/dist/features/ExternalDeposit.js.map +1 -1
  45. package/dist/features/SendAddress/index.js +15 -14
  46. package/dist/features/SendAddress/index.js.map +1 -1
  47. package/dist/features/SendAddress/useNotification.js +1 -1
  48. package/dist/features/SubmitButton/index.js +1 -1
  49. package/dist/features/SuccessScreen/CopyableValue.d.ts +5 -0
  50. package/dist/features/SuccessScreen/CopyableValue.js +11 -0
  51. package/dist/features/SuccessScreen/CopyableValue.js.map +1 -0
  52. package/dist/features/SuccessScreen/TokenRow.d.ts +8 -0
  53. package/dist/features/SuccessScreen/TokenRow.js +20 -0
  54. package/dist/features/SuccessScreen/TokenRow.js.map +1 -0
  55. package/dist/features/SuccessScreen/index.d.ts +5 -4
  56. package/dist/features/SuccessScreen/index.js +151 -49
  57. package/dist/features/SuccessScreen/index.js.map +1 -1
  58. package/dist/features/SuccessScreen/useSummaryItemsCount.d.ts +1 -0
  59. package/dist/features/SuccessScreen/useSummaryItemsCount.js +14 -0
  60. package/dist/features/SuccessScreen/useSummaryItemsCount.js.map +1 -0
  61. package/dist/features/SwapDirectionSwitcher.js +1 -1
  62. package/dist/features/SwapQuote/SwapQuote.js +1 -1
  63. package/dist/features/SwapQuote/index.js +1 -1
  64. package/dist/features/TokenInput/TokenInput.js +1 -1
  65. package/dist/features/TokenInput/TokenInputEmpty.js +1 -1
  66. package/dist/features/TokenInput/TokenInputSource.js +1 -1
  67. package/dist/features/TokenInput/TokenInputTarget.js +2 -2
  68. package/dist/features/TokenInput/WalletBalance.js +1 -1
  69. package/dist/features/TokenInput/hooks/index.js +1 -1
  70. package/dist/features/TokenInput/hooks/useTokenInputBalance.js +1 -1
  71. package/dist/features/TokenInput/index.js +1 -1
  72. package/dist/features/TokensList/TokenItem.js +2 -2
  73. package/dist/features/TokensList/TokensList.js +1 -1
  74. package/dist/features/TokensList/index.js +1 -1
  75. package/dist/features/TokensModal.js +11 -11
  76. package/dist/features/TokensModal.js.map +1 -1
  77. package/dist/features/WalletCompatibilityCheck/WalletCompatibilityModal.js +19 -6
  78. package/dist/features/WalletCompatibilityCheck/WalletCompatibilityModal.js.map +1 -1
  79. package/dist/features/WalletCompatibilityCheck/index.js +1 -1
  80. package/dist/features/index.js +1 -1
  81. package/dist/hooks/index.js +1 -1
  82. package/dist/hooks/useAllTokens.js +1 -1
  83. package/dist/hooks/useChains.js +1 -1
  84. package/dist/hooks/useCompatibilityCheck.js +1 -1
  85. package/dist/hooks/useDefaultToken.js +1 -1
  86. package/dist/hooks/useExternalDepositStatus/index.js +1 -1
  87. package/dist/hooks/useExternalDepositStatus/usePoaExternalDepositStatus.js +1 -1
  88. package/dist/hooks/useIntentsBalance.js +1 -1
  89. package/dist/hooks/useIsCompatibilityCheckRequired.js +1 -1
  90. package/dist/hooks/useMakeDepositAddress.js +1 -1
  91. package/dist/hooks/useMakeIntentsTransfer.js +1 -1
  92. package/dist/hooks/useMakeNEARFtTransferCall.js +1 -1
  93. package/dist/hooks/useMakeQuote.js +1 -1
  94. package/dist/hooks/useMakeQuoteTransfer.js +1 -1
  95. package/dist/hooks/useMakeTransfer.js +1 -1
  96. package/dist/hooks/useMergedBalance.js +1 -1
  97. package/dist/hooks/useSwitchChain.js +1 -1
  98. package/dist/hooks/useTheme.js +1 -1
  99. package/dist/hooks/useTokenInputPair.js +1 -1
  100. package/dist/hooks/useTokens.js +1 -1
  101. package/dist/hooks/useTokensFiltered.js +1 -1
  102. package/dist/hooks/useTokensIntentsUnique.js +1 -1
  103. package/dist/index.js +1 -1
  104. package/dist/machine/effects/index.js +1 -1
  105. package/dist/machine/effects/useAlchemyBalanceEffect.js +1 -1
  106. package/dist/machine/effects/useBalancesUpdateEffect.js +1 -1
  107. package/dist/machine/effects/useMakeQuoteEffect.js +1 -1
  108. package/dist/machine/effects/useSelectedTokensEffect.js +1 -1
  109. package/dist/machine/effects/useSetTokenBalanceEffect.js +1 -1
  110. package/dist/machine/effects/useSetTokenIntentsTargetEffect.js +1 -1
  111. package/dist/machine/effects/useWalletConnEffect.js +1 -1
  112. package/dist/machine/events/index.js +1 -1
  113. package/dist/machine/events/reset.d.ts +1 -0
  114. package/dist/machine/events/reset.js +2 -2
  115. package/dist/machine/events/reset.js.map +1 -1
  116. package/dist/machine/events/tokenSelect.js +1 -1
  117. package/dist/machine/events/validateInputAndMoveTo.js +1 -1
  118. package/dist/machine/events/validateInputs.js +1 -1
  119. package/dist/machine/index.js +1 -1
  120. package/dist/machine/snap.js +1 -1
  121. package/dist/machine/subscriptions/checkers/isSendAddressAsConnected.js +1 -1
  122. package/dist/machine/subscriptions/index.js +1 -1
  123. package/dist/styles.css +1 -1
  124. package/dist/tailwind.css +9 -0
  125. package/dist/theme/ThemeProvider.js +1 -1
  126. package/dist/types/localisation.d.ts +1 -1
  127. package/dist/utils/intents/signers/near.js +1 -1
  128. package/dist/utils/intents/signers/privy.js +1 -1
  129. package/dist/utils/near/getNearNep141StorageBalance.js +1 -1
  130. package/dist/widgets/WidgetDeposit/WidgetDepositContent.js +79 -71
  131. package/dist/widgets/WidgetDeposit/WidgetDepositContent.js.map +1 -1
  132. package/dist/widgets/WidgetDeposit/WidgetDepositSkeleton.js +1 -1
  133. package/dist/widgets/WidgetSwap/WidgetSwapContent.js +94 -81
  134. package/dist/widgets/WidgetSwap/WidgetSwapContent.js.map +1 -1
  135. package/dist/widgets/WidgetSwap/WidgetSwapSkeleton.js +1 -1
  136. package/dist/widgets/WidgetWithdraw/WidgetWithdrawContent.js +79 -67
  137. package/dist/widgets/WidgetWithdraw/WidgetWithdrawContent.js.map +1 -1
  138. package/dist/widgets/WidgetWithdraw/WidgetWithdrawSkeleton.js +1 -1
  139. package/package.json +1 -2
  140. package/src/components/Accordion.tsx +8 -9
  141. package/src/components/Banner.tsx +17 -8
  142. package/src/components/BlockingError.tsx +4 -6
  143. package/src/components/Button.tsx +26 -7
  144. package/src/components/CloseButton.tsx +2 -2
  145. package/src/components/CopyButton.tsx +14 -4
  146. package/src/components/DirectionSwitcher.tsx +4 -4
  147. package/src/components/Input.tsx +5 -4
  148. package/src/components/Notes.tsx +1 -1
  149. package/src/components/StatusWidget.tsx +4 -11
  150. package/src/features/ChainsDropdown/AllNetworksIcon.tsx +2 -2
  151. package/src/features/ChainsDropdown/ChainItem.tsx +2 -2
  152. package/src/features/ChainsDropdown/index.tsx +9 -3
  153. package/src/features/DepositMethodSwitcher.tsx +4 -3
  154. package/src/features/ExternalDeposit.tsx +2 -2
  155. package/src/features/SendAddress/index.tsx +3 -2
  156. package/src/features/SuccessScreen/CopyableValue.tsx +13 -0
  157. package/src/features/SuccessScreen/TokenRow.tsx +26 -0
  158. package/src/features/SuccessScreen/index.tsx +161 -55
  159. package/src/features/SuccessScreen/useSummaryItemsCount.ts +33 -0
  160. package/src/features/TokensModal.tsx +2 -2
  161. package/src/features/WalletCompatibilityCheck/WalletCompatibilityModal.tsx +8 -9
  162. package/src/machine/events/reset.ts +6 -3
  163. package/src/tailwind.css +9 -0
  164. package/src/types/localisation.ts +10 -3
  165. package/src/widgets/WidgetDeposit/WidgetDepositContent.tsx +6 -4
  166. package/src/widgets/WidgetSwap/WidgetSwapContent.tsx +7 -4
  167. package/src/widgets/WidgetWithdraw/WidgetWithdrawContent.tsx +7 -4
  168. package/dist/config-DJObWR7Z.js.map +0 -1
  169. package/dist/features/SuccessScreen/CheckIcon.d.ts +0 -1
  170. package/dist/features/SuccessScreen/CheckIcon.js +0 -7
  171. package/dist/features/SuccessScreen/CheckIcon.js.map +0 -1
  172. package/dist/features/SuccessScreen/ExternalAction.d.ts +0 -5
  173. package/dist/features/SuccessScreen/ExternalAction.js +0 -16
  174. package/dist/features/SuccessScreen/ExternalAction.js.map +0 -1
  175. package/dist/features/SuccessScreen/SummaryItem.d.ts +0 -8
  176. package/dist/features/SuccessScreen/SummaryItem.js +0 -21
  177. package/dist/features/SuccessScreen/SummaryItem.js.map +0 -1
  178. package/src/features/SuccessScreen/CheckIcon.tsx +0 -7
  179. package/src/features/SuccessScreen/ExternalAction.tsx +0 -15
  180. package/src/features/SuccessScreen/SummaryItem.tsx +0 -28
@@ -7,19 +7,20 @@ import {
7
7
  useState,
8
8
  } from 'react';
9
9
  import { Input as UIInput } from '@headlessui/react';
10
+ import { CloseW700 as Close } from '@material-symbols-svg/react-rounded/icons/close';
11
+ import type { MaterialSymbolsComponent } from '@material-symbols-svg/react';
10
12
  import type { InputProps } from '@headlessui/react';
11
13
  import type { PropsWithChildren } from 'react';
12
- import type { LucideIcon } from 'lucide-react';
13
- import * as Icons from 'lucide-react';
14
14
 
15
15
  import { cn } from '@/utils/cn';
16
16
 
17
17
  type State = 'default' | 'disabled' | 'error' | 'fixed';
18
18
 
19
19
  export type Props = Omit<InputProps, 'size'> & {
20
- icon?: LucideIcon;
20
+ icon?: MaterialSymbolsComponent;
21
21
  defaultValue?: string;
22
22
  focusOnMount?: boolean;
23
+ fontSize?: 'sm' | 'md';
23
24
  state?: State;
24
25
  };
25
26
 
@@ -121,7 +122,7 @@ export const Input = forwardRef<HTMLInputElement, PropsWithChildren<Props>>(
121
122
  },
122
123
  )}
123
124
  onClick={handleClear}>
124
- <Icons.X className="h-sw-xl w-sw-xl" />
125
+ <Close className="h-sw-xl w-sw-xl" />
125
126
  </button>
126
127
  ) : null}
127
128
  </div>
@@ -28,7 +28,7 @@ const NoteItem = ({
28
28
 
29
29
  const NotesList = ({ children, className }: Props) => {
30
30
  return (
31
- <ul className={cn('gap-sw-2xl flex flex-col', className)}>{children}</ul>
31
+ <ul className={cn('gap-sw-xl flex flex-col', className)}>{children}</ul>
32
32
  );
33
33
  };
34
34
 
@@ -1,23 +1,16 @@
1
- import * as Icons from 'lucide-react';
1
+ import { CloseW700 as Close } from '@material-symbols-svg/react-rounded/icons/close';
2
+ import { CheckCircleFillW700 as CheckCircleFill } from '@material-symbols-svg/react-rounded/icons/check-circle';
2
3
 
3
4
  const Error = ({ message }: { message: string }) => (
4
5
  <div className="flex flex-col gap-sw-lg py-sw-6xl items-center justify-center">
5
- <Icons.CircleX
6
- size={36}
7
- strokeWidth={1.5}
8
- className="text-sw-status-error"
9
- />
6
+ <Close size={36} className="text-sw-status-error" />
10
7
  <span className="text-sw-label-sm text-sw-status-error">{message}</span>
11
8
  </div>
12
9
  );
13
10
 
14
11
  const Success = () => (
15
12
  <div className="flex flex-col gap-sw-lg py-sw-6xl items-center justify-center">
16
- <Icons.CheckCircle2
17
- size={36}
18
- strokeWidth={1.5}
19
- className="text-sw-status-success"
20
- />
13
+ <CheckCircleFill size={36} className="text-sw-status-success" />
21
14
  <span className="text-sw-label-sm text-sw-status-success text-center">
22
15
  Transaction detected
23
16
  </span>
@@ -1,7 +1,7 @@
1
- import * as Icons from 'lucide-react';
1
+ import { TargetW700 as Target } from '@material-symbols-svg/react-rounded/icons/target';
2
2
 
3
3
  export const AllNetworksIcon = () => (
4
4
  <div className="bg-sw-accent-500 flex h-[28px] w-[28px] items-center justify-center">
5
- <Icons.Target size={16} className="text-sw-accent-950" />
5
+ <Target size={16} className="text-sw-accent-950" />
6
6
  </div>
7
7
  );
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import * as Icons from 'lucide-react';
2
+ import { CheckW700 as Check } from '@material-symbols-svg/react-rounded/icons/check';
3
3
 
4
4
  import { cn } from '@/utils/cn';
5
5
  import { Icon } from '@/components/Icon';
@@ -34,7 +34,7 @@ export const ChainItem = React.forwardRef<HTMLButtonElement, Props>(
34
34
  )}>
35
35
  <Icon radius={10} label={label} icon={icon} />
36
36
  <span className="text-sw-label-md mr-auto">{label}</span>
37
- {isSelected && <Icons.Check size={16} />}
37
+ {isSelected && <Check size={16} />}
38
38
  </button>
39
39
  ),
40
40
  );
@@ -1,7 +1,7 @@
1
1
  import { Fragment, useMemo } from 'react';
2
2
  import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/react';
3
+ import { ChevronLeftW700 as ChevronLeft } from '@material-symbols-svg/react-rounded/icons/chevron-left';
3
4
  import { AnimatePresence, motion } from 'framer-motion';
4
- import * as Icons from 'lucide-react';
5
5
 
6
6
  import { ChainItem } from './ChainItem';
7
7
  import { AllNetworksIcon } from './AllNetworksIcon';
@@ -79,9 +79,15 @@ export const ChainsDropdown = ({
79
79
  })()}
80
80
 
81
81
  {isOpen ? (
82
- <Icons.ChevronUp size={18} className="text-sw-gray-50" />
82
+ <ChevronLeft
83
+ size={18}
84
+ className="text-sw-gray-50 rotate-90"
85
+ />
83
86
  ) : (
84
- <Icons.ChevronDown size={18} className="text-sw-gray-50" />
87
+ <ChevronLeft
88
+ size={18}
89
+ className="text-sw-gray-50 -rotate-90"
90
+ />
85
91
  )}
86
92
  </div>
87
93
  )}
@@ -1,4 +1,5 @@
1
- import * as Icons from 'lucide-react';
1
+ import { QrCodeW700 as QrCode } from '@material-symbols-svg/react-rounded/icons/qr-code';
2
+ import { WalletW700 as Wallet } from '@material-symbols-svg/react-rounded/icons/wallet';
2
3
 
3
4
  import { cn } from '@/utils/cn';
4
5
  import { Card } from '@/components/Card';
@@ -26,7 +27,7 @@ export const DepositMethodSwitcher = ({ children, className }: Props) => {
26
27
  <div className="flex gap-sw-lg">
27
28
  <Button
28
29
  size="md"
29
- icon={Icons.Wallet2}
30
+ icon={Wallet}
30
31
  state={ctx.isDepositFromExternalWallet ? 'default' : 'active'}
31
32
  variant={ctx.isDepositFromExternalWallet ? 'outlined' : 'primary'}
32
33
  onClick={() => onToggle(false)}>
@@ -34,7 +35,7 @@ export const DepositMethodSwitcher = ({ children, className }: Props) => {
34
35
  </Button>
35
36
  <Button
36
37
  size="md"
37
- icon={Icons.QrCode}
38
+ icon={QrCode}
38
39
  state={ctx.isDepositFromExternalWallet ? 'active' : 'default'}
39
40
  variant={ctx.isDepositFromExternalWallet ? 'primary' : 'outlined'}
40
41
  onClick={() => onToggle(true)}>
@@ -1,7 +1,7 @@
1
1
  import { useEffect } from 'react';
2
2
  import { QRCodeSVG } from 'qrcode.react';
3
3
  import { GetExecutionStatusResponse } from '@defuse-protocol/one-click-sdk-typescript';
4
- import * as Icons from 'lucide-react';
4
+ import { ProgressActivityW700 as ProgressActivity } from '@material-symbols-svg/react-rounded/icons/progress-activity';
5
5
 
6
6
  import { notReachable } from '@/utils';
7
7
  import { CHAIN_IDS_MAP } from '@/constants/chains';
@@ -50,7 +50,7 @@ const Skeleton = () => {
50
50
  <div className="flex flex-col gap-sw-2xl items-center">
51
51
  <div className="bg-sw-gray-800 h-[180px] w-[180px] animate-pulse rounded-sw-md" />
52
52
  <div className="bg-sw-gray-800 h-[44px] w-full animate-pulse rounded-sw-md flex items-center justify-center gap-sw-sm">
53
- <Icons.Loader className="animate-spin text-sw-gray-100 h-sw-lg w-sw-lg" />
53
+ <ProgressActivity className="animate-spin text-sw-gray-100 h-sw-lg w-sw-lg" />
54
54
  <span className="text-sw-gray-100 text-sw-label-sm">
55
55
  {!isNotEmptyAmount(ctx.sourceTokenAmount)
56
56
  ? t('deposit.external.loading.waiting', 'Waiting for token amount')
@@ -1,7 +1,7 @@
1
- import * as Icons from 'lucide-react';
2
1
  import { Button } from '@headlessui/react';
3
2
  import { useEffect, useMemo, useState } from 'react';
4
3
  import { useDebounce } from 'use-debounce';
4
+ import { WandShineW700 as WandShine } from '@material-symbols-svg/react-rounded/icons/wand-shine';
5
5
  import type { ChangeEvent } from 'react';
6
6
 
7
7
  import { useNotification } from './useNotification';
@@ -76,6 +76,7 @@ export const SendAddress = ({ error, className, onMsg }: Props) => {
76
76
  {t('sendAddress.label', 'Send to')}
77
77
  </h5>
78
78
  <Input
79
+ fontSize="sm"
79
80
  defaultValue={ctx.sendAddress}
80
81
  state={inputState}
81
82
  className="mb-sw-xl"
@@ -88,7 +89,7 @@ export const SendAddress = ({ error, className, onMsg }: Props) => {
88
89
  <Button
89
90
  className="absolute right-0 flex items-center gap-sw-md min-w-max cursor-pointer"
90
91
  onClick={() => fireEvent('addressSet', ctx.walletAddress ?? '')}>
91
- <Icons.Wand2 size={14} />
92
+ <WandShine size={14} />
92
93
  <span className="text-sw-label-md">
93
94
  {t('sendAddress.button.magic.label', 'My wallet')}
94
95
  </span>
@@ -0,0 +1,13 @@
1
+ import { formatAddressTruncate } from '@/utils/formatters/formatAddressTruncate';
2
+ import { CopyButton } from '@/components/CopyButton';
3
+
4
+ type Props = {
5
+ value: string;
6
+ };
7
+
8
+ export const CopyableValue = ({ value }: Props) => (
9
+ <span className="text-sw-gray-50 flex items-center gap-sw-xs bg-sw-gray-800 rounded-full px-sw-sm py-sw-xs">
10
+ {formatAddressTruncate(value, 16)}
11
+ <CopyButton className="scale-80" value={value} />
12
+ </span>
13
+ );
@@ -0,0 +1,26 @@
1
+ import { Card } from '@/components/Card';
2
+ import { TokenIcon } from '@/components/TokenIcon';
3
+ import { formatUsdAmount } from '@/utils/formatters/formatUsdAmount';
4
+ import type { Token } from '@/types/token';
5
+
6
+ type Props = {
7
+ token: Token;
8
+ amount: string;
9
+ amountUsd: number | bigint;
10
+ };
11
+
12
+ export const TokenRow = ({ token, amount, amountUsd }: Props) => (
13
+ <Card className="flex items-center justify-between gap-sw-md pl-sw-2xl py-sw-lg">
14
+ <TokenIcon
15
+ token={token}
16
+ chainShowIcon={!token.isIntent}
17
+ className="border-sw-gray-900"
18
+ />
19
+ <div className="text-sw-label-md text-sw-gray-50 mr-auto">
20
+ {`${amount} ${token.symbol}`}
21
+ </div>
22
+ <span className="text-sw-label-sm text-sw-gray-200">
23
+ {formatUsdAmount(amountUsd)}
24
+ </span>
25
+ </Card>
26
+ );
@@ -1,79 +1,185 @@
1
- import { Fragment } from 'react';
1
+ import {
2
+ ArrowDownward,
3
+ Check,
4
+ OpenInNew,
5
+ } from '@material-symbols-svg/react-rounded/w700';
2
6
 
3
- import { CheckIcon } from './CheckIcon';
4
- import { SummaryItem } from './SummaryItem';
5
- import { Hr } from '@/components/Hr';
6
- import { Card } from '@/components/Card';
7
+ import { TokenRow } from './TokenRow';
8
+ import { CopyableValue } from './CopyableValue';
9
+ import { useSummaryItemsCount } from './useSummaryItemsCount';
10
+
11
+ import { Notes } from '@/components/Notes';
12
+ import { Button } from '@/components/Button';
7
13
  import { CloseButton } from '@/components/CloseButton';
8
- import type { TransferResult } from '@/types/transfer';
14
+ import { Accordion } from '@/components/Accordion';
9
15
 
10
- import { fireEvent, useUnsafeSnapshot } from '@/machine';
16
+ import { guardStates } from '@/machine/guards';
17
+ import { useUnsafeSnapshot } from '@/machine/snap';
18
+ import { formatUsdAmount } from '@/utils/formatters/formatUsdAmount';
19
+ import { formatTinyNumber } from '@/utils/formatters/formatTinyNumber';
20
+ import { formatBigToHuman } from '@/utils/formatters/formatBigToHuman';
11
21
  import { useTypedTranslation } from '@/localisation';
22
+ import { useHandleKeyDown } from '@/hooks';
23
+ import { logger } from '@/logger';
24
+
25
+ import type { TransferResult } from '@/types/transfer';
26
+
27
+ const NOTES_ITEM_HEIGHT = 44;
12
28
 
13
29
  type Msg = { type: 'on_dismiss_success' };
14
30
 
15
31
  type Props = TransferResult & {
16
- message: string | string[];
17
- onMsg?: (msg: Msg) => void;
18
- hideHeader?: boolean;
32
+ title: string;
33
+ message?: string;
34
+ showTargetToken?: boolean;
35
+ onMsg: (msg: Msg) => void;
19
36
  };
20
37
 
21
38
  export const SuccessScreen = ({
22
- intent,
23
- transactionLink,
24
- hash: txHash,
39
+ title,
25
40
  message,
41
+ showTargetToken = true,
42
+ transactionLink,
26
43
  onMsg,
27
- hideHeader,
44
+ ...transferResult
28
45
  }: Props) => {
29
- const { ctx } = useUnsafeSnapshot();
30
46
  const { t } = useTypedTranslation();
31
- const lines = Array.isArray(message) ? message : [message];
47
+ const { ctx } = useUnsafeSnapshot();
48
+
49
+ const isValidState = guardStates(ctx, ['transfer_success']);
50
+ const handleClose = () => onMsg({ type: 'on_dismiss_success' });
51
+ const summaryItemsCount = useSummaryItemsCount(!!transferResult.intent);
52
+
53
+ useHandleKeyDown('Escape', handleClose);
32
54
 
33
- const onDismiss = () => {
34
- fireEvent('reset', { clearWalletAddress: false }).moveTo(
35
- ctx.walletAddress ? 'initial_wallet' : 'initial_dry',
55
+ if (!isValidState) {
56
+ logger.warn(
57
+ '[WIDGET] Success screen can be rendered only in transfer_success state',
36
58
  );
37
- onMsg?.({ type: 'on_dismiss_success' });
38
- };
59
+
60
+ return null;
61
+ }
62
+
63
+ const sourceAmount = formatBigToHuman(
64
+ ctx.quote?.amountIn ?? ctx.sourceTokenAmount,
65
+ ctx.sourceToken.decimals,
66
+ );
67
+
68
+ const targetAmount = formatBigToHuman(
69
+ ctx.quote?.amountOut ?? ctx.targetTokenAmount,
70
+ ctx.targetToken.decimals,
71
+ );
72
+
73
+ const sourceAmountUsd = ctx.quote?.amountInUsd
74
+ ? parseFloat(ctx.quote.amountInUsd)
75
+ : ctx.sourceToken.price * parseFloat(sourceAmount);
76
+
77
+ const targetAmountUsd = ctx.quote?.amountOutUsd
78
+ ? parseFloat(ctx.quote.amountOutUsd)
79
+ : ctx.targetToken.price * parseFloat(targetAmount);
80
+
81
+ const targetTokenUnitPrice = targetAmountUsd / parseFloat(targetAmount);
82
+
83
+ const sourceTokenUnitAmount = formatTinyNumber(
84
+ targetTokenUnitPrice / (parseFloat(sourceAmount) / sourceAmountUsd),
85
+ );
39
86
 
40
87
  return (
41
- <Card className="w-full">
42
- {!hideHeader && (
43
- <>
44
- <header className="flex justify-between">
45
- <CheckIcon />
46
- <CloseButton onClick={onDismiss} />
47
- </header>
48
- <span className="text-sw-label-lg text-sw-gray-50">
49
- {t('transfer.success.title', 'All done!')}
50
- </span>
51
- </>
88
+ <div className="flex flex-col gap-sw-2xl w-full">
89
+ <header className="flex items-center gap-sw-lg">
90
+ <div className="flex items-center justify-center p-sw-md bg-sw-status-success rounded-sw-md">
91
+ <Check size={20} className="text-sw-gray-900" />
92
+ </div>
93
+ <span className="text-sw-label-lg text-sw-status-success mr-auto">
94
+ {title}
95
+ </span>
96
+ <CloseButton onClick={handleClose} />
97
+ </header>
98
+
99
+ {!!message && (
100
+ <p className="text-sw-body-md text-sw-gray-200">{message}</p>
52
101
  )}
53
- <p className="mt-sw-sm text-sw-body-md text-sw-gray-400">
54
- {lines.map((line, idx) => (
55
- <Fragment key={idx}>
56
- {line}
57
- {idx !== lines.length - 1 && <br />}
58
- </Fragment>
59
- ))}
60
- </p>
61
- <Hr className="mt-sw-xl mb-sw-md" />
62
- <ul className="mt-sw-xl flex flex-col">
63
- <SummaryItem
64
- hasCopyAction
65
- value={txHash}
66
- externalUrl={transactionLink}
67
- label={t('transfer.success.hash.label', 'Transaction hash')}
102
+
103
+ <div className="flex flex-col">
104
+ <TokenRow
105
+ token={ctx.sourceToken}
106
+ amount={sourceAmount}
107
+ amountUsd={sourceAmountUsd}
68
108
  />
69
- {!!intent && (
70
- <SummaryItem
71
- hasCopyAction
72
- label={t('transfer.success.intent.label', 'Intent')}
73
- value={intent}
74
- />
109
+ {showTargetToken && (
110
+ <>
111
+ <div className="flex items-center justify-center w-full h-[12px] z-1">
112
+ <div className="flex items-center justify-center p-sw-md bg-sw-gray-950 rounded-sw-md w-fit">
113
+ <ArrowDownward size={18} className="text-sw-gray-200" />
114
+ </div>
115
+ </div>
116
+ <TokenRow
117
+ token={ctx.targetToken}
118
+ amount={targetAmount}
119
+ amountUsd={targetAmountUsd}
120
+ />
121
+ </>
75
122
  )}
76
- </ul>
77
- </Card>
123
+ </div>
124
+
125
+ <Accordion
126
+ expandedByDefault={false}
127
+ expandedHeightPx={summaryItemsCount * NOTES_ITEM_HEIGHT}
128
+ title={t('transfer.success.details.label', 'Transaction details')}>
129
+ <Notes>
130
+ {ctx.sourceToken.symbol !== ctx.targetToken.symbol && (
131
+ <Notes.Item
132
+ label={t('transfer.success.details.rate', 'Rate')}
133
+ value={
134
+ <span
135
+ className="text-sw-gray-50"
136
+ style={{ borderBottomWidth: '2px', borderStyle: 'dotted' }}>
137
+ {`1 ${ctx.targetToken.symbol} ≈ `} {sourceTokenUnitAmount}{' '}
138
+ {`${ctx.sourceToken.symbol}`}
139
+ <span>{` (${formatUsdAmount(targetTokenUnitPrice)})`}</span>
140
+ </span>
141
+ }
142
+ />
143
+ )}
144
+ {/* send address is missing if target token is on intents */}
145
+ {!!ctx.sendAddress && (
146
+ <Notes.Item
147
+ label={t(
148
+ 'transfer.success.details.recipient',
149
+ 'Recipient address',
150
+ )}
151
+ value={<CopyableValue value={ctx.sendAddress} />}
152
+ />
153
+ )}
154
+ {!!transferResult.intent && (
155
+ <Notes.Item
156
+ label={t('transfer.success.details.intent', 'Intent hash')}
157
+ value={<CopyableValue value={transferResult.intent} />}
158
+ />
159
+ )}
160
+ <Notes.Item
161
+ label={t('transfer.success.details.hash', 'Transaction hash')}
162
+ value={<CopyableValue value={transferResult.hash} />}
163
+ />
164
+ </Notes>
165
+ </Accordion>
166
+
167
+ <div className="flex flex-col gap-sw-lg">
168
+ <Button
169
+ fluid
170
+ as="a"
171
+ size="lg"
172
+ target="_blank"
173
+ variant="primary"
174
+ iconPosition="tail"
175
+ href={transactionLink}
176
+ icon={OpenInNew}>
177
+ {t('transfer.success.action.viewOnExplorer', 'View in explorer')}
178
+ </Button>
179
+ <Button fluid size="lg" variant="outlined" onClick={handleClose}>
180
+ {t('transfer.success.action.backToSwap', 'Back to swap')}
181
+ </Button>
182
+ </div>
183
+ </div>
78
184
  );
79
185
  };
@@ -0,0 +1,33 @@
1
+ import { useMemo } from 'react';
2
+
3
+ import { guardStates } from '@/machine/guards';
4
+ import { useUnsafeSnapshot } from '@/machine/snap';
5
+
6
+ export const useSummaryItemsCount = (hasIntentHash: boolean) => {
7
+ const { ctx } = useUnsafeSnapshot();
8
+ const isValidState = guardStates(ctx, ['transfer_success']);
9
+
10
+ const summaryItemsCount = useMemo(() => {
11
+ let count = 1;
12
+
13
+ if (!isValidState) {
14
+ return 0;
15
+ }
16
+
17
+ if (ctx.sourceToken.symbol !== ctx.targetToken.symbol) {
18
+ count += 1;
19
+ }
20
+
21
+ if (ctx.sendAddress) {
22
+ count += 1;
23
+ }
24
+
25
+ if (hasIntentHash) {
26
+ count += 1;
27
+ }
28
+
29
+ return count;
30
+ }, [hasIntentHash, ctx.sendAddress, ctx.sourceToken, ctx.targetToken]);
31
+
32
+ return summaryItemsCount;
33
+ };
@@ -1,5 +1,5 @@
1
+ import { SearchW700 as Search } from '@material-symbols-svg/react-rounded/icons/search';
1
2
  import { useRef, useState } from 'react';
2
- import * as Icons from 'lucide-react';
3
3
 
4
4
  import { TokensList } from './TokensList';
5
5
  import { ChainsDropdown } from './ChainsDropdown';
@@ -99,7 +99,7 @@ export const TokensModal = ({
99
99
  <div className="gap-sw-xl flex items-center">
100
100
  <Input
101
101
  focusOnMount
102
- icon={Icons.Search}
102
+ icon={Search}
103
103
  ref={searchInputRef}
104
104
  defaultValue={search}
105
105
  className="w-full"
@@ -1,12 +1,11 @@
1
- import {
2
- AccountBalanceWalletFill,
3
- ArmingCountdownFill,
4
- BeenhereFill,
5
- CheckCircleFill,
6
- EncryptedFill,
7
- GppBadFill,
8
- type MaterialSymbolsComponent,
9
- } from '@material-symbols-svg/react-rounded';
1
+ import { AccountBalanceWalletFillW700 as AccountBalanceWalletFill } from '@material-symbols-svg/react-rounded/icons/account-balance-wallet';
2
+ import { ArmingCountdownFillW700 as ArmingCountdownFill } from '@material-symbols-svg/react-rounded/icons/arming-countdown';
3
+ import { BeenhereFillW700 as BeenhereFill } from '@material-symbols-svg/react-rounded/icons/beenhere';
4
+ import { CheckCircleFillW700 as CheckCircleFill } from '@material-symbols-svg/react-rounded/icons/check-circle';
5
+ import { EncryptedFillW700 as EncryptedFill } from '@material-symbols-svg/react-rounded/icons/encrypted';
6
+ import { GppBadFillW700 as GppBadFill } from '@material-symbols-svg/react-rounded/icons/gpp-bad';
7
+ import type { MaterialSymbolsComponent } from '@material-symbols-svg/react-rounded';
8
+
10
9
  import { useTimer } from 'use-timer';
11
10
  import { useEffect } from 'react';
12
11
 
@@ -2,15 +2,13 @@ import type { Machine } from '@/machine';
2
2
  import type { Context } from '@/machine/context';
3
3
 
4
4
  export type ResetPayload = {
5
+ keepSelectedTokens?: boolean;
5
6
  clearWalletAddress: boolean;
6
7
  };
7
8
 
8
9
  export const reset = (ctx: Context, payload: ResetPayload, m: Machine) => {
9
- ctx.sourceToken = undefined;
10
10
  ctx.sourceTokenBalance = undefined;
11
11
  ctx.sourceTokenAmount = '';
12
-
13
- ctx.targetToken = undefined;
14
12
  ctx.targetTokenAmount = '';
15
13
 
16
14
  ctx.sendAddress = undefined;
@@ -22,6 +20,11 @@ export const reset = (ctx: Context, payload: ResetPayload, m: Machine) => {
22
20
  ctx.quoteStatus = 'idle';
23
21
  ctx.transferStatus = { status: 'idle' };
24
22
 
23
+ if (!payload.keepSelectedTokens) {
24
+ ctx.sourceToken = undefined;
25
+ ctx.targetToken = undefined;
26
+ }
27
+
25
28
  if (payload.clearWalletAddress) {
26
29
  ctx.walletAddress = undefined;
27
30
  }
package/src/tailwind.css CHANGED
@@ -102,6 +102,15 @@
102
102
  }
103
103
  }
104
104
 
105
+ @utility text-sw-label-2sm {
106
+ @layer components {
107
+ @apply font-semibold;
108
+ font-size: 0.825rem;
109
+ line-height: 0.875rem;
110
+ letter-spacing: -0.01875rem;
111
+ }
112
+ }
113
+
105
114
  @utility text-sw-label-sm {
106
115
  @layer components {
107
116
  @apply font-semibold;
@@ -14,9 +14,16 @@ export type LocalisationKeys =
14
14
  | 'wallet.recipient.message.receiveFunds'
15
15
  | 'wallet.connected.error.notSupportedChain'
16
16
  // transfer
17
- | 'transfer.success.title'
18
- | 'transfer.success.hash.label'
19
- | 'transfer.success.intent.label'
17
+ | 'transfer.success.swap.title'
18
+ | 'transfer.success.withdrawal.title'
19
+ | 'transfer.success.deposit.title'
20
+ | 'transfer.success.details.label'
21
+ | 'transfer.success.details.hash'
22
+ | 'transfer.success.details.rate'
23
+ | 'transfer.success.details.intent'
24
+ | 'transfer.success.details.recipient'
25
+ | 'transfer.success.action.viewOnExplorer'
26
+ | 'transfer.success.action.backToSwap'
20
27
  // quote
21
28
  | 'quote.result.maxSlippage.label'
22
29
  | 'quote.result.processingTime.label'
@@ -121,6 +121,10 @@ export const WidgetDepositContent = ({
121
121
  });
122
122
  }, [ctx.isDepositFromExternalWallet]);
123
123
 
124
+ const onBackToSwap = () => {
125
+ fireEvent('reset', { clearWalletAddress: false, keepSelectedTokens: true });
126
+ };
127
+
124
128
  if (!!isLoading || (tokensStatus !== 'error' && !ctx.sourceToken)) {
125
129
  return <WidgetDepositSkeleton />;
126
130
  }
@@ -150,14 +154,12 @@ export const WidgetDepositContent = ({
150
154
  return (
151
155
  <SuccessScreen
152
156
  {...transferResult}
153
- message={[
154
- 'Your deposit has been successfully completed,',
155
- 'and the funds are now available in your account.',
156
- ]}
157
+ title={t('transfer.success.deposit.title', 'Deposit successful')}
157
158
  onMsg={(msg) => {
158
159
  switch (msg.type) {
159
160
  case 'on_dismiss_success':
160
161
  setTransferResult(undefined);
162
+ onBackToSwap();
161
163
  break;
162
164
  default:
163
165
  notReachable(msg.type);