- Add UniswapV3Service for reading TWAP prices from LP pools
- Add /uniswap routes for price queries and comparison
- Add pool configuration settings (SKQNT_WETH_POOL_V3, SKSV_WETH_POOL_V3)
- Add TWAP period configuration (default 30 min for manipulation resistance)
- Add price deviation threshold for peg monitoring
- Initialize Uniswap service in main.py lifespan
Features:
- TWAP (Time-Weighted Average Price) calculation
- Spot price reading for comparison
- Price comparison between oracle target and Uniswap market price
- Pool liquidity monitoring
- Automatic token0/token1 ordering detection
Configuration:
- UNISWAP_ENABLED: Enable/disable Uniswap price reading
- SKQNT_WETH_POOL_V3: SKQNT/WETH pool address (set after pool creation)
- SKSV_WETH_POOL_V3: SKSV/WETH pool address (set after pool creation)
- TWAP_PERIOD_SECONDS: TWAP calculation period (default 1800 = 30 min)
- UNISWAP_PRICE_DEVIATION_THRESHOLD: Alert threshold (default 0.02 = 2%)
New endpoints:
- GET /uniswap/status - Service status and configuration
- GET /uniswap/price/{token} - Get TWAP/spot price for token
- GET /uniswap/prices - Get all configured token prices
- GET /uniswap/compare/{token} - Compare oracle vs Uniswap price
- POST /uniswap/refresh - Force refresh prices from blockchain
|
||
|---|---|---|
| .forgejo/workflows | ||
| app | ||
| contracts | ||
| docs | ||
| src/config/skgentis-oracle-api | ||
| tests | ||
| .gitignore | ||
| deploy.j2 | ||
| deploy_skgentis-oracle-api-dev.yml | ||
| deploy_skgentis-oracle-api-prod.yml | ||
| deploy_skgentis-oracle-api-staging.yml | ||
| Dockerfile | ||
| ENV_TEMPLATE.txt | ||
| pytest.ini | ||
| README.md | ||
| requirements.txt | ||
Standard Operating Procedure: SKGentis Oracle API
Document ID: SOP-SKGENTIS-ORACLE-001
Version: 1.1.0 - ZKP Groups & Attestation Release
Status: ✅ Active / Production Ready
Type: Standalone Service
Domain: gentistrust.com
Registry: skgit.skstack01.douno.it
📚 Documentation Index
| Document | Description |
|---|---|
| README.md | This SOP document - deployment & operations |
| Source Repo | Python FastAPI source code |
| SKGentis SOP | Main SKGentis platform documentation |
1. Purpose
The SKGentis Oracle API is a Python FastAPI microservice that provides:
- Price Oracle: Monitors ETH/token prices and signs price attestations
- Reward Signing: Signs milestone reward claims for on-chain verification
- Bot API: Provides structured endpoints for MEV bots and arbitrageurs
- Peg Monitoring: Tracks stablecoin peg status (SKQNT, SKSV)
This service was extracted from the main SKGentis application to enable:
- Independent scaling and deployment
- Public API exposure for bot traffic
- Dedicated security context for private key management
2. Scope
This SOP covers:
- Deployment: Ansible playbooks for prod/staging/dev environments
- Configuration: Vault secrets and Jinja2 templates
- Operations: Monitoring, troubleshooting, and maintenance
- API Usage: Endpoint documentation and examples
3. Architecture Overview
3.1 High-Level Data Flow
graph TD
subgraph "External Consumers"
Bot[MEV/Arbitrage Bots]
FE[SKGentis Frontend]
Ext[External dApps]
end
subgraph "SKGentis Oracle API"
API[FastAPI Service]
Sign[Signer Service]
Price[Price Feed Service]
end
subgraph "Blockchain"
RPC[Ethereum RPC]
Vault[RWAVault Contract]
Chain[Chainlink Price Feed]
end
Bot --> |"/opportunities"| API
FE --> |"/rewards/sign"| API
Ext --> |"/oracle/status"| API
API --> Sign
API --> Price
Sign --> |"ECDSA Sign"| API
Price --> |"ETH/USD"| Chain
Price --> |"Contract State"| RPC
API --> |"Signed Reward"| FE
FE --> |"claimMilestoneReward"| Vault
style API fill:#D4AF37,color:#000
style Sign fill:#4CAF50,color:#fff
style Price fill:#2196F3,color:#fff
3.2 Service Components
| Component | File | Purpose |
|---|---|---|
| Main App | app/main.py |
FastAPI application entry point |
| Config | app/config.py |
Environment configuration |
| Signer | app/services/signer.py |
ECDSA signature generation |
| Price Feed | app/services/price_feed.py |
Chainlink & contract state |
| Health Routes | app/routes/health.py |
/health endpoint |
| Oracle Routes | app/routes/oracle.py |
/oracle/* endpoints |
| Rewards Routes | app/routes/rewards.py |
/rewards/* endpoints |
| Opportunities | app/routes/opportunities.py |
/opportunities/* bot API |
| Groups Routes | app/routes/groups.py |
/groups/* ZKP eligibility management |
| Attestation | app/routes/attestation.py |
/attestation/* RWA compliance |
4. Operational Workflows
4.1 Workflow: Deploy to Production
Objective: Deploy or update the Oracle API to production environment.
# 1. Ensure vault password file exists
ls ~/.vault_pass_env/.skgentis-oracle-api_prod_vault_pass
# 2. Run deployment playbook
cd /home/cbrd21/dkloud.douno.it/p/smilinTux/SKStacks/v1/ansible
ansible-playbook -e env=prod -e domain=gentistrust.com -e cluster=skstack01 \
--vault-password-file ~/.vault_pass_env/.skgentis-oracle-api_prod_vault_pass \
standalone/skgentis-oracle-api/deploy_skgentis-oracle-api-prod.yml
# 3. Verify deployment
curl -s https://skgentis-oracle-api.skstack01.gentistrust.com/health | jq .
4.2 Workflow: Sign a Milestone Reward
Objective: Backend signs a reward for user to claim on-chain.
sequenceDiagram
participant User
participant FE as SKGentis Frontend
participant API as Oracle API
participant Contract as RWAVault
User->>FE: Click "Claim Reward"
FE->>API: POST /rewards/sign
Note over API: Validates eligibility
API->>API: ECDSA.sign(message)
API->>FE: { signature, amount, nonce }
FE->>Contract: claimMilestoneReward(sig, amount, nonce)
Contract->>Contract: Verify oracle signature
Contract->>User: Transfer reward tokens
API Request:
curl -X POST https://skgentis-oracle-api.skstack01.gentistrust.com/rewards/sign \
-H "Content-Type: application/json" \
-d '{
"token_id": 1,
"user_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f23b1c",
"reward_type": 250,
"amount": "1000000000000000000"
}'
4.3 Workflow: Bot Querying Opportunities
Objective: MEV bots discover profitable interactions.
# Get all opportunities for Ethereum mainnet
curl -s https://skgentis-oracle-api.skstack01.gentistrust.com/opportunities/1 | jq .
# Response includes:
# - Vaults approaching milestones
# - Early depositor slots available
# - Price deviation opportunities
5. Deployment Configuration
5.1 Environment URLs
| Environment | URL | RPC Network |
|---|---|---|
| Production | https://skgentis-oracle-api.skstack01.gentistrust.com | Mainnet |
| Staging | https://skgentis-oracle-api-staging.skstack01.gentistrust.com | Sepolia |
| Development | https://skgentis-oracle-api-dev.skstack01.gentistrust.com | Sepolia |
5.2 Vault Files
| Environment | Vault File Path |
|---|---|
| Production | group_vars/prod/skgentis-oracle-api-prod-gentistrust-com-skstack01_vault.yml |
| Staging | group_vars/staging/skgentis-oracle-api-staging-gentistrust-com-skstack01_vault.yml |
| Development | group_vars/dev/skgentis-oracle-api-dev-gentistrust-com-skstack01_vault.yml |
5.3 Required Vault Variables
skgentis_oracle_api:
# === Domain/Cluster Configuration ===
CLUSTERNAME: "skstack01"
DOMAIN: "gentistrust.com"
APP_ENV: "prod" # prod, staging, dev
API_PORT: "3002"
TZ: "UTC"
# === Traefik Network Configuration ===
TRAEFIK_NETWORK: "prod" # Shared Traefik network
# === Registry Configuration ===
REGISTRY_URL: "skgit.skstack01.douno.it"
APP_VERSION: "latest" # Docker image tag
# ---------------------------------------------------------------------------
# ORACLE HOT WALLET (CRITICAL - SENSITIVE)
# Used to sign price attestations and milestone reward claims
# ---------------------------------------------------------------------------
ORACLE_PRIVATE_KEY: "0x..." # 64-char hex private key
ORACLE_ADDRESS: "0x..." # Corresponding public address
# ---------------------------------------------------------------------------
# Ethereum Configuration
# ---------------------------------------------------------------------------
ETH_RPC_URL: "https://mainnet.infura.io/v3/YOUR_KEY"
ETH_VAULT_ADDRESS: "0x..." # RWAVault contract address
CHAIN_ID: "1" # 1 for mainnet, 11155111 for Sepolia
# ---------------------------------------------------------------------------
# Security Configuration
# ---------------------------------------------------------------------------
ADMIN_SECRET: "your-32-char-secret"
ALLOWED_ORIGINS: "https://skgentis.skstack01.gentistrust.com"
# ---------------------------------------------------------------------------
# Price Feed Configuration
# ---------------------------------------------------------------------------
CHECK_INTERVAL_SECONDS: "600" # 10 minutes for prod
PRICE_THRESHOLD: "0.001" # 0.1% deviation threshold
SKQNT_TARGET_PRICE: "1.00" # $1 peg target
SKSV_TARGET_PRICE: "0.01" # $0.01 peg target
skgentis_oracle_api_prod_networks:
- name: "skgentis-oracle-api-prod"
subnet: "172.16.135.0/24"
- name: "cloud-public-prod"
subnet: "172.16.200.0/24"
5.4 Create New Vault
cd /home/cbrd21/dkloud.douno.it/p/smilinTux/SKStacks/v1/ansible/shared/vault_management
./manage_vault_environments.sh init prod standalone skgentis-oracle-api \
--domain gentistrust.com --cluster skstack01
5.5 View/Edit Vault
# View vault contents
ansible-vault view --vault-password-file ~/.vault_pass_env/.skgentis-oracle-api_prod_vault_pass \
standalone/group_vars/prod/skgentis-oracle-api-prod-gentistrust-com-skstack01_vault.yml
# Edit vault contents
ansible-vault edit --vault-password-file ~/.vault_pass_env/.skgentis-oracle-api_prod_vault_pass \
standalone/group_vars/prod/skgentis-oracle-api-prod-gentistrust-com-skstack01_vault.yml
6. API Reference
6.1 Health & Status
| Endpoint | Method | Description | Auth |
|---|---|---|---|
/health |
GET | Basic health check | None |
/oracle/status |
GET | Detailed oracle status | None |
Example - Health Check:
curl https://skgentis-oracle-api.skstack01.gentistrust.com/health
# {"status":"healthy","running":true,"demo_mode":false,"rpc_connected":true}
Example - Oracle Status:
curl https://skgentis-oracle-api.skstack01.gentistrust.com/oracle/status | jq .
# {
# "success": true,
# "data": {
# "running": true,
# "demo_mode": false,
# "contract_available": true,
# "checks_performed": 142,
# "updates_performed": 5
# },
# "config": {
# "check_interval": 600,
# "vault_address": "0x670E..."
# }
# }
6.2 Oracle Operations
| Endpoint | Method | Description | Auth |
|---|---|---|---|
/oracle/trigger |
POST | Force price check/update | Admin |
/oracle/peg/{token} |
GET | Get peg status for token | None |
Example - Trigger Update:
curl -X POST https://skgentis-oracle-api.skstack01.gentistrust.com/oracle/trigger \
-H "X-Admin-Secret: YOUR_SECRET"
6.3 Reward Signing
| Endpoint | Method | Description | Auth |
|---|---|---|---|
/rewards/sign |
POST | Sign milestone reward claim | None |
/rewards/preview |
POST | Preview reward without signing | None |
Example - Sign Reward:
curl -X POST https://skgentis-oracle-api.skstack01.gentistrust.com/rewards/sign \
-H "Content-Type: application/json" \
-d '{
"token_id": 1,
"user_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f23b1c",
"reward_type": 250,
"amount": "1000000000000000000"
}'
6.4 Bot Opportunities
| Endpoint | Method | Description | Auth |
|---|---|---|---|
/opportunities/{chain_id} |
GET | Get opportunities for chain | None |
Example - Get Opportunities:
curl https://skgentis-oracle-api.skstack01.gentistrust.com/opportunities/1 | jq .
# Returns: milestone vaults, early depositor slots, price deviations
7. Network Configuration
6.5 ZKP Eligibility Groups
| Endpoint | Method | Description | Auth |
|---|---|---|---|
/groups |
GET | List all eligibility groups | None |
/groups/{id} |
GET | Get group details | None |
/groups/{id}/members |
GET | List group members | Admin |
/groups/{id}/merkle-root |
GET | Get current Merkle root | None |
/groups/{id}/members |
POST | Add member to group | Admin |
/groups/{id}/members/{commitment} |
DELETE | Remove member | Admin |
/groups/{id}/check/{commitment} |
GET | Check membership | None |
Example - List Groups:
curl https://skgentis-oracle-api.skstack01.gentistrust.com/groups | jq .
# {
# "success": true,
# "count": 3,
# "groups": [
# {"id": 1, "name": "Accredited Investors", "member_count": 0},
# {"id": 2, "name": "Institutional", "member_count": 0},
# {"id": 3, "name": "KYC Verified", "member_count": 0}
# ]
# }
Example - Add Member (Admin):
curl -X POST https://skgentis-oracle-api.skstack01.gentistrust.com/groups/1/members \
-H "Content-Type: application/json" \
-H "X-Admin-Secret: YOUR_SECRET" \
-d '{"commitment": "0x123...64hex", "label": "user@example.com"}'
6.6 RWA Attestation
| Endpoint | Method | Description | Auth |
|---|---|---|---|
/attestation/report |
GET | Get signed attestation report | None |
Example - Get Attestation Report:
curl https://skgentis-oracle-api.skstack01.gentistrust.com/attestation/report | jq .
# {
# "attestation": {
# "timestamp": "2025-12-12T12:00:00Z",
# "vault_state": { "total_vaults": 10, "total_eth_locked": "125.5" },
# "contract_address": "0x5Cd76ca2978a80B0D4655123815803140699E506"
# },
# "oracle": { "address": "0xFE8a...", "signature": "0x..." }
# }
| Environment | Docker Network | Subnet |
|---|---|---|
| Production | skgentis-oracle-api-prod |
172.16.135.0/24 |
| Staging | skgentis-oracle-api-staging |
172.16.136.0/24 |
| Development | skgentis-oracle-api-dev |
172.16.137.0/24 |
All environments connect to cloud-public-prod (172.16.200.0/24) for Traefik routing.
8. Troubleshooting
| Issue | Probable Cause | Resolution |
|---|---|---|
demo_mode: true |
Invalid or missing ORACLE_PRIVATE_KEY |
Check vault variable is valid hex |
rpc_connected: false |
Invalid RPC URL or network issue | Verify ETH_RPC_URL in vault |
401 Unauthorized |
Invalid admin secret on protected endpoint | Check ADMIN_SECRET matches |
| Service not starting | Image not found in registry | Build and push Docker image first |
| CORS errors | Frontend origin not in allowlist | Update ALLOWED_ORIGINS in vault |
8.1 Check Service Logs
# On the Docker Swarm manager node
docker service logs skgentis-oracle-api-prod_skgentis-oracle-api --tail 100 -f
8.2 Force Service Update
docker service update --force skgentis-oracle-api-prod_skgentis-oracle-api
9. Source Code
Repository: https://skgit.skstack01.douno.it/smilinTux/skgentis-oracle-api
The source code is symlinked into this directory:
src/skgentis-oracle-api -> /home/cbrd21/dkloud.douno.it/p/smilinTux/skgentis-oracle-api
9.1 Technology Stack
| Component | Technology |
|---|---|
| Framework | Python FastAPI |
| Validation | Pydantic |
| Ethereum | web3.py, eth_account |
| Container | Docker (Python 3.11-slim) |
| Orchestration | Docker Swarm |
| Proxy | Traefik (TLS termination) |
9.2 Build & Push Docker Image
cd /home/cbrd21/dkloud.douno.it/p/smilinTux/skgentis-oracle-api
# Build image
docker build -t skgit.skstack01.douno.it/smilintux/skgentis-oracle-api:latest .
# Push to registry
docker push skgit.skstack01.douno.it/smilintux/skgentis-oracle-api:latest
# For staging
docker tag skgit.skstack01.douno.it/smilintux/skgentis-oracle-api:latest \
skgit.skstack01.douno.it/smilintux/skgentis-oracle-api:staging
docker push skgit.skstack01.douno.it/smilintux/skgentis-oracle-api:staging
10. Security Considerations
10.1 Private Key Management
- NEVER log or expose
ORACLE_PRIVATE_KEY - Store only in encrypted Ansible vault
- Use separate keys for each environment
- Rotate keys periodically
10.2 Admin Endpoints
- Protected by
X-Admin-Secretheader - Secret stored in vault as
ADMIN_SECRET - Rate limited by Traefik middleware
10.3 CORS Configuration
ALLOWED_ORIGINSrestricts which domains can call the API- Production: Only SKGentis frontend domain
- Staging: May include localhost for testing
References
- Framework: SKStacks v1
- Protocol: SKEth RWA Protocol
- Main App: SKGentis SOP
- Contracts: skgentis-rwavault-contracts
Maintained by: S&K Holding QT / GentisTrust
License: AGPL-3.0
SK = staycuriousANDkeepsmilin 🐧