diff --git a/ORGCHAIN.md b/ORGCHAIN.md new file mode 100644 index 0000000..82ae6e6 --- /dev/null +++ b/ORGCHAIN.md @@ -0,0 +1,13 @@ +# Orgchain (branch `orgchain`) + +Super Testnet restyled for lineage, served at https://lineage.yolopreneur.lol/orgchain/. + +- Same lab and code as `main`. The differences are a skin and copy: `src/lineage.css` (loads after `style.css` and + points its tokens at lineage's), a rehearsal guide and lineage branding in `index.html`, the lineage favicon, + relative paths (`vite.config.js` `base: './'`, the recursive preview, license links), the theme following the system + setting under its own storage key, and Inscriboor downloads linking to supertestnet.lol (the extension only connects + there, so the local test wallet is the path here). +- Build: `npm ci && npm run build`, then copy `dist/` to `ventures/lineage/orgchain/` on `teahubxyz/time` `gh-pages`. + Headers (CSP and the rest, matching supertestnet.lol's) come from `ventures/lineage/_headers`, scoped to + `/orgchain/*`. +- Keep in step with `main`: rebase this branch onto `main`, rebuild, recopy. diff --git a/index.html b/index.html index ec33067..3805585 100644 --- a/index.html +++ b/index.html @@ -2,28 +2,38 @@ - - - Super Testnet — your own little Bitcoin universe - + + + Orgchain — rehearse an org on a small chain · Lineage + -
- SUPER TESTNET v0 -
PRIVATE LOCAL CHAIN
+
+
+
+

Orgchain

+

Rehearse an org on a small chain. Mint a root, give birth to children, award a badge, all as inscriptions on a private toy Bitcoin chain in this tab, with pretend money.

+
+
+ Test coins + Private chain + Lineage ↗ + +
+
-

BITCOIN, WITH ROOM TO EXPERIMENT

Your own little
Bitcoin universe.

Mine a block. Inscribe a thought. See it land in your wallet.
All in your browser, all with pretend money.

- +

Rehearsal a lineage in four moves

  1. Root. Fund a wallet, then inscribe the org with metaprotocol lineage/v0 and metadata like {"lineage":"root","name":"yolopreneur"}.
  2. Birth. Inscribe a child with the root as its parent. Only the parent's holder can: the parent is spent to make the child, and the child carries the parent's ID on-chain (ord tag 3).
  3. Generations. Children can be parents too: time under the root, docscope under time, as deep as the tree goes.
  4. Badge. Inscribe a badge once, like {"lineage":"badge","skill":"launch","belt":"green"}, then mint each award as a child of it with the badge as delegate, so every award shows the same mark.

Not in this lab yet: handing an award to a seat, graduation (moving a venture's inscription to its own new root) and closing (burning a parent so no more children can be born). Those need transfers and burns, which this lab doesn't do.

+
Choose Inscriboor or a local test wallet to start your first loop.
01

Your test wallet

NOT CREATED
-

One wallet. A whole chain to play with.

Looking for the extension…

Install Inscriboor
  1. Download and unzip Inscriboor.
  2. Open chrome://extensions (or Brave extensions).
  3. Turn on Developer mode.
  4. Choose Load unpacked and select the unzipped extension folder.
  5. Refresh this page. The button above will change from Get Inscriboor to Connect Inscriboor.
+

One wallet. A whole chain to play with.

Looking for the extension…

Install Inscriboor

Inscriboor 0.2.4 connects on supertestnet.lol only. On Orgchain, use the local test wallet.

  1. Download and unzip Inscriboor.
  2. Open chrome://extensions (or Brave extensions).
  3. Turn on Developer mode.
  4. Choose Load unpacked and select the unzipped extension folder.
  5. Refresh this page. The button above will change from Get Inscriboor to Connect Inscriboor.
02

Make some blocks

Skip the faucet queue. Every block gives you 50 fake BTC, ready to use immediately.

BLOCK HEIGHT0
PENDING TXS0

Auto mining OFF

Keep a lab tab open; browser throttling may delay blocks. Mining also confirms your pending inscriptions.

-
03

Leave a little something

INSCRIPTION LAB

Recursive HTML/SVG scripts use local fetch and ord.render(text) in an isolated worker; ord.id is the requested inscription. No DOM or network access.

0 / 2048 CBOR bytes · ord tag 5 · JSON is authoring format only

Native ord metaprotocol identifier. Metadata and inscription data remain independent.

+
03

Inscribe a root, a birth, a badge

INSCRIPTION LAB

Recursive HTML/SVG scripts use local fetch and ord.render(text) in an isolated worker; ord.id is the requested inscription. No DOM or network access.

0 / 2048 CBOR bytes · ord tag 5 · JSON is authoring format only

Native ord metaprotocol identifier. Metadata and inscription data remain independent.

@@ -53,7 +63,7 @@
Choose a path and press Try.
-
Under the hood & attribution

Real serialized Bitcoin transactions, Schnorr signatures and Taproot commit/reveal scripts, on a deliberately simplified local UTXO chain. No proof of work, Bitcoin consensus, peer network, public broadcast, or production custody. Synthetic local sats follow FIFO input-to-output ranges. Child creation and reinscription preserve the owned sat. Fees retire the input tail; this is not Bitcoin consensus.

Built from and inspired by Supertestnet’s testnet_generator, inscriptions-online, and vanilla-js-browser-wallet. node_faker was evaluated for future RPC compatibility.

Transaction library: tapscript by Christopher Scott (CC-BY-1.0). Supertestnet CC0 license · noble-curves license · noble-hashes license.

-
SMALL CHAIN. BIG POSSIBILITIES.
+
Under the hood & attribution

Orgchain is Super Testnet in lineage's clothes: the same lab and code, restyled, with a rehearsal guide on top. Its lab state lives in this browser, separate from supertestnet.lol's.

Real serialized Bitcoin transactions, Schnorr signatures and Taproot commit/reveal scripts, on a deliberately simplified local UTXO chain. No proof of work, Bitcoin consensus, peer network, public broadcast, or production custody. Synthetic local sats follow FIFO input-to-output ranges. Child creation and reinscription preserve the owned sat. Fees retire the input tail; this is not Bitcoin consensus.

Built from and inspired by Supertestnet’s testnet_generator, inscriptions-online, and vanilla-js-browser-wallet. node_faker was evaluated for future RPC compatibility.

Transaction library: tapscript by Christopher Scott (CC-BY-1.0). Supertestnet CC0 license · noble-curves license · noble-hashes license.

+
\ No newline at end of file diff --git a/public/downloads/inscriboor-extension-v0.2.1.zip b/public/downloads/inscriboor-extension-v0.2.1.zip deleted file mode 100644 index d091e26..0000000 Binary files a/public/downloads/inscriboor-extension-v0.2.1.zip and /dev/null differ diff --git a/public/downloads/inscriboor-extension-v0.2.2.zip b/public/downloads/inscriboor-extension-v0.2.2.zip deleted file mode 100644 index 6c20534..0000000 Binary files a/public/downloads/inscriboor-extension-v0.2.2.zip and /dev/null differ diff --git a/public/downloads/inscriboor-extension-v0.2.3.zip b/public/downloads/inscriboor-extension-v0.2.3.zip deleted file mode 100644 index 19d492e..0000000 Binary files a/public/downloads/inscriboor-extension-v0.2.3.zip and /dev/null differ diff --git a/public/downloads/inscriboor-extension-v0.2.4.zip b/public/downloads/inscriboor-extension-v0.2.4.zip deleted file mode 100644 index b1c63b0..0000000 Binary files a/public/downloads/inscriboor-extension-v0.2.4.zip and /dev/null differ diff --git a/public/downloads/inscriboor-extension-v0.2.zip b/public/downloads/inscriboor-extension-v0.2.zip deleted file mode 100644 index 0d45933..0000000 Binary files a/public/downloads/inscriboor-extension-v0.2.zip and /dev/null differ diff --git a/public/downloads/inscriboor-version.json b/public/downloads/inscriboor-version.json deleted file mode 100644 index be3a56d..0000000 --- a/public/downloads/inscriboor-version.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"0.2.4","url":"https://supertestnet.lol/downloads/inscriboor-extension-v0.2.4.zip"}n \ No newline at end of file diff --git a/public/favicon.svg b/public/favicon.svg index 0543594..8485fa4 100644 --- a/public/favicon.svg +++ b/public/favicon.svg @@ -1 +1 @@ - + diff --git a/public/recursive-preview.html b/public/recursive-preview.html index 7f78e6a..fd2503b 100644 --- a/public/recursive-preview.html +++ b/public/recursive-preview.html @@ -1 +1 @@ -

+

diff --git a/src/lineage.css b/src/lineage.css
new file mode 100644
index 0000000..3f170c9
--- /dev/null
+++ b/src/lineage.css
@@ -0,0 +1,153 @@
+/* Orgchain: Super Testnet in lineage's clothes.
+   Same lab, dressed as lineage's key-ceremony sheet: raw concrete, black rule, hazard yellow for the action and for
+   anything live, everything in the system monospace. Restyle only: loads after style.css and repoints its tokens. */
+:root {
+  --concrete: #e4e3dd; --slab: #f6f5f1; --ink: #141414; --ink-2: #4a4944; --ink-3: #66655f;
+  --signal: #ffc21a; --on-signal: #141414; --ok: #1d7a3a; --focus: #2346ff;
+  --band: #141414; --band-fg: #f6f5f1; --band-muted: #b0afa8; --shadow: #141414;
+  --mono: ui-monospace, "SF Mono", "Cascadia Mono", "JetBrains Mono", Menlo, Consolas, "Liberation Mono", "DejaVu Sans Mono", monospace;
+  --display: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+  --t-xs: 0.75rem; --t-s: 0.8125rem; --t-m: 0.9375rem; --t-l: 1.25rem;
+}
+:root[data-theme="dark"] {
+  --concrete: #151514; --slab: #1e1e1c; --ink: #ecebe4; --ink-2: #b9b8b0; --ink-3: #94938b;
+  --ok: #62c784; --focus: #93a8ff; --band: #0b0b0a; --band-fg: #ecebe4; --band-muted: #9d9c95; --shadow: #4d4c47;
+}
+/* Super Testnet's own tokens, pointed at lineage's in both themes (style.css sets light values on [data-theme]) */
+:root, :root[data-theme="light"], :root[data-theme="dark"] {
+  --orange: var(--signal); --orange-2: var(--signal);
+  --bg: var(--concrete); --panel: var(--slab); --panel-2: var(--concrete); --soft: var(--concrete);
+  --text: var(--ink); --muted: var(--ink-2); --line: var(--ink);
+  font-family: var(--mono);
+}
+:root, :root[data-theme="light"] { --danger: #b3261e; }
+:root[data-theme="dark"] { --danger: #ff8a7f; }
+
+* { border-radius: 0 !important; }
+html, body { background: var(--concrete); }
+body { font: 400 var(--t-m)/1.5 var(--mono); color: var(--ink); transition: none; }
+::selection { background: var(--signal); color: var(--on-signal); }
+a { color: var(--ink); text-decoration-thickness: 2px; text-underline-offset: 3px; }
+a:hover { background: var(--signal); color: var(--on-signal); }
+code { font-family: inherit; font-weight: 700; }
+button:focus-visible, a:focus-visible, summary:focus-visible, .file-button:focus-visible,
+input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
+
+/* header slab, as on lineage's key tree */
+header.band { max-width: none; margin: 0; padding: 0; display: block; border-bottom: 3px solid var(--ink); background: var(--band); color: var(--band-fg); }
+.band-in {
+  max-width: 1240px; margin: 0 auto; padding-block: 22px 20px;
+  padding-left: max(16px, env(safe-area-inset-left, 0px)); padding-right: max(16px, env(safe-area-inset-right, 0px));
+  display: flex; flex-wrap: wrap; gap: 16px 32px; align-items: flex-end; justify-content: space-between;
+}
+.wordmark { margin: 0; color: var(--band-fg); font: 900 clamp(3.25rem, 11vw, 7rem)/0.82 var(--display); letter-spacing: -0.05em; text-transform: uppercase; }
+.lede { margin: 12px 0 0; color: var(--band-muted); font-size: var(--t-s); max-width: 58ch; }
+.lede b { color: var(--band-fg); }
+.flags { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
+.flag, button.flag {
+  font: 700 var(--t-xs)/1 var(--mono); letter-spacing: 0.1em; text-transform: uppercase; padding: 7px 9px 6px;
+  border: 2px solid var(--band-fg); background: transparent; color: var(--band-fg); box-shadow: none; text-decoration: none;
+}
+.flag.hz { background: var(--signal); border-color: var(--signal); color: var(--on-signal); }
+a.flag:hover, button.flag:hover:not(:disabled) { background: var(--band-fg); color: var(--band); border-color: var(--band-fg); transform: none; }
+button.flag:active:not(:disabled) { transform: none; }
+
+/* blocks with ink tabs */
+.blk { display: flex; flex-direction: column; align-items: flex-start; min-width: 0; }
+.blk > .panel { align-self: stretch; }
+.tab {
+  margin: 0; background: var(--ink); color: var(--slab); font: 700 var(--t-xs)/1 var(--mono);
+  letter-spacing: 0.14em; text-transform: uppercase; padding: 8px 11px 7px; display: flex; gap: 12px; max-width: 100%;
+}
+.tab .sub { font-weight: 400; letter-spacing: 0.06em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
+.rehearse { margin: 40px 0 0; }
+.moves { margin: 0; padding: 0 0 0 1.6em; display: grid; gap: 10px; font-size: var(--t-s); line-height: 1.6; max-width: 96ch; }
+.moves li::marker { font-weight: 700; }
+.moves b, .panel .later b { color: var(--ink); }
+.panel .later { margin: 16px 0 0; padding: 10px 12px; border: 2px dashed var(--ink); font-size: var(--t-s); color: var(--ink-2); max-width: 96ch; }
+
+.notice { margin-top: 28px; background: transparent; border: 2px dashed var(--ink); padding: 10px 12px; font-size: var(--t-s); color: var(--ink-2); }
+.notice strong { color: var(--ink); }
+#status { color: var(--ink); font: 700 var(--t-s)/1.5 var(--mono); padding: 16px 0; }
+#status::before { content: "\25B8  "; }
+#status.error { color: var(--danger); }
+
+/* panels: slabs with a hard ink shadow */
+.panel { background: var(--slab); border: 3px solid var(--ink); box-shadow: 8px 8px 0 var(--shadow); padding: 22px; }
+.workspace { gap: 28px; }
+.panel-title { gap: 12px; margin-bottom: 18px; flex-wrap: wrap; }
+.panel-title h2, #indexes > h2, #api-explorer > h2 { font: 700 var(--t-m)/1.3 var(--mono); letter-spacing: 0.04em; text-transform: uppercase; margin: 0; }
+.step { background: var(--ink); color: var(--slab); border: 0; padding: 7px 9px 6px; font: 700 var(--t-xs)/1 var(--mono); letter-spacing: 0.1em; }
+.tag { border: 2px solid var(--ink); color: var(--ink); font: 700 0.6875rem/1 var(--mono); letter-spacing: 0.1em; text-transform: uppercase; padding: 5px 7px 4px; }
+.panel p { font-size: var(--t-s); color: var(--ink-2); }
+.label, .chain-kicker { font: 700 var(--t-xs)/1.2 var(--mono) !important; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-2); }
+h3 { font: 700 var(--t-m)/1.3 var(--mono); text-transform: uppercase; letter-spacing: 0.04em; }
+
+/* form */
+label { font: 700 var(--t-xs)/1.3 var(--mono); letter-spacing: 0.06em; color: var(--ink-2); margin: 16px 0 6px; }
+input, textarea, select { background: var(--concrete); border: 2px solid var(--ink); color: var(--ink); font: 400 var(--t-s)/1.4 var(--mono); padding: 9px 10px; }
+input:focus, textarea:focus, select:focus { border-color: var(--ink); outline: 3px solid var(--focus); outline-offset: 2px; }
+input[type=file] { border-style: dashed; background: transparent; }
+.file-button { color: var(--ink); font-weight: 700; text-decoration-thickness: 2px; }
+.wallet-footer { border-top: 2px dashed var(--ink-3); }
+.install-help summary { cursor: pointer; font-weight: 700; }
+
+/* buttons, as on the key tree */
+button {
+  font: 700 var(--t-s)/1 var(--mono); letter-spacing: 0.06em; text-transform: uppercase; padding: 10px 12px 9px;
+  background: var(--slab); color: var(--ink); border: 2px solid var(--ink); box-shadow: 3px 3px 0 var(--shadow); transition: none;
+}
+button:hover:not(:disabled) { background: var(--concrete); border-color: var(--ink); transform: none; }
+button:active:not(:disabled) { transform: translate(3px, 3px); box-shadow: none; }
+button:disabled { opacity: 0.45; box-shadow: none; }
+button.primary { background: var(--signal); color: var(--on-signal); border-color: var(--ink); }
+button.primary:hover:not(:disabled) { background: var(--signal); filter: brightness(1.05); }
+.quiet { background: transparent; font-size: var(--t-xs); box-shadow: 2px 2px 0 var(--shadow); }
+button.danger, .danger { color: var(--danger); }
+
+/* numbers */
+.balance { font: 700 2.4rem/1 var(--mono); letter-spacing: -0.02em; }
+.balance small { color: var(--ink-2); font: 700 var(--t-xs)/1 var(--mono); letter-spacing: 0.1em; }
+.chain-stats strong { font: 700 2.5rem/1 var(--mono); }
+pre { background: var(--concrete); border: 2px solid var(--ink); font: 400 var(--t-xs)/1.6 var(--mono); }
+
+/* sections */
+.section-title { margin: 52px 0 18px; }
+.eyebrow { display: inline-block; background: var(--ink); color: var(--slab); padding: 8px 11px 7px; font: 700 var(--t-xs)/1 var(--mono); letter-spacing: 0.14em; margin: 0 0 10px; }
+.section-title h2 { font: 900 clamp(1.6rem, 3.4vw, 2.4rem)/1 var(--display); letter-spacing: -0.03em; text-transform: uppercase; }
+#collection-count { background: var(--signal); color: var(--on-signal); font: 700 var(--t-s)/1 var(--mono); padding: 5px 8px 4px; vertical-align: middle; }
+.empty { border: 2px dashed var(--ink); color: var(--ink-2); font-size: var(--t-s); }
+.collectible { background: var(--slab); border: 3px solid var(--ink); box-shadow: 6px 6px 0 var(--shadow); }
+.collectible pre { font: 400 1rem/1.5 var(--mono); border: 0; background: transparent; }
+.inscription-preview { border: 2px solid var(--ink); }
+
+/* chain board: pending is live, so it wears the signal */
+.chain-board { background: var(--slab); border: 3px solid var(--ink); box-shadow: 8px 8px 0 var(--shadow); }
+.chain-kicker { color: var(--ink); }
+.mempool-empty { border: 2px dashed var(--ink); color: var(--ink-2); }
+.mempool-card { background: var(--signal); color: var(--on-signal); border: 2px solid var(--ink); text-transform: none; letter-spacing: 0; }
+.mempool-card strong { color: var(--on-signal); }
+.mempool-card span { color: var(--on-signal); }
+.chain-divider { border-left: 3px solid var(--ink); }
+.chain-divider span { color: var(--ink-2); font: 700 var(--t-xs)/1 var(--mono); letter-spacing: 0.1em; }
+.block-card { background: var(--concrete); border: 2px solid var(--ink); text-transform: none; letter-spacing: 0; font-weight: 400; }
+.block-card:before { border-top: 3px solid var(--ink); opacity: 1; }
+.block-card .block-accent { color: var(--on-signal); background: var(--signal); display: inline-block; padding: 2px 5px; }
+.inspector h2 { font: 700 var(--t-l)/1.25 var(--mono); }
+#protocol-events article { border-bottom: 1px dashed var(--ink-3); }
+#indexes, #api-explorer { margin-top: 2.5rem; }
+
+/* about + footer */
+.about { border-top: 3px solid var(--ink); color: var(--ink-2); font-size: var(--t-s); }
+.about summary { color: var(--ink); font: 700 var(--t-xs)/1.4 var(--mono); letter-spacing: 0.1em; text-transform: uppercase; }
+footer { border-top: 3px solid var(--ink); font: 700 var(--t-xs)/1.4 var(--mono); letter-spacing: 0.12em; color: var(--ink); flex-wrap: wrap; gap: 12px; }
+footer .made { color: var(--ink-2); font-weight: 400; letter-spacing: 0.04em; }
+
+@media (max-width: 700px) {
+  .band-in { padding-block: 18px 16px; }
+  .panel, .chain-board { box-shadow: 5px 5px 0 var(--shadow); padding: 18px; }
+}
+@media (prefers-reduced-motion: reduce) { button:active:not(:disabled) { transform: none; } }
+
+/* long ids and JSON wrap instead of widening the page */
+.moves, .moves code, .collectible, .inspector, #review-panel, #status { overflow-wrap: anywhere; }
diff --git a/src/main.js b/src/main.js
index 8bed3c9..09b2634 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,5 +1,6 @@
 import { RECURSIVE_DEMO } from './recursion.js';
 import './style.css';
+import './lineage.css';
 import { encodeMetadata, parseMetadataJSON } from './adapters/metadata.js';
 import { MetadataIndex, deriveProtocol } from './adapters/metadata-index.js';
 import { LocalOrdAPI } from './adapters/local-ord-api.js';
@@ -14,11 +15,11 @@ import { STORAGE_KEY, readLab, mutateLab, decodeLab, encodeLab } from './storage
 const $ = id => document.getElementById(id);
 const btc = sats => (sats / 1e8).toFixed(8);
 const short = id => `${id.slice(0, 12)}…${id.slice(-8)}`;
-const THEME_KEY = 'super-testnet-theme';
+const THEME_KEY = 'orgchain-theme';
 let fileBytes = null, fileLoading = false, fileRevision = 0;
 let lab, busy = false, reviewed = null, failed = false;
 let inscriboorProvider = null;
-const INSCRIBOOR_RELEASE = { version: '0.2.4', url: '/downloads/inscriboor-extension-v0.2.4.zip' };
+const INSCRIBOOR_RELEASE = { version: '0.2.4', url: 'https://supertestnet.lol/downloads/inscriboor-extension-v0.2.4.zip' };
 
 const message = (text, error = false) => { $('status').textContent = text; $('status').classList.toggle('error', error); };
 const el = (tag, text, className) => { const node = document.createElement(tag); if (text !== undefined) node.textContent = text; if (className) node.className = className; return node; };
@@ -46,7 +47,7 @@ function setTheme(theme, persist = false) {
 }
 function initTheme() {
   const saved = localStorage.getItem(THEME_KEY);
-  setTheme(saved === 'light' || saved === 'dark' ? saved : 'dark');
+  setTheme(saved === 'light' || saved === 'dark' ? saved : (matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'));
 }
 function download(name, contents) {
   const url = URL.createObjectURL(new Blob([contents], { type: 'application/json' }));
diff --git a/src/preview.js b/src/preview.js
index 3653f09..89bf9db 100644
--- a/src/preview.js
+++ b/src/preview.js
@@ -33,7 +33,7 @@ export function preview(item, api = null) {
       node.title = `${type} recursive preview`; node.referrerPolicy = 'no-referrer';
       const payload = recursivePayload(template.innerHTML, scripts, item.id);
       node.onload = () => { node.cleanup?.(); node.cleanup = connectRecursion(node, api, payload); };
-      node.src = '/recursive-preview.html'; node.dataset.previewUrl = ''; node.className = 'inscription-preview';
+      node.src = 'recursive-preview.html'; node.dataset.previewUrl = ''; node.className = 'inscription-preview';
       return node;
     }
     const csp = "default-src 'none'; style-src 'unsafe-inline'; script-src 'none'; form-action 'none'; base-uri 'none'";
diff --git a/vite.config.js b/vite.config.js
new file mode 100644
index 0000000..8e55af1
--- /dev/null
+++ b/vite.config.js
@@ -0,0 +1,4 @@
+import { defineConfig } from 'vite';
+
+// Orgchain is served from lineage.yolopreneur.lol/orgchain/: relative asset URLs work at any sub-path.
+export default defineConfig({ base: './' });