diff --git a/src/components/Swap/PendingModalContent/TradeSummary.tsx b/src/components/Swap/PendingModalContent/TradeSummary.tsx index dd9fcb29..3667420f 100644 --- a/src/components/Swap/PendingModalContent/TradeSummary.tsx +++ b/src/components/Swap/PendingModalContent/TradeSummary.tsx @@ -31,14 +31,22 @@ export function TradeSummary({ trade: Pick; }) { const getSwappedAmounts = () => { - let input = '0'; - let output = '0'; + let input = 0; + let output = 0; if (swapResult && swapResult?.switchValues) { - input = swapResult?.switchValues?.[0]; - output = swapResult?.switchValues?.[swapResult?.switchValues?.length - 1]; + if (Array.isArray(swapResult?.switchValues?.[0])) { + for (let i = 0; i < swapResult?.switchValues.length; i++) { + const values = swapResult?.switchValues[i]; + input += Number(values[0]); + output += Number(values[values.length - 1]); + } + } else { + input = Number(swapResult?.switchValues?.[0]); + output = Number(swapResult?.switchValues?.[swapResult?.switchValues?.length - 1]); + } } else { - input = trade?.inputAmount?.value ?? '0'; - output = trade?.outputAmount?.value ?? '0'; + input = Number(trade?.inputAmount?.value ?? '0'); + output = Number(trade?.outputAmount?.value ?? '0'); } const formattedInput = formatTokenAmount(input); diff --git a/src/functions/generateRoute.ts b/src/functions/generateRoute.ts index a414358b..3004cd49 100644 --- a/src/functions/generateRoute.ts +++ b/src/functions/generateRoute.ts @@ -64,7 +64,7 @@ export const useRouterSDK = () => { const router = useMemo(() => { const protocols = [Protocols.SOROSWAP]; - if (isAggregator) protocols.push(Protocols.PHOENIX); + // if (isAggregator) protocols.push(Protocols.PHOENIX); return new Router({ getPairsFns: shouldUseBackend @@ -119,38 +119,31 @@ export const useRouterSDK = () => { tradeType, }; - const horizonPath = await getHorizonBestPath( - horizonProps, - sorobanContext, - ) as BuildTradeRoute; + const horizonPath = (await getHorizonBestPath(horizonProps, sorobanContext)) as BuildTradeRoute; let sorobanPath: BuildTradeRoute; if (isAggregator) { - sorobanPath = (await router.routeSplit(currencyAmount, quoteCurrency, tradeType).then((response)=>{ - if(!response) return undefined; - const result = { - ...response, - platform: PlatformType.ROUTER, - }; - return result; - } - )) as BuildTradeRoute; + sorobanPath = (await router + .routeSplit(currencyAmount, quoteCurrency, tradeType) + .then((response) => { + if (!response) return undefined; + const result = { + ...response, + platform: PlatformType.AGGREGATOR, + }; + return result; + })) as BuildTradeRoute; } else { - sorobanPath = (await router.route( - currencyAmount, - quoteCurrency, - tradeType, - factory, - sorobanContext as any, - ).then((response)=>{ - if(!response) return undefined; + sorobanPath = (await router + .route(currencyAmount, quoteCurrency, tradeType, factory, sorobanContext as any) + .then((response) => { + if (!response) return undefined; const result = { ...response, platform: PlatformType.ROUTER, }; return result; - } - )) as BuildTradeRoute; + })) as BuildTradeRoute; } const bestPath = getBestPath(horizonPath, sorobanPath, tradeType); // .then((res) => { diff --git a/src/helpers/aggregator/index.ts b/src/helpers/aggregator/index.ts index 56143c09..3aa1979c 100644 --- a/src/helpers/aggregator/index.ts +++ b/src/helpers/aggregator/index.ts @@ -1,23 +1,18 @@ -import { Address, nativeToScVal, xdr } from "@stellar/stellar-sdk"; +import { Address, nativeToScVal, xdr } from '@stellar/stellar-sdk'; export interface DexDistribution { protocol_id: string; - path: string[], - parts: number, - is_exact_in: boolean, + path: string[]; + parts: number; + is_exact_in: boolean; } -export const dexDistributionParser = (dexDistributionRaw: DexDistribution[]) : xdr.ScVal => { - +export const dexDistributionParser = (dexDistributionRaw: DexDistribution[]): xdr.ScVal => { const dexDistributionScVal = dexDistributionRaw.map((distribution) => { return xdr.ScVal.scvMap([ - new xdr.ScMapEntry({ - key: xdr.ScVal.scvSymbol('is_exact_in'), - val: xdr.ScVal.scvBool(distribution.is_exact_in), - }), new xdr.ScMapEntry({ key: xdr.ScVal.scvSymbol('parts'), - val: nativeToScVal(distribution.parts, {type: "i128"}), + val: nativeToScVal(distribution.parts, { type: 'u32' }), }), new xdr.ScMapEntry({ key: xdr.ScVal.scvSymbol('path'), @@ -30,7 +25,8 @@ export const dexDistributionParser = (dexDistributionRaw: DexDistribution[]) : x ]); }); - return xdr.ScVal.scvVec(dexDistributionScVal) -} + return xdr.ScVal.scvVec(dexDistributionScVal); +}; -export const hasDistribution = (trade: any): trade is { distribution: DexDistribution[] } => trade && 'distribution' in trade; +export const hasDistribution = (trade: any): trade is { distribution: DexDistribution[] } => + trade && 'distribution' in trade; diff --git a/src/hooks/useAggregator.tsx b/src/hooks/useAggregator.tsx index 4edad8f5..0d6b10e0 100644 --- a/src/hooks/useAggregator.tsx +++ b/src/hooks/useAggregator.tsx @@ -16,13 +16,13 @@ export const useAggregator = () => { if (activeChain?.id == 'mainnet') { //TODO: Add mainnet aggregator address - setAddress('CD4NUEFTQU53SM7LPAQX5RHJOWOLOHRBM4HCNGA7UBQJ6MPIJNVGYEVL'); + setAddress('CA4VZX7N577XGPSKDG4RT24CZ6XGR37TM2652SO2AASERVUWP72N4UGZ'); setIsAggregatorEnabled(false && shouldUseAggregator); } else if (activeChain?.id == 'testnet') { - setAddress('CD4NUEFTQU53SM7LPAQX5RHJOWOLOHRBM4HCNGA7UBQJ6MPIJNVGYEVL'); + setAddress('CA4VZX7N577XGPSKDG4RT24CZ6XGR37TM2652SO2AASERVUWP72N4UGZ'); setIsAggregatorEnabled(true && shouldUseAggregator); } else { - setAddress('CD4NUEFTQU53SM7LPAQX5RHJOWOLOHRBM4HCNGA7UBQJ6MPIJNVGYEVL'); + setAddress('CA4VZX7N577XGPSKDG4RT24CZ6XGR37TM2652SO2AASERVUWP72N4UGZ'); setIsAggregatorEnabled(false && shouldUseAggregator); } }, [activeChain?.id, sorobanContext]); diff --git a/src/hooks/useAggregatorCallback.tsx b/src/hooks/useAggregatorCallback.tsx index c089a69e..ada02ee2 100644 --- a/src/hooks/useAggregatorCallback.tsx +++ b/src/hooks/useAggregatorCallback.tsx @@ -6,9 +6,10 @@ import { useCallback } from 'react'; import { useAggregator } from './useAggregator'; export enum AggregatorMethod { - SWAP = 'swap', GET_PROTOCOLS = 'get_protocols', IS_PROTOCOL_PAUSED = 'is_protocol_paused', + SWAP_EXACT_IN = 'swap_exact_tokens_for_tokens', + SWAP_EXACT_OUT = 'swap_tokens_for_exact_tokens', } // fn swap( diff --git a/src/hooks/useSwapCallback.tsx b/src/hooks/useSwapCallback.tsx index c42b953a..c44a48e9 100644 --- a/src/hooks/useSwapCallback.tsx +++ b/src/hooks/useSwapCallback.tsx @@ -70,6 +70,11 @@ export const getSwapAmounts = ({ const routerMethod = tradeType == TradeType.EXACT_INPUT ? RouterMethod.SWAP_EXACT_IN : RouterMethod.SWAP_EXACT_OUT; + const aggregatorMethod = + tradeType == TradeType.EXACT_INPUT + ? AggregatorMethod.SWAP_EXACT_IN + : AggregatorMethod.SWAP_EXACT_OUT; + const factorLess = BigNumber(100).minus(allowedSlippage).dividedBy(100); const factorMore = BigNumber(100).plus(allowedSlippage).dividedBy(100); @@ -83,7 +88,7 @@ export const getSwapAmounts = ({ ? BigNumber(outputAmount).multipliedBy(factorLess).decimalPlaces(0) : BigNumber(inputAmount).multipliedBy(factorMore).decimalPlaces(0); - return { amount0, amount1, routerMethod }; + return { amount0, amount1, routerMethod, aggregatorMethod }; }; export type SuccessfullSwapResponse = StellarSdk.SorobanRpc.Api.GetSuccessfulTransactionResponse & @@ -118,7 +123,7 @@ export function useSwapCallback( if (!address || !activeChain) throw new Error('wallet must be connected to swap'); if (!trade.tradeType) throw new Error('tradeType must be defined'); - const { amount0, amount1, routerMethod } = getSwapAmounts({ + const { amount0, amount1, routerMethod, aggregatorMethod } = getSwapAmounts({ tradeType: trade.tradeType, inputAmount: trade.inputAmount?.value as string, outputAmount: trade.outputAmount?.value as string, @@ -189,7 +194,7 @@ export function useSwapCallback( try { const result = (await aggregatorCallback( - AggregatorMethod.SWAP, + aggregatorMethod, aggregatorSwapParams, !simulation, )) as StellarSdk.SorobanRpc.Api.GetTransactionResponse; @@ -203,12 +208,19 @@ export function useSwapCallback( const switchValues: string[] = scValToJs(result.returnValue!); - const currencyA = switchValues?.[0]; - const currencyB = switchValues?.[switchValues?.length - 1]; + let currencyA = 0; + let currencyB = 0; - const notificationMessage = `${formatTokenAmount(currencyA ?? '0')} ${trade?.inputAmount - ?.currency.code} for ${formatTokenAmount(currencyB ?? '0')} ${trade?.outputAmount - ?.currency.code}`; + for (let i = 0; i < switchValues.length; i++) { + const values = switchValues[i]; + + currencyA += Number(values[0]); + currencyB += Number(values[values.length - 1]); + } + + const notificationMessage = `${formatTokenAmount(currencyA)} ${trade?.inputAmount + ?.currency.code} for ${formatTokenAmount(currencyB)} ${trade?.outputAmount?.currency + .code}`; sendNotification(notificationMessage, 'Swapped', SnackbarIconType.SWAP, SnackbarContext); @@ -232,7 +244,7 @@ export function useSwapCallback( return result!; } catch (error: any) { console.error(error); - throw new Error('Cannot create path payment') + throw new Error('Cannot create path payment'); } default: throw new Error('Unsupported platform');