5.1 KiB
Extension architecture
Product and implementation status
One browser extension hosts four tabs: Nostr (identities, events, relays), Wallet (BTC accounts, balances, transaction review), Inscribe (content and commit/reveal transaction preparation), and Chain (chain inspection and isolated test-network experiments). v0.2 implements the first narrow wallet boundary for Super Testnet: an extension-owned test Taproot key, page provider bridge, semantic approval popup, and commit/reveal signing. Nostr, real-network custody, encrypted vaulting, and generalized wallet RPC remain design work.
Shared primitives and key hierarchy
A single master seed belongs to an extension-private vault. A BTC derivation adapter produces network/account-scoped BTC keys. A separate BIP-85 adapter derives deterministic entropy for indexed Nostr identities; BTC keys must never be reused as Nostr identities. Before implementation, specify and version the exact BTC paths, BIP-85 application/path, entropy-to-scalar validation, identity indexes, and recovery metadata, and validate against published test vectors. Do not invent an incompatible derivation scheme silently.
All tabs use one shared key service, signing service, encrypted storage service, and network configuration. Feature adapters construct requests and consume public keys, addresses, signatures, and transaction results. They never accept the master seed as a parameter. Only the trusted vault/derivation/signing boundary handles secret bytes. Keep plaintext keys out of logs, DOM, sync storage, error messages, telemetry, and content scripts. Persist only authenticated encrypted vault data, with reviewed password KDF parameters and versioned migrations. Locking and background-worker suspension must clear in-memory authority and require unlock again; JavaScript cannot guarantee physical memory erasure.
The extension now has a trusted Manifest V3 service worker plus storage permission for a test-only Super Testnet key. This is intentionally not the future production vault: it is unencrypted local extension storage and must never hold real funds. Backup/recovery, auto-lock, encrypted vaulting, unlock UX, and corruption recovery remain gates before any real-network key.
Requests and trust boundaries
Planned flow: site/agent → untrusted bridge → trusted extension request validator → permission and confirmation UI → key/signing service → bounded response. Do not expose generic key export, seed access, arbitrary derivation, or unrestricted signing RPCs. Bind grants to authenticated sender origin, account/identity, network, operation, expiry, and appropriate spending/rate limits. Validate schemas, sizes, sender provenance, replay protection, and revocation on every request. A claimed origin inside a payload is not authentication.
For BTC, review transaction outputs, fees, inputs, network, and change before signing; distinguish signing from broadcast authorization. For Nostr, constrain event kinds and identity and show the event being authorized. NWC connection credentials are secrets too; keep them inside the vault and expose only budgeted, expiring payment capabilities. A narrow site bridge now exists for supertestnet.lol and localhost development: bitcoin_getAccounts, bitcoin_getNetwork, and ord_signInscription. Signing requests are origin-bound by the content-script match plus service-worker validation and require an extension approval window. NWC integration does not exist yet.
Treat relay events, inscription content, and chain responses as untrusted data; render text safely and isolate active content. Chain experiments must use explicit network selection and separate account contexts, never silently route mainnet funds into a sandbox.
Upstream integration
Keep original upstream trees intact under upstream/<repository>. Put future reviewed adapters and shared primitives under packages/, with provenance for any derived code. Do not package upstream demo HTML or import its remote scripts directly. Audit dependencies and notices, pin/localize required runtime code, remove demo secret-handling patterns, and adapt inline scripts for extension CSP before enabling functionality. Preserve original licenses and asset-specific notices when extracting code.
Unsquashed Git subtrees preserve original commit identities and ancestry while permitting a normal clone without recursive setup. This is preferable here to flattened copies or submodules that require additional checkout steps. Coinos remains a reference; vanilla-js-nostr awaits license clarification. Exact commands and pinned tips are in SOURCES.md.
Next implementation gates
- Resolve Nostr source licensing and complete bundled dependency/asset attribution review.
- Specify deterministic derivation and recovery formats; add independent known-answer tests.
- Implement encrypted vault, lock lifecycle, and signing policy with failure-path tests.
- Adapt each feature against shared primitives, beginning with explicit test networks.
- Add bounded external capabilities only after origin, consent, expiry, replay, and revocation tests.
- Test loading, navigation, CSP, and lifecycle in supported browsers before release.