Skip to content

Commit

Permalink
fix bug & opt dex (#3303)
Browse files Browse the repository at this point in the history
* fix bugs

* fix bug

* hide swap v2
  • Loading branch information
wow-sven authored Feb 12, 2025
1 parent b4f6f82 commit 413d8e5
Show file tree
Hide file tree
Showing 17 changed files with 637 additions and 591 deletions.
14 changes: 7 additions & 7 deletions infra/rooch-portal-v2/src/layouts/config-nav-dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,18 @@ export const navData = [
noAddressRequired: true,
},
// temporary disable swap, when the swap v2 is all good, will remove this path
// {
// title: 'Swap',
// path: paths.dashboard.swap,
// icon: <Iconify icon="solar:money-bag-broken" />,
// noAddressRequired: true,
// },
{
title: 'Swap',
path: paths.dashboard['swap-v2'],
path: paths.dashboard.swap,
icon: <Iconify icon="solar:money-bag-broken" />,
noAddressRequired: true,
},
// {
// title: 'Swap',
// path: paths.dashboard['swap-v2'],
// icon: <Iconify icon="solar:money-bag-broken" />,
// noAddressRequired: true,
// },
],
},
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ import { toDust, fromDust, formatByIntl } from 'src/utils/number';

import { toast } from 'src/components/snackbar';

import type { TradeCoinType } from './types';
import { useTokenPair } from '../hooks/use-token-pair';

type TokenType = {
id: string;
type: string;
name: string;
};
Expand All @@ -35,27 +34,29 @@ type TokenPairType = {

interface SelectTokenPairProps {
onLoading: (status: boolean) => void;
onCallback: (x?: TradeCoinType, y?: TradeCoinType) => void;
onCallback: (
x?: { amount: string } & BalanceInfoView,
y?: { amount: string } & BalanceInfoView
) => void;
}

export default function SelectTokenPair({ onLoading, onCallback }: SelectTokenPairProps) {
const client = useRoochClient();
const dex = useNetworkVariable('dex');
const currentAddress = useCurrentAddress();
const { tokenPairs } = useTokenPair();

const [loading, setLoading] = useState(false);
const [x, setX] = useState<TokenType>();
const [x, setX] = useState<BalanceInfoView>();
const [xValue, setXValue] = useState('');
const [xCount, setXCount] = useState('');
const [xRatio, setXRation] = useState(0);
const [y, setY] = useState<TokenType>();
const [y, setY] = useState<BalanceInfoView>();
const [x2y, setX2y] = useState(true);
const [yValue, setYValue] = useState('');
const [yCount, setYCount] = useState('');
// map<x_coin_id, ...>
const [tokenPair, setTokenPair] = useState<Map<string, TokenPairType[]>>();

const { data } = useRoochClientQuery(
const { data: balances } = useRoochClientQuery(
'getBalances',
{
owner: currentAddress?.toStr() || '',
Expand All @@ -68,69 +69,13 @@ export default function SelectTokenPair({ onLoading, onCallback }: SelectTokenPa
// map<coin_type, ...>
const assetsMap = useMemo(() => {
const assetsMap = new Map<string, BalanceInfoView>();
data?.data.forEach((i) => {
balances?.data.forEach((i) => {
assetsMap.set(i.coin_type, {
...i,
});
});
return assetsMap;
}, [data]);

useEffect(() => {
client
.queryObjectStates({
filter: {
object_type: `${dex.address}::swap::TokenPair`,
},
})
.then((result) => {
const pair: TokenPairType[] = result.data.map((item) => {
const xView = item.decoded_value!.value.balance_x as AnnotatedMoveStructView;
let xType = xView.type.replace('0x2::object::Object<0x3::coin_store::CoinStore<', '');
xType = xType.replace('>>', '');
const xName = xType.split('::');
const yView = item.decoded_value!.value.balance_y as AnnotatedMoveStructView;
let yType = yView.type.replace('0x2::object::Object<0x3::coin_store::CoinStore<', '');
yType = yType.replace('>>', '');
const yName = yType.split('::');
return {
x2y: true,
x: {
id: xView.value.id as string,
type: xType,
name: xName[xName.length - 1].replace('>>', ''),
},
y: {
id: yView.value.id as string,
type: yType,
name: yName[yName.length - 1].replace('>>', ''),
},
};
});

const pairMap = new Map<string, TokenPairType[]>();
pair.forEach((p) => {
const key = p.x.name;
if (!pairMap.has(key)) {
pairMap.set(key, []);
}
pairMap.get(key)!.push(p);

const key1 = p.y.name;
if (!pairMap.has(key1)) {
pairMap.set(key1, []);
}
pairMap.get(key1)!.push({
x2y: false,
x: p.y,
y: p.x,
});
});

// Update the state
setTokenPair(pairMap);
});
}, [client, dex]);
}, [balances]);

const fetchY = useCallback(async () => {
if (xCount === '' || xCount === '0' || !x || !y) {
Expand All @@ -139,39 +84,34 @@ export default function SelectTokenPair({ onLoading, onCallback }: SelectTokenPa

try {
setLoading(true);
const fixdXCount = toDust(xCount.replaceAll(',', ''), assetsMap?.get(x.type)?.decimals || 0);
const fixdXCount = toDust(
xCount.replaceAll(',', ''),
assetsMap?.get(x.coin_type)?.decimals || 0
);
const result = await client.executeViewFunction({
target: `${dex.address}::router::get_amount_out`,
args: [Args.u64(fixdXCount)],
typeArgs: [x.type, y.type],
typeArgs: [x.coin_type, y.coin_type],
});

if (result.vm_status !== 'Executed') {
toast.error('unknow error');
}

const yCount = result.return_values![0].decoded_value as string;
const fixdYCount = fromDust(yCount, assetsMap?.get(y.type)?.decimals || 0);
const fixdYCount = fromDust(yCount, assetsMap?.get(y.coin_type)?.decimals || 0);
setYCount(formatByIntl(fixdYCount.toString()));

const xCoin = assetsMap?.get(x.type)!;
const yCoin = assetsMap?.get(y.type);
const xCoin = assetsMap?.get(x.coin_type)!;
const yCoin = assetsMap?.get(y.coin_type);
onCallback(
{
balance: xCoin.fixedBalance,
type: xCoin.coin_type,
icon: xCoin.icon_url || undefined,
symbol: xCoin.symbol,
...x,
amount: xCount.replaceAll(',', ''),
decimal: xCoin.decimals,
},
{
balance: yCoin?.fixedBalance || 0,
type: yCoin?.coin_type || y.type,
icon: yCoin?.icon_url || undefined,
symbol: yCoin?.symbol || y.name,
...y,
amount: fixdYCount.toString(),
decimal: yCoin?.decimals || 0, // TODO: fix
}
);
} catch (e) {
Expand Down Expand Up @@ -203,7 +143,7 @@ export default function SelectTokenPair({ onLoading, onCallback }: SelectTokenPa
setY(oldX);
setYValue(oldXValue);

const xbalance = assetsMap?.get(oldY.type)!.fixedBalance || 0;
const xbalance = assetsMap?.get(oldY.coin_type)!.fixedBalance || 0;
if (xRatio !== 0) {
setXCount(formatByIntl(xbalance * xRatio));
} else if (Number(xCount) > xbalance) {
Expand All @@ -227,22 +167,24 @@ export default function SelectTokenPair({ onLoading, onCallback }: SelectTokenPa
label="X"
onChange={(e: SelectChangeEvent) => {
const s = e.target.value;
const {x} = tokenPair!.get(s)![0];
const x = tokenPairs!.get(s)?.x;
setX(x);
setXValue(e.target.value);
setY(undefined);
setYValue('');
setYCount('');
if (xRatio !== 0) {
setXCount(((assetsMap?.get(x!.type)!.fixedBalance || 0) * xRatio).toString());
setXCount(formatByIntl((assetsMap?.get(x!.coin_type)?.fixedBalance || 0) * xRatio));
}
}}
>
{tokenPair &&
[...tokenPair.entries()].map(([key, pairs]) => (
{tokenPairs &&
[...tokenPairs.entries()].map(([key, pairs]) => (
<MenuItem key={key} id={key} value={`${key}`}>
<span>{key} :</span>
<span>{formatByIntl(assetsMap?.get(pairs[0].x.type)?.fixedBalance || 0)}</span>
<span>
{formatByIntl(assetsMap?.get(pairs.x.coin_type)?.fixedBalance || 0, '0')}
</span>
</MenuItem>
))}
</Select>
Expand All @@ -260,7 +202,7 @@ export default function SelectTokenPair({ onLoading, onCallback }: SelectTokenPa
if (/^\d*\.?\d*$/.test(value) === false) {
return;
}
const xBalance = assetsMap?.get(x!.type)!.fixedBalance || 0;
const xBalance = assetsMap?.get(x!.coin_type)!.fixedBalance || 0;
if (xRatio !== 0) {
if (value !== (xBalance * xRatio).toString()) {
setXRation(0);
Expand All @@ -281,25 +223,29 @@ export default function SelectTokenPair({ onLoading, onCallback }: SelectTokenPa
<Button
startIcon={<ArrowDownwardIcon />}
variant="text"
disabled={!x || !y}
disabled={!x || !y || assetsMap.get(y.coin_type)?.fixedBalance === 0}
onClick={exchange}
sx={{ display: { xs: 'none', sm: 'flex', justifyContent: 'center' } }}
>
Exchange
</Button>
</Box>
<Box display="flex" alignItems="center">
{[0.25, 0.5, 0.75, x?.name === 'RGas' ? 0.99 : 1].map((item, index) => (
{[0.25, 0.5, 0.75, x?.symbol === 'RGAS' ? 0.99 : 1].map((item, index) => (
<Button
key={item.toString()}
variant={xRatio === item ? 'contained' : 'outlined'}
variant={
xRatio === item || (xRatio === 0.99 && item === 1) ? 'contained' : 'outlined'
}
size="small"
sx={{ mx: 0.5 }}
disabled={!x}
onClick={() => {
setXRation(item);
const ration = item === 1 ? 0.99 : item; // TODO: Calculating gas
setXCount(formatByIntl((assetsMap?.get(x!.type)!.fixedBalance || 0) * ration));
setXCount(
formatByIntl((assetsMap?.get(x!.coin_type)?.fixedBalance || 0) * ration, '0')
);
}}
>
{item * 100}%
Expand All @@ -318,15 +264,15 @@ export default function SelectTokenPair({ onLoading, onCallback }: SelectTokenPa
label="Y"
onChange={(e: SelectChangeEvent) => {
const s = e.target.value;
const pair = tokenPair!.get(x!.name)!.find((item) => item.y.name === s)!;
setY(pair.y);
const pair = tokenPairs!.get(x!.symbol)!.y.find((item) => item.symbol === s)!;
setY(pair);
setYValue(e.target.value);
}}
>
{tokenPair?.get(x?.name || '')?.map((item) => (
<MenuItem key={item.y.name} id={item.y.name} value={`${item.y.name}`}>
<span>{item.y.name} :</span>
<span>{formatByIntl(assetsMap?.get(item.y.type)?.fixedBalance || 0)}</span>
{tokenPairs?.get(x?.symbol || '')?.y?.map((item) => (
<MenuItem key={item.symbol} id={item.symbol} value={`${item.symbol}`}>
<span>{item.symbol} :</span>
<span>{formatByIntl(assetsMap?.get(item.coin_type)?.fixedBalance || 0, '0')}</span>
</MenuItem>
))}
</Select>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { SelectChangeEvent} from '@mui/material';
import type { SelectChangeEvent } from '@mui/material';

import { useState } from 'react';
import { useDebounce } from 'react-use';

import { Box, Button, Select , MenuItem , TextField , InputLabel, FormControl } from '@mui/material';
import { Box, Button, Select, MenuItem, TextField, InputLabel, FormControl } from '@mui/material';

import type { TradeCoinType } from './types';

Expand Down Expand Up @@ -42,7 +42,7 @@ export default function TokenPair({ coins, onChange }: TokenPairProps) {
}}
>
{coins.map((item) => (
<MenuItem id={item.symbol} value={`${item.type}&${item.balance}`}>
<MenuItem id={item.symbol} value={`${item.symbol}&${item.balance}`}>
<span>{item.symbol} :</span>
<span> {item.balance}</span>
</MenuItem>
Expand Down
9 changes: 3 additions & 6 deletions infra/rooch-portal-v2/src/sections/trade/components/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { BalanceInfoView } from '@roochnetwork/rooch-sdk';

export type TradeCoinType = {
symbol: string;
type: string;
balance: number;
amount: string;
icon?: string;
decimal: number;
};
} & BalanceInfoView;
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ export function useAllLiquidity(limit: number = 10): UseAllLiquidityReturn {
const dex = useNetworkVariable('dex');
const client = useRoochClient();

console.log(limit);
const [paginationModel, setPaginationModel] = useState({ index: 1, limit });
const mapPageToNextCursor = useRef<{ [page: number]: IndexerStateIDView | null }>({});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ export function useOwnerLiquidity(): UseOwnerLiquidityReturn {
return tokens;
}, [assetsList, dex.address]);

console.log(lpTokens);

return {
lpTokens,
isPending,
Expand Down
Loading

0 comments on commit 413d8e5

Please sign in to comment.