@clonegod/ttd-sui-common 1.0.34 → 1.0.36
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 +1 -0
- package/dist/trade/abstract_sui_dex_trade_plus.d.ts +32 -0
- package/dist/trade/abstract_sui_dex_trade_plus.js +216 -0
- package/dist/trade/index.d.ts +1 -0
- package/dist/trade/index.js +1 -0
- package/dist/ttd-sui-common/src/constants/index.d.ts +4 -0
- package/dist/ttd-sui-common/src/constants/index.js +8 -0
- package/dist/ttd-sui-common/src/grpc/gas-price-cache.d.ts +21 -0
- package/dist/ttd-sui-common/src/grpc/gas-price-cache.js +83 -0
- package/dist/ttd-sui-common/src/grpc/grpc-connection.d.ts +13 -0
- package/dist/ttd-sui-common/src/grpc/grpc-connection.js +99 -0
- package/dist/ttd-sui-common/src/grpc/index.d.ts +7 -0
- package/dist/ttd-sui-common/src/grpc/index.js +17 -0
- package/dist/ttd-sui-common/src/grpc/ledger-service.d.ts +12 -0
- package/dist/ttd-sui-common/src/grpc/ledger-service.js +161 -0
- package/dist/ttd-sui-common/src/grpc/live-data-service.d.ts +10 -0
- package/dist/ttd-sui-common/src/grpc/live-data-service.js +107 -0
- package/dist/ttd-sui-common/src/grpc/subscription-service.d.ts +7 -0
- package/dist/ttd-sui-common/src/grpc/subscription-service.js +69 -0
- package/dist/ttd-sui-common/src/grpc/sui-grpc-client.d.ts +16 -0
- package/dist/ttd-sui-common/src/grpc/sui-grpc-client.js +38 -0
- package/dist/ttd-sui-common/src/grpc/transaction-service.d.ts +7 -0
- package/dist/ttd-sui-common/src/grpc/transaction-service.js +49 -0
- package/dist/ttd-sui-common/src/index.d.ts +9 -0
- package/dist/ttd-sui-common/src/index.js +25 -0
- package/dist/ttd-sui-common/src/quote/index.d.ts +1 -0
- package/dist/ttd-sui-common/src/quote/index.js +17 -0
- package/dist/ttd-sui-common/src/quote/pricing/index.d.ts +1 -0
- package/dist/ttd-sui-common/src/quote/pricing/index.js +17 -0
- package/dist/ttd-sui-common/src/quote/pricing/token_price_cache.d.ts +9 -0
- package/dist/ttd-sui-common/src/quote/pricing/token_price_cache.js +42 -0
- package/dist/ttd-sui-common/src/redis/index.d.ts +1 -0
- package/dist/ttd-sui-common/src/redis/index.js +17 -0
- package/dist/ttd-sui-common/src/redis/redis_client.d.ts +21 -0
- package/dist/ttd-sui-common/src/redis/redis_client.js +155 -0
- package/dist/ttd-sui-common/src/test/test.d.ts +1 -0
- package/dist/ttd-sui-common/src/test/test.js +126 -0
- package/dist/ttd-sui-common/src/test/test_checkpoint.d.ts +1 -0
- package/dist/ttd-sui-common/src/test/test_checkpoint.js +64 -0
- package/dist/ttd-sui-common/src/test/test_grpc.d.ts +1 -0
- package/dist/ttd-sui-common/src/test/test_grpc.js +84 -0
- package/dist/ttd-sui-common/src/trade/abstract_sui_dex_trade_plus.d.ts +32 -0
- package/dist/ttd-sui-common/src/trade/abstract_sui_dex_trade_plus.js +216 -0
- package/dist/ttd-sui-common/src/trade/check/index.d.ts +1 -0
- package/dist/ttd-sui-common/src/trade/check/index.js +5 -0
- package/dist/ttd-sui-common/src/trade/check/tx_result_checker.d.ts +13 -0
- package/dist/ttd-sui-common/src/trade/check/tx_result_checker.js +111 -0
- package/dist/ttd-sui-common/src/trade/index.d.ts +4 -0
- package/dist/ttd-sui-common/src/trade/index.js +20 -0
- package/dist/ttd-sui-common/src/trade/parse/index.d.ts +1 -0
- package/dist/ttd-sui-common/src/trade/parse/index.js +5 -0
- package/dist/ttd-sui-common/src/trade/parse/sui_tx_parser.d.ts +13 -0
- package/dist/ttd-sui-common/src/trade/parse/sui_tx_parser.js +167 -0
- package/dist/ttd-sui-common/src/trade/send_tx/index.d.ts +10 -0
- package/dist/ttd-sui-common/src/trade/send_tx/index.js +48 -0
- package/dist/ttd-sui-common/src/trade/test/test_parse_sui_tx_result.d.ts +1 -0
- package/dist/ttd-sui-common/src/trade/test/test_parse_sui_tx_result.js +105 -0
- package/dist/ttd-sui-common/src/type/index.d.ts +18 -0
- package/dist/ttd-sui-common/src/type/index.js +2 -0
- package/dist/ttd-sui-common/src/utils/checkpoint_parse.d.ts +0 -0
- package/dist/ttd-sui-common/src/utils/checkpoint_parse.js +0 -0
- package/dist/ttd-sui-common/src/utils/decode.d.ts +2 -0
- package/dist/ttd-sui-common/src/utils/decode.js +43 -0
- package/dist/ttd-sui-common/src/utils/format.d.ts +1 -0
- package/dist/ttd-sui-common/src/utils/format.js +18 -0
- package/dist/ttd-sui-common/src/utils/index.d.ts +2 -0
- package/dist/ttd-sui-common/src/utils/index.js +18 -0
- package/dist/ttd-sui-market-data/src/sui_objects/config_manager.d.ts +22 -0
- package/dist/ttd-sui-market-data/src/sui_objects/config_manager.js +169 -0
- package/dist/ttd-sui-market-data/src/sui_objects/example.d.ts +1 -0
- package/dist/ttd-sui-market-data/src/sui_objects/example.js +72 -0
- package/dist/ttd-sui-market-data/src/sui_objects/index.d.ts +6 -0
- package/dist/ttd-sui-market-data/src/sui_objects/index.js +15 -0
- package/dist/ttd-sui-market-data/src/sui_objects/object_mgt.d.ts +47 -0
- package/dist/ttd-sui-market-data/src/sui_objects/object_mgt.js +483 -0
- package/dist/ttd-sui-market-data/src/sui_objects/types.d.ts +60 -0
- package/dist/ttd-sui-market-data/src/sui_objects/types.js +24 -0
- package/dist/ttd-sui-market-data/src/sui_objects/version_checker.d.ts +30 -0
- package/dist/ttd-sui-market-data/src/sui_objects/version_checker.js +207 -0
- package/package.json +1 -1
|
@@ -0,0 +1,105 @@
|
|
|
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
|
+
require('dotenv').config();
|
|
16
|
+
const fs_1 = __importDefault(require("fs"));
|
|
17
|
+
const sui_tx_parser_1 = require("../parse/sui_tx_parser");
|
|
18
|
+
const index_1 = require("../../index");
|
|
19
|
+
const index_2 = require("../../index");
|
|
20
|
+
function test_get_tx_result() {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
const grpc_endpoint = process.env.SUI_GRPC_ENDPOINT || '';
|
|
23
|
+
const grpc_token = process.env.SUI_GRPC_TOKEN || '';
|
|
24
|
+
const grpcConnection = index_1.GrpcConnection.getInstance(grpc_endpoint, grpc_token);
|
|
25
|
+
const ledgerService = new index_1.LedgerService(grpcConnection);
|
|
26
|
+
let wallet_address = '0x6367c8755b8c39cab7305bfa75cb17d050508d2e55f6862a7682377ad6d46ee7';
|
|
27
|
+
let test_tx_success_buy = {
|
|
28
|
+
txid: '',
|
|
29
|
+
filename: './src/trade/test/receipt_buy_sui.json'
|
|
30
|
+
};
|
|
31
|
+
let test_tx_success_sell = {
|
|
32
|
+
txid: '28FaeTYoctpP1VdWCuyPxNEBeaMm3ebj27kdF5umi9YL',
|
|
33
|
+
filename: './src/trade/test/receipt_sell_sui.json'
|
|
34
|
+
};
|
|
35
|
+
let { txid, filename } = test_tx_success_sell;
|
|
36
|
+
console.log('=== 测试 SUI 链交易结果查询 ===');
|
|
37
|
+
console.log('交易哈希:', txid);
|
|
38
|
+
try {
|
|
39
|
+
const raw_tx_result = yield ledgerService.getTransaction(txid, ['*']);
|
|
40
|
+
console.log('✅ 成功获取交易结果');
|
|
41
|
+
const decoded_tx_result = (0, index_2.decodeBytes)(raw_tx_result);
|
|
42
|
+
fs_1.default.writeFileSync(filename, JSON.stringify(decoded_tx_result, null, 2));
|
|
43
|
+
let poolInfo = get_pool_info();
|
|
44
|
+
const parser = new sui_tx_parser_1.SuiTransactionParser(wallet_address);
|
|
45
|
+
const result = yield parser.parseTransaction(raw_tx_result, poolInfo);
|
|
46
|
+
console.log('解析交易结果:', JSON.stringify(result, null, 2));
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
console.error('❌ 查询失败:', error);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function get_pool_info() {
|
|
54
|
+
return {
|
|
55
|
+
"program_id": "",
|
|
56
|
+
"authority": "",
|
|
57
|
+
"subscribe_type": "grpc",
|
|
58
|
+
"pair": "SUI/USDT",
|
|
59
|
+
"dex_id": "MOMENTUM-CLMM",
|
|
60
|
+
"pool_name": "SUI/USDC",
|
|
61
|
+
"pool_address": "0x455cf8d2ac91e7cb883f515874af750ed3cd18195c970b7a2d46235ac2b0c388",
|
|
62
|
+
"pool_address_hex": "",
|
|
63
|
+
"tokenA": {
|
|
64
|
+
"symbol": "SUI",
|
|
65
|
+
"address": "0x2::sui::SUI",
|
|
66
|
+
"address_hex": "",
|
|
67
|
+
"decimals": 9,
|
|
68
|
+
"name": "Sui",
|
|
69
|
+
"is_token2022": false,
|
|
70
|
+
"market_price": "3.27",
|
|
71
|
+
"update_time": "2025-09-01 20:25:48 469",
|
|
72
|
+
"alias": "",
|
|
73
|
+
"enable": true
|
|
74
|
+
},
|
|
75
|
+
"tokenB": {
|
|
76
|
+
"symbol": "USDC",
|
|
77
|
+
"address": "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
|
|
78
|
+
"address_hex": "",
|
|
79
|
+
"decimals": 6,
|
|
80
|
+
"name": "USDC",
|
|
81
|
+
"is_token2022": false,
|
|
82
|
+
"market_price": "0.9992228892",
|
|
83
|
+
"update_time": "2025-09-01 20:25:48 469",
|
|
84
|
+
"alias": "",
|
|
85
|
+
"enable": true
|
|
86
|
+
},
|
|
87
|
+
"vaultA": "",
|
|
88
|
+
"vaultB": "",
|
|
89
|
+
"router_id": null,
|
|
90
|
+
"fee_rate": 25,
|
|
91
|
+
"quote_token": "USDC",
|
|
92
|
+
"quote_amount_usd": 200,
|
|
93
|
+
"quote_price_decimals": 18,
|
|
94
|
+
"is_reverse_token": false,
|
|
95
|
+
"cu_limit": 200000,
|
|
96
|
+
"tvl": 14160391.2697,
|
|
97
|
+
"vol_24h": 21668306.2082508,
|
|
98
|
+
"update_time": "2025-09-01 20:25:48 899",
|
|
99
|
+
"enable": true,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
if (require.main === module) {
|
|
103
|
+
test_get_tx_result()
|
|
104
|
+
.catch(console.error);
|
|
105
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface BlockUpdateEvent {
|
|
2
|
+
blockHash: string;
|
|
3
|
+
blockNumber: number;
|
|
4
|
+
blockTime: number;
|
|
5
|
+
transactions: TransactionData[];
|
|
6
|
+
}
|
|
7
|
+
export interface TransactionData {
|
|
8
|
+
txHash: string;
|
|
9
|
+
txIndex: number;
|
|
10
|
+
txType: string;
|
|
11
|
+
events: SimpleTxEventsType[];
|
|
12
|
+
}
|
|
13
|
+
export interface SimpleTxEventsType {
|
|
14
|
+
pool_address: string;
|
|
15
|
+
dex_id: string;
|
|
16
|
+
pair: string;
|
|
17
|
+
events: any[];
|
|
18
|
+
}
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.decodeBytes = decodeBytes;
|
|
4
|
+
exports.parseObjectAmount = parseObjectAmount;
|
|
5
|
+
function decodeBytes(obj) {
|
|
6
|
+
if (Array.isArray(obj)) {
|
|
7
|
+
return obj.map((item) => decodeBytes(item));
|
|
8
|
+
}
|
|
9
|
+
else if (obj && typeof obj === 'object') {
|
|
10
|
+
const result = {};
|
|
11
|
+
for (const key of Object.keys(obj)) {
|
|
12
|
+
const val = obj[key];
|
|
13
|
+
if (Buffer.isBuffer(val) || (Array.isArray(val) && typeof val[0] === 'number')) {
|
|
14
|
+
result[key] = Buffer.from(val).toString('hex');
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
result[key] = decodeBytes(val);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
return obj;
|
|
23
|
+
}
|
|
24
|
+
function parseObjectAmount(objectResponse) {
|
|
25
|
+
var _a, _b;
|
|
26
|
+
try {
|
|
27
|
+
if (!((_b = (_a = objectResponse === null || objectResponse === void 0 ? void 0 : objectResponse.object) === null || _a === void 0 ? void 0 : _a.contents) === null || _b === void 0 ? void 0 : _b.value)) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const contentsValue = objectResponse.object.contents.value;
|
|
31
|
+
if (contentsValue.length < 80) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const balanceHex = contentsValue.substring(64, 80);
|
|
35
|
+
const balanceBytes = Buffer.from(balanceHex, 'hex');
|
|
36
|
+
const balance = balanceBytes.readBigUInt64LE(0).toString();
|
|
37
|
+
return balance;
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.error('提取代币余额失败:', error);
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const normalizeSuiTokenAddress: (address: string, useLongAddress?: boolean) => string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeSuiTokenAddress = void 0;
|
|
4
|
+
const constants_1 = require("../constants");
|
|
5
|
+
const normalizeSuiTokenAddress = (address, useLongAddress = true) => {
|
|
6
|
+
if (useLongAddress) {
|
|
7
|
+
if (address === constants_1.SUI_TOKEN_ADDRESS.SHORT) {
|
|
8
|
+
return constants_1.SUI_TOKEN_ADDRESS.LONG;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
if (address === constants_1.SUI_TOKEN_ADDRESS.LONG) {
|
|
13
|
+
return constants_1.SUI_TOKEN_ADDRESS.SHORT;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return address;
|
|
17
|
+
};
|
|
18
|
+
exports.normalizeSuiTokenAddress = normalizeSuiTokenAddress;
|
|
@@ -0,0 +1,18 @@
|
|
|
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("./decode"), exports);
|
|
18
|
+
__exportStar(require("./format"), exports);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { TokenConfig } from './types';
|
|
2
|
+
export declare class ConfigManager {
|
|
3
|
+
private configs;
|
|
4
|
+
private configPath;
|
|
5
|
+
constructor(configPath?: string);
|
|
6
|
+
private loadConfigFromFile;
|
|
7
|
+
private initializeDefaultConfigs;
|
|
8
|
+
getTokenConfig(tokenAddress: string): TokenConfig;
|
|
9
|
+
addTokenConfig(config: TokenConfig): void;
|
|
10
|
+
updateTokenConfig(tokenAddress: string, updates: Partial<TokenConfig>): void;
|
|
11
|
+
removeTokenConfig(tokenAddress: string): void;
|
|
12
|
+
getAllTokenConfigs(): TokenConfig[];
|
|
13
|
+
getGasTokenConfigs(): TokenConfig[];
|
|
14
|
+
getNonGasTokenConfigs(): TokenConfig[];
|
|
15
|
+
needsMaintenance(tokenAddress: string, availableCount: number): {
|
|
16
|
+
needsSplit: boolean;
|
|
17
|
+
needsMerge: boolean;
|
|
18
|
+
reason: string;
|
|
19
|
+
};
|
|
20
|
+
private extractTokenSymbol;
|
|
21
|
+
printAllConfigs(): void;
|
|
22
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConfigManager = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
class ConfigManager {
|
|
7
|
+
constructor(configPath) {
|
|
8
|
+
this.configs = new Map();
|
|
9
|
+
this.configPath = configPath || (0, path_1.join)(__dirname, 'sui_objects_config.json');
|
|
10
|
+
this.loadConfigFromFile();
|
|
11
|
+
}
|
|
12
|
+
loadConfigFromFile() {
|
|
13
|
+
try {
|
|
14
|
+
const rawData = (0, fs_1.readFileSync)(this.configPath, 'utf-8');
|
|
15
|
+
const configData = JSON.parse(rawData);
|
|
16
|
+
for (const [tokenAddress, config] of Object.entries(configData.token_configs)) {
|
|
17
|
+
this.configs.set(tokenAddress, config);
|
|
18
|
+
}
|
|
19
|
+
console.log(`✅ 从配置文件加载了 ${this.configs.size} 个代币配置`);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
console.error(`❌ 加载配置文件失败: ${this.configPath}`, error);
|
|
23
|
+
console.log('🔄 使用默认配置');
|
|
24
|
+
this.initializeDefaultConfigs();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
initializeDefaultConfigs() {
|
|
28
|
+
this.configs.set('0x2::sui::SUI', {
|
|
29
|
+
address: '0x2::sui::SUI',
|
|
30
|
+
symbol: 'SUI',
|
|
31
|
+
min_objects: 3,
|
|
32
|
+
max_objects: 8,
|
|
33
|
+
target_objects: 5,
|
|
34
|
+
min_balance_per_object: '1000000000',
|
|
35
|
+
max_balance_per_object: '100000000000',
|
|
36
|
+
split_threshold: '10000000000',
|
|
37
|
+
merge_threshold: '1000000000',
|
|
38
|
+
priority: 1,
|
|
39
|
+
is_gas_token: true
|
|
40
|
+
});
|
|
41
|
+
this.configs.set('0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf', {
|
|
42
|
+
address: '0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf',
|
|
43
|
+
symbol: 'USDC',
|
|
44
|
+
min_objects: 3,
|
|
45
|
+
max_objects: 8,
|
|
46
|
+
target_objects: 5,
|
|
47
|
+
min_balance_per_object: '100000000',
|
|
48
|
+
max_balance_per_object: '10000000000',
|
|
49
|
+
split_threshold: '1000000000',
|
|
50
|
+
merge_threshold: '100000000',
|
|
51
|
+
priority: 2,
|
|
52
|
+
is_gas_token: false
|
|
53
|
+
});
|
|
54
|
+
this.configs.set('0xc060006111016b8a020ad5b33834984a437aaa7d3c74c18e09a95d48aceab08c', {
|
|
55
|
+
address: '0xc060006111016b8a020ad5b33834984a437aaa7d3c74c18e09a95d48aceab08c',
|
|
56
|
+
symbol: 'USDT',
|
|
57
|
+
min_objects: 3,
|
|
58
|
+
max_objects: 8,
|
|
59
|
+
target_objects: 5,
|
|
60
|
+
min_balance_per_object: '100000000',
|
|
61
|
+
max_balance_per_object: '10000000000',
|
|
62
|
+
split_threshold: '1000000000',
|
|
63
|
+
merge_threshold: '100000000',
|
|
64
|
+
priority: 2,
|
|
65
|
+
is_gas_token: false
|
|
66
|
+
});
|
|
67
|
+
this.configs.set('default', {
|
|
68
|
+
address: 'default',
|
|
69
|
+
symbol: 'OTHER',
|
|
70
|
+
min_objects: 2,
|
|
71
|
+
max_objects: 5,
|
|
72
|
+
target_objects: 3,
|
|
73
|
+
min_balance_per_object: '100000000',
|
|
74
|
+
max_balance_per_object: '10000000000',
|
|
75
|
+
split_threshold: '1000000000',
|
|
76
|
+
merge_threshold: '100000000',
|
|
77
|
+
priority: 3,
|
|
78
|
+
is_gas_token: false
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
getTokenConfig(tokenAddress) {
|
|
82
|
+
const config = this.configs.get(tokenAddress);
|
|
83
|
+
if (config) {
|
|
84
|
+
return config;
|
|
85
|
+
}
|
|
86
|
+
const defaultConfig = this.configs.get('default');
|
|
87
|
+
return Object.assign(Object.assign({}, defaultConfig), { address: tokenAddress, symbol: this.extractTokenSymbol(tokenAddress) });
|
|
88
|
+
}
|
|
89
|
+
addTokenConfig(config) {
|
|
90
|
+
this.configs.set(config.address, config);
|
|
91
|
+
console.log(`✅ 添加代币配置: ${config.symbol} (${config.address})`);
|
|
92
|
+
}
|
|
93
|
+
updateTokenConfig(tokenAddress, updates) {
|
|
94
|
+
const existingConfig = this.configs.get(tokenAddress);
|
|
95
|
+
if (existingConfig) {
|
|
96
|
+
const updatedConfig = Object.assign(Object.assign({}, existingConfig), updates);
|
|
97
|
+
this.configs.set(tokenAddress, updatedConfig);
|
|
98
|
+
console.log(`✅ 更新代币配置: ${updatedConfig.symbol} (${tokenAddress})`);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
console.log(`⚠️ 代币配置不存在: ${tokenAddress}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
removeTokenConfig(tokenAddress) {
|
|
105
|
+
if (this.configs.has(tokenAddress)) {
|
|
106
|
+
this.configs.delete(tokenAddress);
|
|
107
|
+
console.log(`✅ 删除代币配置: ${tokenAddress}`);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
console.log(`⚠️ 代币配置不存在: ${tokenAddress}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
getAllTokenConfigs() {
|
|
114
|
+
return Array.from(this.configs.values()).filter(config => config.address !== 'default');
|
|
115
|
+
}
|
|
116
|
+
getGasTokenConfigs() {
|
|
117
|
+
return Array.from(this.configs.values()).filter(config => config.is_gas_token);
|
|
118
|
+
}
|
|
119
|
+
getNonGasTokenConfigs() {
|
|
120
|
+
return Array.from(this.configs.values()).filter(config => !config.is_gas_token && config.address !== 'default');
|
|
121
|
+
}
|
|
122
|
+
needsMaintenance(tokenAddress, availableCount) {
|
|
123
|
+
const config = this.getTokenConfig(tokenAddress);
|
|
124
|
+
if (availableCount < config.min_objects) {
|
|
125
|
+
return {
|
|
126
|
+
needsSplit: true,
|
|
127
|
+
needsMerge: false,
|
|
128
|
+
reason: `对象数量不足: ${availableCount}/${config.min_objects}`
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
if (availableCount > config.max_objects) {
|
|
132
|
+
return {
|
|
133
|
+
needsSplit: false,
|
|
134
|
+
needsMerge: true,
|
|
135
|
+
reason: `对象数量过多: ${availableCount}/${config.max_objects}`
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
needsSplit: false,
|
|
140
|
+
needsMerge: false,
|
|
141
|
+
reason: '对象数量正常'
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
extractTokenSymbol(tokenAddress) {
|
|
145
|
+
if (tokenAddress.includes('sui'))
|
|
146
|
+
return 'SUI';
|
|
147
|
+
if (tokenAddress.includes('usdc'))
|
|
148
|
+
return 'USDC';
|
|
149
|
+
if (tokenAddress.includes('usdt'))
|
|
150
|
+
return 'USDT';
|
|
151
|
+
return tokenAddress.slice(-8).toUpperCase();
|
|
152
|
+
}
|
|
153
|
+
printAllConfigs() {
|
|
154
|
+
console.log('\n📋 代币配置信息:');
|
|
155
|
+
const allConfigs = this.getAllTokenConfigs();
|
|
156
|
+
allConfigs.sort((a, b) => a.priority - b.priority);
|
|
157
|
+
for (const config of allConfigs) {
|
|
158
|
+
const gasInfo = config.is_gas_token ? ' (Gas代币)' : '';
|
|
159
|
+
console.log(`\n 🪙 ${config.symbol}${gasInfo}`);
|
|
160
|
+
console.log(` 地址: ${config.address}`);
|
|
161
|
+
console.log(` 对象配置: ${config.min_objects}-${config.max_objects} (目标: ${config.target_objects})`);
|
|
162
|
+
console.log(` 拆分阈值: ${config.split_threshold}`);
|
|
163
|
+
console.log(` 合并阈值: ${config.merge_threshold}`);
|
|
164
|
+
console.log(` 优先级: ${config.priority}`);
|
|
165
|
+
}
|
|
166
|
+
console.log('');
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.ConfigManager = ConfigManager;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
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
|
+
const dist_1 = require("@clonegod/ttd-core/dist");
|
|
13
|
+
const object_mgt_1 = require("./object_mgt");
|
|
14
|
+
function example() {
|
|
15
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
const appConfig = new dist_1.AppConfig();
|
|
17
|
+
const groupId = 'test_group';
|
|
18
|
+
const walletAddress = '0x1234567890abcdef...';
|
|
19
|
+
const manager = new object_mgt_1.SuiWalletObjectsManagement(appConfig, groupId, walletAddress);
|
|
20
|
+
yield manager.init();
|
|
21
|
+
const tokenAddress = '0x2::sui::SUI';
|
|
22
|
+
const chainObjects = yield manager.queryTokenObjectsFromChain(tokenAddress);
|
|
23
|
+
console.log(`从链上查询到 ${chainObjects.length} 个对象`);
|
|
24
|
+
const requiredAmount = BigInt('1000000000');
|
|
25
|
+
const transactionHash = '0xabcdef123456...';
|
|
26
|
+
const allocatedObject = yield manager.allocateObjectForTrade(tokenAddress, requiredAmount, transactionHash);
|
|
27
|
+
if (allocatedObject) {
|
|
28
|
+
console.log(`✅ 成功分配对象: ${allocatedObject.object_id}`);
|
|
29
|
+
console.log(` 余额: ${allocatedObject.balance}`);
|
|
30
|
+
console.log(` 版本: ${allocatedObject.version}`);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
console.log('❌ 对象分配失败');
|
|
34
|
+
}
|
|
35
|
+
yield manager.printPoolStatus(tokenAddress);
|
|
36
|
+
yield manager.performSplitMaintenance(tokenAddress);
|
|
37
|
+
yield manager.performMergeMaintenance(tokenAddress);
|
|
38
|
+
const stats = yield manager.getPoolStats(tokenAddress);
|
|
39
|
+
console.log('对象池统计:', stats);
|
|
40
|
+
manager.configManager.printAllConfigs();
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function configExample() {
|
|
44
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
const appConfig = new dist_1.AppConfig();
|
|
46
|
+
const groupId = 'test_group';
|
|
47
|
+
const walletAddress = '0x1234567890abcdef...';
|
|
48
|
+
const manager = new object_mgt_1.SuiWalletObjectsManagement(appConfig, groupId, walletAddress);
|
|
49
|
+
console.log('=== 当前配置 ===');
|
|
50
|
+
manager.configManager.printAllConfigs();
|
|
51
|
+
manager.configManager.addTokenConfig({
|
|
52
|
+
address: '0x...NEW_TOKEN',
|
|
53
|
+
symbol: 'NEW',
|
|
54
|
+
min_objects: 2,
|
|
55
|
+
max_objects: 6,
|
|
56
|
+
target_objects: 4,
|
|
57
|
+
min_balance_per_object: '500000000',
|
|
58
|
+
max_balance_per_object: '5000000000',
|
|
59
|
+
split_threshold: '5000000000',
|
|
60
|
+
merge_threshold: '500000000',
|
|
61
|
+
priority: 4,
|
|
62
|
+
is_gas_token: false
|
|
63
|
+
});
|
|
64
|
+
manager.configManager.updateTokenConfig('0x2::sui::SUI', {
|
|
65
|
+
min_objects: 5,
|
|
66
|
+
max_objects: 10,
|
|
67
|
+
target_objects: 7
|
|
68
|
+
});
|
|
69
|
+
const maintenanceCheck = manager.configManager.needsMaintenance('0x2::sui::SUI', 3);
|
|
70
|
+
console.log('维护检查结果:', maintenanceCheck);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { SuiWalletObjectsManagement } from './object_mgt';
|
|
2
|
+
export { ObjectVersionChecker } from './version_checker';
|
|
3
|
+
export { ConfigManager } from './config_manager';
|
|
4
|
+
export { SuiWalletObjectsManagement as WalletObjectManager, } from './object_mgt';
|
|
5
|
+
export type { ObjectInfo, PoolStats, TokenConfig, MaintenanceTask, ObjectEvent } from './types';
|
|
6
|
+
export { ObjectStatus, MaintenanceType, ObjectEventType } from './types';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ObjectEventType = exports.MaintenanceType = exports.ObjectStatus = exports.WalletObjectManager = exports.ConfigManager = exports.ObjectVersionChecker = exports.SuiWalletObjectsManagement = void 0;
|
|
4
|
+
var object_mgt_1 = require("./object_mgt");
|
|
5
|
+
Object.defineProperty(exports, "SuiWalletObjectsManagement", { enumerable: true, get: function () { return object_mgt_1.SuiWalletObjectsManagement; } });
|
|
6
|
+
var version_checker_1 = require("./version_checker");
|
|
7
|
+
Object.defineProperty(exports, "ObjectVersionChecker", { enumerable: true, get: function () { return version_checker_1.ObjectVersionChecker; } });
|
|
8
|
+
var config_manager_1 = require("./config_manager");
|
|
9
|
+
Object.defineProperty(exports, "ConfigManager", { enumerable: true, get: function () { return config_manager_1.ConfigManager; } });
|
|
10
|
+
var object_mgt_2 = require("./object_mgt");
|
|
11
|
+
Object.defineProperty(exports, "WalletObjectManager", { enumerable: true, get: function () { return object_mgt_2.SuiWalletObjectsManagement; } });
|
|
12
|
+
var types_1 = require("./types");
|
|
13
|
+
Object.defineProperty(exports, "ObjectStatus", { enumerable: true, get: function () { return types_1.ObjectStatus; } });
|
|
14
|
+
Object.defineProperty(exports, "MaintenanceType", { enumerable: true, get: function () { return types_1.MaintenanceType; } });
|
|
15
|
+
Object.defineProperty(exports, "ObjectEventType", { enumerable: true, get: function () { return types_1.ObjectEventType; } });
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { StandardTokenInfoType } from "@clonegod/ttd-core";
|
|
2
|
+
import { AppConfig } from "@clonegod/ttd-core/dist";
|
|
3
|
+
import { SuiGrpcClient } from "../../../ttd-sui-common/src/grpc";
|
|
4
|
+
import { SimpleRedisClient } from "../../../ttd-sui-common/src/redis";
|
|
5
|
+
import { ConfigManager } from './config_manager';
|
|
6
|
+
import { ObjectInfo, PoolStats } from './types';
|
|
7
|
+
import { ObjectVersionChecker } from './version_checker';
|
|
8
|
+
export declare class SuiWalletObjectsManagement {
|
|
9
|
+
appConfig: AppConfig;
|
|
10
|
+
group_id: string;
|
|
11
|
+
wallet_address: string;
|
|
12
|
+
grpcClient: SuiGrpcClient;
|
|
13
|
+
redisClient: SimpleRedisClient;
|
|
14
|
+
versionChecker: ObjectVersionChecker;
|
|
15
|
+
configManager: ConfigManager;
|
|
16
|
+
token_list: StandardTokenInfoType[];
|
|
17
|
+
constructor(appConfig: AppConfig, group_id: string, wallet_address: string);
|
|
18
|
+
init(): Promise<void>;
|
|
19
|
+
init_trade_tokens(): Promise<void>;
|
|
20
|
+
queryTokenObjectsFromChain(tokenAddress: string): Promise<ObjectInfo[]>;
|
|
21
|
+
initializeAllObjectPools(): Promise<void>;
|
|
22
|
+
initializeObjectPool(tokenAddress: string): Promise<void>;
|
|
23
|
+
allocateObjectForTrade(tokenAddress: string, requiredAmount: bigint, transactionHash: string): Promise<ObjectInfo | null>;
|
|
24
|
+
performMaintenance(tokenAddress: string, type?: 'split' | 'merge' | 'auto'): Promise<void>;
|
|
25
|
+
printPoolStatus(tokenAddress: string): Promise<void>;
|
|
26
|
+
private allocateObject;
|
|
27
|
+
releaseObject(tokenAddress: string, objectId: string): Promise<void>;
|
|
28
|
+
private poolOperation;
|
|
29
|
+
private storeObjectsToRedis;
|
|
30
|
+
private getObjectsFromRedis;
|
|
31
|
+
private getAvailableObjects;
|
|
32
|
+
private updateObjectStatus;
|
|
33
|
+
private updatePoolStats;
|
|
34
|
+
getPoolStats(tokenAddress: string): Promise<PoolStats | null>;
|
|
35
|
+
private splitObject;
|
|
36
|
+
private mergeObjects;
|
|
37
|
+
private objectPoolOperation;
|
|
38
|
+
private removeObjectFromPool;
|
|
39
|
+
private addObjectToPool;
|
|
40
|
+
private executeSplitTransaction;
|
|
41
|
+
private executeMergeTransaction;
|
|
42
|
+
grpcQuery(operation: 'listOwnedObjects' | 'getBalance' | 'listBalances' | 'getCoinInfo', coin_type?: string): Promise<any>;
|
|
43
|
+
listOwnedObjects(coin_type: string): Promise<any>;
|
|
44
|
+
getBalance(coin_type: string): Promise<any>;
|
|
45
|
+
listBalances(): Promise<any>;
|
|
46
|
+
getCoinInfo(coin_type: string): Promise<any>;
|
|
47
|
+
}
|