Skip to content

Commit 8994dba

Browse files
committed
wip: only auto login SIWE when using a url to login
1 parent c2acfd1 commit 8994dba

File tree

18 files changed

+170
-143
lines changed

18 files changed

+170
-143
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { getCachedChain } from "../../chains/utils.js";
2+
import type { Account, Wallet } from "../../wallets/interfaces/wallet.js";
3+
import type { SiweAuthOptions } from "./types.js";
4+
5+
export async function signAndLogin(params: {
6+
activeWallet: Wallet;
7+
activeAccount: Account;
8+
authOptions: SiweAuthOptions;
9+
}) {
10+
const { activeWallet, activeAccount, authOptions } = params;
11+
12+
const chain = activeWallet.getChain();
13+
if (!chain) {
14+
throw new Error("No active chain");
15+
}
16+
17+
const [payload, { signLoginPayload }] = await Promise.all([
18+
authOptions.getLoginPayload({
19+
address: activeAccount.address,
20+
chainId: chain.id,
21+
}),
22+
// we lazy-load this because it's only needed when logging in
23+
import("./sign-login-payload.js"),
24+
]);
25+
26+
if (payload.chain_id) {
27+
await activeWallet.switchChain(getCachedChain(Number(payload.chain_id)));
28+
}
29+
30+
const signedPayload = await signLoginPayload({
31+
payload,
32+
account: activeAccount,
33+
});
34+
35+
return await authOptions.doLogin(signedPayload);
36+
}

packages/thirdweb/src/auth/core/types.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import type { ThirdwebClient } from "../../client/client.js";
22
import type { Account } from "../../wallets/interfaces/wallet.js";
3+
import type { VerifyLoginPayloadParams } from "./verify-login-payload.js";
34

45
/**
6+
* Options for creating an Auth instance
57
* @auth
68
*/
79
export type AuthOptions = {
@@ -44,3 +46,43 @@ export type LoginPayload = {
4446
invalid_before: string;
4547
resources?: string[];
4648
};
49+
50+
/**
51+
* Options for Setting up SIWE (Sign in with Ethereum) Authentication
52+
* @auth
53+
*/
54+
export type SiweAuthOptions = {
55+
// we pass address and chainId and retrieve a login payload (we do not care how)
56+
57+
/**
58+
* Method to get the login payload for given address and chainId
59+
* @param params - The parameters to get the login payload for.
60+
*/
61+
getLoginPayload: (params: {
62+
address: string;
63+
chainId: number;
64+
}) => Promise<LoginPayload>;
65+
66+
// we pass the login payload and signature and the developer passes this to the auth server however they want
67+
68+
/**
69+
* Method to login with the signed login payload
70+
* @param params
71+
*/
72+
doLogin: (params: VerifyLoginPayloadParams) => Promise<void>;
73+
74+
// we call this internally when a user explicitly disconnects their wallet
75+
76+
/**
77+
* Method to logout the user
78+
*/
79+
doLogout: () => Promise<void>;
80+
81+
// the developer specifies how to check if the user is logged in, this is called internally by the component
82+
83+
/**
84+
* Method to check if the user is logged in or not
85+
* @param address
86+
*/
87+
isLoggedIn: (address: string) => Promise<boolean>;
88+
};

packages/thirdweb/src/exports/auth.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ export type {
2121
VerifyLoginPayloadResult,
2222
} from "../auth/core/verify-login-payload.js";
2323
export type { GenerateLoginPayloadParams } from "../auth/core/generate-login-payload.js";
24-
export type { AuthOptions, LoginPayload } from "../auth/core/types.js";
24+
export type {
25+
AuthOptions,
26+
LoginPayload,
27+
SiweAuthOptions,
28+
} from "../auth/core/types.js";
2529

2630
// meant to be used on the "client" side to sign the login payload with a given account
2731
export {

packages/thirdweb/src/exports/react.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ export {
123123
export { AutoConnect } from "../react/web/ui/AutoConnect/AutoConnect.js";
124124
export type { AutoConnectProps } from "../wallets/connection/types.js";
125125

126-
// auth
127-
export type { SiweAuthOptions } from "../react/core/hooks/auth/useSiweAuth.js";
126+
// auth - its in core but must export from here to avoid breaking changes
127+
export type { SiweAuthOptions } from "../auth/core/types.js";
128128

129129
export {
130130
PayEmbed,

packages/thirdweb/src/react/core/hooks/auth/useSiweAuth.ts

Lines changed: 6 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,8 @@
11
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
2-
import type { LoginPayload } from "../../../../auth/core/types.js";
3-
import type { VerifyLoginPayloadParams } from "../../../../auth/core/verify-login-payload.js";
4-
import { getCachedChain } from "../../../../chains/utils.js";
2+
import { signAndLogin } from "../../../../auth/core/sign-and-login.js";
3+
import type { SiweAuthOptions } from "../../../../auth/core/types.js";
54
import type { Account, Wallet } from "../../../../wallets/interfaces/wallet.js";
65

7-
/**
8-
* Options for Setting up SIWE (Sign in with Ethereum) Authentication
9-
* @auth
10-
*/
11-
export type SiweAuthOptions = {
12-
// we pass address and chainId and retrieve a login payload (we do not care how)
13-
14-
/**
15-
* Method to get the login payload for given address and chainId
16-
* @param params - The parameters to get the login payload for.
17-
*/
18-
getLoginPayload: (params: {
19-
address: string;
20-
chainId: number;
21-
}) => Promise<LoginPayload>;
22-
23-
// we pass the login payload and signature and the developer passes this to the auth server however they want
24-
25-
/**
26-
* Method to login with the signed login payload
27-
* @param params
28-
*/
29-
doLogin: (params: VerifyLoginPayloadParams) => Promise<void>;
30-
31-
// we call this internally when a user explicitly disconnects their wallet
32-
33-
/**
34-
* Method to logout the user
35-
*/
36-
doLogout: () => Promise<void>;
37-
38-
// the developer specifies how to check if the user is logged in, this is called internally by the component
39-
40-
/**
41-
* Method to check if the user is logged in or not
42-
* @param address
43-
*/
44-
isLoggedIn: (address: string) => Promise<boolean>;
45-
};
46-
476
/**
487
* @internal
498
*/
@@ -81,34 +40,15 @@ export function useSiweAuth(
8140
if (!activeWallet) {
8241
throw new Error("No active wallet");
8342
}
84-
const chain = activeWallet.getChain();
85-
if (!chain) {
86-
throw new Error("No active chain");
87-
}
8843
if (!activeAccount) {
8944
throw new Error("No active account");
9045
}
91-
const [payload, { signLoginPayload }] = await Promise.all([
92-
authOptions.getLoginPayload({
93-
address: activeAccount.address,
94-
chainId: chain.id,
95-
}),
96-
// we lazy-load this because it's only needed when logging in
97-
import("../../../../auth/core/sign-login-payload.js"),
98-
]);
9946

100-
if (payload.chain_id) {
101-
await activeWallet.switchChain(
102-
getCachedChain(Number(payload.chain_id)),
103-
);
104-
}
105-
106-
const signedPayload = await signLoginPayload({
107-
payload,
108-
account: activeAccount,
47+
await signAndLogin({
48+
activeWallet,
49+
activeAccount,
50+
authOptions,
10951
});
110-
111-
return await authOptions.doLogin(signedPayload);
11252
},
11353
onSuccess: () => {
11454
return queryClient.invalidateQueries({

packages/thirdweb/src/react/core/hooks/connection/ConnectButtonProps.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { JSX } from "react";
2+
import type { SiweAuthOptions } from "../../../../auth/core/types.js";
23
import type { Chain } from "../../../../chains/types.js";
34
import type { ThirdwebClient } from "../../../../client/client.js";
45
import type { BuyWithCryptoStatus } from "../../../../pay/buyWithCrypto/getStatus.js";
@@ -23,7 +24,6 @@ import type {
2324
SupportedTokens,
2425
TokenInfo,
2526
} from "../../utils/defaultTokens.js";
26-
import type { SiweAuthOptions } from "../auth/useSiweAuth.js";
2727

2828
export type PaymentInfo = {
2929
/**

packages/thirdweb/src/react/core/hooks/connection/ConnectEmbedProps.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { SiweAuthOptions } from "../../../../auth/core/types.js";
12
import type { Chain } from "../../../../chains/types.js";
23
import type { ThirdwebClient } from "../../../../client/client.js";
34
import type { Wallet } from "../../../../wallets/interfaces/wallet.js";
@@ -6,7 +7,6 @@ import type { AppMetadata } from "../../../../wallets/types.js";
67
import type { WelcomeScreen } from "../../../web/ui/ConnectWallet/screens/types.js";
78
import type { LocaleId } from "../../../web/ui/types.js";
89
import type { Theme } from "../../design-system/index.js";
9-
import type { SiweAuthOptions } from "../auth/useSiweAuth.js";
1010

1111
export type ConnectEmbedProps = {
1212
/**

packages/thirdweb/src/react/native/ui/connect/ConnectButton.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ export function ConnectButton(props: ConnectButtonProps) {
4747
const status = useActiveWalletConnectionStatus();
4848
const connectionManager = useConnectionManager();
4949
const siweAuth = useSiweAuth(wallet, account, props.auth);
50-
useAutoConnect(props);
50+
useAutoConnect({
51+
...props,
52+
siweLogin: siweAuth.doLogin,
53+
});
5154

5255
const fadeAnim = useRef(new Animated.Value(0)); // For background opacity
5356
const slideAnim = useRef(new Animated.Value(screenHeight)); // For bottom sheet position

packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import { LockIcon } from "./icons/LockIcon.js";
3030
import { useConnectLocale } from "./locale/getConnectLocale.js";
3131
import type { ConnectLocale } from "./locale/types.js";
3232
import { SignatureScreen } from "./screens/SignatureScreen.js";
33-
import { useAdminWallet } from "src/exports/react.native.js";
3433

3534
const TW_CONNECT_WALLET = "tw-connect-wallet";
3635

@@ -298,6 +297,9 @@ export function ConnectButton(props: ConnectButtonProps) {
298297
);
299298
const localeQuery = useConnectLocale(props.locale || "en_US");
300299
const connectionManager = useConnectionManager();
300+
const activeAccount = useActiveAccount();
301+
const activeWallet = useActiveWallet();
302+
const siweAuth = useSiweAuth(activeWallet, activeAccount, props.auth);
301303

302304
usePreloadWalletProviders({
303305
wallets,
@@ -331,13 +333,15 @@ export function ConnectButton(props: ConnectButtonProps) {
331333
appMetadata={props.appMetadata}
332334
client={props.client}
333335
wallets={wallets}
336+
auth={props.auth}
334337
timeout={
335338
typeof props.autoConnect === "boolean"
336339
? undefined
337340
: props.autoConnect?.timeout
338341
}
339342
accountAbstraction={props.accountAbstraction}
340343
onConnect={props.onConnect}
344+
siweLogin={siweAuth.doLogin}
341345
/>
342346
);
343347

@@ -363,7 +367,11 @@ export function ConnectButton(props: ConnectButtonProps) {
363367

364368
return (
365369
<WalletUIStatesProvider theme={props.theme} isOpen={false}>
366-
<ConnectButtonInner {...props} connectLocale={localeQuery.data} />
370+
<ConnectButtonInner
371+
{...props}
372+
siweAuth={siweAuth}
373+
connectLocale={localeQuery.data}
374+
/>
367375
<ConnectModal
368376
shouldSetActive={true}
369377
accountAbstraction={props.accountAbstraction}
@@ -397,12 +405,11 @@ export function ConnectButton(props: ConnectButtonProps) {
397405
function ConnectButtonInner(
398406
props: ConnectButtonProps & {
399407
connectLocale: ConnectLocale;
408+
siweAuth: ReturnType<typeof useSiweAuth>;
400409
},
401410
) {
402-
const activeWallet = useActiveWallet();
411+
const siweAuth = props.siweAuth;
403412
const activeAccount = useActiveAccount();
404-
const adminWallet = useAdminWallet();
405-
const siweAuth = useSiweAuth(activeWallet, activeAccount, props.auth);
406413
const [showSignatureModal, setShowSignatureModal] = useState(false);
407414

408415
// if wallet gets disconnected suddently, close the signature modal if it's open
@@ -412,28 +419,6 @@ function ConnectButtonInner(
412419
}
413420
}, [activeAccount]);
414421

415-
// if an IAW wallet is connected and auth is required, trigger a login attempt automatically
416-
useEffect(() => {
417-
const isIAW = activeWallet?.id === "inApp" || adminWallet?.id === "inApp";
418-
if (
419-
activeAccount &&
420-
siweAuth.requiresAuth &&
421-
!siweAuth.isLoggedIn &&
422-
!siweAuth.isLoggingIn &&
423-
isIAW
424-
) {
425-
siweAuth.doLogin();
426-
}
427-
}, [
428-
activeAccount,
429-
siweAuth.requiresAuth,
430-
siweAuth.doLogin,
431-
siweAuth.isLoggedIn,
432-
siweAuth.isLoggingIn,
433-
activeWallet,
434-
adminWallet,
435-
]);
436-
437422
const theme = props.theme || "dark";
438423
const connectionStatus = useActiveWalletConnectionStatus();
439424
const locale = props.connectLocale;

packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"use client";
22
import { useEffect, useMemo } from "react";
3+
import type { SiweAuthOptions } from "../../../../../auth/core/types.js";
34
import type { Chain } from "../../../../../chains/types.js";
45
import type { ThirdwebClient } from "../../../../../client/client.js";
56
import { getDefaultWallets } from "../../../../../wallets/defaultWallets.js";
@@ -10,10 +11,7 @@ import {
1011
useCustomTheme,
1112
} from "../../../../core/design-system/CustomThemeProvider.js";
1213
import { radius } from "../../../../core/design-system/index.js";
13-
import {
14-
type SiweAuthOptions,
15-
useSiweAuth,
16-
} from "../../../../core/hooks/auth/useSiweAuth.js";
14+
import { useSiweAuth } from "../../../../core/hooks/auth/useSiweAuth.js";
1715
import type { ConnectEmbedProps } from "../../../../core/hooks/connection/ConnectEmbedProps.js";
1816
import { useActiveAccount } from "../../../../core/hooks/wallets/useActiveAccount.js";
1917
import { useActiveWallet } from "../../../../core/hooks/wallets/useActiveWallet.js";
@@ -247,6 +245,7 @@ export function ConnectEmbed(props: ConnectEmbedProps) {
247245
chain={preferredChain}
248246
appMetadata={props.appMetadata}
249247
client={props.client}
248+
auth={props.auth}
250249
wallets={wallets}
251250
accountAbstraction={props.accountAbstraction}
252251
timeout={

packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
"use client";
22
import { useCallback, useEffect, useState } from "react";
3+
import type { SiweAuthOptions } from "../../../../../auth/core/types.js";
34
import type { Chain } from "../../../../../chains/types.js";
45
import type { ThirdwebClient } from "../../../../../client/client.js";
56
import type { Wallet } from "../../../../../wallets/interfaces/wallet.js";
67
import type { SmartWalletOptions } from "../../../../../wallets/smart/types.js";
7-
import type { SiweAuthOptions } from "../../../../core/hooks/auth/useSiweAuth.js";
88
import { useActiveAccount } from "../../../../core/hooks/wallets/useActiveAccount.js";
99
import {
1010
useIsWalletModalOpen,

packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectModalContent.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
"use client";
22
import { Suspense, lazy, useCallback } from "react";
3+
import type { SiweAuthOptions } from "../../../../../auth/core/types.js";
34
import type { Chain } from "../../../../../chains/types.js";
45
import type { ThirdwebClient } from "../../../../../client/client.js";
56
import type { Wallet } from "../../../../../wallets/interfaces/wallet.js";
67
import type { SmartWalletOptions } from "../../../../../wallets/smart/types.js";
78
import type { WalletId } from "../../../../../wallets/wallet-types.js";
8-
import {
9-
type SiweAuthOptions,
10-
useSiweAuth,
11-
} from "../../../../core/hooks/auth/useSiweAuth.js";
9+
import { useSiweAuth } from "../../../../core/hooks/auth/useSiweAuth.js";
1210
import { useActiveAccount } from "../../../../core/hooks/wallets/useActiveAccount.js";
1311
import { useActiveWallet } from "../../../../core/hooks/wallets/useActiveWallet.js";
1412
import { useSetActiveWallet } from "../../../../core/hooks/wallets/useSetActiveWallet.js";

0 commit comments

Comments
 (0)