upstream

Concepts

Platforms

What Upstream reads on GitHub, YouTube, Twitch and Kick, which id it binds to, and what can go wrong.

At a glance

Id usedProof textLive status
GitHubrepo:<id> or user:<id>file .upstream on the default branch, or account bion/a
YouTubechannel id (UC...)channel descriptionunknown
Twitchnumeric user idchannel bioyes, with viewers
Kicknumeric user idchannel bioyes, with viewers

What you can type

Links, short links and bare handles with a prefix all work:

twitch.tv/name        https://www.twitch.tv/name        twitch:name
kick.com/name         kick:name
youtube.com/@name     youtube.com/channel/UCxxxxxxxxxxxxxxxxxxxxxx
github.com/owner/repo github.com/owner/repo.git   github:owner

Names are validated against each platform's own rules before anything is fetched.

GitHub

Two kinds of target. A repo (owner/repo) is proven by a file named .upstream at its root on the default branch. Writing a file there needs write access, so it proves the person is a maintainer. An account (owner) is proven by the bio.

The engine reads api.github.com, which allows browser reads. Without a token GitHub allows 60 requests per hour per IP address; the engine reports rate_limited if you hit it.

pump.fun's own app already supports sending fees to GitHub accounts. Upstream adds repos and the same proof for the other three platforms.

YouTube

The code goes in the channel description. In a browser, YouTube blocks reads from other sites, so the page uses the official Data API with a key you restrict to your domain (put it in config.js). In Node, the CLI reads the public /about page and needs no key at all.

An id is a channel id (UC followed by 22 characters), found by the handle or given directly.

Twitch

The code goes in the channel bio. The engine reads the same public GraphQL endpoint the Twitch web player uses, with the handle passed as a variable (never pasted into the query text). It returns the numeric id, the bio, followers, and whether the channel is live now with its viewer count.

Not an official API

That endpoint is public and widely used, but Twitch has not promised to keep it. If it changes, Twitch reads will fail with a clear error until the adapter is updated. This is the most fragile of the four.

Kick

The code goes in the channel bio. The engine reads Kick's public channel endpoint, which returns the user id, bio, followers and the live stream if any. Kick sits behind a bot filter that sometimes refuses browsers; Node reads it reliably.

The live badge

Twitch and Kick tell us whether a channel is live. The app shows it next to the profile. It has no effect on money: it is information, and the vault never looks at it.

Adding a platform

An adapter is one function that takes a target and returns a profile: stable id, name, avatar, proof text, live state. Add it to src/engine/platforms.mjs, add tests with the platform's real response shape, and the rest (codes, attestations, the vault) works unchanged.