Mina merkle offchain state dev
Skill mysteryon88/skills/mina-protocol/skills/mina-merkle-offchain-state-dev
My Web3 skills & experiments
npx -y skills add mysteryon88/skills --skill mina-merkle-offchain-state-devAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use when designing, implementing, testing, or reviewing Mina Merkle trees, off-chain state commitments, membership proofs, update proofs, nullifier sets, or root transition logic.
SKILL.md
3.8 KB, as published. Nobody here has run it
Mina Merkle and Off-chain State Development Skill
Use when
Use this skill when building or reviewing Mina apps that store commitments, Merkle roots, indexed maps, off-chain state, membership proofs, allowlists, credentials, nullifier sets or private balances.
Shared references
If installed from the full package, shared resources live in ../mina-protocol-agent/references/. Load ../mina-protocol-agent/references/INDEX.md only when task cards, examples, templates, source links or deeper checklists are needed.
Mental model
Mina on-chain state is intentionally small. Real apps often store a root or commitment on-chain and keep the larger data structure off-chain. The proof must show that the off-chain update is valid relative to the old on-chain commitment and produces the new commitment.
First output
State structure:
On-chain commitment/root:
Off-chain data owner:
Leaf schema:
Index/key schema:
Membership proof type:
Update rule:
Nullifier/replay model:
Data availability assumption:
Recovery plan if off-chain data is lost:
Design checklist
Leaf schema
Define a fixed schema:
leaf = Poseidon.hash([DOMAIN_LEAF, userKey, value, nonce, ...])
Check:
- domain separation;
- stable field order;
- fixed encoding;
- no ambiguous packing;
- values are range-checked before hashing;
- leaf includes owner/index when needed.
Membership proof
For every update:
- old root is read with
getAndRequireEquals(); - witness computes old root from old leaf;
- old root equals on-chain root;
- new leaf is computed from constrained inputs;
- witness computes new root;
- new root is written to state;
- index/key cannot be swapped by attacker.
Nullifier set
For one-time actions:
- nullifier is domain-separated;
- non-membership or unused-state proof is verified;
- nullifier is inserted/marked used;
- repeated use fails;
- app/domain/poll/epoch binding is explicit.
Off-chain storage
Document:
Who stores the tree:
How users get witnesses:
How witnesses are verified client-side:
How data is reconstructed from events/actions if possible:
What happens if server lies or goes offline:
Concurrency
Check:
- two users updating same root at the same time;
- stale witness behavior;
- actions/reducers or batching if concurrent updates are required;
- retry flow for users.
Common bad patterns
Root update without old root binding
Bad:
const oldRoot = this.root.get();
const newRoot = witness.calculateRoot(newLeaf);
this.root.set(newRoot);
Good:
const oldRoot = this.root.getAndRequireEquals();
witness.calculateRoot(oldLeaf).assertEquals(oldRoot);
const newRoot = witness.calculateRoot(newLeaf);
this.root.set(newRoot);
Leaf does not bind owner
Bad:
const leaf = Poseidon.hash([balance]);
Good:
const leaf = Poseidon.hash([DOMAIN_BALANCE_LEAF, ...owner.toFields(), balance.value]);
Index not constrained
Bad:
// witness proves some leaf exists, but user chooses recipient separately
Good:
// leaf binds owner/index/key, and transfer proof asserts it matches sender/recipient semantics
Required tests
- valid membership proof succeeds;
- wrong leaf fails;
- wrong index/key fails;
- old root replay fails after update;
- new root equals expected local tree update;
- stale witness gives clear failure;
- server-provided wrong witness fails;
- data availability/reconstruction story is documented.
Output format
State design
Leaf and hash schema
Proof/update flow
Concurrency model
Data availability assumptions
Code
Tests
Security notes