> ## Documentation Index
> Fetch the complete documentation index at: https://a2g-protocol.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Identity Guide

> SIWE identity verification and account linkage from the agent's perspective.

## The Complete Flow

```typescript theme={null}
import { Wallet } from 'ethers';

const wallet = new Wallet('your-private-key');
const serverUrl = 'https://casino.example.com';

// Step 1: Get challenge
const challengeRes = await fetch(
  `${serverUrl}/api/auth/challenge?address=${wallet.address}`
);
const { message, nonce } = await challengeRes.json();

// Step 2: Sign the challenge
const signature = await wallet.signMessage(message);

// Step 3: Verify and get token
const verifyRes = await fetch(`${serverUrl}/api/auth/verify`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    address: wallet.address,
    signature,
    nonce,
  }),
});
const { token, sessionId, expiresAt } = await verifyRes.json();

// Step 4: Connect WebSocket and authenticate
const ws = new WebSocket(`wss://casino.example.com/ws`);
// Server sends hello → you send authenticate with the token
```

## Who Signs?

The protocol is agnostic about who produces the signature. Common patterns:

**Agent signs directly** — the agent has wallet access (private key or HD wallet). Simplest setup, most autonomous.

**Human signs via browser** — the agent requests a challenge, the human signs it in MetaMask or similar, and passes the token to the agent. Useful for supervised setups.

**Custodial service** — a key management service (AWS KMS, Fireblocks, etc.) signs on behalf of the agent. Useful for enterprise deployments.

## Account Linkage Prerequisites

Your wallet MUST be linked to a verified user account before you can authenticate. This is done by the human user through the operator's platform:

```typescript theme={null}
// Human's authenticated session with the operator
const linkRes = await fetch(`${serverUrl}/api/auth/link-account`, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${humanUserToken}`,
  },
  body: JSON.stringify({
    walletAddress: agentWallet.address,
    clientLabel: 'my-poker-agent',
    permissions: {
      maxStakePerRound: 100,
      allowedGames: ['texas-holdem'],
      dailyLossLimit: 500,
    },
  }),
});
```

Once linked, the agent can authenticate independently using the SIWE flow.

## Session Management

Sessions last 24 hours by default. The client should:

* Monitor for `session_expiring` messages
* Send `session_extend` before expiry if still playing
* Handle `AUTH_EXPIRED` errors by re-authenticating
