Skip to content

Commit b63991c

Browse files
authored
Merge pull request #9 from aave/fix/read-hooks
fix: read hooks variables to avoid unnecessary refetch
2 parents d66a378 + acf7481 commit b63991c

File tree

8 files changed

+220
-44
lines changed

8 files changed

+220
-44
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { type ChainId, type Market, useAaveMarkets } from '@aave/react';
2+
import { useEffect } from 'react';
3+
4+
interface MarketSelectorProps {
5+
chainId: ChainId;
6+
onChange: (market: Market) => void;
7+
}
8+
9+
export function MarketSelector({
10+
chainId,
11+
onChange: onMarketSelect,
12+
}: MarketSelectorProps) {
13+
const { data: markets } = useAaveMarkets({
14+
chainIds: [chainId],
15+
suspense: true,
16+
});
17+
18+
useEffect(() => {
19+
if (markets.length > 0) {
20+
onMarketSelect(markets[0]);
21+
}
22+
}, [markets, onMarketSelect]);
23+
24+
const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
25+
const selectedMarket = markets.find(
26+
(market) => market.address === event.target.value,
27+
);
28+
if (selectedMarket) {
29+
onMarketSelect(selectedMarket);
30+
}
31+
};
32+
33+
if (markets.length === 0) {
34+
return <p style={{ marginBottom: '5px' }}>No markets found</p>;
35+
}
36+
37+
return (
38+
<label>
39+
<strong style={{ display: 'block' }}>Market:</strong>
40+
<select
41+
onChange={handleChange}
42+
disabled={markets.length === 1}
43+
style={{ padding: '8px', width: '100%' }}
44+
>
45+
{markets.map((market) => (
46+
<option key={market.address} value={market.address}>
47+
{market.name} - ${market.totalMarketSize}
48+
</option>
49+
))}
50+
</select>
51+
<small style={{ color: '#666' }}>
52+
{markets.length === 1
53+
? 'Only one market found'
54+
: 'Select the market you want to supply to'}
55+
</small>
56+
</label>
57+
);
58+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import type { Reserve } from '@aave/react';
2+
3+
interface ReserveSelectorProps {
4+
children?: React.ReactNode;
5+
reserves: Reserve[];
6+
onChange: (reserve: Reserve) => void;
7+
}
8+
9+
export function ReserveSelector({
10+
children,
11+
reserves,
12+
onChange,
13+
}: ReserveSelectorProps) {
14+
const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
15+
const selectedReserve = reserves.find(
16+
(reserve) => reserve.underlyingToken.address === event.target.value,
17+
);
18+
if (selectedReserve) {
19+
onChange(selectedReserve);
20+
}
21+
};
22+
23+
return (
24+
<label style={{ marginBottom: '5px' }}>
25+
<strong style={{ display: 'block' }}>Reserve:</strong>
26+
<select onChange={handleChange} style={{ padding: '8px', width: '100%' }}>
27+
{reserves.map((reserve) => (
28+
<option
29+
key={reserve.underlyingToken.address}
30+
value={reserve.underlyingToken.address}
31+
>
32+
{reserve.underlyingToken.symbol} - APY:{' '}
33+
{reserve.supplyInfo.apy.value}%
34+
</option>
35+
))}
36+
</select>
37+
{children}
38+
</label>
39+
);
40+
}

examples/supply/src/SupplyForm.tsx

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import {
2+
bigDecimal,
3+
errAsync,
4+
evmAddress,
5+
type Reserve,
6+
useSupply,
7+
} from '@aave/react';
8+
import { useSendTransaction } from '@aave/react/viem';
9+
import { useState } from 'react';
10+
import type { WalletClient } from 'viem';
11+
12+
interface SupplyFormProps {
13+
reserve: Reserve;
14+
walletClient: WalletClient;
15+
}
16+
17+
export function SupplyForm({ reserve, walletClient }: SupplyFormProps) {
18+
const [amount, setAmount] = useState<string>('');
19+
const [status, setStatus] = useState<string>('');
20+
21+
const [supply, supplying] = useSupply();
22+
const [sendTransaction, sending] = useSendTransaction(walletClient);
23+
24+
const loading = supplying.loading || sending.loading;
25+
const error = supplying.error || sending.error;
26+
27+
const handleSupply = async () => {
28+
if (!amount) {
29+
setStatus('Please enter an amount');
30+
return;
31+
}
32+
33+
const result = await supply({
34+
chainId: reserve.market.chain.chainId,
35+
market: reserve.market.address,
36+
amount: {
37+
erc20: {
38+
currency: reserve.underlyingToken.address,
39+
value: bigDecimal(amount),
40+
},
41+
},
42+
supplier: evmAddress(walletClient.account!.address),
43+
}).andThen((plan) => {
44+
switch (plan.__typename) {
45+
case 'TransactionRequest':
46+
setStatus('Sending transaction...');
47+
return sendTransaction(plan);
48+
49+
case 'ApprovalRequired':
50+
setStatus('Approval required. Sending approval transaction...');
51+
52+
return sendTransaction(plan.approval).andThen(() => {
53+
setStatus('Approval sent. Now sending supply transaction...');
54+
55+
return sendTransaction(plan.originalTransaction);
56+
});
57+
58+
case 'InsufficientBalanceError':
59+
setStatus(
60+
`Insufficient balance: ${plan.available.value} ${reserve.underlyingToken.symbol}`,
61+
);
62+
return errAsync(
63+
new Error(`Insufficient balance: ${plan.required.value}`),
64+
);
65+
}
66+
});
67+
68+
if (result.isOk()) {
69+
setStatus('Supply successful!');
70+
}
71+
};
72+
73+
return (
74+
<div>
75+
<label
76+
style={{
77+
marginBottom: '5px',
78+
}}
79+
>
80+
<strong style={{ display: 'block' }}>Amount:</strong>
81+
<input
82+
disabled={loading}
83+
type='number'
84+
onChange={(e) => setAmount(e.target.value)}
85+
style={{ width: '100%', padding: '8px' }}
86+
placeholder='Amount to supply (in token units)'
87+
/>
88+
<small style={{ color: '#666' }}>
89+
Human-friendly amount (e.g. 1.23, 4.56, 7.89)
90+
</small>
91+
</label>
92+
93+
<button type='button' disabled={loading} onClick={handleSupply}>
94+
Supply
95+
</button>
96+
97+
{status && <p style={{ marginBottom: '10px' }}>{status}</p>}
98+
99+
{error && <p style={{ color: '#f44336' }}>Error: {error.toString()}</p>}
100+
</div>
101+
);
102+
}

packages/react/src/markets.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,16 @@ export function useAaveMarket(
4444

4545
export function useAaveMarket({
4646
suspense = false,
47-
address,
48-
chainId,
49-
user,
5047
borrowsOrderBy = defaultMarketReservesRequestOrderBy,
5148
suppliesOrderBy = defaultMarketReservesRequestOrderBy,
49+
...request
5250
}: UseAaveMarketArgs & {
5351
suspense?: boolean;
5452
}): SuspendableResult<Market | null> {
5553
return useSuspendableQuery({
5654
document: MarketQuery,
5755
variables: {
58-
request: { address, chainId, user },
56+
request,
5957
borrowsOrderBy,
6058
suppliesOrderBy,
6159
},
@@ -96,17 +94,16 @@ export function useAaveMarkets(args: UseAaveMarketsArgs): ReadResult<Market[]>;
9694

9795
export function useAaveMarkets({
9896
suspense = false,
99-
chainIds,
100-
user,
10197
borrowsOrderBy = defaultMarketReservesRequestOrderBy,
10298
suppliesOrderBy = defaultMarketReservesRequestOrderBy,
99+
...request
103100
}: UseAaveMarketsArgs & {
104101
suspense?: boolean;
105102
}): SuspendableResult<Market[]> {
106103
return useSuspendableQuery({
107104
document: MarketsQuery,
108105
variables: {
109-
request: { chainIds, user },
106+
request,
110107
borrowsOrderBy,
111108
suppliesOrderBy,
112109
},

packages/react/src/misc.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,14 @@ export function useUsdExchangeRates(
119119

120120
export function useUsdExchangeRates({
121121
suspense = false,
122-
market,
123-
underlyingTokens,
124-
chainId,
122+
...request
125123
}: UseUsdExchangeRatesArgs & {
126124
suspense?: boolean;
127125
}): SuspendableResult<UsdExchangeRate[]> {
128126
return useSuspendableQuery({
129127
document: UsdExchangeRatesQuery,
130128
variables: {
131-
request: { market, underlyingTokens, chainId },
129+
request,
132130
},
133131
suspense,
134132
});

packages/react/src/reserves.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,14 @@ export function useAaveReserve(
5353

5454
export function useAaveReserve({
5555
suspense = false,
56-
market,
57-
underlyingToken,
58-
chainId,
59-
user,
56+
...request
6057
}: UseAaveReserveArgs & {
6158
suspense?: boolean;
6259
}): SuspendableResult<Reserve | null> {
6360
return useSuspendableQuery({
6461
document: ReserveQuery,
6562
variables: {
66-
request: { market, underlyingToken, chainId, user },
63+
request,
6764
},
6865
suspense,
6966
});

packages/react/src/user.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,14 @@ export function useUserSupplies(
5959

6060
export function useUserSupplies({
6161
suspense = false,
62-
markets,
63-
user,
64-
collateralsOnly,
65-
orderBy,
62+
...request
6663
}: UseUserSuppliesArgs & {
6764
suspense?: boolean;
6865
}): SuspendableResult<MarketUserReserveSupplyPosition[]> {
6966
return useSuspendableQuery({
7067
document: UserSuppliesQuery,
7168
variables: {
72-
request: { markets, user, collateralsOnly, orderBy },
69+
request,
7370
},
7471
suspense,
7572
});
@@ -112,16 +109,14 @@ export function useUserBorrows(
112109

113110
export function useUserBorrows({
114111
suspense = false,
115-
markets,
116-
user,
117-
orderBy,
112+
...request
118113
}: UseUserBorrowsArgs & {
119114
suspense?: boolean;
120115
}): SuspendableResult<MarketUserReserveBorrowPosition[]> {
121116
return useSuspendableQuery({
122117
document: UserBorrowsQuery,
123118
variables: {
124-
request: { markets, user, orderBy },
119+
request,
125120
},
126121
suspense,
127122
});
@@ -164,16 +159,14 @@ export function useUserMarketState(
164159

165160
export function useUserMarketState({
166161
suspense = false,
167-
market,
168-
user,
169-
chainId,
162+
...request
170163
}: UseUserStateArgs & {
171164
suspense?: boolean;
172165
}): SuspendableResult<MarketUserState> {
173166
return useSuspendableQuery({
174167
document: UserMarketStateQuery,
175168
variables: {
176-
request: { market, user, chainId },
169+
request,
177170
},
178171
suspense,
179172
});

0 commit comments

Comments
 (0)