four-flap-meme-sdk 1.5.41 → 1.5.42

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.
@@ -1134,7 +1134,8 @@ export class BundleExecutor {
1134
1134
  // 1. 准备代币地址
1135
1135
  const tokenAddress = params.tokenAddress || ZERO_ADDRESS;
1136
1136
  // 2. 构造 UserOperations
1137
- const ops = [];
1137
+ const mainOps = [];
1138
+ const profitOps = [];
1138
1139
  const nonceMap = new AANonceMap();
1139
1140
  // 2a. Dev 发射代币
1140
1141
  const devAccount = await this.aaManager.getAccountInfo(devWallet.address);
@@ -1205,15 +1206,14 @@ export class BundleExecutor {
1205
1206
  deployed: devAccount.deployed
1206
1207
  });
1207
1208
  const signedDevOp = await this.aaManager.signUserOp(devCreateOp.userOp, devWallet);
1208
- ops.push(signedDevOp.userOp);
1209
+ mainOps.push(signedDevOp.userOp);
1209
1210
  // 2b. Buyers 买入
1210
1211
  const profitSettings = resolveProfitSettings(effConfig);
1211
1212
  const inputToken = params.quoteToken && params.quoteToken !== ZERO_ADDRESS ? params.quoteToken : ZERO_ADDRESS;
1212
1213
  const useNativeToken = inputToken === ZERO_ADDRESS;
1213
- // BundleCreateBuyParams 目前没有 quoteTokenDecimals,默认用 18
1214
1214
  const quoteDecimals = 18;
1215
1215
  let totalBuyWei = 0n;
1216
- let totalBuyProfitWei = 0n; // inputToken 本位利润
1216
+ let totalBuyProfitWei = 0n;
1217
1217
  const buyerSenders = [];
1218
1218
  const profitWeis = [];
1219
1219
  const portalIface = new Interface(PORTAL_ABI);
@@ -1234,7 +1234,6 @@ export class BundleExecutor {
1234
1234
  const buyerAccount = await this.aaManager.getAccountInfo(buyer.address);
1235
1235
  buyerSenders.push(buyerAccount.sender);
1236
1236
  nonceMap.init(buyerAccount.sender, buyerAccount.nonce);
1237
- // 买入:使用扣除利润后的金额
1238
1237
  const swapData = portalIface.encodeFunctionData('swapExactInput', [
1239
1238
  {
1240
1239
  inputToken,
@@ -1253,11 +1252,10 @@ export class BundleExecutor {
1253
1252
  deployed: buyerAccount.deployed
1254
1253
  });
1255
1254
  const signedBuyOp = await this.aaManager.signUserOp(buyOp.userOp, buyer);
1256
- ops.push(signedBuyOp.userOp);
1255
+ mainOps.push(signedBuyOp.userOp);
1257
1256
  }
1258
- // ✅ 刮取利润:折算并转账(SignOnly 模式也需要包含此 UserOp)
1257
+ // ✅ 刮取利润:单独作为一个交易签名
1259
1258
  if (profitSettings.extractProfit && totalBuyProfitWei > 0n) {
1260
- // 1. 获取 OKB 报价(SignOnly 模式也需要这个报价来决定最终转账金额)
1261
1259
  let nativeProfitAmount = totalBuyProfitWei;
1262
1260
  if (!useNativeToken) {
1263
1261
  try {
@@ -1275,19 +1273,16 @@ export class BundleExecutor {
1275
1273
  }
1276
1274
  }
1277
1275
  if (nativeProfitAmount > 0n) {
1278
- console.log(`[利润提取-签名] 总利润: ${useNativeToken ? formatOkb(nativeProfitAmount) : `${formatOkb(totalBuyProfitWei)} (ERC20) -> ${formatOkb(nativeProfitAmount)} (OKB)`} -> ${profitSettings.profitRecipient}`);
1279
- // 找到利润贡献最大的买家作为利润转账的 sender
1280
1276
  const maxProfitIndex = profitWeis.reduce((maxIdx, p, idx) => p > (profitWeis[maxIdx] ?? 0n) ? idx : maxIdx, 0);
1281
1277
  const pOwner = buyerWallets[maxProfitIndex];
1282
1278
  const pSender = buyerSenders[maxProfitIndex];
1283
- // 利润转账:直接转 OKB(对齐 bundleBuy 语义)
1284
1279
  const profitCallData = encodeExecute(profitSettings.profitRecipient, nativeProfitAmount, '0x');
1285
1280
  const profitOp = await this.aaManager.buildUserOpWithFixedGas({
1286
1281
  ownerWallet: pOwner,
1287
1282
  sender: pSender,
1288
1283
  callData: profitCallData,
1289
1284
  nonce: nonceMap.next(pSender),
1290
- initCode: '0x', // 之前买入阶段已处理 initCode
1285
+ initCode: '0x',
1291
1286
  deployed: true,
1292
1287
  fixedGas: {
1293
1288
  ...(effConfig.fixedGas ?? {}),
@@ -1295,17 +1290,33 @@ export class BundleExecutor {
1295
1290
  }
1296
1291
  });
1297
1292
  const signedProfitOp = await this.aaManager.signUserOp(profitOp.userOp, pOwner);
1298
- ops.push(signedProfitOp.userOp);
1293
+ profitOps.push(signedProfitOp.userOp);
1299
1294
  }
1300
1295
  }
1301
1296
  // 3. 签名 handleOps 交易
1302
- const signedTx = await this.signHandleOpsTx({
1303
- ops,
1297
+ const provider = this.aaManager.getProvider();
1298
+ const startNonce = params.payerStartNonce ?? await provider.getTransactionCount(payer.address, 'pending');
1299
+ const signedTransactions = [];
1300
+ // 3a. 签名主交易
1301
+ const signedMainTx = await this.signHandleOpsTx({
1302
+ ops: mainOps,
1304
1303
  payerWallet: payer,
1305
- beneficiary: useBeneficiary
1304
+ beneficiary: useBeneficiary,
1305
+ nonce: startNonce
1306
1306
  });
1307
+ signedTransactions.push(signedMainTx);
1308
+ // 3b. 签名利润交易
1309
+ if (profitOps.length > 0) {
1310
+ const signedProfitTx = await this.signHandleOpsTx({
1311
+ ops: profitOps,
1312
+ payerWallet: payer,
1313
+ beneficiary: useBeneficiary,
1314
+ nonce: startNonce + 1
1315
+ });
1316
+ signedTransactions.push(signedProfitTx);
1317
+ }
1307
1318
  return {
1308
- signedTransactions: [signedTx],
1319
+ signedTransactions,
1309
1320
  tokenAddress,
1310
1321
  metadata: {
1311
1322
  tokenAddress,
@@ -1326,33 +1337,41 @@ export class BundleExecutor {
1326
1337
  payerPrivateKey: params.privateKeys[0]
1327
1338
  });
1328
1339
  const sharedProvider = this.aaManager.getProvider();
1329
- const tx = await sharedProvider.broadcastTransaction(signResult.signedTransactions[0]);
1330
- const receipt = await tx.wait();
1331
- const epIface = new Interface(ENTRYPOINT_ABI);
1340
+ let mainTxHash = '';
1341
+ let lastReceipt;
1332
1342
  const userOpEvents = [];
1333
- if (receipt) {
1334
- for (const log of receipt.logs) {
1335
- try {
1336
- const parsed = epIface.parseLog(log);
1337
- if (parsed?.name === 'UserOperationEvent') {
1338
- userOpEvents.push({
1339
- userOpHash: parsed.args.userOpHash,
1340
- sender: parsed.args.sender,
1341
- paymaster: parsed.args.paymaster,
1342
- success: parsed.args.success,
1343
- actualGasCost: parsed.args.actualGasCost,
1344
- actualGasUsed: parsed.args.actualGasUsed
1345
- });
1343
+ const epIface = new Interface(ENTRYPOINT_ABI);
1344
+ for (let i = 0; i < signResult.signedTransactions.length; i++) {
1345
+ const signedTx = signResult.signedTransactions[i];
1346
+ const tx = await sharedProvider.broadcastTransaction(signedTx);
1347
+ if (i === 0)
1348
+ mainTxHash = tx.hash;
1349
+ const receipt = await tx.wait();
1350
+ lastReceipt = receipt;
1351
+ if (receipt) {
1352
+ for (const log of receipt.logs) {
1353
+ try {
1354
+ const parsed = epIface.parseLog(log);
1355
+ if (parsed?.name === 'UserOperationEvent') {
1356
+ userOpEvents.push({
1357
+ userOpHash: parsed.args.userOpHash,
1358
+ sender: parsed.args.sender,
1359
+ paymaster: parsed.args.paymaster,
1360
+ success: parsed.args.success,
1361
+ actualGasCost: parsed.args.actualGasCost,
1362
+ actualGasUsed: parsed.args.actualGasUsed
1363
+ });
1364
+ }
1346
1365
  }
1366
+ catch { }
1347
1367
  }
1348
- catch { }
1349
1368
  }
1350
1369
  }
1351
1370
  return {
1352
1371
  createBuyResult: {
1353
- txHash: tx.hash,
1354
- blockNumber: receipt?.blockNumber ?? 0,
1355
- status: receipt?.status ?? 0,
1372
+ txHash: mainTxHash,
1373
+ blockNumber: lastReceipt?.blockNumber ?? 0,
1374
+ status: lastReceipt?.status ?? 0,
1356
1375
  userOpEvents
1357
1376
  },
1358
1377
  tokenAddress: signResult.tokenAddress
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.5.41",
3
+ "version": "1.5.42",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",