mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-11 17:28:08 +00:00
feat: 添加 Lighter 适配器的调试日志功能,优化错误处理和订单簿数据规范化
This commit is contained in:
@@ -140,7 +140,9 @@ export class LighterExchangeAdapter implements ExchangeAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private logError(context: string, error: unknown): void {
|
private logError(context: string, error: unknown): void {
|
||||||
console.error(`[LighterExchangeAdapter] ${context} failed: ${extractMessage(error)}`);
|
if (process.env.LIGHTER_DEBUG === "1" || process.env.LIGHTER_DEBUG === "true") {
|
||||||
|
console.error(`[LighterExchangeAdapter] ${context} failed: ${extractMessage(error)}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -210,7 +210,13 @@ export class LighterGateway {
|
|||||||
apiKeyIndices: this.apiKeyIndices,
|
apiKeyIndices: this.apiKeyIndices,
|
||||||
http: this.http,
|
http: this.http,
|
||||||
});
|
});
|
||||||
this.logger = options.logger ?? ((context, error) => console.error(`[LighterGateway] ${context}`, error));
|
const debugEnabled = process.env.LIGHTER_DEBUG === "1" || process.env.LIGHTER_DEBUG === "true";
|
||||||
|
this.logger = options.logger ?? ((context, error) => {
|
||||||
|
if (debugEnabled) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(`[LighterGateway] ${context}`, error);
|
||||||
|
}
|
||||||
|
});
|
||||||
this.marketId = options.marketId != null ? Number(options.marketId) : null;
|
this.marketId = options.marketId != null ? Number(options.marketId) : null;
|
||||||
this.priceDecimals = options.priceDecimals ?? null;
|
this.priceDecimals = options.priceDecimals ?? null;
|
||||||
this.sizeDecimals = options.sizeDecimals ?? null;
|
this.sizeDecimals = options.sizeDecimals ?? null;
|
||||||
@@ -263,7 +269,9 @@ export class LighterGateway {
|
|||||||
nonce,
|
nonce,
|
||||||
});
|
});
|
||||||
if (!this.loggedCreateOrderPayload) {
|
if (!this.loggedCreateOrderPayload) {
|
||||||
this.logger("createOrder.txInfo", signed.txInfo);
|
if (process.env.LIGHTER_DEBUG === "1" || process.env.LIGHTER_DEBUG === "true") {
|
||||||
|
this.logger("createOrder.txInfo", signed.txInfo);
|
||||||
|
}
|
||||||
this.loggedCreateOrderPayload = true;
|
this.loggedCreateOrderPayload = true;
|
||||||
}
|
}
|
||||||
const auth = await this.ensureAuthToken();
|
const auth = await this.ensureAuthToken();
|
||||||
@@ -271,7 +279,9 @@ export class LighterGateway {
|
|||||||
authToken: auth,
|
authToken: auth,
|
||||||
priceProtection: false,
|
priceProtection: false,
|
||||||
});
|
});
|
||||||
this.logger("createOrder.sendTx.response", response);
|
if (process.env.LIGHTER_DEBUG === "1" || process.env.LIGHTER_DEBUG === "true") {
|
||||||
|
this.logger("createOrder.sendTx.response", response);
|
||||||
|
}
|
||||||
return lighterOrderToAster(this.displaySymbol, {
|
return lighterOrderToAster(this.displaySymbol, {
|
||||||
order_index: Number(signParams.clientOrderIndex % 1_000_000_000n),
|
order_index: Number(signParams.clientOrderIndex % 1_000_000_000n),
|
||||||
client_order_index: Number(signParams.clientOrderIndex),
|
client_order_index: Number(signParams.clientOrderIndex),
|
||||||
@@ -458,7 +468,7 @@ export class LighterGateway {
|
|||||||
return this.auth.token;
|
return this.auth.token;
|
||||||
}
|
}
|
||||||
const deadline = now + 10 * 60 * 1000; // 10 minutes horizon
|
const deadline = now + 10 * 60 * 1000; // 10 minutes horizon
|
||||||
const token = this.signer.createAuthToken(deadline);
|
const token = await this.signer.createAuthToken(deadline);
|
||||||
this.auth.token = token;
|
this.auth.token = token;
|
||||||
this.auth.expiresAt = deadline;
|
this.auth.expiresAt = deadline;
|
||||||
return token;
|
return token;
|
||||||
@@ -507,8 +517,8 @@ export class LighterGateway {
|
|||||||
const snapshot: LighterOrderBookSnapshot = {
|
const snapshot: LighterOrderBookSnapshot = {
|
||||||
market_id: this.marketId ?? 0,
|
market_id: this.marketId ?? 0,
|
||||||
offset: message.order_book.offset ?? Date.now(),
|
offset: message.order_book.offset ?? Date.now(),
|
||||||
bids: message.order_book.bids ?? [],
|
bids: normalizeLevels(message.order_book.bids ?? []),
|
||||||
asks: message.order_book.asks ?? [],
|
asks: normalizeLevels(message.order_book.asks ?? []),
|
||||||
};
|
};
|
||||||
this.orderBook = snapshot;
|
this.orderBook = snapshot;
|
||||||
this.emitDepth();
|
this.emitDepth();
|
||||||
@@ -519,10 +529,12 @@ export class LighterGateway {
|
|||||||
const update = message?.order_book;
|
const update = message?.order_book;
|
||||||
if (!update) return;
|
if (!update) return;
|
||||||
if (Array.isArray(update.asks)) {
|
if (Array.isArray(update.asks)) {
|
||||||
this.orderBook.asks = mergeLevels(this.orderBook.asks ?? [], update.asks);
|
const asks = normalizeLevels(update.asks);
|
||||||
|
this.orderBook.asks = mergeLevels(this.orderBook.asks ?? [], asks);
|
||||||
}
|
}
|
||||||
if (Array.isArray(update.bids)) {
|
if (Array.isArray(update.bids)) {
|
||||||
this.orderBook.bids = mergeLevels(this.orderBook.bids ?? [], update.bids);
|
const bids = normalizeLevels(update.bids);
|
||||||
|
this.orderBook.bids = mergeLevels(this.orderBook.bids ?? [], bids);
|
||||||
}
|
}
|
||||||
this.orderBook.offset = update.offset ?? this.orderBook.offset;
|
this.orderBook.offset = update.offset ?? this.orderBook.offset;
|
||||||
this.emitDepth();
|
this.emitDepth();
|
||||||
@@ -777,6 +789,21 @@ function getBestPrice(levels: LighterOrderBookLevel[] | Array<any> | undefined,
|
|||||||
return side === "bid" ? Math.max(...sorted) : Math.min(...sorted);
|
return side === "bid" ? Math.max(...sorted) : Math.min(...sorted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeLevels(raw: Array<LighterOrderBookLevel | [string | number, string | number]>): LighterOrderBookLevel[] {
|
||||||
|
if (!Array.isArray(raw)) return [];
|
||||||
|
return raw
|
||||||
|
.map((entry) => {
|
||||||
|
if (Array.isArray(entry)) {
|
||||||
|
const price = String(entry[0]);
|
||||||
|
const size = String(entry[1]);
|
||||||
|
return { price, size } as LighterOrderBookLevel;
|
||||||
|
}
|
||||||
|
const obj = entry as LighterOrderBookLevel;
|
||||||
|
return { price: String(obj.price), size: String(obj.size) } as LighterOrderBookLevel;
|
||||||
|
})
|
||||||
|
.filter((lvl) => lvl.price != null && lvl.size != null);
|
||||||
|
}
|
||||||
|
|
||||||
function mapOrderType(type: OrderType): number {
|
function mapOrderType(type: OrderType): number {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "MARKET":
|
case "MARKET":
|
||||||
|
|||||||
@@ -61,7 +61,9 @@ export class HttpNonceManager implements LighterNonceManager {
|
|||||||
async refresh(apiKeyIndex: number): Promise<void> {
|
async refresh(apiKeyIndex: number): Promise<void> {
|
||||||
const nonce = await this.http.getNextNonce(this.accountIndex, apiKeyIndex);
|
const nonce = await this.http.getNextNonce(this.accountIndex, apiKeyIndex);
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.debug("[LighterNonceManager] refresh", { apiKeyIndex, nonce: nonce.toString() });
|
if (process.env.LIGHTER_DEBUG === "1" || process.env.LIGHTER_DEBUG === "true") {
|
||||||
|
console.debug("[LighterNonceManager] refresh", { apiKeyIndex, nonce: nonce.toString() });
|
||||||
|
}
|
||||||
this.slots.set(apiKeyIndex, { apiKeyIndex, next: nonce, lastIssued: null });
|
this.slots.set(apiKeyIndex, { apiKeyIndex, next: nonce, lastIssued: null });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user