Skip to content

Validate Soroban env vars at build time - #215

Closed
Bryandero98 wants to merge 3 commits into
SmartDropLabs:mainfrom
Bryandero98:fix/env-validation
Closed

Validate Soroban env vars at build time#215
Bryandero98 wants to merge 3 commits into
SmartDropLabs:mainfrom
Bryandero98:fix/env-validation

Conversation

@Bryandero98

Copy link
Copy Markdown

Fixes #199.

Adds validateEnv(), called from next.config.ts before build/dev/start, so the app fails fast with a clear, aggregated error instead of silently falling back to demo-mode data or a runtime 500 when config is missing or malformed.

Validates the three variables named in the issue:

  • NEXT_PUBLIC_FACTORY_CONTRACT_ID — required, must be a valid Soroban contract id (StrKey.isValidContract, the same check already used in feeBumpGuard.ts).
  • NEXT_PUBLIC_SOROBAN_RPC_URL — if set, must be a valid URL (it already has a network-preset fallback, so it isn't required).
  • STELLAR_FEE_SPONSOR_SECRET — required and must be a valid Stellar secret key only in server mode, since the /api/sign-fee-bump route it backs doesn't exist under static export.

Repro from the issue, verified locally: with the vars unset, npm run build used to succeed silently in demo mode; with this change it now aborts immediately with:

Invalid environment configuration:
  - NEXT_PUBLIC_FACTORY_CONTRACT_ID is not set.
  - STELLAR_FEE_SPONSOR_SECRET is not set (required in server mode for /api/sign-fee-bump).

With valid values set, next build passes validation and compiles successfully.

Tests

7 new Vitest cases in src/config/validateEnv.test.ts, all green: happy path, missing/invalid value for each variable individually, and the static-export vs. server-mode branch for STELLAR_FEE_SPONSOR_SECRET.

No new dependencies — reuses StrKey from @stellar/stellar-sdk, already a project dependency.

Add validateEnv(), called from next.config.ts before build/dev/start,
which fails fast with an aggregated error instead of letting missing
or malformed config silently fall through to demo-mode data or a
runtime 500:

- NEXT_PUBLIC_FACTORY_CONTRACT_ID: required, must be a valid Soroban
  contract id (StrKey.isValidContract, matching the check already used
  in feeBumpGuard.ts)
- NEXT_PUBLIC_SOROBAN_RPC_URL: if set, must be a valid URL (has a
  network-preset fallback otherwise)
- STELLAR_FEE_SPONSOR_SECRET: required and must be a valid Stellar
  secret key in server mode only, since /api/sign-fee-bump does not
  exist under static export

Covered by 7 Vitest cases in validateEnv.test.ts (missing/invalid
value per var, static-export vs server-mode branching, happy path).
No new dependencies.
@netlify

netlify Bot commented Aug 25, 2026

Copy link
Copy Markdown

Deploy Preview for smart-drop failed.

Name Link
🔨 Latest commit f15f81c
🔍 Latest deploy log https://app.netlify.com/projects/smart-drop/deploys/6a8e50f486a3730008adda73

@netlify

netlify Bot commented Aug 25, 2026

Copy link
Copy Markdown

Deploy Preview for spiffy-melomakarona-eb1e8a failed.

Name Link
🔨 Latest commit f15f81c
🔍 Latest deploy log https://app.netlify.com/projects/spiffy-melomakarona-eb1e8a/deploys/6a8e50f413e8da0008b2356d

@Bryandero98

Copy link
Copy Markdown
Author

Hi team! I noticed this issue was unassigned but had a few folks in the queue. I had some free time and went ahead and implemented the full solution with Vitest coverage (7/7 passing) just to speed things up in case you need a quick merge. I fully respect the Drips Network assignment process, so feel free to review or handle it however fits your workflow best. Cheers!

…ntexts

Netlify sets CONTEXT to production/deploy-preview/branch-deploy. The strict validateEnv() from the previous commit blocks deploy-preview builds that don't have production Soroban config (NEXT_PUBLIC_FACTORY_CONTRACT_ID, STELLAR_FEE_SPONSOR_SECRET) configured in Netlify - those builds fell into silent demo mode before this PR too, so warn-and-continue there is not a regression, just a louder version of the previous behavior. Local dev/build and the production context stay strict, per the original issue.

9/9 tests green, including two new cases for the strict:false path.
@Bryandero98

Copy link
Copy Markdown
Author

Following up on the failed deploy previews above.

My validateEnv() from this PR was strict in every context, including Netlify's deploy-preview/branch-deploy builds — which don't necessarily have NEXT_PUBLIC_FACTORY_CONTRACT_ID / STELLAR_FEE_SPONSOR_SECRET configured. Pushed a fix: it now detects Netlify's CONTEXT env var and warns instead of failing the build for deploy-preview/branch-deploy, while staying strict for local dev/build and the production context (the actual intent of this issue). 9/9 tests still green.

But that's not the whole story: I also checked out a clean copy of main with none of my changes and ran next build there directly — it fails too, on a pre-existing TypeScript error in TvlChart.tsx/soroban.ts unrelated to this PR (getPoolHistory's return type is missing [], plus a missing Account import). So the deploy-preview failures above weren't only my env validation — the build breaks downstream of it regardless. Opened #246 with just those two fixes so it's not tangled up with this PR's actual scope, and it also unblocks CI for anyone else's open PR against main, not just this one. There's a third pre-existing issue (useLeaderboard.ts calling getLeaderboard with an unsupported 4th search argument) that's incomplete feature work rather than a typo, so I left that one alone — noted in #246.

Unrelated to this PR's env-validation change, but next build type-checks
the whole app, so these also block this branch's own Netlify preview:

- getPoolHistory's return type was missing the array brackets - the
  implementation always returns an array (via .map(...) on success or
  [] on catch), so every caller consuming it as a single object was
  wrong.
- Account was used (accountCache/inflightAccount maps) but never
  imported from @stellar/stellar-sdk.

Same root-cause fix as PR SmartDropLabs#246 (opened separately against main, since
these bugs pre-date this branch); applying it here directly too so
this PR's own Netlify checks aren't blocked on SmartDropLabs#246 landing first.
@Bryandero98

Copy link
Copy Markdown
Author

Pushed a fix for two pre-existing type errors on this branch (not caused by this PR's env-validation change, but next build type-checks the whole app so they block this branch's own Netlify preview too):

  • getPoolHistory's return type was missing the array brackets - the implementation always returns an array.
  • Account was used but never imported from @stellar/stellar-sdk.

Same root cause I already fixed separately in #246 (opened against main, since these bugs pre-date this branch and that PR). Applied the identical 2-line fix here directly so this PR isn't blocked waiting on #246 to land first. next build (with CONTEXT=deploy-preview) now passes cleanly, and the full test suite shows no new failures (verified against a clean stash of this commit - same 10 pre-existing failures either way, consistent with flake unrelated to this change).

One remaining caveat I can't fix from here: package-lock.json is out of sync with package.json repo-wide (missing the @next/bundle-analyzer subtree - same finding as in #246), which makes npm ci fail before any build step runs. If Netlify's checks are still red after this push, that's almost certainly why. I didn't regenerate the lockfile myself since I only have npm 11/Node 24 locally and CI's npm ci step (per the public deploy GitHub Actions log) runs npm 10.8.2/Node 20.20.2 - a lockfile regenerated with a newer toolchain than CI's produced a much larger diff than the missing packages alone would explain, and I didn't want to commit that without verifying against the same npm/Node version CI actually uses.

@Bryandero98

Copy link
Copy Markdown
Author

Closing this PR as superseded. Upon checking, issue #199 has already been resolved and merged into main via PR #216 with a warning-only environment validation approach. My implementation is now redundant, so I am closing this out to keep things clean. Great work by the team!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No env variable validation at build time

1 participant