Define umbrella extension architecture, provenance, and minimal shell
This commit is contained in:
1 parent
8f169789ef
commit
05d6cd934d
7 files changed
+177
-1
No files matched your search
@@ -1,3 +1,20 @@
|
||||
# inscriboor
|
||||
|
||||
Browser-native Bitcoin + Nostr lab: Nostr, wallet, inscriptions, and chain sandbox.
|
||||
`matcha/inscriboor` is the umbrella repository for one browser extension with four tabs: **Nostr**, **Wallet**, **Inscribe**, and **Chain**. Browser-first, with vanilla JavaScript where practical.
|
||||
|
||||
The intended key model is one master seed, with separate BTC derivation and BIP-85-derived Nostr identities. Shared key, signing, and storage primitives will serve all four tabs. Raw seeds and private keys stay inside the extension; sites and agents receive only explicitly bounded capabilities and signing results.
|
||||
|
||||
## Current status
|
||||
|
||||
This repository contains an inert Manifest V3 extension shell and four unmodified, history-preserving Supertestnet subtree imports under `upstream/`. The shell does not load upstream demos, generate keys, store secrets, connect to networks, or sign transactions. No wallet functionality is implemented yet.
|
||||
|
||||
Load `extension/` as an unpacked extension in a Chromium browser with developer mode enabled, then open its toolbar popup. Select Nostr, Wallet, Inscribe, or Chain to see the planned responsibilities. No build or dependencies are required. Browser compatibility beyond this initial Chromium target remains to be validated.
|
||||
|
||||
## Boundaries
|
||||
|
||||
- `extension/`: installable shell; only this directory is packaged.
|
||||
- `upstream/`: original source trees and licenses, imported without squashing history; not executable extension dependencies.
|
||||
- `docs/architecture.md`: intended architecture, trust boundaries, and remaining implementation work.
|
||||
- `SOURCES.md`: upstream attribution, pinned commits, import evidence, and repeatable update/import instructions.
|
||||
|
||||
Supertestnet and the upstream contributors authored the imported projects. Coinos is a design reference only. See [SOURCES.md](SOURCES.md) for attribution and license status; there is no blanket relicensing of upstream or bundled third-party material.
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
# Sources and provenance
|
||||
|
||||
## Verification on 2026-10-04
|
||||
|
||||
`origin` is `https://teahub.xyz/matcha/inscriboor.git`. Live `git ls-remote origin refs/heads/main` returned `7298f2f9c569961c318ffc74f88ce0ecc8eaa4e4`, matching the starting worktree HEAD. Changes here are local; nothing was pushed or deployed and no issues were created.
|
||||
|
||||
## Imported sources
|
||||
|
||||
Credit: **Supertestnet and each repository's contributors**. Each source below is an unsquashed subtree under `upstream/<name>`, including its original README, LICENSE, assets, and full reachable history. Original commit authorship is preserved; integration commits use the Codex identity. These are source imports, not functioning extension integrations. Tree-object equality and upstream-tip ancestry were verified for all four imports.
|
||||
|
||||
| Source | Original upstream tip | Local import commit | License at tip |
|
||||
| --- | --- | --- | --- |
|
||||
| [vanilla-js-browser-wallet](https://github.com/supertestnet/vanilla-js-browser-wallet) | `19ae5097f4645bf5b1103a39abc04155a8b072fc` | `4f5f7dfcacc4646be48fcc0d78807ed800fbbf8e` | CC0 1.0; original `LICENSE` retained |
|
||||
| [inscriptions-online](https://github.com/supertestnet/inscriptions-online) | `470b8bdf29ead319cff9dc119a005cbf58ee598c` | `70419cffc2ccf33c75a91403f7acc1eedfc27235` | CC0 1.0; original `LICENSE` retained |
|
||||
| [testnet_generator](https://github.com/supertestnet/testnet_generator) | `498be4cc775ef18e7ff17357d007918518f47b98` | `60d02f9669d6b6b55bf75dfb7b1bb12ff30f10f9` | CC0 1.0; original `LICENSE` retained |
|
||||
| [nwcjs](https://github.com/supertestnet/nwcjs) | `ab2ba5d780c1f753016da3ed64a9eca00a5afcca` | `8f169789ef5ae8e0af80ecf03f707b8a85b06e12` | CC0 1.0; original `LICENSE` retained |
|
||||
|
||||
Repository-level CC0 files do not replace bundled third-party notices. In particular, inscriptions-online includes libraries, fonts, images, and template assets that still require an asset/dependency license audit before packaging. Nothing under `upstream/` is packaged in the extension shell.
|
||||
|
||||
## References not imported
|
||||
|
||||
- [supertestnet/vanilla-js-nostr](https://github.com/supertestnet/vanilla-js-nostr): pinned candidate `8107d822beb5d74bf8bc85878f40ace2f279f3ec`. Its complete Git history was fetched to a temporary bare checkout for inspection, but **no source or history was imported into this repository**. The tip has no LICENSE file; its README invites code reuse without a formal license declaration. Clarify permission/license before importing or adapting it. Intended role: Nostr feed and event adapter.
|
||||
- [coinos/coinosv3](https://github.com/coinos/coinosv3): **Coinos and contributors**, browser-wallet design reference only. No source/history imported, no commit pinned, and no license claim made. Any future reuse requires pinning and license review.
|
||||
|
||||
Intended roles of imported sources: vanilla-js-browser-wallet → Wallet/BTC adapter; inscriptions-online → Inscribe preparation; testnet_generator → Chain experiments; nwcjs → optional Nostr Wallet Connect adapter. These roles are inscriboor's proposed integration boundaries, not upstream endorsements.
|
||||
|
||||
## Repeatable history-preserving imports
|
||||
|
||||
Use unsquashed `git subtree` imports into separate prefixes. This keeps original commits reachable from ordinary clones and avoids extra submodule checkout steps. Never use archive downloads, copy/paste, shallow history, or `--squash` as a substitute. Keep imported trees unchanged initially; implement reviewed extension adapters separately under `packages/`. Temporary clone paths used during this task are not runtime dependencies.
|
||||
|
||||
For a new import, start from a clean committed worktree with Git author/committer identity configured. The following is the exact deferred Nostr import sequence **after license clarification**; if permission requires a later licensed commit, replace the pinned SHA with that reviewed commit and update this ledger:
|
||||
|
||||
```sh
|
||||
git remote add supertestnet-nostr https://github.com/supertestnet/vanilla-js-nostr.git
|
||||
git fetch supertestnet-nostr
|
||||
nostr_tip=8107d822beb5d74bf8bc85878f40ace2f279f3ec
|
||||
git cat-file -e "$nostr_tip^{commit}"
|
||||
git subtree add --prefix=upstream/vanilla-js-nostr "$nostr_tip" \
|
||||
-m "Import supertestnet/vanilla-js-nostr with full upstream history"
|
||||
git merge-base --is-ancestor "$nostr_tip" HEAD
|
||||
test "$(git rev-parse HEAD:upstream/vanilla-js-nostr)" = "$(git rev-parse "$nostr_tip^{tree}")"
|
||||
```
|
||||
|
||||
If a named remote already exists, inspect its URL rather than replacing it blindly. Fetching without a depth limit preserves full reachable history. Preserve licensing clarification alongside the import.
|
||||
|
||||
To update an existing subtree (example: nwcjs):
|
||||
|
||||
```sh
|
||||
git remote add supertestnet-nwcjs https://github.com/supertestnet/nwcjs.git
|
||||
git fetch supertestnet-nwcjs
|
||||
# Inspect upstream changes and licenses; set reviewed_tip to the full reviewed SHA.
|
||||
: "${reviewed_tip:?Set the reviewed upstream commit SHA}"
|
||||
git cat-file -e "$reviewed_tip^{commit}"
|
||||
git subtree merge --prefix=upstream/nwcjs "$reviewed_tip" \
|
||||
-m "Update supertestnet/nwcjs preserving history"
|
||||
git merge-base --is-ancestor "$reviewed_tip" HEAD
|
||||
```
|
||||
|
||||
Record the new tip/import commit, license changes, and validation here. For untouched subtrees, compare tree IDs as above. For future local upstream patches, review diffs explicitly and preserve attribution. Do not flatten demo code into the extension to bypass these boundaries.
|
||||
|
||||
## Remaining work
|
||||
|
||||
Resolve vanilla-js-nostr licensing/import; audit bundled dependencies/assets; specify derivation paths and recovery format; implement and test shared vault/signing/storage and feature adapters; implement bounded site/agent capabilities; validate browser loading and security behavior. The shell contains no crypto and has not been exercised in a real extension browser session.
|
||||
@@ -0,0 +1,36 @@
|
||||
# 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](../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.
|
||||
@@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
const descriptions = {
|
||||
Nostr: 'Identities, events, and relays.',
|
||||
Wallet: 'BTC accounts, balances, and transaction review.',
|
||||
Inscribe: 'Content and inscription transaction preparation.',
|
||||
Chain: 'Chain inspection and isolated test-network experiments.'
|
||||
};
|
||||
const buttons = document.querySelectorAll('[data-feature]');
|
||||
for (const button of buttons) {
|
||||
button.addEventListener('click', () => {
|
||||
const feature = button.dataset.feature;
|
||||
document.querySelector('#feature').textContent = feature;
|
||||
document.querySelector('#description').textContent = descriptions[feature];
|
||||
for (const candidate of buttons) {
|
||||
candidate.setAttribute('aria-pressed', String(candidate === button));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Inscriboor</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="app.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Inscriboor</h1>
|
||||
<p>Bitcoin and Nostr, in one extension.</p>
|
||||
<nav aria-label="Features">
|
||||
<button type="button" aria-pressed="true" data-feature="Nostr">Nostr</button>
|
||||
<button type="button" aria-pressed="false" data-feature="Wallet">Wallet</button>
|
||||
<button type="button" aria-pressed="false" data-feature="Inscribe">Inscribe</button>
|
||||
<button type="button" aria-pressed="false" data-feature="Chain">Chain</button>
|
||||
</nav>
|
||||
<main aria-live="polite">
|
||||
<h2 id="feature">Nostr</h2>
|
||||
<p id="description">Identities, events, and relays.</p>
|
||||
</main>
|
||||
<p class="status">Shell preview. Key storage and signing are not implemented.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Inscriboor",
|
||||
"version": "0.1.0",
|
||||
"description": "Browser-first Bitcoin and Nostr extension shell.",
|
||||
"action": { "default_popup": "index.html" },
|
||||
"content_security_policy": { "extension_pages": "script-src 'self'; object-src 'none'" }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
:root { color-scheme: light dark; font-family: system-ui, sans-serif; }
|
||||
body { width: 360px; margin: 0; padding: 20px; box-sizing: border-box; }
|
||||
h1 { margin-top: 0; }
|
||||
nav { display: flex; gap: 6px; }
|
||||
button { padding: 8px; cursor: pointer; border: 1px solid GrayText; border-radius: 4px; }
|
||||
button[aria-pressed="true"] { border-color: Highlight; outline: 2px solid Highlight; }
|
||||
button:focus-visible { outline: 2px dashed Highlight; outline-offset: 3px; }
|
||||
main { min-height: 105px; }
|
||||
.status { font-size: 0.85rem; color: GrayText; }
|
||||
Reference in new issue
Block a user