@clonegod/ttd-sui-common 1.0.101 → 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/appconfig/SuiQuoteAppConfig.d.ts +10 -0
- package/dist/appconfig/SuiQuoteAppConfig.js +35 -0
- package/dist/appconfig/SuiTradeAppConfig.d.ts +7 -0
- package/dist/appconfig/SuiTradeAppConfig.js +13 -0
- package/dist/appconfig/ensure_core_env.d.ts +1 -0
- package/dist/appconfig/ensure_core_env.js +18 -0
- package/dist/appconfig/index.d.ts +5 -0
- package/dist/appconfig/index.js +21 -0
- package/dist/appconfig/sui_dex_env_args.d.ts +5 -0
- package/dist/appconfig/sui_dex_env_args.js +28 -0
- package/dist/appconfig/sui_env_args.d.ts +4 -0
- package/dist/appconfig/sui_env_args.js +20 -0
- package/dist/grpc/gas-price-cache.js +19 -32
- package/dist/grpc/grpc-connection.js +5 -3
- package/dist/grpc/grpc_provider_registry.d.ts +14 -0
- package/dist/grpc/grpc_provider_registry.js +60 -0
- package/dist/grpc/index.d.ts +3 -0
- package/dist/grpc/index.js +13 -1
- package/dist/grpc/ledger-service.js +107 -128
- package/dist/grpc/proto_value.d.ts +4 -0
- package/dist/grpc/proto_value.js +59 -0
- package/dist/grpc/state-service.d.ts +1 -0
- package/dist/grpc/state-service.js +99 -102
- package/dist/grpc/sui-grpc-client.js +2 -13
- package/dist/grpc/sui_object_reader.d.ts +15 -0
- package/dist/grpc/sui_object_reader.js +60 -0
- package/dist/grpc/transaction-service.js +26 -37
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/quote/abstract_dex_quote.d.ts +60 -0
- package/dist/quote/abstract_dex_quote.js +186 -0
- package/dist/quote/chain_ops.d.ts +17 -0
- package/dist/quote/chain_ops.js +52 -0
- package/dist/quote/index.d.ts +7 -0
- package/dist/quote/index.js +7 -0
- package/dist/quote/pool_event.d.ts +21 -0
- package/dist/quote/pool_event.js +6 -0
- package/dist/quote/pricing/token_price_cache.js +18 -29
- package/dist/quote/quote_amount.d.ts +4 -0
- package/dist/quote/quote_amount.js +24 -0
- package/dist/quote/quote_trace.d.ts +16 -0
- package/dist/quote/quote_trace.js +40 -0
- package/dist/quote/tick/clmm_v3_engine.d.ts +32 -0
- package/dist/quote/tick/clmm_v3_engine.js +48 -0
- package/dist/quote/tick/index.d.ts +4 -0
- package/dist/quote/tick/index.js +20 -0
- package/dist/quote/tick/local_clmm_state.d.ts +17 -0
- package/dist/quote/tick/local_clmm_state.js +22 -0
- package/dist/quote/tick/sui_clmm_tick_cache.d.ts +42 -0
- package/dist/quote/tick/sui_clmm_tick_cache.js +163 -0
- package/dist/quote/tick/sui_tick_data_provider.d.ts +2 -0
- package/dist/quote/tick/sui_tick_data_provider.js +6 -0
- package/dist/quote/verify/index.d.ts +1 -0
- package/dist/quote/verify/index.js +17 -0
- package/dist/quote/verify/quote_price_verify.d.ts +30 -0
- package/dist/quote/verify/quote_price_verify.js +247 -0
- package/dist/redis/redis_client.d.ts +1 -0
- package/dist/redis/redis_client.js +88 -117
- package/dist/rpc/index.js +59 -75
- package/dist/test/test.js +1 -1
- package/dist/test/test_checkpoint.js +4 -13
- package/dist/test/test_grpc.js +32 -41
- package/dist/trade/abstract_sui_dex_trade.d.ts +43 -0
- package/dist/trade/abstract_sui_dex_trade.js +380 -0
- package/dist/trade/abstract_sui_dex_trade_plus.d.ts +3 -1
- package/dist/trade/abstract_sui_dex_trade_plus.js +232 -212
- package/dist/trade/check/tx_result_checker.js +65 -75
- package/dist/trade/coin/index.d.ts +1 -0
- package/dist/trade/coin/index.js +17 -0
- package/dist/trade/coin/lua_scripts.d.ts +5 -0
- package/dist/trade/coin/lua_scripts.js +130 -0
- package/dist/trade/coin/types.d.ts +30 -0
- package/dist/trade/coin/types.js +2 -0
- package/dist/trade/coin/wallet_coin_ledger.d.ts +22 -0
- package/dist/trade/coin/wallet_coin_ledger.js +85 -0
- package/dist/trade/executor/central_executor.d.ts +72 -0
- package/dist/trade/executor/central_executor.js +240 -0
- package/dist/trade/executor/coin_cache.d.ts +21 -0
- package/dist/trade/executor/coin_cache.js +143 -0
- package/dist/trade/executor/coin_maintainer.d.ts +32 -0
- package/dist/trade/executor/coin_maintainer.js +123 -0
- package/dist/trade/executor/core_channel.d.ts +38 -0
- package/dist/trade/executor/core_channel.js +131 -0
- package/dist/trade/executor/data_channel.d.ts +27 -0
- package/dist/trade/executor/data_channel.js +2 -0
- package/dist/trade/executor/effects.d.ts +16 -0
- package/dist/trade/executor/effects.js +63 -0
- package/dist/trade/executor/executor_client.d.ts +13 -0
- package/dist/trade/executor/executor_client.js +55 -0
- package/dist/trade/executor/executor_protocol.d.ts +26 -0
- package/dist/trade/executor/executor_protocol.js +32 -0
- package/dist/trade/executor/executor_server.d.ts +8 -0
- package/dist/trade/executor/executor_server.js +33 -0
- package/dist/trade/executor/executor_ws_client.d.ts +13 -0
- package/dist/trade/executor/executor_ws_client.js +58 -0
- package/dist/trade/executor/grpc_channel.d.ts +14 -0
- package/dist/trade/executor/grpc_channel.js +73 -0
- package/dist/trade/executor/index.d.ts +7 -0
- package/dist/trade/executor/index.js +23 -0
- package/dist/trade/executor/json_rpc_channel.d.ts +14 -0
- package/dist/trade/executor/json_rpc_channel.js +77 -0
- package/dist/trade/index.d.ts +5 -1
- package/dist/trade/index.js +5 -1
- package/dist/trade/parse/sui_tx_parser.js +98 -81
- package/dist/trade/send_tx/index.js +34 -47
- package/dist/trade/swap/builders/bluefin.d.ts +9 -0
- package/dist/trade/swap/builders/bluefin.js +60 -0
- package/dist/trade/swap/builders/cetus_magma.d.ts +13 -0
- package/dist/trade/swap/builders/cetus_magma.js +52 -0
- package/dist/trade/swap/builders/momentum.d.ts +9 -0
- package/dist/trade/swap/builders/momentum.js +80 -0
- package/dist/trade/swap/dex_swap_config.d.ts +28 -0
- package/dist/trade/swap/dex_swap_config.js +40 -0
- package/dist/trade/swap/index.d.ts +7 -0
- package/dist/trade/swap/index.js +36 -0
- package/dist/trade/swap/types.d.ts +20 -0
- package/dist/trade/swap/types.js +2 -0
- package/dist/trade/test/test_parse_sui_tx_result.js +33 -44
- package/dist/trade/tx_result_channel.d.ts +7 -0
- package/dist/trade/tx_result_channel.js +7 -0
- package/dist/utils/decode.js +1 -2
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/trade_direction.d.ts +14 -0
- package/dist/utils/trade_direction.js +23 -0
- package/package.json +3 -2
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JsonRpcDataChannel = void 0;
|
|
4
|
+
const utils_1 = require("@mysten/sui/utils");
|
|
5
|
+
const dist_1 = require("@clonegod/ttd-core/dist");
|
|
6
|
+
class JsonRpcDataChannel {
|
|
7
|
+
constructor(client) {
|
|
8
|
+
this.client = client;
|
|
9
|
+
this.kind = 'jsonrpc';
|
|
10
|
+
}
|
|
11
|
+
async listCoins(owner, coinType) {
|
|
12
|
+
const out = [];
|
|
13
|
+
let cursor = undefined;
|
|
14
|
+
do {
|
|
15
|
+
const page = await this.client.getCoins({ owner, coinType, cursor });
|
|
16
|
+
for (const c of page.data) {
|
|
17
|
+
out.push({ objectId: c.coinObjectId, version: c.version, digest: c.digest, balance: c.balance });
|
|
18
|
+
}
|
|
19
|
+
cursor = page.hasNextPage ? page.nextCursor : null;
|
|
20
|
+
} while (cursor);
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
async getSharedRef(objectId) {
|
|
24
|
+
const res = await this.client.getObject({ id: objectId, options: { showOwner: true } });
|
|
25
|
+
const owner = res.data?.owner;
|
|
26
|
+
const isv = owner?.Shared?.initial_shared_version;
|
|
27
|
+
if (isv == null)
|
|
28
|
+
throw new Error(`[jsonrpc] ${objectId} 非共享对象或无 initial_shared_version`);
|
|
29
|
+
return { objectId, initialSharedVersion: String(isv) };
|
|
30
|
+
}
|
|
31
|
+
async getGasPrice() {
|
|
32
|
+
return BigInt(await this.client.getReferenceGasPrice());
|
|
33
|
+
}
|
|
34
|
+
async simulate(txBytes) {
|
|
35
|
+
const res = await this.client.dryRunTransactionBlock({ transactionBlock: txBytes });
|
|
36
|
+
return this.normalize('', res.effects, res.objectChanges, res.balanceChanges);
|
|
37
|
+
}
|
|
38
|
+
async execute(txBytes, signatures) {
|
|
39
|
+
const res = await this.client.executeTransactionBlock({
|
|
40
|
+
transactionBlock: (0, utils_1.toB64)(txBytes),
|
|
41
|
+
signature: signatures,
|
|
42
|
+
options: { showEffects: true, showObjectChanges: true, showBalanceChanges: true },
|
|
43
|
+
});
|
|
44
|
+
return this.normalize(res.digest, res.effects, res.objectChanges, res.balanceChanges);
|
|
45
|
+
}
|
|
46
|
+
normalize(digest, effects, objectChanges, balanceChanges) {
|
|
47
|
+
const success = effects?.status?.status === 'success';
|
|
48
|
+
const error = success ? undefined : (effects?.status?.error || 'unknown');
|
|
49
|
+
const changes = (objectChanges || [])
|
|
50
|
+
.filter((c) => c?.type === 'created' || c?.type === 'mutated' || c?.type === 'deleted')
|
|
51
|
+
.map((c) => ({
|
|
52
|
+
type: c.type,
|
|
53
|
+
objectId: c.objectId,
|
|
54
|
+
objectType: c.objectType,
|
|
55
|
+
version: c.version != null ? String(c.version) : undefined,
|
|
56
|
+
digest: c.digest,
|
|
57
|
+
owner: typeof c.owner === 'object' ? c.owner?.AddressOwner : c.owner,
|
|
58
|
+
}));
|
|
59
|
+
let gasUsed;
|
|
60
|
+
const g = effects?.gasUsed;
|
|
61
|
+
if (g) {
|
|
62
|
+
try {
|
|
63
|
+
gasUsed = BigInt(g.computationCost) + BigInt(g.storageCost) - BigInt(g.storageRebate);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
(0, dist_1.log_warn)('[jsonrpc] gasUsed 解析失败');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const normBalances = (balanceChanges || []).map((b) => ({
|
|
70
|
+
owner: typeof b.owner === 'object' ? b.owner?.AddressOwner : b.owner,
|
|
71
|
+
coinType: b.coinType,
|
|
72
|
+
amount: String(b.amount),
|
|
73
|
+
}));
|
|
74
|
+
return { digest, success, error, objectChanges: changes, balanceChanges: normBalances, gasUsed };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.JsonRpcDataChannel = JsonRpcDataChannel;
|
package/dist/trade/index.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export * from './send_tx';
|
|
2
2
|
export * from './check';
|
|
3
3
|
export * from './parse';
|
|
4
|
-
export * from './
|
|
4
|
+
export * from './coin';
|
|
5
|
+
export * from './swap';
|
|
6
|
+
export * from './executor';
|
|
7
|
+
export * from './tx_result_channel';
|
|
8
|
+
export * from './abstract_sui_dex_trade';
|
package/dist/trade/index.js
CHANGED
|
@@ -17,4 +17,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./send_tx"), exports);
|
|
18
18
|
__exportStar(require("./check"), exports);
|
|
19
19
|
__exportStar(require("./parse"), exports);
|
|
20
|
-
__exportStar(require("./
|
|
20
|
+
__exportStar(require("./coin"), exports);
|
|
21
|
+
__exportStar(require("./swap"), exports);
|
|
22
|
+
__exportStar(require("./executor"), exports);
|
|
23
|
+
__exportStar(require("./tx_result_channel"), exports);
|
|
24
|
+
__exportStar(require("./abstract_sui_dex_trade"), exports);
|
|
@@ -1,13 +1,4 @@
|
|
|
1
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
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -20,74 +11,91 @@ class SuiTransactionParser {
|
|
|
20
11
|
constructor(walletAddress) {
|
|
21
12
|
this.walletAddress = walletAddress;
|
|
22
13
|
}
|
|
23
|
-
parseTransaction(receipt, poolInfo) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return yield this.parse_transaction_result(receipt, poolInfo);
|
|
37
|
-
}
|
|
38
|
-
catch (error) {
|
|
39
|
-
console.error('Error parsing transaction:', error);
|
|
40
|
-
return this.create_failed_result(receipt, poolInfo, error.message);
|
|
14
|
+
async parseTransaction(receipt, poolInfo) {
|
|
15
|
+
try {
|
|
16
|
+
if (receipt.transaction?.effects?.status?.success !== true) {
|
|
17
|
+
const reason = receipt.transaction?.effects?.status?.error?.kind
|
|
18
|
+
?? receipt.transaction?.effects?.status?.error
|
|
19
|
+
?? 'unknown';
|
|
20
|
+
console.log('Transaction failed', {
|
|
21
|
+
txid: receipt.transaction?.digest,
|
|
22
|
+
success: receipt.transaction?.effects?.status?.success,
|
|
23
|
+
balance_changes: receipt.transaction?.balance_changes?.length,
|
|
24
|
+
reason,
|
|
25
|
+
});
|
|
26
|
+
return this.create_failed_result(receipt, poolInfo, String(reason));
|
|
41
27
|
}
|
|
42
|
-
|
|
28
|
+
return await this.parse_transaction_result(receipt, poolInfo);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error('Error parsing transaction:', error);
|
|
32
|
+
return this.create_failed_result(receipt, poolInfo, error.message);
|
|
33
|
+
}
|
|
43
34
|
}
|
|
44
|
-
parse_transaction_result(tx_receipt, pool_info) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (normalizedCoinType === poolTokenAAddress) {
|
|
60
|
-
tokenAChangeAmount = amount.div(Math.pow(10, pool_info.tokenA.decimals));
|
|
61
|
-
}
|
|
62
|
-
if (normalizedCoinType === poolTokenBAddress) {
|
|
63
|
-
tokenBChangeAmount = amount.div(Math.pow(10, pool_info.tokenB.decimals));
|
|
64
|
-
}
|
|
35
|
+
async parse_transaction_result(tx_receipt, pool_info) {
|
|
36
|
+
const txid = tx_receipt.transaction?.digest || '';
|
|
37
|
+
let swap_detail = null;
|
|
38
|
+
let tokenAChangeAmount = new decimal_js_1.default(0);
|
|
39
|
+
let tokenBChangeAmount = new decimal_js_1.default(0);
|
|
40
|
+
const balanceChanges = tx_receipt.transaction?.balance_changes || [];
|
|
41
|
+
(0, dist_1.log_info)('balance_changes', { txid, balance_changes: balanceChanges });
|
|
42
|
+
for (const change of balanceChanges) {
|
|
43
|
+
const amount = new decimal_js_1.default(change.amount);
|
|
44
|
+
const coinType = change.coin_type;
|
|
45
|
+
const normalizedCoinType = (0, index_1.normalizeSuiTokenAddress)(coinType);
|
|
46
|
+
const poolTokenAAddress = (0, index_1.normalizeSuiTokenAddress)(pool_info.tokenA.address);
|
|
47
|
+
const poolTokenBAddress = (0, index_1.normalizeSuiTokenAddress)(pool_info.tokenB.address);
|
|
48
|
+
if (normalizedCoinType === poolTokenAAddress) {
|
|
49
|
+
tokenAChangeAmount = amount.div(10 ** pool_info.tokenA.decimals);
|
|
65
50
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
51
|
+
if (normalizedCoinType === poolTokenBAddress) {
|
|
52
|
+
tokenBChangeAmount = amount.div(10 ** pool_info.tokenB.decimals);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
let tx_price = this.calc_tx_price(tokenAChangeAmount, tokenBChangeAmount, pool_info);
|
|
56
|
+
swap_detail = {
|
|
57
|
+
tokenA: {
|
|
58
|
+
...pool_info.tokenA,
|
|
59
|
+
pre_bal: 0,
|
|
60
|
+
post_bal: 0,
|
|
61
|
+
change: tokenAChangeAmount
|
|
62
|
+
},
|
|
63
|
+
tokenB: {
|
|
64
|
+
...pool_info.tokenB,
|
|
65
|
+
pre_bal: 0,
|
|
66
|
+
post_bal: 0,
|
|
67
|
+
change: tokenBChangeAmount
|
|
68
|
+
},
|
|
69
|
+
tx_price,
|
|
70
|
+
};
|
|
71
|
+
const gasFee = this.calculateGasFee(tx_receipt);
|
|
72
|
+
return {
|
|
73
|
+
success: true,
|
|
74
|
+
error_code: '',
|
|
75
|
+
wallet: this.walletAddress,
|
|
76
|
+
txid,
|
|
77
|
+
block_time: this.extractTimestamp(tx_receipt),
|
|
78
|
+
block_number: this.extractCheckpoint(tx_receipt),
|
|
79
|
+
tx_index: 0,
|
|
80
|
+
pool_address: pool_info.pool_address,
|
|
81
|
+
tokenA: {
|
|
82
|
+
...pool_info.tokenA,
|
|
83
|
+
pre_bal: 0,
|
|
84
|
+
post_bal: 0,
|
|
85
|
+
change: swap_detail?.tokenA?.change?.toNumber() || 0
|
|
86
|
+
},
|
|
87
|
+
tokenB: {
|
|
88
|
+
...pool_info.tokenB,
|
|
89
|
+
pre_bal: 0,
|
|
90
|
+
post_bal: 0,
|
|
91
|
+
change: swap_detail?.tokenB?.change?.toNumber() || 0
|
|
92
|
+
},
|
|
93
|
+
tx_price: swap_detail?.tx_price || '0',
|
|
94
|
+
gas_fee: gasFee
|
|
95
|
+
};
|
|
87
96
|
}
|
|
88
97
|
calculateGasFee(receipt) {
|
|
89
|
-
|
|
90
|
-
const gasUsed = (_b = (_a = receipt.transaction) === null || _a === void 0 ? void 0 : _a.effects) === null || _b === void 0 ? void 0 : _b.gas_used;
|
|
98
|
+
const gasUsed = receipt.transaction?.effects?.gas_used;
|
|
91
99
|
if (!gasUsed) {
|
|
92
100
|
return {
|
|
93
101
|
base_fee: 0,
|
|
@@ -100,8 +108,8 @@ class SuiTransactionParser {
|
|
|
100
108
|
const storageRebate = new decimal_js_1.default(gasUsed.storage_rebate || 0);
|
|
101
109
|
const nonRefundableStorageFee = new decimal_js_1.default(gasUsed.non_refundable_storage_fee || 0);
|
|
102
110
|
const actualStorageCost = storageCost.minus(storageRebate).plus(nonRefundableStorageFee);
|
|
103
|
-
const baseFee = actualStorageCost.div(
|
|
104
|
-
const priorityFee = computationCost.div(
|
|
111
|
+
const baseFee = actualStorageCost.div(10 ** 9);
|
|
112
|
+
const priorityFee = computationCost.div(10 ** 9);
|
|
105
113
|
const totalFee = baseFee.plus(priorityFee);
|
|
106
114
|
return {
|
|
107
115
|
base_fee: baseFee.toNumber(),
|
|
@@ -122,18 +130,28 @@ class SuiTransactionParser {
|
|
|
122
130
|
return '0';
|
|
123
131
|
}
|
|
124
132
|
create_failed_result(txReceipt, poolInfo, errorMessage) {
|
|
125
|
-
var _a;
|
|
126
133
|
const gasFee = this.calculateGasFee(txReceipt);
|
|
127
134
|
return {
|
|
128
135
|
success: false,
|
|
129
136
|
error_code: this.parseErrorMsgToErrorCode(errorMessage),
|
|
130
137
|
wallet: this.walletAddress,
|
|
131
|
-
txid:
|
|
138
|
+
txid: txReceipt.transaction?.digest || '',
|
|
132
139
|
block_time: this.extractTimestamp(txReceipt),
|
|
133
140
|
block_number: this.extractCheckpoint(txReceipt),
|
|
141
|
+
tx_index: 0,
|
|
134
142
|
pool_address: poolInfo.pool_address,
|
|
135
|
-
tokenA:
|
|
136
|
-
|
|
143
|
+
tokenA: {
|
|
144
|
+
...poolInfo.tokenA,
|
|
145
|
+
pre_bal: 0,
|
|
146
|
+
post_bal: 0,
|
|
147
|
+
change: 0
|
|
148
|
+
},
|
|
149
|
+
tokenB: {
|
|
150
|
+
...poolInfo.tokenB,
|
|
151
|
+
pre_bal: 0,
|
|
152
|
+
post_bal: 0,
|
|
153
|
+
change: 0
|
|
154
|
+
},
|
|
137
155
|
tx_price: '0',
|
|
138
156
|
gas_fee: gasFee
|
|
139
157
|
};
|
|
@@ -152,9 +170,8 @@ class SuiTransactionParser {
|
|
|
152
170
|
return dist_1.TradeErrorCodeType.UNKOWN;
|
|
153
171
|
}
|
|
154
172
|
extractTimestamp(receipt) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if (timestamp === null || timestamp === void 0 ? void 0 : timestamp.seconds) {
|
|
173
|
+
const timestamp = receipt.transaction?.timestamp;
|
|
174
|
+
if (timestamp?.seconds) {
|
|
158
175
|
return parseInt(timestamp.seconds) * 1000;
|
|
159
176
|
}
|
|
160
177
|
return Date.now();
|
|
@@ -1,30 +1,21 @@
|
|
|
1
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
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.SuiTxSender = void 0;
|
|
13
4
|
const dist_1 = require("@clonegod/ttd-core/dist");
|
|
14
5
|
class SuiTxSender {
|
|
15
6
|
constructor(appConfig, sui_client, grpcClient) {
|
|
16
|
-
this.send_tx =
|
|
7
|
+
this.send_tx = async (signedTxBytes, signature, txDigest, send_type, read_mask_fields = ['transaction']) => {
|
|
17
8
|
const start_time = Date.now();
|
|
18
9
|
try {
|
|
19
10
|
send_type = (send_type || 'ALL').toUpperCase();
|
|
20
11
|
if (send_type === 'GRPC') {
|
|
21
|
-
|
|
12
|
+
await this.sendTxByGrpc(signedTxBytes, signature, txDigest, read_mask_fields);
|
|
22
13
|
}
|
|
23
14
|
else if (send_type === 'RPC') {
|
|
24
|
-
|
|
15
|
+
await this.sendTxByRpc(signedTxBytes, signature, txDigest);
|
|
25
16
|
}
|
|
26
17
|
else {
|
|
27
|
-
|
|
18
|
+
await Promise.race([
|
|
28
19
|
this.sendTxByGrpc(signedTxBytes, signature, txDigest, read_mask_fields),
|
|
29
20
|
this.sendTxByRpc(signedTxBytes, signature, txDigest)
|
|
30
21
|
]);
|
|
@@ -35,45 +26,41 @@ class SuiTxSender {
|
|
|
35
26
|
(0, dist_1.log_warn)(`send_tx failed, txid=${txDigest}, send_type=${send_type}, cost=${Date.now() - start_time}ms, error=${error.message}`);
|
|
36
27
|
throw error;
|
|
37
28
|
}
|
|
38
|
-
}
|
|
29
|
+
};
|
|
39
30
|
this.appConfig = appConfig;
|
|
40
31
|
this.sui_client = sui_client;
|
|
41
32
|
this.grpcClient = grpcClient;
|
|
42
33
|
}
|
|
43
|
-
sendTxByGrpc(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
});
|
|
34
|
+
async sendTxByGrpc(signedTxBytes, signature, txDigest, read_mask_fields = ['transaction']) {
|
|
35
|
+
const bcsBytes = Buffer.from(signedTxBytes, 'base64');
|
|
36
|
+
const signatureBytes = Buffer.from(signature, 'base64');
|
|
37
|
+
try {
|
|
38
|
+
let response = await this.grpcClient.transactionService.executeTransaction(bcsBytes, signatureBytes, read_mask_fields);
|
|
39
|
+
this.appConfig.emit(`SUI_TX_RESULT_${txDigest}`, response);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
(0, dist_1.log_warn)(`send tx by grpc failed!!! txid=${txDigest}, error=${error.message}`);
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
56
45
|
}
|
|
57
|
-
sendTxByRpc(signedTxBytes, signature, txDigest) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
});
|
|
46
|
+
async sendTxByRpc(signedTxBytes, signature, txDigest) {
|
|
47
|
+
try {
|
|
48
|
+
let _response = await this.sui_client.executeTransactionBlock({
|
|
49
|
+
transactionBlock: signedTxBytes,
|
|
50
|
+
signature: signature,
|
|
51
|
+
options: {
|
|
52
|
+
showEvents: true,
|
|
53
|
+
showBalanceChanges: true,
|
|
54
|
+
showObjectChanges: true,
|
|
55
|
+
showEffects: true
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
this.appConfig.emit(`SUI_TX_RESULT_${txDigest}`, txDigest);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
(0, dist_1.log_warn)(`send tx by rpc failed!!! txid=${txDigest}, error=${error.message}`);
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
77
64
|
}
|
|
78
65
|
}
|
|
79
66
|
exports.SuiTxSender = SuiTxSender;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Transaction, TransactionObjectArgument } from '@mysten/sui/transactions';
|
|
2
|
+
import { DEX_ID } from '@clonegod/ttd-core/dist';
|
|
3
|
+
import { SwapBuilder, SwapBuildParams, SwapBuildResult } from '../types';
|
|
4
|
+
declare class BluefinSwapBuilder implements SwapBuilder {
|
|
5
|
+
readonly dexId = DEX_ID.BLUEFIN_CLMM;
|
|
6
|
+
build(tx: Transaction, params: SwapBuildParams, inputCoin: TransactionObjectArgument): SwapBuildResult;
|
|
7
|
+
}
|
|
8
|
+
export declare const BLUEFIN_SWAP_BUILDER: BluefinSwapBuilder;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BLUEFIN_SWAP_BUILDER = void 0;
|
|
4
|
+
const dist_1 = require("@clonegod/ttd-core/dist");
|
|
5
|
+
const dex_swap_config_1 = require("../dex_swap_config");
|
|
6
|
+
class BluefinSwapBuilder {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.dexId = dist_1.DEX_ID.BLUEFIN_CLMM;
|
|
9
|
+
}
|
|
10
|
+
build(tx, params, inputCoin) {
|
|
11
|
+
const { coinTypeA, coinTypeB, poolId, a2b, byAmountIn, amount, amountLimit } = params;
|
|
12
|
+
const inType = a2b ? coinTypeA : coinTypeB;
|
|
13
|
+
const outType = a2b ? coinTypeB : coinTypeA;
|
|
14
|
+
const sqrtLimit = params.sqrtPriceLimit !== 0n
|
|
15
|
+
? params.sqrtPriceLimit
|
|
16
|
+
: (a2b ? dex_swap_config_1.SQRT_PRICE_LIMIT.BLUEFIN_MIN : dex_swap_config_1.SQRT_PRICE_LIMIT.BLUEFIN_MAX);
|
|
17
|
+
const [inBalance] = tx.moveCall({
|
|
18
|
+
target: '0x2::coin::into_balance',
|
|
19
|
+
typeArguments: [inType],
|
|
20
|
+
arguments: [inputCoin],
|
|
21
|
+
});
|
|
22
|
+
const [zeroBalance] = tx.moveCall({
|
|
23
|
+
target: '0x2::balance::zero',
|
|
24
|
+
typeArguments: [outType],
|
|
25
|
+
arguments: [],
|
|
26
|
+
});
|
|
27
|
+
const balanceA = a2b ? inBalance : zeroBalance;
|
|
28
|
+
const balanceB = a2b ? zeroBalance : inBalance;
|
|
29
|
+
const [balOutA, balOutB] = tx.moveCall({
|
|
30
|
+
target: `${dex_swap_config_1.BLUEFIN_SWAP_CONFIG.pkg}::pool::swap`,
|
|
31
|
+
typeArguments: [coinTypeA, coinTypeB],
|
|
32
|
+
arguments: [
|
|
33
|
+
tx.object(dex_swap_config_1.SUI_CLOCK_ID),
|
|
34
|
+
tx.object(dex_swap_config_1.BLUEFIN_SWAP_CONFIG.globalConfig),
|
|
35
|
+
tx.object(poolId),
|
|
36
|
+
balanceA,
|
|
37
|
+
balanceB,
|
|
38
|
+
tx.pure.bool(a2b),
|
|
39
|
+
tx.pure.bool(byAmountIn),
|
|
40
|
+
tx.pure.u64(amount),
|
|
41
|
+
tx.pure.u64(amountLimit),
|
|
42
|
+
tx.pure.u128(sqrtLimit),
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
const [coinOutA] = tx.moveCall({
|
|
46
|
+
target: '0x2::coin::from_balance',
|
|
47
|
+
typeArguments: [coinTypeA],
|
|
48
|
+
arguments: [balOutA],
|
|
49
|
+
});
|
|
50
|
+
const [coinOutB] = tx.moveCall({
|
|
51
|
+
target: '0x2::coin::from_balance',
|
|
52
|
+
typeArguments: [coinTypeB],
|
|
53
|
+
arguments: [balOutB],
|
|
54
|
+
});
|
|
55
|
+
const outputCoin = a2b ? coinOutB : coinOutA;
|
|
56
|
+
const leftover = a2b ? coinOutA : coinOutB;
|
|
57
|
+
return { outputCoin, leftoverCoins: [leftover] };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.BLUEFIN_SWAP_BUILDER = new BluefinSwapBuilder();
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Transaction, TransactionObjectArgument } from '@mysten/sui/transactions';
|
|
2
|
+
import { DEX_ID } from '@clonegod/ttd-core/dist';
|
|
3
|
+
import { SwapBuilder, SwapBuildParams, SwapBuildResult } from '../types';
|
|
4
|
+
import { CetusLikeSwapConfig } from '../dex_swap_config';
|
|
5
|
+
declare class CetusLikeSwapBuilder implements SwapBuilder {
|
|
6
|
+
readonly dexId: DEX_ID;
|
|
7
|
+
private readonly cfg;
|
|
8
|
+
constructor(dexId: DEX_ID, cfg: CetusLikeSwapConfig);
|
|
9
|
+
build(tx: Transaction, params: SwapBuildParams, inputCoin: TransactionObjectArgument): SwapBuildResult;
|
|
10
|
+
}
|
|
11
|
+
export declare const CETUS_SWAP_BUILDER: CetusLikeSwapBuilder;
|
|
12
|
+
export declare const MAGMA_SWAP_BUILDER: CetusLikeSwapBuilder;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MAGMA_SWAP_BUILDER = exports.CETUS_SWAP_BUILDER = void 0;
|
|
4
|
+
const dist_1 = require("@clonegod/ttd-core/dist");
|
|
5
|
+
const dex_swap_config_1 = require("../dex_swap_config");
|
|
6
|
+
class CetusLikeSwapBuilder {
|
|
7
|
+
constructor(dexId, cfg) {
|
|
8
|
+
this.dexId = dexId;
|
|
9
|
+
this.cfg = cfg;
|
|
10
|
+
}
|
|
11
|
+
build(tx, params, inputCoin) {
|
|
12
|
+
const { coinTypeA, coinTypeB, poolId, a2b, byAmountIn, amount, amountLimit } = params;
|
|
13
|
+
const sqrtLimit = params.sqrtPriceLimit !== 0n
|
|
14
|
+
? params.sqrtPriceLimit
|
|
15
|
+
: (a2b ? dex_swap_config_1.SQRT_PRICE_LIMIT.CETUS_MIN : dex_swap_config_1.SQRT_PRICE_LIMIT.CETUS_MAX);
|
|
16
|
+
const [zeroCoin] = tx.moveCall({
|
|
17
|
+
target: '0x2::coin::zero',
|
|
18
|
+
typeArguments: [a2b ? coinTypeB : coinTypeA],
|
|
19
|
+
arguments: [],
|
|
20
|
+
});
|
|
21
|
+
const coinA = a2b ? inputCoin : zeroCoin;
|
|
22
|
+
const coinB = a2b ? zeroCoin : inputCoin;
|
|
23
|
+
const coinABs = tx.moveCall({
|
|
24
|
+
target: `${this.cfg.integratePkg}::router::swap`,
|
|
25
|
+
typeArguments: [coinTypeA, coinTypeB],
|
|
26
|
+
arguments: [
|
|
27
|
+
tx.object(this.cfg.globalConfig),
|
|
28
|
+
tx.object(poolId),
|
|
29
|
+
coinA,
|
|
30
|
+
coinB,
|
|
31
|
+
tx.pure.bool(a2b),
|
|
32
|
+
tx.pure.bool(byAmountIn),
|
|
33
|
+
tx.pure.u64(amount),
|
|
34
|
+
tx.pure.u128(sqrtLimit),
|
|
35
|
+
tx.pure.bool(false),
|
|
36
|
+
tx.object(dex_swap_config_1.SUI_CLOCK_ID),
|
|
37
|
+
],
|
|
38
|
+
});
|
|
39
|
+
const outputCoin = a2b ? coinABs[1] : coinABs[0];
|
|
40
|
+
const leftover = a2b ? coinABs[0] : coinABs[1];
|
|
41
|
+
if (byAmountIn && amountLimit > 0n) {
|
|
42
|
+
tx.moveCall({
|
|
43
|
+
target: `${this.cfg.integratePkg}::router::check_coin_threshold`,
|
|
44
|
+
typeArguments: [a2b ? coinTypeB : coinTypeA],
|
|
45
|
+
arguments: [outputCoin, tx.pure.u64(amountLimit)],
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return { outputCoin, leftoverCoins: [leftover] };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.CETUS_SWAP_BUILDER = new CetusLikeSwapBuilder(dist_1.DEX_ID.CETUS_CLMM, dex_swap_config_1.CETUS_SWAP_CONFIG);
|
|
52
|
+
exports.MAGMA_SWAP_BUILDER = new CetusLikeSwapBuilder(dist_1.DEX_ID.MAGMA_CLMM, dex_swap_config_1.MAGMA_SWAP_CONFIG);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Transaction, TransactionObjectArgument } from '@mysten/sui/transactions';
|
|
2
|
+
import { DEX_ID } from '@clonegod/ttd-core/dist';
|
|
3
|
+
import { SwapBuilder, SwapBuildParams, SwapBuildResult } from '../types';
|
|
4
|
+
declare class MomentumSwapBuilder implements SwapBuilder {
|
|
5
|
+
readonly dexId = DEX_ID.MOMENTUM_CLMM;
|
|
6
|
+
build(tx: Transaction, params: SwapBuildParams, inputCoin: TransactionObjectArgument): SwapBuildResult;
|
|
7
|
+
}
|
|
8
|
+
export declare const MOMENTUM_SWAP_BUILDER: MomentumSwapBuilder;
|
|
9
|
+
export {};
|