@clonegod/ttd-sol-common 2.0.17 → 2.0.19
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/trade/send/helius.d.ts +2 -2
- package/dist/trade/send/helius.js +5 -5
- package/dist/trade/send/jito.d.ts +9 -0
- package/dist/trade/send/jito.js +62 -0
- package/dist/trade/send/send_tx.d.ts +1 -1
- package/dist/trade/send/send_tx.js +4 -3
- package/dist/trade/tx_builder.d.ts +4 -6
- package/dist/trade/tx_builder.js +23 -22
- package/package.json +1 -1
- package/src/trade/send/helius.ts +5 -4
- package/src/trade/send/jito.ts +67 -35
- package/src/trade/send/send_tx.ts +6 -13
- package/src/trade/tx_builder.ts +43 -28
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Transaction } from "@solana/web3.js";
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const sendTxWithHelius: (signedTransaction: Transaction,
|
|
2
|
+
export declare const HELIUS_TIP_ACCOUNTS: string[];
|
|
3
|
+
export declare const sendTxWithHelius: (signedTransaction: Transaction, swqos_only: boolean) => Promise<string>;
|
|
@@ -3,9 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.sendTxWithHelius = exports.
|
|
6
|
+
exports.sendTxWithHelius = exports.HELIUS_TIP_ACCOUNTS = void 0;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
|
-
exports.
|
|
8
|
+
exports.HELIUS_TIP_ACCOUNTS = [
|
|
9
9
|
"4ACfpUFoaSD9bfPdeu6DBt89gB6ENTeHBXCAi87NhDEE",
|
|
10
10
|
"D2L6yPZ2FmmmTKPgzaMKdhu6EWZcTpLy1Vhx8uvZe7NZ",
|
|
11
11
|
"9bnz4RShgq1hAnLnZbP8kbgBg1kEmcJBYQq3gQbmnSta",
|
|
@@ -17,9 +17,9 @@ exports.HELIUS_JITO_TIP_ACCOUNTS = [
|
|
|
17
17
|
"4vieeGHPYPG2MmyPRcYjdiDmmhN3ww7hsFNap8pVN3Ey",
|
|
18
18
|
"4TQLFNWK8AovT1gFvda5jfw2oJeRMKEmw7aH6MGBJ3or"
|
|
19
19
|
];
|
|
20
|
-
const sendTxWithHelius = async (signedTransaction,
|
|
21
|
-
let url = 'http://tyo-sender.helius-rpc.com/fast';
|
|
22
|
-
if (!
|
|
20
|
+
const sendTxWithHelius = async (signedTransaction, swqos_only) => {
|
|
21
|
+
let url = process.env.HELIUS_SEND_TX_URL || 'http://tyo-sender.helius-rpc.com/fast';
|
|
22
|
+
if (!swqos_only) {
|
|
23
23
|
url = url + "?swqos_only=true";
|
|
24
24
|
}
|
|
25
25
|
const response = await axios_1.default.post(url, {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Transaction } from "@solana/web3.js";
|
|
2
|
+
export declare const JITO_TIP_ACCOUNTS: string[];
|
|
3
|
+
export declare class JitoUtils {
|
|
4
|
+
static jitoTipAccounts: string[];
|
|
5
|
+
static init(): Promise<void>;
|
|
6
|
+
static fetchJitoTipAccounts(): Promise<string[]>;
|
|
7
|
+
}
|
|
8
|
+
export declare const getJitoTipAccount: () => string;
|
|
9
|
+
export declare const sendBundleWithJito: (signedTransactions: Transaction[]) => Promise<string>;
|
package/dist/trade/send/jito.js
CHANGED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.sendBundleWithJito = exports.getJitoTipAccount = exports.JitoUtils = exports.JITO_TIP_ACCOUNTS = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
exports.JITO_TIP_ACCOUNTS = [
|
|
9
|
+
"DfXygSm4jCyNCybVYYK6DwvWqjKee8pbDmJGcLWNDXjh",
|
|
10
|
+
"DttWaMuVvTiduZRnguLF7jNxTgiMBZ1hyAumKUiL2KRL",
|
|
11
|
+
"3AVi9Tg9Uo68tJfuvoKvqKNWKkC5wPdSSdeBnizKZ6jT",
|
|
12
|
+
"96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5",
|
|
13
|
+
"ADuUkR4vqLUMWXxW9gh6D6L8pMSawimctcNZ5pGwDcEt",
|
|
14
|
+
"Cw8CFyM9FkoMi7K7Crf6HNQqf4uEMzpKw6QNghXLvLkY",
|
|
15
|
+
"ADaUMid9yfUytqMBgopwjb2DTLSokTSzL1zt6iGPaS49",
|
|
16
|
+
"HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe"
|
|
17
|
+
];
|
|
18
|
+
class JitoUtils {
|
|
19
|
+
static async init() {
|
|
20
|
+
return JitoUtils.fetchJitoTipAccounts().then((accounts) => {
|
|
21
|
+
JitoUtils.jitoTipAccounts = accounts;
|
|
22
|
+
console.log(`fetchJitoTipAccounts success: ${accounts.length} accounts`, accounts);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
static async fetchJitoTipAccounts() {
|
|
26
|
+
const response = await axios_1.default.post('https://mainnet.block-engine.jito.wtf/api/v1/getTipAccounts', {
|
|
27
|
+
jsonrpc: '2.0',
|
|
28
|
+
id: 1,
|
|
29
|
+
method: 'getTipAccounts',
|
|
30
|
+
params: []
|
|
31
|
+
});
|
|
32
|
+
return response.data.result;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.JitoUtils = JitoUtils;
|
|
36
|
+
JitoUtils.jitoTipAccounts = [];
|
|
37
|
+
const getJitoTipAccount = () => {
|
|
38
|
+
let jito_tip_accounts = JitoUtils.jitoTipAccounts;
|
|
39
|
+
if (JitoUtils.jitoTipAccounts.length === 0) {
|
|
40
|
+
jito_tip_accounts = exports.JITO_TIP_ACCOUNTS;
|
|
41
|
+
}
|
|
42
|
+
return jito_tip_accounts[Math.floor(Math.random() * jito_tip_accounts.length)];
|
|
43
|
+
};
|
|
44
|
+
exports.getJitoTipAccount = getJitoTipAccount;
|
|
45
|
+
JitoUtils.init();
|
|
46
|
+
const sendBundleWithJito = async (signedTransactions) => {
|
|
47
|
+
let url = process.env.JITO_SEND_BUNDLE_URL || 'https://tokyo.mainnet.block-engine.jito.wtf/api/v1/bundles';
|
|
48
|
+
const response = await axios_1.default.post(url, {
|
|
49
|
+
jsonrpc: '2.0',
|
|
50
|
+
id: 1,
|
|
51
|
+
method: 'sendBundle',
|
|
52
|
+
params: [
|
|
53
|
+
signedTransactions.map(tx => Buffer.from(tx.serialize()).toString('base64')),
|
|
54
|
+
{
|
|
55
|
+
"encoding": "base64"
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
console.dir(response.data, { depth: null });
|
|
60
|
+
return response.data.result;
|
|
61
|
+
};
|
|
62
|
+
exports.sendBundleWithJito = sendBundleWithJito;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Transaction } from '@solana/web3.js';
|
|
2
2
|
export declare class TransactionSender {
|
|
3
3
|
constructor();
|
|
4
|
-
sendTransaction(singedTransactions: Transaction[],
|
|
4
|
+
sendTransaction(singedTransactions: Transaction[], swqos_only: boolean): Promise<string>;
|
|
5
5
|
sendBundle(signedTransactions: Transaction[]): Promise<string>;
|
|
6
6
|
}
|
|
@@ -2,19 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TransactionSender = void 0;
|
|
4
4
|
const helius_1 = require("./helius");
|
|
5
|
+
const jito_1 = require("./jito");
|
|
5
6
|
class TransactionSender {
|
|
6
7
|
constructor() {
|
|
7
8
|
}
|
|
8
|
-
async sendTransaction(singedTransactions,
|
|
9
|
+
async sendTransaction(singedTransactions, swqos_only) {
|
|
9
10
|
if (singedTransactions.length === 1) {
|
|
10
|
-
return await (0, helius_1.sendTxWithHelius)(singedTransactions[0],
|
|
11
|
+
return await (0, helius_1.sendTxWithHelius)(singedTransactions[0], swqos_only);
|
|
11
12
|
}
|
|
12
13
|
else {
|
|
13
14
|
return await this.sendBundle(singedTransactions);
|
|
14
15
|
}
|
|
15
16
|
}
|
|
16
17
|
async sendBundle(signedTransactions) {
|
|
17
|
-
|
|
18
|
+
return await (0, jito_1.sendBundleWithJito)(signedTransactions);
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
21
|
exports.TransactionSender = TransactionSender;
|
|
@@ -10,10 +10,8 @@ export declare class SolTransactionBuilder {
|
|
|
10
10
|
constructor(appConfig: SolanaTradeAppConfig);
|
|
11
11
|
init(): Promise<void>;
|
|
12
12
|
private handleBlockUpdateEvent;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
getHeliusJitoTipInstruction(context: TradeContext): TransactionInstruction;
|
|
18
|
-
buildTransactionForTip(context: TradeContext, tipAccount: string, tipAmount: number, tipPayer?: Keypair): Transaction;
|
|
13
|
+
private getPreInstructions;
|
|
14
|
+
private getPostInstructions;
|
|
15
|
+
buildTransactionForSwap(context: TradeContext, swapInstructions: TransactionInstruction[]): Transaction;
|
|
16
|
+
buildTransactionForTipJito(context: TradeContext, tipPayer?: Keypair): Transaction;
|
|
19
17
|
}
|
package/dist/trade/tx_builder.js
CHANGED
|
@@ -5,6 +5,7 @@ const dist_1 = require("@clonegod/ttd-core/dist");
|
|
|
5
5
|
const web3_js_1 = require("@solana/web3.js");
|
|
6
6
|
const common_1 = require("../common");
|
|
7
7
|
const helius_1 = require("./send/helius");
|
|
8
|
+
const jito_1 = require("./send/jito");
|
|
8
9
|
class SolTransactionBuilder {
|
|
9
10
|
constructor(appConfig) {
|
|
10
11
|
this.appConfig = appConfig;
|
|
@@ -21,9 +22,6 @@ class SolTransactionBuilder {
|
|
|
21
22
|
this.recentBlockhash = blockHash;
|
|
22
23
|
this.recentBlockheight = blockHeight;
|
|
23
24
|
}
|
|
24
|
-
execute(context) {
|
|
25
|
-
throw new Error('not implemented!!!');
|
|
26
|
-
}
|
|
27
25
|
getPreInstructions(context) {
|
|
28
26
|
const cu_limit = context.pool_info.cu_limit || 600000;
|
|
29
27
|
const sol_priority_fee_lamports = context.trade_runtime.settings.strategy.sol_priority_fee;
|
|
@@ -39,7 +37,7 @@ class SolTransactionBuilder {
|
|
|
39
37
|
getPostInstructions(context) {
|
|
40
38
|
return [];
|
|
41
39
|
}
|
|
42
|
-
buildTransactionForSwap(context, swapInstructions
|
|
40
|
+
buildTransactionForSwap(context, swapInstructions) {
|
|
43
41
|
const max_block_offset = context.trade_runtime.settings.strategy.max_block_offset;
|
|
44
42
|
const swapTx = new web3_js_1.Transaction();
|
|
45
43
|
const preInstructions = this.getPreInstructions(context);
|
|
@@ -48,37 +46,40 @@ class SolTransactionBuilder {
|
|
|
48
46
|
swapTx.recentBlockhash = this.recentBlockhash;
|
|
49
47
|
swapTx.lastValidBlockHeight = this.recentBlockheight + max_block_offset;
|
|
50
48
|
swapTx.feePayer = this.keypair.publicKey;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
let tip_lamports = context.trade_runtime.settings.strategy.sol_tip_fee;
|
|
50
|
+
if (tip_lamports < 5000) {
|
|
51
|
+
tip_lamports = 5000;
|
|
54
52
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
let tip_lamports = Math.min(context.trade_runtime.settings.strategy.sol_tip_fee, 0.0002 * web3_js_1.LAMPORTS_PER_SOL);
|
|
60
|
-
return web3_js_1.SystemProgram.transfer({
|
|
53
|
+
if (tip_lamports > 300000) {
|
|
54
|
+
tip_lamports = 300000;
|
|
55
|
+
}
|
|
56
|
+
let tip_instruction = web3_js_1.SystemProgram.transfer({
|
|
61
57
|
fromPubkey: this.keypair.publicKey,
|
|
62
|
-
toPubkey: new web3_js_1.PublicKey(helius_1.
|
|
58
|
+
toPubkey: new web3_js_1.PublicKey(helius_1.HELIUS_TIP_ACCOUNTS[Math.floor(Math.random() * helius_1.HELIUS_TIP_ACCOUNTS.length)]),
|
|
63
59
|
lamports: tip_lamports,
|
|
64
60
|
});
|
|
61
|
+
swapTx.instructions.push(tip_instruction);
|
|
62
|
+
swapTx.sign(this.keypair);
|
|
63
|
+
return swapTx;
|
|
65
64
|
}
|
|
66
|
-
|
|
65
|
+
buildTransactionForTipJito(context, tipPayer = undefined) {
|
|
67
66
|
const max_block_offset = context.trade_runtime.settings.strategy.max_block_offset;
|
|
68
67
|
if (!tipPayer) {
|
|
69
68
|
tipPayer = this.keypair;
|
|
70
69
|
}
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
let tipAccount = (0, jito_1.getJitoTipAccount)();
|
|
71
|
+
let tipAmount = Math.min(context.trade_runtime.settings.strategy.sol_tip_fee, 0.0002 * web3_js_1.LAMPORTS_PER_SOL);
|
|
72
|
+
const jitoTipTx = new web3_js_1.Transaction();
|
|
73
|
+
jitoTipTx.add(web3_js_1.SystemProgram.transfer({
|
|
73
74
|
fromPubkey: tipPayer.publicKey,
|
|
74
75
|
toPubkey: new web3_js_1.PublicKey(tipAccount),
|
|
75
76
|
lamports: tipAmount,
|
|
76
77
|
}));
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return
|
|
78
|
+
jitoTipTx.recentBlockhash = this.recentBlockhash;
|
|
79
|
+
jitoTipTx.lastValidBlockHeight = this.recentBlockheight + max_block_offset;
|
|
80
|
+
jitoTipTx.feePayer = tipPayer.publicKey;
|
|
81
|
+
jitoTipTx.sign(tipPayer);
|
|
82
|
+
return jitoTipTx;
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
exports.SolTransactionBuilder = SolTransactionBuilder;
|
package/package.json
CHANGED
package/src/trade/send/helius.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Transaction } from "@solana/web3.js"
|
|
2
2
|
import axios from "axios"
|
|
3
3
|
|
|
4
|
-
export const
|
|
4
|
+
export const HELIUS_TIP_ACCOUNTS = [
|
|
5
5
|
"4ACfpUFoaSD9bfPdeu6DBt89gB6ENTeHBXCAi87NhDEE",
|
|
6
6
|
"D2L6yPZ2FmmmTKPgzaMKdhu6EWZcTpLy1Vhx8uvZe7NZ",
|
|
7
7
|
"9bnz4RShgq1hAnLnZbP8kbgBg1kEmcJBYQq3gQbmnSta",
|
|
@@ -17,9 +17,10 @@ export const HELIUS_JITO_TIP_ACCOUNTS = [
|
|
|
17
17
|
/**
|
|
18
18
|
* Jito + SWQOS
|
|
19
19
|
*/
|
|
20
|
-
export const sendTxWithHelius = async (signedTransaction: Transaction,
|
|
21
|
-
let url = 'http://tyo-sender.helius-rpc.com/fast'
|
|
22
|
-
|
|
20
|
+
export const sendTxWithHelius = async (signedTransaction: Transaction, swqos_only: boolean): Promise<string> => {
|
|
21
|
+
let url = process.env.HELIUS_SEND_TX_URL || 'http://tyo-sender.helius-rpc.com/fast'
|
|
22
|
+
|
|
23
|
+
if (!swqos_only) {
|
|
23
24
|
url = url + "?swqos_only=true"
|
|
24
25
|
}
|
|
25
26
|
const response = await axios.post<{ result: string }>(url, {
|
package/src/trade/send/jito.ts
CHANGED
|
@@ -1,35 +1,67 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
1
|
+
import { Transaction } from "@solana/web3.js";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
|
|
4
|
+
export const JITO_TIP_ACCOUNTS = [
|
|
5
|
+
"DfXygSm4jCyNCybVYYK6DwvWqjKee8pbDmJGcLWNDXjh",
|
|
6
|
+
"DttWaMuVvTiduZRnguLF7jNxTgiMBZ1hyAumKUiL2KRL",
|
|
7
|
+
"3AVi9Tg9Uo68tJfuvoKvqKNWKkC5wPdSSdeBnizKZ6jT",
|
|
8
|
+
"96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5",
|
|
9
|
+
"ADuUkR4vqLUMWXxW9gh6D6L8pMSawimctcNZ5pGwDcEt",
|
|
10
|
+
"Cw8CFyM9FkoMi7K7Crf6HNQqf4uEMzpKw6QNghXLvLkY",
|
|
11
|
+
"ADaUMid9yfUytqMBgopwjb2DTLSokTSzL1zt6iGPaS49",
|
|
12
|
+
"HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe"
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
export class JitoUtils {
|
|
16
|
+
static jitoTipAccounts: string[] = []
|
|
17
|
+
|
|
18
|
+
static async init(): Promise<void> {
|
|
19
|
+
return JitoUtils.fetchJitoTipAccounts().then((accounts) => {
|
|
20
|
+
JitoUtils.jitoTipAccounts = accounts;
|
|
21
|
+
console.log(`fetchJitoTipAccounts success: ${accounts.length} accounts`, accounts)
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static async fetchJitoTipAccounts(): Promise<string[]> {
|
|
26
|
+
const response = await axios.post<{ result: string[] }>('https://mainnet.block-engine.jito.wtf/api/v1/getTipAccounts', {
|
|
27
|
+
jsonrpc: '2.0',
|
|
28
|
+
id: 1,
|
|
29
|
+
method: 'getTipAccounts',
|
|
30
|
+
params: []
|
|
31
|
+
})
|
|
32
|
+
return response.data.result;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
export const getJitoTipAccount = (): string => {
|
|
38
|
+
let jito_tip_accounts = JitoUtils.jitoTipAccounts
|
|
39
|
+
if (JitoUtils.jitoTipAccounts.length === 0) {
|
|
40
|
+
jito_tip_accounts = JITO_TIP_ACCOUNTS
|
|
41
|
+
}
|
|
42
|
+
return jito_tip_accounts[Math.floor(Math.random() * jito_tip_accounts.length)];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
JitoUtils.init()
|
|
46
|
+
|
|
47
|
+
// -----------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
export const sendBundleWithJito = async (signedTransactions: Transaction[]): Promise<string> => {
|
|
50
|
+
let url = process.env.JITO_SEND_BUNDLE_URL || 'https://tokyo.mainnet.block-engine.jito.wtf/api/v1/bundles'
|
|
51
|
+
|
|
52
|
+
const response = await axios.post<{ result: string }>(url, {
|
|
53
|
+
jsonrpc: '2.0',
|
|
54
|
+
id: 1,
|
|
55
|
+
method: 'sendBundle',
|
|
56
|
+
params: [
|
|
57
|
+
signedTransactions.map(tx => Buffer.from(tx.serialize()).toString('base64')),
|
|
58
|
+
{
|
|
59
|
+
"encoding": "base64"
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
})
|
|
63
|
+
console.dir(response.data, { depth: null })
|
|
64
|
+
|
|
65
|
+
return response.data.result;
|
|
66
|
+
}
|
|
67
|
+
|
|
@@ -1,34 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Connection, Keypair, Transaction, TransactionInstruction } from '@solana/web3.js';
|
|
1
|
+
import { Transaction } from '@solana/web3.js';
|
|
3
2
|
import { sendTxWithHelius } from './helius';
|
|
3
|
+
import { sendBundleWithJito } from './jito';
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Solana
|
|
8
|
-
*
|
|
9
|
-
* 设计思路对齐 BSC:
|
|
10
|
-
* - 交易构造由具体 DEX Trade 类完成,只返回 swap 指令
|
|
11
|
-
* - buildMainTx 负责构建主交易(所有渠道共用,只构建一次)
|
|
12
|
-
* - buildTipTx 负责构建 tip 交易(渠道特定,动态构建)
|
|
13
|
-
* - TransactionSender 负责多渠道并行发送(RPC / Helius / Jito)
|
|
7
|
+
* Solana 交易发送器
|
|
14
8
|
*/
|
|
15
9
|
export class TransactionSender {
|
|
16
10
|
|
|
17
11
|
constructor() {
|
|
18
12
|
}
|
|
19
13
|
|
|
20
|
-
async sendTransaction(singedTransactions: Transaction[],
|
|
14
|
+
async sendTransaction(singedTransactions: Transaction[], swqos_only:boolean): Promise<string> {
|
|
21
15
|
if(singedTransactions.length === 1) {
|
|
22
|
-
return await sendTxWithHelius(singedTransactions[0],
|
|
16
|
+
return await sendTxWithHelius(singedTransactions[0], swqos_only)
|
|
23
17
|
} else {
|
|
24
18
|
return await this.sendBundle(singedTransactions)
|
|
25
19
|
}
|
|
26
20
|
}
|
|
27
21
|
|
|
28
22
|
async sendBundle(signedTransactions: Transaction[]): Promise<string> {
|
|
29
|
-
|
|
23
|
+
return await sendBundleWithJito(signedTransactions)
|
|
30
24
|
}
|
|
31
25
|
|
|
32
|
-
|
|
33
26
|
}
|
|
34
27
|
|
package/src/trade/tx_builder.ts
CHANGED
|
@@ -3,7 +3,8 @@ import { ComputeBudgetProgram, Connection, Keypair, LAMPORTS_PER_SOL, PublicKey,
|
|
|
3
3
|
import { LAMPORTS_PER_MICRO_LAMPORTS } from "../common";
|
|
4
4
|
import { SolanaBlockMetaUpdateEvent } from "../types";
|
|
5
5
|
import { SolanaTradeAppConfig } from "./SolanaTradeAppConfig";
|
|
6
|
-
import {
|
|
6
|
+
import { HELIUS_TIP_ACCOUNTS } from "./send/helius";
|
|
7
|
+
import { getJitoTipAccount } from "./send/jito";
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
export class SolTransactionBuilder {
|
|
@@ -34,13 +35,9 @@ export class SolTransactionBuilder {
|
|
|
34
35
|
// console.log(`handleBlockUpdateEvent, blockHeight: ${blockHeight}, blockHash: ${blockHash}`)
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
execute(context: TradeContext): Promise<string> {
|
|
38
|
-
throw new Error('not implemented!!!')
|
|
39
|
-
}
|
|
40
|
-
|
|
41
38
|
|
|
42
39
|
// pre-instructions
|
|
43
|
-
getPreInstructions(context: TradeContext): TransactionInstruction[] {
|
|
40
|
+
private getPreInstructions(context: TradeContext): TransactionInstruction[] {
|
|
44
41
|
const cu_limit = context.pool_info.cu_limit || 600000
|
|
45
42
|
const sol_priority_fee_lamports = context.trade_runtime.settings.strategy.sol_priority_fee
|
|
46
43
|
const priorityFeeMicroLamports = Math.floor((sol_priority_fee_lamports * LAMPORTS_PER_MICRO_LAMPORTS) / cu_limit)
|
|
@@ -61,12 +58,18 @@ export class SolTransactionBuilder {
|
|
|
61
58
|
|
|
62
59
|
|
|
63
60
|
// post-instructions
|
|
64
|
-
getPostInstructions(context: TradeContext): TransactionInstruction[] {
|
|
61
|
+
private getPostInstructions(context: TradeContext): TransactionInstruction[] {
|
|
65
62
|
return []
|
|
66
63
|
}
|
|
67
64
|
|
|
68
65
|
|
|
69
|
-
|
|
66
|
+
/**
|
|
67
|
+
* 构建 Swap 交易指令
|
|
68
|
+
* @param context
|
|
69
|
+
* @param swapInstructions
|
|
70
|
+
* @returns
|
|
71
|
+
*/
|
|
72
|
+
buildTransactionForSwap(context: TradeContext, swapInstructions: TransactionInstruction[]): Transaction {
|
|
70
73
|
const max_block_offset = context.trade_runtime.settings.strategy.max_block_offset
|
|
71
74
|
// console.log(`buildTransactionForSwap, max_block_offset: ${max_block_offset}`)
|
|
72
75
|
|
|
@@ -80,48 +83,60 @@ export class SolTransactionBuilder {
|
|
|
80
83
|
swapTx.lastValidBlockHeight = this.recentBlockheight + max_block_offset
|
|
81
84
|
swapTx.feePayer = this.keypair.publicKey
|
|
82
85
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
// Helius Sender 要求:
|
|
87
|
+
// 1、swqos_only: 至少 5000 lamports 小费
|
|
88
|
+
// -> transaction must send a tip of at least 5000 lamports to one of the following Helius wallets: [xxx, ...]
|
|
89
|
+
// 2、swqos + jito: 至少 0.0002 SOL 小费 -> lamports = 0.0002 * LAMPORTS_PER_SOL
|
|
90
|
+
// -> Requires minimum 0.0002 SOL tip.
|
|
91
|
+
let tip_lamports = context.trade_runtime.settings.strategy.sol_tip_fee
|
|
92
|
+
if(tip_lamports < 5000) {
|
|
93
|
+
tip_lamports = 5000
|
|
94
|
+
}
|
|
95
|
+
if(tip_lamports > 300000) {
|
|
96
|
+
tip_lamports = 300000
|
|
86
97
|
}
|
|
98
|
+
let tip_instruction = SystemProgram.transfer({
|
|
99
|
+
fromPubkey: this.keypair.publicKey,
|
|
100
|
+
toPubkey: new PublicKey(HELIUS_TIP_ACCOUNTS[Math.floor(Math.random() * HELIUS_TIP_ACCOUNTS.length)]),
|
|
101
|
+
lamports: tip_lamports,
|
|
102
|
+
})
|
|
103
|
+
swapTx.instructions.push(tip_instruction)
|
|
87
104
|
|
|
88
105
|
swapTx.sign(this.keypair)
|
|
89
106
|
|
|
90
107
|
return swapTx
|
|
91
108
|
}
|
|
92
109
|
|
|
93
|
-
getHeliusJitoTipInstruction(context: TradeContext): TransactionInstruction {
|
|
94
|
-
// Requires minimum 0.0002 SOL tip. (Helius)
|
|
95
|
-
let tip_lamports = Math.min(context.trade_runtime.settings.strategy.sol_tip_fee, 0.0002 * LAMPORTS_PER_SOL)
|
|
96
|
-
return SystemProgram.transfer({
|
|
97
|
-
fromPubkey: this.keypair.publicKey,
|
|
98
|
-
toPubkey: new PublicKey(HELIUS_JITO_TIP_ACCOUNTS[Math.floor(Math.random() * HELIUS_JITO_TIP_ACCOUNTS.length)]),
|
|
99
|
-
lamports: tip_lamports,
|
|
100
|
-
})
|
|
101
|
-
}
|
|
102
110
|
|
|
103
|
-
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* build transaction for tip jito
|
|
114
|
+
*/
|
|
115
|
+
buildTransactionForTipJito(context: TradeContext, tipPayer: Keypair=undefined): Transaction {
|
|
104
116
|
const max_block_offset = context.trade_runtime.settings.strategy.max_block_offset
|
|
105
117
|
|
|
106
118
|
if(!tipPayer) {
|
|
107
119
|
tipPayer = this.keypair
|
|
108
120
|
}
|
|
121
|
+
|
|
122
|
+
let tipAccount = getJitoTipAccount()
|
|
123
|
+
let tipAmount = Math.min(context.trade_runtime.settings.strategy.sol_tip_fee, 0.0002 * LAMPORTS_PER_SOL)
|
|
109
124
|
|
|
110
|
-
const
|
|
111
|
-
|
|
125
|
+
const jitoTipTx = new Transaction();
|
|
126
|
+
jitoTipTx.add(
|
|
112
127
|
SystemProgram.transfer({
|
|
113
128
|
fromPubkey: tipPayer.publicKey,
|
|
114
129
|
toPubkey: new PublicKey(tipAccount),
|
|
115
130
|
lamports: tipAmount,
|
|
116
131
|
}),
|
|
117
132
|
);
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
133
|
+
jitoTipTx.recentBlockhash = this.recentBlockhash
|
|
134
|
+
jitoTipTx.lastValidBlockHeight = this.recentBlockheight + max_block_offset
|
|
135
|
+
jitoTipTx.feePayer = tipPayer.publicKey;
|
|
121
136
|
|
|
122
|
-
|
|
137
|
+
jitoTipTx.sign(tipPayer)
|
|
123
138
|
|
|
124
|
-
return
|
|
139
|
+
return jitoTipTx
|
|
125
140
|
}
|
|
126
141
|
|
|
127
142
|
}
|