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
- Creator uploads a video file (IPFS via Pinata), or pastes a YouTube or X URL.
- 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.
- 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-fundin one atomic transaction. STX moves from the creator's wallet into the escrowed pool. - Once the tx confirms, the video appears on /browse.
- 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.
- The client POSTs to
/api/distribute-reward. The server signs and broadcastsdistribute-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
timeupdatedeltas 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.