Utexo's Browser SDK makes two claims: a full Lightning + RGB node inside a browser tab, and payments that arrive while you're offline. Both are real - and both come with architecture worth reading before you trust it. This note answers the two questions the announcement raised: who holds the HTLC, and where the stash lives.
Before reading the SDK, fix the physics. A browser tab is a strange place to run financial infrastructure - powerful in two ways, constrained in one that shapes everything else.
rgb-lightning-node compiles to WebAssembly and runs in-tab as @utexo/rln-wasm - the same Rust core read in No. 04, not a thin client. Two WASM bundles, deliberately separate memory spaces.
Browsers cannot dial raw TCP, and Lightning peers speak TCP. So every P2P byte tunnels through a WebSocket gateway - wss://ln-gateway-*.utexo.com by default, with production relays requiring an auth token.
The wallet DB path is an in-memory path inside WASM; a nodeRuntimeId keeps runtime state across reloads, and a VSS cloud backup - encrypted client-side - is configured automatically at init.
Five parts make the claim true. Tap each one for what the source actually says - including the parts that live outside your tab.
@utexo/rln-wasm is the rgb-lightning-node core compiled to WebAssembly - LDK for channels, rgb-lib for assets, running entirely inside the tab. Only one RLN wallet can exist per tab; creating a second requires removing the first and reloading.
The announcement's boldest line, decoded from docs/async-payments.md. You pre-register a signed pool of payment hashes with an always-online Host node. Then close the tab. Here is exactly what happens when someone pays you.
While online, your tab signs and uploads a batch of payment hashes - enableLightningAddress() - and the LSP mints you a stable username@domain address. The attestation signature guards against hash substitution.
LNURL discovery returns a fresh HODL BOLT11 from the Host for one of your pre-registered hashes. You are offline. Nothing wakes your tab.
The HTLC locks at the Host RLN - and stops there. Held, not settled. The Host cannot claim it: settling requires a preimage only your side can produce.
Your tab opens, lsp.connect() runs, and the LSP outbox reaches your node over P2P to request an outbound invoice for the held amount.
The Host pays your invoice; your node auto-claims - no manual claimHodlInvoice. The asset lands in your channel, validated client-side like any RGB transfer.
Only now - holding the preimage your claim revealed - does the Host settle the original HTLC. The payer's payment completes end-to-end.
Read off the repo, not the announcement.
"Full node in a tab" is true - and incomplete. The node is yours; by default, the wires are theirs. Five axes, each one swappable via constructor params. Tap for the source.
The mnemonic enters sdk.initValue(password, mnemonic) and never leaves the tab; signing is in-WASM. RGB validation is client-side, exactly as in No. 04 - your node replays state history itself. This is the part that makes "full node" honest.
No TCP in browsers, so proxyUrl defaults to wss://ln-gateway-signet.utexo.com and production gateways reject unauthenticated relays with 401 (relayAuthToken). The gateway sees your traffic patterns and can drop you - it cannot read channel crypto. Swappable: run your own gateway.
The tab has no chain. indexerUrl defaults to Utexo's indexer; goOnline() runs against it at unlock, and if it's unreachable the wallet comes up OFFLINE with a warning. Your view of Bitcoin is whatever the indexer serves - point it elsewhere if that matters to you.
VSS cloud backup is configured automatically at init with an identity derived from the mnemonic (storeId = wallet_<fingerprint>), against DEFAULT_VSS_SERVER_URL. The server holds ciphertext only - the No. 04 security model - but the default is on, and restore is never automatic. Pass null to opt out.
Offline receive means the Host RLN fronts for you: it holds HTLCs, mints your Lightning Address, and its outbox decides when delivery runs. APay routes need a lspBearerToken. It can't spend your money; it is your availability. Virtual channels v0 - on by default - deepen the same dependency.
The honest read: this is not a custodial wallet wearing a mask - keys, validation and claims are genuinely yours. It is a sovereign node with default-routed plumbing. Every axis above has a constructor param to move the dot left. Defaults are destiny for most users; that is the trade the browser buys.
Four things I would test in anger before putting user money behind a tab - the kind of checks that turn into good bug reports.
Kill the tab mid-payment, mid-claim, mid-channel-open. nodeRuntimeId promises state across reloads; the interesting cases are the ones between beats ④ and ⑥.
Browsers evict storage under pressure. An evicted stash plus a VSS restore that is "never automatic" is a recovery flow real users will hit - walk it before they do.
Every default URL - gateway, indexer, LSP - points at *-signet.utexo.com. "Live" today means live against signet infrastructure. The mainnet flip is a config change with production consequences.
refillHashPool() when unusedHashes runs low, and prefer apayNewWithAddress - the attested variant - over bare apayNew, which skips the signature that guards against hash substitution.
The two questions from the announcement, answered - plus what turned up on the way.
The Host RLN locks the payer's HTLC and cannot settle it without a preimage your claim produces. It sees every payment to your address and controls delivery timing - availability custody, not money custody. That is a defensible design, and it deserves to be stated as precisely as the marketing is bold.
question one · answeredThe wallet DB path is an in-memory path inside WASM; persistence rides nodeRuntimeId plus a VSS backup configured automatically at init, encrypted client-side, keyed from the mnemonic. Ciphertext-only - but a browser tab's stash is one eviction away from being a restore flow. No. 05 called stash custody RGB's sharp edge; the tab makes that edge a product surface.
Every production default in RlnDefaults.ts - the WS gateway, the indexer, the LSP - resolves to *-signet.utexo.com. Nothing wrong with that for a launch; worth knowing before you read "full node in a tab" as a mainnet claim today.
The engine in this tab is the exact core No. 04 read at beta.8 - now beta.14, with the version footnotes resolved upstream. The availability trade is the one No. 05 named as RGB's sharp edge. Field notes are starting to cite each other; that was the plan.
continuity · nos. 04 → 05 → 06