> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://www.openfort.io/api/mcp` to find what you need.
>
> **Have feedback?** Use `submit_feedback` on the same MCP server.

# Automatic Recovery (Embedded Wallet)

To create a wallet with automatic recovery, you need to set up an encryption session. This session is only valid for **a single use**.

:::info
This guide assumes you have a backend server correctly set up with Openfort. If you haven't done this yet, please refer to the [Server Environment Quickstart](https://www.openfort.io/docs/products/server/setup) guide.
:::

When using automatic recovery, **[Shield](https://github.com/openfort-xyz/shield)** generates a password that is used for the encryption of the recovery share. The full encryption key can only be accessed if the decryption request includes the user's auth token.

:::warning
When using **automatic recovery**, it's important to ensure that the `encryption share` is not available from the client side of the application.
:::

It is worth noting that while **automatic recovery** makes for smooth user UX (without needing to set up a recovery system upfront when logging in), it comes with tradeoffs. Notably, the root of trust with is in the user's authentication token. This means access to the auth token grants access to the wallet. Accordingly, this token must be properly secured at all times.

:::tip
Use our prebuilt endpoint and deploy in one click on Cloudflare or Vercel as a function.

[![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/openfort-xyz/recovery-endpoint-cloudflare)

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/openfort-xyz/recovery-endpoint-vercel\&project-name=shield-recovery-endpoint\&env=SHIELD_PUBLISHABLE_KEY,SHIELD_SECRET_KEY,SHIELD_ENCRYPTION_SHARE\&envDescription=Required%20Shield%20API%20keys%20from%20your%20Openfort%20project\&envLink=https://www.openfort.io/docs)
:::

## With Node SDK

```ts
import Openfort from "@openfort/openfort-node";
const openfort = new Openfort("YOUR_OPENFORT_SECRET_KEY");
const session = await openfort.createEncryptionSession(
  "YOUR_SHIELD_PUBLISHABLE_KEY",
  "YOUR_SHIELD_SECRET_KEY",
  "YOUR_SHIELD_ENCRYPTION_SHARE"
);
```

## With Raw HTTPS call

```ts
const response = await fetch("https://shield.openfort.io/project/encryption-session", {
  headers: {
    "Content-Type": "application/json",
    "x-api-key": "YOUR_SHIELD_PUBLISHABLE_KEY",
    "x-api-secret": "YOUR_SHIELD_SECRET_KEY",
  },
  method: "POST",
  body: JSON.stringify({
    encryption_part: "YOUR_SHIELD_ENCRYPTION_SHARE",
  }),
});
```

## Next.js backend API route example

The React SDK sends the current Openfort access token as `Authorization: Bearer <token>`. Verify that token before creating a session:

:::code-group
```ts [protected-create-encryption-session.ts]
import type { NextApiRequest, NextApiResponse } from "next";
import openfort from "./openfortAdminConfig";

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const accessToken = req.headers.authorization?.replace(/^Bearer /i, "");
  if (!accessToken) {
    return res.status(401).send({ error: "Missing access token" });
  }

  try {
    await openfort.iam.getSession({ accessToken });
  } catch {
    return res.status(401).send({ error: "Invalid access token" });
  }

  try {
    const session = await openfort.createEncryptionSession(
      process.env.SHIELD_PUBLISHABLE_KEY!,
      process.env.SHIELD_SECRET_KEY!,
      process.env.SHIELD_ENCRYPTION_SHARE!
    );

    return res.status(200).send({ session });
  } catch {
    return res.status(500).send({ error: "Failed to create encryption session" });
  }
}
```

```ts [openfortAdminConfig.ts]
import Openfort from "@openfort/openfort-node";

const openfort = new Openfort("YOUR_OPENFORT_SECRET_KEY");

export default openfort;
```

Serve this endpoint over HTTPS. Plain HTTP is supported only for local development on `localhost`. Keep the Shield secret key and encryption share exclusively on the server.
:::
