Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

README.md

ODNCA State Commitments — merkle proofs & ownership certificates (v1.1)

Multi-protocol: commits SNS and OpNS state on separate, isolated chains (sns-commit / opns-commit). Offered under the ODNCA flag: ODNCA publishes the rulesets and the keys; the math validates, ODNCA coordinates. See DEPLOY.md for the server-37/167 deployment layout.

Implementation of B-SNS-STATE-COMMITMENT-SPEC.md: the ORDnet indexer's canonical SNS state is periodically committed as an on-chain merkle root, and every name holder can obtain a compact, independently verifiable Certificate of Ownership.

Zero dependencies. Node >= 20. No npm install.

Components

Piece Run What it does
src/committer.js cron per protocol: node src/committer.js sns / opns fetch state → build tree → publish sns-commit inscription → persist
src/server.js service: node src/server.js /proof/<name> JSON certificates, /certificate/<name> human page, /commits, /commit-key
verify-cert.js anyone, anywhere offline reference verifier — folds the merkle path to a root pinned from the chain (--root, required) and, with --key, the API signature; exit 0 only when all checks pass

node src/committer.js --dry-run prints the root + inscription content without publishing — use it for the first manual end-to-end check.

Configuration (env)

Variable Default Meaning
SNS_STATE_URL http://127.0.0.1:8080/state Indexer state endpoint: { h, entries: [{name, origin, outpoint, script, pubkey?}] }
SNS_STATE_FILE Alternative: read the same shape from a JSON file (takes precedence)
SNS_INSCRIBER_URL http://127.0.0.1:8083/inscribe ORDnet mint service: POST {content, contentType}{txid}
SNS_RULESET_HASH placeholder Required in production: sha256 of the frozen, published ruleset doc
SNS_COMMIT_DIR ./commits Commit storage (index.json + one snapshot per height)
SNS_SIGNING_KEY_PEM dev key secp256k1 PEM for signing /proof responses
SNS_PROOF_HOST/PORT 127.0.0.1:8090 Listen address (TLS proxy in front)

Protocol constants (do not change once live)

  • Leaf JSON, exact key order: {"v":1,"name","origin","outpoint","script","pubkey","h"}
  • Leaf hash SHA256(0x00 || leafJson), node hash SHA256(0x01 || L || R), leaves sorted bytewise by name, odd node promoted
  • Commit inscription: {"p":"sns-commit","v":1,"root","h","names","ruleset","prev"}prev chains commitments into an auditable history
  • Proof positions: 'L' = sibling left of running hash, 'R' = right

These are pinned by golden-vector tests; changing any of them invalidates every certificate in the wild.

The two buttons (spec §4.4)

  • Verify (free): point the button on domains.ordnet.io at /certificate/<name>.<tld> — the included page renders the Certificate of Ownership from /proof/<name> (shareable URL, "verify this yourself" panel with raw JSON + verifier instructions).
  • Mint Ownership Certificate (cents): the wallet inscribes the /proof/<name> JSON as "p":"sns-cert" onto the holder's address via your existing mint flow. The proof JSON is the certificate content.

Keys — two, deliberately separate

  1. Commitment key (in your wallet/mint infra, NOT here): posts the sns-commit inscriptions. Publish its pubkey; verifiers check roots came from it. Compromise = fake roots (detectable via re-run + prev fork), never stolen names.
  2. API signing key (SNS_SIGNING_KEY_PEM): signs /proof responses so consumers can pin ORDnet's API. Served at /commit-key.

Tests & measured scale

node test/run-tests.js

50 checks (incl. multi-protocol isolation and cross-protocol replay rejection): golden vectors (leaf/commit encoding pinned), determinism, proofs at odd/even sizes (promotion), tamper cases (leaf, path, positions, root), duplicate names, committer chain (prev), dry-run, same-height refusal, historical proofs, certificate page (incl. injection-safety), reference verifier CLI (valid + tampered), and the §8.6 fork drill (honest re-run reproduces the root; a dishonest state diverges detectably).

Measured on this machine at 1,000,000 names: tree build 14.6 s, proof depth 20, proof generation + verification < 1 ms, ~1.8 GB RSS during build. Daily cadence is trivial; per-block is feasible with an incremental builder later.

Rollout order (mirrors spec §9)

  1. Freeze + publish the ruleset doc; set SNS_RULESET_HASH
  2. Wire SNS_STATE_URL to the real indexer; --dry-run; eyeball the root
  3. Determinism check: run the indexer twice at the same height → same root
  4. First real commit (small ceremony: verify the inscription on-chain)
  5. Proof server live; publish verify-cert.js + /commit-key
  6. "Verify" button on domains.ordnet.io → /certificate/<name>
  7. Bridge pki extension (ordnetProof field, File A §5.1) + BRFC ID
  8. Wallet "Mint Ownership Certificate" flow
  9. Later: invite a second independent committer (spec §5 federation)