diff --git a/src/exchanges/lighter/gateway.ts b/src/exchanges/lighter/gateway.ts index 9ec937e..d8daa7a 100644 --- a/src/exchanges/lighter/gateway.ts +++ b/src/exchanges/lighter/gateway.ts @@ -905,13 +905,18 @@ export class LighterGateway { candidates = preferred; } + const preferSpot = wantsSpot; candidates.sort((a, b) => { const aExact = normalizeSymbolForms(a.symbol).includes(desiredSymbol.toUpperCase()) ? 1 : 0; const bExact = normalizeSymbolForms(b.symbol).includes(desiredSymbol.toUpperCase()) ? 1 : 0; if (aExact !== bExact) return bExact - aExact; const aSpot = normalizeMarketType(a.market_type) === "spot" ? 1 : 0; const bSpot = normalizeMarketType(b.market_type) === "spot" ? 1 : 0; - if (aSpot !== bSpot) return bSpot - aSpot; + if (aSpot !== bSpot) { + const aScore = preferSpot ? aSpot : 1 - aSpot; // prefer perp when not explicitly spot + const bScore = preferSpot ? bSpot : 1 - bSpot; + return bScore - aScore; + } return 0; }); diff --git a/tests/lighter/order-book-choice.test.ts b/tests/lighter/order-book-choice.test.ts new file mode 100644 index 0000000..be7a07d --- /dev/null +++ b/tests/lighter/order-book-choice.test.ts @@ -0,0 +1,40 @@ +import { describe, expect, it } from "vitest"; +import type { LighterOrderBookMetadata } from "../../src/exchanges/lighter/types"; +import { LighterGateway } from "../../src/exchanges/lighter/gateway"; + +const pickBestOrderBook = (books: LighterOrderBookMetadata[], desiredSymbol: string) => + (LighterGateway.prototype as any).pickBestOrderBook.call({}, books, desiredSymbol); + +describe("pickBestOrderBook", () => { + const spotBook = { + market_id: 2048, + symbol: "ETH/USDC", + market_type: "spot", + supported_price_decimals: 2, + supported_size_decimals: 4, + min_base_amount: "0.0001", + min_quote_amount: "5", + } as LighterOrderBookMetadata; + + const perpBook = { + market_id: 3048, + symbol: "ETH-PERP", + market_type: "perp", + supported_price_decimals: 2, + supported_size_decimals: 3, + min_base_amount: "0.001", + min_quote_amount: "5", + } as LighterOrderBookMetadata; + + it("prefers perp when desired symbol does not explicitly request spot", () => { + const picked = pickBestOrderBook([spotBook, perpBook], "ETH"); + expect(picked?.market_type).toBe("perp"); + expect(picked?.market_id).toBe(3048); + }); + + it("still prefers spot when symbol clearly indicates spot", () => { + const picked = pickBestOrderBook([spotBook, perpBook], "ETH/USDC"); + expect(picked?.market_type).toBe("spot"); + expect(picked?.market_id).toBe(2048); + }); +});