From ffe8668dffeaabc97c3e4fc37bbeaa915b200c7e Mon Sep 17 00:00:00 2001 From: Naji Dmeiri Date: Tue, 21 Apr 2026 18:09:44 -0400 Subject: [PATCH 1/2] Support get-market-by-token Polymarket endpoint --- core/specs/polymarket/PolymarketClobAPI.yaml | 40 ++++++++++++++++++++ core/src/exchanges/kalshi/api.ts | 4 +- core/src/exchanges/limitless/api.ts | 4 +- core/src/exchanges/myriad/api.ts | 4 +- core/src/exchanges/opinion/api.ts | 4 +- core/src/exchanges/polymarket/api-clob.ts | 22 ++++++++++- core/src/exchanges/polymarket/api-data.ts | 4 +- core/src/exchanges/polymarket/api-gamma.ts | 4 +- core/src/exchanges/probable/api.ts | 4 +- 9 files changed, 74 insertions(+), 16 deletions(-) diff --git a/core/specs/polymarket/PolymarketClobAPI.yaml b/core/specs/polymarket/PolymarketClobAPI.yaml index f9d0558b..58eed2a9 100644 --- a/core/specs/polymarket/PolymarketClobAPI.yaml +++ b/core/specs/polymarket/PolymarketClobAPI.yaml @@ -219,6 +219,25 @@ components: type: string description: Map of token_id to spread value + # --- Markets Schemas --- + MarketsByTokenResponse: + type: object + required: + - condition_id + - primary_token_id + - secondary_token_id + properties: + condition_id: + type: string + description: The condition ID of the market + primary_token_id: + type: string + description: The primary (Yes) token ID + secondary_token_id: + type: string + description: The secondary (No) token ID + description: Condition ID and both token IDs in the market + # --- Auth Schemas --- ApiKeyCreds: type: object @@ -616,6 +635,27 @@ paths: schema: $ref: '#/components/schemas/PriceHistoryResponse' + # ---------------------------------------------------------------------------- + # Markets + # ---------------------------------------------------------------------------- + /markets-by-token/{token_id}: + get: + tags: [Markets] + summary: Get market by token + parameters: + - name: token_id + in: path + required: true + schema: + type: string + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/MarketsByTokenResponse' + # ---------------------------------------------------------------------------- # L1 Auth Methods (From "L1 Authentication" text) # ---------------------------------------------------------------------------- diff --git a/core/src/exchanges/kalshi/api.ts b/core/src/exchanges/kalshi/api.ts index 7f1a0edf..2ce7420b 100644 --- a/core/src/exchanges/kalshi/api.ts +++ b/core/src/exchanges/kalshi/api.ts @@ -1,6 +1,6 @@ /** - * Auto-generated from /Users/samueltinnerholm/Documents/GitHub/pmxt/core/specs/kalshi/Kalshi.yaml - * Generated at: 2026-03-21T08:02:59.422Z + * Auto-generated from /Users/ndmeiri/Developer/pmxt/core/specs/kalshi/Kalshi.yaml + * Generated at: 2026-04-21T22:01:26.550Z * Do not edit manually -- run "npm run fetch:openapi" to regenerate. */ export const kalshiApiSpec = { diff --git a/core/src/exchanges/limitless/api.ts b/core/src/exchanges/limitless/api.ts index e35526d7..cd935420 100644 --- a/core/src/exchanges/limitless/api.ts +++ b/core/src/exchanges/limitless/api.ts @@ -1,6 +1,6 @@ /** - * Auto-generated from /Users/samueltinnerholm/Documents/GitHub/pmxt/core/specs/limitless/Limitless.yaml - * Generated at: 2026-03-21T08:02:59.451Z + * Auto-generated from /Users/ndmeiri/Developer/pmxt/core/specs/limitless/Limitless.yaml + * Generated at: 2026-04-21T22:01:26.562Z * Do not edit manually -- run "npm run fetch:openapi" to regenerate. */ export const limitlessApiSpec = { diff --git a/core/src/exchanges/myriad/api.ts b/core/src/exchanges/myriad/api.ts index 6ef3e0fd..7a99ed03 100644 --- a/core/src/exchanges/myriad/api.ts +++ b/core/src/exchanges/myriad/api.ts @@ -1,6 +1,6 @@ /** - * Auto-generated from /Users/samueltinnerholm/Documents/GitHub/pmxt/core/specs/myriad/myriad.yaml - * Generated at: 2026-03-21T08:02:59.457Z + * Auto-generated from /Users/ndmeiri/Developer/pmxt/core/specs/myriad/myriad.yaml + * Generated at: 2026-04-21T22:01:26.565Z * Do not edit manually -- run "npm run fetch:openapi" to regenerate. */ export const myriadApiSpec = { diff --git a/core/src/exchanges/opinion/api.ts b/core/src/exchanges/opinion/api.ts index 14f70c97..b6434f0b 100644 --- a/core/src/exchanges/opinion/api.ts +++ b/core/src/exchanges/opinion/api.ts @@ -1,6 +1,6 @@ /** - * Auto-generated from /Users/samueltinnerholm/Documents/GitHub/pmxt/core/specs/opinion/opinion-openapi.yaml - * Generated at: 2026-03-21T08:02:59.460Z + * Auto-generated from /Users/ndmeiri/Developer/pmxt/core/specs/opinion/opinion-openapi.yaml + * Generated at: 2026-04-21T22:01:26.567Z * Do not edit manually -- run "npm run fetch:openapi" to regenerate. */ export const opinionApiSpec = { diff --git a/core/src/exchanges/polymarket/api-clob.ts b/core/src/exchanges/polymarket/api-clob.ts index dd8443c3..dbd5cb5b 100644 --- a/core/src/exchanges/polymarket/api-clob.ts +++ b/core/src/exchanges/polymarket/api-clob.ts @@ -1,6 +1,6 @@ /** - * Auto-generated from /Users/samueltinnerholm/Documents/GitHub/pmxt/core/specs/polymarket/PolymarketClobAPI.yaml - * Generated at: 2026-03-21T08:02:59.429Z + * Auto-generated from /Users/ndmeiri/Developer/pmxt/core/specs/polymarket/PolymarketClobAPI.yaml + * Generated at: 2026-04-21T22:01:26.553Z * Do not edit manually -- run "npm run fetch:openapi" to regenerate. */ export const polymarketClobSpec = { @@ -188,6 +188,24 @@ export const polymarketClobSpec = { ] } }, + "/markets-by-token/{token_id}": { + "get": { + "tags": [ + "Markets" + ], + "summary": "Get market by token", + "parameters": [ + { + "name": "token_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ] + } + }, "/auth/api-key": { "post": { "summary": "Create API Key", diff --git a/core/src/exchanges/polymarket/api-data.ts b/core/src/exchanges/polymarket/api-data.ts index ded4cc51..f0ffbd57 100644 --- a/core/src/exchanges/polymarket/api-data.ts +++ b/core/src/exchanges/polymarket/api-data.ts @@ -1,6 +1,6 @@ /** - * Auto-generated from /Users/samueltinnerholm/Documents/GitHub/pmxt/core/specs/polymarket/Polymarket_Data_API.yaml - * Generated at: 2026-03-21T08:02:59.438Z + * Auto-generated from /Users/ndmeiri/Developer/pmxt/core/specs/polymarket/Polymarket_Data_API.yaml + * Generated at: 2026-04-21T22:01:26.557Z * Do not edit manually -- run "npm run fetch:openapi" to regenerate. */ export const polymarketDataSpec = { diff --git a/core/src/exchanges/polymarket/api-gamma.ts b/core/src/exchanges/polymarket/api-gamma.ts index d9365a7e..83a63934 100644 --- a/core/src/exchanges/polymarket/api-gamma.ts +++ b/core/src/exchanges/polymarket/api-gamma.ts @@ -1,6 +1,6 @@ /** - * Auto-generated from /Users/samueltinnerholm/Documents/GitHub/pmxt/core/specs/polymarket/PolymarketGammaAPI.yaml - * Generated at: 2026-03-21T08:02:59.435Z + * Auto-generated from /Users/ndmeiri/Developer/pmxt/core/specs/polymarket/PolymarketGammaAPI.yaml + * Generated at: 2026-04-21T22:01:26.556Z * Do not edit manually -- run "npm run fetch:openapi" to regenerate. */ export const polymarketGammaSpec = { diff --git a/core/src/exchanges/probable/api.ts b/core/src/exchanges/probable/api.ts index b4c8a512..aac43d6b 100644 --- a/core/src/exchanges/probable/api.ts +++ b/core/src/exchanges/probable/api.ts @@ -1,6 +1,6 @@ /** - * Auto-generated from /Users/samueltinnerholm/Documents/GitHub/pmxt/core/specs/probable/probable.yaml - * Generated at: 2026-03-21T08:02:59.454Z + * Auto-generated from /Users/ndmeiri/Developer/pmxt/core/specs/probable/probable.yaml + * Generated at: 2026-04-21T22:01:26.564Z * Do not edit manually -- run "npm run fetch:openapi" to regenerate. */ export const probableApiSpec = { From 44ea32cf56d278d3aa8b83da871c724e8c01345e Mon Sep 17 00:00:00 2001 From: Naji Dmeiri Date: Tue, 21 Apr 2026 18:22:45 -0400 Subject: [PATCH 2/2] Regenerate --- core/api-doc-config.generated.json | 52 ++--- sdks/python/API_REFERENCE.md | 11 + sdks/python/pmxt/client.py | 285 +++++++++++++++++-------- sdks/typescript/API_REFERENCE.md | 11 + sdks/typescript/pmxt/client.ts | 330 +++++++++++++++++++++-------- 5 files changed, 491 insertions(+), 198 deletions(-) diff --git a/core/api-doc-config.generated.json b/core/api-doc-config.generated.json index dcad3fb5..e8f6a58f 100644 --- a/core/api-doc-config.generated.json +++ b/core/api-doc-config.generated.json @@ -1,5 +1,5 @@ { - "_generated": "Auto-generated by extract-jsdoc.js on 2026-04-18T08:57:36.940Z. Do not edit manually.", + "_generated": "Auto-generated by extract-jsdoc.js on 2026-04-21T22:21:45.494Z. Do not edit manually.", "methods": { "has": { "summary": "HTTP verb for the endpoint (e.g. GET, POST). */", @@ -110,7 +110,7 @@ "type": "PaginatedMarketsResult", "description": "PaginatedMarketsResult with data, total, and optional nextCursor" }, - "source": "BaseExchange.ts:531" + "source": "BaseExchange.ts:533" }, "fetchEvents": { "summary": "Fetch events with optional keyword search.", @@ -148,7 +148,7 @@ "notes": [ "Some exchanges (like Limitless) may only support status 'active' for search results." ], - "source": "BaseExchange.ts:600" + "source": "BaseExchange.ts:602" }, "fetchMarket": { "summary": "Fetch a single market by lookup parameters.", @@ -165,7 +165,7 @@ "type": "UnifiedMarket", "description": "A single unified market" }, - "source": "BaseExchange.ts:633" + "source": "BaseExchange.ts:637" }, "fetchEvent": { "summary": "Fetch a single event by lookup parameters.", @@ -182,7 +182,7 @@ "type": "UnifiedEvent", "description": "A single unified event" }, - "source": "BaseExchange.ts:664" + "source": "BaseExchange.ts:668" }, "fetchOHLCV": { "summary": "Fetch historical OHLCV (candlestick) price data for a specific market outcome.", @@ -210,7 +210,7 @@ "Polymarket: outcomeId is the CLOB Token ID. Kalshi: outcomeId is the Market Ticker.", "Resolution options: '1m' | '5m' | '15m' | '1h' | '6h' | '1d'" ], - "source": "BaseExchange.ts:681" + "source": "BaseExchange.ts:685" }, "fetchOrderBook": { "summary": "Fetch the current order book (bids/asks) for a specific outcome.", @@ -227,7 +227,7 @@ "type": "OrderBook", "description": "Current order book with bids and asks" }, - "source": "BaseExchange.ts:696" + "source": "BaseExchange.ts:700" }, "fetchTrades": { "summary": "Fetch raw trade history for a specific outcome.", @@ -253,7 +253,7 @@ "notes": [ "Polymarket requires an API key for trade history. Use fetchOHLCV for public historical data." ], - "source": "BaseExchange.ts:707" + "source": "BaseExchange.ts:711" }, "createOrder": { "summary": "Place a new order on the exchange.", @@ -270,7 +270,7 @@ "type": "Order", "description": "The created order" }, - "source": "BaseExchange.ts:727" + "source": "BaseExchange.ts:731" }, "buildOrder": { "summary": "Build an order payload without submitting it to the exchange.", @@ -287,7 +287,7 @@ "type": "BuiltOrder", "description": "A BuiltOrder containing the exchange-native payload" }, - "source": "BaseExchange.ts:741" + "source": "BaseExchange.ts:745" }, "submitOrder": { "summary": "Submit a pre-built order returned by buildOrder().", @@ -304,7 +304,7 @@ "type": "Order", "description": "The submitted order" }, - "source": "BaseExchange.ts:753" + "source": "BaseExchange.ts:757" }, "cancelOrder": { "summary": "Cancel an existing open order.", @@ -321,7 +321,7 @@ "type": "Order", "description": "The cancelled order" }, - "source": "BaseExchange.ts:763" + "source": "BaseExchange.ts:767" }, "fetchOrder": { "summary": "Fetch a specific order by ID.", @@ -338,7 +338,7 @@ "type": "Order", "description": "The order details" }, - "source": "BaseExchange.ts:773" + "source": "BaseExchange.ts:777" }, "fetchOpenOrders": { "summary": "Fetch all open orders, optionally filtered by market.", @@ -355,7 +355,7 @@ "type": "Order[]", "description": "Array of open orders" }, - "source": "BaseExchange.ts:783" + "source": "BaseExchange.ts:787" }, "fetchPositions": { "summary": "Fetch current user positions across all markets.", @@ -372,7 +372,7 @@ "type": "Position[]", "description": "Array of user positions" }, - "source": "BaseExchange.ts:805" + "source": "BaseExchange.ts:809" }, "fetchBalance": { "summary": "Fetch account balances.", @@ -389,7 +389,7 @@ "type": "Balance[]", "description": "Array of account balances" }, - "source": "BaseExchange.ts:815" + "source": "BaseExchange.ts:819" }, "getExecutionPrice": { "summary": "Calculate the volume-weighted average execution price for a given order size.", @@ -418,7 +418,7 @@ "type": "number", "description": "Average execution price, or 0 if insufficient liquidity" }, - "source": "BaseExchange.ts:825" + "source": "BaseExchange.ts:829" }, "getExecutionPriceDetailed": { "summary": "Calculate detailed execution price information including partial fill data.", @@ -447,7 +447,7 @@ "type": "ExecutionPriceResult", "description": "Detailed execution result with price, filled amount, and fill status" }, - "source": "BaseExchange.ts:838" + "source": "BaseExchange.ts:842" }, "filterMarkets": { "summary": "Filter a list of markets by criteria.", @@ -470,7 +470,7 @@ "type": "UnifiedMarket[]", "description": "Filtered array of markets" }, - "source": "BaseExchange.ts:854" + "source": "BaseExchange.ts:858" }, "filterEvents": { "summary": "Filter a list of events by criteria.", @@ -493,7 +493,7 @@ "type": "UnifiedEvent[]", "description": "Filtered array of events" }, - "source": "BaseExchange.ts:1013" + "source": "BaseExchange.ts:1017" }, "watchOrderBook": { "summary": "Watch order book updates in real-time via WebSocket.", @@ -516,7 +516,7 @@ "type": "OrderBook", "description": "Promise that resolves with the current orderbook state" }, - "source": "BaseExchange.ts:1109" + "source": "BaseExchange.ts:1113" }, "unwatchOrderBook": { "summary": "Unsubscribe from a previously watched order book stream.", @@ -533,7 +533,7 @@ "type": "void", "description": "Result" }, - "source": "BaseExchange.ts:1121" + "source": "BaseExchange.ts:1125" }, "watchTrades": { "summary": "Watch trade executions in real-time via WebSocket.", @@ -568,7 +568,7 @@ "type": "Trade[]", "description": "Promise that resolves with recent trades" }, - "source": "BaseExchange.ts:1134" + "source": "BaseExchange.ts:1138" }, "watchAddress": { "summary": "Stream activity for a public wallet address", @@ -591,7 +591,7 @@ "type": "SubscribedAddressSnapshot", "description": "Promise that resolves with the latest SubscribedAddressSnapshot snapshot" }, - "source": "BaseExchange.ts:1148" + "source": "BaseExchange.ts:1152" }, "unwatchAddress": { "summary": "Stop watching a previously registered wallet address and release its resource updates.", @@ -608,7 +608,7 @@ "type": "void", "description": "Result" }, - "source": "BaseExchange.ts:1161" + "source": "BaseExchange.ts:1165" }, "close": { "summary": "Close all WebSocket connections and clean up resources.", @@ -618,7 +618,7 @@ "type": "void", "description": "Result" }, - "source": "BaseExchange.ts:1170" + "source": "BaseExchange.ts:1174" }, "watchPrices": { "summary": "Watch AMM price updates for a market address (Limitless only).", diff --git a/sdks/python/API_REFERENCE.md b/sdks/python/API_REFERENCE.md index 24b38fc2..f20db42d 100644 --- a/sdks/python/API_REFERENCE.md +++ b/sdks/python/API_REFERENCE.md @@ -1597,6 +1597,7 @@ result = exchange.call_api('operationName', {'param': 'value'}) | `getMidpoint` | `GET` | `/midpoint` | Get midpoint price | Public | | `postSpreads` | `POST` | `/spreads` | Get bid-ask spreads | Public | | `getPricesHistory` | `GET` | `/prices-history` | Get price history for a traded token | Public | +| `getMarketsByToken` | `GET` | `/markets-by-token/{token_id}` | Get market by token | Public | | `postAuthApiKey` | `POST` | `/auth/api-key` | Create API Key | Required | | `getAuthDeriveApiKey` | `GET` | `/auth/derive-api-key` | Derive API Key | Required | | `postOrder` | `POST` | `/order` | Place Single Order | Required | @@ -2046,6 +2047,16 @@ Get price history for a traded token - `interval` (query, string) — enum: `1m,1w,1d,6h,1h,max` - `fidelity` (query, number) +--- +##### `getMarketsByToken` + +**GET** `/markets-by-token/{token_id}` + +Get market by token + +**Parameters:** +- `token_id` (path, string) **required** + --- ##### `postAuthApiKey` diff --git a/sdks/python/pmxt/client.py b/sdks/python/pmxt/client.py index f44b4dfb..404da3d3 100644 --- a/sdks/python/pmxt/client.py +++ b/sdks/python/pmxt/client.py @@ -690,94 +690,130 @@ def load_markets(self, reload: bool = False) -> Dict[str, UnifiedMarket]: def fetch_markets(self, params: Optional[dict] = None, **kwargs) -> List[UnifiedMarket]: try: - args: List[Any] = [] + args = [] if kwargs: params = {**(params or {}), **kwargs} if params is not None: args.append(params) - query = dict(params or {}) - data = self._handle_response( - self._sidecar_read_request("fetchMarkets", query, args) - ) + body: dict = {"args": args} + creds = self._get_credentials_dict() + if creds: + body["credentials"] = creds + url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/fetchMarkets" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + headers.update(self._get_auth_headers()) + response = self._api_client.call_api(method="POST", url=url, body=body, header_params=headers) + response.read() + data = self._handle_response(json.loads(response.data)) return [_convert_market(e) for e in data] except Exception as e: - raise self._parse_api_exception(e) from None + raise Exception(f"Failed to fetch_markets: {self._extract_api_error(e)}") from None def fetch_markets_paginated(self, params: Optional[dict] = None, **kwargs) -> PaginatedMarketsResult: try: - args: List[Any] = [] + args = [] if kwargs: params = {**(params or {}), **kwargs} if params is not None: args.append(params) - query = dict(params or {}) - data = self._handle_response( - self._sidecar_read_request("fetchMarketsPaginated", query, args) - ) + body: dict = {"args": args} + creds = self._get_credentials_dict() + if creds: + body["credentials"] = creds + url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/fetchMarketsPaginated" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + headers.update(self._get_auth_headers()) + response = self._api_client.call_api(method="POST", url=url, body=body, header_params=headers) + response.read() + data = self._handle_response(json.loads(response.data)) return PaginatedMarketsResult( data=[_convert_market(m) for m in data.get("data", [])], total=data.get("total", 0), next_cursor=data.get("nextCursor"), ) except Exception as e: - raise self._parse_api_exception(e) from None + raise Exception(f"Failed to fetch_markets_paginated: {self._extract_api_error(e)}") from None def fetch_events(self, params: Optional[dict] = None, **kwargs) -> List[UnifiedEvent]: try: - args: List[Any] = [] + args = [] if kwargs: params = {**(params or {}), **kwargs} if params is not None: args.append(params) - query = dict(params or {}) - data = self._handle_response( - self._sidecar_read_request("fetchEvents", query, args) - ) + body: dict = {"args": args} + creds = self._get_credentials_dict() + if creds: + body["credentials"] = creds + url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/fetchEvents" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + headers.update(self._get_auth_headers()) + response = self._api_client.call_api(method="POST", url=url, body=body, header_params=headers) + response.read() + data = self._handle_response(json.loads(response.data)) return [_convert_event(e) for e in data] except Exception as e: - raise self._parse_api_exception(e) from None + raise Exception(f"Failed to fetch_events: {self._extract_api_error(e)}") from None def fetch_market(self, params: Optional[dict] = None, **kwargs) -> UnifiedMarket: try: - args: List[Any] = [] + args = [] if kwargs: params = {**(params or {}), **kwargs} if params is not None: args.append(params) - query = dict(params or {}) - data = self._handle_response( - self._sidecar_read_request("fetchMarket", query, args) - ) + body: dict = {"args": args} + creds = self._get_credentials_dict() + if creds: + body["credentials"] = creds + url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/fetchMarket" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + headers.update(self._get_auth_headers()) + response = self._api_client.call_api(method="POST", url=url, body=body, header_params=headers) + response.read() + data = self._handle_response(json.loads(response.data)) return _convert_market(data) except Exception as e: - raise self._parse_api_exception(e) from None + raise Exception(f"Failed to fetch_market: {self._extract_api_error(e)}") from None def fetch_event(self, params: Optional[dict] = None, **kwargs) -> UnifiedEvent: try: - args: List[Any] = [] + args = [] if kwargs: params = {**(params or {}), **kwargs} if params is not None: args.append(params) - query = dict(params or {}) - data = self._handle_response( - self._sidecar_read_request("fetchEvent", query, args) - ) + body: dict = {"args": args} + creds = self._get_credentials_dict() + if creds: + body["credentials"] = creds + url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/fetchEvent" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + headers.update(self._get_auth_headers()) + response = self._api_client.call_api(method="POST", url=url, body=body, header_params=headers) + response.read() + data = self._handle_response(json.loads(response.data)) return _convert_event(data) except Exception as e: - raise self._parse_api_exception(e) from None + raise Exception(f"Failed to fetch_event: {self._extract_api_error(e)}") from None - def fetch_order_book(self, id: Union[str, "MarketOutcome"]) -> OrderBook: + def fetch_order_book(self, id: str) -> OrderBook: try: - id = _resolve_outcome_id(id) - args: List[Any] = [id] - query = {"id": id} - data = self._handle_response( - self._sidecar_read_request("fetchOrderBook", query, args) - ) + args = [] + args.append(id) + body: dict = {"args": args} + creds = self._get_credentials_dict() + if creds: + body["credentials"] = creds + url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/fetchOrderBook" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + headers.update(self._get_auth_headers()) + response = self._api_client.call_api(method="POST", url=url, body=body, header_params=headers) + response.read() + data = self._handle_response(json.loads(response.data)) return _convert_order_book(data) except Exception as e: - raise self._parse_api_exception(e) from None + raise Exception(f"Failed to fetch_order_book: {self._extract_api_error(e)}") from None def cancel_order(self, order_id: str) -> Order: try: @@ -795,98 +831,179 @@ def cancel_order(self, order_id: str) -> Order: data = self._handle_response(json.loads(response.data)) return _convert_order(data) except Exception as e: - raise self._parse_api_exception(e) from None + raise Exception(f"Failed to cancel_order: {self._extract_api_error(e)}") from None def fetch_order(self, order_id: str) -> Order: try: - args: List[Any] = [order_id] - query = {"orderId": order_id} - data = self._handle_response( - self._sidecar_read_request("fetchOrder", query, args) - ) + args = [] + args.append(order_id) + body: dict = {"args": args} + creds = self._get_credentials_dict() + if creds: + body["credentials"] = creds + url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/fetchOrder" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + headers.update(self._get_auth_headers()) + response = self._api_client.call_api(method="POST", url=url, body=body, header_params=headers) + response.read() + data = self._handle_response(json.loads(response.data)) return _convert_order(data) except Exception as e: - raise self._parse_api_exception(e) from None + raise Exception(f"Failed to fetch_order: {self._extract_api_error(e)}") from None def fetch_open_orders(self, market_id: Optional[str] = None) -> List[Order]: try: - args: List[Any] = [] + args = [] if market_id is not None: args.append(market_id) - query = {"marketId": market_id} - data = self._handle_response( - self._sidecar_read_request("fetchOpenOrders", query, args) - ) + body: dict = {"args": args} + creds = self._get_credentials_dict() + if creds: + body["credentials"] = creds + url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/fetchOpenOrders" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + headers.update(self._get_auth_headers()) + response = self._api_client.call_api(method="POST", url=url, body=body, header_params=headers) + response.read() + data = self._handle_response(json.loads(response.data)) return [_convert_order(e) for e in data] except Exception as e: - raise self._parse_api_exception(e) from None + raise Exception(f"Failed to fetch_open_orders: {self._extract_api_error(e)}") from None def fetch_my_trades(self, params: Optional[dict] = None, **kwargs) -> List[UserTrade]: try: - args: List[Any] = [] + args = [] if kwargs: params = {**(params or {}), **kwargs} if params is not None: args.append(params) - query = dict(params or {}) - data = self._handle_response( - self._sidecar_read_request("fetchMyTrades", query, args) - ) + body: dict = {"args": args} + creds = self._get_credentials_dict() + if creds: + body["credentials"] = creds + url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/fetchMyTrades" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + headers.update(self._get_auth_headers()) + response = self._api_client.call_api(method="POST", url=url, body=body, header_params=headers) + response.read() + data = self._handle_response(json.loads(response.data)) return [_convert_user_trade(e) for e in data] except Exception as e: - raise self._parse_api_exception(e) from None + raise Exception(f"Failed to fetch_my_trades: {self._extract_api_error(e)}") from None def fetch_closed_orders(self, params: Optional[dict] = None, **kwargs) -> List[Order]: try: - args: List[Any] = [] + args = [] if kwargs: params = {**(params or {}), **kwargs} if params is not None: args.append(params) - query = dict(params or {}) - data = self._handle_response( - self._sidecar_read_request("fetchClosedOrders", query, args) - ) + body: dict = {"args": args} + creds = self._get_credentials_dict() + if creds: + body["credentials"] = creds + url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/fetchClosedOrders" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + headers.update(self._get_auth_headers()) + response = self._api_client.call_api(method="POST", url=url, body=body, header_params=headers) + response.read() + data = self._handle_response(json.loads(response.data)) return [_convert_order(e) for e in data] except Exception as e: - raise self._parse_api_exception(e) from None + raise Exception(f"Failed to fetch_closed_orders: {self._extract_api_error(e)}") from None def fetch_all_orders(self, params: Optional[dict] = None, **kwargs) -> List[Order]: try: - args: List[Any] = [] + args = [] if kwargs: params = {**(params or {}), **kwargs} if params is not None: args.append(params) - query = dict(params or {}) - data = self._handle_response( - self._sidecar_read_request("fetchAllOrders", query, args) - ) + body: dict = {"args": args} + creds = self._get_credentials_dict() + if creds: + body["credentials"] = creds + url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/fetchAllOrders" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + headers.update(self._get_auth_headers()) + response = self._api_client.call_api(method="POST", url=url, body=body, header_params=headers) + response.read() + data = self._handle_response(json.loads(response.data)) return [_convert_order(e) for e in data] except Exception as e: - raise self._parse_api_exception(e) from None + raise Exception(f"Failed to fetch_all_orders: {self._extract_api_error(e)}") from None - def fetch_positions(self) -> List[Position]: + def fetch_positions(self, address: Optional[str] = None) -> List[Position]: try: - args: List[Any] = [] - query: Dict[str, Any] = {} - data = self._handle_response( - self._sidecar_read_request("fetchPositions", query, args) - ) + args = [] + if address is not None: + args.append(address) + body: dict = {"args": args} + creds = self._get_credentials_dict() + if creds: + body["credentials"] = creds + url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/fetchPositions" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + headers.update(self._get_auth_headers()) + response = self._api_client.call_api(method="POST", url=url, body=body, header_params=headers) + response.read() + data = self._handle_response(json.loads(response.data)) return [_convert_position(e) for e in data] except Exception as e: - raise self._parse_api_exception(e) from None + raise Exception(f"Failed to fetch_positions: {self._extract_api_error(e)}") from None - def fetch_balance(self) -> List[Balance]: + def fetch_balance(self, address: Optional[str] = None) -> List[Balance]: try: - args: List[Any] = [] - query: Dict[str, Any] = {} - data = self._handle_response( - self._sidecar_read_request("fetchBalance", query, args) - ) + args = [] + if address is not None: + args.append(address) + body: dict = {"args": args} + creds = self._get_credentials_dict() + if creds: + body["credentials"] = creds + url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/fetchBalance" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + headers.update(self._get_auth_headers()) + response = self._api_client.call_api(method="POST", url=url, body=body, header_params=headers) + response.read() + data = self._handle_response(json.loads(response.data)) return [_convert_balance(e) for e in data] except Exception as e: - raise self._parse_api_exception(e) from None + raise Exception(f"Failed to fetch_balance: {self._extract_api_error(e)}") from None + + def unwatch_order_book(self, id: str) -> None: + try: + args = [] + args.append(id) + body: dict = {"args": args} + creds = self._get_credentials_dict() + if creds: + body["credentials"] = creds + url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/unwatchOrderBook" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + headers.update(self._get_auth_headers()) + response = self._api_client.call_api(method="POST", url=url, body=body, header_params=headers) + response.read() + self._handle_response(json.loads(response.data)) + except Exception as e: + raise Exception(f"Failed to unwatch_order_book: {self._extract_api_error(e)}") from None + + def unwatch_address(self, address: str) -> None: + try: + args = [] + args.append(address) + body: dict = {"args": args} + creds = self._get_credentials_dict() + if creds: + body["credentials"] = creds + url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/unwatchAddress" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + headers.update(self._get_auth_headers()) + response = self._api_client.call_api(method="POST", url=url, body=body, header_params=headers) + response.read() + self._handle_response(json.loads(response.data)) + except Exception as e: + raise Exception(f"Failed to unwatch_address: {self._extract_api_error(e)}") from None def close(self) -> None: try: @@ -902,7 +1019,7 @@ def close(self) -> None: response.read() self._handle_response(json.loads(response.data)) except Exception as e: - raise self._parse_api_exception(e) from None + raise Exception(f"Failed to close: {self._extract_api_error(e)}") from None # END GENERATED METHODS diff --git a/sdks/typescript/API_REFERENCE.md b/sdks/typescript/API_REFERENCE.md index 677beae2..08e13dcf 100644 --- a/sdks/typescript/API_REFERENCE.md +++ b/sdks/typescript/API_REFERENCE.md @@ -1598,6 +1598,7 @@ const result = await exchange.callApi('operationName', { param: 'value' }); | `getMidpoint` | `GET` | `/midpoint` | Get midpoint price | Public | | `postSpreads` | `POST` | `/spreads` | Get bid-ask spreads | Public | | `getPricesHistory` | `GET` | `/prices-history` | Get price history for a traded token | Public | +| `getMarketsByToken` | `GET` | `/markets-by-token/{token_id}` | Get market by token | Public | | `postAuthApiKey` | `POST` | `/auth/api-key` | Create API Key | Required | | `getAuthDeriveApiKey` | `GET` | `/auth/derive-api-key` | Derive API Key | Required | | `postOrder` | `POST` | `/order` | Place Single Order | Required | @@ -2047,6 +2048,16 @@ Get price history for a traded token - `interval` (query, string) — enum: `1m,1w,1d,6h,1h,max` - `fidelity` (query, number) +--- +##### `getMarketsByToken` + +**GET** `/markets-by-token/{token_id}` + +Get market by token + +**Parameters:** +- `token_id` (path, string) **required** + --- ##### `postAuthApiKey` diff --git a/sdks/typescript/pmxt/client.ts b/sdks/typescript/pmxt/client.ts index 44d21644..060867bc 100644 --- a/sdks/typescript/pmxt/client.ts +++ b/sdks/typescript/pmxt/client.ts @@ -585,11 +585,8 @@ export abstract class Exchange { body: JSON.stringify({ args, credentials: this.getCredentials() }), }); if (!response.ok) { - const body = await response.json().catch(() => ({})); - if (body.error && typeof body.error === "object") { - throw fromServerError(body.error); - } - throw new PmxtError(body.error?.message || response.statusText); + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); } const json = await response.json(); const data = this.handleResponse(json); @@ -599,31 +596,47 @@ export abstract class Exchange { } return result; } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to loadMarkets: ${error}`); + throw new Error(`Failed to loadMarkets: ${error}`); } } async fetchMarkets(params?: any): Promise { await this.initPromise; try { - const args = buildArgsWithOptionalOptions(params); - const query = { ...(params || {}) }; - const json = await this.sidecarReadRequest('fetchMarkets', query, args); + const args: any[] = []; + if (params !== undefined) args.push(params); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/fetchMarkets`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); const data = this.handleResponse(json); return data.map(convertMarket); } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to fetchMarkets: ${error}`); + throw new Error(`Failed to fetchMarkets: ${error}`); } } async fetchMarketsPaginated(params?: any): Promise { await this.initPromise; try { - const args = buildArgsWithOptionalOptions(params); - const query = { ...(params || {}) }; - const json = await this.sidecarReadRequest('fetchMarketsPaginated', query, args); + const args: any[] = []; + if (params !== undefined) args.push(params); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/fetchMarketsPaginated`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); const data = this.handleResponse(json); return { data: (data.data || []).map(convertMarket), @@ -631,68 +644,119 @@ export abstract class Exchange { nextCursor: data.nextCursor, }; } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to fetchMarketsPaginated: ${error}`); + throw new Error(`Failed to fetchMarketsPaginated: ${error}`); } } async fetchEvents(params?: any): Promise { await this.initPromise; try { - const args = buildArgsWithOptionalOptions(params); - const query = { ...(params || {}) }; - const json = await this.sidecarReadRequest('fetchEvents', query, args); + const args: any[] = []; + if (params !== undefined) args.push(params); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/fetchEvents`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); const data = this.handleResponse(json); return data.map(convertEvent); } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to fetchEvents: ${error}`); + throw new Error(`Failed to fetchEvents: ${error}`); } } async fetchMarket(params?: any): Promise { await this.initPromise; try { - const args = buildArgsWithOptionalOptions(params); - const query = { ...(params || {}) }; - const json = await this.sidecarReadRequest('fetchMarket', query, args); + const args: any[] = []; + if (params !== undefined) args.push(params); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/fetchMarket`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); const data = this.handleResponse(json); return convertMarket(data); } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to fetchMarket: ${error}`); + throw new Error(`Failed to fetchMarket: ${error}`); } } async fetchEvent(params?: any): Promise { await this.initPromise; try { - const args = buildArgsWithOptionalOptions(params); - const query = { ...(params || {}) }; - const json = await this.sidecarReadRequest('fetchEvent', query, args); + const args: any[] = []; + if (params !== undefined) args.push(params); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/fetchEvent`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); const data = this.handleResponse(json); return convertEvent(data); } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to fetchEvent: ${error}`); + throw new Error(`Failed to fetchEvent: ${error}`); } } - async fetchOrderBook(id: string | MarketOutcome): Promise { + async fetchOrderBook(id: string): Promise { await this.initPromise; - const resolvedId = resolveOutcomeId(id); try { - const args: any[] = [resolvedId]; - const query = { id: resolvedId }; - const json = await this.sidecarReadRequest('fetchOrderBook', query, args); + const args: any[] = []; + args.push(id); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/fetchOrderBook`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); const data = this.handleResponse(json); return convertOrderBook(data); } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to fetchOrderBook: ${error}`); + throw new Error(`Failed to fetchOrderBook: ${error}`); } } + async submitOrder(built: any): Promise { + await this.initPromise; + try { + const args: any[] = []; + args.push(built); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/submitOrder`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); + const data = this.handleResponse(json); + return convertOrder(data); + } catch (error) { + throw new Error(`Failed to submitOrder: ${error}`); + } + } async cancelOrder(orderId: string): Promise { await this.initPromise; @@ -705,116 +769,210 @@ export abstract class Exchange { body: JSON.stringify({ args, credentials: this.getCredentials() }), }); if (!response.ok) { - const body = await response.json().catch(() => ({})); - if (body.error && typeof body.error === "object") { - throw fromServerError(body.error); - } - throw new PmxtError(body.error?.message || response.statusText); + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); } const json = await response.json(); const data = this.handleResponse(json); return convertOrder(data); } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to cancelOrder: ${error}`); + throw new Error(`Failed to cancelOrder: ${error}`); } } async fetchOrder(orderId: string): Promise { await this.initPromise; try { - const args: any[] = [orderId]; - const query = { orderId }; - const json = await this.sidecarReadRequest('fetchOrder', query, args); + const args: any[] = []; + args.push(orderId); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/fetchOrder`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); const data = this.handleResponse(json); return convertOrder(data); } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to fetchOrder: ${error}`); + throw new Error(`Failed to fetchOrder: ${error}`); } } async fetchOpenOrders(marketId?: string): Promise { await this.initPromise; try { - const args = buildArgsWithOptionalOptions(marketId); - const query = { marketId }; - const json = await this.sidecarReadRequest('fetchOpenOrders', query, args); + const args: any[] = []; + if (marketId !== undefined) args.push(marketId); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/fetchOpenOrders`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); const data = this.handleResponse(json); return data.map(convertOrder); } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to fetchOpenOrders: ${error}`); + throw new Error(`Failed to fetchOpenOrders: ${error}`); } } async fetchMyTrades(params?: any): Promise { await this.initPromise; try { - const args = buildArgsWithOptionalOptions(params); - const query = { ...(params || {}) }; - const json = await this.sidecarReadRequest('fetchMyTrades', query, args); + const args: any[] = []; + if (params !== undefined) args.push(params); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/fetchMyTrades`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); const data = this.handleResponse(json); return data.map(convertUserTrade); } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to fetchMyTrades: ${error}`); + throw new Error(`Failed to fetchMyTrades: ${error}`); } } async fetchClosedOrders(params?: any): Promise { await this.initPromise; try { - const args = buildArgsWithOptionalOptions(params); - const query = { ...(params || {}) }; - const json = await this.sidecarReadRequest('fetchClosedOrders', query, args); + const args: any[] = []; + if (params !== undefined) args.push(params); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/fetchClosedOrders`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); const data = this.handleResponse(json); return data.map(convertOrder); } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to fetchClosedOrders: ${error}`); + throw new Error(`Failed to fetchClosedOrders: ${error}`); } } async fetchAllOrders(params?: any): Promise { await this.initPromise; try { - const args = buildArgsWithOptionalOptions(params); - const query = { ...(params || {}) }; - const json = await this.sidecarReadRequest('fetchAllOrders', query, args); + const args: any[] = []; + if (params !== undefined) args.push(params); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/fetchAllOrders`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); const data = this.handleResponse(json); return data.map(convertOrder); } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to fetchAllOrders: ${error}`); + throw new Error(`Failed to fetchAllOrders: ${error}`); } } async fetchPositions(address?: string): Promise { await this.initPromise; try { - const args: any[] = address ? [address] : []; - const query = { address }; - const json = await this.sidecarReadRequest('fetchPositions', query, args); + const args: any[] = []; + if (address !== undefined) args.push(address); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/fetchPositions`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); const data = this.handleResponse(json); return data.map(convertPosition); } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to fetchPositions: ${error}`); + throw new Error(`Failed to fetchPositions: ${error}`); } } async fetchBalance(address?: string): Promise { await this.initPromise; try { - const args: any[] = address ? [address] : []; - const query = { address }; - const json = await this.sidecarReadRequest('fetchBalance', query, args); + const args: any[] = []; + if (address !== undefined) args.push(address); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/fetchBalance`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); const data = this.handleResponse(json); return data.map(convertBalance); } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to fetchBalance: ${error}`); + throw new Error(`Failed to fetchBalance: ${error}`); + } + } + + async unwatchOrderBook(id: string): Promise { + await this.initPromise; + try { + const args: any[] = []; + args.push(id); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/unwatchOrderBook`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); + this.handleResponse(json); + } catch (error) { + throw new Error(`Failed to unwatchOrderBook: ${error}`); + } + } + + async unwatchAddress(address: string): Promise { + await this.initPromise; + try { + const args: any[] = []; + args.push(address); + const response = await fetch(`${this.config.basePath}/api/${this.exchangeName}/unwatchAddress`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() }, + body: JSON.stringify({ args, credentials: this.getCredentials() }), + }); + if (!response.ok) { + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); + } + const json = await response.json(); + this.handleResponse(json); + } catch (error) { + throw new Error(`Failed to unwatchAddress: ${error}`); } } @@ -828,17 +986,13 @@ export abstract class Exchange { body: JSON.stringify({ args, credentials: this.getCredentials() }), }); if (!response.ok) { - const body = await response.json().catch(() => ({})); - if (body.error && typeof body.error === "object") { - throw fromServerError(body.error); - } - throw new PmxtError(body.error?.message || response.statusText); + const error = await response.json().catch(() => ({})); + throw new Error(error.error?.message || response.statusText); } const json = await response.json(); this.handleResponse(json); } catch (error) { - if (error instanceof PmxtError) throw error; - throw new PmxtError(`Failed to close: ${error}`); + throw new Error(`Failed to close: ${error}`); } }