four-flap-meme-sdk 1.3.95 → 1.3.98
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/dex/direct-router.d.ts +2 -0
- package/dist/dex/direct-router.js +150 -49
- package/package.json +1 -1
|
@@ -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
|
// ============================================================================
|
|
@@ -717,22 +746,34 @@ export async function directV2BatchBuy(params) {
|
|
|
717
746
|
};
|
|
718
747
|
}
|
|
719
748
|
};
|
|
749
|
+
// ✅ 优化:选择金额最大的钱包支付贿赂和利润
|
|
750
|
+
const maxFlowIndex = findMaxFlowIndex(flowAmounts);
|
|
751
|
+
// ✅ 计算贿赂金额(仅 BSC 链)
|
|
752
|
+
const bribeWei = getBribeAmount(config, chain);
|
|
753
|
+
const hasBribe = bribeWei > 0n && wallets.length > 0;
|
|
754
|
+
// ✅ 计算 nonce 偏移:如果有贿赂交易,需要为金额最大的钱包预留 nonce
|
|
755
|
+
const nonceOffsets = wallets.map((_, i) => i === maxFlowIndex && hasBribe ? 1 : 0);
|
|
756
|
+
// ✅ 贿赂交易放在首位(提高 BlockRazor 打包优先级)
|
|
757
|
+
const bribeTxs = [];
|
|
758
|
+
if (hasBribe) {
|
|
759
|
+
const bribeTx = await buildBribeTransaction(wallets[maxFlowIndex], bribeWei, nonces[maxFlowIndex], // 使用原始 nonce
|
|
760
|
+
gasPrice, chainId, txType);
|
|
761
|
+
bribeTxs.push(bribeTx);
|
|
762
|
+
}
|
|
720
763
|
// ✅ 优化:并行签名所有交易
|
|
721
|
-
const
|
|
764
|
+
const swapTxs = await Promise.all(wallets.map(async (wallet, i) => {
|
|
722
765
|
const { txData, txValue } = buildTxData(wallet, flowAmounts[i]);
|
|
723
766
|
return wallet.signTransaction({
|
|
724
767
|
to: routerAddress,
|
|
725
768
|
data: txData,
|
|
726
769
|
value: txValue,
|
|
727
|
-
nonce: nonces[i],
|
|
770
|
+
nonce: nonces[i] + nonceOffsets[i], // ✅ 考虑贿赂交易的 nonce 偏移
|
|
728
771
|
gasLimit,
|
|
729
772
|
gasPrice,
|
|
730
773
|
chainId,
|
|
731
774
|
type: txType,
|
|
732
775
|
});
|
|
733
776
|
}));
|
|
734
|
-
// ✅ 优化:选择金额最大的钱包支付利润(和 core.ts 逻辑一致)
|
|
735
|
-
const maxFlowIndex = findMaxFlowIndex(flowAmounts);
|
|
736
777
|
let profitWei = calculateProfitAmount(totalFlowWei);
|
|
737
778
|
// ✅ 修复:ERC20 交易时,将利润转换为原生代币
|
|
738
779
|
if (!useNative && profitWei > 0n && quoteToken) {
|
|
@@ -744,11 +785,15 @@ export async function directV2BatchBuy(params) {
|
|
|
744
785
|
profitWei = 0n; // 报价失败,跳过利润
|
|
745
786
|
}
|
|
746
787
|
}
|
|
788
|
+
// ✅ 利润交易
|
|
789
|
+
const profitTxs = [];
|
|
747
790
|
if (profitWei > 0n) {
|
|
748
|
-
const profitNonce = nonces[maxFlowIndex] + 1; // ✅
|
|
791
|
+
const profitNonce = nonces[maxFlowIndex] + nonceOffsets[maxFlowIndex] + 1; // ✅ 考虑贿赂交易的 nonce 偏移
|
|
749
792
|
const profitTx = await buildProfitTransaction(wallets[maxFlowIndex], profitWei, profitNonce, gasPrice, chainId, txType);
|
|
750
|
-
|
|
793
|
+
profitTxs.push(profitTx);
|
|
751
794
|
}
|
|
795
|
+
// ✅ 组装最终交易列表:贿赂 → 交易 → 利润
|
|
796
|
+
const signedTxs = [...bribeTxs, ...swapTxs, ...profitTxs];
|
|
752
797
|
return {
|
|
753
798
|
signedTransactions: signedTxs,
|
|
754
799
|
metadata: {
|
|
@@ -855,23 +900,55 @@ export async function directV2BatchSell(params) {
|
|
|
855
900
|
if (!config.skipApprovalCheck) {
|
|
856
901
|
allowances = await Promise.all(wallets.map(w => tokenContract.allowance(w.address, routerAddress)));
|
|
857
902
|
}
|
|
858
|
-
// ✅
|
|
903
|
+
// ✅ 先获取报价,确定哪个钱包输出最大(用于支付贿赂和利润)
|
|
904
|
+
const router = new Contract(routerAddress, V2_ROUTER_ABI, provider);
|
|
905
|
+
const quotePromises = wallets.map(async (_, i) => {
|
|
906
|
+
if (sellAmountsWei[i] <= 0n)
|
|
907
|
+
return sellAmountsWei[i];
|
|
908
|
+
try {
|
|
909
|
+
const amounts = await router.getAmountsOut(sellAmountsWei[i], path);
|
|
910
|
+
return amounts[amounts.length - 1];
|
|
911
|
+
}
|
|
912
|
+
catch {
|
|
913
|
+
return sellAmountsWei[i];
|
|
914
|
+
}
|
|
915
|
+
});
|
|
916
|
+
const outputEstimates = await Promise.all(quotePromises);
|
|
917
|
+
const maxOutputIndex = findMaxFlowIndex(outputEstimates);
|
|
918
|
+
// ✅ 计算贿赂金额(仅 BSC 链)
|
|
919
|
+
const bribeWei = getBribeAmount(config, chain);
|
|
920
|
+
const hasBribe = bribeWei > 0n && wallets.length > 0;
|
|
921
|
+
// ✅ 优化:计算每个钱包的 nonce 偏移(授权 + 贿赂)
|
|
859
922
|
const currentNonceOffset = wallets.map((_, i) => {
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
923
|
+
let offset = 0;
|
|
924
|
+
// 贿赂交易偏移(只有 maxOutputIndex 钱包需要)
|
|
925
|
+
if (hasBribe && i === maxOutputIndex)
|
|
926
|
+
offset++;
|
|
927
|
+
// 授权交易偏移
|
|
928
|
+
if (!config.skipApprovalCheck && allowances[i] < sellAmountsWei[i])
|
|
929
|
+
offset++;
|
|
930
|
+
return offset;
|
|
863
931
|
});
|
|
932
|
+
// ✅ 贿赂交易放在首位(提高 BlockRazor 打包优先级)
|
|
933
|
+
const bribeTxs = [];
|
|
934
|
+
if (hasBribe) {
|
|
935
|
+
const bribeTx = await buildBribeTransaction(wallets[maxOutputIndex], bribeWei, nonces[maxOutputIndex], // 使用原始 nonce
|
|
936
|
+
gasPrice, chainId, txType);
|
|
937
|
+
bribeTxs.push(bribeTx);
|
|
938
|
+
}
|
|
864
939
|
// ✅ 优化:并行签名所有授权交易
|
|
865
940
|
const approvalTxPromises = wallets.map(async (wallet, i) => {
|
|
866
941
|
if (config.skipApprovalCheck || sellAmountsWei[i] <= 0n)
|
|
867
942
|
return null;
|
|
868
943
|
if (allowances[i] >= sellAmountsWei[i])
|
|
869
944
|
return null;
|
|
945
|
+
// 授权交易的 nonce = 原始 nonce + 贿赂偏移
|
|
946
|
+
const approvalNonce = nonces[i] + (hasBribe && i === maxOutputIndex ? 1 : 0);
|
|
870
947
|
return wallet.signTransaction({
|
|
871
948
|
to: tokenAddress,
|
|
872
949
|
data: approveIface.encodeFunctionData('approve', [routerAddress, ethers.MaxUint256]),
|
|
873
950
|
value: 0n,
|
|
874
|
-
nonce:
|
|
951
|
+
nonce: approvalNonce,
|
|
875
952
|
gasLimit: 60000n,
|
|
876
953
|
gasPrice,
|
|
877
954
|
chainId,
|
|
@@ -895,35 +972,19 @@ export async function directV2BatchSell(params) {
|
|
|
895
972
|
});
|
|
896
973
|
});
|
|
897
974
|
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
975
|
// ✅ 按顺序组装签名交易:先授权,后卖出
|
|
913
|
-
const
|
|
976
|
+
const swapTxs = [];
|
|
914
977
|
for (let i = 0; i < wallets.length; i++) {
|
|
915
978
|
const approvalTx = approvalTxResults[i];
|
|
916
979
|
const sellTx = sellTxResults[i];
|
|
917
980
|
if (approvalTx)
|
|
918
|
-
|
|
981
|
+
swapTxs.push(approvalTx);
|
|
919
982
|
if (sellTx) {
|
|
920
|
-
|
|
983
|
+
swapTxs.push(sellTx);
|
|
921
984
|
currentNonceOffset[i]++; // 更新 offset 供利润交易使用
|
|
922
985
|
}
|
|
923
986
|
}
|
|
924
987
|
const totalOutputEstimate = outputEstimates.reduce((sum, o) => sum + o, 0n);
|
|
925
|
-
// ✅ 优化:选择输出最大的钱包支付利润(和 core.ts 逻辑一致)
|
|
926
|
-
const maxOutputIndex = findMaxFlowIndex(outputEstimates);
|
|
927
988
|
let profitWei = calculateProfitAmount(totalOutputEstimate);
|
|
928
989
|
// ✅ 修复:ERC20 输出时,将利润转换为原生代币
|
|
929
990
|
if (!useNativeOutput && profitWei > 0n && quoteToken) {
|
|
@@ -935,11 +996,15 @@ export async function directV2BatchSell(params) {
|
|
|
935
996
|
profitWei = 0n;
|
|
936
997
|
}
|
|
937
998
|
}
|
|
999
|
+
// ✅ 利润交易
|
|
1000
|
+
const profitTxs = [];
|
|
938
1001
|
if (profitWei > 0n && wallets.length > 0) {
|
|
939
1002
|
const profitTx = await buildProfitTransaction(wallets[maxOutputIndex], // ✅ 使用输出最大的钱包
|
|
940
1003
|
profitWei, nonces[maxOutputIndex] + currentNonceOffset[maxOutputIndex], gasPrice, chainId, txType);
|
|
941
|
-
|
|
1004
|
+
profitTxs.push(profitTx);
|
|
942
1005
|
}
|
|
1006
|
+
// ✅ 组装最终交易列表:贿赂 → 授权+卖出 → 利润
|
|
1007
|
+
const signedTxs = [...bribeTxs, ...swapTxs, ...profitTxs];
|
|
943
1008
|
return {
|
|
944
1009
|
signedTransactions: signedTxs,
|
|
945
1010
|
metadata: {
|
|
@@ -1031,22 +1096,33 @@ export async function directV3BatchBuy(params) {
|
|
|
1031
1096
|
}
|
|
1032
1097
|
}
|
|
1033
1098
|
};
|
|
1099
|
+
// ✅ 优化:选择金额最大的钱包支付贿赂和利润
|
|
1100
|
+
const maxFlowIndex = findMaxFlowIndex(flowAmounts);
|
|
1101
|
+
// ✅ 计算贿赂金额(仅 BSC 链)
|
|
1102
|
+
const bribeWei = getBribeAmount(config, chain);
|
|
1103
|
+
const hasBribe = bribeWei > 0n && wallets.length > 0;
|
|
1104
|
+
// ✅ 计算 nonce 偏移
|
|
1105
|
+
const nonceOffsets = wallets.map((_, i) => i === maxFlowIndex && hasBribe ? 1 : 0);
|
|
1106
|
+
// ✅ 贿赂交易放在首位(提高 BlockRazor 打包优先级)
|
|
1107
|
+
const bribeTxs = [];
|
|
1108
|
+
if (hasBribe) {
|
|
1109
|
+
const bribeTx = await buildBribeTransaction(wallets[maxFlowIndex], bribeWei, nonces[maxFlowIndex], gasPrice, chainId, txType);
|
|
1110
|
+
bribeTxs.push(bribeTx);
|
|
1111
|
+
}
|
|
1034
1112
|
// ✅ 优化:并行签名所有交易
|
|
1035
|
-
const
|
|
1113
|
+
const swapTxs = await Promise.all(wallets.map(async (wallet, i) => {
|
|
1036
1114
|
const { txData, txValue } = buildV3BuyTxData(wallet, flowAmounts[i]);
|
|
1037
1115
|
return wallet.signTransaction({
|
|
1038
1116
|
to: routerAddress,
|
|
1039
1117
|
data: txData,
|
|
1040
1118
|
value: txValue,
|
|
1041
|
-
nonce: nonces[i],
|
|
1119
|
+
nonce: nonces[i] + nonceOffsets[i],
|
|
1042
1120
|
gasLimit,
|
|
1043
1121
|
gasPrice,
|
|
1044
1122
|
chainId,
|
|
1045
1123
|
type: txType,
|
|
1046
1124
|
});
|
|
1047
1125
|
}));
|
|
1048
|
-
// ✅ 优化:选择金额最大的钱包支付利润
|
|
1049
|
-
const maxFlowIndex = findMaxFlowIndex(flowAmounts);
|
|
1050
1126
|
let profitWei = calculateProfitAmount(totalFlowWei);
|
|
1051
1127
|
// ✅ 修复:ERC20 交易时,将利润转换为原生代币
|
|
1052
1128
|
if (!useNative && profitWei > 0n && quoteToken) {
|
|
@@ -1058,11 +1134,14 @@ export async function directV3BatchBuy(params) {
|
|
|
1058
1134
|
profitWei = 0n;
|
|
1059
1135
|
}
|
|
1060
1136
|
}
|
|
1137
|
+
// ✅ 利润交易
|
|
1138
|
+
const profitTxs = [];
|
|
1061
1139
|
if (profitWei > 0n) {
|
|
1062
|
-
const profitTx = await buildProfitTransaction(wallets[maxFlowIndex],
|
|
1063
|
-
|
|
1064
|
-
signedTxs.push(profitTx);
|
|
1140
|
+
const profitTx = await buildProfitTransaction(wallets[maxFlowIndex], profitWei, nonces[maxFlowIndex] + nonceOffsets[maxFlowIndex] + 1, gasPrice, chainId, txType);
|
|
1141
|
+
profitTxs.push(profitTx);
|
|
1065
1142
|
}
|
|
1143
|
+
// ✅ 组装最终交易列表:贿赂 → 交易 → 利润
|
|
1144
|
+
const signedTxs = [...bribeTxs, ...swapTxs, ...profitTxs];
|
|
1066
1145
|
return {
|
|
1067
1146
|
signedTransactions: signedTxs,
|
|
1068
1147
|
metadata: {
|
|
@@ -1162,23 +1241,43 @@ export async function directV3BatchSell(params) {
|
|
|
1162
1241
|
if (!config.skipApprovalCheck) {
|
|
1163
1242
|
allowances = await Promise.all(wallets.map(w => tokenContract.allowance(w.address, routerAddress)));
|
|
1164
1243
|
}
|
|
1165
|
-
// ✅
|
|
1244
|
+
// ✅ 先找出输出最大的钱包索引(用于支付贿赂和利润)
|
|
1245
|
+
// 对于 V3 卖出,使用卖出金额作为输出估计
|
|
1246
|
+
const maxOutputIndex = findMaxFlowIndex(sellAmountsWei);
|
|
1247
|
+
// ✅ 计算贿赂金额(仅 BSC 链)
|
|
1248
|
+
const bribeWei = getBribeAmount(config, chain);
|
|
1249
|
+
const hasBribe = bribeWei > 0n && wallets.length > 0;
|
|
1250
|
+
// ✅ 优化:计算每个钱包的 nonce 偏移(贿赂 + 授权)
|
|
1166
1251
|
const currentNonceOffset = wallets.map((_, i) => {
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1252
|
+
let offset = 0;
|
|
1253
|
+
// 贿赂交易偏移(只有 maxOutputIndex 钱包需要)
|
|
1254
|
+
if (hasBribe && i === maxOutputIndex)
|
|
1255
|
+
offset++;
|
|
1256
|
+
// 授权交易偏移
|
|
1257
|
+
if (!config.skipApprovalCheck && sellAmountsWei[i] > 0n && allowances[i] < sellAmountsWei[i])
|
|
1258
|
+
offset++;
|
|
1259
|
+
return offset;
|
|
1170
1260
|
});
|
|
1261
|
+
// ✅ 贿赂交易放在首位(提高 BlockRazor 打包优先级)
|
|
1262
|
+
const bribeTxs = [];
|
|
1263
|
+
if (hasBribe) {
|
|
1264
|
+
const bribeTx = await buildBribeTransaction(wallets[maxOutputIndex], bribeWei, nonces[maxOutputIndex], // 使用原始 nonce
|
|
1265
|
+
gasPrice, chainId, txType);
|
|
1266
|
+
bribeTxs.push(bribeTx);
|
|
1267
|
+
}
|
|
1171
1268
|
// ✅ 优化:并行签名所有授权交易
|
|
1172
1269
|
const approvalTxPromises = wallets.map(async (wallet, i) => {
|
|
1173
1270
|
if (config.skipApprovalCheck || sellAmountsWei[i] <= 0n)
|
|
1174
1271
|
return null;
|
|
1175
1272
|
if (allowances[i] >= sellAmountsWei[i])
|
|
1176
1273
|
return null;
|
|
1274
|
+
// 授权交易的 nonce = 原始 nonce + 贿赂偏移
|
|
1275
|
+
const approvalNonce = nonces[i] + (hasBribe && i === maxOutputIndex ? 1 : 0);
|
|
1177
1276
|
return wallet.signTransaction({
|
|
1178
1277
|
to: tokenAddress,
|
|
1179
1278
|
data: approveIface.encodeFunctionData('approve', [routerAddress, ethers.MaxUint256]),
|
|
1180
1279
|
value: 0n,
|
|
1181
|
-
nonce:
|
|
1280
|
+
nonce: approvalNonce,
|
|
1182
1281
|
gasLimit: 60000n,
|
|
1183
1282
|
gasPrice,
|
|
1184
1283
|
chainId,
|
|
@@ -1203,15 +1302,15 @@ export async function directV3BatchSell(params) {
|
|
|
1203
1302
|
});
|
|
1204
1303
|
const sellTxResults = await Promise.all(sellTxPromises);
|
|
1205
1304
|
// ✅ 按顺序组装签名交易:先授权,后卖出
|
|
1206
|
-
const
|
|
1305
|
+
const swapTxs = [];
|
|
1207
1306
|
const outputEstimates = [];
|
|
1208
1307
|
for (let i = 0; i < wallets.length; i++) {
|
|
1209
1308
|
const approvalTx = approvalTxResults[i];
|
|
1210
1309
|
const sellTx = sellTxResults[i];
|
|
1211
1310
|
if (approvalTx)
|
|
1212
|
-
|
|
1311
|
+
swapTxs.push(approvalTx);
|
|
1213
1312
|
if (sellTx) {
|
|
1214
|
-
|
|
1313
|
+
swapTxs.push(sellTx);
|
|
1215
1314
|
outputEstimates.push(sellAmountsWei[i]);
|
|
1216
1315
|
currentNonceOffset[i]++;
|
|
1217
1316
|
}
|
|
@@ -1220,8 +1319,6 @@ export async function directV3BatchSell(params) {
|
|
|
1220
1319
|
}
|
|
1221
1320
|
}
|
|
1222
1321
|
const totalOutputEstimate = outputEstimates.reduce((sum, o) => sum + o, 0n);
|
|
1223
|
-
// ✅ 优化:选择输出最大的钱包支付利润
|
|
1224
|
-
const maxOutputIndex = findMaxFlowIndex(outputEstimates);
|
|
1225
1322
|
let profitWei = calculateProfitAmount(totalOutputEstimate);
|
|
1226
1323
|
// ✅ 修复:ERC20 输出时,将利润转换为原生代币
|
|
1227
1324
|
if (!useNativeOutput && profitWei > 0n && quoteToken) {
|
|
@@ -1233,11 +1330,15 @@ export async function directV3BatchSell(params) {
|
|
|
1233
1330
|
profitWei = 0n;
|
|
1234
1331
|
}
|
|
1235
1332
|
}
|
|
1333
|
+
// ✅ 利润交易
|
|
1334
|
+
const profitTxs = [];
|
|
1236
1335
|
if (profitWei > 0n && wallets.length > 0) {
|
|
1237
1336
|
const profitTx = await buildProfitTransaction(wallets[maxOutputIndex], // ✅ 使用输出最大的钱包
|
|
1238
1337
|
profitWei, nonces[maxOutputIndex] + currentNonceOffset[maxOutputIndex], gasPrice, chainId, txType);
|
|
1239
|
-
|
|
1338
|
+
profitTxs.push(profitTx);
|
|
1240
1339
|
}
|
|
1340
|
+
// ✅ 组装最终交易列表:贿赂 → 授权+卖出 → 利润
|
|
1341
|
+
const signedTxs = [...bribeTxs, ...swapTxs, ...profitTxs];
|
|
1241
1342
|
return {
|
|
1242
1343
|
signedTransactions: signedTxs,
|
|
1243
1344
|
metadata: {
|