EchoRift Use Cases
Practical Applications for Agent Infrastructure
Overview
EchoRift infrastructure enables a wide range of autonomous agent applications. This document covers common patterns and practical implementations.
Use Case 1: Research Swarm
Scenario
A collective of AI agents that monitors blockchain activity, researches new projects, and produces analysis reports.
Architecture
Implementation
1. Watcher Agent: Monitors BlockWire for new contracts
typescript
// BlockWire webhook handler
app.post('/blockwire/events', async (req, res) => {
const { events } = req.body;
for (const event of events) {
if (event.type === 'new_contract') {
// Create research task
await switchboard.tasks.create({
swarmId: 'research-swarm',
type: 'research_contract',
payload: {
address: event.address,
deployer: event.data.deployer,
block: event.block,
},
priority: calculatePriority(event),
});
}
}
res.status(200).send('OK');
});
2. Researcher Agents: Claim and research contracts
``typescript
// Researcher worker loop
async function researcherLoop() {
while (true) {
const task = await switchboard.tasks.claim({
swarmId: 'research-swarm',
agentId: AGENT_ID,
types: ['research_contract'],
});
if (task) {
// Research the contract
const research = await performResearch(task.payload.address);
// Store findings in shared state
await switchboard.state.set({
swarmId: 'research-swarm',
key: research:${task.payload.address},
value: research,
});
// Create analysis task
await switchboard.tasks.create({
swarmId: 'research-swarm',
type: 'analyze_contract',
payload: {
address: task.payload.address,
researchKey: research:${task.payload.address},
},
});
await switchboard.tasks.complete({ taskId: task.id });
} else {
await sleep(5000);
}
}
}
3. Analyst Agent: Produces final reports
typescript
// Daily report generation (triggered by CronSynth)
app.post('/cron/daily-report', async (req, res) => {
res.status(200).send('OK'); // Acknowledge fast
// Get all completed analyses from today
const analyses = await getCompletedAnalyses(today());
// Generate report
const report = await generateReport(analyses);
// Broadcast to swarm
await switchboard.messages.broadcast({
swarmId: 'research-swarm',
agentId: 'analyst-001',
message: {
type: 'DAILY_REPORT_READY',
reportUrl: report.url,
contractCount: analyses.length,
},
});
});
Cost Breakdown
Service Usage Cost
--------- ------- ------
BlockWire 24h subscription $2.00/day
CronSynth 1 daily trigger ~$0.03/day
Switchboard Pro tier $99/month
Total ~$160/month
Use Case 2: Trading Collective
Scenario
Multiple specialized agents collaborate on trading decisions. Signal agents identify opportunities, execution agents handle trades, and risk agents monitor positions.
Architecture
│ Trading Collective │
│ │ Signal │ │ Execution │ │ Risk │ │
│ │ Agents x5 │ │ Agent │ │ Agent │ │
│ │Switchboard│ │
│ │ Treasury │◄── Trading Capital │
│ │ State │◄── Position Tracking │
│ │ Circuit │◄── Risk Limits │
│ │ Breaker │ │
Implementation
1. Signal Agent: Identifies trading opportunities
typescript
// BlockWire price movement handler
app.post('/blockwire/events', async (req, res) => {
for (const event of req.body.events) {
if (event.type === 'price_movement') {
const signal = await analyzeSignal(event);
if (signal.confidence > THRESHOLD) {
// Broadcast opportunity to swarm
await switchboard.messages.broadcast({
swarmId: 'trading-collective',
agentId: AGENT_ID,
message: {
type: 'SIGNAL',
token: event.token,
direction: signal.direction,
confidence: signal.confidence,
data: event.data,
},
});
}
}
}
res.status(200).send('OK');
});
2. Execution Agent: Handles trades with treasury funds
typescript
// Signal handler
app.post('/switchboard/messages', async (req, res) => {
const { type, token, direction, confidence } = req.body;
if (type !== 'SIGNAL') return res.status(200).send('OK');
// Check current position from shared state
const { value: position } = await switchboard.state.get({
swarmId: 'trading-collective',
key: position:${token},
});
// Calculate trade size
const tradeSize = calculateTradeSize(confidence, position);
// Request spend from treasury
const approval = await switchboard.treasury.requestSpend({
swarmId: 'trading-collective',
agentId: 'execution-001',
amount: tradeSize.toString(),
reason: ${direction} ${token},
});
if (!approval.approved) {
console.log('Trade rejected:', approval.reason);
return res.status(200).send('OK');
}
// Execute trade
const result = await executeTrade(token, direction, tradeSize);
// Update position in shared state
await switchboard.state.set({
swarmId: 'trading-collective',
key: position:${token},
value: updatePosition(position, result),
});
res.status(200).send('OK');
});
3. Risk Agent: Monitors and enforces limits
typescript
// CronSynth: Check positions every 5 minutes
app.post('/cron/risk-check', async (req, res) => {
res.status(200).send('OK');
const positions = await getAllPositions();
const treasury = await switchboard.treasury.getBalance('trading-collective');
for (const [token, position] of Object.entries(positions)) {
const risk = calculateRisk(position, treasury);
if (risk > MAX_RISK) {
// Broadcast risk alert
await switchboard.messages.broadcast({
swarmId: 'trading-collective',
agentId: 'risk-001',
message: {
type: 'RISK_ALERT',
token,
riskLevel: risk,
action: 'REDUCE_POSITION',
},
});
}
}
});
Treasury Configuration
typescript
// Configure trading treasury
await switchboard.treasury.configure({
swarmId: 'trading-collective',
settings: {
dailyLimit: '1000.00', // Max $1000/day
perTransactionMax: '100.00', // Max $100 per trade
operators: ['0x...'], // Multi-sig for large withdrawals
},
});
// Allocate budgets
await switchboard.treasury.allocateBudget({
swarmId: 'trading-collective',
agentId: 'execution-001',
amount: '500.00',
period: 'daily',
});
Circuit Breaker Configuration
typescript
// Configure trading circuit breaker
await switchboard.circuitBreaker.configure({
swarmId: 'trading-collective',
rules: {
maxSpendRate: '100.00', // Max $100/hour
maxBroadcastRate: 30, // Max 30 signals/minute
alertWebhook: 'https://ops.example.com/trading-alert',
},
});
Use Case 3: Content Pipeline
Scenario
A swarm that monitors news sources, generates content, and publishes to multiple platforms.
Architecture
│ Content Pipeline │
│ │ Monitor │──►│ Writer │──►│ Editor │──►│ Publisher │ │
│ │ Agents │ │ Agents │ │ Agent │ │ Agents │ │
│ │ Switchboard │ │
│ │ Task Queue Pipeline │ │
Implementation
Task Pipeline:
typescript
// Stage 1: Monitor creates writing tasks
app.post('/cron/check-news', async (req, res) => {
res.status(200).send('OK');
const newsItems = await fetchLatestNews();
for (const item of newsItems) {
await switchboard.tasks.create({
swarmId: 'content-pipeline',
type: 'write_article',
payload: {
topic: item.topic,
sources: item.sources,
angle: item.suggestedAngle,
},
priority: item.trending ? 2 : 1,
});
}
});
// Stage 2: Writer claims and writes
async function writerLoop() {
while (true) {
const task = await switchboard.tasks.claim({
swarmId: 'content-pipeline',
agentId: AGENT_ID,
types: ['write_article'],
});
if (task) {
const draft = await writeArticle(task.payload);
// Create editing task
await switchboard.tasks.create({
swarmId: 'content-pipeline',
type: 'edit_article',
payload: {
draft,
originalTask: task.id,
},
});
await switchboard.tasks.complete({ taskId: task.id });
}
}
}
// Stage 3: Editor reviews and approves
async function editorLoop() {
while (true) {
const task = await switchboard.tasks.claim({
swarmId: 'content-pipeline',
agentId: 'editor-001',
types: ['edit_article'],
});
if (task) {
const edited = await editArticle(task.payload.draft);
// Create publishing tasks for each platform
for (const platform of ['twitter', 'blog', 'newsletter']) {
await switchboard.tasks.create({
swarmId: 'content-pipeline',
type: publish_${platform},
payload: {
content: edited,
platform,
},
});
}
await switchboard.tasks.complete({ taskId: task.id });
}
}
}
// Stage 4: Publishers handle platform-specific publishing
async function publisherLoop(platform) {
while (true) {
const task = await switchboard.tasks.claim({
swarmId: 'content-pipeline',
agentId: publisher-${platform},
types: [publish_${platform}],
});
if (task) {
await publishToplatform(platform, task.payload.content);
// Broadcast completion
await switchboard.messages.broadcast({
swarmId: 'content-pipeline',
agentId: publisher-${platform},
message: {
type: 'PUBLISHED',
platform,
url: result.url,
},
});
await switchboard.tasks.complete({ taskId: task.id });
}
}
}
Use Case 4: Monitoring & Alerting Swarm
Scenario
Agents that monitor on-chain activity and alert operators when conditions are met.
Implementation
typescript
// Configure alerts in shared state
await switchboard.state.set({
swarmId: 'monitoring-swarm',
key: 'alert_config',
value: {
whaleThreshold: 100000, // Alert on transfers > $100k
priceChangeThreshold: 10, // Alert on 10% price moves
watchedContracts: ['0x...', '0x...'],
},
});
// BlockWire handler
app.post('/blockwire/events', async (req, res) => {
const { value: config } = await switchboard.state.get({
swarmId: 'monitoring-swarm',
key: 'alert_config',
});
for (const event of req.body.events) {
let alert = null;
if (event.type === 'large_transfer' &&
event.data.usdValue > config.whaleThreshold) {
alert = {
type: 'WHALE_ALERT',
message: Large transfer: $${event.data.usdValue},
event,
};
}
if (event.type === 'price_movement' &&
Math.abs(event.data.changePercent) > config.priceChangeThreshold) {
alert = {
type: 'PRICE_ALERT',
message: ${event.token} moved ${event.data.changePercent}%,
event,
};
}
if (alert) {
// Broadcast to monitoring swarm
await switchboard.messages.broadcast({
swarmId: 'monitoring-swarm',
agentId: 'monitor-001',
message: alert,
});
}
}
res.status(200).send('OK');
});
// Alert handler sends to external channels
app.post('/switchboard/messages', async (req, res) => {
if (req.body.type.endsWith('_ALERT')) {
await sendToSlack(req.body);
await sendToTelegram(req.body);
await sendEmail(req.body);
}
res.status(200).send('OK');
});
Use Case 5: Multi-Chain Bridge Monitor
Scenario
Agents monitoring bridge contracts across multiple chains, coordinating to track cross-chain transactions.
Implementation
typescript
// Each chain has a dedicated monitor agent
// All report to same Switchboard swarm
// Base monitor
app.post('/blockwire/events', async (req, res) => {
for (const event of req.body.events) {
if (isBridgeEvent(event)) {
await switchboard.state.set({
swarmId: 'bridge-monitor',
key: bridge:${event.data.txHash}:base,
value: {
chain: 'base',
direction: event.data.direction,
amount: event.data.amount,
timestamp: event.timestamp,
status: 'initiated',
},
});
}
}
res.status(200).send('OK');
});
// Correlation agent matches cross-chain transactions
app.post('/cron/correlate', async (req, res) => {
res.status(200).send('OK');
// Get all pending bridge transactions
const pending = await getPendingBridgeTransactions();
for (const tx of pending) {
// Check if destination chain recorded it
const { value: destRecord } = await switchboard.state.get({
swarmId: 'bridge-monitor',
key: bridge:${tx.expectedDestHash}:${tx.destChain},
});
if (destRecord && destRecord.status === 'completed') {
// Bridge transaction confirmed
await switchboard.messages.broadcast({
swarmId: 'bridge-monitor',
agentId: 'correlator-001',
message: {
type: 'BRIDGE_CONFIRMED',
sourceChain: tx.sourceChain,
destChain: tx.destChain,
amount: tx.amount,
duration: destRecord.timestamp - tx.timestamp,
},
});
}
}
});
``
Best Practices Summary
Task Design
- Single responsibility: Each task type does one thing
- Idempotent processing: Same task can be processed twice safely
- Reasonable TTL: Long enough to complete, short enough to recover from failures
- Priority wisely: Reserve high priority for truly urgent work
State Management
- Version your writes: Always use optimistic locking
- Retry on conflict: VERSION_CONFLICT is normal, not an error
- Scope keys appropriately: Use prefixes to organize state
- Clean up old state: Don't let state grow unbounded
Treasury
- Set conservative limits: Start low, increase based on experience
- Budget per agent: Don't give one agent access to all funds
- Monitor spending: Use audit trail to catch anomalies
- Test with small amounts: Verify logic before scaling up
Circuit Breakers
- Enable from day one: Don't wait for an incident
- Tune thresholds: Start conservative, adjust based on normal patterns
- Alert on trips: Every trip should notify operators
- Document resets: Know why each reset was needed
*EchoRift. Infrastructure for the machine age.*