Files
smom-dbis-138/services/chain138-oracle/README.md
zaragoza444 54ca9bea3b
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 52s
CI/CD Pipeline / Security Scanning (push) Successful in 2m40s
CI/CD Pipeline / Lint and Format (push) Failing after 49s
CI/CD Pipeline / Terraform Validation (push) Failing after 24s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 27s
Deploy ChainID 138 / Deploy ChainID 138 (push) Has been cancelled
Validation / validate-genesis (push) Has been cancelled
Validation / validate-terraform (push) Has been cancelled
Validation / validate-kubernetes (push) Has been cancelled
Verify Deployment / Verify Deployment (push) Has been cancelled
Validation / validate-smart-contracts (push) Failing after 14s
Validation / validate-security (push) Failing after 1m20s
Validation / validate-documentation (push) Failing after 18s
feat(settlement): wire real Chain 138 contracts for 1,000 BTC ledger
Add canonical btc-l1-ledger config, /btc/contracts API, Python chain138-oracle
service, and production deploy scripts so secure.omdnl.org can serve live cBTC,
DODO, and PMM pool addresses with headroom-aware mint gating.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 02:26:20 -07:00

4.9 KiB

Chain 138 Python Oracle

Unified Python replacement for the Chain 138 oracle stack:

  • Off-chain pricing (Frankfurter FX + CoinGecko + on-chain ETH/USD aggregator)
  • MetaMask-compatible spot price API (drop-in for token-aggregation routes)
  • PMM liquidity (8 canonical DODO pools via DODOPMMIntegration)
  • On-chain oracle push (replaces scripts/update-oracle-price.sh)
  • Keeper mesh (replaces scripts/reserve/keeper-service.js + pmm-mesh-6s-automation.sh)

Token coverage is driven by config/omnl-m2-token-registry.v1.json (all M2 symbols) plus config/chain138-pmm-pools.json (PMM pool tokens).

Install

cd services/chain138-oracle
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -r requirements.txt

Load repo root .env (RPC, CoinGecko, keeper/oracle keys).

Commands

Command Replaces Purpose
python -m chain138_oracle serve token-aggregation price routes + oracle-publisher HTTP API on port 3500 (override CHAIN138_ORACLE_PORT)
python -m chain138_oracle mesh pmm-mesh-6s-automation.sh 6s oracle + keeper + PMM TVL loop
python -m chain138_oracle keeper keeper-service.js Keeper-only loop
python -m chain138_oracle refresh-fx iso4217-fx-refresh.ts Refresh FX/crypto reference rates
python -m chain138_oracle update-oracle update-oracle-price.sh Push ETH/USD to aggregator
python -m chain138_oracle liquidity chain138-dodo-liquidity.ts PMM pool TVL snapshot
python -m chain138_oracle validate Fail if any registry token lacks USD price

API endpoints

Endpoint Description
GET /health Service + on-chain ETH/USD status
GET /api/v1/prices/metamask/v2/chains/138/spot-prices?tokenAddresses=0x… MetaMask Codefi-compatible spot prices
GET /api/v1/oracle/tokens All registry tokens with price + PMM liquidity USD
GET /api/v1/oracle/liquidity/pools Canonical PMM pool reserves and TVL
GET /api/v1/oracle/reference-rates Live FX/crypto cache + contract addresses

Settlement / token-aggregation integration

Point spot prices at the Python oracle; keep OMNL mint/transfer on token-aggregation:

CHAIN138_ORACLE_URL=http://127.0.0.1:3500
TOKEN_AGGREGATION_URL=http://127.0.0.1:3000

Settlement middleware reads CHAIN138_ORACLE_URL for live BTC/USD (resolveLiveBtcUsd).

Production cutover (one command)

On the Chain 138 / OMNL host (Linux, systemd):

chmod +x scripts/deployment/cutover-chain138-oracle-python.sh
sudo RESTART_SETTLEMENT=1 ./scripts/deployment/cutover-chain138-oracle-python.sh

Dry-run first:

./scripts/deployment/cutover-chain138-oracle-python.sh --dry-run

This script:

  1. Stops legacy pmm-mesh-6s-automation.sh, keeper-service.js, and old systemd units
  2. Installs Python venv + validates all 37 M2 tokens
  3. Sets CHAIN138_ORACLE_URL in .env
  4. Enables chain138-oracle-api.service + chain138-oracle-mesh.service
  5. Smoke-tests cBTC spot price and restarts settlement-middleware

Smoke test only:

CHAIN138_ORACLE_URL=http://127.0.0.1:3500 node scripts/deployment/smoke-chain138-oracle-pricing.mjs

Docker Compose (includes chain138-oracle on port 3500):

docker compose -f docker-compose.omnl-production.yml up -d chain138-oracle settlement-middleware

Required environment

Variable Purpose
RPC_URL_138 Chain 138 JSON-RPC
COINGECKO_API_KEY FX/crypto refresh (optional but recommended)
PRIVATE_KEY / DEPLOYER_PRIVATE_KEY On-chain aggregator transmitter
KEEPER_PRIVATE_KEY PriceFeedKeeper.performUpkeep
PRICE_FEED_KEEPER_ADDRESS Keeper contract (default in code)
AGGREGATOR_ADDRESS ETH/USD aggregator
OMNL_REQUIRE_LIVE_BTC_PRICE=1 Block repo BTC fallback (production)

systemd example

[Unit]
Description=Chain 138 Python Oracle Mesh
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/smom-dbis-138/services/chain138-oracle
EnvironmentFile=/opt/smom-dbis-138/.env
ExecStart=/opt/smom-dbis-138/services/chain138-oracle/.venv/bin/python -m chain138_oracle mesh
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target


## Coverage validation

```bash
python -m chain138_oracle validate
# or
python scripts/validate_coverage.py

Exits 0 when every token in omnl-m2-token-registry.v1.json resolves a positive USD price.

Architecture

flowchart LR
  CG[CoinGecko] --> FX[fx_refresh.py]
  FF[Frankfurter] --> FX
  FX --> CACHE[reference_cache]
  AGG[On-chain Aggregator] --> ETH[onchain_eth.py]
  ETH --> CACHE
  CACHE --> CANON[canonical_price.py]
  CANON --> API[FastAPI api.py]
  CANON --> LIQ[liquidity.py]
  PMM[DODO PMM Integration] --> LIQ
  MESH[mesh.py] --> ORA[onchain_oracle.py]
  MESH --> KEEP[keeper.py]

See also: docs/integration/ORACLE_AND_KEEPER_CHAIN138.md