Skip to content

Commit 00edc15

Browse files
committed
Add login functionality with multiple authentication methods
1 parent 30fafd1 commit 00edc15

File tree

13 files changed

+967
-568
lines changed

13 files changed

+967
-568
lines changed

packages/thirdweb/package.json

Lines changed: 31 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@
6060
"import": "./dist/esm/exports/extensions/*.js",
6161
"default": "./dist/cjs/exports/extensions/*.js"
6262
},
63+
"./login": {
64+
"types": "./dist/types/exports/login.d.ts",
65+
"import": "./dist/esm/exports/login.js",
66+
"default": "./dist/cjs/exports/login.js"
67+
},
6368
"./pay": {
6469
"types": "./dist/types/exports/pay.d.ts",
6570
"import": "./dist/esm/exports/pay.js",
@@ -147,66 +152,27 @@
147152
},
148153
"typesVersions": {
149154
"*": {
150-
"adapters/*": [
151-
"./dist/types/exports/adapters/*.d.ts"
152-
],
153-
"auth": [
154-
"./dist/types/exports/auth.d.ts"
155-
],
156-
"chains": [
157-
"./dist/types/exports/chains.d.ts"
158-
],
159-
"contract": [
160-
"./dist/types/exports/contract.d.ts"
161-
],
162-
"deploys": [
163-
"./dist/types/exports/deploys.d.ts"
164-
],
165-
"event": [
166-
"./dist/types/exports/event.d.ts"
167-
],
168-
"extensions/*": [
169-
"./dist/types/exports/extensions/*.d.ts"
170-
],
171-
"pay": [
172-
"./dist/types/exports/pay.d.ts"
173-
],
174-
"react": [
175-
"./dist/types/exports/react.d.ts"
176-
],
177-
"react-native": [
178-
"./dist/types/exports/react.native.d.ts"
179-
],
180-
"rpc": [
181-
"./dist/types/exports/rpc.d.ts"
182-
],
183-
"storage": [
184-
"./dist/types/exports/storage.d.ts"
185-
],
186-
"transaction": [
187-
"./dist/types/exports/transaction.d.ts"
188-
],
189-
"utils": [
190-
"./dist/types/exports/utils.d.ts"
191-
],
192-
"wallets": [
193-
"./dist/types/exports/wallets.d.ts"
194-
],
195-
"wallets/*": [
196-
"./dist/types/exports/wallets/*.d.ts"
197-
],
198-
"modules": [
199-
"./dist/types/exports/modules.d.ts"
200-
],
201-
"social": [
202-
"./dist/types/exports/social.d.ts"
203-
],
204-
"ai": [
205-
"./dist/types/exports/ai.d.ts"
206-
],
207-
"bridge": [
208-
"./dist/types/exports/bridge.d.ts"
209-
]
155+
"adapters/*": ["./dist/types/exports/adapters/*.d.ts"],
156+
"auth": ["./dist/types/exports/auth.d.ts"],
157+
"chains": ["./dist/types/exports/chains.d.ts"],
158+
"contract": ["./dist/types/exports/contract.d.ts"],
159+
"deploys": ["./dist/types/exports/deploys.d.ts"],
160+
"event": ["./dist/types/exports/event.d.ts"],
161+
"extensions/*": ["./dist/types/exports/extensions/*.d.ts"],
162+
"login": ["./dist/types/exports/login.d.ts"],
163+
"pay": ["./dist/types/exports/pay.d.ts"],
164+
"react": ["./dist/types/exports/react.d.ts"],
165+
"react-native": ["./dist/types/exports/react.native.d.ts"],
166+
"rpc": ["./dist/types/exports/rpc.d.ts"],
167+
"storage": ["./dist/types/exports/storage.d.ts"],
168+
"transaction": ["./dist/types/exports/transaction.d.ts"],
169+
"utils": ["./dist/types/exports/utils.d.ts"],
170+
"wallets": ["./dist/types/exports/wallets.d.ts"],
171+
"wallets/*": ["./dist/types/exports/wallets/*.d.ts"],
172+
"modules": ["./dist/types/exports/modules.d.ts"],
173+
"social": ["./dist/types/exports/social.d.ts"],
174+
"ai": ["./dist/types/exports/ai.d.ts"],
175+
"bridge": ["./dist/types/exports/bridge.d.ts"]
210176
}
211177
},
212178
"browser": {
@@ -241,6 +207,7 @@
241207
"@walletconnect/ethereum-provider": "2.20.1",
242208
"@walletconnect/sign-client": "2.20.1",
243209
"abitype": "1.0.8",
210+
"better-call": "1.0.9",
244211
"cross-spawn": "7.0.6",
245212
"fuse.js": "7.1.0",
246213
"input-otp": "^1.4.1",
@@ -251,7 +218,8 @@
251218
"prompts": "2.4.2",
252219
"toml": "3.0.0",
253220
"uqr": "0.1.2",
254-
"viem": "2.28.1"
221+
"viem": "2.28.1",
222+
"zod": "3.24.3"
255223
},
256224
"peerDependencies": {
257225
"@aws-sdk/client-lambda": "^3",
@@ -324,7 +292,7 @@
324292
"bench:compare": "bun run ./benchmarks/run.ts",
325293
"bench": "vitest -c ./test/vitest.config.ts bench",
326294
"format": "biome format ./src --write",
327-
"lint": "knip && biome check ./src && tsc --project ./tsconfig.build.json --module esnext --noEmit",
295+
"lint": "knip && biome check ./src && tsc --project ./tsconfig.build.json --module nodenext --moduleResolution nodenext --noEmit",
328296
"fix": "biome check ./src --fix",
329297
"knip": "knip",
330298
"build:generate": "bun scripts/generate/generate.ts",
@@ -335,7 +303,7 @@
335303
"build": "pnpm clean && pnpm build:types && pnpm build:cjs && pnpm build:esm",
336304
"build:cjs": "tsc --noCheck --project ./tsconfig.build.json --module commonjs --outDir ./dist/cjs --verbatimModuleSyntax false && printf '{\"type\":\"commonjs\"}' > ./dist/cjs/package.json",
337305
"build:esm": "tsc --noCheck --project ./tsconfig.build.json --module es2020 --outDir ./dist/esm && printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/esm/package.json",
338-
"build:types": "tsc --project ./tsconfig.build.json --module esnext --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap",
306+
"build:types": "tsc --project ./tsconfig.build.json --module nodenext --moduleResolution nodenext --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap",
339307
"clean": "rimraf dist",
340308
"size": "size-limit",
341309
"test:watch": "vitest -c ./test/vitest.config.ts dev",
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "../login/index.js";

packages/thirdweb/src/exports/thirdweb.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ export * as Insight from "../insight/index.js";
8686
*/
8787
export * as Engine from "../engine/index.js";
8888

89+
/**
90+
* LOGIN
91+
*/
92+
export * as Login from "../login/index.js";
93+
8994
/**
9095
* WALLETS
9196
*/

packages/thirdweb/src/login/README.md

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
## Installation
2+
3+
```bash
4+
npm install thirdweb
5+
```
6+
7+
## Usage
8+
9+
```typescript
10+
// Import everything
11+
import { Login } from "thirdweb";
12+
13+
// Or import specific parts
14+
import { login, createAuthHandler } from "thirdweb";
15+
```
16+
17+
## Client-Side Authentication
18+
19+
The client-side authentication system provides methods for handling user authentication in the browser.
20+
21+
### Basic Usage
22+
23+
```typescript
24+
import { Login } from "thirdweb/login";
25+
26+
// Email login
27+
const result = await Login.Client.login({
28+
type: "email",
29+
email: "user@example.com",
30+
client: thirdwebClient,
31+
});
32+
33+
// Handle OTP verification
34+
if (result.status === "requires_otp") {
35+
const account = await result.verifyOtp("123456");
36+
}
37+
38+
// Phone login
39+
const result = await Login.Client.login({
40+
type: "phone",
41+
phoneNumber: "+1234567890",
42+
client: thirdwebClient,
43+
});
44+
45+
// Wallet login
46+
const result = await Login.Client.login({
47+
type: "wallet",
48+
wallet: userWallet,
49+
chain: selectedChain,
50+
client: thirdwebClient,
51+
});
52+
53+
// JWT login
54+
const result = await Login.Client.login({
55+
type: "jwt",
56+
jwt: "your-jwt-token",
57+
client: thirdwebClient,
58+
});
59+
```
60+
61+
### Authentication Options
62+
63+
```typescript
64+
type LoginOptions = {
65+
client: ThirdwebClient;
66+
options?: {
67+
sponsorGas?: boolean; // Enable gas sponsorship
68+
redirectUrl?: string; // Custom redirect URL
69+
passkeyDomain?: string; // Domain for passkey authentication
70+
storage?: AsyncStorage; // Custom storage implementation
71+
};
72+
baseURL?: string; // Base URL for your authentication server
73+
};
74+
```
75+
76+
### Authenticated Account Features
77+
78+
Once authenticated, you get access to the following features:
79+
80+
```typescript
81+
const account = await Login.Client.login({...});
82+
83+
// Get JWT token
84+
const jwt = await account.getJWT();
85+
86+
// Send a transaction
87+
await account.sendTransaction(transaction);
88+
89+
// Send batch transactions
90+
await account.sendBatchTransaction([transaction1, transaction2]);
91+
92+
// Sign messages
93+
await account.signMessage(message);
94+
95+
// Sign typed data
96+
await account.signTypedData(typedData);
97+
98+
// Logout
99+
await account.logout();
100+
```
101+
102+
## Server-Side Authentication
103+
104+
The server-side authentication system provides utilities for handling authentication on the server.
105+
106+
### Basic Setup
107+
108+
```typescript
109+
import { Login } from "thirdweb/login";
110+
111+
// Initialize the server-side authentication handler
112+
const authHandler = Login.Server.createAuthHandler({
113+
// Your configuration options
114+
});
115+
```
116+
117+
### Framework Integrations
118+
119+
The package provides built-in integrations for popular frameworks:
120+
121+
```typescript
122+
import { Login } from "thirdweb/login";
123+
124+
// Express.js integration
125+
app.all("/api/auth/*", Login.Server.toNodeHandler(authHandler));
126+
127+
// Next.js integration
128+
// /app/api/auth/[...all]/route.ts
129+
export const { GET, POST } = Login.Server.toNextJsHandler(authHandler);
130+
131+
132+
// Hono integration
133+
import { Hono } from "hono";
134+
import { serve } from "@hono/node-server"
135+
136+
const app = new Hono();
137+
138+
app.on(["GET", "POST"], "/api/auth/**", (c) => authHandler.handler(c.req.raw));
139+
140+
serve(app);
141+
```
142+
143+
### Required Endpoints
144+
145+
The server implements the following endpoints:
146+
147+
1. `/api/auth/payload` - Generate authentication payload
148+
2. `/api/auth/login` - Handle login requests
149+
3. `/api/auth/logout` - Handle logout requests
150+
4. `/api/auth/is-logged-in` - Verify authentication status
151+
152+
(You can change the base path (`/api/auth`) by passing the `basePath` option to the `createAuthHandler` function.)
153+
154+
### Server-Side Features
155+
156+
- JWT validation and generation
157+
- Session management
158+
- Authentication state verification
159+
- Secure token storage
160+
- Rate limiting support
161+
- Framework integrations
162+
163+
## Security Considerations
164+
165+
- JWT tokens are automatically refreshed when expired
166+
- Sensitive operations require proper authentication
167+
- Session management is handled securely
168+
- Gas sponsorship can be enabled for better UX
169+
170+
## Best Practices
171+
172+
1. Always use HTTPS for authentication endpoints
173+
2. Implement proper error handling
174+
3. Use secure storage for sensitive data
175+
4. Implement rate limiting for authentication attempts
176+
5. Keep JWT tokens secure and handle them properly
177+
178+
## Error Handling
179+
180+
The login system provides detailed error messages for various scenarios:
181+
- Invalid credentials
182+
- Expired tokens
183+
- Network issues
184+
- Invalid authentication methods
185+
186+
## TypeScript Support
187+
188+
Full TypeScript support is included with proper type definitions for all authentication methods and responses.
189+
190+
## API Reference
191+
192+
### Client Exports
193+
194+
- `login(options: LoginOptions)`: Initiates the login process
195+
- `LoginParams`: Type definition for login options
196+
197+
### Server Exports
198+
199+
- `createAuthHandler(options: CreateAuthHandlerOptions)`: Creates an authentication handler
200+
- `toNodeHandler(handler)`: Converts auth handler to be used in Node.js servers (e.g. Express, Fastify, etc.)
201+
- `toNextJsHandler(handler)`: Converts auth handler to Next.js API route handler
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { login, type LoginOptions as LoginParams } from "./login.js";

0 commit comments

Comments
 (0)