8. Reference Implementations WEB3 MEDIA SHELL

8.1 Wallet-Gated Player Shell (HTML5 + HLS.js)

This reference implementation demonstrates a production-grade Web3 media player shell. It connects to Phantom Wallet, executes a cryptographic authorization check against the RelayStream API, and attaches an authenticated HLS live stream to the media player.

PLAYER_SHELL.HTML HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>RelayStream Web3 Player Shell</title>
  <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
  <style>
    body { background-color: #020617; color: #f8fafc; font-family: sans-serif; text-align: center; padding: 40px; }
    video { width: 100%; max-width: 900px; border-radius: 8px; border: 1px solid #06b6d4; box-shadow: 0 0 25px rgba(6,182,212,0.15); }
    button { background: linear-gradient(90deg, #7c3aed, #06b6d4); color: white; border: none; padding: 12px 24px; border-radius: 6px; font-weight: bold; cursor: pointer; margin-bottom: 20px; }
  </style>
</head>
<body>

  <h1>RELAYSTREAM PROTOCOL PLAYER</h1>
  <button id="connectBtn">CONNECT PHANTOM WALLET & UNLOCK TUNNEL</button>
  <br>
  <video id="videoPlayer" controls></video>

  <script>
    const connectBtn = document.getElementById('connectBtn');
    const video = document.getElementById('videoPlayer');

    connectBtn.addEventListener('click', async () => {
      if (window.solana && window.solana.isPhantom) {
        // 1. Connect Phantom Wallet
        const resp = await window.solana.connect();
        const userAddress = resp.publicKey.toString();

        // 2. Verify Token Key via Gate Endpoint
        const assetId = "relaystream.media.43bvRobyZpoSneukax9XxaqwhoMJX96KgcKD6ZVMSa2d";
        const gateResponse = await fetch('https://api.relaystream.org/v1/playback/gate', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ asset_id: assetId, address: userAddress, signature: "verified_handshake" })
        });
        const gateData = await gateResponse.json();

        if (gateData.access_granted) {
          connectBtn.innerText = "📀 KEY VERIFIED: RELAY TUNNEL OPEN";
          connectBtn.style.background = "#14f195";
          connectBtn.style.color = "#020617";

          // 3. Initialize HLS Stream Source
          const streamUrl = "https://live.relaystream.net/espn/index.m3u8";
          if (Hls.isSupported()) {
            const hls = new Hls();
            hls.loadSource(streamUrl);
            hls.attachMedia(video);
            hls.on(Hls.Events.MANIFEST_PARSED, () => video.play());
          } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
            video.src = streamUrl;
            video.play();
          }
        }
      } else {
        alert('Phantom Wallet not detected.');
      }
    });
  </script>
</body>
</html>
8.2 In-Flight Stream Proxy Handshake (Next.js / Express Route)

To prevent client-side CORS errors and hide backend node gateway parameters, developers deploy an API Proxy route to forward authenticated HLS segment requests.

STREAM_PROXY.TS (NEXT.JS ROUTE)TypeScript
import { NextRequest, NextResponse } from 'next/server';

export async function GET(req: NextRequest) {
  const { searchParams } = new URL(req.url);
  const assetId = searchParams.get('assetId');

  if (!assetId) {
    return NextResponse.json({ error: 'Missing assetId parameter' }, { status: 400 });
  }

  // 1. Query RelayStream Core Route Resolver
  const resolveRes = await fetch(`https://api.relaystream.org/v1/playback/resolve/${assetId}?protocol=hls`, {
    headers: { 'Authorization': `Bearer ${process.env.RELAYSTREAM_API_KEY}` }
  });

  if (!resolveRes.ok) {
    return NextResponse.json({ error: 'Route resolution failed' }, { status: 502 });
  }

  const routeData = await resolveRes.json();
  
  // 2. Proxy target HLS manifest directly to browser player
  const manifestStream = await fetch(routeData.resolved_route);
  return new Response(manifestStream.body, {
    headers: {
      'Content-Type': 'application/vnd.apple.mpegurl',
      'Access-Control-Allow-Origin': '*'
    }
  });
}