@clonegod/ttd-core 2.0.28 → 2.0.30
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/index.d.ts +5 -2
- package/dist/index.js +3 -0
- package/dist/token/price/get_eth_token_price.d.ts +2 -0
- package/dist/token/price/get_eth_token_price.js +168 -0
- package/dist/token/price/test_uniswap_gql.d.ts +1 -0
- package/dist/token/price/test_uniswap_gql.js +65 -0
- package/package.json +16 -14
package/dist/index.d.ts
CHANGED
|
@@ -23,7 +23,8 @@ export declare const STREAMING_TRANSACTION_CONFIRMED = "STREAMING_TRANSACTION_CO
|
|
|
23
23
|
export declare enum CHAIN_ID {
|
|
24
24
|
TRON = "TRON",
|
|
25
25
|
SOLANA = "SOLANA",
|
|
26
|
-
BSC = "BSC"
|
|
26
|
+
BSC = "BSC",
|
|
27
|
+
ETH = "ETH"
|
|
27
28
|
}
|
|
28
29
|
export declare enum DEX_ID {
|
|
29
30
|
SUNSWAP_V2 = "SUNSWAP-V2",
|
|
@@ -36,7 +37,9 @@ export declare enum DEX_ID {
|
|
|
36
37
|
METEORA_AMM = "METEORA-AMM",
|
|
37
38
|
PUMPFUN_AMM = "PUMPFUN-AMM",
|
|
38
39
|
PANCAKE_AMM = "PANCAKE-AMM",
|
|
39
|
-
PANCAKE_CLMM = "PANCAKE-CLMM"
|
|
40
|
+
PANCAKE_CLMM = "PANCAKE-CLMM",
|
|
41
|
+
UNISWAP_AMM = "UNISWAP-AMM",
|
|
42
|
+
UNISWAP_CLMM = "UNISWAP-CLMM"
|
|
40
43
|
}
|
|
41
44
|
export declare enum GROUP_ID {
|
|
42
45
|
TRON_DEV1 = "TRON-DEV1",
|
package/dist/index.js
CHANGED
|
@@ -106,6 +106,7 @@ var CHAIN_ID;
|
|
|
106
106
|
CHAIN_ID["TRON"] = "TRON";
|
|
107
107
|
CHAIN_ID["SOLANA"] = "SOLANA";
|
|
108
108
|
CHAIN_ID["BSC"] = "BSC";
|
|
109
|
+
CHAIN_ID["ETH"] = "ETH";
|
|
109
110
|
})(CHAIN_ID || (exports.CHAIN_ID = CHAIN_ID = {}));
|
|
110
111
|
var DEX_ID;
|
|
111
112
|
(function (DEX_ID) {
|
|
@@ -120,6 +121,8 @@ var DEX_ID;
|
|
|
120
121
|
DEX_ID["PUMPFUN_AMM"] = "PUMPFUN-AMM";
|
|
121
122
|
DEX_ID["PANCAKE_AMM"] = "PANCAKE-AMM";
|
|
122
123
|
DEX_ID["PANCAKE_CLMM"] = "PANCAKE-CLMM";
|
|
124
|
+
DEX_ID["UNISWAP_AMM"] = "UNISWAP-AMM";
|
|
125
|
+
DEX_ID["UNISWAP_CLMM"] = "UNISWAP-CLMM";
|
|
123
126
|
})(DEX_ID || (exports.DEX_ID = DEX_ID = {}));
|
|
124
127
|
var GROUP_ID;
|
|
125
128
|
(function (GROUP_ID) {
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.get_eth_token_price_info = get_eth_token_price_info;
|
|
16
|
+
require('dotenv').config();
|
|
17
|
+
const axios_1 = __importDefault(require("axios"));
|
|
18
|
+
const index_1 = require("../../index");
|
|
19
|
+
const gecko_terminal_1 = require("./gecko_terminal");
|
|
20
|
+
const price_cache_1 = require("./price_cache");
|
|
21
|
+
function get_eth_token_price_info(addresses) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
addresses = addresses.map(addr => addr.toLowerCase());
|
|
24
|
+
const result = new Map();
|
|
25
|
+
const PRICE_CHANNELS = [
|
|
26
|
+
{
|
|
27
|
+
name: 'CachedPrice',
|
|
28
|
+
fetchFn: price_cache_1.fetchPriceFromCache,
|
|
29
|
+
batchSize: 100,
|
|
30
|
+
batchDelay: 1000,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'Uniswap',
|
|
34
|
+
fetchFn: fetchPriceFromUniSwap,
|
|
35
|
+
batchSize: 10,
|
|
36
|
+
batchDelay: 1000,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'GeckoTerminal',
|
|
40
|
+
fetchFn: (address_list) => (0, gecko_terminal_1.fetchPriceFromGeckoTerminal)(index_1.CHAIN_ID.ETH, address_list),
|
|
41
|
+
batchSize: 10,
|
|
42
|
+
batchDelay: 2000,
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
try {
|
|
46
|
+
for (const channel of PRICE_CHANNELS) {
|
|
47
|
+
if (addresses.length === 0)
|
|
48
|
+
break;
|
|
49
|
+
(0, index_1.log_debug)(`[get_token_price_info] Processing ${addresses.length} tokens using ${channel.name}`);
|
|
50
|
+
const batches = (0, index_1.chunkArray)(addresses, channel.batchSize);
|
|
51
|
+
(0, index_1.log_debug)(`[get_token_price_info] Split into ${batches.length} batches of size ${channel.batchSize}`);
|
|
52
|
+
let remainingAddresses = [...addresses];
|
|
53
|
+
for (let i = 0; i < batches.length; i++) {
|
|
54
|
+
const batch = batches[i];
|
|
55
|
+
if (batch.length === 0)
|
|
56
|
+
continue;
|
|
57
|
+
(0, index_1.log_debug)(`[get_token_price_info] Processing batch ${i + 1}/${batches.length} (${batch.length} tokens) with ${channel.name}`);
|
|
58
|
+
try {
|
|
59
|
+
const channelResult = yield channel.fetchFn(batch);
|
|
60
|
+
for (const [address, priceInfo] of channelResult.entries()) {
|
|
61
|
+
result.set(address, priceInfo);
|
|
62
|
+
remainingAddresses = remainingAddresses.filter(addr => addr !== address);
|
|
63
|
+
if (channel.name !== 'CachedPrice') {
|
|
64
|
+
(0, price_cache_1.cache_new_market_price)(address, priceInfo.price, channel.name);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
(0, index_1.log_warn)(`[get_token_price_info] Error processing batch ${i + 1} with ${channel.name}: ${error instanceof Error ? error.message : String(error)}`);
|
|
70
|
+
}
|
|
71
|
+
if (i < batches.length - 1) {
|
|
72
|
+
yield (0, index_1.sleep)(channel.batchDelay);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
addresses = [...remainingAddresses];
|
|
76
|
+
if (addresses.length === 0) {
|
|
77
|
+
(0, index_1.log_debug)(`[get_token_price_info] All token prices retrieved using ${channel.name}`);
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (result.size === 0) {
|
|
82
|
+
throw new Error(`Unable to get price information for any token: ${addresses.join(', ')}`);
|
|
83
|
+
}
|
|
84
|
+
if (addresses.length > 0) {
|
|
85
|
+
(0, index_1.log_warn)(`[get_token_price_info] Failed to get prices for ${addresses.length} tokens after trying all channels: ${addresses.join(', ')}`);
|
|
86
|
+
}
|
|
87
|
+
(0, index_1.log_debug)(`[get_token_price_info] Completed price fetching for ${result.size} tokens`);
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
throw new Error(`Failed to get token price information: ${error instanceof Error ? error.message : String(error)}`);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function fetchPriceFromUniSwap(addresses) {
|
|
96
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
var _a, _b, _c, _d;
|
|
98
|
+
const result = new Map();
|
|
99
|
+
const currentTime = (0, index_1.getCurDateTime)();
|
|
100
|
+
const query = `
|
|
101
|
+
query Tokens($contracts: [ContractInput!]!) {
|
|
102
|
+
tokens(contracts: $contracts) {
|
|
103
|
+
id
|
|
104
|
+
address
|
|
105
|
+
symbol
|
|
106
|
+
name
|
|
107
|
+
decimals
|
|
108
|
+
market(currency: USD) {
|
|
109
|
+
price { value }
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
`;
|
|
114
|
+
const variables = {
|
|
115
|
+
contracts: addresses.map(address => ({
|
|
116
|
+
address: address,
|
|
117
|
+
chain: 'ETHEREUM'
|
|
118
|
+
}))
|
|
119
|
+
};
|
|
120
|
+
const headers = {
|
|
121
|
+
'Content-Type': 'application/json',
|
|
122
|
+
'Origin': 'https://app.uniswap.org',
|
|
123
|
+
'Referer': 'https://app.uniswap.org/',
|
|
124
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
|
|
125
|
+
};
|
|
126
|
+
try {
|
|
127
|
+
const response = yield axios_1.default.post('https://interface.gateway.uniswap.org/v1/graphql', {
|
|
128
|
+
query,
|
|
129
|
+
variables
|
|
130
|
+
}, {
|
|
131
|
+
headers,
|
|
132
|
+
timeout: 30000
|
|
133
|
+
});
|
|
134
|
+
if ((_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.tokens) {
|
|
135
|
+
for (const token of response.data.data.tokens) {
|
|
136
|
+
if ((_d = (_c = token.market) === null || _c === void 0 ? void 0 : _c.price) === null || _d === void 0 ? void 0 : _d.value) {
|
|
137
|
+
result.set(token.address.toLowerCase(), {
|
|
138
|
+
symbol: token.symbol || '',
|
|
139
|
+
address: token.address.toLowerCase(),
|
|
140
|
+
price: token.market.price.value.toString(),
|
|
141
|
+
update_time: currentTime
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
(0, index_1.log_debug)(`[fetchPriceFromUniSwap] Retrieved prices for ${result.size}/${addresses.length} tokens`);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
(0, index_1.log_debug)(`[fetchPriceFromUniSwap] Invalid response from Uniswap for ${addresses.length} tokens`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
(0, index_1.log_warn)(`[fetchPriceFromUniSwap] Request failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
153
|
+
}
|
|
154
|
+
return result;
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
if (require.main === module) {
|
|
158
|
+
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
159
|
+
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
160
|
+
let addresses = [
|
|
161
|
+
"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
|
|
162
|
+
"0xdac17f958d2ee523a2206206994597c13d831ec7",
|
|
163
|
+
"0x1f9840a85d5af5bf1d1762f925bdaddc4201f984",
|
|
164
|
+
];
|
|
165
|
+
console.log(yield get_eth_token_price_info(addresses));
|
|
166
|
+
}))();
|
|
167
|
+
}))();
|
|
168
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const axios_1 = __importDefault(require("axios"));
|
|
16
|
+
const query = `
|
|
17
|
+
query Tokens($contracts: [ContractInput!]!) {
|
|
18
|
+
tokens(contracts: $contracts) {
|
|
19
|
+
id
|
|
20
|
+
address
|
|
21
|
+
symbol
|
|
22
|
+
name
|
|
23
|
+
decimals
|
|
24
|
+
market(currency: USD) {
|
|
25
|
+
price { value }
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
`;
|
|
30
|
+
const variables = {
|
|
31
|
+
contracts: [
|
|
32
|
+
{ address: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984', chain: 'ETHEREUM' },
|
|
33
|
+
{ address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', chain: 'ETHEREUM' },
|
|
34
|
+
{ address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', chain: 'ETHEREUM' }
|
|
35
|
+
]
|
|
36
|
+
};
|
|
37
|
+
const headers = {
|
|
38
|
+
'Content-Type': 'application/json',
|
|
39
|
+
'Origin': 'https://app.uniswap.org',
|
|
40
|
+
'Referer': 'https://app.uniswap.org/',
|
|
41
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
|
|
42
|
+
};
|
|
43
|
+
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
44
|
+
try {
|
|
45
|
+
const response = yield axios_1.default.post('https://interface.gateway.uniswap.org/v1/graphql', {
|
|
46
|
+
query,
|
|
47
|
+
variables
|
|
48
|
+
}, {
|
|
49
|
+
headers,
|
|
50
|
+
timeout: 30000
|
|
51
|
+
});
|
|
52
|
+
console.log(JSON.stringify(response.data, null, 2));
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
56
|
+
console.error('请求错误:', error.message);
|
|
57
|
+
if (error.response) {
|
|
58
|
+
console.error('响应数据:', error.response.data);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
console.error('其他错误:', error);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}))();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clonegod/ttd-core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.30",
|
|
4
4
|
"description": "Common types and utilities for trading systems - use `npm run push` to publish",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -13,32 +13,34 @@
|
|
|
13
13
|
"push": "npm run build && npm publish"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"express": "^4.19.2",
|
|
19
|
-
"express-ws": "^5.0.2",
|
|
20
|
-
"body-parser": "^1.20.3",
|
|
21
|
-
"axios": "^1.8.4",
|
|
16
|
+
"@noble/secp256k1": "1.7.1",
|
|
17
|
+
"axios": "^1.9.0",
|
|
22
18
|
"bn.js": "^5.2.1",
|
|
19
|
+
"body-parser": "^1.20.3",
|
|
23
20
|
"bs58": "^6.0.0",
|
|
24
21
|
"decimal.js": "^10.5.0",
|
|
22
|
+
"dotenv": "^16.4.7",
|
|
23
|
+
"express": "^4.19.2",
|
|
24
|
+
"express-ws": "^5.0.2",
|
|
25
|
+
"graphql": "^16.11.0",
|
|
26
|
+
"graphql-request": "^7.2.0",
|
|
27
|
+
"keccak": "^3.0.4",
|
|
25
28
|
"moment": "^2.30.1",
|
|
26
|
-
"
|
|
29
|
+
"redis": "^4.7.0",
|
|
27
30
|
"short-uuid": "^5.2.0",
|
|
28
|
-
"
|
|
29
|
-
"@noble/secp256k1": "1.7.1",
|
|
31
|
+
"ts-node": "^10.9.2",
|
|
30
32
|
"typescript": "^5.3.3",
|
|
31
|
-
"
|
|
33
|
+
"uuid": "^11.1.0"
|
|
32
34
|
},
|
|
33
35
|
"devDependencies": {
|
|
34
36
|
"@types/bn.js": "~5.1.5",
|
|
37
|
+
"@types/node": "^22.7.9",
|
|
35
38
|
"rimraf": "^5.0.5",
|
|
36
39
|
"ts-node": "^10.9.2",
|
|
37
|
-
"typescript": "^5.3.3"
|
|
38
|
-
"@types/node": "^22.7.9"
|
|
40
|
+
"typescript": "^5.3.3"
|
|
39
41
|
},
|
|
40
42
|
"overrides": {},
|
|
41
43
|
"publishConfig": {
|
|
42
44
|
"access": "public"
|
|
43
45
|
}
|
|
44
|
-
}
|
|
46
|
+
}
|