@tokenops/sdk 2.0.0-alpha.1 → 2.0.0-alpha.3

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 (155) hide show
  1. package/CHANGELOG.md +67 -2
  2. package/README.md +14 -8
  3. package/dist/{chunk-PUX5VXDB.cjs → chunk-4AWQJQXY.cjs} +1415 -69
  4. package/dist/{chunk-74QFZ5MK.js → chunk-4IB4IY5Y.js} +1 -1
  5. package/dist/{chunk-DZHYSUGY.js → chunk-6HCT4QIX.js} +12 -5
  6. package/dist/{chunk-FGEB7RMY.cjs → chunk-6XOAYDC6.cjs} +4 -4
  7. package/dist/{chunk-XAYGD4E4.cjs → chunk-AHU2HMNE.cjs} +3 -3
  8. package/dist/{chunk-6NAVMWZQ.js → chunk-BPIVVCSQ.js} +2 -2
  9. package/dist/{chunk-GKKDAW44.js → chunk-BXX5TETM.js} +1401 -59
  10. package/dist/{chunk-456VDDA3.js → chunk-GCJFAY4X.js} +78 -25
  11. package/dist/{chunk-CTED3MTR.cjs → chunk-GKYZQJGP.cjs} +82 -29
  12. package/dist/{chunk-JZLGCTGK.cjs → chunk-IEKTGJ4J.cjs} +2 -2
  13. package/dist/{chunk-6PXXGACR.cjs → chunk-JVNJSDQ4.cjs} +2 -2
  14. package/dist/{chunk-O5676ZWY.js → chunk-LEYYG4RF.js} +232 -6
  15. package/dist/{chunk-335Z2W67.js → chunk-NGU4JYIR.js} +1 -1
  16. package/dist/{chunk-5576FRT3.cjs → chunk-PG3WXT3K.cjs} +12 -5
  17. package/dist/{chunk-H5POPGOZ.js → chunk-PK6Q6J5F.js} +1 -1
  18. package/dist/chunk-TND5NDV7.cjs +263 -0
  19. package/dist/chunk-U3TBQRT7.js +253 -0
  20. package/dist/{chunk-EAJ7SYHE.js → chunk-WRWRA4TN.js} +1 -1
  21. package/dist/{chunk-JQYC66TO.cjs → chunk-YABHXJNH.cjs} +5 -5
  22. package/dist/{chunk-M4IT6DNJ.cjs → chunk-YTIYTV4K.cjs} +236 -4
  23. package/dist/core/addresses.d.ts +4 -4
  24. package/dist/core/errors.d.ts +1 -1
  25. package/dist/fhe/types.d.ts +2 -2
  26. package/dist/fhe-airdrop/abis/airdrop-base.d.ts +19 -0
  27. package/dist/fhe-airdrop/abis/ecdsa.d.ts +19 -0
  28. package/dist/fhe-airdrop/abis/factory.d.ts +113 -0
  29. package/dist/fhe-airdrop/abis/merkle.d.ts +43 -12
  30. package/dist/fhe-airdrop/advanced/index.cjs +4 -4
  31. package/dist/fhe-airdrop/advanced/index.js +1 -1
  32. package/dist/fhe-airdrop/advanced/react/index.cjs +620 -9
  33. package/dist/fhe-airdrop/advanced/react/index.d.cts +35 -0
  34. package/dist/fhe-airdrop/advanced/react/index.d.ts +35 -0
  35. package/dist/fhe-airdrop/advanced/react/index.js +590 -7
  36. package/dist/fhe-airdrop/advanced/react/useClearCompliancePolicy.d.ts +28 -0
  37. package/dist/fhe-airdrop/advanced/react/useClearUpgradeabilityPolicy.d.ts +26 -0
  38. package/dist/fhe-airdrop/advanced/react/useDisableCustomFee.d.ts +26 -0
  39. package/dist/fhe-airdrop/advanced/react/useEcdsaInitCodeHash.d.ts +30 -0
  40. package/dist/fhe-airdrop/advanced/react/useFactoryComplianceDelegate.d.ts +25 -0
  41. package/dist/fhe-airdrop/advanced/react/useFactoryCompliancePolicy.d.ts +38 -0
  42. package/dist/fhe-airdrop/advanced/react/useFactoryCustomFee.d.ts +24 -0
  43. package/dist/fhe-airdrop/advanced/react/useFactoryGrantRole.d.ts +32 -0
  44. package/dist/fhe-airdrop/advanced/react/useFactoryHasRole.d.ts +27 -0
  45. package/dist/fhe-airdrop/advanced/react/useFactoryImplementations.d.ts +33 -0
  46. package/dist/fhe-airdrop/advanced/react/useFactoryRenounceRole.d.ts +37 -0
  47. package/dist/fhe-airdrop/advanced/react/useFactoryRevokeRole.d.ts +37 -0
  48. package/dist/fhe-airdrop/advanced/react/useFactoryRoleConstants.d.ts +46 -0
  49. package/dist/fhe-airdrop/advanced/react/useFactoryRoleMembers.d.ts +48 -0
  50. package/dist/fhe-airdrop/advanced/react/useFactoryUpgradeabilityPolicy.d.ts +39 -0
  51. package/dist/fhe-airdrop/advanced/react/useMerkleInitCodeHash.d.ts +24 -0
  52. package/dist/fhe-airdrop/advanced/react/useSetComplianceDelegate.d.ts +33 -0
  53. package/dist/fhe-airdrop/advanced/react/useSetComplianceManagerImpl.d.ts +27 -0
  54. package/dist/fhe-airdrop/advanced/react/useSetCompliancePolicy.d.ts +28 -0
  55. package/dist/fhe-airdrop/advanced/react/useSetCustomFee.d.ts +29 -0
  56. package/dist/fhe-airdrop/advanced/react/useSetDefaultDelegateToCompliance.d.ts +31 -0
  57. package/dist/fhe-airdrop/advanced/react/useSetDefaultGasFee.d.ts +30 -0
  58. package/dist/fhe-airdrop/advanced/react/useSetDefaultUpgradeable.d.ts +27 -0
  59. package/dist/fhe-airdrop/advanced/react/useSetEcdsaImplementation.d.ts +34 -0
  60. package/dist/fhe-airdrop/advanced/react/useSetFeeCollector.d.ts +27 -0
  61. package/dist/fhe-airdrop/advanced/react/useSetMaxGasFee.d.ts +33 -0
  62. package/dist/fhe-airdrop/advanced/react/useSetMerkleImplementation.d.ts +30 -0
  63. package/dist/fhe-airdrop/advanced/react/useSetUpgradeabilityPolicy.d.ts +31 -0
  64. package/dist/fhe-airdrop/airdrop-base.d.ts +55 -8
  65. package/dist/fhe-airdrop/campaign.d.ts +61 -20
  66. package/dist/fhe-airdrop/constants.d.ts +9 -1
  67. package/dist/fhe-airdrop/ecdsa.d.ts +13 -0
  68. package/dist/fhe-airdrop/errors.d.ts +87 -0
  69. package/dist/fhe-airdrop/factory.d.ts +62 -22
  70. package/dist/fhe-airdrop/guards.d.ts +133 -4
  71. package/dist/fhe-airdrop/index.cjs +86 -971
  72. package/dist/fhe-airdrop/index.d.cts +4 -4
  73. package/dist/fhe-airdrop/index.d.ts +4 -4
  74. package/dist/fhe-airdrop/index.js +8 -927
  75. package/dist/fhe-airdrop/merkle-tree.d.ts +32 -38
  76. package/dist/fhe-airdrop/merkle.d.ts +52 -31
  77. package/dist/fhe-airdrop/react/_shared.d.ts +13 -0
  78. package/dist/fhe-airdrop/react/index.cjs +997 -87
  79. package/dist/fhe-airdrop/react/index.d.cts +53 -4
  80. package/dist/fhe-airdrop/react/index.d.ts +53 -4
  81. package/dist/fhe-airdrop/react/index.js +887 -27
  82. package/dist/fhe-airdrop/react/keys.d.ts +98 -0
  83. package/dist/fhe-airdrop/react/useAccessEcdsaClaimAmount.d.ts +26 -0
  84. package/dist/fhe-airdrop/react/useAccessMerkleClaimAmount.d.ts +27 -0
  85. package/dist/fhe-airdrop/react/useAddComplianceDelegate.d.ts +37 -0
  86. package/dist/fhe-airdrop/react/useAdminBatchDiscloseBalanceToParties.d.ts +36 -0
  87. package/dist/fhe-airdrop/react/useAdminDiscloseBalanceToParty.d.ts +31 -0
  88. package/dist/fhe-airdrop/react/useAdminGetCurrentBalance.d.ts +27 -0
  89. package/dist/fhe-airdrop/react/useAirdropConfig.d.ts +49 -0
  90. package/dist/fhe-airdrop/react/useAirdropDeploymentMode.d.ts +28 -0
  91. package/dist/fhe-airdrop/react/useAirdropGrantRole.d.ts +35 -0
  92. package/dist/fhe-airdrop/react/useAirdropRenounceRole.d.ts +36 -0
  93. package/dist/fhe-airdrop/react/useAirdropRevokeRole.d.ts +33 -0
  94. package/dist/fhe-airdrop/react/useAirdropRoleAdmin.d.ts +28 -0
  95. package/dist/fhe-airdrop/react/useAirdropRoleConstants.d.ts +67 -0
  96. package/dist/fhe-airdrop/react/useAirdropRoleMembers.d.ts +49 -0
  97. package/dist/fhe-airdrop/react/useAirdropUpgradeToAndCall.d.ts +45 -0
  98. package/dist/fhe-airdrop/react/useBatchDiscloseHandlesToParty.d.ts +32 -0
  99. package/dist/fhe-airdrop/react/useBuildMerkleCampaign.d.ts +68 -0
  100. package/dist/fhe-airdrop/react/useComplianceGrantRole.d.ts +32 -0
  101. package/dist/fhe-airdrop/react/useComplianceHasRole.d.ts +37 -0
  102. package/dist/fhe-airdrop/react/useComplianceInfo.d.ts +50 -0
  103. package/dist/fhe-airdrop/react/useComplianceManagerOf.d.ts +32 -0
  104. package/dist/fhe-airdrop/react/useComplianceRenounceRole.d.ts +38 -0
  105. package/dist/fhe-airdrop/react/useComplianceRevokeRole.d.ts +36 -0
  106. package/dist/fhe-airdrop/react/useComplianceRoleConstants.d.ts +41 -0
  107. package/dist/fhe-airdrop/react/useComplianceRoleMembers.d.ts +45 -0
  108. package/dist/fhe-airdrop/react/useCreateAndFundEcdsaAirdrop.d.ts +55 -0
  109. package/dist/fhe-airdrop/react/useCreateAndFundMerkleAirdrop.d.ts +52 -0
  110. package/dist/fhe-airdrop/react/useDiscloseHandleToParty.d.ts +35 -0
  111. package/dist/fhe-airdrop/react/useEcdsaClaim.d.ts +4 -3
  112. package/dist/fhe-airdrop/react/useEcdsaClaimAndUnwrap.d.ts +27 -0
  113. package/dist/fhe-airdrop/react/useEcdsaDomain.d.ts +41 -0
  114. package/dist/fhe-airdrop/react/useEffectiveDelegateToCompliance.d.ts +26 -0
  115. package/dist/fhe-airdrop/react/useEncryptCampaignAmounts.d.ts +59 -0
  116. package/dist/fhe-airdrop/react/useFactoryFees.d.ts +11 -4
  117. package/dist/fhe-airdrop/react/useIsActiveDelegate.d.ts +29 -0
  118. package/dist/fhe-airdrop/react/useIsAirdrop.d.ts +44 -0
  119. package/dist/fhe-airdrop/react/useIsMerkleRootMutable.d.ts +21 -0
  120. package/dist/fhe-airdrop/react/useIsSignatureValid.d.ts +46 -0
  121. package/dist/fhe-airdrop/react/useMerkleClaim.d.ts +7 -19
  122. package/dist/fhe-airdrop/react/useMerkleClaimAndUnwrap.d.ts +29 -0
  123. package/dist/fhe-airdrop/react/usePlanMerkleCampaign.d.ts +53 -0
  124. package/dist/fhe-airdrop/react/usePreflightClaim.d.ts +46 -0
  125. package/dist/fhe-airdrop/react/usePreflightCreateAirdrop.d.ts +67 -0
  126. package/dist/fhe-airdrop/react/useRefreshComplianceBalance.d.ts +36 -0
  127. package/dist/fhe-airdrop/react/useRescueERC20.d.ts +30 -0
  128. package/dist/fhe-airdrop/react/useRescueOtherConfidentialToken.d.ts +34 -0
  129. package/dist/fhe-airdrop/react/useResolveGasFee.d.ts +30 -0
  130. package/dist/fhe-airdrop/react/useRevokeComplianceDelegate.d.ts +37 -0
  131. package/dist/fhe-airdrop/react/useRotateMerkleRoot.d.ts +52 -0
  132. package/dist/fhe-airdrop/react/useSignClaimAuthorization.d.ts +42 -0
  133. package/dist/fhe-airdrop/react/useWithdrawGasFee.d.ts +37 -0
  134. package/dist/fhe-airdrop/types.d.ts +27 -1
  135. package/dist/fhe-disperse/index.cjs +21 -21
  136. package/dist/fhe-disperse/index.js +2 -2
  137. package/dist/fhe-disperse/react/index.cjs +22 -22
  138. package/dist/fhe-disperse/react/index.js +3 -3
  139. package/dist/fhe-vesting/advanced/index.cjs +5 -5
  140. package/dist/fhe-vesting/advanced/index.js +3 -3
  141. package/dist/fhe-vesting/advanced/react/index.cjs +7 -7
  142. package/dist/fhe-vesting/advanced/react/index.js +4 -4
  143. package/dist/fhe-vesting/index.cjs +8 -8
  144. package/dist/fhe-vesting/index.js +2 -2
  145. package/dist/fhe-vesting/react/index.cjs +114 -114
  146. package/dist/fhe-vesting/react/index.js +3 -3
  147. package/dist/index.cjs +18 -18
  148. package/dist/index.js +1 -1
  149. package/dist/testnet-faucet/index.cjs +14 -14
  150. package/dist/testnet-faucet/index.js +2 -2
  151. package/dist/testnet-faucet/react/index.cjs +8 -8
  152. package/dist/testnet-faucet/react/index.js +3 -3
  153. package/package.json +1 -1
  154. package/dist/chunk-NCVX3K2N.cjs +0 -161
  155. package/dist/chunk-VP2B4WM2.js +0 -154
@@ -0,0 +1,29 @@
1
+ import { type UseMutationResult } from "@tanstack/react-query";
2
+ import type { Address, Hex } from "viem";
3
+ import type { WriteAccountOverride } from "../../airdrop-base.js";
4
+ import { type AirdropClientOptions } from "../../react/_shared.js";
5
+ /** @alpha */
6
+ export interface SetCustomFeeArgs extends WriteAccountOverride {
7
+ /** The creator whose fee is being overridden - NOT the admin sending the transaction. */
8
+ creator: Address;
9
+ /** Wei charged per claim for this creator's future instances, `uint96` on-chain. */
10
+ gasFee: bigint;
11
+ }
12
+ /**
13
+ * Override the factory's default per-claim gas fee for one creator.
14
+ *
15
+ * Requires `FEE_MANAGER_ROLE`.
16
+ *
17
+ * **Invalidates:** `useFactoryCustomFee({ creator })` for the TARGET creator -
18
+ * `variables.creator`, never the sending admin. `account` is the submitter and
19
+ * has no cache entry of its own here, so keying the invalidation off it would
20
+ * refresh the wrong row and leave the edited one stale. Also every
21
+ * `useResolveGasFee` entry, since an override is what that hook resolves.
22
+ *
23
+ * @example
24
+ * const setCustomFee = useSetCustomFee();
25
+ * await setCustomFee.mutateAsync({ creator, gasFee: 0n });
26
+ *
27
+ * @alpha
28
+ */
29
+ export declare function useSetCustomFee(options?: AirdropClientOptions): UseMutationResult<Hex, Error, SetCustomFeeArgs>;
@@ -0,0 +1,31 @@
1
+ import { type UseMutationResult } from "@tanstack/react-query";
2
+ import type { Hex } from "viem";
3
+ import type { WriteAccountOverride } from "../../airdrop-base.js";
4
+ import { type AirdropClientOptions } from "../../react/_shared.js";
5
+ /** @alpha */
6
+ export interface SetDefaultDelegateToComplianceArgs extends WriteAccountOverride {
7
+ /** Whether new instances default to delegating compliance disclosure to the platform delegate. */
8
+ on: boolean;
9
+ }
10
+ /**
11
+ * Set the factory-wide default for whether new instances delegate compliance
12
+ * disclosure to the platform delegate. Requires `COMPLIANCE_WIRING_ROLE`.
13
+ *
14
+ * **Ordering is load-bearing.** `on: true` reverts `ZeroComplianceDelegate`
15
+ * unless {@link useSetComplianceDelegate} has already set a delegate - read
16
+ * {@link useFactoryComplianceDelegate} first and sequence the two writes.
17
+ *
18
+ * **Invalidates:** the `fn "effectiveDelegateToCompliance"` PREFIX and the
19
+ * `fn "compliancePolicy"` PREFIX - every cached creator at once, because this
20
+ * write is chain-wide: any creator without an override moves with the
21
+ * default, and {@link useFactoryCompliancePolicy}'s bundle carries the
22
+ * resolved `effective` field. Contrast {@link useSetCompliancePolicy}, which
23
+ * stays keyed on the one creator it targets.
24
+ *
25
+ * @example
26
+ * const setDefault = useSetDefaultDelegateToCompliance();
27
+ * await setDefault.mutateAsync({ on: true });
28
+ *
29
+ * @alpha
30
+ */
31
+ export declare function useSetDefaultDelegateToCompliance(options?: AirdropClientOptions): UseMutationResult<Hex, Error, SetDefaultDelegateToComplianceArgs>;
@@ -0,0 +1,30 @@
1
+ import { type UseMutationResult } from "@tanstack/react-query";
2
+ import type { Hex } from "viem";
3
+ import type { WriteAccountOverride } from "../../airdrop-base.js";
4
+ import { type AirdropClientOptions } from "../../react/_shared.js";
5
+ /** @alpha */
6
+ export interface SetDefaultGasFeeArgs extends WriteAccountOverride {
7
+ /** Wei charged per claim, `uint96` on-chain. */
8
+ gasFee: bigint;
9
+ }
10
+ /**
11
+ * Set the per-claim gas fee that new instances default to when their creator
12
+ * has no `setCustomFee` override.
13
+ *
14
+ * Requires `FEE_MANAGER_ROLE`. Affects only instances created afterwards: an
15
+ * instance's `gasFee()` is baked in at create time, so no deployed campaign's
16
+ * fee changes.
17
+ *
18
+ * **Invalidates:** this factory's `useFactoryFees` entry (fn `"fees"`) and every
19
+ * `useResolveGasFee` entry - the default is what resolves for every creator
20
+ * without an override, so all of them move at once. Deliberately NOT any
21
+ * instance's fn `"gasFee"` key: those are frozen at create and invalidating
22
+ * them would refetch unchanged values.
23
+ *
24
+ * @example
25
+ * const setDefaultFee = useSetDefaultGasFee();
26
+ * await setDefaultFee.mutateAsync({ gasFee: parseEther("0.0001") });
27
+ *
28
+ * @alpha
29
+ */
30
+ export declare function useSetDefaultGasFee(options?: AirdropClientOptions): UseMutationResult<Hex, Error, SetDefaultGasFeeArgs>;
@@ -0,0 +1,27 @@
1
+ import { type UseMutationResult } from "@tanstack/react-query";
2
+ import type { Hex } from "viem";
3
+ import type { WriteAccountOverride } from "../../airdrop-base.js";
4
+ import { type AirdropClientOptions } from "../../react/_shared.js";
5
+ /** @alpha */
6
+ export interface SetDefaultUpgradeableArgs extends WriteAccountOverride {
7
+ /** Whether creators without an override may deploy `mode: "uups"`. */
8
+ allowed: boolean;
9
+ }
10
+ /**
11
+ * Set the factory-wide default for whether a `create*` may deploy
12
+ * `mode: "uups"`. Requires `UPGRADE_MANAGER_ROLE`.
13
+ *
14
+ * **Invalidates:** the `fn "effectiveUpgradeable"`,
15
+ * `fn "upgradeabilityPolicy"` and `fn `preflightCreate`` PREFIXES.
16
+ * Prefix invalidation is correct here because the write is chain-wide: every
17
+ * cached creator without an override moves with the default, and a preflight
18
+ * result is exactly the thing that flips between allowed and
19
+ * `UpgradeabilityNotAllowedError`.
20
+ *
21
+ * @example
22
+ * const setDefault = useSetDefaultUpgradeable();
23
+ * await setDefault.mutateAsync({ allowed: false });
24
+ *
25
+ * @alpha
26
+ */
27
+ export declare function useSetDefaultUpgradeable(options?: AirdropClientOptions): UseMutationResult<Hex, Error, SetDefaultUpgradeableArgs>;
@@ -0,0 +1,34 @@
1
+ import { type UseMutationResult } from "@tanstack/react-query";
2
+ import type { Address, Hex } from "viem";
3
+ import type { WriteAccountOverride } from "../../airdrop-base.js";
4
+ import { type AirdropClientOptions } from "../../react/_shared.js";
5
+ /** @alpha */
6
+ export interface SetEcdsaImplementationArgs extends WriteAccountOverride {
7
+ /** The new ECDSA implementation. The zero address reverts. */
8
+ implementation: Address;
9
+ }
10
+ /**
11
+ * Point future `createEcdsaAirdrop*` calls at a new ECDSA implementation.
12
+ *
13
+ * Requires `IMPL_MANAGER_ROLE`. Deployed instances are untouched - a clone
14
+ * stays bound to the implementation live when it was created.
15
+ *
16
+ * **Moving this pointer moves every future predicted address.** Any campaign
17
+ * plan built before this write is stale, and on an immutable-root instance
18
+ * its entries would be unclaimable; that is what `PredictionDriftError`
19
+ * exists to catch.
20
+ *
21
+ * **Invalidates:** `useFactoryImplementations` (fn `"implementations"`), plus
22
+ * the fn `"getEcdsaInitCodeHash"`, `"predictEcdsaAirdropAddress"` and
23
+ * ``preflightCreate`` PREFIXES - every cached args combination of each,
24
+ * because the init-code hash, the predicted address and the create preflight
25
+ * all shift together with the pointer. Invalidating the predictions is what
26
+ * stops a mounted UI offering a dead address.
27
+ *
28
+ * @example
29
+ * const setEcdsaImpl = useSetEcdsaImplementation();
30
+ * await setEcdsaImpl.mutateAsync({ implementation: newEcdsaImpl });
31
+ *
32
+ * @alpha
33
+ */
34
+ export declare function useSetEcdsaImplementation(options?: AirdropClientOptions): UseMutationResult<Hex, Error, SetEcdsaImplementationArgs>;
@@ -0,0 +1,27 @@
1
+ import { type UseMutationResult } from "@tanstack/react-query";
2
+ import type { Address, Hex } from "viem";
3
+ import type { WriteAccountOverride } from "../../airdrop-base.js";
4
+ import { type AirdropClientOptions } from "../../react/_shared.js";
5
+ /** @alpha */
6
+ export interface SetFeeCollectorArgs extends WriteAccountOverride {
7
+ /** Where accrued claim-fee ETH withdraws to. The zero address reverts. */
8
+ feeCollector: Address;
9
+ }
10
+ /**
11
+ * Redirect where the factory's accrued claim-fee ETH withdraws to.
12
+ *
13
+ * Requires `FEE_MANAGER_ROLE`. The headless factory method takes positional
14
+ * args, so this hook adapts its object-shaped variables to
15
+ * `setFeeCollector(feeCollector, account?)`.
16
+ *
17
+ * **Invalidates:** this factory's `useFactoryFees` entry (fn `"fees"`), which
18
+ * bundles `feeCollector` with `defaultGasFee`. Nothing else moves - deployed
19
+ * instances hold no copy of the collector.
20
+ *
21
+ * @example
22
+ * const setCollector = useSetFeeCollector();
23
+ * await setCollector.mutateAsync({ feeCollector: treasuryAddress });
24
+ *
25
+ * @alpha
26
+ */
27
+ export declare function useSetFeeCollector(options?: AirdropClientOptions): UseMutationResult<Hex, Error, SetFeeCollectorArgs>;
@@ -0,0 +1,33 @@
1
+ import { type UseMutationResult } from "@tanstack/react-query";
2
+ import type { Hex } from "viem";
3
+ import type { WriteAccountOverride } from "../../airdrop-base.js";
4
+ import { type AirdropClientOptions } from "../../react/_shared.js";
5
+ /** @alpha */
6
+ export interface SetMaxGasFeeArgs extends WriteAccountOverride {
7
+ /** The factory-wide ceiling in wei, `uint96` on-chain. `0n` admits only a zero fee. */
8
+ maxGasFee: bigint;
9
+ }
10
+ /**
11
+ * Set the factory's ceiling on every fee `setDefaultGasFee` / `setCustomFee` may
12
+ * configure, and on the fee resolved at create.
13
+ *
14
+ * Requires `DEFAULT_ADMIN_ROLE`, deliberately not `FEE_MANAGER_ROLE` (audit-09):
15
+ * the fee manager moves fees only within a bound the admin owns. This is the
16
+ * one fee control that is not a fee-manager operation.
17
+ *
18
+ * **Lowering it does not rewrite an already-configured fee.** The stale value
19
+ * stays in storage and reverts `GasFeeExceedsMaximum` at the next create until
20
+ * it is lowered too, so a reduction is two steps, not one.
21
+ *
22
+ * **Invalidates:** this factory's `useFactoryFees` entry (fn `"fees"`, which
23
+ * carries `maxGasFee`) and every `useResolveGasFee` entry, since the ceiling
24
+ * bounds what any creator's fee can resolve to. Deliberately NOT any instance's
25
+ * fn `"gasFee"` key - an instance's fee is frozen at create and cannot move.
26
+ *
27
+ * @example
28
+ * const setCeiling = useSetMaxGasFee();
29
+ * await setCeiling.mutateAsync({ maxGasFee: parseEther("0.5") });
30
+ *
31
+ * @alpha
32
+ */
33
+ export declare function useSetMaxGasFee(options?: AirdropClientOptions): UseMutationResult<Hex, Error, SetMaxGasFeeArgs>;
@@ -0,0 +1,30 @@
1
+ import { type UseMutationResult } from "@tanstack/react-query";
2
+ import type { Address, Hex } from "viem";
3
+ import type { WriteAccountOverride } from "../../airdrop-base.js";
4
+ import { type AirdropClientOptions } from "../../react/_shared.js";
5
+ /** @alpha */
6
+ export interface SetMerkleImplementationArgs extends WriteAccountOverride {
7
+ /** The new Merkle implementation. The zero address reverts. */
8
+ implementation: Address;
9
+ }
10
+ /**
11
+ * Point future `createMerkleAirdrop*` calls at a new Merkle implementation.
12
+ *
13
+ * Requires `IMPL_MANAGER_ROLE`. Deployed instances are untouched.
14
+ *
15
+ * **Same prediction-drift hazard as {@link useSetEcdsaImplementation}, with a
16
+ * worse blast radius.** Merkle campaigns are commonly immutable-root: a plan
17
+ * whose entries were bound to an address predicted before this write has no
18
+ * on-chain repair, so re-plan rather than re-point.
19
+ *
20
+ * **Invalidates:** `useFactoryImplementations` (fn `"implementations"`), plus
21
+ * the fn `"getMerkleInitCodeHash"`, `"predictMerkleAirdropAddress"` and
22
+ * ``preflightCreate`` PREFIXES - every cached args combination of each.
23
+ *
24
+ * @example
25
+ * const setMerkleImpl = useSetMerkleImplementation();
26
+ * await setMerkleImpl.mutateAsync({ implementation: newMerkleImpl });
27
+ *
28
+ * @alpha
29
+ */
30
+ export declare function useSetMerkleImplementation(options?: AirdropClientOptions): UseMutationResult<Hex, Error, SetMerkleImplementationArgs>;
@@ -0,0 +1,31 @@
1
+ import { type UseMutationResult } from "@tanstack/react-query";
2
+ import type { Address, Hex } from "viem";
3
+ import type { WriteAccountOverride } from "../../airdrop-base.js";
4
+ import { type AirdropClientOptions } from "../../react/_shared.js";
5
+ /** @alpha */
6
+ export interface SetUpgradeabilityPolicyArgs extends WriteAccountOverride {
7
+ /** The creator the override applies to - not the admin sending the transaction. */
8
+ creator: Address;
9
+ /** Whether that creator may deploy `mode: "uups"`. */
10
+ allowed: boolean;
11
+ }
12
+ /**
13
+ * Override the factory's default upgradeability policy for one creator.
14
+ * Requires `UPGRADE_MANAGER_ROLE`.
15
+ *
16
+ * This is the write that flips whether that creator's next `mode: "uups"`
17
+ * create is refused with `UpgradeabilityNotAllowedError`.
18
+ *
19
+ * **Invalidates:** `fn "effectiveUpgradeable"` and
20
+ * `fn "upgradeabilityPolicy"` keyed on `args.creator` - the TARGET creator,
21
+ * never the sending admin - plus the `fn `preflightCreate`` PREFIX,
22
+ * which is keyed on the whole create payload rather than the creator alone
23
+ * and so cannot be narrowed here.
24
+ *
25
+ * @example
26
+ * const setPolicy = useSetUpgradeabilityPolicy();
27
+ * await setPolicy.mutateAsync({ creator, allowed: true });
28
+ *
29
+ * @alpha
30
+ */
31
+ export declare function useSetUpgradeabilityPolicy(options?: AirdropClientOptions): UseMutationResult<Hex, Error, SetUpgradeabilityPolicyArgs>;
@@ -137,7 +137,7 @@ export interface WriteAccountOverride {
137
137
  * do not care about (an admin panel listing campaigns, say). The ECDSA and
138
138
  * Merkle clients extend it and add their own claim path.
139
139
  *
140
- * What it encapsulates beyond the raw ABI is the encrypted-view protocol: five
140
+ * What it encapsulates beyond the raw ABI is the encrypted-view protocol: six
141
141
  * of the contract's disclosure entrypoints look like getters and are not —
142
142
  * they mutate ACL state, so they are transactions, and their result must be
143
143
  * recovered from the receipt. See {@link extractGrantedHandle}.
@@ -217,8 +217,12 @@ export declare class AirdropBaseClient {
217
217
  * Sweep a plain ERC-20 that was sent to the instance by mistake. Requires
218
218
  * `RESCUER_ROLE`.
219
219
  *
220
- * The campaign's own token is ERC-7984, not ERC-20, so it cannot be reached
221
- * through this path — use {@link withdrawConfidential} for the pool.
220
+ * Passing the campaign's own token reverts `CannotRescueAirdropToken`
221
+ * (audit-05), matching {@link rescueOtherConfidentialToken}. ERC-7984 and
222
+ * ERC-20 are not disjoint in practice - a wrapper token answers both
223
+ * interfaces - so "the pool token is confidential, therefore out of reach
224
+ * here" was never a guarantee, only an assumption. Use
225
+ * {@link withdrawConfidential} for the pool.
222
226
  *
223
227
  * @returns The transaction hash.
224
228
  */
@@ -469,10 +473,38 @@ export declare class AirdropBaseClient {
469
473
  * @alpha
470
474
  */
471
475
  deploymentMode(): Promise<DeploymentMode>;
476
+ /**
477
+ * Re-grant the compliance-manager clone on the instance's current pool
478
+ * balance, and return the handle it was granted on.
479
+ *
480
+ * **Permissionless, and deliberately so** (audit-04). The token rotates the
481
+ * instance's balance handle on every incoming transfer, including one no
482
+ * airdrop code observes - a third party transferring in directly - and
483
+ * grants the fresh handle to the token and the holder only. Without this the
484
+ * compliance clone's grant can be stranded on a handle the token has already
485
+ * replaced, with no admin necessarily around to restore it. There is no
486
+ * argument to abuse: the only handle read is `address(this)`'s own balance,
487
+ * and the only grantee is the clone wired at initialization.
488
+ *
489
+ * This is therefore the normative way to obtain a readable live-balance
490
+ * handle - and it is a **snapshot, not a subscription**. Grants are
491
+ * append-only, so the handle this returns stays readable forever; but the
492
+ * next incoming transfer rotates the instance to a NEW handle the clone was
493
+ * never granted on. A compliance reader that refreshes once and stops is
494
+ * reading a stale balance, not a live one. Call it again after any transfer
495
+ * in, or before each read.
496
+ *
497
+ * @returns `{ handle, hash }` - the handle the compliance clone may now decrypt.
498
+ * @throws {@link ReceiptEventNotFoundError} when the transaction granted no ACL to the clone.
499
+ */
500
+ refreshComplianceBalance(args?: WriteAccountOverride): Promise<EncryptedViewResult>;
472
501
  /**
473
502
  * Read the instance's own remaining pool balance as a handle the **caller**
474
503
  * can decrypt. Requires `DISCLOSURE_ADMIN_ROLE`.
475
504
  *
505
+ * Also re-grants the compliance-manager clone on the same handle (audit-04),
506
+ * so an admin read doubles as a {@link refreshComplianceBalance}.
507
+ *
476
508
  * @returns `{ handle, hash }` — pass `handle` to the Zama relayer's `userDecrypt`.
477
509
  * @throws {@link ReceiptEventNotFoundError} when the transaction granted no ACL to the caller.
478
510
  */
@@ -515,11 +547,18 @@ export declare class AirdropBaseClient {
515
547
  /**
516
548
  * Grant `party` decrypt access to a handle you already hold.
517
549
  *
518
- * Two gates apply on-chain: the caller must itself be allowed on the handle
519
- * (bypassed by `DISCLOSURE_ADMIN_ROLE`), and the *instance* must be allowed
520
- * on it — so an arbitrary handle from another contract cannot be laundered
521
- * through this campaign. A failure of the first surfaces as
522
- * `FheHandleNotAllowedError`.
550
+ * Two gates apply on-chain. Gate #1: the handle must be **persistently**
551
+ * user-decryptable in the `(caller, instance)` context - BOTH legs, and a
552
+ * transient allowance does not satisfy either (audit-06). `DISCLOSURE_ADMIN_ROLE`
553
+ * bypasses gate #1 only. Gate #2: the instance must be allowed on the handle,
554
+ * so an arbitrary handle from another contract cannot be laundered through
555
+ * this campaign.
556
+ *
557
+ * **The transient case is the trap.** An `euint64` that just came back from
558
+ * an FHE op carries a transient allowance, which used to be enough here and
559
+ * no longer is. Handles worth disclosing come from the encrypted views on
560
+ * this client, whose grants are persistent. A gate #1 failure surfaces as
561
+ * `FheHandleNotAllowedError` carrying the offending handle.
523
562
  *
524
563
  * @param args.handle An existing `euint64` handle — a public pointer, not a value.
525
564
  * @returns The transaction hash. No new handle is produced.
@@ -588,6 +627,14 @@ export declare class AirdropBaseClient {
588
627
  protected mapRevert(method: string, err: unknown, account: Account | Address): TokenOpsSdkError;
589
628
  protected requireWallet(method: string): WalletClient;
590
629
  protected resolveAccount(wallet: WalletClient, override: Account | Address | undefined, method: string): Account | Address;
630
+ /**
631
+ * The address that will actually send the transaction, as a plain `Address`.
632
+ *
633
+ * Needed by any method whose arguments must be validated against the sender before
634
+ * the write — on the Merkle variant the claim identity, the payout destination and
635
+ * the submitter are three separate addresses with rules between them.
636
+ */
637
+ protected resolveSender(override: Account | Address | undefined, method: string): Address;
591
638
  }
592
639
  /**
593
640
  * Create an {@link AirdropBaseClient}. Mirrors viem's `create*` convention.
@@ -46,12 +46,45 @@ export declare function validateCampaignRecipients(recipients: readonly Campaign
46
46
  * pattern as `buildMerkleTreeInternal` in `./merkle-tree.js`.
47
47
  */
48
48
  export declare function validateCampaignRecipientsInternal(recipients: readonly CampaignRecipient[], method: string): void;
49
+ /**
50
+ * Who will submit the claims, for every builder that encrypts a roster.
51
+ *
52
+ * Follows the same shared-option pattern as `WriteAccountOverride`, because the choice
53
+ * applies identically to all four builders and is frozen once the root is published.
54
+ *
55
+ * @alpha
56
+ */
57
+ export interface CampaignSubmitterOption {
58
+ /**
59
+ * The single address that will send every `claim` in this campaign.
60
+ *
61
+ * Omit for a **self-claim** campaign: each recipient's input is bound to that
62
+ * recipient, one relayer request each, and only they can claim.
63
+ *
64
+ * Set it for a **relayed** campaign: the whole roster is bound to this one address and
65
+ * batched, so a single `inputProof` covers up to 32 recipients and only this address
66
+ * can submit. That batching is the point — one proof cannot be bound to many
67
+ * addresses, so per-recipient binding and batching are mutually exclusive.
68
+ *
69
+ * An input ciphertext packs at most 2048 bits, so a `euint64` roster is chunked at 32
70
+ * recipients per request; a longer roster simply issues more requests. Nothing about a
71
+ * claim changes, since every chunk's proof is bound to the same submitter.
72
+ *
73
+ * Either way the leaf still commits each recipient's own `account`, so payout and
74
+ * accounting are unaffected by who submits.
75
+ *
76
+ * **Frozen at publication.** An FHEVM handle encodes its `(instance, userAddress)`
77
+ * binding, so re-pointing a leaf at a different submitter means re-encrypting, which
78
+ * changes the handle and therefore the root. Choose before publishing, not after.
79
+ */
80
+ submitter?: Address;
81
+ }
49
82
  /**
50
83
  * Inputs for {@link buildMerkleCampaign}.
51
84
  *
52
85
  * @alpha
53
86
  */
54
- export interface BuildMerkleCampaignArgs {
87
+ export interface BuildMerkleCampaignArgs extends CampaignSubmitterOption {
55
88
  /** The LIVE `MerkleConfidentialAirdrop` instance every input is bound to. Not the factory, not the implementation. */
56
89
  instance: Address;
57
90
  recipients: readonly CampaignRecipient[];
@@ -63,7 +96,9 @@ export interface BuildMerkleCampaignArgs {
63
96
  * @alpha
64
97
  */
65
98
  export interface EncryptedCampaignLeaf extends MerkleLeafInput {
66
- /** The KMS input proof binding `handle` to `(instance, recipient)`. Required at claim time, unused by the tree. */
99
+ /** The only address that can submit this leaf — what `handle`/`inputProof` are bound to. */
100
+ boundTo: Address;
101
+ /** The KMS input proof binding `handle` to `(instance, boundTo)`. Required at claim time, unused by the tree. */
67
102
  inputProof: Hex;
68
103
  }
69
104
  /**
@@ -71,7 +106,7 @@ export interface EncryptedCampaignLeaf extends MerkleLeafInput {
71
106
  *
72
107
  * @alpha
73
108
  */
74
- export interface EncryptCampaignAmountsArgs {
109
+ export interface EncryptCampaignAmountsArgs extends CampaignSubmitterOption {
75
110
  /** The LIVE `MerkleConfidentialAirdrop` instance every input is bound to. Not the factory, not the implementation. */
76
111
  instance: Address;
77
112
  recipients: readonly CampaignRecipient[];
@@ -84,17 +119,17 @@ export interface EncryptCampaignAmountsArgs {
84
119
  * publishing a root, or to hand them to something else that builds the tree.
85
120
  * If you just want a campaign, {@link buildMerkleCampaign} does both.
86
121
  *
87
- * **One relayer request per recipient, issued concurrently.** Each input binds
88
- * to `(instance, that recipient)`, so they cannot share a proof: a single
89
- * batched proof binds every value to one account and produces a campaign only
90
- * that account can claim against.
122
+ * **Request count follows `submitter`.** Omitted: one relayer request per recipient,
123
+ * issued concurrently, each bound to that recipient. Set: one batched request per 32
124
+ * recipients (the 2048-bit input-ciphertext limit), every leaf claimable only by that
125
+ * submitter.
91
126
  *
92
127
  * **The output is not reproducible.** Encryption is randomised, so calling this
93
128
  * twice with the same roster yields different handles and therefore a different
94
129
  * root. Persist what you get back; you cannot regenerate it.
95
130
  *
96
131
  * @param args The live instance, the roster, and an eager or lazy encryptor.
97
- * @returns One `{ recipient, handle, inputProof }` per roster entry, in roster order.
132
+ * @returns One `{ account, boundTo, handle, inputProof }` per roster entry, in roster order.
98
133
  * @throws {@link InvalidArgumentError} on any roster problem {@link validateCampaignRecipients} rejects, or a zero `instance`.
99
134
  * @throws {@link MissingEncryptorError} when `encryptor` resolves to `undefined`.
100
135
  *
@@ -106,8 +141,9 @@ export interface EncryptCampaignAmountsArgs {
106
141
  */
107
142
  export declare function encryptCampaignAmounts(args: EncryptCampaignAmountsArgs): Promise<readonly EncryptedCampaignLeaf[]>;
108
143
  /**
109
- * Encrypt every recipient's cumulative total against their own address, then
110
- * build the tree those ciphertexts belong to.
144
+ * Encrypt every recipient's cumulative total, then build the tree those ciphertexts
145
+ * belong to. Binding follows `submitter`: omitted, each input is bound to its own
146
+ * recipient; set, the whole roster is bound to that one submitter.
111
147
  *
112
148
  * Use this on the **mutable-root** path: the instance already exists, so its
113
149
  * address is known and encryption can bind to it directly. Publish the returned
@@ -124,10 +160,9 @@ export declare function encryptCampaignAmounts(args: EncryptCampaignAmountsArgs)
124
160
  * claim, and no amount of on-chain data will reconstruct it. Persist the
125
161
  * entries when this resolves and serve each recipient theirs.
126
162
  *
127
- * **One relayer request per recipient, issued concurrently.** Each input has a
128
- * different `userAddress`, so they cannot share a proof — see the note on
129
- * `encryptUint64Batch` below. Large rosters fan out correspondingly; chunk the
130
- * roster yourself if your relayer rate-limits.
163
+ * **Relayer load follows `submitter`.** A self-claim roster fans out one request per
164
+ * recipient; a relayed roster issues one per 32. Either way, split the roster across
165
+ * calls yourself if your relayer rate-limits.
131
166
  *
132
167
  * **Already hold the handles?** This function encrypts unconditionally, and
133
168
  * encryption is randomised — so re-encrypting handles that exist elsewhere
@@ -146,17 +181,17 @@ export declare function encryptCampaignAmounts(args: EncryptCampaignAmountsArgs)
146
181
  * encryptor,
147
182
  * });
148
183
  * await airdrop.setMerkleRoot({ newRoot: root });
149
- * // then hand `entries[i]` to `entries[i].recipient`, out of band
184
+ * // then hand `entries[i]` to `entries[i].account`, out of band
150
185
  *
151
186
  * @alpha
152
187
  */
153
- export declare function buildMerkleCampaign({ instance, recipients, encryptor, }: BuildMerkleCampaignArgs): Promise<BuiltCampaign>;
188
+ export declare function buildMerkleCampaign({ instance, recipients, encryptor, submitter, }: BuildMerkleCampaignArgs): Promise<BuiltCampaign>;
154
189
  /**
155
190
  * Inputs for {@link planMerkleCampaign}.
156
191
  *
157
192
  * @alpha
158
193
  */
159
- export interface PlanMerkleCampaignArgs {
194
+ export interface PlanMerkleCampaignArgs extends CampaignSubmitterOption {
160
195
  factory: ConfidentialAirdropFactoryClient;
161
196
  /** The exact params the subsequent `createMerkleAirdrop` will use, except `merkleRoot` — supply the planned root there. */
162
197
  params: MerkleAirdropParams;
@@ -236,13 +271,13 @@ export interface PlannedCampaign extends BuiltCampaign {
236
271
  *
237
272
  * @alpha
238
273
  */
239
- export declare function planMerkleCampaign({ factory, params, mode, creator, userSalt, recipients, encryptor, }: PlanMerkleCampaignArgs): Promise<PlannedCampaign>;
274
+ export declare function planMerkleCampaign({ factory, params, mode, creator, userSalt, recipients, encryptor, submitter, }: PlanMerkleCampaignArgs): Promise<PlannedCampaign>;
240
275
  /**
241
276
  * Inputs for {@link rotateMerkleRoot}.
242
277
  *
243
278
  * @alpha
244
279
  */
245
- export interface RotateMerkleRootArgs extends WriteAccountOverride {
280
+ export interface RotateMerkleRootArgs extends WriteAccountOverride, CampaignSubmitterOption {
246
281
  /** The live instance. Its `address` is read off the client — nothing is predicted here. */
247
282
  airdrop: MerkleAirdropClient;
248
283
  /** The FULL updated roster: cumulative totals, not the deltas since the last root. */
@@ -276,6 +311,12 @@ export interface RotatedCampaign extends BuiltCampaign {
276
311
  * entries to every recipient**, including the ones whose total was unchanged —
277
312
  * the chain stores only the root, so an un-updated recipient is simply stuck.
278
313
  *
314
+ * **`submitter` is not remembered across rotations.** It is read from THIS call, not from
315
+ * the campaign being replaced, so omitting it on a rotation rebuilds a relayed campaign as
316
+ * a self-claim one - every new entry becomes claimable only by its own recipient, and the
317
+ * relayer that was settling for them can no longer submit anything. Pass the same
318
+ * `submitter` again to keep a relayed campaign relayed.
319
+ *
279
320
  * Requires `MERKLE_ADMIN_ROLE` on the instance and an instance created with
280
321
  * `isMerkleRootMutable: true`.
281
322
  *
@@ -294,4 +335,4 @@ export interface RotatedCampaign extends BuiltCampaign {
294
335
  *
295
336
  * @alpha
296
337
  */
297
- export declare function rotateMerkleRoot({ airdrop, recipients, encryptor, account, }: RotateMerkleRootArgs): Promise<RotatedCampaign>;
338
+ export declare function rotateMerkleRoot({ airdrop, recipients, encryptor, submitter, account, }: RotateMerkleRootArgs): Promise<RotatedCampaign>;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @alpha
5
5
  */
6
- export declare const AIRDROP_CONTRACTS_COMMIT = "8e5b144bdbcdf35b9f36b62f5257d795bf954e8e";
6
+ export declare const AIRDROP_CONTRACTS_COMMIT = "c5c12c2087f61bcd5bd1daa802563ed3cd68f002";
7
7
  /**
8
8
  * Deployment shell selected at create time. Mirrors the contract's `DeploymentMode` enum
9
9
  * (`IConfidentialAirdropTypes.sol`): `enum DeploymentMode { Clone, UUPS }`.
@@ -31,3 +31,11 @@ export declare const DEDUP_MODE: {
31
31
  };
32
32
  /** @alpha */
33
33
  export type DedupMode = keyof typeof DEDUP_MODE;
34
+ /**
35
+ * The largest value `CommonAirdropParams.maxAcceptedGasFee` can carry - the
36
+ * `uint96` ceiling. Passing it accepts whatever fee the factory resolves, which
37
+ * is the opt-out, not the default.
38
+ *
39
+ * @alpha
40
+ */
41
+ export declare const UINT96_MAX: bigint;
@@ -186,11 +186,24 @@ export declare class EcdsaAirdropClient extends AirdropBaseClient {
186
186
  * consuming either replay guard — the same input can still be claimed for
187
187
  * real afterwards. No fee.
188
188
  *
189
+ * **It is repeatable, not unconditional** (audit-07). While the claim is
190
+ * still available this may be called any number of times; once it is not,
191
+ * this reverts with the same error the consuming claim would raise, in the
192
+ * same order: the mode's dedup slot first (`AddressAlreadyClaimed` /
193
+ * `DedupIdAlreadyClaimed`), the EIP-712 digest second (`SignatureAlreadyUsed`).
194
+ * A rejected preview performs no FHE op, grants no ACL and emits nothing.
195
+ *
196
+ * So this is not a probe for "has this been claimed" - use
197
+ * {@link isSignatureValid}, which never reverts and answers the same
198
+ * question for free. Reach for this when you want the AMOUNT.
199
+ *
189
200
  * An encrypted view: the contract calls `FHE.allow(amount, msg.sender)`, so
190
201
  * the result is recovered from the receipt's ACL `Allowed` event, never
191
202
  * from a simulation. See {@link AirdropBaseClient}'s class TSDoc.
192
203
  *
193
204
  * @returns `{ handle, hash }` — pass `handle` to the Zama relayer's `userDecrypt`.
205
+ * @throws {@link AlreadyClaimedError} when this recipient's dedup slot is consumed.
206
+ * @throws {@link DedupIdConsumedError} when this `dedupId`'s slot is consumed.
194
207
  */
195
208
  getClaimAmount(args: GetClaimAmountArgs): Promise<EncryptedViewResult>;
196
209
  /**