Compose automated DeFi strategies with natural language.
Symphony lets anyone describe DeFi automation in plain English. Gemini AI parses your intent into a structured rule (one condition + one action), and Chainlink's CRE (Compute Runtime Environment) executes it on a decentralized oracle network — no bots, no centralized infrastructure.
Built for the Chainlink Hackathon — Tracks: CRE & AI, DeFi & Tokenization
- Node.js >= 20
- Bun (for CRE workflow)
- Foundry (for smart contracts)
- MongoDB (local or Atlas)
- MetaMask wallet with Sepolia ETH
- Gemini API key (free tier works)
git clone <repo-url>
cd symphony
cp .env.example .env
# Fill in .envInstall each workspace:
# Backend
cd backend && npm install && cd ..
# Frontend
cd frontend/symphony && npm install && cd ../..
# CRE workflow
cd symphony/symphony && npm install && cd ../..Start MongoDB if using local instance of it
cd contracts
# Load env
source ../.env
# Deploy SessionManager + SymphonyExecutor + Mocks
forge script script/DeploySymphony.s.sol:DeploySymphony \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEY \
--broadcast -vvvAfter deployment, copy the logged addresses into .env:
SYMPHONY_EXECUTOR_ADDRESS=0x...
SESSION_MANAGER_ADDRESS=0x...
# Terminal 1 — Backend (port 4000)
cd backend && npm run dev
# Terminal 2 — Frontend (port 3000)
cd frontend/symphony && npm run devNavigate to http://localhost:3000
User (Browser)
│
├── Compose: NL prompt → Gemini AI → Structured rule (1 condition + 1 action)
├── Dashboard: Live price, strategy cards, execution logs
│
▼
Backend (Express + MongoDB, port 4000)
│
├── /api/parse — Gemini AI parsing
├── /api/strategy — Strategy CRUD
├── /api/logs — Execution history
├── /api/demo — Mock price injection
│
▼
Chainlink CRE Workflow (DON)
│
├── Chainlink ETH/USD feed (on-chain price via EVMClient)
├── Fetch active strategies from backend (runInNodeMode)
├── Evaluate condition (price_below / price_above)
│
▼ (if condition met)
EVMClient.writeReport → SymphonyExecutor
│
├── SessionManager — verifies DON session key authorization
├── Aave V3 — withdraw
└── Uniswap V3 — swap
symphony/
├── contracts/ # Foundry — Solidity smart contracts
│ ├── src/
│ │ ├── SymphonyExecutor.sol # Per-user DeFi executor
│ │ ├── SessionManager.sol # Session key registry
│ │ ├── interfaces/
│ │ └── mocks/
│ ├── script/
│ │ └── DeploySymphony.s.sol
│ └── test/
│ └── SymphonyExecutor.t.sol
│
├── backend/ # Express.js API server
│ └── src/
│ ├── db/ # MongoDB connection & schemas
│ ├── models/ # Mongoose models (Strategy, ExecutionLog)
│ ├── routes/ # API routes (strategy, parse, demo, logs)
│ ├── services/ # Gemini parser, strategy manager, price service
│ ├── utils/ # Constants (token addresses), logger
│ └── index.ts # Server entry (port 4000)
│
├── frontend/symphony/ # Next.js 16 frontend
│ ├── app/ # Pages (landing, compose, dashboard, logs, strategy detail)
│ ├── components/ # React components
│ ├── hooks/ # useWallet, useStrategy, useLivePrice
│ ├── lib/ # API client, utilities
│ └── types/ # TypeScript types
│
├── symphony/ # Chainlink CRE workflow
│ └── symphony/
│ ├── main.ts # Workflow entry (~290 lines, compiles to WASM)
│ ├── config.*.json # Environment configs
│ └── workflow.yaml # CRE manifest
│
├── scripts/ # Demo & utility scripts
│ └── inject-mock-price.ts
└── .env.example
| Contract | Description |
|---|---|
SessionManager |
Per-user session key registry. Users call setSessionKey(addr) to authorize the DON. |
SymphonyExecutor |
Per-user DeFi executor. Queries SessionManager for auth. Executes Aave withdraw & Uniswap swap. |
MockAavePool |
Simulated Aave V3 pool for reliable demos |
MockUniswapRouter |
Simulated Uniswap V3 router with configurable rates |
cd contracts && forge test -vvvEach strategy has one condition and one action:
Conditions:
price_below— trigger when ETH drops below a USD thresholdprice_above— trigger when ETH rises above a USD threshold
Actions:
withdraw— withdraw from Aave V3swap— swap tokens on Uniswap V3
Example natural language inputs:
- "If ETH drops below $2000, withdraw all USDC from Aave"
- "When ETH goes above $3000, swap ETH to USDC on Uniswap"
- "If ETH falls below $2500, swap to USDC"
The CRE workflow runs on the Chainlink DON every 5 minutes:
- Read Chainlink ETH/USD price feed — on-chain via
EVMClient.callContract - Fetch active strategies — from backend API via
runInNodeMode - Evaluate conditions — compare price against each strategy's threshold
- Execute — if condition met, call
EVMClient.writeReportto triggerSymphonyExecutor
Symphony includes a demo mode that lets you inject mock ETH prices to trigger strategies on demand — perfect for presentations.
Open the Dashboard → use the Demo Mode toggle in the sidebar to inject a custom price.
See .env.example for all configuration options.
| Variable | Description |
|---|---|
GEMINI_API_KEY |
Google Gemini API key for NL parsing |
MONGODB_URI |
MongoDB connection string |
PRIVATE_KEY |
Deployer wallet private key (Sepolia) |
SYMPHONY_API_KEY |
Internal API key for CRE → backend auth |
SYMPHONY_EXECUTOR_ADDRESS |
Deployed SymphonyExecutor address |
SESSION_MANAGER_ADDRESS |
Deployed SessionManager address |
ENVIRONMENT |
demo or production |
MIT