# Step 3 – Add an Off-Chain Identity Layer (Magmar Auth)

Magmar Smart Accounts are wallet-agnostic, so we need a conventional method to map a real-world user to an on-chain account before we can mint NFTs on their behalf.\
For this tutorial we’ll use Userbase, a quick, server-less identity service to keep things simple. Remember: this is fine for demos, **not for production**.

### 3.1 Install and Configure Userbase

1. **Install the SDK**

```bash
npm i userbase-js
```

2. **Create a Userbase project**

* Visit https://userbase.com and sign up
* After login, you’ll see a default **Starter App** → copy its **App ID**

3. **Add environment variables**

```env
# .env.local
NEXT_PUBLIC_USERBASE_APP_ID=<YOUR_APP_ID>
```

> `NEXT_PUBLIC_` exposes the value to the browser—required by the SDK.

4. **Generate an access token**

* In the dashboard, open **Account → Access Tokens**
* Label it `magmar-get-user` and click **Generate**

Add the token to `.env.local`:

```env
USERBASE_ACCESS_TOKEN=<YOUR_ACCESS_TOKEN>
```

***

### 3.2 Create an `AuthProvider`

Inside `/common`, add `AuthProvider.tsx`:

```tsx
import { createContext, useContext, useEffect, useState, ReactNode } from "react";
import userbase from "userbase-js";

interface User {
  username: string;
  isLoggedIn: boolean;
  userId: string;
  scwAddress?: string;     // Smart-contract wallet address
}

interface AuthContextType {
  user: User | null;
  login: (u: User) => void;
  logout: () => void;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);
export const useAuth = () => {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error("useAuth must be used inside AuthProvider");
  return ctx;
};

export function AuthProvider({ children }: { children: ReactNode }) {
  const [user, setUser] = useState<User | null>(null);

  /* Restore session if browser already has a valid token */
  useEffect(() => {
    userbase
      .init({ appId: process.env.NEXT_PUBLIC_USERBASE_APP_ID! })
      .then((session) => {
        if (session.user) {
          const u: User = {
            username: session.user.username,
            userId: session.user.userId,
            scwAddress: session.user.profile.scwAddress,
            isLoggedIn: true,
          };
          setUser(u);
        }
      })
      .catch(console.error);
  }, []);

  return (
    <AuthContext.Provider
      value={{
        user,
        login: (u) => setUser(u),
        logout: () => setUser(null),
      }}
    >
      {children}
    </AuthContext.Provider>
  );
}
```

***

### 3.3 Wrap the App with `AuthProvider`

Modify `app/layout.tsx` (Next 13 App Router):

```tsx
"use client";

import { WagmiConfig, createConfig, sepolia } from "wagmi";
import { ConnectKitProvider } from "connectkit";
import { AuthProvider } from "@common/AuthProvider";

const config = createConfig({
  appName: "Magmar Gasless NFT Minter",
  chains: [sepolia],
  // … add connectors & providers here
});

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <AuthProvider>
        <WagmiConfig config={config}>
          <ConnectKitProvider mode="dark">
            <body>{children}</body>
          </ConnectKitProvider>
        </WagmiConfig>
      </AuthProvider>
    </html>
  );
}
```

> We restrict chains to **Sepolia** to keep testnet usage safe.

***

### 3.4 Result

Any component can now call `useAuth()` to read or update the current user:

```tsx
const { user } = useAuth();
console.log(user?.scwAddress);
```

You’ve connected an off-chain identity system to Magmar Smart Accounts.\
Next we’ll create **Sign-Up** and **Login** routes that:

1. Generate a private key for the user
2. Derive their deterministic smart-contract wallet address
3. Store both in Userbase (plaintext only for demo!)
