Agents and automation
ClaimRush is permissionless:
- EOAs and smart contracts can play.
- Anyone can build bots/agents.
Pre-freeze note: The protocol launches before freezeConfig(). During the pre-freeze phase, the admin can re-wire contract addresses (to apply audit fixes). Gameplay is permissionless from day one, but agents should be aware that contract wiring may change. After freezeConfig(), wiring is permanent. Agents can check configFrozen on core contracts to detect the current phase. See Security, guardian, pausing.
This page covers:
- Self-run agents: agent plays from its own wallet.
- Delegated agents: agent acts for a user address via DelegationHub sessions.
Related docs:
CRAL pack
Machine-readable CRAL companion (runnable manifests and guardrails):
Key manifest IDs (quick map):
- Install:
10.install - Snapshot:
21.snapshot.example - Quotes:
23.quote.takeover_with_token - Prices:
24.prices.live - Events:
30.events.stream,32.events.backfill.subgraph - Harness:
40.harness.run - Agent loop:
51.agent.loop.dry_run_once,52.agent.loop.execute - Monitor + durability:
57.agent.monitor,58.agent.event_cursor - Tx reliability:
59.agent.tx_replacement,59.agent.backoff - Private RPC:
55.private_rpc.route,56.private_rpc.only - Auto approvals:
54.agent.auto_approve - Achievements:
54.achievements.jsonl - Delegation:
61.delegation.create_session.local_demo,62.delegation.agent_run.once - Plans:
71.plan.write,72.plan.execute - Market demo:
74.market.demo.help,75.market.offer.create.simulate - Strategy + replay:
77.strategy.modules,78.strategy.dev_runner,79.replay.runner - Action coverage audit:
76.action.coverage - Subgraph health:
80.subgraph.health - Operational guidance:
90.ops.guidance.self_run
Use the Markdown page for explanation. Use the CRAL file for automation.
Repo entrypoints
| What | Where |
|---|---|
| Agent tooling root | agents/ |
| TypeScript SDK | agents/sdk/ |
| Local manifests | deployments/<network>.json |
| ABIs | abis/<network>/*.abi.json |
| Optional snapshot bundler | src/lens/AgentLens.sol |
| MineCore takeover quoter | src/MineCoreQuoter.sol |
| Spot swap quoting (DexAdapter + registries) | agents/sdk/src/dexQuotes.ts |
| Live prices helper (CLAIM/ETH + entry tokens) | agents/sdk/src/prices.ts |
| Event cursor (reorg-safe checkpoints) | agents/sdk/src/agent/eventCursor.ts |
| Monitor endpoint (HTTP) | agents/sdk/src/agent/monitor.ts |
| Tx manager + replacement | agents/sdk/src/tx/txManager.ts |
| Backoff / circuit breaker | agents/sdk/src/agent/backoff.ts |
| Strategy plugins + loader | agents/sdk/src/agent/strategies.ts, agents/sdk/src/agent/strategyLoader.ts |
| Strategy templates | agents/sdk/strategies/ |
| Replay runner | agents/sdk/src/agent/replay.ts, agents/sdk/examples/replay.ts |
| Achievements telemetry (SDK) | agents/sdk/src/achievements/ |
The SDK is designed for:
- deterministic inputs (snapshots)
- event-driven wakeups (JSONL event stream)
- safe execution (dry-run by default; explicit
--execute)
Install
From repo root:
npm -C agents/sdk installRead state for decision making
Snapshot API
The SDK exposes getGameStateSnapshot() which returns:
meta(chainId, blockNumber, timestamps)addresses(contract addresses from manifest)global(MineCore/Furnace/Royalties/Ve/Market/LP vault/Dex state)- optional
userslice (balances + claimables + config) when a wallet address is provided
Run the snapshot example:
RPC_URL=http://127.0.0.1:8545 \
USER_ADDRESS=0xYourAgentAddress \
npm -C agents/sdk run example:snapshotPerformance: If AgentLens is deployed and present in the manifest, the snapshot prefers:
AgentLens.readGlobalV1()AgentLens.readUserV1(user)
…and falls back to publicClient.multicall() (or sequential reads).
Optional onchain snapshot bundler (AgentLens)
AgentLens is a pure view contract that bundles reads into two calls:
readGlobalV1()readUserV1(user)
Local deploys include it in deployments/local.json.
Use cases:
- reduce RPC calls for high-frequency agents
- reduce “N reads” variance across RPC providers
Quote token takeovers
MineCore.takeoverWithToken(tokenIn, amountIn, minEthOut) requires a minEthOut slippage guard.
Use the view-only contract MineCoreQuoter (and the SDK helpers) to:
- validate the allowlisted takeover route for
tokenIn - compute the expected ETH out for a given
amountIn - derive a safe
minEthOutfrom a slippage setting
Example (local):
# Default uses wrapped native (WETH) + amountIn = current takeover price
RPC_URL=http://127.0.0.1:8545 \
npm -C agents/sdk run example:takeover-token-quote
# Custom token route (token must be enabled in MineCoreEntryTokenRegistry)
# AMOUNT_IN is raw base units (example: 1 USDC = 1000000)
RPC_URL=http://127.0.0.1:8545 \
TOKEN_IN=0xYourTokenAddress \
AMOUNT_IN=1000000 \
SLIPPAGE_BPS=100 \
npm -C agents/sdk run example:takeover-token-quoteOutputs include:
expectedEthOuttakeoverPriceAtQuoteminEthOut(slippage-adjusted)minEthOutStrict(optional: clamped to never be below takeover price)
Agent rule of thumb:
- never hardcode a route
- always compute
minEthOutfrom a quote and an explicit slippage policy
Live prices and swap quotes
Most strategies need spot prices for:
- CLAIM/ETH (how expensive it is to acquire CLAIM, or what ETH you get back)
- entry tokens in ETH or CLAIM (to decide between paying with ETH vs token, or whether a token path is economical)
The SDK includes getLivePrices() which:
- enumerates enabled entry tokens from the subgraph (
EntryTokenConfig) - computes spot quotes from onchain reads using the protocol’s
DexAdapter.getAmountsOut - uses allowlisted routes from the registries (no hardcoded Aerodrome paths)
- optionally includes the subgraph
TokenPricingSnapshot(CLAIM/ETH TWAP + ETH/USD)
Example:
RPC_URL=http://127.0.0.1:8545 \
SUBGRAPH_URL=http://127.0.0.1:8000/subgraphs/name/claimrush/local \
npm -C agents/sdk run example:prices
# Optional tuning
# MAX_TOKENS=200 (default)
# INCLUDE_SUBGRAPH_PRICING=true (default)
# Optional: enable in-memory caching + RPC throttling (useful when polling)
# PRICES_CACHE=1
# PRICES_RPC_CONCURRENCY=16
# PRICES_QUOTE_TTL_MS=5000 (set 0 to disable quote caching)
# PRICES_ENTRYTOKENS_TTL_MS=60000 (entry token enumeration via subgraph)
# PRICES_PRICING_TTL_MS=15000 (subgraph pricing snapshot)
# PRICES_META_TTL_MS=21600000 (ERC20 metadata)
# PRICES_DEX_TTL_MS=300000 (DexAdapter config)Notes:
- Cached quotes are for decision support / UI. For tx guardrails (
minOut), re-quote immediately before sending. - Spot quotes are size-dependent. The default snapshot quotes 1 token (10^decimals) per entry token.
- Treat subgraph pricing as informational (it can lag). Spot quotes come from onchain reads.
- If a token fails to quote, the output includes per-token
errors. Agents should treat those tokens as unknown/unsupported.
Listen to events
JSONL event stream
The SDK includes an event streamer that prints one event per line (JSONL).
RPC_URL=http://127.0.0.1:8545 \
npm -C agents/sdk run example:eventsFilters:
--contracts MineCore,Furnace--events Takeover,FurnaceEnter--from-block 0--poll(HTTP polling fallback)
Optional subgraph backfill
If you have a subgraph endpoint, you can backfill recent history before starting the live RPC stream.
RPC_URL=http://127.0.0.1:8545 \
SUBGRAPH_URL=http://127.0.0.1:8000/subgraphs/name/claimrush/local \
npm -C agents/sdk run example:events -- --backfill --backfill-limit 100Backfilled events include source: "subgraph" (live RPC events use source: "rpc").
Local simulation harness
Use the harness to run a deterministic “golden path” and write artifacts:
RPC_URL=http://127.0.0.1:8545 \
npm -C agents/sdk run example:harnessArtifacts are written under:
agents/sdk/out/harness-<timestamp>/
Live agent loop
The SDK includes a reference live loop:
- takes snapshots
- (optionally) listens to events
- proposes actions
- can execute transactions if explicitly enabled
Dry-run once:
RPC_URL=http://127.0.0.1:8545 \
npm -C agents/sdk run example:agent -- --onceExecute (sends tx):
RPC_URL=http://127.0.0.1:8545 \
npm -C agents/sdk run example:agent -- --executeSpending actions are opt-in:
--enable-furnace-entry --furnace-eth-in <amount>--enable-takeovers --max-takeover-eth <cap>
Private RPC for takeovers and swaps (optional)
Takeovers and swap-heavy actions are MEV-sensitive. If you operate a private tx endpoint (protected RPC / builder relay), the SDK can route selected transactions there.
Config
- Env:
PRIVATE_RPC_URL,PRIVATE_RPC_MODE=off|route|only - CLI:
--private-rpc-url,--private-rpc-mode off|route|only
Modes
route: send allowlisted actions viaPRIVATE_RPC_URL, everything else viaRPC_URLonly: block execution of non-allowlisted actions (dry-run still works)off: disable private routing (default whenPRIVATE_RPC_URLis unset)
Allowlisted actions (v3)
- Takeovers (MEV-sensitive):
mineCore.takeover,mineCore.takeoverFormineCore.takeoverWithToken
- Furnace entry (swap-heavy when token-based):
furnace.enterWithEth,furnace.enterWithEthForfurnace.enterWithToken,furnace.enterWithTokenFromCallerForfurnace.enterWithClaim,furnace.enterWithClaimFromCallerFor
- Market exits / fills (swap/quote sensitive):
marketRouter.sellLockToFurnace,marketRouter.sellListedLockToFurnace,marketRouter.executeAutoFurnace
- Royalties lock-mode claim (routes ETH through Furnace):
royalties.claimShareholderLock
- ClaimAllHelper when it performs a Furnace lock:
claimAllHelper.claimShareholderForUser,claimAllHelper.claimAllForwhenmode=LOCK_FURNACE (1)
Notes
- Reads and simulations always use
RPC_URL(private routing only affects sending). - In
PRIVATE_RPC_MODE=only, non-allowlisted writes (offers/listings/approvals/config) are blocked. Useroutefor mixed workloads. - Private RPC providers are trusted infrastructure. Use only endpoints you trust.
Example (strict allowlist mode)
RPC_URL=http://127.0.0.1:8545 PRIVATE_RPC_URL=http://127.0.0.1:8545 PRIVATE_RPC_MODE=only npm -C agents/sdk run example:agent -- --execute --enable-takeovers --max-takeover-eth 0.01Reliability and monitoring
These knobs are optional, but recommended for real unattended bots.
Monitor endpoint (optional)
Expose a local HTTP endpoint with agent health + recent telemetry:
- Enable:
--monitor(or envAGENT_MONITOR_ENABLED=1) - Bind:
AGENT_MONITOR_HOST=127.0.0.1(default),AGENT_MONITOR_PORT=8787(default) - Optional auth:
AGENT_MONITOR_TOKEN=<secret> - Ring size:
AGENT_MONITOR_MAX_RECENT=200(default)
Example:
RPC_URL=http://127.0.0.1:8545 npm -C agents/sdk run example:agent -- --once --monitor
curl http://127.0.0.1:8787/healthDurable event cursor (events + reorg safety)
When events are enabled, the agent persists a cursor file:
agents/sdk/out/agent-state/<chain>/<chainId>/<agent[-for-user]>/event-cursor.json- This includes the last processed block + a recent-key set used to dedupe events across reorgs.
- On startup, the agent rewinds a small number of blocks and replays deterministically.
Config (env)
AGENT_STATE_DIR=<path>(override state root)EVENT_CURSOR_REWIND_BLOCKS=20(default)EVENT_CURSOR_MAX_KEYS=5000(default)
Nonce manager + tx replacement (optional)
For MEV-sensitive txs and flaky RPCs, the SDK can manage nonces and fee-bump stuck txs:
TX_MANAGE_NONCES=1(managed nonce allocation + receipt timeout; useful when mixing public + private RPC)TX_REPLACEMENT_ENABLED=1(implies managed nonces; fee-bump + resubmit stuck txs)TX_REPLACEMENT_TIMEOUT_MS=45000(receipt timeout; also the per-attempt replacement window when enabled)TX_REPLACEMENT_MAX_ATTEMPTS=3TX_POLL_INTERVAL_MS=1500TX_FEE_BUMP_BPS=12500(+25% per attempt)
The per-action txs.jsonl file records nonce, attempts, and hashes when replacement is enabled.
Backoff circuit breaker (execute mode)
When --execute is enabled, the runner uses a simple circuit breaker:
- Default: enabled (set
BACKOFF_ENABLED=0to disable) - Emits achievements:
BACKOFF_ENTERED,BACKOFF_CLEARED - Config (env):
BACKOFF_BASE_MS=1000BACKOFF_MAX_MS=600000BACKOFF_MULTIPLIER=2BACKOFF_MAX_TIMEOUTS=3BACKOFF_MAX_ERRORS=10BACKOFF_RESET_AFTER_MS=600000
Replay + strategy development (offline)
Record ticks in a live run, then replay offline to regression-test decision-making:
- Record:
WRITE_TICK_RECORDS=1(live agent) - Replay:
npm -C agents/sdk run example:replay -- --run-dir agents/sdk/out/agent-<timestamp> --compare --pretty - Strategy modules:
- Load into the live agent:
--strategy-module ./path/to/strategy.mjs - Or via env:
STRATEGY_MODULES=./a.mjs,./b.mjs - Templates live in
agents/sdk/strategies/
- Load into the live agent:
- Fast iteration:
npm -C agents/sdk run example:strategy -- --run-dir ... --strategy-module ... --pretty
Achievements telemetry
The SDK writes a compact JSONL telemetry stream in two modes:
- Live agent:
agents/sdk/out/agent-<timestamp>/achievements.jsonl - Plan executor:
agents/sdk/out/execute-plan-<timestamp>/achievements.jsonl
Use this for:
- dashboards / alerting / postmortems
- feeding an external AI a compressed “what happened recently” context window
Format
- each line is an
Achievementobject with:ts(ms since unix epoch)kind(string)level(info|warn|error)- optional context:
chain,chainId,agent,user,blockNumber,txHash,data
Achievement kinds (v1)
- Value milestones:
TAKEOVER_SUCCESSREIGN_REWARD_COLLECTEDFURNACE_LOCK_CREATEDROYALTIES_CLAIMEDAUTOCOMPOUND_EXECUTED
- Frontend profile badges (optional):
BADGE_UNLOCKED
- Safety/ops:
SLIPPAGE_GUARD_TRIGGEREDSESSION_EXPIREDPAUSED_ACTION_SKIPPEDREVERTED_TXRPC_LAG_DETECTEDSUBGRAPH_LAG_DETECTED
- Optional scoring:
ACTION_UTILITY(only ifEMIT_ACTION_UTILITY=1)
Frontend badge polling (optional)
- Set
ACHIEVEMENTS_BASE_URL=<url>to enable (works in both the live agent and the plan executor). - The agent polls:
{ACHIEVEMENTS_BASE_URL}/api/achievements?address=<user>&chainId=<chainId>. - Supported chain ids: 8453 (Base), 84532 (Base sepolia), 31337 (local).
- First successful poll initializes a baseline and emits nothing.
- After a confirmed onchain tx, the agent requests a one-shot refresh (debounced,
refresh=1). - Badge definitions are ported from the frontend into
agents/sdk/src/achievements/profileBadges.ts(delegation-only badges excluded).
Tuning (env)
ACHIEVEMENTS_POLL_MS=20000(default)ACHIEVEMENTS_REFRESH_COOLDOWN_MS=5000(default)ACHIEVEMENTS_TIMEOUT_MS=10000(default)
Notes
- Treat
dataas versioned/best-effort. Usekindandlevelas stable keys. - Achievements are telemetry and reward hooks, not an objective to “farm”.
Delegated agents
Delegated agents run from the bot’s wallet, but act for a user address via DelegationHub sessions.
High-level model:
- User grants a session:
(delegate, perms, expiry). - Bot submits txs from its own address (pays gas and any ETH/CLAIM spend), calling delegated protocol entry points.
- Protocol contracts verify the session onchain (
DelegationHub.isAuthorized).
Create or refresh a session
In production, the user signature should come from their wallet (EOA) or an EIP-1271 smart wallet.
Local demo (actor0=user, actor1=delegate):
RPC_URL=http://127.0.0.1:8545 \
npm -C agents/sdk run example:delegationRun the live agent for a user
Use --acting-for to switch the agent into delegated mode.
# run the delegate (actor1) but act for the user address
RPC_URL=http://127.0.0.1:8545 \
npm -C agents/sdk run example:agent -- --actor-index 1 --acting-for 0xUserAddress --once
# execute (sends tx)
RPC_URL=http://127.0.0.1:8545 \
npm -C agents/sdk run example:agent -- --actor-index 1 --acting-for 0xUserAddress --executeNotes:
- Strategy flags like
--enable-furnace-entry/--enable-takeoversstill apply, but the SDK will prefer delegated entry points when--acting-foris set. - The session must include the required permission bits for each action (see Bot sessions (DelegationHub)).
Delegated smoke test harness
The harness includes a small delegated scenario:
RPC_URL=http://127.0.0.1:8545 \
npm -C agents/sdk run example:harness -- --scenario delegatedThis performs:
DelegationHub.setSessionBySig(user signs, delegate submits)Furnace.enterWithEthFor(user, ...)(delegate pays, user receives ve)MineCore.takeoverFor(user)(delegate pays, user becomes King)
Plan format for external AI
If you want an external AI system to decide actions, use AgentPlan v1:
example:planwrites a plan JSON fileexample:execute-plansimulates or executes a plan
RPC_URL=http://127.0.0.1:8545 \
npm -C agents/sdk run example:plan -- --out /tmp/agent-plan.json --pretty
RPC_URL=http://127.0.0.1:8545 \
npm -C agents/sdk run example:execute-plan -- --plan /tmp/agent-plan.json
# Optional: emit achievements.jsonl (and poll frontend badges)
ACHIEVEMENTS_BASE_URL=http://127.0.0.1:3000 \
npm -C agents/sdk run example:execute-plan -- --plan /tmp/agent-plan.json --executeTip: the same knobs are also available as CLI flags (see --help):
--achievements-base-url--achievements-poll-ms--achievements-refresh-cooldown-ms--achievements-timeout-ms
Market actions (offers, listings, sells) are expressed as plan actions too:
# Show available commands
RPC_URL=http://127.0.0.1:8545 \
npm -C agents/sdk run example:market -- --help
# Example: create an offer (simulated)
RPC_URL=http://127.0.0.1:8545 TARGET_BONUS_BPS=2500 BUDGET_CLAIM=1000000000000000000 DURATION_DAYS=30 \
npm -C agents/sdk run example:market -- --cmd offer-createDelegated mode: add --acting-for 0xUserAddress to example:plan so the plan targets a user identity (and uses delegated entry points when executed).
The JSON Schema lives at:
agents/sdk/schemas/agent-plan.v1.schema.json
Action coverage (AgentPlan v1)
The SDK executor now covers (nearly) the full gameplay surface for self-run agents:
- MineCore
- Takeovers:
mineCore.takeover,mineCore.takeoverWithToken - Config:
mineCore.setCurrentReignRecipients,mineCore.setKingAutoLockConfig - Withdrawals:
mineCore.withdrawKingBalance,mineCore.withdrawRefundBalance
- Takeovers:
- Furnace
- Entry:
furnace.enterWithEth,furnace.enterWithClaim,furnace.enterWithToken
- Entry:
- ShareholderRoyalties
- Claims:
royalties.claimShareholderEth,royalties.claimShareholderLock - Config:
royalties.setAutoCompoundConfig
- Claims:
- MarketRouter
- Listings:
marketRouter.listLock,marketRouter.delistLock,marketRouter.cancelExpiredListing - Offers:
marketRouter.createBonusTargetEscrowWithTarget,marketRouter.cancelBonusTargetEscrow,marketRouter.extendBonusTargetEscrowExpiry,marketRouter.cancelExpiredBonusTargetEscrow,marketRouter.executeAutoFurnace - Exits:
marketRouter.sellLockToFurnace,marketRouter.sellListedLockToFurnace
- Listings:
- VeClaimNFT (veCLAIM positions)
- Maintenance:
ve.extendLock,ve.extendLockTo,ve.mergeLocks,ve.unlock,ve.setAutoMax - Checkpoints:
ve.checkpointGlobalState,ve.checkpointTotalVe
- Maintenance:
- Approvals
- ERC20:
erc20.approve,erc20.ensureAllowance - veNFT:
ve.approve,ve.setApprovalForAll
- ERC20:
Auto approvals
For unattended operation, the agent can automatically insert the required ERC20 and veNFT approval actions ahead of swap/takeover/market actions.
Enable (env vars)
AUTO_APPROVE_ENABLED=1AUTO_APPROVE_MODE=exact|max(default:exact)AUTO_APPROVE_NFT=0|1(default:1)
Notes
- Auto approvals are inserted only when executing transactions (dry-run does not send approvals).
- Not compatible with
PRIVATE_RPC_MODE=only(approval txs are blocked). Pre-approve, or usePRIVATE_RPC_MODE=route. - veNFT auto approvals use per-tokenId
approve(notsetApprovalForAll) for safety.
Delegated mode adds ...For(user) action variants where the protocol exposes them, plus safe account-management actions (auto-compound configs and ve maintenance).
Canonical source of truth:
agents/sdk/schemas/agent-plan.v1.schema.json(action enum + field set)
Subgraph health and address parity
Before relying on subgraph data in production, validate:
- indexing lag vs RPC head
- protocol contract address parity vs current manifest
RPC_URL=... \
SUBGRAPH_URL=... \
npm -C agents/sdk run example:subgraph-health -- --prettyOperational guidance
For self-run agents:
- Use a dedicated wallet (separate from treasury / cold storage).
- Always cap spend (
maxTakeoverEth, max actions per cycle). - Always include slippage floors and deadlines.
- Treat MineCore contention reverts as normal; re-quote right before send.
- Log everything (snapshots, decisions, tx hashes, reverts).
For delegated agents:
- Prefer short session expiries (hours, not days) to limit user exposure.
- Re-check session validity before executing; user may revoke mid-cycle.
- Track permission bits required per action type (see Bot sessions).
- Separate spend accounting: bot pays gas and ETH/CLAIM, user receives benefits.
- Log the user address (
--acting-for) with every action for audit trails. - Handle EIP-1271 smart wallet signatures in production (not just EOA).
- Monitor for session expiry approaching; prompt user to refresh proactively.