Skip to content

Commit fc65350

Browse files
[SDK] Preload wallet balances on pay embed (#7034)
1 parent b15c3c0 commit fc65350

File tree

4 files changed

+92
-55
lines changed

4 files changed

+92
-55
lines changed

.changeset/sour-flies-post.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
Preload wallet balances on pay embed

packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ import { SwapFlow } from "./swap/SwapFlow.js";
6363
import { SwapScreenContent } from "./swap/SwapScreenContent.js";
6464
import { TokenSelectorScreen } from "./swap/TokenSelectorScreen.js";
6565
import { TransferFlow } from "./swap/TransferFlow.js";
66+
import { useWalletsAndBalances } from "./swap/fetchBalancesForWallet.js";
6667
import {
6768
type SupportedChainAndTokens,
6869
useBuySupportedDestinations,
@@ -218,6 +219,15 @@ function BuyScreenContent(props: BuyScreenContentProps) {
218219
);
219220
}, [props.supportedTokens, supportedSourcesQuery.data, payOptions]);
220221

222+
// preload wallets and balances
223+
useWalletsAndBalances({
224+
client: props.client,
225+
sourceSupportedTokens: sourceSupportedTokens || [],
226+
toChain: toChain,
227+
toToken: toToken,
228+
mode: payOptions.mode,
229+
});
230+
221231
const { fromChain, setFromChain, fromToken, setFromToken } =
222232
useFromTokenSelectionStates({
223233
payOptions,

packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.tsx

Lines changed: 7 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
ChevronRightIcon,
55
Cross2Icon,
66
} from "@radix-ui/react-icons";
7-
import { useQuery } from "@tanstack/react-query";
87
import { trackPayEvent } from "../../../../../../../analytics/track/pay.js";
98
import type { Chain } from "../../../../../../../chains/types.js";
109
import type { ThirdwebClient } from "../../../../../../../client/client.js";
@@ -43,14 +42,9 @@ import { FiatValue } from "./FiatValue.js";
4342
import { WalletRow } from "./WalletRow.js";
4443
import {
4544
type TokenBalance,
46-
fetchBalancesForWallet,
45+
useWalletsAndBalances,
4746
} from "./fetchBalancesForWallet.js";
4847

49-
type WalletKey = {
50-
id: WalletId;
51-
address: string;
52-
};
53-
5448
export function TokenSelectorScreen(props: {
5549
client: ThirdwebClient;
5650
sourceTokens: SupportedTokens | undefined;
@@ -71,46 +65,12 @@ export function TokenSelectorScreen(props: {
7165
const chainInfo = useChainMetadata(props.toChain);
7266
const theme = useCustomTheme();
7367

74-
const walletsAndBalances = useQuery({
75-
queryKey: [
76-
"wallets-and-balances",
77-
props.sourceSupportedTokens,
78-
props.toChain.id,
79-
props.toToken,
80-
props.tokenAmount,
81-
props.mode,
82-
activeAccount?.address,
83-
connectedWallets.map((w) => w.getAccount()?.address),
84-
],
85-
enabled: !!props.sourceSupportedTokens && !!chainInfo.data,
86-
queryFn: async () => {
87-
const entries = await Promise.all(
88-
connectedWallets.map(async (wallet) => {
89-
const balances = await fetchBalancesForWallet({
90-
wallet,
91-
accountAddress: activeAccount?.address,
92-
sourceSupportedTokens: props.sourceSupportedTokens || [],
93-
toChain: props.toChain,
94-
toToken: props.toToken,
95-
tokenAmount: props.tokenAmount,
96-
mode: props.mode,
97-
client: props.client,
98-
});
99-
return [
100-
{
101-
id: wallet.id,
102-
address: wallet.getAccount()?.address || "",
103-
} as WalletKey,
104-
balances,
105-
] as const;
106-
}),
107-
);
108-
const map = new Map<WalletKey, TokenBalance[]>();
109-
for (const entry of entries) {
110-
map.set(entry[0], entry[1]);
111-
}
112-
return map;
113-
},
68+
const walletsAndBalances = useWalletsAndBalances({
69+
client: props.client,
70+
sourceSupportedTokens: props.sourceSupportedTokens || [],
71+
toChain: props.toChain,
72+
toToken: props.toToken,
73+
mode: props.mode,
11474
});
11575

11676
if (

packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/fetchBalancesForWallet.ts renamed to packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/fetchBalancesForWallet.tsx

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useQuery } from "@tanstack/react-query";
12
import type { Chain } from "../../../../../../../chains/types.js";
23
import { getCachedChain } from "../../../../../../../chains/utils.js";
34
import type { ThirdwebClient } from "../../../../../../../client/client.js";
@@ -9,7 +10,11 @@ import {
910
type GetWalletBalanceResult,
1011
getWalletBalance,
1112
} from "../../../../../../../wallets/utils/getWalletBalance.js";
13+
import type { WalletId } from "../../../../../../../wallets/wallet-types.js";
1214
import type { PayUIOptions } from "../../../../../../core/hooks/connection/ConnectButtonProps.js";
15+
import { useChainMetadata } from "../../../../../../core/hooks/others/useChainQuery.js";
16+
import { useActiveAccount } from "../../../../../../core/hooks/wallets/useActiveAccount.js";
17+
import { useConnectedWallets } from "../../../../../../core/hooks/wallets/useConnectedWallets.js";
1318
import type {
1419
SupportedTokens,
1520
TokenInfo,
@@ -32,7 +37,6 @@ type FetchBalancesParams = {
3237
sourceSupportedTokens: SupportedTokens;
3338
toChain: Chain;
3439
toToken: ERC20OrNativeToken;
35-
tokenAmount: string;
3640
mode: PayUIOptions["mode"];
3741
client: ThirdwebClient;
3842
};
@@ -43,13 +47,70 @@ export type TokenBalance = {
4347
token: TokenInfo;
4448
};
4549

46-
export async function fetchBalancesForWallet({
50+
type WalletKey = {
51+
id: WalletId;
52+
address: string;
53+
};
54+
55+
export function useWalletsAndBalances(props: {
56+
sourceSupportedTokens: SupportedTokens;
57+
toChain: Chain;
58+
toToken: ERC20OrNativeToken;
59+
mode: PayUIOptions["mode"];
60+
client: ThirdwebClient;
61+
}) {
62+
const activeAccount = useActiveAccount();
63+
const connectedWallets = useConnectedWallets();
64+
const chainInfo = useChainMetadata(props.toChain);
65+
66+
return useQuery({
67+
queryKey: [
68+
"wallets-and-balances",
69+
props.sourceSupportedTokens,
70+
props.toChain.id,
71+
props.toToken,
72+
props.mode,
73+
activeAccount?.address,
74+
connectedWallets.map((w) => w.getAccount()?.address),
75+
],
76+
enabled:
77+
!!props.sourceSupportedTokens && !!chainInfo.data && !!activeAccount,
78+
queryFn: async () => {
79+
const entries = await Promise.all(
80+
connectedWallets.map(async (wallet) => {
81+
const balances = await fetchBalancesForWallet({
82+
wallet,
83+
accountAddress: activeAccount?.address,
84+
sourceSupportedTokens: props.sourceSupportedTokens || [],
85+
toChain: props.toChain,
86+
toToken: props.toToken,
87+
mode: props.mode,
88+
client: props.client,
89+
});
90+
return [
91+
{
92+
id: wallet.id,
93+
address: wallet.getAccount()?.address || "",
94+
} as WalletKey,
95+
balances,
96+
] as const;
97+
}),
98+
);
99+
const map = new Map<WalletKey, TokenBalance[]>();
100+
for (const entry of entries) {
101+
map.set(entry[0], entry[1]);
102+
}
103+
return map;
104+
},
105+
});
106+
}
107+
108+
async function fetchBalancesForWallet({
47109
wallet,
48110
accountAddress,
49111
sourceSupportedTokens,
50112
toChain,
51113
toToken,
52-
tokenAmount,
53114
mode,
54115
client,
55116
}: FetchBalancesParams): Promise<TokenBalance[]> {
@@ -133,7 +194,7 @@ export async function fetchBalancesForWallet({
133194
b.chain.id === chainId &&
134195
b.token.address.toLowerCase() === token.address.toLowerCase(),
135196
);
136-
if (!isNative && !isAlreadyFetched) {
197+
if (isAlreadyFetched && !isNative) {
137198
// ERC20 on insight-enabled chain already handled by insight call
138199
continue;
139200
}
@@ -148,11 +209,12 @@ export async function fetchBalancesForWallet({
148209
});
149210

150211
const include =
151-
token.address === destinationToken.address &&
212+
token.address.toLowerCase() ===
213+
destinationToken.address.toLowerCase() &&
152214
chain.id === toChain.id
153-
? mode === "fund_wallet" && account.address === accountAddress
154-
? false
155-
: Number(balance.displayValue) > Number(tokenAmount)
215+
? !(
216+
mode === "fund_wallet" && account.address === accountAddress
217+
)
156218
: balance.value > 0n;
157219

158220
if (include) {

0 commit comments

Comments
 (0)