@clonegod/ttd-sol-common 1.0.40 → 1.0.42

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.
@@ -32,9 +32,17 @@ class AppConfig extends events_1.EventEmitter {
32
32
  this.arb_cache = (0, dist_1.getArbCache)(this.env_args);
33
33
  yield this.arb_cache.init();
34
34
  this.arb_cache.listen_trade_result(this);
35
- this.connection = new web3_js_1.Connection(this.env_args.quicknode_endpoint, {
35
+ this.connection = new web3_js_1.Connection(this.env_args.rpc_endpoint, {
36
36
  commitment: common_1.COMMITMENT_LEVEL.CONFIRMED,
37
37
  });
38
+ let common_service_config = yield this.arb_cache.get_common_service();
39
+ if ((0, dist_1.isEmpty)(common_service_config)) {
40
+ throw new Error(`get_common_service from cache failed! read from cache=${(0, dist_1.to_json_str)(common_service_config)}`);
41
+ }
42
+ let { config_center } = common_service_config;
43
+ this.query_token_market_price_url = this.env_args.token_price_url
44
+ .replace('${config_center_http_port}', config_center.http_port + '')
45
+ .replace('${chain_id}', this.env_args.chain_id);
38
46
  });
39
47
  }
40
48
  init_trade_runtime() {
@@ -56,6 +64,7 @@ class AppConfig extends events_1.EventEmitter {
56
64
  return __awaiter(this, void 0, void 0, function* () {
57
65
  this.arb_event_subscriber = (0, dist_1.getArbEventSubscriber)(this.arb_cache);
58
66
  yield this.arb_event_subscriber.pre_load_config_cache();
67
+ yield this.arb_event_subscriber.subscribe_config_change_event();
59
68
  const refresh_trade_runtime = (is_sussess, event) => __awaiter(this, void 0, void 0, function* () {
60
69
  (0, dist_1.log_info)(`subscribe_config_change_event, callback`, { is_sussess, event });
61
70
  if (event.event_type === dist_1.REDIS_EVENT_TYPE_CONFIG_CHANGE.GROUP_CONFIG_CHANGE) {
@@ -6,8 +6,13 @@ export declare class EnvArgs {
6
6
  app_name: string;
7
7
  redis_host: string;
8
8
  redis_port: string;
9
- quicknode_endpoint: string;
9
+ rpc_endpoint: string;
10
10
  helius_api_key: string;
11
+ geyser_ws_url: string;
12
+ token_price_url: string;
13
+ auto_quote_enable: boolean;
14
+ auto_quote_interval_seconds: number;
15
+ quote_pair_list: string[];
11
16
  trade_cmd_args: TradeCommandLineArgs;
12
17
  constructor();
13
18
  init(): void;
@@ -17,8 +17,13 @@ class EnvArgs {
17
17
  this.dex_id_list = [process.env.INPUT_DEX_ID];
18
18
  this.redis_host = process.env.REDIS_HOST;
19
19
  this.redis_port = process.env.REDIS_PORT;
20
- this.quicknode_endpoint = process.env.QUICKNODE_ENDPOINT;
20
+ this.rpc_endpoint = process.env.RPC_ENDPOINT;
21
21
  this.helius_api_key = process.env.HELIUS_API_KEY;
22
+ this.geyser_ws_url = `wss://atlas-mainnet.helius-rpc.com/?api-key=${process.env.HELIUS_API_KEY}`;
23
+ this.quote_pair_list = (process.env.QUOTE_PAIR_LIST || '').split(',');
24
+ this.auto_quote_enable = process.env.AUTO_QUOTE_ENABLE === 'true';
25
+ this.auto_quote_interval_seconds = parseInt(process.env.AUTO_QUOTE_INTERVAL_SECONDS || '60');
26
+ this.token_price_url = process.env.TOKEN_PRICE_URL;
22
27
  (0, dist_1.log_info)('Env args init finish', this);
23
28
  }
24
29
  }
@@ -18,5 +18,5 @@ export declare class TradeContext {
18
18
  aToB: boolean;
19
19
  slippage_bps: number;
20
20
  constructor(price_msg: PriceMessageType, order_msg: OrderMessageType);
21
- init(trade_runtime: TradeRuntimeType): Promise<void>;
21
+ init(connection: Connection, trade_runtime: TradeRuntimeType): Promise<void>;
22
22
  }
@@ -18,8 +18,9 @@ class TradeContext {
18
18
  this.order_msg = order_msg;
19
19
  this.order_trace_id = order_msg.order_trace_id;
20
20
  }
21
- init(trade_runtime) {
21
+ init(connection, trade_runtime) {
22
22
  return __awaiter(this, void 0, void 0, function* () {
23
+ this.connection = connection;
23
24
  this.trade_runtime = trade_runtime;
24
25
  let { group_id, unique_orderbook_id } = this.order_msg;
25
26
  this.group_id = group_id;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- export * from './common';
2
1
  export * from './appconfig';
2
+ export * from './common';
3
3
  export * from './helius_geyser_ws';
4
+ export * from './quote';
4
5
  export * from './send_tx';
5
6
  export * from './trade';
package/dist/index.js CHANGED
@@ -14,8 +14,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./common"), exports);
18
17
  __exportStar(require("./appconfig"), exports);
18
+ __exportStar(require("./common"), exports);
19
19
  __exportStar(require("./helius_geyser_ws"), exports);
20
+ __exportStar(require("./quote"), exports);
20
21
  __exportStar(require("./send_tx"), exports);
21
22
  __exportStar(require("./trade"), exports);
@@ -0,0 +1,3 @@
1
+ export * from './log_quote_price';
2
+ export * from './publish_quote_price';
3
+ export * from './to_price_message';
@@ -0,0 +1,19 @@
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("./log_quote_price"), exports);
18
+ __exportStar(require("./publish_quote_price"), exports);
19
+ __exportStar(require("./to_price_message"), exports);
@@ -0,0 +1,2 @@
1
+ import { PriceMessageType } from "@clonegod/ttd-common";
2
+ export declare function log_quote_price(event_source: string, price_message: PriceMessageType, tx_hash: string): Promise<void>;
@@ -0,0 +1,31 @@
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.log_quote_price = void 0;
13
+ const dist_1 = require("@clonegod/ttd-common/dist");
14
+ function log_quote_price(event_source, price_message, tx_hash) {
15
+ return __awaiter(this, void 0, void 0, function* () {
16
+ const { unique_orderbook_id, pool_name, pair, fee_rate, price_id, quote_amount_usd, ask, bid, time } = price_message;
17
+ let price_time = new Date().getTime();
18
+ let price_time_str = (0, dist_1.parseToDateTime)(price_time);
19
+ let times = [
20
+ time.stream_time - time.block_time,
21
+ time.quote_end_time - time.quote_start_time,
22
+ time.price_time - time.stream_time,
23
+ time.price_time - time.block_time,
24
+ ];
25
+ setTimeout(() => {
26
+ console.log(`> [${event_source}] - ${tx_hash}`);
27
+ console.log(price_time_str, ' - ', unique_orderbook_id, ' - ', String(price_id).padEnd(32), ' - ', pool_name.padEnd(12), ' - ', pair.padEnd(12), ' - ', String(quote_amount_usd).padEnd(4), ' - ', String(ask.price).padEnd(8), ' - ', String(bid.price).padEnd(8), ' - ', `${times.join(',')} ms`, '\n');
28
+ }, 0);
29
+ });
30
+ }
31
+ exports.log_quote_price = log_quote_price;
@@ -0,0 +1,3 @@
1
+ import { PriceMessageType } from "@clonegod/ttd-common";
2
+ import { AppConfig } from "../appconfig";
3
+ export declare const publish_quote_price: (appConfig: AppConfig, price_msg: PriceMessageType) => void;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.publish_quote_price = void 0;
4
+ const dist_1 = require("@clonegod/ttd-common/dist");
5
+ const publish_quote_price = (appConfig, price_msg) => {
6
+ const chain_id = appConfig.env_args.chain_id;
7
+ let price_id = price_msg.price_id;
8
+ let event = {
9
+ event_type: dist_1.REDIS_EVENT_TYPE_QUOTE.NEW_QUOTE_PRICE,
10
+ event_time: Date.now(),
11
+ chain_id,
12
+ data: price_msg
13
+ };
14
+ appConfig.arb_cache.redis_event_publisher.publish_quote_price_event(chain_id, event);
15
+ appConfig.arb_cache.cache_price_message(price_msg)
16
+ .then(() => (0, dist_1.log_debug)(`cache price success, price_id=${price_id}`))
17
+ .catch(err => (0, dist_1.log_error)(`cache price error! price_id=${price_id}`, err));
18
+ };
19
+ exports.publish_quote_price = publish_quote_price;
@@ -0,0 +1,4 @@
1
+ import { PriceMessageType, QuoteTimeInfoType, StandardPoolInfoType } from '@clonegod/ttd-common';
2
+ import { AppConfig } from '../appconfig';
3
+ export declare function to_price_message(appConfig: AppConfig, quote_amount_usd: number, tx_price: number, quote_ask_price: number, quote_bid_price: number, pool_info: StandardPoolInfoType, time: QuoteTimeInfoType): Promise<PriceMessageType>;
4
+ export declare function normalize_pair_name(priceMessage: PriceMessageType): void;
@@ -0,0 +1,90 @@
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.normalize_pair_name = exports.to_price_message = void 0;
16
+ const decimal_js_1 = __importDefault(require("decimal.js"));
17
+ const uuid_1 = require("uuid");
18
+ const dist_1 = require("@clonegod/ttd-common/dist");
19
+ function to_price_message(appConfig, quote_amount_usd, tx_price, quote_ask_price, quote_bid_price, pool_info, time) {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ let { pool_address, tokenA, tokenB } = pool_info;
22
+ let { dex_id, pool_name, fee_rate, is_reverse_token } = yield appConfig.arb_cache.get_one_pool_info(pool_address);
23
+ let _dex_id = dex_id;
24
+ let price_id = (0, uuid_1.v4)().replace(/-/gi, '');
25
+ let chain_id = appConfig.env_args.chain_id;
26
+ let unique_orderbook_id = (0, dist_1.format_unique_orderbook_id)(chain_id, _dex_id, pool_address, fee_rate);
27
+ time.price_time = new Date().getTime();
28
+ let fee_rate_bps = fee_rate / 100100;
29
+ let ask_price = getAskPrice(new decimal_js_1.default(quote_ask_price), fee_rate_bps * 0);
30
+ let bid_price = getBidPrice(new decimal_js_1.default(quote_bid_price), fee_rate_bps * 0);
31
+ let price_message = {
32
+ chain_id,
33
+ dex_id,
34
+ price_id,
35
+ pool_id: pool_address,
36
+ pool_name,
37
+ fee_rate,
38
+ pair: pool_name,
39
+ unique_orderbook_id,
40
+ is_reverse_token,
41
+ tokenA: {
42
+ symbol: tokenA.symbol,
43
+ address: tokenA.address,
44
+ address_hex: tokenA.address_hex,
45
+ decimals: tokenA.decimals,
46
+ name: tokenA.name,
47
+ enable: true,
48
+ },
49
+ tokenB: {
50
+ symbol: tokenB.symbol,
51
+ address: tokenB.address,
52
+ address_hex: tokenB.address_hex,
53
+ decimals: tokenB.decimals,
54
+ name: tokenB.name,
55
+ enable: true,
56
+ },
57
+ tx_price: tx_price === null || tx_price === void 0 ? void 0 : tx_price.toFixed(8),
58
+ quote_amount_usd,
59
+ ask: {
60
+ price: ask_price,
61
+ quantity: quote_amount_usd
62
+ },
63
+ bid: {
64
+ price: bid_price,
65
+ quantity: quote_amount_usd
66
+ },
67
+ time
68
+ };
69
+ normalize_pair_name(price_message);
70
+ return price_message;
71
+ });
72
+ }
73
+ exports.to_price_message = to_price_message;
74
+ const getAskPrice = (price, feeRate) => {
75
+ return price.mul(1 + feeRate).toFixed(8);
76
+ };
77
+ const getBidPrice = (price, feeRate) => {
78
+ return price.mul(1 - feeRate).toFixed(8);
79
+ };
80
+ function normalize_pair_name(priceMessage) {
81
+ let { pool_name, is_reverse_token } = priceMessage;
82
+ if (is_reverse_token) {
83
+ pool_name = pool_name.split('/')[1] + '/' + pool_name.split('/')[0];
84
+ }
85
+ const dex_pair_names = pool_name.split('/');
86
+ let cex_base_token = (0, dist_1.format_symbol_name)(dex_pair_names[0]);
87
+ let cex_qutoe_token = (0, dist_1.format_symbol_name)(dex_pair_names[1]);
88
+ priceMessage.pair = cex_base_token.toUpperCase() + '/' + cex_qutoe_token.toUpperCase();
89
+ }
90
+ exports.normalize_pair_name = normalize_pair_name;
@@ -0,0 +1,14 @@
1
+ import { SendOptions, Signer, TransactionInstruction } from "@solana/web3.js";
2
+ import { Helius } from "../helius_sdk_v1.4.0";
3
+ import { SolanaTradeRuntimeType } from '../../types';
4
+ export declare class HeliusClient {
5
+ signers: Signer[];
6
+ sendOptions: SendOptions;
7
+ cluster: string;
8
+ helius_mainnet: Helius;
9
+ helius_staked: Helius;
10
+ constructor(signers: Signer[]);
11
+ send_transaction(solana_trade_runtime: SolanaTradeRuntimeType, instructions: TransactionInstruction[]): Promise<string>;
12
+ private send_smart_transaction;
13
+ private send_transaction_by_jito;
14
+ }
@@ -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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.HeliusClient = void 0;
13
+ const dist_1 = require("@clonegod/ttd-common/dist");
14
+ const helius_sdk_v1_4_0_1 = require("../helius_sdk_v1.4.0");
15
+ const strategy_util_1 = require("./strategy_util");
16
+ class HeliusClient {
17
+ constructor(signers) {
18
+ this.cluster = 'mainnet-beta';
19
+ this.signers = signers;
20
+ this.sendOptions = {
21
+ skipPreflight: true,
22
+ maxRetries: 0
23
+ };
24
+ let helius_api_key = process.env.HELIUS_API_KEY;
25
+ let helius_mainnet_endpoint = `https://mainnet.helius-rpc.com/?api-key=${helius_api_key}`;
26
+ let helius_staked_endpoint = `https://staked.helius-rpc.com?api-key=${helius_api_key}`;
27
+ this.helius_mainnet = new helius_sdk_v1_4_0_1.Helius('', this.cluster, 'helius-sdk', helius_mainnet_endpoint);
28
+ this.helius_staked = new helius_sdk_v1_4_0_1.Helius('', this.cluster, 'helius-sdk', helius_staked_endpoint);
29
+ }
30
+ send_transaction(solana_trade_runtime, instructions) {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ let txid = '';
33
+ let { broadcast_type, speed } = solana_trade_runtime.settings.strategy;
34
+ if (broadcast_type === 'rpc') {
35
+ let use_staked_endpint = speed === 'turbo' || speed === 'ultra';
36
+ txid = yield this.send_smart_transaction(solana_trade_runtime, instructions, use_staked_endpint);
37
+ }
38
+ else if (broadcast_type === 'jito') {
39
+ txid = yield this.send_transaction_by_jito(solana_trade_runtime, instructions);
40
+ }
41
+ else {
42
+ throw new Error(`Not support broadcast_type: ${broadcast_type}`);
43
+ }
44
+ return txid;
45
+ });
46
+ }
47
+ send_smart_transaction(solana_trade_runtime, instructions, use_staked_endpint) {
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ (0, dist_1.log_info)(`send_smart_transaction, start`);
50
+ let start_time = Date.now();
51
+ let rpc = use_staked_endpint ? this.helius_staked.rpc : this.helius_mainnet.rpc;
52
+ let txid = yield rpc.sendSmartTransaction(solana_trade_runtime, instructions, this.signers, [], this.sendOptions);
53
+ (0, dist_1.log_info)(`send_smart_transaction, end`, {
54
+ txid,
55
+ use_staked_endpint,
56
+ take_time: Date.now() - start_time
57
+ });
58
+ return txid;
59
+ });
60
+ }
61
+ send_transaction_by_jito(solana_trade_runtime, instructions) {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ (0, dist_1.log_info)(`send_transaction_by_jito, start`);
64
+ let start_time = Date.now();
65
+ let tipAmount = solana_trade_runtime.priority_fee;
66
+ let jito_region = (0, strategy_util_1.get_jito_region)();
67
+ let rpc = this.helius_mainnet.rpc;
68
+ let txid = yield rpc.sendSmartTransactionWithTip(solana_trade_runtime, instructions, this.signers, [], tipAmount, jito_region);
69
+ (0, dist_1.log_info)(`send_transaction_by_jito, end`, {
70
+ tipAmount,
71
+ jito_region,
72
+ txid,
73
+ take_time: Date.now() - start_time
74
+ });
75
+ return txid;
76
+ });
77
+ }
78
+ }
79
+ exports.HeliusClient = HeliusClient;
@@ -1,3 +1,3 @@
1
1
  export * from './get_signature';
2
- export * from './send_transaction';
2
+ export * from './helius_client';
3
3
  export * from './strategy_util';
@@ -15,5 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./get_signature"), exports);
18
- __exportStar(require("./send_transaction"), exports);
18
+ __exportStar(require("./helius_client"), exports);
19
19
  __exportStar(require("./strategy_util"), exports);
@@ -84,9 +84,9 @@ const handle_order_message = (appConfig, trade, message) => __awaiter(void 0, vo
84
84
  let txid = '';
85
85
  let order_submit_result;
86
86
  try {
87
- let { env_args, trade_runtime } = appConfig;
87
+ let { env_args, trade_runtime, connection } = appConfig;
88
88
  context = new common_1.TradeContext(price_msg, order_msg);
89
- yield context.init(trade_runtime);
89
+ yield context.init(connection, trade_runtime);
90
90
  txid = yield trade.execute(context);
91
91
  order_msg.order_submit_time = Date.now();
92
92
  order_submit_result = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clonegod/ttd-sol-common",
3
- "version": "1.0.40",
3
+ "version": "1.0.42",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "types/index.d.ts",
@@ -13,7 +13,7 @@
13
13
  "push": "npm run build && npm publish"
14
14
  },
15
15
  "dependencies": {
16
- "@clonegod/ttd-common": "1.0.147",
16
+ "@clonegod/ttd-common": "^1.0.147",
17
17
  "@solana/web3.js": "1.91.6",
18
18
  "@irys/sdk": "^0.2.10",
19
19
  "@metaplex-foundation/mpl-token-metadata": "^2.5.2",