# musiquay (web app) The browser side of musiquay: the wasm bundles and static shell, built from the smesh web app with the kind-1 forum stripped out. It boots, you can create a vault, sign in and reach settings/wallet; the main area is deliberately empty and notifications are deliberately empty. The native relay lives in `../morly` and serves `web/static/` (static files, `/blossom/`, `/proxy/` and the Nostr WebSocket endpoint). Shared protocol code comes from `../nostr`. The protocol corpus for the platform is in `docs/` (a copy of `~/s/musiquay/docs`). ## Build make build # every wasm bundle -> web/static/ make dev # the same minus the signer (relay already running) make test-unit # every package under web/ carrying a *_test.mx make test-helpers # the standalone vector harnesses under web/_test/ make test-signer # the signer wasm under the node harness make test-smoke # playwright: boot, sign in, assert the parked state make test # all of the above `make test-smoke` needs the relay built first: `cd ../morly && make build` (override with `make test-smoke MORLY=/path/to/morly`). It starts the relay on port 3401 against this repo's `web/static` and writes a screenshot to `test/artifacts/`. `make test-signer` runs `web/_test/signertest/run.mjs`, which loads the signer wasm and checks it against the legacy moxiejs secp256k1 runtime as an *independent* verifier. That runtime is a build product of the legacy compiler and is not in this tree; the harness looks in `../smesh/ext/signer-bg/$runtime` or wherever `MOXIEJS_RUNTIME` points. ## What is parked The code is in the tree; only the entry points are gated off. - **Forum (kind 1)** - no sidebar compose/feed buttons, no `/compose`, `/feed`, `/t/...` or `/search` routes (they land on the empty home page), no kind-1 subscription, and `feed.wasm` is not built or served. The feed/compose/ thread/search pages and the feed worker are kept for the port. - **Direct messages (MLS/Marmot)** - the worker is not built or served. Its KeyPackage generation panics inside Moxie's codec (an invalid type descriptor, `kind=0`); re-enable when that is fixed. - Notifications are wired but subscribe to nothing, so the page stays empty. The build targets `build-feed-wasm` and `build-mls-wasm` exist for when those features come back. ## Sharing code with morly `moxie.mod` replaces `git.smesh.lol/nostr` with `../nostr`, so both this app and the relay import one implementation of the protocol types and codecs: replace git.smesh.lol/nostr => ../nostr Shared packages must compile for both wasm and native: pure types, parsers and encoders are fine; anything touching `os`/`net`/syscalls is native-only and stays in `../morly/pkg`. Shared code goes under a `/pkg/` path segment, which is where the compiler stops applying the application-code restrictions. The app still carries its own older ports under `web/common/` (marmot, the MLS subset, jsbridge). Porting them onto `../nostr` is a later project. ## Bugs this base fixed Found while getting the shell to boot, sign in and route. All were verified by the smoke suite or the signer harness, not by inspection. - **Translations never applied.** Every `t("key")` returned the key, so the login page read `subtitle` instead of its tagline and Japanese/Portuguese were unreachable. The i18n tables are `map[string]map[string]string` written with elided inner literals (`"en": { ... }`); stage4 built each entry's value as an empty map, silently. Fixed in the compiler (`_mxc_stage4/ssa_builder.mx`) and covered by `tests/data/maplit` + phase6 `6r` in the moxie tree. - **The signer answered no management method.** The wasm signer's methods are `musiquay.*`, the JS host asked for `musiquay.*`, but the byte-built method names in `web/wasm/signer/main.mx` still spelled `smesh.*`, so every vault call came back `{"error":"unknown method"}` and the signer panel rendered empty. - **Vault and permission storage keys were split.** `vaultStorageKey` was `musiquay-vault` while several call sites built `smesh-vault` byte by byte, so `resetExtension` deleted a key nothing wrote and `importVault` wrote a key nothing read. The permissions and NWC keys had the same split. The legacy v1 *crypto* salt stays `smesh-vault-salt:` on purpose - it is the interop contract for importing an old vault. - **Deep links landed on home.** `showApp` pushed `/` (via `switchPage("home")`) before the router read the initial URL, so `/settings` and `/notifications` always opened the home page. The router now shows home as a route instead of pre-empting the URL. - **Every bech32 payload was wrong.** `web/_test/bech32test` (wired up as `make test-helpers`) showed encode/decode round trips failing. The cause was in the compiler, not here: `acc := 0` left the variable *untyped*, so the `byte(...)` around a shift retyped the shift to 8 bits and it ran on the accumulator's low byte. Fixed in the moxie tree (`tests/data/untypedvar`, phase6 `6t`); npub/nsec display went from wrong to right, and the harness's nsec known answer now matches the pubkey the signer derives.