Introduction

How it works

Four moving parts: creators, videos, reward pools, and viewers. Each one has a well-defined on-chain contract behind it.

The actors

  • Creator — publishes a video and funds its reward pool up front. Sets the reward per view and the minimum completion percentage (default 70%).
  • Viewer — connects a Stacks wallet, watches to the threshold, receives STX from the pool.
  • Platform — takes a small fee at fund time (currently 5%), escrowed transparently. See Contracts & security.

The lifecycle of a video

  1. Creator uploads a video file (IPFS via Pinata), or pastes a YouTube or X URL.
  2. The client extracts 5 frames and runs them through an AI moderation classifier. Anything flagged for nudity, gore, extreme violence, hard drugs, or hate symbols is rejected here — nothing is pinned or broadcast on-chain.
  3. Creator sets a title, reward per view, and pool size. The client pins an IPFS manifest (title, description, source, thumbnail CID) and calls mozoflix-rewards-v2.register-and-fund in one atomic transaction. STX moves from the creator's wallet into the escrowed pool.
  4. Once the tx confirms, the video appears on /browse.
  5. A viewer opens the video, watches past the completion gate. The player tracks real watch time, not scrub position — so skipping to the end doesn't trigger the reward.
  6. The client POSTs to /api/distribute-reward. The server signs and broadcasts distribute-reward(viewer, videoId, completion). The contract verifies the wallet hasn't already claimed for this video, that the pool has funds, and that the video is active, then transfers STX out to the viewer.

Anti-fraud

Three defences work together:

  • Honest watch time. The player counts only timeupdate deltas under 2.5 seconds. Seeks and scrubs don't add to the counter.
  • One claim per wallet, forever. Enforced by the Clarity contract. Reloading the page, opening a new tab, or clearing storage won't re-trigger a payout.
  • Rate limits. The distribute endpoint is throttled per-IP and per-wallet before it's ever handed to the signer.
warningHeads up
Determined attackers can still spin up new wallets and use each one once. This is a Web3-shaped problem — solved long term with reputation and creator-side sybil controls (see the roadmap in FAQ).

What counts as a “view”

Whatever the creator sets as min-completion-pct (between 50% and 100%). Default is 70%. For YouTube embeds we poll the IFrame API for actual playback time; for X embeds, where playback isn't exposed to third parties, we use a visibility-gated timer that pauses when the tab or embed leaves the viewport.