four-flap-meme-sdk 1.9.28 → 1.9.30

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.
@@ -7,4 +7,4 @@ export * from './constants.js';
7
7
  export * as platforms from './platforms/index.js';
8
8
  export { disperseWithBundleMerkle, sweepWithBundleMerkle, pairwiseTransferWithBundleMerkle, fourBundleSwapMerkle, fourBatchSwapMerkle, fourQuickBatchSwapMerkle, fourBundleBuyFirstMerkle, submitBundleToMerkle, submitBundleToBlockRazor, submitDirectToRpc, submitDirectToRpcSmart, approveFourTokenManagerBatch, } from './platforms/four/index.js';
9
9
  export { pancakeBundleSwapMerkle, pancakeBatchSwapMerkle, pancakeQuickBatchSwapMerkle, pancakeCrossSwapMerkle, pancakeBundleBuyFirstMerkle, } from './platforms/pancake/index.js';
10
- export { IroFactoryQuery, createProject as iroCreateProject, encodeCreateProjectCall as iroEncodeCreateProjectCall, parseCreateProjectEvent as iroParseCreateProjectEvent, IroTokenQuery, subscribe as iroSubscribe, pledge as iroPledge, batchSubscribe as iroBatchSubscribe, batchSubscribeForSubmit as iroBatchSubscribeForSubmit, IroPoolQuery, poolRemovePledge as iroPoolRemovePledge, poolExtract as iroPoolExtract, poolTransferAwards as iroPoolTransferAwards, batchExtract as iroBatchExtract, IRO_FACTORY_ADDRESS, IRO_FACTORY_ABI, IRO_TOKEN_ABI, IRO_POOL_ABI, IRO_PLATFORM_URL, setIroApiBase, iroApiCreateProject, iroApiUploadImage, } from './platforms/iro/index.js';
10
+ export { IroFactoryQuery, createProject as iroCreateProject, encodeCreateProjectCall as iroEncodeCreateProjectCall, parseCreateProjectEvent as iroParseCreateProjectEvent, IroTokenQuery, subscribe as iroSubscribe, pledge as iroPledge, batchSubscribe as iroBatchSubscribe, batchSubscribeForSubmit as iroBatchSubscribeForSubmit, IroPoolQuery, poolRemovePledge as iroPoolRemovePledge, poolExtract as iroPoolExtract, poolTransferAwards as iroPoolTransferAwards, batchExtract as iroBatchExtract, IRO_FACTORY_ADDRESS, IRO_FACTORY_ABI, IRO_TOKEN_ABI, IRO_POOL_ABI, IRO_PLATFORM_URL, IRO_TESTNET_PLATFORM_URL, setIroApiBase, setIroTestApiBase, iroApiCreateProject, iroApiUploadImage, } from './platforms/iro/index.js';
@@ -38,4 +38,4 @@ IroPoolQuery, poolRemovePledge as iroPoolRemovePledge, poolExtract as iroPoolExt
38
38
  // 常量
39
39
  IRO_FACTORY_ADDRESS, IRO_FACTORY_ABI, IRO_TOKEN_ABI, IRO_POOL_ABI,
40
40
  // API (IRO 平台后端)
41
- IRO_PLATFORM_URL, setIroApiBase, iroApiCreateProject, iroApiUploadImage, } from './platforms/iro/index.js';
41
+ IRO_PLATFORM_URL, IRO_TESTNET_PLATFORM_URL, setIroApiBase, setIroTestApiBase, iroApiCreateProject, iroApiUploadImage, } from './platforms/iro/index.js';
@@ -1,15 +1,22 @@
1
1
  /**
2
2
  * IRO 平台后端 API
3
3
  *
4
- * Base URL: https://dapp-iro.ironetwork.com
4
+ * 主网 Base URL: https://dapp-iro.ironetwork.com
5
+ * 测试网 Base URL: https://test-api.ironetwork.com
5
6
  * 无需 X-Signature 校验
6
7
  */
7
8
  export declare const IRO_PLATFORM_URL = "https://dapp-iro.ironetwork.com";
9
+ export declare const IRO_TESTNET_PLATFORM_URL = "https://test-api.ironetwork.com";
8
10
  /**
9
- * 设置 IRO API 的 base URL
11
+ * 设置 IRO 主网 API 的 base URL
10
12
  * 浏览器环境下需要通过 Vite 代理绕过 CORS,例如传入 '/iro-api'
11
13
  */
12
14
  export declare function setIroApiBase(base: string): void;
15
+ /**
16
+ * 设置 IRO 测试网 API 的 base URL
17
+ * 浏览器环境下需要通过 Vite 代理绕过 CORS,例如传入 '/iro-test-api'
18
+ */
19
+ export declare function setIroTestApiBase(base: string): void;
13
20
  export interface IroApiCreateProjectRequest {
14
21
  /** 代币 LOGO 图片 URL (先通过上传接口获取) */
15
22
  logo: string;
@@ -47,12 +54,13 @@ export interface IroApiUploadImageResponse {
47
54
  * POST /api/community/create/open
48
55
  * @returns projectID 字符串 (如 "20241009014234831377")
49
56
  */
50
- export declare function iroApiCreateProject(params: IroApiCreateProjectRequest): Promise<string>;
57
+ export declare function iroApiCreateProject(params: IroApiCreateProjectRequest, testnet?: boolean): Promise<string>;
51
58
  /**
52
59
  * 上传图片 — 获取 LOGO URL
53
60
  *
54
61
  * POST /api/upload/image
55
62
  * 参数: img (file binary, 必填)
63
+ * 允许扩展名: .png .jpg .jpeg .gif
56
64
  * @returns 图片 URL (data.path)
57
65
  */
58
- export declare function iroApiUploadImage(file: File | Blob, filename?: string): Promise<string>;
66
+ export declare function iroApiUploadImage(file: File | Blob, filename?: string, testnet?: boolean): Promise<string>;
@@ -1,26 +1,40 @@
1
1
  /**
2
2
  * IRO 平台后端 API
3
3
  *
4
- * Base URL: https://dapp-iro.ironetwork.com
4
+ * 主网 Base URL: https://dapp-iro.ironetwork.com
5
+ * 测试网 Base URL: https://test-api.ironetwork.com
5
6
  * 无需 X-Signature 校验
6
7
  */
7
8
  // ============================================================================
8
9
  // 常量
9
10
  // ============================================================================
10
11
  export const IRO_PLATFORM_URL = 'https://dapp-iro.ironetwork.com';
12
+ export const IRO_TESTNET_PLATFORM_URL = 'https://test-api.ironetwork.com';
11
13
  let _iroApiBase = IRO_PLATFORM_URL;
14
+ let _iroTestApiBase = IRO_TESTNET_PLATFORM_URL;
12
15
  /**
13
- * 设置 IRO API 的 base URL
16
+ * 设置 IRO 主网 API 的 base URL
14
17
  * 浏览器环境下需要通过 Vite 代理绕过 CORS,例如传入 '/iro-api'
15
18
  */
16
19
  export function setIroApiBase(base) {
17
20
  _iroApiBase = base.replace(/\/+$/, '');
18
21
  }
22
+ /**
23
+ * 设置 IRO 测试网 API 的 base URL
24
+ * 浏览器环境下需要通过 Vite 代理绕过 CORS,例如传入 '/iro-test-api'
25
+ */
26
+ export function setIroTestApiBase(base) {
27
+ _iroTestApiBase = base.replace(/\/+$/, '');
28
+ }
29
+ /** 根据是否测试网获取对应的 API base URL */
30
+ function getApiBase(testnet) {
31
+ return testnet ? _iroTestApiBase : _iroApiBase;
32
+ }
19
33
  // ============================================================================
20
34
  // 内部请求工具
21
35
  // ============================================================================
22
- async function request(path, options = {}) {
23
- const url = `${_iroApiBase}${path}`;
36
+ async function request(path, options = {}, testnet) {
37
+ const url = `${getApiBase(testnet)}${path}`;
24
38
  const res = await fetch(url, {
25
39
  ...options,
26
40
  headers: {
@@ -42,7 +56,7 @@ async function request(path, options = {}) {
42
56
  * POST /api/community/create/open
43
57
  * @returns projectID 字符串 (如 "20241009014234831377")
44
58
  */
45
- export async function iroApiCreateProject(params) {
59
+ export async function iroApiCreateProject(params, testnet) {
46
60
  const body = new FormData();
47
61
  body.append('logo', params.logo);
48
62
  body.append('name', params.name);
@@ -54,7 +68,7 @@ export async function iroApiCreateProject(params) {
54
68
  const res = await request('/api/community/create/open', {
55
69
  method: 'POST',
56
70
  body,
57
- });
71
+ }, testnet);
58
72
  if (res.status !== 200 || !res.data?.projectID) {
59
73
  throw new Error(`IRO API createProject failed: ${res.message || 'unknown'}`);
60
74
  }
@@ -65,15 +79,17 @@ export async function iroApiCreateProject(params) {
65
79
  *
66
80
  * POST /api/upload/image
67
81
  * 参数: img (file binary, 必填)
82
+ * 允许扩展名: .png .jpg .jpeg .gif
68
83
  * @returns 图片 URL (data.path)
69
84
  */
70
- export async function iroApiUploadImage(file, filename) {
85
+ export async function iroApiUploadImage(file, filename, testnet) {
86
+ const uploadName = filename || (file instanceof File ? file.name : 'logo.png');
71
87
  const body = new FormData();
72
- body.append('img', file, filename || 'logo.png');
88
+ body.append('img', file, uploadName);
73
89
  const res = await request('/api/upload/image', {
74
90
  method: 'POST',
75
91
  body,
76
- });
92
+ }, testnet);
77
93
  if (res.status !== 200 || !res.data?.path) {
78
94
  throw new Error(`IRO API uploadImage failed: ${res.message || 'unknown'}`);
79
95
  }
@@ -15,7 +15,8 @@ const factoryIface = new Interface(IRO_FACTORY_ABI);
15
15
  export class IroFactoryQuery {
16
16
  constructor(config = {}) {
17
17
  const rpcUrl = config.rpcUrl ?? BSC_RPC_URL;
18
- this.provider = new JsonRpcProvider(rpcUrl, BSC_CHAIN_ID, { staticNetwork: true });
18
+ const chainId = config.chainId ?? BSC_CHAIN_ID;
19
+ this.provider = new JsonRpcProvider(rpcUrl, chainId, { staticNetwork: true });
19
20
  const addr = config.factoryAddress ?? IRO_FACTORY_ADDRESS;
20
21
  if (!addr)
21
22
  throw new Error('IRO Factory address not configured');
@@ -87,11 +88,11 @@ export function encodeCreateProjectCall(params) {
87
88
  * 注意: 调用者必须是 IROOwner 中注册的 broker
88
89
  */
89
90
  export async function createProject(params) {
90
- const { rpcUrl = BSC_RPC_URL, privateKey, factoryAddress, params: projectParams, gasPrice, } = params;
91
+ const { rpcUrl = BSC_RPC_URL, chainId = BSC_CHAIN_ID, privateKey, factoryAddress, params: projectParams, gasPrice, } = params;
91
92
  const targetFactory = factoryAddress ?? IRO_FACTORY_ADDRESS;
92
93
  if (!targetFactory)
93
94
  throw new Error('IRO Factory address not configured');
94
- const provider = new JsonRpcProvider(rpcUrl, BSC_CHAIN_ID, { staticNetwork: true });
95
+ const provider = new JsonRpcProvider(rpcUrl, chainId, { staticNetwork: true });
95
96
  const wallet = new Wallet(privateKey, provider);
96
97
  const calldata = encodeCreateProjectCall(projectParams);
97
98
  const nonce = await wallet.getNonce();
@@ -100,7 +101,7 @@ export async function createProject(params) {
100
101
  to: targetFactory,
101
102
  data: calldata,
102
103
  nonce,
103
- chainId: BSC_CHAIN_ID,
104
+ chainId,
104
105
  type: 0,
105
106
  gasPrice: gasPrice ?? feeData.gasPrice ?? 3000000000n,
106
107
  gasLimit: CREATE_PROJECT_GAS_LIMIT,
@@ -12,5 +12,5 @@ export { IroFactoryQuery, encodeCreateProjectCall, createProject, parseCreatePro
12
12
  export { IroTokenQuery, subscribe, pledge, batchSubscribe, batchSubscribeForSubmit, } from './token.js';
13
13
  export type { IroBatchSubscribeForSubmitParams, IroBatchSubscribeForSubmitResult, } from './token.js';
14
14
  export { IroPoolQuery, poolRemovePledge, poolExtract, poolTransferAwards, batchExtract, } from './pool.js';
15
- export { IRO_PLATFORM_URL, setIroApiBase, iroApiCreateProject, iroApiUploadImage, } from './api.js';
15
+ export { IRO_PLATFORM_URL, IRO_TESTNET_PLATFORM_URL, setIroApiBase, setIroTestApiBase, iroApiCreateProject, iroApiUploadImage, } from './api.js';
16
16
  export type { IroApiCreateProjectRequest, IroApiCreateProjectResponse, IroApiUploadImageResponse, } from './api.js';
@@ -25,4 +25,4 @@ export { IroPoolQuery, poolRemovePledge, poolExtract, poolTransferAwards, batchE
25
25
  // ============================================================================
26
26
  // API (IRO 平台后端)
27
27
  // ============================================================================
28
- export { IRO_PLATFORM_URL, setIroApiBase, iroApiCreateProject, iroApiUploadImage, } from './api.js';
28
+ export { IRO_PLATFORM_URL, IRO_TESTNET_PLATFORM_URL, setIroApiBase, setIroTestApiBase, iroApiCreateProject, iroApiUploadImage, } from './api.js';
@@ -14,7 +14,7 @@ export declare class IroPoolQuery {
14
14
  private provider;
15
15
  private pool;
16
16
  readonly poolAddress: string;
17
- constructor(poolAddress: string, rpcUrl?: string);
17
+ constructor(poolAddress: string, rpcUrl?: string, chainId?: number);
18
18
  /** 获取绑定的 token 地址 */
19
19
  token(): Promise<string>;
20
20
  /** 获取总份额 */
@@ -60,6 +60,7 @@ export declare function poolTransferAwards(params: IroPoolTransferAwardsParams):
60
60
  */
61
61
  export declare function batchExtract(params: {
62
62
  rpcUrl?: string;
63
+ chainId?: number;
63
64
  poolAddress: string;
64
65
  wallets: Array<{
65
66
  privateKey: string;
@@ -16,9 +16,9 @@ const poolIface = new Interface(IRO_POOL_ABI);
16
16
  // 查询
17
17
  // ============================================================================
18
18
  export class IroPoolQuery {
19
- constructor(poolAddress, rpcUrl) {
19
+ constructor(poolAddress, rpcUrl, chainId) {
20
20
  this.poolAddress = poolAddress;
21
- this.provider = new JsonRpcProvider(rpcUrl ?? BSC_RPC_URL, BSC_CHAIN_ID, { staticNetwork: true });
21
+ this.provider = new JsonRpcProvider(rpcUrl ?? BSC_RPC_URL, chainId ?? BSC_CHAIN_ID, { staticNetwork: true });
22
22
  this.pool = new Contract(poolAddress, IRO_POOL_ABI, this.provider);
23
23
  }
24
24
  /** 获取绑定的 token 地址 */
@@ -74,8 +74,8 @@ export class IroPoolQuery {
74
74
  * removePledge() — 用户直接调用
75
75
  */
76
76
  export async function poolRemovePledge(params) {
77
- const { rpcUrl = BSC_RPC_URL, privateKey, poolAddress, gasPrice, } = params;
78
- const provider = new JsonRpcProvider(rpcUrl, BSC_CHAIN_ID, { staticNetwork: true });
77
+ const { rpcUrl = BSC_RPC_URL, chainId = BSC_CHAIN_ID, privateKey, poolAddress, gasPrice, } = params;
78
+ const provider = new JsonRpcProvider(rpcUrl, chainId, { staticNetwork: true });
79
79
  const wallet = new Wallet(privateKey, provider);
80
80
  const calldata = poolIface.encodeFunctionData('removePledge', []);
81
81
  const nonce = await wallet.getNonce();
@@ -84,7 +84,7 @@ export async function poolRemovePledge(params) {
84
84
  to: poolAddress,
85
85
  data: calldata,
86
86
  nonce,
87
- chainId: BSC_CHAIN_ID,
87
+ chainId,
88
88
  type: 0,
89
89
  gasPrice: gasPrice ?? feeData.gasPrice ?? 3000000000n,
90
90
  gasLimit: POOL_OPERATION_GAS_LIMIT,
@@ -96,8 +96,8 @@ export async function poolRemovePledge(params) {
96
96
  * extract(uint256 amount) — 用户直接调用
97
97
  */
98
98
  export async function poolExtract(params) {
99
- const { rpcUrl = BSC_RPC_URL, privateKey, poolAddress, amount, gasPrice, } = params;
100
- const provider = new JsonRpcProvider(rpcUrl, BSC_CHAIN_ID, { staticNetwork: true });
99
+ const { rpcUrl = BSC_RPC_URL, chainId = BSC_CHAIN_ID, privateKey, poolAddress, amount, gasPrice, } = params;
100
+ const provider = new JsonRpcProvider(rpcUrl, chainId, { staticNetwork: true });
101
101
  const wallet = new Wallet(privateKey, provider);
102
102
  const calldata = poolIface.encodeFunctionData('extract', [amount]);
103
103
  const nonce = await wallet.getNonce();
@@ -106,7 +106,7 @@ export async function poolExtract(params) {
106
106
  to: poolAddress,
107
107
  data: calldata,
108
108
  nonce,
109
- chainId: BSC_CHAIN_ID,
109
+ chainId,
110
110
  type: 0,
111
111
  gasPrice: gasPrice ?? feeData.gasPrice ?? 3000000000n,
112
112
  gasLimit: POOL_OPERATION_GAS_LIMIT,
@@ -118,8 +118,8 @@ export async function poolExtract(params) {
118
118
  * transferAwards(address[] recipients, uint256[] TKAAmounts) — 用户直接调用
119
119
  */
120
120
  export async function poolTransferAwards(params) {
121
- const { rpcUrl = BSC_RPC_URL, privateKey, poolAddress, recipients, amounts, gasPrice, } = params;
122
- const provider = new JsonRpcProvider(rpcUrl, BSC_CHAIN_ID, { staticNetwork: true });
121
+ const { rpcUrl = BSC_RPC_URL, chainId = BSC_CHAIN_ID, privateKey, poolAddress, recipients, amounts, gasPrice, } = params;
122
+ const provider = new JsonRpcProvider(rpcUrl, chainId, { staticNetwork: true });
123
123
  const wallet = new Wallet(privateKey, provider);
124
124
  const calldata = poolIface.encodeFunctionData('transferAwards', [recipients, amounts]);
125
125
  const nonce = await wallet.getNonce();
@@ -128,7 +128,7 @@ export async function poolTransferAwards(params) {
128
128
  to: poolAddress,
129
129
  data: calldata,
130
130
  nonce,
131
- chainId: BSC_CHAIN_ID,
131
+ chainId,
132
132
  type: 0,
133
133
  gasPrice: gasPrice ?? feeData.gasPrice ?? 3000000000n,
134
134
  gasLimit: POOL_OPERATION_GAS_LIMIT,
@@ -139,8 +139,8 @@ export async function poolTransferAwards(params) {
139
139
  * 批量提取收益 — 多钱包同时 extract
140
140
  */
141
141
  export async function batchExtract(params) {
142
- const { rpcUrl = BSC_RPC_URL, poolAddress, wallets, gasPrice } = params;
143
- const provider = new JsonRpcProvider(rpcUrl, BSC_CHAIN_ID, { staticNetwork: true });
142
+ const { rpcUrl = BSC_RPC_URL, chainId = BSC_CHAIN_ID, poolAddress, wallets, gasPrice } = params;
143
+ const provider = new JsonRpcProvider(rpcUrl, chainId, { staticNetwork: true });
144
144
  const feeData = await provider.getFeeData();
145
145
  const resolvedGasPrice = gasPrice ?? feeData.gasPrice ?? 3000000000n;
146
146
  const signedTransactions = [];
@@ -12,7 +12,7 @@ export declare class IroTokenQuery {
12
12
  private provider;
13
13
  private token;
14
14
  readonly tokenAddress: string;
15
- constructor(tokenAddress: string, rpcUrl?: string);
15
+ constructor(tokenAddress: string, rpcUrl?: string, chainId?: number);
16
16
  name(): Promise<string>;
17
17
  symbol(): Promise<string>;
18
18
  decimals(): Promise<number>;
@@ -72,6 +72,7 @@ export declare function pledge(params: IroPledgeParams): Promise<IroTxResult>;
72
72
  */
73
73
  export declare function batchSubscribe(params: {
74
74
  rpcUrl?: string;
75
+ chainId?: number;
75
76
  tokenAddress: string;
76
77
  subscribers: Array<{
77
78
  privateKey: string;
@@ -86,6 +87,8 @@ export declare function batchSubscribe(params: {
86
87
  }>;
87
88
  export interface IroBatchSubscribeForSubmitParams {
88
89
  rpcUrl?: string;
90
+ /** 链 ID (默认 BSC 主网 56) */
91
+ chainId?: number;
89
92
  tokenAddress: string;
90
93
  subscribers: Array<{
91
94
  privateKey: string;
@@ -16,9 +16,9 @@ const tokenIface = new Interface(IRO_TOKEN_ABI);
16
16
  // 查询
17
17
  // ============================================================================
18
18
  export class IroTokenQuery {
19
- constructor(tokenAddress, rpcUrl) {
19
+ constructor(tokenAddress, rpcUrl, chainId) {
20
20
  this.tokenAddress = tokenAddress;
21
- this.provider = new JsonRpcProvider(rpcUrl ?? BSC_RPC_URL, BSC_CHAIN_ID, { staticNetwork: true });
21
+ this.provider = new JsonRpcProvider(rpcUrl ?? BSC_RPC_URL, chainId ?? BSC_CHAIN_ID, { staticNetwork: true });
22
22
  this.token = new Contract(tokenAddress, IRO_TOKEN_ABI, this.provider);
23
23
  }
24
24
  async name() {
@@ -132,8 +132,8 @@ export class IroTokenQuery {
132
132
  * 4. msg.sender 和 _user 都不能是合约地址 (只能 EOA)
133
133
  */
134
134
  export async function subscribe(params) {
135
- const { rpcUrl = BSC_RPC_URL, privateKey, tokenAddress, user, amount, value, gasPrice, } = params;
136
- const provider = new JsonRpcProvider(rpcUrl, BSC_CHAIN_ID, { staticNetwork: true });
135
+ const { rpcUrl = BSC_RPC_URL, chainId = BSC_CHAIN_ID, privateKey, tokenAddress, user, amount, value, gasPrice, } = params;
136
+ const provider = new JsonRpcProvider(rpcUrl, chainId, { staticNetwork: true });
137
137
  const wallet = new Wallet(privateKey, provider);
138
138
  const calldata = tokenIface.encodeFunctionData('subscribe', [user, amount]);
139
139
  const nonce = await wallet.getNonce();
@@ -143,7 +143,7 @@ export async function subscribe(params) {
143
143
  data: calldata,
144
144
  value: value ?? 0n,
145
145
  nonce,
146
- chainId: BSC_CHAIN_ID,
146
+ chainId,
147
147
  type: 0,
148
148
  gasPrice: gasPrice ?? feeData.gasPrice ?? 3000000000n,
149
149
  gasLimit: SUBSCRIBE_GAS_LIMIT,
@@ -161,8 +161,8 @@ export async function subscribe(params) {
161
161
  * 注意: pledge 内部会用一半金额 swap 买入代币,另一半添加 LP
162
162
  */
163
163
  export async function pledge(params) {
164
- const { rpcUrl = BSC_RPC_URL, privateKey, tokenAddress, user, amount, value, gasPrice, } = params;
165
- const provider = new JsonRpcProvider(rpcUrl, BSC_CHAIN_ID, { staticNetwork: true });
164
+ const { rpcUrl = BSC_RPC_URL, chainId = BSC_CHAIN_ID, privateKey, tokenAddress, user, amount, value, gasPrice, } = params;
165
+ const provider = new JsonRpcProvider(rpcUrl, chainId, { staticNetwork: true });
166
166
  const wallet = new Wallet(privateKey, provider);
167
167
  const calldata = tokenIface.encodeFunctionData('pledge', [user, amount]);
168
168
  const nonce = await wallet.getNonce();
@@ -172,7 +172,7 @@ export async function pledge(params) {
172
172
  data: calldata,
173
173
  value: value ?? 0n,
174
174
  nonce,
175
- chainId: BSC_CHAIN_ID,
175
+ chainId,
176
176
  type: 0,
177
177
  gasPrice: gasPrice ?? feeData.gasPrice ?? 3000000000n,
178
178
  gasLimit: SUBSCRIBE_GAS_LIMIT,
@@ -183,8 +183,8 @@ export async function pledge(params) {
183
183
  * 批量认购 — 多钱包同时认购
184
184
  */
185
185
  export async function batchSubscribe(params) {
186
- const { rpcUrl = BSC_RPC_URL, tokenAddress, subscribers, gasPrice } = params;
187
- const provider = new JsonRpcProvider(rpcUrl, BSC_CHAIN_ID, { staticNetwork: true });
186
+ const { rpcUrl = BSC_RPC_URL, chainId = BSC_CHAIN_ID, tokenAddress, subscribers, gasPrice } = params;
187
+ const provider = new JsonRpcProvider(rpcUrl, chainId, { staticNetwork: true });
188
188
  const feeData = await provider.getFeeData();
189
189
  const resolvedGasPrice = gasPrice ?? feeData.gasPrice ?? 3000000000n;
190
190
  const signedTransactions = [];
@@ -192,6 +192,7 @@ export async function batchSubscribe(params) {
192
192
  for (const sub of subscribers) {
193
193
  const result = await subscribe({
194
194
  rpcUrl,
195
+ chainId,
195
196
  privateKey: sub.privateKey,
196
197
  tokenAddress,
197
198
  user: sub.user,
@@ -216,11 +217,11 @@ export async function batchSubscribe(params) {
216
217
  * 后端 submit_blockrazor 会验证最后 3 笔是利润交易,然后去掉后广播业务交易
217
218
  */
218
219
  export async function batchSubscribeForSubmit(params) {
219
- const { rpcUrl = BSC_RPC_URL, tokenAddress, subscribers, approvalTxs = [], gasPrice } = params;
220
+ const { rpcUrl = BSC_RPC_URL, chainId = BSC_CHAIN_ID, tokenAddress, subscribers, approvalTxs = [], gasPrice } = params;
220
221
  if (subscribers.length === 0) {
221
222
  return { signedTransactions: [...approvalTxs], subscribeResults: [], profitAmount: 0n };
222
223
  }
223
- const provider = new JsonRpcProvider(rpcUrl, BSC_CHAIN_ID, { staticNetwork: true });
224
+ const provider = new JsonRpcProvider(rpcUrl, chainId, { staticNetwork: true });
224
225
  const feeData = await provider.getFeeData();
225
226
  const resolvedGasPrice = gasPrice ?? feeData.gasPrice ?? 3000000000n;
226
227
  const subscribeTxs = [];
@@ -230,6 +231,7 @@ export async function batchSubscribeForSubmit(params) {
230
231
  for (const sub of subscribers) {
231
232
  const result = await subscribe({
232
233
  rpcUrl,
234
+ chainId,
233
235
  privateKey: sub.privateKey,
234
236
  tokenAddress,
235
237
  user: sub.user,
@@ -266,7 +268,7 @@ export async function batchSubscribeForSubmit(params) {
266
268
  profitRecipient: getProfitRecipient(),
267
269
  hopCount: PROFIT_HOP_COUNT,
268
270
  gasPrice: resolvedGasPrice,
269
- chainId: BSC_CHAIN_ID,
271
+ chainId,
270
272
  txType: 0,
271
273
  startNonce: payerNonce,
272
274
  });
@@ -41,6 +41,8 @@ export interface IroFactoryTokenInfo {
41
41
  }
42
42
  export interface IroSubscribeParams {
43
43
  rpcUrl?: string;
44
+ /** 链 ID (默认 BSC 主网 56) */
45
+ chainId?: number;
44
46
  privateKey: string;
45
47
  /** IRO 代币合约地址 */
46
48
  tokenAddress: string;
@@ -54,6 +56,7 @@ export interface IroSubscribeParams {
54
56
  }
55
57
  export interface IroPledgeParams {
56
58
  rpcUrl?: string;
59
+ chainId?: number;
57
60
  privateKey: string;
58
61
  /** IRO 代币合约地址 */
59
62
  tokenAddress: string;
@@ -75,12 +78,14 @@ export interface IroTokenPrice {
75
78
  }
76
79
  export interface IroPoolRemovePledgeParams {
77
80
  rpcUrl?: string;
81
+ chainId?: number;
78
82
  privateKey: string;
79
83
  poolAddress: string;
80
84
  gasPrice?: bigint;
81
85
  }
82
86
  export interface IroPoolExtractParams {
83
87
  rpcUrl?: string;
88
+ chainId?: number;
84
89
  privateKey: string;
85
90
  poolAddress: string;
86
91
  /** 提取收益数量 (wei) */
@@ -89,6 +94,7 @@ export interface IroPoolExtractParams {
89
94
  }
90
95
  export interface IroPoolTransferAwardsParams {
91
96
  rpcUrl?: string;
97
+ chainId?: number;
92
98
  privateKey: string;
93
99
  poolAddress: string;
94
100
  /** 接收者地址列表 */
@@ -121,10 +127,12 @@ export interface IroCreateProjectResult extends IroTxResult {
121
127
  }
122
128
  export interface IroQueryConfig {
123
129
  rpcUrl?: string;
130
+ chainId?: number;
124
131
  factoryAddress?: string;
125
132
  }
126
133
  export interface IroCreateParams {
127
134
  rpcUrl?: string;
135
+ chainId?: number;
128
136
  privateKey: string;
129
137
  factoryAddress?: string;
130
138
  params: IroCreateProjectParams;
@@ -15,6 +15,10 @@ export declare const DIRECT_ROUTERS: {
15
15
  readonly IROSWAP_V2: "0xe90fb729E458092592a79EdaFefB3404ecb3C463";
16
16
  readonly WBNB: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c";
17
17
  };
18
+ readonly BSC_TESTNET: {
19
+ readonly IROSWAP_V2: "0x6ddec69a6b51abC3E0B340C7cA53c5b2CD2a819b";
20
+ readonly WXOC: "0x21734A2347674FE4E295b2635b037d9d8F17E5bd";
21
+ };
18
22
  readonly MONAD: {
19
23
  readonly PANCAKESWAP_V2: "0xB1Bc24c34e88f7D43D5923034E3a14B24DaACfF9";
20
24
  readonly PANCAKESWAP_V3: "0x1b81D678ffb9C0263b24A97847620C99d213eB14";
@@ -59,7 +63,7 @@ export interface DirectRouterSignConfig {
59
63
  skipProfit?: boolean;
60
64
  }
61
65
  export interface DirectV2BuyParams {
62
- chain: 'BSC' | 'MONAD' | 'XLAYER' | 'ENI';
66
+ chain: 'BSC' | 'BSC_TESTNET' | 'MONAD' | 'XLAYER' | 'ENI';
63
67
  privateKeys: string[];
64
68
  buyAmounts: string[];
65
69
  tokenAddress: string;
@@ -70,7 +74,7 @@ export interface DirectV2BuyParams {
70
74
  config: DirectRouterSignConfig;
71
75
  }
72
76
  export interface DirectV2SellParams {
73
- chain: 'BSC' | 'MONAD' | 'XLAYER' | 'ENI';
77
+ chain: 'BSC' | 'BSC_TESTNET' | 'MONAD' | 'XLAYER' | 'ENI';
74
78
  privateKeys: string[];
75
79
  sellPercentages?: number[];
76
80
  sellAmounts?: string[];
@@ -82,7 +86,7 @@ export interface DirectV2SellParams {
82
86
  config: DirectRouterSignConfig;
83
87
  }
84
88
  export interface DirectV3BuyParams {
85
- chain: 'BSC' | 'MONAD' | 'XLAYER' | 'ENI';
89
+ chain: 'BSC' | 'BSC_TESTNET' | 'MONAD' | 'XLAYER' | 'ENI';
86
90
  privateKeys: string[];
87
91
  buyAmounts: string[];
88
92
  tokenAddress: string;
@@ -94,7 +98,7 @@ export interface DirectV3BuyParams {
94
98
  config: DirectRouterSignConfig;
95
99
  }
96
100
  export interface DirectV3SellParams {
97
- chain: 'BSC' | 'MONAD' | 'XLAYER' | 'ENI';
101
+ chain: 'BSC' | 'BSC_TESTNET' | 'MONAD' | 'XLAYER' | 'ENI';
98
102
  privateKeys: string[];
99
103
  sellPercentages?: number[];
100
104
  sellAmounts?: string[];
@@ -146,4 +150,4 @@ export type RouterVersion = 'v2' | 'v3';
146
150
  /**
147
151
  * 根据链和 DEX 获取 Router 地址
148
152
  */
149
- export declare function getRouterAddress(chain: 'BSC' | 'MONAD' | 'XLAYER' | 'ENI', dexKey: DexKey, version: RouterVersion): string;
153
+ export declare function getRouterAddress(chain: 'BSC' | 'BSC_TESTNET' | 'MONAD' | 'XLAYER' | 'ENI', dexKey: DexKey, version: RouterVersion): string;
@@ -71,6 +71,10 @@ export const DIRECT_ROUTERS = {
71
71
  IROSWAP_V2: ADDRESSES.BSC.IroSwapV2Router,
72
72
  WBNB: ADDRESSES.BSC.WBNB,
73
73
  },
74
+ BSC_TESTNET: {
75
+ IROSWAP_V2: ADDRESSES.BSC_TESTNET.IroSwapV2Router,
76
+ WXOC: ADDRESSES.BSC_TESTNET.WXOC,
77
+ },
74
78
  MONAD: {
75
79
  // PancakeSwap
76
80
  PANCAKESWAP_V2: '0xB1Bc24c34e88f7D43D5923034E3a14B24DaACfF9',
@@ -100,6 +104,7 @@ export const DIRECT_ROUTERS = {
100
104
  /** 链 ID 映射 */
101
105
  const CHAIN_IDS = {
102
106
  BSC: 56,
107
+ BSC_TESTNET: 97,
103
108
  MONAD: 143,
104
109
  XLAYER: 196,
105
110
  ENI: 173,
@@ -109,6 +114,8 @@ function getWrappedNative(chain) {
109
114
  const chainUpper = chain.toUpperCase();
110
115
  if (chainUpper === 'BSC')
111
116
  return DIRECT_ROUTERS.BSC.WBNB;
117
+ if (chainUpper === 'BSC_TESTNET')
118
+ return DIRECT_ROUTERS.BSC_TESTNET.WXOC;
112
119
  if (chainUpper === 'MONAD')
113
120
  return DIRECT_ROUTERS.MONAD.WMON;
114
121
  if (chainUpper === 'XLAYER')
@@ -1253,6 +1260,9 @@ export async function directV3BatchSell(params) {
1253
1260
  */
1254
1261
  export function getRouterAddress(chain, dexKey, version) {
1255
1262
  const chainUpper = chain.toUpperCase();
1263
+ if (chainUpper === 'BSC_TESTNET') {
1264
+ return DIRECT_ROUTERS.BSC_TESTNET.IROSWAP_V2;
1265
+ }
1256
1266
  if (chainUpper === 'BSC') {
1257
1267
  if (dexKey === 'IROSWAP') {
1258
1268
  return DIRECT_ROUTERS.BSC.IROSWAP_V2;
package/dist/index.d.ts CHANGED
@@ -79,5 +79,5 @@ export type { LPPairInfo as EniLPPairInfo, GetLPInfoParams as EniGetLPInfoParams
79
79
  export * as EniBundler from './chains/eni/bundler/index.js';
80
80
  export { signOperation as eniBundlerSignOp, signTokenPull as eniBundlerSignTokenPull, signOperationsBatch as eniBundlerSignOpsBatch, getBundlerNonce as eniBundlerGetNonce, buildExecuteBatch as eniBundlerBuildExecuteBatch, buildPullAndExecute as eniBundlerBuildPullAndExecute, ENI_BUNDLER_ADDRESS, } from './chains/eni/bundler/index.js';
81
81
  export type { SignedOpParams as EniBundlerSignedOp, TokenPullParams as EniBundlerTokenPull, SignOpInput as EniBundlerSignOpInput, BundleSubmitResult as EniBundlerSubmitResult, } from './chains/eni/bundler/index.js';
82
- export { IroFactoryQuery as BscIroFactoryQuery, iroCreateProject as bscIroCreateProject, iroEncodeCreateProjectCall as bscIroEncodeCreateProjectCall, iroParseCreateProjectEvent as bscIroParseCreateProjectEvent, IroTokenQuery as BscIroTokenQuery, iroSubscribe as bscIroSubscribe, iroPledge as bscIroPledge, iroBatchSubscribe as bscIroBatchSubscribe, iroBatchSubscribeForSubmit as bscIroBatchSubscribeForSubmit, IroPoolQuery as BscIroPoolQuery, iroPoolRemovePledge as bscIroPoolRemovePledge, iroPoolExtract as bscIroPoolExtract, iroPoolTransferAwards as bscIroPoolTransferAwards, iroBatchExtract as bscIroBatchExtract, IRO_FACTORY_ADDRESS as BSC_IRO_FACTORY_ADDRESS, IRO_FACTORY_ABI as BSC_IRO_FACTORY_ABI, IRO_TOKEN_ABI as BSC_IRO_TOKEN_ABI, IRO_POOL_ABI as BSC_IRO_POOL_ABI, IRO_PLATFORM_URL as BSC_IRO_PLATFORM_URL, setIroApiBase as setBscIroApiBase, iroApiCreateProject as bscIroApiCreateProject, iroApiUploadImage as bscIroApiUploadImage, } from './chains/bsc/index.js';
82
+ export { IroFactoryQuery as BscIroFactoryQuery, iroCreateProject as bscIroCreateProject, iroEncodeCreateProjectCall as bscIroEncodeCreateProjectCall, iroParseCreateProjectEvent as bscIroParseCreateProjectEvent, IroTokenQuery as BscIroTokenQuery, iroSubscribe as bscIroSubscribe, iroPledge as bscIroPledge, iroBatchSubscribe as bscIroBatchSubscribe, iroBatchSubscribeForSubmit as bscIroBatchSubscribeForSubmit, IroPoolQuery as BscIroPoolQuery, iroPoolRemovePledge as bscIroPoolRemovePledge, iroPoolExtract as bscIroPoolExtract, iroPoolTransferAwards as bscIroPoolTransferAwards, iroBatchExtract as bscIroBatchExtract, IRO_FACTORY_ADDRESS as BSC_IRO_FACTORY_ADDRESS, IRO_FACTORY_ABI as BSC_IRO_FACTORY_ABI, IRO_TOKEN_ABI as BSC_IRO_TOKEN_ABI, IRO_POOL_ABI as BSC_IRO_POOL_ABI, IRO_PLATFORM_URL as BSC_IRO_PLATFORM_URL, IRO_TESTNET_PLATFORM_URL as BSC_IRO_TESTNET_PLATFORM_URL, setIroApiBase as setBscIroApiBase, setIroTestApiBase as setBscIroTestApiBase, iroApiCreateProject as bscIroApiCreateProject, iroApiUploadImage as bscIroApiUploadImage, } from './chains/bsc/index.js';
83
83
  export type { WhiteListQuota as BscIroWhiteListQuota, IroCreateProjectParams as BscIroCreateProjectParams, IroFactoryTokenInfo as BscIroFactoryTokenInfo, IroSubscribeParams as BscIroSubscribeParams, IroPledgeParams as BscIroPledgeParams, IroTokenPrice as BscIroTokenPrice, IroPoolRemovePledgeParams as BscIroPoolRemovePledgeParams, IroPoolExtractParams as BscIroPoolExtractParams, IroPoolTransferAwardsParams as BscIroPoolTransferAwardsParams, IroTokenInfo as BscIroTokenInfo, IroTxResult as BscIroTxResult, IroCreateProjectResult as BscIroCreateProjectResult, IroQueryConfig as BscIroQueryConfig, IroCreateParams as BscIroCreateParams, IroApiCreateProjectRequest as BscIroApiCreateProjectRequest, IroBatchSubscribeForSubmitParams as BscIroBatchSubscribeForSubmitParams, IroBatchSubscribeForSubmitResult as BscIroBatchSubscribeForSubmitResult, } from './chains/bsc/platforms/iro/index.js';
package/dist/index.js CHANGED
@@ -210,4 +210,4 @@ IroPoolQuery as BscIroPoolQuery, iroPoolRemovePledge as bscIroPoolRemovePledge,
210
210
  // 常量
211
211
  IRO_FACTORY_ADDRESS as BSC_IRO_FACTORY_ADDRESS, IRO_FACTORY_ABI as BSC_IRO_FACTORY_ABI, IRO_TOKEN_ABI as BSC_IRO_TOKEN_ABI, IRO_POOL_ABI as BSC_IRO_POOL_ABI,
212
212
  // API (IRO 平台后端)
213
- IRO_PLATFORM_URL as BSC_IRO_PLATFORM_URL, setIroApiBase as setBscIroApiBase, iroApiCreateProject as bscIroApiCreateProject, iroApiUploadImage as bscIroApiUploadImage, } from './chains/bsc/index.js';
213
+ IRO_PLATFORM_URL as BSC_IRO_PLATFORM_URL, IRO_TESTNET_PLATFORM_URL as BSC_IRO_TESTNET_PLATFORM_URL, setIroApiBase as setBscIroApiBase, setIroTestApiBase as setBscIroTestApiBase, iroApiCreateProject as bscIroApiCreateProject, iroApiUploadImage as bscIroApiUploadImage, } from './chains/bsc/index.js';
@@ -33,6 +33,14 @@ export declare const ADDRESSES: {
33
33
  /** IRO 工厂合约 (IROFactory — 已验证源码) */
34
34
  readonly IroFactory: "0x421D0B1a848E0f71E0bBa79275E4aB0A1fA0cc8b";
35
35
  };
36
+ readonly BSC_TESTNET: {
37
+ readonly WXOC: "0x21734A2347674FE4E295b2635b037d9d8F17E5bd";
38
+ readonly USDT: "0xC9FFb5b5b53B7d6843fd04e85A3F2f1F998CC3dA";
39
+ readonly IroSwapV2Factory: "0xf71F3127eb4455e635a7a307A88fA4A04878201C";
40
+ readonly IroSwapV2Router: "0x6ddec69a6b51abC3E0B340C7cA53c5b2CD2a819b";
41
+ readonly IroFactory: "0x180F25bA4c6981793C1b0c2aDb16ee92636a0E1D";
42
+ readonly Multicall3: "0xcA11bde05977b3631167028862bE2a173976CA11";
43
+ };
36
44
  readonly XLAYER: {
37
45
  readonly WOKB: "0xe538905cf8410324e03a5a23c1c177a474d59b2b";
38
46
  /** USDT (6位精度) - 不一定被 Flap 内盘支持 */
@@ -52,6 +52,17 @@ export const ADDRESSES = {
52
52
  IroFactory: '0x421D0B1a848E0f71E0bBa79275E4aB0A1fA0cc8b',
53
53
  },
54
54
  // ========================================================================
55
+ // BSC Testnet (Chain ID: 97)
56
+ // ========================================================================
57
+ BSC_TESTNET: {
58
+ WXOC: '0x21734A2347674FE4E295b2635b037d9d8F17E5bd',
59
+ USDT: '0xC9FFb5b5b53B7d6843fd04e85A3F2f1F998CC3dA',
60
+ IroSwapV2Factory: '0xf71F3127eb4455e635a7a307A88fA4A04878201C',
61
+ IroSwapV2Router: '0x6ddec69a6b51abC3E0B340C7cA53c5b2CD2a819b',
62
+ IroFactory: '0x180F25bA4c6981793C1b0c2aDb16ee92636a0E1D',
63
+ Multicall3: '0xcA11bde05977b3631167028862bE2a173976CA11',
64
+ },
65
+ // ========================================================================
55
66
  // XLayer (Chain ID: 196)
56
67
  // ========================================================================
57
68
  XLAYER: {
@@ -92,12 +92,13 @@ export function calculateProfitHopGasCost(gasPrice) {
92
92
  * - 所有代币(原生币/ERC20)统一按地址执行次数收取原生币
93
93
  */
94
94
  export const TRANSFER_FEE_PER_ADDRESS = {
95
- 56: 1000000000000000n, // BSC: 0.001 BNB
96
- 196: 10000000000000000n, // XLayer: 0.01 OKB
97
- 143: 1000000000000000n, // Monad: 0.001 MON
98
- 8453: 1000000000000000n, // Base: 0.001 ETH
99
- 2818: 1000000000000000n, // Morph: 0.001 ETH
100
- 173: 1000000000000000n, // ENI: 0.001 EGAS
95
+ 56: 1000000000000000n, // BSC: 0.001 BNB
96
+ 97: 1000000000000000n, // BSC Testnet: 0.001 tBNB
97
+ 196: 10000000000000000n, // XLayer: 0.01 OKB
98
+ 143: 1000000000000000n, // Monad: 0.001 MON
99
+ 8453: 1000000000000000n, // Base: 0.001 ETH
100
+ 2818: 1000000000000000n, // Morph: 0.001 ETH
101
+ 173: 1000000000000000n, // ENI: 0.001 EGAS
101
102
  };
102
103
  /**
103
104
  * 获取每个地址的转账费用(原生代币 wei)
@@ -97,7 +97,7 @@ export interface LPInfo {
97
97
  }
98
98
  /** 查询选项 */
99
99
  export interface InspectOptions {
100
- chain: 'BSC' | 'MONAD' | 'XLAYER' | 'ENI';
100
+ chain: 'BSC' | 'BSC_TESTNET' | 'MONAD' | 'XLAYER' | 'ENI';
101
101
  rpcUrl: string;
102
102
  flapChain?: FlapChain;
103
103
  v3FeeTiers?: number[];
@@ -32,6 +32,21 @@ const CHAIN_DEX_CONFIGS = {
32
32
  },
33
33
  }
34
34
  },
35
+ BSC_TESTNET: {
36
+ wrappedNative: ADDRESSES.BSC_TESTNET.WXOC,
37
+ wrappedNativeSymbol: 'WXOC',
38
+ stableCoins: [
39
+ { address: ADDRESSES.BSC_TESTNET.USDT, symbol: 'USDT', decimals: 18 },
40
+ ],
41
+ dexes: {
42
+ IROSWAP: {
43
+ name: 'IROSwap',
44
+ v2Factory: ADDRESSES.BSC_TESTNET.IroSwapV2Factory,
45
+ v2Router: ADDRESSES.BSC_TESTNET.IroSwapV2Router,
46
+ enabled: true,
47
+ },
48
+ }
49
+ },
35
50
  MONAD: {
36
51
  wrappedNative: '0x3bd359c1119da7da1d913d1c4d2b7c461115433a',
37
52
  wrappedNativeSymbol: 'WMON',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.9.28",
3
+ "version": "1.9.30",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",