{
  "markdown": "<!-- textura-banner -->\n<div align=\"center\">\n  <a href=\"https://github.com/beepboop2025/umbra-xmr-bridge\"><img src=\"./banner.svg\" width=\"100%\" alt=\"umbra-xmr-bridge\" /></a>\n</div>\n\n<p align=\"center\">\n  <a href=\"https://github.com/beepboop2025/umbra-xmr-bridge/actions/workflows/tests.yml\"><img src=\"https://github.com/beepboop2025/umbra-xmr-bridge/actions/workflows/tests.yml/badge.svg\" alt=\"tests\" /></a>\n  <img src=\"https://img.shields.io/badge/coverage-85%25-brightgreen\" alt=\"coverage\" />\n</p>\n\n<p align=\"center\">\n  <img src=\"public/monero.svg\" width=\"40\" alt=\"XMR\" />&nbsp;&nbsp;\n  <strong style=\"font-size: 2em;\">UMBRA</strong>&nbsp;&nbsp;\n  <img src=\"public/ton.svg\" width=\"40\" alt=\"TON\" />\n</p>\n\n<h3 align=\"center\">Privacy-first cross-chain bridge</h3>\n\n<p align=\"center\">\n  Swap XMR, BTC, ETH, TON, SOL and more — trustless MPC threshold signatures, real-time rates, zero KYC.\n</p>\n\n<p align=\"center\">\n  <img src=\"https://img.shields.io/badge/Rust-000000?style=for-the-badge&logo=rust&logoColor=white\" alt=\"Rust\" />\n  <img src=\"https://img.shields.io/badge/Next.js-000000?style=for-the-badge&logo=next.js&logoColor=white\" alt=\"Next.js\" />\n  <img src=\"https://img.shields.io/badge/Telegram-26A5E4?style=for-the-badge&logo=telegram&logoColor=white\" alt=\"Telegram\" />\n  <img src=\"https://img.shields.io/badge/PostgreSQL-4169E1?style=for-the-badge&logo=postgresql&logoColor=white\" alt=\"PostgreSQL\" />\n  <img src=\"https://img.shields.io/badge/Docker-2496ED?style=for-the-badge&logo=docker&logoColor=white\" alt=\"Docker\" />\n</p>\n\n---\n\n## What is Umbra?\n\nUmbra is a non-custodial cross-chain bridge built around **Monero** — the only cryptocurrency with mandatory privacy. It enables trustless swaps between privacy coins and public blockchains using **FROST threshold signatures** (2-of-3 MPC), meaning no single party ever holds your funds.\n\nWhat makes Umbra different from every other bridge is the **Proof Layer**: the bridge does not ask to be trusted — it produces cryptographic evidence for everything it does, and ships the tools to check that evidence offline.\n\n---\n\n## The Proof Layer\n\nBridges are the most-hacked primitive in crypto (Ronin $624M, Multichain $126M, Nomad $190M, Harmony $100M — drained over minutes-to-hours while nothing watched). Umbra's answer is a layer of verifiable accountability that no major bridge ships today:\n\n```\n              ┌─────────────────────────────────────────────────────────┐\n              │                      PROOF LAYER                        │\n              │                                                         │\n   every      │  ┌────────────┐   sealed    ┌──────────────────┐        │\n   order ────►│  │  Signed    │  every 5m   │  Transparency    │        │\n   event      │  │  Receipts  │────────────►│  Log (Merkle)    │        │\n              │  │ Ed25519 +  │             │  RFC 6962 proofs │        │\n              │  │ ML-DSA-65  │             └────────┬─────────┘        │\n              │  └────────────┘                      │ anchors          │\n              │                                      ▼                  │\n              │  ┌──────────────────┐        ┌──────────────┐           │\n              │  │  Sentinel        │        │  Signed      │           │\n              │  │  5 guards, 30s   │        │  Canary      │           │\n              │  │  + Isolation     │        │  (freshness- │           │\n              │  │    Forest (ML)   │        │   bound)     │           │\n              │  └──────────────────┘        └──────────────┘           │\n              └─────────────────────────────────────────────────────────┘\n                        ▲ verify offline: browser page, single-file\n                          HTML, or pure-stdlib Python CLI — zero trust\n```\n\n### 1. Signed swap receipts — a flight recorder for every order\n\nEvery lifecycle event of every order (`order_created`, `status_confirming`, `status_completed`, …) produces a receipt signed with the bridge's **Ed25519** key over canonical JSON. Receipts for one order are **hash-chained** (each embeds the SHA-256 of the previous receipt), so a user holding their final receipt can detect any retroactive edit to their order's history. Receipts carry a *hash* of the destination address, not the address — the proof layer never becomes a metadata leak.\n\n```bash\ncurl -s https://your-bridge/v1/proof/receipt/br_ab12cd34ef56 | \\\n    python3 tools/verify_receipt.py receipts - --pin <PUBLIC_KEY>\n```\n\n### 2. Post-quantum hybrid signatures\n\nReceipts are archival evidence with a multi-decade shelf life. Alongside Ed25519, every receipt and checkpoint is signed with **ML-DSA-65 (FIPS 204, CRYSTALS-Dilithium)** over the same canonical bytes. Ed25519 stays the cheap, universally verifiable online layer; the ML-DSA signature keeps the archive forgery-proof against a future quantum adversary. Forging history requires breaking **both** schemes.\n\n### 3. Transparency log — Certificate Transparency for a bridge\n\nThe audit hash-chain is sealed every few minutes into a **signed Merkle checkpoint** (the RFC 6962 construction used by Certificate Transparency, validated against the CT known-answer vectors). Anyone can then demand:\n\n- **Inclusion proofs** — `GET /v1/proof/inclusion/{audit_id}` proves a specific audit entry is committed to by a checkpoint (log₂ n hashes, verifiable offline).\n- **Consistency proofs** — `GET /v1/proof/consistency?old_size=&new_size=` proves a newer checkpoint is a pure append-only extension of an older one. **History cannot be rewritten without detection.**\n\nMirror `GET /v1/proof/checkpoint/latest` on a cron job and you become an external witness the operator cannot silently contradict.\n\n### 4. The Sentinel — a circuit breaker between the bridge and catastrophe\n\nFive guards run every 30 seconds:\n\n| Guard | Trips when | Would have caught |\n|-------|-----------|-------------------|\n| Outflow velocity | per-chain outbound volume exceeds hourly caps | Ronin, Harmony (key-compromise drains) |\n| Order velocity | order creation rate spikes | bot floods, probing attacks |\n| Failure spike | failed orders cluster | subsystem exploitation |\n| Rate divergence | independent price sources disagree > 5% | oracle poisoning |\n| **ML anomaly** (optional) | Isolation Forest flags order-flow combinations vs the 7-day baseline | drain signatures no fixed threshold expresses |\n\nA trip pauses **new intake only** — in-flight swaps keep settling, so a false positive costs minutes of intake, not user funds. The sentinel never auto-resumes: a human must investigate and resume with a note. Every trip, pause, and resume lands in the tamper-evident audit chain and the public `GET /v1/proof/status` endpoint — **the bridge cannot be paused or unpaused in secret**. The ML guard fails open: a risk-engine outage never blocks the bridge.\n\n### 5. Signed, freshness-bound warrant canary\n\n`GET /v1/proof/canary` returns a signed statement embedding the current time **and the latest checkpoint root** — it cannot be replayed against a rewound log. A canary that stops updating is itself a signal.\n\n### Verify without trusting anything\n\nThree independent verifiers ship in this repo, all validated against RFC 8032 test vectors and against each other:\n\n| Verifier | Trust required |\n|----------|---------------|\n| `website /verify` page | verification runs client-side in your browser |\n| [`verifier/umbra-verify.html`](verifier/umbra-verify.html) | **none** — save the file, open from `file://`, zero network requests, pure-BigInt Ed25519 with an on-load self-test |\n| [`tools/verify_receipt.py`](tools/verify_receipt.py) | **none** — pure Python stdlib, no dependencies; `receipts`/`checkpoint`/`inclusion` subcommands |\n\nPin the bridge's public key (`GET /v1/proof/key`) out-of-band once; from then on, every receipt either verifies or it doesn't. Telegram users get the same via `/receipt <order_id>` and `/trust`.\n\nThe full wire-format specification — exact canonical forms, algorithms, threat model, and test vectors for building your own verifier — lives in [`docs/PROOF_LAYER.md`](docs/PROOF_LAYER.md).\n\n### Supported Chains\n\n| Chain | Ticker | Type |\n|-------|--------|------|\n| Monero | XMR | Privacy L1 |\n| Bitcoin | BTC | L1 |\n| Ethereum | ETH | L1 |\n| TON | TON | L1 |\n| Solana | SOL | L1 |\n| Arbitrum | ARB | L2 (EVM) |\n| Base | BASE | L2 (EVM) |\n| USDT / USDC | Stablecoins | Multi-chain |\n\n---\n\n## Architecture\n\n```\n                        +------------------+\n                        |   Nginx Proxy    |\n                        |  :80 / :443      |\n                        +--------+---------+\n                                 |\n              +------------------+------------------+\n              |                  |                  |\n     /app     |        /        |        /api      |\n              v                 v                  v\n     +--------+------+  +------+-------+  +-------+-------+\n     | Telegram Mini  |  |   Next.js    |  |  Rust Backend |\n     | App (Vite)     |  |   Website    |  |  (axum)       |\n     | :3000          |  |   :3001      |  |  :8000        |\n     +----------------+  +--------------+  +---+---+-------+\n                                               |   |\n                            +------------------+   +--------+\n                            |                               |\n                    +-------v------+               +--------v-------+\n                    |  PostgreSQL  |               |     Redis      |\n                    |  :5432       |               |     :6379      |\n                    +--------------+               +----------------+\n                                                          |\n              +-------------------------------------------+\n              |                    |\n     +--------v-------+  +--------v--------+\n     | Telegram Bot   |  | Prometheus +    |\n     | (aiogram)      |  | Grafana         |\n     +----------------+  +-----------------+\n```\n\n**Single Rust binary** replaces what would typically be 3+ Python processes. The backend handles HTTP API, WebSocket streaming, background task scheduling, and blockchain RPC — all in one process using `tokio`.\n\n---\n\n## Three Interfaces, One Backend\n\n### 1. Telegram Mini App\nMobile-optimized bridge UI that runs inside Telegram. Tap, swap, done.\n\n### 2. Telegram Bot\nFull conversational bridge — `/bridge`, `/rate`, `/history`, `/status`. Works without ever leaving the chat.\n\n### 3. Enterprise Website\nDesktop dashboard with portfolio tracking, analytics charts, order history, public transaction explorer, admin panel — plus `/verify` (client-side receipt verification) and `/transparency` (live sentinel status, checkpoints, canary).\n\nAll three share the same Rust API and real-time WebSocket feed.\n\n---\n\n## Tech Stack\n\n| Layer | Technology |\n|-------|-----------|\n| **Backend** | Rust, axum 0.7, sqlx, tokio, tower |\n| **Database** | PostgreSQL 17, Redis 7 |\n| **MPC** | FROST threshold signatures (`frost-secp256k1`) |\n| **Blockchain** | monero-wallet-rpc, toncenter, EVM JSON-RPC, Solana RPC, Bitcoin Core |\n| **Website** | Next.js 15, React 19, Tailwind CSS 4, Zustand, Recharts, TON Connect |\n| **Mini App** | Vite 6, vanilla JS, Telegram WebApp SDK |\n| **Bot** | Python, aiogram 3, httpx |\n| **Monitoring** | Prometheus, Grafana |\n| **Proxy** | Nginx with rate limiting |\n| **Rates** | CoinGecko -> Binance -> CoinCap (triple fallback) |\n\n---\n\n## Quick Start\n\n```bash\n# Clone\ngit clone https://github.com/beepboop2025/umbra.git\ncd umbra\n\n# Configure\ncp backend/.env.example .env\n# Edit .env with your keys (Telegram bot token, RPC endpoints, etc.)\n\n# Launch everything\ndocker compose up --build\n```\n\n| Service | URL |\n|---------|-----|\n| Website | http://localhost |\n| Mini App | http://localhost/app |\n| API | http://localhost/api/health |\n| Grafana | http://localhost:3002 |\n| Prometheus | http://localhost:9090 |\n\n---\n\n## Project Structure\n\n```\numbra/\n├── backend/               # Rust API (axum + sqlx + tokio)\n│   ├── src/\n│   │   ├── routes/        # HTTP + WebSocket endpoints (incl. /v1/proof/*)\n│   │   ├── services/      # Rates, orders, attestations, transparency, sentinel\n│   │   ├── blockchain/    # Monero, Bitcoin, EVM, TON, Solana RPC clients\n│   │   ├── mpc/           # FROST threshold signatures, coordinator, signers\n│   │   ├── middleware/     # Security headers, rate limiting, Telegram auth\n│   │   ├── tasks/         # Deposit monitor, confirmations, expiry, sentinel, sealing\n│   │   ├── models/        # SQLx models (orders, rates, audit, MPC)\n│   │   └── utils/         # Crypto helpers, address validation, RFC 6962 Merkle\n│   └── migrations/        # PostgreSQL schema\n├── bot/                   # Telegram bot (aiogram 3)\n│   └── bot/\n│       ├── handlers/      # /start, /bridge, /rate, /history, /admin\n│       ├── keyboards/     # Inline keyboards for bridge flow\n│       └── services/      # Backend API client\n├── website/               # Enterprise dashboard (Next.js 15)\n│   └── src/\n│       ├── app/           # Pages: bridge, dashboard, explorer, admin\n│       ├── components/    # UI, bridge, charts, wallet, layout\n│       ├── hooks/         # useRate, useOrders, useWebSocket, useWallet\n│       ├── stores/        # Zustand state management\n│       └── lib/           # API client, validators, utilities\n├── src/                   # Telegram Mini App (Vite)\n├── risk-engine/           # Python risk service (FastAPI)\n│   └── services/          # Isolation Forest, MAD z-score, drain scoring\n├── verifier/              # Single-file offline verifier (umbra-verify.html)\n├── tools/                 # verify_receipt.py — pure-stdlib CLI verifier\n├── docker-compose.yml     # Full stack orchestration (10 services)\n├── nginx.conf             # Reverse proxy + rate limiting\n└── monitoring/            # Prometheus + Grafana config\n```\n\n---\n\n## How a Bridge Swap Works\n\n```\n1. User selects pair         XMR -> TON, enters amount\n2. Rate lock                 Cross-rate from CoinGecko (30s cache)\n3. Sentinel gate             Intake refused instantly if the circuit breaker is tripped\n4. Order created             Deposit address generated, 30min expiry, signed receipt #0\n5. Deposit detected          Monero wallet-rpc monitors subaddress\n6. Confirmations             10 confirms for XMR, 1 for TON\n7. MPC signing               2-of-3 FROST threshold signature\n8. Withdrawal sent           TON transfer broadcast\n9. Complete                  Signed receipt binds the withdrawal tx hash;\n                             user notified via WebSocket + Telegram\n```\n\nEvery step from 4 onward emits a hash-chained, dual-signed receipt the user can verify offline — the order's history is provable end to end.\n\n---\n\n## Security\n\n- **FROST 2-of-3 MPC** — No single party can sign transactions\n- **Proof Layer** — Signed receipts (Ed25519 + ML-DSA-65), RFC 6962 transparency log, sentinel circuit breaker, signed canary (see above)\n- **Hash-chain audit log** — Every state change is tamper-evident (SHA-256 chain), sealed into signed Merkle checkpoints\n- **Telegram WebApp auth** — HMAC-SHA-256 verification of `initData`\n- **Rate limiting** — Redis sliding window (60/min API, 10/min orders, 5 WS/IP)\n- **Security headers** — CSP, HSTS, X-Frame-Options, X-Content-Type-Options\n- **Argon2id** — Password hashing for admin accounts\n- **JWT** — Admin authentication with configurable expiry\n- **Anti-replay** — Nonce-based protection on order creation and MPC signing\n- **Address validation** — Per-chain regex validation (XMR base58, BTC bech32, ETH checksum, TON friendly/raw, SOL base58)\n\n### Key custody for the Proof Layer\n\nThe attestation identity is derived deterministically from `SECRET_KEY` by default (fine for development). In production set independent seeds — `ATTESTATION_SECRET_KEY` (Ed25519) and `ATTESTATION_PQ_SEED` (ML-DSA-65) — so receipt-signing custody can be separated from JWT custody, and publish the public keys from `GET /v1/proof/key` somewhere you don't control (a tweet, a git tag, another bridge's transparency page) so users can pin them.\n\n---\n\n## API Reference\n\n### Rates\n```\nGET  /v1/rate?direction=XMR_TO_TON          Current rate + 24h change + sparkline\nGET  /v1/rate/history?direction=&period=1h  Rate history (1h/4h/24h/7d/30d)\n```\n\n### Orders\n```\nPOST /v1/order                              Create bridge order\nGET  /v1/order/:id                          Order details\nGET  /v1/orders?telegram_user_id=&limit=50  Order history\nPOST /v1/order/:id/cancel                   Cancel pending order\n```\n\n### WebSocket\n```\nWS   /v1/ws/order/:id                      Real-time order status updates\nWS   /v1/ws/rates                           Live rate feed\n```\n\n### Proof Layer (public — no auth, by design)\n```\nGET  /v1/proof/key                          Bridge public keys (Ed25519 + ML-DSA-65) — pin these\nGET  /v1/proof/receipt/:order_id            Signed receipts for an order (full lifecycle)\nGET  /v1/proof/checkpoint/latest            Latest signed Merkle tree head\nGET  /v1/proof/checkpoints?limit=20         Checkpoint history\nGET  /v1/proof/inclusion/:audit_id          RFC 6962 inclusion proof for an audit entry\nGET  /v1/proof/consistency?old_size=&new_size=  Append-only proof between two checkpoints\nGET  /v1/proof/audit/verify                 Server-side full hash-chain walk\nGET  /v1/proof/canary                       Signed, freshness-bound warrant canary\nGET  /v1/proof/status                       Sentinel state: accepting orders? why not?\n```\n\n### Risk Engine (internal, X-API-Key)\n```\nPOST /v1/risk/anomaly                       Statistical drain scores (MAD z-score, burst, round amounts)\nPOST /v1/risk/anomaly/ml                    Isolation Forest anomaly scores over order-flow features\n```\n\n### Admin\n```\nPOST /v1/admin/login                        JWT authentication\nGET  /v1/admin/stats                        System statistics\nPOST /v1/admin/order/:id/refund             Manual refund\nGET  /v1/admin/sentinel                     Sentinel state + last 50 events\nPOST /v1/admin/sentinel/pause               Manual pause (reason required)\nPOST /v1/admin/sentinel/resume              Resume (investigation note required)\n```\n\n### System\n```\nGET  /health                                Liveness probe\nGET  /ready                                 Readiness probe (DB + Redis)\nGET  /metrics                               Prometheus metrics\n```\n\n---\n\n## Monitoring\n\nPrometheus scrapes the `/metrics` endpoint for:\n- API request latency (p50/p95/p99)\n- Order throughput and failure rate\n- Rate source health and fetch duration\n- WebSocket connection count\n- Background task execution metrics\n\nGrafana dashboards available at `:3002` (default password: `admin`).\n\n---\n\n## Development\n\n```bash\n# Backend only (requires local Postgres + Redis)\ncd backend\ncargo run\n\n# Website only\ncd website\nnpm install && npm run dev\n\n# Mini App only\nnpm run dev\n\n# Run backend tests\ncd backend\ncargo test\n```\n\n---\n\n## Environment Variables\n\nSee [`backend/.env.example`](backend/.env.example) for the full list. Key ones:\n\n| Variable | Description |\n|----------|-------------|\n| `SECRET_KEY` | JWT signing key (64+ chars) |\n| `TELEGRAM_BOT_TOKEN` | From @BotFather |\n| `MONERO_RPC_URL` | monero-wallet-rpc endpoint |\n| `TON_API_URL` | toncenter API |\n| `ETH_RPC_URL` | Ethereum JSON-RPC |\n| `BRIDGE_FEE_PERCENT` | Fee per swap (default: 0.3%) |\n| `MPC_THRESHOLD` | Signatures required (default: 2) |\n| `ATTESTATION_SECRET_KEY` | Ed25519 receipt-signing seed, 64 hex chars (derived from `SECRET_KEY` if unset) |\n| `ATTESTATION_PQ_SEED` | ML-DSA-65 seed, 64 hex chars (derived if unset) |\n| `PQ_SIGNATURES_ENABLED` | Post-quantum hybrid signatures (default: true) |\n| `TRANSPARENCY_SEAL_INTERVAL_SECS` | Checkpoint sealing cadence (default: 300) |\n| `CANARY_STATEMENT` | Warrant-canary text served at `/v1/proof/canary` |\n| `SENTINEL_ENABLED` | Circuit breaker (default: true) |\n| `SENTINEL_OUTFLOW_CAPS` | Per-chain hourly caps, e.g. `XMR:1000,BTC:20` |\n| `RISK_ENGINE_URL` | Enables the Isolation Forest sentinel guard (optional) |\n\n---\n\n## License\n\nSource-available under the [Source-Available License v1.0](LICENSE.md). You may view, study, fork, and run it locally for non-commercial evaluation and research. Commercial use, operating it as a service, or redistribution require a separate written license.\n",
  "bytes": 20317,
  "sha": "1165707d19c28ac921930dc2c55f8a4e185a6f150a1b8b2cab5f20c5e4cf05b6",
  "repo_slug": "beepboop2025/umbra-xmr-bridge",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_beepboop2025_umbra_proof_84120c0c/readme"
}