four-flap-meme-sdk 1.3.82 → 1.3.84

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 (103) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +1 -0
  3. package/dist/sol/constants.d.ts +136 -0
  4. package/dist/sol/constants.js +156 -0
  5. package/dist/sol/dex/index.d.ts +8 -0
  6. package/dist/sol/dex/index.js +12 -0
  7. package/dist/sol/dex/meteora/client.d.ts +75 -0
  8. package/dist/sol/dex/meteora/client.js +218 -0
  9. package/dist/sol/dex/meteora/damm-v1-bundle.d.ts +61 -0
  10. package/dist/sol/dex/meteora/damm-v1-bundle.js +112 -0
  11. package/dist/sol/dex/meteora/damm-v1.d.ts +118 -0
  12. package/dist/sol/dex/meteora/damm-v1.js +315 -0
  13. package/dist/sol/dex/meteora/damm-v2-bundle.d.ts +82 -0
  14. package/dist/sol/dex/meteora/damm-v2-bundle.js +242 -0
  15. package/dist/sol/dex/meteora/damm-v2.d.ts +172 -0
  16. package/dist/sol/dex/meteora/damm-v2.js +632 -0
  17. package/dist/sol/dex/meteora/dbc-bundle.d.ts +123 -0
  18. package/dist/sol/dex/meteora/dbc-bundle.js +304 -0
  19. package/dist/sol/dex/meteora/dbc.d.ts +192 -0
  20. package/dist/sol/dex/meteora/dbc.js +619 -0
  21. package/dist/sol/dex/meteora/dlmm-bundle.d.ts +39 -0
  22. package/dist/sol/dex/meteora/dlmm-bundle.js +189 -0
  23. package/dist/sol/dex/meteora/dlmm.d.ts +146 -0
  24. package/dist/sol/dex/meteora/dlmm.js +593 -0
  25. package/dist/sol/dex/meteora/index.d.ts +25 -0
  26. package/dist/sol/dex/meteora/index.js +65 -0
  27. package/dist/sol/dex/meteora/types.d.ts +787 -0
  28. package/dist/sol/dex/meteora/types.js +110 -0
  29. package/dist/sol/dex/orca/index.d.ts +10 -0
  30. package/dist/sol/dex/orca/index.js +16 -0
  31. package/dist/sol/dex/orca/orca-bundle.d.ts +41 -0
  32. package/dist/sol/dex/orca/orca-bundle.js +140 -0
  33. package/dist/sol/dex/orca/orca.d.ts +65 -0
  34. package/dist/sol/dex/orca/orca.js +426 -0
  35. package/dist/sol/dex/orca/types.d.ts +263 -0
  36. package/dist/sol/dex/orca/types.js +38 -0
  37. package/dist/sol/dex/orca/wavebreak-bundle.d.ts +34 -0
  38. package/dist/sol/dex/orca/wavebreak-bundle.js +189 -0
  39. package/dist/sol/dex/orca/wavebreak-types.d.ts +227 -0
  40. package/dist/sol/dex/orca/wavebreak-types.js +23 -0
  41. package/dist/sol/dex/orca/wavebreak.d.ts +78 -0
  42. package/dist/sol/dex/orca/wavebreak.js +469 -0
  43. package/dist/sol/dex/pump/index.d.ts +9 -0
  44. package/dist/sol/dex/pump/index.js +14 -0
  45. package/dist/sol/dex/pump/pump-bundle.d.ts +92 -0
  46. package/dist/sol/dex/pump/pump-bundle.js +383 -0
  47. package/dist/sol/dex/pump/pump-swap-bundle.d.ts +103 -0
  48. package/dist/sol/dex/pump/pump-swap-bundle.js +380 -0
  49. package/dist/sol/dex/pump/pump-swap.d.ts +46 -0
  50. package/dist/sol/dex/pump/pump-swap.js +199 -0
  51. package/dist/sol/dex/pump/pump.d.ts +35 -0
  52. package/dist/sol/dex/pump/pump.js +352 -0
  53. package/dist/sol/dex/pump/types.d.ts +215 -0
  54. package/dist/sol/dex/pump/types.js +5 -0
  55. package/dist/sol/dex/raydium/index.d.ts +8 -0
  56. package/dist/sol/dex/raydium/index.js +12 -0
  57. package/dist/sol/dex/raydium/launchlab.d.ts +68 -0
  58. package/dist/sol/dex/raydium/launchlab.js +210 -0
  59. package/dist/sol/dex/raydium/raydium-bundle.d.ts +64 -0
  60. package/dist/sol/dex/raydium/raydium-bundle.js +324 -0
  61. package/dist/sol/dex/raydium/raydium.d.ts +40 -0
  62. package/dist/sol/dex/raydium/raydium.js +366 -0
  63. package/dist/sol/dex/raydium/types.d.ts +240 -0
  64. package/dist/sol/dex/raydium/types.js +5 -0
  65. package/dist/sol/index.d.ts +10 -0
  66. package/dist/sol/index.js +16 -0
  67. package/dist/sol/jito/bundle.d.ts +90 -0
  68. package/dist/sol/jito/bundle.js +263 -0
  69. package/dist/sol/jito/index.d.ts +7 -0
  70. package/dist/sol/jito/index.js +7 -0
  71. package/dist/sol/jito/tip.d.ts +51 -0
  72. package/dist/sol/jito/tip.js +83 -0
  73. package/dist/sol/jito/types.d.ts +100 -0
  74. package/dist/sol/jito/types.js +5 -0
  75. package/dist/sol/token/create-complete.d.ts +115 -0
  76. package/dist/sol/token/create-complete.js +235 -0
  77. package/dist/sol/token/create-token.d.ts +57 -0
  78. package/dist/sol/token/create-token.js +230 -0
  79. package/dist/sol/token/index.d.ts +9 -0
  80. package/dist/sol/token/index.js +14 -0
  81. package/dist/sol/token/metadata-upload.d.ts +86 -0
  82. package/dist/sol/token/metadata-upload.js +173 -0
  83. package/dist/sol/token/metadata.d.ts +92 -0
  84. package/dist/sol/token/metadata.js +274 -0
  85. package/dist/sol/token/types.d.ts +153 -0
  86. package/dist/sol/token/types.js +5 -0
  87. package/dist/sol/types.d.ts +176 -0
  88. package/dist/sol/types.js +7 -0
  89. package/dist/sol/utils/balance.d.ts +160 -0
  90. package/dist/sol/utils/balance.js +638 -0
  91. package/dist/sol/utils/connection.d.ts +69 -0
  92. package/dist/sol/utils/connection.js +156 -0
  93. package/dist/sol/utils/index.d.ts +9 -0
  94. package/dist/sol/utils/index.js +9 -0
  95. package/dist/sol/utils/lp-inspect.d.ts +129 -0
  96. package/dist/sol/utils/lp-inspect.js +515 -0
  97. package/dist/sol/utils/transfer.d.ts +125 -0
  98. package/dist/sol/utils/transfer.js +220 -0
  99. package/dist/sol/utils/wallet.d.ts +107 -0
  100. package/dist/sol/utils/wallet.js +210 -0
  101. package/package.json +24 -3
  102. package/dist/flap/portal-bundle-merkle/encryption.d.ts +0 -16
  103. package/dist/flap/portal-bundle-merkle/encryption.js +0 -146
@@ -0,0 +1,426 @@
1
+ /**
2
+ * Orca Whirlpool 核心功能
3
+ * 提供 Swap、LP 添加/移除等功能
4
+ *
5
+ * 基于 @orca-so/whirlpools-sdk (Legacy SDK)
6
+ * 文档: https://dev.orca.so/SDKs/Overview
7
+ */
8
+ import { PublicKey, } from '@solana/web3.js';
9
+ import { Wallet as AnchorWallet } from '@coral-xyz/anchor';
10
+ import { WhirlpoolContext, buildWhirlpoolClient, ORCA_WHIRLPOOL_PROGRAM_ID, PDAUtil, TickUtil, PriceMath, PoolUtil, TokenExtensionUtil, } from '@orca-so/whirlpools-sdk';
11
+ import { Percentage, AddressUtil, DecimalUtil } from '@orca-so/common-sdk';
12
+ import { createConnection } from '../../utils/connection.js';
13
+ import { ORCA_WHIRLPOOL_CONFIG } from './types.js';
14
+ /**
15
+ * 创建 Orca Whirlpool Context
16
+ */
17
+ export async function createOrcaContext(connection, wallet) {
18
+ const conn = connection || createConnection();
19
+ // 创建 Anchor Wallet 适配器
20
+ const anchorWallet = wallet
21
+ ? new AnchorWallet(wallet)
22
+ : {
23
+ publicKey: PublicKey.default,
24
+ signTransaction: async (tx) => tx,
25
+ signAllTransactions: async (txs) => txs,
26
+ };
27
+ // WhirlpoolContext.from 只需要 connection 和 wallet
28
+ const ctx = WhirlpoolContext.from(conn, anchorWallet);
29
+ return ctx;
30
+ }
31
+ /**
32
+ * 创建 Orca Whirlpool Client
33
+ */
34
+ export async function createOrcaClient(connection, wallet) {
35
+ const ctx = await createOrcaContext(connection, wallet);
36
+ return buildWhirlpoolClient(ctx);
37
+ }
38
+ /**
39
+ * 获取 Orca Whirlpool 池信息
40
+ */
41
+ export async function getOrcaPoolInfo(poolAddress, connection) {
42
+ const client = await createOrcaClient(connection);
43
+ const pool = await client.getPool(poolAddress);
44
+ const data = pool.getData();
45
+ const tokenInfoA = pool.getTokenAInfo();
46
+ const tokenInfoB = pool.getTokenBInfo();
47
+ const vaultInfoA = pool.getTokenVaultAInfo();
48
+ const vaultInfoB = pool.getTokenVaultBInfo();
49
+ const rewardInfos = pool.getRewardInfos();
50
+ // 计算当前价格
51
+ const price = PriceMath.sqrtPriceX64ToPrice(data.sqrtPrice, tokenInfoA.decimals, tokenInfoB.decimals);
52
+ return {
53
+ poolAddress,
54
+ tokenMintA: tokenInfoA.mint.toBase58(),
55
+ tokenMintB: tokenInfoB.mint.toBase58(),
56
+ tokenDecimalsA: tokenInfoA.decimals,
57
+ tokenDecimalsB: tokenInfoB.decimals,
58
+ tokenVaultA: vaultInfoA.address.toBase58(),
59
+ tokenVaultB: vaultInfoB.address.toBase58(),
60
+ price: price.toNumber(),
61
+ sqrtPrice: data.sqrtPrice.toString(),
62
+ currentTick: data.tickCurrentIndex,
63
+ tickSpacing: data.tickSpacing,
64
+ feeRate: data.feeRate,
65
+ protocolFeeRate: data.protocolFeeRate,
66
+ liquidity: data.liquidity.toString(),
67
+ feeGrowthGlobalA: data.feeGrowthGlobalA.toString(),
68
+ feeGrowthGlobalB: data.feeGrowthGlobalB.toString(),
69
+ rewardInfos: rewardInfos.map(info => ({
70
+ mint: info.mint.toBase58(),
71
+ vault: info.vault.toBase58(),
72
+ emissionsPerSecond: info.emissionsPerSecondX64.toString(),
73
+ growthGlobal: info.growthGlobalX64.toString(),
74
+ })),
75
+ };
76
+ }
77
+ /**
78
+ * 查找 Orca Whirlpool 池
79
+ */
80
+ export async function findOrcaPool(tokenMintA, tokenMintB, tickSpacing = 64, connection) {
81
+ const conn = connection || createConnection();
82
+ // 确保代币顺序正确 (按地址排序)
83
+ const [mintAAddr, mintBAddr] = PoolUtil.orderMints(new PublicKey(tokenMintA), new PublicKey(tokenMintB));
84
+ // 转换为 PublicKey
85
+ const mintA = AddressUtil.toPubKey(mintAAddr);
86
+ const mintB = AddressUtil.toPubKey(mintBAddr);
87
+ // 计算池 PDA
88
+ const poolPda = PDAUtil.getWhirlpool(ORCA_WHIRLPOOL_PROGRAM_ID, new PublicKey(ORCA_WHIRLPOOL_CONFIG.MAINNET), mintA, mintB, tickSpacing);
89
+ // 检查池是否存在
90
+ const accountInfo = await conn.getAccountInfo(poolPda.publicKey);
91
+ return accountInfo ? poolPda.publicKey.toBase58() : null;
92
+ }
93
+ /**
94
+ * 签名 Orca Swap 交易
95
+ * 使用 Whirlpool 的高级 swap 接口
96
+ */
97
+ export async function signOrcaSwap(params, payer, connection) {
98
+ const conn = connection || createConnection();
99
+ const client = await createOrcaClient(conn, payer);
100
+ const pool = await client.getPool(params.poolAddress);
101
+ const ctx = await createOrcaContext(conn, payer);
102
+ const inputMint = new PublicKey(params.inputMint);
103
+ const slippage = Percentage.fromFraction(params.slippageBps || 100, 10000);
104
+ // 获取 token extension context
105
+ const tokenInfoA = pool.getTokenAInfo();
106
+ const tokenInfoB = pool.getTokenBInfo();
107
+ const tokenExtensionCtx = await TokenExtensionUtil.buildTokenExtensionContextForPool(ctx.fetcher, tokenInfoA.mint, tokenInfoB.mint);
108
+ // 使用 SDK 的 swapQuoteByInputToken
109
+ const { swapQuoteByInputToken } = await import('@orca-so/whirlpools-sdk');
110
+ const quote = await swapQuoteByInputToken(pool, inputMint, params.amountIn, slippage, ORCA_WHIRLPOOL_PROGRAM_ID, ctx.fetcher);
111
+ // 构建 swap 交易
112
+ const txBuilder = await pool.swap(quote, payer.publicKey);
113
+ // 获取最新区块哈希
114
+ const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash();
115
+ // 构建交易
116
+ const tx = await txBuilder.build();
117
+ // 如果是 Transaction 类型
118
+ if ('recentBlockhash' in tx.transaction) {
119
+ const transaction = tx.transaction;
120
+ transaction.recentBlockhash = blockhash;
121
+ transaction.lastValidBlockHeight = lastValidBlockHeight;
122
+ transaction.feePayer = payer.publicKey;
123
+ // 签名
124
+ transaction.sign(payer, ...tx.signers);
125
+ return {
126
+ signedTransaction: transaction,
127
+ type: 'swap',
128
+ poolAddress: params.poolAddress,
129
+ metadata: {
130
+ estimatedAmountOut: quote.estimatedAmountOut.toString(),
131
+ },
132
+ };
133
+ }
134
+ // VersionedTransaction 类型
135
+ const versionedTx = tx.transaction;
136
+ versionedTx.sign([payer, ...tx.signers]);
137
+ return {
138
+ signedTransaction: versionedTx,
139
+ type: 'swap',
140
+ poolAddress: params.poolAddress,
141
+ metadata: {
142
+ estimatedAmountOut: quote.estimatedAmountOut.toString(),
143
+ },
144
+ };
145
+ }
146
+ /**
147
+ * 签名 Orca 添加流动性交易
148
+ */
149
+ export async function signOrcaAddLiquidity(params, payer, connection) {
150
+ const conn = connection || createConnection();
151
+ const client = await createOrcaClient(conn, payer);
152
+ const pool = await client.getPool(params.poolAddress);
153
+ const ctx = await createOrcaContext(conn, payer);
154
+ const tokenInfoA = pool.getTokenAInfo();
155
+ const tokenInfoB = pool.getTokenBInfo();
156
+ const slippage = Percentage.fromFraction(params.slippageBps || 100, 10000);
157
+ // 获取 token extension context
158
+ const tokenExtensionCtx = await TokenExtensionUtil.buildTokenExtensionContextForPool(ctx.fetcher, tokenInfoA.mint, tokenInfoB.mint);
159
+ // 计算流动性报价
160
+ const { increaseLiquidityQuoteByInputToken } = await import('@orca-so/whirlpools-sdk');
161
+ // 使用 DecimalUtil 创建 Decimal 值 (从 BN 转换,不带小数位移位)
162
+ const inputAmount = DecimalUtil.fromBN(params.tokenAmountA, 0);
163
+ const quote = increaseLiquidityQuoteByInputToken(tokenInfoA.mint, inputAmount, params.tickLower, params.tickUpper, slippage, pool, tokenExtensionCtx);
164
+ const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash();
165
+ if (params.createNewPosition !== false) {
166
+ // 创建新的 position
167
+ const { positionMint, tx: txBuilder } = await pool.openPosition(params.tickLower, params.tickUpper, quote);
168
+ const tx = await txBuilder.build();
169
+ if ('recentBlockhash' in tx.transaction) {
170
+ const transaction = tx.transaction;
171
+ transaction.recentBlockhash = blockhash;
172
+ transaction.lastValidBlockHeight = lastValidBlockHeight;
173
+ transaction.feePayer = payer.publicKey;
174
+ transaction.sign(payer, ...tx.signers);
175
+ return {
176
+ signedTransaction: transaction,
177
+ type: 'addLiquidity',
178
+ poolAddress: params.poolAddress,
179
+ metadata: {
180
+ positionMint: positionMint.toBase58(),
181
+ liquidityAmount: quote.liquidityAmount.toString(),
182
+ },
183
+ };
184
+ }
185
+ const versionedTx = tx.transaction;
186
+ versionedTx.sign([payer, ...tx.signers]);
187
+ return {
188
+ signedTransaction: versionedTx,
189
+ type: 'addLiquidity',
190
+ poolAddress: params.poolAddress,
191
+ metadata: {
192
+ positionMint: positionMint.toBase58(),
193
+ liquidityAmount: quote.liquidityAmount.toString(),
194
+ },
195
+ };
196
+ }
197
+ else {
198
+ // 增加已有 position 的流动性
199
+ if (!params.positionAddress) {
200
+ throw new Error('positionAddress is required when createNewPosition is false');
201
+ }
202
+ const position = await client.getPosition(params.positionAddress);
203
+ const txBuilder = await position.increaseLiquidity(quote);
204
+ const tx = await txBuilder.build();
205
+ if ('recentBlockhash' in tx.transaction) {
206
+ const transaction = tx.transaction;
207
+ transaction.recentBlockhash = blockhash;
208
+ transaction.lastValidBlockHeight = lastValidBlockHeight;
209
+ transaction.feePayer = payer.publicKey;
210
+ transaction.sign(payer, ...tx.signers);
211
+ return {
212
+ signedTransaction: transaction,
213
+ type: 'addLiquidity',
214
+ poolAddress: params.poolAddress,
215
+ metadata: {
216
+ positionAddress: params.positionAddress,
217
+ liquidityAmount: quote.liquidityAmount.toString(),
218
+ },
219
+ };
220
+ }
221
+ const versionedTx = tx.transaction;
222
+ versionedTx.sign([payer, ...tx.signers]);
223
+ return {
224
+ signedTransaction: versionedTx,
225
+ type: 'addLiquidity',
226
+ poolAddress: params.poolAddress,
227
+ metadata: {
228
+ positionAddress: params.positionAddress,
229
+ liquidityAmount: quote.liquidityAmount.toString(),
230
+ },
231
+ };
232
+ }
233
+ }
234
+ /**
235
+ * 签名 Orca 移除流动性交易
236
+ */
237
+ export async function signOrcaRemoveLiquidity(params, payer, connection) {
238
+ const conn = connection || createConnection();
239
+ const client = await createOrcaClient(conn, payer);
240
+ const ctx = await createOrcaContext(conn, payer);
241
+ const position = await client.getPosition(params.positionAddress);
242
+ const positionData = position.getData();
243
+ const whirlpoolData = position.getWhirlpoolData();
244
+ const pool = await client.getPool(positionData.whirlpool);
245
+ const tokenInfoA = pool.getTokenAInfo();
246
+ const tokenInfoB = pool.getTokenBInfo();
247
+ const slippage = Percentage.fromFraction(params.slippageBps || 100, 10000);
248
+ // 获取 token extension context
249
+ const tokenExtensionCtx = await TokenExtensionUtil.buildTokenExtensionContextForPool(ctx.fetcher, tokenInfoA.mint, tokenInfoB.mint);
250
+ // 确定要移除的流动性数量
251
+ const liquidityToRemove = params.liquidityAmount || positionData.liquidity;
252
+ // 计算移除流动性报价
253
+ const { decreaseLiquidityQuoteByLiquidity } = await import('@orca-so/whirlpools-sdk');
254
+ const quote = decreaseLiquidityQuoteByLiquidity(liquidityToRemove, slippage, position, pool, tokenExtensionCtx);
255
+ const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash();
256
+ if (params.closePosition) {
257
+ // 关闭 position (移除全部流动性并关闭)
258
+ const txBuilders = await pool.closePosition(params.positionAddress, slippage);
259
+ const signedTxs = [];
260
+ for (const txBuilder of txBuilders) {
261
+ const tx = await txBuilder.build();
262
+ if ('recentBlockhash' in tx.transaction) {
263
+ const transaction = tx.transaction;
264
+ transaction.recentBlockhash = blockhash;
265
+ transaction.lastValidBlockHeight = lastValidBlockHeight;
266
+ transaction.feePayer = payer.publicKey;
267
+ transaction.sign(payer, ...tx.signers);
268
+ signedTxs.push(transaction);
269
+ }
270
+ else {
271
+ const versionedTx = tx.transaction;
272
+ versionedTx.sign([payer, ...tx.signers]);
273
+ signedTxs.push(versionedTx);
274
+ }
275
+ }
276
+ // 返回第一个交易 (通常只有一个)
277
+ return {
278
+ signedTransaction: signedTxs[0],
279
+ type: 'removeLiquidity',
280
+ poolAddress: positionData.whirlpool.toBase58(),
281
+ metadata: {
282
+ positionAddress: params.positionAddress,
283
+ liquidityAmount: liquidityToRemove.toString(),
284
+ },
285
+ };
286
+ }
287
+ else {
288
+ // 只移除部分流动性
289
+ const txBuilder = await position.decreaseLiquidity(quote);
290
+ const tx = await txBuilder.build();
291
+ if ('recentBlockhash' in tx.transaction) {
292
+ const transaction = tx.transaction;
293
+ transaction.recentBlockhash = blockhash;
294
+ transaction.lastValidBlockHeight = lastValidBlockHeight;
295
+ transaction.feePayer = payer.publicKey;
296
+ transaction.sign(payer, ...tx.signers);
297
+ return {
298
+ signedTransaction: transaction,
299
+ type: 'removeLiquidity',
300
+ poolAddress: positionData.whirlpool.toBase58(),
301
+ metadata: {
302
+ positionAddress: params.positionAddress,
303
+ liquidityAmount: liquidityToRemove.toString(),
304
+ },
305
+ };
306
+ }
307
+ const versionedTx = tx.transaction;
308
+ versionedTx.sign([payer, ...tx.signers]);
309
+ return {
310
+ signedTransaction: versionedTx,
311
+ type: 'removeLiquidity',
312
+ poolAddress: positionData.whirlpool.toBase58(),
313
+ metadata: {
314
+ positionAddress: params.positionAddress,
315
+ liquidityAmount: liquidityToRemove.toString(),
316
+ },
317
+ };
318
+ }
319
+ }
320
+ /**
321
+ * 签名创建 Orca Whirlpool 池交易
322
+ */
323
+ export async function signOrcaCreatePool(params, payer, connection) {
324
+ const conn = connection || createConnection();
325
+ const client = await createOrcaClient(conn, payer);
326
+ const initialPrice = DecimalUtil.fromNumber(params.initialPrice);
327
+ // 创建 Splash Pool (简化的全范围流动性池)
328
+ const { poolKey, tx: txBuilder } = await client.createSplashPool(params.whirlpoolsConfig || ORCA_WHIRLPOOL_CONFIG.MAINNET, params.tokenMintA, params.tokenMintB, initialPrice, payer.publicKey.toBase58());
329
+ const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash();
330
+ const tx = await txBuilder.build();
331
+ if ('recentBlockhash' in tx.transaction) {
332
+ const transaction = tx.transaction;
333
+ transaction.recentBlockhash = blockhash;
334
+ transaction.lastValidBlockHeight = lastValidBlockHeight;
335
+ transaction.feePayer = payer.publicKey;
336
+ transaction.sign(payer, ...tx.signers);
337
+ return {
338
+ signedTransaction: transaction,
339
+ type: 'createPool',
340
+ poolAddress: poolKey.toBase58(),
341
+ };
342
+ }
343
+ const versionedTx = tx.transaction;
344
+ versionedTx.sign([payer, ...tx.signers]);
345
+ return {
346
+ signedTransaction: versionedTx,
347
+ type: 'createPool',
348
+ poolAddress: poolKey.toBase58(),
349
+ };
350
+ }
351
+ /**
352
+ * 签名收集费用交易
353
+ */
354
+ export async function signOrcaCollectFees(positionAddress, payer, connection) {
355
+ const conn = connection || createConnection();
356
+ const client = await createOrcaClient(conn, payer);
357
+ const position = await client.getPosition(positionAddress);
358
+ const positionData = position.getData();
359
+ const txBuilder = await position.collectFees();
360
+ const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash();
361
+ const tx = await txBuilder.build();
362
+ if ('recentBlockhash' in tx.transaction) {
363
+ const transaction = tx.transaction;
364
+ transaction.recentBlockhash = blockhash;
365
+ transaction.lastValidBlockHeight = lastValidBlockHeight;
366
+ transaction.feePayer = payer.publicKey;
367
+ transaction.sign(payer, ...tx.signers);
368
+ return {
369
+ signedTransaction: transaction,
370
+ type: 'collectFees',
371
+ poolAddress: positionData.whirlpool.toBase58(),
372
+ metadata: {
373
+ positionAddress,
374
+ },
375
+ };
376
+ }
377
+ const versionedTx = tx.transaction;
378
+ versionedTx.sign([payer, ...tx.signers]);
379
+ return {
380
+ signedTransaction: versionedTx,
381
+ type: 'collectFees',
382
+ poolAddress: positionData.whirlpool.toBase58(),
383
+ metadata: {
384
+ positionAddress,
385
+ },
386
+ };
387
+ }
388
+ /**
389
+ * 获取 Position 信息
390
+ */
391
+ export async function getOrcaPositionInfo(positionAddress, connection) {
392
+ const client = await createOrcaClient(connection);
393
+ const position = await client.getPosition(positionAddress);
394
+ const data = position.getData();
395
+ return {
396
+ positionAddress,
397
+ positionMint: data.positionMint.toBase58(),
398
+ poolAddress: data.whirlpool.toBase58(),
399
+ tickLower: data.tickLowerIndex,
400
+ tickUpper: data.tickUpperIndex,
401
+ liquidity: data.liquidity.toString(),
402
+ feeOwedA: data.feeOwedA.toString(),
403
+ feeOwedB: data.feeOwedB.toString(),
404
+ rewardOwed: data.rewardInfos.map(info => info.amountOwed.toString()),
405
+ };
406
+ }
407
+ /**
408
+ * 计算全范围流动性的 tick 范围
409
+ */
410
+ export function getFullRangeTickIndices(tickSpacing) {
411
+ const [tickLower, tickUpper] = TickUtil.getFullRangeTickIndex(tickSpacing);
412
+ return { tickLower, tickUpper };
413
+ }
414
+ /**
415
+ * 根据价格范围计算 tick 范围
416
+ */
417
+ export function getTickIndicesFromPriceRange(priceLower, priceUpper, decimalsA, decimalsB, tickSpacing) {
418
+ const sqrtPriceLower = PriceMath.priceToSqrtPriceX64(DecimalUtil.fromNumber(priceLower), decimalsA, decimalsB);
419
+ const sqrtPriceUpper = PriceMath.priceToSqrtPriceX64(DecimalUtil.fromNumber(priceUpper), decimalsA, decimalsB);
420
+ let tickLower = PriceMath.sqrtPriceX64ToTickIndex(sqrtPriceLower);
421
+ let tickUpper = PriceMath.sqrtPriceX64ToTickIndex(sqrtPriceUpper);
422
+ // 对齐到 tickSpacing
423
+ tickLower = TickUtil.getInitializableTickIndex(tickLower, tickSpacing);
424
+ tickUpper = TickUtil.getInitializableTickIndex(tickUpper, tickSpacing);
425
+ return { tickLower, tickUpper };
426
+ }
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Orca Whirlpool 类型定义
3
+ */
4
+ import type { Keypair, Transaction, VersionedTransaction } from '@solana/web3.js';
5
+ import type BN from 'bn.js';
6
+ /**
7
+ * Orca Whirlpool 池信息
8
+ */
9
+ export interface OrcaPoolInfo {
10
+ /** 池地址 */
11
+ poolAddress: string;
12
+ /** Token A 地址 */
13
+ tokenMintA: string;
14
+ /** Token B 地址 */
15
+ tokenMintB: string;
16
+ /** Token A 符号 */
17
+ tokenSymbolA?: string;
18
+ /** Token B 符号 */
19
+ tokenSymbolB?: string;
20
+ /** Token A 小数位数 */
21
+ tokenDecimalsA: number;
22
+ /** Token B 小数位数 */
23
+ tokenDecimalsB: number;
24
+ /** Token A 金库地址 */
25
+ tokenVaultA: string;
26
+ /** Token B 金库地址 */
27
+ tokenVaultB: string;
28
+ /** 当前价格 (Token B / Token A) */
29
+ price: number;
30
+ /** 当前 sqrt 价格 */
31
+ sqrtPrice: string;
32
+ /** 当前 tick */
33
+ currentTick: number;
34
+ /** Tick 间距 */
35
+ tickSpacing: number;
36
+ /** 费率 (bps) */
37
+ feeRate: number;
38
+ /** 协议费率 (bps) */
39
+ protocolFeeRate: number;
40
+ /** 流动性 */
41
+ liquidity: string;
42
+ /** 费用增长 A */
43
+ feeGrowthGlobalA: string;
44
+ /** 费用增长 B */
45
+ feeGrowthGlobalB: string;
46
+ /** 奖励信息 */
47
+ rewardInfos: OrcaRewardInfo[];
48
+ }
49
+ /**
50
+ * Orca 奖励信息
51
+ */
52
+ export interface OrcaRewardInfo {
53
+ /** 奖励代币地址 */
54
+ mint: string;
55
+ /** 奖励金库地址 */
56
+ vault: string;
57
+ /** 每秒排放量 */
58
+ emissionsPerSecond: string;
59
+ /** 增长全局 */
60
+ growthGlobal: string;
61
+ }
62
+ /**
63
+ * Orca Swap 参数
64
+ */
65
+ export interface OrcaSwapParams {
66
+ /** 池地址 */
67
+ poolAddress: string;
68
+ /** 输入代币地址 */
69
+ inputMint: string;
70
+ /** 输出代币地址 */
71
+ outputMint: string;
72
+ /** 输入金额 (lamports) */
73
+ amountIn: BN;
74
+ /** 最小输出金额 (lamports) */
75
+ minAmountOut: BN;
76
+ /** 滑点 (bps, 如 100 = 1%) */
77
+ slippageBps?: number;
78
+ /** 是否精确输入 */
79
+ exactInput?: boolean;
80
+ }
81
+ /**
82
+ * Orca Swap 报价
83
+ */
84
+ export interface OrcaSwapQuote {
85
+ /** 输入金额 */
86
+ amountIn: BN;
87
+ /** 预估输出金额 */
88
+ estimatedAmountOut: BN;
89
+ /** 最小输出金额 (考虑滑点) */
90
+ minAmountOut: BN;
91
+ /** 费用金额 */
92
+ feeAmount: BN;
93
+ /** 价格影响 (百分比) */
94
+ priceImpact: number;
95
+ }
96
+ /**
97
+ * Orca 添加流动性参数
98
+ */
99
+ export interface OrcaAddLiquidityParams {
100
+ /** 池地址 */
101
+ poolAddress: string;
102
+ /** 下限 tick */
103
+ tickLower: number;
104
+ /** 上限 tick */
105
+ tickUpper: number;
106
+ /** Token A 金额 */
107
+ tokenAmountA: BN;
108
+ /** Token B 金额 */
109
+ tokenAmountB: BN;
110
+ /** 滑点 (bps) */
111
+ slippageBps?: number;
112
+ /** 是否创建新 position */
113
+ createNewPosition?: boolean;
114
+ /** 已有 position 地址 (如果不创建新的) */
115
+ positionAddress?: string;
116
+ }
117
+ /**
118
+ * Orca 移除流动性参数
119
+ */
120
+ export interface OrcaRemoveLiquidityParams {
121
+ /** Position 地址 */
122
+ positionAddress: string;
123
+ /** 流动性金额 (如果不指定,移除全部) */
124
+ liquidityAmount?: BN;
125
+ /** 最小 Token A 输出 */
126
+ minTokenAmountA?: BN;
127
+ /** 最小 Token B 输出 */
128
+ minTokenAmountB?: BN;
129
+ /** 滑点 (bps) */
130
+ slippageBps?: number;
131
+ /** 是否关闭 position */
132
+ closePosition?: boolean;
133
+ }
134
+ /**
135
+ * Orca Position 信息
136
+ */
137
+ export interface OrcaPositionInfo {
138
+ /** Position 地址 */
139
+ positionAddress: string;
140
+ /** Position Mint 地址 */
141
+ positionMint: string;
142
+ /** 池地址 */
143
+ poolAddress: string;
144
+ /** 下限 tick */
145
+ tickLower: number;
146
+ /** 上限 tick */
147
+ tickUpper: number;
148
+ /** 流动性 */
149
+ liquidity: string;
150
+ /** 费用 A 应收 */
151
+ feeOwedA: string;
152
+ /** 费用 B 应收 */
153
+ feeOwedB: string;
154
+ /** 奖励应收 */
155
+ rewardOwed: string[];
156
+ }
157
+ /**
158
+ * Orca 创建池参数
159
+ */
160
+ export interface OrcaCreatePoolParams {
161
+ /** Whirlpools Config 地址 */
162
+ whirlpoolsConfig: string;
163
+ /** Token A 地址 */
164
+ tokenMintA: string;
165
+ /** Token B 地址 */
166
+ tokenMintB: string;
167
+ /** 初始价格 (Token B / Token A) */
168
+ initialPrice: number;
169
+ /** Tick 间距 (决定费率) */
170
+ tickSpacing?: number;
171
+ /** 资金提供者 (默认为签名者) */
172
+ funder?: string;
173
+ }
174
+ /**
175
+ * Orca Bundle Swap 参数 (批量交易)
176
+ */
177
+ export interface OrcaBundleSwapParams {
178
+ /** 池地址 */
179
+ poolAddress: string;
180
+ /** 输入代币地址 */
181
+ inputMint: string;
182
+ /** 输出代币地址 */
183
+ outputMint: string;
184
+ /** 交易列表 */
185
+ trades: {
186
+ /** 钱包 */
187
+ wallet: Keypair;
188
+ /** 输入金额 */
189
+ amountIn: BN;
190
+ /** 最小输出金额 */
191
+ minAmountOut: BN;
192
+ }[];
193
+ /** Jito 小费 (lamports) */
194
+ jitoTipLamports?: number;
195
+ }
196
+ /**
197
+ * Orca 签名结果
198
+ */
199
+ export interface OrcaSignedResult {
200
+ /** 签名后的交易 */
201
+ signedTransaction: Transaction | VersionedTransaction;
202
+ /** 交易类型 */
203
+ type: 'swap' | 'addLiquidity' | 'removeLiquidity' | 'createPool' | 'collectFees';
204
+ /** 池地址 */
205
+ poolAddress: string;
206
+ /** 额外信息 */
207
+ metadata?: {
208
+ positionMint?: string;
209
+ positionAddress?: string;
210
+ estimatedAmountOut?: string;
211
+ liquidityAmount?: string;
212
+ };
213
+ }
214
+ /**
215
+ * Orca Bundle 签名结果
216
+ */
217
+ export interface OrcaBundleSignedResult {
218
+ /** 签名后的交易列表 */
219
+ signedTransactions: (Transaction | VersionedTransaction)[];
220
+ /** Bundle 类型 */
221
+ type: 'bundleSwap';
222
+ /** 池地址 */
223
+ poolAddress: string;
224
+ /** 交易数量 */
225
+ tradeCount: number;
226
+ /** Jito 小费 */
227
+ jitoTipLamports: number;
228
+ }
229
+ /**
230
+ * Whirlpool 费率等级
231
+ * tickSpacing 决定费率
232
+ */
233
+ export declare const WHIRLPOOL_TICK_SPACING: {
234
+ /** 0.01% 费率 */
235
+ readonly TICK_SPACING_1: 1;
236
+ /** 0.02% 费率 */
237
+ readonly TICK_SPACING_2: 2;
238
+ /** 0.04% 费率 */
239
+ readonly TICK_SPACING_4: 4;
240
+ /** 0.08% 费率 */
241
+ readonly TICK_SPACING_8: 8;
242
+ /** 0.16% 费率 */
243
+ readonly TICK_SPACING_16: 16;
244
+ /** 0.30% 费率 */
245
+ readonly TICK_SPACING_64: 64;
246
+ /** 1.00% 费率 */
247
+ readonly TICK_SPACING_128: 128;
248
+ /** 2.00% 费率 */
249
+ readonly TICK_SPACING_256: 256;
250
+ };
251
+ /**
252
+ * Orca Whirlpools Config 地址
253
+ */
254
+ export declare const ORCA_WHIRLPOOL_CONFIG: {
255
+ /** Mainnet Whirlpools Config */
256
+ readonly MAINNET: "FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR";
257
+ /** Devnet Whirlpools Config */
258
+ readonly DEVNET: "FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR";
259
+ };
260
+ /**
261
+ * Orca Whirlpool Program ID
262
+ */
263
+ export declare const ORCA_WHIRLPOOL_PROGRAM_ID = "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc";