From 9764b8bfc48ff53fe25e8c2717549e69dd06df33 Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Wed, 7 Jan 2026 15:39:47 +0800 Subject: [PATCH 01/33] feat: easy update --- .../PrivateKeySpeedBumpModal.test.tsx.snap | 6 +- .../FavoriteHeaderRow.test.tsx.snap | 2 +- .../SelectionCircle.test.tsx.snap | 10 +- .../GenericImportForm.test.tsx.snap | 6 +- .../CollectionPreviewCard.test.tsx.snap | 4 +- .../__snapshots__/BackupScreen.test.tsx.snap | 20 +-- .../dark.svg | 2 +- .../light.svg | 2 +- .../dark.svg | 30 ++-- .../light.svg | 30 ++-- .../mobile-dark.svg | 30 ++-- .../mobile-light.svg | 30 ++-- .../web/src/assets/svg/demo-wallet-emblem.svg | 2 +- .../OffchainActivityModal.test.tsx.snap | 12 +- .../OffchainOrderLineItem.test.tsx.snap | 4 +- .../__snapshots__/Pending.test.tsx.snap | 16 +- .../components/NavBar/CompanyMenu/index.tsx | 88 ++------- .../NavBar/PreferencesMenu/Preferences.tsx | 8 +- .../components/NavBar/Tabs/TabsContent.tsx | 170 +++++++++--------- apps/web/src/components/NavBar/index.tsx | 10 +- .../PoolDetails/PoolDetailsStats.test.tsx | 2 +- .../PoolDetailsHeader.test.tsx.snap | 4 +- .../PoolDetailsLink.test.tsx.snap | 8 +- .../PoolDetailsStats.test.tsx.snap | 2 +- .../PoolDetailsTransactionTable.test.tsx.snap | 8 +- .../TokenDetailsPoolsTable.test.tsx.snap | 4 +- apps/web/src/components/Web3Status/index.tsx | 50 ++++-- .../__snapshots__/SwapDetails.test.tsx.snap | 4 +- apps/web/src/components/swap/styled.tsx | 7 +- .../AnimatedStyledBanner/Emblems/EmblemA.tsx | 2 +- .../AnimatedStyledBanner/Emblems/EmblemB.tsx | 2 +- .../AnimatedStyledBanner/Emblems/EmblemC.tsx | 2 +- .../AnimatedStyledBanner/Emblems/EmblemD.tsx | 2 +- .../AnimatedStyledBanner/Emblems/EmblemE.tsx | 2 +- .../AnimatedStyledBanner/Emblems/EmblemF.tsx | 2 +- .../AnimatedStyledBanner/Emblems/EmblemG.tsx | 2 +- .../AnimatedStyledBanner/Emblems/EmblemH.tsx | 2 +- apps/web/src/pages/Positions/TopPools.tsx | 4 +- apps/web/src/pages/Positions/index.tsx | 14 +- apps/web/src/pages/RouteDefinitions.tsx | 53 +++--- .../ProviderConnectedView.test.tsx.snap | 4 +- apps/web/src/pages/Swap/index.tsx | 81 +++++---- apps/web/src/theme/components/ThemeToggle.tsx | 8 +- .../arrow-down-circle-filled-with-border.svg | 2 +- packages/ui/src/assets/icons/coin-stack.svg | 20 +-- packages/ui/src/assets/icons/compass.svg | 2 +- .../ui/src/assets/icons/crosschain-icon.svg | 2 +- packages/ui/src/assets/icons/hskswap-icon.svg | 13 ++ packages/ui/src/assets/icons/hskswap-text.svg | 9 + packages/ui/src/assets/icons/one-to-one.svg | 2 +- packages/ui/src/assets/icons/rocket.svg | 2 +- packages/ui/src/assets/icons/smart-wallet.svg | 4 +- packages/ui/src/assets/icons/stopwatch.svg | 2 +- .../ui/src/assets/icons/uniswapX-generic.svg | 2 +- .../icons/ArrowDownCircleFilledWithBorder.tsx | 2 +- .../ui/src/components/icons/CoinStack.tsx | 2 +- packages/ui/src/components/icons/Compass.tsx | 2 +- .../src/components/icons/CrosschainIcon.tsx | 2 +- packages/ui/src/components/icons/Magic.tsx | 2 +- packages/ui/src/components/icons/OneToOne.tsx | 2 +- packages/ui/src/components/icons/Rocket.tsx | 2 +- .../src/components/icons/SettingsCustom.tsx | 35 ++++ .../ui/src/components/icons/SmartWallet.tsx | 2 +- .../ui/src/components/icons/Stopwatch.tsx | 2 +- .../src/components/icons/UniswapXGeneric.tsx | 2 +- packages/ui/src/theme/color/colors.ts | 12 +- .../AmountInputPresets/AmountInputPresets.tsx | 5 +- .../CurrencyInputPanelHeader.tsx | 22 ++- .../__snapshots__/PasteButton.test.tsx.snap | 6 +- .../__snapshots__/LearnMoreLink.test.tsx.snap | 2 +- .../settings/TransactionSettings.tsx | 39 +++- .../settings/TransactionSettingsButton.tsx | 24 ++- .../TransactionSettingsButtonWithSlippage.tsx | 6 +- .../SwapFormButton/SwapFormButton.tsx | 68 +++++-- .../SwapFormCurrencyInputPanel.tsx | 1 + .../SwapFormCurrencyOutputPanel.tsx | 15 +- .../form/SwapFormScreen/SwapFormScreen.tsx | 36 +++- .../hooks/useCurrencyInputFocusedStyle.ts | 4 +- .../WalletPreviewCard.test.tsx.snap | 4 +- .../__snapshots__/LinkButton.test.tsx.snap | 4 +- 80 files changed, 652 insertions(+), 462 deletions(-) create mode 100644 packages/ui/src/assets/icons/hskswap-icon.svg create mode 100644 packages/ui/src/assets/icons/hskswap-text.svg create mode 100644 packages/ui/src/components/icons/SettingsCustom.tsx diff --git a/apps/mobile/src/components/RestoreWalletModal/__snapshots__/PrivateKeySpeedBumpModal.test.tsx.snap b/apps/mobile/src/components/RestoreWalletModal/__snapshots__/PrivateKeySpeedBumpModal.test.tsx.snap index a7a02717069..6a097d8735c 100644 --- a/apps/mobile/src/components/RestoreWalletModal/__snapshots__/PrivateKeySpeedBumpModal.test.tsx.snap +++ b/apps/mobile/src/components/RestoreWalletModal/__snapshots__/PrivateKeySpeedBumpModal.test.tsx.snap @@ -437,7 +437,7 @@ exports[`PrivateKeySpeedBumpModal renders correctly 1`] = ` disabled={false} focusVisibleStyle={ { - "backgroundColor": "#E500A5", + "backgroundColor": "#3d7fff", } } forwardedRef={[Function]} @@ -462,7 +462,7 @@ exports[`PrivateKeySpeedBumpModal renders correctly 1`] = ` { "alignItems": "center", "alignSelf": "stretch", - "backgroundColor": "#FF37C7", + "backgroundColor": "#4177e2", "borderBottomColor": "transparent", "borderBottomLeftRadius": 16, "borderBottomRightRadius": 16, @@ -504,7 +504,7 @@ exports[`PrivateKeySpeedBumpModal renders correctly 1`] = ` { "alignItems": "center", "alignSelf": "stretch", - "backgroundColor": "#FF37C7", + "backgroundColor": "#4177e2", "borderBottomColor": "transparent", "borderBottomLeftRadius": 16, "borderBottomRightRadius": 16, diff --git a/apps/mobile/src/components/explore/__snapshots__/FavoriteHeaderRow.test.tsx.snap b/apps/mobile/src/components/explore/__snapshots__/FavoriteHeaderRow.test.tsx.snap index da2b061869e..d18613f43ac 100644 --- a/apps/mobile/src/components/explore/__snapshots__/FavoriteHeaderRow.test.tsx.snap +++ b/apps/mobile/src/components/explore/__snapshots__/FavoriteHeaderRow.test.tsx.snap @@ -100,7 +100,7 @@ exports[`FavoriteHeaderRow when editing renders without error 1`] = ` maxFontSizeMultiplier={1.2} style={ { - "color": "#FF37C7", + "color": "#4177e2", "fontFamily": "Basel Grotesk", "fontSize": 17, "fontWeight": "500", diff --git a/apps/mobile/src/components/input/__snapshots__/SelectionCircle.test.tsx.snap b/apps/mobile/src/components/input/__snapshots__/SelectionCircle.test.tsx.snap index b29ce1681af..20dedf53a4a 100644 --- a/apps/mobile/src/components/input/__snapshots__/SelectionCircle.test.tsx.snap +++ b/apps/mobile/src/components/input/__snapshots__/SelectionCircle.test.tsx.snap @@ -5,16 +5,16 @@ exports[`renders selection circle 1`] = ` style={ { "alignItems": "center", - "borderBottomColor": "#FF37C7", + "borderBottomColor": "#4177e2", "borderBottomLeftRadius": 999999, "borderBottomRightRadius": 999999, "borderBottomWidth": 1, - "borderLeftColor": "#FF37C7", + "borderLeftColor": "#4177e2", "borderLeftWidth": 1, - "borderRightColor": "#FF37C7", + "borderRightColor": "#4177e2", "borderRightWidth": 1, "borderStyle": "solid", - "borderTopColor": "#FF37C7", + "borderTopColor": "#4177e2", "borderTopLeftRadius": 999999, "borderTopRightRadius": 999999, "borderTopWidth": 1, @@ -28,7 +28,7 @@ exports[`renders selection circle 1`] = ` - + diff --git a/apps/web/src/assets/images/portfolio-connect-wallet-banner-grid/light.svg b/apps/web/src/assets/images/portfolio-connect-wallet-banner-grid/light.svg index 4a2adf55f55..5115d05a0bc 100644 --- a/apps/web/src/assets/images/portfolio-connect-wallet-banner-grid/light.svg +++ b/apps/web/src/assets/images/portfolio-connect-wallet-banner-grid/light.svg @@ -4,7 +4,7 @@ - + diff --git a/apps/web/src/assets/images/portfolio-page-disconnected-preview/dark.svg b/apps/web/src/assets/images/portfolio-page-disconnected-preview/dark.svg index 1ae6e3cb76e..b912375daff 100644 --- a/apps/web/src/assets/images/portfolio-page-disconnected-preview/dark.svg +++ b/apps/web/src/assets/images/portfolio-page-disconnected-preview/dark.svg @@ -3,13 +3,13 @@ - - + + - + @@ -85,18 +85,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/apps/web/src/assets/images/portfolio-page-disconnected-preview/light.svg b/apps/web/src/assets/images/portfolio-page-disconnected-preview/light.svg index 8e9c0579fe4..8bc51215777 100644 --- a/apps/web/src/assets/images/portfolio-page-disconnected-preview/light.svg +++ b/apps/web/src/assets/images/portfolio-page-disconnected-preview/light.svg @@ -3,13 +3,13 @@ - - + + - + @@ -85,18 +85,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/apps/web/src/assets/images/portfolio-page-disconnected-preview/mobile-dark.svg b/apps/web/src/assets/images/portfolio-page-disconnected-preview/mobile-dark.svg index 843ed723d5d..d1819f6a782 100644 --- a/apps/web/src/assets/images/portfolio-page-disconnected-preview/mobile-dark.svg +++ b/apps/web/src/assets/images/portfolio-page-disconnected-preview/mobile-dark.svg @@ -4,13 +4,13 @@ - - + + - + @@ -81,18 +81,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/apps/web/src/assets/images/portfolio-page-disconnected-preview/mobile-light.svg b/apps/web/src/assets/images/portfolio-page-disconnected-preview/mobile-light.svg index 9530c38d4e9..e3b463c6dcc 100644 --- a/apps/web/src/assets/images/portfolio-page-disconnected-preview/mobile-light.svg +++ b/apps/web/src/assets/images/portfolio-page-disconnected-preview/mobile-light.svg @@ -4,13 +4,13 @@ - - + + - + @@ -81,18 +81,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/apps/web/src/assets/svg/demo-wallet-emblem.svg b/apps/web/src/assets/svg/demo-wallet-emblem.svg index 1839d363511..1b6db501ef0 100644 --- a/apps/web/src/assets/svg/demo-wallet-emblem.svg +++ b/apps/web/src/assets/svg/demo-wallet-emblem.svg @@ -1,3 +1,3 @@ - + diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/__snapshots__/OffchainActivityModal.test.tsx.snap b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/__snapshots__/OffchainActivityModal.test.tsx.snap index 67a62366db7..f7607dc28ed 100644 --- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/__snapshots__/OffchainActivityModal.test.tsx.snap +++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/__snapshots__/OffchainActivityModal.test.tsx.snap @@ -76,8 +76,8 @@ exports[`OrderContent > should render without error, filled order 1`] = ` text-decoration: none; cursor: pointer; transition-duration: 125ms; - color: #FF37C7; - stroke: #FF37C7; + color: #4177e2; + stroke: #4177e2; font-weight: 500; } @@ -487,8 +487,8 @@ exports[`OrderContent > should render without error, limit order 1`] = ` text-decoration: none; cursor: pointer; transition-duration: 125ms; - color: #FF37C7; - stroke: #FF37C7; + color: #4177e2; + stroke: #4177e2; font-weight: 500; } @@ -960,8 +960,8 @@ exports[`OrderContent > should render without error, open order 1`] = ` text-decoration: none; cursor: pointer; transition-duration: 125ms; - color: #FF37C7; - stroke: #FF37C7; + color: #4177e2; + stroke: #4177e2; font-weight: 500; } diff --git a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/__snapshots__/OffchainOrderLineItem.test.tsx.snap b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/__snapshots__/OffchainOrderLineItem.test.tsx.snap index 8324810cefc..e53d9d12139 100644 --- a/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/__snapshots__/OffchainOrderLineItem.test.tsx.snap +++ b/apps/web/src/components/AccountDrawer/MiniPortfolio/Activity/__snapshots__/OffchainOrderLineItem.test.tsx.snap @@ -135,8 +135,8 @@ exports[`OffchainOrderLineItem > should render type TRANSACTION_ID 1`] = ` text-decoration: none; cursor: pointer; transition-duration: 125ms; - color: #FF37C7; - stroke: #FF37C7; + color: #4177e2; + stroke: #4177e2; font-weight: 500; } diff --git a/apps/web/src/components/ConfirmSwapModal/__snapshots__/Pending.test.tsx.snap b/apps/web/src/components/ConfirmSwapModal/__snapshots__/Pending.test.tsx.snap index 98a92eb2482..bf4faf952e6 100644 --- a/apps/web/src/components/ConfirmSwapModal/__snapshots__/Pending.test.tsx.snap +++ b/apps/web/src/components/ConfirmSwapModal/__snapshots__/Pending.test.tsx.snap @@ -90,8 +90,8 @@ exports[`Pending - classic trade titles > renders classic trade correctly, with text-decoration: none; cursor: pointer; transition-duration: 125ms; - color: #FF37C7; - stroke: #FF37C7; + color: #4177e2; + stroke: #4177e2; font-weight: 500; } @@ -161,7 +161,7 @@ exports[`Pending - classic trade titles > renders classic trade correctly, with > @@ -346,8 +346,8 @@ exports[`Pending - classic trade titles > renders classic trade correctly, with text-decoration: none; cursor: pointer; transition-duration: 125ms; - color: #FF37C7; - stroke: #FF37C7; + color: #4177e2; + stroke: #4177e2; font-weight: 500; } @@ -892,7 +892,7 @@ exports[`Pending - uniswapX trade titles > renders limit order correctly, with a > @@ -1095,8 +1095,8 @@ exports[`Pending - uniswapX trade titles > renders limit order correctly, with a text-decoration: none; cursor: pointer; transition-duration: 125ms; - color: #FF37C7; - stroke: #FF37C7; + color: #4177e2; + stroke: #4177e2; font-weight: 500; } diff --git a/apps/web/src/components/NavBar/CompanyMenu/index.tsx b/apps/web/src/components/NavBar/CompanyMenu/index.tsx index a707c30f888..5be68aceb45 100644 --- a/apps/web/src/components/NavBar/CompanyMenu/index.tsx +++ b/apps/web/src/components/NavBar/CompanyMenu/index.tsx @@ -1,76 +1,26 @@ -import { ArrowChangeDown } from 'components/Icons/ArrowChangeDown' -import { NavIcon } from 'components/Logo/NavIcon' -import { MenuDropdown } from 'components/NavBar/CompanyMenu/MenuDropdown' -import { MobileMenuDrawer } from 'components/NavBar/CompanyMenu/MobileMenuDrawer' -import { useIsMobileDrawer } from 'components/NavBar/ScreenSizes' -import { useCallback, useEffect, useRef, useState } from 'react' -import { Link, useLocation } from 'react-router' -import { Flex, Popover, styled, Text, useIsTouchDevice, useMedia } from 'ui/src' -import { Hamburger } from 'ui/src/components/icons/Hamburger' +import { Link } from 'react-router' +import { Flex } from 'ui/src' +import { ReactComponent as HskswapIcon } from 'ui/src/assets/icons/hskswap-icon.svg' +import { ReactComponent as HskswapText } from 'ui/src/assets/icons/hskswap-text.svg' import { TestID } from 'uniswap/src/test/fixtures/testIDs' -const ArrowDownWrapper = styled(Text, { - color: '$neutral2', - '$group-hover': { color: '$neutral1' }, - variants: { - open: { - true: { color: '$neutral1' }, - }, - }, -}) - export function CompanyMenu() { - const popoverRef = useRef(null) - const media = useMedia() - const isMobileDrawer = useIsMobileDrawer() - const isLargeScreen = !media.xxl - const location = useLocation() - const [isOpen, setIsOpen] = useState(false) - - // biome-ignore lint/correctness/useExhaustiveDependencies: +popoverRef - const closeMenu = useCallback(() => { - popoverRef.current?.close() - }, [popoverRef]) - // biome-ignore lint/correctness/useExhaustiveDependencies: location dependency is sufficient for this effect - useEffect(() => { - // Immediately reset state to prevent flash during transitions - setIsOpen(false) - closeMenu() - }, [location, closeMenu]) - - const isTouchDevice = useIsTouchDevice() - return ( - - - - - - - {isLargeScreen && ( - - Uniswap - - )} - - - {(media.md || isTouchDevice) && } - {!media.md && !isTouchDevice && ( - - - - )} + + {/* */} + + + + + - - {isMobileDrawer ? : } - + {/* */} + ) } diff --git a/apps/web/src/components/NavBar/PreferencesMenu/Preferences.tsx b/apps/web/src/components/NavBar/PreferencesMenu/Preferences.tsx index b0ceecbae84..6136686e31b 100644 --- a/apps/web/src/components/NavBar/PreferencesMenu/Preferences.tsx +++ b/apps/web/src/components/NavBar/PreferencesMenu/Preferences.tsx @@ -64,10 +64,10 @@ export function PreferenceSettings({ const languageInfo = useLanguageInfo(activeLanguage) const items: SettingItem[] = [ - { - label: showThemeLabel ? t('themeToggle.theme') : undefined, - component: , - }, + // { + // label: showThemeLabel ? t('themeToggle.theme') : undefined, + // component: , + // }, { label: t('common.language'), component: ( diff --git a/apps/web/src/components/NavBar/Tabs/TabsContent.tsx b/apps/web/src/components/NavBar/Tabs/TabsContent.tsx index 4e3a75e2b94..325887ecf33 100644 --- a/apps/web/src/components/NavBar/Tabs/TabsContent.tsx +++ b/apps/web/src/components/NavBar/Tabs/TabsContent.tsx @@ -44,7 +44,7 @@ export const useTabsContent = (): TabsSection[] => { { title: t('common.trade'), href: '/swap', - isActive: pathname.startsWith('/swap') || pathname.startsWith('/limit') || pathname.startsWith('/send'), + isActive: pathname === '/' || pathname.startsWith('/swap') || pathname.startsWith('/send'), icon: , items: [ { @@ -53,46 +53,46 @@ export const useTabsContent = (): TabsSection[] => { href: '/swap', internal: true, }, - { - label: t('swap.limit'), - icon: , - href: '/limit', - internal: true, - }, - { - label: t('common.buy.label'), - icon: , - href: '/buy', - internal: true, - }, - ...(isFiatOffRampEnabled - ? [ - { - label: t('common.sell.label'), - icon: , - href: '/sell', - internal: true, - }, - ] - : []), - ], - }, - { - title: t('common.explore'), - href: '/explore', - isActive: pathname.startsWith('/explore') || pathname.startsWith('/nfts'), - icon: , - items: [ - { label: t('common.tokens'), href: '/explore/tokens', internal: true }, - { label: t('common.pools'), href: '/explore/pools', internal: true }, - { - label: t('common.transactions'), - href: '/explore/transactions', - internal: true, - }, - ...(isToucanEnabled ? [{ label: 'Toucan', href: '/explore/auctions', internal: true }] : []), + // { + // label: t('swap.limit'), + // icon: , + // href: '/limit', + // internal: true, + // }, + // { + // label: t('common.buy.label'), + // icon: , + // href: '/buy', + // internal: true, + // }, + // ...(isFiatOffRampEnabled + // ? [ + // { + // label: t('common.sell.label'), + // icon: , + // href: '/sell', + // internal: true, + // }, + // ] + // : []), ], }, + // { + // title: t('common.explore'), + // href: '/explore', + // isActive: pathname.startsWith('/explore') || pathname.startsWith('/nfts'), + // icon: , + // items: [ + // { label: t('common.tokens'), href: '/explore/tokens', internal: true }, + // { label: t('common.pools'), href: '/explore/pools', internal: true }, + // { + // label: t('common.transactions'), + // href: '/explore/transactions', + // internal: true, + // }, + // ...(isToucanEnabled ? [{ label: 'Toucan', href: '/explore/auctions', internal: true }] : []), + // ], + // }, { title: t('common.pool'), href: '/positions', @@ -111,51 +111,51 @@ export const useTabsContent = (): TabsSection[] => { }, ], }, - ...(isPortfolioPageEnabled - ? [ - { - title: t('common.portfolio'), - href: buildPortfolioUrl(PortfolioTab.Overview, portfolioChainId), - isActive: pathname.startsWith('/portfolio'), - icon: , - items: [ - { - label: t('portfolio.overview.title'), - href: buildPortfolioUrl(PortfolioTab.Overview, portfolioChainId), - internal: true, - elementName: ElementName.NavbarPortfolioDropdownOverview, - }, - { - label: t('portfolio.tokens.title'), - href: buildPortfolioUrl(PortfolioTab.Tokens, portfolioChainId), - internal: true, - elementName: ElementName.NavbarPortfolioDropdownTokens, - }, - ...(isPortfolioDefiTabEnabled - ? [ - { - label: t('portfolio.defi.title'), - href: buildPortfolioUrl(PortfolioTab.Defi, portfolioChainId), - internal: true, - elementName: ElementName.NavbarPortfolioDropdownDefi, - }, - ] - : []), - { - label: t('portfolio.nfts.title'), - href: buildPortfolioUrl(PortfolioTab.Nfts, portfolioChainId), - internal: true, - elementName: ElementName.NavbarPortfolioDropdownNfts, - }, - { - label: t('portfolio.activity.title'), - href: buildPortfolioUrl(PortfolioTab.Activity, portfolioChainId), - internal: true, - elementName: ElementName.NavbarPortfolioDropdownActivity, - }, - ], - }, - ] - : []), + // ...(isPortfolioPageEnabled + // ? [ + // { + // title: t('common.portfolio'), + // href: buildPortfolioUrl(PortfolioTab.Overview, portfolioChainId), + // isActive: pathname.startsWith('/portfolio'), + // icon: , + // items: [ + // { + // label: t('portfolio.overview.title'), + // href: buildPortfolioUrl(PortfolioTab.Overview, portfolioChainId), + // internal: true, + // elementName: ElementName.NavbarPortfolioDropdownOverview, + // }, + // { + // label: t('portfolio.tokens.title'), + // href: buildPortfolioUrl(PortfolioTab.Tokens, portfolioChainId), + // internal: true, + // elementName: ElementName.NavbarPortfolioDropdownTokens, + // }, + // ...(isPortfolioDefiTabEnabled + // ? [ + // { + // label: t('portfolio.defi.title'), + // href: buildPortfolioUrl(PortfolioTab.Defi, portfolioChainId), + // internal: true, + // elementName: ElementName.NavbarPortfolioDropdownDefi, + // }, + // ] + // : []), + // { + // label: t('portfolio.nfts.title'), + // href: buildPortfolioUrl(PortfolioTab.Nfts, portfolioChainId), + // internal: true, + // elementName: ElementName.NavbarPortfolioDropdownNfts, + // }, + // { + // label: t('portfolio.activity.title'), + // href: buildPortfolioUrl(PortfolioTab.Activity, portfolioChainId), + // internal: true, + // elementName: ElementName.NavbarPortfolioDropdownActivity, + // }, + // ], + // }, + // ] + // : []), ] } diff --git a/apps/web/src/components/NavBar/index.tsx b/apps/web/src/components/NavBar/index.tsx index 232012386e6..69d4ec0a150 100644 --- a/apps/web/src/components/NavBar/index.tsx +++ b/apps/web/src/components/NavBar/index.tsx @@ -29,6 +29,8 @@ const Nav = styled(TamaguiNav, { height: INTERFACE_NAV_HEIGHT, zIndex: zIndexes.sticky, justifyContent: 'center', + borderBottomWidth: 1, + borderColor: '#545C69', }) const NavItems = css` gap: 12px; @@ -43,6 +45,8 @@ const Left = deprecatedStyled(Row)` ${NavItems} ` const Right = deprecatedStyled(Row)` + display: flex; + align-items: center; justify-content: flex-end; ${NavItems} ` @@ -67,13 +71,13 @@ export default function Navbar() { {areTabsVisible && } - {isSearchBarVisible && } + {/* {isSearchBarVisible && } */} - {!isSearchBarVisible && } + {/* {!isSearchBarVisible && } */} {!isEmbeddedWalletEnabled && isLandingPage && !isSmallScreen && } - {!isConnected && } + {/* {!isConnected && } */} {isTestnetModeEnabled && } {isEmbeddedWalletEnabled && !isConnected && } diff --git a/apps/web/src/components/Pools/PoolDetails/PoolDetailsStats.test.tsx b/apps/web/src/components/Pools/PoolDetails/PoolDetailsStats.test.tsx index 1428cd7d000..c80789112a9 100644 --- a/apps/web/src/components/Pools/PoolDetails/PoolDetailsStats.test.tsx +++ b/apps/web/src/components/Pools/PoolDetails/PoolDetailsStats.test.tsx @@ -22,7 +22,7 @@ describe('PoolDetailsStats', () => { poolData: validPoolDataResponse.data, isReversed: false, chainId: 1, - tokenAColor: '#FF37C7', + tokenAColor: '#4177e2', tokenBColor: '#222222', } diff --git a/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsHeader.test.tsx.snap b/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsHeader.test.tsx.snap index 101fc983a82..87448d68aff 100644 --- a/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsHeader.test.tsx.snap +++ b/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsHeader.test.tsx.snap @@ -218,8 +218,8 @@ exports[`PoolDetailsHeader > renders header text correctly 1`] = ` text-decoration: none; cursor: pointer; transition-duration: 125ms; - color: #FF37C7; - stroke: #FF37C7; + color: #4177e2; + stroke: #4177e2; font-weight: 500; } diff --git a/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsLink.test.tsx.snap b/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsLink.test.tsx.snap index 6d0e61d22ae..239b1374fb8 100644 --- a/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsLink.test.tsx.snap +++ b/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsLink.test.tsx.snap @@ -33,8 +33,8 @@ exports[`PoolDetailsHeader > renders link for pool address 1`] = ` text-decoration: none; cursor: pointer; transition-duration: 125ms; - color: #FF37C7; - stroke: #FF37C7; + color: #4177e2; + stroke: #4177e2; font-weight: 500; } @@ -319,8 +319,8 @@ exports[`PoolDetailsHeader > renders link for token address 1`] = ` text-decoration: none; cursor: pointer; transition-duration: 125ms; - color: #FF37C7; - stroke: #FF37C7; + color: #4177e2; + stroke: #4177e2; font-weight: 500; } diff --git a/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsStats.test.tsx.snap b/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsStats.test.tsx.snap index 63d33269ef1..7fd85ce8875 100644 --- a/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsStats.test.tsx.snap +++ b/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsStats.test.tsx.snap @@ -443,7 +443,7 @@ exports[`PoolDetailsStats > renders stats text correctly 1`] = ` .c10 { height: 8px; width: 99.99999996483845%; - background: #FF37C7; + background: #4177e2; border-top-left-radius: 5px; border-bottom-left-radius: 5px; border-right: 1px solid #F9F9F9; diff --git a/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsTransactionTable.test.tsx.snap b/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsTransactionTable.test.tsx.snap index 54df5c83f17..662254b108a 100644 --- a/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsTransactionTable.test.tsx.snap +++ b/apps/web/src/components/Pools/PoolDetails/__snapshots__/PoolDetailsTransactionTable.test.tsx.snap @@ -8,7 +8,7 @@ exports[`PoolDetailsTransactionsTable > renders data filled state 1`] = ` } .c4 path { - stroke: #FF37C7; + stroke: #4177e2; background: rgba(19, 19, 19, 0.63); fill: none; } @@ -26,8 +26,8 @@ exports[`PoolDetailsTransactionsTable > renders data filled state 1`] = ` text-decoration: none; cursor: pointer; transition-duration: 125ms; - color: #FF37C7; - stroke: #FF37C7; + color: #4177e2; + stroke: #4177e2; font-weight: 500; } @@ -301,7 +301,7 @@ exports[`PoolDetailsTransactionsTable > renders data filled state 1`] = ` diff --git a/apps/web/src/components/Tokens/TokenDetails/tables/__snapshots__/TokenDetailsPoolsTable.test.tsx.snap b/apps/web/src/components/Tokens/TokenDetails/tables/__snapshots__/TokenDetailsPoolsTable.test.tsx.snap index 198f78d31a8..85c126364b6 100644 --- a/apps/web/src/components/Tokens/TokenDetails/tables/__snapshots__/TokenDetailsPoolsTable.test.tsx.snap +++ b/apps/web/src/components/Tokens/TokenDetails/tables/__snapshots__/TokenDetailsPoolsTable.test.tsx.snap @@ -8,7 +8,7 @@ exports[`TDPPoolTable > renders data filled state 1`] = ` } .c1 path { - stroke: #FF37C7; + stroke: #4177e2; background: rgba(19, 19, 19, 0.63); fill: none; } @@ -593,7 +593,7 @@ exports[`TDPPoolTable > renders data filled state 1`] = ` diff --git a/apps/web/src/components/Web3Status/index.tsx b/apps/web/src/components/Web3Status/index.tsx index 3a87f8bd76c..7a67697efb0 100644 --- a/apps/web/src/components/Web3Status/index.tsx +++ b/apps/web/src/components/Web3Status/index.tsx @@ -65,28 +65,52 @@ const AddressAndChevronContainer = deprecatedStyled.div<{ $loading?: boolean }>` } ` +const ConnectButtonStyled = deprecatedStyled.button` + display: flex; + justify-content: center; + align-items: center; + padding: 9px 16px; + width: 134px; + height: 36px; + background: #2362DD; + box-shadow: 0px 0px 20px -5px #2362DD; + border-radius: 8px; + border: none; + cursor: pointer; + font-family: 'Aleo', sans-serif; + font-weight: 500; + font-size: 14px; + line-height: 20px; + color: #FFFFFF; + + &:hover { + opacity: 0.9; + } + + &:active { + opacity: 0.8; + } +` + const ExistingUserCTAButton = forwardRef void }>(function ExistingUserCTAButton( { onPress }, ref, ) { const { t } = useTranslation() - const isEmbeddedWalletEnabled = useFeatureFlag(FeatureFlags.EmbeddedWallet) const isLogIn = isEmbeddedWalletEnabled return ( - +
+ + {isLogIn ? t('nav.logIn.button') : t('common.connect.button')} + +
) }) diff --git a/apps/web/src/components/swap/__snapshots__/SwapDetails.test.tsx.snap b/apps/web/src/components/swap/__snapshots__/SwapDetails.test.tsx.snap index d9a1e29e215..dea6d348982 100644 --- a/apps/web/src/components/swap/__snapshots__/SwapDetails.test.tsx.snap +++ b/apps/web/src/components/swap/__snapshots__/SwapDetails.test.tsx.snap @@ -118,8 +118,8 @@ exports[`SwapDetails.tsx > renders slippage tooltip 1`] = ` text-decoration: none; cursor: pointer; transition-duration: 125ms; - color: #FF37C7; - stroke: #FF37C7; + color: #4177e2; + stroke: #4177e2; font-weight: 500; } diff --git a/apps/web/src/components/swap/styled.tsx b/apps/web/src/components/swap/styled.tsx index 58c91d514a1..d9b1ceb4906 100644 --- a/apps/web/src/components/swap/styled.tsx +++ b/apps/web/src/components/swap/styled.tsx @@ -5,11 +5,14 @@ import { AlertTriangleFilled } from 'ui/src/components/icons/AlertTriangleFilled export const PAGE_WRAPPER_MAX_WIDTH = 480 export const PageWrapper = styled(Flex, { - pt: '$spacing60', + pt: '$spacing8', px: '$spacing8', - pb: '$spacing40', + pb: '$spacing20', width: '100%', maxWidth: PAGE_WRAPPER_MAX_WIDTH, + borderWidth: 1, + borderColor: '$surface3', + marginTop:60, $lg: { pt: '$spacing48', }, diff --git a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemA.tsx b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemA.tsx index b82a3bb3a1f..2be2ffa02f8 100644 --- a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemA.tsx +++ b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemA.tsx @@ -1,7 +1,7 @@ import { EmblemProps } from 'pages/Portfolio/components/AnimatedStyledBanner/Emblems/types' import { useSporeColors } from 'ui/src' -export function EmblemA({ fill = '#FF37C7', opacity = 1, ...props }: EmblemProps): JSX.Element { +export function EmblemA({ fill = '#4177e2', opacity = 1, ...props }: EmblemProps): JSX.Element { const colors = useSporeColors() return ( diff --git a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemB.tsx b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemB.tsx index 97a95e05515..174dd57da35 100644 --- a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemB.tsx +++ b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemB.tsx @@ -1,7 +1,7 @@ import { EmblemProps } from 'pages/Portfolio/components/AnimatedStyledBanner/Emblems/types' import { useSporeColors } from 'ui/src' -export function EmblemB({ fill = '#FF37C7', opacity = 1, ...props }: EmblemProps): JSX.Element { +export function EmblemB({ fill = '#4177e2', opacity = 1, ...props }: EmblemProps): JSX.Element { const colors = useSporeColors() return ( diff --git a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemC.tsx b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemC.tsx index 43409765e33..8e262158413 100644 --- a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemC.tsx +++ b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemC.tsx @@ -2,7 +2,7 @@ import { EmblemProps } from 'pages/Portfolio/components/AnimatedStyledBanner/Emb import { useId } from 'react' import { useSporeColors } from 'ui/src' -export function EmblemC({ fill = '#FF37C7', opacity = 1, ...props }: EmblemProps): JSX.Element { +export function EmblemC({ fill = '#4177e2', opacity = 1, ...props }: EmblemProps): JSX.Element { const colors = useSporeColors() const clipPathId = useId() diff --git a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemD.tsx b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemD.tsx index 6d2dce5ec4b..6494f47899c 100644 --- a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemD.tsx +++ b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemD.tsx @@ -1,7 +1,7 @@ import { EmblemProps } from 'pages/Portfolio/components/AnimatedStyledBanner/Emblems/types' import { useSporeColors } from 'ui/src' -export function EmblemD({ fill = '#FF37C7', opacity = 1, ...props }: EmblemProps): JSX.Element { +export function EmblemD({ fill = '#4177e2', opacity = 1, ...props }: EmblemProps): JSX.Element { const colors = useSporeColors() return ( diff --git a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemE.tsx b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemE.tsx index d07e8cff91b..a19e9e39be1 100644 --- a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemE.tsx +++ b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemE.tsx @@ -1,7 +1,7 @@ import { EmblemProps } from 'pages/Portfolio/components/AnimatedStyledBanner/Emblems/types' import { useSporeColors } from 'ui/src' -export function EmblemE({ fill = '#FF37C7', opacity = 1, ...props }: EmblemProps): JSX.Element { +export function EmblemE({ fill = '#4177e2', opacity = 1, ...props }: EmblemProps): JSX.Element { const colors = useSporeColors() return ( diff --git a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemF.tsx b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemF.tsx index f39c3cf8cb7..048afbf43d9 100644 --- a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemF.tsx +++ b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemF.tsx @@ -1,7 +1,7 @@ import { EmblemProps } from 'pages/Portfolio/components/AnimatedStyledBanner/Emblems/types' import { useSporeColors } from 'ui/src' -export function EmblemF({ fill = '#FF37C7', opacity = 1, ...props }: EmblemProps): JSX.Element { +export function EmblemF({ fill = '#4177e2', opacity = 1, ...props }: EmblemProps): JSX.Element { const colors = useSporeColors() return ( diff --git a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemG.tsx b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemG.tsx index d0e5263fc54..22d31f8b672 100644 --- a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemG.tsx +++ b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemG.tsx @@ -1,7 +1,7 @@ import { EmblemProps } from 'pages/Portfolio/components/AnimatedStyledBanner/Emblems/types' import { useSporeColors } from 'ui/src' -export function EmblemG({ fill = '#FF37C7', opacity = 1, ...props }: EmblemProps): JSX.Element { +export function EmblemG({ fill = '#4177e2', opacity = 1, ...props }: EmblemProps): JSX.Element { const colors = useSporeColors() return ( diff --git a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemH.tsx b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemH.tsx index 2568174c990..2a470109700 100644 --- a/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemH.tsx +++ b/apps/web/src/pages/Portfolio/components/AnimatedStyledBanner/Emblems/EmblemH.tsx @@ -1,7 +1,7 @@ import { EmblemProps } from 'pages/Portfolio/components/AnimatedStyledBanner/Emblems/types' import { useSporeColors } from 'ui/src' -export function EmblemH({ fill = '#FF37C7', opacity = 1, ...props }: EmblemProps): JSX.Element { +export function EmblemH({ fill = '#4177e2', opacity = 1, ...props }: EmblemProps): JSX.Element { const colors = useSporeColors() return ( diff --git a/apps/web/src/pages/Positions/TopPools.tsx b/apps/web/src/pages/Positions/TopPools.tsx index 92b14c1ebe2..68840bf2d4b 100644 --- a/apps/web/src/pages/Positions/TopPools.tsx +++ b/apps/web/src/pages/Positions/TopPools.tsx @@ -44,7 +44,7 @@ export function TopPools({ chainId }: { chainId: UniverseChainId | null }) { return ( - {displayBoostedPools && ( + {/* {displayBoostedPools && ( - )} + )} */} {displayTopPools && ( diff --git a/apps/web/src/pages/Positions/index.tsx b/apps/web/src/pages/Positions/index.tsx index 795d43a7e94..6e34697e24a 100644 --- a/apps/web/src/pages/Positions/index.tsx +++ b/apps/web/src/pages/Positions/index.tsx @@ -402,7 +402,7 @@ export default function Pool() { $lg={{ px: '$spacing20' }} > - {isLPIncentivesEnabled && ( + {/* {isLPIncentivesEnabled && ( { @@ -412,8 +412,8 @@ export default function Pool() { setTokenRewards={setTokenRewards} initialHasCollectedRewards={hasCollectedRewards} /> - )} - + )} */} + )} - {!statusFilter.includes(PositionStatus.CLOSED) && !closedCTADismissed && account.address && ( + {/* {!statusFilter.includes(PositionStatus.CLOSED) && !closedCTADismissed && account.address && ( setClosedCTADismissed(true)} size="$icon.20" /> - )} + )} */} {isConnected && ( @@ -509,7 +509,7 @@ export default function Pool() { - {isConnected && ( + {/* {isConnected && ( {t('liquidity.learnMoreLabel')} @@ -528,7 +528,7 @@ export default function Pool() { {t('common.button.learn')} - )} + )} */} {isLPIncentivesEnabled && ( diff --git a/apps/web/src/pages/RouteDefinitions.tsx b/apps/web/src/pages/RouteDefinitions.tsx index 48a0eca12b2..ad66f775cbc 100644 --- a/apps/web/src/pages/RouteDefinitions.tsx +++ b/apps/web/src/pages/RouteDefinitions.tsx @@ -3,7 +3,6 @@ import { getExploreDescription, getExploreTitle } from 'pages/getExploreTitle' import { getPortfolioDescription, getPortfolioTitle } from 'pages/getPortfolioTitle' import { getAddLiquidityPageTitle, getPositionPageDescription, getPositionPageTitle } from 'pages/getPositionPageTitle' // High-traffic pages (index and /swap) should not be lazy-loaded. -import Landing from 'pages/Landing' import Swap from 'pages/Swap' import { lazy, ReactNode, Suspense, useMemo } from 'react' import { matchPath, Navigate, Route, Routes, useLocation } from 'react-router' @@ -127,7 +126,7 @@ export const routes: RouteDefinition[] = [ getTitle: () => StaticTitlesAndDescriptions.UniswapTitle, getDescription: () => StaticTitlesAndDescriptions.SwapDescription, getElement: (args) => { - return args.browserRouterEnabled && args.hash ? : + return args.browserRouterEnabled && args.hash ? : }, }), createRouteDefinition({ @@ -217,36 +216,36 @@ export const routes: RouteDefinition[] = [ getDescription: () => i18n.t('title.createGovernanceTo'), getElement: () => , }), - createRouteDefinition({ - path: '/buy', - getElement: () => , - getTitle: () => StaticTitlesAndDescriptions.SwapTitle, - }), - createRouteDefinition({ - path: '/sell', - getElement: () => , - getTitle: () => StaticTitlesAndDescriptions.SwapTitle, - }), + // createRouteDefinition({ + // path: '/buy', + // getElement: () => , + // getTitle: () => StaticTitlesAndDescriptions.SwapTitle, + // }), + // createRouteDefinition({ + // path: '/sell', + // getElement: () => , + // getTitle: () => StaticTitlesAndDescriptions.SwapTitle, + // }), createRouteDefinition({ path: '/send', getElement: () => , getTitle: () => i18n.t('title.sendTokens'), }), - createRouteDefinition({ - path: '/limits', - getElement: () => , - getTitle: () => i18n.t('title.placeLimit'), - }), - createRouteDefinition({ - path: '/limit', - getElement: () => , - getTitle: () => i18n.t('title.placeLimit'), - }), - createRouteDefinition({ - path: '/buy', - getElement: () => , - getTitle: () => StaticTitlesAndDescriptions.SwapTitle, - }), + // createRouteDefinition({ + // path: '/limits', + // getElement: () => , + // getTitle: () => i18n.t('title.placeLimit'), + // }), + // createRouteDefinition({ + // path: '/limit', + // getElement: () => , + // getTitle: () => i18n.t('title.placeLimit'), + // }), + // createRouteDefinition({ + // path: '/buy', + // getElement: () => , + // getTitle: () => StaticTitlesAndDescriptions.SwapTitle, + // }), createRouteDefinition({ path: '/swap', getElement: () => , diff --git a/apps/web/src/pages/Swap/Buy/__snapshots__/ProviderConnectedView.test.tsx.snap b/apps/web/src/pages/Swap/Buy/__snapshots__/ProviderConnectedView.test.tsx.snap index 10be5ade299..13eac2d7656 100644 --- a/apps/web/src/pages/Swap/Buy/__snapshots__/ProviderConnectedView.test.tsx.snap +++ b/apps/web/src/pages/Swap/Buy/__snapshots__/ProviderConnectedView.test.tsx.snap @@ -5,8 +5,8 @@ exports[`ProviderConnectedView > should render the component and call callbacks text-decoration: none; cursor: pointer; transition-duration: 125ms; - color: #FF37C7; - stroke: #FF37C7; + color: #4177e2; + stroke: #4177e2; font-weight: 500; } diff --git a/apps/web/src/pages/Swap/index.tsx b/apps/web/src/pages/Swap/index.tsx index 5fca94d2bca..09473c1e943 100644 --- a/apps/web/src/pages/Swap/index.tsx +++ b/apps/web/src/pages/Swap/index.tsx @@ -214,21 +214,21 @@ export function Swap({ ) } -const SWAP_TABS = [SwapTab.Swap, SwapTab.Limit, SwapTab.Buy, SwapTab.Sell] +const SWAP_TABS: SwapTab[] = [] // SwapTab.Swap, SwapTab.Limit, SwapTab.Buy, SwapTab.Sell const TAB_TYPE_TO_LABEL = { - [SwapTab.Swap]: (t: AppTFunction) => t('swap.form.header'), - [SwapTab.Limit]: (t: AppTFunction) => t('swap.limit'), + // [SwapTab.Swap]: (t: AppTFunction) => t('swap.form.header'), + // [SwapTab.Limit]: (t: AppTFunction) => t('swap.limit'), [SwapTab.Send]: (t: AppTFunction) => t('send.title'), - [SwapTab.Buy]: (t: AppTFunction) => t('common.buy.label'), - [SwapTab.Sell]: (t: AppTFunction) => t('common.sell.label'), + // [SwapTab.Buy]: (t: AppTFunction) => t('common.buy.label'), + // [SwapTab.Sell]: (t: AppTFunction) => t('common.sell.label'), } const PATHNAME_TO_TAB: { [key: string]: SwapTab } = { '/swap': SwapTab.Swap, - '/limit': SwapTab.Limit, - '/buy': SwapTab.Buy, - '/sell': SwapTab.Sell, + // '/limit': SwapTab.Limit, + // '/buy': SwapTab.Buy, + // '/sell': SwapTab.Sell, } function UniversalSwapFlow({ @@ -260,16 +260,16 @@ function UniversalSwapFlow({ const { t } = useTranslation() const swapHandlers = useSwapHandlers() - const LimitFormWrapper = useDeferredComponent(() => - import('pages/Swap/Limit/LimitForm').then((module) => ({ - default: module.LimitFormWrapper, - })), - ) - const BuyForm = useDeferredComponent(() => - import('pages/Swap/Buy/BuyForm').then((module) => ({ - default: module.BuyForm, - })), - ) + // const LimitFormWrapper = useDeferredComponent(() => + // import('pages/Swap/Limit/LimitForm').then((module) => ({ + // default: module.LimitFormWrapper, + // })), + // ) + // const BuyForm = useDeferredComponent(() => + // import('pages/Swap/Buy/BuyForm').then((module) => ({ + // default: module.BuyForm, + // })), + // ) const { openModal: openSendFormModal } = useModalState(ModalName.Send) @@ -302,9 +302,9 @@ function UniversalSwapFlow({ const isFiatOffRampEnabled = useFeatureFlag(FeatureFlags.FiatOffRamp) const SWAP_TAB_OPTIONS: readonly SegmentedControlOption[] = useMemo(() => { return SWAP_TABS.filter((tab) => { - if (tab === SwapTab.Sell && !isFiatOffRampEnabled) { - return false - } + // if (tab === SwapTab.Sell && !isFiatOffRampEnabled) { + // return false + // } return true }).map((tab) => ({ @@ -316,7 +316,7 @@ function UniversalSwapFlow({ color={currentTab === tab ? '$neutral1' : '$neutral2'} tag="h1" > - {TAB_TYPE_TO_LABEL[tab](t)} + {tab in TAB_TYPE_TO_LABEL ? TAB_TYPE_TO_LABEL[tab as keyof typeof TAB_TYPE_TO_LABEL](t) : tab} ), })) @@ -332,14 +332,25 @@ function UniversalSwapFlow({ {!hideHeader && ( - + {SWAP_TAB_OPTIONS.length >= 2 ? ( + + ) : ( + // + // {TAB_TYPE_TO_LABEL[SwapTab.Swap](t)} + // + null + )} )} {currentTab === SwapTab.Swap && ( @@ -361,21 +372,21 @@ function UniversalSwapFlow({ )} - {currentTab === SwapTab.Limit && LimitFormWrapper && } - {currentTab === SwapTab.Buy && BuyForm && ( + {/* {currentTab === SwapTab.Limit && LimitFormWrapper && } */} + {/* {currentTab === SwapTab.Buy && BuyForm && ( - )} - {currentTab === SwapTab.Sell && BuyForm && ( + )} */} + {/* {currentTab === SwapTab.Sell && BuyForm && ( - )} + )} */} ) } diff --git a/apps/web/src/theme/components/ThemeToggle.tsx b/apps/web/src/theme/components/ThemeToggle.tsx index 25e71933737..22226044249 100644 --- a/apps/web/src/theme/components/ThemeToggle.tsx +++ b/apps/web/src/theme/components/ThemeToggle.tsx @@ -81,10 +81,12 @@ export function ThemeColorMetaUpdater() { } export function useIsDarkMode(): boolean { - const mode = useAtomValue(themeModeAtom) - const systemTheme = useAtomValue(systemThemeAtom) + // Force dark mode only + return true + // const mode = useAtomValue(themeModeAtom) + // const systemTheme = useAtomValue(systemThemeAtom) - return (mode === ThemeMode.AUTO ? systemTheme : mode) === ThemeMode.DARK + // return (mode === ThemeMode.AUTO ? systemTheme : mode) === ThemeMode.DARK } export function useDarkModeManager(): [boolean, (mode: ThemeMode) => void] { diff --git a/packages/ui/src/assets/icons/arrow-down-circle-filled-with-border.svg b/packages/ui/src/assets/icons/arrow-down-circle-filled-with-border.svg index 6c971508e68..e37fde9b521 100644 --- a/packages/ui/src/assets/icons/arrow-down-circle-filled-with-border.svg +++ b/packages/ui/src/assets/icons/arrow-down-circle-filled-with-border.svg @@ -1,4 +1,4 @@ - + diff --git a/packages/ui/src/assets/icons/coin-stack.svg b/packages/ui/src/assets/icons/coin-stack.svg index 94c9b8df03b..813db9d988f 100644 --- a/packages/ui/src/assets/icons/coin-stack.svg +++ b/packages/ui/src/assets/icons/coin-stack.svg @@ -1,12 +1,12 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/packages/ui/src/assets/icons/compass.svg b/packages/ui/src/assets/icons/compass.svg index 089dec3c186..c1c4f278ed1 100644 --- a/packages/ui/src/assets/icons/compass.svg +++ b/packages/ui/src/assets/icons/compass.svg @@ -1,3 +1,3 @@ - + diff --git a/packages/ui/src/assets/icons/crosschain-icon.svg b/packages/ui/src/assets/icons/crosschain-icon.svg index 3fd788f55b0..27bab000602 100644 --- a/packages/ui/src/assets/icons/crosschain-icon.svg +++ b/packages/ui/src/assets/icons/crosschain-icon.svg @@ -1,4 +1,4 @@ - + diff --git a/packages/ui/src/assets/icons/hskswap-icon.svg b/packages/ui/src/assets/icons/hskswap-icon.svg new file mode 100644 index 00000000000..99993a33cde --- /dev/null +++ b/packages/ui/src/assets/icons/hskswap-icon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/packages/ui/src/assets/icons/hskswap-text.svg b/packages/ui/src/assets/icons/hskswap-text.svg new file mode 100644 index 00000000000..915fe09464a --- /dev/null +++ b/packages/ui/src/assets/icons/hskswap-text.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/packages/ui/src/assets/icons/one-to-one.svg b/packages/ui/src/assets/icons/one-to-one.svg index d79d839145a..455bbd61642 100644 --- a/packages/ui/src/assets/icons/one-to-one.svg +++ b/packages/ui/src/assets/icons/one-to-one.svg @@ -1,5 +1,5 @@ - + diff --git a/packages/ui/src/assets/icons/rocket.svg b/packages/ui/src/assets/icons/rocket.svg index 8cae57b8331..1b4050d68e8 100644 --- a/packages/ui/src/assets/icons/rocket.svg +++ b/packages/ui/src/assets/icons/rocket.svg @@ -1,3 +1,3 @@ - + diff --git a/packages/ui/src/assets/icons/smart-wallet.svg b/packages/ui/src/assets/icons/smart-wallet.svg index b7550868fa8..54506a4c4d5 100644 --- a/packages/ui/src/assets/icons/smart-wallet.svg +++ b/packages/ui/src/assets/icons/smart-wallet.svg @@ -1,7 +1,7 @@ - - + + diff --git a/packages/ui/src/assets/icons/stopwatch.svg b/packages/ui/src/assets/icons/stopwatch.svg index 0ebcce3f3a7..0265bb764b4 100644 --- a/packages/ui/src/assets/icons/stopwatch.svg +++ b/packages/ui/src/assets/icons/stopwatch.svg @@ -1,3 +1,3 @@ - + diff --git a/packages/ui/src/assets/icons/uniswapX-generic.svg b/packages/ui/src/assets/icons/uniswapX-generic.svg index 98c7bb36d9c..6b1e4333ce8 100644 --- a/packages/ui/src/assets/icons/uniswapX-generic.svg +++ b/packages/ui/src/assets/icons/uniswapX-generic.svg @@ -1,3 +1,3 @@ - + diff --git a/packages/ui/src/components/icons/ArrowDownCircleFilledWithBorder.tsx b/packages/ui/src/components/icons/ArrowDownCircleFilledWithBorder.tsx index a0e65279068..5d26a3fbec8 100644 --- a/packages/ui/src/components/icons/ArrowDownCircleFilledWithBorder.tsx +++ b/packages/ui/src/components/icons/ArrowDownCircleFilledWithBorder.tsx @@ -14,5 +14,5 @@ export const [ArrowDownCircleFilledWithBorder, AnimatedArrowDownCircleFilledWith /> ), - defaultFill: '#FF37C7', + defaultFill: '#4177e2', }) diff --git a/packages/ui/src/components/icons/CoinStack.tsx b/packages/ui/src/components/icons/CoinStack.tsx index cbd10937b31..d1df8c6d376 100644 --- a/packages/ui/src/components/icons/CoinStack.tsx +++ b/packages/ui/src/components/icons/CoinStack.tsx @@ -49,5 +49,5 @@ export const [CoinStack, AnimatedCoinStack] = createIcon({ /> ), - defaultFill: '#FF37C7', + defaultFill: '#4177e2', }) diff --git a/packages/ui/src/components/icons/Compass.tsx b/packages/ui/src/components/icons/Compass.tsx index 663c35a793c..e7017a35848 100644 --- a/packages/ui/src/components/icons/Compass.tsx +++ b/packages/ui/src/components/icons/Compass.tsx @@ -13,5 +13,5 @@ export const [Compass, AnimatedCompass] = createIcon({ /> ), - defaultFill: '#FF37C7', + defaultFill: '#4177e2', }) diff --git a/packages/ui/src/components/icons/CrosschainIcon.tsx b/packages/ui/src/components/icons/CrosschainIcon.tsx index 9e866968c50..23cbcc06429 100644 --- a/packages/ui/src/components/icons/CrosschainIcon.tsx +++ b/packages/ui/src/components/icons/CrosschainIcon.tsx @@ -14,5 +14,5 @@ export const [CrosschainIcon, AnimatedCrosschainIcon] = createIcon({ /> ), - defaultFill: '#FF37C7', + defaultFill: '#4177e2', }) diff --git a/packages/ui/src/components/icons/Magic.tsx b/packages/ui/src/components/icons/Magic.tsx index 1589dfd320d..7199f4ac768 100644 --- a/packages/ui/src/components/icons/Magic.tsx +++ b/packages/ui/src/components/icons/Magic.tsx @@ -9,7 +9,7 @@ export const [Magic, AnimatedMagic] = createIcon({ ), diff --git a/packages/ui/src/components/icons/OneToOne.tsx b/packages/ui/src/components/icons/OneToOne.tsx index 48b45c91aa2..a79d0235a34 100644 --- a/packages/ui/src/components/icons/OneToOne.tsx +++ b/packages/ui/src/components/icons/OneToOne.tsx @@ -25,5 +25,5 @@ export const [OneToOne, AnimatedOneToOne] = createIcon({ /> ), - defaultFill: '#FF37C7', + defaultFill: '#4177e2', }) diff --git a/packages/ui/src/components/icons/Rocket.tsx b/packages/ui/src/components/icons/Rocket.tsx index c7059b4ea6d..32a947ff1c1 100644 --- a/packages/ui/src/components/icons/Rocket.tsx +++ b/packages/ui/src/components/icons/Rocket.tsx @@ -13,5 +13,5 @@ export const [Rocket, AnimatedRocket] = createIcon({ /> ), - defaultFill: '#FF37C7', + defaultFill: '#4177e2', }) diff --git a/packages/ui/src/components/icons/SettingsCustom.tsx b/packages/ui/src/components/icons/SettingsCustom.tsx new file mode 100644 index 00000000000..27d39c377c3 --- /dev/null +++ b/packages/ui/src/components/icons/SettingsCustom.tsx @@ -0,0 +1,35 @@ +import { Path, Svg } from 'react-native-svg' + +// eslint-disable-next-line no-relative-import-paths/no-relative-import-paths +import { createIcon } from '../factories/createIcon' + +export const [SettingsCustom, AnimatedSettingsCustom] = createIcon({ + name: 'SettingsCustom', + getIcon: (props) => ( + + + + + + ), + defaultFill: '#94A3B8', +}) + diff --git a/packages/ui/src/components/icons/SmartWallet.tsx b/packages/ui/src/components/icons/SmartWallet.tsx index 5de30d19b30..6f2c59ae0fa 100644 --- a/packages/ui/src/components/icons/SmartWallet.tsx +++ b/packages/ui/src/components/icons/SmartWallet.tsx @@ -24,5 +24,5 @@ export const [SmartWallet, AnimatedSmartWallet] = createIcon({
), - defaultFill: '#FF37C7', + defaultFill: '#4177e2', }) diff --git a/packages/ui/src/components/icons/Stopwatch.tsx b/packages/ui/src/components/icons/Stopwatch.tsx index 6ee36479406..22f68a2230c 100644 --- a/packages/ui/src/components/icons/Stopwatch.tsx +++ b/packages/ui/src/components/icons/Stopwatch.tsx @@ -15,5 +15,5 @@ export const [Stopwatch, AnimatedStopwatch] = createIcon({ /> ), - defaultFill: '#FF37C7', + defaultFill: '#4177e2', }) diff --git a/packages/ui/src/components/icons/UniswapXGeneric.tsx b/packages/ui/src/components/icons/UniswapXGeneric.tsx index feeb2615d6e..747779ea8be 100644 --- a/packages/ui/src/components/icons/UniswapXGeneric.tsx +++ b/packages/ui/src/components/icons/UniswapXGeneric.tsx @@ -13,5 +13,5 @@ export const [UniswapXGeneric, AnimatedUniswapXGeneric] = createIcon({ /> ), - defaultFill: '#FF37C7', + defaultFill: '#4177e2', }) diff --git a/packages/ui/src/theme/color/colors.ts b/packages/ui/src/theme/color/colors.ts index 126eb7dd50e..f16e23451e6 100644 --- a/packages/ui/src/theme/color/colors.ts +++ b/packages/ui/src/theme/color/colors.ts @@ -184,14 +184,14 @@ const sporeLight = { surface1Hovered: '#FCFCFC', surface2: '#F9F9F9', surface2Hovered: '#F2F2F2', - surface3: 'rgba(19, 19, 19, 0.08)', + surface3: 'rgba(148, 163, 184, 0.5)', surface3Solid: '#F2F2F2', surface3Hovered: 'rgba(19, 19, 19, 0.1)', surface4: 'rgba(255, 255, 255, 0.64)', surface5: 'rgba(0,0,0,0.04)', surface5Hovered: 'rgba(0,0,0,0.06)', - accent1: '#FF37C7', - accent1Hovered: '#E500A5', + accent1: '#4177e2', + accent1Hovered: '#3d7fff', accent2: 'rgba(255, 55, 199, 0.08)', accent2Hovered: 'rgba(255, 55, 199, 0.12)', accent2Solid: '#FFF3FC', @@ -233,14 +233,14 @@ const sporeDark = { surface1Hovered: '#1A1A1A', surface2: '#1F1F1F', surface2Hovered: '#242424', - surface3: 'rgba(255,255,255,0.12)', + surface3: 'rgba(148, 163, 184, 0.5)', surface3Solid: '#393939', surface3Hovered: 'rgba(255,255,255,0.16)', surface4: 'rgba(255,255,255,0.20)', surface5: 'rgba(0,0,0,0.04)', surface5Hovered: 'rgba(0,0,0,0.06)', - accent1: '#FF37C7', - accent1Hovered: '#E500A5', + accent1: '#4177e2', + accent1Hovered: '#3d7fff', accent2: 'rgba(255, 55, 199, 0.08)', accent2Hovered: 'rgba(255, 55, 199, 0.12)', diff --git a/packages/uniswap/src/components/CurrencyInputPanel/AmountInputPresets/AmountInputPresets.tsx b/packages/uniswap/src/components/CurrencyInputPanel/AmountInputPresets/AmountInputPresets.tsx index 1103debb35d..f151e3f874d 100644 --- a/packages/uniswap/src/components/CurrencyInputPanel/AmountInputPresets/AmountInputPresets.tsx +++ b/packages/uniswap/src/components/CurrencyInputPanel/AmountInputPresets/AmountInputPresets.tsx @@ -20,7 +20,10 @@ export function AmountInputPresets({ ? { opacity: 0, transform: [{ translateY: -4 }], - '$group-hover': { opacity: 1, transform: [{ translateY: 0 }] }, + '$group-hover': { + opacity: 1, + transform: [{ translateY: 0 }], + }, } : {})} animation="100ms" diff --git a/packages/uniswap/src/components/CurrencyInputPanel/CurrencyInputPanelHeader.tsx b/packages/uniswap/src/components/CurrencyInputPanel/CurrencyInputPanelHeader.tsx index 5d5ee44584d..c1ea8c0ad41 100644 --- a/packages/uniswap/src/components/CurrencyInputPanel/CurrencyInputPanelHeader.tsx +++ b/packages/uniswap/src/components/CurrencyInputPanel/CurrencyInputPanelHeader.tsx @@ -1,5 +1,5 @@ import type { Currency, CurrencyAmount } from '@uniswap/sdk-core' -import { useCallback } from 'react' +import { useCallback, useState } from 'react' import { Flex, Text } from 'ui/src' import { spacing } from 'ui/src/theme/spacing' import { @@ -37,6 +37,7 @@ export function CurrencyInputPanelHeader({ showDefaultTokenOptions, }: CurrencyInputPanelHeaderProps): JSX.Element | null { const priceUXEnabled = usePriceUXEnabled() + const [isHovering, setIsHovering] = useState(false) const isOutput = currencyField === CurrencyField.OUTPUT const showFlippableRate = priceUXEnabled && isOutput && !!currencyInfo @@ -64,13 +65,28 @@ export function CurrencyInputPanelHeader({ (isWebAppDesktop || isExtensionApp) && currencyField === CurrencyField.INPUT && currencyBalance return ( - + setIsHovering(true)} + onMouseLeave={() => setIsHovering(false)} + > {/* IMPORTANT: $micro crashes on mobile */} {headerLabel} {showInputPresets && ( - + setIsHovering(true)} + onMouseLeave={() => setIsHovering(false)} + opacity={isHovering ? 1 : 0} + transform={isHovering ? [{ translateY: 0 }] : [{ translateY: -4 }]} + pointerEvents={isHovering ? 'auto' : 'none'} + animation="100ms" + > )} diff --git a/packages/uniswap/src/components/buttons/__snapshots__/PasteButton.test.tsx.snap b/packages/uniswap/src/components/buttons/__snapshots__/PasteButton.test.tsx.snap index 01d42344ab4..080f034ba57 100644 --- a/packages/uniswap/src/components/buttons/__snapshots__/PasteButton.test.tsx.snap +++ b/packages/uniswap/src/components/buttons/__snapshots__/PasteButton.test.tsx.snap @@ -246,7 +246,7 @@ exports[`SplitLogo renders without error 1`] = ` maxFontSizeMultiplier={1.2} style={ { - "color": "#FF37C7", + "color": "#4177e2", "fontFamily": "Basel Grotesk", "fontSize": 15, "fontWeight": "500", @@ -274,7 +274,7 @@ exports[`SplitLogo renders without error 1`] = ` "borderWidth": 0, }, { - "color": "#FF37C7", + "color": "#4177e2", "height": 16, "width": 16, }, @@ -289,7 +289,7 @@ exports[`SplitLogo renders without error 1`] = ` vbWidth={16} > - + + {/* Swap text button - only show when absolutely positioned */} + {position === 'absolute' && ( + + Swap + + )} {isViewOnlyWallet ? ( ) : ( diff --git a/packages/uniswap/src/features/transactions/components/settings/TransactionSettingsButton.tsx b/packages/uniswap/src/features/transactions/components/settings/TransactionSettingsButton.tsx index d0294c7e154..e7a4df737ab 100644 --- a/packages/uniswap/src/features/transactions/components/settings/TransactionSettingsButton.tsx +++ b/packages/uniswap/src/features/transactions/components/settings/TransactionSettingsButton.tsx @@ -2,6 +2,7 @@ import { memo } from 'react' import type { ColorTokens, GeneratedIcon } from 'ui/src' import { Flex, Tooltip as TooltipComponent } from 'ui/src' import { Settings } from 'ui/src/components/icons/Settings' +import { SettingsCustom } from 'ui/src/components/icons/SettingsCustom' import type { IconSizeTokens } from 'ui/src/theme' import { TransactionSettingsModalId } from 'uniswap/src/features/transactions/components/settings/stores/TransactionSettingsModalStore/createTransactionSettingsModalStore' import { useModalVisibility } from 'uniswap/src/features/transactions/components/settings/stores/TransactionSettingsModalStore/useTransactionSettingsModalStore' @@ -24,9 +25,16 @@ export const TransactionSettingsButton = memo( CustomIconComponent, IconLabel, }: Omit): JSX.Element => { - const IconComponent = CustomIconComponent ?? Settings + // Use SettingsCustom as default icon, or CustomIconComponent if provided + const IconComponent = CustomIconComponent ?? SettingsCustom - const iconSize = iconSizeProp ?? (isWebPlatform ? '$icon.20' : '$icon.24') + // Check if the icon is SettingsCustom (by checking displayName or comparing function) + const isSettingsCustom = !CustomIconComponent || CustomIconComponent === SettingsCustom || CustomIconComponent.displayName === 'SettingsCustom' + + // Use 32x32 size for SettingsCustom, otherwise use prop or default + const iconSize = isSettingsCustom + ? 32 + : iconSizeProp ?? (isWebPlatform ? '$icon.20' : '$icon.24') return ( {IconLabel} - + ) diff --git a/packages/uniswap/src/features/transactions/components/settings/TransactionSettingsButtonWithSlippage.tsx b/packages/uniswap/src/features/transactions/components/settings/TransactionSettingsButtonWithSlippage.tsx index a2e0d0f9d6d..114959d94ec 100644 --- a/packages/uniswap/src/features/transactions/components/settings/TransactionSettingsButtonWithSlippage.tsx +++ b/packages/uniswap/src/features/transactions/components/settings/TransactionSettingsButtonWithSlippage.tsx @@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next' import type { ColorTokens } from 'ui/src' import { Text } from 'ui/src' import { Settings } from 'ui/src/components/icons/Settings' +import { SettingsCustom } from 'ui/src/components/icons/SettingsCustom' import { SettingsWarning } from 'ui/src/components/icons/SettingsWarning' import type { IconSizeTokens } from 'ui/src/theme' import { SLIPPAGE_CRITICAL_TOLERANCE } from 'uniswap/src/constants/transactions' @@ -57,15 +58,16 @@ export function TransactionSettingsButtonWithSlippage({ autoSlippageTolerance, fallbackColorValue: iconColor, }) + // Use SettingsCustom as default, SettingsWarning only for critical slippage const SettingsIconComponent = - customSlippageTolerance && customSlippageTolerance > SLIPPAGE_CRITICAL_TOLERANCE ? SettingsWarning : Settings + customSlippageTolerance && customSlippageTolerance > SLIPPAGE_CRITICAL_TOLERANCE ? SettingsWarning : SettingsCustom return { backgroundColor: iconBackgroundColor, contentColor: fillColor, IconComponent: SettingsIconComponent } }, [customSlippageTolerance, iconColor, autoSlippageTolerance]) return ( - + + + diff --git a/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormCurrencyInputPanel.tsx b/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormCurrencyInputPanel.tsx index ee0dda30cc0..48dc3d7483e 100644 --- a/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormCurrencyInputPanel.tsx +++ b/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormCurrencyInputPanel.tsx @@ -65,6 +65,7 @@ export function SwapFormCurrencyInputPanel(): JSX.Element { - + {!isWebApp && /* Interface renders its own header with multiple tabs */} - {!hideSettings && } + {/* Original Swap+Settings button moved to swapblock position below */} + {/* {!hideSettings && } */} {!hideContent && ( - + )} @@ -77,17 +84,38 @@ export function SwapFormScreen({ ) } -function SwapFormContent(): JSX.Element { +function SwapFormContent({ + hideSettings, + filteredSettings, + isBridgeTrade, +}: { + hideSettings: boolean + filteredSettings: TransactionSettingConfig[] + isBridgeTrade: boolean +}): JSX.Element { const { trade, isCrossChain } = useSwapFormScreenStore((state) => ({ trade: state.trade, isCrossChain: state.isCrossChain, })) const priceUXEnabled = usePriceUXEnabled() + const { autoSlippageTolerance } = useSlippageSettings() return ( + + {/* Original Swap+Settings button moved here to occupy space within the border */} + {!hideSettings && ( + + {/* Swap text */} + + Swap + + {/* Settings button */} + + + )} diff --git a/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/hooks/useCurrencyInputFocusedStyle.ts b/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/hooks/useCurrencyInputFocusedStyle.ts index b23b700f4e8..3dc3f22b62f 100644 --- a/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/hooks/useCurrencyInputFocusedStyle.ts +++ b/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/hooks/useCurrencyInputFocusedStyle.ts @@ -3,10 +3,10 @@ import type { FlexProps } from 'ui/src' function getCurrencyInputFocusedStyle(isFocused: boolean): FlexProps { return { borderColor: isFocused ? '$surface3' : '$transparent', - backgroundColor: isFocused ? '$surface1' : '$surface2', + backgroundColor: '$surface1', // Always use surface1 for consistent background hoverStyle: { borderColor: isFocused ? '$surface3Hovered' : '$transparent', - backgroundColor: isFocused ? '$surface1' : '$surface2Hovered', + backgroundColor: '$surface1', // Always use surface1 for consistent background }, } } diff --git a/packages/wallet/src/components/WalletPreviewCard/__snapshots__/WalletPreviewCard.test.tsx.snap b/packages/wallet/src/components/WalletPreviewCard/__snapshots__/WalletPreviewCard.test.tsx.snap index 0b525bc03cb..0c5c1a632cf 100644 --- a/packages/wallet/src/components/WalletPreviewCard/__snapshots__/WalletPreviewCard.test.tsx.snap +++ b/packages/wallet/src/components/WalletPreviewCard/__snapshots__/WalletPreviewCard.test.tsx.snap @@ -341,7 +341,7 @@ exports[`renders wallet preview card 1`] = ` "borderWidth": 0, }, { - "color": "#FF37C7", + "color": "#4177e2", "height": 20, "width": 20, }, @@ -356,7 +356,7 @@ exports[`renders wallet preview card 1`] = ` vbWidth={48} > Date: Wed, 7 Jan 2026 18:58:02 +0800 Subject: [PATCH 02/33] feat: update border --- apps/web/index.html | 7 ++++-- apps/web/src/components/swap/styled.tsx | 6 ++--- apps/web/src/pages/MigrateV2/index.tsx | 2 +- apps/web/src/pages/Swap/index.tsx | 2 +- packages/ui/src/theme/fonts.ts | 4 ++-- .../settings/TransactionSettings.tsx | 2 +- .../swap/components/SwapArrowButton.tsx | 4 ++-- .../form/SwapFormScreen/SwapFormScreen.tsx | 22 +++++++++++-------- .../SwapFormScreenDetails.web.tsx | 4 ++-- .../SwapFormScreen/SwitchCurrenciesButton.tsx | 4 ++-- 10 files changed, 32 insertions(+), 25 deletions(-) diff --git a/apps/web/index.html b/apps/web/index.html index a8125656e59..b245facc5c0 100644 --- a/apps/web/index.html +++ b/apps/web/index.html @@ -18,13 +18,16 @@ + + + - + - + diff --git a/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwitchCurrenciesButton.tsx b/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwitchCurrenciesButton.tsx index a92aa260da7..418be436225 100644 --- a/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwitchCurrenciesButton.tsx +++ b/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwitchCurrenciesButton.tsx @@ -16,8 +16,8 @@ const SWAP_DIRECTION_BUTTON_SIZE = { small: spacing.spacing8, }, borderWidth: { - regular: spacing.spacing4, - small: spacing.spacing1, + regular: 1, + small: 1, }, } as const From c89db36645a07a27fb748c91d95f0757f1c0e26e Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Mon, 12 Jan 2026 11:39:44 +0800 Subject: [PATCH 03/33] feat: support hsk --- apps/web/index.html | 4 +- apps/web/public/favicon.png | Bin 28170 -> 3878 bytes apps/web/public/icons/hskswap-icon.png | Bin 0 -> 3878 bytes apps/web/public/icons/hskswap-icon.svg | 13 + .../components/Web3Provider/walletConnect.ts | 4 +- apps/web/src/pages/RouteDefinitions.tsx | 1 + .../uniswap/src/features/chains/chainInfo.ts | 5 + .../src/features/chains/evm/info/hashkey.ts | 177 +++++ .../uniswap/src/features/chains/logos.tsx | 2 + packages/uniswap/src/features/chains/types.ts | 2 + .../telemetry/constants/trace/element.ts | 2 + .../SwapConfirmationModal.tsx | 644 ++++++++++++++++++ .../SwapFormButton/SwapFormButton.tsx | 123 ++-- .../src/i18n/locales/source/en-US.json | 8 +- .../src/i18n/locales/translations/es-ES.json | 2 +- .../src/i18n/locales/translations/fil-PH.json | 2 +- .../src/i18n/locales/translations/fr-FR.json | 2 +- .../src/i18n/locales/translations/id-ID.json | 2 +- .../src/i18n/locales/translations/ja-JP.json | 2 +- .../src/i18n/locales/translations/ko-KR.json | 2 +- .../src/i18n/locales/translations/nl-NL.json | 2 +- .../src/i18n/locales/translations/pt-PT.json | 2 +- .../src/i18n/locales/translations/ru-RU.json | 2 +- .../src/i18n/locales/translations/tr-TR.json | 2 +- .../src/i18n/locales/translations/vi-VN.json | 2 +- .../src/i18n/locales/translations/zh-CN.json | 8 +- .../src/i18n/locales/translations/zh-TW.json | 8 +- 27 files changed, 953 insertions(+), 70 deletions(-) create mode 100644 apps/web/public/icons/hskswap-icon.png create mode 100644 apps/web/public/icons/hskswap-icon.svg create mode 100644 packages/uniswap/src/features/chains/evm/info/hashkey.ts create mode 100644 packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx diff --git a/apps/web/index.html b/apps/web/index.html index b245facc5c0..444e28fc636 100644 --- a/apps/web/index.html +++ b/apps/web/index.html @@ -3,9 +3,11 @@ - Uniswap Interface + HSKSwap | Trade Crypto on DeFi's Leading Exchange + + diff --git a/apps/web/public/favicon.png b/apps/web/public/favicon.png index be81f693ced51ef958666ab4311df7a6994e0e2a..76f55b74f9d5116e544c4e5b987733e75510384d 100644 GIT binary patch literal 3878 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 literal 28170 zcmV)uK$gFWP)#NklOal{!eah~HRk#=m_+D#ZCs_9ZIL>``LW2ek7<=94 zF)*;#mhe9c3%5fDZZ}7ny)Z!-m;mfSd$Bw7k6D0!3k{(+XfO))Iy$=EF@z79t>$_d zGseaMthL9%lW?WuURSxZ9tRB?G#EGbmH=;Wwcz@3X$B)RfQIlJG?+3hJZ21B3oW>2 zR7Nlo1F%opD{T+n))0P!1~UO^1npzYwXi{KhykEu&k_Cy-Ri~Aph1IKW3Oq!^EaXm z6fh)6>UZHbXo$Z-gLwf8Ay9XQ{>+syxB-ahd0 zgC6LJ|AUVBFNX#V8q75uonG5I##}MTu>&!H@(GJ7|FfY%g9eL&+lyn&IqMy?t`7hu zKa7L;t@WRN+YK5t7$=_H^R&Ar)?@(o|Fdr$kJ_IRIugDyah(`}ZJ0uX24jSyu*=bJ zx6U#3Aa8#O?}d?J75$s))opgHd^eFOr{WoCwy7R&8I0|a@f0H#Y@e|m_BxulJ z<9N)h!ZXa%%wxPG)c|^MC5%)0DPNM*24jL4yXvAkhM%2GFDAp79aC%|5cKZHfjN6Cti19cVD)#t8JvDW8?fvH z@ISP{8DLl=s9dB$g9bw&(E>z%mQUDk!???LDNjFX0CYt|YCW0&hhOGQfd`&~_Aj3S z9rrQ$D=0l_n8jKH*6~~yT;R&DV6zokn6$l> zfe^(hc?87Pgi<$XFak_plxdaD!6^Eds7)1-XCt)muDTyQ*X+5@Yw@@h9iaP>F+_qLu9(6UrE^_*w| zhC`WaL!E6OLO1avCW49nkZ|udF()7fTQz1ugCWs#BY%bKKa(x=p&eZP?DWugm;UTu zgE{#q+1+&vVD;*Mq64&soD3J@Dal!AQUaM3*p9a~Uoepd;`XF}lMQMdU$$gl3?c{kz z=F_l(25Z6fl${05*EjJiX?55{3n1y`;ZR5XOMm*DBz?H|c{f7vQ$A*Zf2L`iX(%BW z8wsmoa*PqyCY&vAgwSqOUyxCi36r2xl=+DvA!O1B^o}yUuF=;E&)PH^L4&nm;8bIu zu-~>Y1ttJ21$omd^<5nk)cM}0_QA@pd?Psn#SVPpJTeo+zs7t`ZO_$ z)DBRO&_pc?U=7AFK?c}h;W1qXfJlhOCaSK|mpvnJ%kF!tOaRgOkGr7t%AJwkgL!SV zy01Ha#Q|wyq~M{P_;ZGqjR3Hzz*j`A0GR=rH|5Qbig}}f454-Dc4(b{eBvBUDPQl4 z>oz$|GsT7z^u-bQXr|8q5H&z(EZf@%4ynHoerI=&Jc6JGVSZJ_X=Ss z$!SMm0+qt1vAxjm9zow@ik@Qvz3ZIGP;;LM%$h7-wjJ6pIuX>FLlaEep5(qwJldG# zc{Hp5ARU>h+1})s5d%=BK%Flj>=%XL@l{y)>06+5s&kIE(*oK~8!&8vi%Ad;sO$7v zDvt7=mBvy__+>mKvF8Kj=_fCA>@r~Jo^!~fz|h}#R$$I z6Cu~~g$dS~3H|mTDX=NgYtG#L({Drj)z8oehhsMH1DYWNP|%uy5DY{L3EDyVz>`iB zxV0}qAQONcM@MNImb6`%R0A}YeE%gybIkSpD zTt)@A;KE7xrJ(LtPKQNCe&nmrb)I$L5@g9Is^&hBhNb_IJkVwvLiqj*it|y@8rOTD z-VZA;zZDK$^c7fn!yUAb%cOB##Ms}wIl$i$t-4WwrFTCImfrKMBvO)rL#BtGcfB`} zl<6exwRt-Y^fSFS7ueL)T-L8xj-qs$C63BS(v|j^$l)^&GM@-$%K-A6cv0K+i!ccz zMxd(JdCRWaQ=(?D`U_uo((*p(%z37*kF$sPQcHDqee3{Dx8l6?Do40tCHP0$7nlJu zg4H+P=@~^CuV*q%g0z<455Y^I&5yxQEjJ=ickV;qe?4gm)i3#vffznq!vu=WBkC+a zG;J1{z;KlU)cfo|lj_frlS!TlgBbGWV*#^e05uS=bXXFJ7T!qKzP#enlPDITA1Ho+ znLsj37i?=*;S+*aTz)+|$g}_(P9nB`jfs+j7{SF~f$r~pD`7m*6{5L-9l1@Xp?mGm`)yU3AMh`DvQW-1WY|AA4=$RTJuVt z-6pgH=7#}LAGdmgmSSVm?#KafKMet1d3xVdA`|HT#=WTu%wUO_?K8PozfKjP=9$!- z=AY!}7y#YhyAKXud_x@J2#g8+A6An|;?>HjpT(t%haNhI7Kl)X#YKKl@%bK2=ziW|*eQafBL^ib5R)0DS$ba#( zw}z5vpiT}|!J~HL2*dKn_tY{0I;R^oDepc|qXopJt)*ybL~_jvk!6R;cV>;>lasiMCsm+18GXZL2`Lp-Sor}Hv?JLiK z_7$i0JtfB8AO0CfT>GC=oz3SRkcwQ|tYfMkY_c|Sr!cvu5SzA95W&9UYc$+xLz|2q z&s5jqzD>?T=O9E)pg3!5{W*WwIYzJB54o8kZPo;$(yQY#r}lim%_OnfUgP(%(vk87 z<-91roZfGsf3p(CZtIzgf#|GFXy5j4!zQx==8pkXpgKOT7Dm>E(W5%-oPy{e>xU=} z4`zfeM`V4~rpM%cxK8@1PGq(p1segCM0?F`>Y8eVAa`aN)c~i$;^;`b&ojVqY78pU z_rs3RoJMIBgBfE9_4kgS{5xCoy&O}e9HRrlf;ygD1E8M3b*b2Vep=mRU9g;$18@KGk?%ZXS{TFy-kAoHvyRN z@~Ac5m#D)*75?~nYcm0dt|Nl(HTR{RNv;V=2a|850I3n_nbQZiZ=)uFG{G^d?g#f) zo5#e@?bQ2C@EN%O9XCwaQkjDq#01`(4UzJ#1;RF3`jSat{IUAj za84PH1%Dk=rfsToC7`2}9CwOX`PvBs;Pxo(Mh8gIxdW5MU?7UXlr{%uWphobF#)Cr zlRCaC&ptSD;=8u~j*tmBO<+AKj0|A)H|~iNEObnxr4c|DRhKghThl05mjMj|)B;dr z@icE!N4L^?^mDQjLFt$PnnZotK@9M{iUG2e41~x;nraA;+4btTM7*AW4f_so*|Rm; zLTEO(+43=w@T^*Ah~v{S*YdLu(cF?NIMM8lkHmLmAkpABH$zK()&vN_1hC{Al4Nm! zI#FMt%)H56;WRyOPp7D?ES)U1f@P0Ui!-S{;iiB66r1CBcGnQJA z8sj$7;;0$`o$f%F+GlmA)tykTZ4*;K)}2pa=@aMmeFnq?uG_C}41^H%eO4O=k!iAa z0IV4>U$9E}E4yDY7j`xx<48>XGS@)-7e*0w>(U)mMH(w7b$|ChICRz*XnMKsC-*t2 z9>RJv$)7wv{yIc#Vho0r=V0Rf$A>LHtMgkdDi&ZAAV52wlwSaye%<$f8@TtIpa#>w z0hs^|6aL7J0Q;U2sb;nGQRaXFlMSK8j*?_IZ*7n42SAj!JSwgQZTU#sfp?hXOHrB} z6QES-K5bcj!yObf#6&8&2f`4nNOk#uO+%L1gRcozJ`nj6n*wEI2*TJ(tB4+w4}ISQ z^={&|Fu`j1&-cLcXP-w-(A8i51{`{(V+KEYD|G*SAH7q_zSM0F_sPS6WKtj#2;U1& zPn-tf9yU>S;C!S54}v;7Jt)WBKlwJae(*$+y0n{B%<$r9%CVQ%rx9yVHsQxGrPyZ^ z8Xj^iATk{xa!%I`@dO4$a}3 z$BO?cyZ8cQaTowYNn>&yg$};*`ftF}@9g$3m_68~D$KEOKqla%Nav5wq4Zs&iC#M$ z!)_)x>3!C#vwZFDr}q;R7!~c;okk(gWa1#v>yD`yl5dtYOxk1vBcuW&zgFKK$}jlH zxsh=9KLtHE9Ek)~x+R)OI6R3nINJg89QuK>ICpFTv$aD}j8rdSms{@IMvQ`;xsn)) zn?+bBXRnDBmHeUUHsAKmk5W}>{k|zJ+i8p#LT=97O0^g6rQ9D|7(X`}Lhn!qd8X99@!Th4^e6+7z*U)PTdJtR7< zY$UqJoP>GKmta&NGa}6dC1PP?41{J*f?&f!mO~Jpg$x7MfQa9~K+k6qAOdyFfEa?i zXJW#TJ^QdiT7zuH2Vk>9yPw)ezK;B!IGtQGGrazm8!oD9T1IInMqN{Ev&Cfsi^Tw# z_!a#FtB_9eq7w+`7{rUP}6tApVsX9OqjKkyu30Ku8I z@{$`#f{u#i+kODdu^rzIWdg_}(a(fCrhcagv*ugAl*T z7#||YWo8b65u&HR=bWki7@x+HW3(-tqcUOo8AAX_>n<*^60pD;fZ7iFV(GL1ti-eY zsq@JWPwIS>ocnJ{y*>Q$!I?n&%G1DCD6xV6n6x8UWs_>g)P@deNF#vA6T_t=GqBMbkl{`D9Gv}*g;QoF={E}0P>3P?#7RlSC*7_Z5iyys z#;>@~zC-J3fVmc+i_BUuk=fG0i_ZWSXB2>8>Ljs$$uzOX$wx!?&-PX%bu6#t{%$|o zsnq8V)mUNzLZAw*b7u@2@fNjs(lGHkF(<&P z!f*Z_SXAJyy;G2 z1ZW;qOtrwT`LT7@xOW^Kpty+#;=2}KAP+@G(GPJ<5*7-ZgaO2-PR!ViF?ZhXOabQ* z^itCbhmI=ZOHaJwX-CGZ;d=h9HqdO+#0;zkj0Xi0nm zVHz-=)Ktfj<97SCr@^S`g|J}lf8tPN%ax4-<@;evQ#FCY8MHY7&PTEIhtG!1hVqv0 z!lCE?t@9DwLGww(=M(*Qtq^a}55AC$8#dKt-t~x*aNEd;7s(7*Tn!+%?-}ZSw14>w z=zZ=X=zaE~P(%d82T&JH2X35w>En9_VgiU&XD8y=vP@n==i_?wsibJ_Ibmciz&ZvX zZU>dG&vYGqQQ8j>G#{lEU@(zi4II%Jnv#4?X}G}X{l$ZD_}|_HUCgf3sz5;9eQS+~ zOuwJHB_s@K`+xDV_$EMZ5VKoJ2rxe8 zq4k2n?t9^YnU%lwk8s#&1Q-vX=@`S1H7FA9Zd@;zx1%m479Owt+M}<3!8Xvz7fHR#VSJq2{Y)t>+G>)G0rQ{Kd|y9 z%!g1zeCVT5S|5&#kOtt)!p^&QL+7o#{KT`!1b*@s&p_y8Rrw=W5GJtL8bChgEtNn+dsdPf`iJN9s$;sC7wvz!el#xMD}&wwR_EZ2Q)BmAB%ZnlwCY!)kf+3hcjUm zV2N+T1g}RTAkKCqmldWMHiY9b@rx(WAC8RSxQ-th-9%2o9Obh+hf&%Kh!)S>3hm2Ig^i;3#fPDCQi7?>a#ZPr5<_95vzob;&N6hPB8wa(v@V=E zP~LMO*=4qGiR&jF6}yv9LG)(9XP*bHm+kOO;AOYOL?RJ9HJEcou=orhdB7P#hwmvk z=+!&v#dWX#rur(Amf|$ys>A-vj^qOj&>RdH!rJ~JR=|7g(}=Y8FP*mW=s@hexA?GN zs|j68e*TW{Nwffv7>H=Y`rolHffa=IB|A2)QxK6SXccu6tAwR!i&$alcb-KvGTFNh z!0KD?PKm#c;hOp80GmVuP!CzEIq2_!%m6e8$P~aaeDz)JIkOK=K7#h~ARs#vnZW)K zr>=Yt#9XlEz;8bjHi|A58A+r)U)ahbxizh-s`fy(N{m5i0-e{LL4`CnBkcaCYW*|_ z#rr|WSuk)ab}UC$e)eI{1ky8C1kgNV^F#tNnE0~?Pek{&vuGWQhoDD2ao}VOBRbXN z+oU>l118Zh6R`IlsA-~46542N0EWJnq54ju?T1DieLu9{R-97e3NS`K`Z?I(9PIr1 znF9}tE)poOgI4^aP9xJ=V4m*Ldhv;{{Q2*vVP?!gO;4VjWUiUO=7|K<5?k+A>KT@M z!eK!&1>V0`D1|j>{s}D-reI_plY5r`@8=E{HHb{$XTJt;?}4gB1{@YVjdI;Lf*$3z zD^Ipn!dB_-S=(CpD)4Qhzfu4fG3q z>U^gO{4+6v#N5&^rk|!c2iP18fK}XFC5Ea;948Y+P?+$Y2jno&Kb3rYh(lyrLhcx> z*eIRTX&Q%KdJ}Y=)VBI6#wYc5{`1)zlCTui62`MFq(v+(==cMr!iq$*u~!=zD~!ir zp^?x&`oCifEd9Ybn=4$Hhw@~HT9uiCA~Cx#z%eLK*E5bF#)EA zy0?@OKkdHY1XAA+D{sF$Is%P8E=ta%;*KIBE+9H^)Zm-$bgKJ4wI^H`O_Trf>&0?T^~k^`hLH9%VXYH{>{L3HyzM+`_)+yjTc(MN>^1uobJ=Vk@fJuHM^A8qr>BEJOhoyJ! zhRp(*Pl7hW&TSnb?mC51IzyRuF60ZvPi?Q)_!}Rp6VOjS3*TSKmj) zLozd%5A_5Z&dnx)?l2fS-1(zt4<0b|oBs&i_vsR0LA^kY;x8{4I#O^2XErkGezg}f zv|IDW1j<2W)w41@G#E}Nt^#BNmu`2X1EYmB&n3ch&@(AB5XkOY)xebUTG zSOR^4bb!q_3J@N?F*zZyobx-{ukzuZl-Y;HLvn7B{hU4NbOz=#M0lQnsdV>%JF)x-`a8M zHXRXAnUYD{6cgxNwb)Dm9h<3o@3*Mfs4}UrZy@j)_pS>*9QAySRD;cs6d!=O#U|7M zAXRy@hp)MI>s31`I0&)&_Ip5F=iC7bNXtv5E0M#Ss13BQIK|n?g9Qw&{QKMDaFm?S ze=q=N>7(Zk6o|uGj5bk4gUJ$;YN3WXMQc!_AIt>g+=X9hFR~`kXGFs&r!GCuyJN&) z_dnh1t1G4MJY z+awqByKNxe0hj=KjIp4lO-~U98l1ho!#Nq>wVND`x(s$5&>4u*%IMB#n1+QLz&b68 z4bW{;+d78;&x;|_Sh9T4h6wAbHIr|Mi-Uwd(o^#%P?<1i4!{FXdO4vVr>*()lR|TZ z&C38Zv>KbJ#X$Mq+<8~gA$TAb-h{droD3L4YC|jHD}G}8;I@1qCZCXF!Z>^&wgM=4 z2@91hyN_;f1yue_bv7Qd(hk8j+hHIXDr8N7zhg~6wGD%YiWfZ{mjCL4g$fob&P<1I zQ4_;-Z9PdUEpJIDP@&==IK3Jxi$d_3_NcM02{t>lVY7n?AXCveI+o|C!@1OzDu$h)lamL+R57msmi?3N5QPUz0+R(`6}-YPbN)ENkzoP^m@rpdGF=ovMRi^IPr)H*<9idr zw)r`&8VOLR<=<>uhsQeUO+#+Mv8GSN{Gj58(EbRM5x+P3MPkPW4GG;(3lkoKk?Wd- zuY`7l_G3kzC1(g-t+*De84XnK38%cdelb8dL_7~9* z<_nvf0jN%FGW9*aD@VLrQzAvrFRHRMzhIbQ#!odKI6@D?x{tZ1iog~?&qPD##;LV$ z`7W&4#2s9GA|-zBZ4djzBM+3NmrwGM+;5Q7X?5xi_B^f5(GOzAPz=WJ`3XmD2oBNi0D|(Xm^qXFh|SFaSc6KKvPP)As;Iygbj1ed5O>GjOVlI`Q4wD|LYD|50py~d;mhGEKn0yKFIK! z5MLtsO`@)w3TN0LR0poG5oS2jHe1<8;lm%IE|Q} zC?*IBYsF`iXak7(qyHnr1mKuQ2|b~W;4*Qm`d)z zykK)OfIPWBOx9t7G!F*_o6Smzt;%VrsK>1UkFQ1_4uF^h;WWW$1RB@Jslc%YeZO;R zklKkp0;XlAt6a4f;7ZAcHXPxVw>$zp zEPH;>6B8Rjz_I?NkDcq=M1O+9j_urc2oAp@n+j||AQRj2m5btgBZbW*8kl8mZjP|| z7=R`c-RXkL?xl6uQF`u;rMuPxc535>k2wDywF8tEHY+YUC{X%$-m^QZ{zfqX3BC!m zR+xmiW22zDUpP}{4vY#ZD+ZAnB$CZP&qF`-cNATTMMa}cY|?P#njR;&5Y9~u!AWZ@ z;Y~9mkC7=z2(x;Ac#V}`xNSqk&%ikZ@V?pqAp~DQHj*(6UjnQ{+Ilp@fFh}A6$HBG!z*{J$xtqRiZ!{2{BRmMRg zi)q8Q5|lWIIvjbKKbVSbAj8EaGT;ZFB7Y0j=%;;$24)fz_Uo81rgLKqNbmCx!Kk43 z`nMN((?^fohz|uK7nlDRS2#)4=S%u*6|tGV_LD4m9kE4BjX$0CKHP zHFU<x-Ie1z((%nbO|XthxbVu0zH z0c@KC^PTuyb-cylXMM3&4Mztm7EGy(xdZfdZP0q{J*juCU%5QO;Mg<4|G?jAL%fE` zSRTW-@jDtJKyAVKim5$0nV$#vI7s-lY0eZ~}5*lrX2@Q?Vg7;_$z@eoe+o zjNrA75ny!S_M`O$gxHf?s_?yd({&w}Cq0!>5U;porj>q-LM9Dcm7C=3RelUT^ z75R%=Z!-oU>+zASsaeP^+Gu@Qko%3vWZrME>iSW?h`}v)ywEuq+Yr@%#dkDgm@zg7 z1JKf6)Y9-Gwc`(+eiwcPCJ9Q-z2qclzwksbSj2<4ee7_0TJl8j=gvOJZqMjgHCv-M ztKKw;jwQo@Hik!6oUH&WKm2#zjvf*iYfLJ;W;X)ERU>9hv(I zcrnfn#^=KDXXDeU^)n`hfY12XzA=_(j0^x%ZE-ebtlon){ERjkGJa>Xef&kNrr;@A z>Mii2QI9Vim~a%uC(`5iMdCqjWMTDJ@1!#A3@YN{%mA0LFlX@Ih>U z8`M*b{=<0x700PZ0d+zwAcE5BEH9-{%@=~FgTf0{!8~k-#`kTQTU9%itY#X47IOuk zFz&bfn`FWdP`wUDhlRumD1lXo(to$Ok^?m!2%!r^0aygO05H^`ggdK1am-BQdBEVrqc8N@TXM7O(D3E z3CQ)M5eo^|m{4C6EvAfZMxvY)aCCuU?%k)CeMgMJG3esVZPW%#@kS3GJM!-Bs1^*bU)eQICoVq@XIzTprWtU(0mt=pU zHK4X|mS4~7|NFbJ;ePT*7Fa}(`iWV<=3O|Z^PXo>fm!r}P%J^BU#n-8bd=d)bNB#M zhfKz&OYg8kwG8e5L4m_m?bn{35WbGt_uBx8-k2{dIwnLrKy?J!a-9Y%5pf-Q1lhnS zQ4jbCHvSHM4(->U0qvJav&(xrP9lY8UzkRhp7|ZH8u=I{d?5rIPbYpM9P`qiBxmxW)-M0<`g_i5?L; zBvtfrOZ3tXlAeno$^YwTs+3Wnmn7S`C^CYoQ5SQeFKyIgOJULb)IMKxJ_OLTuR0xC zSDYHF|I$y~p9i0G$3EzWGW~q?7;@Tq>si6h^yiM|2&8SSi#6CNRA{wP+x*PCj*$(U zQaca8VM(lBM8lJgF|d7ajW*d#8WjzYGXL=YOQ-&?{>mM&eAf%;i%QgI&P-;6#nu3{ zL`s}dfoGTA4{+$T&kb}s3f2AaxwIsD$?Nom4iO0|aByZ0HjWcl+sbV;i3IIlx6gTy zqju8y<8z?x)O_vO*NOvm$h!}~;h(vc7zWPTyYz|kpb%3f(@L~P!WZ4J)KLr<0t3(* zSSXrOj=|wNYnY%N;OI{K1y2t<*;oJ>O^~N51a3qNTY2@@q3wnPi<6J8i3BuieRf#v zf*^tDcwNL$u+l;iIy=@_cWjlY5lLU|B3n8~pcFZ1&%>bB|EF?iG zy3gAof>K&PzCEgHn(&Lb8kqr9nFDJGY&UX4j9RxK!;^=9I+c=sVhTuAYGwjqKM%d> zS!|KXtzPp@;TaVhU7IJPDtwyYGkAr_-+y~fD*|r>sA(ZHSoztnQSlgbD3|#JGWvam zedK5iCCDnV1_%~ZGgQJCz9d)-pbNHlAQrYwd$+Eiyum=J<%P9L>}b*0jM@=aZ89-r zl=4Pv0#=os3cLb4QSK=7+cuRJp;Ot!Z(u8$P4E5p13cbk1r-u|Kj~j1>YO!OOhJPJvqy0{x0RRNNaf$`15big+FIg>_P>ZqseTbrH5^eZ8x4!e05sRM zx=X7lan^R7nmq_aqSmOjHdk|%nES&j#R2I6;nX1 zruXTzY&A-$?gzdd2~tPu@zpg`7zOH7{xQU&ru+bLv-7UOCP`gHAS1w>609bLi~yN$ z)YQQLDYZrxh8QzVATsvZXaS4K0Q#w*;prNdxYieW90`~y*{ge4NW>ulKR>QZhc3Qh5$u_Krf;tUNJqUX)R zEPTkD{=%ojW(G3?OfTP{0z-}m~Tzg>_VAB966zSm1(3}C9sDA)Df|Gt{xld_La(Y-$ z4S-joq&F4S3P@rOe9G-xl<9KBnpn1Cin=Lz@%2Ex0()llXAG#lUZcH5uQ4Cb? zPTA*RYreBJ`-g^!Oi=OR$`VIOj_ttmAD#n83aH5JOPx0G!TW;zOk0A97)6t_c-0HDV<8E-f7oL1Y>8|BcssW1W1G-HW5(#IAUhq}qnN}t@Q z)9c;O+$Ixm9tptWrK|6_7gpYIC)FV|Awm-LaBi791jCA$2-9H*3qK5)XroqZ;AW_L ze^QXbB&UyrJ17Cy9hXNcP6!x5C~c4$bfCPVFkU9a=i**u)wQ$d)_LWrR1)k+0*>_H zXaP<%DzO~w*kvZ5HG`xRPgq(6EPNo4fNg&cQ^ldOVQTi%EWIF-O}yNow2DE9*rrSQ ziK4|~0>fiCgxS7yhYCqB^=+GkWU1J%(g+Hh_V;g~L-qKNEGB@y4~&W|X>`X{m;lct zl=Pb#AIqe$@EU-Oup5wJRZ-=K@&OzLHhY8U>YD3SaOa*Np?B{fPMj-c8umGWTFrKD=YSv_BlPWGyyCg1F&j^ zA0RuW0|9&WfAAqdO1tGwE5m(CYA2F)y|)o0p=zdXJeLDode5^q94SYH@6_q#zr7IJ z&bE$m${D|6CI)6Av>zLkuA4AQz^Xqp0h(AnXjQEjKOL6-`hravE!Y>x1cEtW*)bS$ z3KETg)ma_LH6bRjSPZ~s;@E)1o=0x#AL1}00I;d{k{-D5jKEGwDa(CxFFD2NolrHsS*; zZSb;M$)v+*xq)i{IKt|@d6$<|D#OnzwKnkw4Aj=Njg=+WEWmXvb#>PPKhBTEKk#x` z$_gEmn3{~W2wmg2*1ZigTyU@wHxB~wCt6YFf0!u5e&QQ7(y3{yj2&Bs#)3LrV$qiO zeQVPP3^A}W(ehtC*E>mz)O4bL2qqC6lX`!PR}VntqHCL>13sI1Rt2qThm^g2b|3xmC2>_X@Z&Kn9 zaoD|EA028cX`1p|Bx$T6A5H6xJowC9(W_coi|QU#V^ESEv?NFMxiZFXVx2;W=aE_k zlQJIrfk#WidQy>Bn=1vxG;5kC(djs+91Wd!?uMm5I_HS+4Pf=;^5*ZRb61qY6{VjO zCgcoUJSSjAi&5UhB#faX$TnX+mQEcAN&0Y*;AW$Qr0c(lG&hO8F55+1^`;0!A_+t< z_o}3XFe%=}nR(Lw89*_CB$+Dt-orBE;~PLm@WQ9V^7R)|O#NnO1gmen!wV}V+&ul) zXm8_J02Yk_q-rx|rKyL;>6YcKLsS7e@A#-@F@@Po3U7#zSk$R)ueMYVF^Za7CX?{$ z7?$i1mU%3`#4qz73zJYA2ZGiF{0_e;)c0YSkTw&|#_z|Phf5zhcT+nF(dU744f+kg z&_mjZ$*2z+6BdI3h%__R2g0@`c&8FpZW+drMCqyqGMhR+ycCmV$~reh9+;=B`te&qRTQ(zo4WD{c!qBfv*(RI^9@?(rX2XC9ICSYew z_X#StYsv)lgsJkp^+*gmX5FwUI%~HeBe-OfF#FDEqxeLGm zGFBKKkltm26A+Uw1|9lCP#NfxkE)8(=vaV!CfW@_tL6z2XVN|FPStuyr9baaQ~|wz zJUnZxpa$8L(J`Y6(q5)aR~47?Xhw1tI-dYK3RxrAEItCN2KD%A;^dx&A7=p=Kp;SE zI%}Q~k|}U(oJund0g)uR1kzf@xU>Lu9a)$2n~bPU%;r;Gepw%9o2CV=2?Sq_X01|* z={rw}Ip*synCS0-$TZM2Si%tl=Ofq@&O*`x_NK%SVMWQ0abvz2fOdk&w%_1U6T?F% z5BM_9gMwz)xnzg*!itj~W`?gs#RZhEx)hmrn>&g*>f46S)r9B7M9 zaPtV8t2-d(0lweXi~kk$KKBrG-@i9`7aRiZM+dB8+`%-^*FZnPZ#zH1m;a4hp6w@l zSrA|h3p)a9HQ+I0J{dsb{NO35Z8}4as6m#BF%AO?``y7c08J!(T|%p36EqkZ>||Nv zxl-=KwhpXbeIEc0=Z1IV2U4Osl=u&n166oN&?eeWD?mnoQ@$;NR?z$6L$nmOW)v}q zOtdgA=`^1Vz<^SNd<;BK+pGy6|6}pRVG~HmdmJ2WdUjn3EoM6trl9^GX|Q=`w(&)q z=m<18{rQ1aSovjT3iL6PJQKH(IJDNF{03<9C0fC}It|$jupo0th_joA2ghg&%ohVl ziX;T?mk~U7AYzOdMK$Csv^4wc`6mP>V3a{!tzJvQ!9{JpDKjzH_RAKf;nOUO05Z; z&L%0NAp3a66-po7Kb-V$qwOC$2gl4O0cy#Nz>Nwpc5rl{)LRJZJTqIg^G}Y_x%+2( z{c$!#ds1em6`6qb_6}Y273eA-kUw9|r9t@+4JfT(zG4cn1U$7hnG_b%if&p^jez-? z7$l2u5=RJt4EIF=ZK>iaeue=J89C`sr{#c?K=4NQj&O~J0ZagzG8Ls7rNeV_76PRq z2FOs^b~OY{-`#ys%)iw)+(FLZ&g)JCds3B1L^!}szj21@zE4Oum7;BKS_U#{Nof`$T({u z7S>ofY=bpmqA!r3wS#R@IqiM^p^8e6o4uN_Zww-$x%zM#Z!`;Rze}4qdH@h>Ga!m! z9{j;MGm9y(_Z|$surMBAQ+HTjAIgxJEd%g|cv#muezsJ1kCK0wcz;IwwWlTCAYF`u zFF#K2YJ+}IqdB}O-Z~Q*zOu*33^=$NTnCC0)|mO3=juEB{2Qn~q;fI%?`mO1GURN^(MneNAr5^w^&hLLB6lAeSoFhj^f;M!@ct)m zVt{JqT7$77Cpu;STN5?GItQM;>CsT8!9-uc{zI_tB^@I;{9`x4>YMH$yI%7hzhUZM zd2kd;W@zveOp6iNgWYHzmG$i#2WF@N7^Tw$2tnGw?Lj00&9L&C+hHR>TaF|Od;h`2 zQ2-eMFfeWhOM?t~jRKbF08%8>=6!+>b;O=eqA^U_H%t>pZ9o`-(gbu}ewhqbI|q2R zn4(5-U?nsV5=}rbCP6hD29U5}NNpPHIUZL<;n9GV4cPq*9QS2NS?&s@hXyob{}Y5& zwicuvnhSy8YEk9Fg+OJ>HnD*#33|yB~os3e|t_^*8GDmekIm1x6E~@%~Q`Y=A}c4+D6t zO{dGkGVhgPILi^C+%-1Ns8NvMNWtNk-XxAfF$wVe*=Q7f#eGGpMThpIY2ciNOOuW+ zoKUx%G6RU*-zZ|YEE)Lasw%0yFFw36yFZ}V^EA0Ozc*|69U6&CskO5jj32?I(~Lh+ z1a0uoWDLOD?@9w014WRd@J-%P*i|tlhHY=%=w#J%3}4OIFLC&ABKZb3TjuK{V!8}K zRoS%J4T*oKgc#|y?+|p~FkGTfj@FNF7YQ%nz69-JZ6yEHkoy3{E5onJKzUc)tWMEq zMC1Bf#}~uKi~vo8WX2vYI;;FcM*R!7keUU*y?cDxfO115lsd+)Iz0xE5xgD%&>zwa zdO*n_IGN%wj-EOgiYntNxq|kQ#Qw^K8%!G7_ai1i_(Bmk&7zy**o@$}jz5SM%}mq= z(BA}s5!m2|(kaVH`;|GsjzZK1mYp^*3KKBfmH-r^sg?R;=(AJR0F?Fbkp%vL?*OIm z1Q^;mayX_N{xcjJtb|h~Q~e z@1BW2Mtu8`0F39a0ii8k($)MzZh$|XH|L5eRQjPnBF6-9*ifuRRhy!cnp;!Nxbxc6 zp?%q@FbvGGo#Y&RZXT?X??%Mr89+j1keJ*Y*dYNPI634SM|1ksU0!>cqt_-osKI!V ztEsH;39)CdA`p{L{HdZP^EbvHOi}~Lfm$gt0tngw2aeH*5(|*P=V(PwF6-7izkcR$ z$weV>O#;*sm4AFHz~mS}Zlly`0eau#U9!7Ib^0Yu*#A^eFoL?4j~(l0$fBshn4r~u zTmMz4?Z8=nnB3D({WqK$1$*Y2o2C6)TtUjHzpOHSSy6#T@#y7HRa;z)tyH0btuCgmSRAYRvAEM2}H zP_yB9l_>13l9#y+yKzjM0q~>IkY*P!TObrrGOOdQs+s>Yh2;Q&J; zJj<$150H4x^-g6Cdg3>0)^==NvO~q_hf4(YdR8U9&`FIND}*+)h)X7yu}a{8Z+o%l z_;n{c#fnJb7cgl|h5-boPf|CiO7c(ana~k7SlnY!^#0;OF#|Z9)OS1`&Y{}fU@#Q}I;QEZOrw#EbDNQad_Q1#nr6G}XMVU^eHtv)TX+clisu_qd+LDh0AMN>zU+*gbD3R-u?MYiGAWwpBJYmeLbe9JD1*8-i z_bU}JMEg`2bo+{W27nCBoN|;%|B9gJ%*46X0O+QD>tYSJIFW;JFo)IOycec{-iPid zMxZ&THcOMST#il@)pnDjPO^*R4l;%q7^e`m5tUvBPsF1i)qW}CR_aqJ;(z(ARIR5U z+E<OLqYK3j!6T z2iTepJOakg0P2!zLR(GPz-8Znj|qV4#0ht{UOg4Zm91}Y-Di=Z2|Xu%-pHMGrRl>A ztU4EOtKTNt9-l6LkMI5PkKVW@@gs4xF4-R2!V+IiA1*4k^RBlpKLzFi$OKkpl24mt z7HS@g%hsjUFkzY#A#rqqeB}3{{fv$YXaE4wBdm7Xl;(z=%WqWRD1(?A7GkwwvQMo@ zu%yjk^J?Xb2d2$Bo1NDaMrWgBSMN>FP~({c#82|u>=MB##?l`Pe6AqzufhB&$Nt^B zDb1E@I2e-@?KI*9i>5&P@||;`1t7ZbxR+uY^fT1YMKqVpcYzE6M*xzM1l9jc>KGUc zCgcMM%NpT8`yA(AGv0ebSpBVgeWqENz8I@Jb}scx8*PL!KKQXBd%jhzCF8yog01PK zqRxkpQRn1(4f?qx-+`2HmvcITU;TyKVD%SoTQ}Hi`H!CC2;pd2Ct@ieGBJ~_vy@!N zu{Le2{QKLIxE5=worj2BF|GE?b|`{Zl%J;pk5MR%mjOrziY?S77kO{@+PyFnI8#7! zzC#E1J_?)Iv4qfUYIEWjm_yXIOHpOcg!4nxCQEDmwfEaZf@Yo}QG5VkC9WcT_!vj* zIK+o4fA0$q!FnLcf3}bMOQgOKyNSKlq|X2yYxAN7@aTX%U+hCBrEhw+JGRhfal!HQ zLFBmv5$vNGpCp=q47J}^Ti9@UuWZyszwicH4ie&x#NTpKP#k3mAt<$y_XSgc zD)Zp#Hq-*+Be@ossw~#y%6F|&c9&lBsB&Q#3@YrJjR6aG642;f)4lz z`#56)lPP96?GnNUO#ojGwTdO1wK5-})#@^VS#~Be$HP3&K4dE5=CSGw zpcDhE7@L*DaxExT?IAUpf~rrC<$YRd-PMkUL=w6-aVxGB;)c?FfF(F}odgpjx$|uIugXsp12vCv| z2qi73w*SqKxDN6)m=|DFR{M1!Ut4Ez@is(`ES-~VQj^-G(*zTLWgh?=T~d1?Cw%aP zZ^CwRrocDE+R1pG;qURC9$fWv^PxY-X;UceHp1AESeHMx2jG-w^8*t#Kr(g?nG#^t z@T4#@$Dn%H$6hf%eGGFMmOrwGBKS;Z#`Lb+2j=_}XzZWI_pQ-1pQ!?4^8U-&$I1Yr z3J^O_P%F9ad+!5#Vf7u;8UG&?n0&GHhv)cNX=RL=dmtn;1~c7zhG1%aHj{%QSFOU! zssWxwH~*Q$s(TUImkEes!7E5pj^snBs_{pQ%EMDm9wW~JLq z-AzHo3<@UQ>TA9}mZCD_0?jq(Y<%i7g%Td&-dIBxUkBbyVdBdX?Q^^xZOnz$Z0)9R zzu%x4PX++0g~gBkZ%};CF#u2WpuG1W^#1FEFbUvntSB)^8^E#WLUls!SV8>Jy|9!t zQR|rwYF@r{5Z@@1eaD1O-!idhOoG?T?>y-U{UDiXB-L@mWZ$8&rf4H@jGqYKNxnz~ zAnOw8mNe3)#K13yIdX73vWAAKx8*H2jJ@p}1;(LJl%J?psb(WurVTor?pJd7_@&Hb zHGnYOX4q~lORDwP`}Ep`j47T=AN<#qR8JgMS-IjLCX+TCfHmB(a{|v%A2@QFg$7v% zRl2De|4Z_xu3-^O)Ter(iUXpuN^-J<7x6Bq(MPuk}4Uta*lS;zW!P?*fuVX}LUjBR3l3dX4c z)JQ^7Yl1_GlRxZ%-ukE7TA$~Q`<6d_J{-Q}=7})@3{Wa>ebku*&v7qntFC08QIT#K z6Q`*#_wgY+sj~UCv(iA;VB;NhF9PrX3rCgU}3^<*1WJ_cISdXV*6HiE)ad=dSpK_+g?Lp9Y}COCWk1 z9D!{ABUeUMdypWY_8b3?`Z{XvG`$ah2UdUkA7RoUliR9y_mqcg1cxrd^c zG4SU7d!hGdd#BRriP&*0d&d@Nop*v$@3DGMCp-)F988VHq*7#){Rn>6{T`)NEBqX? zzQ^-Q_C9d`)Dq9u!_r63b6m#=n3Sc{Y7T`KWJ_X`OjB$RYur%5B2x$G>d_;AjgA7wwmmCxD<(id^ z7S_dAqqOpo!JRrMcy*2S2%iY|ramJlwmYpFBQSl?F;d?fb z`t{~f8ug}6vYz^z|4uy|CVpbl-X!h3>+HEO1xidvLyeN2n}2xTTrtrXkkirxG2UT7 zB@NhFliR2?;lThv^}qGwHTB-`JP#h4iu6w|>zF|IH|}*E3A5C!PnB(j29+jtM2+Lk z*)?{ekb8U;R^N6v^!_|%RTj^5MD84ysFIVX9TRF$TjB$hfK;1nx3*3~+iZIsI%PsO zb=pxa@#hB(3!4fe<29VtYfppjj7v-=m*O(kYvI&raUE3{v=(>Di)pK|-HTu*Wh3JZzHoFgmUxmSPZ zpUB3i47i_v1_hXqhh2!>KkLc}5)(thq!lvlja7E25z>jSFW>ncqWe>VF~LWzM=tyg1_@Y}z9hLidyK$N!}lpM#$ zP2ITwDw-M-yH$6g2QzeW3d_v7T7*pvu9-$;Md7%ea!I0?7uYGrJh#!H8Fupzf<}Abtum+M!JCz?R13U46 z+w?mwsjVcq)#0vMs%NFS=rw5JXX6KKrf}qaENtgv0o*Y~z4jXrH*Kow7bZO?pJY^N z-wz4B7{z>)_~+;C+BQp5z$a31-(fjm(p;ZJ1DqTtQxOOeUW8HVrF=EZI_~4bzC%#0 z@)Sxz%ce;!EJr+z4{o)j^Qdsd`y}CJfZG<8P?_Z+)SIP%Mh0~+m;{5i8O(w z?X0NZlSZOxSVizqF-6RbO#$YayspcsPZQ%W2vW0?ZqUT_)_G5ZMTge_5?Kl|?O50n zf(OWmP>W&M z${-RAM(>BoNcmwvJ=;ct$EGTWCFKfSaq7$_6|pv72{3)uCxi)=1hbW^ux5teV4V2E z!>GDOB^7I(A8JTIv3mIO2zm;sP|T>gmfC2ZKr0sHAUbyzou`hglQ+&PN2k- zz8_nE*!&<6y{+R+UIcMpM6Q6-cFzX3Uc1lx(1aQ3gvx@eZIf*yGjM)@V$sb2Atvrv z*?!*4h%ZWEMXaS_5*2&im-wP=N?{E81EC0plKR%Bi7_@#&t*!h9AZ3^kFBvi!$w~M zR}Q{usrZAy)U-=$C8UDJn>Eke8Y@Cg8~HN_wJqzD<*;Ke2m(>mbEhg(M#gm=uuRgt zq-kyhX4{gi)BROAH+X_$258mMHkR#@-zM*wRs3)*fXFn$@lwBgS@IGb9P zYcbF%m{DUK22`j~b!~87NtV{*t8nO?FTtW>%k4kl6J;7j7p?IC6Nyb~ys&+~0X%;4>0sf)3e6YAE5xzT1Z zLCC0};iIjcI2r~_w_1EcoKHY4^gM)|uBsUV!7)c7c&8ziUwC-zk_qz~diZhYroqgR zzu$3^5Z7aP0y-ZxQ?RKzr;dyJrqgi;f@Z)*y(PAKOnm08Fw5{%v{J5*z}j-IIm)(~ z_+y-m20*ZhJ!yH)bX6P#iGQA|w+;&ID3lqqQ9Z6OpdEA-sZYFu?RDd;?7HWH zQQ?RKfqXB3sfiPBrgDC4Ma6RI>ySDnc{{;fp4NN&T-?B=;>Dj~# z6+u)gejAt|<*I-B!MO-_BCW%HaFR=`h=h#5a2fO>3Vcel1*2UKAe@d>BRdC7K-CQ} z!ijmrMiCeaD9jkV{1i3A?}VDf8L`QuiABy#qPf6CG5%2igm|qG!J!rY`Fo2mVxH!6 z8wAuzE(vMMO37hiuC*RNZqHKQ%8WWxu<~;cQFSELfH1dUo+2F)Xm(%$*TWaz0Oehe z%SeLF?lbbh+|Gvi&;THltYOKMj7STEAE$lU&gn-8Y7;;&r||qH!vGL0Aw_*ODsDa+ z&!}!L(vTnx8HK0DLue97#~ojd=W_rLJ3d#hxepFK=Wk%;HMcFqCv@y*g8)mT;RK)d zJKiD5jDWxdrKGJ%hBIc(1q@V1XV^;73PR8VP%E9}^kOtCFfKXAT5D6xj56Ap6eh<2 z5ZaHyS^!^_Z?y3B;#)76@94mm^OB=YoJbB3ffwgKur^ume&GIvCVUOA4crLb&p#An z*M$kBPT#Q8FU*w0*+4MKs!@zUcDVnY32FhwnOkcnKZU-{oFpb_0^}^0`-YMYiu-on za_0O@?VJIp4r{-2cVN~wa_d0k9)2l~{hJ?wLylOm8ttMJz6RdQ>Mz~~JuEdIVmf42 z;UvcaB6n2U&|JWz8zO9lAs8r}rZ=hnh;bMMW$T;FB$yVzoU8^wP&N)io-}WVr@sBD ziQ8Tq0Z;5m6>)=O%ZKyE&Tf>W59`q5ymaW?vkNx5F${3-dn}Qb5PR@{SZgaG(DI&V z3E|q1NMD`MC{{R`0^=`Ai<8YzN_=w7I(nZD2bcl_@ZfALqqwZL#pr?0FgvRbXbUbm z;s;g5NV;&=kFdkj)Yxtud7dVvoFuyM_(z&?NHc(>+X@q~^P>S|Oo*Cgl)|FS)k%y9 za4Nh_h~J7UAW=uAfXOoeU4lkAWA#lkL%@f=G_&li2z=?7B}SQIT-z=LY9!_hJHTW2zA;Yj+AQXhxO7CEtL z6rf|Ud(Ah=@hMV1SwgB7%tLH|dWR<(`5>nI ze5PgsWW6BSoAi?cC_8JC!!UI~sgI0j`LCY~fY&C^u!%NH5MDOui6s4;9ekuo{W|dM zN!kXe2smv5%!@OS!Sab6f;?J<&On^Zb4+Fc`jhC~VeC=rE^1ALt~_>nhdJ^&colkZZ`81%px*WoM>QOC|oe%_BAbj6Q-~gts^L*nBLGvp0G0q(C2WtSBlTeFtH*>HH z7C&xO0`o2=F||7754dO3x|C;gGPV6#stV5qtn@`n$|-gGB4J{T%BcO2-pR>Z5}yO< z9ND(om;Odb-S@ND6qg<-)IN}`$Ip|j)&@H@Gn$|&&pBiilphveXk~02VC4i`s)i$@HOtWd8f@i?)3A3#5dtT65vE* zyXfeA5)NH_18fv}9stmGKbgEnnZ*XCT}xrg8UV!JnHP}IS^-2Z*}3wJ4Ko0mRAkpN z6v9jK1tvOQxGA(FsQrls#-mm^k;$vS4i?9|=M0_SKHE!u1Ih3ttz)GbE`1dsQ+Y#_ z$e7#Ea?fV<_rFDDu|@@&0iE+t@C;lSt5)w6^Pi)_A(pEyhbJj5!#`+FxxTbfvk&`U zWX?J910?mqr~EvouK_Ulsx0}rb8^9uz=84E;MClMRt{pKr!2!4p6Da^#NINIKupc^ zmL0ldT4DmF``Eh=Kn2H~vEsjMS9Wk%0!2qzRhzSWr zRQQsJUe8CswqCqe6i8t*4}L+?u-Hg*%2Cid+1Y`?XF%VUUNyu>ICQL)w>;vQ!gQuD zYdN(aKNaGCqD#p~y=(i|7r+jQA=mg!ZFoTbH5k$+iap1}%Fq4%#!Z3)=xjXT-p2_b z^WG=V7J_CX>d5>c8?CUaiDqkiL#?GS@}PCv5D8ng`De!jXU6~(0g6pZtHxK>f%v_7 z=C=4Vl<*i&?T8*#R~#+C`h0OLS82J%B-=9EHvh5lxQgHhP+Ce*nG@y&es&r6DR6dP zIE{{{3O^`)v9ittaskjG)xPYM)Lg+^*?$ODoTh|Q3TF#$z3Ayao&h^D)&F~l+D3&w z-gqZ;-}f!D*HOKta|Ck%&%gZP?}Ni5Faf-O)HX=E;d#*aYvZ=5? z!UkdiFqjO;^KVj()2Plm<3}(%6M$i}mC96E-W(`zdelc!QKzQJ<&wf`i#n_O)(O%AGF>D5FK?^ zxFwaNd+zZhap}7dsAEHQAz!}Q$nc#wR@v54Ql7`4O+QYYzk~dk+>fBnAMIRk>!Ie- zdDm`O`l|~_?H)%&8G8LWB$;@XyMF0B`9%DmaO$Qbe%)3kKwK8?yUu%dL;Eee{FBFM z#+QGMvBHx4sLeEa>cLgbD|zDRAY=oFoCjpxFPft!4iV#WNJhBi-a7`g zB}z|z%iPE7q}h}(dj??YMQ~y>X2dMaGe{MZgv1y?&Hv_^0_`^@(E=o*PrTDLA2ACQ zXI2t7585ROt^-cy!IEEt?S3xVt&>^gek8HUx3zs$ z)JS|K;O|036Eb0#a0AtvI5(iSYwPRGgCd}&ViTvIG}`(|$^lKdmK%BMNJu&O{y|Hd zJ>S?zXK94b2LoV9o9;-}Sl%7%C=*nE{#bsxk-n2zZRG5E&`(bId0WIwYpXq(+ZQN5 z32l%UABbN`gTi^>mp*bXjb0234pdEwMvqWI*NJ2NLJJPJK4ck=43vxav4aG%^87a%mg= z0D3y|Ss{Bawx&tw%w6|1==A&O9(q=6YJoCGjmfx+{BX7maDEs7tJ4*I$cQQ(>uYO$ zEoO0vja3*qU!oDn$JD-yYLgOHo$gmY0)DqvdTacdv@Z2LaQLs5)R z6iMUt7i@Fyiw~`N7GmZf!_k+cgn7m42RT+8>2`rCA=vlJy)?ZE1qQK+azk>tlAYBu?V;Ro@=+GPGx<^XfY z01_hCOM({X;Y(A`6ehx9>zGs3egI+c@sI2m$0YGx5wGx0IN^B#{@8xmwW+ArLMXwLX8_$afUr62#l;Om2->2t%cr$7GrGU|3u&j#=u$t z`T;^4m|6KKPTlAkaRJSw0ph3$ZTRoeFOoA!viCo69&|8{B4~H$`;h>&LiJ6pC2GMn zM_5b-urR3c#A`voJ_GsAZ@1m>T>H(t`kxiUbYF2Rl)=VkI%2z8RPIu@BQ?NRf9;Os zoNdf!NZM$WR7)A$pd%M?_{>zCZIr^^T0tg&-g}$U z7tMLk|Eym6W03fDYAZ@L>eN|#m?;@y0{(-k)`P?a&^2)Ak~U1Nx?|)0YQ8jeWc28p z6`0-wPtxp1h~ffg>;Jiv`u}m4Peu#x&?s{+FLM@k8&i9&c|pSfrUC8^YzAnD5qCJ2 zCQ2i~h_W@A0BQmke#M9KqPnddepdYx!S9@dhkyFkid`#V!PFd90gP-)XJ=`5Y#Roi zHD}+UKg5Qq>o2%?~z{tMBjRdr?A`eFfS|656&chE>>ja?m-*V%{VFMtK zA0itU{Di06IGPe1naRaBtQ#VWk#X%ycKGmZh$^xvlw@QZX4U>VP(u?^084OT?V(faT{O@~ZoQ zG3lhDJ0`GJ6&s3P`{a2Pz{13ylt;6wP25XV#imuKd2niRKVVKg7I&41Ol2b*4)Br& z!Ss;~PFOKlgdqrzt|53mDy=lUbbG$hm;lp;?i7WRe3@D)pU|PO=*aSad+xvAJC3I;mR4McB}xk8M-=!{^pKr)jI4@Tx>^fqg5xdyX5^Lx6XV6lTl|T`IUMB5?XtIbY;FEfAoE%G$t%aqJo=bj- z=rn^QeAue8_%pQG^s%nPz|=*eUeA{{}c6ldQh64WHbl=N4lPO8sq>b^I9 znSu9D1SWI-+P(nJsH5n=Qk{%!2wOcj6Q5N!cP^())^OHTMwMrYR$`LN{Z%*CtBijq?(?FO6Xf1Y_oG2bwc46u>zC+8LqFFzkpMS3z%5-dfg{K z7C4WqOu-|r%YbP|AFJ#0J zBh`Yi*3K_>5;AegZWX+u>09D^E!2um3D&n6!P@kCxULIox<7}1wTIL^6V?-y(IDCV;S7ombLd zCP`7}WUau~da!LqP>DLC_NCf~u6?)k$It1TC`9uRgpg(v7zft~OlK~(Nt2SMSI2KtGgUcnG@J+!s#ES&K>`3D=`K20Cg;wS$h=!yw@vgm)-L*I*4; zxW90W_Hv4&T!3ofLcYmiKGJqt5 z5mG%vcoGvfDAR+#17-sL;=LOmf!?2fJ5yNJxvwJ}?lIlob~eE6ws}sAf!yAuWnv&l z)7RGg)yB@vrnuL8wV$( z#sN7FgKuNslhFO#!_fQeLv;Mo)z7NoB2DM+hoXSnjeW}Qv_1GXG-$9M60f^W_DN(Q z?+f;Q`T2)o^;g%nC?W z#}PkeNQy?3`8Fz!&ISQ{i(||)C=Q^s@R!h_!5~PSYl^tklw;8e7Y@OqBY$@>%}hMh zAGG1Y)pIAWmDQOEd}Crl+aIxXN*;W(3=opoN)?7aUK1fyxMmg=}9& z@eKp$2U7oWMIKS_pnaQres6^a4F-kHDUg{$l^OWMV+hY+Fpx|YuXfAufXU1en;qAn z0;iZ=(LTmpi|g`;?04;PwnL)gaM(UOY|VGcpuY*b;z2Pq*g_@zm;DNSI9KAy zRez(d)r}T>_bfah~z0XT0n!5ppAU1cG#L@>W)uF@ND1% zrm77{OmL0b-w^*=*z2VK^ECrV(t$|}0C+nzXs{8GbhcS2uBkfeDp~_1$9N%cg!tKW zAjHpFK<)J#;_nA%`@dZiKce<&xexZM(AuP_PHz0_Ou8@E^S|dixF37A+B9LPPw0Vaf6L z{JO8|8Gut08dIRbSWuUN$OgUk?(=v0lmEVQ9%#J%1Hd^^E2=-EZ%MG$G3LF^s6c~> zAsIE$`?aLk4!`_&(AfL~z|rvAk(T>?zwXoP9kAD$0xp9F4JH8zD^{L;z20EMuqAw` zwar|<)-eM;VdoUQ%`Kh{4H`696x{Bde&?)r&_Gpz@kGc?ph1HMa}T7|L5LqQa9MCv zCD5LL1`Qg_Ezobbp4zW5)Vu(#t>$gcI(t1dLxc?)%op5HAJV3y(W{2}*@nC`p;n|BtirQP1J8C0;d>ny+X=qj zz)on;paEkq;OLrh1Yg4aIAITToO5r3w*8>^{{iC2-3~583dEP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91KcE8u1ONa40RR91MgRZ+0Ba{owg3PQkV!;ARCoc^TT5>o#}V#X(vEY8 zwfY4bCH7eqkeo#xbFyT|$dOcjKxq8|?`(VsU?32M9C9%t>SVx=kUAK-1kmavAT~hi z93dJxKR`@kShl%4o$srz>g^rQE@xM(N7|U_>Uwp(x@LALXYP59!gsOVnqC($+nQG7 zyd|Rqe5BVQ=KHt~U6B!9%E*?YWtNh{=Pq-b&bxK6t>Nm>6LnM?HZd}=t*5rbG_CuU%<8IGCYcV*{ycYzZl1lVCX)s zySN684uY`IDEvC)4o`QUXZ-n}i>1J@N?8#>cbjsdQX{HVP6#@GKm z`su&Q*nLTSo+E4AtngdF^X+YsL8l95^I%VYzjrTQ(N|1%V9oLyzxhYuU55d7S*Nq{ z;G^>c!u3HN$Hy+uGS^*Qb!F65XIx-?()m#Ccc3d@Kp%fq6)-p-4iUWY8{WZi?<;p> z^;Or0@lxXX*2C^fr?Qu&a#VFLmb>RC%Kxj+&}=K$^Whg_uocZW)w6(&QKYHtw?WM# zM|)tGj{p4=zXrz-%yEc&@9|{CvlaL~Q%6U$PIXn+d1tkfDlj@7N5FRIID!{P)^Xdz zKgg{Qm5j@Irm@Y!aFWznb!4g+OMIA2vaIe+=7Uk6`K7z3aT(;0MCZd-eblINes&WEgT&96cv`uA|o zVdbXE)8J6<0=P^{pTx|qbFz_^zt7}@B}tc*E;=l5Cc{cV`FDpu$QL6+&pnTwU;JAe zzo?cd_jT-U+2L$(Y7~RgJ@{DOAtL_4M{f=?SM@u-x~<4{okd3sTtM#ZdiWt6({-?{0# z)u;;c%nmKX96*|fA?uJRF3CZZoeSw;#QTb3avB8S4f+Bdf%3?+4Qjw!kZ5w%8qfnH zwVj!H3bq~BQpYLu+UjtP*_Mnmd$7lkDmNOzMJAdwz(Pkgj7C+)HR(ad0j>yx7mkY# zrWmS($LPUV(v>Gv8RdqHX1=}iJmWj{C{heMoW zW|Nr)EY%?07=>)n}qH+^2W z?X)$!{kc<^2FQ3ZjR%J2Ay+VrXA-GE_IaF{c|;^EBt=Ym7@Ac+slXBx5Etk`jWWqR z5bTiw4%&kPurNY_ANTLv4?MnQptify`R)wX611z+=y(3~B!^`ev~jWIrNpHd(R%_2 z0EQYV@sM)?G|6My^cFYj=S+m@B}pO|wL|$j82Y$c51#pH znddn_oTUlJdehD*&tQb*yz?;Y8OFI}K!gW;3>eRu6FmRA~$Rd!KtVU4op#X>@2WyQ~xl=z*1jR^Pd)0k=9rIN# zW({V(Oc;&;_mlMrkmc@2Sr5+JGg;59oMUDNm!3_@pk_T}Q=DSPG^vpQ}{ zTIw`FOIPV)yc`L2m@@c*6G|UJLZgxf7LEl12zfsw9gUH*(8DV+aS|xX3k^pF$Bi#R z5(M&+CV{ASzWDH)HFKkq zWj0jBiHVtiq*(r~tUSSyB1XqOMjpFyUqo2TPa@574;cf`_(;fOEmQ{V(Tv9i$4rG| z!YYuGmx|)gU%5iIxfeDS9!y~$oDX^J4UarjOl-Eo3;vP2uva|prY@u~Gk>UveoCmr zP?E!dE#l>QhM57-F2i?FQUEo^^gBEamj)Jbt{mf^2Gf!}--QM=Lkfn29#z0yA|Q4kwUI3ZZ$f{8F4nr(pnDq}gT@5WhF4~6jE@;8^}^dn$my)L zPtL|DPKE^yu+1g(u<;W5#J>CfJLi7%nu&zja5hg;U6e`a=r?$O531oDww5HM`$jFK zVLZOlJKLCbGD^gv#1!Du5B|H}sj53h){VK0@=Z9bHA}9}TVK~U=)coD zQ`B&AIqeNEG7wm)s>_DJW>)qVagx$3$eK6;ItZuh6mR;7YvN&#iFnO+l*iiO2|gfa zI!>XcH@v9K0QBE;XdkR2Lm6NJ07=S_biy*LVYDu#lV-#8r0Y6A6{mbcSAmG{WZCYp z8r>ouP90t;&K{Z4X>%**(R0rrDKx_Lqy~xsseyzw0OUVGHzmnz4%wVmgRns#)CRqn z6VU+TL(1X1#o56L!VE;Kvd6RQ5jTe(+ci1_z#>e`j6P$_Mv~}*`~)%4CytZI08B7p zA$-1iRL7sTZs)wK?rO9rHpY9_7B;ZIuhsXe2O;zzmqV{`Jt$NWamG)FgkXRkAJC^& zm{p+2wYjxC^UmRs(Z^dJ-v_#Qc9y0bCPtWsk8L#$am@NfS~=!0aS>mWw+b+2rpIK7 zCrtSg*Ic8u^VF&xbTYyoFG=I0Zbl&v`l@;Ij7FZs(k2|q=4`?`23Z9dbo{7IcOOdz zs8!k5h0-;CqLj8)Lud?*GPKMLh7JLeHPOTwo`N7pe$wkhh`JwX59ZUL-(JyFP*@kkx~r_OgzN|FCKFd_+#V5nmokItT!$!2$}C>_fuk9 zcsb5{e`0ewp^l`6(k^>ci8mGj4Fs3wrN|MldMHbr&@~tmfR)jx>FAMv=2(jJ_+&Jw z??NZc5i?Zhh*ueNwyuI}p_!h90Vu7e%ss@>D-&94a4F8S>A}kQ2xO*Uft6)66aWpA z8+kMs5eERM@pF>|8_H{X#{sM4e?~C2x#p!fFHJAY4$bhG6_}z%)2Mp6ryV~!qq3M9k8upkLKx3IXFU@)Gg3r%=P68(x;u?e5lMLeLXGz4g(eZwe1dlQ{q;Dv#eCPew zca5;fyj17;B?X4vZ7?LQf=8&5G_xnzhrYVcOeX}BXWx(u|9Y{X&=&%i>O3tNRinOU zh6YEY6YF*pxDnJK4oFm8X&`|0$hv%EAj`sI>CV$|WaoFVhz5(%>Hr*ZB|d`io4~09 zf2hAkC#?dYLu3%mLmZ2ZQx&ve2pU^3&dc(7@pvoitZc&gb;y>ucIo&$-I;$P!#}Jq o5VdoVXVbe29Xs>rpxm_aKSAmqr1p1be*gdg07*qoM6N<$g8oV{)Bpeg literal 0 HcmV?d00001 diff --git a/apps/web/public/icons/hskswap-icon.svg b/apps/web/public/icons/hskswap-icon.svg new file mode 100644 index 00000000000..99993a33cde --- /dev/null +++ b/apps/web/public/icons/hskswap-icon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/apps/web/src/components/Web3Provider/walletConnect.ts b/apps/web/src/components/Web3Provider/walletConnect.ts index 833664f5325..1804380b033 100644 --- a/apps/web/src/components/Web3Provider/walletConnect.ts +++ b/apps/web/src/components/Web3Provider/walletConnect.ts @@ -37,7 +37,7 @@ export const WC_PARAMS = { name: 'Uniswap', description: 'Uniswap Interface', url: 'https://app.uniswap.org', - icons: ['https://app.uniswap.org/favicon.png'], + icons: ['https://app.uniswap.org/icons/hskswap-icon.svg'], }, qrModalOptions: { themeVariables: { @@ -76,7 +76,7 @@ export function uniswapWalletConnect() { id: 'uniswapWalletConnect', type: 'uniswapWalletConnect', name: 'Uniswap Wallet', - icon: 'https://app.uniswap.org/favicon.png', + icon: 'https://app.uniswap.org/icons/hskswap-icon.svg', } }) } diff --git a/apps/web/src/pages/RouteDefinitions.tsx b/apps/web/src/pages/RouteDefinitions.tsx index ad66f775cbc..ed6765c73f6 100644 --- a/apps/web/src/pages/RouteDefinitions.tsx +++ b/apps/web/src/pages/RouteDefinitions.tsx @@ -250,6 +250,7 @@ export const routes: RouteDefinition[] = [ path: '/swap', getElement: () => , getTitle: () => StaticTitlesAndDescriptions.SwapTitle, + getDescription: () => StaticTitlesAndDescriptions.SwapDescription, }), // Refreshed pool routes createRouteDefinition({ diff --git a/packages/uniswap/src/features/chains/chainInfo.ts b/packages/uniswap/src/features/chains/chainInfo.ts index 3338792128c..b76f1e39ddf 100644 --- a/packages/uniswap/src/features/chains/chainInfo.ts +++ b/packages/uniswap/src/features/chains/chainInfo.ts @@ -4,6 +4,7 @@ import { BASE_CHAIN_INFO } from 'uniswap/src/features/chains/evm/info/base' import { BLAST_CHAIN_INFO } from 'uniswap/src/features/chains/evm/info/blast' import { BNB_CHAIN_INFO } from 'uniswap/src/features/chains/evm/info/bnb' import { CELO_CHAIN_INFO } from 'uniswap/src/features/chains/evm/info/celo' +import { HASHKEY_CHAIN_INFO, HASHKEY_TESTNET_CHAIN_INFO } from 'uniswap/src/features/chains/evm/info/hashkey' import { MAINNET_CHAIN_INFO, SEPOLIA_CHAIN_INFO } from 'uniswap/src/features/chains/evm/info/mainnet' import { MONAD_CHAIN_INFO } from 'uniswap/src/features/chains/evm/info/monad' import { OPTIMISM_CHAIN_INFO } from 'uniswap/src/features/chains/evm/info/optimism' @@ -39,8 +40,10 @@ export const ORDERED_CHAINS = [ SONEIUM_CHAIN_INFO, ZORA_CHAIN_INFO, ZKSYNC_CHAIN_INFO, + HASHKEY_CHAIN_INFO, SEPOLIA_CHAIN_INFO, UNICHAIN_SEPOLIA_CHAIN_INFO, + HASHKEY_TESTNET_CHAIN_INFO, ] as const satisfies UniverseChainInfo[] type ConstChainInfo

= Extract<(typeof ORDERED_CHAINS)[number], { platform: P }> @@ -84,10 +87,12 @@ export const UNIVERSE_CHAIN_INFO = { [UniverseChainId.Zora]: ZORA_CHAIN_INFO, [UniverseChainId.Zksync]: ZKSYNC_CHAIN_INFO, [UniverseChainId.Monad]: MONAD_CHAIN_INFO, + [UniverseChainId.HashKey]: HASHKEY_CHAIN_INFO, // TESTNET [UniverseChainId.Sepolia]: SEPOLIA_CHAIN_INFO, [UniverseChainId.UnichainSepolia]: UNICHAIN_SEPOLIA_CHAIN_INFO, + [UniverseChainId.HashKeyTestnet]: HASHKEY_TESTNET_CHAIN_INFO, // SVM [UniverseChainId.Solana]: SOLANA_CHAIN_INFO, diff --git a/packages/uniswap/src/features/chains/evm/info/hashkey.ts b/packages/uniswap/src/features/chains/evm/info/hashkey.ts new file mode 100644 index 00000000000..b2c2ca232b7 --- /dev/null +++ b/packages/uniswap/src/features/chains/evm/info/hashkey.ts @@ -0,0 +1,177 @@ +import { GraphQLApi } from '@universe/api' +import { ETH_LOGO, ETHEREUM_LOGO } from 'ui/src/assets' +import { config } from 'uniswap/src/config' +import { + DEFAULT_NATIVE_ADDRESS_LEGACY, + getPlaywrightRpcUrls, + getQuicknodeEndpointUrl, +} from 'uniswap/src/features/chains/evm/rpc' +import { buildChainTokens } from 'uniswap/src/features/chains/evm/tokens' +import { GENERIC_L2_GAS_CONFIG } from 'uniswap/src/features/chains/gasDefaults' +import { + GqlChainId, + NetworkLayer, + RPCType, + UniverseChainId, + UniverseChainInfo, +} from 'uniswap/src/features/chains/types' +import { Platform } from 'uniswap/src/features/platforms/types/Platform' +import { ElementName } from 'uniswap/src/features/telemetry/constants' +import { buildUSDC } from 'uniswap/src/features/tokens/stablecoin' +import { isPlaywrightEnv } from 'utilities/src/environment/env' +import { isWebApp } from 'utilities/src/platform' +import { DEFAULT_MS_BEFORE_WARNING } from 'uniswap/src/features/chains/evm/rpc' +import { ONE_MINUTE_MS } from 'utilities/src/time/time' + +// HashKey Chain Mainnet tokens +const tokens = buildChainTokens({ + stables: { + USDC: buildUSDC('0x054ed45810DbBAb8B27668922D110669c9D88D0a', UniverseChainId.HashKey), + }, +}) + +const LOCAL_HASHKEY_PLAYWRIGHT_RPC_URL = 'http://127.0.0.1:8547' + +export const HASHKEY_CHAIN_INFO = { + name: 'HashKey Chain', + id: UniverseChainId.HashKey, + blockExplorers: { + default: { + name: 'HashKey Explorer', + url: 'https://hashkey.blockscout.com', + }, + }, + testnet: false, + platform: Platform.EVM, + assetRepoNetworkName: 'hashkey', + backendChain: { + chain: GraphQLApi.Chain.Ethereum as GqlChainId, // Use Ethereum as fallback until HashKey is added to GraphQL API + backendSupported: false, // Set to true when backend supports HashKey + nativeTokenBackendAddress: undefined, + }, + blockPerMainnetEpochForChainId: 6, // L2 chains typically have faster block times + blockWaitMsBeforeWarning: isWebApp ? DEFAULT_MS_BEFORE_WARNING : ONE_MINUTE_MS, + bridge: undefined, + docs: 'https://docs.hashkeychain.io/', + elementName: ElementName.ChainHashKey, + explorer: { + name: 'HashKey Explorer', + url: 'https://hashkey.blockscout.com/', + }, + interfaceName: 'hashkey', + label: 'HashKey Chain', + logo: ETHEREUM_LOGO, // Use Ethereum logo as placeholder, replace with HashKey logo when available + nativeCurrency: { + name: 'HashKey ETH', + symbol: 'ETH', + decimals: 18, + address: DEFAULT_NATIVE_ADDRESS_LEGACY, + logo: ETH_LOGO, + }, + networkLayer: NetworkLayer.L2, + pendingTransactionsRetryOptions: undefined, + rpcUrls: isPlaywrightEnv() + ? getPlaywrightRpcUrls(LOCAL_HASHKEY_PLAYWRIGHT_RPC_URL) + : { + [RPCType.Public]: { + http: ['https://mainnet.hashkeychain.io'], + }, + [RPCType.Default]: { + http: ['https://mainnet.hashkeychain.io'], + }, + [RPCType.Fallback]: { + http: ['https://mainnet.hashkeychain.io'], + }, + [RPCType.Interface]: { + http: ['https://mainnet.hashkeychain.io'], + }, + }, + urlParam: 'hashkey', + statusPage: undefined, + tokens, + supportsV4: true, + supportsNFTs: true, + wrappedNativeCurrency: { + name: 'Wrapped Ether', + symbol: 'WETH', + decimals: 18, + address: '0x4200000000000000000000000000000000000006', // Standard OP-Stack WETH address + }, + gasConfig: GENERIC_L2_GAS_CONFIG, + tradingApiPollingIntervalMs: 150, +} as const satisfies UniverseChainInfo + +// HashKey Chain Testnet tokens +const testnetTokens = buildChainTokens({ + stables: { + USDC: buildUSDC('0x18Ec8e93627c893ae61ae0491c1C98769FD4Dfa2', UniverseChainId.HashKeyTestnet), + }, +}) + +export const HASHKEY_TESTNET_CHAIN_INFO = { + name: 'HashKey Chain Testnet', + id: UniverseChainId.HashKeyTestnet, + blockExplorers: { + default: { + name: 'HashKey Testnet Explorer', + url: 'https://testnet-explorer.hsk.xyz', + }, + }, + testnet: true, + platform: Platform.EVM, + assetRepoNetworkName: undefined, + backendChain: { + chain: GraphQLApi.Chain.EthereumSepolia as GqlChainId, // Use Sepolia as fallback + backendSupported: false, + nativeTokenBackendAddress: undefined, + }, + blockPerMainnetEpochForChainId: 6, + blockWaitMsBeforeWarning: undefined, + bridge: undefined, + docs: 'https://docs.hashkeychain.io/', + elementName: ElementName.ChainHashKeyTestnet, + explorer: { + name: 'HashKey Testnet Explorer', + url: 'https://testnet-explorer.hsk.xyz/', + }, + interfaceName: 'hashkey-testnet', + label: 'HashKey Testnet', + logo: ETHEREUM_LOGO, + nativeCurrency: { + name: 'HashKey Testnet ETH', + symbol: 'ETH', + decimals: 18, + address: DEFAULT_NATIVE_ADDRESS_LEGACY, + logo: ETH_LOGO, + }, + networkLayer: NetworkLayer.L2, + pendingTransactionsRetryOptions: undefined, + rpcUrls: { + [RPCType.Public]: { + http: ['https://testnet.hashkeychain.io'], + }, + [RPCType.Default]: { + http: ['https://testnet.hashkeychain.io'], + }, + [RPCType.Fallback]: { + http: ['https://testnet.hashkeychain.io'], + }, + [RPCType.Interface]: { + http: ['https://testnet.hashkeychain.io'], + }, + }, + urlParam: 'hashkey_testnet', + statusPage: undefined, + tokens: testnetTokens, + supportsV4: true, + supportsNFTs: false, + wrappedNativeCurrency: { + name: 'Wrapped Ether', + symbol: 'WETH', + decimals: 18, + address: '0x4200000000000000000000000000000000000006', + }, + gasConfig: GENERIC_L2_GAS_CONFIG, + tradingApiPollingIntervalMs: 150, +} as const satisfies UniverseChainInfo + diff --git a/packages/uniswap/src/features/chains/logos.tsx b/packages/uniswap/src/features/chains/logos.tsx index 54eeaa69add..7c0a314eb1f 100644 --- a/packages/uniswap/src/features/chains/logos.tsx +++ b/packages/uniswap/src/features/chains/logos.tsx @@ -30,6 +30,8 @@ const BLOCK_EXPLORER_LOGOS_LIGHT: Record = { [UniverseChainId.Blast]: BlockExplorer, [UniverseChainId.Bnb]: EtherscanLogoLight, [UniverseChainId.Celo]: BlockExplorer, + [UniverseChainId.HashKey]: BlockExplorer, + [UniverseChainId.HashKeyTestnet]: BlockExplorer, [UniverseChainId.Monad]: BlockExplorer, [UniverseChainId.Optimism]: OpEtherscanLogoLight, [UniverseChainId.Polygon]: PolygonscanLogoLight, diff --git a/packages/uniswap/src/features/chains/types.ts b/packages/uniswap/src/features/chains/types.ts index 11685650eb0..258900a2883 100644 --- a/packages/uniswap/src/features/chains/types.ts +++ b/packages/uniswap/src/features/chains/types.ts @@ -28,6 +28,8 @@ export enum UniverseChainId { WorldChain = UniswapSDKChainId.WORLDCHAIN, Zksync = UniswapSDKChainId.ZKSYNC, Zora = UniswapSDKChainId.ZORA, + HashKey = 530, // HashKey Chain Mainnet + HashKeyTestnet = 53000, // HashKey Chain Testnet Solana = 501000101, } diff --git a/packages/uniswap/src/features/telemetry/constants/trace/element.ts b/packages/uniswap/src/features/telemetry/constants/trace/element.ts index a3c7684c01b..1b10a3a23a5 100644 --- a/packages/uniswap/src/features/telemetry/constants/trace/element.ts +++ b/packages/uniswap/src/features/telemetry/constants/trace/element.ts @@ -40,6 +40,8 @@ export enum ElementName { ChainBlast = 'chain-blast', ChainCelo = 'chain-celo', ChainEthereum = 'chain-ethereum', + ChainHashKey = 'chain-hashkey', + ChainHashKeyTestnet = 'chain-hashkey-testnet', ChainMonad = 'chain-monad', ChainOptimism = 'chain-optimism', ChainPolygon = 'chain-polygon', diff --git a/packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx b/packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx new file mode 100644 index 00000000000..dfdb5f8cf3a --- /dev/null +++ b/packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx @@ -0,0 +1,644 @@ +import { useEffect, useMemo, useState } from 'react' +import { Flex, Text, TouchableArea } from 'ui/src' +import { Chevron } from 'ui/src/components/icons/Chevron' +import { X } from 'ui/src/components/icons/X' +import { InfoCircle } from 'ui/src/components/icons/InfoCircle' +import { Modal } from 'uniswap/src/components/modals/Modal' +import { AdaptiveWebModal } from 'ui/src/components/modal/AdaptiveWebModal' +import { CurrencyLogo } from 'uniswap/src/components/CurrencyLogo/CurrencyLogo' +import type { CurrencyInfo } from 'uniswap/src/features/dataApi/types' +import { useLocalizationContext } from 'uniswap/src/features/language/LocalizationContext' +import { useUSDCValue } from 'uniswap/src/features/transactions/hooks/useUSDCPrice' +import type { DerivedSwapInfo } from 'uniswap/src/features/transactions/swap/types/derivedSwapInfo' +import { getTradeAmounts } from 'uniswap/src/features/transactions/swap/utils/getTradeAmounts' +import { usePriceUXEnabled } from 'uniswap/src/features/transactions/swap/hooks/usePriceUXEnabled' +import { CurrencyField } from 'uniswap/src/types/currency' +import { NumberType } from 'utilities/src/format/types' +import { styled } from 'ui/src' +import { isWebPlatform } from 'utilities/src/platform' +import { ModalName } from 'uniswap/src/features/telemetry/constants' +import { useSwapFormScreenStore } from 'uniswap/src/features/transactions/swap/form/stores/swapFormScreenStore/useSwapFormScreenStore' + +const ModalContainer = styled(Flex, { + width: 440, + backgroundColor: '#1A1B23', + borderWidth: 1, + borderColor: '#545C69', + borderRadius: 0, + flexDirection: 'column', + p: 0, + overflow: 'hidden', + '$platform-web': { + boxShadow: '0px 25px 50px -12px rgba(0, 0, 0, 0.25)', + borderRadius: '0 !important', + margin: '0 !important', + padding: '0 !important', + }, +}) + +const Header = styled(Flex, { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + py: 8, + px: 12, + width: '100%', + height: 50, + borderBottomWidth: 1, + borderBottomColor: '#545C69', + borderRadius: 0, +}) + +const Content = styled(Flex, { + flexDirection: 'column', + alignItems: 'center', + p: 0, + pt: 18, + gap: 10, + width: '100%', +}) + +const TokenRow = styled(Flex, { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + width: '100%', + height: 67, + gap: 18, +}) + +const TokenInfo = styled(Flex, { + flexDirection: 'column', + alignItems: 'flex-start', + gap: 4, + width: 133.85, + height: 67, +}) + +const FeesSection = styled(Flex, { + flexDirection: 'column', + alignItems: 'flex-start', + px: 18, + gap: 16, + width: '100%', + alignSelf: 'stretch', +}) + +const FeeRow = styled(Flex, { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + width: '100%', + height: 21, +}) + +interface SwapConfirmationModalProps { + isOpen: boolean + onClose: () => void + onConfirm: () => void + derivedSwapInfo: DerivedSwapInfo +} + +export function SwapConfirmationModal({ + isOpen, + onClose, + onConfirm, + derivedSwapInfo, +}: SwapConfirmationModalProps): JSX.Element { + const [isExpanded, setIsExpanded] = useState(false) + const { formatCurrencyAmount, convertFiatAmountFormatted } = useLocalizationContext() + const priceUXEnabled = usePriceUXEnabled() + const { inputCurrencyAmount, outputCurrencyAmount } = getTradeAmounts(derivedSwapInfo, priceUXEnabled) + + const formattedTokenAmountIn = useMemo( + () => + inputCurrencyAmount + ? formatCurrencyAmount({ + value: inputCurrencyAmount, + type: NumberType.TokenTx, + }) + : '0', + [formatCurrencyAmount, inputCurrencyAmount], + ) + + const formattedTokenAmountOut = useMemo( + () => + outputCurrencyAmount + ? formatCurrencyAmount({ + value: outputCurrencyAmount, + type: NumberType.TokenTx, + }) + : '0', + [formatCurrencyAmount, outputCurrencyAmount], + ) + + const usdAmountIn = useUSDCValue(inputCurrencyAmount) + const usdAmountOut = useUSDCValue(outputCurrencyAmount) + const formattedFiatAmountIn = useMemo( + () => convertFiatAmountFormatted(usdAmountIn?.toExact(), NumberType.FiatTokenQuantity), + [convertFiatAmountFormatted, usdAmountIn], + ) + const formattedFiatAmountOut = useMemo( + () => convertFiatAmountFormatted(usdAmountOut?.toExact(), NumberType.FiatTokenQuantity), + [convertFiatAmountFormatted, usdAmountOut], + ) + + const inputCurrency = inputCurrencyAmount?.currency + const outputCurrency = outputCurrencyAmount?.currency + + // Get currencies from SwapFormScreenStore (the actual currencies shown in the form) + const formCurrencies = useSwapFormScreenStore((s) => s.currencies) + const sellCurrencyInfo = formCurrencies[CurrencyField.INPUT] ?? undefined + // Use buy currency from form if available, otherwise fallback to derivedSwapInfo + const buyCurrencyInfo = formCurrencies[CurrencyField.OUTPUT] ?? derivedSwapInfo.currencies[CurrencyField.OUTPUT] ?? undefined + + // TokenRow component + interface TokenRowProps { + currencyInfo: CurrencyInfo | undefined + amount: string + fiatAmount: string + paddingX: number + hasValidData: boolean + } + + function TokenRowComponent({ currencyInfo, amount, fiatAmount, paddingX, hasValidData }: TokenRowProps): JSX.Element { + return ( + + + + {amount} + + + {fiatAmount} + + + {hasValidData && currencyInfo ? ( + + ) : ( + + )} + + ) + } + + // Force-remove any rounding/overflow applied by Radix/Tamagui wrappers + useEffect(() => { + if (!isOpen) { + return + } + const content = document.querySelector('[data-radix-dialog-content]') + if (content) { + const parent = content.parentElement as HTMLElement | null + const grand = parent?.parentElement as HTMLElement | null + const apply = (el: HTMLElement | null) => { + if (!el) return + el.style.borderRadius = '0' + el.style.overflow = 'visible' + el.style.boxShadow = 'none' + el.style.margin = '0' + el.style.padding = '0' + el.style.background = 'transparent' + el.style.maxWidth = 'none' + el.style.width = 'auto' + } + apply(parent) + apply(grand) + } + }, [isOpen]) + + // Debug: log modal state + if (process.env.NODE_ENV === 'development') { + console.log('SwapConfirmationModal render:', { + isOpen, + hasInputCurrency: !!inputCurrency, + hasOutputCurrency: !!outputCurrency, + hasInputCurrencyInfo: !!derivedSwapInfo.currencies[CurrencyField.INPUT], + hasOutputCurrencyInfo: !!derivedSwapInfo.currencies[CurrencyField.OUTPUT], + }) + } + + // Don't render modal if it's not open + if (!isOpen) { + return <> + } + + // If currencies are missing, still show modal but with placeholder data + const hasValidData = inputCurrency && outputCurrency && sellCurrencyInfo && buyCurrencyInfo + + const modalContent = ( + +

+ + You're swapping + + + + + + +
+ + + + {/* Sell Token (Input) */} + + + {/* Arrow */} + + + + + + + {/* Buy Token (Output) */} + + + + {/* Fees Section */} + + + + setIsExpanded((prev) => !prev)} + style={{ + width: 98, + height: 20, + borderRadius: 8, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + gap: 8, + }} + > + + {isExpanded ? 'Show less' : 'Show more'} + + + + + + + + + + + + + Fee + + + + + Free + + + + + + + Network cost + + + + + + $0.02 + + + + + + {isExpanded && ( + <> + + + + Rate + + + + 1 ETH = 3218.57 USDC ($3,218.57) + + + + + + + Max slippage + + + + + Auto 0.67% + + + + + + + Order routing + + + + + HSK API + + + + + + + Price impact + + + + + -0.05% + + + + )} + + + + {/* Swap Button */} + + + + Swap Tokens + + + + + + ) + + return ( + <> + {/* Global CSS to override Dialog.Content border radius and padding */} + {isOpen && ( + + )} + + {isWebPlatform ? ( + + {modalContent} + + ) : ( + + {modalContent} + + )} + + ) +} + diff --git a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx index ded3b3b619d..4f3c4a313b1 100644 --- a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx +++ b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx @@ -1,10 +1,6 @@ +import { useState } from 'react' import { Button, Flex, styled, useIsShortMobileDevice } from 'ui/src' -import { useCexTransferProviders } from 'uniswap/src/features/fiatOnRamp/useCexTransferProviders' -import { - useIsShowingWebFORNudge, - useIsWebFORNudgeEnabled, - useSetIsShowingWebFORNudge, -} from 'uniswap/src/features/providers/webForNudgeProvider' +import { useTranslation } from 'react-i18next' import { useTransactionModalContext } from 'uniswap/src/features/transactions/components/TransactionModal/TransactionModalContext' import { useIsSwapButtonDisabled } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsSwapButtonDisabled' import { useIsTradeIndicative } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsTradeIndicative' @@ -12,6 +8,9 @@ import { useOnReviewPress } from 'uniswap/src/features/transactions/swap/compone import { useSwapFormButtonColors } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useSwapFormButtonColors' import { useSwapFormButtonText } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useSwapFormButtonText' import { SwapFormButtonTrace } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButtonTrace' +import { SwapConfirmationModal } from 'uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal' +import { useSwapFormStoreDerivedSwapInfo } from 'uniswap/src/features/transactions/swap/stores/swapFormStore/useSwapFormStore' +import { useIsWebFORNudgeEnabled } from 'uniswap/src/features/providers/webForNudgeProvider' import { TestID } from 'uniswap/src/test/fixtures/testIDs' import { useEvent } from 'utilities/src/react/hooks' @@ -58,51 +57,87 @@ export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Ele emphasis: buttonEmphasis, buttonTextColor, } = useSwapFormButtonColors(tokenColor) - const isShowingWebFORNudge = useIsShowingWebFORNudge() - const setIsShowingWebFORNudge = useSetIsShowingWebFORNudge() - const promptWebFORNudge = useIsWebFORNudgeEnabled() && !swapRedirectCallback && !isShowingWebFORNudge // Only show loading state if the trade is `indicative` and we're not on the landing page. // This is so that the `Get Started` button is always enabled/clickable. const shouldShowLoading = !!indicative && !swapRedirectCallback - // preload cex transfer providers to avoid flickering when showing web for nudge - useCexTransferProviders({ isDisabled: !promptWebFORNudge }) + const [isSwapConfirmationModalOpen, setIsSwapConfirmationModalOpen] = useState(false) + const derivedSwapInfo = useSwapFormStoreDerivedSwapInfo((s) => s) + const isWebFORNudgeEnabled = useIsWebFORNudgeEnabled() + const { t } = useTranslation() + const swapTokensText = t('empty.swap.button.text') - const setIsShowingWebFORNudgeHandler: () => void = useEvent(() => { - setIsShowingWebFORNudge(true) + const handleButtonPress = useEvent(() => { + // Show confirmation modal when button text is "Swap Tokens" (either from WebFORNudge or other conditions) + // Check both the flag and the actual button text to be safe + const shouldShowModal = (isWebFORNudgeEnabled || buttonText === swapTokensText) && !swapRedirectCallback + + // Debug: log the values to help troubleshoot + if (process.env.NODE_ENV === 'development') { + console.log('SwapFormButton press:', { + isWebFORNudgeEnabled, + buttonText, + swapTokensText, + shouldShowModal, + swapRedirectCallback, + }) + } + + if (shouldShowModal) { + setIsSwapConfirmationModalOpen(true) + } else { + handleOnReviewPress() + } + }) + + const handleConfirmSwap = useEvent(() => { + setIsSwapConfirmationModalOpen(false) + handleOnReviewPress() + }) + + const handleCloseModal = useEvent(() => { + setIsSwapConfirmationModalOpen(false) }) return ( - - - - - - - - - + <> + + + + + + + + + + + ) } diff --git a/packages/uniswap/src/i18n/locales/source/en-US.json b/packages/uniswap/src/i18n/locales/source/en-US.json index 7ac4662ed3d..7bcb243971d 100644 --- a/packages/uniswap/src/i18n/locales/source/en-US.json +++ b/packages/uniswap/src/i18n/locales/source/en-US.json @@ -716,7 +716,7 @@ "downloadApp.modal.getStarted.title": "Start swapping in seconds", "downloadApp.modal.getTheApp.title": "Get started with Uniswap", "downloadApp.modal.uniswapProducts.subtitle": "Uniswap products work seamlessly together to create the best onchain experience.", - "empty.swap.button.text": "Add funds to swap", + "empty.swap.button.text": "Swap Tokens", "error.dataUnavailable": "Data is unavailable at the moment; we’re working on a fix", "error.id": "Error ID: {{eventId}}", "error.jupiterApi.execute.default.title": "Something went wrong with Jupiter API. Please try again.", @@ -2207,7 +2207,7 @@ "testnet.modal.swapDeepLink.title.toTestnetMode": "Enable testnet mode", "testnet.unsupported": "This functionality is not supported in testnet mode.", "themeToggle.theme": "Theme", - "title.buySellTradeEthereum": "Buy, sell & trade Ethereum and other top tokens on Uniswap", + "title.buySellTradeEthereum": "Buy, sell & trade Ethereum and other top tokens on HSKSwap", "title.createGovernanceOn": "Create a new governance proposal on Uniswap", "title.createGovernanceTo": "Create a new governance proposal to be voted on by UNI holders. UNI tokens represent voting shares in Uniswap governance.", "title.earnFees": "Earn fees when others swap on Uniswap by adding tokens to liquidity pools.", @@ -2226,9 +2226,9 @@ "title.removev3Liquidity": "Remove your tokens from v3 liquidity pools.", "title.sendCrypto": "Send crypto", "title.sendTokens": "Send tokens on Uniswap", - "title.swappingMadeSimple": "Instantly buy and sell crypto on Ethereum, Base, Arbitrum, Polygon, Unichain and more. The DeFi platform trusted by millions.", + "title.swappingMadeSimple": "Instantly buy and sell crypto on Ethereum, Base, Arbitrum, Polygon, HashKey Chain and more. The DeFi platform trusted by millions.", "title.tradeTokens": "Trade tokens and provide liquidity. Real-time prices, charts, transaction data, and more.", - "title.uniswapTradeCrypto": "Uniswap | Trade Crypto on DeFi’s Leading Exchange ", + "title.uniswapTradeCrypto": "HSKSwap | Trade Crypto on DeFi's Leading Exchange", "title.uniToken": "UNI tokens represent voting shares in Uniswap governance. You can vote on each proposal yourself or delegate your votes to a third party.", "title.voteOnGov": "Vote on governance proposals on Uniswap", "token.balances.main": "Your balance", diff --git a/packages/uniswap/src/i18n/locales/translations/es-ES.json b/packages/uniswap/src/i18n/locales/translations/es-ES.json index 74954ee2c95..d8ffb997b46 100644 --- a/packages/uniswap/src/i18n/locales/translations/es-ES.json +++ b/packages/uniswap/src/i18n/locales/translations/es-ES.json @@ -717,7 +717,7 @@ "downloadApp.modal.getStarted.title": "Comienza a hacer intercambios en segundos", "downloadApp.modal.getTheApp.title": "Comienza con Uniswap", "downloadApp.modal.uniswapProducts.subtitle": "Los productos de Uniswap funcionan perfectamente juntos para crear la mejor experiencia en la cadena.", - "empty.swap.button.text": "Agregar fondos para hacer intercambios", + "empty.swap.button.text": "Intercambiar tokens", "error.dataUnavailable": "Los datos no están disponibles en este momento; estamos trabajando para solucionarlo", "error.id": "ID del error: {{eventId}}", "error.jupiterApi.execute.default.title": "Ocurrió un error con la API de Jupiter. Inténtalo de nuevo.", diff --git a/packages/uniswap/src/i18n/locales/translations/fil-PH.json b/packages/uniswap/src/i18n/locales/translations/fil-PH.json index 6aa457d12e3..8d6df899430 100644 --- a/packages/uniswap/src/i18n/locales/translations/fil-PH.json +++ b/packages/uniswap/src/i18n/locales/translations/fil-PH.json @@ -717,7 +717,7 @@ "downloadApp.modal.getStarted.title": "Simulang mag-swap sa loob lang ng ilang segundo", "downloadApp.modal.getTheApp.title": "Magsimula sa Uniswap", "downloadApp.modal.uniswapProducts.subtitle": "Maayos na gumagana nang magkakasama ang mga produkto ng Uniswap para magawa ang pinakamagandang onchain na experience.", - "empty.swap.button.text": "Magdagdag ng mga pondo para mag-swap", + "empty.swap.button.text": "Mag-swap ng Tokens", "error.dataUnavailable": "Hindi available ang data sa ngayon; inaayos na namin ito", "error.id": "Error ID: {{eventId}}", "error.jupiterApi.execute.default.title": "Nagkaproblema sa Jupiter API. Pakisubukan ulit.", diff --git a/packages/uniswap/src/i18n/locales/translations/fr-FR.json b/packages/uniswap/src/i18n/locales/translations/fr-FR.json index 8b07ccf4c4b..fa8566a9524 100644 --- a/packages/uniswap/src/i18n/locales/translations/fr-FR.json +++ b/packages/uniswap/src/i18n/locales/translations/fr-FR.json @@ -717,7 +717,7 @@ "downloadApp.modal.getStarted.title": "Commencez à échanger en quelques secondes", "downloadApp.modal.getTheApp.title": "Commencer avec Uniswap", "downloadApp.modal.uniswapProducts.subtitle": "Les produits Uniswap fonctionnent parfaitement ensemble pour créer la meilleure expérience en chaîne.", - "empty.swap.button.text": "Ajouter des fonds à échanger", + "empty.swap.button.text": "Échanger des jetons", "error.dataUnavailable": "Les données ne sont pas disponibles pour le moment ; nous travaillons à corriger ceci", "error.id": "ID de l'erreur : {{eventId}}", "error.jupiterApi.execute.default.title": "Une erreur est survenue avec l’API Jupiter, veuillez réessayer.", diff --git a/packages/uniswap/src/i18n/locales/translations/id-ID.json b/packages/uniswap/src/i18n/locales/translations/id-ID.json index 6c0f6952db9..f429afbc493 100644 --- a/packages/uniswap/src/i18n/locales/translations/id-ID.json +++ b/packages/uniswap/src/i18n/locales/translations/id-ID.json @@ -717,7 +717,7 @@ "downloadApp.modal.getStarted.title": "Tukarkan sekarang dengan cepat", "downloadApp.modal.getTheApp.title": "Mulai menggunakan Uniswap", "downloadApp.modal.uniswapProducts.subtitle": "Semua produk Uniswap bekerja sama dengan lancar demi menciptakan pengalaman onchain terbaik.", - "empty.swap.button.text": "Tambah dana ke pertukaran", + "empty.swap.button.text": "Tukar Token", "error.dataUnavailable": "Data tidak tersedia saat ini; kami sedang mengatasinya", "error.id": "ID Kesalahan: {{eventId}}", "error.jupiterApi.execute.default.title": "Terjadi kesalahan dengan Jupiter API. Silakan coba lagi.", diff --git a/packages/uniswap/src/i18n/locales/translations/ja-JP.json b/packages/uniswap/src/i18n/locales/translations/ja-JP.json index 442c1009306..34edfb0dfa5 100644 --- a/packages/uniswap/src/i18n/locales/translations/ja-JP.json +++ b/packages/uniswap/src/i18n/locales/translations/ja-JP.json @@ -717,7 +717,7 @@ "downloadApp.modal.getStarted.title": "すぐにスワップを始められます", "downloadApp.modal.getTheApp.title": "Uniswap を始めましょう", "downloadApp.modal.uniswapProducts.subtitle": "Uniswap 製品はシームレスに連携して、最高のオンチェーンエクスペリエンスを実現します。", - "empty.swap.button.text": "資金を追加してスワップする", + "empty.swap.button.text": "トークンをスワップ", "error.dataUnavailable": "現在、データをご利用いただけません。問題を解決中です", "error.id": "エラーID:{{eventId}}", "error.jupiterApi.execute.default.title": "Jupiter API でエラーが発生しました。もう一度お試しください。", diff --git a/packages/uniswap/src/i18n/locales/translations/ko-KR.json b/packages/uniswap/src/i18n/locales/translations/ko-KR.json index fbfce56b879..defda020e47 100644 --- a/packages/uniswap/src/i18n/locales/translations/ko-KR.json +++ b/packages/uniswap/src/i18n/locales/translations/ko-KR.json @@ -717,7 +717,7 @@ "downloadApp.modal.getStarted.title": "빠르게 스왑 시작", "downloadApp.modal.getTheApp.title": "Uniswap 시작하기", "downloadApp.modal.uniswapProducts.subtitle": "Uniswap 제품은 서로 원활하게 작동하여 최고의 온체인 경험을 만들어냅니다.", - "empty.swap.button.text": "스왑을 위해 자금 추가", + "empty.swap.button.text": "토큰 교환", "error.dataUnavailable": "지금은 데이터를 사용할 수 없습니다. 우리는 문제를 해결하기 위해 노력하고 있습니다", "error.id": "오류 ID: {{eventId}}", "error.jupiterApi.execute.default.title": "Jupiter API에 문제가 발생했습니다. 다시 시도해 주세요.", diff --git a/packages/uniswap/src/i18n/locales/translations/nl-NL.json b/packages/uniswap/src/i18n/locales/translations/nl-NL.json index 33255752911..b6e2f34985c 100644 --- a/packages/uniswap/src/i18n/locales/translations/nl-NL.json +++ b/packages/uniswap/src/i18n/locales/translations/nl-NL.json @@ -717,7 +717,7 @@ "downloadApp.modal.getStarted.title": "Begin in een paar seconden met swappen", "downloadApp.modal.getTheApp.title": "Aan de slag met Uniswap", "downloadApp.modal.uniswapProducts.subtitle": "Uniswap-producten werken naadloos samen om de beste onchain-ervaring te creëren.", - "empty.swap.button.text": "Geld toevoegen aan swap", + "empty.swap.button.text": "Tokens Wisselen", "error.dataUnavailable": "Gegevens zijn momenteel niet beschikbaar; we werken aan een oplossing", "error.id": "Fout-ID: {{eventId}}", "error.jupiterApi.execute.default.title": "Er is iets misgegaan met de Jupiter-API. Probeer het opnieuw.", diff --git a/packages/uniswap/src/i18n/locales/translations/pt-PT.json b/packages/uniswap/src/i18n/locales/translations/pt-PT.json index 724c01edb8e..33c7611e669 100644 --- a/packages/uniswap/src/i18n/locales/translations/pt-PT.json +++ b/packages/uniswap/src/i18n/locales/translations/pt-PT.json @@ -717,7 +717,7 @@ "downloadApp.modal.getStarted.title": "Comece a fazer swap em segundos", "downloadApp.modal.getTheApp.title": "Como começar a usar a Uniswap", "downloadApp.modal.uniswapProducts.subtitle": "Os produtos Uniswap funcionam muito bem juntos para criar a melhor experiência de on-chain.", - "empty.swap.button.text": "Adicionar fundos para fazer swap", + "empty.swap.button.text": "Trocar Tokens", "error.dataUnavailable": "Dados indisponíveis no momento; estamos trabalhando para resolver", "error.id": "ID do erro: {{eventId}}", "error.jupiterApi.execute.default.title": "Ocorreu um problema com a API Jupiter. Tente novamente.", diff --git a/packages/uniswap/src/i18n/locales/translations/ru-RU.json b/packages/uniswap/src/i18n/locales/translations/ru-RU.json index 554749095a5..c2001a65189 100644 --- a/packages/uniswap/src/i18n/locales/translations/ru-RU.json +++ b/packages/uniswap/src/i18n/locales/translations/ru-RU.json @@ -717,7 +717,7 @@ "downloadApp.modal.getStarted.title": "Начните выполнять своп токенов за считанные секунды", "downloadApp.modal.getTheApp.title": "Начало работы с Uniswap", "downloadApp.modal.uniswapProducts.subtitle": "Продукты Uniswap прекрасно взаимодействуют друг с другом, обеспечивая наилучший опыт работы ончейн.", - "empty.swap.button.text": "Добавить средства для свопа", + "empty.swap.button.text": "Обменять токены", "error.dataUnavailable": "Данные сейчас недоступны. Мы работаем над исправлением.", "error.id": "Идентификатор ошибки: {{eventId}}", "error.jupiterApi.execute.default.title": "Возникла проблема с Jupiter API. Попробуйте еще раз.", diff --git a/packages/uniswap/src/i18n/locales/translations/tr-TR.json b/packages/uniswap/src/i18n/locales/translations/tr-TR.json index eb506ef35a4..88bef40bdc4 100644 --- a/packages/uniswap/src/i18n/locales/translations/tr-TR.json +++ b/packages/uniswap/src/i18n/locales/translations/tr-TR.json @@ -717,7 +717,7 @@ "downloadApp.modal.getStarted.title": "Saniyeler içinde swap işlemlerine başla", "downloadApp.modal.getTheApp.title": "Uniswap'ı kullanmaya başla", "downloadApp.modal.uniswapProducts.subtitle": "Uniswap ürünleri, en iyi zincir içi deneyimi sunmak için kusursuz bir şekilde birlikte çalışır.", - "empty.swap.button.text": "Swap'a fon ekle", + "empty.swap.button.text": "Token Takasla", "error.dataUnavailable": "Veriler şu anda kullanılamıyor; bir düzeltme üzerinde çalışıyoruz", "error.id": "Hata Kimliği: {{eventId}}", "error.jupiterApi.execute.default.title": "Jupiter API ile ilgili bir sorun oluştu. Lütfen tekrar dene.", diff --git a/packages/uniswap/src/i18n/locales/translations/vi-VN.json b/packages/uniswap/src/i18n/locales/translations/vi-VN.json index 2e1c12e3ad0..95512e3074a 100644 --- a/packages/uniswap/src/i18n/locales/translations/vi-VN.json +++ b/packages/uniswap/src/i18n/locales/translations/vi-VN.json @@ -717,7 +717,7 @@ "downloadApp.modal.getStarted.title": "Bắt đầu hoán đổi trong giây lát", "downloadApp.modal.getTheApp.title": "Bắt đầu với Uniswap", "downloadApp.modal.uniswapProducts.subtitle": "Các sản phẩm Uniswap hoạt động liền mạch cùng nhau để tạo trải nghiệm onchain tốt nhất.", - "empty.swap.button.text": "Nạp quỹ để hoán đổi", + "empty.swap.button.text": "Hoán đổi Token", "error.dataUnavailable": "Dữ liệu hiện không khả dụng; chúng tôi đang khắc phục", "error.id": "ID Lỗi: {{eventId}}", "error.jupiterApi.execute.default.title": "Đã xảy ra lỗi với API Jupiter. Vui lòng thử lại.", diff --git a/packages/uniswap/src/i18n/locales/translations/zh-CN.json b/packages/uniswap/src/i18n/locales/translations/zh-CN.json index 883b448d931..6272d891679 100644 --- a/packages/uniswap/src/i18n/locales/translations/zh-CN.json +++ b/packages/uniswap/src/i18n/locales/translations/zh-CN.json @@ -717,7 +717,7 @@ "downloadApp.modal.getStarted.title": "数秒内即可开始交换代币", "downloadApp.modal.getTheApp.title": "开始使用 Uniswap", "downloadApp.modal.uniswapProducts.subtitle": "Uniswap 产品无缝协作,创造最佳的链上体验。", - "empty.swap.button.text": "添加资金以进行交换", + "empty.swap.button.text": "交换代币", "error.dataUnavailable": "目前无法提供数据;我们正在努力修复", "error.id": "错误 ID:{{eventId}}", "error.jupiterApi.execute.default.title": "Jupiter API 出错了,请重试。", @@ -2222,7 +2222,7 @@ "testnet.modal.swapDeepLink.title.toTestnetMode": "启用测试网模式", "testnet.unsupported": "测试网模式不支持此功能。", "themeToggle.theme": "主题", - "title.buySellTradeEthereum": "在 Uniswap 上购买、出售和交易以太坊及其他顶级代币", + "title.buySellTradeEthereum": "在 HSKSwap 上购买、出售和交易以太坊及其他顶级代币", "title.createGovernanceOn": "在 Uniswap 上创建新的治理提案", "title.createGovernanceTo": "创建一个新的治理提案,供 UNI 持有者投票。UNI 代币代表 Uniswap 治理中的投票权份额。", "title.earnFees": "在他人通过向流动性池添加代币以在 Uniswap 上进行交换时赚取费用。", @@ -2241,9 +2241,9 @@ "title.removev3Liquidity": "从 v3 流动性资金池中移除你的代币。", "title.sendCrypto": "发送加密货币", "title.sendTokens": "在 Uniswap 上发送代币", - "title.swappingMadeSimple": "支持在以太坊、Base、Arbitrum、Polygon、Unichain 等链上即时买卖加密货币。数百万用户信赖的 DeFi 平台。", + "title.swappingMadeSimple": "支持在以太坊、Base、Arbitrum、Polygon、HashKey Chain 等链上即时买卖加密货币。数百万用户信赖的 DeFi 平台。", "title.tradeTokens": "交易代币并提供流动性。实时价格、图表、交易数据等。", - "title.uniswapTradeCrypto": "Uniswap | 在 DeFi 领先交易所交易加密货币 ", + "title.uniswapTradeCrypto": "HSKSwap | 在 DeFi 领先交易所交易加密货币", "title.uniToken": "UNI 代币代表 Uniswap 治理中的投票权份额。你可以自己对每个提案进行投票,也可以将你的投票委托给第三方。", "title.voteOnGov": "对 Uniswap 上的治理提案进行投票", "token.balances.main": "你的余额", diff --git a/packages/uniswap/src/i18n/locales/translations/zh-TW.json b/packages/uniswap/src/i18n/locales/translations/zh-TW.json index a802ae873ca..11de0f3c92e 100644 --- a/packages/uniswap/src/i18n/locales/translations/zh-TW.json +++ b/packages/uniswap/src/i18n/locales/translations/zh-TW.json @@ -717,7 +717,7 @@ "downloadApp.modal.getStarted.title": "幾秒內即可開始交換", "downloadApp.modal.getTheApp.title": "開始使用 Uniswap", "downloadApp.modal.uniswapProducts.subtitle": "Uniswap 產品無縫協作,創造最佳的鏈上體驗。", - "empty.swap.button.text": "新增資金以進行交換", + "empty.swap.button.text": "交換代幣", "error.dataUnavailable": "目前無法取得資料;我們正在努力修復問題", "error.id": "錯誤 ID:{{eventId}}", "error.jupiterApi.execute.default.title": "Jupiter API 發生錯誤,請重試。", @@ -2222,7 +2222,7 @@ "testnet.modal.swapDeepLink.title.toTestnetMode": "啟用測試網模式", "testnet.unsupported": "測試網模式不支援此功能。", "themeToggle.theme": "主題", - "title.buySellTradeEthereum": "在 Uniswap 上購買、出售和交易以太幣和其他頂級代幣", + "title.buySellTradeEthereum": "在 HSKSwap 上購買、出售和交易以太幣和其他頂級代幣", "title.createGovernanceOn": "在 Uniswap 上建立新的治理提案", "title.createGovernanceTo": "建立一個新的治理提案,供 UNI 持有者投票。UNI 代幣代表 Uniswap 治理中的投票份額。", "title.earnFees": "你可以在其他人將代幣新增到流動資產池,以在 Uniswap 上進行交換時賺取交易費用。", @@ -2241,9 +2241,9 @@ "title.removev3Liquidity": "從 v3 流動性資產池中移除你的代幣。", "title.sendCrypto": "傳送加密貨幣", "title.sendTokens": "在 Uniswap 上傳送代幣", - "title.swappingMadeSimple": "支援在以太坊、Base、Arbitrum、Polygon、Unichain 等鏈上即時買賣加密貨幣。深受數百萬用戶信賴的 DeFi 平台。", + "title.swappingMadeSimple": "支援在以太坊、Base、Arbitrum、Polygon、HashKey Chain 等鏈上即時買賣加密貨幣。深受數百萬用戶信賴的 DeFi 平台。", "title.tradeTokens": "交易代幣並提供流動資產。即時價格、圖表、交易資料和其他。", - "title.uniswapTradeCrypto": "Uniswap | 在 DeFi 領先交易所交易加密貨幣 ", + "title.uniswapTradeCrypto": "HSKSwap | 在 DeFi 領先交易所交易加密貨幣", "title.uniToken": "UNI 代幣代表 Uniswap 治理中的投票份額。你可以自己對每個提案進行投票,也可以將你的投票委託給第三方。", "title.voteOnGov": "對 Uniswap 治理提案進行投票", "token.balances.main": "你的餘額", From a1bde4f08ded739415b640fdce67cd01b6184000 Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Mon, 12 Jan 2026 16:16:35 +0800 Subject: [PATCH 04/33] feat : udpate wallet --- apps/web/package.json | 2 + .../src/components/HashKeyChainOnlyModal.tsx | 86 +++ .../src/components/TopLevelModals/index.tsx | 2 +- .../PendingWalletConnectionModal.tsx | 34 +- .../Web3Provider/createWeb3Provider.tsx | 11 +- .../components/Web3Provider/reownConfig.tsx | 157 +++++ .../components/Web3Status/ReownWeb3Status.tsx | 234 +++++++ apps/web/src/components/Web3Status/index.tsx | 237 +------ ...eateLegacyBannersNotificationDataSource.ts | 25 +- apps/web/src/pages/App.tsx | 57 +- apps/web/src/pages/Positions/index.tsx | 6 +- apps/web/src/pages/Swap/Buy/BuyFormButton.tsx | 6 +- apps/web/src/pages/Swap/index.tsx | 8 +- bun.lock | 658 ++++++++++++------ 14 files changed, 1034 insertions(+), 489 deletions(-) create mode 100644 apps/web/src/components/HashKeyChainOnlyModal.tsx create mode 100644 apps/web/src/components/Web3Provider/reownConfig.tsx create mode 100644 apps/web/src/components/Web3Status/ReownWeb3Status.tsx diff --git a/apps/web/package.json b/apps/web/package.json index 247b5e9febb..365d3efdf79 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -173,6 +173,8 @@ "@popperjs/core": "2.11.8", "@reach/dialog": "0.10.5", "@reach/portal": "0.10.5", + "@reown/appkit": "^1.7.8", + "@reown/appkit-adapter-wagmi": "^1.0.0", "@reduxjs/toolkit": "1.9.3", "@rive-app/canvas": "2.19.0", "@rive-app/react-canvas": "4.13.0", diff --git a/apps/web/src/components/HashKeyChainOnlyModal.tsx b/apps/web/src/components/HashKeyChainOnlyModal.tsx new file mode 100644 index 00000000000..f40dce81c8a --- /dev/null +++ b/apps/web/src/components/HashKeyChainOnlyModal.tsx @@ -0,0 +1,86 @@ +import { useTranslation } from 'react-i18next' +import { Button, Flex, Text } from 'ui/src' +import { AlertTriangleFilled } from 'ui/src/components/icons/AlertTriangleFilled' +import { Modal } from 'uniswap/src/components/modals/Modal' +import { ModalName } from 'uniswap/src/features/telemetry/constants' +import { UniverseChainId } from 'uniswap/src/features/chains/types' +import { getChainInfo } from 'uniswap/src/features/chains/chainInfo' +import useSelectChain from 'hooks/useSelectChain' + +interface HashKeyChainOnlyModalProps { + isOpen: boolean + onClose: () => void + currentChainId?: UniverseChainId +} + +export function HashKeyChainOnlyModal({ + isOpen, + onClose, + currentChainId, +}: HashKeyChainOnlyModalProps): JSX.Element { + const { t } = useTranslation() + const selectChain = useSelectChain() + + const handleSwitchToMainnet = async () => { + await selectChain(UniverseChainId.HashKey) + onClose() + } + + const handleSwitchToTestnet = async () => { + await selectChain(UniverseChainId.HashKeyTestnet) + onClose() + } + + const hashKeyMainnetInfo = getChainInfo(UniverseChainId.HashKey) + const hashKeyTestnetInfo = getChainInfo(UniverseChainId.HashKeyTestnet) + + return ( + + + + + + + + 仅支持 HashKey Chain + + + + 当前应用仅支持 HashKey Chain 主网和测试网。请切换到以下网络之一: + + + + + + + + + + + + ) +} + diff --git a/apps/web/src/components/TopLevelModals/index.tsx b/apps/web/src/components/TopLevelModals/index.tsx index c708b7c44ac..7900ccd3ff0 100644 --- a/apps/web/src/components/TopLevelModals/index.tsx +++ b/apps/web/src/components/TopLevelModals/index.tsx @@ -83,7 +83,7 @@ export default function TopLevelModals() { - + {/* SolanaPromo modal removed for HSKSwap */} {shouldShowDevFlags && } diff --git a/apps/web/src/components/WalletModal/PendingWalletConnectionModal/PendingWalletConnectionModal.tsx b/apps/web/src/components/WalletModal/PendingWalletConnectionModal/PendingWalletConnectionModal.tsx index 71aa8760a27..24f6a6cee27 100644 --- a/apps/web/src/components/WalletModal/PendingWalletConnectionModal/PendingWalletConnectionModal.tsx +++ b/apps/web/src/components/WalletModal/PendingWalletConnectionModal/PendingWalletConnectionModal.tsx @@ -47,26 +47,30 @@ function useApplicablePendingWallet() { /** * Tracks which wallet needs the Solana prompt. Persists after EVM completes to keep modal open. * Different from useApplicablePendingWallet which becomes undefined once connection starts. + * + * DISABLED: Solana prompt is disabled for HSKSwap. */ function useSolanaWalletToPrompt(applicablePendingWallet: ExternalWallet | undefined) { - const hasAcceptedSolanaConnectionPrompt = useHasAcceptedSolanaConnectionPromptWithBuffer() - - const [solanaWalletToPrompt, setSolanaWalletToPrompt] = useState() - - const isMultiPlatformConnection = !useConnectWallet().variables?.individualPlatform - - // Set a flag to keep the modal open if the solana prompt should be shown - useEffect(() => { - if (applicablePendingWallet && !hasAcceptedSolanaConnectionPrompt && isMultiPlatformConnection) { - setSolanaWalletToPrompt(applicablePendingWallet) - } - }, [hasAcceptedSolanaConnectionPrompt, applicablePendingWallet, isMultiPlatformConnection]) - + // Always return undefined to disable Solana prompt const resetSolanaWalletToPrompt = useEvent(() => { - setSolanaWalletToPrompt(undefined) + // No-op }) - return { solanaWalletToPrompt, resetSolanaWalletToPrompt } + return { solanaWalletToPrompt: undefined, resetSolanaWalletToPrompt } + + // Original implementation (disabled): + // const hasAcceptedSolanaConnectionPrompt = useHasAcceptedSolanaConnectionPromptWithBuffer() + // const [solanaWalletToPrompt, setSolanaWalletToPrompt] = useState() + // const isMultiPlatformConnection = !useConnectWallet().variables?.individualPlatform + // useEffect(() => { + // if (applicablePendingWallet && !hasAcceptedSolanaConnectionPrompt && isMultiPlatformConnection) { + // setSolanaWalletToPrompt(applicablePendingWallet) + // } + // }, [hasAcceptedSolanaConnectionPrompt, applicablePendingWallet, isMultiPlatformConnection]) + // const resetSolanaWalletToPrompt = useEvent(() => { + // setSolanaWalletToPrompt(undefined) + // }) + // return { solanaWalletToPrompt, resetSolanaWalletToPrompt } } /** Modal for dual-VM wallets (MetaMask) that shows connection status and prompts for Solana opt-in. */ diff --git a/apps/web/src/components/Web3Provider/createWeb3Provider.tsx b/apps/web/src/components/Web3Provider/createWeb3Provider.tsx index 11346af0509..5e85d61d859 100644 --- a/apps/web/src/components/Web3Provider/createWeb3Provider.tsx +++ b/apps/web/src/components/Web3Provider/createWeb3Provider.tsx @@ -1,6 +1,7 @@ import { CoinbaseWalletAdapter } from '@solana/wallet-adapter-coinbase' import { WalletProvider as SolanaWalletProvider } from '@solana/wallet-adapter-react' import { SolanaSignerUpdater } from 'components/Web3Provider/signSolanaTransaction' +import { AppKitProvider } from 'components/Web3Provider/reownConfig' import React, { type PropsWithChildren, type ReactNode, useMemo } from 'react' import { useWalletCapabilitiesStateEffect } from 'state/walletCapabilities/hooks/useWalletCapabilitiesStateEffect' import { type Register, WagmiProvider } from 'wagmi' @@ -10,9 +11,13 @@ export function createWeb3Provider(params: { wagmiConfig: Register['config']; re const Provider = ({ children }: { children: ReactNode }) => ( - - {children} - + + {/* Use our wagmiConfig which includes HashKey Chain (from ORDERED_EVM_CHAINS) */} + {/* WagmiAdapter creates its own config internally for Reown AppKit, but we still need our full config for other features */} + + {children} + + ) diff --git a/apps/web/src/components/Web3Provider/reownConfig.tsx b/apps/web/src/components/Web3Provider/reownConfig.tsx new file mode 100644 index 00000000000..3534541e23b --- /dev/null +++ b/apps/web/src/components/Web3Provider/reownConfig.tsx @@ -0,0 +1,157 @@ +// Reown AppKit configuration +import React from 'react' +import { UNISWAP_WEB_URL } from 'uniswap/src/constants/urls' +// biome-ignore lint/style/noRestrictedImports: wagmi account hook needed for wallet integration +import { useAccount as useWagmiAccount } from 'wagmi' + +// Import Reown AppKit - use ES6 import syntax for Vite compatibility (matching hsk-staking-launchpad) +import { + createAppKit, + useAppKit as useAppKitBase, + useAppKitAccount as useAppKitAccountBase, + useDisconnect as useDisconnectBase, + useWalletInfo as useWalletInfoBase, +} from '@reown/appkit/react' +import { WagmiAdapter } from '@reown/appkit-adapter-wagmi' +// Import HashKey networks from Reown AppKit (matching hsk-staking-launchpad) +import { type AppKitNetwork, hashkey, hashkeyTestnet } from '@reown/appkit/networks' + +if (process.env.REACT_APP_WALLET_CONNECT_PROJECT_ID === undefined) { + throw new Error('REACT_APP_WALLET_CONNECT_PROJECT_ID must be a defined environment variable') +} +const WALLET_CONNECT_PROJECT_ID = process.env.REACT_APP_WALLET_CONNECT_PROJECT_ID + +// Use Reown AppKit's predefined HashKey networks with explicit RPC URLs +// (matching hsk-staking-launchpad - they use default hashkey network, but we override RPC for reliability) +const DEFAULT_CHAIN: AppKitNetwork = hashkey + +// Override networks with explicit RPC URLs to ensure connectivity +// Using the same RPC URLs as defined in our chain info +const networks = [ + { + ...hashkey, + rpcUrls: { + default: { + http: ['https://mainnet.hashkeychain.io'], + }, + public: { + http: ['https://mainnet.hashkeychain.io'], + }, + }, + blockExplorers: { + default: { + name: 'HashKey Explorer', + url: 'https://hashkey.blockscout.com', + }, + }, + }, + { + ...hashkeyTestnet, + rpcUrls: { + default: { + http: ['https://testnet.hashkeychain.io'], + }, + public: { + http: ['https://testnet.hashkeychain.io'], + }, + }, + blockExplorers: { + default: { + name: 'HashKey Testnet Explorer', + url: 'https://testnet-explorer.hsk.xyz', + }, + }, + }, +] as [AppKitNetwork, ...AppKitNetwork[]] + +// Create Wagmi adapter (matching hsk-staking-launchpad) +// WagmiAdapter creates its own wagmi config internally with only the specified networks +export const wagmiAdapter = new WagmiAdapter({ + networks, + projectId: WALLET_CONNECT_PROJECT_ID, +}) + +// Create AppKit modal (matching hsk-staking-launchpad exactly) +// createAppKit creates a global modal instance - no Provider needed +const modal = createAppKit({ + projectId: WALLET_CONNECT_PROJECT_ID, + adapters: [wagmiAdapter], + networks, + allWallets: 'ONLY_MOBILE' as const, + debug: false, + enableAuthLogger: false, + enableReconnect: false, + enableCoinbase: false, + metadata: { + name: 'HSKSwap', + description: 'HSKSwap Interface', + url: UNISWAP_WEB_URL, + icons: [`${UNISWAP_WEB_URL}icons/hskswap-icon.svg`], + }, + features: { + analytics: false, + email: false, + socials: false as const, + swaps: false as const, + send: false as const, + receive: false as const, + onramp: false as const, + history: false as const, + legalCheckbox: false as const, + }, + themeMode: 'dark' as const, + themeVariables: { + '--w3m-font-family': "'Aleo', sans-serif", + '--w3m-accent': '#2362DD', + '--w3m-border-radius-master': '8px', + '--w3m-z-index': 9999, + }, + includeWalletIds: [ + 'c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96', // metaMask + '971e689d0a5be527bac79629b4ee9b925e82208e5168b733496a09c0faed0709', // okx-default + ], +}) + +// Export AppKitProvider - createAppKit doesn't need a Provider, but we keep it for compatibility +// The modal is created globally and hooks work without a Provider +export const AppKitProvider = ({ children }: { children: React.ReactNode }): React.ReactElement => { + // createAppKit creates a global modal, no Provider wrapper needed + // But we keep this component for compatibility with existing code + return <>{children} +} + +// Export hooks +export const useAppKit = useAppKitBase + +// Sync account state from Wagmi to ensure consistency +// Reown AppKit uses WagmiAdapter internally, so we should use Wagmi's account state +export const useAppKitAccount = () => { + // Try to get account from Reown AppKit first + const appKitAccount = useAppKitAccountBase() + // Also get account from Wagmi to ensure consistency + const wagmiAccount = useWagmiAccount() + + // Prefer Wagmi account if available, otherwise fall back to AppKit account + return { + address: wagmiAccount.address ?? appKitAccount.address, + isConnected: wagmiAccount.isConnected ?? appKitAccount.isConnected, + chainId: wagmiAccount.chainId, + connector: wagmiAccount.connector, + } +} + +// Custom hook for connection status (not directly available in AppKit) +export const useAppKitConnectionStatus = () => { + const wagmiAccount = useWagmiAccount() + const account = useAppKitAccount() + + return { + isConnecting: wagmiAccount.status === 'connecting' || wagmiAccount.status === 'reconnecting', + isConnected: account.isConnected, + } +} + +// Export additional hooks for wallet management +export const useDisconnect = useDisconnectBase +export const useWalletInfo = useWalletInfoBase + diff --git a/apps/web/src/components/Web3Status/ReownWeb3Status.tsx b/apps/web/src/components/Web3Status/ReownWeb3Status.tsx new file mode 100644 index 00000000000..30c1a39f1c1 --- /dev/null +++ b/apps/web/src/components/Web3Status/ReownWeb3Status.tsx @@ -0,0 +1,234 @@ +import { useState } from 'react' +import { useAppKit, useAppKitAccount, useAppKitConnectionStatus, useDisconnect, useWalletInfo } from 'components/Web3Provider/reownConfig' +import { useTranslation } from 'react-i18next' +import { Button, Flex, Text } from 'ui/src' +import { shortenAddress } from 'utilities/src/addresses' +import { Modal } from 'uniswap/src/components/modals/Modal' +import { ModalName } from 'uniswap/src/features/telemetry/constants' +import { CopyAlt } from 'ui/src/components/icons/CopyAlt' +import { CheckCircleFilled } from 'ui/src/components/icons/CheckCircleFilled' +import useCopyClipboard from 'hooks/useCopyClipboard' +// biome-ignore lint/style/noRestrictedImports: wagmi hook needed for wallet disconnection +import { useDisconnect as useDisconnectWagmi } from 'wagmi' + +const ConnectButtonStyled = { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + padding: '9px 16px', + width: '134px', + height: '36px', + background: '#2362DD', + boxShadow: '0px 0px 20px -5px #2362DD', + borderRadius: '8px', + border: 'none', + cursor: 'pointer', + fontFamily: "'Aleo', sans-serif", + fontWeight: 500, + fontSize: '14px', + lineHeight: '20px', + color: '#FFFFFF', +} as const + +export default function ReownWeb3Status(): JSX.Element { + const { t } = useTranslation() + const { open } = useAppKit() + const reownDisconnect = useDisconnect() + const { disconnect: wagmiDisconnect } = useDisconnectWagmi() + const { address, isConnected } = useAppKitAccount() + const { isConnecting } = useAppKitConnectionStatus() + const { walletInfo } = useWalletInfo() + const [accountModalOpen, setAccountModalOpen] = useState(false) + const [copied, copyToClipboard] = useCopyClipboard() + + // Debug logging + if (process.env.NODE_ENV === 'development') { + console.log('ReownWeb3Status:', { + address, + isConnected, + isConnecting, + walletInfo, + reownDisconnect, + wagmiDisconnect + }) + } + + // Prevent multiple connection attempts + const handleConnect = () => { + if (isConnecting) { + console.warn('Connection already in progress, ignoring click') + return + } + open({ view: 'Connect' }) + } + + const handleAccountClick = () => { + if (isConnecting) { + console.warn('Connection in progress, ignoring account click') + return + } + if (isConnected) { + setAccountModalOpen(true) + } else { + open({ view: 'Connect' }) + } + } + + const handleDisconnect = () => { + // Try both Reown disconnect and Wagmi disconnect to ensure it works + try { + // First try Reown's disconnect (matching hsk-staking-launchpad) + // useDisconnect from Reown returns an object with disconnect property + const disconnectFn = (reownDisconnect as any)?.disconnect || reownDisconnect + if (disconnectFn && typeof disconnectFn === 'function') { + disconnectFn() + } + + // Also call Wagmi disconnect directly to ensure disconnection + if (wagmiDisconnect) { + wagmiDisconnect() + } + + console.log('Disconnect called successfully') + } catch (error) { + console.error('Failed to disconnect:', error) + // Still try wagmi disconnect as fallback + try { + if (wagmiDisconnect) { + wagmiDisconnect() + } + } catch (fallbackError) { + console.error('Fallback disconnect also failed:', fallbackError) + } + } + // Always close the modal (matching hsk-staking-launchpad behavior) + setAccountModalOpen(false) + } + + const handleCopyAddress = () => { + if (address) { + copyToClipboard(address) + } + } + + if (isConnecting) { + return ( + + + + ) + } + + if (isConnected && address) { + // Show account button with custom modal (matching hsk-staking-launchpad experience) + return ( + <> + + + + + {/* Custom Account Modal (matching hsk-staking-launchpad exactly) */} + setAccountModalOpen(false)} + > + + + Account + + + + + + + Connect with {walletInfo?.name || 'Wallet'} + + + + + {walletInfo?.icon && ( + + {walletInfo.name + + )} + + {shortenAddress({ address, chars: 6, charsEnd: 4 })} + + + + + + ) + } + + return ( + + + + ) +} + diff --git a/apps/web/src/components/Web3Status/index.tsx b/apps/web/src/components/Web3Status/index.tsx index 7a67697efb0..660b709ac87 100644 --- a/apps/web/src/components/Web3Status/index.tsx +++ b/apps/web/src/components/Web3Status/index.tsx @@ -1,234 +1,7 @@ -import { PrefetchBalancesWrapper } from 'appGraphql/data/apollo/AdaptiveTokenBalancesProvider' -import { FeatureFlags, useFeatureFlag } from '@universe/gating' -import PortfolioDrawer from 'components/AccountDrawer' -import { usePendingActivity } from 'components/AccountDrawer/MiniPortfolio/Activity/hooks' -import { useAccountDrawer } from 'components/AccountDrawer/MiniPortfolio/hooks' -import { Portal } from 'components/Popups/Portal' -import StatusIcon from 'components/StatusIcon' -import { RecentlyConnectedModal } from 'components/Web3Status/RecentlyConnectedModal' -import { useAccountIdentifier } from 'components/Web3Status/useAccountIdentifier' -import { useShowPendingAfterDelay } from 'components/Web3Status/useShowPendingAfterDelay' -import { useModalState } from 'hooks/useModalState' -import { atom, useAtom } from 'jotai' -import { deprecatedStyled } from 'lib/styled-components' -import { forwardRef, RefObject, useCallback, useEffect, useRef } from 'react' -import { Trans, useTranslation } from 'react-i18next' -import { AnimatePresence, Button, ButtonProps, Flex, Popover, Text } from 'ui/src' -import { Unitag } from 'ui/src/components/icons/Unitag' -import { breakpoints } from 'ui/src/theme' -import { useActiveAddresses, useConnectionStatus } from 'uniswap/src/features/accounts/store/hooks' -import { ElementName, InterfaceEventName, ModalName } from 'uniswap/src/features/telemetry/constants' -import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send' -import Trace from 'uniswap/src/features/telemetry/Trace' -import { TestID } from 'uniswap/src/test/fixtures/testIDs' -import { isIFramed } from 'utils/isIFramed' +// Replaced with Reown AppKit - AccountDrawer removed +import ReownWeb3Status from './ReownWeb3Status' -const TextStyled = deprecatedStyled.span<{ marginRight?: number }>` - flex: 1 1 auto; - text-overflow: ellipsis; - white-space: nowrap; - font-size: 1rem; - width: fit-content; - font-weight: 485; - margin-right: ${({ marginRight = 0 }) => marginRight}px; - color: ${({ theme }) => theme.neutral1}; -` - -const Web3StatusGeneric = forwardRef(function Web3StatusGeneric( - { children, ...props }, - ref, -) { - return ( - - - - ) -}) - -const AddressAndChevronContainer = deprecatedStyled.div<{ $loading?: boolean }>` - display: flex; - opacity: ${({ $loading, theme }) => $loading && theme.opacity.disabled}; - align-items: center; - - @media only screen and (max-width: ${breakpoints.xl}px) { - display: none; - } -` - -const ConnectButtonStyled = deprecatedStyled.button` - display: flex; - justify-content: center; - align-items: center; - padding: 9px 16px; - width: 134px; - height: 36px; - background: #2362DD; - box-shadow: 0px 0px 20px -5px #2362DD; - border-radius: 8px; - border: none; - cursor: pointer; - font-family: 'Aleo', sans-serif; - font-weight: 500; - font-size: 14px; - line-height: 20px; - color: #FFFFFF; - - &:hover { - opacity: 0.9; - } - - &:active { - opacity: 0.8; - } -` - -const ExistingUserCTAButton = forwardRef void }>(function ExistingUserCTAButton( - { onPress }, - ref, -) { - const { t } = useTranslation() - const isEmbeddedWalletEnabled = useFeatureFlag(FeatureFlags.EmbeddedWallet) - const isLogIn = isEmbeddedWalletEnabled - - return ( -
- - {isLogIn ? t('nav.logIn.button') : t('common.connect.button')} - -
- ) -}) - -export const Web3StatusRef = atom | undefined>(undefined) - -function Web3StatusInner() { - const activeAddresses = useActiveAddresses() - const { isConnecting } = useConnectionStatus() - const ref = useRef(null) - const [, setRef] = useAtom(Web3StatusRef) - - // To share the Connect button ref with the AccountDrawer modal so it doesn't trigger useOnClickOutside - useEffect(() => { - setRef(ref) - }, [setRef]) - - const accountDrawer = useAccountDrawer() - const handleWalletDropdownClick = useCallback(() => { - sendAnalyticsEvent(InterfaceEventName.AccountDropdownButtonClicked) - accountDrawer.toggle() - }, [accountDrawer]) - - const { hasPendingActivity, pendingActivityCount, hasL1PendingActivity } = usePendingActivity() - const { accountIdentifier, hasUnitag } = useAccountIdentifier() - const showLoadingState = useShowPendingAfterDelay({ - hasPendingActivity, - hasL1PendingActivity, - }) - - // TODO(WEB-4173): Remove isIFrame check when we can update wagmi to version >= 2.9.4 - if (isConnecting && !isIFramed()) { - return ( - - - - {accountIdentifier} - - {hasUnitag ? : undefined} - - - ) - } - - if (activeAddresses.evmAddress || activeAddresses.svmAddress) { - return ( - - - {showLoadingState ? ( - - - - - - - - ) : ( - - } - > - - - {accountIdentifier} - - {hasUnitag && } - - - - )} - - - ) - } - - return ( - - {/* biome-ignore lint/correctness/noRestrictedElements: needed here */} -
e.key === 'Enter' && handleWalletDropdownClick()}> - -
-
- ) -} - -export default function Web3Status() { - const { isOpen: recentlyConnectedModalIsOpen } = useModalState(ModalName.RecentlyConnectedModal) - return ( - - - - - - - - - - - - ) +// Replaced with Reown AppKit - all drawer functionality removed +export default function Web3Status(): JSX.Element { + return } diff --git a/apps/web/src/notification-service/data-sources/createLegacyBannersNotificationDataSource.ts b/apps/web/src/notification-service/data-sources/createLegacyBannersNotificationDataSource.ts index 6213df32305..19defb7f356 100644 --- a/apps/web/src/notification-service/data-sources/createLegacyBannersNotificationDataSource.ts +++ b/apps/web/src/notification-service/data-sources/createLegacyBannersNotificationDataSource.ts @@ -176,9 +176,9 @@ async function fetchNotifications(isDarkMode: boolean): Promise { - const isEnabled = getFeatureFlag(FeatureFlags.SolanaPromo) - - if (!isEnabled) { - return [] - } - - // Processor will identify modal as chained due to POPUP action - return [createSolanaPromoBanner(isDarkMode), createSolanaPromoModal()] + // Always return empty array to disable Solana promo + return [] + + // Original implementation (disabled): + // const isEnabled = getFeatureFlag(FeatureFlags.SolanaPromo) + // if (!isEnabled) { + // return [] + // } + // return [createSolanaPromoBanner(isDarkMode), createSolanaPromoModal()] } /** diff --git a/apps/web/src/pages/App.tsx b/apps/web/src/pages/App.tsx index 4928cdbecbd..7dcc6f51e40 100644 --- a/apps/web/src/pages/App.tsx +++ b/apps/web/src/pages/App.tsx @@ -1,16 +1,20 @@ import { useFeatureFlagUrlOverrides } from 'featureFlags/useFeatureFlagUrlOverrides' import ErrorBoundary from 'components/ErrorBoundary' +import { HashKeyChainOnlyModal } from 'components/HashKeyChainOnlyModal' +import { useAccount } from 'hooks/useAccount' import { Body } from 'pages/App/Body' import { AppLayout } from 'pages/App/Layout' import { ResetPageScrollEffect } from 'pages/App/utils/ResetPageScroll' import { UserPropertyUpdater } from 'pages/App/utils/UserPropertyUpdater' import { useDynamicMetatags } from 'pages/metatags' import { findRouteByPath } from 'pages/RouteDefinitions' -import { useEffect, useLayoutEffect } from 'react' +import { useEffect, useLayoutEffect, useState } from 'react' import { Helmet } from 'react-helmet-async/lib/index' import { Navigate, useLocation } from 'react-router' import DarkModeQueryParamReader from 'theme/components/DarkModeQueryParamReader' import { useSporeColors } from 'ui/src' +import { getChainInfo } from 'uniswap/src/features/chains/chainInfo' +import { UniverseChainId } from 'uniswap/src/features/chains/types' import { initializeScrollWatcher } from 'uniswap/src/components/modals/ScrollLock' import { EXTENSION_PASSKEY_AUTH_PATH } from 'uniswap/src/features/passkey/constants' import Trace from 'uniswap/src/features/telemetry/Trace' @@ -20,8 +24,13 @@ import { getCurrentPageFromLocation } from 'utils/urlRoutes' const OVERRIDE_PAGE_LAYOUT = [EXTENSION_PASSKEY_AUTH_PATH] +// 支持的链 ID:仅 HashKey Chain 主网和测试网 +const ALLOWED_CHAIN_IDS = [UniverseChainId.HashKey, UniverseChainId.HashKeyTestnet] + export default function App() { const colors = useSporeColors() + const account = useAccount() + const [showHashKeyModal, setShowHashKeyModal] = useState(false) const location = useLocation() const { pathname } = location @@ -33,6 +42,47 @@ export default function App() { initializeScrollWatcher() }, []) + // 检查当前链是否在允许的链列表中 + useEffect(() => { + if (account.chainId !== undefined) { + const isAllowedChain = ALLOWED_CHAIN_IDS.includes(account.chainId) + setShowHashKeyModal(!isAllowedChain) + } else { + // 如果链 ID 未定义(钱包未连接),不显示弹窗 + setShowHashKeyModal(false) + } + }, [account.chainId]) + + // Console log current wallet chain + useEffect(() => { + console.log('钱包连接状态:', { + isConnected: account.isConnected, + address: account.address, + chainId: account.chainId, + status: account.status, + connector: account.connector?.name, + }) + + if (account.chainId) { + try { + const chainInfo = getChainInfo(account.chainId) + console.log('当前钱包所在的链:', { + chainId: account.chainId, + chainName: chainInfo.label, + chainInfo: chainInfo, + }) + } catch (error) { + console.log('当前钱包所在的链 (chainId):', account.chainId, '错误:', error) + } + } else { + if (account.isConnected) { + console.log('钱包已连接,但链信息不可用。地址:', account.address) + } else { + console.log('当前钱包未连接') + } + } + }, [account.chainId, account.isConnected, account.address, account.status, account.connector]) + const metaTags = useDynamicMetatags() const staticTitle = findRouteByPath(pathname)?.getTitle(pathname) ?? 'Uniswap Interface' const staticDescription = findRouteByPath(pathname)?.getDescription(pathname) @@ -84,6 +134,11 @@ export default function App() { {shouldOverridePageLayout ? : } + setShowHashKeyModal(false)} + currentChainId={account.chainId} + />
) diff --git a/apps/web/src/pages/Positions/index.tsx b/apps/web/src/pages/Positions/index.tsx index 6e34697e24a..b7cdc960bfe 100644 --- a/apps/web/src/pages/Positions/index.tsx +++ b/apps/web/src/pages/Positions/index.tsx @@ -5,7 +5,7 @@ import PROVIDE_LIQUIDITY from 'assets/images/provideLiquidity.png' import tokenLogo from 'assets/images/token-logo.png' import V4_HOOK from 'assets/images/v4Hooks.png' import { ExpandoRow } from 'components/AccountDrawer/MiniPortfolio/ExpandoRow' -import { useAccountDrawer } from 'components/AccountDrawer/MiniPortfolio/hooks' +import { useAppKit } from 'components/Web3Provider/reownConfig' import { MenuStateVariant, useSetMenu } from 'components/AccountDrawer/menuState' import { ExternalArrowLink } from 'components/Liquidity/ExternalArrowLink' import { LiquidityPositionCard, LiquidityPositionCardLoader } from 'components/Liquidity/LiquidityPositionCard' @@ -50,7 +50,7 @@ const PAGE_SIZE = 25 function DisconnectedWalletView() { const { t } = useTranslation() - const accountDrawer = useAccountDrawer() + const { open } = useAppKit() const setMenu = useSetMenu() const connectedWithoutEVM = useIsMissingPlatformWallet(Platform.EVM) @@ -58,7 +58,7 @@ function DisconnectedWalletView() { if (connectedWithoutEVM) { setMenu({ variant: MenuStateVariant.CONNECT_PLATFORM, platform: Platform.EVM }) } - accountDrawer.open() + open({ view: 'Connect' }) } return ( diff --git a/apps/web/src/pages/Swap/Buy/BuyFormButton.tsx b/apps/web/src/pages/Swap/Buy/BuyFormButton.tsx index 0484223e100..16032c51fd3 100644 --- a/apps/web/src/pages/Swap/Buy/BuyFormButton.tsx +++ b/apps/web/src/pages/Swap/Buy/BuyFormButton.tsx @@ -1,4 +1,4 @@ -import { useAccountDrawer } from 'components/AccountDrawer/MiniPortfolio/hooks' +import { useAppKit } from 'components/Web3Provider/reownConfig' import { useConnectionStatus } from 'features/accounts/store/hooks' import { useBuyFormContext } from 'pages/Swap/Buy/BuyFormContext' import { useTranslation } from 'react-i18next' @@ -14,7 +14,7 @@ interface BuyFormButtonProps { export function BuyFormButton({ forceDisabled }: BuyFormButtonProps) { const isDisconnected = useConnectionStatus('aggregate').isDisconnected - const accountDrawer = useAccountDrawer() + const { open } = useAppKit() const { t } = useTranslation() const isShortMobileDevice = useIsShortMobileDevice() @@ -29,7 +29,7 @@ export function BuyFormButton({ forceDisabled }: BuyFormButtonProps) { if (isDisconnected || isMissingPlatformWallet) { return ( -
- + {/* 未连接钱包时隐藏 "providing liquidity" 和 "hooks on v4" 内容 */} + {/* - + */}
) } diff --git a/apps/web/vite.config.mts b/apps/web/vite.config.mts index 9867176c562..0f791d88e93 100644 --- a/apps/web/vite.config.mts +++ b/apps/web/vite.config.mts @@ -350,7 +350,22 @@ export default defineConfig(({ mode }) => { proxy: { ...(ENABLE_PROXY ? { '/entry-gateway': createEntryGatewayProxy({ getLogger }) - } : {})} + } : {}), + // HSK Subgraph 代理 - 解决 CORS 问题 + '/hsk-subgraph': { + target: 'https://graphnode-testnet.hashkeychain.net', + changeOrigin: true, + secure: true, + rewrite: (path) => path.replace(/^\/hsk-subgraph/, '/subgraphs/name/uniswap-v3/hsk-test'), + configure: (proxy) => { + proxy.on('proxyReq', (proxyReq, req) => { + if (DEBUG_PROXY) { + console.log(`[HSK Subgraph Proxy] ${req.method} ${req.url}`) + } + }) + }, + }, + } }, build: { From 8e5e63f6e3cf9e67a3a3b3ca439f2a01f4551d18 Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Wed, 14 Jan 2026 14:44:38 +0800 Subject: [PATCH 08/33] fix: update rpc url --- .../Web3Provider/createWeb3Provider.tsx | 14 +++++----- .../components/Web3Provider/reownConfig.tsx | 26 ++++++++++++------- .../components/Web3Provider/wagmiConfig.ts | 2 +- .../components/Web3Provider/walletConnect.ts | 12 ++++----- apps/web/src/index.tsx | 3 ++- .../src/i18n/locales/source/en-US.json | 1 + .../src/i18n/locales/translations/es-ES.json | 1 + .../src/i18n/locales/translations/fil-PH.json | 1 + .../src/i18n/locales/translations/fr-FR.json | 1 + .../src/i18n/locales/translations/id-ID.json | 1 + .../src/i18n/locales/translations/ja-JP.json | 1 + .../src/i18n/locales/translations/ko-KR.json | 1 + .../src/i18n/locales/translations/nl-NL.json | 1 + .../src/i18n/locales/translations/pt-BR.json | 1 + .../src/i18n/locales/translations/pt-PT.json | 1 + .../src/i18n/locales/translations/ru-RU.json | 1 + .../src/i18n/locales/translations/tr-TR.json | 1 + .../src/i18n/locales/translations/vi-VN.json | 1 + .../src/i18n/locales/translations/zh-CN.json | 1 + .../src/i18n/locales/translations/zh-TW.json | 1 + 20 files changed, 47 insertions(+), 25 deletions(-) diff --git a/apps/web/src/components/Web3Provider/createWeb3Provider.tsx b/apps/web/src/components/Web3Provider/createWeb3Provider.tsx index 5e85d61d859..f4a1b3b28d1 100644 --- a/apps/web/src/components/Web3Provider/createWeb3Provider.tsx +++ b/apps/web/src/components/Web3Provider/createWeb3Provider.tsx @@ -1,20 +1,20 @@ import { CoinbaseWalletAdapter } from '@solana/wallet-adapter-coinbase' import { WalletProvider as SolanaWalletProvider } from '@solana/wallet-adapter-react' import { SolanaSignerUpdater } from 'components/Web3Provider/signSolanaTransaction' -import { AppKitProvider } from 'components/Web3Provider/reownConfig' +import { AppKitProvider, wagmiAdapter } from 'components/Web3Provider/reownConfig' import React, { type PropsWithChildren, type ReactNode, useMemo } from 'react' import { useWalletCapabilitiesStateEffect } from 'state/walletCapabilities/hooks/useWalletCapabilitiesStateEffect' -import { type Register, WagmiProvider } from 'wagmi' +import { type Config, WagmiProvider } from 'wagmi' -export function createWeb3Provider(params: { wagmiConfig: Register['config']; reconnectOnMount?: boolean }) { - const { wagmiConfig, reconnectOnMount = true } = params +export function createWeb3Provider(params: { reconnectOnMount?: boolean }) { + const { reconnectOnMount = true } = params const Provider = ({ children }: { children: ReactNode }) => ( - {/* Use our wagmiConfig which includes HashKey Chain (from ORDERED_EVM_CHAINS) */} - {/* WagmiAdapter creates its own config internally for Reown AppKit, but we still need our full config for other features */} - + {/* Use wagmiAdapter.wagmiConfig to ensure connection state syncs with Reown AppKit */} + {/* This matches hsk-staking-launchpad-main implementation */} + {children} diff --git a/apps/web/src/components/Web3Provider/reownConfig.tsx b/apps/web/src/components/Web3Provider/reownConfig.tsx index 3534541e23b..28bbb07bcd0 100644 --- a/apps/web/src/components/Web3Provider/reownConfig.tsx +++ b/apps/web/src/components/Web3Provider/reownConfig.tsx @@ -32,10 +32,10 @@ const networks = [ ...hashkey, rpcUrls: { default: { - http: ['https://mainnet.hashkeychain.io'], + http: ['https://mainnet.hsk.xyz'], }, public: { - http: ['https://mainnet.hashkeychain.io'], + http: ['https://mainnet.hsk.xyz'], }, }, blockExplorers: { @@ -49,10 +49,10 @@ const networks = [ ...hashkeyTestnet, rpcUrls: { default: { - http: ['https://testnet.hashkeychain.io'], + http: ['https://testnet.hsk.xyz'], }, public: { - http: ['https://testnet.hashkeychain.io'], + http: ['https://testnet.hsk.xyz'], }, }, blockExplorers: { @@ -82,12 +82,18 @@ const modal = createAppKit({ enableAuthLogger: false, enableReconnect: false, enableCoinbase: false, - metadata: { - name: 'HSKSwap', - description: 'HSKSwap Interface', - url: UNISWAP_WEB_URL, - icons: [`${UNISWAP_WEB_URL}icons/hskswap-icon.svg`], - }, + // metadata: Reown AppKit will automatically use window.location for metadata + // If needed, uncomment and customize: + // metadata: { + // name: 'HSKSwap', + // description: 'HSKSwap Interface', + // url: typeof window !== 'undefined' ? window.location.origin : UNISWAP_WEB_URL, + // icons: [ + // typeof window !== 'undefined' + // ? `${window.location.origin}/icons/hskswap-icon.svg` + // : `${UNISWAP_WEB_URL}icons/hskswap-icon.svg` + // ], + // }, features: { analytics: false, email: false, diff --git a/apps/web/src/components/Web3Provider/wagmiConfig.ts b/apps/web/src/components/Web3Provider/wagmiConfig.ts index 4bcf7a5db41..2f347d4dd1d 100644 --- a/apps/web/src/components/Web3Provider/wagmiConfig.ts +++ b/apps/web/src/components/Web3Provider/wagmiConfig.ts @@ -78,7 +78,7 @@ function createWagmiConnectors(params: { ...(isTestEnv() && !isPlaywrightEnv() ? [] : [walletConnect(WC_PARAMS)]), embeddedWallet(), coinbaseWallet({ - appName: 'Uniswap', + appName: 'HSKSwap', // CB SDK doesn't pass the parent origin context to their passkey site // Flagged to CB team and can remove UNISWAP_WEB_URL once fixed appLogoUrl: `${UNISWAP_WEB_URL}${UNISWAP_LOGO}`, diff --git a/apps/web/src/components/Web3Provider/walletConnect.ts b/apps/web/src/components/Web3Provider/walletConnect.ts index 1804380b033..028d2907369 100644 --- a/apps/web/src/components/Web3Provider/walletConnect.ts +++ b/apps/web/src/components/Web3Provider/walletConnect.ts @@ -34,10 +34,10 @@ export function walletTypeToAmplitudeWalletType(connectionType?: string): string export const WC_PARAMS = { projectId: WALLET_CONNECT_PROJECT_ID, metadata: { - name: 'Uniswap', - description: 'Uniswap Interface', - url: 'https://app.uniswap.org', - icons: ['https://app.uniswap.org/icons/hskswap-icon.svg'], + name: 'HSKSwap', + description: 'HSKSwap Interface', + url: typeof window !== 'undefined' ? window.location.origin : 'https://app.uniswap.org', + icons: [typeof window !== 'undefined' ? `${window.location.origin}/icons/hskswap-icon.svg` : 'https://app.uniswap.org/icons/hskswap-icon.svg'], }, qrModalOptions: { themeVariables: { @@ -75,8 +75,8 @@ export function uniswapWalletConnect() { ...wc, id: 'uniswapWalletConnect', type: 'uniswapWalletConnect', - name: 'Uniswap Wallet', - icon: 'https://app.uniswap.org/icons/hskswap-icon.svg', + name: 'HSKSwap Wallet', + icon: typeof window !== 'undefined' ? `${window.location.origin}/icons/hskswap-icon.svg` : 'https://app.uniswap.org/icons/hskswap-icon.svg', } }) } diff --git a/apps/web/src/index.tsx b/apps/web/src/index.tsx index 106e29df54f..ed01fe55c7d 100644 --- a/apps/web/src/index.tsx +++ b/apps/web/src/index.tsx @@ -127,7 +127,8 @@ function Updaters() { } // Production Web3Provider – always reconnects on mount and runs capability effects. -const Web3Provider = createWeb3Provider({ wagmiConfig }) +// Use wagmiAdapter.wagmiConfig from reownConfig (matching hsk-staking-launchpad-main) +const Web3Provider = createWeb3Provider({}) function GraphqlProviders({ children }: { children: React.ReactNode }) { return ( diff --git a/packages/uniswap/src/i18n/locales/source/en-US.json b/packages/uniswap/src/i18n/locales/source/en-US.json index 7bcb243971d..0247151d61f 100644 --- a/packages/uniswap/src/i18n/locales/source/en-US.json +++ b/packages/uniswap/src/i18n/locales/source/en-US.json @@ -301,6 +301,7 @@ "common.connectAWallet.button.switch": "Switch wallet", "common.connectTo": "Connect to {{platform}}", "common.connectWallet.button": "Connect wallet", + "common.connecting": "Connecting", "common.contactUs.button": "Contact us", "common.copied": "Copied", "common.copy.address": "Copy address", diff --git a/packages/uniswap/src/i18n/locales/translations/es-ES.json b/packages/uniswap/src/i18n/locales/translations/es-ES.json index d8ffb997b46..cb29377436c 100644 --- a/packages/uniswap/src/i18n/locales/translations/es-ES.json +++ b/packages/uniswap/src/i18n/locales/translations/es-ES.json @@ -301,6 +301,7 @@ "common.connectAWallet.button.switch": "Cambiar billetera", "common.connectTo": "Conectar a {{platform}}", "common.connectWallet.button": "Conectar billetera", + "common.connecting": "Conectando", "common.contactUs.button": "Contáctanos", "common.copied": "Copiado", "common.copy.address": "Copiar dirección", diff --git a/packages/uniswap/src/i18n/locales/translations/fil-PH.json b/packages/uniswap/src/i18n/locales/translations/fil-PH.json index 8d6df899430..7d33bdb162f 100644 --- a/packages/uniswap/src/i18n/locales/translations/fil-PH.json +++ b/packages/uniswap/src/i18n/locales/translations/fil-PH.json @@ -301,6 +301,7 @@ "common.connectAWallet.button.switch": "I-switch ang wallet", "common.connectTo": "Kumonekta sa {{platform}}", "common.connectWallet.button": "Ikonekta ang wallet", + "common.connecting": "Kumokonekta", "common.contactUs.button": "Makipag-ugnayan sa amin", "common.copied": "Nakopya na", "common.copy.address": "Kopyahin ang address", diff --git a/packages/uniswap/src/i18n/locales/translations/fr-FR.json b/packages/uniswap/src/i18n/locales/translations/fr-FR.json index fa8566a9524..2a6af3f218a 100644 --- a/packages/uniswap/src/i18n/locales/translations/fr-FR.json +++ b/packages/uniswap/src/i18n/locales/translations/fr-FR.json @@ -301,6 +301,7 @@ "common.connectAWallet.button.switch": "Changer de wallet", "common.connectTo": "Se connecter à {{platform}}", "common.connectWallet.button": "Connecter le wallet", + "common.connecting": "Connexion en cours", "common.contactUs.button": "Nous contacter", "common.copied": "Copié", "common.copy.address": "Copier l’adresse", diff --git a/packages/uniswap/src/i18n/locales/translations/id-ID.json b/packages/uniswap/src/i18n/locales/translations/id-ID.json index f429afbc493..66a6b42bffd 100644 --- a/packages/uniswap/src/i18n/locales/translations/id-ID.json +++ b/packages/uniswap/src/i18n/locales/translations/id-ID.json @@ -301,6 +301,7 @@ "common.connectAWallet.button.switch": "Ganti dompet", "common.connectTo": "Hubungkan ke {{platform}}", "common.connectWallet.button": "Hubungkan dompet", + "common.connecting": "Menghubungkan", "common.contactUs.button": "Hubungi kami", "common.copied": "Disalin", "common.copy.address": "Salin alamat", diff --git a/packages/uniswap/src/i18n/locales/translations/ja-JP.json b/packages/uniswap/src/i18n/locales/translations/ja-JP.json index 34edfb0dfa5..d9da5a16036 100644 --- a/packages/uniswap/src/i18n/locales/translations/ja-JP.json +++ b/packages/uniswap/src/i18n/locales/translations/ja-JP.json @@ -301,6 +301,7 @@ "common.connectAWallet.button.switch": "ウォレットを切り替え", "common.connectTo": "{{platform}} に接続", "common.connectWallet.button": "ウォレットを接続", + "common.connecting": "接続中", "common.contactUs.button": "お問い合わせ", "common.copied": "コピーしました", "common.copy.address": "アドレスをコピー", diff --git a/packages/uniswap/src/i18n/locales/translations/ko-KR.json b/packages/uniswap/src/i18n/locales/translations/ko-KR.json index defda020e47..6e6e06aa6a2 100644 --- a/packages/uniswap/src/i18n/locales/translations/ko-KR.json +++ b/packages/uniswap/src/i18n/locales/translations/ko-KR.json @@ -301,6 +301,7 @@ "common.connectAWallet.button.switch": "지갑 전환", "common.connectTo": "{{platform}}에 연결", "common.connectWallet.button": "지갑 연결", + "common.connecting": "연결 중", "common.contactUs.button": "문의하기", "common.copied": "복사됨", "common.copy.address": "주소 복사", diff --git a/packages/uniswap/src/i18n/locales/translations/nl-NL.json b/packages/uniswap/src/i18n/locales/translations/nl-NL.json index b6e2f34985c..eab1cd5098a 100644 --- a/packages/uniswap/src/i18n/locales/translations/nl-NL.json +++ b/packages/uniswap/src/i18n/locales/translations/nl-NL.json @@ -301,6 +301,7 @@ "common.connectAWallet.button.switch": "Van wallet wisselen", "common.connectTo": "Verbinden met {{platform}}", "common.connectWallet.button": "Wallet koppelen", + "common.connecting": "Bezig met verbinden", "common.contactUs.button": "Neem contact met ons op", "common.copied": "Gekopieerd", "common.copy.address": "Adres kopiëren", diff --git a/packages/uniswap/src/i18n/locales/translations/pt-BR.json b/packages/uniswap/src/i18n/locales/translations/pt-BR.json index 1ac5f3bf105..0db6c35465b 100644 --- a/packages/uniswap/src/i18n/locales/translations/pt-BR.json +++ b/packages/uniswap/src/i18n/locales/translations/pt-BR.json @@ -288,6 +288,7 @@ "common.connectAWallet.button": "Conectar uma carteira", "common.connectingWallet": "Conectando carteira...", "common.connectWallet.button": "Conectar carteira", + "common.connecting": "Conectando", "common.contactUs.button": "Fale conosco", "common.contractInteraction": "Interação contratual", "common.copied": "Copiado", diff --git a/packages/uniswap/src/i18n/locales/translations/pt-PT.json b/packages/uniswap/src/i18n/locales/translations/pt-PT.json index 33c7611e669..14061154213 100644 --- a/packages/uniswap/src/i18n/locales/translations/pt-PT.json +++ b/packages/uniswap/src/i18n/locales/translations/pt-PT.json @@ -301,6 +301,7 @@ "common.connectAWallet.button.switch": "Alterar carteira", "common.connectTo": "Conectar à {{platform}}", "common.connectWallet.button": "Conectar carteira", + "common.connecting": "Conectando", "common.contactUs.button": "Fale conosco", "common.copied": "Copiado", "common.copy.address": "Copiar endereço", diff --git a/packages/uniswap/src/i18n/locales/translations/ru-RU.json b/packages/uniswap/src/i18n/locales/translations/ru-RU.json index c2001a65189..4d78a21e839 100644 --- a/packages/uniswap/src/i18n/locales/translations/ru-RU.json +++ b/packages/uniswap/src/i18n/locales/translations/ru-RU.json @@ -301,6 +301,7 @@ "common.connectAWallet.button.switch": "Переключить кошелек", "common.connectTo": "Подключиться к {{platform}}", "common.connectWallet.button": "Подключить кошелек", + "common.connecting": "Подключение", "common.contactUs.button": "Свяжитесь с нами", "common.copied": "Скопировано", "common.copy.address": "Копировать адрес", diff --git a/packages/uniswap/src/i18n/locales/translations/tr-TR.json b/packages/uniswap/src/i18n/locales/translations/tr-TR.json index 88bef40bdc4..e2b7be115c8 100644 --- a/packages/uniswap/src/i18n/locales/translations/tr-TR.json +++ b/packages/uniswap/src/i18n/locales/translations/tr-TR.json @@ -301,6 +301,7 @@ "common.connectAWallet.button.switch": "Cüzdanı değiştir", "common.connectTo": "{{platform}} platformuna bağlan", "common.connectWallet.button": "Cüzdanı bağla", + "common.connecting": "Bağlanıyor", "common.contactUs.button": "Bize ulaş", "common.copied": "Kopyalandı", "common.copy.address": "Adresi kopyala", diff --git a/packages/uniswap/src/i18n/locales/translations/vi-VN.json b/packages/uniswap/src/i18n/locales/translations/vi-VN.json index 95512e3074a..4f148ff4aed 100644 --- a/packages/uniswap/src/i18n/locales/translations/vi-VN.json +++ b/packages/uniswap/src/i18n/locales/translations/vi-VN.json @@ -301,6 +301,7 @@ "common.connectAWallet.button.switch": "Chuyển ví", "common.connectTo": "Kết nối với {{platform}}", "common.connectWallet.button": "Kết nối ví", + "common.connecting": "Đang kết nối", "common.contactUs.button": "Liên hệ", "common.copied": "Đã sao chép", "common.copy.address": "Sao chép địa chỉ", diff --git a/packages/uniswap/src/i18n/locales/translations/zh-CN.json b/packages/uniswap/src/i18n/locales/translations/zh-CN.json index 6272d891679..b0eaca64ee1 100644 --- a/packages/uniswap/src/i18n/locales/translations/zh-CN.json +++ b/packages/uniswap/src/i18n/locales/translations/zh-CN.json @@ -301,6 +301,7 @@ "common.connectAWallet.button.switch": "切换钱包", "common.connectTo": "连接到 {{platform}}", "common.connectWallet.button": "连接钱包", + "common.connecting": "连接中", "common.contactUs.button": "联系我们", "common.copied": "已复制", "common.copy.address": "复制地址", diff --git a/packages/uniswap/src/i18n/locales/translations/zh-TW.json b/packages/uniswap/src/i18n/locales/translations/zh-TW.json index 11de0f3c92e..c209a1e16e8 100644 --- a/packages/uniswap/src/i18n/locales/translations/zh-TW.json +++ b/packages/uniswap/src/i18n/locales/translations/zh-TW.json @@ -301,6 +301,7 @@ "common.connectAWallet.button.switch": "切換錢包", "common.connectTo": "連接至 {{platform}}", "common.connectWallet.button": "連線錢包", + "common.connecting": "連線中", "common.contactUs.button": "聯絡我們", "common.copied": "已複製", "common.copy.address": "複製地址", From be1497e9841adce05c718091c19a510f8fd6fae5 Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Thu, 15 Jan 2026 17:00:13 +0800 Subject: [PATCH 09/33] feat: udpate for quote --- apps/web/public/favicon.ico | Bin 28847 -> 3878 bytes .../src/components/HashKeyChainOnlyModal.tsx | 22 +- .../components/NavBar/CompanyMenu/index.tsx | 19 +- .../NavBar/PreferencesMenu/Preferences.tsx | 1 - .../components/NavBar/Tabs/TabsContent.tsx | 7 - apps/web/src/components/NavBar/index.tsx | 2 - .../components/SearchModal/CurrencySearch.tsx | 14 +- .../PendingWalletConnectionModal.tsx | 4 +- .../Web3Provider/WebUniswapContext.tsx | 11 + .../Web3Provider/createWeb3Provider.tsx | 2 +- .../components/Web3Provider/reownConfig.tsx | 22 +- .../components/Web3Provider/walletConnect.ts | 11 +- .../components/Web3Status/ReownWeb3Status.tsx | 19 +- apps/web/src/components/Web3Status/index.tsx | 2 +- apps/web/src/components/swap/styled.tsx | 2 +- apps/web/src/hooks/useHSKSubgraphPools.ts | 35 +- apps/web/src/index.tsx | 1 - ...eateLegacyBannersNotificationDataSource.ts | 4 +- apps/web/src/pages/App.tsx | 29 -- apps/web/src/pages/MigrateV2/index.tsx | 1 - apps/web/src/pages/Positions/TopPools.tsx | 25 +- apps/web/src/pages/Positions/TopPoolsCard.tsx | 17 +- .../src/pages/Positions/TopPoolsSection.tsx | 4 +- apps/web/src/pages/Positions/index.tsx | 9 +- apps/web/src/pages/Swap/index.tsx | 23 +- apps/web/src/state/swap/hooks.tsx | 19 +- apps/web/src/theme/components/ThemeToggle.tsx | 2 +- .../src/components/icons/SettingsCustom.tsx | 1 - packages/ui/src/theme/fonts.ts | 8 +- .../CurrencyInputPanelHeader.tsx | 2 +- .../TokenSelector/TokenSelector.tsx | 77 +-- .../hooks/useHSKSubgraphPoolsForSelector.ts | 179 +++++++ .../hooks/usePoolTokensOptions.ts | 129 +++++ .../lists/TokenSelectorSwapList.tsx | 257 ++++----- .../components/TokenSelector/utils.test.tsx | 18 +- .../src/components/TokenSelector/utils.tsx | 5 +- .../OnchainItemList/OnchainItemList.web.tsx | 8 + .../components/lists/OnchainItemList/types.ts | 1 + .../src/components/lists/SectionHeader.tsx | 4 + .../apiClients/tradingApi/TradingApiClient.ts | 64 +-- packages/uniswap/src/data/cache.ts | 6 +- .../dataApi/tokenProjects/tokenProjects.ts | 16 +- .../features/dataApi/utils/buildCurrency.ts | 12 + .../src/features/tokens/useCurrencyInfo.ts | 45 +- .../settings/TransactionSettings.tsx | 18 +- .../settings/TransactionSettingsButton.tsx | 10 +- .../TransactionSettingsButtonWithSlippage.tsx | 5 +- .../hooks/usePollingIntervalByChain.ts | 2 +- .../SwapConfirmationModal.tsx | 486 +++++++++--------- .../SwapFormButton/SwapFormButton.tsx | 53 +- .../SwapFormCurrencyInputPanel.tsx | 8 +- .../form/SwapFormScreen/SwapFormScreen.tsx | 12 +- .../SwapFormScreenDetails.web.tsx | 22 +- .../GasAndWarningRows.web.tsx | 7 +- .../TradeInfoRow/TradeInfoRow.tsx | 54 +- .../swap/form/hooks/useOnSelectCurrency.ts | 19 + .../transformations/buildQuoteRequest.ts | 38 +- .../hooks/useDefaultSwapFormState.ts | 2 +- .../transactions/swap/utils/protocols.ts | 8 +- .../transactions/swap/utils/tradingApi.ts | 34 +- .../src/i18n/locales/source/en-US.json | 1 + 61 files changed, 1139 insertions(+), 779 deletions(-) create mode 100644 packages/uniswap/src/components/TokenSelector/hooks/useHSKSubgraphPoolsForSelector.ts create mode 100644 packages/uniswap/src/components/TokenSelector/hooks/usePoolTokensOptions.ts diff --git a/apps/web/public/favicon.ico b/apps/web/public/favicon.ico index 883787c6c0beb987b075038aeeb81b1083519fcb..76f55b74f9d5116e544c4e5b987733e75510384d 100644 GIT binary patch literal 3878 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 literal 28847 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 HTZI1~PqZDb diff --git a/apps/web/src/components/HashKeyChainOnlyModal.tsx b/apps/web/src/components/HashKeyChainOnlyModal.tsx index f40dce81c8a..09ac40f1cf7 100644 --- a/apps/web/src/components/HashKeyChainOnlyModal.tsx +++ b/apps/web/src/components/HashKeyChainOnlyModal.tsx @@ -1,11 +1,11 @@ +import useSelectChain from 'hooks/useSelectChain' import { useTranslation } from 'react-i18next' import { Button, Flex, Text } from 'ui/src' import { AlertTriangleFilled } from 'ui/src/components/icons/AlertTriangleFilled' import { Modal } from 'uniswap/src/components/modals/Modal' -import { ModalName } from 'uniswap/src/features/telemetry/constants' -import { UniverseChainId } from 'uniswap/src/features/chains/types' import { getChainInfo } from 'uniswap/src/features/chains/chainInfo' -import useSelectChain from 'hooks/useSelectChain' +import { UniverseChainId } from 'uniswap/src/features/chains/types' +import { ModalName } from 'uniswap/src/features/telemetry/constants' interface HashKeyChainOnlyModalProps { isOpen: boolean @@ -13,11 +13,7 @@ interface HashKeyChainOnlyModalProps { currentChainId?: UniverseChainId } -export function HashKeyChainOnlyModal({ - isOpen, - onClose, - currentChainId, -}: HashKeyChainOnlyModalProps): JSX.Element { +export function HashKeyChainOnlyModal({ isOpen, onClose, currentChainId }: HashKeyChainOnlyModalProps): JSX.Element { const { t } = useTranslation() const selectChain = useSelectChain() @@ -37,14 +33,7 @@ export function HashKeyChainOnlyModal({ return ( - + @@ -83,4 +72,3 @@ export function HashKeyChainOnlyModal({ ) } - diff --git a/apps/web/src/components/NavBar/CompanyMenu/index.tsx b/apps/web/src/components/NavBar/CompanyMenu/index.tsx index 5be68aceb45..8a84a356351 100644 --- a/apps/web/src/components/NavBar/CompanyMenu/index.tsx +++ b/apps/web/src/components/NavBar/CompanyMenu/index.tsx @@ -1,4 +1,3 @@ -import { Link } from 'react-router' import { Flex } from 'ui/src' import { ReactComponent as HskswapIcon } from 'ui/src/assets/icons/hskswap-icon.svg' import { ReactComponent as HskswapText } from 'ui/src/assets/icons/hskswap-text.svg' @@ -6,20 +5,14 @@ import { TestID } from 'uniswap/src/test/fixtures/testIDs' export function CompanyMenu() { return ( - + {/* */} - - - - - + + + + + {/* */} ) diff --git a/apps/web/src/components/NavBar/PreferencesMenu/Preferences.tsx b/apps/web/src/components/NavBar/PreferencesMenu/Preferences.tsx index 6136686e31b..f7e574f2879 100644 --- a/apps/web/src/components/NavBar/PreferencesMenu/Preferences.tsx +++ b/apps/web/src/components/NavBar/PreferencesMenu/Preferences.tsx @@ -3,7 +3,6 @@ import { PreferencesView } from 'components/NavBar/PreferencesMenu/shared' import { deprecatedStyled } from 'lib/styled-components' import { ChevronRight } from 'react-feather' import { Trans, useTranslation } from 'react-i18next' -import { ThemeSelector } from 'theme/components/ThemeToggle' import { Flex, Text, useSporeColors } from 'ui/src' import { useAppFiatCurrency } from 'uniswap/src/features/fiatCurrency/hooks' import { useCurrentLanguage, useLanguageInfo } from 'uniswap/src/features/language/hooks' diff --git a/apps/web/src/components/NavBar/Tabs/TabsContent.tsx b/apps/web/src/components/NavBar/Tabs/TabsContent.tsx index 325887ecf33..155c975a9c6 100644 --- a/apps/web/src/components/NavBar/Tabs/TabsContent.tsx +++ b/apps/web/src/components/NavBar/Tabs/TabsContent.tsx @@ -1,19 +1,12 @@ import { FeatureFlags, useFeatureFlag } from '@universe/gating' -import { Limit } from 'components/Icons/Limit' import { SwapV2 } from 'components/Icons/SwapV2' import { MenuItem } from 'components/NavBar/CompanyMenu/Content' import { usePortfolioRoutes } from 'pages/Portfolio/Header/hooks/usePortfolioRoutes' -import { PortfolioTab } from 'pages/Portfolio/types' -import { buildPortfolioUrl } from 'pages/Portfolio/utils/portfolioUrls' import { useTranslation } from 'react-i18next' import { useLocation } from 'react-router' import { useSporeColors } from 'ui/src' import { CoinConvert } from 'ui/src/components/icons/CoinConvert' -import { Compass } from 'ui/src/components/icons/Compass' -import { CreditCard } from 'ui/src/components/icons/CreditCard' import { Pools } from 'ui/src/components/icons/Pools' -import { ReceiveAlt } from 'ui/src/components/icons/ReceiveAlt' -import { Wallet } from 'ui/src/components/icons/Wallet' import { ElementName } from 'uniswap/src/features/telemetry/constants' export type TabsSection = { diff --git a/apps/web/src/components/NavBar/index.tsx b/apps/web/src/components/NavBar/index.tsx index 69d4ec0a150..613537d22eb 100644 --- a/apps/web/src/components/NavBar/index.tsx +++ b/apps/web/src/components/NavBar/index.tsx @@ -2,9 +2,7 @@ import { FeatureFlags, useFeatureFlag } from '@universe/gating' import Row from 'components/deprecated/Row' import { CompanyMenu } from 'components/NavBar/CompanyMenu' import { NewUserCTAButton } from 'components/NavBar/DownloadApp/NewUserCTAButton' -import { PreferenceMenu } from 'components/NavBar/PreferencesMenu' import { useTabsVisible } from 'components/NavBar/ScreenSizes' -import { SearchBar } from 'components/NavBar/SearchBar' import { useIsSearchBarVisible } from 'components/NavBar/SearchBar/useIsSearchBarVisible' import { Tabs } from 'components/NavBar/Tabs/Tabs' import TestnetModeTooltip from 'components/NavBar/TestnetMode/TestnetModeTooltip' diff --git a/apps/web/src/components/SearchModal/CurrencySearch.tsx b/apps/web/src/components/SearchModal/CurrencySearch.tsx index 3b1e934121d..114caeff3b1 100644 --- a/apps/web/src/components/SearchModal/CurrencySearch.tsx +++ b/apps/web/src/components/SearchModal/CurrencySearch.tsx @@ -1,13 +1,12 @@ import { Currency } from '@uniswap/sdk-core' import { SwitchNetworkAction } from 'components/Popups/types' import useSelectChain from 'hooks/useSelectChain' -import { useCallback, useEffect } from 'react' +import { useCallback, useEffect, useMemo } from 'react' import { useMultichainContext } from 'state/multichain/useMultichainContext' import { useSwapAndLimitContext } from 'state/swap/useSwapContext' import { Flex } from 'ui/src' import { TokenSelectorContent, TokenSelectorVariation } from 'uniswap/src/components/TokenSelector/TokenSelector' import { TokenSelectorFlow } from 'uniswap/src/components/TokenSelector/types' -import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' import { UniverseChainId } from 'uniswap/src/features/chains/types' import { InterfaceEventName, ModalName } from 'uniswap/src/features/telemetry/constants' import Trace from 'uniswap/src/features/telemetry/Trace' @@ -17,6 +16,9 @@ import { SwapTab } from 'uniswap/src/types/screens/interface' import { usePrevious } from 'utilities/src/react/hooks' import { showSwitchNetworkNotification } from 'utils/showSwitchNetworkNotification' +// HSKSwap 只支持 HashKey 主网和测试网 +const HSKSWAP_ALLOWED_CHAIN_IDS = [UniverseChainId.HashKey, UniverseChainId.HashKeyTestnet] + interface CurrencySearchProps { currencyField: CurrencyField switchNetworkAction: SwitchNetworkAction @@ -41,7 +43,11 @@ export function CurrencySearch({ const prevChainId = usePrevious(chainId) const selectChain = useSelectChain() - const { chains } = useEnabledChains() + + // 如果没有提供 chainIds,默认只使用 HashKey 主网和测试网 + const allowedChainIds = useMemo(() => { + return chainIds ?? HSKSWAP_ALLOWED_CHAIN_IDS + }, [chainIds]) const handleCurrencySelectTokenSelectorCallback = useCallback( async ({ currency }: { currency: Currency }) => { @@ -77,7 +83,7 @@ export function CurrencySearch({ svmAddress={wallet.svmAccount?.address} isLimits={currentTab === SwapTab.Limit} chainId={!isMultichainContext || isUserSelectedToken ? chainId : undefined} - chainIds={chainIds ?? chains} + chainIds={allowedChainIds} currencyField={currencyField} flow={TokenSelectorFlow.Swap} isSurfaceReady={true} diff --git a/apps/web/src/components/WalletModal/PendingWalletConnectionModal/PendingWalletConnectionModal.tsx b/apps/web/src/components/WalletModal/PendingWalletConnectionModal/PendingWalletConnectionModal.tsx index 24f6a6cee27..104cb76c64e 100644 --- a/apps/web/src/components/WalletModal/PendingWalletConnectionModal/PendingWalletConnectionModal.tsx +++ b/apps/web/src/components/WalletModal/PendingWalletConnectionModal/PendingWalletConnectionModal.tsx @@ -6,7 +6,7 @@ import { WalletIconWithRipple } from 'components/WalletModal/WalletIconWithRippl import { useConnectionStatus } from 'features/accounts/store/hooks' import { ExternalWallet } from 'features/accounts/store/types' import { useConnectWallet } from 'features/wallet/connection/hooks/useConnectWallet' -import { useEffect, useMemo, useState } from 'react' +import { useMemo } from 'react' import { useTranslation } from 'react-i18next' import { AnimatePresence, Button, Flex, HeightAnimator, Text } from 'ui/src' import SOLANA_ICON from 'ui/src/assets/logos/png/solana-logo.png' @@ -47,7 +47,7 @@ function useApplicablePendingWallet() { /** * Tracks which wallet needs the Solana prompt. Persists after EVM completes to keep modal open. * Different from useApplicablePendingWallet which becomes undefined once connection starts. - * + * * DISABLED: Solana prompt is disabled for HSKSwap. */ function useSolanaWalletToPrompt(applicablePendingWallet: ExternalWallet | undefined) { diff --git a/apps/web/src/components/Web3Provider/WebUniswapContext.tsx b/apps/web/src/components/Web3Provider/WebUniswapContext.tsx index 624b206f311..30589d4c72a 100644 --- a/apps/web/src/components/Web3Provider/WebUniswapContext.tsx +++ b/apps/web/src/components/Web3Provider/WebUniswapContext.tsx @@ -4,6 +4,7 @@ import { MenuStateVariant, useMenuState } from 'components/AccountDrawer/menuSta import { SwitchNetworkAction } from 'components/Popups/types' import { ReceiveModalState } from 'components/ReceiveCryptoModal/types' import { useOpenReceiveCryptoModal } from 'components/ReceiveCryptoModal/useOpenReceiveCryptoModal' +import { useAppKit } from 'components/Web3Provider/reownConfig' import { useConnectionStatus } from 'features/accounts/store/hooks' import { useAccountsStoreContext } from 'features/accounts/store/provider' import { useAccount } from 'hooks/useAccount' @@ -53,6 +54,16 @@ export function WebUniswapProvider({ children }: PropsWithChildren): JSX.Element // Abstracts web-specific transaction flow objects for usage in cross-platform flows in the `uniswap` package. function WebUniswapProviderInner({ children }: PropsWithChildren) { const account = useAccount() + const { open } = useAppKit() + + // Set up global connect wallet function for SwapFormButton + useEffect(() => { + if (typeof window !== 'undefined') { + window.__uniswapConnectWallet = () => { + open({ view: 'Connect' }) + } + } + }, [open]) // Check if current wallet can pay gas fees in any token (e.g., Porto wallet) const getCanPayGasInAnyToken = useCallback(() => { diff --git a/apps/web/src/components/Web3Provider/createWeb3Provider.tsx b/apps/web/src/components/Web3Provider/createWeb3Provider.tsx index f4a1b3b28d1..66c943587c6 100644 --- a/apps/web/src/components/Web3Provider/createWeb3Provider.tsx +++ b/apps/web/src/components/Web3Provider/createWeb3Provider.tsx @@ -1,7 +1,7 @@ import { CoinbaseWalletAdapter } from '@solana/wallet-adapter-coinbase' import { WalletProvider as SolanaWalletProvider } from '@solana/wallet-adapter-react' -import { SolanaSignerUpdater } from 'components/Web3Provider/signSolanaTransaction' import { AppKitProvider, wagmiAdapter } from 'components/Web3Provider/reownConfig' +import { SolanaSignerUpdater } from 'components/Web3Provider/signSolanaTransaction' import React, { type PropsWithChildren, type ReactNode, useMemo } from 'react' import { useWalletCapabilitiesStateEffect } from 'state/walletCapabilities/hooks/useWalletCapabilitiesStateEffect' import { type Config, WagmiProvider } from 'wagmi' diff --git a/apps/web/src/components/Web3Provider/reownConfig.tsx b/apps/web/src/components/Web3Provider/reownConfig.tsx index 28bbb07bcd0..ab4231cf449 100644 --- a/apps/web/src/components/Web3Provider/reownConfig.tsx +++ b/apps/web/src/components/Web3Provider/reownConfig.tsx @@ -1,20 +1,19 @@ // Reown AppKit configuration -import React from 'react' -import { UNISWAP_WEB_URL } from 'uniswap/src/constants/urls' -// biome-ignore lint/style/noRestrictedImports: wagmi account hook needed for wallet integration -import { useAccount as useWagmiAccount } from 'wagmi' +// Import HashKey networks from Reown AppKit (matching hsk-staking-launchpad) +import { type AppKitNetwork, hashkey, hashkeyTestnet } from '@reown/appkit/networks' // Import Reown AppKit - use ES6 import syntax for Vite compatibility (matching hsk-staking-launchpad) -import { +import { createAppKit, - useAppKit as useAppKitBase, useAppKitAccount as useAppKitAccountBase, + useAppKit as useAppKitBase, useDisconnect as useDisconnectBase, useWalletInfo as useWalletInfoBase, } from '@reown/appkit/react' import { WagmiAdapter } from '@reown/appkit-adapter-wagmi' -// Import HashKey networks from Reown AppKit (matching hsk-staking-launchpad) -import { type AppKitNetwork, hashkey, hashkeyTestnet } from '@reown/appkit/networks' +import React from 'react' +// biome-ignore lint/style/noRestrictedImports: wagmi account hook needed for wallet integration +import { useAccount as useWagmiAccount } from 'wagmi' if (process.env.REACT_APP_WALLET_CONNECT_PROJECT_ID === undefined) { throw new Error('REACT_APP_WALLET_CONNECT_PROJECT_ID must be a defined environment variable') @@ -89,7 +88,7 @@ const modal = createAppKit({ // description: 'HSKSwap Interface', // url: typeof window !== 'undefined' ? window.location.origin : UNISWAP_WEB_URL, // icons: [ - // typeof window !== 'undefined' + // typeof window !== 'undefined' // ? `${window.location.origin}/icons/hskswap-icon.svg` // : `${UNISWAP_WEB_URL}icons/hskswap-icon.svg` // ], @@ -136,7 +135,7 @@ export const useAppKitAccount = () => { const appKitAccount = useAppKitAccountBase() // Also get account from Wagmi to ensure consistency const wagmiAccount = useWagmiAccount() - + // Prefer Wagmi account if available, otherwise fall back to AppKit account return { address: wagmiAccount.address ?? appKitAccount.address, @@ -150,7 +149,7 @@ export const useAppKitAccount = () => { export const useAppKitConnectionStatus = () => { const wagmiAccount = useWagmiAccount() const account = useAppKitAccount() - + return { isConnecting: wagmiAccount.status === 'connecting' || wagmiAccount.status === 'reconnecting', isConnected: account.isConnected, @@ -160,4 +159,3 @@ export const useAppKitConnectionStatus = () => { // Export additional hooks for wallet management export const useDisconnect = useDisconnectBase export const useWalletInfo = useWalletInfoBase - diff --git a/apps/web/src/components/Web3Provider/walletConnect.ts b/apps/web/src/components/Web3Provider/walletConnect.ts index 028d2907369..aed25cf226d 100644 --- a/apps/web/src/components/Web3Provider/walletConnect.ts +++ b/apps/web/src/components/Web3Provider/walletConnect.ts @@ -37,7 +37,11 @@ export const WC_PARAMS = { name: 'HSKSwap', description: 'HSKSwap Interface', url: typeof window !== 'undefined' ? window.location.origin : 'https://app.uniswap.org', - icons: [typeof window !== 'undefined' ? `${window.location.origin}/icons/hskswap-icon.svg` : 'https://app.uniswap.org/icons/hskswap-icon.svg'], + icons: [ + typeof window !== 'undefined' + ? `${window.location.origin}/icons/hskswap-icon.svg` + : 'https://app.uniswap.org/icons/hskswap-icon.svg', + ], }, qrModalOptions: { themeVariables: { @@ -76,7 +80,10 @@ export function uniswapWalletConnect() { id: 'uniswapWalletConnect', type: 'uniswapWalletConnect', name: 'HSKSwap Wallet', - icon: typeof window !== 'undefined' ? `${window.location.origin}/icons/hskswap-icon.svg` : 'https://app.uniswap.org/icons/hskswap-icon.svg', + icon: + typeof window !== 'undefined' + ? `${window.location.origin}/icons/hskswap-icon.svg` + : 'https://app.uniswap.org/icons/hskswap-icon.svg', } }) } diff --git a/apps/web/src/components/Web3Status/ReownWeb3Status.tsx b/apps/web/src/components/Web3Status/ReownWeb3Status.tsx index 30c1a39f1c1..bc2afb9f2ff 100644 --- a/apps/web/src/components/Web3Status/ReownWeb3Status.tsx +++ b/apps/web/src/components/Web3Status/ReownWeb3Status.tsx @@ -41,22 +41,9 @@ export default function ReownWeb3Status(): JSX.Element { const [accountModalOpen, setAccountModalOpen] = useState(false) const [copied, copyToClipboard] = useCopyClipboard() - // Debug logging - if (process.env.NODE_ENV === 'development') { - console.log('ReownWeb3Status:', { - address, - isConnected, - isConnecting, - walletInfo, - reownDisconnect, - wagmiDisconnect - }) - } - // Prevent multiple connection attempts const handleConnect = () => { if (isConnecting) { - console.warn('Connection already in progress, ignoring click') return } open({ view: 'Connect' }) @@ -64,7 +51,6 @@ export default function ReownWeb3Status(): JSX.Element { const handleAccountClick = () => { if (isConnecting) { - console.warn('Connection in progress, ignoring account click') return } if (isConnected) { @@ -88,17 +74,14 @@ export default function ReownWeb3Status(): JSX.Element { if (wagmiDisconnect) { wagmiDisconnect() } - - console.log('Disconnect called successfully') } catch (error) { - console.error('Failed to disconnect:', error) // Still try wagmi disconnect as fallback try { if (wagmiDisconnect) { wagmiDisconnect() } } catch (fallbackError) { - console.error('Fallback disconnect also failed:', fallbackError) + // Fallback disconnect failed } } // Always close the modal (matching hsk-staking-launchpad behavior) diff --git a/apps/web/src/components/Web3Status/index.tsx b/apps/web/src/components/Web3Status/index.tsx index 660b709ac87..8ae702dfa4d 100644 --- a/apps/web/src/components/Web3Status/index.tsx +++ b/apps/web/src/components/Web3Status/index.tsx @@ -1,5 +1,5 @@ // Replaced with Reown AppKit - AccountDrawer removed -import ReownWeb3Status from './ReownWeb3Status' +import ReownWeb3Status from 'components/Web3Status/ReownWeb3Status' // Replaced with Reown AppKit - all drawer functionality removed export default function Web3Status(): JSX.Element { diff --git a/apps/web/src/components/swap/styled.tsx b/apps/web/src/components/swap/styled.tsx index fadb32a2e5b..81be91c7a42 100644 --- a/apps/web/src/components/swap/styled.tsx +++ b/apps/web/src/components/swap/styled.tsx @@ -12,7 +12,7 @@ export const PageWrapper = styled(Flex, { maxWidth: PAGE_WRAPPER_MAX_WIDTH, borderWidth: 1, borderColor: '$surface3', - marginTop:60, + marginTop: 60, $lg: { pt: '$spacing48', }, diff --git a/apps/web/src/hooks/useHSKSubgraphPools.ts b/apps/web/src/hooks/useHSKSubgraphPools.ts index 050df189f61..5ccada3bad6 100644 --- a/apps/web/src/hooks/useHSKSubgraphPools.ts +++ b/apps/web/src/hooks/useHSKSubgraphPools.ts @@ -1,14 +1,12 @@ import { useQuery } from '@tanstack/react-query' -import { Percent } from '@uniswap/sdk-core' -import { DEFAULT_TICK_SPACING, V2_DEFAULT_FEE_TIER } from 'uniswap/src/constants/pools' -import { BIPS_BASE } from 'uniswap/src/constants/misc' -import { PoolStat } from 'state/explore/types' import { Amount } from '@uniswap/client-explore/dist/uniswap/explore/v1/service_pb' -import { FeeData } from 'components/Liquidity/Create/types' +import { Percent } from '@uniswap/sdk-core' import { GraphQLApi } from '@universe/api' +import { PoolStat } from 'state/explore/types' +import { BIPS_BASE } from 'uniswap/src/constants/misc' +import { DEFAULT_TICK_SPACING } from 'uniswap/src/constants/pools' import { UniverseChainId } from 'uniswap/src/features/chains/types' import { toGraphQLChain } from 'uniswap/src/features/chains/utils' -import { ProtocolVersion } from '@uniswap/client-data-api/dist/data/v1/poolTypes_pb' // 使用代理 URL 避免 CORS 问题 // 开发环境:使用 Vite 代理(localhost) @@ -16,10 +14,10 @@ import { ProtocolVersion } from '@uniswap/client-data-api/dist/data/v1/poolTypes // 注意:如果生产环境出现 CORS 错误,需要: // 1. 让 subgraph 服务器配置 CORS 头(推荐) // 2. 或者通过后端 API 转发请求 -const SUBGRAPH_URL = +const SUBGRAPH_URL = typeof window !== 'undefined' && window.location.hostname === 'localhost' - ? '/hsk-subgraph' // 开发环境:使用 Vite 代理 - : 'https://graphnode-testnet.hashkeychain.net/subgraphs/name/uniswap-v3/hsk-test' // 生产环境:直接请求(需要服务器配置 CORS) + ? '/hsk-subgraph' // 开发环境:使用 Vite 代理 + : 'https://graphnode-testnet.hashkeychain.net/subgraphs/name/uniswap-v3/hsk-test' // 生产环境:直接请求(需要服务器配置 CORS) const BEARER_TOKEN = '' interface SubgraphPool { @@ -193,15 +191,20 @@ export function useHSKSubgraphPools(first: number = 10) { console.log('[useHSKSubgraphPools] 开始查询 subgraph...') try { const data = await querySubgraph(TOP_POOLS_QUERY, { first }) - console.log('[useHSKSubgraphPools] 查询成功,原始 pools 数量:', data.pools?.length) + console.log('[useHSKSubgraphPools] 查询成功,原始 pools 数量:', data.pools.length) const converted = data.pools.map(convertSubgraphPoolToPoolStat) console.log('[useHSKSubgraphPools] 转换后的 pools 数量:', converted.length) - console.log('[useHSKSubgraphPools] 转换后的第一个 pool:', converted[0] ? { - id: converted[0].id, - token0: converted[0].token0, - token1: converted[0].token1, - totalLiquidity: converted[0].totalLiquidity, - } : null) + console.log( + '[useHSKSubgraphPools] 转换后的第一个 pool:', + converted[0] + ? { + id: converted[0].id, + token0: converted[0].token0, + token1: converted[0].token1, + totalLiquidity: converted[0].totalLiquidity, + } + : null, + ) return converted } catch (error) { console.error('[useHSKSubgraphPools] 查询失败:', error) diff --git a/apps/web/src/index.tsx b/apps/web/src/index.tsx index ed01fe55c7d..0bef757b160 100644 --- a/apps/web/src/index.tsx +++ b/apps/web/src/index.tsx @@ -18,7 +18,6 @@ import { createChallengeSolverService, createSessionInitializationService } from import { QueryClientPersistProvider } from 'components/PersistQueryClient' import { createWeb3Provider, WalletCapabilitiesEffects } from 'components/Web3Provider/createWeb3Provider' import { WebUniswapProvider } from 'components/Web3Provider/WebUniswapContext' -import { wagmiConfig } from 'components/Web3Provider/wagmiConfig' import { AccountsStoreDevTool } from 'features/accounts/store/devtools' import { WebAccountsStoreProvider } from 'features/accounts/store/provider' import { ConnectWalletMutationProvider } from 'features/wallet/connection/hooks/useConnectWalletMutation' diff --git a/apps/web/src/notification-service/data-sources/createLegacyBannersNotificationDataSource.ts b/apps/web/src/notification-service/data-sources/createLegacyBannersNotificationDataSource.ts index 19defb7f356..c812cd4fe46 100644 --- a/apps/web/src/notification-service/data-sources/createLegacyBannersNotificationDataSource.ts +++ b/apps/web/src/notification-service/data-sources/createLegacyBannersNotificationDataSource.ts @@ -207,13 +207,13 @@ async function checkNoUniswapInterfaceFeesBanner(isDarkMode: boolean): Promise { // Always return empty array to disable Solana promo return [] - + // Original implementation (disabled): // const isEnabled = getFeatureFlag(FeatureFlags.SolanaPromo) // if (!isEnabled) { diff --git a/apps/web/src/pages/App.tsx b/apps/web/src/pages/App.tsx index 7dcc6f51e40..07cb5d287f1 100644 --- a/apps/web/src/pages/App.tsx +++ b/apps/web/src/pages/App.tsx @@ -53,35 +53,6 @@ export default function App() { } }, [account.chainId]) - // Console log current wallet chain - useEffect(() => { - console.log('钱包连接状态:', { - isConnected: account.isConnected, - address: account.address, - chainId: account.chainId, - status: account.status, - connector: account.connector?.name, - }) - - if (account.chainId) { - try { - const chainInfo = getChainInfo(account.chainId) - console.log('当前钱包所在的链:', { - chainId: account.chainId, - chainName: chainInfo.label, - chainInfo: chainInfo, - }) - } catch (error) { - console.log('当前钱包所在的链 (chainId):', account.chainId, '错误:', error) - } - } else { - if (account.isConnected) { - console.log('钱包已连接,但链信息不可用。地址:', account.address) - } else { - console.log('当前钱包未连接') - } - } - }, [account.chainId, account.isConnected, account.address, account.status, account.connector]) const metaTags = useDynamicMetatags() const staticTitle = findRouteByPath(pathname)?.getTitle(pathname) ?? 'Uniswap Interface' diff --git a/apps/web/src/pages/MigrateV2/index.tsx b/apps/web/src/pages/MigrateV2/index.tsx index abc496a02a7..cbefdc76310 100644 --- a/apps/web/src/pages/MigrateV2/index.tsx +++ b/apps/web/src/pages/MigrateV2/index.tsx @@ -6,7 +6,6 @@ import { LightCard } from 'components/Card/cards' import { AutoColumn } from 'components/deprecated/Column' import MigrateSushiPositionCard from 'components/PositionCard/Sushi' import MigrateV2PositionCard from 'components/PositionCard/V2' -import { SwitchLocaleLink } from 'components/SwitchLocaleLink' import { Dots } from 'components/swap/styled' import { V2Unsupported } from 'components/V2Unsupported' import { useAccount } from 'hooks/useAccount' diff --git a/apps/web/src/pages/Positions/TopPools.tsx b/apps/web/src/pages/Positions/TopPools.tsx index 703e7ce948e..3b7c9e1352d 100644 --- a/apps/web/src/pages/Positions/TopPools.tsx +++ b/apps/web/src/pages/Positions/TopPools.tsx @@ -56,12 +56,35 @@ export function TopPools({ chainId }: { chainId: UniverseChainId | null }) { : parseFloat(String(b.totalLiquidity?.value || '0')) return tvlB - tvlA }) - console.log('[TopPools] 排序后的 pools:', sorted.length, sorted.map(p => ({ + console.log('[TopPools] 排序后的 pools (前6个):', sorted.slice(0, 6).map(p => ({ id: p.id, token0: p.token0?.symbol, token1: p.token1?.symbol, tvl: p.totalLiquidity?.value }))) + // 输出所有 pools 的完整数据 + console.log('[TopPools] 所有 pools 数据 (完整):', { + totalCount: sorted.length, + allPools: sorted.map(p => ({ + id: p.id, + address: p.address, + token0: { + symbol: p.token0?.symbol, + name: p.token0?.name, + address: p.token0?.address, + }, + token1: { + symbol: p.token1?.symbol, + name: p.token1?.name, + address: p.token1?.address, + }, + totalLiquidity: p.totalLiquidity?.value, + feeTier: p.feeTier, + volume24h: p.volume24h?.value, + volume30d: p.volume30d?.value, + txCount: p.txCount, + })) + }) return sorted }, [hskPools]) diff --git a/apps/web/src/pages/Positions/TopPoolsCard.tsx b/apps/web/src/pages/Positions/TopPoolsCard.tsx index ce34b60155e..02e301ff5ac 100644 --- a/apps/web/src/pages/Positions/TopPoolsCard.tsx +++ b/apps/web/src/pages/Positions/TopPoolsCard.tsx @@ -1,4 +1,5 @@ import { gqlToCurrency, supportedChainIdFromGQLChain, unwrapToken } from 'appGraphql/data/util' +import { Percent } from '@uniswap/sdk-core' import { GraphQLApi } from '@universe/api' import { LiquidityPositionInfoBadges } from 'components/Liquidity/LiquidityPositionInfoBadges' import { LPIncentiveRewardsBadge } from 'components/Liquidity/LPIncentives/LPIncentiveRewardsBadge' @@ -7,9 +8,7 @@ import { Trans } from 'react-i18next' import { PoolStat } from 'state/explore/types' import { Flex, Text } from 'ui/src' import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' -import { toGraphQLChain } from 'uniswap/src/features/chains/utils' import { useLocalizationContext } from 'uniswap/src/features/language/LocalizationContext' -import { Percent } from '@uniswap/sdk-core' export function TopPoolsCard({ pool }: { pool: PoolStat }) { const { defaultChainId } = useEnabledChains() @@ -32,11 +31,11 @@ export function TopPoolsCard({ pool }: { pool: PoolStat }) { }) const chainId = supportedChainIdFromGQLChain(pool.chain as GraphQLApi.Chain) ?? defaultChainId - + // 尝试使用 gqlToCurrency,如果失败则直接使用 pool 中的 symbol - let token0 = pool.token0 ? gqlToCurrency(unwrapToken(chainId, pool.token0)) : undefined - let token1 = pool.token1 ? gqlToCurrency(unwrapToken(chainId, pool.token1)) : undefined - + const token0 = pool.token0 ? gqlToCurrency(unwrapToken(chainId, pool.token0)) : undefined + const token1 = pool.token1 ? gqlToCurrency(unwrapToken(chainId, pool.token1)) : undefined + // 如果 gqlToCurrency 返回 undefined(比如数据来自 HSK subgraph),直接使用 pool 中的 symbol const token0Symbol = token0?.symbol || pool.token0?.symbol || '--' const token1Symbol = token1?.symbol || pool.token1?.symbol || '--' @@ -58,7 +57,7 @@ export function TopPoolsCard({ pool }: { pool: PoolStat }) { if ('numerator' in apr && 'denominator' in apr) { let numValue: number let denValue: number - + // 处理数组格式(protobuf 序列化后的 JSBI) if (Array.isArray(apr.numerator)) { // JSBI 序列化为数组,需要转换为数字 @@ -73,7 +72,7 @@ export function TopPoolsCard({ pool }: { pool: PoolStat }) { } else { numValue = Number(apr.numerator) || 0 } - + if (Array.isArray(apr.denominator)) { if (apr.denominator.length === 0) { denValue = 1 @@ -83,7 +82,7 @@ export function TopPoolsCard({ pool }: { pool: PoolStat }) { } else { denValue = Number(apr.denominator) || 1 } - + // 计算百分比:Percent 是 numerator/denominator,转换为百分比需要 * 100 const percentValue = denValue > 0 ? (numValue / denValue) * 100 : 0 return formatPercent(percentValue.toFixed(3)) diff --git a/apps/web/src/pages/Positions/TopPoolsSection.tsx b/apps/web/src/pages/Positions/TopPoolsSection.tsx index 82ed9a066dc..edb9cee6da3 100644 --- a/apps/web/src/pages/Positions/TopPoolsSection.tsx +++ b/apps/web/src/pages/Positions/TopPoolsSection.tsx @@ -7,10 +7,10 @@ import { Flex, Text } from 'ui/src' export function TopPoolsSection({ pools, title, isLoading }: { pools: PoolStat[]; title: string; isLoading: boolean }) { // 调试信息 console.log('[TopPoolsSection] 渲染状态:', { - poolsLength: pools?.length, + poolsLength: pools.length, isLoading, title, - pools: pools?.slice(0, 3).map(p => ({ id: p.id, token0: p.token0?.symbol, token1: p.token1?.symbol })), + pools: pools.slice(0, 3).map((p) => ({ id: p.id, token0: p.token0?.symbol, token1: p.token1?.symbol })), }) if (isLoading) { diff --git a/apps/web/src/pages/Positions/index.tsx b/apps/web/src/pages/Positions/index.tsx index c6878a0b309..b37a18d1239 100644 --- a/apps/web/src/pages/Positions/index.tsx +++ b/apps/web/src/pages/Positions/index.tsx @@ -1,20 +1,16 @@ /* eslint-disable max-lines */ import { PositionStatus, ProtocolVersion } from '@uniswap/client-data-api/dist/data/v1/poolTypes_pb' import { FeatureFlags, useFeatureFlag } from '@universe/gating' -import PROVIDE_LIQUIDITY from 'assets/images/provideLiquidity.png' import tokenLogo from 'assets/images/token-logo.png' -import V4_HOOK from 'assets/images/v4Hooks.png' import { ExpandoRow } from 'components/AccountDrawer/MiniPortfolio/ExpandoRow' -import { useAppKit } from 'components/Web3Provider/reownConfig' import { MenuStateVariant, useSetMenu } from 'components/AccountDrawer/menuState' -import { ExternalArrowLink } from 'components/Liquidity/ExternalArrowLink' import { LiquidityPositionCard, LiquidityPositionCardLoader } from 'components/Liquidity/LiquidityPositionCard' import { LpIncentiveClaimModal } from 'components/Liquidity/LPIncentives/LpIncentiveClaimModal' -import LpIncentiveRewardsCard from 'components/Liquidity/LPIncentives/LpIncentiveRewardsCard' import { PositionsHeader } from 'components/Liquidity/PositionsHeader' import { PositionInfo } from 'components/Liquidity/types' import { getPositionUrl } from 'components/Liquidity/utils/getPositionUrl' import { parseRestPosition } from 'components/Liquidity/utils/parseFromRest' +import { useAppKit } from 'components/Web3Provider/reownConfig' import { useAccount } from 'hooks/useAccount' import { useLpIncentives } from 'hooks/useLpIncentives' import { atom, useAtom } from 'jotai' @@ -27,11 +23,8 @@ import { usePendingLPTransactionsChangeListener } from 'state/transactions/hooks import { useRequestPositionsForSavedPairs } from 'state/user/hooks' import { ClickableTamaguiStyle } from 'theme/components/styles' import { Anchor, Button, Flex, Text, useMedia } from 'ui/src' -import { CloseIconWithHover } from 'ui/src/components/icons/CloseIconWithHover' -import { InfoCircleFilled } from 'ui/src/components/icons/InfoCircleFilled' import { Pools } from 'ui/src/components/icons/Pools' import { Wallet } from 'ui/src/components/icons/Wallet' -import { uniswapUrls } from 'uniswap/src/constants/urls' import { useGetPositionsInfiniteQuery } from 'uniswap/src/data/rest/getPositions' import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' import { UniverseChainId } from 'uniswap/src/features/chains/types' diff --git a/apps/web/src/pages/Swap/index.tsx b/apps/web/src/pages/Swap/index.tsx index 4697c5b03f6..42ebd0b8b97 100644 --- a/apps/web/src/pages/Swap/index.tsx +++ b/apps/web/src/pages/Swap/index.tsx @@ -1,12 +1,10 @@ import { PrefetchBalancesWrapper } from 'appGraphql/data/apollo/AdaptiveTokenBalancesProvider' import type { Currency } from '@uniswap/sdk-core' import { FeatureFlags, useFeatureFlag } from '@universe/gating' -import { useAppKit } from 'components/Web3Provider/reownConfig' import { SwapBottomCard } from 'components/SwapBottomCard' -import { SwitchLocaleLink } from 'components/SwitchLocaleLink' import { PageWrapper } from 'components/swap/styled' +import { useAppKit } from 'components/Web3Provider/reownConfig' import { useAccount } from 'hooks/useAccount' -import { useDeferredComponent } from 'hooks/useDeferredComponent' import { PageType, useIsPage } from 'hooks/useIsPage' import { useModalState } from 'hooks/useModalState' import { useResetOverrideOneClickSwapFlag } from 'pages/Swap/settings/OneClickSwap' @@ -29,7 +27,6 @@ import { zIndexes } from 'ui/src/theme' import { useUniswapContext } from 'uniswap/src/contexts/UniswapContext' import { useIsModeMismatch } from 'uniswap/src/features/chains/hooks/useEnabledChains' import { UniverseChainId } from 'uniswap/src/features/chains/types' -import { RampDirection } from 'uniswap/src/features/fiatOnRamp/types' import { useGetPasskeyAuthStatus } from 'uniswap/src/features/passkey/hooks/useGetPasskeyAuthStatus' import { WebFORNudgeProvider } from 'uniswap/src/features/providers/webForNudgeProvider' import { InterfaceEventName, InterfacePageName, ModalName } from 'uniswap/src/features/telemetry/constants' @@ -341,16 +338,14 @@ function UniversalSwapFlow({ onSelectOption={onTabClick} gap={isMobileWeb ? '$spacing8' : undefined} /> - ) : ( - // - // {TAB_TYPE_TO_LABEL[SwapTab.Swap](t)} - // - null - )} + ) : // + // {TAB_TYPE_TO_LABEL[SwapTab.Swap](t)} + // + null} )} {currentTab === SwapTab.Swap && ( diff --git a/apps/web/src/state/swap/hooks.tsx b/apps/web/src/state/swap/hooks.tsx index 33540d6479e..d3bc4385f76 100644 --- a/apps/web/src/state/swap/hooks.tsx +++ b/apps/web/src/state/swap/hooks.tsx @@ -228,33 +228,22 @@ export function useInitialCurrencyState(): { // biome-ignore lint/correctness/useExhaustiveDependencies: We do not want to rerender on a change to persistedFilteredChainIds const { initialInputCurrencyAddress, initialChainId } = useMemo(() => { - // Default to native if no query params or chain is not compatible with testnet or mainnet mode - if (!hasCurrencyQueryParams || !isSupportedChainCompatible) { - const initialChainId = persistedFilteredChainIds?.input ?? defaultChainId - return { - initialInputCurrencyAddress: getNativeAddress(initialChainId), - initialChainId, - } - } - // Handle query params or disconnected state + // Handle query params - only set currency if explicitly provided in URL if (parsedCurrencyState.inputCurrencyAddress) { return { initialInputCurrencyAddress: parsedCurrencyState.inputCurrencyAddress, initialChainId: parsedCurrencyState.chainId ? supportedChainId : undefined, } } - // return ETH or parsedCurrencyState + // No default currency - return undefined to let user select return { - initialInputCurrencyAddress: parsedCurrencyState.outputCurrencyAddress ? undefined : 'ETH', + initialInputCurrencyAddress: undefined, initialChainId: parsedCurrencyState.chainId ? supportedChainId : undefined, } }, [ - hasCurrencyQueryParams, - isSupportedChainCompatible, parsedCurrencyState.inputCurrencyAddress, - parsedCurrencyState.outputCurrencyAddress, + parsedCurrencyState.chainId, supportedChainId, - defaultChainId, ]) const supportedOutputChainId = useSupportedChainId(parsedCurrencyState.outputChainId) diff --git a/apps/web/src/theme/components/ThemeToggle.tsx b/apps/web/src/theme/components/ThemeToggle.tsx index 22226044249..96bb117200f 100644 --- a/apps/web/src/theme/components/ThemeToggle.tsx +++ b/apps/web/src/theme/components/ThemeToggle.tsx @@ -1,5 +1,5 @@ import { atom, useAtom } from 'jotai' -import { atomWithStorage, useAtomValue, useUpdateAtom } from 'jotai/utils' +import { atomWithStorage, useUpdateAtom } from 'jotai/utils' import ms from 'ms' import { useCallback, useEffect, useMemo } from 'react' import { Moon, Sun } from 'react-feather' diff --git a/packages/ui/src/components/icons/SettingsCustom.tsx b/packages/ui/src/components/icons/SettingsCustom.tsx index 27d39c377c3..b3a4e5a7ec6 100644 --- a/packages/ui/src/components/icons/SettingsCustom.tsx +++ b/packages/ui/src/components/icons/SettingsCustom.tsx @@ -32,4 +32,3 @@ export const [SettingsCustom, AnimatedSettingsCustom] = createIcon({ ), defaultFill: '#94A3B8', }) - diff --git a/packages/ui/src/theme/fonts.ts b/packages/ui/src/theme/fonts.ts index ca70baf1333..e9de4aefd72 100644 --- a/packages/ui/src/theme/fonts.ts +++ b/packages/ui/src/theme/fonts.ts @@ -45,13 +45,9 @@ const fontFamily = { }, } -const baselMedium = isWebPlatform - ? "'Aleo', sans-serif" - : fontFamily.sansSerif.medium +const baselMedium = isWebPlatform ? "'Aleo', sans-serif" : fontFamily.sansSerif.medium -const baselBook = isWebPlatform - ? "'Aleo', sans-serif" - : fontFamily.sansSerif.book +const baselBook = isWebPlatform ? "'Aleo', sans-serif" : fontFamily.sansSerif.book const monospaceFontFamily = isWebPlatform ? 'ui-monospace, SFMono-Regular, SF Mono, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono", "Roboto Mono", "Courier New", monospace' diff --git a/packages/uniswap/src/components/CurrencyInputPanel/CurrencyInputPanelHeader.tsx b/packages/uniswap/src/components/CurrencyInputPanel/CurrencyInputPanelHeader.tsx index c1ea8c0ad41..b4340d82d92 100644 --- a/packages/uniswap/src/components/CurrencyInputPanel/CurrencyInputPanelHeader.tsx +++ b/packages/uniswap/src/components/CurrencyInputPanel/CurrencyInputPanelHeader.tsx @@ -62,7 +62,7 @@ export function CurrencyInputPanelHeader({ } const showInputPresets = - (isWebAppDesktop || isExtensionApp) && currencyField === CurrencyField.INPUT && currencyBalance + (isWebAppDesktop || isExtensionApp) && currencyField === CurrencyField.INPUT && currencyInfo return ( { - if (searchInFocus && !searchFilter && !isTestnetModeEnabled) { - return ( - - ) - } - - if (searchFilter) { - return ( - - ) - } + // Search-related logic commented out - 搜索相关逻辑已注释 + // if (searchInFocus && !searchFilter && !isTestnetModeEnabled) { + // return ( + // + // ) + // } + + // if (searchFilter) { + // return ( + // + // ) + // } switch (variation) { case TokenSelectorVariation.BalancesOnly: @@ -321,7 +322,8 @@ export function TokenSelectorContent({ )} - + /> */} + {/* NetworkFilter commented out - 网络选择器已注释 */} + {/* + { + onChangeChainFilter(newChainId) + onSelectChain?.(newChainId) + }} + /> + */} {isLimits && ( = {}) { + // Debug log + if (typeof window !== 'undefined') { + console.log('[useHSKSubgraphPoolsForSelector] Querying Subgraph:', { + url: SUBGRAPH_URL, + isLocalhost: window.location.hostname === 'localhost', + variables, + }) + } + + try { + const response = await fetch(SUBGRAPH_URL, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + query, + variables, + }), + }) + + if (!response.ok) { + const errorText = await response.text() + console.error('[useHSKSubgraphPoolsForSelector] HTTP error:', { + status: response.status, + statusText: response.statusText, + body: errorText, + }) + throw new Error(`HTTP error! status: ${response.status}, body: ${errorText}`) + } + + const data = await response.json() + + if (data.errors) { + console.error('[useHSKSubgraphPoolsForSelector] GraphQL errors:', data.errors) + throw new Error(`GraphQL errors: ${JSON.stringify(data.errors, null, 2)}`) + } + + // Debug log + if (typeof window !== 'undefined') { + console.log('[useHSKSubgraphPoolsForSelector] Query success:', { + poolsCount: data.data?.pools?.length ?? 0, + }) + } + + return data.data as SubgraphResponse + } catch (error) { + console.error('[useHSKSubgraphPoolsForSelector] Query failed:', { + url: SUBGRAPH_URL, + error: error instanceof Error ? error.message : String(error), + }) + throw error + } +} + +const TOP_POOLS_QUERY = ` + query TopPools($first: Int!) { + pools( + first: $first + orderBy: totalValueLockedUSD + orderDirection: desc + ) { + id + token0 { + id + symbol + name + decimals + } + token1 { + id + symbol + name + decimals + } + feeTier + liquidity + totalValueLockedUSD + } + } +` + +function convertSubgraphPoolToPoolForSelector(pool: SubgraphPool): PoolForSelector { + return { + token0: { + address: pool.token0.id, + symbol: pool.token0.symbol, + name: pool.token0.name, + decimals: parseInt(pool.token0.decimals, 10), + }, + token1: { + address: pool.token1.id, + symbol: pool.token1.symbol, + name: pool.token1.name, + decimals: parseInt(pool.token1.decimals, 10), + }, + } +} + +/** + * Hook to fetch pools from HSK Subgraph for Token Selector + * Returns pools data in a format suitable for extracting tokens + */ +export function useHSKSubgraphPoolsForSelector(first: number = 1000) { + return useQuery({ + queryKey: ['hsk-subgraph-pools-selector', first], + queryFn: async () => { + const data = await querySubgraph(TOP_POOLS_QUERY, { first }) + const pools = data.pools.map(convertSubgraphPoolToPoolForSelector) + + // Debug log + if (typeof window !== 'undefined') { + console.log('[useHSKSubgraphPoolsForSelector] Converted pools:', { + originalCount: data.pools.length, + convertedCount: pools.length, + samplePool: pools[0] ? { + token0: pools[0].token0.symbol, + token1: pools[0].token1.symbol, + } : null, + }) + } + + return pools + }, + staleTime: 60 * 1000, // 1 minute + refetchInterval: 60 * 1000, // Refetch every minute + retry: 2, // Retry 2 times on failure + retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000), // Exponential backoff + }) +} diff --git a/packages/uniswap/src/components/TokenSelector/hooks/usePoolTokensOptions.ts b/packages/uniswap/src/components/TokenSelector/hooks/usePoolTokensOptions.ts new file mode 100644 index 00000000000..907c1ba7e48 --- /dev/null +++ b/packages/uniswap/src/components/TokenSelector/hooks/usePoolTokensOptions.ts @@ -0,0 +1,129 @@ +import { useMemo } from 'react' +import { TokenOption } from 'uniswap/src/components/lists/items/types' +import { currencyInfosToTokenOptions } from 'uniswap/src/components/TokenSelector/hooks/useCurrencyInfosToTokenOptions' +import { UniverseChainId } from 'uniswap/src/features/chains/types' +import { CurrencyInfo } from 'uniswap/src/features/dataApi/types' +import { buildCurrency, buildCurrencyInfo } from 'uniswap/src/features/dataApi/utils/buildCurrency' +import { currencyId } from 'uniswap/src/utils/currencyId' + +interface PoolToken { + address?: string + symbol?: string + name?: string + decimals?: number +} + +interface Pool { + token0?: PoolToken + token1?: PoolToken +} + +/** + * Extract unique tokens from pools and convert them to TokenOptions + * Format matches recent searches + */ +export function usePoolTokensOptions( + pools: Pool[] | undefined, + chainId: UniverseChainId, +): { tokenOptions: TokenOption[]; loading: boolean } { + // Extract unique tokens from pools + const uniqueTokens = useMemo(() => { + if (!pools || pools.length === 0) { + return [] + } + + const tokenMap = new Map() + + pools.forEach((pool) => { + // Add token0 + if (pool.token0?.address) { + const key = pool.token0.address.toLowerCase() + if (!tokenMap.has(key)) { + tokenMap.set(key, pool.token0) + } + } + + // Add token1 + if (pool.token1?.address) { + const key = pool.token1.address.toLowerCase() + if (!tokenMap.has(key)) { + tokenMap.set(key, pool.token1) + } + } + }) + + return Array.from(tokenMap.values()) + }, [pools]) + + // Build CurrencyInfos directly from pool tokens (since GraphQL API doesn't support HashKey) + const currencyInfos = useMemo(() => { + if (uniqueTokens.length === 0) { + return [] + } + + const infos: CurrencyInfo[] = [] + + uniqueTokens.forEach((token) => { + if (!token.address || !token.symbol || !token.name || token.decimals === undefined) { + return + } + + try { + // Build currency from token data + const currency = buildCurrency({ + chainId, + address: token.address, + decimals: token.decimals, + symbol: token.symbol, + name: token.name, + }) + + if (currency) { + // Build currency info + const currencyInfo = buildCurrencyInfo({ + currency, + currencyId: currencyId(currency), + logoUrl: undefined, // Pools data doesn't include logo + safetyInfo: undefined, // No safety info from pools + }) + + if (currencyInfo) { + infos.push(currencyInfo) + } + } + } catch (error) { + // Skip invalid tokens + if (typeof window !== 'undefined') { + console.warn('[usePoolTokensOptions] Failed to build currency for token:', token, error) + } + } + }) + + // Debug log + if (typeof window !== 'undefined') { + console.log('[usePoolTokensOptions] Debug:', { + uniqueTokens: uniqueTokens.length, + currencyInfos: infos.length, + chainId, + }) + } + + return infos + }, [uniqueTokens, chainId]) + + // Convert to TokenOptions (same format as recent searches) + const tokenOptions = useMemo(() => { + const options = currencyInfosToTokenOptions(currencyInfos) ?? [] + // Debug log + if (typeof window !== 'undefined') { + console.log('[usePoolTokensOptions] TokenOptions:', { + currencyInfos: currencyInfos.length, + tokenOptions: options.length, + }) + } + return options + }, [currencyInfos]) + + // Loading is false since we're building from pools data directly + return { tokenOptions, loading: false } +} diff --git a/packages/uniswap/src/components/TokenSelector/lists/TokenSelectorSwapList.tsx b/packages/uniswap/src/components/TokenSelector/lists/TokenSelectorSwapList.tsx index 75b4149731a..252fe1bc997 100644 --- a/packages/uniswap/src/components/TokenSelector/lists/TokenSelectorSwapList.tsx +++ b/packages/uniswap/src/components/TokenSelector/lists/TokenSelectorSwapList.tsx @@ -5,16 +5,17 @@ import { type OnchainItemSection, OnchainItemSectionName } from 'uniswap/src/com import { useOnchainItemListSection } from 'uniswap/src/components/lists/utils' import { useCommonTokensOptionsWithFallback } from 'uniswap/src/components/TokenSelector/hooks/useCommonTokensOptionsWithFallback' import { useFavoriteTokensOptions } from 'uniswap/src/components/TokenSelector/hooks/useFavoriteTokensOptions' +import { useHSKSubgraphPoolsForSelector } from 'uniswap/src/components/TokenSelector/hooks/useHSKSubgraphPoolsForSelector' +import { usePoolTokensOptions } from 'uniswap/src/components/TokenSelector/hooks/usePoolTokensOptions' import { usePortfolioTokenOptions } from 'uniswap/src/components/TokenSelector/hooks/usePortfolioTokenOptions' -import { useRecentlySearchedTokens } from 'uniswap/src/components/TokenSelector/hooks/useRecentlySearchedTokens' -import { useTrendingTokensOptions } from 'uniswap/src/components/TokenSelector/hooks/useTrendingTokensOptions' +// import { useRecentlySearchedTokens } from 'uniswap/src/components/TokenSelector/hooks/useRecentlySearchedTokens' import { TokenSelectorList } from 'uniswap/src/components/TokenSelector/TokenSelectorList' import { OnSelectCurrency, TokenSectionsHookProps } from 'uniswap/src/components/TokenSelector/types' import { isSwapListLoading } from 'uniswap/src/components/TokenSelector/utils' import { useBridgingTokensOptions } from 'uniswap/src/features/bridging/hooks/tokens' import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' import { UniverseChainId } from 'uniswap/src/features/chains/types' -import { ClearRecentSearchesButton } from 'uniswap/src/features/search/ClearRecentSearchesButton' +// import { ClearRecentSearchesButton } from 'uniswap/src/features/search/ClearRecentSearchesButton' import { isMobileApp } from 'utilities/src/platform' // eslint-disable-next-line complexity @@ -26,143 +27,149 @@ function useTokenSectionsForSwap({ }: TokenSectionsHookProps): GqlResult[]> { const { defaultChainId, isTestnetModeEnabled } = useEnabledChains() + // Get pools from HSK Subgraph const { - data: portfolioTokenOptions, - error: portfolioTokenOptionsError, - refetch: refetchPortfolioTokenOptions, - loading: portfolioTokenOptionsLoading, - } = usePortfolioTokenOptions({ evmAddress, svmAddress, chainFilter }) - - const { - data: trendingTokenOptions, - error: trendingTokenOptionsError, - refetch: refetchTrendingTokenOptions, - loading: trendingTokenOptionsLoading, - } = useTrendingTokensOptions({ evmAddress, svmAddress, chainFilter }) - - const { - data: favoriteTokenOptions, - error: favoriteTokenOptionsError, - refetch: refetchFavoriteTokenOptions, - loading: favoriteTokenOptionsLoading, - } = useFavoriteTokensOptions({ evmAddress, svmAddress, chainFilter }) - - const { - data: commonTokenOptions, - error: commonTokenOptionsError, - refetch: refetchCommonTokenOptions, - loading: commonTokenOptionsLoading, - // if there is no chain filter, first check if the input token has a chainId, fallback to defaultChainId - } = useCommonTokensOptionsWithFallback({ - evmAddress, - svmAddress, - chainFilter: chainFilter ?? oppositeSelectedToken?.chainId ?? defaultChainId, - }) + data: hskPools, + isLoading: hskPoolsLoading, + error: hskPoolsError, + refetch: refetchPools, + } = useHSKSubgraphPoolsForSelector(1000) + + // Extract tokens from pools (only for HashKey chains) + // Always use HashKeyTestnet as default since Subgraph is for testnet + // If chainFilter is HashKey or HashKeyTestnet, use it; otherwise default to HashKeyTestnet + const poolChainId = useMemo(() => { + if (chainFilter === UniverseChainId.HashKey || chainFilter === UniverseChainId.HashKeyTestnet) { + return chainFilter + } + // Default to HashKeyTestnet since Subgraph is for testnet + return UniverseChainId.HashKeyTestnet + }, [chainFilter]) + + const { tokenOptions: poolTokensOptions, loading: poolTokensLoading } = usePoolTokensOptions( + hskPools, + poolChainId, + ) - const { - data: bridgingTokenOptions, - error: bridgingTokenOptionsError, - refetch: refetchBridgingTokenOptions, - loading: bridgingTokenOptionsLoading, - shouldNest: shouldNestBridgingTokens, - } = useBridgingTokensOptions({ oppositeSelectedToken, evmAddress, svmAddress, chainFilter }) - - const recentlySearchedTokenOptions = useRecentlySearchedTokens(chainFilter) - - const error = - (!portfolioTokenOptions && portfolioTokenOptionsError) || - (!trendingTokenOptions && trendingTokenOptionsError) || - (!favoriteTokenOptions && favoriteTokenOptionsError) || - (!commonTokenOptions && commonTokenOptionsError) || - (!bridgingTokenOptions && bridgingTokenOptionsError) - - const loading = - (!portfolioTokenOptions && portfolioTokenOptionsLoading) || - (!trendingTokenOptions && trendingTokenOptionsLoading) || - (!favoriteTokenOptions && favoriteTokenOptionsLoading) || - (!commonTokenOptions && commonTokenOptionsLoading) || - (!bridgingTokenOptions && bridgingTokenOptionsLoading) - - const refetchAllRef = useRef<() => void>(() => {}) - - refetchAllRef.current = (): void => { - refetchPortfolioTokenOptions?.() - refetchTrendingTokenOptions?.() - refetchFavoriteTokenOptions?.() - refetchCommonTokenOptions?.() - refetchBridgingTokenOptions?.() + // Debug logs + if (typeof window !== 'undefined') { + console.log('[TokenSelectorSwapList] Debug:', { + chainFilter, + poolChainId, + hskPools: hskPools?.length, + hskPoolsLoading, + hskPoolsError: hskPoolsError?.message, + poolTokensOptions: poolTokensOptions?.length, + poolTokensLoading, + samplePoolTokens: poolTokensOptions?.slice(0, 3).map(t => ({ + symbol: t.currencyInfo?.currency.symbol, + name: t.currencyInfo?.currency.name, + address: t.currencyInfo?.currency.address, + })), + }) } - const refetch = useCallback(() => { - refetchAllRef.current() - }, []) - - // we draw the Suggested pills as a single item of a section list, so `data` is TokenOption[][] - - const suggestedSectionOptions = useMemo(() => [commonTokenOptions ?? []], [commonTokenOptions]) - const suggestedSection = useOnchainItemListSection({ - sectionKey: OnchainItemSectionName.SuggestedTokens, - options: suggestedSectionOptions, + // Other token options commented out - 其他代币选项已注释 + // const { + // data: portfolioTokenOptions, + // error: portfolioTokenOptionsError, + // refetch: refetchPortfolioTokenOptions, + // loading: portfolioTokenOptionsLoading, + // } = usePortfolioTokenOptions({ evmAddress, svmAddress, chainFilter }) + + // const { + // data: favoriteTokenOptions, + // error: favoriteTokenOptionsError, + // refetch: refetchFavoriteTokenOptions, + // loading: favoriteTokenOptionsLoading, + // } = useFavoriteTokensOptions({ evmAddress, svmAddress, chainFilter }) + + // const { + // data: commonTokenOptions, + // error: commonTokenOptionsError, + // refetch: refetchCommonTokenOptions, + // loading: commonTokenOptionsLoading, + // } = useCommonTokensOptionsWithFallback({ + // evmAddress, + // svmAddress, + // chainFilter: chainFilter ?? oppositeSelectedToken?.chainId ?? defaultChainId, + // }) + + // const { + // data: bridgingTokenOptions, + // error: bridgingTokenOptionsError, + // refetch: refetchBridgingTokenOptions, + // loading: bridgingTokenOptionsLoading, + // shouldNest: shouldNestBridgingTokens, + // } = useBridgingTokensOptions({ oppositeSelectedToken, evmAddress, svmAddress, chainFilter }) + + // Recent Searches - 已注释 + // const recentlySearchedTokenOptions = useRecentlySearchedTokens(chainFilter) + + // Pool tokens section - 使用新的 section name,格式和 recent searches 一样 + const poolTokensSection = useOnchainItemListSection({ + sectionKey: OnchainItemSectionName.PoolTokens, // 使用新的 PoolTokens section key + options: poolTokensOptions, }) - const portfolioSection = useOnchainItemListSection({ - sectionKey: OnchainItemSectionName.YourTokens, - options: portfolioTokenOptions, - }) + // Recent Searches section - 已注释 + // const memoizedEndElement = useMemo(() => , []) + // const recentSection = useOnchainItemListSection({ + // sectionKey: OnchainItemSectionName.RecentSearches, + // options: recentlySearchedTokenOptions, + // endElement: memoizedEndElement, + // }) - const memoizedEndElement = useMemo(() => , []) - const recentSection = useOnchainItemListSection({ - sectionKey: OnchainItemSectionName.RecentSearches, - options: recentlySearchedTokenOptions, - endElement: memoizedEndElement, - }) - const favoriteSection = useOnchainItemListSection({ - sectionKey: OnchainItemSectionName.FavoriteTokens, - options: favoriteTokenOptions, - }) - const trendingSection = useOnchainItemListSection({ - sectionKey: OnchainItemSectionName.TrendingTokens, - options: trendingTokenOptions, - }) - const bridgingSectionTokenOptions: TokenSelectorOption[] = useMemo( - () => (shouldNestBridgingTokens ? [bridgingTokenOptions ?? []] : (bridgingTokenOptions ?? [])), - [bridgingTokenOptions, shouldNestBridgingTokens], - ) + // Error and loading handling + const error = hskPoolsError ? new Error(String(hskPoolsError)) : undefined + const loading = hskPoolsLoading || poolTokensLoading - const bridgingSection = useOnchainItemListSection({ - sectionKey: OnchainItemSectionName.BridgingTokens, - options: bridgingSectionTokenOptions, - }) + const refetch = useCallback(() => { + refetchPools() + }, [refetchPools]) + + // Other sections commented out - 其他部分已注释 + // const portfolioSection = useOnchainItemListSection({ + // sectionKey: OnchainItemSectionName.YourTokens, + // options: portfolioTokenOptions, + // }) + + // const favoriteSection = useOnchainItemListSection({ + // sectionKey: OnchainItemSectionName.FavoriteTokens, + // options: favoriteTokenOptions, + // }) + + // const bridgingSectionTokenOptions: TokenSelectorOption[] = useMemo( + // () => (shouldNestBridgingTokens ? [bridgingTokenOptions ?? []] : (bridgingTokenOptions ?? [])), + // [bridgingTokenOptions, shouldNestBridgingTokens], + // ) + + // const bridgingSection = useOnchainItemListSection({ + // sectionKey: OnchainItemSectionName.BridgingTokens, + // options: bridgingSectionTokenOptions, + // }) const sections = useMemo(() => { - if (isSwapListLoading({ loading, portfolioSection, trendingSection, isTestnetModeEnabled })) { + // Only show pool tokens - 只显示 pools 中的 tokens + // Format matches recent searches - 格式和 recent searches 一致 + if (isSwapListLoading({ loading, portfolioSection: undefined, isTestnetModeEnabled })) { return undefined } - if (isTestnetModeEnabled) { - return [...(suggestedSection ?? []), ...(portfolioSection ?? [])] + const result: OnchainItemSection[] = [] + + // Add pool tokens section if available + if (poolTokensSection && poolTokensSection.length > 0) { + result.push(...poolTokensSection) } - return [ - ...(suggestedSection ?? []), - ...(bridgingSection ?? []), - ...(portfolioSection ?? []), - ...(recentSection ?? []), - // TODO(WEB-3061): Favorited wallets/tokens - // Extension & interface do not support favoriting but has a default list, so we can't rely on empty array check - ...(isMobileApp ? (favoriteSection ?? []) : []), - ...(trendingSection ?? []), - ] - }, [ - loading, - portfolioSection, - trendingSection, - suggestedSection, - bridgingSection, - recentSection, - favoriteSection, - isTestnetModeEnabled, - ]) + // Recent searches section - 已注释 + // if (recentSection && recentSection.length > 0) { + // result.push(...recentSection) + // } + + return result.length > 0 ? result : [] + }, [loading, poolTokensSection, isTestnetModeEnabled]) return useMemo( () => ({ diff --git a/packages/uniswap/src/components/TokenSelector/utils.test.tsx b/packages/uniswap/src/components/TokenSelector/utils.test.tsx index 7e01be40171..5624a8da86f 100644 --- a/packages/uniswap/src/components/TokenSelector/utils.test.tsx +++ b/packages/uniswap/src/components/TokenSelector/utils.test.tsx @@ -2,34 +2,21 @@ import { OnchainItemSectionName } from 'uniswap/src/components/lists/OnchainItem import { isSwapListLoading } from 'uniswap/src/components/TokenSelector/utils' describe(isSwapListLoading, () => { - it('returns true if loading and no sections', () => { + it('returns true if loading and no portfolio section', () => { expect( isSwapListLoading({ loading: true, portfolioSection: undefined, - trendingSection: undefined, isTestnetModeEnabled: false, }), ).toBe(true) }) - it('returns false if loading, testnet mode is on, portfolioSection is defined, and trendingSection is undefined', () => { + it('returns false if loading and portfolioSection is defined', () => { expect( isSwapListLoading({ loading: true, portfolioSection: [{ sectionKey: OnchainItemSectionName.YourTokens, data: [] }], - trendingSection: undefined, - isTestnetModeEnabled: true, - }), - ).toBe(false) - }) - - it('returns false if loading and sections are defined', () => { - expect( - isSwapListLoading({ - loading: true, - portfolioSection: [{ sectionKey: OnchainItemSectionName.YourTokens, data: [] }], - trendingSection: [{ sectionKey: OnchainItemSectionName.TrendingTokens, data: [] }], isTestnetModeEnabled: false, }), ).toBe(false) @@ -38,7 +25,6 @@ describe(isSwapListLoading, () => { isSwapListLoading({ loading: true, portfolioSection: [{ sectionKey: OnchainItemSectionName.YourTokens, data: [] }], - trendingSection: [{ sectionKey: OnchainItemSectionName.TrendingTokens, data: [] }], isTestnetModeEnabled: true, }), ).toBe(false) diff --git a/packages/uniswap/src/components/TokenSelector/utils.tsx b/packages/uniswap/src/components/TokenSelector/utils.tsx index 9852b559a18..69ecddddf6d 100644 --- a/packages/uniswap/src/components/TokenSelector/utils.tsx +++ b/packages/uniswap/src/components/TokenSelector/utils.tsx @@ -123,16 +123,13 @@ export function isTokenOptionArray(option: OnchainItemListOption): option is Tok export function isSwapListLoading({ loading, portfolioSection, - trendingSection, isTestnetModeEnabled, }: { loading: boolean portfolioSection: OnchainItemSection[] | undefined - trendingSection: OnchainItemSection[] | undefined isTestnetModeEnabled: boolean }): boolean { - // the trending section is not shown on testnet - return loading && (isTestnetModeEnabled ? !portfolioSection : !portfolioSection || !trendingSection) + return loading && !portfolioSection } export function flowToModalName(flow: TokenSelectorFlow): ModalNameType | undefined { diff --git a/packages/uniswap/src/components/lists/OnchainItemList/OnchainItemList.web.tsx b/packages/uniswap/src/components/lists/OnchainItemList/OnchainItemList.web.tsx index 5fc18b78bae..29b6a25fb69 100644 --- a/packages/uniswap/src/components/lists/OnchainItemList/OnchainItemList.web.tsx +++ b/packages/uniswap/src/components/lists/OnchainItemList/OnchainItemList.web.tsx @@ -78,8 +78,16 @@ export function OnchainItemList({ }, [sectionListRef, sections]) const items = useMemo(() => { + if (!sections || sections.length === 0) { + return [] + } + let rowIndex = 0 return sections.reduce((acc: OnchainItemListData[], section) => { + if (!section || !section.data) { + return acc + } + if (section.sectionKey !== OnchainItemSectionName.SuggestedTokens) { const sectionInfo: ListSectionRowInfo = { section: { diff --git a/packages/uniswap/src/components/lists/OnchainItemList/types.ts b/packages/uniswap/src/components/lists/OnchainItemList/types.ts index 6e1babdbe7b..9619d1ec4de 100644 --- a/packages/uniswap/src/components/lists/OnchainItemList/types.ts +++ b/packages/uniswap/src/components/lists/OnchainItemList/types.ts @@ -10,6 +10,7 @@ export enum OnchainItemSectionName { SuggestedTokens = 'suggestedTokens', BridgingTokens = 'bridgingTokens', OtherChainsTokens = 'otherNetworksTokens', + PoolTokens = 'poolTokens', // Tokens from pools Tokens = 'tokens', Pools = 'pools', diff --git a/packages/uniswap/src/components/lists/SectionHeader.tsx b/packages/uniswap/src/components/lists/SectionHeader.tsx index e1e9b39d564..e8486c59e48 100644 --- a/packages/uniswap/src/components/lists/SectionHeader.tsx +++ b/packages/uniswap/src/components/lists/SectionHeader.tsx @@ -74,6 +74,8 @@ function useSectionTitle(section: OnchainItemSectionName): string { return t('tokens.selector.section.trending') case OnchainItemSectionName.RecentSearches: return t('tokens.selector.section.recent') + case OnchainItemSectionName.PoolTokens: + return t('tokens.selector.section.poolTokens') case OnchainItemSectionName.FavoriteTokens: return t('tokens.selector.section.favorite') case OnchainItemSectionName.SearchResults: @@ -113,6 +115,8 @@ function getSectionIcon(section: OnchainItemSectionName): JSX.Element | null { return case OnchainItemSectionName.RecentSearches: return + case OnchainItemSectionName.PoolTokens: + return case OnchainItemSectionName.SearchResults: return case OnchainItemSectionName.FavoriteTokens: diff --git a/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts b/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts index b22fea5cbe0..b484b448205 100644 --- a/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts +++ b/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts @@ -39,7 +39,10 @@ if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { console.log('[TradingApiClient] API Path Prefix:', tradingApiVersionPrefix) console.log('[TradingApiClient] Quote URL Path:', debugQuoteUrlPath) console.log('[TradingApiClient] Full Quote URL:', `${quoteApiBaseUrl}${debugQuoteUrlPath}`) - console.log('[TradingApiClient] Trading API Key:', config.tradingApiKey ? '***' : '(empty - no API key header will be sent)') + console.log( + '[TradingApiClient] Trading API Key:', + config.tradingApiKey ? '***' : '(empty - no API key header will be sent)', + ) console.log('[TradingApiClient] Quote API Headers:', quoteApiHeaders) } @@ -143,65 +146,30 @@ const quoteUrlPath = tradingApiVersionPrefix ? `${tradingApiVersionPrefix}/${TRADING_API_PATHS.quote}` : `/${TRADING_API_PATHS.quote}` -// Map chain IDs to internal service format -// Internal service expects "hsk" or "hsktest" instead of numeric chain IDs -const mapChainIdToInternalFormat = (chainId: number): string | null => { - // HashKey Chain Mainnet: 177 -> "hsk" - if (chainId === 177) { - return 'hsk' - } - // HashKey Chain Testnet: 133 -> "hsktest" - if (chainId === 133) { - return 'hsktest' - } - // Other chain IDs are not supported by internal service - return null -} - // Transform request for internal quote API -// Only converts chain IDs to internal service format, keeps all other fields unchanged +// Keep all fields unchanged - API expects numeric chain IDs const transformQuoteRequest = async (request: { url: string headers?: HeadersInit params: QuoteRequest & { isUSDQuote?: boolean } }) => { const { params } = request - - // Convert chain IDs to internal service format - const tokenInChainIdInternal = mapChainIdToInternalFormat(params.tokenInChainId) - const tokenOutChainIdInternal = mapChainIdToInternalFormat(params.tokenOutChainId) - - // If chain IDs are not supported, log warning and use original values - // (This will likely result in 400 error, but allows debugging) - if (!tokenInChainIdInternal || !tokenOutChainIdInternal) { - if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { - console.warn('[TradingApiClient] Unsupported chain IDs:', { - tokenInChainId: params.tokenInChainId, - tokenOutChainId: params.tokenOutChainId, - message: 'Internal service only supports HashKey Chain (177) and HashKey Testnet (133)', - }) - } - } - - // Keep all original fields unchanged, only update chain IDs + + // Ensure chain IDs are numbers (not strings) + // API expects numeric chain IDs for HashKey chains (177 and 133) const transformedParams = { ...params, - // Override chain IDs with internal format if available, otherwise keep original - tokenInChainId: tokenInChainIdInternal ?? params.tokenInChainId, - tokenOutChainId: tokenOutChainIdInternal ?? params.tokenOutChainId, + tokenInChainId: typeof params.tokenInChainId === 'string' ? parseInt(params.tokenInChainId, 10) : params.tokenInChainId, + tokenOutChainId: typeof params.tokenOutChainId === 'string' ? parseInt(params.tokenOutChainId, 10) : params.tokenOutChainId, } if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { - console.log('[TradingApiClient] Transformed request:', { - original: { - tokenInChainId: params.tokenInChainId, - tokenOutChainId: params.tokenOutChainId, - }, - transformed: { - tokenInChainId: transformedParams.tokenInChainId, - tokenOutChainId: transformedParams.tokenOutChainId, - hasGasStrategies: !!transformedParams.gasStrategies, - }, + console.log('[TradingApiClient] Request params:', { + tokenInChainId: transformedParams.tokenInChainId, + tokenOutChainId: transformedParams.tokenOutChainId, + tokenInChainIdType: typeof transformedParams.tokenInChainId, + tokenOutChainIdType: typeof transformedParams.tokenOutChainId, + hasGasStrategies: !!transformedParams.gasStrategies, }) } diff --git a/packages/uniswap/src/data/cache.ts b/packages/uniswap/src/data/cache.ts index 97b9116ce80..1e9a98b1007 100644 --- a/packages/uniswap/src/data/cache.ts +++ b/packages/uniswap/src/data/cache.ts @@ -35,9 +35,13 @@ export function setupSharedApolloCache(): InMemoryCache { // simply use chain / address pair as id instead for tokens token: { read(_, { args, toReference }): Reference | undefined { + // Don't create reference if chain is undefined (e.g., for unsupported chains like HashKey) + if (!args?.chain) { + return undefined + } return toReference({ __typename: 'Token', - chain: args?.chain, + chain: args.chain, address: normalizeTokenAddressForCache(args?.address), }) }, diff --git a/packages/uniswap/src/features/dataApi/tokenProjects/tokenProjects.ts b/packages/uniswap/src/features/dataApi/tokenProjects/tokenProjects.ts index 71489e683aa..b80690b6951 100644 --- a/packages/uniswap/src/features/dataApi/tokenProjects/tokenProjects.ts +++ b/packages/uniswap/src/features/dataApi/tokenProjects/tokenProjects.ts @@ -1,8 +1,10 @@ import { GqlResult, GraphQLApi } from '@universe/api' import { useCallback, useMemo } from 'react' +import { isBackendSupportedChainId } from 'uniswap/src/features/chains/utils' import { tokenProjectToCurrencyInfos } from 'uniswap/src/features/dataApi/tokenProjects/utils/tokenProjectToCurrencyInfos' import { CurrencyInfo } from 'uniswap/src/features/dataApi/types' import { currencyIdToContractInput } from 'uniswap/src/features/dataApi/utils/currencyIdToContractInput' +import { currencyIdToChain } from 'uniswap/src/utils/currencyId' import { CurrencyId } from 'uniswap/src/types/currency' /** @@ -12,9 +14,21 @@ import { CurrencyId } from 'uniswap/src/types/currency' export function useTokenProjects(currencyIds: CurrencyId[]): GqlResult { const contracts = useMemo(() => currencyIds.map((id) => currencyIdToContractInput(id)), [currencyIds]) + // Skip GraphQL query for chains that don't support backend (like HashKey) + const shouldSkip = useMemo(() => { + if (currencyIds.length === 0) { + return true + } + // Check if all currencyIds are from unsupported chains + return currencyIds.every((id) => { + const chainId = currencyIdToChain(id) + return chainId && !isBackendSupportedChainId(chainId) + }) + }, [currencyIds]) + const { data, loading, error, refetch } = GraphQLApi.useTokenProjectsQuery({ variables: { contracts }, - skip: currencyIds.length === 0, + skip: shouldSkip, }) const formattedData = useMemo(() => { diff --git a/packages/uniswap/src/features/dataApi/utils/buildCurrency.ts b/packages/uniswap/src/features/dataApi/utils/buildCurrency.ts index b211d178107..8140d097ebe 100644 --- a/packages/uniswap/src/features/dataApi/utils/buildCurrency.ts +++ b/packages/uniswap/src/features/dataApi/utils/buildCurrency.ts @@ -101,6 +101,8 @@ export function buildCurrency(args: BuildCurrencyParams): Token | NativeCurrency } const CURRENCY_INFO_CACHE = new Map() +// Global cache for CurrencyInfo by currencyId (for unsupported chains like HashKey) +const CURRENCY_INFO_BY_ID_CACHE = new Map() export function buildCurrencyInfo(args: CurrencyInfo): CurrencyInfo { const cacheKey = JSON.stringify(sortKeysRecursively(args)) @@ -113,5 +115,15 @@ export function buildCurrencyInfo(args: CurrencyInfo): CurrencyInfo { } CURRENCY_INFO_CACHE.set(cacheKey, args) + // Also cache by currencyId for quick lookup + CURRENCY_INFO_BY_ID_CACHE.set(args.currencyId, args) return args } + +/** + * Get CurrencyInfo from cache by currencyId + * Useful for unsupported chains where GraphQL queries don't work + */ +export function getCurrencyInfoFromCache(currencyId: string): CurrencyInfo | undefined { + return CURRENCY_INFO_BY_ID_CACHE.get(currencyId) +} diff --git a/packages/uniswap/src/features/tokens/useCurrencyInfo.ts b/packages/uniswap/src/features/tokens/useCurrencyInfo.ts index f1f424a5108..77e75c803ce 100644 --- a/packages/uniswap/src/features/tokens/useCurrencyInfo.ts +++ b/packages/uniswap/src/features/tokens/useCurrencyInfo.ts @@ -1,13 +1,16 @@ import { GraphQLApi } from '@universe/api' import { useMemo } from 'react' import { getCommonBase } from 'uniswap/src/constants/routing' +import { isBackendSupportedChainId } from 'uniswap/src/features/chains/utils' import { UniverseChainId } from 'uniswap/src/features/chains/types' import { CurrencyInfo } from 'uniswap/src/features/dataApi/types' +import { getCurrencyInfoFromCache } from 'uniswap/src/features/dataApi/utils/buildCurrency' import { currencyIdToContractInput } from 'uniswap/src/features/dataApi/utils/currencyIdToContractInput' import { gqlTokenToCurrencyInfo } from 'uniswap/src/features/dataApi/utils/gqlTokenToCurrencyInfo' import { buildNativeCurrencyId, buildWrappedNativeCurrencyId, + currencyId, currencyIdToAddress, currencyIdToChain, } from 'uniswap/src/utils/currencyId' @@ -16,9 +19,12 @@ function useCurrencyInfoQuery( _currencyId?: string, options?: { refetch?: boolean; skip?: boolean }, ): { currencyInfo: Maybe; loading: boolean; error?: Error } { + const chainId = useMemo(() => (_currencyId ? currencyIdToChain(_currencyId) : undefined), [_currencyId]) + const isUnsupportedChain = chainId && !isBackendSupportedChainId(chainId) + const queryResult = GraphQLApi.useTokenQuery({ variables: currencyIdToContractInput(_currencyId ?? ''), - skip: !_currencyId || options?.skip, + skip: !_currencyId || options?.skip || isUnsupportedChain, fetchPolicy: options?.refetch ? 'cache-and-network' : 'cache-first', }) @@ -27,15 +33,42 @@ function useCurrencyInfoQuery( return undefined } - const chainId = currencyIdToChain(_currencyId) + const chainIdFromId = currencyIdToChain(_currencyId) let address: Address | undefined try { address = currencyIdToAddress(_currencyId) } catch (_error) { return undefined } - if (chainId && address) { - const commonBase = getCommonBase(chainId, address) + + if (!chainIdFromId || !address) { + return undefined + } + + // For unsupported chains (like HashKey), try to get CurrencyInfo from cache first + if (isUnsupportedChain) { + // Try to get token info from common base first + const commonBase = getCommonBase(chainIdFromId, address) + if (commonBase) { + const copyCommonBase = { ...commonBase } + copyCommonBase.currencyId = _currencyId + return copyCommonBase + } + + // Try to get from cache (e.g., from pools data) + const cachedCurrencyInfo = getCurrencyInfoFromCache(_currencyId) + if (cachedCurrencyInfo) { + return cachedCurrencyInfo + } + + // If no cache, return undefined + // The CurrencyInfo should be cached when token is selected from pools + return undefined + } + + // For supported chains, use GraphQL query result + if (chainIdFromId && address) { + const commonBase = getCommonBase(chainIdFromId, address) if (commonBase) { // Creating new object to avoid error "Cannot assign to read only property" const copyCommonBase = { ...commonBase } @@ -50,11 +83,11 @@ function useCurrencyInfoQuery( } return queryResult.data?.token && gqlTokenToCurrencyInfo(queryResult.data.token) - }, [_currencyId, queryResult.data?.token]) + }, [_currencyId, queryResult.data?.token, isUnsupportedChain]) return { currencyInfo, - loading: queryResult.loading, + loading: isUnsupportedChain ? false : queryResult.loading, error: queryResult.error, } } diff --git a/packages/uniswap/src/features/transactions/components/settings/TransactionSettings.tsx b/packages/uniswap/src/features/transactions/components/settings/TransactionSettings.tsx index 26c55cb84b7..3233a345f37 100644 --- a/packages/uniswap/src/features/transactions/components/settings/TransactionSettings.tsx +++ b/packages/uniswap/src/features/transactions/components/settings/TransactionSettings.tsx @@ -128,7 +128,16 @@ export function TransactionSettings({ return ( <> - + {/* Swap text button - only show when absolutely positioned */} {position === 'absolute' && ( @@ -146,7 +155,12 @@ export function TransactionSettings({ > - + {CustomSettingsButton ?? ( SLIPPAGE_CRITICAL_TOLERANCE ? SettingsWarning : SettingsCustom + customSlippageTolerance && customSlippageTolerance > SLIPPAGE_CRITICAL_TOLERANCE + ? SettingsWarning + : SettingsCustom return { backgroundColor: iconBackgroundColor, contentColor: fillColor, IconComponent: SettingsIconComponent } }, [customSlippageTolerance, iconColor, autoSlippageTolerance]) diff --git a/packages/uniswap/src/features/transactions/hooks/usePollingIntervalByChain.ts b/packages/uniswap/src/features/transactions/hooks/usePollingIntervalByChain.ts index ad0350be0c1..b65982d6f37 100644 --- a/packages/uniswap/src/features/transactions/hooks/usePollingIntervalByChain.ts +++ b/packages/uniswap/src/features/transactions/hooks/usePollingIntervalByChain.ts @@ -4,7 +4,7 @@ import { isMainnetChainId } from 'uniswap/src/features/chains/utils' import { ONE_SECOND_MS } from 'utilities/src/time/time' export const AVERAGE_L1_BLOCK_TIME_MS = 12 * ONE_SECOND_MS -export const AVERAGE_L2_BLOCK_TIME_MS = 3 * ONE_SECOND_MS +export const AVERAGE_L2_BLOCK_TIME_MS = 10 * ONE_SECOND_MS export function usePollingIntervalByChain(chainId?: UniverseChainId): number { const averageL1BlockTimeMs = useDynamicConfigValue({ diff --git a/packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx b/packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx index dfdb5f8cf3a..5e1569c3a14 100644 --- a/packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx +++ b/packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx @@ -1,23 +1,22 @@ import { useEffect, useMemo, useState } from 'react' -import { Flex, Text, TouchableArea } from 'ui/src' +import { Flex, styled, Text, TouchableArea } from 'ui/src' import { Chevron } from 'ui/src/components/icons/Chevron' -import { X } from 'ui/src/components/icons/X' import { InfoCircle } from 'ui/src/components/icons/InfoCircle' -import { Modal } from 'uniswap/src/components/modals/Modal' +import { X } from 'ui/src/components/icons/X' import { AdaptiveWebModal } from 'ui/src/components/modal/AdaptiveWebModal' import { CurrencyLogo } from 'uniswap/src/components/CurrencyLogo/CurrencyLogo' +import { Modal } from 'uniswap/src/components/modals/Modal' import type { CurrencyInfo } from 'uniswap/src/features/dataApi/types' import { useLocalizationContext } from 'uniswap/src/features/language/LocalizationContext' +import { ModalName } from 'uniswap/src/features/telemetry/constants' import { useUSDCValue } from 'uniswap/src/features/transactions/hooks/useUSDCPrice' +import { useSwapFormScreenStore } from 'uniswap/src/features/transactions/swap/form/stores/swapFormScreenStore/useSwapFormScreenStore' +import { usePriceUXEnabled } from 'uniswap/src/features/transactions/swap/hooks/usePriceUXEnabled' import type { DerivedSwapInfo } from 'uniswap/src/features/transactions/swap/types/derivedSwapInfo' import { getTradeAmounts } from 'uniswap/src/features/transactions/swap/utils/getTradeAmounts' -import { usePriceUXEnabled } from 'uniswap/src/features/transactions/swap/hooks/usePriceUXEnabled' import { CurrencyField } from 'uniswap/src/types/currency' import { NumberType } from 'utilities/src/format/types' -import { styled } from 'ui/src' import { isWebPlatform } from 'utilities/src/platform' -import { ModalName } from 'uniswap/src/features/telemetry/constants' -import { useSwapFormScreenStore } from 'uniswap/src/features/transactions/swap/form/stores/swapFormScreenStore/useSwapFormScreenStore' const ModalContainer = styled(Flex, { width: 440, @@ -150,7 +149,8 @@ export function SwapConfirmationModal({ const formCurrencies = useSwapFormScreenStore((s) => s.currencies) const sellCurrencyInfo = formCurrencies[CurrencyField.INPUT] ?? undefined // Use buy currency from form if available, otherwise fallback to derivedSwapInfo - const buyCurrencyInfo = formCurrencies[CurrencyField.OUTPUT] ?? derivedSwapInfo.currencies[CurrencyField.OUTPUT] ?? undefined + const buyCurrencyInfo = + formCurrencies[CurrencyField.OUTPUT] ?? derivedSwapInfo.currencies[CurrencyField.OUTPUT] ?? undefined // TokenRow component interface TokenRowProps { @@ -252,121 +252,137 @@ export function SwapConfirmationModal({ overflow: 'hidden', }} > -
- - You're swapping - - - - +
+ + You're swapping + + + + + + +
+ + + + {/* Sell Token (Input) */} + + + {/* Arrow */} + + + -
-
- - - - {/* Sell Token (Input) */} - - - {/* Arrow */} - + + + {/* Buy Token (Output) */} + + + + {/* Fees Section */} + + + + setIsExpanded((prev) => !prev)} + > + + {isExpanded ? 'Show less' : 'Show more'} + - - - {/* Buy Token (Output) */} - +
+ - {/* Fees Section */} - - - - setIsExpanded((prev) => !prev)} - style={{ - width: 98, - height: 20, - borderRadius: 8, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center', - gap: 8, - }} - > + + + - {isExpanded ? 'Show less' : 'Show more'} + Fee - - - - - + + + + Free + - - - - - Fee - - - + + - Free + Network cost + - - - - - Network cost - - - - - - $0.02 - - - + + + $0.02 + + - {isExpanded && ( - <> - - - - Rate - - + {isExpanded && ( + <> + + - 1 ETH = 3218.57 USDC ($3,218.57) + Rate + + 1 ETH = 3218.57 USDC ($3,218.57) + + - - - - Max slippage - - - + + - Auto 0.67% + Max slippage + + + Auto 0.67% + + - - - - Order routing - - - + + - HSK API + Order routing + + + HSK API + + - - - - Price impact - - - + + - -0.05% + Price impact + - - )} - - + + -0.05% + +
+ + )} +
+ - {/* Swap Button */} - - + + - - Swap Tokens - - - - - + Swap Tokens + + +
+ + ) return ( @@ -602,7 +601,6 @@ export function SwapConfirmationModal({ {isWebPlatform ? ( {modalContent} @@ -623,7 +622,6 @@ export function SwapConfirmationModal({ {modalContent} @@ -641,4 +640,3 @@ export function SwapConfirmationModal({ ) } - diff --git a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx index 4f3c4a313b1..e7865ec5661 100644 --- a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx +++ b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx @@ -1,17 +1,20 @@ import { useState } from 'react' -import { Button, Flex, styled, useIsShortMobileDevice } from 'ui/src' import { useTranslation } from 'react-i18next' +import { Button, Flex, styled, useIsShortMobileDevice } from 'ui/src' +import { useConnectionStatus } from 'uniswap/src/features/accounts/store/hooks' +import { useIsWebFORNudgeEnabled } from 'uniswap/src/features/providers/webForNudgeProvider' import { useTransactionModalContext } from 'uniswap/src/features/transactions/components/TransactionModal/TransactionModalContext' +import { SwapConfirmationModal } from 'uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal' import { useIsSwapButtonDisabled } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsSwapButtonDisabled' +import { useIsMissingPlatformWallet } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsMissingPlatformWallet' import { useIsTradeIndicative } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsTradeIndicative' import { useOnReviewPress } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useOnReviewPress' import { useSwapFormButtonColors } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useSwapFormButtonColors' import { useSwapFormButtonText } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useSwapFormButtonText' import { SwapFormButtonTrace } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButtonTrace' -import { SwapConfirmationModal } from 'uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal' import { useSwapFormStoreDerivedSwapInfo } from 'uniswap/src/features/transactions/swap/stores/swapFormStore/useSwapFormStore' -import { useIsWebFORNudgeEnabled } from 'uniswap/src/features/providers/webForNudgeProvider' import { TestID } from 'uniswap/src/test/fixtures/testIDs' +import { isWebPlatform } from 'utilities/src/platform' import { useEvent } from 'utilities/src/react/hooks' export const SWAP_BUTTON_TEXT_VARIANT = 'buttonLabel1' @@ -23,7 +26,6 @@ const WhiteButtonText = styled(Button.Text, { }, }) - const GradientWrapper = styled(Flex, { borderRadius: 12, height: 60, @@ -43,6 +45,21 @@ const GradientWrapper = styled(Flex, { }, }) +// Global function to connect wallet - can be set by platform-specific code +// Type declaration for the global connect wallet function +declare global { + // eslint-disable-next-line no-var + var __uniswapConnectWallet: (() => void) | undefined +} + +const getConnectWalletFunction = (): (() => void) | undefined => { + // Check if we're on web platform and if a connect function is available + if (typeof window !== 'undefined' && typeof window.__uniswapConnectWallet === 'function') { + return window.__uniswapConnectWallet + } + return undefined +} + // TODO(SWAP-573): Co-locate button action/color/text logic instead of separating the very-coupled UI state export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Element { const isShortMobileDevice = useIsShortMobileDevice() @@ -67,11 +84,25 @@ export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Ele const { t } = useTranslation() const swapTokensText = t('empty.swap.button.text') + // Check connection status + const { isDisconnected } = useConnectionStatus() + const { chainId } = useSwapFormStoreDerivedSwapInfo((s) => ({ + chainId: s.chainId, + })) + const isMissingPlatformWallet = useIsMissingPlatformWallet(chainId) + const connectWallet = getConnectWalletFunction() + const handleButtonPress = useEvent(() => { + // If wallet is disconnected or missing, try to connect + if ((isDisconnected || isMissingPlatformWallet) && connectWallet) { + connectWallet() + return + } + // Show confirmation modal when button text is "Swap Tokens" (either from WebFORNudge or other conditions) // Check both the flag and the actual button text to be safe const shouldShowModal = (isWebFORNudgeEnabled || buttonText === swapTokensText) && !swapRedirectCallback - + // Debug: log the values to help troubleshoot if (process.env.NODE_ENV === 'development') { console.log('SwapFormButton press:', { @@ -82,7 +113,7 @@ export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Ele swapRedirectCallback, }) } - + if (shouldShowModal) { setIsSwapConfirmationModalOpen(true) } else { @@ -107,14 +138,10 @@ export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Ele @@ -134,9 +165,9 @@ export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Ele
) diff --git a/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormCurrencyInputPanel.tsx b/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormCurrencyInputPanel.tsx index 48dc3d7483e..380e98d7056 100644 --- a/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormCurrencyInputPanel.tsx +++ b/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormCurrencyInputPanel.tsx @@ -59,7 +59,8 @@ export function SwapFormCurrencyInputPanel(): JSX.Element { onToggleIsFiatMode: s.onToggleIsFiatMode, })) - const focusedStyles = useCurrencyInputFocusedStyle(focusOnCurrencyField === CurrencyField.INPUT) + const isFocused = focusOnCurrencyField === CurrencyField.INPUT + const focusedStyles = useCurrencyInputFocusedStyle(isFocused) return ( @@ -71,6 +72,11 @@ export function SwapFormCurrencyInputPanel(): JSX.Element { overflow="hidden" pb={currencies[CurrencyField.INPUT] ? '$spacing4' : '$none'} {...focusedStyles} + borderColor={isFocused ? focusedStyles.borderColor : '$surface3'} + hoverStyle={{ + ...focusedStyles.hoverStyle, + borderColor: '$surface3Hovered', + }} > - {/* Original Swap+Settings button moved here to occupy space within the border */} {!hideSettings && ( <> @@ -114,7 +112,13 @@ function SwapFormContent({ Swap {/* Settings button */} - + {/* Border below Swap+Settings with 8px left/right extension */} diff --git a/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenDetails.web.tsx b/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenDetails.web.tsx index 19c57951dfd..9f29e18a0f6 100644 --- a/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenDetails.web.tsx +++ b/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenDetails.web.tsx @@ -1,17 +1,17 @@ import { Accordion, Flex } from 'ui/src' import { SwapFormButton } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton' -import { ExpandableRows } from 'uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/ExpandableRows' -import { SwapFormScreenFooter } from 'uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenFooter/SwapFormScreenFooter' +// import { ExpandableRows } from 'uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/ExpandableRows' +// import { SwapFormScreenFooter } from 'uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenFooter/SwapFormScreenFooter' import { SwapFormWarningModals } from 'uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormWarningModals/SwapFormWarningModals' import { useSwapFormScreenStore } from 'uniswap/src/features/transactions/swap/form/stores/swapFormScreenStore/useSwapFormScreenStore' import { SwapFormWarningStoreContextProvider } from 'uniswap/src/features/transactions/swap/form/stores/swapFormWarningStore/SwapFormWarningStoreContextProvider' -import { usePriceUXEnabled } from 'uniswap/src/features/transactions/swap/hooks/usePriceUXEnabled' +// import { usePriceUXEnabled } from 'uniswap/src/features/transactions/swap/hooks/usePriceUXEnabled' export function SwapFormScreenDetails(): JSX.Element { - const isPriceUXEnabled = usePriceUXEnabled() - const { tokenColor, showFooter } = useSwapFormScreenStore((state) => ({ + // const isPriceUXEnabled = usePriceUXEnabled() + const { tokenColor } = useSwapFormScreenStore((state) => ({ tokenColor: state.tokenColor, - showFooter: state.showFooter, + // showFooter: state.showFooter, })) return ( @@ -24,15 +24,17 @@ export function SwapFormScreenDetails(): JSX.Element { } `} - + - + - + {/* SwapFormScreenFooter removed - footer content (gas info, warnings) are hidden to prevent space changes */} + {/* */} - {showFooter && !isPriceUXEnabled ? : null} + {/* ExpandableRows removed - fee, network cost, etc. details are hidden before modal opens */} + {/* {showFooter && !isPriceUXEnabled ? : null} */} ) diff --git a/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenFooter/GasAndWarningRows/GasAndWarningRows.web.tsx b/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenFooter/GasAndWarningRows/GasAndWarningRows.web.tsx index e75566903af..bdd03334e19 100644 --- a/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenFooter/GasAndWarningRows/GasAndWarningRows.web.tsx +++ b/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenFooter/GasAndWarningRows/GasAndWarningRows.web.tsx @@ -3,7 +3,7 @@ import { WarningLabel } from 'uniswap/src/components/modals/WarningModal/types' import { isSVMChain } from 'uniswap/src/features/platforms/utils/chains' import { InsufficientNativeTokenWarning } from 'uniswap/src/features/transactions/components/InsufficientNativeTokenWarning/InsufficientNativeTokenWarning' import { BlockedAddressWarning } from 'uniswap/src/features/transactions/modals/BlockedAddressWarning' -import { TradeInfoRow } from 'uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenFooter/GasAndWarningRows/TradeInfoRow/TradeInfoRow' +// import { TradeInfoRow } from 'uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenFooter/GasAndWarningRows/TradeInfoRow/TradeInfoRow' import { useDebouncedGasInfo } from 'uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenFooter/GasAndWarningRows/useDebouncedGasInfo' import { useParsedSwapWarnings } from 'uniswap/src/features/transactions/swap/hooks/useSwapWarnings/useSwapWarnings' import { useSwapFormStoreDerivedSwapInfo } from 'uniswap/src/features/transactions/swap/stores/swapFormStore/useSwapFormStore' @@ -49,11 +49,12 @@ export function GasAndWarningRows(): JSX.Element { /> )} - {!insufficientGasFundsWarning && ( + {/* TradeInfoRow removed - rate display and accordion trigger are hidden */} + {/* {!insufficientGasFundsWarning && ( - )} + )} */} diff --git a/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenFooter/GasAndWarningRows/TradeInfoRow/TradeInfoRow.tsx b/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenFooter/GasAndWarningRows/TradeInfoRow/TradeInfoRow.tsx index 2938946f4f3..31246eda617 100644 --- a/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenFooter/GasAndWarningRows/TradeInfoRow/TradeInfoRow.tsx +++ b/packages/uniswap/src/features/transactions/swap/form/SwapFormScreen/SwapFormScreenDetails/SwapFormScreenFooter/GasAndWarningRows/TradeInfoRow/TradeInfoRow.tsx @@ -43,55 +43,7 @@ export function TradeInfoRow({ gasInfo, warning }: { gasInfo: GasInfo; warning?: const outputChainId = currencies.output?.currency.chainId const showCanonicalBridge = isWebApp && warning?.type === WarningLabel.NoQuotesFound && inputChainId !== outputChainId - return ( - - - {debouncedTrade && !warning && ( - - )} - - {warning && ( - - - - - {warning.title} - - - - )} - - - {showCanonicalBridge ? ( - - ) : debouncedTrade ? ( - - {({ open }: { open: boolean }) => ( - - - )} - - ) : ( - - )} - - ) + // TradeInfoRow removed - rate display and accordion trigger are hidden + // Only show gas info without rate and accordion + return } diff --git a/packages/uniswap/src/features/transactions/swap/form/hooks/useOnSelectCurrency.ts b/packages/uniswap/src/features/transactions/swap/form/hooks/useOnSelectCurrency.ts index 1fe6f228c5a..3bcffb5dddc 100644 --- a/packages/uniswap/src/features/transactions/swap/form/hooks/useOnSelectCurrency.ts +++ b/packages/uniswap/src/features/transactions/swap/form/hooks/useOnSelectCurrency.ts @@ -153,6 +153,25 @@ export function useOnSelectCurrency({ outputCurrency: CurrencyField.OUTPUT === field ? currency : todoFixMeOtherCurrency?.currency, } + // Console log selected coin information + if (typeof window !== 'undefined') { + console.log('[Token Selected]', { + field: field === CurrencyField.INPUT ? 'INPUT' : 'OUTPUT', + currency: { + symbol: currency.symbol, + name: currency.name, + chainId: currency.chainId, + address: currencyAddress(currency), + decimals: currency.decimals, + isNative: currency.isNative, + currencyId: currencyId(currency), + }, + allowCrossChainPair, + isPreselectedAsset, + isBridgePair, + }) + } + onSelect?.() updateSwapForm(newState) maybeLogFirstSwapAction(traceRef.current) diff --git a/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/buildQuoteRequest.ts b/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/buildQuoteRequest.ts index d93bbd29d59..2a276d32bd6 100644 --- a/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/buildQuoteRequest.ts +++ b/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/buildQuoteRequest.ts @@ -121,14 +121,31 @@ export interface ParsedTradeInput { export function parseTradeInputForTradingApiQuote(input: UseTradeArgs): ParsedTradeInput { const { currencyIn, currencyOut, requestTradeType } = parseQuoteCurrencies(input) + const tokenInChainId = toTradingApiSupportedChainId(currencyIn?.chainId) + const tokenOutChainId = toTradingApiSupportedChainId(currencyOut?.chainId) + + // Debug log + if (typeof window !== 'undefined') { + console.log('[parseTradeInputForTradingApiQuote] Parsing input:', { + currencyIn: currencyIn?.symbol, + currencyOut: currencyOut?.symbol, + currencyInChainId: currencyIn?.chainId, + currencyOutChainId: currencyOut?.chainId, + tokenInChainId, + tokenOutChainId, + amountSpecified: input.amountSpecified?.toExact(), + hasAmountSpecified: !!input.amountSpecified, + }) + } + return { currencyIn, currencyOut, amount: input.amountSpecified, requestTradeType, activeAccountAddress: input.account?.address, - tokenInChainId: toTradingApiSupportedChainId(currencyIn?.chainId), - tokenOutChainId: toTradingApiSupportedChainId(currencyOut?.chainId), + tokenInChainId, + tokenOutChainId, tokenInAddress: getTokenAddressForApi(currencyIn), tokenOutAddress: getTokenAddressForApi(currencyOut), generatePermitAsTransaction: input.generatePermitAsTransaction, @@ -140,17 +157,32 @@ export function parseTradeInputForTradingApiQuote(input: UseTradeArgs): ParsedTr // Takes parsed input and returns validated input or undefined export function validateParsedInput(input: ParsedTradeInput): ValidatedTradeInput | undefined { // Check all conditions that would make the input invalid + // Reject zero amount - quote should not be fetched when amount is 0 if ( !input.tokenInChainId || !input.tokenOutChainId || !input.tokenInAddress || !input.tokenOutAddress || !input.amount || + isZeroAmount(input.amount) || !input.currencyIn || !input.currencyOut || - isZeroAmount(input.amount) || areCurrenciesEqual(input.currencyIn, input.currencyOut) ) { + // Debug log to understand why validation fails + if (typeof window !== 'undefined') { + console.log('[validateParsedInput] Validation failed:', { + tokenInChainId: input.tokenInChainId, + tokenOutChainId: input.tokenOutChainId, + tokenInAddress: input.tokenInAddress, + tokenOutAddress: input.tokenOutAddress, + hasAmount: !!input.amount, + amountValue: input.amount?.toExact(), + currencyIn: input.currencyIn?.symbol, + currencyOut: input.currencyOut?.symbol, + areCurrenciesEqual: areCurrenciesEqual(input.currencyIn, input.currencyOut), + }) + } return undefined } diff --git a/packages/uniswap/src/features/transactions/swap/stores/swapFormStore/hooks/useDefaultSwapFormState.ts b/packages/uniswap/src/features/transactions/swap/stores/swapFormStore/hooks/useDefaultSwapFormState.ts index 4705b5cebcf..a894685f264 100644 --- a/packages/uniswap/src/features/transactions/swap/stores/swapFormStore/hooks/useDefaultSwapFormState.ts +++ b/packages/uniswap/src/features/transactions/swap/stores/swapFormStore/hooks/useDefaultSwapFormState.ts @@ -19,7 +19,7 @@ export const getDefaultState = (defaultChainId: UniverseChainId): Readonly): TradingApi.ChainId | undefined { - if (!chainId || !isTradingApiSupportedChainId(chainId)) { + if (!chainId) { + return undefined + } + + // HashKey chains are supported by the Trading API (even if not in TradingApi.ChainId enum) + // The backend will handle the conversion to internal format ("hsk" or "hsktest") + if (chainId === 177 || chainId === 133) { + return chainId as TradingApi.ChainId + } + + if (!isTradingApiSupportedChainId(chainId)) { return undefined } return chainId @@ -482,29 +492,23 @@ export function createGetQuoteRoutingParams(ctx: { const { isUSDQuote } = input // for USD quotes, we avoid routing through UniswapX // hooksOptions should not be sent for USD quotes + // HSKSwap only supports V3 if (isUSDQuote) { return { - protocols: [TradingApi.ProtocolItems.V2, TradingApi.ProtocolItems.V3, TradingApi.ProtocolItems.V4], + protocols: [TradingApi.ProtocolItems.V3], } } const protocols = ctx.getProtocols() - let finalProtocols = [...protocols] - let hooksOptions: TradingApi.HooksOptions + // HSKSwap only supports V3, filter out V2, V4, and UniswapX + const v3OnlyProtocols = protocols.filter((p) => p === TradingApi.ProtocolItems.V3) - const isV4HookPoolsEnabled = ctx.getIsV4HookPoolsEnabled() + // If no V3 in protocols, force V3 (shouldn't happen with DEFAULT_PROTOCOL_OPTIONS, but safety check) + const finalProtocols = v3OnlyProtocols.length > 0 ? v3OnlyProtocols : [TradingApi.ProtocolItems.V3] - if (isV4HookPoolsEnabled) { - if (!protocols.includes(TradingApi.ProtocolItems.V4)) { - finalProtocols = [...protocols, TradingApi.ProtocolItems.V4] // we need to re-add v4 to protocols if v4 hooks is toggled on - hooksOptions = TradingApi.HooksOptions.V4_HOOKS_ONLY - } else { - hooksOptions = TradingApi.HooksOptions.V4_HOOKS_INCLUSIVE - } - } else { - hooksOptions = TradingApi.HooksOptions.V4_NO_HOOKS - } + // HSKSwap doesn't support V4 hooks + const hooksOptions = TradingApi.HooksOptions.V4_NO_HOOKS return { protocols: finalProtocols, hooksOptions } } diff --git a/packages/uniswap/src/i18n/locales/source/en-US.json b/packages/uniswap/src/i18n/locales/source/en-US.json index 0247151d61f..90898a711ab 100644 --- a/packages/uniswap/src/i18n/locales/source/en-US.json +++ b/packages/uniswap/src/i18n/locales/source/en-US.json @@ -2368,6 +2368,7 @@ "tokens.selector.section.favorite": "Favorites", "tokens.selector.section.otherNetworksSearchResults": "Tokens found on other networks", "tokens.selector.section.otherSearchResults": "Other tokens on {{network}}", + "tokens.selector.section.poolTokens": "Pool tokens", "tokens.selector.section.recent": "Recent searches", "tokens.selector.section.search": "Search results", "tokens.selector.section.trending": "Tokens by 24H volume", From 492d30ca37cdfa5dacf02d248569f54fd1b31840 Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Fri, 16 Jan 2026 16:20:04 +0800 Subject: [PATCH 10/33] feat: update icon --- .../components/metaTagInjector.test.ts | 4 +- .../functions/components/metaTagInjector.ts | 4 +- apps/web/functions/default.test.ts | 4 +- apps/web/index.html | 6 +- .../1200x630_Rich_Link_Preview_Image.png | Bin 22913 -> 0 bytes apps/web/public/images/192x192_App_Icon.png | Bin 50878 -> 157390 bytes apps/web/public/images/512x512_App_Icon.png | Bin 386611 -> 157390 bytes apps/web/public/images/hashkey-logo.png | Bin 0 -> 157390 bytes apps/web/public/manifest.json | 46 ++++++++ apps/web/src/appGraphql/data/apollo/client.ts | 2 +- .../components/Web3Provider/walletConnect.ts | 6 +- apps/web/src/pages/metatags.ts | 7 +- .../SwapConfirmationModal.tsx | 105 +++++++++++++++++- .../services/swapTxAndGasInfoService/utils.ts | 49 +++++++- .../src/i18n/locales/source/en-US.json | 2 +- .../src/i18n/locales/translations/zh-CN.json | 2 +- 16 files changed, 211 insertions(+), 26 deletions(-) delete mode 100644 apps/web/public/images/1200x630_Rich_Link_Preview_Image.png create mode 100644 apps/web/public/images/hashkey-logo.png create mode 100644 apps/web/public/manifest.json diff --git a/apps/web/functions/components/metaTagInjector.test.ts b/apps/web/functions/components/metaTagInjector.test.ts index 64c934a5c4e..4bafdfb2a30 100644 --- a/apps/web/functions/components/metaTagInjector.test.ts +++ b/apps/web/functions/components/metaTagInjector.test.ts @@ -53,7 +53,7 @@ describe('metaTagInjectionMiddleware', () => { ' { expect(responseText).toContain(' + - - + + + diff --git a/apps/web/public/images/1200x630_Rich_Link_Preview_Image.png b/apps/web/public/images/1200x630_Rich_Link_Preview_Image.png deleted file mode 100644 index 12328b33190eb9be07e51430ea086290c5fec58d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22913 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�iBGZjb2f?EKu0 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 z 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 z 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 literal 50878 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 diff --git a/apps/web/public/images/512x512_App_Icon.png b/apps/web/public/images/512x512_App_Icon.png index f24aada72a180c2d4e6dd9cbd7519519626de5c0..a96d353914086addf96494de356e4429667c4d2b 100644 GIT binary patch literal 157390 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�iBGZjb2f?EKu0 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 z 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 z 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 literal 386611 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ℜSF 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%0D6*Ptz zgNz-XpZvA;Z}ibP$&J?N&$+?19qP>}T*t%bY{o$8-Y*zO3jQq^guw+0dI8fG?Yke6 z01E}oC}8S zlh=X+jy6HsPOmm}Zpdeaia>rzERyy5v-VuNXUD~Bh!IVuEp&Q{n=q`&c{b#_or_+}e?581TbeSGI8g?M6fpNLJ)%O>+B zzi8wjn-==cn43T=_WDYIqeCC~n{P4!!6&BTUotw+Bh71+gp2lv^kIU7hpcNR)MGGF*y0Y)2+eLi(7;V!ypii_ofwhrJb{Njwvwqz5- z;%{gBjax{1j=+@zycB=1mcs07h-6Wa zT@kY|irf;;-doUq{M~W%D+m0_7Hmv!LenjsmJ85!YlA(>oG&-GZQ)rcfwyI!^nB=>7msWrA)tpwZ|l64 zI(5`m=<7Fe@BMRxEc#AgEqOjWu>PlHlxFw-aA-Qj5Rz^C+XRQtEOF6)Vi3TBMn^E5 zW9x7IK8mG(OENm12;(24fCtye+K%tVLp@ncV!~c~TFhj?6?O3T=@a=$F!?Wp7jE#Sxm(bfcx9G=G46cu*W0aO6pIJaHal`TvxW9Xt2 zZb$V4tf7z2CUKx9y_Qb9(f}Vuy6x%$zGQEr?=_ge@9#BUQhQrJtJ_>VUfV=?{`($} z@7Y=Ozi8ir%%q4u)18ZrXtPE4&m9wevfHNTilapheQsN^hsj2Eaw}eJS^|0?@B9>g zFpty|uL?Q1Xgs`cD|X*+UJNFa$(&K}I{kjivCE79yff)W&%z!qD4uarD_H7<7a!69#5;(ouOjxidHQa)Wf4YVY)ACj`bNw0Np z!GKP($V$&#HbUD&D1g|&*BCW6l&DIU`!4o<#+00j%H#L{(Btv%{hZ^O|M|}z$N%tm zN__e7WhF)T$NkzKGO_~{NUS2iuaUAfR)B_V^S^3!X#4A~Jsi}vW8IU(5bY0E^}<8ce3aGjN# zU-G_rq~O;c#k{W;nlGAtwAqk;?97&A0h=t#_k2Pg?-ubc17mCk=Uu|58ynbOa*B(` zZx>xO^)J`NbH4>p-wI5}w*KA4uoOVFXZsM)w($qF;~?)bJv$vo$Kcs++Kw1)n2_<5 zzzhtbz0uR5Nq1nz>50z_um3g{P_#1gK+%G-KrnRbwJ~rjW+%Qx-ri`fkcNlu_Q`^V z;}vg=Y7#u&Xdx<*3kYNW_;7%6K|bBu=+ofze|8JkHvwjE@PV5cJLA6L1QFDZ@4#C? z8gC}ptkLDN$M?dNBN8)H<^7u6+0Q(XZTO`k;%cJ7PB)@UVmt10Gw2_-{ zJLb!4F}3Fd8gprV59`HqFDr`voiumZ9o_UtYYVr@9->6UCT!s2%qCgpBMDkT5E~_} zEulrSE+_e#(#S0l^=89H02X zE$X^u(hsy8uaNw1X72#oFU;m2{60Mt_?gG?H(!&&*_N%?)O=$zwyt~rv(JzG!oK2T zuowLN8q7WK8eYKzj}~|_D5lUXUgf>bMMX%g%1dCyw|R8O%KAEX2Cj&TVG9D6p2?u; zcb2a4qs5Haq7yn~#zU~92VNhT=A|jRW3fkn9rUg3>#Xv{y&wvI3-devC~)d<{2x?SIIrKW=n5@@t1CV96P}%Rxn;UFkzFHu7W@A@B^6Bj_y7T#a`!zs1 z63l>|pRu zT)@N_#F97ItB<{=hOYRWh2Q=;u(AGl{qIxpiq4P>7HnHN-uyWWC;yXuOdDI$4PI=n zn2<0Yvln|zCgWEipHwayggcA=9KFL}O*lb-$%QO`Mt#nE@MjFIPzF0b?12tkHi4s+AWr*b*DZVzin1#uWFr$u6^Z)$Moynd* zC4T;10m_E_BHmnn_7kxDcKgr5$=Bf&7xq;g#1lX9nS~u%{K$du?BlI1kJtYcxAo&I zrd%yh)X<*aJ6<7gm<-n(8DGafc)23j)v?KK@qsqIz~6Jl+*J6*9)9EjM?PoI_?W9Z zqmMs2Vh#`Tcf2c*`oN*xD{Y=Vq8N{+{N=WMRf2Kqw5G}^P?>s-5o!;wX&D@ zMEmv&KWt%BANe(Xc))el!SQSy5Be$AY(qx6kcEtIF86`G7iIKI?#)H83O-nNp(8rQ z!?GFQhz&lRpHA~6je>RRCb^wOvqV6v8lANjwR3lWukOZ!ybf&OMQ;5A+`;zFgypz4 zJUe((#BPH4H##HQ-bwUK;K2-%z@r0ssQYsldIv*8!{>sxv9I8)hyq;SMJCu4a`M1i zaR??`J{NFB4dTGkH|On22BY7ww~Sy)WV2^9C&TzOP%!p4hc+(A$)bmh(OlsbXjq}4 zD8vJe$p9V!vifwqG4e~Uy2&J%?)`wEtr;VeBCrm4XQ5iLf>fZgm&ML#kkc+)lPNw} z8@neu-`<_~!sJvu7&b+V9z$v$O=Jl%+zuopaw`J(H&Gw{+~);Q%Ou}yL+hVm(!J#O z>Y=G6n(U{*nDjMg=-Y3y>};6)S34JO9VCO|wM7zn_?bOS-uBnBHJh)XvI$+#s&hqG zvAf2Xgvg?SLGSX@NhDDAsc0`TijPh9Q;yTt#ehq;|$+O!<{CFq0(Qd5mt`;!5 z{oR6T8~XG}ez9kPwE2H0LOPOBGC`9aZhmdIc%er{u?Y+pQY z!68u@Apd;bm;@yu*Y-^UaeQ5U*;&mCx^424zi+=I@Dq>6U;1&!@wp{LFNONR?67w} z4E5XYpSNVA_b!pY=C#Me=X}9AH(Xlxu$Z`FckyyREaoY6myunHR#e|7SU%)f&j#=T z8~gP}XZxC>#3$ld?%^Y`fd2ebpMJiCYfQsipc_Nu<}D`lgU4H3+zst}F|Y6`a`*r- zsT3+jlkDP96DzJPpyvZ-anwE;Lfh87qB~i@-MXMfZu7vHMhCiC5M`5HK?BbQ=)iZ? z!#*AGvzXFPZuGM87W@i7T(I}z*8aV?y6qX;Ew&@~WFPa4zAMyq&lh-HcEFoV&hCBN z04;AsG-v3=HgsSEixIHhYTS>Kji!M<bk?7|gUg{y;^C5)99uAy49)^GS5Ma)A6p6_F&)t^V0Jm! zC8Y7{kDwxp4oG&%wZ8UCHj{{^du%-&&5RjcQOojNoC{70VXiefju0 zL*Bhiw$d7(4artpoJdUhehG#QOFsAoz@KbP2Yl8pIV9P3H;?9r4vK~Oa|Q{RO%!>s z5^l#9i|4Zk!Ar>c+nrzvfS8a3$tW(OJsx1RblF^x@GO2LG&b?EzZl4FJ>2y8)n9u& zzO>sqKmX&7$G`sbkH??;QOEJcEd+d(P|M}#_nUU~ZST)lWXE?($)EEV`gVj%z8!NT z+p^W{?pR0d_R|g<)Nk?YK{E5|o?qrBT>b+ihFp$T_{5CZQ;6zbY+FF^vjT13&u+zv-9PS%^wu0C9s`SD~cS1r&7ThTuk#Pq43e&lCk zbH(eA7u&&hHEXx#XbBFj7GL{$V79PmvGpMz8Nks&9tm$eErQt72M=5JpCG^QkINFy0=Wxc$4tx1d0DC*%`r=2% z%U}{08R$a@Mrz3Fn%K6Rzwr6ZB;&p*lJDe`2RKAeo$ z2wt0~<4bQg)EE7MVGEC5^-T<9h;;D)clxNE^)-Ik2*MKm@Y{!5kWaq)PFzCQ;(cCj zZXcZjc*V8J`t;Brc}#kRiZF1p$NVec={j2NciHRVGyZO8d|%lm-vYQf_|3MxQ$C;{ z`r_m9BVTgfmm`O`zhY~}e+<(3UY)ZKeNAFpGIpjw&hs_7>1m9-7BH9H;O}_=wprh^ z_8Y7uMITS+f@L>}Dh+2}`r$!uPhMx-JwxE^T6_TYCpx>_hfl{lleSN8w!<52&Nwg8 zpT%}Ig$s7L=*7K#aCideqLepvd`j!tuoW`9fJE#FFB51_Jfbd&;Gf`<4^r= zb!IEcnr~hd6VHM4|Jz(+)1z+%{La607Eb=>DDz2ibH*?6JLXFTZePC(jZb_O7>hH0 z_dRh1jW5CT(YEb_n=hlMIGI0u#CQ5lByr8qV%M25I^+;*gK2vgti^rf`?}mkQ(;1n z9txskG+Ys&7k$W#CVFHLE9N5J!Tzz-Xggg(< z-GIUKg`{I^;6&?yQg>^21+&q!V4mF8r#RibQg$@MJBwaQz)k)qas-#OHgGY(&aN$k zIUo?Z1o8$?nv(7_oEiQuL*KA%cMp6d=@ZP9I%%Hr#9Dw|&G6paALE_T)Ia{nzcn~p z&LGp194G8eV?Z1S7wzQQVu5pO_<7d>9Zs3riRSD<54dPwO|jTnE0PK5Omjuw@k#Ow z8Udz(LI0ju6S{tMFWH}T7;GqwAvGBSBe#Nf-cwKC`p)8i(MDeox0!r*;!qF-uTQim zXUOLSEHnkP_^^G$*BlRD@I`S2PnoyTX20ma@&nH^5;C(ddC6l3TN4OxGW+TyIFmJ- zt{5lu`9M)9aq9deeiCI$*>3q8I8;ZK*Q*~*!`!on|tlaJVxS)5U`xw&A$z$f;>@&}q=3#}~_ zz$lsuwfQid;BI{I_TgGsh!t??i8BRTA2}=vR+t+TyVrbJ+?o#>Tvs0G0aicy z#g1I1u~R-+4ndb~%nAE`3*ZchQ{QL*;?$@AO|5~%W{nOS`%R$%oud=VKp*?(nIt%% z9TWCyql%XP_4Ri+7w!A>Y>dvNYMjFUjo09x<%iMT|BOV6F%}%rKm75!7Z1oy*6e0q z0b7B}DTCqI=fK0?f>u zp;VMSz{By8pA2mTw_>vbbn#nIj7j|9q}x+b2<2QDkt3aU+<106i&GsYuYm$+1)oli zJ<)p8!V3>}BX5&#JoFZ5D^PS)Xuvi>#&?tF@?mJ+ssH4g6_0R6H`2jAcIolKkD~nU zS9h}b-#NvHEHmKycLS#m=!#%x)v>_NdRvCQ@fwJRcM@F|+CU zPQJ)2!HD$|*RD*ooh{it_tY_- zHhnbsYzzhsynUS1qE+{7$6WNcIH0#H27H3od=x)4#FJ&=nuV+=pWoOA~1N&D0t>}3N1 z5`R|?W@PaZ{pp9R1w(vqou2wHxlf&f6ND7i1ij?-Tp0GK51nn}7x6w*`jkgsU_j2I zb;^vSroc|GCCFqHV9|ZLDsb6RqTcNe!7DJZNt|;(2D1x-WNLhqgW}hiU}nP(wH4~V z6h8Y{aOg)5K*7ATVFB5|id~a5sW$n>+oW}N0G^$i6nm$=ii7f{ZH1nH1^o` zZMNvVpzr^`;`y_c6>vQ#{p`7kS%>0BwiR9z&e#C2*}z^VUH*D3dG1PwH_~xHu=m4* zE9QF0&bKBo`zX5Y4~`$$dkHt-_V;j(1q56)*&!OUqs|i2t|o~KG=tgO{U%d#=);e( z+iZ?B+2{9S;L!^};?E#%=d2wQ zMw~|GvENF6_pkwwd~nB-sg&7Gm6Ti0YE zZ||_*1B+l>#uYCXf360+TfE5(UZaCK0tPKS-0KHpF@m=u`Od-N`_(Nb*ub2!2(kdD zpSI=}g8x=(>V4+XwF| z0sid%uE~v7pV_qGl}J2HSa1))(G9#y{=PL}>rIOCt9^}sU-a#dcls5d@+&??szZZ( z+Ie(suK~$=6YT^U!`-))kV3q1cQ7I$Ht>WqfQ~cnEj*^iu~@e+1W@TE8R={~jaF#oO4uxIl}_qa(nzONYsZj%MNtn#SM`zwLZL zcJiVF_o=mSg3|Mn_gOl@H#BIp8=uT@(NO%c7K|n?-uFHvN&e#Z6jRANw&F>VMMFZNpSdAuB!4oo2^sn~T^rwave$d-aM^Bz z(cv4k6omF&>DjFW@G=sc!AY-ONr1!F?9{F{o!J8Htq~Cl|gKJ-5 z<##eYR|YZj?iMh~rl={dXput^)pyHbk>Cmio#;*x`{cf379Bk3fDU?eU=vqA&;qmh ze%)R*?jxS*WdFv!ZApJR$$w}%3ug;*u#1I_4|&L99}NpOaPTK*TMnTd002M$Nkl3bH{I8EW+@yn1)Mk3$17RQvNeJ^G#p#o9#xehCs4h>EoRIb>GE$NrGZ` zvmegW+47{SD@H3ojh%%dm~fESf3Mha9j|*3J{-_DpSJ#uz|HsG=7^24xpv7jMht)! zrYH{fS&+e8IFkYV&2w@zSg=iZB%TB)xul=VP8R=e@4gxTDhpVOKBXE%1D+huDDj4d1$(EPiFfkXhFd~S=B zco$FN%-Iv)@I$^=+;^MB zE+_As2Faq$C+WAM8<{i7o?}}GiER%-i8D!ABftIZuuGVdDp@6U_B3_}8$FzD8Ix!w zKk^v=jur9ueV5~z-|<=9j-YQa&i1m`o}6}t;iki|lIrExCCabr7QicC(CwiApa%wj z(DC?Je&KQaqVL}iEoIZM>pJL)W;pK=ulo&!rv~4;|1$r-Oy8q>#9#ROUKO04=8eKH zPF$9Dtg)F(>I#P)S#!iY2Kl}Jjy@JCx;P~Ng&WLY%V9jrf19ZWorSC3eVDAE` z|GvUEp252vq2HN4UBL1qzxzs}g@JMY^idq;5|{AB3Y`>4^ZUM7+PY zoZP+&eR_+3_VYj{xi;T}w+N2U1HO2ie@=hl@546W(V`1{^3l<;aeCv=U$tH)**^o2 zG{i^i>bQ>sI14IXI-xv^bakC`X@iYQT<~sT>wk8?1b{D6wwg`*lHm%Vj`RNpSHSL$ z7>-u>ljo8XnVZg;goA2q&je)rCAW)@fhA~xa^pcB!U&)8IM%%))-L!9WrZteuK=Qf zCitrj7Q8BrGVDXIp!{>d;as27O-DTU({NC2Rf3#m1&oAxl{}+DuCYUpW zI3|apy)$?dnrs!bEkI_E@Eo%pyLwiDjD5HIe8>N#mt;sMrr4AoLAj`K)SG4Qqx42H<2S4Hx%=uhEaA@#r{Pyr- z{3kO5vU{8T;-8&6$r2+UPYy9A8R2!`I+7I0fhRk;4EjA@aUB24-#8xrc#A>rQ?Gxv zm&|WJNOoj{y79IWD%xz@E0vEAXfg5fz8Uh1f8g=>_kY3h_{ksFt)jkCs7cg{(g#HQ z-6|&u!hG*Duc5(D-i8 zgr|6j74}8bT(X6yPXROz7d^Z;zoOxG!H(-QXW)W$6%AqZ7n`xquHvy;&@lo_y!$vw%OVH76rjKe|F0dkAA;kbCUg> zkSOxzmxUAE(PtYzw{?uag)`mB?oEJA!vi`G6VGgQqG3X1HJkjtWW>d^q{ec zy*>mbegB@N_e5vIMxLc4)o2Rp&X9Jb)J zJ!Mb1Mwwnn`$Xp~uo?AK=m|vs0w&8nQxMa2NnIi|X3+z`k79fNUO?y<{kPspjy~kI z3imQ%fIi1wTA|tEYEs_Mjd>YPhDJG%vrC1DLHnJPuLyG`kGju5V zoo74k^D~__iL0b_EU_u2hS@D~qc3k`c@r-MY7PUixoetmS59BcC{ndF3C8ua+S70yrksN?Z({_NxN zfBF%}@zcM{aeTLaGol6L9vXZ__}?)Z+3Z_udrSJge?{u}f|7ji1bFv~mG~v|T}V6R_KSft38d0BY6X_8%L2}Y$bcV7o%S3i!Pgp+2_i> zt5MOUA6|}~VbghYurYe!<=EC-C9eJHLyz|1;*C~k{#zg`ve|G~znU}SO~zXnS7AJS z$S>gZvjyLoGi+edbNB74M}0MQXNv)REs*Kv3JagH3wha>Kgi2&7Bghk^!F`*clzW{ z{^Uo=FaYv%kL+)^^zSZ(-4P3k9GT?Gs|; z;-6w*VEJPY6MfD++XwT6YNz2L417rSWhk)v`rFYi;RC<>M&#;P@hM1lh#sCC0=UlM ztiK_NN5>6^_Ha-5^OeHThBdfzw?s>(9o%DxT(r|A{ifsb*L>XZ_|dPbfJMjY zAXKv8i!Nc3c?E%}|1 zEuf;aB5s1xb5#2qtaz9Vh}ZV4BXMgRD*EEuFZvtX``DFB;$2#_IQ-3-F^$ zydU!+-823U=RIkLATwdN!cLYzSNyZXF4ODRunBB_VE4wK6}&MvsB8TVOkQ}=+f|WU zF9nQ!NKPu9hFRrS#o%GL_=F~wiT;z$E>z$xy1%K zToEys*a;qb7A*8OPH!|VgwPaE)J{zy3EQl>U|RI_^csJu;~JpJW-Ou)s1}?Wu^ThyC+o zpbz8Mrepf72+}L#p2d}Q&;C=73qAurU4pD@frik{0~RAg(q|0ac9xXaQGm|2C!BtC z;7uR+w~dG2AL7)%A{33m(P?@FegB-6vki_G^>j(tSFUBRVU71@qZY1RvYFRCdvz*G2l2836%m+h=E|CU}QW$!CFFaHG@M3MQT1d;is+7GRU$-JYlt z`{htNInjQBFAUm;LXUnq7=v{yTkr z>I9cvR)hkXEhUO{9~?W~a*W3aowlU^ZNHM+Wb(F0mtXV2eZ@eW&5Vq#*wB%FBe%7J5glY!saQPL)m{w1f& zZjPUlj)WMT#0(Z(!w-^Chf9DnMV+<1(Qy6=j=eO;>-nT~hA>C#_-}U~0ZV&v3ZX^AyPdFYw z{ihs{zpfu3`qFprTPR?>CM5B4sOU~e8^`FMq9Smz)9*aLlyT`@WT5RvWC z#g|;*Toxw_e=48~p@j@zYh(~(_$kx`HjcJf^NH@}Ve?{FvBaNwLsl|^w-qPsv+wq! zr?|HD`d)L8F640e9DOv%cJng6xUS!Vz(Rq{=7?Ck8=1Yfm@UX`?picxYzW69nofA% zve{Z>CFf2Qz-Z>XF^d)pBJ$C3bUUW!bdKI^8JscuWU*)<-0!ZJ9N)XiNcn@)Pyke@GBZqV1Jzd_s!E@>=GT? z)S>t7DQ9iyX$8`Xzu?|68;3KU0=l>0^%qQgqQCtWzXEH8MUd$e%&iC?oQ;ILLWwRt z6wFABW*Y@=izV`utoDOHfArPo!yV~BYC*eslc%h4y zt;9!`Vs2;m_9d{A6~AtgL`HNiV93wMwcBr!-4+cx*_mB#UO@4@^gI_0@dYa`kaLAW zd_;d|@S~AD@!5lsaFcZfgnt!+64Bz5JoY6sXPf(UEb+ms<&kr7fd|>q&}_koUHa2~ zp9-=>+}IwZ`jB4gqkTk|=zr~JAICp_-6^+Z%D1)ojh`s?=f2>0_{D$xc=%<1yr0kg z(&NE**Ubm?#94`Rd4PEQ9-YO!OT9b8%qPBE|9xL|96zaN1^&)YJ05@kPdkp6ea8~D zC+?G%Z{9Q9eoy}2S)=PW;GevH7)jA!54NKhKe0I*>*p(TgWbIYKr!JDzPFuf)0n1V)^o!Hx=M82+{NDU&c5SMK5`dF%Sq%E2=p}XoZ*WxI%tYEJ1DHq%r!XVrw2L68i~p7e!PCN z8DpQtS^#h+M}71p3!N=C=xQFqfp5-}XLG-Ox|kO2YfS_ryFEoR)S=V2!W1Q`|?Z)4%)pEdJ-vH9Wi^ zAP;N>e;_B373Yi2XaNPe;r47t;O-|&Nu%Hxzs6QvGcM2-JVCbq{mI}% zS$3ComL$NiUu}hVlagP8TY+w{gy8bKg~kdh zJI`-dJVJ(d`F&fqr<(~*pJ?nVilj;23c81p#*_`XGs}c&0=V@9LMvViw)3&+$%E0h(x@YYz!Z?Iv}uKE=Sab*!< zT#=@an7U)&njf<>T>XH&epnph$Db><{2pD!3>;eSdE+I97SHvuzXj`fgu{pUixE%l z^DDk+K6i{C&0+djB%nuru#V9%Z}v<;G!%RA_-p8IG0`y_&{rJX_7Dr^1$w*H(RRf) zSPvl5$HD;o{jPBvlh#a?5^uY69lr^P~xuSc{k8pw(k-;z^p zb0uZ_;b*5Up!tE%?!_Qnx)Fd~>_>v8>m--m(#>RcxFN$Q$hwvgQi`lkjgmL;)qkU{ zm<9~uE>bsWZaNJzLSgiONj4)4Um^&1g&9oX-ixm=o%b${ou837K`xxLhdv_~@-55G zn4akXd1GGPPLEx2s~?qg%@+}^lnVL55Ob(85Nyu^PQ zb~@(No8{iuP~cA%Fo+6d4UmAkfENHuf;pK?>9iy)xHR^qQ}maR?eoz+aRQlbPKR`q z4h4*>O-q<~Z2}9Z+VI;_DZb;SKe!cDdJI1T_Dwo0B_}YB>zDK&{z&(C|DV@(ueHhX zRhL3&eN!#8<16X)uE$$H@w=6TOUUHYuhCKP*Y@?fwu;U4OYU=FRA)HknXNWa^kt`A zYC2`yLWr(D^l`>)0$z4q@o8-SO~EZj`B%%fE0pxic8e1>^tt_7a@%4}9~tmb6x;5J z{>bdR`RIuOex#p$@-Go5Ye{~3p}PXxI2*7FdL>J;@0|^3X?RH5=-_KHLUuMFj|8iq zOMK$J1tQ*(uue9IafL!t{NuH+E_S%DaKh>9e~%y4 zgKl4(EHA3C|Ej-zo{6K+t{Ptu=j%&ypZVI7a$_$LOC5j8pF5uULBG3)`#%4K;k(%- z_U4j8aTlG$8!ZX6qOmJkWKG6LPq%-smmkL;`pG>f@RN_@mweQ5ysBptUf-FQ`|W<3 z*lT+KZMJGrfz(?QyG7yE&*qdx)8Z>x6n)nbrc@soqLAPa^(Xhv#hsAA3d6|>`EOkB8>jvu~@uW-c=SUAq) zjk{$qpCm6_dN>YbvMJP)p>f3+J^m&$1Pcy&+-Lb>96!3i<$L;*8}INpuXbf6Ius%C$m2LWG1_D^F$wd^ql>oNr%32 zI2p3jc~vVQ^x1^%@Y#YO{4H|ptHsGqlb_=4hQ9s#xRIxRV-C-;3n%P7XpJ#Ojz(hI}863=IWHg?o*8woLv^56q`Zrn|ID5v(aSi|Ja2-!axC}yuwzsa} z?|p@F3GVEi0f!Tvr>8;NpNx|S;6>N2K-R!>_~@Muce#FzYyzau61gq3@n~mqo=QLa zee{^k4~^3S0{U9JI}UHHfYLSaf^TQ{{}7<9KEFU%xmyZ%=EUq{wmnxK|v< z5BQLMWo&2bF`wM=ym_pEC&$i+>CgnS_*l_bI22TqihuZ}Vo3@UN)g-xIhR_q5B)%d zqqwi&bvW2;C82IIvLCwf+?IdvU|)R6AR%ZSlXvtbSV;pP<7nVj;+n6bH<{>iCnzv@ zFLvrj-&F>-M&sU+H};a7``)8NF0}YAxcQ15YImH>b|oCRzAa!;H61VCj|YF!)tONV zcQ|O4)V3H-d6zZOTHDq=}>W) zUa#nN)1UGqj>q5ipY&b)k3Ehb@B>foSUt)7k0fK|0(;Sv-mn^cFzjx_6FFg>#E+bQS*j zH>L`yqRNi?(6m6%b{Rf9DN6bm%ke;uoZ^{d{3w(dS*&!dDU#ZJA6-27UV(>32lK)_ z5}$O$7rOo8ez)tUXPxFsV6zijDY|%)gZ|N4tcxXQ;%KbMhf6Q8nk#Q;(OWDlyyT|a z=!MG`w?1SXZZPI5`@_d0+&$G#H?r{`UFe_>ee!p^WOVrHuGo5=TkOC_uQ@k?x^EA_}n&~voo$2{JA@rosBo9Ybfp9xGQk$FTukHlssO{^RFO`Ze99o zcVRvYZ1PP+gbnrw9nH4S-v8e&U1kUd*E0GkOUL>WaF<@|m*6(WF(=!NpYZkF@-njh zaPMMr^Ciy;;FVB^8|dVW{t|V-MD}fjlScG7*vf#xCRaG&z17(h)>pD0AADC>gMW@* zw@j14#6+wA!$Bt49o}Od&%RU1V@Fr)p1hX-X z&OOz=v+gH(&M~&x!~mB*WH}3Nf&PVGaXkE_KiSz+ljV!(fx+9+is@$4@z($Nd-m0> zCVa}{(cjTtQPxX`wxeo)Nr8UB`H+&k=efP^`Unc&FJh(gd~i& z1Ohgl`Nmb8`KW!$?M$WJ!Gh;YwE9d!1_*!m;KfY6o-*DQ2{K7o8+L1h?rdTVJ$UTEr;7GnVA*>8(K5HhHym=2!M>sc#+4qQ zhR$yYG=>NN!HwnklGSJYgGWa!poPCUrIWa^7(fqSa+2$oKhPDzHtUD~{H_!x|DIVv zN1p`)J8W)7gRJyb$k|~wiw2n-8wcCZAA7)bF;B+(V_fkkn|p#W&f1!^Yv~#e5#?jn&-FFIYs6MczI1W$j^Y5sfGTj}QGE1(J*WM~PPvK9tWQxuSbILHl`;Rel2^gT0qhrA^)R?tp zX!=bgLy{@kukFaOL*Og6_kIJrObihn@}b?q>`NE08W_h~`@5AehWMPk+uQK?;@y#? zJN*PBJ!o+ihch@X+0odl{G`8vCxGy>QH}NjKCHmQ`F$qK= zH*PUNH@aMSXs&24`RhOJC~5eCpxFe^;1{>S?~?Mm>Px@b!}07?(ZHK6?qn7}JnvuO z8-J63MK`=a_hvu7f;-vuCA%>RfHQ*M%Y`HeGWj?ov1JQ>=fBydzIe<(x4!I&4!LHJ zcx(8?b4Af{3zePiMfa9Kk;rBnFUe3%^VfXl@$ggr@NxXX z&u-z_i*ytYIDPi50sAH2+kU$ubJ=A%Cpou>matvfcty7Ye$@9o9)H;nJ0Ab&&o~~x z-v{*)tIo>bJDGhy|5EiymT%D=!nWXu)#<7h`>2-aV5xyA6Pz7$XxM@2@Q?%J|ch zO{l-y2W`o-zB=7X$c}sY4_zHA&g_n+Mc_T}$bZWUR=ioPnXeW|^l{}zEW3)s20r+a zn?K{b{6R1B-dEIaeD=EMFaMHXAAE5d%JI+Ix|7oGj=|kYWrp!bp9bOjY;y;~iFtuY zo3q1?H)Jou67bXDfaUZ#H#H| zf@IWL$rccFXZPss%-0r84Q~H!=}gc2BcXv88?!h2&yK;5W^!yY$17YuzWGi5WSlIS zbiADnz{3N7x=J{FM4!P2OeVUrxo)(BSy8=stg!72hfR`u_9Ab7QTQalE6%1LzQvWN z^Y>;%a>Jo}XCM{`JF7Bhj8!b2iYI^H$p{?UL!{RQpFWEb@uShl7$0hAz)6g4-_TjM z1&#zKnerETzOKvQfI9p}+m}WEb3Qj@s0}8X@6*|K-SeX&C5G6{`yaqNcDBC#;4Cn}qf3T{$JciAtsS%hkp--H z;~R?#vVtXtt@x>HdRovpQ{H^5Z-v@mjW5x)Wg~V$8$MkfyS+kQHo313frV#YiaiCK zoy4+RA!68b3+U>1EZ>qrV{5wOgO>RS20tHhho5o!8xu$LAd5M{mtffdJq?_z8f-op z!(A-Y5BBT7{@Ll#)ITTc5Kp>Gj=>qzmYA;X)iwSg%4qQm64M)_{ltUuG`36D0r?7nl@E3h(?c3h%k_UaOT|9O{BblBa00e`~9Cun9{BCPpa?OG4 zDsTqeM$m^!o+VBD+2brG7q5bBHjmEiLtgR=#?W06oelyc`9{!c6nyfWeqo=A!gyai zjF&{*_(=U4_(|ks^$q{+U#YD>Qq;Rj=Q)SWZN;MZtskH8U5>}k{iNgZ7kqTD?QNmzt$ptn z-1Eu&E!g;&0lK$4J0$jsC_jjle6iRErl7DPyR&hdHL`2YVx3vDB{A8E?-V)@rI|x3 zMvdtM;~2bRr!cdVxp(D)1uLI|@e!+Sw(qPR{VhV`jlL${$%qH~>+e{R^f0Dl`3had zPQmTxpchkUc|O71y3gj}D4t{j#|Ci0*eayjE~f`WKK=OI3m-lf)1%WEJ;bJdHulUD zx?ZJ7u6W$`D&WE6CunBJ=uL|B^wqiXy!c`^8H3q74Zw!GuK+IC zVU3%c+BYd@`nCS51;YsTK5_QDu`$=4i@ z|IK&nH}9_>#$YG0QL>=dWMK#N1pn2TViPmHW(yOP-J2*gQ-4;p!xU8SR`=vWkKGf&;$jnC z?9ne76rU~p6yWqf;j(LVR@kGy*mc$-DbpQLwB{FasfZN=R9uq5licYvze~d8Eos4- zObzc$8IJj&MQ00(?6O-E?5M~{sxCpYgTzkP_o^VWNp17SjwFtk#6<>iMz$qg0Cx-T zjmh@fH=Se7A_HB*{f3I*+DZF5_{KM19iP|q>HQI#Yk%U^$HR~MJ;%e(>WaWWcwJvH z{b%_)eaX8Riwr(=(8!nW`!z)NYLQ?L@4W+HzN#~FKSJ~=KlFI~LqF{}e*Q;R0K$7? z3IFBU>RYOjgZI8FJ1ACc&3^o%;44CGs$ZXlfr7-=9d3>|g9gJVii!pnZT9Co#|$8j z?lXFNng`%45ELI{VD;Y(ef+MtI(>zH9}BYDgDpDZ2wjQUxS|b2ennd>o7alEg_+{* zV&ptdf(BA}YOFw<+v#t4nu5pW&y3B_MHgtAx+X8EO$yJuwxn~*3VXl)89lEv% z*xY23`7{1>McV_qFYP@5?VjyvhpZ9lxM{mF@N4Tf@SKjp(9Y-Cjbz4ex;J9~Ztbu5 zGg$vkmKDLq$$9P%YjCF+*Sqfn05hWG=>LjXU8A!O2LS;baL2ly!)J&cuZW(5!JZl; z3vU|}zWo)ktGG@+d^7aUVi^B+YN&oBXiiuk^yI*+%DUou!S2caOMWoB+JP?tCd62u z#e!3_*NT6^eS$!)kgBK`9dhh!P0+Q^mv{oXb=}z>8St8H?M8nKg>+d#pi^x&L(^mr z#bQQLlb&Mn9S==4wIR@f`7>*{uWF0n=g`=jTjPM@RK)``Et(%SnOn%;BH^x zGg~(C6#OkRW{2oCnfCysiC){-WvB7diI1&GUz>eRR5F20l=a_9vkATU;jas3m;KqB z{OPtyj_5vUP`ri*dgO1TU{C)N?ED?rigz1Z)e&nMC`$ zm4hdK63iaH5;K^ObGl{6;RPo-D?Z}lT8vDO^@Z}*c)|@7&BY^o;P>jUsxuzdIGX{1 zWe+mgmsHXIH*H?2OI`))T`MA={tu6bkNq9T!*BbG$HPB*L$W0E^GeYCL~e_c683|_ zn%=v@fxmc=n4JMz%!mj59Y4P0J&(u#@&_M}pZa5td=b!NS8tsO{K5fQ6XwuVF5yxNl=GGShDH8tQt*N_X z{gRz_7g_u3y5QMBdqTgCPpA$Yr^pJ!0E0~EyBMwO9&8A`bL=D}Q6auW88KVU;^Hnu zw!@KRj5jvp4f5J2L;t1+VUbA=;G;uV1_xsTw`YH}pX>1THySLS!-aS2boZfK@SI8S zqV{w=(#eTeV+pYpoa6R)W#U?$5)+?^mIJ{rNfR6@c`Zx=nC{nNV8NXpl5h}x#%9tx z8<<@Mr;jnbi77zVIxwbF@FoKyr@jHC%XzEe=G(Y{gaej50=Wi<9qK(36>P6Ycn9ubugu=n{^&AqSamog5n@51lT#=BFmB zZw#>GihlAgIKsJ)rw@CuJ$x|u*eV9>?d%WTlHzRNM7wRhSeQ?e7Y^DbiU(&fP3#ra zO;WT@dYo*Lc7DY$x+SQ4fA$wY^slI|5SOIHl10M!PLD*Eq&s6;!EfC0iC^r{K@4Wm zEfORLpSoAbN-$v0#lS@?9q;E8w$R}|yx>XD!Nb{NMMCVeLg`GD?IbCB!HHH>aX&W_ znb-;6*k~;ICF>WuR8+qgHlYizUyYRT2ItK1KErJE-?+uv8>sigKi{rI`SR`~|K`s+ z9)4gC3jWd0>54#KJ$#oE?rnGeB8DQMWwRy!btaueEdKP{I&1YX;1BJ#!2j594gAWF zZ&6cWdtv?GVn0C~eYO+t%&Oo!TVxx)CevN06huXp55$OZ1%^IykVOQ0iu=u<%U|Z1 zg#rJe-SG4SkGBG<2@?;EMh~{?UNB5bJ^C1oS}^eS;dT; zu&V*_>dE}!lille(b=nhqp88Ck0RaB`7VHV$f{$qoV(*Yn_N0rh|r(iG`iB+Mh1)5+pMk&`2DZ@nW&(JXh^9HAf!NwD8sY^$QQn?Le1CY|Bg*dGQaD{NO}GhGy2UGO@O8=um2y@c=jaMrd#)F3kCCUC2e~E?&>A!+(Z4dZY4Hj5 z*&fkASKjfpLQGPX`X)ZIEghXUa5)J~9Bjxr5pp0GngecJPs79k0}vq zH+d9H!0{a=`u4%U@TyM>#@bdeC5M0%UHZ*|2A{Ok84Q+!lm22;{h~izXClz&Dd=ag zyy>R#k{#a^3CSud;MzK6yE*9`M79483Lfu@>}O|^dhT7@?)g8w?VkMu+wR4$jlCj^ zC(ffrCx&FEw?Ix`a-=Q2GlH(b>zs|~>P1Bt=Rv_g^SRspKV&!H`tY!7K5P2h??CMO z3Onkf_DN)8BLcB0oAc|H6v=CRN=)BJvUouZes>G#)=&O~WRnN} zK2;PSvP@de$*~*tBgdz zGlZL<&18S+nr-(@FVFkb6TGb5!8Zq^xepH*kBN zz|q8CKMK99xVpQ;S4%v6BVT<0J$;9-fCDGI#!5c?1^P*6^jBykAgwn@E}OKDjO@f_ z=n4jcS@1h)KxYQ5P8jIP#)60mL$+$0xarxzJ#U2=i)LB%mE^wKu&(P!RuIb`bd=0iB8Uq1?L$6~JW<1g?e ze#s08x{-NJ2CUYtuE8td*R23FS3gOxlA+Z&eEK0s4)v1wl93JhD>~rma$8~$*^O6l z#$aOu+fMt2W@8LF;HOVk%;|Ud$e=zikOfI;64`0;ycbItB*b;0*YjnshWt_cAa#1Wa@@F{+NP75esk@GGCt={9hh z#lG_4umz2d4J;bTH1ISY_(YG&#Tg}fj)+j;C6OjjGPwqW$C4woyQ+;$rIDrvkJ<)1 zJTm~`I8{G&3AN&oV=uWS`5*i89~^+U1i^&i!zmAg7afxP1qp$+I}IyPu(v_s7|{0T zVig%HC|GjpM>-HY!A0^~$3mjRzTgrVhEJqr>IkO#XRx*(^*_F)nZAjw`!Vn{09Qh7 zA~rz5)d6#WRv(Y8Q`d+2($9s(e<(8ovHn>f6PxgC(gtVi79A_n&@7yO6j1QfN7|hW z>;b8MY!w;Nk~F$=kj75()CZm!y92QFcNCP+7GUrfqy<{^wUbl5AXEYv=2XxUNEHD~ zn*<*GlFxN_7HsRH_3C#QwA=H}z$*#%^=Y&OYUN=Gd@T!TUVgX-w;Zkr{gcyY=Y;l4 zuGn^e@@4ty;Fso`1h*x)j|U?wc#}*-W|K^S`Yi!AiQW6+CI0F>Nw$eY!g*3|W&OSE z1iaw0^EJLCx03_^+nofk5u>oBvE`Eg8t*H?Nop(pu!W>)vLK-_mE`W4AH(58+Ts(P zWbuvmuRaMpTCQ!c!_mjCgX6XvjlW9|;~$ae%E{!_8^oikr4RMW0G`QHKtEV^{x5 z)X@uCC%bkN@MJqh8+dk(eL86;PjATt-;Xzu!9-dAX;aj#apUNk?rg%2e7$2W=aPO7 z#_kX#_{Nb5`07V8u@P9ZpplZV%4bj$GK~VZ|4sPn3v%Mm3`>I$ID%me&2>O?NKv1_ zl}dpb-kL=87Im3}o~5{O@_!j1O@iT)Z!pMN`mZ?*-PkI0dX_$wbER z8wp^DSz9c9rcPZU8Vu_FM_*e`iaQKE+rv{^zzaww?Jnaib_tdQux9MM9*;m%c0WPI4;Yq*N58y9f6om02kACNGN`p_1k-hd&$37VP&?%*| z){d#O5{o@*XS|lbWb8CS3fk}_8up%gbcaEo36z2v+x__4LOt+_Ywf>?*pnm^blIVP zN{_S87;Qr&fFGISM|W-vQ4a&g_jW)0E4eN3-TB(!Teh8Kk@s4(2)z0{lY#0<2iHCk zuM;G`EV0yffqz^cX8k*PfzUtxl57!2xpM;d+nEH+ZrV;sa^iUU5HI%7m+D-5dz_V} zqD}JA$NI)(1T5c`XeBsuD(du)t!4V?J4t&^bV@^FN5@BhqQ#%8cj)v!cX*__^rG|f z+u~>s-Qll+A)91Z`6mt~=td5Fy2T$^@B?4j;B&Hzt@8EP7-G zYode){n0_&5j-2@Ke*>jo&69nMf3=h@qsO->?(;$sk~QaOukU4{q8O zLEMDk^v5dT`JJpyCw z@Dn=bx*kO@GMW@QZ=#8Qbfu@x{kr`0@OOUkwp|mQ&kdj1pZ{Mi>IQ+&4<)q^Ysb*k zuY6X5BeVXsg4SQ;tgQJXQ5pB(tg6ASzO2myPiFP{UgD!4+Qzy2+GxUQ5(-Ve=>x|H zf9-hEtI1GOjhtvGo;e|hNs8obe37Ys9{OzMoE_1yqGe;W!IDklGZB|q$!s+YraKVf zj~6;*k!bnfoUE3wq?)Qj|LG^!=n@_;NjF!O9_YhCbK({zN;dGJ>c95V zqW`EXA>1dI2e?iB>$n+hz!5@rP(PON99Jlv%QH2`7ogXudHMFyTCt( z!!@Ab!A*ne7AN^c!h^gAVmg;Vl`*<F|M2!~F zQhI;ic?QzaKCCG?Dkjx)$XrJQpSlKHvPCX^L7d8Huz_J?ZO3EK?|sd-{kwe5OY-km ztpI}s6t=wZM|zD|y`8XyK-a4Uaw?nG(&h`K)b zXW%IODFdnfKJD0*t;qs9N?5t2(mrFS&bA4i(x4DIDsMp8D4#>W7|i4p5XwC5WCyQ5 z;*jk}D;EWfagla;b1zBapHG9HV1Z`zuAFGKM34AU#mufq<%nLj75@6whb`GcflHU@ zP+wz*1`}}MZ9AWS;K;8Kgg>AaSUV2)n}DRb_JK#g;s>umwiJrnuPFZX72EdaJnb)J zg&dweIWO0Fn65SqpW0r4{Upohl#uRk<`zV%Ls6?d-zNKJ4n6OwJwId7XEq9~`oy&kk&)STyjF z0B}H$zcoSBW`|MV1cfXef9wf{E@UMW+33Q?3R|vr_97d74?hMp0R_*Hjeum#LurD+ zyvCK>t29~XVk8c=li3)Vhw)kX;4S!G<2S)i&~FRCoD^Z4M)+=_lPUTQJhEg!kvHJv zYGBMo<;gWTJe%}U1cX-Ur-GBD_&tCIywtCzUZbgwp>^z-eI)pWCgQWbMEt>%q0Qkpo>$+dr@GS})9^2I?8_h8j&lXN)F1ZyXQU9>uYgRb*SBl2;0d=dblRp&Tj z126GJk#mL#zhw^-BT1^sk{p~IC|LsAzLD4xh>rbC-t_mamyK0g zZj~PND1#5P0#RU=gOx)4YD|V>o~km2V!J1(Abkc?2Vr5=*cGfuK07N z-IaJ~)@FFIb8wa|1(yc)Nwc;=J3KonU>A7k>lbp7m#rEk!!Q48<^-a{&JBIg6vWwB zUzAp4v|6Hj0%c_dhlk)$IDpX$4S}ru_(w>fmHHNPCRpq}wH%oGExEPxkH~xY5hw@( z3ts#Ij37dA{{>5S&Uu3(T?0?g`j)XISkW6^NHmxWzDI*o=p7~#%YQ?3_xj6&5dNnQ z`{yDhL{3TYd}3a*BZ%TT_1j#T5VmFmDxYOY}>uyN4D+t?~17+ zJ6q`&ea{c$TXsp@=ia$@F1fMkN>BowA8YxupR;X$>)G3OZ4%$P4ErHUP&|;h-?H<; z;OwfeI^oEXjTQDMi&b|0CH2Mx^5C^Q?*t%l+Sr!guafHaKYjTyUXBX;&e8B$NnSfy=ws}FBO~8-&KB*@X)C(eddG{NCg+m(?Rh}3`h_;VO=^svkSJYz z$XvQvE3nAay@@P=kg;kRoRTy_YHjNWB7w!441OLH8AQ!Q|FXvV0DhN1kSOx z%dz@^B?r2kvr5D!lFXz(9Bj}iu6hH}5ubUey+Vhq#nqNiw~q1P@PRcT##aJITUVQ@ z#$Q|+yBG=V8DOOYM~Tyrv)j_)U){(|7M7&z3}QtI&+?`t!f?qE2b47T2Ew~<-gbW= z4@&iCS>tf`EM^#fn1u|2<7PDwM~-Zgag%xMQ9B^bK9Q+*r-FoT<?KgS{r@I`hUrIlJ(nsvl)%6SzXw+8f!RsRdEcI61oq(`i-YmCDeaZmV zM{G#84*CeP61}#-&^5I~_RReIT!I;WeS7GOZzmvd=oXswC$dGPCgPmeKJ?7WqOu99 z`VTGglHW%_Y5xW{fvP?PcG+|4SssEno<4NyM38RbGgmyFJmDd^(31~U-zY|RU*}Rx zAmIE;zWVo?Yf=%|xj-6`D>7d2gwn2@O+=v;o9)g{BD~Zjfb57p0LAkGSB8&w2mJiC zxh0UV4F228rtd{|{lG4fr?*!0ZC0&)#W7p3Gk;SrctiQ>&&rPrJ$Xz5P7UsFR!&Nr zA9(rl=qxdyhacNYE|R@O5uX?nwbZj$K-$h9wD}mj`Ug9>wzbKHmOApeR;;><6Z#4~ zIBpL}g!;9gwA*4w!z2h!Ko76uHAc`~ysc`>FYx@RKP?@(`jV)?)nC%q``oz(tI!*N z3C@^wuFeNf1>e%ob(3@|@JFLb8qdH3)F<940B6b0zI?R(6<9w|1p1F1W$Orcq@Xk2^Pl?a8`#At zZN<#>2w*`herh$8pz}hhDDIN&;0*Y|n{*mz(avX_4^(s-)U+|!B-`N5uuA!dkWO1k zB6UG2{RYh7rnR)2>0&pEFxoyXp_TWyPQ-~|FU3!U+tKxC*b*(@+w zg>?rE+J?bngq4}KbX+V}b_a(041&hm&HbJEbU5&ofATXd4) zI<_k>L5j`TLZBgQ0*vkVP9oKne`JY#wefsdtNth0@m~QP4cnKF>`xynKmEjitxncg z{{%Vp(YJKg16Azj0l2(<@7QI(xNUE_e)!S7p{IBmRDK3}d+sOna`a(N=_5$yE2sM} zJb%Cxc7T1<|LRQd4miUkChund_E&AYZ+vlf2r>?c&VP(c_LkU^l+B+jvuk!tw>frV zaOPvS{kJ_gfjzq%cZ4pr|6k>?8e-$mId6tirYKDky;G5uXSp=q*#o;n4d1f)NKyRL794xN{u%!#t!wy(@gs_e{_q+nf@gAoHh8u`f5moo@Sq-eg&uYq$Z2OoJ^O<~T2n>3~gTs>>8(kf8zi#Ibx^ zG5!oWrX7$!@EA17U)hjj?35v|lYBzoKvq@~#TzNOK>Bn!T!EV2l`##@3z) zCngG^Qzr%=dTvGNJ$k`uNqqur6S?}qd>jHl>^bDFK5^0}Ms$(@Ycl~lwD1K#b`T`GO8vgqMGSJV zSF%BSNHKg1U$#kd=(f0tl^|_GkY_x0Kl`?A`|GbC54PPz!C9<$1%PKgY4D|M_^>xR z?UT>HATZf7aNFR4F1N%!g1_Gv_~9$I-Piq4ZV6nKKAQnvl3}OFTbWIYrn&03d77RJ z^(8eIoxbh=*%#y@b~)uY(dE&A6Wl*B?<#2U4iEFPN&L(ITzejX zOcFRhAvajQrI?5)#xhyR2fnL zDounYVkz&8`4uIft_Je%n$#qIsvvI7_sLVN!gWl;6IV4a+6i?uqqdP=}{Z!+8|)ZVeT=Q*jmD`zLH8%gU|kMBXn0m0%zmUshy{9 zc2XyRq^-L==o-ANikJRJhpp76&h6T6?X!JktbGk|@EOSM=fD(JKcOEv=+@l|fvKNd zPxzrwkRo4y9jrP>2Eho=J|GmD>_9>7rJcSaUq0j-50q+;uxyZ1uvY)$0n*^X7qHmY zy;VFCq$~Fd{FD`}*&40s>(y0XRfg~t;MT;!!-?*#{+HJVA@@^{g}yiQDPE=fo&@1f zxg-;VQwBYL&Sq%myk8%D#<>ALCq7C(j340gYmwJ;i&nI6%L9Uc`1`lrkNls=7aMuX zoZa{)ADN$yC3@%^ML^FaZvT6qx@~{>X?<|3`j6J}mumf0mrS-#&yE4R^Aib4=cR9( zJS7RR>BA-wekoC~e|;fs@RT`*3P&Dz{^%qA>8EztT!+GybR;0K5*?oSOJF`8dF{xiMMj*+>3tJggzi`qrZs^9mq>|_FG97ulV4;+d9E9QIf1{-@uW>`MM6s zx{X_%>9f9;2+!C?pKeO(`rL@?>K=GUV_JWLH3rB?R{i3GpQFAriRy%b+eC>5%Ao6u z`;|$rSs@J>`lHz)ZOX!(SK&Wk1O~GB_yew|z0{T~Mhf_98#GS*E$)Oruui4=-nX5g z>nDSc2vxe82b%F*gE{ndCli71 zgN*U>u2R@Tp@t;y1E0SpaCUN%30I$aSp2jLVwF9I*s-=CZ<^Xi{1qH|VypV0)&GxX z2kAe(dE1_xiRAUh$}CR|{C#nl;LBx$_AH_3}{YOg#& z(ofFGEXkmQ2Ol#A(D5_EjUTyg5}SBdpT>`EMCS8dDz>ya!p2Ko%~B@yugr`e8#$+3-XvKfnzU6 zc4S-nx^@diY5xX>4VNA9I(!Qtl?`%{V~*4C8~-Tb*XG(j$n{+7(K6cArR8Xo^AZh> zTBIO@UTCiZ|3rI`CXEJ&1vHPXE0Yo*^zmR&JaRq~Bc36}kd;IO=+F1IU#1K>FCHH05BA^tU2)vo?>VN9E(l3>Xpe~;h0+GcN(3)eYRNYH)yl9d zcMZ<+g)>kWUXci{C1Vi=_pwPoV ztHttK2`SsE-TH@1#~)1c|I4r1woCK1wznl%6)AX+3JpPjJAd0QI(r0IateG2bd@z? zb+snp{Ju+ak>e?;Tr^VifET|V@U94OVRZZEmv6g&@)OZN=eF1dcD_kI=WLMvsITZJ zi7i$8b2AZo{xd@-6Ph#m|16JZ*F1Cc4VQ*qR_1WgYCq)29{O6)_rYr=Ek3Vq!J9xT z#*eN-^l7*oohO?xt$6!ALS$QlLcQk01L*Bgl8A*IP@NU z=qPl<58t5GUM3XI=Y;#vzP9Gq7$7sc==`}?88$<|w8JsB))W1h z+Ig@5VrvCFyMQ&uYTwvczmi$|BXbL&$zdr0u`T`vB6Qn6>)M=3!BTt91_u0;@pl{t z-BlSlpe7Oy45#Qshe@YDYdfnKOcPRpf*ZV&8Au@%I#ZS!2O9x9pMftS42;sz;kmZ5 zt`6i#)p()Lq7MdGt|xss=#5Vdn)azdc`bOAg>iy5937SGt^&iqlM&aUX%f+i1U~tA ziBGq6$*CLUgwEC$TI+3t2#r*sQCS0cT9t;jos+Sm zk1a5O%w7syHpiQN^cy>-sl0MN1|jjLf%L&L7JH_^g@snGWtuudKU3xw>#4icH5mh0MqlF_>pTeh9Mfo(IXd;b5()_I7$eb{4}r(cJ=F|=Oz zsYw7?1xg0hDfCJ|@GBumNavloZJ&K{UgMhp{$M-{K+je5_q(Fg$0zu|@O9hnMgKF2 zE%LLKz|4n@Z#zo0Ng9%{`r2TVn{!Xw_Fwt*0B5CnI;2@*h7x(onfdljaM6BMB!7(^!u`#;!uT+9lBpKsRpRa4L#l?eO@EpmY z&SaqRC^X>uc&i}Z5-{EhSp6x%;qL?2>UT{F_}6-Q5IMD5C7al|Ua`R#pbx%|IUFVd ze4H)NCkwwthb`Y1I#&3pY8#n6`A>gX`8$SzOym zz>htRMFo_kR${(o!tz@%~?q|2;p#1=&x@|$!c0`s2Y;9m1 z2$bvMBbMvdp~oRA-w+JU(n&HtaUJ|=>(VX#VTZowA1|n(Hxhg<(8g}cQW^0Q>~%~C z33d{G6L)AFk`mM4 zgc%2cBfvM=gCn0hHY^TCLCL|SrU{XZH^roU=){gT4&l`(p*V5N@pw;^g!!j&C_35$m0Tbt9X5NVe5^&2}iab+-J zgeThsw#nDvR~MT(Hlbw@cM^hsO7F|hKGj|>g0ND#2hE<(l}2|b(pGyL_y^f@E_mr9 zD~*({7{QcQDkN=*A^y|VI~ivXua8HTeG@6!(nj_uXJXOY2Xs#9tqS8}>b&f_53Npi zz@@D+TGg#!tDfDLy{xFTv8M#$=$1?P?SA#fZTGc57;XuI_X=362XcB&uHTVcKF_*v z+rB7?&^rM5q{)mGl>kTYW&g0*pO<&+fAv#>9C^+ddgS84EBfu4us=8V>%a5W+xA_r zh&^+i=LEX7tIuqqJFY&ISX{q9I~|V*-ls(OUyXfEjy{h{y*CD)eo>xz=a*Y1xf@YXYTT(%j^$|JsMCkbJ=EI|&<%#BOD~`dRWM zhslF}!JBVYkLagPlA@zFH24gfYb@XsHr?WP)UMEluj7ZWu&s%e-2#1P zoG@xgZI3)DBoI+jCm0<5|XMnh!yF&@)Fc3vaL@#g6MaZ<<1 zoXf80$l<&^!+X&UT9cB1ONcmYSCMi0USpK{1`#%PZbHG)!ROP7hJhQPuJ$%3C z9XoKe3kn8wP&+W&o^$;f(xts@0u71mbD#wuxseBM<+=VIeI>d;FZ$J1>et3N_WK6!v*IVjFl!W~+U$Y(i-pf)KaV2JbCD13?^&!mqUu;V^esfkHdi;aug-E^zYlq~_w7oC4 z1YU5#wtIT&XJ6DVe46h|Q0PiXE0KWn(cuz~$p9GbuEiWaZv5z5D`6kk`QK!@+Q8?3 zy~zmL3lHCeyrIv} z&;q~kz`$V}=O)7Bq>~AQxaT2GN!3HCR{dfNe)@}@=w>H}{qR$lG1y5vdlI$!1xFiy zjSxG>&^3h0i`X)4A#yMiCj{#hh-!}oOP3mf_iHB~fuV)>Cx02~-$Ti&1ZV?d8 z9+f2zd-QtL(RExO(LtSRA06YAEIrE~dioSM6BdqEHiCKrE}Y`$+Ij5~cr?i7!?D5S zRD10edFgxDnvE0scev$3A9`@QDPu(lUA7y6AoS416CVzpPvyvif4j@CN#o69*1W!} zotlq&i63VKZo7Z*$~?830U8;5i!m}<^)`Xi-9Tm&f7p(0>|&6&K8FnCeZI!VX0^9L zCGbw2o74?<*KEty9yVi_IRNWxv15}j+ks&(JlQO82iv8owAekLKEy^C0f>B7Bk=iv zL>+p)6%l$w#sfd`Wg@d+ zo+c`FrH*IXJ1(*s>+V44u$xsUm0OCCGc@V1-Yu5|;!X&f6vF34KeKJmdub9{0+q?o zU5mgVv*k^@+imx3`@j0kZTqaJINgz-q4 zljMVXVDfiH$4m14{=fON+wP^AJWD!Ot?7HozY{%4P2Wfyd?fGr-(PZe>Lj8Z+INrL z_RqL5tM~-=^ndND|E>H4dxdSR@~xb$GMTq4=@1F&!mXqMrU@{GPHNFw*ZneP}IhVBw-Qeg81I2w3mAcZELb=tr@T@8Z=RyR@+hy-a@5 zB#UH8jx<$Abxq`HCl`KcJ|uj48q@uz0NF#&iXUy0g;SH{>7t;8_FCCH(!mZ*cO-&~ zKHco9IM)C14gXwLPW~O6x=%58}CH~S&AGLbY>53(C37YClr=Qk!E&}Jl~ zQ8{op5E&xRuvrv$ZXm`C3k5 z!UQv~M13GjeBA)qz3i70ME`f>jH9z69Xi+r!qm|*#p<||0;}XG(Kf*)ecI2mXKcJ| zUf)PyaJ_8a**zTgtbJk!eqj*09$j=|Wnb99vvCJ-=p`_95|IH6ybr-?tEf395Dh;| zBbxbu6Bzo?Wvqly9!op!R~?-ALVc4$!Uik{%oOM;AAJ~09^Z=k_XnVylvZk*MHl#zxLm^?a4_{ zx2FE+%AX9jxo=F;`iu+mpxft#PV9n|porf}77V~o@oLb_k$k%PcYorxedZJLcFH8Q z#{hgNln8%CJ{QM7pa0|A_6t`TN} z_LO`)M8~gVkKPViiA>V8^5%nK*MxyKR+6LSWirsDmvjBA6D6%qAaXAG8b=b12^JW{ z_y!qQpL#kTZE~16Xak!=SEgM-r%xmyeuJm}vKzp^$Rr8lW31rY+YB0%93|!DZ*bwQ ziH^w)J=v?1h43Z^8Qcq(Eb-Llvuq*;po1@&*GC=yVjq(P_LA_mQwm)+@Sq<5SBHkl zj)Dh!@I&qF)C4`x=?JGf<>;FNCOCM2T?>wmoq*zxjlNl93LN_C$mN>cWT2Niwnn#p z5Pajrn*arggqF&X>e6m!VG{V(#7G(TF6O1id>C)Gjlful{-GC)*4M}jAMR)?Oi6`) zE}C@Ons(RgJPMRn15D2FjA8qOI@;Dc~t=OGuamrj9E zXpLy$N(-+L5C67JISSnNfJ0HyKZpdfbzu;?-Nq+xI&W>|4jTnF`gOY>g5nT-1X>d( z=;Wu3nkO7E&H$E;e9(6ku(hL2mNoFf(j~2K8K_4?;CH{f@^uge9}e4O;Mgw4r?(b5 zXhQv0uS@$iY0qF?-_=gd15#=NvgN(%-}IAtH^47MFHRrbI6b+Q9C~k>E!&5wqYGPS zurNm_1_qM;p8;mrEwBbv>N{RKOHW;Jdpn2SIxs^-LWLiDH;EdE&Lvw%ZGmwuptg^| zEc=s3(Qg7*N+0wTXo5@5s^l0w+BXR}E-O#um&8jyfwZ?m_>F*$HES@nB%hviw^nUWa8HkpPk9mZR`?X`m~Gk zmc-bl$uCv>$+IJhevQ?>mwMpCz}+4%%?sNvk zB@A9Yp6uZkiSb=o5zU8<@L9VD;K72?7y4-lz-Dw=aw2Tfwd~A3`bxsbhm3IGn^eJz z%HtV;oUh~)6su5*=2;HrQ_ge%;v)=(NjZ9-f1NEJ2}vrfBDUs^*DxG_-c!=%R= zY+w{5_5HqoE*fysfmYKCkF93NnQ~GJ>3j!&((YA3{ghp{34VwIKpr^lr1o}OXOq{gz zFw6g3YcCx6rar)jol@sKa7|tu3hnS-IxvV;WA$EqI1M{Y2kei+m|>9_tRxfIomu90 zzd2`lIO&G8Js8D`(HqjvOk((xKeTPH&ier#oqK7uZ`#tN?^@V6Vm3)fzuJ>+Omb?M z96NCcG+1~737cDG)czqD8nj=X>)Rgs3c1P>{Q7D9tvd+esSTh0xKVXtl$0d>@*zWn*3_;4T=zZv zq*?kzh~3Y|=U3(jqW)aolmC}8VSDWj`9@!o z*RLc{6X9s_&|ZHtA$ULWr}FUMMI+dgNzf;kAZQ{LdzD|V*ZAwR5ZWa#U#a|4&)T*N z^Uaa>q%I;pWXe5p$kP&>-*D}=`|h6|c9uY5@54iwY?JHmSUn;3dS-S3w%q%FcJ%p@ z>~2{7dlrY?`Mt>xgR+an;AkxKEfWFB%C&m^+Er^Zf&|VNbSOKcCl;ueDpQ^evg3 zvlm`uA-{2mM)~Hv+w_r1p)dQOOHav_>~w?=hs?|xG@j_;;l%0}SUQmdK3~VjEgUkSD~8~!o~%n3a?xF#xW&G7 zRHxtR$FBN6r7r?{_Yad8xT~@lu!&dQ z+FEd$4yn$_rLE_2%(b##vKB4%O)&Vt<513XJZ$Z@CUy9w6KfjCK9LjLuxlerG0J9ySnP^7v97x>D9K6&sLykoC!>&6aXYZEw%0q7jRI$SP) zEl<0?{2k-T|GOry0zbfiZV&JGr+?4Q>gh|rZ`*$Qt&uUSMuC4#X4sUTIW&ppSi7WR zthl0=LF3s0ZFFS>0czT*$qzjJW3SpXfv_u3cAW#V6ACtDs}zB|UzJ0&#K{nuwUfz! zSMOS%p{-v8sUoyHykswR#CSWuIUzros+{fO>{7vFF!66_Zj)Pzm{Nle3AB2iuxV(k>||#)(xe+u;WeE&VO|bOM}nW5k1M z>eyXb$FAbTSK_g%c1u74Lv(17zsMZ?gE4s-}M3;uo5#_(4+@H?TS3`=%JzT z1A0&Y>tskh93W)ClkH3doSQ76@0?GeMNa2)JRM{ri-~~bDpAt`|4s^W^sNmAjERhT z$(uZEMK&~MZ0UGIqjIO6oPEbY;EYppiVbXfB&KvVuTQ|Ie;QA~xkeAXey4LDv>pDR zBY#mx4*KGSH?TIOPH94GuZ(Mdn;^C2UxrZefxGU19h3@i>RhgJz*Prq!X1F-^@8g$ za1CULOuUK|*d`-&O8KTzp?n#WF9va*Pi4&Ix~`z=R|gXaY{~eOPi)yTtH;Db+X&`| zgcw}^nlM9eJ*mHbtxw_>6pv-*I^@od2M559@pEi)&bgIJb!Wpk*0>FTC7d`_<;#Ig z9AI9TF5QP=tCwDAa#M{&@Ye)^J>e9OEK2H%?>w@sq_p~={J^jyxj7`BK9H}zEyp~y z{p%;>OvQs!ydm(W==b>8{JAgAONri;#QwOEaAoyO%IMKmcCMPVwP~^9 z$bfD#a~;2G(${YWUxHD0hs?smVYPLV#7=xHhbBe?G)Z@tpx(Zo`22883doV-Ce3X9vCy17fc7z3(B<9_zc~I?^d$!$Gw{E-3uidtP@~Ulj>A%@_&-*Xi z_H$Q7!5|B^w+6>s@;;|583f*7N^0qsPEyGeQk9LpntUQ} z>d4aP96pe~3f$V4$E)+W)DA4ypHh%K6sQors8JA#!c6#gLDlz(=ZC#_yZ`2`R1xg-#oTJ_3l{R(yS-XT!UInhCZNfq){mlWjJ4c89 zCVh_JO>`vtB@21Aq3uXMZD`P=$IxW!j@ul;i3@P(M?U9dhHs2imdMCvb|T10UlRsx z0V_PY*%K~#?V_NUOUEt*;F1a5B`JN$aGRS$XuD;HuTt3Bl)Lf}-V8MM8>`Tqo#+?*KaiD6n*8 zJgdqNx%^vlLK+hVt@+2W$f}QVR^q}Z&4n#o`H>6p9G&9Fpo)5@beJH6*Q!1u1F(e) z)^+~vBTIEHtwJSz@44$3PDhVYJo*=da3~GOz@!t8PdgTz^U}Xg zGw4vI-8$Gz+NlhvDh@Uh9Jv@W1^+mYq|kfjO^Cs%d})v0kfj8`U3PUU;_x5*)OKng zlwv^L7Wwj~wB6VINc779cuuxRJw0s;EPAq06KakUV{MS%QtzPc>Nv?bWMYg?4mx2_ zk*8>zV2cxYW;U?Wr(ioc*=Znmk|0qvC?~mgOFC`q{(I{U#Pl0>V;3Ok?lnrr31oe( zE8j{#fQMVz`HEk>GsxklzdBjdk9b%~2@E;3KZ_T9eW!2Jcg9g=5iA4_w&B-SZi13? z^o z2dg@=J}f#5&foj_@r~RnIzNGS?LNSNu*>^m=kpTSfByQsF8FoXt$0rKP2Ifr%m-@! zyZ~wcfyn;iFWmNd_y33s(J!F7r+-Y|_?DHm{?*vPAA9Ar$w#u{XC}M+h99#fb2_(G z%-%}tLq{U7ucV!Ctlb0s!S})AYg`yh>`oww$l^?r$6q1OdY%R?Ja4~yBvCsN!n88 zmanb6q0R&Q~QyFm&|2&`uaqPqh2)Lk&=v%rdV0)uMi!uR|TKt>aGv z2_+}!xSqV#3p6>l{sgrFKHE^zekenT;tjsDZPIBFiLMDr18?yNfr{Z8G5imuEd}6< zZ3po-K|CQ%#z7DoCAxNh* zn1YE;eSpuPsBL0j3ElwXLlS3$SFj`=cC3?x2G%-=&DaS&0adaVlp0)LaP^H94XqoF?!1 z#d=Xp#}Ndy1JnEec)+2zvie*wyCz%uHzwKNkK}fApE#{@hc?Ldw*BFNRqs59!-S$^BiGu=wS36=O0tq)SNN&xggdb0N5}XeCw$2k9(~}d zH)$b<0#-Yn>`XY)NxLK4n8Ykz^hUEku#_Vk!C#Z4^*w)d6!v5%zJ&MU8#1i}h7aE4 zVh=^~HL2=Y3^00d*Te*^#)llqh)-icgaJ$Uj=3E1YJW{S;M*suN7ICs9l-d&Cr5Ql zJ$N=oM__w63@*oSR*-FzxzoD3Y%LCHq|j8n~j>s%9B1uoox zIjpoJ8=OU>pan-9UHCb7$q*@}ow^3l)gC&7#(;rvNWy{5JC0}js&^UK$)loS;y>6l zHL0b&d?(o^;5c#XfTg{`R6>WV4b9RR$I{dJsp}*ldeoeg_cZMsM1eynzvfjuI_tm{ z63f1>R$qz37*_)$u zH-=ns=G0&mxq8;!j(!v1+B}GacSt;>3On8qxh_o-`471j@N?I1`@i=^+xEpzOXA2X zhz$%9F`xr8@agQm!D;YT&)9%=RtEYb1E|;CN{?O8I83@2KCK3sfCWGHYM+|a1;4ui z2BY(7-?nFv_N6a#fHv{t*MuLs`ew;N1_@lyGC7b0@dd-@^k)J?Z+qZRx4?P7K_?PG zqhozG`j2E9JlpDg!dIo>2*?7>^-1h+zj@nTmsR=QcW=8pa=S;e|D`1U*ILHs+)HWd za7h?X%;&LZCGe(7V!bJ!@ca#hx%!j7X}mk1dqU&f^S9&w`U|$*XIwPyao=*+wvQ}T zpFQk|w10xkrYm`bRL7+Ln7&;k{l=yVrkz0NSXx7fv60E7OyY-! zpD{uveykpz?Jj+)kkPJ^Wcdm_7lK}RlgJJ@QKbz9!Vd)o5%kE@>4>#|{nmYhs zXRs=jam`qL`3<8fITWsvpc~5h-#~~7Fvpg0LWb5&66?IlNMiwl8XgTw6Td9|DaZ)6 zYXUGjU~-{Yz#2&BxfVuNmW<^y^;o(tUDovp`O%yLPZ{YrCILre!azrdZ`-FX)lplT zdOpdu8QEM{9u=I)b@=sGfP{kPk(Fib0?&XA91y5P>}zc6kZBL0-dB#Z_t?arY7>ee zH1NmSsv3SAG=ua|zjP!J8OksC=-@Zo8-xjw)%5PE|8(1~;YoOq;UQR_6xpuMfJq1M zpZ{sw{+mB{+g+3ZD&ZRt`cD!zXrg!RVW9J;w$UxP+UMktmSingj>ZD~%AmDNo2-{l5NFx9v}S>bB3%%=W8`c`1uh;*Xd`0rSZGUTaSvoO`%_R)Uv#Y2?7=SV4qt+s ze%E%stzD9|-K^Bl#%Xc*O6?q8{0F=-AfT8mIQp4j_Lh|G7AR!EpUh;@5pdD(#3JYF zmycG?;An>fh7YL6Ka<(=BCEtMVS|-C>A^o-i+f}OlSB1YPaYq(aIMWbn=RVxQ=0_0 z@`pbBb!kf{v(m7d0_LVgo+6D;!i z>Lea?(#Nq`9C_699q}Bq-Ld<2r=Rk$?LBwc0Z^GznhAuET;|y1 zNs$RM5@ws*Hkb!0!t^{wIVAE)qxY-l`NFJV>Qvx^{(&#u2sz~FIXDI%2ml}q8Hzt- zP`_j%cC0GbvZ*iPx`mp=*G0jL3AH^N=<2kHj>jJSaBzmz#f&baLq1n* z`aFg> zD-66Re}61E39!3-Yh%0T*S7t&cWk?#ddIfC@uqF})*H6nyR)UgkPk-;!^FqeEFY2J z@^CAmRQav@m}k2_M>|L#s#xhiF8KMT==Q$Y<%Ucc^MK#>jMKO6%YN6k|3jaWm2Q%7 zigDOLwQMQiGLrs@nuj3H4)m!#V$b?`>Wn$I5h&-_X+T7e&!aEUA5Z&dKRpi^zAZZ$ zSLIeflF2P;e<&2X9#6pDuFo?Hw`5o4%>H;&6J!%r^lQS*PLJ{KAve16fd=^;*@GQC zNC;;YlLmYBRBlLk8==(34+GSS;uH2FYVK&0PF#z)^>fDZfMA(5|1jTJlH zC1?{Yv^o2-E1o7v>Ky4vHrJ2NHTl_AoiX8dMdJCsyE?(uZ|s97yW|n1C&q0hzyW z2KwL&Hp;I=+$2?`)K#DlW-|DZa>zC)uZc;?FT>_|nCPGxyNo361bV2{Jb^c6^d2lXB_E!XvaXk~$ux09qg;xXw+jDXnfN|(0f8iRKbH>s0)vjX~{`2Au;d1&= zE)jX$YtEqfK$76!_`E!5^|_fGY* zzHKMPk{ztM%;58*EcN{cOjaCatnxFd5D@&*VEFg8jK0KY1#!nzb>~H3YDeUcSd>zq zj2!*7J^d?yWEWyDVBMK}<~Jp|-9IF|XJ2}86~2R`)$e+3_VcCrw>+6z4oWc_5`Ao&$98K$tk z8ukx~!hVm6j_*Hf+rRNo3|R@r7VN+$ByTHm=lV~gTuDNr=PMEbo3M>Bt&U%(zB^Ev zJeX*9XNjHIMUj*xQwa)Bwsvfy4Gp|YpC!@R0aiJ0}Al14lMAB~z0q`gP?@_7pNm ztn|POzNByA*TkD^_IAxq^yVFj6*mmok7azU_5LQE&$Tm*H zJ^y@Km&|tR}y}t#(p` zCfeaJadL(aRP}L=^;CQDVhG2H(Y9WfKZIa1D7uaehcleRd9DL5@g4?A+TFYDF9*U~ zfN8sf=s!SAeqPvu?Lg&h$O$J|eK5+o|kS!Sl7m93f0PBISO&AU{^~Nx8S5t?V;$>&1`O zSaGvOf_AWmolIIXzB)-2Alc55e+saIwZLj@7>DFYFdwl2jlk?8jOQIZMNX#%;vCsO z?GjyYYoh6;L|^!{ZT~Hwy6s;0`VrLK!gwf@J_`_Md-vP(97S%&JU$Op(#48ig5_V` z(Gc6Bw)&pLCRCuG#LH$MsD+1CY{XCbUp|L7SVH2>OL&+FTrTv+D@J;HYx_{}678tsr)7uOZU}$Lb zI^Hx@Z#3A5Ja{)z(;|e2i|zn48KiwAMe>9|+Tp~#dMwcxs%^6l-jUYAEm}csS%b4lBxH%#f(Pu# zQ+8q2m1dK7=tjT;E#eRuKH!{_Z54QjqBAwBItp|E7$?;ghu}7WrrH|=`^w-LujufX z;0IbcsqES!hs(tuOc2SqXdWE4e3G!!8OzRzU=XW z$6olkMi9I+_yEai*2$pVk3ivovct&s<(m81_q-xwlL#1v#-%(LjzNP zq`f!-Nu6Z$#qy0ld^b(j!~}<3!*ARMm_AgS2T)%s`W$c9`QO#EzJ!;=yL-zGxp(}o zZFkwbw(a}h9)zs)&&c-r=?M_`2JX(_x>r9O2E|d*bib3sb!weQwtjNxgrSkhMd*!f zf*ce4He2~;W$*vAQ?~u%A2lYN_rzv`>C%Zk71t&_b_7!Q%~|@&*O$jL7O@N4+d3sMJDE_JV01-F{@|Fj3F>$y=BJ)yx7WY zidqka;x`M(_|2caZQuI&V|AItRX^dM5`y5)Ms(+EwuSkTWGKlg{6*m>e64=;~uM z>4qMj`U{Re6Nlgs3=Mv)eaT2J6N^04()w=I2iIiJ>YN_S_u0dF{tp}FdTr0Ela!5r zczkXpTepz3k=3f2jE?Nxm3riZ$Ii>gL%KT@n9*h3wqa*Ghx(5WWLkEtzJXs034G8c zGdm=~7aqM-9SZ&7qT@)8_I=>VeBb`Q-4pV%lwZ5|;`==Wh`>lD0$B!67zMrj?w8~W z=ub)*OUKeq;SYE);SR~rJ(ScHr*)}!4ekJQgx-<5F9VH0&wgT|5e+HKhHiU4s@b}-^ zK!`zV{|22*8VyQyj<)pUu=QC%Zv|;al%&!>-E9cX^3YfK@CRm3VCY06Y}=1V`m+-T zvwLloEjX{gYTLc!4cqpLtG4Z$TeWQ4)3WvG1x;5a0C>+qF&uxZ1&7dXl21a}vTC=S zx*&8f$!(L9BEu(SC*iClc(3!lLBM866s=quU<#h%Z}0~<>qd^lUE^=Cm`y?)@|355M2 zEBGcDuY2dV`+fg0{t!L=RPRHfFg?GB-S_YM#;mB5WcZdM8AxXOly68L>`?znoofko z`Aw5i;J}A&pJPd~>rM%Jw%DyA*~3<}chx)B7wpD|9VK_Rm3;WU@uAP~MSE?-gT)&R zdTRyG{>Bbix=}}eRIcFQng7K@)3pM|HNEg(`l6wJ*?>GtR>_V|?ep-INRdMez9QkX z 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

#7MxBFu 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≫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�iBGZjb2f?EKu0 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 z z__5Dg)lMgq*EL*Fa#bbsVdpsOqJOG`DB`{=8_a-EmV`s-n+ep;F>-#ZO;Uv5=M%Cp zBWHZy&bKXGDi09m-iDeDbVz4s+r<@|GdB%qsXlLEk;qNKn`?c*E9u$$u;L+r9P>2;)AI>#P#zw6WBFKE7#SWetd$~}F z!o?rfhD_ z3gNTpt0){W)G>4t{u!wBT)DiqRxv)K51KPan)hC6G~xmkU!U7lRaZMZTCW`_XgD8N zS5*xsXVbZ6R@)d%T)a85y=;+uHV>+Bf!*ckP_tWse0^5G5_P83OG@V+f5|PRG2@fT z=lElM#r3avL%%%qYw6cG{F=f2UEgZjzr%d2{$5o`C~17CU+a;I*}DB=OCjSY3w_44 zqAt$~?4(rY^TpmjUMq^5*9j-Q>HZn%=Bk{u&?PFFq3kj9slW_|BXUu}L1dgZ!_mDKq$18Ya^CDGN&~Olq9FM(mZ)a{CHJru)3>qH>RyY~Ug-kXv z=Py-DK0Z2Fu+Cg?hrt+FlumEQQeH*T`cTS8)zd*EjB3Mt2B&$Zvc^(n-Om=Z6Mx8W zTQ~i{`OF^F27Aoo@e-3}Dh1m5s(wiA>~KCY*HCP7)g7gfs@fq_+_~gz{)mE89yFkJ z*?iq}-u$<9yo#j^;jBAyhN~En9PjA1@Ho;S0%hGYai&eWKk6uZ(%+McivxQ;I6}2j zHNU?PT3Ntgd!bE%&-uxwm&Rxvd`T<&&3e1hk&2p{DrE!+Zr^95Rb4Ok_Z_ZK<44@l zA$-C3BJw{Li}3~hneV(kC|bKceid7M0oI%q^E)YOr3SR?Y3ignt;O>eX49>iB8~us z&+r(!qIEiVc6f`;~B(a?_ZGiVY)Pg zJ9t%n4BzbOhKR8#g>xxt&C}4>a&ne!bCS^SR1gPdq7A$fCbRxJik3y^sQTBVvvp9^ zTRNMmirev`TvA&#KXSZ~0d%7-cHO2RY*`5cZBVv!PQRH3#ZZ9irO#XV$BH+4HdZT=Q!79PBkKJbzwUd$bI)wNxYerc@aatL_Ua4vzWS=rByYGq z4Kp8d!tJ2vp=wph4*Bi@pSPp5GN84SQWOaGq9p`n)#!j-zc9;jg#uR;&X%pasUyfipu3JPcN#t-vnfMrnUh8G`ef=tEF`K|*%AJ_0tW(tELt(fa0XUOo zT2tvsRyJ%k5|v+iM$2EeqGdbMBN%*ReUqw9XFm8k=or7vlRVT%bmQ;$^@DM9wR_ zn=2ldgEoq)&SPHl(+tNt3-=$v*4A^gHS0JXZ&0V7thw`_))kjy|Dcoh`i{yw;tJ?o zQSSD&;1(hL{__ylqH=%80JZ-3<09+PS$;B>L8!5D)kDp`bZ%{AYy2F6EO5eL8MJ!%m5o44KMS|ebBU_H_=dEzae&G;au8bmn4 zpZmk{%Twdyf zH!(|y&y}vB@$!iBZmr|7pbj^-vDpg(gYD>ux}>0ps;t59 zgkooMz!@WgU!Ph==##^xE@=s$xL=1IhZUEBhR?3-rOvx$UIO5xI?rRBML-cvP}FlK z{?L_=uMPCF!7)&*t*yoC)~=3^_K%(xf_06ot`ahP#pD{_#^E%yKeKclbxS&Z#Lx}& z#0E&Eb})bKxI*XbKD^112Qz73?`l1=KL+*wlcp_C-9Ps~1UCqYQ`2}$N$Q>x)3sNd_&QBTab-gY0v~J_DqJN)$Lr%dMVX0>k5hyZ@PI6w^zlYpEW=vaEUfS8wBA zGJ%L<4(>CXTmjJK`kbPGP^ddQ6-1)w1L2I>;boA>p;trK#5vl!~l+wj&9tYar; z^TeG@d;4?T@{hGTkDVu^tH`t^bb`m8Y)$<#>GK{47*MUSTr*()3xUj%A*cE0)VMxv zzhkE(M@M;lMC*VMxG2Absio_>r_tSl%njz`(-xHCmpKcY3qaQ;ycvN+H@N3bxVX9_ zfOf9~@JL$Qs)HK+Bmk^=#F@zNZ1tzVdXlQz4c@uDwD^MSHp)k0@E5N^r*u zlo5+83tHMO4jC)HFf~OjAx-)(GV6fNIXd3;z?&Dctp+HA+52d@D`Vz)7%kmUaT{|! zG<(hAii@ZI!YLkX;yJIL-lOCvM0j1Z0$|Mu{X21}M`H%jZ_-@A(?^n<_RP z{-{`$ivZXsB;KAU;}Niy{#n)4?y^I3dsIlI^G^T+3Kmz^m|P-w=>oXZe^E4sM4}9!&c@>vUO24fzau^uSFk&e4Izo}pOWN^qRTU-B7 z;u%p;2ceH=T6`^?qjbtnnufmuFsi+V*rmFlk=2oILFJ|PkzZ`fLwTEOY;62@;NW2P zwTvcHl98PR0TT_n1_9?mKoCltI@MT6-(fv4L?58u>Ug|xHTTc*Pc@4r<$-EX9AY*Q zrwV)GQ&T{8^$X*dNFNVVB?aX^+x}=B1j8an;_x-|(w~r=1}z>YKk zb26w=H6DMz9V2It?%DCMPvpx=d+jAAEosqR=R5CxDf`%;8JnT^o#FQBJ`DD$KA^{j z^+>YxZFkJ*zSW7x0?3t{nBX$G5Z_}j;n{~$I+b9k|EVj)=a#nK{7haq$8CrsB`q^^ z{7X{-h_<5ME#vH7aeAV&~7e9B;x*A8;QobwA*A6*)4yIk`a=l~~>{T%O7RU~J#w-rH*a^0O>}!H)p0 zae!9~1uCw}g=~ly#2!aSoWUKRP8iIX9crHYH#?ia@=tX10-!+(L+3|+8%@x>5v&#f zdRuQv$4e`*0_RhVXU7s4Ob zODzKkGURw}#5pJhP?g0Yx}R}z6*#{>ZFJJU^nwT;%m5CK9hOZ3-Z;DO+ZpjxSb0Du zcj`OgQ#_pKluIN9F4Zk0{=j7NOjj37xZt-2#!IMYvVcm?HwQiTtzFV`%dyocVTxEs zC+AObJHjZctr@G9voT#~-%dO^zcxM4mXXMWXZkJDo{i_I&3cqvM<8TG_^;W5_+5M2)b|X9j7#D; z{L`)3`+Zh`N<^T(h%4#%4DbNY`O})MkPA2C9y{0VKf69J)NH@~t17{-s`~*fqbW;D zz`8cq{6`0Bl!9tu=~V%F7@|p7aD4PEK9xwCB{G=|8eyF0nvIatf|-nzZ>O?fXS?-C zQPLAoS@hZT8u{bREU@-NHg1l6gWay+?(Hj8Ujo>BdkZU{h^gIJkOme#j<5g2Jt>aJ+*sF+togPe2E-D{#dZy(ZeI$`y8HM>rxffv6KRORw zc8MYqhR|zgVLC(cygZIsH+9H9$dU4a#f=9ZH!Ak%5Ak{o#sT!An2E>GowCc}O>2i0 z8JUIKd-`U~f&Y@B;_Tdnjj*|UDBEMPUW&%cm_+b+JUIDmx5l2M|y@)NNqO9|!6of_j zAFmB>h?}qbt%Hkw^?A9~*a6@w2E@eN3K^?(w$5HV|MI83!n5i95b7CKx7!jO;q}-t zEcO0+BCYq}5V!VXy2?@%gD2r}$#`@*`LD zJ5=Z0Q8P=^sD)OM}Y*w{)hPRU%7A`@&Vn<>r7eW#;)u8BJHKkQIQq#J@Gss= z#igOu;UJ&@UQRBV?%okM6(XvAAtm5HKEkV&%6W)Nu1Y@(Z^o(Maiz!Sq^kV#&*cb5 zI54!kce!ys_VlWI94GuH=k52()ZDq{9QsS->q^}`ZhL?K^uUk$ch6#DJku%bFNYC? zXV95~0=QhrJ5^$wy2?Ga{iYgi$l;GB8y&V4_TSEY*9?KrvNHMoJ$Sj`kG*UWPi3dc zdR{{)qs~?V#<0gXm%S5_)h5=2^BnBG2UHa$Q|K___R)LX;mXzZk>Z-1Lb-qd{gKt- z?D#(9LQ2i3^SB=)ormQN2Ze@CWqWkZGaIl^O}RU+qHYnlu4HtBD%TA=FR1qGTN=Hy zZyR@CeEvk|NE47k*}xltC-b|pM1!7|(J*F2-6M5GF(TW21-H!|(I6);tkj?N0W zt0Lb3kcx)>@jAs7(Zd|=#~YsU!aM-hP~tN52E}Hbyojo127!IFxv}#x3N=bD(ue7L z?FPaw9r_j)`m-DeulcnaDc7O1QrV%Hk+T%UjD4Ak{+&vxl6dknz=lI(F<|wRgB^qG zItROvN}j$gB8#-;xYg?-lhFxo`q0s9BqNLZeC`PS&9;25WIQ={hIN*qcX^Z+M`m6v z3M_GF%OlE~HF(QO&;s|ok}kj|sCjky_nm`Z?=pwxgg7rEp3VziL~MLnI>@RxTFGjg zJ7ou!U^f2+E2UXDJ3u*j-p=n$y-Bk_#VsNsa`FNA;^_Qh=O3X$)k0&!Db`YMX_C(R z>su754yjM$lJCHQg^AM&x5kELm;;aa4H(sxbNUM!(=Vgui=1zrf9*M{Se~Y%b$l|$ zLz1o)FTdBYSbDuQYL1hxJe%W0H9=ej`F95)!KUldK6Fsj>oF9w;rX>Up787&FFsZh zwe@HBgN&`UmadDbvCgQFl0FUyyk1pVt*s|aeP4{wQ#Sj-;7PqmAN+c<^hPY~IkTF` ze1Uu!wIjiOn1~?Im}w5ojjmRPZ?k#_mX}mSkjsaY?Vl8$=|oZh?nLra{BVUSHi54$ zC$sVHMGzDNh!FUIsDUoNeITo=p!y&ismFIfEK@Li{MO9Ef(lCru2q0txM>Mn49fsQ zJZNu`FBl(|;F+#q>``8g8Xi$U$OK0^iu~T#2EB~F7L~0qvr;e3;s66ezDTey@fTwNSPKb|OInOyJ~^ByWk!Un>9Q=AfOyTMPnU3H_e;hyy{>+} zOXIbNaQ&?Exa^y7^4_l5Cf`o*u~~lA!$$+y8v!W28wt?Y!!n*~DYRZ_m7G>{IQu=K z_2>tUP}}T&Xc8>9R^iIvLd(|`a~rR7z*&0s8}VD?PJ`+PWfuKk@5Wvk5{y8^6PBNoYQ#Pv(aQ^pQWE_ z-1uG6&XlMHgoZsW69?p4+2WwR` z{&cplEppVHk6UaGx>gtH1pZ38S-lTG@+LfvuCKSmC1wMDt`3$V{a3&k6mR~(3m}W( zp6*d*Wv8_j%Lp4#n69xEu14)7(|UQ#92d@)OAK4kQZX?ESahg5F1~2F7C|6zs3YSq z%kOni|1CLeC!;MXVkct;%P>l-5-Kyg#^YvYsj$CTXnhsCevR6FtN1dd#JBd$IcAJJCl|Td{5F_58(ZsSXcNX__)hy;MLx0OmfX zhR^X`9yf-3un}8+gCbUcpw~z&bsJh*Sdl;2nhzc=SD9Ny@1&N#9v_Mp7pOW8EF|2i zSU>b8MDj1`N?l6-Z!Gcefu!(VyD1k7XeZ>t(Q8+GLx zXe+Y?9qC&`w`CB76aaljbrK>L9m+*YXG`DY-0Y994Avej(478fZ^{W#vRrtU@(_J$ z-7C0$iMzUCG?~oZXl0DCSy{uA&1S0g{r}=X=iK6vua*RsL`xU-og~$VetLu07{nn= z^9~%GD!^{bQHot_B`wgs*E);70wBa*=I8m&wa&E=XUmrc0XhKX<1HE%&7U8YXUi?t z+T$j@AG-y=T6T-GgMbMe@|~3{O|^~e(yk(nIFU|Ey7k_HG5>m3 zh|%iT;V5R82jS-`(l%qEBx}I8{M7W5m*ef#bCXH0#7eRqekcWy?c0eTY4-DPCNymH zN*p%>`^5ZV-T{s_Yc=J?pFN@@W}@v!Dd2>?4S}gd&`!5k9J>$4bu#Qe-{1y+K(NSE z_={zJ9GDZA(l%{5x97Bs%@zp8_9A`32xCN2Eb z++#6MPXBfu^@x;zzwqiGvBd+>x{}Ptq1fy{XURIZ^R4tyXFnH*h6x}v(7>x*_7Zc; z{x}f=jh*{i#6CksHE|_H=!&U4a9#|Gs@#Ow`4_uD;Wi{ z_Xbk$A%^2w(}*4k9Ct6^36ZE){N@el%02TlwFQ_c3GXl8v%@Xdx~&i9d-?`}><)*l z!^=N0g@ji?qcTs|RflKK&!xrrZ?C8&(m>quuu9}>{k#aXegc@Z-WAy+^*a(&I>cS> zj~wfvIRm%I6K1c|djOv=msHIYm-2n1Qs0$J(?eHYtS_sB!cxrq$)R@1%bpd@;%j_7 z5eqLQoUEqy+MD0#O~FSpD!DuOhIC>t%MGq8*S8$gd#MJlMIY9Z-K{9!9_vK-ojO0M z8g=LrR+M$K#ZLJpYnzN;LE-h~W|HqC+5eepDg^!=2Wnu|i<<&_~|ys!c?TEtMm1qwEDOMuu) zv+u6PK7Z+)VsZ1>B3i0sD4-<0bT0?Pk&GQZ!--~v0;{j7@h8+5UfujFIR0_Max?3Y zf%O!_f)Z2_`Pwnu29UWB)#~qO)qk0_f6fDokmbC1Bc`k;r(R!DHYuO#Ks~wyiNL#! zer?N^8e{yngYT@f7BnI}o)kIIyKka#h%yZljI$!?-0MyBTht^_yQTOPyFnUyWsaM@ z^U*8GK7n7etEb0_hF;lQUq@Z)qYZ!NTnjeQw><07DptqKaxwom3I z!*w3+!86IcuSBO&FJyIN_@piZ3g9T%?F3#PNhSVQWdz)tybg=pZEYZKQNv`!pQ!Rs zLyT3<5u?&fX-DohY3Z9e!QpcY^pJ~%RF@qC+PQMNzTs7^Jn+jnsaR~~qQb?AFo8gU zrq=LAIo`(sOS zpX|V)@(ARV^ap_;5GE?Yxlf4beiJPe-9Utw3NQ_4M-;uZNo?u%+bjLcCB zn#fXWFT1UH&Lzd_e<@KG=vd9zEYEb2jH5MiczR{&M&PfCD(CefFhm&aDKiNOoGJYG5_g%Zj<#j5$Y?4UUl6GNy#PXWd@=D9wj`s^<9Igg zJXTvd1~~KzX&f2eJMRmVdnGrM13J0i0TX^sx`~-TyUVTQd6ySD=`bciuo)kAJ4#Hh z0q&25X7NUBl`~4UO)G|_3D;EYTy41&MgRqUKxhdFy9G%sKH9q4vraw6gmbZ_B_wr> z(2Jx~nTJdxI)Ho>*`%R~nUEuT$ig04>Caf5?!nsg~!zMamLAUX)-;q}PFEEO;B29>YiKPFb#)r3pd<(B*_Qho- zc4q$a*#e=n%jD<2IpcZZ@2}EDfWUj(GHsc+!kHBiMI6b7)~ql&kWbdc3iu%<1AUmU>e^c54_&iWJywe1D z6K|hiDOaiKc-E?b+ZC0VB&-l^{p96?&s(mpPcEU9A795F8!Fr~*py^t={~UX**KZJ zjQc?;wn@bMjtqpElb1~gGb+!1j}O(AGOjTK?P#owIca}GL{IB{=6#vV`FUQ8IozAH z%=>7VBdrZLi|pCExY*qNEBjS+}u5?Z1mDTN-Y17lt+*wfs`j z@N?S3VThL#OulAHs3OrCgmGB1)Tm>0ydj73y-q$iNUWi!!q*3vhtoPHWrHSkmCG8t zr7R-lFMDVxrMu$fYt{6TLsZbNwtJ-jNpC54-smk{d}Q(u0=&-+?dl=G03eOECoeI0 zmCJ;_EQqw#>?^k~RzFw!12q1IRt@lP30Llg2YMQ#7P{DQBSd(n7g3GCTWiSwB0@kj z(E6_9D?iWl@f^3&o4_QQ8_gUX4569RQ0`f;c9F|$i`0E|aJXZ*36I!(yoH&WS&u%I z$npoFWebfYGB{yY-zx5!1wQJ63N3dcF~prRfm{UD%m08Kf~x{pm}!H_*l#WDz&*wF zJY=6aJ-$T&k)38=aUgjq_X9_eCsqUU#QvL^Ajy0bjMQINWbG*ehgPbyYVF=%1ZJ8B zs1b!VTPO>vDdp`7_vM*b(qeOVwzbC`jyIyzbzjf&RZ7=KVYpI@f$%jTo|Vkb#{cGl zBZ*ux5bE{q1(RJhsAGZR0M_b0JQmPLIP?x?C530&Ku4|M-?KTskIOu*F>wwkoX!0)3(wSLgs!X%YU^38rZ zcbL9kFDMFrKx_JI_4eYyy;S3gZsMTEliojm`jWj8sm1Tj*9!`)4_5!G%2%@jhU-Xrusn^y*1S3Y)@MjQ zd?a@%6hlu}vv8VZw8sfMEKa>8d>`^wOhvo;L{KeZ+cF+?A1PO+_|DR|%ogbC!@N;uurHg}E@BmdwG%UxNVapD$nQd@`7c0K-$B zCX4}C_kx2pJ_<+W-9L5!_j}mYly;P7?dnS_79B$$p1`%EEJ?-IQenk*Y-BX{A*k~G z()20B;3s{${Etc@>_veAc~EVwbu+8>sNW@3b_x(@ej)@|1-E?WH}S4grzd-{Z)$NyqKDxt>mS6aDh7d-UI@pFQ86;1=X(0H zhLaYc<(r;M5M##kf)Ai~H+XK&-THDfSfc}L?4Ui_G3Qj&vKB>%Fkd}}%fw={hvzTn zpR*8M*do!u^WX*m;v&FUYb+i|P$CcA$+fR@ytH6Banmm#gx(lM)HaI-i-s4d_>S}P zkFB=Acy{>F!t^|}AIK><4b7y05<=20qNG1;C$?}m?x_s|#EO}-onauFWd50+ifix; zRjG#^2mLOg7lwHP7{n}RtbJN0l;(<0f)S#x_u6^FxN2F-oUHYEaaK<} zI~zdO+uIgR`<1|>FU&{uxC{gz<7+?Hl^N;+i%;egegJ=C?xQ`wKi!6>VBu(TT-H|FKUH+X%L(2>=ak z-Eg{Xa`QQ}JBjM^h|?ICZzRxXie4&Ys^WLNeE;sW5X(m&40PPn&(T&l7iZy-ak7_{ zDlxV^xd>7$#&!~yZ4ol{-GXxVD zr$#?+((p4C@P*q1LQ_)LN%`AB=56L|);RF{yTvYw(((ZPAX@v3-(INl6>@SH3L*th zS)k8@&2pGm=8Bm&yq!E|mV1AXZniPwdQhX0h$F#ATX0;E5w-t^t+$SgY75&y2R+I$ z0FMYNsZs(G($azmLx_}sfS?l64Uz*Ya0DDW1|+4VrE>;@?ru=Jk(eQdVeZ<4=eys% zzit?-+qDur-4%@m!2#@kk3^d5XDpY3TiH#ha0z3Z#*xcyxIB{3XcD*$I& zdfsUB(PeuO9(?Q>iN%nT_{U#k2ZTP}D#d_UE~?pGXN1{2JeodH;``#WYvN~)wS629 z+Rd7*wdC0A>(F9V$zEezK`16FU=)9l^aZehM)z8=dSH_u{V|Y7oKvi)u9tBoyDPr5 zKAzW@D~jH&tyeEImnw^?E%`s?FfU^;GidIx;mvJ?VLQ#BH7QBB9)7~L^uLSF`^L&2 z3hX$d3ZPQ*%?)AQrVm_yW4B$#`lL1CEOR9_cMRq{a0Nbwoy%TXA z>=`|P2ILn$Zi3hPwSA+1aN|2*PBM#DEQE;;-!reV2#fNtEsFB|%wZHlUn1~-h~0Kk zii;%{XFF~U=mZD^D3DSU3&E*?G*_>r>K7ktJ;;Rt?7sh%^=@d!#K^?Qg=Y-nXWSBR z5)z@fU*n6a#qe-p9h=KV266XsuqI_N2x!w=k_4^LMU3*vS;+nk_K)(tV;rbs!MHBi zQ~HMrLi`o6CZsY8D*|9u>rwNG9rwXkmhAMlf^V|!MdY3Yh>ws=sTj+$Q5EWuD0 zk4`(MBz}SX2#DT=NYOi@o924>%(2SWv2F0tyR4y=tkR;K4N#8*)S_sV5jEJn&@Dz9 z%2VIrZJ`HvYpYnki;OJo5EUT^6$|JdZ0z;kZaT+7%~G>f-{md7-gj7Z&AaAnzXVp8 zIyV$R=@*`FX*A&;)!Zeh0KGO`qweNk{Dn|of>1%Bv}oLecB8{&ob<0a&y@12f4Hgp z`ask(45FSHPt*n-3IxC0L1V7j5Ko!*kzH^eLSl5<7>%^3g1@CmvKmxHV0|8x^1WS#a&*yRZi{TnNcVw0;2c#$;gOB<9!%3VI zu2c8VU;LaOY!Aj0o?hUHKT_j$0Ylf^)J<}$O1Z{$PBCym zENPhAn!G|uBd^@{q4Oh+g5%N^ebWtQilm#X9WHNZDDjqG^g4pN-oOQo6tWvByL6e_?ZXJB*l`@TxVV!4UqT3BRdp0VlyE-f3 z^F)If+B>;Bo|w;(Or!4-%~ru5!DyCzCwf#vfJZz1lW9fIyduhF&M(jjq9$FG1NYnQ zX-LSEb0;7CR!I)@Rnec^?6Yux@HWL)rOu?CjF3eFrf47d&TqJD-6p^Iw=8FsVN)0QQQ8FM#9y+#bFP^0qisibT)cEj75yC`&|gyQ?<>4o>6Kay0uXW-mB z8<0DybAjAQQNiv)X4)sol7QHKjgnVswajLHzpV_;Z+~Rvj4*Yo9^FX6L~vB{_{b2~ z)XNb6O1%?^syM#zCFM236jyy)S=z@<5@UZJQAv`08=eBAgNJY|scxBcllu0#v#QZo z1?Qa#+u7RLyYIAmdd82YbS6E=%Jduvvlz;>UeZVJ3d4;Jyq06#Q3sik$QX9%`&E5=)e%M8 z6clZrB1)(GhX9jvrn^W;YuiEvXG4#=I=dmDpef+}*6f9R@MX*DidR6`!r-2IU<9%k z2JRDisOtGGlZSUTBtzOVM?C_ovO*t;1-!%NGtmt)#=n0~=m*W`eR`EMHa93x^dv)0 zAj7IPuTz^R*3@&?ljY{sl`_zWHTBSjd)wd1F+_FLB+iS9g&GMF{yeKb|~ z#rtQRqc&Ikqp{OMoA$!P7Va091Q!jperihqk${beI`8DY?y0N$U4KQ{YES!lG+9)A zsh*AAoTiZA5Q zaLS@Yx_XaWGeyNG!XPDjms1lXbY%TLUtJ>o_(KrmF)$ZrA$-;DhhAc|5*mSaIgMu??C(anN-&&3$y4rbFnv@Qn}466&lWtjr!|6O)Q7y=ZLN z(NQt8Z_4-~*T)YXaAixP+5vi^^63>L=FuLGZsg)#fUgv^jW^bTr`lJE;sKb0tZb9t zd#4v!hB2$>;hTRaW%hLzFHQ7ZFXpQla2E8{068+Br{~5#rpL1QYX7R7qU`&4kpLuk zOV*>8lABjoc{hp1s7HS%ow5A-$EckGA@pq&NeHQorMroiUj^~g&r8%>uoI5zSEjrQ zGJNdNZSP1Nu`hg4tub->&$bsY5`Ah@;u)U>5+8mzcr6{7as7QPhd~*xfa>Tu{yIvLMlpRBl2W@mHI)@(HRXDY-8NMi`Ij~_9G1w@b z4AfO%$yx)gv@|-j>^+sG%Y)t}tCz<`a{{9q$G<1{4zmg{ zqkKg^rn13!`}2D#E~D7w{_LkSN3)s7JW%lJcixOv-x^T&>V7>h@oszDM~^=cZ2M-g znmk_Y*AGh%dc)$MtX2B#CIU6 zAi&v5U%KV7-QROJoSl?MMGstth{1qEV+9J9vaLw~r&Kx&&M3+csZ5SzZJjq4A8VHG z5yQRvbv|!Wk(ugYCg9Q-L?eAab-74s^{EQd;9S%3x8qD}*{{ZXo0|A@d`EoZD15bx z5fku;Y`GN`dDHUABWcNj7rPjfTFL9$rl*}Kltqf&*Okw*l#;nqB-q^05V&1R#zq%v zQzcSLrY=;69HRRiW%{@ziCqUZdQrWuO;ynQwx`_R5V)=^5NmK+a!I$Cu*1 zT2p0TV5$acplbP`wbi|!i)QN87snzJ_OE>n980|BhpjsLp&!S>Du>;|3RhLoN_2~V zt)I`W{#>*@pKB_O`_y*@%PfqI9^M}P9(AYbn8Ir)>(~AB-($kAR~1`Gc~>)NS?~WV zM8BiH8^Q6f4|Dm1`{eH$JP{FzouaxOv`@&$qSULsa*n36>6xb15Q42R#p&ScS*KnO zqCl4nxMB|=DE`5!Lv-SQv3E}%NT1iT+I&8wbZZ;B!9>4h&2k6{`BU|rr;Ck8Im`Oph&~poY!rw zY+cimV3DZsaK$QIjE5HM_f`uOZVXXU91s9?klb4gST| zB}>^VSNRrQFXZ@cwUwGx@Vih(2i68|)L48sB5^@J4_{_JPBpj!2*5&P!mr*ehCy#n zee;{0s-evCy{*Md!+m_UPry^QL+e&1&>FYOZ82Y%N5bOrp(m*B7QNiw=s^DX1i{|@ zVXrg5Kln_mNFg6X@T^7rT3-(*zsE(1W|y?#wnxsOplY;qDJIKqYx`<~iz#R+;%Apo z)!3*7Wj1>d0_Ala`J@S^x^xWOd{3Q625b2@t9>WM+t+X!QV(>@v{T zhB66)=XfuGy^kh17I>ayP{9vB;iNTcKU&*W0VBCfFAP1{uR|@dJ%lI0V?MPR-48Uh z`$4Il>^mFuo}WEDJd|~c=G~+|Qm{@TuukAWm*>Fhs!w0)0Ht|kR@Lw7 zd+Kx6bBFX%OcUkRd*{Z@w4J}}h(Ii_&(K3v^RVLGMx}hNZLLa5=e$!hloFOebq_RA z0g8cOQSL_H10 z?z51$khMgmgJ$S`;%M#8@2altjadvnltBW?c8~HB9mAV~_iStx7g@6|sHmipT|UKD z(uj*qLg(|S+#Z#rYu6vW=^uNFFTA8pQ|`v4r?ma7ylfY~ZnNKG8GWSscfb$2dt15p z_V7V*BTW?#D>4>8qBa+6T%;yyD2DCLyI$VimfQm?r(P94pcZXQ2O02bxY-5!CtJ0D zQls734~%|4d8@v<@vh|%ZR%WKRb)_A@BWLMtlsz22^x66zVkdUSeGuA19$jIJw@8* zaJPLe@yZ37PPOEL)uNAR6$#TC$6*H{>)yyiDgi?h(Ae~3c5QMqVzeLFu-gujwA7)$ z4wqj7<{3EBc+7c5SaWyB)aU>|kvu!et!n^SHKYDD4}1R7MG*Sj6{%ZAlGvj^4C0IM z2;NQL=i!Yf-Z|&5y3eP>ui1iy;J+ac)xEUc13{l=26@>gWfOXjit#aX4SQC1PyyGo ztcS59t6|WBm;3ojH|v=5UoVtoJVUVTG7Ap(8Py(@1*oh{69cWY2)^DaB$7mq^r($n ziNaF`aq_n2aOZd5%Hw!JuI@NA5et<1K3L<9>J#A0ngUV0`6=RcFNX4~vje*{KQDBA zBwh?5wO!g&ThG?0t@>VtI??`SN!BE~#SMYa$|wmC&D&4v;q*H<-}Rv$2-9N?G3~!@ zIF4;sSU+#xaACffU5BMRN?Zm5Nz8@| z9*c&TbKhPcCLucKiR4#hU!Xd!x(>t>qw+J-n0Q#4i|+42c^YsomrSx$>GtGSI$f zt7F!rb5;5ZF{kn7d6T;fS_0TogB@&2^=-sh#jI}~v}8Y)HuKUbGhh8BhTF`iyZ)gY zHmQkUGjldislVZZEDM=fc-Q6k#iCEpie157v@-$W3qs`#P6_+>rhK5Y>}9tUS`cz} zm!7QBa1gpo`C?ald-TJ#D}I~PVA@aQMu~Z!9wM*A|uk}H)8~q z(Oc|6xDHln2CGOC@a4F1MOUR2Y^6ngJ4@}WUy(Jxs2)p$z>~xU@Cez)iq?zSf1f=j zRcT<_pQ5B+m1qI`cyP@D*;944pQEJ1HBB%hsl5vzPP2_!`VWb{(MiO#9yr&1=kG_u z@#&zI^BQyJbBh*Wr+XR?YOoPz&sH|n-*vso_ya6w{9``@%TP8zyR8F37uDmm3*Ysq zwx4!aoRimO{Dq<9kh>$npcLaI)qw9p=HC9>Xc^yFMsBy#Wp4H-&?m@g^c1+G5z6 z^O)tLYRqaMNh}gsIIC#;8#}rZ1@q{Ns@C5LM`hD`?4GDOVAbwx-hD;V`My9=2bkt(>`Ig<57=Sj zG70fXHCiE#(A&i+5GoEl3{1?-W$m&;+ONTo>|Z0sM1lA2QC_Pr)+A8i$9ZYQTS; zp-$&8PuRU#Z6AyDRh-`{{1BC>b8`Tzpawls=EAx1zgIh%N~8gm|wjx zyZ?&h4HP3f%~uT%9e~`XNMKs-m+;%jxF!!vdQGXw2Ptto%iIHGl#5Y=%DDN3z*y!a zY<_7nlejvakcGkVxAdh&_Q8OzH(RrX67o>#zV&(ab2GA5~6%CR0+gYk_K0*8q-zP=f1!E2~V z{8e#OrpW$V1A=#9lq|CxMlZ4sApsENo>eEK4tkE~yrQ5RgbaUT_oC%N`CTuCkEnrh zq1t(D+9y{1{`}YwR{VVOFNPdbN4Ptw^c4xXVArny$u=oo_n%EouLGKJL1G1sc7RWg zvU|lCawA=W=H-X)uI~6_a{29ssYn($TSmi2JLo+IeW-Sv{5fn;+8Nlqyz#;mjgKus zq{)3^bv7afS5XLn*hYt?Ehupnb`E$ zO+6lwS&q0Pch0^7fJz)yAN7)p;EuQ;GFQ0a#e{~IKOir>nO+1&WBpull8V-C0Mjt> z?8Ye7+%|!OE6j;}VYa}?yEvCFbQmjta_rBAbHD#(q;7ubdIvGNl4IBP4Y^Eo`btsZ ze8db|HbHo1C@j7u(E12ipZS+L_acL>1${u*HbBrmOdP1{=m>hjqrVKQl`c-d#&wih zyhBotS!O2*mfw>ga%*HD?)qNRCLgvhssl^}vZ6UpyZ!xSkS+Cp&bo}d&t@xYN;Ik$F_nzv+5ckidikBPd409~= zOn1pR9-MpTSyT(<(~fZ+$&&o;6RsWExw%bxhI|90=cctbdaK&kO(APDdZv$KEVfIJ z=I|!Td>{*j?m1VZ)Ibn8KYR94V7Rs|cg_}RythEIz1-1jK+4Vj_oLxX@D56kUZ-QkeBvmD$-b*Lj!u>VjH?`LSC z!ZPutdLltxMA};yu!geez75|5 z9U1e^?#Bh^KL2#Oj512zMCsEo+5s zdhcd+CW_iqF8$Z7$A|b{QoH13z4XZ!Qfqw@4{gQHOb{U4m9&_raXTMOey z#he3K9apiT)wc=IBYqcX^cQ13J1{hRW07wyUb;xwcyIoKU2#$xGcXoFw7pBsJEe58 z+(90;eYb_da<)r2k)7Sz$}XNb20DDd103^jC6TC=j$Jf7SHFLtXM6es1rM`j@}xH) zihmj$>2Z1noM%z8NjWA23&jF=P&p#1RhM= zCJ%Z)T#^LL2Z5=0vIerTZEOG(lww%ud;=$>ZL&W2{=Ba$F=vtm55gV5Ola%&z>nI=9-gB#or8~pGFG){-wDs_EmT#Zv8KoSQ%sU9p8r|Wu zvwC&#TB~9{t!2%^+%p6Pcw7|cem*U=`(AT0M#1GjD<*qg)s{(Z#n$H4ffCdnteu+x zN(49FAFCfn--M^MEfNHGyjSxkXQ^7&6!43R48;kQV)2XKu;N^X1?=?RiLX$X+49jw zhi1IqL@;d~{+@1gnMEcY&OmW4o2m(PUJZJ!<_6}tb?;CLiPj8E#OQPjtJXt7tIR0tMPhFTSv9dY zGaYsIWu;7lhrU<;WO~cdmDUx*XMFkvpsPJs)T6%R(bNuyAl@l-_T__2hwcf$`38wI z!+*B^b{HyYb~^@0d(rah=7A$gUe5#2h;!hew|NC};TMxWjomTy+$Ka$IjzozAzbz{ z`n*&<;|$fu-N~1H+~0{DKS$5R1kU%8k&95dD>|G+ff>VH zeKj;`&QJ0ThzC^VMaLsrm0%_Yq@LTRr96W3IDoA@mhM_)!B+WcHG=cD==O4+ZpbYP z?20tqSXpdqdM&Wb8JT>`Yg>yw;`7?`OKuG*QcKQUpZ2F=lnY^4Y|-5G2OvH1Ajl?p zU0II~n_zgQsKp}2(&+g-CJ5Y6E6WB-H{o)EIJZqud8ZjJ@;(K^18}Z7sMJ_11^=kKj8ND5JgR14lP6Rn+0F6rTkC(!=ktAfhGGp{bMz`APf-YfP}Qu||fD#F_0Mu~@e?O3ufw=Tn~jN|VYcukDS_ON43dMGi28hm%LjKq^==Nh^gng#K>UCHdR#U=w70Q zXv+1I&!OkP5g-}aj{A7kxu0ID&?84e*M?{{mHn>kNdYZSL9Mff;$))+XR@t%3Plq6 zEO%rx8hlZ5oxCIon{sViiG1AaE%vOSsYe!+wLCGd;HC<5R_HvT? zi5$po-z_LK+(L+7rAnq2Vt!0P=^XU>;GaE?KZ=kq?dRy+53Z*k7?gfpAb^r?HK3}M z84ZGrd6S;@%i)CU#N))vya<<(ipfjhKA6};k^BwEy+jB?s-jg{R6Wng@>vyE3MNjO z$X!%4zQ71prcHHL&4fh3jczs!DIJYPLHis2q;C0C-^y+GoY>`VmQt@8r^dt@KEzD7 zoZ=a-zKFePC4AHgE~NgDxgp-U+I2o?O2l>L{h3x?*Mm8hO?6*3$mp7^33XXnMlY8` z2g+n^nf7=D!0!A*l0)-pf+klwlBdMH_Ppepm2#*2V^-&n0XzxgM;{@lK43-xk}ml9MEo5J6z?id)>ZRdHUTo$|gSmWUc;v}i_ z-NwV3wD)Gx7Tp&sriw-|xBB}P$5OV%99}^C7W3m4MCN$-l@NjUha3ORc={TZ554E% z+@T%h78Ra;>@?>H0`unV+`K>(!e2PCPs{``#^3+5Y4hb4$#*O7fjJtmzJEmxWS=rF zP!0waWJcZT>l=IhicsRcrN+Ccca#5Y+Zf^`hKCoDg}yf^WU$eTrLP<9+>G@0t;R?A zfH#0PI-#zF@fYS-K@g?E&l9sT&M1DC|JlrQOh?kWM9b$TT2|gGc=<&ot~dnLigk^T zm*8eZY%2s!Q7~DoRp(&Azn_-o!Jb8oezT+SVF5t1tP=`lW|gi2B3#&w51_u85yMz~ z+{)-kWsqX`1?}r>w@OH={)(Z9rpviAzbSL#S>^^|NR>r1gOsrtKHsz}`bDVvhjjD4 zrp!>Tag8PReIa0seENCZQ}Zo@F91mvnvGVIqVHHU0Qz-BH7?n0?4Fi#+Qrex~Vyf<8TPIA7$JM9kZD4hth?L__cJ%`Ni>(ww0WJYGyLod9lapY5ZDr&F5Morwh`w#=g?9 z^4%kF;a{iGxNXjE0JO0%*3Te>0i0SfaePqXjy#y%Kn7D{7fcjr%|^3BxpH41H3jJK zno|^S(SA7Haa?nynY-4hv1l>@F;f;!bw=sa?C5_IdFv4NFw;50qQ*&nGt?^Ruyf$% zaM|p5ierN!q%x_RdZ1oQlF78GV;$pjjHl!O_DS>rj4kk^^Yu>bbq3ohVZ`$b=WOZbD}1+AaHJzjFu!~Ll=(36!YiaNGY#c|-F?u!P; z1VQ}T8FSn=*iZCGz0qYYat-0Y`Frl*bU{3zZ7gaQFY$)yp)sO6Z2s5;QtH^iP8rge zm4-AZQOW4wHbhH-L?se+6uW^;TMVK+1yf>*O1TP!PA6x-<~JBtiQ|kk7H2EGzSKrT zTn-`rjAGyKg)IxQ|YHxzLN5h4TQG0Zj> z2$%dH(BlcsZO|kBh1-v%h7B{X51f&Ey4Yd4YBzI=PfL+0_)jo~+Iywl&u)~)LAhXc zzR#wFTx#ycM7|hrU0{O3P%DDIeQasYtQuw3`zn!vKui2)=Qpg9hXP|(~U*}jRi0#mb9bX`A6nU46=U* z$aR~;jX{B7KBPk?8o+sSi%JQ?iNlf$8`Hq0!7E{f3EsZ#L_ zprWuF`l`LxNz%zql1?hUJtl1d#)Y3h9e35-kc~Lz$@NBw+U>WCfv@9b(?84}|EZuf z*Hf8b47Lrj_^g@hq>(E0s-9sJ>en_2tcbTK)f#&j{nG$-BEpkZ!d;k9Y)v zE-*L^q$c4{+!|J94Qf}HuF42#mc!Gl23Bw3Ch`$HSs%K_2 z8El0r5wW8K=f=a<X8Yg*f#!dO;>_Ja% znfNYc6?JjK^0(VaUH8hXm`N0$xxCC7*~ip%L_K}zY4$#ot7kE#4s=YWN>JMJ6H1(Q zQ2j`HPFDb0=)wk+{4FtI0)H~O(L?C#s94$6GcOZx(Eg4W%GWM{adc!SWCk9*PGO7{n-NrKVA zOg1`(*;Dza#b5D{Z|*Vw!D!iiQiH1|K)f`p*eSniinHfUO8%E{4tm$89-+MXTTu&; zZ@+yo)ANrXYwOw_Bklw0lYKOEx?;p6u6Q{{8MNAiV1tgA!o$%5@SA_07!ZJNMFxCz+XPW z*)1L12f7}aKU%kNHw;@1xlzG->yz4DgwU$!?gZyv3bdMefyM*03=TA*fbBE6WB4(T zz!#E^iSaf7l`zUEM6uvzKPdwEqeXJG?a0>-oC91ky=o!ZKZFx&wi_9~vp;SX5H5MJ zCUL?dnAJ<#dz<4hSv?Z~Ea;>Y;qkTye8io+&^#i*7YXe^h9apbBm@TTMf2hIOM0&R zvC<(cj5tVpYv}eZS~dDY(yjM1V#f|(Yai1NXSoLGh`vLD{o{}QgPaMzI;CDRMrZ4z z3r1^#C!C#u>r@}tP4Z8arH^#;**H8qvkDt8Cd!^sY4Uw(20c0Pr&3NzvUo=3lI!lEQ9q4kYjl-)KL~j4 zg8g#5Tnr|VLr<9X87@`#!q?Ar3tv|z+Bpxud9WsU;t=ol#3zlLmt;ZS&(T|9>2KLc z3Tr&aqz(}F`4Va?!|EQ+$lF{L2qj)hK{BN~alR#mhUHNlsAgPm{Q|Iuvju?~J75UBRQ#9#{HA>zAZ2+qGF}2@BU-GTV;`)U z9X-5&A~?K0uG*Z~iY0|QP2=f?lS!aDWi>arXE;H|W|F_Dly@s~7>?o63L`}7#C*~$k1 zex+r?p}2KGQ93%r0DLcG4+sqwo{ z&A)s`bP?RR3k8XwJaPJw5RB7|g+Wi*YFd>ealkR%N`x0AE|Jfvl?wja;5(`KBD8&O zWY#!0UZ@=paj$hrRK0My8q>DYoR*>ty`|NHR$p=H5 zg6Lc5NbQ3~S;zULTmCQhmKcH5HGDlnc;a=ZNEubb11sAiBj^-M^o|j7LC_ohgh+S| zQ>&4pbOYvW`Ac{7h@*;c`);Z_7ytRp=N{>MS5Iu6@xy7hM^!93 zHBN5}+MOD`CS4M1X<0oGG5w+nOuOeG>Rb40HHw`nn-Va!CDr>&94~O6N>R_Hwk+dh z=%B4Mk5DTCgV|U$jEVM7er!Nt1Pu3H#Zv`>d|@~FU!4M|RM7?Cbivc-2jm|l_fbf1 zKR6!Am6>Xv6(uz^6RAk$I)7Hi4d7-e;?LDt9YTTeU|nNA*-YZ=!zTRw4B5q7-7bs4 zi0MJ;vWF$Sf=N;D2!gael_TuGKSL2ixO7CTxLlCzf#EUpD*4a^HMq5j9i;c!6QC${ z8YDW0P~IPajCfE>*iyNcaO%c6P`8{8Oh%J31UXBvsZ5+TfSvT0>C+yMLEyb0;{t=h zA+V?b>E_3ov?_%1F?Cn7)Y3)o2Xx_@ldm6go<(w9#|Oqh4|YWN##i56-;{|MdT;ju z$z8uhyGXqL`w`KX)!W=8s+nT%0RQH?fP@sVbKNRiGN7|1qqkVf@zVq|RQ9=BdOP?(W|BjF+T``A_TGBehTQ7U%F7HC5>rXAjFv*s(kLM4txk5&G~@C-zGia&m=BD z(iaz7DB967n9Zj>W+d_tVfVb7jbwmHl8tdfWR&?dugW!pw?M&b*~PXr3f=N7f;l@~NQr1@!_vLc-L|6UzSMlyw1wlc8@+%s@ooSs)Rn zT~6q^9?3O@Ch+hQpy6PHjgwNbQ&q>mun1_TF1S+Tnvh1l;qfpO)Pi8L4~%P35|sIw zsyPp?stKV{z<@*rQD?K&bD{b7^}mot0yy#$e%IEZtV!jwu;I)Ja)qyt>P>n zzQB>=p_R#AT2u{I1@@W$e4zn^>wvUSsS@wjT!`%91kSj&>V#qw`HJv;mAJG4pi!`Y zcQI%v*nuz;7^{Z0*ZQ_nZvZKRU`N8$WLl`CNMpRAx+#Q4&qW-io>m?#MR#;;Liv`3 zzTMJbnlZU{^>4iYiHN?|r6SB;8O)QA5v%1ku5)x(TmGk&H^Ta<9Io+Q!NNaYr2H`D zmCXpj4h1+6z#StAkULiH5#?WQcOuoMy9Ii6(gay`p!9Ik6+~yS+<@s`13gy{lH-ND zIihik=BNuKyUyN438vGW$Y?8c+To1?^veyJY_M zmsB!ED4&cF00Yv%Q0#EcLU~Hw<(|_jI=%K!){NhKzv?f+eQlSJIn*QUOU*Xi{ANu2 zLp|8q^FQ~~$sm^A(-pYwxEHmG<^_?8UyF#WyO0t22^041!<*uEfk$F;51Sov20l3^ zqY^QwJ9qq;gjDrn!Hy0#eV}(=tLV#P12Z9MLA~Cc)k|m7-iw)n5!kpJJU}*$3;|XR zkkUVAZn;3tpq;yMxXfNV#;%B2x8n1yzz6eKgnli(z+mK5h&VxmUKaT~?ta?C&uvT$ z5yzA0SA=&q;hw(fg~T3V=v@pq5<4Ho9+*MkPX~IkGA$dluBU$c!5dha@g7z0-L+PF z6?8>u2Yg%c4O_>8)#s>gY{}&F`nPiGQ?|9klPdnM;v{)ft0*6%WVN;9-OBa3w4jL@ zM2zL5nL@CE2QiQ@@jI=$O-*by1(>$~wtk&8eCZ;%v|!yBD_qS48gk~_^%fx2&UZJN zw{;@E1~SP700A7X=31u}Ho_0pn z5(U8C#eAJaR2O0v38XMBWAc9+_@&ez~IoV6Oba*QlhDOu@P28`fA^i!Dnl$ zT@>{`>BijJ#SaXpPvFVsXYG657sQ?!9ej1Jb(T-s7}_k{YgzlzGwe>c;xi4&j$hU& zkF9_NK=q>S)opLUC7?Da}AY206CD(|CD<<_4J!`rZ35}+kEcjR0O-xnXl~_kL91O z&HKBjy;xTdvq%qCM>aTj-5Afqtl?ce`=J znCY4x9>7qtnISZb@)p3!KfRqK2=G2ugHn&qmm+oeMqVkv5b$$xvV2t;NOYTRn!Xs= z1)$EykUekx2yr(6s&EAYDXgZ+*ce?NhkO1QOR&#=L2_Mb*IzTuITSKK<0s~);i%iHyrn=OSf7W6EyJ{LomJCj zj{?31S|;)h$f?hJuvQYtqj32HpYqML<~>t}AJEs1k=NGJUL_t~dv;zs&nT**c9lv~ zuF&F-j_0tAv!<$&d=N;%i;&a~@V}}JDAI#CnWQ{uDu*XOX$u}1ky#Qwo&hP^S&hZ1q)@6f4ANki6;4ky!*huJ6(`76tv8#p$U zC$*#0Nd3x{|mY?I&)p0?R6Fc~hKww{o;5hCS@G6bmw zS@@|hyhgf92XZ8XFbJZ1nkGO_fE)=d+*BB}My*b3}^QtVDx)Oey{DY>=C0a0j~#knQJI>_3V>p zfX@SB3}GmUovJroJ+rYDrkZeBoC=wQ0xlPNz2ess12XPU9z`jZGbcWW2WD4P>q!aU z16SAKJJx(tOR)#u2EJn~X7yq@R<;L+&8(9(dn(4A_-Jv8Xu{qi}yZ-e1i|z1G-E2C&MbY~{v zC@^z~jKz76u{JXgBtE$sn}Ny9Lc(Pe*5-?WU2i@Kg7KKw`vUJ%!;noh?z@!vFB*XB zlZAn(@sb@-U-0;SB4sP4pwj}Sp{2nPbr{#Z*T9&e(92Ixs&A= zcqIUaBFsuhYd{VRE{953V-`x=Z;n*EkVGykP&Kpac_9y?DS@JxdBJ*ldmN9)QOrUn zfL-3aoXz6-6L3aC0Vn5h6nV7iz^s0vWu!_`$Ss5s00dGL4kwCN(EXrFO?{BSLfG~Q zVVlJ4t)7Li0GEU`9mbbpZGp0GP^;bL5yR^0_3^{44a2RF%-cHw5NT7+_`Fil z(9td#{B)#UWJZ^_V_+jru5|xQ@LB-VYPESn^t)9OYsB--iV~Gae(jw;qryI;f`ces zRH)$cHR|@AXFGa^Hm;=z?R?CbGr_~DkoezcwpU)azkInq zy3)?={d}8OCBJm{sezscVs`mMckj6Xd)&S=bAqkrunrA&$Wd=h!XUkns5t-W|fN!gNf2xyBw^OU-ncYNt_>RcE#?H%*E>Q zQ?1=GqHonI>dfMjtQS)f2?cwdvbgK0-mqq#~RfkZ>!|? z>}wB5546t@uMjqw!*BCatZx?pa`)+ms3H5M>QX>)$rkXkT)MNbWj;kMF3+~isCV$I zX>Gz7+-GZ^MJ>Nb#xFfVkX|3bmS8dKK0?r)2C&e45SDqk`~JSw>I()RK78W*f-z+n z^7{W{GI1%?rGHKM#~r4MyUDPDBU|ZrBZQ`Bq^uDlSzVu1U_XnD5+^3EDv9fwU$}zT ziYhaP*pS?5PfTm2kY4GxYjhpG!>Xqx>g*0zD$Jgo$M=)zbgzF-+at$DSXYk78Q%i` z4tBX=c3zX+CyH?gn!c(9T+~RraXcG*#Rjp4icq|8Cz$s2+M=?!uBMMBjtV5~t~1u3=eAvG zmy`9}?60gQM_TDtxQ_6W!K3b(H27aGM&wW(;8`z2-?D3~H`yO;J8DycN-O;-dpr`$ zvD*p&%%jiP)7Bf7fEf4%RS(iN2AgadU%)bm$$6|-TCv6Xq5I2nR2&LaZ+Acen|J!N zp8Y!g(t#UEyTn8w7f>5#QxC!rxH;zUB0hZhn__I{wk zwCQamQ}jUnrkChq&_eVJV-xdkx4i=mQywP#XZVOZq*cGHG1DDS8nf^^CHSMQnR=*2 z$ZG`C=`Rq2>$Q-75fix%qSV0${UYad0P~%glmB&O!{KPrS*X?1;4vuKM`V4F&x_Z-Vy3XbI9Cg;d zcWI8o#tv&D$HAyTVr&NCA=G&A(DhEg>>9eQ;|b~@SCjK;c|{h^|LAhanG7BC?$7b> z)g|+VcR64a9QUN>^moufiln?zxmjUb#BFouVgM3E;C^3vL9XaM8rf{j$v4@Q`rh=q z8|J^HTO1O%*l>y8n#_jHUdV8=&$y=5Ec=Mvkb2`t*0}M`gPD9WC|^p>|i+hr@<|<@Qq>O@t%}Az$AYz)m<^RL|v3;zub@+;}eh!_~9Bn5Tq0_Fc6*O zUcgx+pf+%pf1%A4RlQ9I#kWH~)0-XmbHQi3+kW&)DoCq;DUTnOj7y>Ql+o1E(siv@ zD-;$mW-Ha%K(}>n*tZYwgem4Qq2$lfv05NBRU&VZ&PTe|c0U-N`@H4Bs}0Pw23^fv zaQ`dI>UeQYHs^SsZOKrNer{5XGJrtS=&-a;jD|ki>a$mFwnYQ7TEnmEGAF(7_P4JL z<%20tV70T^z{=eN-|(I1(2ayM!@|!(($?m(D>2hYHM}RK*zA|v3*w|m-_kv6Ojnrn zlOpQ1Q4RJ4jy(@^k?xl%*5>8#NelpQ)Xgv%N@v`S&CK)eAa!HXUk#>v8(~`a(?VCC zcse2P%k9~_?$LxT=0Ps#hS~W5Ve7l;7nLqg&-XC&ZDVbhmaXmLr#ZDi@elkZ z&9;`1l=f1)RxYhrtIw>Hf@j)gInUh9Zb?h}(K>ur&1C!^gn z$bgVtDS6$^a9U=UvYLEg_dE9GV*WJ;A;|edw@r;x9iiK8_3^R&g3_PA>a;z*BK(6% zH2x0v-dVvsih2wHVPpyk&qK;ujR*o*FNQr8lpK4>@voV(;|le0oCCs{Y}xcUdz1ch z4Kc4|lh)um9}D^JB|W?~QLW#T5$b+k#IN4xTJpTivV{Cpn&X{lG@lNyxm8FqJu% zlu3sgCH`0DfXaNz>$TJy5gYL;GKSMX^zZ)Ei|;6ZK&9;YxNln?pA={7V+D#lvn}); zgFiKgZV6ZA-OtKqdrkx}6XG2j?^c>KJ-K%=k{_FxC&T6O+*6H^b#>8J57zW(!O#D! z^8Pf{;E1mF1~&wvrv~rZu8cY?ly-T-v$7T_DT5w?k*Gsh^+QdN=sqk0h}a<@EZQgR zHUT{g+KfEl9zzH^w~8anGf)ar;8kkRj7Ji7p7FJDsh_4!$ma3Di{(08N=WI ze-Er)?y&41uYxbHMmwsX`6lNsp z>H%I_8BS)mH1sURJ@mB2!nO!5=wtLD-5qZYuBbh+&{Z$W$m_}1W@)aDuaGRrnAO&A zs*X33ps5+>Xr z6Xt^W&FO_17gh<&!LMN&I=5CLo;%G&d#aD)DnkzHZ0y#Lrs@yDV@yC{k@BXA`EF*r zH#ekVSney}MREaSuaI?g!_lHg%QU`?meg5n^Ivj2*dB2@+pIPmu7@HJ6`WBk_x3Vn zg~rqpEd5%y1>&-=mPn@+)mycF&b{A>k@4FLOCO`$Oto9#xsX}OwqmK)CG|mzqWoz& zqsam(O;uEyVz{hz#pnC^uSc1oCx0xm+wZGqEl2H6C?4Gk2NT>9SxpkyvlwESaT~JY z%TU1O^J=x5IGovhN{8XMjraQs4hk6C-HFlgH!Pk*|~-y#GndIK?QjM7vW-i9kU zBbE{p?r%tP7x7&5iI4w7NYwYXrXnkd|76JF8k{^S)tU z0+_PtOZarJ^7N+9Vsv+dPVOBHFOq`osI4j)ZND? z&+>5K}lKFJl;A%%?IPlv6?@@d8Dh|^#VF?-`T ziGySHYvk)DOo%-jzoC!uxBdo~XDUHnLXk-;i3ELZY<7AC&U$B`ztc>mx5dY?)b^RNZ%9?&?3>>WB5DFV3KEHmx77Uano+=InF7dc$E7}8mN%g!ubn25>GyQiF0kl> z7iEpDyPS!RboG|C{9LfR!+0-ZD-xwQCknfy&c=KO4t!M$DrQWov#eqbyiv$P39~V7 z-EU_EEG}&gF?!TCv1R)jY23bUA2XZQx-Pp;S>%+9ig)2_$IdnisGyzrT5V131!fsn zKh>}?qISunmaY29qnIL)K2u`vO?;eklem{3z{PrI#PrJDx6ZQ}d_3nF%E1utK~?P} z@2YeL7J2nB5+PtmG9KiOhWV1tJ`~v%4Qg^@91GdVdP}9h_eQqxOAGo8Tur^CtSD7= z?>6YXQoKTPPo-;PQ~TY$=8ghH_`X3J$`-rjX7-%sn6^e%sp_8pCl9TPsaz?WZTgny zrgI-Xi+5B;@Y&71t=q5BCzPk?LQE~@_|_WU2VD-Sx|}o%63myMB@#KL-FZ!(vF{k8 z;bOwV?MpLTufUuWti!i-`Sf4X@)8feCh2@0Z0)*uPI!uG(|%34HT8ZojpwzMg^82< zS0zNY+Cy!0tY=-budR2zl&I}OsE6#F`8{fWEh>D^zsEHts`Wv7l#viiSi2H}AKOhE zKG4!5Sp6x=rZsT>pheR?LD7YktkEqyimb#H91bS9eVMheAM4YSFOSv-UuOx`_HJ~H>q1L3%=6w;XC+GI8<+jvamV~8 z#ZO;Lo$c&fn8{Y$+spOl$S!=D6@dcSnp-zATFW5)VUyvH)WuZl5MdjZ?`hWC`i)C? z7Yf{-tcS-D*plo++5$E#uw8NQV6B$pNZLsF9!3Q9Q2NO>hqC1y4tr40;r(G(cgP$p ziaurGdVNuSv`vK;JgLi`sf2_t>1!>cl$GNJl+fQArh21!*ezAQqqDP9B zc`@%!!r`OksGH)d35lP~jU?_F=SQ_Gbt7I+@nhXmScPP|ltSA=oJymHMzY|3LlT=p zQ3a(vMt(!sa%{`cNUw$8&`3GlXgNN;RcV>qGOu%+d0%AIqH$nfaTzztmX{ZFQ{P9I z?%~ICDvv`=Ym%cW1B&;35rPf@4FXrT&#|i0dsOzgUA-3)T^babHZ#K#!nk*oievE$ zi5~Hh$hn+6|E_VX$vpeo{5y_8oj>}0TFh7O>I}cjw_J(dR2dedO>lvkyrzi{YE&s> zyJy3$uK<%Kn%Sa}dh=WLh|ORRnZQ@43-?FclWg?o@83JBa9uUbw%K*&FBL#3Ykga@ zDbe102DwH>MMaxFH`owA)W{h*r=44sT;JMFL5@q<8Y{A_bkLu3KCA9fuu;kCW%gbz0n>{%F2vX~VG>OlxW>P+q< zA$KC&4o_C#*gHiA$(h^FU|MUhKQg{UNq0>qBEdQz?)B>R_Giv|Y)nCF+GmeFQQa}{ zA=ea$n#H8ii!cFLh?Ng1D;-)jyr-{)nd<8G3%MfvEV#Q`Y9Pwdm70n1g(_a@{HZp8o`e`_VOV_F3;s!Saz}KI!m+UY54VIRsC-2|x zfB9W^fp1>Q2hEZyDnktu2yHC7yVccUHx-f`10Ha<3kt+T#qQte9I#(L_^Hiy$*W&9 zcH==Yw$9wcr>5MVCx%AD=p!%5+9l=ajx zt8Z&SaPzG?cO=1^GHdvZH=G>C)~|A#`kjF*?nTmS^eLZq{L@jj!GmO+LVa@l9&?FU z5#Rl)*B1PTY;ws;79C@Qz6wugsGpz3x7pI28iec4>`=3TMFnOh_&hA-4 zHYKHpwOEQ*=-(naaqd;{1XVZ3TP51sy^rUgRGs+LSq_eX7Mu!8-7}q|^E6uP@nFKd zF5^=XSv(ieyEx;jmV(r!BZn)77v~#(+0DzQfXkn1yo=vYM8Z5xqQ)38CoaVl53n#u zZl4N*NY`L+#`*dSrQLjh^m>Zae0NnE5g~@fmYf^j7Hr&2&PZ8*N}q{$nPc~iv|{r9 z>eM5xjpM@WlxSmQyAm26{|0}cq+1~bOeRHd{0Y8XpoV#->jMY&bEO4ob2%eDdsx$x zx#)L{6wenimAcE0GT@)0xXZhz@qj+uk7#yi+O%M#iPuNlAKY=!-}XvG-qz*hI=F!% zb1JCBjgi5LI+SJv+hU|&%XJ-{#}I$Jo6+C8YjmZY55+h*?m{_er%^E|cUyz<_O=%` z2(v!}BrWYPUXbmBKGtycychZHaoeC%5DZ5QgoQW@2=UUmD|#-+?*Oh*~5j)huB1p+xF)3W4Rf+^N#u@s+f*N_W;E)8;fyi zx#C6iqs{*J9LdHg4KWLLDb-P03|mcF+47+|ZU{8SfLTfO5dw$oo%#@k*~c(Xm6=L9 z;A7W`c`;~_S$YfS62&ullE)$zRL3iIHDcpd*1MPVfvv+jt(UpC?Oj<=w9-^j^j_r0 z!N6%cI$?;O9kSy3y86*~ijuPNV~G$KJh6}?&K#O>Bl{6JH)=c$Y@JW$R6WZONs}Eg zGiiJHsn^9>*rQPQclcC%#Xa=MXkV=JUK=PLF^P}f8spr3Fem!bYB_X~sPV;~_q5qO z@oU8=A<5GfU2)S2^()aqoMHR*BZ6l!*S|SdG$#l3yzZ`@Hmg^3W{)dUNcTpc*7|mI z0rRr#o|>B|2sW3N@F|KnC(mX5G+!El&dA0?*T>d<17)%;iHn1{ZvXs9HhUWR;bTBkD5eitOz&*E}jFH$OaU8B% z@5p9O)RV@VNsxNB(=;tCBjzZrbZ9G~t7mLt?Xcsd;9z^9y0C`?>KrUORWObV#?eUJ`a zn<&a;Z##_WcwF-Y=~2&uJ0nNrX^nIL_N4sq5STRWR%pk`DVhYA6ZH`93oJj^&*m() zd&$Y&2da0;fy~);QXKZg1|>Cs|3ir$gaP^#G6-?bz=_YYv?Z}kii;9$2X1VHO9nqO zdyCyvcaWgNd`!99O@BKA_F-4<`J5My?i9TKk?rm+hoc=|*IOk;lPg6QV|$LkfqC$F z{Jx8`n4}guoIC8`w8oxfME5|@jJ3pE+SpQBxV?r#JCBCqkq2PEG#E~V+HUaLeFval zMyID;sqVYYUBGBO&lYZ24o;(000i=kY&I?ruVAS$PuyJCrNVI8g@p?iR)@If0a?0lX&s+N}K@Or&r{6YeaX$FcjfiHp9< z1w*@^Q?-GlV5i#fIbH=Xp3U)ja%MbY_u|H0!~~XE&!eG`87^am5`fVPj+2$tSl397 z-iGEePCN>l+KqIa&`bl{xfy3#FS!A`wwu9}%&x{u{6i8Ms%Z>MI4(C-`xiJV7Jp=C zDnA#^rc;g^u_2in`1YcZ0!oe;L!Z~c6VS|`?_k5a^zDGHnasWP^n0HXv$C9qDofJ+ zolBv6FS~K`n1eYfoI1A|OL2EkHGShTHf+oIeFmdPPC@nto@GXYDD-1$b`Og~bZ}~P zs_-g_-@-SV6TO9C(-{6X;xO-Xgs|ypcWPm3;E-5nb zYHkLd_k1_9d^A{SKKugsh}P_1K$Zj53_Ls!Adf-*`DB&>gn825cjJTnu7SeZP;_b0 z#u)3^1x#T0^r2U0JFjQxxOnulSb4RS%1RFpz{xtkRTQ3t!jzayzX0tB-o+rm2WDfo zzvZ&scz{n_jJzs%@5uEAqn0Y#zRU^o*hJFf@tN_XZ7!G$#{P&5M$$#o<^JizTg3Oj zHCmZ=V2`*S;{{cgdeurf7?IBGF_r9CF-nY3ej)1HH)R_S5fo!qb7^Tt42aODFA>k< zypT67QvypJ!Z`qy=|2`5C@37iepl3O%ku7Fc}D>t+a$_|YmaMh9?@aK2YP+*+pM$1 z&tWA~xD~E#`vVu?ZR+oOd@2{(vW8nHaFR=#JU(cmvta6BiLcK@BOaIo?Ce`WT(#)4 zLB63u|L|$S2r$XJ&DI{p6-QMC24v>2`+@5w=~hgFwOh;EI1UZb(TFoWR1MuRQ$viH z6#igmJR|VVv!mZCwt@_u90N-iaEB$R8lD9-sw}6d=SyMB6 zQCRnoJEDTCzoMhyGCBA1yZvj6@rQaPUA(EfT=<77$?JXkhq(e5FhW!E?UNENElXh` zG$wrWu9oHlM~Z-iXj+XbF*=a-$RC6O{kPRbI}B9WMX#&gTWPBXcS`1g((z3kz1h!b>|RH&lEEl$CSJJ>PIOYVVOz1^)>%l?dxS=bXO(L2 zHD~p<>Qlfku4QF(S?foqSe}B*H>aicOMpR-b{N8V$IGJVX6DV>=<|b1j z^Vn^_=-5KC+PQ z@kFN|I14P-ciqIsn#o%&?GbTvnChxDms8=$SZLzY^MWPiTp;95JVc{hN3brp`&SXg zrOlhQ`MBn$-Y#bQZF{M+7`6{uO<}E4xU}$5HDFnpy5=#HdLB;~+>=HsS%4*NK3yv= z3fY%di=?BZwOb>W(hpOw{y-Z zbQC~0VFFz>lrm?QF89le>jD9ut~y17@vLk>R)%g;4@%j1$4<)NEvnuu&< zV-DX4$0^M7CvqIi4P2j7vSzBC3E7Q^)rlG1qVPM&2Jbj9@vn7PaA^CE$YbBGH;3!) zxvH%tb=V0^;JCY&1$+C|*>y0t`-y7iK6-QLBmB?`2#sP?NfZ@GGE@RfwSmg-7jL;zCGg9$z6l9xv0#E<~G6YLJx~U23Olr0L#%SL`;h*Z;f`?AqISPvnR`L zWt6(%tC&j{sqU#zz?o#6{DS%~aX0rBQA-Ac0*30`vCTjIaRI zm;=QnO^Vd1KukNZfqA`|jC>w%qm(J&?ZLVWA`j>tM?nN3e}z6N?Fy#0Hzti5$6lc) zHMuLR7w45F+~ShK$hC4!IzQg*4zcAH9-Ou*bwz!D#TD8^g(+mnC~+D5v_G=s?ojD* z{i&Bzr)=V+>Nx2c!xJ61 z&C(WU;?0Jo6t)9jaTA-^DTeDxW@8sY?Jt;^HT@k2-i$Ik;`)|#m?_|=t)K%jY4fd@ zzxDD}vY;4EOiVWSZUX8A;^G7Pw?xQkZDtI)QVSwRJu9IV91mmia+)+k|BtWvJc<}` z6qnXFRe4ohqp=oZwpeC-OBJV@@RI?d#KKjitb!F2-ME2`I|WB`)AtOv+AbBT6u@_Sk3}oay+H0>kbE6K=H7;C7ucs&S|wB|1`Tiv#4k>5t3mZs`Cv8*YB>q zpTLYq$Zu#a61S;s5zBY-MHd}-LN>S~%G*Af0ulNpG%OMIXT@z^3_4lj1;;=vkYf}@f5pZ0W3TuH6I{9KT(xY5*?IlT}9hMnG z^-U8ZnE*;*jEv(CHgx4x#F(cf+eHb)X@ zti?ELV~X*XO731Q@sybO>m^db3c}Rs1wnRcND5K_+XG)PEKIE=c0}o6Eetuo0^8hL8Y~4*21u{*@(SgjiZR79|IBbix|mEuTGN2^KWOq zJc^4NHR@XG*sN)Q2Pt4mjARnfkJ!PKG!ddVgjLa~Xnv_OBIKyaiJv#3u-VR5m2p=< zN=0@Qt39&sFI!M4Jl`79dK&VmJ?D_CE0q?@nWZxQA=jFzvvn`$6@=(9VyIvu7jZ*o zYuhLd#RO6~={pTYYWNoQy^kud&`B3RrB|k;b~zydZ}EfD^$!6^lI-wZMu3enGC+pV z22(KD%OOn$O^*J(4!aNMfJsZAYIomCR=H`cZ4=sfq>wvcxoUdaVL4)7e!KU;i$WrQ z*RNv}<^j>3Q%-d&H7>RDyA^ps6xdg#Fzi3*4~bP&@|O z=bmy5?TpDv&Ca`kk-MZ$N+oWL+o%~!uNgCgKQ2U}_Mw@wWH?p9!3BbWA z)76QK?a@YsLxzkVUDV@sM>;PTg>QRwq{Uq+ro3F2Rn90CxgbSa)uZJ; zzP8@m=N_*r)z9UW&MBc19(!#&HIO3doq!J7G-SxI&qB4dbO;-Y^9f4k^<}Q|&)B$=`SBt;BvtMpU z92Pm5583v&D`S#NhjJdON}wd9GoqzD4hO;O)s+AzNz1Ev&d2!hc!gQHd!}>GJO{Aa z8&Q5+nY_D}B^$1x;Yz&;(_P&6qy)E_uiE!j>gkBP3_rqaiMT0Jqcu%W>aeP~*H5*F z59ZzOKXECcjwGQ8@4mjFh%JvhI)`C{)$0^abc4}NGi?hHdfNE};bCPF%1Hqi2#eQ{rQ; za;xdvNXSEtQ@&pH*wJRks`ht?T4bKEVhiWSY>@e}GKZVu5FXDR@Ey}gm-OTn<*j<+ zjv;P6t5yDFbr7o}h5Ede#-!+|xj7Fi|LdH1eucak#`+u5Oq0uH17~63&2p8{H;(6YYS6>(eJZlRz?`*{z#@!qn~@&wlT!>v3chw?S&;qKTb@Yl0mZ|zp| zQP%rokq5-IUTJJohqCNg-9P#y`;yV)9n&xsIi0!Vuvk%*skNM=tVs>zcl)*0#^%Ve z?u80%2F!<<0(#Z{Ao1T_9h9xvLTh2LDC>P?m9hcS#<${|aT&rbc-cAU8+PJh&0nRM zLoL7CE7r+C-D>bQvs1j&#mwc_*Hv__JEc;2O)7Yh|NgW=@&2(W^ECmyuFA>`j}p89 zw)RJM_IgB!oE)UUlHRzKQUX@ zk$K2h0>7R|sw6pv&)f`)ICHUbUWKlmar58Du!SO?mt8apo_;r?Z z$HErD5%v-&^Hu@(TdyIc-2_OREDsPRmKX^nKg8(^AQCr9^&mCcT0wLS?)=NInn-8m-Y?nM0 zr{)be=iylD(nW8!%8pOQnE5ES)`;gubK33xD~yaH+3pcc)`MO~d*d(mzG2VA%X1JW zXzH=AkRkiOSv0YZm6dg4qNoG5d_Ixt?h*0td)266)frsHmAhB2`I(2fb{n;pRBGl6 zpztuyB~Y2>HJc{kcF)W{tP#D|!y{;GJ2)rpcV4{Gw?wn#Y%QQ(#7;~kP(9*5FGT;q zXK%|uJkcc?$bx!0g}(&~-I$N8V_kc?#wRMYKGC>B;gKE%UqmC7Q!dgmjA%0KB#sEP zn%Zouoz8PV9KMs`ec*5mhN#wfD?{!7#};KHI^-a|$1M$E;Bn+{pP#U>PO7bQroDd3 z3ICr@hj}_e!1Bjy;fY*geKpZKo5?dzcUIVv*y&h*s}I35t8}|$;kGlK+trw2Cp;Ko zU~%(d7H}1p_KRuz7mc=JY&;$=9HLC~S=?L$dl7g%OH#cA#WP2Me;aNxUy;x{;$JTT zsLB+)KQwAINg7X#u?i509+Vd!L8XJ-&kUhMUBb-_ptDoXzQ+_2_FE|DLDGN^DPbO}Z;-WUs)QJ1N!QCEi z-IpDG=m)A&IW~Hy2^XlYSU%=P@zo6=y!bz6VuJ z{d%nuEZZL8)#Yb#oo(#ERiR!}PxkXs{5X0{<&d?l#OuGK;1y4J zXZcLZz>jYTKRcd7Nm9dkC!69#*9m$Xzv|k_IE0DT=1cLkJGo== zvY9pU)3|m8L_bE+?;d?W&K;a^8I(L-Cui+)%YYRA@2tt zPm3>A^r}p}8tm%&p=NHs*5**kPlODAv$kjLQM{(We!xzoh_YIR^*{RY^H*iUOaf=v zuIBkkS>Y*4p8yKG$d85>7x;n@m2vjZ?Gs0M-Vd@n{QeMB-OxLZ7{-M-M7yMl&yVQS z3?2+kIC-fZX`S>G8QC-A$>+kl1c&Us>3Qyr;JB*)G^KVEb9$0-Vv=m~v|D_FR;iHL1SH#3mnQxe%Tdo|bH=3X))O`KYu@0zQo-choptv4A6_dcca!IE7t<6!~Exj%^ z)+4S^_vTiF9}-hEUufrrPb=$2#M#(Ui7$`9BlD)o?ueb;L&9Lj6Mgg!JW3%5?|U30 zuHKF6#T49|vc@ID1G{rR^j}#dDpiDoTz&11f~7VN2zB4TcHt4!1+$Oz)IGN|sDq#r z9UGEU|CD=?PyceB;uLrx+|tQQnWXF91AF~_cBN+~m?8%!wHER_;V8~uo-dsTR=zd- zF=^4j8h9{4DY4Bx7X8% z?KbAqV}PafWUUMf*1sN7*S=gXn|qN>XFM(YU2mJBp}}nboau#5Cpu0l+Z>zA;dnXm zhq13mnSOaZ^x={Zfkj;N$sUQ{k<*=cm*XGUs;-gU7pB7s4DW?0rrpIvD@cBZjQASZc7d#USmD12!jf1H)O zBtXz6$Q~tcBPmDSe8(gb#CdIOmpU3jsJSLd^T)F zvS_Tu@z$}McE;BGH%aW;YU78xu6C+A=(7*r3DHLw&3+1L2@qJFqk6dt(D;85A36j2f+935lSBCZ3HTXFV0rr)vbiq4#y@y;Ka%%iYHGm7dI z<-#zA<-SFS)||Xy?%yNBF{z5!&}18Zv!T3Vz0amIAu;3yPh)%}J=V@KM-RUUr)qX* ziNAhd#u6%S{PlV#^8@R4cODm?$AXtlLgAe`g9{6SPO82JmD55(aXh=bZ2Mde5i#$J z5!4iBlb9DaX3paf?iz1}5nH7Qq3Jbw=CfJjkT?YjWufmm#EYHOj*n&)1D}=5Sy@_# zH(@6RENklPjV8x>|E(AS6-o>YmfF@;ZE&WAeC(CWBPB`A!v`d^+UkksDAJnZqXtDb zE{-!radxNmRbgs1N^e=?=sS0%4}Av$R!DT>uH|ZOGdnfnJ7WIbc=YR(E8tag>A8Lt z8w2j$ndtz%9C2U!qu_{yK8*`ikNlQhFL~66bCS2{LO2rX z1K+2W=Y#`)+%0a++19M;LukF;|y4IbEqeIo-AKHB|AeOy+)&xUHV&K#jfRJE@7-sj?Ptf(Unl zp}LY^uT!3Z#FvuDv7TbLmZrRB=B?U&p#PmIgXIu}C&B}b0Fs^V{8f*Ff2-g=v_edd z5p&F;%-T;R`u~>*#5xrut>VeIbs_B=w~?NW8fYU~^U)9;S-;$em)GNSzxr?aA1A0@ zM)=#p9H{>*y&U1Xz77OjEq`t0DS>oPTGX%xvZYi@NIe7o6kq^b zJ>|x9R)wK^Jf0#4K;NW61&FHud0qbV-pwS-8dhd*6(1K#sJHyHCw-Nl&l2sjwB7qt zh5pQq|9Lyi6E2ec*$dEWnaZ(#Yc2*LO;;3lWa z+cj0zL{FRz=$Ji*oc!yn{52NZe+|0B6{onzwD{`N|Hj8 zK6?VVOvk?erYw@q+2vn%don;8zvJB*W7!KlkA;~}rQXOLLNewyB3~JQAoQHni$8@v zTS{1}@k=9TAkKHqFNpw#d*Evgh)^sEc%|D;vSzT(D#Bw6S#JEze`Mc3 zTe)-w%B-Oxip+;eY$g6!dx*vigr4}`hC69=FPJxgj!H1?dc4~&L-_@50Z)`9xD|GcDOKZ;NY?AB{) zexL;cz1^Jt@dtB^$DimzZd08T`8JH;u^}8}<%Cmie`!XV9HNIGznXZ3&|!U%Q!+E4 znIIa_Otllt+IQ9Uk`x_3H3z|+{;Tanqj`L&w^)5g>)xV>OrS zfE))VPycj2;LN`~9QyD>41pNhqRxPlDKLs3&<#cb?0|q=WnB<*K=hUtR2luNfmV5W zqIX~;e*fXQI^DHfYmgs+&~dP{cvhP8nHX~evtI2_&%h6ktlv1}$sO z|8#x}2Ey=veDm*zL;DB4UAR^PeBXpK)qtPk*L(j2JwJng-RfxsZHDzQ(Q<^-YdW|5Z_(NKf}lrrQErwdcJ4JH?EaA5UtxE)tR)7DqyG)D326Uu&!m3F z59AgAv48r{pNQ?$)?DTXBJTf;9P9!WmmR)_fnxPPbvCeQCHJ@KI{g*(Cglk`?*1af z54!;IbN_HxO6u~X6KNEd__G5+<>WpD84#4;_NVo-ZVPN|{n7&A!_68uLHH$JeHkPR|> zFdp~41NmUmx``X_iqzV_AKnV(%x_QEkN7sz^(p`X5)jLYvF%j349uU@jp?(H9^?=N z5a;+Gt^dv@4c$jgdZFiCIZ>pE+q8@K^n7Fz9Zq>#C$Ptd7aTHTGdDhtghPy8<|9c3^KRh6b5$FCg#;?(*xjQF{ z;H`imJUb6SEPkEO5<h@7 zKyJvb{zELB8++)MgfV%ukU{|fh5~A zfo6ZO0q*h_1VsOUV!#0;8=d^Zsk@=1^522bLEDr63EG2(s#iXO#qw(}uka+q#~^`1CQuTE%{ckRw@ydF2~F8QUdsGaELAnooWaBKIpSo#Kz3@D09xVq)4E5Sg z9JyA6eljI8Pc+G?329M^iPANC@=!OpmfrWu*LM2PZyb+ZFtdKFi-p@M--7cjVL10} zH4JsmYIsu_mLE{9yzxEMef3Eog72Q!=ea}aqTk8hv#rODF?S1eH}Z!zB8=LcW}M0o zzqc4mHu76KwZ*orBif*?e!x|A)~4aanUBHXggRnYJFx=BnCir^-4vXDePNh*MwRv- z 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 literal 0 HcmV?d00001 diff --git a/apps/web/public/manifest.json b/apps/web/public/manifest.json new file mode 100644 index 00000000000..ea63d893b0d --- /dev/null +++ b/apps/web/public/manifest.json @@ -0,0 +1,46 @@ +{ + "name": "HSKSwap", + "short_name": "HSKSwap", + "description": "Trade Crypto on DeFi's Leading Exchange", + "start_url": "/", + "display": "standalone", + "background_color": "#ffffff", + "theme_color": "#ffffff", + "orientation": "portrait-primary", + "icons": [ + { + "src": "/icons/hskswap-icon.svg", + "sizes": "any", + "type": "image/svg+xml", + "purpose": "any maskable" + }, + { + "src": "/icons/hskswap-icon.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any maskable" + }, + { + "src": "/favicon.ico", + "sizes": "48x48", + "type": "image/x-icon" + }, + { + "src": "/favicon.png", + "sizes": "any", + "type": "image/png" + }, + { + "src": "/icons/hskswap-icon.svg", + "sizes": "192x192", + "type": "image/svg+xml", + "purpose": "any maskable" + }, + { + "src": "/icons/hskswap-icon.svg", + "sizes": "512x512", + "type": "image/svg+xml", + "purpose": "any maskable" + } + ] +} diff --git a/apps/web/src/appGraphql/data/apollo/client.ts b/apps/web/src/appGraphql/data/apollo/client.ts index 2d129fd1d35..138472b609d 100644 --- a/apps/web/src/appGraphql/data/apollo/client.ts +++ b/apps/web/src/appGraphql/data/apollo/client.ts @@ -17,7 +17,7 @@ export const apolloClient = new ApolloClient({ link: from([datadogLink, retryLink, httpLink]), headers: { 'Content-Type': 'application/json', - Origin: 'https://app.uniswap.org', + Origin: typeof window !== 'undefined' ? window.location.origin : '', }, cache: setupSharedApolloCache(), defaultOptions: { diff --git a/apps/web/src/components/Web3Provider/walletConnect.ts b/apps/web/src/components/Web3Provider/walletConnect.ts index aed25cf226d..bbb68cc846b 100644 --- a/apps/web/src/components/Web3Provider/walletConnect.ts +++ b/apps/web/src/components/Web3Provider/walletConnect.ts @@ -36,11 +36,11 @@ export const WC_PARAMS = { metadata: { name: 'HSKSwap', description: 'HSKSwap Interface', - url: typeof window !== 'undefined' ? window.location.origin : 'https://app.uniswap.org', + url: typeof window !== 'undefined' ? window.location.origin : '', icons: [ typeof window !== 'undefined' ? `${window.location.origin}/icons/hskswap-icon.svg` - : 'https://app.uniswap.org/icons/hskswap-icon.svg', + : '/favicon.ico', ], }, qrModalOptions: { @@ -83,7 +83,7 @@ export function uniswapWalletConnect() { icon: typeof window !== 'undefined' ? `${window.location.origin}/icons/hskswap-icon.svg` - : 'https://app.uniswap.org/icons/hskswap-icon.svg', + : '/favicon.ico', } }) } diff --git a/apps/web/src/pages/metatags.ts b/apps/web/src/pages/metatags.ts index 09c4145fb93..11947e97540 100644 --- a/apps/web/src/pages/metatags.ts +++ b/apps/web/src/pages/metatags.ts @@ -6,8 +6,11 @@ import i18n from 'uniswap/src/i18n' const DEFAULT_METATAGS: MetaTagInjectorInput = { title: i18n.t('interface.metatags.title'), description: i18n.t('interface.metatags.description'), - image: `https://app.uniswap.com/images/1200x630_Rich_Link_Preview_Image.png`, - url: 'https://app.uniswap.com', + image: + typeof window !== 'undefined' + ? `${window.location.origin}/images/hashkey-logo.png` + : '/images/hashkey-logo.png', + url: typeof window !== 'undefined' ? window.location.origin : '', } type MetatagAttributes = { property?: string; name?: string; content: string } diff --git a/packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx b/packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx index 5e1569c3a14..16d367eb199 100644 --- a/packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx +++ b/packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx @@ -8,12 +8,23 @@ import { CurrencyLogo } from 'uniswap/src/components/CurrencyLogo/CurrencyLogo' import { Modal } from 'uniswap/src/components/modals/Modal' import type { CurrencyInfo } from 'uniswap/src/features/dataApi/types' import { useLocalizationContext } from 'uniswap/src/features/language/LocalizationContext' +import { + useTransactionSettingsAutoSlippageToleranceStore, + useTransactionSettingsStore, +} from 'uniswap/src/features/transactions/components/settings/stores/transactionSettingsStore/useTransactionSettingsStore' import { ModalName } from 'uniswap/src/features/telemetry/constants' import { useUSDCValue } from 'uniswap/src/features/transactions/hooks/useUSDCPrice' import { useSwapFormScreenStore } from 'uniswap/src/features/transactions/swap/form/stores/swapFormScreenStore/useSwapFormScreenStore' import { usePriceUXEnabled } from 'uniswap/src/features/transactions/swap/hooks/usePriceUXEnabled' import type { DerivedSwapInfo } from 'uniswap/src/features/transactions/swap/types/derivedSwapInfo' import { getTradeAmounts } from 'uniswap/src/features/transactions/swap/utils/getTradeAmounts' +import { calculateRateLine, getRateToDisplay } from 'uniswap/src/features/transactions/swap/utils/trade' +import { formatPriceImpact } from 'uniswap/src/features/transactions/swap/utils/formatPriceImpact' +import { getPriceImpact } from 'uniswap/src/features/transactions/swap/utils/getPriceImpact' +import { getSwapFeeUsdFromDerivedSwapInfo } from 'uniswap/src/features/transactions/swap/utils/getSwapFeeUsd' +import { useSwapTxStore } from 'uniswap/src/features/transactions/swap/stores/swapTxStore/useSwapTxStore' +import { useGasFeeFormattedDisplayAmounts } from 'uniswap/src/features/gas/hooks' +import { useRoutingProvider } from 'uniswap/src/utils/routingDiagram/routingRegistry' import { CurrencyField } from 'uniswap/src/types/currency' import { NumberType } from 'utilities/src/format/types' import { isWebPlatform } from 'utilities/src/platform' @@ -152,6 +163,88 @@ export function SwapConfirmationModal({ const buyCurrencyInfo = formCurrencies[CurrencyField.OUTPUT] ?? derivedSwapInfo.currencies[CurrencyField.OUTPUT] ?? undefined + // Calculate rate from trade + const trade = derivedSwapInfo.trade.trade + const formatter = useLocalizationContext() + const { formatPercent } = formatter + const rateText = useMemo(() => { + if (!trade) { + return null + } + const rate = getRateToDisplay({ formatter, trade, showInverseRate: false }) + const rateAmountUSD = calculateRateLine({ + usdAmountOut, + outputCurrencyAmount, + trade, + showInverseRate: false, + formatter, + }) + return rateAmountUSD ? `${rate} (${rateAmountUSD})` : rate + }, [trade, formatter, usdAmountOut, outputCurrencyAmount]) + + // Get slippage tolerance from settings - prioritize settings over trade to ensure immediate sync + const customSlippageTolerance = useTransactionSettingsStore((s) => s.customSlippageTolerance) + const autoSlippageTolerance = useTransactionSettingsAutoSlippageToleranceStore((s) => s.autoSlippageTolerance) + // Prioritize customSlippageTolerance or autoSlippageTolerance from settings (these update immediately) + // Fallback to trade.slippageTolerance only if settings are not available + const slippageTolerance = customSlippageTolerance ?? autoSlippageTolerance ?? trade?.slippageTolerance ?? 0 + const slippageText = useMemo(() => { + // If customSlippageTolerance is set, don't show "Auto" prefix (user has customized it) + // Otherwise, show "Auto" prefix for auto-calculated slippage + if (customSlippageTolerance) { + return formatPercent(slippageTolerance) + } + return `Auto ${formatPercent(slippageTolerance)}` + }, [customSlippageTolerance, slippageTolerance, formatPercent]) + + // Calculate price impact from trade + const priceImpact = getPriceImpact(derivedSwapInfo) + const priceImpactText = useMemo(() => { + if (!priceImpact) { + return 'N/A' + } + return formatPriceImpact(priceImpact, formatter.formatPercent) + }, [priceImpact, formatter.formatPercent]) + + // Get gas fee from swapTxStore + const { gasFee } = useSwapTxStore((s) => ({ + gasFee: s.gasFee, + })) + const { gasFeeFormatted } = useGasFeeFormattedDisplayAmounts({ + gasFee, + chainId: derivedSwapInfo.chainId, + placeholder: undefined, + }) + + // Get swap fee info + const swapFeeUsd = getSwapFeeUsdFromDerivedSwapInfo(derivedSwapInfo) + const swapFee = trade?.swapFee + const feeText = useMemo(() => { + if (!swapFee || swapFee.percent.equalTo(0)) { + return 'Free' + } + // If USD value is available, show it, otherwise show percentage + if (swapFeeUsd !== undefined && !isNaN(swapFeeUsd)) { + return convertFiatAmountFormatted(swapFeeUsd, NumberType.FiatGasPrice) ?? formatPercent(swapFee.percent.toFixed()) + } + return formatPercent(swapFee.percent.toFixed()) + }, [swapFee, swapFeeUsd, convertFiatAmountFormatted, formatPercent]) + + // Get routing provider name + const routingProvider = useRoutingProvider({ routing: trade?.routing }) + const routingText = useMemo(() => { + if (!trade?.routing) { + return 'N/A' + } + // For CLASSIC routing, use provider name (e.g., "Uniswap API") + // For other routing types, you might want to customize the display + if (routingProvider?.name) { + return routingProvider.name + } + // Fallback: return routing type as string + return trade.routing + }, [trade?.routing, routingProvider]) + // TokenRow component interface TokenRowProps { currencyInfo: CurrencyInfo | undefined @@ -377,7 +470,7 @@ export function SwapConfirmationModal({ color: '#AD81F1', }} > - Free + {feeText} @@ -408,7 +501,7 @@ export function SwapConfirmationModal({ color: '#FFFFFF', }} > - $0.02 + {gasFeeFormatted ?? 'N/A'} @@ -440,7 +533,7 @@ export function SwapConfirmationModal({ color: '#FFFFFF', }} > - 1 ETH = 3218.57 USDC ($3,218.57) + {rateText ?? 'N/A'} @@ -470,7 +563,7 @@ export function SwapConfirmationModal({ color: '#FFFFFF', }} > - Auto 0.67% + {slippageText} @@ -500,7 +593,7 @@ export function SwapConfirmationModal({ color: '#FFFFFF', }} > - HSK API + {routingText} @@ -530,7 +623,7 @@ export function SwapConfirmationModal({ color: '#FFFFFF', }} > - -0.05% + {priceImpactText} diff --git a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts index 01a1403a058..81f5c6ee21d 100644 --- a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts +++ b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts @@ -191,6 +191,49 @@ export function getSimulationError({ return null } +/** + * Calculate gasFee from quote response + * If gasFee is directly available, use it. Otherwise, calculate from gasPriceWei * gasUseEstimate + */ +function getGasFeeFromQuote( + swapQuote: TradingApi.ClassicQuote | TradingApi.BridgeQuote | undefined, + gasStrategy: GasStrategy, +): { value: string | undefined; displayValue: string | undefined } { + if (!swapQuote) { + return { value: undefined, displayValue: undefined } + } + + // Try to use gasFee directly if available + if ('gasFee' in swapQuote && swapQuote.gasFee) { + return { + value: swapQuote.gasFee, + displayValue: convertGasFeeToDisplayValue(swapQuote.gasFee, gasStrategy), + } + } + + // Calculate from gasPriceWei * gasUseEstimate if available + if ('gasPriceWei' in swapQuote && 'gasUseEstimate' in swapQuote) { + const gasPriceWei = swapQuote.gasPriceWei + const gasUseEstimate = swapQuote.gasUseEstimate + + if (gasPriceWei && gasUseEstimate) { + try { + // Calculate: gasFee = gasPriceWei * gasUseEstimate + const gasFeeValue = (BigInt(gasPriceWei) * BigInt(gasUseEstimate)).toString() + return { + value: gasFeeValue, + displayValue: convertGasFeeToDisplayValue(gasFeeValue, gasStrategy), + } + } catch (error) { + // If calculation fails, return undefined + return { value: undefined, displayValue: undefined } + } + } + } + + return { value: undefined, displayValue: undefined } +} + export function createProcessSwapResponse({ gasStrategy }: { gasStrategy: GasStrategy }) { return function processSwapResponse({ response, @@ -212,10 +255,8 @@ export function createProcessSwapResponse({ gasStrategy }: { gasStrategy: GasStr permitsDontNeedSignature?: boolean }): TransactionRequestInfo { // We use the gasFee estimate from quote, as its more accurate - const swapGasFee = { - value: swapQuote?.gasFee, - displayValue: convertGasFeeToDisplayValue(swapQuote?.gasFee, gasStrategy), - } + // Calculate gasFee from quote response (either directly from gasFee or from gasPriceWei * gasUseEstimate) + const swapGasFee = getGasFeeFromQuote(swapQuote, gasStrategy) // This is a case where simulation fails on backend, meaning txn is expected to fail const simulationError = getSimulationError({ swapQuote, isRevokeNeeded }) diff --git a/packages/uniswap/src/i18n/locales/source/en-US.json b/packages/uniswap/src/i18n/locales/source/en-US.json index 90898a711ab..ad7133c7475 100644 --- a/packages/uniswap/src/i18n/locales/source/en-US.json +++ b/packages/uniswap/src/i18n/locales/source/en-US.json @@ -965,7 +965,7 @@ "home.upsell.receive.title": "Receive crypto", "home.warning.viewOnly": "This is a view-only wallet", "interface.metatags.description": "Swap crypto on Ethereum, Base, Arbitrum, Polygon, Unichain and more. The DeFi platform trusted by millions.", - "interface.metatags.title": "Uniswap Interface", + "interface.metatags.title": "HSKSwap", "landing.api": "API", "landing.appsOverview": "Built for all the ways you swap", "landing.blog.description": "Catch up on the latest company news, product features and more", diff --git a/packages/uniswap/src/i18n/locales/translations/zh-CN.json b/packages/uniswap/src/i18n/locales/translations/zh-CN.json index b0eaca64ee1..47bfad80127 100644 --- a/packages/uniswap/src/i18n/locales/translations/zh-CN.json +++ b/packages/uniswap/src/i18n/locales/translations/zh-CN.json @@ -967,7 +967,7 @@ "home.upsell.receive.title": "接收加密货币", "home.warning.viewOnly": "这是仅供查看的钱包", "interface.metatags.description": "支持在以太坊、Base、Arbitrum、Polygon、Unichain 等链上交换加密货币。数百万用户信赖的 DeFi 平台。", - "interface.metatags.title": "Uniswap 界面", + "interface.metatags.title": "HSKSwap", "landing.api": "API", "landing.appsOverview": "专为各种交换方式而设计", "landing.blog.description": "了解最新的公司新闻、产品功能等", From ea8822b0dd5286479653707b571cbf5dcbe3ea61 Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Fri, 16 Jan 2026 16:28:19 +0800 Subject: [PATCH 11/33] feat: change language and hide get app --- apps/web/src/components/NavBar/index.tsx | 5 +- .../components/WalletModal/DownloadHeader.tsx | 87 ++++++++--------- .../WalletModal/UniswapWalletOptions.tsx | 5 +- apps/web/src/i18n/LanguageProvider.tsx | 19 ++-- apps/web/src/pages/App/Header.tsx | 3 +- .../src/features/language/constants.ts | 69 +++++++------- .../uniswap/src/i18n/i18n-setup-interface.tsx | 8 +- packages/uniswap/src/i18n/i18n-setup.tsx | 93 ++++++++++--------- 8 files changed, 152 insertions(+), 137 deletions(-) diff --git a/apps/web/src/components/NavBar/index.tsx b/apps/web/src/components/NavBar/index.tsx index 613537d22eb..395769286c5 100644 --- a/apps/web/src/components/NavBar/index.tsx +++ b/apps/web/src/components/NavBar/index.tsx @@ -74,10 +74,11 @@ export default function Navbar() { {/* {!isSearchBarVisible && } */} - {!isEmbeddedWalletEnabled && isLandingPage && !isSmallScreen && } + {/* Get App button is hidden - only English is supported */} + {/* {!isEmbeddedWalletEnabled && isLandingPage && !isSmallScreen && } */} {/* {!isConnected && } */} {isTestnetModeEnabled && } - {isEmbeddedWalletEnabled && !isConnected && } + {/* {isEmbeddedWalletEnabled && !isConnected && } */} diff --git a/apps/web/src/components/WalletModal/DownloadHeader.tsx b/apps/web/src/components/WalletModal/DownloadHeader.tsx index 04472181a66..1314d1f85f7 100644 --- a/apps/web/src/components/WalletModal/DownloadHeader.tsx +++ b/apps/web/src/components/WalletModal/DownloadHeader.tsx @@ -15,50 +15,53 @@ interface DownloadHeaderProps { } export function DownloadHeader({ showOnMobile = true, showOnDesktop = true }: DownloadHeaderProps): JSX.Element | null { - const wallets = useOrderedWallets({ showSecondaryConnectors: false }) - const { openModal: openGetTheAppModal } = useModalState(ModalName.GetTheApp) - const [, setPage] = useAtom(downloadAppModalPageAtom) - const recentConnectorId = useRecentConnectorId() + // Get App button is hidden - only English is supported + return null - const shouldShow = - !wallets.some((wallet) => wallet.id === CONNECTION_PROVIDER_IDS.UNISWAP_EXTENSION_RDNS) && - recentConnectorId !== CONNECTION_PROVIDER_IDS.UNISWAP_WALLET_CONNECT_CONNECTOR_ID + // const wallets = useOrderedWallets({ showSecondaryConnectors: false }) + // const { openModal: openGetTheAppModal } = useModalState(ModalName.GetTheApp) + // const [, setPage] = useAtom(downloadAppModalPageAtom) + // const recentConnectorId = useRecentConnectorId() - const handleOpenGetTheAppModal = useEvent(() => { - openGetTheAppModal() - setPage(Page.GetApp) - }) + // const shouldShow = + // !wallets.some((wallet) => wallet.id === CONNECTION_PROVIDER_IDS.UNISWAP_EXTENSION_RDNS) && + // recentConnectorId !== CONNECTION_PROVIDER_IDS.UNISWAP_WALLET_CONNECT_CONNECTOR_ID - if (!shouldShow) { - return null - } + // const handleOpenGetTheAppModal = useEvent(() => { + // openGetTheAppModal() + // setPage(Page.GetApp) + // }) - return ( - <> - {showOnMobile && ( - - - - )} - {showOnDesktop && ( - - - - )} - - ) + // if (!shouldShow) { + // return null + // } + + // return ( + // <> + // {showOnMobile && ( + // + // + // + // )} + // {showOnDesktop && ( + // + // + // + // )} + // + // ) } diff --git a/apps/web/src/components/WalletModal/UniswapWalletOptions.tsx b/apps/web/src/components/WalletModal/UniswapWalletOptions.tsx index ba0017222ef..37f3e6c343d 100644 --- a/apps/web/src/components/WalletModal/UniswapWalletOptions.tsx +++ b/apps/web/src/components/WalletModal/UniswapWalletOptions.tsx @@ -117,7 +117,8 @@ export function UniswapWalletOptions() { - {isMobileWeb && ( + {/* Get App button is hidden - only English is supported */} + {/* {isMobileWeb && ( // If on a mobile web browser show the relevant app store download link { @@ -148,7 +149,7 @@ export function UniswapWalletOptions() { )} - )} + )} */} ) diff --git a/apps/web/src/i18n/LanguageProvider.tsx b/apps/web/src/i18n/LanguageProvider.tsx index 1a3f4167e57..58f905d7813 100644 --- a/apps/web/src/i18n/LanguageProvider.tsx +++ b/apps/web/src/i18n/LanguageProvider.tsx @@ -13,9 +13,10 @@ function getStoreLocale(): Locale | undefined { } function setupInitialLanguage() { - const lngQuery = typeof window !== 'undefined' ? new URL(window.location.href).searchParams.get('lng') : '' - const initialLocale = parseLocale(lngQuery) ?? getStoreLocale() ?? navigatorLocale() ?? DEFAULT_LOCALE - changeLanguage(initialLocale) + // Force English only - ignore query params, store, and navigator locale + // const lngQuery = typeof window !== 'undefined' ? new URL(window.location.href).searchParams.get('lng') : '' + // const initialLocale = parseLocale(lngQuery) ?? getStoreLocale() ?? navigatorLocale() ?? DEFAULT_LOCALE + changeLanguage(DEFAULT_LOCALE) // Always use English } if (!isTestEnv()) { @@ -24,14 +25,16 @@ if (!isTestEnv()) { export function LanguageProvider({ children }: { children: ReactNode }): JSX.Element { const dispatch = useAppDispatch() - const locale = useCurrentLocale() + // Force English only - ignore current locale + // const locale = useCurrentLocale() + const locale = DEFAULT_LOCALE useEffect(() => { - changeLanguage(locale) - document.documentElement.setAttribute('lang', locale) + changeLanguage(DEFAULT_LOCALE) // Always use English + document.documentElement.setAttribute('lang', DEFAULT_LOCALE) // stores the selected locale to persist across sessions - dispatch(setCurrentLanguage(mapLocaleToLanguage[locale])) - }, [locale, dispatch]) + dispatch(setCurrentLanguage(mapLocaleToLanguage[DEFAULT_LOCALE])) + }, [dispatch]) // Remove locale dependency return <>{children} } diff --git a/apps/web/src/pages/App/Header.tsx b/apps/web/src/pages/App/Header.tsx index e7d2b4cc3b6..f0200ef503d 100644 --- a/apps/web/src/pages/App/Header.tsx +++ b/apps/web/src/pages/App/Header.tsx @@ -40,7 +40,8 @@ export const Header = memo(function Header() { `} - {extensionEligible && } + {/* Get App banner is hidden - only English is supported */} + {/* {extensionEligible && } */} {renderUkBanner && } {renderUniswapWrapped2025Banner} diff --git a/packages/uniswap/src/features/language/constants.ts b/packages/uniswap/src/features/language/constants.ts index ff62b74b71a..1ac55607220 100644 --- a/packages/uniswap/src/features/language/constants.ts +++ b/packages/uniswap/src/features/language/constants.ts @@ -78,42 +78,43 @@ export const WALLET_SUPPORTED_LANGUAGES: Language[] = [ // Web's supported Languages // order as they appear in the language dropdown +// Only English is supported - other languages are disabled export const WEB_SUPPORTED_LANGUAGES: Language[] = [ Language.English, - Language.ChineseSimplified, - Language.ChineseTraditional, - Language.Dutch, - Language.French, - Language.Indonesian, - Language.Japanese, - Language.Korean, - Language.Portuguese, - Language.Russian, - Language.SpanishSpain, - Language.SpanishLatam, - Language.SpanishUnitedStates, - Language.SpanishArgentina, - Language.SpanishBolivia, - Language.SpanishChile, - Language.SpanishColombia, - Language.SpanishCostaRica, - Language.SpanishEcuador, - Language.SpanishParaguay, - Language.SpanishUruguay, - Language.SpanishVenezuela, - Language.SpanishBelize, - Language.SpanishCuba, - Language.SpanishDominicanRepublic, - Language.SpanishGuatemala, - Language.SpanishHonduras, - Language.SpanishMexico, - Language.SpanishNicaragua, - Language.SpanishPanama, - Language.SpanishPeru, - Language.SpanishPuertoRico, - Language.SpanishElSalvador, - Language.Turkish, - Language.Vietnamese, + // Language.ChineseSimplified, + // Language.ChineseTraditional, + // Language.Dutch, + // Language.French, + // Language.Indonesian, + // Language.Japanese, + // Language.Korean, + // Language.Portuguese, + // Language.Russian, + // Language.SpanishSpain, + // Language.SpanishLatam, + // Language.SpanishUnitedStates, + // Language.SpanishArgentina, + // Language.SpanishBolivia, + // Language.SpanishChile, + // Language.SpanishColombia, + // Language.SpanishCostaRica, + // Language.SpanishEcuador, + // Language.SpanishParaguay, + // Language.SpanishUruguay, + // Language.SpanishVenezuela, + // Language.SpanishBelize, + // Language.SpanishCuba, + // Language.SpanishDominicanRepublic, + // Language.SpanishGuatemala, + // Language.SpanishHonduras, + // Language.SpanishMexico, + // Language.SpanishNicaragua, + // Language.SpanishPanama, + // Language.SpanishPeru, + // Language.SpanishPuertoRico, + // Language.SpanishElSalvador, + // Language.Turkish, + // Language.Vietnamese, ] export const PLATFORM_SUPPORTED_LANGUAGES = isWebApp ? WEB_SUPPORTED_LANGUAGES : WALLET_SUPPORTED_LANGUAGES diff --git a/packages/uniswap/src/i18n/i18n-setup-interface.tsx b/packages/uniswap/src/i18n/i18n-setup-interface.tsx index 8e8858fe8af..9904b9ffb33 100644 --- a/packages/uniswap/src/i18n/i18n-setup-interface.tsx +++ b/packages/uniswap/src/i18n/i18n-setup-interface.tsx @@ -29,10 +29,12 @@ export function setupi18n(): undefined { return enUsLocale } - const fileName = getLocaleTranslationKey(locale) + // Only English is supported - return undefined for other languages + return undefined - // eslint-disable-next-line no-unsanitized/method - return import(`./locales/translations/${fileName}.json`) + // const fileName = getLocaleTranslationKey(locale) + // // eslint-disable-next-line no-unsanitized/method + // return import(`./locales/translations/${fileName}.json`) }), ) // eslint-disable-next-line max-params diff --git a/packages/uniswap/src/i18n/i18n-setup.tsx b/packages/uniswap/src/i18n/i18n-setup.tsx index 61cfdfc348a..ad0f73ea034 100644 --- a/packages/uniswap/src/i18n/i18n-setup.tsx +++ b/packages/uniswap/src/i18n/i18n-setup.tsx @@ -3,58 +3,60 @@ import 'uniswap/src/i18n/locales/@types/i18next' import i18n from 'i18next' import { initReactI18next } from 'react-i18next' import enUS from 'uniswap/src/i18n/locales/source/en-US.json' -import esES from 'uniswap/src/i18n/locales/translations/es-ES.json' -import frFR from 'uniswap/src/i18n/locales/translations/fr-FR.json' -import idID from 'uniswap/src/i18n/locales/translations/id-ID.json' -import jaJP from 'uniswap/src/i18n/locales/translations/ja-JP.json' -import nlNL from 'uniswap/src/i18n/locales/translations/nl-NL.json' -import ptPT from 'uniswap/src/i18n/locales/translations/pt-PT.json' -import ruRU from 'uniswap/src/i18n/locales/translations/ru-RU.json' -import trTR from 'uniswap/src/i18n/locales/translations/tr-TR.json' -import viVN from 'uniswap/src/i18n/locales/translations/vi-VN.json' -import zhCN from 'uniswap/src/i18n/locales/translations/zh-CN.json' -import zhTW from 'uniswap/src/i18n/locales/translations/zh-TW.json' +// Only English is supported - other languages are disabled +// import esES from 'uniswap/src/i18n/locales/translations/es-ES.json' +// import frFR from 'uniswap/src/i18n/locales/translations/fr-FR.json' +// import idID from 'uniswap/src/i18n/locales/translations/id-ID.json' +// import jaJP from 'uniswap/src/i18n/locales/translations/ja-JP.json' +// import nlNL from 'uniswap/src/i18n/locales/translations/nl-NL.json' +// import ptPT from 'uniswap/src/i18n/locales/translations/pt-PT.json' +// import ruRU from 'uniswap/src/i18n/locales/translations/ru-RU.json' +// import trTR from 'uniswap/src/i18n/locales/translations/tr-TR.json' +// import viVN from 'uniswap/src/i18n/locales/translations/vi-VN.json' +// import zhCN from 'uniswap/src/i18n/locales/translations/zh-CN.json' +// import zhTW from 'uniswap/src/i18n/locales/translations/zh-TW.json' import { MissingI18nInterpolationError } from 'uniswap/src/i18n/shared' import { getWalletDeviceLocale } from 'uniswap/src/i18n/utils' import { logger } from 'utilities/src/logger/logger' +// Only English is supported - other languages are disabled const resources = { - 'zh-Hans': { translation: zhCN, statsigKey: 'zh-CN' }, - 'zh-Hant': { translation: zhTW, statsigKey: 'zh-TW' }, - 'nl-NL': { translation: nlNL, statsigKey: 'nl-NL' }, 'en-US': { translation: enUS, statsigKey: 'en-US' }, - 'fr-FR': { translation: frFR, statsigKey: 'fr-FR' }, - 'id-ID': { translation: idID, statsigKey: 'id-ID' }, - 'ja-JP': { translation: jaJP, statsigKey: 'ja-JP' }, - 'pt-PT': { translation: ptPT, statsigKey: 'pt-PT' }, - 'ru-RU': { translation: ruRU, statsigKey: 'ru-RU' }, + // 'zh-Hans': { translation: zhCN, statsigKey: 'zh-CN' }, + // 'zh-Hant': { translation: zhTW, statsigKey: 'zh-TW' }, + // 'nl-NL': { translation: nlNL, statsigKey: 'nl-NL' }, + // 'fr-FR': { translation: frFR, statsigKey: 'fr-FR' }, + // 'id-ID': { translation: idID, statsigKey: 'id-ID' }, + // 'ja-JP': { translation: jaJP, statsigKey: 'ja-JP' }, + // 'pt-PT': { translation: ptPT, statsigKey: 'pt-PT' }, + // 'ru-RU': { translation: ruRU, statsigKey: 'ru-RU' }, // Spanish locales that use `,` as the decimal separator - 'es-419': { translation: esES, statsigKey: 'es-ES' }, - 'es-BZ': { translation: esES, statsigKey: 'es-ES' }, - 'es-CU': { translation: esES, statsigKey: 'es-ES' }, - 'es-DO': { translation: esES, statsigKey: 'es-ES' }, - 'es-GT': { translation: esES, statsigKey: 'es-ES' }, - 'es-HN': { translation: esES, statsigKey: 'es-ES' }, - 'es-MX': { translation: esES, statsigKey: 'es-ES' }, - 'es-NI': { translation: esES, statsigKey: 'es-ES' }, - 'es-PA': { translation: esES, statsigKey: 'es-ES' }, - 'es-PE': { translation: esES, statsigKey: 'es-ES' }, - 'es-PR': { translation: esES, statsigKey: 'es-ES' }, - 'es-SV': { translation: esES, statsigKey: 'es-ES' }, - 'es-US': { translation: esES, statsigKey: 'es-ES' }, + // 'es-419': { translation: esES, statsigKey: 'es-ES' }, + // 'es-BZ': { translation: esES, statsigKey: 'es-ES' }, + // 'es-CU': { translation: esES, statsigKey: 'es-ES' }, + // 'es-DO': { translation: esES, statsigKey: 'es-ES' }, + // 'es-GT': { translation: esES, statsigKey: 'es-ES' }, + // 'es-HN': { translation: esES, statsigKey: 'es-ES' }, + // 'es-MX': { translation: esES, statsigKey: 'es-ES' }, + // 'es-NI': { translation: esES, statsigKey: 'es-ES' }, + // 'es-PA': { translation: esES, statsigKey: 'es-ES' }, + // 'es-PE': { translation: esES, statsigKey: 'es-ES' }, + // 'es-PR': { translation: esES, statsigKey: 'es-ES' }, + // 'es-SV': { translation: esES, statsigKey: 'es-ES' }, + // 'es-US': { translation: esES, statsigKey: 'es-ES' }, // Spanish locales that use `.` as the decimal separator - 'es-AR': { translation: esES, statsigKey: 'es-ES' }, - 'es-BO': { translation: esES, statsigKey: 'es-ES' }, - 'es-CL': { translation: esES, statsigKey: 'es-ES' }, - 'es-CO': { translation: esES, statsigKey: 'es-ES' }, - 'es-CR': { translation: esES, statsigKey: 'es-ES' }, - 'es-EC': { translation: esES, statsigKey: 'es-ES' }, - 'es-ES': { translation: esES, statsigKey: 'es-ES' }, - 'es-PY': { translation: esES, statsigKey: 'es-ES' }, - 'es-UY': { translation: esES, statsigKey: 'es-ES' }, - 'es-VE': { translation: esES, statsigKey: 'es-ES' }, - 'tr-TR': { translation: trTR, statsigKey: 'tr-TR' }, - 'vi-VN': { translation: viVN, statsigKey: 'vi-VN' }, + // 'es-AR': { translation: esES, statsigKey: 'es-ES' }, + // 'es-BO': { translation: esES, statsigKey: 'es-ES' }, + // 'es-CL': { translation: esES, statsigKey: 'es-ES' }, + // 'es-CO': { translation: esES, statsigKey: 'es-ES' }, + // 'es-CR': { translation: esES, statsigKey: 'es-ES' }, + // 'es-EC': { translation: esES, statsigKey: 'es-ES' }, + // 'es-ES': { translation: esES, statsigKey: 'es-ES' }, + // 'es-PY': { translation: esES, statsigKey: 'es-ES' }, + // 'es-UY': { translation: esES, statsigKey: 'es-ES' }, + // 'es-VE': { translation: esES, statsigKey: 'es-ES' }, + // 'tr-TR': { translation: trTR, statsigKey: 'tr-TR' }, + // 'vi-VN': { translation: viVN, statsigKey: 'vi-VN' }, } const defaultNS = 'translation' @@ -63,7 +65,8 @@ i18n .use(initReactI18next) .init({ defaultNS, - lng: getWalletDeviceLocale(), + lng: 'en-US', // Force English only + // lng: getWalletDeviceLocale(), fallbackLng: 'en-US', resources, interpolation: { From e043f1ff2776aaecd1ac852c9f2465c278a2b33b Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Tue, 20 Jan 2026 14:37:54 +0800 Subject: [PATCH 12/33] feat: udpate sdk --- apps/extension/package.json | 2 +- .../types/UniversalRouterTypes.ts | 2 +- .../utils/getCalldataInfoFromTransaction.ts | 2 +- apps/extension/wxt.config.ts | 4 +- apps/web/package.json | 2 +- apps/web/src/hooks/useSwapCallback.tsx | 2 +- apps/web/src/hooks/useSwapTaxes.ts | 2 +- apps/web/src/hooks/useUniversalRouter.ts | 26 +- apps/web/src/pages/Swap/Limit/LimitForm.tsx | 2 +- .../web/src/pages/Swap/Swap.anvil.e2e.test.ts | 2 +- .../web/src/pages/Swap/Wrap.anvil.e2e.test.ts | 2 +- apps/web/src/playwright/fixtures/anvil.ts | 2 +- apps/web/src/state/index.ts | 13 +- .../src/state/sagas/transactions/swapSaga.ts | 84 +++++- .../sagas/transactions/useSwapHandlers.ts | 13 +- .../web/src/state/sagas/transactions/utils.ts | 64 ++++ apps/web/vite.config.mts | 4 +- bun.lock | 42 ++- packages/uniswap/package.json | 2 +- .../hooks/useHSKSubgraphPoolsForSelector.ts | 39 --- .../lists/TokenSelectorSwapList.tsx | 18 -- .../hooks/useTokenContextMenuOptions.ts | 2 +- .../swap/SwapFlow/CurrentScreen.web.tsx | 6 +- .../SwapConfirmationModal.tsx | 11 - .../SwapFormButton/SwapFormButton.tsx | 252 ++++++++++++++-- .../UnichainInstantBalanceModal/constants.ts | 8 + .../swap/form/hooks/useOnSelectCurrency.ts | 19 -- .../features/transactions/swap/plan/utils.ts | 20 +- .../hooks/useCreateSwapReviewCallbacks.tsx | 27 ++ .../services/swapTxAndGasInfoService/utils.ts | 273 +++++++++++++++++- .../swap/services/executeSwapService.ts | 40 ++- .../swap/services/hooks/usePrepareSwap.ts | 3 +- .../swap/services/prepareSwapService.ts | 19 +- .../transformations/buildQuoteRequest.ts | 28 -- .../hooks/useTransactionRequestInfo.ts | 112 ++++--- .../features/transactions/swap/utils/gas.ts | 28 +- .../utils/generateSwapTransactionSteps.ts | 59 +++- .../transactionServiceImpl.ts | 25 +- .../transactionSignerServiceImpl.ts | 10 + .../transactions/swap/executeSwapSaga.ts | 61 +++- .../swap/services/transactionExecutor.ts | 19 ++ 41 files changed, 1092 insertions(+), 259 deletions(-) diff --git a/apps/extension/package.json b/apps/extension/package.json index afe0d102858..31401636bb2 100644 --- a/apps/extension/package.json +++ b/apps/extension/package.json @@ -18,7 +18,7 @@ "@uniswap/analytics-events": "2.43.0", "@uniswap/client-embeddedwallet": "0.0.16", "@uniswap/sdk-core": "7.9.0", - "@uniswap/universal-router-sdk": "4.19.5", + "@hkdex-tmp/universal_router_sdk": "1.0.3", "@uniswap/v3-sdk": "3.25.2", "@uniswap/v4-sdk": "1.21.2", "@universe/api": "workspace:^", diff --git a/apps/extension/src/app/features/dappRequests/types/UniversalRouterTypes.ts b/apps/extension/src/app/features/dappRequests/types/UniversalRouterTypes.ts index 5990962ebb1..1090ed99fff 100644 --- a/apps/extension/src/app/features/dappRequests/types/UniversalRouterTypes.ts +++ b/apps/extension/src/app/features/dappRequests/types/UniversalRouterTypes.ts @@ -1,4 +1,4 @@ -import { CommandType } from '@uniswap/universal-router-sdk' +import { CommandType } from '@hkdex-tmp/universal_router_sdk' import { FeeAmount as FeeAmountV3 } from '@uniswap/v3-sdk' import { BigNumberSchema } from 'src/app/features/dappRequests/types/EthersTypes' import { z } from 'zod' diff --git a/apps/extension/src/background/utils/getCalldataInfoFromTransaction.ts b/apps/extension/src/background/utils/getCalldataInfoFromTransaction.ts index adff8212d30..924a5bc22b3 100644 --- a/apps/extension/src/background/utils/getCalldataInfoFromTransaction.ts +++ b/apps/extension/src/background/utils/getCalldataInfoFromTransaction.ts @@ -1,4 +1,4 @@ -import { CommandParser, UniversalRouterCall } from '@uniswap/universal-router-sdk' +import { CommandParser, UniversalRouterCall } from '@hkdex-tmp/universal_router_sdk' import { V4BaseActionsParser, V4RouterCall } from '@uniswap/v4-sdk' import { EthSendTransactionRPCActions } from 'src/app/features/dappRequests/types/DappRequestTypes' import { parseCalldata as parseNfPMCalldata } from 'src/app/features/dappRequests/types/NonfungiblePositionManager' diff --git a/apps/extension/wxt.config.ts b/apps/extension/wxt.config.ts index 6fa77e81623..45c8b956a46 100644 --- a/apps/extension/wxt.config.ts +++ b/apps/extension/wxt.config.ts @@ -170,7 +170,7 @@ export default defineConfig({ '@uniswap/v3-sdk', '@uniswap/v4-sdk', '@uniswap/router-sdk', - '@uniswap/universal-router-sdk', + '@hkdex-tmp/universal_router_sdk', '@uniswap/uniswapx-sdk', '@uniswap/permit2-sdk', 'jsbi', @@ -286,7 +286,7 @@ export default defineConfig({ '@uniswap/v3-sdk', '@uniswap/v4-sdk', '@uniswap/router-sdk', - '@uniswap/universal-router-sdk', + '@hkdex-tmp/universal_router_sdk', '@uniswap/uniswapx-sdk', '@uniswap/permit2-sdk', 'jsbi', diff --git a/apps/web/package.json b/apps/web/package.json index 365d3efdf79..b9d7ef6b90a 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -203,7 +203,7 @@ "@uniswap/sdk-core": "7.9.0", "@uniswap/token-lists": "1.0.0-beta.33", "@uniswap/uniswapx-sdk": "3.0.0-beta.7", - "@uniswap/universal-router-sdk": "4.19.5", + "@hkdex-tmp/universal_router_sdk": "1.0.3", "@uniswap/v2-core": "1.0.1", "@uniswap/v2-sdk": "4.15.2", "@uniswap/v3-core": "1.0.1", diff --git a/apps/web/src/hooks/useSwapCallback.tsx b/apps/web/src/hooks/useSwapCallback.tsx index 99657925bf2..81c25423e6b 100644 --- a/apps/web/src/hooks/useSwapCallback.tsx +++ b/apps/web/src/hooks/useSwapCallback.tsx @@ -1,7 +1,7 @@ import { BigNumber } from '@ethersproject/bignumber' import type { Percent } from '@uniswap/sdk-core' import { TradeType } from '@uniswap/sdk-core' -import type { FlatFeeOptions } from '@uniswap/universal-router-sdk' +import type { FlatFeeOptions } from '@hkdex-tmp/universal_router_sdk' import type { FeeOptions } from '@uniswap/v3-sdk' import { TradingApi } from '@universe/api' import { useAccount } from 'hooks/useAccount' diff --git a/apps/web/src/hooks/useSwapTaxes.ts b/apps/web/src/hooks/useSwapTaxes.ts index 607518b2945..b0019cf4ea2 100644 --- a/apps/web/src/hooks/useSwapTaxes.ts +++ b/apps/web/src/hooks/useSwapTaxes.ts @@ -1,5 +1,5 @@ import { Percent } from '@uniswap/sdk-core' -import { WETH_ADDRESS as getWethAddress } from '@uniswap/universal-router-sdk' +import { WETH_ADDRESS as getWethAddress } from '@hkdex-tmp/universal_router_sdk' import { BIPS_BASE, ZERO_PERCENT } from 'constants/misc' import { useAccount } from 'hooks/useAccount' import { useContract } from 'hooks/useContract' diff --git a/apps/web/src/hooks/useUniversalRouter.ts b/apps/web/src/hooks/useUniversalRouter.ts index b8f26d2fb15..ad02cb2e82e 100644 --- a/apps/web/src/hooks/useUniversalRouter.ts +++ b/apps/web/src/hooks/useUniversalRouter.ts @@ -7,7 +7,7 @@ import { SwapRouter, UNIVERSAL_ROUTER_ADDRESS, UniversalRouterVersion, -} from '@uniswap/universal-router-sdk' +} from '@hkdex-tmp/universal_router_sdk' import { FeeOptions, toHex } from '@uniswap/v3-sdk' import { useAccount } from 'hooks/useAccount' import { useEthersWeb3Provider } from 'hooks/useEthersProvider' @@ -103,6 +103,28 @@ export function useUniversalRouterSwapCallback({ const deadline = await getDeadline() + // Check if SwapRouter and UNIVERSAL_ROUTER_ADDRESS are available + if (!SwapRouter || typeof SwapRouter.swapCallParameters !== 'function') { + throw new Error('SwapRouter.swapCallParameters is not available in @hkdex-tmp/universal_router_sdk') + } + + if (!UNIVERSAL_ROUTER_ADDRESS || typeof UNIVERSAL_ROUTER_ADDRESS !== 'function') { + throw new Error('UNIVERSAL_ROUTER_ADDRESS is not available in @hkdex-tmp/universal_router_sdk') + } + + let routerAddress: string + try { + routerAddress = UNIVERSAL_ROUTER_ADDRESS(UniversalRouterVersion.V1_2, chainId) + } catch (error) { + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: Failed to get router address', { + error: error instanceof Error ? error.message : String(error), + chainId, + }) + } + throw new Error(`Failed to get router address for chain ${chainId}: ${error instanceof Error ? error.message : String(error)}`) + } + const { calldata: data, value } = SwapRouter.swapCallParameters(trade, { slippageTolerance: options.slippageTolerance, deadlineOrPreviousBlockhash: deadline?.toString(), @@ -112,7 +134,7 @@ export function useUniversalRouterSwapCallback({ }) const tx = { from: account.address, - to: UNIVERSAL_ROUTER_ADDRESS(UniversalRouterVersion.V1_2, chainId), + to: routerAddress, data, // TODO(https://github.com/Uniswap/universal-router-sdk/issues/113): universal-router-sdk returns a non-hexlified value. ...(value && !isZero(value) ? { value: toHex(value) } : {}), diff --git a/apps/web/src/pages/Swap/Limit/LimitForm.tsx b/apps/web/src/pages/Swap/Limit/LimitForm.tsx index b572055b66c..04250ace694 100644 --- a/apps/web/src/pages/Swap/Limit/LimitForm.tsx +++ b/apps/web/src/pages/Swap/Limit/LimitForm.tsx @@ -1,6 +1,6 @@ /* eslint-disable max-lines */ import { Currency, CurrencyAmount, Token } from '@uniswap/sdk-core' -import { UNIVERSAL_ROUTER_ADDRESS, UniversalRouterVersion } from '@uniswap/universal-router-sdk' +import { UNIVERSAL_ROUTER_ADDRESS, UniversalRouterVersion } from '@hkdex-tmp/universal_router_sdk' import { FeatureFlags, useFeatureFlag } from '@universe/gating' import { useAccountDrawer } from 'components/AccountDrawer/MiniPortfolio/hooks' import { OpenLimitOrdersButton } from 'components/AccountDrawer/MiniPortfolio/Limits/OpenLimitOrdersButton' diff --git a/apps/web/src/pages/Swap/Swap.anvil.e2e.test.ts b/apps/web/src/pages/Swap/Swap.anvil.e2e.test.ts index 9954cd060a6..67774bf3467 100644 --- a/apps/web/src/pages/Swap/Swap.anvil.e2e.test.ts +++ b/apps/web/src/pages/Swap/Swap.anvil.e2e.test.ts @@ -1,5 +1,5 @@ import { MaxUint160, MaxUint256, PERMIT2_ADDRESS } from '@uniswap/permit2-sdk' -import { UNIVERSAL_ROUTER_ADDRESS, UniversalRouterVersion } from '@uniswap/universal-router-sdk' +import { UNIVERSAL_ROUTER_ADDRESS, UniversalRouterVersion } from '@hkdex-tmp/universal_router_sdk' import { TradingApi } from '@universe/api' import { ONE_MILLION_USDT } from 'playwright/anvil/utils' import { expect, getTest } from 'playwright/fixtures' diff --git a/apps/web/src/pages/Swap/Wrap.anvil.e2e.test.ts b/apps/web/src/pages/Swap/Wrap.anvil.e2e.test.ts index dba692f2dba..28f490a56c0 100644 --- a/apps/web/src/pages/Swap/Wrap.anvil.e2e.test.ts +++ b/apps/web/src/pages/Swap/Wrap.anvil.e2e.test.ts @@ -1,4 +1,4 @@ -import { WETH_ADDRESS } from '@uniswap/universal-router-sdk' +import { WETH_ADDRESS } from '@hkdex-tmp/universal_router_sdk' import { createExpectSingleTransaction } from 'playwright/anvil/transactions' import { expect, getTest } from 'playwright/fixtures' import { stubTradingApiEndpoint } from 'playwright/fixtures/tradingApi' diff --git a/apps/web/src/playwright/fixtures/anvil.ts b/apps/web/src/playwright/fixtures/anvil.ts index cdaec4670df..b361d401d7f 100644 --- a/apps/web/src/playwright/fixtures/anvil.ts +++ b/apps/web/src/playwright/fixtures/anvil.ts @@ -1,7 +1,7 @@ // biome-ignore lint/style/noRestrictedImports: Anvil test fixtures need direct ethers imports import { test as base } from '@playwright/test' import { MaxUint160, MaxUint256, permit2Address } from '@uniswap/permit2-sdk' -import { WETH_ADDRESS } from '@uniswap/universal-router-sdk' +import { WETH_ADDRESS } from '@hkdex-tmp/universal_router_sdk' import type { AnvilClient as BaseAnvilClient } from 'playwright/anvil/anvil-manager' import { getAnvilManager } from 'playwright/anvil/anvil-manager' import { setErc20BalanceWithMultipleSlots } from 'playwright/anvil/utils' diff --git a/apps/web/src/state/index.ts b/apps/web/src/state/index.ts index 2a09646e52b..865040ea455 100644 --- a/apps/web/src/state/index.ts +++ b/apps/web/src/state/index.ts @@ -61,9 +61,15 @@ export function createDefaultStore() { ? false : { warnAfter: 128, - // meta.arg and meta.baseQueryMeta are defaults. payload.trade is a nonserializable return value, but that's ok + // meta.arg and meta.baseQueryMeta are defaults. payload.trade and payload.swapTxContext.trade are nonserializable return values, but that's ok // because we are not adding it into any persisted store that requires serialization (e.g. localStorage) - ignoredActionPaths: ['meta.arg', 'meta.baseQueryMeta', 'payload.trade'], + ignoredActionPaths: [ + 'meta.arg', + 'meta.baseQueryMeta', + 'payload.trade', + 'payload.swapTxContext.trade', + 'payload.swapTxContext', // Ignore entire swapTxContext as it contains non-serializable trade objects + ], ignoredPaths: [routingApi.reducerPath], ignoredActions: [ // ignore the redux-persist actions @@ -71,6 +77,9 @@ export function createDefaultStore() { 'persist/REHYDRATE', 'persist/PURGE', 'persist/FLUSH', + // ignore swapSaga actions as they contain non-serializable trade objects + 'swapSaga/trigger', + 'planSaga/trigger', ], }, }) diff --git a/apps/web/src/state/sagas/transactions/swapSaga.ts b/apps/web/src/state/sagas/transactions/swapSaga.ts index 7193610ad24..ea5bf6c7e70 100644 --- a/apps/web/src/state/sagas/transactions/swapSaga.ts +++ b/apps/web/src/state/sagas/transactions/swapSaga.ts @@ -78,13 +78,33 @@ import { useTrace } from 'utilities/src/telemetry/trace/TraceContext' function* handleSwapTransactionStep(params: HandleSwapStepParams): SagaGenerator { const { trade, step, signature, analytics, onTransactionHash } = params + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] handleSwapTransactionStep: Starting', { + stepType: step.type, + hasStep: !!step, + hasSignature: !!signature, + }) + } + const info = getSwapTransactionInfo({ trade, isFinalStep: analytics.is_final_step, swapStartTimestamp: analytics.swap_start_timestamp, }) + + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] handleSwapTransactionStep: Calling getSwapTxRequest') + } const txRequest = yield* call(getSwapTxRequest, step, signature) + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] handleSwapTransactionStep: Got txRequest:', { + hasTxRequest: !!txRequest, + to: txRequest?.to, + chainId: txRequest?.chainId, + }) + } + const onModification = ({ hash, data }: VitalTxFields) => { sendAnalyticsEvent(SwapEventName.SwapModifiedInWallet, { ...analytics, @@ -96,6 +116,14 @@ function* handleSwapTransactionStep(params: HandleSwapStepParams): SagaGenerator // Now that we have the txRequest, we can create a definitive SwapTransactionStep, incase we started with an async step. const onChainStep = { ...step, txRequest } + + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] handleSwapTransactionStep: About to call handleOnChainStep:', { + stepType: onChainStep.type, + hasTxRequest: !!onChainStep.txRequest, + }) + } + const hash = yield* call(handleOnChainStep, { ...params, info, @@ -103,8 +131,13 @@ function* handleSwapTransactionStep(params: HandleSwapStepParams): SagaGenerator ignoreInterrupt: true, // We avoid interruption during the swap step, since it is too late to give user a new trade once the swap is submitted. shouldWaitForConfirmation: false, onModification, + allowDuplicativeTx: true, // Allow duplicate transactions for swap - user may want to submit multiple swaps }) + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] handleSwapTransactionStep: handleOnChainStep returned hash:', hash) + } + handleSwapTransactionAnalytics({ ...params, hash }) const chainId = trade.inputAmount.currency.chainId @@ -223,13 +256,25 @@ function* swap(params: SwapParams) { } = params const { trade } = swapTxContext + const swapChainId = swapTxContext.trade.inputAmount.currency.chainId + const { chainSwitchFailed } = yield* call(handleSwitchChains, { selectChain: params.selectChain, startChainId: params.startChainId, swapTxContext, }) + if (chainSwitchFailed) { - onFailure() + const error = new Error(`Chain switch failed: unable to switch from chain ${params.startChainId} to chain ${swapChainId}`) + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: Chain switch failed', { + error: error.message, + startChainId: params.startChainId, + swapChainId, + }) + } + const onPressRetry = params.getOnPressRetry(error) + onFailure(error, onPressRetry) return } @@ -248,22 +293,43 @@ function* swap(params: SwapParams) { } for (step of steps) { + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] swap saga: Processing step:', { + stepType: step.type, + stepIndex: steps.indexOf(step), + }) + } switch (step.type) { case TransactionStepType.TokenRevocationTransaction: case TransactionStepType.TokenApprovalTransaction: { + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] swap saga: Handling approval step') + } yield* call(handleApprovalTransactionStep, { address: account.address, step, setCurrentStep }) break } case TransactionStepType.Permit2Signature: { + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] swap saga: Handling permit signature step') + } signature = yield* call(handleSignatureStep, { address: account.address, step, setCurrentStep }) break } case TransactionStepType.Permit2Transaction: { + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] swap saga: Handling permit transaction step') + } yield* call(handlePermitTransactionStep, { address: account.address, step, setCurrentStep }) break } case TransactionStepType.SwapTransaction: case TransactionStepType.SwapTransactionAsync: { + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] swap saga: Handling swap transaction step:', { + stepType: step.type, + hasTxRequest: !!step.txRequest, + }) + } requireRouting(trade, [TradingApi.Routing.CLASSIC, TradingApi.Routing.BRIDGE]) yield* call(handleSwapTransactionStep, { address: account.address, @@ -303,11 +369,20 @@ function* swap(params: SwapParams) { if (displayableError) { logger.error(displayableError, { tags: { file: 'swapSaga', function: 'swap' } }) } + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] swap saga: Error occurred:', { + error: displayableError?.message || error instanceof Error ? error.message : String(error), + stepType: step?.type, + }) + } const onPressRetry = params.getOnPressRetry(displayableError) onFailure(displayableError, onPressRetry) return } + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] swap saga: All steps completed, calling onSuccess') + } yield* call(onSuccess) } @@ -333,6 +408,13 @@ export function useSwapCallback(): SwapCallback { return useCallback( (args: SwapCallbackParams) => { + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] swapCallback called', { + routing: args.swapTxContext.routing, + hasTxRequests: !!args.swapTxContext.txRequests, + txRequestCount: args.swapTxContext.txRequests?.length || 0, + }) + } const { swapTxContext, onSuccess, diff --git a/apps/web/src/state/sagas/transactions/useSwapHandlers.ts b/apps/web/src/state/sagas/transactions/useSwapHandlers.ts index 8fb0a8040a5..e4ed1768bb4 100644 --- a/apps/web/src/state/sagas/transactions/useSwapHandlers.ts +++ b/apps/web/src/state/sagas/transactions/useSwapHandlers.ts @@ -83,7 +83,8 @@ export function useSwapHandlers(): SwapHandlers { } } else { // Handle regular swap transactions - swapCallback({ + try { + swapCallback({ account, swapTxContext, currencyInAmountUSD, @@ -100,6 +101,16 @@ export function useSwapHandlers(): SwapHandlers { isFiatInputMode, includesDelegation: swapTxContext.includesDelegation, }) + } catch (error) { + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: swapCallback threw error', { + error: error instanceof Error ? error.message : String(error), + errorDetails: error, + stack: error instanceof Error ? error.stack : undefined, + }) + } + onFailure(error instanceof Error ? error : new Error(String(error))) + } } }, [swapCallback, wrapCallback], diff --git a/apps/web/src/state/sagas/transactions/utils.ts b/apps/web/src/state/sagas/transactions/utils.ts index d2bebbbb760..d0223e8c4f3 100644 --- a/apps/web/src/state/sagas/transactions/utils.ts +++ b/apps/web/src/state/sagas/transactions/utils.ts @@ -124,10 +124,19 @@ export function* handleOnChainStep(params: Han addTransactionBreadcrumb({ step, data: { ...info } }) // Avoid sending prompting a transaction if the user already submitted an equivalent tx, e.g. by closing and reopening a transaction flow + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] handleOnChainStep: Checking for duplicative transaction') + } const duplicativeTx = yield* findDuplicativeTx({ info, address, chainId, allowDuplicativeTx }) const interfaceDuplicativeTx = duplicativeTx ? getInterfaceTransaction(duplicativeTx) : undefined if (interfaceDuplicativeTx && interfaceDuplicativeTx.hash) { + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] handleOnChainStep: Found duplicative transaction:', { + hash: interfaceDuplicativeTx.hash, + status: interfaceDuplicativeTx.status, + }) + } if (interfaceDuplicativeTx.status === TransactionStatus.Success) { addTransactionBreadcrumb({ step, @@ -146,10 +155,22 @@ export function* handleOnChainStep(params: Han } } + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] handleOnChainStep: No duplicative transaction found, proceeding with new transaction') + } + // Add a watcher to check if the transaction flow during user input const { throwIfInterrupted } = yield* watchForInterruption(ignoreInterrupt) // Trigger UI prompting user to accept + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] handleOnChainStep: Triggering UI to prompt user to accept:', { + stepType: step.type, + chainId, + hasTxRequest: !!step.txRequest, + to: step.txRequest?.to, + }) + } setCurrentStep({ step, accepted: false }) let transaction: InterfaceTransactionDetails @@ -188,6 +209,13 @@ export function* handleOnChainStep(params: Han // If should wait for confirmation, we block until the transaction is confirmed // Otherwise, we submit the transaction and return the hash immediately and spawn a detection task to check for modifications if (blockedAsyncSubmissionChainIds.includes(chainId) || shouldWaitForConfirmation) { + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] handleOnChainStep: Calling submitTransaction (sync):', { + chainId, + shouldWaitForConfirmation, + isBlockedAsync: blockedAsyncSubmissionChainIds.includes(chainId), + }) + } const { hash, data, nonce } = yield* call(submitTransaction, params) transaction = createTransaction(hash) @@ -198,6 +226,12 @@ export function* handleOnChainStep(params: Han yield* call(onModification, { hash, data, nonce }) } } else { + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] handleOnChainStep: Calling submitTransactionAsync:', { + chainId, + shouldWaitForConfirmation, + }) + } const hash = yield* call(submitTransactionAsync, params) transaction = createTransaction(hash) @@ -270,7 +304,21 @@ function* submitTransaction(params: HandleOnChainStepParams): SagaGenerator { '@uniswap/v3-sdk', '@uniswap/v4-sdk', '@uniswap/router-sdk', - '@uniswap/universal-router-sdk', + '@hkdex-tmp/universal_router_sdk', '@uniswap/uniswapx-sdk', '@uniswap/permit2-sdk', '@visx/responsive', @@ -326,7 +326,7 @@ export default defineConfig(({ mode }) => { '@uniswap/v3-sdk', '@uniswap/v4-sdk', '@uniswap/router-sdk', - '@uniswap/universal-router-sdk', + '@hkdex-tmp/universal_router_sdk', '@uniswap/uniswapx-sdk', '@uniswap/permit2-sdk', 'jsbi', diff --git a/bun.lock b/bun.lock index a95c4608ab5..291f4fdccf4 100644 --- a/bun.lock +++ b/bun.lock @@ -106,6 +106,7 @@ "@ethersproject/providers": "5.7.2", "@ethersproject/strings": "5.7.0", "@ethersproject/wordlists": "5.7.0", + "@hkdex-tmp/universal_router_sdk": "1.0.3", "@metamask/rpc-errors": "6.2.1", "@reduxjs/toolkit": "1.9.3", "@svgr/webpack": "8.0.1", @@ -115,7 +116,6 @@ "@uniswap/analytics-events": "2.43.0", "@uniswap/client-embeddedwallet": "0.0.16", "@uniswap/sdk-core": "7.9.0", - "@uniswap/universal-router-sdk": "4.19.5", "@uniswap/v3-sdk": "3.25.2", "@uniswap/v4-sdk": "1.21.2", "@universe/api": "workspace:^", @@ -396,6 +396,7 @@ "@graphql-codegen/typescript-operations": "3.0.4", "@graphql-codegen/typescript-react-apollo": "3.3.7", "@graphql-codegen/typescript-resolvers": "3.2.1", + "@hkdex-tmp/universal_router_sdk": "1.0.3", "@juggle/resize-observer": "3.4.0", "@popperjs/core": "2.11.8", "@reach/dialog": "0.10.5", @@ -430,7 +431,6 @@ "@uniswap/sdk-core": "7.9.0", "@uniswap/token-lists": "1.0.0-beta.33", "@uniswap/uniswapx-sdk": "3.0.0-beta.7", - "@uniswap/universal-router-sdk": "4.19.5", "@uniswap/v2-core": "1.0.1", "@uniswap/v2-sdk": "4.15.2", "@uniswap/v3-core": "1.0.1", @@ -894,6 +894,7 @@ "@ethersproject/units": "5.7.0", "@ethersproject/web": "5.7.1", "@gorhom/bottom-sheet": "4.6.4", + "@hkdex-tmp/universal_router_sdk": "1.0.3", "@react-navigation/core": "7.9.2", "@reduxjs/toolkit": "1.9.3", "@shopify/flash-list": "1.7.6", @@ -915,7 +916,6 @@ "@uniswap/router-sdk": "2.0.2", "@uniswap/sdk-core": "7.9.0", "@uniswap/uniswapx-sdk": "3.0.0-beta.7", - "@uniswap/universal-router-sdk": "4.19.5", "@uniswap/v2-sdk": "4.15.2", "@uniswap/v3-sdk": "3.25.2", "@uniswap/v4-sdk": "1.21.2", @@ -2248,6 +2248,8 @@ "@hapi/topo": ["@hapi/topo@5.1.0", "", { "dependencies": { "@hapi/hoek": "^9.0.0" } }, "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg=="], + "@hkdex-tmp/universal_router_sdk": ["@hkdex-tmp/universal_router_sdk@1.0.3", "", { "dependencies": { "@openzeppelin/contracts": "4.7.0", "@uniswap/permit2-sdk": "^1.3.0", "@uniswap/router-sdk": "^2.3.3", "@uniswap/sdk-core": "npm:@hkdex-tmp/sdk-core@1.0.1", "@uniswap/universal-router": "2.0.0-beta.2", "@uniswap/v2-core": "^1.0.1", "@uniswap/v2-sdk": "^4.17.0", "@uniswap/v3-core": "1.0.0", "@uniswap/v3-sdk": "^3.27.0", "@uniswap/v4-sdk": "^1.25.2", "bignumber.js": "^9.0.2", "ethers": "^5.7.0" } }, "sha512-f1Y47/kKNwLq+e3tAlJzvPPzDP/0pOSv38hk2fa7faMQHsLqh5HxDXXm7ttQOkrfgW4ZdXpp02fu7h8cxBwuDQ=="], + "@humanwhocodes/config-array": ["@humanwhocodes/config-array@0.13.0", "", { "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" } }, "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw=="], "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="], @@ -3966,8 +3968,6 @@ "@uniswap/universal-router": ["@uniswap/universal-router@2.0.0-beta.2", "", { "dependencies": { "@openzeppelin/contracts": "5.0.2", "@uniswap/v2-core": "1.0.1", "@uniswap/v3-core": "1.0.0" } }, "sha512-/USVkWZrOCjLeZluR7Yk8SpfWDUKG/MLcOyuxuwnqM1xCJj5ekguSYhct+Yfo/3t9fsZcnL8vSYgz0MKqAomGg=="], - "@uniswap/universal-router-sdk": ["@uniswap/universal-router-sdk@4.19.5", "", { "dependencies": { "@openzeppelin/contracts": "4.7.0", "@uniswap/permit2-sdk": "^1.3.0", "@uniswap/router-sdk": "^2.0.2", "@uniswap/sdk-core": "^7.7.1", "@uniswap/universal-router": "2.0.0-beta.2", "@uniswap/v2-core": "^1.0.1", "@uniswap/v2-sdk": "^4.15.2", "@uniswap/v3-core": "1.0.0", "@uniswap/v3-sdk": "^3.25.2", "@uniswap/v4-sdk": "^1.21.2", "bignumber.js": "^9.0.2", "ethers": "^5.7.0" } }, "sha512-FpfvTrJnvxhLdfX1N+GqOfAbHEsbFHP7J3JbpSAFWl3QDW63BB1/rqgW3E17xQha+WnPdP7uMLHwe7oi6mr39Q=="], - "@uniswap/v2-core": ["@uniswap/v2-core@1.0.1", "", {}, "sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q=="], "@uniswap/v2-sdk": ["@uniswap/v2-sdk@4.15.2", "", { "dependencies": { "@ethersproject/address": "^5.0.2", "@ethersproject/solidity": "^5.0.9", "@uniswap/sdk-core": "^7.7.1", "tiny-invariant": "^1.1.0", "tiny-warning": "^1.0.3" } }, "sha512-EtROgWTdhHzw4EUj7SdK9wjppOG7psJ16c656cRuv69nWbD9QyDL2shVcQccEiY7ak9WlJ+bIv/VldybXYBDuw=="], @@ -9640,6 +9640,14 @@ "@grpc/grpc-js/@grpc/proto-loader": ["@grpc/proto-loader@0.8.0", "", { "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", "protobufjs": "^7.5.3", "yargs": "^17.7.2" }, "bin": { "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" } }, "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ=="], + "@hkdex-tmp/universal_router_sdk/@uniswap/sdk-core": ["@hkdex-tmp/sdk-core@1.0.1", "", { "dependencies": { "@ethersproject/address": "^5.0.2", "@ethersproject/bytes": "^5.7.0", "@ethersproject/keccak256": "5.7.0", "@ethersproject/strings": "5.7.0", "big.js": "^5.2.2", "decimal.js-light": "^2.5.0", "jsbi": "^3.1.4", "tiny-invariant": "^1.1.0", "toformat": "^2.0.0" } }, "sha512-zyyURHf0SKYz2q6pmKSkBp1/th/s2bU1bw/OsMvgfzb2DD5XytKj+X1E1KRbACKBzq8DP9vsnZTSJ5QgndMUBw=="], + + "@hkdex-tmp/universal_router_sdk/@uniswap/v3-core": ["@uniswap/v3-core@1.0.0", "", {}, "sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA=="], + + "@hkdex-tmp/universal_router_sdk/@uniswap/v3-sdk": ["@uniswap/v3-sdk@3.27.0", "", { "dependencies": { "@ethersproject/abi": "^5.5.0", "@ethersproject/solidity": "^5.0.9", "@uniswap/sdk-core": "^7.10.0", "@uniswap/swap-router-contracts": "^1.3.0", "@uniswap/v3-periphery": "^1.1.1", "@uniswap/v3-staker": "1.0.0", "tiny-invariant": "^1.1.0", "tiny-warning": "^1.0.3" } }, "sha512-BRgb9nWuxptXJmuQrax9XyqcuOMEuWsUjDSyus0UvOavzijbOu8jh3DWptg/15D7oL67Xmz5zvQaSPbLIL1cpA=="], + + "@hkdex-tmp/universal_router_sdk/@uniswap/v4-sdk": ["@uniswap/v4-sdk@1.25.5", "", { "dependencies": { "@ethersproject/solidity": "^5.0.9", "@uniswap/sdk-core": "^7.10.0", "@uniswap/v3-sdk": "3.26.0", "tiny-invariant": "^1.1.0", "tiny-warning": "^1.0.3" } }, "sha512-S5hlrurvNOQW9dwdSgfsZZMaO2s0oek4268uUJSVB7VQxDI587jG3aDA2cHQo0q26uasIInrz7eCqCc3jVHvBw=="], + "@humanwhocodes/config-array/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], "@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], @@ -10340,8 +10348,6 @@ "@uniswap/universal-router/@uniswap/v3-core": ["@uniswap/v3-core@1.0.0", "", {}, "sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA=="], - "@uniswap/universal-router-sdk/@uniswap/v3-core": ["@uniswap/v3-core@1.0.0", "", {}, "sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA=="], - "@uniswap/v3-periphery/@openzeppelin/contracts": ["@openzeppelin/contracts@3.4.2-solc-0.7", "", {}, "sha512-W6QmqgkADuFcTLzHL8vVoNBtkwjvQRpYIAom7KiUNoLKghyx3FgH0GBjt8NRvigV1ZmMOBllvE1By1C+bi8WpA=="], "@uniswap/v3-staker/@openzeppelin/contracts": ["@openzeppelin/contracts@3.4.1-solc-0.7-2", "", {}, "sha512-tAG9LWg8+M2CMu7hIsqHPaTyG4uDzjr6mhvH96LvOpLZZj6tgzTluBt+LsCf1/QaYrlis6pITvpIaIhE+iZB+Q=="], @@ -12532,6 +12538,20 @@ "@graphql-tools/wrap/@graphql-tools/schema/@graphql-tools/merge": ["@graphql-tools/merge@8.4.2", "", { "dependencies": { "@graphql-tools/utils": "^9.2.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-XbrHAaj8yDuINph+sAfuq3QCZ/tKblrTLOpirK0+CAgNlZUCHs0Fa+xtMUURgwCVThLle1AF7svJCxFizygLsw=="], + "@hkdex-tmp/universal_router_sdk/@uniswap/sdk-core/@ethersproject/address": ["@ethersproject/address@5.8.0", "", { "dependencies": { "@ethersproject/bignumber": "^5.8.0", "@ethersproject/bytes": "^5.8.0", "@ethersproject/keccak256": "^5.8.0", "@ethersproject/logger": "^5.8.0", "@ethersproject/rlp": "^5.8.0" } }, "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA=="], + + "@hkdex-tmp/universal_router_sdk/@uniswap/sdk-core/tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="], + + "@hkdex-tmp/universal_router_sdk/@uniswap/v3-sdk/@uniswap/sdk-core": ["@uniswap/sdk-core@7.9.0", "", { "dependencies": { "@ethersproject/address": "^5.0.2", "@ethersproject/bytes": "^5.7.0", "@ethersproject/keccak256": "5.7.0", "@ethersproject/strings": "5.7.0", "big.js": "^5.2.2", "decimal.js-light": "^2.5.0", "jsbi": "^3.1.4", "tiny-invariant": "^1.1.0", "toformat": "^2.0.0" } }, "sha512-HHUFNK3LMi4KMQCAiHkdUyL62g/nrZLvNT44CY8RN4p8kWO6XYWzqdQt6OcjCsIbhMZ/Ifhe6Py5oOoccg/jUQ=="], + + "@hkdex-tmp/universal_router_sdk/@uniswap/v3-sdk/tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="], + + "@hkdex-tmp/universal_router_sdk/@uniswap/v4-sdk/@uniswap/sdk-core": ["@uniswap/sdk-core@7.9.0", "", { "dependencies": { "@ethersproject/address": "^5.0.2", "@ethersproject/bytes": "^5.7.0", "@ethersproject/keccak256": "5.7.0", "@ethersproject/strings": "5.7.0", "big.js": "^5.2.2", "decimal.js-light": "^2.5.0", "jsbi": "^3.1.4", "tiny-invariant": "^1.1.0", "toformat": "^2.0.0" } }, "sha512-HHUFNK3LMi4KMQCAiHkdUyL62g/nrZLvNT44CY8RN4p8kWO6XYWzqdQt6OcjCsIbhMZ/Ifhe6Py5oOoccg/jUQ=="], + + "@hkdex-tmp/universal_router_sdk/@uniswap/v4-sdk/@uniswap/v3-sdk": ["@uniswap/v3-sdk@3.26.0", "", { "dependencies": { "@ethersproject/abi": "^5.5.0", "@ethersproject/solidity": "^5.0.9", "@uniswap/sdk-core": "^7.8.0", "@uniswap/swap-router-contracts": "^1.3.0", "@uniswap/v3-periphery": "^1.1.1", "@uniswap/v3-staker": "1.0.0", "tiny-invariant": "^1.1.0", "tiny-warning": "^1.0.3" } }, "sha512-bcoWNE7ntNNTHMOnDPscIqtIN67fUyrbBKr6eswI2gD2wm5b0YYFBDeh+Qc5Q3117o9i8S7QdftqrU8YSMQUfQ=="], + + "@hkdex-tmp/universal_router_sdk/@uniswap/v4-sdk/tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="], + "@humanwhocodes/config-array/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], "@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], @@ -14664,6 +14684,14 @@ "@graphql-tools/prisma-loader/chalk/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + "@hkdex-tmp/universal_router_sdk/@uniswap/sdk-core/@ethersproject/address/@ethersproject/bignumber": ["@ethersproject/bignumber@5.8.0", "", { "dependencies": { "@ethersproject/bytes": "^5.8.0", "@ethersproject/logger": "^5.8.0", "bn.js": "^5.2.1" } }, "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA=="], + + "@hkdex-tmp/universal_router_sdk/@uniswap/sdk-core/@ethersproject/address/@ethersproject/keccak256": ["@ethersproject/keccak256@5.8.0", "", { "dependencies": { "@ethersproject/bytes": "^5.8.0", "js-sha3": "0.8.0" } }, "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng=="], + + "@hkdex-tmp/universal_router_sdk/@uniswap/v3-sdk/@uniswap/sdk-core/tiny-invariant": ["tiny-invariant@1.3.1", "", {}, "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw=="], + + "@hkdex-tmp/universal_router_sdk/@uniswap/v4-sdk/@uniswap/sdk-core/tiny-invariant": ["tiny-invariant@1.3.1", "", {}, "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw=="], + "@jest/console/@jest/types/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.34.41", "", {}, "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g=="], "@jest/console/chalk/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], diff --git a/packages/uniswap/package.json b/packages/uniswap/package.json index edc4520cb45..fe1e71ac21a 100644 --- a/packages/uniswap/package.json +++ b/packages/uniswap/package.json @@ -58,7 +58,7 @@ "@uniswap/router-sdk": "2.0.2", "@uniswap/sdk-core": "7.9.0", "@uniswap/uniswapx-sdk": "3.0.0-beta.7", - "@uniswap/universal-router-sdk": "4.19.5", + "@hkdex-tmp/universal_router_sdk": "1.0.3", "@uniswap/v2-sdk": "4.15.2", "@uniswap/v3-sdk": "3.25.2", "@uniswap/v4-sdk": "1.21.2", diff --git a/packages/uniswap/src/components/TokenSelector/hooks/useHSKSubgraphPoolsForSelector.ts b/packages/uniswap/src/components/TokenSelector/hooks/useHSKSubgraphPoolsForSelector.ts index 685b81c0532..61a023e295c 100644 --- a/packages/uniswap/src/components/TokenSelector/hooks/useHSKSubgraphPoolsForSelector.ts +++ b/packages/uniswap/src/components/TokenSelector/hooks/useHSKSubgraphPoolsForSelector.ts @@ -47,15 +47,6 @@ interface PoolForSelector { } async function querySubgraph(query: string, variables: Record = {}) { - // Debug log - if (typeof window !== 'undefined') { - console.log('[useHSKSubgraphPoolsForSelector] Querying Subgraph:', { - url: SUBGRAPH_URL, - isLocalhost: window.location.hostname === 'localhost', - variables, - }) - } - try { const response = await fetch(SUBGRAPH_URL, { method: 'POST', @@ -70,34 +61,17 @@ async function querySubgraph(query: string, variables: Record = if (!response.ok) { const errorText = await response.text() - console.error('[useHSKSubgraphPoolsForSelector] HTTP error:', { - status: response.status, - statusText: response.statusText, - body: errorText, - }) throw new Error(`HTTP error! status: ${response.status}, body: ${errorText}`) } const data = await response.json() if (data.errors) { - console.error('[useHSKSubgraphPoolsForSelector] GraphQL errors:', data.errors) throw new Error(`GraphQL errors: ${JSON.stringify(data.errors, null, 2)}`) } - // Debug log - if (typeof window !== 'undefined') { - console.log('[useHSKSubgraphPoolsForSelector] Query success:', { - poolsCount: data.data?.pools?.length ?? 0, - }) - } - return data.data as SubgraphResponse } catch (error) { - console.error('[useHSKSubgraphPoolsForSelector] Query failed:', { - url: SUBGRAPH_URL, - error: error instanceof Error ? error.message : String(error), - }) throw error } } @@ -156,19 +130,6 @@ export function useHSKSubgraphPoolsForSelector(first: number = 1000) { queryFn: async () => { const data = await querySubgraph(TOP_POOLS_QUERY, { first }) const pools = data.pools.map(convertSubgraphPoolToPoolForSelector) - - // Debug log - if (typeof window !== 'undefined') { - console.log('[useHSKSubgraphPoolsForSelector] Converted pools:', { - originalCount: data.pools.length, - convertedCount: pools.length, - samplePool: pools[0] ? { - token0: pools[0].token0.symbol, - token1: pools[0].token1.symbol, - } : null, - }) - } - return pools }, staleTime: 60 * 1000, // 1 minute diff --git a/packages/uniswap/src/components/TokenSelector/lists/TokenSelectorSwapList.tsx b/packages/uniswap/src/components/TokenSelector/lists/TokenSelectorSwapList.tsx index 252fe1bc997..a45bf1a7690 100644 --- a/packages/uniswap/src/components/TokenSelector/lists/TokenSelectorSwapList.tsx +++ b/packages/uniswap/src/components/TokenSelector/lists/TokenSelectorSwapList.tsx @@ -51,24 +51,6 @@ function useTokenSectionsForSwap({ poolChainId, ) - // Debug logs - if (typeof window !== 'undefined') { - console.log('[TokenSelectorSwapList] Debug:', { - chainFilter, - poolChainId, - hskPools: hskPools?.length, - hskPoolsLoading, - hskPoolsError: hskPoolsError?.message, - poolTokensOptions: poolTokensOptions?.length, - poolTokensLoading, - samplePoolTokens: poolTokensOptions?.slice(0, 3).map(t => ({ - symbol: t.currencyInfo?.currency.symbol, - name: t.currencyInfo?.currency.name, - address: t.currencyInfo?.currency.address, - })), - }) - } - // Other token options commented out - 其他代币选项已注释 // const { // data: portfolioTokenOptions, diff --git a/packages/uniswap/src/features/portfolio/balances/hooks/useTokenContextMenuOptions.ts b/packages/uniswap/src/features/portfolio/balances/hooks/useTokenContextMenuOptions.ts index 1099d6f5350..233829cb468 100644 --- a/packages/uniswap/src/features/portfolio/balances/hooks/useTokenContextMenuOptions.ts +++ b/packages/uniswap/src/features/portfolio/balances/hooks/useTokenContextMenuOptions.ts @@ -1,5 +1,5 @@ import { SharedEventName } from '@uniswap/analytics-events' -import { isNativeCurrency } from '@uniswap/universal-router-sdk' +import { isNativeCurrency } from '@hkdex-tmp/universal_router_sdk' import { useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' import { useDispatch, useSelector } from 'react-redux' diff --git a/packages/uniswap/src/features/transactions/swap/SwapFlow/CurrentScreen.web.tsx b/packages/uniswap/src/features/transactions/swap/SwapFlow/CurrentScreen.web.tsx index b328adba0a1..421a5cffac9 100644 --- a/packages/uniswap/src/features/transactions/swap/SwapFlow/CurrentScreen.web.tsx +++ b/packages/uniswap/src/features/transactions/swap/SwapFlow/CurrentScreen.web.tsx @@ -36,8 +36,10 @@ export function CurrentScreen({ {/* We want to render the `Modal` from the start to allow the tamagui animation to happen once we switch the `isModalOpen` prop to `true`. We only render `SwapReviewScreen` once the user is truly on that step though. + + COMMENTED OUT: Second modal is disabled - using only the first SwapConfirmationModal */} - - + */} {isFlashblocksEnabled && } diff --git a/packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx b/packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx index 16d367eb199..126b167d8ed 100644 --- a/packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx +++ b/packages/uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal.tsx @@ -317,17 +317,6 @@ export function SwapConfirmationModal({ } }, [isOpen]) - // Debug: log modal state - if (process.env.NODE_ENV === 'development') { - console.log('SwapConfirmationModal render:', { - isOpen, - hasInputCurrency: !!inputCurrency, - hasOutputCurrency: !!outputCurrency, - hasInputCurrencyInfo: !!derivedSwapInfo.currencies[CurrencyField.INPUT], - hasOutputCurrencyInfo: !!derivedSwapInfo.currencies[CurrencyField.OUTPUT], - }) - } - // Don't render modal if it's not open if (!isOpen) { return <> diff --git a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx index e7865ec5661..c6ea26b0056 100644 --- a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx +++ b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx @@ -1,9 +1,10 @@ -import { useState } from 'react' +import { TradingApi } from '@universe/api' +import { useState, useCallback } from 'react' import { useTranslation } from 'react-i18next' import { Button, Flex, styled, useIsShortMobileDevice } from 'ui/src' import { useConnectionStatus } from 'uniswap/src/features/accounts/store/hooks' import { useIsWebFORNudgeEnabled } from 'uniswap/src/features/providers/webForNudgeProvider' -import { useTransactionModalContext } from 'uniswap/src/features/transactions/components/TransactionModal/TransactionModalContext' +import { TransactionScreen, useTransactionModalContext } from 'uniswap/src/features/transactions/components/TransactionModal/TransactionModalContext' import { SwapConfirmationModal } from 'uniswap/src/features/transactions/swap/components/SwapConfirmationModal/SwapConfirmationModal' import { useIsSwapButtonDisabled } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsSwapButtonDisabled' import { useIsMissingPlatformWallet } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsMissingPlatformWallet' @@ -12,10 +13,23 @@ import { useOnReviewPress } from 'uniswap/src/features/transactions/swap/compone import { useSwapFormButtonColors } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useSwapFormButtonColors' import { useSwapFormButtonText } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useSwapFormButtonText' import { SwapFormButtonTrace } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButtonTrace' -import { useSwapFormStoreDerivedSwapInfo } from 'uniswap/src/features/transactions/swap/stores/swapFormStore/useSwapFormStore' -import { TestID } from 'uniswap/src/test/fixtures/testIDs' -import { isWebPlatform } from 'utilities/src/platform' +import { useSwapFormStoreDerivedSwapInfo, useSwapFormStore } from 'uniswap/src/features/transactions/swap/stores/swapFormStore/useSwapFormStore' +import { usePrepareSwap } from 'uniswap/src/features/transactions/swap/services/hooks/usePrepareSwap' +import { useWarningService } from 'uniswap/src/features/transactions/swap/services/hooks/useWarningService' +import { useSwapDependenciesStore } from 'uniswap/src/features/transactions/swap/stores/swapDependenciesStore/useSwapDependenciesStore' +import { + ensureFreshSwapTxData, + useSwapParams, + useSwapTxAndGasInfoService, +} from 'uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/hooks' +import { useIsUnichainFlashblocksEnabled } from 'uniswap/src/features/transactions/swap/hooks/useIsUnichainFlashblocksEnabled' +import { shouldShowFlashblocksUI } from 'uniswap/src/features/transactions/swap/components/UnichainInstantBalanceModal/utils' +import { isValidSwapTxContext } from 'uniswap/src/features/transactions/swap/types/swapTxAndGasInfo' +import { tryCatch } from 'utilities/src/errors' +import { logger } from 'utilities/src/logger/logger' +import { isWebApp } from 'utilities/src/platform' import { useEvent } from 'utilities/src/react/hooks' +import { TestID } from 'uniswap/src/test/fixtures/testIDs' export const SWAP_BUTTON_TEXT_VARIANT = 'buttonLabel1' @@ -67,7 +81,7 @@ export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Ele const { handleOnReviewPress } = useOnReviewPress() const disabled = useIsSwapButtonDisabled() const buttonText = useSwapFormButtonText() - const { swapRedirectCallback } = useTransactionModalContext() + const { swapRedirectCallback, setScreen } = useTransactionModalContext() const { backgroundColor: buttonBackgroundColor, variant: buttonVariant, @@ -103,17 +117,6 @@ export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Ele // Check both the flag and the actual button text to be safe const shouldShowModal = (isWebFORNudgeEnabled || buttonText === swapTokensText) && !swapRedirectCallback - // Debug: log the values to help troubleshoot - if (process.env.NODE_ENV === 'development') { - console.log('SwapFormButton press:', { - isWebFORNudgeEnabled, - buttonText, - swapTokensText, - shouldShowModal, - swapRedirectCallback, - }) - } - if (shouldShowModal) { setIsSwapConfirmationModalOpen(true) } else { @@ -121,9 +124,222 @@ export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Ele } }) + // Get dependencies for swap execution + const getExecuteSwapService = useSwapDependenciesStore((s) => s.getExecuteSwapService) + const swapTxAndGasInfoService = useSwapTxAndGasInfoService() + const swapParams = useSwapParams() + const updateSwapForm = useSwapFormStore((s) => s.updateSwapForm) + const isFlashblocksEnabled = useIsUnichainFlashblocksEnabled(derivedSwapInfo.chainId) + const shouldShowConfirmedState = + (isFlashblocksEnabled && shouldShowFlashblocksUI(derivedSwapInfo.trade.trade?.routing)) || + // show the confirmed state for bridges + derivedSwapInfo.trade.trade?.routing === TradingApi.Routing.BRIDGE + + // Create callbacks for swap execution + const onSuccess = useCallback(() => { + if (process.env.NODE_ENV === 'development') { + console.log('[Swap Result] Swap succeeded!', { + chainId: derivedSwapInfo.chainId, + inputCurrency: derivedSwapInfo.currencies.input?.currency.symbol, + outputCurrency: derivedSwapInfo.currencies.output?.currency.symbol, + }) + } + // For Unichain networks, trigger confirmation and branch to stall+fetch logic (ie handle in component) + if (isFlashblocksEnabled && shouldShowConfirmedState) { + updateSwapForm({ + isConfirmed: true, + isSubmitting: false, + showPendingUI: false, + }) + return + } + + // On interface, the swap component stays mounted; after swap we reset the form to avoid showing the previous values. + if (isWebApp) { + updateSwapForm({ + exactAmountFiat: undefined, + exactAmountToken: '', + showPendingUI: false, + isConfirmed: false, + instantReceiptFetchTime: undefined, + instantOutputAmountRaw: undefined, + txHash: undefined, + txHashReceivedTime: undefined, + }) + setScreen(TransactionScreen.Form) + } + }, [setScreen, updateSwapForm, isFlashblocksEnabled, shouldShowConfirmedState, derivedSwapInfo]) + + const onFailure = useCallback( + (error?: Error) => { + if (process.env.NODE_ENV === 'development') { + console.log('[Swap Result] Swap failed:', { + error: error?.message || 'Unknown error', + }) + } + updateSwapForm({ isSubmitting: false, isConfirmed: false, showPendingUI: false }) + }, + [updateSwapForm], + ) + + const onPending = useCallback(() => { + // Skip pending UI only for Unichain networks with flashblocks-compatible routes + if (isFlashblocksEnabled && shouldShowConfirmedState) { + return + } + updateSwapForm({ showPendingUI: true }) + }, [updateSwapForm, isFlashblocksEnabled, shouldShowConfirmedState]) + + // Direct swap execution function + const executeSwapDirectly = useEvent(async () => { + try { + if (!swapParams.trade) { + const error = new Error('No `trade` found when calling `executeSwap`') + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: No trade found', { + swapParams: { + hasTrade: !!swapParams.trade, + hasDerivedSwapInfo: !!swapParams.derivedSwapInfo, + chainId: swapParams.derivedSwapInfo?.chainId, + }, + }) + } + onFailure(error) + return + } + + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] Starting swap execution...', { + trade: swapParams.trade, + chainId: swapParams.derivedSwapInfo.chainId, + }) + } + + // Ensure we have fresh transaction data before executing the swap + const { data: freshSwapTxData, error } = await tryCatch( + ensureFreshSwapTxData( + { + trade: swapParams.trade, + approvalTxInfo: swapParams.approvalTxInfo, + derivedSwapInfo: swapParams.derivedSwapInfo, + }, + swapTxAndGasInfoService, + ), + ) + + if (error) { + const wrappedError = new Error('Failed to ensure fresh transaction data when calling `executeSwap`', { + cause: error, + }) + + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: Failed to ensure fresh transaction data', { + error: error.message, + errorDetails: error, + cause: error instanceof Error ? error.cause : undefined, + }) + } + + logger.error(wrappedError, { + tags: { file: 'SwapFormButton', function: 'executeSwapDirectly' }, + }) + + onFailure(wrappedError) + return + } + + if (!freshSwapTxData) { + const error = new Error('Empty swap transaction data returned') + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: Empty swap transaction data', { + swapParams: { + trade: swapParams.trade, + chainId: swapParams.derivedSwapInfo.chainId, + }, + }) + } + onFailure(error) + return + } + + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] Transaction data prepared, executing swap...', { + txRequests: 'txRequests' in freshSwapTxData ? freshSwapTxData.txRequests : undefined, + gasEstimate: freshSwapTxData.gasFeeEstimation, + gasFee: freshSwapTxData.gasFee, + routing: freshSwapTxData.routing, + hasTrade: !!freshSwapTxData.trade, + isValidSwapTxContext: isValidSwapTxContext(freshSwapTxData), + swapTxContextKeys: Object.keys(freshSwapTxData), + }) + } + + if (!isValidSwapTxContext(freshSwapTxData)) { + const error = new Error('Invalid swap transaction context') + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: Invalid swap transaction context', { + swapTxContext: { + routing: freshSwapTxData.routing, + hasTrade: !!freshSwapTxData.trade, + hasTxRequests: 'txRequests' in freshSwapTxData ? !!freshSwapTxData.txRequests : false, + gasFee: freshSwapTxData.gasFee, + gasFeeEstimation: freshSwapTxData.gasFeeEstimation, + keys: Object.keys(freshSwapTxData), + }, + }) + } + onFailure(error) + return + } + + const executeSwapService = getExecuteSwapService({ + onSuccess, + onFailure, + onPending, + setCurrentStep: () => {}, + setSteps: () => {}, + getSwapTxContext: () => freshSwapTxData, + }) + + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] Calling executeSwapService.executeSwap()...') + } + + executeSwapService.executeSwap() + } catch (error) { + const swapError = error instanceof Error ? error : new Error(String(error)) + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: Unexpected error in executeSwapDirectly', { + error: swapError.message, + errorDetails: swapError, + stack: swapError.stack, + }) + } + logger.error(swapError, { + tags: { file: 'SwapFormButton', function: 'executeSwapDirectly' }, + }) + onFailure(swapError) + } + }) + + // Create a prepareSwap that executes swap directly instead of showing review screen + const warningService = useWarningService() + const prepareSwapDirectly = usePrepareSwap({ + warningService, + onExecuteSwapDirectly: () => { + // Execute swap directly without showing review screen + executeSwapDirectly() + }, + }) + const handleConfirmSwap = useEvent(() => { + if (process.env.NODE_ENV === 'development') { + console.log('swap tokens now') + } setIsSwapConfirmationModalOpen(false) - handleOnReviewPress() + // Use prepareSwapDirectly which will execute swap directly if no warnings + // If there are warnings, they will be shown, otherwise swap will execute + prepareSwapDirectly() }) const handleCloseModal = useEvent(() => { diff --git a/packages/uniswap/src/features/transactions/swap/components/UnichainInstantBalanceModal/constants.ts b/packages/uniswap/src/features/transactions/swap/components/UnichainInstantBalanceModal/constants.ts index 7d397ff058a..7487e15671a 100644 --- a/packages/uniswap/src/features/transactions/swap/components/UnichainInstantBalanceModal/constants.ts +++ b/packages/uniswap/src/features/transactions/swap/components/UnichainInstantBalanceModal/constants.ts @@ -18,6 +18,14 @@ export const CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS: Partial void) => { + if (process.env.NODE_ENV === 'development') { + console.log('[Swap Result] Swap failed:', { + error: error?.message || 'Unknown error', + errorDetails: error, + }) + } resetCurrentStep() // Create a new txId for the next transaction, as the existing one may be used in state to track the failed submission. @@ -99,6 +105,13 @@ export function useCreateSwapReviewCallbacks(ctx: { ) const onSuccess = useCallback(() => { + if (process.env.NODE_ENV === 'development') { + console.log('[Swap Result] Swap succeeded!', { + chainId: derivedSwapInfo.chainId, + inputCurrency: derivedSwapInfo.currencies.input?.currency.symbol, + outputCurrency: derivedSwapInfo.currencies.output?.currency.symbol, + }) + } // For Unichain networks, trigger confirmation and branch to stall+fetch logic (ie handle in component) if (isFlashblocksEnabled && shouldShowConfirmedState) { resetCurrentStep() @@ -152,6 +165,13 @@ export function useCreateSwapReviewCallbacks(ctx: { return } + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] Starting swap execution...', { + trade: swapParams.trade, + chainId: swapParams.derivedSwapInfo.chainId, + }) + } + // Ensure we have fresh transaction data before executing the swap. // We need this because we allow the user to click `Submit` when a new `/quote` response is being displayed in the UI // even though we might still not have the corresponding `/swap` response for that `/quote`. @@ -182,6 +202,13 @@ export function useCreateSwapReviewCallbacks(ctx: { return } + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] Transaction data prepared, executing swap...', { + txRequests: freshSwapTxData.txRequests, + gasEstimate: freshSwapTxData.gasFeeEstimation, + }) + } + const executeSwapService = getExecuteSwapService({ onSuccess, onFailure, diff --git a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts index 81f5c6ee21d..e46ab749298 100644 --- a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts +++ b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts @@ -54,6 +54,7 @@ import { import { SWAP_GAS_URGENCY_OVERRIDE } from 'uniswap/src/features/transactions/swap/utils/tradingApi' import type { ValidatedTransactionRequest } from 'uniswap/src/features/transactions/types/transactionRequests' import { CurrencyField } from 'uniswap/src/types/currency' +import { UniverseChainId } from 'uniswap/src/features/chains/types' import { logger } from 'utilities/src/logger/logger' import { isExtensionApp, isMobileApp, isWebApp } from 'utilities/src/platform' import type { ITraceContext } from 'utilities/src/telemetry/trace/TraceContext' @@ -216,7 +217,7 @@ function getGasFeeFromQuote( const gasPriceWei = swapQuote.gasPriceWei const gasUseEstimate = swapQuote.gasUseEstimate - if (gasPriceWei && gasUseEstimate) { + if (gasPriceWei && gasUseEstimate && typeof gasPriceWei === 'string' && typeof gasUseEstimate === 'string') { try { // Calculate: gasFee = gasPriceWei * gasUseEstimate const gasFeeValue = (BigInt(gasPriceWei) * BigInt(gasUseEstimate)).toString() @@ -234,6 +235,174 @@ function getGasFeeFromQuote( return { value: undefined, displayValue: undefined } } +/** + * Build transaction request from quote methodParameters when swap API response is not available + */ +function buildTxRequestFromQuote( + swapQuote: TradingApi.ClassicQuote | TradingApi.BridgeQuote | undefined, + chainId: number, +): providers.TransactionRequest[] | undefined { + // Type assertion: methodParameters exists in ClassicQuote but may not be in type definition + const quoteWithMethodParams = swapQuote as (TradingApi.ClassicQuote | TradingApi.BridgeQuote) & { + methodParameters?: { calldata: string; value: string } + } + + if (!quoteWithMethodParams?.methodParameters) { + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: No methodParameters in quote', { + hasSwapQuote: !!swapQuote, + chainId, + }) + } + return undefined + } + + const { calldata, value } = quoteWithMethodParams.methodParameters + + if (!calldata) { + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: No calldata in methodParameters', { + hasMethodParameters: !!quoteWithMethodParams?.methodParameters, + hasValue: !!value, + chainId, + }) + } + return undefined + } + + // Get Universal Router address from chainId + // For HashKey chains, use the first address from CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS if available + // Otherwise, try to get from UNIVERSAL_ROUTER_ADDRESS function + let routerAddress: string | undefined + let routerSource: string | undefined + + // Try to get from CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS first (for HashKey chains) + try { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const { CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS } = require('uniswap/src/features/transactions/swap/components/UnichainInstantBalanceModal/constants') + // eslint-disable-next-line @typescript-eslint/no-require-imports + const { UniverseChainId: UniverseChainIdEnum } = require('uniswap/src/features/chains/types') + + // Try both numeric key and enum key lookup + const chainIdAsEnum = chainId as UniverseChainId + let addresses = CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS[chainIdAsEnum] + + // If not found, try looking up by numeric value (for HashKey chains: 133, 177) + if (!addresses && (chainId === 133 || chainId === 177)) { + // Try direct numeric lookup + addresses = CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS[chainId as keyof typeof CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS] + // Also try enum lookup + if (!addresses) { + const hashKeyEnumValue = chainId === 133 ? UniverseChainIdEnum.HashKeyTestnet : UniverseChainIdEnum.HashKey + addresses = CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS[hashKeyEnumValue] + } + } + if (addresses && addresses.length > 0) { + routerAddress = addresses[0] + routerSource = 'CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS' + } + } catch (error) { + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: Failed to load CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS', { + error: error instanceof Error ? error.message : String(error), + chainId, + errorDetails: error, + }) + } + } + + // Fallback to UNIVERSAL_ROUTER_ADDRESS if available + if (!routerAddress) { + try { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const { UNIVERSAL_ROUTER_ADDRESS, UniversalRouterVersion } = require('@hkdex-tmp/universal_router_sdk') + routerAddress = UNIVERSAL_ROUTER_ADDRESS(UniversalRouterVersion.V1_2, chainId) + routerSource = 'UNIVERSAL_ROUTER_ADDRESS' + } catch (error) { + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: Failed to get router address from UNIVERSAL_ROUTER_ADDRESS', { + error: error instanceof Error ? error.message : String(error), + chainId, + }) + } + } + } + + if (!routerAddress) { + // For HashKey chains (133, 177), they may not use Universal Router + // In this case, we need to check if the quote's methodParameters contains a 'to' address + // or if the user has configured a custom router address + if (chainId === 133 || chainId === 177) { + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: HashKey chain does not have Universal Router configured', { + chainId, + routerSource, + message: 'Please configure the swap router address for HashKey chains in CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS', + suggestion: 'Add the HashKey swap router address to constants.ts', + }) + } + logger.error('HashKey chain does not have Universal Router configured', { + tags: { file: 'utils.ts', function: 'buildTxRequestFromQuote' }, + extra: { chainId }, + }) + // Return undefined to indicate that we cannot build the transaction request + // The user needs to configure the router address in CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS + return undefined + } + + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: Could not determine router address', { + chainId, + routerSource, + }) + } + logger.error('Could not determine Universal Router address', { + tags: { file: 'utils.ts', function: 'buildTxRequestFromQuote' }, + extra: { chainId }, + }) + return undefined + } + + // Build transaction request from quote methodParameters + // Note: chainId is required for validateTransactionRequest to pass validation + const txRequest: providers.TransactionRequest = { + to: routerAddress, + data: calldata, + value: value && value !== '0x00' ? value : undefined, + chainId, // Required for validation + } + + // Add gas limit from quote if available + // This is critical - quote's gasUseEstimate is more accurate than provider's estimate + // Add 20% buffer to gas limit for safety (to account for price changes, etc.) + const quoteWithGasEstimate = quoteWithMethodParams as (TradingApi.ClassicQuote | TradingApi.BridgeQuote) & { + gasUseEstimate?: string | number + } + if (quoteWithGasEstimate && 'gasUseEstimate' in quoteWithGasEstimate && quoteWithGasEstimate.gasUseEstimate) { + try { + const gasUseEstimateStr = String(quoteWithGasEstimate.gasUseEstimate) + // Add 20% buffer: gasLimit = gasUseEstimate * 1.2 + const gasLimitWithBuffer = (BigInt(gasUseEstimateStr) * BigInt(120)) / BigInt(100) + txRequest.gasLimit = gasLimitWithBuffer.toString() + + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] buildTxRequestFromQuote: Set gasLimit from quote', { + gasUseEstimate: gasUseEstimateStr, + gasLimitWithBuffer: gasLimitWithBuffer.toString(), + chainId, + }) + } + } catch (error) { + // If conversion fails, let prepareTransaction handle it + if (process.env.NODE_ENV === 'development') { + console.warn('[Swap] Failed to set gasLimit from quote:', error) + } + } + } + + return [txRequest] +} + export function createProcessSwapResponse({ gasStrategy }: { gasStrategy: GasStrategy }) { return function processSwapResponse({ response, @@ -244,6 +413,7 @@ export function createProcessSwapResponse({ gasStrategy }: { gasStrategy: GasStr swapRequestParams, isRevokeNeeded, permitsDontNeedSignature, + chainId, }: { response: SwapData | undefined error: Error | null @@ -253,30 +423,120 @@ export function createProcessSwapResponse({ gasStrategy }: { gasStrategy: GasStr swapRequestParams: TradingApi.CreateSwapRequest | undefined isRevokeNeeded: boolean permitsDontNeedSignature?: boolean + chainId?: number }): TransactionRequestInfo { - // We use the gasFee estimate from quote, as its more accurate - // Calculate gasFee from quote response (either directly from gasFee or from gasPriceWei * gasUseEstimate) - const swapGasFee = getGasFeeFromQuote(swapQuote, gasStrategy) + // Try to get chainId from swapQuote if not provided + let finalChainId = chainId + if (!finalChainId && swapQuote) { + // Try to get chainId from quote's token chain IDs + const quoteWithChainIds = swapQuote as (TradingApi.ClassicQuote | TradingApi.BridgeQuote) & { + tokenInChainId?: number | string + tokenOutChainId?: number | string + } + const tokenInChainId = 'tokenInChainId' in quoteWithChainIds ? quoteWithChainIds.tokenInChainId : undefined + const tokenOutChainId = 'tokenOutChainId' in quoteWithChainIds ? quoteWithChainIds.tokenOutChainId : undefined + + if (tokenInChainId && typeof tokenInChainId === 'number') { + finalChainId = tokenInChainId + } else if (tokenOutChainId && typeof tokenOutChainId === 'number') { + finalChainId = tokenOutChainId + } + } + + // Final fallback: use HashKeyTestnet (133) since we only support HSK chains + if (!finalChainId) { + finalChainId = 133 // UniverseChainId.HashKeyTestnet + } + + // We use the gasFee estimate from quote, as its more accurate + // Calculate gasFee from quote response (either directly from gasFee or from gasPriceWei * gasUseEstimate) + const swapGasFee = getGasFeeFromQuote(swapQuote, gasStrategy) // This is a case where simulation fails on backend, meaning txn is expected to fail const simulationError = getSimulationError({ swapQuote, isRevokeNeeded }) const gasEstimateError = simulationError ?? error + // Only set error if there's actually an error (not just an empty object) + // Check if error is a valid Error instance or has meaningful content + let finalError: Error | null = null + if (gasEstimateError) { + if (gasEstimateError instanceof Error) { + finalError = gasEstimateError + } else if (typeof gasEstimateError === 'object' && gasEstimateError !== null) { + // Check if it's not just an empty object + const errorKeys = Object.keys(gasEstimateError) + if (errorKeys.length > 0) { + // Convert to Error if it has content + finalError = new Error(JSON.stringify(gasEstimateError)) + } + } + } + const gasFeeResult = { value: swapGasFee.value, displayValue: swapGasFee.displayValue, isLoading: isSwapLoading, - error: gasEstimateError, + error: finalError, } const gasEstimate: SwapGasFeeEstimation = { swapEstimate: response?.gasEstimate, } + // Use swap API transactions if available, otherwise build from quote methodParameters + let txRequests: providers.TransactionRequest[] | undefined + + if (response?.transactions) { + txRequests = response.transactions + } else if (finalChainId && swapQuote) { + txRequests = buildTxRequestFromQuote(swapQuote, finalChainId) + if (!txRequests) { + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: Failed to build transaction requests from quote', { + chainId: finalChainId, + originalChainId: chainId, + hasSwapQuote: !!swapQuote, + hasMethodParameters: !!(swapQuote as any)?.methodParameters, + methodParameters: (() => { + const methodParams = (swapQuote as any)?.methodParameters + if (methodParams) { + return { + hasCalldata: !!methodParams.calldata, + hasValue: !!methodParams.value, + calldata: methodParams.calldata?.substring(0, 20) + '...', + } + } + return undefined + })(), + // This error means swap cannot proceed - txRequests is required + willCauseValidationFailure: true, + }) + } + } + } else { + // This should not happen if finalChainId fallback is working correctly + // But if it does, we should still try to build with finalChainId + if (finalChainId && swapQuote) { + txRequests = buildTxRequestFromQuote(swapQuote, finalChainId) + } else { + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: Cannot build transaction requests - missing required data', { + hasResponseTransactions: !!response?.transactions, + hasChainId: !!chainId, + hasFinalChainId: !!finalChainId, + hasSwapQuote: !!swapQuote, + chainId, + finalChainId, + swapQuoteKeys: swapQuote ? Object.keys(swapQuote) : undefined, + }) + } + } + } + return { gasFeeResult, - txRequests: response?.transactions, + txRequests, permitData: permitsDontNeedSignature ? undefined : permitData, gasEstimate, includesDelegation: response?.includesDelegation, @@ -373,6 +633,7 @@ export function createGasFields({ permitTxInfo.gasFeeResult, ) + const gasFeeEstimation: SwapGasFeeEstimation = { ...swapTxInfo.gasEstimate, approvalEstimate: approvalGasFeeResult.gasEstimate, diff --git a/packages/uniswap/src/features/transactions/swap/services/executeSwapService.ts b/packages/uniswap/src/features/transactions/swap/services/executeSwapService.ts index f817d1aae13..89be845c61c 100644 --- a/packages/uniswap/src/features/transactions/swap/services/executeSwapService.ts +++ b/packages/uniswap/src/features/transactions/swap/services/executeSwapService.ts @@ -55,17 +55,21 @@ export function createExecuteSwapService(ctx: { !isSignerMnemonicAccountDetails(account) || !isValidSwapTxContext(swapTxContext) ) { - ctx.onFailure( - new Error( - !account - ? 'No account available' - : !swapTxContext - ? 'Missing swap transaction context' - : !isSignerMnemonicAccountDetails(account) - ? 'Invalid account type - must be signer mnemonic account' - : 'Invalid swap transaction context', - ), - ) + const errorMessage = !account + ? 'No account available' + : !swapTxContext + ? 'Missing swap transaction context' + : !isSignerMnemonicAccountDetails(account) + ? 'Invalid account type - must be signer mnemonic account' + : 'Invalid swap transaction context' + + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: Validation failed in executeSwapService', { + error: errorMessage, + }) + } + + ctx.onFailure(new Error(errorMessage)) return } @@ -90,7 +94,19 @@ export function createExecuteSwapService(ctx: { wrapType, inputCurrencyAmount: currencyAmounts.input ?? undefined, }) - .catch(ctx.onFailure) + .catch((error) => { + const swapError = error instanceof Error ? error : new Error(String(error)) + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: onExecuteSwap failed', { + error: swapError.message, + errorDetails: swapError, + stack: swapError.stack, + accountAddress: account.address, + txId, + }) + } + ctx.onFailure(swapError) + }) }, } } diff --git a/packages/uniswap/src/features/transactions/swap/services/hooks/usePrepareSwap.ts b/packages/uniswap/src/features/transactions/swap/services/hooks/usePrepareSwap.ts index ec134e49a94..8e6ac78cde5 100644 --- a/packages/uniswap/src/features/transactions/swap/services/hooks/usePrepareSwap.ts +++ b/packages/uniswap/src/features/transactions/swap/services/hooks/usePrepareSwap.ts @@ -19,7 +19,7 @@ const getIsViewOnlyWallet = (activeAccount?: AccountDetails): boolean => { return activeAccount?.accountType === AccountType.Readonly } -export function usePrepareSwap(ctx: { warningService: WarningService }): () => void { +export function usePrepareSwap(ctx: { warningService: WarningService; onExecuteSwapDirectly?: () => void }): () => void { const { handleShowTokenWarningModal, handleShowBridgingWarningModal, @@ -79,6 +79,7 @@ export function usePrepareSwap(ctx: { warningService: WarningService }): () => v // ctx warningService: ctx.warningService, logger, + onExecuteSwapDirectly: ctx.onExecuteSwapDirectly, }), ) } diff --git a/packages/uniswap/src/features/transactions/swap/services/prepareSwapService.ts b/packages/uniswap/src/features/transactions/swap/services/prepareSwapService.ts index a9b9c9cc0a1..d7875ff0674 100644 --- a/packages/uniswap/src/features/transactions/swap/services/prepareSwapService.ts +++ b/packages/uniswap/src/features/transactions/swap/services/prepareSwapService.ts @@ -20,12 +20,14 @@ export function createPrepareSwap( const getAction = createGetAction(ctx) const handleEventAction = createHandleEventAction(ctx) - const action = getAction({ + const skipWarnings = { skipBridgingWarning: ctx.warningService.getSkipBridgingWarning(), skipMaxTransferWarning: ctx.warningService.getSkipMaxTransferWarning(), skipTokenProtectionWarning: ctx.warningService.getSkipTokenProtectionWarning(), skipBridgedAssetWarning: ctx.warningService.getSkipBridgedAssetWarning(), - }) + } + + const action = getAction(skipWarnings) handleEventAction(action) } catch (error) { @@ -35,6 +37,9 @@ export function createPrepareSwap( function: 'prepareSwap', }, }) + if (process.env.NODE_ENV === 'development') { + console.error('[prepareSwap] Error:', error) + } } // always reset the warning service after the action is handled ctx.warningService.reset() @@ -154,6 +159,7 @@ interface HandleEventActionContext { onConnectWallet?: (platform?: Platform) => void updateSwapForm: (newState: Partial) => void setScreen: (screen: TransactionScreen) => void + onExecuteSwapDirectly?: () => void } function createHandleEventAction(ctx: HandleEventActionContext): (action: ReviewAction) => void { @@ -167,6 +173,7 @@ function createHandleEventAction(ctx: HandleEventActionContext): (action: Review onConnectWallet, updateSwapForm, setScreen, + onExecuteSwapDirectly, } = ctx function handleEventAction(action: ReviewAction): void { switch (action.type) { @@ -193,8 +200,14 @@ function createHandleEventAction(ctx: HandleEventActionContext): (action: Review handleShowBridgedAssetModal() break case ReviewActionType.PROCEED_TO_REVIEW: - updateSwapForm({ txId: createTransactionId() }) + const txId = createTransactionId() + updateSwapForm({ txId }) + // If onExecuteSwapDirectly is provided, execute swap directly instead of showing review screen + if (onExecuteSwapDirectly) { + onExecuteSwapDirectly() + } else { setScreen(TransactionScreen.Review) + } break } } diff --git a/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/buildQuoteRequest.ts b/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/buildQuoteRequest.ts index 2a276d32bd6..bce005f374b 100644 --- a/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/buildQuoteRequest.ts +++ b/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/buildQuoteRequest.ts @@ -124,20 +124,6 @@ export function parseTradeInputForTradingApiQuote(input: UseTradeArgs): ParsedTr const tokenInChainId = toTradingApiSupportedChainId(currencyIn?.chainId) const tokenOutChainId = toTradingApiSupportedChainId(currencyOut?.chainId) - // Debug log - if (typeof window !== 'undefined') { - console.log('[parseTradeInputForTradingApiQuote] Parsing input:', { - currencyIn: currencyIn?.symbol, - currencyOut: currencyOut?.symbol, - currencyInChainId: currencyIn?.chainId, - currencyOutChainId: currencyOut?.chainId, - tokenInChainId, - tokenOutChainId, - amountSpecified: input.amountSpecified?.toExact(), - hasAmountSpecified: !!input.amountSpecified, - }) - } - return { currencyIn, currencyOut, @@ -169,20 +155,6 @@ export function validateParsedInput(input: ParsedTradeInput): ValidatedTradeInpu !input.currencyOut || areCurrenciesEqual(input.currencyIn, input.currencyOut) ) { - // Debug log to understand why validation fails - if (typeof window !== 'undefined') { - console.log('[validateParsedInput] Validation failed:', { - tokenInChainId: input.tokenInChainId, - tokenOutChainId: input.tokenOutChainId, - tokenInAddress: input.tokenInAddress, - tokenOutAddress: input.tokenOutAddress, - hasAmount: !!input.amount, - amountValue: input.amount?.toExact(), - currencyIn: input.currencyIn?.symbol, - currencyOut: input.currencyOut?.symbol, - areCurrenciesEqual: areCurrenciesEqual(input.currencyIn, input.currencyOut), - }) - } return undefined } diff --git a/packages/uniswap/src/features/transactions/swap/stores/swapTxStore/hooks/useTransactionRequestInfo.ts b/packages/uniswap/src/features/transactions/swap/stores/swapTxStore/hooks/useTransactionRequestInfo.ts index 78f27648f34..915ebd5b0c2 100644 --- a/packages/uniswap/src/features/transactions/swap/stores/swapTxStore/hooks/useTransactionRequestInfo.ts +++ b/packages/uniswap/src/features/transactions/swap/stores/swapTxStore/hooks/useTransactionRequestInfo.ts @@ -1,18 +1,14 @@ import { TradingApi } from '@universe/api' -import { DynamicConfigs, SwapConfigKey, useDynamicConfigValue } from '@universe/gating' import { useEffect, useMemo, useRef } from 'react' import { useUniswapContextSelector } from 'uniswap/src/contexts/UniswapContext' -import { useTradingApiSwapQuery } from 'uniswap/src/data/apiClients/tradingApi/useTradingApiSwapQuery' import { useActiveGasStrategy } from 'uniswap/src/features/gas/hooks' import { useAllTransactionSettings } from 'uniswap/src/features/transactions/components/settings/stores/transactionSettingsStore/useTransactionSettingsStore' -import { FALLBACK_SWAP_REQUEST_POLL_INTERVAL_MS } from 'uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/constants' import { processUniswapXResponse } from 'uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/uniswapx/utils' import type { TransactionRequestInfo } from 'uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils' import { createLogSwapRequestErrors, createPrepareSwapRequestParams, createProcessSwapResponse, - getShouldSkipSwapRequest, } from 'uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils' import { usePermit2SignatureWithData } from 'uniswap/src/features/transactions/swap/stores/swapTxStore/hooks/usePermit2Signature' import type { DerivedSwapInfo } from 'uniswap/src/features/transactions/swap/types/derivedSwapInfo' @@ -21,7 +17,10 @@ import { ApprovalAction } from 'uniswap/src/features/transactions/swap/types/tra import { isBridge, isClassic, isUniswapX, isWrap } from 'uniswap/src/features/transactions/swap/utils/routing' import { isWebApp } from 'utilities/src/platform' import { useTrace } from 'utilities/src/telemetry/trace/TraceContext' -import { ONE_SECOND_MS } from 'utilities/src/time/time' +import { useActiveAccount } from 'uniswap/src/features/accounts/store/hooks' +import { UniverseChainId } from 'uniswap/src/features/chains/types' +import { Platform } from 'uniswap/src/features/platforms/types/Platform' +import { usePrevious } from 'utilities/src/react/hooks' function useSwapTransactionRequestInfo({ derivedSwapInfo, @@ -31,24 +30,63 @@ function useSwapTransactionRequestInfo({ tokenApprovalInfo: TokenApprovalInfo | undefined }): TransactionRequestInfo { const trace = useTrace() - const gasStrategy = useActiveGasStrategy(derivedSwapInfo.chainId, 'general') const transactionSettings = useAllTransactionSettings() const permitData = derivedSwapInfo.trade.trade?.quote.permitData // On interface, we do not fetch signature until after swap is clicked, as it requires user interaction. const { data: signature } = usePermit2SignatureWithData({ permitData, skip: isWebApp }) + // Keep track of the last successful quote to use if current quote fails + const lastSuccessfulQuoteRef = useRef( + undefined, + ) + const swapQuoteResponse = useMemo(() => { const quote = derivedSwapInfo.trade.trade?.quote if (quote && (isClassic(quote) || isBridge(quote) || isWrap(quote))) { + // Update the last successful quote + lastSuccessfulQuoteRef.current = quote return quote } + // If current quote is not available, use the last successful quote + if (lastSuccessfulQuoteRef.current) { + return lastSuccessfulQuoteRef.current + } return undefined }, [derivedSwapInfo.trade.trade?.quote]) const swapQuote = swapQuoteResponse?.quote - const swapDelegationInfo = useUniswapContextSelector((ctx) => ctx.getSwapDelegationInfo?.(derivedSwapInfo.chainId)) + // Get current chainId from active account if derivedSwapInfo.chainId is not available + // We only support HSK chains (HashKey = 177, HashKeyTestnet = 133) + const activeAccount = useActiveAccount(Platform.EVM) + const currentChainId = (activeAccount as { chainId?: UniverseChainId } | undefined)?.chainId ?? derivedSwapInfo.chainId + + // Resolve chainId with multiple fallbacks + // Priority: 1. currentChainId (from account or derivedSwapInfo), 2. swapQuote tokenInChainId, 3. swapQuote tokenOutChainId, 4. default HashKeyTestnet + const resolvedChainId = useMemo(() => { + // First try: use currentChainId if available + if (currentChainId) { + return currentChainId + } + + // Second try: get from swapQuote tokenInChainId + if (swapQuote && 'tokenInChainId' in swapQuote && swapQuote.tokenInChainId) { + return swapQuote.tokenInChainId as UniverseChainId + } + + // Third try: get from swapQuote tokenOutChainId + if (swapQuote && 'tokenOutChainId' in swapQuote && swapQuote.tokenOutChainId) { + return swapQuote.tokenOutChainId as UniverseChainId + } + + // Final fallback: use HashKeyTestnet (133) since we only support HSK chains + return UniverseChainId.HashKeyTestnet + }, [currentChainId, swapQuote]) + + const gasStrategy = useActiveGasStrategy(resolvedChainId, 'general') + + const swapDelegationInfo = useUniswapContextSelector((ctx) => ctx.getSwapDelegationInfo?.(resolvedChainId)) const overrideSimulation = !!swapDelegationInfo?.delegationAddress const prepareSwapRequestParams = useMemo(() => createPrepareSwapRequestParams({ gasStrategy }), [gasStrategy]) @@ -77,47 +115,24 @@ function useSwapTransactionRequestInfo({ ]) const canBatchTransactions = useUniswapContextSelector((ctx) => - ctx.getCanBatchTransactions?.(derivedSwapInfo.chainId), + ctx.getCanBatchTransactions?.(resolvedChainId), ) const permitsDontNeedSignature = !!canBatchTransactions - const shouldSkipSwapRequest = getShouldSkipSwapRequest({ - derivedSwapInfo, - tokenApprovalInfo, - signature: signature ?? undefined, - permitsDontNeedSignature, - }) - - const tradingApiSwapRequestMs = useDynamicConfigValue({ - config: DynamicConfigs.Swap, - key: SwapConfigKey.TradingApiSwapRequestMs, - defaultValue: FALLBACK_SWAP_REQUEST_POLL_INTERVAL_MS, - }) - - const { - data, - error, - isLoading: isSwapLoading, - } = useTradingApiSwapQuery( - { - params: shouldSkipSwapRequest ? undefined : swapRequestParams, - refetchInterval: tradingApiSwapRequestMs, - staleTime: tradingApiSwapRequestMs, - // We add a small buffer in case connection is too slow - immediateGcTime: tradingApiSwapRequestMs + ONE_SECOND_MS * 5, - }, - { - canBatchTransactions, - swapDelegationAddress: swapDelegationInfo?.delegationAddress, - includesDelegation: swapDelegationInfo?.delegationInclusion, - }, - ) + + // Skip swap API call - use quote methodParameters directly instead + // Don't call swap API - we'll use quote methodParameters directly + const data = undefined + const error = null + const isSwapLoading = false const processSwapResponse = useMemo(() => createProcessSwapResponse({ gasStrategy }), [gasStrategy]) - const result = useMemo( - () => - processSwapResponse({ + const result = useMemo(() => { + // Ensure resolvedChainId is always defined + const chainIdToUse = resolvedChainId ?? UniverseChainId.HashKeyTestnet + + return processSwapResponse({ response: data, error, swapQuote, @@ -126,8 +141,9 @@ function useSwapTransactionRequestInfo({ swapRequestParams, isRevokeNeeded: tokenApprovalInfo?.action === ApprovalAction.RevokeAndPermit2Approve, permitsDontNeedSignature, - }), - [ + chainId: chainIdToUse, + }) + }, [ data, error, isSwapLoading, @@ -137,8 +153,12 @@ function useSwapTransactionRequestInfo({ processSwapResponse, tokenApprovalInfo?.action, permitsDontNeedSignature, - ], - ) + resolvedChainId, + derivedSwapInfo, + swapQuoteResponse, + activeAccount, + currentChainId, + ]) // Only log analytics events once per request const previousRequestIdRef = useRef(swapQuoteResponse?.requestId) diff --git a/packages/uniswap/src/features/transactions/swap/utils/gas.ts b/packages/uniswap/src/features/transactions/swap/utils/gas.ts index e31dd89ca12..8be515f6e6d 100644 --- a/packages/uniswap/src/features/transactions/swap/utils/gas.ts +++ b/packages/uniswap/src/features/transactions/swap/utils/gas.ts @@ -23,14 +23,38 @@ export function sumGasFees(gasFees: (string | undefined)[]): string | undefined * - displayValue: Sum of all display values (undefined if any result has error or missing value) */ export function mergeGasFeeResults(...gasFeeResults: GasFeeResult[]): GasFeeResult { - const error = gasFeeResults.map((g) => g.error).find((e) => !!e) ?? null + // Filter out "Approval action unknown" errors - these are informational and shouldn't block swap + // Also filter out empty objects and empty Error instances + const meaningfulErrors = gasFeeResults + .map((g) => g.error) + .filter((e) => { + if (!e) return false + if (e instanceof Error) { + // Filter out empty Error objects and "Approval action unknown" errors + if (!e.message || e.message.length === 0) return false + if (e.message === 'Approval action unknown') return false + return true + } + if (typeof e === 'object' && Object.keys(e).length > 0) return true + // Empty object {} should be filtered out + return false + }) + + // Use the first meaningful error, or null if none + const error = meaningfulErrors[0] ?? null + const isLoading = gasFeeResults.some((r) => r.isLoading) - const expectedValueMissing = gasFeeResults.some((r) => r.value === undefined) + // Only consider value missing if it's missing AND there's a meaningful error + // If value is missing but error is null (or filtered out), we can still proceed if other results have values + const resultsWithValues = gasFeeResults.filter((r) => r.value !== undefined) + const expectedValueMissing = resultsWithValues.length === 0 && error !== null + if (expectedValueMissing || error) { return { value: undefined, displayValue: undefined, error, isLoading } } + // Sum only the values that are defined const value = sumGasFees(gasFeeResults.map((r) => r.value)) const displayValue = sumGasFees(gasFeeResults.map((r) => r.displayValue)) return { value, displayValue, error, isLoading } diff --git a/packages/uniswap/src/features/transactions/swap/utils/generateSwapTransactionSteps.ts b/packages/uniswap/src/features/transactions/swap/utils/generateSwapTransactionSteps.ts index 1f6da056acf..099ec5cb1ce 100644 --- a/packages/uniswap/src/features/transactions/swap/utils/generateSwapTransactionSteps.ts +++ b/packages/uniswap/src/features/transactions/swap/utils/generateSwapTransactionSteps.ts @@ -17,6 +17,18 @@ import { isBridge, isClassic, isUniswapX } from 'uniswap/src/features/transactio export function generateSwapTransactionSteps(txContext: SwapTxAndGasInfo): TransactionStep[] { const isValidSwap = isValidSwapTxContext(txContext) + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] generateSwapTransactionSteps:', { + isValidSwap, + routing: txContext.routing, + hasTxRequests: !!txContext.txRequests, + txRequestCount: txContext.txRequests?.length || 0, + isClassic: isClassic(txContext), + isBridge: isBridge(txContext), + isUniswapX: isUniswapX(txContext), + }) + } + if (isValidSwap) { const { trade, approveTxRequest, revocationTxRequest } = txContext @@ -59,33 +71,62 @@ export function generateSwapTransactionSteps(txContext: SwapTxAndGasInfo): Trans }) : undefined - return orderClassicSwapSteps({ + const steps = orderClassicSwapSteps({ revocation, approval, permit, swap: createSwapTransactionStep(txContext.txRequests[0]), }) + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] generateSwapTransactionSteps: Returning classic steps:', { + stepCount: steps.length, + stepTypes: steps.map((s) => s.type), + }) + } + return steps } else if (isUniswapX(txContext)) { - return orderUniswapXSteps({ + const steps = orderUniswapXSteps({ revocation, approval, signOrder: createSignUniswapXOrderStep(txContext.permit.typedData, txContext.trade.quote.quote), }) + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] generateSwapTransactionSteps: Returning UniswapX steps:', { + stepCount: steps.length, + stepTypes: steps.map((s) => s.type), + }) + } + return steps } else if (isBridge(txContext)) { + let steps: TransactionStep[] if (txContext.txRequests.length > 1) { - return orderClassicSwapSteps({ + steps = orderClassicSwapSteps({ permit: undefined, swap: createSwapTransactionStepBatched(txContext.txRequests), }) + } else { + steps = orderClassicSwapSteps({ + revocation, + approval, + permit: undefined, + swap: createSwapTransactionStep(txContext.txRequests[0]), + }) } - return orderClassicSwapSteps({ - revocation, - approval, - permit: undefined, - swap: createSwapTransactionStep(txContext.txRequests[0]), - }) + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] generateSwapTransactionSteps: Returning bridge steps:', { + stepCount: steps.length, + stepTypes: steps.map((s) => s.type), + }) + } + return steps } } + if (process.env.NODE_ENV === 'development') { + console.warn('[Swap] generateSwapTransactionSteps: Returning empty steps array!', { + isValidSwap, + routing: txContext.routing, + }) + } return [] } diff --git a/packages/wallet/src/features/transactions/executeTransaction/services/TransactionService/transactionServiceImpl.ts b/packages/wallet/src/features/transactions/executeTransaction/services/TransactionService/transactionServiceImpl.ts index 099b0cc0d67..55e9f1cb93a 100644 --- a/packages/wallet/src/features/transactions/executeTransaction/services/TransactionService/transactionServiceImpl.ts +++ b/packages/wallet/src/features/transactions/executeTransaction/services/TransactionService/transactionServiceImpl.ts @@ -307,6 +307,12 @@ export function createTransactionService(ctx: { const { request, provider, unsubmittedTransaction, timestampBeforeSign, timestampBeforeSend } = submitParams // Sign and send the transaction + if (process.env.NODE_ENV === 'development') { + logger.debug('TransactionService', 'submissionFunction', 'About to send signed transaction:', { + hasSignedRequest: !!request.signedRequest, + signedRequestLength: request.signedRequest?.length, + }) + } const transactionHash = await ctx.transactionSigner.sendTransaction({ signedTx: request.signedRequest }) logger.debug('TransactionService', 'sendTransaction', 'Tx submitted:', transactionHash) @@ -338,7 +344,8 @@ export function createTransactionService(ctx: { // Calculate the transaction hash directly from the signed request const transactionHash = utils.keccak256(params.request.signedRequest) - // Submit the transaction in the background + // Submit the transaction and wait for it to complete + // This ensures the transaction is actually sent to the wallet before returning const submitPromise = params.typeInfo ? // Submit and update the local state createSubmitTransaction({ @@ -348,14 +355,22 @@ export function createTransactionService(ctx: { : // Submit the transaction directly without updating the local state ctx.transactionSigner.sendTransaction({ signedTx: params.request.signedRequest }) - submitPromise.catch((error) => { + // Wait for the transaction to be submitted before returning + // This ensures onSuccess is only called after the transaction is actually sent to the wallet + try { + await submitPromise + if (process.env.NODE_ENV === 'development') { + logger.debug('TransactionService', 'submitTransaction', 'Transaction submitted successfully:', transactionHash) + } + } catch (error) { logger.error(error, { tags: { file: 'TransactionService', function: 'submitTransaction' }, - extra: { context: 'Background submission failed' }, + extra: { context: 'Transaction submission failed' }, }) - }) + throw error + } - // Return the hash immediately + // Return the hash after transaction is submitted return { transactionHash } } diff --git a/packages/wallet/src/features/transactions/executeTransaction/services/TransactionSignerService/transactionSignerServiceImpl.ts b/packages/wallet/src/features/transactions/executeTransaction/services/TransactionSignerService/transactionSignerServiceImpl.ts index 78bcce0c630..408789d9ace 100644 --- a/packages/wallet/src/features/transactions/executeTransaction/services/TransactionSignerService/transactionSignerServiceImpl.ts +++ b/packages/wallet/src/features/transactions/executeTransaction/services/TransactionSignerService/transactionSignerServiceImpl.ts @@ -56,7 +56,17 @@ export function createTransactionSignerService(ctx: { const sendTransaction: TransactionSigner['sendTransaction'] = async (input) => { const provider = await ctx.getProvider() + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] Sending signed transaction to provider:', { + hasSignedTx: !!input.signedTx, + signedTxLength: input.signedTx?.length, + providerType: provider.constructor.name, + }) + } const transactionResponse = await provider.sendTransaction(input.signedTx) + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] Transaction sent, received hash:', transactionResponse.hash) + } return transactionResponse.hash } diff --git a/packages/wallet/src/features/transactions/swap/executeSwapSaga.ts b/packages/wallet/src/features/transactions/swap/executeSwapSaga.ts index d1b6273433d..e8f7564acda 100644 --- a/packages/wallet/src/features/transactions/swap/executeSwapSaga.ts +++ b/packages/wallet/src/features/transactions/swap/executeSwapSaga.ts @@ -170,10 +170,35 @@ function* executeTransactionStep(params: { } // Execute async (either because sync is not enabled or sync failed) + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] Executing transaction step asynchronously:', { + stepType: step.type, + chainId, + }) + } const asyncResult = yield* executor.executeStep(step) if (!asyncResult.success) { + const error = asyncResult.error instanceof Error + ? asyncResult.error + : new Error(asyncResult.error ? String(asyncResult.error) : 'Transaction failed') + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: Transaction step execution failed', { + error: error.message, + errorDetails: error, + stepType: step.type, + chainId, + }) + } yield* call(onFailure) - throw new Error('Transaction failed') + throw error + } + + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] Transaction step executed successfully:', { + stepType: step.type, + hash: asyncResult.hash, + chainId, + }) } return undefined // Async execution doesn't return a sync result @@ -326,9 +351,8 @@ export function createExecuteSwapSaga( if (isUniswapXPreSignedSwapTransaction(preSignedTransaction) || swapTxHasDelayedSubmission) { yield* call(onPending) - } else { - yield* call(onSuccess) } + // Note: onSuccess will be called after transaction is successfully submitted const gasFeeEstimation = swapTxContext.gasFeeEstimation @@ -437,6 +461,14 @@ export function createExecuteSwapSaga( ) } + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] About to execute swap transaction step:', { + stepType: swapStep.type, + hasParams: !!swapStep.params, + chainId, + }) + } + swapResult = yield* executeTransactionStep({ executor, step: swapStep, @@ -444,6 +476,14 @@ export function createExecuteSwapSaga( logger: dependencies.logger, onFailure: params.onFailure, }) + + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] Swap transaction step executed:', { + hasResult: !!swapResult, + resultType: swapResult ? 'sync' : 'async', + chainId, + }) + } } if (swapResult) { @@ -460,15 +500,22 @@ export function createExecuteSwapSaga( } } - // Call onSuccess now if it wasn't called earlier due to transaction spacing - if (swapTxHasDelayedSubmission) { - yield* call(onSuccess) - } + // Call onSuccess after transaction is successfully submitted + // For delayed submission, onSuccess will be called after all transactions are submitted + yield* call(onSuccess) } catch (error) { dependencies.logger.error(error, { tags: { file: 'executeSwapSaga', function: 'executeSwap' }, extra: { analytics: params.analytics }, }) + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: executeSwapSaga failed', { + error: error instanceof Error ? error.message : String(error), + }) + } + // Call onFailure with the error so it can be displayed to the user + const swapError = error instanceof Error ? error : new Error(String(error)) + yield* call(params.onFailure, swapError) } } } diff --git a/packages/wallet/src/features/transactions/swap/services/transactionExecutor.ts b/packages/wallet/src/features/transactions/swap/services/transactionExecutor.ts index fd04a21c66d..8149fe65ad9 100644 --- a/packages/wallet/src/features/transactions/swap/services/transactionExecutor.ts +++ b/packages/wallet/src/features/transactions/swap/services/transactionExecutor.ts @@ -39,9 +39,22 @@ export function createTransactionExecutor(transactionService: TransactionService try { const { params, shouldWait } = step + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] executeStep: Calling submitTransaction:', { + stepType: step.type, + hasParams: !!params, + hasRequest: !!params?.request, + hasSignedRequest: !!params?.request?.signedRequest, + }) + } + const result = yield* call(transactionService.submitTransaction, params) const hash = result.transactionHash + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] executeStep: Transaction submitted, hash:', hash) + } + // Handle transaction spacing if required if (shouldWait) { const { success } = yield* call(waitForTransactionConfirmation, { hash }) @@ -57,6 +70,12 @@ export function createTransactionExecutor(transactionService: TransactionService tags: { file: 'transactionExecutor', function: 'executeStep' }, extra: { stepType: step.type }, }) + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: executeStep failed:', { + error: error instanceof Error ? error.message : String(error), + stepType: step.type, + }) + } return { error, success: false } } } From e1a3e06a52549382c5485e4567358dd2d7931612 Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Wed, 21 Jan 2026 16:54:50 +0800 Subject: [PATCH 13/33] feat: no execute and swap work --- apps/web/public/csp.json | 3 + apps/web/src/hooks/useContract.ts | 21 +- .../web/src/hooks/useCurrentBlockTimestamp.ts | 93 ++++- apps/web/src/hooks/useTransactionDeadline.ts | 25 +- apps/web/src/hooks/useUniversalRouter.ts | 85 +++-- .../src/state/sagas/transactions/swapSaga.ts | 351 +++++++++++++++++- .../sagas/transactions/useSwapHandlers.ts | 45 ++- .../web/src/state/sagas/transactions/utils.ts | 68 +--- .../useQueryWithImmediateGarbageCollection.ts | 17 +- .../tradingApi/useCheckApprovalQuery.ts | 4 +- .../utils/getTradeSettingsDeadline.ts | 37 +- .../SwapFormButton/SwapFormButton.tsx | 68 +--- .../UnichainInstantBalanceModal/constants.ts | 6 +- .../features/transactions/swap/plan/utils.ts | 11 +- .../hooks/useCreateSwapReviewCallbacks.tsx | 14 - .../swap/review/hooks/useTokenApprovalInfo.ts | 18 + .../classic/classicSwapTxAndGasInfoService.ts | 26 ++ .../evm/evmSwapInstructionsService.ts | 26 +- .../swapTxAndGasInfoService/evm/utils.ts | 83 ++++- .../services/swapTxAndGasInfoService/utils.ts | 216 +++++------ .../swap/services/executeSwapService.ts | 95 ++++- .../services/tradeService/evmTradeService.ts | 2 + .../transformations/transformQuoteToTrade.ts | 17 +- .../hooks/useTransactionRequestInfo.ts | 34 +- .../utils/generateSwapTransactionSteps.ts | 81 ++-- .../transactions/swap/executeSwapSaga.ts | 2 +- .../swap/hooks/useSwapHandlers.ts | 37 ++ 27 files changed, 1106 insertions(+), 379 deletions(-) diff --git a/apps/web/public/csp.json b/apps/web/public/csp.json index 53f051b7aac..dcbe9efcefb 100644 --- a/apps/web/public/csp.json +++ b/apps/web/public/csp.json @@ -106,6 +106,9 @@ "https://mainnet.era.zksync.io/", "https://8mr3mthjba.execute-api.us-east-2.amazonaws.com", "https://mainnet.unichain.org/", + "https://testnet.hsk.xyz", + "https://mainnet.hsk.xyz", + "https://*.hsk.xyz", "https://api.web3modal.org", "https://api.statsig.com", "https://featuregates.org", diff --git a/apps/web/src/hooks/useContract.ts b/apps/web/src/hooks/useContract.ts index 2260ae1cef6..ea0df122b3e 100644 --- a/apps/web/src/hooks/useContract.ts +++ b/apps/web/src/hooks/useContract.ts @@ -108,8 +108,27 @@ export function usePairContract(pairAddress?: string, withSignerIfPossible?: boo export function useInterfaceMulticall(chainId?: UniverseChainId) { const account = useAccount() const chain = chainId ?? account.chainId + + // Use extended MULTICALL addresses for HashKey chains (same as useCurrentBlockTimestamp) + let multicallAddress: string | undefined + if (chain) { + // First check standard MULTICALL_ADDRESSES + multicallAddress = MULTICALL_ADDRESSES[chain] + + // If not found, check extended addresses for HashKey chains + if (!multicallAddress && (chain === UniverseChainId.HashKeyTestnet || chain === UniverseChainId.HashKey)) { + // Extended MULTICALL_ADDRESSES for HashKey chains (same as in useCurrentBlockTimestamp) + const EXTENDED_MULTICALL_ADDRESSES: Partial> = { + [UniverseChainId.HashKeyTestnet]: '0xcA11bde05977b3631167028862bE2a173976CA11', + [UniverseChainId.HashKey]: '0xcA11bde05977b3631167028862bE2a173976CA11', + } + multicallAddress = EXTENDED_MULTICALL_ADDRESSES[chain] + } + } + + return useContract({ - address: chain ? MULTICALL_ADDRESSES[chain] : undefined, + address: multicallAddress, ABI: MulticallABI, withSignerIfPossible: false, chainId: chain, diff --git a/apps/web/src/hooks/useCurrentBlockTimestamp.ts b/apps/web/src/hooks/useCurrentBlockTimestamp.ts index 6e4504b46e0..529feea253d 100644 --- a/apps/web/src/hooks/useCurrentBlockTimestamp.ts +++ b/apps/web/src/hooks/useCurrentBlockTimestamp.ts @@ -3,7 +3,33 @@ import { useAccount } from 'hooks/useAccount' import ms from 'ms' import { UniverseChainId } from 'uniswap/src/features/chains/types' import { assume0xAddress } from 'utils/wagmi' -import { useReadContract } from 'wagmi' +import { useReadContract, useChainId as useWagmiChainId, useBlock, useBlockNumber } from 'wagmi' +import { selectRpcUrl } from 'uniswap/src/features/providers/rpcUrlSelector' +import { RPCType } from 'uniswap/src/features/chains/types' + +// Extended MULTICALL_ADDRESSES for chains not in @uniswap/sdk-core +// TODO: Replace with actual MULTICALL contract addresses for HashKey chains +const EXTENDED_MULTICALL_ADDRESSES: Partial> = { + [UniverseChainId.HashKeyTestnet]: '0xcA11bde05977b3631167028862bE2a173976CA11', // Standard MULTICALL3 address (common for EVM chains) + [UniverseChainId.HashKey]: '0xcA11bde05977b3631167028862bE2a173976CA11', // Standard MULTICALL3 address (common for EVM chains) +} + +/** + * Gets the MULTICALL address for a given chainId + */ +function getMulticallAddress(chainId: UniverseChainId | undefined): string | undefined { + if (!chainId) { + return MULTICALL_ADDRESSES[UniverseChainId.Mainnet] + } + + // First check extended addresses for custom chains + if (chainId in EXTENDED_MULTICALL_ADDRESSES) { + return EXTENDED_MULTICALL_ADDRESSES[chainId as keyof typeof EXTENDED_MULTICALL_ADDRESSES] + } + + // Then check standard MULTICALL_ADDRESSES + return MULTICALL_ADDRESSES[chainId] ?? MULTICALL_ADDRESSES[UniverseChainId.Mainnet] +} /** * Gets the current block timestamp from the blockchain @@ -16,9 +42,18 @@ export default function useCurrentBlockTimestamp({ refetchInterval?: number | false } = {}): bigint | undefined { const account = useAccount() + const wagmiChainId = useWagmiChainId() // Get raw chainId from wagmi + const chainId = account.chainId ?? wagmiChainId ?? UniverseChainId.Mainnet + const multicallAddress = getMulticallAddress(chainId) - return useReadContract({ - address: assume0xAddress(MULTICALL_ADDRESSES[account.chainId ?? UniverseChainId.Mainnet]), + + + if (!multicallAddress) { + return undefined + } + + const result = useReadContract({ + address: assume0xAddress(multicallAddress), abi: [ { inputs: [], @@ -36,5 +71,55 @@ export default function useCurrentBlockTimestamp({ ], functionName: 'getCurrentBlockTimestamp', query: { refetchInterval }, - }).data + }) + + // Fallback to useBlock if Multicall fails or returns no data + // Try to get blockNumber first, but if that fails, useBlock can still work without blockNumber (gets latest block) + const blockNumberQuery = useBlockNumber({ chainId }) + const blockNumber = blockNumberQuery.data + const shouldUseFallback = result.isError || !result.data + const blockData = useBlock({ + chainId, + blockNumber: blockNumber, // If undefined, useBlock will get the latest block + query: { + enabled: shouldUseFallback, + }, + }) + + // Use Multicall result if available, otherwise fallback to useBlock + const blockTimestamp = result.data ?? (blockData.data?.timestamp ? BigInt(blockData.data.timestamp) : undefined) + + if (process.env.NODE_ENV === 'development') { + // 获取 RPC URL 信息用于调试 + const rpcConfig = selectRpcUrl(chainId, RPCType.Public) + const rpcUrl = rpcConfig?.rpcUrl || 'N/A' + + console.log('[swap debug] useCurrentBlockTimestamp - Query result:', { + chainId, + rpcUrl, + multicallAddress, + hasData: !!result.data, + data: result.data?.toString(), + isLoading: result.isLoading, + isError: result.isError, + error: result.error?.message, + shouldUseFallback, + hasBlockNumber: !!blockNumber, + blockNumberLoading: blockNumberQuery.isLoading, + blockNumberError: blockNumberQuery.isError, + fallbackBlockNumber: blockNumber?.toString(), + fallbackDataLoading: blockData.isLoading, + fallbackDataError: blockData.isError, + fallbackTimestamp: blockData.data?.timestamp?.toString(), + usingFallback: shouldUseFallback && !!blockData.data?.timestamp, + blockTimestamp: blockTimestamp ? { + value: blockTimestamp.toString(), + hex: '0x' + blockTimestamp.toString(16), + date: new Date(Number(blockTimestamp) * 1000).toLocaleString('zh-CN'), + source: result.data ? 'multicall' : 'useBlock', + } : undefined, + }) + } + + return blockTimestamp } diff --git a/apps/web/src/hooks/useTransactionDeadline.ts b/apps/web/src/hooks/useTransactionDeadline.ts index 8b8441174bf..9227b97bf7a 100644 --- a/apps/web/src/hooks/useTransactionDeadline.ts +++ b/apps/web/src/hooks/useTransactionDeadline.ts @@ -12,10 +12,17 @@ export default function useTransactionDeadline(): BigNumber | undefined { const { chainId } = useAccount() const ttl = useAppSelector((state) => state.user.userDeadline) const blockTimestamp = useCurrentBlockTimestamp() - return useMemo( - () => timestampToDeadline({ chainId, blockTimestamp: BigNumber.from(blockTimestamp), ttl }), - [blockTimestamp, chainId, ttl], - ) + + return useMemo(() => { + // Handle undefined blockTimestamp + if (!blockTimestamp) { + return undefined + } + + const deadline = timestampToDeadline({ chainId, blockTimestamp: BigNumber.from(blockTimestamp), ttl }) + + return deadline + }, [blockTimestamp, chainId, ttl]) } /** @@ -28,7 +35,8 @@ export function useGetTransactionDeadline(): () => Promise { const blockTimestamp = await multicall.getCurrentBlockTimestamp() - return timestampToDeadline({ chainId, blockTimestamp, ttl }) + const deadline = timestampToDeadline({ chainId, blockTimestamp, ttl }) + return deadline }, [chainId, multicall, ttl]) } @@ -42,10 +50,13 @@ function timestampToDeadline({ ttl?: number }) { if (blockTimestamp && isL2ChainId(chainId)) { - return blockTimestamp.add(L2_DEADLINE_FROM_NOW) + const deadline = blockTimestamp.add(L2_DEADLINE_FROM_NOW) + return deadline } if (blockTimestamp && ttl) { - return blockTimestamp.add(ttl) + const deadline = blockTimestamp.add(ttl) + return deadline } + return undefined } diff --git a/apps/web/src/hooks/useUniversalRouter.ts b/apps/web/src/hooks/useUniversalRouter.ts index ad02cb2e82e..cd4e29e9a1b 100644 --- a/apps/web/src/hooks/useUniversalRouter.ts +++ b/apps/web/src/hooks/useUniversalRouter.ts @@ -4,10 +4,11 @@ import { BigNumber } from '@ethersproject/bignumber' import { Percent } from '@uniswap/sdk-core' import { FlatFeeOptions, - SwapRouter, + SwapRouter as UniversalSwapRouter, UNIVERSAL_ROUTER_ADDRESS, UniversalRouterVersion, } from '@hkdex-tmp/universal_router_sdk' +import { SwapRouter as V3SwapRouter } from '@uniswap/router-sdk' import { FeeOptions, toHex } from '@uniswap/v3-sdk' import { useAccount } from 'hooks/useAccount' import { useEthersWeb3Provider } from 'hooks/useEthersProvider' @@ -19,7 +20,9 @@ import { useCallback, useRef } from 'react' import { useTranslation } from 'react-i18next' import { useMultichainContext } from 'state/multichain/useMultichainContext' import { ClassicTrade, TradeFillType } from 'state/routing/types' +import { UniverseChainId } from 'uniswap/src/features/chains/types' import { useUserSlippageTolerance } from 'state/user/hooks' +import { CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS } from 'uniswap/src/features/transactions/swap/components/UnichainInstantBalanceModal/constants' import { SwapEventName } from 'uniswap/src/features/telemetry/constants' import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send' import i18n from 'uniswap/src/i18n' @@ -103,8 +106,10 @@ export function useUniversalRouterSwapCallback({ const deadline = await getDeadline() + const isHashKeyChain = chainId === UniverseChainId.HashKey || chainId === UniverseChainId.HashKeyTestnet + // Check if SwapRouter and UNIVERSAL_ROUTER_ADDRESS are available - if (!SwapRouter || typeof SwapRouter.swapCallParameters !== 'function') { + if (!UniversalSwapRouter || typeof UniversalSwapRouter.swapCallParameters !== 'function') { throw new Error('SwapRouter.swapCallParameters is not available in @hkdex-tmp/universal_router_sdk') } @@ -112,26 +117,46 @@ export function useUniversalRouterSwapCallback({ throw new Error('UNIVERSAL_ROUTER_ADDRESS is not available in @hkdex-tmp/universal_router_sdk') } - let routerAddress: string - try { - routerAddress = UNIVERSAL_ROUTER_ADDRESS(UniversalRouterVersion.V1_2, chainId) - } catch (error) { - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: Failed to get router address', { - error: error instanceof Error ? error.message : String(error), - chainId, - }) + let routerAddress: string | undefined + const configuredRouterAddress = CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS[chainId as UniverseChainId]?.[0] + if (configuredRouterAddress) { + routerAddress = configuredRouterAddress + } + + if (!isHashKeyChain) { + try { + routerAddress ??= UNIVERSAL_ROUTER_ADDRESS(UniversalRouterVersion.V1_2, chainId) + } catch (error) { + if (process.env.NODE_ENV === 'development') { + console.error('[Swap] Error: Failed to get router address', { + error: error instanceof Error ? error.message : String(error), + chainId, + }) + } + throw new Error( + `Failed to get router address for chain ${chainId}: ${error instanceof Error ? error.message : String(error)}`, + ) } - throw new Error(`Failed to get router address for chain ${chainId}: ${error instanceof Error ? error.message : String(error)}`) } - const { calldata: data, value } = SwapRouter.swapCallParameters(trade, { - slippageTolerance: options.slippageTolerance, - deadlineOrPreviousBlockhash: deadline?.toString(), - inputTokenPermit: options.permit, - fee: options.feeOptions, - flatFee: options.flatFeeOptions, - }) + if (!routerAddress) { + throw new Error(`Failed to resolve router address for chain ${chainId}`) + } + + const { calldata: data, value } = isHashKeyChain + ? V3SwapRouter.swapCallParameters(trade, { + slippageTolerance: options.slippageTolerance, + recipient: account.address, + deadline: deadline?.toString() ?? '0', + fee: options.feeOptions, + }) + : UniversalSwapRouter.swapCallParameters(trade, { + slippageTolerance: options.slippageTolerance, + deadlineOrPreviousBlockhash: deadline?.toString(), + inputTokenPermit: options.permit, + fee: options.feeOptions, + flatFee: options.flatFeeOptions, + }) const tx = { from: account.address, to: routerAddress, @@ -141,10 +166,25 @@ export function useUniversalRouterSwapCallback({ } let gasLimit: BigNumber - try { - const gasEstimate = await provider.estimateGas(tx) - gasLimit = calculateGasMargin(gasEstimate) + try { + const gasEstimate = await provider.estimateGas(tx) + gasLimit = calculateGasMargin(gasEstimate) } catch (gasError) { + // HashKey RPC may revert during estimation (e.g., STF) even when tx would succeed. + // Fallback to buffered quote gasUseEstimate to allow wallet confirmation. + if (isHashKeyChain) { + const gasUseEstimate = + (trade as any)?.quote?.quote?.gasUseEstimate !== undefined + ? Number((trade as any).quote.quote.gasUseEstimate) + : undefined + const fallbackGas = gasUseEstimate ? Math.ceil(gasUseEstimate * 1.6) : 700000 + gasLimit = BigNumber.from(fallbackGas) + logger.warn('useUniversalRouter', 'useUniversalRouterSwapCallback', 'Estimate gas failed, using fallback for HashKey', { + fallbackGas, + gasUseEstimate, + error: gasError, + }) + } else { sendAnalyticsEvent(SwapEventName.SwapEstimateGasCallFailed, { ...formatCommonPropertiesForTrade({ trade, allowedSlippage: options.slippageTolerance }), ...analyticsContext, @@ -156,6 +196,7 @@ export function useUniversalRouterSwapCallback({ logger.warn('useUniversalRouter', 'useUniversalRouterSwapCallback', 'Failed to estimate gas', wrappedError) throw new GasEstimationError() } + } const response = await (async () => { try { diff --git a/apps/web/src/state/sagas/transactions/swapSaga.ts b/apps/web/src/state/sagas/transactions/swapSaga.ts index ea5bf6c7e70..5eb3d0d063e 100644 --- a/apps/web/src/state/sagas/transactions/swapSaga.ts +++ b/apps/web/src/state/sagas/transactions/swapSaga.ts @@ -1,6 +1,7 @@ import { useTotalBalancesUsdForAnalytics } from 'appGraphql/data/apollo/useTotalBalancesUsdForAnalytics' import { TradingApi } from '@universe/api' import { Experiments } from '@universe/gating' +import { Interface } from '@ethersproject/abi' import { popupRegistry } from 'components/Popups/registry' import { PopupType } from 'components/Popups/types' import { DEFAULT_TXN_DISMISS_MS, L2_TXN_DISMISS_MS, ZERO_PERCENT } from 'constants/misc' @@ -40,6 +41,7 @@ import { TransactionStep, TransactionStepType, } from 'uniswap/src/features/transactions/steps/types' +import { UNCONNECTED_ADDRESS } from 'uniswap/src/features/transactions/swap/services/tradeService/transformations/buildQuoteRequest' import { ExtractedBaseTradeAnalyticsProperties, getBaseTradeAnalyticsProperties, @@ -75,6 +77,285 @@ import { createSaga } from 'uniswap/src/utils/saga' import { logger } from 'utilities/src/logger/logger' import { useTrace } from 'utilities/src/telemetry/trace/TraceContext' +function patchFirstWordAddressIfUnconnected(input: string, recipientAddress: string): string { + if (typeof input !== 'string' || !input.startsWith('0x') || input.length < 66) { + return input + } + + const firstWord = input.slice(2, 66) // 32 bytes + const embeddedAddress = `0x${firstWord.slice(24)}`.toLowerCase() + if (embeddedAddress !== UNCONNECTED_ADDRESS.toLowerCase()) { + return input + } + + const addrNo0x = recipientAddress.toLowerCase().replace(/^0x/, '') + const padded = addrNo0x.padStart(64, '0') + return `0x${padded}${input.slice(66)}` +} + +/** + * Extracts total amountIn from all exactInput calls in multicall data + * This is used to ensure sufficient token allowance for Universal Router + */ +function getTotalAmountInFromMulticall(multicallData: string): bigint | undefined { + try { + const MULTICALL_ABI = ['function multicall(bytes[] data) payable returns (bytes[] results)'] + const EXACT_INPUT_ABI = [ + 'function exactInput((bytes path, address recipient, uint256 amountIn, uint256 amountOutMinimum))', + ] + + const multicallIface = new Interface(MULTICALL_ABI) + const exactInputIface = new Interface(EXACT_INPUT_ABI) + + const decoded = multicallIface.decodeFunctionData('multicall', multicallData) + const calls = decoded[0] + + let totalAmountIn = BigInt(0) + for (const callData of calls) { + try { + const decodedCall = exactInputIface.decodeFunctionData('exactInput', callData) + const params = decodedCall[0] + // amountIn is a BigNumber from ethers, convert to bigint + totalAmountIn += BigInt(params.amountIn.toString()) + } catch { + // Skip if not exactInput call + } + } + + return totalAmountIn > 0 ? totalAmountIn : undefined + } catch { + return undefined + } +} + +/** + * Patches recipient address in multicall exactInput calls + * Replaces the recipient address in each exactInput call within multicall + * + * Why use multicall directly? + * 1. Universal Router supports multicall natively (as seen in successful transactions) + * 2. Multicall format is simpler and already proven to work + * 3. No need for complex conversion to execute format + */ +function patchMulticallRecipient(multicallData: string, recipientAddress: string): string { + try { + const MULTICALL_ABI = ['function multicall(bytes[] data) payable returns (bytes[] results)'] + const EXACT_INPUT_ABI = [ + 'function exactInput((bytes path, address recipient, uint256 amountIn, uint256 amountOutMinimum))', + ] + + const multicallIface = new Interface(MULTICALL_ABI) + const exactInputIface = new Interface(EXACT_INPUT_ABI) + + const decoded = multicallIface.decodeFunctionData('multicall', multicallData) + const calls = decoded[0] + + // Patch each call's recipient address + const patchedCalls = calls.map((callData: string) => { + try { + const decodedCall = exactInputIface.decodeFunctionData('exactInput', callData) + const params = decodedCall[0] + + // Check if recipient needs to be patched + // Only patch if recipient is UNCONNECTED_ADDRESS (placeholder from Trading API) + // + // Note: Other recipient addresses (like 0xfCb42db392E6641fFA057f143aCe1953759f708f) + // should be preserved as they may be special addresses that Universal Router handles correctly. + // The key issue was insufficient token allowance, not the recipient address itself. + const currentRecipient = params.recipient.toLowerCase() + const unconnectedAddress = UNCONNECTED_ADDRESS.toLowerCase() + + // Only patch if recipient is UNCONNECTED_ADDRESS + if (currentRecipient === unconnectedAddress) { + // Re-encode exactInput with user address as recipient + const patchedParams = { + ...params, + recipient: recipientAddress, + } + return exactInputIface.encodeFunctionData('exactInput', [patchedParams]) + } + + return callData + } catch (error) { + if (process.env.NODE_ENV === 'development') { + console.warn('[Swap] Failed to patch multicall call:', error) + } + return callData + } + }) + + // Re-encode multicall with patched calls + return multicallIface.encodeFunctionData('multicall', [patchedCalls]) + } catch (error) { + if (process.env.NODE_ENV === 'development') { + console.warn('[Swap] Failed to patch multicall recipient:', error) + } + return multicallData + } +} + +function normalizeHexData(data: string): string { + return data.startsWith('0x') ? data : `0x${data}` +} + +/** + * Converts multicall (SwapRouter02) calldata to Universal Router execute format. + * This handles the case where Trading API returns multicall instead of execute. + * + * Note: This is a simplified conversion. For production, consider using Universal Router SDK + * to properly rebuild the swap commands from the trade object instead of converting calldata. + */ +function convertMulticallToExecute( + multicallData: string, + deadlineSeconds: number, + recipientAddress: string, +): string | undefined { + try { + const MULTICALL_ABI = ['function multicall(bytes[] data) payable returns (bytes[] results)'] + const EXACT_INPUT_ABI = [ + 'function exactInput((bytes path, address recipient, uint256 amountIn, uint256 amountOutMinimum))', + ] + const EXECUTE_3_ABI = ['function execute(bytes commands, bytes[] inputs, uint256 deadline)'] + + const multicallIface = new Interface(MULTICALL_ABI) + const exactInputIface = new Interface(EXACT_INPUT_ABI) + const executeIface = new Interface(EXECUTE_3_ABI) + + const decoded = multicallIface.decodeFunctionData('multicall', multicallData) + const calls = decoded[0] + + // For now, log that we detected multicall but don't convert + // The proper solution is to ensure Trading API returns execute format, + // or rebuild using Universal Router SDK from the trade object + if (process.env.NODE_ENV === 'development') { + console.warn( + '[Swap] Received multicall calldata - conversion to execute not yet implemented. ' + + 'Consider using Universal Router SDK to rebuild from trade object.', + ) + } + + // Return undefined to fall back to original data + // TODO: Implement proper conversion using Universal Router SDK + return undefined + } catch { + return undefined + } +} + +function fixUniversalRouterExecuteData({ + data, + deadlineSeconds, + recipientAddress, +}: { + data: string | undefined + deadlineSeconds: number | undefined + recipientAddress: string | undefined +}): string | undefined { + if (!data || typeof data !== 'string') { + return data + } + if (!deadlineSeconds || !Number.isFinite(deadlineSeconds)) { + return data + } + if (!recipientAddress) { + return data + } + + try { + const normalized = normalizeHexData(data) + const selector = normalized.slice(0, 10).toLowerCase() + + // Check if it's multicall (SwapRouter02) + // Universal Router supports multicall directly, so we can use it as-is + // Just need to patch recipient address if needed + // + // Why use multicall instead of converting to execute? + // 1. Universal Router natively supports multicall (proven by successful transactions) + // 2. Multicall format is simpler and already working + // 3. Conversion to execute format has been problematic + const MULTICALL_SELECTOR = '0xac9650d8' + if (selector === MULTICALL_SELECTOR.toLowerCase()) { + // Patch recipient address in multicall instead of converting to execute + // This is simpler and matches the successful transaction format + // + // IMPORTANT: When using multicall, ensure sufficient token allowance for Universal Router. + // Multicall may contain multiple swap calls, each with its own amountIn. + // The total amount needed = sum of all amountIn values in all exactInput calls. + // Universal Router requires direct ERC20 approval (not just Permit2 approval). + const totalAmountIn = getTotalAmountInFromMulticall(normalized) + if (totalAmountIn && process.env.NODE_ENV === 'development') { + console.log( + `[Swap] Multicall total amountIn: ${totalAmountIn.toString()} (${totalAmountIn.toString() / BigInt(10 ** 18)} tokens)`, + ) + } + const patched = patchMulticallRecipient(normalized, recipientAddress) + if (patched !== normalized) { + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] Patched recipient address in multicall calldata') + } + logger.info( + 'swapSaga', + 'fixUniversalRouterExecuteData', + '[Swap] Patched multicall recipient', + { + originalRecipient: 'from multicall', + newRecipient: recipientAddress, + selector: MULTICALL_SELECTOR, + approach: 'multicall_direct', + }, + ) + return patched + } + // If no patching needed, return original multicall data + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] Using multicall calldata directly (Universal Router supports it)') + } + logger.info( + 'swapSaga', + 'fixUniversalRouterExecuteData', + '[Swap] Using multicall calldata directly', + { + selector: MULTICALL_SELECTOR, + approach: 'multicall_direct', + recipient: recipientAddress, + totalAmountIn: totalAmountIn?.toString(), + note: 'Ensure token allowance >= totalAmountIn for Universal Router', + }, + ) + return normalized + } + + // Handle execute format (2-param or 3-param) + const EXECUTE_2_ABI = ['function execute(bytes commands, bytes[] inputs)'] + const EXECUTE_3_ABI = ['function execute(bytes commands, bytes[] inputs, uint256 deadline)'] + const iface2 = new Interface(EXECUTE_2_ABI) + const iface3 = new Interface(EXECUTE_3_ABI) + + const execute2Selector = iface2.getSighash('execute').toLowerCase() + const execute3Selector = iface3.getSighash('execute').toLowerCase() + + let commands: string + let inputs: string[] + + if (selector === execute2Selector) { + const decoded = iface2.decodeFunctionData('execute', normalized) + commands = decoded[0] + inputs = decoded[1] + } else if (selector === execute3Selector) { + const decoded = iface3.decodeFunctionData('execute', normalized) + commands = decoded[0] + inputs = decoded[1] + } else { + return data + } + + const patchedInputs = inputs.map((input) => patchFirstWordAddressIfUnconnected(input, recipientAddress)) + return iface3.encodeFunctionData('execute', [commands, patchedInputs, deadlineSeconds]) + } catch { + return data + } +} + function* handleSwapTransactionStep(params: HandleSwapStepParams): SagaGenerator { const { trade, step, signature, analytics, onTransactionHash } = params @@ -96,12 +377,61 @@ function* handleSwapTransactionStep(params: HandleSwapStepParams): SagaGenerator console.log('[Swap] handleSwapTransactionStep: Calling getSwapTxRequest') } const txRequest = yield* call(getSwapTxRequest, step, signature) + const deadlineSeconds = typeof (trade as any).deadline === 'number' ? (trade as any).deadline : undefined + const recipientAddress = (params as HandleSwapStepParams & { address?: string }).address + const txRequestDataFixed = fixUniversalRouterExecuteData({ + data: txRequest.data?.toString(), + deadlineSeconds, + recipientAddress, + }) + const txRequestFixed = + txRequestDataFixed && txRequestDataFixed !== txRequest.data?.toString() + ? { ...txRequest, data: txRequestDataFixed } + : txRequest + + const originalSelector = txRequest.data?.toString()?.slice(0, 10)?.toLowerCase() + const finalSelector = txRequestFixed.data?.toString()?.slice(0, 10)?.toLowerCase() + const wasModified = txRequestDataFixed && txRequestDataFixed !== txRequest.data?.toString() + + ;(globalThis as any).__SWAP_SAGA_LAST_TX__ = { + stage: 'afterGetSwapTxRequest', + time: Date.now(), + chainId: txRequestFixed.chainId, + to: txRequestFixed.to, + originalSelector, + finalSelector, + wasModified, + deadlineSeconds, + recipientAddress, + originalDataLength: txRequest.data?.toString()?.length, + finalDataLength: txRequestFixed.data?.toString()?.length, + } + + logger.info('swapSaga', 'handleSwapTransactionStep', 'Prepared swap txRequest', { + chainId: txRequestFixed.chainId, + to: txRequestFixed.to, + originalSelector, + finalSelector, + wasModified, + deadlineSeconds, + recipientAddress, + }) + + if (process.env.NODE_ENV === 'development') { + console.log('[Swap] Calldata transformation:', { + originalSelector, + finalSelector, + wasModified, + deadlineSeconds, + recipientAddress, + }) + } if (process.env.NODE_ENV === 'development') { console.log('[Swap] handleSwapTransactionStep: Got txRequest:', { - hasTxRequest: !!txRequest, - to: txRequest?.to, - chainId: txRequest?.chainId, + hasTxRequest: !!txRequestFixed, + to: txRequestFixed?.to, + chainId: txRequestFixed?.chainId, }) } @@ -109,13 +439,13 @@ function* handleSwapTransactionStep(params: HandleSwapStepParams): SagaGenerator sendAnalyticsEvent(SwapEventName.SwapModifiedInWallet, { ...analytics, txHash: hash, - expected: txRequest.data?.toString() ?? '', + expected: txRequestFixed.data?.toString() ?? '', actual: data, }) } // Now that we have the txRequest, we can create a definitive SwapTransactionStep, incase we started with an async step. - const onChainStep = { ...step, txRequest } + const onChainStep = { ...step, txRequest: txRequestFixed } if (process.env.NODE_ENV === 'development') { console.log('[Swap] handleSwapTransactionStep: About to call handleOnChainStep:', { @@ -327,7 +657,7 @@ function* swap(params: SwapParams) { if (process.env.NODE_ENV === 'development') { console.log('[Swap] swap saga: Handling swap transaction step:', { stepType: step.type, - hasTxRequest: !!step.txRequest, + hasTxRequest: 'txRequest' in step && !!step.txRequest, }) } requireRouting(trade, [TradingApi.Routing.CLASSIC, TradingApi.Routing.BRIDGE]) @@ -409,10 +739,15 @@ export function useSwapCallback(): SwapCallback { return useCallback( (args: SwapCallbackParams) => { if (process.env.NODE_ENV === 'development') { + const hasTxRequests = 'txRequests' in args.swapTxContext && Array.isArray(args.swapTxContext.txRequests) + const txRequestCount = + 'txRequests' in args.swapTxContext && Array.isArray(args.swapTxContext.txRequests) + ? args.swapTxContext.txRequests.length + : 0 console.log('[Swap] swapCallback called', { routing: args.swapTxContext.routing, - hasTxRequests: !!args.swapTxContext.txRequests, - txRequestCount: args.swapTxContext.txRequests?.length || 0, + hasTxRequests, + txRequestCount, }) } const { diff --git a/apps/web/src/state/sagas/transactions/useSwapHandlers.ts b/apps/web/src/state/sagas/transactions/useSwapHandlers.ts index e4ed1768bb4..562bb2bdc4a 100644 --- a/apps/web/src/state/sagas/transactions/useSwapHandlers.ts +++ b/apps/web/src/state/sagas/transactions/useSwapHandlers.ts @@ -43,6 +43,42 @@ export function useSwapHandlers(): SwapHandlers { // Execute routes to the appropriate callback based on transaction type const execute: ExecuteSwapCallback = useCallback( async (params) => { + if (process.env.NODE_ENV === 'development') { + console.log('[execute] useSwapHandlers execute called with params:', params) + console.log('[execute] useSwapHandlers - Detailed swapTxContext:', { + routing: params.swapTxContext?.routing, + hasTxRequests: !!params.swapTxContext?.txRequests, + txRequestCount: params.swapTxContext?.txRequests?.length || 0, + txRequests: params.swapTxContext?.txRequests?.map((tx, idx) => ({ + index: idx, + to: tx.to, + data: tx.data?.substring(0, 20) + '...', + value: tx.value?.toString(), + gasLimit: tx.gasLimit?.toString(), + chainId: tx.chainId, + })), + hasTrade: !!params.swapTxContext?.trade, + trade: params.swapTxContext?.trade ? { + routing: params.swapTxContext.trade.routing, + inputAmount: params.swapTxContext.trade.inputAmount?.toExact(), + outputAmount: params.swapTxContext.trade.outputAmount?.toExact(), + deadline: params.swapTxContext.trade.deadline, + deadlineDate: params.swapTxContext.trade.deadline ? new Date(params.swapTxContext.trade.deadline * 1000).toLocaleString('zh-CN') : undefined, + } : undefined, + includesDelegation: params.swapTxContext?.includesDelegation, + hasSwapRequestArgs: 'swapRequestArgs' in (params.swapTxContext || {}), + swapRequestArgs: params.swapTxContext?.swapRequestArgs ? { + deadline: params.swapTxContext.swapRequestArgs.deadline, + deadlineDate: params.swapTxContext.swapRequestArgs.deadline ? new Date(params.swapTxContext.swapRequestArgs.deadline * 1000).toLocaleString('zh-CN') : undefined, + hasQuote: !!params.swapTxContext.swapRequestArgs.quote, + simulateTransaction: params.swapTxContext.swapRequestArgs.simulateTransaction, + allKeys: Object.keys(params.swapTxContext.swapRequestArgs), + fullSwapRequestArgs: params.swapTxContext.swapRequestArgs, + } : 'swapRequestArgs is undefined', + swapTxContextKeys: params.swapTxContext ? Object.keys(params.swapTxContext) : [], + }) + } + const { account, swapTxContext, @@ -84,7 +120,7 @@ export function useSwapHandlers(): SwapHandlers { } else { // Handle regular swap transactions try { - swapCallback({ + swapCallback({ account, swapTxContext, currencyInAmountUSD, @@ -102,13 +138,6 @@ export function useSwapHandlers(): SwapHandlers { includesDelegation: swapTxContext.includesDelegation, }) } catch (error) { - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: swapCallback threw error', { - error: error instanceof Error ? error.message : String(error), - errorDetails: error, - stack: error instanceof Error ? error.stack : undefined, - }) - } onFailure(error instanceof Error ? error : new Error(String(error))) } } diff --git a/apps/web/src/state/sagas/transactions/utils.ts b/apps/web/src/state/sagas/transactions/utils.ts index d0223e8c4f3..5a20bb32ce6 100644 --- a/apps/web/src/state/sagas/transactions/utils.ts +++ b/apps/web/src/state/sagas/transactions/utils.ts @@ -124,19 +124,10 @@ export function* handleOnChainStep(params: Han addTransactionBreadcrumb({ step, data: { ...info } }) // Avoid sending prompting a transaction if the user already submitted an equivalent tx, e.g. by closing and reopening a transaction flow - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] handleOnChainStep: Checking for duplicative transaction') - } const duplicativeTx = yield* findDuplicativeTx({ info, address, chainId, allowDuplicativeTx }) const interfaceDuplicativeTx = duplicativeTx ? getInterfaceTransaction(duplicativeTx) : undefined if (interfaceDuplicativeTx && interfaceDuplicativeTx.hash) { - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] handleOnChainStep: Found duplicative transaction:', { - hash: interfaceDuplicativeTx.hash, - status: interfaceDuplicativeTx.status, - }) - } if (interfaceDuplicativeTx.status === TransactionStatus.Success) { addTransactionBreadcrumb({ step, @@ -155,22 +146,10 @@ export function* handleOnChainStep(params: Han } } - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] handleOnChainStep: No duplicative transaction found, proceeding with new transaction') - } - // Add a watcher to check if the transaction flow during user input const { throwIfInterrupted } = yield* watchForInterruption(ignoreInterrupt) // Trigger UI prompting user to accept - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] handleOnChainStep: Triggering UI to prompt user to accept:', { - stepType: step.type, - chainId, - hasTxRequest: !!step.txRequest, - to: step.txRequest?.to, - }) - } setCurrentStep({ step, accepted: false }) let transaction: InterfaceTransactionDetails @@ -209,13 +188,6 @@ export function* handleOnChainStep(params: Han // If should wait for confirmation, we block until the transaction is confirmed // Otherwise, we submit the transaction and return the hash immediately and spawn a detection task to check for modifications if (blockedAsyncSubmissionChainIds.includes(chainId) || shouldWaitForConfirmation) { - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] handleOnChainStep: Calling submitTransaction (sync):', { - chainId, - shouldWaitForConfirmation, - isBlockedAsync: blockedAsyncSubmissionChainIds.includes(chainId), - }) - } const { hash, data, nonce } = yield* call(submitTransaction, params) transaction = createTransaction(hash) @@ -226,12 +198,6 @@ export function* handleOnChainStep(params: Han yield* call(onModification, { hash, data, nonce }) } } else { - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] handleOnChainStep: Calling submitTransactionAsync:', { - chainId, - shouldWaitForConfirmation, - }) - } const hash = yield* call(submitTransactionAsync, params) transaction = createTransaction(hash) @@ -321,6 +287,21 @@ function* submitTransaction(params: HandleOnChainStepParams): SagaGenerator( - { ...queryArgs, gcTime: immediateGcTime }, + { ...queryArgs, queryKey: safeQueryKey, gcTime: immediateGcTime }, queryClient, ) const { dataUpdatedAt } = result @@ -53,10 +54,12 @@ export function useQueryWithImmediateGarbageCollection< const timeSinceLastUpdate = Date.now() - dataUpdatedAt const timeout = setTimeout(() => { - const state = queryClient.getQueryCache().find({ queryKey })?.state + const state = queryClient.getQueryCache().find({ queryKey: safeQueryKey })?.state if (!state) { - logger.debug('TradingApiClient.ts', 'useQueryWithImmediateGarbageCollection', 'Cache not found', { queryKey }) + logger.debug('TradingApiClient.ts', 'useQueryWithImmediateGarbageCollection', 'Cache not found', { + queryKey: safeQueryKey, + }) return } @@ -72,19 +75,19 @@ export function useQueryWithImmediateGarbageCollection< if (latestTimeSinceLastUpdate >= immediateGcTime) { logger.debug('TradingApiClient.ts', 'useQueryWithImmediateGarbageCollection', 'Clearing stale data', { - queryKey, + queryKey: safeQueryKey, immediateGcTime, latestDataUpdatedAt, latestTimeSinceLastUpdate, state, }) - queryClient.removeQueries({ queryKey, exact: true }) + queryClient.removeQueries({ queryKey: safeQueryKey, exact: true }) } }, immediateGcTime - timeSinceLastUpdate) return () => clearTimeout(timeout) - }, [dataUpdatedAt, immediateGcTime, queryClient, queryKey, skip]) + }, [dataUpdatedAt, immediateGcTime, queryClient, safeQueryKey, skip]) return result } diff --git a/packages/uniswap/src/data/apiClients/tradingApi/useCheckApprovalQuery.ts b/packages/uniswap/src/data/apiClients/tradingApi/useCheckApprovalQuery.ts index bb63a8a336b..2e6ad008cd2 100644 --- a/packages/uniswap/src/data/apiClients/tradingApi/useCheckApprovalQuery.ts +++ b/packages/uniswap/src/data/apiClients/tradingApi/useCheckApprovalQuery.ts @@ -15,7 +15,9 @@ export function useCheckApprovalQuery({ TradingApi.ApprovalRequest, TradingApi.ApprovalResponse >): UseQueryResult { - const queryKey = [ReactQueryCacheKey.TradingApi, uniswapUrls.tradingApiPaths.approval, params] + const queryKey = params + ? [ReactQueryCacheKey.TradingApi, uniswapUrls.tradingApiPaths.approval, params] + : [ReactQueryCacheKey.TradingApi, uniswapUrls.tradingApiPaths.approval, 'skip'] return useQueryWithImmediateGarbageCollection({ queryKey, diff --git a/packages/uniswap/src/data/apiClients/tradingApi/utils/getTradeSettingsDeadline.ts b/packages/uniswap/src/data/apiClients/tradingApi/utils/getTradeSettingsDeadline.ts index 3313007bd78..90139ac639d 100644 --- a/packages/uniswap/src/data/apiClients/tradingApi/utils/getTradeSettingsDeadline.ts +++ b/packages/uniswap/src/data/apiClients/tradingApi/utils/getTradeSettingsDeadline.ts @@ -1,7 +1,36 @@ -export const getTradeSettingsDeadline = (customDeadline?: number): number | undefined => { - // if custom deadline is set (in minutes), convert to unix timestamp format from now - const deadlineSeconds = (customDeadline ?? 0) * 60 - const deadline = customDeadline ? Math.floor(Date.now() / 1000) + deadlineSeconds : undefined +import { DEFAULT_CUSTOM_DEADLINE } from 'uniswap/src/constants/transactions' + +export const getTradeSettingsDeadline = ( + customDeadline?: number, + blockTimestamp?: bigint | number, +): number | undefined => { + // Use default deadline (30 minutes) if customDeadline is not set + const deadlineMinutes = customDeadline ?? DEFAULT_CUSTOM_DEADLINE + const deadlineSeconds = deadlineMinutes * 60 + + // Prefer using block timestamp if available (more accurate for on-chain execution) + // Otherwise fall back to client time + const baseTimestamp = blockTimestamp + ? (typeof blockTimestamp === 'bigint' ? Number(blockTimestamp) : blockTimestamp) + : Math.floor(Date.now() / 1000) + + const deadline = baseTimestamp + deadlineSeconds + + if (process.env.NODE_ENV === 'development') { + console.log('[swap debug] getTradeSettingsDeadline:', { + customDeadline, + usingDefault: customDeadline === undefined, + defaultDeadline: DEFAULT_CUSTOM_DEADLINE, + deadlineMinutes, + deadlineSeconds, + blockTimestamp: blockTimestamp?.toString(), + baseTimestamp, + deadline, + deadlineDate: new Date(deadline * 1000).toLocaleString('zh-CN'), + currentTime: new Date().toLocaleString('zh-CN'), + usingBlockTimestamp: !!blockTimestamp, + }) + } return deadline } diff --git a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx index c6ea26b0056..a6f8531a6ef 100644 --- a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx +++ b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx @@ -195,26 +195,10 @@ export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Ele try { if (!swapParams.trade) { const error = new Error('No `trade` found when calling `executeSwap`') - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: No trade found', { - swapParams: { - hasTrade: !!swapParams.trade, - hasDerivedSwapInfo: !!swapParams.derivedSwapInfo, - chainId: swapParams.derivedSwapInfo?.chainId, - }, - }) - } onFailure(error) return } - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] Starting swap execution...', { - trade: swapParams.trade, - chainId: swapParams.derivedSwapInfo.chainId, - }) - } - // Ensure we have fresh transaction data before executing the swap const { data: freshSwapTxData, error } = await tryCatch( ensureFreshSwapTxData( @@ -232,14 +216,6 @@ export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Ele cause: error, }) - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: Failed to ensure fresh transaction data', { - error: error.message, - errorDetails: error, - cause: error instanceof Error ? error.cause : undefined, - }) - } - logger.error(wrappedError, { tags: { file: 'SwapFormButton', function: 'executeSwapDirectly' }, }) @@ -250,44 +226,12 @@ export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Ele if (!freshSwapTxData) { const error = new Error('Empty swap transaction data returned') - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: Empty swap transaction data', { - swapParams: { - trade: swapParams.trade, - chainId: swapParams.derivedSwapInfo.chainId, - }, - }) - } onFailure(error) return } - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] Transaction data prepared, executing swap...', { - txRequests: 'txRequests' in freshSwapTxData ? freshSwapTxData.txRequests : undefined, - gasEstimate: freshSwapTxData.gasFeeEstimation, - gasFee: freshSwapTxData.gasFee, - routing: freshSwapTxData.routing, - hasTrade: !!freshSwapTxData.trade, - isValidSwapTxContext: isValidSwapTxContext(freshSwapTxData), - swapTxContextKeys: Object.keys(freshSwapTxData), - }) - } - if (!isValidSwapTxContext(freshSwapTxData)) { const error = new Error('Invalid swap transaction context') - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: Invalid swap transaction context', { - swapTxContext: { - routing: freshSwapTxData.routing, - hasTrade: !!freshSwapTxData.trade, - hasTxRequests: 'txRequests' in freshSwapTxData ? !!freshSwapTxData.txRequests : false, - gasFee: freshSwapTxData.gasFee, - gasFeeEstimation: freshSwapTxData.gasFeeEstimation, - keys: Object.keys(freshSwapTxData), - }, - }) - } onFailure(error) return } @@ -301,22 +245,12 @@ export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Ele getSwapTxContext: () => freshSwapTxData, }) - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] Calling executeSwapService.executeSwap()...') - } - executeSwapService.executeSwap() } catch (error) { const swapError = error instanceof Error ? error : new Error(String(error)) - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: Unexpected error in executeSwapDirectly', { - error: swapError.message, - errorDetails: swapError, - stack: swapError.stack, - }) - } logger.error(swapError, { tags: { file: 'SwapFormButton', function: 'executeSwapDirectly' }, + extra: { stack: swapError.stack }, }) onFailure(swapError) } diff --git a/packages/uniswap/src/features/transactions/swap/components/UnichainInstantBalanceModal/constants.ts b/packages/uniswap/src/features/transactions/swap/components/UnichainInstantBalanceModal/constants.ts index 7487e15671a..29547fef9eb 100644 --- a/packages/uniswap/src/features/transactions/swap/components/UnichainInstantBalanceModal/constants.ts +++ b/packages/uniswap/src/features/transactions/swap/components/UnichainInstantBalanceModal/constants.ts @@ -18,11 +18,11 @@ export const CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS: Partial ctx.getSwapDelegationInfo?.(chainId)) const isBatchableFlow = Boolean(routing && !isUniswapX({ routing })) + const isHashKeyChain = chainId === UniverseChainId.HashKey || chainId === UniverseChainId.HashKeyTestnet + + if (isHashKeyChain) { + // HashKey swaps use direct router calldata and are not atomic-batched with approvals. + return false + } return Boolean((canBatchTransactions || swapDelegationInfo?.delegationAddress) && isBatchableFlow) } @@ -47,6 +53,7 @@ export function useTokenApprovalInfo(params: TokenApprovalInfoParams): ApprovalT const isWrap = wrapType !== WrapType.NotApplicable /** Approval is included elsewhere for Chained Actions so it can be skipped */ const isChained = routing === TradingApi.Routing.CHAINED + const isHashKeyChain = chainId === UniverseChainId.HashKey || chainId === UniverseChainId.HashKeyTestnet const address = account?.address const inputWillBeWrapped = routing && isUniswapX({ routing }) @@ -125,6 +132,17 @@ export function useTokenApprovalInfo(params: TokenApprovalInfoParams): ApprovalT } if (data && !error) { + if (process.env.NODE_ENV === 'development' && isHashKeyChain) { + console.log('[approval debug][HashKey] checkApproval result', { + approvalRequestArgs, + data, + hasApproval: !!data.approval, + hasCancel: !!data.cancel, + gasFee: data.gasFee, + cancelGasFee: data.cancelGasFee, + }) + } + // API returns null if no approval is required // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition diff --git a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/classic/classicSwapTxAndGasInfoService.ts b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/classic/classicSwapTxAndGasInfoService.ts index ade68068025..8a81e073ca9 100644 --- a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/classic/classicSwapTxAndGasInfoService.ts +++ b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/classic/classicSwapTxAndGasInfoService.ts @@ -19,7 +19,33 @@ export function createClassicSwapTxAndGasInfoService(ctx: { const service: SwapTxAndGasInfoService = { async getSwapTxAndGasInfo(params) { + if (process.env.NODE_ENV === 'development') { + console.log('[execute] classicSwapTxAndGasInfoService.getSwapTxAndGasInfo called:', { + hasTrade: !!params.trade, + routing: params.trade?.routing, + hasApprovalTxInfo: !!params.approvalTxInfo, + hasDerivedSwapInfo: !!params.derivedSwapInfo, + }) + } + const swapTxInfo = await getEVMSwapTransactionRequestInfo(params) + + if (process.env.NODE_ENV === 'development') { + console.log('[execute] classicSwapTxAndGasInfoService - Got swapTxInfo:', { + hasSwapTxInfo: !!swapTxInfo, + hasSwapRequestArgs: !!swapTxInfo.swapRequestArgs, + swapRequestArgs: swapTxInfo.swapRequestArgs ? { + deadline: swapTxInfo.swapRequestArgs.deadline, + deadlineDate: swapTxInfo.swapRequestArgs.deadline ? new Date(swapTxInfo.swapRequestArgs.deadline * 1000).toLocaleString('zh-CN') : undefined, + hasQuote: !!swapTxInfo.swapRequestArgs.quote, + simulateTransaction: swapTxInfo.swapRequestArgs.simulateTransaction, + allKeys: Object.keys(swapTxInfo.swapRequestArgs), + } : 'swapRequestArgs is undefined', + hasTxRequests: !!swapTxInfo.txRequests, + txRequestCount: swapTxInfo.txRequests?.length || 0, + }) + } + const permitTxInfo = getPermitTxInfo(params.trade) return getClassicSwapTxAndGasInfo({ ...params, swapTxInfo, permitTxInfo }) diff --git a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/evmSwapInstructionsService.ts b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/evmSwapInstructionsService.ts index 3c896cb72e5..e8b1c4b5bf4 100644 --- a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/evmSwapInstructionsService.ts +++ b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/evmSwapInstructionsService.ts @@ -24,7 +24,7 @@ import { ApprovalAction } from 'uniswap/src/features/transactions/swap/types/tra import { tradingApiToUniverseChainId } from 'uniswap/src/features/transactions/swap/utils/tradingApi' type SwapInstructions = - | { response: SwapData; unsignedPermit: null; swapRequestParams: null } + | { response: SwapData; unsignedPermit: null; swapRequestParams: TradingApi.CreateSwapRequest | null } | { response: null; unsignedPermit: TradingApi.Permit; swapRequestParams: TradingApi.CreateSwapRequest } /** A service utility capable of fetching swap instructions or returning unsigned permit data when instructions cannot yet be fetched. */ @@ -69,12 +69,22 @@ function createLegacyEVMSwapInstructionsService( alreadyApproved, }) + if (process.env.NODE_ENV === 'development') { + console.log('[execute] createLegacyEVMSwapInstructionsService - Prepared swapRequestParams:', { + deadline: swapRequestParams.deadline, + deadlineDate: swapRequestParams.deadline ? new Date(swapRequestParams.deadline * 1000).toLocaleString('zh-CN') : undefined, + hasQuote: !!swapRequestParams.quote, + simulateTransaction: swapRequestParams.simulateTransaction, + }) + } + if (signatureMissing) { return { response: null, unsignedPermit: permitData, swapRequestParams } } const response = await swapRepository.fetchSwapData(swapRequestParams) - return { response, unsignedPermit: null, swapRequestParams: null } + // Keep swapRequestParams even when we have a response, so deadline is preserved in swapTxContext + return { response, unsignedPermit: null, swapRequestParams } }, } @@ -100,8 +110,18 @@ function createBatchedEVMSwapInstructionsService( overrideSimulation: true, // always simulate for batched transactions }) + if (process.env.NODE_ENV === 'development') { + console.log('[execute] createBatchedEVMSwapInstructionsService - Prepared swapRequestParams:', { + deadline: swapRequestParams.deadline, + deadlineDate: swapRequestParams.deadline ? new Date(swapRequestParams.deadline * 1000).toLocaleString('zh-CN') : undefined, + hasQuote: !!swapRequestParams.quote, + simulateTransaction: swapRequestParams.simulateTransaction, + }) + } + const response = await swapRepository.fetchSwapData(swapRequestParams) - return { response, unsignedPermit: null, swapRequestParams: null } + // Keep swapRequestParams even when we have a response, so deadline is preserved in swapTxContext + return { response, unsignedPermit: null, swapRequestParams } }, } diff --git a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/utils.ts b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/utils.ts index 3baef326bbf..218bb9ee597 100644 --- a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/utils.ts +++ b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/utils.ts @@ -4,6 +4,7 @@ import type { ApprovalTxInfo } from 'uniswap/src/features/transactions/swap/revi import type { EVMSwapInstructionsService } from 'uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/evmSwapInstructionsService' import type { TransactionRequestInfo } from 'uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils' import { + createPrepareSwapRequestParams, createProcessSwapResponse, getSwapInputExceedsBalance, } from 'uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils' @@ -31,6 +32,7 @@ export function createGetEVMSwapTransactionRequestInfo(ctx: { const { gasStrategy, transactionSettings, instructionService } = ctx const processSwapResponse = createProcessSwapResponse({ gasStrategy }) + const prepareSwapRequestParams = createPrepareSwapRequestParams({ gasStrategy }) const getEVMSwapTransactionRequestInfo: GetEVMSwapTransactionRequestInfoFn = async ({ trade, @@ -46,23 +48,102 @@ export function createGetEVMSwapTransactionRequestInfo(ctx: { const approvalUnknown = approvalAction === ApprovalAction.Unknown const skip = getSwapInputExceedsBalance({ derivedSwapInfo }) || approvalUnknown + + if (process.env.NODE_ENV === 'development') { + console.log('[execute] createGetEVMSwapTransactionRequestInfo - Before getSwapInstructions:', { + skip, + approvalAction, + approvalUnknown, + inputExceedsBalance: getSwapInputExceedsBalance({ derivedSwapInfo }), + hasInstructionService: !!instructionService, + }) + } + + // Always prepare swapRequestParams, even if skip is true, so deadline is preserved + const alreadyApproved = approvalAction === ApprovalAction.None && !swapQuoteResponse.permitTransaction + const swapRequestParams = prepareSwapRequestParams({ + swapQuoteResponse, + signature: undefined, + transactionSettings, + alreadyApproved, + }) + + if (process.env.NODE_ENV === 'development') { + console.log('[execute] createGetEVMSwapTransactionRequestInfo - Prepared swapRequestParams:', { + deadline: swapRequestParams.deadline, + deadlineDate: swapRequestParams.deadline ? new Date(swapRequestParams.deadline * 1000).toLocaleString('zh-CN') : undefined, + hasQuote: !!swapRequestParams.quote, + simulateTransaction: swapRequestParams.simulateTransaction, + }) + } + const { data, error } = await tryCatch( skip ? Promise.resolve(undefined) : instructionService.getSwapInstructions({ swapQuoteResponse, transactionSettings, approvalAction }), ) + if (process.env.NODE_ENV === 'development') { + console.log('[execute] createGetEVMSwapTransactionRequestInfo - After getSwapInstructions:', { + hasData: !!data, + data: data ? { + hasResponse: !!data.response, + hasUnsignedPermit: !!data.unsignedPermit, + hasSwapRequestParams: !!data.swapRequestParams, + swapRequestParams: data.swapRequestParams ? { + deadline: data.swapRequestParams.deadline, + deadlineDate: data.swapRequestParams.deadline ? new Date(data.swapRequestParams.deadline * 1000).toLocaleString('zh-CN') : undefined, + hasQuote: !!data.swapRequestParams.quote, + simulateTransaction: data.swapRequestParams.simulateTransaction, + } : 'swapRequestParams is undefined', + } : 'data is undefined', + hasError: !!error, + error: error?.message, + }) + } + const isRevokeNeeded = tokenApprovalInfo.action === ApprovalAction.RevokeAndPermit2Approve + + if (process.env.NODE_ENV === 'development') { + console.log('[execute] createGetEVMSwapTransactionRequestInfo - Before processSwapResponse:', { + hasResponse: !!data?.response, + hasSwapRequestParams: !!data?.swapRequestParams, + swapRequestParams: data?.swapRequestParams ? { + deadline: data.swapRequestParams.deadline, + deadlineDate: data.swapRequestParams.deadline ? new Date(data.swapRequestParams.deadline * 1000).toLocaleString('zh-CN') : undefined, + hasQuote: !!data.swapRequestParams.quote, + simulateTransaction: data.swapRequestParams.simulateTransaction, + } : 'swapRequestParams is undefined', + hasUnsignedPermit: !!data?.unsignedPermit, + }) + } + + // Use swapRequestParams from data if available, otherwise use the one we prepared + const finalSwapRequestParams = data?.swapRequestParams ?? swapRequestParams + const swapTxInfo = processSwapResponse({ response: data?.response ?? undefined, error, permitData: data?.unsignedPermit, swapQuote, + trade, isSwapLoading: false, isRevokeNeeded, - swapRequestParams: data?.swapRequestParams ?? undefined, + swapRequestParams: finalSwapRequestParams, }) + if (process.env.NODE_ENV === 'development') { + console.log('[execute] createGetEVMSwapTransactionRequestInfo - After processSwapResponse:', { + hasSwapRequestArgs: !!swapTxInfo.swapRequestArgs, + swapRequestArgs: swapTxInfo.swapRequestArgs ? { + deadline: swapTxInfo.swapRequestArgs.deadline, + deadlineDate: swapTxInfo.swapRequestArgs.deadline ? new Date(swapTxInfo.swapRequestArgs.deadline * 1000).toLocaleString('zh-CN') : undefined, + hasQuote: !!swapTxInfo.swapRequestArgs.quote, + simulateTransaction: swapTxInfo.swapRequestArgs.simulateTransaction, + } : 'swapRequestArgs is undefined', + }) + } + return swapTxInfo } diff --git a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts index e46ab749298..4f19c36cce7 100644 --- a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts +++ b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts @@ -16,6 +16,7 @@ import { getTradeSettingsDeadline } from 'uniswap/src/data/apiClients/tradingApi import { getChainLabel } from 'uniswap/src/features/chains/utils' import { convertGasFeeToDisplayValue, useActiveGasStrategy } from 'uniswap/src/features/gas/hooks' import type { GasFeeResult } from 'uniswap/src/features/gas/types' +import { SwapRouter as V3SwapRouter } from '@uniswap/router-sdk' import { SwapEventName } from 'uniswap/src/features/telemetry/constants' import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send' import type { TransactionSettings } from 'uniswap/src/features/transactions/components/settings/types' @@ -46,6 +47,7 @@ import type { import { ApprovalAction } from 'uniswap/src/features/transactions/swap/types/trade' import { mergeGasFeeResults } from 'uniswap/src/features/transactions/swap/utils/gas' import { isClassic } from 'uniswap/src/features/transactions/swap/utils/routing' +import { slippageToleranceToPercent } from 'uniswap/src/features/transactions/swap/utils/format' import { validatePermit, validateTransactionRequest, @@ -100,12 +102,14 @@ export function createPrepareSwapRequestParams({ gasStrategy }: { gasStrategy: G transactionSettings, alreadyApproved, overrideSimulation, + blockTimestamp, }: { swapQuoteResponse: ClassicQuoteResponse | BridgeQuoteResponse | WrapQuoteResponse | UnwrapQuoteResponse signature: string | undefined transactionSettings: TransactionSettings alreadyApproved: boolean overrideSimulation?: boolean + blockTimestamp?: bigint | number }): TradingApi.CreateSwapRequest { const isBridgeTrade = swapQuoteResponse.routing === TradingApi.Routing.BRIDGE const permitData = swapQuoteResponse.permitData @@ -119,7 +123,7 @@ export function createPrepareSwapRequestParams({ gasStrategy }: { gasStrategy: G */ const shouldSimulateTxn = overrideSimulation ?? (isBridgeTrade ? false : alreadyApproved) - const deadline = getTradeSettingsDeadline(transactionSettings.customDeadline) + const deadline = getTradeSettingsDeadline(transactionSettings.customDeadline, blockTimestamp) return { quote: swapQuoteResponse.quote, @@ -238,39 +242,8 @@ function getGasFeeFromQuote( /** * Build transaction request from quote methodParameters when swap API response is not available */ -function buildTxRequestFromQuote( - swapQuote: TradingApi.ClassicQuote | TradingApi.BridgeQuote | undefined, - chainId: number, -): providers.TransactionRequest[] | undefined { - // Type assertion: methodParameters exists in ClassicQuote but may not be in type definition - const quoteWithMethodParams = swapQuote as (TradingApi.ClassicQuote | TradingApi.BridgeQuote) & { - methodParameters?: { calldata: string; value: string } - } - - if (!quoteWithMethodParams?.methodParameters) { - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: No methodParameters in quote', { - hasSwapQuote: !!swapQuote, - chainId, - }) - } - return undefined - } - - const { calldata, value } = quoteWithMethodParams.methodParameters - - if (!calldata) { - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: No calldata in methodParameters', { - hasMethodParameters: !!quoteWithMethodParams?.methodParameters, - hasValue: !!value, - chainId, - }) - } - return undefined - } - - // Get Universal Router address from chainId +function getRouterAddressForChain(chainId: number): { routerAddress?: string; routerSource?: string } { + // Get router address from chainId // For HashKey chains, use the first address from CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS if available // Otherwise, try to get from UNIVERSAL_ROUTER_ADDRESS function let routerAddress: string | undefined @@ -282,11 +255,11 @@ function buildTxRequestFromQuote( const { CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS } = require('uniswap/src/features/transactions/swap/components/UnichainInstantBalanceModal/constants') // eslint-disable-next-line @typescript-eslint/no-require-imports const { UniverseChainId: UniverseChainIdEnum } = require('uniswap/src/features/chains/types') - + // Try both numeric key and enum key lookup const chainIdAsEnum = chainId as UniverseChainId let addresses = CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS[chainIdAsEnum] - + // If not found, try looking up by numeric value (for HashKey chains: 133, 177) if (!addresses && (chainId === 133 || chainId === 177)) { // Try direct numeric lookup @@ -302,13 +275,7 @@ function buildTxRequestFromQuote( routerSource = 'CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS' } } catch (error) { - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: Failed to load CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS', { - error: error instanceof Error ? error.message : String(error), - chainId, - errorDetails: error, - }) - } + // Ignore error } // Fallback to UNIVERSAL_ROUTER_ADDRESS if available @@ -319,43 +286,60 @@ function buildTxRequestFromQuote( routerAddress = UNIVERSAL_ROUTER_ADDRESS(UniversalRouterVersion.V1_2, chainId) routerSource = 'UNIVERSAL_ROUTER_ADDRESS' } catch (error) { - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: Failed to get router address from UNIVERSAL_ROUTER_ADDRESS', { - error: error instanceof Error ? error.message : String(error), - chainId, - }) - } + // Ignore error } } + return { routerAddress, routerSource } +} + +function getGasLimitWithBuffer( + gasUseEstimate?: string | number, + { multiplier = 1.2 }: { multiplier?: number } = {}, +): string | undefined { + if (!gasUseEstimate) { + return undefined + } + try { + const gasUseEstimateStr = String(gasUseEstimate) + const factor = Math.floor(multiplier * 100) + const gasLimitWithBuffer = (BigInt(gasUseEstimateStr) * BigInt(factor)) / BigInt(100) + return gasLimitWithBuffer.toString() + } catch { + return undefined + } +} + +function buildTxRequestFromQuote( + swapQuote: TradingApi.ClassicQuote | TradingApi.BridgeQuote | undefined, + chainId: number, +): providers.TransactionRequest[] | undefined { + // Type assertion: methodParameters exists in ClassicQuote but may not be in type definition + const quoteWithMethodParams = swapQuote as (TradingApi.ClassicQuote | TradingApi.BridgeQuote) & { + methodParameters?: { calldata: string; value: string } + } + + if (!quoteWithMethodParams?.methodParameters) { + return undefined + } + + const { calldata, value } = quoteWithMethodParams.methodParameters + + if (!calldata) { + return undefined + } + + const { routerAddress } = getRouterAddressForChain(chainId) + if (!routerAddress) { // For HashKey chains (133, 177), they may not use Universal Router - // In this case, we need to check if the quote's methodParameters contains a 'to' address - // or if the user has configured a custom router address if (chainId === 133 || chainId === 177) { - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: HashKey chain does not have Universal Router configured', { - chainId, - routerSource, - message: 'Please configure the swap router address for HashKey chains in CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS', - suggestion: 'Add the HashKey swap router address to constants.ts', - }) - } logger.error('HashKey chain does not have Universal Router configured', { tags: { file: 'utils.ts', function: 'buildTxRequestFromQuote' }, extra: { chainId }, }) - // Return undefined to indicate that we cannot build the transaction request - // The user needs to configure the router address in CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS return undefined } - - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: Could not determine router address', { - chainId, - routerSource, - }) - } logger.error('Could not determine Universal Router address', { tags: { file: 'utils.ts', function: 'buildTxRequestFromQuote' }, extra: { chainId }, @@ -378,26 +362,50 @@ function buildTxRequestFromQuote( const quoteWithGasEstimate = quoteWithMethodParams as (TradingApi.ClassicQuote | TradingApi.BridgeQuote) & { gasUseEstimate?: string | number } - if (quoteWithGasEstimate && 'gasUseEstimate' in quoteWithGasEstimate && quoteWithGasEstimate.gasUseEstimate) { - try { - const gasUseEstimateStr = String(quoteWithGasEstimate.gasUseEstimate) - // Add 20% buffer: gasLimit = gasUseEstimate * 1.2 - const gasLimitWithBuffer = (BigInt(gasUseEstimateStr) * BigInt(120)) / BigInt(100) - txRequest.gasLimit = gasLimitWithBuffer.toString() - - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] buildTxRequestFromQuote: Set gasLimit from quote', { - gasUseEstimate: gasUseEstimateStr, - gasLimitWithBuffer: gasLimitWithBuffer.toString(), - chainId, - }) - } - } catch (error) { - // If conversion fails, let prepareTransaction handle it - if (process.env.NODE_ENV === 'development') { - console.warn('[Swap] Failed to set gasLimit from quote:', error) - } - } + const isHashKey = chainId === UniverseChainId.HashKey || chainId === UniverseChainId.HashKeyTestnet + const gasLimitBuffered = getGasLimitWithBuffer(quoteWithGasEstimate.gasUseEstimate, { + multiplier: isHashKey ? 1.6 : 1.2, + }) + if (gasLimitBuffered) { + txRequest.gasLimit = gasLimitBuffered + } + + return [txRequest] +} + +function buildTxRequestFromTrade( + trade: ClassicTrade, + chainId: number, + deadline?: number, +): providers.TransactionRequest[] | undefined { + const { routerAddress } = getRouterAddressForChain(chainId) + if (!routerAddress) { + return undefined + } + + const slippageTolerance = slippageToleranceToPercent(trade.slippageTolerance) + const deadlineOrPreviousBlockhash = String(deadline ?? trade.deadline ?? 0) + const feeOptions = + trade.swapFee?.recipient && trade.swapFee.feeField === CurrencyField.OUTPUT + ? { fee: trade.swapFee.percent, recipient: trade.swapFee.recipient } + : undefined + + const gasLimitBuffered = getGasLimitWithBuffer((trade as any)?.quote?.quote?.gasUseEstimate, { + multiplier: chainId === UniverseChainId.HashKey || chainId === UniverseChainId.HashKeyTestnet ? 1.6 : 1.2, + }) + + const { calldata, value } = V3SwapRouter.swapCallParameters(trade, { + slippageTolerance, + deadlineOrPreviousBlockhash, + fee: feeOptions, + }) + + const txRequest: providers.TransactionRequest = { + to: routerAddress, + data: calldata, + value: value && value !== '0x00' ? value : undefined, + chainId, + ...(gasLimitBuffered ? { gasLimit: gasLimitBuffered } : {}), } return [txRequest] @@ -408,6 +416,7 @@ export function createProcessSwapResponse({ gasStrategy }: { gasStrategy: GasStr response, error, swapQuote, + trade, isSwapLoading, permitData, swapRequestParams, @@ -418,6 +427,7 @@ export function createProcessSwapResponse({ gasStrategy }: { gasStrategy: GasStr response: SwapData | undefined error: Error | null swapQuote: TradingApi.ClassicQuote | TradingApi.BridgeQuote | undefined + trade?: ClassicTrade isSwapLoading: boolean permitData: TradingApi.NullablePermit | undefined swapRequestParams: TradingApi.CreateSwapRequest | undefined @@ -448,9 +458,9 @@ export function createProcessSwapResponse({ gasStrategy }: { gasStrategy: GasStr finalChainId = 133 // UniverseChainId.HashKeyTestnet } - // We use the gasFee estimate from quote, as its more accurate - // Calculate gasFee from quote response (either directly from gasFee or from gasPriceWei * gasUseEstimate) - const swapGasFee = getGasFeeFromQuote(swapQuote, gasStrategy) + // We use the gasFee estimate from quote, as its more accurate + // Calculate gasFee from quote response (either directly from gasFee or from gasPriceWei * gasUseEstimate) + const swapGasFee = getGasFeeFromQuote(swapQuote, gasStrategy) // This is a case where simulation fails on backend, meaning txn is expected to fail const simulationError = getSimulationError({ swapQuote, isRevokeNeeded }) @@ -484,10 +494,20 @@ export function createProcessSwapResponse({ gasStrategy }: { gasStrategy: GasStr swapEstimate: response?.gasEstimate, } + const isHashKeyChain = finalChainId === UniverseChainId.HashKey || finalChainId === UniverseChainId.HashKeyTestnet + // Use swap API transactions if available, otherwise build from quote methodParameters let txRequests: providers.TransactionRequest[] | undefined - if (response?.transactions) { + if (isHashKeyChain && trade) { + txRequests = buildTxRequestFromTrade(trade, finalChainId, swapRequestParams?.deadline) + if (!txRequests) { + logger.error('HashKey chain failed to build SwapRouter02 txRequest from trade', { + tags: { file: 'utils.ts', function: 'processSwapResponse' }, + extra: { chainId: finalChainId }, + }) + } + } else if (response?.transactions) { txRequests = response.transactions } else if (finalChainId && swapQuote) { txRequests = buildTxRequestFromQuote(swapQuote, finalChainId) @@ -519,18 +539,6 @@ export function createProcessSwapResponse({ gasStrategy }: { gasStrategy: GasStr // But if it does, we should still try to build with finalChainId if (finalChainId && swapQuote) { txRequests = buildTxRequestFromQuote(swapQuote, finalChainId) - } else { - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: Cannot build transaction requests - missing required data', { - hasResponseTransactions: !!response?.transactions, - hasChainId: !!chainId, - hasFinalChainId: !!finalChainId, - hasSwapQuote: !!swapQuote, - chainId, - finalChainId, - swapQuoteKeys: swapQuote ? Object.keys(swapQuote) : undefined, - }) - } } } diff --git a/packages/uniswap/src/features/transactions/swap/services/executeSwapService.ts b/packages/uniswap/src/features/transactions/swap/services/executeSwapService.ts index 89be845c61c..1a7c358afb8 100644 --- a/packages/uniswap/src/features/transactions/swap/services/executeSwapService.ts +++ b/packages/uniswap/src/features/transactions/swap/services/executeSwapService.ts @@ -49,6 +49,40 @@ export function createExecuteSwapService(ctx: { const swapTxContext = ctx.getSwapTxContext?.() const account = ctx.getAccount?.() + if (process.env.NODE_ENV === 'development') { + console.log('[execute] executeSwapService executeSwap called:', { + account: account ? { + address: account.address, + chainId: account.chainId, + accountType: account.accountType, + } : undefined, + swapTxContext: swapTxContext ? { + routing: swapTxContext.routing, + hasTxRequests: !!swapTxContext.txRequests, + txRequestCount: swapTxContext.txRequests?.length || 0, + hasTrade: !!swapTxContext.trade, + includesDelegation: swapTxContext.includesDelegation, + hasSwapRequestArgs: 'swapRequestArgs' in swapTxContext, + swapRequestArgs: swapTxContext.swapRequestArgs ? { + deadline: swapTxContext.swapRequestArgs.deadline, + deadlineDate: swapTxContext.swapRequestArgs.deadline ? new Date(swapTxContext.swapRequestArgs.deadline * 1000).toLocaleString('zh-CN') : undefined, + hasQuote: !!swapTxContext.swapRequestArgs.quote, + simulateTransaction: swapTxContext.swapRequestArgs.simulateTransaction, + allKeys: Object.keys(swapTxContext.swapRequestArgs), + } : 'swapRequestArgs is undefined', + swapTxContextKeys: Object.keys(swapTxContext), + } : undefined, + currencyAmounts: currencyAmounts ? { + input: currencyAmounts.input?.toExact(), + output: currencyAmounts.output?.toExact(), + } : undefined, + currencyAmountsUSDValue: currencyAmountsUSDValue, + txId, + wrapType, + customSlippageTolerance, + }) + } + if ( !account || !swapTxContext || @@ -56,11 +90,11 @@ export function createExecuteSwapService(ctx: { !isValidSwapTxContext(swapTxContext) ) { const errorMessage = !account - ? 'No account available' - : !swapTxContext - ? 'Missing swap transaction context' - : !isSignerMnemonicAccountDetails(account) - ? 'Invalid account type - must be signer mnemonic account' + ? 'No account available' + : !swapTxContext + ? 'Missing swap transaction context' + : !isSignerMnemonicAccountDetails(account) + ? 'Invalid account type - must be signer mnemonic account' : 'Invalid swap transaction context' if (process.env.NODE_ENV === 'development') { @@ -75,8 +109,7 @@ export function createExecuteSwapService(ctx: { const { presetPercentage, preselectAsset } = ctx.getPresetInfo() - ctx - .onExecuteSwap({ + const executeParams = { account, swapTxContext, currencyInAmountUSD: currencyAmountsUSDValue[CurrencyField.INPUT] ?? undefined, @@ -93,18 +126,48 @@ export function createExecuteSwapService(ctx: { isFiatInputMode: ctx.getIsFiatMode?.(), wrapType, inputCurrencyAmount: currencyAmounts.input ?? undefined, + } + + if (process.env.NODE_ENV === 'development') { + console.log('[execute] executeSwapService calling onExecuteSwap with params:', executeParams) + console.log('[execute] executeSwapService - Detailed swapTxContext:', { + routing: executeParams.swapTxContext?.routing, + hasTxRequests: !!executeParams.swapTxContext?.txRequests, + txRequestCount: executeParams.swapTxContext?.txRequests?.length || 0, + txRequests: executeParams.swapTxContext?.txRequests?.map((tx, idx) => ({ + index: idx, + to: tx.to, + data: tx.data?.substring(0, 20) + '...', + value: tx.value?.toString(), + gasLimit: tx.gasLimit?.toString(), + gasPrice: tx.gasPrice?.toString(), + chainId: tx.chainId, + })), + hasTrade: !!executeParams.swapTxContext?.trade, + trade: executeParams.swapTxContext?.trade ? { + routing: executeParams.swapTxContext.trade.routing, + inputAmount: executeParams.swapTxContext.trade.inputAmount?.toExact(), + outputAmount: executeParams.swapTxContext.trade.outputAmount?.toExact(), + deadline: executeParams.swapTxContext.trade.deadline, + deadlineDate: executeParams.swapTxContext.trade.deadline ? new Date(executeParams.swapTxContext.trade.deadline * 1000).toLocaleString('zh-CN') : undefined, + } : undefined, + includesDelegation: executeParams.swapTxContext?.includesDelegation, + hasSwapRequestArgs: 'swapRequestArgs' in (executeParams.swapTxContext || {}), + swapRequestArgs: executeParams.swapTxContext?.swapRequestArgs ? { + deadline: executeParams.swapTxContext.swapRequestArgs.deadline, + deadlineDate: executeParams.swapTxContext.swapRequestArgs.deadline ? new Date(executeParams.swapTxContext.swapRequestArgs.deadline * 1000).toLocaleString('zh-CN') : undefined, + hasQuote: !!executeParams.swapTxContext.swapRequestArgs.quote, + simulateTransaction: executeParams.swapTxContext.swapRequestArgs.simulateTransaction, + allKeys: Object.keys(executeParams.swapTxContext.swapRequestArgs), + fullSwapRequestArgs: executeParams.swapTxContext.swapRequestArgs, + } : 'swapRequestArgs is undefined', + swapTxContextKeys: executeParams.swapTxContext ? Object.keys(executeParams.swapTxContext) : [], }) + } + + ctx.onExecuteSwap(executeParams) .catch((error) => { const swapError = error instanceof Error ? error : new Error(String(error)) - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: onExecuteSwap failed', { - error: swapError.message, - errorDetails: swapError, - stack: swapError.stack, - accountAddress: account.address, - txId, - }) - } ctx.onFailure(swapError) }) }, diff --git a/packages/uniswap/src/features/transactions/swap/services/tradeService/evmTradeService.ts b/packages/uniswap/src/features/transactions/swap/services/tradeService/evmTradeService.ts index 5a0cb0be4b9..6469529891a 100644 --- a/packages/uniswap/src/features/transactions/swap/services/tradeService/evmTradeService.ts +++ b/packages/uniswap/src/features/transactions/swap/services/tradeService/evmTradeService.ts @@ -103,6 +103,7 @@ export function createEVMTradeService(ctx: EVMTradeServiceContext): TradeService const quoteHash = getIdentifierForQuote(quoteRequestArgs) // Step 5: Transform quote to trade + // Pass customSlippageTolerance to ensure trade uses user configuration instead of API response const result = transformQuoteToTrade({ quote: quoteResponse, amountSpecified: validatedInput.amount, @@ -111,6 +112,7 @@ export function createEVMTradeService(ctx: EVMTradeServiceContext): TradeService currencyOut: validatedInput.currencyOut, requestTradeType: validatedInput.requestTradeType, }, + customSlippageTolerance: input.customSlippageTolerance, }) // Return trade with gas estimates return { diff --git a/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/transformQuoteToTrade.ts b/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/transformQuoteToTrade.ts index ab49565b8ae..44a39b0818d 100644 --- a/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/transformQuoteToTrade.ts +++ b/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/transformQuoteToTrade.ts @@ -22,6 +22,7 @@ export function transformQuoteToTrade(input: { quote: DiscriminatedQuoteResponse | null amountSpecified: Maybe> quoteCurrencyData: QuoteCurrencyData + customSlippageTolerance?: number }): QuoteWithTradeAndGasEstimate { if (!input.quote) { return null @@ -35,6 +36,18 @@ export function transformQuoteToTrade(input: { requestTradeType === TradingApi.TradeType.EXACT_INPUT ? SdkTradeType.EXACT_INPUT : SdkTradeType.EXACT_OUTPUT const gasEstimate = getGasEstimate(input.quote) + // Override quote.slippage with customSlippageTolerance if provided + // This ensures trade.slippageTolerance uses user configuration instead of API response + const quoteWithCustomSlippage = input.customSlippageTolerance !== undefined && input.quote.routing === TradingApi.Routing.CLASSIC + ? { + ...input.quote, + quote: { + ...input.quote.quote, + slippage: input.customSlippageTolerance, + }, + } + : input.quote + const formattedTrade = currencyIn && currencyOut ? transformTradingApiResponseToTrade({ @@ -42,7 +55,7 @@ export function transformQuoteToTrade(input: { currencyOut, tradeType, deadline: inXMinutesUnix(DEFAULT_SWAP_VALIDITY_TIME_MINS), // TODO(MOB-3050): set deadline as `quoteRequestArgs.deadline` - data: input.quote, + data: quoteWithCustomSlippage, }) : null @@ -57,7 +70,7 @@ export function transformQuoteToTrade(input: { : null return { - ...input.quote, + ...quoteWithCustomSlippage, gasEstimate, trade, } diff --git a/packages/uniswap/src/features/transactions/swap/stores/swapTxStore/hooks/useTransactionRequestInfo.ts b/packages/uniswap/src/features/transactions/swap/stores/swapTxStore/hooks/useTransactionRequestInfo.ts index 915ebd5b0c2..397b069c14c 100644 --- a/packages/uniswap/src/features/transactions/swap/stores/swapTxStore/hooks/useTransactionRequestInfo.ts +++ b/packages/uniswap/src/features/transactions/swap/stores/swapTxStore/hooks/useTransactionRequestInfo.ts @@ -22,6 +22,14 @@ import { UniverseChainId } from 'uniswap/src/features/chains/types' import { Platform } from 'uniswap/src/features/platforms/types/Platform' import { usePrevious } from 'utilities/src/react/hooks' +// Conditionally import useCurrentBlockTimestamp only on web app +let useCurrentBlockTimestamp: (() => bigint | undefined) | undefined +if (isWebApp) { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const useCurrentBlockTimestampModule = require('apps/web/src/hooks/useCurrentBlockTimestamp') + useCurrentBlockTimestamp = useCurrentBlockTimestampModule.default || useCurrentBlockTimestampModule +} + function useSwapTransactionRequestInfo({ derivedSwapInfo, tokenApprovalInfo, @@ -89,6 +97,21 @@ function useSwapTransactionRequestInfo({ const swapDelegationInfo = useUniswapContextSelector((ctx) => ctx.getSwapDelegationInfo?.(resolvedChainId)) const overrideSimulation = !!swapDelegationInfo?.delegationAddress + // Get block timestamp for accurate deadline calculation + // Only fetch on web app (where useCurrentBlockTimestamp is available) + const blockTimestamp = isWebApp && useCurrentBlockTimestamp ? useCurrentBlockTimestamp() : undefined + + if (process.env.NODE_ENV === 'development') { + console.log('[swap debug] useTransactionRequestInfo - Preparing swap request params:', { + customDeadline: transactionSettings.customDeadline, + hasSwapQuoteResponse: !!swapQuoteResponse, + alreadyApproved: tokenApprovalInfo?.action === ApprovalAction.None && !swapQuoteResponse?.permitTransaction, + overrideSimulation, + blockTimestamp: blockTimestamp?.toString(), + usingBlockTimestamp: !!blockTimestamp, + }) + } + const prepareSwapRequestParams = useMemo(() => createPrepareSwapRequestParams({ gasStrategy }), [gasStrategy]) const swapRequestParams = useMemo(() => { @@ -98,13 +121,16 @@ function useSwapTransactionRequestInfo({ const alreadyApproved = tokenApprovalInfo?.action === ApprovalAction.None && !swapQuoteResponse.permitTransaction - return prepareSwapRequestParams({ + const requestParams = prepareSwapRequestParams({ swapQuoteResponse, signature: signature ?? undefined, transactionSettings, alreadyApproved, overrideSimulation, + blockTimestamp, }) + + return requestParams }, [ swapQuoteResponse, tokenApprovalInfo?.action, @@ -112,6 +138,7 @@ function useSwapTransactionRequestInfo({ signature, transactionSettings, overrideSimulation, + blockTimestamp, ]) const canBatchTransactions = useUniswapContextSelector((ctx) => @@ -132,10 +159,11 @@ function useSwapTransactionRequestInfo({ // Ensure resolvedChainId is always defined const chainIdToUse = resolvedChainId ?? UniverseChainId.HashKeyTestnet - return processSwapResponse({ + const processResult = processSwapResponse({ response: data, error, swapQuote, + trade: derivedSwapInfo.trade.trade ?? undefined, isSwapLoading, permitData, swapRequestParams, @@ -143,6 +171,8 @@ function useSwapTransactionRequestInfo({ permitsDontNeedSignature, chainId: chainIdToUse, }) + + return processResult }, [ data, error, diff --git a/packages/uniswap/src/features/transactions/swap/utils/generateSwapTransactionSteps.ts b/packages/uniswap/src/features/transactions/swap/utils/generateSwapTransactionSteps.ts index 099ec5cb1ce..16c805095a9 100644 --- a/packages/uniswap/src/features/transactions/swap/utils/generateSwapTransactionSteps.ts +++ b/packages/uniswap/src/features/transactions/swap/utils/generateSwapTransactionSteps.ts @@ -1,3 +1,4 @@ +import { Interface } from '@ethersproject/abi' import { createApprovalTransactionStep } from 'uniswap/src/features/transactions/steps/approve' import { createPermit2SignatureStep } from 'uniswap/src/features/transactions/steps/permit2Signature' import { createPermit2TransactionStep } from 'uniswap/src/features/transactions/steps/permit2Transaction' @@ -13,22 +14,40 @@ import { import { orderUniswapXSteps } from 'uniswap/src/features/transactions/swap/steps/uniswapxSteps' import { isValidSwapTxContext, SwapTxAndGasInfo } from 'uniswap/src/features/transactions/swap/types/swapTxAndGasInfo' import { isBridge, isClassic, isUniswapX } from 'uniswap/src/features/transactions/swap/utils/routing' +import { UniverseChainId } from 'uniswap/src/features/chains/types' +import type { ValidatedTransactionRequest } from 'uniswap/src/features/transactions/types/transactionRequests' -export function generateSwapTransactionSteps(txContext: SwapTxAndGasInfo): TransactionStep[] { - const isValidSwap = isValidSwapTxContext(txContext) +function buildHashKeyApprovalTxRequest({ + trade, + swapTxRequest, +}: { + trade: ClassicTrade | BridgeTrade + swapTxRequest: ValidatedTransactionRequest | undefined +}): ValidatedTransactionRequest | undefined { + const chainId = trade.inputAmount.currency.chainId + const isHashKeyChain = chainId === UniverseChainId.HashKey || chainId === UniverseChainId.HashKeyTestnet + if (!isHashKeyChain) { + return undefined + } - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] generateSwapTransactionSteps:', { - isValidSwap, - routing: txContext.routing, - hasTxRequests: !!txContext.txRequests, - txRequestCount: txContext.txRequests?.length || 0, - isClassic: isClassic(txContext), - isBridge: isBridge(txContext), - isUniswapX: isUniswapX(txContext), - }) + const spender = swapTxRequest?.to?.toString() + if (!spender) { + return undefined } + const approveInterface = new Interface(['function approve(address spender,uint256 value)']) + + return { + to: trade.inputAmount.currency.wrapped.address, + data: approveInterface.encodeFunctionData('approve', [spender, trade.inputAmount.quotient.toString()]), + value: '0x0', + chainId, + } +} + +export function generateSwapTransactionSteps(txContext: SwapTxAndGasInfo): TransactionStep[] { + const isValidSwap = isValidSwapTxContext(txContext) + if (isValidSwap) { const { trade, approveTxRequest, revocationTxRequest } = txContext @@ -42,7 +61,7 @@ export function generateSwapTransactionSteps(txContext: SwapTxAndGasInfo): Trans }) const approval = createApprovalTransactionStep({ ...requestFields, - txRequest: approveTxRequest, + txRequest: approveTxRequest ?? buildHashKeyApprovalTxRequest({ trade, swapTxRequest: txContext.txRequests?.[0] }), amount: trade.inputAmount.quotient.toString(), }) @@ -71,62 +90,34 @@ export function generateSwapTransactionSteps(txContext: SwapTxAndGasInfo): Trans }) : undefined - const steps = orderClassicSwapSteps({ + return orderClassicSwapSteps({ revocation, approval, permit, swap: createSwapTransactionStep(txContext.txRequests[0]), }) - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] generateSwapTransactionSteps: Returning classic steps:', { - stepCount: steps.length, - stepTypes: steps.map((s) => s.type), - }) - } - return steps } else if (isUniswapX(txContext)) { - const steps = orderUniswapXSteps({ + return orderUniswapXSteps({ revocation, approval, signOrder: createSignUniswapXOrderStep(txContext.permit.typedData, txContext.trade.quote.quote), }) - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] generateSwapTransactionSteps: Returning UniswapX steps:', { - stepCount: steps.length, - stepTypes: steps.map((s) => s.type), - }) - } - return steps } else if (isBridge(txContext)) { - let steps: TransactionStep[] if (txContext.txRequests.length > 1) { - steps = orderClassicSwapSteps({ + return orderClassicSwapSteps({ permit: undefined, swap: createSwapTransactionStepBatched(txContext.txRequests), }) } else { - steps = orderClassicSwapSteps({ + return orderClassicSwapSteps({ revocation, approval, permit: undefined, swap: createSwapTransactionStep(txContext.txRequests[0]), }) } - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] generateSwapTransactionSteps: Returning bridge steps:', { - stepCount: steps.length, - stepTypes: steps.map((s) => s.type), - }) - } - return steps } } - if (process.env.NODE_ENV === 'development') { - console.warn('[Swap] generateSwapTransactionSteps: Returning empty steps array!', { - isValidSwap, - routing: txContext.routing, - }) - } return [] } diff --git a/packages/wallet/src/features/transactions/swap/executeSwapSaga.ts b/packages/wallet/src/features/transactions/swap/executeSwapSaga.ts index e8f7564acda..c2897dce9e2 100644 --- a/packages/wallet/src/features/transactions/swap/executeSwapSaga.ts +++ b/packages/wallet/src/features/transactions/swap/executeSwapSaga.ts @@ -502,7 +502,7 @@ export function createExecuteSwapSaga( // Call onSuccess after transaction is successfully submitted // For delayed submission, onSuccess will be called after all transactions are submitted - yield* call(onSuccess) + yield* call(onSuccess) } catch (error) { dependencies.logger.error(error, { tags: { file: 'executeSwapSaga', function: 'executeSwap' }, diff --git a/packages/wallet/src/features/transactions/swap/hooks/useSwapHandlers.ts b/packages/wallet/src/features/transactions/swap/hooks/useSwapHandlers.ts index 698d06c190a..20837dc5dde 100644 --- a/packages/wallet/src/features/transactions/swap/hooks/useSwapHandlers.ts +++ b/packages/wallet/src/features/transactions/swap/hooks/useSwapHandlers.ts @@ -39,6 +39,43 @@ export function useSwapHandlers(): SwapHandlers { const execute: ExecuteSwapCallback = useCallback( async (params: ExecuteSwapParams) => { + if (process.env.NODE_ENV === 'development') { + console.log('[execute] ExecuteSwapCallback called with params:', params) + console.log('[execute] ExecuteSwapCallback - Detailed swapTxContext:', { + routing: params.swapTxContext?.routing, + hasTxRequests: !!params.swapTxContext?.txRequests, + txRequestCount: params.swapTxContext?.txRequests?.length || 0, + txRequests: params.swapTxContext?.txRequests?.map((tx, idx) => ({ + index: idx, + to: tx.to, + data: tx.data?.substring(0, 20) + '...', + value: tx.value?.toString(), + gasLimit: tx.gasLimit?.toString(), + gasPrice: tx.gasPrice?.toString(), + chainId: tx.chainId, + })), + hasTrade: !!params.swapTxContext?.trade, + trade: params.swapTxContext?.trade ? { + routing: params.swapTxContext.trade.routing, + inputAmount: params.swapTxContext.trade.inputAmount?.toExact(), + outputAmount: params.swapTxContext.trade.outputAmount?.toExact(), + deadline: params.swapTxContext.trade.deadline, + deadlineDate: params.swapTxContext.trade.deadline ? new Date(params.swapTxContext.trade.deadline * 1000).toLocaleString('zh-CN') : undefined, + } : undefined, + includesDelegation: params.swapTxContext?.includesDelegation, + hasSwapRequestArgs: 'swapRequestArgs' in (params.swapTxContext || {}), + swapRequestArgs: params.swapTxContext?.swapRequestArgs ? { + deadline: params.swapTxContext.swapRequestArgs.deadline, + deadlineDate: params.swapTxContext.swapRequestArgs.deadline ? new Date(params.swapTxContext.swapRequestArgs.deadline * 1000).toLocaleString('zh-CN') : undefined, + hasQuote: !!params.swapTxContext.swapRequestArgs.quote, + simulateTransaction: params.swapTxContext.swapRequestArgs.simulateTransaction, + allKeys: Object.keys(params.swapTxContext.swapRequestArgs), + fullSwapRequestArgs: params.swapTxContext.swapRequestArgs, + } : 'swapRequestArgs is undefined', + swapTxContextKeys: params.swapTxContext ? Object.keys(params.swapTxContext) : [], + }) + } + // Mark execution as called to prevent future prepareAndSign calls signing.markExecutionCalled() From 4ed06555ad3f7d069b26ddc1467d18e0db674d28 Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Wed, 21 Jan 2026 18:44:01 +0800 Subject: [PATCH 14/33] feat: update quote --- apps/web/.env | 2 +- apps/web/public/csp.json | 1 + apps/web/src/state/routing/slice.ts | 1 + .../src/state/routing/useRoutingAPITrade.ts | 2 +- .../apiClients/tradingApi/TradingApiClient.ts | 49 ++++++++++++++----- 5 files changed, 41 insertions(+), 14 deletions(-) diff --git a/apps/web/.env b/apps/web/.env index 673b2b3eff9..2927a1aeeda 100644 --- a/apps/web/.env +++ b/apps/web/.env @@ -12,7 +12,7 @@ REACT_APP_STATSIG_API_KEY="statsig_api_key" REACT_APP_STATSIG_PROXY_URL="https://interface.gateway.uniswap.org/v1/statsig-proxy" REACT_APP_TEMP_API_URL="https://temp.gateway.uniswap.org/v1" REACT_APP_UNISWAP_BASE_API_URL="https://interface.gateway.uniswap.org" -REACT_APP_UNISWAP_GATEWAY_DNS=http://10.225.81.180:8888 +REACT_APP_UNISWAP_GATEWAY_DNS=https://zy95c64c3c.execute-api.ap-southeast-1.amazonaws.com/prod/v2 REACT_APP_WALLET_CONNECT_PROJECT_ID="c6c9bacd35afa3eb9e6cccf6d8464395" REACT_APP_TRADING_API_KEY= REACT_APP_IS_UNISWAP_INTERFACE=true diff --git a/apps/web/public/csp.json b/apps/web/public/csp.json index dcbe9efcefb..72b5ec8c177 100644 --- a/apps/web/public/csp.json +++ b/apps/web/public/csp.json @@ -118,6 +118,7 @@ "https://assetsconfigcdn.org", "https://prodregistryv2.org", "https://cloudflare-dns.com", + "https://zy95c64c3c.execute-api.ap-southeast-1.amazonaws.com", "https://beyondwickedmapping.org", "wss://*.uniswap.org", "wss://relay.walletconnect.com", diff --git a/apps/web/src/state/routing/slice.ts b/apps/web/src/state/routing/slice.ts index 5d51c36d8db..8e2ae3a82b8 100644 --- a/apps/web/src/state/routing/slice.ts +++ b/apps/web/src/state/routing/slice.ts @@ -138,6 +138,7 @@ export const routingApi = createApi({ url: `${UNISWAP_GATEWAY_DNS_URL}/quote`, body: JSON.stringify(requestBody), headers: { + 'content-type': 'application/json', 'x-request-source': REQUEST_SOURCE, }, }) diff --git a/apps/web/src/state/routing/useRoutingAPITrade.ts b/apps/web/src/state/routing/useRoutingAPITrade.ts index f6d534802b4..8ef26296c49 100644 --- a/apps/web/src/state/routing/useRoutingAPITrade.ts +++ b/apps/web/src/state/routing/useRoutingAPITrade.ts @@ -100,7 +100,7 @@ export function useRoutingAPITrade( const { isError, data: tradeResult, error, currentData } = useGetQuoteQueryState(queryArgs) useGetQuoteQuery(skipFetch || !isWindowVisible ? skipToken : queryArgs, { // Price-fetching is informational and costly, so it's done less frequently. - pollingInterval: routerPreference === INTERNAL_ROUTER_PREFERENCE_PRICE ? ms(`1m`) : AVERAGE_L1_BLOCK_TIME_MS, + pollingInterval: routerPreference === INTERNAL_ROUTER_PREFERENCE_PRICE ? ms(`1m`) : ms(`10s`), // If latest quote from cache was fetched > 2m ago, instantly repoll for another instead of waiting for next poll period refetchOnMountOrArgChange: 2 * 60, }) diff --git a/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts b/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts index b484b448205..1714ced6ed2 100644 --- a/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts +++ b/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts @@ -80,8 +80,15 @@ export const getFeatureFlaggedHeaders = ( } const uniquoteEnabled = getFeatureFlag(FeatureFlags.UniquoteEnabled) const viemProviderEnabled = getFeatureFlag(FeatureFlags.ViemProviderEnabled) - addHeaderIfEnabled({ headers, key: TradingApiHeaders.UniquoteEnabled, enabled: uniquoteEnabled }) - addHeaderIfEnabled({ headers, key: TradingApiHeaders.ViemProviderEnabled, enabled: viemProviderEnabled }) + // Avoid custom headers on /quote until API Gateway CORS allowlist is updated. + // TODO: Re-enable /quote headers once CORS allowlist includes them. + if (tradingApiPath !== TRADING_API_PATHS.quote) { + addHeaderIfEnabled({ headers, key: TradingApiHeaders.UniquoteEnabled, enabled: uniquoteEnabled }) + addHeaderIfEnabled({ headers, key: TradingApiHeaders.ViemProviderEnabled, enabled: viemProviderEnabled }) + } else { + // addHeaderIfEnabled({ headers, key: TradingApiHeaders.UniquoteEnabled, enabled: uniquoteEnabled }) + // addHeaderIfEnabled({ headers, key: TradingApiHeaders.ViemProviderEnabled, enabled: viemProviderEnabled }) + } const chainedActionsEnabled = getFeatureFlag(FeatureFlags.ChainedActions) const unirouteEnabled = getFeatureFlag(FeatureFlags.UnirouteEnabled) @@ -89,14 +96,17 @@ export const getFeatureFlaggedHeaders = ( const disableUniswapInterfaceFees = getFeatureFlag(FeatureFlags.NoUniswapInterfaceFees) switch (tradingApiPath) { case TRADING_API_PATHS.quote: - addHeaderIfEnabled({ headers, key: TradingApiHeaders.UnirouteEnabled, enabled: unirouteEnabled }) - addHeaderIfEnabled({ headers, key: TradingApiHeaders.Erc20EthEnabled, enabled: ethAsErc20UniswapXEnabled }) - addHeaderIfEnabled({ headers, key: TradingApiHeaders.ChainedActionsEnabled, enabled: chainedActionsEnabled }) - addHeaderIfEnabled({ - headers, - key: TradingApiHeaders.DisableUniswapInterfaceFees, - enabled: disableUniswapInterfaceFees, - }) + // Temporarily skip headers blocked by API Gateway CORS allowlist. + // TODO: Re-enable /quote headers once CORS allowlist includes them. + // Server should add: x-uniquote-enabled, x-disable-uniswap-interface-fees. + // addHeaderIfEnabled({ headers, key: TradingApiHeaders.UnirouteEnabled, enabled: unirouteEnabled }) + // addHeaderIfEnabled({ headers, key: TradingApiHeaders.Erc20EthEnabled, enabled: ethAsErc20UniswapXEnabled }) + // addHeaderIfEnabled({ headers, key: TradingApiHeaders.ChainedActionsEnabled, enabled: chainedActionsEnabled }) + // addHeaderIfEnabled({ + // headers, + // key: TradingApiHeaders.DisableUniswapInterfaceFees, + // enabled: disableUniswapInterfaceFees, + // }) break case TRADING_API_PATHS.plan: addHeaderIfEnabled({ headers, key: TradingApiHeaders.ChainedActionsEnabled, enabled: chainedActionsEnabled }) @@ -141,8 +151,23 @@ type IndicativeQuoteRequest = Pick< 'type' | 'amount' | 'tokenInChainId' | 'tokenOutChainId' | 'tokenIn' | 'tokenOut' | 'swapper' > -// Build the quote URL path - ensure it starts with / if prefix is empty -const quoteUrlPath = tradingApiVersionPrefix +// Build the quote URL path. +// If the override base already includes a version segment (e.g. /prod/v2), do not append /v1. +const shouldUseVersionPrefix = (() => { + if (!quoteApiBaseUrl) { + return true + } + try { + const url = new URL(quoteApiBaseUrl) + const path = url.pathname.replace(/\/+$/, '') + return !path.endsWith('/v2') + } catch { + // If it's not a valid URL, fall back to previous behavior. + return true + } +})() + +const quoteUrlPath = shouldUseVersionPrefix ? `${tradingApiVersionPrefix}/${TRADING_API_PATHS.quote}` : `/${TRADING_API_PATHS.quote}` From 42f5be2d592fc7aaff557dad05232fb565ee14af Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Thu, 22 Jan 2026 13:35:08 +0800 Subject: [PATCH 15/33] feat: update inner net --- apps/web/src/hooks/useHSKSubgraphPools.ts | 13 ++---- apps/web/src/polyfills.ts | 30 +++++++++++++ apps/web/vite.config.mts | 9 ++++ .../hooks/useHSKSubgraphPoolsForSelector.ts | 8 ++-- packages/uniswap/src/constants/subgraphUrl.ts | 42 +++++++++++++++++++ 5 files changed, 87 insertions(+), 15 deletions(-) create mode 100644 packages/uniswap/src/constants/subgraphUrl.ts diff --git a/apps/web/src/hooks/useHSKSubgraphPools.ts b/apps/web/src/hooks/useHSKSubgraphPools.ts index 5ccada3bad6..167eff74fff 100644 --- a/apps/web/src/hooks/useHSKSubgraphPools.ts +++ b/apps/web/src/hooks/useHSKSubgraphPools.ts @@ -5,19 +5,12 @@ import { GraphQLApi } from '@universe/api' import { PoolStat } from 'state/explore/types' import { BIPS_BASE } from 'uniswap/src/constants/misc' import { DEFAULT_TICK_SPACING } from 'uniswap/src/constants/pools' +import { getHSKSubgraphUrl } from 'uniswap/src/constants/subgraphUrl' import { UniverseChainId } from 'uniswap/src/features/chains/types' import { toGraphQLChain } from 'uniswap/src/features/chains/utils' -// 使用代理 URL 避免 CORS 问题 -// 开发环境:使用 Vite 代理(localhost) -// 生产环境:如果 subgraph 服务器配置了 CORS,可以直接使用;否则需要通过后端代理 -// 注意:如果生产环境出现 CORS 错误,需要: -// 1. 让 subgraph 服务器配置 CORS 头(推荐) -// 2. 或者通过后端 API 转发请求 -const SUBGRAPH_URL = - typeof window !== 'undefined' && window.location.hostname === 'localhost' - ? '/hsk-subgraph' // 开发环境:使用 Vite 代理 - : 'https://graphnode-testnet.hashkeychain.net/subgraphs/name/uniswap-v3/hsk-test' // 生产环境:直接请求(需要服务器配置 CORS) +// 使用统一的 subgraph URL 获取函数,支持环境变量和内网访问 +const SUBGRAPH_URL = getHSKSubgraphUrl() const BEARER_TOKEN = '' interface SubgraphPool { diff --git a/apps/web/src/polyfills.ts b/apps/web/src/polyfills.ts index bbedb9d0e5c..14fa79a4f0a 100644 --- a/apps/web/src/polyfills.ts +++ b/apps/web/src/polyfills.ts @@ -26,3 +26,33 @@ if (!window.Buffer) { if (!window.ResizeObserver) { window.ResizeObserver = ResizeObserver } + +// Polyfill for crypto.randomUUID if not available +// This is needed for environments that don't support crypto.randomUUID (e.g., older Node.js versions, some browsers) +const cryptoObj = typeof crypto !== 'undefined' ? crypto : typeof window !== 'undefined' ? window.crypto : undefined +if (cryptoObj && !cryptoObj.randomUUID) { + cryptoObj.randomUUID = function randomUUID(): string { + // Generate a UUID v4 using crypto.getRandomValues + // Format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx + const bytes = new Uint8Array(16) + cryptoObj.getRandomValues(bytes) + + // Set version (4) and variant bits + bytes[6] = (bytes[6] & 0x0f) | 0x40 // Version 4 + bytes[8] = (bytes[8] & 0x3f) | 0x80 // Variant 10 + + // Convert to hex string + const hex = Array.from(bytes) + .map((byte) => byte.toString(16).padStart(2, '0')) + .join('') + + // Format as UUID: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx + return [ + hex.slice(0, 8), + hex.slice(8, 12), + hex.slice(12, 16), + hex.slice(16, 20), + hex.slice(20, 32), + ].join('-') + } +} diff --git a/apps/web/vite.config.mts b/apps/web/vite.config.mts index b30dbb02665..c9b030b4866 100644 --- a/apps/web/vite.config.mts +++ b/apps/web/vite.config.mts @@ -347,6 +347,15 @@ export default defineConfig(({ mode }) => { server: { port: DEFAULT_PORT, + host: '0.0.0.0', + allowedHosts: 'all', + hmr: { + host: '10.225.81.22', + port: 8888, + clientPort: 8888, + protocol: 'ws', + }, + strictPort: false, // 如果端口被占用,自动尝试下一个可用端口 proxy: { ...(ENABLE_PROXY ? { '/entry-gateway': createEntryGatewayProxy({ getLogger }) diff --git a/packages/uniswap/src/components/TokenSelector/hooks/useHSKSubgraphPoolsForSelector.ts b/packages/uniswap/src/components/TokenSelector/hooks/useHSKSubgraphPoolsForSelector.ts index 61a023e295c..b88980245fa 100644 --- a/packages/uniswap/src/components/TokenSelector/hooks/useHSKSubgraphPoolsForSelector.ts +++ b/packages/uniswap/src/components/TokenSelector/hooks/useHSKSubgraphPoolsForSelector.ts @@ -1,12 +1,10 @@ import { useQuery } from '@tanstack/react-query' +import { getHSKSubgraphUrl } from 'uniswap/src/constants/subgraphUrl' import { UniverseChainId } from 'uniswap/src/features/chains/types' import { toGraphQLChain } from 'uniswap/src/features/chains/utils' -// 使用代理 URL 避免 CORS 问题 -const SUBGRAPH_URL = - typeof window !== 'undefined' && window.location.hostname === 'localhost' - ? '/hsk-subgraph' // 开发环境:使用 Vite 代理 - : 'https://graphnode-testnet.hashkeychain.net/subgraphs/name/uniswap-v3/hsk-test' // 生产环境:直接请求 +// 使用统一的 subgraph URL 获取函数,支持环境变量和内网访问 +const SUBGRAPH_URL = getHSKSubgraphUrl() interface SubgraphPool { id: string diff --git a/packages/uniswap/src/constants/subgraphUrl.ts b/packages/uniswap/src/constants/subgraphUrl.ts new file mode 100644 index 00000000000..2d19ed3a4b9 --- /dev/null +++ b/packages/uniswap/src/constants/subgraphUrl.ts @@ -0,0 +1,42 @@ +/** + * 获取 HSK Subgraph URL + * + * 优先级: + * 1. 环境变量 REACT_APP_HSK_SUBGRAPH_URL 或 VITE_HSK_SUBGRAPH_URL + * 2. 开发环境(localhost 或内网 IP):使用 Vite 代理路径 + * 3. 默认生产环境 URL + * + * @returns subgraph URL + */ +export function getHSKSubgraphUrl(): string { + // 优先使用环境变量 + const envUrl = + (typeof process !== 'undefined' && process.env?.REACT_APP_HSK_SUBGRAPH_URL) || + (typeof process !== 'undefined' && process.env?.VITE_HSK_SUBGRAPH_URL) || + (typeof import.meta !== 'undefined' && import.meta.env?.VITE_HSK_SUBGRAPH_URL) + + if (envUrl) { + return envUrl + } + + // 判断是否为开发环境(localhost 或内网 IP) + if (typeof window !== 'undefined') { + const hostname = window.location.hostname + const isLocalhost = hostname === 'localhost' || hostname === '127.0.0.1' + + // 判断是否为内网 IP(私有 IP 地址范围) + // 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12 + const isPrivateIP = + hostname.startsWith('192.168.') || + hostname.startsWith('10.') || + /^172\.(1[6-9]|2[0-9]|3[01])\./.test(hostname) + + // 开发环境或内网环境:使用 Vite 代理 + if (isLocalhost || isPrivateIP) { + return '/hsk-subgraph' + } + } + + // 默认生产环境 URL + return 'https://graphnode-testnet.hashkeychain.net/subgraphs/name/uniswap-v3/hsk-test' +} From 75ea0d3aa6657cdadc9efaf3d6393e895514bff9 Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Thu, 22 Jan 2026 17:09:57 +0800 Subject: [PATCH 16/33] fix : review fix --- apps/web/src/hooks/useHSKSubgraphPools.ts | 15 -- .../src/state/sagas/transactions/swapSaga.ts | 116 --------------- .../providers/webForNudgeProvider.tsx | 46 +++++- .../SwapFormButton/SwapFormButton.tsx | 15 -- .../hooks/useIsPortfolioZero.ts | 65 ++++++++- .../hooks/useOnChainPortfolioTotalValue.ts | 132 ++++++++++++++++++ .../hooks/useCreateSwapReviewCallbacks.tsx | 13 -- .../swap/review/hooks/useTokenApprovalInfo.ts | 49 +++++-- .../classic/classicSwapTxAndGasInfoService.ts | 25 ---- .../evm/evmSwapInstructionsService.ts | 17 --- .../swapTxAndGasInfoService/evm/utils.ts | 66 +-------- .../services/swapTxAndGasInfoService/utils.ts | 22 +-- .../swap/services/executeSwapService.ts | 81 ----------- .../swap/services/prepareSwapService.ts | 3 - .../hooks/useTransactionRequestInfo.ts | 10 -- .../swap/utils/getIsWebForNudgeEnabled.ts | 21 ++- packages/utilities/src/reactQuery/cache.ts | 1 + 17 files changed, 306 insertions(+), 391 deletions(-) create mode 100644 packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useOnChainPortfolioTotalValue.ts diff --git a/apps/web/src/hooks/useHSKSubgraphPools.ts b/apps/web/src/hooks/useHSKSubgraphPools.ts index 167eff74fff..c8e0c478928 100644 --- a/apps/web/src/hooks/useHSKSubgraphPools.ts +++ b/apps/web/src/hooks/useHSKSubgraphPools.ts @@ -181,26 +181,11 @@ export function useHSKSubgraphPools(first: number = 10) { return useQuery({ queryKey: ['hsk-subgraph-pools', first], queryFn: async () => { - console.log('[useHSKSubgraphPools] 开始查询 subgraph...') try { const data = await querySubgraph(TOP_POOLS_QUERY, { first }) - console.log('[useHSKSubgraphPools] 查询成功,原始 pools 数量:', data.pools.length) const converted = data.pools.map(convertSubgraphPoolToPoolStat) - console.log('[useHSKSubgraphPools] 转换后的 pools 数量:', converted.length) - console.log( - '[useHSKSubgraphPools] 转换后的第一个 pool:', - converted[0] - ? { - id: converted[0].id, - token0: converted[0].token0, - token1: converted[0].token1, - totalLiquidity: converted[0].totalLiquidity, - } - : null, - ) return converted } catch (error) { - console.error('[useHSKSubgraphPools] 查询失败:', error) throw error } }, diff --git a/apps/web/src/state/sagas/transactions/swapSaga.ts b/apps/web/src/state/sagas/transactions/swapSaga.ts index 5eb3d0d063e..b11ed959b5e 100644 --- a/apps/web/src/state/sagas/transactions/swapSaga.ts +++ b/apps/web/src/state/sagas/transactions/swapSaga.ts @@ -177,9 +177,6 @@ function patchMulticallRecipient(multicallData: string, recipientAddress: string return callData } catch (error) { - if (process.env.NODE_ENV === 'development') { - console.warn('[Swap] Failed to patch multicall call:', error) - } return callData } }) @@ -187,9 +184,6 @@ function patchMulticallRecipient(multicallData: string, recipientAddress: string // Re-encode multicall with patched calls return multicallIface.encodeFunctionData('multicall', [patchedCalls]) } catch (error) { - if (process.env.NODE_ENV === 'development') { - console.warn('[Swap] Failed to patch multicall recipient:', error) - } return multicallData } } @@ -224,16 +218,6 @@ function convertMulticallToExecute( const decoded = multicallIface.decodeFunctionData('multicall', multicallData) const calls = decoded[0] - // For now, log that we detected multicall but don't convert - // The proper solution is to ensure Trading API returns execute format, - // or rebuild using Universal Router SDK from the trade object - if (process.env.NODE_ENV === 'development') { - console.warn( - '[Swap] Received multicall calldata - conversion to execute not yet implemented. ' + - 'Consider using Universal Router SDK to rebuild from trade object.', - ) - } - // Return undefined to fall back to original data // TODO: Implement proper conversion using Universal Router SDK return undefined @@ -283,16 +267,8 @@ function fixUniversalRouterExecuteData({ // The total amount needed = sum of all amountIn values in all exactInput calls. // Universal Router requires direct ERC20 approval (not just Permit2 approval). const totalAmountIn = getTotalAmountInFromMulticall(normalized) - if (totalAmountIn && process.env.NODE_ENV === 'development') { - console.log( - `[Swap] Multicall total amountIn: ${totalAmountIn.toString()} (${totalAmountIn.toString() / BigInt(10 ** 18)} tokens)`, - ) - } const patched = patchMulticallRecipient(normalized, recipientAddress) if (patched !== normalized) { - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] Patched recipient address in multicall calldata') - } logger.info( 'swapSaga', 'fixUniversalRouterExecuteData', @@ -307,9 +283,6 @@ function fixUniversalRouterExecuteData({ return patched } // If no patching needed, return original multicall data - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] Using multicall calldata directly (Universal Router supports it)') - } logger.info( 'swapSaga', 'fixUniversalRouterExecuteData', @@ -359,23 +332,12 @@ function fixUniversalRouterExecuteData({ function* handleSwapTransactionStep(params: HandleSwapStepParams): SagaGenerator { const { trade, step, signature, analytics, onTransactionHash } = params - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] handleSwapTransactionStep: Starting', { - stepType: step.type, - hasStep: !!step, - hasSignature: !!signature, - }) - } - const info = getSwapTransactionInfo({ trade, isFinalStep: analytics.is_final_step, swapStartTimestamp: analytics.swap_start_timestamp, }) - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] handleSwapTransactionStep: Calling getSwapTxRequest') - } const txRequest = yield* call(getSwapTxRequest, step, signature) const deadlineSeconds = typeof (trade as any).deadline === 'number' ? (trade as any).deadline : undefined const recipientAddress = (params as HandleSwapStepParams & { address?: string }).address @@ -417,24 +379,6 @@ function* handleSwapTransactionStep(params: HandleSwapStepParams): SagaGenerator recipientAddress, }) - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] Calldata transformation:', { - originalSelector, - finalSelector, - wasModified, - deadlineSeconds, - recipientAddress, - }) - } - - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] handleSwapTransactionStep: Got txRequest:', { - hasTxRequest: !!txRequestFixed, - to: txRequestFixed?.to, - chainId: txRequestFixed?.chainId, - }) - } - const onModification = ({ hash, data }: VitalTxFields) => { sendAnalyticsEvent(SwapEventName.SwapModifiedInWallet, { ...analytics, @@ -447,13 +391,6 @@ function* handleSwapTransactionStep(params: HandleSwapStepParams): SagaGenerator // Now that we have the txRequest, we can create a definitive SwapTransactionStep, incase we started with an async step. const onChainStep = { ...step, txRequest: txRequestFixed } - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] handleSwapTransactionStep: About to call handleOnChainStep:', { - stepType: onChainStep.type, - hasTxRequest: !!onChainStep.txRequest, - }) - } - const hash = yield* call(handleOnChainStep, { ...params, info, @@ -464,10 +401,6 @@ function* handleSwapTransactionStep(params: HandleSwapStepParams): SagaGenerator allowDuplicativeTx: true, // Allow duplicate transactions for swap - user may want to submit multiple swaps }) - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] handleSwapTransactionStep: handleOnChainStep returned hash:', hash) - } - handleSwapTransactionAnalytics({ ...params, hash }) const chainId = trade.inputAmount.currency.chainId @@ -596,13 +529,6 @@ function* swap(params: SwapParams) { if (chainSwitchFailed) { const error = new Error(`Chain switch failed: unable to switch from chain ${params.startChainId} to chain ${swapChainId}`) - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: Chain switch failed', { - error: error.message, - startChainId: params.startChainId, - swapChainId, - }) - } const onPressRetry = params.getOnPressRetry(error) onFailure(error, onPressRetry) return @@ -623,43 +549,22 @@ function* swap(params: SwapParams) { } for (step of steps) { - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] swap saga: Processing step:', { - stepType: step.type, - stepIndex: steps.indexOf(step), - }) - } switch (step.type) { case TransactionStepType.TokenRevocationTransaction: case TransactionStepType.TokenApprovalTransaction: { - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] swap saga: Handling approval step') - } yield* call(handleApprovalTransactionStep, { address: account.address, step, setCurrentStep }) break } case TransactionStepType.Permit2Signature: { - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] swap saga: Handling permit signature step') - } signature = yield* call(handleSignatureStep, { address: account.address, step, setCurrentStep }) break } case TransactionStepType.Permit2Transaction: { - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] swap saga: Handling permit transaction step') - } yield* call(handlePermitTransactionStep, { address: account.address, step, setCurrentStep }) break } case TransactionStepType.SwapTransaction: case TransactionStepType.SwapTransactionAsync: { - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] swap saga: Handling swap transaction step:', { - stepType: step.type, - hasTxRequest: 'txRequest' in step && !!step.txRequest, - }) - } requireRouting(trade, [TradingApi.Routing.CLASSIC, TradingApi.Routing.BRIDGE]) yield* call(handleSwapTransactionStep, { address: account.address, @@ -699,20 +604,11 @@ function* swap(params: SwapParams) { if (displayableError) { logger.error(displayableError, { tags: { file: 'swapSaga', function: 'swap' } }) } - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] swap saga: Error occurred:', { - error: displayableError?.message || error instanceof Error ? error.message : String(error), - stepType: step?.type, - }) - } const onPressRetry = params.getOnPressRetry(displayableError) onFailure(displayableError, onPressRetry) return } - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] swap saga: All steps completed, calling onSuccess') - } yield* call(onSuccess) } @@ -738,18 +634,6 @@ export function useSwapCallback(): SwapCallback { return useCallback( (args: SwapCallbackParams) => { - if (process.env.NODE_ENV === 'development') { - const hasTxRequests = 'txRequests' in args.swapTxContext && Array.isArray(args.swapTxContext.txRequests) - const txRequestCount = - 'txRequests' in args.swapTxContext && Array.isArray(args.swapTxContext.txRequests) - ? args.swapTxContext.txRequests.length - : 0 - console.log('[Swap] swapCallback called', { - routing: args.swapTxContext.routing, - hasTxRequests, - txRequestCount, - }) - } const { swapTxContext, onSuccess, diff --git a/packages/uniswap/src/features/providers/webForNudgeProvider.tsx b/packages/uniswap/src/features/providers/webForNudgeProvider.tsx index 0051c83d2fd..353ee1596c6 100644 --- a/packages/uniswap/src/features/providers/webForNudgeProvider.tsx +++ b/packages/uniswap/src/features/providers/webForNudgeProvider.tsx @@ -45,7 +45,51 @@ export function useWebFORNudgeGateEnabled(): boolean { // If wallet can pay gas in any token (e.g., Porto wallet), don't show the nudge const canPayGasInAnyToken = getCanPayGasInAnyToken?.() ?? false - return isWebFORNudgeEnabled && isPortfolioZero && !canPayGasInAnyToken + const result = isWebFORNudgeEnabled && isPortfolioZero && !canPayGasInAnyToken + + // Debug logging for WebFORNudge condition 3: Can pay gas in any token + if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { + console.log('[review] WebFORNudge Condition 3 - canPayGasInAnyToken:', { + canPayGasInAnyToken, + explanation: { + parameter: '!canPayGasInAnyToken', + meaning: '检查钱包是否可以用任何代币支付 gas 费用。某些钱包(如 Porto 钱包)支持用任意代币支付 gas,这种情况下不需要引导用户购买原生代币,因此不显示 WebFORNudge。', + note: canPayGasInAnyToken + ? '钱包可以用任何代币支付 gas(如 Porto 钱包)- 不满足 WebFORNudge 条件,不需要引导购买原生代币' + : '钱包不能用任何代币支付 gas - 满足 WebFORNudge 条件,需要引导用户购买原生代币', + }, + }) + } + + // Debug logging for final WebFORNudge result + if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { + console.log('[review] WebFORNudge Final Result:', { + result, + conditions: { + condition1_getIsWebFORNudgeEnabled: isWebFORNudgeEnabled, + condition2_isPortfolioZero: isPortfolioZero, + condition3_notCanPayGasInAnyToken: !canPayGasInAnyToken, + }, + explanation: { + whatIsWebFORNudge: 'WebFORNudge = Web Fiat On Ramp Nudge(Web 法币入金提示)。当用户钱包为空时,显示 "Swap Tokens" 按钮和空钱包引导卡片,引导用户购买/接收代币。', + formula: 'isWebFORNudgeEnabled = condition1 && condition2 && condition3', + result: result + ? '✅ WebFORNudge 已启用 - 将显示 "Swap Tokens" 按钮' + : '❌ WebFORNudge 未启用 - 将显示 "Review" 按钮', + whyFalse: !result + ? `未启用的原因:${[ + !isWebFORNudgeEnabled && '条件1: Statsig 实验未启用', + !isPortfolioZero && '条件2: 投资组合余额不为 0', + canPayGasInAnyToken && '条件3: 钱包可以用任何代币支付 gas', + ] + .filter(Boolean) + .join(' 或 ')}` + : '所有条件都满足', + }, + }) + } + + return result } export function useIsWebFORNudgeEnabled(): boolean { diff --git a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx index a6f8531a6ef..61e4491bd99 100644 --- a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx +++ b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/SwapFormButton.tsx @@ -137,13 +137,6 @@ export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Ele // Create callbacks for swap execution const onSuccess = useCallback(() => { - if (process.env.NODE_ENV === 'development') { - console.log('[Swap Result] Swap succeeded!', { - chainId: derivedSwapInfo.chainId, - inputCurrency: derivedSwapInfo.currencies.input?.currency.symbol, - outputCurrency: derivedSwapInfo.currencies.output?.currency.symbol, - }) - } // For Unichain networks, trigger confirmation and branch to stall+fetch logic (ie handle in component) if (isFlashblocksEnabled && shouldShowConfirmedState) { updateSwapForm({ @@ -172,11 +165,6 @@ export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Ele const onFailure = useCallback( (error?: Error) => { - if (process.env.NODE_ENV === 'development') { - console.log('[Swap Result] Swap failed:', { - error: error?.message || 'Unknown error', - }) - } updateSwapForm({ isSubmitting: false, isConfirmed: false, showPendingUI: false }) }, [updateSwapForm], @@ -267,9 +255,6 @@ export function SwapFormButton({ tokenColor }: { tokenColor?: string }): JSX.Ele }) const handleConfirmSwap = useEvent(() => { - if (process.env.NODE_ENV === 'development') { - console.log('swap tokens now') - } setIsSwapConfirmationModalOpen(false) // Use prepareSwapDirectly which will execute swap directly if no warnings // If there are warnings, they will be shown, otherwise swap will execute diff --git a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsPortfolioZero.ts b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsPortfolioZero.ts index 8d4d60fa9ed..9b0f2baf308 100644 --- a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsPortfolioZero.ts +++ b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsPortfolioZero.ts @@ -1,14 +1,73 @@ import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' -import { usePortfolioTotalValue } from 'uniswap/src/features/dataApi/balances/balancesRest' import { useWallet } from 'uniswap/src/features/wallet/hooks/useWallet' +import { useOnChainPortfolioTotalValue } from 'uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useOnChainPortfolioTotalValue' export function useIsPortfolioZero(): boolean { const wallet = useWallet() const { isTestnetModeEnabled } = useEnabledChains() - const { data } = usePortfolioTotalValue({ + // 使用链上查询替代 Uniswap GetPortfolio API + const { balanceUSD, loading, error } = useOnChainPortfolioTotalValue({ evmAddress: wallet.evmAccount?.address, svmAddress: wallet.svmAccount?.address, }) - return !isTestnetModeEnabled && data?.balanceUSD === 0 + const result = !isTestnetModeEnabled && balanceUSD === 0 + + // Debug logging for WebFORNudge condition 2: Portfolio zero + if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { + // Log immediately when loading state changes + if (loading) { + console.log('[review] WebFORNudge Condition 2 - useIsPortfolioZero: 链上查询中...', { + loading: true, + currentBalanceUSD: balanceUSD, + environment: { + hostname: window.location.hostname, + origin: window.location.origin, + port: window.location.port, + }, + }) + } + + // Log when loading completes (either success or error) + if (!loading) { + console.log('[review] WebFORNudge Condition 2 - useIsPortfolioZero: 链上查询完成', { + result, + isTestnetModeEnabled, + balanceUSD, + loading: false, + error: error ? String(error) : undefined, + errorDetails: error + ? { + message: error.message, + name: error.name, + stack: error.stack?.substring(0, 200), + } + : undefined, + walletAddresses: { + evmAddress: wallet.evmAccount?.address, + svmAddress: wallet.svmAccount?.address, + }, + environment: { + hostname: window.location.hostname, + origin: window.location.origin, + port: window.location.port, + protocol: window.location.protocol, + href: window.location.href, + }, + explanation: { + parameter: 'isPortfolioZero', + meaning: '检查投资组合余额是否为 0。使用链上查询替代 Uniswap GetPortfolio API,查询所有启用链的原生代币余额。', + calculation: '!isTestnetModeEnabled && balanceUSD === 0', + note: result + ? '投资组合余额为 0 - 满足 WebFORNudge 条件(所有链的原生代币余额都为 0)' + : error + ? `链上查询失败: ${String(error)}` + : `投资组合余额不为 0 (检测到非零余额) 或处于测试网模式 - 不满足 WebFORNudge 条件`, + implementation: '使用链上直接查询,不依赖 Uniswap API,避免 CORS 问题', + }, + }) + } + } + + return result } diff --git a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useOnChainPortfolioTotalValue.ts b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useOnChainPortfolioTotalValue.ts new file mode 100644 index 00000000000..d4f01fdf264 --- /dev/null +++ b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useOnChainPortfolioTotalValue.ts @@ -0,0 +1,132 @@ +import { useQuery } from '@tanstack/react-query' +import { useMemo } from 'react' +import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' +import { filterChainIdsByPlatform } from 'uniswap/src/features/chains/utils' +import { Platform } from 'uniswap/src/features/platforms/types/Platform' +import { createEthersProvider } from 'uniswap/src/features/providers/createEthersProvider' +import { getSolanaConnection } from 'uniswap/src/features/providers/getSolanaConnection' +import { SOLANA_ONCHAIN_BALANCE_COMMITMENT } from 'uniswap/src/data/solanaConnection/getSolanaParsedTokenAccountsByOwnerQueryOptions' +import { PublicKey } from '@solana/web3.js' +import { ReactQueryCacheKey } from 'utilities/src/reactQuery/cache' +import { logger } from 'utilities/src/logger/logger' +import type { Address } from 'utilities/src/addresses/types' + +interface OnChainPortfolioTotalValueResult { + balanceUSD: number + loading: boolean + error: Error | undefined +} + +/** + * 使用链上查询获取投资组合总价值(USD) + * 替代 Uniswap GetPortfolio API,避免 CORS 问题和外部依赖 + * + * 当前实现:查询所有启用链的原生代币余额 + * 如果所有链的原生代币余额都为 0,则认为投资组合为 0 + */ +export function useOnChainPortfolioTotalValue({ + evmAddress, + svmAddress, +}: { + evmAddress?: Address + svmAddress?: Address +}): OnChainPortfolioTotalValueResult { + const { chains: enabledChainIds, isTestnetModeEnabled } = useEnabledChains() + + // 过滤出 EVM 和 SVM 链 + const evmChainIds = useMemo( + () => filterChainIdsByPlatform(enabledChainIds, Platform.EVM), + [enabledChainIds] + ) + const svmChainIds = useMemo( + () => filterChainIdsByPlatform(enabledChainIds, Platform.SVM), + [enabledChainIds] + ) + + // 查询所有链的原生代币余额 + const { data, isLoading, error } = useQuery({ + queryKey: [ + ReactQueryCacheKey.OnchainPortfolioTotalValue, + evmAddress, + svmAddress, + evmChainIds, + svmChainIds, + isTestnetModeEnabled, + ], + queryFn: async (): Promise<{ balanceUSD: number; hasAnyBalance: boolean }> => { + if (!evmAddress && !svmAddress) { + return { balanceUSD: 0, hasAnyBalance: false } + } + + // 并行查询所有 EVM 链的原生代币余额 + const evmBalancePromises = evmChainIds.map(async (chainId): Promise => { + if (!evmAddress) return BigInt(0) + + try { + const provider = createEthersProvider({ chainId }) + if (!provider) { + return BigInt(0) + } + const balance = await provider.getBalance(evmAddress) + return BigInt(balance.toString()) + } catch (error) { + logger.warn('useOnChainPortfolioTotalValue', 'queryFn', `Failed to fetch balance for chain ${chainId}`, { + error, + chainId, + address: evmAddress, + }) + return BigInt(0) + } + }) + + // 并行查询所有 SVM 链的原生代币余额 + const svmBalancePromises = svmChainIds.map(async (chainId): Promise => { + if (!svmAddress) return BigInt(0) + + try { + const connection = getSolanaConnection() + if (!connection) { + return BigInt(0) + } + const balance = await connection.getBalance(new PublicKey(svmAddress), SOLANA_ONCHAIN_BALANCE_COMMITMENT) + return BigInt(balance.toString()) + } catch (error) { + logger.warn('useOnChainPortfolioTotalValue', 'queryFn', `Failed to fetch balance for chain ${chainId}`, { + error, + chainId, + address: svmAddress, + }) + return BigInt(0) + } + }) + + // 等待所有查询完成 + const [evmBalances, svmBalances] = await Promise.all([ + Promise.all(evmBalancePromises), + Promise.all(svmBalancePromises), + ]) + + // 检查是否有任何非零余额 + const allBalances = [...evmBalances, ...svmBalances] + const hasAnyBalance = allBalances.some((balance) => balance > BigInt(0)) + + // 如果测试网模式启用,或者有任何余额,返回非零值 + // 否则返回 0(表示投资组合为空) + const balanceUSD = isTestnetModeEnabled || hasAnyBalance ? 1 : 0 + + return { balanceUSD, hasAnyBalance } + }, + enabled: !!(evmAddress || svmAddress) && (evmChainIds.length > 0 || svmChainIds.length > 0), + staleTime: 30 * 1000, // 30 秒 + refetchInterval: 60 * 1000, // 60 秒刷新一次 + }) + + return useMemo( + () => ({ + balanceUSD: data?.balanceUSD ?? 0, + loading: isLoading, + error: error instanceof Error ? error : error ? new Error(String(error)) : undefined, + }), + [data?.balanceUSD, isLoading, error] + ) +} diff --git a/packages/uniswap/src/features/transactions/swap/review/hooks/useCreateSwapReviewCallbacks.tsx b/packages/uniswap/src/features/transactions/swap/review/hooks/useCreateSwapReviewCallbacks.tsx index 85222e0600e..35cec8fe86a 100644 --- a/packages/uniswap/src/features/transactions/swap/review/hooks/useCreateSwapReviewCallbacks.tsx +++ b/packages/uniswap/src/features/transactions/swap/review/hooks/useCreateSwapReviewCallbacks.tsx @@ -86,12 +86,6 @@ export function useCreateSwapReviewCallbacks(ctx: { const onFailure = useCallback( (error?: Error, onPressRetry?: () => void) => { - if (process.env.NODE_ENV === 'development') { - console.log('[Swap Result] Swap failed:', { - error: error?.message || 'Unknown error', - errorDetails: error, - }) - } resetCurrentStep() // Create a new txId for the next transaction, as the existing one may be used in state to track the failed submission. @@ -105,13 +99,6 @@ export function useCreateSwapReviewCallbacks(ctx: { ) const onSuccess = useCallback(() => { - if (process.env.NODE_ENV === 'development') { - console.log('[Swap Result] Swap succeeded!', { - chainId: derivedSwapInfo.chainId, - inputCurrency: derivedSwapInfo.currencies.input?.currency.symbol, - outputCurrency: derivedSwapInfo.currencies.output?.currency.symbol, - }) - } // For Unichain networks, trigger confirmation and branch to stall+fetch logic (ie handle in component) if (isFlashblocksEnabled && shouldShowConfirmedState) { resetCurrentStep() diff --git a/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.ts b/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.ts index 9dd43a499b3..cf1ea54af07 100644 --- a/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.ts +++ b/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.ts @@ -112,6 +112,34 @@ export function useTokenApprovalInfo(params: TokenApprovalInfoParams): ApprovalT immediateGcTime: ONE_MINUTE_MS, }) + // Debug logging for allowance check + if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { + if (!isLoading && (data !== undefined || error)) { + console.log('[allowance] useTokenApprovalInfo check result:', { + shouldSkip, + skipReasons: { + noApprovalRequestArgs: !approvalRequestArgs, + isWrap, + noAddress: !address, + approvalWillBeBatchedWithSwap, + isChained, + }, + approvalWillBeBatchedWithSwap, + chainId, + routing, + data: data ? { approval: data.approval !== null, hasCancel: !!data.cancel } : undefined, + error: error ? String(error) : undefined, + approvalRequestArgs: approvalRequestArgs + ? { + token: approvalRequestArgs.token, + amount: approvalRequestArgs.amount, + chainId: approvalRequestArgs.chainId, + } + : undefined, + }) + } + } + const tokenApprovalInfo: TokenApprovalInfo = useMemo(() => { if (error) { logger.error(error, { @@ -120,6 +148,17 @@ export function useTokenApprovalInfo(params: TokenApprovalInfoParams): ApprovalT approvalRequestArgs, }, }) + + // Debug: Log error details + if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { + console.error('[allowance] API error - returning ApprovalAction.Unknown:', { + error: String(error), + errorType: error?.constructor?.name, + errorMessage: error instanceof Error ? error.message : String(error), + approvalRequestArgs, + willBlockTransaction: true, + }) + } } // Approval is N/A for wrap transactions or unconnected state. @@ -132,16 +171,6 @@ export function useTokenApprovalInfo(params: TokenApprovalInfoParams): ApprovalT } if (data && !error) { - if (process.env.NODE_ENV === 'development' && isHashKeyChain) { - console.log('[approval debug][HashKey] checkApproval result', { - approvalRequestArgs, - data, - hasApproval: !!data.approval, - hasCancel: !!data.cancel, - gasFee: data.gasFee, - cancelGasFee: data.cancelGasFee, - }) - } // API returns null if no approval is required diff --git a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/classic/classicSwapTxAndGasInfoService.ts b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/classic/classicSwapTxAndGasInfoService.ts index 8a81e073ca9..1c1e375d5f1 100644 --- a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/classic/classicSwapTxAndGasInfoService.ts +++ b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/classic/classicSwapTxAndGasInfoService.ts @@ -19,33 +19,8 @@ export function createClassicSwapTxAndGasInfoService(ctx: { const service: SwapTxAndGasInfoService = { async getSwapTxAndGasInfo(params) { - if (process.env.NODE_ENV === 'development') { - console.log('[execute] classicSwapTxAndGasInfoService.getSwapTxAndGasInfo called:', { - hasTrade: !!params.trade, - routing: params.trade?.routing, - hasApprovalTxInfo: !!params.approvalTxInfo, - hasDerivedSwapInfo: !!params.derivedSwapInfo, - }) - } - const swapTxInfo = await getEVMSwapTransactionRequestInfo(params) - if (process.env.NODE_ENV === 'development') { - console.log('[execute] classicSwapTxAndGasInfoService - Got swapTxInfo:', { - hasSwapTxInfo: !!swapTxInfo, - hasSwapRequestArgs: !!swapTxInfo.swapRequestArgs, - swapRequestArgs: swapTxInfo.swapRequestArgs ? { - deadline: swapTxInfo.swapRequestArgs.deadline, - deadlineDate: swapTxInfo.swapRequestArgs.deadline ? new Date(swapTxInfo.swapRequestArgs.deadline * 1000).toLocaleString('zh-CN') : undefined, - hasQuote: !!swapTxInfo.swapRequestArgs.quote, - simulateTransaction: swapTxInfo.swapRequestArgs.simulateTransaction, - allKeys: Object.keys(swapTxInfo.swapRequestArgs), - } : 'swapRequestArgs is undefined', - hasTxRequests: !!swapTxInfo.txRequests, - txRequestCount: swapTxInfo.txRequests?.length || 0, - }) - } - const permitTxInfo = getPermitTxInfo(params.trade) return getClassicSwapTxAndGasInfo({ ...params, swapTxInfo, permitTxInfo }) diff --git a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/evmSwapInstructionsService.ts b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/evmSwapInstructionsService.ts index e8b1c4b5bf4..751bcb65721 100644 --- a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/evmSwapInstructionsService.ts +++ b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/evmSwapInstructionsService.ts @@ -69,15 +69,6 @@ function createLegacyEVMSwapInstructionsService( alreadyApproved, }) - if (process.env.NODE_ENV === 'development') { - console.log('[execute] createLegacyEVMSwapInstructionsService - Prepared swapRequestParams:', { - deadline: swapRequestParams.deadline, - deadlineDate: swapRequestParams.deadline ? new Date(swapRequestParams.deadline * 1000).toLocaleString('zh-CN') : undefined, - hasQuote: !!swapRequestParams.quote, - simulateTransaction: swapRequestParams.simulateTransaction, - }) - } - if (signatureMissing) { return { response: null, unsignedPermit: permitData, swapRequestParams } } @@ -110,14 +101,6 @@ function createBatchedEVMSwapInstructionsService( overrideSimulation: true, // always simulate for batched transactions }) - if (process.env.NODE_ENV === 'development') { - console.log('[execute] createBatchedEVMSwapInstructionsService - Prepared swapRequestParams:', { - deadline: swapRequestParams.deadline, - deadlineDate: swapRequestParams.deadline ? new Date(swapRequestParams.deadline * 1000).toLocaleString('zh-CN') : undefined, - hasQuote: !!swapRequestParams.quote, - simulateTransaction: swapRequestParams.simulateTransaction, - }) - } const response = await swapRepository.fetchSwapData(swapRequestParams) // Keep swapRequestParams even when we have a response, so deadline is preserved in swapTxContext diff --git a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/utils.ts b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/utils.ts index 218bb9ee597..6926c309e67 100644 --- a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/utils.ts +++ b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/utils.ts @@ -49,13 +49,13 @@ export function createGetEVMSwapTransactionRequestInfo(ctx: { const skip = getSwapInputExceedsBalance({ derivedSwapInfo }) || approvalUnknown - if (process.env.NODE_ENV === 'development') { - console.log('[execute] createGetEVMSwapTransactionRequestInfo - Before getSwapInstructions:', { - skip, + // Debug logging for approval unknown case + if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development' && approvalUnknown) { + console.warn('[allowance] ApprovalAction.Unknown - skipping swap instructions:', { approvalAction, - approvalUnknown, - inputExceedsBalance: getSwapInputExceedsBalance({ derivedSwapInfo }), - hasInstructionService: !!instructionService, + skip, + balanceExceeds: getSwapInputExceedsBalance({ derivedSwapInfo }), + note: 'This should block the transaction, but swapRequestParams will still be prepared', }) } @@ -68,55 +68,13 @@ export function createGetEVMSwapTransactionRequestInfo(ctx: { alreadyApproved, }) - if (process.env.NODE_ENV === 'development') { - console.log('[execute] createGetEVMSwapTransactionRequestInfo - Prepared swapRequestParams:', { - deadline: swapRequestParams.deadline, - deadlineDate: swapRequestParams.deadline ? new Date(swapRequestParams.deadline * 1000).toLocaleString('zh-CN') : undefined, - hasQuote: !!swapRequestParams.quote, - simulateTransaction: swapRequestParams.simulateTransaction, - }) - } - const { data, error } = await tryCatch( skip ? Promise.resolve(undefined) : instructionService.getSwapInstructions({ swapQuoteResponse, transactionSettings, approvalAction }), ) - if (process.env.NODE_ENV === 'development') { - console.log('[execute] createGetEVMSwapTransactionRequestInfo - After getSwapInstructions:', { - hasData: !!data, - data: data ? { - hasResponse: !!data.response, - hasUnsignedPermit: !!data.unsignedPermit, - hasSwapRequestParams: !!data.swapRequestParams, - swapRequestParams: data.swapRequestParams ? { - deadline: data.swapRequestParams.deadline, - deadlineDate: data.swapRequestParams.deadline ? new Date(data.swapRequestParams.deadline * 1000).toLocaleString('zh-CN') : undefined, - hasQuote: !!data.swapRequestParams.quote, - simulateTransaction: data.swapRequestParams.simulateTransaction, - } : 'swapRequestParams is undefined', - } : 'data is undefined', - hasError: !!error, - error: error?.message, - }) - } - const isRevokeNeeded = tokenApprovalInfo.action === ApprovalAction.RevokeAndPermit2Approve - - if (process.env.NODE_ENV === 'development') { - console.log('[execute] createGetEVMSwapTransactionRequestInfo - Before processSwapResponse:', { - hasResponse: !!data?.response, - hasSwapRequestParams: !!data?.swapRequestParams, - swapRequestParams: data?.swapRequestParams ? { - deadline: data.swapRequestParams.deadline, - deadlineDate: data.swapRequestParams.deadline ? new Date(data.swapRequestParams.deadline * 1000).toLocaleString('zh-CN') : undefined, - hasQuote: !!data.swapRequestParams.quote, - simulateTransaction: data.swapRequestParams.simulateTransaction, - } : 'swapRequestParams is undefined', - hasUnsignedPermit: !!data?.unsignedPermit, - }) - } // Use swapRequestParams from data if available, otherwise use the one we prepared const finalSwapRequestParams = data?.swapRequestParams ?? swapRequestParams @@ -132,18 +90,6 @@ export function createGetEVMSwapTransactionRequestInfo(ctx: { swapRequestParams: finalSwapRequestParams, }) - if (process.env.NODE_ENV === 'development') { - console.log('[execute] createGetEVMSwapTransactionRequestInfo - After processSwapResponse:', { - hasSwapRequestArgs: !!swapTxInfo.swapRequestArgs, - swapRequestArgs: swapTxInfo.swapRequestArgs ? { - deadline: swapTxInfo.swapRequestArgs.deadline, - deadlineDate: swapTxInfo.swapRequestArgs.deadline ? new Date(swapTxInfo.swapRequestArgs.deadline * 1000).toLocaleString('zh-CN') : undefined, - hasQuote: !!swapTxInfo.swapRequestArgs.quote, - simulateTransaction: swapTxInfo.swapRequestArgs.simulateTransaction, - } : 'swapRequestArgs is undefined', - }) - } - return swapTxInfo } diff --git a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts index 4f19c36cce7..25407564d92 100644 --- a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts +++ b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts @@ -512,27 +512,7 @@ export function createProcessSwapResponse({ gasStrategy }: { gasStrategy: GasStr } else if (finalChainId && swapQuote) { txRequests = buildTxRequestFromQuote(swapQuote, finalChainId) if (!txRequests) { - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: Failed to build transaction requests from quote', { - chainId: finalChainId, - originalChainId: chainId, - hasSwapQuote: !!swapQuote, - hasMethodParameters: !!(swapQuote as any)?.methodParameters, - methodParameters: (() => { - const methodParams = (swapQuote as any)?.methodParameters - if (methodParams) { - return { - hasCalldata: !!methodParams.calldata, - hasValue: !!methodParams.value, - calldata: methodParams.calldata?.substring(0, 20) + '...', - } - } - return undefined - })(), - // This error means swap cannot proceed - txRequests is required - willCauseValidationFailure: true, - }) - } + // This error means swap cannot proceed - txRequests is required } } else { // This should not happen if finalChainId fallback is working correctly diff --git a/packages/uniswap/src/features/transactions/swap/services/executeSwapService.ts b/packages/uniswap/src/features/transactions/swap/services/executeSwapService.ts index 1a7c358afb8..a8b9951857b 100644 --- a/packages/uniswap/src/features/transactions/swap/services/executeSwapService.ts +++ b/packages/uniswap/src/features/transactions/swap/services/executeSwapService.ts @@ -49,40 +49,6 @@ export function createExecuteSwapService(ctx: { const swapTxContext = ctx.getSwapTxContext?.() const account = ctx.getAccount?.() - if (process.env.NODE_ENV === 'development') { - console.log('[execute] executeSwapService executeSwap called:', { - account: account ? { - address: account.address, - chainId: account.chainId, - accountType: account.accountType, - } : undefined, - swapTxContext: swapTxContext ? { - routing: swapTxContext.routing, - hasTxRequests: !!swapTxContext.txRequests, - txRequestCount: swapTxContext.txRequests?.length || 0, - hasTrade: !!swapTxContext.trade, - includesDelegation: swapTxContext.includesDelegation, - hasSwapRequestArgs: 'swapRequestArgs' in swapTxContext, - swapRequestArgs: swapTxContext.swapRequestArgs ? { - deadline: swapTxContext.swapRequestArgs.deadline, - deadlineDate: swapTxContext.swapRequestArgs.deadline ? new Date(swapTxContext.swapRequestArgs.deadline * 1000).toLocaleString('zh-CN') : undefined, - hasQuote: !!swapTxContext.swapRequestArgs.quote, - simulateTransaction: swapTxContext.swapRequestArgs.simulateTransaction, - allKeys: Object.keys(swapTxContext.swapRequestArgs), - } : 'swapRequestArgs is undefined', - swapTxContextKeys: Object.keys(swapTxContext), - } : undefined, - currencyAmounts: currencyAmounts ? { - input: currencyAmounts.input?.toExact(), - output: currencyAmounts.output?.toExact(), - } : undefined, - currencyAmountsUSDValue: currencyAmountsUSDValue, - txId, - wrapType, - customSlippageTolerance, - }) - } - if ( !account || !swapTxContext || @@ -97,12 +63,6 @@ export function createExecuteSwapService(ctx: { ? 'Invalid account type - must be signer mnemonic account' : 'Invalid swap transaction context' - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: Validation failed in executeSwapService', { - error: errorMessage, - }) - } - ctx.onFailure(new Error(errorMessage)) return } @@ -128,48 +88,7 @@ export function createExecuteSwapService(ctx: { inputCurrencyAmount: currencyAmounts.input ?? undefined, } - if (process.env.NODE_ENV === 'development') { - console.log('[execute] executeSwapService calling onExecuteSwap with params:', executeParams) - console.log('[execute] executeSwapService - Detailed swapTxContext:', { - routing: executeParams.swapTxContext?.routing, - hasTxRequests: !!executeParams.swapTxContext?.txRequests, - txRequestCount: executeParams.swapTxContext?.txRequests?.length || 0, - txRequests: executeParams.swapTxContext?.txRequests?.map((tx, idx) => ({ - index: idx, - to: tx.to, - data: tx.data?.substring(0, 20) + '...', - value: tx.value?.toString(), - gasLimit: tx.gasLimit?.toString(), - gasPrice: tx.gasPrice?.toString(), - chainId: tx.chainId, - })), - hasTrade: !!executeParams.swapTxContext?.trade, - trade: executeParams.swapTxContext?.trade ? { - routing: executeParams.swapTxContext.trade.routing, - inputAmount: executeParams.swapTxContext.trade.inputAmount?.toExact(), - outputAmount: executeParams.swapTxContext.trade.outputAmount?.toExact(), - deadline: executeParams.swapTxContext.trade.deadline, - deadlineDate: executeParams.swapTxContext.trade.deadline ? new Date(executeParams.swapTxContext.trade.deadline * 1000).toLocaleString('zh-CN') : undefined, - } : undefined, - includesDelegation: executeParams.swapTxContext?.includesDelegation, - hasSwapRequestArgs: 'swapRequestArgs' in (executeParams.swapTxContext || {}), - swapRequestArgs: executeParams.swapTxContext?.swapRequestArgs ? { - deadline: executeParams.swapTxContext.swapRequestArgs.deadline, - deadlineDate: executeParams.swapTxContext.swapRequestArgs.deadline ? new Date(executeParams.swapTxContext.swapRequestArgs.deadline * 1000).toLocaleString('zh-CN') : undefined, - hasQuote: !!executeParams.swapTxContext.swapRequestArgs.quote, - simulateTransaction: executeParams.swapTxContext.swapRequestArgs.simulateTransaction, - allKeys: Object.keys(executeParams.swapTxContext.swapRequestArgs), - fullSwapRequestArgs: executeParams.swapTxContext.swapRequestArgs, - } : 'swapRequestArgs is undefined', - swapTxContextKeys: executeParams.swapTxContext ? Object.keys(executeParams.swapTxContext) : [], - }) - } - ctx.onExecuteSwap(executeParams) - .catch((error) => { - const swapError = error instanceof Error ? error : new Error(String(error)) - ctx.onFailure(swapError) - }) }, } } diff --git a/packages/uniswap/src/features/transactions/swap/services/prepareSwapService.ts b/packages/uniswap/src/features/transactions/swap/services/prepareSwapService.ts index d7875ff0674..22c34e60a33 100644 --- a/packages/uniswap/src/features/transactions/swap/services/prepareSwapService.ts +++ b/packages/uniswap/src/features/transactions/swap/services/prepareSwapService.ts @@ -37,9 +37,6 @@ export function createPrepareSwap( function: 'prepareSwap', }, }) - if (process.env.NODE_ENV === 'development') { - console.error('[prepareSwap] Error:', error) - } } // always reset the warning service after the action is handled ctx.warningService.reset() diff --git a/packages/uniswap/src/features/transactions/swap/stores/swapTxStore/hooks/useTransactionRequestInfo.ts b/packages/uniswap/src/features/transactions/swap/stores/swapTxStore/hooks/useTransactionRequestInfo.ts index 397b069c14c..8577f92e84b 100644 --- a/packages/uniswap/src/features/transactions/swap/stores/swapTxStore/hooks/useTransactionRequestInfo.ts +++ b/packages/uniswap/src/features/transactions/swap/stores/swapTxStore/hooks/useTransactionRequestInfo.ts @@ -101,16 +101,6 @@ function useSwapTransactionRequestInfo({ // Only fetch on web app (where useCurrentBlockTimestamp is available) const blockTimestamp = isWebApp && useCurrentBlockTimestamp ? useCurrentBlockTimestamp() : undefined - if (process.env.NODE_ENV === 'development') { - console.log('[swap debug] useTransactionRequestInfo - Preparing swap request params:', { - customDeadline: transactionSettings.customDeadline, - hasSwapQuoteResponse: !!swapQuoteResponse, - alreadyApproved: tokenApprovalInfo?.action === ApprovalAction.None && !swapQuoteResponse?.permitTransaction, - overrideSimulation, - blockTimestamp: blockTimestamp?.toString(), - usingBlockTimestamp: !!blockTimestamp, - }) - } const prepareSwapRequestParams = useMemo(() => createPrepareSwapRequestParams({ gasStrategy }), [gasStrategy]) diff --git a/packages/uniswap/src/features/transactions/swap/utils/getIsWebForNudgeEnabled.ts b/packages/uniswap/src/features/transactions/swap/utils/getIsWebForNudgeEnabled.ts index 7cb7c6fe964..46f35940b57 100644 --- a/packages/uniswap/src/features/transactions/swap/utils/getIsWebForNudgeEnabled.ts +++ b/packages/uniswap/src/features/transactions/swap/utils/getIsWebForNudgeEnabled.ts @@ -6,9 +6,28 @@ export function getIsWebFORNudgeEnabled(): boolean { return false } - return getExperimentValue({ + const result = getExperimentValue({ experiment: Experiments.WebFORNudges, param: WebFORNudgesProperties.NudgeEnabled, defaultValue: false, }) + + // Debug logging for WebFORNudge condition 1: Statsig experiment + if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { + console.log('[review] WebFORNudge Condition 1 - getIsWebFORNudgeEnabled:', { + result, + explanation: { + parameter: 'getIsWebFORNudgeEnabled()', + meaning: '检查 Statsig 实验 "WebFORNudges" 是否启用。WebFORNudge = Web Fiat On Ramp Nudge,用于在钱包为空时引导用户购买/接收代币。', + experiment: 'WebFORNudges (web_for_nudge)', + param: 'NudgeEnabled', + defaultValue: false, + note: result + ? 'Statsig 实验已启用 - 钱包为空时将显示 "Swap Tokens" 按钮' + : 'Statsig 实验未启用或未配置 - 将显示 "Review" 按钮', + }, + }) + } + + return result } diff --git a/packages/utilities/src/reactQuery/cache.ts b/packages/utilities/src/reactQuery/cache.ts index 1d36c92437e..0807ecf2862 100644 --- a/packages/utilities/src/reactQuery/cache.ts +++ b/packages/utilities/src/reactQuery/cache.ts @@ -35,6 +35,7 @@ export enum ReactQueryCacheKey { OnboardingRedirect = 'OnboardingRedirect', OnchainBalances = 'OnchainBalances', OnchainENS = 'OnchainENS', + OnchainPortfolioTotalValue = 'OnchainPortfolioTotalValue', OnRampAuth = 'OnRampAuth', PasskeyAuthStatus = 'PasskeyAuthStatus', Permit2SignatureWithData = 'Permit2SignatureWithData', From 32e40f2635e464dadb906f49ce972e08241c90f5 Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Thu, 22 Jan 2026 17:54:04 +0800 Subject: [PATCH 17/33] feat: remove consoles --- .../src/features/accounts/store/devtools.tsx | 29 +--------- .../web/src/hooks/useCurrentBlockTimestamp.ts | 32 ----------- apps/web/src/hooks/useUniversalRouter.ts | 7 +-- apps/web/src/lib/expo-clipboard.jsx | 8 +-- apps/web/src/pages/Positions/TopPools.tsx | 49 ---------------- apps/web/src/pages/Positions/TopPoolsCard.tsx | 16 ------ .../src/pages/Positions/TopPoolsSection.tsx | 9 --- apps/web/src/sideEffects.ts | 3 +- .../sagas/transactions/useSwapHandlers.ts | 36 ------------ .../web/src/state/sagas/transactions/utils.ts | 24 -------- apps/web/src/utils/lazyWithRetry.ts | 14 +---- .../src/utils/setupVitePreloadErrorHandler.ts | 3 - .../hooks/usePoolTokensOptions.ts | 19 ------- .../apiClients/tradingApi/TradingApiClient.ts | 54 +----------------- .../utils/getTradeSettingsDeadline.ts | 16 ------ .../providers/webForNudgeProvider.tsx | 42 -------------- .../hooks/useIsPortfolioZero.ts | 56 ------------------- .../swap/review/hooks/useTokenApprovalInfo.ts | 38 ------------- .../swapTxAndGasInfoService/evm/utils.ts | 10 ---- .../swap/utils/getIsWebForNudgeEnabled.ts | 17 ------ .../transactionSignerServiceImpl.ts | 10 ---- .../transactions/swap/executeSwapSaga.ts | 40 ------------- .../swap/hooks/useSwapHandlers.ts | 37 ------------ .../swap/services/transactionExecutor.ts | 19 ------- 24 files changed, 6 insertions(+), 582 deletions(-) diff --git a/apps/web/src/features/accounts/store/devtools.tsx b/apps/web/src/features/accounts/store/devtools.tsx index c89160f0469..67866fd8585 100644 --- a/apps/web/src/features/accounts/store/devtools.tsx +++ b/apps/web/src/features/accounts/store/devtools.tsx @@ -66,34 +66,7 @@ function UniswapAccountsStoreDevToolLogger() { numFontWeights += 4 } - const fontWeightStrings = [] - for (let i = 0; i < numFontWeights; i++) { - fontWeightStrings.push('font-weight: bold;', '') - } - - // biome-ignore lint/suspicious/noConsole: console logging required for devtools functionality - console.clear() - // biome-ignore lint/suspicious/noConsole: console logging required for devtools functionality - console.log( - ` - %cAccountsStore 🦄%c - type logAccountsStore again to stop - - %cStatus:%c ${status} - %cWallet:%c ${getWalletString(wallet)} - - %cAddresses:%c ${JSON.stringify(addresses)} - - %cEVM Address:%c ${evmAddress} - %cEVMConnector:%c ${getConnectorString(evmConnector)} - - %cSVM Address:%c ${svmAddress} - %cSVMConnector:%c ${getConnectorString(svmConnector)} - `, - 'color: hotpink; font-weight: bold; font-size: 1.2rem;', - '', - ...fontWeightStrings, - ) + // Devtools logging removed }, [wallet, evmConnector, svmConnector, addresses, evmAddress, status, svmAddress]) return null } diff --git a/apps/web/src/hooks/useCurrentBlockTimestamp.ts b/apps/web/src/hooks/useCurrentBlockTimestamp.ts index 529feea253d..ea9fa4925ce 100644 --- a/apps/web/src/hooks/useCurrentBlockTimestamp.ts +++ b/apps/web/src/hooks/useCurrentBlockTimestamp.ts @@ -89,37 +89,5 @@ export default function useCurrentBlockTimestamp({ // Use Multicall result if available, otherwise fallback to useBlock const blockTimestamp = result.data ?? (blockData.data?.timestamp ? BigInt(blockData.data.timestamp) : undefined) - if (process.env.NODE_ENV === 'development') { - // 获取 RPC URL 信息用于调试 - const rpcConfig = selectRpcUrl(chainId, RPCType.Public) - const rpcUrl = rpcConfig?.rpcUrl || 'N/A' - - console.log('[swap debug] useCurrentBlockTimestamp - Query result:', { - chainId, - rpcUrl, - multicallAddress, - hasData: !!result.data, - data: result.data?.toString(), - isLoading: result.isLoading, - isError: result.isError, - error: result.error?.message, - shouldUseFallback, - hasBlockNumber: !!blockNumber, - blockNumberLoading: blockNumberQuery.isLoading, - blockNumberError: blockNumberQuery.isError, - fallbackBlockNumber: blockNumber?.toString(), - fallbackDataLoading: blockData.isLoading, - fallbackDataError: blockData.isError, - fallbackTimestamp: blockData.data?.timestamp?.toString(), - usingFallback: shouldUseFallback && !!blockData.data?.timestamp, - blockTimestamp: blockTimestamp ? { - value: blockTimestamp.toString(), - hex: '0x' + blockTimestamp.toString(16), - date: new Date(Number(blockTimestamp) * 1000).toLocaleString('zh-CN'), - source: result.data ? 'multicall' : 'useBlock', - } : undefined, - }) - } - return blockTimestamp } diff --git a/apps/web/src/hooks/useUniversalRouter.ts b/apps/web/src/hooks/useUniversalRouter.ts index cd4e29e9a1b..971d654a213 100644 --- a/apps/web/src/hooks/useUniversalRouter.ts +++ b/apps/web/src/hooks/useUniversalRouter.ts @@ -127,12 +127,7 @@ export function useUniversalRouterSwapCallback({ try { routerAddress ??= UNIVERSAL_ROUTER_ADDRESS(UniversalRouterVersion.V1_2, chainId) } catch (error) { - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: Failed to get router address', { - error: error instanceof Error ? error.message : String(error), - chainId, - }) - } + // Router address lookup failed throw new Error( `Failed to get router address for chain ${chainId}: ${error instanceof Error ? error.message : String(error)}`, ) diff --git a/apps/web/src/lib/expo-clipboard.jsx b/apps/web/src/lib/expo-clipboard.jsx index 04821da3c9b..d5c2213bf77 100644 --- a/apps/web/src/lib/expo-clipboard.jsx +++ b/apps/web/src/lib/expo-clipboard.jsx @@ -6,11 +6,9 @@ const Clipboard = { await navigator.clipboard.writeText(text) return { content: text } } catch (e) { - console.warn('Clipboard write failed:', e) return null } } - console.warn('Clipboard API not available') return null }, @@ -20,11 +18,9 @@ const Clipboard = { const text = await navigator.clipboard.readText() return text } catch (e) { - console.warn('Clipboard read failed:', e) return '' } } - console.warn('Clipboard API not available') return '' }, @@ -40,8 +36,6 @@ const Clipboard = { // Non-JSX implementation of ClipboardPasteButton const createPasteButton = (options = {}) => { - console.warn('ClipboardPasteButton is mocked and will not render a real button') - // This returns a function that will create a simple button element when called return function ClipboardPasteButton(props) { // If this gets called, we'll return a simple object instead of JSX @@ -56,7 +50,7 @@ const createPasteButton = (options = {}) => { props.onPress({ text }) } } catch (e) { - console.error('Error in paste button:', e) + // Error handling } }, }, diff --git a/apps/web/src/pages/Positions/TopPools.tsx b/apps/web/src/pages/Positions/TopPools.tsx index 3b7c9e1352d..789f9293745 100644 --- a/apps/web/src/pages/Positions/TopPools.tsx +++ b/apps/web/src/pages/Positions/TopPools.tsx @@ -31,21 +31,11 @@ export function TopPools({ chainId }: { chainId: UniverseChainId | null }) { error: hskPoolsError, } = useHSKSubgraphPools(1000) // 获取足够多的 pools(1000 应该足够覆盖所有 pools) - // 调试信息 - console.log('[TopPools] HSK Subgraph 数据:', { - hskPools, - hskPoolsLoading, - hskPoolsError, - poolsCount: hskPools?.length, - }) - // 按 TVL 排序 pools const sortedHSKPools = useMemo(() => { if (!hskPools) { - console.log('[TopPools] hskPools 为空') return [] } - console.log('[TopPools] 开始排序,pools 数量:', hskPools.length) const sorted = [...hskPools].sort((a, b) => { // totalLiquidity.value 是 number 类型 const tvlA = typeof a.totalLiquidity?.value === 'number' @@ -56,35 +46,6 @@ export function TopPools({ chainId }: { chainId: UniverseChainId | null }) { : parseFloat(String(b.totalLiquidity?.value || '0')) return tvlB - tvlA }) - console.log('[TopPools] 排序后的 pools (前6个):', sorted.slice(0, 6).map(p => ({ - id: p.id, - token0: p.token0?.symbol, - token1: p.token1?.symbol, - tvl: p.totalLiquidity?.value - }))) - // 输出所有 pools 的完整数据 - console.log('[TopPools] 所有 pools 数据 (完整):', { - totalCount: sorted.length, - allPools: sorted.map(p => ({ - id: p.id, - address: p.address, - token0: { - symbol: p.token0?.symbol, - name: p.token0?.name, - address: p.token0?.address, - }, - token1: { - symbol: p.token1?.symbol, - name: p.token1?.name, - address: p.token1?.address, - }, - totalLiquidity: p.totalLiquidity?.value, - feeTier: p.feeTier, - volume24h: p.volume24h?.value, - volume30d: p.volume30d?.value, - txCount: p.txCount, - })) - }) return sorted }, [hskPools]) @@ -114,16 +75,6 @@ export function TopPools({ chainId }: { chainId: UniverseChainId | null }) { const displayBoostedPools = false // HSK Subgraph 数据不包含 boosted pools const displayTopPools = topPools && topPools.length > 0 - // 调试信息 - console.log('[TopPools] 渲染状态:', { - isBelowXlScreen, - topPoolsLength: topPools?.length, - displayTopPools, - isLoading, - hasError, - media: media, - }) - // 临时:即使屏幕很大也显示,用于调试 // if (!isBelowXlScreen) { // return null diff --git a/apps/web/src/pages/Positions/TopPoolsCard.tsx b/apps/web/src/pages/Positions/TopPoolsCard.tsx index 02e301ff5ac..87b6efe2a68 100644 --- a/apps/web/src/pages/Positions/TopPoolsCard.tsx +++ b/apps/web/src/pages/Positions/TopPoolsCard.tsx @@ -14,22 +14,6 @@ export function TopPoolsCard({ pool }: { pool: PoolStat }) { const { defaultChainId } = useEnabledChains() const { formatPercent } = useLocalizationContext() - // Console pool 数据用于调试 - console.log('[TopPoolsCard] Pool 数据:', { - id: pool.id, - token0: pool.token0, - token1: pool.token1, - apr: pool.apr, - aprType: typeof pool.apr, - aprIsPercent: pool.apr instanceof Percent, - aprHasToFixed: pool.apr && typeof (pool.apr as any).toFixed === 'function', - totalLiquidity: pool.totalLiquidity, - volume1Day: pool.volume1Day, - protocolVersion: pool.protocolVersion, - feeTier: pool.feeTier, - boostedApr: pool.boostedApr, - }) - const chainId = supportedChainIdFromGQLChain(pool.chain as GraphQLApi.Chain) ?? defaultChainId // 尝试使用 gqlToCurrency,如果失败则直接使用 pool 中的 symbol diff --git a/apps/web/src/pages/Positions/TopPoolsSection.tsx b/apps/web/src/pages/Positions/TopPoolsSection.tsx index edb9cee6da3..ceb7b3e529e 100644 --- a/apps/web/src/pages/Positions/TopPoolsSection.tsx +++ b/apps/web/src/pages/Positions/TopPoolsSection.tsx @@ -5,14 +5,6 @@ import { PoolStat } from 'state/explore/types' import { Flex, Text } from 'ui/src' export function TopPoolsSection({ pools, title, isLoading }: { pools: PoolStat[]; title: string; isLoading: boolean }) { - // 调试信息 - console.log('[TopPoolsSection] 渲染状态:', { - poolsLength: pools.length, - isLoading, - title, - pools: pools.slice(0, 3).map((p) => ({ id: p.id, token0: p.token0?.symbol, token1: p.token1?.symbol })), - }) - if (isLoading) { return ( @@ -27,7 +19,6 @@ export function TopPoolsSection({ pools, title, isLoading }: { pools: PoolStat[] } if (!pools || pools.length === 0) { - console.log('[TopPoolsSection] 没有 pools 数据') return null } diff --git a/apps/web/src/sideEffects.ts b/apps/web/src/sideEffects.ts index e6a758fdb59..38ca941a248 100644 --- a/apps/web/src/sideEffects.ts +++ b/apps/web/src/sideEffects.ts @@ -13,8 +13,7 @@ import { setupWagmiAutoConnect } from 'components/Web3Provider/wagmiAutoConnect' import { setupVitePreloadErrorHandler } from 'utils/setupVitePreloadErrorHandler' if (WalletConnect) { - // biome-ignore lint/suspicious/noConsole: Side effects module needs console for initialization logging - console.debug('WalletConnect is defined') + // WalletConnect is defined } // adding these so webpack won't tree shake this away, sideEffects was giving trouble diff --git a/apps/web/src/state/sagas/transactions/useSwapHandlers.ts b/apps/web/src/state/sagas/transactions/useSwapHandlers.ts index 562bb2bdc4a..9e9a1ca11ce 100644 --- a/apps/web/src/state/sagas/transactions/useSwapHandlers.ts +++ b/apps/web/src/state/sagas/transactions/useSwapHandlers.ts @@ -43,42 +43,6 @@ export function useSwapHandlers(): SwapHandlers { // Execute routes to the appropriate callback based on transaction type const execute: ExecuteSwapCallback = useCallback( async (params) => { - if (process.env.NODE_ENV === 'development') { - console.log('[execute] useSwapHandlers execute called with params:', params) - console.log('[execute] useSwapHandlers - Detailed swapTxContext:', { - routing: params.swapTxContext?.routing, - hasTxRequests: !!params.swapTxContext?.txRequests, - txRequestCount: params.swapTxContext?.txRequests?.length || 0, - txRequests: params.swapTxContext?.txRequests?.map((tx, idx) => ({ - index: idx, - to: tx.to, - data: tx.data?.substring(0, 20) + '...', - value: tx.value?.toString(), - gasLimit: tx.gasLimit?.toString(), - chainId: tx.chainId, - })), - hasTrade: !!params.swapTxContext?.trade, - trade: params.swapTxContext?.trade ? { - routing: params.swapTxContext.trade.routing, - inputAmount: params.swapTxContext.trade.inputAmount?.toExact(), - outputAmount: params.swapTxContext.trade.outputAmount?.toExact(), - deadline: params.swapTxContext.trade.deadline, - deadlineDate: params.swapTxContext.trade.deadline ? new Date(params.swapTxContext.trade.deadline * 1000).toLocaleString('zh-CN') : undefined, - } : undefined, - includesDelegation: params.swapTxContext?.includesDelegation, - hasSwapRequestArgs: 'swapRequestArgs' in (params.swapTxContext || {}), - swapRequestArgs: params.swapTxContext?.swapRequestArgs ? { - deadline: params.swapTxContext.swapRequestArgs.deadline, - deadlineDate: params.swapTxContext.swapRequestArgs.deadline ? new Date(params.swapTxContext.swapRequestArgs.deadline * 1000).toLocaleString('zh-CN') : undefined, - hasQuote: !!params.swapTxContext.swapRequestArgs.quote, - simulateTransaction: params.swapTxContext.swapRequestArgs.simulateTransaction, - allKeys: Object.keys(params.swapTxContext.swapRequestArgs), - fullSwapRequestArgs: params.swapTxContext.swapRequestArgs, - } : 'swapRequestArgs is undefined', - swapTxContextKeys: params.swapTxContext ? Object.keys(params.swapTxContext) : [], - }) - } - const { account, swapTxContext, diff --git a/apps/web/src/state/sagas/transactions/utils.ts b/apps/web/src/state/sagas/transactions/utils.ts index 5a20bb32ce6..ba060f5321a 100644 --- a/apps/web/src/state/sagas/transactions/utils.ts +++ b/apps/web/src/state/sagas/transactions/utils.ts @@ -270,33 +270,9 @@ function* submitTransaction(params: HandleOnChainStepParams): SagaGenerator>( // Calculate delay and wait before retrying const delay = calculateDelay(attempt, { baseDelay: options.baseDelay, maxDelay: options.maxDelay }) - // biome-ignore lint/suspicious/noConsole: Need console for debugging import retry attempts - console.warn( - `Dynamic import failed (attempt ${attempt}/${options.maxRetries}), retrying in ${Math.round(delay)}ms:`, - lastError.message, - ) - await new Promise((resolve) => setTimeout(resolve, delay)) } } diff --git a/apps/web/src/utils/setupVitePreloadErrorHandler.ts b/apps/web/src/utils/setupVitePreloadErrorHandler.ts index 8c607e3e30b..7a5af4b1275 100644 --- a/apps/web/src/utils/setupVitePreloadErrorHandler.ts +++ b/apps/web/src/utils/setupVitePreloadErrorHandler.ts @@ -2,8 +2,5 @@ export function setupVitePreloadErrorHandler(): void { window.addEventListener('vite:preloadError', (event: Event) => { // Prevent Vite from throwing the error and crashing the app event.preventDefault() - - // biome-ignore lint/suspicious/noConsole: Error handler needs console for debugging preload issues - console.error('Vite preload error: Dynamic import failed to load') }) } diff --git a/packages/uniswap/src/components/TokenSelector/hooks/usePoolTokensOptions.ts b/packages/uniswap/src/components/TokenSelector/hooks/usePoolTokensOptions.ts index 907c1ba7e48..c9eb8e237f5 100644 --- a/packages/uniswap/src/components/TokenSelector/hooks/usePoolTokensOptions.ts +++ b/packages/uniswap/src/components/TokenSelector/hooks/usePoolTokensOptions.ts @@ -93,34 +93,15 @@ export function usePoolTokensOptions( } } catch (error) { // Skip invalid tokens - if (typeof window !== 'undefined') { - console.warn('[usePoolTokensOptions] Failed to build currency for token:', token, error) - } } }) - // Debug log - if (typeof window !== 'undefined') { - console.log('[usePoolTokensOptions] Debug:', { - uniqueTokens: uniqueTokens.length, - currencyInfos: infos.length, - chainId, - }) - } - return infos }, [uniqueTokens, chainId]) // Convert to TokenOptions (same format as recent searches) const tokenOptions = useMemo(() => { const options = currencyInfosToTokenOptions(currencyInfos) ?? [] - // Debug log - if (typeof window !== 'undefined') { - console.log('[usePoolTokensOptions] TokenOptions:', { - currencyInfos: currencyInfos.length, - tokenOptions: options.length, - }) - } return options }, [currencyInfos]) diff --git a/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts b/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts index 1714ced6ed2..e13fbb15065 100644 --- a/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts +++ b/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts @@ -29,22 +29,6 @@ const QuoteFetchClient = createUniswapFetchClient({ additionalHeaders: quoteApiHeaders, }) -// Debug: Log Trading API configuration (quoteUrlPath will be defined later) -if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { - const debugQuoteUrlPath = tradingApiVersionPrefix - ? `${tradingApiVersionPrefix}/${TRADING_API_PATHS.quote}` - : `/${TRADING_API_PATHS.quote}` - console.log('[TradingApiClient] Base URL:', uniswapUrls.tradingApiUrl) - console.log('[TradingApiClient] Quote API Base URL:', quoteApiBaseUrl) - console.log('[TradingApiClient] API Path Prefix:', tradingApiVersionPrefix) - console.log('[TradingApiClient] Quote URL Path:', debugQuoteUrlPath) - console.log('[TradingApiClient] Full Quote URL:', `${quoteApiBaseUrl}${debugQuoteUrlPath}`) - console.log( - '[TradingApiClient] Trading API Key:', - config.tradingApiKey ? '***' : '(empty - no API key header will be sent)', - ) - console.log('[TradingApiClient] Quote API Headers:', quoteApiHeaders) -} /** * Helper to add a header only if enabled. @@ -188,16 +172,6 @@ const transformQuoteRequest = async (request: { tokenOutChainId: typeof params.tokenOutChainId === 'string' ? parseInt(params.tokenOutChainId, 10) : params.tokenOutChainId, } - if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { - console.log('[TradingApiClient] Request params:', { - tokenInChainId: transformedParams.tokenInChainId, - tokenOutChainId: transformedParams.tokenOutChainId, - tokenInChainIdType: typeof transformedParams.tokenInChainId, - tokenOutChainIdType: typeof transformedParams.tokenOutChainId, - hasGasStrategies: !!transformedParams.gasStrategies, - }) - } - return { headers: getFeatureFlaggedHeaders(TRADING_API_PATHS.quote), params: transformedParams, @@ -210,16 +184,7 @@ const customFetchQuote = createFetcher { - // Use the logger from the default client if available - if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { - console.warn('[TradingApiClient] Quote 404', { - chainIdIn: params.tokenInChainId, - chainIdOut: params.tokenOutChainId, - tradeType: params.type, - isBridging: params.tokenInChainId !== params.tokenOutChainId, - url: `${quoteApiBaseUrl}${quoteUrlPath}`, - }) - } + // 404 handler - no logging needed }, }) @@ -228,25 +193,8 @@ const customFetchQuoteWithErrorHandling = async ( params: QuoteRequest & { isUSDQuote?: boolean }, ): Promise => { try { - if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { - console.log('[TradingApiClient] Fetching quote (original request):', { - url: `${quoteApiBaseUrl}${quoteUrlPath}`, - chainIdIn: params.tokenInChainId, - chainIdOut: params.tokenOutChainId, - requestBody: JSON.stringify(params, null, 2), - }) - console.log('[TradingApiClient] Note: Request will be transformed by transformQuoteRequest before sending') - } return await customFetchQuote(params) } catch (error) { - if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { - console.error('[TradingApiClient] Quote fetch error:', error, { - url: `${quoteApiBaseUrl}${quoteUrlPath}`, - chainIdIn: params.tokenInChainId, - chainIdOut: params.tokenOutChainId, - originalRequestBody: JSON.stringify(params, null, 2), - }) - } throw error } } diff --git a/packages/uniswap/src/data/apiClients/tradingApi/utils/getTradeSettingsDeadline.ts b/packages/uniswap/src/data/apiClients/tradingApi/utils/getTradeSettingsDeadline.ts index 90139ac639d..b04fed22e08 100644 --- a/packages/uniswap/src/data/apiClients/tradingApi/utils/getTradeSettingsDeadline.ts +++ b/packages/uniswap/src/data/apiClients/tradingApi/utils/getTradeSettingsDeadline.ts @@ -16,21 +16,5 @@ export const getTradeSettingsDeadline = ( const deadline = baseTimestamp + deadlineSeconds - if (process.env.NODE_ENV === 'development') { - console.log('[swap debug] getTradeSettingsDeadline:', { - customDeadline, - usingDefault: customDeadline === undefined, - defaultDeadline: DEFAULT_CUSTOM_DEADLINE, - deadlineMinutes, - deadlineSeconds, - blockTimestamp: blockTimestamp?.toString(), - baseTimestamp, - deadline, - deadlineDate: new Date(deadline * 1000).toLocaleString('zh-CN'), - currentTime: new Date().toLocaleString('zh-CN'), - usingBlockTimestamp: !!blockTimestamp, - }) - } - return deadline } diff --git a/packages/uniswap/src/features/providers/webForNudgeProvider.tsx b/packages/uniswap/src/features/providers/webForNudgeProvider.tsx index 353ee1596c6..ee844ede604 100644 --- a/packages/uniswap/src/features/providers/webForNudgeProvider.tsx +++ b/packages/uniswap/src/features/providers/webForNudgeProvider.tsx @@ -47,48 +47,6 @@ export function useWebFORNudgeGateEnabled(): boolean { const result = isWebFORNudgeEnabled && isPortfolioZero && !canPayGasInAnyToken - // Debug logging for WebFORNudge condition 3: Can pay gas in any token - if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { - console.log('[review] WebFORNudge Condition 3 - canPayGasInAnyToken:', { - canPayGasInAnyToken, - explanation: { - parameter: '!canPayGasInAnyToken', - meaning: '检查钱包是否可以用任何代币支付 gas 费用。某些钱包(如 Porto 钱包)支持用任意代币支付 gas,这种情况下不需要引导用户购买原生代币,因此不显示 WebFORNudge。', - note: canPayGasInAnyToken - ? '钱包可以用任何代币支付 gas(如 Porto 钱包)- 不满足 WebFORNudge 条件,不需要引导购买原生代币' - : '钱包不能用任何代币支付 gas - 满足 WebFORNudge 条件,需要引导用户购买原生代币', - }, - }) - } - - // Debug logging for final WebFORNudge result - if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { - console.log('[review] WebFORNudge Final Result:', { - result, - conditions: { - condition1_getIsWebFORNudgeEnabled: isWebFORNudgeEnabled, - condition2_isPortfolioZero: isPortfolioZero, - condition3_notCanPayGasInAnyToken: !canPayGasInAnyToken, - }, - explanation: { - whatIsWebFORNudge: 'WebFORNudge = Web Fiat On Ramp Nudge(Web 法币入金提示)。当用户钱包为空时,显示 "Swap Tokens" 按钮和空钱包引导卡片,引导用户购买/接收代币。', - formula: 'isWebFORNudgeEnabled = condition1 && condition2 && condition3', - result: result - ? '✅ WebFORNudge 已启用 - 将显示 "Swap Tokens" 按钮' - : '❌ WebFORNudge 未启用 - 将显示 "Review" 按钮', - whyFalse: !result - ? `未启用的原因:${[ - !isWebFORNudgeEnabled && '条件1: Statsig 实验未启用', - !isPortfolioZero && '条件2: 投资组合余额不为 0', - canPayGasInAnyToken && '条件3: 钱包可以用任何代币支付 gas', - ] - .filter(Boolean) - .join(' 或 ')}` - : '所有条件都满足', - }, - }) - } - return result } diff --git a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsPortfolioZero.ts b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsPortfolioZero.ts index 9b0f2baf308..6c209b9a7bd 100644 --- a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsPortfolioZero.ts +++ b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsPortfolioZero.ts @@ -13,61 +13,5 @@ export function useIsPortfolioZero(): boolean { const result = !isTestnetModeEnabled && balanceUSD === 0 - // Debug logging for WebFORNudge condition 2: Portfolio zero - if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { - // Log immediately when loading state changes - if (loading) { - console.log('[review] WebFORNudge Condition 2 - useIsPortfolioZero: 链上查询中...', { - loading: true, - currentBalanceUSD: balanceUSD, - environment: { - hostname: window.location.hostname, - origin: window.location.origin, - port: window.location.port, - }, - }) - } - - // Log when loading completes (either success or error) - if (!loading) { - console.log('[review] WebFORNudge Condition 2 - useIsPortfolioZero: 链上查询完成', { - result, - isTestnetModeEnabled, - balanceUSD, - loading: false, - error: error ? String(error) : undefined, - errorDetails: error - ? { - message: error.message, - name: error.name, - stack: error.stack?.substring(0, 200), - } - : undefined, - walletAddresses: { - evmAddress: wallet.evmAccount?.address, - svmAddress: wallet.svmAccount?.address, - }, - environment: { - hostname: window.location.hostname, - origin: window.location.origin, - port: window.location.port, - protocol: window.location.protocol, - href: window.location.href, - }, - explanation: { - parameter: 'isPortfolioZero', - meaning: '检查投资组合余额是否为 0。使用链上查询替代 Uniswap GetPortfolio API,查询所有启用链的原生代币余额。', - calculation: '!isTestnetModeEnabled && balanceUSD === 0', - note: result - ? '投资组合余额为 0 - 满足 WebFORNudge 条件(所有链的原生代币余额都为 0)' - : error - ? `链上查询失败: ${String(error)}` - : `投资组合余额不为 0 (检测到非零余额) 或处于测试网模式 - 不满足 WebFORNudge 条件`, - implementation: '使用链上直接查询,不依赖 Uniswap API,避免 CORS 问题', - }, - }) - } - } - return result } diff --git a/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.ts b/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.ts index cf1ea54af07..54313bafa73 100644 --- a/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.ts +++ b/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.ts @@ -112,33 +112,6 @@ export function useTokenApprovalInfo(params: TokenApprovalInfoParams): ApprovalT immediateGcTime: ONE_MINUTE_MS, }) - // Debug logging for allowance check - if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { - if (!isLoading && (data !== undefined || error)) { - console.log('[allowance] useTokenApprovalInfo check result:', { - shouldSkip, - skipReasons: { - noApprovalRequestArgs: !approvalRequestArgs, - isWrap, - noAddress: !address, - approvalWillBeBatchedWithSwap, - isChained, - }, - approvalWillBeBatchedWithSwap, - chainId, - routing, - data: data ? { approval: data.approval !== null, hasCancel: !!data.cancel } : undefined, - error: error ? String(error) : undefined, - approvalRequestArgs: approvalRequestArgs - ? { - token: approvalRequestArgs.token, - amount: approvalRequestArgs.amount, - chainId: approvalRequestArgs.chainId, - } - : undefined, - }) - } - } const tokenApprovalInfo: TokenApprovalInfo = useMemo(() => { if (error) { @@ -148,17 +121,6 @@ export function useTokenApprovalInfo(params: TokenApprovalInfoParams): ApprovalT approvalRequestArgs, }, }) - - // Debug: Log error details - if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { - console.error('[allowance] API error - returning ApprovalAction.Unknown:', { - error: String(error), - errorType: error?.constructor?.name, - errorMessage: error instanceof Error ? error.message : String(error), - approvalRequestArgs, - willBlockTransaction: true, - }) - } } // Approval is N/A for wrap transactions or unconnected state. diff --git a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/utils.ts b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/utils.ts index 6926c309e67..bc5c03d057c 100644 --- a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/utils.ts +++ b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/utils.ts @@ -49,16 +49,6 @@ export function createGetEVMSwapTransactionRequestInfo(ctx: { const skip = getSwapInputExceedsBalance({ derivedSwapInfo }) || approvalUnknown - // Debug logging for approval unknown case - if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development' && approvalUnknown) { - console.warn('[allowance] ApprovalAction.Unknown - skipping swap instructions:', { - approvalAction, - skip, - balanceExceeds: getSwapInputExceedsBalance({ derivedSwapInfo }), - note: 'This should block the transaction, but swapRequestParams will still be prepared', - }) - } - // Always prepare swapRequestParams, even if skip is true, so deadline is preserved const alreadyApproved = approvalAction === ApprovalAction.None && !swapQuoteResponse.permitTransaction const swapRequestParams = prepareSwapRequestParams({ diff --git a/packages/uniswap/src/features/transactions/swap/utils/getIsWebForNudgeEnabled.ts b/packages/uniswap/src/features/transactions/swap/utils/getIsWebForNudgeEnabled.ts index 46f35940b57..8e61c350ecc 100644 --- a/packages/uniswap/src/features/transactions/swap/utils/getIsWebForNudgeEnabled.ts +++ b/packages/uniswap/src/features/transactions/swap/utils/getIsWebForNudgeEnabled.ts @@ -12,22 +12,5 @@ export function getIsWebFORNudgeEnabled(): boolean { defaultValue: false, }) - // Debug logging for WebFORNudge condition 1: Statsig experiment - if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') { - console.log('[review] WebFORNudge Condition 1 - getIsWebFORNudgeEnabled:', { - result, - explanation: { - parameter: 'getIsWebFORNudgeEnabled()', - meaning: '检查 Statsig 实验 "WebFORNudges" 是否启用。WebFORNudge = Web Fiat On Ramp Nudge,用于在钱包为空时引导用户购买/接收代币。', - experiment: 'WebFORNudges (web_for_nudge)', - param: 'NudgeEnabled', - defaultValue: false, - note: result - ? 'Statsig 实验已启用 - 钱包为空时将显示 "Swap Tokens" 按钮' - : 'Statsig 实验未启用或未配置 - 将显示 "Review" 按钮', - }, - }) - } - return result } diff --git a/packages/wallet/src/features/transactions/executeTransaction/services/TransactionSignerService/transactionSignerServiceImpl.ts b/packages/wallet/src/features/transactions/executeTransaction/services/TransactionSignerService/transactionSignerServiceImpl.ts index 408789d9ace..78bcce0c630 100644 --- a/packages/wallet/src/features/transactions/executeTransaction/services/TransactionSignerService/transactionSignerServiceImpl.ts +++ b/packages/wallet/src/features/transactions/executeTransaction/services/TransactionSignerService/transactionSignerServiceImpl.ts @@ -56,17 +56,7 @@ export function createTransactionSignerService(ctx: { const sendTransaction: TransactionSigner['sendTransaction'] = async (input) => { const provider = await ctx.getProvider() - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] Sending signed transaction to provider:', { - hasSignedTx: !!input.signedTx, - signedTxLength: input.signedTx?.length, - providerType: provider.constructor.name, - }) - } const transactionResponse = await provider.sendTransaction(input.signedTx) - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] Transaction sent, received hash:', transactionResponse.hash) - } return transactionResponse.hash } diff --git a/packages/wallet/src/features/transactions/swap/executeSwapSaga.ts b/packages/wallet/src/features/transactions/swap/executeSwapSaga.ts index c2897dce9e2..ba38273db59 100644 --- a/packages/wallet/src/features/transactions/swap/executeSwapSaga.ts +++ b/packages/wallet/src/features/transactions/swap/executeSwapSaga.ts @@ -170,33 +170,14 @@ function* executeTransactionStep(params: { } // Execute async (either because sync is not enabled or sync failed) - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] Executing transaction step asynchronously:', { - stepType: step.type, - chainId, - }) - } const asyncResult = yield* executor.executeStep(step) if (!asyncResult.success) { const error = asyncResult.error instanceof Error ? asyncResult.error : new Error(asyncResult.error ? String(asyncResult.error) : 'Transaction failed') - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: Transaction step execution failed', { - error: error.message, - errorDetails: error, - stepType: step.type, - chainId, - }) - } yield* call(onFailure) throw error } - - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] Transaction step executed successfully:', { - stepType: step.type, - hash: asyncResult.hash, chainId, }) } @@ -461,14 +442,6 @@ export function createExecuteSwapSaga( ) } - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] About to execute swap transaction step:', { - stepType: swapStep.type, - hasParams: !!swapStep.params, - chainId, - }) - } - swapResult = yield* executeTransactionStep({ executor, step: swapStep, @@ -476,14 +449,6 @@ export function createExecuteSwapSaga( logger: dependencies.logger, onFailure: params.onFailure, }) - - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] Swap transaction step executed:', { - hasResult: !!swapResult, - resultType: swapResult ? 'sync' : 'async', - chainId, - }) - } } if (swapResult) { @@ -508,11 +473,6 @@ export function createExecuteSwapSaga( tags: { file: 'executeSwapSaga', function: 'executeSwap' }, extra: { analytics: params.analytics }, }) - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: executeSwapSaga failed', { - error: error instanceof Error ? error.message : String(error), - }) - } // Call onFailure with the error so it can be displayed to the user const swapError = error instanceof Error ? error : new Error(String(error)) yield* call(params.onFailure, swapError) diff --git a/packages/wallet/src/features/transactions/swap/hooks/useSwapHandlers.ts b/packages/wallet/src/features/transactions/swap/hooks/useSwapHandlers.ts index 20837dc5dde..698d06c190a 100644 --- a/packages/wallet/src/features/transactions/swap/hooks/useSwapHandlers.ts +++ b/packages/wallet/src/features/transactions/swap/hooks/useSwapHandlers.ts @@ -39,43 +39,6 @@ export function useSwapHandlers(): SwapHandlers { const execute: ExecuteSwapCallback = useCallback( async (params: ExecuteSwapParams) => { - if (process.env.NODE_ENV === 'development') { - console.log('[execute] ExecuteSwapCallback called with params:', params) - console.log('[execute] ExecuteSwapCallback - Detailed swapTxContext:', { - routing: params.swapTxContext?.routing, - hasTxRequests: !!params.swapTxContext?.txRequests, - txRequestCount: params.swapTxContext?.txRequests?.length || 0, - txRequests: params.swapTxContext?.txRequests?.map((tx, idx) => ({ - index: idx, - to: tx.to, - data: tx.data?.substring(0, 20) + '...', - value: tx.value?.toString(), - gasLimit: tx.gasLimit?.toString(), - gasPrice: tx.gasPrice?.toString(), - chainId: tx.chainId, - })), - hasTrade: !!params.swapTxContext?.trade, - trade: params.swapTxContext?.trade ? { - routing: params.swapTxContext.trade.routing, - inputAmount: params.swapTxContext.trade.inputAmount?.toExact(), - outputAmount: params.swapTxContext.trade.outputAmount?.toExact(), - deadline: params.swapTxContext.trade.deadline, - deadlineDate: params.swapTxContext.trade.deadline ? new Date(params.swapTxContext.trade.deadline * 1000).toLocaleString('zh-CN') : undefined, - } : undefined, - includesDelegation: params.swapTxContext?.includesDelegation, - hasSwapRequestArgs: 'swapRequestArgs' in (params.swapTxContext || {}), - swapRequestArgs: params.swapTxContext?.swapRequestArgs ? { - deadline: params.swapTxContext.swapRequestArgs.deadline, - deadlineDate: params.swapTxContext.swapRequestArgs.deadline ? new Date(params.swapTxContext.swapRequestArgs.deadline * 1000).toLocaleString('zh-CN') : undefined, - hasQuote: !!params.swapTxContext.swapRequestArgs.quote, - simulateTransaction: params.swapTxContext.swapRequestArgs.simulateTransaction, - allKeys: Object.keys(params.swapTxContext.swapRequestArgs), - fullSwapRequestArgs: params.swapTxContext.swapRequestArgs, - } : 'swapRequestArgs is undefined', - swapTxContextKeys: params.swapTxContext ? Object.keys(params.swapTxContext) : [], - }) - } - // Mark execution as called to prevent future prepareAndSign calls signing.markExecutionCalled() diff --git a/packages/wallet/src/features/transactions/swap/services/transactionExecutor.ts b/packages/wallet/src/features/transactions/swap/services/transactionExecutor.ts index 8149fe65ad9..fd04a21c66d 100644 --- a/packages/wallet/src/features/transactions/swap/services/transactionExecutor.ts +++ b/packages/wallet/src/features/transactions/swap/services/transactionExecutor.ts @@ -39,22 +39,9 @@ export function createTransactionExecutor(transactionService: TransactionService try { const { params, shouldWait } = step - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] executeStep: Calling submitTransaction:', { - stepType: step.type, - hasParams: !!params, - hasRequest: !!params?.request, - hasSignedRequest: !!params?.request?.signedRequest, - }) - } - const result = yield* call(transactionService.submitTransaction, params) const hash = result.transactionHash - if (process.env.NODE_ENV === 'development') { - console.log('[Swap] executeStep: Transaction submitted, hash:', hash) - } - // Handle transaction spacing if required if (shouldWait) { const { success } = yield* call(waitForTransactionConfirmation, { hash }) @@ -70,12 +57,6 @@ export function createTransactionExecutor(transactionService: TransactionService tags: { file: 'transactionExecutor', function: 'executeStep' }, extra: { stepType: step.type }, }) - if (process.env.NODE_ENV === 'development') { - console.error('[Swap] Error: executeStep failed:', { - error: error instanceof Error ? error.message : String(error), - stepType: step.type, - }) - } return { error, success: false } } } From eca741994dce06a90dc4fb6a4fd565d5e82b75ec Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Thu, 22 Jan 2026 18:00:22 +0800 Subject: [PATCH 18/33] fix: csp --- apps/web/src/state/sagas/transactions/utils.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/web/src/state/sagas/transactions/utils.ts b/apps/web/src/state/sagas/transactions/utils.ts index ba060f5321a..f0d0d52781f 100644 --- a/apps/web/src/state/sagas/transactions/utils.ts +++ b/apps/web/src/state/sagas/transactions/utils.ts @@ -273,11 +273,15 @@ function* submitTransaction(params: HandleOnChainStepParams): SagaGenerator Date: Fri, 23 Jan 2026 01:12:04 +0800 Subject: [PATCH 19/33] feat: update on chain approval check --- .../src/state/sagas/transactions/swapSaga.ts | 28 ++- .../sagas/transactions/useSwapHandlers.ts | 38 ++-- .../web/src/state/sagas/transactions/utils.ts | 84 ++++++- .../SwapReviewFooter/SwapReviewFooter.tsx | 1 - .../review/hooks/useTokenApprovalInfo.test.ts | 99 ++++++++- .../swap/review/hooks/useTokenApprovalInfo.ts | 205 +++++++++++++++++- .../services/swapTxAndGasInfoService/utils.ts | 11 + .../utils/generateSwapTransactionSteps.ts | 1 - 8 files changed, 432 insertions(+), 35 deletions(-) diff --git a/apps/web/src/state/sagas/transactions/swapSaga.ts b/apps/web/src/state/sagas/transactions/swapSaga.ts index b11ed959b5e..87cf69e7b70 100644 --- a/apps/web/src/state/sagas/transactions/swapSaga.ts +++ b/apps/web/src/state/sagas/transactions/swapSaga.ts @@ -61,6 +61,7 @@ import { PermitMethod, ValidatedSwapTxContext } from 'uniswap/src/features/trans import { BridgeTrade, ChainedActionTrade, ClassicTrade } from 'uniswap/src/features/transactions/swap/types/trade' import { slippageToleranceToPercent } from 'uniswap/src/features/transactions/swap/utils/format' import { generateSwapTransactionSteps } from 'uniswap/src/features/transactions/swap/utils/generateSwapTransactionSteps' +import { createApprovalTransactionStep } from 'uniswap/src/features/transactions/steps/approve' import { isClassic, isJupiter, @@ -73,6 +74,7 @@ import { isSignerMnemonicAccountDetails, SignerMnemonicAccountDetails, } from 'uniswap/src/features/wallet/types/AccountDetails' +import { UniverseChainId } from 'uniswap/src/features/chains/types' import { createSaga } from 'uniswap/src/utils/saga' import { logger } from 'utilities/src/logger/logger' import { useTrace } from 'utilities/src/telemetry/trace/TraceContext' @@ -535,7 +537,21 @@ function* swap(params: SwapParams) { } const steps = yield* call(generateSwapTransactionSteps, swapTxContext, v4Enabled) - setSteps(steps) + const isHashKeyChain = + swapChainId === UniverseChainId.HashKey || swapChainId === UniverseChainId.HashKeyTestnet + const approvalStep = + isHashKeyChain && swapTxContext.approveTxRequest + ? createApprovalTransactionStep({ + txRequest: swapTxContext.approveTxRequest, + amount: swapTxContext.trade.inputAmount.quotient.toString(), + tokenAddress: swapTxContext.trade.inputAmount.currency.wrapped.address, + chainId: swapChainId, + }) + : undefined + const stepsWithoutApproval = approvalStep + ? steps.filter((step) => step.type !== TransactionStepType.TokenApprovalTransaction) + : steps + setSteps(approvalStep ? [approvalStep, ...stepsWithoutApproval] : steps) let signature: string | undefined let step: TransactionStep | undefined @@ -548,7 +564,15 @@ function* swap(params: SwapParams) { return } - for (step of steps) { + if (approvalStep) { + try { + yield* call(handleApprovalTransactionStep, { address: account.address, step: approvalStep, setCurrentStep }) + } catch (error) { + throw error + } + } + + for (step of stepsWithoutApproval) { switch (step.type) { case TransactionStepType.TokenRevocationTransaction: case TransactionStepType.TokenApprovalTransaction: { diff --git a/apps/web/src/state/sagas/transactions/useSwapHandlers.ts b/apps/web/src/state/sagas/transactions/useSwapHandlers.ts index 9e9a1ca11ce..3c1c219199c 100644 --- a/apps/web/src/state/sagas/transactions/useSwapHandlers.ts +++ b/apps/web/src/state/sagas/transactions/useSwapHandlers.ts @@ -61,7 +61,9 @@ export function useSwapHandlers(): SwapHandlers { } = params // Route to appropriate callback based on transaction type - if (isWrap(swapTxContext)) { + const isWrapFlow = isWrap(swapTxContext) + + if (isWrapFlow) { // Handle wrap transactions try { const { inputCurrencyAmount, wrapType } = validateWrapParams(params) @@ -84,23 +86,23 @@ export function useSwapHandlers(): SwapHandlers { } else { // Handle regular swap transactions try { - swapCallback({ - account, - swapTxContext, - currencyInAmountUSD, - currencyOutAmountUSD, - isAutoSlippage, - presetPercentage, - preselectAsset, - onSuccess, - onFailure, - onPending, - txId, - setCurrentStep, - setSteps, - isFiatInputMode, - includesDelegation: swapTxContext.includesDelegation, - }) + swapCallback({ + account, + swapTxContext, + currencyInAmountUSD, + currencyOutAmountUSD, + isAutoSlippage, + presetPercentage, + preselectAsset, + onSuccess, + onFailure, + onPending, + txId, + setCurrentStep, + setSteps, + isFiatInputMode, + includesDelegation: swapTxContext.includesDelegation, + }) } catch (error) { onFailure(error instanceof Error ? error : new Error(String(error))) } diff --git a/apps/web/src/state/sagas/transactions/utils.ts b/apps/web/src/state/sagas/transactions/utils.ts index f0d0d52781f..71442f3e044 100644 --- a/apps/web/src/state/sagas/transactions/utils.ts +++ b/apps/web/src/state/sagas/transactions/utils.ts @@ -1,11 +1,12 @@ /* eslint-disable max-lines */ import { datadogRum } from '@datadog/browser-rum' import type { TransactionResponse } from '@ethersproject/abstract-provider' -import type { JsonRpcSigner, Web3Provider } from '@ethersproject/providers' +import type { JsonRpcSigner, TransactionReceipt as EthersTransactionReceipt, Web3Provider } from '@ethersproject/providers' import { TradeType } from '@uniswap/sdk-core' import { FetchError, TradingApi } from '@universe/api' import { BlockedAsyncSubmissionChainIdsConfigKey, DynamicConfigs, getDynamicConfigValue } from '@universe/gating' import { wagmiConfig } from 'components/Web3Provider/wagmiConfig' +import { Contract } from 'ethers/lib/ethers' import { clientToProvider } from 'hooks/useEthersProvider' import ms from 'ms' import type { Action } from 'redux' @@ -29,6 +30,7 @@ import { finalizeTransaction, interfaceUpdateTransactionInfo, } from 'uniswap/src/features/transactions/slice' +import ERC20_ABI from 'uniswap/src/abis/erc20.json' import { TokenApprovalTransactionStep } from 'uniswap/src/features/transactions/steps/approve' import type { Permit2TransactionStep } from 'uniswap/src/features/transactions/steps/permit2Transaction' import { TokenRevocationTransactionStep } from 'uniswap/src/features/transactions/steps/revoke' @@ -62,6 +64,7 @@ import { TransactionStatus, TransactionType, } from 'uniswap/src/features/transactions/types/transactionDetails' +import { receiptFromEthersReceipt } from 'uniswap/src/features/transactions/utils/receipt' import { getInterfaceTransaction, isInterfaceTransaction } from 'uniswap/src/features/transactions/types/utils' import { areAddressesEqual } from 'uniswap/src/utils/addresses' import { parseERC20ApproveCalldata } from 'uniswap/src/utils/approvals' @@ -126,7 +129,59 @@ export function* handleOnChainStep(params: Han // Avoid sending prompting a transaction if the user already submitted an equivalent tx, e.g. by closing and reopening a transaction flow const duplicativeTx = yield* findDuplicativeTx({ info, address, chainId, allowDuplicativeTx }) - const interfaceDuplicativeTx = duplicativeTx ? getInterfaceTransaction(duplicativeTx) : undefined + let interfaceDuplicativeTx = duplicativeTx ? getInterfaceTransaction(duplicativeTx) : undefined + if ( + interfaceDuplicativeTx && + interfaceDuplicativeTx.hash && + step.type === TransactionStepType.TokenApprovalTransaction && + (chainId === UniverseChainId.HashKey || chainId === UniverseChainId.HashKeyTestnet) + ) { + const allowance = yield* call(fetchTokenAllowance, { + tokenAddress: step.tokenAddress, + owner: address, + spender: step.spender, + }) + const requiredAmount = BigInt(step.amount) + + if (allowance !== null && allowance < requiredAmount) { + // Allow prompting a fresh approval if on-chain allowance is still insufficient. + interfaceDuplicativeTx = undefined + } else if (interfaceDuplicativeTx.status === TransactionStatus.Pending) { + const receipt = yield* call(fetchTransactionReceipt, interfaceDuplicativeTx.hash) + const resolvedStatus = + receipt?.status === 1 ? TransactionStatus.Success : receipt ? TransactionStatus.Failed : undefined + if (resolvedStatus) { + const adaptedReceipt = receiptFromEthersReceipt(receipt) + yield* put( + finalizeTransaction({ + ...interfaceDuplicativeTx, + status: resolvedStatus, + receipt: adaptedReceipt, + hash: interfaceDuplicativeTx.hash, + }), + ) + interfaceDuplicativeTx = undefined + } else if (allowance !== null && allowance >= requiredAmount) { + const fallbackReceipt: TransactionReceipt = { + transactionIndex: 0, + blockHash: interfaceDuplicativeTx.hash, + blockNumber: 0, + confirmedTime: Date.now(), + gasUsed: 0, + effectiveGasPrice: 0, + } + yield* put( + finalizeTransaction({ + ...interfaceDuplicativeTx, + status: TransactionStatus.Success, + receipt: fallbackReceipt, + hash: interfaceDuplicativeTx.hash, + }), + ) + interfaceDuplicativeTx = undefined + } + } + } if (interfaceDuplicativeTx && interfaceDuplicativeTx.hash) { if (interfaceDuplicativeTx.status === TransactionStatus.Success) { addTransactionBreadcrumb({ @@ -419,6 +474,31 @@ function checkApprovalAmount(data: string, step: TokenApprovalTransactionStep | return { isInsufficient: submitted.amount < requiredAmount, approvedAmount } } +async function fetchTokenAllowance(params: { + tokenAddress: Address + owner: Address + spender: Address +}): Promise { + const { tokenAddress, owner, spender } = params + try { + const provider = await getProvider() + const contract = new Contract(tokenAddress, ERC20_ABI, provider) + const allowance = await contract.allowance(owner, spender) + return BigInt(allowance.toString()) + } catch { + return null + } +} + +async function fetchTransactionReceipt(hash: HexString): Promise { + try { + const provider = await getProvider() + return await provider.getTransactionReceipt(hash) + } catch { + return undefined + } +} + function isRecentTx(tx: InterfaceTransactionDetails | TransactionDetails) { const currentTime = Date.now() const failed = tx.status === TransactionStatus.Failed diff --git a/packages/uniswap/src/features/transactions/swap/review/SwapReviewScreen/SwapReviewFooter/SwapReviewFooter.tsx b/packages/uniswap/src/features/transactions/swap/review/SwapReviewScreen/SwapReviewFooter/SwapReviewFooter.tsx index f9e0bc461d1..a292b403fdc 100644 --- a/packages/uniswap/src/features/transactions/swap/review/SwapReviewScreen/SwapReviewFooter/SwapReviewFooter.tsx +++ b/packages/uniswap/src/features/transactions/swap/review/SwapReviewScreen/SwapReviewFooter/SwapReviewFooter.tsx @@ -2,7 +2,6 @@ import { memo, useMemo } from 'react' import { Flex, IconButton, useIsShortMobileDevice } from 'ui/src' import { BackArrow } from 'ui/src/components/icons/BackArrow' import type { Warning } from 'uniswap/src/components/modals/WarningModal/types' -import { UniverseChainId } from 'uniswap/src/features/chains/types' import { TransactionModalFooterContainer } from 'uniswap/src/features/transactions/components/TransactionModal/TransactionModal' import { useSwapOnPrevious } from 'uniswap/src/features/transactions/swap/review/hooks/useSwapOnPrevious' import { SubmitSwapButton } from 'uniswap/src/features/transactions/swap/review/SwapReviewScreen/SwapReviewFooter/SubmitSwapButton' diff --git a/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.test.ts b/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.test.ts index d92ed919f55..3b67b85da76 100644 --- a/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.test.ts +++ b/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.test.ts @@ -1,12 +1,14 @@ -import { renderHook } from '@testing-library/react' +import { renderHook, waitFor } from '@testing-library/react' import { CurrencyAmount, Token } from '@uniswap/sdk-core' import { FeeType, GasEstimate, TradingApi } from '@universe/api' +import { Contract } from 'ethers/lib/ethers' import { DAI, USDC } from 'uniswap/src/constants/tokens' import { useCheckApprovalQuery } from 'uniswap/src/data/apiClients/tradingApi/useCheckApprovalQuery' import { AccountType } from 'uniswap/src/features/accounts/types' import { UniverseChainId } from 'uniswap/src/features/chains/types' import { DEFAULT_GAS_STRATEGY } from 'uniswap/src/features/gas/utils' import { Platform } from 'uniswap/src/features/platforms/types/Platform' +import { createEthersProvider } from 'uniswap/src/features/providers/createEthersProvider' import type { TokenApprovalInfoParams } from 'uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo' import { useTokenApprovalInfo } from 'uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo' import { ApprovalAction } from 'uniswap/src/features/transactions/swap/types/trade' @@ -15,12 +17,20 @@ import { SignerMnemonicAccountDetails } from 'uniswap/src/features/wallet/types/ import { logger } from 'utilities/src/logger/logger' jest.mock('uniswap/src/data/apiClients/tradingApi/useCheckApprovalQuery') +jest.mock('uniswap/src/features/providers/createEthersProvider', () => ({ + createEthersProvider: jest.fn(), +})) +jest.mock('ethers/lib/ethers', () => ({ + Contract: jest.fn(), +})) jest.mock('utilities/src/logger/logger', () => ({ logger: { error: jest.fn(), }, })) const mockUseCheckApprovalQuery = useCheckApprovalQuery as jest.Mock +const mockCreateEthersProvider = createEthersProvider as jest.Mock +const mockContract = Contract as jest.Mock describe('useTokenApprovalInfo', () => { const mockAccount: SignerMnemonicAccountDetails = { @@ -179,4 +189,91 @@ describe('useTokenApprovalInfo', () => { }, }) }) + + it('uses on-chain allowance for HashKey chains and skips approval when allowance is sufficient', async () => { + const hashKeyTokenIn = new Token( + UniverseChainId.HashKeyTestnet, + DAI.address, + DAI.decimals, + DAI.symbol, + DAI.name, + ) + const hashKeyTokenOut = new Token( + UniverseChainId.HashKeyTestnet, + USDC.address, + USDC.decimals, + USDC.symbol, + USDC.name, + ) + const hashKeyParams: TokenApprovalInfoParams = { + ...mockParams, + chainId: UniverseChainId.HashKeyTestnet, + currencyInAmount: CurrencyAmount.fromRawAmount(hashKeyTokenIn, mockCurrencyInAmount.quotient), + currencyOutAmount: CurrencyAmount.fromRawAmount(hashKeyTokenOut, mockCurrencyOutAmount.quotient), + } + + mockUseCheckApprovalQuery.mockReturnValue({ + data: undefined, + isLoading: false, + error: null, + }) + mockCreateEthersProvider.mockReturnValue({}) + mockContract.mockImplementation(() => ({ + allowance: jest.fn().mockResolvedValue({ + toString: () => mockCurrencyInAmount.quotient.toString(), + }), + })) + + const { result } = renderHook(() => useTokenApprovalInfo(hashKeyParams)) + + await waitFor(() => { + expect(result.current.tokenApprovalInfo.action).toBe(ApprovalAction.None) + }) + }) + + it('uses on-chain allowance for HashKey chains and returns approval tx when allowance is insufficient', async () => { + const hashKeyTokenIn = new Token( + UniverseChainId.HashKeyTestnet, + DAI.address, + DAI.decimals, + DAI.symbol, + DAI.name, + ) + const hashKeyParams: TokenApprovalInfoParams = { + ...mockParams, + chainId: UniverseChainId.HashKeyTestnet, + currencyInAmount: CurrencyAmount.fromRawAmount(hashKeyTokenIn, mockCurrencyInAmount.quotient), + currencyOutAmount: undefined, + } + + mockUseCheckApprovalQuery.mockReturnValue({ + data: undefined, + isLoading: false, + error: null, + }) + mockCreateEthersProvider.mockReturnValue({}) + mockContract.mockImplementation(() => ({ + allowance: jest.fn().mockResolvedValue({ + toString: () => '0', + }), + })) + + const { result } = renderHook(() => useTokenApprovalInfo(hashKeyParams)) + + await waitFor(() => { + expect(result.current.tokenApprovalInfo.action).toBe(ApprovalAction.Permit2Approve) + }) + + expect(result.current.tokenApprovalInfo).toMatchObject({ + action: ApprovalAction.Permit2Approve, + txRequest: { + to: hashKeyTokenIn.address, + chainId: UniverseChainId.HashKeyTestnet, + value: '0x0', + }, + cancelTxRequest: null, + }) + const txData = result.current.tokenApprovalInfo.txRequest?.data?.toString() ?? '' + expect(txData.startsWith('0x095ea7b3')).toBe(true) + }) }) diff --git a/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.ts b/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.ts index 54313bafa73..b5f0cc31a8c 100644 --- a/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.ts +++ b/packages/uniswap/src/features/transactions/swap/review/hooks/useTokenApprovalInfo.ts @@ -1,13 +1,18 @@ import { Currency, CurrencyAmount } from '@uniswap/sdk-core' import { TradingApi } from '@universe/api' -import { useMemo } from 'react' +import { Interface } from '@ethersproject/abi' +import { Contract } from 'ethers/lib/ethers' +import { useEffect, useMemo, useState } from 'react' +import ERC20_ABI from 'uniswap/src/abis/erc20.json' import { useUniswapContextSelector } from 'uniswap/src/contexts/UniswapContext' import { useCheckApprovalQuery } from 'uniswap/src/data/apiClients/tradingApi/useCheckApprovalQuery' import { UniverseChainId } from 'uniswap/src/features/chains/types' import { convertGasFeeToDisplayValue, useActiveGasStrategy } from 'uniswap/src/features/gas/hooks' import { GasFeeResult } from 'uniswap/src/features/gas/types' +import { createEthersProvider } from 'uniswap/src/features/providers/createEthersProvider' import { ApprovalAction, TokenApprovalInfo } from 'uniswap/src/features/transactions/swap/types/trade' import { isUniswapX } from 'uniswap/src/features/transactions/swap/utils/routing' +import { CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS } from 'uniswap/src/features/transactions/swap/components/UnichainInstantBalanceModal/constants' import { getTokenAddressForApi, toTradingApiSupportedChainId, @@ -61,6 +66,7 @@ export function useTokenApprovalInfo(params: TokenApprovalInfoParams): ApprovalT const currencyIn = inputWillBeWrapped ? currencyInAmount?.currency.wrapped : currencyInAmount?.currency const amount = currencyInAmount?.quotient.toString() + const tokenInAllowanceAddress = currencyIn?.isNative ? undefined : currencyIn?.wrapped.address const tokenInAddress = getTokenAddressForApi(currencyIn) // Only used for bridging @@ -69,6 +75,85 @@ export function useTokenApprovalInfo(params: TokenApprovalInfoParams): ApprovalT const tokenOutAddress = getTokenAddressForApi(currencyOut) const gasStrategy = useActiveGasStrategy(chainId, 'general') + const erc20Interface = useMemo(() => new Interface(ERC20_ABI), []) + + const approvalWillBeBatchedWithSwap = useApprovalWillBeBatchedWithSwap(chainId, routing) + + const hskRouterAddress = useMemo(() => { + if (!isHashKeyChain) { + return undefined + } + return CHAIN_TO_UNIVERSAL_ROUTER_ADDRESS[chainId]?.[0] + }, [chainId, isHashKeyChain]) + + const [allowanceState, setAllowanceState] = useState<{ + value: string | undefined + isLoading: boolean + error: Error | null + }>({ + value: undefined, + isLoading: false, + error: null, + }) + + const shouldCheckOnchainAllowance = Boolean( + isHashKeyChain && + !isWrap && + !approvalWillBeBatchedWithSwap && + !isChained && + address && + amount && + tokenInAllowanceAddress && + hskRouterAddress, + ) + + useEffect(() => { + if (!shouldCheckOnchainAllowance) { + setAllowanceState((prev) => + prev.value || prev.isLoading || prev.error ? { value: undefined, isLoading: false, error: null } : prev, + ) + return + } + + const provider = createEthersProvider({ chainId }) + if (!provider) { + setAllowanceState({ + value: undefined, + isLoading: false, + error: new Error('No RPC provider available for HashKey allowance check'), + }) + return + } + + let cancelled = false + setAllowanceState((prev) => ({ ...prev, isLoading: true, error: null })) + + ;(async () => { + try { + const erc20Contract = new Contract(tokenInAllowanceAddress as string, ERC20_ABI, provider) + const allowance = await erc20Contract.allowance(address, hskRouterAddress as string) + if (!cancelled) { + setAllowanceState({ value: allowance.toString(), isLoading: false, error: null }) + } + } catch (err) { + if (!cancelled) { + const error = err instanceof Error ? err : new Error('Allowance check failed') + setAllowanceState({ value: undefined, isLoading: false, error }) + } + } + })() + + return () => { + cancelled = true + } + }, [ + address, + amount, + chainId, + hskRouterAddress, + shouldCheckOnchainAllowance, + tokenInAllowanceAddress, + ]) const approvalRequestArgs: TradingApi.ApprovalRequest | undefined = useMemo(() => { const tokenInChainId = toTradingApiSupportedChainId(chainId) @@ -103,8 +188,8 @@ export function useTokenApprovalInfo(params: TokenApprovalInfoParams): ApprovalT tokenOutAddress, ]) - const approvalWillBeBatchedWithSwap = useApprovalWillBeBatchedWithSwap(chainId, routing) - const shouldSkip = !approvalRequestArgs || isWrap || !address || approvalWillBeBatchedWithSwap || isChained + const shouldSkip = + !approvalRequestArgs || isWrap || !address || approvalWillBeBatchedWithSwap || isChained || isHashKeyChain const { data, isLoading, error } = useCheckApprovalQuery({ params: shouldSkip ? undefined : approvalRequestArgs, @@ -123,6 +208,75 @@ export function useTokenApprovalInfo(params: TokenApprovalInfoParams): ApprovalT }) } + if (isHashKeyChain) { + if (allowanceState.error) { + logger.error(allowanceState.error, { + tags: { file: 'useTokenApprovalInfo', function: 'useTokenApprovalInfo' }, + extra: { + address, + amount, + chainId, + hskRouterAddress, + tokenInAddress: tokenInAllowanceAddress, + }, + }) + } + + if (isWrap || !address || approvalWillBeBatchedWithSwap || isChained) { + return { + action: ApprovalAction.None, + txRequest: null, + cancelTxRequest: null, + } + } + + if (!tokenInAllowanceAddress || currencyIn?.isNative) { + return { + action: ApprovalAction.None, + txRequest: null, + cancelTxRequest: null, + } + } + + if (!shouldCheckOnchainAllowance || allowanceState.isLoading || !allowanceState.value || !amount) { + return { + action: ApprovalAction.Unknown, + txRequest: null, + cancelTxRequest: null, + } + } + + try { + const hasAllowance = BigInt(allowanceState.value) >= BigInt(amount) + if (hasAllowance) { + return { + action: ApprovalAction.None, + txRequest: null, + cancelTxRequest: null, + } + } + } catch { + return { + action: ApprovalAction.Unknown, + txRequest: null, + cancelTxRequest: null, + } + } + + const txRequest = { + to: tokenInAllowanceAddress, + data: erc20Interface.encodeFunctionData('approve', [hskRouterAddress as string, amount]), + value: '0x0', + chainId, + } + + return { + action: ApprovalAction.Permit2Approve, + txRequest, + cancelTxRequest: null, + } + } + // Approval is N/A for wrap transactions or unconnected state. if (isWrap || !address || approvalWillBeBatchedWithSwap || isChained) { return { @@ -170,19 +324,40 @@ export function useTokenApprovalInfo(params: TokenApprovalInfoParams): ApprovalT txRequest: null, cancelTxRequest: null, } - }, [address, approvalRequestArgs, approvalWillBeBatchedWithSwap, data, error, isWrap, isChained]) + }, [ + address, + allowanceState.error, + allowanceState.isLoading, + allowanceState.value, + amount, + approvalRequestArgs, + approvalWillBeBatchedWithSwap, + chainId, + currencyIn?.isNative, + data, + error, + erc20Interface, + hskRouterAddress, + isChained, + isHashKeyChain, + isWrap, + shouldCheckOnchainAllowance, + tokenInAllowanceAddress, + ]) return useMemo(() => { - const gasEstimate = data?.gasEstimates?.[0] + const gasEstimate = isHashKeyChain ? undefined : data?.gasEstimates?.[0] const noApprovalNeeded = tokenApprovalInfo.action === ApprovalAction.None const noRevokeNeeded = tokenApprovalInfo.action === ApprovalAction.Permit2Approve || tokenApprovalInfo.action === ApprovalAction.None - const approvalFee = noApprovalNeeded ? '0' : data?.gasFee - const revokeFee = noRevokeNeeded ? '0' : data?.cancelGasFee + const approvalFee = noApprovalNeeded ? '0' : isHashKeyChain ? undefined : data?.gasFee + const revokeFee = noRevokeNeeded ? '0' : isHashKeyChain ? undefined : data?.cancelGasFee const unknownApproval = tokenApprovalInfo.action === ApprovalAction.Unknown - const isGasLoading = unknownApproval && isLoading - const approvalGasError = unknownApproval && !isLoading ? new Error('Approval action unknown') : null + const isApprovalLoading = isHashKeyChain ? allowanceState.isLoading : isLoading + const approvalGasError = + allowanceState.error ?? (unknownApproval && !isApprovalLoading ? new Error('Approval action unknown') : null) + const isGasLoading = unknownApproval && isApprovalLoading return { tokenApprovalInfo, @@ -200,5 +375,15 @@ export function useTokenApprovalInfo(params: TokenApprovalInfoParams): ApprovalT error: approvalGasError, }, } - }, [gasStrategy, data?.cancelGasFee, data?.gasEstimates, data?.gasFee, isLoading, tokenApprovalInfo]) + }, [ + allowanceState.error, + allowanceState.isLoading, + data?.cancelGasFee, + data?.gasEstimates, + data?.gasFee, + gasStrategy, + isHashKeyChain, + isLoading, + tokenApprovalInfo, + ]) } diff --git a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts index 25407564d92..e849a4f35f9 100644 --- a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts +++ b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts @@ -522,6 +522,17 @@ export function createProcessSwapResponse({ gasStrategy }: { gasStrategy: GasStr } } + // HashKey does not provide reliable gas simulation via backend; allow swap flow to proceed. + if (isHashKeyChain) { + if (gasFeeResult.value === undefined) { + gasFeeResult.value = '0' + gasFeeResult.displayValue = '0' + } + if (gasFeeResult.error) { + gasFeeResult.error = null + } + } + return { gasFeeResult, txRequests, diff --git a/packages/uniswap/src/features/transactions/swap/utils/generateSwapTransactionSteps.ts b/packages/uniswap/src/features/transactions/swap/utils/generateSwapTransactionSteps.ts index 16c805095a9..ed4661bf6a8 100644 --- a/packages/uniswap/src/features/transactions/swap/utils/generateSwapTransactionSteps.ts +++ b/packages/uniswap/src/features/transactions/swap/utils/generateSwapTransactionSteps.ts @@ -14,7 +14,6 @@ import { import { orderUniswapXSteps } from 'uniswap/src/features/transactions/swap/steps/uniswapxSteps' import { isValidSwapTxContext, SwapTxAndGasInfo } from 'uniswap/src/features/transactions/swap/types/swapTxAndGasInfo' import { isBridge, isClassic, isUniswapX } from 'uniswap/src/features/transactions/swap/utils/routing' -import { UniverseChainId } from 'uniswap/src/features/chains/types' import type { ValidatedTransactionRequest } from 'uniswap/src/features/transactions/types/transactionRequests' function buildHashKeyApprovalTxRequest({ From ee33e8e8291a74a57f18f9e761513a03182d702a Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Fri, 23 Jan 2026 14:15:33 +0800 Subject: [PATCH 20/33] feat: fix review --- .../Overview/hooks/useIsPortfolioZero.ts | 32 +++++++++++++- .../src/state/sagas/transactions/swapSaga.ts | 6 +-- .../providers/webForNudgeProvider.tsx | 4 +- .../hooks/useIsPortfolioZero.ts | 4 +- .../hooks/useSwapFormButtonText.ts | 42 +++++-------------- .../swap/services/prepareSwapService.ts | 2 +- 6 files changed, 47 insertions(+), 43 deletions(-) diff --git a/apps/web/src/pages/Portfolio/Overview/hooks/useIsPortfolioZero.ts b/apps/web/src/pages/Portfolio/Overview/hooks/useIsPortfolioZero.ts index c4f16c0ed74..83a1c629089 100644 --- a/apps/web/src/pages/Portfolio/Overview/hooks/useIsPortfolioZero.ts +++ b/apps/web/src/pages/Portfolio/Overview/hooks/useIsPortfolioZero.ts @@ -1,5 +1,10 @@ +import { useCurrencyBalances } from 'lib/hooks/useCurrencyBalance' import { usePortfolioAddresses } from 'pages/Portfolio/hooks/usePortfolioAddresses' import { useMemo } from 'react' +import { useAccount } from 'hooks/useAccount' +import { getStablecoinsForChain } from 'uniswap/src/features/chains/utils' +import { UniverseChainId } from 'uniswap/src/features/chains/types' +import { nativeOnChain } from 'uniswap/src/constants/tokens' import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' import { usePortfolioTotalValue } from 'uniswap/src/features/dataApi/balances/balancesRest' @@ -10,6 +15,25 @@ import { usePortfolioTotalValue } from 'uniswap/src/features/dataApi/balances/ba export function useIsPortfolioZero(): boolean { const portfolioAddresses = usePortfolioAddresses() const { isTestnetModeEnabled } = useEnabledChains() + const { chainId } = useAccount() + const isHashKeyChain = + chainId === UniverseChainId.HashKey || chainId === UniverseChainId.HashKeyTestnet + + const hskCurrencies = useMemo(() => { + if (!isHashKeyChain || !chainId) { + return undefined + } + + const nativeCurrency = nativeOnChain(chainId) + const stablecoins = getStablecoinsForChain(chainId) + return [nativeCurrency, ...stablecoins] + }, [chainId, isHashKeyChain]) + + const hskBalances = useCurrencyBalances(portfolioAddresses.evmAddress, hskCurrencies) + const hasNonZeroHskBalance = useMemo( + () => hskBalances.some((balance) => balance?.greaterThan(0)), + [hskBalances], + ) // Fetch portfolio total value to determine if portfolio is zero const { data: portfolioData } = usePortfolioTotalValue({ @@ -20,5 +44,11 @@ export function useIsPortfolioZero(): boolean { const { balanceUSD } = portfolioData || {} // Calculate isPortfolioZero - denominated portfolio balance on testnet is always 0 - return useMemo(() => !isTestnetModeEnabled && balanceUSD === 0, [isTestnetModeEnabled, balanceUSD]) + const defaultIsPortfolioZero = useMemo( + () => !isTestnetModeEnabled && balanceUSD === 0, + [isTestnetModeEnabled, balanceUSD], + ) + + // TODO(HSK): Replace on-chain fallback with a dedicated portfolio/price service for HashKey. + return isHashKeyChain ? !hasNonZeroHskBalance : defaultIsPortfolioZero } diff --git a/apps/web/src/state/sagas/transactions/swapSaga.ts b/apps/web/src/state/sagas/transactions/swapSaga.ts index 87cf69e7b70..0675209fc42 100644 --- a/apps/web/src/state/sagas/transactions/swapSaga.ts +++ b/apps/web/src/state/sagas/transactions/swapSaga.ts @@ -520,9 +520,7 @@ function* swap(params: SwapParams) { setSteps, } = params const { trade } = swapTxContext - const swapChainId = swapTxContext.trade.inputAmount.currency.chainId - const { chainSwitchFailed } = yield* call(handleSwitchChains, { selectChain: params.selectChain, startChainId: params.startChainId, @@ -673,6 +671,7 @@ export function useSwapCallback(): SwapCallback { onPending, } = args const { trade, gasFee } = swapTxContext + const chainId = trade.inputAmount.currency.chainId const isClassicSwap = isClassic(swapTxContext) const isBatched = isClassicSwap && swapTxContext.txRequests && swapTxContext.txRequests.length > 1 @@ -692,8 +691,7 @@ export function useSwapCallback(): SwapCallback { swapStartTimestamp, }) - const account = isSVMChain(trade.inputAmount.currency.chainId) ? wallet.svmAccount : wallet.evmAccount - + const account = isSVMChain(chainId) ? wallet.svmAccount : wallet.evmAccount if (!account || !isSignerMnemonicAccountDetails(account)) { throw new Error('No account found') } diff --git a/packages/uniswap/src/features/providers/webForNudgeProvider.tsx b/packages/uniswap/src/features/providers/webForNudgeProvider.tsx index ee844ede604..0051c83d2fd 100644 --- a/packages/uniswap/src/features/providers/webForNudgeProvider.tsx +++ b/packages/uniswap/src/features/providers/webForNudgeProvider.tsx @@ -45,9 +45,7 @@ export function useWebFORNudgeGateEnabled(): boolean { // If wallet can pay gas in any token (e.g., Porto wallet), don't show the nudge const canPayGasInAnyToken = getCanPayGasInAnyToken?.() ?? false - const result = isWebFORNudgeEnabled && isPortfolioZero && !canPayGasInAnyToken - - return result + return isWebFORNudgeEnabled && isPortfolioZero && !canPayGasInAnyToken } export function useIsWebFORNudgeEnabled(): boolean { diff --git a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsPortfolioZero.ts b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsPortfolioZero.ts index 6c209b9a7bd..7e4c493c6bc 100644 --- a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsPortfolioZero.ts +++ b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useIsPortfolioZero.ts @@ -11,7 +11,5 @@ export function useIsPortfolioZero(): boolean { svmAddress: wallet.svmAccount?.address, }) - const result = !isTestnetModeEnabled && balanceUSD === 0 - - return result + return !isTestnetModeEnabled && balanceUSD === 0 } diff --git a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useSwapFormButtonText.ts b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useSwapFormButtonText.ts index be565d133cc..9d10dce2ffa 100644 --- a/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useSwapFormButtonText.ts +++ b/packages/uniswap/src/features/transactions/swap/components/SwapFormButton/hooks/useSwapFormButtonText.ts @@ -42,49 +42,29 @@ export const useSwapFormButtonText = (): string => { if (swapRedirectCallback) { return t('common.getStarted') - } - - if (isWebFORNudgeEnabled) { + } else if (isWebFORNudgeEnabled) { return t('empty.swap.button.text') - } - - if (isIndicative) { + } else if (isIndicative) { return t('swap.finalizingQuote') - } - - if (isDisconnected) { + } else if (isDisconnected) { return isLogIn ? t('nav.logIn.button') : t('common.connectWallet.button') - } - - if (isMissingPlatformWallet) { + } else if (isMissingPlatformWallet) { return t('common.connectTo', { platform: isSVMChain(chainId) ? 'Solana' : 'Ethereum' }) - } - - if (blockingWarning?.buttonText) { + } else if (blockingWarning?.buttonText) { return blockingWarning.buttonText - } - - if (isTokenSelectionInvalid) { + } else if (isTokenSelectionInvalid) { return t('common.selectToken.label') - } - - if (isAmountSelectionInvalid) { + } else if (isAmountSelectionInvalid) { return t('common.noAmount.error') - } - - if (insufficientBalanceWarning) { + } else if (insufficientBalanceWarning) { return t('common.insufficientTokenBalance.error.simple', { tokenSymbol: currencies[CurrencyField.INPUT]?.currency.symbol ?? '', }) - } - - if (insufficientGasFundsWarning) { + } else if (insufficientGasFundsWarning) { return t('common.insufficientTokenBalance.error.simple', { tokenSymbol: nativeCurrency.symbol ?? '' }) - } - - if (isWrap) { + } else if (isWrap) { return getActionText({ t, wrapType }) } - return t('swap.button.review') + return t('empty.swap.button.text') } diff --git a/packages/uniswap/src/features/transactions/swap/services/prepareSwapService.ts b/packages/uniswap/src/features/transactions/swap/services/prepareSwapService.ts index 22c34e60a33..a0749e585ca 100644 --- a/packages/uniswap/src/features/transactions/swap/services/prepareSwapService.ts +++ b/packages/uniswap/src/features/transactions/swap/services/prepareSwapService.ts @@ -203,7 +203,7 @@ function createHandleEventAction(ctx: HandleEventActionContext): (action: Review if (onExecuteSwapDirectly) { onExecuteSwapDirectly() } else { - setScreen(TransactionScreen.Review) + setScreen(TransactionScreen.Review) } break } From a3d92e1a988232b2699113c28c79f1d8492a4d34 Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Fri, 23 Jan 2026 14:32:58 +0800 Subject: [PATCH 21/33] feat: update gaslimit --- .../swap/review/services/swapTxAndGasInfoService/utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts index e849a4f35f9..7d60e05aaba 100644 --- a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts +++ b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/utils.ts @@ -364,7 +364,7 @@ function buildTxRequestFromQuote( } const isHashKey = chainId === UniverseChainId.HashKey || chainId === UniverseChainId.HashKeyTestnet const gasLimitBuffered = getGasLimitWithBuffer(quoteWithGasEstimate.gasUseEstimate, { - multiplier: isHashKey ? 1.6 : 1.2, + multiplier: isHashKey ? 2.0 : 1.5, }) if (gasLimitBuffered) { txRequest.gasLimit = gasLimitBuffered @@ -391,7 +391,7 @@ function buildTxRequestFromTrade( : undefined const gasLimitBuffered = getGasLimitWithBuffer((trade as any)?.quote?.quote?.gasUseEstimate, { - multiplier: chainId === UniverseChainId.HashKey || chainId === UniverseChainId.HashKeyTestnet ? 1.6 : 1.2, + multiplier: chainId === UniverseChainId.HashKey || chainId === UniverseChainId.HashKeyTestnet ? 2.0 : 1.2, }) const { calldata, value } = V3SwapRouter.swapCallParameters(trade, { From 20771f7f7cac1bcc5f5f0026974146f2b5781723 Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Fri, 23 Jan 2026 15:53:32 +0800 Subject: [PATCH 22/33] feat: udpate quote --- .../transactions/swap/hooks/useTrade.ts | 16 ++++-- .../hooks/useTrade/parseQuoteCurrencies.ts | 29 ++++++++-- .../swap/hooks/useTrade/useTradeQuery.ts | 21 ++++++- .../useTrade/useTradeServiceQueryOptions.ts | 49 +++++++++++++++- .../transformations/buildQuoteRequest.ts | 57 +++++++++++++++++-- .../swapFormStore/hooks/useDerivedSwapInfo.ts | 11 ++++ .../features/transactions/swap/types/trade.ts | 5 ++ 7 files changed, 168 insertions(+), 20 deletions(-) diff --git a/packages/uniswap/src/features/transactions/swap/hooks/useTrade.ts b/packages/uniswap/src/features/transactions/swap/hooks/useTrade.ts index 7b95c661fb2..28ba3dc3637 100644 --- a/packages/uniswap/src/features/transactions/swap/hooks/useTrade.ts +++ b/packages/uniswap/src/features/transactions/swap/hooks/useTrade.ts @@ -1,10 +1,10 @@ import { Currency } from '@uniswap/sdk-core' import { useMemo } from 'react' import { parseQuoteCurrencies } from 'uniswap/src/features/transactions/swap/hooks/useTrade/parseQuoteCurrencies' -import { useIndicativeTradeQuery } from 'uniswap/src/features/transactions/swap/hooks/useTrade/useIndicativeTradeQuery' import { useTradeQuery } from 'uniswap/src/features/transactions/swap/hooks/useTrade/useTradeQuery' import type { TradeWithGasEstimates } from 'uniswap/src/features/transactions/swap/services/tradeService/tradeService' import { TradeWithStatus, UseTradeArgs } from 'uniswap/src/features/transactions/swap/types/trade' +import type { IndicativeTrade } from 'uniswap/src/features/transactions/swap/types/trade' // error strings hardcoded in @uniswap/unified-routing-api // https://github.com/Uniswap/unified-routing-api/blob/020ea371a00d4cc25ce9f9906479b00a43c65f2c/lib/util/errors.ts#L4 @@ -15,8 +15,16 @@ export const API_RATE_LIMIT_ERROR = 'TOO_MANY_REQUESTS' export function useTrade(params: UseTradeArgs): TradeWithStatus { const { error, data, isLoading: queryIsLoading, isFetching } = useTradeQuery(params) const isLoading = (params.amountSpecified && params.isDebouncing) || queryIsLoading - const indicative = useIndicativeTradeQuery(params) - const { currencyIn, currencyOut } = parseQuoteCurrencies(params) + // Disable indicative quote to ensure single source of quote requests + // This prevents duplicate requests and ensures consistency + const indicative = { trade: undefined, isLoading: false } + const { currencyIn, currencyOut } = parseQuoteCurrencies({ + tradeType: params.tradeType, + amountSpecified: params.amountSpecified, + otherCurrency: params.otherCurrency, + sellToken: params.sellToken, + buyToken: params.buyToken, + }) return useMemo(() => { return parseTradeResult({ @@ -38,7 +46,7 @@ function parseTradeResult(input: { currencyOut?: Currency isLoading: boolean isFetching: boolean - indicative: ReturnType + indicative: { trade: IndicativeTrade | undefined; isLoading: boolean } error: Error | null isDebouncing?: boolean }): TradeWithStatus { diff --git a/packages/uniswap/src/features/transactions/swap/hooks/useTrade/parseQuoteCurrencies.ts b/packages/uniswap/src/features/transactions/swap/hooks/useTrade/parseQuoteCurrencies.ts index 713087857cd..fe325cd2b51 100644 --- a/packages/uniswap/src/features/transactions/swap/hooks/useTrade/parseQuoteCurrencies.ts +++ b/packages/uniswap/src/features/transactions/swap/hooks/useTrade/parseQuoteCurrencies.ts @@ -6,6 +6,9 @@ interface ParseQuoteCurrenciesInput { tradeType: SdkTradeType amountSpecified?: CurrencyAmount | null otherCurrency?: Currency | null + // Explicit sell and buy tokens from UI to ensure consistency + sellToken?: Currency + buyToken?: Currency } export interface QuoteCurrencyData { @@ -15,17 +18,31 @@ export interface QuoteCurrencyData { } export function parseQuoteCurrencies(input: ParseQuoteCurrenciesInput): QuoteCurrencyData { - const { tradeType, amountSpecified, otherCurrency } = input - - const currencyIn = tradeType === SdkTradeType.EXACT_INPUT ? amountSpecified?.currency : otherCurrency - const currencyOut = tradeType === SdkTradeType.EXACT_OUTPUT ? amountSpecified?.currency : otherCurrency + const { tradeType, amountSpecified, otherCurrency, sellToken, buyToken } = input + + // CRITICAL: If explicit sellToken and buyToken are provided, use them directly + // This ensures tokenIn/tokenOut always match UI's sell/buy tokens + // If either is missing, we should NOT use fallback logic as it may use stale/incorrect values + if (sellToken && buyToken) { + const requestTradeType = + tradeType === SdkTradeType.EXACT_INPUT ? TradingApi.TradeType.EXACT_INPUT : TradingApi.TradeType.EXACT_OUTPUT + + return { + currencyIn: sellToken, + currencyOut: buyToken, + requestTradeType, + } + } + // If sellToken or buyToken is missing, return undefined to prevent incorrect quote requests + // This ensures we only send requests when we have explicit UI state, not inferred state + // The skip flag in useDerivedSwapInfo should prevent this from being called, but this is a safety check const requestTradeType = tradeType === SdkTradeType.EXACT_INPUT ? TradingApi.TradeType.EXACT_INPUT : TradingApi.TradeType.EXACT_OUTPUT return { - currencyIn: currencyIn ?? undefined, - currencyOut: currencyOut ?? undefined, + currencyIn: undefined, + currencyOut: undefined, requestTradeType, } } diff --git a/packages/uniswap/src/features/transactions/swap/hooks/useTrade/useTradeQuery.ts b/packages/uniswap/src/features/transactions/swap/hooks/useTrade/useTradeQuery.ts index aa17f35c9f1..fdff03f9a36 100644 --- a/packages/uniswap/src/features/transactions/swap/hooks/useTrade/useTradeQuery.ts +++ b/packages/uniswap/src/features/transactions/swap/hooks/useTrade/useTradeQuery.ts @@ -11,15 +11,32 @@ import { useEvent } from 'utilities/src/react/hooks' import { ONE_SECOND_MS } from 'utilities/src/time/time' export function useTradeQuery(params: UseTradeArgs): UseQueryResult { - const quoteCurrencyData = parseQuoteCurrencies(params) + const quoteCurrencyData = parseQuoteCurrencies({ + tradeType: params.tradeType, + amountSpecified: params.amountSpecified, + otherCurrency: params.otherCurrency, + sellToken: params.sellToken, + buyToken: params.buyToken, + }) + + // CRITICAL: If currencyIn or currencyOut is undefined, the query should be disabled + // This prevents sending quote requests with missing or incorrect tokens + const isQueryEnabled = !params.skip && !!quoteCurrencyData.currencyIn && !!quoteCurrencyData.currencyOut + const pollingIntervalForChain = usePollingIntervalByChain(quoteCurrencyData.currencyIn?.chainId) const internalPollInterval = params.pollInterval ?? pollingIntervalForChain const tradeService = useTradeService() const getTradeQueryOptions = useEvent(createTradeServiceQueryOptions({ tradeService })) + const baseQueryOptions = getTradeQueryOptions(params) const response = useQueryWithImmediateGarbageCollection({ - ...getTradeQueryOptions(params), + ...baseQueryOptions, + // Override enabled flag to ensure query is disabled if currencies are missing + enabled: isQueryEnabled && baseQueryOptions.enabled, refetchInterval: internalPollInterval, + // Set staleTime to prevent duplicate requests within the polling interval + // This ensures we don't refetch if data is still fresh, even if query key changes + staleTime: internalPollInterval, // We set the `gcTime` to 15 seconds longer than the refetch interval so that there's more than enough time for a refetch to complete before we clear the stale data. // If the user loses internet connection (or leaves the app and comes back) for longer than this, // then we clear stale data and show a big loading spinner in the swap review screen. diff --git a/packages/uniswap/src/features/transactions/swap/hooks/useTrade/useTradeServiceQueryOptions.ts b/packages/uniswap/src/features/transactions/swap/hooks/useTrade/useTradeServiceQueryOptions.ts index 9610082f01a..532aa05e2a5 100644 --- a/packages/uniswap/src/features/transactions/swap/hooks/useTrade/useTradeServiceQueryOptions.ts +++ b/packages/uniswap/src/features/transactions/swap/hooks/useTrade/useTradeServiceQueryOptions.ts @@ -15,18 +15,63 @@ export type TradeServiceQueryOptions = UseQueryOptions< [ ReactQueryCacheKey.TradeService, 'getTrade', - ValidatedTradeInput | JupiterOrderUrlParams | null, // TODO(SWAP-383): Remove JupiterOrderUrlParams from union once Solana trade repo is implemented + string, // Stable query key based on values instead of object reference ] > +/** + * Creates a stable query key based on validated input values instead of object reference. + * This prevents unnecessary refetches when object references change but values remain the same. + */ +function createStableQueryKey( + validatedInput: ValidatedTradeInput | JupiterOrderUrlParams | null, +): string { + if (!validatedInput) { + return 'null' + } + + // Handle JupiterOrderUrlParams (Solana trades) + if ('inputMint' in validatedInput && 'outputMint' in validatedInput) { + const jupiterParams = validatedInput as JupiterOrderUrlParams + const keyParts = [ + 'jupiter', + jupiterParams.inputMint, + jupiterParams.outputMint, + jupiterParams.amount, + jupiterParams.swapMode, + jupiterParams.slippageBps ?? 'default', + ] + return keyParts.join('|') + } + + // Handle ValidatedTradeInput (EVM trades) + const evmInput = validatedInput as ValidatedTradeInput + // Create a stable key based on all relevant values + // This ensures the query key only changes when actual values change, not object references + const keyParts = [ + evmInput.tokenInChainId, + evmInput.tokenInAddress, + evmInput.tokenOutChainId, + evmInput.tokenOutAddress, + evmInput.amount.quotient.toString(), + evmInput.requestTradeType, + evmInput.activeAccountAddress ?? 'unconnected', + evmInput.isUSDQuote ?? false, + evmInput.generatePermitAsTransaction ?? false, + ] + + return keyParts.join('|') +} + export function createTradeServiceQueryOptions(ctx: { tradeService: TradeService }): (params?: UseTradeArgs) => TradeServiceQueryOptions { return (params?: UseTradeArgs) => { const validatedInput = params ? ctx.tradeService.prepareTradeInput(params) : null + const stableKey = createStableQueryKey(validatedInput) return queryOptions({ - queryKey: [ReactQueryCacheKey.TradeService, 'getTrade', validatedInput], + queryKey: [ReactQueryCacheKey.TradeService, 'getTrade', stableKey], queryFn: async (): Promise => { if (!params) { return { trade: null } diff --git a/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/buildQuoteRequest.ts b/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/buildQuoteRequest.ts index bce005f374b..b4de5b8d371 100644 --- a/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/buildQuoteRequest.ts +++ b/packages/uniswap/src/features/transactions/swap/services/tradeService/transformations/buildQuoteRequest.ts @@ -97,10 +97,14 @@ export type FlattenedQuoteRequestResult = Omit> otherCurrency: Maybe tradeType: TradeType + // Explicit sell and buy tokens from UI to ensure consistency + // sellToken should always correspond to CurrencyField.INPUT (what user is selling) + // buyToken should always correspond to CurrencyField.OUTPUT (what user is buying) + sellToken?: Currency + buyToken?: Currency pollInterval?: PollingInterval customSlippageTolerance?: number isUSDQuote?: boolean From 7db5ca172c4b01c289254aaea8eb173f8139c70c Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Sat, 24 Jan 2026 11:58:55 +0800 Subject: [PATCH 23/33] feat: remove useless api --- apps/web/src/index.tsx | 68 ++++---- apps/web/src/tracing/amplitude.ts | 32 ++-- apps/web/src/tracing/index.ts | 15 +- .../clients/trading/createTradingApiClient.ts | 61 ++----- packages/gating/src/sdk/statsig.ts | 14 +- .../tradingApi/TradingApiClient.test.ts | 1 - .../apiClients/tradingApi/TradingApiClient.ts | 3 - .../tradingApi/useTradingApiSwapQuery.ts | 62 ++----- .../useTradingApiSwappableTokensQuery.ts | 10 +- packages/uniswap/src/data/links.ts | 32 ++-- .../uniswap/src/data/rest/getPortfolio.ts | 163 +++++++++--------- .../gating/StatsigProviderWrapper.tsx | 86 +++++---- .../src/features/gating/statsigBaseConfig.ts | 4 +- .../evm/evmSwapRepository.ts | 68 +++----- .../features/transactions/swap/steps/swap.ts | 23 +-- 15 files changed, 296 insertions(+), 346 deletions(-) diff --git a/apps/web/src/index.tsx b/apps/web/src/index.tsx index 0bef757b160..d8dae449851 100644 --- a/apps/web/src/index.tsx +++ b/apps/web/src/index.tsx @@ -138,39 +138,43 @@ function GraphqlProviders({ children }: { children: React.ReactNode }) { ) } +// HKSWAP: Disabled Statsig feature flags - not needed for hkswap function StatsigProvider({ children }: PropsWithChildren) { - const account = useAccount() - - const statsigUser: StatsigUser = useMemo( - () => ({ - userID: getDeviceId(), - customIDs: { address: account.address ?? '' }, - }), - [account.address], - ) - - useEffect(() => { - datadogRum.setUserProperty('connection', { - type: account.connector?.type, - name: account.connector?.name, - rdns: account.connector?.id, - address: account.address, - status: account.status, - }) - }, [account]) - - const onStatsigInit = () => { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (!isDevEnv() || localDevDatadogEnabled) { - initializeDatadog('web').catch(() => undefined) - } - } - - return ( - - {children} - - ) + // const account = useAccount() + + // const statsigUser: StatsigUser = useMemo( + // () => ({ + // userID: getDeviceId(), + // customIDs: { address: account.address ?? '' }, + // }), + // [account.address], + // ) + + // useEffect(() => { + // datadogRum.setUserProperty('connection', { + // type: account.connector?.type, + // name: account.connector?.name, + // rdns: account.connector?.id, + // address: account.address, + // status: account.status, + // }) + // }, [account]) + + // const onStatsigInit = () => { + // // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + // if (!isDevEnv() || localDevDatadogEnabled) { + // initializeDatadog('web').catch(() => undefined) + // } + // } + + // return ( + // + // {children} + // + // ) + + // HKSWAP: Return children directly without Statsig initialization + return <>{children} } const container = document.getElementById('root') as HTMLElement diff --git a/apps/web/src/tracing/amplitude.ts b/apps/web/src/tracing/amplitude.ts index 14949704610..9e7b59b2da3 100644 --- a/apps/web/src/tracing/amplitude.ts +++ b/apps/web/src/tracing/amplitude.ts @@ -8,21 +8,23 @@ import { ApplicationTransport } from 'utilities/src/telemetry/analytics/Applicat // biome-ignore lint/style/noRestrictedImports: Need direct analytics import for Amplitude initialization import { analytics, getAnalyticsAtomDirect } from 'utilities/src/telemetry/analytics/analytics' +// HKSWAP: Disabled Amplitude analytics - not needed for hkswap export function setupAmplitude() { - if (isTestEnv()) { - logger.debug('amplitude.ts', 'setupAmplitude', 'Skipping Amplitude initialization in test environment') - return - } + // if (isTestEnv()) { + // logger.debug('amplitude.ts', 'setupAmplitude', 'Skipping Amplitude initialization in test environment') + // return + // } - getAnalyticsAtomDirect(true).then((allowAnalytics) => { - analytics.init({ - transportProvider: new ApplicationTransport({ - serverUrl: uniswapUrls.amplitudeProxyUrl, - appOrigin: OriginApplication.INTERFACE, - reportOriginCountry: (country: string) => store.dispatch(setOriginCountry(country)), - }), - allowed: allowAnalytics, - initHash: process.env.REACT_APP_GIT_COMMIT_HASH, - }) - }) + // getAnalyticsAtomDirect(true).then((allowAnalytics) => { + // analytics.init({ + // transportProvider: new ApplicationTransport({ + // serverUrl: uniswapUrls.amplitudeProxyUrl, + // appOrigin: OriginApplication.INTERFACE, + // reportOriginCountry: (country: string) => store.dispatch(setOriginCountry(country)), + // }), + // allowed: allowAnalytics, + // initHash: process.env.REACT_APP_GIT_COMMIT_HASH, + // }) + // }) + return } diff --git a/apps/web/src/tracing/index.ts b/apps/web/src/tracing/index.ts index 11464392b9d..5ed076dec19 100644 --- a/apps/web/src/tracing/index.ts +++ b/apps/web/src/tracing/index.ts @@ -1,9 +1,10 @@ -import { setupAmplitude } from 'tracing/amplitude' -import { isRemoteReportingEnabled } from 'utils/env' +// HKSWAP: Disabled Amplitude analytics - not needed for hkswap +// import { setupAmplitude } from 'tracing/amplitude' +// import { isRemoteReportingEnabled } from 'utils/env' -if (isRemoteReportingEnabled()) { - // Dump some metadata into the window to allow client verification. - window.GIT_COMMIT_HASH = process.env.REACT_APP_GIT_COMMIT_HASH -} +// if (isRemoteReportingEnabled()) { +// // Dump some metadata into the window to allow client verification. +// window.GIT_COMMIT_HASH = process.env.REACT_APP_GIT_COMMIT_HASH +// } -setupAmplitude() +// setupAmplitude() diff --git a/packages/api/src/clients/trading/createTradingApiClient.ts b/packages/api/src/clients/trading/createTradingApiClient.ts index ec4ab60a231..b14b75a6e2e 100644 --- a/packages/api/src/clients/trading/createTradingApiClient.ts +++ b/packages/api/src/clients/trading/createTradingApiClient.ts @@ -18,12 +18,6 @@ import type { ClaimLPRewardsResponse, CreateLPPositionRequest, CreateLPPositionResponse, - CreateSwap5792Request, - CreateSwap5792Response, - CreateSwap7702Request, - CreateSwap7702Response, - CreateSwapRequest, - CreateSwapResponse, DecreaseLPPositionRequest, DecreaseLPPositionResponse, Encode7702ResponseBody, @@ -91,9 +85,6 @@ export interface TradingClientContext { export interface TradingApiClient { fetchQuote: (params: QuoteRequest & { isUSDQuote?: boolean }) => Promise fetchIndicativeQuote: (params: IndicativeQuoteRequest) => Promise - fetchSwap: (params: CreateSwapRequest) => Promise - fetchSwap5792: (params: CreateSwap5792Request) => Promise - fetchSwap7702: (params: CreateSwap7702Request) => Promise fetchSwaps: (params: { txHashes: TransactionHash[]; chainId: ChainId }) => Promise fetchCheckApproval: (params: ApprovalRequest) => Promise submitOrder: (params: OrderRequest) => Promise @@ -161,33 +152,6 @@ export function createTradingApiClient(ctx: TradingClientContext): TradingApiCli }) } - const fetchSwap = createFetcher({ - client, - url: getApiPath(TRADING_API_PATHS.swap), - method: 'post', - transformRequest: async () => ({ - headers: getFeatureFlagHeaders(TRADING_API_PATHS.swap), - }), - }) - - const fetchSwap5792 = createFetcher({ - client, - url: getApiPath(TRADING_API_PATHS.swap5792), - method: 'post', - transformRequest: async () => ({ - headers: getFeatureFlagHeaders(TRADING_API_PATHS.swap5792), - }), - }) - - const fetchSwap7702 = createFetcher({ - client, - url: getApiPath(TRADING_API_PATHS.swap7702), - method: 'post', - transformRequest: async () => ({ - headers: getFeatureFlagHeaders(TRADING_API_PATHS.swap7702), - }), - }) - const fetchCheckApproval = createFetcher({ client, url: getApiPath(TRADING_API_PATHS.approval), @@ -239,14 +203,20 @@ export function createTradingApiClient(ctx: TradingClientContext): TradingApiCli }), }) - const fetchSwappableTokens = createFetcher({ - client, - url: getApiPath(TRADING_API_PATHS.swappableTokens), - method: 'get', - transformRequest: async () => ({ - headers: getFeatureFlagHeaders(TRADING_API_PATHS.swappableTokens), - }), - }) + // HKSWAP: Disabled swappable_tokens API - not needed for single-chain swap + // const fetchSwappableTokens = createFetcher({ + // client, + // url: getApiPath(TRADING_API_PATHS.swappableTokens), + // method: 'get', + // transformRequest: async () => ({ + // headers: getFeatureFlagHeaders(TRADING_API_PATHS.swappableTokens), + // }), + // }) + + // HKSWAP: Return empty response instead of calling API + const fetchSwappableTokens = async (_params: SwappableTokensParams): Promise => { + return { tokens: [] } + } const getLPPriceDiscrepancy = createFetcher({ client, @@ -436,9 +406,6 @@ export function createTradingApiClient(ctx: TradingClientContext): TradingApiCli return { fetchQuote, fetchIndicativeQuote, - fetchSwap, - fetchSwap5792, - fetchSwap7702, fetchSwaps, fetchCheckApproval, submitOrder, diff --git a/packages/gating/src/sdk/statsig.ts b/packages/gating/src/sdk/statsig.ts index ffd96409134..699adca2136 100644 --- a/packages/gating/src/sdk/statsig.ts +++ b/packages/gating/src/sdk/statsig.ts @@ -24,15 +24,19 @@ export { let localOverrideAdapter: LocalOverrideAdapterWrapper | undefined +// HKSWAP: Disabled Statsig - return dummy key to prevent errors function getStatsigApiKeyOrThrow(): string { // A dummy key is used in test env b/c the wallet/mobile tests use this file instead of the statsig.native file - const statsigApiKey = isTestEnv() ? 'dummy-test-key' : getConfig().statsigApiKey + // HKSWAP: Always return dummy key since Statsig is disabled + return 'dummy-key-for-hkswap' + + // const statsigApiKey = isTestEnv() ? 'dummy-test-key' : getConfig().statsigApiKey - if (!statsigApiKey) { - throw new Error('STATSIG_API_KEY is not set') - } + // if (!statsigApiKey) { + // throw new Error('STATSIG_API_KEY is not set') + // } - return statsigApiKey + // return statsigApiKey } export function getOverrideAdapter(): LocalOverrideAdapterWrapper { diff --git a/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.test.ts b/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.test.ts index 36d379e216a..030aba4865e 100644 --- a/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.test.ts +++ b/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.test.ts @@ -502,7 +502,6 @@ describe('getFeatureFlaggedHeaders', () => { mockGetFeatureFlag.mockImplementation((flag) => flag === FeatureFlags.UnirouteEnabled) const headers = getFeatureFlaggedHeaders(path) switch (path) { - case TRADING_API_PATHS.swap7702: case TRADING_API_PATHS.quote: expect(headers).toHaveProperty(TradingApiHeaders.UnirouteEnabled, 'true') break diff --git a/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts b/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts index e13fbb15065..ea14e4ee466 100644 --- a/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts +++ b/packages/uniswap/src/data/apiClients/tradingApi/TradingApiClient.ts @@ -98,9 +98,6 @@ export const getFeatureFlaggedHeaders = ( case TRADING_API_PATHS.order: addHeaderIfEnabled({ headers, key: TradingApiHeaders.Erc20EthEnabled, enabled: ethAsErc20UniswapXEnabled }) break - case TRADING_API_PATHS.swap7702: - addHeaderIfEnabled({ headers, key: TradingApiHeaders.UnirouteEnabled, enabled: unirouteEnabled }) - break } return headers } diff --git a/packages/uniswap/src/data/apiClients/tradingApi/useTradingApiSwapQuery.ts b/packages/uniswap/src/data/apiClients/tradingApi/useTradingApiSwapQuery.ts index 4cdb28774ac..58ae0fefcfb 100644 --- a/packages/uniswap/src/data/apiClients/tradingApi/useTradingApiSwapQuery.ts +++ b/packages/uniswap/src/data/apiClients/tradingApi/useTradingApiSwapQuery.ts @@ -5,65 +5,29 @@ import { useQueryWithImmediateGarbageCollection, } from '@universe/api' import { uniswapUrls } from 'uniswap/src/constants/urls' -import { TradingApiClient } from 'uniswap/src/data/apiClients/tradingApi/TradingApiClient' -import { - convertSwap5792ResponseToSwapData, - convertSwap7702ResponseToSwapData, - convertSwapResponseToSwapData, - type SwapData, -} from 'uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/evmSwapRepository' +import type { SwapData } from 'uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/evmSwapRepository' import { ReactQueryCacheKey } from 'utilities/src/reactQuery/cache' +/** + * HashKey chains (133, 177) do not use swap API. + * This hook should never be called for HashKey chains. + * Transactions are built directly from quote methodParameters. + */ export function useTradingApiSwapQuery( { params, ...rest }: UseQueryWithImmediateGarbageCollectionApiHelperHookArgs, config?: { canBatchTransactions?: boolean; swapDelegationAddress?: string; includesDelegation?: boolean }, ): UseQueryResult { const queryKey = [ReactQueryCacheKey.TradingApi, uniswapUrls.tradingApiPaths.swap, params] - const fetch = getFetchFn(config) return useQueryWithImmediateGarbageCollection({ queryKey, - queryFn: params ? (): Promise => fetch(params) : skipToken, + queryFn: params + ? (): Promise => { + throw new Error( + 'Swap API is not used for HashKey chains. Transactions should be built from quote methodParameters.', + ) + } + : skipToken, ...rest, }) } - -function getFetchFn(config?: { - canBatchTransactions?: boolean - swapDelegationAddress?: string - includesDelegation?: boolean -}): (params: TradingApi.CreateSwapRequest) => Promise { - const { canBatchTransactions, swapDelegationAddress, includesDelegation } = config ?? {} - if (swapDelegationAddress) { - return (params) => fetch7702({ swapDelegationAddress, params, includesDelegation }) - } - - if (canBatchTransactions) { - return fetch5792 - } - - return fetchLegacy -} - -async function fetch7702({ - swapDelegationAddress, - params, - includesDelegation, -}: { - swapDelegationAddress: string - params: TradingApi.CreateSwapRequest - includesDelegation?: boolean -}): Promise { - return convertSwap7702ResponseToSwapData( - await TradingApiClient.fetchSwap7702({ ...params, smartContractDelegationAddress: swapDelegationAddress }), - includesDelegation, - ) -} - -async function fetchLegacy(params: TradingApi.CreateSwapRequest): Promise { - return convertSwapResponseToSwapData(await TradingApiClient.fetchSwap(params)) -} - -async function fetch5792(params: TradingApi.CreateSwapRequest): Promise { - return convertSwap5792ResponseToSwapData(await TradingApiClient.fetchSwap5792(params)) -} diff --git a/packages/uniswap/src/data/apiClients/tradingApi/useTradingApiSwappableTokensQuery.ts b/packages/uniswap/src/data/apiClients/tradingApi/useTradingApiSwappableTokensQuery.ts index ef104a5e46b..31fef4a4901 100644 --- a/packages/uniswap/src/data/apiClients/tradingApi/useTradingApiSwappableTokensQuery.ts +++ b/packages/uniswap/src/data/apiClients/tradingApi/useTradingApiSwappableTokensQuery.ts @@ -83,9 +83,15 @@ const swappableTokensQueryKey = (params?: SwappableTokensParams): QueryKey => { return [ReactQueryCacheKey.TradingApi, uniswapUrls.tradingApiPaths.swappableTokens, params] } +// HKSWAP: Disabled swappable_tokens API - not needed for single-chain swap const swappableTokensQueryFn = ( params: SwappableTokensParams, ): QueryFunction | undefined => { - return async (): ReturnType => - await TradingApiClient.fetchSwappableTokens(params) + // return async (): ReturnType => + // await TradingApiClient.fetchSwappableTokens(params) + + // HKSWAP: Return empty response instead of calling API + return async (): Promise => { + return { tokens: [] } + } } diff --git a/packages/uniswap/src/data/links.ts b/packages/uniswap/src/data/links.ts index 052de4c5d10..eb143553c8e 100644 --- a/packages/uniswap/src/data/links.ts +++ b/packages/uniswap/src/data/links.ts @@ -1,4 +1,4 @@ -import { ApolloLink, createHttpLink } from '@apollo/client' +import { ApolloLink, createHttpLink, Observable } from '@apollo/client' import { onError } from '@apollo/client/link/error' import { RestLink } from 'apollo-link-rest' import { config } from 'uniswap/src/config' @@ -43,18 +43,28 @@ export const getCustomGraphqlHttpLink = (endpoint: CustomEndpoint): ApolloLink = }, }) +// HKSWAP: Disabled GraphQL API - not needed for hskswap (only supports HashKey chain) export const getGraphqlHttpLink = (): ApolloLink => - createHttpLink({ - uri: uniswapUrls.graphQLUrl, - headers: { - 'Content-Type': 'application/json', - 'X-API-KEY': config.uniswapApiKey, - 'x-request-source': REQUEST_SOURCE, - 'x-app-version': getVersionHeader(), - // TODO: [MOB-3883] remove once API gateway supports mobile origin URL - Origin: uniswapUrls.apiOrigin, - }, + // Return a link that never sends requests + new ApolloLink(() => { + // Return empty observable that never emits + return new Observable(() => { + // No-op: never emit any values + }) }) + + // Original implementation commented out: + // createHttpLink({ + // uri: uniswapUrls.graphQLUrl, + // headers: { + // 'Content-Type': 'application/json', + // 'X-API-KEY': config.uniswapApiKey, + // 'x-request-source': REQUEST_SOURCE, + // 'x-app-version': getVersionHeader(), + // // TODO: [MOB-3883] remove once API gateway supports mobile origin URL + // Origin: uniswapUrls.apiOrigin, + // }, + // }) // Samples error reports to reduce load on backend // Recurring errors that we must fix should have enough occurrences that we detect them still diff --git a/packages/uniswap/src/data/rest/getPortfolio.ts b/packages/uniswap/src/data/rest/getPortfolio.ts index 3b3db8f6bb3..cbf77c92152 100644 --- a/packages/uniswap/src/data/rest/getPortfolio.ts +++ b/packages/uniswap/src/data/rest/getPortfolio.ts @@ -95,85 +95,90 @@ export const getPortfolioQuery = ({ return queryOptions({ queryKey: [ReactQueryCacheKey.GetPortfolio, accountAddressesByPlatform, inputWithoutModifierAndWalletAccount], queryFn: async () => { - const log = createLogger('getPortfolio.ts', 'queryFn', '[REST-ITBU]') - - if (!transformedInput) { - return Promise.resolve(undefined) - } - - // Fetch portfolio data from the backend - const apiResponse = await portfolioClient.getPortfolio(transformedInput) - - try { - const reduxStore = getPortfolioQueryReduxStore() - - if (!reduxStore) { - log.warn('`getPortfolioQuery` called before `initializePortfolioQueryOverrides`') - return apiResponse - } - - if (!accountAddressesByPlatform || !apiResponse.portfolio) { - return apiResponse - } - - log.debug('Removing potentially expired balance overrides') - reduxStore.dispatch(removeExpiredBalanceOverrides()) - - const overrideCurrencyIds = getOverridesForQuery({ accountAddressesByPlatform }) - - if (overrideCurrencyIds.size === 0) { - log.debug('No overrides to apply, returning original response') - return apiResponse - } - - log.debug('Applying portfolio balance overrides', { - overrideCount: overrideCurrencyIds.size, - currencyIds: Array.from(overrideCurrencyIds), - accountAddresses: accountAddressesByPlatform, - }) - - let modifiedResponse = apiResponse - const addresses = Object.values(accountAddressesByPlatform) - - for (const address of addresses) { - // Get overrides specific to this address only - const overridesForCurrentAddress = getOverridesForAddress({ address }) - - if (overridesForCurrentAddress.size === 0 || !modifiedResponse.portfolio) { - continue - } - - log.debug(`Processing ${overridesForCurrentAddress.size} overrides for address ${address}`, { - currencyIds: Array.from(overridesForCurrentAddress), - }) - - const mergedResult = await fetchAndMergeOnchainBalances({ - cachedPortfolio: modifiedResponse.portfolio, - accountAddress: address, - currencyIds: overridesForCurrentAddress, - }) - - if (!mergedResult) { - log.debug(`No merged result for address ${address}, continuing`) - continue - } - - // Check if backend has caught up and clean up overrides if needed - cleanupCaughtUpOverrides({ ownerAddress: address, originalData: apiResponse, mergedData: mergedResult }) - - // Update result for next iteration - modifiedResponse = mergedResult - - log.debug(`Successfully applied overrides for address ${address}`) - } - - log.debug('Successfully applied all overrides in queryFn') - - return modifiedResponse - } catch (error) { - log.error(new Error('Unexpected error when trying to apply portfolio balance overrides', { cause: error })) - return apiResponse - } + // HKSWAP: Disabled GetPortfolio API - not needed for hkswap + // Return undefined to prevent API calls + return Promise.resolve(undefined) + + // const log = createLogger('getPortfolio.ts', 'queryFn', '[REST-ITBU]') + + // if (!transformedInput) { + // return Promise.resolve(undefined) + // } + + // // Fetch portfolio data from the backend + // const apiResponse = await portfolioClient.getPortfolio(transformedInput) + + // HKSWAP: All portfolio processing logic commented out since API is disabled + // try { + // const reduxStore = getPortfolioQueryReduxStore() + + // if (!reduxStore) { + // log.warn('`getPortfolioQuery` called before `initializePortfolioQueryOverrides`') + // return apiResponse + // } + + // if (!accountAddressesByPlatform || !apiResponse.portfolio) { + // return apiResponse + // } + + // log.debug('Removing potentially expired balance overrides') + // reduxStore.dispatch(removeExpiredBalanceOverrides()) + + // const overrideCurrencyIds = getOverridesForQuery({ accountAddressesByPlatform }) + + // if (overrideCurrencyIds.size === 0) { + // log.debug('No overrides to apply, returning original response') + // return apiResponse + // } + + // log.debug('Applying portfolio balance overrides', { + // overrideCount: overrideCurrencyIds.size, + // currencyIds: Array.from(overrideCurrencyIds), + // accountAddresses: accountAddressesByPlatform, + // }) + + // let modifiedResponse = apiResponse + // const addresses = Object.values(accountAddressesByPlatform) + + // for (const address of addresses) { + // // Get overrides specific to this address only + // const overridesForCurrentAddress = getOverridesForAddress({ address }) + + // if (overridesForCurrentAddress.size === 0 || !modifiedResponse.portfolio) { + // continue + // } + + // log.debug(`Processing ${overridesForCurrentAddress.size} overrides for address ${address}`, { + // currencyIds: Array.from(overridesForCurrentAddress), + // }) + + // const mergedResult = await fetchAndMergeOnchainBalances({ + // cachedPortfolio: modifiedResponse.portfolio, + // accountAddress: address, + // currencyIds: overridesForCurrentAddress, + // }) + + // if (!mergedResult) { + // log.debug(`No merged result for address ${address}, continuing`) + // continue + // } + + // // Check if backend has caught up and clean up overrides if needed + // cleanupCaughtUpOverrides({ ownerAddress: address, originalData: apiResponse, mergedData: mergedResult }) + + // // Update result for next iteration + // modifiedResponse = mergedResult + + // log.debug(`Successfully applied overrides for address ${address}`) + // } + + // log.debug('Successfully applied all overrides in queryFn') + + // return modifiedResponse + // } catch (error) { + // log.error(new Error('Unexpected error when trying to apply portfolio balance overrides', { cause: error })) + // return apiResponse + // } }, placeholderData: (prev) => prev, // this prevents the loading skeleton from appearing when hiding/unhiding tokens refetchInterval, diff --git a/packages/uniswap/src/features/gating/StatsigProviderWrapper.tsx b/packages/uniswap/src/features/gating/StatsigProviderWrapper.tsx index 8dcec0f93b7..4dfcb042cf0 100644 --- a/packages/uniswap/src/features/gating/StatsigProviderWrapper.tsx +++ b/packages/uniswap/src/features/gating/StatsigProviderWrapper.tsx @@ -4,6 +4,7 @@ import { type StatsigUser, type StorageProvider, useClientAsyncInit, + StatsigClient, } from '@universe/gating' import { type ReactNode, useEffect, useMemo } from 'react' import { config } from 'uniswap/src/config' @@ -18,6 +19,7 @@ type StatsigProviderWrapperProps = { storageProvider?: StorageProvider } +// HKSWAP: Disabled Statsig feature flags - not needed for hkswap export function StatsigProviderWrapper({ children, options, @@ -25,45 +27,61 @@ export function StatsigProviderWrapper({ storageProvider, onInit, }: StatsigProviderWrapperProps): ReactNode { - if (!config.statsigApiKey) { - throw new Error('statsigApiKey is not set') - } + // if (!config.statsigApiKey) { + // throw new Error('statsigApiKey is not set') + // } - const statsigOptions = useMemo( - () => ({ - ...statsigBaseConfig, - storageProvider, - ...options, - }), - [storageProvider, options], - ) + // const statsigOptions = useMemo( + // () => ({ + // ...statsigBaseConfig, + // storageProvider, + // ...options, + // }), + // [storageProvider, options], + // ) - const { client, isLoading: isStatsigLoading } = useClientAsyncInit(config.statsigApiKey, user, statsigOptions) + // const { client, isLoading: isStatsigLoading } = useClientAsyncInit(config.statsigApiKey, user, statsigOptions) - useEffect(() => { - if (isStatsigLoading) { - return - } + // useEffect(() => { + // if (isStatsigLoading) { + // return + // } - onInit?.() - }, [isStatsigLoading, onInit]) + // onInit?.() + // }, [isStatsigLoading, onInit]) + + // useEffect(() => { + // const errorHandler = (event: unknown): void => { + // logger.error('StatsigProviderWrapper', { + // tags: { file: 'StatsigProviderWrapper', function: 'error' }, + // extra: { + // event, + // }, + // }) + // } + // client.on('error', errorHandler) + // client.on('initialization_failure', errorHandler) + // return () => { + // client.off('error', errorHandler) + // client.off('initialization_failure', errorHandler) + // } + // }, [client]) + + // return {children} + + // HKSWAP: Create a mock StatsigClient that returns false for all feature flags + // This ensures useFeatureFlag hooks work without actually initializing Statsig + const mockClient = useMemo(() => { + // Create a minimal mock client that satisfies the StatsigProvider requirements + // All feature flags will return false by default + return StatsigClient.instance('dummy-key-for-hkswap') + }, []) useEffect(() => { - const errorHandler = (event: unknown): void => { - logger.error('StatsigProviderWrapper', { - tags: { file: 'StatsigProviderWrapper', function: 'error' }, - extra: { - event, - }, - }) - } - client.on('error', errorHandler) - client.on('initialization_failure', errorHandler) - return () => { - client.off('error', errorHandler) - client.off('initialization_failure', errorHandler) - } - }, [client]) + // Call onInit immediately since we're not actually initializing Statsig + onInit?.() + }, [onInit]) - return {children} + // Return StatsigProvider with mock client to satisfy hooks that require StatsigContext + return {children} } diff --git a/packages/uniswap/src/features/gating/statsigBaseConfig.ts b/packages/uniswap/src/features/gating/statsigBaseConfig.ts index dbb1f13d574..78b03e4982c 100644 --- a/packages/uniswap/src/features/gating/statsigBaseConfig.ts +++ b/packages/uniswap/src/features/gating/statsigBaseConfig.ts @@ -1,8 +1,10 @@ import { getOverrideAdapter, getStatsigEnvName, StatsigOptions } from '@universe/gating' import { uniswapUrls } from 'uniswap/src/constants/urls' +// HKSWAP: Disabled Statsig - use dummy config export const statsigBaseConfig: StatsigOptions = { - networkConfig: { api: uniswapUrls.statsigProxyUrl }, + // networkConfig: { api: uniswapUrls.statsigProxyUrl }, + networkConfig: { api: 'https://dummy-statsig-proxy.hkswap.local/v1/statsig-proxy' }, // HKSWAP: Dummy URL since Statsig is disabled environment: { tier: getStatsigEnvName(), }, diff --git a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/evmSwapRepository.ts b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/evmSwapRepository.ts index efc674be5a0..985f4dacc67 100644 --- a/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/evmSwapRepository.ts +++ b/packages/uniswap/src/features/transactions/swap/review/services/swapTxAndGasInfoService/evm/evmSwapRepository.ts @@ -1,9 +1,7 @@ import { TransactionRequest } from '@ethersproject/providers' import { GasEstimate, TradingApi } from '@universe/api' -import { TradingApiClient } from 'uniswap/src/data/apiClients/tradingApi/TradingApiClient' import { UniverseChainId } from 'uniswap/src/features/chains/types' import { SwapDelegationInfo } from 'uniswap/src/features/smartWallet/delegation/types' -import { tradingApiToUniverseChainId } from 'uniswap/src/features/transactions/swap/utils/tradingApi' export type SwapData = { requestId: string @@ -16,63 +14,41 @@ export interface EVMSwapRepository { fetchSwapData: (params: TradingApi.CreateSwapRequest) => Promise } -export function convertSwapResponseToSwapData(response: TradingApi.CreateSwapResponse): SwapData { - return { - requestId: response.requestId, - transactions: [response.swap], - gasFee: response.gasFee, - gasEstimate: response.gasEstimates?.[0], - } -} - +/** + * HashKey chains (133, 177) do not use swap API. + * Transactions are built directly from quote methodParameters using buildTxRequestFromTrade. + * This repository should never be called for HashKey chains. + */ export function createLegacyEVMSwapRepository(): EVMSwapRepository { return { - fetchSwapData: async (params: TradingApi.CreateSwapRequest) => - convertSwapResponseToSwapData(await TradingApiClient.fetchSwap(params)), - } -} - -export function convertSwap7702ResponseToSwapData( - response: TradingApi.CreateSwap7702Response, - includesDelegation?: boolean, -): SwapData { - return { - requestId: response.requestId, - transactions: [response.swap], - gasFee: response.gasFee, - includesDelegation, + fetchSwapData: async () => { + throw new Error('Swap API is not used for HashKey chains. Transactions should be built from quote methodParameters.') + }, } } +/** + * HashKey chains (133, 177) do not use swap API. + * This repository should never be called for HashKey chains. + */ export function create7702EVMSwapRepository(ctx: { getSwapDelegationInfo: (chainId?: UniverseChainId) => SwapDelegationInfo }): EVMSwapRepository { - const { getSwapDelegationInfo } = ctx - async function fetchSwapData(params: TradingApi.CreateSwapRequest): Promise { - const chainId = tradingApiToUniverseChainId(params.quote.chainId) - const smartContractDelegationInfo = getSwapDelegationInfo(chainId) - const response = await TradingApiClient.fetchSwap7702({ - ...params, - smartContractDelegationAddress: smartContractDelegationInfo.delegationAddress, - }) - - return convertSwap7702ResponseToSwapData(response, smartContractDelegationInfo.delegationInclusion) - } - - return { fetchSwapData } -} - -export function convertSwap5792ResponseToSwapData(response: TradingApi.CreateSwap5792Response): SwapData { return { - requestId: response.requestId, - transactions: response.calls.map((c) => ({ ...c, chainId: response.chainId })), - gasFee: response.gasFee, + fetchSwapData: async () => { + throw new Error('Swap API is not used for HashKey chains. Transactions should be built from quote methodParameters.') + }, } } +/** + * HashKey chains (133, 177) do not use swap API. + * This repository should never be called for HashKey chains. + */ export function create5792EVMSwapRepository(): EVMSwapRepository { return { - fetchSwapData: async (params: TradingApi.CreateSwapRequest) => - convertSwap5792ResponseToSwapData(await TradingApiClient.fetchSwap5792(params)), + fetchSwapData: async () => { + throw new Error('Swap API is not used for HashKey chains. Transactions should be built from quote methodParameters.') + }, } } diff --git a/packages/uniswap/src/features/transactions/swap/steps/swap.ts b/packages/uniswap/src/features/transactions/swap/steps/swap.ts index c59bc330d8a..7101d11d850 100644 --- a/packages/uniswap/src/features/transactions/swap/steps/swap.ts +++ b/packages/uniswap/src/features/transactions/swap/steps/swap.ts @@ -1,6 +1,5 @@ import { TradingApi } from '@universe/api' import invariant from 'tiny-invariant' -import { TradingApiClient } from 'uniswap/src/data/apiClients/tradingApi/TradingApiClient' import { UnexpectedTransactionStateError } from 'uniswap/src/features/transactions/errors' import { OnChainTransactionFields, @@ -28,24 +27,20 @@ export function createSwapTransactionStep(txRequest: ValidatedTransactionRequest return { type: TransactionStepType.SwapTransaction, txRequest } } +/** + * HashKey chains (133, 177) do not use swap API. + * Transactions are built directly from quote methodParameters. + * This function should never be called for HashKey chains. + */ export function createSwapTransactionAsyncStep( swapRequestArgs: TradingApi.CreateSwapRequest | undefined, ): SwapTransactionStepAsync { return { type: TransactionStepType.SwapTransactionAsync, - getTxRequest: async (signature: string): Promise => { - if (!swapRequestArgs) { - return undefined - } - - const { swap } = await TradingApiClient.fetchSwap({ - ...swapRequestArgs, - signature, - /* simulating transaction provides a more accurate gas limit, and the simulation will succeed because async swap step will only occur after approval has been confirmed. */ - simulateTransaction: true, - }) - - return validateTransactionRequest(swap) + getTxRequest: async (): Promise => { + throw new Error( + 'Swap API is not used for HashKey chains. Transactions should be built from quote methodParameters using buildTxRequestFromTrade.', + ) }, } } From ed30ffbd0222ab68cec8c4a3c9c196345f08a797 Mon Sep 17 00:00:00 2001 From: Raymond Wang Date: Sat, 24 Jan 2026 19:41:32 +0800 Subject: [PATCH 24/33] feat: remove most errors --- apps/web/index.html | 30 +---------- apps/web/public/csp.json | 1 - apps/web/public/dev-csp.json | 9 +++- .../Web3Provider/createWeb3Provider.tsx | 7 +-- .../components/Web3Provider/reownConfig.tsx | 51 ++++++++++++++----- .../components/Web3Provider/wagmiConfig.ts | 6 ++- .../components/Web3Provider/walletConnect.ts | 35 +++++++++---- apps/web/src/index.tsx | 19 ++++++- apps/web/src/pages/App.tsx | 5 -- .../pages/App/utils/UserPropertyUpdater.tsx | 20 ++++---- .../src/components/factories/createIcon.tsx | 4 +- .../apiClients/tradingApi/TradingApiClient.ts | 29 ++++++++--- .../uniswap/src/data/rest/getPortfolio.ts | 4 +- .../smartWallet/delegation/effects.ts | 1 - .../src/logger/datadog/Datadog.web.ts | 3 +- packages/utilities/src/logger/logger.ts | 5 +- .../src/telemetry/analytics/logging.ts | 14 ++--- 17 files changed, 149 insertions(+), 94 deletions(-) diff --git a/apps/web/index.html b/apps/web/index.html index 72efde8b26b..02b22aca7c9 100644 --- a/apps/web/index.html +++ b/apps/web/index.html @@ -25,8 +25,6 @@ - -