System topology
The browser-to-chain path, numbered from local preparation to public settlement.
The numbered path is the write path. The dashed line is the free-read path used for balances, prices, constants and action rehearsal.
The numbered route is for pool writes. Chat is the exception: its ciphertext goes from browser
to /api/room/*, through the app host and room relay, then to the other browser; it never reaches
Starknet. Follow the separate Chat map,
Mail map, Passkey map, or
Earn / Yield map for each complete path.
Prepare in the browser
The browser holds the active account key, keeps the shielded and public balances separate, reads
chain state and asks the privacy SDK builder to compose the action list. Proven writes use state
from latest − 10; the proof facts and proof travel together as transaction details.
Post to the same-origin host
The browser sends the request to /api/* on the app's own origin. No relayer credential is bundled
into browser JavaScript.
Inject the relayer credential
The app host proxy adds the server-held auth token and forwards the bounded request. This is a credential boundary, not a privacy claim: the host can see the request it forwards.
Validate and submit from the relayer
The relayer checks its (contract, entrypoint) allowlist, reads the live pool fee for any capped
STRK approval, then submits the v3 invoke. Its account is the visible submitter, and it learns the
request IP and timing.
Settle on Starknet
The STRK20 pool and the selected product contract execute the action list. Pool notes, app commitments and receipts become part of the public record according to the surface. A deposit is a public leg; later note ownership is what the pool obscures.
Who touches the request
| Party | What it is | What it sees |
|---|---|---|
| Your browser | Holds the active key; a password or passkey can seal the stored account record | Everything needed to prepare the action |
| App host proxy | Same origin. The browser posts to /api/* and the host injects the relayer auth token | The request. The browser never holds the token |
| Relayer | A trust assumption, and named as one | Pool writes: your IP and request timing. Chat: ciphertext plus room metadata. It never carries Mail and holds no key of yours |
| Starknet · STRK20 pool | The public record | Deposits: depositor and amount. What it hides is which notes are yours afterwards |
The proxy exists so the browser never holds a secret
The relayer requires an auth token when it is reachable off-loopback. If the browser held that token, it would be in the bundle, which means it would be public — so the app host injects it server-side and the browser posts to same-origin paths. See the relayer.
Why the relayer is the visible submitter
This is the whole reason it exists. Somebody's address appears on-chain as the submitter of every transaction, and the design choice is whether that is yours or ours. It is ours.
The cost is that the relayer learns your IP and the timing of your request, which is why it is listed as a trust assumption on the surface and here, rather than described as infrastructure.
Design rules that follow
The account is an embedded key. Generated in the browser during setup, then optionally sealed with a password or passkey. See the account and the separate Passkey architecture.
The name directory is public by construction. Claiming a name publishes name → address; that
is its function. Search is private — the client fetches the whole list and matches locally.
No protocol number is hardcoded. The pool fee is mutable with no upgrade delay, so it is read
from the pool at call time, every time. evidence/ records only what a probe actually measured.