Plant your ECN — stand up a PolitiCap syndicate downlink under the Nakhon Nayok hub. Same binary runs the regional market API, Redis caches, and an optional public HTML wire with server-imposed content filters.
What you get
The politicap-node package is a self-contained regional stack:
| Component | Role |
|---|---|
bin/politicap-api |
Market API + optional edge HTML wire (one binary) |
etc/politicap-api.yaml |
Node identity, uplink key, Redis, edge flags |
db/schema.sql + db/seed.sql |
Schema + catalog seed |
systemd/politicap-api.service |
Service unit |
| Redis | Normal on every node — tickers + wire cache |
Topology
Nakhon Nayok hub
▲
│ X-ECN-Node-Key: pcn_…
│ content: /api/ecn/v1/content/*
│
your regional node
{city}.{country}.politicap.eu
│
├─ /api/… market API
└─ / /a/id optional filtered HTML wire
(Redis cache)
- Humans sign up and trade on politicap.eu (apex). Your wire deep-links login / enroll / account there.
- Your node is a downlink: market API + optional public wire.
- Content policy is imposed on the hub. The edge may only narrow filters — never widen them.
Prerequisites
- Linux + systemd (Debian/Ubuntu recommended)
- MySQL or MariaDB 10.5+
- Redis 6+ (localhost or private network) — treat as standard, not optional long-term
- Outbound HTTPS to
https://api.politicap.eu - Node API key from the hub (
pcn_…) — private channel only - DNS for
{city}.{country}.politicap.eu(+ TLS when live)
Need a downlink provisioned? support@politicap.eu
1. Unpack
tar -xzf politicap-node-*.tar.gz cd politicap-node-* sudo mkdir -p /opt/politicap-api/bin /etc/politicap-api sudo cp bin/politicap-api /opt/politicap-api/bin/ sudo chmod 755 /opt/politicap-api/bin/politicap-api
2. Database
sudo mysql -e "CREATE DATABASE politicap CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'politicap'@'localhost' IDENTIFIED BY 'STRONG_PASSWORD'; GRANT ALL ON politicap.* TO 'politicap'@'localhost'; FLUSH PRIVILEGES;" mysql -u politicap -p politicap < db/schema.sql mysql -u politicap -p politicap < db/seed.sql
3. Redis
Every ECN node should run Redis for catalog and wire caches (logical DB 4 by default).
sudo apt install redis-server # or point at your managed Redis redis-cli ping # PONG
4. Configure
sudo cp etc/politicap-api.yaml.example /etc/politicap-api/politicap-api.yaml sudo edit /etc/politicap-api/politicap-api.yaml
Minimum fields:
node: name: "Your node name" hostname: your-city.your-country.politicap.eu role: regional ecn_id: 1 listen: addr: "0.0.0.0:18082" database: user: politicap password: "STRONG_PASSWORD" host: "127.0.0.1" port: "3306" name: politicap uplink: url: "https://api.politicap.eu" api_key: "pcn_YOUR_KEY_FROM_HUB" redis: addr: "127.0.0.1:6379" db: 4 public: site_url: https://politicap.eu api_url: https://your-city.your-country.politicap.eu # Optional public HTML wire (filtered desk content) edge: enabled: false title: "PolitiCap Your City" tagline: "Regional market wire" tenant: "your-city" lang: "en" signup_url: "https://politicap.eu/" login_url: "https://politicap.eu/?threedn_oidc=login" account_url: "https://politicap.eu/my-account/" agencies_deny: ["satire", "dox"] feed_ttl_seconds: 60 article_ttl_seconds: 300
5. systemd
sudo cp systemd/politicap-api.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable --now politicap-api curl -sS http://127.0.0.1:18082/healthz
6. Handshake
export KEY='pcn_…' curl -sS -H "X-ECN-Node-Key: $KEY" \ https://api.politicap.eu/api/ecn/v1/hello | jq . curl -sS -H "X-ECN-Node-Key: $KEY" \ https://api.politicap.eu/api/ecn/v1/content/policy | jq .
7. Catalog + sanitized wire API
curl -sS -H "X-ECN-Node-Key: $KEY" \ 'https://api.politicap.eu/api/ecn/v1/catalog/tickers?limit=50' | jq '.count' curl -sS -H "X-ECN-Node-Key: $KEY" \ 'https://api.politicap.eu/api/ecn/v1/content/feed?lang=en' | jq '.count, .articles[0].title' curl -sS -H "X-ECN-Node-Key: $KEY" \ 'https://api.politicap.eu/api/ecn/v1/content/posts/123' | jq '.title, .agency'
8. Edge HTML wire
Set edge.enabled: true, restart, reverse-proxy your hostname to :18082.
GET /— filtered article list (Redis-cached)GET /a/{id}— article body- Header buttons: Sign up / Log in / Account → apex PolitiCap
Speech-sensitive regions (example cn.politicap.eu): hub policy can force agency allowlists and languages. The node binary never sees denied desks.
API reference (downlink → hub)
| Method | Path | Auth |
|---|---|---|
| GET/POST | /api/ecn/v1/hello |
node key |
| GET | /api/ecn/v1/me |
node key |
| GET | /api/ecn/v1/catalog/tickers |
node key |
| GET | /api/ecn/v1/catalog/countries |
node key |
| GET | /api/ecn/v1/catalog/cities |
node key |
| GET | /api/ecn/v1/content/policy |
node key |
| GET | /api/ecn/v1/content/feed |
node key |
| GET | /api/ecn/v1/content/posts/{id} |
node key |
Also accepted: Authorization: Bearer pcn_….
Security
- Treat
pcn_keys as production secrets. Hub stores only a hash. - Do not commit keys or DB passwords.
- Expose only TLS on the public hostname; keep Redis and MySQL private.
- Edge content is intentionally filtered. Do not bypass the hub export with raw WordPress credentials on the node.
What this release still leaves for later
- Automatic apply of catalog pull into the local DB
- Cross-ECN order batching (
ecn_to_ecn) - Regional DutchBud ledgers (ledger remains hub-central)
Package source
Hub operators build with scripts/build-node-package.sh in politicap-api. Operators receive a versioned tarball plus a one-time API key.
Related: Technical index · Android app · Dual IPO