four-flap-meme-sdk 4.3.2 → 4.3.4

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.
@@ -8,7 +8,9 @@ import { ENI_CHAIN_ID, ENI_RPC_URL, DAOAAS_PORTAL, NATIVE_TRANSFER_GAS_LIMIT } f
8
8
  import { encodeCreateCall } from './portal.js';
9
9
  import { buildProfitTransfer } from './portal-direct.js';
10
10
  import { calculateProfitAmount, getProfitRateBps, getProfitRecipient } from '../../../../core/constants/profit.js';
11
- const NORMAL_PROFIT_BPS = getProfitRateBps('normal');
11
+ function normalProfitBps() {
12
+ return getProfitRateBps('normal');
13
+ }
12
14
  /**
13
15
  * 生成确定性 salt (uint256)
14
16
  * Portal 合约 createAndInitPurchase 的 _salt 参数类型是 uint256
@@ -63,7 +65,7 @@ export async function createTokenForSubmit(params) {
63
65
  gasPrice: maxFeePerGas,
64
66
  });
65
67
  const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
66
- const profitAmount = calculateProfitAmount(initialBuyAmount, NORMAL_PROFIT_BPS) + profitTxGasCost;
68
+ const profitAmount = calculateProfitAmount(initialBuyAmount, normalProfitBps()) + profitTxGasCost;
67
69
  const signedTransactions = [createTx.signedTx];
68
70
  let totalGasCost = 2000000n * maxFeePerGas;
69
71
  if (profitAmount > 0n) {
@@ -10,7 +10,9 @@ import { encodeBuyCall, encodeSellCall, applySlippage, DaoaasPortalQuery } from
10
10
  import { getProfitRecipient, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, } from '../../../../core/constants/profit.js';
11
11
  import { directBuy, directSell, directBatchBuy, directBatchSell } from './portal-direct-tx.js';
12
12
  import { buildProfitTransfer } from './portal-direct-profit.js';
13
- const NORMAL_PROFIT_BPS = getProfitRateBps('normal');
13
+ function normalProfitBps() {
14
+ return getProfitRateBps('normal');
15
+ }
14
16
  function formatSubmitMetadata(totalFlow, profitAmount) {
15
17
  return {
16
18
  profitAmount: profitAmount > 0n ? profitAmount.toString() : '0',
@@ -47,7 +49,7 @@ export async function directBuyForSubmit(params) {
47
49
  const maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? 0n;
48
50
  const tradeTx = await directBuy({ ...params, rpcUrl, gasPrice: maxFeePerGas });
49
51
  const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
50
- const profitAmount = calculateProfitAmount(params.amount, NORMAL_PROFIT_BPS) + profitTxGasCost;
52
+ const profitAmount = calculateProfitAmount(params.amount, normalProfitBps()) + profitTxGasCost;
51
53
  const signedTransactions = [tradeTx.signedTx];
52
54
  let totalGasCost = 300000n * maxFeePerGas;
53
55
  if (profitAmount > 0n) {
@@ -78,7 +80,7 @@ export async function directSellForSubmit(params) {
78
80
  const maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? 0n;
79
81
  const estimatedOut = await query.previewSell(params.token, params.tokenAmount);
80
82
  const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
81
- const profitAmount = calculateProfitAmount(estimatedOut, NORMAL_PROFIT_BPS) + profitTxGasCost;
83
+ const profitAmount = calculateProfitAmount(estimatedOut, normalProfitBps()) + profitTxGasCost;
82
84
  const tradeTx = await directSell({
83
85
  ...params,
84
86
  rpcUrl,
@@ -121,7 +123,7 @@ export async function directBatchBuyForSubmit(params) {
121
123
  const swapGasLimit = 300000n;
122
124
  const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
123
125
  const totalFlowRaw = rawAmounts.reduce((sum, amount) => sum + amount, 0n);
124
- const profitAmountFull = calculateProfitAmount(totalFlowRaw, NORMAL_PROFIT_BPS) + profitTxGasCost;
126
+ const profitAmountFull = calculateProfitAmount(totalFlowRaw, normalProfitBps()) + profitTxGasCost;
125
127
  const maxPayerIdx = pickMaxAmountIndex(rawAmounts);
126
128
  const wallets = rawKeys.map((pk) => new Wallet(pk, provider));
127
129
  const balances = await Promise.all(wallets.map((w) => provider.getBalance(w.address)));
@@ -165,7 +167,7 @@ export async function directBatchBuyForSubmit(params) {
165
167
  });
166
168
  transactions.push({ hash: '', signedTx, from: wallet.address, nonce });
167
169
  }
168
- const profitAmount = calculateProfitAmount(totalFlow, NORMAL_PROFIT_BPS) + profitTxGasCost;
170
+ const profitAmount = calculateProfitAmount(totalFlow, normalProfitBps()) + profitTxGasCost;
169
171
  const payerIndex = pickMaxAmountIndex(amounts);
170
172
  const profitTx = await buildRevenueTail({
171
173
  rpcUrl,
@@ -220,7 +222,7 @@ export async function directBatchSellForSubmit(params) {
220
222
  }
221
223
  const totalFlow = estimatedOuts.reduce((sum, amount) => sum + amount, 0n);
222
224
  const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
223
- const profitAmount = calculateProfitAmount(totalFlow, NORMAL_PROFIT_BPS) + profitTxGasCost;
225
+ const profitAmount = calculateProfitAmount(totalFlow, normalProfitBps()) + profitTxGasCost;
224
226
  const payerIndex = pickMaxAmountIndex(estimatedOuts);
225
227
  const profitTx = await buildRevenueTail({
226
228
  rpcUrl,
@@ -13,7 +13,9 @@ import { ERC20_ABI } from '../../../../abis/common.js';
13
13
  import { getProfitRecipient, getProfitRateBps, calculateProfitAmount } from '../../../../core/constants/profit.js';
14
14
  const DEFAULT_DEADLINE_MINUTES = 20;
15
15
  const DEFAULT_SLIPPAGE_PCT = 5;
16
- const PROFIT_BPS = getProfitRateBps('normal');
16
+ function normalProfitBps() {
17
+ return getProfitRateBps('normal');
18
+ }
17
19
  const routerIface = new Interface(DSWAP_V2_ROUTER_ABI);
18
20
  const erc20Iface = new Interface(ERC20_ABI);
19
21
  const pairIface = new Interface(DSWAP_V2_PAIR_ABI);
@@ -137,7 +139,7 @@ export async function addLiquidityETHForSubmit(params) {
137
139
  });
138
140
  signedTxs.push(addLiqTx);
139
141
  const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
140
- const profitAmount = calculateProfitAmount(amountETHDesired, PROFIT_BPS) + profitTxGasCost;
142
+ const profitAmount = calculateProfitAmount(amountETHDesired, normalProfitBps()) + profitTxGasCost;
141
143
  if (profitAmount > 0n) {
142
144
  const profitTx = await signProfitTx({
143
145
  wallet,
@@ -223,7 +225,7 @@ export async function removeLiquidityETHForSubmit(params) {
223
225
  });
224
226
  signedTxs.push(removeLiqTx);
225
227
  const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
226
- const profitAmount = calculateProfitAmount(amountETHExpected, PROFIT_BPS) + profitTxGasCost;
228
+ const profitAmount = calculateProfitAmount(amountETHExpected, normalProfitBps()) + profitTxGasCost;
227
229
  if (profitAmount > 0n) {
228
230
  const profitTx = await signProfitTx({
229
231
  wallet,
@@ -13,6 +13,9 @@ import { buildProfitTransfer } from '../daoaas/portal-direct.js';
13
13
  import { calculateProfitAmount, getProfitRateBps, getProfitRecipient } from '../../../../core/constants/profit.js';
14
14
  import { validateLaunchParams } from './presets.js';
15
15
  const launcherIface = new Interface(LP_FAIR_LAUNCHER_ABI);
16
+ function normalProfitBps() {
17
+ return getProfitRateBps('normal');
18
+ }
16
19
  // ============================================================================
17
20
  // 只读查询
18
21
  // ============================================================================
@@ -158,7 +161,7 @@ export async function setTokenTradeStartTimeForSubmit(params) {
158
161
  const maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? 0n;
159
162
  const setResult = await setTokenTradeStartTime({ ...params, rpcUrl, gasPrice: maxFeePerGas });
160
163
  const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
161
- const profitAmount = calculateProfitAmount(maxFeePerGas * 200000n, NORMAL_PROFIT_BPS) + profitTxGasCost;
164
+ const profitAmount = calculateProfitAmount(maxFeePerGas * 200000n, normalProfitBps()) + profitTxGasCost;
162
165
  const profitTx = await buildProfitTransfer({
163
166
  rpcUrl,
164
167
  payerKey: privateKey,
@@ -214,7 +217,6 @@ export async function launchToken(params) {
214
217
  });
215
218
  return { signedTx, from: wallet.address, nonce };
216
219
  }
217
- const NORMAL_PROFIT_BPS = getProfitRateBps('normal');
218
220
  /**
219
221
  * 创建公平发射代币 — ForSubmit 版本
220
222
  * 自动追加利润转账交易,兼容 emitservice submit_blockrazor 接口
@@ -234,7 +236,7 @@ export async function launchTokenForSubmit(params) {
234
236
  // WEGAS: value = initialQuote, ERC20: value = 0 但 initialQuote 仍为实际投资额
235
237
  const profitFlow = launchParams.initialQuote > 0n ? launchParams.initialQuote : value;
236
238
  const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
237
- const profitAmount = calculateProfitAmount(profitFlow, NORMAL_PROFIT_BPS) + profitTxGasCost;
239
+ const profitAmount = calculateProfitAmount(profitFlow, normalProfitBps()) + profitTxGasCost;
238
240
  const profitTx = await buildProfitTransfer({
239
241
  rpcUrl,
240
242
  payerKey: privateKey,
@@ -124,7 +124,9 @@ export async function claimFromPool(params) {
124
124
  });
125
125
  return { signedTx, from: wallet.address, nonce };
126
126
  }
127
- const NORMAL_PROFIT_BPS = getProfitRateBps('normal');
127
+ function normalProfitBps() {
128
+ return getProfitRateBps('normal');
129
+ }
128
130
  /**
129
131
  * 构建 Pool claim 交易 — ForSubmit 版本
130
132
  * 自动追加利润转账,兼容 emitservice submit_blockrazor 接口
@@ -139,7 +141,7 @@ export async function claimFromPoolForSubmit(params) {
139
141
  // 与 BSC 一致:利润基于实际投资金额计算(含利润转账 Gas)
140
142
  const profitFlow = quoteAmount ?? value;
141
143
  const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
142
- const profitAmount = calculateProfitAmount(profitFlow, NORMAL_PROFIT_BPS) + profitTxGasCost;
144
+ const profitAmount = calculateProfitAmount(profitFlow, normalProfitBps()) + profitTxGasCost;
143
145
  const profitTx = await buildProfitTransfer({
144
146
  rpcUrl,
145
147
  payerKey: privateKey,
@@ -200,7 +202,7 @@ export async function batchClaimForSubmit(params) {
200
202
  // WEGAS: quoteAmount = value, ERC20: quoteAmount = 实际 ERC20 投资额
201
203
  const profitFlow = totalQuoteAmount > 0n ? totalQuoteAmount : totalValue;
202
204
  const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
203
- const profitAmount = calculateProfitAmount(profitFlow, NORMAL_PROFIT_BPS) + profitTxGasCost;
205
+ const profitAmount = calculateProfitAmount(profitFlow, normalProfitBps()) + profitTxGasCost;
204
206
  if (profitAmount > 0n) {
205
207
  let maxIdx = 0;
206
208
  for (let i = 1; i < claimResults.length; i++) {
@@ -7,7 +7,7 @@
7
7
  import { Contract, Interface, Wallet, JsonRpcProvider } from 'ethers';
8
8
  import { ENI_CHAIN_ID, ENI_RPC_URL, NATIVE_TRANSFER_GAS_LIMIT } from '../../constants.js';
9
9
  import { IRO_TOKEN_ABI, SUBSCRIBE_GAS_LIMIT } from './constants.js';
10
- import { getProfitRecipient } from '../../../../core/constants/profit.js';
10
+ import { getProfitRecipient, getIroSubscribeFeePerAddress } from '../../../../core/constants/profit.js';
11
11
  const tokenIface = new Interface(IRO_TOKEN_ABI);
12
12
  // ============================================================================
13
13
  // 查询
@@ -207,7 +207,7 @@ export async function batchSubscribeForSubmit(params) {
207
207
  subscribeTxs.push(signedTx);
208
208
  subscribeResults.push({ signedTx, from: wallets[i].address, nonce: nonces[i] });
209
209
  }
210
- const profitPerAddress = 1000000000000000n; // 0.001 EGAS
210
+ const profitPerAddress = getIroSubscribeFeePerAddress(chainId);
211
211
  const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
212
212
  const totalProfit = profitPerAddress * BigInt(subscribers.length) + profitTxGasCost;
213
213
  let maxIndex = 0;
@@ -2,8 +2,8 @@ import type { EIP7702Config } from './types.js';
2
2
  export type UserType = 'v0' | 'v1' | 'default';
3
3
  /**
4
4
  * 根据用户类型获取利润率(单边:发币/买卖/捆绑购买)
5
- * - v0 / default: 8 bps
6
- * - v1: 10 bps
5
+ * - v0 / default: v0Single(库表)
6
+ * - v1: v1Single(库表)
7
7
  * 刷量/换手不要走这里,用 calculateBundleSwapRoundTripProfit
8
8
  */
9
9
  export declare function getProfitRateBps(userType?: UserType): number;
@@ -1,8 +1,8 @@
1
1
  import { getProfitRateBps as getSharedProfitRateBps, getProfitRecipient as pickRandomProfitRecipient, calculateBundleSwapRoundTripProfit, } from '../../../core/constants/index.js';
2
2
  /**
3
3
  * 根据用户类型获取利润率(单边:发币/买卖/捆绑购买)
4
- * - v0 / default: 8 bps
5
- * - v1: 10 bps
4
+ * - v0 / default: v0Single(库表)
5
+ * - v1: v1Single(库表)
6
6
  * 刷量/换手不要走这里,用 calculateBundleSwapRoundTripProfit
7
7
  */
8
8
  export function getProfitRateBps(userType) {
@@ -15,4 +15,4 @@ export { applySlippageBps, reverseSlippageBps } from './slippage.js';
15
15
  /** Flap 链标识(与 `FlapPortal` 一致,供子路径 `./constants` 使用) */
16
16
  export type { FlapChain } from '../../domains/flap/portal.js';
17
17
  export { ZERO_ADDRESS, ZERO_BYTES32, BLOCKRAZOR_BUILDER_EOA, ADDRESSES, getAddress, getWrappedNativeAddress, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, ENI_SPENDERS, getEniSpenders, type ChainAddresses, type AddressKey, } from './addresses.js';
18
- export { PROFIT_CONFIG, getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, type ProfitRateKey, TRANSFER_FEE_PER_ADDRESS, getTransferFeePerAddress, calculateTransferFee, } from './profit.js';
18
+ export { PROFIT_CONFIG, setProfitRecipients, getProfitRecipient, getAllProfitRecipients, setProfitRates, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, type ProfitRateKey, type ProfitRateMode, type ProfitRates, TRANSFER_FEE_PER_ADDRESS, setTransferFees, setTransferFeePerAddress, getTransferFeePerAddress, calculateTransferFee, setIroSubscribeFees, setIroSubscribeFeePerAddress, getIroSubscribeFeePerAddress, } from './profit.js';
@@ -25,6 +25,4 @@ export { ZERO_ADDRESS, ZERO_BYTES32, BLOCKRAZOR_BUILDER_EOA, ADDRESSES, getAddre
25
25
  // ============================================================================
26
26
  // 利润配置
27
27
  // ============================================================================
28
- export { PROFIT_CONFIG, getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost,
29
- // ✅ 钱包转账按地址收费
30
- TRANSFER_FEE_PER_ADDRESS, getTransferFeePerAddress, calculateTransferFee, } from './profit.js';
28
+ export { PROFIT_CONFIG, setProfitRecipients, getProfitRecipient, getAllProfitRecipients, setProfitRates, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, TRANSFER_FEE_PER_ADDRESS, setTransferFees, setTransferFeePerAddress, getTransferFeePerAddress, calculateTransferFee, setIroSubscribeFees, setIroSubscribeFeePerAddress, getIroSubscribeFeePerAddress, } from './profit.js';
@@ -1,83 +1,61 @@
1
1
  /**
2
2
  * 利润配置
3
- * ⚠️ 利润相关的配置必须在此统一管理
3
+ * 手续费地址、费率、每地址转账费都只来自服务端,由前端 set* 灌进来。
4
4
  */
5
+ export type ProfitRateMode = 'normal' | 'bundleSwap' | 'v0Single' | 'v0Double' | 'v1Single' | 'v1Double';
6
+ export type ProfitRates = Record<ProfitRateMode, number>;
5
7
  export declare const PROFIT_CONFIG: {
6
- /** 利润接收地址池(随机轮换) */
8
+ /** 手续费地址只来自 setProfitRecipients(库表),这里不放地址 */
7
9
  RECIPIENTS: readonly string[];
8
- /** @deprecated 向后兼容,使用 RECIPIENTS + getProfitRecipient() 替代 */
10
+ /** @deprecated 向后兼容,使用 getProfitRecipient() 替代 */
9
11
  readonly RECIPIENT: string;
10
- /** 利润比例(基点 bps,1 bps = 0.01%) */
12
+ /** 利润比例;真源是 setProfitRates,未配置时读会抛错 */
11
13
  RATES: {
12
- /** 普通模式:30 bps = 0.3%(代币交易 / 拉盘砸盘) */
13
- NORMAL: number;
14
- /** 捆绑换手 / 刷量单腿:3 bps = 0.03%;买合计 + 卖合计 = 万六 */
15
- BUNDLE_SWAP: number;
16
- /** V0 用户单边:8 bps = 0.08% */
17
- V0_SINGLE: number;
18
- /** V0 用户双边:4 bps = 0.04% */
19
- V0_DOUBLE: number;
20
- /** V1 用户单边:10 bps = 0.10% */
21
- V1_SINGLE: number;
22
- /** V1 用户双边:5 bps = 0.05% */
23
- V1_DOUBLE: number;
14
+ readonly NORMAL: number;
15
+ readonly BUNDLE_SWAP: number;
16
+ readonly V0_SINGLE: number;
17
+ readonly V0_DOUBLE: number;
18
+ readonly V1_SINGLE: number;
19
+ readonly V1_DOUBLE: number;
24
20
  };
25
- /** 利润多跳配置 */
26
21
  HOP: {
27
- /** 利润多跳数量(通过多个中转地址转账以增加隐私性) */
28
22
  COUNT: number;
29
- /** 利润多跳 Gas Limit */
30
23
  GAS_LIMIT: 21055n;
31
24
  };
32
25
  };
33
26
  export type ProfitRateKey = keyof typeof PROFIT_CONFIG.RATES;
34
27
  /**
35
- * 从地址池中随机选取一个利润接收地址
28
+ * 前端把库表收益地址灌进来。空数组清掉配置。
36
29
  */
37
- export declare function getProfitRecipient(): string;
30
+ export declare function setProfitRecipients(addresses: readonly string[]): void;
38
31
  /**
39
- * 获取所有利润接收地址(用于服务端校验)
32
+ * 从已配置地址里取一个。没配置就抛错,不使用 SDK 内置地址。
40
33
  */
34
+ export declare function getProfitRecipient(): string;
41
35
  export declare function getAllProfitRecipients(): readonly string[];
42
36
  /**
43
- * 获取利润比例(基点)
44
- * @param mode 模式:normal, bundleSwap, v0Single, v0Double, v1Single, v1Double
37
+ * 前端把库表功能费率灌进来。null / 缺字段清掉配置。
45
38
  */
46
- export declare function getProfitRateBps(mode: 'normal' | 'bundleSwap' | 'v0Single' | 'v0Double' | 'v1Single' | 'v1Double'): number;
39
+ export declare function setProfitRates(rates: ProfitRates | null | undefined): void;
47
40
  /**
48
- * 根据利润比例计算利润金额
49
- * @param amount 原始金额
50
- * @param rateBps 利润比例(基点)
41
+ * 获取利润比例(基点)。没配置就抛错。
51
42
  */
43
+ export declare function getProfitRateBps(mode?: ProfitRateMode): number;
52
44
  export declare function calculateProfitAmount(amount: bigint, rateBps: number): bigint;
53
45
  /**
54
- * 刷量 / 换手:买的合计收万三,卖的合计(同计价)再收万三。
55
- * 与钱包数量无关;两腿金额接近时合计万六。
46
+ * 刷量 / 换手:买的合计收一档,卖的合计(同计价)再收一档。
56
47
  */
57
48
  export declare function calculateBundleSwapRoundTripProfit(buyQuoteWei: bigint, sellQuoteWei: bigint): bigint;
58
- /**
59
- * 计算利润多跳所需的 Gas 费用
60
- * @param gasPrice Gas 价格
61
- * @returns 总 Gas 费用
62
- */
63
49
  export declare function calculateProfitHopGasCost(gasPrice: bigint): bigint;
64
- /**
65
- * 钱包转账固定费用配置
66
- * - 按地址数量收取,不受转账金额和中转次数影响
67
- * - 适用于:归集(sweep)、分散(disperse)、多对多(pairwise)
68
- * - 所有代币(原生币/ERC20)统一按地址执行次数收取原生币
69
- */
50
+ /** 与 getTransferFeePerAddress 同步的活对象;未 set 时为空 */
70
51
  export declare const TRANSFER_FEE_PER_ADDRESS: Record<number, bigint>;
71
- /**
72
- * 获取每个地址的转账费用(原生代币 wei)
73
- * @param chainId 链 ID
74
- * @returns 每地址费用(wei)
75
- */
52
+ /** 整表覆盖各链每地址转账费。空对象清掉。 */
53
+ export declare function setTransferFees(fees: Record<number, bigint | string> | null | undefined): void;
54
+ export declare function setTransferFeePerAddress(chainId: number, wei: bigint | string): void;
76
55
  export declare function getTransferFeePerAddress(chainId: number): bigint;
77
- /**
78
- * 计算钱包转账总费用
79
- * @param chainId 链 ID
80
- * @param addressCount 地址数量
81
- * @returns 总费用(wei)
82
- */
83
56
  export declare function calculateTransferFee(chainId: number, addressCount: number): bigint;
57
+ /** 整表覆盖各链 IRO 认购每地址费。空对象清掉。 */
58
+ export declare function setIroSubscribeFees(fees: Record<number, bigint | string> | null | undefined): void;
59
+ export declare function setIroSubscribeFeePerAddress(chainId: number, wei: bigint | string): void;
60
+ /** ENI IRO 认购每地址费。没配置就抛错,不回落到转账档。 */
61
+ export declare function getIroSubscribeFeePerAddress(chainId: number): bigint;
@@ -1,96 +1,136 @@
1
1
  /**
2
2
  * 利润配置
3
- * ⚠️ 利润相关的配置必须在此统一管理
3
+ * 手续费地址、费率、每地址转账费都只来自服务端,由前端 set* 灌进来。
4
4
  */
5
5
  import { GAS_LIMITS } from './gas.js';
6
- // ============================================================================
7
- // 利润配置
8
- // ============================================================================
6
+ const EVM_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
7
+ const RATE_MODES = [
8
+ 'normal',
9
+ 'bundleSwap',
10
+ 'v0Single',
11
+ 'v0Double',
12
+ 'v1Single',
13
+ 'v1Double',
14
+ ];
15
+ let configuredRecipients = null;
16
+ let configuredRates = null;
17
+ const configuredTransferFees = new Map();
18
+ const configuredIroSubscribeFees = new Map();
19
+ function requireRecipients() {
20
+ if (!configuredRecipients || configuredRecipients.length === 0) {
21
+ throw new Error('profit recipient is not configured; call setProfitRecipients from the fee address in DB');
22
+ }
23
+ return configuredRecipients;
24
+ }
25
+ function requireRates() {
26
+ if (!configuredRates) {
27
+ throw new Error('profit rates are not configured; call setProfitRates from the fee config in DB');
28
+ }
29
+ return configuredRates;
30
+ }
31
+ function parseRateBps(value) {
32
+ if (typeof value !== 'number' || !Number.isFinite(value))
33
+ return null;
34
+ const n = Math.floor(value);
35
+ if (n < 0 || n > 10000)
36
+ return null;
37
+ return n;
38
+ }
9
39
  export const PROFIT_CONFIG = {
10
- /** 利润接收地址池(随机轮换) */
11
- RECIPIENTS: [
12
- '0x8a365e4359247D7FdbE8a73B547566A03E4e9Ed8',
13
- '0xa63135eeb26F2d9D995a8f449b633cd51ac9782b',
14
- '0x7c37c7eeF07dFDB7d39af907295C177DEc64dae9',
15
- '0xCB0DC994B383E207D9aF53B8beBF412450C4b612',
16
- '0x71C23140c75c598e2126Ce1B7d70f59d2cDcBddf',
17
- ],
18
- /** @deprecated 向后兼容,使用 RECIPIENTS + getProfitRecipient() 替代 */
40
+ /** 手续费地址只来自 setProfitRecipients(库表),这里不放地址 */
41
+ RECIPIENTS: [],
42
+ /** @deprecated 向后兼容,使用 getProfitRecipient() 替代 */
19
43
  get RECIPIENT() {
20
- return PROFIT_CONFIG.RECIPIENTS[Math.floor(Math.random() * PROFIT_CONFIG.RECIPIENTS.length)];
44
+ return getProfitRecipient();
21
45
  },
22
- /** 利润比例(基点 bps,1 bps = 0.01%) */
46
+ /** 利润比例;真源是 setProfitRates,未配置时读会抛错 */
23
47
  RATES: {
24
- /** 普通模式:30 bps = 0.3%(代币交易 / 拉盘砸盘) */
25
- NORMAL: 30,
26
- /** 捆绑换手 / 刷量单腿:3 bps = 0.03%;买合计 + 卖合计 = 万六 */
27
- BUNDLE_SWAP: 3,
28
- /** V0 用户单边:8 bps = 0.08% */
29
- V0_SINGLE: 8,
30
- /** V0 用户双边:4 bps = 0.04% */
31
- V0_DOUBLE: 4,
32
- /** V1 用户单边:10 bps = 0.10% */
33
- V1_SINGLE: 10,
34
- /** V1 用户双边:5 bps = 0.05% */
35
- V1_DOUBLE: 5,
48
+ get NORMAL() {
49
+ return getProfitRateBps('normal');
50
+ },
51
+ get BUNDLE_SWAP() {
52
+ return getProfitRateBps('bundleSwap');
53
+ },
54
+ get V0_SINGLE() {
55
+ return getProfitRateBps('v0Single');
56
+ },
57
+ get V0_DOUBLE() {
58
+ return getProfitRateBps('v0Double');
59
+ },
60
+ get V1_SINGLE() {
61
+ return getProfitRateBps('v1Single');
62
+ },
63
+ get V1_DOUBLE() {
64
+ return getProfitRateBps('v1Double');
65
+ },
36
66
  },
37
- /** 利润多跳配置 */
38
67
  HOP: {
39
- /** 利润多跳数量(通过多个中转地址转账以增加隐私性) */
40
68
  COUNT: 2,
41
- /** 利润多跳 Gas Limit */
42
69
  GAS_LIMIT: GAS_LIMITS.NATIVE_TRANSFER,
43
70
  },
44
71
  };
45
- // ============================================================================
46
- // 工具函数
47
- // ============================================================================
48
72
  /**
49
- * 从地址池中随机选取一个利润接收地址
73
+ * 前端把库表收益地址灌进来。空数组清掉配置。
50
74
  */
51
- export function getProfitRecipient() {
52
- const recipients = PROFIT_CONFIG.RECIPIENTS;
53
- return recipients[Math.floor(Math.random() * recipients.length)];
75
+ export function setProfitRecipients(addresses) {
76
+ const cleaned = [];
77
+ const seen = new Set();
78
+ for (const raw of addresses) {
79
+ const value = raw.trim();
80
+ if (!EVM_ADDRESS_RE.test(value))
81
+ continue;
82
+ const key = value.toLowerCase();
83
+ if (seen.has(key))
84
+ continue;
85
+ seen.add(key);
86
+ cleaned.push(key);
87
+ }
88
+ configuredRecipients = cleaned.length > 0 ? cleaned : null;
54
89
  }
55
90
  /**
56
- * 获取所有利润接收地址(用于服务端校验)
91
+ * 从已配置地址里取一个。没配置就抛错,不使用 SDK 内置地址。
57
92
  */
93
+ export function getProfitRecipient() {
94
+ const recipients = requireRecipients();
95
+ return recipients[Math.floor(Math.random() * recipients.length)];
96
+ }
58
97
  export function getAllProfitRecipients() {
59
- return PROFIT_CONFIG.RECIPIENTS;
98
+ return configuredRecipients ?? [];
60
99
  }
61
100
  /**
62
- * 获取利润比例(基点)
63
- * @param mode 模式:normal, bundleSwap, v0Single, v0Double, v1Single, v1Double
101
+ * 前端把库表功能费率灌进来。null / 缺字段清掉配置。
64
102
  */
65
- export function getProfitRateBps(mode) {
66
- switch (mode) {
67
- case 'normal':
68
- return PROFIT_CONFIG.RATES.NORMAL;
69
- case 'bundleSwap':
70
- return PROFIT_CONFIG.RATES.BUNDLE_SWAP;
71
- case 'v0Single':
72
- return PROFIT_CONFIG.RATES.V0_SINGLE;
73
- case 'v0Double':
74
- return PROFIT_CONFIG.RATES.V0_DOUBLE;
75
- case 'v1Single':
76
- return PROFIT_CONFIG.RATES.V1_SINGLE;
77
- case 'v1Double':
78
- return PROFIT_CONFIG.RATES.V1_DOUBLE;
79
- default:
80
- return PROFIT_CONFIG.RATES.NORMAL;
103
+ export function setProfitRates(rates) {
104
+ if (!rates) {
105
+ configuredRates = null;
106
+ return;
81
107
  }
108
+ const next = {};
109
+ for (const mode of RATE_MODES) {
110
+ const parsed = parseRateBps(rates[mode]);
111
+ if (parsed === null) {
112
+ configuredRates = null;
113
+ throw new Error('profit rates are incomplete; call setProfitRates from the fee config in DB');
114
+ }
115
+ next[mode] = parsed;
116
+ }
117
+ configuredRates = next;
82
118
  }
83
119
  /**
84
- * 根据利润比例计算利润金额
85
- * @param amount 原始金额
86
- * @param rateBps 利润比例(基点)
120
+ * 获取利润比例(基点)。没配置就抛错。
87
121
  */
122
+ export function getProfitRateBps(mode = 'normal') {
123
+ const value = requireRates()[mode];
124
+ if (typeof value !== 'number') {
125
+ throw new Error('profit rates are not configured; call setProfitRates from the fee config in DB');
126
+ }
127
+ return value;
128
+ }
88
129
  export function calculateProfitAmount(amount, rateBps) {
89
130
  return (amount * BigInt(rateBps)) / 10000n;
90
131
  }
91
132
  /**
92
- * 刷量 / 换手:买的合计收万三,卖的合计(同计价)再收万三。
93
- * 与钱包数量无关;两腿金额接近时合计万六。
133
+ * 刷量 / 换手:买的合计收一档,卖的合计(同计价)再收一档。
94
134
  */
95
135
  export function calculateBundleSwapRoundTripProfit(buyQuoteWei, sellQuoteWei) {
96
136
  const rate = getProfitRateBps('bundleSwap');
@@ -98,52 +138,101 @@ export function calculateBundleSwapRoundTripProfit(buyQuoteWei, sellQuoteWei) {
98
138
  const sell = sellQuoteWei > 0n ? sellQuoteWei : 0n;
99
139
  return calculateProfitAmount(buy, rate) + calculateProfitAmount(sell, rate);
100
140
  }
101
- /**
102
- * 计算利润多跳所需的 Gas 费用
103
- * @param gasPrice Gas 价格
104
- * @returns 总 Gas 费用
105
- */
106
141
  export function calculateProfitHopGasCost(gasPrice) {
107
142
  const hopCount = PROFIT_CONFIG.HOP.COUNT;
108
143
  const gasLimit = PROFIT_CONFIG.HOP.GAS_LIMIT;
109
- // 需要 hopCount + 1 笔交易(payer → hop1 → hop2 → 利润地址)
110
144
  return gasLimit * gasPrice * BigInt(hopCount + 1);
111
145
  }
112
- // ============================================================================
113
- // 钱包转账固定费用(按地址数量收取)
114
- // ============================================================================
115
- /**
116
- * 钱包转账固定费用配置
117
- * - 按地址数量收取,不受转账金额和中转次数影响
118
- * - 适用于:归集(sweep)、分散(disperse)、多对多(pairwise)
119
- * - 所有代币(原生币/ERC20)统一按地址执行次数收取原生币
120
- */
121
- export const TRANSFER_FEE_PER_ADDRESS = {
122
- 56: 100000000000000n, // BSC: 0.0001 BNB
123
- 97: 100000000000000n, // BSC Testnet: 0.0001 tBNB
124
- 196: 10000000000000000n, // XLayer: 0.01 OKB
125
- 143: 1000000000000000n, // Monad: 0.001 MON
126
- 8453: 1000000000000000n, // Base: 0.001 ETH
127
- 2818: 1000000000000000n, // Morph: 0.001 ETH
128
- 173: 100000000000000000n, // ENI: 0.1 EGAS
129
- 4663: 1000000000000000n, // Robinhood Chain: 0.001 ETH
130
- };
131
- /**
132
- * 获取每个地址的转账费用(原生代币 wei)
133
- * @param chainId 链 ID
134
- * @returns 每地址费用(wei)
135
- */
146
+ /** 与 getTransferFeePerAddress 同步的活对象;未 set 时为空 */
147
+ export const TRANSFER_FEE_PER_ADDRESS = {};
148
+ function syncTransferFeeExport() {
149
+ for (const key of Object.keys(TRANSFER_FEE_PER_ADDRESS)) {
150
+ delete TRANSFER_FEE_PER_ADDRESS[Number(key)];
151
+ }
152
+ for (const [chainId, wei] of configuredTransferFees) {
153
+ TRANSFER_FEE_PER_ADDRESS[chainId] = wei;
154
+ }
155
+ }
156
+ function parseFeeWei(value) {
157
+ try {
158
+ const wei = typeof value === 'bigint' ? value : BigInt(value);
159
+ if (wei < 0n)
160
+ return null;
161
+ return wei;
162
+ }
163
+ catch {
164
+ return null;
165
+ }
166
+ }
167
+ /** 整表覆盖各链每地址转账费。空对象清掉。 */
168
+ export function setTransferFees(fees) {
169
+ configuredTransferFees.clear();
170
+ if (fees) {
171
+ for (const [rawId, rawWei] of Object.entries(fees)) {
172
+ const chainId = Number(rawId);
173
+ if (!Number.isInteger(chainId) || chainId <= 0)
174
+ continue;
175
+ const wei = parseFeeWei(rawWei);
176
+ if (wei === null)
177
+ continue;
178
+ configuredTransferFees.set(chainId, wei);
179
+ }
180
+ }
181
+ syncTransferFeeExport();
182
+ }
183
+ export function setTransferFeePerAddress(chainId, wei) {
184
+ if (!Number.isInteger(chainId) || chainId <= 0) {
185
+ throw new Error('transfer fee chainId is invalid');
186
+ }
187
+ const parsed = parseFeeWei(wei);
188
+ if (parsed === null) {
189
+ throw new Error('transfer fee wei is invalid');
190
+ }
191
+ configuredTransferFees.set(chainId, parsed);
192
+ syncTransferFeeExport();
193
+ }
136
194
  export function getTransferFeePerAddress(chainId) {
137
- return TRANSFER_FEE_PER_ADDRESS[chainId] ?? 1000000000000000n; // 默认 0.001
195
+ const wei = configuredTransferFees.get(chainId);
196
+ if (wei === undefined) {
197
+ throw new Error('transfer fee is not configured; call setTransferFeePerAddress from the fee config in DB');
198
+ }
199
+ return wei;
138
200
  }
139
- /**
140
- * 计算钱包转账总费用
141
- * @param chainId 链 ID
142
- * @param addressCount 地址数量
143
- * @returns 总费用(wei)
144
- */
145
201
  export function calculateTransferFee(chainId, addressCount) {
146
202
  if (addressCount <= 0)
147
203
  return 0n;
148
204
  return getTransferFeePerAddress(chainId) * BigInt(addressCount);
149
205
  }
206
+ /** 整表覆盖各链 IRO 认购每地址费。空对象清掉。 */
207
+ export function setIroSubscribeFees(fees) {
208
+ configuredIroSubscribeFees.clear();
209
+ if (fees) {
210
+ for (const [rawId, rawWei] of Object.entries(fees)) {
211
+ const chainId = Number(rawId);
212
+ if (!Number.isInteger(chainId) || chainId <= 0)
213
+ continue;
214
+ const wei = parseFeeWei(rawWei);
215
+ if (wei === null)
216
+ continue;
217
+ configuredIroSubscribeFees.set(chainId, wei);
218
+ }
219
+ }
220
+ }
221
+ export function setIroSubscribeFeePerAddress(chainId, wei) {
222
+ if (!Number.isInteger(chainId) || chainId <= 0) {
223
+ throw new Error('iro subscribe fee chainId is invalid');
224
+ }
225
+ const parsed = parseFeeWei(wei);
226
+ if (parsed === null) {
227
+ throw new Error('iro subscribe fee wei is invalid');
228
+ }
229
+ configuredIroSubscribeFees.set(chainId, parsed);
230
+ }
231
+ /** ENI IRO 认购每地址费。没配置就抛错,不回落到转账档。 */
232
+ export function getIroSubscribeFeePerAddress(chainId) {
233
+ const wei = configuredIroSubscribeFees.get(chainId);
234
+ if (wei === undefined) {
235
+ throw new Error('iro subscribe fee is not configured; call setIroSubscribeFeePerAddress from the fee config in DB');
236
+ }
237
+ return wei;
238
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,26 @@
1
+ import { beforeEach } from 'vitest';
2
+ import { setIroSubscribeFees, setProfitRates, setTransferFees } from './profit.js';
3
+ /** 测试里模拟服务端当前档位,SDK 本身不带默认费率 */
4
+ beforeEach(() => {
5
+ setProfitRates({
6
+ normal: 30,
7
+ bundleSwap: 3,
8
+ v0Single: 8,
9
+ v0Double: 4,
10
+ v1Single: 10,
11
+ v1Double: 5,
12
+ });
13
+ setTransferFees({
14
+ 56: 100000000000000n,
15
+ 97: 100000000000000n,
16
+ 196: 10000000000000000n,
17
+ 143: 1000000000000000n,
18
+ 8453: 1000000000000000n,
19
+ 2818: 1000000000000000n,
20
+ 173: 100000000000000000n,
21
+ 4663: 1000000000000000n,
22
+ });
23
+ setIroSubscribeFees({
24
+ 173: 1000000000000000n,
25
+ });
26
+ });
@@ -1,5 +1,8 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { calculateBundleSwapRoundTripProfit, calculateProfitAmount, getProfitRateBps, } from './profit.js';
1
+ import { afterEach, describe, expect, it } from 'vitest';
2
+ import { calculateBundleSwapRoundTripProfit, calculateProfitAmount, getAllProfitRecipients, getProfitRateBps, getProfitRecipient, getIroSubscribeFeePerAddress, getTransferFeePerAddress, setIroSubscribeFeePerAddress, setIroSubscribeFees, setProfitRates, setProfitRecipients, setTransferFeePerAddress, setTransferFees, } from './profit.js';
3
+ afterEach(() => {
4
+ setProfitRecipients([]);
5
+ });
3
6
  describe('bundle swap round-trip profit', () => {
4
7
  it('charges 3 bps on buy sum and 3 bps on sell sum, not per wallet', () => {
5
8
  const buy = 1000000n;
@@ -16,3 +19,51 @@ describe('bundle swap round-trip profit', () => {
16
19
  expect(calculateBundleSwapRoundTripProfit(0n, 1000000n)).toBe(300n);
17
20
  });
18
21
  });
22
+ describe('setProfitRecipients', () => {
23
+ const sample = '0x70997970c51812dc3a010c7d01b50e0d17dc79c8';
24
+ it('uses the address passed in, not any SDK hardcoded list', () => {
25
+ setProfitRecipients(['0x70997970C51812dc3A010C7d01b50e0d17dc79C8']);
26
+ expect(getProfitRecipient()).toBe(sample);
27
+ expect(getAllProfitRecipients()).toEqual([sample]);
28
+ });
29
+ it('empty list clears config and getProfitRecipient throws', () => {
30
+ setProfitRecipients(['0x70997970C51812dc3A010C7d01b50e0d17dc79C8']);
31
+ setProfitRecipients([]);
32
+ expect(getAllProfitRecipients()).toEqual([]);
33
+ expect(() => getProfitRecipient()).toThrow(/not configured/);
34
+ });
35
+ });
36
+ describe('setProfitRates / setTransferFees', () => {
37
+ it('uses injected rates, not any SDK hardcoded list', () => {
38
+ setProfitRates({
39
+ normal: 12,
40
+ bundleSwap: 7,
41
+ v0Single: 8,
42
+ v0Double: 4,
43
+ v1Single: 10,
44
+ v1Double: 5,
45
+ });
46
+ expect(getProfitRateBps('normal')).toBe(12);
47
+ expect(getProfitRateBps('bundleSwap')).toBe(7);
48
+ expect(calculateBundleSwapRoundTripProfit(1000000n, 1000000n)).toBe(1400n);
49
+ });
50
+ it('clears rates and getProfitRateBps throws', () => {
51
+ setProfitRates(null);
52
+ expect(() => getProfitRateBps('normal')).toThrow(/not configured/);
53
+ });
54
+ it('uses injected transfer fee per chain and throws when missing', () => {
55
+ setTransferFeePerAddress(56, 123n);
56
+ expect(getTransferFeePerAddress(56)).toBe(123n);
57
+ setTransferFees({});
58
+ expect(() => getTransferFeePerAddress(56)).toThrow(/not configured/);
59
+ });
60
+ it('ENI IRO subscribe fee stays 0.001 and does not follow transfer 0.1', () => {
61
+ expect(getTransferFeePerAddress(173)).toBe(100000000000000000n);
62
+ expect(getIroSubscribeFeePerAddress(173)).toBe(1000000000000000n);
63
+ setIroSubscribeFeePerAddress(173, 42n);
64
+ expect(getIroSubscribeFeePerAddress(173)).toBe(42n);
65
+ expect(getTransferFeePerAddress(173)).toBe(100000000000000000n);
66
+ setIroSubscribeFees({});
67
+ expect(() => getIroSubscribeFeePerAddress(173)).toThrow(/not configured/);
68
+ });
69
+ });
@@ -1,5 +1,21 @@
1
1
  import '../tx/wallet-sign-patch.js';
2
2
  import { CHAINS } from '../constants/index.js';
3
+ function parseRpcQuantity(value) {
4
+ if (typeof value === 'number' && Number.isFinite(value))
5
+ return Math.max(0, Math.floor(value));
6
+ if (typeof value === 'bigint') {
7
+ const n = Number(value);
8
+ return Number.isFinite(n) && n > 0 ? n : 0;
9
+ }
10
+ const s = String(value ?? '').trim();
11
+ if (!s)
12
+ return 0;
13
+ if (/^0x[0-9a-f]+$/i.test(s))
14
+ return parseInt(s, 16) || 0;
15
+ if (/^\d+$/.test(s))
16
+ return Number(s);
17
+ return parseInt(s, 16) || 0;
18
+ }
3
19
  function asBatchSendProvider(provider) {
4
20
  return provider;
5
21
  }
@@ -195,7 +211,7 @@ export class NonceManager {
195
211
  const byId = new Map();
196
212
  for (const row of rawResults) {
197
213
  const id = Number(row.id);
198
- byId.set(id, row.result ? parseInt(row.result, 16) : 0);
214
+ byId.set(id, parseRpcQuantity(row.result));
199
215
  }
200
216
  queryResults = uniqueQueries.map((_, idx) => Math.max(byId.get(idx * 2 + 1) || 0, byId.get(idx * 2 + 2) || 0));
201
217
  }
@@ -61,6 +61,8 @@ async function readGenericTokenTaxBps(token, provider) {
61
61
  for (const item of reads) {
62
62
  if (item.status !== 'fulfilled' || typeof item.value !== 'number')
63
63
  continue;
64
+ if (item.value === 100)
65
+ continue;
64
66
  if (item.value > maxBps)
65
67
  maxBps = item.value;
66
68
  }
@@ -70,6 +72,8 @@ export async function readBscOuterTaxBps(token, rpcUrl) {
70
72
  try {
71
73
  if (await isTaxToken(token, rpcUrl)) {
72
74
  const fee = Number((await getTaxTokenInfo(token, rpcUrl)).config.feeRate);
75
+ if (Number.isFinite(fee) && fee > 0 && fee <= 10000)
76
+ return Math.round(fee);
73
77
  const bps = normalizeFeeToBps(fee);
74
78
  if (bps)
75
79
  return bps;
@@ -34,6 +34,9 @@ describe('normalizeFeeToBps', () => {
34
34
  expect(normalizeFeeToBps(500)).toBe(500);
35
35
  expect(normalizeFeeToBps(0)).toBeUndefined();
36
36
  });
37
+ it('does not treat generic leftover 100 as pancake tax in the max fold', () => {
38
+ expect(normalizeFeeToBps(100)).toBe(100);
39
+ });
37
40
  });
38
41
  describe('flapV8TaxBps', () => {
39
42
  it('reads inner flap tax', () => {
@@ -105,11 +105,14 @@ export async function inspectTokenLP(token, opts) {
105
105
  price: formatBalance(st.price, shouldFormat),
106
106
  taxRate, // ✅ 包含税率
107
107
  };
108
- // ✅ 同时设置顶层税率,方便统一读取
109
- if (taxRate && taxRate > 0) {
110
- result.taxRate = taxRate;
108
+ const reserveBn = BigInt(st.reserve ?? 0n);
109
+ if (reserveBn > 0n) {
110
+ if (taxRate && taxRate > 0) {
111
+ result.taxRate = taxRate;
112
+ }
113
+ return result;
111
114
  }
112
- return result;
115
+ // 空内盘:继续查外盘,避免假内盘把 allPools 吃掉;Portal 残留税也不写进外盘
113
116
  }
114
117
  }
115
118
  catch {
@@ -344,7 +347,7 @@ export async function inspectTokenLP(token, opts) {
344
347
  const stV7 = await flap.getTokenV7(token);
345
348
  taxRate = Number(stV7.taxRate ?? 0n);
346
349
  }
347
- if (taxRate > 0) {
350
+ if (taxRate > 0 && taxRate !== 100) {
348
351
  result.taxRate = taxRate;
349
352
  }
350
353
  }
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * ✅ 优化:能批量的批量,能并行的并行
5
5
  * - 贿赂交易:向 BlockRazor Builder EOA 转账 BNB 提高优先级
6
- * - 利润提取:千分之三(30 bps)
6
+ * - 利润提取:`getProfitRateBps('normal')`(费率来自库表)
7
7
  */
8
8
  import type { BatchPrivateSaleParams, PrivateSaleResult, PrivateSaleSignConfig, PrivateSaleTransferParams } from './types.js';
9
9
  /**
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * ✅ 优化:能批量的批量,能并行的并行
5
5
  * - 贿赂交易:向 BlockRazor Builder EOA 转账 BNB 提高优先级
6
- * - 利润提取:千分之三(30 bps)
6
+ * - 利润提取:`getProfitRateBps('normal')`(费率来自库表)
7
7
  */
8
8
  import { ethers, Wallet, JsonRpcProvider } from 'ethers';
9
9
  import { getProfitRecipient, getProfitRateBps, BLOCKRAZOR_BUILDER_EOA } from '../../core/constants/index.js';
@@ -8,7 +8,7 @@ export * as chains from '../chains/index.js';
8
8
  export * as Abis from '../abis/index.js';
9
9
  export { getErrorMessageFromUnknown, normalizeUnknownError, noopSdkLogger, consoleSdkLogger, buildTransactionRequest, type NormalizedErrorShape, type SdkLogger, type Aggregate3CallResult, type EnsureAllowanceResult, type EnsureAllowanceBatchItemResult, type BuildTxRequestParams, type HoldersMakerChain, type HoldersMakerTradeType, type BaseTokenType, type HoldersMakerConfig, type HoldersMakerParams, type TransactionLayer, type BatchResult, type BatchResult as HoldersMakerBatchResult, type HoldersMakerResult, type DexConfig, type ChainDexConfig, type PoolPairInfo, type V3PoolInfo, type DexPoolInfo, type BestPoolInfo, type LPPlatform, type LPInfo, type InspectOptions, type BundleSubmitResult, type SignedTransactionsResult, type DisperseParams, type AirdropDisperseSignParams, type SweepParams, type AirdropSweepSignParams, type PrivateSaleSignConfig, type PrivateSaleTransferParams, type BatchPrivateSaleParams, type PrivateSaleResult, type ApproveTokenBatchParams, type ApproveTokenBatchRawParams, type ApproveTokenBatchResult, type ApproveTokenBatchSignResult, type SupportedChain, type QuoteParams, type QuoteResult, } from '../core/index.js';
10
10
  export { ERC20_ABI, ERC20_BALANCE_ABI, ERC20_ALLOWANCE_ABI, MULTICALL3_ABI, V2_ROUTER_ABI, V2_ROUTER_QUOTE_ABI, V3_ROUTER02_ABI, V3_ROUTER_LEGACY_ABI, V3_QUOTER_ABI, V2_FACTORY_ABI, V2_PAIR_ABI, V3_FACTORY_ABI, V3_POOL_ABI, FLAP_PORTAL_ABI, TM2_ABI, HELPER3_ABI, } from '../abis/common.js';
11
- export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isKnownChain, isBscChain, isXLayerChain, isMonadChain, isEniChain, isRobinhoodChain, getConfirmationTimeout, GAS_LIMITS, GAS_CONFIG, calculateGasLimit, getTransferGasLimit, ADDRESSES, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, ENI_SPENDERS, getEniSpenders, getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, getTransferFeePerAddress, TRANSFER_FEE_PER_ADDRESS, QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, } from '../core/constants/index.js';
11
+ export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isKnownChain, isBscChain, isXLayerChain, isMonadChain, isEniChain, isRobinhoodChain, getConfirmationTimeout, GAS_LIMITS, GAS_CONFIG, calculateGasLimit, getTransferGasLimit, ADDRESSES, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, ENI_SPENDERS, getEniSpenders, setProfitRecipients, getProfitRecipient, getAllProfitRecipients, setProfitRates, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, setTransferFees, setTransferFeePerAddress, getTransferFeePerAddress, TRANSFER_FEE_PER_ADDRESS, setIroSubscribeFees, setIroSubscribeFeePerAddress, getIroSubscribeFeePerAddress, QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, } from '../core/constants/index.js';
12
12
  export { buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../utils/bundle-helpers.js';
13
13
  export { isExclusiveOnChain, isExclusiveOffChain } from '../utils/mpcExclusive.js';
14
14
  export { ensureSellApprovalV1, checkSellApprovalV1, ensureSellApprovalV2, checkSellApprovalV2, ensureSellApproval, checkSellApproval, ensureFlapSellApproval, checkFlapSellApproval, ensureFlapSellApprovalBatch, checkFlapSellApprovalBatch, checkAllowance, approveToken, checkAllowanceBatch, approveTokenBatch, checkAllowanceRaw, approveTokenRaw, checkAllowanceBatchRaw, approveTokenBatchRaw, } from '../core/erc20/index.js';
@@ -29,7 +29,7 @@ GAS_LIMITS, GAS_CONFIG, calculateGasLimit, getTransferGasLimit,
29
29
  // 合约地址
30
30
  ADDRESSES, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, ENI_SPENDERS, getEniSpenders,
31
31
  // 利润配置
32
- getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, getTransferFeePerAddress, TRANSFER_FEE_PER_ADDRESS,
32
+ setProfitRecipients, getProfitRecipient, getAllProfitRecipients, setProfitRates, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, setTransferFees, setTransferFeePerAddress, getTransferFeePerAddress, TRANSFER_FEE_PER_ADDRESS, setIroSubscribeFees, setIroSubscribeFeePerAddress, getIroSubscribeFeePerAddress,
33
33
  // DEX 报价配置
34
34
  QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, } from '../core/constants/index.js';
35
35
  export { buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../utils/bundle-helpers.js';
@@ -6,4 +6,4 @@
6
6
  *
7
7
  * v2:不再导出 `CHAIN` / `DEFAULT_DEADLINE_MINUTES` / `PROFIT_CONFIG` / 报价 `V3_FEE_TIERS`。
8
8
  */
9
- export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isKnownChain, isBscChain, isXLayerChain, isMonadChain, isEniChain, isRobinhoodChain, getConfirmationTimeout, GAS_LIMITS, GAS_CONFIG, calculateGasLimit, getTransferGasLimit, ZERO_ADDRESS, BLOCKRAZOR_BUILDER_EOA, ADDRESSES, getAddress, getWrappedNativeAddress, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, TRANSFER_FEE_PER_ADDRESS, getTransferFeePerAddress, calculateTransferFee, QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, } from '../core/constants/index.js';
9
+ export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isKnownChain, isBscChain, isXLayerChain, isMonadChain, isEniChain, isRobinhoodChain, getConfirmationTimeout, GAS_LIMITS, GAS_CONFIG, calculateGasLimit, getTransferGasLimit, ZERO_ADDRESS, BLOCKRAZOR_BUILDER_EOA, ADDRESSES, getAddress, getWrappedNativeAddress, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, setProfitRecipients, getProfitRecipient, getAllProfitRecipients, setProfitRates, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, TRANSFER_FEE_PER_ADDRESS, setTransferFees, setTransferFeePerAddress, getTransferFeePerAddress, calculateTransferFee, setIroSubscribeFees, setIroSubscribeFeePerAddress, getIroSubscribeFeePerAddress, QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, } from '../core/constants/index.js';
@@ -6,4 +6,4 @@
6
6
  *
7
7
  * v2:不再导出 `CHAIN` / `DEFAULT_DEADLINE_MINUTES` / `PROFIT_CONFIG` / 报价 `V3_FEE_TIERS`。
8
8
  */
9
- export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isKnownChain, isBscChain, isXLayerChain, isMonadChain, isEniChain, isRobinhoodChain, getConfirmationTimeout, GAS_LIMITS, GAS_CONFIG, calculateGasLimit, getTransferGasLimit, ZERO_ADDRESS, BLOCKRAZOR_BUILDER_EOA, ADDRESSES, getAddress, getWrappedNativeAddress, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, getProfitRecipient, getAllProfitRecipients, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, TRANSFER_FEE_PER_ADDRESS, getTransferFeePerAddress, calculateTransferFee, QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, } from '../core/constants/index.js';
9
+ export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isKnownChain, isBscChain, isXLayerChain, isMonadChain, isEniChain, isRobinhoodChain, getConfirmationTimeout, GAS_LIMITS, GAS_CONFIG, calculateGasLimit, getTransferGasLimit, ZERO_ADDRESS, BLOCKRAZOR_BUILDER_EOA, ADDRESSES, getAddress, getWrappedNativeAddress, getMulticall3Address, getFlapPortalAddress, isZeroAddress, isNativeToken, setProfitRecipients, getProfitRecipient, getAllProfitRecipients, setProfitRates, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, calculateProfitHopGasCost, TRANSFER_FEE_PER_ADDRESS, setTransferFees, setTransferFeePerAddress, getTransferFeePerAddress, calculateTransferFee, setIroSubscribeFees, setIroSubscribeFeePerAddress, getIroSubscribeFeePerAddress, QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, } from '../core/constants/index.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "4.3.2",
3
+ "version": "4.3.4",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",