upstream

Concepts

Proof of handle

How a string in a bio proves who gets paid, and why copying it does nothing.

Why a bio

A bio, a channel description and a file in a repo share one property: only the owner of the account can change them. Anyone can read them. That is exactly what is needed: a public place that only the owner can write to, readable by a machine with no credentials.

Compared with "log in with the platform":

  • No OAuth app to register with four platforms, no secrets to protect.
  • No permission is asked from the owner. Nothing can be read or posted on their behalf.
  • Anyone can re-check a proof at any time by opening the same page.

The code

code = "up1-" + crockford32( sha256( "upstream:v1|code|" + mint + "|" + platform + "|" + id + "|" + wallet ) )[0..12]
        formatted as  up1-XXXX-XXXX-XXXX

Crockford base32 skips the letters that look alike (I, L, O, U), so a code survives being read aloud. Twelve characters are 60 bits: nobody can guess a code for a wallet they do not control.

Why it is bound to the wallet

This is the part that matters. The wallet is one of the inputs. So:

  • The owner posts the code for their wallet. The page is public, so anyone sees it.
  • An attacker copies it and asks the vault to pay the attacker's wallet. The vault computes the code for that wallet, gets a different string, and the attesters (reading the same page) do not find it. Refused.
  • The attacker cannot ask the attesters to sign for the owner's wallet either: that would pay the owner.
Tested

The test suite checks that the code changes when any one of mint, platform, id or wallet changes, and that an attester will not sign when the code on the page belongs to another wallet.

Why the id, not the name

Handles can be renamed, abandoned, then taken by someone else. If the vault were bound to "twitch.tv/name", whoever grabbed the name next could claim. It is bound to the platform's own stable id instead (see Platforms), and the id is also part of the code. A new owner of an old name has a different id and a different code.

How the code is matched

Matching ignores case, spaces and dashes, so a code that a platform reformatted still counts. The page must contain the whole code. A partial or altered code does not count.

What if the code is removed afterwards

Nothing happens to funds already paid. The bound wallet keeps receiving fees. The proof is needed to bind a wallet and to change it, not to stay bound. If an account is later compromised, the attacker would need the code for their own wallet on the page, a two-day wait, and no veto from the real wallet: see Rotation and veto.