1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//! # dig-merkle — the DIG Network canonical CHIP-0035 DataLayer coin expert crate
//!
//! `dig-merkle` is a **pure, key-free, network-free** SpendBundle-builder for the Chia CHIP-0035
//! DataLayer singleton that anchors a `.dig` file's merkle root on-chain. It constructs the exact
//! [`CoinSpend`]s for every DataLayer-coin lifecycle operation and reports — via
//! [`required_signatures`] — the exact signatures a caller must produce. It never holds a secret
//! key, never signs, and never touches the network. The consumer signs the reported messages,
//! assembles the `SpendBundle`, and broadcasts.
//!
//! ## The DataLayer coin
//!
//! A DataLayer coin is a CHIP-0035 singleton whose `launcher_id` IS the DIG `store_id`. Its
//! [`DatastoreMetadata`] carries the capsule's `root_hash` (the anchored `.dig` merkle root) plus
//! optional `label`/`description`/`size_proof`, the additive `program_hash` (`"p"`), and the store
//! size as a power-of-2 `size_bucket` (`"sz"` — see [`SizeBucket`]) that REPLACES the SDK's exact
//! `bytes`/`"b"` field, and its [`DelegatedPuzzle`] list grants
//! admin/writer/oracle authority. Spending the coin recreates it with a new root, transferring
//! ownership, delegating write access, or melting it. dig-merkle builds each such spend unsigned.
//!
//! ## Invariants
//!
//! These four invariants hold across the entire crate and are the contract every unit is built to
//! (SPEC §1):
//!
//! - **INV-1 — No network.** dig-merkle performs NO network or chain I/O. Every function is a pure
//! transform of its inputs; the caller fetches coins and broadcasts bundles.
//! - **INV-2 — No keys.** dig-merkle never accepts, holds, derives, or logs a secret key. It
//! computes what must be signed ([`required_signatures`]); the caller's signer produces the
//! signatures.
//! - **INV-3 — Unsigned output.** Every operation returns an unsigned [`MerkleCoinSpend`] — coin
//! spends plus the recreated child Datastore. Signatures are always the caller's responsibility.
//! - **INV-4 — SDK byte-source-of-truth.** Every puzzle, layer, and coin-spend byte is produced by
//! `chia-wallet-sdk` (pinned to the 0.30 / chia-protocol 0.26 family, `chip-0035` feature).
//! dig-merkle adds DataLayer-workflow ergonomics on top; it never re-implements a puzzle or
//! hand-rolls a spend bundle, and re-exports the SDK's Datastore types verbatim.
//!
//! ## Consumer pattern
//!
//! ```text
//! build an unsigned MerkleCoinSpend -> required_signatures(&spend.coin_spends, &constants)
//! -> caller signs each reported message -> assemble SpendBundle -> broadcast
//! ```
//!
//! ## Operation surface
//!
//! On the foundation (the type surface [`MerkleCoinSpend`]/[`Owner`] + re-exported SDK Datastore
//! types, the error taxonomy [`MerkleError`], the inner-spend helpers, and the signing boundary
//! [`required_signatures`]) the crate ships the DataLayer-coin lifecycle:
//! - [`mint_datastore`] / [`mint_datastore_with_kind`] — launch a new DataLayer coin anchoring a
//! root; the kind-aware entry selects the launcher-hint discriminator ([`StoreKind`], SPEC §9).
//! - [`update_root`] — recreate the coin with new metadata (a new merkle root), preserving identity.
//! - [`melt()`] — terminally spend the coin, leaving no successor.
//! - [`did_ref_from_spend`] / [`resolve_owner_did`] — read owner-DID ownership without spending.
//! - [`hydrate()`] — reconstruct a spendable [`Datastore`] from a parent coin spend (fail-closed).
//! - [`child_lineage_proof`] — derive the [`LineageProof`] a child spend requires.
//! - [`launcher_hint_for`] / [`from_launcher_hint`] — the launcher-hint kind contract (SPEC §9).
//!
//! `delegation`, `oracle`, and `fee` remain doc-only stubs, landing in their own units.
// Internal helpers — not part of the public surface.
// Public modules.
// The DataLayer operation modules. `delegation`/`oracle`/`fee` remain doc-only stubs (declared so
// the crate layout is final); the rest are implemented.
/// Grant or revoke admin/writer/oracle [`crate::DelegatedPuzzle`] authority (future unit,
/// SPEC §3.3).
/// Spend the oracle delegated puzzle to read the coin for a fee (future unit, SPEC §3.4).
/// Attach a reserve fee condition to any DataLayer operation (future unit, SPEC §3).
// The curated public surface — consumers depend on these paths, not the module layout.
pub use ;
pub use ;
pub use hydrate;
pub use child_lineage_proof;
pub use melt;
pub use DigDataStoreMetadata;
pub use ;
pub use ;
pub use required_signatures;
pub use SizeBucket;
pub use ;
pub use update_root;
// Re-export the signing types a consumer needs to CALL [`required_signatures`] and consume its
// result, so a downstream crate need not add a direct chia-wallet-sdk dependency for them.
pub use ;
// Re-export the two launcher builders a consumer needs to CALL
// [`mint_datastore_launch_with_kind`], for the same reason: `Launcher::new(parent_coin_id, 1)` for an
// ordinary parent, `IntermediateLauncher::new(parent_coin_id, 0, 1).create(ctx)?` for a singleton one.
pub use ;