four-flap-meme-sdk 1.5.30 → 1.5.31
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/utils/wallet.js +46 -0
- package/package.json +1 -1
package/dist/utils/wallet.js
CHANGED
|
@@ -15,6 +15,13 @@ const MULTICALL3_BY_CHAIN = {
|
|
|
15
15
|
2818: DEFAULT_MULTICALL3, // Morph
|
|
16
16
|
143: DEFAULT_MULTICALL3, // Monad
|
|
17
17
|
};
|
|
18
|
+
/**
|
|
19
|
+
* ✅ Multicall3 每批最多查询的地址数量
|
|
20
|
+
* - 考虑因素:RPC 节点 gas 限制(通常 50M)、返回数据大小限制、超时风险
|
|
21
|
+
* - 每个地址的调用数 = 1 (native) + N (tokens)
|
|
22
|
+
* - 安全值:100 个地址,即使查询 10 个代币也只有 ~1100 个 calls
|
|
23
|
+
*/
|
|
24
|
+
const MULTICALL_BATCH_SIZE = 100;
|
|
18
25
|
// ============================================================================
|
|
19
26
|
// 钱包生成与验证
|
|
20
27
|
// ============================================================================
|
|
@@ -66,8 +73,28 @@ function normalizePrivateKey(input) {
|
|
|
66
73
|
// ============================================================================
|
|
67
74
|
/**
|
|
68
75
|
* ✅ 内部:批量查询多代币余额(统一逻辑)
|
|
76
|
+
* ✅ 自动分批:如果地址数量超过 MULTICALL_BATCH_SIZE,自动分批查询并合并结果
|
|
69
77
|
*/
|
|
70
78
|
async function _queryMultiTokenBalances(provider, multicallAddress, tokenAddresses, holders) {
|
|
79
|
+
if (!holders?.length)
|
|
80
|
+
return [];
|
|
81
|
+
// ✅ 如果地址数量超过批次上限,分批处理
|
|
82
|
+
if (holders.length > MULTICALL_BATCH_SIZE) {
|
|
83
|
+
const allResults = [];
|
|
84
|
+
for (let i = 0; i < holders.length; i += MULTICALL_BATCH_SIZE) {
|
|
85
|
+
const batchHolders = holders.slice(i, i + MULTICALL_BATCH_SIZE);
|
|
86
|
+
const batchResults = await _queryMultiTokenBalancesSingle(provider, multicallAddress, tokenAddresses, batchHolders);
|
|
87
|
+
allResults.push(...batchResults);
|
|
88
|
+
}
|
|
89
|
+
return allResults;
|
|
90
|
+
}
|
|
91
|
+
// ✅ 地址数量在限制内,直接查询
|
|
92
|
+
return _queryMultiTokenBalancesSingle(provider, multicallAddress, tokenAddresses, holders);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* ✅ 内部:单批次查询多代币余额(不超过 MULTICALL_BATCH_SIZE 个地址)
|
|
96
|
+
*/
|
|
97
|
+
async function _queryMultiTokenBalancesSingle(provider, multicallAddress, tokenAddresses, holders) {
|
|
71
98
|
if (!holders?.length)
|
|
72
99
|
return [];
|
|
73
100
|
const erc20Iface = new Interface(ERC20_ABI);
|
|
@@ -153,8 +180,27 @@ async function _queryMultiTokenBalances(provider, multicallAddress, tokenAddress
|
|
|
153
180
|
}
|
|
154
181
|
/**
|
|
155
182
|
* ✅ 内部:查询单代币余额(旧接口兼容)
|
|
183
|
+
* ✅ 自动分批:如果地址数量超过 MULTICALL_BATCH_SIZE,自动分批查询并合并结果
|
|
156
184
|
*/
|
|
157
185
|
async function _querySingleTokenBalances(provider, multicallAddress, token, holders) {
|
|
186
|
+
if (!holders?.length)
|
|
187
|
+
return [];
|
|
188
|
+
// ✅ 如果地址数量超过批次上限,分批处理
|
|
189
|
+
if (holders.length > MULTICALL_BATCH_SIZE) {
|
|
190
|
+
const allResults = [];
|
|
191
|
+
for (let i = 0; i < holders.length; i += MULTICALL_BATCH_SIZE) {
|
|
192
|
+
const batchHolders = holders.slice(i, i + MULTICALL_BATCH_SIZE);
|
|
193
|
+
const batchResults = await _querySingleTokenBalancesSingle(provider, multicallAddress, token, batchHolders);
|
|
194
|
+
allResults.push(...batchResults);
|
|
195
|
+
}
|
|
196
|
+
return allResults;
|
|
197
|
+
}
|
|
198
|
+
return _querySingleTokenBalancesSingle(provider, multicallAddress, token, holders);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* ✅ 内部:单批次查询单代币余额(不超过 MULTICALL_BATCH_SIZE 个地址)
|
|
202
|
+
*/
|
|
203
|
+
async function _querySingleTokenBalancesSingle(provider, multicallAddress, token, holders) {
|
|
158
204
|
if (!holders?.length)
|
|
159
205
|
return [];
|
|
160
206
|
const erc20Iface = new Interface(ERC20_ABI);
|