From 1a5535c2d150b5854a25a30e6d95d8f034196eea Mon Sep 17 00:00:00 2001 From: Matias Poblete <86752543+MattPoblete@users.noreply.github.com> Date: Fri, 30 Aug 2024 09:17:19 -0400 Subject: [PATCH 1/6] =?UTF-8?q?=F0=9F=9A=A7Add=20switches=20to=20toggle=20?= =?UTF-8?q?protocols?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Providers.tsx | 26 +++- .../Settings/ProtocolsSettings/index.tsx | 132 ++++++++++++++++++ src/components/Settings/index.tsx | 2 + src/contexts/index.ts | 15 ++ src/functions/generateRoute.ts | 68 +++++---- 5 files changed, 214 insertions(+), 29 deletions(-) create mode 100644 src/components/Settings/ProtocolsSettings/index.tsx diff --git a/src/components/Providers.tsx b/src/components/Providers.tsx index fd9aa524..e2d0d44d 100644 --- a/src/components/Providers.tsx +++ b/src/components/Providers.tsx @@ -1,15 +1,16 @@ import { Analytics } from '@vercel/analytics/react'; -import { AppContext, AppContextType, ColorModeContext, SnackbarIconType } from 'contexts'; -import { CssBaseline, ThemeProvider } from 'soroswap-ui'; +import { AppContext, AppContextType, ColorModeContext, SnackbarIconType, ProtocolsStatus } from 'contexts'; import { Provider } from 'react-redux'; -import { theme } from 'soroswap-ui'; -import { useMemo, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import InkathonProvider from 'inkathon/InkathonProvider'; import MainLayout from './Layout/MainLayout'; import MySorobanReactProvider from 'soroban/MySorobanReactProvider'; import store from 'state'; import { SorobanContextType } from '@soroban-react/core'; import { SoroswapThemeProvider } from 'soroswap-ui'; +import { Protocols } from 'soroswap-router-sdk'; +import { PlatformType } from 'state/routing/types'; + export default function Providers({ children, sorobanReactProviderProps, @@ -21,6 +22,19 @@ export default function Providers({ const [maxHops, setMaxHops] = useState(2); + //Defines the default protocols to be used in the app + const defaultProtocols = [ + Protocols.SOROSWAP + ] + const [protocols, setProtocols] = useState(defaultProtocols); + + //Defines the default platforms to be used in the app + const defaultProtocolsStatus: ProtocolsStatus[] = [ + { key: Protocols.SOROSWAP, value: true }, + { key: Protocols.PHOENIX, value: false }, + { key: PlatformType.STELLAR_CLASSIC, value: true }, + ] + const [protocolsStatus, setProtocolsStatus] = useState(defaultProtocolsStatus); const [openSnackbar, setOpenSnackbar] = useState(false); const [snackbarMessage, setSnackbarMessage] = useState(''); const [snackbarTitle, setSnackbarTitle] = useState('Swapped'); @@ -54,6 +68,10 @@ export default function Providers({ Settings: { maxHops, setMaxHops, + protocols, + setProtocols, + protocolsStatus, + setProtocolsStatus, }, }; diff --git a/src/components/Settings/ProtocolsSettings/index.tsx b/src/components/Settings/ProtocolsSettings/index.tsx new file mode 100644 index 00000000..69af46ab --- /dev/null +++ b/src/components/Settings/ProtocolsSettings/index.tsx @@ -0,0 +1,132 @@ +import Expand from 'components/Expand'; +import QuestionHelper from 'components/QuestionHelper'; +import Row, { RowBetween } from 'components/Row'; +import { BodySmall } from 'components/Text'; +import { AppContext } from 'contexts'; +import React, { useContext, useEffect, useState } from 'react' +import { Box, styled, Switch, SwitchProps, Typography, useTheme } from 'soroswap-ui'; + + +export const CustomSwitch = styled((props: SwitchProps) => ( + +))(({ theme }) => ({ + width: 42, + height: 26, + padding: 0, + alignContent: 'center', + alignItems: 'center', + '& .MuiSwitch-switchBase': { + padding: 0, + margin: 3, + '&.Mui-checked': { + transform: 'translateX(16px)', + color: '#8866DD', + '& .MuiSwitch-thumb:before': { + backgroundColor: '#8866DD', + borderRadius: 32, + }, + '& + .MuiSwitch-track': { + backgroundColor: theme.palette.background.paper, + opacity: 1, + border: 0, + }, + }, + }, + '& .MuiSwitch-thumb': { + backgroundColor: 'rgba(136, 102, 221, 0.25)', + width: 20, + height: 20, + '&:before': { + content: "''", + position: 'absolute', + width: '100%', + height: '100%', + left: 0, + top: 0, + backgroundRepeat: 'no-repeat', + backgroundPosition: 'center', + }, + }, + '& .MuiSwitch-track': { + borderRadius: 32, + backgroundColor: theme.palette.background.paper, + opacity: 1, + }, +})); + +const Option = styled(Row, { + shouldForwardProp: (prop) => prop !== 'isActive', +}) <{ isActive: boolean }>` + width: auto; + cursor: pointer; + padding: 6px 12px; + text-align: center; + gap: 4px; + border-radius: 12px; + background: ${({ isActive, theme }) => + isActive ? theme.palette.customBackground.module : 'transparent'}; + pointer-events: ${({ isActive }) => isActive && 'none'}; +`; + +const firstLetterUppercase = (string: string) => { + return string.charAt(0).toUpperCase() + string.slice(1); +} +const ProtocolsSettings = () => { + const theme = useTheme(); + const [isOpen, setIsOpen] = useState(false); + const { Settings } = useContext(AppContext); + const { protocolsStatus, setProtocolsStatus } = Settings; + + const switchProtocolValue = (key: string) => { + const newProtocolsStatus = protocolsStatus.map((protocol) => { + if (protocol.key === key) { + return { + key: protocol.key, + value: !protocol.value, + }; + } + return protocol; + }); + setProtocolsStatus(newProtocolsStatus); + } + + return ( + + setIsOpen(!isOpen)} + header={ + + Protocols + + The protocols Soroswap.finance will use to calculate the most efficient path for your transaction. + + } + /> + + } + button={<>} + > + + + {protocolsStatus.map((option, index) => { + return ( + + {firstLetterUppercase(option.key)} + { switchProtocolValue(option.key) }} color="secondary" /> + + ) + })} + { } + + + + + + ) +} + +export default ProtocolsSettings diff --git a/src/components/Settings/index.tsx b/src/components/Settings/index.tsx index b620036a..c6665f5e 100644 --- a/src/components/Settings/index.tsx +++ b/src/components/Settings/index.tsx @@ -8,6 +8,7 @@ import { useRef, useState } from 'react'; import MaxSlippageSettings from './MaxSlippageSettings'; import MenuButton from './MenuButton'; import MaxHopsSettings from './MaxHopsSettings'; +import ProtocolsSettings from './ProtocolsSettings'; const Menu = styled('div')` position: relative; @@ -74,6 +75,7 @@ export default function SettingsTab({ + diff --git a/src/contexts/index.ts b/src/contexts/index.ts index f0f8a446..0b6ef333 100644 --- a/src/contexts/index.ts +++ b/src/contexts/index.ts @@ -1,4 +1,6 @@ import React from 'react'; +import { Protocols } from 'soroswap-router-sdk'; +import { PlatformType } from 'state/routing/types'; type ConnectWalletModalType = { isConnectWalletModalOpen: boolean; @@ -13,6 +15,11 @@ export enum SnackbarIconType { ERROR, } +export interface ProtocolsStatus { + key: Protocols | PlatformType; + value: boolean; +} + export type SnackbarContextType = { openSnackbar: boolean; snackbarMessage: string; @@ -27,6 +34,10 @@ export type SnackbarContextType = { export type Settings = { maxHops: number; setMaxHops: React.Dispatch>; + protocols: Protocols[]; + setProtocols: React.Dispatch>; + protocolsStatus: ProtocolsStatus[]; + setProtocolsStatus: React.Dispatch>; }; export type AppContextType = { @@ -57,5 +68,9 @@ export const AppContext = React.createContext({ Settings: { maxHops: 2, setMaxHops: () => {}, + protocols: [], + setProtocols: () => {}, + protocolsStatus: [], + setProtocolsStatus: () => {}, }, }); diff --git a/src/functions/generateRoute.ts b/src/functions/generateRoute.ts index 3004cd49..df991a24 100644 --- a/src/functions/generateRoute.ts +++ b/src/functions/generateRoute.ts @@ -20,6 +20,7 @@ import { getBestPath, getHorizonBestPath } from 'helpers/horizon/getHorizonPath' import { PlatformType } from 'state/routing/types'; import { CurrencyAmount as AmountAsset } from 'interfaces'; import { DexDistribution } from 'helpers/aggregator'; +import { fn } from 'cypress/types/jquery'; export interface BuildTradeRoute { amountCurrency: AmountAsset | CurrencyAmount; @@ -57,30 +58,44 @@ export const useRouterSDK = () => { const { isEnabled: isAggregator } = useAggregator(); const { Settings } = useContext(AppContext); - const { maxHops } = Settings; + const { maxHops, protocols, protocolsStatus } = Settings; const network = sorobanContext.activeChain?.networkPassphrase as Networks; + const getPairsFns = useMemo(() => { + console.log('Router protocols changed!') + const routerProtocols = [] + if(!shouldUseBackend) return undefined +// here you should add your new supported aggregator protocols + for(let protocol of protocolsStatus){ + if(protocol.key === Protocols.SOROSWAP && protocol.value === true){ + routerProtocols.push({protocol: Protocols.SOROSWAP, fn: async () => fetchAllSoroswapPairs(network)}); + } + if(protocol.key === Protocols.PHOENIX && protocol.value === true){ + routerProtocols.push({protocol: Protocols.PHOENIX, fn: async () => fetchAllPhoenixPairs(network)}); + } + } + console.log('New router protocols:', routerProtocols) + return routerProtocols; + }, [network, protocolsStatus]); + + const getProtocols = useMemo(() => { + const newProtocols = []; + for(let protocol of protocolsStatus){ + if(protocol.key != PlatformType.STELLAR_CLASSIC && protocol.value === true){ + newProtocols.push(protocol.key); + } + } + return newProtocols as Protocols[]; + },[protocolsStatus]); const router = useMemo(() => { - const protocols = [Protocols.SOROSWAP]; // if (isAggregator) protocols.push(Protocols.PHOENIX); return new Router({ - getPairsFns: shouldUseBackend - ? [ - { - protocol: Protocols.SOROSWAP, - fn: async () => fetchAllSoroswapPairs(network), - }, - { - protocol: Protocols.PHOENIX, - fn: async () => fetchAllPhoenixPairs(network), - }, - ] - : undefined, + getPairsFns: getPairsFns, pairsCacheInSeconds: 60, - protocols: protocols, + protocols: getProtocols, network, maxHops, }); @@ -119,8 +134,11 @@ export const useRouterSDK = () => { tradeType, }; - const horizonPath = (await getHorizonBestPath(horizonProps, sorobanContext)) as BuildTradeRoute; - + let horizonPath; + if(protocolsStatus.find((protocol) => protocol.key === PlatformType.STELLAR_CLASSIC && protocol.value === true)){ + horizonPath = (await getHorizonBestPath(horizonProps, sorobanContext)) as BuildTradeRoute; + } + let sorobanPath: BuildTradeRoute; if (isAggregator) { sorobanPath = (await router @@ -146,17 +164,17 @@ export const useRouterSDK = () => { })) as BuildTradeRoute; } const bestPath = getBestPath(horizonPath, sorobanPath, tradeType); - // .then((res) => { - // if (!res) return; - // const response = { - // ...res, - // platform: PlatformType.ROUTER, - // }; - // return response; - // }); return bestPath; }; return { generateRoute, resetRouterSdkCache, maxHops }; }; +// .then((res) => { +// if (!res) return; +// const response = { +// ...res, +// platform: PlatformType.ROUTER, +// }; +// return response; +// }); From c643eff996bd9dcbab5f76658096187062c03f1d Mon Sep 17 00:00:00 2001 From: Matias Poblete <86752543+MattPoblete@users.noreply.github.com> Date: Fri, 30 Aug 2024 12:15:07 -0400 Subject: [PATCH 2/6] =?UTF-8?q?=E2=9C=A8reset=20RouterSDK=20hook=20when=20?= =?UTF-8?q?protocolsStatus=20update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Settings/ProtocolsSettings/index.tsx | 26 ++++++----------- src/functions/generateRoute.ts | 29 ++++++++++--------- 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/components/Settings/ProtocolsSettings/index.tsx b/src/components/Settings/ProtocolsSettings/index.tsx index 69af46ab..85fef28c 100644 --- a/src/components/Settings/ProtocolsSettings/index.tsx +++ b/src/components/Settings/ProtocolsSettings/index.tsx @@ -3,6 +3,7 @@ import QuestionHelper from 'components/QuestionHelper'; import Row, { RowBetween } from 'components/Row'; import { BodySmall } from 'components/Text'; import { AppContext } from 'contexts'; +import { useRouterSDK } from 'functions/generateRoute'; import React, { useContext, useEffect, useState } from 'react' import { Box, styled, Switch, SwitchProps, Typography, useTheme } from 'soroswap-ui'; @@ -54,28 +55,15 @@ export const CustomSwitch = styled((props: SwitchProps) => ( }, })); -const Option = styled(Row, { - shouldForwardProp: (prop) => prop !== 'isActive', -}) <{ isActive: boolean }>` - width: auto; - cursor: pointer; - padding: 6px 12px; - text-align: center; - gap: 4px; - border-radius: 12px; - background: ${({ isActive, theme }) => - isActive ? theme.palette.customBackground.module : 'transparent'}; - pointer-events: ${({ isActive }) => isActive && 'none'}; -`; const firstLetterUppercase = (string: string) => { return string.charAt(0).toUpperCase() + string.slice(1); } const ProtocolsSettings = () => { + const { resetRouterSdkCache } = useRouterSDK(); const theme = useTheme(); const [isOpen, setIsOpen] = useState(false); - const { Settings } = useContext(AppContext); - const { protocolsStatus, setProtocolsStatus } = Settings; + const { protocolsStatus, setProtocolsStatus } = useContext(AppContext).Settings; const switchProtocolValue = (key: string) => { const newProtocolsStatus = protocolsStatus.map((protocol) => { @@ -87,7 +75,12 @@ const ProtocolsSettings = () => { } return protocol; }); - setProtocolsStatus(newProtocolsStatus); + const hasTrueValue = newProtocolsStatus.some((protocol) => protocol.value); + if (hasTrueValue) { + setProtocolsStatus(newProtocolsStatus); + resetRouterSdkCache(); + } + else return; } return ( @@ -120,7 +113,6 @@ const ProtocolsSettings = () => { ) })} - { } diff --git a/src/functions/generateRoute.ts b/src/functions/generateRoute.ts index df991a24..74b3bb1e 100644 --- a/src/functions/generateRoute.ts +++ b/src/functions/generateRoute.ts @@ -1,4 +1,4 @@ -import { SorobanContextType, useSorobanReact } from '@soroban-react/core'; +import { useSorobanReact } from '@soroban-react/core'; import { AppContext } from 'contexts'; import { useFactory } from 'hooks'; import { useAggregator } from 'hooks/useAggregator'; @@ -20,7 +20,6 @@ import { getBestPath, getHorizonBestPath } from 'helpers/horizon/getHorizonPath' import { PlatformType } from 'state/routing/types'; import { CurrencyAmount as AmountAsset } from 'interfaces'; import { DexDistribution } from 'helpers/aggregator'; -import { fn } from 'cypress/types/jquery'; export interface BuildTradeRoute { amountCurrency: AmountAsset | CurrencyAmount; @@ -63,7 +62,6 @@ export const useRouterSDK = () => { const network = sorobanContext.activeChain?.networkPassphrase as Networks; const getPairsFns = useMemo(() => { - console.log('Router protocols changed!') const routerProtocols = [] if(!shouldUseBackend) return undefined // here you should add your new supported aggregator protocols @@ -75,7 +73,6 @@ export const useRouterSDK = () => { routerProtocols.push({protocol: Protocols.PHOENIX, fn: async () => fetchAllPhoenixPairs(network)}); } } - console.log('New router protocols:', routerProtocols) return routerProtocols; }, [network, protocolsStatus]); @@ -88,18 +85,20 @@ export const useRouterSDK = () => { } return newProtocols as Protocols[]; },[protocolsStatus]); - const router = useMemo(() => { - - // if (isAggregator) protocols.push(Protocols.PHOENIX); + const router = useMemo(() => { return new Router({ getPairsFns: getPairsFns, - pairsCacheInSeconds: 60, + pairsCacheInSeconds: 5, protocols: getProtocols, network, maxHops, }); - }, [network, maxHops, isAggregator]); + }, [network, maxHops, isAggregator, protocolsStatus]); + + const isProtocolEnabled = (protocol: any) => { + return protocolsStatus.find((p) => p.key === protocol)?.value; + } const fromAddressToToken = (address: string) => { return new Token(network, address, 18); @@ -127,6 +126,9 @@ export const useRouterSDK = () => { ); const quoteCurrency = fromAddressToToken(quoteAsset.contract); + const isHorizonEnabled = isProtocolEnabled(PlatformType.STELLAR_CLASSIC); + const isSoroswapEnabled = isProtocolEnabled(Protocols.SOROSWAP); + const horizonProps = { assetFrom: amountAsset.currency, assetTo: quoteAsset, @@ -134,12 +136,12 @@ export const useRouterSDK = () => { tradeType, }; - let horizonPath; - if(protocolsStatus.find((protocol) => protocol.key === PlatformType.STELLAR_CLASSIC && protocol.value === true)){ + let horizonPath: BuildTradeRoute | undefined; + if(isHorizonEnabled){ horizonPath = (await getHorizonBestPath(horizonProps, sorobanContext)) as BuildTradeRoute; } - let sorobanPath: BuildTradeRoute; + let sorobanPath: BuildTradeRoute | undefined; if (isAggregator) { sorobanPath = (await router .routeSplit(currencyAmount, quoteCurrency, tradeType) @@ -151,7 +153,7 @@ export const useRouterSDK = () => { }; return result; })) as BuildTradeRoute; - } else { + } else if(isSoroswapEnabled){ sorobanPath = (await router .route(currencyAmount, quoteCurrency, tradeType, factory, sorobanContext as any) .then((response) => { @@ -163,6 +165,7 @@ export const useRouterSDK = () => { return result; })) as BuildTradeRoute; } + const bestPath = getBestPath(horizonPath, sorobanPath, tradeType); return bestPath; From f210de03a867715789c36987dee5e7babf3d99ff Mon Sep 17 00:00:00 2001 From: Matias Poblete <86752543+MattPoblete@users.noreply.github.com> Date: Fri, 30 Aug 2024 16:39:44 -0400 Subject: [PATCH 3/6] =?UTF-8?q?=F0=9F=9A=A7Refresh=20trade=20in=20protocol?= =?UTF-8?q?=20change?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Settings/ProtocolsSettings/index.tsx | 12 +++++++++++- src/hooks/useBestTrade.ts | 9 ++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/components/Settings/ProtocolsSettings/index.tsx b/src/components/Settings/ProtocolsSettings/index.tsx index 85fef28c..921f0077 100644 --- a/src/components/Settings/ProtocolsSettings/index.tsx +++ b/src/components/Settings/ProtocolsSettings/index.tsx @@ -6,6 +6,7 @@ import { AppContext } from 'contexts'; import { useRouterSDK } from 'functions/generateRoute'; import React, { useContext, useEffect, useState } from 'react' import { Box, styled, Switch, SwitchProps, Typography, useTheme } from 'soroswap-ui'; +import { useSWRConfig } from 'swr'; export const CustomSwitch = styled((props: SwitchProps) => ( @@ -64,6 +65,7 @@ const ProtocolsSettings = () => { const theme = useTheme(); const [isOpen, setIsOpen] = useState(false); const { protocolsStatus, setProtocolsStatus } = useContext(AppContext).Settings; + const { mutate } = useSWRConfig(); const switchProtocolValue = (key: string) => { const newProtocolsStatus = protocolsStatus.map((protocol) => { @@ -77,8 +79,16 @@ const ProtocolsSettings = () => { }); const hasTrueValue = newProtocolsStatus.some((protocol) => protocol.value); if (hasTrueValue) { - setProtocolsStatus(newProtocolsStatus); resetRouterSdkCache(); + setProtocolsStatus(newProtocolsStatus); + mutate( + (key: any) => { + console.log(key) + return true; + }, + undefined, + { revalidate: true }, + ); } else return; } diff --git a/src/hooks/useBestTrade.ts b/src/hooks/useBestTrade.ts index 210b57ee..e2ebca65 100644 --- a/src/hooks/useBestTrade.ts +++ b/src/hooks/useBestTrade.ts @@ -1,7 +1,8 @@ +import { AppContext } from 'contexts'; import { useRouterSDK } from 'functions/generateRoute'; import { hasDistribution } from 'helpers/aggregator'; import { CurrencyAmount, TokenType } from 'interfaces'; -import { useEffect, useMemo, useState } from 'react'; +import { useContext, useEffect, useMemo, useState } from 'react'; import { TradeType as SdkTradeType } from 'soroswap-router-sdk'; import { InterfaceTrade, QuoteState, TradeState, TradeType } from 'state/routing/types'; import useSWR from 'swr'; @@ -29,6 +30,7 @@ export function useBestTrade( resetRouterSdkCache: () => void; } { const { generateRoute, resetRouterSdkCache, maxHops } = useRouterSDK(); + const {protocolsStatus} = useContext(AppContext).Settings; /** * Custom hook that fetches the best trade based on the specified amount and trade type. * @@ -142,7 +144,7 @@ export function useBestTrade( } return baseTrade; - }, [expectedAmount, inputAmount, outputAmount, tradeType, data]); + }, [expectedAmount, inputAmount, outputAmount, tradeType, data, protocolsStatus]); /* If the pairAddress or the trades chenges, we upgrade the tradeResult @@ -154,7 +156,7 @@ export function useBestTrade( const myTradeResult = { state: state, trade: trade }; return myTradeResult; - }, [data, trade]); //should get the pair address and quotes + }, [data, trade, protocolsStatus]); //should get the pair address and quotes const skipFetch: boolean = false; @@ -195,6 +197,7 @@ export function useBestTrade( trade, isLoading, resetRouterSdkCache, + protocolsStatus ]); return bestTrade; From 89d7d5f588d81fa311d2cb38c858fa5c64d7e46a Mon Sep 17 00:00:00 2001 From: Matias Poblete <86752543+MattPoblete@users.noreply.github.com> Date: Tue, 3 Sep 2024 22:42:39 -0400 Subject: [PATCH 4/6] =?UTF-8?q?=E2=9C=A8Set=20default=20protocols=20by=20n?= =?UTF-8?q?etwork?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + src/components/Providers.tsx | 21 +------- .../Settings/ProtocolsSettings/index.tsx | 1 - src/contexts/index.ts | 4 -- src/functions/generateRoute.ts | 48 ++++++++++++++++++- 5 files changed, 50 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index ca9df5e7..0ee7c692 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,8 @@ cp .env.production.example .env You have successfully set up Soroswap on your local machine! Start swapping, pooling, and exploring the possibilities of decentralized finance (DeFi) on the Soroban network. +If you want to add or remove supported protocols, you can do so by editing the `functions/generateRoute.ts:79-97` file and adding or removing the protocols you want to support on swap. + ## 🧪🔨 Testing 🧪🔨 To execute the tests, you must first start the development container. To do this, run the following command from your host machine: diff --git a/src/components/Providers.tsx b/src/components/Providers.tsx index e2d0d44d..1669b353 100644 --- a/src/components/Providers.tsx +++ b/src/components/Providers.tsx @@ -1,15 +1,13 @@ import { Analytics } from '@vercel/analytics/react'; import { AppContext, AppContextType, ColorModeContext, SnackbarIconType, ProtocolsStatus } from 'contexts'; import { Provider } from 'react-redux'; -import { useEffect, useMemo, useState } from 'react'; +import { useMemo, useState } from 'react'; import InkathonProvider from 'inkathon/InkathonProvider'; import MainLayout from './Layout/MainLayout'; import MySorobanReactProvider from 'soroban/MySorobanReactProvider'; import store from 'state'; import { SorobanContextType } from '@soroban-react/core'; import { SoroswapThemeProvider } from 'soroswap-ui'; -import { Protocols } from 'soroswap-router-sdk'; -import { PlatformType } from 'state/routing/types'; export default function Providers({ children, @@ -21,20 +19,7 @@ export default function Providers({ const [isConnectWalletModal, setConnectWalletModal] = useState(false); const [maxHops, setMaxHops] = useState(2); - - //Defines the default protocols to be used in the app - const defaultProtocols = [ - Protocols.SOROSWAP - ] - const [protocols, setProtocols] = useState(defaultProtocols); - - //Defines the default platforms to be used in the app - const defaultProtocolsStatus: ProtocolsStatus[] = [ - { key: Protocols.SOROSWAP, value: true }, - { key: Protocols.PHOENIX, value: false }, - { key: PlatformType.STELLAR_CLASSIC, value: true }, - ] - const [protocolsStatus, setProtocolsStatus] = useState(defaultProtocolsStatus); + const [protocolsStatus, setProtocolsStatus] = useState([]); const [openSnackbar, setOpenSnackbar] = useState(false); const [snackbarMessage, setSnackbarMessage] = useState(''); const [snackbarTitle, setSnackbarTitle] = useState('Swapped'); @@ -68,8 +53,6 @@ export default function Providers({ Settings: { maxHops, setMaxHops, - protocols, - setProtocols, protocolsStatus, setProtocolsStatus, }, diff --git a/src/components/Settings/ProtocolsSettings/index.tsx b/src/components/Settings/ProtocolsSettings/index.tsx index 921f0077..12276c4f 100644 --- a/src/components/Settings/ProtocolsSettings/index.tsx +++ b/src/components/Settings/ProtocolsSettings/index.tsx @@ -83,7 +83,6 @@ const ProtocolsSettings = () => { setProtocolsStatus(newProtocolsStatus); mutate( (key: any) => { - console.log(key) return true; }, undefined, diff --git a/src/contexts/index.ts b/src/contexts/index.ts index 0b6ef333..f3a45c7d 100644 --- a/src/contexts/index.ts +++ b/src/contexts/index.ts @@ -34,8 +34,6 @@ export type SnackbarContextType = { export type Settings = { maxHops: number; setMaxHops: React.Dispatch>; - protocols: Protocols[]; - setProtocols: React.Dispatch>; protocolsStatus: ProtocolsStatus[]; setProtocolsStatus: React.Dispatch>; }; @@ -68,8 +66,6 @@ export const AppContext = React.createContext({ Settings: { maxHops: 2, setMaxHops: () => {}, - protocols: [], - setProtocols: () => {}, protocolsStatus: [], setProtocolsStatus: () => {}, }, diff --git a/src/functions/generateRoute.ts b/src/functions/generateRoute.ts index 74b3bb1e..052a5fe9 100644 --- a/src/functions/generateRoute.ts +++ b/src/functions/generateRoute.ts @@ -2,7 +2,7 @@ import { useSorobanReact } from '@soroban-react/core'; import { AppContext } from 'contexts'; import { useFactory } from 'hooks'; import { useAggregator } from 'hooks/useAggregator'; -import { useContext, useMemo } from 'react'; +import { useContext, useEffect, useMemo } from 'react'; import { fetchAllPhoenixPairs, fetchAllSoroswapPairs } from 'services/pairs'; import { Currency, @@ -57,10 +57,54 @@ export const useRouterSDK = () => { const { isEnabled: isAggregator } = useAggregator(); const { Settings } = useContext(AppContext); - const { maxHops, protocols, protocolsStatus } = Settings; + const { maxHops, protocolsStatus, setProtocolsStatus } = Settings; const network = sorobanContext.activeChain?.networkPassphrase as Networks; + const getValuebyKey = (key: string) => { + let value = protocolsStatus.find((p) => p.key === key)?.value; + if (typeof value === 'undefined') { + return false; + } + if (typeof value === 'undefined' && key === Protocols.SOROSWAP) { + return true; + } + if (value === true || value === false) { + return value; + } + return value; + } + + const getDefaultProtocolsStatus = async (network: Networks) => { + switch (network) { + case Networks.PUBLIC: + // here you should add your new supported protocols + return [ + { key: Protocols.SOROSWAP , value: getValuebyKey(Protocols.SOROSWAP) }, + { key: PlatformType.STELLAR_CLASSIC, value: getValuebyKey(PlatformType.STELLAR_CLASSIC) }, + ]; + case Networks.TESTNET: + return [ + { key: Protocols.SOROSWAP, value: getValuebyKey(Protocols.SOROSWAP) }, + { key: Protocols.PHOENIX, value: getValuebyKey(Protocols.PHOENIX) }, + ]; + default: + return [ + { key: Protocols.SOROSWAP, value: true }, + { key: Protocols.PHOENIX, value: false }, + { key: PlatformType.STELLAR_CLASSIC, value: false }, + ]; + } + } + + useEffect(() => { + const fetchProtocolsStatus = async () => { + const defaultProtocols = await getDefaultProtocolsStatus(network); + setProtocolsStatus(defaultProtocols); + }; + fetchProtocolsStatus(); + }, [network]); + const getPairsFns = useMemo(() => { const routerProtocols = [] if(!shouldUseBackend) return undefined From af19e05562d3b3711c6a5a364f6a45b8ab3f0061 Mon Sep 17 00:00:00 2001 From: Matias Poblete <86752543+MattPoblete@users.noreply.github.com> Date: Tue, 3 Sep 2024 23:10:49 -0400 Subject: [PATCH 5/6] =?UTF-8?q?=F0=9F=A9=B9Fix=20no=20protocols=20enabled?= =?UTF-8?q?=20on=20network=20change?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +++ src/functions/generateRoute.ts | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0ee7c692..a8582b7c 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,9 @@ You have successfully set up Soroswap on your local machine! Start swapping, poo If you want to add or remove supported protocols, you can do so by editing the `functions/generateRoute.ts:79-97` file and adding or removing the protocols you want to support on swap. +> [!HINT] +> You can found the list of supported protocols in the `soroswap-router-sdk` repository. + ## 🧪🔨 Testing 🧪🔨 To execute the tests, you must first start the development container. To do this, run the following command from your host machine: diff --git a/src/functions/generateRoute.ts b/src/functions/generateRoute.ts index 052a5fe9..6508da6c 100644 --- a/src/functions/generateRoute.ts +++ b/src/functions/generateRoute.ts @@ -63,12 +63,12 @@ export const useRouterSDK = () => { const getValuebyKey = (key: string) => { let value = protocolsStatus.find((p) => p.key === key)?.value; + if (value === undefined && key === Protocols.SOROSWAP) { + return true; + } if (typeof value === 'undefined') { return false; } - if (typeof value === 'undefined' && key === Protocols.SOROSWAP) { - return true; - } if (value === true || value === false) { return value; } From 83eb3429b913bf3456335027692960ecdf1b04f3 Mon Sep 17 00:00:00 2001 From: Matias Poblete <86752543+MattPoblete@users.noreply.github.com> Date: Tue, 3 Sep 2024 23:15:19 -0400 Subject: [PATCH 6/6] =?UTF-8?q?=F0=9F=A9=B9Fix=20disabled=20loading=20befo?= =?UTF-8?q?re=20path=20is=20ready?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Swap/SwapPathComponent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Swap/SwapPathComponent.tsx b/src/components/Swap/SwapPathComponent.tsx index d9e41bb9..10715c5f 100644 --- a/src/components/Swap/SwapPathComponent.tsx +++ b/src/components/Swap/SwapPathComponent.tsx @@ -106,8 +106,8 @@ function SwapPathComponent({ trade }: { trade: InterfaceTrade | undefined }) { tempDistributionArray.push({ path: fulfilledValues, parts: distribution.parts, protocol: distribution.protocol_id }); setDistributionArray(tempDistributionArray); setTotalParts(tempDistributionArray.reduce((acc, curr) => acc + curr.parts, 0)); - setPathTokensIsLoading(false); } + setPathTokensIsLoading(false); } })(); }, [trade?.path, isLoading, sorobanContext]);