(The protocol is Vulpine; Fwetch, 4chain and Breddit are readers on it. On the wire, records are tagged fwetch- - permanent, historical, not the name.)*
curl -O https://vulpinenetwork.com/starter/vulpine-reader-starter.zip unzip vulpine-reader-starter.zip && cd starter npm install && npm start
Open <http://localhost:3000>. That is a real site on the network: the posts are real, from the chain, and if you connect a wallet and post, every other reader sees it.
A reader inherits the network rather than starting one. Already on chain, shared by every site that speaks the protocol:
$handle, their user number, their reputation, their things.yoursite.fox, resolved without DNS.You write what makes your site yours: what it looks like, what it shows, and who it is for.
Everything else is decoration.
Read. No key, no account, no permission:
const { posts } = await (await fetch('/api/feed?limit=30&board=all&sort=new')).json();
Who they are. The library finds the wallet and asks:
await FwetchSign.connect(); const address = FwetchSign.address();
Write. The wallet signs, a protocol host pays the network fee, the record lands on chain:
await FwetchSign.post('hello');
Every record carries the app that wrote it, and readers choose what to recognize:
/api/feed?app=my-reader only what was written through your site /api/feed?board=K one board /api/feed?board=all the whole network
A post written into a board travels; a post written on a timeline is marked scope: local and stays home. That is how two readers share threads without sharing each other's chatter.
1. A front end - the starter. Minutes. It leans on someone else's index, which is why it is instant.
2. Your own index - an afternoon. Run a protocol host (SETUP.md in the server package) and point VULPINE_UPSTREAM at yourself. Nothing else changes, because the records are the same records. Now nobody can turn your site off.
3. Your own house, publisher and ads - a weekend, and now it is a business:
FWETCH_SITE_PUBLISHER) makes ads bought on your site yours: you keep 80%, the protocol takes 20%, and your board owners and posters are paid out of your share;The same shape throughout - FwetchSign.<thing>:
FwetchSign.name.register('yoursite.fox', 'https://your-host'); FwetchSign.market.list({ title, price, kind: 'good' }); FwetchSign.wiki.write('camera-obscura', 'Camera obscura', text); FwetchSign.classified.post({ title, category: 'for-sale', location, price }); FwetchSign.tartary.found('800000.41'); FwetchSign.vote(pollTxid, choice); FwetchSign.tip(postTxid, 10000);
Each is a signed record in a transaction. A reader that does not know a record ignores it; a reader that does, shows it. Nobody needs permission to write one, and nobody can be stopped from writing one.
Every reader checks the same things at index time, which is why a record from a site you have never heard of is safe to show:
The test every part of this passes: could another application use it without us? If the answer is ever no, that part is built wrong.
A tod is an application that installs onto the Vulpine desktop from the chain: one JSON file holding a manifest and a page, talking to the wallet through six calls and nothing else. Anyone can publish one to the Den and anyone can foxhole install it. Tods is the developer guide.
Gekker is the protocol's own language: one statement a line, its words are the bridge, a program can greet somebody and write to the chain and nothing else. The Workshop in the wallet compiles it as you type. Gekker.
A tod is also a website on the chain: point a .fox name at tod:<name> and the page is served from the inscription, sealed, with the name claim as its certificate. Publish once; install it or visit it.
A fox buries what it wants to keep and digs it up later. Cache keeps a document (an AI handoff, a to-do list, a skill file) on the chain, encrypted, under a name, and gives you one line to paste into any chat:
cache:<name>#<key>.<write>
The name finds the newest version, the key unlocks it, the write token lets a chat bury a new version. Treat the line like a password. The page is at <https://cache.gekker.lol>; encryption happens in the page (AES-GCM, a random 256-bit key), and the house inscribes the ciphertext with the map { p: 'fwetch-cache', name, version }. Any reader that indexes the chain knows every cache by name.
The routes, which a chat uses:
GET /api/cache/<name> — the newest version: { version, ts, ciphertext }, ciphertext as base64url of a 12-byte IV followed by the AES-GCM output. ?version=N for an older one. Add ?key=<key> and the reader decrypts with the key in the request and returns { text }; add &format=text for the bare text. The key is used once and never stored, but in this mode it does pass through the reader; without it, the reader only ever sees ciphertext.GET /api/cache/<name>/versions — the history.POST /api/cache { name, ciphertext, write? } — bury. The first time a name is used a write token is minted and returned once; after that the token must match. A version is at most 300 KB. Rate-limited by address; no sign-in. The house pays the inscription for now.Code for both modes, in Python and JavaScript, is on the page.
Holding a Pixel Fox is recognised on the network without the collection's say-so, because a fox is a 1Sat ordinal and the ordinals index says who holds one. A holder (any of their linked addresses) gets the pixelfox flag on every post, once earned kept; may read and write the chat room foxes, which is not listed, reached by name (/join foxes in fox irc, say foxes "…" in the terminal, and it appears in Chat's rooms for holders); and may found parcels in the foxes' district, district 1, the block after Genesis (FWETCH_FOX_DISTRICT on the reader). Founders' seats found there too.