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

# Verifying Attestations

> Verify attested decrypt, reveal, and compute responses in Solidity.

Attested flows (`attestedDecrypt`, `attestedCompute`, `attestedReveal`) allow wallets to convert an encrypted handle into plaintext or a computed result. This page shows how to plug those responses into Solidity, verify the covalidator signatures, and bind attestations to the expected handles.

## DecryptionAttestation Structure

```solidity theme={null}
struct DecryptionAttestation {
    bytes32 handle;
    bytes32 value;
}
```

## Attested Decrypt

**Off-chain (JS SDK):**

<Tabs>
  <Tab title="example.ts">
    ```typescript theme={null}
    import { getContract } from "viem";
    import { gatedAccessAbi } from "./abi";
    import { walletClient } from "./client";

    // 1. Create contract instance
    const contract = getContract({
      address: "0x...", // Replace with your deployed contract address
      abi: gatedAccessAbi,
      client: walletClient,
    });

    // 2. Use attested decrypt and call contract
    const results = await zap.attestedDecrypt(walletClient, [handleHex]);
    const { handle, plaintext, covalidatorSignatures } = results[0];
    const { value } = plaintext;

    await contract.write.gatedAction([
      {
        handle,
        value,
      },
      covalidatorSignatures,
    ]);
    ```
  </Tab>

  <Tab title="client.ts">
    ```typescript theme={null}
    import { createWalletClient, http } from "viem";
    import { baseSepolia } from "viem/chains";
    import { Lightning, supportedChains } from "@inco/js";

    export const walletClient = createWalletClient({
      chain: baseSepolia,
      transport: http(),
    });

    export const zap = await Lightning.latest(
      "testnet",
      supportedChains.baseSepolia
    );
    ```
  </Tab>

  <Tab title="abi.ts">
    ```typescript theme={null}
    export const gatedAccessAbi = [
      {
        inputs: [
          {
            components: [
              {
                internalType: "bytes32",
                name: "handle",
                type: "bytes32",
              },
              {
                internalType: "bytes32",
                name: "value",
                type: "bytes32",
              },
            ],
            internalType: "struct DecryptionAttestation",
            name: "decryption",
            type: "tuple",
          },
          {
            internalType: "bytes[]",
            name: "signatures",
            type: "bytes[]",
          },
        ],
        name: "gatedAction",
        outputs: [],
        stateMutability: "nonpayable",
        type: "function",
      },
    ] as const;
    ```
  </Tab>
</Tabs>

**On-chain (Solidity):**

```solidity theme={null}
import {DecryptionAttestation} from "@inco/lightning/src/lightning-parts/DecryptionAttester.types.sol";
import {inco, ebool} from "@inco/lightning/src/Lib.sol";
import {asBool} from "@inco/lightning/src/shared/TypeUtils.sol";

contract GatedAccess {
    mapping(address => ebool) internal userAllowed;

    function gatedAction(
        DecryptionAttestation memory decryption,
        bytes[] memory signatures
    ) external {
        require(
            inco.incoVerifier().isValidDecryptionAttestation(decryption, signatures),
            "Invalid signature"
        );
        require(ebool.unwrap(userAllowed[msg.sender]) == decryption.handle, "Handle mismatch");
        require(asBool(decryption.value) == true, "Not allowed");

        // proceed
    }
}
```

***

## Attested Reveal

**Off-chain (JS SDK):**

<Tabs>
  <Tab title="example.ts">
    ```typescript theme={null}
    import { getContract } from "viem";
    import { revealAbi } from "./abi";
    import { walletClient } from "./client";

    // 1. Create contract instance
    const contract = getContract({
      address: "0x...", // Replace with your deployed contract address
      abi: revealAbi,
      client: walletClient,
    });

    // 2. Use attested reveal and call contract
    const results = await zap.attestedReveal([handleHex]);
    const { handle, plaintext, covalidatorSignatures } = results[0];
    const { value } = plaintext;

    await contract.write.submitRevealedValue([
      {
        handle,
        value,
      },
      covalidatorSignatures,
    ]);
    ```
  </Tab>

  <Tab title="client.ts">
    ```typescript theme={null}
    import { createWalletClient, http } from "viem";
    import { baseSepolia } from "viem/chains";
    import { Lightning, supportedChains } from "@inco/js";

    export const walletClient = createWalletClient({
      chain: baseSepolia,
      transport: http(),
    });

    export const zap = await Lightning.latest(
      "testnet",
      supportedChains.baseSepolia
    );
    ```
  </Tab>

  <Tab title="abi.ts">
    ```typescript theme={null}
    export const revealAbi = [
      {
        inputs: [
          {
            components: [
              {
                internalType: "bytes32",
                name: "handle",
                type: "bytes32",
              },
              {
                internalType: "bytes32",
                name: "value",
                type: "bytes32",
              },
            ],
            internalType: "struct DecryptionAttestation",
            name: "decryption",
            type: "tuple",
          },
          {
            internalType: "bytes[]",
            name: "signatures",
            type: "bytes[]",
          },
        ],
        name: "submitRevealedValue",
        outputs: [],
        stateMutability: "nonpayable",
        type: "function",
      },
    ] as const;
    ```
  </Tab>
</Tabs>

**On-chain (Solidity):**

```solidity theme={null}
import {DecryptionAttestation} from "@inco/lightning/src/lightning-parts/DecryptionAttester.types.sol";
import {inco, e, ebool, euint256} from "@inco/lightning/src/Lib.sol";
import {asBool} from "@inco/lightning/src/shared/TypeUtils.sol";

contract GatedAccess {
    using e for *;

    euint256 someHandle;
    function submitRevealedValue(
        DecryptionAttestation memory decryption,
        bytes[] memory signatures
    ) external {
        require(
            inco.incoVerifier().isValidDecryptionAttestation(
                decryption,
                signatures
            ),
            "Invalid signature"
        );
        require(
            euint256.unwrap(someHandle) == decryption.handle,
            "Handle mismatch"
        );

        uint256 revealedValue = uint256(decryption.value);
        // use revealedValue
    }
}
```

***

## Attested Compute

Attested compute first produces a **computed handle** (for example
`handleB = handleA.ge(700)`), and then returns a decryption attestation
**for that result handle**. On-chain you verify that:

* the attestation is valid,
* the `decryption.handle` matches the expected computed handle (e.g. `handleB`),
* and the decrypted value of `handleB` satisfies your predicate.

**Off-chain (JS SDK):**

<Tabs>
  <Tab title="example.ts">
    ```typescript theme={null}
    import { getContract } from "viem";
    import { creditCheckAbi } from "./abi";
    import { walletClient } from "./client";

    // 1. Create contract instance
    const contract = getContract({
      address: "0x...", // Replace with your deployed contract address
      abi: creditCheckAbi,
      client: walletClient,
    });

    // 2. Read encrypted credit score handle
    const creditScoreHandle = await contract.read.userCreditScore([
      walletClient.account.address,
    ]);

    // 3. Off-chain check: is credit score >= 700?
    const { handle, plaintext, covalidatorSignatures } = await zap.attestedCompute(
      walletClient,
      creditScoreHandle,
      AttestedComputeSupportedOps.Ge,
      700n
    );

    const { value } = plaintext; // always boolean
    await contract.write.submitCreditCheck([
      {
        handle,
        value,
      },
      covalidatorSignatures,
    ]);
    ```
  </Tab>

  <Tab title="client.ts">
    ```typescript theme={null}
    import { createWalletClient, http } from "viem";
    import { baseSepolia } from "viem/chains";
    import { Lightning, supportedChains } from "@inco/js";

    export const walletClient = createWalletClient({
      chain: baseSepolia,
      transport: http(),
    });

    export const zap = await Lightning.latest(
      "testnet",
      supportedChains.baseSepolia
    );
    ```
  </Tab>

  <Tab title="abi.ts">
    ```typescript theme={null}
    export const creditCheckAbi = [
      {
        inputs: [
          {
            components: [
              {
                internalType: "bytes32",
                name: "handle",
                type: "bytes32",
              },
              {
                internalType: "bytes32",
                name: "value",
                type: "bytes32",
              },
            ],
            internalType: "struct DecryptionAttestation",
            name: "decryption",
            type: "tuple",
          },
          {
            internalType: "bytes[]",
            name: "signatures",
            type: "bytes[]",
          },
        ],
        name: "submitCreditCheck",
        outputs: [],
        stateMutability: "nonpayable",
        type: "function",
      },
    ] as const;
    ```
  </Tab>
</Tabs>

**On-chain (Solidity):**

```solidity theme={null}
import {DecryptionAttestation} from "@inco/lightning/src/lightning-parts/DecryptionAttester.types.sol";
import {inco, e, ebool, euint256} from "@inco/lightning/src/Lib.sol";
import {asBool} from "@inco/lightning/src/shared/TypeUtils.sol";

contract GatedAccess {
    using e for *;

    // Encrypted credit score handle stored on-chain for each user
    mapping(address => euint256) internal userCreditScore;

    function submitCreditCheck(
        DecryptionAttestation memory decryption,
        bytes[] memory signatures
    ) external {
        // 1. Verify covalidator signatures over the attested result
        require(
            inco.incoVerifier().isValidDecryptionAttestation(
                decryption,
                signatures
            ),
            "Invalid signature"
        );

        // 2. Recompute the expected "creditScore >= 700" handle on-chain
        euint256 creditScore = userCreditScore[msg.sender];
        require(
            ebool.unwrap(creditScore.ge(700)) == decryption.handle,
            "Computed handle mismatch"
        );

        // 3. Check that the decrypted boolean is true
        require(asBool(decryption.value) == true, "Credit check failed");

        // proceed with approval
    }
}
```
