From 9d1ee6d062c9ad7279088f2a232a81133f4f05e5 Mon Sep 17 00:00:00 2001 From: Samuel Tinnerholm Date: Fri, 5 Jun 2026 15:09:01 +0000 Subject: [PATCH 1/3] fix: preserve Myriad wei precision --- core/src/exchanges/myriad/normalizer.ts | 17 ++++++++++++----- .../normalizers/exchange-normalizers-2.test.ts | 11 +++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/core/src/exchanges/myriad/normalizer.ts b/core/src/exchanges/myriad/normalizer.ts index 60513406..88b8dea9 100644 --- a/core/src/exchanges/myriad/normalizer.ts +++ b/core/src/exchanges/myriad/normalizer.ts @@ -19,6 +19,14 @@ const MYRIAD_PROMOTED_EVENT_KEYS = [ 'id', 'title', 'markets', ] as const; +const WEI_SCALE = BigInt('1000000000000000000'); +const PRECISION_SCALE = BigInt('1000000000000'); + +function weiStringToNumber(value: string): number { + const scaled = (BigInt(value) * PRECISION_SCALE) / WEI_SCALE; + return Number(scaled) / Number(PRECISION_SCALE); +} + function selectTimeframe(interval: CandleInterval): string { switch (interval) { case '1m': @@ -213,15 +221,14 @@ export class MyriadNormalizer implements IExchangeNormalizer ({ - price: Number(priceWei) / WEI, - size: Number(sizeWei) / WEI, + price: weiStringToNumber(priceWei), + size: weiStringToNumber(sizeWei), })), asks: raw.asks.map(([priceWei, sizeWei]) => ({ - price: Number(priceWei) / WEI, - size: Number(sizeWei) / WEI, + price: weiStringToNumber(priceWei), + size: weiStringToNumber(sizeWei), })), timestamp: Date.now(), }; diff --git a/core/test/normalizers/exchange-normalizers-2.test.ts b/core/test/normalizers/exchange-normalizers-2.test.ts index 19f07bd0..17b3bf0f 100644 --- a/core/test/normalizers/exchange-normalizers-2.test.ts +++ b/core/test/normalizers/exchange-normalizers-2.test.ts @@ -565,6 +565,17 @@ describe('MyriadNormalizer', () => { const result = normalizer.normalizeMarket(noExpiry)!; expect(result.resolutionDate.getTime()).toBe(0); }); + + it('preserves sub-1 wei prices without rounding to 1', () => { + const result = normalizer.normalizeClobOrderBook({ + bids: [['999999999999999999', '250000000000000000'], ['100000000000000000', '1']], + asks: [['500000000000000000', '1000000000000000000']], + }); + + expect(result.bids[0].price).toBeLessThan(1); + expect(result.bids[0].price).toBeCloseTo(0.999999999999); + expect(result.bids[0].size).toBeCloseTo(0.25); + }); }); // ----------------------------------------------------------------------- From 9693fc960779e12d3a2b2d11910765a24c10d26c Mon Sep 17 00:00:00 2001 From: Samuel Tinnerholm Date: Mon, 8 Jun 2026 08:46:57 +0000 Subject: [PATCH 2/3] docs: regenerate API reference --- core/api-doc-config.generated.json | 36 +++++++++++++++--------------- sdks/python/API_REFERENCE.md | 2 +- sdks/typescript/API_REFERENCE.md | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/core/api-doc-config.generated.json b/core/api-doc-config.generated.json index 3e176c67..f23c41f8 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-06-02T00:34:44.916Z. Do not edit manually.", + "_generated": "Auto-generated by extract-jsdoc.js on 2026-06-08T08:46:43.899Z. Do not edit manually.", "methods": { "has": { "summary": "HTTP verb for the endpoint (e.g. GET, POST). */", @@ -566,7 +566,7 @@ "type": "UnifiedEvent[]", "description": "Filtered array of events" }, - "source": "BaseExchange.ts:1317" + "source": "BaseExchange.ts:1318" }, "watchOrderBook": { "summary": "Watch order book updates in real-time via WebSocket.", @@ -595,7 +595,7 @@ "type": "OrderBook", "description": "Promise that resolves with the current orderbook state" }, - "source": "BaseExchange.ts:1413" + "source": "BaseExchange.ts:1414" }, "watchOrderBooks": { "summary": "Watch multiple order books simultaneously via WebSocket.", @@ -624,7 +624,7 @@ "type": "Record", "description": "Promise that resolves with order books keyed by ID" }, - "source": "BaseExchange.ts:1426" + "source": "BaseExchange.ts:1427" }, "unwatchOrderBook": { "summary": "Unsubscribe from a previously watched order book stream.", @@ -641,7 +641,7 @@ "type": "void", "description": "Result" }, - "source": "BaseExchange.ts:1454" + "source": "BaseExchange.ts:1455" }, "watchTrades": { "summary": "Watch trade executions in real-time via WebSocket.", @@ -676,7 +676,7 @@ "type": "Trade[]", "description": "Promise that resolves with recent trades" }, - "source": "BaseExchange.ts:1467" + "source": "BaseExchange.ts:1468" }, "watchAddress": { "summary": "Stream activity for a public wallet address", @@ -699,7 +699,7 @@ "type": "SubscribedAddressSnapshot", "description": "Promise that resolves with the latest SubscribedAddressSnapshot snapshot" }, - "source": "BaseExchange.ts:1481" + "source": "BaseExchange.ts:1482" }, "unwatchAddress": { "summary": "Stop watching a previously registered wallet address and release its resource updates.", @@ -716,7 +716,7 @@ "type": "void", "description": "Result" }, - "source": "BaseExchange.ts:1494" + "source": "BaseExchange.ts:1495" }, "close": { "summary": "Close all WebSocket connections and clean up resources.", @@ -726,7 +726,7 @@ "type": "void", "description": "Result" }, - "source": "BaseExchange.ts:1503" + "source": "BaseExchange.ts:1504" }, "fetchMarketMatches": { "summary": "Find the same or related market on other venues. Two modes:", @@ -743,7 +743,7 @@ "type": "MatchResult[]", "description": "Array of matched markets with relation and confidence" }, - "source": "BaseExchange.ts:1517" + "source": "BaseExchange.ts:1518" }, "fetchMatches": { "summary": "fetchMatches", @@ -760,7 +760,7 @@ "type": "MatchResult[]", "description": "Result" }, - "source": "BaseExchange.ts:1533" + "source": "BaseExchange.ts:1534" }, "fetchEventMatches": { "summary": "Find the same or related event on other venues. Two modes:", @@ -777,7 +777,7 @@ "type": "EventMatchResult[]", "description": "Array of matched events with market-level match details" }, - "source": "BaseExchange.ts:1541" + "source": "BaseExchange.ts:1542" }, "compareMarketPrices": { "summary": "Compare live prices for the same market across venues. Finds identity matches and returns side-by-side best bid/ask prices so you can spot price differences at a glance.", @@ -794,7 +794,7 @@ "type": "PriceComparison[]", "description": "Array of price comparisons across venues" }, - "source": "BaseExchange.ts:1557" + "source": "BaseExchange.ts:1558" }, "fetchRelatedMarkets": { "summary": "Find related markets across venues. Discovers subset/superset market relationships", @@ -811,7 +811,7 @@ "type": "PriceComparison[]", "description": "Array of subset/superset matches with live prices" }, - "source": "BaseExchange.ts:1567" + "source": "BaseExchange.ts:1568" }, "fetchMatchedMarkets": { "summary": "fetchMatchedMarkets", @@ -828,7 +828,7 @@ "type": "MatchedMarketPair[]", "description": "Result" }, - "source": "BaseExchange.ts:1578" + "source": "BaseExchange.ts:1579" }, "fetchMatchedPrices": { "summary": "fetchMatchedPrices", @@ -845,7 +845,7 @@ "type": "MatchedPricePair[]", "description": "Array of matched market pairs with prices from each venue" }, - "source": "BaseExchange.ts:1586" + "source": "BaseExchange.ts:1587" }, "fetchHedges": { "summary": "fetchHedges", @@ -862,7 +862,7 @@ "type": "PriceComparison[]", "description": "Array of subset/superset matches with live prices" }, - "source": "BaseExchange.ts:1597" + "source": "BaseExchange.ts:1598" }, "fetchArbitrage": { "summary": "fetchArbitrage", @@ -879,7 +879,7 @@ "type": "ArbitrageOpportunity[]", "description": "Array of arbitrage opportunities sorted by spread" }, - "source": "BaseExchange.ts:1607" + "source": "BaseExchange.ts:1608" }, "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 dac681ce..b20f3aa2 100644 --- a/sdks/python/API_REFERENCE.md +++ b/sdks/python/API_REFERENCE.md @@ -1456,7 +1456,7 @@ title: str # The market title (e.g., "Will BTC close above $100k on Dec 31?"). description: str # Long-form market description or resolution criteria. slug: str # URL-friendly slug for the market. outcomes: List[MarketOutcome] # The possible outcomes for this market. -resolution_date: str # When the market is scheduled to resolve. +resolution_date: str # When the market is scheduled to resolve. Optional because some venues do not publish a cutoff for every market (e.g. Opinion categorical children) — emit `undefined` rather than coercing to epoch. volume24h: float # Trading volume over the past 24 hours (USD). volume: float # Total / Lifetime volume liquidity: float # Current market liquidity (USD). diff --git a/sdks/typescript/API_REFERENCE.md b/sdks/typescript/API_REFERENCE.md index f8504e0a..ec2f3280 100644 --- a/sdks/typescript/API_REFERENCE.md +++ b/sdks/typescript/API_REFERENCE.md @@ -1456,7 +1456,7 @@ title: string; // The market title (e.g., "Will BTC close above $100k on Dec 31? description: string; // Long-form market description or resolution criteria. slug: string; // URL-friendly slug for the market. outcomes: MarketOutcome[]; // The possible outcomes for this market. -resolutionDate: string; // When the market is scheduled to resolve. +resolutionDate: string; // When the market is scheduled to resolve. Optional because some venues do not publish a cutoff for every market (e.g. Opinion categorical children) — emit `undefined` rather than coercing to epoch. volume24h: number; // Trading volume over the past 24 hours (USD). volume: number; // Total / Lifetime volume liquidity: number; // Current market liquidity (USD). From e4fb6ddd8153dcaaa3ea85ba22f8d517fd61743e Mon Sep 17 00:00:00 2001 From: Samuel Tinnerholm Date: Mon, 8 Jun 2026 09:03:12 +0000 Subject: [PATCH 3/3] docs: regenerate generated artifacts for PR #879 --- core/api-doc-config.generated.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/api-doc-config.generated.json b/core/api-doc-config.generated.json index 134a795d..6d5ae97e 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-06-08T08:31:38.004Z. Do not edit manually.", + "_generated": "Auto-generated by extract-jsdoc.js on 2026-06-08T09:03:10.122Z. Do not edit manually.", "methods": { "has": { "summary": "HTTP verb for the endpoint (e.g. GET, POST). */",