@clonegod/ttd-sol-common 2.0.0 → 2.0.2

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 CHANGED
@@ -0,0 +1 @@
1
+ export * from './quote';
package/dist/index.js CHANGED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./quote"), exports);
@@ -0,0 +1 @@
1
+ export * from './pricing';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./pricing"), exports);
@@ -0,0 +1 @@
1
+ export * from './token_price_cache';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./token_price_cache"), exports);
@@ -0,0 +1,9 @@
1
+ export declare class TokenPriceCache {
2
+ private tokenPriceCache;
3
+ private readonly PRICE_CACHE_TIMEOUT_MILLS;
4
+ constructor();
5
+ getTokenPrice(tokenAddress: string): Promise<{
6
+ price: string;
7
+ timestamp: number;
8
+ }>;
9
+ }
@@ -0,0 +1,39 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.TokenPriceCache = void 0;
13
+ const dist_1 = require("@clonegod/ttd-core/dist");
14
+ class TokenPriceCache {
15
+ constructor() {
16
+ this.tokenPriceCache = new Map();
17
+ this.PRICE_CACHE_TIMEOUT_MILLS = parseInt(process.env.PRICE_CACHE_TIMEOUT_MILLS || Number(1000 * 60 * 60 * 1).toString());
18
+ (0, dist_1.log_info)(`代币价格缓存超时时间: ${this.PRICE_CACHE_TIMEOUT_MILLS} ms`);
19
+ }
20
+ getTokenPrice(tokenAddress) {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ const now = Date.now();
23
+ const cachedData = this.tokenPriceCache.get(tokenAddress);
24
+ if (cachedData && (now - cachedData.timestamp) < this.PRICE_CACHE_TIMEOUT_MILLS) {
25
+ (0, dist_1.log_debug)(`use cached token price: ${tokenAddress}, price: ${cachedData.price}`, '');
26
+ return cachedData;
27
+ }
28
+ const priceMap = yield (0, dist_1.get_solana_token_price_info)([tokenAddress]);
29
+ const tokenPrice = priceMap.get(tokenAddress);
30
+ if (!tokenPrice || !tokenPrice.price || Number(tokenPrice.price) <= 0) {
31
+ throw new Error(`无法获取代币 ${tokenAddress} 的有效USD价格`);
32
+ }
33
+ const newPrice = { price: tokenPrice.price, timestamp: now };
34
+ this.tokenPriceCache.set(tokenAddress, newPrice);
35
+ return newPrice;
36
+ });
37
+ }
38
+ }
39
+ exports.TokenPriceCache = TokenPriceCache;
@@ -0,0 +1,11 @@
1
+ export interface SolanaPoolAccountUpdateData {
2
+ recv_ms: number;
3
+ slot: number;
4
+ writeVersion: number;
5
+ transactionHash: string;
6
+ dexId: string;
7
+ pair: string;
8
+ poolAddress: string;
9
+ poolName?: string;
10
+ accountData?: Buffer | string;
11
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,32 +1,33 @@
1
1
  {
2
- "name": "@clonegod/ttd-sol-common",
3
- "version": "2.0.0",
4
- "description": "",
5
- "main": "dist/index.js",
6
- "types": "types/index.d.ts",
7
- "keywords": [],
8
- "author": "",
9
- "license": "ISC",
10
- "scripts": {
11
- "clean": "rm -rf dist node_modules",
12
- "build": "npx tsc --outDir ./dist",
13
- "push": "npm run build && npm publish"
14
- },
15
- "dependencies": {
16
- "@clonegod/ttd-core": "2.1.0",
17
- "@solana/web3.js": "1.91.6",
18
- "rpc-websockets": "7.10.0",
19
- "axios": "^1.2.3",
20
- "bn.js": "^4.12.1",
21
- "bs58": "^6.0.0"
22
- },
23
- "devDependencies": {
24
- "@types/node": "^22.7.9",
25
- "ts-node": "^10.9.2",
26
- "typescript": "^5.3.3"
27
- },
28
- "overrides": {},
29
- "publishConfig": {
30
- "access": "public"
31
- }
32
- }
2
+ "name": "@clonegod/ttd-sol-common",
3
+ "version": "2.0.2",
4
+ "description": "",
5
+ "main": "dist/index.js",
6
+ "types": "types/index.d.ts",
7
+ "keywords": [],
8
+ "author": "",
9
+ "license": "ISC",
10
+ "scripts": {
11
+ "clean": "rm -rf dist node_modules",
12
+ "build": "npx tsc --outDir ./dist",
13
+ "push": "npm run build && npm publish"
14
+ },
15
+ "dependencies": {
16
+ "@clonegod/ttd-core": "2.1.3",
17
+ "@solana/web3.js": "1.91.6",
18
+ "rpc-websockets": "7.10.0",
19
+ "axios": "^1.2.3",
20
+ "bn.js": "^4.12.1",
21
+ "bs58": "^6.0.0",
22
+ "helius-laserstream": "^0.2.7"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "^22.7.9",
26
+ "ts-node": "^10.9.2",
27
+ "typescript": "^5.3.3"
28
+ },
29
+ "overrides": {},
30
+ "publishConfig": {
31
+ "access": "public"
32
+ }
33
+ }
package/src/index.ts CHANGED
@@ -0,0 +1 @@
1
+ export * from './quote'
@@ -0,0 +1 @@
1
+ export * from './pricing'
@@ -0,0 +1 @@
1
+ export * from './token_price_cache'
@@ -0,0 +1,48 @@
1
+ import { get_solana_token_price_info, log_debug, log_info } from "@clonegod/ttd-core/dist";
2
+
3
+ /**
4
+ * 代币价格管理器
5
+ * 负责获取和缓存代币价格
6
+ */
7
+ export class TokenPriceCache {
8
+ // 代币相对美元(USD)的市场价格-缓存
9
+ private tokenPriceCache: Map<string, { price: string, timestamp: number }> = new Map();
10
+ private readonly PRICE_CACHE_TIMEOUT_MILLS: number;
11
+
12
+ constructor() {
13
+ this.PRICE_CACHE_TIMEOUT_MILLS = parseInt(process.env.PRICE_CACHE_TIMEOUT_MILLS || Number(1000 * 60 * 60 * 1).toString());
14
+ log_info(`代币价格缓存超时时间: ${this.PRICE_CACHE_TIMEOUT_MILLS} ms`);
15
+ }
16
+
17
+ /**
18
+ * 获取代币价格,优先使用缓存
19
+ * @param tokenAddress 代币地址
20
+ * @returns 代币价格信息
21
+ */
22
+ public async getTokenPrice(tokenAddress: string): Promise<{ price: string, timestamp: number }> {
23
+ const now = Date.now();
24
+
25
+ // 检查缓存
26
+ const cachedData = this.tokenPriceCache.get(tokenAddress);
27
+ if (cachedData && (now - cachedData.timestamp) < this.PRICE_CACHE_TIMEOUT_MILLS) {
28
+ log_debug(`use cached token price: ${tokenAddress}, price: ${cachedData.price}`, '');
29
+ return cachedData;
30
+ }
31
+
32
+ // 缓存不存在或已过期,请求最新价格
33
+ // log_info(`获取代币${tokenAddress}的最新价格`, '');
34
+ const priceMap = await get_solana_token_price_info([tokenAddress]);
35
+ const tokenPrice = priceMap.get(tokenAddress);
36
+
37
+ if (!tokenPrice || !tokenPrice.price || Number(tokenPrice.price) <= 0) {
38
+ throw new Error(`无法获取代币 ${tokenAddress} 的有效USD价格`);
39
+ }
40
+
41
+ // 更新缓存
42
+ const newPrice = { price: tokenPrice.price, timestamp: now };
43
+ this.tokenPriceCache.set(tokenAddress, newPrice);
44
+
45
+ return newPrice;
46
+ }
47
+
48
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Solana 池子账户更新事件数据结构
3
+ */
4
+ export interface SolanaPoolAccountUpdateData {
5
+ recv_ms: number; // 接收时间戳(毫秒)
6
+
7
+ // 公共字段
8
+ slot: number; // Solana slot 号
9
+ writeVersion: number; // 账户写入版本
10
+ transactionHash: string; // 交易哈希
11
+
12
+ // 池子信息
13
+ dexId: string; // DEX ID
14
+ pair: string; // 交易对名称
15
+ poolAddress: string; // 池子地址
16
+ poolName?: string; // 池子名称
17
+
18
+ // 账户数据(原始数据,由客户端解析)
19
+ accountData?: Buffer | string; // 账户原始数据
20
+ }
21
+