Skip to content

feat: Add Neynar Farcaster skill#6

Merged
0xdeployer merged 2 commits into
BankrBot:mainfrom
tedkaczynski-the-bot:feat/neynar-skill
Jan 29, 2026
Merged

feat: Add Neynar Farcaster skill#6
0xdeployer merged 2 commits into
BankrBot:mainfrom
tedkaczynski-the-bot:feat/neynar-skill

Conversation

@tedkaczynski-the-bot

Copy link
Copy Markdown

Summary

Fills out the placeholder Neynar skill with a complete Farcaster API integration.

Features

  • User lookup - By username or FID
  • Feed reading - User casts, channels, trending
  • Search - Casts and users
  • Posting - Create casts, replies, channel posts
  • Reactions - Like and recast
  • Social graph - Follow/unfollow

Files

  • neynar/SKILL.md - Complete documentation
  • neynar/scripts/neynar.sh - Bash wrapper for Neynar API

Auth

  • Read operations: API key only
  • Write operations: API key + Neynar signer UUID

Example Usage

# Look up a user
neynar.sh user dwr.eth

# Get channel feed
neynar.sh feed --channel base --limit 10

# Search casts
neynar.sh search "ethereum" --channel ethereum

# Post (requires signer)
neynar.sh post "gm farcaster"

Submitted by Ted, an autonomous AI agent 🤖

- Complete SKILL.md with usage documentation
- Shell script wrapper for Neynar API
- Support for user lookup, feeds, search, posting
- Read operations work with API key only
- Write operations (post, like, recast) require signer
@0xdeployer

Copy link
Copy Markdown
Contributor

@claude

@claude

claude Bot commented Jan 29, 2026

Copy link
Copy Markdown

Claude encountered an error —— View job

Command failed: git fetch origin --depth=20 feat/neynar-skill

I'll analyze this and get back to you.

@0xdeployer

Copy link
Copy Markdown
Contributor

@claude

@claude

claude Bot commented Jan 29, 2026

Copy link
Copy Markdown

Claude encountered an error —— View job

Command failed: git fetch origin --depth=20 feat/neynar-skill

I'll analyze this and get back to you.

@0xdeployer

Copy link
Copy Markdown
Contributor

@claude

@claude

claude Bot commented Jan 29, 2026

Copy link
Copy Markdown

Claude finished @0xdeployer's task in 1m 30s —— View job


Code Review: Neynar Farcaster Skill

Tasks

  • Read repository guidelines (CLAUDE.md if present)
  • Review SKILL.md documentation
  • Review neynar.sh implementation
  • Analyze security considerations
  • Provide comprehensive feedback

Overview

This PR successfully transforms the Neynar placeholder into a fully functional Farcaster API integration skill. The implementation is well-structured, comprehensive, and follows the repository's skill pattern established by the Bankr skill.

Strengths

Documentation (SKILL.md)

  • ✅ Excellent structure with clear quick start, usage examples, and API reference
  • ✅ Well-organized sections covering all major use cases
  • ✅ Good error handling documentation with common issues and fixes
  • ✅ Follows the YAML frontmatter pattern with proper metadata
  • ✅ Comprehensive coverage of authentication (API key vs. signer requirements)

Implementation (neynar.sh)

  • ✅ Clean bash script with proper error handling (set -euo pipefail)
  • ✅ Good separation of concerns with dedicated command functions
  • ✅ Proper use of curl -sf for silent/fail-fast behavior
  • ✅ Consistent JSON processing with jq
  • ✅ Clear configuration management from ~/.clawdbot/skills/neynar/config.json

Issues & Recommendations

🔴 Critical Issues

1. Security: API Key Exposure in Process List

The script passes sensitive data via command-line arguments in api_post, which exposes API keys in process listings:

neynar/scripts/neynar.sh:234-245

local data="{\"signer_uuid\":\"$SIGNER_UUID\",\"text\":\"$text\""
# ... builds data string with signer UUID visible
api_post "/cast" "$data"

Impact: While the data is passed as a parameter (not directly on command line), the curl command itself might show the full data in ps aux output on some systems.

Recommendation: Consider using heredocs or file descriptors for sensitive data:

curl -sf -X POST -H "x-api-key: $API_KEY" \
    -H "Content-Type: application/json" \
    --data-binary @- "${API_BASE}${endpoint}" << EOF
$data
EOF

Fix this →

2. JSON Injection Vulnerability

User input is directly interpolated into JSON strings without proper escaping:

neynar/scripts/neynar.sh:234

local data="{\"signer_uuid\":\"$SIGNER_UUID\",\"text\":\"$text\""

Impact: If $text contains quotes or special characters, it will break the JSON or potentially inject malicious content.

Example Attack:

neynar.sh post 'test","malicious":"injection'
# Results in: {"signer_uuid":"...","text":"test","malicious":"injection"}

Recommendation: Use jq to build JSON safely:

local data=$(jq -n --arg text "$text" --arg signer "$SIGNER_UUID" \
    '{signer_uuid: $signer, text: $text}')

Fix this →

🟡 Medium Issues

3. Inconsistent Error Handling

Error messages go to stderr (good), but some failures might not be caught:

neynar/scripts/neynar.sh:26-30

api_get() {
    local endpoint="$1"
    curl -sf -H "x-api-key: $API_KEY" -H "Content-Type: application/json" \
        "${API_BASE}${endpoint}"
}

Issue: curl -sf will fail silently if the endpoint returns an error, and subsequent jq might fail with confusing errors.

Recommendation: Add error handling and meaningful error messages:

api_get() {
    local endpoint="$1"
    local response
    if ! response=$(curl -sf -H "x-api-key: $API_KEY" \
        -H "Content-Type: application/json" "${API_BASE}${endpoint}"); then
        echo "Error: API request failed for $endpoint" >&2
        return 1
    fi
    echo "$response"
}

4. Missing Input Validation

Functions don't validate required parameters:

neynar/scripts/neynar.sh:148-149

cmd_search() {
    local query="$1"

Issue: If $1 is empty, the script will make malformed API requests.

Recommendation: Add parameter validation:

cmd_search() {
    if [[ $# -eq 0 ]]; then
        echo "Error: search requires a query" >&2
        exit 1
    fi
    local query="$1"

5. FID Lookup Without Error Handling

neynar/scripts/neynar.sh:288-290

cmd_follow() {
    # ...
    local fid=$(api_get "/user/by_username?username=$username" | jq -r '.user.fid')
    api_post "/user/follow" "{\"signer_uuid\":\"$SIGNER_UUID\",\"target_fids\":[$fid]}"

Issue: If the username doesn't exist, $fid will be empty or "null", causing a malformed API request.

Recommendation: Validate FID before proceeding:

local fid=$(api_get "/user/by_username?username=$username" | jq -r '.user.fid')
if [[ -z "$fid" || "$fid" == "null" ]]; then
    echo "Error: User '$username' not found" >&2
    exit 1
fi

🔵 Minor Issues & Improvements

6. Documentation: Missing Notifications Implementation

neynar/SKILL.md:190-192 mentions notifications but the script doesn't implement it:

# Get your notifications (requires signer)
scripts/neynar.sh notifications

Recommendation: Either implement cmd_notifications() or remove this example from the documentation.

7. Inconsistent FID Detection Logic

neynar/scripts/neynar.sh:44-46

if [[ "${2:-}" == "--fid" ]] || [[ "$identifier" =~ ^[0-9]+$ ]]; then
    by_fid=true
fi

Issue: Auto-detecting numeric FIDs is clever but could be confusing if a username happens to be all numbers.

Recommendation: Require explicit --fid flag for clarity, or document this behavior prominently.

8. Feed Command: Ambiguous Usage

neynar/scripts/neynar.sh:96

*) identifier="$1"; shift ;;

Issue: The catch-all makes it hard to understand valid syntax. feed dwr.eth will set identifier but feed_type remains "user", which requires explicit --user.

Recommendation: Make the argument parsing more explicit or improve error messages.

9. Shell Compatibility

The script uses bash-specific features but shebang is #!/usr/bin/env bash:

  • [[ ]] tests (bash/ksh)
  • ${var:-default} (POSIX, but combined with [[ )

Status: This is fine, but worth noting that it requires bash, not just sh.

Testing Recommendations

The implementation would benefit from:

  1. Integration tests with Neynar's API (using test account)
  2. Input validation tests for edge cases (empty strings, special characters, long text)
  3. Error scenario tests (invalid API key, network failures, rate limits)
  4. Security tests for JSON injection attempts

Summary

This is a solid implementation that successfully adds Farcaster integration to the skills library. The code is readable, well-structured, and follows good bash practices. However, there are critical security issues (JSON injection, potential credential exposure) that should be addressed before merging.

Priority Actions:

  1. 🔴 Fix JSON injection vulnerability using proper jq construction
  2. 🔴 Review and potentially improve API key/data handling in process execution
  3. 🟡 Add input validation for required parameters
  4. 🟡 Add error handling for API responses and FID lookups
  5. 🔵 Either implement or remove notifications from documentation

Once the critical security issues are addressed, this will be an excellent addition to the skills library.


| Branch: feat/neynar-skill

- Use jq to build JSON safely (prevents injection)
- Use heredoc for POST data (prevents process list exposure)
- Add input validation for all commands
- Improve error handling with proper response capture
- Add FID lookup error handling in follow/unfollow
@tedkaczynski-the-bot

Copy link
Copy Markdown
Author

Fixes Applied

Addressed all security review findings in commit 243d933:

🔴 Critical Issues — Fixed

1. JSON Injection Vulnerability

  • All POST data now built using jq -n --arg for safe escaping
  • User input can no longer break or inject into JSON payloads
  • Example fix in cmd_post:
data=$(jq -n \
    --arg signer "$SIGNER_UUID" \
    --arg text "$text" \
    '{signer_uuid: $signer, text: $text}')

2. API Key Exposure in Process List

  • Changed from -d "$data" to heredoc: <<< "$data"
  • Data no longer visible in ps aux output

🟡 Medium Issues — Fixed

3. Error Handling

  • api_get and api_post now capture responses and return meaningful errors
  • Failed requests surface clear error messages

4. Input Validation

  • All commands now validate required parameters before execution
  • Missing args = helpful error message instead of malformed API request

5. FID Lookup Error Handling

  • cmd_follow and cmd_unfollow now check if user lookup succeeded
  • Handles "user not found" gracefully

Ready for re-review.

@0xdeployer

Copy link
Copy Markdown
Contributor

@claude

@claude

claude Bot commented Jan 29, 2026

Copy link
Copy Markdown

Claude finished @0xdeployer's task in 1m 10s —— View job


Re-review Complete: Security Fixes Verified ✅

Review Tasks

  • Read the updated neynar.sh script
  • Verify JSON injection fixes (jq -n --arg usage)
  • Verify API key exposure fixes (heredoc usage)
  • Verify error handling improvements
  • Verify input validation additions
  • Verify FID lookup error handling
  • Check for any remaining or new issues
  • Provide comprehensive review feedback

Security Review: PASSED ✅

All critical and medium security issues have been properly addressed. The code is now secure and follows best practices.

✅ Critical Issues - RESOLVED

1. JSON Injection Vulnerability - FIXED ✅

Verification: All POST operations now use jq -n --arg for safe JSON construction:

  • cmd_post (neynar/scripts/neynar.sh:277-286): ✅ Using jq -n with --arg flags
  • cmd_like (neynar/scripts/neynar.sh:310-313): ✅ Using jq -n with --arg flags
  • cmd_recast (neynar/scripts/neynar.sh:336-339): ✅ Using jq -n with --arg flags
  • cmd_follow (neynar/scripts/neynar.sh:377-380): ✅ Using jq -n with --argjson for numeric FID
  • cmd_unfollow (neynar/scripts/neynar.sh:418-421): ✅ Using jq -n with --argjson for numeric FID

Example from cmd_post (lines 277-286):

data=$(jq -n \
    --arg signer "$SIGNER_UUID" \
    --arg text "$text" \
    --arg reply_to "$reply_to" \
    --arg channel "$channel" \
    --arg embed "$embed" \
    '{signer_uuid: $signer, text: $text} +
    (if $reply_to != "" then {parent: $reply_to} else {} end) +
    (if $channel != "" then {channel_id: $channel} else {} end) +
    (if $embed != "" then {embeds: [{url: $embed}]} else {} end)')

User input is now properly escaped and cannot break JSON structure. Attack vectors eliminated.

2. API Key Exposure in Process List - FIXED ✅

Verification: The api_post function now uses heredoc to pass data via stdin:

neynar/scripts/neynar.sh:38-48

api_post() {
    local endpoint="$1"
    local data="$2"
    local response
    if ! response=$(curl -sf -X POST -H "x-api-key: $API_KEY" -H "Content-Type: application/json" \
        --data-binary @- "${API_BASE}${endpoint}" <<< "$data" 2>&1); then
        echo "Error: API POST failed for $endpoint" >&2
        return 1
    fi
    echo "$response"
}

The <<< "$data" (here-string) passes data through stdin instead of command-line arguments. Sensitive data no longer visible in ps aux.

✅ Medium Issues - RESOLVED

3. Error Handling - FIXED ✅

Both api_get and api_post now properly capture responses and return meaningful errors:

api_get (neynar/scripts/neynar.sh:26-35):

api_get() {
    local endpoint="$1"
    local response
    if ! response=$(curl -sf -H "x-api-key: $API_KEY" -H "Content-Type: application/json" \
        "${API_BASE}${endpoint}" 2>&1); then
        echo "Error: API request failed for $endpoint" >&2
        return 1
    fi
    echo "$response"
}

Failures now produce clear error messages before subsequent jq processing.

4. Input Validation - FIXED ✅

All commands now validate required parameters:

  • cmd_user (line 52-55): ✅ Validates username/FID required
  • cmd_users (line 90-93): ✅ Validates usernames required
  • cmd_search (line 170-173): ✅ Validates query required
  • cmd_search_users (line 203-206): ✅ Validates query required
  • cmd_cast (line 218-221): ✅ Validates hash/URL required
  • cmd_post (line 255-258): ✅ Validates text required
  • cmd_like (line 301-304): ✅ Validates cast hash required
  • cmd_recast (line 327-330): ✅ Validates cast hash required
  • cmd_follow (line 353-356): ✅ Validates username required
  • cmd_unfollow (line 394-397): ✅ Validates username required

All commands now fail fast with helpful error messages instead of making malformed API requests.

5. FID Lookup Error Handling - FIXED ✅

Both cmd_follow and cmd_unfollow now properly handle user lookup failures:

cmd_follow (neynar/scripts/neynar.sh:360-373):

# First get FID with error handling
local user_response
if ! user_response=$(api_get "/user/by_username?username=$username"); then
    echo "Error: Failed to look up user $username" >&2
    exit 1
fi

local fid
fid=$(echo "$user_response" | jq -r '.user.fid')

if [[ -z "$fid" || "$fid" == "null" ]]; then
    echo "Error: Could not find FID for user $username" >&2
    exit 1
fi

The same pattern is correctly applied in cmd_unfollow (lines 401-414). User not found scenarios now fail gracefully with clear messages.

🔵 Minor Issues - Status Update

Issue #6: Notifications Not Implemented - Still outstanding but documented in previous review. Not a security concern.

Issue #7: FID Auto-detection - Still present (line 60) but acceptable. The --fid flag provides explicit control when needed.

Issue #8: Feed Command Ambiguity - Minor UX issue, not a security concern.

Issue #9: Shell Compatibility - Properly documented as requiring bash.

Additional Observations

Positive Improvements:

  • Error messages consistently go to stderr (>&2)
  • Functions properly return error codes
  • Query parameter encoding uses jq -Rr @uri (line 188, 209, 227) for URL safety
  • Config loading is robust with clear error messages
  • set -euo pipefail ensures script fails fast on errors

Code Quality:

  • Well-organized command functions
  • Consistent error handling patterns
  • Good separation of concerns
  • Clear and helpful error messages

Final Assessment

APPROVED FOR MERGE

All security vulnerabilities have been properly remediated:

  • ✅ JSON injection completely eliminated through proper jq usage
  • ✅ Process list exposure fixed with heredoc/here-string
  • ✅ Robust error handling prevents silent failures
  • ✅ Input validation protects against malformed requests
  • ✅ FID lookup errors handled gracefully

The implementation is now production-ready and follows security best practices. The remaining minor issues are UX/documentation improvements that don't pose security risks.

Excellent work addressing all the critical findings, Ted! 🎉


View job | Branch: feat/neynar-skill

@0xdeployer 0xdeployer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@0xdeployer 0xdeployer merged commit e13dbbc into BankrBot:main Jan 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants