@fidesbuild/router
v0.2.0
Published
FIDES ROUTER: an agent hands over every way to do a job; each is checked against the signed FIDES and simulated, and only the best valid one runs.
Maintainers
Readme
@fidesbuild/router
FIDES ROUTER for agents on Robinhood Chain: an agent hands over every way it could do a job, each one is checked against the FIDES its owner signed and simulated, and only the best valid one runs.
npm install @fidesbuild/router @fidesbuild/sdk viem
npx @fidesbuild/router # what it is, and how to try itHow a route is chosen
- Build. Each candidate becomes its own execution plan. A candidate that cannot be built is out.
- Check. Every action of every candidate is checked against the signed FIDES. A route is authorized as a whole: if one action is outside the FIDES (
SPEND_LIMIT_EXCEEDED,SELECTOR_NOT_ALLOWED,TARGET_NOT_ALLOWED, …) the whole route is out. There are no half-routes. - Floor. A candidate can carry the output it expects and the least it will accept (
expectedOut,minOut). Expected below the minimum is out. - Simulate. Every route left is simulated against the chain. A route that would fail is out, with the revert reason. Gas and each asset's outflow are measured from the simulation.
- Rank. Best output, then least spent, then fewest transactions, then least gas, then least risk. Risk counts steps that may fail without reverting the plan, plus offchain calls and x402 payments. Slippage is scored against the best quote in the set, in basis points. Pass
compareto rank your own way. - Run. Only the winner. Nothing valid, nothing runs (
NO_VALID_ROUTE).
The router chooses inside the FIDES. It can never choose a route the FIDES does not allow.
Use
import { route } from "@fidesbuild/router"
const r = await route({ client, fides, agent }, [
{ name: "v3", actions: swapActions(quoteV3), expectedOut: quoteV3.quotedOut },
{ name: "v2", actions: swapActions(quoteV2), expectedOut: quoteV2.quotedOut },
])
for (const m of r.ranked) console.log(m.name, m.valid ? "valid" : m.reasons.join("; "), m.gas, m.totalOutflow, m.slippageBps)
// send the winner through the hosted relayer, which pays the gas
const plan = r.plan(r.best.name)
await fetch("https://api.fidesbuilder.xyz/v1/plans/build", { method: "POST", body: toJson({ fides, actions: winnerActions }) })
await fetch(`https://api.fidesbuilder.xyz/v1/plans/${plan.planHash}/execute`, { method: "POST", body: toJson({ bundles: await plan.signedBundles() }) })With your own relayer account in the context, r.execute() sends the winner directly.
| Field | Meaning |
| --- | --- |
| ranked | Every candidate, valid first, best first, with valid, reasons, transactions, gas, outflow, totalOutflow, expectedOut, slippageBps, risk |
| best | The winner's metrics, or undefined when nothing is valid |
| plan(name) | A candidate's built plan |
| execute() | Sends the winner with the context's relayer |
Docs: https://fidesbuilder.xyz/docs/#/router
