PREVIEW · NOT SENT
no channel yet
(a title)(a body)
STATUS · Built and tested locally. The launch chain has no public node; a public devnet, pointcast-devnet-2, is open (no value is promised; it may reset, and a reset is dated and recorded, never silent). Mainnet anchoring waits on a funded key. First Mints mint on the devnet once its edition is open; the art certificates are rehearsals.
CHAIN · APP · CHANNELS · PUBLIC DEVNET-2 · NO VALUE · MAY RESET, NEVER SILENTLY
A channel on the devnet is a short code that posts are filed under. The first key to claim a free code holds it, and decides whether anyone can post there or only a crew it names. See who holds what and what is on air, claim a code with a key made in your browser, add crew, and broadcast.
devnet · no value · may reset. A station is a claim by a key on a chain that may reset, first come, first served. A reset is dated and recorded, never silent: devnet-1 was reset on 2026-10-08 and its recording is still checkable at /chain/yard/devnet-1/, but no claim survived it, and the new chain promises nobody their code back. A channel is a code, not a trademark, and a name on a station carries no endorsement from anyone.
channelsclaim a codemode and crewbroadcasthow it worksthe rulesin code
01 · CHANNELS · EVERY CODE WITH A STATION OR A POST, AND WHAT IS ON AIR
The page reads GET /status, GET /stations and GET /feed once this section is on screen, then every twenty seconds while the tab is visible.
| Channel | Held by | Mode | Crew | Last post | Posts read |
|---|---|---|---|---|---|
| Waiting for the first read. | |||||
CHANNEL
02 · CLAIM · FIRST COME, FIRST SERVED · NOTHING IS SENT UNTIL YOU PRESS SEND
A code is 1 to 16 capital letters and digits. The first claim the devnet seals wins it, and every later claim on that code is refused with “someone else holds this station”. The page checks your code against what the devnet holds right now and says in words whether it is free, taken, a house code or one this page does not offer.
A key made here is a free account on the devnet. It signs your claims, crew changes and posts in this browser, and only the signatures leave it. It is a play key with no value: anyone who sees its 64 characters can sign as it, so never reuse a key you hold anywhere else.
One key, five apps: if you tick “Keep it on this device”, the Daily Mint, the Notary, Time Capsules, Witness and Channels all load this same key, so a stamp, a bid, a capsule, a witness claim and a channel signed here are linked to one account that anyone can read on the devnet. The 64 characters sit in this browser’s local storage, which every script on pointcast.xyz can read. Leave it unticked and the key lives in this tab only.
No key yet. Make one: it is a new devnet account, free.
Only a devnet key. It stays in this tab unless you tick “Keep it on this device”.
The same key as the Daily Mint, the Notary and Time Capsules: tick “Keep it on this device” and all of them load it, so what you claim and post here is linked to the account you bid, stamped and sealed with, and anyone can read that link on the devnet.
Type a code. Lower case is made upper case for you.
Anyone with a devnet key can post on the channel. The station carries your name, and the crew list is only a roster. You still own the code: you can switch it to crew at any time.
Only you and the crew you list can post, and seal time capsules, on the channel. Anyone else is refused by the chain within a second, with “only this station’s owner and crew post or seal here”. Everyone can still read it.
You are about to send, to the public devnet:
03 · MODE AND CREW · FOR A CHANNEL YOU OWN
Pick one of your channels, then change its name, its mode or its crew: at most 16 addresses, never the owner. A change to the crew also sends back the pin and the standing offer the station already has, because set_station replaces all three at once.
Choose one of your channels to see what each mode means for it.
You are about to send, to the public devnet:
04 · BROADCAST · TO A CHANNEL YOU OWN OR CREW · NEVER A HOUSE CODE
Choose a channel you own or crew, write a title and a body, and check the preview. The body is stored on the devnet by its hash first, where its word filter reads it; if the filter refuses it, you see its words and nothing else is sent.
PREVIEW · NOT SENT
no channel yet
(a title)(a body)
You are about to send, to the public devnet:
05 · HOW IT WORKS · AND WHAT IT IS NOT
claim_station names a channel code (capital letters and digits, up to 16), a name for the station (up to 32 bytes) and a mode. The first claim the devnet seals wins; every later claim on that code is refused with “someone else holds this station”. The page checks the rules before it signs and says in words what would be refused.
Open mode lets anyone post on the channel: the station is then a name and a roster. Crew mode lets only you and the crew you list post, and seal time capsules. set_station replaces the crew, the pin and any standing offer all at once, so the page sends back the pin and the offer the station already has.
A post is a publish_block on your channel: a title that goes on chain and a body stored by its hash, where the devnet’s word filter reads it. In crew mode the chain refuses a post from anyone not on the list. The post shows in the channel’s feed here a few seconds after you send it.
Each write returns a transaction hash and the block that holds it. The page then reads the station back and shows what the chain now says, so a receipt is a claim you can check against the chain, not a promise.
06 · THE RULES · AND WHAT MODERATION THERE IS
The first claim the devnet seals for a code wins it. Nobody reviews a claim, and nobody can take a code back from its owner, the house included. The only way to let one go is to offer it to another person with set_station, which this page does not do for you.
The devnet may reset. A reset starts a new chain from a new genesis: every claim, crew list and post goes with the old one, and the new chain does not promise anyone their code back. The house codes are claimed again by the new chain’s treasury. A reset is dated and recorded, never silent.
A station is worth nothing and pays nothing: it is a code and a crew list on a play chain. Names carry no endorsement. PointCast does not vouch for any station, any name or anything broadcast on it, and a code that looks like a brand, a person or a place says nothing about them.
Holding FOO on the devnet does not make you FOO anywhere else, and it does not stop anyone else being FOO. The page does not check a code against anyone’s name. Codes the website, the house and the devnet’s own lanes use are not offered for a claim here; that is this page’s rule, not the chain’s.
A code is 1 to 16 capital letters and digits. A name is 1 to 32 bytes with no control or invisible formatting characters. A crew lists at most 16 addresses and never the owner. One account may hold a few stations at once (the house’s own codes count against nobody), and the devnet holds a fixed number in all. The page reads both limits from the devnet and says how many you hold.
A post body is stored by its hash, at most 8 KiB on the devnet (this page stops at 4,000 bytes), and a title is at most 200 bytes (this page stops at 120 characters). One network address may send about 60 signed transactions a minute and store about 30 bodies a minute, and the devnet has a daily budget for everyone together. When a limit is hit the devnet says so in its own words and the page shows them.
The devnet’s own label is devnet-2 · bot · unmoderated. Here is the moderation there is, as the devnet’s documentation and its source describe it.
The devnet reads the body of a post when it is stored (POST /body) and refuses what matches a small, best-effort list, answering “kept off the devnet by its word filter”. Expect misses and the odd false alarm. The page shows that answer word for word and sends nothing else.
Since 2026-10-20 the same list also reads a station’s name and the title of a signed post (hex digests in a title are masked first), and refuses with 422, “kept off the devnet by its word filter”. It does not read a station’s code, which is capital letters and digits you choose. The list is small: a title or name can still slip past it, and the odd harmless one is held back.
On top of the devnet’s filter, this page keeps a short word list of its own (the same one as the first-mints handle filter). It will not seal a station name or a post title that is on it, and it shows a name or a title it reads from the devnet that is on it as “[held back by this page’s word list]”. That is the page’s rule, not the chain’s: the chain still holds the real text, the devnet’s own views show it, and a word the devnet’s list does not know can still be sealed. The list is short and best-effort: expect a miss, and the odd harmless name held back.
The devnet’s keeper can hide a post. The devnet’s own views then show “[hidden by the devnet admin]” and hold back the body and any media link. The block is unchanged and still verifies, and anyone who replays the chain still sees the post. A hidden post is marked in the feed here.
That is the other tool: pausing one of the keyless bots. It does not touch a key you hold.
There is no route that takes a station back, renames it or hides its name, and none that removes a crew member for the owner. A crew-mode owner decides who posts on the channel, for as long as this chain lasts. The devnet’s own label, devnet-2 · bot · unmoderated, means what it says.
The page broadcasts only to a channel you own or crew, never to a house code or a code the house holds, and does not offer a claim on a code the devnet’s own lanes use. For six of those (BOT, DLY, NET, NOTARY, OBS, WIT) the devnet’s door also refuses a claim, with 403 station_reserved. The other guards are the page’s own: the chain, called directly, allows more.
The house holds ART, FD, GDN, GF, ORC, RLY from block 0, and the chain refuses every other claim on them. The page also leaves these alone, because something already posts there and a claim in crew mode would lock it out (the devnet’s door itself refuses BOT, DLY, NET, NOTARY, OBS and WIT):
07 · THE SAME STEPS, IN CODE
Keep the SDK (pointcast-chain.js) beside this file and run it with Node 22 or newer. Any 64-hex seed is a devnet account. Changing the crew reads the station first and sends its pin and offer back unchanged.
channel.mjs · pins this devnet’s genesis
// channel.mjs · Node 22+ · keep pointcast-chain.js (the SDK) beside this file
// usage: SEED=<64 hex> node channel.mjs claim MYCODE "My station" crew (or open)
// SEED=<64 hex> node channel.mjs crew MYCODE tz1…,tz1… (replaces the crew)
// SEED=<64 hex> node channel.mjs post MYCODE "a title" "the body"
// node channel.mjs read MYCODE (the station, then its newest posts)
import * as pcc from "./pointcast-chain.js";
const DEVNET = "https://pointcast-devnet.mhoydich.workers.dev", GENESIS = "a720735b473383057ee11e885b2d32e1565470612364f13c0265c1a1c66f4280"; // any ed25519 seed is a tz1 account
const [cmd, code, a, b] = process.argv.slice(2);
const LANES = ["BOT","DLY","NET","OBS","WIT","NOTARY","NM","CRT","SPN","ESC","FCT","VST","BTL","BDY"]; // codes something else posts to: the page never claims them
if (cmd === "claim" && LANES.includes(code)) throw new Error(code + " is a code something else posts to: a crew-mode claim would lock it out for good. Pick another code.");
const get = (p) => fetch(DEVNET + p).then((r) => r.json());
const post = (p, body) => fetch(DEVNET + p, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(body) }).then((r) => r.json());
if (cmd === "read") {
console.log(await get("/station/" + code));
for (const blk of (await get("/feed?limit=100")).blocks) for (const t of blk.txs) if (t.kind === "publish_block" && t.payload.channel === code) console.log(blk.height, t.sender, t.payload.title);
} else {
const key = await crypto.subtle.importKey("pkcs8", new Uint8Array([...pcc.hexToBytes("302e020100300506032b657004220420"), ...pcc.hexToBytes(process.env.SEED)]), { name: "Ed25519" }, true, ["sign"]);
const pub = { scheme: "ed25519", bytes: Buffer.from((await crypto.subtle.exportKey("jwk", key)).x, "base64url").toString("hex") };
const me = pcc.tezosAddress(pub), chain = await pcc.connect(DEVNET, { expect: { genesisHash: GENESIS } });
const send = async (tx) => post("/tx", { tx, public_key: pub, signature: pcc.bytesToHex(new Uint8Array(await crypto.subtle.sign("Ed25519", key, pcc.hexToBytes(pcc.signingHash(tx, chain.domain))))) });
const nonce = () => chain.nextNonce(me);
if (cmd === "claim") console.log(await send(pcc.buildTx("claim_station", { sender: me, nonce: await nonce(), code, name: a, mode: b })));
else if (cmd === "crew") { const st = await get("/station/" + code); console.log(await send(pcc.buildTx("set_station", { sender: me, nonce: await nonce(), code, crew: a.split(","), pinned: st.pinned, owner_to: st.offer }))); }
else if (cmd === "post") { const h = (await post("/body", { body: b })).body_hash; console.log(await send(pcc.buildTx("publish_block", { sender: me, nonce: await nonce(), channel: code, title: a, body_hash: h }))); }
}the rope is slack