LOCAL-TRUE · not on-chain

Midnight dual-state · privacy bulletin

Seal it private. Commit it public. Disclose on your terms.

Shield Board is a polished local studio for Midnight’s dual-state idea: a public ledger of commitments and owners, and a private vault that never leaves this browser until you choose to disclose. Identity is witness-derived (MPS-0029) — never ownPublicKey() alone. Inspired by example-bboard. Built by @kshot9000 / Kshot3000 (Midnight GrokBot Agent).

Honest capabilities: LOCAL-TRUE browser persistence (schema v2 localStorage, multi-tab sync, JSON export/import) — still not on-chain Compact. No proof server, no Lace transfers, no deploy in this app. Use it to feel dual-state UX before wiring real circuits.

Dual-state studio

Left = what the chain would see. Right = what stays in your private vault until you disclose.

Your witness identity

Secret stays local. Public commitment is derive(sk, domain) — Mallory cannot forge take-down without your secret.

Derived pk —
0Public posts
0Sealed private
0Disclosed
0Ledger seq

Public ledger

Commitments on-chain (simulated)

Visible

Post id, commitment hash, owner pk, sequence, disclosure flag. Bodies are not here unless disclosed.

    Ledger rail quiet

    No public commitments yet. Seal a message to mint a hash the chain would see — body stays veiled unless you disclose.

    Private vault

    Local state (this browser)

    Shielded

    Raw message bodies you authored. Cleared on refresh unless you export. Take-down requires your derived pk.

      Vault empty

      Private bodies live only in this browser until you disclose. LOCAL-TRUE persistence — not on-chain custody.

      Compose & seal

      0/500

      Default keeps the body sealed — public side shows only the commitment.

      localStorage schema v2 · BroadcastChannel sync · not Compact

      Activity

      Ready. Generate or keep your secret, then seal a message.

      How dual-state maps here

      Teaching model aligned with Midnight docs — not a substitute for the Compact compiler.

      1. 1
        Witness

        You hold a local secret. Circuits would receive it via witness; we simulate derive(sk) in-browser.

      2. 2
        Commit

        Public ledger stores H(body ‖ pk ‖ seq ‖ domain) + owner pk. Observers see evidence a post exists — not the text.

      3. 3
        Prove (simulated)

        A real Midnight tx would attach a ZK proof that the commitment matches a valid witness. Here we animate a local hash only.

      4. 4
        Disclose / take-down

        Selective disclosure publishes the body. Take-down checks derived pk equality — forgeable ownPublicKey() gates are rejected (see Auth Lab).

      Compact shape educational

      Illustrative — verify against official Compact docs and example-bboard before shipping circuits.

      Safe pattern — witness-derived owner
      witness localSecretKey(): Bytes<32>;
      
      export circuit post(commitment: Bytes<32>): [] {
        const sk = localSecretKey();
        const pk = publicKey(sk); // derive in-circuit
        // ledger.posts.insert(commitment, pk, seq);
      }
      
      export circuit takeDown(id: PostId): [] {
        const sk = localSecretKey();
        assert publicKey(sk) == ledger.posts[id].owner;
        // ledger.posts.delete(id);
      }
      Unsafe — ownPublicKey as auth gate
      // MPS-0029: ownPublicKey() is prover-chosen
      export circuit takeDownBad(id: PostId): [] {
        assert ownPublicKey() == ledger.posts[id].owner;
        // Mallory supplies the owner's pk as "own"
      }

      Deep dive: MPS-0029 Auth Lab · MPS-0029 · example-bboard

      Wallet discovery optional

      Enumerates window.midnight — never hardcodes mnLace. This studio does not call connect or transfer.

      Not scanned.