Rust port of Melvin Carvalho's sidestr sidechains, AGPL-3.0-only: the economic engine for did:nostr agents. A did:nostr key is a sidechain wallet.
sidestr is a protocol for user-activated sidechains beside a Bitcoin-family parent. A chain is a JSON document. Its blocks carry a BIP-325 signed challenge instead of proof of work. Coins enter by a peg-in on the parent and leave by a burn the peg holders pay. Nostr relays carry the chain's transactions and its tip announcements.
The protocol, and the reference implementation this repository ports
(siding, with the bitcoin-desktop/schema kernel and
bitcoin-blake/blaketestnode it loads), are the work of Melvin Carvalho.
This repository is a Rust port of them. Where it adds something, it says so.
In a sidestr chain the output key of a taproot coin is a 32-byte x-only
secp256k1 key, and so is a Nostr identity. So an agent that holds a
did:nostr key holds a wallet. It can be paid by npub, spend with the key
its identity already has, and sign the event that carries each payment.
sidestr-agent is that wallet.
Testnet only. Everything here runs beside Bitcoin testnet4 and on experimental sidechains such as
sidestr:dreamlab. Their coins have no value. No real funds exist anywhere in this work.
| crate | what | crates.io | docs |
|---|---|---|---|
sidestr-header |
both header families: stock 80-byte SHA-256d and Knots' 164-byte v2 BLAKE2b; compact targets, powLimit, BIP-325 block data; no_std |
docs.rs | |
sidestr-core |
the chain document, parents table, signed blocks, peg-in claims and peg-out burns, Knots' unified sighash, the parent view, the block file and a mirror's bytes replayed, SPEC 12 records and the assets view, a validating chain | docs.rs | |
sidestr-nostr |
the Nostr plane: NIP-01 events, a sealed signer port, tips (33333, with the peg script), transactions (23500/23501/23503), rule and genesis documents, the round envelopes, estate kinds 38420–38425 | docs.rs | |
sidestr-wallet |
coins, the reference coin selection, key-path spends and burns signed by the parent's family, spends with records, issued assets (issue, transfer), the peg-in shape, delivery | docs.rs | |
sidestr-round |
the level-2 co-signing round and the peg-out PSBT round as pure state machines on the reference's wire, a vote journal, the cosign signer |
docs.rs | |
sidestr-agent |
an agent wallet where the did:nostr key is the wallet: balance, npub → address, spends, burns and asset transfers as kind-23500 events, a peg-in plan, a faucet; the library builds for wasm32 | docs.rs |
The dependencies run one way: core ← header, nostr, wallet ← round
← agent. sidestr-core never depends on sidestr-header.
SPEC 0.0.4 (@sidestr/spec 0.0.6), reference commit
fa86dac.
Ported since 0.0.2:
-
the peg output is the taproot output the peg holders own, at any position (0.0.3);
-
signatures follow the parent's family (0.0.3);
-
the signer announces the peg script with every tip (the
pegtag), and an output paying it is the peg wherever it sits (0.0.4); -
kind 23503 carries a signed parent transaction to a producer with a node (0.0.4);
-
a record is exactly its push: bytes after it or missing refuse it (sidestr/spec#17; sidestr-rs always read it so).
-
Level 1 (one signer): complete. Both header families work end to end: genesis from the document, production, validation, the mempool policy, claims, burns, the block file, the wallet.
-
Level 2 (a k-of-n federation): usable. Blocks are co-signed through the round, interoperating with the reference signer on the wire. Tested with three signers on one box, in both mixes of Rust and JS. Not yet done: a signer on another machine, changing the signer set, and a Byzantine fault-tolerant redesign of the round.
-
Out of scope: the EVM and pool rules, assets as consensus (sidestr-core reads them as a holders' view,
assets), and a trust-minimised peg-out.
The reference engine is the oracle. What is tested:
- Genesis: a throwaway chain's genesis is byte-identical to the one siding
seals. The sealed
sidestr:dreamlabgenesis replays to its documented hash. - Blocks: blocks made here are accepted by siding, and siding's are accepted here.
- Live chain replay: Melvin Carvalho's live
sidestr:txbt4-sidingchain (BLAKE2b parent) replays from genesis to its tip with every rule on. - Records: claims, burns and records read alike; the same blocks give the same records.
- Wallet: its spends and burns pass siding's
Siding.submit(). - Signatures: each engine verifies the other's key-path signatures under the family's rule. With the same auxiliary randomness they are byte-identical, on both families.
- Nostr events: events are byte-identical to siding's, including id and signature.
- Round: Rust and JS co-signers seal the same blocks and pay peg-outs proposed by either engine.
- Audit regressions: independent audits' counter-examples are kept as
tests/audit_regressions*.rs. The 0.0.3 release was verified by GPT-6 Astra before publishing. It re-ran every gate and confirmed each change at its layer against the reference. It compared 103 stock and 104 BLAKE2b block snapshots, including claims, burns and the full UTXO set, and found them equal. It raised four findings, all fixed and pinned astests/audit_regressions_0_0_3.rs.
To run the oracle suites, check out the three reference repositories at the pinned commits and name them:
git clone https://github.com/sidestr/spec && git -C spec checkout fa86dac83d47b8f70195132e91e9dc083e1d9228
git clone https://github.com/bitcoin-desktop/schema && git -C schema checkout b8cbf6337c7450fe14ddc5bce00c7280059aab5d
git clone https://github.com/bitcoin-blake/blaketestnode && git -C blaketestnode checkout d2764d21fe1f8c29b1979e49eb8287a72dd2347e
SIDESTR_SIDING=$PWD/spec/siding SCHEMA=$PWD/schema BLAKETESTNODE=$PWD/blaketestnode \
cargo test --workspace --all-featuresWithout these three variables the oracle halves say they are skipped, and
the Rust halves still run. You need Node.js 20 or later, and no npm install. CI runs both ways (.github/workflows/ci.yml).
sidestr:dreamlab runs beside Bitcoin testnet4 (tbtc4):
- address prefix
drm; - genesis
4db37517728bd509c0cb96ee5a2e3e2a77f9e965a092e9f67948b413d453dbc0, sealed 2026-09-22 (the document is vendored atsidestr-core/fixtures/dreamlab/chain.json); - mirror: https://dreamlab-ai.github.io/sidestr-dreamlab, holding
chain.json,blocks.datandblocks.json.
On 2026-09-23 it ran its first full economic loop:
- a peg-in from testnet4;
- three trades between two agents, each a kind-23500 event signed with the agent's own Nostr key;
- a peg-out paid back on testnet4.
That loop found the two issues SPEC 0.0.3 fixes.
sidestr-rs is the economic layer of DreamLab's agent estate:
- VisionFlow: the ecosystem these components make up.
- VisionClaw: a knowledge graph engine with immersive 3D and XR and embodied agent swarms. It is the flagship.
- agentbox: a sovereign agent
container with
did:nostridentities. These crates were developed there. TheADR-,PRD-andDDD-numbers in the crate docs refer to its decision ledger. - solid-pod-rs: a Rust-native Solid pod server (LDP, WAC, NIP-98).
- nostr-rust-forum: a decentralised Nostr forum, all Rust.
- loom: the ontology node and model façade.
- knowledgeGraph: the public ontology frontend.
- dreamlab-ai-website: the DreamLab website.
AGPL-3.0-only (LICENSE). The reference implementation these crates port is AGPL-3.0, and they are derivative works of it: attributed ports of its logic, tested against it. So they carry the same licence. They are not dual-licensed, and a permissively licensed crate must not depend on them. A network service built from them owes its users the source, as the AGPL requires.
See CONTRIBUTING.md.