The Robinhood Chain KOL set grew by 102 wallets today, taking rhc_kol_trades from 185,005 rows to 324,788 — a 76% increase in tracked KOL activity. 412 KOLs have traded on the chain in the last seven days. Every endpoint that reads KOL data picks this up with no version change: /rhc/kol/feed, /rhc/kol/leaderboard, /rhc/kol/first-touches, consensus, and all four rule engines.
None of this is new ingestion. Every one of the 102 wallets was already trading through our pipeline and being written to rhc_trades — we simply had not labelled them as KOLs, so their activity never surfaced on a KOL endpoint. Retro-matching their history against the trades we already held produced 139,518 rows in under half a minute. The lesson we keep relearning on this chain is that the ingestion is rarely the constraint; the identity mapping is.
Where the coverage gap actually was. Two leaderboards went in. The first, sorted by 30-day smart-money ranking, was 92% new to us. The second, sorted by 1-day PnL, was 78% already covered. The difference is entirely explained by whether a wallet has a linked X account: our earlier imports scraped named KOLs, and every trader on the second list had a handle. The wallets we were missing are the anonymous ones — 73 of the 102 have no public identity at all and appear as a truncated address. They trade like KOLs and now score like them.
One wallet mattered more than the other 101. A trader we already tracked as a Solana KOL turned out to have a Robinhood Chain address we had never linked. That is not a new person — it is the same identity, now joined across both chains, which is the one thing a chain-specific leaderboard cannot tell you.
First-touch records were rebuilt rather than appended. Adding KOLs retroactively changes who touched a token first: 5,400 tokens gained a first-touch record they never had, and 2,575 existing records turned out to name the wrong wallet, because a newly-tracked KOL had bought the same token earlier. Those were repointed to the true earliest buy, keeping their row identity so nothing downstream broke. The correction is usually small and occasionally enormous: the median newly-correct first-toucher beat the previously-recorded one by 136 seconds, but the tail runs to 41 days. Had we skipped this, the next trade any of these KOLs made on a token they had already touched would have fired a "first touch" alert for a token that was first touched weeks ago.
No alerts were sent for any of it. A bulk insert of historical KOL trades will, by default, emit a first-touch event per token onto our internal bus — which is to say it would have pushed several thousand weeks-old tokens to live WebSocket subscribers and first-touch webhooks as if they had just happened. The backfill ran with trigger replication disabled so that history stayed history. If you have a first-touch subscription, you saw nothing today that was not genuinely first-touched today.
2026-08-02 (SDKs) — All seven Robinhood Chain SDKs now speak the rule engines — v0.4.0
Every Robinhood Chain SDK is updated to 0.4.0 with the four rule engines shipped earlier today: copy-trade, price alerts, coordination alerts and first-touch subscriptions — 22 operations each.
- TypeScript (
robinhood-chain-sdk, robinhood-chain-x402) — full CRUD plus the two read endpoints, with typed request/response shapes throughout.
- Python (
robinhood-chain) — same surface, sync and async. Also ships a NULL sentinel: the API's schemas are strict, so None cannot mean both "leave unchanged" and "clear this field" on a PATCH. NULL is how you clear a name, webhook URL or market-cap bound.
- Rust (
robinhood-chain) — same surface.
- MCP server (
mcp-server-robinhood-chain) — 52 tools, up from 30. The 22 new ones are correctly annotated as writes rather than reads, and the four deletes as destructive, so an agent knows what is safe to call speculatively.
- ElizaOS and Solana Agent Kit plugins — grouped actions per engine. The agent actions default to list, so a mis-triggered action cannot delete one of your rules.
Four bugs we found in our own SDKs while doing this, all pre-existing:
- Five endpoints were half-shipped in 0.3.x.
top-traders, flow, peak-history, risk and holders existed in the TypeScript client but were missing from the Python async dispatch map — so await client.token_risk(...) raised AttributeError rather than returning data. They were also absent from the Solana Agent Kit plugin's method map and from the TypeScript smoke test's expected count, which is why nothing caught it. All fixed, with a regression test that asserts the endpoint map and the async dispatch set cannot diverge again.
- The ElizaOS Robinhood Chain smoke test was failing outright — it asserted an error message pointing at
/developer while the client points at /pricing. Its Agent Kit counterpart only appeared to pass because the assertion sat inside a catch that swallowed the failure.
- The MCP tool registry had drifted: 30 tools registered, 25 declared in the published manifest. Now all three lists — registration, tool cards, manifest — are generated in step and verified equal.
- Version manifests disagreed with themselves: the MCP server's
server.json said 0.2.0 and its glama.json said 0.1.2 while the package was 0.3.1. All aligned.
None of these were caused by the new work; they were found because adding a surface this size forces you to read every list you own.
2026-08-02 (later) — Copy-trade rules on Robinhood Chain, and the one missing line that kept the chain read-only
Robinhood Chain now has a rule engine: POST /api/v1/rhc/copytrade/subscriptions. Point it at RHC KOL wallets, get a signal the moment one of them trades — by webhook, by WebSocket on the new rhc:copytrade:signals channel, or both.
The body mirrors the Solana engine with EVM-native names: source_wallets (lowercase 0x), min_trade_eth, sizing_amount in ETH, sizing modes fixed | proportional | percent_source. Quotas are per chain — a full set of Solana copy-trade rules does not consume RHC capacity. PRO gets 3 rules × 5 wallets, ULTRA 20 × 50, BUSINESS 100 × 250. Replays cannot double-fire: (subscription_id, tx_hash) is unique and delivery only happens after a fresh insert.
One filter is deliberately absent. There is no min_mc_usd / max_mc_usd on RHC copy-trade. The event our ingest publishes carries no market cap, so the band could only be implemented as a database lookup on every event of a chain doing ~3.3 million trades a day, or as a filter that silently never matches. We would rather the filter not exist than have it quietly lie — the same call we made keeping ?min_kol_winrate off the RHC KOL feed until the scores existed.
Why this took until now is the uncomfortable part. The ingestion service has been publishing rhc:kol_trade onto our internal event bus since the Robinhood Chain rollout. The evaluator that turns events into rule fires was subscribed to that same bus the entire time. It just had no branch for the event type, so every RHC trade arrived and was dropped on the floor. Nothing errored, nothing alerted, and the WebSocket channels carrying the same events worked fine — which is exactly why it went unnoticed. Robinhood Chain was read-only because of a missing if, not a missing pipeline.
There is now a health check that fails if active rules stop producing fires, rather than one that only confirms the tables exist.
Also fixed: you could create an RHC webhook but not edit it. POST /api/v1/webhooks and PATCH /api/v1/webhooks/{id} each carried their own copy of the valid-event list, and they had drifted — rhc:kol_trade was only in the create path. Registering worked, deliveries fired, and any PATCH that round-tripped the webhook's own events array came back 400. Both now read one shared list.
Price-alert webhooks now actually send. If you created a price alert with delivery_mode: "webhook" or "both", we handed you a signing secret and then delivered nothing. The market-cap tracker loaded your webhook URL and secret into memory on every reload and never called the signing/POST path — alerts fired correctly, but only over WebSocket, regardless of the delivery mode you chose. Our own API reference stated delivery happened there, which made it look intentional. It is now implemented: price_alert:dip and price_alert:recovery are signed HMAC-SHA256 over <timestamp>.<body> with the per-alert secret, delivery_mode is honoured, and success or failure is recorded on the alert event so you can see it in the events endpoint.
Price alerts on Robinhood Chain: POST /api/v1/rhc/price-alerts. Set a drop threshold against a token's market cap, get a dip — and optionally a recovery once it bounces off its low by a percentage you choose. Same one-shot state machine as the Solana alerts, delivered by webhook, on the new rhc:price_alert:events WebSocket channel, or both. Quota is per chain.
One difference we are putting in the response, not just the docs. Solana alerts are evaluated inside the market-cap tracker's live price loop and fire sub-second. Robinhood Chain prices are written by a service on a different machine that publishes no event when a price changes, so there is nothing for the evaluator to react to — it polls instead, roughly every 15 seconds, over just the tokens that have an alert on them. Effective latency is that interval plus how often the token itself reprices. Every create response carries an evaluation block saying exactly this, because the failure mode we care about is someone assuming parity with Solana and sizing a strategy around a number that does not apply.
Coordination alerts on Robinhood Chain: POST /api/v1/rhc/kol/coordination/alerts. Fire when several tracked KOLs buy the same token inside a rolling window — set the number of KOLs, the window, a minimum score, a cooldown, and a market-cap band. A token whose cap we cannot read is dropped from the band rather than passed through it; "unknown" is not "inside".
The score is the same v1 scorer we use on Solana, so the number means the same thing on both chains — with two differences we record on every signal rather than smoothing over. Quality is now real on Robinhood Chain: the KOL scoring layer we shipped earlier today supplies a genuine win-rate instead of a placeholder. Earliness is still a default — there is no early-entry measure on this chain, and inventing one would move scores without making them better. Each fired signal carries a score_inputs object showing exactly which components were measured and which were defaulted, so a score can be audited later without guessing what the engine knew at the time.
First-touch alerts on Robinhood Chain: POST /api/v1/rhc/kol/first-touches/subscriptions. Get pushed the moment a token receives its first buy from a tracked KOL — the earliest signal we have, and the one with the least competition on it. The subscription endpoint (filtered delivery to your own webhook) is Ultra. The rhc:kol:first_touches broadcast channel it publishes on is Pro+ — every first touch is emitted whether or not anyone holds a subscription, so a Pro socket receives the full stream.
This was the only one of the four Robinhood Chain rule engines that needed new data capture rather than wiring; the others ran off events that were already flowing. There is now a proper first-touch record per token, backfilled across all history — 9,613 tokens, exactly matching the number that have ever had a KOL buy. A second KOL buying the same token produces nothing, which is the whole point: this is a "first" feed, not a second trade feed.
Filters are kol, min_first_buy_eth, min_kol_winrate, strategy and a market-cap band. Unknown filter keys are rejected outright rather than quietly ignored — if you typo a filter name, you get a 400 instead of an alert stream that silently ignores half your criteria. Note there is deliberately no scout-tier filter here as there is on Solana: Robinhood Chain has no scout scoring, and we would rather omit the filter than ship one that matches nothing.
That completes all four Robinhood Chain rule engines — copy-trade, price alerts, coordination and first-touch — each with its own health check and end-to-end test.
And GET /api/v1/me now reports price_alerts. It was listed in the docs as part of the response and was never actually returned, so a client self-throttling off /me had no way to see its alert quota. The same response now also carries rhc_copytrade_rules — a per-chain budget that does not consume your Solana copy-trade allowance.