Skip to content

Commit

Permalink
🚧Add switches to toggle protocols
Browse files Browse the repository at this point in the history
  • Loading branch information
MattPoblete committed Aug 30, 2024
1 parent b9e9c89 commit 1a5535c
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 29 deletions.
26 changes: 22 additions & 4 deletions src/components/Providers.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -21,6 +22,19 @@ export default function Providers({

const [maxHops, setMaxHops] = useState<number>(2);

//Defines the default protocols to be used in the app
const defaultProtocols = [
Protocols.SOROSWAP
]
const [protocols, setProtocols] = useState<Protocols[]>(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<ProtocolsStatus[]>(defaultProtocolsStatus);
const [openSnackbar, setOpenSnackbar] = useState<boolean>(false);
const [snackbarMessage, setSnackbarMessage] = useState<string>('');
const [snackbarTitle, setSnackbarTitle] = useState<string>('Swapped');
Expand Down Expand Up @@ -54,6 +68,10 @@ export default function Providers({
Settings: {
maxHops,
setMaxHops,
protocols,
setProtocols,
protocolsStatus,
setProtocolsStatus,
},
};

Expand Down
132 changes: 132 additions & 0 deletions src/components/Settings/ProtocolsSettings/index.tsx
Original file line number Diff line number Diff line change
@@ -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) => (
<Switch sx={{ my: 1 }} focusVisibleClassName=".Mui-focusVisible" disableRipple {...props} />
))(({ 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<boolean>(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 (

<Expand
testId="protocols-settings"
isOpen={isOpen}
onToggle={() => setIsOpen(!isOpen)}
header={
<Row width="auto">
<Typography color={theme.palette.secondary.main}>Protocols</Typography>
<QuestionHelper
text={
<div>
The protocols Soroswap.finance will use to calculate the most efficient path for your transaction.
</div>
}
/>
</Row>
}
button={<></>}
>
<RowBetween gap="md" width={'100%'}>
<Box sx={{ ml: 2 }} width={'100%'} >
{protocolsStatus.map((option, index) => {
return (
<Row key={index} gap="4px" justify='space-between' align='center'>
<BodySmall fontWeight={100} color={theme.palette.secondary.main} >{firstLetterUppercase(option.key)}</BodySmall>
<CustomSwitch checked={option.value} onClick={() => { switchProtocolValue(option.key) }} color="secondary" />
</Row>
)
})}
{ }
</Box>
</RowBetween>

</Expand>

)
}

export default ProtocolsSettings
2 changes: 2 additions & 0 deletions src/components/Settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -74,6 +75,7 @@ export default function SettingsTab({
<ExpandColumn>
<MaxSlippageSettings autoSlippage={autoSlippage} />
<MaxHopsSettings />
<ProtocolsSettings />
</ExpandColumn>
</AnimatedDropdown>
</MenuFlyout>
Expand Down
15 changes: 15 additions & 0 deletions src/contexts/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React from 'react';
import { Protocols } from 'soroswap-router-sdk';
import { PlatformType } from 'state/routing/types';

type ConnectWalletModalType = {
isConnectWalletModalOpen: boolean;
Expand All @@ -13,6 +15,11 @@ export enum SnackbarIconType {
ERROR,
}

export interface ProtocolsStatus {
key: Protocols | PlatformType;
value: boolean;
}

export type SnackbarContextType = {
openSnackbar: boolean;
snackbarMessage: string;
Expand All @@ -27,6 +34,10 @@ export type SnackbarContextType = {
export type Settings = {
maxHops: number;
setMaxHops: React.Dispatch<React.SetStateAction<number>>;
protocols: Protocols[];
setProtocols: React.Dispatch<React.SetStateAction<Protocols[]>>;
protocolsStatus: ProtocolsStatus[];
setProtocolsStatus: React.Dispatch<React.SetStateAction<ProtocolsStatus[]>>;
};

export type AppContextType = {
Expand Down Expand Up @@ -57,5 +68,9 @@ export const AppContext = React.createContext<AppContextType>({
Settings: {
maxHops: 2,
setMaxHops: () => {},
protocols: [],
setProtocols: () => {},
protocolsStatus: [],
setProtocolsStatus: () => {},
},
});
68 changes: 43 additions & 25 deletions src/functions/generateRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Currency>;
Expand Down Expand Up @@ -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,
});
Expand Down Expand Up @@ -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
Expand All @@ -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;
// });

0 comments on commit 1a5535c

Please sign in to comment.