@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.
- package/CHANGELOG.md +67 -2
- package/README.md +14 -8
- package/dist/{chunk-PUX5VXDB.cjs → chunk-4AWQJQXY.cjs} +1415 -69
- package/dist/{chunk-74QFZ5MK.js → chunk-4IB4IY5Y.js} +1 -1
- package/dist/{chunk-DZHYSUGY.js → chunk-6HCT4QIX.js} +12 -5
- package/dist/{chunk-FGEB7RMY.cjs → chunk-6XOAYDC6.cjs} +4 -4
- package/dist/{chunk-XAYGD4E4.cjs → chunk-AHU2HMNE.cjs} +3 -3
- package/dist/{chunk-6NAVMWZQ.js → chunk-BPIVVCSQ.js} +2 -2
- package/dist/{chunk-GKKDAW44.js → chunk-BXX5TETM.js} +1401 -59
- package/dist/{chunk-456VDDA3.js → chunk-GCJFAY4X.js} +78 -25
- package/dist/{chunk-CTED3MTR.cjs → chunk-GKYZQJGP.cjs} +82 -29
- package/dist/{chunk-JZLGCTGK.cjs → chunk-IEKTGJ4J.cjs} +2 -2
- package/dist/{chunk-6PXXGACR.cjs → chunk-JVNJSDQ4.cjs} +2 -2
- package/dist/{chunk-O5676ZWY.js → chunk-LEYYG4RF.js} +232 -6
- package/dist/{chunk-335Z2W67.js → chunk-NGU4JYIR.js} +1 -1
- package/dist/{chunk-5576FRT3.cjs → chunk-PG3WXT3K.cjs} +12 -5
- package/dist/{chunk-H5POPGOZ.js → chunk-PK6Q6J5F.js} +1 -1
- package/dist/chunk-TND5NDV7.cjs +263 -0
- package/dist/chunk-U3TBQRT7.js +253 -0
- package/dist/{chunk-EAJ7SYHE.js → chunk-WRWRA4TN.js} +1 -1
- package/dist/{chunk-JQYC66TO.cjs → chunk-YABHXJNH.cjs} +5 -5
- package/dist/{chunk-M4IT6DNJ.cjs → chunk-YTIYTV4K.cjs} +236 -4
- package/dist/core/addresses.d.ts +4 -4
- package/dist/core/errors.d.ts +1 -1
- package/dist/fhe/types.d.ts +2 -2
- package/dist/fhe-airdrop/abis/airdrop-base.d.ts +19 -0
- package/dist/fhe-airdrop/abis/ecdsa.d.ts +19 -0
- package/dist/fhe-airdrop/abis/factory.d.ts +113 -0
- package/dist/fhe-airdrop/abis/merkle.d.ts +43 -12
- package/dist/fhe-airdrop/advanced/index.cjs +4 -4
- package/dist/fhe-airdrop/advanced/index.js +1 -1
- package/dist/fhe-airdrop/advanced/react/index.cjs +620 -9
- package/dist/fhe-airdrop/advanced/react/index.d.cts +35 -0
- package/dist/fhe-airdrop/advanced/react/index.d.ts +35 -0
- package/dist/fhe-airdrop/advanced/react/index.js +590 -7
- package/dist/fhe-airdrop/advanced/react/useClearCompliancePolicy.d.ts +28 -0
- package/dist/fhe-airdrop/advanced/react/useClearUpgradeabilityPolicy.d.ts +26 -0
- package/dist/fhe-airdrop/advanced/react/useDisableCustomFee.d.ts +26 -0
- package/dist/fhe-airdrop/advanced/react/useEcdsaInitCodeHash.d.ts +30 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryComplianceDelegate.d.ts +25 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryCompliancePolicy.d.ts +38 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryCustomFee.d.ts +24 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryGrantRole.d.ts +32 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryHasRole.d.ts +27 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryImplementations.d.ts +33 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryRenounceRole.d.ts +37 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryRevokeRole.d.ts +37 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryRoleConstants.d.ts +46 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryRoleMembers.d.ts +48 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryUpgradeabilityPolicy.d.ts +39 -0
- package/dist/fhe-airdrop/advanced/react/useMerkleInitCodeHash.d.ts +24 -0
- package/dist/fhe-airdrop/advanced/react/useSetComplianceDelegate.d.ts +33 -0
- package/dist/fhe-airdrop/advanced/react/useSetComplianceManagerImpl.d.ts +27 -0
- package/dist/fhe-airdrop/advanced/react/useSetCompliancePolicy.d.ts +28 -0
- package/dist/fhe-airdrop/advanced/react/useSetCustomFee.d.ts +29 -0
- package/dist/fhe-airdrop/advanced/react/useSetDefaultDelegateToCompliance.d.ts +31 -0
- package/dist/fhe-airdrop/advanced/react/useSetDefaultGasFee.d.ts +30 -0
- package/dist/fhe-airdrop/advanced/react/useSetDefaultUpgradeable.d.ts +27 -0
- package/dist/fhe-airdrop/advanced/react/useSetEcdsaImplementation.d.ts +34 -0
- package/dist/fhe-airdrop/advanced/react/useSetFeeCollector.d.ts +27 -0
- package/dist/fhe-airdrop/advanced/react/useSetMaxGasFee.d.ts +33 -0
- package/dist/fhe-airdrop/advanced/react/useSetMerkleImplementation.d.ts +30 -0
- package/dist/fhe-airdrop/advanced/react/useSetUpgradeabilityPolicy.d.ts +31 -0
- package/dist/fhe-airdrop/airdrop-base.d.ts +55 -8
- package/dist/fhe-airdrop/campaign.d.ts +61 -20
- package/dist/fhe-airdrop/constants.d.ts +9 -1
- package/dist/fhe-airdrop/ecdsa.d.ts +13 -0
- package/dist/fhe-airdrop/errors.d.ts +87 -0
- package/dist/fhe-airdrop/factory.d.ts +62 -22
- package/dist/fhe-airdrop/guards.d.ts +133 -4
- package/dist/fhe-airdrop/index.cjs +86 -971
- package/dist/fhe-airdrop/index.d.cts +4 -4
- package/dist/fhe-airdrop/index.d.ts +4 -4
- package/dist/fhe-airdrop/index.js +8 -927
- package/dist/fhe-airdrop/merkle-tree.d.ts +32 -38
- package/dist/fhe-airdrop/merkle.d.ts +52 -31
- package/dist/fhe-airdrop/react/_shared.d.ts +13 -0
- package/dist/fhe-airdrop/react/index.cjs +997 -87
- package/dist/fhe-airdrop/react/index.d.cts +53 -4
- package/dist/fhe-airdrop/react/index.d.ts +53 -4
- package/dist/fhe-airdrop/react/index.js +887 -27
- package/dist/fhe-airdrop/react/keys.d.ts +98 -0
- package/dist/fhe-airdrop/react/useAccessEcdsaClaimAmount.d.ts +26 -0
- package/dist/fhe-airdrop/react/useAccessMerkleClaimAmount.d.ts +27 -0
- package/dist/fhe-airdrop/react/useAddComplianceDelegate.d.ts +37 -0
- package/dist/fhe-airdrop/react/useAdminBatchDiscloseBalanceToParties.d.ts +36 -0
- package/dist/fhe-airdrop/react/useAdminDiscloseBalanceToParty.d.ts +31 -0
- package/dist/fhe-airdrop/react/useAdminGetCurrentBalance.d.ts +27 -0
- package/dist/fhe-airdrop/react/useAirdropConfig.d.ts +49 -0
- package/dist/fhe-airdrop/react/useAirdropDeploymentMode.d.ts +28 -0
- package/dist/fhe-airdrop/react/useAirdropGrantRole.d.ts +35 -0
- package/dist/fhe-airdrop/react/useAirdropRenounceRole.d.ts +36 -0
- package/dist/fhe-airdrop/react/useAirdropRevokeRole.d.ts +33 -0
- package/dist/fhe-airdrop/react/useAirdropRoleAdmin.d.ts +28 -0
- package/dist/fhe-airdrop/react/useAirdropRoleConstants.d.ts +67 -0
- package/dist/fhe-airdrop/react/useAirdropRoleMembers.d.ts +49 -0
- package/dist/fhe-airdrop/react/useAirdropUpgradeToAndCall.d.ts +45 -0
- package/dist/fhe-airdrop/react/useBatchDiscloseHandlesToParty.d.ts +32 -0
- package/dist/fhe-airdrop/react/useBuildMerkleCampaign.d.ts +68 -0
- package/dist/fhe-airdrop/react/useComplianceGrantRole.d.ts +32 -0
- package/dist/fhe-airdrop/react/useComplianceHasRole.d.ts +37 -0
- package/dist/fhe-airdrop/react/useComplianceInfo.d.ts +50 -0
- package/dist/fhe-airdrop/react/useComplianceManagerOf.d.ts +32 -0
- package/dist/fhe-airdrop/react/useComplianceRenounceRole.d.ts +38 -0
- package/dist/fhe-airdrop/react/useComplianceRevokeRole.d.ts +36 -0
- package/dist/fhe-airdrop/react/useComplianceRoleConstants.d.ts +41 -0
- package/dist/fhe-airdrop/react/useComplianceRoleMembers.d.ts +45 -0
- package/dist/fhe-airdrop/react/useCreateAndFundEcdsaAirdrop.d.ts +55 -0
- package/dist/fhe-airdrop/react/useCreateAndFundMerkleAirdrop.d.ts +52 -0
- package/dist/fhe-airdrop/react/useDiscloseHandleToParty.d.ts +35 -0
- package/dist/fhe-airdrop/react/useEcdsaClaim.d.ts +4 -3
- package/dist/fhe-airdrop/react/useEcdsaClaimAndUnwrap.d.ts +27 -0
- package/dist/fhe-airdrop/react/useEcdsaDomain.d.ts +41 -0
- package/dist/fhe-airdrop/react/useEffectiveDelegateToCompliance.d.ts +26 -0
- package/dist/fhe-airdrop/react/useEncryptCampaignAmounts.d.ts +59 -0
- package/dist/fhe-airdrop/react/useFactoryFees.d.ts +11 -4
- package/dist/fhe-airdrop/react/useIsActiveDelegate.d.ts +29 -0
- package/dist/fhe-airdrop/react/useIsAirdrop.d.ts +44 -0
- package/dist/fhe-airdrop/react/useIsMerkleRootMutable.d.ts +21 -0
- package/dist/fhe-airdrop/react/useIsSignatureValid.d.ts +46 -0
- package/dist/fhe-airdrop/react/useMerkleClaim.d.ts +7 -19
- package/dist/fhe-airdrop/react/useMerkleClaimAndUnwrap.d.ts +29 -0
- package/dist/fhe-airdrop/react/usePlanMerkleCampaign.d.ts +53 -0
- package/dist/fhe-airdrop/react/usePreflightClaim.d.ts +46 -0
- package/dist/fhe-airdrop/react/usePreflightCreateAirdrop.d.ts +67 -0
- package/dist/fhe-airdrop/react/useRefreshComplianceBalance.d.ts +36 -0
- package/dist/fhe-airdrop/react/useRescueERC20.d.ts +30 -0
- package/dist/fhe-airdrop/react/useRescueOtherConfidentialToken.d.ts +34 -0
- package/dist/fhe-airdrop/react/useResolveGasFee.d.ts +30 -0
- package/dist/fhe-airdrop/react/useRevokeComplianceDelegate.d.ts +37 -0
- package/dist/fhe-airdrop/react/useRotateMerkleRoot.d.ts +52 -0
- package/dist/fhe-airdrop/react/useSignClaimAuthorization.d.ts +42 -0
- package/dist/fhe-airdrop/react/useWithdrawGasFee.d.ts +37 -0
- package/dist/fhe-airdrop/types.d.ts +27 -1
- package/dist/fhe-disperse/index.cjs +21 -21
- package/dist/fhe-disperse/index.js +2 -2
- package/dist/fhe-disperse/react/index.cjs +22 -22
- package/dist/fhe-disperse/react/index.js +3 -3
- package/dist/fhe-vesting/advanced/index.cjs +5 -5
- package/dist/fhe-vesting/advanced/index.js +3 -3
- package/dist/fhe-vesting/advanced/react/index.cjs +7 -7
- package/dist/fhe-vesting/advanced/react/index.js +4 -4
- package/dist/fhe-vesting/index.cjs +8 -8
- package/dist/fhe-vesting/index.js +2 -2
- package/dist/fhe-vesting/react/index.cjs +114 -114
- package/dist/fhe-vesting/react/index.js +3 -3
- package/dist/index.cjs +18 -18
- package/dist/index.js +1 -1
- package/dist/testnet-faucet/index.cjs +14 -14
- package/dist/testnet-faucet/index.js +2 -2
- package/dist/testnet-faucet/react/index.cjs +8 -8
- package/dist/testnet-faucet/react/index.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-NCVX3K2N.cjs +0 -161
- package/dist/chunk-VP2B4WM2.js +0 -154
|
@@ -0,0 +1,45 @@
|
|
|
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 AirdropInstanceClientOptions } from "./_shared.js";
|
|
5
|
+
/** @alpha */
|
|
6
|
+
export interface AirdropUpgradeToAndCallArgs extends WriteAccountOverride {
|
|
7
|
+
/** The new implementation the proxy should point at. */
|
|
8
|
+
newImplementation: Address;
|
|
9
|
+
/**
|
|
10
|
+
* Initializer calldata to run against the new implementation, or `"0x"`
|
|
11
|
+
* (the default) for a plain swap. A non-empty payload is a `delegatecall`:
|
|
12
|
+
* the new implementation's code executes against THIS instance's storage.
|
|
13
|
+
*/
|
|
14
|
+
data?: Hex;
|
|
15
|
+
/**
|
|
16
|
+
* Wei to attach. Leave unset for a plain swap — ERC-1967 reverts
|
|
17
|
+
* `ERC1967NonPayable` when value is sent with empty `data`.
|
|
18
|
+
*/
|
|
19
|
+
value?: bigint;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Point an airdrop instance's ERC-1967 proxy at a new implementation,
|
|
23
|
+
* optionally calling into it in the same transaction. Requires
|
|
24
|
+
* `UPGRADER_ROLE`.
|
|
25
|
+
*
|
|
26
|
+
* **Inert on clone-mode instances** — a clone has no implementation slot to
|
|
27
|
+
* rewrite. Gate the UI on `useAirdropDeploymentMode().data === "uups"`;
|
|
28
|
+
* `proxiableUUID` cannot tell the two shells apart. Merkle campaigns never
|
|
29
|
+
* reach this at all, because the SDK refuses to create one in `uups` mode
|
|
30
|
+
* (`MerkleUupsUnsupportedError`).
|
|
31
|
+
*
|
|
32
|
+
* **Non-empty `data` runs as a delegatecall against this instance's own
|
|
33
|
+
* storage** — a wrong payload can brick the campaign irrecoverably.
|
|
34
|
+
*
|
|
35
|
+
* **Invalidates:** nothing. No hook in this subpath reads the instance's
|
|
36
|
+
* implementation pointer, and `deploymentMode` does not change across an
|
|
37
|
+
* upgrade.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* const upgrade = useAirdropUpgradeToAndCall({ address: airdropAddress });
|
|
41
|
+
* await upgrade.mutateAsync({ newImplementation: nextImpl });
|
|
42
|
+
*
|
|
43
|
+
* @alpha
|
|
44
|
+
*/
|
|
45
|
+
export declare function useAirdropUpgradeToAndCall(options: AirdropInstanceClientOptions): UseMutationResult<Hex, Error, AirdropUpgradeToAndCallArgs>;
|
|
@@ -0,0 +1,32 @@
|
|
|
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 AirdropInstanceClientOptions } from "./_shared.js";
|
|
5
|
+
/** @alpha */
|
|
6
|
+
export interface UseBatchDiscloseHandlesToPartyArgs extends WriteAccountOverride {
|
|
7
|
+
/** Existing `euint64` handles - public pointers, not values. */
|
|
8
|
+
handles: readonly Hex[];
|
|
9
|
+
/** The single address granted decrypt access on every handle. */
|
|
10
|
+
party: Address;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Grants one `party` decrypt access to several handles you already hold, in a
|
|
14
|
+
* single transaction. Produces no new handles, so it returns the transaction
|
|
15
|
+
* hash.
|
|
16
|
+
*
|
|
17
|
+
* The same two gates as `useDiscloseHandleToParty` apply per handle - the
|
|
18
|
+
* caller allowed on it (unless it holds `DISCLOSURE_ADMIN_ROLE`) and the
|
|
19
|
+
* instance allowed on it - and the first failure reverts the whole batch,
|
|
20
|
+
* naming the offending handle. It is all-or-nothing: a partial grant is never
|
|
21
|
+
* left behind.
|
|
22
|
+
*
|
|
23
|
+
* **Invalidates:** nothing. ACL is append-only and no read hook in this
|
|
24
|
+
* subpath caches who is allowed on a handle.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* const disclose = useBatchDiscloseHandlesToParty({ address: airdropAddress });
|
|
28
|
+
* await disclose.mutateAsync({ handles: [balanceHandle, claimHandle], party: auditor });
|
|
29
|
+
*
|
|
30
|
+
* @alpha
|
|
31
|
+
*/
|
|
32
|
+
export declare function useBatchDiscloseHandlesToParty(options: AirdropInstanceClientOptions): UseMutationResult<Hex, Error, UseBatchDiscloseHandlesToPartyArgs>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type UseMutationResult } from "@tanstack/react-query";
|
|
2
|
+
import type { Address } from "viem";
|
|
3
|
+
import { type CampaignSubmitterOption } from "../campaign.js";
|
|
4
|
+
import { type EncryptorSource } from "../encryption.js";
|
|
5
|
+
import type { BuiltCampaign, CampaignRecipient } from "../types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Hook-level config for {@link useBuildMerkleCampaign}. The instance already
|
|
8
|
+
* exists on the mutable-root path, so no chain client is needed — only the
|
|
9
|
+
* encryptor.
|
|
10
|
+
*
|
|
11
|
+
* @alpha
|
|
12
|
+
*/
|
|
13
|
+
export interface UseBuildMerkleCampaignOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Eager or lazy encryptor. Wire it lazily so the live React context is read
|
|
16
|
+
* at submit time rather than captured at mount (CLAUDE.md Pitfall #3):
|
|
17
|
+
* `const sdk = useZamaSDK()` once, then `encryptor: () => sdk.relayer`.
|
|
18
|
+
*/
|
|
19
|
+
encryptor?: EncryptorSource;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Variables for {@link useBuildMerkleCampaign}.
|
|
23
|
+
*
|
|
24
|
+
* @alpha
|
|
25
|
+
*/
|
|
26
|
+
export interface UseBuildMerkleCampaignArgs extends CampaignSubmitterOption {
|
|
27
|
+
/** The LIVE `MerkleConfidentialAirdrop` instance every input is bound to. Not the factory, not the implementation. */
|
|
28
|
+
instance: Address;
|
|
29
|
+
/** CUMULATIVE totals per account, never per-drop tranches. */
|
|
30
|
+
recipients: readonly CampaignRecipient[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Encrypt a roster and build the Merkle tree those ciphertexts belong to, for
|
|
34
|
+
* an instance that already exists — the **mutable-root** path. Publish the
|
|
35
|
+
* returned `root` with {@link useSetMerkleRoot}, or let
|
|
36
|
+
* {@link useRotateMerkleRoot} build and publish in one call. For an instance
|
|
37
|
+
* whose root is fixed at create time use {@link usePlanMerkleCampaign}: there
|
|
38
|
+
* is no address to encrypt against yet.
|
|
39
|
+
*
|
|
40
|
+
* **The returned `entries` ARE the campaign — persist them before the
|
|
41
|
+
* component unmounts.** The instance stores only the 32-byte root; there is no
|
|
42
|
+
* getter and no event that maps an account to its handle, input proof or
|
|
43
|
+
* Merkle branch. A recipient who does not hold their own
|
|
44
|
+
* `(handle, inputProof, merkleProof)` triple can never claim, and no on-chain
|
|
45
|
+
* data reconstructs it. Losing this result to a re-render is the likeliest way
|
|
46
|
+
* to brick a campaign.
|
|
47
|
+
*
|
|
48
|
+
* A mutation rather than a query: encryption is randomised, so the same roster
|
|
49
|
+
* builds a different root every call and there is no cache identity to key.
|
|
50
|
+
*
|
|
51
|
+
* Each entry is `{ account, boundTo, handle, inputProof, merkleProof }` —
|
|
52
|
+
* `account` selects the leaf and the cumulative accounting, `boundTo` is the
|
|
53
|
+
* only address the coprocessor accepts as sender. They are equal unless
|
|
54
|
+
* `submitter` was set.
|
|
55
|
+
*
|
|
56
|
+
* **Invalidates:** nothing. Off-chain work only; the root is not published here.
|
|
57
|
+
*
|
|
58
|
+
* @throws {@link InvalidArgumentError} on a duplicate, zero-address or out-of-`uint64`-range roster entry, or a zero `instance`.
|
|
59
|
+
* @throws {@link MissingEncryptorError} when `encryptor` resolves to `undefined`.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* const build = useBuildMerkleCampaign({ encryptor: () => sdk.relayer });
|
|
63
|
+
* const { root, entries } = await build.mutateAsync({ instance: airdrop, recipients });
|
|
64
|
+
* await persist(entries); // before anything else
|
|
65
|
+
*
|
|
66
|
+
* @alpha
|
|
67
|
+
*/
|
|
68
|
+
export declare function useBuildMerkleCampaign(options?: UseBuildMerkleCampaignOptions): UseMutationResult<BuiltCampaign, Error, UseBuildMerkleCampaignArgs>;
|
|
@@ -0,0 +1,32 @@
|
|
|
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 AirdropInstanceClientOptions } from "./_shared.js";
|
|
5
|
+
/** @alpha */
|
|
6
|
+
export interface ComplianceGrantRoleArgs extends WriteAccountOverride {
|
|
7
|
+
/** A `bytes32` role identifier - from {@link useComplianceRoleConstants}, never hand-hashed. */
|
|
8
|
+
role: Hex;
|
|
9
|
+
/** The account receiving the role. Distinct from `account`, which is who sends the transaction. */
|
|
10
|
+
holder: Address;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Grant one role on a compliance-manager clone. `options.address` is the
|
|
14
|
+
* CLONE. Requires the role's admin role, which is `DEFAULT_ADMIN_ROLE` for
|
|
15
|
+
* both roles this contract defines.
|
|
16
|
+
*
|
|
17
|
+
* This is how a campaign owner hands delegate administration to a compliance
|
|
18
|
+
* team without giving them anything on the airdrop instance itself - the two
|
|
19
|
+
* contracts keep separate role sets, and a grant here confers no pause,
|
|
20
|
+
* treasury or disclosure power over the campaign.
|
|
21
|
+
*
|
|
22
|
+
* **Invalidates:** this clone's {@link useComplianceHasRole} entry for exactly
|
|
23
|
+
* `(role, holder)` and its {@link useComplianceRoleMembers} entry for `role`
|
|
24
|
+
* (the list and the count both move). Scoped to this clone.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* const grant = useComplianceGrantRole({ address: managerAddress });
|
|
28
|
+
* await grant.mutateAsync({ role: roles.DELEGATION_ADMIN_ROLE, holder: complianceTeam });
|
|
29
|
+
*
|
|
30
|
+
* @alpha
|
|
31
|
+
*/
|
|
32
|
+
export declare function useComplianceGrantRole(options: AirdropInstanceClientOptions): UseMutationResult<Hex, Error, ComplianceGrantRoleArgs>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type UseQueryResult } from "@tanstack/react-query";
|
|
2
|
+
import type { Address, Hex } from "viem";
|
|
3
|
+
import { type AirdropInstanceHookOptions } from "./_shared.js";
|
|
4
|
+
/** @alpha */
|
|
5
|
+
export interface UseComplianceHasRoleArgs extends AirdropInstanceHookOptions<boolean> {
|
|
6
|
+
/** A `bytes32` role identifier - from {@link useComplianceRoleConstants}, not hand-hashed. */
|
|
7
|
+
role?: Hex;
|
|
8
|
+
/** The account to check. Distinct from a delegate: this is who may MANAGE delegates. */
|
|
9
|
+
holder?: Address;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Whether `holder` holds `role` on a compliance-manager clone. `address` is
|
|
13
|
+
* the CLONE.
|
|
14
|
+
*
|
|
15
|
+
* With `DELEGATION_ADMIN_ROLE` this is the gate on the delegate surface -
|
|
16
|
+
* mount {@link useAddComplianceDelegate}'s and
|
|
17
|
+
* {@link useRevokeComplianceDelegate}'s controls behind it. Holding a role
|
|
18
|
+
* here grants nothing on the airdrop instance itself; the two contracts have
|
|
19
|
+
* separate role sets.
|
|
20
|
+
*
|
|
21
|
+
* Stays disabled until both `role` and `holder` are defined, so a UI can call
|
|
22
|
+
* it unconditionally while the role constants are still loading.
|
|
23
|
+
*
|
|
24
|
+
* @remarks
|
|
25
|
+
* Invalidated by {@link useComplianceGrantRole},
|
|
26
|
+
* {@link useComplianceRevokeRole} and {@link useComplianceRenounceRole}.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* const { data: canDelegate } = useComplianceHasRole({
|
|
30
|
+
* address: managerAddress,
|
|
31
|
+
* role: roles?.DELEGATION_ADMIN_ROLE,
|
|
32
|
+
* holder: account,
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* @alpha
|
|
36
|
+
*/
|
|
37
|
+
export declare function useComplianceHasRole(args: UseComplianceHasRoleArgs): UseQueryResult<boolean, Error>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type UseQueryResult } from "@tanstack/react-query";
|
|
2
|
+
import type { Address } from "viem";
|
|
3
|
+
import { type AirdropInstanceHookOptions } from "./_shared.js";
|
|
4
|
+
/**
|
|
5
|
+
* One compliance-manager clone's wiring - who it serves and who may decrypt
|
|
6
|
+
* through it, read together.
|
|
7
|
+
*
|
|
8
|
+
* @alpha
|
|
9
|
+
*/
|
|
10
|
+
export interface ComplianceInfo {
|
|
11
|
+
/** The one airdrop instance this clone serves. */
|
|
12
|
+
airdrop: Address;
|
|
13
|
+
/**
|
|
14
|
+
* The platform compliance delegate, or the zero address when this clone was
|
|
15
|
+
* created with the factory's compliance policy OFF. Never "not wired yet" -
|
|
16
|
+
* see the hook's TSDoc. Irrevocable when set.
|
|
17
|
+
*/
|
|
18
|
+
platformDelegate: Address;
|
|
19
|
+
/** The mutable client-delegate set. Excludes `platformDelegate`. */
|
|
20
|
+
clientDelegates: readonly Address[];
|
|
21
|
+
}
|
|
22
|
+
/** @alpha */
|
|
23
|
+
export type UseComplianceInfoArgs = AirdropInstanceHookOptions<ComplianceInfo>;
|
|
24
|
+
/**
|
|
25
|
+
* Read a compliance-manager clone's whole wiring in one round trip - the
|
|
26
|
+
* airdrop it serves, its platform delegate, and its client-delegate set.
|
|
27
|
+
*
|
|
28
|
+
* `address` is the CLONE, not the airdrop instance: resolve it with
|
|
29
|
+
* {@link useComplianceManagerOf} or take it off `CreateAirdropResult.complianceManager`.
|
|
30
|
+
*
|
|
31
|
+
* A zero `platformDelegate` is unambiguous. The factory runs the clone's
|
|
32
|
+
* `initialize` atomically inside `createX`, so there is no observable
|
|
33
|
+
* "deployed but not yet wired" state - zero always means "created with the
|
|
34
|
+
* platform compliance policy off", never "not set up yet".
|
|
35
|
+
*
|
|
36
|
+
* `clientDelegates` deliberately omits the platform delegate, so it is not the
|
|
37
|
+
* answer to "may this address decrypt?" - use {@link useIsActiveDelegate},
|
|
38
|
+
* which reads the ACL directly and covers both slots.
|
|
39
|
+
*
|
|
40
|
+
* @remarks
|
|
41
|
+
* Invalidated by {@link useAddComplianceDelegate} and
|
|
42
|
+
* {@link useRevokeComplianceDelegate}.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* const { data } = useComplianceInfo({ address: complianceManagerAddress });
|
|
46
|
+
* const hasPlatformDelegate = data?.platformDelegate !== "0x0000000000000000000000000000000000000000";
|
|
47
|
+
*
|
|
48
|
+
* @alpha
|
|
49
|
+
*/
|
|
50
|
+
export declare function useComplianceInfo(args: UseComplianceInfoArgs): UseQueryResult<ComplianceInfo, Error>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type UseQueryResult } from "@tanstack/react-query";
|
|
2
|
+
import type { Address } from "viem";
|
|
3
|
+
import { type AirdropHookOptions } from "./_shared.js";
|
|
4
|
+
/** @alpha */
|
|
5
|
+
export interface UseComplianceManagerOfArgs extends AirdropHookOptions<Address> {
|
|
6
|
+
/** The airdrop instance whose compliance-manager clone to resolve. */
|
|
7
|
+
airdrop?: Address;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the `ComplianceRoleManager` clone bound to an airdrop instance, by
|
|
11
|
+
* asking the factory. This is the entry point for every other compliance
|
|
12
|
+
* hook: they are all scoped to the CLONE address, not the instance address.
|
|
13
|
+
*
|
|
14
|
+
* **Also a provenance check.** The factory records this mapping only for
|
|
15
|
+
* instances it deployed, so a zero address means the instance did not come
|
|
16
|
+
* from this factory - do not mount the compliance hooks on it.
|
|
17
|
+
*
|
|
18
|
+
* Cached indefinitely (`staleTime: Infinity`, overridable through `query`):
|
|
19
|
+
* the mapping is written once, inside `createX`, and never changes.
|
|
20
|
+
*
|
|
21
|
+
* @remarks
|
|
22
|
+
* {@link useComplianceManager} answers the same question from the other side,
|
|
23
|
+
* by asking the instance for its own clone. Prefer this hook when you hold no
|
|
24
|
+
* instance client, or when you want the provenance answer as well.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* const { data: manager } = useComplianceManagerOf({ airdrop: airdropAddress });
|
|
28
|
+
* const { data: info } = useComplianceInfo({ address: manager! });
|
|
29
|
+
*
|
|
30
|
+
* @alpha
|
|
31
|
+
*/
|
|
32
|
+
export declare function useComplianceManagerOf(args?: UseComplianceManagerOfArgs): UseQueryResult<Address, Error>;
|
|
@@ -0,0 +1,38 @@
|
|
|
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 AirdropInstanceClientOptions } from "./_shared.js";
|
|
5
|
+
/** @alpha */
|
|
6
|
+
export interface ComplianceRenounceRoleArgs extends WriteAccountOverride {
|
|
7
|
+
/** A `bytes32` role identifier - from {@link useComplianceRoleConstants}, never hand-hashed. */
|
|
8
|
+
role: Hex;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Give up a role on a compliance-manager clone yourself. `options.address` is
|
|
12
|
+
* the CLONE.
|
|
13
|
+
*
|
|
14
|
+
* Self-only by construction: the contract's
|
|
15
|
+
* `renounceRole(role, callerConfirmation)` reverts
|
|
16
|
+
* `AccessControlBadConfirmation` unless the confirmation is the sender, so
|
|
17
|
+
* there is no holder to pass - the headless client fills it from the resolved
|
|
18
|
+
* sending account. To remove somebody else's role use
|
|
19
|
+
* {@link useComplianceRevokeRole}.
|
|
20
|
+
*
|
|
21
|
+
* No last-admin floor guards this: the sole `DEFAULT_ADMIN_ROLE` holder CAN
|
|
22
|
+
* renounce, and doing so freezes the clone's delegate set permanently.
|
|
23
|
+
*
|
|
24
|
+
* **Invalidates:** every {@link useComplianceHasRole} entry for this clone
|
|
25
|
+
* (prefix, all role/holder pairs), plus its
|
|
26
|
+
* {@link useComplianceRoleMembers} entry for `role`. The prefix is
|
|
27
|
+
* deliberate - the holder here is whichever account the wallet client resolves
|
|
28
|
+
* at submit time, which need not match any `(role, holder)` pair a component
|
|
29
|
+
* happens to have cached, and a narrower key would invalidate nothing while
|
|
30
|
+
* throwing nothing. Still scoped to this clone.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const renounce = useComplianceRenounceRole({ address: managerAddress });
|
|
34
|
+
* await renounce.mutateAsync({ role: roles.DELEGATION_ADMIN_ROLE });
|
|
35
|
+
*
|
|
36
|
+
* @alpha
|
|
37
|
+
*/
|
|
38
|
+
export declare function useComplianceRenounceRole(options: AirdropInstanceClientOptions): UseMutationResult<Hex, Error, ComplianceRenounceRoleArgs>;
|
|
@@ -0,0 +1,36 @@
|
|
|
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 AirdropInstanceClientOptions } from "./_shared.js";
|
|
5
|
+
/** @alpha */
|
|
6
|
+
export interface ComplianceRevokeRoleArgs extends WriteAccountOverride {
|
|
7
|
+
/** A `bytes32` role identifier - from {@link useComplianceRoleConstants}, never hand-hashed. */
|
|
8
|
+
role: Hex;
|
|
9
|
+
/** The account losing the role. Distinct from `account`, which is who sends the transaction. */
|
|
10
|
+
holder: Address;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Revoke one role from one holder on a compliance-manager clone.
|
|
14
|
+
* `options.address` is the CLONE. Requires the role's admin role.
|
|
15
|
+
*
|
|
16
|
+
* **Revoking a delegation admin revokes no delegation.** The FHEVM ACL is
|
|
17
|
+
* append-only, so every delegate that account already added keeps decrypting
|
|
18
|
+
* until {@link useRevokeComplianceDelegate} is called for it explicitly. This
|
|
19
|
+
* is the most likely wrong assumption about this button: it removes the power
|
|
20
|
+
* to add more delegates, nothing else.
|
|
21
|
+
*
|
|
22
|
+
* The contract enforces no last-admin floor either - revoking the sole
|
|
23
|
+
* `DEFAULT_ADMIN_ROLE` holder freezes the clone's delegate set permanently.
|
|
24
|
+
* Check {@link useComplianceRoleMembers}'s `count` first.
|
|
25
|
+
*
|
|
26
|
+
* **Invalidates:** this clone's {@link useComplianceHasRole} entry for exactly
|
|
27
|
+
* `(role, holder)` and its {@link useComplianceRoleMembers} entry for `role`.
|
|
28
|
+
* Scoped to this clone.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* const revoke = useComplianceRevokeRole({ address: managerAddress });
|
|
32
|
+
* await revoke.mutateAsync({ role: roles.DELEGATION_ADMIN_ROLE, holder: formerTeam });
|
|
33
|
+
*
|
|
34
|
+
* @alpha
|
|
35
|
+
*/
|
|
36
|
+
export declare function useComplianceRevokeRole(options: AirdropInstanceClientOptions): UseMutationResult<Hex, Error, ComplianceRevokeRoleArgs>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type UseQueryResult } from "@tanstack/react-query";
|
|
2
|
+
import type { Hex } from "viem";
|
|
3
|
+
import { type AirdropInstanceHookOptions } from "./_shared.js";
|
|
4
|
+
/**
|
|
5
|
+
* The `bytes32` role identifiers a compliance-manager clone exposes.
|
|
6
|
+
*
|
|
7
|
+
* @alpha
|
|
8
|
+
*/
|
|
9
|
+
export interface ComplianceRoleConstants {
|
|
10
|
+
/** Gates `addDelegate` / `revokeDelegate`. */
|
|
11
|
+
DELEGATION_ADMIN_ROLE: Hex;
|
|
12
|
+
/** OpenZeppelin's root role, read off the clone rather than assumed to be `bytes32(0)`. It administers `DELEGATION_ADMIN_ROLE`. */
|
|
13
|
+
DEFAULT_ADMIN_ROLE: Hex;
|
|
14
|
+
}
|
|
15
|
+
/** @alpha */
|
|
16
|
+
export type UseComplianceRoleConstantsArgs = AirdropInstanceHookOptions<ComplianceRoleConstants>;
|
|
17
|
+
/**
|
|
18
|
+
* Read a compliance-manager clone's role identifiers. `address` is the CLONE.
|
|
19
|
+
*
|
|
20
|
+
* Both values are bytecode constants, so this is cacheable indefinitely
|
|
21
|
+
* (`staleTime: Infinity` by default, overridable through `query`). Feed them
|
|
22
|
+
* into {@link useComplianceHasRole}, {@link useComplianceRoleMembers} and the
|
|
23
|
+
* role mutations rather than hand-hashing `keccak256("DELEGATION_ADMIN_ROLE")`
|
|
24
|
+
* client-side, which would turn a constant renamed in a future contract
|
|
25
|
+
* version into a grant of a role nothing checks.
|
|
26
|
+
*
|
|
27
|
+
* Bundled despite being only two reads, so the shape matches
|
|
28
|
+
* {@link useAirdropRoleConstants} and the factory equivalent - and because two
|
|
29
|
+
* one-line hooks for two constants is the pattern this subpath avoids.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* const { data: roles } = useComplianceRoleConstants({ address: managerAddress });
|
|
33
|
+
* const { data: canDelegate } = useComplianceHasRole({
|
|
34
|
+
* address: managerAddress,
|
|
35
|
+
* role: roles?.DELEGATION_ADMIN_ROLE,
|
|
36
|
+
* holder: account,
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* @alpha
|
|
40
|
+
*/
|
|
41
|
+
export declare function useComplianceRoleConstants(args: UseComplianceRoleConstantsArgs): UseQueryResult<ComplianceRoleConstants, Error>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type UseQueryResult } from "@tanstack/react-query";
|
|
2
|
+
import type { Address, Hex } from "viem";
|
|
3
|
+
import { type AirdropInstanceHookOptions } from "./_shared.js";
|
|
4
|
+
/**
|
|
5
|
+
* One role's membership on a compliance-manager clone - the set and its size,
|
|
6
|
+
* read together.
|
|
7
|
+
*
|
|
8
|
+
* @alpha
|
|
9
|
+
*/
|
|
10
|
+
export interface ComplianceRoleMembership {
|
|
11
|
+
/** Every account currently holding the role, in `EnumerableSet` order. Treat it as a set: the order is not stable across grants and revokes. */
|
|
12
|
+
members: readonly Address[];
|
|
13
|
+
/** How many accounts hold it. */
|
|
14
|
+
count: bigint;
|
|
15
|
+
}
|
|
16
|
+
/** @alpha */
|
|
17
|
+
export interface UseComplianceRoleMembersArgs extends AirdropInstanceHookOptions<ComplianceRoleMembership> {
|
|
18
|
+
/** The role whose members to list - from {@link useComplianceRoleConstants}, not hand-hashed. */
|
|
19
|
+
role?: Hex;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* List who holds `role` on a compliance-manager clone, with the member count.
|
|
23
|
+
* `address` is the CLONE.
|
|
24
|
+
*
|
|
25
|
+
* With `DELEGATION_ADMIN_ROLE` this answers "who may add or revoke a
|
|
26
|
+
* delegate?" - the administrative counterpart to
|
|
27
|
+
* {@link useComplianceInfo}'s `clientDelegates`, which answers "who may
|
|
28
|
+
* currently decrypt?".
|
|
29
|
+
*
|
|
30
|
+
* Unlike an airdrop instance, this contract enforces no "never empty" floor:
|
|
31
|
+
* emptying `DEFAULT_ADMIN_ROLE` here freezes the clone's delegate set
|
|
32
|
+
* permanently, so surface `count` before offering the last revoke.
|
|
33
|
+
* Unpaginated - role sets here are operator-sized.
|
|
34
|
+
*
|
|
35
|
+
* @remarks
|
|
36
|
+
* Invalidated by {@link useComplianceGrantRole},
|
|
37
|
+
* {@link useComplianceRevokeRole} and {@link useComplianceRenounceRole}.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* const { data } = useComplianceRoleMembers({ address: managerAddress, role: roles?.DEFAULT_ADMIN_ROLE });
|
|
41
|
+
* const wouldFreezeClone = data?.count === 1n;
|
|
42
|
+
*
|
|
43
|
+
* @alpha
|
|
44
|
+
*/
|
|
45
|
+
export declare function useComplianceRoleMembers(args: UseComplianceRoleMembersArgs): UseQueryResult<ComplianceRoleMembership, Error>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type UseMutationResult } from "@tanstack/react-query";
|
|
2
|
+
import type { WriteAccountOverride } from "../airdrop-base.js";
|
|
3
|
+
import type { FundInput } from "../factory.js";
|
|
4
|
+
import type { CreateAirdropArgs, CreateAirdropResult, EcdsaAirdropParams } from "../types.js";
|
|
5
|
+
import { type AirdropClientOptions } from "./_shared.js";
|
|
6
|
+
/**
|
|
7
|
+
* Variables for {@link useCreateAndFundEcdsaAirdrop} — the create arguments plus
|
|
8
|
+
* exactly one of `amount` / `encryptedInput`.
|
|
9
|
+
*
|
|
10
|
+
* @alpha
|
|
11
|
+
*/
|
|
12
|
+
export type UseCreateAndFundEcdsaAirdropArgs = CreateAirdropArgs<EcdsaAirdropParams> & FundInput & WriteAccountOverride;
|
|
13
|
+
/**
|
|
14
|
+
* Deploy an ECDSA-authorised airdrop instance and seed its pool in one
|
|
15
|
+
* transaction.
|
|
16
|
+
*
|
|
17
|
+
* Prerequisite: the funder must already have approved the factory as an
|
|
18
|
+
* ERC-7984 operator on the token (`token.setOperator(factoryAddress, deadline)`) —
|
|
19
|
+
* the factory pulls the pool via `confidentialTransferFrom`. Pass `amount`
|
|
20
|
+
* (plaintext, encrypted against the hook-level `encryptor`) or a pre-built
|
|
21
|
+
* `encryptedInput`, never both.
|
|
22
|
+
*
|
|
23
|
+
* Returns `CreateAirdropResult` unflattened — `{ hash, airdrop,
|
|
24
|
+
* complianceManager }`; the caller needs the instance address to do anything
|
|
25
|
+
* with the campaign afterwards.
|
|
26
|
+
*
|
|
27
|
+
* **A successful receipt does not prove the pool was funded.** An ERC-7984
|
|
28
|
+
* transfer moves an encrypted zero instead of reverting when the funder is
|
|
29
|
+
* short, because reverting would leak the balance.
|
|
30
|
+
*
|
|
31
|
+
* **Invalidates:** the factory's registry reads (`useFactoryRegistry`) for
|
|
32
|
+
* this factory address, whatever page was cached — a new instance moves
|
|
33
|
+
* `airdropCount()` / `airdrops()`. Nothing else: the new instance has no
|
|
34
|
+
* cached reads yet, and no read hook here exposes the confidential pool
|
|
35
|
+
* balance.
|
|
36
|
+
*
|
|
37
|
+
* **Never log `amount`.** It is the one plaintext confidential value this
|
|
38
|
+
* hook sees — keep it out of telemetry, `onError` context and console.
|
|
39
|
+
*
|
|
40
|
+
* @throws {@link DeploymentAddressUnavailableError} when no factory is deployed for the connected chain.
|
|
41
|
+
* @throws {@link MissingEncryptorError} when `amount` is given and no encryptor resolves.
|
|
42
|
+
* @throws {@link SaltCollisionError} when this `(mode, deployer, userSalt)` tuple already deployed an instance.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* const createAndFund = useCreateAndFundEcdsaAirdrop({ encryptor: () => sdk.relayer });
|
|
46
|
+
* const { airdrop } = await createAndFund.mutateAsync({
|
|
47
|
+
* params: { common, signer, dedupMode: "perAddress" },
|
|
48
|
+
* mode: "clone",
|
|
49
|
+
* userSalt,
|
|
50
|
+
* amount: 1_000_000n,
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* @alpha
|
|
54
|
+
*/
|
|
55
|
+
export declare function useCreateAndFundEcdsaAirdrop(options?: AirdropClientOptions): UseMutationResult<CreateAirdropResult, Error, UseCreateAndFundEcdsaAirdropArgs>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type UseMutationResult } from "@tanstack/react-query";
|
|
2
|
+
import type { WriteAccountOverride } from "../airdrop-base.js";
|
|
3
|
+
import type { FundInput } from "../factory.js";
|
|
4
|
+
import type { CreateAirdropArgs, CreateAirdropResult, MerkleAirdropParams } from "../types.js";
|
|
5
|
+
import { type AirdropClientOptions } from "./_shared.js";
|
|
6
|
+
/**
|
|
7
|
+
* Variables for {@link useCreateAndFundMerkleAirdrop} — the create arguments plus
|
|
8
|
+
* exactly one of `amount` / `encryptedInput`.
|
|
9
|
+
*
|
|
10
|
+
* @alpha
|
|
11
|
+
*/
|
|
12
|
+
export type UseCreateAndFundMerkleAirdropArgs = CreateAirdropArgs<MerkleAirdropParams> & FundInput & WriteAccountOverride;
|
|
13
|
+
/**
|
|
14
|
+
* Deploy a Merkle-proof airdrop instance and seed its pool in one transaction.
|
|
15
|
+
*
|
|
16
|
+
* Prerequisite: the funder must already have approved the factory as an
|
|
17
|
+
* ERC-7984 operator on the token (`token.setOperator(factoryAddress, deadline)`).
|
|
18
|
+
* Pass `amount` (plaintext, encrypted against the hook-level `encryptor`) or a
|
|
19
|
+
* pre-built `encryptedInput`, never both.
|
|
20
|
+
*
|
|
21
|
+
* `mode: "uups"` is rejected before the wallet is even looked up, so the
|
|
22
|
+
* mutation rejects without prompting for a signature. Returns
|
|
23
|
+
* `CreateAirdropResult` unflattened — `{ hash, airdrop, complianceManager }`.
|
|
24
|
+
*
|
|
25
|
+
* **A successful receipt does not prove the pool was funded.** An ERC-7984
|
|
26
|
+
* transfer moves an encrypted zero instead of reverting when the funder is
|
|
27
|
+
* short, because reverting would leak the balance.
|
|
28
|
+
*
|
|
29
|
+
* **Invalidates:** the factory's registry reads (`useFactoryRegistry`) for
|
|
30
|
+
* this factory address, whatever page was cached — a new instance moves
|
|
31
|
+
* `airdropCount()` / `airdrops()`. Nothing else.
|
|
32
|
+
*
|
|
33
|
+
* **Never log `amount`.** It is the one plaintext confidential value this
|
|
34
|
+
* hook sees — keep it out of telemetry, `onError` context and console.
|
|
35
|
+
*
|
|
36
|
+
* @throws {@link MerkleUupsUnsupportedError} when `mode` is `"uups"`.
|
|
37
|
+
* @throws {@link DeploymentAddressUnavailableError} when no factory is deployed for the connected chain.
|
|
38
|
+
* @throws {@link MissingEncryptorError} when `amount` is given and no encryptor resolves.
|
|
39
|
+
* @throws {@link SaltCollisionError} when this `(mode, deployer, userSalt)` tuple already deployed an instance.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* const createAndFund = useCreateAndFundMerkleAirdrop({ encryptor: () => sdk.relayer });
|
|
43
|
+
* const { airdrop } = await createAndFund.mutateAsync({
|
|
44
|
+
* params: { common, merkleRoot: plan.root, isMerkleRootMutable: false },
|
|
45
|
+
* mode: "clone",
|
|
46
|
+
* userSalt,
|
|
47
|
+
* amount: 1_000_000n,
|
|
48
|
+
* });
|
|
49
|
+
*
|
|
50
|
+
* @alpha
|
|
51
|
+
*/
|
|
52
|
+
export declare function useCreateAndFundMerkleAirdrop(options?: AirdropClientOptions): UseMutationResult<CreateAirdropResult, Error, UseCreateAndFundMerkleAirdropArgs>;
|
|
@@ -0,0 +1,35 @@
|
|
|
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 AirdropInstanceClientOptions } from "./_shared.js";
|
|
5
|
+
/** @alpha */
|
|
6
|
+
export interface UseDiscloseHandleToPartyArgs extends WriteAccountOverride {
|
|
7
|
+
/** An existing `euint64` handle - a public pointer, not a value. */
|
|
8
|
+
handle: Hex;
|
|
9
|
+
/** The address granted decrypt access on `handle`. */
|
|
10
|
+
party: Address;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Grants `party` decrypt access to a handle you already hold - typically one
|
|
14
|
+
* returned by `useAdminGetCurrentBalance` or a claim preview, forwarded to an
|
|
15
|
+
* auditor without ever revealing plaintext.
|
|
16
|
+
*
|
|
17
|
+
* Unlike the `admin*Disclose*` hooks this produces no new handle, so it
|
|
18
|
+
* returns the transaction hash rather than an `EncryptedViewResult`; there is
|
|
19
|
+
* no ACL event to parse.
|
|
20
|
+
*
|
|
21
|
+
* Two gates apply on-chain: the caller must itself be allowed on `handle`
|
|
22
|
+
* (bypassed by `DISCLOSURE_ADMIN_ROLE`), and the *instance* must be allowed on
|
|
23
|
+
* it, so a handle minted by an unrelated contract cannot be laundered through
|
|
24
|
+
* this campaign. A failure of the first surfaces as `FheHandleNotAllowedError`.
|
|
25
|
+
*
|
|
26
|
+
* **Invalidates:** nothing. ACL is append-only and no read hook in this
|
|
27
|
+
* subpath caches who is allowed on a handle.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* const disclose = useDiscloseHandleToParty({ address: airdropAddress });
|
|
31
|
+
* await disclose.mutateAsync({ handle, party: auditorAddress });
|
|
32
|
+
*
|
|
33
|
+
* @alpha
|
|
34
|
+
*/
|
|
35
|
+
export declare function useDiscloseHandleToParty(options: AirdropInstanceClientOptions): UseMutationResult<Hex, Error, UseDiscloseHandleToPartyArgs>;
|
|
@@ -10,9 +10,10 @@ import { type EcdsaAirdropInstanceClientOptions } from "./_shared.js";
|
|
|
10
10
|
* (see {@link EcdsaAirdropClientConfig.dedupMode}); pass the same value used
|
|
11
11
|
* at `createEcdsaAirdrop` time.
|
|
12
12
|
*
|
|
13
|
-
* **Invalidates:**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* **Invalidates:** the `fn "isSignatureValid"` PREFIX for this instance. A successful
|
|
14
|
+
* claim consumes the EIP-712 digest, so every cached signature check on this instance
|
|
15
|
+
* is now stale in the dangerous direction - it still answers `true` for a signature
|
|
16
|
+
* that can no longer be claimed. Per-claim dedup state itself remains unqueryable.
|
|
16
17
|
*
|
|
17
18
|
* @example
|
|
18
19
|
* const claim = useEcdsaClaim({ address: airdropAddress, dedupMode: "perAddress" });
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type UseMutationResult } from "@tanstack/react-query";
|
|
2
|
+
import type { Hex } from "viem";
|
|
3
|
+
import type { EcdsaClaimArgs } from "../ecdsa.js";
|
|
4
|
+
import { type EcdsaAirdropInstanceClientOptions } from "./_shared.js";
|
|
5
|
+
/**
|
|
6
|
+
* Claim a signed encrypted allocation and route it straight into the wrapper's unwrap,
|
|
7
|
+
* making `to` the underlying ERC-20 beneficiary.
|
|
8
|
+
*
|
|
9
|
+
* Reverts {@link FeatureDisabledError} on a non-unwrappable campaign - gate the button
|
|
10
|
+
* on `useAirdropConfig().unwrappable`. Consumes the same replay guards and EIP-712
|
|
11
|
+
* digest as {@link useEcdsaClaim}.
|
|
12
|
+
*
|
|
13
|
+
* `dedupMode` must be supplied - the contract has no on-chain getter for it; pass the
|
|
14
|
+
* same value used at `createEcdsaAirdrop` time.
|
|
15
|
+
*
|
|
16
|
+
* **Invalidates:** nothing, mirroring {@link useEcdsaClaim}. Replay consumption is not
|
|
17
|
+
* queryable, so no cached read in this subpath tracks the state a successful claim
|
|
18
|
+
* changes. `useIsSignatureValid` DOES flip to `false` once the digest is consumed, but
|
|
19
|
+
* it is not invalidated from here - refetch it yourself after a claim.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const unwrapClaim = useEcdsaClaimAndUnwrap({ address: airdropAddress, dedupMode: "perAddress" });
|
|
23
|
+
* await unwrapClaim.mutateAsync({ encryptedInput, dedupId, deadline, signer, signature, to });
|
|
24
|
+
*
|
|
25
|
+
* @alpha
|
|
26
|
+
*/
|
|
27
|
+
export declare function useEcdsaClaimAndUnwrap(options: EcdsaAirdropInstanceClientOptions): UseMutationResult<Hex, Error, EcdsaClaimArgs>;
|