diff --git a/packages/thirdweb/src/exports/react.ts b/packages/thirdweb/src/exports/react.ts
index 243afcb505d..659e70588e3 100644
--- a/packages/thirdweb/src/exports/react.ts
+++ b/packages/thirdweb/src/exports/react.ts
@@ -121,4 +121,10 @@ export {
type PayEmbedProps,
type PayEmbedConnectOptions,
} from "../react/web/ui/PayEmbed.js";
+
+export {
+ PayEmbedUI,
+ type PayEmbedUIProps,
+} from "../react/web/ui/PayEmbedUI.js";
+
export type { PayUIOptions } from "../react/web/ui/ConnectWallet/ConnectButtonProps.js";
diff --git a/packages/thirdweb/src/react/web/hooks/useSendTransaction.tsx b/packages/thirdweb/src/react/web/hooks/useSendTransaction.tsx
index ce4709f29b5..b69e3fbb5ea 100644
--- a/packages/thirdweb/src/react/web/hooks/useSendTransaction.tsx
+++ b/packages/thirdweb/src/react/web/hooks/useSendTransaction.tsx
@@ -5,7 +5,12 @@ import type { GaslessOptions } from "../../../transaction/actions/gasless/types.
import type { PreparedTransaction } from "../../../transaction/prepare-transaction.js";
import type { Wallet } from "../../../wallets/interfaces/wallet.js";
import { useSendTransactionCore } from "../../core/hooks/contract/useSendTransaction.js";
-import { useActiveWallet } from "../../core/hooks/wallets/wallet-hooks.js";
+import {
+ useActiveAccount,
+ useActiveWallet,
+ useActiveWalletChain,
+ useSwitchActiveWalletChain,
+} from "../../core/hooks/wallets/wallet-hooks.js";
import { SetRootElementContext } from "../../core/providers/RootElementContext.js";
import type { PayUIOptions } from "../ui/ConnectWallet/ConnectButtonProps.js";
import type { SupportedTokens } from "../ui/ConnectWallet/defaultTokens.js";
@@ -182,7 +187,11 @@ function ModalContent(props: ModalProps) {
"buy",
);
- if (!localeQuery.data) {
+ const account = useActiveAccount();
+ const activeChain = useActiveWalletChain();
+ const switchChain = useSwitchActiveWalletChain();
+
+ if (!localeQuery.data || !account || !activeChain) {
return ;
}
@@ -202,6 +211,9 @@ function ModalContent(props: ModalProps) {
}}
isBuyForTx={true}
isEmbed={false}
+ account={account}
+ activeChain={activeChain}
+ switchChain={switchChain}
/>
);
}
@@ -226,6 +238,9 @@ function ModalContent(props: ModalProps) {
onDone={() => {
setScreen("execute-tx");
}}
+ account={account}
+ activeChain={activeChain}
+ switchChain={switchChain}
/>
);
}
diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx
index dfba3ded8c0..45c9de8d9fb 100644
--- a/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx
+++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx
@@ -6,6 +6,8 @@ import { useSiweAuth } from "../../../core/hooks/auth/useSiweAuth.js";
import { AutoConnect } from "../../../core/hooks/connection/useAutoConnect.js";
import {
useActiveAccount,
+ useActiveWallet,
+ useActiveWalletChain,
useActiveWalletConnectionStatus,
} from "../../../core/hooks/wallets/wallet-hooks.js";
import { ConnectUIContext } from "../../../core/providers/wallet-connection.js";
@@ -135,6 +137,9 @@ function ConnectButtonInner(
},
) {
const activeAccount = useActiveAccount();
+ const activeChain = useActiveWalletChain();
+ const activeWallet = useActiveWallet();
+
const siweAuth = useSiweAuth(props.auth);
const [showSignatureModal, setShowSignatureModal] = useState(false);
@@ -173,7 +178,7 @@ function ConnectButtonInner(
return tokens;
}, [props.supportedTokens]);
- if (!activeAccount) {
+ if (!activeAccount || !activeChain || !activeWallet) {
// Connect Wallet button
return (
);
}
diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx
index 638c3404f21..b22b93e1880 100644
--- a/packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx
+++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx
@@ -16,6 +16,7 @@ import { getContract } from "../../../../contract/contract.js";
import { resolveAvatar } from "../../../../extensions/ens/resolve-avatar.js";
import { resolveName } from "../../../../extensions/ens/resolve-name.js";
import { isContractDeployed } from "../../../../utils/bytecode/is-contract-deployed.js";
+import type { Account, Wallet } from "../../../../wallets/interfaces/wallet.js";
import {
useChainQuery,
useChainsQuery,
@@ -97,24 +98,26 @@ export const ConnectedWalletDetails: React.FC<{
chains: Chain[];
chain?: Chain;
switchButton: ConnectButtonProps["switchButton"];
+ activeWallet: Wallet;
+ activeChain: Chain;
+ activeAccount: Account;
}> = (props) => {
const { connectLocale: locale, client } = useConnectUI();
+ const { activeChain, activeWallet, activeAccount } = props;
+ const switchChain = useSwitchActiveWalletChain();
- const activeWallet = useActiveWallet();
- const activeAccount = useActiveAccount();
- const walletChain = useActiveWalletChain();
- const chainQuery = useChainQuery(walletChain);
+ const chainQuery = useChainQuery(activeChain);
const { disconnect } = useDisconnect();
// prefetch chains metadata with low concurrency
useChainsQuery(props.chains, 5);
const tokenAddress =
- walletChain && props.detailsButton?.displayBalanceToken
- ? props.detailsButton.displayBalanceToken[Number(walletChain.id)]
+ activeChain && props.detailsButton?.displayBalanceToken
+ ? props.detailsButton.displayBalanceToken[Number(activeChain.id)]
: undefined;
const balanceQuery = useWalletBalance({
- chain: walletChain ? walletChain : undefined,
+ chain: activeChain,
tokenAddress,
address: activeAccount?.address,
client,
@@ -174,8 +177,7 @@ export const ConnectedWalletDetails: React.FC<{
// avatarOrWalletIconUrl = smartWalletMetadata.iconUrl;
// }
- const isNetworkMismatch =
- props.chain && walletChain && walletChain.id !== props.chain.id;
+ const isNetworkMismatch = props.chain && activeChain.id !== props.chain.id;
// Note: Must wrap the `SwitchNetworkButton` in a fragment to avoid warning from radix-ui
// Note: Must wrap the `detailsButton.render` in an container element
@@ -293,7 +295,7 @@ export const ConnectedWalletDetails: React.FC<{
) : (
- {chainQuery.data?.name || `Unknown chain #${walletChain?.id}`}
+ {chainQuery.data?.name || `Unknown chain #${activeChain?.id}`}
)}
@@ -604,6 +606,9 @@ export const ConnectedWalletDetails: React.FC<{
onDone={() => {
setIsOpen(false);
}}
+ account={activeAccount}
+ activeChain={activeChain}
+ switchChain={switchChain}
/>
);
}
@@ -613,9 +618,8 @@ export const ConnectedWalletDetails: React.FC<{
c.id === walletChain.id) === undefined
- ? [walletChain, ...props.chains]
+ props.chains.find((c) => c.id === activeChain.id) === undefined
+ ? [activeChain, ...props.chains]
: props.chains
}
closeModal={() => {
@@ -697,6 +701,9 @@ export const ConnectedWalletDetails: React.FC<{
onDone={() => {
setIsOpen(false);
}}
+ account={activeAccount}
+ activeChain={activeChain}
+ switchChain={switchChain}
/>
);
}
diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx
index cc9df7e0c72..9e89f764e7e 100644
--- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx
+++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx
@@ -14,10 +14,6 @@ import {
import { useWalletBalance } from "../../../../../core/hooks/others/useWalletBalance.js";
import { useBuyWithCryptoQuote } from "../../../../../core/hooks/pay/useBuyWithCryptoQuote.js";
import { useBuyWithFiatQuote } from "../../../../../core/hooks/pay/useBuyWithFiatQuote.js";
-import {
- useActiveAccount,
- useActiveWalletChain,
-} from "../../../../../core/hooks/wallets/wallet-hooks.js";
import { LoadingScreen } from "../../../../wallets/shared/LoadingScreen.js";
import {
Drawer,
@@ -65,7 +61,7 @@ import {
useBuySupportedSources,
} from "./swap/useSwapSupportedChains.js";
-// NOTE: Must not use useConnectUI here because this UI can be used outside connect ui
+// NOTE: Can not use any wallet hooks or Context
export type BuyScreenProps = {
onBack?: () => void;
@@ -79,6 +75,9 @@ export type BuyScreenProps = {
onDone: () => void;
connectButton?: React.ReactNode;
isEmbed: boolean;
+ account: Account | null;
+ activeChain: Chain | null;
+ switchChain: (chain: Chain) => Promise;
};
/**
@@ -114,6 +113,9 @@ type BuyScreenContentProps = {
onDone: () => void;
connectButton?: React.ReactNode;
isEmbed: boolean;
+ account: Account | null;
+ activeChain: Chain | null;
+ switchChain: (chain: Chain) => Promise;
};
function useBuyScreenStates(options: {
@@ -166,11 +168,15 @@ function useBuyScreenStates(options: {
* @internal
*/
function BuyScreenContent(props: BuyScreenContentProps) {
- const { client, supportedDestinations, connectLocale, payOptions, buyForTx } =
- props;
-
- const account = useActiveAccount();
- const activeChain = useActiveWalletChain();
+ const {
+ client,
+ supportedDestinations,
+ connectLocale,
+ payOptions,
+ buyForTx,
+ activeChain,
+ account,
+ } = props;
// prefetch chains metadata for destination chains
useChainsQuery(supportedDestinations.map((x) => x.chain) || [], 50);
@@ -489,6 +495,8 @@ function BuyScreenContent(props: BuyScreenContentProps) {
// currently disabled because we are only using Stripe
}}
account={account}
+ activeChain={activeChain}
+ switchChain={props.switchChain}
/>
)}
@@ -547,6 +555,7 @@ function SwapScreenContent(
showFromTokenSelector: () => void;
account: Account;
activeChain: Chain;
+ switchChain: (chain: Chain) => Promise;
},
) {
const {
@@ -650,6 +659,8 @@ function SwapScreenContent(
});
quoteQuery.refetch();
}}
+ activeChain={props.activeChain}
+ switchChain={props.switchChain}
/>
),
});
@@ -691,6 +702,7 @@ function SwapScreenContent(
prefillSource?.allowEdits?.chain === false &&
prefillSource?.allowEdits?.token === false
}
+ account={account}
/>
+
) : (