Skip to content
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
33 changes: 12 additions & 21 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,26 +140,24 @@ jobs:
- name: test-wallet-backend
identifier: 'wallet:backend'
path: packages/wallet/backend
# No build configuration: every URL, the theme and the feature flags
# are read from the container environment per request, so one image
# serves every deployment. The Helm chart supplies the values.
- name: test-wallet-frontend
identifier: 'wallet:frontend'
path: packages/wallet/frontend
port: 4003
cookie_name: testnet.cookie
backend_url: https://api-wallet.interledger-test.dev
open_payments_host: $ilp.interledger-test.dev/
auth_host: https://auth.interledger-test.dev
gatehub_env: sandbox
theme: dark
# Byte-identical to test-wallet-frontend, still published so the
# interledger.cards deployments keep resolving the name they
# reference. Retire once they repoint.
#
# This image no longer carries baked URLs. Any deployment on either
# name must supply BACKEND_URL, OPEN_PAYMENTS_HOST and AUTH_HOST, or
# the container exits at start-up naming what is missing. The Helm
# chart sets them; a deployment pinned to an older chart, which wrote
# `NEXT_PUBLIC_*` keys, must be upgraded with the image.
- name: test-wallet-frontend-cards
identifier: 'wallet:frontend'
path: packages/wallet/frontend
port: 4003
cookie_name: interledgercards.cookie
backend_url: https://api.interledger.cards
open_payments_host: $ilp.dev/
auth_host: https://auth.interledger.cards
gatehub_env: production
theme: light
- name: test-boutique-frontend
identifier: 'boutique:frontend'
path: packages/boutique/frontend
Expand Down Expand Up @@ -217,11 +215,4 @@ jobs:
${{ matrix.package.identifier == 'boutique:frontend' && format('VITE_API_BASE_URL={0}', matrix.package.api_base_url) || '' }}
${{ matrix.package.identifier == 'boutique:frontend' && format('VITE_CURRENCY={0}', matrix.package.currency) || '' }}
${{ matrix.package.identifier == 'boutique:frontend' && format('VITE_THEME={0}', matrix.package.theme) || '' }}
${{ matrix.package.identifier == 'wallet:frontend' && format('PORT={0}', matrix.package.port) || '' }}
${{ matrix.package.identifier == 'wallet:frontend' && format('COOKIE_NAME={0}', matrix.package.cookie_name) || '' }}
${{ matrix.package.identifier == 'wallet:frontend' && format('NEXT_PUBLIC_BACKEND_URL={0}', matrix.package.backend_url) || '' }}
${{ matrix.package.identifier == 'wallet:frontend' && format('NEXT_PUBLIC_OPEN_PAYMENTS_HOST={0}', matrix.package.open_payments_host) || '' }}
${{ matrix.package.identifier == 'wallet:frontend' && format('NEXT_PUBLIC_AUTH_HOST={0}', matrix.package.auth_host) || '' }}
${{ matrix.package.identifier == 'wallet:frontend' && format('NEXT_PUBLIC_GATEHUB_ENV={0}', matrix.package.gatehub_env) || '' }}
${{ matrix.package.identifier == 'wallet:frontend' && format('NEXT_PUBLIC_THEME={0}', matrix.package.theme) || '' }}
tags: ${{ steps.image_tags.outputs.tags }}
44 changes: 30 additions & 14 deletions helm/testnet-wallet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,36 @@ All application configuration is driven through `values.yaml`. Environment varia

Defined under `configMaps.backend.contentMap` and `configMaps.frontend.contentMap`. Keys map directly to environment variable names injected into each container via `envFrom`.

**Frontend ConfigMap keys** (`NEXT_PUBLIC_*` vars + runtime config):

| Key | `values.yaml` path |
| -------------------------------- | ----------------------------------------- |
| `NODE_ENV` | `config.frontend.nodeEnv` |
| `PORT` | `config.frontend.port` |
| `COOKIE_NAME` | `config.frontend.cookie.name` |
| `NEXT_PUBLIC_USE_TEST_KYC_DATA` | `config.frontend.features.useTestKycData` |
| `NEXT_PUBLIC_BACKEND_URL` | `config.frontend.urls.backend` |
| `NEXT_PUBLIC_OPEN_PAYMENTS_HOST` | `config.frontend.urls.openPaymentsHost` |
| `NEXT_PUBLIC_AUTH_HOST` | `config.frontend.urls.authHost` |
| `NEXT_PUBLIC_THEME` | `config.frontend.theme` |
| `NEXT_PUBLIC_GATEHUB_ENV` | `config.frontend.gatehub.env` |
| `NEXT_PUBLIC_FEATURES_ENABLED` | `config.frontend.features.enabled` |
**Frontend ConfigMap keys**

Read per request, never baked into the image: to move the wallet to a different
hostname, change the value and restart the pod. The names carry no
`NEXT_PUBLIC_` prefix because Next.js replaces those with literals at build
time.

| Key | `values.yaml` path |
| ---------------------- | --------------------------------------- |
| `NODE_ENV` | `config.frontend.nodeEnv` |
| `PORT` | `config.frontend.port` |
| `COOKIE_NAME` | `config.frontend.cookie.name` |
| `BACKEND_URL` | `config.frontend.urls.backend` |
| `BACKEND_INTERNAL_URL` | `config.frontend.urls.backendInternal` |
| `OPEN_PAYMENTS_HOST` | `config.frontend.urls.openPaymentsHost` |
| `AUTH_HOST` | `config.frontend.urls.authHost` |
| `THEME` | `config.frontend.theme` |
| `GATEHUB_ENV` | `config.frontend.gatehub.env` |
| `FEATURES_ENABLED` | `config.frontend.features.enabled` |

`BACKEND_URL` may be absolute, or a path such as `/wallet-api` where one
hostname serves the frontend at `/` and the backend at a prefix — a path needs
no edit when DNS changes. When it is a path, set `BACKEND_INTERNAL_URL` to the
in-cluster Service address: SSR has no origin to resolve against, and the
container refuses to start without it.

`BACKEND_URL`, `OPEN_PAYMENTS_HOST` and `AUTH_HOST` are required. The container
checks them before accepting traffic and exits if one is missing. It also
rejects a `BACKEND_URL` or `BACKEND_INTERNAL_URL` that is neither an absolute
http(s) URL nor, for `BACKEND_URL`, a path beginning with `/`.

**Backend ConfigMap keys** (see `configMaps.backend.contentMap` in `values.yaml` for the full list — covers `NODE_ENV`, `PORT`, cookie settings, GateHub config, Rafiki endpoints, Stripe flags, rate limiting, card URLs, and more).

Expand Down
80 changes: 80 additions & 0 deletions helm/testnet-wallet/tests/configMap.frontend_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# The key names are a contract with
# packages/wallet/frontend/src/lib/runtimeConfig.ts. A rename on one side alone
# leaves the container with nothing to read, and it exits at start-up.
suite: testnet-wallet frontend - runtime configuration
templates:
- configMap.frontend.yaml
set:
fullnameOverride: test-testnet-wallet
release:
name: test-testnet-wallet
tests:
- it: 'emits the runtime keys the frontend reads'
set:
config:
frontend:
theme: dark
urls:
backend: https://api.example.test
openPaymentsHost: https://ilp.example.test
authHost: https://auth.example.test
asserts:
- equal:
path: data.BACKEND_URL
value: https://api.example.test
- equal:
path: data.OPEN_PAYMENTS_HOST
value: https://ilp.example.test
- equal:
path: data.AUTH_HOST
value: https://auth.example.test
- equal:
path: data.THEME
value: dark
# Booleans must reach the ConfigMap as strings.
- equal:
path: data.FEATURES_ENABLED
value: 'false'
- equal:
path: data.NODE_ENV
value: production
# Numbers must reach the ConfigMap as strings.
- equal:
path: data.PORT
value: '4003'

# The build-time names. The container does not look for them.
# USE_TEST_KYC_DATA is gone in both spellings: the frontend stopped reading it
# in #1643, when GateHub KYC replaced Rapyd.
- it: 'emits no NEXT_PUBLIC_ key'
asserts:
- notExists:
path: data.NEXT_PUBLIC_BACKEND_URL
- notExists:
path: data.NEXT_PUBLIC_OPEN_PAYMENTS_HOST
- notExists:
path: data.NEXT_PUBLIC_AUTH_HOST
- notExists:
path: data.NEXT_PUBLIC_THEME
- notExists:
path: data.NEXT_PUBLIC_GATEHUB_ENV
- notExists:
path: data.NEXT_PUBLIC_FEATURES_ENABLED
- notExists:
path: data.USE_TEST_KYC_DATA

# A path means the page origin, so the server needs the in-cluster address.
- it: 'carries a path backend address and the in-cluster address together'
set:
config:
frontend:
urls:
backend: /wallet-api
backendInternal: http://test-testnet-wallet-backend-service:4003
asserts:
- equal:
path: data.BACKEND_URL
value: /wallet-api
- equal:
path: data.BACKEND_INTERNAL_URL
value: http://test-testnet-wallet-backend-service:4003
32 changes: 23 additions & 9 deletions helm/testnet-wallet/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,25 @@ config:
theme: 'dark'

urls:
# The backend address the browser uses. Absolute where the backend has
# its own hostname. Where one hostname serves the frontend at `/` and the
# backend at a prefix, use a path (`/wallet-api`): it follows the host
# that served the page, so it survives a DNS change. Set
# `backendInternal` too, because SSR cannot resolve a path.
backend: 'https://api.interledger-test.dev'

# The backend address the frontend container uses. Point it at the
# in-cluster Service to keep SSR traffic inside the cluster. Required
# when `backend` is a path; empty reuses `backend`.
backendInternal: ''

openPaymentsHost: 'https://ilp.interledger-test.dev'
authHost: 'https://auth.interledger-test.dev'

cookie:
name: 'testnet.cookie'

features:
useTestKycData: true
# Public features are intended for the production interledger.cards
# environment only
enabled: false
Expand Down Expand Up @@ -416,6 +426,10 @@ services:
# This section of the values file defines Kubernetes config maps that will be created
# for each service (backend and frontend).
configMaps:
# Read per request, never baked into the image: change one, restart the pod.
# The names carry no `NEXT_PUBLIC_` prefix because Next.js replaces those with
# literals at build time. See
# packages/wallet/frontend/src/lib/runtimeConfig.ts.
frontend:
name: 'frontend'
contentMap:
Expand All @@ -425,19 +439,19 @@ configMaps:
valueRef: config.frontend.port
- key: COOKIE_NAME
valueRef: config.frontend.cookie.name
- key: NEXT_PUBLIC_USE_TEST_KYC_DATA
valueRef: config.frontend.features.useTestKycData
- key: NEXT_PUBLIC_BACKEND_URL
- key: BACKEND_URL
valueRef: config.frontend.urls.backend
- key: NEXT_PUBLIC_OPEN_PAYMENTS_HOST
- key: BACKEND_INTERNAL_URL
valueRef: config.frontend.urls.backendInternal
- key: OPEN_PAYMENTS_HOST
valueRef: config.frontend.urls.openPaymentsHost
- key: NEXT_PUBLIC_AUTH_HOST
- key: AUTH_HOST
valueRef: config.frontend.urls.authHost
- key: NEXT_PUBLIC_THEME
- key: THEME
valueRef: config.frontend.theme
- key: NEXT_PUBLIC_GATEHUB_ENV
- key: GATEHUB_ENV
valueRef: config.frontend.gatehub.env
- key: NEXT_PUBLIC_FEATURES_ENABLED
- key: FEATURES_ENABLED
valueRef: config.frontend.features.enabled
backend:
name: 'backend'
Expand Down
41 changes: 28 additions & 13 deletions packages/wallet/frontend/.env.example
Original file line number Diff line number Diff line change
@@ -1,30 +1,45 @@
# You can copy this file to .env.local and adjust values to run the wallet frontend locally.
# If you create both .env.local and .env, values in .env override values from .env.local.
# Keep NEXT_PUBLIC_* URLs aligned with the local testnet domains.
# Copy to .env.local and adjust. If you create both .env.local and .env, values
# in .env win.
#
# Every variable here is read when the server answers a request, not when the
# bundle is built: `pnpm wallet:frontend dev` picks up an edit on the next
# request, a production image on the next pod restart.
#
# None of these names carries a `NEXT_PUBLIC_` prefix, and none should — Next.js
# replaces those with literals at build time, which is what used to tie a
# deployment URL to an image tag. See src/lib/runtimeConfig.ts.

########## SESSION AND INTERNAL BACKEND #########################################################

# COOKIE_NAME=testnet.cookie

# The address this process uses for the backend, skipping Traefik. Required
# when BACKEND_URL is a path.
# BACKEND_INTERNAL_URL=http://localhost:3003

########## PUBLIC FRONTEND CONFIG ################################################################
## NEXT_PUBLIC_* variables are exposed to the browser.
########## BROWSER-FACING CONFIG #################################################################
## The server writes these into every page; the browser reads them back.

# The backend address the browser uses. Absolute where the backend has its own
# hostname, which is the local setup. Where one hostname serves the frontend at
# / and the backend at a prefix, use the path (BACKEND_URL=/wallet-api): it
# follows whatever host served the page, so it survives a DNS change.
# BACKEND_URL=https://api.testnet.test

# NEXT_PUBLIC_BACKEND_URL=https://api.testnet.test
# NEXT_PUBLIC_AUTH_HOST=https://auth.testnet.test
# NEXT_PUBLIC_OPEN_PAYMENTS_HOST=https://rafiki-backend.testnet.test
# AUTH_HOST=https://auth.testnet.test
# OPEN_PAYMENTS_HOST=https://rafiki-backend.testnet.test

# NEXT_PUBLIC_THEME=light
# THEME=light

######### Controlling branding and features ######################################################
# NEXT_PUBLIC_FEATURES_ENABLED controls the wallet UI mode (frontend only):
# FEATURES_ENABLED controls the wallet UI mode (frontend only):
# - true: enables "Interledger Wallet" mode (wallet branding, card/deposit-first flows,
# cards menu visibility, card-related labels in transactions, and production-style auth copy)
# - false: enables "Test Wallet" mode (test branding, test-only hints, and cards visibility
# controlled by per-user settings instead of forced-on)
# If omitted, next.config.js defaults to false only when NODE_ENV=production and NEXT_PUBLIC_GATEHUB_ENV=sandbox
# If omitted, it defaults to false only when NODE_ENV=production and GATEHUB_ENV=sandbox,
# otherwise it defaults to true.

# NODE_ENV=production
# NEXT_PUBLIC_GATEHUB_ENV=production
# NEXT_PUBLIC_FEATURES_ENABLED=true
# GATEHUB_ENV=production
# FEATURES_ENABLED=true
17 changes: 11 additions & 6 deletions packages/wallet/frontend/.env.local
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
COOKIE_NAME=testnet.cookie

# Separate hosts locally, so the browser needs the absolute address.
BACKEND_URL=https://api.testnet.test

# SSR and the middleware go direct, skipping Traefik's self-signed certificate.
BACKEND_INTERNAL_URL=http://localhost:3003
NEXT_PUBLIC_BACKEND_URL=https://api.testnet.test
NEXT_PUBLIC_AUTH_HOST=https://auth.testnet.test
NEXT_PUBLIC_OPEN_PAYMENTS_HOST=https://rafiki-backend.testnet.test
NEXT_PUBLIC_GATEHUB_ENV=sandbox
NEXT_PUBLIC_THEME=dark
NEXT_PUBLIC_FEATURES_ENABLED=false

AUTH_HOST=https://auth.testnet.test
OPEN_PAYMENTS_HOST=https://rafiki-backend.testnet.test
GATEHUB_ENV=sandbox
THEME=dark
FEATURES_ENABLED=false
17 changes: 2 additions & 15 deletions packages/wallet/frontend/Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,7 @@ ADD . ./
# Install packages from virtual store
RUN pnpm install --filter @wallet/frontend... --offline

# Accept build arguments for Next.js public environment variables
ARG NEXT_PUBLIC_BACKEND_URL
ARG NEXT_PUBLIC_AUTH_HOST
ARG NEXT_PUBLIC_OPEN_PAYMENTS_HOST
ARG NEXT_PUBLIC_GATEHUB_ENV
ARG NEXT_PUBLIC_THEME
ARG NEXT_PUBLIC_FEATURES_ENABLED

# Make them available as environment variables during build
ENV NEXT_PUBLIC_BACKEND_URL=$NEXT_PUBLIC_BACKEND_URL
ENV NEXT_PUBLIC_AUTH_HOST=$NEXT_PUBLIC_AUTH_HOST
ENV NEXT_PUBLIC_OPEN_PAYMENTS_HOST=$NEXT_PUBLIC_OPEN_PAYMENTS_HOST
ENV NEXT_PUBLIC_GATEHUB_ENV=$NEXT_PUBLIC_GATEHUB_ENV
ENV NEXT_PUBLIC_THEME=$NEXT_PUBLIC_THEME
ENV NEXT_PUBLIC_FEATURES_ENABLED=$NEXT_PUBLIC_FEATURES_ENABLED
# No build arguments: configuration is read per request, so pass it to the
# container instead. See packages/wallet/frontend/.env.example.

CMD ["pnpm", "wallet:frontend", "dev"]
Loading
Loading