Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/thirdweb/src/exports/react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
19 changes: 17 additions & 2 deletions packages/thirdweb/src/react/web/hooks/useSendTransaction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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 <LoadingScreen />;
}

Expand All @@ -202,6 +211,9 @@ function ModalContent(props: ModalProps) {
}}
isBuyForTx={true}
isEmbed={false}
account={account}
activeChain={activeChain}
switchChain={switchChain}
/>
);
}
Expand All @@ -226,6 +238,9 @@ function ModalContent(props: ModalProps) {
onDone={() => {
setScreen("execute-tx");
}}
account={account}
activeChain={activeChain}
switchChain={switchChain}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -173,7 +178,7 @@ function ConnectButtonInner(
return tokens;
}, [props.supportedTokens]);

if (!activeAccount) {
if (!activeAccount || !activeChain || !activeWallet) {
// Connect Wallet button
return (
<AnimatedButton
Expand Down Expand Up @@ -290,6 +295,9 @@ function ConnectButtonInner(
chains={props?.chains || []}
chain={props.chain}
switchButton={props.switchButton}
activeAccount={activeAccount}
activeChain={activeChain}
activeWallet={activeWallet}
/>
);
}
Expand Down
33 changes: 20 additions & 13 deletions packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -293,7 +295,7 @@ export const ConnectedWalletDetails: React.FC<{
<Skeleton height={"16px"} width={"200px"} />
) : (
<Text color="primaryText" multiline>
{chainQuery.data?.name || `Unknown chain #${walletChain?.id}`}
{chainQuery.data?.name || `Unknown chain #${activeChain?.id}`}
</Text>
)}

Expand Down Expand Up @@ -604,6 +606,9 @@ export const ConnectedWalletDetails: React.FC<{
onDone={() => {
setIsOpen(false);
}}
account={activeAccount}
activeChain={activeChain}
switchChain={switchChain}
/>
);
}
Expand All @@ -613,9 +618,8 @@ export const ConnectedWalletDetails: React.FC<{
<NetworkSelectorContent
// add currently connected chain to the list of chains if it's not already in the list
chains={
walletChain &&
props.chains.find((c) => c.id === walletChain.id) === undefined
? [walletChain, ...props.chains]
props.chains.find((c) => c.id === activeChain.id) === undefined
? [activeChain, ...props.chains]
: props.chains
}
closeModal={() => {
Expand Down Expand Up @@ -697,6 +701,9 @@ export const ConnectedWalletDetails: React.FC<{
onDone={() => {
setIsOpen(false);
}}
account={activeAccount}
activeChain={activeChain}
switchChain={switchChain}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand All @@ -79,6 +75,9 @@ export type BuyScreenProps = {
onDone: () => void;
connectButton?: React.ReactNode;
isEmbed: boolean;
account: Account | null;
activeChain: Chain | null;
switchChain: (chain: Chain) => Promise<void>;
};

/**
Expand Down Expand Up @@ -114,6 +113,9 @@ type BuyScreenContentProps = {
onDone: () => void;
connectButton?: React.ReactNode;
isEmbed: boolean;
account: Account | null;
activeChain: Chain | null;
switchChain: (chain: Chain) => Promise<void>;
};

function useBuyScreenStates(options: {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -489,6 +495,8 @@ function BuyScreenContent(props: BuyScreenContentProps) {
// currently disabled because we are only using Stripe
}}
account={account}
activeChain={activeChain}
switchChain={props.switchChain}
/>
)}

Expand Down Expand Up @@ -547,6 +555,7 @@ function SwapScreenContent(
showFromTokenSelector: () => void;
account: Account;
activeChain: Chain;
switchChain: (chain: Chain) => Promise<void>;
},
) {
const {
Expand Down Expand Up @@ -650,6 +659,8 @@ function SwapScreenContent(
});
quoteQuery.refetch();
}}
activeChain={props.activeChain}
switchChain={props.switchChain}
/>
),
});
Expand Down Expand Up @@ -691,6 +702,7 @@ function SwapScreenContent(
prefillSource?.allowEdits?.chain === false &&
prefillSource?.allowEdits?.token === false
}
account={account}
/>
<EstimatedTimeAndFees
quoteIsLoading={quoteQuery.isLoading}
Expand All @@ -713,7 +725,12 @@ function SwapScreenContent(
!quoteQuery.isLoading &&
!isNotEnoughBalance &&
!quoteQuery.error ? (
<SwitchNetworkButton variant="accent" fullWidth chain={fromChain} />
<SwitchNetworkButton
variant="accent"
fullWidth
chain={fromChain}
switchChain={props.switchChain}
/>
) : (
<Button
variant={disableContinue ? "outline" : "accent"}
Expand Down Expand Up @@ -754,6 +771,8 @@ function FiatScreenContent(
selectedCurrency: CurrencyMeta;
showCurrencySelector: () => void;
account: Account;
activeChain: Chain;
switchChain: (chain: Chain) => Promise<void>;
},
) {
const {
Expand Down Expand Up @@ -830,6 +849,9 @@ function FiatScreenContent(
openedWindow={openedWindow}
onDone={props.onDone}
isEmbed={props.isEmbed}
account={account}
activeChain={props.activeChain}
switchChain={props.switchChain}
/>
),
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { useState } from "react";
import type { Chain } from "../../../../../../../chains/types.js";
import type { ThirdwebClient } from "../../../../../../../client/client.js";
import type { BuyWithFiatQuote } from "../../../../../../../pay/buyWithFiat/getQuote.js";
import type { BuyWithFiatStatus } from "../../../../../../../pay/buyWithFiat/getStatus.js";
import { isSwapRequiredPostOnramp } from "../../../../../../../pay/buyWithFiat/isSwapRequiredPostOnramp.js";
import type { Account } from "../../../../../../../wallets/interfaces/wallet.js";
import { openOnrampPopup } from "../openOnRamppopup.js";
import { addPendingTx } from "../swap/pendingSwapTx.js";
import { OnrampStatusScreen } from "./FiatStatusScreen.js";
Expand Down Expand Up @@ -46,6 +48,9 @@ export function FiatFlow(props: {
onDone: () => void;
isBuyForTx: boolean;
isEmbed: boolean;
account: Account;
activeChain: Chain;
switchChain: (chain: Chain) => Promise<void>;
}) {
const hasTwoSteps = isSwapRequiredPostOnramp(props.quote);
const [screen, setScreen] = useState<Screen>(
Expand Down Expand Up @@ -116,6 +121,9 @@ export function FiatFlow(props: {
}}
isBuyForTx={props.isBuyForTx}
isEmbed={props.isEmbed}
account={props.account}
activeChain={props.activeChain}
switchChain={props.switchChain}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useQuery } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import type { Chain } from "../../../../../../../chains/types.js";
import type { ThirdwebClient } from "../../../../../../../client/client.js";
import type { BuyWithCryptoQuote } from "../../../../../../../pay/buyWithCrypto/getQuote.js";
import { getPostOnRampQuote } from "../../../../../../../pay/buyWithFiat/getPostOnRampQuote.js";
import type { BuyWithFiatStatus } from "../../../../../../../pay/buyWithFiat/getStatus.js";
import { useActiveAccount } from "../../../../../../core/hooks/wallets/wallet-hooks.js";
import type { Account } from "../../../../../../../wallets/interfaces/wallet.js";
import { Spacer } from "../../../../components/Spacer.js";
import { Spinner } from "../../../../components/Spinner.js";
import { Container, ModalHeader } from "../../../../components/basic.js";
Expand All @@ -22,9 +23,11 @@ export function PostOnRampSwap(props: {
onDone: () => void;
isBuyForTx: boolean;
isEmbed: boolean;
account: Account;
activeChain: Chain;
switchChain: (chain: Chain) => Promise<void>;
}) {
const account = useActiveAccount();

const { account } = props;
const [lockedOnRampQuote, setLockedOnRampQuote] = useState<
BuyWithCryptoQuote | undefined
>(undefined);
Expand Down Expand Up @@ -131,6 +134,8 @@ export function PostOnRampSwap(props: {
}}
isBuyForTx={props.isBuyForTx}
isEmbed={props.isEmbed}
activeChain={props.activeChain}
switchChain={props.switchChain}
/>
);
}
Loading