@routescore/agentkit
v0.1.0
Published
Coinbase AgentKit action provider for the Routescore public API — a free-tier, read-only pre-sign evidence check (check_swap returns a clear/caution/unsupported verdict + a hash-verifiable record) plus modeled route risk context and policy evaluation as a
Maintainers
Readme
Routescore Action Provider for Coinbase AgentKit
"Ask Routescore before acting." This package is a Coinbase AgentKit action provider that gives an on-chain AI agent read-only, modeled, point-in-time, source-backed risk context from the Routescore public API before the agent swaps, bridges, or restakes.
Routescore is read-only decision support: it does not execute trades, sign transactions, or move funds. The agent's own stack decides whether to act, on its own wallet and its own risk. Action results are context objects with caveats — never advice, never an instruction to act.
Prototype status (ROU-691): the canonical copy of this provider lives in the Routescore repo. The prepared upstream contribution to
coinbase/agentkitis underexternal-pr/and is submitted separately.
Actions
| Action | Tier | Wraps | What it returns |
|---|---|---|---|
| routescore_check_swap | free | POST /api/public/v1/check/swap | The pre-sign evidence read — start here. Given notional, chain, and an optional route/token: a modeled route-quality grade, price-impact/slippage band, and a recognized-vs-unverified token registry read, composed into a clear \| caution \| unsupported verdict with machine-readable reasons + caveats, plus a persisted, hash-verifiable evidence record id. |
| routescore_get_preflight_record | free | GET /api/public/v1/records/{record_id} | The durable, owner-scoped evidence record a prior check_swap persisted (the "record" leg of plan → preflight → execute → record), with a canonical-JSON SHA-256 integrity hash for offline re-verification. |
| routescore_quote_check | power | POST /api/public/v1/quote/{mev,bridge,lrt} | Modeled risk context for an intended swap (kind: "swap"), bridge (kind: "bridge"), or LRT restake (kind: "restake"): modeled premium/exposure estimate + trust envelope. |
| routescore_policy_evaluate | power | POST /api/public/v1/policy/evaluate | Deterministic, advisory allow \| warn \| block decision for a declared agent policy against a route/strategy context, with cited reasons + trust envelope. |
check_swap and get_preflight_record work on the free agent tier (mint a
key at no cost); the quote and policy actions need a higher tier. All quote
figures are modeled premium/exposure estimates — not a live cover, insurance,
refund, or premium-acceptance offer, and not a guarantee of outcome. A caution
or block is decision support, not an instruction; a clear verdict or an
allow is not a recommendation to trade.
Output contract — the trust envelope
Every action result is a JSON string that preserves the full Routescore trust envelope. Downstream agents should reason over these fields by default:
{
"action": "routescore_quote_check",
"premium_bps": 4.2,
"score_state": "valid",
"source_freshness": { "state": "fresh", "checked_at": "…", "sources": [ … ] },
"methodology_version": "routescore.public_api.v1",
"confidence_band": { "low": 3.1, "high": 9.4, "unit": "bps", "label": "calibrated" },
"caveats": [
"Modeled, point-in-time decision support. Not an execution guarantee."
],
"commercial_disclosure": { "paid_placement": false, "score_influenced_by_partner": false },
"generated_at": "…",
"decision_support_only": true,
"trust": { "…": "the same envelope, mirrored" },
"envelope_status": "upstream",
"non_execution_disclaimer": "Routescore is read-only decision support: it does not execute trades, sign transactions, or move funds; results are modeled, point-in-time context, not advice or an instruction to act."
}Honest failure states, never silent omission:
- Upstream response missing any envelope field →
score_state: "degraded"with an explicit caveat (the wrapper never presents an unverifiable number as trustworthy). - HTTP error or unreachable API →
score_state: "unavailable"with the status and reason inerror— no default is substituted. stale/partial/unsupportedupstream states pass through unchanged; a weaker score state means weaker evidence, not lower risk.
Install & configure
Install from npm:
npm install @routescore/agentkit @coinbase/agentkitThe provider is published as
@routescore/agentkit —
0.x, explicitly unstable semver we own. Its canonical source lives in the
Routescore monorepo; the prepared upstream contribution to coinbase/agentkit
is held (see external-pr/).
Get an API key (rs_live_…, shown once) at
routescore.io/account
→ Developer → API & MCP access. It is free to mint on any tier;
routescore_check_swap and routescore_get_preflight_record work on the free
agent tier, and the quote / policy actions unlock on higher tiers.
| Env var | Required | Default |
|---|---|---|
| ROUTESCORE_API_KEY | yes | — |
| ROUTESCORE_API_URL | no | https://www.routescore.io (use www, the apex redirects) |
Cookbook: an agent that asks Routescore before acting
LangChain + AgentKit (the AgentKit-native getLangChainTools runner):
import { AgentKit, cdpApiActionProvider, walletActionProvider } from "@coinbase/agentkit";
import { getLangChainTools } from "@coinbase/agentkit-langchain";
import { ChatOpenAI } from "@langchain/openai";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { routescoreActionProvider } from "@routescore/agentkit";
const agentKit = await AgentKit.from({
cdpApiKeyId: process.env.CDP_API_KEY_ID,
cdpApiKeySecret: process.env.CDP_API_KEY_SECRET,
actionProviders: [
walletActionProvider(),
cdpApiActionProvider(),
// Read-only Routescore preflight — needs ROUTESCORE_API_KEY in env.
routescoreActionProvider(),
],
});
const agent = createReactAgent({
llm: new ChatOpenAI({ model: "gpt-4o-mini" }),
tools: await getLangChainTools(agentKit),
stateModifier: [
"Before signing any onchain swap, call routescore_check_swap with the",
"notional, chain, and (if known) route and token_out, and read the verdict,",
"reasons, and caveats. If the verdict is 'unsupported', or 'caution' on a",
"point that matters, surface the reasons to the user before proceeding.",
"For deeper checks you may also call routescore_quote_check and",
"routescore_policy_evaluate against the declared policy. Persist evidence:",
"the record_id check_swap returns can be re-fetched with",
"routescore_get_preflight_record for an offline-verifiable record.",
"Routescore output is modeled, point-in-time context — not advice, and",
"never an instruction to act.",
].join(" "),
});
const result = await agent.invoke({
messages: [
{
role: "user",
content: "Swap 50,000 USDC to ETH on Base if my policy allows it.",
},
],
});A typical preflight sequence the agent runs:
routescore_check_swap→{ "notional_usd": 50000, "chain_id": 8453, "route": "uniswap-v3", "token_out": "ETH" }→clear | caution | unsupportedverdict + reasons + caveats +record_id.- (optional, power tier)
routescore_quote_check→{ "kind": "swap", "notional_usd": 50000, "asset_pair": "USDC/ETH", "route": "uniswap-v3", "chain_id": 8453 }androutescore_policy_evaluate→{ "policy": "autonomous-agent-strict", "context": { "action": "swap", "notional_usd": 50000, "route": "uniswap-v3" } }. routescore_get_preflight_record→{ "record_id": "<from step 1>" }to keep an offline-verifiable evidence record.- The agent reasons over the
verdict,score_state,caveats, and any policy decision, then acts (or declines to act) through its own wallet tooling — never through Routescore.
Honest limitations
- Read-only. Routescore never executes, routes, signs, or custodies anything. There is no "execute the checked route" action, by design.
- Modeled, point-in-time. Figures are model outputs about a moment, not
measured outcomes and not a durable state of the world. Public calibration
evidence is published as it accrues; until then treat confidence bands as
labeled (
not_calibratedwhere applicable). - Not advice. Nothing in a result is investment advice or a
recommendation; advice-seeking requests to
policy/evaluateare refused server-side and surfaced asrefused: true. - Coverage. Quote endpoints cover EVM-family contexts (e.g. chain ids 1,
8453). Unsupported inputs come back
unsupportedrather than approximated. - Envelope stripping is the main misuse risk. Agents that drop
caveats/score_stateand treat a number as an instruction defeat the contract — the conformance tests in this package fail if the provider ever drops an envelope field, and the payload carries the non-execution disclaimer inline so a bare number never travels alone. - Rate limits apply per key; responses carry
X-RateLimit-*headers. - Requires a paid (Power-tier) key. Key signup: routescore.io/account.
Develop & test
npm install
npm run typecheck
npm test # conformance + claims-copy guardrail (vitest)The conformance suite (src/routescoreActionProvider.test.ts) asserts every
canonical envelope key against ENVELOPE_KEYS and fails if any field is
dropped; the claims guardrail (src/claims-copy.test.ts) enforces the
Routescore claims vocabulary (see divisions/sojourn/CLAIMS_BOUNDARY_QA.md).
Upstream contribution
The adapted provider for coinbase/agentkit (their repo layout, jest tests,
changeset, README) plus exact founder submission steps live in
external-pr/. Submission is founder-gated — do not fork or
open the upstream PR from automation.
