four-flap-meme-sdk 1.5.23 → 1.5.24
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/flap/portal-bundle-merkle/encryption.d.ts +16 -0
- package/dist/flap/portal-bundle-merkle/encryption.js +146 -0
- package/dist/xlayer/aa-account.d.ts +1 -32
- package/dist/xlayer/aa-account.js +46 -184
- package/dist/xlayer/bundle.js +136 -182
- package/dist/xlayer/bundler.js +11 -30
- package/dist/xlayer/portal-ops.d.ts +0 -1
- package/dist/xlayer/portal-ops.js +8 -125
- package/dist/xlayer/types.d.ts +0 -20
- package/package.json +1 -1
|
@@ -8,8 +8,7 @@
|
|
|
8
8
|
* - 代币转账
|
|
9
9
|
*/
|
|
10
10
|
import { ethers, Interface, Contract, JsonRpcProvider } from 'ethers';
|
|
11
|
-
import { FLAP_PORTAL, ZERO_ADDRESS, PORTAL_ABI, ERC20_ABI,
|
|
12
|
-
import { mapWithConcurrency } from '../utils/concurrency.js';
|
|
11
|
+
import { FLAP_PORTAL, ZERO_ADDRESS, PORTAL_ABI, ERC20_ABI, DEFAULT_RPC_URL, XLAYER_CHAIN_ID, } from './constants.js';
|
|
13
12
|
// ============================================================================
|
|
14
13
|
// Portal 操作编码器
|
|
15
14
|
// ============================================================================
|
|
@@ -82,22 +81,10 @@ export class PortalQuery {
|
|
|
82
81
|
constructor(config = {}) {
|
|
83
82
|
const rpcUrl = config.rpcUrl ?? DEFAULT_RPC_URL;
|
|
84
83
|
const chainId = config.chainId ?? XLAYER_CHAIN_ID;
|
|
85
|
-
this.provider = new JsonRpcProvider(rpcUrl, { chainId, name: 'xlayer' }
|
|
86
|
-
batchMaxCount: 20,
|
|
87
|
-
batchStallTime: 30,
|
|
88
|
-
});
|
|
84
|
+
this.provider = new JsonRpcProvider(rpcUrl, { chainId, name: 'xlayer' });
|
|
89
85
|
this.portalAddress = config.portalAddress ?? FLAP_PORTAL;
|
|
90
86
|
this.portal = new Contract(this.portalAddress, PORTAL_ABI, this.provider);
|
|
91
87
|
}
|
|
92
|
-
async multicallAggregate3(params) {
|
|
93
|
-
const mcIface = new Interface([
|
|
94
|
-
'function aggregate3((address target,bool allowFailure,bytes callData)[] calls) view returns ((bool success,bytes returnData)[] returnData)',
|
|
95
|
-
]);
|
|
96
|
-
const data = mcIface.encodeFunctionData('aggregate3', [params.calls]);
|
|
97
|
-
const raw = await this.provider.call({ to: MULTICALL3, data });
|
|
98
|
-
const decoded = mcIface.decodeFunctionResult('aggregate3', raw)?.[0];
|
|
99
|
-
return decoded || [];
|
|
100
|
-
}
|
|
101
88
|
/**
|
|
102
89
|
* 获取 Provider
|
|
103
90
|
*/
|
|
@@ -184,42 +171,8 @@ export class PortalQuery {
|
|
|
184
171
|
*/
|
|
185
172
|
async getMultipleTokenBalances(tokenAddress, accounts) {
|
|
186
173
|
const balances = new Map();
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
return balances;
|
|
190
|
-
const calls = list.map((acc) => ({
|
|
191
|
-
target: tokenAddress,
|
|
192
|
-
allowFailure: true,
|
|
193
|
-
callData: erc20Iface.encodeFunctionData('balanceOf', [acc]),
|
|
194
|
-
}));
|
|
195
|
-
const BATCH = 350;
|
|
196
|
-
try {
|
|
197
|
-
for (let cursor = 0; cursor < calls.length; cursor += BATCH) {
|
|
198
|
-
const sliceCalls = calls.slice(cursor, cursor + BATCH);
|
|
199
|
-
const res = await this.multicallAggregate3({ calls: sliceCalls });
|
|
200
|
-
for (let i = 0; i < res.length; i++) {
|
|
201
|
-
const r = res[i];
|
|
202
|
-
const idx = cursor + i;
|
|
203
|
-
const acc = list[idx];
|
|
204
|
-
if (!r?.success || !r.returnData || r.returnData === '0x') {
|
|
205
|
-
balances.set(acc, 0n);
|
|
206
|
-
continue;
|
|
207
|
-
}
|
|
208
|
-
try {
|
|
209
|
-
const decoded = erc20Iface.decodeFunctionResult('balanceOf', r.returnData);
|
|
210
|
-
balances.set(acc, BigInt(decoded?.[0] ?? 0n));
|
|
211
|
-
}
|
|
212
|
-
catch {
|
|
213
|
-
balances.set(acc, 0n);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return balances;
|
|
218
|
-
}
|
|
219
|
-
catch {
|
|
220
|
-
const results = await mapWithConcurrency(list, 8, async (acc) => this.getTokenBalance(tokenAddress, acc));
|
|
221
|
-
list.forEach((acc, i) => balances.set(acc, results[i] ?? 0n));
|
|
222
|
-
}
|
|
174
|
+
const results = await Promise.all(accounts.map((acc) => this.getTokenBalance(tokenAddress, acc)));
|
|
175
|
+
accounts.forEach((acc, i) => balances.set(acc, results[i]));
|
|
223
176
|
return balances;
|
|
224
177
|
}
|
|
225
178
|
/**
|
|
@@ -227,43 +180,8 @@ export class PortalQuery {
|
|
|
227
180
|
*/
|
|
228
181
|
async getMultipleOkbBalances(accounts) {
|
|
229
182
|
const balances = new Map();
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
return balances;
|
|
233
|
-
const ethBalIface = new Interface(['function getEthBalance(address addr) view returns (uint256)']);
|
|
234
|
-
const calls = list.map((acc) => ({
|
|
235
|
-
target: MULTICALL3,
|
|
236
|
-
allowFailure: true,
|
|
237
|
-
callData: ethBalIface.encodeFunctionData('getEthBalance', [acc]),
|
|
238
|
-
}));
|
|
239
|
-
const BATCH = 350;
|
|
240
|
-
try {
|
|
241
|
-
for (let cursor = 0; cursor < calls.length; cursor += BATCH) {
|
|
242
|
-
const sliceCalls = calls.slice(cursor, cursor + BATCH);
|
|
243
|
-
const res = await this.multicallAggregate3({ calls: sliceCalls });
|
|
244
|
-
for (let i = 0; i < res.length; i++) {
|
|
245
|
-
const r = res[i];
|
|
246
|
-
const idx = cursor + i;
|
|
247
|
-
const acc = list[idx];
|
|
248
|
-
if (!r?.success || !r.returnData || r.returnData === '0x') {
|
|
249
|
-
balances.set(acc, 0n);
|
|
250
|
-
continue;
|
|
251
|
-
}
|
|
252
|
-
try {
|
|
253
|
-
const decoded = ethBalIface.decodeFunctionResult('getEthBalance', r.returnData);
|
|
254
|
-
balances.set(acc, BigInt(decoded?.[0] ?? 0n));
|
|
255
|
-
}
|
|
256
|
-
catch {
|
|
257
|
-
balances.set(acc, 0n);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
return balances;
|
|
262
|
-
}
|
|
263
|
-
catch {
|
|
264
|
-
const results = await mapWithConcurrency(list, 8, async (acc) => this.getOkbBalance(acc));
|
|
265
|
-
list.forEach((acc, i) => balances.set(acc, results[i] ?? 0n));
|
|
266
|
-
}
|
|
183
|
+
const results = await Promise.all(accounts.map((acc) => this.getOkbBalance(acc)));
|
|
184
|
+
accounts.forEach((acc, i) => balances.set(acc, results[i]));
|
|
267
185
|
return balances;
|
|
268
186
|
}
|
|
269
187
|
/**
|
|
@@ -271,43 +189,8 @@ export class PortalQuery {
|
|
|
271
189
|
*/
|
|
272
190
|
async getMultipleAllowances(tokenAddress, owners, spender) {
|
|
273
191
|
const allowances = new Map();
|
|
274
|
-
const
|
|
275
|
-
|
|
276
|
-
return allowances;
|
|
277
|
-
const useSpender = spender ?? this.portalAddress;
|
|
278
|
-
const calls = list.map((owner) => ({
|
|
279
|
-
target: tokenAddress,
|
|
280
|
-
allowFailure: true,
|
|
281
|
-
callData: erc20Iface.encodeFunctionData('allowance', [owner, useSpender]),
|
|
282
|
-
}));
|
|
283
|
-
const BATCH = 350;
|
|
284
|
-
try {
|
|
285
|
-
for (let cursor = 0; cursor < calls.length; cursor += BATCH) {
|
|
286
|
-
const sliceCalls = calls.slice(cursor, cursor + BATCH);
|
|
287
|
-
const res = await this.multicallAggregate3({ calls: sliceCalls });
|
|
288
|
-
for (let i = 0; i < res.length; i++) {
|
|
289
|
-
const r = res[i];
|
|
290
|
-
const idx = cursor + i;
|
|
291
|
-
const owner = list[idx];
|
|
292
|
-
if (!r?.success || !r.returnData || r.returnData === '0x') {
|
|
293
|
-
allowances.set(owner, 0n);
|
|
294
|
-
continue;
|
|
295
|
-
}
|
|
296
|
-
try {
|
|
297
|
-
const decoded = erc20Iface.decodeFunctionResult('allowance', r.returnData);
|
|
298
|
-
allowances.set(owner, BigInt(decoded?.[0] ?? 0n));
|
|
299
|
-
}
|
|
300
|
-
catch {
|
|
301
|
-
allowances.set(owner, 0n);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
return allowances;
|
|
306
|
-
}
|
|
307
|
-
catch {
|
|
308
|
-
const results = await mapWithConcurrency(list, 8, async (owner) => this.getAllowance(tokenAddress, owner, useSpender));
|
|
309
|
-
list.forEach((owner, i) => allowances.set(owner, results[i] ?? 0n));
|
|
310
|
-
}
|
|
192
|
+
const results = await Promise.all(owners.map((owner) => this.getAllowance(tokenAddress, owner, spender)));
|
|
193
|
+
owners.forEach((owner, i) => allowances.set(owner, results[i]));
|
|
311
194
|
return allowances;
|
|
312
195
|
}
|
|
313
196
|
}
|
package/dist/xlayer/types.d.ts
CHANGED
|
@@ -41,17 +41,6 @@ export interface GasEstimate {
|
|
|
41
41
|
maxFeePerGas?: HexString;
|
|
42
42
|
maxPriorityFeePerGas?: HexString;
|
|
43
43
|
}
|
|
44
|
-
export type GasPolicy = 'fixed' | 'localEstimate' | 'bundlerEstimate';
|
|
45
|
-
export interface FixedGasConfig {
|
|
46
|
-
/** callGasLimit(若不提供,SDK 会使用较保守的默认值) */
|
|
47
|
-
callGasLimit?: bigint;
|
|
48
|
-
/** 已部署 sender 的 verificationGasLimit(默认用 SDK 常量) */
|
|
49
|
-
verificationGasLimitDeployed?: bigint;
|
|
50
|
-
/** 未部署 sender 的 verificationGasLimit(默认用 SDK 常量) */
|
|
51
|
-
verificationGasLimitUndeployed?: bigint;
|
|
52
|
-
/** preVerificationGas(默认用 SDK 常量) */
|
|
53
|
-
preVerificationGas?: bigint;
|
|
54
|
-
}
|
|
55
44
|
/**
|
|
56
45
|
* XLayer SDK 基础配置
|
|
57
46
|
*/
|
|
@@ -76,15 +65,6 @@ export interface XLayerConfig {
|
|
|
76
65
|
timeoutMs?: number;
|
|
77
66
|
/** Gas 估算安全余量倍数 */
|
|
78
67
|
gasLimitMultiplier?: number;
|
|
79
|
-
/**
|
|
80
|
-
* AA Gas 策略(用于大规模地址时减少 RPC)
|
|
81
|
-
* - fixed:固定 gas(不 estimate)
|
|
82
|
-
* - localEstimate:eth_estimateGas(不走 bundler)
|
|
83
|
-
* - bundlerEstimate:eth_estimateUserOperationGas(最慢但最稳)
|
|
84
|
-
*/
|
|
85
|
-
gasPolicy?: GasPolicy;
|
|
86
|
-
/** fixed 策略的默认 gas 配置(可被每次调用覆盖) */
|
|
87
|
-
fixedGas?: FixedGasConfig;
|
|
88
68
|
}
|
|
89
69
|
/**
|
|
90
70
|
* AA 账户信息
|