@tokenops/sdk 1.5.1 → 1.6.0

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.
Files changed (120) hide show
  1. package/CHANGELOG.md +158 -2
  2. package/SECURITY.md +7 -1
  3. package/dist/{chunk-67OV5CX2.cjs → chunk-2RNW4MIJ.cjs} +18 -0
  4. package/dist/{chunk-KLKI352M.cjs → chunk-43RFBQ73.cjs} +29 -29
  5. package/dist/{chunk-ZA673I3O.js → chunk-46T67CE2.js} +1 -1
  6. package/dist/{chunk-6BMP4ICG.js → chunk-4KJ66YRH.js} +61 -3
  7. package/dist/{chunk-JYOTGRSO.cjs → chunk-4ZCXK4VI.cjs} +68 -8
  8. package/dist/{chunk-SG65XWH7.js → chunk-6WSNS3UV.js} +1 -1
  9. package/dist/{chunk-V2PXZVBF.cjs → chunk-7G7UOQV4.cjs} +4 -4
  10. package/dist/{chunk-WENHUPZC.cjs → chunk-AYGRYDBX.cjs} +35 -36
  11. package/dist/{chunk-2NCLOQ56.cjs → chunk-BD4LZBVF.cjs} +85 -9
  12. package/dist/{chunk-5X5WL5CU.cjs → chunk-BK7YIVLK.cjs} +110 -149
  13. package/dist/{chunk-W7IGCOVL.cjs → chunk-CBRL2PJA.cjs} +12 -11
  14. package/dist/{chunk-ORFTDNFZ.js → chunk-CNP4L3GF.js} +4 -4
  15. package/dist/{chunk-QBJ7O2B4.js → chunk-DRSPMIZ7.js} +11 -1
  16. package/dist/{chunk-C7BRZXJA.cjs → chunk-EUKPOXWR.cjs} +15 -16
  17. package/dist/{chunk-YQIBBEFJ.js → chunk-HETNKZEE.js} +1 -1
  18. package/dist/{chunk-ODLTEGHB.js → chunk-KSDSXJ34.js} +1 -1
  19. package/dist/{chunk-TIUKIY5V.cjs → chunk-LBWRFZR3.cjs} +58 -40
  20. package/dist/{chunk-WMACINXO.js → chunk-NFW7AUEX.js} +1 -1
  21. package/dist/{chunk-4WPGQSNT.cjs → chunk-OL6SHN3D.cjs} +3 -3
  22. package/dist/{chunk-AOP6HMPW.js → chunk-PD7ME2BT.js} +75 -2
  23. package/dist/{chunk-2PWNH3UE.js → chunk-QET3Q4JP.js} +65 -9
  24. package/dist/{chunk-XGGTQQFH.js → chunk-QKKBBH7I.js} +2 -2
  25. package/dist/{chunk-6R4KNAPK.js → chunk-S2XD75JM.js} +10 -3
  26. package/dist/{chunk-MCRBVJGZ.cjs → chunk-SPGSO5SO.cjs} +29 -22
  27. package/dist/{chunk-FAXIIH5R.cjs → chunk-SYHNZSZZ.cjs} +3 -3
  28. package/dist/{chunk-IXLO7GO5.js → chunk-TN65XNTI.js} +47 -83
  29. package/dist/chunk-U57COLUE.js +56 -0
  30. package/dist/{chunk-DUZIIRPF.js → chunk-UE5XK2SY.js} +27 -9
  31. package/dist/{chunk-TEBM66WA.cjs → chunk-UJS4N2XM.cjs} +12 -12
  32. package/dist/{chunk-OXTLPTO3.js → chunk-V5D7BHW3.js} +4 -5
  33. package/dist/{chunk-NTZY6IB7.js → chunk-VHSNYUYV.js} +5 -4
  34. package/dist/{chunk-JK4XMMKM.cjs → chunk-VR3FREBX.cjs} +3 -3
  35. package/dist/{chunk-T46YXSBP.cjs → chunk-WO72UBQD.cjs} +11 -11
  36. package/dist/chunk-WOEETTH7.cjs +59 -0
  37. package/dist/{chunk-IJFQ5L4I.js → chunk-WTK6JDSI.js} +4 -5
  38. package/dist/{chunk-PUPKNW3R.cjs → chunk-WUXUWTFW.cjs} +3 -3
  39. package/dist/{chunk-PFXURMBZ.cjs → chunk-YFIWCYHC.cjs} +112 -54
  40. package/dist/{chunk-ZWXJTBZO.js → chunk-YPYCWLYP.js} +1 -1
  41. package/dist/core/addresses.d.ts +1 -1
  42. package/dist/core/errors.d.ts +1 -1
  43. package/dist/fhe/index.cjs +84 -64
  44. package/dist/fhe/index.d.cts +1 -0
  45. package/dist/fhe/index.d.ts +1 -0
  46. package/dist/fhe/index.js +21 -9
  47. package/dist/fhe/mock-erc7984.d.ts +4 -4
  48. package/dist/fhe/operators.d.ts +142 -2
  49. package/dist/fhe/react/index.cjs +21 -8
  50. package/dist/fhe/react/index.d.cts +2 -0
  51. package/dist/fhe/react/index.d.ts +2 -0
  52. package/dist/fhe/react/index.js +8 -3
  53. package/dist/fhe/react/useEnsureOperator.d.ts +56 -0
  54. package/dist/fhe/react/useIsOperator.d.ts +54 -0
  55. package/dist/fhe/sepolia-encryptor-web.d.ts +18 -3
  56. package/dist/fhe-airdrop/advanced/index.cjs +8 -9
  57. package/dist/fhe-airdrop/advanced/index.js +6 -7
  58. package/dist/fhe-airdrop/advanced/react/index.cjs +13 -14
  59. package/dist/fhe-airdrop/advanced/react/index.js +9 -10
  60. package/dist/fhe-airdrop/airdrop.d.ts +7 -0
  61. package/dist/fhe-airdrop/index.cjs +66 -67
  62. package/dist/fhe-airdrop/index.js +7 -8
  63. package/dist/fhe-airdrop/react/index.cjs +148 -137
  64. package/dist/fhe-airdrop/react/index.d.cts +3 -1
  65. package/dist/fhe-airdrop/react/index.d.ts +3 -1
  66. package/dist/fhe-airdrop/react/index.js +16 -14
  67. package/dist/fhe-airdrop/react/useAccessClaimAmount.d.ts +17 -11
  68. package/dist/fhe-airdrop/react/useClaim.d.ts +8 -0
  69. package/dist/fhe-airdrop/react/useSignClaimAuthorization.d.ts +1 -1
  70. package/dist/fhe-airdrop/types.d.ts +14 -3
  71. package/dist/fhe-disperse/errors.d.ts +55 -0
  72. package/dist/fhe-disperse/index.cjs +74 -67
  73. package/dist/fhe-disperse/index.d.cts +1 -1
  74. package/dist/fhe-disperse/index.d.ts +1 -1
  75. package/dist/fhe-disperse/index.js +8 -9
  76. package/dist/fhe-disperse/react/index.cjs +105 -88
  77. package/dist/fhe-disperse/react/index.d.cts +3 -1
  78. package/dist/fhe-disperse/react/index.d.ts +3 -1
  79. package/dist/fhe-disperse/react/index.js +12 -11
  80. package/dist/fhe-vesting/advanced/index.cjs +8 -9
  81. package/dist/fhe-vesting/advanced/index.js +6 -7
  82. package/dist/fhe-vesting/advanced/react/index.cjs +14 -15
  83. package/dist/fhe-vesting/advanced/react/index.js +11 -12
  84. package/dist/fhe-vesting/index.cjs +75 -76
  85. package/dist/fhe-vesting/index.js +9 -10
  86. package/dist/fhe-vesting/manager.d.ts +19 -0
  87. package/dist/fhe-vesting/react/index.cjs +245 -227
  88. package/dist/fhe-vesting/react/index.d.cts +6 -4
  89. package/dist/fhe-vesting/react/index.d.ts +6 -4
  90. package/dist/fhe-vesting/react/index.js +27 -21
  91. package/dist/fhe-vesting/react/useAccessClaimableAmount.d.ts +11 -3
  92. package/dist/fhe-vesting/react/useAccessSettledAmount.d.ts +11 -3
  93. package/dist/fhe-vesting/react/useAccessTotalAllocation.d.ts +11 -3
  94. package/dist/fhe-vesting/react/useAccessVestedAmount.d.ts +11 -3
  95. package/dist/fhe-vesting/react/useAdminGetClaimableAmount.d.ts +1 -1
  96. package/dist/fhe-vesting/react/useAdminGetSettledAmount.d.ts +1 -1
  97. package/dist/fhe-vesting/react/useAdminGetTotalAllocation.d.ts +1 -1
  98. package/dist/fhe-vesting/react/useAdminGetVestedAmount.d.ts +1 -1
  99. package/dist/fhe-vesting/react/useAdminPartialClaim.d.ts +8 -0
  100. package/dist/fhe-vesting/react/useClaim.d.ts +1 -1
  101. package/dist/fhe-vesting/react/useDiscloseHandleToParty.d.ts +1 -1
  102. package/dist/fhe-vesting/react/useManagerDiscloseHandleToParty.d.ts +1 -1
  103. package/dist/fhe-vesting/react/usePartialClaim.d.ts +1 -1
  104. package/dist/fhe-vesting/react/useVestingInfo.d.ts +1 -1
  105. package/dist/fhe-vesting/types.d.ts +12 -1
  106. package/dist/index.cjs +87 -88
  107. package/dist/index.js +2 -3
  108. package/dist/testnet-faucet/index.cjs +55 -56
  109. package/dist/testnet-faucet/index.js +5 -6
  110. package/dist/testnet-faucet/react/index.cjs +53 -54
  111. package/dist/testnet-faucet/react/index.js +7 -8
  112. package/package.json +13 -8
  113. package/dist/chunk-66IHPTOK.cjs +0 -20
  114. package/dist/chunk-KWFFIJYX.js +0 -11
  115. package/dist/fhe-airdrop/react/useAirdropClaim.d.ts +0 -27
  116. package/dist/fhe-airdrop/react/useGetClaimAmount.d.ts +0 -30
  117. package/dist/fhe-vesting/react/useGetClaimableAmount.d.ts +0 -13
  118. package/dist/fhe-vesting/react/useGetSettledAmount.d.ts +0 -14
  119. package/dist/fhe-vesting/react/useGetTotalAllocation.d.ts +0 -13
  120. package/dist/fhe-vesting/react/useGetVestedAmount.d.ts +0 -25
@@ -1,11 +1,10 @@
1
- import { mapZamaError } from './chunk-WMACINXO.js';
2
- import { getFhevmAclAddress, requireFhevmAclAddress, ACL_ALLOWED_EVENT } from './chunk-ZWXJTBZO.js';
3
- import { SDK_VERSION, isContractRevert, mapContractRevert } from './chunk-SG65XWH7.js';
4
- import { getFheDisperseSingletonAddress } from './chunk-XGGTQQFH.js';
5
- import { normaliseAddress } from './chunk-ZA673I3O.js';
1
+ import { mapZamaError } from './chunk-NFW7AUEX.js';
2
+ import { getFhevmAclAddress, requireFhevmAclAddress, ACL_ALLOWED_EVENT } from './chunk-YPYCWLYP.js';
3
+ import { SDK_VERSION, isContractRevert, mapContractRevert } from './chunk-6WSNS3UV.js';
4
+ import { getFheDisperseSingletonAddress } from './chunk-QKKBBH7I.js';
5
+ import { normaliseAddress } from './chunk-46T67CE2.js';
6
+ import { InvalidArgumentError, asExternalInputProof, asEncryptedHandle, TokenOpsSdkError, DeploymentAddressUnavailableError, PausedError, InsufficientFeeError, MissingEncryptorError, ReceiptEventAmbiguousError, MissingWalletClientError, MissingAccountError, BatchTooLargeError } from './chunk-DRSPMIZ7.js';
6
7
  import { withTelemetry } from './chunk-Q2GP5UDC.js';
7
- import { asExternalInputProof, asEncryptedHandle } from './chunk-KWFFIJYX.js';
8
- import { InvalidArgumentError, TokenOpsSdkError, DeploymentAddressUnavailableError, PausedError, InsufficientFeeError, MissingEncryptorError, ReceiptEventAmbiguousError, MissingWalletClientError, MissingAccountError, BatchTooLargeError } from './chunk-QBJ7O2B4.js';
9
8
  import { bytesToHex, keccak256, encodePacked, parseEventLogs, isAddress, getCreate2Address } from 'viem';
10
9
 
11
10
  // src/fhe-disperse/abis/singleton.ts
@@ -1771,6 +1770,44 @@ var NotRegisteredError = class extends TokenOpsSdkError {
1771
1770
  );
1772
1771
  }
1773
1772
  };
1773
+ var SubwalletsNotApprovedError = class extends TokenOpsSdkError {
1774
+ name = "SubwalletsNotApprovedError";
1775
+ constructor(args) {
1776
+ super(
1777
+ `${args.method}: sub-wallets are not fully approved for token ${args.token} \u2014 wallet0: ${args.wallet0Approved}, wallet1: ${args.wallet1Approved}. Call \`approveUserWalletsForToken\` first.`,
1778
+ {
1779
+ code: "TOKENOPS_SUBWALLETS_NOT_APPROVED",
1780
+ cause: args.cause,
1781
+ context: {
1782
+ method: args.method,
1783
+ contractAddress: args.contractAddress,
1784
+ user: args.user,
1785
+ token: args.token,
1786
+ wallet0Approved: args.wallet0Approved,
1787
+ wallet1Approved: args.wallet1Approved
1788
+ }
1789
+ }
1790
+ );
1791
+ }
1792
+ };
1793
+ var SingletonNotApprovedError = class extends TokenOpsSdkError {
1794
+ name = "SingletonNotApprovedError";
1795
+ constructor(args) {
1796
+ super(
1797
+ `${args.method}: ${args.user} has not approved the singleton ${args.contractAddress} as an operator on token ${args.token}. Call setOperator() (see @tokenops/sdk/fhe) before this transaction.`,
1798
+ {
1799
+ code: "TOKENOPS_SINGLETON_NOT_APPROVED",
1800
+ cause: args.cause,
1801
+ context: {
1802
+ method: args.method,
1803
+ contractAddress: args.contractAddress,
1804
+ user: args.user,
1805
+ token: args.token
1806
+ }
1807
+ }
1808
+ );
1809
+ }
1810
+ };
1774
1811
  var AlreadyRegisteredError = class extends TokenOpsSdkError {
1775
1812
  name = "AlreadyRegisteredError";
1776
1813
  constructor(args) {
@@ -2335,13 +2372,32 @@ var ConfidentialDisperseClient = class {
2335
2372
  })
2336
2373
  );
2337
2374
  } else if (mode === "wallet" || mode === "wallet-token-fee") {
2338
- if (!hasApprovedSubwallets.both)
2375
+ if (!hasApprovedSubwallets.both) {
2339
2376
  blockers.push(
2340
2377
  `Wallets not fully approved for token \u2014 wallet0: ${hasApprovedSubwallets.wallet0}, wallet1: ${hasApprovedSubwallets.wallet1}`
2341
2378
  );
2379
+ blockerErrors.push(
2380
+ new SubwalletsNotApprovedError({
2381
+ method: "preflightDisperse",
2382
+ contractAddress: this.address,
2383
+ user: args.user,
2384
+ token: args.token,
2385
+ wallet0Approved: hasApprovedSubwallets.wallet0,
2386
+ wallet1Approved: hasApprovedSubwallets.wallet1
2387
+ })
2388
+ );
2389
+ }
2342
2390
  }
2343
2391
  if (mode === "direct" && hasApprovedSingleton === false) {
2344
2392
  blockers.push("Sender has not approved the singleton as operator on the token");
2393
+ blockerErrors.push(
2394
+ new SingletonNotApprovedError({
2395
+ method: "preflightDisperse",
2396
+ contractAddress: this.address,
2397
+ user: args.user,
2398
+ token: args.token
2399
+ })
2400
+ );
2345
2401
  }
2346
2402
  if (isPaused) {
2347
2403
  blockers.push("Singleton is paused");
@@ -3414,4 +3470,4 @@ var PAUSER_ROLE = "0x65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440
3414
3470
  var WITHDRAWER_ROLE = "0x10dac8c06a04bec0b551627dad28bc00d6516b0caacd1c7b345fcdb5211334e4";
3415
3471
  var DEFAULT_ADMIN_ROLE = "0x0000000000000000000000000000000000000000000000000000000000000000";
3416
3472
 
3417
- export { AlreadyRegisteredError, ConfidentialDisperseClient, DEFAULT_ADMIN_ROLE, DisperseEncryptedReserveNotGrantedError, DisperseSubwalletNotFoundError, FEE_COLLECTOR_ROLE, FEE_MANAGER_ROLE, NotRegisteredError, PAUSER_ROLE, WITHDRAWER_ROLE, computeSubtotals, createConfidentialDisperseClient, disperseConfidentialAbi, disperseWalletAbi, encryptUint64, encryptUint64Batch, resolveEncryptor };
3473
+ export { AlreadyRegisteredError, ConfidentialDisperseClient, DEFAULT_ADMIN_ROLE, DisperseEncryptedReserveNotGrantedError, DisperseSubwalletNotFoundError, FEE_COLLECTOR_ROLE, FEE_MANAGER_ROLE, NotRegisteredError, PAUSER_ROLE, SingletonNotApprovedError, SubwalletsNotApprovedError, WITHDRAWER_ROLE, computeSubtotals, createConfidentialDisperseClient, disperseConfidentialAbi, disperseWalletAbi, encryptUint64, encryptUint64Batch, resolveEncryptor };
@@ -1,10 +1,10 @@
1
- import { DeploymentAddressUnavailableError } from './chunk-QBJ7O2B4.js';
1
+ import { DeploymentAddressUnavailableError } from './chunk-DRSPMIZ7.js';
2
2
  import { sepolia, mainnet } from 'viem/chains';
3
3
 
4
4
  var DEPLOYED_ADDRESSES = {
5
5
  fheVesting: {
6
6
  confidentialVestingFactory: {
7
- [sepolia.id]: "0xA87701CE9A52D43681600583a99c85b50DbE3150"
7
+ [sepolia.id]: "0x059d6Bb8ff9a13E794fe416d4757d7310CdC69ab"
8
8
  // mainnet omitted — not deployed.
9
9
  }
10
10
  },
@@ -1,7 +1,7 @@
1
- import { getFhevmAclAddress, requireFhevmAclAddress, ACL_ALLOWED_EVENT } from './chunk-ZWXJTBZO.js';
2
- import { SDK_VERSION, mapContractRevert, isContractRevert } from './chunk-SG65XWH7.js';
1
+ import { getFhevmAclAddress, requireFhevmAclAddress, ACL_ALLOWED_EVENT } from './chunk-YPYCWLYP.js';
2
+ import { SDK_VERSION, mapContractRevert, isContractRevert } from './chunk-6WSNS3UV.js';
3
+ import { TokenOpsSdkError, PausedError, InsufficientFeeError, ReceiptEventNotFoundError, ReceiptEventAmbiguousError, InvalidArgumentError, MissingWalletClientError, MissingAccountError, InsufficientBalanceError, InvalidSignatureError } from './chunk-DRSPMIZ7.js';
3
4
  import { withTelemetry } from './chunk-Q2GP5UDC.js';
4
- import { TokenOpsSdkError, PausedError, InsufficientFeeError, ReceiptEventNotFoundError, ReceiptEventAmbiguousError, InvalidArgumentError, MissingWalletClientError, MissingAccountError, InsufficientBalanceError, InvalidSignatureError } from './chunk-QBJ7O2B4.js';
5
5
  import { parseEventLogs, isAddress } from 'viem';
6
6
 
7
7
  // src/fhe-airdrop/abis/cloneable.ts
@@ -1360,6 +1360,13 @@ var ConfidentialAirdropClient = class {
1360
1360
  *
1361
1361
  * **Silent-zero transfers.** ERC-7984 transfers do not revert when the sender's encrypted balance is insufficient — the transfer succeeds and moves an encrypted zero instead. This is by design: reverting would leak balance information. The transaction receipt alone cannot tell you whether value actually moved.
1362
1362
  *
1363
+ * **An unfunded pool is the opposite case — it reverts loudly.** Do not
1364
+ * generalize the silent-zero rule above to a clone whose pool was never
1365
+ * funded: that claim throws {@link FheHandleNotAllowedError} (the FHEVM ACL
1366
+ * rejects `FHE.allowTransient` on an uninitialized handle), and
1367
+ * {@link preflightClaim} cannot detect it because the pool balance is an
1368
+ * encrypted `euint64` the SDK cannot read in plaintext.
1369
+ *
1363
1370
  * @returns Transaction hash.
1364
1371
  * @example
1365
1372
  * const fee = await airdrop.gasFee();
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var chunkFAXIIH5R_cjs = require('./chunk-FAXIIH5R.cjs');
4
- var chunkKLKI352M_cjs = require('./chunk-KLKI352M.cjs');
3
+ var chunkSYHNZSZZ_cjs = require('./chunk-SYHNZSZZ.cjs');
4
+ var chunk43RFBQ73_cjs = require('./chunk-43RFBQ73.cjs');
5
+ var chunk2RNW4MIJ_cjs = require('./chunk-2RNW4MIJ.cjs');
5
6
  var chunkVJKZWYYJ_cjs = require('./chunk-VJKZWYYJ.cjs');
6
- var chunk67OV5CX2_cjs = require('./chunk-67OV5CX2.cjs');
7
7
  var viem = require('viem');
8
8
 
9
9
  // src/fhe-airdrop/abis/cloneable.ts
@@ -1016,7 +1016,7 @@ var confidentialAirdropCloneableAbi = [
1016
1016
  ];
1017
1017
 
1018
1018
  // src/fhe-airdrop/errors.ts
1019
- var AlreadyClaimedError = class extends chunk67OV5CX2_cjs.TokenOpsSdkError {
1019
+ var AlreadyClaimedError = class extends chunk2RNW4MIJ_cjs.TokenOpsSdkError {
1020
1020
  name = "AlreadyClaimedError";
1021
1021
  constructor(args) {
1022
1022
  const who = args.caller ? `${args.caller}: ` : "";
@@ -1031,7 +1031,7 @@ var AlreadyClaimedError = class extends chunk67OV5CX2_cjs.TokenOpsSdkError {
1031
1031
  });
1032
1032
  }
1033
1033
  };
1034
- var ClaimNotStartedError = class extends chunk67OV5CX2_cjs.TokenOpsSdkError {
1034
+ var ClaimNotStartedError = class extends chunk2RNW4MIJ_cjs.TokenOpsSdkError {
1035
1035
  name = "ClaimNotStartedError";
1036
1036
  constructor(args) {
1037
1037
  const detail = args.startsAt !== void 0 ? ` Opens at unix timestamp ${args.startsAt}.` : "";
@@ -1046,7 +1046,7 @@ var ClaimNotStartedError = class extends chunk67OV5CX2_cjs.TokenOpsSdkError {
1046
1046
  });
1047
1047
  }
1048
1048
  };
1049
- var ClaimWindowClosedError = class extends chunk67OV5CX2_cjs.TokenOpsSdkError {
1049
+ var ClaimWindowClosedError = class extends chunk2RNW4MIJ_cjs.TokenOpsSdkError {
1050
1050
  name = "ClaimWindowClosedError";
1051
1051
  constructor(args) {
1052
1052
  const detail = args.endedAt !== void 0 ? ` Closed at unix timestamp ${args.endedAt}.` : "";
@@ -1081,10 +1081,10 @@ var airdropProductMapper = (name, _args, ctx) => {
1081
1081
  case "ECDSAInvalidSignature":
1082
1082
  case "ECDSAInvalidSignatureS":
1083
1083
  case "ECDSAInvalidSignatureLength":
1084
- return new chunk67OV5CX2_cjs.InvalidSignatureError(ctx);
1084
+ return new chunk2RNW4MIJ_cjs.InvalidSignatureError(ctx);
1085
1085
  case "ZeroBalance":
1086
1086
  case "InsufficientBalance":
1087
- return CONFIDENTIAL_POOL_BALANCE_METHODS.has(ctx.method) ? new chunk67OV5CX2_cjs.InsufficientBalanceError({ ...ctx, balanceKind: "confidential" }) : void 0;
1087
+ return CONFIDENTIAL_POOL_BALANCE_METHODS.has(ctx.method) ? new chunk2RNW4MIJ_cjs.InsufficientBalanceError({ ...ctx, balanceKind: "confidential" }) : void 0;
1088
1088
  default:
1089
1089
  return void 0;
1090
1090
  }
@@ -1107,8 +1107,8 @@ var ConfidentialAirdropClient = class {
1107
1107
  surface: "client",
1108
1108
  chainId: chainIdForInit ?? null,
1109
1109
  hasWallet: !!this.walletClient,
1110
- aclResolved: !!config.aclAddress || chainIdForInit !== void 0 && !!chunkFAXIIH5R_cjs.getFhevmAclAddress(chainIdForInit),
1111
- sdkVersion: chunkKLKI352M_cjs.SDK_VERSION
1110
+ aclResolved: !!config.aclAddress || chainIdForInit !== void 0 && !!chunkSYHNZSZZ_cjs.getFhevmAclAddress(chainIdForInit),
1111
+ sdkVersion: chunk43RFBQ73_cjs.SDK_VERSION
1112
1112
  });
1113
1113
  }
1114
1114
  /**
@@ -1119,7 +1119,7 @@ var ConfidentialAirdropClient = class {
1119
1119
  */
1120
1120
  get aclAddress() {
1121
1121
  if (this.#cachedAclAddress) return this.#cachedAclAddress;
1122
- this.#cachedAclAddress = this.#aclAddressOverride ?? chunkFAXIIH5R_cjs.requireFhevmAclAddress(this.publicClient.chain?.id, "ConfidentialAirdropClient");
1122
+ this.#cachedAclAddress = this.#aclAddressOverride ?? chunkSYHNZSZZ_cjs.requireFhevmAclAddress(this.publicClient.chain?.id, "ConfidentialAirdropClient");
1123
1123
  return this.#cachedAclAddress;
1124
1124
  }
1125
1125
  // ============================================================
@@ -1254,7 +1254,7 @@ var ConfidentialAirdropClient = class {
1254
1254
  account: args.caller
1255
1255
  });
1256
1256
  } catch (err) {
1257
- throw chunkKLKI352M_cjs.mapContractRevert(err, {
1257
+ throw chunk43RFBQ73_cjs.mapContractRevert(err, {
1258
1258
  method: "isSignatureValid",
1259
1259
  contractAddress: this.address,
1260
1260
  abi: confidentialAirdropCloneableAbi,
@@ -1308,7 +1308,7 @@ var ConfidentialAirdropClient = class {
1308
1308
  ]);
1309
1309
  const now = Number(block.timestamp);
1310
1310
  if (isPaused) {
1311
- blockers.push(new chunk67OV5CX2_cjs.PausedError({ method: "claim", contractAddress: this.address }));
1311
+ blockers.push(new chunk2RNW4MIJ_cjs.PausedError({ method: "claim", contractAddress: this.address }));
1312
1312
  }
1313
1313
  if (now < startTime) {
1314
1314
  blockers.push(
@@ -1339,7 +1339,7 @@ var ConfidentialAirdropClient = class {
1339
1339
  }
1340
1340
  if (callerBalance < gasFee) {
1341
1341
  blockers.push(
1342
- new chunk67OV5CX2_cjs.InsufficientFeeError({
1342
+ new chunk2RNW4MIJ_cjs.InsufficientFeeError({
1343
1343
  method: "claim",
1344
1344
  contractAddress: this.address,
1345
1345
  feeKind: "gas",
@@ -1362,6 +1362,13 @@ var ConfidentialAirdropClient = class {
1362
1362
  *
1363
1363
  * **Silent-zero transfers.** ERC-7984 transfers do not revert when the sender's encrypted balance is insufficient — the transfer succeeds and moves an encrypted zero instead. This is by design: reverting would leak balance information. The transaction receipt alone cannot tell you whether value actually moved.
1364
1364
  *
1365
+ * **An unfunded pool is the opposite case — it reverts loudly.** Do not
1366
+ * generalize the silent-zero rule above to a clone whose pool was never
1367
+ * funded: that claim throws {@link FheHandleNotAllowedError} (the FHEVM ACL
1368
+ * rejects `FHE.allowTransient` on an uninitialized handle), and
1369
+ * {@link preflightClaim} cannot detect it because the pool balance is an
1370
+ * encrypted `euint64` the SDK cannot read in plaintext.
1371
+ *
1365
1372
  * @returns Transaction hash.
1366
1373
  * @example
1367
1374
  * const fee = await airdrop.gasFee();
@@ -1435,12 +1442,12 @@ var ConfidentialAirdropClient = class {
1435
1442
  const aclLogs = receipt.logs.filter(
1436
1443
  (log) => log.address.toLowerCase() === this.aclAddress.toLowerCase()
1437
1444
  );
1438
- const events = viem.parseEventLogs({ abi: [chunkFAXIIH5R_cjs.ACL_ALLOWED_EVENT], logs: aclLogs });
1445
+ const events = viem.parseEventLogs({ abi: [chunkSYHNZSZZ_cjs.ACL_ALLOWED_EVENT], logs: aclLogs });
1439
1446
  const granted = events.filter(
1440
1447
  (ev) => ev.args.account.toLowerCase() === callerAddress && ev.args.caller.toLowerCase() === this.address.toLowerCase()
1441
1448
  );
1442
1449
  if (granted.length === 0) {
1443
- throw new chunk67OV5CX2_cjs.ReceiptEventNotFoundError({
1450
+ throw new chunk2RNW4MIJ_cjs.ReceiptEventNotFoundError({
1444
1451
  method: "getClaimAmount",
1445
1452
  eventName: "Allowed",
1446
1453
  contractAddress: this.aclAddress,
@@ -1449,7 +1456,7 @@ var ConfidentialAirdropClient = class {
1449
1456
  });
1450
1457
  }
1451
1458
  if (granted.length > 1) {
1452
- throw new chunk67OV5CX2_cjs.ReceiptEventAmbiguousError({
1459
+ throw new chunk2RNW4MIJ_cjs.ReceiptEventAmbiguousError({
1453
1460
  method: "getClaimAmount",
1454
1461
  eventName: "Allowed",
1455
1462
  contractAddress: this.aclAddress,
@@ -1537,7 +1544,7 @@ var ConfidentialAirdropClient = class {
1537
1544
  // ============================================================
1538
1545
  #requireChecksumAddress(method, argument, value) {
1539
1546
  if (!viem.isAddress(value, { strict: true })) {
1540
- throw new chunk67OV5CX2_cjs.InvalidArgumentError({
1547
+ throw new chunk2RNW4MIJ_cjs.InvalidArgumentError({
1541
1548
  method,
1542
1549
  argument,
1543
1550
  reason: "must be a valid EIP-55 checksummed address",
@@ -1547,14 +1554,14 @@ var ConfidentialAirdropClient = class {
1547
1554
  }
1548
1555
  #requireWallet(method) {
1549
1556
  if (!this.walletClient) {
1550
- throw new chunk67OV5CX2_cjs.MissingWalletClientError(method);
1557
+ throw new chunk2RNW4MIJ_cjs.MissingWalletClientError(method);
1551
1558
  }
1552
1559
  return this.walletClient;
1553
1560
  }
1554
1561
  #resolveAccount(wallet, override, method) {
1555
1562
  const acct = override ?? wallet.account;
1556
1563
  if (!acct) {
1557
- throw new chunk67OV5CX2_cjs.MissingAccountError(method);
1564
+ throw new chunk2RNW4MIJ_cjs.MissingAccountError(method);
1558
1565
  }
1559
1566
  if (typeof acct === "string") {
1560
1567
  this.#requireChecksumAddress(method, "account", acct);
@@ -1562,7 +1569,7 @@ var ConfidentialAirdropClient = class {
1562
1569
  return acct;
1563
1570
  }
1564
1571
  #mapRevert(method, err, account) {
1565
- return chunkKLKI352M_cjs.mapContractRevert(err, {
1572
+ return chunk43RFBQ73_cjs.mapContractRevert(err, {
1566
1573
  method,
1567
1574
  contractAddress: this.address,
1568
1575
  abi: confidentialAirdropCloneableAbi,
@@ -1607,7 +1614,7 @@ var ConfidentialAirdropClient = class {
1607
1614
  ...value !== void 0 ? { value } : {}
1608
1615
  });
1609
1616
  } catch (err) {
1610
- if (chunkKLKI352M_cjs.isContractRevert(err)) {
1617
+ if (chunk43RFBQ73_cjs.isContractRevert(err)) {
1611
1618
  throw this.#mapRevert(method, err, accountAddress(account));
1612
1619
  }
1613
1620
  }
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunk67OV5CX2_cjs = require('./chunk-67OV5CX2.cjs');
3
+ var chunk2RNW4MIJ_cjs = require('./chunk-2RNW4MIJ.cjs');
4
4
  var viem = require('viem');
5
5
 
6
6
  var FHEVM_ACL_ADDRESS_BY_CHAIN = {
@@ -16,7 +16,7 @@ function getFhevmAclAddress(chainId) {
16
16
  }
17
17
  function requireFhevmAclAddress(chainId, clientLabel) {
18
18
  if (chainId === void 0) {
19
- throw new chunk67OV5CX2_cjs.DeploymentAddressUnavailableError({
19
+ throw new chunk2RNW4MIJ_cjs.DeploymentAddressUnavailableError({
20
20
  reason: "chain-id-missing",
21
21
  product: "fhevm",
22
22
  contract: "acl",
@@ -26,7 +26,7 @@ function requireFhevmAclAddress(chainId, clientLabel) {
26
26
  }
27
27
  const addr = FHEVM_ACL_ADDRESS_BY_CHAIN[chainId];
28
28
  if (addr) return addr;
29
- throw new chunk67OV5CX2_cjs.DeploymentAddressUnavailableError({
29
+ throw new chunk2RNW4MIJ_cjs.DeploymentAddressUnavailableError({
30
30
  reason: "registry-unknown-chain",
31
31
  product: "fhevm",
32
32
  contract: "acl",
@@ -1,13 +1,12 @@
1
- import { mapZamaError } from './chunk-WMACINXO.js';
2
- import { scaleRatio } from './chunk-AOP6HMPW.js';
3
- import { getFhevmAclAddress, requireFhevmAclAddress, ACL_ALLOWED_EVENT } from './chunk-ZWXJTBZO.js';
1
+ import { mapZamaError } from './chunk-NFW7AUEX.js';
2
+ import { resolveEncryptor, encryptUint64Batch, scaleRatio, encryptUint64 } from './chunk-PD7ME2BT.js';
3
+ import { getFhevmAclAddress, requireFhevmAclAddress, ACL_ALLOWED_EVENT } from './chunk-YPYCWLYP.js';
4
4
  import { erc7984OperatorAbi } from './chunk-7VELUOMI.js';
5
- import { SDK_VERSION, mapContractRevert, isContractRevert } from './chunk-SG65XWH7.js';
6
- import { normaliseAddress } from './chunk-ZA673I3O.js';
5
+ import { SDK_VERSION, mapContractRevert, isContractRevert } from './chunk-6WSNS3UV.js';
6
+ import { normaliseAddress } from './chunk-46T67CE2.js';
7
+ import { TokenOpsSdkError, PausedError, InsufficientFeeError, AccessDeniedError, InvalidArgumentError, OperatorNotApprovedError, MissingEncryptorError, ReceiptEventNotFoundError, ReceiptEventAmbiguousError, MissingWalletClientError, MissingAccountError, asEncryptedHandle, asTxHash } from './chunk-DRSPMIZ7.js';
7
8
  import { withTelemetry } from './chunk-Q2GP5UDC.js';
8
- import { asExternalInputProof, asEncryptedHandle, asTxHash } from './chunk-KWFFIJYX.js';
9
- import { InvalidArgumentError, TokenOpsSdkError, PausedError, InsufficientFeeError, AccessDeniedError, OperatorNotApprovedError, MissingEncryptorError, ReceiptEventNotFoundError, ReceiptEventAmbiguousError, MissingWalletClientError, MissingAccountError } from './chunk-QBJ7O2B4.js';
10
- import { bytesToHex, parseEventLogs, isAddress } from 'viem';
9
+ import { parseEventLogs, isAddress, BaseError, ContractFunctionZeroDataError } from 'viem';
11
10
 
12
11
  // src/fhe-vesting/abis/manager.ts
13
12
  var confidentialVestingManagerAbi = [
@@ -987,78 +986,6 @@ var confidentialVestingManagerAbi = [
987
986
  type: "function"
988
987
  }
989
988
  ];
990
- function resolveEncryptor(source) {
991
- if (source === void 0) return void 0;
992
- return typeof source === "function" ? source() : source;
993
- }
994
- var MAX_UINT64 = (1n << 64n) - 1n;
995
- function assertUint64(value, label) {
996
- if (value < 0n || value > MAX_UINT64) {
997
- throw new InvalidArgumentError({
998
- method: "encryptUint64",
999
- argument: label,
1000
- reason: `does not fit in uint64 (0..2^64-1)`,
1001
- value
1002
- });
1003
- }
1004
- }
1005
- async function encryptUint64({
1006
- encryptor,
1007
- contractAddress,
1008
- userAddress,
1009
- value
1010
- }) {
1011
- assertUint64(value, "value");
1012
- const { handles, inputProof } = await encryptor.encrypt({
1013
- values: [{ value, type: "euint64" }],
1014
- contractAddress,
1015
- userAddress
1016
- });
1017
- if (handles.length !== 1) {
1018
- throw new InvalidArgumentError({
1019
- method: "encryptUint64",
1020
- argument: "handles",
1021
- reason: `expected 1 handle, got ${handles.length}`,
1022
- value: handles.length
1023
- });
1024
- }
1025
- return {
1026
- handle: asEncryptedHandle(bytesToHex(handles[0])),
1027
- inputProof: asExternalInputProof(bytesToHex(inputProof))
1028
- };
1029
- }
1030
- async function encryptUint64Batch({
1031
- encryptor,
1032
- contractAddress,
1033
- userAddress,
1034
- values
1035
- }) {
1036
- if (values.length === 0) {
1037
- throw new InvalidArgumentError({
1038
- method: "encryptUint64Batch",
1039
- argument: "values",
1040
- reason: "must be non-empty"
1041
- });
1042
- }
1043
- values.forEach((v, i) => assertUint64(v, `values[${i}]`));
1044
- const { handles, inputProof } = await encryptor.encrypt({
1045
- values: values.map((value) => ({ value, type: "euint64" })),
1046
- contractAddress,
1047
- userAddress
1048
- });
1049
- if (handles.length !== values.length) {
1050
- throw new InvalidArgumentError({
1051
- method: "encryptUint64Batch",
1052
- argument: "handles",
1053
- reason: `expected ${values.length} handles, got ${handles.length}`,
1054
- value: handles.length
1055
- });
1056
- }
1057
- return {
1058
- handles: handles.map((h) => asEncryptedHandle(bytesToHex(h))),
1059
- inputProof: asExternalInputProof(bytesToHex(inputProof))
1060
- };
1061
- }
1062
989
 
1063
990
  // src/fhe-vesting/errors.ts
1064
991
  var VestingNotFoundError = class extends TokenOpsSdkError {
@@ -1554,6 +1481,11 @@ var ConfidentialVestingManagerClient = class {
1554
1481
  * - Operator: creator has approved this manager as an ERC-7984 operator on
1555
1482
  * the distribution token, required for the manager's
1556
1483
  * `confidentialTransferFrom` pull ({@link OperatorNotApprovedError} blocker).
1484
+ * If the bound `token` does not implement the ERC-7984 `isOperator`
1485
+ * view — a revert, or a zero-data response for an EOA / undeployed
1486
+ * address — operator status is undetermined rather than the call
1487
+ * throwing: `isOperatorSet` reports `false` and the read failure becomes
1488
+ * an {@link InvalidArgumentError} blocker on `token` instead (TOK-436).
1557
1489
  *
1558
1490
  * **Not preflight-detectable — read before trusting `ready: true`:**
1559
1491
  * - The creator's confidential token balance is an encrypted `euint64` the
@@ -1585,15 +1517,19 @@ var ConfidentialVestingManagerClient = class {
1585
1517
  this.token(),
1586
1518
  this.#read("VESTING_CREATOR_ROLE")
1587
1519
  ]);
1588
- const [hasCreatorRole, isOperatorSet] = await Promise.all([
1520
+ const [hasCreatorRole, operatorRead] = await Promise.all([
1589
1521
  this.hasRole(creatorRole, args.creator),
1590
1522
  this.publicClient.readContract({
1591
1523
  address: token,
1592
1524
  abi: erc7984OperatorAbi,
1593
1525
  functionName: "isOperator",
1594
1526
  args: [args.creator, this.address]
1527
+ }).then((v) => ({ ok: true, value: v })).catch((err) => {
1528
+ if (isNotErc7984Failure(err)) return { ok: false, err };
1529
+ throw err;
1595
1530
  })
1596
1531
  ]);
1532
+ const isOperatorSet = operatorRead.ok ? operatorRead.value : false;
1597
1533
  if (!hasCreatorRole) {
1598
1534
  pushBlocker(
1599
1535
  new AccessDeniedError({
@@ -1604,7 +1540,16 @@ var ConfidentialVestingManagerClient = class {
1604
1540
  })
1605
1541
  );
1606
1542
  }
1607
- if (!isOperatorSet) {
1543
+ if (!operatorRead.ok) {
1544
+ pushBlocker(
1545
+ new InvalidArgumentError({
1546
+ method: "createVesting",
1547
+ argument: "token",
1548
+ reason: "does not implement the ERC-7984 `isOperator(address,address)` view \u2014 it is not a confidential token (or the address holds no contract on this chain)",
1549
+ value: token
1550
+ })
1551
+ );
1552
+ } else if (!isOperatorSet) {
1608
1553
  pushBlocker(
1609
1554
  new OperatorNotApprovedError({
1610
1555
  method: "createVesting",
@@ -1697,6 +1642,13 @@ var ConfidentialVestingManagerClient = class {
1697
1642
  * for the CTTT test token (6 decimals) `1_000_000n` = 1 CTTT, while the
1698
1643
  * transparent TTT test token uses 18 decimals.
1699
1644
  *
1645
+ * Prerequisites: caller must have set this manager as an operator on the
1646
+ * token: `token.setOperator(managerAddress, deadline)` — or use
1647
+ * `ensureOperator()` from `@tokenops/sdk/fhe`. Skipping it fails with
1648
+ * {@link OperatorNotApprovedError} (the SDK's mapping of the on-chain
1649
+ * `ERC7984UnauthorizedSpender` revert, whose message is the canonical
1650
+ * `OPERATOR_NOT_APPROVED_REMEDIATION` copy).
1651
+ *
1700
1652
  * @returns Transaction hash. Parse the `VestingCreated` event to extract the `vestingId`.
1701
1653
  * @example
1702
1654
  * const hash = await manager.createVesting({
@@ -1746,6 +1698,13 @@ var ConfidentialVestingManagerClient = class {
1746
1698
  * for the CTTT test token (6 decimals) `1_000_000n` = 1 CTTT, while the
1747
1699
  * transparent TTT test token uses 18 decimals.
1748
1700
  *
1701
+ * Prerequisites: caller must have set this manager as an operator on the
1702
+ * token: `token.setOperator(managerAddress, deadline)` — or use
1703
+ * `ensureOperator()` from `@tokenops/sdk/fhe`. Skipping it fails with
1704
+ * {@link OperatorNotApprovedError} (the SDK's mapping of the on-chain
1705
+ * `ERC7984UnauthorizedSpender` revert, whose message is the canonical
1706
+ * `OPERATOR_NOT_APPROVED_REMEDIATION` copy).
1707
+ *
1749
1708
  * @returns Transaction hash.
1750
1709
  */
1751
1710
  async batchCreateVesting(args) {
@@ -2858,6 +2817,11 @@ var ConfidentialVestingManagerClient = class {
2858
2817
  function createConfidentialVestingManagerClient(config) {
2859
2818
  return new ConfidentialVestingManagerClient(config);
2860
2819
  }
2820
+ function isNotErc7984Failure(err) {
2821
+ if (isContractRevert(err)) return true;
2822
+ if (!(err instanceof BaseError)) return false;
2823
+ return err.walk((e) => e instanceof ContractFunctionZeroDataError) instanceof ContractFunctionZeroDataError;
2824
+ }
2861
2825
  function accountAddress(account) {
2862
2826
  return typeof account === "string" ? account : account.address;
2863
2827
  }
@@ -2915,4 +2879,4 @@ function collectVestingParamsErrors(params, where) {
2915
2879
  return errors;
2916
2880
  }
2917
2881
 
2918
- export { ClaimLockedError, ConfidentialVestingManagerClient, NoPendingTransferError, NotPendingRecipientError, NotVestingRecipientError, TransferAlreadyPendingError, TransferExpiredError, VestingExpiredError, VestingNotFoundError, VestingNotRevocableError, VestingRevokedError, confidentialVestingManagerAbi, createConfidentialVestingManagerClient, encryptUint64, encryptUint64Batch, resolveEncryptor };
2882
+ export { ClaimLockedError, ConfidentialVestingManagerClient, NoPendingTransferError, NotPendingRecipientError, NotVestingRecipientError, TransferAlreadyPendingError, TransferExpiredError, VestingExpiredError, VestingNotFoundError, VestingNotRevocableError, VestingRevokedError, confidentialVestingManagerAbi, createConfidentialVestingManagerClient };
@@ -0,0 +1,56 @@
1
+ import { useWagmiAccount } from './chunk-FT4LNBOS.js';
2
+ import { isOperator, ensureOperator } from './chunk-4KJ66YRH.js';
3
+ import { MissingPublicClientError, MissingWalletClientError } from './chunk-DRSPMIZ7.js';
4
+ import { useQuery, useMutation } from '@tanstack/react-query';
5
+ import { usePublicClient, useWalletClient } from 'wagmi';
6
+
7
+ function useIsOperator(options = {}) {
8
+ const publicClient = usePublicClient({ chainId: options.chainId });
9
+ const { address: connected } = useWagmiAccount();
10
+ const chainId = options.chainId ?? publicClient?.chain?.id;
11
+ const holder = options.holder ?? connected;
12
+ const { token, spender, telemetry } = options;
13
+ return useQuery({
14
+ queryKey: [
15
+ "tokenops-sdk",
16
+ "fhe",
17
+ "isOperator",
18
+ chainId ?? null,
19
+ token ? token.toLowerCase() : null,
20
+ holder ? holder.toLowerCase() : null,
21
+ spender ? spender.toLowerCase() : null
22
+ ],
23
+ queryFn: () => isOperator({
24
+ publicClient,
25
+ token,
26
+ holder,
27
+ spender,
28
+ ...telemetry ? { telemetry } : {}
29
+ }),
30
+ enabled: !!publicClient && !!token && !!holder && !!spender && options.enabled !== false,
31
+ staleTime: 0
32
+ });
33
+ }
34
+ function useEnsureOperator(options = {}) {
35
+ const publicClient = usePublicClient({ chainId: options.chainId });
36
+ const { data: walletClient } = useWalletClient({ chainId: options.chainId });
37
+ const telemetry = options.telemetry;
38
+ return useMutation({
39
+ mutationFn: async (vars) => {
40
+ if (!publicClient) throw new MissingPublicClientError("useEnsureOperator");
41
+ if (!walletClient) throw new MissingWalletClientError("useEnsureOperator");
42
+ return ensureOperator({
43
+ publicClient,
44
+ walletClient,
45
+ token: vars.token,
46
+ spender: vars.spender,
47
+ deadline: vars.deadline,
48
+ ...vars.account !== void 0 ? { account: vars.account } : {},
49
+ ...vars.waitForReceipt !== void 0 ? { waitForReceipt: vars.waitForReceipt } : {},
50
+ ...telemetry ? { telemetry } : {}
51
+ });
52
+ }
53
+ });
54
+ }
55
+
56
+ export { useEnsureOperator, useIsOperator };
@@ -1,11 +1,10 @@
1
1
  import { erc7984OperatorAbi } from './chunk-7VELUOMI.js';
2
- import { SDK_VERSION, mapContractRevert, isContractRevert } from './chunk-SG65XWH7.js';
3
- import { getFheAirdropFactoryAddress } from './chunk-XGGTQQFH.js';
4
- import { normaliseAddress } from './chunk-ZA673I3O.js';
2
+ import { SDK_VERSION, mapContractRevert, isContractRevert } from './chunk-6WSNS3UV.js';
3
+ import { getFheAirdropFactoryAddress } from './chunk-QKKBBH7I.js';
4
+ import { normaliseAddress } from './chunk-46T67CE2.js';
5
+ import { InvalidArgumentError, asExternalInputProof, asEncryptedHandle, TokenOpsSdkError, MissingAccountError, asSignature, DeploymentAddressUnavailableError, OperatorNotApprovedError, AlreadyInitializedError, asTxHash, MissingWalletClientError, MissingEncryptorError } from './chunk-DRSPMIZ7.js';
5
6
  import { withTelemetry } from './chunk-Q2GP5UDC.js';
6
- import { asExternalInputProof, asEncryptedHandle, asSignature, asTxHash } from './chunk-KWFFIJYX.js';
7
- import { InvalidArgumentError, TokenOpsSdkError, MissingAccountError, DeploymentAddressUnavailableError, OperatorNotApprovedError, AlreadyInitializedError, MissingWalletClientError, MissingEncryptorError } from './chunk-QBJ7O2B4.js';
8
- import { bytesToHex, isAddress, parseEventLogs } from 'viem';
7
+ import { bytesToHex, isAddress, parseEventLogs, BaseError, ContractFunctionZeroDataError } from 'viem';
9
8
 
10
9
  // src/fhe-airdrop/abis/factory.ts
11
10
  var confidentialAirdropFactoryAbi = [
@@ -1434,7 +1433,7 @@ var ConfidentialAirdropFactoryClient = class {
1434
1433
  })
1435
1434
  );
1436
1435
  }
1437
- const [block, customFee, defaultFee, isFactoryOperator] = await Promise.all([
1436
+ const [block, customFee, defaultFee, operatorRead] = await Promise.all([
1438
1437
  this.publicClient.getBlock(),
1439
1438
  this.getCustomFee(creator),
1440
1439
  this.defaultGasFee(),
@@ -1443,8 +1442,22 @@ var ConfidentialAirdropFactoryClient = class {
1443
1442
  abi: erc7984OperatorAbi,
1444
1443
  functionName: "isOperator",
1445
1444
  args: [creator, this.address]
1446
- }) : Promise.resolve(false)
1445
+ }).then((v) => ({ ok: true, value: v })).catch((err) => {
1446
+ if (isNotErc7984Failure(err)) return { ok: false, err };
1447
+ throw err;
1448
+ }) : Promise.resolve({ ok: true, value: false })
1447
1449
  ]);
1450
+ const isFactoryOperator = operatorRead.ok ? operatorRead.value : false;
1451
+ if (!operatorRead.ok) {
1452
+ pushBlocker(
1453
+ new InvalidArgumentError({
1454
+ method: "createConfidentialAirdrop",
1455
+ argument: "params.token",
1456
+ reason: "does not implement the ERC-7984 `isOperator(address,address)` view \u2014 it is not a confidential token (or the address holds no contract on this chain)",
1457
+ value: params.token
1458
+ })
1459
+ );
1460
+ }
1448
1461
  const gasFee = customFee.enabled ? customFee.gasFee : defaultFee;
1449
1462
  if (params.endTimestamp <= Number(block.timestamp)) {
1450
1463
  pushBlocker(
@@ -1456,7 +1469,7 @@ var ConfidentialAirdropFactoryClient = class {
1456
1469
  })
1457
1470
  );
1458
1471
  }
1459
- if (funding === true && !isFactoryOperator) {
1472
+ if (funding === true && tokenOk && operatorRead.ok && !isFactoryOperator) {
1460
1473
  pushBlocker(
1461
1474
  new OperatorNotApprovedError({
1462
1475
  method: "createAndFundConfidentialAirdrop",
@@ -1638,6 +1651,11 @@ var ConfidentialAirdropFactoryClient = class {
1638
1651
  function createConfidentialAirdropFactoryClient(config) {
1639
1652
  return new ConfidentialAirdropFactoryClient(config);
1640
1653
  }
1654
+ function isNotErc7984Failure(err) {
1655
+ if (isContractRevert(err)) return true;
1656
+ if (!(err instanceof BaseError)) return false;
1657
+ return err.walk((e) => e instanceof ContractFunctionZeroDataError) instanceof ContractFunctionZeroDataError;
1658
+ }
1641
1659
  var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
1642
1660
  function accountAddress(account) {
1643
1661
  return typeof account === "string" ? account : account.address;