ERC7824
Trivia Royale GuidePatterns & Examples

Ping-Pong Session

Your first session with typed messages and event handlers

Ping-Pong Session

This pattern demonstrates sessions, typed messaging, and event handlers - the building blocks of interactive applications.

Complete Code


async function () {
  const  = .;
  const  = .;

  // Server tracks pong responses
  const : <{ : ; : number }> = [];

  // Create clients with typed message handlers
  const  = <PingPongSchema>({
    : ,
    : async (, , ) => {
      if ( === 'pong') {
        // TypeScript knows: data is { from: Address; replyTo: number }
        const  = .() - .replyTo;
        .({ : .from,  });
        .(`📬 Received pong from ${.from.slice(0, 10)} (${}ms)`);
      }
    }
  });

  const  = <PingPongSchema>({
    : ,
    : async (, , ) => {
      if ( === 'ping') {
        // TypeScript knows: data is { from: Address; timestamp: number }
        .(`📬 Received ping from ${.from.slice(0, 10)}`);

        // Auto-respond with pong
        await .(, 'pong', {
          : .,
          : .timestamp
        });
        .(`📤 Sent pong response`);
      }
    }
  });

  // Connect both clients
  await .([
    .(),
    .()
  ]);

  // Create session
  const  = .({
    : [., .],
    : [
      { : ., : 'USDC', : '0' },
      { : ., : 'USDC', : '0' }
    ]
  });

  const [, ] = await .([
    .(),
    .()
  ]);

  const  = await .(, [, ]);
  .(`✅ Session created: ${}\n`);

  // Send ping
  .('📤 Server sending ping...');
  await .(, 'ping', {
    : .,
    : .()
  });

  // Wait for response
  await new ( => (, 500));

  // Check results
  .(`\n📊 Results:`);
  .(`Pong responses: ${.}`);
  .( => {
    .(`  - ${..(0, 10)}: ${.}ms`);
  });

  // Cleanup
  await .(, [
    { : ., : 'USDC', : '0' },
    { : ., : 'USDC', : '0' }
  ]);

  await .();
  await .();
}

Key Concepts

1. Message Schema

Defines the structure of messages:

import type { MessageSchema } from '@trivia-royale/game';
import type {  } from 'viem';

interface PingPongSchema extends MessageSchema {
  : { : { : ; : number } };
  : { : { : ; : number } };
}

2. Event Handlers

Clients react to messages asynchronously with automatic type narrowing:


. = async (, , ) => {
  if ( === 'ping') {
    // data is automatically { from: Address; timestamp: number }
    await .(, 'pong', {
      : ,
      : .timestamp
    });
  }
};

3. Broadcasting

Messages are broadcast to all participants:

Server sends 'ping' → ClearNode → Player receives
Player sends 'pong' → ClearNode → Server receives

4. Session Lifecycle

Create → Active → Exchange Messages → Close

Next Steps