SoroTask Keeper CI Rust Contract CI
SoroTask is a decentralized automation marketplace on Soroban. It allows users to schedule recurring tasks (like yield harvesting) and incentivizes Keepers to execute them.
See the Glossary for definitions of terms used in this project.
Project Structure /contract: Soroban smart contract (Rust). Contains TaskConfig struct and core logic. /keeper: Off-chain bot (Node.js). Monitors the network and executes due tasks. /frontend: Dashboard (Next.js + Tailwind). Interface for task creation and management. Setup Instructions Quick Start with Docker (Recommended) The fastest way to run a Keeper is using Docker:
cp keeper/.env.example keeper/.env
docker compose up -d
docker compose logs -f keeper curl http://localhost:3001/health See keeper/README.md for detailed Docker deployment documentation.
Manual Setup
- Smart Contract cd contract cargo build --target wasm32-unknown-unknown --release
- Keeper Bot cd keeper npm install node index.js
- Frontend Dashboard cd frontend npm run dev Architecture System Overview The SoroTask ecosystem operates through a coordinated loop between Users, the Smart Contract, Keepers, and Target Contracts:
flowchart TB subgraph User_Layer["User Layer"] User["👤 User\n(Task Creator)"] Dashboard["🖥️ Frontend Dashboard\n(Next.js)"] end
subgraph Contract_Layer["Smart Contract Layer"]
SoroTask["📜 SoroTask Contract\n(Soroban/Rust)"]
Resolver["⚖️ [Resolver](GLOSSARY.md#resolver) Contract\n(Optional Condition)"]
end
subgraph Keeper_Layer["Keeper Layer"]
Keeper["🤖 Keeper Bot\n(Node.js)"]
Poller["📡 Task Poller"]
Executor["⚡ Task Executor"]
end
subgraph Target_Layer["Target Layer"]
TargetContract["🎯 Target Contract\n(User-Defined)"]
end
%% User Registration Flow
User -->|"1. Creates Task via UI"| Dashboard
Dashboard -->|"2. register\nTaskConfig"| SoroTask
%% Keeper Monitoring Flow
SoroTask -->|"3. Query Tasks"| Poller
Poller -->|"4. Check Intervals\n& Conditions"| Keeper
%% Execution Flow
Keeper -->|"5. execute\ntask_id"| SoroTask
SoroTask -->|"6. check_condition\n(optional)"| Resolver
Resolver -->|"7. Returns true/false"| SoroTask
SoroTask -->|"8. Invoke target function"| TargetContract
%% Feedback Loop
TargetContract -->|"9. Execution Result"| SoroTask
SoroTask -->|"10. Update last_run\n& Emit Events"| SoroTask
%% Styling
style User_Layer fill:#e1f5ff
style Contract_Layer fill:#fff4e1
style Keeper_Layer fill:#f0e1ff
style Target_Layer fill:#e1ffe1
Component Interaction Flow sequenceDiagram participant User participant Dashboard participant SoroTask as SoroTask Contract participant Keeper as Keeper Bot participant Target as Target Contract
Note over User,Keeper: Registration Phase
User->>Dashboard: Create automation task
Dashboard->>SoroTask: register(TaskConfig)
SoroTask->>SoroTask: Store task & emit event
SoroTask-->>Dashboard: Task ID assigned
Dashboard-->>User: Task registered successfully
Note over SoroTask,Keeper: Monitoring Phase
Keeper->>SoroTask: get_task(taskId)
SoroTask-->>Keeper: TaskConfig {interval, last_run, ...}
Keeper->>Keeper: Check: now >= last_run + interval
Note over SoroTask,Keeper: Execution Phase
Keeper->>SoroTask: execute(keeper, taskId)
SoroTask->>SoroTask: Validate keeper (whitelist)
SoroTask->>SoroTask: Check interval elapsed
opt If resolver is set
SoroTask->>SoroTask: Call resolver.check_condition()
SoroTask-->>SoroTask: Returns true/false
end
SoroTask->>Target: Invoke target.function(args)
Target-->>SoroTask: Execution result
SoroTask->>SoroTask: Update last_run timestamp
SoroTask-->>Keeper: Success
Keeper->>Keeper: Log execution & metrics
Architecture Summary Register: User registers a task via Contract. Monitor: Keepers scan for due tasks. Execute: Keeper executes the task and gets his Incentive. Git Hooks This project uses Husky and lint-staged to enforce code quality automatically on every commit.
What runs on git commit:
eslint --fix + prettier --write on all staged .js, .jsx, .ts, and .tsx files. prettier --write on all staged .json, .md, .yml, and .yaml files. Only staged files are processed, so commits stay fast regardless of monorepo size.
Setup (first time after cloning):
npm install The prepare script runs husky automatically, installing the hooks.
Bypassing hooks (emergency use only):
git commit -m "your message" --no-verify
Monitoring The Keeper exposes HTTP endpoints for health checks and operational metrics.
Health Check Endpoint: GET /health Port: 3001 (configurable via METRICS_PORT)
Returns the current health status of the Keeper process.
Response (200 OK):
{ "status": "ok", "uptime": 3600, "lastPollAt": "2024-01-15T10:30:00.000Z", "rpcConnected": true } Response (503 Service Unavailable):
{ "status": "stale", "uptime": 3600, "lastPollAt": "2024-01-15T10:25:00.000Z", "rpcConnected": false } The endpoint returns 503 if the last poll timestamp is older than HEALTH_STALE_THRESHOLD_MS (default: 60000ms).
Metrics Endpoint: GET /metrics Port: 3001 (configurable via METRICS_PORT)
Returns operational statistics for monitoring task execution performance.
Response (200 OK):
{ "tasksCheckedTotal": 1250, "tasksDueTotal": 45, "tasksExecutedTotal": 42, "tasksFailedTotal": 3, "avgFeePaidXlm": 0.0001234, "lastCycleDurationMs": 1523 } Metrics:
tasksCheckedTotal: Total number of tasks checked across all polling cycles tasksDueTotal: Total number of tasks that were due for execution tasksExecutedTotal: Total number of successfully executed tasks tasksFailedTotal: Total number of failed task executions avgFeePaidXlm: Rolling average of transaction fees paid (XLM) lastCycleDurationMs: Duration of the most recent execution cycle (milliseconds) Note: All metrics are in-memory and reset on process restart.
Environment Variables METRICS_PORT=3001 # Port for metrics/health server (default: 3001) HEALTH_STALE_THRESHOLD_MS=60000 # Health staleness threshold (default: 60000ms) MAX_CONCURRENT_EXECUTIONS=3 # Max concurrent task executions (default: 3)
Task to be completed;
Contributor Focus: [Process Safety] Shut the backend down cleanly without abandoning critical in-flight work abruptly ETA: 2 days
Context Deployments and incident response often require stopping the keeper process.
Problem Hard shutdowns can interrupt transaction submission, drop execution context, or leave partial operational state behind.
Task Breakdown Define the keeper shutdown lifecycle and drain policy. Stop accepting new work while in-flight operations finish or time out cleanly. Emit clear shutdown progress logs and final summaries. Ensure retries or locks recover correctly after shutdown. Add tests or scripted validation for stop behavior. Acceptance Criteria The keeper can stop gracefully. In-flight operations are drained or bounded predictably. Shutdown state is visible in logs. Restart behavior after graceful stop remains correct.
I am working on a project with a team of software engineers on an open source project. I want you to take the role of a web developer with more than 15 years of experience to help me on my assingment that is required for the project. You are to execute only what required in this assignment of this project. You must provide a step-by-step process for me to test that i have successfully completed my assignment. Remember, you a web developer with more than 15 years of experience so as to help me on my assingment that is required for the project and you are to execute only what required in this assignment of this project.