From 2d1b611468d6f353ecba43fc514109ea3312f62e Mon Sep 17 00:00:00 2001 From: Kyle Fang Date: Thu, 24 Aug 2023 16:17:58 +0800 Subject: [PATCH] feat(Swap): add review step --- .../swap-assets-pair/swap-assets-pair.tsx | 2 +- .../components/swap-details/swap-details.tsx | 30 ++++++-- src/app/pages/swap/swap-container.tsx | 71 +++++++++++++++---- src/app/pages/swap/swap.context.ts | 11 +++ 4 files changed, 95 insertions(+), 19 deletions(-) diff --git a/src/app/pages/swap/components/swap-assets-pair/swap-assets-pair.tsx b/src/app/pages/swap/components/swap-assets-pair/swap-assets-pair.tsx index b6377926..a0dfb470 100644 --- a/src/app/pages/swap/components/swap-assets-pair/swap-assets-pair.tsx +++ b/src/app/pages/swap/components/swap-assets-pair/swap-assets-pair.tsx @@ -32,6 +32,6 @@ export function SwapAssetsPair() { value={swapAmountTo} /> } - > + /> ); } diff --git a/src/app/pages/swap/components/swap-details/swap-details.tsx b/src/app/pages/swap/components/swap-details/swap-details.tsx index 27c5fe64..67596ad7 100644 --- a/src/app/pages/swap/components/swap-details/swap-details.tsx +++ b/src/app/pages/swap/components/swap-details/swap-details.tsx @@ -1,14 +1,34 @@ +import { useSwapContext } from '@app/pages/swap/swap.context'; + import { SwapDetailLayout } from './swap-detail.layout'; import { SwapDetailsLayout } from './swap-details.layout'; -// TODO: Replace with live data export function SwapDetails() { + const { swapSubmissionData } = useSwapContext(); + if (swapSubmissionData == null) { + return null; + } return ( - - - - + x.name).join(' > ')} + /> + + + ); } diff --git a/src/app/pages/swap/swap-container.tsx b/src/app/pages/swap/swap-container.tsx index edf12dff..260da36f 100644 --- a/src/app/pages/swap/swap-container.tsx +++ b/src/app/pages/swap/swap-container.tsx @@ -13,7 +13,7 @@ import { whenPageMode } from '@app/common/utils'; import { SwapContainerLayout } from './components/swap-container.layout'; import { SwapForm } from './components/swap-form'; import { SwapAsset, SwapFormValues } from './hooks/use-swap'; -import { SwapContext, SwapProvider } from './swap.context'; +import { SwapContext, SwapProvider, SwapSubmissionData } from './swap.context'; export function SwapContainer() { const alexSDK = useState(() => new AlexSDK())[0]; @@ -55,26 +55,71 @@ export function SwapContainer() { [getAssetFromAlexCurrency, supportedCurrencies] ); - function onSubmitSwapForReview(values: SwapFormValues) { - navigate(RouteUrls.SwapReview, { - state: { ...values }, + const [swapSubmissionData, setSwapSubmissionData] = useState(); + const [slippage, _setSlippage] = useState(0.04); + + async function onSubmitSwapForReview(values: SwapFormValues) { + if (values.swapAssetFrom == null || values.swapAssetTo == null) { + return; + } + const [router, lpFee] = await Promise.all([ + alexSDK.getRouter(values.swapAssetFrom.currency, values.swapAssetTo.currency), + alexSDK.getFeeRate(values.swapAssetFrom.currency, values.swapAssetTo.currency), + ]); + setSwapSubmissionData({ + swapAmountFrom: values.swapAmountFrom, + swapAmountTo: values.swapAmountTo, + swapAssetFrom: values.swapAssetFrom, + swapAssetTo: values.swapAssetTo, + router: router.map(x => getAssetFromAlexCurrency(supportedCurrencies.find(y => y.id === x)!)), + liquidityFee: new BigNumber(Number(lpFee)).dividedBy(1e8).toNumber(), + slippage, }); + navigate(RouteUrls.SwapReview); } - // TODO: Generate/broadcast transaction > pass real tx data function onSubmitSwap() { + if (swapSubmissionData == null) { + return; + } + const fromAmount = BigInt( + new BigNumber(swapSubmissionData.swapAmountFrom).multipliedBy(1e8).dp(0).toString() + ); + const minToAmount = BigInt( + new BigNumber(swapSubmissionData.swapAmountTo) + .multipliedBy(1e8) + .multipliedBy(1 - slippage) + .dp(0) + .toString() + ); + const txToBroadcast = alexSDK.runSwap( + '', // TODO: current user's stxAddress + swapSubmissionData.swapAssetFrom.currency, + swapSubmissionData.swapAssetTo.currency, + fromAmount, + minToAmount, + swapSubmissionData.router.map(x => x.currency) + ); + // TODO: broadcast the tx + console.log(txToBroadcast); navigate(RouteUrls.SwapSummary); } + async function fetchToAmount( + from: SwapAsset, + to: SwapAsset, + fromAmount: string + ): Promise { + const result = await alexSDK.getAmountTo( + from.currency, + BigInt(new BigNumber(fromAmount).multipliedBy(1e8).dp(0).toString()), + to.currency + ); + return new BigNumber(Number(result)).dividedBy(1e8).toString(); + } const swapContextValue: SwapContext = { - async fetchToAmount(from: SwapAsset, to: SwapAsset, fromAmount: string): Promise { - const result = await alexSDK.getAmountTo( - from.currency, - BigInt(new BigNumber(fromAmount).multipliedBy(1e8).dp(0).toString()), - to.currency - ); - return new BigNumber(Number(result)).dividedBy(1e8).toString(); - }, + swapSubmissionData, + fetchToAmount, onSubmitSwapForReview, onSubmitSwap, swappableAssets: swappableAssets, diff --git a/src/app/pages/swap/swap.context.ts b/src/app/pages/swap/swap.context.ts index a27b35e0..a3a215e1 100644 --- a/src/app/pages/swap/swap.context.ts +++ b/src/app/pages/swap/swap.context.ts @@ -2,7 +2,18 @@ import { createContext, useContext } from 'react'; import { SwapAsset, SwapFormValues } from './hooks/use-swap'; +export interface SwapSubmissionData { + swapAmountFrom: string; + swapAmountTo: string; + swapAssetFrom: SwapAsset; + swapAssetTo: SwapAsset; + liquidityFee: number; + router: SwapAsset[]; + slippage: number; +} + export interface SwapContext { + swapSubmissionData?: SwapSubmissionData; fetchToAmount(from: SwapAsset, to: SwapAsset, fromAmount: string): Promise; onSubmitSwapForReview(values: SwapFormValues): Promise | void; onSubmitSwap(): Promise | void;