> For the complete documentation index, see [llms.txt](https://docs.orda.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.orda.network/developers/widget/authentication.md).

# 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 %}
