diff --git a/AGENTS.md b/AGENTS.md index d4b3435..8aa548e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,7 +10,7 @@ Orgchain is lineage's app for creating and operating lineage holdings on Super T regtest rehearsal and its comparison (`tools/regtest/README.md`) and refresh the fixture it records. - The engine (`src/adapters`, `src/upstream`, `src/storage.js`, `src/miner.js`) is Super Testnet's. Compose with it rather than rewriting it, and keep its tests passing. Preserve upstream licenses and provenance. Its local - changes are P2WPKH payments, a coinbase split across up to 64 outputs, ordinary spends of up to eight inputs and + changes are P2WPKH payments, a coinbase split across up to 64 outputs, ordinary spends of up to 64 inputs and outputs whose key-path signatures may carry 0x83, coins imported from a real chain, and BIP-341/342 checks of reveals' script paths, all in `src/adapters/chain.js` (PROVENANCE.md); keep them small and tested. - Money lives in `src/orgchain/money.js`: beats pay the holdings (split by hashrate, or all to the last act; under @@ -21,13 +21,18 @@ Orgchain is lineage's app for creating and operating lineage holdings on Super T - Deals live in `src/orgchain/offers.js`, both sides of the PSBT: an offer (the buyer pre-signs the whole transaction and the holder countersigns) and an ask (the holder signs the lot's input alone, SIGHASH_SINGLE|ANYONECANPAY, and any buyer completes it behind a dummy of its own). Offers and asks are signatures kept in the lab, never chain state, and - who holds a lot is read off the chain, never from metadata. An org sells cash-free and is frozen while listed or sold - (`actions.js` cashOut, frozenWhy), and its buyer's keys sign the adoption: never sign for the buyer at the seller's - act. + who holds a lot is read off the chain, never from metadata. An org sells with its tree, and a holding whole, by its + owner (the lab wallet): cash-free, and frozen with everything in it while listed or sold (`actions.js` cashOut, + frozenWhy; a listed holding mines nothing). A tree travels as one output (`bundle` for an ask; an offer merges its + inputs) and splits back by the deal's layout once adopted (`unbundle`): one output per inscription, never two + inscriptions left sharing a coin, or selling one would sell the other. Its buyer's keys sign the adoption and the + split: never sign for the buyer at the seller's act. - Moves (`join`, `adopt`): neither half's effect may depend on their order within a block, since a miner may put them either way; the move records both halves. An old parent keeps a moved child in `children` so its index is never - reused: walk children with `kidsOf`. Inscription metadata is public and permanent, so never put a secret in it (item notes included), and a - charter carries a hash of the filings, never the filings. + reused: walk children with `kidsOf`. A holding that moves becomes an org: its old root stays in `keys.roots` so old + keys still resolve (`money.js` keyAt), and graduation roots are kept by graduation event (`keys.adopted`), since a + node can graduate, move and graduate again. Inscription metadata is public and permanent, so never put a secret in it + (item notes included), and a charter carries a hash of the filings, never the filings. - Charters (`src/orgchain/lineage.js`): legal form is an attribute of a node, and whether a charter stands is derived from the tree (`standing`), never stored, so charters commute with graduations and closes. - Keys follow the tree (`src/orgchain/keys.js`): store roots only (one per holding, one per graduated org) and derive diff --git a/README.md b/README.md index 67faeb7..246f27e 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ chain itself records who did what, and when. - **Found** a holding (a root: the LLC). **Birth** orgs and agents under any org. **Award** a belt (one skill, one seat, in any holding: a registry like well-known certifies agents it doesn't hold). **Decide** (a decision on a node's - record). **Make** an item (an inscription its maker holds, and can sell). **Buy** an item or an org another node - holds, and **Sell** your own (both sides of a deal, below). **Keyring** (a node publishes its keys on each chain, each + record). **Make** an item (an inscription its maker holds, and can sell). **Buy** an item, an org or a whole holding, + and **Sell** your own (both sides of a deal, below). **Keyring** (a node publishes its keys on each chain, each key signing the same statement). **Charter** (a node's legal form, from sole proprietor to series LLC). **Graduate** an org or an agent: its edge flips from derived to adopted, and it becomes a holding of its own, with its own tree, timeline and share of the mining, while its parent's tree keeps a row for it. **Close** a node (derived children close @@ -24,7 +24,7 @@ chain itself records who did what, and when. for the next beat; under *Mainnet* no holding mines, as on mainnet: beats pay the lab wallet, standing in for the world's miners, and **Fund** moves test BTC from it to a holding, the way you'd fund a seed from a wallet you already have. **Send** moves test BTC from any active node to any other, in - its holding or another, signed by the sender's BIP-84 key: at most eight coins in, at most 50 test BTC out, and the + its holding or another, signed by the sender's BIP-84 key: at most 64 coins in, at most 50 test BTC out, and the toy chain's fixed 500-sat fee. Sends land like acts, at once or cued, and *Beat now* mines a beat even when nothing is cued. A graduation moves each re-keyed node's money to its new address along with its inscription. Balances follow the slider, the timeline lists every reward, send and gas top-up, and Inspect has the exact amounts and the @@ -34,24 +34,32 @@ chain itself records who did what, and when. up from its own money 0.0001 test BTC at a time. A node with neither can't act until someone sends it money, and a graduating org pays for the claim on its new root itself. The lab wallet pays only for foundings (a holding owns nothing until it mines) and for holdings that predate lab keys. -- **Deals.** Both sides of OpenOrdex's partially signed transaction, on a lot: an item, or an org inside a holding, - which its parent sells. **Buy** makes an offer, the buy order: the buyer's SegWit key signs the whole deal at once - (SIGHASH_ALL), the lot and its own coins in, the lot to its Taproot key, the price to the seller's SegWit address and - its change out, and nothing reaches the chain until the holder **Accepts** by countersigning the lot's input. **Sell** - makes an ask, the sell order: the lot's key signs its input alone with SIGHASH_SINGLE|ANYONECANPAY (0x83), which - commits to that input and to the price to the seller at the same index and to nothing else, so any node can **Take** - it. The buyer leads with a 600-sat coin of its own, so the lot lands in its first output (sats move first in, first - out), then the lot and its funds; out go the lot to the buyer and the price to the seller. Offers and asks stand in - the lab like PSBTs in an order book until they land, are withdrawn, or go stale (a coin they spend moved, or a side - closed or re-keyed). The buyer pays the fees, and an offer of 0 is a free claim. Payments spend coins no offer has - promised first, and the timeline and Inspect show each deal (`src/orgchain/offers.js`). -- **Acquisitions.** An org sells cash-free: before its parent lists it or accepts an offer on it, the org's money, gas - tank and items go home to the parent, so the price is for the org alone, and a listed org is frozen until its ask is - taken or withdrawn. Its buyer then adopts it: a `join`, signed by the key that now holds the org's inscription, and an - `adopt`, signed by the buyer, move it into the buyer's tree at the buyer's next index, where its keys derive from the - buyer's seed, and its inscription moves to its new key. Taking an ask adopts at once; after an accepted offer the - buyer adopts when it's ready. The seller's tree keeps a row at the old index, marked with where the org went. The - sample ends with both sides standing: lineage's offer for the launch kit, and well-known's ask for mailr. +- **Deals.** Both sides of OpenOrdex's partially signed transaction, on a lot: an item, which its holder sells; an org + inside a holding, which its parent sells with its tree; or a whole holding, which its owner sells (the lab wallet + plays the owner). **Buy** makes an offer, the buy order: the buyer's SegWit key signs the whole deal at once + (SIGHASH_ALL), every coin the lot sits in and its own coins in, the lot to its Taproot key as one coin, the price to + the seller and its change out, and nothing reaches the chain until the holder **Accepts** by countersigning the lot's + inputs. **Sell** makes an ask, the sell order: the lot's key signs its input alone with SIGHASH_SINGLE|ANYONECANPAY + (0x83), which commits to that input and to the price to the seller at the same index and to nothing else, so any node + can **Take** it. The buyer leads with a 600-sat coin of its own, so the lot lands in its first output (sats move first + in, first out), then the lot and its funds; out go the lot to the buyer and the price to the seller. Offers and asks + stand in the lab like PSBTs in an order book until they land, are withdrawn, or go stale (a coin they spend moved, or + a side closed or re-keyed). The buyer pays the fees, and an offer of 0 is a free claim. Payments spend coins no offer + has promised first, and the timeline and Inspect show each deal (`src/orgchain/offers.js`). +- **Acquisitions.** An org changes hands with its tree (the derived orgs and agents below it, and the items they hold), + and a holding changes hands whole. Either sells cash-free: before it is listed, or an offer on it is accepted, the + money in its tree, every gas tank included, goes to its seller (for a holding, the lab wallet), so the price is for + the tree and its items. An ask signs one input, so listing a tree first bundles every inscription in it into one coin + at its key, and while it's listed the whole tree is frozen: nothing in it acts or moves money, nothing above it + graduates or closes it, nothing in it sells alone, and a listed holding doesn't mine. An offer spends every coin the + tree sits in and merges them into one. The buyer then adopts it: a `join`, signed by the key that now holds its + inscription, and an `adopt`, signed by the buyer, move it into the buyer's tree at the buyer's next index (a holding + becomes an org there), where its keys and its tree's derive from the buyer's seed. Then the coin it came in splits + back, each node's inscription to its new key and each item to the node that held it, by the layout the deal kept. + Taking an ask adopts at once; after an accepted offer the buyer adopts when it's ready. The seller's tree keeps a row + at the old index, marked with where the org went, and a holding bought whole brings its history into its buyer's + timeline. The sample ends with both sides standing: lineage's offer for the launch kit, and well-known's ask for + mailr; selling time with its ventures, or yolopreneur whole, is one Sell away. - **Keyrings.** **Keyring** publishes a node's keys in one inscription whose parent is the node itself: its Taproot and SegWit addresses, its npub and its Ethereum address, so another chain or a registry like well-known can find them without deriving anything. Every key signs the same statement, the way its own wallets sign a message: BIP-322 for the @@ -108,13 +116,13 @@ keyring's is the statement its keys signed). | `charter` | the node itself, or a series' master; the newest counts | `form`; `jurisdiction`, `legal`, `provider`, `filing`, or `of` for a series | | `graduate` | the child's parent (then the handoff to the child's fresh root); the child, org or agent, becomes a holding | `of` | | `close` | the node itself | none | -| `join` | the org, signed by whoever holds its inscription (its buyer); with the `adopt`, in either order, it moves | `to` | -| `adopt` | the new parent, which takes the org in at its next index; its keys derive from there | `of` | +| `join` | the org or holding, signed by whoever holds its inscription (its buyer); with the `adopt`, in either order, it moves with its tree | `to` | +| `adopt` | the new parent, which takes it in at its next index; its keys and its tree's derive from there | `of` | Names are domain labels (lowercase letters, digits, hyphens). Org and agent indices count separately and are never -reused (an org that changes hands takes its buyer's next one). The metadata says what an event means; the parent it -spends proves who was allowed to make it; who holds an item afterwards is the chain's to say, never the metadata's. -Metadata is public and permanent: an item's note is for a hash or a link, never a secret or a document. +reused (an org or a holding that changes hands takes its buyer's next one). The metadata says what an event means; the +parent it spends proves who was allowed to make it; who holds an item afterwards is the chain's to say, never the +metadata's. Metadata is public and permanent: an item's note is for a hash or a link, never a secret or a document. ## Lineage as a metaprotocol @@ -126,12 +134,15 @@ fold in, why a parent proves authority, and every rule the reducer applies. The node bin/lineage-index.mjs --ord http://127.0.0.1:8088 [--from ] [--compare ] ``` -`tools/regtest/` rehearses the sample, keyrings, asks, offers and moves included, on Bitcoin Core regtest: the lab's own -transactions, byte for byte, confirmed by Bitcoin Core and indexed by `ord`, which then tell the same story as the lab -(`tests/indexer.test.js` replays a recorded run). The first rehearsal found that the lab's reveals committed to the -wrong tapleaf, which real Bitcoin rejects; reveals are now checked the way Bitcoin checks them (`SPEC.md`, section 1). -The rehearsal of org sales found that a miner can put a join and its adoption in either order within a block, so a move -records both halves and each half belongs to both holdings (`SPEC.md`, section 5). +`tools/regtest/` rehearses the sample, keyrings, asks, offers and whole trees changing hands included, on Bitcoin Core +regtest: the lab's own transactions, byte for byte, confirmed by Bitcoin Core and indexed by `ord`, which then tell the +same story as the lab (`tests/indexer.test.js` replays a recorded run). The first rehearsal found that the lab's reveals +committed to the wrong tapleaf, which real Bitcoin rejects; reveals are now checked the way Bitcoin checks them +(`SPEC.md`, section 1). The rehearsal of org sales found that a miner can put a join and its adoption in either order +within a block, so a move records both halves and each half belongs to both holdings (`SPEC.md`, section 5). The +rehearsal of whole trees sold an org with its six below it on an offer and a holding whole on an ask, bundling eleven +inscriptions into one coin and splitting them again, and `ord` put every one in the same output as the lab (`SPEC.md`, +section 7). ## Build and test @@ -152,7 +163,7 @@ Deploy: copy `dist/` to `ventures/lineage/orgchain/` on `teahubxyz/time` `gh-pag The chain, wallet, inscriptions, metadata and index (`src/adapters`, `src/upstream`, with `src/storage.js` and `src/miner.js`) are [Super Testnet](https://supertestnet.lol)'s, with their tests (`tests/adapters.test.js`) and five additions: the chain also moves native SegWit (P2WPKH) payments, BIP-143 signatures included; a coinbase may split -its reward across up to 64 outputs; ordinary spends take up to eight inputs and outputs, whose key-path +its reward across up to 64 outputs; ordinary spends take up to 64 inputs and outputs, whose key-path signatures may carry SIGHASH_SINGLE|ANYONECANPAY (0x83, the sell-order flag), while reveals keep their two-in, two-out shape (`tests/money.test.js`); a chain may start from coins imported from a real chain; and reveals' script paths are checked per BIP-341 and BIP-342 (`tests/indexer.test.js`). diff --git a/SPEC.md b/SPEC.md index 5262ecf..58e1095 100644 --- a/SPEC.md +++ b/SPEC.md @@ -1,9 +1,9 @@ # lineage/v0 lineage/v0 is an ordinals metaprotocol for lineage holdings: LLCs, the orgs and agents they birth, the belts and -decisions on their record, the items they make, and the orgs that change hands between them. Every event is an -inscription. The chain orders the events and proves who was allowed to make each one; the state (the trees) is stored -nowhere, and every indexer that applies these rules to the same inscriptions gets the same trees. +decisions on their record, the items they make, and the orgs and holdings that change hands between them. Every event +is an inscription. The chain orders the events and proves who was allowed to make each one; the state (the trees) is +stored nowhere, and every indexer that applies these rules to the same inscriptions gets the same trees. Status: test networks only (Orgchain's in-browser chain and Bitcoin Core regtest). The reference implementation is `reduce()` in `src/orgchain/lineage.js`; `src/indexer/ord.js` and `bin/lineage-index.mjs` run it over a real ord index. @@ -62,8 +62,8 @@ the inscription moves the authority. | `charter` | the node itself, active; for a series, its master | `form`; `jurisdiction`, `legal`, `provider` and `filing`, or `of` for a series | the node's legal form, replacing its earlier charter (section 5) | | `graduate` | the child's parent, active | `of` (an active child, org or agent, not yet adopted) | the edge becomes adopted, and the child becomes a holding of its own (section 5) | | `close` | the node itself, active | none | the node closes, with every active derived descendant; adopted ones stay open | -| `join` | the org itself, active | `to` (the new parent) | half of a move: the org asks to join `to`, and moves once `to` adopts it (section 5) | -| `adopt` | the new parent, active | `of` (the org) | the other half: `to` takes the org in, and it moves once it has joined (section 5) | +| `join` | the moving org or holding itself, active | `to` (the new parent) | half of a move: it asks to join `to`, and moves there with its tree once `to` adopts it (section 5) | +| `adopt` | the new parent, active | `of` (the org or holding) | the other half: `to` takes it in, and it moves once it has joined (section 5) | Names (holdings, children, skills, items) are 1 to 40 lowercase letters, digits or hyphens, starting and ending with a letter or digit, because they become domains. Text fields are trimmed, and only their first characters count: 140 for a @@ -81,20 +81,23 @@ root, and so do its derived descendants', so their keyrings retire (section 8). In Orgchain a graduation is followed by a handoff: the graduate's fresh root claims its inscription, and the derived key that held it countersigns. After that, only the new root can act for it. -An org can change hands: move to a new parent, in its own holding or in another. Both sides must authorize it, and an -event has one parent (section 1), so a move takes two events: a `join`, whose parent is the org (so whoever holds the -org's inscription, its buyer after a sale), names the new parent in `to`, and an `adopt`, whose parent is the new -parent, names the org in `of`. Either may come first, and the second completes the move. A newer `join` replaces the -org's pending one; an `adopt` waits for its own join. Only an org inside a holding moves (a holding's root would take -its whole tree, which is another matter), and it moves alone: an org with active derived children does not. The new -parent is an active holding, org or graduated agent, not the org nor anything below it, with no active child of the -org's name. +An org or a holding can change hands: move to a new parent, in its own holding or in another, with its tree. Both sides +must authorize it, and an event has one parent (section 1), so a move takes two events: a `join`, whose parent is the +moving node (so whoever holds its inscription, its buyer after a sale), names the new parent in `to`, and an `adopt`, +whose parent is the new parent, names the moving node in `of`. Either may come first, and the second completes the move. +A newer `join` replaces the node's pending one; an `adopt` waits for its own join. An org moves with its derived tree, +and a holding, or a graduate (which holds its own root), moves whole; an agent moves only with the org it sits in. The +new parent is an active holding, org or graduated agent, not the moving node nor anything below it by parent links (so +no ancestor of a graduate can join it), with no active child of the moving node's name. -When the move completes, the org takes the next index of its kind under its new parent, and it and its derived -descendants still in its old holding re-root into the new one. Its keys now derive from its new parent at its new index, -so its keyring retires (section 8). Its charter goes with it; a series that leaves its master's holding lapses. The move -records both halves, and each half belongs to both holdings, so the miner may put them in either order within a block. A -graduation of an org with a pending join is rejected. +When the move completes, the node takes the next index of its kind under its new parent, and it and its derived +descendants still in its old holding re-root into the new one. A holding that moves becomes an org of its new parent and +leaves the holdings. Its keys now derive from its new parent at its new index, and so do its derived descendants', so +their keyrings retire (section 8); graduated descendants hold their own roots and stay where they are, their parent +links pointing into the tree that moved. Its charter goes with it: a series that leaves its master's holding lapses, and +so does a sole proprietorship, since an org is not a person. The move records both halves, and each half belongs to +both holdings, so the miner may put them in either order within a block. A graduation of a node with a pending join is +rejected. A `charter` records a node's legal form: what it is off chain. Legal form is an attribute, not an identity, so a node keeps its inscription, history and keys whatever form it takes, and the newest charter counts. @@ -123,36 +126,52 @@ same block land the same way in either order. Control follows the inscription, w Where independent events conflict within one block, the block's order decides. These are the cases: a close and an act by one of its derived descendants; an award and its recipient's close; two foundings with the same name; a keyring and a graduation or close that retires it; two keyrings that list the same key; a join or adoption and a graduation, close or -birth that changes the org or its new parent. Orgchain keeps a keyring and the graduation that would retire it a block -apart, and it freezes an org that is listed or sold, so its seller can't graduate it before its buyer adopts it. +birth that changes the moving node or its new parent. Orgchain keeps a keyring and the graduation that would retire it +a block apart, and it freezes a tree that is listed or sold (section 7), so nothing in it acts, and nothing above it +graduates or closes it, before its buyer adopts it. ## 7. Ownership, items and deals Whoever controls the output that holds an inscription's sat holds that node or item; for indexers that is ord's -satpoint. Items and orgs move like any inscription. A deal is not an event: ord sees the lot move, and nothing else -needs indexing. Orgchain makes deals both ways OpenOrdex does, on a lot that is an item or an org: +satpoint. Items and nodes move like any inscription, and one output may hold several. A deal is not an event: ord sees +the lot move, and nothing else needs indexing. Orgchain makes deals both ways OpenOrdex does, on a lot that is an item, +an org with its tree, or a holding, whole: -- An offer is a buy order: one transaction with the lot and the buyer's coins in, and the lot to the buyer, the price - to the seller and the buyer's change out. The buyer signs its inputs first (SIGHASH_ALL), and the lot's holder - countersigns. +- An offer is a buy order: one transaction with every output the lot sits in and the buyer's coins in, and the lot to + the buyer as one output, the price to the seller and the buyer's change out. The buyer signs its inputs first + (SIGHASH_ALL), and the lot's holders countersign theirs. - An ask is a sell order: the holder signs the lot's input alone with SIGHASH_SINGLE|ANYONECANPAY (0x83), which commits to that input and to the output at its index, the price to the seller, and to nothing else. Any buyer completes it: a small coin of its own, the lot and its funds in; the lot to the buyer's key and the price to the seller out. The - small coin leads so that the lot's sat lands in the buyer's output, since sats move first in, first out. + small coin leads so that the lot's sats land in the buyer's output, since sats move first in, first out. One input is + one output, so a tree is bundled into one before it is listed. -An org's seller is its parent, and a sold org joins its buyer's tree by `join` and `adopt` (section 5); until then the -trees still draw it under its seller. Orgchain sells an org cash-free: before it lists one or accepts an offer on one, -the parent takes home the org's money, gas tank and items, so the price is for the org alone, and a listed org is frozen -until its ask is taken or withdrawn. +A tree is a node and its active derived descendants, with the items they hold. An org's seller is its parent; a +holding's is its owner, whoever holds its root (in Orgchain, the lab wallet), and the price goes to the owner's key. A +sold node joins its buyer's tree by `join` and `adopt` (section 5); until then the trees still draw it with its seller. +In Orgchain a deal on a tree goes like this: + +- Cash-free: before it lists a tree, or accepts an offer on one, the seller takes home the money in it, every node's + SegWit coins and gas tank, so the price is for the tree and its items. +- Listing bundles it: one transaction spends every output that holds the inscription of one of its nodes or items, the + lot's own first, and pays them into one output at the lot's key, with a coin of the seller's last for the fee, so no + inscription's sat pays it. The ask signs that output, and withdrawing the ask splits it back. +- After the `join` and the `adopt`, the buyer splits the output it bought: one transaction with an output for each + inscription, running from its sat to the next one's (the first from the output's start), to the node's new key, or, + for an item, to the new key of the node that held it, which the deal records as its layout. +- While a tree is listed or sold it is frozen: nothing in it acts or moves money, nothing above it graduates or closes + it, nothing in it sells alone, and a listed holding mines nothing. The records of a tree's events (decisions, belts, + keyrings and the like) are not part of it: they carry no authority, and stay where they landed. ## 8. Keys and keyrings Indexers need no keys to fold the trees. Keys say where a node's inscription is expected to live, and who can sign for it. Each holding has a 24-word root (BIP-39), and an org's seed is BIP-85 from its parent's (`m/83696968'/39'/0'/24'/i'`) -until it graduates. An org is account 0 of its seed and its agents are accounts 1 to n. Each account holds its -inscription at its BIP-86 Taproot address (`m/86'/coin'/account'/0/0`), keeps its money at BIP-84 SegWit, and has a -NIP-06 npub (`m/44'/1237'/account'/0/0`) and an Ethereum address (`m/44'/60'/account'/0/0`). An org's Ethereum key, at -account 0, is its legal-control key: the one that holds its entity NFT. +until it graduates, and from its new parent's at its new index once it moves (a holding that moves becomes an org, and +its old root no longer signs for it). An org is account 0 of its seed and its agents are accounts 1 to n. Each account +holds its inscription at its BIP-86 Taproot address (`m/86'/coin'/account'/0/0`), keeps its money at BIP-84 SegWit, and +has a NIP-06 npub (`m/44'/1237'/account'/0/0`) and an Ethereum address (`m/44'/60'/account'/0/0`). An org's Ethereum +key, at account 0, is its legal-control key: the one that holds its entity NFT. A `keyring` publishes a node's keys, so other chains and registries can find them without deriving anything. Its parent is the node itself. Its metadata lists four keys, each written the way its chain writes it, and a proof from each: @@ -184,8 +203,9 @@ A keyring is rejected unless every key is well formed and every proof checks out keys are bound to that node, and a keyring that lists a key bound to another node is rejected; a key binds once, whatever network it is written for. A node's newer keyring replaces its older one and frees the keys it no longer lists. A graduation retires the keyrings of the graduate and its derived descendants, since their keys change with the new -root, a move retires the moving org's, since its keys change with its parent, and a close retires the keyrings of the -nodes it closes. A retired keyring binds nothing, so the node publishes a new one. +root, a move retires those of the moving node and its derived descendants, since their keys change with its new parent, +and a close retires the keyrings of the nodes it closes. A retired keyring binds nothing, so the node publishes a new +one. Lineage's key tree page also makes an agent's keyring as a nostr event (kind 30078, `d` = `lineage/keyring/v0`), signed by its npub and listing its leaves too. The inscription is the chain's record, with a proof from every key. @@ -200,8 +220,9 @@ chain's own wallets sign a message. ## 10. Conformance -`tools/regtest` rehearses Orgchain's sample on Bitcoin Core regtest, byte for byte, keyrings, asks, offers and moves -included, and `bin/lineage-index.mjs --compare` checks that ord and the lab tell the same story: the same events in the -same beats, the same metadata and parents, the same trees and keyrings, and every inscription in the same output. -`tests/indexer.test.js` replays a recorded run. `tests/keyring.test.js` checks the proofs against BIP-322's published -vectors, the key tree page's Ethereum vector, and values cross-checked with bip322-js, ethers and nostr-tools. +`tools/regtest` rehearses Orgchain's sample on Bitcoin Core regtest, byte for byte, keyrings, asks, offers and whole +trees changing hands included (bundled outputs and their splits too), and `bin/lineage-index.mjs --compare` checks that +ord and the lab tell the same story: the same events in the same beats, the same metadata and parents, the same trees +and keyrings, and every inscription in the same output. `tests/indexer.test.js` replays a recorded run. +`tests/keyring.test.js` checks the proofs against BIP-322's published vectors, the key tree page's Ethereum vector, and +values cross-checked with bip322-js, ethers and nostr-tools. diff --git a/bin/lineage-index.mjs b/bin/lineage-index.mjs index fb0b9ca..d4f9767 100644 --- a/bin/lineage-index.mjs +++ b/bin/lineage-index.mjs @@ -19,8 +19,8 @@ for (const root of state.roots) { console.log(rows(state, root.id).map(r => (r.type === 'group' ? `${r.guide}${r.label}` : `${r.guide}${r.path} ${r.node.name}${r.moved ? ` · moved to ${state.nodes.get(r.node.parent).name}` : r.away ? ' · graduated' : ''}`)).join('\n')); } -const moves = [...state.nodes.values()].flatMap(n => n.moves.map(m => `${n.name} from ${state.nodes.get(m.from).name} to ${state.nodes.get(m.to).name}`)); -if (moves.length) console.log(`\n${plural(moves.length, 'org')} changed hands: ${moves.join('; ')}`); +const moves = [...state.nodes.values()].flatMap(n => n.moves.map(m => `${n.name} ${m.from ? `from ${state.nodes.get(m.from).name}` : 'whole'} to ${state.nodes.get(m.to).name}`)); +if (moves.length) console.log(`\n${plural(moves.length, 'tree')} changed hands: ${moves.join('; ')}`); const rejected = state.log.filter(e => !e.ok); console.log(`\n${plural(events.length, 'lineage/v0 event')} on ord, ${plural(state.items.size, 'item')}${rejected.length ? `, ${rejected.length} rejected:` : ''}`); for (const e of rejected) console.log(` ${summary(e, state)} (${e.id})`); diff --git a/index.html b/index.html index de7dfa0..6ab6401 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ Orgchain · Lineage - + @@ -16,7 +16,7 @@

Lineage /

Orgchain

-

Found a holding, then birth its orgs and agents, award belts, record decisions, make items, buy and sell items and orgs, publish keyrings, charter legal forms, send test BTC, graduate and close. Each act is an inscription whose parent is the node that authorizes it, paid for with the actor's own gas, and each beat is a block whose 50 test BTC the holdings mine. Lineage gives the structure; the chain adds time.

+

Found a holding, then birth its orgs and agents, award belts, record decisions, make items, buy and sell items, orgs and whole holdings, publish keyrings, charter legal forms, send test BTC, graduate and close. Each act is an inscription whose parent is the node that authorizes it, paid for with the actor's own gas, and each beat is a block whose 50 test BTC the holdings mine. Lineage gives the structure; the chain adds time.

Test coins only @@ -136,11 +136,11 @@
-

The sender pays the chain's 500-sat fee. One send spends at most eight coins and moves at most 50 test BTC, one block reward.

+

The sender pays the chain's 500-sat fee. One send spends at most 64 coins and moves at most 50 test BTC, one block reward.