Releases: knobcore/musicchain
v0.9.1 — BlockPropagator + dynamic quorum + relay-credit + wallet save
musicchain v0.9.1 — BlockPropagator + dynamic quorum + relay-credit + wallet save-to-file
Core (musicchain):
- Replace SyncManager with BlockPropagator: bitcoin-style block distribution (block.hello / getblocks / inv / getdata / data) over librats typed messages, with DHT bootstrap and per-block DHT announce for multi-source catch-up.
- Dynamic confirmation quorum scaling with peer count: solo = 1, +1 per peer, capped at MAX_CONFIRMATIONS = 5.
- Block.signing_hash() so verifiers check signatures against the header-minus-confirmations hash that producers actually sign.
- Mini-node carries its wallet in mini.hello so the full node can credit the right address on RelayRewardTx via RelayCreditTracker.
Player (musicchain_player):
- Wallet first-launch show-seed step gets a Save to a file button alongside Copy to clipboard (uses file_picker bytes for mobile sandbox, manual writeAsString for desktop).
- Direct librats connect to the home node from LibratsDiscovery so player RPCs route peer-to-peer rather than tunneling through the VPS.
- NDK bumped to 28.2.13676358 to match the :jni plugin.
APK: arm64-v8a only, ~83 MB, signed with the debug keys (replace before production).
v0.2.0 — moderator system, offline play-proof
Squashed v0.2.0 release. See the README for build instructions per target.
What's new since v0.1.0
- Chain-level moderator system (FOUNDER / OP / VOICE) with passphrase founder bootstrap and no on-chain handles.
- Offline play-proof: continuous local heartbeat + network / BSSID / battery / screen-on capture, signed bundle posted via
offline.play_proof.submiton reconnect. Ten bot-pattern heuristics stubbed for the node-side validator. - Player UX: album-play queues the full sorted album, library rows show play count, Connect button long-press disconnects, banner shows full rats peer id + STUN-observed public address.
- Per-target build scripts under
scripts/for all five binaries plus systemd install scripts for the two Linux node modes.
Binaries
| Target | File |
|---|---|
| Windows full node | musicchain-node-windows-x64.zip |
| Windows desktop player | musicchain-player-windows-x64.zip |
| Android player | musicchain-player-android-arm64.apk |
| Linux full node | musicchain-node-linux-x64.tar.gz |
| Linux mini node | musicchain-mini-node-linux-x64.tar.gz |
musicchain v0.1.0-20260610
musicchain — peer-to-peer music with on-chain royalties
I've been quietly building a peer-to-peer music platform for the last
few months. First public binaries are up, multi-container audio support
landed today, and the system finally feels coherent enough to write
about. Here's what it is and where it stands.
The shape of it
Songs live in two places at once. The chain holds a tiny block per
song: a Chromaprint fingerprint, content hash, ID3 metadata, royalty
splits, and a few timestamps. About 3 KB per block — small enough that
a Spotify-scale 100 M-track catalog would weigh in around 310 GB on
chain, same order of magnitude as a portable backup drive.
The audio bytes live with players. When you scan a folder, the
player computes the fingerprint locally and either matches you into an
existing swarm or registers a new block. When you press play on
someone else's track, the chain tells you which peers are currently
serving it and your player pulls the bytes peer-to-peer over librats.
That bisection is the whole trick. The chain is the catalog and the
royalty ledger; the swarm is the CDN.
Containers shipped today
mp3, ogg, flac, m4a, aac, opus, wav, aiff, wma, ape, mka — anything
libmpv decodes, the player scans and serves. Format detection rides on
extension, stamps into a 1-byte enum on the song block, and
round-trips back as the right file extension on download so other
players hand the right bytes to their decoder.
Discovery, online-only
There's no central song registry. The Discover tab is generated live
from "who's connected right now and what fingerprints did they vouch
for." Close the phone app — peers see your songs vanish from their
Discover within seconds. Open it again — they reappear.
The state pipeline runs end-to-end on rats connection callbacks plus a
small delta protocol: an unchanged library re-announces itself in one
96-byte round trip — a SHA-256 digest, no list bytes. New file? Single
swarm.add event. Delete a file? Single swarm.remove. The
"flood every fingerprint on every boot" pattern that the prototype
shipped with is gone.
The mini-nodes — our VPSes — gossip routes and online-state between
themselves over a librats mesh. Stand up another bootstrap VPS, hand it
a --peer-vps flag pointing at any existing one, and the mesh figures
out the rest. No single point of failure on the catalog surface.
Royalty model
Pre-10 000 plays per song (the discovery tier):
- Listener earns 1 token as discoverer
- Serving node earns 1 token
- Artist's 1 token routes to a per-artist escrow, releasable by a
moderator. Quality gate for the first decade of plays.
Post-10 000:
- Artist and serving node each get 1 spendable token
- No discoverer credit
- Listener burns a dynamic amount that scales cubically with total
supply between a 1 B floor and a 2 B hard cap — zero burn while the
network is bootstrapping, exponential pressure as we approach the
ceiling, mint refused entirely past it.
A play counts when timestamped heartbeats prove the listener consumed
at least 50 % of the song's unique timestamp range. Replay-the-chorus-
on-loop earns nothing; only union coverage of distinct seconds counts.
Seeking around still works as expected — listening to seconds 0–60 and
then 90–150 is 120 seconds of credit, not the wall-clock duration.
NAT and transport
librats over TCP today, with a custom keepalive (~30 s dead-socket
detection) and a duplicate-peer-eviction patch for the dial→disconnect
storm we hit when the watchdog re-dialed faster than half-open cleanup.
Cellular peers can't ICE-punch through symmetric NAT on the
US carrier we're testing on, so cellular traffic falls back to VPS
relay — TURN-shaped, with a binary forward path for audio chunks so
relayed downloads don't pay a base64 tax. Direct rats connections still
work on home wifi and most non-cellular networks.
Planned but not in this release: QUIC + libdatachannel ICE signaling
for proper hole punching on phones.
What this isn't
Honest list:
- One moderator. The escrow-release model needs a real council before
it scales beyond hobby use. - No algorithmic discovery. Discover is a live chain catalog filtered
by who's online — no recommendations, no playlists from someone
else's taste graph. - Mobile peer connections relay through VPS on symmetric cellular NAT.
- Search is plain-substring against title / artist / genre / album.
Where to try it
Binaries on the latest GitHub release:
musicchain-player-windows-x64.zip— Windows desktop. Unzip
anywhere, runmusicchain_player.exe.musicchain-player.apk— Android sideload. Needs READ_MEDIA_AUDIO
(Android 13+) or "All files access" for folders outside/Music.
Workflow:
- Create a wallet (one password, auto-loaded thereafter via the OS
keyring). - Open My Library, tap the folder-plus icon, add a music folder.
- Tap refresh — files get fingerprinted on the device and join the
chain catalog. Songs that match existing chain entries swarm-join
silently; new ones queue for the next block. - Switch to Discover. Pick an artist or genre, drill in, pick an
album. The track list opens in the bottom pane (drag the handle to
resize). - Tap a track to stream, or long-press / right-click an album to
download the whole thing into your library.
If you find a song you want to keep, hit download — it'll pull from
the swarm and add to your local library. From there, you serve it too.
That's the entire growth model.
Built solo, in C++ for the home node + VPS mini-node and Flutter for
the player. Comments, issues, and "this crashed when I…" reports
welcome on the repo.