Skip to content

Commit 87d55dd

Browse files
committed
update email auth example
1 parent d3a0e54 commit 87d55dd

File tree

8 files changed

+76
-158
lines changed

8 files changed

+76
-158
lines changed

Diff for: examples/email-auth/package.json

+2-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@
1010
"typecheck": "tsc --noEmit"
1111
},
1212
"dependencies": {
13-
"@turnkey/http": "workspace:*",
14-
"@turnkey/api-key-stamper": "workspace:*",
15-
"@turnkey/iframe-stamper": "workspace:*",
13+
"@turnkey/sdk-server": "workspace:*",
14+
"@turnkey/sdk-react": "workspace:*",
1615
"@types/node": "20.3.1",
1716
"@types/react": "18.2.14",
1817
"@types/react-dom": "18.2.6",

Diff for: examples/email-auth/src/components/Auth.tsx

-42
This file was deleted.

Diff for: examples/email-auth/src/pages/_app.tsx

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { AppProps } from "next/app";
2+
import Head from "next/head";
3+
4+
import { TurnkeyProvider } from "@turnkey/sdk-react";
5+
6+
const turnkeyConfig = {
7+
apiBaseUrl: process.env.NEXT_PUBLIC_BASE_URL!,
8+
defaultOrganizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!,
9+
rpId: process.env.NEXT_PUBLIC_RPID!,
10+
iframeUrl:
11+
process.env.NEXT_PUBLIC_AUTH_IFRAME_URL ?? "https://auth.turnkey.com",
12+
};
13+
14+
function EmailAuth({ Component, pageProps }: AppProps) {
15+
return (
16+
<div>
17+
<TurnkeyProvider config={turnkeyConfig}>
18+
<Head>
19+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
20+
</Head>
21+
<Component {...pageProps} />
22+
</TurnkeyProvider>
23+
</div>
24+
);
25+
}
26+
27+
export default EmailAuth;

Diff for: examples/email-auth/src/pages/_document.tsx

-19
This file was deleted.

Diff for: examples/email-auth/src/pages/api/auth.ts

+14-35
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { NextApiRequest, NextApiResponse } from "next";
2-
import { TurnkeyClient, createActivityPoller } from "@turnkey/http";
3-
import { ApiKeyStamper } from "@turnkey/api-key-stamper";
2+
import { Turnkey as TurnkeySDKClient } from "@turnkey/sdk-server";
43

54
type AuthRequest = {
65
suborgID: string;
@@ -29,53 +28,33 @@ export default async function auth(
2928
) {
3029
try {
3130
const request = req.body as AuthRequest;
32-
const turnkeyClient = new TurnkeyClient(
33-
{ baseUrl: process.env.NEXT_PUBLIC_BASE_URL! },
34-
new ApiKeyStamper({
35-
apiPublicKey: process.env.API_PUBLIC_KEY!,
36-
apiPrivateKey: process.env.API_PRIVATE_KEY!,
37-
})
38-
);
39-
40-
const activityPoller = createActivityPoller({
41-
client: turnkeyClient,
42-
requestFn: turnkeyClient.emailAuth,
31+
const turnkeyClient = new TurnkeySDKClient({
32+
apiBaseUrl: process.env.NEXT_PUBLIC_BASE_URL!,
33+
apiPublicKey: process.env.API_PUBLIC_KEY!,
34+
apiPrivateKey: process.env.API_PRIVATE_KEY!,
35+
defaultOrganizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!,
4336
});
4437

45-
const completedActivity = await activityPoller({
46-
type: "ACTIVITY_TYPE_EMAIL_AUTH_V2",
47-
timestampMs: String(Date.now()),
48-
// This is simple in the case of a single organization.
49-
// If you use sub-organizations for each user, this needs to be replaced by the user's specific sub-organization.
50-
organizationId:
51-
request.suborgID || process.env.NEXT_PUBLIC_ORGANIZATION_ID!,
52-
parameters: {
53-
email: request.email,
54-
targetPublicKey: request.targetPublicKey,
55-
invalidateExisting: request.invalidateExisting,
56-
},
38+
const emailAuthResponse = await turnkeyClient.apiClient().emailAuth({
39+
email: request.email,
40+
targetPublicKey: request.targetPublicKey,
41+
invalidateExisting: request.invalidateExisting,
42+
organizationId: request.suborgID || process.env.NEXT_PUBLIC_ORGANIZATION_ID!,
5743
});
5844

59-
const userId = completedActivity.result.emailAuthResult?.userId;
60-
if (!userId) {
61-
throw new Error("Expected a non-null user ID!");
62-
}
45+
const { userId, apiKeyId } = emailAuthResponse;
6346

64-
const apiKeyId = completedActivity.result.emailAuthResult?.apiKeyId;
65-
if (!apiKeyId) {
66-
throw new Error("Expected a non-null API key ID!");
47+
if (!userId || !apiKeyId) {
48+
throw new Error("Expected non-null values for userId and apiKeyId.");
6749
}
6850

6951
res.status(200).json({
7052
userId,
7153
apiKeyId,
72-
// This is simple in the case of a single organization
73-
// If you use sub-organizations for each user, this needs to be replaced by the user's specific sub-organization.
7454
organizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!,
7555
});
7656
} catch (e) {
7757
console.error(e);
78-
7958
res.status(500).json({
8059
message: "Something went wrong.",
8160
});

Diff for: examples/email-auth/src/pages/index.tsx

+27-51
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import Image from "next/image";
22
import styles from "./index.module.css";
3-
import { createActivityPoller, TurnkeyClient } from "@turnkey/http";
4-
import { IframeStamper } from "@turnkey/iframe-stamper";
3+
import { useTurnkey } from "@turnkey/sdk-react";
54
import { useForm } from "react-hook-form";
65
import axios from "axios";
76
import * as React from "react";
87
import { useState } from "react";
9-
import { Auth } from "@/components/Auth";
108

119
/**
1210
* Type definition for the server response coming back from `/api/auth`
@@ -32,9 +30,7 @@ type AuthFormData = {
3230

3331
export default function AuthPage() {
3432
const [authResponse, setAuthResponse] = useState<AuthResponse | null>(null);
35-
const [iframeStamper, setIframeStamper] = useState<IframeStamper | null>(
36-
null
37-
);
33+
const { authIframeClient } = useTurnkey();
3834
const { register: authFormRegister, handleSubmit: authFormSubmit } =
3935
useForm<AuthFormData>();
4036
const {
@@ -43,75 +39,60 @@ export default function AuthPage() {
4339
} = useForm<InjectCredentialsFormData>();
4440

4541
const auth = async (data: AuthFormData) => {
46-
if (iframeStamper === null) {
42+
if (authIframeClient === null) {
4743
throw new Error("cannot initialize auth without an iframe");
4844
}
4945

5046
const response = await axios.post("/api/auth", {
5147
suborgID: data.suborgID,
5248
email: data.email,
53-
targetPublicKey: iframeStamper.publicKey(),
49+
targetPublicKey: authIframeClient!.iframePublicKey,
5450
invalidateExisting: data.invalidateExisting,
5551
});
5652

5753
setAuthResponse(response.data);
5854
};
5955

6056
const injectCredentials = async (data: InjectCredentialsFormData) => {
61-
if (iframeStamper === null) {
62-
throw new Error("iframeStamper is null");
57+
if (authIframeClient === null) {
58+
throw new Error("iframe client is null");
6359
}
6460
if (authResponse === null) {
6561
throw new Error("authResponse is null");
6662
}
67-
6863
try {
69-
await iframeStamper.injectCredentialBundle(data.authBundle);
64+
await authIframeClient!.injectCredentialBundle(
65+
data.authBundle
66+
);
7067
} catch (e) {
7168
const msg = `error while injecting bundle: ${e}`;
7269
console.error(msg);
7370
alert(msg);
7471
return;
7572
}
7673

77-
const client = new TurnkeyClient(
78-
{
79-
baseUrl: process.env.NEXT_PUBLIC_BASE_URL!,
80-
},
81-
iframeStamper
82-
);
83-
8474
// get whoami for suborg
85-
const whoamiResponse = await client.getWhoami({
75+
const whoamiResponse = await authIframeClient!.getWhoami({
8676
organizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!,
8777
});
8878

8979
const orgID = whoamiResponse.organizationId;
9080

91-
const activityPoller = createActivityPoller({
92-
client,
93-
requestFn: client.createWallet,
94-
});
95-
96-
const completedActivity = await activityPoller({
97-
type: "ACTIVITY_TYPE_CREATE_WALLET",
98-
timestampMs: String(Date.now()),
81+
const createWalletResponse = await authIframeClient!.createWallet({
9982
organizationId: orgID,
100-
parameters: {
101-
walletName: data.walletName,
102-
accounts: [
103-
{
104-
curve: "CURVE_SECP256K1",
105-
pathFormat: "PATH_FORMAT_BIP32",
106-
path: "m/44'/60'/0'/0/0",
107-
addressFormat: "ADDRESS_FORMAT_ETHEREUM",
108-
},
109-
],
110-
},
83+
walletName: data.walletName,
84+
accounts: [
85+
{
86+
curve: "CURVE_SECP256K1",
87+
pathFormat: "PATH_FORMAT_BIP32",
88+
path: "m/44'/60'/0'/0/0",
89+
addressFormat: "ADDRESS_FORMAT_ETHEREUM",
90+
},
91+
],
11192
});
11293

113-
const wallet = refineNonNull(completedActivity.result.createWalletResult);
114-
const address = refineNonNull(wallet.addresses[0]);
94+
const wallet = refineNonNull(createWalletResponse.walletId);
95+
const address = refineNonNull(createWalletResponse.addresses[0]);
11596

11697
alert(`SUCCESS! Wallet and new address created: ${address} `);
11798
};
@@ -133,15 +114,10 @@ export default function AuthPage() {
133114
/>
134115
</a>
135116

136-
<Auth
137-
setIframeStamper={setIframeStamper}
138-
iframeUrl={process.env.NEXT_PUBLIC_AUTH_IFRAME_URL!}
139-
turnkeyBaseUrl={process.env.NEXT_PUBLIC_BASE_URL!}
140-
></Auth>
141117

142-
{!iframeStamper && <p>Loading...</p>}
118+
{!authIframeClient && <p>Loading...</p>}
143119

144-
{iframeStamper && iframeStamper.publicKey() && authResponse === null && (
120+
{authIframeClient && authIframeClient.iframePublicKey && authResponse === null && (
145121
<form className={styles.form} onSubmit={authFormSubmit(auth)}>
146122
<label className={styles.label}>
147123
Email
@@ -171,16 +147,16 @@ export default function AuthPage() {
171147
<label className={styles.label}>
172148
Encryption Target from iframe:
173149
<br />
174-
<code title={iframeStamper.publicKey()!}>
175-
{iframeStamper.publicKey()!.substring(0, 30)}...
150+
<code title={authIframeClient.iframePublicKey!}>
151+
{authIframeClient.iframePublicKey!.substring(0, 30)}...
176152
</code>
177153
</label>
178154

179155
<input className={styles.button} type="submit" value="Auth" />
180156
</form>
181157
)}
182158

183-
{iframeStamper && iframeStamper.publicKey() && authResponse !== null && (
159+
{authIframeClient && authIframeClient.iframePublicKey && authResponse !== null && (
184160
<form
185161
className={styles.form}
186162
onSubmit={injectCredentialsFormSubmit(injectCredentials)}

Diff for: examples/email-auth/tsconfig.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
}
2121
],
2222
"paths": {
23-
"@/*": ["./src/*"]
23+
"@/*": ["./src/*"],
24+
"react": ["./node_modules/@types/react"]
2425
}
2526
},
2627
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],

Diff for: pnpm-lock.yaml

+4-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)