with one click
tweet-allocator
// Allocate $10/day worth of $MIROSHARK to top tweeters about the project — rewards organic engagement
// Allocate $10/day worth of $MIROSHARK to top tweeters about the project — rewards organic engagement
Daily report on new stars, forks, and traffic for watched repos
Audit every enabled skill's upstream file dependencies for staleness — flags chained skills about to consume yesterday's article or a long-dead topic file
Write an article about the project through a surprising lens — connecting it to current events, trends, philosophy, or comparable projects
Weekly recognition post for one fork operator — converts fork-cohort cohort data into a named human moment (POWER fork callout with their work, stars, and skills enabled)
Build a feature for the watched repo — picks from yesterday's repo-actions ideas first
Promote important recent log entries into MEMORY.md
| name | tweet-allocator |
| description | Allocate $10/day worth of $MIROSHARK to top tweeters about the project — rewards organic engagement |
| var | |
| tags | ["crypto","social"] |
${var} — Override daily budget (e.g. "20" for $20/day). If empty, defaults to $10/day.
Today is ${today}. Distribute $MIROSHARK rewards to the authors of the best tweets about this project's token.
memory/MEMORY.md (Tracked Token table).memory/logs/${today}.md under ## Fetch Tweets sections (written earlier today by the fetch-tweets skill). Do not read yesterday's log..bankr-cache/verified-handles.json (produced by scripts/prefetch-bankr.sh before Claude starts — the sandbox blocks BANKR_API_KEY in curl headers, so the prefetch is the only path).Project-owned accounts. Valuable signal, but self-dealing:
aaronjmarsmiroshark_BANKR_API_KEY (read-only, required) — handle-to-wallet lookups only. Used by scripts/prefetch-bankr.sh. Cannot send funds. Safe in CI.BANKR_SEND_KEY (read-write, optional) — only set when you want auto-send enabled. If unset, the skill writes a manual send plan instead.Read today's tweets. Extract every tweet from ## Fetch Tweets sections in memory/logs/${today}.md. For each capture: handle, tweet_url, summary, likes, retweets. If the log has no ## Fetch Tweets sections, log TWEET_ALLOCATOR_EMPTY — no tweets in today's log, send a one-line notification via ./notify (e.g. Tweet Allocator — ${today}: no tweets in today's log to allocate from.), and stop.
Exclude project accounts (aaronjmars, miroshark_).
Exclude already-paid tweets and authors. Scan the last 30 days of memory/logs/ for previous ## Tweet Allocator entries. Drop any tweet URL that's already been rewarded. Drop any author who already got paid today.
Check Bankr. First read .bankr-cache/prefetch-status.json (a sidecar written by scripts/prefetch-bankr.sh at every exit point). It has {status, note, candidate_count, lookup_attempted, curl_failed, verified_count, null_count, timed_out}. Branch on status:
"no-api-key" → BANKR_API_KEY env var was not set in the workflow when prefetch ran. Log TWEET_ALLOCATOR_DISABLED — BANKR_API_KEY not set in workflow; skill is dormant until secret is configured and skip the notification entirely — there's no recipient who can fix this, and a daily alert is just noise. Stop."no-candidates" → prefetch found no eligible handles to look up. Log TWEET_ALLOCATOR_EMPTY — no candidate handles in .xai-cache/ or today's log and send a one-line notification: Tweet Allocator — ${today}: no candidate handles to allocate to. Stop."lookups-failed" → all lookup_attempted Bankr API calls failed at the curl/jobId step (API down, key invalid, or rate-limited). This is a real outage. Log TWEET_ALLOCATOR_ERROR — Bankr Agent API unreachable: <note> and send an alert: Tweet Allocator — ${today}: ERROR — Bankr Agent API unreachable (X/N curl failures). Check api.bankr.bot status / BANKR_API_KEY validity. Stop."agent-timeout" → Bankr Agent jobs were submitted successfully but the LLM-backed responses didn't complete inside the prefetch's polling window (112s). Transient — likely Bankr LLM-mode latency, not a "these handles have no wallet" signal. Log TWEET_ALLOCATOR_ERROR — Bankr Agent jobs timed out: <note> and send an alert: Tweet Allocator — ${today}: ERROR — Bankr Agent jobs did not complete in time (N/N timed out). Retrying tomorrow; check api.bankr.bot LLM credit / Max Mode latency. Stop."completed-no-wallets" → prefetch ran cleanly but no candidate handle had a Bankr wallet. Treat as empty (TWEET_ALLOCATOR_EMPTY): Tweet Allocator — ${today}: no eligible tweeters (none of N candidates had a verified Bankr wallet). Stop."crashed" → prefetch script started but bailed before completing (e.g. unexpected set -e exit on a jq/grep failure). The note carries the exit code. Log TWEET_ALLOCATOR_ERROR — bankr prefetch crashed mid-run: <note> and send an alert: Tweet Allocator — ${today}: ERROR — bankr-prefetch crashed mid-run (exit_code=N). Check workflow logs for scripts/prefetch-bankr.sh. Stop."completed" → continue below.If prefetch-status.json is missing entirely (prefetch script didn't run at all — workflow misconfiguration; the script's EXIT trap should have stamped a crashed status, so a truly absent file means the script never started), log TWEET_ALLOCATOR_ERROR — prefetch-bankr.sh did not run; check workflow prefetch step and send an alert. Stop.
On "completed", read .bankr-cache/verified-handles.json — a { "handle": "0xwallet" | null } map. For each remaining candidate, look up the handle:
0x... address → eligible, keep for allocation.null, or handle missing from the cache → not eligible, drop silently.No "unverified" fallback — no wallet, no payment. If zero candidates remain after this filter, log TWEET_ALLOCATOR_EMPTY — none of today's tweet authors are in the Bankr cache and send the same one-line empty notification as above. Stop.
Score and rank. score = likes + 3 * retweets. If both are zero/missing, score = 1. Sort descending. Take top 5.
Allocate. Budget = ${var} if set, else 10 — USD-equivalent, paid in $MIROSHARK on Base. Always phrase amounts as "$X.XX in $MIROSHARK" so the USD-vs-cashtag distinction is unambiguous.
(score / total_score) * budget, rounded to 2 decimals.Send or queue.
If BANKR_SEND_KEY is not set (manual mode — default): do not send. Write a ready-to-execute allocation plan. For each recipient: @handle, amount in $MIROSHARK, tweet URL, verified wallet.
If BANKR_SEND_KEY is set (auto-send):
JOB_ID=$(curl -s -X POST "https://api.bankr.bot/agent/prompt" \
-H "X-API-Key: ${BANKR_SEND_KEY}" \
-H "Content-Type: application/json" \
-d '{"prompt":"send '"${amount}"' $MIROSHARK to @'"${handle}"' on base"}' \
| jq -r '.jobId')
Poll for completion (max 60s, 8s intervals). Record each result: handle, amount, status, tx hash or error. If curl fails (sandbox), write the request JSON to .pending-bankr-send/ for a post-run script to process.
Build the report at articles/tweet-allocator-${today}.md:
# Tweet Allocation — ${today}
**Token:** $MIROSHARK | **Budget:** $X.XX in $MIROSHARK | **Chain:** Base
## Rewards
| Rank | Author | Tweet | Score | Reward | Wallet | Status |
|------|--------|-------|-------|--------|--------|--------|
| 1 | x.com/handle | [summary](tweet_url) | XX | $X.XX in $MIROSHARK | 0x... | pending |
| ... | | | | | | |
**Total allocated:** $X.XX in $MIROSHARK to N authors
Notify via ./notify:
*Tweet Rewards — ${today}*
Budget: $X.XX in $MIROSHARK on Base
1. x.com/handle — $X.XX in $MIROSHARK (score: XX)
[brief summary]
[View tweet](tweet_url)
...
Total: $X.XX in $MIROSHARK allocated to N authors
IMPORTANT: Use x.com/handle not @handle (avoid pinging on Telegram). Always write "$X.XX in $MIROSHARK" (not "$X.XX $MIROSHARK") so the USD-vs-cashtag distinction is unambiguous.
Log to memory/logs/${today}.md:
## Tweet Allocator — ${today}
- **Status:** TWEET_ALLOCATOR_OK (or _EMPTY / _ERROR)
- **Budget:** $X.XX in $MIROSHARK
- **Tweets in log:** N | **With Bankr wallet:** M | **Paid:** K
- **Paid tweets:**
- x.com/handle — $X.XX in $MIROSHARK — tweet_url — wallet 0x... — pending (manual send)
- ...
- **Total distributed:** $X.XX in $MIROSHARK
- **Notification sent:** yes
The Bankr Agent API requires BANKR_API_KEY in the header — the sandbox blocks env var expansion in curl, so direct calls from this skill fail. All wallet verification happens in scripts/prefetch-bankr.sh before Claude starts. That script is the authoritative source. If the cache is missing, the skill stops — it does not try to call Bankr from inside the sandbox.
BANKR_API_KEY — Read-only Bankr API key (required for prefetch). Enable Wallet API + Agent API, keep Read Only Mode on. Cannot send funds. Bankr's Agent API now requires Max Mode for AI prompts, so the account must have LLM credits topped up at https://bankr.bot/llm?tab=credits (separate pool from regular API credits). The prefetch sends maxMode: {enabled: true, model: "claude-sonnet-4.6"} and bills against that pool.BANKR_SEND_KEY — Read-write Bankr API key (optional). Only set when enabling auto-send. Enable Wallet API + Agent API, Read Only Mode off.TWEET_ALLOCATOR_OK — allocation plan produced (or auto-send completed).TWEET_ALLOCATOR_EMPTY — no tweets in today's log, OR no candidates have a Bankr wallet (either zero candidates or all returned null). Sends a brief one-line notification.TWEET_ALLOCATOR_DISABLED — BANKR_API_KEY not set in workflow. Logged but silent (no notification — no human can fix this from the bot side and a daily alert is just noise).TWEET_ALLOCATOR_ERROR — real failure: Bankr Agent API unreachable (all lookups failed), Bankr Agent jobs timed out before completing (agent-timeout), prefetch script crashed mid-run (crashed), or prefetch script didn't run at all. Sends an alert notification.