Install
$ agentstack add skill-realproject7-dropcast-cli-skill Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Reads credentials/environment and may exfiltrate them.
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
dropcast-cli Skill Definition
> Skill file for AI agents. Read this to learn how to create DropCast airdrop campaigns.
1. Overview
dropcast-cli is a command-line tool for creating DropCast token airdrop campaigns on Base Mainnet (chain ID 8453).
- Platforms: Farcaster, X (Twitter)
- Reward types:
pool_split(total split among all participants) orfixed(fixed amount per user) - On-chain: Funds are locked via the DropCast Router contract; fees are paid in ETH
- Commands:
validate,create,resume,status,list
The CLI is installed locally in the project. Run via npx dropcast-cli or the built binary.
All API requests include the X-Dropcast-Client: cli header. The backend persists this as campaigns.created_via = 'cli', enabling the /ai page to deterministically filter CLI-originated campaigns. Historical campaigns (created before source tagging was deployed) may have created_via = NULL; NULL is also expected for non-CLI creation paths (e.g. the web app).
2. Quick Defaults
Default token: USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, 6 decimals)
Default budget: 12 USDC pool_split
Default period: 1 day (now + 24h)
Farcaster: follow + like + recast | minFollowers: 20, minAccountAgeDays: 7 | fee ~0.0018 ETH
X: proof-of-read only | minXFollowers: 20 | fee ~0.0037 ETH
ETH needed: ~0.005 ETH for fee + gas (covers both platforms with buffer)
3. Workflow
Follow these steps in order. Never skip the dry-run.
Step 1: Build the campaign config
The user's post URL is the primary required input. Parse the user's request and write a campaign.json file.
- Farcaster: Use
skill/templates/campaign.farcaster.template.jsonas the starting point. To resolvehost.fidautomatically:
- Write the config with a temporary
host.fid(e.g.1) and runvalidate --config campaign.json --json(online). - Read
castPreview.authorFidfrom the JSON output — this is the cast author's FID. - If the cast author is the host (common case), use this FID. Confirm with user before finalizing.
- Update
host.fidin the config with the confirmed value.
- X: Use
skill/templates/campaign.x.template.jsonas the starting point.host.fidmust be asked or known from context (X posts don't carry FID). - Token: Default to USDC if the user doesn't specify a token.
Fields the agent must replace from user/context:
host.fid-- the user's Farcaster FID (integer). For Farcaster campaigns, auto-resolve fromcastPreview.authorFid(see above); for X, must ask.host.walletAddress-- the user's wallet address (0x...). Derive fromPRIVATE_KEYif available in.env.post.url-- the Farcaster or X post URLschedule.endsAt-- must always be overwritten. Compute asnow + 24hby default, or from user input. The template uses2099-12-31as a placeholder — never submit this value.
Fields the agent replaces only if user specifies non-default values:
token.address,token.symbol,token.decimals-- only if not using USDCreward.totalAmount(pool_split) orreward.amountPerUser+reward.maxParticipants(fixed)actions.*-- engagement actions (template defaults are opinionated per platform)targeting.*-- audience filters (template defaults are opinionated per platform)
Before writing the config, present a defaults summary for user confirmation: > "Using defaults: 12 USDC pool_split, ends in 24h, follow+like+recast. Confirm or adjust?"
For X campaigns, set platform to "x" and use a tweet URL for post.url.
Step 2: Offline schema validation
dropcast-cli validate --config campaign.json --offline --json
This checks the Zod schema locally with zero network calls. Fix any reported errors before proceeding.
Step 3: Full validation with live data
dropcast-cli validate --config campaign.json --json
This resolves the cast/post, fetches the token price, checks wallet balances, and calculates fees. Present the result to the user.
Step 4: Dry-run the create command
dropcast-cli create --config campaign.json --json
Without --execute, create runs in dry-run mode: it resolves on-chain data, fetches eligible user count for quota surcharge, calculates fees (including surcharge), checks balances, and returns a full preview. No transactions are sent. Present the dry-run summary to the user.
Step 5: Execute (only after explicit user confirmation)
dropcast-cli create --config campaign.json --execute --yes --json
Requires the PRIVATE_KEY environment variable. The --yes flag skips the interactive prompt (safe when the agent controls invocation). The CLI will:
- Fetch eligible user count via
GET /api/targeting/countand calculate the fee including quota surcharge (aborts if count unavailable unless--allow-fee-uncertainis passed) - Approve the ERC-20 token spend (if allowance insufficient)
- Call
fundCampaign()on the Router contract (sends tokens + ETH fee including surcharge) - Write a recovery file to
.dropcast-cli/.json - Register the campaign via
POST /api/campaigns(withX-Dropcast-Client: cliheader and internal 202 retry) - On success, delete the recovery file and return the campaign details
Step 6: Error recovery
If the CLI exits with an error after on-chain funding succeeded, use resume:
dropcast-cli resume --recovery .dropcast-cli/.json --json
This re-sends the API registration call without any on-chain transaction.
4. Commands Reference
Always use --json for structured, parseable output.
validate
Validate a campaign config file.
dropcast-cli validate --config [--offline] [--json]
| Flag | Required | Description | |------|----------|-------------| | --config, -c | Yes | Path to campaign.json | | --offline | No | Schema-only check (no network) | | --json | No | Output as JSON |
JSON output (offline): { "valid": true, "config": { ... } } JSON output (online): { "valid": true, "config": { ... }, "fee": { "total": 0.0014, "totalFormatted": "0.0014 ETH", "breakdown": { ... } }, "tokenPriceUsd": ..., "totalAmount": "...", "castPreview": { "authorFid": 12345, "author": "username", "text": "..." } }
create
Create a campaign. Dry-run by default; add --execute for live execution.
dropcast-cli create --config [--execute] [--campaign-id ] [--yes] [--allow-fee-uncertain] [--json]
| Flag | Required | Description | |------|----------|-------------| | --config, -c | Yes | Path to campaign.json | | --execute | No | Send real transactions (requires PRIVATE_KEY) | | --campaign-id | No | Reuse a UUID for idempotent retries | | --yes, -y | No | Skip interactive confirmation prompt | | --allow-fee-uncertain | No | Proceed without quota surcharge when eligible count is unavailable | | --json | No | Output as JSON |
Dry-run JSON output: { "mode": "dry-run", "campaignId": "...", "fee": { "total": 0.0022, "formatted": "0.0022 ETH", "breakdown": { ... } }, "totalAmount": "...", "config": { ... }, "balances": { ... } } Execute JSON output (success): { "success": true, "campaignNumber": 42, "campaignId": "...", "fundingTxHash": "0x...", "status": "active", "viewUrl": "https://dropcast.xyz/campaign/42" } Execute JSON output (error): { "error": "...", "status": 403, "recoveryFile": ".dropcast-cli/.json", "fundingTxHash": "0x..." }
resume
Resume a funded-but-unregistered campaign from its recovery file. Sends no on-chain transactions.
dropcast-cli resume --recovery [--json]
| Flag | Required | Description | |------|----------|-------------| | --recovery, -r | Yes | Path to recovery file (.dropcast-cli/.json) | | --json | No | Output as JSON |
JSON output (success): { "success": true, "resumed": true, "campaignNumber": 42, "campaignId": "...", "fundingTxHash": "0x...", "status": "active", "viewUrl": "..." }
status
Show details for a single campaign.
dropcast-cli status --id [--json]
| Flag | Required | Description | |------|----------|-------------| | --id | Yes | Campaign UUID or campaign number (integer) | | --json | No | Output as JSON |
list
List campaigns with pagination and status filter.
dropcast-cli list [--status active|ended|all] [--limit N] [--offset N] [--json]
| Flag | Required | Default | Description | |------|----------|---------|-------------| | --status | No | active | Filter: active, ended, or all | | --limit | No | 20 | Results per page | | --offset | No | 0 | Pagination offset | | --json | No | | Output as JSON |
5. Config Schema
Campaign configs must pass the Zod schema defined in src/config.ts. Brief field reference:
| Section | Key Fields | Notes | |---------|-----------|-------| | network | "base" (literal) | Only Base Mainnet is supported | | platform | "farcaster" or "x" | Determines post resolution and action behavior | | host | fid, walletAddress | Must match PRIVATE_KEY wallet for --execute | | post | url | Farcaster post URL or tweet URL (X) | | token | address, symbol, decimals, logoUrl? | ERC-20 on Base | | reward | type + type-specific fields | pool_split: totalAmount; fixed: amountPerUser + maxParticipants | | actions | follow, like, recast, quote, comment | Booleans. X campaigns ignore these (proof-of-read only) | | targeting | minFollowers, minNeynarScore, etc. | All optional with 0/false defaults | | schedule | endsAt | ISO 8601 datetime string |
For full field-by-field documentation, see skill/references/campaign-params.md.
6. Safety Rules
- ALWAYS dry-run first. Never call
create --executewithout presenting the dry-run summary to the user and receiving explicit confirmation. - ALWAYS use
--json. Parse structured output; never rely on human-readable text. - NEVER log, print, or expose
PRIVATE_KEY. Set it via.envor environment variable only. - NEVER auto-execute. The user must explicitly approve before any on-chain transaction.
- Verify wallet match. The CLI checks that
PRIVATE_KEYwallet matcheshost.walletAddress. If they differ, the backend will reject with 403. - Respect the fee. Fees are calculated dynamically. The CLI checks against the on-chain
minBaseFeebefore executing. Do not override or skip fee checks.
For the full safety policy, see skill/references/safety-policy.md.
7. Error Handling
Schema validation errors
Fix the config fields reported in the error output and re-run validate --offline.
Cast/post resolution errors
The post URL may be invalid or the Neynar API may be down. Verify the URL and retry once.
Insufficient balance errors
The CLI checks ETH (for fees + gas) and token balances before executing. Top up the wallet and retry.
On-chain errors
Do NOT retry create --execute after an on-chain error. The transaction may have partially succeeded. Check the funding transaction hash on Basescan first.
Post-funding API registration errors (most critical)
If the CLI exits with an error after the funding transaction confirmed, the tokens are already locked on-chain. Do NOT re-run create. Instead:
dropcast-cli resume --recovery .dropcast-cli/.json --json
202 pending finality
The CLI handles 202 (pending finality) retries internally with exponential backoff (2s to 60s, up to 7 attempts). Do NOT retry create yourself. If the CLI exhausts retries, use resume with the recovery file.
API error codes
| Code | Meaning | Action | |------|---------|--------| | 200 | Idempotent return (already exists) | Success -- campaign was already registered | | 201 | Created | Success | | 202 | Pending finality | CLI retries automatically; if exhausted, use resume | | 400 | Validation failure | Fix the config or payload | | 400 (fee_insufficient) | Quota surcharge mismatch | On-chain fee underpaid vs server expectation. See error playbook. Do NOT re-run create --execute. | | 403 | Authorization failure | Wallet mismatch or unauthorized | | 409 | Conflict | Duplicate txHash or mismatched campaign data |
For the full error playbook, see skill/references/error-playbook.md.
8. DropCast Platform Refund Policy
| Scenario | Pool Split | Fixed | |----------|-----------|-------| | Full participation | All tokens distributed | All tokens distributed | | Partial participation | Remaining split among verified | Unused tokens refunded to host | | Zero participants | No refund (tokens held) | Full refund to host | | Host fee (ETH) | Non-refundable | Non-refundable |
- Refunds (fixed mode only) are processed automatically after successful airdrop distribution.
- Host fees are forwarded to the BuyBackBurner contract on-chain at funding time and cannot be reversed.
9. Environment Variables
Set these in a .env file in the working directory or export them in the shell.
| Variable | Required | Default | Description | |----------|----------|---------|-------------| | PRIVATE_KEY | For --execute only | -- | Hex private key of the funding wallet | | DROPCAST_API_BASE_URL | No | https://dropcast.xyz | DropCast API base URL | | RPC_URL | No | https://mainnet.base.org | Base Mainnet RPC endpoint | | DROPCAST_ROUTER_ADDRESS | No | 0xd216801c9B658f9bEcB8125387a2A02c0d7Cc3d2 | Router contract address |
PRIVATE_KEY is not needed for validate, status, list, or dry-run create. Only the --execute flag requires it.
Users need ~0.005 ETH on Base for fee + gas. The fee cannot be paid in USDC.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: realproject7
- Source: realproject7/dropcast-cli
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.