four-flap-meme-sdk 1.4.91 → 1.4.93
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/index.d.ts +2 -0
- package/dist/index.js +24 -0
- package/dist/xlayer/aa-account.d.ts +240 -0
- package/dist/xlayer/aa-account.js +510 -0
- package/dist/xlayer/bundle.d.ts +93 -0
- package/dist/xlayer/bundle.js +472 -0
- package/dist/xlayer/bundler.d.ts +111 -0
- package/dist/xlayer/bundler.js +162 -0
- package/dist/xlayer/constants.d.ts +75 -0
- package/dist/xlayer/constants.js +145 -0
- package/dist/xlayer/dex.d.ts +132 -0
- package/dist/xlayer/dex.js +335 -0
- package/dist/xlayer/examples/bundle-buy-sell.d.ts +11 -0
- package/dist/xlayer/examples/bundle-buy-sell.js +194 -0
- package/dist/xlayer/index.d.ts +75 -0
- package/dist/xlayer/index.js +130 -0
- package/dist/xlayer/portal-ops.d.ts +152 -0
- package/dist/xlayer/portal-ops.js +239 -0
- package/dist/xlayer/types.d.ts +298 -0
- package/dist/xlayer/types.js +6 -0
- package/dist/xlayer/volume.d.ts +65 -0
- package/dist/xlayer/volume.js +235 -0
- package/package.json +1 -1
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XLayer SDK 类型定义
|
|
3
|
+
*
|
|
4
|
+
* 包含 ERC-4337 UserOperation、AA 账户、交易参数等核心类型
|
|
5
|
+
*/
|
|
6
|
+
import type { HexString } from './constants.js';
|
|
7
|
+
/**
|
|
8
|
+
* UserOperation v0.6 结构
|
|
9
|
+
* 用于 ERC-4337 EntryPoint v0.6
|
|
10
|
+
*/
|
|
11
|
+
export interface UserOperation {
|
|
12
|
+
sender: string;
|
|
13
|
+
nonce: HexString | string;
|
|
14
|
+
initCode: HexString | string;
|
|
15
|
+
callData: HexString | string;
|
|
16
|
+
callGasLimit: HexString | string;
|
|
17
|
+
verificationGasLimit: HexString | string;
|
|
18
|
+
preVerificationGas: HexString | string;
|
|
19
|
+
maxFeePerGas: HexString | string;
|
|
20
|
+
maxPriorityFeePerGas: HexString | string;
|
|
21
|
+
paymasterAndData: HexString | string;
|
|
22
|
+
signature: HexString | string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 签名后的 UserOperation(包含额外元数据)
|
|
26
|
+
*/
|
|
27
|
+
export interface SignedUserOp {
|
|
28
|
+
userOp: UserOperation;
|
|
29
|
+
userOpHash: string;
|
|
30
|
+
prefundWei: bigint;
|
|
31
|
+
sender: string;
|
|
32
|
+
ownerName?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Gas 估算结果(来自 Bundler)
|
|
36
|
+
*/
|
|
37
|
+
export interface GasEstimate {
|
|
38
|
+
callGasLimit: HexString;
|
|
39
|
+
verificationGasLimit: HexString;
|
|
40
|
+
preVerificationGas: HexString;
|
|
41
|
+
maxFeePerGas?: HexString;
|
|
42
|
+
maxPriorityFeePerGas?: HexString;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* XLayer SDK 基础配置
|
|
46
|
+
*/
|
|
47
|
+
export interface XLayerConfig {
|
|
48
|
+
/** RPC URL(默认使用公共节点) */
|
|
49
|
+
rpcUrl?: string;
|
|
50
|
+
/** Bundler URL(默认使用 Particle) */
|
|
51
|
+
bundlerUrl?: string;
|
|
52
|
+
/** Chain ID(默认 196) */
|
|
53
|
+
chainId?: number;
|
|
54
|
+
/** EntryPoint 地址 */
|
|
55
|
+
entryPoint?: string;
|
|
56
|
+
/** SimpleAccountFactory 地址 */
|
|
57
|
+
factory?: string;
|
|
58
|
+
/** Salt(用于 AA 账户派生) */
|
|
59
|
+
salt?: bigint;
|
|
60
|
+
/** Paymaster 地址(如果指定,不需要往 AA 转手续费) */
|
|
61
|
+
paymaster?: string;
|
|
62
|
+
/** Paymaster Data(与 paymaster 一起使用) */
|
|
63
|
+
paymasterData?: string;
|
|
64
|
+
/** 默认超时时间(毫秒) */
|
|
65
|
+
timeoutMs?: number;
|
|
66
|
+
/** Gas 估算安全余量倍数 */
|
|
67
|
+
gasLimitMultiplier?: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* AA 账户信息
|
|
71
|
+
*/
|
|
72
|
+
export interface AAAccount {
|
|
73
|
+
/** Owner EOA 地址 */
|
|
74
|
+
owner: string;
|
|
75
|
+
/** AA Sender 地址 */
|
|
76
|
+
sender: string;
|
|
77
|
+
/** 是否已部署 */
|
|
78
|
+
deployed: boolean;
|
|
79
|
+
/** OKB 余额 */
|
|
80
|
+
balance: bigint;
|
|
81
|
+
/** Nonce */
|
|
82
|
+
nonce: bigint;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Owner 钱包信息
|
|
86
|
+
*/
|
|
87
|
+
export interface OwnerInfo {
|
|
88
|
+
name: string;
|
|
89
|
+
privateKey: string;
|
|
90
|
+
address?: string;
|
|
91
|
+
sender?: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 买入参数
|
|
95
|
+
*/
|
|
96
|
+
export interface BuyParams {
|
|
97
|
+
/** Flap 代币地址 */
|
|
98
|
+
tokenAddress: string;
|
|
99
|
+
/** 买入金额(OKB,字符串格式) */
|
|
100
|
+
amountOkb: string;
|
|
101
|
+
/** 最小输出代币数量(默认 0) */
|
|
102
|
+
minOutputAmount?: bigint;
|
|
103
|
+
/** 滑点基点(默认 100 = 1%) */
|
|
104
|
+
slippageBps?: number;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 卖出参数
|
|
108
|
+
*/
|
|
109
|
+
export interface SellParams {
|
|
110
|
+
/** Flap 代币地址 */
|
|
111
|
+
tokenAddress: string;
|
|
112
|
+
/** 卖出代币数量(可选,默认全部) */
|
|
113
|
+
amount?: bigint;
|
|
114
|
+
/** 卖出比例(0-100,如 50 表示卖出 50%) */
|
|
115
|
+
sellPercent?: number;
|
|
116
|
+
/** 最小输出 OKB 数量(默认 0) */
|
|
117
|
+
minOutputAmount?: bigint;
|
|
118
|
+
/** 滑点基点(默认 100 = 1%) */
|
|
119
|
+
slippageBps?: number;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 捆绑买入参数
|
|
123
|
+
*/
|
|
124
|
+
export interface BundleBuyParams {
|
|
125
|
+
/** 代币地址 */
|
|
126
|
+
tokenAddress: string;
|
|
127
|
+
/** Owner 私钥列表 */
|
|
128
|
+
privateKeys: string[];
|
|
129
|
+
/** 每个 owner 的买入金额(OKB) */
|
|
130
|
+
buyAmounts: string[];
|
|
131
|
+
/** 是否将代币转回 owner EOA(默认 false) */
|
|
132
|
+
transferBackToOwner?: boolean;
|
|
133
|
+
/** 配置覆盖 */
|
|
134
|
+
config?: Partial<XLayerConfig>;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* 捆绑卖出参数
|
|
138
|
+
*/
|
|
139
|
+
export interface BundleSellParams {
|
|
140
|
+
/** 代币地址 */
|
|
141
|
+
tokenAddress: string;
|
|
142
|
+
/** Owner 私钥列表 */
|
|
143
|
+
privateKeys: string[];
|
|
144
|
+
/** 卖出比例(0-100,默认 100 全部卖出) */
|
|
145
|
+
sellPercent?: number;
|
|
146
|
+
/** 是否将 OKB 归集回 owner EOA(默认 true) */
|
|
147
|
+
withdrawToOwner?: boolean;
|
|
148
|
+
/** 归集时保留的最小 OKB 余额 */
|
|
149
|
+
withdrawReserve?: string;
|
|
150
|
+
/** 配置覆盖 */
|
|
151
|
+
config?: Partial<XLayerConfig>;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* 捆绑买卖参数(先买后卖)
|
|
155
|
+
*/
|
|
156
|
+
export interface BundleBuySellParams {
|
|
157
|
+
/** 代币地址 */
|
|
158
|
+
tokenAddress: string;
|
|
159
|
+
/** Owner 私钥列表 */
|
|
160
|
+
privateKeys: string[];
|
|
161
|
+
/** 每个 owner 的买入金额(OKB) */
|
|
162
|
+
buyAmounts: string[];
|
|
163
|
+
/** 卖出比例(0-100,默认 100 全部卖出) */
|
|
164
|
+
sellPercent?: number;
|
|
165
|
+
/** 是否将 OKB 归集回 owner EOA(默认 true) */
|
|
166
|
+
withdrawToOwner?: boolean;
|
|
167
|
+
/** 归集时保留的最小 OKB 余额 */
|
|
168
|
+
withdrawReserve?: string;
|
|
169
|
+
/** 配置覆盖 */
|
|
170
|
+
config?: Partial<XLayerConfig>;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* 刷量参数
|
|
174
|
+
*/
|
|
175
|
+
export interface VolumeParams {
|
|
176
|
+
/** 代币地址 */
|
|
177
|
+
tokenAddress: string;
|
|
178
|
+
/** Owner 私钥列表 */
|
|
179
|
+
privateKeys: string[];
|
|
180
|
+
/** 每轮买入金额(OKB) */
|
|
181
|
+
buyAmountPerRound: string;
|
|
182
|
+
/** 刷量轮数 */
|
|
183
|
+
rounds: number;
|
|
184
|
+
/** 每轮间隔时间(毫秒,默认 3000) */
|
|
185
|
+
intervalMs?: number;
|
|
186
|
+
/** 每轮是否立即卖出(默认 true) */
|
|
187
|
+
sellImmediately?: boolean;
|
|
188
|
+
/** 配置覆盖 */
|
|
189
|
+
config?: Partial<XLayerConfig>;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* handleOps 执行结果
|
|
193
|
+
*/
|
|
194
|
+
export interface HandleOpsResult {
|
|
195
|
+
/** 交易哈希 */
|
|
196
|
+
txHash: string;
|
|
197
|
+
/** 区块号 */
|
|
198
|
+
blockNumber: number;
|
|
199
|
+
/** 交易状态 */
|
|
200
|
+
status: number;
|
|
201
|
+
/** UserOperationEvent 列表 */
|
|
202
|
+
userOpEvents: UserOpEventResult[];
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* UserOperationEvent 解析结果
|
|
206
|
+
*/
|
|
207
|
+
export interface UserOpEventResult {
|
|
208
|
+
userOpHash: string;
|
|
209
|
+
sender: string;
|
|
210
|
+
paymaster: string;
|
|
211
|
+
success: boolean;
|
|
212
|
+
actualGasCost: bigint;
|
|
213
|
+
actualGasUsed: bigint;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* 捆绑买入结果
|
|
217
|
+
*/
|
|
218
|
+
export interface BundleBuyResult {
|
|
219
|
+
/** 买入交易结果 */
|
|
220
|
+
buyResult: HandleOpsResult;
|
|
221
|
+
/** 转账交易结果(如果 transferBackToOwner) */
|
|
222
|
+
transferResult?: HandleOpsResult;
|
|
223
|
+
/** 各 sender 的代币余额 */
|
|
224
|
+
tokenBalances: Map<string, bigint>;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* 捆绑卖出结果
|
|
228
|
+
*/
|
|
229
|
+
export interface BundleSellResult {
|
|
230
|
+
/** 授权交易结果(如果需要) */
|
|
231
|
+
approveResult?: HandleOpsResult;
|
|
232
|
+
/** 卖出交易结果 */
|
|
233
|
+
sellResult: HandleOpsResult;
|
|
234
|
+
/** 归集交易结果(如果 withdrawToOwner) */
|
|
235
|
+
withdrawResult?: HandleOpsResult;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* 捆绑买卖结果
|
|
239
|
+
*/
|
|
240
|
+
export interface BundleBuySellResult {
|
|
241
|
+
/** 买入阶段结果 */
|
|
242
|
+
buyResult: HandleOpsResult;
|
|
243
|
+
/** 授权阶段结果(如果需要) */
|
|
244
|
+
approveResult?: HandleOpsResult;
|
|
245
|
+
/** 卖出阶段结果 */
|
|
246
|
+
sellResult: HandleOpsResult;
|
|
247
|
+
/** 归集阶段结果(如果 withdrawToOwner) */
|
|
248
|
+
withdrawResult?: HandleOpsResult;
|
|
249
|
+
/** 各 sender 的最终 OKB 余额 */
|
|
250
|
+
finalBalances: Map<string, bigint>;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* 刷量结果
|
|
254
|
+
*/
|
|
255
|
+
export interface VolumeResult {
|
|
256
|
+
/** 成功轮数 */
|
|
257
|
+
successRounds: number;
|
|
258
|
+
/** 失败轮数 */
|
|
259
|
+
failedRounds: number;
|
|
260
|
+
/** 每轮结果 */
|
|
261
|
+
roundResults: BundleBuySellResult[];
|
|
262
|
+
/** 总交易量(OKB) */
|
|
263
|
+
totalVolume: bigint;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* 外盘(PotatoSwap)交易参数
|
|
267
|
+
*/
|
|
268
|
+
export interface DexSwapParams {
|
|
269
|
+
/** 输入代币地址(零地址表示 OKB) */
|
|
270
|
+
inputToken: string;
|
|
271
|
+
/** 输出代币地址(零地址表示 OKB) */
|
|
272
|
+
outputToken: string;
|
|
273
|
+
/** 输入金额 */
|
|
274
|
+
inputAmount: bigint;
|
|
275
|
+
/** 最小输出金额 */
|
|
276
|
+
minOutputAmount: bigint;
|
|
277
|
+
/** 交易截止时间(默认 20 分钟) */
|
|
278
|
+
deadline?: number;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* 外盘交易结果
|
|
282
|
+
*/
|
|
283
|
+
export interface DexSwapResult {
|
|
284
|
+
txHash: string;
|
|
285
|
+
inputAmount: bigint;
|
|
286
|
+
outputAmount: bigint;
|
|
287
|
+
gasUsed: bigint;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* 深度 Partial 类型
|
|
291
|
+
*/
|
|
292
|
+
export type DeepPartial<T> = {
|
|
293
|
+
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
|
|
294
|
+
};
|
|
295
|
+
/**
|
|
296
|
+
* 必需的配置字段
|
|
297
|
+
*/
|
|
298
|
+
export type RequiredConfig = Required<Pick<XLayerConfig, 'rpcUrl' | 'bundlerUrl' | 'chainId' | 'entryPoint' | 'factory'>>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XLayer 刷量/做市 SDK
|
|
3
|
+
*
|
|
4
|
+
* 通过多轮买卖循环实现刷量:
|
|
5
|
+
* - 多地址轮转刷量
|
|
6
|
+
* - 可配置买卖间隔
|
|
7
|
+
* - 支持部分卖出
|
|
8
|
+
* - 自动归集
|
|
9
|
+
*/
|
|
10
|
+
import type { XLayerConfig, VolumeParams, VolumeResult, BundleBuySellResult } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* 刷量执行器
|
|
13
|
+
*
|
|
14
|
+
* 通过多轮买卖循环制造交易量
|
|
15
|
+
*/
|
|
16
|
+
export declare class VolumeExecutor {
|
|
17
|
+
private bundleExecutor;
|
|
18
|
+
private config;
|
|
19
|
+
constructor(config?: XLayerConfig);
|
|
20
|
+
/**
|
|
21
|
+
* 执行刷量
|
|
22
|
+
*
|
|
23
|
+
* @param params 刷量参数
|
|
24
|
+
* @returns 刷量结果
|
|
25
|
+
*/
|
|
26
|
+
execute(params: VolumeParams): Promise<VolumeResult>;
|
|
27
|
+
/**
|
|
28
|
+
* 单轮刷量(简化接口)
|
|
29
|
+
*/
|
|
30
|
+
singleRound(params: Omit<VolumeParams, 'rounds' | 'intervalMs'>): Promise<BundleBuySellResult>;
|
|
31
|
+
/**
|
|
32
|
+
* 轮转刷量(每轮使用不同地址子集)
|
|
33
|
+
*/
|
|
34
|
+
rotatingVolume(params: {
|
|
35
|
+
tokenAddress: string;
|
|
36
|
+
allPrivateKeys: string[];
|
|
37
|
+
ownersPerRound: number;
|
|
38
|
+
buyAmountPerOwner: string;
|
|
39
|
+
rounds: number;
|
|
40
|
+
intervalMs?: number;
|
|
41
|
+
}): Promise<VolumeResult>;
|
|
42
|
+
/**
|
|
43
|
+
* 随机金额刷量
|
|
44
|
+
*/
|
|
45
|
+
randomAmountVolume(params: {
|
|
46
|
+
tokenAddress: string;
|
|
47
|
+
privateKeys: string[];
|
|
48
|
+
minBuyAmount: string;
|
|
49
|
+
maxBuyAmount: string;
|
|
50
|
+
rounds: number;
|
|
51
|
+
intervalMs?: number;
|
|
52
|
+
}): Promise<VolumeResult>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 创建刷量执行器
|
|
56
|
+
*/
|
|
57
|
+
export declare function createVolumeExecutor(config?: XLayerConfig): VolumeExecutor;
|
|
58
|
+
/**
|
|
59
|
+
* 快速刷量
|
|
60
|
+
*/
|
|
61
|
+
export declare function makeVolume(params: VolumeParams): Promise<VolumeResult>;
|
|
62
|
+
/**
|
|
63
|
+
* 单轮刷量
|
|
64
|
+
*/
|
|
65
|
+
export declare function singleRoundVolume(params: Omit<VolumeParams, 'rounds' | 'intervalMs'>): Promise<BundleBuySellResult>;
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XLayer 刷量/做市 SDK
|
|
3
|
+
*
|
|
4
|
+
* 通过多轮买卖循环实现刷量:
|
|
5
|
+
* - 多地址轮转刷量
|
|
6
|
+
* - 可配置买卖间隔
|
|
7
|
+
* - 支持部分卖出
|
|
8
|
+
* - 自动归集
|
|
9
|
+
*/
|
|
10
|
+
import { createBundleExecutor } from './bundle.js';
|
|
11
|
+
import { parseOkb, formatOkb } from './portal-ops.js';
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// 刷量执行器
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* 刷量执行器
|
|
17
|
+
*
|
|
18
|
+
* 通过多轮买卖循环制造交易量
|
|
19
|
+
*/
|
|
20
|
+
export class VolumeExecutor {
|
|
21
|
+
constructor(config = {}) {
|
|
22
|
+
this.config = config;
|
|
23
|
+
this.bundleExecutor = createBundleExecutor(config);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 执行刷量
|
|
27
|
+
*
|
|
28
|
+
* @param params 刷量参数
|
|
29
|
+
* @returns 刷量结果
|
|
30
|
+
*/
|
|
31
|
+
async execute(params) {
|
|
32
|
+
const { tokenAddress, privateKeys, buyAmountPerRound, rounds, intervalMs = 3000, sellImmediately = true, } = params;
|
|
33
|
+
console.log('=== XLayer Volume Maker ===');
|
|
34
|
+
console.log('token:', tokenAddress);
|
|
35
|
+
console.log('owners:', privateKeys.length);
|
|
36
|
+
console.log('rounds:', rounds);
|
|
37
|
+
console.log('buyAmountPerRound:', buyAmountPerRound, 'OKB');
|
|
38
|
+
console.log('intervalMs:', intervalMs);
|
|
39
|
+
console.log('sellImmediately:', sellImmediately);
|
|
40
|
+
const roundResults = [];
|
|
41
|
+
let successRounds = 0;
|
|
42
|
+
let failedRounds = 0;
|
|
43
|
+
let totalVolume = 0n;
|
|
44
|
+
const buyWei = parseOkb(buyAmountPerRound);
|
|
45
|
+
for (let round = 0; round < rounds; round++) {
|
|
46
|
+
console.log(`\n========== Round ${round + 1}/${rounds} ==========`);
|
|
47
|
+
try {
|
|
48
|
+
// 为每个 owner 分配相同的买入金额
|
|
49
|
+
const buyAmounts = privateKeys.map(() => buyAmountPerRound);
|
|
50
|
+
const result = await this.bundleExecutor.bundleBuySell({
|
|
51
|
+
tokenAddress,
|
|
52
|
+
privateKeys,
|
|
53
|
+
buyAmounts,
|
|
54
|
+
sellPercent: sellImmediately ? 100 : 0,
|
|
55
|
+
withdrawToOwner: true,
|
|
56
|
+
config: this.config,
|
|
57
|
+
});
|
|
58
|
+
roundResults.push(result);
|
|
59
|
+
successRounds++;
|
|
60
|
+
totalVolume += buyWei * BigInt(privateKeys.length);
|
|
61
|
+
console.log(`Round ${round + 1} 完成`);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error(`Round ${round + 1} 失败:`, error);
|
|
65
|
+
failedRounds++;
|
|
66
|
+
}
|
|
67
|
+
// 等待间隔
|
|
68
|
+
if (round < rounds - 1 && intervalMs > 0) {
|
|
69
|
+
console.log(`等待 ${intervalMs}ms...`);
|
|
70
|
+
await sleep(intervalMs);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
console.log('\n=== Volume Summary ===');
|
|
74
|
+
console.log('成功轮数:', successRounds);
|
|
75
|
+
console.log('失败轮数:', failedRounds);
|
|
76
|
+
console.log('总交易量:', formatOkb(totalVolume), 'OKB');
|
|
77
|
+
return {
|
|
78
|
+
successRounds,
|
|
79
|
+
failedRounds,
|
|
80
|
+
roundResults,
|
|
81
|
+
totalVolume,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* 单轮刷量(简化接口)
|
|
86
|
+
*/
|
|
87
|
+
async singleRound(params) {
|
|
88
|
+
const buyAmounts = params.privateKeys.map(() => params.buyAmountPerRound);
|
|
89
|
+
return this.bundleExecutor.bundleBuySell({
|
|
90
|
+
tokenAddress: params.tokenAddress,
|
|
91
|
+
privateKeys: params.privateKeys,
|
|
92
|
+
buyAmounts,
|
|
93
|
+
sellPercent: params.sellImmediately !== false ? 100 : 0,
|
|
94
|
+
withdrawToOwner: true,
|
|
95
|
+
config: this.config,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* 轮转刷量(每轮使用不同地址子集)
|
|
100
|
+
*/
|
|
101
|
+
async rotatingVolume(params) {
|
|
102
|
+
const { tokenAddress, allPrivateKeys, ownersPerRound, buyAmountPerOwner, rounds, intervalMs = 3000, } = params;
|
|
103
|
+
console.log('=== XLayer Rotating Volume ===');
|
|
104
|
+
console.log('token:', tokenAddress);
|
|
105
|
+
console.log('totalOwners:', allPrivateKeys.length);
|
|
106
|
+
console.log('ownersPerRound:', ownersPerRound);
|
|
107
|
+
console.log('rounds:', rounds);
|
|
108
|
+
const roundResults = [];
|
|
109
|
+
let successRounds = 0;
|
|
110
|
+
let failedRounds = 0;
|
|
111
|
+
let totalVolume = 0n;
|
|
112
|
+
const buyWei = parseOkb(buyAmountPerOwner);
|
|
113
|
+
for (let round = 0; round < rounds; round++) {
|
|
114
|
+
// 轮转选择地址
|
|
115
|
+
const startIdx = (round * ownersPerRound) % allPrivateKeys.length;
|
|
116
|
+
const selectedKeys = [];
|
|
117
|
+
for (let i = 0; i < ownersPerRound; i++) {
|
|
118
|
+
const idx = (startIdx + i) % allPrivateKeys.length;
|
|
119
|
+
selectedKeys.push(allPrivateKeys[idx]);
|
|
120
|
+
}
|
|
121
|
+
console.log(`\n========== Round ${round + 1}/${rounds} (owners: ${startIdx}-${startIdx + ownersPerRound - 1}) ==========`);
|
|
122
|
+
try {
|
|
123
|
+
const buyAmounts = selectedKeys.map(() => buyAmountPerOwner);
|
|
124
|
+
const result = await this.bundleExecutor.bundleBuySell({
|
|
125
|
+
tokenAddress,
|
|
126
|
+
privateKeys: selectedKeys,
|
|
127
|
+
buyAmounts,
|
|
128
|
+
sellPercent: 100,
|
|
129
|
+
withdrawToOwner: true,
|
|
130
|
+
config: this.config,
|
|
131
|
+
});
|
|
132
|
+
roundResults.push(result);
|
|
133
|
+
successRounds++;
|
|
134
|
+
totalVolume += buyWei * BigInt(ownersPerRound);
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
console.error(`Round ${round + 1} 失败:`, error);
|
|
138
|
+
failedRounds++;
|
|
139
|
+
}
|
|
140
|
+
if (round < rounds - 1 && intervalMs > 0) {
|
|
141
|
+
await sleep(intervalMs);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
successRounds,
|
|
146
|
+
failedRounds,
|
|
147
|
+
roundResults,
|
|
148
|
+
totalVolume,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* 随机金额刷量
|
|
153
|
+
*/
|
|
154
|
+
async randomAmountVolume(params) {
|
|
155
|
+
const { tokenAddress, privateKeys, minBuyAmount, maxBuyAmount, rounds, intervalMs = 3000, } = params;
|
|
156
|
+
console.log('=== XLayer Random Amount Volume ===');
|
|
157
|
+
console.log('token:', tokenAddress);
|
|
158
|
+
console.log('owners:', privateKeys.length);
|
|
159
|
+
console.log('buyRange:', minBuyAmount, '-', maxBuyAmount, 'OKB');
|
|
160
|
+
console.log('rounds:', rounds);
|
|
161
|
+
const roundResults = [];
|
|
162
|
+
let successRounds = 0;
|
|
163
|
+
let failedRounds = 0;
|
|
164
|
+
let totalVolume = 0n;
|
|
165
|
+
const minWei = parseOkb(minBuyAmount);
|
|
166
|
+
const maxWei = parseOkb(maxBuyAmount);
|
|
167
|
+
const range = maxWei - minWei;
|
|
168
|
+
for (let round = 0; round < rounds; round++) {
|
|
169
|
+
console.log(`\n========== Round ${round + 1}/${rounds} ==========`);
|
|
170
|
+
try {
|
|
171
|
+
// 为每个 owner 生成随机金额
|
|
172
|
+
const buyAmounts = [];
|
|
173
|
+
let roundVolume = 0n;
|
|
174
|
+
for (let i = 0; i < privateKeys.length; i++) {
|
|
175
|
+
const randomWei = minWei + BigInt(Math.floor(Math.random() * Number(range)));
|
|
176
|
+
buyAmounts.push(formatOkb(randomWei));
|
|
177
|
+
roundVolume += randomWei;
|
|
178
|
+
}
|
|
179
|
+
const result = await this.bundleExecutor.bundleBuySell({
|
|
180
|
+
tokenAddress,
|
|
181
|
+
privateKeys,
|
|
182
|
+
buyAmounts,
|
|
183
|
+
sellPercent: 100,
|
|
184
|
+
withdrawToOwner: true,
|
|
185
|
+
config: this.config,
|
|
186
|
+
});
|
|
187
|
+
roundResults.push(result);
|
|
188
|
+
successRounds++;
|
|
189
|
+
totalVolume += roundVolume;
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
console.error(`Round ${round + 1} 失败:`, error);
|
|
193
|
+
failedRounds++;
|
|
194
|
+
}
|
|
195
|
+
if (round < rounds - 1 && intervalMs > 0) {
|
|
196
|
+
await sleep(intervalMs);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
successRounds,
|
|
201
|
+
failedRounds,
|
|
202
|
+
roundResults,
|
|
203
|
+
totalVolume,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// ============================================================================
|
|
208
|
+
// 便捷函数
|
|
209
|
+
// ============================================================================
|
|
210
|
+
/**
|
|
211
|
+
* 创建刷量执行器
|
|
212
|
+
*/
|
|
213
|
+
export function createVolumeExecutor(config) {
|
|
214
|
+
return new VolumeExecutor(config);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* 快速刷量
|
|
218
|
+
*/
|
|
219
|
+
export async function makeVolume(params) {
|
|
220
|
+
const executor = createVolumeExecutor(params.config);
|
|
221
|
+
return executor.execute(params);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* 单轮刷量
|
|
225
|
+
*/
|
|
226
|
+
export async function singleRoundVolume(params) {
|
|
227
|
+
const executor = createVolumeExecutor(params.config);
|
|
228
|
+
return executor.singleRound(params);
|
|
229
|
+
}
|
|
230
|
+
// ============================================================================
|
|
231
|
+
// 工具函数
|
|
232
|
+
// ============================================================================
|
|
233
|
+
function sleep(ms) {
|
|
234
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
235
|
+
}
|