@tokenops/sdk 1.6.0 → 2.0.0-alpha.2

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 (263) hide show
  1. package/CHANGELOG.md +77 -8
  2. package/CONTRIBUTING.md +4 -2
  3. package/README.md +146 -90
  4. package/SUPPORT.md +47 -0
  5. package/dist/{chunk-BD4LZBVF.cjs → chunk-3QHNYEQD.cjs} +18 -17
  6. package/dist/{chunk-YFIWCYHC.cjs → chunk-3YHBO2DL.cjs} +56 -54
  7. package/dist/{chunk-QET3Q4JP.js → chunk-44YJPMQC.js} +8 -6
  8. package/dist/{chunk-6WSNS3UV.js → chunk-4RAAATVY.js} +2 -4
  9. package/dist/{chunk-4KJ66YRH.js → chunk-4TSDNZQ3.js} +2 -2
  10. package/dist/chunk-66IHPTOK.cjs +20 -0
  11. package/dist/{chunk-2RNW4MIJ.cjs → chunk-67OV5CX2.cjs} +0 -18
  12. package/dist/{chunk-PD7ME2BT.js → chunk-6GNR22OV.js} +2 -1
  13. package/dist/{chunk-WOEETTH7.cjs → chunk-7AFPOE7N.cjs} +6 -6
  14. package/dist/{chunk-QKKBBH7I.js → chunk-A4DCEE33.js} +34 -7
  15. package/dist/chunk-AREQJHKA.cjs +713 -0
  16. package/dist/{chunk-U57COLUE.js → chunk-AXIPOR3C.js} +2 -2
  17. package/dist/chunk-EBLBPUPI.cjs +255 -0
  18. package/dist/chunk-EYDA6Q6C.js +245 -0
  19. package/dist/{chunk-SYHNZSZZ.cjs → chunk-FAXIIH5R.cjs} +3 -3
  20. package/dist/{chunk-AYGRYDBX.cjs → chunk-FEDX7B6T.cjs} +37 -35
  21. package/dist/{chunk-CBRL2PJA.cjs → chunk-FHWSBGWE.cjs} +12 -12
  22. package/dist/{chunk-WUXUWTFW.cjs → chunk-FT5H2Q7Y.cjs} +37 -7
  23. package/dist/chunk-GADGBQJO.js +423 -0
  24. package/dist/{chunk-VHSNYUYV.js → chunk-IGO5XSPS.js} +5 -5
  25. package/dist/chunk-IUKKNJ2R.cjs +433 -0
  26. package/dist/{chunk-VR3FREBX.cjs → chunk-JK4XMMKM.cjs} +3 -3
  27. package/dist/{chunk-4ZCXK4VI.cjs → chunk-KFRDLKMA.cjs} +14 -14
  28. package/dist/chunk-KWFFIJYX.js +11 -0
  29. package/dist/{chunk-7G7UOQV4.cjs → chunk-MM5BV5CS.cjs} +4 -4
  30. package/dist/{chunk-43RFBQ73.cjs → chunk-MVDQMV25.cjs} +29 -32
  31. package/dist/chunk-NWFMBLSQ.js +4 -0
  32. package/dist/{chunk-HETNKZEE.js → chunk-PYYSB5ZN.js} +1 -1
  33. package/dist/chunk-PZZK3O3S.cjs +9843 -0
  34. package/dist/{chunk-DRSPMIZ7.js → chunk-QBJ7O2B4.js} +1 -11
  35. package/dist/{chunk-WTK6JDSI.js → chunk-SPLNGUFF.js} +6 -4
  36. package/dist/{chunk-UJS4N2XM.cjs → chunk-TEBM66WA.cjs} +12 -12
  37. package/dist/{chunk-TN65XNTI.js → chunk-TWT3STIX.js} +8 -6
  38. package/dist/chunk-UG5RKLU2.cjs +6 -0
  39. package/dist/{chunk-EUKPOXWR.cjs → chunk-UHHMVBLU.cjs} +17 -15
  40. package/dist/chunk-VW356KR3.js +688 -0
  41. package/dist/{chunk-BK7YIVLK.cjs → chunk-WJLECC22.cjs} +75 -73
  42. package/dist/{chunk-V5D7BHW3.js → chunk-WJMEBBU7.js} +6 -4
  43. package/dist/{chunk-NFW7AUEX.js → chunk-WMACINXO.js} +1 -1
  44. package/dist/chunk-X7WBPCEU.js +9817 -0
  45. package/dist/{chunk-46T67CE2.js → chunk-ZA673I3O.js} +1 -1
  46. package/dist/{chunk-YPYCWLYP.js → chunk-ZWXJTBZO.js} +1 -1
  47. package/dist/core/addresses.d.ts +14 -2
  48. package/dist/core/brands.d.ts +8 -2
  49. package/dist/core/errors.d.ts +71 -10
  50. package/dist/core/preflight.d.ts +1 -0
  51. package/dist/fhe/erc7984-abi.d.ts +1 -0
  52. package/dist/fhe/index.cjs +64 -63
  53. package/dist/fhe/index.js +7 -6
  54. package/dist/fhe/operators.d.ts +22 -5
  55. package/dist/fhe/react/index.cjs +13 -12
  56. package/dist/fhe/react/index.js +6 -5
  57. package/dist/fhe/types.d.ts +8 -2
  58. package/dist/fhe-airdrop/abis/{cloneable.d.ts → airdrop-base.d.ts} +254 -396
  59. package/dist/fhe-airdrop/abis/compliance.d.ts +422 -0
  60. package/dist/fhe-airdrop/abis/ecdsa.d.ts +1316 -0
  61. package/dist/fhe-airdrop/abis/factory.d.ts +1319 -190
  62. package/dist/fhe-airdrop/abis/index.d.ts +5 -2
  63. package/dist/fhe-airdrop/abis/merkle.d.ts +1250 -0
  64. package/dist/fhe-airdrop/advanced/index.cjs +11 -12
  65. package/dist/fhe-airdrop/advanced/index.d.cts +34 -11
  66. package/dist/fhe-airdrop/advanced/index.d.ts +34 -11
  67. package/dist/fhe-airdrop/advanced/index.js +3 -8
  68. package/dist/fhe-airdrop/advanced/react/index.cjs +619 -51
  69. package/dist/fhe-airdrop/advanced/react/index.d.cts +43 -3
  70. package/dist/fhe-airdrop/advanced/react/index.d.ts +43 -3
  71. package/dist/fhe-airdrop/advanced/react/index.js +592 -52
  72. package/dist/fhe-airdrop/advanced/react/useClearCompliancePolicy.d.ts +28 -0
  73. package/dist/fhe-airdrop/advanced/react/useClearUpgradeabilityPolicy.d.ts +26 -0
  74. package/dist/fhe-airdrop/advanced/react/useDisableCustomFee.d.ts +25 -0
  75. package/dist/fhe-airdrop/advanced/react/useEcdsaInitCodeHash.d.ts +30 -0
  76. package/dist/fhe-airdrop/advanced/react/useFactoryComplianceDelegate.d.ts +25 -0
  77. package/dist/fhe-airdrop/advanced/react/useFactoryCompliancePolicy.d.ts +38 -0
  78. package/dist/fhe-airdrop/advanced/react/useFactoryCustomFee.d.ts +24 -0
  79. package/dist/fhe-airdrop/advanced/react/useFactoryGrantRole.d.ts +32 -0
  80. package/dist/fhe-airdrop/advanced/react/useFactoryHasRole.d.ts +27 -0
  81. package/dist/fhe-airdrop/advanced/react/useFactoryImplementations.d.ts +33 -0
  82. package/dist/fhe-airdrop/advanced/react/useFactoryRenounceRole.d.ts +36 -0
  83. package/dist/fhe-airdrop/advanced/react/useFactoryRevokeRole.d.ts +35 -0
  84. package/dist/fhe-airdrop/advanced/react/useFactoryRoleConstants.d.ts +46 -0
  85. package/dist/fhe-airdrop/advanced/react/useFactoryRoleMembers.d.ts +47 -0
  86. package/dist/fhe-airdrop/advanced/react/useFactoryUpgradeabilityPolicy.d.ts +39 -0
  87. package/dist/fhe-airdrop/advanced/react/useMerkleInitCodeHash.d.ts +24 -0
  88. package/dist/fhe-airdrop/advanced/react/usePredictEcdsaAirdropAddress.d.ts +33 -0
  89. package/dist/fhe-airdrop/advanced/react/usePredictMerkleAirdropAddress.d.ts +27 -0
  90. package/dist/fhe-airdrop/advanced/react/useSetComplianceDelegate.d.ts +33 -0
  91. package/dist/fhe-airdrop/advanced/react/useSetComplianceManagerImpl.d.ts +27 -0
  92. package/dist/fhe-airdrop/advanced/react/useSetCompliancePolicy.d.ts +28 -0
  93. package/dist/fhe-airdrop/advanced/react/useSetCustomFee.d.ts +28 -0
  94. package/dist/fhe-airdrop/advanced/react/useSetDefaultDelegateToCompliance.d.ts +31 -0
  95. package/dist/fhe-airdrop/advanced/react/useSetDefaultGasFee.d.ts +28 -0
  96. package/dist/fhe-airdrop/advanced/react/useSetDefaultUpgradeable.d.ts +27 -0
  97. package/dist/fhe-airdrop/advanced/react/useSetEcdsaImplementation.d.ts +34 -0
  98. package/dist/fhe-airdrop/advanced/react/useSetFeeCollector.d.ts +27 -0
  99. package/dist/fhe-airdrop/advanced/react/useSetMerkleImplementation.d.ts +30 -0
  100. package/dist/fhe-airdrop/advanced/react/useSetUpgradeabilityPolicy.d.ts +31 -0
  101. package/dist/fhe-airdrop/airdrop-base.d.ts +608 -0
  102. package/dist/fhe-airdrop/campaign.d.ts +338 -0
  103. package/dist/fhe-airdrop/compliance.d.ts +302 -0
  104. package/dist/fhe-airdrop/constants.d.ts +33 -0
  105. package/dist/fhe-airdrop/ecdsa.d.ts +263 -0
  106. package/dist/fhe-airdrop/encryption.d.ts +92 -14
  107. package/dist/fhe-airdrop/errors.d.ts +273 -15
  108. package/dist/fhe-airdrop/factory.d.ts +533 -274
  109. package/dist/fhe-airdrop/guards.d.ts +317 -0
  110. package/dist/fhe-airdrop/index.cjs +233 -73
  111. package/dist/fhe-airdrop/index.d.cts +46 -8
  112. package/dist/fhe-airdrop/index.d.ts +46 -8
  113. package/dist/fhe-airdrop/index.js +11 -7
  114. package/dist/fhe-airdrop/merkle-tree.d.ts +97 -0
  115. package/dist/fhe-airdrop/merkle.d.ts +201 -0
  116. package/dist/fhe-airdrop/react/_shared.d.ts +156 -70
  117. package/dist/fhe-airdrop/react/index.cjs +1174 -384
  118. package/dist/fhe-airdrop/react/index.d.cts +99 -74
  119. package/dist/fhe-airdrop/react/index.d.ts +99 -74
  120. package/dist/fhe-airdrop/react/index.js +993 -303
  121. package/dist/fhe-airdrop/react/keys.d.ts +90 -0
  122. package/dist/fhe-airdrop/react/useAccessEcdsaClaimAmount.d.ts +26 -0
  123. package/dist/fhe-airdrop/react/useAccessMerkleClaimAmount.d.ts +27 -0
  124. package/dist/fhe-airdrop/react/useAddComplianceDelegate.d.ts +37 -0
  125. package/dist/fhe-airdrop/react/useAdminBatchDiscloseBalanceToParties.d.ts +36 -0
  126. package/dist/fhe-airdrop/react/useAdminDiscloseBalanceToParty.d.ts +31 -0
  127. package/dist/fhe-airdrop/react/useAdminGetCurrentBalance.d.ts +27 -0
  128. package/dist/fhe-airdrop/react/useAirdropConfig.d.ts +49 -0
  129. package/dist/fhe-airdrop/react/useAirdropDeploymentMode.d.ts +28 -0
  130. package/dist/fhe-airdrop/react/useAirdropGasFee.d.ts +10 -5
  131. package/dist/fhe-airdrop/react/useAirdropGrantRole.d.ts +29 -10
  132. package/dist/fhe-airdrop/react/useAirdropHasRole.d.ts +15 -6
  133. package/dist/fhe-airdrop/react/useAirdropPause.d.ts +30 -0
  134. package/dist/fhe-airdrop/react/useAirdropPaused.d.ts +17 -0
  135. package/dist/fhe-airdrop/react/useAirdropRenounceRole.d.ts +36 -0
  136. package/dist/fhe-airdrop/react/useAirdropRevokeRole.d.ts +27 -9
  137. package/dist/fhe-airdrop/react/useAirdropRoleAdmin.d.ts +28 -0
  138. package/dist/fhe-airdrop/react/useAirdropRoleConstants.d.ts +67 -0
  139. package/dist/fhe-airdrop/react/useAirdropRoleMembers.d.ts +49 -0
  140. package/dist/fhe-airdrop/react/useAirdropToken.d.ts +11 -4
  141. package/dist/fhe-airdrop/react/useAirdropUpgradeToAndCall.d.ts +45 -0
  142. package/dist/fhe-airdrop/react/useAirdropWindow.d.ts +37 -0
  143. package/dist/fhe-airdrop/react/useBatchDiscloseHandlesToParty.d.ts +32 -0
  144. package/dist/fhe-airdrop/react/useBuildMerkleCampaign.d.ts +68 -0
  145. package/dist/fhe-airdrop/react/useClaimedAmount.d.ts +29 -0
  146. package/dist/fhe-airdrop/react/useComplianceGrantRole.d.ts +32 -0
  147. package/dist/fhe-airdrop/react/useComplianceHasRole.d.ts +37 -0
  148. package/dist/fhe-airdrop/react/useComplianceInfo.d.ts +50 -0
  149. package/dist/fhe-airdrop/react/useComplianceManager.d.ts +16 -0
  150. package/dist/fhe-airdrop/react/useComplianceManagerOf.d.ts +32 -0
  151. package/dist/fhe-airdrop/react/useComplianceRenounceRole.d.ts +38 -0
  152. package/dist/fhe-airdrop/react/useComplianceRevokeRole.d.ts +36 -0
  153. package/dist/fhe-airdrop/react/useComplianceRoleConstants.d.ts +41 -0
  154. package/dist/fhe-airdrop/react/useComplianceRoleMembers.d.ts +45 -0
  155. package/dist/fhe-airdrop/react/useCreateAndFundEcdsaAirdrop.d.ts +55 -0
  156. package/dist/fhe-airdrop/react/useCreateAndFundMerkleAirdrop.d.ts +52 -0
  157. package/dist/fhe-airdrop/react/useCreateEcdsaAirdrop.d.ts +28 -0
  158. package/dist/fhe-airdrop/react/useCreateMerkleAirdrop.d.ts +25 -0
  159. package/dist/fhe-airdrop/react/useDiscloseHandleToParty.d.ts +35 -0
  160. package/dist/fhe-airdrop/react/useEcdsaClaim.d.ts +24 -0
  161. package/dist/fhe-airdrop/react/useEcdsaClaimAndUnwrap.d.ts +27 -0
  162. package/dist/fhe-airdrop/react/useEcdsaDomain.d.ts +41 -0
  163. package/dist/fhe-airdrop/react/useEffectiveDelegateToCompliance.d.ts +26 -0
  164. package/dist/fhe-airdrop/react/useEffectiveUpgradeable.d.ts +20 -0
  165. package/dist/fhe-airdrop/react/useEncryptCampaignAmounts.d.ts +59 -0
  166. package/dist/fhe-airdrop/react/useExtendClaimWindow.d.ts +17 -12
  167. package/dist/fhe-airdrop/react/useFactoryFees.d.ts +28 -0
  168. package/dist/fhe-airdrop/react/useFactoryRegistry.d.ts +35 -0
  169. package/dist/fhe-airdrop/react/useFundAirdrop.d.ts +35 -0
  170. package/dist/fhe-airdrop/react/useGrantInstanceRoles.d.ts +35 -0
  171. package/dist/fhe-airdrop/react/useIsActiveDelegate.d.ts +29 -0
  172. package/dist/fhe-airdrop/react/useIsMerkleRootMutable.d.ts +21 -0
  173. package/dist/fhe-airdrop/react/useIsSignatureValid.d.ts +46 -0
  174. package/dist/fhe-airdrop/react/useMerkleClaim.d.ts +22 -0
  175. package/dist/fhe-airdrop/react/useMerkleClaimAndUnwrap.d.ts +29 -0
  176. package/dist/fhe-airdrop/react/useMerkleRoot.d.ts +15 -0
  177. package/dist/fhe-airdrop/react/usePlanMerkleCampaign.d.ts +53 -0
  178. package/dist/fhe-airdrop/react/usePreflightClaim.d.ts +46 -0
  179. package/dist/fhe-airdrop/react/usePreflightCreateAirdrop.d.ts +51 -35
  180. package/dist/fhe-airdrop/react/useRescueERC20.d.ts +30 -0
  181. package/dist/fhe-airdrop/react/useRescueOtherConfidentialToken.d.ts +34 -0
  182. package/dist/fhe-airdrop/react/useRevokeComplianceDelegate.d.ts +37 -0
  183. package/dist/fhe-airdrop/react/useRotateMerkleRoot.d.ts +52 -0
  184. package/dist/fhe-airdrop/react/useSetMerkleRoot.d.ts +22 -0
  185. package/dist/fhe-airdrop/react/useSignClaimAuthorization.d.ts +32 -21
  186. package/dist/fhe-airdrop/react/useWithdrawConfidential.d.ts +23 -0
  187. package/dist/fhe-airdrop/react/useWithdrawGasFee.d.ts +37 -0
  188. package/dist/fhe-airdrop/roles.d.ts +147 -0
  189. package/dist/fhe-airdrop/types.d.ts +78 -63
  190. package/dist/fhe-disperse/index.cjs +70 -68
  191. package/dist/fhe-disperse/index.js +10 -8
  192. package/dist/fhe-disperse/react/index.cjs +94 -92
  193. package/dist/fhe-disperse/react/index.js +13 -11
  194. package/dist/fhe-vesting/advanced/index.cjs +10 -8
  195. package/dist/fhe-vesting/advanced/index.js +8 -6
  196. package/dist/fhe-vesting/advanced/react/index.cjs +16 -14
  197. package/dist/fhe-vesting/advanced/react/index.js +13 -11
  198. package/dist/fhe-vesting/index.cjs +74 -72
  199. package/dist/fhe-vesting/index.js +11 -9
  200. package/dist/fhe-vesting/react/index.cjs +228 -226
  201. package/dist/fhe-vesting/react/index.js +15 -13
  202. package/dist/index.cjs +100 -87
  203. package/dist/index.js +3 -2
  204. package/dist/testnet-faucet/index.cjs +57 -55
  205. package/dist/testnet-faucet/index.js +7 -5
  206. package/dist/testnet-faucet/react/index.cjs +55 -53
  207. package/dist/testnet-faucet/react/index.js +9 -7
  208. package/package.json +6 -2
  209. package/dist/chunk-CNP4L3GF.js +0 -105
  210. package/dist/chunk-KSDSXJ34.js +0 -41
  211. package/dist/chunk-LBWRFZR3.cjs +0 -1681
  212. package/dist/chunk-OL6SHN3D.cjs +0 -44
  213. package/dist/chunk-S2XD75JM.js +0 -1637
  214. package/dist/chunk-SPGSO5SO.cjs +0 -1644
  215. package/dist/chunk-UE5XK2SY.js +0 -1673
  216. package/dist/chunk-WO72UBQD.cjs +0 -109
  217. package/dist/fhe-airdrop/advanced/factory-advanced.d.ts +0 -53
  218. package/dist/fhe-airdrop/advanced/react/usePredictAirdropAddress.d.ts +0 -49
  219. package/dist/fhe-airdrop/airdrop.d.ts +0 -317
  220. package/dist/fhe-airdrop/react/useAccessClaimAmount.d.ts +0 -37
  221. package/dist/fhe-airdrop/react/useAirdropCanExtendClaimWindow.d.ts +0 -7
  222. package/dist/fhe-airdrop/react/useAirdropClaimTypehash.d.ts +0 -10
  223. package/dist/fhe-airdrop/react/useAirdropClaimedSignatures.d.ts +0 -16
  224. package/dist/fhe-airdrop/react/useAirdropDeploymentBlockNumber.d.ts +0 -6
  225. package/dist/fhe-airdrop/react/useAirdropDomainSeparator.d.ts +0 -8
  226. package/dist/fhe-airdrop/react/useAirdropEndTime.d.ts +0 -10
  227. package/dist/fhe-airdrop/react/useAirdropFactoryCustomFee.d.ts +0 -17
  228. package/dist/fhe-airdrop/react/useAirdropFactoryDefaultGasFee.d.ts +0 -10
  229. package/dist/fhe-airdrop/react/useAirdropFactoryDisableCustomFee.d.ts +0 -15
  230. package/dist/fhe-airdrop/react/useAirdropFactoryFeeCollector.d.ts +0 -11
  231. package/dist/fhe-airdrop/react/useAirdropFactoryInitCodeHash.d.ts +0 -17
  232. package/dist/fhe-airdrop/react/useAirdropFactorySetCustomFee.d.ts +0 -17
  233. package/dist/fhe-airdrop/react/useAirdropFactorySetDefaultGasFee.d.ts +0 -16
  234. package/dist/fhe-airdrop/react/useAirdropFactorySetFeeCollector.d.ts +0 -15
  235. package/dist/fhe-airdrop/react/useAirdropHasClaimEnded.d.ts +0 -7
  236. package/dist/fhe-airdrop/react/useAirdropHasClaimStarted.d.ts +0 -7
  237. package/dist/fhe-airdrop/react/useAirdropIsClaimWindowActive.d.ts +0 -9
  238. package/dist/fhe-airdrop/react/useAirdropIsPaused.d.ts +0 -8
  239. package/dist/fhe-airdrop/react/useAirdropIsSignatureClaimed.d.ts +0 -22
  240. package/dist/fhe-airdrop/react/useAirdropIsSignatureValid.d.ts +0 -51
  241. package/dist/fhe-airdrop/react/useAirdropStartTime.d.ts +0 -10
  242. package/dist/fhe-airdrop/react/useAirdropWithdrawGasFee.d.ts +0 -15
  243. package/dist/fhe-airdrop/react/useAirdropWithdrawOtherConfidentialToken.d.ts +0 -14
  244. package/dist/fhe-airdrop/react/useAirdropWithdrawOtherToken.d.ts +0 -14
  245. package/dist/fhe-airdrop/react/useClaim.d.ts +0 -39
  246. package/dist/fhe-airdrop/react/useConfidentialAirdropFactoryImplementation.d.ts +0 -11
  247. package/dist/fhe-airdrop/react/useCreateAndFundConfidentialAirdrop.d.ts +0 -41
  248. package/dist/fhe-airdrop/react/useCreateAndFundConfidentialAirdropAndGetAddress.d.ts +0 -48
  249. package/dist/fhe-airdrop/react/useCreateConfidentialAirdrop.d.ts +0 -29
  250. package/dist/fhe-airdrop/react/useCreateConfidentialAirdropAndGetAddress.d.ts +0 -31
  251. package/dist/fhe-airdrop/react/useDisableCustomFee.d.ts +0 -14
  252. package/dist/fhe-airdrop/react/useFactoryCustomFee.d.ts +0 -17
  253. package/dist/fhe-airdrop/react/useFactoryDefaultGasFee.d.ts +0 -10
  254. package/dist/fhe-airdrop/react/useFactoryFeeCollector.d.ts +0 -11
  255. package/dist/fhe-airdrop/react/useFactoryInitCodeHash.d.ts +0 -17
  256. package/dist/fhe-airdrop/react/useFundConfidentialAirdrop.d.ts +0 -33
  257. package/dist/fhe-airdrop/react/useSetCustomFee.d.ts +0 -16
  258. package/dist/fhe-airdrop/react/useSetDefaultGasFee.d.ts +0 -15
  259. package/dist/fhe-airdrop/react/useSetFeeCollector.d.ts +0 -14
  260. package/dist/fhe-airdrop/react/useSetPaused.d.ts +0 -14
  261. package/dist/fhe-airdrop/react/useWithdraw.d.ts +0 -12
  262. package/dist/fhe-airdrop/react/useWithdrawOtherConfidentialToken.d.ts +0 -13
  263. package/dist/fhe-airdrop/react/useWithdrawOtherToken.d.ts +0 -13
package/CHANGELOG.md CHANGED
@@ -5,22 +5,91 @@ All notable changes to `@tokenops/sdk` will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [1.6.0](https://github.com/VestingLabs/tokenops-sdk/compare/v1.5.1...v1.6.0) (2026-07-28)
8
+ ## [2.0.0-alpha.2] - 2026-09-10
9
9
 
10
+ > **Pre-release built against unaudited contracts.** Continues the `2.0.0-alpha` line. `/fhe-airdrop` in this build targets `tokenops-fhe-airdrop-v2`, frozen at commit `7175ac82f467f0f88c05aba1a4536892999b4251`, which has not completed a final security audit. Every Sepolia `fheAirdrop` address moved in this build, and breaking changes may land between any two alpha builds without a major bump (SemVer prerelease semantics). Published on the `alpha` dist-tag; `latest` stays on `1.6.0`. **For internal testing, not production value.**
11
+ >
12
+ > Migration guide: [`docs/migration/airdrop-v1-to-v2.md`](docs/migration/airdrop-v1-to-v2.md). Support policy: [`SUPPORT.md`](SUPPORT.md).
10
13
 
11
- ### Features
14
+ ### Changed — BREAKING
15
+
16
+ - **`MerkleAirdropClient.claim` and `.getClaimAmount` submit an explicit claim identity.** The contracts gained a leading `address account`, which decoupled the leaf/accounting identity from the address the FHE input proof binds to. A relayer can now settle a leaf on a recipient's behalf.
17
+ - **`CampaignEntry` is `{ account, boundTo, handle, inputProof, merkleProof }`.** `recipient` is removed with **no alias**, as are `MerkleLeafInput.recipient` and `LeafOfArgs.recipient`. The field meant "leaf identity and submitter" at once and those are now different addresses, so an alias would have kept compiling while meaning something else. Entries serialised under `2.0.0-alpha.1` must be re-keyed; their handles remain valid, since leaf hashing did not change.
18
+ - **Every Sepolia `fheAirdrop` address moved.** `claim`'s breaking signature forced a fresh Merkle implementation and the deploy script redeploys the whole system, factory included. Instances created through the previous factory are unreachable from this release, and a campaign planned against it now fails `PredictionDriftError`.
19
+ - `claimAndUnwrap` is deliberately **unchanged** and remains submitted for the caller: publishing an allocation as a plain ERC-20 transfer is the recipient's own choice, so a relayed unwrap is unrepresentable rather than rejected. A `submitter`-bound campaign therefore has no unwrap path.
20
+ - `SenderNotAllowedToUseHandle` is gone from the Merkle ABI — that path no longer calls `FHE.fromExternal`.
21
+
22
+ ### Added
23
+
24
+ - **Batched relayed rosters are chunked at 32 recipients**, the 2048-bit input-ciphertext limit for `euint64`. `@zama-fhe/sdk` does not enforce it client-side, so an unchunked batch would have failed inside the prover; each chunk's proof is bound to the same submitter, so claims are unaffected.
25
+ - **`submitter?: Address` on every campaign builder** (`CampaignSubmitterOption`, accepted by `buildMerkleCampaign`, `encryptCampaignAmounts`, `planMerkleCampaign` and `rotateMerkleRoot`). Omitted keeps per-recipient binding; set binds the whole roster to one address under a single `encryptUint64Batch` call with one shared `inputProof`. The two shapes are mutually exclusive because an input proof carries exactly one `userAddress`, which is why bulk distribution needs a relayer. Shaped so a per-recipient `submitters?: Address[]` stays additive.
26
+ - **`UnauthorizedRedirectError`** (`TOKENOPS_UNAUTHORIZED_REDIRECT`), carrying `account`, `to` and `submitter` — the relation is the error, so blaming a single argument would mislead. Thrown before the write and mapped from the contract revert. `ZeroAccount` maps to `InvalidArgumentError`.
27
+ - **72 React hooks**, completing parity with the headless surface. Recipient, creator, campaign-owner and compliance-manager tiers on `@tokenops/sdk/fhe-airdrop/react`; the factory-admin tier (fee setters, implementation pointers, policy setters) on `@tokenops/sdk/fhe-airdrop/advanced/react`. Includes the encrypted-view mutations (`useAccessMerkleClaimAmount`, `useAccessEcdsaClaimAmount`, `useAdminGetCurrentBalance` and the disclosure family) that submit a transaction and return a handle recovered from the receipt.
28
+ - `useMemoComplianceManagerClient`, so the compliance-manager surface has a hook path at all.
12
29
 
13
- * **fhe:** add operator prerequisite DX helpers (S2, TOK-75) ([#63](https://github.com/VestingLabs/tokenops-sdk/issues/63)) ([ef45c2e](https://github.com/VestingLabs/tokenops-sdk/commit/ef45c2e61529f57a2b2338c7573b466e57fbf2cf))
30
+ ### Fixed
31
+
32
+ - **`useMerkleClaim` invalidated the wrong account.** It keyed `getClaimedAmount` on the transaction sender; the contract keys `claimedAmount` on the claim identity, so every relayed claim invalidated the relayer's cache entry and left the recipient's read stale.
33
+ - **`getClaimAmount` extracted the ACL handle for the wrong grantee.** The contract grants the outstanding handle to `account`, never the caller, so a relayed preview threw `ReceiptEventNotFoundError` after its transaction had already been mined. Silent on the self-preview path.
34
+ - The vendored local-fixture bytecode was a commit behind the vendored ABIs, so local Merkle suites deployed an implementation carrying the old `claim` selector.
35
+ - The ABI generator now emits `@alpha` itself, instead of relying on a hand-added tag that every regeneration silently dropped.
36
+
37
+ ## [1.6.0](https://github.com/VestingLabs/tokenops-sdk/compare/v1.5.1...v1.6.0) (2026-07-28)
38
+
39
+ ### Features
14
40
 
41
+ - **fhe:** add operator prerequisite DX helpers (S2, TOK-75) ([#63](https://github.com/VestingLabs/tokenops-sdk/issues/63)) ([ef45c2e](https://github.com/VestingLabs/tokenops-sdk/commit/ef45c2e61529f57a2b2338c7573b466e57fbf2cf))
15
42
 
16
43
  ### Bug Fixes
17
44
 
18
- * **airdrop:** stop preflightCreateAirdrop throwing on a non-ERC7984 token (TOK-436) ([b650324](https://github.com/VestingLabs/tokenops-sdk/commit/b6503243cb430fe224913fbbb39251586a4d4925))
19
- * correct operator-deadline guidance in SECURITY.md, record advisory rationale ([b09273d](https://github.com/VestingLabs/tokenops-sdk/commit/b09273d7d911a4dcfdfe8e2ae7f4e3a24c2130e8))
20
- * **fhe-vesting:** point Sepolia factory at the redeployed address ([0888404](https://github.com/VestingLabs/tokenops-sdk/commit/08884040987d0ebb4326d1fb80a2c2d630a6e3a6))
21
- * **vesting:** stop preflightCreateVesting throwing on a non-ERC7984 token ([dfbc795](https://github.com/VestingLabs/tokenops-sdk/commit/dfbc795fa7f0fd2aee9e1abfb711e82bca22ec4c))
45
+ - **airdrop:** stop preflightCreateAirdrop throwing on a non-ERC7984 token (TOK-436) ([b650324](https://github.com/VestingLabs/tokenops-sdk/commit/b6503243cb430fe224913fbbb39251586a4d4925))
46
+ - correct operator-deadline guidance in SECURITY.md, record advisory rationale ([b09273d](https://github.com/VestingLabs/tokenops-sdk/commit/b09273d7d911a4dcfdfe8e2ae7f4e3a24c2130e8))
47
+ - **fhe-vesting:** point Sepolia factory at the redeployed address ([0888404](https://github.com/VestingLabs/tokenops-sdk/commit/08884040987d0ebb4326d1fb80a2c2d630a6e3a6))
48
+ - **vesting:** stop preflightCreateVesting throwing on a non-ERC7984 token ([dfbc795](https://github.com/VestingLabs/tokenops-sdk/commit/dfbc795fa7f0fd2aee9e1abfb711e82bca22ec4c))
49
+
50
+ ## [2.0.0-alpha.1] - 2026-09-07
51
+
52
+ > **Pre-release built against unaudited contracts.** `/fhe-airdrop` in this build targets `tokenops-fhe-airdrop-v2`, frozen at commit `8e5b144bdbcdf35b9f36b62f5257d795bf954e8e`, which has not completed a final security audit. Deployed addresses may change before `2.0.0` GA, and breaking changes may land between any two alpha builds without a major bump (SemVer prerelease semantics). Published on the `alpha` dist-tag; `latest` stays on `1.6.0`. **For internal testing, not production value.**
53
+ >
54
+ > Migration guide: [`docs/migration/airdrop-v1-to-v2.md`](docs/migration/airdrop-v1-to-v2.md). Support policy: [`SUPPORT.md`](SUPPORT.md).
55
+
56
+ ### Changed — BREAKING
57
+
58
+ - **`/fhe-airdrop` now targets confidential airdrop v2.** The subpath name is unchanged; everything behind it is new. v1 and v2 are different contract systems, not two versions of one — there is no in-place upgrade path for a deployed v1 airdrop. `AIRDROP_CONTRACTS_COMMIT` pins the contract commit the vendored ABIs were generated from.
59
+ - **`DEPLOYED_ADDRESSES.fheAirdrop` reshaped from one key to four.** Previously a single `confidentialAirdropFactory`; now `{ airdropFactory, ecdsaImplementation, merkleImplementation, complianceManagerImplementation }`. Code reading `DEPLOYED_ADDRESSES.fheAirdrop[chainId]` must read `.airdropFactory[chainId]`. Note this member is `@public`, not `@alpha` — it is the one breaking change outside the alpha-tagged surface.
60
+ - **The EIP-712 claim typehash gained two fields.** A v1 signature will not verify against a v2 instance, or vice versa. Re-issue authorizations from the v2 signing surface; do not port stored signatures.
61
+ - **Claim entrypoints take an explicit `signer`.** The claiming account is no longer inferred from the wallet client, because a Merkle leaf commits the _claimant_ — inferring it silently produced proofs bound to the wrong address.
62
+ - **Role-constant getters renamed to SCREAMING_SNAKE** across all five clients (`DEFAULT_ADMIN_ROLE`, `PAUSER_ROLE`, `MERKLE_ADMIN_ROLE`, `DISCLOSURE_ADMIN_ROLE`, `DELEGATION_ADMIN_ROLE`, `COMPLIANCE_WIRING_ROLE`, `FEE_MANAGER_ROLE`, `FEE_COLLECTOR_ROLE`, `IMPL_MANAGER_ROLE`, `RESCUER_ROLE`). They are contract function names and now read as such.
63
+
64
+ ### Removed — BREAKING
65
+
66
+ - **The entire v1 `/fhe-airdrop` module** — clients, types, errors, ABIs, advanced surface and examples. There is no deprecation window on the v1 _shape_: it is deleted, not aliased. `1.x` remains fully supported for consumers not ready to migrate; see [`SUPPORT.md`](SUPPORT.md).
67
+ - **44 airdrop-specific React hooks** — 43 from `@tokenops/sdk/fhe-airdrop/react`, and `usePredictAirdropAddress` from `@tokenops/sdk/fhe-airdrop/advanced/react`. The v2 surface is 23 hooks (21 + 2 advanced); the reduction is deliberate, since several v1 hooks wrapped a single contract read with no added value.
68
+ - **`useIsOperator` and `useEnsureOperator` are NOT removed.** They live at `@tokenops/sdk/fhe/react` and are unaffected. If you imported them _via_ `@tokenops/sdk/fhe-airdrop/react`, change the import path; the hooks themselves are unchanged.
69
+
70
+ ### Added — confidential airdrop v2
71
+
72
+ - **Split clients per variant.** `EcdsaAirdropClient` (signature-authorized claims) and `MerkleAirdropClient` (proof-authorized claims) over a shared `AirdropBaseClient`, plus `ConfidentialAirdropFactoryClient` for creation, funding, fee administration and address prediction.
73
+ - **Merkle campaign construction, in two independently usable stages.** `encryptCampaignAmounts()` is the relayer-only half — one request per recipient, no tree. `buildMerkleTree()` is the pure half: no relayer, no chain access, deterministic, and generic over its leaf type (`L extends MerkleLeafInput`), so an `inputProof` or any caller-defined field rides through onto the returned entry at the same index with no re-correlation. `buildMerkleCampaign()` is unchanged in signature and behaviour and is now the composition of the two. This is what lets a consumer who already holds encrypted handles build a claimable campaign without re-encrypting — necessary because FHE encryption is randomised, so re-encrypting produces a tree committing to handles nobody holds.
74
+ - **`planMerkleCampaign()`** for the immutable-root path, which is otherwise circular: the root must exist before creation, yet every ciphertext binds to the instance address creation has not produced. It uses the factory's CREATE2 prediction and brackets that prediction with two init-code-hash reads, throwing `PredictionDriftError` rather than returning a plan bound to a stale address.
75
+ - **`rotateMerkleRoot()`** — re-encrypt and republish as a top-up. A claim pays `total − min(total, alreadyDelivered)`, so `recipients` must carry each account's new _cumulative_ total, never an increment.
76
+ - **`ComplianceManagerClient`** for the compliance clone: wiring, party disclosure, and role administration.
77
+ - **Instance role splitting and full role administration** — `planInstanceRoleSplit()` and `grantInstanceRoles()`, which confirms each step's receipt before advancing so a dependent revoke cannot be simulated against state that lacks the preceding grant.
78
+ - **Guardrails and preflights** — typed, pre-transaction failures for salt collisions, wrapper assumptions and window state, instead of an opaque revert.
79
+ - **`deploymentMode()`** on `AirdropBaseClient`, reading the ERC-1967 implementation slot. Necessary because `proxiableUUID()` cannot discriminate a clone from a UUPS proxy: OpenZeppelin's `notDelegated` makes it revert through _any_ proxy.
80
+ - **`upgradeToAndCall()`** on `AirdropBaseClient`, and **`eip712Domain()`** on `EcdsaAirdropClient` (EIP-5267 domain discovery).
81
+ - **23 React hooks** across `/fhe-airdrop/react` and `/fhe-airdrop/advanced/react`, wagmi + TanStack Query, sharing the `"tokenops-sdk"` query-key prefix used by every sibling subpath.
82
+ - **Typed error mapping** from v2 revert selectors, and encrypted-view reads that extract handles from the executed receipt's ACL `Allowed` event rather than from `simulateContract()` — a simulated handle carries no ACL and fails later, at the decrypt, far from its cause.
83
+ - **Docs and examples** — [`docs/fhe-airdrop/README.md`](docs/fhe-airdrop/README.md) with measured live-relayer throughput, per-recipient storage sizing, and a "bring your own handles" guide; [`docs/migration/airdrop-v1-to-v2.md`](docs/migration/airdrop-v1-to-v2.md); a README compatibility matrix; and three runnable examples (`fhe-airdrop-merkle-campaign.ts`, `fhe-airdrop-external-handles.ts`, `fhe-airdrop-ecdsa-claim.ts`).
84
+
85
+ ### Fixed
86
+
87
+ - **`release.yml` no longer defaults a prerelease onto the `latest` dist-tag.** The npm dist-tag is derived from the package version (`alpha` / `beta` / `rc` / `next` / `latest`), and the `workflow_dispatch` override input now defaults to blank so it cannot mask that derivation.
88
+ - **`useAirdropPause` invalidates the `window` query as well as `paused`.** `isClaimWindowActive()` ANDs the pause flag with the window check, so mounted `useAirdropWindow` consumers previously kept a stale `isActive` after either pause transition.
89
+
90
+ ---
22
91
 
23
- ## [Unreleased]
92
+ _The sections below were developed against `1.x` and had not yet shipped when `2.0.0-alpha.1` was cut. They are unrelated to the airdrop rewrite, and none of them are breaking._
24
93
 
25
94
  ### Added — operator prerequisite DX helpers (TOK-75)
26
95
 
package/CONTRIBUTING.md CHANGED
@@ -108,6 +108,8 @@ Pattern: `<type>(<scope>): <imperative description>`. Scope is optional; use the
108
108
 
109
109
  ## Claude Code Setup
110
110
 
111
- The `claude-setup/` directory contains a `settings.json` and skill definitions that configure Claude Code for this repository. Copy or symlink them to your local `.claude/` to get the same hooks (auto-typecheck, auto-lint on Write/Edit) and skills (jsdoc, tanstack-best-practices) that CI enforces.
111
+ The `claude-setup/` directory contains a `settings.json` and skill definitions (jsdoc, tanstack-best-practices, fhevm-security) that configure Claude Code for this repository. Run `pnpm setup:claude` to install them into your local `.claude/`. It copies on a first run and merges on later ones, so re-running after a pull picks up repo changes without discarding your own settings.
112
112
 
113
- See the `claude-setup/` directory and Zama's [Claude Code plugin model](https://docs.claude.ai/en/docs/claude-code) for details.
113
+ `.claude/` is gitignored, so adoption is opt-in and nothing you put there is shared. `.codex/` and `.agents/` are ignored on the same basis - this repo does not assume which agent you use.
114
+
115
+ See the `claude-setup/` directory and Anthropic's [Claude Code plugin model](https://docs.claude.ai/en/docs/claude-code) for details.
package/README.md CHANGED
@@ -21,27 +21,43 @@ Node `>= 22` is required (constraint from `@zama-fhe/sdk`).
21
21
 
22
22
  All subpaths are independently tree-shakeable. The `/react` paths keep React deps out of the server bundle.
23
23
 
24
- | Subpath | Status | Description |
25
- | ------------------------------------------ | ----------------------------------- | --------------------------------------------------------------------------------------------------------- |
26
- | `@tokenops/sdk` | stable | Root re-exports (version, core error types) |
27
- | `@tokenops/sdk/telemetry` | stable | Telemetry sink adapters (`NoopTelemetry`, `ConsoleTelemetry`, `TokenOpsTelemetry`) |
28
- | `@tokenops/sdk/fhe` | stable | FHE utility helpers (ratio scaling, encrypted-input types, operator helpers) |
29
- | `@tokenops/sdk/fhe/react` | stable | React hooks for shared FHE utilities |
30
- | `@tokenops/sdk/fhe-vesting` | factory live on Sepolia | Confidential vesting (LibClone + packed immutable args) |
31
- | `@tokenops/sdk/fhe-vesting/react` | stable | React/wagmi hooks for confidential vesting |
32
- | `@tokenops/sdk/fhe-vesting/advanced` | stable | Pre-mine address prediction (`predictManagerAddress`) |
33
- | `@tokenops/sdk/fhe-vesting/advanced/react` | stable | React hooks for advanced vesting flows |
34
- | `@tokenops/sdk/fhe-airdrop` | factory live on Sepolia | ConfidentialAirdrop (EIP-712 gated confidential claims) |
35
- | `@tokenops/sdk/fhe-airdrop/react` | stable | React/wagmi hooks for confidential airdrops |
36
- | `@tokenops/sdk/fhe-airdrop/advanced` | stable | Pre-mine address prediction (`predictAirdropAddress`) |
37
- | `@tokenops/sdk/fhe-airdrop/advanced/react` | stable | React hooks for advanced airdrop flows |
38
- | `@tokenops/sdk/fhe-disperse` | singleton live on mainnet + Sepolia | DisperseConfidential (singleton + per-user wallet-pair clones) |
39
- | `@tokenops/sdk/fhe-disperse/react` | stable | React/wagmi hooks for confidential disperse |
40
- | `@tokenops/sdk/testnet-faucet` | token pair live on Sepolia | Testnet faucet for the TokenOps test-token pair — TTT (plain ERC-20) + CTTT (ERC-7984 wrapper); open mint |
41
- | `@tokenops/sdk/testnet-faucet/react` | stable | React/wagmi hooks for the testnet faucet |
24
+ | Subpath | Status | Description |
25
+ | ------------------------------------------ | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
26
+ | `@tokenops/sdk` | stable | Root re-exports (version, core error types) |
27
+ | `@tokenops/sdk/telemetry` | stable | Telemetry sink adapters (`NoopTelemetry`, `ConsoleTelemetry`, `TokenOpsTelemetry`) |
28
+ | `@tokenops/sdk/fhe` | stable | FHE utility helpers (ratio scaling, encrypted-input types, operator helpers) |
29
+ | `@tokenops/sdk/fhe/react` | stable | React hooks for shared FHE utilities |
30
+ | `@tokenops/sdk/fhe-vesting` | factory live on Sepolia | Confidential vesting (LibClone + packed immutable args) |
31
+ | `@tokenops/sdk/fhe-vesting/react` | stable | React/wagmi hooks for confidential vesting |
32
+ | `@tokenops/sdk/fhe-vesting/advanced` | stable | Pre-mine address prediction (`predictManagerAddress`) |
33
+ | `@tokenops/sdk/fhe-vesting/advanced/react` | stable | React hooks for advanced vesting flows |
34
+ | `@tokenops/sdk/fhe-airdrop` | **v2, unaudited** — `alpha` dist-tag, factory live on Sepolia | ECDSA + Merkle confidential airdrop campaigns — see [Compatibility](#compatibility) |
35
+ | `@tokenops/sdk/fhe-airdrop/react` | **v2, unaudited** | React/wagmi hooks for recipients, campaign creators, campaign owners and the compliance manager |
36
+ | `@tokenops/sdk/fhe-airdrop/advanced` | **v2, unaudited** | Prediction-freshness / salt-availability guards for CREATE2 address prediction (prediction itself is on the headline `ConfidentialAirdropFactoryClient`) |
37
+ | `@tokenops/sdk/fhe-airdrop/advanced/react` | **v2, unaudited** | Address-prediction hooks plus the factory-admin tier (fee setters, implementation pointers, policy setters) |
38
+ | `@tokenops/sdk/fhe-disperse` | singleton live on mainnet + Sepolia | DisperseConfidential (singleton + per-user wallet-pair clones) |
39
+ | `@tokenops/sdk/fhe-disperse/react` | stable | React/wagmi hooks for confidential disperse |
40
+ | `@tokenops/sdk/testnet-faucet` | token pair live on Sepolia | Testnet faucet for the TokenOps test-token pair — TTT (plain ERC-20) + CTTT (ERC-7984 wrapper); open mint |
41
+ | `@tokenops/sdk/testnet-faucet/react` | stable | React/wagmi hooks for the testnet faucet |
42
42
 
43
43
  The canonical exports map is in [`package.json`](https://github.com/VestingLabs/tokenops-sdk/blob/main/package.json) under `"exports"`.
44
44
 
45
+ ## Compatibility
46
+
47
+ Which contract generation a given SDK version talks to, and where that generation is deployed:
48
+
49
+ | SDK | Airdrop contracts | Contract commit | Chains |
50
+ | --------------- | ------------------ | --------------- | ------- |
51
+ | `2.0.0-alpha.x` | v2 (**unaudited**) | `7175ac8` | Sepolia |
52
+ | `1.x` | v1 | n/a | Sepolia |
53
+
54
+ `2.x`'s `/fhe-airdrop` is a full replacement of v1, not an extension — see
55
+ [`docs/migration/airdrop-v1-to-v2.md`](docs/migration/airdrop-v1-to-v2.md) for the symbol-by-symbol
56
+ delta and [`SUPPORT.md`](SUPPORT.md) for how long `1.x` keeps receiving fixes. The v1 Sepolia
57
+ factory (`0xbE6A3B78B36684fFee48De77d47Bc3393F5Acd4c`) stays live on-chain; `2.x` simply stops
58
+ addressing it. `/fhe-vesting` and `/fhe-disperse` are unaffected by this table — both are on their
59
+ usual SemVer track regardless of which `/fhe-airdrop` line you install.
60
+
45
61
  ## Quickstart — confidential vesting
46
62
 
47
63
  ```ts
@@ -268,17 +284,22 @@ See [Confidential Vesting — React hooks on docs.tokenops.xyz](https://docs.tok
268
284
 
269
285
  ## Quickstart — confidential airdrop
270
286
 
287
+ > **v2, unaudited.** `/fhe-airdrop` targets `tokenops-fhe-airdrop-v2` (`7175ac8`, Sepolia only, `alpha` dist-tag) — see [Compatibility](#compatibility). Migrating from `1.x`? See [`docs/migration/airdrop-v1-to-v2.md`](docs/migration/airdrop-v1-to-v2.md).
288
+
289
+ Two claim-authorisation variants share one factory: **ECDSA** (an off-chain signature from a `SIGNER_ROLE` holder) and **Merkle** (inclusion in a published tree). The example below is ECDSA — see [`docs/fhe-airdrop/README.md`](docs/fhe-airdrop/README.md#quickstart--merkle-campaign) for the Merkle flow.
290
+
271
291
  ```ts
272
- import { createPublicClient, createWalletClient, http } from "viem";
292
+ import { createPublicClient, createWalletClient, http, zeroAddress } from "viem";
273
293
  import { sepolia } from "viem/chains";
274
294
  import { privateKeyToAccount } from "viem/accounts";
275
295
  import { RelayerNode, SepoliaConfig } from "@zama-fhe/sdk/node";
276
296
  import {
277
297
  createConfidentialAirdropFactoryClient,
278
- createConfidentialAirdropClient,
298
+ createEcdsaAirdropClient,
279
299
  encryptUint64,
280
300
  signClaimAuthorization,
281
301
  } from "@tokenops/sdk/fhe-airdrop";
302
+ import { setOperator } from "@tokenops/sdk/fhe";
282
303
 
283
304
  const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
284
305
  const rpcUrl = process.env.RPC_URL!;
@@ -291,80 +312,98 @@ const encryptor = new RelayerNode({
291
312
  });
292
313
 
293
314
  // Factory address resolves automatically from DEPLOYED_ADDRESSES on Sepolia.
294
- const factory = createConfidentialAirdropFactoryClient({
295
- publicClient,
296
- walletClient,
297
- encryptor,
298
- });
315
+ const factory = createConfidentialAirdropFactoryClient({ publicClient, walletClient, encryptor });
299
316
 
300
317
  const now = Math.floor(Date.now() / 1000);
301
318
  const userSalt = "0x0000000000000000000000000000000000000000000000000000000000000001" as const;
302
319
  const token = process.env.TOKEN as `0x${string}`;
303
- const params = {
304
- token,
305
- startTimestamp: now + 60,
306
- endTimestamp: now + 30 * 86400,
307
- canExtendClaimWindow: false,
308
- admin: account.address,
309
- };
310
-
311
- // Deploy and read the clone address from the ConfidentialAirdropCreated event.
312
- // (predictAirdropAddress also works — airdrop immutable args don't pack
313
- // block.number, so the predicted address is stable across blocks.)
314
- const { airdrop: airdropAddress } = await factory.createConfidentialAirdropAndGetAddress({
315
- params,
320
+
321
+ // Create. There is no `admin` field — the factory injects `admin = msg.sender`.
322
+ // `dedupMode` is required and cannot be read back from the chain later; record
323
+ // it yourself alongside the deployed address.
324
+ const { airdrop: airdropAddress } = await factory.createEcdsaAirdrop({
325
+ params: {
326
+ common: {
327
+ token,
328
+ startTime: now + 60,
329
+ endTime: now + 30 * 86400,
330
+ canExtendClaimWindow: false,
331
+ unwrappable: false,
332
+ complianceAdmin: zeroAddress, // zero => msg.sender
333
+ },
334
+ signer: account.address, // SIGNER_ROLE holder authorising claims
335
+ dedupMode: "perAddress",
336
+ },
337
+ mode: "clone",
316
338
  userSalt,
317
339
  });
318
340
 
319
- // Admin: issue a signed claim authorization for a recipient. Bind the input
320
- // proof to the RECIPIENT — Zama proofs commit to (contractAddress, userAddress)
321
- // at encrypt time, and `FHE.fromExternal` on-chain rejects any other binding.
341
+ // Fund. Requires the factory to hold ERC-7984 operator approval first — the
342
+ // FACTORY calls FHE.fromExternal on the pool amount, so the operator grant
343
+ // and the encryption both bind to the factory, not to the airdrop instance.
344
+ await setOperator({ publicClient, walletClient, token, spender: factory.address });
345
+ await factory.fundAirdrop({ airdrop: airdropAddress, amount: 1_000_000n });
346
+
347
+ // Admin: sign a claim authorization for a recipient. Bind the input proof to
348
+ // the RECIPIENT and to the AIRDROP INSTANCE — Zama proofs commit to
349
+ // (contractAddress, userAddress) at encrypt time, and a claim binds to
350
+ // (instance, claimant), not (factory, funder). Get the pair wrong and
351
+ // `FHE.fromExternal` reverts; it does not silently decrypt to zero.
322
352
  // amount is raw token units; ERC-7984 uses 6 decimals, so 1_000_000n = 1 token.
323
353
  const recipient = "0xRecipientAddress" as `0x${string}`;
324
- const encrypted = await encryptUint64({
354
+ const encryptedInput = await encryptUint64({
325
355
  encryptor,
326
356
  contractAddress: airdropAddress,
327
357
  userAddress: recipient,
328
358
  value: 1_000_000n,
329
359
  });
360
+ const dedupId = "0x0000000000000000000000000000000000000000000000000000000000000001" as const;
361
+ const deadline = BigInt(now + 3600); // signature expires in 1 hour
330
362
  const signature = await signClaimAuthorization({
331
363
  walletClient,
332
- airdropAddress,
364
+ airdrop: airdropAddress,
365
+ chainId: sepolia.id,
333
366
  recipient,
334
- encryptedAmountHandle: encrypted.handle,
367
+ encryptedAmountHandle: encryptedInput.handle,
368
+ dedupId,
369
+ deadline,
335
370
  });
336
- // Deliver { encryptedInput: encrypted, signature } to the recipient via API / email / etc.
371
+ // Deliver { encryptedInput, dedupId, deadline, signer: account.address, signature }
372
+ // to the recipient via API / email / etc.
337
373
 
338
374
  // User: claim tokens. The SDK submits the admin-issued pair verbatim — no
339
- // re-encryption. (GAS_FEE() is fetched and attached as msg.value automatically.)
340
- const airdrop = createConfidentialAirdropClient({
375
+ // re-encryption. The exact-equality gas fee (0 on the live Sepolia deployment
376
+ // today) is fetched fresh and attached as msg.value automatically.
377
+ const airdrop = createEcdsaAirdropClient({
341
378
  publicClient,
342
379
  walletClient,
343
380
  address: airdropAddress,
381
+ dedupMode: "perAddress", // must match what was passed at create — no getter exists
344
382
  });
345
- await airdrop.claim({ signature, encryptedInput: encrypted });
383
+ await airdrop.claim({ encryptedInput, dedupId, deadline, signer: account.address, signature });
346
384
  ```
347
385
 
348
- See [Confidential Airdrop on docs.tokenops.xyz](https://docs.tokenops.xyz/sdk/fhe-airdrop) for the full API reference and claim flow diagram.
386
+ See [`docs/fhe-airdrop/README.md`](docs/fhe-airdrop/README.md) for the full API reference, the Merkle campaign flow, guardrails, and the unaudited-contracts warning.
349
387
 
350
388
  ### Quickstart — confidential airdrop (React hooks)
351
389
 
352
- Uses `@tokenops/sdk/fhe-airdrop/react`. Requires `wagmi`, `@tanstack/react-query`, and `@zama-fhe/react-sdk` as additional peer deps.
390
+ Uses `@tokenops/sdk/fhe-airdrop/react`. Requires `wagmi`, `@tanstack/react-query`, and `@zama-fhe/react-sdk` as additional peer deps. `signClaimAuthorization` is re-exported as a plain function (not a mutation hook) — signing is a synchronous `walletClient.signTypedData` call with no chain state to invalidate.
353
391
 
354
392
  ```tsx
355
- import { useQueryClient } from "@tanstack/react-query";
393
+ import { useWalletClient } from "wagmi";
356
394
  import { useZamaSDK } from "@zama-fhe/react-sdk";
357
395
  import {
358
- useCreateConfidentialAirdropAndGetAddress,
359
- useSignClaimAuthorization,
360
- useClaim,
396
+ useCreateEcdsaAirdrop,
397
+ useFundAirdrop,
398
+ useEcdsaClaim,
361
399
  encryptUint64,
400
+ signClaimAuthorization,
362
401
  } from "@tokenops/sdk/fhe-airdrop/react";
363
402
 
364
403
  // Wrap your app in wagmi's <WagmiProvider> + <QueryClientProvider> +
365
404
  // @zama-fhe/react-sdk's <ZamaProvider> before rendering these components.
366
405
 
367
- // --- Admin: deploy a campaign and issue a claim authorization ---
406
+ // --- Admin: deploy a campaign, fund it, and issue a claim authorization ---
368
407
 
369
408
  function AdminPanel({
370
409
  token,
@@ -379,58 +418,79 @@ function AdminPanel({
379
418
  airdrop: `0x${string}`,
380
419
  payload: {
381
420
  encryptedInput: { handle: `0x${string}`; inputProof: `0x${string}` };
421
+ dedupId: `0x${string}`;
422
+ deadline: bigint;
423
+ signer: `0x${string}`;
382
424
  signature: `0x${string}`;
383
425
  },
384
426
  ) => void;
385
427
  }) {
386
- const queryClient = useQueryClient();
387
428
  const zamaSDK = useZamaSDK();
429
+ const { data: walletClient } = useWalletClient();
388
430
 
389
431
  // Factory address resolves automatically from DEPLOYED_ADDRESSES on Sepolia.
390
- const create = useCreateConfidentialAirdropAndGetAddress();
391
-
392
- // walletClient is pulled from wagmi's useWalletClient() internally.
393
- const sign = useSignClaimAuthorization();
432
+ // `useCreateEcdsaAirdrop` invalidates the factory registry reads for you.
433
+ const create = useCreateEcdsaAirdrop({ encryptor: () => zamaSDK.relayer });
434
+ const fund = useFundAirdrop({ encryptor: () => zamaSDK.relayer });
394
435
 
395
436
  const now = Math.floor(Date.now() / 1000);
396
437
 
397
438
  async function handleLaunch() {
398
439
  const { airdrop } = await create.mutateAsync({
399
440
  params: {
400
- token,
401
- startTimestamp: now + 60,
402
- endTimestamp: now + 30 * 86400,
403
- canExtendClaimWindow: false,
404
- admin: "0xYourAdminAddress" as `0x${string}`,
441
+ common: {
442
+ token,
443
+ startTime: now + 60,
444
+ endTime: now + 30 * 86400,
445
+ canExtendClaimWindow: false,
446
+ unwrappable: false,
447
+ complianceAdmin: "0x0000000000000000000000000000000000000000",
448
+ },
449
+ signer: "0xYourSignerAddress" as `0x${string}`,
450
+ dedupMode: "perAddress", // record this — no on-chain getter exists later
405
451
  },
452
+ mode: "clone",
406
453
  userSalt:
407
454
  "0x0000000000000000000000000000000000000000000000000000000000000001" as `0x${string}`,
408
455
  });
409
456
 
410
- queryClient.invalidateQueries({ queryKey: ["tokenops-sdk", "fhe-airdrop"] });
457
+ await fund.mutateAsync({ airdrop, amount });
411
458
 
412
- // Encrypt the allocation for the recipient.
413
- const encrypted = await encryptUint64({
459
+ // Encrypt bound to (airdrop instance, recipient) — not the factory.
460
+ const encryptedInput = await encryptUint64({
414
461
  encryptor: zamaSDK.relayer,
415
462
  contractAddress: airdrop,
416
463
  userAddress: recipient,
417
464
  value: amount,
418
465
  });
419
466
 
420
- // Sign the EIP-712 claim authorization.
421
- const signature = await sign.mutateAsync({
422
- airdropAddress: airdrop,
467
+ const dedupId = "0x0000000000000000000000000000000000000000000000000000000000000001" as const;
468
+ const deadline = BigInt(now + 3600);
469
+
470
+ // Sign is a plain async function here — walletClient comes from wagmi.
471
+ const signature = await signClaimAuthorization({
472
+ walletClient: walletClient!,
473
+ airdrop,
474
+ chainId: walletClient!.chain.id,
423
475
  recipient,
424
- encryptedAmountHandle: encrypted.handle,
476
+ encryptedAmountHandle: encryptedInput.handle,
477
+ dedupId,
478
+ deadline,
425
479
  });
426
480
 
427
- // Deliver { encryptedInput: encrypted, signature } to the recipient via your API / email.
428
- onCampaignReady(airdrop, { encryptedInput: encrypted, signature });
481
+ // Deliver this payload to the recipient via your API / email.
482
+ onCampaignReady(airdrop, {
483
+ encryptedInput,
484
+ dedupId,
485
+ deadline,
486
+ signer: "0xYourSignerAddress" as `0x${string}`,
487
+ signature,
488
+ });
429
489
  }
430
490
 
431
491
  return (
432
- <button onClick={handleLaunch} disabled={create.isPending || sign.isPending}>
433
- {create.isPending ? "Deploying…" : sign.isPending ? "Signing…" : "Launch airdrop"}
492
+ <button onClick={handleLaunch} disabled={create.isPending || fund.isPending}>
493
+ {create.isPending ? "Deploying…" : fund.isPending ? "Funding…" : "Launch airdrop"}
434
494
  </button>
435
495
  );
436
496
  }
@@ -442,33 +502,29 @@ function RecipientClaim({
442
502
  claimPayload,
443
503
  }: {
444
504
  airdropAddress: `0x${string}`;
445
- // The admin-issued payload — encryption bound to this recipient, handle
446
- // committed to by the signature. The recipient submits it verbatim.
505
+ // The admin-issued payload — encryption bound to this recipient and this
506
+ // instance, handle committed to by the signature. Submitted verbatim.
447
507
  claimPayload: {
448
508
  encryptedInput: { handle: `0x${string}`; inputProof: `0x${string}` };
509
+ dedupId: `0x${string}`;
510
+ deadline: bigint;
511
+ signer: `0x${string}`;
449
512
  signature: `0x${string}`;
450
513
  };
451
514
  }) {
452
- const queryClient = useQueryClient();
453
- const claim = useClaim({ address: airdropAddress });
515
+ // `dedupMode` must match what the campaign was created with — the contract
516
+ // has no on-chain getter, so a consumer must already know it.
517
+ const claim = useEcdsaClaim({ address: airdropAddress, dedupMode: "perAddress" });
454
518
 
455
519
  return (
456
- <button
457
- onClick={() =>
458
- claim.mutate(claimPayload, {
459
- onSuccess: () =>
460
- queryClient.invalidateQueries({ queryKey: ["tokenops-sdk", "fhe-airdrop"] }),
461
- })
462
- }
463
- disabled={claim.isPending}
464
- >
520
+ <button onClick={() => claim.mutate(claimPayload)} disabled={claim.isPending}>
465
521
  {claim.isPending ? "Claiming…" : "Claim tokens"}
466
522
  </button>
467
523
  );
468
524
  }
469
525
  ```
470
526
 
471
- See [Confidential Airdrop — React hooks on docs.tokenops.xyz](https://docs.tokenops.xyz/sdk/fhe-airdrop#react-hooks) for the full hook catalogue, encryptor wiring, address overrides, and query-key reference.
527
+ See [`docs/fhe-airdrop/README.md`](docs/fhe-airdrop/README.md) for the full hook catalogue across both import paths (`/fhe-airdrop/react` for recipients, creators, owners and compliance; `/fhe-airdrop/advanced/react` for prediction and factory admin), encryptor wiring, address overrides, and query-key reference.
472
528
 
473
529
  ## Quickstart — confidential disperse
474
530
 
package/SUPPORT.md ADDED
@@ -0,0 +1,47 @@
1
+ # Support policy
2
+
3
+ This document states what level of support each `@tokenops/sdk` release line receives. It exists
4
+ because `2.0.0` is a major version driven by a full replacement of the `/fhe-airdrop` module
5
+ (v1 deleted, v2 takes the subpath) — see
6
+ [`docs/migration/airdrop-v1-to-v2.md`](docs/migration/airdrop-v1-to-v2.md) for the technical
7
+ delta.
8
+
9
+ ## `1.x`
10
+
11
+ - **Critical security and correctness fixes only, for 90 days after `2.0.0` reaches `latest`
12
+ (GA).** After that window, `1.x` receives no further fixes of any kind.
13
+ - **No feature work on `1.x` from the day `release/v2` was opened (2026-09-05).** Every new
14
+ capability lands on the `2.x` line only, starting from that date.
15
+ - `1.x` is what you stay on if you depend on the v1 `/fhe-airdrop` shape and are not ready to
16
+ migrate — nothing about `1.x` breaks or is withdrawn by `2.0.0` shipping. Consumers that do not
17
+ import `/fhe-airdrop` are unaffected by the replacement and can move on their own schedule.
18
+ - The v1 contracts stay live on-chain throughout and beyond this window. This policy governs the
19
+ SDK's code, not contract uptime.
20
+
21
+ ## `2.x`
22
+
23
+ - `2.0.0-alpha.x` and `2.0.0-beta.x` are pre-release channels for the airdrop v2 rewrite. No
24
+ stability promise between alpha builds; breaking changes may land between any two alpha
25
+ versions without a major bump, per SemVer's prerelease semantics. See the compatibility matrix
26
+ in [`README.md`](README.md#compatibility) for which contract commit each build speaks to.
27
+ - `2.0.0` (GA, `latest` dist-tag) ships once `tokenops-fhe-airdrop-v2` is audited and its
28
+ addresses are final. From GA onward, `2.x` follows the SDK's normal SemVer + Conventional
29
+ Commits support model — the same one `1.x` operated under before this document existed.
30
+
31
+ ## Why `npm deprecate` is not used on the `1.x` range
32
+
33
+ `npm deprecate` operates on the package as a whole, scoped by version range — it has no concept
34
+ of "deprecate this subpath only." Running it against the `1.x` range would print a deprecation
35
+ warning on every install of `@tokenops/sdk@1.x`, including installs that use only `/fhe-vesting`
36
+ or `/fhe-disperse` — modules that are not being replaced and are not affected by this migration.
37
+ A package-wide deprecation notice would misrepresent the status of code that isn't changing. The
38
+ `1.x` line is fully supported per the window above; only the `/fhe-airdrop` _shape_ is superseded,
39
+ and that message belongs in the migration guide and the module README, not in an npm-wide flag
40
+ that cannot be scoped to one subpath.
41
+
42
+ ## Getting help
43
+
44
+ - Migrating off v1 `/fhe-airdrop`: [`docs/migration/airdrop-v1-to-v2.md`](docs/migration/airdrop-v1-to-v2.md).
45
+ - Module docs (v2, unaudited): [`docs/fhe-airdrop/README.md`](docs/fhe-airdrop/README.md).
46
+ - Security issues: see [`SECURITY.md`](SECURITY.md).
47
+ - Everything else: open an issue against `VestingLabs/tokenops-sdk`.