Skip to content

chore: shutter env variables #2017

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions contracts/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ LOGTAIL_TOKEN_RELAYER_BOT=41h8q5Z4gnz5yDx215eqcQ4r
LOGTAIL_TOKEN_DISPUTOR_BOT=mSryyvYubviaMqKDWfBKAGsi
HEARTBEAT_URL_KEEPER_BOT=https://uptime.betterstack.com/api/v1/heartbeat/jc23S8ZZzpf8KbzwxL1hoBp9
HEARTBEAT_URL_RELAYER_BOT=https://uptime.betterstack.com/api/v1/heartbeat/eT6Trk6CddJV6fFBbqZNzyqC
SHUTTER_API="https://shutter-api.chiado.staging.shutter.network/api"
DISPUTES_TO_SKIP=

# Optionally for debugging
Expand Down
6 changes: 4 additions & 2 deletions contracts/scripts/shutter.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import env from "./utils/env";
import { encryptData, decrypt as shutterDecrypt } from "@shutter-network/shutter-sdk";
import { Hex, stringToHex, hexToString } from "viem";
import crypto from "crypto";
import "isomorphic-fetch";

const SHUTTER_API = env.optionalNoDefault("SHUTTER_API");
Copy link
Contributor

@coderabbitai coderabbitai bot May 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add validation for the required environment variable.

The SHUTTER_API environment variable is declared as optional with no default value, which means it could be undefined. This will cause runtime errors when constructing API URLs in the fetch functions.

Add proper validation to ensure the environment variable is set:

-const SHUTTER_API = env.optionalNoDefault("SHUTTER_API");
+const SHUTTER_API = env.required("SHUTTER_API");

Or if you want to keep it optional, add validation:

-const SHUTTER_API = env.optionalNoDefault("SHUTTER_API");
+const SHUTTER_API = env.optionalNoDefault("SHUTTER_API");
+if (!SHUTTER_API) {
+  throw new Error("SHUTTER_API environment variable is required but not set");
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const SHUTTER_API = env.optionalNoDefault("SHUTTER_API");
-const SHUTTER_API = env.optionalNoDefault("SHUTTER_API");
+const SHUTTER_API = env.required("SHUTTER_API");
Suggested change
const SHUTTER_API = env.optionalNoDefault("SHUTTER_API");
const SHUTTER_API = env.optionalNoDefault("SHUTTER_API");
+if (!SHUTTER_API) {
+ throw new Error("SHUTTER_API environment variable is required but not set");
+}
🤖 Prompt for AI Agents
In contracts/scripts/shutter.ts at line 7, the SHUTTER_API environment variable
is declared as optional without a default, which can lead to undefined values
and runtime errors. Modify the code to validate that SHUTTER_API is defined
before using it by either making it required with env.required or adding a
runtime check that throws an error if SHUTTER_API is undefined, ensuring safe
usage in API URL construction.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually handle it like this in the feat/shutter-dispute-kit branch. I will change it when merging.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jaybuidl Thanks for the confirmation! That sounds like a good approach to handle the environment variable validation in the feature branch and apply it during the merge. I appreciate you keeping track of these improvements across branches.

// Time in seconds to wait before the message can be decrypted
export const DECRYPTION_DELAY = 5;

Expand Down Expand Up @@ -38,7 +40,7 @@ async function fetchShutterData(decryptionTimestamp: number): Promise<ShutterApi
const identityPrefix = generateRandomBytes32();
console.log(`Generated identity prefix: ${identityPrefix}`);

const response = await fetch("https://shutter-api.shutter.network/api/register_identity", {
const response = await fetch(`${SHUTTER_API}/register_identity`, {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify the environment variable is properly set.

Since SHUTTER_API could be undefined, this URL construction could result in "undefined/register_identity", causing API calls to fail.

Ensure the environment variable is properly configured across all deployment environments:


🏁 Script executed:

#!/bin/bash
# Description: Check if SHUTTER_API is defined in environment configuration files

# Look for SHUTTER_API definitions in env files
fd -e env -e example | xargs grep -l "SHUTTER_API" || echo "No SHUTTER_API found in env files"

# Check if there are any default values or fallbacks defined
rg "SHUTTER_API.*=" -A 2 -B 2

Length of output: 1202


🏁 Script executed:

#!/bin/bash
set -e
# Search for definition of optionalNoDefault to understand its behavior
rg "optionalNoDefault" -n -C 3

Length of output: 3790


Use a required environment variable for SHUTTER_API

The env.optionalNoDefault("SHUTTER_API") call can return undefined, leading to requests against "undefined/register_identity". Instead, make SHUTTER_API mandatory so the script fails fast if it’s unset.

• In contracts/scripts/shutter.ts (at the top, around line 7)

- const SHUTTER_API = env.optionalNoDefault("SHUTTER_API");
+ const SHUTTER_API = env.require("SHUTTER_API");

• This change will throw a clear error at startup if SHUTTER_API is not defined, preventing invalid fetch URLs.
• Ensure your deployment/CI environments define SHUTTER_API.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const response = await fetch(`${SHUTTER_API}/register_identity`, {
// contracts/scripts/shutter.ts (around the top of the file)
-import { env } from "...";
-const SHUTTER_API = env.optionalNoDefault("SHUTTER_API");
+const SHUTTER_API = env.require("SHUTTER_API");
🤖 Prompt for AI Agents
In contracts/scripts/shutter.ts around line 7, change the environment variable
retrieval for SHUTTER_API from an optional call to a required one so that the
script throws an error immediately if SHUTTER_API is not set. This prevents
constructing fetch URLs with "undefined" and ensures the script fails fast.
Update the code to use a method that enforces SHUTTER_API presence and verify
that all deployment and CI environments define this variable.

method: "POST",
headers: {
accept: "application/json",
Expand Down Expand Up @@ -88,7 +90,7 @@ async function fetchShutterData(decryptionTimestamp: number): Promise<ShutterApi
async function fetchDecryptionKey(identity: string): Promise<ShutterDecryptionKeyData> {
console.log(`Fetching decryption key for identity: ${identity}`);

const response = await fetch(`https://shutter-api.shutter.network/api/get_decryption_key?identity=${identity}`, {
const response = await fetch(`${SHUTTER_API}/get_decryption_key?identity=${identity}`, {
method: "GET",
headers: {
accept: "application/json",
Expand Down
1 change: 1 addition & 0 deletions web/.env.devnet-neo.public
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export REACT_APP_ATLAS_URI=http://localhost:3000
export WALLETCONNECT_PROJECT_ID=
export ALCHEMY_API_KEY=
export NODE_OPTIONS='--max-old-space-size=7680'
export REACT_APP_SHUTTER_API="https://shutter-api.chiado.staging.shutter.network/api"
1 change: 1 addition & 0 deletions web/.env.devnet-university.public
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export REACT_APP_ATLAS_URI=http://localhost:3000
export WALLETCONNECT_PROJECT_ID=
export ALCHEMY_API_KEY=
export NODE_OPTIONS='--max-old-space-size=7680'
export REACT_APP_SHUTTER_API="https://shutter-api.chiado.staging.shutter.network/api"

# devtools
export REACT_APP_GRAPH_API_KEY=
1 change: 1 addition & 0 deletions web/.env.devnet.public
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export REACT_APP_ATLAS_URI=http://localhost:3000
export REACT_APP_DEVTOOLS_URL=https://dev--kleros-v2-testnet-devtools.netlify.app
export NODE_OPTIONS='--max-old-space-size=7680'
export REACT_APP_SPAM_EVIDENCES_IDS="0-2,3-1"
export REACT_APP_SHUTTER_API="https://shutter-api.chiado.staging.shutter.network/api"
# devtools
export REACT_APP_GRAPH_API_KEY=
1 change: 1 addition & 0 deletions web/.env.local.public
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export REACT_APP_ATLAS_URI=http://localhost:3000
export WALLETCONNECT_PROJECT_ID=
export ALCHEMY_API_KEY=
export NODE_OPTIONS='--max-old-space-size=7680'
export REACT_APP_SHUTTER_API="https://shutter-api.chiado.staging.shutter.network/api"

# devtools
export REACT_APP_GRAPH_API_KEY=
3 changes: 2 additions & 1 deletion web/.env.mainnet-neo.public
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export REACT_APP_ARBITRATOR_TYPE=neo
export REACT_APP_ATLAS_URI=http://localhost:3000
export WALLETCONNECT_PROJECT_ID=
export ALCHEMY_API_KEY=
export NODE_OPTIONS='--max-old-space-size=7680'
export NODE_OPTIONS='--max-old-space-size=7680'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify if staging URL is appropriate for mainnet environment.

The mainnet (production) environment is configured to use the staging Shutter API URL. This may cause reliability issues if the staging environment has different uptime guarantees or gets reset.

Please confirm if this is intentional or if a production Shutter API URL should be used instead:


🌐 Web query:

What is the production URL for the Shutter API? Is there a difference between staging and production endpoints?

💡 Result:

Based on the search results, the Shutter API has different endpoints for staging and production environments.

Shutter API Endpoints

The production and staging URLs for Shutter API are environment-specific. According to the information available, the Shutter API can be accessed through the following endpoint for the Chiado environment:

https://shutter-api.chiado

This appears to be one of the available endpoints where you can query the API[2]. However, the complete production URL structure isn't fully specified in the provided information.

Staging vs. Production Environments

There is indeed a difference between staging and production environments for APIs, including the Shutter API. These differences typically include:

  1. Separate Endpoints: Organizations often provide distinct URLs for staging and production environments[6][10].

  2. Different Rate Limits: Staging environments may have lower rate limits compared to production environments[6][10].

  3. Method Restrictions: Some API methods or endpoints might be restricted in staging environments but available in production, or vice versa. This allows testing new features safely before making them available to all users[6].

  4. Traffic Separation: In proper implementations, staging and production traffic is separated to allow for better analytics and monitoring[6][10].

One common approach is to use different application plans for each environment with distinct rate limits and method availability. This helps developers test their applications in a controlled environment before moving to production[6][10].

While the specific differences between Shutter API's staging and production endpoints aren't explicitly detailed in the search results, it follows standard API management practices of providing separate environments for development/testing and production use.

Citations:


Use Production Shutter API Endpoint in Mainnet Environment

The web/.env.mainnet-neo.public file is currently pointing at the staging API (https://shutter-api.chiado.staging.shutter.network/api), but the production Chiado endpoint should be different.

• File: web/.env.mainnet-neo.public
Line 12:

- export REACT_APP_SHUTTER_API="https://shutter-api.chiado.staging.shutter.network/api"
+ export REACT_APP_SHUTTER_API="https://shutter-api.chiado/api"

Please confirm the exact production URL (e.g. include or omit /api) and update this variable to avoid relying on the staging service in production.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export REACT_APP_SHUTTER_API="https://shutter-api.chiado.staging.shutter.network/api"
export REACT_APP_SHUTTER_API="https://shutter-api.chiado/api"
🤖 Prompt for AI Agents
In web/.env.mainnet-neo.public at line 12, the REACT_APP_SHUTTER_API is set to
the staging URL, which is inappropriate for the mainnet production environment.
Replace the staging URL with the correct production Shutter API endpoint for
Chiado, ensuring you confirm whether the path should include "/api" or not.
Update the environment variable to point to the verified production URL to avoid
using the staging service in production.

export REACT_APP_SHUTTER_API="https://shutter-api.chiado.staging.shutter.network/api"
1 change: 1 addition & 0 deletions web/.env.testnet.public
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ export REACT_APP_DEVTOOLS_URL=https://devtools.v2-testnet.kleros.builders
export WALLETCONNECT_PROJECT_ID=
export ALCHEMY_API_KEY=
export NODE_OPTIONS='--max-old-space-size=7680'
export REACT_APP_SHUTTER_API="https://shutter-api.chiado.staging.shutter.network/api"
# devtools
export REACT_APP_GRAPH_API_KEY=
4 changes: 2 additions & 2 deletions web/src/utils/shutter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ async function fetchShutterData(decryptionTimestamp: number): Promise<ShutterApi
// Generate a random identity prefix
const identityPrefix = generateRandomBytes32();

const response = await fetch("https://shutter-api.shutter.network/api/register_identity", {
const response = await fetch(`${import.meta.env.REACT_APP_SHUTTER_API}/register_identity`, {
method: "POST",
headers: {
accept: "application/json",
Expand Down Expand Up @@ -77,7 +77,7 @@ async function fetchShutterData(decryptionTimestamp: number): Promise<ShutterApi
* @returns Promise with the decryption key data
*/
async function fetchDecryptionKey(identity: string): Promise<ShutterDecryptionKeyData> {
const response = await fetch(`https://shutter-api.shutter.network/api/get_decryption_key?identity=${identity}`, {
const response = await fetch(`${import.meta.env.REACT_APP_SHUTTER_API}/get_decryption_key?identity=${identity}`, {
method: "GET",
headers: {
accept: "application/json",
Expand Down
Loading