From 322a014e9122d0201b7acfa80be8d8b80c3880ac Mon Sep 17 00:00:00 2001 From: gregfromstl Date: Sun, 11 May 2025 12:26:29 -0700 Subject: [PATCH 1/7] [Thirdweb] Fix: Automatically trigger login for connected wallets when auth is required MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .changeset/every-sides-invent.md | 5 +++++ .../web/ui/ConnectWallet/ConnectButton.tsx | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 .changeset/every-sides-invent.md diff --git a/.changeset/every-sides-invent.md b/.changeset/every-sides-invent.md new file mode 100644 index 00000000000..c33f2cd11c9 --- /dev/null +++ b/.changeset/every-sides-invent.md @@ -0,0 +1,5 @@ +--- +"thirdweb": patch +--- + +Automatically trigger SIWE sign in when a wallet is connected diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx index 0a54aeb85f6..de8563cb25d 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx @@ -410,6 +410,24 @@ function ConnectButtonInner( } }, [activeAccount]); + // if the wallet is connected and auth is required, trigger a login attempt automatically + useEffect(() => { + if ( + activeAccount && + siweAuth.requiresAuth && + !siweAuth.isLoggedIn && + !siweAuth.isLoggingIn + ) { + siweAuth.doLogin(); + } + }, [ + activeAccount, + siweAuth.requiresAuth, + siweAuth.doLogin, + siweAuth.isLoggedIn, + siweAuth.isLoggingIn, + ]); + const theme = props.theme || "dark"; const connectionStatus = useActiveWalletConnectionStatus(); const locale = props.connectLocale; From c2acfd1a52110ba1ebb8a4adb4934f09ee6edb89 Mon Sep 17 00:00:00 2001 From: gregfromstl Date: Sun, 11 May 2025 12:32:06 -0700 Subject: [PATCH 2/7] fix: only trigger SIWE auto sign in for IAW --- .../src/react/web/ui/ConnectWallet/ConnectButton.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx index de8563cb25d..3cb8f63cb7d 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx @@ -30,6 +30,7 @@ import { LockIcon } from "./icons/LockIcon.js"; import { useConnectLocale } from "./locale/getConnectLocale.js"; import type { ConnectLocale } from "./locale/types.js"; import { SignatureScreen } from "./screens/SignatureScreen.js"; +import { useAdminWallet } from "src/exports/react.native.js"; const TW_CONNECT_WALLET = "tw-connect-wallet"; @@ -400,6 +401,7 @@ function ConnectButtonInner( ) { const activeWallet = useActiveWallet(); const activeAccount = useActiveAccount(); + const adminWallet = useAdminWallet(); const siweAuth = useSiweAuth(activeWallet, activeAccount, props.auth); const [showSignatureModal, setShowSignatureModal] = useState(false); @@ -410,13 +412,15 @@ function ConnectButtonInner( } }, [activeAccount]); - // if the wallet is connected and auth is required, trigger a login attempt automatically + // if an IAW wallet is connected and auth is required, trigger a login attempt automatically useEffect(() => { + const isIAW = activeWallet?.id === "inApp" || adminWallet?.id === "inApp"; if ( activeAccount && siweAuth.requiresAuth && !siweAuth.isLoggedIn && - !siweAuth.isLoggingIn + !siweAuth.isLoggingIn && + isIAW ) { siweAuth.doLogin(); } @@ -426,6 +430,8 @@ function ConnectButtonInner( siweAuth.doLogin, siweAuth.isLoggedIn, siweAuth.isLoggingIn, + activeWallet, + adminWallet, ]); const theme = props.theme || "dark"; From 3edf9318f5f1a4a308e55af0372005ff07302b9d Mon Sep 17 00:00:00 2001 From: gregfromstl Date: Sun, 11 May 2025 13:34:19 -0700 Subject: [PATCH 3/7] feat: auto-login when connecting via url --- .../hooks/connection/ConnectEmbedProps.ts | 5 +++ .../react/native/ui/connect/ConnectButton.tsx | 5 ++- .../web/ui/ConnectWallet/ConnectButton.tsx | 38 +++++------------ .../ui/ConnectWallet/Modal/ConnectEmbed.tsx | 23 ++++++----- .../screens/Buy/fiat/OnRampScreen.tsx | 22 +--------- .../thirdweb/src/react/web/ui/PayEmbed.tsx | 24 ++++++++--- .../src/wallets/connection/autoConnectCore.ts | 41 +++++++++++-------- .../thirdweb/src/wallets/connection/types.ts | 5 +++ .../in-app/core/wallet/is-in-app-signer.ts | 21 ++++++++++ 9 files changed, 101 insertions(+), 83 deletions(-) create mode 100644 packages/thirdweb/src/wallets/in-app/core/wallet/is-in-app-signer.ts diff --git a/packages/thirdweb/src/react/core/hooks/connection/ConnectEmbedProps.ts b/packages/thirdweb/src/react/core/hooks/connection/ConnectEmbedProps.ts index 7756b720b6f..c9ba44d6853 100644 --- a/packages/thirdweb/src/react/core/hooks/connection/ConnectEmbedProps.ts +++ b/packages/thirdweb/src/react/core/hooks/connection/ConnectEmbedProps.ts @@ -289,6 +289,11 @@ export type ConnectEmbedProps = { */ auth?: SiweAuthOptions; + /** + * @hidden + */ + siweLogin?: () => Promise; + /** * Customize the welcome screen. This prop is only applicable when modalSize prop is set to "wide". On "wide" Modal size, a welcome screen is shown on the right side of the modal. * diff --git a/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx b/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx index 683f75a9c51..a96ad940392 100644 --- a/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx +++ b/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx @@ -47,7 +47,10 @@ export function ConnectButton(props: ConnectButtonProps) { const status = useActiveWalletConnectionStatus(); const connectionManager = useConnectionManager(); const siweAuth = useSiweAuth(wallet, account, props.auth); - useAutoConnect(props); + useAutoConnect({ + ...props, + siweLogin: siweAuth.doLogin, + }); const fadeAnim = useRef(new Animated.Value(0)); // For background opacity const slideAnim = useRef(new Animated.Value(screenHeight)); // For bottom sheet position diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx index 3cb8f63cb7d..7ae08abd615 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx @@ -30,7 +30,6 @@ import { LockIcon } from "./icons/LockIcon.js"; import { useConnectLocale } from "./locale/getConnectLocale.js"; import type { ConnectLocale } from "./locale/types.js"; import { SignatureScreen } from "./screens/SignatureScreen.js"; -import { useAdminWallet } from "src/exports/react.native.js"; const TW_CONNECT_WALLET = "tw-connect-wallet"; @@ -298,6 +297,9 @@ export function ConnectButton(props: ConnectButtonProps) { ); const localeQuery = useConnectLocale(props.locale || "en_US"); const connectionManager = useConnectionManager(); + const activeAccount = useActiveAccount(); + const activeWallet = useActiveWallet(); + const siweAuth = useSiweAuth(activeWallet, activeAccount, props.auth); usePreloadWalletProviders({ wallets, @@ -338,6 +340,7 @@ export function ConnectButton(props: ConnectButtonProps) { } accountAbstraction={props.accountAbstraction} onConnect={props.onConnect} + siweLogin={siweAuth.doLogin} /> ); @@ -363,7 +366,11 @@ export function ConnectButton(props: ConnectButtonProps) { return ( - + ; }, ) { - const activeWallet = useActiveWallet(); + const siweAuth = props.siweAuth; const activeAccount = useActiveAccount(); - const adminWallet = useAdminWallet(); - const siweAuth = useSiweAuth(activeWallet, activeAccount, props.auth); const [showSignatureModal, setShowSignatureModal] = useState(false); // if wallet gets disconnected suddently, close the signature modal if it's open @@ -412,28 +418,6 @@ function ConnectButtonInner( } }, [activeAccount]); - // if an IAW wallet is connected and auth is required, trigger a login attempt automatically - useEffect(() => { - const isIAW = activeWallet?.id === "inApp" || adminWallet?.id === "inApp"; - if ( - activeAccount && - siweAuth.requiresAuth && - !siweAuth.isLoggedIn && - !siweAuth.isLoggingIn && - isIAW - ) { - siweAuth.doLogin(); - } - }, [ - activeAccount, - siweAuth.requiresAuth, - siweAuth.doLogin, - siweAuth.isLoggedIn, - siweAuth.isLoggingIn, - activeWallet, - adminWallet, - ]); - const theme = props.theme || "dark"; const connectionStatus = useActiveWalletConnectionStatus(); const locale = props.connectLocale; diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx index 62570702010..fb8869dd815 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx @@ -11,8 +11,8 @@ import { } from "../../../../core/design-system/CustomThemeProvider.js"; import { radius } from "../../../../core/design-system/index.js"; import { - type SiweAuthOptions, useSiweAuth, + type SiweAuthOptions, } from "../../../../core/hooks/auth/useSiweAuth.js"; import type { ConnectEmbedProps } from "../../../../core/hooks/connection/ConnectEmbedProps.js"; import { useActiveAccount } from "../../../../core/hooks/wallets/useActiveAccount.js"; @@ -247,6 +247,7 @@ export function ConnectEmbed(props: ConnectEmbedProps) { chain={preferredChain} appMetadata={props.appMetadata} client={props.client} + siweLogin={siweAuth.doLogin} wallets={wallets} accountAbstraction={props.accountAbstraction} timeout={ @@ -326,21 +327,21 @@ const ConnectEmbedContent = (props: { }; size: "compact" | "wide"; header: - | { - title?: string; - titleIcon?: string; - } - | true - | undefined; + | { + title?: string; + titleIcon?: string; + } + | true + | undefined; localeId: LocaleId; onConnect: ((wallet: Wallet) => void) | undefined; recommendedWallets: Wallet[] | undefined; showAllWallets: boolean | undefined; walletConnect: - | { - projectId?: string; - } - | undefined; + | { + projectId?: string; + } + | undefined; wallets: Wallet[]; welcomeScreen: WelcomeScreen | undefined; }) => { diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/OnRampScreen.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/OnRampScreen.tsx index cc49c2459eb..971651d215b 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/OnRampScreen.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/OnRampScreen.tsx @@ -23,10 +23,7 @@ import { sendTransaction } from "../../../../../../../transaction/actions/send-t import type { WaitForReceiptOptions } from "../../../../../../../transaction/actions/wait-for-tx-receipt.js"; import { waitForReceipt } from "../../../../../../../transaction/actions/wait-for-tx-receipt.js"; import { formatNumber } from "../../../../../../../utils/formatNumber.js"; -import { isEcosystemWallet } from "../../../../../../../wallets/ecosystem/is-ecosystem-wallet.js"; -import { isInAppWallet } from "../../../../../../../wallets/in-app/core/wallet/index.js"; -import type { Wallet } from "../../../../../../../wallets/interfaces/wallet.js"; -import { isSmartWallet } from "../../../../../../../wallets/smart/is-smart-wallet.js"; +import { isInAppSigner } from "../../../../../../../wallets/in-app/core/wallet/is-in-app-signer.js"; import { spacing } from "../../../../../../core/design-system/index.js"; import { useChainName } from "../../../../../../core/hooks/others/useChainQuery.js"; import { useBuyWithCryptoStatus } from "../../../../../../core/hooks/pay/useBuyWithCryptoStatus.js"; @@ -779,20 +776,3 @@ function useSwapMutation(props: { }, }); } - -function isInAppSigner(options: { - wallet: Wallet; - connectedWallets: Wallet[]; -}) { - const isInAppOrEcosystem = (w: Wallet) => - isInAppWallet(w) || isEcosystemWallet(w); - const isSmartWalletWithAdmin = - isSmartWallet(options.wallet) && - options.connectedWallets.some( - (w) => - isInAppOrEcosystem(w) && - w.getAccount()?.address?.toLowerCase() === - options.wallet.getAdminAccount?.()?.address?.toLowerCase(), - ); - return isInAppOrEcosystem(options.wallet) || isSmartWalletWithAdmin; -} diff --git a/packages/thirdweb/src/react/web/ui/PayEmbed.tsx b/packages/thirdweb/src/react/web/ui/PayEmbed.tsx index d7efb970c35..fe7d5430b64 100644 --- a/packages/thirdweb/src/react/web/ui/PayEmbed.tsx +++ b/packages/thirdweb/src/react/web/ui/PayEmbed.tsx @@ -9,7 +9,10 @@ import type { AppMetadata } from "../../../wallets/types.js"; import type { WalletId } from "../../../wallets/wallet-types.js"; import { CustomThemeProvider } from "../../core/design-system/CustomThemeProvider.js"; import type { Theme } from "../../core/design-system/index.js"; -import type { SiweAuthOptions } from "../../core/hooks/auth/useSiweAuth.js"; +import { + useSiweAuth, + type SiweAuthOptions, +} from "../../core/hooks/auth/useSiweAuth.js"; import type { ConnectButton_connectModalOptions, PayUIOptions, @@ -23,6 +26,9 @@ import { ExecutingTxScreen } from "./TransactionButton/ExecutingScreen.js"; import { DynamicHeight } from "./components/DynamicHeight.js"; import { Spinner } from "./components/Spinner.js"; import type { LocaleId } from "./types.js"; +import { useActiveAccount } from "../../core/hooks/wallets/useActiveAccount.js"; +import { useActiveWallet } from "../../core/hooks/wallets/useActiveWallet.js"; +import { AutoConnect } from "../../web/ui/AutoConnect/AutoConnect.js"; /** * Props of [`PayEmbed`](https://portal.thirdweb.com/references/typescript/v5/PayEmbed) component @@ -300,6 +306,13 @@ export function PayEmbed(props: PayEmbedProps) { const [screen, setScreen] = useState<"buy" | "execute-tx">("buy"); const theme = props.theme || "dark"; const connectionManager = useConnectionManager(); + const activeAccount = useActiveAccount(); + const activeWallet = useActiveWallet(); + const siweAuth = useSiweAuth( + activeWallet, + activeAccount, + props.connectOptions?.auth, + ); // Add props.chain and props.chains to defined chains store useEffect(() => { @@ -342,6 +355,7 @@ export function PayEmbed(props: PayEmbedProps) { } else { content = ( <> + {screen === "buy" && ( w.id === result?.walletId); - if (result?.authCookie && wallet) { + const wallet = wallets.find((w) => w.id === urlToken?.walletId); + if (urlToken?.authCookie && wallet) { const clientStorage = new ClientScopedStorage({ storage, clientId: props.client.clientId, ecosystem: isEcosystemWallet(wallet) ? { - id: wallet.id, - partnerId: wallet.getConfig()?.partnerId, - } + id: wallet.id, + partnerId: wallet.getConfig()?.partnerId, + } : undefined, }); - await clientStorage.saveAuthCookie(result.authCookie); + await clientStorage.saveAuthCookie(urlToken.authCookie); } - if (result?.walletId) { - lastActiveWalletId = result.walletId; - lastConnectedWalletIds = lastConnectedWalletIds?.includes(result.walletId) + if (urlToken?.walletId) { + lastActiveWalletId = urlToken.walletId; + lastConnectedWalletIds = lastConnectedWalletIds?.includes(urlToken.walletId) ? lastConnectedWalletIds - : [result.walletId, ...(lastConnectedWalletIds || [])]; + : [urlToken.walletId, ...(lastConnectedWalletIds || [])]; } - if (result?.authProvider) { - await setLastAuthProvider?.(result.authProvider, storage); + if (urlToken?.authProvider) { + await setLastAuthProvider?.(urlToken.authProvider, storage); } // if no wallets were last connected or we didn't receive an auth token @@ -132,7 +132,7 @@ const _autoConnectCore = async ({ wallet: activeWallet, client: props.client, lastConnectedChain, - authResult: result?.authResult, + authResult: urlToken?.authResult, }), { ms: timeout, @@ -150,9 +150,9 @@ const _autoConnectCore = async ({ const connectedWallet = await (connectOverride ? connectOverride(activeWallet) : manager.connect(activeWallet, { - client: props.client, - accountAbstraction: props.accountAbstraction, - })); + client: props.client, + accountAbstraction: props.accountAbstraction, + })); if (connectedWallet) { autoConnected = true; try { @@ -183,13 +183,18 @@ const _autoConnectCore = async ({ wallet, client: props.client, lastConnectedChain, - authResult: result?.authResult, + authResult: urlToken?.authResult, }); manager.addConnectedWallet(wallet); } catch { // no-op } } + + // Auto-login with SIWE + if (urlToken && activeWallet && props.siweLogin) { + await props.siweLogin(); + } manager.isAutoConnecting.setValue(false); return autoConnected; // useQuery needs a return value }; diff --git a/packages/thirdweb/src/wallets/connection/types.ts b/packages/thirdweb/src/wallets/connection/types.ts index a08ef8bbd6c..d30bca8e645 100644 --- a/packages/thirdweb/src/wallets/connection/types.ts +++ b/packages/thirdweb/src/wallets/connection/types.ts @@ -118,4 +118,9 @@ export type AutoConnectProps = { * Callback to be called when the connection is timeout-ed */ onTimeout?: () => void; + + /** + * @hidden + */ + siweLogin?: () => Promise; }; diff --git a/packages/thirdweb/src/wallets/in-app/core/wallet/is-in-app-signer.ts b/packages/thirdweb/src/wallets/in-app/core/wallet/is-in-app-signer.ts new file mode 100644 index 00000000000..48a57680a8c --- /dev/null +++ b/packages/thirdweb/src/wallets/in-app/core/wallet/is-in-app-signer.ts @@ -0,0 +1,21 @@ +import { isEcosystemWallet } from "../../../../wallets/ecosystem/is-ecosystem-wallet.js"; +import type { Wallet } from "../../../interfaces/wallet.js"; +import { isSmartWallet } from "../../../smart/index.js"; +import { isInAppWallet } from "./index.js"; + +export function isInAppSigner(options: { + wallet: Wallet; + connectedWallets: Wallet[]; +}) { + const isInAppOrEcosystem = (w: Wallet) => + isInAppWallet(w) || isEcosystemWallet(w); + const isSmartWalletWithAdmin = + isSmartWallet(options.wallet) && + options.connectedWallets.some( + (w) => + isInAppOrEcosystem(w) && + w.getAccount()?.address?.toLowerCase() === + options.wallet.getAdminAccount?.()?.address?.toLowerCase(), + ); + return isInAppOrEcosystem(options.wallet) || isSmartWalletWithAdmin; +} From da3e776a774fdaacb782af5ca391746af66dae3f Mon Sep 17 00:00:00 2001 From: gregfromstl Date: Sun, 11 May 2025 13:45:46 -0700 Subject: [PATCH 4/7] fix: include full useSiweAuth return value --- .../src/react/native/ui/connect/ConnectButton.tsx | 8 ++++---- .../src/react/web/ui/ConnectWallet/ConnectButton.tsx | 2 +- .../src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx | 2 +- packages/thirdweb/src/react/web/ui/PayEmbed.tsx | 2 +- .../thirdweb/src/wallets/connection/autoConnectCore.ts | 4 ++-- packages/thirdweb/src/wallets/connection/types.ts | 5 ++++- 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx b/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx index a96ad940392..6f15969058e 100644 --- a/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx +++ b/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx @@ -49,7 +49,7 @@ export function ConnectButton(props: ConnectButtonProps) { const siweAuth = useSiweAuth(wallet, account, props.auth); useAutoConnect({ ...props, - siweLogin: siweAuth.doLogin, + siweAuth: siweAuth, }); const fadeAnim = useRef(new Animated.Value(0)); // For background opacity @@ -122,9 +122,9 @@ export function ConnectButton(props: ConnectButtonProps) { ) : ( openModal()}> {status === "connecting" || - siweAuth.isLoggingIn || - siweAuth.isLoading || - siweAuth.isLoggingOut ? ( + siweAuth.isLoggingIn || + siweAuth.isLoading || + siweAuth.isLoggingOut ? ( <> diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx index 7ae08abd615..442f67abecc 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx @@ -340,7 +340,7 @@ export function ConnectButton(props: ConnectButtonProps) { } accountAbstraction={props.accountAbstraction} onConnect={props.onConnect} - siweLogin={siweAuth.doLogin} + siweAuth={siweAuth} /> ); diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx index fb8869dd815..315d5d5db6b 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx @@ -247,7 +247,7 @@ export function ConnectEmbed(props: ConnectEmbedProps) { chain={preferredChain} appMetadata={props.appMetadata} client={props.client} - siweLogin={siweAuth.doLogin} + siweAuth={siweAuth} wallets={wallets} accountAbstraction={props.accountAbstraction} timeout={ diff --git a/packages/thirdweb/src/react/web/ui/PayEmbed.tsx b/packages/thirdweb/src/react/web/ui/PayEmbed.tsx index fe7d5430b64..0677f666359 100644 --- a/packages/thirdweb/src/react/web/ui/PayEmbed.tsx +++ b/packages/thirdweb/src/react/web/ui/PayEmbed.tsx @@ -355,7 +355,7 @@ export function PayEmbed(props: PayEmbedProps) { } else { content = ( <> - + {screen === "buy" && ( Promise; + siweAuth?: { + requiresAuth: boolean; + doLogin: () => Promise; + }; }; From a3a9e6311e1b9d2912b8e1bd009988619fdd2a2a Mon Sep 17 00:00:00 2001 From: gregfromstl Date: Sun, 11 May 2025 13:50:35 -0700 Subject: [PATCH 5/7] lint --- .../src/components/auth/auth-button.tsx | 14 ++++++++++++ .../hooks/connection/ConnectEmbedProps.ts | 5 ----- .../react/native/ui/connect/ConnectButton.tsx | 6 ++--- .../ui/ConnectWallet/Modal/ConnectEmbed.tsx | 22 +++++++++---------- .../thirdweb/src/react/web/ui/PayEmbed.tsx | 16 +++++++------- .../src/wallets/connection/autoConnectCore.ts | 12 +++++----- 6 files changed, 42 insertions(+), 33 deletions(-) diff --git a/apps/playground-web/src/components/auth/auth-button.tsx b/apps/playground-web/src/components/auth/auth-button.tsx index 5e39d170511..08de975f3c2 100644 --- a/apps/playground-web/src/components/auth/auth-button.tsx +++ b/apps/playground-web/src/components/auth/auth-button.tsx @@ -8,11 +8,25 @@ import { } from "@/app/connect/auth/server/actions/auth"; import { THIRDWEB_CLIENT } from "@/lib/client"; import { ConnectButton } from "thirdweb/react"; +import { createWallet, inAppWallet } from "thirdweb/wallets"; export function AuthButton() { return ( isLoggedIn(address), doLogin: (params) => login(params), diff --git a/packages/thirdweb/src/react/core/hooks/connection/ConnectEmbedProps.ts b/packages/thirdweb/src/react/core/hooks/connection/ConnectEmbedProps.ts index c9ba44d6853..7756b720b6f 100644 --- a/packages/thirdweb/src/react/core/hooks/connection/ConnectEmbedProps.ts +++ b/packages/thirdweb/src/react/core/hooks/connection/ConnectEmbedProps.ts @@ -289,11 +289,6 @@ export type ConnectEmbedProps = { */ auth?: SiweAuthOptions; - /** - * @hidden - */ - siweLogin?: () => Promise; - /** * Customize the welcome screen. This prop is only applicable when modalSize prop is set to "wide". On "wide" Modal size, a welcome screen is shown on the right side of the modal. * diff --git a/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx b/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx index 6f15969058e..ae053189125 100644 --- a/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx +++ b/packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx @@ -122,9 +122,9 @@ export function ConnectButton(props: ConnectButtonProps) { ) : ( openModal()}> {status === "connecting" || - siweAuth.isLoggingIn || - siweAuth.isLoading || - siweAuth.isLoggingOut ? ( + siweAuth.isLoggingIn || + siweAuth.isLoading || + siweAuth.isLoggingOut ? ( <> diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx index 315d5d5db6b..d876f3ac138 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx @@ -11,8 +11,8 @@ import { } from "../../../../core/design-system/CustomThemeProvider.js"; import { radius } from "../../../../core/design-system/index.js"; import { - useSiweAuth, type SiweAuthOptions, + useSiweAuth, } from "../../../../core/hooks/auth/useSiweAuth.js"; import type { ConnectEmbedProps } from "../../../../core/hooks/connection/ConnectEmbedProps.js"; import { useActiveAccount } from "../../../../core/hooks/wallets/useActiveAccount.js"; @@ -327,21 +327,21 @@ const ConnectEmbedContent = (props: { }; size: "compact" | "wide"; header: - | { - title?: string; - titleIcon?: string; - } - | true - | undefined; + | { + title?: string; + titleIcon?: string; + } + | true + | undefined; localeId: LocaleId; onConnect: ((wallet: Wallet) => void) | undefined; recommendedWallets: Wallet[] | undefined; showAllWallets: boolean | undefined; walletConnect: - | { - projectId?: string; - } - | undefined; + | { + projectId?: string; + } + | undefined; wallets: Wallet[]; welcomeScreen: WelcomeScreen | undefined; }) => { diff --git a/packages/thirdweb/src/react/web/ui/PayEmbed.tsx b/packages/thirdweb/src/react/web/ui/PayEmbed.tsx index 0677f666359..b123511b02c 100644 --- a/packages/thirdweb/src/react/web/ui/PayEmbed.tsx +++ b/packages/thirdweb/src/react/web/ui/PayEmbed.tsx @@ -10,15 +10,18 @@ import type { WalletId } from "../../../wallets/wallet-types.js"; import { CustomThemeProvider } from "../../core/design-system/CustomThemeProvider.js"; import type { Theme } from "../../core/design-system/index.js"; import { - useSiweAuth, type SiweAuthOptions, + useSiweAuth, } from "../../core/hooks/auth/useSiweAuth.js"; import type { ConnectButton_connectModalOptions, PayUIOptions, } from "../../core/hooks/connection/ConnectButtonProps.js"; +import { useActiveAccount } from "../../core/hooks/wallets/useActiveAccount.js"; +import { useActiveWallet } from "../../core/hooks/wallets/useActiveWallet.js"; import { useConnectionManager } from "../../core/providers/connection-manager.js"; import type { SupportedTokens } from "../../core/utils/defaultTokens.js"; +import { AutoConnect } from "../../web/ui/AutoConnect/AutoConnect.js"; import { EmbedContainer } from "./ConnectWallet/Modal/ConnectEmbed.js"; import { useConnectLocale } from "./ConnectWallet/locale/getConnectLocale.js"; import BuyScreen from "./ConnectWallet/screens/Buy/BuyScreen.js"; @@ -26,9 +29,6 @@ import { ExecutingTxScreen } from "./TransactionButton/ExecutingScreen.js"; import { DynamicHeight } from "./components/DynamicHeight.js"; import { Spinner } from "./components/Spinner.js"; import type { LocaleId } from "./types.js"; -import { useActiveAccount } from "../../core/hooks/wallets/useActiveAccount.js"; -import { useActiveWallet } from "../../core/hooks/wallets/useActiveWallet.js"; -import { AutoConnect } from "../../web/ui/AutoConnect/AutoConnect.js"; /** * Props of [`PayEmbed`](https://portal.thirdweb.com/references/typescript/v5/PayEmbed) component @@ -473,10 +473,10 @@ export type PayEmbedConnectOptions = { * ``` */ autoConnect?: - | { - timeout: number; - } - | boolean; + | { + timeout: number; + } + | boolean; /** * Metadata of the app that will be passed to connected wallet. Setting this is highly recommended. diff --git a/packages/thirdweb/src/wallets/connection/autoConnectCore.ts b/packages/thirdweb/src/wallets/connection/autoConnectCore.ts index 93a3c0d7bac..0dbac362b27 100644 --- a/packages/thirdweb/src/wallets/connection/autoConnectCore.ts +++ b/packages/thirdweb/src/wallets/connection/autoConnectCore.ts @@ -92,9 +92,9 @@ const _autoConnectCore = async ({ clientId: props.client.clientId, ecosystem: isEcosystemWallet(wallet) ? { - id: wallet.id, - partnerId: wallet.getConfig()?.partnerId, - } + id: wallet.id, + partnerId: wallet.getConfig()?.partnerId, + } : undefined, }); await clientStorage.saveAuthCookie(urlToken.authCookie); @@ -150,9 +150,9 @@ const _autoConnectCore = async ({ const connectedWallet = await (connectOverride ? connectOverride(activeWallet) : manager.connect(activeWallet, { - client: props.client, - accountAbstraction: props.accountAbstraction, - })); + client: props.client, + accountAbstraction: props.accountAbstraction, + })); if (connectedWallet) { autoConnected = true; try { From 1894888e224810107596c5d6a05e521295885a95 Mon Sep 17 00:00:00 2001 From: gregfromstl Date: Sun, 11 May 2025 14:14:27 -0700 Subject: [PATCH 6/7] fix: auto-login on autoconnect of IAW in all cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .changeset/little-cities-help.md | 5 ++++ .../src/wallets/connection/autoConnectCore.ts | 28 ++++++++++++++----- .../thirdweb/src/wallets/connection/types.ts | 2 ++ 3 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 .changeset/little-cities-help.md diff --git a/.changeset/little-cities-help.md b/.changeset/little-cities-help.md new file mode 100644 index 00000000000..0f051bc26fd --- /dev/null +++ b/.changeset/little-cities-help.md @@ -0,0 +1,5 @@ +--- +"thirdweb": patch +--- + +Auto-login on autoconnect of IAW in all cases diff --git a/packages/thirdweb/src/wallets/connection/autoConnectCore.ts b/packages/thirdweb/src/wallets/connection/autoConnectCore.ts index 0dbac362b27..58c5e7f8483 100644 --- a/packages/thirdweb/src/wallets/connection/autoConnectCore.ts +++ b/packages/thirdweb/src/wallets/connection/autoConnectCore.ts @@ -8,6 +8,7 @@ import type { AuthArgsType, AuthStoredTokenWithCookieReturnType, } from "../in-app/core/authentication/types.js"; +import { isInAppSigner } from "../in-app/core/wallet/is-in-app-signer.js"; import { getUrlToken } from "../in-app/web/lib/get-url-token.js"; import type { Wallet } from "../interfaces/wallet.js"; import { @@ -92,9 +93,9 @@ const _autoConnectCore = async ({ clientId: props.client.clientId, ecosystem: isEcosystemWallet(wallet) ? { - id: wallet.id, - partnerId: wallet.getConfig()?.partnerId, - } + id: wallet.id, + partnerId: wallet.getConfig()?.partnerId, + } : undefined, }); await clientStorage.saveAuthCookie(urlToken.authCookie); @@ -150,9 +151,9 @@ const _autoConnectCore = async ({ const connectedWallet = await (connectOverride ? connectOverride(activeWallet) : manager.connect(activeWallet, { - client: props.client, - accountAbstraction: props.accountAbstraction, - })); + client: props.client, + accountAbstraction: props.accountAbstraction, + })); if (connectedWallet) { autoConnected = true; try { @@ -192,7 +193,20 @@ const _autoConnectCore = async ({ } // Auto-login with SIWE - if (urlToken && activeWallet && props.siweAuth?.requiresAuth) { + const isIAW = + activeWallet && + isInAppSigner({ + wallet: activeWallet, + connectedWallets: activeWallet + ? [activeWallet, ...otherWallets] + : otherWallets, + }); + if ( + isIAW && + props.siweAuth?.requiresAuth && + !props.siweAuth?.isLoggedIn && + !props.siweAuth?.isLoggingIn + ) { await props.siweAuth?.doLogin(); } manager.isAutoConnecting.setValue(false); diff --git a/packages/thirdweb/src/wallets/connection/types.ts b/packages/thirdweb/src/wallets/connection/types.ts index 2af5015ad68..159600cd13c 100644 --- a/packages/thirdweb/src/wallets/connection/types.ts +++ b/packages/thirdweb/src/wallets/connection/types.ts @@ -125,5 +125,7 @@ export type AutoConnectProps = { siweAuth?: { requiresAuth: boolean; doLogin: () => Promise; + isLoggedIn: boolean | undefined; + isLoggingIn: boolean | undefined; }; }; From bab2088e4f6440202300cbce1555d7ebf24e9c14 Mon Sep 17 00:00:00 2001 From: gregfromstl Date: Sun, 11 May 2025 14:24:34 -0700 Subject: [PATCH 7/7] lint --- .../src/wallets/connection/autoConnectCore.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/thirdweb/src/wallets/connection/autoConnectCore.ts b/packages/thirdweb/src/wallets/connection/autoConnectCore.ts index 58c5e7f8483..11f68a34da1 100644 --- a/packages/thirdweb/src/wallets/connection/autoConnectCore.ts +++ b/packages/thirdweb/src/wallets/connection/autoConnectCore.ts @@ -93,9 +93,9 @@ const _autoConnectCore = async ({ clientId: props.client.clientId, ecosystem: isEcosystemWallet(wallet) ? { - id: wallet.id, - partnerId: wallet.getConfig()?.partnerId, - } + id: wallet.id, + partnerId: wallet.getConfig()?.partnerId, + } : undefined, }); await clientStorage.saveAuthCookie(urlToken.authCookie); @@ -151,9 +151,9 @@ const _autoConnectCore = async ({ const connectedWallet = await (connectOverride ? connectOverride(activeWallet) : manager.connect(activeWallet, { - client: props.client, - accountAbstraction: props.accountAbstraction, - })); + client: props.client, + accountAbstraction: props.accountAbstraction, + })); if (connectedWallet) { autoConnected = true; try {