Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨Show aggregator paths in advanced swap details #531

Merged
merged 6 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 13 additions & 71 deletions src/components/Swap/AdvancedSwapDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { BodySmall } from 'components/Text';
import React from 'react';
import { BodySmall, } from 'components/Text';
import { Box, styled } from 'soroswap-ui';
import { ChevronRight } from '@mui/icons-material';
import { useSorobanReact } from '@soroban-react/core';
import Column from 'components/Column';
import { LoadingRows } from 'components/Loader/styled';
import CurrencyLogo from 'components/Logo/CurrencyLogo';
Expand All @@ -10,19 +9,11 @@ import { Separator } from 'components/SearchModal/styleds';
import { MouseoverTooltip } from 'components/Tooltip';
import { formatTokenAmount } from 'helpers/format';
import { useAllTokens } from 'hooks/tokens/useAllTokens';
import { findToken } from 'hooks/tokens/useToken';
import React, { useEffect, useState } from 'react';
import { Percent } from 'soroswap-router-sdk';
import { InterfaceTrade, PlatformType } from 'state/routing/types';
import SwapPathComponent from './SwapPathComponent';
import { InterfaceTrade } from 'state/routing/types';

export const PathBox = styled(Box)`
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
`;

interface AdvancedSwapDetailsProps {
export interface AdvancedSwapDetailsProps {
trade: InterfaceTrade | undefined;
allowedSlippage: number;
syncing?: boolean;
Expand Down Expand Up @@ -63,6 +54,13 @@ export const formattedPriceImpact = (priceImpact: Percent | Number | undefined)
return `~${priceImpact?.toFixed(2)}%`;
};

export const FormattedProtocolName = (protocol: string) => {
return protocol.charAt(0).toUpperCase() + protocol.slice(1);
}
export const calculatePercentage = (parts: number, totalParts: number) => {
return (parts / totalParts) * 100;
}

export function AdvancedSwapDetails({
trade,
allowedSlippage,
Expand All @@ -72,42 +70,8 @@ export function AdvancedSwapDetails({
// const { chainId } = useWeb3React()
// const nativeCurrency = useNativeCurrency(chainId)
// const txCount = getTransactionCount(trade)
const sorobanContext = useSorobanReact();
const { tokensAsMap, isLoading } = useAllTokens();

const [pathArray, setPathArray] = useState<string[]>([]);

const [pathTokensIsLoading, setPathTokensIsLoading] = useState(false);

useEffect(() => {
(async () => {
if (!trade?.path || isLoading) return;
if (trade.platform == PlatformType.ROUTER) {
setPathTokensIsLoading(true);
const promises = trade.path.map(async (contract) => {
const asset = await findToken(contract, tokensAsMap, sorobanContext);
const code = asset?.code == 'native' ? 'XLM' : asset?.code;
return code;
});
const results = await Promise.allSettled(promises);

const fulfilledValues = results
.filter((result) => result.status === 'fulfilled' && result.value)
.map((result) => (result.status === 'fulfilled' && result.value ? result.value : ''));
setPathArray(fulfilledValues);
setPathTokensIsLoading(false);
} else if (trade.platform == PlatformType.STELLAR_CLASSIC) {
setPathTokensIsLoading(true);
const codes = trade.path.map((address) => {
if (address == 'native') return 'XLM';
return address.split(':')[0];
});
setPathArray(codes);
setPathTokensIsLoading(false);
}
})();
}, [trade?.path, isLoading, sorobanContext]);

return (
<Column gap="md">
<Separator />
Expand Down Expand Up @@ -160,29 +124,7 @@ export function AdvancedSwapDetails({
</BodySmall>
</TextWithLoadingPlaceholder>
</RowBetween>
{
<RowBetween>
<RowFixed>
<MouseoverTooltip
title={`
Routing through these assets resulted in the best price for your trade
`}
>
<BodySmall color="textSecondary">Path</BodySmall>
</MouseoverTooltip>
</RowFixed>
<TextWithLoadingPlaceholder syncing={pathTokensIsLoading} width={100}>
<PathBox data-testid="swap__details__path">
{pathArray?.map((contract, index) => (
<React.Fragment key={index}>
{contract}
{index !== pathArray.length - 1 && <ChevronRight style={{ opacity: '50%' }} />}
</React.Fragment>
))}
</PathBox>
</TextWithLoadingPlaceholder>
</RowBetween>
}
<SwapPathComponent trade={trade} />
{trade?.platform && (
<RowBetween>
<MouseoverTooltip title={'The platform where the swap will be made.'}>
Expand Down
77 changes: 8 additions & 69 deletions src/components/Swap/SwapModalFooter.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
import { CircularProgress, styled, useTheme } from 'soroswap-ui';
import { useSorobanReact } from '@soroban-react/core';
import BigNumber from 'bignumber.js';
import { styled, useTheme } from 'soroswap-ui';
import { ButtonError, SmallButtonPrimary } from 'components/Buttons/Button';
import Column from 'components/Column';
import CurrencyLogo from 'components/Logo/CurrencyLogo';
import Row, { AutoRow, RowBetween, RowFixed } from 'components/Row';
import { BodySmall, HeadlineSmall, SubHeaderSmall } from 'components/Text';
import { MouseoverTooltip } from 'components/Tooltip';
import { getPriceImpactNew2 } from 'functions/getPriceImpact';
import { formatTokenAmount, twoDecimalsPercentage } from 'helpers/format';
import { useAllTokens } from 'hooks/tokens/useAllTokens';
import { findToken } from 'hooks/tokens/useToken';
import useGetReservesByPair from 'hooks/useGetReservesByPair';
import { formatTokenAmount } from 'helpers/format';
import { getSwapAmounts } from 'hooks/useSwapCallback';
import React, { ReactNode, useEffect, useState } from 'react';
import { AlertTriangle, ChevronRight } from 'react-feather';
import { InterfaceTrade, PlatformType, TradeType } from 'state/routing/types';
import { PathBox, TextWithLoadingPlaceholder, formattedPriceImpact } from './AdvancedSwapDetails';
import React, { ReactNode } from 'react';
import { AlertTriangle } from 'react-feather';
import { InterfaceTrade, TradeType } from 'state/routing/types';
import { formattedPriceImpact } from './AdvancedSwapDetails';
import { Label } from './SwapModalHeaderAmount';
import { getExpectedAmountOfOne } from './TradePrice';
import { SwapCallbackError, SwapShowAcceptChanges } from './styleds';
import SwapPathComponent from './SwapPathComponent';

const DetailsContainer = styled(Column)`
padding: 0 8px;
Expand Down Expand Up @@ -77,13 +72,10 @@ export default function SwapModalFooter({
// const routes = isClassicTrade(trade) ? getRoutingDiagramEntries(trade) : undefined
// const { chainId } = useWeb3React()
// const nativeCurrency = useNativeCurrency(chainId)
const { tokensAsMap, isLoading } = useAllTokens();

const label = `${trade?.inputAmount?.currency.code}`;
const labelInverted = `${trade?.outputAmount?.currency.code}`;

const sorobanContext = useSorobanReact();

const getSwapValues = () => {
if (!trade || !trade?.tradeType) return { formattedAmount0: '0', formattedAmount1: '0' };

Expand All @@ -100,39 +92,6 @@ export default function SwapModalFooter({
return { formattedAmount0, formattedAmount1 };
};

const [pathArray, setPathArray] = useState<string[]>([]);

const [pathTokensIsLoading, setPathTokensIsLoading] = useState(false);

useEffect(() => {
(async () => {
if (!trade?.path || isLoading) return;
if (trade.platform == PlatformType.ROUTER) {
setPathTokensIsLoading(true);
const promises = trade.path.map(async (contract) => {
const asset = await findToken(contract, tokensAsMap, sorobanContext);
const code = asset?.code == 'native' ? 'XLM' : asset?.code;
return code;
});
const results = await Promise.allSettled(promises);

const fulfilledValues = results
.filter((result) => result.status === 'fulfilled' && result.value)
.map((result) => (result.status === 'fulfilled' && result.value ? result.value : ''));
setPathArray(fulfilledValues);
setPathTokensIsLoading(false);
} else if (trade.platform == PlatformType.STELLAR_CLASSIC) {
setPathTokensIsLoading(true);
const codes = trade.path.map((address) => {
if (address == "native") return "XLM"
return address.split(":")[0]
})
setPathArray(codes);
setPathTokensIsLoading(false);
}
})();
}, [trade?.path, isLoading, sorobanContext]);

return (
<>
<DetailsContainer gap="md">
Expand Down Expand Up @@ -205,27 +164,7 @@ export default function SwapModalFooter({
</DetailRowValue>
</Row>
</BodySmall>
<RowBetween>
<RowFixed>
<MouseoverTooltip
title={`
Routing through these assets resulted in the best price for your trade
`}
>
<Label cursor="help">Path</Label>
</MouseoverTooltip>
</RowFixed>
<TextWithLoadingPlaceholder syncing={pathTokensIsLoading} width={100}>
<PathBox>
{pathArray?.map((contract, index) => (
<React.Fragment key={index}>
{contract}
{index !== pathArray.length - 1 && <ChevronRight style={{ opacity: '50%' }} />}
</React.Fragment>
))}
</PathBox>
</TextWithLoadingPlaceholder>
</RowBetween>
<SwapPathComponent trade={trade} />
{trade?.platform && (
<RowBetween>
<MouseoverTooltip title={'The platform where the swap will be made.'}>
Expand Down
Loading