Skip to content

Commit

Permalink
feat: add otp and magic link example updates to the documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
iykazrji committed Dec 19, 2024
1 parent 4cbfa9b commit d083b22
Show file tree
Hide file tree
Showing 13 changed files with 347 additions and 135 deletions.
6 changes: 5 additions & 1 deletion examples/react-native-expo-example/app/(tabs)/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ export default function MagicLinkAuthScreen() {
onPress={() => {
setAuthRequestSent(true);
signer
.authenticate({ email, type: "email" })
.authenticate({
email,
type: "email",
emailMode: "magicLink",
})
.catch(console.error);
}}
>
Expand Down
115 changes: 0 additions & 115 deletions site/pages/react-native/signer/authenticating-users.mdx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
---
title: Authenticating Users via Magic Link
description: Learn how to authenticate users using an emailmagic link using the React Native Signer
---

# Authenticating Users via Magic Link

This guide assumes you have already followed the [Setup Guide](/react-native/signer/setup-guide) and have a basic understanding of how to use the Signer in your project.

:::info
For example code on how to use the Signer in your project, please checkout our example apps in our github repository.

- [Bare React Native Example](https://github.com/alchemyplatform/aa-sdk/tree/main/examples/react-native-bare-example)
- [Expo Example](https://github.com/alchemyplatform/aa-sdk/tree/main/examples/react-native-expo-example)

:::

## Create a Signer Instance

```tsx
import { RNAlchemySigner } from "@account-kit/react-native-signer";

const signer = RNAlchemySigner({
client: { connection: { apiKey: API_KEY } },
});
```

## Authenticate a User

Next, you'll need to authenticate your user before you can use the Signer as an owner on the account

### Send an Email Magic Link to a User

To send an email magic link to a user, you can use the `signer.authenticate()` method.

```tsx
signer
.authenticate({
email: "user@example.com",
type: "email",
emailMode: "magicLink",
})
.catch((error) => {
console.error(error);
});
```

### Authenticate User via Deep Link

When a user clicks on the magic link in their email, it should deep link to your app if this has been setup correctly.

A `bundle` parameter present in the deep link url will be used to authenticate the user and save the user's session.

Here's an example of what this might look like:

```tsx [example.tsx] twoslash
import { useEffect, useState } from "react";
import { Linking } from "react-native";
import { User } from "@account-kit/signer";
import { RNAlchemySigner } from "@account-kit/react-native-signer";

const API_KEY = "your-api-key";

const signer = RNAlchemySigner({
client: { connection: { apiKey: API_KEY } },
});

const App = () => {
const [user, setUser] = useState<User | null>(null);

// Make an authentication request to a user's email
const performAuthRequest = async () => {
const user = await signer.authenticate({
email: "user@example.com",
type: "email",
});
};

// Authenticate a user using a bundle returned from a deep link
const handleUserAuth = async ({ bundle }: { bundle: string }) => {
const user = await signer.authenticate({ bundle, type: "email" });

return user;
};

// Handle incoming deep links and authenticate the user
const handleIncomingURL = (event: { url: string }) => {
const regex = /[?&]([^=#]+)=([^&#]*)/g;

let params: Record<string, string> = {};
let match: RegExpExecArray | null;

while ((match = regex.exec(event.url))) {
if (match[1] && match[2]) {
params[match[1]] = match[2];
}
}

if (!params.bundle) {
return;
}

handleUserAuth({
bundle: params.bundle ?? "",
})
.then((user) => {
setUser(user);
})
.catch((error) => {
console.error(error);
});
};

// Create a subscription to handle incoming deep links
useEffect(() => {
const subscription = Linking.addEventListener("url", handleIncomingURL);

return () => subscription.remove();
}, []);

return null;
};
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
title: Authenticating Users via One-Time Password (OTP)
description: Learn how to authenticate users via a one-time password (OTP), sent to their email
---

# Authenticating Users via OTP

This guide assumes you have already followed the [Setup Guide](/react-native/signer/setup-guide) and have a basic understanding of how to use the Signer in your project.

:::info
For example code on how to use the Signer in your project, please checkout our example apps in our github repository.

- [Bare React Native Example](https://github.com/alchemyplatform/aa-sdk/tree/main/examples/react-native-bare-example)
- [Expo Example](https://github.com/alchemyplatform/aa-sdk/tree/main/examples/react-native-expo-example)

:::

## Create a Signer Instance

```tsx
import { RNAlchemySigner } from "@account-kit/react-native-signer";

const signer = RNAlchemySigner({
client: { connection: { apiKey: API_KEY } },
});
```

## Authenticate a User

Next, you'll need to authenticate your user before you can use the Signer as an owner on the account

### Send a One-Time Password (OTP) to a User

To send an OTP to a user's email, use the `signer.authenticate()` method with the `emailMode` set to `otp`.

```tsx
signer
.authenticate({
email: "user@example.com",
type: "email",
emailMode: "otp",
})
.catch((error) => {
console.error(error);
});
```

### Prompt the User to enter the One-Time Password to complete authentication

The user will receive an email with a one-time password (OTP) to enter into your app.

Provide a means for the user to enter the OTP into your app and then call the `signer.authenticate()` method using the `otpCode` parameter to complete the authentication process.

Here's an example of what this might look like:

```tsx [example.tsx] twoslash
import React, { useEffect, useState } from "react";
import { Linking, View, Text, TextInput, Button } from "react-native";
import { User } from "@account-kit/signer";
import { RNAlchemySigner } from "@account-kit/react-native-signer";

const API_KEY = "your-api-key";

const signer = RNAlchemySigner({
client: { connection: { apiKey: API_KEY } },
});

const App = () => {
const [user, setUser] = useState<User | null>(null);
const [otpCode, setOtpCode] = useState<string>("");

useEffect(() => {
// For example purposes only. Make the performAuthRequest() call on mount
performAuthRequest().catch((error) => {
console.error(error);
});
}, []);

// Make an authentication request to a user's email
const performAuthRequest = async () => {
const user = await signer.authenticate({
email: "user@example.com",
type: "email",
emailMode: "otp",
});
};

// Authenticate a user using a bundle returned from a deep link
const handleUserAuth = async ({ otpCode }: { otpCode: string }) => {
const user = await signer.authenticate({ otpCode, type: "otp" }); //<-- Pass the user's OTP code to the authenticate method using `otp` as the type value

return user;
};

return (
<View>
<Text>Enter OTP</Text>
<TextInput
value={otpCode}
onChangeText={setOtpCode}
placeholder="Enter OTP"
/>
<Button
title="Authenticate"
onPress={() => handleUserAuth({ otpCode })}
/>

{/* ... Rest of your app */}
</View>
);
};
```
12 changes: 12 additions & 0 deletions site/sidebar/react-native/authenticating-users.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { SidebarItem } from "vocs";

export const authenticatingUsersSidebar: SidebarItem[] = [
{
text: "Authenticating Users via Magic Link",
link: "/react-native/signer/authenticating-users/authenticating-with-magic-link",
},
{
text: "Authenticating Users via One-Time Password (OTP)",
link: "/react-native/signer/authenticating-users/authenticating-with-otp",
},
];
Loading

0 comments on commit d083b22

Please sign in to comment.