Skip to main content

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.

Use decryptForTx to reveal a confidential (encrypted) value on-chain: it returns the plaintext together with a Threshold Network signature, so a contract can verify the reveal when you publish it in a transaction. Common use cases:
  • Unshield a confidential token: reveal the encrypted amount you’re unshielding so the contract can finalize the public transfer.
  • Finalize a private auction / game move: bids or moves are submitted encrypted, and the winner is revealed later in a verifiable way.
If you only need to show plaintext in your UI (and you do not need an on-chain-verifiable signature), use decryptForView instead.

Prerequisites

  1. Create and connect a client.
  2. Know the on-chain encrypted handle (ctHash) you want to decrypt.
  3. Determine whether the contract’s ACL policy for this ctHash requires a permit.
decryptForTx does not take a utype. It always returns the plaintext as a bigint because the result is intended to be passed into a transaction. If you need UI-friendly decoding, use decryptForView.

Permit: when is it needed?

Often, decryptForTx is used to reveal a value that the protocol already considers OK to make public. In those cases, the contract’s ACL policy can allow anyone to decrypt, and you can use .withoutPermit(). Examples where a permit is not needed:
  • Unshielding: the amount being unshielded is no longer meant to stay secret.
  • Auction/game reveal: it doesn’t matter who submits the reveal — only that the result is verified.
If the ACL policy restricts decryption, you must use .withPermit(...).

What decryptForTx returns

.execute() resolves to an object with:
  • ctHash: bigint | string — the ciphertext handle you decrypted
  • decryptedValue: bigint — the plaintext value (always a bigint)
  • signature: 0x${string} — the Threshold Network signature as a hex string

Decrypt (choose permit mode)

const decryptResult = await client
  .decryptForTx(ctHash)
  .withoutPermit()
  .execute();

decryptResult.decryptedValue;
decryptResult.signature;
After decrypting, see Writing Decrypt Result to Contract for how to publish or verify the result on-chain.

Builder API

.execute() — required, call last

Runs the decryption and returns { ctHash, decryptedValue, signature }.

.withPermit(...) — required unless using .withoutPermit()

  • .withPermit() — uses the active permit
  • .withPermit(permitHash) — fetches a stored permit by hash
  • .withPermit(permit) — uses the provided permit object

.withoutPermit() — required unless using .withPermit(...)

Decrypt via global allowance (no permit). Only works if the contract’s ACL policy allows anyone to decrypt that ctHash.

.setAccount(address) — optional

Overrides the account used to resolve the active/stored permit.

.setChainId(chainId) — optional

Overrides the chain used to resolve the Threshold Network URL and permits.

.onPoll(callback) — optional

Register a callback that fires once per poll attempt while decryptForTx waits for the Threshold Network to return the plaintext. Useful for surfacing progress in a UI.
const decryptResult = await client
  .decryptForTx(ctHash)
  .withoutPermit()
  .onPoll(({ operation, requestId, attemptIndex, elapsedMs, intervalMs, timeoutMs }) => {
    console.log(`[${operation}] attempt ${attemptIndex} after ${elapsedMs}ms (next in ${intervalMs}ms, budget ${timeoutMs}ms)`);
  })
  .execute();
The callback receives:
FieldTypeDescription
operation'decrypt' | 'sealoutput'Which Threshold Network flow is polling. For decryptForTx this is always 'decrypt'.
requestIdstringThe Threshold Network request id. May be the empty string during submit-time retries — see .set404RetryTimeout(...) below.
attemptIndexnumberZero-based poll attempt counter.
elapsedMsnumberTime since the first submit attempt.
intervalMsnumberDelay until the next poll.
timeoutMsnumberOverall budget shared by submit-retries and status-polling.

.set404RetryTimeout(timeoutMs) — optional

Configures how long decryptForTx keeps retrying when the Threshold Network’s submit endpoint responds with 404 Not Found before a requestId is available. This typically happens on slower backends where the ciphertext isn’t visible yet at submit time. Defaults to 10_000 ms.
const decryptResult = await client
  .decryptForTx(ctHash)
  .withoutPermit()
  .set404RetryTimeout(20_000) // give a slower backend more time
  .execute();
Pass 0 to disable submit-time retries (404 becomes a hard failure). Submit retries share the same overall timeout budget as status polling, so a larger value here trades poll time for submit-recovery time.

Common pitfalls

  • Permit mode must be selected: you must call exactly one of .withPermit(...) or .withoutPermit() before .execute().
  • Wrong chain/account: permits are scoped to chainId + account. If you get an ACL/permit error, double-check the connected chain and account.