Skip to main content
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.

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.