four-flap-meme-sdk 1.5.55 → 1.5.56
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/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/sol/constants.d.ts +150 -0
- package/dist/sol/constants.js +188 -0
- package/dist/sol/dex/blockrazor/client.d.ts +51 -0
- package/dist/sol/dex/blockrazor/client.js +96 -0
- package/dist/sol/dex/blockrazor/constants.d.ts +34 -0
- package/dist/sol/dex/blockrazor/constants.js +55 -0
- package/dist/sol/dex/blockrazor/geyser.d.ts +128 -0
- package/dist/sol/dex/blockrazor/geyser.js +530 -0
- package/dist/sol/dex/blockrazor/index.d.ts +18 -0
- package/dist/sol/dex/blockrazor/index.js +23 -0
- package/dist/sol/dex/blockrazor/send.d.ts +135 -0
- package/dist/sol/dex/blockrazor/send.js +254 -0
- package/dist/sol/dex/blockrazor/types.d.ts +191 -0
- package/dist/sol/dex/blockrazor/types.js +5 -0
- package/dist/sol/dex/index.d.ts +10 -0
- package/dist/sol/dex/index.js +16 -0
- package/dist/sol/dex/jup/client.d.ts +33 -0
- package/dist/sol/dex/jup/client.js +110 -0
- package/dist/sol/dex/jup/index.d.ts +16 -0
- package/dist/sol/dex/jup/index.js +148 -0
- package/dist/sol/dex/jup/legacy.d.ts +623 -0
- package/dist/sol/dex/jup/legacy.js +416 -0
- package/dist/sol/dex/jup/lend.d.ts +640 -0
- package/dist/sol/dex/jup/lend.js +603 -0
- package/dist/sol/dex/jup/portfolio.d.ts +362 -0
- package/dist/sol/dex/jup/portfolio.js +367 -0
- package/dist/sol/dex/jup/price.d.ts +173 -0
- package/dist/sol/dex/jup/price.js +220 -0
- package/dist/sol/dex/jup/recurring.d.ts +437 -0
- package/dist/sol/dex/jup/recurring.js +320 -0
- package/dist/sol/dex/jup/send.d.ts +282 -0
- package/dist/sol/dex/jup/send.js +295 -0
- package/dist/sol/dex/jup/studio.d.ts +457 -0
- package/dist/sol/dex/jup/studio.js +488 -0
- package/dist/sol/dex/jup/tokens.d.ts +767 -0
- package/dist/sol/dex/jup/tokens.js +697 -0
- package/dist/sol/dex/jup/trigger.d.ts +511 -0
- package/dist/sol/dex/jup/trigger.js +397 -0
- package/dist/sol/dex/jup/types.d.ts +433 -0
- package/dist/sol/dex/jup/types.js +5 -0
- package/dist/sol/dex/jup/ultra.d.ts +646 -0
- package/dist/sol/dex/jup/ultra.js +853 -0
- package/dist/sol/dex/meteora/client.d.ts +76 -0
- package/dist/sol/dex/meteora/client.js +219 -0
- package/dist/sol/dex/meteora/damm-v1-bundle.d.ts +61 -0
- package/dist/sol/dex/meteora/damm-v1-bundle.js +112 -0
- package/dist/sol/dex/meteora/damm-v1.d.ts +118 -0
- package/dist/sol/dex/meteora/damm-v1.js +315 -0
- package/dist/sol/dex/meteora/damm-v2-bundle.d.ts +82 -0
- package/dist/sol/dex/meteora/damm-v2-bundle.js +242 -0
- package/dist/sol/dex/meteora/damm-v2.d.ts +172 -0
- package/dist/sol/dex/meteora/damm-v2.js +632 -0
- package/dist/sol/dex/meteora/dbc-bundle.d.ts +123 -0
- package/dist/sol/dex/meteora/dbc-bundle.js +304 -0
- package/dist/sol/dex/meteora/dbc.d.ts +192 -0
- package/dist/sol/dex/meteora/dbc.js +619 -0
- package/dist/sol/dex/meteora/dlmm-bundle.d.ts +39 -0
- package/dist/sol/dex/meteora/dlmm-bundle.js +189 -0
- package/dist/sol/dex/meteora/dlmm.d.ts +157 -0
- package/dist/sol/dex/meteora/dlmm.js +671 -0
- package/dist/sol/dex/meteora/index.d.ts +25 -0
- package/dist/sol/dex/meteora/index.js +65 -0
- package/dist/sol/dex/meteora/types.d.ts +787 -0
- package/dist/sol/dex/meteora/types.js +110 -0
- package/dist/sol/dex/orca/index.d.ts +10 -0
- package/dist/sol/dex/orca/index.js +16 -0
- package/dist/sol/dex/orca/orca-bundle.d.ts +41 -0
- package/dist/sol/dex/orca/orca-bundle.js +173 -0
- package/dist/sol/dex/orca/orca.d.ts +65 -0
- package/dist/sol/dex/orca/orca.js +474 -0
- package/dist/sol/dex/orca/types.d.ts +263 -0
- package/dist/sol/dex/orca/types.js +38 -0
- package/dist/sol/dex/orca/wavebreak-bundle.d.ts +34 -0
- package/dist/sol/dex/orca/wavebreak-bundle.js +198 -0
- package/dist/sol/dex/orca/wavebreak-types.d.ts +227 -0
- package/dist/sol/dex/orca/wavebreak-types.js +23 -0
- package/dist/sol/dex/orca/wavebreak.d.ts +78 -0
- package/dist/sol/dex/orca/wavebreak.js +497 -0
- package/dist/sol/dex/pump/index.d.ts +9 -0
- package/dist/sol/dex/pump/index.js +14 -0
- package/dist/sol/dex/pump/pump-bundle.d.ts +92 -0
- package/dist/sol/dex/pump/pump-bundle.js +383 -0
- package/dist/sol/dex/pump/pump-swap-bundle.d.ts +103 -0
- package/dist/sol/dex/pump/pump-swap-bundle.js +380 -0
- package/dist/sol/dex/pump/pump-swap.d.ts +46 -0
- package/dist/sol/dex/pump/pump-swap.js +199 -0
- package/dist/sol/dex/pump/pump.d.ts +35 -0
- package/dist/sol/dex/pump/pump.js +352 -0
- package/dist/sol/dex/pump/types.d.ts +215 -0
- package/dist/sol/dex/pump/types.js +5 -0
- package/dist/sol/dex/raydium/index.d.ts +8 -0
- package/dist/sol/dex/raydium/index.js +12 -0
- package/dist/sol/dex/raydium/launchlab.d.ts +68 -0
- package/dist/sol/dex/raydium/launchlab.js +210 -0
- package/dist/sol/dex/raydium/raydium-bundle.d.ts +64 -0
- package/dist/sol/dex/raydium/raydium-bundle.js +324 -0
- package/dist/sol/dex/raydium/raydium.d.ts +40 -0
- package/dist/sol/dex/raydium/raydium.js +366 -0
- package/dist/sol/dex/raydium/types.d.ts +240 -0
- package/dist/sol/dex/raydium/types.js +5 -0
- package/dist/sol/index.d.ts +11 -0
- package/dist/sol/index.js +18 -0
- package/dist/sol/jito/bundle.d.ts +90 -0
- package/dist/sol/jito/bundle.js +263 -0
- package/dist/sol/jito/index.d.ts +7 -0
- package/dist/sol/jito/index.js +7 -0
- package/dist/sol/jito/tip.d.ts +51 -0
- package/dist/sol/jito/tip.js +83 -0
- package/dist/sol/jito/types.d.ts +100 -0
- package/dist/sol/jito/types.js +5 -0
- package/dist/sol/nozomi/client.d.ts +63 -0
- package/dist/sol/nozomi/client.js +222 -0
- package/dist/sol/nozomi/index.d.ts +8 -0
- package/dist/sol/nozomi/index.js +8 -0
- package/dist/sol/nozomi/tip.d.ts +50 -0
- package/dist/sol/nozomi/tip.js +80 -0
- package/dist/sol/nozomi/types.d.ts +96 -0
- package/dist/sol/nozomi/types.js +5 -0
- package/dist/sol/token/create-complete.d.ts +115 -0
- package/dist/sol/token/create-complete.js +235 -0
- package/dist/sol/token/create-token.d.ts +57 -0
- package/dist/sol/token/create-token.js +230 -0
- package/dist/sol/token/index.d.ts +9 -0
- package/dist/sol/token/index.js +14 -0
- package/dist/sol/token/metadata-upload.d.ts +86 -0
- package/dist/sol/token/metadata-upload.js +173 -0
- package/dist/sol/token/metadata.d.ts +92 -0
- package/dist/sol/token/metadata.js +274 -0
- package/dist/sol/token/types.d.ts +153 -0
- package/dist/sol/token/types.js +5 -0
- package/dist/sol/types.d.ts +176 -0
- package/dist/sol/types.js +7 -0
- package/dist/sol/utils/balance.d.ts +160 -0
- package/dist/sol/utils/balance.js +638 -0
- package/dist/sol/utils/connection.d.ts +78 -0
- package/dist/sol/utils/connection.js +168 -0
- package/dist/sol/utils/index.d.ts +9 -0
- package/dist/sol/utils/index.js +9 -0
- package/dist/sol/utils/lp-inspect.d.ts +75 -0
- package/dist/sol/utils/lp-inspect.js +235 -0
- package/dist/sol/utils/transfer.d.ts +196 -0
- package/dist/sol/utils/transfer.js +307 -0
- package/dist/sol/utils/wallet.d.ts +107 -0
- package/dist/sol/utils/wallet.js +210 -0
- package/package.json +44 -5
- package/README.zh-CN.pdf +0 -0
- package/dist/flap/portal-bundle-merkle/encryption.d.ts +0 -16
- package/dist/flap/portal-bundle-merkle/encryption.js +0 -146
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jito Bundle 构建和签名
|
|
3
|
+
* SDK 只负责构建和签名,提交到后端服务器广播
|
|
4
|
+
* @module sol/jito/bundle
|
|
5
|
+
*/
|
|
6
|
+
import { Connection, Keypair, Transaction, TransactionInstruction } from '@solana/web3.js';
|
|
7
|
+
import type { SerializedTransaction, SignedBundleData, TransactionBuildOptions } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Bundle 构建器
|
|
10
|
+
* 用于构建、签名 Jito Bundle,然后提交到后端
|
|
11
|
+
*/
|
|
12
|
+
export declare class BundleBuilder {
|
|
13
|
+
private connection;
|
|
14
|
+
private transactions;
|
|
15
|
+
private signers;
|
|
16
|
+
private tipAccount;
|
|
17
|
+
private tipLamports;
|
|
18
|
+
constructor(connection: Connection, options?: {
|
|
19
|
+
tipAccount?: string;
|
|
20
|
+
tipLamports?: bigint;
|
|
21
|
+
});
|
|
22
|
+
/**
|
|
23
|
+
* 添加交易
|
|
24
|
+
* @param transaction 交易
|
|
25
|
+
* @param signers 签名者列表
|
|
26
|
+
*/
|
|
27
|
+
addTransaction(transaction: Transaction, signers: Keypair[]): this;
|
|
28
|
+
/**
|
|
29
|
+
* 添加多个交易
|
|
30
|
+
* @param items 交易和签名者列表
|
|
31
|
+
*/
|
|
32
|
+
addTransactions(items: Array<{
|
|
33
|
+
transaction: Transaction;
|
|
34
|
+
signers: Keypair[];
|
|
35
|
+
}>): this;
|
|
36
|
+
/**
|
|
37
|
+
* 设置 Tip
|
|
38
|
+
* @param lamports Tip 金额
|
|
39
|
+
* @param account Tip 账户
|
|
40
|
+
*/
|
|
41
|
+
setTip(lamports: bigint, account?: string): this;
|
|
42
|
+
/**
|
|
43
|
+
* 获取交易数量
|
|
44
|
+
*/
|
|
45
|
+
getTransactionCount(): number;
|
|
46
|
+
/**
|
|
47
|
+
* 清空所有交易
|
|
48
|
+
*/
|
|
49
|
+
clear(): this;
|
|
50
|
+
/**
|
|
51
|
+
* 构建并签名 Bundle
|
|
52
|
+
* @param feePayer 手续费支付者
|
|
53
|
+
* @returns 签名后的 Bundle 数据,用于提交到后端
|
|
54
|
+
*/
|
|
55
|
+
buildAndSign(feePayer: Keypair): Promise<SignedBundleData>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 构建单个交易并签名(用于简单场景)
|
|
59
|
+
* @param connection Solana 连接
|
|
60
|
+
* @param instructions 指令列表
|
|
61
|
+
* @param signers 签名者列表(第一个为 feePayer)
|
|
62
|
+
* @param options 选项
|
|
63
|
+
*/
|
|
64
|
+
export declare function buildAndSignTransaction(connection: Connection, instructions: TransactionInstruction[], signers: Keypair[], options?: TransactionBuildOptions): Promise<SerializedTransaction>;
|
|
65
|
+
/**
|
|
66
|
+
* 构建批量交易并签名(每个钱包一笔交易)
|
|
67
|
+
* @param connection Solana 连接
|
|
68
|
+
* @param walletInstructions 每个钱包的指令
|
|
69
|
+
* @param options 选项
|
|
70
|
+
*/
|
|
71
|
+
export declare function buildAndSignBatchTransactions(connection: Connection, walletInstructions: Array<{
|
|
72
|
+
wallet: Keypair;
|
|
73
|
+
instructions: TransactionInstruction[];
|
|
74
|
+
}>, options?: TransactionBuildOptions & {
|
|
75
|
+
/** 统一的 feePayer,如果不指定则每个钱包自己付费 */
|
|
76
|
+
feePayer?: Keypair;
|
|
77
|
+
}): Promise<SignedBundleData>;
|
|
78
|
+
/**
|
|
79
|
+
* 将 SignedBundleData 转换为后端 API 需要的格式
|
|
80
|
+
* @param bundleData 签名后的 Bundle 数据
|
|
81
|
+
*/
|
|
82
|
+
export declare function toBundleRequest(bundleData: SignedBundleData): {
|
|
83
|
+
transactions: string[];
|
|
84
|
+
signatures: string[];
|
|
85
|
+
tipAccount: string;
|
|
86
|
+
tipLamports: string;
|
|
87
|
+
recentBlockhash: string;
|
|
88
|
+
lastValidBlockHeight: number;
|
|
89
|
+
timestamp: number;
|
|
90
|
+
};
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jito Bundle 构建和签名
|
|
3
|
+
* SDK 只负责构建和签名,提交到后端服务器广播
|
|
4
|
+
* @module sol/jito/bundle
|
|
5
|
+
*/
|
|
6
|
+
import { Transaction, ComputeBudgetProgram, } from '@solana/web3.js';
|
|
7
|
+
import { TX_CONFIG } from '../constants.js';
|
|
8
|
+
import { buildTipInstruction, getRandomTipAccount, calculateRecommendedTip } from './tip.js';
|
|
9
|
+
/**
|
|
10
|
+
* Bundle 构建器
|
|
11
|
+
* 用于构建、签名 Jito Bundle,然后提交到后端
|
|
12
|
+
*/
|
|
13
|
+
export class BundleBuilder {
|
|
14
|
+
constructor(connection, options) {
|
|
15
|
+
this.transactions = [];
|
|
16
|
+
this.signers = [];
|
|
17
|
+
this.connection = connection;
|
|
18
|
+
this.tipAccount = options?.tipAccount || getRandomTipAccount();
|
|
19
|
+
this.tipLamports = options?.tipLamports || BigInt(TX_CONFIG.COMPUTE_UNIT_PRICE);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 添加交易
|
|
23
|
+
* @param transaction 交易
|
|
24
|
+
* @param signers 签名者列表
|
|
25
|
+
*/
|
|
26
|
+
addTransaction(transaction, signers) {
|
|
27
|
+
this.transactions.push(transaction);
|
|
28
|
+
this.signers.push(signers);
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 添加多个交易
|
|
33
|
+
* @param items 交易和签名者列表
|
|
34
|
+
*/
|
|
35
|
+
addTransactions(items) {
|
|
36
|
+
for (const item of items) {
|
|
37
|
+
this.addTransaction(item.transaction, item.signers);
|
|
38
|
+
}
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 设置 Tip
|
|
43
|
+
* @param lamports Tip 金额
|
|
44
|
+
* @param account Tip 账户
|
|
45
|
+
*/
|
|
46
|
+
setTip(lamports, account) {
|
|
47
|
+
this.tipLamports = lamports;
|
|
48
|
+
if (account) {
|
|
49
|
+
this.tipAccount = account;
|
|
50
|
+
}
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 获取交易数量
|
|
55
|
+
*/
|
|
56
|
+
getTransactionCount() {
|
|
57
|
+
return this.transactions.length;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 清空所有交易
|
|
61
|
+
*/
|
|
62
|
+
clear() {
|
|
63
|
+
this.transactions = [];
|
|
64
|
+
this.signers = [];
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 构建并签名 Bundle
|
|
69
|
+
* @param feePayer 手续费支付者
|
|
70
|
+
* @returns 签名后的 Bundle 数据,用于提交到后端
|
|
71
|
+
*/
|
|
72
|
+
async buildAndSign(feePayer) {
|
|
73
|
+
if (this.transactions.length === 0) {
|
|
74
|
+
throw new Error('No transactions to bundle');
|
|
75
|
+
}
|
|
76
|
+
// 获取最新 blockhash
|
|
77
|
+
const { blockhash, lastValidBlockHeight } = await this.connection.getLatestBlockhash('finalized');
|
|
78
|
+
const serializedTransactions = [];
|
|
79
|
+
const allSignatures = [];
|
|
80
|
+
// 处理每个交易
|
|
81
|
+
for (let i = 0; i < this.transactions.length; i++) {
|
|
82
|
+
const tx = this.transactions[i];
|
|
83
|
+
const txSigners = this.signers[i];
|
|
84
|
+
// 设置 blockhash 和 feePayer
|
|
85
|
+
tx.recentBlockhash = blockhash;
|
|
86
|
+
tx.feePayer = feePayer.publicKey;
|
|
87
|
+
// 签名
|
|
88
|
+
const allTxSigners = [feePayer, ...txSigners.filter(s => !s.publicKey.equals(feePayer.publicKey))];
|
|
89
|
+
tx.sign(...allTxSigners);
|
|
90
|
+
// 序列化
|
|
91
|
+
const serialized = tx.serialize();
|
|
92
|
+
const signature = tx.signature?.toString('base64') || '';
|
|
93
|
+
serializedTransactions.push({
|
|
94
|
+
data: Buffer.from(serialized).toString('base64'),
|
|
95
|
+
isVersioned: false,
|
|
96
|
+
signature,
|
|
97
|
+
});
|
|
98
|
+
if (tx.signature) {
|
|
99
|
+
allSignatures.push(Buffer.from(tx.signature).toString('base64'));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// 创建 Tip 交易(最后一笔)
|
|
103
|
+
const tipTx = new Transaction().add(buildTipInstruction(feePayer.publicKey, this.tipLamports, this.tipAccount));
|
|
104
|
+
tipTx.recentBlockhash = blockhash;
|
|
105
|
+
tipTx.feePayer = feePayer.publicKey;
|
|
106
|
+
tipTx.sign(feePayer);
|
|
107
|
+
const tipSerialized = tipTx.serialize();
|
|
108
|
+
serializedTransactions.push({
|
|
109
|
+
data: Buffer.from(tipSerialized).toString('base64'),
|
|
110
|
+
isVersioned: false,
|
|
111
|
+
signature: tipTx.signature ? Buffer.from(tipTx.signature).toString('base64') : '',
|
|
112
|
+
});
|
|
113
|
+
if (tipTx.signature) {
|
|
114
|
+
allSignatures.push(Buffer.from(tipTx.signature).toString('base64'));
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
transactions: serializedTransactions,
|
|
118
|
+
signatures: allSignatures,
|
|
119
|
+
tip: {
|
|
120
|
+
account: this.tipAccount,
|
|
121
|
+
lamports: this.tipLamports,
|
|
122
|
+
},
|
|
123
|
+
recentBlockhash: blockhash,
|
|
124
|
+
lastValidBlockHeight,
|
|
125
|
+
createdAt: Date.now(),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* 构建单个交易并签名(用于简单场景)
|
|
131
|
+
* @param connection Solana 连接
|
|
132
|
+
* @param instructions 指令列表
|
|
133
|
+
* @param signers 签名者列表(第一个为 feePayer)
|
|
134
|
+
* @param options 选项
|
|
135
|
+
*/
|
|
136
|
+
export async function buildAndSignTransaction(connection, instructions, signers, options) {
|
|
137
|
+
if (signers.length === 0) {
|
|
138
|
+
throw new Error('At least one signer (feePayer) is required');
|
|
139
|
+
}
|
|
140
|
+
const feePayer = signers[0];
|
|
141
|
+
const { blockhash } = await connection.getLatestBlockhash('finalized');
|
|
142
|
+
const transaction = new Transaction();
|
|
143
|
+
// 添加计算预算指令(如果指定)
|
|
144
|
+
if (options?.computeUnitLimit) {
|
|
145
|
+
transaction.add(ComputeBudgetProgram.setComputeUnitLimit({
|
|
146
|
+
units: options.computeUnitLimit,
|
|
147
|
+
}));
|
|
148
|
+
}
|
|
149
|
+
if (options?.computeUnitPrice) {
|
|
150
|
+
transaction.add(ComputeBudgetProgram.setComputeUnitPrice({
|
|
151
|
+
microLamports: options.computeUnitPrice,
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
// 添加业务指令
|
|
155
|
+
transaction.add(...instructions);
|
|
156
|
+
// 添加 Tip 指令(如果需要)
|
|
157
|
+
if (options?.addTip) {
|
|
158
|
+
const tipLamports = options.tipLamports || calculateRecommendedTip(1);
|
|
159
|
+
transaction.add(buildTipInstruction(feePayer.publicKey, tipLamports, options.tipAccount));
|
|
160
|
+
}
|
|
161
|
+
transaction.recentBlockhash = blockhash;
|
|
162
|
+
transaction.feePayer = feePayer.publicKey;
|
|
163
|
+
transaction.sign(...signers);
|
|
164
|
+
const serialized = transaction.serialize();
|
|
165
|
+
return {
|
|
166
|
+
data: Buffer.from(serialized).toString('base64'),
|
|
167
|
+
isVersioned: false,
|
|
168
|
+
signature: transaction.signature ? Buffer.from(transaction.signature).toString('base64') : undefined,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* 构建批量交易并签名(每个钱包一笔交易)
|
|
173
|
+
* @param connection Solana 连接
|
|
174
|
+
* @param walletInstructions 每个钱包的指令
|
|
175
|
+
* @param options 选项
|
|
176
|
+
*/
|
|
177
|
+
export async function buildAndSignBatchTransactions(connection, walletInstructions, options) {
|
|
178
|
+
if (walletInstructions.length === 0) {
|
|
179
|
+
throw new Error('No transactions to build');
|
|
180
|
+
}
|
|
181
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('finalized');
|
|
182
|
+
const serializedTransactions = [];
|
|
183
|
+
const allSignatures = [];
|
|
184
|
+
// 确定 tip 支付者
|
|
185
|
+
const tipPayer = options?.feePayer || walletInstructions[0].wallet;
|
|
186
|
+
const tipAccount = options?.tipAccount || getRandomTipAccount();
|
|
187
|
+
const tipLamports = options?.tipLamports || calculateRecommendedTip(walletInstructions.length);
|
|
188
|
+
// 构建每个交易
|
|
189
|
+
for (const { wallet, instructions } of walletInstructions) {
|
|
190
|
+
const transaction = new Transaction();
|
|
191
|
+
// 添加计算预算
|
|
192
|
+
if (options?.computeUnitLimit) {
|
|
193
|
+
transaction.add(ComputeBudgetProgram.setComputeUnitLimit({
|
|
194
|
+
units: options.computeUnitLimit,
|
|
195
|
+
}));
|
|
196
|
+
}
|
|
197
|
+
if (options?.computeUnitPrice) {
|
|
198
|
+
transaction.add(ComputeBudgetProgram.setComputeUnitPrice({
|
|
199
|
+
microLamports: options.computeUnitPrice,
|
|
200
|
+
}));
|
|
201
|
+
}
|
|
202
|
+
// 添加业务指令
|
|
203
|
+
transaction.add(...instructions);
|
|
204
|
+
// 设置 blockhash 和 feePayer
|
|
205
|
+
transaction.recentBlockhash = blockhash;
|
|
206
|
+
transaction.feePayer = options?.feePayer?.publicKey || wallet.publicKey;
|
|
207
|
+
// 签名
|
|
208
|
+
const signers = options?.feePayer
|
|
209
|
+
? [options.feePayer, wallet].filter((s, i, arr) => arr.findIndex(x => x.publicKey.equals(s.publicKey)) === i)
|
|
210
|
+
: [wallet];
|
|
211
|
+
transaction.sign(...signers);
|
|
212
|
+
const serialized = transaction.serialize();
|
|
213
|
+
serializedTransactions.push({
|
|
214
|
+
data: Buffer.from(serialized).toString('base64'),
|
|
215
|
+
isVersioned: false,
|
|
216
|
+
signature: transaction.signature ? Buffer.from(transaction.signature).toString('base64') : undefined,
|
|
217
|
+
});
|
|
218
|
+
if (transaction.signature) {
|
|
219
|
+
allSignatures.push(Buffer.from(transaction.signature).toString('base64'));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// 添加 Tip 交易
|
|
223
|
+
if (options?.addTip !== false) {
|
|
224
|
+
const tipTx = new Transaction().add(buildTipInstruction(tipPayer.publicKey, tipLamports, tipAccount));
|
|
225
|
+
tipTx.recentBlockhash = blockhash;
|
|
226
|
+
tipTx.feePayer = tipPayer.publicKey;
|
|
227
|
+
tipTx.sign(tipPayer);
|
|
228
|
+
serializedTransactions.push({
|
|
229
|
+
data: Buffer.from(tipTx.serialize()).toString('base64'),
|
|
230
|
+
isVersioned: false,
|
|
231
|
+
signature: tipTx.signature ? Buffer.from(tipTx.signature).toString('base64') : undefined,
|
|
232
|
+
});
|
|
233
|
+
if (tipTx.signature) {
|
|
234
|
+
allSignatures.push(Buffer.from(tipTx.signature).toString('base64'));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
transactions: serializedTransactions,
|
|
239
|
+
signatures: allSignatures,
|
|
240
|
+
tip: {
|
|
241
|
+
account: tipAccount,
|
|
242
|
+
lamports: tipLamports,
|
|
243
|
+
},
|
|
244
|
+
recentBlockhash: blockhash,
|
|
245
|
+
lastValidBlockHeight,
|
|
246
|
+
createdAt: Date.now(),
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* 将 SignedBundleData 转换为后端 API 需要的格式
|
|
251
|
+
* @param bundleData 签名后的 Bundle 数据
|
|
252
|
+
*/
|
|
253
|
+
export function toBundleRequest(bundleData) {
|
|
254
|
+
return {
|
|
255
|
+
transactions: bundleData.transactions.map(tx => tx.data),
|
|
256
|
+
signatures: bundleData.signatures,
|
|
257
|
+
tipAccount: bundleData.tip.account,
|
|
258
|
+
tipLamports: bundleData.tip.lamports.toString(),
|
|
259
|
+
recentBlockhash: bundleData.recentBlockhash,
|
|
260
|
+
lastValidBlockHeight: bundleData.lastValidBlockHeight,
|
|
261
|
+
timestamp: bundleData.createdAt,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jito Tip 相关功能
|
|
3
|
+
* @module sol/jito/tip
|
|
4
|
+
*/
|
|
5
|
+
import { PublicKey, TransactionInstruction } from '@solana/web3.js';
|
|
6
|
+
/**
|
|
7
|
+
* 随机选择一个 Tip 账户
|
|
8
|
+
* @returns Tip 账户地址
|
|
9
|
+
*/
|
|
10
|
+
export declare function getRandomTipAccount(): string;
|
|
11
|
+
/**
|
|
12
|
+
* 获取所有 Tip 账户
|
|
13
|
+
* @returns Tip 账户列表
|
|
14
|
+
*/
|
|
15
|
+
export declare function getAllTipAccounts(): string[];
|
|
16
|
+
/**
|
|
17
|
+
* 验证是否是有效的 Tip 账户
|
|
18
|
+
* @param address 地址
|
|
19
|
+
*/
|
|
20
|
+
export declare function isValidTipAccount(address: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* 构建 Tip 指令
|
|
23
|
+
* @param fromPubkey 付款者公钥
|
|
24
|
+
* @param tipLamports Tip 金额(lamports)
|
|
25
|
+
* @param tipAccount 可选:指定 Tip 账户,默认随机选择
|
|
26
|
+
* @returns TransactionInstruction
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildTipInstruction(fromPubkey: PublicKey, tipLamports?: bigint, tipAccount?: string): TransactionInstruction;
|
|
29
|
+
/**
|
|
30
|
+
* 计算推荐的 Tip 金额
|
|
31
|
+
* 根据交易数量和优先级计算
|
|
32
|
+
* @param txCount 交易数量
|
|
33
|
+
* @param priority 优先级 (1-10,10 最高)
|
|
34
|
+
* @returns 推荐的 Tip 金额(lamports)
|
|
35
|
+
*/
|
|
36
|
+
export declare function calculateRecommendedTip(txCount?: number, priority?: number): bigint;
|
|
37
|
+
/**
|
|
38
|
+
* Tip 金额预设
|
|
39
|
+
*/
|
|
40
|
+
export declare const TIP_PRESETS: {
|
|
41
|
+
/** 最低 tip (0.00001 SOL) */
|
|
42
|
+
readonly LOW: bigint;
|
|
43
|
+
/** 标准 tip (0.0001 SOL) */
|
|
44
|
+
readonly STANDARD: bigint;
|
|
45
|
+
/** 中等 tip (0.0005 SOL) */
|
|
46
|
+
readonly MEDIUM: bigint;
|
|
47
|
+
/** 高 tip (0.001 SOL) */
|
|
48
|
+
readonly HIGH: bigint;
|
|
49
|
+
/** 紧急 tip (0.005 SOL) */
|
|
50
|
+
readonly URGENT: bigint;
|
|
51
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jito Tip 相关功能
|
|
3
|
+
* @module sol/jito/tip
|
|
4
|
+
*/
|
|
5
|
+
import { PublicKey, SystemProgram, } from '@solana/web3.js';
|
|
6
|
+
import { JITO_CONFIG } from '../constants.js';
|
|
7
|
+
/**
|
|
8
|
+
* 随机选择一个 Tip 账户
|
|
9
|
+
* @returns Tip 账户地址
|
|
10
|
+
*/
|
|
11
|
+
export function getRandomTipAccount() {
|
|
12
|
+
const accounts = JITO_CONFIG.TIP_ACCOUNTS;
|
|
13
|
+
const index = Math.floor(Math.random() * accounts.length);
|
|
14
|
+
return accounts[index];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 获取所有 Tip 账户
|
|
18
|
+
* @returns Tip 账户列表
|
|
19
|
+
*/
|
|
20
|
+
export function getAllTipAccounts() {
|
|
21
|
+
return [...JITO_CONFIG.TIP_ACCOUNTS];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 验证是否是有效的 Tip 账户
|
|
25
|
+
* @param address 地址
|
|
26
|
+
*/
|
|
27
|
+
export function isValidTipAccount(address) {
|
|
28
|
+
return JITO_CONFIG.TIP_ACCOUNTS.includes(address);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 构建 Tip 指令
|
|
32
|
+
* @param fromPubkey 付款者公钥
|
|
33
|
+
* @param tipLamports Tip 金额(lamports)
|
|
34
|
+
* @param tipAccount 可选:指定 Tip 账户,默认随机选择
|
|
35
|
+
* @returns TransactionInstruction
|
|
36
|
+
*/
|
|
37
|
+
export function buildTipInstruction(fromPubkey, tipLamports = BigInt(JITO_CONFIG.DEFAULT_TIP_LAMPORTS), tipAccount) {
|
|
38
|
+
const tipAccountAddress = tipAccount || getRandomTipAccount();
|
|
39
|
+
// 确保 tip 金额不低于最小值
|
|
40
|
+
const finalTip = tipLamports < BigInt(JITO_CONFIG.MIN_TIP_LAMPORTS)
|
|
41
|
+
? BigInt(JITO_CONFIG.MIN_TIP_LAMPORTS)
|
|
42
|
+
: tipLamports;
|
|
43
|
+
return SystemProgram.transfer({
|
|
44
|
+
fromPubkey,
|
|
45
|
+
toPubkey: new PublicKey(tipAccountAddress),
|
|
46
|
+
lamports: finalTip,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 计算推荐的 Tip 金额
|
|
51
|
+
* 根据交易数量和优先级计算
|
|
52
|
+
* @param txCount 交易数量
|
|
53
|
+
* @param priority 优先级 (1-10,10 最高)
|
|
54
|
+
* @returns 推荐的 Tip 金额(lamports)
|
|
55
|
+
*/
|
|
56
|
+
export function calculateRecommendedTip(txCount = 1, priority = 5) {
|
|
57
|
+
// 基础 tip
|
|
58
|
+
const baseTip = BigInt(JITO_CONFIG.DEFAULT_TIP_LAMPORTS);
|
|
59
|
+
// 根据交易数量增加
|
|
60
|
+
const txMultiplier = BigInt(Math.max(1, txCount));
|
|
61
|
+
// 根据优先级增加(1-10 映射到 0.5x - 2x)
|
|
62
|
+
const priorityMultiplier = 0.5 + (priority / 10) * 1.5;
|
|
63
|
+
const tip = BigInt(Math.floor(Number(baseTip * txMultiplier) * priorityMultiplier));
|
|
64
|
+
// 确保不低于最小值
|
|
65
|
+
return tip < BigInt(JITO_CONFIG.MIN_TIP_LAMPORTS)
|
|
66
|
+
? BigInt(JITO_CONFIG.MIN_TIP_LAMPORTS)
|
|
67
|
+
: tip;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Tip 金额预设
|
|
71
|
+
*/
|
|
72
|
+
export const TIP_PRESETS = {
|
|
73
|
+
/** 最低 tip (0.00001 SOL) */
|
|
74
|
+
LOW: BigInt(10000),
|
|
75
|
+
/** 标准 tip (0.0001 SOL) */
|
|
76
|
+
STANDARD: BigInt(100000),
|
|
77
|
+
/** 中等 tip (0.0005 SOL) */
|
|
78
|
+
MEDIUM: BigInt(500000),
|
|
79
|
+
/** 高 tip (0.001 SOL) */
|
|
80
|
+
HIGH: BigInt(1000000),
|
|
81
|
+
/** 紧急 tip (0.005 SOL) */
|
|
82
|
+
URGENT: BigInt(5000000),
|
|
83
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jito Bundle 类型定义
|
|
3
|
+
* @module sol/jito/types
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Jito Bundle 状态
|
|
7
|
+
*/
|
|
8
|
+
export type JitoBundleStatus = 'pending' | 'landed' | 'failed' | 'invalid' | 'dropped';
|
|
9
|
+
/**
|
|
10
|
+
* Jito Bundle 提交结果
|
|
11
|
+
*/
|
|
12
|
+
export interface JitoBundleSubmitResult {
|
|
13
|
+
success: boolean;
|
|
14
|
+
bundleId?: string;
|
|
15
|
+
error?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Jito Bundle 状态查询结果
|
|
19
|
+
*/
|
|
20
|
+
export interface JitoBundleStatusResult {
|
|
21
|
+
bundleId: string;
|
|
22
|
+
status: JitoBundleStatus;
|
|
23
|
+
slot?: number;
|
|
24
|
+
confirmationStatus?: string;
|
|
25
|
+
error?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 序列化的交易(用于提交到后端)
|
|
29
|
+
*/
|
|
30
|
+
export interface SerializedTransaction {
|
|
31
|
+
/** Base64 编码的交易数据 */
|
|
32
|
+
data: string;
|
|
33
|
+
/** 是否是 VersionedTransaction */
|
|
34
|
+
isVersioned: boolean;
|
|
35
|
+
/** 交易签名(如果已签名) */
|
|
36
|
+
signature?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Bundle 请求(提交到后端)
|
|
40
|
+
*/
|
|
41
|
+
export interface BundleRequest {
|
|
42
|
+
/** 序列化的交易列表 */
|
|
43
|
+
transactions: SerializedTransaction[];
|
|
44
|
+
/** Tip 金额(lamports) */
|
|
45
|
+
tipLamports: bigint;
|
|
46
|
+
/** Tip 账户地址 */
|
|
47
|
+
tipAccount: string;
|
|
48
|
+
/** 请求时间戳 */
|
|
49
|
+
timestamp: number;
|
|
50
|
+
/** 可选:最后有效区块高度 */
|
|
51
|
+
lastValidBlockHeight?: number;
|
|
52
|
+
/** 可选:blockhash */
|
|
53
|
+
recentBlockhash?: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Bundle 响应(从后端返回)
|
|
57
|
+
*/
|
|
58
|
+
export interface BundleResponse {
|
|
59
|
+
success: boolean;
|
|
60
|
+
bundleId?: string;
|
|
61
|
+
signatures?: string[];
|
|
62
|
+
error?: string;
|
|
63
|
+
/** 后端处理时间 */
|
|
64
|
+
processingTime?: number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 交易构建选项
|
|
68
|
+
*/
|
|
69
|
+
export interface TransactionBuildOptions {
|
|
70
|
+
/** 是否添加 Jito Tip */
|
|
71
|
+
addTip?: boolean;
|
|
72
|
+
/** Tip 金额(lamports),默认使用 JITO_CONFIG.DEFAULT_TIP_LAMPORTS */
|
|
73
|
+
tipLamports?: bigint;
|
|
74
|
+
/** 指定 Tip 账户,默认随机选择 */
|
|
75
|
+
tipAccount?: string;
|
|
76
|
+
/** 计算单元限制 */
|
|
77
|
+
computeUnitLimit?: number;
|
|
78
|
+
/** 计算单元价格(microlamports) */
|
|
79
|
+
computeUnitPrice?: number;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 签名后的 Bundle 数据(准备提交到后端)
|
|
83
|
+
*/
|
|
84
|
+
export interface SignedBundleData {
|
|
85
|
+
/** 序列化的交易列表 */
|
|
86
|
+
transactions: SerializedTransaction[];
|
|
87
|
+
/** 所有交易签名 */
|
|
88
|
+
signatures: string[];
|
|
89
|
+
/** Tip 信息 */
|
|
90
|
+
tip: {
|
|
91
|
+
account: string;
|
|
92
|
+
lamports: bigint;
|
|
93
|
+
};
|
|
94
|
+
/** blockhash */
|
|
95
|
+
recentBlockhash: string;
|
|
96
|
+
/** 最后有效区块高度 */
|
|
97
|
+
lastValidBlockHeight: number;
|
|
98
|
+
/** 创建时间 */
|
|
99
|
+
createdAt: number;
|
|
100
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nozomi 客户端
|
|
3
|
+
* 用于发送交易到 Temporal Nozomi 服务
|
|
4
|
+
* @module sol/nozomi/client
|
|
5
|
+
*/
|
|
6
|
+
import { Connection, Keypair, Transaction, VersionedTransaction, TransactionInstruction } from '@solana/web3.js';
|
|
7
|
+
import type { NozomiClientConfig, NozomiSendOptions, NozomiSendResult, NozomiBatchSendResult, NozomiTransactionBuildOptions, NozomiRegion } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Nozomi 客户端
|
|
10
|
+
* 用于发送交易到 Temporal Nozomi 服务
|
|
11
|
+
*/
|
|
12
|
+
export declare class NozomiClient {
|
|
13
|
+
private apiKeyFast;
|
|
14
|
+
private apiKeyMev;
|
|
15
|
+
private defaultRegion;
|
|
16
|
+
private defaultUseMevProtection;
|
|
17
|
+
private timeout;
|
|
18
|
+
constructor(config: NozomiClientConfig);
|
|
19
|
+
/**
|
|
20
|
+
* 获取 Nozomi 端点 URL
|
|
21
|
+
* @param useMevProtection 是否使用 MEV 保护
|
|
22
|
+
* @param region 区域
|
|
23
|
+
*/
|
|
24
|
+
getEndpoint(useMevProtection?: boolean, region?: NozomiRegion): string;
|
|
25
|
+
/**
|
|
26
|
+
* 发送单笔交易
|
|
27
|
+
* @param transaction 交易(Transaction 或 VersionedTransaction)
|
|
28
|
+
* @param options 发送选项
|
|
29
|
+
*/
|
|
30
|
+
sendTransaction(transaction: Transaction | VersionedTransaction, options?: NozomiSendOptions): Promise<NozomiSendResult>;
|
|
31
|
+
/**
|
|
32
|
+
* 批量发送交易(并行发送,非 Bundle)
|
|
33
|
+
* @param transactions 交易列表
|
|
34
|
+
* @param options 发送选项
|
|
35
|
+
*/
|
|
36
|
+
sendTransactions(transactions: Array<Transaction | VersionedTransaction>, options?: NozomiSendOptions): Promise<NozomiBatchSendResult>;
|
|
37
|
+
/**
|
|
38
|
+
* 构建并发送交易
|
|
39
|
+
* @param connection Solana 连接(用于获取 blockhash)
|
|
40
|
+
* @param instructions 指令列表
|
|
41
|
+
* @param signers 签名者列表(第一个为 feePayer)
|
|
42
|
+
* @param buildOptions 构建选项
|
|
43
|
+
* @param sendOptions 发送选项
|
|
44
|
+
*/
|
|
45
|
+
buildAndSendTransaction(connection: Connection, instructions: TransactionInstruction[], signers: Keypair[], buildOptions?: NozomiTransactionBuildOptions, sendOptions?: NozomiSendOptions): Promise<NozomiSendResult>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 构建带 Nozomi Tip 的交易
|
|
49
|
+
* @param connection Solana 连接
|
|
50
|
+
* @param instructions 指令列表
|
|
51
|
+
* @param feePayer 手续费支付者
|
|
52
|
+
* @param options 构建选项
|
|
53
|
+
*/
|
|
54
|
+
export declare function buildNozomiTransaction(connection: Connection, instructions: TransactionInstruction[], feePayer: Keypair, options?: NozomiTransactionBuildOptions): Promise<Transaction>;
|
|
55
|
+
/**
|
|
56
|
+
* 将现有交易添加 Nozomi Tip
|
|
57
|
+
* 注意:这会在交易开头添加 Tip 指令
|
|
58
|
+
* @param transaction 原始交易
|
|
59
|
+
* @param feePayer 手续费支付者
|
|
60
|
+
* @param tipLamports Tip 金额
|
|
61
|
+
* @param tipAccount Tip 账户
|
|
62
|
+
*/
|
|
63
|
+
export declare function addNozomiTipToTransaction(transaction: Transaction, feePayer: Keypair, tipLamports?: bigint, tipAccount?: string): Transaction;
|