> ## Documentation Index
> Fetch the complete documentation index at: https://docs.privacyboost.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Privy Integration

> Authenticate Privacy Boost users with Privy

# Privy Integration

[Privy](https://www.privy.io) provides embedded wallets, social login, and user management for web3 apps. You can use Privy as your auth provider for Privacy Boost, letting users log in with email, social accounts, or wallets through Privy while using Privacy Boost for private transactions.

## How It Works

Privy authenticates your users and issues JWTs. Your backend forwards the Privacy Boost login payload with the Privy token attached. Privacy Boost validates the token against Privy's JWKS endpoint.

<img className="block dark:hidden" src="https://mintcdn.com/sunnysidelabs/npTSPV0krdyxjvTn/images/sdk/privy-flow.svg?fit=max&auto=format&n=npTSPV0krdyxjvTn&q=85&s=c9808cb436341160d581426a87e03124" alt="Privy Authentication Flow" width="800" height="400" data-path="images/sdk/privy-flow.svg" />

<img className="hidden dark:block" src="https://mintcdn.com/sunnysidelabs/npTSPV0krdyxjvTn/images/sdk/privy-flow-dark.svg?fit=max&auto=format&n=npTSPV0krdyxjvTn&q=85&s=e2bb5c7a2214f93b7f052323d0cbbab7" alt="Privy Authentication Flow" width="800" height="400" data-path="images/sdk/privy-flow-dark.svg" />

## Server-Side Setup

Your app must be configured with the `privy_jwt` auth method. Contact the Privacy Boost team with:

* **Privy App ID** — Your Privy application ID (found in the [Privy Dashboard](https://dashboard.privy.io))
* **JWKS URL** — Privy's JWKS endpoint: `https://auth.privy.io/api/v1/apps/<YOUR_PRIVY_APP_ID>/.well-known/jwks.json`

The backend configuration looks like:

```json theme={null}
{
  "privy_app_id": "clx...",
  "jwks_url": "https://auth.privy.io/api/v1/apps/clx.../.well-known/jwks.json"
}
```

## Client-Side Integration

### 1. Set Up Privy

Follow [Privy's React quickstart](https://docs.privy.io/guide/react/quickstart) to set up `PrivyProvider`:

```tsx theme={null}
import { PrivyProvider } from '@privy-io/react-auth';

function App() {
  return (
    <PrivyProvider appId="clx..." config={{ /* ... */ }}>
      <YourApp />
    </PrivyProvider>
  );
}
```

### 2. Create a Token Provider

The token provider gets the Privy auth token and forwards it with the Privacy Boost login payload:

```typescript theme={null}
import { usePrivy } from '@privy-io/react-auth';

function usePrivacyBoostAuth() {
  const { getAccessToken } = usePrivy();

  const tokenProvider = async (loginPayload: any) => {
    const privyToken = await getAccessToken();

    const res = await fetch('https://your-backend.com/api/privacy-boost/auth', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${privyToken}`,
      },
      body: JSON.stringify(loginPayload),
    });

    return await res.json(); // { token, expiresIn }
  };

  return { tokenProvider };
}
```

### 3. Authenticate with Privacy Boost

```typescript theme={null}
const { tokenProvider } = usePrivacyBoostAuth();

await sdk.auth.authenticate(adapter, {
  type: 'walletDerived',
  tokenProvider,
});
```

### 4. Implement the Backend Endpoint

Your backend receives the SDK's login payload, verifies the Privy token, and forwards to Privacy Boost:

```typescript theme={null}
app.post('/api/privacy-boost/auth', async (req, res) => {
  // 1. Extract Privy token from Authorization header
  const privyToken = req.headers.authorization?.replace('Bearer ', '');
  if (!privyToken) return res.status(401).json({ error: 'Missing Privy token' });

  // 2. Forward to Privacy Boost with the Privy token attached
  const pbResponse = await fetch('https://optimism.sepolia.privacyboost.io/auth/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      ...req.body,             // SDK's login payload
      privy_token: privyToken, // Privy JWT — Privacy Boost validates this via JWKS
    }),
  });

  const data = await pbResponse.json();
  res.json({
    token: data.access_token,
    expiresIn: data.expires_in,
  });
});
```

<Info>
  You don't need to validate the Privy JWT yourself. Privacy Boost fetches Privy's JWKS and verifies the token signature, audience, and expiry.
</Info>

### Using Privy's Embedded Wallet

If your users use Privy's embedded wallet (no MetaMask), you can create a wallet adapter from Privy's wallet provider:

```typescript theme={null}
import { useWallets } from '@privy-io/react-auth';

function usePrivyWalletAdapter() {
  const { wallets } = useWallets();
  const embeddedWallet = wallets.find((w) => w.walletClientType === 'privy');

  const getAdapter = async () => {
    if (!embeddedWallet) throw new Error('No embedded wallet');
    const provider = await embeddedWallet.getEthereumProvider();

    return {
      async connect() {
        const accounts = await provider.request({ method: 'eth_requestAccounts' });
        const chainId = await provider.request({ method: 'eth_chainId' });
        return { address: accounts[0], chainId: parseInt(chainId, 16) };
      },
      async disconnect() {},
      async signMessage(message: string) {
        const accounts = await provider.request({ method: 'eth_accounts' });
        return provider.request({ method: 'personal_sign', params: [message, accounts[0]] });
      },
      async signTypedData(typedData: string) {
        const accounts = await provider.request({ method: 'eth_accounts' });
        return provider.request({ method: 'eth_signTypedData_v4', params: [accounts[0], typedData] });
      },
      async sendTransaction(tx: unknown) {
        return provider.request({ method: 'eth_sendTransaction', params: [tx] });
      },
      async getAddress() {
        const accounts = await provider.request({ method: 'eth_accounts' });
        return accounts[0];
      },
      async getChainId() {
        const chainId = await provider.request({ method: 'eth_chainId' });
        return parseInt(chainId, 16);
      },
    };
  };

  return { getAdapter, hasWallet: !!embeddedWallet };
}
```

## Next Steps

Continue with setup:

* [Key Management](/sdk/concepts/key-management) — Configure key persistence for returning users
* [Error Handling](/sdk/concepts/error-handling) — Handle auth and operation errors

Or explore other auth methods:

* [Custom JWT](/sdk/guides/custom-jwt) — For Auth0, Firebase, Supabase, Clerk, or OIDC providers
* [Dynamic](/sdk/guides/dynamic) — For Dynamic wallet connection and embedded wallets
