Post with an app key
Cast from a test account through your own node with a gasless app key.
Add an app key to a test account from the app on your own computer, then post, like and follow through your node.
You need:
- A test Farcaster account and its recovery phrase. Read What the app does with your recovery phrase first.
- Node.js 22.12 or later (22.x, 24.x or 26+) and this repo on your computer.
- Your node from the Full run, and the HTTPS address that
deploy-client.shprinted.
Why run the app on your own computer
Section titled “Why run the app on your own computer”Add the key from the app on your own computer at localhost. The address deploy-client.sh prints is usually <ip-with-dashes>.sslip.io, and sslip.io is a DNS service someone else runs. Whoever controls that DNS, or the server, could serve a changed page that sends your recovery phrase elsewhere. A page served from localhost comes from files on your own disk, built from code you can read.
The local dev server passes /v1 requests on to your node’s HTTPS address, so you need no SSH tunnel, and ports 3381 and 3383 stay closed. The add-key steps show a Check the address warning whenever the app is not on localhost.
What the app does with your recovery phrase
Section titled “What the app does with your recovery phrase”The code is in client/src/signer.ts:
- Your browser makes a new ed25519 app key.
- The browser uses the phrase once to sign one gasless
KEY_ADDwith your custody address. There is no transaction and no gas. - Nothing stores, logs or sends the phrase. Only the signed
KEY_ADDgoes to your node. - The app key is saved in this browser’s
localStorage. Remove from this browser deletes it there; the key stays valid on the network until it expires.
JavaScript cannot promise that the browser has wiped the phrase from memory.
What the app key can and cannot do
Section titled “What the app key can and cannot do”| The app key can | The app key cannot |
|---|---|
Post casts (CAST_ADD) | Move money or sign transactions |
Like and recast (REACTION_ADD) | Delete casts, unfollow or edit your profile; the app does not ask for those scopes |
Follow (LINK_ADD) | Approve or cancel other keys (KEY_ADD and KEY_REMOVE are never scopes) |
| Work until it expires: 7 days by default (pick 1 day for a test), 90 at most, renewed each time it is used | Keep working after your custody address cancels it |
SECURITY.md has the full list.
1. Run the app locally
Section titled “1. Run the app locally”From the repo folder, start the app. Put your node’s HTTPS address in SNAPCHAIN_NODE_URL:
cd clientnpm ci --ignore-scriptsSNAPCHAIN_NODE_URL=https://<your node> npm run devLeave it running. You should see ready and Local: http://localhost:5317/. Ctrl-C stops it.
npm ci installs the exact versions in package-lock.json. --ignore-scripts stops packages from running their own install scripts. The app builds and its tests pass without them.
Open http://localhost:5317. The status at the top should say Connected to your node; Details shows the version and how far behind each shard is. To see your feed, type your FID or username under Enter your FID to see your feed and press Show my feed.
The app uses port 5317, not Vite’s usual 5173, because a browser keeps one localStorage per address and port. If 5317 is taken, npm run dev stops with an error instead of moving to another port.
The page’s Content-Security-Policy lets it connect only to its own address, so a changed library cannot send data elsewhere.
2. Add an app key
Section titled “2. Add an app key”Before you type the phrase, check that the address bar shows exactly localhost:5317, close other tabs, and turn off clipboard history and screen sharing.
In the post box at the top (To post, add an app key first.), press Add app key. A dialog walks you through 4 steps:
- What an app key is: press Next.
- Before you start: read it. There must be no yellow Check the address. box; if there is, you are not on
localhost, so stop. Press I understand, continue. - Sign and send: type the test account’s recovery phrase (12 to 24 words) under Recovery phrase. If you paste it instead, clear your clipboard afterwards: clipboard history and sync tools can keep a copy, and the app cannot clear it. Under Key expires after, pick 1 day for a test (the default is 7 days). Press Add app key. You see Signed for FID with your FID, then Sending to your node. If it shows another FID, the phrase belongs to another account.
- App key added: the phrase field is gone. Press Close or Write a cast.
From the phrase, the app works out your custody address, asks the node which FID that address owns, and reads currentUserNonce. Then it signs one gasless KEY_ADD and submits it.
The App key card shows Waiting for your node, then Active when GET /v1/signer returns the key. The app checks every 4 seconds. Post only after it says Active; a cast sent earlier is rejected and marked Failed.
Check it from the terminal:
curl -s "https://<your node>/v1/signersByFid?fid=<your-fid>" | jq '.currentUserNonce, [.signers[] | .source]'currentUserNonce should be one higher than before, with one more signer in the list.
The app key is saved in the browser for localhost:5317 only, so post from the local app. The copy at your HTTPS address has no key, and adding one there means typing the phrase into a page served through sslip.io (Why run the app on your own computer).
3. Cast, follow, like
Section titled “3. Cast, follow, like”| Action | Where | Message type |
|---|---|---|
| Cast | Type in the post box at the top (New cast as FID …), press Post (a standard cast, up to 320 bytes) | CAST_ADD |
| Follow | In Settings, Follow someone: type an FID in FID to follow, press Follow | LINK_ADD (type follow) |
| Like, recast | The heart and repeat buttons under each cast | REACTION_ADD |
A new cast shows first in the feed, with a state badge. Every message also shows up in the Sent panel (right column, or the Settings tab on a narrow window) with the same state:
| State | Meaning |
|---|---|
| Sending | The app is sending it to your node |
| Waiting for a block | The node accepted it and sent it on |
| Retrying | Not seen yet, so the app sent it again |
| Confirmed | The node returns it |
| Failed | Still missing after 4 sends, or the node rejected it |
A failed message shows the reason and a Retry button. Your node passes messages on explains these states.
The app can only add. It has no button to delete a cast, unfollow or unlike.
4. Look for it in another app
Section titled “4. Look for it in another app”Open your profile in any other Farcaster app. The app does not show hashes; ask your node:
curl -s "https://<your node>/v1/castsByFid?fid=<your-fid>&pageSize=1&reverse=true" \ | jq '.messages[0] | {hash, text: .data.castAddBody.text}'Remove the key
Section titled “Remove the key”- Remove from this browser (Settings, App key) deletes the key from this browser. The network still accepts it until its lifetime runs out.
- This app cannot revoke keys yet. When it says your account’s wallet can revoke the key, it means a
KEY_REMOVEmessage signed by your custody address and sent to a node, which is how a gasless key is cancelled. Removing a key through the KeyRegistry contract does not apply to it. This guide has no tested way to send aKEY_REMOVE, so pick a 1-day expiry for a test key and let it run out.
When you are done on localhost, press Remove from this browser, so no other page on localhost:5317 can read the key later. Then stop the dev server with Ctrl-C.