Lapis Net is a fully decentralized peer-to-peer social network protocol on the Kotlin/JVM platform. It is part of the Lapis family of distributed systems, alongside Lapis Cloud.
The protocol combines:
-
Decentralized identity — secp256k1 keypairs, Bitcoin-compatible
-
Content-addressed storage — Nabu (IPFS-on-libp2p), DHT + Bitswap
-
Web-of-trust reputation — Veritas, a shortest-path trust graph
-
Gossip-based propagation — libp2p GossipSub
-
Bitcoin/Lightning-anchored micropayment relevance — Virtus (on-chain OP_RETURN and Lightning BOLT-11 payment proofs)
-
Sybil-resistant free "likes" — Karma, weighted by Veritas and a Bitcoin time anchor
-
Machine-to-machine infrastructure reputation — Madli, a five-metric weighted-median node-reputation layer
The protocol core is deliberately neutral about curation, sorting, and reputation models. Veritas, Karma, Virtus, and Madli (the scoring dimensions) are optional tools for browser/view implementations, not protocol requirements.
Every wave through V0.9 is implemented and merged to master (V0.7 was never
a standalone wave — its scope was folded into the incremental browser growth
of V0.2–V0.5, see docs/roadmap.adoc). Full technical
detail for each module is in the Modules table below; the full wave-by-wave
history — including scope cuts and hardening follow-ups — is in
docs/roadmap.adoc and
docs/architecture.adoc.
| Wave | What it added | Status |
|---|---|---|
V0.1 |
Protocol core: secp256k1/Ed25519 identity, libp2p bootstrap, Nabu (DHT + Bitswap) storage, Veritas (web-of-trust) |
✅ |
V0.2 |
Virtus (LTR micropayment economy, on-chain |
✅ |
V0.3 |
Karma (Sybil-resistant free "likes", Bitcoin time-anchored) |
✅ |
V0.4 |
Genesis-bootstrap, QR-code/deep-link identity linking, keystore encryption at rest (Argon2id + AES-256-GCM) |
✅ |
V0.5 |
Madli (machine-to-machine node reputation, weighted-median aggregation) |
✅ |
V0.6 |
Lightning payment-proof verification ( |
✅ |
V0.7 |
(no standalone wave — folded into V0.2–V0.5’s incremental browser growth) |
— |
V0.8 |
Direct messages (X3DH/Double Ratchet, online + offline delivery, encrypted attachments, acceptance policy, browser UI) and 1:1 voice calls over WebRTC |
✅ |
V0.9 |
Asynchronous messages / mail replacement: encryption, threading, attachments, spam protection |
✅ |
Known, deliberate gaps — not oversights, each documented at the point it was cut:
-
No embedded Lightning node — proof verification only, no payment sending; no BOLT-12 offer publication.
-
NAT traversal is relay-only — no hole punching. A node behind NAT can now be reached: it reserves a slot on a Circuit-Relay-v2 relay and publishes the resulting
/p2p-circuitaddress, and a peer that holds only that address dials it through the relay with an end-to-end Noise session the relay cannot read. Acting as a relay is opt-in and off by default. What is still missing isdcutrhole punching, which would let two NAT’d peers upgrade a relayed connection to a direct one: it is absent fromjvm-libp2pentirely and would have to be implemented from scratch. Every relayed connection therefore stays relayed for its whole life, and relay operators are compensated only in reputation (Madli), not payment. -
No browser control surface for calls (V0.8.7b) — a 1:1 call’s audio runs in the JVM node process; a browser page would only remote-control it, not carry browser-native WebRTC.
-
No group calls, video, multi-device messaging, or MLS — cut from the V0.8 arc’s scope entirely on 2026-08-04, not a partial or stubbed implementation.
-
No delivery receipts or typing indicators for direct messages — deliberately deferred, not built even as stubs.
-
No DHT-based peer/mailbox discovery in the messaging modules —
lapis-net-directory,lapis-net-mail,lapis-net-dmandlapis-net-ratchetpublish and discover over GossipSub. They were built that way because cross-node DHT provider discovery was broken from V0.1.4 onwards. V0.9.8 repaired that at the storage layer —NabuStorage.provide()/findProviders()now work across nodes, andget()fetches a block from a peer it learned about through the DHT alone (seedocs/architecture.adoc) — but migrating those four modules onto it is a separate wave that has not happened yet.
How Lapis Net stands next to the five closest decentralized social protocols — full methodology and sources at net.lapisproject.dev/comparison.
| Feature | Lapis Net | Nostr | Secure Scuttlebutt | Farcaster | Bluesky / AT Proto | Mastodon / Fediverse |
|---|---|---|---|---|---|---|
Genuine peer-to-peer (no relay, hub, or homeserver) |
● |
◐ |
● |
○ |
○ |
○ |
Cryptographic identity instead of an account |
● |
● |
● |
◐ |
◐ |
○ |
Weighted web of trust (transitive trust paths) |
● |
◐ |
◐ |
○ |
○ |
○ |
Bitcoin/Lightning-native value layer |
● |
● |
○ |
○ |
○ |
○ |
Market-based visibility (real value at stake, not a black-box algorithm) |
● |
○ |
○ |
◐ |
○ |
○ |
End-to-end encrypted voice calls |
● |
○ |
○ |
○ |
○ |
○ |
Asynchronous long-lived messaging (e-mail replacement) |
● |
◐ |
◐ |
○ |
○ |
○ |
Machine-to-machine node reputation (infrastructure, not opinions) |
● |
○ |
○ |
○ |
○ |
○ |
● yes · ◐ partial · ○ no
Honest caveat: Nostr, Mastodon, Bluesky and Farcaster each already have millions of users and mature client ecosystems. Lapis Net is, as of this comparison, a working multi-wave prototype (V0.1–V0.9 implemented) without a public network yet — a real trade-off against the table above, not a detail to gloss over.
| Module | Purpose |
|---|---|
|
Base protocol abstractions shared by all other modules. |
|
secp256k1 identity keypairs, Ed25519 dual-key binding for the libp2p peer ID, keystore encryption at rest (Argon2id + AES-256-GCM), and multi-device/pseudonym self-trust linking. |
|
DHT + Bitswap content storage via Nabu. |
|
Veritas (web-of-trust): trust-edge data model, shortest-path scoring algorithm, GossipSub propagation, Nabu persistence. |
|
libp2p node bootstrap, peer identity derivation, mDNS discovery, GossipSub, and the Genesis-bootstrap/QR-code connection flow. |
|
Virtus (the LTR micropayment economy): on-chain (OP_RETURN) and Lightning (BOLT-11) payment proofs, 10%/24h decay, view-specific accumulation. |
|
Karma (free likes): Bitcoin time-anchored, Veritas-weighted Sybil-resistant "like" scoring. |
|
Madli (machine-to-machine node reputation): five-metric observation vector with Veritas-weighted, manipulation-resistant weighted-median aggregation. |
|
Asynchronous messages (the e-mail replacement), fully implemented (V0.9.1–V0.9.4): a signed, addressed |
|
Acceptance-gate machinery extracted from |
|
Signed peer/presence directory records ( |
|
X25519 encryption sub-key and the X3DH handshake (Signal’s Extended Triple Diffie-Hellman, reimplemented from the public specification): |
|
The custom |
|
1:1 audio calls over WebRTC (V0.8.7): |
|
Minimal-Browser — the first real Lapis Net client, exposing Veritas/Virtus/Karma/Madli data, the LTR record-authoring endpoints, a mail inbox UI (V0.9.3), and a direct-message UI (V0.8.6b). |
|
Entry point / multi-node demo harness proving trust propagation end to end. |
./gradlew clean check # compiles, runs tests, runs ktlint
./gradlew :lapis-net-cli:runRequires JDK 25.
-
Code style is enforced by ktlint and checked in CI.
-
Logging uses kotlin-logging:
private val logger = KotlinLogging.logger {}in every file that logs. -
Documentation is written in AsciiDoc; diagrams (once introduced) use kUML via the
kumlAsciidoctor macro — no PlantUML, Mermaid, or hand-drawn diagrams. -
All identifiers (classes, interfaces, packages) are named in English. Domain terms (Veritas, Karma, Virtus, Madli) are the one exception, as they are Latin proper nouns used directly as identifiers.
See docs/architecture.adoc and docs/roadmap.adoc for more.
Apache License 2.0 — see LICENSE.
See CONTRIBUTING.adoc.
