From b15229fbd52c49f22a9563812fe0c8d07c86c444 Mon Sep 17 00:00:00 2001 From: Sylvain Duchesne Date: Mon, 6 Jul 2026 10:15:06 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20explicit=20virtual-wallet=20structure?= =?UTF-8?q?=20=E2=80=94=20the=203=20emulated=20stores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a diagram + prose to simulation.md: a virtual wallet = one shim account keyed by a virtual-wallet id; it has the 3 native stores (public/protected/private) but EMULATED — each "store" is an index document (AccountRecord.docPublic/Protected/ Private) listing that scope's per-entity doc NURIs. Everything physical lives in the ONE shared wallet's private store; the 3-store structure is the per-account logical layer. At migration the index docs become real native stores. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/simulation.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/docs/simulation.md b/docs/simulation.md index c4394f8..faed6e9 100644 --- a/docs/simulation.md +++ b/docs/simulation.md @@ -116,6 +116,40 @@ The `store≠document` two axes materialize here directly: the registry moves al axis B (more documents = more isolation), never axis A (it always writes into the one private store via `docCreate(..., undefined)`). +### A virtual wallet's structure — the three emulated stores + +A **virtual wallet** = one account in the shim, keyed by its **virtual-wallet id** +(the technical identifier the consumer sets when the physical wallet is opened; it +identifies *which* virtual wallet, and is NOT the consumer's application username). +Its structure mirrors the target "1 user = 1 wallet with 3 native stores": + +``` +Virtual wallet (id) +├── public store = docPublic index → [ event doc NURI, PdR doc NURI, … ] +├── protected store = docProtected index → [ profile doc NURI, participation doc NURI, … ] +└── private store = docPrivate index → [ settings doc NURI, … ] +``` + +So **yes, the 3 native stores (public/protected/private) are present** — but +**emulated**: each "store" is an **index document** +(`AccountRecord.{docPublic,docProtected,docPrivate}`) that LISTS the NURIs of the +per-entity documents in that scope. It is not a physical native store. + +Everything is physical in ONE place: the 3 index documents, every per-entity +document, and the shim anchor itself all live in the shared **physical** wallet's +private store (`docCreate(..., undefined)`). The 3-store structure is the per-account +**logical** layer the lib maintains on top. + +``` +Physical wallet (shared, ONE) → private_store (physical) holds EVERYTHING: + • the shim anchor: virtual-wallet-id → { docPublic, docProtected, docPrivate } + • every account's 3 scope-index docs + all per-entity docs + inbox + discovery index +``` + +At migration each virtual wallet's 3 index documents become the user's 3 **real** +native stores, the entity documents move into them physically, and the +virtual/physical distinction dissolves (see [`migration-guide.md`](./migration-guide.md)). + ### SDK-shaped scope resolvers — the consumer holds NO store-id The consumer must never construct a `did:ng:${store_id}` NURI itself: physical