four-flap-meme-sdk 1.5.6 → 1.5.9

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 (160) hide show
  1. package/README.zh-CN.pdf +0 -0
  2. package/dist/abis/common.js +2 -0
  3. package/dist/contracts/tm-bundle-merkle/config.d.ts +0 -1
  4. package/dist/contracts/tm-bundle-merkle/config.js +0 -1
  5. package/dist/contracts/tm-bundle-merkle/core.js +13 -9
  6. package/dist/contracts/tm-bundle-merkle/submit.js +58 -0
  7. package/dist/flap/portal-bundle-merkle/config.d.ts +0 -1
  8. package/dist/flap/portal-bundle-merkle/config.js +0 -1
  9. package/dist/flap/portal-bundle-merkle/create-to-dex.d.ts +8 -2
  10. package/dist/flap/portal-bundle-merkle/create-to-dex.js +170 -128
  11. package/dist/flap/portal-bundle-merkle/encryption.d.ts +16 -0
  12. package/dist/flap/portal-bundle-merkle/encryption.js +146 -0
  13. package/dist/flap/portal-bundle-merkle/private.js +8 -4
  14. package/dist/index.d.ts +0 -1
  15. package/dist/index.js +1 -1
  16. package/package.json +5 -41
  17. package/dist/sol/constants.d.ts +0 -150
  18. package/dist/sol/constants.js +0 -188
  19. package/dist/sol/dex/blockrazor/client.d.ts +0 -51
  20. package/dist/sol/dex/blockrazor/client.js +0 -96
  21. package/dist/sol/dex/blockrazor/constants.d.ts +0 -34
  22. package/dist/sol/dex/blockrazor/constants.js +0 -55
  23. package/dist/sol/dex/blockrazor/geyser.d.ts +0 -128
  24. package/dist/sol/dex/blockrazor/geyser.js +0 -530
  25. package/dist/sol/dex/blockrazor/index.d.ts +0 -18
  26. package/dist/sol/dex/blockrazor/index.js +0 -23
  27. package/dist/sol/dex/blockrazor/send.d.ts +0 -135
  28. package/dist/sol/dex/blockrazor/send.js +0 -254
  29. package/dist/sol/dex/blockrazor/types.d.ts +0 -191
  30. package/dist/sol/dex/blockrazor/types.js +0 -5
  31. package/dist/sol/dex/index.d.ts +0 -10
  32. package/dist/sol/dex/index.js +0 -16
  33. package/dist/sol/dex/jup/client.d.ts +0 -33
  34. package/dist/sol/dex/jup/client.js +0 -110
  35. package/dist/sol/dex/jup/index.d.ts +0 -16
  36. package/dist/sol/dex/jup/index.js +0 -148
  37. package/dist/sol/dex/jup/legacy.d.ts +0 -623
  38. package/dist/sol/dex/jup/legacy.js +0 -416
  39. package/dist/sol/dex/jup/lend.d.ts +0 -640
  40. package/dist/sol/dex/jup/lend.js +0 -603
  41. package/dist/sol/dex/jup/portfolio.d.ts +0 -362
  42. package/dist/sol/dex/jup/portfolio.js +0 -367
  43. package/dist/sol/dex/jup/price.d.ts +0 -173
  44. package/dist/sol/dex/jup/price.js +0 -220
  45. package/dist/sol/dex/jup/recurring.d.ts +0 -437
  46. package/dist/sol/dex/jup/recurring.js +0 -320
  47. package/dist/sol/dex/jup/send.d.ts +0 -282
  48. package/dist/sol/dex/jup/send.js +0 -295
  49. package/dist/sol/dex/jup/studio.d.ts +0 -457
  50. package/dist/sol/dex/jup/studio.js +0 -488
  51. package/dist/sol/dex/jup/tokens.d.ts +0 -767
  52. package/dist/sol/dex/jup/tokens.js +0 -697
  53. package/dist/sol/dex/jup/trigger.d.ts +0 -511
  54. package/dist/sol/dex/jup/trigger.js +0 -397
  55. package/dist/sol/dex/jup/types.d.ts +0 -433
  56. package/dist/sol/dex/jup/types.js +0 -5
  57. package/dist/sol/dex/jup/ultra.d.ts +0 -646
  58. package/dist/sol/dex/jup/ultra.js +0 -853
  59. package/dist/sol/dex/meteora/client.d.ts +0 -76
  60. package/dist/sol/dex/meteora/client.js +0 -219
  61. package/dist/sol/dex/meteora/damm-v1-bundle.d.ts +0 -61
  62. package/dist/sol/dex/meteora/damm-v1-bundle.js +0 -112
  63. package/dist/sol/dex/meteora/damm-v1.d.ts +0 -118
  64. package/dist/sol/dex/meteora/damm-v1.js +0 -315
  65. package/dist/sol/dex/meteora/damm-v2-bundle.d.ts +0 -82
  66. package/dist/sol/dex/meteora/damm-v2-bundle.js +0 -242
  67. package/dist/sol/dex/meteora/damm-v2.d.ts +0 -172
  68. package/dist/sol/dex/meteora/damm-v2.js +0 -632
  69. package/dist/sol/dex/meteora/dbc-bundle.d.ts +0 -123
  70. package/dist/sol/dex/meteora/dbc-bundle.js +0 -304
  71. package/dist/sol/dex/meteora/dbc.d.ts +0 -192
  72. package/dist/sol/dex/meteora/dbc.js +0 -619
  73. package/dist/sol/dex/meteora/dlmm-bundle.d.ts +0 -39
  74. package/dist/sol/dex/meteora/dlmm-bundle.js +0 -189
  75. package/dist/sol/dex/meteora/dlmm.d.ts +0 -157
  76. package/dist/sol/dex/meteora/dlmm.js +0 -671
  77. package/dist/sol/dex/meteora/index.d.ts +0 -25
  78. package/dist/sol/dex/meteora/index.js +0 -65
  79. package/dist/sol/dex/meteora/types.d.ts +0 -787
  80. package/dist/sol/dex/meteora/types.js +0 -110
  81. package/dist/sol/dex/orca/index.d.ts +0 -10
  82. package/dist/sol/dex/orca/index.js +0 -16
  83. package/dist/sol/dex/orca/orca-bundle.d.ts +0 -41
  84. package/dist/sol/dex/orca/orca-bundle.js +0 -173
  85. package/dist/sol/dex/orca/orca.d.ts +0 -65
  86. package/dist/sol/dex/orca/orca.js +0 -474
  87. package/dist/sol/dex/orca/types.d.ts +0 -263
  88. package/dist/sol/dex/orca/types.js +0 -38
  89. package/dist/sol/dex/orca/wavebreak-bundle.d.ts +0 -34
  90. package/dist/sol/dex/orca/wavebreak-bundle.js +0 -198
  91. package/dist/sol/dex/orca/wavebreak-types.d.ts +0 -227
  92. package/dist/sol/dex/orca/wavebreak-types.js +0 -23
  93. package/dist/sol/dex/orca/wavebreak.d.ts +0 -78
  94. package/dist/sol/dex/orca/wavebreak.js +0 -497
  95. package/dist/sol/dex/pump/index.d.ts +0 -9
  96. package/dist/sol/dex/pump/index.js +0 -14
  97. package/dist/sol/dex/pump/pump-bundle.d.ts +0 -92
  98. package/dist/sol/dex/pump/pump-bundle.js +0 -383
  99. package/dist/sol/dex/pump/pump-swap-bundle.d.ts +0 -103
  100. package/dist/sol/dex/pump/pump-swap-bundle.js +0 -380
  101. package/dist/sol/dex/pump/pump-swap.d.ts +0 -46
  102. package/dist/sol/dex/pump/pump-swap.js +0 -199
  103. package/dist/sol/dex/pump/pump.d.ts +0 -35
  104. package/dist/sol/dex/pump/pump.js +0 -352
  105. package/dist/sol/dex/pump/types.d.ts +0 -215
  106. package/dist/sol/dex/pump/types.js +0 -5
  107. package/dist/sol/dex/raydium/index.d.ts +0 -8
  108. package/dist/sol/dex/raydium/index.js +0 -12
  109. package/dist/sol/dex/raydium/launchlab.d.ts +0 -68
  110. package/dist/sol/dex/raydium/launchlab.js +0 -210
  111. package/dist/sol/dex/raydium/raydium-bundle.d.ts +0 -64
  112. package/dist/sol/dex/raydium/raydium-bundle.js +0 -324
  113. package/dist/sol/dex/raydium/raydium.d.ts +0 -40
  114. package/dist/sol/dex/raydium/raydium.js +0 -366
  115. package/dist/sol/dex/raydium/types.d.ts +0 -240
  116. package/dist/sol/dex/raydium/types.js +0 -5
  117. package/dist/sol/index.d.ts +0 -11
  118. package/dist/sol/index.js +0 -18
  119. package/dist/sol/jito/bundle.d.ts +0 -90
  120. package/dist/sol/jito/bundle.js +0 -263
  121. package/dist/sol/jito/index.d.ts +0 -7
  122. package/dist/sol/jito/index.js +0 -7
  123. package/dist/sol/jito/tip.d.ts +0 -51
  124. package/dist/sol/jito/tip.js +0 -83
  125. package/dist/sol/jito/types.d.ts +0 -100
  126. package/dist/sol/jito/types.js +0 -5
  127. package/dist/sol/nozomi/client.d.ts +0 -63
  128. package/dist/sol/nozomi/client.js +0 -222
  129. package/dist/sol/nozomi/index.d.ts +0 -8
  130. package/dist/sol/nozomi/index.js +0 -8
  131. package/dist/sol/nozomi/tip.d.ts +0 -50
  132. package/dist/sol/nozomi/tip.js +0 -80
  133. package/dist/sol/nozomi/types.d.ts +0 -96
  134. package/dist/sol/nozomi/types.js +0 -5
  135. package/dist/sol/token/create-complete.d.ts +0 -115
  136. package/dist/sol/token/create-complete.js +0 -235
  137. package/dist/sol/token/create-token.d.ts +0 -57
  138. package/dist/sol/token/create-token.js +0 -230
  139. package/dist/sol/token/index.d.ts +0 -9
  140. package/dist/sol/token/index.js +0 -14
  141. package/dist/sol/token/metadata-upload.d.ts +0 -86
  142. package/dist/sol/token/metadata-upload.js +0 -173
  143. package/dist/sol/token/metadata.d.ts +0 -92
  144. package/dist/sol/token/metadata.js +0 -274
  145. package/dist/sol/token/types.d.ts +0 -153
  146. package/dist/sol/token/types.js +0 -5
  147. package/dist/sol/types.d.ts +0 -176
  148. package/dist/sol/types.js +0 -7
  149. package/dist/sol/utils/balance.d.ts +0 -160
  150. package/dist/sol/utils/balance.js +0 -638
  151. package/dist/sol/utils/connection.d.ts +0 -78
  152. package/dist/sol/utils/connection.js +0 -168
  153. package/dist/sol/utils/index.d.ts +0 -9
  154. package/dist/sol/utils/index.js +0 -9
  155. package/dist/sol/utils/lp-inspect.d.ts +0 -129
  156. package/dist/sol/utils/lp-inspect.js +0 -900
  157. package/dist/sol/utils/transfer.d.ts +0 -196
  158. package/dist/sol/utils/transfer.js +0 -307
  159. package/dist/sol/utils/wallet.d.ts +0 -107
  160. package/dist/sol/utils/wallet.js +0 -210
@@ -1,474 +0,0 @@
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, Transaction, } from '@solana/web3.js';
9
- import { WhirlpoolContext, buildWhirlpoolClient, ORCA_WHIRLPOOL_PROGRAM_ID, PDAUtil, TickUtil, PriceMath, PoolUtil, TokenExtensionUtil, } from '@orca-so/whirlpools-sdk';
10
- import { Percentage, AddressUtil, DecimalUtil } from '@orca-so/common-sdk';
11
- import { ORCA_WHIRLPOOL_CONFIG } from './types.js';
12
- /**
13
- * 从 Keypair 创建 Wallet 适配器(兼容浏览器环境)
14
- */
15
- function createWalletFromKeypair(keypair) {
16
- return {
17
- publicKey: keypair.publicKey,
18
- signTransaction: async (tx) => {
19
- if (tx instanceof Transaction) {
20
- tx.partialSign(keypair);
21
- }
22
- else {
23
- // VersionedTransaction
24
- tx.sign([keypair]);
25
- }
26
- return tx;
27
- },
28
- signAllTransactions: async (txs) => {
29
- for (const tx of txs) {
30
- if (tx instanceof Transaction) {
31
- tx.partialSign(keypair);
32
- }
33
- else {
34
- tx.sign([keypair]);
35
- }
36
- }
37
- return txs;
38
- },
39
- };
40
- }
41
- /**
42
- * 创建 Orca Whirlpool Context
43
- */
44
- export async function createOrcaContext(connection, wallet) {
45
- if (!connection) {
46
- throw new Error('Connection is required. Please pass a connection created with user-configured RPC.');
47
- }
48
- const conn = connection;
49
- // 创建 Wallet 适配器(不依赖 @coral-xyz/anchor 的 Wallet 类)
50
- const anchorWallet = wallet
51
- ? createWalletFromKeypair(wallet)
52
- : {
53
- publicKey: PublicKey.default,
54
- signTransaction: async (tx) => tx,
55
- signAllTransactions: async (txs) => txs,
56
- };
57
- // WhirlpoolContext.from 只需要 connection 和 wallet
58
- const ctx = WhirlpoolContext.from(conn, anchorWallet);
59
- return ctx;
60
- }
61
- /**
62
- * 创建 Orca Whirlpool Client
63
- */
64
- export async function createOrcaClient(connection, wallet) {
65
- const ctx = await createOrcaContext(connection, wallet);
66
- return buildWhirlpoolClient(ctx);
67
- }
68
- /**
69
- * 获取 Orca Whirlpool 池信息
70
- */
71
- export async function getOrcaPoolInfo(poolAddress, connection) {
72
- const client = await createOrcaClient(connection);
73
- const pool = await client.getPool(poolAddress);
74
- const data = pool.getData();
75
- const tokenInfoA = pool.getTokenAInfo();
76
- const tokenInfoB = pool.getTokenBInfo();
77
- const vaultInfoA = pool.getTokenVaultAInfo();
78
- const vaultInfoB = pool.getTokenVaultBInfo();
79
- const rewardInfos = pool.getRewardInfos();
80
- // 计算当前价格
81
- const price = PriceMath.sqrtPriceX64ToPrice(data.sqrtPrice, tokenInfoA.decimals, tokenInfoB.decimals);
82
- return {
83
- poolAddress,
84
- tokenMintA: tokenInfoA.mint.toBase58(),
85
- tokenMintB: tokenInfoB.mint.toBase58(),
86
- tokenDecimalsA: tokenInfoA.decimals,
87
- tokenDecimalsB: tokenInfoB.decimals,
88
- tokenVaultA: vaultInfoA.address.toBase58(),
89
- tokenVaultB: vaultInfoB.address.toBase58(),
90
- price: price.toNumber(),
91
- sqrtPrice: data.sqrtPrice.toString(),
92
- currentTick: data.tickCurrentIndex,
93
- tickSpacing: data.tickSpacing,
94
- feeRate: data.feeRate,
95
- protocolFeeRate: data.protocolFeeRate,
96
- liquidity: data.liquidity.toString(),
97
- feeGrowthGlobalA: data.feeGrowthGlobalA.toString(),
98
- feeGrowthGlobalB: data.feeGrowthGlobalB.toString(),
99
- rewardInfos: rewardInfos.map(info => ({
100
- mint: info.mint.toBase58(),
101
- vault: info.vault.toBase58(),
102
- emissionsPerSecond: info.emissionsPerSecondX64.toString(),
103
- growthGlobal: info.growthGlobalX64.toString(),
104
- })),
105
- };
106
- }
107
- /**
108
- * 查找 Orca Whirlpool 池
109
- */
110
- export async function findOrcaPool(tokenMintA, tokenMintB, tickSpacing = 64, connection) {
111
- if (!connection) {
112
- throw new Error('Connection is required. Please pass a connection created with user-configured RPC.');
113
- }
114
- const conn = connection;
115
- // 确保代币顺序正确 (按地址排序)
116
- const [mintAAddr, mintBAddr] = PoolUtil.orderMints(new PublicKey(tokenMintA), new PublicKey(tokenMintB));
117
- // 转换为 PublicKey
118
- const mintA = AddressUtil.toPubKey(mintAAddr);
119
- const mintB = AddressUtil.toPubKey(mintBAddr);
120
- // 计算池 PDA
121
- const poolPda = PDAUtil.getWhirlpool(ORCA_WHIRLPOOL_PROGRAM_ID, new PublicKey(ORCA_WHIRLPOOL_CONFIG.MAINNET), mintA, mintB, tickSpacing);
122
- // 检查池是否存在
123
- const accountInfo = await conn.getAccountInfo(poolPda.publicKey);
124
- return accountInfo ? poolPda.publicKey.toBase58() : null;
125
- }
126
- /**
127
- * 签名 Orca Swap 交易
128
- * 使用 Whirlpool 的高级 swap 接口
129
- */
130
- export async function signOrcaSwap(params, payer, connection) {
131
- if (!connection) {
132
- throw new Error('Connection is required. Please pass a connection created with user-configured RPC.');
133
- }
134
- const conn = connection;
135
- const client = await createOrcaClient(conn, payer);
136
- const pool = await client.getPool(params.poolAddress);
137
- const ctx = await createOrcaContext(conn, payer);
138
- const inputMint = new PublicKey(params.inputMint);
139
- const slippage = Percentage.fromFraction(params.slippageBps || 100, 10000);
140
- // 获取 token extension context
141
- const tokenInfoA = pool.getTokenAInfo();
142
- const tokenInfoB = pool.getTokenBInfo();
143
- const tokenExtensionCtx = await TokenExtensionUtil.buildTokenExtensionContextForPool(ctx.fetcher, tokenInfoA.mint, tokenInfoB.mint);
144
- // 使用 SDK 的 swapQuoteByInputToken
145
- const { swapQuoteByInputToken } = await import('@orca-so/whirlpools-sdk');
146
- const quote = await swapQuoteByInputToken(pool, inputMint, params.amountIn, slippage, ORCA_WHIRLPOOL_PROGRAM_ID, ctx.fetcher);
147
- // 构建 swap 交易
148
- const txBuilder = await pool.swap(quote, payer.publicKey);
149
- // 获取最新区块哈希
150
- const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash();
151
- // 构建交易
152
- const tx = await txBuilder.build();
153
- // 如果是 Transaction 类型
154
- if ('recentBlockhash' in tx.transaction) {
155
- const transaction = tx.transaction;
156
- transaction.recentBlockhash = blockhash;
157
- transaction.lastValidBlockHeight = lastValidBlockHeight;
158
- transaction.feePayer = payer.publicKey;
159
- // 签名
160
- transaction.sign(payer, ...tx.signers);
161
- return {
162
- signedTransaction: transaction,
163
- type: 'swap',
164
- poolAddress: params.poolAddress,
165
- metadata: {
166
- estimatedAmountOut: quote.estimatedAmountOut.toString(),
167
- },
168
- };
169
- }
170
- // VersionedTransaction 类型
171
- const versionedTx = tx.transaction;
172
- versionedTx.sign([payer, ...tx.signers]);
173
- return {
174
- signedTransaction: versionedTx,
175
- type: 'swap',
176
- poolAddress: params.poolAddress,
177
- metadata: {
178
- estimatedAmountOut: quote.estimatedAmountOut.toString(),
179
- },
180
- };
181
- }
182
- /**
183
- * 签名 Orca 添加流动性交易
184
- */
185
- export async function signOrcaAddLiquidity(params, payer, connection) {
186
- if (!connection) {
187
- throw new Error('Connection is required. Please pass a connection created with user-configured RPC.');
188
- }
189
- const conn = connection;
190
- const client = await createOrcaClient(conn, payer);
191
- const pool = await client.getPool(params.poolAddress);
192
- const ctx = await createOrcaContext(conn, payer);
193
- const tokenInfoA = pool.getTokenAInfo();
194
- const tokenInfoB = pool.getTokenBInfo();
195
- const slippage = Percentage.fromFraction(params.slippageBps || 100, 10000);
196
- // 获取 token extension context
197
- const tokenExtensionCtx = await TokenExtensionUtil.buildTokenExtensionContextForPool(ctx.fetcher, tokenInfoA.mint, tokenInfoB.mint);
198
- // 计算流动性报价
199
- const { increaseLiquidityQuoteByInputToken } = await import('@orca-so/whirlpools-sdk');
200
- // 使用 DecimalUtil 创建 Decimal 值 (从 BN 转换,不带小数位移位)
201
- const inputAmount = DecimalUtil.fromBN(params.tokenAmountA, 0);
202
- const quote = increaseLiquidityQuoteByInputToken(tokenInfoA.mint, inputAmount, params.tickLower, params.tickUpper, slippage, pool, tokenExtensionCtx);
203
- const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash();
204
- if (params.createNewPosition !== false) {
205
- // 创建新的 position
206
- const { positionMint, tx: txBuilder } = await pool.openPosition(params.tickLower, params.tickUpper, quote);
207
- const tx = await txBuilder.build();
208
- if ('recentBlockhash' in tx.transaction) {
209
- const transaction = tx.transaction;
210
- transaction.recentBlockhash = blockhash;
211
- transaction.lastValidBlockHeight = lastValidBlockHeight;
212
- transaction.feePayer = payer.publicKey;
213
- transaction.sign(payer, ...tx.signers);
214
- return {
215
- signedTransaction: transaction,
216
- type: 'addLiquidity',
217
- poolAddress: params.poolAddress,
218
- metadata: {
219
- positionMint: positionMint.toBase58(),
220
- liquidityAmount: quote.liquidityAmount.toString(),
221
- },
222
- };
223
- }
224
- const versionedTx = tx.transaction;
225
- versionedTx.sign([payer, ...tx.signers]);
226
- return {
227
- signedTransaction: versionedTx,
228
- type: 'addLiquidity',
229
- poolAddress: params.poolAddress,
230
- metadata: {
231
- positionMint: positionMint.toBase58(),
232
- liquidityAmount: quote.liquidityAmount.toString(),
233
- },
234
- };
235
- }
236
- else {
237
- // 增加已有 position 的流动性
238
- if (!params.positionAddress) {
239
- throw new Error('positionAddress is required when createNewPosition is false');
240
- }
241
- const position = await client.getPosition(params.positionAddress);
242
- const txBuilder = await position.increaseLiquidity(quote);
243
- const tx = await txBuilder.build();
244
- if ('recentBlockhash' in tx.transaction) {
245
- const transaction = tx.transaction;
246
- transaction.recentBlockhash = blockhash;
247
- transaction.lastValidBlockHeight = lastValidBlockHeight;
248
- transaction.feePayer = payer.publicKey;
249
- transaction.sign(payer, ...tx.signers);
250
- return {
251
- signedTransaction: transaction,
252
- type: 'addLiquidity',
253
- poolAddress: params.poolAddress,
254
- metadata: {
255
- positionAddress: params.positionAddress,
256
- liquidityAmount: quote.liquidityAmount.toString(),
257
- },
258
- };
259
- }
260
- const versionedTx = tx.transaction;
261
- versionedTx.sign([payer, ...tx.signers]);
262
- return {
263
- signedTransaction: versionedTx,
264
- type: 'addLiquidity',
265
- poolAddress: params.poolAddress,
266
- metadata: {
267
- positionAddress: params.positionAddress,
268
- liquidityAmount: quote.liquidityAmount.toString(),
269
- },
270
- };
271
- }
272
- }
273
- /**
274
- * 签名 Orca 移除流动性交易
275
- */
276
- export async function signOrcaRemoveLiquidity(params, payer, connection) {
277
- if (!connection) {
278
- throw new Error('Connection is required. Please pass a connection created with user-configured RPC.');
279
- }
280
- const conn = connection;
281
- const client = await createOrcaClient(conn, payer);
282
- const ctx = await createOrcaContext(conn, payer);
283
- const position = await client.getPosition(params.positionAddress);
284
- const positionData = position.getData();
285
- const whirlpoolData = position.getWhirlpoolData();
286
- const pool = await client.getPool(positionData.whirlpool);
287
- const tokenInfoA = pool.getTokenAInfo();
288
- const tokenInfoB = pool.getTokenBInfo();
289
- const slippage = Percentage.fromFraction(params.slippageBps || 100, 10000);
290
- // 获取 token extension context
291
- const tokenExtensionCtx = await TokenExtensionUtil.buildTokenExtensionContextForPool(ctx.fetcher, tokenInfoA.mint, tokenInfoB.mint);
292
- // 确定要移除的流动性数量
293
- const liquidityToRemove = params.liquidityAmount || positionData.liquidity;
294
- // 计算移除流动性报价
295
- const { decreaseLiquidityQuoteByLiquidity } = await import('@orca-so/whirlpools-sdk');
296
- const quote = decreaseLiquidityQuoteByLiquidity(liquidityToRemove, slippage, position, pool, tokenExtensionCtx);
297
- const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash();
298
- if (params.closePosition) {
299
- // 关闭 position (移除全部流动性并关闭)
300
- const txBuilders = await pool.closePosition(params.positionAddress, slippage);
301
- const signedTxs = [];
302
- for (const txBuilder of txBuilders) {
303
- const tx = await txBuilder.build();
304
- if ('recentBlockhash' in tx.transaction) {
305
- const transaction = tx.transaction;
306
- transaction.recentBlockhash = blockhash;
307
- transaction.lastValidBlockHeight = lastValidBlockHeight;
308
- transaction.feePayer = payer.publicKey;
309
- transaction.sign(payer, ...tx.signers);
310
- signedTxs.push(transaction);
311
- }
312
- else {
313
- const versionedTx = tx.transaction;
314
- versionedTx.sign([payer, ...tx.signers]);
315
- signedTxs.push(versionedTx);
316
- }
317
- }
318
- // 返回第一个交易 (通常只有一个)
319
- return {
320
- signedTransaction: signedTxs[0],
321
- type: 'removeLiquidity',
322
- poolAddress: positionData.whirlpool.toBase58(),
323
- metadata: {
324
- positionAddress: params.positionAddress,
325
- liquidityAmount: liquidityToRemove.toString(),
326
- },
327
- };
328
- }
329
- else {
330
- // 只移除部分流动性
331
- const txBuilder = await position.decreaseLiquidity(quote);
332
- const tx = await txBuilder.build();
333
- if ('recentBlockhash' in tx.transaction) {
334
- const transaction = tx.transaction;
335
- transaction.recentBlockhash = blockhash;
336
- transaction.lastValidBlockHeight = lastValidBlockHeight;
337
- transaction.feePayer = payer.publicKey;
338
- transaction.sign(payer, ...tx.signers);
339
- return {
340
- signedTransaction: transaction,
341
- type: 'removeLiquidity',
342
- poolAddress: positionData.whirlpool.toBase58(),
343
- metadata: {
344
- positionAddress: params.positionAddress,
345
- liquidityAmount: liquidityToRemove.toString(),
346
- },
347
- };
348
- }
349
- const versionedTx = tx.transaction;
350
- versionedTx.sign([payer, ...tx.signers]);
351
- return {
352
- signedTransaction: versionedTx,
353
- type: 'removeLiquidity',
354
- poolAddress: positionData.whirlpool.toBase58(),
355
- metadata: {
356
- positionAddress: params.positionAddress,
357
- liquidityAmount: liquidityToRemove.toString(),
358
- },
359
- };
360
- }
361
- }
362
- /**
363
- * 签名创建 Orca Whirlpool 池交易
364
- */
365
- export async function signOrcaCreatePool(params, payer, connection) {
366
- if (!connection) {
367
- throw new Error('Connection is required. Please pass a connection created with user-configured RPC.');
368
- }
369
- const conn = connection;
370
- const client = await createOrcaClient(conn, payer);
371
- const initialPrice = DecimalUtil.fromNumber(params.initialPrice);
372
- // 创建 Splash Pool (简化的全范围流动性池)
373
- const { poolKey, tx: txBuilder } = await client.createSplashPool(params.whirlpoolsConfig || ORCA_WHIRLPOOL_CONFIG.MAINNET, params.tokenMintA, params.tokenMintB, initialPrice, payer.publicKey.toBase58());
374
- const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash();
375
- const tx = await txBuilder.build();
376
- if ('recentBlockhash' in tx.transaction) {
377
- const transaction = tx.transaction;
378
- transaction.recentBlockhash = blockhash;
379
- transaction.lastValidBlockHeight = lastValidBlockHeight;
380
- transaction.feePayer = payer.publicKey;
381
- transaction.sign(payer, ...tx.signers);
382
- return {
383
- signedTransaction: transaction,
384
- type: 'createPool',
385
- poolAddress: poolKey.toBase58(),
386
- };
387
- }
388
- const versionedTx = tx.transaction;
389
- versionedTx.sign([payer, ...tx.signers]);
390
- return {
391
- signedTransaction: versionedTx,
392
- type: 'createPool',
393
- poolAddress: poolKey.toBase58(),
394
- };
395
- }
396
- /**
397
- * 签名收集费用交易
398
- */
399
- export async function signOrcaCollectFees(positionAddress, payer, connection) {
400
- if (!connection) {
401
- throw new Error('Connection is required. Please pass a connection created with user-configured RPC.');
402
- }
403
- const conn = connection;
404
- const client = await createOrcaClient(conn, payer);
405
- const position = await client.getPosition(positionAddress);
406
- const positionData = position.getData();
407
- const txBuilder = await position.collectFees();
408
- const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash();
409
- const tx = await txBuilder.build();
410
- if ('recentBlockhash' in tx.transaction) {
411
- const transaction = tx.transaction;
412
- transaction.recentBlockhash = blockhash;
413
- transaction.lastValidBlockHeight = lastValidBlockHeight;
414
- transaction.feePayer = payer.publicKey;
415
- transaction.sign(payer, ...tx.signers);
416
- return {
417
- signedTransaction: transaction,
418
- type: 'collectFees',
419
- poolAddress: positionData.whirlpool.toBase58(),
420
- metadata: {
421
- positionAddress,
422
- },
423
- };
424
- }
425
- const versionedTx = tx.transaction;
426
- versionedTx.sign([payer, ...tx.signers]);
427
- return {
428
- signedTransaction: versionedTx,
429
- type: 'collectFees',
430
- poolAddress: positionData.whirlpool.toBase58(),
431
- metadata: {
432
- positionAddress,
433
- },
434
- };
435
- }
436
- /**
437
- * 获取 Position 信息
438
- */
439
- export async function getOrcaPositionInfo(positionAddress, connection) {
440
- const client = await createOrcaClient(connection);
441
- const position = await client.getPosition(positionAddress);
442
- const data = position.getData();
443
- return {
444
- positionAddress,
445
- positionMint: data.positionMint.toBase58(),
446
- poolAddress: data.whirlpool.toBase58(),
447
- tickLower: data.tickLowerIndex,
448
- tickUpper: data.tickUpperIndex,
449
- liquidity: data.liquidity.toString(),
450
- feeOwedA: data.feeOwedA.toString(),
451
- feeOwedB: data.feeOwedB.toString(),
452
- rewardOwed: data.rewardInfos.map(info => info.amountOwed.toString()),
453
- };
454
- }
455
- /**
456
- * 计算全范围流动性的 tick 范围
457
- */
458
- export function getFullRangeTickIndices(tickSpacing) {
459
- const [tickLower, tickUpper] = TickUtil.getFullRangeTickIndex(tickSpacing);
460
- return { tickLower, tickUpper };
461
- }
462
- /**
463
- * 根据价格范围计算 tick 范围
464
- */
465
- export function getTickIndicesFromPriceRange(priceLower, priceUpper, decimalsA, decimalsB, tickSpacing) {
466
- const sqrtPriceLower = PriceMath.priceToSqrtPriceX64(DecimalUtil.fromNumber(priceLower), decimalsA, decimalsB);
467
- const sqrtPriceUpper = PriceMath.priceToSqrtPriceX64(DecimalUtil.fromNumber(priceUpper), decimalsA, decimalsB);
468
- let tickLower = PriceMath.sqrtPriceX64ToTickIndex(sqrtPriceLower);
469
- let tickUpper = PriceMath.sqrtPriceX64ToTickIndex(sqrtPriceUpper);
470
- // 对齐到 tickSpacing
471
- tickLower = TickUtil.getInitializableTickIndex(tickLower, tickSpacing);
472
- tickUpper = TickUtil.getInitializableTickIndex(tickUpper, tickSpacing);
473
- return { tickLower, tickUpper };
474
- }