From 0e5026aaa105d066ccb1135a2e36ce7a9fd9365d Mon Sep 17 00:00:00 2001 From: discountry Date: Fri, 3 Oct 2025 02:54:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Lighter=20?= =?UTF-8?q?=E9=80=82=E9=85=8D=E5=99=A8=E7=9A=84=E8=B4=A6=E6=88=B7=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E9=83=A8=E5=88=86=E6=9B=B4=E6=96=B0=E5=92=8C=E5=B8=82?= =?UTF-8?q?=E5=9C=BA=E8=AE=A2=E5=8D=95=E7=B1=BB=E5=9E=8B=E7=9A=84=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/exchanges/lighter/gateway.ts | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/exchanges/lighter/gateway.ts b/src/exchanges/lighter/gateway.ts index d8bb8bb..b27850e 100644 --- a/src/exchanges/lighter/gateway.ts +++ b/src/exchanges/lighter/gateway.ts @@ -566,9 +566,14 @@ export class LighterGateway { private handleAccountAll(message: any): void { if (!message) return; - const positionsObject = message.positions ?? {}; - const positions: LighterPosition[] = Object.values(positionsObject) as LighterPosition[]; - this.positions = positions; + // account_all messages may be partial updates; if positions is omitted, retain existing positions + if (Object.prototype.hasOwnProperty.call(message, "positions")) { + const positionsObject = message.positions ?? {}; + const positions: LighterPosition[] = (Array.isArray(positionsObject) + ? (positionsObject as LighterPosition[]) + : (Object.values(positionsObject) as LighterPosition[])) as LighterPosition[]; + this.positions = positions; + } this.emitAccount(); } @@ -727,7 +732,7 @@ export class LighterGateway { const baseAmountScaledString = scaledToDecimalString(baseAmount, this.sizeDecimals); const clientOrderIndex = BigInt(Date.now() % Number.MAX_SAFE_INTEGER); let priceScaled = params.price != null ? decimalToScaled(params.price, this.priceDecimals) : null; - if (params.type === "MARKET" && priceScaled == null) { + if ((params.type === "MARKET" || params.type === "STOP_MARKET") && priceScaled == null) { priceScaled = decimalToScaled(this.estimateMarketPrice(side), this.priceDecimals); } if (priceScaled == null) { @@ -840,7 +845,12 @@ function mapOrderType(type: OrderType): number { } function mapTimeInForce(timeInForce: string | undefined, type: OrderType): number { - const value = (timeInForce ?? (type === "MARKET" ? "IOC" : "GTC")).toUpperCase(); + // Lighter expects STOP orders to be immediate-or-cancel at trigger time. + // Force IOC for MARKET and STOP_MARKET to satisfy chain validation. + if (type === "MARKET" || type === "STOP_MARKET") { + return LIGHTER_TIME_IN_FORCE.IMMEDIATE_OR_CANCEL; + } + const value = (timeInForce ?? "GTC").toUpperCase(); switch (value) { case "IOC": return LIGHTER_TIME_IN_FORCE.IMMEDIATE_OR_CANCEL;