Concept · 02
Dependency Royalty Streams
When repo A imports repo B, value streams continuously from A's treasury to B's. Measured by usage, not download counts. The whole package graph becomes a cash-flow graph.
In plain English
You build a library. Someone else's app imports it. Their app pays a tiny amount per second into your repo's treasury, automatically, for as long as they keep using it. No invoices, no Patreon, no chasing payments — just continuous value flowing through the dependency graph.
What it is
A royalty stream is a per-second flow of value from a dependent repo to one of its dependencies. Streams are continuous, programmable, and additive — a repo with 1,400 dependents receives 1,400 simultaneous streams adding into a single MRR rate.
This is the missing revenue model for open source. You ship code that becomes load-bearing in someone else's stack. You get paid for as long as they keep importing you.
How it works
Each linked repo declares what it imports (auto-detected from manifests + lockfiles) and how it is used (sampled from usage telemetry beacons that opt-in repos run in CI and prod).
The protocol computes a per-epoch payment from each dependent to each dependency:
stream_rate(A→B) = base_rate
× usage_weight(A→B) // share of A's runtime/CI calls into B
× value_share(A, depth) // discount for transitive distance
× A.royalty_multiplier // A can boost what it pays (PR voluntary)
× B.royalty_acceptance // B can cap what it accepts (e.g., from forks)
Streams settle every 7-day epoch in a single batched call on Base. Continuous internally, batched on-chain — fees stay sub-cent per repo per epoch.
Concrete example
The graph:
calendar-utils ─┐
├─→ date-fp ─→ meeting-bot ─→ acme/app
chrono-utils ─┘
This epoch:
meeting-botmade 4.1M calls intodate-fp. Streammeeting-bot → date-fp= $31.40.meeting-botalso importscalendar-utilsdirectly. Stream = $11.20.date-fpimports bothcalendar-utilsandchrono-utils. Transitive depth = 1. Streams of $8.40 and $4.10.acme/appis private (closed source) and importsmeeting-bot. Higher base rate. Stream = $58.00.
Settlement at epoch close:
- One batched tx on Base distributes all streams in one shot.
- Each recipient's
asset.tomlsplits the incoming stream across its own contributors. - Contributors' credit scores tick for the income they earned.
Total settled: $113.10 flowing through six repos and ~40 wallets in one Base block.
Telemetry, without surveillance
Usage measurement is opt-in and privacy-preserving:
- Beacons batch-report aggregate call counts per import. No payloads. No identities.
- Repos without telemetry fall back to a default rate weighted by stars × commit frequency.
- Closed-source dependents can self-report higher usage if they want to pay more (some do — see "the brand effect" below).
The brand effect
Some closed-source dependents opt to pay more than the metered amount. Why?
- The receipt is public on Base. "We pay our dependencies" is a credible signal.
- Audit trails for procurement: "yes, we fund this critical infra."
- Insurance discounts: paying upstreams above the floor lowers your premiums.
We expect this category to become surprisingly large.
Configuration
# asset.toml
[royalties]
# As a payer (dependent):
multiplier = 1.0 # 1.0 = default rate. Set >1 to pay more.
# As a payee (dependency):
acceptance = 1.0 # cap incoming. 0 = refuse all streams (free forever pledge).
allow_forks = false # do you accept streams from forks? default: no.
Reading a stream on-chain
interface IRoyaltyRouter {
function streamRate(bytes32 from, bytes32 to)
external view returns (uint256 weiPerSecond);
function epochAccrued(bytes32 from, bytes32 to)
external view returns (uint256 wei_);
}
Gotchas
Related
- Balance sheet — where streams accumulate.
- Sleeper pool — payment for repos with low import volume but high stability.
- TypeScript SDK —
ga.stream.subscribe(...)for live UI.
