From d81857f249e5cb95acef0a59bc3a953880a4aaca Mon Sep 17 00:00:00 2001 From: D2758695161 Date: Mon, 30 Mar 2026 18:05:43 +0800 Subject: [PATCH] feat(frontend): add env-based API URL and contract ID configuration (closes #125) - Add src/config.js with structured environment presets (dev/staging/prod) - Each preset provides sensible defaults for SOROBAN_RPC_URL, HORIZON_URL, NETWORK_PASSPHRASE, REWARDS_CONTRACT_ID, CAMPAIGN_CONTRACT_ID, and API_URL - Individual VITE_* variables still override any preset value - Add .env.example documenting all available environment variables - Update stellar.js to import resolved config values from config.js - Set VITE_ENV=development as the default preset --- frontend/.env.example | 38 +++++++++++++ frontend/src/config.js | 117 ++++++++++++++++++++++++++++++++++++++++ frontend/src/stellar.js | 21 +++----- 3 files changed, 162 insertions(+), 14 deletions(-) create mode 100644 frontend/.env.example create mode 100644 frontend/src/config.js diff --git a/frontend/.env.example b/frontend/.env.example new file mode 100644 index 0000000..f1c9592 --- /dev/null +++ b/frontend/.env.example @@ -0,0 +1,38 @@ +# Trivela Frontend Environment Variables +# Copy this file to .env.local and fill in your values. +# Environment presets: development | staging | production +# VITE_ENV determines which preset is used as the default. +# Individual VITE_* variables override the preset values. + +# ── Environment preset ──────────────────────────────────────────────────────── +# Set to "development", "staging", or "production". +# Each preset provides default values for all URLs and contract IDs below. +VITE_ENV=development + +# ── Backend API ─────────────────────────────────────────────────────────────── +# The base URL of the Trivela backend API (no trailing slash). +# Development: http://localhost:3001 +# Staging: https://trivela-api-staging.example.com +# Production: https://trivela-api.example.com +VITE_API_URL=http://localhost:3001 + +# ── Stellar network ─────────────────────────────────────────────────────────── +#Soroban RPC endpoint (testnet or mainnet). +VITE_SOROBAN_RPC_URL=https://soroban-testnet.stellar.org + +# Horizon API endpoint for account data. +VITE_HORIZON_URL=https://horizon-testnet.stellar.org + +# Stellar network passphrase. Use "Test SDF Network ; September 2015" for testnet. +# Mainnet passphrase is "Public Global Stellar Network ; September 2015" +VITE_STELLAR_NETWORK_PASSPHRASE="Test SDF Network ; September 2015" + +# ── Contract IDs ────────────────────────────────────────────────────────────── +# Contract IDs are obtained after deploying the contracts with: +# stellar contract deploy --source --network testnet --wasm contracts/rewards/target/wasm32-unknown-unknown/release/rewards.wasm + +# Rewards contract ID (manages user points balances) +VITE_REWARDS_CONTRACT_ID= + +# Campaign contract ID (manages campaign creation and participant registration) +VITE_CAMPAIGN_CONTRACT_ID= diff --git a/frontend/src/config.js b/frontend/src/config.js new file mode 100644 index 0000000..cf4736c --- /dev/null +++ b/frontend/src/config.js @@ -0,0 +1,117 @@ +/** + * Environment-based configuration for Trivela frontend. + * + * Usage: Set VITE_ENV to "development", "staging", or "production". + * Individual VITE_* variables can still be used to override any preset value. + * + * Example .env.development: + * VITE_ENV=development + * VITE_API_URL=http://localhost:3001 + * + * Example .env.staging: + * VITE_ENV=staging + * VITE_API_URL=https://trivela-api-staging.example.com + * + * Example .env.production: + * VITE_ENV=production + * VITE_API_URL=https://trivela-api.example.com + */ + +import { Networks } from "@stellar/stellar-sdk"; + +/** @type {Record} */ +const ENV_PRESETS = { + development: { + stellar: { + networkPassphrase: Networks.TESTNET, + sorobanRpcUrl: "https://soroban-testnet.stellar.org", + horizonUrl: "https://horizon-testnet.stellar.org", + }, + contracts: { + rewardsContractId: "", + campaignContractId: "", + }, + apiUrl: "http://localhost:3001", + }, + staging: { + stellar: { + networkPassphrase: Networks.TESTNET, + sorobanRpcUrl: "https://soroban-testnet.stellar.org", + horizonUrl: "https://horizon-testnet.stellar.org", + }, + contracts: { + rewardsContractId: "", + campaignContractId: "", + }, + apiUrl: "", + }, + production: { + stellar: { + networkPassphrase: Networks.MAINNET, + sorobanRpcUrl: "https://soroban.mainnet.stellar.org", + horizonUrl: "https://horizon.stellar.org", + }, + contracts: { + rewardsContractId: "", + campaignContractId: "", + }, + apiUrl: "", + }, +}; + +/** + * Resolve a single config value. + * Priority: explicit env var > preset value + * + * @template T + * @param {T} presetValue + * @param {string} envKey - VITE_ prefix is added automatically + * @returns {T} + */ +function resolve(presetValue, envKey) { + const envVal = import.meta.env[envKey]; + if (typeof envVal === "string" && envVal.trim() !== "") { + return envVal; + } + return presetValue; +} + +function resolveContractId(presetValue, envKey) { + return resolve(presetValue, envKey); +} + +const presetKey = /** @type {keyof typeof ENV_PRESETS} */ ( + import.meta.env.VITE_ENV || "development" +); +const preset = ENV_PRESETS[presetKey] ?? ENV_PRESETS.development; + +export const STELLAR_NETWORK_PASSPHRASE = resolve( + preset.stellar.networkPassphrase, + "VITE_STELLAR_NETWORK_PASSPHRASE" +); + +export const SOROBAN_RPC_URL = resolve( + preset.stellar.sorobanRpcUrl, + "VITE_SOROBAN_RPC_URL" +); + +export const HORIZON_URL = resolve( + preset.stellar.horizonUrl, + "VITE_HORIZON_URL" +); + +export const REWARDS_CONTRACT_ID = resolveContractId( + preset.contracts.rewardsContractId, + "VITE_REWARDS_CONTRACT_ID" +); + +export const CAMPAIGN_CONTRACT_ID = resolveContractId( + preset.contracts.campaignContractId, + "VITE_CAMPAIGN_CONTRACT_ID" +); + +/** Backend API base URL (no trailing slash). */ +export const API_URL = resolve(preset.apiUrl, "VITE_API_URL"); + +/** Current environment name, one of "development", "staging", "production". */ +export const ENV_NAME = presetKey; diff --git a/frontend/src/stellar.js b/frontend/src/stellar.js index fc5fc95..bf7a057 100644 --- a/frontend/src/stellar.js +++ b/frontend/src/stellar.js @@ -18,20 +18,13 @@ import { /* ---------- environment configuration ---------- */ -export const SOROBAN_RPC_URL = - import.meta.env.VITE_SOROBAN_RPC_URL || "https://soroban-testnet.stellar.org"; - -export const REWARDS_CONTRACT_ID = - import.meta.env.VITE_REWARDS_CONTRACT_ID || ""; - -export const CAMPAIGN_CONTRACT_ID = - import.meta.env.VITE_CAMPAIGN_CONTRACT_ID || ""; - -export const NETWORK_PASSPHRASE = - import.meta.env.VITE_STELLAR_NETWORK_PASSPHRASE || Networks.TESTNET; - -export const HORIZON_URL = - import.meta.env.VITE_HORIZON_URL || "https://horizon-testnet.stellar.org"; +import { + SOROBAN_RPC_URL, + REWARDS_CONTRACT_ID, + CAMPAIGN_CONTRACT_ID, + NETWORK_PASSPHRASE, + HORIZON_URL, +} from "./config"; /* ---------- Freighter helpers ---------- */