L0 development
Evidence level: Implemented capability. CoNET-SI implements POST /post,
hop forwarding, mailbox storage, labeled SSE pools, presence,
acknowledgements, and UDP relay. Persistent application streams and web3://
are application compositions over those primitives; SI does not parse
their business objects.
Public site: https://gitbook.conet.network/developers/l0.html
Layer Minus is a permissionless decentralized cloud. Anyone may use it. Participants join by offering CPU / GPU, forward traffic, and storage, and earn GB. Your application chooses wallets, encryption targets, and the object inside the envelope. SI forwards OpenPGP armor by key ID. It does not parse Chat JSON, mine epochs, or move tokens.
Build as if every node can be malicious. Combine privacy routing, fragmentation, and client-side crypto. Do not give one host plaintext or a whole reconstructable object. That is the path to privacy-first communications, storage, compute, and decentralized AI: independent wallet-addressed roles, private application paths, and micropayments designed so no single party owns the stack. Thesis: Permissionless cloud and zero-trust applications. Product direction: Privacy-first Decentralized AI (whitepaper).
Start here
| Page | Use it for |
|---|---|
| Permissionless cloud and zero-trust applications | Who may join, GB rewards, fragmentation, and why no node is trusted |
| How to use Layer Minus | The application loop and the combinations that already exist |
| SI developer guide | Live /post contract, command catalog, and TypeScript samples |
| CoNET Chat developer guide | CoNET Chat envelopes, mailbox_listen, dual receipts, presence, call offers, wake receipts, voice channels v2 and v3, listen health, history, and group V1 fan-out |
| UDP frame forwarding | User-PGP subscribe + AES frames |
| Persistent application streams | Historical reference. Its L0 attachments (l0_listen / l0_connect) were removed from SI on 2026-10-31 |
| Peel, hop-sig, and listen timeouts | Wrap-to-C listen: peel plaintext, hung SSE, forward <clientIP> |
web3:// Application Protocol |
Cross-platform locator, caller-signed requests, correlated encrypted responses, persistent streams, and host adapters |
Read the SI guide before writing a new client. Read the Chat guide only if the product is mailbox messaging or a typed Beamio control message on the same path.
What you call
Your client
├─ EOA wallet + user OpenPGP + selected mailbox
├─ encrypt business JSON to recipient user PGP
│ or encrypt a signed command to a route PGP
└─ POST { data: <OpenPGP armor> } to a healthy entry
└─ SI reads key ID → forward or decrypt once
| Piece | Role |
|---|---|
| CoNET-SI | HTTP/HTTPS /post, SI-to-SI HTTP :80, mailbox, SSE, UDP relay |
| AddressPGP | L1 binding of an EOA to user PGP and a mailbox route |
| GuardianNodesInfoV6 | Public node list: domain, IP, route public key |
| Your application | Schema, UI, retries, and what a payload means |
Public node source: CoNET-project/CoNET-SI · npm @conet.project/mvp-si. Chat composition: chat-sdk.
Wire contract (do not invent another)
POST /post HTTP/1.1
Host: {domain}.conet.network
Content-Type: application/json
{"data":"<OpenPGP armored message>"}
- Client → entry: HTTP or HTTPS. HTTP is sufficient because the body is already ciphertext.
- SI → SI: HTTP
:80only. - Host
{domain}comes from GuardiangetAllNodesfieldPGPKey. Do not invent a subdomain. - For Chat, listen, ACK, presence, and UDP: pick entry A ≠ B / C ≠ B. Do not default-dial mailbox B.
- Business and mailbox-work armor must encrypt to exactly one OpenPGP encryption key ID. Multi-recipient armor is rejected (
rejected_multi_recipient_armor). Chat group V1 is N independent single-recipient posts — see Group chat V1. - HTTP 200 or an SSE handshake is transport progress, not application delivery.
Full samples: discover nodes, register a route, encrypt a command, Chat listen.
Application protocols built on L0
web3:// is a cross-platform application
protocol using L0 infrastructure. It composes the existing /post, entry,
mailbox, and encrypted-session primitives; it does not add an SI command.
Use one source for each concern:
- Applications —
web3://: product model and platform choices; web3://Application Protocol: normative URI, envelope, signature, response, stream, and failure contract;- CoNET-project/web3Url: browser client implementation; and
- Developers —
conet-l0d: Linux server/client runtime.
A conforming implementation still follows the L0 invariants above: exact
wallet resolution, user-PGP business encryption, entry-to-mailbox routing,
HTTP JSON limited to { "data": "<OpenPGP armor>" }, and fail-closed
identity and authorization checks.
Specification synchronization
Any change to the web3:// grammar, envelope fields, signing domain,
encryption target, route selection, Entry contract, response shape, storage
boundary, or browser lifecycle must update the
Applications page, the
protocol page, and affected runtime
guides in the same change set. Changes to the underlying L0 wire contract must
also update the relevant L0 protocol and SI developer pages before release.
Three families
| Family | Encrypt to | SI behavior | Typical use |
|---|---|---|---|
| Opaque business | Recipient user PGP | Forward and store. No business decrypt. | Chat text, typed JSON, udp_subscribe, and application stream offers or frames. Sender receipts use this as the inner armor. |
| Signed command | Target route PGP | Decrypt once and run the command | Chat listen, mining listen, ACK, presence, UDP relay, SilentPass |
| Mailbox work | Mailbox B route PGP wrapping { data: innerArmor, NoPush?: true } |
B unwraps the inner user-PGP armor; NoPush skips APNs. HTTP is still only { data }. |
Sender beamio_chat_delivery_receipt_v1 |
Do not mix targets. Business JSON encrypted to mailbox B lets the mailbox read it. A listen command encrypted to a user key never reaches B. Do not put NoPush / beamioNoPush on the HTTP JSON. Wire samples: SI developer guide — mailbox work.
Chat module
CoNET Chat is relationship-private communication infrastructure on Layer Minus, not a social silo. Applications get wallet-addressed envelopes, mailbox delivery, receipts, presence, and optional encrypted-history recovery without placing the user’s contact graph in a centralized messaging database. After a fragment is decrypted, the chat module keeps that plaintext in a Worker-local corpus. UI reads it through history.read and does not download the same fragment from IPFS again. Product thesis: CoNET Chat. Wire: CoNET Chat developer guide.
Chat is an application composition, not an extra L0 protocol.
Its central field-visibility rule is easy to test: from / sender EOA is
inside the signed application envelope and that complete envelope is encrypted
to the recipient user PGP. The sender wallet address and the sender PGP key
must not be copied into /post, a hop header, a mailbox command, push
metadata, or relay logs. Only the recipient learns them after decrypt.
The sender PGP private key never leaves the sender device. Entry A sees the
client IP but not the sender wallet or sender PGP key; mailbox B sees the
destination route but receives the transport connection from A. The key id
visible on the ciphertext is the recipient key id. This separates IP
observation, wallet routing, and message content without claiming that IP
metadata disappears.
Every inbound chat message uses the same rule. The session peer and bubble
sender are the EOA recovered from the EIP-191 signature, not a wallet or
@BeamioTag copied from the JSON. BeamioTag is a lookup of that recovered
address. A message whose signature cannot be recovered is dropped. A message whose recovered signer differs from its claimed from is kept under the recovered signer and shown with a warning that names the claimed address.
- Pending row
{ sendId, from: "me", text, createdAt }. - EIP-191
signMessage(text)on the outer envelope. Inbound:verifyMessagerecovers the sender. That recovered address is the sender; a different claimedfromis only a warning.voice_call_offer_v1addscallerSignatureover a canonical text that excludes identity fields; it must recover the same EOA. Then look up@BeamioTagfor that address. Do not display a tag or wallet taken from the payload. base64(JSON)→ encrypt to the recipient EOA user PGP → wrap as mailbox work (the web app does so since PWA 0.52.930) to the recipient mailbox B route PGP → POST to one random entry that is neither mailbox; the next entry only after a clear failure. Browser clients usehttps://{domain}.conet.network/post. In the native apps the Chat SDK signs, encrypts, picks the entry IP and postshttp://{ip}/post; the page calls the SDK'ssendand never names the URL.- Recipient listen:
command: "mailbox_listen"to own mailbox B, HTTP/SSE via C ≠ B (with a freshstreamKey; every frame is sealed and must be opened before parsing). In the native apps the Chat SDK holds this listen with its stored keys. Epoch / listing heartbeats prove the SSE is alive, not that a Chat message was forwarded. B must not expire a healthy writable listen by wall-clock age. - After ingest, send both
gossip_delivery_ack(B route PGP) andbeamio_chat_delivery_receipt_v1(sender user PGP, then mailbox-work wrapNoPush: trueto the sender’s mailbox B). - Presence is
wallet_online_queryonly. Ignore chainrouteOnline. After that answer, CoNET Chat sendswallet_native_wake_query. Encrypt it to the contact mailbox B route PGP andPOST { "data" }to an entry node C ≠ B. Do not connect to B: that entry hop is what keeps the querier's IP off the destination mailbox. B returns booleannativeWakeable(truewhen a registered iOS, Android, Windows, Linux, or macOS shell can be woken). A failed lookup does not clear the last trusted flag, and the response has no device token. Both queries carry the querier's wallet (known limitation, to be solved withweb3://). - Resolve
@BeamioTagwith an exact match. Never takesearch-usersresults[0]. - Voice uses
voice_message_v1: AES-256-GCM audio ciphertext is uploaded as an IPFS fragment in ordered 512 KiB chunks; the recipient-only manifest carries the fragment hash and decryption material. The gateway boundary is 256 MiB, and playback/object URLs remain local and ephemeral. - Real-time voice calls are separate from
mailbox_listen. The caller sends the signed offer, encrypted to the callee user PGP, only to the callee's mailbox:voice_offer_storewithpush: 1, through a random entry. That mailbox stores it and rings its own user; a killed-app native SDK fetches it withvoice_offer_fetchand decrypts it locally. Media uses voice channel v3: each side opens avoice_listen(v: 3, write keywk) on a relay it chooses, signed by a temporary wallet and authorized by the paying callee, and chunks areCVC2binary literals (locator, HMAC, padded AES-GCM blob) with every per-frame field inside the ciphertext. Call control (cancel, decline, timeout, hang-up) travels as ordinary Chat messages through the mailbox. Since 2 November 2026 every node refuses v2 listens and v1 frames and ignores the oldvoice_listenwake fields (targetWallet,offerArmor). Released clients use the v3 format and payer signatures; payment, metering and charging are not implemented. See the Chat developer guide.
Clients decrypt chunks first and then reorder by the sequence numbers inside the ciphertext; the relay never reorders or decrypts. Each chunk goes through a different random entry. Verify the command, push request, SSE frame, and logs received by each node.
Copy-paste envelopes: CoNET Chat developer guide.
Other compositions
| Product | L0 primitives | Developer note |
|---|---|---|
| UDP frames | User-PGP udp_subscribe; route-PGP listen / relay |
Do not put Securitykey in a B-decryptable command |
| Real-time voice | voice_offer_store to the callee mailbox; temporary voice_listen (v3, temporary-wallet and payer signatures); CVC2 chunks; voice_offer_fetch |
Separate voice session pool; never occupy normal Chat SSE; native SDK decrypts offers locally |
| Persistent application stream | — | Removed from SI 2026-10-31 (l0_listen / l0_connect close the connection) |
| SilentPass | Route-PGP SilentPass / SaaS_Sock5* |
Product admission and path rotation are application-owned. Not L1 geth/beacon peering |
| Mining collector | command: "mining", omit listenKind, often direct to the target SI |
Infrastructure exception — see Participate in mining |
web3:// |
Existing entry/mailbox routing plus caller-signed requests, correlated encrypted responses, or application-owned duplex sessions | Protocol · Linux runtime. Do not invent duplex_*, p2p_stream_*, or listenKind: "l1p2p" as SI commands |
Higher privacy: split routing and app wallets
An app may register AddressPGP and sign listen / ACK / presence with a routing EOA, and keep sender / recipient EOAs only inside the encrypted business object. Mailbox B and hop GB then see the routing wallet, not the payment or display wallet. This is an application composition. L0 does not enforce it. Do not fund the routing wallet from the app wallet on-chain if you need that unlink. Full table: wallet-addressed peer identity.
Rules that break clients
- Chat listen uses
mailbox_listen. Amininglisten withoutlistenKindis classified as mining; the legacymining+listenKind: "chat"pool receives no Chat. Amailbox_listenwithoutstreamKeyis refused. - Same-node inner PGP after one decrypt is an attack: SI emits socket
endand does not peel again. - Hop signatures cap at 3. Application clients do not set
X-CoNET-Hop-Sigson the first/post. - After a local peel, hop-sign the inner UTF-8 armor string (prefer peel plaintext; coerce
Message.armor()). Hop-sign or C→B connect failure is a fast 404. A log-onlyuncaughtExceptionthat leaves the SSE open is a clientconnect_timeoutwith B never dialed. - Start the ~12s listen
connect_timeoutafterfetch. Emitlisteningonly onres.ok+ body. Exclude the failed C domain on reconnect. - SI
forward <ip>after peel is the client source IP, not mailbox B. Do not treat “switch C” as the first fix for a fleet-wide peel crash. - A fake-PGP 404 (
body has not PGP message) is an intentional reject, not proof that SI is down. - Do not take
search-usersresults[0]as the encrypt-to EOA. - Do not log private keys, full private PGP, UDP
Securitykey, mailboxstreamKey, voice write keys, or application-session AES keys. - Do not put the app sender / recipient EOA on the hop header or in a plaintext SI command if you split wallets.
Related protocol pages
- L0 overview
- Permissionless cloud and zero-trust applications
- Mailbox routing
- Persistent application streams
- Peel, hop-sig, and listen timeouts
- X-CoNET-Hop-Sigs v1
- Security limits
- Node and client roles
Next
SI developer guide → · CoNET Chat developer guide → · web3:// protocol → · Linux runtime →