Inspiration
DAO treasuries fail not because of bad intent but because a single AI agent has no one to argue with. We wanted to build a system where agents disagree, debate, and veto each other before a single satoshi moves — mirroring how real governance committees work.
What it does
SyndiChain is a five-agent AI swarm that manages crypto treasuries on the Somnia blockchain:
- Manager (Qwen-Plus) decomposes a plain-English goal into parallel sub-tasks
- Analyst (Qwen-Turbo) fetches live yield pools from Somnia Exchange and Potion Swap DEX
- Risk (Qwen-Turbo) queries
SomniaAgentRiskOracle.solon-chain and vetoes anything with risk score > 70 - Debate protocol — 2 rounds of LLM-powered arguments if Analyst and Risk disagree; Manager adjudicates
- Human escalation — deadlocked debates surface to the user with both sides presented
- Execution (Qwen-Turbo) encodes a gas-optimised Multicall3 batch via Somnia Agent Kit + viem
- Compliance verifies against
TreasuryPolicy.sol— daily limits, allowlists, multisig thresholds - Human approval → transaction broadcast to Somnia Testnet
Alongside the swarm, a keeper bot calls batchUpdateStreams() every 10 seconds on StreamPay.sol
so recipients can withdraw real-time STT streams without transactions reverting.
How we built it
- Next.js 14 App Router with
output: 'standalone'for Docker deployment - Qwen-Plus / Qwen-Turbo via Alibaba Cloud DashScope (
dashscope-intl.aliyuncs.com/compatible-mode/v1) - viem for all on-chain reads and writes (Somnia Testnet, Chain ID 50312)
- Somnia Agent Kit Multicall3 SDK for batched transaction encoding
- ioredis hybrid session store — in-memory for speed, Redis for persistence across restarts
- Multi-stage Dockerfile — Next.js standalone + keeper compiled to CommonJS via separate tsconfig
- GitHub Actions CI/CD — typecheck → Docker build/push → SSH deploy via
docker compose - Smart contracts on Somnia Testnet:
TreasuryPolicy.sol,SomniaAgentRiskOracle.sol,StreamPay.sol,StreamFactory.sol,StreamKeeper.sol,Multicall3
Challenges we faced
- viem v2 discriminated union —
maxFeePerGasandgasPricecannot coexist insendTransaction; required a typed branch to satisfy the compiler - ioredis in Next.js standalone — webpack externals are not bundled, so ioredis and its peer
dependencies had to be manually copied into
standalone/node_modules/in the Dockerfile - Stream withdrawals reverting —
StreamPay.solstoresrealTimeBalancein contract storage, only updated bybatchUpdateStreams. The keeper bot running every 10s solved this entirely - EIP-7702 type bleed — viem v2.19+ added
authorizationListto thereadContractunion, requiring a cast to bypass until the Agent Kit types are updated
What we learned
How to build production-grade multi-agent systems: structured debate protocols, hybrid persistence strategies, and the subtle differences between testnet RPC behaviour and what the ABI expects. Qwen-Plus for reasoning-heavy tasks and Qwen-Turbo for fast structured extraction was the right split — it kept latency under 10 seconds for the full swarm pipeline.
What's next
- Multisig threshold enforcement via on-chain governance votes
- Agent memory across sessions using vector embeddings
Built With
- alibaba-cloud
- css
- framer-motion
- multicall3
- next.js
- qwen
- rainbowkit
- recharts
- redis
- solidity
- somnia
- tailwind
- typescript
- viem
- wagmi
Log in or sign up for Devpost to join the conversation.