> For the complete documentation index, see [llms.txt](https://zka-protocol.gitbook.io/zka-protocol-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zka-protocol.gitbook.io/zka-protocol-docs/developer/decrypting-actions.md).

# Decrypting Actions

After the ZKAP Validator verifies a private frame on-chain, it emits an `AnonymousAction` event containing the encrypted payload.\
Applications must decrypt this payload off-chain to recover the original instruction and execute the requested logic.

This file explains everything developers need to know about decrypting anonymous actions.

***

### 1. Where decryption happens

Decryption **always happens off-chain**, typically in:

* backend services
* DEX engines
* agent orchestrators
* bridge routers
* indexer-like consumers
* secure enclaves
* specialized off-chain workers

Nothing in the encrypted payload should ever be decrypted inside a smart contract.

***

### 2. Anatomy of the AnonymousAction event

The validator emits:

AnonymousAction(commitment\_root, encrypted\_payload)

Where:

* `commitment_root` is used to validate commitments
* `encrypted_payload` is the ciphertext generated by the sender

Your application needs only the `encrypted_payload` to decrypt the action.

***

### 3. Requirements for decryption

To decrypt the payload, you must have:

1. The application’s symmetric decryption key
2. The ciphertext received from the event
3. The same encryption scheme used by the sender (AES-GCM or ChaCha20)
4. The correct IV/nonce (included in the ciphertext format)

The encryption key must be kept secure — it is the only piece of information that allows the payload to be read.

***

### 4. Using the SDK to decrypt payloads

The ZKAP SDK provides a simple helper function:

const payload = await decryptPayload(encrypted\_payload, appKey);

This function:

* validates ciphertext structure
* extracts IV/nonce
* performs authenticated decryption
* returns the original JSON payload

If authentication fails, the payload will not decrypt.

***

### 5. Example: decrypting inside a backend listener

import { decryptPayload } from "@zkap/sdk";

contract.on("AnonymousAction", async (root, encrypted) => {\
try {\
const payload = await decryptPayload(encrypted, appKey);\
executeAction(payload);\
} catch (e) {\
console.error("Decryption failed:", e);\
}\
});

This pattern is the most common architecture for applications integrating ZKAP.

***

### 6. Example payload after decryption

After decrypting, the application sees the original instruction:

{\
"action": "swap",\
"tokenIn": "USDC",\
"tokenOut": "ETH",\
"amount": "500",\
"minOut": "0.3",\
"expiry": 12345678\
}

Only the application sees the content — nobody else can.

***

### 7. Encryption schemes supported

ZKAP supports:

* AES-GCM
* ChaCha20-Poly1305

Both provide:

* confidentiality
* authenticity (decryption fails on tampering)
* integrity guarantees

Developers can choose the backend they prefer.

***

### 8. Handling invalid or corrupted ciphertext

The decryption function may throw errors when:

* IV/nonce is missing
* ciphertext was altered
* wrong decryption key is used
* payload is malformed
* encryption backend mismatch

The SDK provides descriptive error messages.

***

### 9. Security model for decryption keys

Best practices:

* Never embed keys in frontend code
* Store keys in backend vaults (HashiCorp Vault, AWS KMS, GCP KMS)
* Rotate keys periodically
* Restrict who/what can decrypt payloads
* Never expose keys in logs
* Isolate decryption workers if possible

ZKAP relies entirely on off-chain decryption privacy,\
so key management is critical.

***

### 10. When to decrypt payloads

An application should decrypt payloads:

* immediately after receiving the event
* OR through a batch listener service
* depending on business logic

For high-throughput applications (e.g., DEX/RFQ), parallel decryption workers may be used.

For agent runtimes, logic may require sequential processing.

***

### 11. Usage patterns across application types

#### Private DEX

Decrypt → read swap → execute routing logic.

#### Wallet backend

Decrypt → execute user operations or intents.

#### Agent system

Decrypt → trigger workflows, task execution, or multi-step logic.

#### RFQ engine

Decrypt → generate private quote → respond via ZKAP.

#### Bridge / Router

Decrypt → read cross-chain intent → dispatch to target chain.
