Vulpine is a set of records on the BSV blockchain and a small number of rules for reading them. fwetch.lol, 4chain.wtf and Breddit are readers. Anyone can write these records from any wallet, index them with any software, and show them however they like. This document is the authority: where the code and this document disagree, this document is right and the code has a bug.
On the name: record tags on the wire are prefixed fwetch- — the first reader was Fwetch, and identifiers written to a blockchain are permanent. The prefix is not the protocol's name, any more than app.bsky.* is the AT Protocol's. The protocol is Vulpine. Any BRC-100 wallet works with it; the Vulpine wallet is one.
Everything on chain is the protocol. The index, the house, the chat server and the user interface are a service — one implementation — and are not.
(For the practical guide — API, SDK, embeds — see BUILDING.md.)
Records are OP_FALSE OP_RETURN outputs with two pushes: a tag and a UTF-8 JSON payload; or, for tokens, 1Sat Ordinals inscriptions carrying a MAP metadata block. Payload fields not listed here are ignored. Unknown tags are ignored. A record whose payload does not parse is ignored.
Numbers in payloads are JSON numbers. Timestamps (t) are Unix seconds. Transaction references are 64-hex txids; outpoints are txid_vout (in MAP) or txid.vout (in payloads) — readers must accept both.
A member is a secp256k1 public key, the identity key (BRC-42 derivation [0, 'fwetch identity'], key id '1', counterparty anyone). Every signed record carries pub (33-byte compressed hex) and sig (DER hex) over the canonical JSON of the payload with sig removed and keys sorted.
A member may declare that other addresses are theirs (where their ordinals live) with a signed fwetch-link record listing them. A reader treats a member's identity address, its linked addresses, and any address that holds a coin the member signed for as one member.
Anonymous records carry no pub and no sig. They are attributed to nobody. A reader may accept a sponsor's vouching (§7.3) for facts about an anonymous record that the sponsor verified out of band (a flag, a per-thread tag), but never for identity.
A $handle is a name bound to an identity key: fwetch-name { name }, signed. Names are 3–20 characters of a–z 0–9 _, compared case-insensitively and shown as claimed ($Rodsirloin). The earliest claim in chain order holds the name; a claim on a held name is nothing. One name per identity (the whole linked set counts as one). { name, un: 1 } releases it; a released name stays reserved for its previous key for thirty days.
A handle is never a coin and cannot be sold — it is how people point at you, and everything that is about you (reviews, votes, reputation) points at the key behind it. Compare a number (§4), which points at a seat and is meant to change hands.
Three things, no overlap: about you → the identity and its handle; owned by you → a coin (a number, a board, a piece); allowed to you → a permission flag; earned by you → a badge.
A User Number is a 1-sat ordinal inscription whose MAP carries:
app=fwetch type=ord p=fwetch-handle number=<N> v=<FWONK_VERSION>
collectionId=<series collection id> series=<series name> (see §4.3)
The inscription content is the coin's image. A GLB model may be referenced.
OP_RETURN tagged fwetch-burn retires the coin.A reader must recognize at most one number per identity key, the earliest. A key that mints again does not gain a second number. Numbers may still be held in any quantity by transfer or purchase; the rule is about minting.
A series is a collection that strikes number coins.
series=fwetch, the Challenge Coins collection) is the original.(series, number) — a person may hold Fwetch #340 and FoxSite #12. Readers show their own series first and other series as collectibles.A series is recognized only if it is registered: a Series coin exists for it (§6.2). Unregistered series are ignored — their coins are ordinary inscriptions, not numbers.
All payloads carry p naming the record type and t. Signed records carry pub and sig. Every record should carry app — the reader that wrote it (fwetch, breddit, …) — and may carry scope: public (the default; any reader may surface it) or local (meant for its origin app; other readers following this document do not surface it). Scope is the poster's choice. Identity, numbers, memes, boards and ads are never scoped.
tag / p | fields | notes | ||
|---|---|---|---|---|
fwetch-post | b body (≤280 chars), reply parent txid, board slug, img image ref, meme meme txid, flag code, anon 1, pid poster tag, tr thread nonce | a post; a reply is a post with reply; a reply lives on its parent's board | ||
fwetch-like | post txid | one per member per post (kept for compatibility; fwetch-reaction is the general form) | ||
fwetch-reaction | post txid, kind | like and dislike are defined; other kinds are allowed. One per member per post per kind. Each reader honours the kinds it chooses | ||
fwetch-repost | post txid | |||
fwetch-delegate | number, add[], remove[] | signed by the number's holder; lets those keys post as the number (§5.2) | ||
fwetch-vote | poll, then choice \ | commit \ | the encrypted envelope | a vote (§5.3) |
fwetch-reveal | poll, choice, salt | opens a sealed vote after close | ||
fwetch-tally | poll, trustee, parts[] | a trustee's partial decryption, with proofs | ||
fwetch-profile | name, pfp (b://txid or ord://outpoint), banner, bio, dh (number to show), ca (coin address), flag | latest signed one wins; a field left out keeps its saved value, so a partial record never wipes a picture. dh must be a number the signer's wallet holds, or readers show the lowest it holds | ||
fwetch-link | addrs[] | address linking (§3.2) | ||
fwetch-transfer | number, to | informational; the spend is the transfer | ||
fwetch-burn | outpoint | in the same tx as the 1-sat spend; retires the piece or coin | ||
fwetch-pin | room, sha, body, by | a pinned chat message, on chain | ||
fwetch-award | code, to | a flag given by hand (curator, or a board's owner for its own flag) | ||
OPENAD1 | op=book, id=AD_PROTOCOL_ID, slot, minutes, image, url, alt, price, board | an ad booking; payment in the same tx (§9.3) |
Image references are b://<txid> (B protocol) or an ordinal outpoint.
reply; its replies share its board.>>N in a body refers to post N on that board.pid) is an 8-character tag consistent for one person within one thread and different in every other thread. Signed posts: base64(sha256(identityAddress + ':' + threadTxid))[0..8], computed by the reader. Anonymous posts: the same construction with the thread's public nonce tr (minted by the OP and carried on it) in place of the txid, computed by the poster and carried as pid; the reader stores it as given.A poll is a post carrying poll: { options[], closes, mode, who }. Votes are fwetch-vote records; one per identity per poll, the first in chain order; votes after closes are ignored. who is anyone, numbers (holders of a number), board (members of the post's board) or flag.
Three modes, one envelope:
{ poll, choice }, signed. Public as cast; live tally.{ poll, commit: sha256(choice + ':' + salt) } during the vote; fwetch-reveal { poll, choice, salt } after close. Hidden while it matters; every reveal checkable against its commitment; a reveal that does not match is ignored.tallyKey, registrarPk and trustees[{i, name, pk}]. A ballot is { poll, mode: 'encrypted', tokenMsg, token, cts[], proofs[], sumProof }: one exponential-ElGamal ciphertext per option under the tally key, a zero-knowledge proof that each encrypts 0 or 1, and one that exactly one encrypts 1. Eligibility is a blind Schnorr token from the registrar over a one-time voting key — the registrar issues one per identity and never sees the key it signs, so a ballot cannot be traced to a person. Readers verify every ballot from its bytes. After close, each trustee publishes fwetch-tally { poll, trustee, parts[] }: its partial decryption of every option's sum, with a DLEQ proof against its key. When all trustees have reported, the counts follow. No single ballot is ever decrypted — not by the operator, not by the trustees. The crypto is one dependency-free file (vox.js) run identically in the browser and the reader.The holder of a number may name other identity keys as delegates with a signed fwetch-delegate record; a later record from the holder revokes. A delegate's signed post carrying as: <number> is shown as that number (name, picture, flag); readers record the real signer. Delegates may post, reply, react and repost as the number; they may not transfer the coin, change its profile, or delegate onward.
Everything that can be owned in the protocol is a 1-sat ordinal coin. Ownership is holding. Selling the coin sells the thing.
MAP: p=fwetch-board slug=<SLUG> boardName=<name> series=Board collectionId=<Challenge Coins>. The holder owns the board /SLUG/: moderates it (hides posts), may make it private (members are addresses the owner lists, or holders of the board's membership flag), makes its flag, pins its threads, and receives the board's share of ad revenue (§9.3). /FG/ (General) is a board with a coin like any other, but may not be private and is not for sale.
MAP: p=fwetch-series name=<series> mode=lite|hard collectionId=<the series' collection>. Registers a series (§4.3). Minted by the protocol's house to the buyer; priced by the publisher (§9). Status: specified; indexer support follows.
The Library is one collection, forever; no reader starts its own. A meme is an inscription in the Library collection with MAP p=fwetch-meme, an optional supply (open edition when absent), and royalty in basis points. Claims are 1-sat outputs of the meme's edition; the inscriber is the creator for royalty purposes (§9.2) — provenance, not authorship.
A generative collection: layered variants with weights, pieces rolled from a seed. Piece MAP: p=fwetch-piece collectionId number traits seed rarity royalty. No two live pieces of a collection share a trait combination; a burned piece frees its combination and restores one to the supply.
Flags are inscriptions to the holder's address (p=fwetch-flag code=<code>), awarded by rule (a reader's own rules, e.g. "posted 100 times"), by a curator, or by a board's owner for that board's membership flag. A post may fly one flag the poster holds; otherwise the reader may show the poster's country.
The reference reader's seats: #1 is the creator; #1–#5 are the founders; #6 is the moderator. Protocol revenue lands with #1; the founders' shares (10% each to #2–#5, FOUNDER_SHARES) are paid from the house on settlement and published (/api/founders/settlements). Seats follow their coins.
The protocol records who holds what — #1, $rodsirloin, a janny flag. Each reader decides what that means on its own site. The reference reader's configuration makes the holders of #1–#3 its founders and #4 its moderator; another reader may name its own seats by number, by handle, or by key. No reader is the admin of another. Founders configure their reader (featured boards and collections, banners, hand-awarded flags, jannies) and mint boards free.
Holders of the janny flag may hide posts and memes from this reader. A hidden record is still on chain; other readers decide for themselves.
A reader may run a house: a wallet that pays the fee for members' records so that posting, minting a number, claiming a meme, and pinning cost the member nothing. A house-paid record is identical on chain to a member-paid one, except that the first input is the house's. A reader may vouch, via a house-paid record, for facts it verified about an anonymous poster (their chosen flag; their poster tag) — readers accept the vouch only when the first input is a known house's.
The house is a convenience, not a requirement: every record can be written by the member's own wallet.
"Earlier in chain order" means: lower block height first; within a block, lower index first; unconfirmed records are ordered by first-seen time by the reader and re-ordered when they confirm. A reader must re-evaluate rules that depend on order (number claims, duplicate memes) when confirmation changes an order it assumed.
Every paid action carries its fees as outputs in the same transaction. A reader recognizes the action only if the outputs are there. That is the enforcement: no fee output, no recognition.
"The publisher" is the holder of #1, resolved on chain at index time — the revenue follows the coin.
Rates are a single table published by the reader (/api/ads/rates, adrates.js). This is the current one:
| action | who is paid |
|---|---|
| minting a number, posting, replying, liking, claiming a meme, minting a meme | free (house pays the network fee) |
| meme aftermarket sale | seller; inscriber royalty (MAP royalty, default 5%); publisher 4.2% |
| collection mint | creator 58%, publisher 42% |
| collection aftermarket sale | seller; creator royalty (MAP); publisher 4.2% |
| ad on all boards | publisher 100% at booking; then 30% to board owners and 10% to posters, settled by attention (§9.3) |
| ad on one board | that board's owner 30% and publisher 70%, both in the booking tx |
| board coin | publisher (1 BSV; curators free) |
| series coin | publisher (lite and hard priced separately) |
A sale of a coin, meme edition or piece is a transaction spending the listed 1-sat output with outputs: the item to the buyer; the price to the seller; the publisher's fee; the creator's royalty. A purchase missing the fee or the royalty is not recognized as a sale (the listing is not marked sold; the item's holder is still tracked by the chain, which is the truth either way).
An OPENAD1 booking is recognized only if the booking transaction pays the publisher at least the rate for slot × minutes, and — for a booking with board — pays that board's owner at least the owner share. Impressions for all-boards ads are counted by the reader, one per member per day per ad, per board and per post beside which the ad appeared; only signed sessions count. Settlement pays the board and poster shares in one transaction and is published (/api/ads/settlements) so the split can be checked against the chain.
One set of records that Amazon, eBay, Etsy and Facebook Marketplace are all readers of. Anything sellable is a listing; every purchase is an order whose payment is in the same transaction; the rest is the life of that order. The rules live in market.js, dependency-free, run identically by readers and browsers.
| record | fields | rule |
|---|---|---|
fwetch-listing | kind (ordinal, good, digital, service), title, body, imgs[], price (sats), qty, category, tags[], condition, variants[{name, price, qty}], ship{from, to[], cost, days}, escrow, aff_bps, expires, auction{reserve, end, min_inc}, outpoint, digital{sha256, size}, replaces, shop | signed by the seller; an ordinal listing must name an outpoint the seller holds; replaces retires an earlier listing |
fwetch-delist | listing | the seller withdraws |
fwetch-offer | listing, amount, message | a haggle |
fwetch-accept | offer | the seller takes it; an order may then be placed at that price |
fwetch-bid | listing, amount | an auction bid: at or above the reserve, at least min_inc over the high bid, before end; the highest at end wins and orders at that amount |
fwetch-order | listing, qty, variant, affiliate, offer, escrow, ship_to (encrypted to the seller), note | the payment is this transaction (§9.5.1); a sold-out or expired listing, or a losing bidder, is not an order |
fwetch-fulfil | order, tracking, carrier, note, payload (digital goods: encrypted to the buyer) | seller only |
fwetch-receive | order, note | buyer only; releases escrow |
fwetch-dispute | order, reason | either side |
fwetch-resolve | order, to, split | the arbiter (the publisher) only |
fwetch-review | order, rating 1–5, body | one per side per order; buyer rates seller, seller rates buyer |
fwetch-shop | name, about, policies, ships_from, logo, banner | a storefront; listings reference it |
Questions on a listing are replies to it. Favourites are reactions (fav). Wishlists and carts are reader-side.
For a listing, a quantity and an optional variant, affiliate and price (offer or winning bid), the outputs a payment must contain are fixed:
unit × qty + shipping − affiliate, to the seller's address — or to the escrow output when the listing asks for it;4.2% of unit × qty + shipping;aff_bps of the goods, to the referrer the order names, when the listing declared one.Short any output and the transaction is not an order. Sats may exceed.
A listing is priced in BSV (satoshis) or USD (cents) and names the rails it accepts: bsv, usd, or both. The quote converts to the rail being paid on at the reader's posted rate (/api/rate, sats per dollar) and stamps the rate and the time.
pay: { rail:'usd', processor, ref, amount, currency, listing, qty, variant, buyer, rate, by, sig }, signed by the app that ran the checkout. A reader accepts dollar orders only from apps it trusts (its own house, plus FWETCH_TRUSTED_APPS); the attested amount must cover the quote. A dollar order is as true as the app that vouched for it — a different kind of truth than the BSV rail, and the protocol says so. Receipt captures the held charge; a resolution for the buyer cancels it.The chain never holds dollars. It holds the listing, the order, the fulfilment, the reviews — the record — while the money moves on whichever rail moves it best.
A bare 2-of-3 multisig: buyer, seller, arbiter (the publisher's identity key). Release is buyer + seller to the seller; refund is seller + arbiter (or buyer + arbiter after a resolution) to the buyer. The arbiter alone cannot move it; neither party alone can. Ordinal sales never use escrow: the item and the money change hands in one transaction.
Reviews are records; a reader computes a seller's (and buyer's) count, average and positive share from them. No reader owns a reputation.
Every layer added after the social records reuses one shape: fwetch-assert { type, parent?, payload }, signed. The txid is the stable id. An edit is an assertion with a parent; a revision by the same author (or a linked address) marks its parent superseded, and the parent chain is the history. Nothing is ever replaced. A revision by anyone else is kept as a rival claim and supersedes nothing. Readers decide their own edit window (30 minutes for social posts, open-ended for a wiki): inside it the revision is the current version, outside it a late revision, and either way the record stands.
.fox)A name is an ordinal, so ownership and transfer come free: whoever holds the satoshi owns the name, and a transfer is an ordinary spend the indexer already follows.
| record | fields | rule |
|---|---|---|
fwetch-domain | name, target, inscription | the claim; first valid write in chain order wins, a later claim on a held name is nothing. name is label.tld, lowercase |
fwetch-retarget | name, target | re-point; only the holder of the satoshi, checked at index time |
target is a hostname, a URL or a txid — a reader fetches it and renders the page; ICANN is never consulted. A resolver exposes /api/name/resolve/:name; a gateway on an ordinary domain does the same lookup for visitors in a normal browser. Squatting is a policy at issuance (auction, renewal, reserved names) and must be settled before registration opens, because it cannot be retrofitted.
The Library has two wings. The Reading Room holds text; the Gallery holds images. The rule is the same in both: the address is the content, written in the library's alphabet, with a locality prefix in front so that things which are nearly the same sit nearly together. Nothing is stored; an article or a picture is found, not uploaded, and it has the same address in every reader, wallet and indexer that computes it.
An image coordinate is G<room>.<wall>.<shelf>.<volume>:<bytes>. The prefix comes from a perceptual hash — a 9×8 grayscale thumbnail, each pixel compared to its neighbour, 64 bits. The room is the broad shape (the top 16 bits), so a re-save, a recompression, a shrink or a caption lands in the same room and usually on the same shelf; a different picture lands elsewhere. Identity is exact-coordinate; "this already exists" is a hash within ten bits. The meme library is the Gallery's first collection. /api/babel/gallery/locate computes an upload's coordinate and lists what already sits near it.
An address space in which every article already exists. It saves no storage and is not meant to — a 20KB article has a ~20KB coordinate. What it provides is that the address is a fact about the text rather than a name someone chose, and that an edit lands nearby, so a reader can walk from one version to the next.
<room>.<wall>.<shelf>.<volume>:<body> 238,328 rooms · 62 walls · 62 shelves · volume by length
The prefix comes from a minhash over word 3-grams — the few rarest grams in the document. A typo destroys only the grams it touches, so it moves at most one component and the address stays in the same room; a rewrite moves all of them. body is the text itself, so a coordinate decodes back exactly, and a coordinate whose text does not derive its own prefix is valid but not catalogued. One dependency-free file, run identically in a browser, a reader and an indexer — the coordinate must be the same everywhere or the library has different addresses in different places.
Two structures, never conflated: an article's lineage through time, and the descent graph between subjects.
| record | fields | rule | ||
|---|---|---|---|---|
fwetch-article | subject, title, coord, parent? | a revision marks its parent not-current; the newest in a lineage is what a reader shows | ||
fwetch-edge | subject, predicate, object | typed predicates only — links-to (a [[link]] in a page), derives-from, subclass-of, participates-in. Untyped edges turn the graph to mush and are ignored | ||
fwetch-edgestate | edge, state | canonical \ | disputed \ | superseded. Disputed is the default: a claim does not become consensus by arriving, and two live claims stand side by side |
fwetch-endorse | target, weight | the endorser is recorded apart from the amount, so a reader can count distinct endorsers rather than satoshis |
Edges point at subjects — stable ids — never at article content, so rewriting or splitting a page cannot move the subject out from under an edge. Descent is a braid, not a tree: convergence is the normal case. A reader exposes the frontier — subjects an edge points at with no article yet — because visible gaps are where the graph funds its own construction.
Open problem, stated rather than papered over: if canonical status follows endorsement weight, the biggest spender rewrites history. That is why the endorser and the amount are separate fields. Weighting by distinct endorsers, expiring canonical status, and challenge-with-escrow are candidates; none is settled, and this is the highest-risk piece in the protocol.
A listing that expires, contacted through an identity rather than an email.
| record | fields | rule |
|---|---|---|
fwetch-classified | title, body, category, location, price, currency, imgs[], expires, parent? | flat categories: for-sale, housing, jobs, gigs, services, community, wanted, free. A revision by the author supersedes |
fwetch-renew | listing, expires | the author only, and only forward |
fwetch-report | target, reason | a moderation signal. A reader may hide; nothing is erased from the chain |
Expiry is a timestamp in the record: past it, a reader drops the listing from active views but the record stands. Contact is the identity — the encrypted DM relay already in the protocol (§10) — so no phone number or email ever appears in a listing.
A world derived from the chain: you don't build it, you found it. Every district that will ever exist was generated the moment its block was mined.
<height>.<index>.| record | fields | rule |
|---|---|---|
fwetch-deed | parcel, inscription? | founding. First in chain order takes it; a parcel in a block that is not mined yet is refused. A reader may charge for founding (FWETCH_DEED_PRICE, paid in the claim's own transaction; the holder of #1 founds free) — off by default, and the lever against mass-founding when it is needed |
fwetch-build | parcel, place[], parent? | the founder or a live lessee. Each entry is {at, footprint, kind, binds, scale} |
fwetch-lease | parcel, to, until, scope | build rights without ownership; expiry returns them and what was raised stays in history |
The deed is an ordinal: send it and the land changes hands, with everything built on it intact.
binds is the point. A founder binds things they already own into the plot — a .fox name becomes a storefront that opens the site, a board becomes a clubhouse, a classified becomes a shop with real inventory, an article becomes a library. Tartary is not a metaverse with nothing in it; it is a spatial index of the protocol.
The protocol defines the slot — a structure of footprint X at position Y, bound to object Z, at scale S — and never the model, the texture or the art. Specifying visuals would make the protocol a game engine and lock the world to one look. Nine clients can render the same plot nine ways and agree on what is there.
fwetch-app { name, url, icon?, kind } — an application for the desktop, published by anyone. An application runs in a window on the desktop; a site opens in the browser. That line is the distinction between what the network is (chat, the map, names, the Library, a game, a drawing tool) and what people host (a site at a .fox name). Readers list applications from /api/apps and may hide what they do not want shown.
fwetch-tod { name, outpoint, version?, about?, needs[] } — a claim on a name in the Den, the registry of applications. A tod is one inscription: a JSON file with a manifest and a page (see Tods). The claim names the inscription. First claim in chain order holds the name; the holder, or any address linked to them, may claim again with a new outpoint to publish a new version. A claim is checked against the inscription before it is believed: an outpoint that does not hold a tod of that name claims nothing. needs is what the tod may ask a wallet for: read, who, sign, pay, store, open. Readers serve the Den at /api/tods and /api/tod/:name.
A tod written in Gekker, the protocol's own language, carries its source (gekker, lang: "gekker-1") beside the page, so a later host compiles it again from the words (see Gekker).
A .fox name's target is one of: a web address; an IP; app:<id> (opens a wallet application); page:<id> (its page); tod:<name> (a tod in the Den); ord:<outpoint> (any inscription). The last two are websites on the chain: a wallet fetches the page from the inscription and shows it in a sealed frame, so nothing serves it and nothing can change what the name shows except a signed retarget by the holder. The name claim is the certificate.
Several coins on chain may claim the same number: old designs the protocol no longer reads, and re-mints after a retirement. Readers answer /api/coins/verdicts?outpoints=… with real, old, duplicate, not-a-number or unknown per coin. A wallet may let a person burn old and duplicate; it must never burn real or unknown.
Ordinals are listed to applications as BRC-100 basket 1sat, laid out per BRC-147 (tags ordinal, origin, type:…, collection:…; outpoints in underscore form). Provenance follows BRC-150 and BRC-159: a wallet proves an ordinal's origin from the transactions and merkle proofs alone and believes no index. Readers publish their own health at /api/indexer/status, with the reason when the indexer is not running.
A block never changes, so a district is derived once and kept. A reader's surveyor walks the chain from genesis forward in the background at a pace the block source tolerates, so the map fills outward whether anyone asks or not; anything asked for first is fetched on demand. /api/tartary/map returns what is surveyed immediately and says how many districts in the window are still coming (missing), so a renderer polls until it is zero.
The byte ranges and thresholds decide what land people found, so they are published (/api/tartary/derivation) and versioned: tartary-1. A change is a new derivation and a new world, never an edit to this one.
One finding worth recording, because any reimplementation will hit it: a block hash is not uniformly random at the front — its leading bytes are the proof of work, and the number of zeros grows as difficulty rises. Reading climate from the head makes every district a glacier and drifts the world as the chain ages. tartary-1 seeds climate from a mix of all 32 bytes, which is uniform across all 25 biomes and stable forever.
Chat is off chain by design. Messages are signed by the identity key so authorship is real; direct messages are ciphertext between two identity keys (BRC-100 encrypt, protocol [2, 'fwetch dm'], key id = room id) that the server cannot read. Rooms mirror boards; a private board is a private room. Pins are on chain (fwetch-pin). Chat is part of the service layer: another reader may run its own, federate with this one, or omit it.
BUILDING.md).@fwetch/sdk (the public/sign.js layer): connect a BRC-100 wallet, sign and write every record type, read feeds.signin.js (connect with your number), memes.js (the Library as a widget: browse, claim, post, contribute), ads.js (a slot on your page; bookings pay you and the publisher), and trollbox.js.Plug and play is: use the embeds and the public API. More work and more control is: run a reader and register a series.
Specified in outline so builders know the direction; not yet in the reference reader. Each is one OP_RETURN payload like the others.
| record | for | shape | |
|---|---|---|---|
fwetch-follow | Facebook, Tumblr, YouTube subscriptions, MySpace top friends | `{ addr \ | number, un: 1?, rank? }` |
fwetch-post with tags[], imgs[], to | DeviantArt tags, albums, MySpace wall posts, Tumblr asks | fields on the post record | |
fwetch-repost with b | Tumblr reblog-with-commentary, quote-tweets | body on the repost | |
fwetch-media | YouTube — a large file the chain points at (BCAT chunks or an off-chain URL with a hash) | { sha256, size, type, src } | |
fwetch-list | playlists, reading lists, galleries | { name, items[], op } | |
fwetch-event | Facebook events | { title, when, where, body }; RSVP is a reaction kind | |
fwetch-tip | creator income on any site | a payment output to the post's author plus the publisher's cut, referencing the post | |
profile theme | MySpace / Tumblr custom pages | a field on fwetch-profile pointing at a CSS record |