If you are integrating cross-chain stablecoin movement in 2026, the fastest path is the one that matches where you are in the build cycle. Eco Routes ships three developer surfaces for the same routing logic — a CLI for evaluation and scripting, a TypeScript SDK for production apps, and a REST API for any language or custom infra. Pick one for tonight and graduate as your needs harden. This guide walks through each tier with real commands, real code, and the tradeoffs that matter at three in the morning when production is on fire.
Eco Routes is the developer surface over the stablecoin orchestration network that routes intents across 15+ chains with a unified stablecoin execution layer. The three surfaces share the same intent model, the same solver network, and the same finality guarantees — they differ only in how you talk to them. For the conceptual overview, see What is Eco Routes.
The three-tier developer journey
The mental model we recommend is a ladder:
CLI — you install, you type four words, you see a real cross-chain intent publish and fill. Goal: understand the product in under five minutes. No TypeScript, no auth headers, no contract ABIs.
SDK — you import `@eco-foundation/routes-sdk` into your TypeScript service, wire it to a wallet or a Fireblocks signer, and ship intents from your application logic. Goal: production integration in TypeScript with type-safe intents.
API — you call `api.eco.com/v1` endpoints from Python, Go, Rust, or whatever non-TypeScript stack you run. Goal: non-TS production integration or custom infra on top of the same routing logic.
Most teams climb all three rungs in order. A few jump straight to the API because they are a Go-native backend. A few stop at the SDK because it handles every case they have. Whichever surface you land on, the underlying network is the same — the solver network and finality behavior are identical across all three.
Tier 1: the CLI — quick evaluation in under five minutes
The CLI is designed for the first thirty minutes a developer spends evaluating the product. Install it globally, run one command, publish a real intent. No production SDK surface area, no TypeScript compile step.
Install
npm i -g eco-routes-cli
That is the whole install. It puts `eco-routes-cli` on your path. If you prefer to build from source, the repo at github.com/eco/routes-cli has a pnpm flow.
Four commands to know
eco-routes-cli chains— list all supported chains.eco-routes-cli tokens— list all configured tokens on every chain.eco-routes-cli publish— interactive wizard that walks you through source chain, destination chain, route token, amount, reward token, amount, deadlines, and confirmation.eco-routes-cli publish --source base --destination optimism --dry-run— skip the prompts and simulate the publish without broadcasting.
The wizard flow
`publish` without flags runs the interactive wizard. The UX looks like this:
? Select source chain: Base? Select destination chain: Optimism? Route token: USDC? Route amount: 100? Reward token: USDC? Reward amount: 101Intent published — tx: 0xabc123...def456
Behind the scenes the CLI built an intent, signed it with your configured private key, and broadcast it. A solver picks it up, fulfills on the destination chain, and the intent settles. The tx hash is the one on the source chain where the intent was published. For the intent lifecycle conceptually, see cross-chain intent protocols.
Useful flags
--source/-s— pre-fill source chain.--destination/-d— pre-fill destination.--private-key/-k— override the env-var private key for this run.--private-key-svm— same for Solana.--recipient— send the fulfillment to a different address than the signer.--rpc/-r— use a non-default RPC URL.--dry-run— simulate without broadcasting.--watch/-w— stay attached after publish and stream the fulfillment status.
Private-key formats
The CLI supports three signer ecosystems:
EVM: `0x` + 64 hex characters. Use
EVM_PRIVATE_KEYenv var or--private-key.Tron (TVM): 64 hex characters without
0x. UseTVM_PRIVATE_KEY.Solana (SVM): base58 OR JSON byte array OR comma-separated bytes. Use
SVM_PRIVATE_KEY.
Other environment variables you may want: EVM_RPC_URL, SVM_RPC_URL, TVM_RPC_URL, SOLVER_URL, QUOTES_PREPROD, and PORTAL_ADDRESS_* overrides per chain.
When to graduate
Graduate from CLI to SDK when one of three things happens:
You want intents to originate from your application code, not your shell.
You want to handle quote inspection, approval flows, or refund paths programmatically.
You want to sign through a custody provider (Fireblocks, Anchorage) rather than a raw private key.
Tier 2: the SDK — production TypeScript integration
The SDK is @eco-foundation/routes-sdk, a TypeScript package with a peer dependency on @eco-foundation/routes-ts (the generated types). It is viem-based, type-safe, and covers the full intent lifecycle — quote, approve, publish, fund, track, refund.
Install
npm install @eco-foundation/routes-sdk @eco-foundation/routes-ts viem
You also need a wallet client. Viem is the supported path — wagmi or ethers users can wrap but SDK primitives expect viem.
Core primitives
The SDK exposes three families of calls:
createSimpleIntent— build an intent for "send token X from chain A to token Y on chain B, reward Z." This is the everyday call for stablecoin transfers.createNativeSendIntent— intent variant that handles native gas tokens (ETH, SOL) as the reward or route asset.OpenQuotingClient— fetch quotes from the competitive solver quoting system. Returns per-solver offers so you can surface best-price to the user or auto-pick.
Minimum working example
import { RoutesService, OpenQuotingClient } from '@eco-foundation/routes-sdk';import { createWalletClient, http } from 'viem';import { privateKeyToAccount } from 'viem/accounts';import { base, optimism } from 'viem/chains';const account = privateKeyToAccount('0x...');const wallet = createWalletClient({ account, chain: base, transport: http() });const routes = new RoutesService({ wallet });const quoter = new OpenQuotingClient();// 1. Build an intent — move 100 USDC from Base to Optimismconst intent = await routes.createSimpleIntent({ originChain: base.id, destinationChain: optimism.id, routeToken: 'USDC', routeAmount: 100_000000n, // 100 USDC in 6-decimal base units rewardToken: 'USDC', rewardAmount: 101_000000n,});// 2. Fetch competitive quotesconst quotes = await quoter.getQuotes(intent);const bestQuote = quotes[0];// 3. Apply chosen quote and publishconst applied = routes.applyQuoteToIntent(intent, bestQuote);const txHash = await routes.publishAndFund(applied);console.log('Intent published:', txHash);That is a production-grade transfer, handled end to end. The SDK handles approvals, the CREATE2 vault deployment (~2,500 gas), event-log parsing, and the fulfillment watch. For the technical architecture, see What is Eco Routes.
Refund handling
If no solver fulfills the intent before the deadline, the SDK exposes a refund flow that reclaims the escrowed reward. Production apps should wire refund into their retry-and-error logic.
const status = await routes.parseIntentFromIntentCreatedEventArgs(receipt);// ... later, if deadline has passed and no fulfillment:const refundTx = await routes.refund(status.intentHash);
Custody-provider signing
Instead of a raw private key, wrap a Fireblocks, Anchorage, or BitGo signer into a viem-compatible wallet client. The companion repo eco-kms ships @eco-foundation/eco-kms-core, eco-kms-hd-wallets, eco-kms-wallets, and eco-kms-provider-aws for AWS KMS plus HD wallet flows. This is the production path for institutional signing.
Event tracking
Every intent emits an IntentCreated event on the source chain and an IntentFilled event on the destination. The SDK's parseIntentFromIntentCreatedEventArgs helper turns event args into a typed intent record. Wire these into your webhook or queue — see stablecoin webhook infrastructure for patterns.
Peer library: routes-ts
@eco-foundation/routes-ts is the generated types package. It declares the on-chain event shapes, the intent struct, and the ABI fragments. The SDK imports it; your app can import it directly for custom event decoding.
When to graduate
Graduate from SDK to API when your production stack is not TypeScript. Go, Python, Rust, Elixir, and Java services all talk to the same routing logic through HTTP; the SDK is a convenience for TS teams, not a requirement.
Tier 3: the API — any language, any infra
The Routes API exposes the same routing logic as the SDK via REST at https://api.eco.com/v1. It is the right surface for Go / Python / Rust backends, custom solver infra, and any case where TypeScript is not the right tool.
Base URL and auth
Base URL:
https://api.eco.com/v1Auth:
X-App-IDheader. No formal API-key scheme as of mid-2026 — pass a string that identifies your application. Example:'X-App-ID': 'my-app-name'.
The X-App-ID header is how solver-side attribution and debugging traces get tagged. Use a stable identifier per environment.
The 12 endpoints
Verb | Path | Purpose |
POST | /quotes | Single quote (v1) |
POST | /api/v2/quote | v2 quote |
POST | /api/v2/quote/reverse | Reverse-quote v2 |
POST | /quotes/get-exact-in-quotes | Exact-in quotes (v3) |
POST | /quotes/get-exact-out-quotes | Exact-out quotes (v3) |
POST | /quotes/get-single-quote | Single quote (v3) |
POST | /quotes/initiate-gasless-intent | Gasless intent init (v3) |
POST | /intentinitiationv2/initiate-gasless-intent | Gasless intent v2 |
POST | /quotes/get-intent-status | Intent status lookup |
POST | /quotes/get-intent-status-array | Batch intent status |
POST | /solver-registration/register-solver | Register a solver |
POST | /solver-registration/update-solver | Update solver config |
Hello-world: fetch a quote
The simplest real call is a quote request. The `intent` object has the same shape the SDK produces — source chain, destination chain, route and reward tokens and amounts. Here is a raw fetch example:
const response = await fetch('https://api.eco.com/v1/quotes', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-App-ID': 'my-app' }, body: JSON.stringify({ intent, originChain: intent.route.source })});const quote = await response.json();In Python:
import requestsr = requests.post('https://api.eco.com/v1/quotes', headers={'X-App-ID': 'my-app', 'Content-Type': 'application/json'}, json={'intent': intent, 'originChain': intent['route']['source']})quote = r.json()In Go:
body, _ := json.Marshal(map[string]interface{}{ "intent": intent, "originChain": sourceChainId,})req, _ := http.NewRequest("POST", "https://api.eco.com/v1/quotes", bytes.NewReader(body))req.Header.Set("X-App-ID", "my-app")req.Header.Set("Content-Type", "application/json")resp, _ := http.DefaultClient.Do(req)Every language has the same two-header, JSON-body pattern. That is the whole auth story. For broader API design context, see stablecoin API architecture.
Gasless intent flow
The gasless endpoints let an application initiate an intent without the user paying gas on the source chain. The flow is: the user signs an EIP-712 permit (ERC-3009 preferred, EIP-2612 fallback); the backend posts to /quotes/initiate-gasless-intent; Eco's operator wallet broadcasts the transaction; the user is refunded in the reward stream. See programmable stablecoin payments for the UX implications.
Batch status polling
/quotes/get-intent-status-array takes an array of intent hashes and returns the current status of each. Use this in your webhook reconciliation job — poll every N seconds for any intents that have not yet emitted a terminal status. Alternatively, consume the source-chain events directly via your own indexer.
Solver registration
The /solver-registration/* endpoints are for teams running their own solver infrastructure rather than consuming the existing solver network. This is an advanced path — most integrators do not need it. For a view of the solver market, see solver networks for stablecoins.
Quote version guidance
Three quote APIs coexist for backward compatibility:
v1 (
/quotes) — simplest shape, still supported.v2 (
/api/v2/quote) — adds reverse-quote and richer metadata.v3 (
/quotes/get-*) — latest generation, exact-in and exact-out variants, gasless initiation in one call.
New integrations should default to v3. v1 is maintained for existing callers.
Choosing the right tier
A quick decision table:
If you are | Start with |
Evaluating Eco for a decision in the next hour | CLI |
Running a TypeScript backend or Next.js app | SDK |
Running a Go / Python / Rust / Elixir / Java backend | API |
Writing agent code (LangChain, CrewAI, AgentKit) in TS | SDK |
Writing agent code in Python | API |
Building your own solver | API ( |
Shipping a cross-chain consumer wallet feature | SDK |
Building cross-chain treasury automation | SDK (TS) or API (non-TS), per the treasury automation guide |
Original framing: the "signature moment" for each tier
A question we often ask in developer-onboarding reviews: what is the exact moment a developer knows the tier is the right one for them?
CLI signature moment: running
eco-routes-cli publish --source base --destination optimismand seeing a real transaction hash on a block explorer within 30 seconds. That is when "Eco works" moves from belief to experience.SDK signature moment: the first production-Sentry-alert-free week after a merged PR that uses
createSimpleIntent. That is when the SDK has earned its place in your architecture.API signature moment: running the same intent from a Go service and a Python service simultaneously, both hitting the same solver network, both settling in the same block range. That is when you know the API gives you the same guarantees regardless of language.
Each moment is real and each is different. Plan for the moment you expect before you plan for the integration.
Composing with other Eco products
Routes (CLI, SDK, API) is one product in a broader Eco developer surface:
Permit3 — cross-chain token approvals with a single signature. Combine with Routes when you want one user signature to authorize many intents across chains.
Programmable Addresses — deterministic deposit addresses that auto-route funds on receipt. Combine with Routes when you need "anyone from anywhere can pay this address and funds land on chain X as stablecoin Y." See programmable stablecoin payments.
Crowd Liquidity — solver-side liquidity aggregation with roughly 10x capital efficiency versus single-pool liquidity. Combine with Routes at scale if you also run solver infrastructure.
None of these compositions require changes to your CLI / SDK / API choice. The primitives slot in alongside Routes, not underneath it.
Operational checklist
Before you ship a Routes integration to production, confirm:
You have a non-placeholder
X-App-IDset for every environment.Your intents have non-zero reward buffers over route amount (this is how solvers are compensated).
You handle the no-fill timeout case with a
refundpath.Your event-listener or poller is wired to both IntentCreated on the source chain and IntentFilled on the destination.
Your custody provider can sign viem-compatible transactions (for SDK path) or raw calldata (for API path).
Your rate limits, retry, and circuit-breaker logic handle network-level failures gracefully.
For the deeper production readiness walk-through, see the cross-chain stablecoin transfer checklist.
FAQ
Which Eco Routes surface should I start with?
Start with the CLI for evaluation (five minutes). Move to the SDK if you run a TypeScript production stack. Move to the API if you run any other language. All three use the same routing network and offer identical finality guarantees.
Is the Routes API free?
There is no formal key-based pricing as of mid-2026. Solvers earn from the reward margin on each intent; the API is the authorship surface. Integrators should still pass a stable X-App-ID for attribution and support.
How do I sign with Fireblocks instead of a raw private key?
Wrap your Fireblocks-compatible signer into a viem wallet client and pass it to RoutesService. Alternatively, use @eco-foundation/eco-kms-core and eco-kms-wallets for the canonical MPC/KMS signing path. Full Fireblocks or Anchorage policies are enforced at the custodian layer, not at the SDK layer.
Can I run my own solver?
Yes. The /solver-registration/* endpoints let you register a solver against the Routes network. This is an advanced integration and usually reserved for teams with dedicated cross-chain trading infrastructure. Most integrators consume the existing solver network. See solver networks for stablecoins.
What chains does the CLI support?
Run eco-routes-cli chains to see the live list. As of mid-2026 it includes 15+ chains — Ethereum, Optimism, Base, Arbitrum, HyperEVM, Plasma, Polygon, Ronin, Unichain, Ink, Celo, Solana, Sonic, BSC, and Worldchain — with active work to add more.
