> ## Documentation Index
> Fetch the complete documentation index at: https://fhenix-docs-deep-dive-rewrite.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# TaskManager

> Onchain entry point for CoFHE integration that initiates FHE operations, generates unique handles, and verifies decrypt result signatures

| Aspect               | Description                                                                                                                                                                                                                                                                                    |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Type**             | Contract deployed on the host chain, UUPS-upgradeable behind a proxy.                                                                                                                                                                                                                          |
| **Function**         | Acts as the onchain entry point for CoFHE integration.                                                                                                                                                                                                                                         |
| **Responsibilities** | • Initiates FHE operations requested through the `FHE.sol` library. <br />• Generates the unique handles that reference future FHE results. <br />• Emits structured task events for the offchain services. <br />• Verifies the signatures on encrypted inputs and published decrypt results. |
| **Deployment**       | A separate TaskManager contract is deployed on each supported host chain, enabling chain-specific integrations.                                                                                                                                                                                |

## Two signers

The TaskManager holds two distinct signer addresses, one per trust boundary:

| Signer                                                            | Verifies                                                                                                                                                                                                                                                       |
| ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <code style={{ whiteSpace: "nowrap" }}>verifierSigner</code>      | Encrypted inputs: the ZK Verifier signs each verified batch, and `batchVerifyInputs` checks that signature before emitting `InputVerified(ctHash, commitment)` per input. The signature binds the consuming contract, so a batch cannot be replayed elsewhere. |
| <code style={{ whiteSpace: "nowrap" }}>decryptResultSigner</code> | Decrypt results: [Teecryptor](/deep-dive/cofhe-components/teecryptor) signs each plaintext it returns, and the publish path checks that signature before storing the result.                                                                                   |

## Decrypt result signature verification

The TaskManager supports **permissionless publishing of decrypt results**. Anyone holding a valid signature from the decryption service can publish the result onchain. Today that signature comes from Teecryptor; a decentralized [Threshold Network](/deep-dive/research/future-plans) is the planned successor.

Verified results are stored in the [PlaintextsStorage](/deep-dive/cofhe-components/plaintext-storage) contract, where any contract can read them back with `getDecryptResult` (reverts with `DecryptionResultNotReady` if pending) or `getDecryptResultSafe` (returns a ready flag).

### Functions

All take `(ctHash, result, signature)`; the batch variants take parallel arrays.

| Function                                                                   | Description                                                                          |
| -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| <code style={{ whiteSpace: "nowrap" }}>publishDecryptResult</code>         | Verify the signature and store the decrypt result onchain. Emits `DecryptionResult`. |
| <code style={{ whiteSpace: "nowrap" }}>publishDecryptResultBatch</code>    | Batch publish multiple results in one transaction for gas efficiency.                |
| <code style={{ whiteSpace: "nowrap" }}>verifyDecryptResult</code>          | Verify a signature without publishing (view). Reverts on failure.                    |
| <code style={{ whiteSpace: "nowrap" }}>verifyDecryptResultSafe</code>      | Verify a signature without publishing (view). Returns `false` on failure.            |
| <code style={{ whiteSpace: "nowrap" }}>verifyDecryptResultBatch</code>     | Batch verify (view). Reverts on the first failure.                                   |
| <code style={{ whiteSpace: "nowrap" }}>verifyDecryptResultBatchSafe</code> | Batch verify (view). Returns a `bool[]` of per-item outcomes.                        |
| <code style={{ whiteSpace: "nowrap" }}>setDecryptResultSigner</code>       | Admin-only. Takes an address; sets the authorized signer.                            |

### Signature message format

The signed message is a fixed **76-byte** buffer:

| Field      | Size     | Encoding                                         |
| ---------- | -------- | ------------------------------------------------ |
| `result`   | 32 bytes | uint256, big-endian, left-padded with zeros      |
| `enc_type` | 4 bytes  | i32, big-endian (extracted from ctHash metadata) |
| `chain_id` | 8 bytes  | u64, big-endian (from `block.chainid`)           |
| `ct_hash`  | 32 bytes | uint256, big-endian                              |

The message is hashed with `keccak256` and verified using OpenZeppelin's `ECDSA.tryRecover`. The `enc_type` and `chain_id` are derived onchain, binding each signature to a specific ciphertext type and chain.
