SoarChain Observer is a Go application designed to monitor the SoarChain blockchain for runner_challenge transactions, store client earnings data in a PostgreSQL database, and provide an API for querying client earnings over specified time periods.
- Features
- Prerequisites
- Installation
- Configuration
- Running the Application
- API Usage
- Endpoints
- Request Parameters
- Response Format
- Examples
- Database Schema
- Development
- Project Structure
- Testing
- Deployment
- License
- Contact
- WebSocket Observer: Connects to the SoarChain blockchain node via WebSocket to listen for runner_challenge events.
- Data Storage: Parses incoming transactions and stores client earnings data in a PostgreSQL database.
- API Server: Provides a RESTful API to query client earnings, both lifetime and over specified time periods.
- Error Handling & Reconnection Logic: Robust handling of WebSocket disconnections with automatic reconnection attempts.
- Concurrent Processing: Efficient handling of high transaction volumes using Go's concurrency features.
- Go: Version 1.15 or higher.
- PostgreSQL: Version 12 or higher.
- Git: For cloning the repository.
- SoarChain Node: Access to a running SoarChain blockchain node with WebSocket support.
git clone https://github.com/Soar-Robotics/SoarchainObserver.git
cd SoarchainObserverEnsure you have Go modules enabled. Run:
go mod downloadgo build -o soarchainobserver cmd/observer/main.goSet up a PostgreSQL database and user:
-- Connect to PostgreSQL as the postgres user
sudo -u postgres psql
-- Create a database user
CREATE USER soaruser WITH PASSWORD 'yourpassword';
-- Create a database
CREATE DATABASE soarchain_db;
-- Grant privileges
GRANT ALL PRIVILEGES ON DATABASE soarchain_db TO soaruser;
-- Exit psql
\qCreate a config.json file in the root directory:
{
"rpc_endpoint": "ws://localhost:26657/websocket",
"api_endpoint": "http://localhost:8080"
}Create a .env file in the root directory:
DB_HOST=localhost
DB_PORT=5432
DB_USER=soaruser
DB_PASSWORD=yourpassword
DB_NAME=soarchain_dbEnsure your environment variables are loaded. If you're running the application directly, use the godotenv package or export them in your shell.
go run cmd/observer/main.goAlternatively, if you've built the executable:
./soarchainobserverThe application exposes a RESTful API to query client earnings data.
http://localhost:8080
Retrieve earnings data for a specific client.
-
URL Parameters:
:address(string) - Client's address.
-
Query Parameters:
period(string, optional) - Time period for earnings calculation. Defaults to1h(last one hour). Accepts durations like1h,24h,7d.
- period (optional):
Specifies the time duration over which to calculate earnings.
Format: A number followed by a time unit (e.g., 1h for one hour, 24h for twenty-four hours, 7d for seven days).
Supported units:
- ns - Nanoseconds
- us - Microseconds
- ms - Milliseconds
- s - Seconds
- m - Minutes
- h - Hours
- d - Days (custom unit, see note below)
Note: The standard Go time.ParseDuration does not support days (d), so if you wish to use days, you need to handle this conversion manually in the code.
-
Status Codes:
200 OK- Successful response.400 Bad Request- Invalid request parameters.404 Not Found- Client not found.500 Internal Server Error- Server error.
-
Response Body (JSON):
{
"address": "soar1...",
"pubkey": "026c28e2efdf...",
"total_lifetime_earnings": 123456789,
"earnings_over_period": 100000,
"period": "1h"
}Request:
GET http://localhost:8080/client/soar1exampleaddress?period=1hResponse:
{
"address": "soar1exampleaddress",
"pubkey": "026c28e2efdf...",
"total_lifetime_earnings": 5000000,
"earnings_over_period": 150000,
"period": "1h"
}Request:
GET http://localhost:8080/client/soar1exampleaddress?period=24hResponse:
{
"address": "soar1exampleaddress",
"pubkey": "026c28e2efdf...",
"total_lifetime_earnings": 5000000,
"earnings_over_period": 1200000,
"period": "24h"
}Defaults to the last 1 hour.
Request:
GET http://localhost:8080/client/soar1exampleaddressStores client information and total lifetime earnings.
- Columns:
address(TEXT, PRIMARY KEY)pub_key(TEXT)total_lifetime_earnings(BIGINT)
Stores individual earnings transactions with timestamps.
- Columns:
id(SERIAL PRIMARY KEY)client_address(TEXT, FOREIGN KEY to clients.address)earnings(BIGINT)timestamp(TIMESTAMP WITH TIME ZONE)
SoarchainObserver/
├── cmd/
│ └── observer/
│ └── main.go
├── internal/
│ ├── blockchain/
│ │ └── websocket.go
│ ├── config/
│ │ └── config.go
│ ├── models/
│ │ ├── client.go
│ │ └── client_earning.go
│ └── utils/
│ └── logger.go
├── config.json
├── .env
├── go.mod
├── go.sum
└── README.md
- Unit Tests: Implement unit tests for critical functions.
- Integration Tests: Test the observer and API server with a running SoarChain node and PostgreSQL database.
- API Testing: Use tools like Postman or curl to test API endpoints.
Create a service file at /etc/systemd/system/soarchainobserver.service:
[Unit]
Description=SoarChain Observer Service
After=network.target
[Service]
User=www-data
WorkingDirectory=/path/to/SoarchainObserver
EnvironmentFile=/path/to/SoarchainObserver/.env
ExecStart=/path/to/SoarchainObserver/soarchainobserver
Restart=always
[Install]
WantedBy=multi-user.targetCommands:
sudo systemctl daemon-reload
sudo systemctl start soarchainobserver
sudo systemctl enable soarchainobserverSet up Nginx to proxy requests to your API server and handle SSL termination.
- Install Nginx:
sudo apt install nginx- Configure Nginx:
server {
listen 80;
server_name observer.soarchain.com;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}- Obtain SSL Certificates:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d observer.soarchain.comThis project is licensed under the MIT License.
For questions or support, please contact:
- Name: Soar Robotics Team
- Email: alperen@soarrobotics.com
- Website: https://soarrobotics.com