@clonegod/ttd-core 3.0.7 → 3.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/quote/on_quote_response.d.ts +1 -1
- package/dist/quote/on_quote_response.js +2 -2
- package/dist/quote/to_price_message.d.ts +1 -1
- package/dist/quote/to_price_message.js +5 -3
- package/dist/token/price/defi_llama.js +13 -7
- package/dist/token/price/gecko_terminal.js +13 -7
- package/dist/token/price/get_solana_token_price.js +14 -8
- package/package.json +1 -1
- package/types/index.d.ts +8 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { StandardPoolInfoType, QuoteResultType } from "../../types";
|
|
2
2
|
import { AppConfig } from "../app_config";
|
|
3
|
-
export declare function on_quote_respose(appConfig: AppConfig, pool_info: StandardPoolInfoType, quote_amount_usd: number, execution_price: number, stream_time: number, quote_start_time: number, slot_info: string, result: [QuoteResultType, QuoteResultType, number], txid: string, push_price_message?: boolean): void;
|
|
3
|
+
export declare function on_quote_respose(appConfig: AppConfig, pool_info: StandardPoolInfoType, quote_amount_usd: number, execution_price: number, stream_time: number, quote_start_time: number, slot_info: string, result: [QuoteResultType, QuoteResultType, number], txid: string, push_price_message?: boolean, source?: string): void;
|
|
@@ -5,7 +5,7 @@ const analyze_1 = require("../analyze");
|
|
|
5
5
|
const log_quote_price_1 = require("./log_quote_price");
|
|
6
6
|
const publish_quote_price_1 = require("./publish_quote_price");
|
|
7
7
|
const to_price_message_1 = require("./to_price_message");
|
|
8
|
-
function on_quote_respose(appConfig, pool_info, quote_amount_usd, execution_price, stream_time, quote_start_time, slot_info, result, txid, push_price_message = true) {
|
|
8
|
+
function on_quote_respose(appConfig, pool_info, quote_amount_usd, execution_price, stream_time, quote_start_time, slot_info, result, txid, push_price_message = true, source = "") {
|
|
9
9
|
const quote_end_time = new Date().getTime();
|
|
10
10
|
const quote_ask_price = Number(result[0].price);
|
|
11
11
|
const quote_bid_price = Number(result[1].price);
|
|
@@ -19,7 +19,7 @@ function on_quote_respose(appConfig, pool_info, quote_amount_usd, execution_pric
|
|
|
19
19
|
price_time,
|
|
20
20
|
total_quote_time: price_time - stream_time
|
|
21
21
|
};
|
|
22
|
-
(0, to_price_message_1.to_price_message)(appConfig, quote_amount_usd, execution_price, quote_ask_price, quote_bid_price, pool_info, time, slot_info)
|
|
22
|
+
(0, to_price_message_1.to_price_message)(appConfig, quote_amount_usd, execution_price, quote_ask_price, quote_bid_price, pool_info, time, slot_info, source)
|
|
23
23
|
.then((price_msg) => {
|
|
24
24
|
if (push_price_message) {
|
|
25
25
|
(0, publish_quote_price_1.publish_quote_price)(appConfig, price_msg);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StandardPoolInfoType, QuoteTimeInfoType, PriceMessageType } from '../../types';
|
|
2
2
|
import { AppConfig } from '../app_config';
|
|
3
3
|
export declare const get_quote_token_decimals: (pool_info: StandardPoolInfoType) => number;
|
|
4
|
-
export declare function to_price_message(appConfig: AppConfig, quote_amount_usd: number, tx_price: number, quote_ask_price: number, quote_bid_price: number, pool_info: StandardPoolInfoType, time: QuoteTimeInfoType, slot?: string): Promise<PriceMessageType>;
|
|
4
|
+
export declare function to_price_message(appConfig: AppConfig, quote_amount_usd: number, tx_price: number, quote_ask_price: number, quote_bid_price: number, pool_info: StandardPoolInfoType, time: QuoteTimeInfoType, slot?: string, source?: string): Promise<PriceMessageType>;
|
|
5
5
|
export declare function normalize_pair_name(priceMessage: PriceMessageType): void;
|
|
@@ -30,8 +30,8 @@ const get_quote_token_decimals = (pool_info) => {
|
|
|
30
30
|
return decimals;
|
|
31
31
|
};
|
|
32
32
|
exports.get_quote_token_decimals = get_quote_token_decimals;
|
|
33
|
-
function to_price_message(
|
|
34
|
-
return __awaiter(this,
|
|
33
|
+
function to_price_message(appConfig_1, quote_amount_usd_1, tx_price_1, quote_ask_price_1, quote_bid_price_1, pool_info_1, time_1, slot_1) {
|
|
34
|
+
return __awaiter(this, arguments, void 0, function* (appConfig, quote_amount_usd, tx_price, quote_ask_price, quote_bid_price, pool_info, time, slot, source = "") {
|
|
35
35
|
let { pool_address, tokenA, tokenB } = pool_info;
|
|
36
36
|
let { dex_id, pool_name, fee_rate, is_reverse_token } = yield appConfig.arb_cache.get_one_pool_info(pool_address);
|
|
37
37
|
let _dex_id = dex_id;
|
|
@@ -79,7 +79,9 @@ function to_price_message(appConfig, quote_amount_usd, tx_price, quote_ask_price
|
|
|
79
79
|
quantity: quote_amount_usd
|
|
80
80
|
},
|
|
81
81
|
time,
|
|
82
|
-
slot
|
|
82
|
+
slot,
|
|
83
|
+
blockNumber: slot ? parseInt(slot, 10) || undefined : undefined,
|
|
84
|
+
source: source !== null && source !== void 0 ? source : ""
|
|
83
85
|
};
|
|
84
86
|
normalize_pair_name(price_message);
|
|
85
87
|
return price_message;
|
|
@@ -17,18 +17,20 @@ const axios_1 = __importDefault(require("axios"));
|
|
|
17
17
|
const index_1 = require("../../index");
|
|
18
18
|
function fetchPriceFromDefiLlama(network, addresses) {
|
|
19
19
|
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
var _a;
|
|
20
21
|
const result = new Map();
|
|
21
22
|
const currentTime = (0, index_1.getCurDateTime)();
|
|
22
23
|
const timeout = 10000;
|
|
23
|
-
const maxRetries =
|
|
24
|
+
const maxRetries = 1;
|
|
24
25
|
const retrysleepMs = 1000;
|
|
25
26
|
const addressString = addresses.map(address => `${network.toLowerCase()}:${address}`).join(',');
|
|
26
27
|
const url = `https://coins.llama.fi/prices/current/${addressString}`;
|
|
27
28
|
console.log(url);
|
|
28
29
|
(0, index_1.log_debug)(`[fetchPriceFromDefiLlama] Requesting prices for ${addresses.length} tokens`);
|
|
29
|
-
let
|
|
30
|
-
while (
|
|
30
|
+
let attempt = 0;
|
|
31
|
+
while (attempt <= maxRetries) {
|
|
31
32
|
try {
|
|
33
|
+
attempt++;
|
|
32
34
|
const response = yield axios_1.default.get(url, { timeout });
|
|
33
35
|
let tokenPrices = response.data['coins'];
|
|
34
36
|
if (tokenPrices) {
|
|
@@ -51,10 +53,14 @@ function fetchPriceFromDefiLlama(network, addresses) {
|
|
|
51
53
|
break;
|
|
52
54
|
}
|
|
53
55
|
catch (error) {
|
|
54
|
-
|
|
55
|
-
(0, index_1.log_warn)(`[fetchPriceFromDefiLlama] Request failed (attempt ${
|
|
56
|
-
if (
|
|
57
|
-
|
|
56
|
+
const status = axios_1.default.isAxiosError(error) ? (_a = error.response) === null || _a === void 0 ? void 0 : _a.status : undefined;
|
|
57
|
+
(0, index_1.log_warn)(`[fetchPriceFromDefiLlama] Request failed (attempt ${attempt}/${maxRetries + 1}): ${error instanceof Error ? error.message : String(error)}`);
|
|
58
|
+
if (status === 429) {
|
|
59
|
+
(0, index_1.log_warn)(`[fetchPriceFromDefiLlama] Rate limited (429). Skip retries and fallback to next channel immediately.`);
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
if (attempt <= maxRetries) {
|
|
63
|
+
const currentRetrysleep = retrysleepMs * attempt;
|
|
58
64
|
(0, index_1.log_debug)(`[fetchPriceFromDefiLlama] Retrying in ${currentRetrysleep}ms...`);
|
|
59
65
|
yield (0, index_1.sleep)(currentRetrysleep);
|
|
60
66
|
}
|
|
@@ -17,18 +17,20 @@ const axios_1 = __importDefault(require("axios"));
|
|
|
17
17
|
const index_1 = require("../../index");
|
|
18
18
|
function fetchPriceFromGeckoTerminal(network, addresses) {
|
|
19
19
|
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
var _a;
|
|
20
21
|
const result = new Map();
|
|
21
22
|
const currentTime = (0, index_1.getCurDateTime)();
|
|
22
23
|
const timeout = 10000;
|
|
23
|
-
const maxRetries =
|
|
24
|
+
const maxRetries = 1;
|
|
24
25
|
const retrysleepMs = 1000;
|
|
25
26
|
const addressString = addresses.join(',');
|
|
26
27
|
const url = `https://api.geckoterminal.com/api/v2/simple/networks/${network.toLowerCase()}/token_price/${addressString}`;
|
|
27
28
|
console.log(url);
|
|
28
29
|
(0, index_1.log_debug)(`[fetchPriceFromGeckoTerminal] Requesting prices for ${addresses.length} tokens`);
|
|
29
|
-
let
|
|
30
|
-
while (
|
|
30
|
+
let attempt = 0;
|
|
31
|
+
while (attempt <= maxRetries) {
|
|
31
32
|
try {
|
|
33
|
+
attempt++;
|
|
32
34
|
const response = yield axios_1.default.get(url, { timeout });
|
|
33
35
|
if (response.data && response.data.data && response.data.data.attributes && response.data.data.attributes.token_prices) {
|
|
34
36
|
const tokenPrices = response.data.data.attributes.token_prices;
|
|
@@ -57,10 +59,14 @@ function fetchPriceFromGeckoTerminal(network, addresses) {
|
|
|
57
59
|
break;
|
|
58
60
|
}
|
|
59
61
|
catch (error) {
|
|
60
|
-
|
|
61
|
-
(0, index_1.log_warn)(`[fetchPriceFromGeckoTerminal] Request failed (attempt ${
|
|
62
|
-
if (
|
|
63
|
-
|
|
62
|
+
const status = axios_1.default.isAxiosError(error) ? (_a = error.response) === null || _a === void 0 ? void 0 : _a.status : undefined;
|
|
63
|
+
(0, index_1.log_warn)(`[fetchPriceFromGeckoTerminal] Request failed (attempt ${attempt}/${maxRetries + 1}): ${error instanceof Error ? error.message : String(error)}`);
|
|
64
|
+
if (status === 429) {
|
|
65
|
+
(0, index_1.log_warn)(`[fetchPriceFromGeckoTerminal] Rate limited (429). Skip retries and fallback to next channel immediately.`);
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
if (attempt <= maxRetries) {
|
|
69
|
+
const currentRetrysleep = retrysleepMs * attempt;
|
|
64
70
|
(0, index_1.log_debug)(`[fetchPriceFromGeckoTerminal] Retrying in ${currentRetrysleep}ms...`);
|
|
65
71
|
yield (0, index_1.sleep)(currentRetrysleep);
|
|
66
72
|
}
|
|
@@ -101,16 +101,18 @@ function get_solana_token_price_info(addresses) {
|
|
|
101
101
|
}
|
|
102
102
|
function fetchPriceFromJupiter(addresses) {
|
|
103
103
|
return __awaiter(this, void 0, void 0, function* () {
|
|
104
|
+
var _a;
|
|
104
105
|
const result = new Map();
|
|
105
106
|
const currentTime = (0, index_1.getCurDateTime)();
|
|
106
107
|
const timeout = 6000;
|
|
107
|
-
const maxRetries =
|
|
108
|
-
const retrysleepMs =
|
|
108
|
+
const maxRetries = 1;
|
|
109
|
+
const retrysleepMs = 1000;
|
|
109
110
|
const url = (process.env.JUPITER_PRICE_API || 'https://api.jup.ag/price/v3') + `?ids=${addresses.join(',')}`;
|
|
110
111
|
(0, index_1.log_debug)(`[fetchPriceFromJupiter] Requesting Jupiter API for ${addresses.length} tokens`);
|
|
111
|
-
let
|
|
112
|
-
while (
|
|
112
|
+
let attempt = 0;
|
|
113
|
+
while (attempt <= maxRetries) {
|
|
113
114
|
try {
|
|
115
|
+
attempt++;
|
|
114
116
|
const response = yield axios_1.default.get(url, {
|
|
115
117
|
headers: {
|
|
116
118
|
'x-api-key': process.env.JUPITER_API_KEY
|
|
@@ -138,10 +140,14 @@ function fetchPriceFromJupiter(addresses) {
|
|
|
138
140
|
break;
|
|
139
141
|
}
|
|
140
142
|
catch (error) {
|
|
141
|
-
|
|
142
|
-
(0, index_1.log_warn)(`[fetchPriceFromJupiter] Request failed (attempt ${
|
|
143
|
-
if (
|
|
144
|
-
|
|
143
|
+
const status = axios_1.default.isAxiosError(error) ? (_a = error.response) === null || _a === void 0 ? void 0 : _a.status : undefined;
|
|
144
|
+
(0, index_1.log_warn)(`[fetchPriceFromJupiter] Request failed (attempt ${attempt}/${maxRetries + 1}): ${error instanceof Error ? error.message : String(error)}, url: ${url}`);
|
|
145
|
+
if (status === 429) {
|
|
146
|
+
(0, index_1.log_warn)(`[fetchPriceFromJupiter] Rate limited (429). Skip retries and fallback to next channel immediately.`);
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
if (attempt <= maxRetries) {
|
|
150
|
+
const currentRetrysleep = retrysleepMs * attempt;
|
|
145
151
|
(0, index_1.log_debug)(`[fetchPriceFromJupiter] Retrying in ${currentRetrysleep}ms...`);
|
|
146
152
|
yield (0, index_1.sleep)(currentRetrysleep);
|
|
147
153
|
}
|
package/package.json
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -295,7 +295,9 @@ export interface PriceMessageType {
|
|
|
295
295
|
bid: PriceType
|
|
296
296
|
time: QuoteTimeInfoType // quote 耗时数据
|
|
297
297
|
slot: string // 询价生成的价格,所对应的slot (account, vaultA, vaultB)
|
|
298
|
+
blockNumber?: number // 报价基于的区块号
|
|
298
299
|
quote_source?: QuoteSourceType // 触发本次询价的事件源信息
|
|
300
|
+
source?: string // 报价来源:rpc:v1, QuickNode:v2, YYWS:v3
|
|
299
301
|
}
|
|
300
302
|
|
|
301
303
|
export interface QuoteSourceType {
|
|
@@ -344,6 +346,12 @@ export interface Ladder {
|
|
|
344
346
|
// 询价生成的价格,所对应的slot (account, vaultA, vaultB)
|
|
345
347
|
slot: string
|
|
346
348
|
|
|
349
|
+
// 区块号
|
|
350
|
+
blockNumber?: string
|
|
351
|
+
|
|
352
|
+
// ��格来源: "rpc:v1" | "{provider_id}:v2" | "{provider_id}:v3"
|
|
353
|
+
source?: string
|
|
354
|
+
|
|
347
355
|
// unique_orderbook_id 价格更新时间
|
|
348
356
|
price_id: string
|
|
349
357
|
price_time: string
|