Attach the rail to your instance — without forking it

Every attachment uses a surface your platform already exposes: a webhook you register, a config value you redirect, a plugin you install, a proxy you put in front. Your platform's source is never modified, and upgrades keep working.

Shared prerequisites (every recipe)

  1. A deployed StakeVaultFactory on the target chain (contracts/script/DeployStakeRail.s.sol — anvil for local, an L2 testnet for staging).
  2. A running facilitator (npx up-facilitator) with its API key.
  3. At least one supporter who has staked + granted a policy via @universal-paywall/agent (the payer side).
  4. A wallet registry for your platform's identities — supplied to the sidecar as PAYER_WALLETS / CREATOR_WALLETS JSON maps (static maps today; music can resolve artists live via MusicBrainz).

The sidecar in one command

Most platforms attach through one env-driven process, up-integration:

PLATFORM=owncast \
FACILITATOR_URL=https://facilitator.example FACILITATOR_API_KEY=… \
PAYER_WALLETS='{"<viewer-id>":"0x…"}' CREATOR_WALLETS='{"<creator-id>":"0x…"}' \
RATE=1000 npx up-integration

Environment reference

EnvMeaning
PLATFORMsubsonic | navidrome | owncast | jellyfin | rsshub | mastodon | immich-proxy
FACILITATOR_URL / FACILITATOR_API_KEYwhere to report charges
PAYER_WALLETS / CREATOR_WALLETSJSON maps: platform id → 0x wallet
RATEunit price (per play / per second / per minute / per citation), micro-USDC
STREAMER_KEYOwncast only: the creator key for the stream
PORTsidecar port (default 8410)
SIDECAR_API_KEYoptional x-api-key gate on the sidecar
MUSICBRAINZ_USER_AGENTmusic modes: enables recording_mbid → artist_mbid → wallet via WS/2 (CREATOR_WALLETS keyed on artist MBID)
MUSICBRAINZ_BASE_URLoverride WS/2 base (point at a local musicbrainz-server in CI)
UPSTREAM_URLimmich-proxy only: the Immich base URL to proxy + meter

Verbatim from the repo's deployment README, which also carries each platform's docker-compose.yml.

Per-platform recipes

PlatformPatternAttach surfaceRecipe
PeerTube published plugin Install the published universal-paywall plugin — per-view support/tips settled on-chain, no PeerTube fork. repo recipe
Owncast event sidecar Register an admin webhook for chat presence events — viewers support the streamer per second watched. repo recipe
Navidrome config redirect Point ND_LISTENBRAINZ_BASEURL at the sidecar — every play pays the artist, per listen. repo recipe
Subsonic (gonic family) config redirect Meter the Subsonic scrobble endpoint — per-play royalties for gonic and other Subsonic-API servers. repo recipe
Jellyfin event sidecar Point the official Webhook plugin at the sidecar — watched minutes settle to the library owner. repo recipe
RSSHub event sidecar A per-citation toll at the crawler boundary — AI agents pay authors when they ground answers in feed items. repo recipe
Immich reverse proxy A transparent reverse proxy in front of Immich meters shared-link photo resolves — a per-resolve license fee. repo recipe
Mastodon external provider Serve Mastodon's donation-campaign slot — instance donations settle on-chain, transparently. repo recipe
MusicBrainz resolver The identity registry that turns a music scrobble into a payable artist — recording MBID → artist MBID → wallet. repo recipe

Verifying your attachment

Each integration page carries its verify command; the general pattern is the on-chain e2e loops (npm run e2e:<platform> -w @universal-paywall/integrations against a local anvil chain). The success check is always the same: after one real platform event from a staked supporter, the payee's on-chain balance increased by exactly rate × units.