Skip to content

Commit 6588a93

Browse files
author
jcheese1
committed
add siwe option for headless use connect for react
1 parent 64d7bf3 commit 6588a93

File tree

5 files changed

+86
-4
lines changed

5 files changed

+86
-4
lines changed

apps/playground-web/src/app/connect/sign-in/headless/page.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ export default function Page() {
3232
<Modal />
3333
<div className="h-6" />
3434
<Hooks />
35+
<div className="h-6" />
36+
<HooksWithAuth />
3537
</main>
3638
</ThirdwebProvider>
3739
);
@@ -103,3 +105,34 @@ function Hooks() {
103105
</>
104106
);
105107
}
108+
109+
function HooksWithAuth() {
110+
return (
111+
<>
112+
<h2 className="mb-2 font-semibold text-2xl tracking-tight sm:text-3xl">
113+
Create custom UI using hooks with SIWE auth
114+
</h2>
115+
116+
<p className="mb-5 max-w-[600px]">
117+
Enforce users to sign a message after connecting their wallet to
118+
authenticate themselves.
119+
</p>
120+
121+
<CodeExample
122+
preview={<ModalPreview enableAuth={true} />}
123+
code={`// Using your own UI
124+
import { useConnectModal } from "thirdweb/react";
125+
126+
function App(){
127+
const { connect } = useConnectModal();
128+
129+
return (
130+
// pass modal configuration options here
131+
<button onClick={() => connect({ client, auth: siweAuth })}>Sign in</button>
132+
);
133+
};`}
134+
lang="tsx"
135+
/>
136+
</>
137+
);
138+
}

apps/playground-web/src/components/sign-in/modal.tsx

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"use client";
22

33
import {
4+
type ConnectButtonProps,
45
useActiveAccount,
56
useActiveWallet,
67
useConnectModal,
@@ -10,14 +11,49 @@ import { shortenAddress } from "thirdweb/utils";
1011
import { THIRDWEB_CLIENT } from "../../lib/client";
1112
import { Button } from "../ui/button";
1213

13-
export function ModalPreview() {
14+
const playgroundAuth: ConnectButtonProps["auth"] = {
15+
async doLogin() {
16+
try {
17+
localStorage.setItem("playground-loggedin", "true");
18+
} catch {
19+
// ignore
20+
}
21+
},
22+
async doLogout() {
23+
localStorage.removeItem("playground-loggedin");
24+
},
25+
async getLoginPayload(params) {
26+
return {
27+
domain: "",
28+
address: params.address,
29+
statement: "",
30+
version: "",
31+
nonce: "",
32+
issued_at: "",
33+
expiration_time: "",
34+
invalid_before: "",
35+
};
36+
},
37+
async isLoggedIn() {
38+
try {
39+
return !!localStorage.getItem("playground-loggedin");
40+
} catch {
41+
return false;
42+
}
43+
},
44+
};
45+
46+
export function ModalPreview({ enableAuth }: { enableAuth?: boolean }) {
1447
const account = useActiveAccount();
1548
const wallet = useActiveWallet();
1649
const connectMutation = useConnectModal();
1750
const { disconnect } = useDisconnect();
1851

1952
const connect = async () => {
20-
const wallet = await connectMutation.connect({ client: THIRDWEB_CLIENT });
53+
const wallet = await connectMutation.connect({
54+
client: THIRDWEB_CLIENT,
55+
auth: enableAuth ? playgroundAuth : undefined,
56+
});
2157
return wallet;
2258
};
2359

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ export const ConnectModalContent = (props: {
235235
const signatureScreen = (
236236
<SignatureScreen
237237
onDone={onClose}
238+
onClose={onClose}
238239
modalSize={props.size}
239240
termsOfServiceUrl={props.meta.termsOfServiceUrl}
240241
privacyPolicyUrl={props.meta.privacyPolicyUrl}

packages/thirdweb/src/react/web/ui/ConnectWallet/screens/SignatureScreen.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type Status = "signing" | "failed" | "idle";
3232

3333
export const SignatureScreen: React.FC<{
3434
onDone: (() => void) | undefined;
35+
onClose?: (() => void) | undefined;
3536
modalSize: "compact" | "wide";
3637
termsOfServiceUrl?: string;
3738
privacyPolicyUrl?: string;
@@ -42,6 +43,7 @@ export const SignatureScreen: React.FC<{
4243
const {
4344
onDone,
4445
modalSize,
46+
onClose,
4547
termsOfServiceUrl,
4648
privacyPolicyUrl,
4749
connectLocale,
@@ -145,6 +147,7 @@ export const SignatureScreen: React.FC<{
145147
variant="secondary"
146148
data-testid="disconnect-button"
147149
onClick={() => {
150+
onClose?.();
148151
disconnect(wallet);
149152
}}
150153
style={{

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { Wallet } from "../../../../wallets/interfaces/wallet.js";
66
import type { SmartWalletOptions } from "../../../../wallets/smart/types.js";
77
import type { AppMetadata } from "../../../../wallets/types.js";
88
import type { Theme } from "../../../core/design-system/index.js";
9+
import type { SiweAuthOptions } from "../../../core/hooks/auth/useSiweAuth.js";
910
import { SetRootElementContext } from "../../../core/providers/RootElementContext.js";
1011
import { WalletUIStatesProvider } from "../../providers/wallet-ui-states-provider.js";
1112
import { canFitWideModal } from "../../utils/canFitWideModal.js";
@@ -62,6 +63,7 @@ export function useConnectModal() {
6263
<Modal
6364
{...props}
6465
onConnect={(w) => {
66+
if (props.auth) return;
6567
resolve(w);
6668
cleanup();
6769
}}
@@ -129,8 +131,7 @@ function Modal(
129131
onClose={props.onClose}
130132
shouldSetActive={props.setActive === undefined ? true : props.setActive}
131133
accountAbstraction={props.accountAbstraction}
132-
// TODO: not set up in `useConnectModal` for some reason?
133-
auth={undefined}
134+
auth={props.auth}
134135
chain={props.chain}
135136
client={props.client}
136137
connectLocale={props.connectLocale}
@@ -432,6 +433,14 @@ export type UseConnectModalOptions = {
432433
* If you want to hide the branding, set this prop to `false`
433434
*/
434435
showThirdwebBranding?: boolean;
436+
437+
/**
438+
* Enable SIWE (Sign in with Ethererum) by passing an object of type `SiweAuthOptions` to
439+
* enforce the users to sign a message after connecting their wallet to authenticate themselves.
440+
*
441+
* Refer to the [`SiweAuthOptions`](https://portal.thirdweb.com/references/typescript/v5/SiweAuthOptions) for more details
442+
*/
443+
auth?: SiweAuthOptions;
435444
};
436445

437446
// TODO: consilidate Button/Embed/Modal props into one type with extras

0 commit comments

Comments
 (0)