Skip to main content

limitless/
api.rs

1//! API endpoint enums for the Limitless Exchange REST and WebSocket APIs.
2//!
3//! All REST endpoints are categorized into logical groups matching the
4//! API reference: Authentication, Markets, Trading, Portfolio, Navigation,
5//! API Tokens, Partner Accounts, and Public Portfolio.
6
7use crate::Config;
8
9/// Represents a REST API endpoint category and its specific operation.
10///
11/// Each variant maps to a URL path relative to the base API URL.
12/// The `as_ref()` implementation returns the full path string.
13#[derive(Debug, Clone)]
14pub enum API {
15    // ── Authentication ──
16    Auth(Auth),
17    // ── Markets ──
18    Market(Market),
19    // ── Trading ──
20    Trade(Trade),
21    // ── Portfolio ──
22    PortfolioEndpoint(PortfolioEndpoint),
23    // ── Market Navigation ──
24    Nav(Nav),
25    // ── API Tokens ──
26    ApiToken(ApiToken),
27    // ── Partner Accounts ──
28    Partner(Partner),
29    // ── Public Portfolio ──
30    PublicPortfolio(PublicPortfolio),
31}
32
33// ── Authentication ──
34
35#[derive(Debug, Clone)]
36pub enum Auth {
37    /// `POST /auth/api-keys` — Create a new API key (UI-authenticated only).
38    CreateApiKey,
39    /// `GET /auth/api-keys` — Get the active API key metadata.
40    GetApiKey,
41    /// `DELETE /auth/api-keys` — Revoke the active API key.
42    RevokeApiKey,
43}
44
45// ── Markets ──
46
47#[derive(Debug, Clone)]
48pub enum Market {
49    /// `GET /markets/active` — Browse active markets.
50    Active,
51    /// `GET /markets/active/{categoryId}` — Browse active markets by category.
52    ActiveCategory,
53    /// `GET /markets/categories/count` — Category counts.
54    CategoryCount,
55    /// `GET /markets/active/slugs` — Active market slugs.
56    ActiveSlugs,
57    /// `GET /markets/{addressOrSlug}` — Get market details.
58    GetMarket,
59    /// `GET /markets/{addressOrSlug}/oracle-candles` — Oracle candlestick data.
60    OracleCandles,
61    /// `GET /markets/{slug}/get-feed-events` — Feed events for a market.
62    FeedEvents,
63    /// `GET /markets/search` — Semantic search for markets.
64    Search,
65}
66
67// ── Trading ──
68
69#[derive(Debug, Clone)]
70pub enum Trade {
71    /// `POST /orders` — Create a new order.
72    CreateOrder,
73    /// `POST /orders/status/batch` — Batch order status lookup.
74    OrderStatusBatch,
75    /// `POST /orders/cancel` — Cancel order (combined: by orderId or clientOrderId).
76    CancelCombined,
77    /// `POST /orders/cancel-batch` — Batch cancel (by orderIds).
78    CancelBatch,
79    /// `DELETE /orders/{orderId}` — Cancel a single order by ID.
80    CancelOrder,
81    /// `DELETE /orders/all/{slug}` — Cancel all orders in a market.
82    CancelAll,
83    /// `GET /markets/{slug}/orderbook` — Get orderbook.
84    Orderbook,
85    /// `GET /markets/{slug}/historical-price` — Historical prices.
86    HistoricalPrice,
87    /// `GET /markets/{slug}/locked-balance` — Locked balance.
88    LockedBalance,
89    /// `GET /markets/{slug}/user-orders` — User's orders in a market.
90    UserOrders,
91    /// `GET /markets/{slug}/events` — Market events.
92    MarketEvents,
93}
94
95// ── Portfolio ──
96
97#[derive(Debug, Clone)]
98pub enum PortfolioEndpoint {
99    /// `GET /profiles/{account}` — Get your profile.
100    GetProfile,
101    /// `GET /portfolio/trades` — Get trades.
102    Trades,
103    /// `GET /portfolio/positions` — Get positions.
104    Positions,
105    /// `GET /portfolio/pnl-chart` — PnL chart.
106    PnlChart,
107    /// `GET /portfolio/points` — Points breakdown.
108    Points,
109    /// `GET /portfolio/history` — Portfolio history (cursor-paginated).
110    History,
111    /// `GET /portfolio/trading/allowance` — Trading allowance check.
112    Allowance,
113}
114
115// ── Market Navigation ──
116
117#[derive(Debug, Clone)]
118pub enum Nav {
119    /// `GET /navigation` — Hierarchical navigation tree.
120    GetNavigation,
121    /// `GET /market-pages/by-path` — Resolve a path to a market page.
122    GetPageByPath,
123    /// `GET /market-pages/{id}/markets` — List markets for a page.
124    ListPageMarkets,
125    /// `GET /property-keys` — List all property keys.
126    ListPropertyKeys,
127    /// `GET /property-keys/{id}` — Get a specific property key.
128    GetPropertyKey,
129    /// `GET /property-keys/{id}/options` — List options for a property key.
130    ListPropertyOptions,
131}
132
133// ── API Tokens ──
134
135#[derive(Debug, Clone)]
136pub enum ApiToken {
137    /// `GET /api-tokens/capabilities` — Partner capabilities.
138    GetCapabilities,
139    /// `POST /api-tokens/derive` — Derive a scoped token.
140    Derive,
141    /// `GET /api-tokens` — List active tokens.
142    ListActive,
143    /// `DELETE /api-tokens/{id}` — Revoke a token.
144    Revoke,
145}
146
147// ── Partner Accounts ──
148
149#[derive(Debug, Clone)]
150pub enum Partner {
151    /// `POST /profiles/partner-accounts` — Create partner sub-account.
152    CreateSubAccount,
153    /// `GET /profiles/partner-accounts/{id}/allowances` — Check allowances.
154    CheckAllowances,
155    /// `POST /profiles/partner-accounts/{id}/allowances/retry` — Retry allowances.
156    RetryAllowances,
157}
158
159// ── Public Portfolio ──
160
161#[derive(Debug, Clone)]
162pub enum PublicPortfolio {
163    /// `GET /public/portfolio/{address}/volume` — User traded volume.
164    TradedVolume,
165    /// `GET /public/portfolio/{address}/positions` — Public positions.
166    Positions,
167    /// `GET /public/portfolio/{address}/pnl-chart` — Public PnL chart.
168    PnlChart,
169}
170
171// ── WebSocket API ──
172
173/// WebSocket API endpoints for the Limitless Exchange.
174#[derive(Debug, Clone)]
175pub enum WebsocketAPI {
176    /// Public market data stream (`/markets` namespace).
177    Markets,
178}
179
180impl AsRef<str> for API {
181    fn as_ref(&self) -> &str {
182        match self {
183            // Authentication
184            API::Auth(Auth::CreateApiKey) => "auth/api-keys",
185            API::Auth(Auth::GetApiKey) => "auth/api-keys",
186            API::Auth(Auth::RevokeApiKey) => "auth/api-keys",
187
188            // Markets
189            API::Market(Market::Active) => "markets/active",
190            API::Market(Market::ActiveCategory) => "markets/active",
191            API::Market(Market::CategoryCount) => "markets/categories/count",
192            API::Market(Market::ActiveSlugs) => "markets/active/slugs",
193            API::Market(Market::GetMarket) => "markets",
194            API::Market(Market::OracleCandles) => "markets",
195            API::Market(Market::FeedEvents) => "markets",
196            API::Market(Market::Search) => "markets/search",
197
198            // Trading
199            API::Trade(Trade::CreateOrder) => "orders",
200            API::Trade(Trade::OrderStatusBatch) => "orders/status/batch",
201            API::Trade(Trade::CancelCombined) => "orders/cancel",
202            API::Trade(Trade::CancelBatch) => "orders/cancel-batch",
203            API::Trade(Trade::CancelOrder) => "orders",
204            API::Trade(Trade::CancelAll) => "orders/all",
205            API::Trade(Trade::Orderbook) => "markets",
206            API::Trade(Trade::HistoricalPrice) => "markets",
207            API::Trade(Trade::LockedBalance) => "markets",
208            API::Trade(Trade::UserOrders) => "markets",
209            API::Trade(Trade::MarketEvents) => "markets",
210
211            // Portfolio
212            API::PortfolioEndpoint(PortfolioEndpoint::GetProfile) => "profiles",
213            API::PortfolioEndpoint(PortfolioEndpoint::Trades) => "portfolio/trades",
214            API::PortfolioEndpoint(PortfolioEndpoint::Positions) => "portfolio/positions",
215            API::PortfolioEndpoint(PortfolioEndpoint::PnlChart) => "portfolio/pnl-chart",
216            API::PortfolioEndpoint(PortfolioEndpoint::Points) => "portfolio/points",
217            API::PortfolioEndpoint(PortfolioEndpoint::History) => "portfolio/history",
218            API::PortfolioEndpoint(PortfolioEndpoint::Allowance) => "portfolio/trading/allowance",
219
220            // Navigation
221            API::Nav(Nav::GetNavigation) => "navigation",
222            API::Nav(Nav::GetPageByPath) => "market-pages/by-path",
223            API::Nav(Nav::ListPageMarkets) => "market-pages",
224            API::Nav(Nav::ListPropertyKeys) => "property-keys",
225            API::Nav(Nav::GetPropertyKey) => "property-keys",
226            API::Nav(Nav::ListPropertyOptions) => "property-keys",
227
228            // API Tokens
229            API::ApiToken(ApiToken::GetCapabilities) => "api-tokens/capabilities",
230            API::ApiToken(ApiToken::Derive) => "api-tokens/derive",
231            API::ApiToken(ApiToken::ListActive) => "api-tokens",
232            API::ApiToken(ApiToken::Revoke) => "api-tokens", // id appended
233
234            // Partner Accounts
235            API::Partner(Partner::CreateSubAccount) => "profiles/partner-accounts",
236            API::Partner(Partner::CheckAllowances) => "profiles/partner-accounts", // appended
237            API::Partner(Partner::RetryAllowances) => "profiles/partner-accounts", // appended
238
239            // Public Portfolio
240            API::PublicPortfolio(PublicPortfolio::TradedVolume) => "public/portfolio", // appended
241            API::PublicPortfolio(PublicPortfolio::Positions) => "public/portfolio",    // appended
242            API::PublicPortfolio(PublicPortfolio::PnlChart) => "public/portfolio",     // appended
243        }
244    }
245}
246
247impl AsRef<str> for WebsocketAPI {
248    fn as_ref(&self) -> &str {
249        match self {
250            WebsocketAPI::Markets => "/markets",
251        }
252    }
253}
254
255// ── The `Limitless` trait ──
256
257/// Trait implemented by all manager types for consistent construction.
258///
259/// Each manager provides either public (no auth) or authenticated
260/// API methods scoped to a specific domain (markets, trading, portfolio, etc.).
261pub trait Limitless {
262    /// Create a new manager instance with optional API key and secret.
263    ///
264    /// Use `None` for both when accessing public endpoints only.
265    fn new(api_key: Option<String>, secret: Option<String>) -> Self;
266
267    /// Create a new manager instance with a custom `Config`.
268    fn new_with_config(config: &Config, api_key: Option<String>, secret: Option<String>) -> Self;
269}