Confidential vesting on the 2.0 line
The same vesting contracts as 1.6, on the Zama 3.6 encryptor, with receipt-free creates and gas headroom.
Where to start
Deploy a manager, approve it as operator, open a schedule and claim it, headless or with hooks.
Deploy, open, claim, disclose, transfer and recover, each with the hooks that ship it.
Every hook on /fhe-vesting/react and /fhe-vesting/advanced/react, generated from the installed package.
Deployment
The vesting factory is deployed on Sepolia only, at the same address as on 1.6. The clients resolve it from DEPLOYED_ADDRESSES.fheVesting.confidentialVestingFactory by chain id, so you do not pass address on Sepolia. Each operator then deploys a per-user manager clone through it.
| Chain | confidentialVestingFactory |
|---|---|
| Sepolia (11155111) | 0x059d6Bb8ff9a13E794fe416d4757d7310CdC69ab |
| Ethereum mainnet (1) | null - registry-not-deployed |
Breaking changes since 1.6
Most of these fail at typecheck. The holder rename is a deprecation, and the telemetry event is a runtime removal. The vesting contracts did not change, so an existing manager clone keeps working; only your call sites move.
Zama SDK peers move to
~3.6.0The encryptor is a
EncryptorsZamaSDK: passencryptor: () => zamaSDKin React, or build one withcreateSepoliaEncryptorin Node. Client signatures and theencryptUint64/encryptUint64Batchoutputs are unchanged.Encrypted views keep only their
useAccess*namesRead an encrypted amount with
From 1.xuseAccessVestedAmount,useAccessClaimableAmount,useAccessTotalAllocationanduseAccessSettledAmount(argsUseAccess*Args). The older aliases, deprecated in 1.6, are removed; the functions are the same.CreateVestingPreflightReportreportsblockerErrorsonlyThe
Typesstring[]field is gone.preflightCreateVestingandusePreflightCreateVestingreturnblockerErrors: TokenOpsSdkError[]; branch onerror.codeor rendererror.message.readyis unchanged.PartialClaimArgsis discriminated byfeeTypeLike
Claim flowClaimArgs:{ feeType: FeeType.Gas, value }on a gas-fee manager,{ feeType: FeeType.DistributionToken }withoutvalueotherwise. A mismatchedmsg.valuenow fails at typecheck forpartialClaim,adminPartialClaim,usePartialClaimanduseAdminPartialClaim.Create and split hooks resolve
Mined | Pending
Receipt-free writesuseCreateManager,useCreateManagerAndGetAddressanduseSplitVestingacceptwaitForReceipt, sodata.manager/data.newVestingIdtype asX | undefined. Narrow withif (data.pending) return;. Headless calls that never pass the option keep the mined type.PredictManagerArgsmoves to/fhe-vesting/advanced/reactIt is no longer exported from
Factory client/fhe-vesting/react. Import it from/fhe-vesting/advancedor/fhe-vesting/advanced/react, next topredictManagerAddress/usePredictManagerAddress.Role hooks name the grantee
holder
RolesuseHasRole({ role, holder })andmutate({ role, holder })onuseGrantRole/useRevokeRole.account(read) andaccountTarget(write) still compile, are deprecated, and cannot be combined withholder.The
fhe-vesting.react.hook.firedtelemetry event is goneIts
TelemetryhookNamecarried a family label, not the hook. The headlessfhe-vesting.client.initevent and the write spans are unchanged; drop any dashboard keyed on the removed event.
Added
Gas headroom on every write, plus per-call
gasEach write estimates gas and pads it by
Gas headroomDEFAULT_GAS_HEADROOM_PERCENT(25) unless the client or hook setsgasHeadroomPercent. Every argument-object write takesgas(GasOverride), sent as is. Hooks over positional setters use the client headroom.Receipt-free
createManagerandsplitVesting
Receipt-free writeswaitForReceipt: falseoncreateManager,createManagerAndGetAddressandsplitVestingreturns on submission withPendingCreateManagerResult/PendingSplitVestingResult(pending: true), for Safe and multisig signers. Read the address or id from the executed transaction's logs.queryon every read hookRead hooks take
Query optionsquery(ReadHookQueryOptions): TanStack options minusqueryKey/queryFn.query.enabledcan turn a ready query off, never an unready one on. Immutable manager reads now default tostaleTime: Infinity.Operator helpers on
/fhe-vesting
OperatorssetOperator,revokeOperator,ERC7984_OPERATOR_MAX_DEADLINE,SetOperatorArgsandRevokeOperatorArgsare exported from the vesting subpath, as on/fhe-disperseand/fhe-airdrop. The React subpath re-exportsuseIsOperatoranduseEnsureOperator.FHE_VESTING_KEYandFHE_VESTING_NAMESPACEThe query-key prefix every vesting hook uses, exported from
Hooks/fhe-vesting/reactso you can invalidate the whole subpath without hand-typing strings.MAX_EUINT64_PER_INPUT_PROOF(32)The most
Manager clienteuint64values one input proof carries.batchCreateVestingrefuses more items withInvalidArgumentErrorbefore encrypting; the manager's on-chainmaxBatchSizestill applies.Telemetry spans on every manager write
Claims, transfers, disclosures, withdrawals, role writes and the encrypted views are each bracketed with a named span on
TelemetryConfidentialVestingManagerClient, not only some admin writes.Error classes on the React subpath
Errors/fhe-vesting/reactre-exports the error palette, includingTokenOpsValidationError, the vesting errors and the wallet errors, so a component caninstanceofwithout a second import path.
Changed and fixed
WithdrawAdminArgs/WithdrawTokenFeeArgsunionswithdrawAdminandwithdrawTokenFeetake exactly one ofamountorencryptedInput.useWithdrawAdminanduseWithdrawTokenFeenow acceptencryptedInputalone (it always threw before), a lazy per-callencryptor, andgas.batchRevokeVestingsorts its idsThe contract requires strictly ascending ids. The SDK now sorts a copy, so pass them in selection order; duplicates throw
InvalidArgumentErrorinstead of revertingVestingIdsNotStrictlyAsc.Hooks return
resolutionErrorinstead of throwing in renderA client constructor that rejects its config (a malformed
address, a badgasHeadroomPercent) no longer crashes the component: read hooks stay disabled and mutation hooks throw it when called.Mainnet is a known chain without a deployment
The vesting factory registry records mainnet as
Deploymentsnull. A registry miss reportsDeploymentAddressUnavailableErrorwithcontext.reasonregistry-not-deployedfor that entry andregistry-unknown-chainfor a chain with no entry.preflightClaimreports a short wallet asInsufficientBalanceErrorA claimant whose ETH balance is below the gas fee gets
ErrorsInsufficientBalanceError(balanceKind: "eth"), notInsufficientFeeError. Code branching onTOKENOPS_INSUFFICIENT_FEEfor this blocker needs the new code.Receipt and wallet checks
createManagerthrowsReceiptEventNotFoundError/ReceiptEventAmbiguousErrorfor a missing or repeatedManagerCreatedevent. Every write refuses a wallet on a different chain than the public client withWalletChainMismatchError, before estimating.Batch disclosure matches handles correctly
batchDiscloseToPartyandadminBatchDiscloseToPartypair eachAmountDisclosedevent with its input by vestingId and disclosure type, so a vestingId repeated with different types gets the right handle at each position.Errors stop leaking confidential inputs
Split errors no longer repeat the encrypted numerator, and
encryptUint64/encryptUint64Batchrange errors no longer copy the amount intocontext.value, which reaches the telemetry sink.MissingEncryptorErrornames the method you called.
Reference
Generated or derived from v2.0.0-rc.1 of the package: ABIs, events and hooks come from the installed artifact.
The factory and manager clients, plus the advanced factory client.
Args unions, result shapes, receipt-free results and fee enums.
Manager roles, the factory fee role, and the holder role hooks.
Every event the factory and manager ABIs declare.
Factory, manager and ERC-7984 operator ABIs.
Vesting errors and the shared palette, with recovery notes.