@tokenops/sdk 1.0.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 (371) hide show
  1. package/CHANGELOG.md +207 -0
  2. package/CONTRIBUTING.md +113 -0
  3. package/LICENSE +32 -0
  4. package/README.md +677 -0
  5. package/SECURITY.md +59 -0
  6. package/dist/chunk-52TC6BF7.js +2755 -0
  7. package/dist/chunk-56UI7LUR.cjs +516 -0
  8. package/dist/chunk-5SA2HF2W.cjs +1635 -0
  9. package/dist/chunk-5SGMJADP.cjs +139 -0
  10. package/dist/chunk-62DF53UQ.cjs +749 -0
  11. package/dist/chunk-66IHPTOK.cjs +20 -0
  12. package/dist/chunk-6ECAHP5O.cjs +1496 -0
  13. package/dist/chunk-72YGZEQE.js +742 -0
  14. package/dist/chunk-7VELUOMI.js +35 -0
  15. package/dist/chunk-BE2AIZ3K.js +23 -0
  16. package/dist/chunk-CMRETRZO.js +46 -0
  17. package/dist/chunk-COPFW5Z4.js +82 -0
  18. package/dist/chunk-CQIPRNS7.cjs +25 -0
  19. package/dist/chunk-ECT3NL2L.js +124 -0
  20. package/dist/chunk-FWHYQZ5E.cjs +37 -0
  21. package/dist/chunk-FYQ2UW4T.js +37 -0
  22. package/dist/chunk-HGXNRR25.js +105 -0
  23. package/dist/chunk-HTOMTEA3.cjs +3406 -0
  24. package/dist/chunk-ITQ7WKVC.cjs +101 -0
  25. package/dist/chunk-IVE3QEGD.js +478 -0
  26. package/dist/chunk-JFLEEXKP.js +325 -0
  27. package/dist/chunk-JFR5J4FL.cjs +128 -0
  28. package/dist/chunk-K6MFFDBJ.cjs +109 -0
  29. package/dist/chunk-KWFFIJYX.js +11 -0
  30. package/dist/chunk-NS44KBV5.cjs +89 -0
  31. package/dist/chunk-OLDGMKW2.cjs +93 -0
  32. package/dist/chunk-Q2GP5UDC.js +29 -0
  33. package/dist/chunk-Q7ARQSUH.cjs +42 -0
  34. package/dist/chunk-QCA7O2Q5.cjs +49 -0
  35. package/dist/chunk-QIHZVLIK.js +3388 -0
  36. package/dist/chunk-SUOG3BQS.cjs +2772 -0
  37. package/dist/chunk-T5LVV3KY.cjs +44 -0
  38. package/dist/chunk-UOG4PJL5.js +1488 -0
  39. package/dist/chunk-VDXVNZCO.cjs +329 -0
  40. package/dist/chunk-VJKZWYYJ.cjs +32 -0
  41. package/dist/chunk-WRCUDSUJ.js +96 -0
  42. package/dist/chunk-XSNLAS5M.js +135 -0
  43. package/dist/chunk-XXXDQSHE.js +1628 -0
  44. package/dist/chunk-ZHFLRKFY.js +41 -0
  45. package/dist/chunk-ZXCOJY2Z.js +87 -0
  46. package/dist/core/addresses.d.ts +59 -0
  47. package/dist/core/brands.d.ts +87 -0
  48. package/dist/core/chains.d.ts +102 -0
  49. package/dist/core/errors.d.ts +687 -0
  50. package/dist/core/index.d.ts +7 -0
  51. package/dist/core/normalise.d.ts +27 -0
  52. package/dist/core/preflight.d.ts +25 -0
  53. package/dist/core/revert-mapper.d.ts +74 -0
  54. package/dist/core/telemetry.d.ts +50 -0
  55. package/dist/core/types.d.ts +10 -0
  56. package/dist/core/version.d.ts +15 -0
  57. package/dist/core/zama-error-mapper.d.ts +27 -0
  58. package/dist/fhe/acl.d.ts +73 -0
  59. package/dist/fhe/erc7984-abi.d.ts +53 -0
  60. package/dist/fhe/index.cjs +599 -0
  61. package/dist/fhe/index.d.cts +11 -0
  62. package/dist/fhe/index.d.ts +11 -0
  63. package/dist/fhe/index.js +394 -0
  64. package/dist/fhe/mock-encryptor.d.ts +90 -0
  65. package/dist/fhe/mock-erc7984.d.ts +134 -0
  66. package/dist/fhe/operators.d.ts +190 -0
  67. package/dist/fhe/react/index.cjs +102 -0
  68. package/dist/fhe/react/index.d.cts +10 -0
  69. package/dist/fhe/react/index.d.ts +10 -0
  70. package/dist/fhe/react/index.js +85 -0
  71. package/dist/fhe/react/use-decrypted-handle.d.ts +102 -0
  72. package/dist/fhe/scale-ratio.d.ts +168 -0
  73. package/dist/fhe/sepolia-encryptor-web.d.ts +101 -0
  74. package/dist/fhe/sepolia-encryptor.d.ts +132 -0
  75. package/dist/fhe/types.d.ts +62 -0
  76. package/dist/fhe-airdrop/abis/cloneable.d.ts +781 -0
  77. package/dist/fhe-airdrop/abis/factory.d.ts +714 -0
  78. package/dist/fhe-airdrop/abis/index.d.ts +2 -0
  79. package/dist/fhe-airdrop/advanced/factory-advanced.d.ts +53 -0
  80. package/dist/fhe-airdrop/advanced/index.cjs +21 -0
  81. package/dist/fhe-airdrop/advanced/index.d.cts +13 -0
  82. package/dist/fhe-airdrop/advanced/index.d.ts +13 -0
  83. package/dist/fhe-airdrop/advanced/index.js +8 -0
  84. package/dist/fhe-airdrop/advanced/react/index.cjs +61 -0
  85. package/dist/fhe-airdrop/advanced/react/index.d.cts +5 -0
  86. package/dist/fhe-airdrop/advanced/react/index.d.ts +5 -0
  87. package/dist/fhe-airdrop/advanced/react/index.js +59 -0
  88. package/dist/fhe-airdrop/advanced/react/usePredictAirdropAddress.d.ts +49 -0
  89. package/dist/fhe-airdrop/airdrop.d.ts +308 -0
  90. package/dist/fhe-airdrop/encryption.d.ts +109 -0
  91. package/dist/fhe-airdrop/errors.d.ts +60 -0
  92. package/dist/fhe-airdrop/factory.d.ts +281 -0
  93. package/dist/fhe-airdrop/index.cjs +227 -0
  94. package/dist/fhe-airdrop/index.d.cts +10 -0
  95. package/dist/fhe-airdrop/index.d.ts +10 -0
  96. package/dist/fhe-airdrop/index.js +10 -0
  97. package/dist/fhe-airdrop/react/_shared.d.ts +107 -0
  98. package/dist/fhe-airdrop/react/index.cjs +638 -0
  99. package/dist/fhe-airdrop/react/index.d.cts +90 -0
  100. package/dist/fhe-airdrop/react/index.d.ts +90 -0
  101. package/dist/fhe-airdrop/react/index.js +430 -0
  102. package/dist/fhe-airdrop/react/useAccessClaimAmount.d.ts +31 -0
  103. package/dist/fhe-airdrop/react/useAirdropCanExtendClaimWindow.d.ts +7 -0
  104. package/dist/fhe-airdrop/react/useAirdropClaim.d.ts +25 -0
  105. package/dist/fhe-airdrop/react/useAirdropClaimTypehash.d.ts +10 -0
  106. package/dist/fhe-airdrop/react/useAirdropClaimedSignatures.d.ts +16 -0
  107. package/dist/fhe-airdrop/react/useAirdropDeploymentBlockNumber.d.ts +6 -0
  108. package/dist/fhe-airdrop/react/useAirdropDomainSeparator.d.ts +8 -0
  109. package/dist/fhe-airdrop/react/useAirdropEndTime.d.ts +10 -0
  110. package/dist/fhe-airdrop/react/useAirdropFactoryCustomFee.d.ts +17 -0
  111. package/dist/fhe-airdrop/react/useAirdropFactoryDefaultGasFee.d.ts +10 -0
  112. package/dist/fhe-airdrop/react/useAirdropFactoryDisableCustomFee.d.ts +15 -0
  113. package/dist/fhe-airdrop/react/useAirdropFactoryFeeCollector.d.ts +11 -0
  114. package/dist/fhe-airdrop/react/useAirdropFactoryInitCodeHash.d.ts +17 -0
  115. package/dist/fhe-airdrop/react/useAirdropFactorySetCustomFee.d.ts +17 -0
  116. package/dist/fhe-airdrop/react/useAirdropFactorySetDefaultGasFee.d.ts +16 -0
  117. package/dist/fhe-airdrop/react/useAirdropFactorySetFeeCollector.d.ts +15 -0
  118. package/dist/fhe-airdrop/react/useAirdropGasFee.d.ts +11 -0
  119. package/dist/fhe-airdrop/react/useAirdropGrantRole.d.ts +16 -0
  120. package/dist/fhe-airdrop/react/useAirdropHasClaimEnded.d.ts +7 -0
  121. package/dist/fhe-airdrop/react/useAirdropHasClaimStarted.d.ts +7 -0
  122. package/dist/fhe-airdrop/react/useAirdropHasRole.d.ts +14 -0
  123. package/dist/fhe-airdrop/react/useAirdropIsClaimWindowActive.d.ts +9 -0
  124. package/dist/fhe-airdrop/react/useAirdropIsPaused.d.ts +8 -0
  125. package/dist/fhe-airdrop/react/useAirdropIsSignatureClaimed.d.ts +22 -0
  126. package/dist/fhe-airdrop/react/useAirdropIsSignatureValid.d.ts +50 -0
  127. package/dist/fhe-airdrop/react/useAirdropRevokeRole.d.ts +15 -0
  128. package/dist/fhe-airdrop/react/useAirdropStartTime.d.ts +10 -0
  129. package/dist/fhe-airdrop/react/useAirdropToken.d.ts +11 -0
  130. package/dist/fhe-airdrop/react/useAirdropWithdrawGasFee.d.ts +15 -0
  131. package/dist/fhe-airdrop/react/useAirdropWithdrawOtherConfidentialToken.d.ts +14 -0
  132. package/dist/fhe-airdrop/react/useAirdropWithdrawOtherToken.d.ts +14 -0
  133. package/dist/fhe-airdrop/react/useClaim.d.ts +29 -0
  134. package/dist/fhe-airdrop/react/useConfidentialAirdropFactoryImplementation.d.ts +11 -0
  135. package/dist/fhe-airdrop/react/useCreateAndFundConfidentialAirdrop.d.ts +33 -0
  136. package/dist/fhe-airdrop/react/useCreateAndFundConfidentialAirdropAndGetAddress.d.ts +40 -0
  137. package/dist/fhe-airdrop/react/useCreateConfidentialAirdrop.d.ts +29 -0
  138. package/dist/fhe-airdrop/react/useCreateConfidentialAirdropAndGetAddress.d.ts +31 -0
  139. package/dist/fhe-airdrop/react/useDisableCustomFee.d.ts +14 -0
  140. package/dist/fhe-airdrop/react/useExtendClaimWindow.d.ts +16 -0
  141. package/dist/fhe-airdrop/react/useFactoryCustomFee.d.ts +17 -0
  142. package/dist/fhe-airdrop/react/useFactoryDefaultGasFee.d.ts +10 -0
  143. package/dist/fhe-airdrop/react/useFactoryFeeCollector.d.ts +11 -0
  144. package/dist/fhe-airdrop/react/useFactoryInitCodeHash.d.ts +17 -0
  145. package/dist/fhe-airdrop/react/useFundConfidentialAirdrop.d.ts +25 -0
  146. package/dist/fhe-airdrop/react/useGetClaimAmount.d.ts +30 -0
  147. package/dist/fhe-airdrop/react/useSetCustomFee.d.ts +16 -0
  148. package/dist/fhe-airdrop/react/useSetDefaultGasFee.d.ts +15 -0
  149. package/dist/fhe-airdrop/react/useSetFeeCollector.d.ts +14 -0
  150. package/dist/fhe-airdrop/react/useSetPaused.d.ts +14 -0
  151. package/dist/fhe-airdrop/react/useSignClaimAuthorization.d.ts +31 -0
  152. package/dist/fhe-airdrop/react/useWithdraw.d.ts +12 -0
  153. package/dist/fhe-airdrop/react/useWithdrawOtherConfidentialToken.d.ts +13 -0
  154. package/dist/fhe-airdrop/react/useWithdrawOtherToken.d.ts +13 -0
  155. package/dist/fhe-airdrop/types.d.ts +21 -0
  156. package/dist/fhe-disperse/abis/index.d.ts +2 -0
  157. package/dist/fhe-disperse/abis/singleton.d.ts +1297 -0
  158. package/dist/fhe-disperse/abis/wallet.d.ts +111 -0
  159. package/dist/fhe-disperse/encryption.d.ts +77 -0
  160. package/dist/fhe-disperse/errors.d.ts +39 -0
  161. package/dist/fhe-disperse/index.cjs +248 -0
  162. package/dist/fhe-disperse/index.d.cts +14 -0
  163. package/dist/fhe-disperse/index.d.ts +14 -0
  164. package/dist/fhe-disperse/index.js +11 -0
  165. package/dist/fhe-disperse/react/_shared.d.ts +104 -0
  166. package/dist/fhe-disperse/react/index.cjs +752 -0
  167. package/dist/fhe-disperse/react/index.d.cts +82 -0
  168. package/dist/fhe-disperse/react/index.d.ts +82 -0
  169. package/dist/fhe-disperse/react/index.js +522 -0
  170. package/dist/fhe-disperse/react/useAccessEncryptedFeeReserve.d.ts +35 -0
  171. package/dist/fhe-disperse/react/useApproveTokenOnWallets.d.ts +25 -0
  172. package/dist/fhe-disperse/react/useBatchDiscloseHandlesToParty.d.ts +16 -0
  173. package/dist/fhe-disperse/react/useCalculateFee.d.ts +26 -0
  174. package/dist/fhe-disperse/react/useDeploymentBlockNumber.d.ts +11 -0
  175. package/dist/fhe-disperse/react/useDisableCustomFee.d.ts +20 -0
  176. package/dist/fhe-disperse/react/useDiscloseHandleToParty.d.ts +20 -0
  177. package/dist/fhe-disperse/react/useDisperse.d.ts +28 -0
  178. package/dist/fhe-disperse/react/useGetBatchLimits.d.ts +12 -0
  179. package/dist/fhe-disperse/react/useGetFeeConfig.d.ts +15 -0
  180. package/dist/fhe-disperse/react/useGetFees.d.ts +19 -0
  181. package/dist/fhe-disperse/react/useGetWallets.d.ts +19 -0
  182. package/dist/fhe-disperse/react/useGrantRole.d.ts +24 -0
  183. package/dist/fhe-disperse/react/useHasApprovedSubwallets.d.ts +25 -0
  184. package/dist/fhe-disperse/react/useHasRole.d.ts +22 -0
  185. package/dist/fhe-disperse/react/useIsPaused.d.ts +11 -0
  186. package/dist/fhe-disperse/react/useIsRegistered.d.ts +15 -0
  187. package/dist/fhe-disperse/react/usePause.d.ts +18 -0
  188. package/dist/fhe-disperse/react/usePredictWallets.d.ts +19 -0
  189. package/dist/fhe-disperse/react/usePreflightDisperse.d.ts +37 -0
  190. package/dist/fhe-disperse/react/useRecoverERC20FromWallets.d.ts +21 -0
  191. package/dist/fhe-disperse/react/useRecoverFromWallets.d.ts +21 -0
  192. package/dist/fhe-disperse/react/useRegister.d.ts +40 -0
  193. package/dist/fhe-disperse/react/useRescueConfidentialTokens.d.ts +21 -0
  194. package/dist/fhe-disperse/react/useRescueERC20.d.ts +21 -0
  195. package/dist/fhe-disperse/react/useRevokeRole.d.ts +24 -0
  196. package/dist/fhe-disperse/react/useRevokeTokenOnWallets.d.ts +24 -0
  197. package/dist/fhe-disperse/react/useSetCustomFee.d.ts +24 -0
  198. package/dist/fhe-disperse/react/useSetFeeConfig.d.ts +23 -0
  199. package/dist/fhe-disperse/react/useSetMaxBatchSizeDirect.d.ts +20 -0
  200. package/dist/fhe-disperse/react/useSetMaxBatchSizeHolding.d.ts +20 -0
  201. package/dist/fhe-disperse/react/useSetMaxBatchSizeTokenFee.d.ts +20 -0
  202. package/dist/fhe-disperse/react/useSingletonBatchDiscloseHandlesToParty.d.ts +13 -0
  203. package/dist/fhe-disperse/react/useSingletonBatchLimits.d.ts +12 -0
  204. package/dist/fhe-disperse/react/useSingletonCalculateFee.d.ts +26 -0
  205. package/dist/fhe-disperse/react/useSingletonDeploymentBlockNumber.d.ts +11 -0
  206. package/dist/fhe-disperse/react/useSingletonDisableCustomFee.d.ts +21 -0
  207. package/dist/fhe-disperse/react/useSingletonDiscloseHandleToParty.d.ts +17 -0
  208. package/dist/fhe-disperse/react/useSingletonFees.d.ts +19 -0
  209. package/dist/fhe-disperse/react/useSingletonGrantRole.d.ts +26 -0
  210. package/dist/fhe-disperse/react/useSingletonHasApprovedSubwallets.d.ts +25 -0
  211. package/dist/fhe-disperse/react/useSingletonHasRole.d.ts +23 -0
  212. package/dist/fhe-disperse/react/useSingletonIsPaused.d.ts +11 -0
  213. package/dist/fhe-disperse/react/useSingletonIsRegistered.d.ts +15 -0
  214. package/dist/fhe-disperse/react/useSingletonPause.d.ts +19 -0
  215. package/dist/fhe-disperse/react/useSingletonPredictWallets.d.ts +19 -0
  216. package/dist/fhe-disperse/react/useSingletonRevokeRole.d.ts +26 -0
  217. package/dist/fhe-disperse/react/useSingletonSetCustomFee.d.ts +25 -0
  218. package/dist/fhe-disperse/react/useSingletonUnpause.d.ts +18 -0
  219. package/dist/fhe-disperse/react/useSingletonWalletImplementation.d.ts +12 -0
  220. package/dist/fhe-disperse/react/useSingletonWallets.d.ts +19 -0
  221. package/dist/fhe-disperse/react/useSingletonWithdrawGasFee.d.ts +21 -0
  222. package/dist/fhe-disperse/react/useSingletonWithdrawTokenFee.d.ts +50 -0
  223. package/dist/fhe-disperse/react/useUnpause.d.ts +17 -0
  224. package/dist/fhe-disperse/react/useWalletImplementation.d.ts +12 -0
  225. package/dist/fhe-disperse/react/useWithdrawGasFee.d.ts +26 -0
  226. package/dist/fhe-disperse/react/useWithdrawTokenFee.d.ts +70 -0
  227. package/dist/fhe-disperse/singleton.d.ts +442 -0
  228. package/dist/fhe-disperse/subtotals.d.ts +14 -0
  229. package/dist/fhe-disperse/types.d.ts +332 -0
  230. package/dist/fhe-disperse/validate.d.ts +78 -0
  231. package/dist/fhe-vesting/abis/factory.d.ts +676 -0
  232. package/dist/fhe-vesting/abis/index.d.ts +3 -0
  233. package/dist/fhe-vesting/abis/manager.d.ts +1797 -0
  234. package/dist/fhe-vesting/advanced/factory-advanced.d.ts +52 -0
  235. package/dist/fhe-vesting/advanced/index.cjs +21 -0
  236. package/dist/fhe-vesting/advanced/index.d.cts +12 -0
  237. package/dist/fhe-vesting/advanced/index.d.ts +12 -0
  238. package/dist/fhe-vesting/advanced/index.js +8 -0
  239. package/dist/fhe-vesting/advanced/react/index.cjs +75 -0
  240. package/dist/fhe-vesting/advanced/react/index.d.cts +5 -0
  241. package/dist/fhe-vesting/advanced/react/index.d.ts +5 -0
  242. package/dist/fhe-vesting/advanced/react/index.js +73 -0
  243. package/dist/fhe-vesting/advanced/react/usePredictManagerAddress.d.ts +41 -0
  244. package/dist/fhe-vesting/encryption.d.ts +104 -0
  245. package/dist/fhe-vesting/errors.d.ts +183 -0
  246. package/dist/fhe-vesting/factory.d.ts +207 -0
  247. package/dist/fhe-vesting/index.cjs +269 -0
  248. package/dist/fhe-vesting/index.d.cts +9 -0
  249. package/dist/fhe-vesting/index.d.ts +9 -0
  250. package/dist/fhe-vesting/index.js +12 -0
  251. package/dist/fhe-vesting/manager.d.ts +808 -0
  252. package/dist/fhe-vesting/react/_shared.d.ts +122 -0
  253. package/dist/fhe-vesting/react/index.cjs +1054 -0
  254. package/dist/fhe-vesting/react/index.d.cts +123 -0
  255. package/dist/fhe-vesting/react/index.d.ts +123 -0
  256. package/dist/fhe-vesting/react/index.js +771 -0
  257. package/dist/fhe-vesting/react/useAcceptVestingTransfer.d.ts +12 -0
  258. package/dist/fhe-vesting/react/useAccessClaimableAmount.d.ts +14 -0
  259. package/dist/fhe-vesting/react/useAccessSettledAmount.d.ts +15 -0
  260. package/dist/fhe-vesting/react/useAccessTotalAllocation.d.ts +14 -0
  261. package/dist/fhe-vesting/react/useAccessVestedAmount.d.ts +26 -0
  262. package/dist/fhe-vesting/react/useAdminBatchDiscloseToParty.d.ts +16 -0
  263. package/dist/fhe-vesting/react/useAdminClaim.d.ts +9 -0
  264. package/dist/fhe-vesting/react/useAdminDiscloseToParty.d.ts +8 -0
  265. package/dist/fhe-vesting/react/useAdminGetClaimableAmount.d.ts +13 -0
  266. package/dist/fhe-vesting/react/useAdminGetSettledAmount.d.ts +13 -0
  267. package/dist/fhe-vesting/react/useAdminGetTokenBalance.d.ts +13 -0
  268. package/dist/fhe-vesting/react/useAdminGetTotalAllocation.d.ts +13 -0
  269. package/dist/fhe-vesting/react/useAdminGetVestedAmount.d.ts +15 -0
  270. package/dist/fhe-vesting/react/useAdminPartialClaim.d.ts +8 -0
  271. package/dist/fhe-vesting/react/useAllRecipients.d.ts +8 -0
  272. package/dist/fhe-vesting/react/useAllRecipientsLength.d.ts +6 -0
  273. package/dist/fhe-vesting/react/useAllRecipientsSliced.d.ts +13 -0
  274. package/dist/fhe-vesting/react/useBatchCreateVesting.d.ts +24 -0
  275. package/dist/fhe-vesting/react/useBatchDiscloseHandlesToParty.d.ts +13 -0
  276. package/dist/fhe-vesting/react/useBatchDiscloseToParty.d.ts +18 -0
  277. package/dist/fhe-vesting/react/useBatchRevokeVesting.d.ts +12 -0
  278. package/dist/fhe-vesting/react/useCancelVestingTransfer.d.ts +12 -0
  279. package/dist/fhe-vesting/react/useClaim.d.ts +19 -0
  280. package/dist/fhe-vesting/react/useConfidentialVestingFactoryImplementation.d.ts +11 -0
  281. package/dist/fhe-vesting/react/useCreateManager.d.ts +32 -0
  282. package/dist/fhe-vesting/react/useCreateManagerAndGetAddress.d.ts +31 -0
  283. package/dist/fhe-vesting/react/useCreateVesting.d.ts +38 -0
  284. package/dist/fhe-vesting/react/useDirectVestingTransfer.d.ts +13 -0
  285. package/dist/fhe-vesting/react/useDisableCustomFee.d.ts +14 -0
  286. package/dist/fhe-vesting/react/useDiscloseHandleToParty.d.ts +14 -0
  287. package/dist/fhe-vesting/react/useDiscloseToParty.d.ts +14 -0
  288. package/dist/fhe-vesting/react/useFactoryCustomFee.d.ts +17 -0
  289. package/dist/fhe-vesting/react/useFactoryDefaultFeeType.d.ts +11 -0
  290. package/dist/fhe-vesting/react/useFactoryDefaultGasFee.d.ts +10 -0
  291. package/dist/fhe-vesting/react/useFactoryDefaultTokenFee.d.ts +10 -0
  292. package/dist/fhe-vesting/react/useFactoryFeeCollector.d.ts +10 -0
  293. package/dist/fhe-vesting/react/useFactoryInitCodeHash.d.ts +18 -0
  294. package/dist/fhe-vesting/react/useGetClaimableAmount.d.ts +13 -0
  295. package/dist/fhe-vesting/react/useGetSettledAmount.d.ts +14 -0
  296. package/dist/fhe-vesting/react/useGetTotalAllocation.d.ts +13 -0
  297. package/dist/fhe-vesting/react/useGetVestedAmount.d.ts +25 -0
  298. package/dist/fhe-vesting/react/useGrantRole.d.ts +15 -0
  299. package/dist/fhe-vesting/react/useHasRole.d.ts +14 -0
  300. package/dist/fhe-vesting/react/useInitiateVestingTransfer.d.ts +12 -0
  301. package/dist/fhe-vesting/react/useIsRecipient.d.ts +10 -0
  302. package/dist/fhe-vesting/react/useManagerBatchDiscloseHandlesToParty.d.ts +15 -0
  303. package/dist/fhe-vesting/react/useManagerDeploymentBlockNumber.d.ts +7 -0
  304. package/dist/fhe-vesting/react/useManagerDiscloseHandleToParty.d.ts +16 -0
  305. package/dist/fhe-vesting/react/useManagerFactoryCustomFee.d.ts +17 -0
  306. package/dist/fhe-vesting/react/useManagerFactoryDefaultGasFee.d.ts +10 -0
  307. package/dist/fhe-vesting/react/useManagerFactoryDisableCustomFee.d.ts +15 -0
  308. package/dist/fhe-vesting/react/useManagerFactoryFeeCollector.d.ts +10 -0
  309. package/dist/fhe-vesting/react/useManagerFactoryInitCodeHash.d.ts +18 -0
  310. package/dist/fhe-vesting/react/useManagerFactorySetCustomFee.d.ts +19 -0
  311. package/dist/fhe-vesting/react/useManagerFactorySetDefaultGasFee.d.ts +13 -0
  312. package/dist/fhe-vesting/react/useManagerFactorySetFeeCollector.d.ts +14 -0
  313. package/dist/fhe-vesting/react/useManagerFee.d.ts +7 -0
  314. package/dist/fhe-vesting/react/useManagerFeeInfo.d.ts +18 -0
  315. package/dist/fhe-vesting/react/useManagerFeeType.d.ts +7 -0
  316. package/dist/fhe-vesting/react/useManagerGrantRole.d.ts +17 -0
  317. package/dist/fhe-vesting/react/useManagerHasRole.d.ts +15 -0
  318. package/dist/fhe-vesting/react/useManagerIsPausable.d.ts +6 -0
  319. package/dist/fhe-vesting/react/useManagerIsSplitEnabled.d.ts +6 -0
  320. package/dist/fhe-vesting/react/useManagerMaxBatchSize.d.ts +6 -0
  321. package/dist/fhe-vesting/react/useManagerMaxRevokeBatchSize.d.ts +6 -0
  322. package/dist/fhe-vesting/react/useManagerPause.d.ts +13 -0
  323. package/dist/fhe-vesting/react/useManagerPaused.d.ts +6 -0
  324. package/dist/fhe-vesting/react/useManagerRevokeRole.d.ts +17 -0
  325. package/dist/fhe-vesting/react/useManagerToken.d.ts +11 -0
  326. package/dist/fhe-vesting/react/useManagerUnpause.d.ts +12 -0
  327. package/dist/fhe-vesting/react/useManagerWithdrawGasFee.d.ts +14 -0
  328. package/dist/fhe-vesting/react/useManagerWithdrawOtherConfidentialToken.d.ts +14 -0
  329. package/dist/fhe-vesting/react/useManagerWithdrawOtherToken.d.ts +14 -0
  330. package/dist/fhe-vesting/react/useManagerWithdrawTokenFee.d.ts +11 -0
  331. package/dist/fhe-vesting/react/usePartialClaim.d.ts +15 -0
  332. package/dist/fhe-vesting/react/usePause.d.ts +12 -0
  333. package/dist/fhe-vesting/react/usePendingVestingTransfer.d.ts +20 -0
  334. package/dist/fhe-vesting/react/useRecipientVestings.d.ts +11 -0
  335. package/dist/fhe-vesting/react/useRecipientVestingsLength.d.ts +10 -0
  336. package/dist/fhe-vesting/react/useRecipientVestingsSliced.d.ts +12 -0
  337. package/dist/fhe-vesting/react/useRenounceRole.d.ts +16 -0
  338. package/dist/fhe-vesting/react/useResetGasFee.d.ts +10 -0
  339. package/dist/fhe-vesting/react/useResetTokenFee.d.ts +10 -0
  340. package/dist/fhe-vesting/react/useRevokeRole.d.ts +15 -0
  341. package/dist/fhe-vesting/react/useRevokeVesting.d.ts +15 -0
  342. package/dist/fhe-vesting/react/useRoleConstants.d.ts +19 -0
  343. package/dist/fhe-vesting/react/useSetCustomFee.d.ts +18 -0
  344. package/dist/fhe-vesting/react/useSetDefaultFeeType.d.ts +14 -0
  345. package/dist/fhe-vesting/react/useSetDefaultGasFee.d.ts +12 -0
  346. package/dist/fhe-vesting/react/useSetDefaultTokenFee.d.ts +13 -0
  347. package/dist/fhe-vesting/react/useSetFeeCollector.d.ts +13 -0
  348. package/dist/fhe-vesting/react/useSetMaxBatchSize.d.ts +12 -0
  349. package/dist/fhe-vesting/react/useSetMaxRevokeBatchSize.d.ts +12 -0
  350. package/dist/fhe-vesting/react/useSplitVesting.d.ts +28 -0
  351. package/dist/fhe-vesting/react/useTransferFeeCollectorRole.d.ts +12 -0
  352. package/dist/fhe-vesting/react/useUnpause.d.ts +11 -0
  353. package/dist/fhe-vesting/react/useVestingClaim.d.ts +19 -0
  354. package/dist/fhe-vesting/react/useVestingInfo.d.ts +25 -0
  355. package/dist/fhe-vesting/react/useWithdrawAdmin.d.ts +17 -0
  356. package/dist/fhe-vesting/react/useWithdrawGasFee.d.ts +13 -0
  357. package/dist/fhe-vesting/react/useWithdrawOtherConfidentialToken.d.ts +13 -0
  358. package/dist/fhe-vesting/react/useWithdrawOtherToken.d.ts +13 -0
  359. package/dist/fhe-vesting/react/useWithdrawTokenFee.d.ts +18 -0
  360. package/dist/fhe-vesting/types.d.ts +72 -0
  361. package/dist/index.cjs +237 -0
  362. package/dist/index.d.cts +3 -0
  363. package/dist/index.d.ts +3 -0
  364. package/dist/index.js +14 -0
  365. package/dist/telemetry/console.d.ts +29 -0
  366. package/dist/telemetry/index.cjs +113 -0
  367. package/dist/telemetry/index.d.cts +3 -0
  368. package/dist/telemetry/index.d.ts +3 -0
  369. package/dist/telemetry/index.js +102 -0
  370. package/dist/telemetry/tokenops.d.ts +15 -0
  371. package/package.json +316 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,207 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@tokenops/sdk` will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.0.0] - 2026-05-27
9
+
10
+ ### Changed — factory create methods now block on receipt before returning
11
+
12
+ - **`ConfidentialVestingFactoryClient.createManager`, `ConfidentialAirdropFactoryClient.createConfidentialAirdrop`, and `ConfidentialAirdropFactoryClient.createAndFundConfidentialAirdrop` now block on `waitForTransactionReceipt` + `parseEventLogs` internally before resolving.** The returned `Create*Result` carries a fully-parsed `manager` / `airdrop` address when the promise resolves — callers no longer need a separate `waitForTransactionReceipt` + event-log scan after the call. Consumer-visible behavior change: if your code was doing `const { hash } = await createManager(...); const receipt = await waitForTransactionReceipt(hash)` you will now double-wait (harmless, but an extra round-trip). Drop the extra `waitForTransactionReceipt` call.
13
+ - **`createManagerAndGetAddress` and `createConfidentialAirdropAndGetAddress` are now passthroughs** — they no longer add a second wait step on top of the base creator. They remain exported as convenience aliases for consumers who discovered them first, but the base methods are the canonical entry point.
14
+
15
+ ### Changed — BREAKING (pre-1.0 publish)
16
+
17
+ The package has not been published to npm yet (`npm view @tokenops/sdk` returns 404), so the entries below land as direct shape changes rather than additive `*AndGetX` helpers.
18
+
19
+ - **`@tokenops/sdk/fhe-airdrop` — signed-claim payload no longer re-encrypts on the recipient side.** `ClaimArgs` and `GetClaimAmountArgs` now require `encryptedInput` and have NO `amount` / `encryptor` fields. The admin EIP-712 signature commits to a specific `bytes32` handle, so re-encrypting the same plaintext on the recipient side produced a divergent handle and the signature silently failed downstream — now it's structurally impossible. Migration: admins build `{ encryptedInput, signature }` with `encryptUint64({ ..., userAddress: recipient })` (input proofs MUST be bound to the recipient — `FHE.fromExternal` rejects any other binding) + `signClaimAuthorization`, and recipients submit the pair as-is via `claim({ encryptedInput, signature })` / `getClaimAmount({ encryptedInput, signature })`. `ConfidentialAirdropClientConfig.encryptor` is removed (the clone client never encrypts). `AirdropHookOptions.encryptor` removed from the clone hooks for the same reason — factory hooks still take it for `createAndFund` / `fund`.
20
+ - **`@tokenops/sdk/fhe-airdrop` — `isSignatureValid()` takes an args object with a required `caller`.** The contract's on-chain check binds to `msg.sender` (`_computeStructHash(msg.sender, inputAmount)` in `ConfidentialAirdropCloneable.sol`), so the result is caller-specific. Migration: `airdrop.isSignatureValid(handle, sig)` → `airdrop.isSignatureValid({ encryptedAmountHandle, signature, caller })`. The React hook `useAirdropIsSignatureValid` now also accepts `caller?: Address` (defaults to the connected wallet via `useAccount()`) and includes it in the TanStack Query key so cached results don't bleed across account switches.
21
+ - **`@tokenops/sdk/fhe-vesting` — disclose + split now return receipt-parsed handles, not just tx hashes.** `splitVesting()` returns `{ hash, newVestingId }` (parsed from `VestingSplit` event filtered by indexed `originalVestingId` + `newRecipient`). `discloseToParty()` and `adminDiscloseToParty()` return `{ hash, handle }` (parsed from `AmountDisclosed`, filtered by indexed `vestingId` + `discloser` + `party`). `batchDiscloseToParty()` and `adminBatchDiscloseToParty()` return `{ hash, handles }` where `handles[i]` corresponds to `vestingIds[i]`. Consumers can now pass these handles to `userDecrypt` / chain into further operations without an extra event-log scan. React hooks `useSplitVesting`, `useDiscloseToParty`, `useAdminDiscloseToParty`, `useBatchDiscloseToParty`, `useAdminBatchDiscloseToParty` mirror the new return shape. New exported types: `SplitVestingResult`, `DiscloseToPartyResult`, `BatchDiscloseToPartyResult`.
22
+
23
+ ### Changed — exactly-one-of(amount, encryptedInput)
24
+
25
+ - **All confidential-write args that previously required a plaintext `amount` while also accepting `encryptedInput` now enforce mutual exclusivity at runtime.** `amount` is optional; pre-encrypted callers can omit it entirely. Passing both throws `InvalidArgumentError` with `context.argument = "amount/encryptedInput"` and a "got both" / "got neither" reason — the SDK refuses to silently pick a side, which previously let plaintext metadata drift from the on-chain ciphertext. Applies to `ConfidentialVestingManagerClient.{createVesting, partialClaim, adminPartialClaim, withdrawAdmin, withdrawTokenFee}`, `ConfidentialAirdropFactoryClient.{createAndFundConfidentialAirdrop, fundConfidentialAirdrop}`, and `ConfidentialDisperseClient.withdrawTokenFee`.
26
+
27
+ ### Added — disperse shared validation
28
+
29
+ - **`ConfidentialDisperseClient.disperse()` now validates inputs deterministically BEFORE encryption.** Length match, zero-address recipients, per-amount uint64 bounds, wallet-mode subtotal overflow, and the mode-specific batch limit (read via `getBatchLimits()` once) are all enforced via the same `validateDisperseInputs` helper `preflightDisperse()` uses — an oversized or malformed batch no longer spends client-side FHE encryption time only to revert on-chain. Throws the first matching typed error (`BatchTooLargeError` / `InvalidArgumentError`).
30
+ - **`preflightDisperse()` for unregistered wallet-mode users no longer surfaces phantom subwallet-approval blockers.** Predicted-wallet ERC-7984 operator reads stay in `hasApprovedSubwallets` for informational pre-warn UIs, but they're not added to `blockers` / `blockerErrors` until the user has actually registered (predicted wallets don't exist on-chain yet — the user cannot approve from them). Registration remains the single typed blocker for that state.
31
+ - **`usePreflightDisperse()` no longer suppresses the SDK's own empty-input blockers.** The query enables once `recipients` and `amounts` are defined (even when empty), so UIs see the headless `InvalidArgumentError` blockers instead of an idle query.
32
+
33
+ ### Added — vesting React hook typing
34
+
35
+ - `ManagerHookOptions` now exports `chainId?: number` (previously only on the internal intersection type). Multi-chain React apps can pass `chainId` to manager hooks without TypeScript excess-property errors.
36
+
37
+ ### Fixed — docs sweep
38
+
39
+ - `docs/fhe-airdrop/README.md`: removed stale "until Sepolia factory is live" comments — the Sepolia factory entry in `DEPLOYED_ADDRESSES.fheAirdrop.confidentialAirdropFactory[sepolia.id]` is populated.
40
+ - `docs/fhe-vesting.md`: tightened the "omit on Sepolia or Mainnet" claim to reflect that `DEPLOYED_ADDRESSES.fheVesting.confidentialVestingFactory[mainnet.id] === null` (Sepolia auto-resolves; mainnet still requires explicit `address`). Fixed `useQueryClient` import: was `from "wagmi"`, corrected to `from "@tanstack/react-query"`.
41
+ - `src/fhe-disperse/singleton.ts` TSDoc example: dropped the "required until an address lands in `DEPLOYED_ADDRESSES`" note — mainnet + Sepolia singletons are live.
42
+ - TSDoc `encryptor` hints across `src/fhe-{airdrop,vesting,disperse}/react/_shared.ts`: replaced the misleading shorthand `() => useZamaSDK().relayer` (which calls a hook inside a callback — a rules-of-hooks violation if anyone copies it verbatim) with the safe two-line pattern. The runtime hint on `MissingEncryptorError` is updated to match.
43
+
44
+ ### Added — Error palette expansion
45
+
46
+ - **New typed error subclasses, all non-breaking.** The SDK now translates every on-chain revert and every `@zama-fhe/sdk` failure into a stable typed `TokenOpsSdkError` with a discriminated `code` and structured `context`. Consumers branch on `error.code` in `onError`; the new subclasses also work with `instanceof`. The existing `TOKENOPS_*` codes keep their meaning — only additions are below.
47
+ - **Cross-product** (`@tokenops/sdk/core/errors`, re-exported from `/fhe`, `/fhe-vesting`, `/fhe-airdrop`, `/fhe-disperse` and each `/react/`): `ContractRevertError` (`TOKENOPS_CONTRACT_REVERT`, the catch-all when the SDK decodes a revert but has no more-specific typed subclass), `PausedError` (`TOKENOPS_PAUSED`), `AccessDeniedError` (`TOKENOPS_ACCESS_DENIED`, with `context.role` + `context.account` from OZ `AccessControlUnauthorizedAccount`), `InsufficientFeeError` (`TOKENOPS_INSUFFICIENT_FEE`, narrowed by `feeKind: "gas" | "token"`), `InsufficientBalanceError` (`TOKENOPS_INSUFFICIENT_BALANCE`, narrowed by `balanceKind: "eth" | "erc20" | "confidential"` — confidential balances never echo plaintext into `context`), `BatchTooLargeError` (`TOKENOPS_BATCH_TOO_LARGE`), `FeatureDisabledError` (`TOKENOPS_FEATURE_DISABLED`, with `context.feature: "split" | "pause" | "extendClaimWindow"`), `TransferFailedError` (`TOKENOPS_TRANSFER_FAILED`), `FheHandleNotAllowedError` (`TOKENOPS_FHE_HANDLE_NOT_ALLOWED`, for on-chain `FHE.isSenderAllowed` failures — distinct from the Zama relayer's user-decrypt ACL refusal below), `AlreadyInitializedError` (`TOKENOPS_ALREADY_INITIALIZED`), `ReentrancyError` (`TOKENOPS_REENTRANCY`), `InvalidSignatureError` (`TOKENOPS_INVALID_SIGNATURE`).
48
+ - **Zama-SDK wrappers** (same import surface): `UserRejectedSignatureError` (`TOKENOPS_USER_REJECTED` — user cancelled a wallet sig prompt), `SigningFailedError` (`TOKENOPS_SIGNING_FAILED`), `RelayerUnreachableError` (`TOKENOPS_RELAYER_UNREACHABLE`, with `context.statusCode?` when the underlying HTTP error exposed it), `EncryptionFailedError` (`TOKENOPS_ENCRYPTION_FAILED`), `DecryptionFailedError` (`TOKENOPS_DECRYPTION_FAILED`), `UserDecryptNotAllowedError` (`TOKENOPS_USER_DECRYPT_NOT_ALLOWED`). The SDK no longer bubbles raw `ZamaError`s out of `encryptUint64` / `encryptUint64Batch` / the manager and airdrop encrypted-view helpers; original Zama errors stay accessible via `error.cause`.
49
+ - **`@tokenops/sdk/fhe-vesting`**: `VestingNotFoundError` (`TOKENOPS_VESTING_NOT_FOUND`), `NotVestingRecipientError` (`TOKENOPS_NOT_RECIPIENT`), `ClaimLockedError` (`TOKENOPS_CLAIM_LOCKED`, with `context.unlocksAt` for countdown UIs), `VestingRevokedError` (`TOKENOPS_VESTING_REVOKED`), `VestingNotRevocableError` (`TOKENOPS_NOT_REVOCABLE`), `VestingExpiredError` (`TOKENOPS_VESTING_EXPIRED`), `TransferAlreadyPendingError` (`TOKENOPS_TRANSFER_ALREADY_PENDING`), `NoPendingTransferError` (`TOKENOPS_NO_PENDING_TRANSFER`), `NotPendingRecipientError` (`TOKENOPS_NOT_PENDING_RECIPIENT`), `TransferExpiredError` (`TOKENOPS_TRANSFER_EXPIRED`).
50
+ - **`@tokenops/sdk/fhe-airdrop`**: `AlreadyClaimedError` (`TOKENOPS_ALREADY_CLAIMED`), `ClaimNotStartedError` (`TOKENOPS_CLAIM_NOT_STARTED`, with `context.startsAt`), `ClaimWindowClosedError` (`TOKENOPS_CLAIM_WINDOW_CLOSED`, with `context.endedAt`).
51
+ - **`@tokenops/sdk/fhe-disperse`**: `NotRegisteredError` (`TOKENOPS_NOT_REGISTERED`), `AlreadyRegisteredError` (`TOKENOPS_ALREADY_REGISTERED`). The existing `DisperseSubwalletNotFoundError` and `DisperseEncryptedReserveNotGrantedError` stay, sharing the existing `TOKENOPS_RECEIPT_EVENT_NOT_FOUND` code.
52
+
53
+ ### Added — Preflight (opt-in)
54
+
55
+ - `ConfidentialVestingManagerClient.preflightClaim({ vestingId, caller })` and `ConfidentialAirdropClient.preflightClaim({ caller, encryptedAmountHandle })` run the deterministic-from-off-chain checks in parallel (recipient match, timelock elapsed, pause state, signature-already-claimed, window state) and return `{ ready: boolean; blockers: TokenOpsSdkError[] }`. The blockers are the same typed errors the write path would throw — same `code`, same `context`, just collected instead of thrown. Preflight is opt-in; consumers who have already validated state call `claim` directly.
56
+ - New shared type `PreflightResult` exported from each product subpath. The existing `ConfidentialDisperseClient.preflightDisperse` keeps returning its product-specific `PreflightReport` shape (back-compat) — typed errors are surfaced in `blockers` via the same revert-mapping infrastructure when the user proceeds to the write.
57
+
58
+ ### Added — Revert mapping infrastructure
59
+
60
+ - `mapContractRevert(error, { method, contractAddress, abi, productMapper?, productContext?, account? })` (from `@tokenops/sdk` via `core/revert-mapper.js`). Walks viem's `BaseError` chain, decodes the revert against the supplied ABI, dispatches through the optional product mapper, falls back to the cross-product default mapper, and finally to `ContractRevertError` when no typed subclass applies. Original viem error is preserved as `error.cause`. Per-product mappers (`vestingProductMapper`, `airdropProductMapper`, `disperseProductMapper`) consume `productContext` (e.g. `{ vestingId }`) supplied by the call site so the typed error carries product-specific UI fields without re-reading the chain.
61
+ - `mapZamaError(error, { method, operation })` translates `@zama-fhe/sdk` v3 / `@fhevm/mock-utils` errors. Code-based mapping for `SIGNING_REJECTED` / `SIGNING_FAILED` / `RELAYER_REQUEST_FAILED` / `ENCRYPTION_FAILED` / `DECRYPTION_FAILED` / `CONFIGURATION`; message-based fallback for the mock-utils plain-`Error` cases ("invalid unsigned integer value", "exceeds the maximum allowed value", "fhevm assertion failed", etc.). Operation-based default (`encrypt` → `EncryptionFailedError`, `*-decrypt` → `DecryptionFailedError`).
62
+
63
+ ### Added — Input validation
64
+
65
+ - `ConfidentialVestingManagerClient.createVesting` and `.batchCreateVesting` now run an SDK-side `#validateVestingParams` check that mirrors the contract's `_validateVestingParams` invariants — `recipient !== 0`, `startTimestamp < endTimestamp`, `startTimestamp + cliffSeconds ≤ endTimestamp`, `initialUnlockBps + cliffAmountBps ≤ 10000`. Throws `InvalidArgumentError` with the offending field name in `context.argument` before the tx is submitted.
66
+ - `.splitVesting`, `.initiateVestingTransfer`, `.directVestingTransfer`, `.withdrawTokenFee` now reject zero-address recipients / zero or negative durations / sub-`10000` split denominators upfront, again as `InvalidArgumentError`.
67
+
68
+ ### Changed
69
+
70
+ - `@tokenops/sdk` (and every subpath): every `writeContract` and FHE-encryption call in `ConfidentialVestingManagerClient`, `ConfidentialAirdropClient`, and `ConfidentialDisperseClient` is now wrapped in the revert mapper / Zama mapper. Consumers that previously matched on viem's `ContractFunctionExecutionError` or on `ZamaError.code` should migrate to `isTokenOpsSdkError` + the new typed `code` literals. Existing `TOKENOPS_*` codes are unchanged.
71
+
72
+ - Docs: `docs/fhe-disperse/README.md`, `docs/fhe-disperse/examples/register.ts`, `docs/fhe-airdrop/README.md`, `docs/fhe-vesting.md` updated to reflect (a) the disperse singleton being live on mainnet + Sepolia and the airdrop factory live on Sepolia — no more `address:` override guidance for those happy paths; (b) the post-Fix-#3 error shape (`DeploymentAddressUnavailableError` with `code: "TOKENOPS_DEPLOYMENT_ADDRESS_UNAVAILABLE"` and structured `context.{clientLabel,chainId,reason,overrideName}`) replacing prior verbatim quotes of an older `TokenOpsSdkError` message template.
73
+ - `ConfidentialVestingManagerClient`, `ConfidentialAirdropClient`, `ConfidentialDisperseClient` constructors now uniformly throw `DeploymentAddressUnavailableError` (`code: "TOKENOPS_DEPLOYMENT_ADDRESS_UNAVAILABLE"`, `context.product: "fhevm"`, `context.contract: "acl"`, `context.overrideName: "aclAddress"`) when no ACL address can be resolved — previously vesting silently `console.warn`'d and deferred the throw, while airdrop and disperse threw `InvalidArgumentError`. **Behavioural change for vesting:** constructing a `ConfidentialVestingManagerClient` on a chain the SDK doesn't recognise (i.e. anything other than mainnet, Sepolia, or local FHEVM 31337) now throws at construction rather than at the first encrypted-view call — pass `aclAddress` explicitly if you need to use the client on an unrecognised chain. The library-level `console.warn` is removed. `ConfidentialVestingManagerClient.aclAddress` is now `Address` (no longer `Address | undefined`).
74
+
75
+ ### Added
76
+
77
+ - `@tokenops/sdk/fhe`: re-exports the same typed-error palette already published by `/fhe-vesting`, `/fhe-airdrop`, and `/fhe-disperse` — `TokenOpsSdkError`, `isTokenOpsSdkError`, `DeploymentAddressUnavailableError`, `InvalidArgumentError`, `MissingAccountError`, `MissingClientError`, `MissingEncryptorError`, `MissingPublicClientError`, `MissingWalletClientError`, `ReceiptEventAmbiguousError`, `ReceiptEventNotFoundError`, `UnsupportedChainError`, `DeploymentAddressUnavailableReason`, `TokenOpsSdkErrorCode`. Consumers no longer reach into `@tokenops/sdk`'s internal `/core/errors` path for any subpath.
78
+ - `@tokenops/sdk/fhe`: typed accessors for the FHEVM ACL contract registry — `getFhevmAclAddress(chainId): Address | undefined` and `requireFhevmAclAddress(chainId, clientLabel): Address`. Mirror the `get*Address` / `require*Address` shape from `core/addresses.ts`. The `require` variant throws `DeploymentAddressUnavailableError` (`code: "TOKENOPS_DEPLOYMENT_ADDRESS_UNAVAILABLE"`) with `context.product = "fhevm"`, `context.contract = "acl"`, `context.overrideName = "aclAddress"`. `FHEVM_ACL_ADDRESS_BY_CHAIN` stays exported (now typed `as const satisfies Partial<Record<number, Address>>`) for power users who want raw registry access. Internal call sites in `fhe-vesting`, `fhe-airdrop`, and `fhe-disperse` migrated to `getFhevmAclAddress`.
79
+ - `@tokenops/sdk` `DeploymentAddressUnavailableError`: new optional `overrideName` field on the constructor args and `context` payload. When set, the rendered error message points users at the named knob (e.g. `"pass \`aclAddress\` explicitly"`) instead of the default `"address"`. Backward-compatible — omitting the field preserves prior message wording.
80
+
81
+ ### Fixed
82
+
83
+ - `@tokenops/sdk/fhe`: `EncryptedInput64` previously declared `{ handle, proof }`, which did not match any product API (all three subpaths use `inputProof`) or the on-chain calldata layout (`bytes inputProof`). The shape was unreachable for any working consumer. Replaced with canonical shared types — `EncryptedInput` / `EncryptedInputs` / `EncryptedViewResult` — re-exported from each product subpath so existing import paths continue to work. `EncryptedInput64`, `EncryptedHandle`, and `ExternalInputProof` remain exported as `@deprecated` aliases (`EncryptedInput64` now aliases the corrected shape) and will be removed in the next major.
84
+
85
+ ### Changed
86
+
87
+ - `@tokenops/sdk/fhe-vesting`, `/fhe-airdrop`, `/fhe-disperse`: each product's `EncryptedInput`, `EncryptedInputs`, and `EncryptedViewResult` are now re-exports of the canonical types from `@tokenops/sdk/fhe`. No consumer-visible shape change — same field names, same `Hex` values.
88
+
89
+ ### Removed
90
+
91
+ - **BREAKING:** dropped non-FHE product subpaths and their React hooks: `@tokenops/sdk/vesting`, `@tokenops/sdk/vesting/react`, `@tokenops/sdk/airdrops`, `@tokenops/sdk/airdrops/react`, `@tokenops/sdk/disperse`, `@tokenops/sdk/disperse/react`, `@tokenops/sdk/staking`, `@tokenops/sdk/staking/react`. The SDK now ships only the FHEVM-targeted subpaths (`/fhe`, `/fhe-vesting`, `/fhe-airdrop`, `/fhe-disperse`, plus their `/react` siblings). `DEPLOYED_ADDRESSES`, the test rig, docs, and examples are pruned to match. Consumers needing the non-FHE wrappers should pin to a 1.x release.
92
+
93
+ ### Added (pre-prune, historical entries below)
94
+
95
+ - `@tokenops/sdk/staking/react`: wagmi + TanStack Query hook surface covering all three staking variants (single-token, dual-token, unbonding) and their factories. 186 hooks total — see `docs/staking/README.md` for the full coverage table.
96
+ - `@tokenops/sdk/disperse/react` subpath: wagmi + TanStack Query hooks for `DisperseFactoryClient`, `DisperseGasFeeClient`, and `DisperseTokenFeeClient` — 44 hooks total covering reads, preflights, and mutations. **Factory reads** (4): `useDisperseFactoryFeeConfig`, `useDisperseFactoryCustomFee`, `useDisperseFactoryBasisPoints`, `useDisperseFactoryOwner`. **Factory mutations** (11): `useCreateGasFeeDisperse`, `useCreateTokenFeeDisperse` (both return `{ hash, disperse: Address }` parsed from the factory's `*Created` event), `useDisperseFactorySetFeeCollector`, `useDisperseFactorySetDefaultGasFee`, `useDisperseFactorySetDefaultTokenFee`, `useDisperseFactorySetDefaultFeeType`, `useDisperseFactoryResetGasFee`, `useDisperseFactoryResetTokenFee`, `useDisperseFactorySetCustomFee`, `useDisperseFactoryDisableCustomFee`, `useDisperseFactoryTransferOwnership`. **Gas-fee clone reads** (5): `useDisperseGasFeeFee`, `useDisperseGasFeeFeeType`, `useDisperseGasFeeDeploymentBlockNumber`, `useDisperseGasFeeFeeCollector`, `useDisperseGasFeeOwner`. **Gas-fee clone preflights** (3): `useDisperseGasFeePreflightDisperseEther`, `useDisperseGasFeePreflightDisperseEtherDeducted`, `useDisperseGasFeePreflightDisperseToken`. **Gas-fee clone mutations** (7): `useDisperseGasFeeDisperseEther`, `useDisperseGasFeeDisperseEtherDeductedFee`, `useDisperseGasFeeDisperseToken`, `useDisperseGasFeeDisperseTokenSimple`, `useDisperseGasFeeWithdrawERC20`, `useDisperseGasFeeWithdrawGasFee`, `useDisperseGasFeeTransferFeeCollectorRole`. **Token-fee clone reads** (7): `useDisperseTokenFeeFee`, `useDisperseTokenFeeBasisPoints`, `useDisperseTokenFeeFeeType`, `useDisperseTokenFeeDeploymentBlockNumber`, `useDisperseTokenFeeFeeCollector`, `useDisperseTokenFeeOwner`, `useDisperseTokenFeeTokenToFeeReserved`. **Token-fee clone preflights** (2): `useDisperseTokenFeePreflightDisperseToken`, `useDisperseTokenFeePreflightDisperseTokenDeducted`. **Token-fee clone mutations** (5): `useDisperseTokenFeeDisperseToken`, `useDisperseTokenFeeDisperseTokenDeductedFee`, `useDisperseTokenFeeWithdrawERC20`, `useDisperseTokenFeeWithdrawTokenFee`, `useDisperseTokenFeeTransferFeeCollectorRole`. No FHE peers required. Factory address resolves automatically from `DEPLOYED_ADDRESSES.disperse.disperseFactory` on mainnet and Sepolia — no `address:` override needed for those chains. `DisperseFactoryNotConfiguredError`, `DisperseNotDeployedError`, `InvalidDisperseEntriesError`, `TokenOpsSdkError`, codec helpers `decodeFeeType`/`encodeFeeType`, and all arg/result types re-exported from `@tokenops/sdk/disperse/react`. Query-key shape: `["tokenops-sdk", "disperse", "<methodName>", chainId, address?.toLowerCase(), ...primitiveArgs]` with bigints stringified to base-10 and hex strings lowercased. `docs/disperse/README.md` — placeholder `## React` section replaced with full `## React hooks` section: hook catalogue grouped by family (factory / gas-fee clone / token-fee clone), factory-create-to-disperse end-to-end quickstart (`useCreateGasFeeDisperse` + `useDisperseGasFeePreflightDisperseEther` + `useDisperseGasFeeDisperseEther`), token-fee allowance-gating quickstart (`useDisperseTokenFeePreflightDisperseToken` guards approve vs disperse path), and recommended invalidation table with query-key reference. Root README — new `## Quickstart — bulk payouts (with React hooks)` section showing `useCreateGasFeeDisperse` + `useDisperseGasFeePreflightDisperseEther` + `useDisperseGasFeeDisperseEther` in a single component.
97
+ - `@tokenops/sdk/airdrops/react` subpath: wagmi + TanStack Query hooks for both non-FHE airdrop variants — 66 hooks covering factory + ERC20 distributor + native distributor surfaces. Grouped by family — **factory reads** (4): `useMerkleDistributorFactoryFeeConfig`, `useMerkleDistributorFactoryCustomFee`, `useMerkleDistributorFactoryBasisPoints`, `useMerkleDistributorFactoryOwner`; **factory writes** (11): `useCreateTokenDistributor`, `useCreateNativeDistributor` (both return `{ hash, distributor }` parsed from the factory's `*Created` event), `useMerkleDistributorFactorySetFeeCollector`, `useMerkleDistributorFactorySetDefaultGasFee`, `useMerkleDistributorFactorySetDefaultTokenFee`, `useMerkleDistributorFactorySetDefaultFeeType`, `useMerkleDistributorFactoryResetGasFee`, `useMerkleDistributorFactoryResetTokenFee`, `useMerkleDistributorFactorySetCustomFee`, `useMerkleDistributorFactoryDisableCustomFee`, `useMerkleDistributorFactoryTransferOwnership`; **ERC20 distributor immutable reads** (10): `useMerkleDistributorToken`, `useMerkleDistributorStaking`, `useMerkleDistributorRewardOwner`, `useMerkleDistributorBonusPercentageBps`, `useMerkleDistributorDeploymentBlockNumber`, `useMerkleDistributorMerkleRoot`, `useMerkleDistributorStartTime`, `useMerkleDistributorFeeType`, `useMerkleDistributorFee`, `useMerkleDistributorStakingGasFee`; **ERC20 distributor state reads** (11): `useMerkleDistributorEndTime`, `useMerkleDistributorIsClaimed`, `useMerkleDistributorFirstClaimTime`, `useMerkleDistributorHasExpired`, `useMerkleDistributorGracePeriodStatus`, `useMerkleDistributorGracePeriodRemainingTime`, `useMerkleDistributorNumTokenReservedForFee`, `useMerkleDistributorHasRole`, `useMerkleDistributorDefaultAdminRole`, `useMerkleDistributorFeeCollectorRole`, `useMerkleDistributorClaimerRole`; **ERC20 distributor preflight** (1): `useMerkleDistributorPreflightClaim` — returns `ClaimPreflightReport` with `ready`, `blockers`, `proofValid`, `alreadyClaimed`, `windowOpen`, `hasFunds`, `ethValueForClaim`, `feeType`; **ERC20 distributor writes** (8): `useMerkleDistributorClaim`, `useMerkleDistributorClaimAndStake`, `useMerkleDistributorWithdraw`, `useMerkleDistributorWithdrawOtherToken`, `useMerkleDistributorWithdrawTokenFee`, `useMerkleDistributorWithdrawGasFee`, `useMerkleDistributorGrantRole`, `useMerkleDistributorRevokeRole`; **native distributor immutable reads** (5): `useMerkleDistributorNativeTotalAmountWei`, `useMerkleDistributorNativeDeploymentBlockNumber`, `useMerkleDistributorNativeMerkleRoot`, `useMerkleDistributorNativeStartTime`, `useMerkleDistributorNativeFee`; **native distributor state reads** (10): `useMerkleDistributorNativeEndTime`, `useMerkleDistributorNativeIsClaimed`, `useMerkleDistributorNativeFirstClaimTime`, `useMerkleDistributorNativeHasExpired`, `useMerkleDistributorNativeGracePeriodStatus`, `useMerkleDistributorNativeGracePeriodRemainingTime`, `useMerkleDistributorNativeNumNativeReservedForFee`, `useMerkleDistributorNativeHasRole`, `useMerkleDistributorNativeDefaultAdminRole`, `useMerkleDistributorNativeFeeCollectorRole`; **native distributor preflight** (1): `useMerkleDistributorNativePreflightClaim`; **native distributor writes** (5): `useMerkleDistributorNativeClaim`, `useMerkleDistributorNativeWithdraw`, `useMerkleDistributorNativeWithdrawGasFee`, `useMerkleDistributorNativeGrantRole`, `useMerkleDistributorNativeRevokeRole`. No FHE peers required — plain ERC20 and ETH contracts. The native variant's `feeType()` always returns `"gas"` synchronously; no hook is shipped for it — read it as a constant. Address-override forwarding: factory hooks accept `{ address?, chainId? }` matching `BaseHookOptions`; distributor hooks accept `DistributorHookOptions` where `address` is required. Factory address slot (`DEPLOYED_ADDRESSES.airdrops.merkleDistributorFactory`) is currently `null` on every chain — pass `address` explicitly until the deployment lands; both `AirdropFactoryNotConfiguredError` and `MerkleDistributorNotDeployedError` are re-exported from `@tokenops/sdk/airdrops/react`. Query-key shape: `["tokenops-sdk", "airdrops", "<methodName>", chainId, address?.toLowerCase(), ...primitiveArgs]` with bigints stringified to base-10 and hex strings lowercased. Pure functions `buildMerkleTree`, `hashLeaf`, `verifyMerkleProof` re-exported alongside all types (`AccountOverride`, `AirdropFeeType`, `AllocationEntry`, `ClaimArgs`, `ClaimPreflightReport`, `CreateDistributorResult`, `CreateNativeDistributorParams`, `CreateTokenDistributorParams`, `FactoryCustomFee`, `FactoryFeeConfig`, `MerkleClaim`, `MerkleTree`), codec helpers `decodeFeeType`, `encodeFeeType`, and `TokenOpsSdkError`. `docs/airdrops/README.md` — placeholder `## React` section replaced with full `## React hooks` section: hook catalogue grouped by family (factory / ERC20 distributor / native distributor), recipient claim quickstart (`useMerkleDistributorPreflightClaim` + `useMerkleDistributorClaim`), creator flow quickstart (`useCreateTokenDistributor` + `buildMerkleTree` + token-seed note), address-override guide, mutation invalidation pattern with query-key reference, and preflight polling setup. Root README — new `## Quickstart — token airdrop (with React hooks)` section showing `useCreateTokenDistributor` + `buildMerkleTree` creator flow and `useMerkleDistributorPreflightClaim` + `useMerkleDistributorClaim` recipient flow in two adjacent components.
98
+ - `@tokenops/sdk/vesting/react` subpath: wagmi + TanStack Query hooks for all four vesting variants (token, native, votes, milestone) — 203 hooks covering factory + manager + preflight surfaces. Hook families per variant: **factory reads** (fee config, custom fee, vault implementation for votes); **factory writes** (create manager, set/reset fee config, set fee collector, set/disable custom fee); **manager reads** (token, fee type/mode, funding type, deployment block, fee collector, reserved-token accounting, admin/recipient membership, vesting/milestone info, claimable/vested amounts, funding info, recipient listings, pending transfer); **manager preflight** (`useTokenVestingManagerPreflightClaim`, `useNativeVestingManagerPreflightClaim`, `useVotesVestingManagerPreflightClaim`, `useMilestoneVestingManagerPreflightStepClaim` — each returns a `ClaimPreflightReport` or `MilestoneStepPreflightReport` with `ready`, `blockers`, `claimable`, `ethValueForClaim`, and supporting fields); **manager writes** (create/fund/revoke vesting, claim, admin claim, batch variants, 2-step transfer, fee-collector withdrawal, admin withdrawal, set admin). Votes variant adds `useVotesVestingManagerVaultFor`, `useVotesVestingManagerDelegate`, `useVotesVestingManagerDelegateBatch`. Milestone variant replaces linear-vesting surface with `useCreate/ApproveMilestoneStep`, `useFundMilestoneStep/Batch`, `useRevokeMilestone/Step`, and `useClaim({ milestoneId, stepIndex })`. Non-FHE subpath — no encryptor wiring, no `@zama-fhe/react-sdk` dependency. Address-override forwarding: factory hooks accept `{ address?, chainId? }` matching `BaseHookOptions`; manager hooks accept `ManagerHookOptions` where `address` is required. All four factory address slots (`tokenVestingFactory`, `nativeVestingFactory`, `votesVestingFactory`, `milestoneVestingFactory`) are currently `null` in `DEPLOYED_ADDRESSES.vesting` — pass `address` explicitly until deployments land. Both `VestingFactoryNotConfiguredError` and `VestingManagerNotDeployedError` re-exported from `@tokenops/sdk/vesting/react`. Query-key shape: `["tokenops-sdk", "vesting", "<variant>", "<methodName>", chainId, address?.toLowerCase(), ...primitiveArgs]`. Utility types and codec helpers (`decodeFeeType`, `encodeFeeType`, `decodeFundingType`, `encodeFundingType`, `ClaimPreflightReport`, `CreateManagerResult`, `CreateVestingParams`, `VestingInfo`, `MilestoneInfo`, `MilestoneStepInfo`, `MilestoneStepPreflightReport`, `VestingFeeType`, `VestingFundingType`, `FactoryFeeConfig`, `FactoryCustomFee`, `FundingInfo`, `ApproveMilestoneStepParams`, `VestingVariant`, `BaseHookOptions`, `ManagerHookOptions`, `NativeManagerHookOptions`, `TokenOpsSdkError`) re-exported from the same path. `docs/vesting/README.md` — new `## React hooks` section with hook catalogue table grouped by variant and family, per-variant quickstarts (token / native / votes / milestone), address-override guide, mutation invalidation pattern with query-key reference, and preflight polling setup. Root README — new `## Quickstart — token vesting (with React hooks)` section showing `useCreateTokenVestingManager` + `useTokenVestingManagerPreflightClaim` + `useTokenVestingManagerClaim` in two adjacent components. See `docs/vesting/README.md#react-hooks`.
99
+ - `@tokenops/sdk/fhe-vesting/react` subpath: 80 React/wagmi hooks wrapping every public method of `ConfidentialVestingFactoryClient` and `ConfidentialVestingManagerClient`. Grouped by family — **factory reads** (8): `useConfidentialVestingFactoryImplementation`, `useFactoryDefaultGasFee`, `useFactoryDefaultTokenFee`, `useFactoryDefaultFeeType`, `useFactoryFeeCollector`, `useFactoryCustomFee`, `usePredictManagerAddress`, `useFactoryInitCodeHash`; **factory writes** (10): `useCreateManager`, `useCreateManagerAndGetAddress`, `useSetDefaultGasFee`, `useSetDefaultTokenFee`, `useSetDefaultFeeType`, `useResetGasFee`, `useResetTokenFee`, `useSetCustomFee`, `useDisableCustomFee`, `useSetFeeCollector`; **manager reads** (21): `useManagerToken`, `useManagerFeeType`, `useManagerFee`, `useManagerFeeInfo`, `useManagerDeploymentBlockNumber`, `useManagerIsSplitEnabled`, `useManagerIsPausable`, `useManagerPaused`, `useManagerMaxBatchSize`, `useManagerMaxRevokeBatchSize`, `useVestingInfo`, `useAllRecipients`, `useAllRecipientsLength`, `useAllRecipientsSliced`, `useIsRecipient`, `useRecipientVestings`, `useRecipientVestingsLength`, `useRecipientVestingsSliced`, `usePendingVestingTransfer`, `useHasRole`, `useRoleConstants`; **manager encrypted views** (9, all `useMutation` — submit a tx, extract the ACL-granted euint128 handle from the receipt): `useGetVestedAmount`, `useGetClaimableAmount`, `useGetTotalAllocation`, `useGetSettledAmount`, `useAdminGetVestedAmount`, `useAdminGetClaimableAmount`, `useAdminGetTotalAllocation`, `useAdminGetSettledAmount`, `useAdminGetTokenBalance`; **manager writes** (32): `useCreateVesting`, `useBatchCreateVesting`, `useClaim`, `useAdminClaim`, `usePartialClaim`, `useAdminPartialClaim`, `useRevokeVesting`, `useBatchRevokeVesting`, `useSplitVesting`, `useInitiateVestingTransfer`, `useAcceptVestingTransfer`, `useCancelVestingTransfer`, `useDirectVestingTransfer`, `useDiscloseToParty`, `useBatchDiscloseToParty`, `useAdminDiscloseToParty`, `useAdminBatchDiscloseToParty`, `useDiscloseHandleToParty`, `useBatchDiscloseHandlesToParty`, `useWithdrawAdmin`, `useWithdrawOtherToken`, `useWithdrawOtherConfidentialToken`, `useWithdrawGasFee`, `useWithdrawTokenFee`, `useSetMaxBatchSize`, `useSetMaxRevokeBatchSize`, `useTransferFeeCollectorRole`, `usePause`, `useUnpause`, `useGrantRole`, `useRevokeRole`, `useRenounceRole`. Lazy encryptor source pattern (`encryptor: () => Encryptor | undefined`) implemented via `useMemoManagerClient` — the memoized client captures the encryptor in a `useRef` and resolves it per-call so React-context lifetime is respected (CLAUDE.md Pitfall #3); eager `Encryptor` instances also type-check for Node/test consumers. `@zama-fhe/react-sdk` is an **optional peer** — the hook surface never imports it at top level; a dynamic-import fallback surfaces the "install the peer dep" error only when FHE flows are exercised without an explicit encryptor. Address-override forwarding: every factory hook accepts `{ address?, chainId? }` matching `BaseHookOptions`; manager hooks accept `ManagerHookOptions` where `address` is required (per-user clones have no deployed default); both resolve `TokenOpsSdkError` verbatim when no address is available. Query-key shape: `["tokenops-sdk", "fhe-vesting", "<methodName>", chainId, address?.toLowerCase(), ...primitiveArgs]` with bigints stringified to base-10 and hex strings lowercased. `EncryptorSource` re-exported from `@tokenops/sdk/fhe-vesting/react` alongside `Encryptor`, `resolveEncryptor`, `encryptUint64`, `encryptUint64Batch`, `VestingParams`, `VestingInfo`, `EncryptedViewResult`, `DisclosureType`, `FeeType`, `scaleRatio`, and all manager/factory arg types. `BaseHookOptions` and `ManagerHookOptions` exported for consumers building custom hook wrappers. `docs/fhe-vesting.md` — new `## React hooks` section with hook catalogue table, `useCreateManagerAndGetAddress` quickstart, `useCreateVesting` encryptor-wiring snippet, `useGetClaimableAmount` encrypted-view pattern note, address-override guide, encryptor-source section listing all seven mutation hooks that require one, and query-key reference. Root README — new `### Quickstart — confidential vesting (React hooks)` sub-section showing `useCreateManagerAndGetAddress` + `useCreateVesting` + `useClaim` in a single component.
100
+ - `@tokenops/sdk/fhe-disperse/react` subpath: 35 React/wagmi hooks wrapping every public method of `ConfidentialDisperseClient`. Grouped by family — **reads** (11): `useIsRegistered`, `useGetWallets`, `usePredictWallets`, `useGetFees`, `useGetBatchLimits`, `useCalculateFee`, `useHasApprovedSubwallets`, `useHasRole`, `useIsPaused`, `useDeploymentBlockNumber`, `useWalletImplementation`; **preflight** (1): `usePreflightDisperse`; **user-flow writes** (5): `useRegister`, `useApproveTokenOnWallets`, `useRevokeTokenOnWallets`, `useRecoverFromWallets`, `useRecoverERC20FromWallets`; **core disperse** (1): `useDisperse`; **encrypted views + disclosure** (3): `useGetEncryptedFeeReserve`, `useDiscloseHandleToParty`, `useBatchDiscloseHandlesToParty`; **admin / fee-manager / fee-collector writes** (14): `usePause`, `useUnpause`, `useSetFeeConfig`, `useSetCustomFee`, `useDisableCustomFee`, `useSetMaxBatchSizeHolding`, `useSetMaxBatchSizeDirect`, `useSetMaxBatchSizeTokenFee`, `useWithdrawGasFee`, `useWithdrawTokenFee`, `useRescueConfidentialTokens`, `useRescueERC20`, `useGrantRole`, `useRevokeRole`. Lazy encryptor source pattern (`encryptor: () => Encryptor | undefined`) implemented via `useMemoDisperseClient` — the memoized client captures the encryptor in a `useRef` and resolves it per-call so React-context lifetime is respected (CLAUDE.md Pitfall #3); eager `Encryptor` instances also type-check for Node/test consumers. Only two mutation hooks require an encryptor (`useDisperse`, `useWithdrawTokenFee`) — all registration, recovery, approval-management, and admin hooks are encryptor-free. `useGetEncryptedFeeReserve` is a `useMutation` (submits a tx) that extracts the ACL-granted `euint64` handle from the receipt's `ACL.Allowed` event — not from simulation. Address-override forwarding: every hook accepts `{ address?, chainId? }` matching `BaseHookOptions`; when no address resolves, mutations surface `TokenOpsSdkError` and queries stay gated with `enabled: false`. Query-key shape: `["tokenops-sdk", "fhe-disperse", "<methodName>", chainId, address?.toLowerCase(), ...primitiveArgs]` with bigints stringified to base-10 and hex strings lowercased. `BaseHookOptions`, `DisperseHookOptions`, `computeSubtotals`, `encryptUint64`, `encryptUint64Batch`, `resolveEncryptor`, `Encryptor`, `EncryptorSource`, `EncryptUint64Args`, `EncryptUint64BatchArgs`, `FheValueInput`, `DisperseSubwalletNotFoundError`, `DisperseEncryptedReserveNotGrantedError`, `TokenOpsSdkError`, and all disperse arg/result types re-exported from `@tokenops/sdk/fhe-disperse/react`. `docs/fhe-disperse/README.md` — new `## React hooks` section with hook catalogue table (6 families, 35 hooks), `useRegister` quickstart with invalidation-on-success pattern, `useDisperse` encryptor-wiring snippet with `useCalculateFee` companion, `usePreflightDisperse` gating pattern with `refetchInterval: 5_000` wiring, `useGetEncryptedFeeReserve` encrypted-view flow note, address-override guide, encryptor-source section listing the two mutation hooks that require one, and query-key reference. Root README — new `### Quickstart — confidential disperse (React hooks)` sub-section showing `useRegister` + `usePreflightDisperse` + `useDisperse` in two adjacent components.
101
+ - `@tokenops/sdk/fhe-airdrop/react` subpath: 40 React/wagmi hooks wrapping every public method of `ConfidentialAirdropFactoryClient` and `ConfidentialAirdropClient`. Grouped by family — **factory reads** (6): `useConfidentialAirdropFactoryImplementation`, `useFactoryDefaultGasFee`, `useFactoryFeeCollector`, `useFactoryCustomFee`, `usePredictAirdropAddress`, `useFactoryInitCodeHash`; **factory writes** (8): `useCreateConfidentialAirdrop`, `useCreateConfidentialAirdropAndGetAddress`, `useCreateAndFundConfidentialAirdrop`, `useFundConfidentialAirdrop`, `useSetFeeCollector`, `useSetDefaultGasFee`, `useSetCustomFee`, `useDisableCustomFee`; **airdrop clone reads** (15): `useAirdropToken`, `useAirdropGasFee`, `useAirdropStartTime`, `useAirdropCanExtendClaimWindow`, `useAirdropEndTime`, `useAirdropIsPaused`, `useAirdropDeploymentBlockNumber`, `useAirdropDomainSeparator`, `useAirdropIsClaimWindowActive`, `useAirdropHasClaimStarted`, `useAirdropHasClaimEnded`, `useAirdropClaimedSignatures`, `useAirdropIsSignatureClaimed`, `useAirdropIsSignatureValid`, `useAirdropHasRole`; **airdrop clone writes** (10, including one encrypted view — `useGetClaimAmount` — which submits a tx and extracts the ACL-granted `euint64` handle from the receipt): `useClaim`, `useGetClaimAmount`, `useWithdraw`, `useSetPaused`, `useExtendClaimWindow`, `useWithdrawOtherToken`, `useWithdrawOtherConfidentialToken`, `useAirdropWithdrawGasFee`, `useAirdropGrantRole`, `useAirdropRevokeRole`; **signing helper** (1): `useSignClaimAuthorization`. Lazy encryptor source pattern (`encryptor: () => Encryptor | undefined`) implemented via `useMemoAirdropClient` and `useMemoFactoryClient` — the memoized client captures the encryptor in a `useRef` and resolves it per-call so React-context lifetime is respected (CLAUDE.md Pitfall #3); eager `Encryptor` instances also type-check for Node/test consumers. `@zama-fhe/react-sdk` is an **optional peer** — the hook surface never imports it at top level; the consumer must wire `encryptor: () => useZamaSDK().relayer` explicitly for encrypted-input flows (`useCreateAndFundConfidentialAirdrop`, `useFundConfidentialAirdrop`, `useClaim`, `useGetClaimAmount`). `useSignClaimAuthorization` pulls `walletClient` from wagmi's `useWalletClient()` internally and throws `TokenOpsSdkError` if no wallet is connected. Address-override forwarding: every factory hook accepts `{ address?, chainId? }` matching `BaseHookOptions`; airdrop clone hooks accept `AirdropHookOptions` where `address` is required (per-campaign clones have no deployed default). Sepolia factory address (`0xbE6A3B78B36684fFee48De77d47Bc3393F5Acd4c`) resolves automatically from `DEPLOYED_ADDRESSES`; mainnet slot is `null`. Query-key shape: `["tokenops-sdk", "fhe-airdrop", "<methodName>", chainId, address?.toLowerCase(), ...primitiveArgs]` with bigints stringified to base-10 and hex strings lowercased. `EncryptorSource`, `Encryptor`, `resolveEncryptor`, `encryptUint64`, `encryptUint64Batch`, `signClaimAuthorization`, `AirdropParams`, `ClaimArgs`, `GetClaimAmountArgs`, `EncryptedViewResult`, `CreateAirdropArgs`, `CreateAirdropAndGetAddressResult`, `CreateAndFundAirdropArgs`, `FundAirdropArgs`, `PredictAirdropArgs`, `CustomFee`, `EncryptedInput`, `EncryptedInputs`, `FheValueInput`, `BaseHookOptions`, `AirdropHookOptions`, `FactoryHookOptions`, and `TokenOpsSdkError` re-exported from `@tokenops/sdk/fhe-airdrop/react`. `docs/fhe-airdrop/README.md` — new `## React hooks` section with hook catalogue table (5 families, 40 hooks), `useCreateConfidentialAirdropAndGetAddress` quickstart, `useClaim` encryptor-wiring snippet, `useGetClaimAmount` encrypted-view pattern note, `useSignClaimAuthorization` admin-sign-then-deliver flow, address-override guide, encryptor-source section listing the four mutation hooks that require one, and query-key reference. Root README — new `### Quickstart — confidential airdrop (React hooks)` sub-section showing `useCreateConfidentialAirdropAndGetAddress` + `useSignClaimAuthorization` + `useClaim` in two adjacent components.
102
+ - `@tokenops/sdk/disperse` subpath: typed wrappers for the two non-FHE bulk-payout variants deployed by `DisperseFactory`. `DisperseFactoryClient` exposes `createGasFeeDisperse()` (deploys a `DisperseGasFee` clone — flat ETH fee per recipient) and `createTokenFeeDisperse()` (deploys a `DisperseTokenFee` clone — BPS-of-amount fee paid in the dispersed ERC20); both return `{ hash, disperse: Address }` parsed from the factory's `*Created` event (plain `new`, not CREATE2, so no `predictAddress` helper). `DisperseGasFeeClient` wraps the gas-fee clone with four user ops: `disperseEther` (gross — sender pays `FEE` per recipient on top of amounts), `disperseEtherDeductedFee` (deducted — fee withheld from each recipient's allocation, requires `values[i] > FEE`), `disperseToken` (batched ERC20 via a single `safeTransferFrom` into the contract then individual push-outs), `disperseTokenSimple` (per-recipient `safeTransferFrom` directly from the sender, saves one transfer hop). `DisperseTokenFeeClient` wraps the token-fee clone with two user ops: `disperseToken` (gross — sender approves `totalAmount + totalFee`, recipients receive full allocations) and `disperseTokenDeductedFee` (deducted — sender approves `totalAmount`, each recipient receives `values[i] - feeAmount`); both are non-payable. Headline ergonomic feature: preflight bundles across the two clones — `DisperseGasFeeClient` exposes `preflightDisperseEther` (gross), `preflightDisperseEtherDeducted` (deducted), and `preflightDisperseToken({ mode: "gross" | "simple" })`; `DisperseTokenFeeClient` exposes `preflightDisperseToken` (gross) and `preflightDisperseTokenDeducted` (deducted). Each validates entries, fetches the fee, checks ERC20 allowance / token balance / ETH balance in one parallel call and returns `DisperseEtherPreflightReport` or `DisperseTokenPreflightReport` with `ready` + `blockers`. Typed errors `DisperseFactoryNotConfiguredError`, `DisperseNotDeployedError`, `InvalidDisperseEntriesError` all extend `TokenOpsSdkError`. `DisperseFeeType` codec helpers `encodeFeeType` / `decodeFeeType` exported. Factory admin surface: `setFeeCollector`, `setDefaultGasFee`, `setDefaultTokenFee`, `setDefaultFeeType`, `resetGasFee`, `resetTokenFee`, `setCustomFee`, `disableCustomFee`, `transferOwnership`. `DisperseTokenFeeClient` additionally exposes `tokenToFeeReserved(token)` so the fee collector can see what's claimable per token. Deployed factory addresses now wired in `DEPLOYED_ADDRESSES.disperse.disperseFactory` on mainnet (`0xD037f091F5446B48e50e6fCf91dC49CA0719669E`) and Sepolia (`0x38cd65b39Ca6ea7a759cF5A2ce324A761aEBc40F`) — no `address:` override required when the public client is on mainnet or Sepolia.
103
+ - `@tokenops/sdk/disperse/react` placeholder subpath, mirroring `/staking`, `/airdrops`, and `/vesting`.
104
+ - `docs/disperse/README.md` — full two-variant API reference with a comparison table (fee model / fee currency / user ops / payable / withdraw paths / fee reserve visibility), factory admin reference, preflight-report shape walkthroughs with `ready: true` and `ready: false` examples, gross-vs-deducted decision table, `disperseToken` vs `disperseTokenSimple` trade-off table, custom-fee guide, address-override section, error catalogue, React placeholder note, and side-by-side `/disperse` vs `/fhe-disperse` comparison table.
105
+ - `docs/disperse/examples/` — four copy-paste-compilable examples: `create-gas-fee-disperse.ts`, `create-token-fee-disperse.ts`, `disperse-ether.ts`, `disperse-token.ts`.
106
+ - Root README: `/disperse` subpath status updated from `scaffold` to `factory live on mainnet + sepolia`; Sepolia deployed-list in the lead paragraph updated to include `/disperse`; added `Quickstart — bulk payouts (non-FHE disperse)` section and link to per-subpath docs.
107
+
108
+ - `@tokenops/sdk/staking` subpath: typed wrappers for three non-FHE staking variants. `StakingFactoryClient` + `StakingClient` — single-token, conditions-based rewards (configurable `timeUnit` + reward ratio per condition); inherits `StakingBase` so it exposes merkle + trusted-distributor whitelisting, three `stake()` overloads (`stake(amount)`, `stake(amount, receiver)`, `stake(amount, receiver, merkleProof)`), and a `claimRewardsAmount(amount)` partial-claim overload. `DualTokenStakingFactoryClient` + `DualTokenStakingClient` — separate staking and reward tokens, optional native ETH acceptance via a `nativeTokenWrapper` (WETH-style) address configured at deploy time; no whitelist surface, no merkle overload on `stake`, no `claimRewardsAmount`; admin must call `depositRewardTokens(amount)` before rewards are claimable. **Bootstrap quirk:** `setTimeUnit` must be called before `setRewardRatio` on a freshly deployed clone — the contract reads `stakingConditions[nextConditionId-1]`, which underflows to `type(uint256).max` when `nextConditionId === 0` (the constructor seeds no initial condition). `UnbondingStakingFactoryClient` + `UnbondingStakingClient` — fixed APY (basis-points percent, configured at deploy time), mandatory `initiateUnbonding(amount)` → wait `unbondingPeriod` → `completeUnbonding()` withdrawal flow; inherits `StakingBase` (same whitelist surface as `Staking`, same three `stake()` overloads and `claimRewardsAmount`). All three factories use plain `new` (no CREATE2) — `create*` methods parse the `*Created` event from the receipt and return `{ hash, staking: Address }`; there is no `predictAddress` helper. Headline ergonomic feature: `preflightStake({ user, amount, merkleProof? })` (all three clients) composes staking window, tier bounds, pool cap, fee type and `ethValueForStake`, and ERC20 allowance shortfall into a single `StakePreflightReport` with `ready` + `blockers`; `preflightWithdraw` and `preflightClaim` follow the same pattern; `UnbondingStakingClient` additionally exposes `preflightCompleteUnbonding({ user })` returning `{ unbondingAmount, timeUntilComplete, ready, blockers }`. `FeeFunctions` named bitmask constants (`FEE_ON_NONE`, `FEE_ON_STAKE`, `FEE_ON_WITHDRAW`, `FEE_ON_CLAIM`, `FEE_ON_ALL`). `encodeFeeFunctions` / `decodeFeeFunctions`, `encodeStakingFeeType` / `decodeStakingFeeType`, `encodeWhitelistStatus` / `decodeWhitelistStatus` codec helpers exported. Typed errors `StakingFactoryNotConfiguredError` and `StakingNotDeployedError` both extend `TokenOpsSdkError`. All three factory address slots (`stakingFactory`, `dualTokenStakingFactory`, `unbondingStakingFactory`) are currently `null` in `DEPLOYED_ADDRESSES.staking` on every chain — pass `address:` override until deployments land.
109
+ - `@tokenops/sdk/staking/react` placeholder subpath, mirroring `/airdrops` and `/vesting`.
110
+ - `docs/staking/README.md` — full three-variant API reference with a comparison table (asset model / whitelist / rewards model / unbonding / stake overloads / admin fund step), `preflightStake` / `preflightWithdraw` / `preflightClaim` / `preflightCompleteUnbonding` report-shape walkthroughs, the three `stake()` overload dispatch rules, funding-model section (single/unbonding `fundStakingContract` vs dual `depositRewardTokens`), fee-modes + `FeeFunctions` bitmask table, DualTokenStaking bootstrap quirk callout, address-override guide, error catalogue, and React placeholder note.
111
+ - `docs/staking/examples/` — four copy-paste-compilable examples: `create-staking.ts`, `create-dual-token-staking.ts` (includes correct `setTimeUnit`-before-`setRewardRatio` order), `create-unbonding-staking.ts`, `preflight-and-stake.ts`.
112
+ - Root README: `/staking` subpath status updated from `scaffold` to `factories not yet deployed`; added Quickstart — staking section and link to per-subpath docs.
113
+ - Polish (auditor + DX + docs pass): fixed `preflightClaim` funding check in `StakingClient` and `UnbondingStakingClient` (`rewardsAvailable >= pendingRewards` replaces the incorrect `rewardsAvailable > 0`); added `DualTokenStakingNotBootstrappedError` (extends `TokenOpsSdkError`) + `isBootstrapped()` to `DualTokenStakingClient` — both `setTimeUnit` and `setRewardRatio` now throw the typed error pre-flight instead of letting the on-chain arithmetic underflow surface opaquely; `StakingClient.setStakingCondition` now validates `timeUnit > 0` with a clear error; `isAddressEqual` from viem replaces `toLowerCase()` comparisons in all three factory event filters; `tierUpperBound` TSDoc corrected on `StakingClient` and `UnbondingStakingClient` (0 = zero capacity, not unlimited); `TokenOpsSdkError` re-exported from `/staking` index; TSDoc added to all six codec functions + six factory/client factory functions; `DualTokenStakingNotBootstrappedError` exported from `/staking` index; docs bootstrap-quirk section renamed and rewritten to document the correct ordering and SDK-enforced guard; root README Docs section now lists `/staking`.
114
+
115
+ - `@tokenops/sdk/airdrops` subpath: typed wrappers for the non-FHE merkle-distributor product. `MerkleDistributorFactoryClient` exposes `createTokenDistributor` (ERC20 variant) and `createNativeDistributor` (ETH variant, payable — `msg.value` funds the pool at deploy time) — both return `{ hash, distributor }` parsed from the factory's `*Created` event in the receipt (the factory uses plain `new`, no CREATE2, so there is no `predict*Address` helper). `MerkleDistributorClient` (ERC20) and `MerkleDistributorNativeClient` (native) wrap the per-campaign clones with reads for `merkleRoot`, `startTime`, `endTime`, `fee`, `feeType`, `isClaimed`, the 7-day grace-period accessors, and AccessControl helpers. Headline ergonomic feature: `buildMerkleTree([{ recipient, amount }])` returns `{ root, claims: Record<address, MerkleClaim>, claimList }` — the per-recipient `MerkleClaim` (`{ index, recipient, amount, proof }`) drops straight into `distributor.claim(...)` without re-shaping. Leaves use the contract's `keccak256(abi.encodePacked(uint256, address, uint256))` format and OZ's sorted-pair root; `verifyMerkleProof(root, claim)` mirrors the on-chain verifier for local checks. `preflightClaim({ index, recipient, amount, proof })` composes proof validity, `isClaimed`, window state, fund sufficiency, and the gas-fee `msg.value` into a single `ClaimPreflightReport` with `ready` + `blockers`. Typed errors `AirdropFactoryNotConfiguredError`, `MerkleDistributorNotDeployedError`, `InvalidMerkleAllocationsError`. The factory address slot is currently `null` in `DEPLOYED_ADDRESSES.airdrops.merkleDistributorFactory` — pass `address:` override until the deployment lands.
116
+ - `@tokenops/sdk/airdrops/react` placeholder subpath.
117
+ - `docs/airdrops/README.md` — full two-variant API reference, headline `buildMerkleTree` + `preflightClaim` walkthroughs, ERC20 vs native funding-model comparison, fee-mode walkthrough, 7-day grace-period rules, address-override guide, error catalogue.
118
+ - `docs/airdrops/examples/` — four copy-paste-compilable examples: `build-merkle-tree.ts`, `create-token-distributor.ts`, `create-native-distributor.ts`, `claim.ts`.
119
+ - `test/helpers/airdrops-fixture.ts` — lazy + memoized forge-artifact loader that deploys the factory + `TestERC20` at test time (production SDK never deploys factories).
120
+ - `src/airdrops/merkle-tree.test.ts` — 9 unit checks for the merkle helper: on-chain-compatible leaf hash, OZ sorted-pair root, odd-tail self-pair proof, tamper rejection, validation errors. No chain required.
121
+ - `test/airdrops/airdrops.test.ts` — 14 local Anvil checks across factory deploy, distributor reads, SDK-built proof verification through preflight, `claim()` happy path + `isClaimed` flip + duplicate-claim preflight blocker, native variant `msg.value` funding, factory fee-config round-trip, constructor failure when no chain id is configured.
122
+ - `test/airdrops/airdrops.sepolia.test.ts` — read + full gates against a deployed factory. Skips cleanly when `SEPOLIA_AIRDROPS_FACTORY` is unset.
123
+ - Sepolia env vars: `SEPOLIA_AIRDROPS_FACTORY`, `SEPOLIA_AIRDROPS_TEST_TOKEN`. Read-only gate needs only RPC + factory; full gate additionally needs the private key + test token.
124
+ - `tsconfig.json` paths alias for `@tokenops/sdk/airdrops/react`, so examples typecheck against local source.
125
+ - Root README: `/airdrops` subpath status updated from `scaffold` to `factory not yet deployed`; added Quickstart — token airdrop section and link to per-subpath docs.
126
+
127
+ - `@tokenops/sdk/vesting` subpath: typed wrappers for the four non-FHE vesting families (`TokenVestingFactoryClient` / `TokenVestingManagerClient`, `NativeVestingFactoryClient` / `NativeVestingManagerClient`, `VotesVestingFactoryClient` / `VotesVestingManagerClient`, `MilestoneVestingFactoryClient` / `MilestoneVestingManagerClient`). All four factories use plain `new` (no CREATE2), so the SDK exposes `create*VestingManager` helpers that deploy and parse the manager address from the factory's `*Created` event in the receipt — there is no `predict*Address` helper. Headline ergonomic feature: `preflightClaim({ vestingId })` (or `preflightStepClaim({ milestoneId, stepIndex })` for milestone vesting) composes vesting / claimable / funding / cliff / timelock / fee state into a single `ClaimPreflightReport` with `ready` + `blockers`. `NativeVesting` makes the funding side payable and the SDK computes `msg.value` automatically (schedule total for `createVesting` in full-funding mode, sum-of-amounts for `fundVestingBatch`, `FEE()` for `claim`). `VotesVesting` exposes per-vesting `Vault` clones via `vaultFor(vestingId)` + `manager.delegate({ vestingId, delegatee })`. `MilestoneVesting` exposes the two-phase create-then-approve flow with `approveMilestoneStep` and `preflightStepClaim`. Typed errors `VestingFactoryNotConfiguredError` and `VestingManagerNotDeployedError`. All four factory address slots are currently `null` in `DEPLOYED_ADDRESSES.vesting` — pass `address:` override until deployments land.
128
+ - `@tokenops/sdk/vesting/react` placeholder subpath, mirroring `/fhe-vesting` and `/fhe-disperse`.
129
+ - `docs/vesting/README.md` — full four-variant API reference with a comparison table (asset / payable createVesting / token-fee mode / per-vesting clone), funding-model + fee-mode walkthroughs, the headline `preflightClaim` helper, address-override guide, error catalogue, and a side-by-side `/vesting` vs `/fhe-vesting` table.
130
+ - `docs/vesting/examples/` — four copy-paste-compilable examples: `token-vesting.ts`, `native-vesting.ts`, `votes-vesting.ts`, `milestone-vesting.ts`.
131
+ - `scripts/extract-vesting-abis.mjs` — one-shot extractor that materializes `src/vesting/abis/*.ts` from `vesting-contracts-v3/out/`. Run only when contracts change.
132
+ - `test/helpers/vesting-fixture.ts` — lazy + memoized forge-artifact loader that deploys factories + a mintable `MockERC20Votes` at test time (production SDK never deploys factories).
133
+ - `test/vesting/{token,native,votes,milestone}-vesting.test.ts` — local Anvil suites covering factory → createManager → preflight → write end-to-end for each variant.
134
+ - `test/vesting/vesting.sepolia.test.ts` — read-only and full gates per variant; skips cleanly when env is absent.
135
+ - Sepolia env vars: `SEPOLIA_VESTING_{TOKEN,NATIVE,VOTES,MILESTONE}_FACTORY`, `SEPOLIA_VESTING_TEST_TOKEN`, `SEPOLIA_VESTING_VOTES_TEST_TOKEN`. Read-only gates need only RPC + factory; full gates additionally need private key + test token (native suite needs no token).
136
+ - `tsconfig.json` paths alias for `@tokenops/sdk/vesting/react`, so examples typecheck against local source.
137
+ - Root README: `/vesting` subpath status updated from `scaffold` to `factories not yet deployed`; added Quickstart — token vesting section and link to per-subpath docs.
138
+
139
+ - `@tokenops/sdk/fhe-disperse` subpath: `ConfidentialDisperseClient` for confidential bulk payouts via the `DisperseConfidential` singleton. Three disperse modes (`"wallet"`, `"wallet-token-fee"`, `"direct"`). `preflightDisperse` returns all five readiness conditions (registration, wallet approvals, ETH gas fee, batch limit, recipient validation) in a single call. `computeSubtotals` exported for callers who need to verify the per-wallet group sums before dispersing. `predictWallets` derives deterministic ERC-1167 wallet clone addresses before registration. `getEncryptedFeeReserve` grants admin FHE ACL on the encrypted token fee reserve and returns the handle via receipt `ACL.Allowed` event (not simulation). `discloseHandleToParty` and `batchDiscloseHandlesToParty` for re-sharing handles. Typed errors `DisperseSubwalletNotFoundError` and `DisperseEncryptedReserveNotGrantedError`. Sepolia singleton address slot is currently `null` in `DEPLOYED_ADDRESSES` — pass `address:` override until the deployment lands.
140
+ - `@tokenops/sdk/fhe-disperse/react` placeholder subpath, mirroring `/fhe-vesting` and `/fhe-airdrop`.
141
+ - `docs/fhe-disperse/README.md` — full API reference with architecture diagram, three-mode table, subtotal correctness warning, encrypted fee reserve guide, error catalogue, FHE pitfall section, and frontend/backend usage examples.
142
+ - `docs/fhe-disperse/examples/` — four copy-paste-compilable examples: `register.ts`, `disperse.ts`, `preflight.ts`, `recover.ts`.
143
+ - `tsconfig.json` paths alias for `@tokenops/sdk/fhe-disperse` so examples typecheck against local source.
144
+ - Root README: `fhe-disperse` subpath status row updated from `scaffold` to `singleton not yet deployed`; added Quickstart — confidential disperse section and link to per-subpath docs.
145
+
146
+ - `/fhe-airdrop` subpath: `ConfidentialAirdropFactoryClient` (with `createConfidentialAirdropAndGetAddress` symmetry helper that parses the `ConfidentialAirdropCreated` event), `ConfidentialAirdropClient`, `signClaimAuthorization`, encryption helpers, types, and ABIs. Sepolia factory address is now wired in `src/core/addresses.ts` (`0xbE6A3B78B36684fFee48De77d47Bc3393F5Acd4c`) — consumers no longer need to pass `address:` explicitly when the public client is on Sepolia.
147
+ - `src/fhe/acl.ts` — shared `FHEVM_ACL_ADDRESS_BY_CHAIN` and `ACL_ALLOWED_EVENT` exports. Single source of truth for ACL host-contract addresses across products; consumed by `fhe-vesting` and `fhe-airdrop`. Re-exported from `@tokenops/sdk/fhe`.
148
+ - `docs/fhe-airdrop/README.md` — full API reference with EIP-712 claim flow diagram, address-override guide, and frontend/backend usage examples.
149
+ - `docs/fhe-airdrop/examples/` — three copy-paste-compilable examples: `create-airdrop.ts`, `claim.ts`, `encrypted-balance-view.ts`.
150
+ - `hasFheAirdropArtifacts()` test helper — symmetry with `hasFheVestingArtifacts()` for the new fixture.
151
+ - `tsconfig.json` paths alias for `@tokenops/sdk/fhe-airdrop` so examples typecheck against local source.
152
+ - JSDoc on `claimedSignatures`, `isSignatureClaimed`, and `isSignatureValid` explaining the input difference and which to reach for in a frontend context.
153
+ - `ConfidentialVestingFactoryClient.createManagerAndGetAddress()` — deploy a clone and return `{ hash, manager }` parsed from the `ManagerCreated` event in the receipt. **This is now the recommended entry point** for the common "deploy and use" flow; `predictManagerAddress` is unreliable on a live chain because the factory packs `block.number` into the clone's immutable args.
154
+ - `hasFheVestingArtifacts()` test helper — detect whether the sibling contracts-repo's artifacts are present, for callers that want to gate local suites on presence rather than failing at module import.
155
+
156
+ ### Changed
157
+
158
+ - Root README: `/fhe-airdrop` subpath status updated from `scaffold` to `factory not yet deployed`; added Quickstart — confidential airdrop section and link to per-subpath docs.
159
+ - `PredictManagerArgs` now requires `blockNumber: bigint`. The factory packs `block.number` into the clone's immutable args, so the predicted address is only stable for the block it was read at. The new field forces callers to acknowledge that. `predictManagerAddress` is now positioned as a historical-lookup tool, not a pre-deploy primitive. README + per-subpath Quickstart rewritten to use `createManagerAndGetAddress` instead of predict-then-deploy.
160
+ - `scripts/local-fhevm-up.sh` verifies the recorded PID is actually `anvil` (defeats PID-recycling false positives), tracks the port in a separate file, and fails fast when anvil doesn't bind within 5s. `local-fhevm-down.sh` belt-and-braces frees the recorded port via `lsof` or `fuser` when the PID is gone but the listener isn't.
161
+ - `test/helpers/fhe-vesting-fixture.ts` and `test/helpers/fhe-airdrop-fixture.ts` defer artifact loads to call-time (lazy + memoized). Missing sibling-repo artifacts no longer crash vitest module discovery with `ENOENT`; the error surfaces inside the test that actually needs them.
162
+
163
+ ### Security
164
+
165
+ - `ConfidentialVestingManagerClient.#encryptedView` and `ConfidentialAirdropClient.getClaimAmount` now assert exactly one matching `Allowed(this, caller, _)` ACL event per tx instead of picking `granted[last]` (or `granted[0]`). Future compound views that emit multiple grants must add their own dedicated helper rather than relying on heuristic position. Removes the auditor-flagged fragility on the existing single-handle view surface.
166
+ - `ConfidentialAirdropClient` constructor now **throws** when no FHEVM ACL address is resolvable (instead of `console.warn`-ing and deferring to first `getClaimAmount` call). Misconfiguration surfaces immediately at construction. Production decrypt flows no longer fail at first user click. Required action: ensure `publicClient` is constructed with a `chain` value (31337 / 11155111 / 1) or pass `aclAddress` explicitly. Flagged by the fhevm-security-auditor against the live Sepolia deployment audit.
167
+
168
+ ## [1.0.0-rc.1] - 2026-05-14
169
+
170
+ ### Added
171
+
172
+ - TSDoc across the full public surface (`ConfidentialVestingFactoryClient`, `ConfidentialVestingManagerClient`, encryption helpers, types).
173
+ - `docs/fhe-vesting.md` — full API reference with examples for factory and manager clients.
174
+ - `docs/local-dev-with-link.md` — guide for consumers doing active SDK development via `link:`.
175
+ - `examples/*.ts` — four copy-paste-compilable examples covering factory setup, manager creation, vesting creation, and claim flow.
176
+ - `aclAddress` constructor warning on unknown chains (raises `console.warn` rather than silently proceeding with a wrong address).
177
+
178
+ ### Changed
179
+
180
+ - `setMaxBatchSize` now accepts `bigint` only (was `bigint | number`). Eliminates silent downcast issues on large values.
181
+ - `#encryptedView` internal filter additionally requires `caller === manager-address`, preventing spurious `ACL.Allowed` events emitted by other contracts in the same transaction from being mistaken for the manager's handle grant.
182
+
183
+ ### Removed
184
+
185
+ - `vesting/`, `airdrops/`, `fhe-airdrop/`, `disperse/`, `fhe-disperse/`, `staking/` subpath exports. These were empty placeholder scaffolds. Each will re-ship as a MINOR release when the corresponding contracts-repo SDK lands.
186
+ - `fhe-vesting/react/` subpath export. Empty placeholder; will re-ship when wagmi hooks are implemented.
187
+
188
+ ### Fixed
189
+
190
+ - Lazy `EncryptorSource` factory path correctly resolves the encryptor at use-site rather than construction-site, supporting React/Vue context lifecycles where the dep lifetime does not match the SDK client's lifetime.
191
+
192
+ ### Security
193
+
194
+ - `#encryptedView` no longer susceptible to spurious `ACL.Allowed` events emitted by non-manager contracts in the same transaction.
195
+
196
+ ## [1.0.0-alpha.0] - 2026-05-14
197
+
198
+ ### Added
199
+
200
+ - Initial scaffold for the v1 SDK targeting `@zama-fhe/sdk@3`.
201
+ - `/fhe-vesting` subpath: `ConfidentialVestingFactoryClient`, `ConfidentialVestingManagerClient`, encryption helpers, React hooks placeholder.
202
+ - Sepolia factory address wired in `src/core/addresses.ts` (`0xA87701CE9A52D43681600583a99c85b50DbE3150`).
203
+ - Three-surface test rig: unit, local FHEVM (anvil + forge-fhevm host contracts + `@fhevm/mock-utils`), Sepolia smoke.
204
+
205
+ [1.1.0]: https://github.com/VestingLabs/tokenops-sdk/compare/v1.0.0...v1.1.0
206
+ [1.0.0]: https://github.com/VestingLabs/tokenops-sdk/compare/v1.0.0-alpha.0...v1.0.0
207
+ [1.0.0-alpha.0]: https://github.com/VestingLabs/tokenops-sdk/releases/tag/v1.0.0-alpha.0
@@ -0,0 +1,113 @@
1
+ # Contributing to @tokenops/sdk
2
+
3
+ ## Prerequisites
4
+
5
+ - **Node.js** >= 22 (see `.nvmrc`)
6
+ - **pnpm** >= 10
7
+ - **Git**
8
+ - An RPC endpoint for Sepolia (for integration tests)
9
+
10
+ ## Development Setup
11
+
12
+ ```bash
13
+ git clone https://github.com/VestingLabs/tokenops-sdk.git
14
+ cd tokenops-sdk
15
+ pnpm install
16
+ pnpm typecheck # verify the baseline compiles
17
+ ```
18
+
19
+ ## Branch Naming
20
+
21
+ Branch from `main`. Use the subpath taxonomy as the scope:
22
+
23
+ ```
24
+ feat/fhe-vesting-split-ui-helpers
25
+ feat/fhe-airdrop-batch-claim
26
+ fix/fhe-disperse-preflight-gas-check
27
+ docs/fhe-vesting-jsdoc-sweep
28
+ chore/tsup-cjs-dts
29
+ ```
30
+
31
+ Pattern: `<type>/<subpath or concern>-<short-description>`. Types are the same as Conventional Commits.
32
+
33
+ ## Making Changes
34
+
35
+ 1. Make your change in `src/`. Public exports live in `src/<product>/index.ts`.
36
+ 2. Run `pnpm typecheck` after every non-trivial edit. The SDK has a strict `tsc` config; fix errors before committing.
37
+ 3. Run `pnpm lint` to check formatting and ESLint rules. Use `pnpm lint:fix` to auto-fix.
38
+ 4. Keep ABIs committed as JSON in `src/<product>/abis/`. Do not import from sibling contract repos at build time.
39
+
40
+ ## Running Tests
41
+
42
+ ```bash
43
+ pnpm test # vitest unit suite (no network needed)
44
+ pnpm test:local # integration tests against local Anvil + FHEVM host contracts
45
+ pnpm test:sepolia # integration tests against Sepolia (requires env vars — see below)
46
+ ```
47
+
48
+ For local FHEVM tests, bring up the local stack first:
49
+
50
+ ```bash
51
+ pnpm fhevm:up # clones zama-ai/forge-fhevm, spawns Anvil, deploys host contracts
52
+ # ... run tests ...
53
+ pnpm fhevm:down
54
+ ```
55
+
56
+ Sepolia tests require:
57
+
58
+ ```
59
+ SEPOLIA_RPC_URL=https://...
60
+ SEPOLIA_PRIVATE_KEY=0x...
61
+ ```
62
+
63
+ Read-only tests gate on `SEPOLIA_RPC_URL` only. Write tests additionally require `SEPOLIA_PRIVATE_KEY` with a funded account. See `test/helpers/skip-if.ts` for the gate helpers.
64
+
65
+ ## Code Style
66
+
67
+ `pnpm lint` runs ESLint and Prettier. Rules are in `eslint.config.mjs` and `.prettierrc`. The build enforces them — PRs with lint failures are blocked.
68
+
69
+ FHE-specific patterns:
70
+
71
+ - Encrypted handles come from `ACL.Allowed` events on the tx receipt, not from `simulateContract` return values. See `CLAUDE.md` Pitfall #1.
72
+ - Pass `euint64` for token balances. Target <= 2 FHE ops per tx where possible.
73
+ - Every public method that takes encrypted inputs must accept `EncryptorSource` (eager or lazy). See `CLAUDE.md` Pitfall #3.
74
+
75
+ ## Build
76
+
77
+ ```bash
78
+ pnpm build # tsup → dist/ (ESM + CJS + .d.ts per subpath)
79
+ ```
80
+
81
+ The build runs `tsup` (JS output) then `tsc -p tsconfig.build.json` (type declarations), then merges `dist-types/` into `dist/`. Do not edit `dist/` directly.
82
+
83
+ ## Pull Request Process
84
+
85
+ **PR title must follow Conventional Commits:**
86
+
87
+ ```
88
+ feat(fhe-airdrop): add batch claim authorization helper
89
+ fix(fhe-vesting): correct gas fee check in preflightClaim
90
+ docs: add @example to encryptUint64 in fhe-disperse
91
+ chore: bump @zama-fhe/sdk to 3.1.0
92
+ ```
93
+
94
+ Pattern: `<type>(<scope>): <imperative description>`. Scope is optional; use the subpath name when the change is product-specific. The PR title is validated by CI against this regex:
95
+
96
+ ```
97
+ ^(feat|fix|perf|refactor|docs|chore|test|build|ci|revert|style)(\([^)]+\))?!?: .+
98
+ ```
99
+
100
+ **Checklist before requesting review:**
101
+
102
+ - `pnpm typecheck` passes
103
+ - `pnpm lint` passes
104
+ - `pnpm test` passes
105
+ - `pnpm build` produces a clean `dist/`
106
+ - New public exports are added to the relevant `src/<product>/index.ts` barrel
107
+ - New public methods have a JSDoc block with `@param`, `@returns`, and `@example`
108
+
109
+ ## Claude Code Setup
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.
112
+
113
+ See the `claude-setup/` directory and Zama's [Claude Code plugin model](https://docs.claude.ai/en/docs/claude-code) for details.
package/LICENSE ADDED
@@ -0,0 +1,32 @@
1
+ BSD 3-Clause Clear License
2
+
3
+ Copyright © 2026 VestingLabs
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted (subject to the limitations in the disclaimer
8
+ below) provided that the following conditions are met:
9
+
10
+ 1. Redistributions of source code must retain the above copyright notice,
11
+ this list of conditions and the following disclaimer.
12
+
13
+ 2. Redistributions in binary form must reproduce the above copyright
14
+ notice, this list of conditions and the following disclaimer in the
15
+ documentation and/or other materials provided with the distribution.
16
+
17
+ 3. Neither the name of the copyright holder nor the names of its
18
+ contributors may be used to endorse or promote products derived from this
19
+ software without specific prior written permission.
20
+
21
+ NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
22
+ THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23
+ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
26
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
30
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ POSSIBILITY OF SUCH DAMAGE.