four-flap-meme-sdk 1.5.75 → 1.5.77
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 +51 -22
- package/dist/xlayer/types.d.ts +6 -0
- package/package.json +1 -1
package/dist/xlayer/bundle.js
CHANGED
|
@@ -1536,16 +1536,19 @@ export class BundleExecutor {
|
|
|
1536
1536
|
* 自动计算剩余毕业容量,将钱包分为内盘和外盘组,生成签名的交易列表
|
|
1537
1537
|
*/
|
|
1538
1538
|
async bundleGraduateBuy(params) {
|
|
1539
|
-
const { tokenAddress, privateKeys, payerPrivateKey, amountMode, totalBuyAmount, minAmount, maxAmount, walletAmounts, enableDexBuy = false,
|
|
1539
|
+
const { tokenAddress, privateKeys, payerPrivateKey, amountMode, totalBuyAmount, minAmount, maxAmount, walletAmounts, enableDexBuy = false,
|
|
1540
|
+
// ✅ 新增:前端传递的分组信息
|
|
1541
|
+
curveAddresses, dexAddresses, graduationAmount, config = {} } = params;
|
|
1540
1542
|
const aaManager = this.getAAManager();
|
|
1541
1543
|
const provider = aaManager.getProvider();
|
|
1542
1544
|
// 1. 获取代币状态,计算剩余毕业容量
|
|
1543
1545
|
const tokenState = await this.portalQuery.getTokenV5(tokenAddress);
|
|
1544
1546
|
const poolReserveOkb = ethers.formatEther(tokenState.reserve);
|
|
1545
|
-
|
|
1547
|
+
// ✅ 优先使用前端传递的动态毕业阈值
|
|
1548
|
+
const graduateCapacity = graduationAmount ?? 73.38;
|
|
1546
1549
|
const remainingToGraduate = Math.max(0, graduateCapacity - parseFloat(poolReserveOkb));
|
|
1547
1550
|
const remainingToGraduateWei = ethers.parseEther(remainingToGraduate.toFixed(18));
|
|
1548
|
-
console.log(`[GraduateBuy] Pool Reserve: ${poolReserveOkb} OKB, Remaining: ${remainingToGraduate} OKB`);
|
|
1551
|
+
console.log(`[GraduateBuy] Pool Reserve: ${poolReserveOkb} OKB, GraduateCapacity: ${graduateCapacity} OKB, Remaining: ${remainingToGraduate} OKB`);
|
|
1549
1552
|
// 2. 准备钱包
|
|
1550
1553
|
const sharedProvider = this.aaManager.getProvider();
|
|
1551
1554
|
const wallets = privateKeys.map(pk => new Wallet(pk, sharedProvider));
|
|
@@ -1573,27 +1576,53 @@ export class BundleExecutor {
|
|
|
1573
1576
|
// 4. 钱包分组
|
|
1574
1577
|
const curveBuyers = [];
|
|
1575
1578
|
const dexBuyers = [];
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1579
|
+
// ✅ 优先使用前端传递的分组信息
|
|
1580
|
+
const hasFrontendGrouping = curveAddresses && curveAddresses.length > 0;
|
|
1581
|
+
if (hasFrontendGrouping) {
|
|
1582
|
+
// ✅ 使用前端计算好的分组,不再重新计算
|
|
1583
|
+
const curveSet = new Set(curveAddresses.map(a => a.toLowerCase()));
|
|
1584
|
+
const dexSet = dexAddresses ? new Set(dexAddresses.map(a => a.toLowerCase())) : new Set();
|
|
1585
|
+
console.log(`[GraduateBuy] Using frontend grouping: ${curveAddresses.length} curve, ${dexAddresses?.length || 0} dex`);
|
|
1586
|
+
for (let i = 0; i < wallets.length; i++) {
|
|
1587
|
+
const wallet = wallets[i];
|
|
1588
|
+
const addr = wallet.address.toLowerCase();
|
|
1589
|
+
const amountWei = ethers.parseEther(finalAmounts[i].toFixed(18));
|
|
1590
|
+
if (curveSet.has(addr)) {
|
|
1583
1591
|
curveBuyers.push({ wallet, amount: amountWei });
|
|
1584
|
-
currentCurveTotal += amountWei;
|
|
1585
1592
|
}
|
|
1586
|
-
else {
|
|
1587
|
-
|
|
1588
|
-
curveBuyers.push({ wallet, amount: needed });
|
|
1589
|
-
currentCurveTotal = remainingToGraduateWei;
|
|
1590
|
-
// 超出部分暂不处理(遵循单钱包单属性逻辑)
|
|
1593
|
+
else if (dexSet.has(addr) && enableDexBuy) {
|
|
1594
|
+
dexBuyers.push({ wallet, amount: amountWei });
|
|
1591
1595
|
}
|
|
1596
|
+
// 如果钱包既不在 curveSet 也不在 dexSet,则跳过
|
|
1592
1597
|
}
|
|
1593
|
-
|
|
1594
|
-
|
|
1598
|
+
}
|
|
1599
|
+
else {
|
|
1600
|
+
// ✅ 原逻辑:SDK 自动分组(可能与前端不一致)
|
|
1601
|
+
console.log(`[GraduateBuy] No frontend grouping, using auto-split by remainingToGraduate=${remainingToGraduate} OKB`);
|
|
1602
|
+
let currentCurveTotal = 0n;
|
|
1603
|
+
for (let i = 0; i < wallets.length; i++) {
|
|
1604
|
+
const wallet = wallets[i];
|
|
1605
|
+
const amountWei = ethers.parseEther(finalAmounts[i].toFixed(18));
|
|
1606
|
+
if (currentCurveTotal < remainingToGraduateWei) {
|
|
1607
|
+
const needed = remainingToGraduateWei - currentCurveTotal;
|
|
1608
|
+
if (amountWei <= needed) {
|
|
1609
|
+
curveBuyers.push({ wallet, amount: amountWei });
|
|
1610
|
+
currentCurveTotal += amountWei;
|
|
1611
|
+
}
|
|
1612
|
+
else {
|
|
1613
|
+
// 当前钱包金额超过了剩余容量,将其限制为 needed
|
|
1614
|
+
curveBuyers.push({ wallet, amount: needed });
|
|
1615
|
+
currentCurveTotal = remainingToGraduateWei;
|
|
1616
|
+
// 超出部分暂不处理(遵循单钱包单属性逻辑)
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
else if (enableDexBuy) {
|
|
1620
|
+
dexBuyers.push({ wallet, amount: amountWei });
|
|
1621
|
+
}
|
|
1595
1622
|
}
|
|
1596
1623
|
}
|
|
1624
|
+
// ✅ 统一计算内盘买入总金额(无论使用哪种分组方式)
|
|
1625
|
+
const curveTotalWei = curveBuyers.reduce((sum, b) => sum + b.amount, 0n);
|
|
1597
1626
|
// 5. 构建 UserOps
|
|
1598
1627
|
const effConfig = { ...(this.config ?? {}), ...(config ?? {}) };
|
|
1599
1628
|
const signedTransactions = [];
|
|
@@ -1612,7 +1641,7 @@ export class BundleExecutor {
|
|
|
1612
1641
|
// ✅ 判断是否是最后一笔内盘买入(触发毕业的那笔)
|
|
1613
1642
|
const isGraduationTrigger = (i === curveBuyers.length - 1);
|
|
1614
1643
|
const callGasLimit = isGraduationTrigger
|
|
1615
|
-
?
|
|
1644
|
+
? 8000000n // 毕业触发交易需要更高 gas
|
|
1616
1645
|
: (effConfig.fixedGas?.callGasLimit ?? 800000n); // 其他买入使用前端配置或默认值
|
|
1617
1646
|
const buyOpRes = await aaManager.buildUserOpWithFixedGas({
|
|
1618
1647
|
ownerWallet: wallet,
|
|
@@ -1652,7 +1681,7 @@ export class BundleExecutor {
|
|
|
1652
1681
|
nonce: nonceMap.next(info.sender),
|
|
1653
1682
|
initCode: info.deployed ? '0x' : (await aaManager.generateInitCode(wallet.address)),
|
|
1654
1683
|
deployed: info.deployed,
|
|
1655
|
-
fixedGas: { callGasLimit: effConfig.fixedGas?.callGasLimit ??
|
|
1684
|
+
fixedGas: { callGasLimit: effConfig.fixedGas?.callGasLimit ?? 600000n } // ✅ 提高到 800K
|
|
1656
1685
|
});
|
|
1657
1686
|
const signedDexBuyOp = await aaManager.signUserOp(dexBuyOpRes.userOp, wallet);
|
|
1658
1687
|
return signedDexBuyOp.userOp;
|
|
@@ -1671,7 +1700,7 @@ export class BundleExecutor {
|
|
|
1671
1700
|
});
|
|
1672
1701
|
signedTransactions.push(signedMainTx);
|
|
1673
1702
|
// 7. 计算并签利润提取交易 (EOA 转账,千分之 4)
|
|
1674
|
-
const totalBuyWei =
|
|
1703
|
+
const totalBuyWei = curveTotalWei + totalDexBuyWei;
|
|
1675
1704
|
const profitWei = (totalBuyWei * 4n) / 1000n; // 0.4%
|
|
1676
1705
|
if (profitWei > 0n) {
|
|
1677
1706
|
const profitRecipient = effConfig.profitRecipient || PROFIT_CONFIG.RECIPIENT;
|
|
@@ -1693,7 +1722,7 @@ export class BundleExecutor {
|
|
|
1693
1722
|
metadata: {
|
|
1694
1723
|
curveCount: curveBuyers.length,
|
|
1695
1724
|
dexCount: dexBuyers.length,
|
|
1696
|
-
curveTotalAmount: ethers.formatEther(
|
|
1725
|
+
curveTotalAmount: ethers.formatEther(curveTotalWei),
|
|
1697
1726
|
dexTotalAmount: ethers.formatEther(totalDexBuyWei),
|
|
1698
1727
|
tokenAddress
|
|
1699
1728
|
}
|
package/dist/xlayer/types.d.ts
CHANGED
|
@@ -856,6 +856,12 @@ export interface BundleGraduateBuyParams {
|
|
|
856
856
|
walletAmounts?: Record<string, number>;
|
|
857
857
|
/** 是否启用外盘买入(默认 false) */
|
|
858
858
|
enableDexBuy?: boolean;
|
|
859
|
+
/** 内盘钱包地址列表(可选,传入则使用前端分组,不传则 SDK 自动分组) */
|
|
860
|
+
curveAddresses?: string[];
|
|
861
|
+
/** 外盘钱包地址列表(可选) */
|
|
862
|
+
dexAddresses?: string[];
|
|
863
|
+
/** 动态毕业阈值(可选,不传则使用默认 73.38 OKB) */
|
|
864
|
+
graduationAmount?: number;
|
|
859
865
|
/** 配置覆盖 */
|
|
860
866
|
config?: Partial<XLayerConfig>;
|
|
861
867
|
/** Payer 起始 nonce */
|