Skip to content

Commit 951e4e7

Browse files
committed
feat: setup swapStore to manage store for swap page
1 parent 7b0b720 commit 951e4e7

File tree

9 files changed

+228
-18
lines changed

9 files changed

+228
-18
lines changed

src/app/layout.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export default function RootLayout({
1111
}: {
1212
children: React.ReactNode;
1313
}) {
14+
1415
return (
1516
<html lang="en" suppressHydrationWarning>
1617
<body>

src/app/swap/page.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,22 @@ import {
2121
ModalContent
2222
} from '@chakra-ui/react';
2323
import TokenSelector from '@/components/uis/TokenSelector';
24+
import { useSwapStore } from '@/store/swap/swapStore';
25+
import { shallow } from 'zustand/shallow';
2426

2527
export default function Home() {
26-
const { address, isConnected } = useAccount();
28+
const { address, status, isConnected } = useAccount();
2729

30+
const {
31+
initAssets,
32+
} = useSwapStore(
33+
state => ({
34+
initAssets: state.actions.initAssets,
35+
}),
36+
shallow
37+
);
2838
useEffect(() => {
29-
if (isConnected) {
30-
console.log('Wallet address: ', address);
31-
} else {
32-
console.log('Not connected');
33-
}
39+
initAssets();
3440
}, [address, isConnected]);
3541

3642
const onSwapClick = () => {

src/components/features/ThemeSwitch.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { useEffect, useState } from 'react';
44
import { useTheme } from 'next-themes';
5-
import { HiSun, HiMoon } from 'react-icons/hi';
5+
import { HiSun, HiMoon } from 'react-icons/hi2';
66

77
export default function ThemeSwitch({ className }: { className?: string }) {
88
const { theme, resolvedTheme, setTheme } = useTheme();

src/components/uis/TokenSelector.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import SwampAvatar from '@/components/core/SwampAvatar';
22
// import LocalTokenSupport from '@/components/core/tokenSelector/LocalTokenSupport';
33
import { useGetBalances, useSearchToken } from '@/hooks/swap';
44
import { Token } from '@/interfaces';
5-
// import { useSwapStore } from '@/store/features/swap/swapStore';
5+
import { useSwapStore } from '@/store/swap/swapStore';
66
import { SearchIcon } from '@chakra-ui/icons';
77
import {
88
Button,
@@ -34,10 +34,14 @@ const TokenSelector = ({ children, type }: TokenSelectorProps) => {
3434

3535
const { filteredTokens, search, setSearch } = useSearchToken();
3636

37-
// const handleOnClick = (token: Token): void => {
38-
// // setAsset(token.address, type);
39-
// onClose();
40-
// };
37+
const {
38+
actions: { setAsset },
39+
} = useSwapStore(state => state);
40+
41+
const handleOnClick = (token: Token): void => {
42+
setAsset(token.address, type);
43+
onClose();
44+
};
4145
const onSearchChanged = async (event: any) => {
4246
// setSearch(event.target.value);
4347
};
@@ -97,7 +101,7 @@ const TokenSelector = ({ children, type }: TokenSelectorProps) => {
97101
color: 'yellow.500',
98102
}}
99103
value={token.address}
100-
// onClick={() => handleOnClick(token)}
104+
onClick={() => handleOnClick(token)}
101105
>
102106
<SwampAvatar
103107
size={'sm'}

src/config/contractsTestnet.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import {
22
erc20ABI,
33
pairABI,
44
tokenABI,
5+
factoryABI,
6+
routerABI
57
} from './abis';
68

79
export const GOV_TOKEN_ADDRESS = '0xc3de830ea07524a0761646a6a4e4be0e114a3c83';
@@ -14,6 +16,10 @@ import {
1416
export const ERC20_ABI = erc20ABI;
1517
export const PAIR_ABI = pairABI;
1618
export const TOKEN_ABI = tokenABI;
19+
export const FACTORY_ABI = factoryABI;
20+
export const ROUTER_ABI = routerABI;
21+
22+
export const COIN_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
1723

1824
export const MULTICALL_ADDRESS = '0x091e99cb1C49331a94dD62755D168E941AbD0693';
1925

src/hooks/swap/useGetBalances.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Token } from '@/interfaces';
22
import { useBaseAssetStore } from '@/store/baseAssetsStore';
3-
import { fetchBalance } from '@wagmi/core';
3+
import { getBalance } from 'wagmi/actions';
44
import { useEffect, useState } from 'react';
55
import { useAccount } from 'wagmi';
66

@@ -21,7 +21,7 @@ const useGetBalances = () => {
2121
const getBalances = async () => {
2222
let localList = await Promise.all(
2323
baseAssets.map(async (token: Token) => {
24-
return await fetchBalance({
24+
return await getBalance({
2525
address: address!,
2626
token: token.address,
2727
})

src/layout/index.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
'use client';
22

3-
import React, { PropsWithChildren, useState } from 'react';
3+
import React, { PropsWithChildren, useState, useEffect } from 'react';
44
import Footer from '@/layout/footer';
55
import Navbar from '@/layout/navbar';
66
import Sidebar from '@/layout/sidebar';
7+
import { useBaseAssetStore } from '@/store/baseAssetsStore';
8+
import { shallow } from 'zustand/shallow';
79

810
export default function Layout({ children }: PropsWithChildren) {
11+
912
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
13+
const { initBaseAssets, isLoading } = useBaseAssetStore(
14+
state => ({
15+
initBaseAssets: state.actions.initBaseAssets,
16+
isLoading: state.isLoading,
17+
}),
18+
shallow
19+
);
20+
useEffect(() => {
21+
initBaseAssets();
22+
}, []);
1023

1124
return (
1225
<div className="min-h-screen flex flex-col">

src/store/baseAssetsStore.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,20 @@ interface BaseAssetState {
1414
setBaseAsset: (token: Token) => void;
1515
};
1616
}
17-
const BASE_URL = process.env.NEXT_PUBLIC_API ?? 'https://localhost:8000';
17+
const BASE_URL = process.env.NEXT_PUBLIC_UNISWAP_SUBGRAPH_URL ?? 'https://localhost:8000';
1818

1919
export const useBaseAssetStore = create<BaseAssetState>()(
2020
devtools((set, get) => ({
2121
baseAssets: [],
2222
isLoading: false,
2323
actions: {
2424
initBaseAssets: async () => {
25+
console.log(process.env.NEXT_PUBLIC_UNISWAP_SUBGRAPH_URL);
2526
set({ isLoading: true });
2627
await axios
27-
.get(BASE_URL.concat('/assets'))
28+
.get(BASE_URL)
2829
.then(response => {
30+
console.log(response);
2931
let baseAssets = response.data.data;
3032
baseAssets = mapToken(baseAssets);
3133

src/store/swap/swapStore.ts

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
import { CONTRACTS } from '@/config';
2+
import { Token } from '@/interfaces';
3+
import { useBaseAssetStore } from '@/store/baseAssetsStore';
4+
import { getBalance, getAccount } from 'wagmi/actions';
5+
import { mainnet } from 'wagmi/chains'; // Or another chain if needed
6+
import { create } from 'zustand';
7+
import { readPairFactory } from '@/lib/swamp';
8+
import { wagmiConfig } from '@/lib/constants/wagmiConfig'
9+
10+
interface SwapState {
11+
inputAsset?: Token;
12+
outputAsset?: Token;
13+
displayRoute: boolean;
14+
amountRaw: string;
15+
slippage: string;
16+
txDeadline: string;
17+
isFetching: boolean;
18+
priceImpact: string;
19+
actions: {
20+
initAssets: () => void;
21+
updateAssets: () => void;
22+
setAsset: (address: string, type: string) => void;
23+
setAmountRaw: (amount: string) => void;
24+
setSlippage: (slippage: string) => void;
25+
setTxDeadline: (txDeadline: string) => void;
26+
getSwapQuote: () => void;
27+
// cleanRoute: () => void;
28+
changeDisplayRoute: (value: boolean) => void;
29+
getFeePercentage: () => Promise<{ stableFee: number; volatileFee: number }>;
30+
setPriceImpact: (value: string) => void;
31+
};
32+
}
33+
34+
export const useSwapStore = create<SwapState>((set, get) => ({
35+
inputAsset: undefined,
36+
outputAsset: undefined,
37+
displayRoute: true,
38+
swapQuote: {},
39+
amountRaw: '0',
40+
slippage: '2',
41+
txDeadline: '300',
42+
isFetching: false,
43+
priceImpact: '0',
44+
actions: {
45+
initAssets: async () => {
46+
console.log("initAssets");
47+
const { getBaseAsset } = useBaseAssetStore.getState().actions;
48+
const inputAsset = getBaseAsset(CONTRACTS.COIN_ADDRESS);
49+
const outputAsset = getBaseAsset(CONTRACTS.GOV_TOKEN_ADDRESS);
50+
const { address } = getAccount(wagmiConfig);
51+
if (address) {
52+
if (inputAsset) {
53+
inputAsset.balance = (
54+
await getBalance(wagmiConfig, { address: address })
55+
).formatted;
56+
}
57+
if (outputAsset) {
58+
outputAsset.balance = (
59+
await getBalance(wagmiConfig, { address: address, token: outputAsset.address })
60+
).formatted;
61+
}
62+
}
63+
64+
set({
65+
inputAsset,
66+
outputAsset,
67+
});
68+
},
69+
updateAssets: async () => {
70+
const { address } = getAccount(wagmiConfig);
71+
const { inputAsset, outputAsset } = get();
72+
const { setBaseAsset } = useBaseAssetStore.getState().actions;
73+
if (address) {
74+
if (inputAsset) {
75+
if (
76+
inputAsset.address.toLowerCase() ===
77+
CONTRACTS.COIN_ADDRESS.toLowerCase()
78+
) {
79+
inputAsset.balance = (
80+
await getBalance(wagmiConfig, { address: address })
81+
).formatted;
82+
inputAsset.balanceWei = (
83+
await getBalance(wagmiConfig, { address: address })
84+
).value.toString();
85+
} else {
86+
inputAsset.balance = (
87+
await getBalance(wagmiConfig, {
88+
address: address,
89+
token: inputAsset.address,
90+
})
91+
).formatted;
92+
inputAsset.balanceWei = (
93+
await getBalance(wagmiConfig, {
94+
address: address,
95+
token: inputAsset.address,
96+
})
97+
).value.toString();
98+
}
99+
setBaseAsset(inputAsset);
100+
}
101+
if (outputAsset) {
102+
if (
103+
outputAsset.address.toLowerCase() ===
104+
CONTRACTS.COIN_ADDRESS.toLowerCase()
105+
) {
106+
outputAsset.balance = (
107+
await getBalance(wagmiConfig, { address: address })
108+
).formatted;
109+
outputAsset.balanceWei = (
110+
await getBalance(wagmiConfig, { address: address })
111+
).value.toString();
112+
} else {
113+
outputAsset.balance = (
114+
await getBalance(wagmiConfig, {
115+
address: address,
116+
token: outputAsset.address,
117+
})
118+
).formatted;
119+
outputAsset.balanceWei = (
120+
await getBalance(wagmiConfig, {
121+
address: address,
122+
token: outputAsset.address,
123+
})
124+
).value.toString();
125+
}
126+
setBaseAsset(outputAsset);
127+
}
128+
}
129+
130+
set({
131+
inputAsset,
132+
outputAsset,
133+
});
134+
},
135+
setAsset: (address, type) => {
136+
const { getBaseAsset } = useBaseAssetStore.getState().actions;
137+
const temp = getBaseAsset(address);
138+
if (type === 'input') {
139+
set({
140+
inputAsset: temp,
141+
});
142+
} else if (type === 'output') {
143+
set({
144+
outputAsset: temp,
145+
});
146+
} else {
147+
console.log("Wrong type parameter: use 'input' or 'output'");
148+
}
149+
},
150+
setAmountRaw: (amount: string) => {
151+
set({ amountRaw: amount });
152+
},
153+
setSlippage: (slippage: string) => set({ slippage }),
154+
setTxDeadline: (txDeadline: string) => set({ txDeadline }),
155+
getSwapQuote: async () => {
156+
set({ isFetching: true });
157+
// const swapQuote = await _getRoute();
158+
// set({ swapQuote: swapQuote });
159+
set({ isFetching: false });
160+
},
161+
// cleanRoute: () => set({ swapQuote: {} }),
162+
changeDisplayRoute: (value: boolean) => set({ displayRoute: value }),
163+
getFeePercentage: async () => {
164+
const stableFee = await readPairFactory(wagmiConfig, {
165+
functionName: 'stableFee',
166+
});
167+
const volatileFee = await readPairFactory(wagmiConfig, {
168+
functionName: 'volatileFee',
169+
});
170+
171+
return {
172+
stableFee: Number(stableFee) / 100,
173+
volatileFee: Number(volatileFee) / 100,
174+
};
175+
},
176+
setPriceImpact: (value: string) => set({ priceImpact: value }),
177+
},
178+
}));

0 commit comments

Comments
 (0)