KeeperHub / KeeperHub/keeperhub
Pre-inclusion triggers on chains with a public mempool (eth-mainnet, BSC, Polygon, Avalanche)
- Dominant language
- TypeScript
- Stars
- 24
- Forks
- 93
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 266
Description
Part of #2239. Tier 4 of four, covering the chains with a conventional public mempool: `eth-mainnet`, `bsc-mainnet`, `polygon-mainnet`, `avax-mainnet`. Grouped into one issue because the integration is shared code - only endpoints and chain parameters differ.
> **Sequencing.** This is tier 4. Tiers 1 to 3 come first, and the lead time this buys is not usable until the reaction path is shortened - that work is tracked internally and is not yet done. This issue is filed for visibility and design discussion. Please comment before starting implementation work.
## Reason: what cannot be done today
A workflow cannot react to a transaction before it is included in a block. For an adversarial, unannounced transaction there is no upstream feed to watch (tier 3 does not help) and no emitted event yet (tiers 1 and 2 do not help): "someone just submitted a call to `upgradeTo()` on our proxy" is only visible in the mempool.
**What the workaround costs:** the user runs their own mempool watcher and drives KeeperHub through the Webhook trigger. As with tier 3 this means operating an always-on service, and here a substantially heavier one - a well-peered node or a paid feed.
Being honest about the size of the problem: the lead time this buys is 2 to 12 seconds on eth-mainnet, and less elsewhere. What a user can *do* with it is the open question, not what they can see.
## Scope: what this touches, and what it does not
**In scope:** pre-inclusion transaction observation on the four chains above, via either self-hosted well-peered nodes or a commercial gateway feed. Choosing between those is a cost and operations question, not a technical one - self-hosting adds an infrastructure class we do not currently run.
**Not in scope, and worth stating explicitly:**
- **Base, Arbitrum and Solana.** They have no public mempool and need entirely different protocols. Separate issues.
- **Submission-side ordering.** Reacting to an observed transaction with a transaction of your own, positioned relative to it, requires atomic bundle submission (`eth_sendBundle`, MEV-Share backruns). Broadcasting a competing public transaction after observing a target loses to searchers with colocated nodes and direct builder connections. That is a different integration and is not part of this issue.
## Plan
Three limitations have to be resolved into product decisions before this is worth building, and they are the substance of this issue:
**1. The private-orderflow blind spot.** A significant share of Ethereum transactions never enter the public mempool, going builder-direct via Flashbots Protect, MEV Blocker and similar. A public-mempool watcher is therefore a biased sample, and it is biased *against* exactly the ordering-sensitive transactions users would most want to see. The share should be measured on our own chain set rather than taken from a commonly quoted figure.
**2. Pending is not a commitment.** A pending transaction can be replaced, dropped, or land reverted. A trigger on one is speculative, needs distinct semantics in the UI, and consumes a paid execution for something that may never have happened.
**3. Lead time is only as useful as what follows it.** An on-chain defensive response loses the race, per the scope note above. A human response takes minutes, not seconds. Which leaves alerting and off-chain reaction as the honest use case - which is real, but should be stated plainly rather than implied to be more.
Note on current state: `eth-mainnet` and `eth-sepolia` are the only chains in our production config with a private-mempool RPC set, and it is submission-side only (`lib/rpc/config-service.ts:138`). It provides no observation capability.
---
Tracking: [KEEP-1276](https://linear.app/keeperhubapp/issue/KEEP-1276) (internal tracker, not publicly accessible)
Contributor guide
Research direction
Start with the plan in the issue and inspect lib/rpc/config-service.ts:138 to understand the current private-mempool configuration. Before implementation, resolve the private-orderflow measurement, pending-transaction semantics, and useful reaction-path decisions described here. Done means those product decisions are settled; the issue explicitly asks contributors to comment before starting implementation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- blockchain
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100