Add CBOR metadata indexes, local API and coordinated auto mining

This commit is contained in:
Codex committed 2026-10-05 02:33:54 +00:00
1 parent 0405452ab2
commit aa39db3879
14 files changed
+599 -54

No files matched your search

+39 -7
View File
@@ -1,6 +1,6 @@
# Super Testnet v0
A small browser-native Bitcoin playground: create a **test-only** wallet, mine fake BTC, sign a MIME inscription, see it in that wallet’s collectibles, and follow its transactions into a local block.
A small browser-local Bitcoin protocol lab: create a **test-only** wallet, mine fake BTC, sign a MIME inscription, see it in that wallet’s collectibles, and follow its transactions into a local block.
This is a private, single-browser simulation inspired by Supertestnet. It uses real Bitcoin transaction serialization, Schnorr signatures and Taproot commit/reveal envelopes. It is **not Bitcoin Core, public testnet, signet, regtest consensus, an Ord indexer, or production custody**. There is no mainnet mode and no external broadcast path.
@@ -27,9 +27,9 @@ Use localhost or HTTPS: secure-context Web Crypto and Web Locks are required. Ch
## Complete the loop
1. **Create test wallet**, or load a previously saved Super Testnet wallet JSON. Wallet creation never signs a transaction.
2. **Mine a block**: receive 50 fake BTC immediately, without coinbase maturity.
3. Choose text/plain, application/json, text/html, image/svg+xml, image/png, image/jpeg or image/webp. Edit text or upload a local file of up to **16,384 bytes (16 KiB)**. No remote fetching. Optionally select an owned inscription as its immutable parent. **Review inscription** shows the payload and costs without signing.
4. **Sign & inscribe** explicitly signs a commit and a reveal locally. Fees total 1,000 fake sats; 1,000 fake sats remain in the inscription output. Both transactions enter the local mempool atomically. A child reveal also signs the parent input and returns its full value to the same wallet. After successful persistence the content, file, parent, review and byte counter reset; failures preserve the composer.
2. **Mine now**: receive 50 fake BTC immediately, without coinbase maturity.
3. Choose text/plain, application/json, text/html, image/svg+xml, image/png, image/jpeg or image/webp. Edit text or upload a local file of up to **16,384 bytes (16 KiB)**. No remote fetching. Optionally select an owned inscription as its immutable parent. Add arbitrary JSON metadata independently of the body: it becomes real CBOR in repeated ord tag-5 fields, each at most 520 bytes. The app caps metadata at **2,048 CBOR bytes** (64 nesting levels); invalid JSON, non-finite numbers and oversized documents are rejected before signing. Blank metadata is omitted; JSON `null` is a present metadata value. **Review inscription** shows the payload and costs without signing.
4. **Sign & inscribe** explicitly signs a commit and a reveal locally. Fees total 1,000 fake sats; 1,000 fake sats remain in the inscription output. Both transactions enter the local mempool atomically. A child reveal also signs the parent input and returns its full value to the same wallet. After successful persistence the content, file, parent, metadata, review and byte counters reset; failures preserve the composer.
5. The inscription immediately appears as **pending** in this wallet’s collectibles. Mine again to confirm both transactions in one block.
6. Open the inscription, its reveal, its commit, or its block in the integrated explorer. Raw transaction hex and witnesses are visible. Reload to verify persistence.
@@ -37,11 +37,43 @@ Wallet ownership is derived from the unspent reveal output’s script, not a dis
**Save test wallet** exports its tagged test key, not chain history. **Save complete lab** exports both wallet and chain, including pending transactions, and is the portable recovery option. Loading a complete lab replaces local state after an explicit prompt. Clearing site data/resetting the lab destroys local state unless you have a backup. Explorer hash links work only with the matching local chain; they are not public explorer links. A different origin (including localhost vs Fly) has separate browser storage; use a complete lab backup to move it.
## Metadata, local indexes and API
Collectible cards and details show metadata decoded from inscription witnesses. **Metadata is data; indexers are interpretation.** `MetadataIndex` reconstructs every inscription event from confirmed block raw transactions in chain order, followed by raw mempool transactions. Events include id, content type, status, height/block hash, metadata, presence flag and parent. No UI metadata sidecar is persisted. A top-level string `metadata.protocol` is the default discovery convention; other fields and values have no built-in semantics. The Indexes surface shows counts, discovered names and the ordered feed for a selected protocol.
The optional `event-counter` reducer derives counts and ordered ids from only the selected protocol's events, displayed separately. Reducers are trusted application code registered above the base index, never downloaded or executed from inscriptions. Adding a reducer requires a source-code change; this is a seam for future metaprotocol experiments, not a sidechain consensus engine. Native ord tag 7 is a separate future compatibility feature and is not conflated with `metadata.protocol`.
The **LOCAL / IN-BROWSER** API explorer calls `LocalOrdAPI.request(path)` and displays/copies its `{status, contentType, body}` response. No HTTP request is made. Fly/the static server cannot read browser state. Available paths:
- `/content/:id`: original MIME and exact `Uint8Array` body. The explorer renders bytes plus an escaped text preview, never executes content.
- `/r/inscription/:id`: decoded event, including JSON metadata and presence flag.
- `/r/metadata/:id`: JSON string of CBOR hex, or `null` when absent.
- `/r/parents/:id`, `/r/children/:id`: `{ids}` for immediate lineage (all local results, no pagination).
- `/r/tx/:txid`: `{txid, hex, height}`; `/r/blockheight`: local height.
- `/r/blockhash/:height`, `/r/blockinfo/:height-or-hash`: local hash or synthetic block info with ordered transaction ids (timestamps in milliseconds).
- `/local/metadata-index`: stats and ordered events; `/local/protocols`: names and counts; `/local/protocol?name=...`: matching ordered events. URL-encode protocol names.
Unknown paths/resources return 404; non-local paths return 400. This deliberately partial ord-like API is not wire-compatible with all ord schemas. Metadata encoding follows the [ord metadata convention](https://docs.ordinals.com/inscriptions/metadata.html); path naming and CBOR-hex metadata responses follow the [ord endpoint reference](https://docs.ordinals.com/inscriptions/recursion.html). This API boundary prepares for later recursion; previews do not resolve recursive resources today.
## Mining at your pace
The miner defaults **OFF**, with 10s / 30s / 60s choices and **Mine now**. Preference and next deadline persist in lab state/backups; old backups default OFF. Auto and manual mining use the same Web Locks → read latest lab → mutate → atomic save path. Auto mining rechecks the persisted deadline inside the lock, so tabs sharing the origin cannot mine the same scheduled block. Manual mining resets the next deadline. Each block clears pending commit/reveal packages naturally.
A tab must stay open; background throttling/suspension can delay mining. Reopening an overdue lab mines at most one block, then starts a fresh interval, without a catch-up burst. Auto mining signs nothing. A failed save publishes no partial state and the UI reports the error.
## Planned backend progression
**Local lab → regtest (Super Regtest) → signet/testnet → mainnet** is a future selector progression, not a list of implemented modes. Chain, wallet/signing, raw metadata index, trusted reducer and API adapters stay separate. A later network adapter must explicitly supply chain data and wallet capabilities; a hosted server cannot implicitly access browser storage. Regtest is not implemented. Public networks and mainnet need separate security and signing designs; this v0 has no production keys/funds, external broadcast or hidden signing.
Recursion, reinscriptions, delegates, pointers/sat tracking and native tag-7 compatibility remain future passes. Metadata supports the JSON data model encoded in CBOR, not every CBOR feature (no byte strings, tags, indefinite collections or arbitrary map keys). The narrow local envelope validator accepts the app's encoding, not arbitrary external ord transactions.
## Architecture
- `src/adapters/wallet.js`: test-wallet creation/loading, regtest-format `bcrt1p` address and explicit signing primitive. Only tagged v0 test backups can be imported; there is no arbitrary production-key input.
- `src/adapters/chain.js`: instant 50-BTC coinbase, UTXO set, package validation, mempool, synthetic blocks and replayable snapshots. Validates transaction shape, values, spent inputs, default Schnorr signatures and the supported Taproot script/control block. Exposes `mine`, `submitPackage`, `coins`, `balance`, `snapshot`.
- `src/adapters/inscription.js`: MIME/byte envelope with optional tag 3, commit/reveal construction, confirmation/ownership view. `prepare` does not sign; `inscribe` is invoked only after the user’s explicit signing action.
- `src/adapters/inscription.js`: MIME/byte envelope with optional parent tag 3 and chunked CBOR metadata tag 5, commit/reveal construction, confirmation/ownership view. `prepare` does not sign; `inscribe` is invoked only after the user’s explicit signing action.
- `src/adapters/metadata.js`, `metadata-index.js`, `local-ord-api.js`: bounded JSON/CBOR codec, byte-derived raw index and trusted reducer boundary, in-process read API.
- `src/miner.js`: persisted schedule and deadline checks, invoked through `mutateLab` in storage for both mining modes.
- `src/upstream/primitives.js`: small attributed adaptations of Supertestnet’s input/output helpers. See [provenance](PROVENANCE.md).
- `LocalRPC`: in-process read facade for `getblockcount`, `getblockhash`, `getblock`, `getrawtransaction`. It is deliberately partial, not wire-compatible bitcoind JSON-RPC. A future Core or node_faker adapter can replace this boundary.
- `src/storage.js`: versioned `localStorage` snapshot; index/UTXO reconstruction with transaction validation on load. One atomic storage write per operation; failed validation/quota writes do not publish partial in-memory state. Web Locks serialize mutations across tabs; storage events refresh other tabs.
@@ -60,7 +92,7 @@ Wallet ownership is derived from the unspent reveal output’s script, not a dis
## Verification
Verified for this extension: `npm test` passed all 13 adapter tests, `npm run build` passed, and Playwright passed all 14 desktop/mobile tests against the production server. The minimal worker required Chromium, runtime libraries and fonts staged under `/tmp`; no system packages or deployment were changed. Run:
Verified for this pass: **19 adapter tests passed** (`npm test`), **22 desktop/mobile browser tests passed** (`npm run test:e2e`), and `npm run build` passed. Chromium, missing runtime libraries and fonts were staged under `/tmp`; no system packages or deployment were changed. Run:
```sh
npm test
@@ -70,7 +102,7 @@ npm run test:e2e
The adapter suite covers ownership, real signed commit/reveal construction, confirmation, RPC inspection, pending/confirmed restoration, malformed imports, MIME/byte round-trips and size limits, parent ownership/preservation, fraudulent tags, untagged parent spends, nested lineage, bad signatures, modified payload/control blocks, over-spending, atomic rollback, double-spending and collectible protection.
Playwright tests the **production build/server**, at desktop and Pixel 7 mobile sizes: full loop, review-before-signing, pending persistence, transaction/block navigation, complete backup/reset/restore, wallet imports, invalid input, two-tab concurrent mining, composer reset and failure preservation, non-text uploads, parent navigation, sandbox preview safety, no third-party requests and no horizontal overflow. Screenshots/traces are written to ignored `test-results/`.
Playwright tests the **production build/server**, at desktop and Pixel 7 mobile sizes: full loop, review-before-signing, pending persistence, transaction/block navigation, complete backup/reset/restore, wallet imports, invalid input, two-tab concurrent mining, composer reset and failure preservation, non-text uploads, parent navigation, sandbox preview safety, no third-party requests and no horizontal overflow. Additional tests cover CBOR vectors/chunking/caps, sidecar-independent metadata indexing, protocol grouping/reducer ordering, local API reads, miner persistence/countdown/manual reset and two-tab deadline races. Screenshots/traces are written to ignored `test-results/`.
## Independent Fly deployment