@clonegod/ttd-bsc-common 3.0.31 → 3.0.33
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/redis/redis_client.d.ts +1 -0
- package/dist/redis/redis_client.js +6 -0
- package/dist/send-tx/types.d.ts +1 -1
- package/dist/trade/abstract_dex_trade.d.ts +1 -1
- package/dist/trade/abstract_dex_trade.js +5 -5
- package/dist/trade/caller_manager.d.ts +0 -2
- package/dist/trade/caller_manager.js +25 -29
- package/dist/trade/check/base_tx_result_checker.d.ts +4 -0
- package/dist/trade/check/base_tx_result_checker.js +31 -12
- package/dist/trade/trade_trace.d.ts +1 -2
- package/dist/trade/trade_trace.js +15 -11
- package/dist/utils/fast_signer.d.ts +1 -0
- package/dist/utils/fast_signer.js +53 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/package.json +5 -3
|
@@ -17,6 +17,7 @@ export declare class SimpleRedisClient {
|
|
|
17
17
|
hgetvalue(key: string, field: string): Promise<any>;
|
|
18
18
|
hkeys(key: string): Promise<any>;
|
|
19
19
|
hgetall(key: string): Promise<any>;
|
|
20
|
+
hmget(key: string, fields: string[]): Promise<(string | null)[]>;
|
|
20
21
|
lrange(key: string, start?: number, stop?: number): Promise<string[]>;
|
|
21
22
|
del(key: string, field?: string): Promise<any>;
|
|
22
23
|
}
|
|
@@ -136,6 +136,12 @@ class SimpleRedisClient {
|
|
|
136
136
|
return yield redisClient.hGetAll(key);
|
|
137
137
|
});
|
|
138
138
|
}
|
|
139
|
+
hmget(key, fields) {
|
|
140
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
141
|
+
const redisClient = yield this.getRedisClient();
|
|
142
|
+
return yield redisClient.hmGet(key, fields);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
139
145
|
lrange(key_1) {
|
|
140
146
|
return __awaiter(this, arguments, void 0, function* (key, start = 0, stop = -1) {
|
|
141
147
|
const redisClient = yield this.getRedisClient();
|
package/dist/send-tx/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { TradeTrace } from '../trade/trade_trace';
|
|
2
2
|
export interface ITransactionSender {
|
|
3
|
-
sendTransaction(signedMainTx: string,
|
|
3
|
+
sendTransaction(signedMainTx: string, tipTxMap: Map<string, string>, order_trace_id: string, pair?: string, only_bundle?: boolean, trace?: Pick<TradeTrace, 'mark'>): Promise<string[]>;
|
|
4
4
|
}
|
|
@@ -36,6 +36,6 @@ export declare abstract class AbstractDexTrade extends AbastrcatTrade {
|
|
|
36
36
|
inputToken: any;
|
|
37
37
|
outputToken: any;
|
|
38
38
|
};
|
|
39
|
-
protected calculateAmountOutMin(context: TradeContext,
|
|
39
|
+
protected calculateAmountOutMin(context: TradeContext, _inputToken: any, outputToken: any): ethers.BigNumber;
|
|
40
40
|
private extractNonceFromErrorMsg;
|
|
41
41
|
}
|
|
@@ -57,6 +57,7 @@ const base_tx_result_checker_1 = require("./check/base_tx_result_checker");
|
|
|
57
57
|
const redis_1 = require("../redis");
|
|
58
58
|
const trade_direction_1 = require("../utils/trade_direction");
|
|
59
59
|
const ethers_compat_1 = require("../utils/ethers_compat");
|
|
60
|
+
const fast_signer_1 = require("../utils/fast_signer");
|
|
60
61
|
const trade_trace_1 = require("./trade_trace");
|
|
61
62
|
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
62
63
|
function buildTradeConfig() {
|
|
@@ -93,6 +94,7 @@ class AbstractDexTrade extends ttd_core_1.AbastrcatTrade {
|
|
|
93
94
|
init(transactionSender) {
|
|
94
95
|
return __awaiter(this, void 0, void 0, function* () {
|
|
95
96
|
var _a, _b;
|
|
97
|
+
(0, fast_signer_1.patchEthersV5Signer)();
|
|
96
98
|
this.provider = new ethers_compat_1.ethersCompat.JsonRpcProvider(this.chainConfig.rpcEndpoint);
|
|
97
99
|
if (transactionSender) {
|
|
98
100
|
this.transactionSender = transactionSender;
|
|
@@ -125,6 +127,7 @@ class AbstractDexTrade extends ttd_core_1.AbastrcatTrade {
|
|
|
125
127
|
const direction = isBuy ? 'BUY' : 'SELL';
|
|
126
128
|
const { inputToken, outputToken } = this.determineInputOutputTokens(order_msg, pool_info);
|
|
127
129
|
const amountOutMin = this.calculateAmountOutMin(context, inputToken, outputToken);
|
|
130
|
+
context._precomputed = { inputToken, outputToken, amountOutMin };
|
|
128
131
|
const trace = new trade_trace_1.TradeTrace(order_trace_id, pair, direction);
|
|
129
132
|
trace.set('input', `${amount} ${inputToken.symbol}`);
|
|
130
133
|
trace.set('outputMin', `${ethers_compat_1.ethersCompat.formatUnits(amountOutMin, outputToken.decimals)} ${outputToken.symbol}`);
|
|
@@ -188,10 +191,7 @@ class AbstractDexTrade extends ttd_core_1.AbastrcatTrade {
|
|
|
188
191
|
trace.set('gas', realGasPriceGwei);
|
|
189
192
|
trace.set('tip', transfer_amount_gwei);
|
|
190
193
|
const only_bundle = order_msg.is_dex_maker;
|
|
191
|
-
|
|
192
|
-
return tipTxMap.get(eoa_address) || (yield this.buildTipTransferTx(eoa_address, transfer_amount_gwei, realGasPriceGwei, tipNonce, caller));
|
|
193
|
-
});
|
|
194
|
-
yield this.transactionSender.sendTransaction(signedMainTx, eoa_tip_transaction, order_trace_id, pair, only_bundle, trace);
|
|
194
|
+
yield this.transactionSender.sendTransaction(signedMainTx, tipTxMap, order_trace_id, pair, only_bundle, trace);
|
|
195
195
|
trace.mark('sent');
|
|
196
196
|
trace.flush();
|
|
197
197
|
try {
|
|
@@ -276,7 +276,7 @@ class AbstractDexTrade extends ttd_core_1.AbastrcatTrade {
|
|
|
276
276
|
const { inputToken, outputToken } = (0, trade_direction_1.resolveTradeDirection)(pool_info, order_msg.isBuy);
|
|
277
277
|
return { inputToken, outputToken };
|
|
278
278
|
}
|
|
279
|
-
calculateAmountOutMin(context,
|
|
279
|
+
calculateAmountOutMin(context, _inputToken, outputToken) {
|
|
280
280
|
const { price_msg, slippage_bps, order_msg } = context;
|
|
281
281
|
const { isBuy } = order_msg;
|
|
282
282
|
const slippage = slippage_bps / 10000;
|
|
@@ -71,10 +71,31 @@ class CallerManager {
|
|
|
71
71
|
}
|
|
72
72
|
acquireCaller() {
|
|
73
73
|
return __awaiter(this, void 0, void 0, function* () {
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
const
|
|
77
|
-
yield
|
|
74
|
+
const addresses = this.callers.map(w => w.address.toLowerCase());
|
|
75
|
+
const lastUsedKey = this.getLastUsedRedisKey();
|
|
76
|
+
const nonceKey = this.getNonceRedisKey();
|
|
77
|
+
const [lastUsedData, nonceValues] = yield Promise.all([
|
|
78
|
+
this.redis.hgetall(lastUsedKey),
|
|
79
|
+
this.redis.hmget(nonceKey, addresses),
|
|
80
|
+
]);
|
|
81
|
+
let selectedIdx = 0;
|
|
82
|
+
let minLastUsed = Number.MAX_SAFE_INTEGER;
|
|
83
|
+
for (let i = 0; i < this.callers.length; i++) {
|
|
84
|
+
const redisTs = parseInt((lastUsedData === null || lastUsedData === void 0 ? void 0 : lastUsedData[addresses[i]]) || '0', 10);
|
|
85
|
+
if (redisTs < minLastUsed) {
|
|
86
|
+
minLastUsed = redisTs;
|
|
87
|
+
selectedIdx = i;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const caller = this.callers[selectedIdx];
|
|
91
|
+
const callerAddr = addresses[selectedIdx];
|
|
92
|
+
const nonceStr = nonceValues[selectedIdx];
|
|
93
|
+
if (nonceStr === null || nonceStr === undefined) {
|
|
94
|
+
throw new Error(`Caller ${caller.address} nonce not found in Redis, stream-trade may not be running`);
|
|
95
|
+
}
|
|
96
|
+
const nonce = parseInt(nonceStr, 10);
|
|
97
|
+
this.redis.hsetValue(lastUsedKey, callerAddr, String(Date.now()), 24 * 60 * 60)
|
|
98
|
+
.catch(err => logger.warn(`updateLastUsed failed: ${err.message}`));
|
|
78
99
|
return { wallet: caller, nonce };
|
|
79
100
|
});
|
|
80
101
|
}
|
|
@@ -124,30 +145,5 @@ class CallerManager {
|
|
|
124
145
|
yield this.redis.hsetValue(nonceKey, address.toLowerCase(), String(nonce), 24 * 60 * 60);
|
|
125
146
|
});
|
|
126
147
|
}
|
|
127
|
-
getCallersSortedByLRU() {
|
|
128
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
129
|
-
const lastUsedKey = this.getLastUsedRedisKey();
|
|
130
|
-
const lastUsedData = yield this.redis.hgetall(lastUsedKey);
|
|
131
|
-
const callersWithTime = this.callers.map(caller => {
|
|
132
|
-
let lastUsedAt = 0;
|
|
133
|
-
const data = lastUsedData === null || lastUsedData === void 0 ? void 0 : lastUsedData[caller.address.toLowerCase()];
|
|
134
|
-
if (data) {
|
|
135
|
-
try {
|
|
136
|
-
lastUsedAt = parseInt(data, 10) || 0;
|
|
137
|
-
}
|
|
138
|
-
catch (_a) { }
|
|
139
|
-
}
|
|
140
|
-
return { caller, lastUsedAt };
|
|
141
|
-
});
|
|
142
|
-
callersWithTime.sort((a, b) => a.lastUsedAt - b.lastUsedAt);
|
|
143
|
-
return callersWithTime.map(item => item.caller);
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
updateLastUsed(address) {
|
|
147
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
148
|
-
const lastUsedKey = this.getLastUsedRedisKey();
|
|
149
|
-
yield this.redis.hsetValue(lastUsedKey, address.toLowerCase(), String(Date.now()), 24 * 60 * 60);
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
148
|
}
|
|
153
149
|
exports.CallerManager = CallerManager;
|
|
@@ -10,6 +10,10 @@ export declare class TradeResultSubscriber {
|
|
|
10
10
|
listen(txHash: string, callback: (receipt: any) => void, timeoutMs?: number): void;
|
|
11
11
|
remove(txHash: string): void;
|
|
12
12
|
sendNonceWatch(caller: string, txHash: string): void;
|
|
13
|
+
private cachedSubscriptions;
|
|
14
|
+
private cachedClientName;
|
|
15
|
+
private getSubscriptions;
|
|
16
|
+
private getClientName;
|
|
13
17
|
private ensureConnected;
|
|
14
18
|
}
|
|
15
19
|
export declare abstract class BaseTxResultChecker extends AbstractTransactionResultCheck {
|
|
@@ -19,6 +19,8 @@ class TradeResultSubscriber {
|
|
|
19
19
|
this.ws = null;
|
|
20
20
|
this.connected = false;
|
|
21
21
|
this.listeners = new Map();
|
|
22
|
+
this.cachedSubscriptions = null;
|
|
23
|
+
this.cachedClientName = null;
|
|
22
24
|
}
|
|
23
25
|
static getInstance() {
|
|
24
26
|
if (!TradeResultSubscriber.instance) {
|
|
@@ -43,26 +45,43 @@ class TradeResultSubscriber {
|
|
|
43
45
|
this.ws.send(JSON.stringify({ type: 'nonceWatch', caller, txHash }));
|
|
44
46
|
}
|
|
45
47
|
}
|
|
48
|
+
getSubscriptions() {
|
|
49
|
+
if (this.cachedSubscriptions)
|
|
50
|
+
return this.cachedSubscriptions;
|
|
51
|
+
const groupIds = (process.env.TRADE_GROUP_ID || process.env.VAULT_GROUP_ID || '').split(',').map(s => s.trim()).filter(Boolean);
|
|
52
|
+
const subs = [];
|
|
53
|
+
for (const gid of groupIds) {
|
|
54
|
+
const w = (0, ttd_core_1.load_wallet)(gid, true);
|
|
55
|
+
if (w.public_key) {
|
|
56
|
+
subs.push({ address: w.public_key, groupId: gid });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
this.cachedSubscriptions = subs;
|
|
60
|
+
return subs;
|
|
61
|
+
}
|
|
62
|
+
getClientName() {
|
|
63
|
+
if (this.cachedClientName)
|
|
64
|
+
return this.cachedClientName;
|
|
65
|
+
this.cachedClientName = process.env.APP_NAME
|
|
66
|
+
|| process.env.name
|
|
67
|
+
|| (process.env.pm_id ? `pm2-${process.env.pm_id}` : null)
|
|
68
|
+
|| `pid-${process.pid}`;
|
|
69
|
+
return this.cachedClientName;
|
|
70
|
+
}
|
|
46
71
|
ensureConnected() {
|
|
47
|
-
if (this.ws
|
|
72
|
+
if (this.ws)
|
|
48
73
|
return;
|
|
49
74
|
const host = process.env.STREAM_TRADE_WS_HOST || '127.0.0.1';
|
|
50
75
|
const wsUrl = `ws://${host}:${ttd_core_1.SERVICE_PORT.STREAM_TRADE_WS}`;
|
|
51
76
|
this.ws = new ttd_core_1.WebSocketClient(wsUrl);
|
|
52
|
-
const clientName = process.env.APP_NAME
|
|
53
|
-
|| process.env.name
|
|
54
|
-
|| (process.env.pm_id ? `pm2-${process.env.pm_id}` : null)
|
|
55
|
-
|| `pid-${process.pid}`;
|
|
56
77
|
this.ws.onOpen(() => {
|
|
57
78
|
this.connected = true;
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
this.ws.send(JSON.stringify({ address: w.public_key, groupId: gid, clientName }));
|
|
63
|
-
}
|
|
79
|
+
const subs = this.getSubscriptions();
|
|
80
|
+
const clientName = this.getClientName();
|
|
81
|
+
for (const { address, groupId } of subs) {
|
|
82
|
+
this.ws.send(JSON.stringify({ address, groupId, clientName }));
|
|
64
83
|
}
|
|
65
|
-
logger.info(`TradeResultSubscriber connected: ${wsUrl}`);
|
|
84
|
+
logger.info(`TradeResultSubscriber connected: ${wsUrl}, subscribed=${subs.length}`);
|
|
66
85
|
});
|
|
67
86
|
this.ws.onMessage((msg) => {
|
|
68
87
|
if (msg.type !== 'TradeResult' || !msg.data)
|
|
@@ -5,12 +5,11 @@ export declare class TradeTrace {
|
|
|
5
5
|
private startTime;
|
|
6
6
|
private marks;
|
|
7
7
|
private data;
|
|
8
|
-
private providers;
|
|
9
8
|
private error;
|
|
10
9
|
constructor(orderId: string, pair?: string, direction?: string);
|
|
11
10
|
mark(name: string): void;
|
|
12
11
|
set(key: string, value: any): void;
|
|
13
|
-
markProvider(name: string, ok: boolean, error?: string): void;
|
|
14
12
|
markError(stage: string, message: string): void;
|
|
13
|
+
private buildTimeline;
|
|
15
14
|
flush(): void;
|
|
16
15
|
}
|
|
@@ -10,7 +10,6 @@ class TradeTrace {
|
|
|
10
10
|
this.direction = direction;
|
|
11
11
|
this.marks = [];
|
|
12
12
|
this.data = {};
|
|
13
|
-
this.providers = [];
|
|
14
13
|
this.error = null;
|
|
15
14
|
this.startTime = Date.now();
|
|
16
15
|
}
|
|
@@ -20,23 +19,28 @@ class TradeTrace {
|
|
|
20
19
|
set(key, value) {
|
|
21
20
|
this.data[key] = value;
|
|
22
21
|
}
|
|
23
|
-
markProvider(name, ok, error) {
|
|
24
|
-
this.providers.push({ name, ok, elapsed: Date.now() - this.startTime, error });
|
|
25
|
-
}
|
|
26
22
|
markError(stage, message) {
|
|
27
23
|
this.error = { stage, message };
|
|
28
24
|
}
|
|
25
|
+
buildTimeline() {
|
|
26
|
+
if (this.marks.length === 0)
|
|
27
|
+
return 'recv';
|
|
28
|
+
let prev = 0;
|
|
29
|
+
const parts = this.marks.map(m => {
|
|
30
|
+
const delta = m.elapsed - prev;
|
|
31
|
+
prev = m.elapsed;
|
|
32
|
+
return `${m.name}(${delta}ms)`;
|
|
33
|
+
});
|
|
34
|
+
const total = this.marks[this.marks.length - 1].elapsed;
|
|
35
|
+
return `recv -> ${parts.join(' -> ')} = ${total}ms`;
|
|
36
|
+
}
|
|
29
37
|
flush() {
|
|
30
|
-
const
|
|
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(' ');
|
|
38
|
+
const timeline = this.buildTimeline();
|
|
35
39
|
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
|
|
40
|
+
logger.info(`[TRADE FAILED] ${this.orderId} | ${this.pair} ${this.direction}`, Object.assign({ timeline, error_stage: this.error.stage, error: this.error.message }, this.data));
|
|
37
41
|
}
|
|
38
42
|
else {
|
|
39
|
-
logger.info(`[TRADE OK] ${this.orderId} | ${this.pair} ${this.direction}`, Object.assign({ timeline
|
|
43
|
+
logger.info(`[TRADE OK] ${this.orderId} | ${this.pair} ${this.direction}`, Object.assign({ timeline }, this.data));
|
|
40
44
|
}
|
|
41
45
|
}
|
|
42
46
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function patchEthersV5Signer(): boolean;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.patchEthersV5Signer = patchEthersV5Signer;
|
|
4
|
+
let patched = false;
|
|
5
|
+
function patchEthersV5Signer() {
|
|
6
|
+
if (patched)
|
|
7
|
+
return true;
|
|
8
|
+
let secp;
|
|
9
|
+
try {
|
|
10
|
+
secp = require('secp256k1');
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
console.warn('[fast_signer] secp256k1 native module not found, skipping patch', err);
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
let SigningKey;
|
|
17
|
+
let arrayify;
|
|
18
|
+
let hexZeroPad;
|
|
19
|
+
let splitSignature;
|
|
20
|
+
try {
|
|
21
|
+
const signingKeyModule = require('@ethersproject/signing-key');
|
|
22
|
+
const bytesModule = require('@ethersproject/bytes');
|
|
23
|
+
SigningKey = signingKeyModule.SigningKey;
|
|
24
|
+
arrayify = bytesModule.arrayify;
|
|
25
|
+
hexZeroPad = bytesModule.hexZeroPad;
|
|
26
|
+
splitSignature = bytesModule.splitSignature;
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
console.warn('[fast_signer] @ethersproject/signing-key not found, skipping patch', err);
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
const originalSignDigest = SigningKey.prototype.signDigest;
|
|
33
|
+
SigningKey.prototype.signDigest = function (digest) {
|
|
34
|
+
const privKeyBytes = arrayify(this.privateKey);
|
|
35
|
+
const digestBytes = arrayify(digest);
|
|
36
|
+
if (digestBytes.length !== 32) {
|
|
37
|
+
return originalSignDigest.call(this, digest);
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
const { signature, recid } = secp.ecdsaSign(digestBytes, privKeyBytes);
|
|
41
|
+
const r = hexZeroPad('0x' + Buffer.from(signature.slice(0, 32)).toString('hex'), 32);
|
|
42
|
+
const s = hexZeroPad('0x' + Buffer.from(signature.slice(32, 64)).toString('hex'), 32);
|
|
43
|
+
return splitSignature({ recoveryParam: recid, r, s });
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
console.warn('[fast_signer] native sign failed, fallback to elliptic.js', err);
|
|
47
|
+
return originalSignDigest.call(this, digest);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
patched = true;
|
|
51
|
+
console.log('[fast_signer] ethers v5 SigningKey patched with native secp256k1');
|
|
52
|
+
return true;
|
|
53
|
+
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from './gas_helper';
|
|
|
3
3
|
export * from './trade_direction';
|
|
4
4
|
export * from './pool_filter';
|
|
5
5
|
export * from './ethers_compat';
|
|
6
|
+
export * from './fast_signer';
|
|
6
7
|
export declare const sleep: (ms: number) => Promise<void>;
|
|
7
8
|
export declare const formatPrice: (price: number, precision?: number) => string;
|
|
8
9
|
export declare const formatUnits: (value: any, decimals: number) => Decimal;
|
package/dist/utils/index.js
CHANGED
|
@@ -24,6 +24,7 @@ __exportStar(require("./gas_helper"), exports);
|
|
|
24
24
|
__exportStar(require("./trade_direction"), exports);
|
|
25
25
|
__exportStar(require("./pool_filter"), exports);
|
|
26
26
|
__exportStar(require("./ethers_compat"), exports);
|
|
27
|
+
__exportStar(require("./fast_signer"), exports);
|
|
27
28
|
const sleep = (ms) => {
|
|
28
29
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
29
30
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clonegod/ttd-bsc-common",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.33",
|
|
4
4
|
"description": "BSC common library",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,14 +14,16 @@
|
|
|
14
14
|
"push": "npm run build && npm publish"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@clonegod/ttd-core": "3.0.
|
|
17
|
+
"@clonegod/ttd-core": "3.0.12",
|
|
18
18
|
"@clonegod/ttd-bsc-send-tx": "2.0.3",
|
|
19
19
|
"axios": "^1.12.0",
|
|
20
20
|
"dotenv": "^16.4.7",
|
|
21
|
-
"ethers": "^5.8.0"
|
|
21
|
+
"ethers": "^5.8.0",
|
|
22
|
+
"secp256k1": "^5.0.1"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
25
|
"@types/node": "^22.14.0",
|
|
26
|
+
"@types/secp256k1": "^4.0.6",
|
|
25
27
|
"typescript": "^5.8.2"
|
|
26
28
|
},
|
|
27
29
|
"overrides": {},
|