TLDR: FarmDash Signal Architect is a zero-custody agent-to-agent swap routing layer. Autonomous agents authenticate with EIP-191 wallet signatures, get quotes from aggregated liquidity (Li.Fi, 0x, Alchemy x402), and receive ready-to-sign calldata without handing over custody. The FarmDash agent-kit source package provides a typed TypeScript client with built-in retry, LRU caching, and Dust Storm resilience. This guide is the single reference for every agentic subsystem.
What is the Signal Architect?
The Signal Architect is FarmDash's non-custodial routing layer for autonomous agents. It sits between an agent (Eliza, LangChain, OpenClaw, or any HTTP client) and the underlying swap protocols. FarmDash never holds funds or keys. It returns EVM calldata that the agent signs and broadcasts on its own.
| Layer | Role | Who Controls It |
|---|---|---|
| Agent (Eliza, LangChain, etc.) | Decides what to trade and when | The agent operator |
| Signal Architect API | Selects the best protocol, attaches the fee, returns calldata | FarmDash |
| Swap Protocol (Li.Fi, 0x, x402) | Executes the on-chain swap | The protocol's smart contracts |
| Blockchain | Settles the trade | The EVM network |
The core design principle: FarmDash is the Matchmaker, not the Bank. The protocol executes the swap. FarmDash collects a fee haircut routed directly to the treasury wallet. No escrow, no custody.
How Does the Architecture Work?
Agent Wallet
|
| EIP-191 signed POST /api/agents/swap
v
Signal Architect API
|
+---> Agent Auth (verify EIP-191 signature + nonce)
+---> Rate Limiter (20 req/60s per agent address)
+---> Toll Booth (Scout / Pioneer / Syndicate tier check)
+---> Route Selector (x402 > Li.Fi > 0x)
+---> Fee Engine (attach 25-75bps based on volume)
|
v
Swap Protocol (Li.Fi / 0x / x402)
|
v
txData returned to agent (never FarmDash custody)
What Are the API Endpoints?
FarmDash exposes core swap endpoints plus advanced intelligence and automation endpoints. All live under https://www.farmdash.one/api.
POST /api/agents/swap
The main swap execution endpoint. Requires EIP-191 authentication.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
fromChainId |
number | Yes | Source chain (e.g., 8453 for Base) |
toChainId |
number | Yes | Destination chain |
fromToken |
string | Yes | Source token address (0x...) |
toToken |
string | Yes | Destination token address |
fromAmount |
string | Yes | Amount in wei |
agentAddress |
string | Yes | Initiating agent wallet |
toAddress |
string | Yes | Receiving wallet |
signature |
string | Yes | EIP-191 signature of the payload |
nonce |
string | Yes | Timestamp nonce (ms) |
slippage |
number | No | Slippage tolerance 0.01-5 (default 0.5%) |
protocol |
string | No | Force a specific protocol (lifi, zerox, x402) |
volumeHintUSD |
number | No | Agent-supplied USD estimate to unlock volume fee discounts |
Response: A SwapQuote object containing txData (calldata ready for the agent to sign and broadcast), estimatedOutput, feeBps, feeAmountUSD, gasEstimate, and expiresAt (30 second TTL).
GET /api/agents/quote
Preview a swap quote without authentication. Useful for agents to compare pricing before committing to a signed request.
Query Parameters: fromChainId, toChainId, fromToken, toToken, fromAmount, and optionally protocol.
GET /api/agents/history
Query fee event history and aggregate metrics. Supports pagination.
Query Parameters: agentAddress (optional filter), limit (default 50, max 200), offset. Add ?metrics=true for aggregate revenue dashboard.
GET /api/v1/agent/protocols
Returns the ranked protocol dataset with Trail Heat scores. Response depends on the caller's tier (Scout gets top 3 with masked numbers, paid tiers get the full dataset).
Advanced intelligence endpoints
GET /api/v1/agent/chain-breakdownGET /api/v1/agent/sybil-auditPOST /api/v1/agent/simulate-pointsPOST /api/v1/agent/optimize-portfolioGET /api/v1/agent/historical-trailheatGET /api/v1/agent/eventsGET|POST|DELETE /api/v1/agent/webhooksGET|POST /api/v1/agent/intent
Premium endpoints return a structured 503 feature_not_ready response if their backing infrastructure has not been provisioned in the current deployment yet.
How Does EIP-191 Authentication Work?
Unlike traditional APIs that require hardcoded API keys, the Signal Architect uses cryptographic wallet signatures. This is critical for autonomous agents because it means no secrets need to be stored in environment variables or passed through untrusted networks.
Step 1: The agent constructs a deterministic payload string:
FARMDASH_SWAP:{fromChainId}:{toChainId}:{fromToken}:{toToken}:{fromAmount}:{agentAddress}:{toAddress}:{nonce}
All addresses must be lowercase. The nonce is the current timestamp in milliseconds.
Step 2: The agent signs this string using personal_sign (EIP-191) with its own private key.
Step 3: FarmDash reconstructs the same payload, recovers the signer address from the signature, and verifies it matches the claimed agentAddress.
Step 4: The nonce is validated against a 60-second window to prevent replay attacks. If the nonce is stale or from the future, the request is rejected.
This approach means agents never need to share private keys with FarmDash, and every request is cryptographically bound to the wallet that initiated it.
How Does Protocol Routing Work?
The Route Selector picks the optimal swap protocol based on chain topology:
| Condition | Protocol Selected | Why |
|---|---|---|
| Both chains are Base (8453) | x402 (Alchemy) | Fastest and cheapest on Base L2 |
| Different source and destination chains | Li.Fi | Handles bridging natively across 60+ chains |
| Same chain, not Base | 0x | Single-chain EVM fallback with deep liquidity |
Agents can override this by passing protocol in the request body, but the automatic selection covers the optimal path for the vast majority of trades.
Built-in fallback: If the primary protocol fails (e.g., Li.Fi is degraded) and the trade is single-chain, the fee engine automatically retries with 0x as a fallback.
How Does the Fee Engine Work?
FarmDash attaches a percentage-based fee to each swap. The fee is routed directly to the FarmDash treasury wallet by the underlying protocol, never held in escrow.
Volume-Based Fee Discounts
The fee engine supports volume-based tiering to incentivize high-volume agents. When an agent provides a volumeHintUSD field in the swap request with its own estimate of the trade's USD value, the fee engine calculates a discount:
| Trade Volume (USD) | Fee Rate | Savings vs Standard |
|---|---|---|
| Under $10,000 | 75 bps (0.75%) | Standard rate |
| $10,000 - $99,999 | 35 bps (0.35%) | 53% discount |
| $100,000+ | 25 bps (0.25%) | 67% discount |
The volumeHintUSD is optional. If omitted, the standard 75bps rate applies. This is an agent-supplied hint (not server-verified), designed for honest high-volume routing agents that benefit from lower fees in exchange for higher throughput.
The default fee rate can also be overridden globally via the FARMDASH_FEE_BPS environment variable.
What is the Toll Booth Tier System?
All API endpoints pass through a toll booth that determines the caller's access level. FarmDash uses three tiers:
Scout (Free Tier)
- Rate limit: 5 requests per 24 hours (IP-based via Upstash Redis)
- Data access: Top 3 protocols only, numerical values masked
- Authentication: None required
- CORS: Open (
*) - After limit exceeded: Returns HTTP 402 with x402 payment headers
Pioneer (Paid Tier)
- Rate limit: 500 requests per 24 hours (API key via
Authorization: Bearer) - Data access: Full unmasked dataset
- Authentication:
FARMDASH_PIONEER_KEYenv var - CORS: Restricted to
farmdash.oneorigins only - After limit exceeded: Returns HTTP 429
Syndicate (Enterprise Tier)
- Rate limit: 50,000 requests per 24 hours (API key)
- Data access: Full dataset, no restrictions
- Authentication:
FARMDASH_SYNDICATE_KEYenv var - CORS: Open (
*) for full programmatic access - After limit exceeded: Returns HTTP 429
The x402 Payment Wall
When Scout tier is exhausted, the API returns HTTP 402 with payment headers that conform to the emerging x402 protocol standard:
| Header | Value | Purpose |
|---|---|---|
X-Payment-Required |
true |
Signals payment is needed |
X-Payment-Address |
Treasury wallet | Where to send payment |
X-Payment-Token |
USDC on Base | Payment denomination |
X-Payment-Amount |
Amount in wei | Cost per request |
X-Payment-Chain-Id |
8453 |
Base chain |
This enables agents with x402 support to automatically pay for continued access without human intervention.
What is the agent-kit SDK?
The FarmDash agent-kit source package is a typed TypeScript SDK that wraps read endpoints with built-in retry logic, caching, and graceful failure handling. It is designed for agents that need a reliable client without rebuilding request logic from scratch.
Installation
git clone https://github.com/Parmasanandgarlic/farmdashbeta.git
cd farmdashbeta
npm install ./agent-kit
Quick Start
import { FarmDashClient } from '@farmdash/agent-kit';
const client = new FarmDashClient({
apiKey: process.env.FARMDASH_SYNDICATE_KEY, // optional
cache: { mode: 'memory', ttlMs: 60_000 },
});
// Fetch ranked protocol dataset
const protocols = await client.getProtocols();
if (protocols.ok) {
console.log(`Found ${protocols.data.count} protocols (tier: ${protocols.data.tier})`);
}
// Preview a swap quote
const quote = await client.getQuote({
fromChainId: 8453,
toChainId: 8453,
fromToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC
toToken: '0x4ed4e862860bef6f5bc2b489d12a64703a110a12', // DEGEN
fromAmount: '1000000', // 1 USDC in wei
});
// Query swap history for a specific agent
const history = await client.getSwapHistory({
agentAddress: '0xYourAgentWallet...',
limit: 20,
});
// Fetch aggregate revenue metrics
const metrics = await client.getRevenueMetrics();
if (metrics.ok) {
console.log(`Total volume: $${metrics.data.totalVolumeUSD}`);
}
SDK Methods
| Method | Endpoint | Description |
|---|---|---|
getProtocols() |
GET /v1/agent/protocols |
Ranked protocol dataset with Trail Heat scores |
getQuote(params) |
GET /agents/quote |
Preview swap pricing without authentication |
getSwapHistory(params) |
GET /agents/history |
Fee event history with pagination |
getRevenueMetrics() |
GET /agents/history?metrics=true |
Aggregate fee/volume/swap/agent counts |
getChainBreakdown() |
GET /v1/agent/chain-breakdown |
Protocol distribution across chains |
auditSybilRisk() |
GET /v1/agent/sybil-audit |
Wallet cluster risk scoring |
simulatePoints() |
POST /v1/agent/simulate-points |
FarmScore what-if projection |
optimizePortfolio() |
POST /v1/agent/optimize-portfolio |
Ranked reallocation suggestions |
getHistoricalTrailHeat() |
GET /v1/agent/historical-trailheat |
Trend snapshots |
getAgentEvents() |
GET /v1/agent/events |
Event polling |
subscribeWebhook() / listWebhooks() |
`POST | GET /v1/agent/webhooks` |
All methods return an ApiEnvelope<T> with ok: true/false, typed data, optional warnings, and meta (including cache status and ETag).
How Does Dust Storm Resilience Work?
When the network fails (timeout, DNS error, etc.), the SDK does not throw. Instead it returns a successful envelope with an empty data shape and a dust_storm warning:
{
ok: true,
data: { tier: 'scout', count: 0, data: [] },
warnings: [{ kind: 'dust_storm', message: 'network_error' }],
meta: { cached: false }
}
This prevents autonomous agents from crashing on transient network failures. The agent can check for warnings and decide whether to retry, use stale cache, or skip the operation.
How Does Caching Work?
The SDK supports three cache modes:
| Mode | Storage | Best For |
|---|---|---|
memory |
In-process Map with LRU eviction (max 256 entries) | Server-side agents, short-lived processes |
idb |
Browser IndexedDB via idb-keyval |
Browser-based agents, persistent cache |
none |
No caching | Testing, real-time requirements |
The memory cache uses LRU (Least Recently Used) eviction to prevent unbounded growth. When the cache exceeds 256 entries, the oldest unused entries are dropped first. Cache entries are also validated using ETag headers: when the server returns HTTP 304 (Not Modified), the cached data is returned and its freshness timestamp is refreshed automatically.
How Does Retry Logic Work?
All HTTP requests go through an exponential-backoff retry layer with jitter:
| Setting | Default | Description |
|---|---|---|
retries |
3 | Maximum retry attempts |
baseDelayMs |
250 | Initial delay before first retry |
maxDelayMs |
2500 | Maximum delay cap |
jitter |
0.2 | Random variance to prevent thundering herd |
retryOnStatuses |
408, 429, 500, 502, 503, 504 | HTTP codes that trigger retry |
These defaults can be overridden via the retry option in the client constructor.
SDK Type Exports
The SDK exports all relevant types for consumers building typed integrations:
import type {
ApiEnvelope,
ApiOkEnvelope,
ApiErrorEnvelope,
ChainBreakdownItem,
ChainBreakdownItemFull,
ChainBreakdownItemScout,
ChainBreakdownResponse,
ChainBreakdownSummary,
ChainBreakdownSummaryFull,
ChainBreakdownSummaryScout,
DustStormWarning,
FeeEvent,
HistoryParams,
HistoryResponse,
ProtocolItem,
ProtocolsResponse,
QuoteParams,
QuoteResponse,
RevenueMetrics,
SupportedProtocol,
SwapTxData,
Tier,
CacheMode,
CachedValue,
RetryOptions,
FarmDashClientOptions,
} from '@farmdash/agent-kit';
What is Trail Heat?
Trail Heat is FarmDash's 0-100 scoring system that ranks protocols by opportunity. The API endpoint (GET /api/v1/agent/protocols) returns Trail Heat scores for all tracked protocols. The score is computed from five factors:
| Factor | Calculation | Max Contribution |
|---|---|---|
| TVL | Logarithmic scale of Total Value Locked | 30 points |
| Status | Confirmed Airdrop (25), Points Program (18), Speculative (8) | 25 points |
| Category | Perps (15), Restaking (14), Lending (12), Bridge (10), DEX (9), etc. | 15 points |
| Momentum | Recency bonus decaying over 30 days for hot protocols | 15 points |
| Recency | Decay curve over 90 days from date added | 15 points |
Each protocol in the API response includes: protocol_name, trail_heat_score, sybil_risk, tvl, category, status, chains, and recommended_agent_deploy_link.
How Does Rate Limiting Work?
The swap endpoint (POST /api/agents/swap) has its own per-agent rate limiter separate from the toll booth:
- Limit: 20 requests per 60-second sliding window per agent address
- Scope: Per serverless instance (in-memory). For distributed limiting, upgrade to Redis.
- Response on limit: HTTP 429 with
Retry-Afterheader andretryAfterMsin the body
This is per-agent, not per-IP. It uses the agentAddress from the request body as the key, normalized to lowercase.
How Does Input Validation Work?
All endpoints validate inputs using a shared validation module. The following checks are enforced on the swap endpoint:
| Field | Rule | Error |
|---|---|---|
agentAddress, toAddress, fromToken, toToken |
Must be 0x + 40 hex characters |
"Invalid {field}" |
fromAmount |
Must be a non-zero, non-leading-zero digit string (wei) | "Invalid fromAmount (must be non-zero wei string)" |
fromChainId, toChainId |
Must be numbers | "Invalid chainId (must be number)" |
signature |
Must be 0x + hex string |
"Invalid signature" |
nonce |
Must be a non-empty string | "Missing nonce" |
slippage |
Must be 0.01 to 5 (if provided) | "Invalid slippage (must be 0.01-5)" |
The quote endpoint runs the same address and amount validations but does not require signature, nonce, or slippage.
How Does the Fee Event Logger Work?
Every executed swap logs a fee event to a Supabase fee_events table using a fire-and-forget pattern. The logger never blocks the swap response. If the write fails, it logs to console.error and moves on.
Logged fields: protocol, from_token, to_token, volume_usd, fee_bps, fee_usd, agent_address, tx_hash.
The revenue metrics endpoint aggregates these events server-side using a Supabase RPC function for efficient aggregation without transferring raw data to the edge.
Frequently Asked Questions?
What frameworks does the Signal Architect support?
Any framework that can make HTTP requests works. The API is a standard REST API. The FarmDash agent-kit source package provides a typed TypeScript client, and the Eliza framework has a dedicated Action implementation. OpenClaw agents can use the published raw FarmDash skill files at /openclaw-skills/.../SKILL.md.
Does FarmDash ever hold custody of agent funds?
No. FarmDash returns EVM calldata. The agent signs and broadcasts the transaction using its own private key. The swap protocol's smart contracts execute the trade. FarmDash treasury receives only the fee haircut, routed by the protocol itself.
How do volume-based fee discounts work?
Agents can pass a volumeHintUSD field in their swap request. If the value is $10,000 or more, the fee drops from 75bps to 35bps. At $100,000+, it drops to 25bps. This is opt-in and designed for honest high-throughput routing agents.
What happens when a swap protocol is down?
The fee engine has built-in fallback logic. If the primary protocol fails and the trade is single-chain, it automatically retries with 0x as a fallback. Cross-chain failures (Li.Fi) propagate as errors since no single-chain fallback can handle bridging.
How does the SDK handle network failures?
The SDK uses the Dust Storm pattern: instead of throwing exceptions, it returns ok: true with empty data and a dust_storm warning. This prevents agent crashes during transient outages and gives the agent the option to retry or degrade gracefully.
What is the nonce window for replay protection?
The nonce must be a timestamp within 60 seconds of the server's current time. Nonces from the future or older than 60 seconds are rejected. This prevents intercepted requests from being replayed.
Can agents force a specific swap protocol?
Yes. Pass protocol: 'lifi', protocol: 'zerox', or protocol: 'x402' in the swap request body. If omitted, the Route Selector automatically picks the optimal protocol based on chain topology.
How do I access Trail Heat data programmatically?
Use client.getProtocols() from the FarmDash agent-kit source package or call GET /api/v1/agent/protocols directly. Free tier returns the top 3 protocols with masked numbers. Paid tiers return the full ranked dataset.