four-flap-meme-sdk 1.5.20 → 1.5.22

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.
@@ -11,6 +11,7 @@ import { Wallet, Interface, Contract } from 'ethers';
11
11
  import { FLAP_PORTAL, ENTRYPOINT_ABI, DEFAULT_CALL_GAS_LIMIT_SELL, DEFAULT_WITHDRAW_RESERVE, } from './constants.js';
12
12
  import { AAAccountManager, encodeExecute } from './aa-account.js';
13
13
  import { encodeBuyCall, encodeSellCall, encodeApproveCall, encodeTransferCall, PortalQuery, parseOkb, formatOkb, } from './portal-ops.js';
14
+ import { mapWithConcurrency } from '../utils/concurrency.js';
14
15
  // ============================================================================
15
16
  // 捆绑交易执行器
16
17
  // ============================================================================
@@ -129,45 +130,46 @@ export class BundleExecutor {
129
130
  /**
130
131
  * 构建授权 UserOp
131
132
  */
132
- async buildApproveUserOp(ownerWallet, tokenAddress, spender, nonce, ownerName) {
133
- const accountInfo = await this.aaManager.getAccountInfo(ownerWallet.address);
133
+ async buildApproveUserOp(ownerWallet, tokenAddress, spender, sender, nonce, initCode, ownerName) {
134
134
  const approveData = encodeApproveCall(spender);
135
135
  const callData = encodeExecute(tokenAddress, 0n, approveData);
136
- await this.aaManager.ensureSenderBalance(ownerWallet, accountInfo.sender, parseOkb('0.0002'), `${ownerName ?? 'owner'}/approve-prefund`);
136
+ await this.aaManager.ensureSenderBalance(ownerWallet, sender, parseOkb('0.0002'), `${ownerName ?? 'owner'}/approve-prefund`);
137
137
  const { userOp, prefundWei } = await this.aaManager.buildUserOpWithLocalEstimate({
138
138
  ownerWallet,
139
- sender: accountInfo.sender,
139
+ sender,
140
140
  callData,
141
141
  nonce,
142
+ initCode,
142
143
  });
143
- await this.aaManager.ensureSenderBalance(ownerWallet, accountInfo.sender, prefundWei + parseOkb('0.00005'), `${ownerName ?? 'owner'}/approve-fund`);
144
+ await this.aaManager.ensureSenderBalance(ownerWallet, sender, prefundWei + parseOkb('0.00005'), `${ownerName ?? 'owner'}/approve-fund`);
144
145
  const signed = await this.aaManager.signUserOp(userOp, ownerWallet);
145
146
  return { ...signed, prefundWei, ownerName };
146
147
  }
147
148
  /**
148
149
  * 构建卖出 UserOp
149
150
  */
150
- async buildSellUserOp(ownerWallet, tokenAddress, sellAmount, nonce, needApprove, ownerName) {
151
- const accountInfo = await this.aaManager.getAccountInfo(ownerWallet.address);
151
+ async buildSellUserOp(ownerWallet, tokenAddress, sellAmount, sender, nonce, initCode, needApprove, ownerName) {
152
152
  const sellData = encodeSellCall(tokenAddress, sellAmount, 0n);
153
153
  const callData = encodeExecute(this.portalAddress, 0n, sellData);
154
- await this.aaManager.ensureSenderBalance(ownerWallet, accountInfo.sender, parseOkb('0.0003'), `${ownerName ?? 'owner'}/sell-prefund`);
154
+ await this.aaManager.ensureSenderBalance(ownerWallet, sender, parseOkb('0.0003'), `${ownerName ?? 'owner'}/sell-prefund`);
155
155
  // 如果需要 approve(还未执行),estimateGas 会 revert,使用固定值
156
156
  const { userOp, prefundWei } = needApprove
157
157
  ? await this.aaManager.buildUserOpWithLocalEstimate({
158
158
  ownerWallet,
159
- sender: accountInfo.sender,
159
+ sender,
160
160
  callData,
161
161
  nonce,
162
+ initCode,
162
163
  callGasLimit: DEFAULT_CALL_GAS_LIMIT_SELL,
163
164
  })
164
165
  : await this.aaManager.buildUserOpWithLocalEstimate({
165
166
  ownerWallet,
166
- sender: accountInfo.sender,
167
+ sender,
167
168
  callData,
168
169
  nonce,
170
+ initCode,
169
171
  });
170
- await this.aaManager.ensureSenderBalance(ownerWallet, accountInfo.sender, prefundWei + parseOkb('0.00005'), `${ownerName ?? 'owner'}/sell-fund`);
172
+ await this.aaManager.ensureSenderBalance(ownerWallet, sender, prefundWei + parseOkb('0.00005'), `${ownerName ?? 'owner'}/sell-fund`);
171
173
  const signed = await this.aaManager.signUserOp(userOp, ownerWallet);
172
174
  return { ...signed, prefundWei, ownerName };
173
175
  }
@@ -177,39 +179,56 @@ export class BundleExecutor {
177
179
  async buildWithdrawUserOp(ownerWallet, reserveWei, ownerName) {
178
180
  const accountInfo = await this.aaManager.getAccountInfo(ownerWallet.address);
179
181
  const senderBalance = await this.portalQuery.getOkbBalance(accountInfo.sender);
180
- if (senderBalance <= reserveWei) {
181
- console.log(`\n[${ownerName ?? 'owner'}] sender OKB 太少,跳过归集:${formatOkb(senderBalance)} OKB`);
182
+ const initCode = accountInfo.deployed ? '0x' : this.aaManager.generateInitCode(ownerWallet.address);
183
+ return await this.buildWithdrawUserOpWithState({
184
+ ownerWallet,
185
+ sender: accountInfo.sender,
186
+ nonce: accountInfo.nonce,
187
+ initCode,
188
+ senderBalance,
189
+ reserveWei,
190
+ ownerName,
191
+ });
192
+ }
193
+ /**
194
+ * 构建归集 UserOp(已知 sender/nonce/balance 的快速版本)
195
+ * - 用于批量流程:避免重复 getAccountInfo / getOkbBalance
196
+ */
197
+ async buildWithdrawUserOpWithState(params) {
198
+ const senderBalance = params.senderBalance;
199
+ if (senderBalance <= params.reserveWei) {
200
+ console.log(`\n[${params.ownerName ?? 'owner'}] sender OKB 太少,跳过归集:${formatOkb(senderBalance)} OKB`);
182
201
  return null;
183
202
  }
184
- // 先估算 prefund
185
- const tempCallData = encodeExecute(ownerWallet.address, 0n, '0x');
186
- await this.aaManager.ensureSenderBalance(ownerWallet, accountInfo.sender, parseOkb('0.0002'), `${ownerName ?? 'owner'}/withdraw-prefund`);
203
+ // 先估算 prefund(使用空调用)
204
+ const tempCallData = encodeExecute(params.ownerWallet.address, 0n, '0x');
205
+ await this.aaManager.ensureSenderBalance(params.ownerWallet, params.sender, parseOkb('0.0002'), `${params.ownerName ?? 'owner'}/withdraw-prefund`);
187
206
  const { prefundWei } = await this.aaManager.buildUserOpWithLocalEstimate({
188
- ownerWallet,
189
- sender: accountInfo.sender,
207
+ ownerWallet: params.ownerWallet,
208
+ sender: params.sender,
190
209
  callData: tempCallData,
191
- nonce: accountInfo.nonce,
210
+ nonce: params.nonce,
211
+ initCode: params.initCode,
192
212
  });
193
- // 计算可归集金额
194
- const currentBalance = await this.portalQuery.getOkbBalance(accountInfo.sender);
195
- const withdrawAmount = currentBalance > prefundWei + reserveWei
196
- ? currentBalance - prefundWei - reserveWei
213
+ // 计算可归集金额(用已知余额近似;fund 发生时余额会变大,属于可接受的保守近似)
214
+ const withdrawAmount = senderBalance > prefundWei + params.reserveWei
215
+ ? senderBalance - prefundWei - params.reserveWei
197
216
  : 0n;
198
217
  if (withdrawAmount <= 0n) {
199
- console.log(`\n[${ownerName ?? 'owner'}] 归集后可转出=0(余额不足以覆盖 prefund+reserve)`);
218
+ console.log(`\n[${params.ownerName ?? 'owner'}] 归集后可转出=0(余额不足以覆盖 prefund+reserve)`);
200
219
  return null;
201
220
  }
202
- // 真正的 callData
203
- const callData = encodeExecute(ownerWallet.address, withdrawAmount, '0x');
221
+ const callData = encodeExecute(params.ownerWallet.address, withdrawAmount, '0x');
204
222
  const { userOp } = await this.aaManager.buildUserOpWithLocalEstimate({
205
- ownerWallet,
206
- sender: accountInfo.sender,
223
+ ownerWallet: params.ownerWallet,
224
+ sender: params.sender,
207
225
  callData,
208
- nonce: accountInfo.nonce,
226
+ nonce: params.nonce,
227
+ initCode: params.initCode,
209
228
  });
210
- console.log(`\n[${ownerName ?? 'owner'}] withdraw: ${formatOkb(withdrawAmount)} OKB`);
211
- const signed = await this.aaManager.signUserOp(userOp, ownerWallet);
212
- return { ...signed, prefundWei, ownerName };
229
+ console.log(`\n[${params.ownerName ?? 'owner'}] withdraw: ${formatOkb(withdrawAmount)} OKB`);
230
+ const signed = await this.aaManager.signUserOp(userOp, params.ownerWallet);
231
+ return { ...signed, prefundWei, ownerName: params.ownerName };
213
232
  }
214
233
  /**
215
234
  * 构建代币转账 UserOp(将代币从 sender 转回 owner)
@@ -338,12 +357,14 @@ export class BundleExecutor {
338
357
  console.log('token:', tokenAddress);
339
358
  console.log('owners:', wallets.length);
340
359
  console.log('sellPercent:', sellPercent);
341
- // 获取 sender 列表和余额
342
- const senders = await Promise.all(wallets.map((w) => this.aaManager.predictSenderAddress(w.address)));
360
+ // 批量获取 accountInfo(含 sender/nonce/deployed),避免循环内重复 getAccountInfo
361
+ const accountInfos = await this.aaManager.getMultipleAccountInfo(wallets.map((w) => w.address));
362
+ const senders = accountInfos.map((ai) => ai.sender);
343
363
  const tokenBalances = await this.portalQuery.getMultipleTokenBalances(tokenAddress, senders);
344
364
  const allowances = await this.portalQuery.getMultipleAllowances(tokenAddress, senders);
345
365
  // 1. 检查授权,必要时先 approve
346
- const approveOps = [];
366
+ const approveItems = [];
367
+ const didApprove = new Array(wallets.length).fill(false);
347
368
  for (let i = 0; i < wallets.length; i++) {
348
369
  const sender = senders[i];
349
370
  const balance = tokenBalances.get(sender) ?? 0n;
@@ -352,9 +373,20 @@ export class BundleExecutor {
352
373
  continue;
353
374
  if (allowance >= balance)
354
375
  continue;
355
- const accountInfo = await this.aaManager.getAccountInfo(wallets[i].address);
356
- const signed = await this.buildApproveUserOp(wallets[i], tokenAddress, this.portalAddress, accountInfo.nonce, `owner${i + 1}`);
357
- approveOps.push(signed.userOp);
376
+ const ai = accountInfos[i];
377
+ const initCode = ai.deployed ? '0x' : this.aaManager.generateInitCode(wallets[i].address);
378
+ approveItems.push({ i, sender, nonce: ai.nonce, initCode });
379
+ didApprove[i] = true;
380
+ }
381
+ const approveOps = [];
382
+ if (approveItems.length > 0) {
383
+ const signedApproves = await mapWithConcurrency(approveItems, 4, async (it) => {
384
+ const i = it.i;
385
+ const signed = await this.buildApproveUserOp(wallets[i], tokenAddress, this.portalAddress, it.sender, it.nonce, it.initCode, `owner${i + 1}`);
386
+ return { i, userOp: signed.userOp };
387
+ });
388
+ for (const r of signedApproves)
389
+ approveOps.push(r.userOp);
358
390
  }
359
391
  let approveResult;
360
392
  if (approveOps.length > 0) {
@@ -362,6 +394,7 @@ export class BundleExecutor {
362
394
  }
363
395
  // 2. 卖出
364
396
  const sellOps = [];
397
+ const sellItems = [];
365
398
  for (let i = 0; i < wallets.length; i++) {
366
399
  const sender = senders[i];
367
400
  const balance = tokenBalances.get(sender) ?? 0n;
@@ -370,11 +403,20 @@ export class BundleExecutor {
370
403
  const sellAmount = (balance * BigInt(sellPercent)) / 100n;
371
404
  if (sellAmount === 0n)
372
405
  continue;
373
- const accountInfo = await this.aaManager.getAccountInfo(wallets[i].address);
374
- const allowance = allowances.get(sender) ?? 0n;
375
- const needApprove = allowance < sellAmount && approveOps.length > 0;
376
- const signed = await this.buildSellUserOp(wallets[i], tokenAddress, sellAmount, accountInfo.nonce, needApprove, `owner${i + 1}`);
377
- sellOps.push(signed.userOp);
406
+ const ai = accountInfos[i];
407
+ const initCode = ai.deployed ? '0x' : this.aaManager.generateInitCode(wallets[i].address);
408
+ // approve 已单独打包并等待确认,因此这里不需要用“needApprove=真”去走保守 callGasLimit
409
+ const needApprove = false;
410
+ const nonce = ai.nonce + (didApprove[i] ? 1n : 0n);
411
+ sellItems.push({ i, sender, nonce, initCode: didApprove[i] ? '0x' : initCode, needApprove, sellAmount });
412
+ }
413
+ if (sellItems.length > 0) {
414
+ const signedSells = await mapWithConcurrency(sellItems, 4, async (it) => {
415
+ const i = it.i;
416
+ const signed = await this.buildSellUserOp(wallets[i], tokenAddress, it.sellAmount, it.sender, it.nonce, it.initCode, it.needApprove, `owner${i + 1}`);
417
+ return signed.userOp;
418
+ });
419
+ sellOps.push(...signedSells);
378
420
  }
379
421
  const sellResult = await this.runHandleOps('sellBundle', sellOps, bundlerSigner, beneficiary);
380
422
  if (!sellResult) {
@@ -384,11 +426,42 @@ export class BundleExecutor {
384
426
  let withdrawResult;
385
427
  if (withdrawToOwner) {
386
428
  const withdrawOps = [];
429
+ // 批量获取 sender OKB 余额
430
+ const okbBalances = await this.portalQuery.getMultipleOkbBalances(senders);
431
+ // 计算 sell 后的下一 nonce
432
+ const nextNonces = new Array(wallets.length).fill(0n);
433
+ const sold = new Array(wallets.length).fill(false);
434
+ for (const it of sellItems) {
435
+ sold[it.i] = true;
436
+ }
387
437
  for (let i = 0; i < wallets.length; i++) {
388
- const signed = await this.buildWithdrawUserOp(wallets[i], reserveWei, `owner${i + 1}`);
389
- if (signed) {
390
- withdrawOps.push(signed.userOp);
391
- }
438
+ const ai = accountInfos[i];
439
+ const sellNonceUsed = ai.nonce + (didApprove[i] ? 1n : 0n);
440
+ nextNonces[i] = sold[i] ? (sellNonceUsed + 1n) : (ai.nonce + (didApprove[i] ? 1n : 0n));
441
+ }
442
+ const withdrawItems = wallets.map((w, i) => ({
443
+ i,
444
+ ownerWallet: w,
445
+ sender: senders[i],
446
+ senderBalance: okbBalances.get(senders[i]) ?? 0n,
447
+ nonce: nextNonces[i],
448
+ initCode: (accountInfos[i].deployed || didApprove[i] || sold[i]) ? '0x' : this.aaManager.generateInitCode(wallets[i].address),
449
+ }));
450
+ const signedWithdraws = await mapWithConcurrency(withdrawItems, 3, async (it) => {
451
+ const signed = await this.buildWithdrawUserOpWithState({
452
+ ownerWallet: it.ownerWallet,
453
+ sender: it.sender,
454
+ nonce: it.nonce,
455
+ initCode: it.initCode,
456
+ senderBalance: it.senderBalance,
457
+ reserveWei,
458
+ ownerName: `owner${it.i + 1}`,
459
+ });
460
+ return signed?.userOp ?? null;
461
+ });
462
+ for (const op of signedWithdraws) {
463
+ if (op)
464
+ withdrawOps.push(op);
392
465
  }
393
466
  if (withdrawOps.length > 0) {
394
467
  withdrawResult = await this.runHandleOps('withdrawBundle', withdrawOps, bundlerSigner, beneficiary) ?? undefined;
@@ -415,15 +488,36 @@ export class BundleExecutor {
415
488
  console.log('token:', tokenAddress);
416
489
  console.log('owners:', wallets.length);
417
490
  console.log('sellPercent:', sellPercent);
418
- // 获取 sender 列表
419
- const senders = await Promise.all(wallets.map((w) => this.aaManager.predictSenderAddress(w.address)));
420
- // 1. 买入
421
- const buyOps = [];
422
- for (let i = 0; i < wallets.length; i++) {
423
- const buyWei = parseOkb(buyAmounts[i]);
424
- const signed = await this.buildBuyUserOp(wallets[i], tokenAddress, buyWei, `owner${i + 1}`);
425
- buyOps.push(signed.userOp);
426
- }
491
+ // 批量获取 accountInfo(含 sender/nonce/deployed)
492
+ const accountInfos = await this.aaManager.getMultipleAccountInfo(wallets.map((w) => w.address));
493
+ const senders = accountInfos.map((ai) => ai.sender);
494
+ // 1. 买入(批量估算 + 并发补余额 + 并发签名)
495
+ const buyWeis = buyAmounts.map((a) => parseOkb(a));
496
+ await mapWithConcurrency(accountInfos, 6, async (ai, i) => {
497
+ const buyWei = buyWeis[i] ?? 0n;
498
+ if (buyWei <= 0n)
499
+ return;
500
+ await this.aaManager.ensureSenderBalance(wallets[i], ai.sender, buyWei + parseOkb('0.0003'), `owner${i + 1}/buy-prefund-before-estimate`);
501
+ });
502
+ const buyCallDatas = buyWeis.map((buyWei) => {
503
+ const swapData = encodeBuyCall(tokenAddress, buyWei, 0n);
504
+ return encodeExecute(this.portalAddress, buyWei, swapData);
505
+ });
506
+ const initCodes = accountInfos.map((ai, i) => (ai.deployed ? '0x' : this.aaManager.generateInitCode(wallets[i].address)));
507
+ const { userOps: buyUserOps, prefundWeis } = await this.aaManager.buildUserOpsWithBundlerEstimateBatch({
508
+ ops: accountInfos.map((ai, i) => ({
509
+ sender: ai.sender,
510
+ nonce: ai.nonce,
511
+ callData: buyCallDatas[i],
512
+ initCode: initCodes[i],
513
+ })),
514
+ });
515
+ await mapWithConcurrency(accountInfos, 6, async (ai, i) => {
516
+ const buyWei = buyWeis[i] ?? 0n;
517
+ await this.aaManager.ensureSenderBalance(wallets[i], ai.sender, buyWei + (prefundWeis[i] ?? 0n) + parseOkb('0.0002'), `owner${i + 1}/buy-fund`);
518
+ });
519
+ const signedBuy = await mapWithConcurrency(buyUserOps, 10, async (op, i) => this.aaManager.signUserOp(op, wallets[i]));
520
+ const buyOps = signedBuy.map((s) => s.userOp);
427
521
  const buyResult = await this.runHandleOps('buyBundle', buyOps, bundlerSigner, beneficiary);
428
522
  if (!buyResult) {
429
523
  throw new Error('买入交易失败');
@@ -433,27 +527,33 @@ export class BundleExecutor {
433
527
  const allowances = await this.portalQuery.getMultipleAllowances(tokenAddress, senders);
434
528
  // 2. 授权 + 卖出(可以合并到同一笔 handleOps)
435
529
  const sellOps = [];
436
- for (let i = 0; i < wallets.length; i++) {
530
+ const sellPerWallet = await mapWithConcurrency(wallets, 4, async (w, i) => {
437
531
  const sender = senders[i];
438
532
  const balance = tokenBalances.get(sender) ?? 0n;
439
533
  if (balance === 0n) {
440
534
  console.log(`[owner${i + 1}] 没买到代币,跳过卖出`);
441
- continue;
535
+ return [];
442
536
  }
443
537
  const allowance = allowances.get(sender) ?? 0n;
444
- let baseNonce = (await this.aaManager.getAccountInfo(wallets[i].address)).nonce;
445
- // 如果需要授权,先添加 approve op
446
538
  const needApprove = allowance < balance;
539
+ // buy 已在上一笔 handleOps 执行,因此 nonce = 原 nonce + 1
540
+ let nonce = accountInfos[i].nonce + 1n;
541
+ const initCode = '0x';
542
+ const out = [];
447
543
  if (needApprove) {
448
- const approveOp = await this.buildApproveUserOp(wallets[i], tokenAddress, this.portalAddress, baseNonce, `owner${i + 1}`);
449
- sellOps.push(approveOp.userOp);
450
- baseNonce = baseNonce + 1n;
544
+ const approveOp = await this.buildApproveUserOp(w, tokenAddress, this.portalAddress, sender, nonce, initCode, `owner${i + 1}`);
545
+ out.push(approveOp.userOp);
546
+ nonce = nonce + 1n;
451
547
  }
452
- // 添加 sell op
453
548
  const sellAmount = (balance * BigInt(sellPercent)) / 100n;
454
- const sellOp = await this.buildSellUserOp(wallets[i], tokenAddress, sellAmount, baseNonce, needApprove, `owner${i + 1}`);
455
- sellOps.push(sellOp.userOp);
456
- }
549
+ if (sellAmount === 0n)
550
+ return out;
551
+ const sellOp = await this.buildSellUserOp(w, tokenAddress, sellAmount, sender, nonce, initCode, needApprove, `owner${i + 1}`);
552
+ out.push(sellOp.userOp);
553
+ return out;
554
+ });
555
+ for (const ops of sellPerWallet)
556
+ sellOps.push(...ops);
457
557
  const sellResult = await this.runHandleOps('sellBundle', sellOps, bundlerSigner, beneficiary);
458
558
  if (!sellResult) {
459
559
  throw new Error('卖出交易失败');
@@ -462,11 +562,41 @@ export class BundleExecutor {
462
562
  let withdrawResult;
463
563
  if (withdrawToOwner) {
464
564
  const withdrawOps = [];
465
- for (let i = 0; i < wallets.length; i++) {
466
- const signed = await this.buildWithdrawUserOp(wallets[i], reserveWei, `owner${i + 1}`);
467
- if (signed) {
468
- withdrawOps.push(signed.userOp);
469
- }
565
+ // 批量获取 OKB 余额(sell 后状态)
566
+ const okbBalances = await this.portalQuery.getMultipleOkbBalances(senders);
567
+ // sell handleOps 里每个 wallet:一定有 sell op(balance>0)且可能还有 approve op
568
+ const nextNonces = wallets.map((_, i) => {
569
+ const sender = senders[i];
570
+ const bal = tokenBalances.get(sender) ?? 0n;
571
+ if (bal === 0n)
572
+ return accountInfos[i].nonce + 1n; // buy 后但未 sell
573
+ const allowance = allowances.get(sender) ?? 0n;
574
+ const needApprove = allowance < bal;
575
+ return accountInfos[i].nonce + 1n + (needApprove ? 2n : 1n);
576
+ });
577
+ const withdrawItems = wallets.map((w, i) => ({
578
+ i,
579
+ ownerWallet: w,
580
+ sender: senders[i],
581
+ senderBalance: okbBalances.get(senders[i]) ?? 0n,
582
+ nonce: nextNonces[i],
583
+ initCode: '0x',
584
+ }));
585
+ const signedWithdraws = await mapWithConcurrency(withdrawItems, 3, async (it) => {
586
+ const signed = await this.buildWithdrawUserOpWithState({
587
+ ownerWallet: it.ownerWallet,
588
+ sender: it.sender,
589
+ nonce: it.nonce,
590
+ initCode: it.initCode,
591
+ senderBalance: it.senderBalance,
592
+ reserveWei,
593
+ ownerName: `owner${it.i + 1}`,
594
+ });
595
+ return signed?.userOp ?? null;
596
+ });
597
+ for (const op of signedWithdraws) {
598
+ if (op)
599
+ withdrawOps.push(op);
470
600
  }
471
601
  if (withdrawOps.length > 0) {
472
602
  withdrawResult = await this.runHandleOps('withdrawBundle', withdrawOps, bundlerSigner, beneficiary) ?? undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.5.20",
3
+ "version": "1.5.22",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",