Skip to content

Setup your application

This section will walk you through the steps to create your application, install the necessary dependencies, and write the boilerplate code you'll need to integrate Embedded Accounts!

Create your app

First, create a NextJS React application by running npx create-next-app from your terminal in a project directory of your choice. Select the default configuration for each question the create-next-app CLI.

Also, at the root of this new application directory, add a .env file.

Configure the Embedded Accounts

First, create an Alchemy API key, an Embedded Accounts Config, and a Gas Manager Policy. You will use these to send UOs, authenticate logins, and sponsor gas respectively.

Alchemy API Key

The Alchemy API Key will allow you to read and write to blockchains through Alchemy's reliable infrastructure. In this context, the API Key will let you create Embedded Accounts onchain for your users, and send UserOperations on behalf of those accounts.

To create an API Key, go to https://dashboard.alchemy.com, sign up for an account, and go through the onboarding. Then on the apps page, click "Create new app" button.

API Key Create

When configuring the Alchemy app, select Arbitrum Sepolia for the network.

API Key Configure

Click the API Key button in the top right corner and copy-paste it into the .env file of your application as an environment variable called ALCHEMY_API_KEY.

API Key View

Alchemy Embedded Accounts Config

The Embedded Accounts Config enables magic link authentication on your app's domain by configuring the Alchemy Signer, which securely stores the user's private key in a non-custodial secure enclave. It is responsible for authenticating a user via email or passkey using this config, managing a user's session, and signing messages to send UserOperations. Check out the AlchemySigner docs for more details.

To create an Embedded Accounts Config, go to the embedded accounts page of the Alchemy dashboard and click the “New account config” button.

Accounts Config Create

Then:

  1. Name your config.
  2. Set http://localhost:3000 as the redirect URL. NextJS apps by default are hosted locally at port 3000, and you will want to direct the user back to the URL where your application is hosted to authenticate them.
  3. [optional] Customize the logo, “Sign In” button color, and support URL of the email.
Accounts Config Configure 1

Next, apply this config to the Alchemy App you created in the previous step. Doing this will allow you send requests to Alchemy Signer via the Account Kit SDKs you will install in the next step.

Accounts Config Configure 2

Alchemy Gas Manager Policy

The Gas Manager Policy defines a config for Alchemy's ERC-4337 Paymaster implementation, allowing you to sponsor your users' gas fees. To learn more about Paymasters, check out Alchemy's blog post.

To create a Gas Manager Policy, go to the gas manager page of the Alchemy dashboard and click the “Create new policy” button.

Gas Manager Create

Then:

  1. Name your policy.
  2. Associate the policy with the Alchemy App you created in the last step by selecting it in the “Policy details” section.
  3. Select the default configurations for the remaining sections.
Gas Manager Configure

Once you create the policy, copy the Policy ID below the policy's header and copy-paste it into the .env file of your application as an environment variable called NEXT_PUBLIC_ALCHEMY_GAS_MANAGER_POLICY_ID.

Install dependencies

In this newly created directory for your app, add the following dependencies:

bash
npm i @alchemy/aa-alchemy @alchemy/aa-accounts @alchemy/aa-core [email protected] @tanstack/[email protected]
bash
yarn add @alchemy/aa-alchemy @alchemy/aa-accounts @alchemy/aa-core [email protected] @tanstack/[email protected]
bash
pnpm i @alchemy/aa-alchemy @alchemy/aa-accounts @alchemy/aa-core [email protected] @tanstack/[email protected]

WARNING

The versions of viem and @tanstack/react-query that's required to be installed is listed as a peerDependency of the various @alchemy/* packages (2.8.6 and 5.28.9, respectively, at the time of writing). Due to some breaking changes between patch and minor versions of viem and @tanstack/react-query, it's recommended to pin your version of viem to the listed peerDependency in the package.json.

The three Alchemy packages - @alchemy/aa-alchemy, @alchemy/aa-accounts, and @alchemy/aa-core - come from the Alchemy Account Kit, and will provide the key building blocks for created Embedded Accounts.

viem is a useful Web3 Utils library and a key dependency of Account Kit.

@tanstack/react-query is a popular library for managing client-side state in NextJS and React applications. You're welcome to use another state management library or vanilla react, but the rest of this demo will use ReactQuery.

Set up your backend

Using your code editor, open your newly created application directory to add the backend! Your application's backend will serve as an API that your frontend will use to send requests to Alchemy's infrastructure to sign messages, send UserOperations, and track your users' Embedded Account activity.

From the root of NextJS project's directory, using the NextJS concept of route handlers, create new directory src/app/api/rpc and add two files: src/app/api/rpc/[...routes]/route.ts to handle calls to the Alchemy Signer, and src/app/api/rpc/route.ts to handle requests to Alchemy's infrastructure. Copy the following into those files.

ts
import { arbitrumSepolia } from "@alchemy/aa-core";
import { NextResponse } from "next/server";

export async function POST(req: Request) {
  // if you want to handle other or multiple chains, you can change this line
  const rpcUrl = arbitrumSepolia.rpcUrls.alchemy.http[0];
  const apiKey = process.env.ALCHEMY_API_KEY;

  if (apiKey == null) {
    return NextResponse.json(
      { error: "ALCHEMY_API_KEY is not set" },
      { status: 500 }
    );
  }

  const body = await req.json();

  const res = await fetch(`${rpcUrl}/${apiKey}`, {
    method: "POST",
    headers: {
      ...req.headers,
    },
    body: JSON.stringify(body),
  });

  if (!res.ok) {
    return NextResponse.json(await res.json().catch((e) => ({})), {
      status: res.status,
    });
  }

  return NextResponse.json(await res.json());
}
ts
import { NextResponse } from "next/server";

export async function POST(
  req: Request,
  { params }: { params: { routes: string[] } }
) {
  const apiUrl = "https://api.g.alchemy.com";
  const apiKey = process.env.ALCHEMY_API_KEY;

  if (apiKey == null) {
    return NextResponse.json(
      { error: "ALCHEMY_API_KEY is not set" },
      { status: 500 }
    );
  }

  const body = await req.json();

  const res = await fetch(apiUrl + `/${params.routes.join("/")}`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${apiKey}`,
      ...req.headers,
    },
    body: JSON.stringify(body),
  });

  if (!res.ok) {
    return NextResponse.json(await res.json().catch((e) => ({})), {
      status: res.status,
    });
  }

  return NextResponse.json(await res.json());
}

Notice that here, you'll be using the ALCHEMY_API_KEY environment variable you set in an earlier step. Also note that the backend routes will make requests to Alchemy's infrastructure for the Arbitrum Sepolia network.

Set up your frontend

Before building your app's UI, you'll want to configure a NextJS router and a ReactQuery client to manage state around requests the app will make, and wrap components that use. From the root of NextJS project's directory, create a file src/app/providers.tsx and initialize these providers.

Then, in the src/app/layout.tsx file that came with the NextJS boilerplate, wrap the children component in the Providers component you just created in src/app/providers.tsx.

These two files should look as follows:

tsx
import { cookieToInitialState } from "@alchemy/aa-alchemy/config";
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { headers } from "next/headers";
import { config } from "./config";
import "./globals.css";
import { Providers } from "./providers";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Embedded Accounts Getting Started",
  description: "Embedded Accounts Quickstart Guide",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  // This will allow us to persist state across page boundaries
  const initialState = cookieToInitialState(config, headers().get("cookie"));

  return (
    <html lang="en">
      <body className={inter.className}>
        <Providers initialState={initialState}>{children}</Providers>
      </body>
    </html>
  );
}
tsx
"use client";

import { AlchemyClientState } from "@alchemy/aa-alchemy/config";
import { AlchemyAccountProvider } from "@alchemy/aa-alchemy/react";
import { QueryClientProvider } from "@tanstack/react-query";
import { PropsWithChildren, Suspense } from "react";
import { config, queryClient } from "./config";

export const Providers = (
  props: PropsWithChildren<{ initialState?: AlchemyClientState }>
) => {
  return (
    <Suspense>
      <QueryClientProvider client={queryClient}>
        <AlchemyAccountProvider
          config={config}
          queryClient={queryClient}
          initialState={props.initialState}
        >
          {props.children}
        </AlchemyAccountProvider>
      </QueryClientProvider>
    </Suspense>
  );
};
ts
import { cookieStorage, createConfig } from "@alchemy/aa-alchemy/config";
import { arbitrumSepolia } from "@alchemy/aa-core";
import { QueryClient } from "@tanstack/react-query";

export const queryClient = new QueryClient();
export const config = createConfig({
  rpcUrl: "/api/rpc", // this will proxy requests through the app's backend via NextJS routing to hide the Alchemy API key
  chain: arbitrumSepolia,
  // because we're using NextJS which is SSR, we need the following settings
  ssr: true,
  // This will allow us to persist user state to cookies, making a smoother user experience
  // not required in non SSR settings
  storage: cookieStorage,
});

Now, you have all the pieces in place to build a new web application using Embedded Accounts! In the next step of this guide, you'll integrate the Alchemy Signer to enable your app to sign users into their newly created Embedded Accounts.