Delegations
On-chain delegation management — grant, revoke, and query decryption delegation rights via the ACL contract.
sdk.delegations manages on-chain decryption delegation through the ACL contract. The delegate never receives the delegator's private keys — they sign with their own wallet, and the relayer verifies the on-chain delegation.
For a step-by-step walkthrough, see the Delegated decryption guide.
Import
Accessed as a namespace on the ZamaSDK instance:
import { ZamaSDK } from "@zama-fhe/sdk";
const sdk = new ZamaSDK(config); // config from createConfig()
sdk.delegations.delegateDecryption(/* ... */);
sdk.delegations.revokeDelegation(/* ... */);
sdk.delegations.isActive(/* ... */);
sdk.delegations.getExpiry(/* ... */);
sdk.delegations.getStatus(/* ... */);Methods
delegateDecryption
(params: { contractAddress: Address; delegateAddress: Address; expirationDate?: Date }) => Promise<TransactionResult>
Grants decryption rights for a confidential contract to another address. Calls ACL.delegateForUserDecryption() on-chain.
Returns { txHash: Hex; receipt: TransactionReceipt }.
expirationDate must be at least 1 hour in the future. The SDK validates this before sending the transaction.
When no expirationDate is provided, the SDK uses 2^64 - 1 (effectively permanent). The SDK accepts a standard JavaScript Date and converts it to a UTC Unix timestamp internally — timezone normalization is handled automatically.
Throws:
SignerNotConfiguredError— no signer configuredChainMismatchError— signer and provider are on different chainsWalletNotConnectedError— wallet is not connectedWalletAccountNotReadyError— wallet account is not readyDelegationExpirationTooSoonError— expiration date less than 1 hour in the futureDelegationSelfNotAllowedError— delegate address equals the connected walletDelegationDelegateEqualsContractError— delegate address equals the contract addressDelegationExpiryUnchangedError— new expiry matches the current on-chain expiryDelegationCooldownError— only one delegate/revoke per(delegator, delegate, contract)per blockAclPausedError— the ACL contract is pausedTransactionRevertedError— on-chain revert for an unmapped reason
revokeDelegation
(params: { contractAddress: Address; delegateAddress: Address }) => Promise<TransactionResult>
Revokes decryption delegation for a confidential contract. Calls ACL.revokeDelegationForUserDecryption() on-chain.
Returns { txHash: Hex; receipt: TransactionReceipt }.
Throws:
SignerNotConfiguredError— no signer configuredChainMismatchError— signer and provider are on different chainsWalletNotConnectedError— wallet is not connectedWalletAccountNotReadyError— wallet account is not readyDelegationNotFoundError— no delegation exists for this(delegator, delegate, contract)tupleDelegationCooldownError— only one delegate/revoke per tuple per blockAclPausedError— the ACL contract is pausedTransactionRevertedError— on-chain revert for an unmapped reason
isActive
(params: { contractAddress: Address; delegatorAddress: Address; delegateAddress: Address }) => Promise<boolean>
Checks whether a delegation is active. Returns true if the delegation exists and has not expired.
Signer-independent — works without a configured signer.
getExpiry
(params: { contractAddress: Address; delegatorAddress: Address; delegateAddress: Address }) => Promise<bigint>
Returns the expiration timestamp of a delegation as a Unix timestamp in seconds.
Signer-independent — works without a configured signer.
0n
No delegation (never set or revoked)
2^64 - 1
Permanent
Other
UTC Unix timestamp in seconds
getStatus
(params: { contractAddress: Address; delegatorAddress: Address; delegateAddress: Address }) => Promise<DelegationStatus>
Returns activity and expiry together ({ isActive: boolean; expiryTimestamp: bigint }) from a single on-chain read, instead of calling isActive() and getExpiry() separately.
Signer-independent — works without a configured signer.
Events
The SDK emits events during delegation operations. Subscribe via the onEvent callback in createConfig:
DelegationSubmitted
Delegation transaction sent
RevokeDelegationSubmitted
Revocation transaction sent
Delegation states
A delegation between (delegator, delegate, contract) can be in one of four states:
Never set
0n
getExpiry() returns 0n
Active
Future timestamp
isActive() returns true
Expired
Past non-zero timestamp
isActive() returns false, getExpiry() returns a non-zero past value
Revoked
0n (reset by contract)
Indistinguishable from never set via state reads — use RevokedDelegationForUserDecryption events to differentiate
The ACL contract resets the expiry to 0n on revocation, so DelegationNotFoundError covers both the never-set and revoked cases. To distinguish them, query RevokedDelegationForUserDecryption events using the ACL event decoders.
Low-level contract builders
For direct ACL contract calls without the Delegations namespace, use the contract builders:
See Contract Builders for the full list.
On-chain delegation events
Parse delegation events from transaction receipts or getLogs results:
See Event Decoders for the full list of ACL event decoders.
Related
Delegated decryption guide — step-by-step walkthrough
Token.decryptBalanceAs — decrypt a delegator's balance
Token.batchDecryptBalancesAs — batch delegated decryption
Contract builders — low-level ACL delegation builders
useDelegateDecryption — React hook to grant delegation
useRevokeDelegation — React hook to revoke delegation
useDelegationStatus — React hook to query delegation status
useDecryptBalanceAs — React hook to decrypt as a delegate
useBatchDecryptBalancesAs — React hook for batch delegation decryption
Last updated