Skip to content

Commit bacb489

Browse files
committed
add JWT signing and redirect for login flow
1 parent ca75681 commit bacb489

File tree

2 files changed

+68
-27
lines changed

2 files changed

+68
-27
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"use server";
2+
3+
import { createThirdwebClient } from "thirdweb";
4+
import { encodeJWT } from "thirdweb/utils";
5+
import { privateKeyToAccount, randomPrivateKey } from "thirdweb/wallets";
6+
7+
const client = createThirdwebClient({
8+
clientId: "e9ba48c289e0cc3d06a23bfd370cc111",
9+
});
10+
const privateKey = process.env.THIRDWEB_ADMIN_PRIVATE_KEY;
11+
12+
const serverAccount = privateKeyToAccount({
13+
client,
14+
privateKey: privateKey || randomPrivateKey(),
15+
});
16+
17+
export async function signJWTAndRedirect(data: {
18+
address: string;
19+
sesionKeySignerAddress: string;
20+
code: string;
21+
redirect: string;
22+
}) {
23+
const jwt = await encodeJWT({
24+
account: serverAccount,
25+
payload: {
26+
iss: serverAccount.address,
27+
sub: data.address,
28+
aud: data.sesionKeySignerAddress,
29+
exp: new Date(Date.now() + 1000 * 60 * 60),
30+
nbf: new Date(),
31+
iat: new Date(),
32+
jti: data.code,
33+
},
34+
});
35+
36+
return `${data.redirect}#${jwt}`;
37+
}

apps/login/src/app/page.tsx

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
useActiveAccount,
1111
} from "thirdweb/react";
1212
import { isContractDeployed } from "thirdweb/utils";
13+
import { signJWTAndRedirect } from "./actions/signJWTAndRedirect";
1314

1415
const sesionKeySignerAddress = "0x6f700ba0258886411D2536399624EAa7158d1742";
1516

@@ -56,6 +57,12 @@ export default function Page() {
5657
if (!account) {
5758
throw new Error("No account found");
5859
}
60+
if (!code) {
61+
throw new Error("No code found");
62+
}
63+
if (!redirect) {
64+
throw new Error("No redirect found");
65+
}
5966
const accountContract = getContract({
6067
address: account.address,
6168
// hard coded for now
@@ -83,25 +90,38 @@ export default function Page() {
8390
}
8491
throw "already-added";
8592
}}
86-
onError={(e) => {
93+
onError={async (e) => {
94+
if (!code) {
95+
throw new Error("No code found");
96+
}
97+
if (!redirect) {
98+
throw new Error("No redirect found");
99+
}
87100
if (typeof e === "string" && e === "already-added") {
88101
// redirect back to the app
89-
window.location.href = `${redirect}${encodeHash(
90-
account.address,
102+
window.location.href = await signJWTAndRedirect({
103+
address: account.address,
91104
sesionKeySignerAddress,
92-
code || "",
93-
)}`;
105+
code,
106+
redirect,
107+
});
94108
} else {
95109
console.error(e);
96110
}
97111
}}
98-
onTransactionConfirmed={() => {
99-
// redirect back to the app
100-
window.location.href = `${redirect}${encodeHash(
101-
account.address,
112+
onTransactionConfirmed={async () => {
113+
if (!code) {
114+
throw new Error("No code found");
115+
}
116+
if (!redirect) {
117+
throw new Error("No redirect found");
118+
}
119+
window.location.href = await signJWTAndRedirect({
120+
address: account.address,
102121
sesionKeySignerAddress,
103-
code || "",
104-
)}`;
122+
code,
123+
redirect,
124+
});
105125
}}
106126
>
107127
Approve
@@ -116,19 +136,3 @@ export default function Page() {
116136
</div>
117137
);
118138
}
119-
120-
function encodeHash(
121-
userAddress: string,
122-
sessionKeyAddress: string,
123-
code: string,
124-
) {
125-
// Create an object with the three keys.
126-
const data = { userAddress, sessionKeyAddress, code };
127-
128-
// Convert to JSON and then Base64-encode the result.
129-
const jsonString = JSON.stringify(data);
130-
const base64Data = btoa(jsonString);
131-
132-
// Return as a hash string (with the "#" prefix).
133-
return `#${base64Data}`;
134-
}

0 commit comments

Comments
 (0)