four-flap-meme-sdk 1.5.36 → 1.5.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/xlayer/bundle.js +75 -6
- package/package.json +1 -1
package/dist/xlayer/bundle.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - OKB 归集:将 sender 的 OKB 转回 owner
|
|
9
9
|
*/
|
|
10
10
|
import { Wallet, Interface, Contract, ethers } from 'ethers';
|
|
11
|
-
import { FLAP_PORTAL, ENTRYPOINT_ABI, DEFAULT_CALL_GAS_LIMIT_SELL, DEFAULT_WITHDRAW_RESERVE, } from './constants.js';
|
|
11
|
+
import { FLAP_PORTAL, ENTRYPOINT_ABI, PORTAL_ABI, DEFAULT_CALL_GAS_LIMIT_SELL, DEFAULT_WITHDRAW_RESERVE, } from './constants.js';
|
|
12
12
|
import { AAAccountManager, encodeExecute, encodeExecuteBatch } from './aa-account.js';
|
|
13
13
|
import { encodeBuyCall, encodeSellCall, encodeApproveCall, encodeTransferCall, encodeCreateCallV2, encodeCreateCallV3, encodeCreateCallV4, PortalQuery, parseOkb, formatOkb, } from './portal-ops.js';
|
|
14
14
|
import { mapWithConcurrency } from '../utils/concurrency.js';
|
|
@@ -1247,21 +1247,47 @@ export class BundleExecutor {
|
|
|
1247
1247
|
const signedDevOp = await this.aaManager.signUserOp(devCreateOp.userOp, devWallet);
|
|
1248
1248
|
ops.push(signedDevOp.userOp);
|
|
1249
1249
|
// 2b. Buyers 买入
|
|
1250
|
+
const profitSettings = resolveProfitSettings(effConfig);
|
|
1251
|
+
const inputToken = params.quoteToken && params.quoteToken !== ZERO_ADDRESS ? params.quoteToken : ZERO_ADDRESS;
|
|
1252
|
+
const useNativeToken = inputToken === ZERO_ADDRESS;
|
|
1253
|
+
// BundleCreateBuyParams 目前没有 quoteTokenDecimals,默认用 18
|
|
1254
|
+
const quoteDecimals = 18;
|
|
1250
1255
|
let totalBuyWei = 0n;
|
|
1256
|
+
let totalBuyProfitWei = 0n; // inputToken 本位利润
|
|
1251
1257
|
const buyerSenders = [];
|
|
1258
|
+
const profitWeis = [];
|
|
1259
|
+
const portalIface = new Interface(PORTAL_ABI);
|
|
1252
1260
|
for (let i = 0; i < buyerWallets.length; i++) {
|
|
1253
1261
|
const buyer = buyerWallets[i];
|
|
1254
|
-
const
|
|
1255
|
-
const
|
|
1256
|
-
|
|
1262
|
+
const amountStr = buyAmounts[i] || '0';
|
|
1263
|
+
const originalWei = useNativeToken ? parseOkb(amountStr) : ethers.parseUnits(amountStr, quoteDecimals);
|
|
1264
|
+
let buyWei = originalWei;
|
|
1265
|
+
let profitWei = 0n;
|
|
1266
|
+
if (profitSettings.extractProfit) {
|
|
1267
|
+
const res = calculateProfit(originalWei, profitSettings.profitBps);
|
|
1268
|
+
buyWei = res.remaining;
|
|
1269
|
+
profitWei = res.profit;
|
|
1270
|
+
}
|
|
1271
|
+
totalBuyWei += buyWei;
|
|
1272
|
+
totalBuyProfitWei += profitWei;
|
|
1273
|
+
profitWeis.push(profitWei);
|
|
1257
1274
|
const buyerAccount = await this.aaManager.getAccountInfo(buyer.address);
|
|
1258
1275
|
buyerSenders.push(buyerAccount.sender);
|
|
1259
1276
|
nonceMap.init(buyerAccount.sender, buyerAccount.nonce);
|
|
1260
|
-
|
|
1277
|
+
// 买入:使用扣除利润后的金额
|
|
1278
|
+
const swapData = portalIface.encodeFunctionData('swapExactInput', [
|
|
1279
|
+
{
|
|
1280
|
+
inputToken,
|
|
1281
|
+
outputToken: tokenAddress,
|
|
1282
|
+
inputAmount: buyWei,
|
|
1283
|
+
minOutputAmount: 0n,
|
|
1284
|
+
permitData: '0x',
|
|
1285
|
+
},
|
|
1286
|
+
]);
|
|
1261
1287
|
const buyOp = await this.aaManager.buildUserOpWithFixedGas({
|
|
1262
1288
|
ownerWallet: buyer,
|
|
1263
1289
|
sender: buyerAccount.sender,
|
|
1264
|
-
callData: encodeExecute(this.portalAddress,
|
|
1290
|
+
callData: encodeExecute(this.portalAddress, useNativeToken ? buyWei : 0n, swapData),
|
|
1265
1291
|
nonce: nonceMap.next(buyerAccount.sender),
|
|
1266
1292
|
initCode: buyerAccount.deployed ? '0x' : this.aaManager.generateInitCode(buyer.address),
|
|
1267
1293
|
deployed: buyerAccount.deployed
|
|
@@ -1269,6 +1295,49 @@ export class BundleExecutor {
|
|
|
1269
1295
|
const signedBuyOp = await this.aaManager.signUserOp(buyOp.userOp, buyer);
|
|
1270
1296
|
ops.push(signedBuyOp.userOp);
|
|
1271
1297
|
}
|
|
1298
|
+
// ✅ 刮取利润:折算并转账(SignOnly 模式也需要包含此 UserOp)
|
|
1299
|
+
if (profitSettings.extractProfit && totalBuyProfitWei > 0n) {
|
|
1300
|
+
// 1. 获取 OKB 报价(SignOnly 模式也需要这个报价来决定最终转账金额)
|
|
1301
|
+
let nativeProfitAmount = totalBuyProfitWei;
|
|
1302
|
+
if (!useNativeToken) {
|
|
1303
|
+
try {
|
|
1304
|
+
const dq = new DexQuery(effConfig);
|
|
1305
|
+
nativeProfitAmount = await dq.quoteTokenToOkb(totalBuyProfitWei, inputToken);
|
|
1306
|
+
}
|
|
1307
|
+
catch {
|
|
1308
|
+
try {
|
|
1309
|
+
const pq = this.portalQuery;
|
|
1310
|
+
nativeProfitAmount = await pq.quoteExactInput(inputToken, ZERO_ADDRESS, totalBuyProfitWei);
|
|
1311
|
+
}
|
|
1312
|
+
catch {
|
|
1313
|
+
nativeProfitAmount = 0n;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
if (nativeProfitAmount > 0n) {
|
|
1318
|
+
console.log(`[利润提取-签名] 总利润: ${useNativeToken ? formatOkb(nativeProfitAmount) : `${formatOkb(totalBuyProfitWei)} (ERC20) -> ${formatOkb(nativeProfitAmount)} (OKB)`} -> ${profitSettings.profitRecipient}`);
|
|
1319
|
+
// 找到利润贡献最大的买家作为利润转账的 sender
|
|
1320
|
+
const maxProfitIndex = profitWeis.reduce((maxIdx, p, idx) => p > (profitWeis[maxIdx] ?? 0n) ? idx : maxIdx, 0);
|
|
1321
|
+
const pOwner = buyerWallets[maxProfitIndex];
|
|
1322
|
+
const pSender = buyerSenders[maxProfitIndex];
|
|
1323
|
+
// 利润转账:直接转 OKB(对齐 bundleBuy 语义)
|
|
1324
|
+
const profitCallData = encodeExecute(profitSettings.profitRecipient, nativeProfitAmount, '0x');
|
|
1325
|
+
const profitOp = await this.aaManager.buildUserOpWithFixedGas({
|
|
1326
|
+
ownerWallet: pOwner,
|
|
1327
|
+
sender: pSender,
|
|
1328
|
+
callData: profitCallData,
|
|
1329
|
+
nonce: nonceMap.next(pSender),
|
|
1330
|
+
initCode: '0x', // 之前买入阶段已处理 initCode
|
|
1331
|
+
deployed: true,
|
|
1332
|
+
fixedGas: {
|
|
1333
|
+
...(effConfig.fixedGas ?? {}),
|
|
1334
|
+
callGasLimit: effConfig.fixedGas?.callGasLimit ?? DEFAULT_CALL_GAS_LIMIT_WITHDRAW,
|
|
1335
|
+
}
|
|
1336
|
+
});
|
|
1337
|
+
const signedProfitOp = await this.aaManager.signUserOp(profitOp.userOp, pOwner);
|
|
1338
|
+
ops.push(signedProfitOp.userOp);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1272
1341
|
// 3. 签名 handleOps 交易
|
|
1273
1342
|
const signedTx = await this.signHandleOpsTx({
|
|
1274
1343
|
ops,
|