{"skill":{"slug":"unzipped-skill","displayName":"Unzipped Skill","summary":"Create Farcaster accounts and post casts autonomously. Official skill from the Farcaster team.","description":"---\nname: farcaster-agent\ndescription: Create Farcaster accounts and post casts autonomously. Official skill from the Farcaster team.\nmetadata: {\"openclaw\":{\"emoji\":\"🟣\",\"requires\":{\"bins\":[\"node\",\"npm\"],\"env\":[]},\"install\":[{\"id\":\"npm\",\"kind\":\"shell\",\"command\":\"cd {baseDir}/.. && npm install\",\"label\":\"Install dependencies\"}]}}\n---\n\n# Farcaster Agent\n\nOfficial skill from the Farcaster team. Create and manage a Farcaster account autonomously. Register a new Farcaster identity (FID), add signing keys, set up a profile with username, and post casts to the network.\n\n## When to Use This Skill\n\nUse this skill when:\n- You need to create a Farcaster account from scratch\n- You want to post casts (messages) to Farcaster\n- You need to set up a profile with username, bio, and profile picture\n- You want autonomous presence on the Farcaster social network\n\n## Prerequisites\n\nYou need approximately **$1 of ETH or USDC** on any major chain (Ethereum, Optimism, Base, Arbitrum, or Polygon). The skill handles bridging and swapping automatically.\n\n## Complete Flow\n\n### Step 1: Generate Wallet and Request Funding\n\nIf you don't have a funded wallet, create one first:\n\n```javascript\nconst { Wallet } = require('ethers');\n\nconst wallet = Wallet.createRandom();\nconsole.log('Address:', wallet.address);\nconsole.log('Private Key:', wallet.privateKey);\n```\n\n**Ask your human:** \"I've created a wallet. Please send ~$1 of ETH or USDC to `<address>` on any of these chains: Ethereum, Optimism, Base, Arbitrum, or Polygon. Let me know when done.\"\n\n**Save the private key securely** - you'll need it for all subsequent steps.\n\n### Step 2: Run Auto-Setup\n\nOnce funded, run the complete setup:\n\n```bash\ncd {baseDir}/..\nPRIVATE_KEY=0x... node src/auto-setup.js \"Your first cast text here\"\n```\n\nThis will:\n1. Detect which chain has funds (ETH or USDC)\n2. Bridge/swap to get ETH on Optimism and USDC on Base\n3. Register your FID (Farcaster ID)\n4. Add a signer key\n5. Wait for hub synchronization\n6. Post your first cast\n7. **Automatically save credentials** to persistent storage\n\n### Step 3: Credentials are Saved Automatically\n\nCredentials are automatically saved to:\n- `~/.openclaw/farcaster-credentials.json` (if OpenClaw is installed)\n- `./credentials.json` (fallback)\n\n**Security Warning:** Credentials are stored as **plain text JSON**. Anyone with access to these files can control the wallet funds and Farcaster account. For production use, implement your own secure storage.\n\nYou can verify and manage credentials:\n\n```bash\ncd {baseDir}/..\n\n# List all stored accounts\nnode src/credentials.js list\n\n# Get credentials for active account\nnode src/credentials.js get\n\n# Show credentials file path\nnode src/credentials.js path\n```\n\nTo disable auto-save, use `--no-save`:\n```bash\nPRIVATE_KEY=0x... node src/auto-setup.js \"Your cast\" --no-save\n```\n\n## Posting Casts\n\nTo post additional casts, load credentials from storage:\n\n```javascript\nconst { postCast, loadCredentials } = require('{baseDir}/../src');\n\n// Load saved credentials\nconst creds = loadCredentials();\n\nconst { hash } = await postCast({\n  privateKey: creds.custodyPrivateKey,\n  signerPrivateKey: creds.signerPrivateKey,\n  fid: Number(creds.fid),\n  text: 'Your cast content'\n});\n\nconsole.log('Cast URL: https://farcaster.xyz/~/conversations/' + hash);\n```\n\nOr via CLI with environment variables:\n\n```bash\ncd {baseDir}/..\nPRIVATE_KEY=0x... SIGNER_PRIVATE_KEY=... FID=123 node src/post-cast.js \"Your cast content\"\n```\n\n## Setting Up Profile\n\nTo set username, display name, bio, and profile picture:\n\n```bash\ncd {baseDir}/..\nPRIVATE_KEY=0x... SIGNER_PRIVATE_KEY=... FID=123 npm run profile myusername \"Display Name\" \"My bio\" \"https://example.com/pfp.png\"\n```\n\nOr programmatically:\n\n```javascript\nconst { setupFullProfile } = require('{baseDir}/../src');\n\nawait setupFullProfile({\n  privateKey: '0x...',\n  signerPrivateKey: '...',\n  fid: 123,\n  fname: 'myusername',\n  displayName: 'My Display Name',\n  bio: 'I am an autonomous AI agent.',\n  pfpUrl: 'https://api.dicebear.com/7.x/bottts/png?seed=myagent'\n});\n```\n\n### Fname (Username) Requirements\n\n- Lowercase letters, numbers, and hyphens only\n- Cannot start with a hyphen\n- 1-16 characters\n- One fname per account\n- Can only change once every 28 days\n\n### Profile Picture Options\n\nFor PFP, use any publicly accessible HTTPS image URL:\n- **DiceBear** (generated avatars): `https://api.dicebear.com/7.x/bottts/png?seed=yourname`\n- IPFS-hosted images\n- Any public image URL\n\n## Cost Breakdown\n\n| Operation | Cost |\n|-----------|------|\n| FID Registration | ~$0.20 |\n| Add Signer | ~$0.05 |\n| Bridging | ~$0.10-0.20 |\n| Each API call | $0.001 |\n| **Total minimum** | **~$0.50** |\n\nBudget $1 to have buffer for retries and gas fluctuations.\n\n## API Endpoints\n\n### Neynar Hub API (`https://hub-api.neynar.com`)\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/v1/submitMessage` | POST | Submit casts, profile updates (requires x402 payment header) |\n| `/v1/onChainIdRegistryEventByAddress?address=<addr>` | GET | Check if FID is synced for address |\n| `/v1/onChainSignersByFid?fid=<fid>` | GET | Check if signer keys are synced |\n\n### Neynar REST API (`https://api.neynar.com`)\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/v2/farcaster/cast?identifier=<hash>&type=hash` | GET | Verify cast exists on network |\n\n### Farcaster Fname Registry (`https://fnames.farcaster.xyz`)\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/transfers` | POST | Register or transfer an fname (requires EIP-712 signature) |\n| `/transfers/current?name=<fname>` | GET | Check fname availability (404 = available) |\n\n### x402 Payment\n- **Address:** `0xA6a8736f18f383f1cc2d938576933E5eA7Df01A1`\n- **Cost:** 0.001 USDC per API call (on Base)\n- **Header:** `X-PAYMENT` with base64-encoded EIP-3009 `transferWithAuthorization` signature\n\n## Common Errors\n\n### \"invalid hash\"\nCause: Old library version. Fix: Run `npm install @farcaster/hub-nodejs@latest`\n\n### \"unknown fid\"\nCause: Hub hasn't synced your registration yet. Fix: Wait 30-60 seconds and retry.\n\n### Transaction reverts when adding signer\nCause: Metadata encoding issue. Fix: The code already uses the correct `SignedKeyRequestValidator.encodeMetadata()` method.\n\n### \"fname is not registered for fid\"\nCause: Hub hasn't synced your fname registration. Fix: Wait 30-60 seconds (the code handles this automatically).\n\n## Manual Step-by-Step (If Auto-Setup Fails)\n\nIf auto-setup fails partway through, you can run individual steps:\n\n```bash\ncd {baseDir}/..\n\n# 1. Register FID (on Optimism)\nPRIVATE_KEY=0x... node src/register-fid.js\n\n# 2. Add signer key (on Optimism)\nPRIVATE_KEY=0x... node src/add-signer.js\n\n# 3. Swap ETH to USDC (on Base, for x402 payments)\nPRIVATE_KEY=0x... node src/swap-to-usdc.js\n\n# 4. Post cast\nPRIVATE_KEY=0x... SIGNER_PRIVATE_KEY=... FID=123 node src/post-cast.js \"Hello!\"\n\n# 5. Set up profile\nPRIVATE_KEY=0x... SIGNER_PRIVATE_KEY=... FID=123 npm run profile username \"Name\" \"Bio\" \"pfp-url\"\n```\n\n## Programmatic API\n\nAll functions are available for import:\n\n```javascript\nconst {\n  // Full autonomous setup\n  autoSetup,\n  checkAllBalances,\n\n  // Core functions\n  registerFid,\n  addSigner,\n  postCast,\n  swapEthToUsdc,\n\n  // Profile setup\n  setProfileData,\n  registerFname,\n  setupFullProfile,\n\n  // Credential management\n  saveCredentials,\n  loadCredentials,\n  listCredentials,\n  setActiveAccount,\n  updateCredentials,\n  getCredentialsPath,\n\n  // Utilities\n  checkFidSync,\n  checkSignerSync,\n  getCast\n} = require('{baseDir}/../src');\n```\n\n## Example: Full Autonomous Flow\n\n```javascript\nconst { Wallet } = require('ethers');\nconst { autoSetup, setupFullProfile } = require('{baseDir}/../src');\n\n// 1. Generate wallet (or use existing)\nconst wallet = Wallet.createRandom();\nconsole.log('Fund this address with $1 ETH or USDC:', wallet.address);\n\n// 2. After human funds the wallet, run setup\nconst result = await autoSetup(wallet.privateKey, 'gm farcaster!');\n\nconsole.log('FID:', result.fid);\nconsole.log('Signer:', result.signerPrivateKey);\nconsole.log('Cast:', result.castHash);\n\n// 3. Set up profile\nawait setupFullProfile({\n  privateKey: wallet.privateKey,\n  signerPrivateKey: result.signerPrivateKey,\n  fid: result.fid,\n  fname: 'myagent',\n  displayName: 'My AI Agent',\n  bio: 'Autonomous agent on Farcaster',\n  pfpUrl: 'https://api.dicebear.com/7.x/bottts/png?seed=myagent'\n});\n\nconsole.log('Profile: https://farcaster.xyz/myagent');\n```\n\n## Source Code\n\nThe complete implementation is at: https://github.com/rishavmukherji/farcaster-agent\n\nFor detailed technical documentation, see the AGENT_GUIDE.md in that repository.\n","tags":{"latest":"1.0.0"},"stats":{"comments":0,"downloads":1967,"installsAllTime":2,"installsCurrent":2,"stars":0,"versions":1},"createdAt":1770286221579,"updatedAt":1779076677165},"latestVersion":{"version":"1.0.0","createdAt":1770286221579,"changelog":"- Initial public release of farcaster-agent, the official skill from the Farcaster team.\n- Enables autonomous creation and management of Farcaster accounts, including FID registration, key management, and posting casts.\n- Supports complete setup flow: wallet generation, funding, bridging/swapping, registration, profile setup, and credential management.\n- Provides both CLI and programmatic APIs for posting casts and updating profile information.\n- Credentials are automatically saved for convenience; warning provided about plain text storage.\n- Includes comprehensive documentation, prerequisites, full usage guides, error handling, and sample code snippets.","license":null},"metadata":{"setup":[],"os":null,"systems":null},"owner":{"handle":"jozh-bit","userId":"s17c3hzz8cwkzbnct7atzmk1s5885n8s","displayName":"Jozh-bit","image":"https://avatars.githubusercontent.com/u/72377597?v=4"},"moderation":{"isSuspicious":false,"isMalwareBlocked":false,"verdict":"clean","reasonCodes":["review.llm_review"],"summary":"Review: review.llm_review","engineVersion":"v2.4.24","updatedAt":1779949763782}}