diff --git a/content/relayer/1.4.x/guides/zama-fhevm-counter-guide.mdx b/content/relayer/1.4.x/guides/zama-fhevm-counter-guide.mdx
index cf3939e9..5ea3b5c4 100644
--- a/content/relayer/1.4.x/guides/zama-fhevm-counter-guide.mdx
+++ b/content/relayer/1.4.x/guides/zama-fhevm-counter-guide.mdx
@@ -4,20 +4,29 @@ title: Zama FHEVM Counter Guide
## Overview
-This guide walks through an end-to-end integration between OpenZeppelin Relayer and a Zama FHEVM contract, using the counter example shipped with the [OpenZeppelin Relayer SDK](https://github.com/OpenZeppelin/openzeppelin-relayer-sdk). The counter contract is deployed from [Zama's fhevm-hardhat-template](https://github.com/zama-ai/fhevm-hardhat-template) and demonstrates the two relayer responsibilities in an FHEVM flow:
+This guide walks through an end-to-end integration between the OpenZeppelin Relayer and a Zama FHEVM contract, using the counter example shipped with the [OpenZeppelin Relayer SDK](https://github.com/OpenZeppelin/openzeppelin-relayer-sdk). The counter contract is deployed from [Zama's fhevm-hardhat-template](https://github.com/zama-ai/fhevm-hardhat-template) and demonstrates the two OpenZeppelin Relayer responsibilities in an FHEVM flow:
- **Transaction submission**: sending an encrypted `increment()` call on-chain.
- **EIP-712 signing**: signing the typed-data payload that authorizes user decryption of the counter's encrypted state.
+
+
+**Terminology.** In this guide:
+
+- **OpenZeppelin Relayer** (or "OZ Relayer") — this service. It holds an EVM signer, submits on-chain transactions, and signs EIP-712 payloads.
+- **Zama Relayer** — the Zama-operated service that the [`@zama-fhe/relayer-sdk`](https://www.npmjs.com/package/@zama-fhe/relayer-sdk) talks to under the hood. It serves FHE public keys and routes decryption requests to the Zama KMS / coprocessor. Applications interact with it only indirectly through the Zama Relayer SDK. It holds no OpenZeppelin key material and does not sign EIP-712.
+
+
+
By the end of this guide you will have:
- Configured a Zama FHE instance in your application.
- Read and decrypted an encrypted counter value from the contract.
-- Submitted an encrypted increment through the relayer and waited for confirmation.
+- Submitted an encrypted increment through the OpenZeppelin Relayer and waited for confirmation.
- Re-read and decrypted the updated value.
-The FHE encryption/decryption primitives run in your application using the Zama SDK. The relayer never sees cleartext values or your decryption keypair — it only sends transactions and signs EIP-712 payloads.
+The FHE encryption/decryption primitives run in your application using the Zama Relayer SDK. The OpenZeppelin Relayer never sees cleartext values or your decryption keypair — it only sends transactions and signs EIP-712 payloads.
## Prerequisites
@@ -42,29 +51,32 @@ The rest of this guide explains the moving parts, references the example files,
Four components participate in the flow:
-- **Your script**: orchestrates the flow and prints progress.
-- **OpenZeppelin Relayer**: signs typed data and submits transactions.
-- **Zama Relayer SDK instance**: encrypts inputs and manages decryption flows.
-- **FHEVM contract**: stores encrypted state on-chain.
+- **Your script** — orchestrates the flow and prints progress.
+- **OpenZeppelin Relayer** — signs typed data and submits transactions. The only component holding an EVM signer.
+- **Zama Relayer SDK (client)** + **Zama Relayer (service)** — the SDK encrypts inputs, generates keypairs for user decryption, and builds EIP-712 payloads; the Zama Relayer service serves FHE public keys and routes decryption requests to the Zama KMS / coprocessor. The application only interacts with it indirectly through the SDK.
+- **FHEVM contract** — stores encrypted state on-chain.
-The key boundary is that the relayer does not do any encryption. The Zama SDK handles encryption and decryption primitives; the relayer provides transaction execution and signature authorization.
+The key boundary is that the OpenZeppelin Relayer does not do any encryption or decryption. The Zama Relayer SDK (and, behind it, the Zama Relayer service) handles all FHE primitives; the OpenZeppelin Relayer only provides EVM transaction execution and EIP-712 signing.
```
-┌─────────────┐ ┌───────────────────────┐ ┌──────────────┐
-│ Your app │──────▶│ OpenZeppelin Relayer │──────▶│ FHEVM network│
-│ (Zama SDK) │ │ sendTransaction + │ │ Sepolia / │
-│ │◀──────│ signTypedData │ │ Mainnet │
-└─────────────┘ └───────────────────────┘ └──────────────┘
+┌─────────────┐ ┌─────────────────────────┐ ┌──────────────┐
+│ Your app │──────▶│ OpenZeppelin Relayer │──────▶│ FHEVM network│
+│ (Zama SDK) │ │ sendTransaction + │ │ Sepolia / │
+│ │◀──────│ signTypedData │ │ Mainnet │
+└─────────────┘ └─────────────────────────┘ └──────────────┘
│
▼
- Zama Gateway
- (public decrypt /
- user decrypt)
+┌─────────────────────────────┐
+│ Zama Relayer │
+│ FHE public keys + │
+│ decryption request routing │
+│ (accessed via Zama SDK) │
+└─────────────────────────────┘
```
-## Relayer Configuration
+## OpenZeppelin Relayer Configuration
-Zama FHEVM contracts live on standard EVM networks, so the relayer is configured as a regular `evm` relayer.
+Zama FHEVM contracts live on standard EVM networks, so the OpenZeppelin Relayer is configured as a regular `evm` relayer.
```json
{
@@ -96,9 +108,9 @@ Zama FHEVM contracts live on standard EVM networks, so the relayer is configured
**Important notes:**
-- The relayer signer is used both for submitting the encrypted transaction and for signing the EIP-712 payload consumed by the Zama Gateway during user decryption. The same key backs both operations.
+- The OpenZeppelin Relayer's signer is used both for submitting the encrypted transaction and for signing the EIP-712 payload that the Zama Relayer SDK requires for user decryption. The same key backs both operations.
- For production, prefer a hosted signer (AWS KMS, Google Cloud KMS, Turnkey, CDP) over `local`.
-- The relayer must be funded on the target network so it can pay gas for FHEVM contract calls.
+- The OpenZeppelin Relayer must be funded on the target network so it can pay gas for FHEVM contract calls.
## Installation
@@ -130,7 +142,7 @@ RELAYER_BASE_PATH=http://localhost:8080
# ZAMA_PRIVATE_KEY=
```
-- `RELAYER_BASE_PATH` defaults to `http://localhost:8080` if not set.
+- `RELAYER_BASE_PATH` defaults to `http://localhost:8080` if not set. This points at your OpenZeppelin Relayer.
- `RPC_URL` defaults to the public Sepolia RPC if not set.
- If `ZAMA_PUBLIC_KEY` and `ZAMA_PRIVATE_KEY` are not set, the script generates a fresh decryption keypair on each run. Reusing the same keypair is useful for consistent user-decryption behavior across runs.
@@ -145,8 +157,8 @@ npx ts-node examples/relayers/zama/counter.ts
The script should:
1. Read the encrypted counter handle from the contract.
-2. Attempt decryption (public first, then user decryption with a relayer-signed EIP-712 payload).
-3. Submit an encrypted `increment()` through the relayer and poll until the transaction is mined or confirmed.
+2. Attempt decryption (public first, then user decryption with an OpenZeppelin Relayer signed EIP-712 payload).
+3. Submit an encrypted `increment()` through the OpenZeppelin Relayer and poll until the transaction is mined or confirmed.
4. Re-read and decrypt the updated counter value.
## Generating a Reusable Decryption Keypair
@@ -160,14 +172,14 @@ npx ts-node examples/relayers/zama/generate-keypair.ts
Copy the printed `ZAMA_PUBLIC_KEY` and `ZAMA_PRIVATE_KEY` values into your `.env` file.
-The decryption keypair is an application-side secret. Do not pass the private key to the relayer; it is only used by the Zama SDK to decrypt results returned by the Gateway.
+The decryption keypair is an application side secret. Do not pass the private key to the OpenZeppelin Relayer; it is only used by the Zama Relayer SDK to decrypt results returned by the Zama Relayer.
## Walkthrough
-The following snippets show the relayer-specific integration points from `counter.ts`. Full code is in the [SDK repository](https://github.com/OpenZeppelin/openzeppelin-relayer-sdk/tree/main/examples/relayers/zama).
+The following snippets show the OpenZeppelin Relayer's specific integration points from `counter.ts`. Full code is in the [SDK repository](https://github.com/OpenZeppelin/openzeppelin-relayer-sdk/tree/main/examples/relayers/zama).
-### 1. Initialize the relayer client and Zama SDK
+### 1. Initialize the OpenZeppelin Relayer client and Zama SDK
```typescript
import { Configuration, RelayersApi } from '@openzeppelin/relayer-sdk';
@@ -190,9 +202,9 @@ const provider = new JsonRpcProvider(process.env.RPC_URL!);
const instance = await createInstance(zamaConfig);
```
-### 2. Fetch the relayer's on-chain address
+### 2. Fetch the OpenZeppelin Relayer's on-chain address
-The relayer's EVM address is needed both when building encrypted inputs and when authorizing user decryption.
+The OpenZeppelin Relayer's EVM address is needed both when building encrypted inputs and when authorizing user decryption.
```typescript
const relayerInfo = await relayersApi.getRelayer(process.env.RELAYER_ID!);
@@ -201,7 +213,7 @@ const relayerAddress = getAddress(relayerInfo.data.data!.address!);
### 3. Read and decrypt the encrypted counter
-The contract exposes a `getCount()` view that returns the encrypted handle. Decoding the handle is a plain EVM call — no relayer involvement.
+The contract exposes a `getCount()` view that returns the encrypted handle. Decoding the handle is a plain EVM call — no OpenZeppelin Relayer involvement.
```typescript
import { Interface } from 'ethers';
@@ -218,9 +230,9 @@ async function getCount(contractAddress: string): Promise {
The script first attempts public decryption. If the handle is not publicly decryptable, it falls back to user decryption (covered in [Decryption Model](#decryption-model) below).
-### 4. Submit an encrypted `increment()` via the relayer
+### 4. Submit an encrypted `increment()` via the OpenZeppelin Relayer
-Encryption happens locally with the Zama SDK. The encrypted handle plus input proof are encoded into a normal EVM transaction and handed to `sendTransaction`.
+Encryption happens locally with the Zama Relayer SDK. The encrypted handle plus input proof are encoded into a normal EVM transaction and handed to the OpenZeppelin Relayer's `sendTransaction`.
```typescript
import { Speed } from '@openzeppelin/relayer-sdk';
@@ -244,7 +256,7 @@ const transactionId = txResponse.data.data!.id!;
### 5. Poll for confirmation
-Poll `getTransactionById` until the transaction reaches `mined` or `confirmed`:
+Poll `getTransactionById` on the OpenZeppelin Relayer until the transaction reaches `mined` or `confirmed`:
```typescript
import type { EvmTransactionResponse } from '@openzeppelin/relayer-sdk';
@@ -256,7 +268,7 @@ async function waitForConfirmation(transactionId: string): Promise
-Mainnet requires API key authentication with the Zama Gateway. See the [Zama mainnet API key guide](https://docs.zama.org/protocol/relayer-sdk-guides/fhevm-relayer/mainnet-api-key) for instructions on obtaining one.
+Mainnet requires API key authentication with the Zama Relayer. See the [Zama mainnet API key guide](https://docs.zama.org/protocol/relayer-sdk-guides/fhevm-relayer/mainnet-api-key) for instructions on obtaining one.
## Current Limitations
@@ -366,15 +378,15 @@ Mainnet requires API key authentication with the Zama Gateway. See the [Zama mai
- The example is hardcoded for Sepolia via `SepoliaConfig` plus an explicit Sepolia RPC URL.
- It assumes a counter contract shape compatible with the included ABI.
- Logging and error handling are intentionally simple — this is a demo script, not production code.
-- It does not cover relayer creation or contract deployment.
+- It does not cover OpenZeppelin Relayer creation or contract deployment.
## Troubleshooting
- **`Missing required environment variable`**: one of the required values in `.env` is unset.
-- **`did not return an address`**: the configured relayer id is valid for the API, but the response did not include an EVM address. Check that the relayer is fully provisioned and the signer is reachable.
+- **`did not return an address`**: the configured `RELAYER_ID` is valid for the API, but the response did not include an EVM address. Check that the OpenZeppelin Relayer is fully provisioned and the signer is reachable.
- **`Public decryption failed`**: this can be expected depending on the contract and permissions. The script will then try user decryption.
-- **`User decryption failed`**: check that the relayer can sign typed data correctly and that the contract address and decryption keypair are the ones you expect. Confirm the EIP-712 `startTimeStamp`/`durationDays` window is valid.
-- **Transaction polling timeout**: the transaction may still be pending, the relayer may be unhealthy, or the target chain may be slow. Inspect `getTransactionById` directly and check relayer logs.
+- **`User decryption failed`**: check that the OpenZeppelin Relayer can sign typed data correctly and that the contract address and decryption keypair are the ones you expect. Confirm the EIP-712 `startTimeStamp` / `durationDays` window is valid.
+- **Transaction polling timeout**: the transaction may still be pending, the OpenZeppelin Relayer may be unhealthy, or the target chain may be slow. Inspect `getTransactionById` directly and check OpenZeppelin Relayer logs.
## Additional Resources
diff --git a/content/relayer/1.4.x/zama-fhevm.mdx b/content/relayer/1.4.x/zama-fhevm.mdx
index 5c9c3d42..f68fbbbf 100644
--- a/content/relayer/1.4.x/zama-fhevm.mdx
+++ b/content/relayer/1.4.x/zama-fhevm.mdx
@@ -4,15 +4,26 @@ title: Zama FHEVM Integration
## Overview
-OpenZeppelin Relayer supports interacting with [Zama FHEVM](https://docs.zama.org/protocol) contracts — EVM smart contracts that operate on Fully Homomorphic Encryption (FHE) ciphertexts. The relayer provides two capabilities that FHEVM applications need from a backend:
+The OpenZeppelin Relayer supports interacting with [Zama FHEVM](https://docs.zama.org/protocol) contracts — EVM smart contracts that operate on Fully Homomorphic Encryption (FHE) ciphertexts. The OpenZeppelin Relayer provides two capabilities that FHEVM applications need from a backend:
- **Transaction submission** for encrypted contract calls (e.g. submitting an `increment()` with an encrypted input).
-- **EIP-712 typed-data signing** for authorizing user decryption requests against the Zama Gateway.
+- **EIP-712 typed-data signing** to authorize user decryption requests served by the Zama Relayer.
-Because FHEVM contracts live on standard EVM networks, a Zama FHEVM relayer is configured as a regular `evm` relayer. Encryption and decryption are handled by the [Zama Relayer SDK](https://docs.zama.org/protocol/relayer-sdk-guides) running in your application; the OpenZeppelin Relayer only deals with on-chain transactions and typed-data signatures.
+Because FHEVM contracts live on standard EVM networks, your OpenZeppelin Relayer is configured exactly as a regular `evm` relayer — there is no FHEVM-specific relayer or network type in OpenZeppelin Relayer. All FHE-specific work (encryption, decryption, key handling) is done by the [Zama Relayer SDK](https://docs.zama.org/protocol/relayer-sdk-guides) running in your application, which in turn talks to the Zama Relayer. The OpenZeppelin Relayer only deals with on-chain transactions and EIP-712 typed-data signatures.
+
+
+
+**Terminology.** In this page:
+
+- **OpenZeppelin Relayer** (or "OZ Relayer") refers to this service. It holds an EVM signer, submits on-chain transactions, and signs EIP-712 payloads.
+- **Zama Relayer** refers to the Zama-operated service that the [`@zama-fhe/relayer-sdk`](https://www.npmjs.com/package/@zama-fhe/relayer-sdk) talks to under the hood. It serves FHE public keys and routes decryption requests to the Zama KMS / coprocessor. Applications interact with it only indirectly through the Zama Relayer SDK. It holds no OpenZeppelin key material and does not sign EIP-712.
+
+The two are different systems and do different things. In this flow, only the OpenZeppelin Relayer holds any signer key material.
+
+
-The FHE encryption/decryption primitives run in your application using the Zama SDK. The OpenZeppelin Relayer is not aware of FHE cleartexts and never handles the decryption keypair.
+The FHE encryption/decryption primitives run in your application using the Zama Relayer SDK. The OpenZeppelin Relayer is not aware of FHE cleartexts and never handles the decryption keypair.
## Features
@@ -27,13 +38,13 @@ The FHE encryption/decryption primitives run in your application using the Zama
Zama FHEVM is available on EVM networks where the FHE coprocessor is deployed. At the time of writing, this includes:
- Ethereum Sepolia (testnet)
-- Ethereum Mainnet (requires a Zama Gateway API key)
+- Ethereum Mainnet (requires a Zama Relayer API key)
-Because the relayer treats these as regular EVM networks, any network configuration that works for EVM will work here. See the [Network Configuration](/relayer/network_configuration) guide for the full list of options.
+Because the OpenZeppelin Relayer treats these as regular EVM networks, any network configuration that works for EVM will work here. See the [Network Configuration](/relayer/network_configuration) guide for the full list of options.
## Supported Signers
-All EVM signers are supported:
+All EVM signers are supported by the OpenZeppelin Relayer:
- `local` (local keystore files)
- `vault` (HashiCorp Vault secret storage)
@@ -46,12 +57,12 @@ All EVM signers are supported:
For signer configuration details, see the [Signers](/relayer/configuration/signers) guide.
-For production, prefer hosted signers (AWS KMS, Google Cloud KMS, Turnkey, CDP). The relayer's signer is used both to sign the on-chain encrypted transactions and the EIP-712 payloads consumed by the Zama Gateway, so key availability and security apply to both flows.
+For production, prefer hosted signers (AWS KMS, Google Cloud KMS, Turnkey, CDP). The OpenZeppelin Relayer's signer is used both to sign the on-chain encrypted transactions and the EIP-712 payloads consumed by the Zama Relayer, so key availability and security apply to both flows.
## Quickstart
-Example relayer configuration for a Sepolia FHEVM relayer:
+Example OpenZeppelin Relayer configuration for a Zama FHEVM application running on Sepolia (note that it is just a standard `evm` relayer — nothing FHEVM-specific in the config):
```json
{
@@ -64,35 +75,33 @@ Example relayer configuration for a Sepolia FHEVM relayer:
}
```
-Once the relayer is running, you will typically:
+Once the OpenZeppelin Relayer is running, you will typically:
1. Create a Zama FHE instance in your application using the Zama Relayer SDK.
2. Read encrypted state from your FHEVM contract via an RPC call.
-3. Decrypt the state publicly, or fall back to user decryption authorized by an EIP-712 signature from the relayer.
-4. Encrypt any inputs locally with the Zama SDK.
+3. Decrypt the state publicly, or fall back to user decryption authorized by an EIP-712 signature from the OpenZeppelin Relayer.
+4. Encrypt any inputs locally with the Zama Relayer SDK.
5. Submit the encrypted transaction through the OpenZeppelin Relayer.
For a full working walkthrough, see the [Zama FHEVM Counter Guide](/relayer/guides/zama-fhevm-counter-guide).
-## How The Relayer Fits Into An FHEVM Flow
+## How The OpenZeppelin Relayer Fits Into An FHEVM Flow
-A typical FHEVM call with OpenZeppelin Relayer has four moving parts:
+A typical FHEVM call has four moving parts:
-- **Your application**: orchestrates encryption, decryption, and calls to the relayer.
-- **Zama Relayer SDK**: encrypts inputs, generates decryption keypairs, and builds EIP-712 payloads for user decryption.
-- **OpenZeppelin Relayer**:
- - signs and submits the encrypted transaction on-chain,
- - signs EIP-712 payloads for user decryption via `signTypedData`.
-- **FHEVM contract**: stores encrypted state on the EVM network.
+- **Your application** — orchestrates encryption/decryption and calls both the Zama Relayer (via SDK) and the OpenZeppelin Relayer.
+- **Zama Relayer SDK (client)** + **Zama Relayer (service)** — the SDK encrypts inputs, generates keypairs for user decryption, and builds EIP-712 payloads; the Zama Relayer service serves FHE public keys and routes decryption requests. No OpenZeppelin key material is involved.
+- **OpenZeppelin Relayer** — the only component in this diagram that holds an EVM signer. It signs and submits the encrypted transaction on-chain, and signs the EIP-712 user-decryption payload via `signTypedData`.
+- **FHEVM contract** — stores encrypted state on the EVM network.
-The relayer never encrypts or decrypts data. It only performs two things that require the relayer's key material: sending the encrypted transaction and signing the EIP-712 message that authorizes the Zama Gateway to return a user decryption.
+The OpenZeppelin Relayer never encrypts or decrypts FHE data and never sees plaintext. It performs exactly two operations that use its signer: (a) signing and submitting the encrypted on-chain transaction, and (b) signing the EIP-712 user-decryption payload produced by the Zama Relayer SDK. The Zama Relayer is a separate system; it does not hold or use the OpenZeppelin Relayer's key material.
## Decryption Model
Zama FHEVM contracts support two decryption paths:
-- **Public decryption**: used when an encrypted handle is flagged as publicly decryptable. The Zama SDK can decrypt it directly, with no authorization from the relayer.
-- **User decryption**: used when decryption requires authorization. The Zama SDK builds an EIP-712 payload, and the relayer signs it with `signTypedData`. The resulting signature is then passed to `userDecrypt` on the SDK, which retrieves the cleartext from the Zama Gateway.
+- **Public decryption** — used when an encrypted handle is flagged as publicly decryptable. The Zama Relayer SDK can decrypt it directly via the Zama Relayer service; the OpenZeppelin Relayer is not involved.
+- **User decryption** — used when decryption requires authorization. The Zama Relayer SDK builds an EIP-712 payload, and the **OpenZeppelin Relayer** signs it with `signTypedData`. The resulting signature is then passed to `userDecrypt` on the SDK, which is authorized by the Zama Relayer to return the cleartext.
Applications typically try public decryption first and fall back to user decryption.
@@ -100,21 +109,21 @@ Applications typically try public decryption first and fall back to user decrypt
Running on Ethereum mainnet requires:
-- A Zama FHEVM Gateway API key (see the [Zama mainnet API key guide](https://docs.zama.org/protocol/relayer-sdk-guides/fhevm-relayer/mainnet-api-key)).
-- The Zama SDK configured with `MainnetConfig` and the API key.
-- The relayer pointed at an Ethereum mainnet RPC.
+- A Zama Relayer API key for mainnet (see the [Zama mainnet API key guide](https://docs.zama.org/protocol/relayer-sdk-guides/fhevm-relayer/mainnet-api-key)).
+- The Zama Relayer SDK configured with `MainnetConfig` and the API key.
+- The OpenZeppelin Relayer pointed at an Ethereum mainnet RPC.
-The FHEVM flow itself does not change between testnet and mainnet; only the Zama SDK configuration and network selection differ.
+The FHEVM flow itself does not change between testnet and mainnet; only the Zama Relayer SDK configuration and network selection differ.
## API Reference
-The relayer endpoints most relevant to FHEVM flows are:
+The OpenZeppelin Relayer endpoints most relevant to FHEVM flows are:
| Method | Purpose |
| --- | --- |
| [Send Transaction](/relayer/api/sendTransaction) | Submit an encrypted FHEVM contract call on-chain |
| [Sign Typed Data](/relayer/api/signTypedData) | Sign the EIP-712 payload used for user decryption |
-| [Get Relayer](/relayer/api/getRelayer) | Retrieve the relayer address (needed for Zama user decryption) |
+| [Get Relayer](/relayer/api/getRelayer) | Retrieve the OpenZeppelin Relayer's EVM address (needed by the Zama SDK for input proofs and decryption requests) |
| [Get Transaction by ID](/relayer/api/getTransactionById) | Poll for transaction status after submission |
See the [API Reference](./api) for complete method documentation.
@@ -129,10 +138,10 @@ The example contract is deployed from [Zama's fhevm-hardhat-template](https://gi
## Security
-- Do not expose the relayer directly to the public internet.
+- Do not expose the OpenZeppelin Relayer directly to the public internet.
- Deploy behind a secure backend (reverse proxy, firewall).
-- Use hosted signers in production. The relayer signer is used both for on-chain submission and for EIP-712 signing consumed by the Zama Gateway, so key availability and audit trails matter for both.
-- Never hand a decryption keypair's private key to the relayer. The decryption keypair is an application-side secret.
+- Use hosted signers in production. The OpenZeppelin Relayer's signer is used both for on-chain submission and for EIP-712 signing consumed by the Zama Relayer, so key availability and audit trails matter for both.
+- Never hand a Zama decryption keypair's private key to the OpenZeppelin Relayer. The decryption keypair is an application-side secret — it is used only by the Zama Relayer SDK.
## Additional Resources
diff --git a/content/relayer/guides/zama-fhevm-counter-guide.mdx b/content/relayer/guides/zama-fhevm-counter-guide.mdx
index cf3939e9..c69fbdd0 100644
--- a/content/relayer/guides/zama-fhevm-counter-guide.mdx
+++ b/content/relayer/guides/zama-fhevm-counter-guide.mdx
@@ -4,20 +4,29 @@ title: Zama FHEVM Counter Guide
## Overview
-This guide walks through an end-to-end integration between OpenZeppelin Relayer and a Zama FHEVM contract, using the counter example shipped with the [OpenZeppelin Relayer SDK](https://github.com/OpenZeppelin/openzeppelin-relayer-sdk). The counter contract is deployed from [Zama's fhevm-hardhat-template](https://github.com/zama-ai/fhevm-hardhat-template) and demonstrates the two relayer responsibilities in an FHEVM flow:
+This guide walks through an end-to-end integration between the OpenZeppelin Relayer and a Zama FHEVM contract, using the counter example shipped with the [OpenZeppelin Relayer SDK](https://github.com/OpenZeppelin/openzeppelin-relayer-sdk). The counter contract is deployed from [Zama's fhevm-hardhat-template](https://github.com/zama-ai/fhevm-hardhat-template) and demonstrates the two OpenZeppelin Relayer responsibilities in an FHEVM flow:
- **Transaction submission**: sending an encrypted `increment()` call on-chain.
- **EIP-712 signing**: signing the typed-data payload that authorizes user decryption of the counter's encrypted state.
+
+
+**Terminology.** In this guide:
+
+- **OpenZeppelin Relayer** (or "OZ Relayer") — this service. It holds an EVM signer, submits on-chain transactions, and signs EIP-712 payloads.
+- **Zama Relayer** — the Zama-operated service that the [`@zama-fhe/relayer-sdk`](https://www.npmjs.com/package/@zama-fhe/relayer-sdk) talks to under the hood. It serves FHE public keys and routes decryption requests to the Zama KMS / coprocessor. Applications interact with it only indirectly through the Zama Relayer SDK. It holds no OpenZeppelin key material and does not sign EIP-712.
+
+
+
By the end of this guide you will have:
- Configured a Zama FHE instance in your application.
- Read and decrypted an encrypted counter value from the contract.
-- Submitted an encrypted increment through the relayer and waited for confirmation.
+- Submitted an encrypted increment through the OpenZeppelin Relayer and waited for confirmation.
- Re-read and decrypted the updated value.
-The FHE encryption/decryption primitives run in your application using the Zama SDK. The relayer never sees cleartext values or your decryption keypair — it only sends transactions and signs EIP-712 payloads.
+The FHE encryption/decryption primitives run in your application using the Zama Relayer SDK. The OpenZeppelin Relayer never sees cleartext values or your decryption keypair — it only sends transactions and signs EIP-712 payloads.
## Prerequisites
@@ -42,29 +51,32 @@ The rest of this guide explains the moving parts, references the example files,
Four components participate in the flow:
-- **Your script**: orchestrates the flow and prints progress.
-- **OpenZeppelin Relayer**: signs typed data and submits transactions.
-- **Zama Relayer SDK instance**: encrypts inputs and manages decryption flows.
-- **FHEVM contract**: stores encrypted state on-chain.
+- **Your script** — orchestrates the flow and prints progress.
+- **OpenZeppelin Relayer** — signs typed data and submits transactions. The only component holding an EVM signer.
+- **Zama Relayer SDK (client)** + **Zama Relayer (service)** — the SDK encrypts inputs, generates keypairs for user decryption, and builds EIP-712 payloads; the Zama Relayer service serves FHE public keys and routes decryption requests to the Zama KMS / coprocessor. The application only interacts with it indirectly through the SDK.
+- **FHEVM contract** — stores encrypted state on-chain.
-The key boundary is that the relayer does not do any encryption. The Zama SDK handles encryption and decryption primitives; the relayer provides transaction execution and signature authorization.
+The key boundary is that the OpenZeppelin Relayer does not do any encryption or decryption. The Zama Relayer SDK (and, behind it, the Zama Relayer service) handles all FHE primitives; the OpenZeppelin Relayer only provides EVM transaction execution and EIP-712 signing.
```
-┌─────────────┐ ┌───────────────────────┐ ┌──────────────┐
-│ Your app │──────▶│ OpenZeppelin Relayer │──────▶│ FHEVM network│
-│ (Zama SDK) │ │ sendTransaction + │ │ Sepolia / │
-│ │◀──────│ signTypedData │ │ Mainnet │
-└─────────────┘ └───────────────────────┘ └──────────────┘
+┌─────────────┐ ┌─────────────────────────┐ ┌──────────────┐
+│ Your app │──────▶│ OpenZeppelin Relayer │──────▶│ FHEVM network│
+│ (Zama SDK) │ │ sendTransaction + │ │ Sepolia / │
+│ │◀──────│ signTypedData │ │ Mainnet │
+└─────────────┘ └─────────────────────────┘ └──────────────┘
│
▼
- Zama Gateway
- (public decrypt /
- user decrypt)
+┌─────────────────────────────┐
+│ Zama Relayer │
+│ FHE public keys + │
+│ decryption request routing │
+│ (accessed via Zama SDK) │
+└─────────────────────────────┘
```
-## Relayer Configuration
+## OpenZeppelin Relayer Configuration
-Zama FHEVM contracts live on standard EVM networks, so the relayer is configured as a regular `evm` relayer.
+Zama FHEVM contracts live on standard EVM networks, so the OpenZeppelin Relayer is configured as a regular `evm` relayer.
```json
{
@@ -96,9 +108,9 @@ Zama FHEVM contracts live on standard EVM networks, so the relayer is configured
**Important notes:**
-- The relayer signer is used both for submitting the encrypted transaction and for signing the EIP-712 payload consumed by the Zama Gateway during user decryption. The same key backs both operations.
+- The OpenZeppelin Relayer's signer is used both for submitting the encrypted transaction and for signing the EIP-712 payload that the Zama Relayer SDK requires for user decryption. The same key backs both operations.
- For production, prefer a hosted signer (AWS KMS, Google Cloud KMS, Turnkey, CDP) over `local`.
-- The relayer must be funded on the target network so it can pay gas for FHEVM contract calls.
+- The OpenZeppelin Relayer must be funded on the target network so it can pay gas for FHEVM contract calls.
## Installation
@@ -130,7 +142,7 @@ RELAYER_BASE_PATH=http://localhost:8080
# ZAMA_PRIVATE_KEY=
```
-- `RELAYER_BASE_PATH` defaults to `http://localhost:8080` if not set.
+- `RELAYER_BASE_PATH` defaults to `http://localhost:8080` if not set. This points at your OpenZeppelin Relayer.
- `RPC_URL` defaults to the public Sepolia RPC if not set.
- If `ZAMA_PUBLIC_KEY` and `ZAMA_PRIVATE_KEY` are not set, the script generates a fresh decryption keypair on each run. Reusing the same keypair is useful for consistent user-decryption behavior across runs.
@@ -145,8 +157,8 @@ npx ts-node examples/relayers/zama/counter.ts
The script should:
1. Read the encrypted counter handle from the contract.
-2. Attempt decryption (public first, then user decryption with a relayer-signed EIP-712 payload).
-3. Submit an encrypted `increment()` through the relayer and poll until the transaction is mined or confirmed.
+2. Attempt decryption (public first, then user decryption with an OpenZeppelin Relayer's signed EIP-712 payload).
+3. Submit an encrypted `increment()` through the OpenZeppelin Relayer and poll until the transaction is mined or confirmed.
4. Re-read and decrypt the updated counter value.
## Generating a Reusable Decryption Keypair
@@ -160,14 +172,14 @@ npx ts-node examples/relayers/zama/generate-keypair.ts
Copy the printed `ZAMA_PUBLIC_KEY` and `ZAMA_PRIVATE_KEY` values into your `.env` file.
-The decryption keypair is an application-side secret. Do not pass the private key to the relayer; it is only used by the Zama SDK to decrypt results returned by the Gateway.
+The decryption keypair is an application side secret. Do not pass the private key to the OpenZeppelin Relayer; it is only used by the Zama Relayer SDK to decrypt results returned by the Zama Relayer.
## Walkthrough
-The following snippets show the relayer-specific integration points from `counter.ts`. Full code is in the [SDK repository](https://github.com/OpenZeppelin/openzeppelin-relayer-sdk/tree/main/examples/relayers/zama).
+The following snippets show the OpenZeppelin Relayer's specific integration points from `counter.ts`. Full code is in the [SDK repository](https://github.com/OpenZeppelin/openzeppelin-relayer-sdk/tree/main/examples/relayers/zama).
-### 1. Initialize the relayer client and Zama SDK
+### 1. Initialize the OpenZeppelin Relayer client and Zama SDK
```typescript
import { Configuration, RelayersApi } from '@openzeppelin/relayer-sdk';
@@ -190,9 +202,9 @@ const provider = new JsonRpcProvider(process.env.RPC_URL!);
const instance = await createInstance(zamaConfig);
```
-### 2. Fetch the relayer's on-chain address
+### 2. Fetch the OpenZeppelin Relayer's on-chain address
-The relayer's EVM address is needed both when building encrypted inputs and when authorizing user decryption.
+The OpenZeppelin Relayer's EVM address is needed both when building encrypted inputs and when authorizing user decryption.
```typescript
const relayerInfo = await relayersApi.getRelayer(process.env.RELAYER_ID!);
@@ -201,7 +213,7 @@ const relayerAddress = getAddress(relayerInfo.data.data!.address!);
### 3. Read and decrypt the encrypted counter
-The contract exposes a `getCount()` view that returns the encrypted handle. Decoding the handle is a plain EVM call — no relayer involvement.
+The contract exposes a `getCount()` view that returns the encrypted handle. Decoding the handle is a plain EVM call — no OpenZeppelin Relayer involvement.
```typescript
import { Interface } from 'ethers';
@@ -218,9 +230,9 @@ async function getCount(contractAddress: string): Promise {
The script first attempts public decryption. If the handle is not publicly decryptable, it falls back to user decryption (covered in [Decryption Model](#decryption-model) below).
-### 4. Submit an encrypted `increment()` via the relayer
+### 4. Submit an encrypted `increment()` via the OpenZeppelin Relayer
-Encryption happens locally with the Zama SDK. The encrypted handle plus input proof are encoded into a normal EVM transaction and handed to `sendTransaction`.
+Encryption happens locally with the Zama Relayer SDK. The encrypted handle plus input proof are encoded into a normal EVM transaction and handed to the OpenZeppelin Relayer's `sendTransaction`.
```typescript
import { Speed } from '@openzeppelin/relayer-sdk';
@@ -244,7 +256,7 @@ const transactionId = txResponse.data.data!.id!;
### 5. Poll for confirmation
-Poll `getTransactionById` until the transaction reaches `mined` or `confirmed`:
+Poll `getTransactionById` on the OpenZeppelin Relayer until the transaction reaches `mined` or `confirmed`:
```typescript
import type { EvmTransactionResponse } from '@openzeppelin/relayer-sdk';
@@ -256,7 +268,7 @@ async function waitForConfirmation(transactionId: string): Promise
-Mainnet requires API key authentication with the Zama Gateway. See the [Zama mainnet API key guide](https://docs.zama.org/protocol/relayer-sdk-guides/fhevm-relayer/mainnet-api-key) for instructions on obtaining one.
+Mainnet requires API key authentication with the Zama Relayer. See the [Zama mainnet API key guide](https://docs.zama.org/protocol/relayer-sdk-guides/fhevm-relayer/mainnet-api-key) for instructions on obtaining one.
## Current Limitations
@@ -366,15 +378,15 @@ Mainnet requires API key authentication with the Zama Gateway. See the [Zama mai
- The example is hardcoded for Sepolia via `SepoliaConfig` plus an explicit Sepolia RPC URL.
- It assumes a counter contract shape compatible with the included ABI.
- Logging and error handling are intentionally simple — this is a demo script, not production code.
-- It does not cover relayer creation or contract deployment.
+- It does not cover OpenZeppelin Relayer creation or contract deployment.
## Troubleshooting
- **`Missing required environment variable`**: one of the required values in `.env` is unset.
-- **`did not return an address`**: the configured relayer id is valid for the API, but the response did not include an EVM address. Check that the relayer is fully provisioned and the signer is reachable.
+- **`did not return an address`**: the configured `RELAYER_ID` is valid for the API, but the response did not include an EVM address. Check that the OpenZeppelin Relayer is fully provisioned and the signer is reachable.
- **`Public decryption failed`**: this can be expected depending on the contract and permissions. The script will then try user decryption.
-- **`User decryption failed`**: check that the relayer can sign typed data correctly and that the contract address and decryption keypair are the ones you expect. Confirm the EIP-712 `startTimeStamp`/`durationDays` window is valid.
-- **Transaction polling timeout**: the transaction may still be pending, the relayer may be unhealthy, or the target chain may be slow. Inspect `getTransactionById` directly and check relayer logs.
+- **`User decryption failed`**: check that the OpenZeppelin Relayer can sign typed data correctly and that the contract address and decryption keypair are the ones you expect. Confirm the EIP-712 `startTimeStamp` / `durationDays` window is valid.
+- **Transaction polling timeout**: the transaction may still be pending, the OpenZeppelin Relayer may be unhealthy, or the target chain may be slow. Inspect `getTransactionById` directly and check OpenZeppelin Relayer logs.
## Additional Resources
diff --git a/content/relayer/zama-fhevm.mdx b/content/relayer/zama-fhevm.mdx
index 5c9c3d42..f68fbbbf 100644
--- a/content/relayer/zama-fhevm.mdx
+++ b/content/relayer/zama-fhevm.mdx
@@ -4,15 +4,26 @@ title: Zama FHEVM Integration
## Overview
-OpenZeppelin Relayer supports interacting with [Zama FHEVM](https://docs.zama.org/protocol) contracts — EVM smart contracts that operate on Fully Homomorphic Encryption (FHE) ciphertexts. The relayer provides two capabilities that FHEVM applications need from a backend:
+The OpenZeppelin Relayer supports interacting with [Zama FHEVM](https://docs.zama.org/protocol) contracts — EVM smart contracts that operate on Fully Homomorphic Encryption (FHE) ciphertexts. The OpenZeppelin Relayer provides two capabilities that FHEVM applications need from a backend:
- **Transaction submission** for encrypted contract calls (e.g. submitting an `increment()` with an encrypted input).
-- **EIP-712 typed-data signing** for authorizing user decryption requests against the Zama Gateway.
+- **EIP-712 typed-data signing** to authorize user decryption requests served by the Zama Relayer.
-Because FHEVM contracts live on standard EVM networks, a Zama FHEVM relayer is configured as a regular `evm` relayer. Encryption and decryption are handled by the [Zama Relayer SDK](https://docs.zama.org/protocol/relayer-sdk-guides) running in your application; the OpenZeppelin Relayer only deals with on-chain transactions and typed-data signatures.
+Because FHEVM contracts live on standard EVM networks, your OpenZeppelin Relayer is configured exactly as a regular `evm` relayer — there is no FHEVM-specific relayer or network type in OpenZeppelin Relayer. All FHE-specific work (encryption, decryption, key handling) is done by the [Zama Relayer SDK](https://docs.zama.org/protocol/relayer-sdk-guides) running in your application, which in turn talks to the Zama Relayer. The OpenZeppelin Relayer only deals with on-chain transactions and EIP-712 typed-data signatures.
+
+
+
+**Terminology.** In this page:
+
+- **OpenZeppelin Relayer** (or "OZ Relayer") refers to this service. It holds an EVM signer, submits on-chain transactions, and signs EIP-712 payloads.
+- **Zama Relayer** refers to the Zama-operated service that the [`@zama-fhe/relayer-sdk`](https://www.npmjs.com/package/@zama-fhe/relayer-sdk) talks to under the hood. It serves FHE public keys and routes decryption requests to the Zama KMS / coprocessor. Applications interact with it only indirectly through the Zama Relayer SDK. It holds no OpenZeppelin key material and does not sign EIP-712.
+
+The two are different systems and do different things. In this flow, only the OpenZeppelin Relayer holds any signer key material.
+
+
-The FHE encryption/decryption primitives run in your application using the Zama SDK. The OpenZeppelin Relayer is not aware of FHE cleartexts and never handles the decryption keypair.
+The FHE encryption/decryption primitives run in your application using the Zama Relayer SDK. The OpenZeppelin Relayer is not aware of FHE cleartexts and never handles the decryption keypair.
## Features
@@ -27,13 +38,13 @@ The FHE encryption/decryption primitives run in your application using the Zama
Zama FHEVM is available on EVM networks where the FHE coprocessor is deployed. At the time of writing, this includes:
- Ethereum Sepolia (testnet)
-- Ethereum Mainnet (requires a Zama Gateway API key)
+- Ethereum Mainnet (requires a Zama Relayer API key)
-Because the relayer treats these as regular EVM networks, any network configuration that works for EVM will work here. See the [Network Configuration](/relayer/network_configuration) guide for the full list of options.
+Because the OpenZeppelin Relayer treats these as regular EVM networks, any network configuration that works for EVM will work here. See the [Network Configuration](/relayer/network_configuration) guide for the full list of options.
## Supported Signers
-All EVM signers are supported:
+All EVM signers are supported by the OpenZeppelin Relayer:
- `local` (local keystore files)
- `vault` (HashiCorp Vault secret storage)
@@ -46,12 +57,12 @@ All EVM signers are supported:
For signer configuration details, see the [Signers](/relayer/configuration/signers) guide.
-For production, prefer hosted signers (AWS KMS, Google Cloud KMS, Turnkey, CDP). The relayer's signer is used both to sign the on-chain encrypted transactions and the EIP-712 payloads consumed by the Zama Gateway, so key availability and security apply to both flows.
+For production, prefer hosted signers (AWS KMS, Google Cloud KMS, Turnkey, CDP). The OpenZeppelin Relayer's signer is used both to sign the on-chain encrypted transactions and the EIP-712 payloads consumed by the Zama Relayer, so key availability and security apply to both flows.
## Quickstart
-Example relayer configuration for a Sepolia FHEVM relayer:
+Example OpenZeppelin Relayer configuration for a Zama FHEVM application running on Sepolia (note that it is just a standard `evm` relayer — nothing FHEVM-specific in the config):
```json
{
@@ -64,35 +75,33 @@ Example relayer configuration for a Sepolia FHEVM relayer:
}
```
-Once the relayer is running, you will typically:
+Once the OpenZeppelin Relayer is running, you will typically:
1. Create a Zama FHE instance in your application using the Zama Relayer SDK.
2. Read encrypted state from your FHEVM contract via an RPC call.
-3. Decrypt the state publicly, or fall back to user decryption authorized by an EIP-712 signature from the relayer.
-4. Encrypt any inputs locally with the Zama SDK.
+3. Decrypt the state publicly, or fall back to user decryption authorized by an EIP-712 signature from the OpenZeppelin Relayer.
+4. Encrypt any inputs locally with the Zama Relayer SDK.
5. Submit the encrypted transaction through the OpenZeppelin Relayer.
For a full working walkthrough, see the [Zama FHEVM Counter Guide](/relayer/guides/zama-fhevm-counter-guide).
-## How The Relayer Fits Into An FHEVM Flow
+## How The OpenZeppelin Relayer Fits Into An FHEVM Flow
-A typical FHEVM call with OpenZeppelin Relayer has four moving parts:
+A typical FHEVM call has four moving parts:
-- **Your application**: orchestrates encryption, decryption, and calls to the relayer.
-- **Zama Relayer SDK**: encrypts inputs, generates decryption keypairs, and builds EIP-712 payloads for user decryption.
-- **OpenZeppelin Relayer**:
- - signs and submits the encrypted transaction on-chain,
- - signs EIP-712 payloads for user decryption via `signTypedData`.
-- **FHEVM contract**: stores encrypted state on the EVM network.
+- **Your application** — orchestrates encryption/decryption and calls both the Zama Relayer (via SDK) and the OpenZeppelin Relayer.
+- **Zama Relayer SDK (client)** + **Zama Relayer (service)** — the SDK encrypts inputs, generates keypairs for user decryption, and builds EIP-712 payloads; the Zama Relayer service serves FHE public keys and routes decryption requests. No OpenZeppelin key material is involved.
+- **OpenZeppelin Relayer** — the only component in this diagram that holds an EVM signer. It signs and submits the encrypted transaction on-chain, and signs the EIP-712 user-decryption payload via `signTypedData`.
+- **FHEVM contract** — stores encrypted state on the EVM network.
-The relayer never encrypts or decrypts data. It only performs two things that require the relayer's key material: sending the encrypted transaction and signing the EIP-712 message that authorizes the Zama Gateway to return a user decryption.
+The OpenZeppelin Relayer never encrypts or decrypts FHE data and never sees plaintext. It performs exactly two operations that use its signer: (a) signing and submitting the encrypted on-chain transaction, and (b) signing the EIP-712 user-decryption payload produced by the Zama Relayer SDK. The Zama Relayer is a separate system; it does not hold or use the OpenZeppelin Relayer's key material.
## Decryption Model
Zama FHEVM contracts support two decryption paths:
-- **Public decryption**: used when an encrypted handle is flagged as publicly decryptable. The Zama SDK can decrypt it directly, with no authorization from the relayer.
-- **User decryption**: used when decryption requires authorization. The Zama SDK builds an EIP-712 payload, and the relayer signs it with `signTypedData`. The resulting signature is then passed to `userDecrypt` on the SDK, which retrieves the cleartext from the Zama Gateway.
+- **Public decryption** — used when an encrypted handle is flagged as publicly decryptable. The Zama Relayer SDK can decrypt it directly via the Zama Relayer service; the OpenZeppelin Relayer is not involved.
+- **User decryption** — used when decryption requires authorization. The Zama Relayer SDK builds an EIP-712 payload, and the **OpenZeppelin Relayer** signs it with `signTypedData`. The resulting signature is then passed to `userDecrypt` on the SDK, which is authorized by the Zama Relayer to return the cleartext.
Applications typically try public decryption first and fall back to user decryption.
@@ -100,21 +109,21 @@ Applications typically try public decryption first and fall back to user decrypt
Running on Ethereum mainnet requires:
-- A Zama FHEVM Gateway API key (see the [Zama mainnet API key guide](https://docs.zama.org/protocol/relayer-sdk-guides/fhevm-relayer/mainnet-api-key)).
-- The Zama SDK configured with `MainnetConfig` and the API key.
-- The relayer pointed at an Ethereum mainnet RPC.
+- A Zama Relayer API key for mainnet (see the [Zama mainnet API key guide](https://docs.zama.org/protocol/relayer-sdk-guides/fhevm-relayer/mainnet-api-key)).
+- The Zama Relayer SDK configured with `MainnetConfig` and the API key.
+- The OpenZeppelin Relayer pointed at an Ethereum mainnet RPC.
-The FHEVM flow itself does not change between testnet and mainnet; only the Zama SDK configuration and network selection differ.
+The FHEVM flow itself does not change between testnet and mainnet; only the Zama Relayer SDK configuration and network selection differ.
## API Reference
-The relayer endpoints most relevant to FHEVM flows are:
+The OpenZeppelin Relayer endpoints most relevant to FHEVM flows are:
| Method | Purpose |
| --- | --- |
| [Send Transaction](/relayer/api/sendTransaction) | Submit an encrypted FHEVM contract call on-chain |
| [Sign Typed Data](/relayer/api/signTypedData) | Sign the EIP-712 payload used for user decryption |
-| [Get Relayer](/relayer/api/getRelayer) | Retrieve the relayer address (needed for Zama user decryption) |
+| [Get Relayer](/relayer/api/getRelayer) | Retrieve the OpenZeppelin Relayer's EVM address (needed by the Zama SDK for input proofs and decryption requests) |
| [Get Transaction by ID](/relayer/api/getTransactionById) | Poll for transaction status after submission |
See the [API Reference](./api) for complete method documentation.
@@ -129,10 +138,10 @@ The example contract is deployed from [Zama's fhevm-hardhat-template](https://gi
## Security
-- Do not expose the relayer directly to the public internet.
+- Do not expose the OpenZeppelin Relayer directly to the public internet.
- Deploy behind a secure backend (reverse proxy, firewall).
-- Use hosted signers in production. The relayer signer is used both for on-chain submission and for EIP-712 signing consumed by the Zama Gateway, so key availability and audit trails matter for both.
-- Never hand a decryption keypair's private key to the relayer. The decryption keypair is an application-side secret.
+- Use hosted signers in production. The OpenZeppelin Relayer's signer is used both for on-chain submission and for EIP-712 signing consumed by the Zama Relayer, so key availability and audit trails matter for both.
+- Never hand a Zama decryption keypair's private key to the OpenZeppelin Relayer. The decryption keypair is an application-side secret — it is used only by the Zama Relayer SDK.
## Additional Resources