Skip to content

Commit

Permalink
pancake limit
Browse files Browse the repository at this point in the history
  • Loading branch information
denis-orbs committed Mar 2, 2024
1 parent 65eb9d8 commit 65c80cb
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 85 deletions.
24 changes: 12 additions & 12 deletions packages/dapp-example/src/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,31 +194,31 @@ export const usePriceUSD = (address?: string) => {
function delay(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

const handleAddress = (address?: string) => {
if (address === "BNB") return zeroAddress;
return address;
};
export const useTrade = (fromToken?: TokenData, toToken?: TokenData, srcAmount?: string) => {
const fromTokenUsd = usePriceUSD(fromToken?.address);
const toTokenUsd = usePriceUSD(toToken?.address);
const fromTokenUsd = usePriceUSD(handleAddress(fromToken?.address));
const toTokenUsd = usePriceUSD(handleAddress(toToken?.address));
const { chainId } = useWeb3React();
const { isLimitOrder, limitDstPriceFor1Src } = store.useTwapStore((s) => ({
isLimitOrder: s.isLimitOrder,
limitDstPriceFor1Src: s.getLimitPrice(false).limitPrice,
}));

const query = useQuery({
queryKey: ["useTrade", fromToken?.address, toToken?.address, srcAmount, chainId, isLimitOrder],
queryKey: ["useTrade", fromToken?.address, toToken?.address, srcAmount, chainId],
queryFn: async () => {
await delay(1000);
const result = convertDecimals(
!isLimitOrder
? BigNumber(srcAmount!)
.times(fromTokenUsd || "0")
.div(toTokenUsd || "0")
: BigNumber(srcAmount || "0").times(limitDstPriceFor1Src),
BigNumber(srcAmount!)
.times(fromTokenUsd || "0")
.div(toTokenUsd || "0"),
fromToken!.decimals,
toToken!.decimals
).integerValue(BigNumber.ROUND_FLOOR);

return result.toString();
},
refetchInterval: 3_000,
enabled: !!fromToken && !!toToken && !!srcAmount && !!fromTokenUsd && !!toTokenUsd,
});

Expand Down
12 changes: 9 additions & 3 deletions packages/lib/src/components/Components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ const SrcTokenInput = (props: { className?: string; placeholder?: string }) => {
};

const DstTokenInput = (props: { className?: string; placeholder?: string; decimalScale?: number }) => {
const { token, amount, srcAmount, isLimitOrder } = useTwapStore((store) => ({
const { token, amount, isLimitOrder } = useTwapStore((store) => ({
token: store.dstToken,
amount: store.getDstAmountUi(),
srcAmount: store.srcAmountUi,
Expand Down Expand Up @@ -755,6 +755,7 @@ export const OrderSummaryTokenDisplay = ({ isSrc, usdSuffix, usdPrefix }: { isSr

const amount = isSrc ? srcAmount : dstAmount;
const prefix = isSrc ? "" : isLimitOrder ? "≥ " : "~ ";
const _amount = useFormatNumber({ value: amount, decimalScale: 5 });

return (
<StyledOrderSummaryTokenDisplay className="twap-orders-summary-token-display">
Expand All @@ -766,7 +767,7 @@ export const OrderSummaryTokenDisplay = ({ isSrc, usdSuffix, usdPrefix }: { isSr
<TokenLogoAndSymbol isSrc={isSrc} />
<StyledRowFlex className="twap-orders-summary-token-display-amount">
{prefix && <StyledText> {prefix}</StyledText>}
<StyledOneLineText>{amount}</StyledOneLineText>
<StyledOneLineText>{_amount}</StyledOneLineText>
</StyledRowFlex>
</StyledRowFlex>
</StyledOrderSummaryTokenDisplay>
Expand Down Expand Up @@ -1092,10 +1093,15 @@ export const CopyTokenAddress = ({ isSrc }: { isSrc: boolean }) => {
};

export const ResetLimitButton = ({ children }: { children?: ReactNode }) => {
const setLimitOrderPriceUi = useTwapStore((store) => store.setLimitOrderPriceUi);
const { setLimitOrderPriceUi, dstAmountFromDex, setOutAmount } = useTwapStore((store) => ({
setLimitOrderPriceUi: store.setLimitOrderPriceUi,
dstAmountFromDex: store.dstAmountFromDex,
setOutAmount: store.setOutAmount,
}));
const { custom } = useLimitPrice();
const onClick = () => {
setLimitOrderPriceUi();
setOutAmount(dstAmountFromDex);
};

if (!custom) return null;
Expand Down
8 changes: 4 additions & 4 deletions packages/lib/src/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ const useLimitPriceUpdater = () => {
};

const Listener = (props: TwapLibProps) => {
const { srcToken, dstToken, srcAmount, updateState } = useTwapStore((s) => ({
const { srcToken, dstToken, srcAmount, setOutAmount } = useTwapStore((s) => ({
srcToken: s.srcToken,
dstToken: s.dstToken,
srcAmount: s.getSrcAmount().toString(),

updateState: s.updateState,
setOutAmount: s.setOutAmount,
}));

const setTokensFromDappCallback = useSetTokensFromDapp();
Expand All @@ -55,8 +55,8 @@ const Listener = (props: TwapLibProps) => {
const result = props.useTrade?.(srcToken, dstToken, srcAmount === "0" ? undefined : srcAmount);

useEffect(() => {
updateState({ dstAmountLoading: result?.isLoading, dstAmount: result?.outAmount });
}, [result?.isLoading, result?.outAmount, updateState]);
setOutAmount(result?.outAmount, result?.isLoading);
}, [result?.isLoading, result?.outAmount, setOutAmount]);

useEffect(() => {
updateStoreOveride(props.storeOverride);
Expand Down
2 changes: 2 additions & 0 deletions packages/lib/src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,8 @@ export const useSetTokensFromDapp = () => {

if (srcTokenAddressOrSymbol) {
const srcToken = getTokenFromTokensList(tokensList, srcTokenAddressOrSymbol);
console.log({ srcToken });

setSrcToken(srcToken);
}
if (dstTokenAddressOrSymbol) {
Expand Down
19 changes: 16 additions & 3 deletions packages/lib/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const initialState: State = {
orderCreatedTimestamp: undefined,
dstAmount: undefined,
dstAmountLoading: false,
dstAmountFromDex: undefined,
};

export const useTwapStore = create(
Expand All @@ -75,8 +76,15 @@ export const useTwapStore = create(
dstUsd: get().dstUsd,
srcBalance: get().srcBalance,
dstBalance: get().dstBalance,
wrongNetwork: get().wrongNetwork,
});
},
setOutAmount: (dstAmount?: string, dstAmountLoading?: boolean) => {
set({ dstAmountFromDex: dstAmount });
if (!get().limitPriceUi.custom) {
set({ dstAmount, dstAmountLoading, limitPriceUi: { ...get().limitPriceUi, priceUi: (get() as any).getMarketPrice(false).marketPriceUi } });
}
},
updateState: (values: Partial<State>) => set({ ...values }),
setOrderCreatedTimestamp: (orderCreatedTimestamp: number) => set({ orderCreatedTimestamp }),
reset: (storeOverride: StoreOverride) =>
Expand All @@ -90,7 +98,7 @@ export const useTwapStore = create(
set({ dstToken, limitPriceUi: { ...get().limitPriceUi, custom: false } });
},
setSrcAmountUi: (srcAmountUi: string) => {
set({ srcAmountUi, dstAmountLoading: true });
set({ srcAmountUi, dstAmountLoading: true, limitPriceUi: { ...get().limitPriceUi, priceUi: "", custom: false } });
(get() as any).setChunks(get().chunks);
},
setSrcBalance: (srcBalance: BN) => set({ srcBalance }),
Expand Down Expand Up @@ -151,10 +159,15 @@ export const useTwapStore = create(
getIsPartialFillWarning: () => (get() as any).getChunks() * (get() as any).getFillDelayUiMillis() > (get() as any).getDurationMillis(),
setDisclaimerAccepted: (disclaimerAccepted: boolean) => set({ disclaimerAccepted }),
setWrongNetwork: (wrongNetwork?: boolean) => set({ wrongNetwork }),
setLimitPriceUi: (limitPriceUi: { priceUi: string; inverted: boolean }) => set({ limitPriceUi: { ...limitPriceUi, custom: true } }),
setLimitPriceUi: (limitPriceUi: { priceUi: string; inverted: boolean }) =>
set({
limitPriceUi: { ...limitPriceUi, custom: true },
dstAmount: BN((get() as any).getSrcAmount() || "0")
.times(limitPriceUi.priceUi || "0")
.toString(),
}),
setChunks: (chunks: number) => set({ chunks: Math.min(chunks, (get() as any).getMaxPossibleChunks()) }),
setDuration: (customDuration: Duration) => set({ customDuration }),
setDstAmount: (dstAmount: string) => set({ dstAmount }),
getMaxPossibleChunks: () => (get().lib && get().srcToken ? get().lib!.maxPossibleChunks(get().srcToken!, amountBN(get().srcToken, get().srcAmountUi), get().srcUsd) : 1),
getChunks: () => {
const srcUsd = get().srcUsd;
Expand Down
1 change: 1 addition & 0 deletions packages/lib/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ export interface State {
showLoadingModal: boolean;
showSuccessModal: boolean;
dstAmount?: string;
dstAmountFromDex?: string;
dstAmountLoading?: boolean;
}

Expand Down
59 changes: 9 additions & 50 deletions packages/pancake/src/PancakeOrders.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import * as React from "react";
import Button from "@mui/material/Button";
import Menu from "@mui/material/Menu";
import MenuItem from "@mui/material/MenuItem";
import { Box, Fade, styled } from "@mui/material";
import { hooks, OrdersContainer, OrdersPortal, SelectedOrders, store, OrdersHeader } from "@orbs-network/twap-ui";
import { IoMdArrowDropdown } from "@react-icons/all-files/io/IoMdArrowDropdown";
import { StyledOrders, StyledOrdersMenuButton } from "./styles";
import { hooks, OrdersPortal, SelectedOrders, store } from "@orbs-network/twap-ui";
import { StyledOrders, StyledOrdersHeader, StyledOrdersTab, StyledOrdersTabs } from "./styles";
import { Styles } from "@orbs-network/twap-ui";
import { Components } from "@orbs-network/twap-ui";

export default function PancakeOrders() {
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
Expand All @@ -18,9 +13,9 @@ export default function PancakeOrders() {
return (
<OrdersPortal>
<StyledOrders>
<Header>
<StyledOrdersHeader>
<Tabs />
</Header>
</StyledOrdersHeader>
<StyledBody>
{/* <Components.Base.Odnp /> */}
<SelectedOrders />
Expand All @@ -33,14 +28,6 @@ export default function PancakeOrders() {
const StyledBody = styled(Styles.StyledColumnFlex)({
padding: 20,
alignItems: "center",
gap: 20,
});

const Header = styled(Styles.StyledRowFlex)({
background: "#372f47",
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
height: 48,
});

const Tabs = () => {
Expand All @@ -56,42 +43,14 @@ const Tabs = () => {
};

return (
<StyledTabs>
<StyledOrdersTabs>
{Object.keys(tabs).map((key, index) => {
const amount = tabs[key as keyof typeof tabs];
const label = ` ${key} (${amount})`;
console.log(key, selectedTab);

return (
<StyledTab selected={key === selectedTab ? 1 : 0} key={key} onClick={() => onSelect(index)}>
{label}
</StyledTab>
<StyledOrdersTab selected={key === selectedTab ? 1 : 0} key={key} onClick={() => onSelect(index)}>
{key}
</StyledOrdersTab>
);
})}
</StyledTabs>
</StyledOrdersTabs>
);
};

const StyledTab = styled(Box)<{ selected: number }>(({ selected }) => ({
cursor: "pointer",
background: selected ? "#27262c" : "transparent",
height: "100%",
padding: " 0px 24px",
display: "flex",
alignItems: "center",
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
flex: 1,
justifyContent: "center",
}));

const StyledTabs = styled(Box)({
display: "flex",
alignItems: "center",
width: "100%",
justifyContent: "space-between",
height: "100%",
flex: 1,
});

const StyledMenuButtonContainer = styled("div")({});
44 changes: 34 additions & 10 deletions packages/pancake/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import {
StyledChunksSlider,
StyledColumnFlex,
StyledLimitPrice,
StyledLimitPriceInput,
StyledLimitPriceBody,
StyledLimitPriceBottom,
StyledLimitPriceLabel,
StyledMarketPriceContainer,
StyledOutputAddress,
StyledPoweredBy,
Expand All @@ -25,6 +27,7 @@ import {
StyledTotalChunks,
StyledTradeSize,
} from "./styles";
import { FaExchangeAlt } from "@react-icons/all-files/fa/FaExchangeAlt";

import { JSXElementConstructor, memo, ReactNode, useCallback, useEffect, useMemo, useState } from "react";
import {
Expand All @@ -40,7 +43,7 @@ import {
StyledTokenSelect,
StyledUSD,
} from "./styles";
import { chainId, isNativeAddress, zeroAddress } from "@defi.org/web3-candies";
import { chainId, isNativeAddress, TokenERC1155, zeroAddress } from "@defi.org/web3-candies";
import { Configs, TokenData } from "@orbs-network/twap";
import { createContext, useContext } from "react";
import Web3 from "web3";
Expand All @@ -52,7 +55,6 @@ import { AiOutlineArrowDown } from "@react-icons/all-files/ai/AiOutlineArrowDown
import { GrPowerReset } from "@react-icons/all-files/gr/GrPowerReset";
import { BsQuestionCircle } from "@react-icons/all-files/bs/BsQuestionCircle";
import PancakeOrders from "./PancakeOrders";
import { amountUi } from "@orbs-network/twap-ui";

const uiPreferences: TwapContextUIPreferences = {
usdSuffix: " USD",
Expand Down Expand Up @@ -173,7 +175,9 @@ const SrcTokenPercentSelector = () => {
return (
<StyledPercentSelect>
{PERCENT.map((p) => {
const selected = percent === p.value || (p.value === 1 && BN(getMaxSrcInputAmount || 0).isEqualTo(srcAmount));
const selected = BN(srcAmount || "0").isZero()
? false
: Math.round(percent * 100) === p.value * 100 || (p.value === 1 && BN(getMaxSrcInputAmount || 0).isEqualTo(srcAmount));
return (
<StyledButton selected={selected ? 1 : 0} key={p.text} onClick={() => onClick(p.value)}>
{p.text}
Expand Down Expand Up @@ -230,6 +234,15 @@ const TWAP = memo((props: AdapterProps) => {
return props.isDarkTheme ? darkTheme : lightTheme;
}, [props.isDarkTheme]);

const useTrade = (fromToken?: TokenData, toToken?: TokenData, value?: string) => {
const _fromToken = useMemo(() => {
if (!fromToken) return undefined;
const address = isNativeAddress(fromToken?.address || "") ? "BNB" : fromToken?.address;
return fromToken ? { ...fromToken, address } : undefined;
}, [fromToken]);
return props.useTrade!(_fromToken, toToken, value);
};

return (
<Box className="twap-adapter-wrapper">
<TwapAdapter
Expand All @@ -249,7 +262,7 @@ const TWAP = memo((props: AdapterProps) => {
onDstTokenSelected={props.onDstTokenSelected}
usePriceUSD={props.usePriceUSD}
onSrcTokenSelected={props.onSrcTokenSelected}
useTrade={props.useTrade}
useTrade={useTrade}
isDarkTheme={props.isDarkTheme}
>
<ThemeProvider theme={theme}>
Expand Down Expand Up @@ -420,13 +433,14 @@ const TradeInterval = () => {

const LimitPrice = ({ limitOnly }: { limitOnly?: boolean }) => {
const isLimitOrder = store.useTwapStore((store) => store.isLimitOrder);
const { leftToken, rightToken, onChange, limitPrice, toggleInverted } = hooks.useLimitPrice();

return (
<StyledLimitPrice>
<Card>
<Card.Header>
<TwapStyles.StyledRowFlex justifyContent="space-between">
<TwapStyles.StyledRowFlex style={{ width: "auto" }}>
<StyledLimitPriceLabel>
<Components.Labels.LimitPriceLabel />
<Components.ResetLimitButton>
<StyledReset>
Expand All @@ -436,18 +450,28 @@ const LimitPrice = ({ limitOnly }: { limitOnly?: boolean }) => {
</TwapStyles.StyledRowFlex>
</StyledReset>
</Components.ResetLimitButton>
</TwapStyles.StyledRowFlex>
</StyledLimitPriceLabel>
{!limitOnly && <Components.LimitPriceToggle />}
</TwapStyles.StyledRowFlex>
</Card.Header>
{isLimitOrder && (
<Card.Body editable={true}>
<StyledLimitPriceInput placeholder="0" sx={{ pointerEvents: limitOnly ? "all" : isLimitOrder ? "all" : "none" }} />
</Card.Body>
<Styles.StyledColumnFlex>
<StyledLimitPriceBody editable={true}>
<Components.Base.NumericInput decimalScale={6} placeholder={""} onChange={onChange} value={limitPrice} />
</StyledLimitPriceBody>
<StyledLimitPriceBottom onClick={toggleInverted}>
<p>
{rightToken?.symbol} Per {leftToken?.symbol}
</p>
<FaExchangeAlt style={{ width: 16, height: 16 }} />
</StyledLimitPriceBottom>
</Styles.StyledColumnFlex>
)}
</Card>
</StyledLimitPrice>
);
};

console.log(Components.Base);

export { TWAP, Orders };
Loading

0 comments on commit 65c80cb

Please sign in to comment.