four-flap-meme-sdk 1.4.90 → 1.4.92

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 (164) hide show
  1. package/dist/flap/portal-bundle-merkle/create-to-dex.d.ts +1 -1
  2. package/dist/flap/portal-bundle-merkle/create-to-dex.js +51 -13
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.js +24 -0
  5. package/dist/sol/constants.d.ts +126 -0
  6. package/dist/sol/constants.js +145 -0
  7. package/dist/sol/dex/blockrazor/client.d.ts +51 -0
  8. package/dist/sol/dex/blockrazor/client.js +96 -0
  9. package/dist/sol/dex/blockrazor/constants.d.ts +34 -0
  10. package/dist/sol/dex/blockrazor/constants.js +55 -0
  11. package/dist/sol/dex/blockrazor/geyser.d.ts +128 -0
  12. package/dist/sol/dex/blockrazor/geyser.js +530 -0
  13. package/dist/sol/dex/blockrazor/index.d.ts +18 -0
  14. package/dist/sol/dex/blockrazor/index.js +23 -0
  15. package/dist/sol/dex/blockrazor/send.d.ts +135 -0
  16. package/dist/sol/dex/blockrazor/send.js +254 -0
  17. package/dist/sol/dex/blockrazor/types.d.ts +191 -0
  18. package/dist/sol/dex/blockrazor/types.js +5 -0
  19. package/dist/sol/dex/index.d.ts +10 -0
  20. package/dist/sol/dex/index.js +16 -0
  21. package/dist/sol/dex/jup/client.d.ts +33 -0
  22. package/dist/sol/dex/jup/client.js +110 -0
  23. package/dist/sol/dex/jup/index.d.ts +16 -0
  24. package/dist/sol/dex/jup/index.js +148 -0
  25. package/dist/sol/dex/jup/legacy.d.ts +623 -0
  26. package/dist/sol/dex/jup/legacy.js +416 -0
  27. package/dist/sol/dex/jup/lend.d.ts +640 -0
  28. package/dist/sol/dex/jup/lend.js +603 -0
  29. package/dist/sol/dex/jup/portfolio.d.ts +362 -0
  30. package/dist/sol/dex/jup/portfolio.js +367 -0
  31. package/dist/sol/dex/jup/price.d.ts +173 -0
  32. package/dist/sol/dex/jup/price.js +220 -0
  33. package/dist/sol/dex/jup/recurring.d.ts +437 -0
  34. package/dist/sol/dex/jup/recurring.js +320 -0
  35. package/dist/sol/dex/jup/send.d.ts +282 -0
  36. package/dist/sol/dex/jup/send.js +295 -0
  37. package/dist/sol/dex/jup/studio.d.ts +457 -0
  38. package/dist/sol/dex/jup/studio.js +488 -0
  39. package/dist/sol/dex/jup/tokens.d.ts +767 -0
  40. package/dist/sol/dex/jup/tokens.js +697 -0
  41. package/dist/sol/dex/jup/trigger.d.ts +511 -0
  42. package/dist/sol/dex/jup/trigger.js +397 -0
  43. package/dist/sol/dex/jup/types.d.ts +433 -0
  44. package/dist/sol/dex/jup/types.js +5 -0
  45. package/dist/sol/dex/jup/ultra.d.ts +646 -0
  46. package/dist/sol/dex/jup/ultra.js +853 -0
  47. package/dist/sol/dex/meteora/client.d.ts +76 -0
  48. package/dist/sol/dex/meteora/client.js +219 -0
  49. package/dist/sol/dex/meteora/damm-v1-bundle.d.ts +61 -0
  50. package/dist/sol/dex/meteora/damm-v1-bundle.js +112 -0
  51. package/dist/sol/dex/meteora/damm-v1.d.ts +118 -0
  52. package/dist/sol/dex/meteora/damm-v1.js +315 -0
  53. package/dist/sol/dex/meteora/damm-v2-bundle.d.ts +82 -0
  54. package/dist/sol/dex/meteora/damm-v2-bundle.js +242 -0
  55. package/dist/sol/dex/meteora/damm-v2.d.ts +172 -0
  56. package/dist/sol/dex/meteora/damm-v2.js +632 -0
  57. package/dist/sol/dex/meteora/dbc-bundle.d.ts +123 -0
  58. package/dist/sol/dex/meteora/dbc-bundle.js +304 -0
  59. package/dist/sol/dex/meteora/dbc.d.ts +192 -0
  60. package/dist/sol/dex/meteora/dbc.js +619 -0
  61. package/dist/sol/dex/meteora/dlmm-bundle.d.ts +39 -0
  62. package/dist/sol/dex/meteora/dlmm-bundle.js +189 -0
  63. package/dist/sol/dex/meteora/dlmm.d.ts +157 -0
  64. package/dist/sol/dex/meteora/dlmm.js +671 -0
  65. package/dist/sol/dex/meteora/index.d.ts +25 -0
  66. package/dist/sol/dex/meteora/index.js +65 -0
  67. package/dist/sol/dex/meteora/types.d.ts +787 -0
  68. package/dist/sol/dex/meteora/types.js +110 -0
  69. package/dist/sol/dex/orca/index.d.ts +10 -0
  70. package/dist/sol/dex/orca/index.js +16 -0
  71. package/dist/sol/dex/orca/orca-bundle.d.ts +41 -0
  72. package/dist/sol/dex/orca/orca-bundle.js +173 -0
  73. package/dist/sol/dex/orca/orca.d.ts +65 -0
  74. package/dist/sol/dex/orca/orca.js +474 -0
  75. package/dist/sol/dex/orca/types.d.ts +263 -0
  76. package/dist/sol/dex/orca/types.js +38 -0
  77. package/dist/sol/dex/orca/wavebreak-bundle.d.ts +34 -0
  78. package/dist/sol/dex/orca/wavebreak-bundle.js +198 -0
  79. package/dist/sol/dex/orca/wavebreak-types.d.ts +227 -0
  80. package/dist/sol/dex/orca/wavebreak-types.js +23 -0
  81. package/dist/sol/dex/orca/wavebreak.d.ts +78 -0
  82. package/dist/sol/dex/orca/wavebreak.js +497 -0
  83. package/dist/sol/dex/pump/index.d.ts +9 -0
  84. package/dist/sol/dex/pump/index.js +14 -0
  85. package/dist/sol/dex/pump/pump-bundle.d.ts +92 -0
  86. package/dist/sol/dex/pump/pump-bundle.js +383 -0
  87. package/dist/sol/dex/pump/pump-swap-bundle.d.ts +103 -0
  88. package/dist/sol/dex/pump/pump-swap-bundle.js +380 -0
  89. package/dist/sol/dex/pump/pump-swap.d.ts +46 -0
  90. package/dist/sol/dex/pump/pump-swap.js +199 -0
  91. package/dist/sol/dex/pump/pump.d.ts +35 -0
  92. package/dist/sol/dex/pump/pump.js +352 -0
  93. package/dist/sol/dex/pump/types.d.ts +215 -0
  94. package/dist/sol/dex/pump/types.js +5 -0
  95. package/dist/sol/dex/raydium/index.d.ts +8 -0
  96. package/dist/sol/dex/raydium/index.js +12 -0
  97. package/dist/sol/dex/raydium/launchlab.d.ts +68 -0
  98. package/dist/sol/dex/raydium/launchlab.js +210 -0
  99. package/dist/sol/dex/raydium/raydium-bundle.d.ts +64 -0
  100. package/dist/sol/dex/raydium/raydium-bundle.js +324 -0
  101. package/dist/sol/dex/raydium/raydium.d.ts +40 -0
  102. package/dist/sol/dex/raydium/raydium.js +366 -0
  103. package/dist/sol/dex/raydium/types.d.ts +240 -0
  104. package/dist/sol/dex/raydium/types.js +5 -0
  105. package/dist/sol/index.d.ts +10 -0
  106. package/dist/sol/index.js +16 -0
  107. package/dist/sol/jito/bundle.d.ts +90 -0
  108. package/dist/sol/jito/bundle.js +263 -0
  109. package/dist/sol/jito/index.d.ts +7 -0
  110. package/dist/sol/jito/index.js +7 -0
  111. package/dist/sol/jito/tip.d.ts +51 -0
  112. package/dist/sol/jito/tip.js +83 -0
  113. package/dist/sol/jito/types.d.ts +100 -0
  114. package/dist/sol/jito/types.js +5 -0
  115. package/dist/sol/token/create-complete.d.ts +115 -0
  116. package/dist/sol/token/create-complete.js +235 -0
  117. package/dist/sol/token/create-token.d.ts +57 -0
  118. package/dist/sol/token/create-token.js +230 -0
  119. package/dist/sol/token/index.d.ts +9 -0
  120. package/dist/sol/token/index.js +14 -0
  121. package/dist/sol/token/metadata-upload.d.ts +86 -0
  122. package/dist/sol/token/metadata-upload.js +173 -0
  123. package/dist/sol/token/metadata.d.ts +92 -0
  124. package/dist/sol/token/metadata.js +274 -0
  125. package/dist/sol/token/types.d.ts +153 -0
  126. package/dist/sol/token/types.js +5 -0
  127. package/dist/sol/types.d.ts +176 -0
  128. package/dist/sol/types.js +7 -0
  129. package/dist/sol/utils/balance.d.ts +160 -0
  130. package/dist/sol/utils/balance.js +638 -0
  131. package/dist/sol/utils/connection.d.ts +78 -0
  132. package/dist/sol/utils/connection.js +168 -0
  133. package/dist/sol/utils/index.d.ts +9 -0
  134. package/dist/sol/utils/index.js +9 -0
  135. package/dist/sol/utils/lp-inspect.d.ts +129 -0
  136. package/dist/sol/utils/lp-inspect.js +900 -0
  137. package/dist/sol/utils/transfer.d.ts +196 -0
  138. package/dist/sol/utils/transfer.js +307 -0
  139. package/dist/sol/utils/wallet.d.ts +107 -0
  140. package/dist/sol/utils/wallet.js +210 -0
  141. package/dist/xlayer/aa-account.d.ts +240 -0
  142. package/dist/xlayer/aa-account.js +510 -0
  143. package/dist/xlayer/bundle.d.ts +93 -0
  144. package/dist/xlayer/bundle.js +472 -0
  145. package/dist/xlayer/bundler.d.ts +111 -0
  146. package/dist/xlayer/bundler.js +162 -0
  147. package/dist/xlayer/constants.d.ts +75 -0
  148. package/dist/xlayer/constants.js +145 -0
  149. package/dist/xlayer/dex.d.ts +132 -0
  150. package/dist/xlayer/dex.js +335 -0
  151. package/dist/xlayer/examples/bundle-buy-sell.d.ts +11 -0
  152. package/dist/xlayer/examples/bundle-buy-sell.js +194 -0
  153. package/dist/xlayer/index.d.ts +75 -0
  154. package/dist/xlayer/index.js +130 -0
  155. package/dist/xlayer/portal-ops.d.ts +152 -0
  156. package/dist/xlayer/portal-ops.js +239 -0
  157. package/dist/xlayer/types.d.ts +298 -0
  158. package/dist/xlayer/types.js +6 -0
  159. package/dist/xlayer/volume.d.ts +65 -0
  160. package/dist/xlayer/volume.js +235 -0
  161. package/package.json +38 -3
  162. package/README.zh-CN.pdf +0 -0
  163. package/dist/flap/portal-bundle-merkle/encryption.d.ts +0 -16
  164. package/dist/flap/portal-bundle-merkle/encryption.js +0 -146
@@ -0,0 +1,335 @@
1
+ /**
2
+ * XLayer 外盘交易 SDK
3
+ *
4
+ * 通过 PotatoSwap 进行外盘交易:
5
+ * - V2 Router 交易
6
+ * - 支持 OKB/Token 双向交换
7
+ * - 通过 AA 账户执行
8
+ */
9
+ import { ethers, Contract, Interface, JsonRpcProvider } from 'ethers';
10
+ import { POTATOSWAP_V2_ROUTER, POTATOSWAP_V2_ROUTER_ABI, WOKB, DEFAULT_RPC_URL, XLAYER_CHAIN_ID, ERC20_ABI, } from './constants.js';
11
+ import { AAAccountManager, encodeExecute, createWallet } from './aa-account.js';
12
+ import { encodeApproveCall, parseOkb } from './portal-ops.js';
13
+ // ============================================================================
14
+ // DEX 交易编码器
15
+ // ============================================================================
16
+ const routerIface = new Interface(POTATOSWAP_V2_ROUTER_ABI);
17
+ /**
18
+ * 编码 swapExactETHForTokens 调用
19
+ */
20
+ export function encodeSwapExactETHForTokens(amountOutMin, path, to, deadline) {
21
+ return routerIface.encodeFunctionData('swapExactETHForTokens', [
22
+ amountOutMin,
23
+ path,
24
+ to,
25
+ deadline,
26
+ ]);
27
+ }
28
+ /**
29
+ * 编码 swapExactETHForTokensSupportingFeeOnTransferTokens 调用
30
+ * 推荐使用:支持有手续费/分红机制的代币
31
+ */
32
+ export function encodeSwapExactETHForTokensSupportingFee(amountOutMin, path, to, deadline) {
33
+ return routerIface.encodeFunctionData('swapExactETHForTokensSupportingFeeOnTransferTokens', [
34
+ amountOutMin,
35
+ path,
36
+ to,
37
+ deadline,
38
+ ]);
39
+ }
40
+ /**
41
+ * 编码 swapExactTokensForETH 调用
42
+ */
43
+ export function encodeSwapExactTokensForETH(amountIn, amountOutMin, path, to, deadline) {
44
+ return routerIface.encodeFunctionData('swapExactTokensForETH', [
45
+ amountIn,
46
+ amountOutMin,
47
+ path,
48
+ to,
49
+ deadline,
50
+ ]);
51
+ }
52
+ /**
53
+ * 编码 swapExactTokensForETHSupportingFeeOnTransferTokens 调用
54
+ * 推荐使用:支持有手续费/分红机制的代币
55
+ */
56
+ export function encodeSwapExactTokensForETHSupportingFee(amountIn, amountOutMin, path, to, deadline) {
57
+ return routerIface.encodeFunctionData('swapExactTokensForETHSupportingFeeOnTransferTokens', [
58
+ amountIn,
59
+ amountOutMin,
60
+ path,
61
+ to,
62
+ deadline,
63
+ ]);
64
+ }
65
+ /**
66
+ * 编码 swapExactTokensForTokens 调用
67
+ */
68
+ export function encodeSwapExactTokensForTokens(amountIn, amountOutMin, path, to, deadline) {
69
+ return routerIface.encodeFunctionData('swapExactTokensForTokens', [
70
+ amountIn,
71
+ amountOutMin,
72
+ path,
73
+ to,
74
+ deadline,
75
+ ]);
76
+ }
77
+ /**
78
+ * 编码 swapExactTokensForTokensSupportingFeeOnTransferTokens 调用
79
+ * 推荐使用:支持有手续费/分红机制的代币
80
+ */
81
+ export function encodeSwapExactTokensForTokensSupportingFee(amountIn, amountOutMin, path, to, deadline) {
82
+ return routerIface.encodeFunctionData('swapExactTokensForTokensSupportingFeeOnTransferTokens', [
83
+ amountIn,
84
+ amountOutMin,
85
+ path,
86
+ to,
87
+ deadline,
88
+ ]);
89
+ }
90
+ /**
91
+ * DEX 交易查询器
92
+ */
93
+ export class DexQuery {
94
+ constructor(config = {}) {
95
+ const rpcUrl = config.rpcUrl ?? DEFAULT_RPC_URL;
96
+ const chainId = config.chainId ?? XLAYER_CHAIN_ID;
97
+ this.provider = new JsonRpcProvider(rpcUrl, { chainId, name: 'xlayer' });
98
+ this.routerAddress = config.routerAddress ?? POTATOSWAP_V2_ROUTER;
99
+ this.wokb = config.wokbAddress ?? WOKB;
100
+ this.router = new Contract(this.routerAddress, POTATOSWAP_V2_ROUTER_ABI, this.provider);
101
+ }
102
+ /**
103
+ * 获取交易路径的输出金额
104
+ */
105
+ async getAmountsOut(amountIn, path) {
106
+ const amounts = await this.router.getAmountsOut(amountIn, path);
107
+ return amounts.map((a) => BigInt(a));
108
+ }
109
+ /**
110
+ * 获取交易路径的输入金额
111
+ */
112
+ async getAmountsIn(amountOut, path) {
113
+ const amounts = await this.router.getAmountsIn(amountOut, path);
114
+ return amounts.map((a) => BigInt(a));
115
+ }
116
+ /**
117
+ * 获取 OKB -> Token 的预期输出
118
+ */
119
+ async quoteOkbToToken(okbAmount, tokenAddress) {
120
+ const path = [this.wokb, tokenAddress];
121
+ const amounts = await this.getAmountsOut(okbAmount, path);
122
+ return amounts[amounts.length - 1];
123
+ }
124
+ /**
125
+ * 获取 Token -> OKB 的预期输出
126
+ */
127
+ async quoteTokenToOkb(tokenAmount, tokenAddress) {
128
+ const path = [tokenAddress, this.wokb];
129
+ const amounts = await this.getAmountsOut(tokenAmount, path);
130
+ return amounts[amounts.length - 1];
131
+ }
132
+ /**
133
+ * 获取 WOKB 地址
134
+ */
135
+ getWokbAddress() {
136
+ return this.wokb;
137
+ }
138
+ /**
139
+ * 获取 Router 地址
140
+ */
141
+ getRouterAddress() {
142
+ return this.routerAddress;
143
+ }
144
+ }
145
+ /**
146
+ * DEX 交易执行器
147
+ *
148
+ * 通过 AA 账户在 PotatoSwap 上进行交易
149
+ */
150
+ export class DexExecutor {
151
+ constructor(config = {}) {
152
+ this.config = config;
153
+ this.aaManager = new AAAccountManager(config);
154
+ this.dexQuery = new DexQuery(config);
155
+ this.routerAddress = config.routerAddress ?? POTATOSWAP_V2_ROUTER;
156
+ this.wokb = config.wokbAddress ?? WOKB;
157
+ this.deadlineMinutes = config.deadlineMinutes ?? 20;
158
+ }
159
+ /**
160
+ * 获取 deadline 时间戳
161
+ */
162
+ getDeadline() {
163
+ return Math.floor(Date.now() / 1000) + this.deadlineMinutes * 60;
164
+ }
165
+ /**
166
+ * OKB -> Token 交易(通过 EOA 直接执行)
167
+ * 使用 SupportingFeeOnTransferTokens 版本,支持有手续费/分红的代币
168
+ */
169
+ async swapOkbForToken(privateKey, tokenAddress, okbAmount, minTokenAmount = 0n) {
170
+ const wallet = createWallet(privateKey, this.config);
171
+ const router = new Contract(this.routerAddress, POTATOSWAP_V2_ROUTER_ABI, wallet);
172
+ const path = [this.wokb, tokenAddress];
173
+ const deadline = this.getDeadline();
174
+ const tx = await router.swapExactETHForTokensSupportingFeeOnTransferTokens(minTokenAmount, path, wallet.address, deadline, { value: okbAmount });
175
+ const receipt = await tx.wait();
176
+ return {
177
+ txHash: tx.hash,
178
+ inputAmount: okbAmount,
179
+ outputAmount: 0n, // 需要从事件中解析
180
+ gasUsed: receipt.gasUsed,
181
+ };
182
+ }
183
+ /**
184
+ * Token -> OKB 交易(通过 EOA 直接执行)
185
+ * 使用 SupportingFeeOnTransferTokens 版本,支持有手续费/分红的代币
186
+ */
187
+ async swapTokenForOkb(privateKey, tokenAddress, tokenAmount, minOkbAmount = 0n) {
188
+ const wallet = createWallet(privateKey, this.config);
189
+ const token = new Contract(tokenAddress, ERC20_ABI, wallet);
190
+ const router = new Contract(this.routerAddress, POTATOSWAP_V2_ROUTER_ABI, wallet);
191
+ // 检查并授权
192
+ const allowance = await token.allowance(wallet.address, this.routerAddress);
193
+ if (allowance < tokenAmount) {
194
+ console.log('授权 Router...');
195
+ const approveTx = await token.approve(this.routerAddress, ethers.MaxUint256);
196
+ await approveTx.wait();
197
+ }
198
+ const path = [tokenAddress, this.wokb];
199
+ const deadline = this.getDeadline();
200
+ const tx = await router.swapExactTokensForETHSupportingFeeOnTransferTokens(tokenAmount, minOkbAmount, path, wallet.address, deadline);
201
+ const receipt = await tx.wait();
202
+ return {
203
+ txHash: tx.hash,
204
+ inputAmount: tokenAmount,
205
+ outputAmount: 0n,
206
+ gasUsed: receipt.gasUsed,
207
+ };
208
+ }
209
+ /**
210
+ * 通过 AA 账户执行 OKB -> Token 交易
211
+ * 使用 SupportingFeeOnTransferTokens 版本,支持有手续费/分红的代币
212
+ */
213
+ async swapOkbForTokenViaAA(privateKey, tokenAddress, okbAmount, minTokenAmount = 0n) {
214
+ const wallet = createWallet(privateKey, this.config);
215
+ const accountInfo = await this.aaManager.getAccountInfo(wallet.address);
216
+ const path = [this.wokb, tokenAddress];
217
+ const deadline = this.getDeadline();
218
+ // 构建 swapExactETHForTokensSupportingFeeOnTransferTokens calldata
219
+ const swapData = encodeSwapExactETHForTokensSupportingFee(minTokenAmount, path, accountInfo.sender, // 代币接收地址为 sender
220
+ deadline);
221
+ // 通过 execute 调用 router
222
+ const callData = encodeExecute(this.routerAddress, okbAmount, swapData);
223
+ // 确保 sender 有足够余额
224
+ await this.aaManager.ensureSenderBalance(wallet, accountInfo.sender, okbAmount + parseOkb('0.001'), 'dex-swap-prefund');
225
+ // 构建并签名 UserOp
226
+ const signedOp = await this.aaManager.buildAndSignUserOp({
227
+ ownerWallet: wallet,
228
+ callData,
229
+ value: okbAmount,
230
+ });
231
+ // 执行 handleOps
232
+ const provider = this.aaManager.getProvider();
233
+ const entryPoint = this.aaManager.getEntryPoint();
234
+ const feeData = await provider.getFeeData();
235
+ // 使用新 Contract 实例避免 TypeScript 类型问题
236
+ const entryPointWithSigner = new Contract(await entryPoint.getAddress(), ['function handleOps((address sender,uint256 nonce,bytes initCode,bytes callData,uint256 callGasLimit,uint256 verificationGasLimit,uint256 preVerificationGas,uint256 maxFeePerGas,uint256 maxPriorityFeePerGas,bytes paymasterAndData,bytes signature)[] ops, address payable beneficiary) external'], wallet);
237
+ const tx = await entryPointWithSigner.handleOps([signedOp.userOp], wallet.address, { gasPrice: feeData.gasPrice ?? 100000000n });
238
+ const receipt = await tx.wait();
239
+ return {
240
+ txHash: tx.hash,
241
+ inputAmount: okbAmount,
242
+ outputAmount: 0n,
243
+ gasUsed: receipt.gasUsed,
244
+ };
245
+ }
246
+ /**
247
+ * 通过 AA 账户执行 Token -> OKB 交易
248
+ */
249
+ async swapTokenForOkbViaAA(privateKey, tokenAddress, tokenAmount, minOkbAmount = 0n) {
250
+ const wallet = createWallet(privateKey, this.config);
251
+ const accountInfo = await this.aaManager.getAccountInfo(wallet.address);
252
+ const provider = this.aaManager.getProvider();
253
+ const entryPoint = this.aaManager.getEntryPoint();
254
+ const feeData = await provider.getFeeData();
255
+ const path = [tokenAddress, this.wokb];
256
+ const deadline = this.getDeadline();
257
+ // 检查授权
258
+ const token = new Contract(tokenAddress, ERC20_ABI, provider);
259
+ const allowance = await token.allowance(accountInfo.sender, this.routerAddress);
260
+ const ops = [];
261
+ let nonce = accountInfo.nonce;
262
+ // 如果需要授权
263
+ if (allowance < tokenAmount) {
264
+ const approveData = encodeApproveCall(this.routerAddress);
265
+ const approveCallData = encodeExecute(tokenAddress, 0n, approveData);
266
+ const approveOp = await this.aaManager.buildUserOpWithLocalEstimate({
267
+ ownerWallet: wallet,
268
+ sender: accountInfo.sender,
269
+ callData: approveCallData,
270
+ nonce,
271
+ });
272
+ const signedApprove = await this.aaManager.signUserOp(approveOp.userOp, wallet);
273
+ ops.push(signedApprove.userOp);
274
+ nonce = nonce + 1n;
275
+ }
276
+ // 构建 swap calldata(使用 SupportingFeeOnTransferTokens 版本)
277
+ const swapData = encodeSwapExactTokensForETHSupportingFee(tokenAmount, minOkbAmount, path, accountInfo.sender, deadline);
278
+ const swapCallData = encodeExecute(this.routerAddress, 0n, swapData);
279
+ // 确保 sender 有足够的 gas 费
280
+ await this.aaManager.ensureSenderBalance(wallet, accountInfo.sender, parseOkb('0.001'), 'dex-swap-gas');
281
+ const swapOp = await this.aaManager.buildUserOpWithLocalEstimate({
282
+ ownerWallet: wallet,
283
+ sender: accountInfo.sender,
284
+ callData: swapCallData,
285
+ nonce,
286
+ });
287
+ const signedSwap = await this.aaManager.signUserOp(swapOp.userOp, wallet);
288
+ ops.push(signedSwap.userOp);
289
+ // 执行(使用新 Contract 实例避免 TypeScript 类型问题)
290
+ const entryPointWithSigner = new Contract(await entryPoint.getAddress(), ['function handleOps((address sender,uint256 nonce,bytes initCode,bytes callData,uint256 callGasLimit,uint256 verificationGasLimit,uint256 preVerificationGas,uint256 maxFeePerGas,uint256 maxPriorityFeePerGas,bytes paymasterAndData,bytes signature)[] ops, address payable beneficiary) external'], wallet);
291
+ const tx = await entryPointWithSigner.handleOps(ops, wallet.address, { gasPrice: feeData.gasPrice ?? 100000000n });
292
+ const receipt = await tx.wait();
293
+ return {
294
+ txHash: tx.hash,
295
+ inputAmount: tokenAmount,
296
+ outputAmount: 0n,
297
+ gasUsed: receipt.gasUsed,
298
+ };
299
+ }
300
+ /**
301
+ * 获取 DEX 查询器
302
+ */
303
+ getDexQuery() {
304
+ return this.dexQuery;
305
+ }
306
+ }
307
+ // ============================================================================
308
+ // 便捷函数
309
+ // ============================================================================
310
+ /**
311
+ * 创建 DEX 查询器
312
+ */
313
+ export function createDexQuery(config) {
314
+ return new DexQuery(config);
315
+ }
316
+ /**
317
+ * 创建 DEX 执行器
318
+ */
319
+ export function createDexExecutor(config) {
320
+ return new DexExecutor(config);
321
+ }
322
+ /**
323
+ * 快速获取 OKB -> Token 报价
324
+ */
325
+ export async function quoteOkbToToken(okbAmount, tokenAddress, config) {
326
+ const query = createDexQuery(config);
327
+ return query.quoteOkbToToken(okbAmount, tokenAddress);
328
+ }
329
+ /**
330
+ * 快速获取 Token -> OKB 报价
331
+ */
332
+ export async function quoteTokenToOkb(tokenAmount, tokenAddress, config) {
333
+ const query = createDexQuery(config);
334
+ return query.quoteTokenToOkb(tokenAmount, tokenAddress);
335
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * XLayer SDK 使用示例:捆绑买卖
3
+ *
4
+ * 演示如何使用 SDK 进行 Flap 内盘交易
5
+ *
6
+ * 运行前请确保:
7
+ * 1. 在 .env 文件中配置 OWNER_PRIVATE_KEY 和 OWNER_PRIVATE_KEY2
8
+ * 2. 配置 FLAP_TOKEN 为目标代币地址
9
+ * 3. 确保 owner 钱包有足够的 OKB
10
+ */
11
+ export {};
@@ -0,0 +1,194 @@
1
+ /**
2
+ * XLayer SDK 使用示例:捆绑买卖
3
+ *
4
+ * 演示如何使用 SDK 进行 Flap 内盘交易
5
+ *
6
+ * 运行前请确保:
7
+ * 1. 在 .env 文件中配置 OWNER_PRIVATE_KEY 和 OWNER_PRIVATE_KEY2
8
+ * 2. 配置 FLAP_TOKEN 为目标代币地址
9
+ * 3. 确保 owner 钱包有足够的 OKB
10
+ */
11
+ import { bundleBuy, bundleSell, bundleBuySell, makeVolume, createBundleExecutor, createAAAccountManager, predictSender, parseOkb, formatOkb, QUIKNODE_RPC_URL, } from '../index.js';
12
+ // 配置
13
+ const config = {
14
+ rpcUrl: QUIKNODE_RPC_URL, // 使用付费 RPC 获得更好的性能
15
+ // paymaster: '0x...', // 如果有 Paymaster,指定后不需要往 AA 地址转手续费
16
+ };
17
+ // 从环境变量读取私钥
18
+ const OWNER_PRIVATE_KEY = process.env.OWNER_PRIVATE_KEY;
19
+ const OWNER_PRIVATE_KEY2 = process.env.OWNER_PRIVATE_KEY2;
20
+ const FLAP_TOKEN = process.env.FLAP_TOKEN;
21
+ /**
22
+ * 示例 1: 查看 AA 账户信息
23
+ */
24
+ async function example1_getAccountInfo() {
25
+ console.log('\n=== 示例 1: 查看 AA 账户信息 ===\n');
26
+ const aaManager = createAAAccountManager(config);
27
+ // 从私钥获取 owner 地址
28
+ const { Wallet } = await import('ethers');
29
+ const owner1 = new Wallet(OWNER_PRIVATE_KEY);
30
+ const owner2 = new Wallet(OWNER_PRIVATE_KEY2);
31
+ // 预测 sender 地址
32
+ const sender1 = await predictSender(owner1.address, config);
33
+ const sender2 = await predictSender(owner2.address, config);
34
+ console.log('Owner 1:', owner1.address);
35
+ console.log('Sender 1 (AA):', sender1);
36
+ console.log('\nOwner 2:', owner2.address);
37
+ console.log('Sender 2 (AA):', sender2);
38
+ // 获取完整账户信息
39
+ const info1 = await aaManager.getAccountInfo(owner1.address);
40
+ const info2 = await aaManager.getAccountInfo(owner2.address);
41
+ console.log('\n账户 1 信息:');
42
+ console.log('- 已部署:', info1.deployed);
43
+ console.log('- 余额:', formatOkb(info1.balance), 'OKB');
44
+ console.log('- Nonce:', info1.nonce.toString());
45
+ console.log('\n账户 2 信息:');
46
+ console.log('- 已部署:', info2.deployed);
47
+ console.log('- 余额:', formatOkb(info2.balance), 'OKB');
48
+ console.log('- Nonce:', info2.nonce.toString());
49
+ }
50
+ /**
51
+ * 示例 2: 捆绑买入
52
+ */
53
+ async function example2_bundleBuy() {
54
+ console.log('\n=== 示例 2: 捆绑买入 ===\n');
55
+ const result = await bundleBuy({
56
+ tokenAddress: FLAP_TOKEN,
57
+ privateKeys: [OWNER_PRIVATE_KEY, OWNER_PRIVATE_KEY2],
58
+ buyAmounts: ['0.001', '0.001'], // 每个地址买入 0.001 OKB
59
+ transferBackToOwner: false, // 代币保留在 sender
60
+ config,
61
+ });
62
+ console.log('买入交易哈希:', result.buyResult.txHash);
63
+ console.log('区块号:', result.buyResult.blockNumber);
64
+ // 显示代币余额
65
+ console.log('\n代币余额:');
66
+ for (const [sender, balance] of result.tokenBalances) {
67
+ console.log(`- ${sender}: ${balance.toString()}`);
68
+ }
69
+ }
70
+ /**
71
+ * 示例 3: 捆绑卖出
72
+ */
73
+ async function example3_bundleSell() {
74
+ console.log('\n=== 示例 3: 捆绑卖出 ===\n');
75
+ const result = await bundleSell({
76
+ tokenAddress: FLAP_TOKEN,
77
+ privateKeys: [OWNER_PRIVATE_KEY, OWNER_PRIVATE_KEY2],
78
+ sellPercent: 100, // 卖出全部
79
+ withdrawToOwner: true, // 将 OKB 归集回 owner
80
+ withdrawReserve: '0.00005', // 保留少量在 sender
81
+ config,
82
+ });
83
+ if (result.approveResult) {
84
+ console.log('授权交易哈希:', result.approveResult.txHash);
85
+ }
86
+ console.log('卖出交易哈希:', result.sellResult.txHash);
87
+ if (result.withdrawResult) {
88
+ console.log('归集交易哈希:', result.withdrawResult.txHash);
89
+ }
90
+ }
91
+ /**
92
+ * 示例 4: 买卖一体化(先买后卖)
93
+ */
94
+ async function example4_bundleBuySell() {
95
+ console.log('\n=== 示例 4: 买卖一体化 ===\n');
96
+ const result = await bundleBuySell({
97
+ tokenAddress: FLAP_TOKEN,
98
+ privateKeys: [OWNER_PRIVATE_KEY, OWNER_PRIVATE_KEY2],
99
+ buyAmounts: ['0.001', '0.001'],
100
+ sellPercent: 100,
101
+ withdrawToOwner: true,
102
+ withdrawReserve: '0.00005',
103
+ config,
104
+ });
105
+ console.log('买入交易:', result.buyResult.txHash);
106
+ console.log('卖出交易:', result.sellResult.txHash);
107
+ if (result.withdrawResult) {
108
+ console.log('归集交易:', result.withdrawResult.txHash);
109
+ }
110
+ console.log('\n最终余额:');
111
+ for (const [sender, balance] of result.finalBalances) {
112
+ console.log(`- ${sender}: ${formatOkb(balance)} OKB`);
113
+ }
114
+ }
115
+ /**
116
+ * 示例 5: 刷量
117
+ */
118
+ async function example5_makeVolume() {
119
+ console.log('\n=== 示例 5: 刷量 ===\n');
120
+ const result = await makeVolume({
121
+ tokenAddress: FLAP_TOKEN,
122
+ privateKeys: [OWNER_PRIVATE_KEY, OWNER_PRIVATE_KEY2],
123
+ buyAmountPerRound: '0.001',
124
+ rounds: 3, // 3 轮
125
+ intervalMs: 3000, // 每轮间隔 3 秒
126
+ sellImmediately: true,
127
+ config,
128
+ });
129
+ console.log('成功轮数:', result.successRounds);
130
+ console.log('失败轮数:', result.failedRounds);
131
+ console.log('总交易量:', formatOkb(result.totalVolume), 'OKB');
132
+ }
133
+ /**
134
+ * 示例 6: 使用 Paymaster(免 Gas)
135
+ */
136
+ async function example6_withPaymaster() {
137
+ console.log('\n=== 示例 6: 使用 Paymaster ===\n');
138
+ // 配置 Paymaster 后,不需要往 AA 地址转手续费
139
+ const paymasterConfig = {
140
+ ...config,
141
+ paymaster: '0x...', // 替换为实际的 Paymaster 地址
142
+ paymasterData: '0x', // 可选的 Paymaster 数据
143
+ };
144
+ const executor = createBundleExecutor(paymasterConfig);
145
+ // 使用 Paymaster 执行交易
146
+ // sender 只需要买入金额,不需要额外的 gas 费
147
+ console.log('使用 Paymaster 后,sender 不需要预先充值 gas 费');
148
+ }
149
+ /**
150
+ * 示例 7: 高级用法 - 手动构建 UserOp
151
+ */
152
+ async function example7_advancedUsage() {
153
+ console.log('\n=== 示例 7: 高级用法 ===\n');
154
+ const executor = createBundleExecutor(config);
155
+ const aaManager = executor.getAAManager();
156
+ const portalQuery = executor.getPortalQuery();
157
+ // 获取代币状态
158
+ const tokenState = await portalQuery.getTokenV5(FLAP_TOKEN);
159
+ console.log('代币状态:', tokenState.status);
160
+ console.log('储备:', formatOkb(tokenState.reserve), 'OKB');
161
+ console.log('流通量:', tokenState.circulatingSupply.toString());
162
+ // 预览买入
163
+ const buyPreview = await portalQuery.previewBuy(FLAP_TOKEN, parseOkb('0.01'));
164
+ console.log('买入 0.01 OKB 预计获得:', buyPreview.toString(), '代币');
165
+ // 预览卖出
166
+ const sellPreview = await portalQuery.previewSell(FLAP_TOKEN, parseOkb('1000'));
167
+ console.log('卖出 1000 代币预计获得:', formatOkb(sellPreview), 'OKB');
168
+ }
169
+ // 主函数
170
+ async function main() {
171
+ console.log('XLayer SDK 使用示例');
172
+ console.log('==================\n');
173
+ if (!OWNER_PRIVATE_KEY || !OWNER_PRIVATE_KEY2 || !FLAP_TOKEN) {
174
+ console.error('请先配置环境变量:');
175
+ console.error('- OWNER_PRIVATE_KEY');
176
+ console.error('- OWNER_PRIVATE_KEY2');
177
+ console.error('- FLAP_TOKEN');
178
+ process.exit(1);
179
+ }
180
+ try {
181
+ // 取消注释以运行对应的示例
182
+ await example1_getAccountInfo();
183
+ // await example2_bundleBuy();
184
+ // await example3_bundleSell();
185
+ // await example4_bundleBuySell();
186
+ // await example5_makeVolume();
187
+ // await example7_advancedUsage();
188
+ }
189
+ catch (error) {
190
+ console.error('错误:', error);
191
+ process.exit(1);
192
+ }
193
+ }
194
+ main();
@@ -0,0 +1,75 @@
1
+ /**
2
+ * XLayer SDK
3
+ *
4
+ * 完整的 XLayer 链 Flap 内盘交易 SDK
5
+ *
6
+ * 功能特性:
7
+ * - 🔗 基于 ERC-4337 AA 账户抽象
8
+ * - 📦 捆绑买入/卖出(多地址同一笔 handleOps)
9
+ * - 🔄 买卖一体化(买入 -> 授权 -> 卖出 -> 归集)
10
+ * - 📊 刷量/做市(多轮买卖循环)
11
+ * - 🌐 外盘交易(PotatoSwap DEX)
12
+ * - 💰 支持 Paymaster(免 Gas)
13
+ *
14
+ * 使用示例:
15
+ *
16
+ * ```typescript
17
+ * import {
18
+ * bundleBuy,
19
+ * bundleSell,
20
+ * bundleBuySell,
21
+ * makeVolume,
22
+ * createBundleExecutor
23
+ * } from './xlayer';
24
+ *
25
+ * // 捆绑买入
26
+ * const buyResult = await bundleBuy({
27
+ * tokenAddress: '0x...',
28
+ * privateKeys: ['0x...', '0x...'],
29
+ * buyAmounts: ['0.01', '0.02'],
30
+ * });
31
+ *
32
+ * // 捆绑卖出
33
+ * const sellResult = await bundleSell({
34
+ * tokenAddress: '0x...',
35
+ * privateKeys: ['0x...', '0x...'],
36
+ * sellPercent: 100,
37
+ * withdrawToOwner: true,
38
+ * });
39
+ *
40
+ * // 买卖一体化
41
+ * const buySellResult = await bundleBuySell({
42
+ * tokenAddress: '0x...',
43
+ * privateKeys: ['0x...', '0x...'],
44
+ * buyAmounts: ['0.01', '0.02'],
45
+ * sellPercent: 100,
46
+ * withdrawToOwner: true,
47
+ * });
48
+ *
49
+ * // 刷量
50
+ * const volumeResult = await makeVolume({
51
+ * tokenAddress: '0x...',
52
+ * privateKeys: ['0x...', '0x...'],
53
+ * buyAmountPerRound: '0.01',
54
+ * rounds: 10,
55
+ * intervalMs: 3000,
56
+ * });
57
+ * ```
58
+ */
59
+ export * from './constants.js';
60
+ export * from './types.js';
61
+ export { BundlerClient, createBundlerClient, type BundlerConfig, type BundlerReceipt, } from './bundler.js';
62
+ export { AAAccountManager, createAAAccountManager, predictSender, createWallet, encodeExecute, encodeExecuteBatch, generateAAWallets, generateAAWalletsFromMnemonic, predictSendersFromPrivateKeys, type GeneratedAAWallet, type GenerateAAWalletsParams, type GenerateAAWalletsResult, } from './aa-account.js';
63
+ export { encodeBuyCall, encodeSellCall, encodeApproveCall, encodeTransferCall, PortalQuery, createPortalQuery, applySlippage, formatOkb, parseOkb, formatTokenAmount, parseTokenAmount, type PortalQueryConfig, } from './portal-ops.js';
64
+ export { BundleExecutor, createBundleExecutor, bundleBuy, bundleSell, bundleBuySell, } from './bundle.js';
65
+ export { VolumeExecutor, createVolumeExecutor, makeVolume, singleRoundVolume, } from './volume.js';
66
+ export { DexQuery, DexExecutor, createDexQuery, createDexExecutor, quoteOkbToToken, quoteTokenToOkb, encodeSwapExactETHForTokens, encodeSwapExactTokensForETH, encodeSwapExactTokensForTokens, encodeSwapExactETHForTokensSupportingFee, encodeSwapExactTokensForETHSupportingFee, encodeSwapExactTokensForTokensSupportingFee, type DexConfig, } from './dex.js';
67
+ export declare const xlayer: {
68
+ bundleBuy: (params: import("./types.js").BundleBuyParams) => Promise<import("./types.js").BundleBuyResult>;
69
+ bundleSell: (params: import("./types.js").BundleSellParams) => Promise<import("./types.js").BundleSellResult>;
70
+ bundleBuySell: (params: import("./types.js").BundleBuySellParams) => Promise<import("./types.js").BundleBuySellResult>;
71
+ makeVolume: (params: import("./types.js").VolumeParams) => Promise<import("./types.js").VolumeResult>;
72
+ quoteOkbToToken: (okbAmount: bigint, tokenAddress: string, config?: import("./dex.js").DexConfig | undefined) => Promise<bigint>;
73
+ quoteTokenToOkb: (tokenAmount: bigint, tokenAddress: string, config?: import("./dex.js").DexConfig | undefined) => Promise<bigint>;
74
+ };
75
+ export default xlayer;