{"id":35575950,"url":"https://github.com/gtg7784/dr-manhattan-rust","last_synced_at":"2026-01-13T23:41:11.734Z","repository":{"id":330453781,"uuid":"1122183579","full_name":"gtg7784/dr-manhattan-rust","owner":"gtg7784","description":"A CCXT-style unified API for prediction markets (Polymarket, Limitless, Opinion, Kalshi and Predict.fun) with Rust","archived":false,"fork":false,"pushed_at":"2026-01-04T17:05:23.000Z","size":186,"stargazers_count":25,"open_issues_count":0,"forks_count":4,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-13T19:46:40.378Z","etag":null,"topics":["arbitrage","ccxt","ccxt-rust","kalshi","kalshi-api","limitless","opinion","polymarket","predictfun","prediction","prediction-market","prediction-market-arbitrage","rust"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/drm-core","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gtg7784.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-24T08:38:25.000Z","updated_at":"2026-01-13T07:55:44.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/gtg7784/dr-manhattan-rust","commit_stats":null,"previous_names":["gtg7784/dr-manhattan-rust"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gtg7784/dr-manhattan-rust","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gtg7784%2Fdr-manhattan-rust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gtg7784%2Fdr-manhattan-rust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gtg7784%2Fdr-manhattan-rust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gtg7784%2Fdr-manhattan-rust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gtg7784","download_url":"https://codeload.github.com/gtg7784/dr-manhattan-rust/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gtg7784%2Fdr-manhattan-rust/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28405309,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T21:51:37.118Z","status":"ssl_error","status_checked_at":"2026-01-13T21:45:14.585Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arbitrage","ccxt","ccxt-rust","kalshi","kalshi-api","limitless","opinion","polymarket","predictfun","prediction","prediction-market","prediction-market-arbitrage","rust"],"created_at":"2026-01-04T19:09:57.795Z","updated_at":"2026-01-13T23:41:11.728Z","avatar_url":"https://github.com/gtg7784.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dr-manhattan-rust 🦀\n\n[![CI](https://github.com/gtg7784/dr-manhattan-rust/actions/workflows/ci.yml/badge.svg)](https://github.com/gtg7784/dr-manhattan-rust/actions/workflows/ci.yml)\n\nCCXT-style unified API for prediction markets, rewritten in Rust.\n\n## Inspiration\n\nThis project is a Rust port of [guzus/dr-manhattan](https://github.com/guzus/dr-manhattan), an excellent Python library that provides a unified interface for prediction markets (similar to how CCXT unifies crypto exchange APIs). Full credit to the original authors for the design and architecture.\n\n## Features\n\n- **Unified API**: Same interface across all supported prediction market exchanges\n- **Type-safe**: Leverage Rust's type system for compile-time safety\n- **Async-first**: Built on tokio for high-performance async operations\n- **WebSocket support**: Real-time orderbook and trade streaming\n- **Rate limiting**: Built-in rate limiter to respect exchange limits\n\n## Architecture\n\n```\ndr-manhattan-rust/\n├── drm-core/                    # Core traits, models, and errors\n│   ├── models/                  # Market, Order, Position, Orderbook\n│   ├── exchange/                # Exchange trait, config, rate limiting\n│   ├── websocket/               # WebSocket trait for orderbook streaming\n│   ├── strategy/                # Strategy trait and order tracker\n│   └── error.rs                 # DrmError hierarchy\n├── drm-exchange-polymarket/     # Polymarket implementation\n├── drm-exchange-limitless/      # Limitless implementation\n├── drm-exchange-opinion/        # Opinion implementation\n├── drm-exchange-kalshi/         # Kalshi implementation\n├── drm-exchange-predictfun/     # Predict.fun implementation\n├── drm-examples/                # Example binaries\n└── Cargo.toml                   # Workspace configuration\n```\n\n## Quick Start\n\n```rust\nuse drm_core::Exchange;\nuse drm_exchange_polymarket::{Polymarket, PolymarketConfig};\n\n#[tokio::main]\nasync fn main() -\u003e anyhow::Result\u003c()\u003e {\n    let exchange = Polymarket::with_default_config()?;\n    \n    let markets = exchange.fetch_markets(None).await?;\n    \n    for market in markets.iter().take(5) {\n        println!(\"{}: {:?}\", market.question, market.prices);\n    }\n    \n    Ok(())\n}\n```\n\n## Supported Exchanges\n\n| Exchange | Status | REST | WebSocket |\n|----------|--------|------|-----------|\n| Polymarket | ✅ Complete | ✅ All endpoints | ✅ Orderbook |\n| Limitless | ✅ Complete | ✅ All endpoints | ✅ Orderbook |\n| Opinion | ✅ Complete | ✅ All endpoints | - |\n| Kalshi | ✅ Complete | ✅ All endpoints | - |\n| Predict.fun | ✅ Complete | ✅ All endpoints | - |\n\n## Running Examples\n\n```bash\n# List markets from any exchange\ncargo run -p drm-examples --bin list-markets -- \u003cexchange\u003e -l \u003climit\u003e\n\n# Examples:\ncargo run -p drm-examples --bin list-markets -- polymarket -l 5\ncargo run -p drm-examples --bin list-markets -- kalshi -l 10\nPREDICTFUN_API_KEY=\u003ckey\u003e cargo run -p drm-examples --bin list-markets -- predictfun -l 5\n\n# Watch orderbook updates (Polymarket)\ncargo run -p drm-examples --bin watch-orderbook\n```\n\n## Development\n\n```bash\n# Build all crates\ncargo build\n\n# Run tests\ncargo test\n\n# Run clippy\ncargo clippy\n\n# Format code\ncargo fmt\n```\n\n## Configuration\n\n### Polymarket\n\n```rust\nuse drm_exchange_polymarket::{Polymarket, PolymarketConfig};\n\n// Public API (no auth required)\nlet exchange = Polymarket::with_default_config()?;\n\n// Authenticated (for trading)\nlet config = PolymarketConfig::new()\n    .with_private_key(\"0x...\")\n    .with_funder(\"0x...\");\nlet exchange = Polymarket::new(config)?;\nexchange.init_trading().await?;\n```\n\n### Limitless\n\n```rust\nuse drm_exchange_limitless::{Limitless, LimitlessConfig};\n\n// Public API\nlet exchange = Limitless::with_default_config()?;\n\n// Authenticated\nlet config = LimitlessConfig::new()\n    .with_private_key(\"0x...\");\nlet exchange = Limitless::new(config)?;\nexchange.authenticate().await?;\n```\n\n### Opinion\n\n```rust\nuse drm_exchange_opinion::{Opinion, OpinionConfig};\n\n// Public API\nlet exchange = Opinion::with_default_config()?;\n\n// Authenticated\nlet config = OpinionConfig::new()\n    .with_api_key(\"your-api-key\")\n    .with_private_key(\"0x...\")\n    .with_multi_sig_addr(\"0x...\");\nlet exchange = Opinion::new(config)?;\n```\n\n### Kalshi\n\n```rust\nuse drm_exchange_kalshi::{Kalshi, KalshiConfig};\n\n// Production API\nlet config = KalshiConfig::new(\"your-api-key-id\", \"/path/to/private-key.pem\");\nlet exchange = Kalshi::new(config)?;\n\n// Demo environment\nlet config = KalshiConfig::demo(\"your-api-key-id\", \"/path/to/private-key.pem\");\nlet exchange = Kalshi::new(config)?;\n\n// With PEM string directly\nlet config = KalshiConfig::new(\"your-api-key-id\", \"\")\n    .with_private_key_pem(\"-----BEGIN PRIVATE KEY-----\\n...\");\nlet exchange = Kalshi::new(config)?;\n```\n\n### Predict.fun\n\n```rust\nuse drm_exchange_predictfun::{PredictFun, PredictFunConfig};\n\n// Public API\nlet exchange = PredictFun::with_default_config()?;\n\n// Authenticated (for trading)\nlet config = PredictFunConfig::new()\n    .with_api_key(\"your-api-key\")\n    .with_private_key(\"0x...\");\nlet exchange = PredictFun::new(config)?;\nexchange.authenticate().await?;\n\n// Testnet\nlet config = PredictFunConfig::testnet()\n    .with_api_key(\"your-api-key\")\n    .with_private_key(\"0x...\");\nlet exchange = PredictFun::new(config)?;\n```\n\n## API Reference\n\n### Exchange Trait\n\nAll exchanges implement the `Exchange` trait:\n\n```rust\n#[async_trait]\npub trait Exchange: Send + Sync {\n    fn id(\u0026self) -\u003e \u0026'static str;\n    fn name(\u0026self) -\u003e \u0026'static str;\n    \n    async fn fetch_markets(\u0026self, params: Option\u003cFetchMarketsParams\u003e) -\u003e Result\u003cVec\u003cMarket\u003e, DrmError\u003e;\n    async fn fetch_market(\u0026self, market_id: \u0026str) -\u003e Result\u003cMarket, DrmError\u003e;\n    async fn fetch_markets_by_slug(\u0026self, slug: \u0026str) -\u003e Result\u003cVec\u003cMarket\u003e, DrmError\u003e;\n    \n    async fn create_order(\u0026self, market_id: \u0026str, outcome: \u0026str, side: OrderSide, price: f64, size: f64, params: HashMap\u003cString, String\u003e) -\u003e Result\u003cOrder, DrmError\u003e;\n    async fn cancel_order(\u0026self, order_id: \u0026str, market_id: Option\u003c\u0026str\u003e) -\u003e Result\u003cOrder, DrmError\u003e;\n    async fn fetch_order(\u0026self, order_id: \u0026str, market_id: Option\u003c\u0026str\u003e) -\u003e Result\u003cOrder, DrmError\u003e;\n    async fn fetch_open_orders(\u0026self, params: Option\u003cFetchOrdersParams\u003e) -\u003e Result\u003cVec\u003cOrder\u003e, DrmError\u003e;\n    \n    async fn fetch_positions(\u0026self, market_id: Option\u003c\u0026str\u003e) -\u003e Result\u003cVec\u003cPosition\u003e, DrmError\u003e;\n    async fn fetch_balance(\u0026self) -\u003e Result\u003cHashMap\u003cString, f64\u003e, DrmError\u003e;\n}\n```\n\n### Models\n\n- `Market`: Prediction market with question, outcomes, prices, volume\n- `Order`: Order with price, size, status, timestamps\n- `Position`: Position with size, average price, current price\n- `Orderbook`: Orderbook with bids and asks\n\n## License\n\nMIT\n\n## Acknowledgments\n\n- [guzus/dr-manhattan](https://github.com/guzus/dr-manhattan) - Original Python implementation\n- [CCXT](https://github.com/ccxt/ccxt) - Inspiration for the unified exchange API pattern\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgtg7784%2Fdr-manhattan-rust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgtg7784%2Fdr-manhattan-rust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgtg7784%2Fdr-manhattan-rust/lists"}