Skip to content

ledger: improve browser compatibility - #281

Merged
rvolosatovs merged 2 commits into
mainfrom
roman/ledger/server-fixes
Oct 22, 2026
Merged

rvolosatovs merged 2 commits into
mainfrom
roman/ledger/server-fixes

Conversation

@rvolosatovs

Copy link
Copy Markdown
Contributor

No description provided.

@rvolosatovs
rvolosatovs force-pushed the roman/ledger/server-fixes branch from 85ced7c to 5f975c1 Compare October 22, 2026 14:55
@rvolosatovs
rvolosatovs marked this pull request as draft October 22, 2026 14:56
@rvolosatovs
rvolosatovs force-pushed the roman/ledger/server-fixes branch 3 times, most recently from 7c275c2 to bbab6d6 Compare October 22, 2026 16:21
The ledger stores a posted transaction as signed, so the digests in it
are kept exactly as submitted. Input transaction digests were accepted in
any multibase base and output contract digests were not checked at all,
so a transaction naming a contract as `BCIQ...` was accepted and then
served back in a form clients that only accept the canonical
base32-lower encoding reject.

Reject input transaction and output contract digests that are not in
the canonical form produced by `encode_digest`, with a distinct error
for each. Lookups still accept any base.

Genesis outputs are served the same way, so `Ledger::new` now panics on
a genesis output contract digest that is malformed or not canonical.

The client named outputs of imported UTXO contracts by the import's
`external-id` verbatim, so a contract importing another as `BCIQ...`
would produce transactions the ledger now rejects. Name them by the
canonical encoding of the resolved digest instead.

Assisted-by: anthropic:claude-opus-5-5
Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
Browsers send a CORS preflight before a `POST /rpc` with
`content-type: application/x.wrpc`, and the ledger answered it with
`405 Method Not Allowed` and no `Access-Control-*` headers, so a page on
another origin (such as the website sandbox) could not query the ledger
at all.

Answer `OPTIONS` on each known path with `Allow` and
`Access-Control-Allow-Methods` listing the methods it accepts (now
including `OPTIONS`, also in `405` responses), `*` allowed headers and a
one-day `Access-Control-Max-Age`, and add
`Access-Control-Allow-Origin: *` and `Access-Control-Expose-Headers: *`
to every response. Unknown paths still get `404 Not Found`. Any origin
is allowed: requests carry no credentials, and writes are authorized by
their signed envelopes.

The headers are constant per path, so they are set in-tree rather than
via tower-http's `CorsLayer`, which answers every `OPTIONS` request as a
preflight and is cloned with its configuration for each request when
served through hyper-util's `TowerToHyperService`.

Assisted-by: anthropic:claude-opus-5-5
Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
@rvolosatovs
rvolosatovs force-pushed the roman/ledger/server-fixes branch from bbab6d6 to 0151e0b Compare October 22, 2026 16:27
@rvolosatovs
rvolosatovs marked this pull request as ready for review October 22, 2026 16:28
Comment thread docs/ledger.md

## HTTP API

CORS is permissive: any origin and request header other than

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose a real ledger might not want this? But it makes sense for the mock ledger.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably 🤔

The docs do call out that this is not secure at the top

:::warning
This is a development ledger, not a secure one. Anyone can spend any
unspent output except genesis outputs, which require the admin's
signature, and proofs are not checked. State is held in memory and is lost
when the node stops.

@rvolosatovs
rvolosatovs merged commit d30a679 into main Oct 22, 2026
5 checks passed
@rvolosatovs
rvolosatovs deleted the roman/ledger/server-fixes branch October 22, 2026 17:45
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.

2 participants