Skip to main content

The Complete Flow

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:
// 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