@relayprotocol/relay-kit-ui 5.1.2 → 6.0.0

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 (220) hide show
  1. package/_cjs/src/components/common/BalanceDisplay.js +4 -3
  2. package/_cjs/src/components/common/BalanceDisplay.js.map +1 -1
  3. package/_cjs/src/components/common/MultiWalletDropdown.js +5 -4
  4. package/_cjs/src/components/common/MultiWalletDropdown.js.map +1 -1
  5. package/_cjs/src/components/common/PercentageButtons.js +9 -9
  6. package/_cjs/src/components/common/PercentageButtons.js.map +1 -1
  7. package/_cjs/src/components/common/SlippageToleranceConfig.js +30 -17
  8. package/_cjs/src/components/common/SlippageToleranceConfig.js.map +1 -1
  9. package/_cjs/src/components/common/TokenSelector/ChainFilter.js +21 -19
  10. package/_cjs/src/components/common/TokenSelector/ChainFilter.js.map +1 -1
  11. package/_cjs/src/components/common/TokenSelector/ChainFilterRow.js +117 -0
  12. package/_cjs/src/components/common/TokenSelector/ChainFilterRow.js.map +1 -0
  13. package/_cjs/src/components/common/TokenSelector/ChainFilterSidebar.js +2 -13
  14. package/_cjs/src/components/common/TokenSelector/ChainFilterSidebar.js.map +1 -1
  15. package/_cjs/src/components/common/TokenSelector/CompactChainFilter.js +180 -0
  16. package/_cjs/src/components/common/TokenSelector/CompactChainFilter.js.map +1 -0
  17. package/_cjs/src/components/common/TokenSelector/PaymentMethod.js +456 -0
  18. package/_cjs/src/components/common/TokenSelector/PaymentMethod.js.map +1 -0
  19. package/_cjs/src/components/common/TokenSelector/PaymentTokenList.js +83 -0
  20. package/_cjs/src/components/common/TokenSelector/PaymentTokenList.js.map +1 -0
  21. package/_cjs/src/components/common/TokenSelector/triggers/PaymentMethodTrigger.js +77 -0
  22. package/_cjs/src/components/common/TokenSelector/triggers/PaymentMethodTrigger.js.map +1 -0
  23. package/_cjs/src/components/primitives/ChainTokenIcon.js +3 -2
  24. package/_cjs/src/components/primitives/ChainTokenIcon.js.map +1 -1
  25. package/_cjs/src/components/primitives/SlippageButton.js +40 -0
  26. package/_cjs/src/components/primitives/SlippageButton.js.map +1 -0
  27. package/_cjs/src/components/primitives/Tabs.js +4 -2
  28. package/_cjs/src/components/primitives/Tabs.js.map +1 -1
  29. package/_cjs/src/components/widgets/SwapButton.js +35 -7
  30. package/_cjs/src/components/widgets/SwapButton.js.map +1 -1
  31. package/_cjs/src/components/widgets/TokenWidget/AmountModeToggle.js +31 -0
  32. package/_cjs/src/components/widgets/TokenWidget/AmountModeToggle.js.map +1 -0
  33. package/_cjs/src/components/widgets/TokenWidget/AmountSectionHeader.js +8 -0
  34. package/_cjs/src/components/widgets/TokenWidget/AmountSectionHeader.js.map +1 -0
  35. package/_cjs/src/components/widgets/TokenWidget/BuyTabContent.js +218 -0
  36. package/_cjs/src/components/widgets/TokenWidget/BuyTabContent.js.map +1 -0
  37. package/_cjs/src/components/widgets/TokenWidget/DestinationWalletSelector.js +20 -0
  38. package/_cjs/src/components/widgets/TokenWidget/DestinationWalletSelector.js.map +1 -0
  39. package/_cjs/src/components/widgets/TokenWidget/FeeBreakdownInfo.js +26 -0
  40. package/_cjs/src/components/widgets/TokenWidget/FeeBreakdownInfo.js.map +1 -0
  41. package/_cjs/src/components/widgets/TokenWidget/FeeBreakdownTooltip.js +40 -0
  42. package/_cjs/src/components/widgets/TokenWidget/FeeBreakdownTooltip.js.map +1 -0
  43. package/_cjs/src/components/widgets/TokenWidget/SectionContainer.js +22 -0
  44. package/_cjs/src/components/widgets/TokenWidget/SectionContainer.js.map +1 -0
  45. package/_cjs/src/components/widgets/TokenWidget/SellTabContent.js +280 -0
  46. package/_cjs/src/components/widgets/TokenWidget/SellTabContent.js.map +1 -0
  47. package/_cjs/src/components/widgets/TokenWidget/TransactionDetailsFooter.js +28 -0
  48. package/_cjs/src/components/widgets/TokenWidget/TransactionDetailsFooter.js.map +1 -0
  49. package/_cjs/src/components/widgets/TokenWidget/hooks/useWalletGuards.js +108 -0
  50. package/_cjs/src/components/widgets/TokenWidget/hooks/useWalletGuards.js.map +1 -0
  51. package/_cjs/src/components/widgets/TokenWidget/index.js +9 -0
  52. package/_cjs/src/components/widgets/TokenWidget/index.js.map +1 -0
  53. package/_cjs/src/components/widgets/TokenWidget/widget/TokenWidgetRenderer.js +770 -0
  54. package/_cjs/src/components/widgets/TokenWidget/widget/TokenWidgetRenderer.js.map +1 -0
  55. package/_cjs/src/components/widgets/TokenWidget/widget/index.js +1005 -0
  56. package/_cjs/src/components/widgets/TokenWidget/widget/index.js.map +1 -0
  57. package/_cjs/src/hooks/index.js +3 -1
  58. package/_cjs/src/hooks/index.js.map +1 -1
  59. package/_cjs/src/hooks/useDuneBalances.js +2 -1
  60. package/_cjs/src/hooks/useDuneBalances.js.map +1 -1
  61. package/_cjs/src/hooks/useEOADetection.js +3 -0
  62. package/_cjs/src/hooks/useEOADetection.js.map +1 -1
  63. package/_cjs/src/hooks/useMultiWalletBalances.js +119 -0
  64. package/_cjs/src/hooks/useMultiWalletBalances.js.map +1 -0
  65. package/_cjs/src/index.js.map +1 -1
  66. package/_cjs/src/styles.css +251 -88
  67. package/_cjs/src/utils/numbers.js +39 -1
  68. package/_cjs/src/utils/numbers.js.map +1 -1
  69. package/_cjs/src/utils/tokenSelector.js +4 -1
  70. package/_cjs/src/utils/tokenSelector.js.map +1 -1
  71. package/_cjs/src/utils/tokens.js +20 -1
  72. package/_cjs/src/utils/tokens.js.map +1 -1
  73. package/_cjs/src/version.js +1 -1
  74. package/_cjs/tsconfig.build.tsbuildinfo +1 -1
  75. package/_esm/src/components/common/BalanceDisplay.js +4 -3
  76. package/_esm/src/components/common/BalanceDisplay.js.map +1 -1
  77. package/_esm/src/components/common/MultiWalletDropdown.js +5 -4
  78. package/_esm/src/components/common/MultiWalletDropdown.js.map +1 -1
  79. package/_esm/src/components/common/PercentageButtons.js +10 -10
  80. package/_esm/src/components/common/PercentageButtons.js.map +1 -1
  81. package/_esm/src/components/common/SlippageToleranceConfig.js +31 -23
  82. package/_esm/src/components/common/SlippageToleranceConfig.js.map +1 -1
  83. package/_esm/src/components/common/TokenSelector/ChainFilter.js +25 -23
  84. package/_esm/src/components/common/TokenSelector/ChainFilter.js.map +1 -1
  85. package/_esm/src/components/common/TokenSelector/ChainFilterRow.js +112 -0
  86. package/_esm/src/components/common/TokenSelector/ChainFilterRow.js.map +1 -0
  87. package/_esm/src/components/common/TokenSelector/ChainFilterSidebar.js +4 -15
  88. package/_esm/src/components/common/TokenSelector/ChainFilterSidebar.js.map +1 -1
  89. package/_esm/src/components/common/TokenSelector/CompactChainFilter.js +176 -0
  90. package/_esm/src/components/common/TokenSelector/CompactChainFilter.js.map +1 -0
  91. package/_esm/src/components/common/TokenSelector/PaymentMethod.js +461 -0
  92. package/_esm/src/components/common/TokenSelector/PaymentMethod.js.map +1 -0
  93. package/_esm/src/components/common/TokenSelector/PaymentTokenList.js +79 -0
  94. package/_esm/src/components/common/TokenSelector/PaymentTokenList.js.map +1 -0
  95. package/_esm/src/components/common/TokenSelector/triggers/PaymentMethodTrigger.js +72 -0
  96. package/_esm/src/components/common/TokenSelector/triggers/PaymentMethodTrigger.js.map +1 -0
  97. package/_esm/src/components/primitives/ChainTokenIcon.js +3 -2
  98. package/_esm/src/components/primitives/ChainTokenIcon.js.map +1 -1
  99. package/_esm/src/components/primitives/SlippageButton.js +36 -0
  100. package/_esm/src/components/primitives/SlippageButton.js.map +1 -0
  101. package/_esm/src/components/primitives/Tabs.js +4 -2
  102. package/_esm/src/components/primitives/Tabs.js.map +1 -1
  103. package/_esm/src/components/widgets/SwapButton.js +35 -7
  104. package/_esm/src/components/widgets/SwapButton.js.map +1 -1
  105. package/_esm/src/components/widgets/TokenWidget/AmountModeToggle.js +30 -0
  106. package/_esm/src/components/widgets/TokenWidget/AmountModeToggle.js.map +1 -0
  107. package/_esm/src/components/widgets/TokenWidget/AmountSectionHeader.js +7 -0
  108. package/_esm/src/components/widgets/TokenWidget/AmountSectionHeader.js.map +1 -0
  109. package/_esm/src/components/widgets/TokenWidget/BuyTabContent.js +215 -0
  110. package/_esm/src/components/widgets/TokenWidget/BuyTabContent.js.map +1 -0
  111. package/_esm/src/components/widgets/TokenWidget/DestinationWalletSelector.js +16 -0
  112. package/_esm/src/components/widgets/TokenWidget/DestinationWalletSelector.js.map +1 -0
  113. package/_esm/src/components/widgets/TokenWidget/FeeBreakdownInfo.js +21 -0
  114. package/_esm/src/components/widgets/TokenWidget/FeeBreakdownInfo.js.map +1 -0
  115. package/_esm/src/components/widgets/TokenWidget/FeeBreakdownTooltip.js +39 -0
  116. package/_esm/src/components/widgets/TokenWidget/FeeBreakdownTooltip.js.map +1 -0
  117. package/_esm/src/components/widgets/TokenWidget/SectionContainer.js +22 -0
  118. package/_esm/src/components/widgets/TokenWidget/SectionContainer.js.map +1 -0
  119. package/_esm/src/components/widgets/TokenWidget/SellTabContent.js +283 -0
  120. package/_esm/src/components/widgets/TokenWidget/SellTabContent.js.map +1 -0
  121. package/_esm/src/components/widgets/TokenWidget/TransactionDetailsFooter.js +27 -0
  122. package/_esm/src/components/widgets/TokenWidget/TransactionDetailsFooter.js.map +1 -0
  123. package/_esm/src/components/widgets/TokenWidget/hooks/useWalletGuards.js +104 -0
  124. package/_esm/src/components/widgets/TokenWidget/hooks/useWalletGuards.js.map +1 -0
  125. package/_esm/src/components/widgets/TokenWidget/index.js +2 -0
  126. package/_esm/src/components/widgets/TokenWidget/index.js.map +1 -0
  127. package/_esm/src/components/widgets/TokenWidget/widget/TokenWidgetRenderer.js +795 -0
  128. package/_esm/src/components/widgets/TokenWidget/widget/TokenWidgetRenderer.js.map +1 -0
  129. package/_esm/src/components/widgets/TokenWidget/widget/index.js +1073 -0
  130. package/_esm/src/components/widgets/TokenWidget/widget/index.js.map +1 -0
  131. package/_esm/src/hooks/index.js +2 -1
  132. package/_esm/src/hooks/index.js.map +1 -1
  133. package/_esm/src/hooks/useDuneBalances.js +2 -1
  134. package/_esm/src/hooks/useDuneBalances.js.map +1 -1
  135. package/_esm/src/hooks/useEOADetection.js +3 -0
  136. package/_esm/src/hooks/useEOADetection.js.map +1 -1
  137. package/_esm/src/hooks/useMultiWalletBalances.js +122 -0
  138. package/_esm/src/hooks/useMultiWalletBalances.js.map +1 -0
  139. package/_esm/src/index.js.map +1 -1
  140. package/_esm/src/styles.css +251 -88
  141. package/_esm/src/utils/numbers.js +44 -1
  142. package/_esm/src/utils/numbers.js.map +1 -1
  143. package/_esm/src/utils/tokenSelector.js +4 -1
  144. package/_esm/src/utils/tokenSelector.js.map +1 -1
  145. package/_esm/src/utils/tokens.js +25 -0
  146. package/_esm/src/utils/tokens.js.map +1 -1
  147. package/_esm/src/version.js +1 -1
  148. package/_esm/tsconfig.build.tsbuildinfo +1 -1
  149. package/_types/src/components/common/BalanceDisplay.d.ts +2 -0
  150. package/_types/src/components/common/BalanceDisplay.d.ts.map +1 -1
  151. package/_types/src/components/common/MultiWalletDropdown.d.ts +2 -1
  152. package/_types/src/components/common/MultiWalletDropdown.d.ts.map +1 -1
  153. package/_types/src/components/common/PercentageButtons.d.ts +3 -1
  154. package/_types/src/components/common/PercentageButtons.d.ts.map +1 -1
  155. package/_types/src/components/common/SlippageToleranceConfig.d.ts +7 -0
  156. package/_types/src/components/common/SlippageToleranceConfig.d.ts.map +1 -1
  157. package/_types/src/components/common/TokenSelector/ChainFilter.d.ts.map +1 -1
  158. package/_types/src/components/common/TokenSelector/ChainFilterRow.d.ts +19 -0
  159. package/_types/src/components/common/TokenSelector/ChainFilterRow.d.ts.map +1 -0
  160. package/_types/src/components/common/TokenSelector/ChainFilterSidebar.d.ts.map +1 -1
  161. package/_types/src/components/common/TokenSelector/CompactChainFilter.d.ts +14 -0
  162. package/_types/src/components/common/TokenSelector/CompactChainFilter.d.ts.map +1 -0
  163. package/_types/src/components/common/TokenSelector/PaymentMethod.d.ts +24 -0
  164. package/_types/src/components/common/TokenSelector/PaymentMethod.d.ts.map +1 -0
  165. package/_types/src/components/common/TokenSelector/PaymentTokenList.d.ts +15 -0
  166. package/_types/src/components/common/TokenSelector/PaymentTokenList.d.ts.map +1 -0
  167. package/_types/src/components/common/TokenSelector/triggers/PaymentMethodTrigger.d.ts +13 -0
  168. package/_types/src/components/common/TokenSelector/triggers/PaymentMethodTrigger.d.ts.map +1 -0
  169. package/_types/src/components/primitives/ChainTokenIcon.d.ts +1 -0
  170. package/_types/src/components/primitives/ChainTokenIcon.d.ts.map +1 -1
  171. package/_types/src/components/primitives/SlippageButton.d.ts +8 -0
  172. package/_types/src/components/primitives/SlippageButton.d.ts.map +1 -0
  173. package/_types/src/components/primitives/Tabs.d.ts.map +1 -1
  174. package/_types/src/components/widgets/SwapButton.d.ts +5 -2
  175. package/_types/src/components/widgets/SwapButton.d.ts.map +1 -1
  176. package/_types/src/components/widgets/TokenWidget/AmountModeToggle.d.ts +12 -0
  177. package/_types/src/components/widgets/TokenWidget/AmountModeToggle.d.ts.map +1 -0
  178. package/_types/src/components/widgets/TokenWidget/AmountSectionHeader.d.ts +11 -0
  179. package/_types/src/components/widgets/TokenWidget/AmountSectionHeader.d.ts.map +1 -0
  180. package/_types/src/components/widgets/TokenWidget/BuyTabContent.d.ts +52 -0
  181. package/_types/src/components/widgets/TokenWidget/BuyTabContent.d.ts.map +1 -0
  182. package/_types/src/components/widgets/TokenWidget/DestinationWalletSelector.d.ts +17 -0
  183. package/_types/src/components/widgets/TokenWidget/DestinationWalletSelector.d.ts.map +1 -0
  184. package/_types/src/components/widgets/TokenWidget/FeeBreakdownInfo.d.ts +16 -0
  185. package/_types/src/components/widgets/TokenWidget/FeeBreakdownInfo.d.ts.map +1 -0
  186. package/_types/src/components/widgets/TokenWidget/FeeBreakdownTooltip.d.ts +15 -0
  187. package/_types/src/components/widgets/TokenWidget/FeeBreakdownTooltip.d.ts.map +1 -0
  188. package/_types/src/components/widgets/TokenWidget/SectionContainer.d.ts +8 -0
  189. package/_types/src/components/widgets/TokenWidget/SectionContainer.d.ts.map +1 -0
  190. package/_types/src/components/widgets/TokenWidget/SellTabContent.d.ts +61 -0
  191. package/_types/src/components/widgets/TokenWidget/SellTabContent.d.ts.map +1 -0
  192. package/_types/src/components/widgets/TokenWidget/TransactionDetailsFooter.d.ts +14 -0
  193. package/_types/src/components/widgets/TokenWidget/TransactionDetailsFooter.d.ts.map +1 -0
  194. package/_types/src/components/widgets/TokenWidget/hooks/useWalletGuards.d.ts +28 -0
  195. package/_types/src/components/widgets/TokenWidget/hooks/useWalletGuards.d.ts.map +1 -0
  196. package/_types/src/components/widgets/TokenWidget/index.d.ts +3 -0
  197. package/_types/src/components/widgets/TokenWidget/index.d.ts.map +1 -0
  198. package/_types/src/components/widgets/TokenWidget/widget/TokenWidgetRenderer.d.ts +125 -0
  199. package/_types/src/components/widgets/TokenWidget/widget/TokenWidgetRenderer.d.ts.map +1 -0
  200. package/_types/src/components/widgets/TokenWidget/widget/index.d.ts +57 -0
  201. package/_types/src/components/widgets/TokenWidget/widget/index.d.ts.map +1 -0
  202. package/_types/src/hooks/index.d.ts +2 -1
  203. package/_types/src/hooks/index.d.ts.map +1 -1
  204. package/_types/src/hooks/useDuneBalances.d.ts.map +1 -1
  205. package/_types/src/hooks/useEOADetection.d.ts.map +1 -1
  206. package/_types/src/hooks/useMultiWalletBalances.d.ts +26 -0
  207. package/_types/src/hooks/useMultiWalletBalances.d.ts.map +1 -0
  208. package/_types/src/index.d.ts +1 -0
  209. package/_types/src/index.d.ts.map +1 -1
  210. package/_types/src/utils/numbers.d.ts +8 -1
  211. package/_types/src/utils/numbers.d.ts.map +1 -1
  212. package/_types/src/utils/tokenSelector.d.ts +1 -1
  213. package/_types/src/utils/tokenSelector.d.ts.map +1 -1
  214. package/_types/src/utils/tokens.d.ts +17 -0
  215. package/_types/src/utils/tokens.d.ts.map +1 -1
  216. package/_types/src/version.d.ts +1 -1
  217. package/_types/tsconfig.build.tsbuildinfo +1 -1
  218. package/dist/panda.buildinfo.json +74 -33
  219. package/dist/styles.css +251 -88
  220. package/package.json +8 -3
@@ -0,0 +1,795 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
3
+ import { useCurrencyBalance, useENSResolver, useRelayClient, useDebounceState, useWalletAddress, useDisconnected, usePreviousValueChange, useIsWalletCompatible, useFallbackState, useEOADetection } from '../../../../hooks/index.js';
4
+ import { formatUnits, parseUnits } from 'viem';
5
+ import { useAccount, useWalletClient } from 'wagmi';
6
+ import { useCapabilities } from 'wagmi/experimental';
7
+ import { useQueryClient } from '@tanstack/react-query';
8
+ import { calculatePriceTimeEstimate, calculateRelayerFeeProportionUsd, extractQuoteId, getCurrentStep, getSwapEventData, isHighRelayerServiceFeeUsd, parseFees } from '../../../../utils/quote.js';
9
+ import { useQuote, useTokenPrice } from '@relayprotocol/relay-kit-hooks';
10
+ import { EventNames } from '../../../../constants/events.js';
11
+ import { ProviderOptionsContext } from '../../../../providers/RelayKitProvider.js';
12
+ import { addressWithFallback, isValidAddress } from '../../../../utils/address.js';
13
+ import { adaptViemWallet, getDeadAddress } from '@relayprotocol/relay-sdk';
14
+ import { errorToJSON } from '../../../../utils/errors.js';
15
+ import { useSwapButtonCta } from '../../../../hooks/widget/useSwapButtonCta.js';
16
+ import { sha256 } from '../../../../utils/hashing.js';
17
+ import { get15MinuteInterval } from '../../../../utils/time.js';
18
+ // shared query options for useTokenPrice
19
+ const tokenPriceQueryOptions = {
20
+ staleTime: 60 * 1000, // 1 minute
21
+ refetchInterval: 30 * 1000, // 30 seconds
22
+ refetchOnWindowFocus: false
23
+ };
24
+ const TokenWidgetRenderer = ({ transactionModalOpen, setTransactionModalOpen, depositAddressModalOpen, fromToken: _fromToken, setFromToken: _setFromToken, toToken: _toToken, setToToken: _setToToken, defaultToAddress, defaultAmount, defaultTradeType, slippageTolerance, context, wallet, multiWalletSupportEnabled = false, linkedWallets, supportedWalletVMs, useSecureBaseUrl, children, onAnalyticEvent, onSwapError }) => {
25
+ const [fromToken, setFromToken] = useFallbackState(_setFromToken ? _fromToken : undefined, _setFromToken
26
+ ? [
27
+ _fromToken,
28
+ _setFromToken
29
+ ]
30
+ : undefined);
31
+ const [toToken, setToToken] = useFallbackState(_setToToken ? _toToken : undefined, _setToToken
32
+ ? [_toToken, _setToToken]
33
+ : undefined);
34
+ const providerOptionsContext = useContext(ProviderOptionsContext);
35
+ const connectorKeyOverrides = providerOptionsContext.vmConnectorKeyOverrides;
36
+ const relayClient = useRelayClient();
37
+ const { connector } = useAccount();
38
+ const walletClient = useWalletClient();
39
+ const [customToAddress, setCustomToAddress] = useState(defaultToAddress);
40
+ const [destinationAddressOverride, setDestinationAddressOverride] = useState(undefined);
41
+ const [originAddressOverride, setOriginAddressOverride] = useState(undefined);
42
+ const [allowUnsupportedOrigin, setAllowUnsupportedOrigin] = useState(false);
43
+ const [allowUnsupportedRecipient, setAllowUnsupportedRecipient] = useState(false);
44
+ const [useExternalLiquidity, setUseExternalLiquidity] = useState(false);
45
+ const defaultAddress = useWalletAddress(wallet, linkedWallets);
46
+ const [tradeType, setTradeType] = useState(defaultTradeType ?? 'EXACT_INPUT');
47
+ const queryClient = useQueryClient();
48
+ const [steps, setSteps] = useState(null);
49
+ const [quoteInProgress, setQuoteInProgress] = useState(null);
50
+ const [waitingForSteps, setWaitingForSteps] = useState(false);
51
+ const [details, setDetails] = useState(null);
52
+ const [abortController, setAbortController] = useState(null);
53
+ const { value: amountInputValue, debouncedValue: debouncedInputAmountValue, setValue: setAmountInputValue, debouncedControls: debouncedAmountInputControls } = useDebounceState(!defaultTradeType || defaultTradeType === 'EXACT_INPUT'
54
+ ? (defaultAmount ?? '')
55
+ : '', 500);
56
+ const { value: amountOutputValue, debouncedValue: debouncedOutputAmountValue, setValue: setAmountOutputValue, debouncedControls: debouncedAmountOutputControls } = useDebounceState(defaultTradeType === 'EXPECTED_OUTPUT' ? (defaultAmount ?? '') : '', 500);
57
+ const [swapError, setSwapError] = useState(null);
58
+ const tokenPairIsCanonical = fromToken?.chainId !== undefined &&
59
+ toToken?.chainId !== undefined &&
60
+ fromToken.symbol === toToken.symbol;
61
+ const toChain = useMemo(() => relayClient?.chains?.find((chain) => chain.id === toToken?.chainId), [relayClient?.chains, toToken?.chainId]);
62
+ const fromChain = useMemo(() => relayClient?.chains?.find((chain) => chain.id === fromToken?.chainId), [relayClient?.chains, fromToken?.chainId]);
63
+ const fromChainWalletVMSupported = useMemo(() => !fromChain?.vmType ||
64
+ supportedWalletVMs.includes(fromChain?.vmType) ||
65
+ fromChain?.id === 1337, [fromChain?.vmType, fromChain?.id, supportedWalletVMs]);
66
+ const toChainWalletVMSupported = useMemo(() => !toChain?.vmType || supportedWalletVMs.includes(toChain?.vmType), [toChain?.vmType, supportedWalletVMs]);
67
+ // Automatically select the correct wallet address based on fromToken's chain VM
68
+ // In sell mode (no fromChain), use toChain to find compatible wallet
69
+ const address = useMemo(() => {
70
+ if (!multiWalletSupportEnabled || !linkedWallets?.length) {
71
+ return defaultAddress;
72
+ }
73
+ if (originAddressOverride) {
74
+ return originAddressOverride;
75
+ }
76
+ const targetChain = fromChain || toChain;
77
+ if (!targetChain) {
78
+ return defaultAddress;
79
+ }
80
+ // Find the first wallet that supports the target chain's VM type
81
+ const compatibleWallet = linkedWallets.find((wallet) => {
82
+ // Check if wallet VM matches chain VM
83
+ if (wallet.vmType !== targetChain.vmType) {
84
+ return false;
85
+ }
86
+ // Additional validation for specific chains
87
+ return isValidAddress(targetChain.vmType, wallet.address, targetChain.id, wallet.connector, connectorKeyOverrides);
88
+ });
89
+ return compatibleWallet?.address || defaultAddress;
90
+ }, [
91
+ multiWalletSupportEnabled,
92
+ originAddressOverride,
93
+ fromChain,
94
+ toChain,
95
+ linkedWallets,
96
+ defaultAddress,
97
+ connectorKeyOverrides
98
+ ]);
99
+ const defaultRecipient = useMemo(() => {
100
+ const _linkedWallet = linkedWallets?.find((linkedWallet) => address ===
101
+ (linkedWallet.vmType === 'evm'
102
+ ? linkedWallet.address.toLowerCase()
103
+ : linkedWallet.address));
104
+ const _isValidToAddress = isValidAddress(toChain?.vmType, customToAddress ?? '', toChain?.id, !customToAddress && _linkedWallet?.address === address
105
+ ? _linkedWallet?.connector
106
+ : undefined, connectorKeyOverrides);
107
+ if (multiWalletSupportEnabled &&
108
+ toChain &&
109
+ linkedWallets &&
110
+ !_isValidToAddress) {
111
+ // Find a compatible wallet, excluding the origin wallet
112
+ const supportedWallet = linkedWallets.find((wallet) => wallet.address !== address &&
113
+ isValidAddress(toChain.vmType, wallet.address, toChain.id, wallet.connector, connectorKeyOverrides));
114
+ return supportedWallet?.address;
115
+ }
116
+ return undefined;
117
+ }, [
118
+ multiWalletSupportEnabled,
119
+ toChain,
120
+ customToAddress,
121
+ address,
122
+ linkedWallets,
123
+ setCustomToAddress,
124
+ connectorKeyOverrides
125
+ ]);
126
+ const recipient = destinationAddressOverride ??
127
+ customToAddress ??
128
+ defaultRecipient ??
129
+ (!allowUnsupportedRecipient && address ? address : undefined);
130
+ const { value: fromBalance, queryKey: fromBalanceQueryKey, isLoading: isLoadingFromBalance, isError: fromBalanceErrorFetching, isDuneBalance: fromBalanceIsDune, hasPendingBalance: fromBalancePending } = useCurrencyBalance({
131
+ chain: fromChain,
132
+ address: address,
133
+ currency: fromToken?.address ? fromToken.address : undefined,
134
+ enabled: fromToken !== undefined,
135
+ refreshInterval: undefined,
136
+ wallet
137
+ });
138
+ const { value: toBalance, queryKey: toBalanceQueryKey, isLoading: isLoadingToBalance, isDuneBalance: toBalanceIsDune, hasPendingBalance: toBalancePending } = useCurrencyBalance({
139
+ chain: toChain,
140
+ address: recipient,
141
+ currency: toToken?.address ? toToken.address : undefined,
142
+ enabled: toToken !== undefined && recipient !== undefined && recipient !== '',
143
+ refreshInterval: undefined,
144
+ wallet
145
+ });
146
+ const invalidateBalanceQueries = useCallback(() => {
147
+ const invalidatePeriodically = (invalidateFn) => {
148
+ let maxRefreshes = 4;
149
+ let refreshCount = 0;
150
+ const timer = setInterval(() => {
151
+ if (maxRefreshes === refreshCount) {
152
+ clearInterval(timer);
153
+ return;
154
+ }
155
+ refreshCount++;
156
+ invalidateFn();
157
+ }, 3000);
158
+ };
159
+ queryClient.invalidateQueries({ queryKey: ['useDuneBalances'] });
160
+ // Dune balances are sometimes stale, because of this we need to aggressively fetch them
161
+ // for a predetermined period to make sure we get back a fresh response
162
+ if (fromBalanceIsDune) {
163
+ invalidatePeriodically(() => {
164
+ queryClient.invalidateQueries({ queryKey: fromBalanceQueryKey });
165
+ });
166
+ }
167
+ else {
168
+ queryClient.invalidateQueries({ queryKey: fromBalanceQueryKey });
169
+ }
170
+ if (toBalanceIsDune) {
171
+ invalidatePeriodically(() => {
172
+ queryClient.invalidateQueries({ queryKey: toBalanceQueryKey });
173
+ });
174
+ }
175
+ else {
176
+ queryClient.invalidateQueries({ queryKey: toBalanceQueryKey });
177
+ }
178
+ }, [
179
+ queryClient,
180
+ fromBalanceQueryKey,
181
+ toBalanceQueryKey,
182
+ toBalanceIsDune,
183
+ fromBalanceIsDune,
184
+ address
185
+ ]);
186
+ const { data: capabilities } = useCapabilities({
187
+ query: {
188
+ enabled: connector &&
189
+ (connector.id === 'coinbaseWalletSDK' || connector.id === 'coinbase')
190
+ }
191
+ });
192
+ const hasAuxiliaryFundsSupport = Boolean(fromToken?.chainId
193
+ ? capabilities?.[fromToken?.chainId]?.auxiliaryFunds?.supported
194
+ : false);
195
+ const isSvmSwap = fromChain?.vmType === 'svm' || toChain?.vmType === 'svm';
196
+ const isBvmSwap = fromChain?.vmType === 'bvm' || toChain?.vmType === 'bvm';
197
+ const linkedWallet = linkedWallets?.find((linkedWallet) => address ===
198
+ (linkedWallet.vmType === 'evm'
199
+ ? linkedWallet.address.toLowerCase()
200
+ : linkedWallet.address) || linkedWallet.address === address);
201
+ const isRecipientLinked = (recipient
202
+ ? linkedWallets?.find((wallet) => wallet.address === recipient)
203
+ : undefined) !== undefined;
204
+ const isValidFromAddress = useMemo(() => isValidAddress(fromChain?.vmType, address ?? '', fromChain?.id, linkedWallet?.connector, connectorKeyOverrides), [
205
+ fromChain?.vmType,
206
+ address,
207
+ fromChain?.id,
208
+ linkedWallet?.connector,
209
+ connectorKeyOverrides
210
+ ]);
211
+ const fromAddressWithFallback = addressWithFallback(fromChain?.vmType, address, fromChain?.id, linkedWallet?.connector, connectorKeyOverrides);
212
+ const isValidToAddress = useMemo(() => isValidAddress(toChain?.vmType, recipient ?? '', toChain?.id), [toChain?.vmType, recipient, toChain?.id]);
213
+ const toAddressWithFallback = addressWithFallback(toChain?.vmType, recipient, toChain?.id);
214
+ const externalLiquiditySupport = useQuote(relayClient ? relayClient : undefined, wallet, fromToken && toToken
215
+ ? {
216
+ user: getDeadAddress(fromChain?.vmType, fromChain?.id),
217
+ originChainId: fromToken.chainId,
218
+ destinationChainId: toToken.chainId,
219
+ originCurrency: fromToken.address,
220
+ destinationCurrency: toToken.address,
221
+ recipient: getDeadAddress(toChain?.vmType, toChain?.id),
222
+ tradeType,
223
+ appFees: providerOptionsContext.appFees,
224
+ amount: '10000000000000000000000', //Hardcode an extremely high number
225
+ referrer: relayClient?.source ?? undefined,
226
+ useExternalLiquidity: true
227
+ }
228
+ : undefined, undefined, undefined, {
229
+ refetchOnWindowFocus: false,
230
+ enabled: fromToken !== undefined &&
231
+ toToken !== undefined &&
232
+ fromChain &&
233
+ toChain &&
234
+ (fromChain.id === toChain.baseChainId ||
235
+ toChain.id === fromChain.baseChainId)
236
+ });
237
+ const supportsExternalLiquidity = tokenPairIsCanonical &&
238
+ externalLiquiditySupport.status === 'success' &&
239
+ fromChainWalletVMSupported
240
+ ? true
241
+ : false;
242
+ const { displayName: toDisplayName } = useENSResolver(recipient, {
243
+ enabled: toChain?.vmType === 'evm' && isValidToAddress
244
+ });
245
+ const [currentSlippageTolerance, setCurrentSlippageTolerance] = useState(slippageTolerance);
246
+ useEffect(() => {
247
+ setCurrentSlippageTolerance(slippageTolerance);
248
+ }, [slippageTolerance]);
249
+ // Retrieve the price of the `from` token
250
+ const { data: fromTokenPriceData, isLoading: isLoadingFromTokenPrice } = useTokenPrice(relayClient?.baseApiUrl, {
251
+ address: fromToken?.address ?? '',
252
+ chainId: fromToken?.chainId ?? 0,
253
+ referrer: relayClient?.source
254
+ }, {
255
+ enabled: !!(fromToken?.address && fromToken.chainId),
256
+ ...tokenPriceQueryOptions
257
+ });
258
+ // Retrieve the price of the `to` token
259
+ const { data: toTokenPriceData, isLoading: isLoadingToTokenPrice } = useTokenPrice(relayClient?.baseApiUrl, {
260
+ address: toToken?.address ?? '',
261
+ chainId: toToken?.chainId ?? 0,
262
+ referrer: relayClient?.source
263
+ }, {
264
+ enabled: !!(toToken?.address && toToken.chainId),
265
+ ...tokenPriceQueryOptions
266
+ });
267
+ const originChainSupportsProtocolv2 = fromChain?.protocol?.v2?.depository !== undefined &&
268
+ toChain?.protocol?.v2?.chainId !== undefined;
269
+ //Enabled only on certain chains
270
+ const quoteProtocol = fromChain?.id && originChainSupportsProtocolv2 ? 'preferV2' : undefined;
271
+ const isFromNative = fromToken?.address === fromChain?.currency?.address;
272
+ const explicitDeposit = useEOADetection(wallet, quoteProtocol, fromToken?.chainId, fromChain?.vmType, fromChain, address, fromBalance, isFromNative);
273
+ const shouldSetQuoteParameters = fromToken &&
274
+ toToken &&
275
+ (quoteProtocol !== 'preferV2' ||
276
+ fromChain?.vmType !== 'evm' ||
277
+ explicitDeposit !== undefined);
278
+ const quoteParameters = shouldSetQuoteParameters
279
+ ? {
280
+ user: fromAddressWithFallback,
281
+ originChainId: fromToken.chainId,
282
+ destinationChainId: toToken.chainId,
283
+ originCurrency: fromToken.address,
284
+ destinationCurrency: toToken.address,
285
+ recipient: toAddressWithFallback,
286
+ tradeType,
287
+ appFees: providerOptionsContext.appFees,
288
+ amount: tradeType === 'EXACT_INPUT'
289
+ ? parseUnits(debouncedInputAmountValue, fromToken.decimals).toString()
290
+ : parseUnits(debouncedOutputAmountValue, toToken.decimals).toString(),
291
+ referrer: relayClient?.source ?? undefined,
292
+ useExternalLiquidity,
293
+ useDepositAddress: !fromChainWalletVMSupported || fromToken?.chainId === 1337,
294
+ refundTo: fromToken?.chainId === 1337 ? address : undefined,
295
+ slippageTolerance: slippageTolerance,
296
+ ...(linkedWallet?.vmType === 'bvm' && wallet?.metadata?.publicKey
297
+ ? {
298
+ additionalData: {
299
+ userPublicKey: wallet?.metadata?.publicKey
300
+ }
301
+ }
302
+ : {}),
303
+ protocolVersion: quoteProtocol,
304
+ ...(quoteProtocol === 'preferV2' &&
305
+ explicitDeposit !== undefined && {
306
+ explicitDeposit: explicitDeposit
307
+ })
308
+ }
309
+ : undefined;
310
+ const onQuoteRequested = (options, config) => {
311
+ const interval = get15MinuteInterval();
312
+ const quoteRequestId = sha256({ ...options, interval });
313
+ onAnalyticEvent?.(EventNames.QUOTE_REQUESTED, {
314
+ parameters: options,
315
+ wallet_connector: linkedWallet?.connector,
316
+ chain_id_in: options?.originChainId,
317
+ chain_id_out: options?.destinationChainId,
318
+ http_config: config,
319
+ quote_request_id: quoteRequestId
320
+ });
321
+ };
322
+ const onQuoteReceived = ({ details, steps }, options) => {
323
+ const interval = get15MinuteInterval();
324
+ const quoteRequestId = sha256({ ...options, interval });
325
+ onAnalyticEvent?.(EventNames.QUOTE_RECEIVED, {
326
+ parameters: options,
327
+ wallet_connector: linkedWallet?.connector,
328
+ amount_in: details?.currencyIn?.amountFormatted,
329
+ amount_in_raw: details?.currencyIn?.amount,
330
+ currency_in: details?.currencyIn?.currency?.symbol,
331
+ chain_id_in: details?.currencyIn?.currency?.chainId,
332
+ amount_out: details?.currencyOut?.amountFormatted,
333
+ amount_out_raw: details?.currencyOut?.amount,
334
+ currency_out: details?.currencyOut?.currency?.symbol,
335
+ chain_id_out: details?.currencyOut?.currency?.chainId,
336
+ slippage_tolerance_destination_percentage: details?.slippageTolerance?.destination?.percent,
337
+ slippage_tolerance_origin_percentage: details?.slippageTolerance?.origin?.percent,
338
+ steps,
339
+ quote_request_id: quoteRequestId,
340
+ quote_id: steps ? extractQuoteId(steps) : undefined
341
+ });
342
+ };
343
+ const quoteFetchingEnabled = Boolean(relayClient &&
344
+ ((tradeType === 'EXACT_INPUT' &&
345
+ debouncedInputAmountValue &&
346
+ debouncedInputAmountValue.length > 0 &&
347
+ Number(debouncedInputAmountValue) !== 0) ||
348
+ (tradeType === 'EXPECTED_OUTPUT' &&
349
+ debouncedOutputAmountValue &&
350
+ debouncedOutputAmountValue.length > 0 &&
351
+ Number(debouncedOutputAmountValue) !== 0)) &&
352
+ fromToken !== undefined &&
353
+ toToken !== undefined &&
354
+ !transactionModalOpen &&
355
+ !depositAddressModalOpen);
356
+ const quoteRefetchInterval = !transactionModalOpen &&
357
+ !depositAddressModalOpen &&
358
+ debouncedInputAmountValue === amountInputValue &&
359
+ debouncedOutputAmountValue === amountOutputValue
360
+ ? 12000
361
+ : undefined;
362
+ const handleQuoteError = (e) => {
363
+ const errorMessage = errorToJSON(e?.response?.data?.message ? new Error(e?.response?.data?.message) : e);
364
+ const interval = get15MinuteInterval();
365
+ const quoteRequestId = sha256({ ...quoteParameters, interval });
366
+ onAnalyticEvent?.(EventNames.QUOTE_ERROR, {
367
+ wallet_connector: linkedWallet?.connector,
368
+ error_message: errorMessage,
369
+ parameters: quoteParameters,
370
+ quote_request_id: quoteRequestId,
371
+ status_code: e.response.status ?? e.status ?? ''
372
+ });
373
+ };
374
+ const { data: quote, error: quoteError, isFetching: isFetchingQuote, executeQuote: executeSwap, queryKey: quoteQueryKey } = useQuote(relayClient ? relayClient : undefined, wallet, quoteParameters, onQuoteRequested, onQuoteReceived, {
375
+ refetchOnWindowFocus: false,
376
+ enabled: Boolean(quoteFetchingEnabled && quoteParameters !== undefined),
377
+ refetchInterval: quoteRefetchInterval
378
+ }, handleQuoteError, undefined, useSecureBaseUrl?.(quoteParameters)
379
+ ? providerOptionsContext?.secureBaseUrl
380
+ : undefined);
381
+ const invalidateQuoteQuery = useCallback(() => {
382
+ queryClient.invalidateQueries({ queryKey: quoteQueryKey });
383
+ }, [queryClient, quoteQueryKey]);
384
+ const derivedError = quote ||
385
+ (isFetchingQuote &&
386
+ Boolean(quoteFetchingEnabled && quoteParameters !== undefined))
387
+ ? null
388
+ : quoteError;
389
+ const error = derivedError;
390
+ useDisconnected(address, () => {
391
+ setCustomToAddress(undefined);
392
+ setOriginAddressOverride(undefined);
393
+ setDestinationAddressOverride(undefined);
394
+ });
395
+ useEffect(() => {
396
+ if (tradeType === 'EXACT_INPUT') {
397
+ const amountOut = quote?.details?.currencyOut?.amount ?? '';
398
+ setAmountOutputValue(amountOut !== ''
399
+ ? formatUnits(BigInt(amountOut), Number(quote?.details?.currencyOut?.currency?.decimals ?? 18))
400
+ : '');
401
+ }
402
+ else if (tradeType === 'EXPECTED_OUTPUT') {
403
+ const amountIn = quote?.details?.currencyIn?.amount ?? '';
404
+ setAmountInputValue(amountIn !== ''
405
+ ? formatUnits(BigInt(amountIn), Number(quote?.details?.currencyIn?.currency?.decimals ?? 18))
406
+ : '');
407
+ }
408
+ debouncedAmountInputControls.flush();
409
+ debouncedAmountOutputControls.flush();
410
+ }, [quote, tradeType]);
411
+ useEffect(() => {
412
+ if (useExternalLiquidity &&
413
+ !externalLiquiditySupport.isFetching &&
414
+ !supportsExternalLiquidity) {
415
+ setUseExternalLiquidity(false);
416
+ }
417
+ }, [
418
+ supportsExternalLiquidity,
419
+ useExternalLiquidity,
420
+ externalLiquiditySupport.isFetching
421
+ ]);
422
+ const feeBreakdown = useMemo(() => {
423
+ const chains = relayClient?.chains;
424
+ const fromChain = chains?.find((chain) => chain.id === fromToken?.chainId);
425
+ const toChain = chains?.find((chain) => chain.id === toToken?.chainId);
426
+ return fromToken && toToken && fromChain && toChain && quote
427
+ ? parseFees(toChain, fromChain, quote)
428
+ : null;
429
+ }, [quote, fromToken, toToken, relayClient]);
430
+ const totalAmount = BigInt(quote?.details?.currencyIn?.amount ?? 0n);
431
+ const hasInsufficientBalance = Boolean(!fromBalanceErrorFetching &&
432
+ totalAmount &&
433
+ address &&
434
+ (fromBalance ?? 0n) < totalAmount &&
435
+ !hasAuxiliaryFundsSupport &&
436
+ fromChainWalletVMSupported);
437
+ const fetchQuoteErrorMessage = error
438
+ ? error?.message
439
+ ? error?.message
440
+ : 'Unknown Error'
441
+ : null;
442
+ const fetchQuoteDataErrorMessage = error
443
+ ? error?.response?.data?.message
444
+ ? error?.response?.data.message
445
+ : 'Unknown Error'
446
+ : null;
447
+ const isInsufficientLiquidityError = Boolean(fetchQuoteErrorMessage?.includes('No quotes available'));
448
+ const isCapacityExceededError = fetchQuoteDataErrorMessage?.includes('Amount is higher than the available liquidity') || fetchQuoteDataErrorMessage?.includes('Insufficient relayer liquidity');
449
+ const isCouldNotExecuteError = fetchQuoteDataErrorMessage?.includes('Could not execute');
450
+ const highRelayerServiceFee = isHighRelayerServiceFeeUsd(quote);
451
+ const relayerFeeProportion = calculateRelayerFeeProportionUsd(quote);
452
+ const timeEstimate = calculatePriceTimeEstimate(quote?.details);
453
+ const canonicalTimeEstimate = calculatePriceTimeEstimate(externalLiquiditySupport.data?.details);
454
+ const recipientWalletSupportsChain = useIsWalletCompatible(toChain?.id, recipient, linkedWallets, onAnalyticEvent);
455
+ const isSameCurrencySameRecipientSwap = fromToken?.address === toToken?.address &&
456
+ fromToken?.chainId === toToken?.chainId &&
457
+ address === recipient;
458
+ const ctaCopy = useSwapButtonCta({
459
+ fromToken,
460
+ toToken,
461
+ multiWalletSupportEnabled,
462
+ isValidFromAddress,
463
+ fromChainWalletVMSupported,
464
+ isValidToAddress,
465
+ toChainWalletVMSupported,
466
+ fromChain,
467
+ toChain,
468
+ isSameCurrencySameRecipientSwap,
469
+ debouncedInputAmountValue,
470
+ debouncedOutputAmountValue,
471
+ hasInsufficientBalance,
472
+ isInsufficientLiquidityError,
473
+ quote,
474
+ operation: quote?.details?.operation
475
+ });
476
+ usePreviousValueChange(isCapacityExceededError && supportsExternalLiquidity, !isFetchingQuote && !externalLiquiditySupport.isFetching, (capacityExceeded) => {
477
+ if (capacityExceeded) {
478
+ onAnalyticEvent?.(EventNames.CTA_MAX_CAPACITY_PROMPTED, {
479
+ inputAmount: debouncedInputAmountValue,
480
+ outputAmount: debouncedOutputAmountValue
481
+ });
482
+ }
483
+ });
484
+ const swap = useCallback(async () => {
485
+ let submittedEvents = [];
486
+ const swapErrorHandler = (error, currentSteps) => {
487
+ const errorMessage = errorToJSON(error?.response?.data?.message
488
+ ? new Error(error?.response?.data?.message)
489
+ : error);
490
+ if (error &&
491
+ ((typeof error.message === 'string' &&
492
+ error.message.includes('rejected')) ||
493
+ (typeof error === 'string' && error.includes('rejected')) ||
494
+ (typeof error === 'string' && error.includes('Approval Denied')) ||
495
+ (typeof error === 'string' && error.includes('denied transaction')) ||
496
+ (typeof error.message === 'string' &&
497
+ error.message.includes('Approval Denied')) ||
498
+ (typeof error.message === 'string' &&
499
+ error.message.includes('Plugin Closed')) ||
500
+ (typeof error.message === 'string' &&
501
+ error.message.includes('denied transaction')) ||
502
+ (typeof error.message === 'string' &&
503
+ error.message.includes('Failed to initialize request') &&
504
+ fromChain?.id === 2741)) // Abstract @TODO: remove once privy improves handling rejected transactions
505
+ ) {
506
+ // Close the transaction modal if the user rejects the tx
507
+ setTransactionModalOpen(false);
508
+ onAnalyticEvent?.(EventNames.USER_REJECTED_WALLET, {
509
+ error_message: errorMessage
510
+ });
511
+ return;
512
+ }
513
+ const { step, stepItem } = getCurrentStep(currentSteps);
514
+ const swapEventData = {
515
+ ...getSwapEventData(quote?.details, quote?.fees, currentSteps ?? null, linkedWallet?.connector, quoteParameters),
516
+ error_message: errorMessage
517
+ };
518
+ const isApproval = step?.id === 'approve';
519
+ const errorEvent = isApproval
520
+ ? EventNames.APPROVAL_ERROR
521
+ : EventNames.DEPOSIT_ERROR;
522
+ //Filter out receipt/deposit transaction errors, those are approval/deposit errors
523
+ const isTransactionConfirmationError = (error &&
524
+ typeof error.message === 'string' &&
525
+ error.message.includes('TransactionConfirmationError')) ||
526
+ (error.name && error.name.includes('TransactionConfirmationError'));
527
+ if (stepItem?.receipt &&
528
+ stepItem.check &&
529
+ !isTransactionConfirmationError &&
530
+ (typeof stepItem.receipt === 'object' && 'status' in stepItem.receipt
531
+ ? stepItem.receipt.status !== 'reverted'
532
+ : true) &&
533
+ (!stepItem.checkStatus || stepItem.checkStatus !== 'unknown')) {
534
+ //In some cases there's a race condition where an error is thrown before the steps get a chance to call
535
+ //the callback which triggers the success event. This is a workaround to ensure the success event is triggered when
536
+ //we have a receipt and require a fill check if we haven't already send the success event.
537
+ const successEvent = isApproval
538
+ ? EventNames.APPROVAL_SUCCESS
539
+ : EventNames.DEPOSIT_SUCCESS;
540
+ if (!submittedEvents.includes(successEvent)) {
541
+ onAnalyticEvent?.(successEvent, swapEventData);
542
+ submittedEvents.push(successEvent);
543
+ //To preserve the order of events we need to delay sending the fill error event but mark that we did send it to avoid duplicates
544
+ setTimeout(() => {
545
+ onAnalyticEvent?.(EventNames.FILL_ERROR, swapEventData);
546
+ }, 20);
547
+ }
548
+ else {
549
+ onAnalyticEvent?.(EventNames.FILL_ERROR, swapEventData);
550
+ }
551
+ }
552
+ else if (!stepItem?.receipt ||
553
+ (typeof stepItem.receipt === 'object' &&
554
+ 'status' in stepItem.receipt &&
555
+ stepItem.receipt.status === 'reverted')) {
556
+ onAnalyticEvent?.(errorEvent, swapEventData);
557
+ }
558
+ else {
559
+ onAnalyticEvent?.(EventNames.SWAP_ERROR, swapEventData);
560
+ }
561
+ setSwapError(errorMessage);
562
+ onSwapError?.(errorMessage, { ...quote, steps: currentSteps });
563
+ };
564
+ try {
565
+ const swapEventData = getSwapEventData(quote?.details, quote?.fees, quote?.steps ? quote?.steps : null, linkedWallet?.connector, quoteParameters);
566
+ onAnalyticEvent?.(EventNames.SWAP_CTA_CLICKED, swapEventData);
567
+ setWaitingForSteps(true);
568
+ if (!executeSwap) {
569
+ throw 'Missing a quote';
570
+ }
571
+ if (!wallet && !walletClient.data) {
572
+ throw 'Missing a wallet';
573
+ }
574
+ setSteps(quote?.steps);
575
+ setQuoteInProgress(quote);
576
+ setTransactionModalOpen(true);
577
+ const _wallet = wallet ?? adaptViemWallet(walletClient.data);
578
+ const activeWalletChainId = await _wallet?.getChainId();
579
+ const activeWalletChain = relayClient?.chains?.find((chain) => chain.id === activeWalletChainId);
580
+ let targetChainId = fromToken?.chainId;
581
+ //Special case for Hyperliquid, to sign txs on an evm chain
582
+ if (fromToken?.chainId === 1337) {
583
+ targetChainId =
584
+ activeWalletChain?.vmType !== 'evm' ? 1 : activeWalletChainId;
585
+ }
586
+ if (fromToken && targetChainId && targetChainId !== activeWalletChainId) {
587
+ onAnalyticEvent?.(EventNames.SWAP_SWITCH_NETWORK, {
588
+ activeWalletChainId,
589
+ ...swapEventData
590
+ });
591
+ await _wallet?.switchChain(targetChainId);
592
+ }
593
+ let _currentSteps = undefined;
594
+ const execPromise = executeSwap(({ steps: currentSteps }) => {
595
+ setSteps(currentSteps);
596
+ _currentSteps = currentSteps;
597
+ const { step, stepItem } = getCurrentStep(currentSteps);
598
+ const swapEventData = getSwapEventData(quote?.details, quote?.fees, currentSteps, linkedWallet?.connector, quoteParameters);
599
+ if (step && stepItem) {
600
+ //@ts-ignore
601
+ const isApproval = step.id === 'approve' || step.id === 'approval';
602
+ let submittedEvent = isApproval
603
+ ? EventNames.APPROVAL_SUBMITTED
604
+ : EventNames.DEPOSIT_SUBMITTED;
605
+ const successEvent = isApproval
606
+ ? EventNames.APPROVAL_SUCCESS
607
+ : EventNames.DEPOSIT_SUCCESS;
608
+ const isBatchTransaction = Boolean(Array.isArray(step.items) &&
609
+ step.items.length > 1 &&
610
+ wallet?.handleBatchTransactionStep);
611
+ if (!isApproval && isBatchTransaction) {
612
+ submittedEvent = EventNames.BATCH_TX_SUBMITTED;
613
+ }
614
+ if (!submittedEvents.includes(submittedEvent) &&
615
+ !stepItem.receipt &&
616
+ stepItem?.txHashes &&
617
+ stepItem?.txHashes?.length > 0) {
618
+ submittedEvents.push(submittedEvent);
619
+ onAnalyticEvent?.(submittedEvent, swapEventData);
620
+ }
621
+ else if (!submittedEvents.includes(successEvent) &&
622
+ ((stepItem.receipt &&
623
+ !(typeof stepItem.receipt === 'object' &&
624
+ 'status' in stepItem.receipt &&
625
+ stepItem.receipt.status === 'reverted')) ||
626
+ stepItem.checkStatus === 'pending')) {
627
+ onAnalyticEvent?.(successEvent, swapEventData);
628
+ submittedEvents.push(successEvent);
629
+ }
630
+ if (stepItem.status === 'complete' &&
631
+ stepItem.check &&
632
+ !submittedEvents.includes(EventNames.FILL_SUCCESS)) {
633
+ //Sometimes a fill may be quicker than the tx receipt is available, so we need to handle this scenario
634
+ if (!submittedEvents.includes(EventNames.DEPOSIT_SUCCESS) &&
635
+ !isBatchTransaction) {
636
+ onAnalyticEvent?.(EventNames.DEPOSIT_SUCCESS, swapEventData);
637
+ submittedEvents.push(EventNames.DEPOSIT_SUCCESS);
638
+ //To preserve the order of events we need to delay sending the fill success event but mark that we did send it to avoid duplicates
639
+ setTimeout(() => {
640
+ onAnalyticEvent?.(EventNames.FILL_SUCCESS, swapEventData);
641
+ }, 20);
642
+ }
643
+ else {
644
+ onAnalyticEvent?.(EventNames.FILL_SUCCESS, swapEventData);
645
+ }
646
+ submittedEvents.push(EventNames.FILL_SUCCESS);
647
+ }
648
+ }
649
+ else if (currentSteps?.every((step) => step.items?.every((item) => item.status === 'complete')) &&
650
+ !submittedEvents.includes(EventNames.FILL_SUCCESS)) {
651
+ //Sometimes a fill may be quicker than the tx receipt is available, so we need to handle this scenario
652
+ if (!submittedEvents.includes(EventNames.DEPOSIT_SUCCESS) &&
653
+ !submittedEvents.includes(EventNames.BATCH_TX_SUBMITTED)) {
654
+ onAnalyticEvent?.(EventNames.DEPOSIT_SUCCESS, swapEventData);
655
+ submittedEvents.push(EventNames.DEPOSIT_SUCCESS);
656
+ //To preserve the order of events we need to delay sending the fill success event but mark that we did send it to avoid duplicates
657
+ setTimeout(() => {
658
+ onAnalyticEvent?.(EventNames.FILL_SUCCESS, swapEventData);
659
+ }, 20);
660
+ }
661
+ else {
662
+ onAnalyticEvent?.(EventNames.FILL_SUCCESS, swapEventData);
663
+ }
664
+ submittedEvents.push(EventNames.FILL_SUCCESS);
665
+ }
666
+ });
667
+ // Store the AbortController for potential cancellation immediately
668
+ if (execPromise &&
669
+ typeof execPromise === 'object' &&
670
+ 'abortController' in execPromise) {
671
+ setAbortController(execPromise.abortController);
672
+ }
673
+ execPromise
674
+ ?.catch((error) => {
675
+ swapErrorHandler(error, _currentSteps);
676
+ })
677
+ .finally(() => {
678
+ setWaitingForSteps(false);
679
+ setAbortController(null);
680
+ invalidateBalanceQueries();
681
+ });
682
+ }
683
+ catch (error) {
684
+ swapErrorHandler(error);
685
+ setWaitingForSteps(false);
686
+ }
687
+ // eslint-disable-next-line react-hooks/exhaustive-deps
688
+ }, [
689
+ relayClient,
690
+ address,
691
+ connector,
692
+ wallet,
693
+ walletClient,
694
+ fromToken,
695
+ toToken,
696
+ customToAddress,
697
+ recipient,
698
+ debouncedInputAmountValue,
699
+ debouncedOutputAmountValue,
700
+ tradeType,
701
+ useExternalLiquidity,
702
+ waitingForSteps,
703
+ executeSwap,
704
+ setSteps,
705
+ setQuoteInProgress,
706
+ invalidateBalanceQueries,
707
+ linkedWallet,
708
+ abortController
709
+ ]);
710
+ return (_jsx(_Fragment, { children: children({
711
+ quote,
712
+ steps,
713
+ setSteps,
714
+ swap,
715
+ transactionModalOpen,
716
+ feeBreakdown,
717
+ fromToken,
718
+ setFromToken,
719
+ toToken,
720
+ setToToken,
721
+ swapError,
722
+ error,
723
+ toDisplayName,
724
+ address,
725
+ originAddressOverride,
726
+ setOriginAddressOverride,
727
+ recipient,
728
+ destinationAddressOverride,
729
+ customToAddress,
730
+ setCustomToAddress,
731
+ setDestinationAddressOverride,
732
+ tradeType,
733
+ setTradeType,
734
+ details,
735
+ isSameCurrencySameRecipientSwap,
736
+ allowUnsupportedOrigin,
737
+ setAllowUnsupportedOrigin,
738
+ allowUnsupportedRecipient,
739
+ setAllowUnsupportedRecipient,
740
+ debouncedInputAmountValue,
741
+ debouncedAmountInputControls,
742
+ setAmountInputValue,
743
+ amountInputValue,
744
+ amountOutputValue,
745
+ debouncedOutputAmountValue,
746
+ debouncedAmountOutputControls,
747
+ setAmountOutputValue,
748
+ toBalance,
749
+ toBalancePending,
750
+ isLoadingToBalance,
751
+ isFetchingQuote,
752
+ isLoadingFromBalance,
753
+ fromBalance,
754
+ fromBalancePending,
755
+ highRelayerServiceFee,
756
+ relayerFeeProportion,
757
+ hasInsufficientBalance,
758
+ isInsufficientLiquidityError,
759
+ isCapacityExceededError,
760
+ isCouldNotExecuteError,
761
+ ctaCopy,
762
+ isFromNative,
763
+ useExternalLiquidity,
764
+ slippageTolerance: currentSlippageTolerance,
765
+ supportsExternalLiquidity,
766
+ timeEstimate,
767
+ canonicalTimeEstimate,
768
+ fetchingExternalLiquiditySupport: externalLiquiditySupport.isFetching,
769
+ isSvmSwap,
770
+ isBvmSwap,
771
+ isValidFromAddress,
772
+ isValidToAddress,
773
+ supportedWalletVMs,
774
+ fromChainWalletVMSupported,
775
+ toChainWalletVMSupported,
776
+ isRecipientLinked,
777
+ recipientWalletSupportsChain,
778
+ invalidateBalanceQueries,
779
+ invalidateQuoteQuery,
780
+ setUseExternalLiquidity,
781
+ setDetails,
782
+ setSwapError,
783
+ quoteInProgress,
784
+ setQuoteInProgress,
785
+ linkedWallet,
786
+ quoteParameters,
787
+ abortController,
788
+ fromTokenPriceData,
789
+ toTokenPriceData,
790
+ isLoadingFromTokenPrice,
791
+ isLoadingToTokenPrice
792
+ }) }));
793
+ };
794
+ export default TokenWidgetRenderer;
795
+ //# sourceMappingURL=TokenWidgetRenderer.js.map