STATUS.md raw

status and evidence

what was verified

All commands run from the repository root with Go 1.25+ and TinyGo 0.43 (Go 1.27 from ~/.local/goroot where TinyGo needs it).

CheckResult
go test ./...pass
go vet ./...pass
go test -race ./pkg/tunnel ./pkg/neutrino ./internal/e2epass
tinygo build -target wasm -o bin/nostrino.wasm ./cmd/nostrino-wasmpass
tinygo build ./cmd/nostrino-bridge ./cmd/nostrino-neutrinopass
wasm sync through torly + bridge + test nodetip 50, 51 filters; ~2.7 s relay, ~20 ms WebSocket
IndexedDB reload (two wasm instances, fake-indexeddb)second sync adds 0, same tip, local match still works
wasm cancel mid-syncsettles as cancelled, bridge closes the session
frozen reader / zero credit4 MiB write blocks, then unblocks on reset
NIP-42 on a torly with auth requiredendpoint-to-endpoint sync passes
two relays, one dropping every eventstream continues on the other
WebSocket data plane (bridge=)e2e sync over the WS stream; both wasm smokes assert transport=websocket
reorg to a different branch at height 6old filters replaced, new branch matches
checkpoint at height 10starts at 10, verifies 11..tip, no filter below
gateway presence + nostrino-discoverfinds the URI, chains and node tip
file store resumesecond sync adds 0; tip and filters preserved
dropped relay events512 KiB echo survives 1-in-9 drops
profile JSON + difficulty/retarget/MTPunit tests pass

Reproduce:

make build wasm
./scripts/wasm-smoke.sh

(cd /tmp && npm install fake-indexeddb)   # once
NODE_PATH=/tmp/node_modules ./scripts/idb-smoke.sh

bin/nostrino-discover -relay wss://relay.example -chain btc

The smoke scripts start torly, the deterministic test node, the bridge and the wasm bundle under Node. They are the acceptance tests for the browser target.

known gaps

Ordered by what matters next.

  1. Pinned network data. Mainnet checkpoint values and the real XBT

parameters are not in the binary. -profile and -checkpoint-* accept them; the operator must obtain them from a trusted node and keep them current. A stale checkpoint only costs sync time; a wrong one is rejected on the first filter header.

  1. Streaming browser storage. The IndexedDB store loads its indexes into

memory on open. That is fine for a regtest chain and a recent-range wallet, but a full mainnet filter set (GB scale) needs a store that reads filters on demand. The Store interface is the seam; the sync loop should not change.

  1. First retarget after a checkpoint. The window's first block is not

stored, so that one boundary is accepted from the peer. Every later boundary is verified. A checkpoint that also pins the window's start would close this.

  1. Deep reorgs. Fork search is bounded at 10,000 headers. A deeper reorg

is refused rather than silently accepted, which is the safe failure; a mainnet wallet also needs the height it scans from.

  1. TLS termination for the bridge. The WebSocket data plane is

implemented, but the reference build listens in plain ws://. A public wss:// endpoint needs a reverse proxy (or a later TLS listener) and the operator supplies its advertised URL with -bridge-url.

  1. Registry abuse and accuracy. Presence is an unauthenticated public

advertisement; the tip is from a handshake every five minutes and can be stale. There is no TTL enforcement beyond the relay's addressable-event replacement, no per-publisher rate on announcements, and discovery trusts the payload (the event signature and d tag are checked, but a gateway can lie about its tip).

  1. Quotas and accounting. The bridge has a per-stream byte rate and a

per-client session cap. There is no per-day quota, no per-IP limit, and no accounting to bill or block a heavy client.

  1. Relay auth for reads. NIP-42 is answered and publications wait for the

auth result. A relay that requires auth for REQ is not specially handled; torly gates writes only.

  1. Wallet and swap layers. Out of scope for this repository: BIP32/BIP84,

UTXO selection, HTLC scripts, signing, the swap state machine, the settlement deadline recomputation on resume, and the server-side swap record. The registry and the tunnel deliberately do not carry swap state.

operational notes

DATA/gateway.uri.

45 s and the listener reconnects with backoff.

55 KiB of encrypted content.

adjust with -max-bytes-per-sec and -max-sessions-per-client.

NODE_COMPACT_FILTERS; an operator must still confirm blockfilterindex=basic and the filter index height.

bridge's idle bound and the WebSocket close/error events bound liveness. The P2P read deadline is advisory on that path.