Skip to content

[1626] [frontend] Move Stellar Horizon, explorer, passphrase and price-API URLs into network config - #1700

Merged
Junirezz merged 5 commits into
Junirezz:mainfrom
ToryMic:fix/1626-frontend-move-stellar-horizon-explorer-passphrase-and-price-api-urls-into-network-config
Oct 19, 2026
Merged

Junirezz merged 5 commits into
Junirezz:mainfrom
ToryMic:fix/1626-frontend-move-stellar-horizon-explorer-passphrase-and-price-api-urls-into-network-config

Conversation

@ToryMic

@ToryMic ToryMic commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Closes #1626

Closes 1626

Summary

Network passphrase, Horizon, Stellar Expert and price-API URLs were read (or
hard-coded) in a dozen places, bypassing the single network config. This PR makes
frontend/src/config/network.ts the only source for them, removes the
VITE_STELLAR_NETWORK_PASSPHRASE ?? "" fallbacks, and documents the new
overrides in .env.example.

Changes

config/network.ts is now the single source

Value Default (testnet / mainnet) Override
networkConfig.horizonUrl horizon-testnet.stellar.org / horizon.stellar.org VITE_HORIZON_URL
networkConfig.explorerUrl, stellarExplorerBaseUrls stellar.expert/explorer/testnet / …/public VITE_STELLAR_EXPLORER_URL
networkConfig.xlmPriceApiUrl CoinGecko simple/price?ids=stellar&vs_currencies=usd VITE_XLM_PRICE_API_URL
  • Added getHorizonUrlForRpcUrl() so lib/stellarAccount.ts no longer keeps its
    own testnet/mainnet Horizon constants, and dropped its local RPC default in
    favour of networkConfig.rpcUrl.
  • Added config/externalLinks.ts for the referral share endpoints.

Passphrase reads

NetworkSwitchNotification, TransactionStatus and TransactionStatusModal
read import.meta.env.VITE_STELLAR_NETWORK_PASSPHRASE ?? "" directly. They now
derive the mode from networkConfig.isTestnet, so the passphrase is only ever
read in config/network.ts:

$ grep -rn VITE_STELLAR_NETWORK_PASSPHRASE frontend/src --include=*.ts --include=*.tsx
frontend/src/config/network.ts:22:  import.meta.env.VITE_STELLAR_NETWORK_PASSPHRASE || TESTNET_PASSPHRASE;

The dead detectExpectedNetwork() helper in NetworkSwitchNotification is gone
(it also compared "Testnet" with "testnet", so the testnet manual-steps branch
was unreachable; fixed while removing the env read).

Horizon

lib/transactionApi.ts, hooks/useTransactionTimeline.ts,
components/TransactionStatusModal.tsx, pages/TransactionReceipt.tsx and
lib/stellarAccount.ts all use networkConfig.horizonUrl (or
getHorizonUrlForRpcUrl) instead of a hard-coded testnet endpoint.

Explorer

  • lib/security.ts#getStellarExplorerUrl() builds links from
    stellarExplorerBaseUrls instead of two inline literals.
  • components/TransactionTimeline.tsx now calls getStellarExplorerUrl()
    instead of building https://stellar.expert/explorer/testnet/tx/… inline, and
    does not render the link when the hash fails validation (getStellarExplorerUrl
    returns "#").
  • pages/TransactionReceipt.tsx builds both the transaction and the ledger link
    from the config (the ledger link previously pointed at …/tx/ledger/<n>).
  • ALLOWED_EXTERNAL_DOMAINS now includes the configured explorer/Horizon
    hostnames so overriding them does not make sanitizeExternalLink() return "#".

Price API

lib/vaultApi.ts#getXlmPrice() uses networkConfig.xlmPriceApiUrl.

Docs

  • frontend/.env.example: documented defaults + the three optional overrides.
  • docs/ENV_VARIABLE_MATRIX.md: new rows / updated sources for the frontend
    Stellar section (count updated in ENVIRONMENT_SETUP_GUIDE.md).

Tests

  • frontend/src/config/network.test.ts (new): testnet defaults, mainnet
    derivation from the passphrase, VITE_ overrides, and RPC → Horizon mapping.
  • frontend/src/components/TransactionTimeline.test.tsx: asserts the explorer
    href equals getStellarExplorerUrl(hash, "testnet") for a valid 64-char hash,
    plus a new case proving no link is rendered for an invalid hash.
  • frontend/src/pages/TransactionHistory.test.tsx: the ../config/network mock
    now spreads the real module so per-network explorer bases stay available.

Verification

  • TZ=UTC npx vitest run → 129 files / 1381 tests passing
  • npm run lint → 0 errors (37 pre-existing warnings, unchanged)
  • npx tsc -b → clean
  • npm run build → exit 0
  • npm run check-size → 7/7 checks passed

Notes

Contracts lint + test + build, Rust + WASM CI, Cargo Security Audit,
Slither, NPM/PNPM Audit, GitHub Dependency Review and
Governance & PR Standards Validation fail identically on main (verified against
the current baseline PRs); they are unrelated to this change.

ToryMic added 5 commits October 19, 2026 07:02
Network passphrase, Horizon, explorer and price-API URLs were read or
hard-coded in a dozen places, bypassing `config/network.ts`.

- `config/network.ts` now owns `horizonUrl`, `explorerUrl`,
  `xlmPriceApiUrl`, per-network `horizonBaseUrls` /
  `stellarExplorerBaseUrls` and `getHorizonUrlForRpcUrl()`, each with a
  built-in default that can be overridden through
  `VITE_HORIZON_URL`, `VITE_STELLAR_EXPLORER_URL` and
  `VITE_XLM_PRICE_API_URL`
- drop the direct `VITE_STELLAR_NETWORK_PASSPHRASE ?? ""` reads in
  `NetworkSwitchNotification`, `TransactionStatus` and
  `TransactionStatusModal`; they now derive the mode from
  `networkConfig.isTestnet`
- route every Horizon call (`transactionApi`, `useTransactionTimeline`,
  `TransactionStatusModal`, `TransactionReceipt`, `stellarAccount`)
  through `networkConfig.horizonUrl`
- `getStellarExplorerUrl()` builds links from
  `stellarExplorerBaseUrls`; `TransactionTimeline` uses it instead of
  inlining the URL and no longer renders a dead link for an invalid hash
- move the CoinGecko price URL and the referral share endpoints into
  config modules
- keep `ALLOWED_EXTERNAL_DOMAINS` in sync with the configured explorer
  and Horizon hosts so overrides do not break `sanitizeExternalLink`
- document the new variables and their defaults in `.env.example` and
  `docs/ENV_VARIABLE_MATRIX.md`

Closes 1626
@ToryMic
ToryMic requested a review from Junirezz as a code owner October 19, 2026 11:27
* fall back to the Horizon endpoint of the configured network.
*/
export function getHorizonUrlForRpcUrl(rpcUrl: string): string {
if (rpcUrl.includes(TESTNET_SOROBAN_RPC_HOST)) {
if (rpcUrl.includes(TESTNET_SOROBAN_RPC_HOST)) {
return horizonBaseUrls.testnet;
}
if (rpcUrl.includes(MAINNET_SOROBAN_RPC_HOST)) {
@drips-wave

drips-wave Bot commented Oct 19, 2026

Copy link
Copy Markdown

@ToryMic Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Junirezz
Junirezz merged commit 2b1fa7e into Junirezz:main Oct 19, 2026
19 of 32 checks passed
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.

[frontend] Move Stellar Horizon, explorer, passphrase and price-API URLs into network config

3 participants