four-flap-meme-sdk 1.3.95 → 1.3.99

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.
@@ -44,6 +44,8 @@ export interface DirectRouterSignConfig {
44
44
  skipApprovalCheck?: boolean;
45
45
  /** 滑点(基点),默认 100 = 1% */
46
46
  slippageBps?: number;
47
+ /** BlockRazor 贿赂金额(BNB),仅 BSC 链有效,用于提高 bundle 打包优先级 */
48
+ bribeAmount?: number;
47
49
  }
48
50
  export interface DirectV2BuyParams {
49
51
  chain: 'BSC' | 'MONAD' | 'XLAYER';
@@ -16,6 +16,8 @@ import { PROFIT_CONFIG } from '../utils/constants.js';
16
16
  const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
17
17
  const DEFAULT_GAS_LIMIT = 300000;
18
18
  const DEADLINE_MINUTES = 20;
19
+ // ✅ BlockRazor Builder EOA 地址(用于贿赂,仅 BSC 链)
20
+ const BLOCKRAZOR_BUILDER_EOA = '0x1266C6bE60392A8Ff346E8d5ECCd3E69dD9c5F20';
19
21
  // ✅ Router ABI(用于 ERC20 → 原生代币报价)
20
22
  const QUOTE_ROUTER_ABI = [
21
23
  'function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts)'
@@ -585,6 +587,33 @@ async function buildProfitTransaction(wallet, profitAmountWei, nonce, gasPrice,
585
587
  };
586
588
  return wallet.signTransaction(tx);
587
589
  }
590
+ /**
591
+ * 获取贿赂金额(wei)
592
+ * ✅ 仅 BSC 链支持贿赂
593
+ */
594
+ function getBribeAmount(config, chain) {
595
+ // 只有 BSC 链支持贿赂
596
+ if (chain.toUpperCase() !== 'BSC')
597
+ return 0n;
598
+ const bribeAmount = config.bribeAmount;
599
+ if (typeof bribeAmount !== 'number' || bribeAmount <= 0)
600
+ return 0n;
601
+ // 转换为 wei
602
+ return ethers.parseEther(String(bribeAmount));
603
+ }
604
+ /** 构建贿赂交易(向 BlockRazor Builder EOA 转账 BNB) */
605
+ async function buildBribeTransaction(wallet, bribeAmountWei, nonce, gasPrice, chainId, txType = 0) {
606
+ const tx = {
607
+ to: BLOCKRAZOR_BUILDER_EOA,
608
+ value: bribeAmountWei,
609
+ nonce,
610
+ gasLimit: 21000n,
611
+ gasPrice,
612
+ chainId,
613
+ type: txType,
614
+ };
615
+ return wallet.signTransaction(tx);
616
+ }
588
617
  // ============================================================================
589
618
  // V2 直接交易
590
619
  // ============================================================================
@@ -647,11 +676,12 @@ export async function directV2BatchBuy(params) {
647
676
  const wrappedNative = getWrappedNative(chain);
648
677
  // 创建钱包
649
678
  const wallets = privateKeys.map(pk => new Wallet(pk, provider));
650
- // 获取 nonce
651
679
  const nonceManager = new NonceManager(provider);
652
- const nonces = await nonceManager.getNextNoncesForWallets(wallets);
653
- // 获取 gas price
654
- const gasPrice = await getGasPrice(provider, config);
680
+ // 性能优化:并行获取 nonce 和 gasPrice(减少 2 轮串行 → 1 轮并行)
681
+ const [nonces, gasPrice] = await Promise.all([
682
+ nonceManager.getNextNoncesForWallets(wallets),
683
+ getGasPrice(provider, config)
684
+ ]);
655
685
  const gasLimit = getGasLimit(config, 250000);
656
686
  const txType = config.txType ?? 0;
657
687
  const deadline = getDeadline();
@@ -717,22 +747,34 @@ export async function directV2BatchBuy(params) {
717
747
  };
718
748
  }
719
749
  };
750
+ // ✅ 优化:选择金额最大的钱包支付贿赂和利润
751
+ const maxFlowIndex = findMaxFlowIndex(flowAmounts);
752
+ // ✅ 计算贿赂金额(仅 BSC 链)
753
+ const bribeWei = getBribeAmount(config, chain);
754
+ const hasBribe = bribeWei > 0n && wallets.length > 0;
755
+ // ✅ 计算 nonce 偏移:如果有贿赂交易,需要为金额最大的钱包预留 nonce
756
+ const nonceOffsets = wallets.map((_, i) => i === maxFlowIndex && hasBribe ? 1 : 0);
757
+ // ✅ 贿赂交易放在首位(提高 BlockRazor 打包优先级)
758
+ const bribeTxs = [];
759
+ if (hasBribe) {
760
+ const bribeTx = await buildBribeTransaction(wallets[maxFlowIndex], bribeWei, nonces[maxFlowIndex], // 使用原始 nonce
761
+ gasPrice, chainId, txType);
762
+ bribeTxs.push(bribeTx);
763
+ }
720
764
  // ✅ 优化:并行签名所有交易
721
- const signedTxs = await Promise.all(wallets.map(async (wallet, i) => {
765
+ const swapTxs = await Promise.all(wallets.map(async (wallet, i) => {
722
766
  const { txData, txValue } = buildTxData(wallet, flowAmounts[i]);
723
767
  return wallet.signTransaction({
724
768
  to: routerAddress,
725
769
  data: txData,
726
770
  value: txValue,
727
- nonce: nonces[i],
771
+ nonce: nonces[i] + nonceOffsets[i], // ✅ 考虑贿赂交易的 nonce 偏移
728
772
  gasLimit,
729
773
  gasPrice,
730
774
  chainId,
731
775
  type: txType,
732
776
  });
733
777
  }));
734
- // ✅ 优化:选择金额最大的钱包支付利润(和 core.ts 逻辑一致)
735
- const maxFlowIndex = findMaxFlowIndex(flowAmounts);
736
778
  let profitWei = calculateProfitAmount(totalFlowWei);
737
779
  // ✅ 修复:ERC20 交易时,将利润转换为原生代币
738
780
  if (!useNative && profitWei > 0n && quoteToken) {
@@ -744,11 +786,15 @@ export async function directV2BatchBuy(params) {
744
786
  profitWei = 0n; // 报价失败,跳过利润
745
787
  }
746
788
  }
789
+ // ✅ 利润交易
790
+ const profitTxs = [];
747
791
  if (profitWei > 0n) {
748
- const profitNonce = nonces[maxFlowIndex] + 1; // ✅ 使用金额最大的钱包
792
+ const profitNonce = nonces[maxFlowIndex] + nonceOffsets[maxFlowIndex] + 1; // ✅ 考虑贿赂交易的 nonce 偏移
749
793
  const profitTx = await buildProfitTransaction(wallets[maxFlowIndex], profitWei, profitNonce, gasPrice, chainId, txType);
750
- signedTxs.push(profitTx);
794
+ profitTxs.push(profitTx);
751
795
  }
796
+ // ✅ 组装最终交易列表:贿赂 → 交易 → 利润
797
+ const signedTxs = [...bribeTxs, ...swapTxs, ...profitTxs];
752
798
  return {
753
799
  signedTransactions: signedTxs,
754
800
  metadata: {
@@ -771,19 +817,26 @@ export async function directV2BatchSell(params) {
771
817
  const wallets = privateKeys.map(pk => new Wallet(pk, provider));
772
818
  // 获取代币合约
773
819
  const tokenContract = new Contract(tokenAddress, ERC20_ABI, provider);
774
- // 自动获取代币精度(如果未提供)
775
- let tokenDecimals = inputDecimals;
776
- if (tokenDecimals === undefined) {
777
- try {
778
- tokenDecimals = Number(await tokenContract.decimals());
779
- }
780
- catch {
781
- tokenDecimals = 18; // 默认 18
782
- }
783
- }
784
- // 获取代币余额
785
- const balances = await Promise.all(wallets.map(w => tokenContract.balanceOf(w.address)));
786
- // 计算卖出数量
820
+ const nonceManager = new NonceManager(provider);
821
+ // 性能优化:并行获取所有独立的 RPC 数据(减少串行 → 1 轮并行)
822
+ // 已移除授权检查(前端应确保已授权)
823
+ const [fetchedDecimals, balances, nonces, gasPrice] = await Promise.all([
824
+ // 1. 获取代币精度(如果未提供)
825
+ inputDecimals !== undefined
826
+ ? Promise.resolve(inputDecimals)
827
+ : tokenContract.decimals().then((d) => Number(d)).catch(() => 18),
828
+ // 2. 批量获取余额
829
+ Promise.all(wallets.map(w => tokenContract.balanceOf(w.address))),
830
+ // 3. 批量获取 nonce
831
+ nonceManager.getNextNoncesForWallets(wallets),
832
+ // 4. 获取 gas price
833
+ getGasPrice(provider, config)
834
+ ]);
835
+ const tokenDecimals = fetchedDecimals;
836
+ const gasLimit = getGasLimit(config, 300000);
837
+ const txType = config.txType ?? 0;
838
+ const deadline = getDeadline();
839
+ // 计算卖出数量(同步操作,无 RPC)
787
840
  const sellAmountsWei = [];
788
841
  for (let i = 0; i < wallets.length; i++) {
789
842
  if (sellAmounts && sellAmounts[i]) {
@@ -799,13 +852,6 @@ export async function directV2BatchSell(params) {
799
852
  sellAmountsWei.push(balances[i]); // 默认全部卖出
800
853
  }
801
854
  }
802
- // 获取 nonce(每个钱包可能需要 2 个:授权 + 卖出)
803
- const nonceManager = new NonceManager(provider);
804
- const nonces = await nonceManager.getNextNoncesForWallets(wallets);
805
- const gasPrice = await getGasPrice(provider, config);
806
- const gasLimit = getGasLimit(config, 300000);
807
- const txType = config.txType ?? 0;
808
- const deadline = getDeadline();
809
855
  // 构建路径
810
856
  const outputToken = useNativeOutput ? wrappedNative : quoteToken;
811
857
  const path = [tokenAddress, outputToken];
@@ -816,7 +862,6 @@ export async function directV2BatchSell(params) {
816
862
  const routerIface = useSwapRouter02
817
863
  ? new ethers.Interface(SWAP_ROUTER02_V2_ABI)
818
864
  : new ethers.Interface(V2_ROUTER_ABI);
819
- const approveIface = new ethers.Interface(ERC20_ABI);
820
865
  // ✅ 优化:构建卖出交易数据的辅助函数(同步)
821
866
  const buildSellTxData = (wallet, sellAmount) => {
822
867
  if (useDYORSwap) {
@@ -850,80 +895,38 @@ export async function directV2BatchSell(params) {
850
895
  return routerIface.encodeFunctionData('swapExactTokensForTokensSupportingFeeOnTransferTokens', [sellAmount, 0n, path, wallet.address, deadline]);
851
896
  }
852
897
  };
853
- // ✅ 优化:并行检查所有授权
854
- let allowances = [];
855
- if (!config.skipApprovalCheck) {
856
- allowances = await Promise.all(wallets.map(w => tokenContract.allowance(w.address, routerAddress)));
898
+ // ✅ 性能优化:直接用 sellAmountsWei 找最大输出钱包(跳过 N 次 getAmountsOut RPC 调用)
899
+ // 因为卖出金额越大,输出也越大(假设线性关系),无需额外报价
900
+ const maxOutputIndex = findMaxFlowIndex(sellAmountsWei);
901
+ // 计算贿赂金额(仅 BSC 链)
902
+ const bribeWei = getBribeAmount(config, chain);
903
+ const hasBribe = bribeWei > 0n && wallets.length > 0;
904
+ // ✅ 计算 nonce 偏移(仅贿赂,已移除授权)
905
+ const nonceOffsets = wallets.map((_, i) => i === maxOutputIndex && hasBribe ? 1 : 0);
906
+ // ✅ 贿赂交易放在首位(提高 BlockRazor 打包优先级)
907
+ const bribeTxs = [];
908
+ if (hasBribe) {
909
+ const bribeTx = await buildBribeTransaction(wallets[maxOutputIndex], bribeWei, nonces[maxOutputIndex], // 使用原始 nonce
910
+ gasPrice, chainId, txType);
911
+ bribeTxs.push(bribeTx);
857
912
  }
858
- // ✅ 优化:计算每个钱包的 nonce 偏移(是否需要授权)
859
- const currentNonceOffset = wallets.map((_, i) => {
860
- if (config.skipApprovalCheck)
861
- return 0;
862
- return allowances[i] < sellAmountsWei[i] ? 1 : 0;
863
- });
864
- // ✅ 优化:并行签名所有授权交易
865
- const approvalTxPromises = wallets.map(async (wallet, i) => {
866
- if (config.skipApprovalCheck || sellAmountsWei[i] <= 0n)
867
- return null;
868
- if (allowances[i] >= sellAmountsWei[i])
869
- return null;
870
- return wallet.signTransaction({
871
- to: tokenAddress,
872
- data: approveIface.encodeFunctionData('approve', [routerAddress, ethers.MaxUint256]),
873
- value: 0n,
874
- nonce: nonces[i],
875
- gasLimit: 60000n,
876
- gasPrice,
877
- chainId,
878
- type: txType,
879
- });
880
- });
881
- const approvalTxResults = await Promise.all(approvalTxPromises);
882
- // ✅ 优化:并行签名所有卖出交易
883
- const sellTxPromises = wallets.map(async (wallet, i) => {
913
+ // ✅ 优化:并行签名所有卖出交易(已移除授权交易)
914
+ const swapTxs = await Promise.all(wallets.map(async (wallet, i) => {
884
915
  if (sellAmountsWei[i] <= 0n)
885
916
  return null;
886
917
  return wallet.signTransaction({
887
918
  to: routerAddress,
888
919
  data: buildSellTxData(wallet, sellAmountsWei[i]),
889
920
  value: 0n,
890
- nonce: nonces[i] + currentNonceOffset[i],
921
+ nonce: nonces[i] + nonceOffsets[i],
891
922
  gasLimit,
892
923
  gasPrice,
893
924
  chainId,
894
925
  type: txType,
895
926
  });
896
- });
897
- const sellTxResults = await Promise.all(sellTxPromises);
898
- // 优化:并行获取所有报价
899
- const router = new Contract(routerAddress, V2_ROUTER_ABI, provider);
900
- const quotePromises = wallets.map(async (_, i) => {
901
- if (sellAmountsWei[i] <= 0n)
902
- return sellAmountsWei[i];
903
- try {
904
- const amounts = await router.getAmountsOut(sellAmountsWei[i], path);
905
- return amounts[amounts.length - 1];
906
- }
907
- catch {
908
- return sellAmountsWei[i];
909
- }
910
- });
911
- const outputEstimates = await Promise.all(quotePromises);
912
- // ✅ 按顺序组装签名交易:先授权,后卖出
913
- const signedTxs = [];
914
- for (let i = 0; i < wallets.length; i++) {
915
- const approvalTx = approvalTxResults[i];
916
- const sellTx = sellTxResults[i];
917
- if (approvalTx)
918
- signedTxs.push(approvalTx);
919
- if (sellTx) {
920
- signedTxs.push(sellTx);
921
- currentNonceOffset[i]++; // 更新 offset 供利润交易使用
922
- }
923
- }
924
- const totalOutputEstimate = outputEstimates.reduce((sum, o) => sum + o, 0n);
925
- // ✅ 优化:选择输出最大的钱包支付利润(和 core.ts 逻辑一致)
926
- const maxOutputIndex = findMaxFlowIndex(outputEstimates);
927
+ })).then(results => results.filter((tx) => tx !== null));
928
+ // 使用 sellAmountsWei 作为输出估计(因为已跳过 getAmountsOut 调用)
929
+ const totalOutputEstimate = sellAmountsWei.reduce((sum, o) => sum + o, 0n);
927
930
  let profitWei = calculateProfitAmount(totalOutputEstimate);
928
931
  // ✅ 修复:ERC20 输出时,将利润转换为原生代币
929
932
  if (!useNativeOutput && profitWei > 0n && quoteToken) {
@@ -935,11 +938,17 @@ export async function directV2BatchSell(params) {
935
938
  profitWei = 0n;
936
939
  }
937
940
  }
941
+ // ✅ 利润交易
942
+ const profitTxs = [];
938
943
  if (profitWei > 0n && wallets.length > 0) {
944
+ // 利润交易 nonce = 原始 nonce + 贿赂偏移 + 1(卖出交易)
945
+ const profitNonce = nonces[maxOutputIndex] + nonceOffsets[maxOutputIndex] + 1;
939
946
  const profitTx = await buildProfitTransaction(wallets[maxOutputIndex], // ✅ 使用输出最大的钱包
940
- profitWei, nonces[maxOutputIndex] + currentNonceOffset[maxOutputIndex], gasPrice, chainId, txType);
941
- signedTxs.push(profitTx);
947
+ profitWei, profitNonce, gasPrice, chainId, txType);
948
+ profitTxs.push(profitTx);
942
949
  }
950
+ // ✅ 组装最终交易列表:贿赂 → 卖出 → 利润
951
+ const signedTxs = [...bribeTxs, ...swapTxs, ...profitTxs];
943
952
  return {
944
953
  signedTransactions: signedTxs,
945
954
  metadata: {
@@ -973,8 +982,11 @@ export async function directV3BatchBuy(params) {
973
982
  const routerAbi = useLegacyRouter ? V3_ROUTER_LEGACY_ABI : V3_ROUTER02_ABI;
974
983
  const wallets = privateKeys.map(pk => new Wallet(pk, provider));
975
984
  const nonceManager = new NonceManager(provider);
976
- const nonces = await nonceManager.getNextNoncesForWallets(wallets);
977
- const gasPrice = await getGasPrice(provider, config);
985
+ // 性能优化:并行获取 nonce 和 gasPrice
986
+ const [nonces, gasPrice] = await Promise.all([
987
+ nonceManager.getNextNoncesForWallets(wallets),
988
+ getGasPrice(provider, config)
989
+ ]);
978
990
  const gasLimit = getGasLimit(config, 300000);
979
991
  const txType = config.txType ?? 0;
980
992
  const routerIface = new ethers.Interface(routerAbi);
@@ -1031,22 +1043,33 @@ export async function directV3BatchBuy(params) {
1031
1043
  }
1032
1044
  }
1033
1045
  };
1046
+ // ✅ 优化:选择金额最大的钱包支付贿赂和利润
1047
+ const maxFlowIndex = findMaxFlowIndex(flowAmounts);
1048
+ // ✅ 计算贿赂金额(仅 BSC 链)
1049
+ const bribeWei = getBribeAmount(config, chain);
1050
+ const hasBribe = bribeWei > 0n && wallets.length > 0;
1051
+ // ✅ 计算 nonce 偏移
1052
+ const nonceOffsets = wallets.map((_, i) => i === maxFlowIndex && hasBribe ? 1 : 0);
1053
+ // ✅ 贿赂交易放在首位(提高 BlockRazor 打包优先级)
1054
+ const bribeTxs = [];
1055
+ if (hasBribe) {
1056
+ const bribeTx = await buildBribeTransaction(wallets[maxFlowIndex], bribeWei, nonces[maxFlowIndex], gasPrice, chainId, txType);
1057
+ bribeTxs.push(bribeTx);
1058
+ }
1034
1059
  // ✅ 优化:并行签名所有交易
1035
- const signedTxs = await Promise.all(wallets.map(async (wallet, i) => {
1060
+ const swapTxs = await Promise.all(wallets.map(async (wallet, i) => {
1036
1061
  const { txData, txValue } = buildV3BuyTxData(wallet, flowAmounts[i]);
1037
1062
  return wallet.signTransaction({
1038
1063
  to: routerAddress,
1039
1064
  data: txData,
1040
1065
  value: txValue,
1041
- nonce: nonces[i],
1066
+ nonce: nonces[i] + nonceOffsets[i],
1042
1067
  gasLimit,
1043
1068
  gasPrice,
1044
1069
  chainId,
1045
1070
  type: txType,
1046
1071
  });
1047
1072
  }));
1048
- // ✅ 优化:选择金额最大的钱包支付利润
1049
- const maxFlowIndex = findMaxFlowIndex(flowAmounts);
1050
1073
  let profitWei = calculateProfitAmount(totalFlowWei);
1051
1074
  // ✅ 修复:ERC20 交易时,将利润转换为原生代币
1052
1075
  if (!useNative && profitWei > 0n && quoteToken) {
@@ -1058,11 +1081,14 @@ export async function directV3BatchBuy(params) {
1058
1081
  profitWei = 0n;
1059
1082
  }
1060
1083
  }
1084
+ // ✅ 利润交易
1085
+ const profitTxs = [];
1061
1086
  if (profitWei > 0n) {
1062
- const profitTx = await buildProfitTransaction(wallets[maxFlowIndex], // 使用金额最大的钱包
1063
- profitWei, nonces[maxFlowIndex] + 1, gasPrice, chainId, txType);
1064
- signedTxs.push(profitTx);
1087
+ const profitTx = await buildProfitTransaction(wallets[maxFlowIndex], profitWei, nonces[maxFlowIndex] + nonceOffsets[maxFlowIndex] + 1, gasPrice, chainId, txType);
1088
+ profitTxs.push(profitTx);
1065
1089
  }
1090
+ // ✅ 组装最终交易列表:贿赂 → 交易 → 利润
1091
+ const signedTxs = [...bribeTxs, ...swapTxs, ...profitTxs];
1066
1092
  return {
1067
1093
  signedTransactions: signedTxs,
1068
1094
  metadata: {
@@ -1090,9 +1116,20 @@ export async function directV3BatchSell(params) {
1090
1116
  const routerAbi = useLegacyRouter ? V3_ROUTER_LEGACY_ABI : V3_ROUTER02_ABI;
1091
1117
  const wallets = privateKeys.map(pk => new Wallet(pk, provider));
1092
1118
  const tokenContract = new Contract(tokenAddress, ERC20_ABI, provider);
1093
- // 获取余额
1094
- const balances = await Promise.all(wallets.map(w => tokenContract.balanceOf(w.address)));
1095
- // 计算卖出数量
1119
+ const nonceManager = new NonceManager(provider);
1120
+ // 性能优化:并行获取所有独立的 RPC 数据
1121
+ // ✅ 已移除授权检查(前端应确保已授权)
1122
+ const [balances, nonces, gasPrice] = await Promise.all([
1123
+ // 1. 批量获取余额
1124
+ Promise.all(wallets.map(w => tokenContract.balanceOf(w.address))),
1125
+ // 2. 批量获取 nonce
1126
+ nonceManager.getNextNoncesForWallets(wallets),
1127
+ // 3. 获取 gas price
1128
+ getGasPrice(provider, config)
1129
+ ]);
1130
+ const gasLimit = getGasLimit(config, 350000);
1131
+ const txType = config.txType ?? 0;
1132
+ // 计算卖出数量(同步操作,无 RPC)
1096
1133
  const sellAmountsWei = [];
1097
1134
  for (let i = 0; i < wallets.length; i++) {
1098
1135
  if (sellAmounts && sellAmounts[i]) {
@@ -1106,13 +1143,7 @@ export async function directV3BatchSell(params) {
1106
1143
  sellAmountsWei.push(balances[i]);
1107
1144
  }
1108
1145
  }
1109
- const nonceManager = new NonceManager(provider);
1110
- const nonces = await nonceManager.getNextNoncesForWallets(wallets);
1111
- const gasPrice = await getGasPrice(provider, config);
1112
- const gasLimit = getGasLimit(config, 350000);
1113
- const txType = config.txType ?? 0;
1114
1146
  const routerIface = new ethers.Interface(routerAbi);
1115
- const approveIface = new ethers.Interface(ERC20_ABI);
1116
1147
  const outputToken = useNativeOutput ? wrappedNative : quoteToken;
1117
1148
  const deadline = getDeadline();
1118
1149
  // ✅ 优化:构建卖出交易数据的辅助函数
@@ -1157,71 +1188,38 @@ export async function directV3BatchSell(params) {
1157
1188
  }
1158
1189
  }
1159
1190
  };
1160
- // ✅ 优化:并行检查所有授权
1161
- let allowances = [];
1162
- if (!config.skipApprovalCheck) {
1163
- allowances = await Promise.all(wallets.map(w => tokenContract.allowance(w.address, routerAddress)));
1191
+ // ✅ 先找出输出最大的钱包索引(用于支付贿赂和利润)
1192
+ // 对于 V3 卖出,使用卖出金额作为输出估计
1193
+ const maxOutputIndex = findMaxFlowIndex(sellAmountsWei);
1194
+ // 计算贿赂金额(仅 BSC 链)
1195
+ const bribeWei = getBribeAmount(config, chain);
1196
+ const hasBribe = bribeWei > 0n && wallets.length > 0;
1197
+ // ✅ 计算 nonce 偏移(仅贿赂,已移除授权)
1198
+ const nonceOffsets = wallets.map((_, i) => i === maxOutputIndex && hasBribe ? 1 : 0);
1199
+ // ✅ 贿赂交易放在首位(提高 BlockRazor 打包优先级)
1200
+ const bribeTxs = [];
1201
+ if (hasBribe) {
1202
+ const bribeTx = await buildBribeTransaction(wallets[maxOutputIndex], bribeWei, nonces[maxOutputIndex], // 使用原始 nonce
1203
+ gasPrice, chainId, txType);
1204
+ bribeTxs.push(bribeTx);
1164
1205
  }
1165
- // ✅ 优化:计算每个钱包的 nonce 偏移
1166
- const currentNonceOffset = wallets.map((_, i) => {
1167
- if (config.skipApprovalCheck || sellAmountsWei[i] <= 0n)
1168
- return 0;
1169
- return allowances[i] < sellAmountsWei[i] ? 1 : 0;
1170
- });
1171
- // ✅ 优化:并行签名所有授权交易
1172
- const approvalTxPromises = wallets.map(async (wallet, i) => {
1173
- if (config.skipApprovalCheck || sellAmountsWei[i] <= 0n)
1174
- return null;
1175
- if (allowances[i] >= sellAmountsWei[i])
1176
- return null;
1177
- return wallet.signTransaction({
1178
- to: tokenAddress,
1179
- data: approveIface.encodeFunctionData('approve', [routerAddress, ethers.MaxUint256]),
1180
- value: 0n,
1181
- nonce: nonces[i],
1182
- gasLimit: 60000n,
1183
- gasPrice,
1184
- chainId,
1185
- type: txType,
1186
- });
1187
- });
1188
- const approvalTxResults = await Promise.all(approvalTxPromises);
1189
- // ✅ 优化:并行签名所有卖出交易
1190
- const sellTxPromises = wallets.map(async (wallet, i) => {
1206
+ // ✅ 优化:并行签名所有卖出交易(已移除授权交易)
1207
+ const swapTxs = await Promise.all(wallets.map(async (wallet, i) => {
1191
1208
  if (sellAmountsWei[i] <= 0n)
1192
1209
  return null;
1193
1210
  return wallet.signTransaction({
1194
1211
  to: routerAddress,
1195
1212
  data: buildV3SellTxData(wallet, sellAmountsWei[i]),
1196
1213
  value: 0n,
1197
- nonce: nonces[i] + currentNonceOffset[i],
1214
+ nonce: nonces[i] + nonceOffsets[i],
1198
1215
  gasLimit,
1199
1216
  gasPrice,
1200
1217
  chainId,
1201
1218
  type: txType,
1202
1219
  });
1203
- });
1204
- const sellTxResults = await Promise.all(sellTxPromises);
1205
- // 按顺序组装签名交易:先授权,后卖出
1206
- const signedTxs = [];
1207
- const outputEstimates = [];
1208
- for (let i = 0; i < wallets.length; i++) {
1209
- const approvalTx = approvalTxResults[i];
1210
- const sellTx = sellTxResults[i];
1211
- if (approvalTx)
1212
- signedTxs.push(approvalTx);
1213
- if (sellTx) {
1214
- signedTxs.push(sellTx);
1215
- outputEstimates.push(sellAmountsWei[i]);
1216
- currentNonceOffset[i]++;
1217
- }
1218
- else {
1219
- outputEstimates.push(0n);
1220
- }
1221
- }
1222
- const totalOutputEstimate = outputEstimates.reduce((sum, o) => sum + o, 0n);
1223
- // ✅ 优化:选择输出最大的钱包支付利润
1224
- const maxOutputIndex = findMaxFlowIndex(outputEstimates);
1220
+ })).then(results => results.filter((tx) => tx !== null));
1221
+ // 使用 sellAmountsWei 计算总输出
1222
+ const totalOutputEstimate = sellAmountsWei.reduce((sum, o) => sum + o, 0n);
1225
1223
  let profitWei = calculateProfitAmount(totalOutputEstimate);
1226
1224
  // ✅ 修复:ERC20 输出时,将利润转换为原生代币
1227
1225
  if (!useNativeOutput && profitWei > 0n && quoteToken) {
@@ -1233,11 +1231,17 @@ export async function directV3BatchSell(params) {
1233
1231
  profitWei = 0n;
1234
1232
  }
1235
1233
  }
1234
+ // ✅ 利润交易
1235
+ const profitTxs = [];
1236
1236
  if (profitWei > 0n && wallets.length > 0) {
1237
+ // 利润交易 nonce = 原始 nonce + 贿赂偏移 + 1(卖出交易)
1238
+ const profitNonce = nonces[maxOutputIndex] + nonceOffsets[maxOutputIndex] + 1;
1237
1239
  const profitTx = await buildProfitTransaction(wallets[maxOutputIndex], // ✅ 使用输出最大的钱包
1238
- profitWei, nonces[maxOutputIndex] + currentNonceOffset[maxOutputIndex], gasPrice, chainId, txType);
1239
- signedTxs.push(profitTx);
1240
+ profitWei, profitNonce, gasPrice, chainId, txType);
1241
+ profitTxs.push(profitTx);
1240
1242
  }
1243
+ // ✅ 组装最终交易列表:贿赂 → 卖出 → 利润
1244
+ const signedTxs = [...bribeTxs, ...swapTxs, ...profitTxs];
1241
1245
  return {
1242
1246
  signedTransactions: signedTxs,
1243
1247
  metadata: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.3.95",
3
+ "version": "1.3.99",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",