feat: 添加 Paradex 适配器支持,更新环境变量配置和适配器构建逻辑

This commit is contained in:
discountry
2025-10-06 18:06:23 +08:00
parent ccc3a2bf89
commit cfd5f4309d
18 changed files with 1681 additions and 177 deletions
+19 -49
View File
@@ -1,11 +1,8 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import { Box, Text, useInput } from "ink";
import { makerConfig } from "../config";
import {
createExchangeAdapter,
getExchangeDisplayName,
resolveExchangeId,
} from "../exchanges/create-adapter";
import { getExchangeDisplayName, resolveExchangeId } from "../exchanges/create-adapter";
import { buildAdapterFromEnv } from "../exchanges/resolve-from-env";
import { MakerEngine, type MakerEngineSnapshot } from "../strategy/maker-engine";
import { DataTable, type TableColumn } from "./components/DataTable";
import { formatNumber } from "../utils/format";
@@ -35,50 +32,7 @@ export function MakerApp({ onExit }: MakerAppProps) {
useEffect(() => {
try {
let adapter;
if (exchangeId === "aster") {
const apiKey = process.env.ASTER_API_KEY;
const apiSecret = process.env.ASTER_API_SECRET;
if (!apiKey || !apiSecret) {
setError(new Error("缺少 ASTER_API_KEY 或 ASTER_API_SECRET 环境变量"));
return;
}
adapter = createExchangeAdapter({
exchange: exchangeId,
symbol: makerConfig.symbol,
aster: { apiKey, apiSecret },
});
} else if (exchangeId === "lighter") {
const accountIndexRaw = process.env.LIGHTER_ACCOUNT_INDEX;
const apiPrivateKey = process.env.LIGHTER_API_PRIVATE_KEY;
if (!accountIndexRaw || !apiPrivateKey) {
setError(new Error("缺少 LIGHTER_ACCOUNT_INDEX 或 LIGHTER_API_PRIVATE_KEY 环境变量"));
return;
}
adapter = createExchangeAdapter({
exchange: exchangeId,
symbol: makerConfig.symbol,
lighter: {
displaySymbol: makerConfig.symbol,
accountIndex: parseInt(accountIndexRaw, 10),
apiPrivateKey,
apiKeyIndex: process.env.LIGHTER_API_KEY_INDEX ? Number(process.env.LIGHTER_API_KEY_INDEX) : 0,
environment: process.env.LIGHTER_ENV,
baseUrl: process.env.LIGHTER_BASE_URL,
marketId: process.env.LIGHTER_MARKET_ID ? Number(process.env.LIGHTER_MARKET_ID) : undefined,
marketSymbol: process.env.LIGHTER_SYMBOL,
priceDecimals: process.env.LIGHTER_PRICE_DECIMALS ? Number(process.env.LIGHTER_PRICE_DECIMALS) : undefined,
sizeDecimals: process.env.LIGHTER_SIZE_DECIMALS ? Number(process.env.LIGHTER_SIZE_DECIMALS) : undefined,
l1Address: process.env.LIGHTER_L1_ADDRESS,
},
});
} else {
adapter = createExchangeAdapter({
exchange: exchangeId,
symbol: makerConfig.symbol,
grvt: { symbol: makerConfig.symbol },
});
}
const adapter = buildAdapterFromEnv({ exchangeId, symbol: makerConfig.symbol });
const engine = new MakerEngine(makerConfig, adapter);
engineRef.current = engine;
setSnapshot(engine.getSnapshot());
@@ -154,6 +108,13 @@ export function MakerApp({ onExit }: MakerAppProps) {
];
const lastLogs = snapshot.tradeLog.slice(-5);
const feedStatus = snapshot.feedStatus;
const feedEntries: Array<{ key: keyof typeof feedStatus; label: string }> = [
{ key: "account", label: "账户" },
{ key: "orders", label: "订单" },
{ key: "depth", label: "深度" },
{ key: "ticker", label: "Ticker" },
];
return (
<Box flexDirection="column" paddingX={1}>
@@ -163,6 +124,15 @@ export function MakerApp({ onExit }: MakerAppProps) {
: {exchangeName} : {snapshot.symbol} : {formatNumber(topBid, 2)} : {formatNumber(topAsk, 2)} : {spreadDisplay}
</Text>
<Text color="gray">: {snapshot.ready ? "实时运行" : "等待市场数据"} Esc </Text>
<Text>
:
{feedEntries.map((entry, index) => (
<Text key={entry.key} color={feedStatus[entry.key] ? "green" : "red"}>
{index === 0 ? " " : " "}
{entry.label}
</Text>
))}
</Text>
</Box>
<Box flexDirection="row" marginBottom={1}>