Skip to content

fix(frontend): keep the public wallet config in the repo, not in deployment secrets - #53

Merged
TaprootFreak merged 2 commits into
developfrom
fix/wallet-config-in-repo
Jul 28, 2026
Merged

fix(frontend): keep the public wallet config in the repo, not in deployment secrets#53
TaprootFreak merged 2 commits into
developfrom
fix/wallet-config-in-repo

Conversation

@TaprootFreak

@TaprootFreak TaprootFreak commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

#49 wired the guard delegation section's two configuration values — a Citrea RPC URL and a WalletConnect
project id — through repository secrets. That was the wrong mechanism. Both are public by nature: they
are baked into the browser bundle at build time and visible to anyone who opens the dashboard. Treating them
as secrets implied a sensitivity they do not have, and it made the delegate button depend on deployment
configuration that a local build or a fork cannot supply.

They are now defaults in frontend/Dockerfile, directly alongside VITE_API_BASE_URL, which already worked
this way. Both frontend workflows stop passing them.

Effect

  • The wallet config no longer needs any setup: a build that supplies only the pre-existing
    VITE_DEPLOYMENT_ENV produces a working delegate button. (That one still has no default and is still
    checked fail-loud in frontend/src/constants.ts, deliberately — it must be exactly prd or dev. This PR
    does not change it.)
  • A deployment that wants a different endpoint or project still overrides either value with --build-arg.
  • Nothing about the read-only half changes: signer, voting power, qualification, helper count and gas come
    from the backend GET /guard endpoint and never needed these values.

The RPC default

https://rpc.citreascan.com — the same public endpoint the backend already uses. Verified that it answers
browser requests directly, so the bundle needs no proxy:

$ curl -sD- -X POST https://rpc.citreascan.com -H 'Origin: https://dev.monitoring.juicedollar.com' \
    -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'
access-control-allow-origin: *
{"jsonrpc":"2.0","id":1,"result":"0x1012"}

0x1012 is 4114, matching BLOCKCHAIN_ID.

Verification

Built the image with no build-arg for either value and confirmed both are present in the emitted bundle,
which is what proves the defaults take effect:

$ docker build --build-arg VITE_DEPLOYMENT_ENV=dev -f frontend/Dockerfile -t jusd-web-cfg:test .
$ docker run --rm --entrypoint sh jusd-web-cfg:test -c \
    'grep -rlo rpc.citreascan.com /usr/share/nginx/html/assets'
/usr/share/nginx/html/assets/index-B6KJsZnf.js

actionlint clean on both workflows, and both parse as valid YAML with their build and deploy jobs
intact.

frontend/.env.example now says what these values actually are — public, defaulted in the image, needed
locally only for the dev server — instead of describing them as required secrets.

…oyment secrets

The guard delegation section needs a Citrea RPC URL and a WalletConnect project
id. Both are public by nature: they are baked into the browser bundle and
visible to anyone who opens the dashboard. Wiring them through repository
secrets was therefore the wrong mechanism — it implied they were sensitive,
and it made the delegate button depend on deployment configuration that a
local or fork build cannot have.

They are now Dockerfile defaults, exactly like VITE_API_BASE_URL above them,
and both workflows stop passing them. A plain `docker build` now produces a
working delegate button, and a deployment that wants a different endpoint or
project can still override either with --build-arg.

The RPC default is the same public endpoint the backend uses; it answers
browser requests directly (access-control-allow-origin: *), so it needs no
proxy. Verified by building the image without any build-arg and confirming
both values are present in the emitted bundle.
… baked RPC URL

The delegate action builds its chain from the chain id the backend reports, while
the RPC URL is now a fixed default in this image. Repointing the backend at
another network without overriding the build-arg in the same breath leaves the
wallet transport pointed at Citrea while the declared chain id says otherwise,
and that combination builds silently. Naming the coupling where the override
lives is cheaper than a runtime cross-check and does not add a mechanism whose
own failure modes would need reviewing.
@TaprootFreak

Copy link
Copy Markdown
Contributor Author

Two review passes (conformity and behaviour), both clean. The behaviour pass raised one latent hazard worth naming rather than mechanising: the delegate action derives its chain from the chain id the backend reports, while the RPC URL is now a fixed default, so repointing the backend at another network without overriding the build-arg would leave the two disagreeing. That coupling is now stated in the Dockerfile next to the override it concerns.

@TaprootFreak
TaprootFreak marked this pull request as ready for review July 28, 2026 06:19
@TaprootFreak
TaprootFreak merged commit d8c96ba into develop Jul 28, 2026
5 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.

1 participant