Skip to main content
Use decryptForTx to reveal a confidential (encrypted) value onchain. 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 onchain-verifiable signature), use decryptForView instead.

Prerequisites

  1. Create and connect a client.
  2. Know the onchain encrypted handle (ctHash) you want to decrypt.
  3. Determine whether the contract’s ACL policy for this ctHash requires a ACP.
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.

ACP: 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 .withoutACP(). Examples where an ACP 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 .withACP(...).

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 ACP mode)

After decrypting, see Writing Decrypt Result to Contract for how to publish or verify the result onchain.

Builder API

.execute() (required, call last)

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

.withACP(...) (required unless using .withoutACP())

  • .withACP(): uses the active ACP
  • .withACP(acpHash): fetches a stored ACP by hash
  • .withACP(acp): uses the provided ACP object

.withoutACP() (required unless using .withACP(...))

Decrypt via global allowance (no ACP). 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 ACP.

.setChainId(chainId) (optional)

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

.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.
The callback receives:

.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.
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

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