@tokenops/sdk 1.6.0 → 2.0.0-alpha.1
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 +48 -8
- package/CONTRIBUTING.md +4 -2
- package/README.md +146 -90
- package/SUPPORT.md +47 -0
- package/dist/{chunk-HETNKZEE.js → chunk-335Z2W67.js} +1 -1
- package/dist/{chunk-BD4LZBVF.cjs → chunk-3QHNYEQD.cjs} +18 -17
- package/dist/chunk-456VDDA3.js +370 -0
- package/dist/{chunk-6WSNS3UV.js → chunk-4RAAATVY.js} +2 -4
- package/dist/{chunk-4KJ66YRH.js → chunk-4TSDNZQ3.js} +2 -2
- package/dist/{chunk-WUXUWTFW.cjs → chunk-5576FRT3.cjs} +31 -7
- package/dist/chunk-66IHPTOK.cjs +20 -0
- package/dist/{chunk-2RNW4MIJ.cjs → chunk-67OV5CX2.cjs} +0 -18
- package/dist/{chunk-PD7ME2BT.js → chunk-6GNR22OV.js} +2 -1
- package/dist/{chunk-VHSNYUYV.js → chunk-6NAVMWZQ.js} +5 -5
- package/dist/{chunk-EUKPOXWR.cjs → chunk-6PXXGACR.cjs} +17 -15
- package/dist/{chunk-WTK6JDSI.js → chunk-74QFZ5MK.js} +6 -4
- package/dist/{chunk-WOEETTH7.cjs → chunk-7AFPOE7N.cjs} +6 -6
- package/dist/{chunk-U57COLUE.js → chunk-AXIPOR3C.js} +2 -2
- package/dist/chunk-CTED3MTR.cjs +380 -0
- package/dist/{chunk-QKKBBH7I.js → chunk-DZHYSUGY.js} +28 -7
- package/dist/{chunk-V5D7BHW3.js → chunk-EAJ7SYHE.js} +6 -4
- package/dist/{chunk-SYHNZSZZ.cjs → chunk-FAXIIH5R.cjs} +3 -3
- package/dist/{chunk-7G7UOQV4.cjs → chunk-FGEB7RMY.cjs} +4 -4
- package/dist/chunk-GKKDAW44.js +8823 -0
- package/dist/{chunk-QET3Q4JP.js → chunk-H5POPGOZ.js} +8 -6
- package/dist/{chunk-VR3FREBX.cjs → chunk-JK4XMMKM.cjs} +3 -3
- package/dist/{chunk-CBRL2PJA.cjs → chunk-JQYC66TO.cjs} +12 -12
- package/dist/{chunk-YFIWCYHC.cjs → chunk-JZLGCTGK.cjs} +56 -54
- package/dist/{chunk-4ZCXK4VI.cjs → chunk-KFRDLKMA.cjs} +14 -14
- package/dist/chunk-KWFFIJYX.js +11 -0
- package/dist/chunk-M4IT6DNJ.cjs +608 -0
- package/dist/{chunk-43RFBQ73.cjs → chunk-MVDQMV25.cjs} +29 -32
- package/dist/chunk-NCVX3K2N.cjs +161 -0
- package/dist/chunk-NWFMBLSQ.js +4 -0
- package/dist/chunk-O5676ZWY.js +585 -0
- package/dist/chunk-PUX5VXDB.cjs +8845 -0
- package/dist/{chunk-DRSPMIZ7.js → chunk-QBJ7O2B4.js} +1 -11
- package/dist/{chunk-UJS4N2XM.cjs → chunk-TEBM66WA.cjs} +12 -12
- package/dist/{chunk-TN65XNTI.js → chunk-TWT3STIX.js} +8 -6
- package/dist/chunk-UG5RKLU2.cjs +6 -0
- package/dist/chunk-VP2B4WM2.js +154 -0
- package/dist/{chunk-BK7YIVLK.cjs → chunk-WJLECC22.cjs} +75 -73
- package/dist/{chunk-NFW7AUEX.js → chunk-WMACINXO.js} +1 -1
- package/dist/{chunk-AYGRYDBX.cjs → chunk-XAYGD4E4.cjs} +37 -35
- package/dist/{chunk-46T67CE2.js → chunk-ZA673I3O.js} +1 -1
- package/dist/{chunk-YPYCWLYP.js → chunk-ZWXJTBZO.js} +1 -1
- package/dist/core/addresses.d.ts +14 -2
- package/dist/core/brands.d.ts +8 -2
- package/dist/core/errors.d.ts +71 -10
- package/dist/core/preflight.d.ts +1 -0
- package/dist/fhe/erc7984-abi.d.ts +1 -0
- package/dist/fhe/index.cjs +64 -63
- package/dist/fhe/index.js +7 -6
- package/dist/fhe/operators.d.ts +22 -5
- package/dist/fhe/react/index.cjs +13 -12
- package/dist/fhe/react/index.js +6 -5
- package/dist/fhe/types.d.ts +6 -0
- package/dist/fhe-airdrop/abis/{cloneable.d.ts → airdrop-base.d.ts} +254 -396
- package/dist/fhe-airdrop/abis/compliance.d.ts +422 -0
- package/dist/fhe-airdrop/abis/ecdsa.d.ts +1316 -0
- package/dist/fhe-airdrop/abis/factory.d.ts +1319 -190
- package/dist/fhe-airdrop/abis/index.d.ts +5 -2
- package/dist/fhe-airdrop/abis/merkle.d.ts +1238 -0
- package/dist/fhe-airdrop/advanced/index.cjs +11 -12
- package/dist/fhe-airdrop/advanced/index.d.cts +34 -11
- package/dist/fhe-airdrop/advanced/index.d.ts +34 -11
- package/dist/fhe-airdrop/advanced/index.js +3 -8
- package/dist/fhe-airdrop/advanced/react/index.cjs +37 -50
- package/dist/fhe-airdrop/advanced/react/index.d.cts +9 -3
- package/dist/fhe-airdrop/advanced/react/index.d.ts +9 -3
- package/dist/fhe-airdrop/advanced/react/index.js +36 -50
- package/dist/fhe-airdrop/advanced/react/usePredictEcdsaAirdropAddress.d.ts +33 -0
- package/dist/fhe-airdrop/advanced/react/usePredictMerkleAirdropAddress.d.ts +27 -0
- package/dist/fhe-airdrop/airdrop-base.d.ts +600 -0
- package/dist/fhe-airdrop/campaign.d.ts +297 -0
- package/dist/fhe-airdrop/compliance.d.ts +302 -0
- package/dist/fhe-airdrop/constants.d.ts +33 -0
- package/dist/fhe-airdrop/ecdsa.d.ts +263 -0
- package/dist/fhe-airdrop/encryption.d.ts +92 -14
- package/dist/fhe-airdrop/errors.d.ts +245 -15
- package/dist/fhe-airdrop/factory.d.ts +533 -274
- package/dist/fhe-airdrop/guards.d.ts +273 -0
- package/dist/fhe-airdrop/index.cjs +1131 -74
- package/dist/fhe-airdrop/index.d.cts +46 -8
- package/dist/fhe-airdrop/index.d.ts +46 -8
- package/dist/fhe-airdrop/index.js +931 -8
- package/dist/fhe-airdrop/merkle-tree.d.ts +103 -0
- package/dist/fhe-airdrop/merkle.d.ts +180 -0
- package/dist/fhe-airdrop/react/_shared.d.ts +144 -71
- package/dist/fhe-airdrop/react/index.cjs +399 -459
- package/dist/fhe-airdrop/react/index.d.cts +53 -74
- package/dist/fhe-airdrop/react/index.d.ts +53 -74
- package/dist/fhe-airdrop/react/index.js +261 -374
- package/dist/fhe-airdrop/react/useAirdropGasFee.d.ts +10 -5
- package/dist/fhe-airdrop/react/useAirdropHasRole.d.ts +15 -6
- package/dist/fhe-airdrop/react/useAirdropPause.d.ts +30 -0
- package/dist/fhe-airdrop/react/useAirdropPaused.d.ts +17 -0
- package/dist/fhe-airdrop/react/useAirdropToken.d.ts +11 -4
- package/dist/fhe-airdrop/react/useAirdropWindow.d.ts +37 -0
- package/dist/fhe-airdrop/react/useClaimedAmount.d.ts +29 -0
- package/dist/fhe-airdrop/react/useComplianceManager.d.ts +16 -0
- package/dist/fhe-airdrop/react/useCreateEcdsaAirdrop.d.ts +28 -0
- package/dist/fhe-airdrop/react/useCreateMerkleAirdrop.d.ts +25 -0
- package/dist/fhe-airdrop/react/useEcdsaClaim.d.ts +23 -0
- package/dist/fhe-airdrop/react/useEffectiveUpgradeable.d.ts +20 -0
- package/dist/fhe-airdrop/react/useExtendClaimWindow.d.ts +17 -12
- package/dist/fhe-airdrop/react/useFactoryFees.d.ts +28 -0
- package/dist/fhe-airdrop/react/useFactoryRegistry.d.ts +35 -0
- package/dist/fhe-airdrop/react/useFundAirdrop.d.ts +35 -0
- package/dist/fhe-airdrop/react/useGrantInstanceRoles.d.ts +35 -0
- package/dist/fhe-airdrop/react/useMerkleClaim.d.ts +34 -0
- package/dist/fhe-airdrop/react/useMerkleRoot.d.ts +15 -0
- package/dist/fhe-airdrop/react/useSetMerkleRoot.d.ts +22 -0
- package/dist/fhe-airdrop/react/useWithdrawConfidential.d.ts +23 -0
- package/dist/fhe-airdrop/roles.d.ts +147 -0
- package/dist/fhe-airdrop/types.d.ts +67 -65
- package/dist/fhe-disperse/index.cjs +70 -68
- package/dist/fhe-disperse/index.js +10 -8
- package/dist/fhe-disperse/react/index.cjs +94 -92
- package/dist/fhe-disperse/react/index.js +13 -11
- package/dist/fhe-vesting/advanced/index.cjs +10 -8
- package/dist/fhe-vesting/advanced/index.js +8 -6
- package/dist/fhe-vesting/advanced/react/index.cjs +16 -14
- package/dist/fhe-vesting/advanced/react/index.js +13 -11
- package/dist/fhe-vesting/index.cjs +74 -72
- package/dist/fhe-vesting/index.js +11 -9
- package/dist/fhe-vesting/react/index.cjs +228 -226
- package/dist/fhe-vesting/react/index.js +15 -13
- package/dist/index.cjs +100 -87
- package/dist/index.js +3 -2
- package/dist/testnet-faucet/index.cjs +57 -55
- package/dist/testnet-faucet/index.js +7 -5
- package/dist/testnet-faucet/react/index.cjs +55 -53
- package/dist/testnet-faucet/react/index.js +9 -7
- package/package.json +6 -2
- package/dist/chunk-CNP4L3GF.js +0 -105
- package/dist/chunk-KSDSXJ34.js +0 -41
- package/dist/chunk-LBWRFZR3.cjs +0 -1681
- package/dist/chunk-OL6SHN3D.cjs +0 -44
- package/dist/chunk-S2XD75JM.js +0 -1637
- package/dist/chunk-SPGSO5SO.cjs +0 -1644
- package/dist/chunk-UE5XK2SY.js +0 -1673
- package/dist/chunk-WO72UBQD.cjs +0 -109
- package/dist/fhe-airdrop/advanced/factory-advanced.d.ts +0 -53
- package/dist/fhe-airdrop/advanced/react/usePredictAirdropAddress.d.ts +0 -49
- package/dist/fhe-airdrop/airdrop.d.ts +0 -317
- package/dist/fhe-airdrop/react/useAccessClaimAmount.d.ts +0 -37
- package/dist/fhe-airdrop/react/useAirdropCanExtendClaimWindow.d.ts +0 -7
- package/dist/fhe-airdrop/react/useAirdropClaimTypehash.d.ts +0 -10
- package/dist/fhe-airdrop/react/useAirdropClaimedSignatures.d.ts +0 -16
- package/dist/fhe-airdrop/react/useAirdropDeploymentBlockNumber.d.ts +0 -6
- package/dist/fhe-airdrop/react/useAirdropDomainSeparator.d.ts +0 -8
- package/dist/fhe-airdrop/react/useAirdropEndTime.d.ts +0 -10
- package/dist/fhe-airdrop/react/useAirdropFactoryCustomFee.d.ts +0 -17
- package/dist/fhe-airdrop/react/useAirdropFactoryDefaultGasFee.d.ts +0 -10
- package/dist/fhe-airdrop/react/useAirdropFactoryDisableCustomFee.d.ts +0 -15
- package/dist/fhe-airdrop/react/useAirdropFactoryFeeCollector.d.ts +0 -11
- package/dist/fhe-airdrop/react/useAirdropFactoryInitCodeHash.d.ts +0 -17
- package/dist/fhe-airdrop/react/useAirdropFactorySetCustomFee.d.ts +0 -17
- package/dist/fhe-airdrop/react/useAirdropFactorySetDefaultGasFee.d.ts +0 -16
- package/dist/fhe-airdrop/react/useAirdropFactorySetFeeCollector.d.ts +0 -15
- package/dist/fhe-airdrop/react/useAirdropGrantRole.d.ts +0 -16
- package/dist/fhe-airdrop/react/useAirdropHasClaimEnded.d.ts +0 -7
- package/dist/fhe-airdrop/react/useAirdropHasClaimStarted.d.ts +0 -7
- package/dist/fhe-airdrop/react/useAirdropIsClaimWindowActive.d.ts +0 -9
- package/dist/fhe-airdrop/react/useAirdropIsPaused.d.ts +0 -8
- package/dist/fhe-airdrop/react/useAirdropIsSignatureClaimed.d.ts +0 -22
- package/dist/fhe-airdrop/react/useAirdropIsSignatureValid.d.ts +0 -51
- package/dist/fhe-airdrop/react/useAirdropRevokeRole.d.ts +0 -15
- package/dist/fhe-airdrop/react/useAirdropStartTime.d.ts +0 -10
- package/dist/fhe-airdrop/react/useAirdropWithdrawGasFee.d.ts +0 -15
- package/dist/fhe-airdrop/react/useAirdropWithdrawOtherConfidentialToken.d.ts +0 -14
- package/dist/fhe-airdrop/react/useAirdropWithdrawOtherToken.d.ts +0 -14
- package/dist/fhe-airdrop/react/useClaim.d.ts +0 -39
- package/dist/fhe-airdrop/react/useConfidentialAirdropFactoryImplementation.d.ts +0 -11
- package/dist/fhe-airdrop/react/useCreateAndFundConfidentialAirdrop.d.ts +0 -41
- package/dist/fhe-airdrop/react/useCreateAndFundConfidentialAirdropAndGetAddress.d.ts +0 -48
- package/dist/fhe-airdrop/react/useCreateConfidentialAirdrop.d.ts +0 -29
- package/dist/fhe-airdrop/react/useCreateConfidentialAirdropAndGetAddress.d.ts +0 -31
- package/dist/fhe-airdrop/react/useDisableCustomFee.d.ts +0 -14
- package/dist/fhe-airdrop/react/useFactoryCustomFee.d.ts +0 -17
- package/dist/fhe-airdrop/react/useFactoryDefaultGasFee.d.ts +0 -10
- package/dist/fhe-airdrop/react/useFactoryFeeCollector.d.ts +0 -11
- package/dist/fhe-airdrop/react/useFactoryInitCodeHash.d.ts +0 -17
- package/dist/fhe-airdrop/react/useFundConfidentialAirdrop.d.ts +0 -33
- package/dist/fhe-airdrop/react/usePreflightCreateAirdrop.d.ts +0 -51
- package/dist/fhe-airdrop/react/useSetCustomFee.d.ts +0 -16
- package/dist/fhe-airdrop/react/useSetDefaultGasFee.d.ts +0 -15
- package/dist/fhe-airdrop/react/useSetFeeCollector.d.ts +0 -14
- package/dist/fhe-airdrop/react/useSetPaused.d.ts +0 -14
- package/dist/fhe-airdrop/react/useSignClaimAuthorization.d.ts +0 -31
- package/dist/fhe-airdrop/react/useWithdraw.d.ts +0 -12
- package/dist/fhe-airdrop/react/useWithdrawOtherConfidentialToken.d.ts +0 -13
- package/dist/fhe-airdrop/react/useWithdrawOtherToken.d.ts +0 -13
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { Address, Hex } from "viem";
|
|
2
|
+
/**
|
|
3
|
+
* Inputs for {@link leafOf}.
|
|
4
|
+
*
|
|
5
|
+
* @alpha
|
|
6
|
+
*/
|
|
7
|
+
export interface LeafOfArgs {
|
|
8
|
+
/** The `MerkleConfidentialAirdrop` instance the leaf is scoped to — `address(this)` on-chain. */
|
|
9
|
+
instance: Address;
|
|
10
|
+
/** The claiming account — always `msg.sender` on-chain, never the claim's payout destination. */
|
|
11
|
+
recipient: Address;
|
|
12
|
+
/** The encrypted handle committing the recipient's cumulative total allocation. */
|
|
13
|
+
handle: Hex;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Compute a Merkle leaf byte-for-byte identical to the contract's
|
|
17
|
+
* `_leafOf(recipient, inputAmount)` — see the module comment above for the
|
|
18
|
+
* verified derivation. Mirrors what the campaign builder (`buildMerkleCampaign`,
|
|
19
|
+
* `campaign.ts`) needs to construct the same tree `StandardMerkleTree` would,
|
|
20
|
+
* and is useful to any caller who wants to recompute a leaf independently of
|
|
21
|
+
* the campaign orchestrator.
|
|
22
|
+
*
|
|
23
|
+
* @alpha
|
|
24
|
+
*/
|
|
25
|
+
export declare function leafOf(args: LeafOfArgs): Hex;
|
|
26
|
+
/**
|
|
27
|
+
* The minimum a leaf must carry. `buildMerkleTree` is generic over anything
|
|
28
|
+
* wider, so a caller's own fields ride along onto the entry.
|
|
29
|
+
*
|
|
30
|
+
* @alpha
|
|
31
|
+
*/
|
|
32
|
+
export interface MerkleLeafInput {
|
|
33
|
+
/** The account that will SEND the claim. The contract recomputes the leaf as `_leafOf(msg.sender, inputAmount)`. */
|
|
34
|
+
recipient: Address;
|
|
35
|
+
/** The encrypted handle committing this recipient's cumulative total. */
|
|
36
|
+
handle: Hex;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Inputs for {@link buildMerkleTree}.
|
|
40
|
+
*
|
|
41
|
+
* @alpha
|
|
42
|
+
*/
|
|
43
|
+
export interface BuildMerkleTreeArgs<L extends MerkleLeafInput> {
|
|
44
|
+
/** The `MerkleConfidentialAirdrop` instance the leaves are scoped to. Not the factory, not the implementation. */
|
|
45
|
+
instance: Address;
|
|
46
|
+
leaves: readonly L[];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A built tree: the root to publish, and every input leaf with its proof attached.
|
|
50
|
+
*
|
|
51
|
+
* @alpha
|
|
52
|
+
*/
|
|
53
|
+
export interface BuiltMerkleTree<L extends MerkleLeafInput> {
|
|
54
|
+
root: Hex;
|
|
55
|
+
entries: readonly (L & {
|
|
56
|
+
merkleProof: readonly Hex[];
|
|
57
|
+
})[];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Build the Merkle tree a `MerkleConfidentialAirdrop` verifies against, from
|
|
61
|
+
* handles produced anywhere.
|
|
62
|
+
*
|
|
63
|
+
* **Pure.** No relayer, no chain access, no encryptor. Given the same leaves
|
|
64
|
+
* it returns the same root, so it can run offline, in a test, or on a machine
|
|
65
|
+
* that has never seen a private key.
|
|
66
|
+
*
|
|
67
|
+
* **The tree commits to the handle, not the amount.** `_leafOf` hashes
|
|
68
|
+
* `(address(this), recipient, encHandle)`, so whoever encrypted must have bound
|
|
69
|
+
* each input to `(instance, that recipient)` — `FHE.fromExternal` reverts on any
|
|
70
|
+
* mismatch. This function cannot check that; it will happily build a tree over
|
|
71
|
+
* wrongly-bound handles, and the failure surfaces at claim time.
|
|
72
|
+
*
|
|
73
|
+
* **Extra fields ride along.** Whatever the leaf carries beyond
|
|
74
|
+
* `recipient` and `handle` — an `inputProof`, your own row id — comes back on
|
|
75
|
+
* the entry, still aligned with its proof. Passing
|
|
76
|
+
* `{ recipient, handle, inputProof }` therefore yields a value structurally
|
|
77
|
+
* assignable to `CampaignEntry`, which is what `MerkleAirdropClient.claim`
|
|
78
|
+
* consumes.
|
|
79
|
+
*
|
|
80
|
+
* @param args The instance the leaves are scoped to, and the leaves.
|
|
81
|
+
* @returns The root to publish, and one proof-bearing entry per input leaf, in input order.
|
|
82
|
+
* @throws {@link InvalidArgumentError} on a zero or malformed instance, an empty leaf set, a malformed or zero recipient, a duplicate recipient, or a handle that is not 32 bytes.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* const { root, entries } = buildMerkleTree({
|
|
86
|
+
* instance: airdrop,
|
|
87
|
+
* leaves: [{ recipient: alice, handle, inputProof }],
|
|
88
|
+
* });
|
|
89
|
+
* await merkle.setMerkleRoot({ newRoot: root });
|
|
90
|
+
*
|
|
91
|
+
* @alpha
|
|
92
|
+
*/
|
|
93
|
+
export declare function buildMerkleTree<L extends MerkleLeafInput>(args: BuildMerkleTreeArgs<L>): BuiltMerkleTree<L>;
|
|
94
|
+
/**
|
|
95
|
+
* Real implementation behind {@link buildMerkleTree}, parameterised on the
|
|
96
|
+
* function name a thrown {@link InvalidArgumentError} blames.
|
|
97
|
+
*
|
|
98
|
+
* Not part of the public surface — exported from this module only so
|
|
99
|
+
* `buildMerkleCampaign` (`campaign.ts`) can call it directly with its own
|
|
100
|
+
* name, attributing a malformed-handle failure to itself rather than to
|
|
101
|
+
* `buildMerkleTree`. Neither barrel (`index.ts`) re-exports it.
|
|
102
|
+
*/
|
|
103
|
+
export declare function buildMerkleTreeInternal<L extends MerkleLeafInput>({ instance, leaves }: BuildMerkleTreeArgs<L>, method: string): BuiltMerkleTree<L>;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import type { Address, Hex } from "viem";
|
|
2
|
+
import { type EncryptedHandle } from "../core/brands.js";
|
|
3
|
+
import type { EncryptedViewResult } from "../fhe/types.js";
|
|
4
|
+
import { AirdropBaseClient, type AirdropBaseClientConfig, type WriteAccountOverride } from "./airdrop-base.js";
|
|
5
|
+
import type { CampaignEntry } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Inputs shared by {@link MerkleAirdropClient.claim} and {@link MerkleAirdropClient.claimAndUnwrap}.
|
|
8
|
+
*
|
|
9
|
+
* @alpha
|
|
10
|
+
*/
|
|
11
|
+
export interface MerkleClaimArgs extends WriteAccountOverride {
|
|
12
|
+
/**
|
|
13
|
+
* Payout destination. Omit (or pass the zero address) to default to the
|
|
14
|
+
* sending account — mirrors the contract's own `to == address(0)` redirect
|
|
15
|
+
* rule. The leaf's recipient field, the outstanding-amount accounting and
|
|
16
|
+
* the FHE input proof all stay bound to the sending account regardless of
|
|
17
|
+
* `to`; this field only redirects where the tokens (and the recipient ACL)
|
|
18
|
+
* land.
|
|
19
|
+
*/
|
|
20
|
+
to?: Address;
|
|
21
|
+
/**
|
|
22
|
+
* The recipient's proof-bearing claim entry, built by the campaign
|
|
23
|
+
* orchestrator (`campaign.ts`, Task 11). `entry.recipient` must equal the
|
|
24
|
+
* account this call sends from (`args.account`, or the wallet client's
|
|
25
|
+
* default account): the contract recomputes the leaf as
|
|
26
|
+
* `_leafOf(msg.sender, inputAmount)`, so submitting `entry.merkleProof`
|
|
27
|
+
* from any account other than `entry.recipient` recomputes a different
|
|
28
|
+
* leaf and reverts `InvalidMerkleProof` even though the proof bytes
|
|
29
|
+
* themselves are untouched.
|
|
30
|
+
*/
|
|
31
|
+
entry: CampaignEntry;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Inputs for {@link MerkleAirdropClient.getClaimAmount}.
|
|
35
|
+
*
|
|
36
|
+
* @alpha
|
|
37
|
+
*/
|
|
38
|
+
export interface GetClaimAmountArgs extends WriteAccountOverride {
|
|
39
|
+
/**
|
|
40
|
+
* Same binding rule as {@link MerkleClaimArgs.entry}: `entry.recipient`
|
|
41
|
+
* must equal the calling account, since the contract's preview also
|
|
42
|
+
* recomputes the leaf against `msg.sender`.
|
|
43
|
+
*/
|
|
44
|
+
entry: CampaignEntry;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Client for one `MerkleConfidentialAirdrop` instance — the variant whose
|
|
48
|
+
* claims are authorised by inclusion in a published Merkle tree rather than
|
|
49
|
+
* an off-chain signature. Each leaf commits `(instance, recipient, handle)`,
|
|
50
|
+
* where `handle` is the recipient's CUMULATIVE total allocation, not a
|
|
51
|
+
* per-drop tranche — see the `@remarks` on {@link getClaimedAmount}.
|
|
52
|
+
*
|
|
53
|
+
* Adds the claim surface on top of {@link AirdropBaseClient}'s shared
|
|
54
|
+
* lifecycle/treasury/rescue/role/disclosure methods: `claim` /
|
|
55
|
+
* `claimAndUnwrap` submit a proof-bearing allocation, `getClaimAmount`
|
|
56
|
+
* previews the outstanding amount as a decryptable handle, and
|
|
57
|
+
* `getClaimedAmount` reads an account's running delivered total.
|
|
58
|
+
*
|
|
59
|
+
* Every claim entrypoint here takes the exact-equality gas fee
|
|
60
|
+
* ({@link AirdropBaseClient.gasFee}) automatically — read fresh on every
|
|
61
|
+
* `claim`/`claimAndUnwrap` call and attached as the transaction's `value`, so
|
|
62
|
+
* a caller never has to source it themselves or risk sending the wrong
|
|
63
|
+
* amount against the contract's `msg.value != gasFee()` revert.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* const airdrop = new MerkleAirdropClient({ publicClient, walletClient, address });
|
|
67
|
+
* const hash = await airdrop.claim({ entry });
|
|
68
|
+
*
|
|
69
|
+
* @alpha
|
|
70
|
+
*/
|
|
71
|
+
export declare class MerkleAirdropClient extends AirdropBaseClient {
|
|
72
|
+
constructor(config: AirdropBaseClientConfig);
|
|
73
|
+
/**
|
|
74
|
+
* Claim the outstanding amount for a proof-bearing entry, delivering the
|
|
75
|
+
* tokens to `to` (defaults to the sending account).
|
|
76
|
+
*
|
|
77
|
+
* Requires `msg.value == gasFee()` exactly — handled for you; see the
|
|
78
|
+
* class TSDoc.
|
|
79
|
+
*
|
|
80
|
+
* @remarks
|
|
81
|
+
* There is no per-leaf consumption on this variant — replay safety is the
|
|
82
|
+
* accounting itself, not a spent-flag. Re-presenting an already-settled
|
|
83
|
+
* entry computes an encrypted-zero outstanding amount and pays nothing,
|
|
84
|
+
* but the gas fee is still charged (the amounts are encrypted, so a
|
|
85
|
+
* zero-outstanding claim cannot be detected or rejected on-chain).
|
|
86
|
+
* Presenting two different entries for the SAME recipient under one root
|
|
87
|
+
* pays whichever entry's cumulative total is higher net of what the other
|
|
88
|
+
* already delivered — effectively `max`, not `sum`, of the two totals.
|
|
89
|
+
*
|
|
90
|
+
* @throws {@link ClaimNotStartedError} before `startTime`.
|
|
91
|
+
* @throws {@link ClaimWindowClosedError} after `endTime`.
|
|
92
|
+
* @throws {@link InvalidArgumentError} (`argument: "merkleProof"`) when the proof does not verify against
|
|
93
|
+
* the current root — including when `entry.recipient` does not match the sending account.
|
|
94
|
+
* @returns The transaction hash.
|
|
95
|
+
*/
|
|
96
|
+
claim(args: MerkleClaimArgs): Promise<Hex>;
|
|
97
|
+
/**
|
|
98
|
+
* Claim then route the allocation straight into the wrapper's unwrap
|
|
99
|
+
* (`to` becomes the underlying ERC-20 beneficiary). Reverts
|
|
100
|
+
* `TokenNotUnwrappable` (surfaced as `FeatureDisabledError`) on a
|
|
101
|
+
* non-unwrappable campaign.
|
|
102
|
+
*
|
|
103
|
+
* Same replay/accounting semantics and `msg.value == gasFee()` requirement
|
|
104
|
+
* as {@link claim} — see its `@remarks`.
|
|
105
|
+
*
|
|
106
|
+
* @returns The transaction hash. The underlying ERC-20 is released later by
|
|
107
|
+
* a separate, permissionless `finalizeUnwrap` — this hash is only the
|
|
108
|
+
* unwrap request.
|
|
109
|
+
*/
|
|
110
|
+
claimAndUnwrap(args: MerkleClaimArgs): Promise<Hex>;
|
|
111
|
+
/**
|
|
112
|
+
* Preview the outstanding amount for a proof-bearing entry as a handle the
|
|
113
|
+
* caller can decrypt. Consumes no accounting and no per-leaf state — the
|
|
114
|
+
* same entry still pays the same amount after a preview. No fee.
|
|
115
|
+
*
|
|
116
|
+
* An encrypted view: the contract calls `FHE.allow(outstanding, msg.sender)`,
|
|
117
|
+
* so the result is recovered from the receipt's ACL `Allowed` event, never
|
|
118
|
+
* from a simulation. See {@link AirdropBaseClient}'s class TSDoc.
|
|
119
|
+
*
|
|
120
|
+
* @returns `{ handle, hash }` — pass `handle` to the Zama relayer's `userDecrypt`.
|
|
121
|
+
*/
|
|
122
|
+
getClaimAmount(args: GetClaimAmountArgs): Promise<EncryptedViewResult>;
|
|
123
|
+
/**
|
|
124
|
+
* Read `account`'s running delivered total as an encrypted handle.
|
|
125
|
+
*
|
|
126
|
+
* @remarks
|
|
127
|
+
* Since round 8 a Merkle leaf commits the recipient's CUMULATIVE total
|
|
128
|
+
* allocation, not a per-drop tranche, and this getter mirrors that: it
|
|
129
|
+
* returns the cumulative amount actually DELIVERED so far, not a per-claim
|
|
130
|
+
* amount. A claim pays `total - min(total, alreadyDelivered)`, where
|
|
131
|
+
* `alreadyDelivered` is exactly this value.
|
|
132
|
+
*
|
|
133
|
+
* Two consequences worth calling out explicitly:
|
|
134
|
+
* - **A root rotation is a top-up, not a second payout.** Rotating the
|
|
135
|
+
* root republishes updated cumulative totals; this value is keyed by
|
|
136
|
+
* `account` alone (not by root), so a claim against the new root pays
|
|
137
|
+
* only the increase over what this getter already reports.
|
|
138
|
+
* - **One leaf per recipient per root.** If a tree mistakenly commits two
|
|
139
|
+
* leaves for the same recipient, claiming both pays the higher of the
|
|
140
|
+
* two totals net of this running value — `max`, not `sum`.
|
|
141
|
+
*
|
|
142
|
+
* The zero handle (uninitialized ciphertext) before an account's first
|
|
143
|
+
* settled claim decrypts as zero.
|
|
144
|
+
*
|
|
145
|
+
* @returns The account's cumulative delivered total, as an encrypted handle.
|
|
146
|
+
*/
|
|
147
|
+
getClaimedAmount(account: Address): Promise<EncryptedHandle>;
|
|
148
|
+
/** The currently published root. Proofs must verify against this exact value. */
|
|
149
|
+
merkleRoot(): Promise<Hex>;
|
|
150
|
+
/** Whether {@link setMerkleRoot} can succeed at all — fixed at create time, never toggled after. */
|
|
151
|
+
isMerkleRootMutable(): Promise<boolean>;
|
|
152
|
+
/**
|
|
153
|
+
* Rotate the published root. Requires `MERKLE_ADMIN_ROLE`.
|
|
154
|
+
*
|
|
155
|
+
* A rotation republishes UPDATED cumulative totals — it tops accounts up,
|
|
156
|
+
* it never claws back: {@link getClaimedAmount}'s running total survives
|
|
157
|
+
* the rotation and every future claim still nets it out. See that
|
|
158
|
+
* getter's `@remarks`.
|
|
159
|
+
*
|
|
160
|
+
* @throws {@link FeatureDisabledError} (`feature: "merkleRootRotation"`) when the campaign was created
|
|
161
|
+
* with `isMerkleRootMutable: false`.
|
|
162
|
+
* @throws {@link InvalidArgumentError} (`argument: "merkleRoot"`) when `newRoot` is zero — a zero root
|
|
163
|
+
* would silently brick every claim with no way to fix it; pause instead.
|
|
164
|
+
* @returns The transaction hash.
|
|
165
|
+
*/
|
|
166
|
+
setMerkleRoot(args: {
|
|
167
|
+
newRoot: Hex;
|
|
168
|
+
} & WriteAccountOverride): Promise<Hex>;
|
|
169
|
+
/** Gates {@link setMerkleRoot}. */
|
|
170
|
+
MERKLE_ADMIN_ROLE(): Promise<Hex>;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Create a {@link MerkleAirdropClient}. Mirrors viem's `create*` convention.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* const airdrop = createMerkleAirdropClient({ publicClient, walletClient, address });
|
|
177
|
+
*
|
|
178
|
+
* @alpha
|
|
179
|
+
*/
|
|
180
|
+
export declare function createMerkleAirdropClient(config: AirdropBaseClientConfig): MerkleAirdropClient;
|
|
@@ -1,64 +1,134 @@
|
|
|
1
|
+
import type { UseQueryOptions } from "@tanstack/react-query";
|
|
1
2
|
import type { Address, PublicClient, WalletClient } from "viem";
|
|
2
3
|
import { DeploymentAddressUnavailableError } from "../../core/errors.js";
|
|
3
|
-
import
|
|
4
|
+
import type { SdkTelemetry } from "../../core/telemetry.js";
|
|
5
|
+
import { type AirdropBaseClient } from "../airdrop-base.js";
|
|
6
|
+
import type { DedupMode } from "../constants.js";
|
|
7
|
+
import { type EcdsaAirdropClient } from "../ecdsa.js";
|
|
8
|
+
import { type EncryptorSource } from "../encryption.js";
|
|
4
9
|
import { type ConfidentialAirdropFactoryClient } from "../factory.js";
|
|
5
|
-
import { type
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
import { type MerkleAirdropClient } from "../merkle.js";
|
|
11
|
+
/**
|
|
12
|
+
* Stable query-key prefix for every hook in this subpath — matches the
|
|
13
|
+
* sibling subpaths' convention (`FHE_VESTING_KEY`/`FHE_DISPERSE_KEY`/
|
|
14
|
+
* `TESTNET_FAUCET_KEY` all use `"tokenops-sdk"`; see `src/fhe-vesting/react/_shared.ts`,
|
|
15
|
+
* `src/fhe-disperse/react/_shared.ts`, `src/testnet-faucet/react/_shared.ts`).
|
|
16
|
+
*
|
|
17
|
+
* Not `"tokenops"` — an earlier draft of this file used that value; fixed so
|
|
18
|
+
* a consumer calling `queryClient.invalidateQueries({ queryKey: ["tokenops-sdk"] })`
|
|
19
|
+
* to clear every `@tokenops/sdk` cache entry doesn't silently miss this
|
|
20
|
+
* subpath's queries.
|
|
21
|
+
*/
|
|
22
|
+
export declare const FHE_AIRDROP_KEY: "tokenops-sdk";
|
|
23
|
+
export declare const FHE_AIRDROP_NAMESPACE: "fhe-airdrop";
|
|
24
|
+
/**
|
|
25
|
+
* Build the TanStack Query key for an `/fhe-airdrop` read.
|
|
26
|
+
*
|
|
27
|
+
* Namespaced by chain id AND instance/factory address so cache entries never
|
|
28
|
+
* bleed across chains or campaigns — two different campaign instances (or
|
|
29
|
+
* the same instance on two chains) never share a cache slot. Caller-specific
|
|
30
|
+
* reads (e.g. `getClaimedAmount(account)`) pass `account` as part of `args`,
|
|
31
|
+
* so switching the connected account changes the key and never serves a
|
|
32
|
+
* stale value cached under the previous account.
|
|
33
|
+
*
|
|
34
|
+
* @returns `["tokenops-sdk", "fhe-airdrop", chainId, address, fn, args]`.
|
|
35
|
+
*
|
|
36
|
+
* @alpha
|
|
37
|
+
*/
|
|
38
|
+
export declare function airdropQueryKey(params: {
|
|
39
|
+
chainId: number | undefined;
|
|
40
|
+
address: Address | undefined;
|
|
41
|
+
fn: string;
|
|
42
|
+
args: ReadonlyArray<unknown>;
|
|
43
|
+
}): unknown[];
|
|
44
|
+
/**
|
|
45
|
+
* Build the *prefix* of {@link airdropQueryKey} up to (and including) `fn` —
|
|
46
|
+
* useful for `invalidateQueries({ queryKey: airdropQueryKeyPrefix(...), exact: false })`
|
|
47
|
+
* when a write affects every cached read for one function regardless of args
|
|
48
|
+
* (e.g. every `hasRole` entry for one instance, regardless of which
|
|
49
|
+
* role/holder pair was queried).
|
|
50
|
+
*
|
|
51
|
+
* @alpha
|
|
52
|
+
*/
|
|
53
|
+
export declare function airdropQueryKeyPrefix(params: {
|
|
54
|
+
chainId: number | undefined;
|
|
55
|
+
address: Address | undefined;
|
|
56
|
+
fn?: string;
|
|
57
|
+
}): unknown[];
|
|
58
|
+
/**
|
|
59
|
+
* The client-construction subset of every hook's options — deliberately NOT
|
|
60
|
+
* generic over `TData`. Client-memo helpers (`useMemoAirdropBaseClient`,
|
|
61
|
+
* etc.) accept this narrower shape rather than {@link AirdropHookOptions},
|
|
62
|
+
* because a `useQuery<TData, ...>` per-hook `query` option makes the wider
|
|
63
|
+
* type invariant in `TData` (the `enabled` callback's parameter type), which
|
|
64
|
+
* would otherwise force every memo helper to be generic too.
|
|
65
|
+
*
|
|
66
|
+
* @alpha
|
|
67
|
+
*/
|
|
68
|
+
export interface AirdropClientOptions {
|
|
69
|
+
/** Instance or factory address override. Factory hooks default this by chain id; instance hooks require it. */
|
|
9
70
|
address?: Address;
|
|
10
71
|
/** Override the chain id used for default address resolution. Defaults to `usePublicClient().chain?.id`. */
|
|
11
72
|
chainId?: number;
|
|
12
|
-
}
|
|
13
|
-
/** Per-hook overrides for factory hooks that submit encrypted inputs. */
|
|
14
|
-
export interface FactoryHookOptions extends BaseHookOptions {
|
|
15
73
|
/**
|
|
16
|
-
* Lazy or eager encryptor source.
|
|
17
|
-
*
|
|
18
|
-
* (`
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* component and wire `encryptor: () => sdk.relayer` — the SDK
|
|
22
|
-
* calls this per-encryption so it picks up the live `ZamaSDK` instance
|
|
23
|
-
* rather than a stale capture (CLAUDE.md Pitfall #3).
|
|
74
|
+
* Lazy or eager encryptor source. Only consumed by hooks that submit
|
|
75
|
+
* encrypted inputs (`useFundAirdrop`). Recommended in React: capture
|
|
76
|
+
* `useZamaSDK()` once and wire `encryptor: () => sdk.relayer` so the SDK
|
|
77
|
+
* picks up the live context at submit time (CLAUDE.md Pitfall #3) rather
|
|
78
|
+
* than a stale capture. An eager `Encryptor` instance also type-checks.
|
|
24
79
|
*/
|
|
25
80
|
encryptor?: EncryptorSource;
|
|
81
|
+
/**
|
|
82
|
+
* Optional telemetry adapter. Forwarded into the headless client so spans
|
|
83
|
+
* and `*.client.init` events flow through whichever sink the consumer
|
|
84
|
+
* wires up (PostHog, OTel, Sentry, custom).
|
|
85
|
+
*/
|
|
86
|
+
telemetry?: SdkTelemetry;
|
|
26
87
|
}
|
|
27
|
-
/** Per-hook overrides for FHE-airdrop *clone* hooks — `address` is required (per-airdrop). */
|
|
28
|
-
export interface AirdropHookOptions {
|
|
29
|
-
/** Deployed airdrop clone address. Required — there is no chain-level default. */
|
|
30
|
-
address: Address;
|
|
31
|
-
/** Override the FHEVM ACL address (defaults to chain-id lookup). */
|
|
32
|
-
aclAddress?: Address;
|
|
33
|
-
/** Override the chain id used for ACL/public-client lookup. Defaults to `usePublicClient().chain?.id`. */
|
|
34
|
-
chainId?: number;
|
|
35
|
-
}
|
|
36
|
-
/** Stable query-key prefix for every hook in this subpath. */
|
|
37
|
-
export declare const FHE_AIRDROP_KEY: "tokenops-sdk";
|
|
38
|
-
export declare const FHE_AIRDROP_NAMESPACE: "fhe-airdrop";
|
|
39
88
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
89
|
+
* Common per-hook overrides — every public read hook accepts these alongside its own args.
|
|
90
|
+
*
|
|
91
|
+
* @alpha
|
|
43
92
|
*/
|
|
44
|
-
export
|
|
93
|
+
export interface AirdropHookOptions<TData = unknown> extends AirdropClientOptions {
|
|
94
|
+
/**
|
|
95
|
+
* Escape hatch for TanStack Query's own cache-behavior options
|
|
96
|
+
* (`staleTime`, `gcTime`, `select`, `refetchInterval`, …). Cannot override
|
|
97
|
+
* `queryKey` / `queryFn` — those stay owned by the hook so cache identity
|
|
98
|
+
* is never at risk of drifting from what was actually fetched.
|
|
99
|
+
*/
|
|
100
|
+
query?: Omit<UseQueryOptions<TData, Error>, "queryKey" | "queryFn">;
|
|
101
|
+
}
|
|
45
102
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
103
|
+
* Instance-scoped hook options — `address` is required (a campaign instance, not a chain-wide default).
|
|
104
|
+
*
|
|
105
|
+
* @alpha
|
|
48
106
|
*/
|
|
49
|
-
export
|
|
107
|
+
export type AirdropInstanceHookOptions<TData = unknown> = AirdropHookOptions<TData> & {
|
|
108
|
+
address: Address;
|
|
109
|
+
};
|
|
50
110
|
/**
|
|
51
|
-
*
|
|
52
|
-
* `(publicClient, walletClient, address)`. The encryptor source is passed
|
|
53
|
-
* through as a **lazy** function (mirroring Pitfall #3 from CLAUDE.md): the
|
|
54
|
-
* SDK calls it per-encryption, picking up the live React context at submit
|
|
55
|
-
* time rather than baking in a stale capture.
|
|
111
|
+
* Non-generic instance-scoped client options, for memo helpers.
|
|
56
112
|
*
|
|
57
|
-
* @
|
|
58
|
-
|
|
59
|
-
|
|
113
|
+
* @alpha
|
|
114
|
+
*/
|
|
115
|
+
export type AirdropInstanceClientOptions = AirdropClientOptions & {
|
|
116
|
+
address: Address;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Resolve the airdrop factory address for `chainId`, mirroring the headless
|
|
120
|
+
* client's resolution. Returns `undefined` instead of throwing — used by
|
|
121
|
+
* query-key builders and `enabled` gates.
|
|
60
122
|
*/
|
|
61
|
-
export declare function
|
|
123
|
+
export declare function tryResolveAirdropFactoryAddress(override: Address | undefined, chainId: number | undefined): Address | undefined;
|
|
124
|
+
/**
|
|
125
|
+
* Memoize a {@link ConfidentialAirdropFactoryClient} keyed on
|
|
126
|
+
* `(publicClient, walletClient, address, chainId)`. The encryptor source is
|
|
127
|
+
* threaded through as a lazy ref (CLAUDE.md Pitfall #3): the client calls it
|
|
128
|
+
* per-encryption, so it always sees the live React value rather than one
|
|
129
|
+
* baked in at memo time.
|
|
130
|
+
*/
|
|
131
|
+
export declare function useMemoAirdropFactoryClient(opts?: AirdropClientOptions): {
|
|
62
132
|
client: ConfidentialAirdropFactoryClient | undefined;
|
|
63
133
|
resolutionError: DeploymentAddressUnavailableError | undefined;
|
|
64
134
|
publicClient: PublicClient | undefined;
|
|
@@ -67,41 +137,44 @@ export declare function useMemoFactoryClient(opts?: FactoryHookOptions): {
|
|
|
67
137
|
resolvedAddress: Address | undefined;
|
|
68
138
|
};
|
|
69
139
|
/**
|
|
70
|
-
* Memoize
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* `{ encryptedInput, signature }` pair as-is — so no encryptor is wired here.
|
|
140
|
+
* Memoize an {@link AirdropBaseClient} for `opts.address` — the surface
|
|
141
|
+
* shared by both variants (lifecycle, treasury, rescue, roles, disclosure).
|
|
142
|
+
* Use this for hooks that don't need a variant-specific method.
|
|
74
143
|
*/
|
|
75
|
-
export declare function
|
|
76
|
-
client:
|
|
144
|
+
export declare function useMemoAirdropBaseClient(opts: AirdropInstanceClientOptions): {
|
|
145
|
+
client: AirdropBaseClient | undefined;
|
|
146
|
+
publicClient: PublicClient | undefined;
|
|
147
|
+
walletClient: WalletClient | undefined;
|
|
148
|
+
chainId: number | undefined;
|
|
149
|
+
};
|
|
150
|
+
/** Memoize a {@link MerkleAirdropClient} for `opts.address`. */
|
|
151
|
+
export declare function useMemoMerkleAirdropClient(opts: AirdropInstanceClientOptions): {
|
|
152
|
+
client: MerkleAirdropClient | undefined;
|
|
77
153
|
publicClient: PublicClient | undefined;
|
|
78
154
|
walletClient: WalletClient | undefined;
|
|
79
155
|
chainId: number | undefined;
|
|
80
156
|
};
|
|
81
157
|
/**
|
|
82
|
-
*
|
|
83
|
-
* 1. Explicit `override` (eager `Encryptor` or lazy `() => Encryptor | undefined`).
|
|
84
|
-
* 2. The hook-level `encryptor` source from the hook options.
|
|
85
|
-
*
|
|
86
|
-
* Both are resolved per-call (not cached), mirroring the lazy `EncryptorSource`
|
|
87
|
-
* pattern from CLAUDE.md Pitfall #3 — the consumer's React context is the
|
|
88
|
-
* source of truth.
|
|
158
|
+
* Per-hook overrides for {@link useMemoEcdsaAirdropClient} — `dedupMode` has no on-chain getter, so it must be supplied.
|
|
89
159
|
*
|
|
90
|
-
*
|
|
91
|
-
* dynamically import `@zama-fhe/react-sdk` — calling `useZamaSDK()` from
|
|
92
|
-
* inside `mutationFn` would violate the rules of hooks. Consumers wire the
|
|
93
|
-
* encryptor at hook construction. The safe pattern is two lines:
|
|
94
|
-
* `const sdk = useZamaSDK();` then `encryptor: () => sdk.relayer` — never
|
|
95
|
-
* `() => useZamaSDK().relayer` inline (that calls a React hook inside a
|
|
96
|
-
* mutation body, violating the rules of hooks).
|
|
160
|
+
* @alpha
|
|
97
161
|
*/
|
|
98
|
-
export
|
|
162
|
+
export type EcdsaAirdropInstanceHookOptions<TData = unknown> = AirdropInstanceHookOptions<TData> & {
|
|
163
|
+
/** @see EcdsaAirdropClientConfig.dedupMode */
|
|
164
|
+
dedupMode: DedupMode;
|
|
165
|
+
};
|
|
99
166
|
/**
|
|
100
|
-
*
|
|
167
|
+
* Non-generic version of {@link EcdsaAirdropInstanceHookOptions}, for the memo helper.
|
|
101
168
|
*
|
|
102
|
-
*
|
|
103
|
-
* - Lowercase the contract address (TanStack uses structural equality; viem
|
|
104
|
-
* sometimes returns checksummed addresses).
|
|
105
|
-
* - Convert bigints to base-10 strings (TanStack's serializer doesn't handle bigints).
|
|
169
|
+
* @alpha
|
|
106
170
|
*/
|
|
107
|
-
export
|
|
171
|
+
export type EcdsaAirdropInstanceClientOptions = AirdropInstanceClientOptions & {
|
|
172
|
+
dedupMode: DedupMode;
|
|
173
|
+
};
|
|
174
|
+
/** Memoize an {@link EcdsaAirdropClient} for `opts.address`. */
|
|
175
|
+
export declare function useMemoEcdsaAirdropClient(opts: EcdsaAirdropInstanceClientOptions): {
|
|
176
|
+
client: EcdsaAirdropClient | undefined;
|
|
177
|
+
publicClient: PublicClient | undefined;
|
|
178
|
+
walletClient: WalletClient | undefined;
|
|
179
|
+
chainId: number | undefined;
|
|
180
|
+
};
|