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

# Off-Chain Decryption Flow

> Complete flow of off-chain decryption using decryptForTx and decryptForView

# Off-Chain Decryption Flow

## Overview

This document lays out the complete flow of off-chain decryption requests. There are two methods for decrypting encrypted data off-chain:

* **`decryptForTx`** — Returns the plaintext value and a Threshold Network signature. Used when the decrypted value needs to be submitted on-chain (e.g., via `FHE.publishDecryptResult` or `FHE.verifyDecryptResult`).
* **`decryptForView`** — Returns only the plaintext value. Used for UI display or off-chain reads where no on-chain proof is needed.

## Key Components

| Component             | Description                                                                             |
| --------------------- | --------------------------------------------------------------------------------------- |
| **CtHash**            | A `bytes32` handle representing an encrypted value. Fetched on-chain.                   |
| **SDK Client**        | Client library handling `permits` and the `decryptForTx` / `decryptForView` operations. |
| **Threshold Network** | Decentralized decryption network that handles the requests and produces signatures.     |
| **ACL**               | On-chain **A**ccess **C**ontrol **L**ist responsible for tracking **CtHash** access.    |

## decryptForTx Flow

Use `decryptForTx` when you need to submit the decrypted value on-chain with a proof.

<Steps>
  <Step title="Fetching the CtHash">
    Solidity contract:

    ```solidity theme={null}
    contract Example {
        euint32 public count;

        function setCount(uint32 num) public {
            count = FHE.asEuint32(num);
            FHE.allowThis(count);
            FHE.allowPublic(count); // Allow anyone to request decryption
        }
    }
    ```

    Fetch the `CtHash` from the chain:

    ```typescript theme={null}
    const ctHash = await example.count();
    ```

    <Note>
      All encrypted types (`euint8`, `euint16`, `euint32`, `euint64`, `euint128`, `ebool`, `eaddress`) are wrappers around `bytes32`. The data returned from the contract can be used as a `CtHash` directly.
    </Note>
  </Step>

  <Step title="Request Decryption">
    Call `decryptForTx` on the SDK client. Since `FHE.allowPublic` was used, no permit is needed:

    ```typescript theme={null}
    const result = await client
      .decryptForTx(ctHash)
      .withoutPermit()
      .execute();
    ```

    If the value was granted access via `FHE.allow` (not `allowPublic`), use `.withPermit()` instead:

    ```typescript theme={null}
    const result = await client
      .decryptForTx(ctHash)
      .withPermit()
      .execute();
    ```
  </Step>

  <Step title="Threshold Network Verification">
    Behind the scenes:

    1. The SDK sends the decryption request to the Threshold Network
    2. The Threshold Network verifies on-chain that the requester has access to the `CtHash` via the ACL
    3. The Threshold Network performs secure decryption
    4. The Threshold Network signs the plaintext result and returns both the plaintext and the signature
  </Step>

  <Step title="Submit On-Chain with Proof">
    The SDK returns an object containing the decrypted value and signature. Submit these on-chain:

    ```typescript theme={null}
    // result contains: { ctHash, decryptedValue, signature }

    await example.revealCount(
      result.decryptedValue,
      result.signature
    );
    ```

    The on-chain function verifies the signature using `FHE.publishDecryptResult` or `FHE.verifyDecryptResult`:

    ```solidity theme={null}
    function revealCount(uint32 _decrypted, bytes memory _signature) external {
        FHE.publishDecryptResult(count, _decrypted, _signature);
    }
    ```
  </Step>
</Steps>

***

## decryptForView Flow

Use `decryptForView` when you only need to display the value in the UI — no on-chain transaction is needed.

<Steps>
  <Step title="Fetching the CtHash">
    The contract must have granted access to the user via `FHE.allow` or `FHE.allowSender`:

    ```solidity theme={null}
    contract Example {
        mapping(address => euint32) private balances;

        function getBalance() public view returns (euint32) {
            return balances[msg.sender];
        }

        function deposit(uint32 amount) public {
            balances[msg.sender] = FHE.asEuint32(amount);
            FHE.allowThis(balances[msg.sender]);
            FHE.allowSender(balances[msg.sender]); // Grant access to the user
        }
    }
    ```

    ```typescript theme={null}
    const ctHash = await example.getBalance();
    ```
  </Step>

  <Step title="Request Decryption">
    Call `decryptForView` with a permit (required since this is user-specific data):

    ```typescript theme={null}
    const result = await client
      .decryptForView(ctHash)
      .withPermit()
      .execute();

    console.log(`Balance: ${result.decryptedValue}`);
    ```
  </Step>

  <Step title="Threshold Network Verification">
    Behind the scenes:

    1. The SDK sends the decryption request with the user's permit to the Threshold Network
    2. The Threshold Network verifies the permit's signature and checks on-chain that `permit.issuer` has access to the `CtHash` via the ACL
    3. The Threshold Network performs secure decryption
    4. The plaintext value is returned to the SDK (no signature needed since this is view-only)
  </Step>
</Steps>

***

## Comparison

|                           | `decryptForTx`                                  | `decryptForView` |
| ------------------------- | ----------------------------------------------- | ---------------- |
| **Returns**               | Plaintext + Threshold Network signature         | Plaintext only   |
| **Use case**              | Submit decrypted value on-chain                 | Display in UI    |
| **Requires permit**       | Only if not `allowPublic`                       | Yes              |
| **On-chain verification** | `publishDecryptResult` or `verifyDecryptResult` | Not applicable   |
| **Gas cost**              | Yes (on-chain tx needed)                        | None             |
