Goal
Move the SIWE nonce fetch below the facade so apps/web holds no seam of its own.
Problem
facade.siweLogin(message, signature) exists, but nothing exposes the challenge that an
EIP-4361 message must embed. The engine's API client already has siwe_challenge()
(crates/engine/src/api/client.rs) against POST /auth/siwe/challenge; it is unreachable
from the facade.
Landing #804 therefore left apps/web/src/auth/siweNonce.ts doing a plain fetch against
the API's public challenge endpoint. That is the only direct API call in apps/web and it
contradicts blueprint/web-client.md "apps/web ... no crypto, no seams, no tokens" — its
only vault-facing dependency should be packages/client.
The nonce is public, single-use, and carries no key material, so this is an architecture
debt, not a live vulnerability.
Work
- Add a
siweChallenge read to the engine facade over the existing ApiClient::siwe_challenge,
and bind it in crates/wasm.
- Thread it through
packages/client: protocol.ts request/response, transport.ts,
the correlated/broadcast transports, worker/serve.ts, and facade.ts.
- Delete
apps/web/src/auth/siweNonce.ts and have WalletLoginButton read the nonce
from the facade.
Note
siweLogin is a Command, so it is refused with NotStarted before facade.start. Settle
whether the wallet method belongs on the cold login page at all, or only as a linked
secondary method on an already-started engine, while doing this.
Gate
Client Browser Suite + web unit.
Depends on
Shares a threading surface with #914: both add a facade member and carry it through crates/wasm and
packages/client (protocol.ts, transport.ts, the correlated/broadcast transports, worker/serve.ts,
facade.ts). Land one, rebase the other.
Blocks
Part of #642
Goal
Move the SIWE nonce fetch below the facade so
apps/webholds no seam of its own.Problem
facade.siweLogin(message, signature)exists, but nothing exposes the challenge that anEIP-4361 message must embed. The engine's API client already has
siwe_challenge()(
crates/engine/src/api/client.rs) againstPOST /auth/siwe/challenge; it is unreachablefrom the facade.
Landing #804 therefore left
apps/web/src/auth/siweNonce.tsdoing a plainfetchagainstthe API's public challenge endpoint. That is the only direct API call in
apps/weband itcontradicts
blueprint/web-client.md"apps/web ... no crypto, no seams, no tokens" — itsonly vault-facing dependency should be
packages/client.The nonce is public, single-use, and carries no key material, so this is an architecture
debt, not a live vulnerability.
Work
siweChallengeread to the engine facade over the existingApiClient::siwe_challenge,and bind it in
crates/wasm.packages/client:protocol.tsrequest/response,transport.ts,the correlated/broadcast transports,
worker/serve.ts, andfacade.ts.apps/web/src/auth/siweNonce.tsand haveWalletLoginButtonread the noncefrom the facade.
Note
siweLoginis aCommand, so it is refused withNotStartedbeforefacade.start. Settlewhether the wallet method belongs on the cold login page at all, or only as a linked
secondary method on an already-started engine, while doing this.
Gate
Client Browser Suite + web unit.
Depends on
apps/web/src/auth/siweNonce.tsand rewires theWalletLoginButtonthat web: harvest the v1 login UI and rewire it to the facade #804 landed.Shares a threading surface with #914: both add a facade member and carry it through
crates/wasmandpackages/client(protocol.ts,transport.ts, the correlated/broadcast transports,worker/serve.ts,facade.ts). Land one, rebase the other.Blocks
siweChallengebehindstart; web: give the wallet method a started-engine surface #938 acts on that settlement and movesWalletLoginButtonoff the cold login page.Httpseam a request deadline. This slice deleted theAbortSignal.timeout(10_000)thatapps/web/src/auth/siweNonce.tscarried, so web: give the Http seam a request deadline #939 restores that behaviour at the seam layer where it belongs.siweChallenge, which is what fires the rule of three; its threading is deliberately mechanical so client: generalize the facade read rail #942 can collapse it.Part of #642