@clonegod/ttd-bsc-common 3.0.29 → 3.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.
@@ -1,3 +1,4 @@
1
+ import { TradeTrace } from '../trade/trade_trace';
1
2
  export interface ITransactionSender {
2
- sendTransaction(signedMainTx: string, eoa_tip_transaction: (eoa_address: string) => Promise<string>, order_trace_id: string, pair?: string, only_bundle?: boolean): Promise<string[]>;
3
+ sendTransaction(signedMainTx: string, eoa_tip_transaction: (eoa_address: string) => Promise<string>, order_trace_id: string, pair?: string, only_bundle?: boolean, trace?: Pick<TradeTrace, 'mark' | 'markProvider'>): Promise<string[]>;
3
4
  }
@@ -48,6 +48,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
48
48
  exports.AbstractDexTrade = void 0;
49
49
  exports.buildTradeConfig = buildTradeConfig;
50
50
  const ttd_core_1 = require("@clonegod/ttd-core");
51
+ const logger = (0, ttd_core_1.createLogger)(__filename);
51
52
  const fs = __importStar(require("fs"));
52
53
  const path = __importStar(require("path"));
53
54
  const caller_manager_1 = require("./caller_manager");
@@ -56,6 +57,7 @@ const base_tx_result_checker_1 = require("./check/base_tx_result_checker");
56
57
  const redis_1 = require("../redis");
57
58
  const trade_direction_1 = require("../utils/trade_direction");
58
59
  const ethers_compat_1 = require("../utils/ethers_compat");
60
+ const trade_trace_1 = require("./trade_trace");
59
61
  const decimal_js_1 = __importDefault(require("decimal.js"));
60
62
  function buildTradeConfig() {
61
63
  const vaultGroupId = process.env.TRADE_GROUP_ID || process.env.VAULT_GROUP_ID;
@@ -110,7 +112,7 @@ class AbstractDexTrade extends ttd_core_1.AbastrcatTrade {
110
112
  chainId: this.chainConfig.chainId,
111
113
  });
112
114
  yield this.callerManager.init();
113
- (0, ttd_core_1.log_info)(`AbstractDexTrade initialized, vault=${this.tradeConfig.vaultAddress}, callers=${this.callerManager.getCallerCount()}`);
115
+ logger.info(`AbstractDexTrade initialized, vault=${this.tradeConfig.vaultAddress}, callers=${this.callerManager.getCallerCount()}`);
114
116
  });
115
117
  }
116
118
  execute(context) {
@@ -119,18 +121,17 @@ class AbstractDexTrade extends ttd_core_1.AbastrcatTrade {
119
121
  const { price_msg, order_msg, slippage_bps, order_trace_id, pool_info } = context;
120
122
  const { pair } = price_msg;
121
123
  const { isBuy, amount } = order_msg;
124
+ const direction = isBuy ? 'BUY' : 'SELL';
122
125
  const { inputToken, outputToken } = this.determineInputOutputTokens(order_msg, pool_info);
123
126
  const amountOutMin = this.calculateAmountOutMin(context, inputToken, outputToken);
124
- (0, ttd_core_1.log_info)(`执行交易`, {
125
- orderId: order_trace_id,
126
- pair,
127
- direction: isBuy ? 'BUY' : 'SELL',
128
- input: `${amount} ${inputToken.symbol}`,
129
- outputMin: `${ethers_compat_1.ethersCompat.formatUnits(amountOutMin, outputToken.decimals)} ${outputToken.symbol}`,
130
- slippage: `${slippage_bps / 100}%`,
131
- });
127
+ const trace = new trade_trace_1.TradeTrace(order_trace_id, pair, direction);
128
+ trace.set('input', `${amount} ${inputToken.symbol}`);
129
+ trace.set('outputMin', `${ethers_compat_1.ethersCompat.formatUnits(amountOutMin, outputToken.decimals)} ${outputToken.symbol}`);
130
+ trace.set('slippage', `${slippage_bps / 100}%`);
132
131
  let maxAttempts = Math.min(Math.max(parseInt(process.env.NONCE_LOCK_MAX_RETRIES || '3'), 1), 3);
133
132
  const { wallet: caller, nonce: initialNonce } = yield this.callerManager.acquireCaller();
133
+ trace.mark('caller');
134
+ trace.set('caller', caller.address);
134
135
  let nonce = initialNonce;
135
136
  let nonce_from_error = -1;
136
137
  let txid = '';
@@ -141,14 +142,14 @@ class AbstractDexTrade extends ttd_core_1.AbastrcatTrade {
141
142
  if (nonce_from_error >= 0) {
142
143
  nonce = nonce_from_error;
143
144
  nonce_from_error = -1;
144
- (0, ttd_core_1.log_info)(`Attempt ${i}/${maxAttempts}, using nonce from error msg: ${nonce}`, {}, order_trace_id);
145
145
  }
146
146
  else {
147
147
  nonce = yield this.provider.getTransactionCount(caller.address, 'pending');
148
- (0, ttd_core_1.log_info)(`Attempt ${i}/${maxAttempts}, using nonce from chain: ${nonce}`, {}, order_trace_id);
149
148
  }
149
+ trace.set('retry', `${i}/${maxAttempts}`);
150
150
  }
151
151
  const { executorId, data } = this.encodeTradeData(context);
152
+ trace.mark('encode');
152
153
  const deadline = Math.floor(Date.now() / 1000) + 60;
153
154
  const vaultCalldata = this.vaultInterface.encodeFunctionData('delegatecallExecutorToTrade', [executorId, data, deadline]);
154
155
  const gasPriceGwei = this.getGasPriceGwei(context);
@@ -174,22 +175,24 @@ class AbstractDexTrade extends ttd_core_1.AbastrcatTrade {
174
175
  caller.signTransaction(mainTx),
175
176
  ...builderAddresses.map(addr => this.buildTipTransferTx(addr, transfer_amount_gwei, realGasPriceGwei, tipNonce, caller)),
176
177
  ]);
178
+ trace.mark('sign');
177
179
  const ensure0x = (tx) => tx.startsWith('0x') ? tx : `0x${tx}`;
178
180
  const signedMainTx = ensure0x(rawMainTx);
179
181
  const signedTips = rawTips.map(ensure0x);
180
182
  txid = ethers_compat_1.ethersCompat.keccak256(signedMainTx);
181
183
  const tipTxMap = new Map();
182
184
  builderAddresses.forEach((addr, idx) => tipTxMap.set(addr, signedTips[idx]));
183
- (0, ttd_core_1.log_info)(`交易已签名`, { txid, nonce, caller: caller.address, gasPriceGwei: realGasPriceGwei }, order_trace_id);
185
+ trace.set('txid', txid);
186
+ trace.set('nonce', nonce);
187
+ trace.set('gas', realGasPriceGwei);
188
+ trace.set('tip', transfer_amount_gwei);
184
189
  const only_bundle = order_msg.is_dex_maker;
185
190
  const eoa_tip_transaction = (eoa_address) => __awaiter(this, void 0, void 0, function* () {
186
191
  return tipTxMap.get(eoa_address) || (yield this.buildTipTransferTx(eoa_address, transfer_amount_gwei, realGasPriceGwei, tipNonce, caller));
187
192
  });
188
- yield this.transactionSender.sendTransaction(signedMainTx, eoa_tip_transaction, order_trace_id, pair, only_bundle);
189
- (0, ttd_core_1.log_info)(`交易发送成功`, {
190
- pair, direction: isBuy ? 'BUY' : 'SELL',
191
- txid, attempt: i, caller: caller.address
192
- }, order_trace_id);
193
+ yield this.transactionSender.sendTransaction(signedMainTx, eoa_tip_transaction, order_trace_id, pair, only_bundle, trace);
194
+ trace.mark('sent');
195
+ trace.flush();
193
196
  try {
194
197
  base_tx_result_checker_1.TradeResultSubscriber.getInstance().sendNonceWatch(caller.address, txid);
195
198
  }
@@ -199,19 +202,20 @@ class AbstractDexTrade extends ttd_core_1.AbastrcatTrade {
199
202
  catch (error) {
200
203
  const errorMessage = ((_a = error.message) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
201
204
  if (errorMessage.includes('rate limit')) {
202
- (0, ttd_core_1.log_warn)(`Rate limit error, no retry! i=${i}`, {}, order_trace_id);
205
+ trace.markError('send', `rate limit, attempt ${i}`);
206
+ trace.flush();
203
207
  return txid;
204
208
  }
205
209
  if (errorMessage.includes('replacement transaction underpriced')) {
206
- (0, ttd_core_1.log_warn)(`Replacement tx underpriced, continue! i=${i}`, {}, order_trace_id);
210
+ trace.set('underpriced_retry', i);
207
211
  continue;
208
212
  }
209
213
  const isNonceError = errorMessage.includes('nonce');
210
214
  if (!isNonceError || i >= maxAttempts) {
211
- (0, ttd_core_1.log_warn)(`Non-nonce error or max retries, i=${i}, error: ${errorMessage}`, {}, order_trace_id);
215
+ trace.markError('send', `${errorMessage}, attempt ${i}/${maxAttempts}`);
216
+ trace.flush();
212
217
  return txid;
213
218
  }
214
- (0, ttd_core_1.log_info)(`Nonce error detected, will retry! i=${i}`, {}, order_trace_id);
215
219
  if (errorMessage.includes('nonce too')) {
216
220
  const correctNonce = this.extractNonceFromErrorMsg(errorMessage);
217
221
  if (correctNonce !== null && correctNonce >= 0) {
@@ -221,6 +225,8 @@ class AbstractDexTrade extends ttd_core_1.AbastrcatTrade {
221
225
  }
222
226
  } while (++i <= maxAttempts);
223
227
  if (!txid) {
228
+ trace.markError('exhaust', `failed after ${maxAttempts} attempts`);
229
+ trace.flush();
224
230
  throw new Error(`交易执行失败,已重试 ${maxAttempts} 次,orderId: ${order_trace_id}`);
225
231
  }
226
232
  return txid;
@@ -262,11 +268,6 @@ class AbstractDexTrade extends ttd_core_1.AbastrcatTrade {
262
268
  };
263
269
  const rawSignedTx = yield wallet.signTransaction(tx_data);
264
270
  const signedTx = rawSignedTx.startsWith('0x') ? rawSignedTx : `0x${rawSignedTx}`;
265
- (0, ttd_core_1.log_info)(`构建 tip 转账交易`, {
266
- to, nonce,
267
- tipGwei: real_transfer_amount_gwei,
268
- txhash: ethers_compat_1.ethersCompat.keccak256(signedTx)
269
- });
270
271
  return signedTx;
271
272
  });
272
273
  }
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.CallerManager = void 0;
13
13
  const dist_1 = require("@clonegod/ttd-core/dist");
14
+ const logger = (0, dist_1.createLogger)(__filename);
14
15
  const ethers_1 = require("ethers");
15
16
  const redis_1 = require("../redis");
16
17
  const CALLER_NONCE_KEY = 'caller:nonce';
@@ -26,21 +27,21 @@ class CallerManager {
26
27
  return __awaiter(this, void 0, void 0, function* () {
27
28
  const walletInfos = (0, dist_1.load_wallet_multi)(this.config.callerGroupIds, false);
28
29
  const allWallets = walletInfos.map(info => new ethers_1.ethers.Wallet(info.private_key, this.config.provider));
29
- (0, dist_1.log_info)(`CallerManager: loaded ${allWallets.length} wallets from CALLER_GROUP_IDS`, allWallets.map(w => w.address));
30
+ logger.info(`CallerManager: loaded ${allWallets.length} wallets from CALLER_GROUP_IDS`, allWallets.map(w => w.address));
30
31
  const vaultCallersKey = `${this.config.chainName}:${VAULT_CALLERS_KEY}`;
31
32
  const allowedAddresses = yield this.redis.lrange(vaultCallersKey);
32
33
  if (allowedAddresses && allowedAddresses.length > 0) {
33
34
  const allowedSet = new Set(allowedAddresses.map(a => a.toLowerCase()));
34
35
  this.callers = allWallets.filter(w => allowedSet.has(w.address.toLowerCase()));
35
- (0, dist_1.log_info)(`CallerManager: matched ${this.callers.length} callers with Vault whitelist`, this.callers.map(w => w.address));
36
+ logger.info(`CallerManager: matched ${this.callers.length} callers with Vault whitelist`, this.callers.map(w => w.address));
36
37
  const skipped = allWallets.filter(w => !allowedSet.has(w.address.toLowerCase()));
37
38
  if (skipped.length > 0) {
38
- (0, dist_1.log_warn)(`CallerManager: skipped ${skipped.length} wallets not in Vault whitelist`, skipped.map(w => w.address));
39
+ logger.warn(`CallerManager: skipped ${skipped.length} wallets not in Vault whitelist`, skipped.map(w => w.address));
39
40
  }
40
41
  }
41
42
  else {
42
43
  this.callers = allWallets;
43
- (0, dist_1.log_warn)(`CallerManager: Vault whitelist not found in Redis (${vaultCallersKey}), using all ${this.callers.length} loaded wallets`);
44
+ logger.warn(`CallerManager: Vault whitelist not found in Redis (${vaultCallersKey}), using all ${this.callers.length} loaded wallets`);
44
45
  }
45
46
  if (this.callers.length === 0) {
46
47
  throw new Error('CallerManager: no valid callers after whitelist matching');
@@ -50,23 +51,21 @@ class CallerManager {
50
51
  const nonceKey = this.getNonceRedisKey();
51
52
  const existing = yield this.redis.hgetvalue(nonceKey, address);
52
53
  if (existing === null || existing === undefined) {
53
- (0, dist_1.log_warn)(`Caller ${caller.address} nonce not found in Redis, stream-trade may not be running`);
54
+ logger.warn(`Caller ${caller.address} nonce not found in Redis, stream-trade may not be running`);
54
55
  }
55
56
  else {
56
- (0, dist_1.log_info)(`Caller ${caller.address} nonce=${existing} (from Redis)`);
57
+ logger.info(`Caller ${caller.address} nonce=${existing} (from Redis)`);
57
58
  }
58
59
  })));
59
- (0, dist_1.log_info)(`CallerManager initialized, ${this.callers.length} active callers`, this.callers.map(w => w.address));
60
+ logger.info(`CallerManager initialized, ${this.callers.length} active callers`, this.callers.map(w => w.address));
60
61
  });
61
62
  }
62
63
  acquireCaller() {
63
64
  return __awaiter(this, void 0, void 0, function* () {
64
- const startTime = Date.now();
65
65
  const sortedCallers = yield this.getCallersSortedByLRU();
66
66
  const caller = sortedCallers[0];
67
67
  const nonce = yield this.getNonce(caller.address);
68
68
  yield this.updateLastUsed(caller.address);
69
- (0, dist_1.log_info)(`acquireCaller: ${caller.address}, nonce=${nonce}, took ${Date.now() - startTime}ms`);
70
69
  return { wallet: caller, nonce };
71
70
  });
72
71
  }
@@ -75,7 +74,7 @@ class CallerManager {
75
74
  const current = yield this.getNonce(address);
76
75
  if (confirmedNonce > current) {
77
76
  yield this.setNonce(address, confirmedNonce);
78
- (0, dist_1.log_info)(`confirmNonce: ${address}, ${current} → ${confirmedNonce}`);
77
+ logger.info(`confirmNonce: ${address}, ${current} → ${confirmedNonce}`);
79
78
  }
80
79
  });
81
80
  }
@@ -84,7 +83,7 @@ class CallerManager {
84
83
  const current = yield this.getNonce(address);
85
84
  if (nonce !== current) {
86
85
  yield this.setNonce(address, nonce);
87
- (0, dist_1.log_info)(`forceSetNonce: ${address}, ${current} → ${nonce}`);
86
+ logger.info(`forceSetNonce: ${address}, ${current} → ${nonce}`);
88
87
  }
89
88
  });
90
89
  }
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.BaseTxResultChecker = exports.TradeResultSubscriber = void 0;
13
13
  const ttd_core_1 = require("@clonegod/ttd-core");
14
+ const logger = (0, ttd_core_1.createLogger)(__filename);
14
15
  const trade_1 = require("@clonegod/ttd-core/dist/trade");
15
16
  const ethers_compat_1 = require("../../utils/ethers_compat");
16
17
  class TradeResultSubscriber {
@@ -57,7 +58,7 @@ class TradeResultSubscriber {
57
58
  this.ws.send(JSON.stringify({ address: w.public_key }));
58
59
  }
59
60
  }
60
- (0, ttd_core_1.log_info)(`TradeResultSubscriber connected: ${wsUrl}`);
61
+ logger.info(`TradeResultSubscriber connected: ${wsUrl}`);
61
62
  });
62
63
  this.ws.onMessage((msg) => {
63
64
  if (msg.type !== 'TradeResult' || !msg.data)
@@ -91,13 +92,13 @@ class BaseTxResultChecker extends trade_1.AbstractTransactionResultCheck {
91
92
  return;
92
93
  const intervalId = setInterval(() => __awaiter(this, void 0, void 0, function* () {
93
94
  this.check_count += 1;
94
- (0, ttd_core_1.log_info)(`check transaction start: seq=[${this.check_count}], txhash=${this.txid}, trace_id=${this.trace_id}`);
95
+ logger.info(`check transaction start: seq=[${this.check_count}], txhash=${this.txid}, trace_id=${this.trace_id}`);
95
96
  try {
96
97
  if (Date.now() - check_start_time < check_timeout) {
97
98
  let txReceipt = yield this.provider.getTransactionReceipt(this.txid);
98
99
  if (!txReceipt)
99
100
  return;
100
- (0, ttd_core_1.log_info)(`Received transaction result via polling: ${this.txid}`);
101
+ logger.info(`Received transaction result via polling: ${this.txid}`);
101
102
  clearInterval(intervalId);
102
103
  yield this.processTransactionResult(txReceipt, 'interval');
103
104
  }
@@ -107,7 +108,7 @@ class BaseTxResultChecker extends trade_1.AbstractTransactionResultCheck {
107
108
  }
108
109
  catch (err) {
109
110
  clearInterval(intervalId);
110
- (0, ttd_core_1.log_error)('parse transaction error!', err);
111
+ logger.error('parse transaction error!', err);
111
112
  }
112
113
  }), check_interval);
113
114
  this.intervalId = intervalId;
@@ -115,11 +116,11 @@ class BaseTxResultChecker extends trade_1.AbstractTransactionResultCheck {
115
116
  }
116
117
  on_subscibe_transaction() {
117
118
  return __awaiter(this, void 0, void 0, function* () {
118
- (0, ttd_core_1.log_info)(`Subscribing trade result, txid=${this.txid}`);
119
+ logger.info(`Subscribing trade result, txid=${this.txid}`);
119
120
  TradeResultSubscriber.getInstance().listen(this.txid, (receipt) => {
120
- (0, ttd_core_1.log_info)(`Received transaction result via stream-trade: ${this.txid}`);
121
+ logger.info(`Received transaction result via stream-trade: ${this.txid}`);
121
122
  this.processTransactionResult(receipt, 'websocket')
122
- .catch(err => (0, ttd_core_1.log_error)(`Error processing trade result: ${this.txid}`, err));
123
+ .catch(err => logger.error(`Error processing trade result: ${this.txid}`, err));
123
124
  });
124
125
  });
125
126
  }
@@ -129,7 +130,7 @@ class BaseTxResultChecker extends trade_1.AbstractTransactionResultCheck {
129
130
  (0, ttd_core_1.writeFile)(`./dist/tx_receipt_${this.txid}_${source}.json`, JSON.stringify(txReceipt, null, 2));
130
131
  }
131
132
  if (this.trade_result_already_processed) {
132
- (0, ttd_core_1.log_warn)(`trade_result_already_processed, ignore result from ${source}!`);
133
+ logger.warn(`trade_result_already_processed, ignore result from ${source}!`);
133
134
  return;
134
135
  }
135
136
  const parser = this.createParser();
@@ -2,3 +2,4 @@ export * from './parse';
2
2
  export * from './check';
3
3
  export * from './caller_manager';
4
4
  export * from './abstract_dex_trade';
5
+ export * from './trade_trace';
@@ -18,3 +18,4 @@ __exportStar(require("./parse"), exports);
18
18
  __exportStar(require("./check"), exports);
19
19
  __exportStar(require("./caller_manager"), exports);
20
20
  __exportStar(require("./abstract_dex_trade"), exports);
21
+ __exportStar(require("./trade_trace"), exports);
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.BaseTxParser = void 0;
13
13
  const ttd_core_1 = require("@clonegod/ttd-core");
14
+ const logger = (0, ttd_core_1.createLogger)(__filename);
14
15
  const ethers_1 = require("ethers");
15
16
  const ethers_compat_1 = require("../../utils/ethers_compat");
16
17
  class BaseTxParser {
@@ -67,7 +68,7 @@ class BaseTxParser {
67
68
  };
68
69
  }
69
70
  catch (error) {
70
- (0, ttd_core_1.log_error)('calculateGasFee error:', error);
71
+ logger.error('calculateGasFee error:', error);
71
72
  return {
72
73
  base_fee: 0,
73
74
  priority_fee: 0,
@@ -0,0 +1,16 @@
1
+ export declare class TradeTrace {
2
+ readonly orderId: string;
3
+ readonly pair: string;
4
+ readonly direction: string;
5
+ private startTime;
6
+ private marks;
7
+ private data;
8
+ private providers;
9
+ private error;
10
+ constructor(orderId: string, pair?: string, direction?: string);
11
+ mark(name: string): void;
12
+ set(key: string, value: any): void;
13
+ markProvider(name: string, ok: boolean, error?: string): void;
14
+ markError(stage: string, message: string): void;
15
+ flush(): void;
16
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TradeTrace = void 0;
4
+ const ttd_core_1 = require("@clonegod/ttd-core");
5
+ const logger = (0, ttd_core_1.createLogger)(__filename);
6
+ class TradeTrace {
7
+ constructor(orderId, pair = '', direction = '') {
8
+ this.orderId = orderId;
9
+ this.pair = pair;
10
+ this.direction = direction;
11
+ this.marks = [];
12
+ this.data = {};
13
+ this.providers = [];
14
+ this.error = null;
15
+ this.startTime = Date.now();
16
+ }
17
+ mark(name) {
18
+ this.marks.push({ name, elapsed: Date.now() - this.startTime });
19
+ }
20
+ set(key, value) {
21
+ this.data[key] = value;
22
+ }
23
+ markProvider(name, ok, error) {
24
+ this.providers.push({ name, ok, elapsed: Date.now() - this.startTime, error });
25
+ }
26
+ markError(stage, message) {
27
+ this.error = { stage, message };
28
+ }
29
+ flush() {
30
+ const total = Date.now() - this.startTime;
31
+ const timeline = this.marks.map(m => `${m.name}=${m.elapsed}ms`).join(' | ');
32
+ const providerStatus = this.providers
33
+ .map(p => `${p.name}=${p.ok ? '✓' : '✗'}${p.ok ? '' : '(' + (p.error || 'err') + ')'}`)
34
+ .join(' ');
35
+ if (this.error) {
36
+ logger.info(`[TRADE FAILED] ${this.orderId} | ${this.pair} ${this.direction}`, Object.assign({ timeline, error_stage: this.error.stage, error: this.error.message, total_ms: total }, this.data));
37
+ }
38
+ else {
39
+ logger.info(`[TRADE OK] ${this.orderId} | ${this.pair} ${this.direction}`, Object.assign({ timeline, providers: providerStatus, total_ms: total }, this.data));
40
+ }
41
+ }
42
+ }
43
+ exports.TradeTrace = TradeTrace;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clonegod/ttd-bsc-common",
3
- "version": "3.0.29",
3
+ "version": "3.0.30",
4
4
  "description": "BSC common library",
5
5
  "license": "UNLICENSED",
6
6
  "main": "dist/index.js",
@@ -14,7 +14,7 @@
14
14
  "push": "npm run build && npm publish"
15
15
  },
16
16
  "dependencies": {
17
- "@clonegod/ttd-core": "3.0.8",
17
+ "@clonegod/ttd-core": "3.0.11",
18
18
  "@clonegod/ttd-bsc-send-tx": "2.0.3",
19
19
  "axios": "^1.12.0",
20
20
  "dotenv": "^16.4.7",