upstream

Start

How it works

Every step, and the data that moves in each one.

The actors

ActorHoldsCan
LauncherA normal walletCreate the vault, choose the split and the expiry. May get a small cut.
OwnerControl of the account (bio, description, repo) and a walletProve the handle, get paid, move to another wallet.
AttesterAn Ed25519 keyRead a public page and sign what it saw. Nothing else.
AnyoneNothingRelay signatures, read the vault, recompute any code.

1. Attach

The vault is configured once, when the coin is created:

mint            the coin
target          { platform, id }   id is the platform's own identifier, not the name
launcher        wallet that receives the launcher cut and expired fees
split           streamer / launcher / burn, in basis points, sums to 10000
expiry          days before unclaimed fees go back (default 180)
onExpiry        launcher | burn
trusted         the attesters' public keys
threshold       how many must sign (default 2)
rotationDelay   how long a wallet change waits (default 2 days)

The id matters: names change, ids do not. A Twitch login can be renamed or sold; the numeric id behind it stays. The vault pays the id, not the name. See Platforms for the id each platform uses.

2. Wait

Every time fees arrive, accrue splits them. The launcher and burn shares move immediately. The streamer share is held as pending until a wallet is bound. All amounts are integers (lamports); the streamer share is whatever is left after the other two, so rounding never loses a lamport.

3. Prove

The owner gives their wallet address and gets back a code of the form up1-XXXX-XXXX-XXXX. The code is the first 60 bits of a SHA-256 over the coin, the platform, the account id and the wallet. They paste it where the platform lets only the owner write. No login, no OAuth, no permission is ever requested from the platform.

4. Attest

An attester fetches the public page, looks for the code, and if it is there signs this message with its Ed25519 key:

upstream:v1:attest|<mint>|<platform>|<id>|<wallet>|<code>|<epoch>|<issuedAt>

The epoch is the vault's current binding counter, and issuedAt a timestamp. Together they stop an old signature from being replayed later (see Attesters).

5. Release

claim takes the signatures and the wallet. It checks that enough distinct, trusted attesters signed, that each signature is fresh, that each one is for this exact coin, account, wallet and epoch, and that each code matches. If all hold, everything pending is paid to the wallet, the wallet is bound, and the epoch goes up by one.

After the claim

  • Fees go straight to the bound wallet, no more waiting.
  • To change the wallet, the owner proves the handle again for the new wallet. The change waits two days, and the current wallet can veto it. See Rotation and veto.
  • If nobody ever claims, after the expiry the waiting fees go to the launcher (or are burned, if the coin said so). See The vault.