Run a Snapchain read node on a server you rent, and post from a client that talks only to it. No API keys. No one's permission.
node scripts/provision.mjsssh … "curl …/node.sh | sudo bash"node fc.mjs init --node <your-server>Tested end to end on mainnet, October 2026: a node synced from scratch, then the first cast sent through it.
A node synced from scratch on a rented server, then every client command went through it to the real network.
Full transcript · 59-second video, music by Kevin MacLeod (CC BY 4.0)
Plus a few hours while the node syncs on its own. You'll need Node.js 20 or later, an Azure, AWS or Hetzner account, and a Farcaster account with storage and its recovery phrase.
git clone https://github.com/Sats100M/farcaster-in-3
cd farcaster-in-3
az login # or aws login, or HCLOUD_TOKEN in .env
node scripts/provision.mjs --provider azureIt shows the price and asks before creating anything: a 4 vCPU, 16 GB server with a 2 TB disk and the Snapchain ports open. Then it prints step 1 for you.
ssh -i ~/.ssh/farcaster_node azureuser@<server-ip> \ "curl -fsSL https://raw.githubusercontent.com/Sats100M/farcaster-in-3/main/scripts/node.sh \ | sudo bash -s -- --fid <your-fid>"
Installs Docker and the official Snapchain node and starts syncing. The first sync downloads a 470 GB snapshot and takes several hours. Run fc-node-status on the server to watch it.
cd client && npm install node fc.mjs init --node <server-ip>
Asks for your recovery phrase once, uses it to give this client its own app key, then forgets it. After that:
node fc.mjs feed node fc.mjs cast "posting from my own node" node fc.mjs follow dwr node fc.mjs like 3/0x… node fc.mjs feed --hide-app <app>
Treat your recovery phrase like rm -rf. It controls your account. Only paste it into software you've read or trust. This client uses it in memory to sign one message and never stores or sends it. You can check: it's one file.
Trying it for the first time? Use a test account. And when an app offers delegated signing, where you approve its key from an app that already holds your account, prefer that: the phrase never leaves your phone. This client asks for the phrase only because a fresh server has no app to approve from.
Finished? node scripts/destroy.mjs deletes everything, and billing stops.
Farcaster splits a social network into three layers, run by different people. If one app bans you or disappears, your account, followers and casts are still there.
Your account number, the wallet that owns it, and the storage you've paid for.
Every cast, like and follow, each one a small signed message kept by every node.
The feed you scroll and the button you press. Including the client in this repo.
Your account number, issued by the ID Registry contract on Optimism. Usernames like @dwr are a separate label that points to it.
The Ethereum wallet that owns your FID, derived from your recovery phrase at m/44'/60'/0'/0/0. It can transfer the account and add or remove app keys, so you use it to authorize things, never to post. The client finds your FID by asking your own node which account your custody address owns, so no Ethereum RPC or API key is needed.
Every message takes space on every node, so accounts pay rent, in yearly units on Optimism. One unit holds roughly 5,000 casts, 2,500 reactions and 2,500 follows. Go over and the oldest are pruned. Accounts made in the Farcaster app usually include storage; this client can't post for an account without it.
Snapchain orders and stores every message. A small, known set of validators propose and vote on blocks. Read nodes run the same software with read_node = true, keep the full state and serve the same APIs. Anyone can run one.
So a success from your node means accepted and relayed, not yet included. Under heavy load a relayed message can get lost and need sending again.
Apps never post with your custody key. Each gets an app key: an Ed25519 key that can sign messages for your FID and nothing else.
Since mid-2026, adding one is free. There's no Optimism transaction: the client sends a KEY_ADD message straight to Snapchain with three signatures.
This client's key can post, delete casts, react and follow. It can't add keys or touch the account. It expires after 30 days unused, and every use resets the clock.
Every app key records the FID of the app that asked for it. So your node knows which app every cast came from, without trusting the app.
node fc.mjs apps dwr # which apps someone posts from node fc.mjs feed --only-app <app> # just that app node fc.mjs feed --hide-app <app> # everything but
Snapchain wants 4 cores, 16 GB of memory, a public IP and ports 3381 to 3383 open. And disk: the snapshot alone is 470 GB compressed, kept while it unpacks. Use 2 TB.
It wraps the official installer from farcasterxyz/snapchain. It mounts the data disk and keeps the database there, answers the installer's prompts up front so it works over SSH, and adds fc-node-status to show sync progress. A weekly job keeps the node upgraded.
fc-node-status # on the server curl http://<ip>:3381/v1/info # from anywhere
Azure. New subscriptions need Compute registered, and the script does it. Free trials allow 4 vCPUs per region, exactly enough. Sizes often sell out, so the script tries others.
AWS. Free-plan accounts can't launch servers this size. Accounts made with the new Projects setup also block EC2 and Lightsail until advanced features are turned on.
Hetzner. The cheapest, once your account is established. New accounts can't create a 2 TB volume yet.
New accounts usually come with credit, so a day of trying it is often free.
| Provider | Per month | Per day |
|---|---|---|
| Hetzner, CX43 with 2 TB | $176 | $5.80 |
| AWS Lightsail, 16 GB with 2 TB | $289 | $9.50 |
| Azure, D4s v4 with 2 TB | $294 | $9.70 |
The API starts after the snapshot is restored. Run fc-node-status on the server, and make sure port 3383 is open.
Snapshots are replaced every day, and the node reads the download list for every shard before it starts. If the first sync takes long enough, a shard's snapshot is gone by the time its turn comes, so the node skips it and replays that shard from the beginning, which takes weeks. fc-node-status warns about this and prints the fix: reload-shard.sh --shard N, which fetches today's snapshot for just that shard and swaps it in. It took about an hour for shard 0.
Another key was added for your account at the same moment. Run init again.
Give it a few seconds. If it never appears, the relay was dropped under load. Post it again.