Skip to content

Commit ce41752

Browse files
committed
Add Login component with Google authentication support
1 parent 0cba3cb commit ce41752

File tree

11 files changed

+153
-18
lines changed

11 files changed

+153
-18
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { THIRDWEB_CLIENT } from "@/lib/client";
2+
import { getDomain } from "@/lib/constants";
3+
import { SERVER_WALLET } from "@/lib/server-wallet";
4+
5+
import { Login } from "thirdweb";
6+
7+
export const { GET, POST } = Login.Server.toNextJsHandler(
8+
Login.Server.createAuthHandler({
9+
client: THIRDWEB_CLIENT,
10+
domain: getDomain() ?? "",
11+
serverWallet: SERVER_WALLET,
12+
}),
13+
);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { CodeExample } from "@/components/code/code-example";
2+
import ThirdwebProvider from "@/components/thirdweb-provider";
3+
import { metadataBase } from "@/lib/constants";
4+
import type { Metadata } from "next";
5+
import { PageLayout } from "../../../components/blocks/APIHeader";
6+
import { BasicLoginExample } from "../../../components/login/basic-example";
7+
8+
export const metadata: Metadata = {
9+
metadataBase,
10+
title: "Login | thirdweb Connect",
11+
description: "TODO",
12+
};
13+
14+
export default function Page() {
15+
return (
16+
<ThirdwebProvider>
17+
<PageLayout
18+
title="Login"
19+
description={
20+
<>Let users login to your app using any authentication provider.</>
21+
}
22+
docsLink="https://portal.thirdweb.com/typescript/v5/auth?utm_source=playground"
23+
>
24+
<div className="flex flex-col gap-14">
25+
<CodeExample
26+
lang="ts"
27+
code={"TODO"}
28+
preview={<BasicLoginExample />}
29+
/>
30+
</div>
31+
</PageLayout>
32+
</ThirdwebProvider>
33+
);
34+
}

apps/playground-web/src/app/engine/actions.ts

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,11 @@
11
"use server";
22

3+
import { THIRDWEB_CLIENT } from "@/lib/client";
4+
import { SERVER_WALLET } from "@/lib/server-wallet";
35
import { Engine, defineChain, encode, getContract } from "thirdweb";
46
import { multicall } from "thirdweb/extensions/common";
57
import * as ERC20 from "thirdweb/extensions/erc20";
68
import * as ERC1155 from "thirdweb/extensions/erc1155";
7-
import { THIRDWEB_CLIENT } from "../../lib/client";
8-
const BACKEND_WALLET_ADDRESS = process.env.ENGINE_BACKEND_WALLET as string;
9-
const ENGINE_VAULT_ACCESS_TOKEN = process.env
10-
.ENGINE_VAULT_ACCESS_TOKEN as string;
11-
12-
const serverWallet = Engine.serverWallet({
13-
address: BACKEND_WALLET_ADDRESS,
14-
client: THIRDWEB_CLIENT,
15-
vaultAccessToken: ENGINE_VAULT_ACCESS_TOKEN,
16-
});
179

1810
export async function airdrop_tokens_with_engine(params: {
1911
contractAddress: string;
@@ -44,7 +36,7 @@ export async function airdrop_tokens_with_engine(params: {
4436
data,
4537
});
4638

47-
const res = await serverWallet.enqueueTransaction({ transaction: tx });
39+
const res = await SERVER_WALLET.enqueueTransaction({ transaction: tx });
4840

4941
return res.transactionId;
5042
}
@@ -82,7 +74,7 @@ export async function mint_erc1155_nft_with_engine(params: MintNFTParams) {
8274
to: params.toAddress,
8375
supply: BigInt(params.metadataWithSupply.supply),
8476
});
85-
const res = await serverWallet.enqueueTransaction({ transaction: tx });
77+
const res = await SERVER_WALLET.enqueueTransaction({ transaction: tx });
8678

8779
return res.transactionId;
8880
}
@@ -106,7 +98,7 @@ export async function claim_erc1155_nft_with_engine(params: ClaimNFTParams) {
10698
tokenId: BigInt(params.tokenId),
10799
quantity: BigInt(params.quantity),
108100
});
109-
const res = await serverWallet.enqueueTransaction({ transaction: tx });
101+
const res = await SERVER_WALLET.enqueueTransaction({ transaction: tx });
110102

111103
return res.transactionId;
112104
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
"use client";
2+
3+
import { THIRDWEB_CLIENT } from "@/lib/client";
4+
import { useRef, useState } from "react";
5+
import { Login } from "thirdweb";
6+
import { sepolia } from "thirdweb/chains";
7+
import { Button } from "../ui/button";
8+
import { Input } from "../ui/input";
9+
10+
export function BasicLoginExample() {
11+
const [account, setAccount] = useState<Login.Client.LoginResult>();
12+
const otpRef = useRef<HTMLInputElement>(null);
13+
14+
if (!account) {
15+
return (
16+
<div className="flex flex-col gap-4">
17+
<Button
18+
onClick={async () => {
19+
const account = await Login.Client.login({
20+
type: "google",
21+
client: THIRDWEB_CLIENT,
22+
baseURL: `${window.location.origin}/connect/login/api/auth`,
23+
chain: sepolia,
24+
});
25+
setAccount(account);
26+
}}
27+
>
28+
Login with Google
29+
</Button>
30+
</div>
31+
);
32+
}
33+
34+
if (account.status === "requires_otp") {
35+
return (
36+
<div className="flex flex-col gap-4">
37+
<Input ref={otpRef} placeholder="OTP" />
38+
<Button
39+
onClick={async () => {
40+
if (!otpRef.current?.value) {
41+
return;
42+
}
43+
setAccount(await account.verifyOtp(otpRef.current?.value));
44+
}}
45+
>
46+
Verify OTP
47+
</Button>
48+
</div>
49+
);
50+
}
51+
52+
return (
53+
<div className="flex flex-col gap-4">
54+
<p>Logged in as: {account.id}</p>
55+
<Button
56+
onClick={async () => {
57+
const jwt = await account.getJWT();
58+
alert(`JWT: ${jwt}`);
59+
}}
60+
>
61+
Get JWT
62+
</Button>
63+
<Button
64+
onClick={async () => {
65+
await account.logout();
66+
setAccount(undefined);
67+
}}
68+
>
69+
Logout
70+
</Button>
71+
</div>
72+
);
73+
}

apps/playground-web/src/lib/client.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ setThirdwebDomains({
1111
analytics: process.env.NEXT_PUBLIC_ANALYTICS_URL,
1212
insight: process.env.NEXT_PUBLIC_INSIGHT_URL,
1313
bridge: process.env.NEXT_PUBLIC_BRIDGE_URL,
14+
engineCloud: process.env.NEXT_PUBLIC_ENGINE_CLOUD_URL,
1415
});
1516

1617
const isDev =

apps/playground-web/src/lib/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export const metadataBase = process.env.VERCEL_ENV
44
? new URL("https://playground.thirdweb.com")
55
: undefined;
66

7-
const getDomain = () => {
7+
export const getDomain = () => {
88
if (process.env.VERCEL_ENV === "production") {
99
return "thirdweb.com";
1010
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import "server-only";
2+
import { Engine } from "thirdweb";
3+
import { sepolia } from "thirdweb/chains";
4+
import { THIRDWEB_CLIENT } from "./client";
5+
6+
const BACKEND_WALLET_ADDRESS = process.env.ENGINE_BACKEND_WALLET as string;
7+
const ENGINE_VAULT_ACCESS_TOKEN = process.env
8+
.ENGINE_VAULT_ACCESS_TOKEN as string;
9+
10+
export const SERVER_WALLET = Engine.serverWallet({
11+
address: BACKEND_WALLET_ADDRESS,
12+
client: THIRDWEB_CLIENT,
13+
vaultAccessToken: ENGINE_VAULT_ACCESS_TOKEN,
14+
chain: sepolia,
15+
});

packages/thirdweb/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@
297297
"knip": "knip",
298298
"build:generate": "bun scripts/generate/generate.ts",
299299
"build:generate-wallets": "bun scripts/wallets/generate.ts",
300-
"dev": "tsc --project ./tsconfig.build.json --module es2020 --outDir ./dist/esm --watch",
300+
"dev": "tsc --project ./tsconfig.build.json --module nodenext --moduleResolution nodenext --outDir ./dist/esm --watch",
301301
"dev:cjs": "printf '{\"type\":\"commonjs\"}' > ./dist/cjs/package.json && tsc --noCheck --project ./tsconfig.build.json --module commonjs --outDir ./dist/cjs --verbatimModuleSyntax false --watch",
302302
"dev:esm": "printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/esm/package.json && tsc --noCheck --project ./tsconfig.build.json --module es2020 --outDir ./dist/esm --watch",
303303
"build": "pnpm clean && pnpm build:types && pnpm build:cjs && pnpm build:esm",
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export { login, type LoginOptions as LoginParams } from "./login.js";
1+
export { login, type LoginOptions, type LoginResult } from "./login.js";

packages/thirdweb/src/login/client/login.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export type LoginOptions = (
3131
}
3232
) & {
3333
client: ThirdwebClient;
34+
chain: Chain;
3435
options?: {
3536
sponsorGas?: boolean;
3637
redirectUrl?: string;
@@ -40,10 +41,12 @@ export type LoginOptions = (
4041
baseURL?: string;
4142
};
4243

44+
export type LoginResult = Awaited<ReturnType<typeof login>>;
45+
4346
export async function login(loginOptions: LoginOptions) {
4447
const IAW = inAppWallet({
4548
auth: {
46-
mode: "redirect",
49+
mode: "popup",
4750
options: [],
4851
redirectUrl: loginOptions.options?.redirectUrl,
4952
passkeyDomain: loginOptions.options?.passkeyDomain,
@@ -62,6 +65,7 @@ export async function login(loginOptions: LoginOptions) {
6265
client: loginOptions.client,
6366
strategy: "jwt",
6467
jwt: loginOptions.jwt,
68+
chain: loginOptions.chain,
6569
});
6670

6771
return mapAccount(account, IAW, loginOptions.baseURL);
@@ -87,6 +91,7 @@ export async function login(loginOptions: LoginOptions) {
8791
phoneNumber: loginOptions.phoneNumber,
8892
verificationCode,
8993
client: loginOptions.client,
94+
chain: loginOptions.chain,
9095
});
9196

9297
return mapAccount(account, IAW, loginOptions.baseURL);
@@ -115,6 +120,7 @@ export async function login(loginOptions: LoginOptions) {
115120
email: loginOptions.email,
116121
verificationCode,
117122
client: loginOptions.client,
123+
chain: loginOptions.chain,
118124
});
119125

120126
return mapAccount(account, IAW, loginOptions.baseURL);
@@ -141,6 +147,7 @@ export async function login(loginOptions: LoginOptions) {
141147
const account = await IAW.connect({
142148
client: loginOptions.client,
143149
strategy: loginOptions.type,
150+
chain: loginOptions.chain,
144151
});
145152

146153
return mapAccount(account, IAW, loginOptions.baseURL);

packages/thirdweb/src/login/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export * as Client from "./client/index.js";
22
export * as Server from "./server/index.js";
33

44
// client
5-
export { login, type LoginOptions as LoginParams } from "./client/login.js";
5+
export { login, type LoginOptions, type LoginResult } from "./client/login.js";
66

77
// server
88
export {

0 commit comments

Comments
 (0)