@clonegod/ttd-sol-common 2.0.0 → 2.0.1
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 +1 -0
- package/dist/index.js +17 -0
- package/dist/quote/index.d.ts +1 -0
- package/dist/quote/index.js +17 -0
- package/dist/quote/pricing/index.d.ts +1 -0
- package/dist/quote/pricing/index.js +17 -0
- package/dist/quote/pricing/token_price_cache.d.ts +9 -0
- package/dist/quote/pricing/token_price_cache.js +39 -0
- package/package.json +31 -31
- package/src/index.ts +1 -0
- package/src/quote/index.ts +1 -0
- package/src/quote/pricing/index.ts +1 -0
- package/src/quote/pricing/token_price_cache.ts +48 -0
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,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;
|
package/package.json
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
2
|
+
"name": "@clonegod/ttd-sol-common",
|
|
3
|
+
"version": "2.0.1",
|
|
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.2",
|
|
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
|
+
}
|
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
|
+
}
|