Files
inscriboor/docs/architecture.md
T

4.7 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). The current vanilla-JS shell provides navigation only. The following is a design contract, not implemented cryptography or a working wallet.

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 initial shell requests no permissions and has no vault or background worker. Introduce a trusted extension worker and narrowly scoped storage permissions only when implementing these primitives. Backup/recovery, auto-lock, unlock UX, and corruption recovery require explicit design before real funds.

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. No site/agent bridge or NWC integration exists 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

  1. Resolve Nostr source licensing and complete bundled dependency/asset attribution review.
  2. Specify deterministic derivation and recovery formats; add independent known-answer tests.
  3. Implement encrypted vault, lock lifecycle, and signing policy with failure-path tests.
  4. Adapt each feature against shared primitives, beginning with explicit test networks.
  5. Add bounded external capabilities only after origin, consent, expiry, replay, and revocation tests.
  6. Test loading, navigation, CSP, and lifecycle in supported browsers before release.