Skip to content

0xnald/CastPay

Repository files navigation

CastPay: Continuous Streaming Monetization Infrastructure

Chain Token Protocol

CastPay is a non-custodial pay-per-second and pay-per-minute settlement sidecar for live video streams (HLS) and Video on Demand (VOD) catalogs. Built for the Arc Testnet and powered by Circle Gateway pre-authorized USDC batching, it enables frictionless, popup-free micro-payments for viewers while allowing content creators to instantly withdraw earnings to any target EVM chain.


Key Engineering & Architecture Features

  1. Non-Custodial Micropayments (Zero MetaMask Popups): High-frequency pay-per-second streaming cannot prompt MetaMask signatures repeatedly. CastPay generates a local, ephemeral Session Key in the browser. The viewer makes a single MetaMask transaction to fund this session balance via depositFor(usdc, sessionAddress, amount) on the Gateway contract. The browser then signs high-frequency heartbeats popup-free.

  2. Multi-Platform Integration:

    • Owncast (Live HLS Proxy): Live stream pay-per-second. The sidecar rewrites .m3u8 playlists on-the-fly, serving video segments only to viewers with active heartbeats.
    • Owncast v0.3.0 Plugin (Beta): Native integration. A WebAssembly-hosted JavaScript plugin that plugs into Owncast's auth.gate architecture to perform in-server session gating and MetaMask script injection.
    • Jellyfin (VOD Webhook Sidecar): Coming soon.
    • PeerTube (Payments Plugin): Coming soon.
  3. Platform Fee Splits on Withdrawals: EIP-3009 does not support multiple payees in a single pre-authorized signature. To avoid forcing viewers to sign two separate transactions per heartbeat (which doubles RPC calls and chokes browser event loops), the viewer pays the full amount to the creator's gateway balance. Upon withdrawal, the creator signs two separate BurnIntent payloads sequentially (Net amount to creator, and 1.5% Platform Fee to the platform wallet).

  4. Cross-Chain Minting (Arc L1 to Destination Chain): Creators sign their withdrawal intents in MetaMask. The backend proxies these burn intents to Circle Gateway on Arc L1, retrieving the attestation payload. The frontend then switches MetaMask to the destination chain (e.g. Base Sepolia) and triggers gatewayMint directly to receive the USDC funds.

  5. Scale & Performance Optimizations:

    • Asynchronous settlements: Signature verification is synchronous (~10ms), while on-chain gateway settlements run asynchronously in the background so segment delivery never blocks.
    • HLS Segment Memory Cache: Caches segments for 30s in backend memory to insulate the creator's home server from multiple concurrent viewers.
    • Clock Jitter Tolerance: Client-side signature validity is automatically padded with a 1-day safety margin to prevent signature expiration errors due to clock skew or network latency.

Repository Structure

├── packages
│   ├── backend
│   │   ├── src/server.ts      # Express settlement server, segment proxy, & webhooks receiver
│   │   └── package.json
│   ├── frontend
│   │   ├── src/App.tsx        # React client app with MetaMask EIP-712 signing & SPA Router
│   │   ├── src/index.css      # Custom glassmorphic styling system & shrink animations
│   │   ├── vercel.json        # SPA route fallback rewrites
│   │   └── package.json
│   └── owncast-plugin
│       ├── src/plugin.ts      # Native auth.gate session checking & script injections
│       ├── plugin.manifest.json # Declarative metadata & permission capabilities
│       └── package.json
├── DOCS.md                    # GitBook user onboarding document source
├── README.md                  # Infrastructure overview & developer documentation
└── package.json               # Monorepo workspaces definition

Self-Hosted Sidecar Setup (Docker Compose)

Streamers can run both Owncast and the CastPay sidecar in a single command using Docker Compose.

Note

Community Testing Phase: Because CastPay is currently in an active community testing phase, the pre-built sidecar image has not been published to a public registry (like Docker Hub) yet. During this phase, streamers need to clone the repository to compile the image locally.

In the upcoming official public release, users will NOT need to clone the repository. The docker-compose.yml will be updated to pull the pre-compiled image directly from Docker Hub:

  castpay-sidecar:
    image: 0xnald/castpay-sidecar:latest  # Pulls pre-built image directly from Docker Hub
    container_name: castpay-sidecar
    # ...

1. Clone the Repository

Open a terminal on your server or VPS and run:

git clone https://github.com/0xnald/CastPay.git
cd CastPay

2. Configure Environment Variables

Create a .env.local file inside the CastPay folder with your payout configuration:

SELLER_ADDRESS=0xYourEVMWalletAddressHere # Payout Wallet Address
SELLER_PRIVATE_KEY=your_private_key_here # Required for backend settlements
RPC=https://rpc.testnet.arc.network

3. Launch the Stack

Run the following command in the CastPay folder:

docker compose up --build -d

This automatically builds the CastPay sidecar container locally and launches the official Owncast service in a shared bridge network.

  • Owncast Web UI: http://localhost:8080
  • CastPay Sidecar Portal: http://localhost:3002

4. Configure Gating

  1. Get your stream key from the Owncast admin panel at http://localhost:8080/admin and start streaming from OBS to rtmp://localhost/live.
  2. Open http://localhost:3002 in your browser.
  3. Register your creator profile, and set the HLS Stream URL to: http://owncast:8080/hls/stream.m3u8
  4. Click Go Live and share the viewer link with your audience!

Native Owncast v0.3.0 Plugin (Beta)

We are actively developing a native plugin for the upcoming Owncast v0.3.0 release to replace the external HLS Proxy Gate.

Features

  • In-Server Gating (auth.gate): Owncast handles stream and segment access checks internally, invoking the plugin's onAuthCheck export.
  • Dynamic Script Injection (ui.modify): Injects MetaMask connection scripts and checkout buttons directly onto the stream viewer's browser client.
  • Heartbeat Settlement: Establishes session balances and settlement intervals within the plugin runtime.

Compile & Bundle

To compile the plugin workspace:

npm run compile --workspace=owncast-plugin-castpay

To bundle the plugin into the QuickJS-compatible WebAssembly module:

npm run build --workspace=owncast-plugin-castpay

Local Development & Setup

Prerequisites

  • Node.js (v18+)
  • MetaMask wallet with some testnet gas and USDC.

1. Installation

Install all monorepo dependencies from the root directory:

npm install

2. Configure Environment Variables

Create a .env.local file in the root workspace folder:

# Custom Canteen JSON-RPC Endpoint (provided during CLI setup)
RPC="https://rpc.testnet.arc-node.thecanteenapp.com/v1/swrm_4ba1cb60eb915a5285d7d4fb29e0923321af16cb4f0e2257aa3920a3a33dab2f"

# Backend server variables
BACKEND_URL="http://localhost:3001"

3. Run Backend Settlement Server

# Start backend server on port 3001
npm run dev:backend

4. Run Frontend Portal

# Start Vite React frontend on port 3000
npm run dev:frontend

Open http://localhost:3000 to interact with the CastPay portal.


Simulation & Verification Flow

To verify all multi-platform integrations in a single browser tab, we have built-in simulated environments directly in the app:

  1. Owncast Simulation: Go live in the Creator Console, copy the gated URL, fund the gateway, and click Pay & Watch to verify HLS segment gating.

Releases

Packages

Contributors

Languages