# Authentication

## JWT Authentication

### Authentication Flow

The widget uses JWT (JSON Web Token) authentication to securely communicate with the orda API:

{% stepper %}
{% step %}

### Initial request

When `OrdaProvider` mounts, it calls your `getToken()` function.
{% endstep %}

{% step %}

### Server exchange

Your server route exchanges `clientId` + `clientSecret` for a JWT.
{% endstep %}

{% step %}

### Token storage

JWT is stored in React state and used for all API requests.
{% endstep %}

{% step %}

### Auto-refresh

SDK automatically refreshes the token 5 minutes before expiration.
{% endstep %}

{% step %}

### Request queuing

Requests during refresh are queued and executed after completion.
{% endstep %}
{% endstepper %}

### Token Permissions

Your JWT should include the following permissions:

| Permission          | Description                         |
| ------------------- | ----------------------------------- |
| `quotes:read`       | Generate payment quotes             |
| `offramp:read`      | Off-ramp operations (crypto → fiat) |
| `onramp:read`       | On-ramp operations (fiat → crypto)  |
| `transactions:read` | View transaction status             |
| `recipients:read`   | List saved recipients               |
| `recipients:write`  | Create/update recipients            |

### Security Best Practices

1. Never expose `clientSecret` in browser code
   * Always generate JWT server-side
   * Use environment variables for secrets
   * Never commit secrets to version control
2. Use HTTPS in production
   * Ensure your JWT endpoint uses HTTPS
   * Tokens sent over HTTP can be intercepted
3. Implement rate limiting
   * Limit JWT generation requests per IP/user
   * Prevent abuse of your authentication endpoint
4. Set appropriate token expiration
   * Default: 1 hour (`expiresIn: 3600`)
   * Balance security and user experience
   * SDK handles auto-refresh seamlessly

### Example with Error Handling

```typescript
export async function POST() {
  try {
    if (!CLIENT_ID || !CLIENT_SECRET) {
      return NextResponse.json(
        { error: 'Server configuration error' },
        { status: 500 }
      );
    }

    const httpClient = new UniversalHttpClient(API_URL, 30000);
    const jwtApi = new JWT(httpClient);

    const { token, expiresAt } = await jwtApi.generate({
      clientId: CLIENT_ID,
      clientSecret: CLIENT_SECRET,
      permissions: [
        'quotes:read',
        'offramp:read',
        'onramp:read',
        'transactions:read',
        'recipients:read',
        'recipients:write',
        'balances:read',
        'prices:read'
      ],
    });

    return NextResponse.json({
      jwt: token,
      expiresAt: Math.floor(new Date(expiresAt).getTime() / 1000),
    });
  } catch (error: any) {
    console.error('JWT generation failed:', error);

    // Return appropriate error response
    return NextResponse.json(
      {
        error: error?.message || 'Authentication failed',
        code: error?.code
      },
      { status: error?.statusCode || 500 }
    );
  }
}
```

***

## Environment Variables

### Required Variables

| Variable                                | Description                   | Where to Get It                             |
| --------------------------------------- | ----------------------------- | ------------------------------------------- |
| `NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID` | WalletConnect project ID      | [cloud.reown.com](https://cloud.reown.com/) |
| `ORDA_CLIENT_ID`                        | orda project ID (server-side) | orda Developer Portal                       |
| `ORDA_CLIENT_SECRET`                    | orda API secret (server-side) | orda Developer Portal                       |

### Optional Variables

| Variable                        | Description       | Default                       |
| ------------------------------- | ----------------- | ----------------------------- |
| `NEXT_PUBLIC_ORDA_API_BASE_URL` | orda API base URL | `https://api.orda.network/v1` |

### Example `.env.local`

```bash
# WalletConnect Configuration
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6

# orda API Credentials (DO NOT expose to client)
ORDA_CLIENT_ID=prj_8a8ce3b783ef467f8f48270e4818e57b
ORDA_CLIENT_SECRET=sec_a3e8773348898a0e6ab19e94ee1169505283c1d5b3eb6f40fdaee99b476a25ea

# NEXT_PUBLIC_ORDA_API_BASE_URL=http://localhost:5002/v1
```

### Getting Your Credentials

{% stepper %}
{% step %}

### WalletConnect Project ID

1. Visit [cloud.reown.com](https://cloud.reown.com/)
2. Sign up or log in
3. Create a new project
4. Copy your **Project ID**
5. Add your app domains to the allowlist
   {% endstep %}

{% step %}

### orda API Credentials

1. Visit the orda Developer Portal
2. Sign up for an account
3. Create a new project
4. Copy your **Client ID** and **Client Secret**
   {% endstep %}
   {% endstepper %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.orda.network/developers/widget-beta/authentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
