Skip to content

Commit 5749082

Browse files
Feat/sgho (#2982)
Co-authored-by: Mark Grothe <grothem@gmail.com>
1 parent e790397 commit 5749082

39 files changed

Lines changed: 2516 additions & 1426 deletions

‎.gitignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ package-lock.json
4444
.eslintcache
4545
.yarn-cache
4646

47+
# TypeScript incremental build cache
48+
tsconfig.tsbuildinfo
49+
4750
# IDE specific
4851
.idea
4952
.vscode

‎package.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@
3737
"dependencies": {
3838
"@aave-dao/aave-address-book": "^4.49.3",
3939
"@aave/contract-helpers": "1.38.0",
40-
"@aave/graphql": "^0.11.0",
40+
"@aave/graphql": "0.12.0",
4141
"@aave/math-utils": "1.38.0",
42-
"@aave/react": "^0.8.2",
42+
"@aave/react": "0.9.0",
4343
"@amplitude/analytics-browser": "^2.13.0",
4444
"@cowprotocol/cow-sdk": "7.3.4",
4545
"@cowprotocol/sdk-ethers-v5-adapter": "0.3.5",

‎pages/sgho.page.tsx‎

Lines changed: 32 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,17 @@
1-
import { StakeUIUserData } from '@aave/contract-helpers/dist/esm/V3-uiStakeDataProvider-contract/types';
2-
import { AaveV3Ethereum } from '@aave-dao/aave-address-book';
3-
import { Trans } from '@lingui/macro';
4-
import { Box, Paper, Typography, useMediaQuery, useTheme } from '@mui/material';
1+
import { Box } from '@mui/material';
52
import dynamic from 'next/dynamic';
63
import { useEffect } from 'react';
74
import { ContentContainer } from 'src/components/ContentContainer';
8-
import { ConnectWalletButton } from 'src/components/WalletConnection/ConnectWalletButton';
9-
import { useWalletBalances } from 'src/hooks/app-data-provider/useWalletBalances';
10-
import { StakeTokenFormatted, useGeneralStakeUiData } from 'src/hooks/stake/useGeneralStakeUiData';
11-
import { useUserStakeUiData } from 'src/hooks/stake/useUserStakeUiData';
12-
import { useModalContext } from 'src/hooks/useModal';
5+
import { useSavingsMarketData } from 'src/hooks/useSavingsMarketData';
136
import { MainLayout } from 'src/layouts/MainLayout';
14-
import { WalletBalance } from 'src/modules/reserve-overview/ReserveActions';
15-
import { SGHODepositPanel } from 'src/modules/sGho/SGhoDepositPanel';
7+
import { useWeb3Context } from 'src/libs/hooks/useWeb3Context';
8+
import { SGhoCard } from 'src/modules/sGho/SGhoCard';
169
import { SGHOHeader } from 'src/modules/sGho/SGhoHeader';
10+
import { YourInfoSidebar } from 'src/modules/sGho/YourInfoSidebar';
11+
import { StkGhoCard } from 'src/modules/stkGho/StkGhoCard';
1712
import { useRootStore } from 'src/store/root';
18-
import { CustomMarket } from 'src/ui-config/marketsConfig';
19-
import { SAFETY_MODULE } from 'src/utils/events';
2013
import { useShallow } from 'zustand/shallow';
2114

22-
import { useWeb3Context } from '../src/libs/hooks/useWeb3Context';
23-
2415
const SavingsGhoDepositModal = dynamic(() =>
2516
import('../src/components/transactions/SavingsGho/SavingsGhoDepositModal').then(
2617
(module) => module.SavingsGhoDepositModal
@@ -36,180 +27,60 @@ const StakeRewardClaimModal = dynamic(() =>
3627
(module) => module.StakeRewardClaimModal
3728
)
3829
);
30+
const SGhoVaultDepositModal = dynamic(() =>
31+
import('../src/components/transactions/SGhoVault/SGhoVaultDepositModal').then(
32+
(module) => module.SGhoVaultDepositModal
33+
)
34+
);
35+
const SGhoVaultWithdrawModal = dynamic(() =>
36+
import('../src/components/transactions/SGhoVault/SGhoVaultWithdrawModal').then(
37+
(module) => module.SGhoVaultWithdrawModal
38+
)
39+
);
3940

4041
export default function SavingsGho() {
41-
const { openSavingsGhoDeposit, openSavingsGhoWithdraw } = useModalContext();
42-
const { currentAccount } = useWeb3Context();
4342
const [trackEvent, currentMarket, setCurrentMarket] = useRootStore(
4443
useShallow((store) => [store.trackEvent, store.currentMarket, store.setCurrentMarket])
4544
);
46-
const currentMarketData = useRootStore((store) => store.currentMarketData);
47-
const { breakpoints } = useTheme();
48-
const downToXsm = useMediaQuery(breakpoints.down('xsm'));
49-
const { data: stakeUserResult } = useUserStakeUiData(currentMarketData);
50-
51-
const { data: stakeGeneralResult } = useGeneralStakeUiData(currentMarketData);
45+
const { marketKey } = useSavingsMarketData();
46+
const { currentAccount } = useWeb3Context();
47+
const isConnected = !!currentAccount;
5248

53-
// Automatically switch to mainnet if not already on mainnet
54-
// since sGHO only exists on Ethereum mainnet
49+
// Keep the global currentMarket in sync with the savings target so the rest
50+
// of the app (wallet network checks, wallet balances, etc.) lines up with
51+
// the chain our data hooks are querying.
5552
useEffect(() => {
56-
if (currentMarket !== CustomMarket.proto_mainnet_v3) {
57-
setCurrentMarket(CustomMarket.proto_mainnet_v3);
53+
if (currentMarket !== marketKey) {
54+
setCurrentMarket(marketKey);
5855
}
59-
}, [currentMarket, setCurrentMarket]);
56+
}, [currentMarket, marketKey, setCurrentMarket]);
6057

6158
useEffect(() => {
6259
trackEvent('Page Viewed', {
6360
'Page Name': 'sGHO',
6461
});
6562
}, [trackEvent]);
6663

67-
let stkGho: StakeTokenFormatted | undefined;
68-
69-
if (stakeGeneralResult && Array.isArray(stakeGeneralResult)) {
70-
[, , stkGho] = stakeGeneralResult;
71-
}
72-
73-
let stkGhoUserData: StakeUIUserData | undefined;
74-
if (stakeUserResult && Array.isArray(stakeUserResult)) {
75-
[, , stkGhoUserData] = stakeUserResult;
76-
}
77-
7864
return (
7965
<>
8066
<SGHOHeader />
8167
<ContentContainer>
8268
<Box
8369
sx={{
8470
display: 'flex',
85-
flexDirection: { xs: 'column', md: 'row' },
86-
gap: { xs: 3, md: 0 },
87-
alignItems: { xs: 'stretch', md: 'flex-start' },
71+
flexDirection: { xs: 'column', mdlg: 'row' },
72+
gap: 4,
73+
alignItems: 'flex-start',
8874
}}
8975
>
90-
<Paper
91-
sx={{
92-
pt: 4,
93-
pb: { xs: 6, md: 20 },
94-
px: downToXsm ? 4 : 6,
95-
flex: 1,
96-
width: { xs: '100%', md: 'auto' },
97-
}}
98-
>
99-
<Box
100-
sx={{
101-
display: 'flex',
102-
alignItems: 'center',
103-
gap: 6,
104-
flexWrap: 'wrap',
105-
mb: { xs: 4, md: 6 },
106-
}}
107-
>
108-
<Box
109-
sx={{
110-
mb: { xs: 4, md: 8 },
111-
}}
112-
>
113-
<Typography variant="h3">
114-
<Trans>Savings GHO (sGHO)</Trans>
115-
</Typography>
116-
</Box>
117-
118-
<SGHODepositPanel
119-
stakedToken="GHO"
120-
stakeData={stkGho}
121-
stakeUserData={stkGhoUserData}
122-
onStakeAction={() => {
123-
trackEvent(SAFETY_MODULE.STAKE_SAFETY_MODULE, {
124-
action: SAFETY_MODULE.OPEN_STAKE_MODAL,
125-
asset: 'GHO',
126-
stakeType: 'Safety Module',
127-
});
128-
openSavingsGhoDeposit();
129-
}}
130-
onCooldownAction={() => {
131-
trackEvent(SAFETY_MODULE.STAKE_SAFETY_MODULE, {
132-
action: SAFETY_MODULE.OPEN_WITHDRAW_MODAL,
133-
asset: 'GHO',
134-
stakeType: 'Safety Module',
135-
});
136-
openSavingsGhoWithdraw();
137-
}}
138-
onUnstakeAction={() => {
139-
trackEvent(SAFETY_MODULE.STAKE_SAFETY_MODULE, {
140-
action: SAFETY_MODULE.OPEN_WITHDRAW_MODAL,
141-
asset: 'GHO',
142-
stakeType: 'Safety Module',
143-
});
144-
openSavingsGhoWithdraw();
145-
}}
146-
/>
147-
</Box>
148-
</Paper>
149-
{currentAccount ? <YourInfoGhoSection /> : <ConnectWallet />}
76+
<SGhoCard />
77+
{isConnected ? <StkGhoCard /> : <YourInfoSidebar />}
15078
</Box>
15179
</ContentContainer>
15280
</>
15381
);
15482
}
15583

156-
const YourInfoGhoSection = () => {
157-
const currentMarketData = useRootStore((store) => store.currentMarketData);
158-
const { walletBalances } = useWalletBalances(currentMarketData);
159-
160-
const GHO_ADDRESS = AaveV3Ethereum.ASSETS.GHO.UNDERLYING;
161-
162-
const userGhoBalance = GHO_ADDRESS
163-
? walletBalances[GHO_ADDRESS.toLowerCase()] || { amount: '0', amountUSD: '0' }
164-
: { amount: '0', amountUSD: '0' };
165-
166-
return (
167-
<Paper
168-
sx={{
169-
pt: 4,
170-
pb: { xs: 4, xsm: 6 },
171-
px: { xs: 4, xsm: 6 },
172-
minWidth: { md: '300px' },
173-
ml: { md: 4 },
174-
height: { md: '180px' },
175-
display: { xs: 'none', md: 'block' },
176-
}}
177-
>
178-
<Typography variant="h3" sx={{ mb: 6 }}>
179-
Your Info
180-
</Typography>
181-
<WalletBalance balance={userGhoBalance.amount} symbol="GHO" marketTitle="GHO" />
182-
</Paper>
183-
);
184-
};
185-
186-
const ConnectWallet = () => {
187-
return (
188-
<Paper
189-
sx={{
190-
pt: 4,
191-
pb: { xs: 4, xsm: 6 },
192-
px: { xs: 4, xsm: 6 },
193-
minWidth: { xs: '100%', md: '300px' },
194-
ml: { xs: 0, md: 4 },
195-
height: { xs: 'auto', md: '180px' },
196-
width: { xs: '100%', md: 'auto' },
197-
}}
198-
>
199-
<>
200-
<Typography variant="h3" sx={{ mb: { xs: 6, xsm: 10 } }}>
201-
<Trans>Your info</Trans>
202-
</Typography>
203-
<Typography sx={{ mb: 6 }} color="text.secondary">
204-
<Trans>Please connect a wallet to view your balance here.</Trans>
205-
</Typography>
206-
{}
207-
<ConnectWalletButton />
208-
</>
209-
</Paper>
210-
);
211-
};
212-
21384
SavingsGho.getLayout = function getLayout(page: React.ReactElement) {
21485
return (
21586
<MainLayout>
@@ -218,6 +89,8 @@ SavingsGho.getLayout = function getLayout(page: React.ReactElement) {
21889
<SavingsGhoDepositModal />
21990
<SavingsGhoWithdrawModal />
22091
<StakeRewardClaimModal />
92+
<SGhoVaultDepositModal />
93+
<SGhoVaultWithdrawModal />
22194
{/** End of modals */}
22295
</MainLayout>
22396
);
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Box, Grid, Skeleton, Stack } from '@mui/material';
2+
3+
interface SavingsCardSkeletonProps {
4+
hasAccount?: boolean;
5+
}
6+
7+
export const SavingsCardSkeleton = ({ hasAccount }: SavingsCardSkeletonProps) => {
8+
return (
9+
<Grid container spacing={{ xs: 1, md: 2 }} sx={{ mb: 4, minHeight: '600px' }}>
10+
<Grid item xs={12}>
11+
{hasAccount && (
12+
<Box
13+
sx={(theme) => ({
14+
borderRadius: { xs: '8px', xsm: '6px' },
15+
border: `1px solid ${theme.palette.divider}`,
16+
p: 4,
17+
mb: 4,
18+
background: theme.palette.background.paper,
19+
})}
20+
>
21+
<Stack spacing={3}>
22+
<Skeleton variant="rectangular" width="100%" height={60} />
23+
</Stack>
24+
</Box>
25+
)}
26+
27+
<Stack spacing={2} direction={{ xs: 'column', md: 'row' }}>
28+
<Skeleton variant="rectangular" width="100%" height={120} sx={{ borderRadius: 1 }} />
29+
</Stack>
30+
31+
<Box sx={{ mt: 4 }}>
32+
<Skeleton variant="rectangular" width="100%" height={200} sx={{ borderRadius: 1 }} />
33+
</Box>
34+
</Grid>
35+
</Grid>
36+
);
37+
};

0 commit comments

Comments
 (0)