Vesting 2.0 type surface.
Args that take an encrypted amount are unions: pass plaintext (the SDK encrypts) or a pre-built EncryptedInput, never both. Claims are discriminated by the manager's FeeType. Receipt-free writes add a Pending* result next to each mined one.
Id aliases (root export)· 2
VestingIdHex aliasbytes32 schedule id from VestingCreated. Exported from the @tokenops/sdk root with asVestingId, not from the fhe-vesting subpath.
EncryptedHandleHex aliasbytes32 pointer to an FHE ciphertext. Root export; the /fhe export of the same name is removed in 2.0, so import it from the root or use Hex.
Args· 13
VestingParams{ recipient, startTimestamp, endTimestamp, cliffSeconds, releaseIntervalSecs, timelockSeconds, initialUnlockBps, cliffAmountBps, isRevocable }Plaintext schedule struct, field for field with the contract.
CreateManagerArgs{ token, userSalt, splitEnabled?, pausableEnabled?, account?, gas? }Input to createManager / createManagerAndGetAddress. waitForReceipt is not part of it: the methods take CreateManagerArgs & ReceiptMode.
CreateVestingArgs{ params, amount, encryptor?, account?, gas? } | { params, encryptedInput, account?, gas? }Input to createVesting / useCreateVesting. Passing both amount and encryptedInput is a compile error.
BatchCreateVestingArgs{ items: { params, amount }[], encryptor?, account?, gas? }All amounts share one input proof, so items.length is capped at MAX_EUINT64_PER_INPUT_PROOF (32), and by maxBatchSize on chain.
ClaimArgs{ vestingId, feeType: FeeType.Gas, value, account?, gas? } | { vestingId, feeType: FeeType.DistributionToken, account?, gas? }claim / adminClaim. Gas managers need value (the fee in wei); DistributionToken managers deduct the fee on chain.
PartialClaimArgs{ vestingId, account?, gas? } & ({ feeType: FeeType.Gas, value } | { feeType: FeeType.DistributionToken }) & ({ amount, encryptor? } | { encryptedInput })partialClaim / adminPartialClaim and their hooks. Discriminated by feeType like ClaimArgs, so a value on a DistributionToken manager, or a missing one on a Gas manager, fails to compile.
SplitVestingArgs{ vestingId, numerator, denominator, newRecipient, encryptor?, preScaled?, account?, gas? }The ratio is scaled to FHE_SPLIT_DENOMINATOR unless preScaled. splitVesting takes SplitVestingArgs & ReceiptMode.
InitiateTransferArgs{ vestingId, newRecipient, transferDurationSeconds, account?, gas? }Recipient-side handoff; the new recipient has transferDurationSeconds to accept.
DiscloseArgs{ vestingId, party, disclosureType, account?, gas? }Grant a third party ACL on one encrypted view of a vesting.
WithdrawAdminArgs{ account?, gas? } & ({ amount, encryptor? } | { encryptedInput })withdrawAdmin. Exactly one of amount or encryptedInput.
WithdrawTokenFeeArgs{ to, account?, gas? } & ({ amount, encryptor? } | { encryptedInput })withdrawTokenFee. Exactly one of amount or encryptedInput.
SetOperatorArgs{ publicClient, walletClient, token, spender, account?, deadline?, waitForReceipt?, telemetry?, gas?, gasHeadroomPercent? }setOperator, now exported from /fhe-vesting. spender is the manager clone. deadline defaults to ERC7984_OPERATOR_MAX_DEADLINE. RevokeOperatorArgs is the same without deadline.
Concept primer →EncryptUint64Args{ encryptor, contractAddress, userAddress, value }encryptUint64: an EncryptedInput bound to the (contract, user) pair. EncryptUint64BatchArgs takes readonly values.
Concept primer →
Results· 11
CreateManagerResult{ hash, manager, pending?: never }Mined result of createManager(AndGetAddress); manager is parsed from ManagerCreated. Extends MinedWrite.
PendingCreateManagerResult{ hash, manager: undefined, pending: true }With waitForReceipt: false. hash is what the wallet returned (a safeTxHash from a Safe). Extends PendingWrite.
Concept primer →SplitVestingResult{ hash, newVestingId, pending?: never }Mined result of splitVesting; newVestingId is parsed from VestingSplit.
PendingSplitVestingResult{ hash, newVestingId: undefined, pending: true }With waitForReceipt: false; read the executed transaction's VestingSplit log for the id.
Concept primer →EncryptedViewResult{ handle, hash }Returned by the encrypted views (useAccessVestedAmount and the rest). The handle is granted to the caller for user-decryption.
DiscloseToPartyResult{ hash, handle }discloseToParty / adminDiscloseToParty; handle comes from the AmountDisclosed event.
BatchDiscloseToPartyResult{ hash, handles }handles[i] corresponds to vestingIds[i], paired by vestingId and disclosure type.
CreateVestingPreflightReport{ token, hasCreatorRole, isOperatorSet, ready, blockerErrors }preflightCreateVesting / usePreflightCreateVesting. blockerErrors is TokenOpsSdkError[]; branch on error.code or render error.message. isOperatorSet is also false when approval could not be read, so check blockerErrors first.
PreflightResult{ ready, blockers }preflightClaim (headless only). blockers holds the typed errors the claim would throw, such as InsufficientBalanceError for a wallet short of the gas fee.
VestingInfo{ recipient, startTimestamp, endTimestamp, revokeTimestamp, cliffReleaseTimestamp, releaseIntervalSecs, timelock, initialUnlockBps, cliffAmountBps, isRevocable }getVestingInfo / useVestingInfo. startTimestamp === 0 means the schedule does not exist.
PendingTransfer{ newRecipient, initiatedAt, expiresAt }usePendingVestingTransfer; all zero when no transfer is pending.
Receipt, gas and query options· 5
ReceiptModeReceiptMode<true> = { waitForReceipt?: true }, ReceiptMode<false> = { waitForReceipt: false }, ReceiptMode = { waitForReceipt?: boolean }Selects the mined or pending overload. A runtime boolean, as hooks pass, uses the default form and yields the union narrowed by pending. MinedWrite and PendingWrite are the two halves.
Concept primer →GasHeadroomOption{ gasHeadroomPercent? }On every client config and hook option. Default DEFAULT_GAS_HEADROOM_PERCENT (25); 0 sends the bare estimate.
Concept primer →GasOverride{ gas? }A per-call gas limit sent as is, on every argument-object write and the encrypted-view, disclosure and withdraw hook variables.
Concept primer →ReadHookQueryOptions{ query?: Omit<UseQueryOptions, 'queryKey' | 'queryFn'> }From /fhe-vesting/react and /fhe-vesting/advanced/react. query.enabled can only turn a ready query off; query.select keeps the hook's data type.
Concept primer →PredictManagerArgs{ token, userSalt, deployer, blockNumber, splitEnabled?, pausableEnabled? }predictManagerAddress on the advanced client. Exported from /fhe-vesting/advanced and /fhe-vesting/advanced/react only.
Config and enums· 5
FeeTypeenum { Gas = 0, DistributionToken = 1 }The claim discriminant. feeTypeName() stringifies it for logs.
DisclosureTypeenum { TotalAllocation = 0, SettledAmount = 1, VestedAmount = 2, ClaimableAmount = 3 }Which encrypted view discloseToParty discloses.
CustomFee{ enabled, preferredFeeType, gasFee, tokenFee }Per-creator fee override on the factory, read with getCustomFee.
ConfidentialVestingFactoryClientConfig{ publicClient, walletClient?, address?, chainId?, telemetry?, gasHeadroomPercent? }address defaults to the registry entry for the chain id.
ConfidentialVestingManagerClientConfig{ publicClient, walletClient?, address, encryptor?, aclAddress?, telemetry?, gasHeadroomPercent? }aclAddress overrides the chain-registry FHEVM ACL lookup the encrypted views use.
Encryptor· 5
Encryptor{ encrypt({ values, contractAddress, userAddress }) => { encryptedValues, inputProof } }Mirrors ZamaSDK.encrypt from @zama-fhe/sdk 3.6, so a ZamaSDK satisfies it directly.
Concept primer →EncryptorSourceEncryptor | () => Encryptor | undefinedWhat clients and hooks accept. In React pass encryptor: () => zamaSDK so the live instance is used per encryption.
Concept primer →FheValueInput{ type: euint8..euint256, value: bigint } | { type: 'ebool', value } | { type: 'eaddress', value }Mirrors upstream EncryptInput.
EncryptedInput{ handle, inputProof }One externalEuint64 ciphertext plus its input proof, bound to (contract, user).
EncryptedInputs{ handles, inputProof }Several ciphertexts under one proof; handles[i] is the i-th value.