@clonegod/ttd-bsc-common 1.0.0

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.
Files changed (73) hide show
  1. package/dist/common/abi.d.ts +31 -0
  2. package/dist/common/abi.js +68 -0
  3. package/dist/common/constants.d.ts +21 -0
  4. package/dist/common/constants.js +37 -0
  5. package/dist/common/index.d.ts +2 -0
  6. package/dist/common/index.js +18 -0
  7. package/dist/config/bsc_env_args.d.ts +11 -0
  8. package/dist/config/bsc_env_args.js +19 -0
  9. package/dist/config/env_args.d.ts +13 -0
  10. package/dist/config/env_args.js +23 -0
  11. package/dist/config/index.d.ts +1 -0
  12. package/dist/config/index.js +17 -0
  13. package/dist/constants/networks.d.ts +10 -0
  14. package/dist/constants/networks.js +28 -0
  15. package/dist/index.d.ts +6 -0
  16. package/dist/index.js +22 -0
  17. package/dist/providers/index.d.ts +9 -0
  18. package/dist/providers/index.js +21 -0
  19. package/dist/quote/event/index.d.ts +1 -0
  20. package/dist/quote/event/index.js +17 -0
  21. package/dist/quote/event/pool_event_listener.d.ts +39 -0
  22. package/dist/quote/event/pool_event_listener.js +231 -0
  23. package/dist/quote/event/verify_clmm_swap_event.d.ts +1 -0
  24. package/dist/quote/event/verify_clmm_swap_event.js +178 -0
  25. package/dist/quote/index.d.ts +2 -0
  26. package/dist/quote/index.js +18 -0
  27. package/dist/quote/pricing/index.d.ts +2 -0
  28. package/dist/quote/pricing/index.js +18 -0
  29. package/dist/quote/pricing/pool.d.ts +13 -0
  30. package/dist/quote/pricing/pool.js +21 -0
  31. package/dist/quote/pricing/token_price_cache.d.ts +9 -0
  32. package/dist/quote/pricing/token_price_cache.js +40 -0
  33. package/dist/trade/abstract_dex_trade.d.ts +27 -0
  34. package/dist/trade/abstract_dex_trade.js +152 -0
  35. package/dist/trade/check/index.d.ts +1 -0
  36. package/dist/trade/check/index.js +17 -0
  37. package/dist/trade/check/tx_websocket_manager.d.ts +23 -0
  38. package/dist/trade/check/tx_websocket_manager.js +119 -0
  39. package/dist/trade/index.d.ts +4 -0
  40. package/dist/trade/index.js +20 -0
  41. package/dist/trade/parse/abstract_parser.d.ts +8 -0
  42. package/dist/trade/parse/abstract_parser.js +2 -0
  43. package/dist/trade/parse/base_parser.d.ts +30 -0
  44. package/dist/trade/parse/base_parser.js +108 -0
  45. package/dist/trade/parse/index.d.ts +1 -0
  46. package/dist/trade/parse/index.js +5 -0
  47. package/dist/trade/send/48club.d.ts +18 -0
  48. package/dist/trade/send/48club.js +97 -0
  49. package/dist/trade/send/blockrazor.d.ts +7 -0
  50. package/dist/trade/send/blockrazor.js +79 -0
  51. package/dist/trade/send/bsc_rpc.d.ts +6 -0
  52. package/dist/trade/send/bsc_rpc.js +43 -0
  53. package/dist/trade/send/index.d.ts +5 -0
  54. package/dist/trade/send/index.js +23 -0
  55. package/dist/trade/send/send_tx.d.ts +8 -0
  56. package/dist/trade/send/send_tx.js +85 -0
  57. package/dist/types/config_types.d.ts +28 -0
  58. package/dist/types/config_types.js +2 -0
  59. package/dist/types/event_types.d.ts +30 -0
  60. package/dist/types/event_types.js +2 -0
  61. package/dist/types/index.d.ts +4 -0
  62. package/dist/types/index.js +20 -0
  63. package/dist/types/quote_types.d.ts +27 -0
  64. package/dist/types/quote_types.js +2 -0
  65. package/dist/types/trade_types.d.ts +38 -0
  66. package/dist/types/trade_types.js +8 -0
  67. package/dist/utils/gas_helper.d.ts +5 -0
  68. package/dist/utils/gas_helper.js +72 -0
  69. package/dist/utils/index.d.ts +7 -0
  70. package/dist/utils/index.js +43 -0
  71. package/dist/utils/redis_lock.d.ts +14 -0
  72. package/dist/utils/redis_lock.js +100 -0
  73. package/package.json +30 -0
@@ -0,0 +1,79 @@
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
+ exports.BlockRazorTrade = void 0;
16
+ const dist_1 = require("@clonegod/ttd-core/dist");
17
+ const axios_1 = __importDefault(require("axios"));
18
+ class BlockRazorTrade {
19
+ constructor() {
20
+ this.rpcUrl = process.env.BLOCKRAZOR_RPC_URL || 'https://rpc.blockrazor.builders';
21
+ this.authToken = process.env.BLOCKRAZOR_AUTH_TOKEN || '';
22
+ }
23
+ sendPrivateTransaction(signedTx) {
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ try {
26
+ const response = yield axios_1.default.post(this.rpcUrl, {
27
+ jsonrpc: "2.0",
28
+ id: "1",
29
+ method: "eth_sendPrivateTransaction",
30
+ params: [signedTx]
31
+ }, {
32
+ headers: {
33
+ 'Content-Type': 'application/json',
34
+ 'Authorization': this.authToken
35
+ }
36
+ });
37
+ if (response.data.error) {
38
+ throw new Error(`交易发送失败: ${response.data.error.code} - ${response.data.error.message}`);
39
+ }
40
+ return response.data.result;
41
+ }
42
+ catch (error) {
43
+ (0, dist_1.log_error)('blockrazor sendPrivateTransaction failed!!!', error);
44
+ throw error;
45
+ }
46
+ });
47
+ }
48
+ sendBundle(transactions, maxBlockNumber, revertingTxHashes) {
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ try {
51
+ const currentTimestamp = Math.floor(Date.now() / 1000);
52
+ const response = yield axios_1.default.post(this.rpcUrl, {
53
+ jsonrpc: "2.0",
54
+ id: "1",
55
+ method: "eth_sendBundle",
56
+ params: [{
57
+ txs: transactions,
58
+ minTimestamp: currentTimestamp + 1,
59
+ maxTimestamp: currentTimestamp + 30,
60
+ }]
61
+ }, {
62
+ headers: {
63
+ 'Content-Type': 'application/json',
64
+ 'Authorization': this.authToken,
65
+ }
66
+ });
67
+ if (response.data.error) {
68
+ throw new Error(`Bundle 发送失败: ${response.data.error.message}`);
69
+ }
70
+ return response.data.result;
71
+ }
72
+ catch (error) {
73
+ (0, dist_1.log_error)('blockrazor sendBundle failed!!!', error);
74
+ throw error;
75
+ }
76
+ });
77
+ }
78
+ }
79
+ exports.BlockRazorTrade = BlockRazorTrade;
@@ -0,0 +1,6 @@
1
+ export declare class BscRpc {
2
+ private url;
3
+ private headers;
4
+ constructor(rpc_endpoint: string);
5
+ eth_sendRawTransaction(signedTx: string): Promise<string>;
6
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.BscRpc = void 0;
13
+ class BscRpc {
14
+ constructor(rpc_endpoint) {
15
+ this.url = rpc_endpoint || process.env.BSC_RPC_ENDPOINT || '';
16
+ this.headers = new Headers();
17
+ this.headers.append("Content-Type", "application/json");
18
+ }
19
+ eth_sendRawTransaction(signedTx) {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ console.log(`Sending transaction to ${this.url}`);
22
+ const raw = JSON.stringify({
23
+ jsonrpc: "2.0",
24
+ method: "eth_sendRawTransaction",
25
+ params: [signedTx],
26
+ id: 1
27
+ });
28
+ const requestOptions = {
29
+ method: 'POST',
30
+ headers: this.headers,
31
+ body: raw,
32
+ redirect: 'follow'
33
+ };
34
+ const response = yield fetch(this.url, requestOptions);
35
+ const result = yield response.json();
36
+ if (result.error) {
37
+ throw new Error(result.error.message);
38
+ }
39
+ return result.result;
40
+ });
41
+ }
42
+ }
43
+ exports.BscRpc = BscRpc;
@@ -0,0 +1,5 @@
1
+ export * from './send_tx';
2
+ export declare enum BSC_EOA_ADDRESS {
3
+ BLOCKRAZOR = "0x1266C6bE60392A8Ff346E8d5ECCd3E69dD9c5F20",
4
+ _48CLUB = "0x4848489f0b2BEdd788c696e2D79b6b69D7484848"
5
+ }
@@ -0,0 +1,23 @@
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
+ exports.BSC_EOA_ADDRESS = void 0;
18
+ __exportStar(require("./send_tx"), exports);
19
+ var BSC_EOA_ADDRESS;
20
+ (function (BSC_EOA_ADDRESS) {
21
+ BSC_EOA_ADDRESS["BLOCKRAZOR"] = "0x1266C6bE60392A8Ff346E8d5ECCd3E69dD9c5F20";
22
+ BSC_EOA_ADDRESS["_48CLUB"] = "0x4848489f0b2BEdd788c696e2D79b6b69D7484848";
23
+ })(BSC_EOA_ADDRESS || (exports.BSC_EOA_ADDRESS = BSC_EOA_ADDRESS = {}));
@@ -0,0 +1,8 @@
1
+ import { AppConfig } from "@clonegod/ttd-core/dist";
2
+ export declare class TransactionSender {
3
+ private rpc;
4
+ private blockRazor;
5
+ private _48Club;
6
+ constructor(appConfig: AppConfig);
7
+ sendTransaction(signedMainTx: string, eoa_tip_transaction: (eoa_address: string) => Promise<string>, order_trace_id: string): Promise<string[]>;
8
+ }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.TransactionSender = void 0;
13
+ const dist_1 = require("@clonegod/ttd-core/dist");
14
+ const blockrazor_1 = require("./blockrazor");
15
+ const bsc_rpc_1 = require("./bsc_rpc");
16
+ const _48club_1 = require("./48club");
17
+ const _1 = require(".");
18
+ class TransactionSender {
19
+ constructor(appConfig) {
20
+ this.rpc = new bsc_rpc_1.BscRpc(appConfig.env_args.rpc_endpoint);
21
+ this.blockRazor = new blockrazor_1.BlockRazorTrade();
22
+ this._48Club = new _48club_1._48ClubTrade();
23
+ }
24
+ sendTransaction(signedMainTx, eoa_tip_transaction, order_trace_id) {
25
+ return __awaiter(this, void 0, void 0, function* () {
26
+ const rpcProviders = [
27
+ {
28
+ name: 'Default (QuickNode / Merkle)',
29
+ enable: process.env.SEND_TX_DEFAULT_RPC_PRIVATE === 'true',
30
+ send: () => __awaiter(this, void 0, void 0, function* () {
31
+ return yield this.rpc.eth_sendRawTransaction(signedMainTx);
32
+ })
33
+ },
34
+ {
35
+ name: 'BlockRazor - Private Transaction',
36
+ enable: process.env.SEND_TX_BLOCKRAZOR_PRIVATE === 'true',
37
+ send: () => __awaiter(this, void 0, void 0, function* () {
38
+ return yield this.blockRazor.sendPrivateTransaction(signedMainTx);
39
+ })
40
+ },
41
+ {
42
+ name: 'BlockRazor - sendBundle',
43
+ enable: process.env.SEND_TX_BLOCKRAZOR_BUNDLE === 'true',
44
+ send: () => __awaiter(this, void 0, void 0, function* () {
45
+ let bundle = [signedMainTx, yield eoa_tip_transaction(_1.BSC_EOA_ADDRESS.BLOCKRAZOR)];
46
+ return yield this.blockRazor.sendBundle(bundle);
47
+ })
48
+ },
49
+ {
50
+ name: '48Club - Private Transaction',
51
+ enable: process.env.SEND_TX_48CLUB_PRIVATE === 'true',
52
+ send: () => __awaiter(this, void 0, void 0, function* () {
53
+ return yield this._48Club.sendPrivateTransaction(signedMainTx);
54
+ })
55
+ },
56
+ {
57
+ name: '48Club - sendBundle',
58
+ enable: process.env.SEND_TX_48CLUB_BUNDLE === 'true',
59
+ send: () => __awaiter(this, void 0, void 0, function* () {
60
+ let bundle = [signedMainTx, yield eoa_tip_transaction(_1.BSC_EOA_ADDRESS._48CLUB)];
61
+ return yield this._48Club.sendBundle({ txs: bundle });
62
+ })
63
+ }
64
+ ];
65
+ const results = [];
66
+ const errors = [];
67
+ yield Promise.all(rpcProviders.filter(provider => provider.enable).map((provider) => __awaiter(this, void 0, void 0, function* () {
68
+ try {
69
+ const txHash = yield provider.send();
70
+ results.push(txHash);
71
+ (0, dist_1.log_info)(`Transaction sent successfully`, { provider: provider.name, order_trace_id, txHash });
72
+ }
73
+ catch (error) {
74
+ errors.push(`${provider.name}: ${error.message}`);
75
+ (0, dist_1.log_info)(`Transaction sending failed`, { provider: provider.name, order_trace_id, error: error.message });
76
+ }
77
+ })));
78
+ if (results.length === 0 || errors.length > 0) {
79
+ throw new Error(`!!!!!! Some RPC providers failed to send transactions: ${JSON.stringify(errors)}`);
80
+ }
81
+ return results;
82
+ });
83
+ }
84
+ }
85
+ exports.TransactionSender = TransactionSender;
@@ -0,0 +1,28 @@
1
+ export interface GasOptions {
2
+ gasLimit: number;
3
+ defaultGasPriceGwei: number;
4
+ maxGasPriceGwei: number;
5
+ defaultTipAmountGwei: number;
6
+ maxTipAmountGwei: number;
7
+ txStatusCheckIntervalMills: number;
8
+ txCancelTimeoutMills: number;
9
+ txCancelGasBoostFactor: number;
10
+ }
11
+ export interface EvmChainConfig {
12
+ chainId: number;
13
+ nativeCurrency: string;
14
+ wrappedNativeCurrencyAddress: string;
15
+ chainName: string;
16
+ rpcEndpoint: string;
17
+ blockConfirmations: number;
18
+ gasOptions: GasOptions;
19
+ }
20
+ export interface DexConfig {
21
+ dexId: string;
22
+ dexName: string;
23
+ routerAddress: string;
24
+ factoryAddress?: string;
25
+ routerAbi: any;
26
+ pairAbi: any;
27
+ dexType: string;
28
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,30 @@
1
+ import { ethers } from 'ethers';
2
+ export interface EvmContractEventData {
3
+ blockNumber: number;
4
+ blockHash: string;
5
+ transactionIndex: number;
6
+ transactionHash: string;
7
+ logIndex: number;
8
+ removed: boolean;
9
+ address: string;
10
+ data: string;
11
+ topics: string[];
12
+ event: string;
13
+ eventSignature: string;
14
+ args: any;
15
+ removeListener: () => void;
16
+ getBlock: () => Promise<ethers.providers.Block>;
17
+ getTransaction: () => Promise<ethers.providers.TransactionResponse>;
18
+ getTransactionReceipt: () => Promise<ethers.providers.TransactionReceipt>;
19
+ decode: (data: string, topics?: string[]) => any;
20
+ }
21
+ export interface AmmPoolSyncEventData extends EvmContractEventData {
22
+ event: 'Sync';
23
+ eventSignature: 'Sync(uint112,uint112)';
24
+ args: {
25
+ 0: ethers.BigNumber;
26
+ 1: ethers.BigNumber;
27
+ reserve0: ethers.BigNumber;
28
+ reserve1: ethers.BigNumber;
29
+ };
30
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export * from './config_types';
2
+ export * from './event_types';
3
+ export * from './quote_types';
4
+ export * from './trade_types';
@@ -0,0 +1,20 @@
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("./config_types"), exports);
18
+ __exportStar(require("./event_types"), exports);
19
+ __exportStar(require("./quote_types"), exports);
20
+ __exportStar(require("./trade_types"), exports);
@@ -0,0 +1,27 @@
1
+ import { BigNumber } from "ethers";
2
+ import { EvmContractEventData } from "./event_types";
3
+ export interface ReserveData {
4
+ reserve0: BigNumber;
5
+ reserve1: BigNumber;
6
+ timestamp: number;
7
+ }
8
+ export interface PoolSyncEventData {
9
+ poolAddress: string;
10
+ reserve0: BigNumber;
11
+ reserve1: BigNumber;
12
+ streamTime?: number;
13
+ event: EvmContractEventData;
14
+ }
15
+ export interface PriceChangeResult {
16
+ eventType: 'NORMAL' | 'LARGE_TRADE' | 'NO_CHANGE' | 'UNKNOWN';
17
+ tradeDirection?: 'BUY' | 'SELL' | 'UNKNOWN';
18
+ details: string;
19
+ priceImpact?: number;
20
+ tradeAmountUsd?: number;
21
+ token0Change?: string;
22
+ token1Change?: string;
23
+ }
24
+ export interface ThresholdConfig {
25
+ largeTradeThresholdUsd: number;
26
+ significantPriceChangePercent: number;
27
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,38 @@
1
+ import { BigNumber, ethers } from 'ethers';
2
+ export interface TxOption {
3
+ gasLimit: number;
4
+ gasPrice: ethers.BigNumber;
5
+ nonce?: number;
6
+ value?: any;
7
+ }
8
+ export interface SwapEvent {
9
+ amount0In: BigNumber;
10
+ amount0Out: BigNumber;
11
+ amount1In: BigNumber;
12
+ amount1Out: BigNumber;
13
+ sender: string;
14
+ to: string;
15
+ }
16
+ export interface ParserConfig {
17
+ version: string;
18
+ rpcEndpoint: string;
19
+ walletAddress: string;
20
+ }
21
+ export interface TokenChanges {
22
+ pre_bal: number;
23
+ post_bal: number;
24
+ change: string;
25
+ }
26
+ export interface TransactionResult {
27
+ status: 'success' | 'failed' | 'pending';
28
+ hash: string;
29
+ blockNumber?: number;
30
+ gasUsed?: ethers.BigNumber;
31
+ effectiveGasPrice?: ethers.BigNumber;
32
+ totalCost?: ethers.BigNumber;
33
+ errorMessage?: string;
34
+ }
35
+ export declare enum TxStatus {
36
+ PENDING = "pending",
37
+ CONFIRMED = "confirmed"
38
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TxStatus = void 0;
4
+ var TxStatus;
5
+ (function (TxStatus) {
6
+ TxStatus["PENDING"] = "pending";
7
+ TxStatus["CONFIRMED"] = "confirmed";
8
+ })(TxStatus || (exports.TxStatus = TxStatus = {}));
@@ -0,0 +1,5 @@
1
+ import { ethers } from 'ethers';
2
+ export declare class EVMGasHelper {
3
+ static wrapNativeToken(provider: ethers.providers.Provider, wallet: ethers.Wallet, wrappedTokenAddress: string, amount: string, minReserve?: string, tokenSymbol?: string): Promise<string>;
4
+ static checkNativeBalance(provider: ethers.providers.Provider, walletAddress: string): Promise<ethers.BigNumber>;
5
+ }
@@ -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
+ exports.EVMGasHelper = void 0;
13
+ const ethers_1 = require("ethers");
14
+ const dist_1 = require("@clonegod/ttd-core/dist");
15
+ class EVMGasHelper {
16
+ static wrapNativeToken(provider_1, wallet_1, wrappedTokenAddress_1, amount_1) {
17
+ return __awaiter(this, arguments, void 0, function* (provider, wallet, wrappedTokenAddress, amount, minReserve = "0.1", tokenSymbol = "ETH") {
18
+ const nativeBalance = yield provider.getBalance(wallet.address);
19
+ const nativeBalanceEth = ethers_1.ethers.utils.formatEther(nativeBalance);
20
+ (0, dist_1.log_info)(`当前${tokenSymbol}余额: ${nativeBalanceEth} ${tokenSymbol}`);
21
+ let wrapAmount;
22
+ if (amount === "max") {
23
+ const minReserveBN = ethers_1.ethers.utils.parseEther(minReserve);
24
+ if (nativeBalance.lte(minReserveBN)) {
25
+ (0, dist_1.log_info)(`${tokenSymbol}余额不足最小保留额 ${minReserve} ${tokenSymbol},不执行转换`);
26
+ return null;
27
+ }
28
+ wrapAmount = nativeBalance.sub(minReserveBN);
29
+ }
30
+ else {
31
+ wrapAmount = ethers_1.ethers.utils.parseEther(amount);
32
+ const minReserveBN = ethers_1.ethers.utils.parseEther(minReserve);
33
+ if (nativeBalance.sub(wrapAmount).lt(minReserveBN)) {
34
+ (0, dist_1.log_info)(`转换后${tokenSymbol}余额将低于最小保留额 ${minReserve} ${tokenSymbol},调整转换金额`);
35
+ wrapAmount = nativeBalance.sub(minReserveBN);
36
+ }
37
+ }
38
+ if (wrapAmount.lte(ethers_1.ethers.constants.Zero)) {
39
+ (0, dist_1.log_info)(`计算的转换金额为0或负数,不执行转换`);
40
+ return null;
41
+ }
42
+ const wrappedTokenContract = new ethers_1.ethers.Contract(wrappedTokenAddress, [
43
+ "function deposit() external payable",
44
+ "function withdraw(uint wad) external"
45
+ ], wallet);
46
+ (0, dist_1.log_info)(`准备将 ${ethers_1.ethers.utils.formatEther(wrapAmount)} ${tokenSymbol} 转换为 W${tokenSymbol}`);
47
+ const gasPrice = yield provider.getGasPrice();
48
+ const txOptions = {
49
+ value: wrapAmount,
50
+ gasLimit: 100000,
51
+ gasPrice: gasPrice
52
+ };
53
+ try {
54
+ const tx = yield wrappedTokenContract.deposit(txOptions);
55
+ (0, dist_1.log_info)(`${tokenSymbol}转换为W${tokenSymbol}交易已发送,txHash: ${tx.hash}`);
56
+ yield tx.wait();
57
+ (0, dist_1.log_info)(`${tokenSymbol}转换为W${tokenSymbol}交易已确认,txHash: ${tx.hash}`);
58
+ return tx.hash;
59
+ }
60
+ catch (error) {
61
+ (0, dist_1.log_error)(`${tokenSymbol}转换为W${tokenSymbol}失败: ${error.message}`, error);
62
+ throw error;
63
+ }
64
+ });
65
+ }
66
+ static checkNativeBalance(provider, walletAddress) {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ return yield provider.getBalance(walletAddress);
69
+ });
70
+ }
71
+ }
72
+ exports.EVMGasHelper = EVMGasHelper;
@@ -0,0 +1,7 @@
1
+ import { ethers } from "ethers";
2
+ import Decimal from "decimal.js";
3
+ export * from './gas_helper';
4
+ export declare const sleep: (ms: number) => Promise<void>;
5
+ export declare const formatPrice: (price: number, precision?: number) => string;
6
+ export declare const formatUnits: (value: ethers.BigNumber, decimals: number) => Decimal;
7
+ export declare const formatNumberHighPrecision: (numStr: string, precision?: number) => string;
@@ -0,0 +1,43 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.formatNumberHighPrecision = exports.formatUnits = exports.formatPrice = exports.sleep = void 0;
21
+ const ethers_1 = require("ethers");
22
+ const decimal_js_1 = __importDefault(require("decimal.js"));
23
+ __exportStar(require("./gas_helper"), exports);
24
+ const sleep = (ms) => {
25
+ return new Promise(resolve => setTimeout(resolve, ms));
26
+ };
27
+ exports.sleep = sleep;
28
+ const formatPrice = (price, precision = 10) => {
29
+ return price.toFixed(precision).replace(/\.?0+$/, '');
30
+ };
31
+ exports.formatPrice = formatPrice;
32
+ const formatUnits = (value, decimals) => {
33
+ return new decimal_js_1.default(ethers_1.ethers.utils.formatUnits(value, decimals).toString());
34
+ };
35
+ exports.formatUnits = formatUnits;
36
+ const formatNumberHighPrecision = (numStr, precision = 12) => {
37
+ const num = new decimal_js_1.default(numStr).toNumber();
38
+ if (Math.abs(num) < 0.000001 && num !== 0) {
39
+ return num.toExponential(precision);
40
+ }
41
+ return num.toFixed(precision).replace(/\.?0+$/, '');
42
+ };
43
+ exports.formatNumberHighPrecision = formatNumberHighPrecision;
@@ -0,0 +1,14 @@
1
+ import { RedisClientType } from "redis";
2
+ export declare class RedisLock {
3
+ private lock_prefix;
4
+ private redisClient;
5
+ private lockMaxRetries;
6
+ private lockRetryDelayMs;
7
+ private lockExpireSeconds;
8
+ constructor(lock_prefix: string);
9
+ getRedisClient(): Promise<RedisClientType>;
10
+ private getLockKey;
11
+ private acquireLock;
12
+ private releaseLock;
13
+ withLock<T>(lock_identifier: string, callback: () => Promise<T>): Promise<T>;
14
+ }