Skip to content

Commit

Permalink
Add layerswap bridge
Browse files Browse the repository at this point in the history
  • Loading branch information
junjieit committed Aug 23, 2024
1 parent 9542bcf commit 496ad60
Show file tree
Hide file tree
Showing 22 changed files with 1,157 additions and 129 deletions.
3 changes: 2 additions & 1 deletion packages/dodoex-widgets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"ton": "^13.9.0",
"ton-core": "^0.53.0",
"ton-crypto": "^3.2.0",
"tonweb": "^0.0.66",
"zustand": "^4.5.4"
},
"peerDependencies": {
Expand Down Expand Up @@ -137,4 +138,4 @@
"ts-jest": "^29.0.1",
"typescript": "^4.7.3"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,20 @@ export default function BridgeSummaryDialog({
fullWidth
isLoading={contractStatus == ContractStatus.Pending}
disabled={!route}
onClick={() => {
handleExecuteRoute();
onClick={async () => {
dispatch(
setGlobalProps({
contractStatus: ContractStatus.Pending,
}),
);
if (route?.sendData) {
route?.sendData();
} else {
await handleExecuteRoute();
setGlobalProps({
contractStatus: ContractStatus.TxSuccess,
});
}
}}
>
{contractStatus == ContractStatus.Pending ? (
Expand Down
1 change: 1 addition & 0 deletions packages/dodoex-widgets/src/components/Swap/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ export function Swap({
account,
chainId: fromToken?.chainId ?? chainId,
contractAddress: selectedRoute?.spenderContractAddress,
skip: !selectedRoute?.spenderContractAddress,
});
const pendingReset = useMemo(
() => getPendingRest(isReverseRouting ? toToken : fromToken),
Expand Down
65 changes: 31 additions & 34 deletions packages/dodoex-widgets/src/components/TokenPicker/TokenItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { TokenInfo } from './../../hooks/Token';
import { Loading } from '@dodoex/icons';
import { tokenPickerItem } from '../../constants/testId';
import { useTheme } from '@dodoex/components';
import { useWalletState } from '../../hooks/ConnectWallet/useWalletState';
import { ChainId } from '../../constants/chains';
import { useWeb3React } from '@web3-react/core';

export default function TokenItem({
token,
Expand All @@ -24,7 +24,7 @@ export default function TokenItem({
}) {
const theme = useTheme();
const getBalance = useGetBalance();
const { account, isTon } = useWalletState();
const { account } = useWeb3React();
const balanceBigNumber = getBalance(token);
const balance = balanceBigNumber
? formatReadableNumber({
Expand Down Expand Up @@ -71,40 +71,37 @@ export default function TokenItem({
>
{token.symbol}
</Box>
{account &&
(isTon
? token.chainId === ChainId.TON
: token.chainId !== ChainId.TON) && (
<Box
sx={{
mt: 4,
textAlign: 'left',
}}
>
{balanceBigNumber?.gte(0) ? (
balance
) : (
<Box
component={Loading}
width={18}
sx={{
'& path': {
fill: theme.palette.text.disabled,
{account && (
<Box
sx={{
mt: 4,
textAlign: 'left',
}}
>
{balanceBigNumber?.gte(0) ? (
balance
) : (
<Box
component={Loading}
width={18}
sx={{
'& path': {
fill: theme.palette.text.disabled,
},
animation: 'loadingRotate 1.1s infinite linear',
'@keyframes loadingRotate': {
'0%': {
transform: 'rotate(0deg)',
},
animation: 'loadingRotate 1.1s infinite linear',
'@keyframes loadingRotate': {
'0%': {
transform: 'rotate(0deg)',
},
'100%': {
transform: 'rotate(359deg)',
},
'100%': {
transform: 'rotate(359deg)',
},
}}
/>
)}
</Box>
)}
},
}}
/>
)}
</Box>
)}
</Box>
</Box>
<Box
Expand Down
20 changes: 19 additions & 1 deletion packages/dodoex-widgets/src/constants/tokenList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,16 @@ export default [
'https://images.dodoex.io/XbtxsPIscM6p5ClHbLO0JumFHA9U23eON8-MDh-Plkg/rs:fit:96:96:0/g:no/aHR0cHM6Ly9pbWFnZS1wcm94eS5kb2RvZXguaW8vaG1nM3hRa1BUTUtkcUNFVnd0LXU4S2lwTW5od1JCdGhLYWxENW9vSWlTZy9hSFIwY0hNNkx5OXpkRzl5WVdkbExtZHZiMmRzWldGd2FYTXVZMjl0TDJSdlpHOHRiV1ZrYVdFdGMzUmhaMmx1Wnk5MWNHeHZZV1JmYVcxblh6UXlNRFEyTkRaZk1qQXlNakEwTWpJd01UQTFNekF4TmpVdWNHNW4ucG5n.webp',
canBridgeToTon: true,
},
{
chainId: 10,
address: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58',
name: 'USDT',
decimals: 6,
symbol: 'USDT',
logoURI:
'https://images.dodoex.io/iD2HcQfBC7tC1Eb0ERs67UIyUo0G-S77OaYuzCArFC0/rs:fit:32:32:0/g:no/aHR0cHM6Ly90b2tlbi1pbWcuZG9kb2V4LmlvLzEwLzB4OTRiMDA4YWEwMDU3OWMxMzA3YjBlZjJjNDk5YWQ5OGE4Y2U1OGU1OA.webp',
canBridgeToTon: true,
},
{
chainId: 10,
address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
Expand Down Expand Up @@ -785,6 +795,14 @@ export default [
logoURI: 'https://tether.to/images/logoCircle.png',
name: 'Tether USD',
address: 'EQBynBO23ywHy_CgarY9NK9FTz0yDsG82PtcbSTQgGoXwiuA',
symbol: 'jUSDT',
chainId: -239,
},
{
decimals: 6,
logoURI: 'https://tether.to/images/logoCircle.png',
name: 'Tether USD',
address: 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs',
symbol: 'USDT',
chainId: -239,
},
Expand All @@ -794,7 +812,7 @@ export default [
'https://images.dodoex.io/XbtxsPIscM6p5ClHbLO0JumFHA9U23eON8-MDh-Plkg/rs:fit:96:96:0/g:no/aHR0cHM6Ly9pbWFnZS1wcm94eS5kb2RvZXguaW8vaG1nM3hRa1BUTUtkcUNFVnd0LXU4S2lwTW5od1JCdGhLYWxENW9vSWlTZy9hSFIwY0hNNkx5OXpkRzl5WVdkbExtZHZiMmRzWldGd2FYTXVZMjl0TDJSdlpHOHRiV1ZrYVdFdGMzUmhaMmx1Wnk5MWNHeHZZV1JmYVcxblh6UXlNRFEyTkRaZk1qQXlNakEwTWpJd01UQTFNekF4TmpVdWNHNW4ucG5n.webp',
name: 'USD Coin',
address: 'EQB-MPwrd1G6WKNkLz_VnV6WqBDd142KMQv-g1O-8QUA3728',
symbol: 'USDC',
symbol: 'jUSDC',
chainId: -239,
},
// {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { useWeb3React } from '@web3-react/core';
import useTonConnectStore from '../ConnectWallet/TonConnect';
import { useOrbiterContractMap } from '../contract/orbiter/useOrbiterContractMap';
import { encodeOrbiterBridge } from '../contract/orbiter/encodeOrbiterBridge';
import { useLayerswapRouters } from '../contract/layerswap/useLayerswapRouters';

export interface BridgeRouteI {
/** update */
Expand Down Expand Up @@ -60,6 +61,8 @@ export interface BridgeRouteI {
chainId: number;
encodeId?: string;
};
sendData?: () => Promise<any>;

productParams: any;
sourceRoute?: {
toAmount: string;
Expand Down Expand Up @@ -181,8 +184,13 @@ export function useFetchRoutePriceBridge({

const needOrbiterQuery = useMemo(
() =>
(fromToken?.chainId === ChainId.TON ||
toToken?.chainId === ChainId.TON) &&
toToken?.chainId === ChainId.TON &&
fromToken?.chainId !== toToken?.chainId,
[fromToken, toToken],
);
const needLayerSwap = useMemo(
() =>
fromToken?.chainId === ChainId.TON &&
fromToken?.chainId !== toToken?.chainId,
[fromToken, toToken],
);
Expand All @@ -194,10 +202,22 @@ export function useFetchRoutePriceBridge({
skip: !needOrbiterQuery,
});

const layerSwapRouter = useLayerswapRouters({
skip: !needLayerSwap,
data: {
toToken,
fromToken,
fromAmount,
evmAccount: web3React.account,
tonAccount: tonConnect.connected?.account,
slippage: Number(slippage),
},
});

const refetch = useCallback(async () => {
const fromChainId = fromToken?.chainId;
const toChainId = toToken?.chainId;
if (needOrbiterQuery) return;
if (needOrbiterQuery || needLayerSwap) return;
if (
!fromChainId ||
!toChainId ||
Expand Down Expand Up @@ -518,13 +538,15 @@ export function useFetchRoutePriceBridge({

const bridgeRouteListRes = useMemo(() => {
if (!fromAmount) return [];
if (layerSwapRouter.router) return [layerSwapRouter.router];
return orbiterRouter ? [orbiterRouter] : bridgeRouteList;
}, [status, fromAmount, bridgeRouteList, orbiterRouter]);
}, [status, fromAmount, bridgeRouteList, orbiterRouter, layerSwapRouter]);

const statusRes = useMemo(
() => (needOrbiterQuery ? orbiterStatus : status),
[status, orbiterStatus, needOrbiterQuery],
);
const statusRes = useMemo(() => {
if (needLayerSwap) return layerSwapRouter.status;
if (needOrbiterQuery) return orbiterStatus;
return status;
}, [status, orbiterStatus, needOrbiterQuery, needLayerSwap, layerSwapRouter]);

return {
status: statusRes,
Expand Down
7 changes: 6 additions & 1 deletion packages/dodoex-widgets/src/hooks/Bridge/useSendRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export function useSendRoute() {
product,
encodeParams,
};
let { encodeResultData } = selectedRoute;
let { encodeResultData, sendData } = selectedRoute;
if (encodeParams) {
const result = await axios.post(
`${bridgeEncodeAPI}${apikey ? `?apikey=${apikey}` : ''}`,
Expand All @@ -63,6 +63,11 @@ export function useSendRoute() {
encodeResultData = result.data.data;
}
if (!encodeResultData) {
if (sendData) {
setSendRouteLoading(false);
goNext();
return;
}
throw new Error('encodeResultData is null');
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {
Address,
beginCell,
Cell,
storeMessage,
TonClient,
Transaction,
} from 'ton';

export const waitForTransaction = async (
options: {
boc: string;
refetchInterval?: number;
refetchLimit?: number;
address: string;
},
client: TonClient,
): Promise<Transaction | null> => {
const { boc, refetchInterval = 1000, refetchLimit, address } = options;

return new Promise((resolve) => {
let refetches = 0;
const walletAddress = Address.parse(address);
const cell = Cell.fromBase64(boc);
const hash = cell.hash().toString('base64');
const interval = setInterval(async () => {
refetches += 1;
const state = await client.getContractState(walletAddress);
if (!state || !state.lastTransaction) {
clearInterval(interval);
resolve(null);
return;
}
// const lastLt = state.lastTransaction.lt;
// const lastHash = state.lastTransaction.hash;
const lastLt = '48655860000001';
const lastHash = 'ineTDPZfNoL0lFLjTRmmqBQv0WVPufAPxpJIMKcY6rA=';
const lastTx = await client.getTransaction(
walletAddress,
lastLt,
lastHash,
);

if (lastTx && lastTx.inMessage) {
const msgCell = beginCell()
.store(storeMessage(lastTx.inMessage))
.endCell();

const inMsgHash = msgCell.hash().toString('base64');
console.log('InMsgHash', inMsgHash);
if (inMsgHash === hash) {
clearInterval(interval);
resolve(lastTx);
}
}
if (refetchLimit && refetches >= refetchLimit) {
clearInterval(interval);
resolve(null);
}
}, refetchInterval);
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,21 @@ const useTonConnectStore = create<TonConnectState>((set, get) => ({
if (!client) {
throw new Error('client not initialized');
}
const data = await client.runMethod(
Address.parseFriendly(jettonWalletAddress).address,
'get_wallet_data',
);
const balance = new BigNumber(data.stack.readBigNumber().toString()).div(
10 ** decimals,
);
let balance = new BigNumber(0);
try {
const data = await client.runMethod(
Address.parseFriendly(jettonWalletAddress).address,
'get_wallet_data',
);
balance = new BigNumber(data.stack.readBigNumber().toString()).div(
10 ** decimals,
);
} catch (error) {
const addressBalance = await get().getBalance(jettonWalletAddress);
if (!addressBalance.isEqualTo(0)) {
throw error;
}
}
return balance;
},
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export function useWalletState({
isTon: true,
chainId: tonConnect.connected?.chainId,
account: tonConnect.connected?.account,
tonAccount: tonConnect.connected?.account,
evmAccount: web3React.account,
isMetamask: false,
autoConnect,
connect: tonConnect.connect,
Expand All @@ -55,6 +57,8 @@ export function useWalletState({
isTon: false,
chainId: web3React.chainId,
account: web3React.account,
tonAccount: tonConnect.connected?.account,
evmAccount: web3React.account,
isMetamask: web3React.provider?.provider?.isMetaMask,
autoConnect,
connect: () => {
Expand Down
4 changes: 3 additions & 1 deletion packages/dodoex-widgets/src/hooks/Swap/useFetchFiatPrice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ export function useFetchFiatPrice({
// TODO: set timeout value!!
fiatPriceAPI,
{
networks: tokens.map(() => getPlatformId(chainId)),
networks: tokens.map((token) =>
getPlatformId(token.chainId ?? chainId),
),
addresses: tokens.map((token) => token.address),
symbols: tokens.map((token) => token.symbol),
isCache: true,
Expand Down
Loading

0 comments on commit 496ad60

Please sign in to comment.