Release notes.
What shipped in each minor + major. Authoritative source: npm + GitHub releases, this page is the navigable summary.
latest resolves SDK 2.1.0, which is what a plain pnpm add @tokenops/sdk installs. The stable 2.x docs live under /v2 and now cover the 2.1 kernel, contract-kit, confidential-client, draft-vault, observability and versioned vesting-engine surfaces. The unversioned pages remain the maintained 1.x docs during the route transition. See migrating to v2 for the delta and the 1.x support window.- ·Stable, backwards-compatible 2.x release on the latest dist-tag. A plain pnpm add @tokenops/sdk now installs 2.1.0.
- ·Adds /kernel, /contract-kit, /confidential-client and /draft-vault, plus /observability, /observability/node and /observability/web for structured SDK telemetry.
- ·Adds the versioned vesting engine v1 and createVestingEngine("v1") for deterministic schedule math outside a client. Existing deployment addresses and contract pins are unchanged.
- ·Requires the zod ^4.1.11 peer. The observability adapters use optional @sentry/node and @sentry/nextjs ^11.4.0 peers; applications that do not import those adapters do not need Sentry.
- ·The 2.x API catalogs now cover every public package export, including React support types, /fhe-airdrop/merkle and the flat observability declaration entrypoints.
- v2.0.02026-10-10
- ·Stable 2.0 release on the latest dist-tag. A plain pnpm add @tokenops/sdk now installs 2.0.0; pin @tokenops/sdk@1.6.0 only while maintaining a legacy integration.
- ·Ships the canonical airdrop v2 contracts on mainnet and Sepolia, plus the 2.0 vesting, disperse, testnet-faucet and FHE core surfaces documented under /v2.
- ·Requires the Zama 3.6 peer line and follows normal SemVer. The receipt-free and Safe create surface of /fhe-airdrop remains @beta.
- ·The 1.x line receives critical security and correctness fixes through 2027-01-08; its deployed contracts remain live.
- v2.0.0-rc.12026-10-07
- ·Release candidate for 2.0.0 on the next dist-tag; latest stays on 1.6.0 until 2.0.0. The API is frozen - later candidates carry fixes only, except the receipt-free and Safe create surface of /fhe-airdrop, which is @beta.
- ·Breaking: /fhe-airdrop targets the canonical deployment of the airdrop v2 contracts (commit 6b0edcc, with the external-audit fixes) at the same addresses on mainnet and Sepolia. Every alpha address moved; an instance created through an alpha factory is not in the canonical registry.
- ·Breaking: the @zama-fhe/sdk and @zama-fhe/react-sdk peers move to ~3.6.0. Pass a ZamaSDK as the encryptor and sdk.decryption as the user decryptor; createSepoliaEncryptorWeb moves to @tokenops/sdk/fhe/web.
- ·Breaking: the deprecated vesting useGet* hooks, the disperse fee-reserve alias, the string blockers on both preflights, and the dedupMode client option are removed. Role hooks name the grantee holder.
- ·Breaking: /fhe drops EncryptedInput64, EncryptedHandle and ExternalInputProof, and the root drops DisperseId, asDisperseId, ClientPair and ContractRef. Vesting PartialClaimArgs is discriminated by feeType, the /fhe-airdrop/react variable types are renamed, and the vesting and disperse create, register, split, disperse and withdraw hooks resolve Mined | Pending. See /v2/migration/from-1x.
- ·Added: gas headroom on every write (DEFAULT_GAS_HEADROOM_PERCENT, gasHeadroomPercent, per-call gas), receipt-free writes across vesting, disperse and airdrop creates, query options on every read hook, and MAX_EUINT64_PER_INPUT_PROOF.
- ·Fixed: FHE writes no longer run out of gas after a same-block estimate, estimate reverts no longer leave nonce gaps, reverted receipts never resolve as success, and every write refuses a wallet on a different chain than the public client.
- v2.0.0-alpha.42026-10-01
- ·Pre-release on the alpha dist-tag; latest stays on 1.6.0. Built against external-audit fixes (contracts 005980d) that are still under review and not yet merged, for internal testing only.
- ·Breaking: every Merkle leaf input is bound to the instance itself, and anyone may submit a claim. The payout still goes to entry.account, only the account may redirect with to, and claimAndUnwrap stays self-only. The submitter option and CampaignEntry's bound-to address are removed; entries built under earlier alphas cannot be claimed.
- ·Breaking: every Sepolia fheAirdrop address moved to a preview deployment under the CREATE3 salt version sdk-preview-13cad511. The factory is now 0xD5906f366Ff50909F403c8EDfDe680015563046a.
- ·Breaking: AirdropInitialized was reshaped and split into ECDSAAirdropInitialized / MerkleAirdropInitialized, and ComplianceManagerCloned gained managerImplementation - a filter on either old signature matches nothing.
- ·Breaking: the React create, register, split and disperse hooks resolve Mined | Pending. Narrow with if (data.pending) return; before reading a receipt-derived field.
- ·Added: create commitments (instance address, compliance-manager implementation, compliance delegate) that the factory checks before consuming the salt, with expected, quoteCreateCommitments and CreateCommitmentMismatchError. A planned Merkle campaign is created from its plan.
- ·Added: receipt-free writes for Safe and multisig signers (waitForReceipt: false), with PendingWrite / MinedWrite and encodeInstanceRoleSplit for a MultiSend role split.
- ·Added: readUnwrapRequest / parseUnwrapRequest and useUnwrapRequest for the finalizeUnwrap handoff; readDedupMode, canExtendClaimWindow, deploymentBlockNumber, factory.tokenOf and rescueNativeToken.
- ·Fixed: preflightCreate now blocks initializer reverts and reports the factory's maxGasFee ceiling before the creator's own bound, matching the write path.
- v2.0.0-alpha.32026-09-16
- ·Pre-release on the alpha dist-tag; latest stays on 1.6.0. Built against contracts that have not completed a security audit, for internal testing only.
- ·Breaking: CommonAirdropParams gains a required maxAcceptedGasFee. The factory resolves the creator's per-claim fee at execution time and reverts GasFeeNotAccepted above the bound. Pass the newly exported UINT96_MAX to accept whatever resolves.
- ·Breaking: every Sepolia fheAirdrop address moved again - the redeploy bumped the canonical salt version to 2.0.2, since CREATE3 returns a consumed salt's existing address without comparing codehashes and would otherwise have handed back the previous contracts.
- ·Breaking: AirdropInitialized gained a uint256 gasFee argument, so any consumer filtering the old topic must re-derive it.
- ·Added: factory.isAirdrop and useIsAirdrop, the genuineness check - a claim against a look-alike instance succeeds and delivers nothing rather than reverting. preflightClaim folds it in when passed a factory.
- ·Added: refreshComplianceBalance and useRefreshComplianceBalance, permissionless restoration of the compliance clone's live-balance grant.
- ·Added: the factory's own fee ceiling (setMaxGasFee / maxGasFee, DEFAULT_ADMIN_ROLE) and resolveGasFee(creator), with useSetMaxGasFee and useResolveGasFee.
- ·Fixed: getClaimAmount is repeatable, not unconditional - on ECDSA it now reverts once a replay guard is consumed. Point availability checks at isSignatureValid, which never reverts.
- ·Fixed: rescueERC20 refuses the campaign token, discloseHandleToParty demands persistent user-decryption ACL on both legs, and the factory admin set can no longer be emptied.
- v2.0.0-alpha.22026-09-10
- ·Pre-release on the alpha dist-tag; latest stays on 1.6.0. Built against unaudited contracts, for internal testing only.
- ·Breaking: MerkleAirdropClient.claim and .getClaimAmount take an explicit claim identity, so a relayer can settle a leaf on a recipient's behalf.
- ·Breaking: CampaignEntry is { account, boundTo, handle, inputProof, merkleProof }; recipient is removed with no alias, so entries serialised under alpha.1 must be re-keyed.
- ·Breaking: every Sepolia fheAirdrop address moved - instances created through the previous factory are unreachable from this build.
- ·Added: submitter?: Address on every campaign builder, batched relayed rosters chunked at 32 recipients, and UnauthorizedRedirectError.
- ·Added: full React parity for the airdrop surface, split across /fhe-airdrop/react and the factory-admin tier on /fhe-airdrop/advanced/react.
- ·Fixed: useMerkleClaim invalidated the submitter's cache entry rather than the claim identity's, leaving the recipient's read stale.
- v2.0.0-alpha.12026-09-07
- ·First 2.0.0-alpha build. /fhe-airdrop now targets confidential airdrop v2 - the subpath name is unchanged, everything behind it is new.
- ·v1 and v2 are different contract systems, not two versions of one: there is no in-place upgrade path for a deployed v1 airdrop.
- ·Breaking: DEPLOYED_ADDRESSES.fheAirdrop reshaped from one key to four. This is the one breaking change outside the alpha-tagged surface.
- ·Breaking: the EIP-712 claim typehash gained two fields, so a v1 signature will not verify against a v2 instance.
- ·AIRDROP_CONTRACTS_COMMIT pins the contract commit the vendored ABIs were generated from.
- v1.6.02026-07-28
- ·Operator prerequisite DX helpers on @tokenops/sdk/fhe, so a UI can check ERC-7984 operator approval before offering a write.
- ·preflightCreateAirdrop and preflightCreateVesting no longer throw on a non-ERC-7984 token - they report it as a blocker instead.
- ·fhe-vesting Sepolia factory repointed at the redeployed address.
- ·Last feature release on the 1.x line: from 2026-09-05 every new capability lands on 2.x.
- v1.5.12026-07-23
- ·Republish baseline - package content identical to 1.5.0 apart from the version number.
- ·1.2.0 through 1.5.0 were unpublished from npm the same day, so 1.5.1 is the first installable version delivering all of their changes.
- ·Rolls up wagmi v3 peer support (the peer range widens to ^2.0.0 || ^3.0.0, with v2 still fully supported).
- ·Rolls up the EncryptorInitPhase / onPhase init-phase callback for surfacing FHE key-download progress in a UI.
- ·Rolls up two documentation passes: the 6-decimals amount convention and the silent-zero transfer warning, applied at every relevant entry point.
- v1.1.12026-06-23
- ·Testnet faucet SDK surface for Sepolia TTT + CTTT, including headless clients, ABIs, types, errors, and React hooks.
- ·Faucet quickstart, hooks catalog, ABI/type/error reference pages, and API reference coverage.
- ·Canonical Sepolia faucet registry resolution for React read hooks, plus clearer mint hook TSDoc.
- ·First faucet release on npm: v1.1.0 was tagged but never published (release-pipeline fix), so v1.1.1 is the registry version.
- v1.0.02026-05-29
- ·Public release. Three FHE products (vesting, airdrop, disperse) under their own subpaths.
- ·Branded primitives: VestingId, AirdropId, DisperseId, EncryptedHandle, plus 4 more.
- ·Eager + lazy encryptor injection (React lazy-factory pattern, Node eager).
- ·DEPLOYED_ADDRESSES baked in for Sepolia (all 3) + Ethereum mainnet (fhe-disperse).
- ·Per-product React subpaths under @tokenops/sdk/<product>/react; vesting and airdrop also expose @tokenops/sdk/<product>/advanced/react for advanced factory helpers.
- ·Two optional Zama peer deps: @zama-fhe/react-sdk and @zama-fhe/sdk (both ^3.0.0); root package ships zero FHE runtime deps (only abitype in dependencies).
- ·Security: OpenZeppelin audits published — fhe-disperse + fhe-vesting (May 2026) and fhe-airdrop (Jan 2026), 0 critical / 0 high; reports linked from /resources.
Upstream dependencies
Known breaking changes in the @zama-fhe/sdk peer dependency, verified against the published npm typings + release notes.
npm view @zama-fhe/sdk time lists every published version with its date.encrypt() now returns contract-ready hex instead of raw bytes, and the handles field was renamed encryptedValues (release note: “return encrypt handles and proof as contract-ready hex”, SDK-200). Code that destructures handles gets undefined at runtime.
// @zama-fhe/sdk <= 3.0.1
interface EncryptResult {
handles: Uint8Array[];
inputProof: Uint8Array;
}
// @zama-fhe/sdk >= 3.1.0 — field renamed, raw bytes -> contract-ready hex
type EncryptResult = {
encryptedValues: `0x${string}`[]; // bytes32 hex
inputProof: `0x${string}`;
};handles from the encryptor result internally, so it breaks at runtime with @zama-fhe/sdk 3.1.0 or later — even though the ^3.0.0 peer range lets the newer version install. Pin the peer until a @tokenops/sdk release notes compatibility:{
"dependencies": {
"@tokenops/sdk": "^1.1.1",
"@zama-fhe/sdk": "~3.0.1"
}
}Often blamed for the encrypt-shape change — it shipped two days after 3.1.0, so upgrades from 3.0.x that landed on 3.2.0 saw the breakage here first. The published 3.1.0 and 3.2.0 typings declare an identical EncryptResult; the actual boundary is 3.0.x → 3.1.0. What 3.2.0 did ship: upgrade codemods for the 3.1.0 migration and configurable, silent-by-default logging.
0.x history
Earlier work happened in the pre-launch sprint and isn't versioned here. See the SDK repo's git log for the rounds-pattern commit history.
npm publishes
Every release pushes a tarball to npm view @tokenops/sdk versions , the cleanest source-of-truth.