pallet_commitment/
traits.rs

1// SPDX-License-Identifier: MPL-2.0
2//
3// Part of Auguth Labs open-source softwares.
4// Built for the Substrate framework.
5//
6// This Source Code Form is subject to the terms of the Mozilla Public
7// License, v. 2.0. If a copy of the MPL was not distributed with this
8// file, You can obtain one at https://mozilla.org/MPL/2.0/.
9//
10// Copyright (c) 2026 Auguth Labs (OPC) Pvt Ltd, India
11
12// ===============================================================================
13// ```````````````````````````` COMMIT-HELPERS TRAITS ````````````````````````````
14// ===============================================================================
15
16//! Defines helper traits for implementing a concrete [`Commitment`] system.
17//! All operations are **low-level and unchecked** - callers must ensure validity,
18//! equilibrium, and invariants before invoking these functions.
19//!
20//! ## Requirements
21//! This module additionally requires the balance primitive [`LazyBalance`] provided
22//! via the implementing pallet. All balance interactions and accounting are expected
23//! to be handled through this abstraction.
24//!
25//! ## Traits
26//! - [`CommitBalance`] - balance management and reconciliation.
27//! - [`CommitDeposit`] - low-level deposit operations.
28//! - [`CommitWithdraw`] - low-level withdrawal operations.
29//! - [`CommitOps`] - placing, raising, and resolving commitments.
30//! - [`CommitInspect`] - inspection and auditing of committed values.
31//! - [`PoolOps`] - operations for pooled commitments.
32//! - [`IndexOps`] - operations for indexed digest commitments.
33//!
34//! ## Design Principles
35//! - Explicit imbalance handling for auditability and safety.
36//! - Composability to build full commitment systems (direct, index, pool).
37//! - Separation of low-level operations from higher-level safety.
38//! - Equillibrium in Queriable values maintained.
39
40// ===============================================================================
41// ``````````````````````````````````` IMPORTS ```````````````````````````````````
42// ===============================================================================
43
44// --- FRAME Suite ---
45use frame_suite::{assets::LazyBalance, commitment::*};
46
47// --- Substrate primitives ---
48use sp_runtime::{
49    traits::{CheckedAdd, CheckedSub},
50    ArithmeticError, DispatchError, DispatchResult,
51};
52
53// ===============================================================================
54// ```````````````````````````````` COMMIT BALANCE ```````````````````````````````
55// ===============================================================================
56
57/// Provides low-level balance management and reconciliation behavior
58/// for [`Commitment`] systems.
59///
60/// Commitment frameworks often employ *unbalanced fungible traits* rather than
61/// automatically balanced ones. This enables explicit safety enforcement and
62/// auditability by requiring all balance mismatches to be resolved intentionally
63/// rather than implicitly.  
64///
65/// This trait defines how those imbalances and balance adjustments should be
66/// handled consistently across the system.
67///
68/// It only defines **low-level, unchecked operations** - callers are
69/// responsible for ensuring validity and equilibrium before invoking this
70/// function.
71///
72/// ### Generics
73/// - **Proprietor** - the entity (e.g. account, vault, or manager) owning
74///   or controlling the underlying asset balance.
75/// - **Pallet** - the pallet public struct which implements [`Commitment`] traits
76///   for consumer pallet usage, and provides the required commitment abstraction.
77/// - The implementing `Pallet` **must provide [`LazyBalance`]** with guarantees
78///   that all balance operations remain consistent with the commitment system's
79///   underlying asset accounting.
80pub trait CommitBalance<Proprietor, Pallet>
81where
82    Pallet: LazyBalance<Asset = <Pallet as InspectAsset<Proprietor>>::Asset>
83        + InspectAsset<Proprietor>
84        + Commitment<Proprietor>,
85{
86    /// The imbalance type representing the difference between deposits and withdrawals.
87    type Imbalance;
88
89    /// Resolves an imbalance in a proprietor's committed balance.
90    ///
91    /// Used when a digest's value adjustment causes a mismatch in
92    /// deposited versus withdrawn amounts.  
93    ///
94    /// Ensures the underlying asset accounting remains correct by minting,
95    /// burning, or otherwise reconciling the imbalance.
96    ///
97    /// It only defines **low-level, unchecked operations** - callers are
98    /// responsible for ensuring validity and equilibrium before invoking this
99    /// function.
100    ///
101    /// ## Returns
102    /// - `Ok(Asset)` containing the final balanced value
103    /// - `Err(DispatchError)` if reconciliation fails
104    fn resolve_imbalance(
105        who: &Proprietor,
106        imbalance: Self::Imbalance,
107    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
108
109    /// Deducts a specified asset value from the proprietor's available balance.
110    ///
111    /// This function deducts the requested amount according to the given
112    /// qualifier - exactness or best effort along with force rules to
113    /// determine whether and how the deduction should proceed.
114    ///
115    /// It only defines **low-level, unchecked operations** - callers are
116    /// responsible for ensuring validity and equilibrium before invoking this
117    /// function.
118    ///
119    /// ## Returns
120    /// - `Ok(Asset)` containing the actual deducted value
121    /// - `Err(DispatchError)` if the deduction fails
122    fn deduct_balance(
123        who: &Proprietor,
124        value: <Pallet as InspectAsset<Proprietor>>::Asset,
125        qualifier: &Pallet::Intent,
126    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
127
128    /// Deducts a specified asset value from a imbalance (effectively mutating it).
129    ///
130    /// This function deducts the exact amount, maintains equillibrium and
131    /// returns another imbalance - to be resolved (typically by [`Self::resolve_imbalance`]).
132    ///
133    /// This provides extracting new-imbalances from existing imbalances safely.
134    ///
135    /// It only defines **low-level, unchecked operations** - callers are
136    /// responsible for ensuring validity and equilibrium before invoking this
137    /// function.
138    ///
139    /// ## Returns
140    /// - `Ok(Imbalance)` containing the new imbalance
141    /// - `Err(DispatchError)` if the deduction fails
142    fn deduct_from_imbalance(
143        imbalance: &mut Self::Imbalance,
144        value: <Pallet as InspectAsset<Proprietor>>::Asset,
145    ) -> Result<Self::Imbalance, DispatchError>;
146}
147
148// ===============================================================================
149// ```````````````````````````````` COMMIT DEPOSIT ```````````````````````````````
150// ===============================================================================
151
152/// Provides low-level deposit operations for commitment systems, enabling assets
153/// to be recorded against digests, indexes, and pools for a given proprietor.
154///
155/// This trait focuses solely on **recording deposits** within the system. It does **not**
156/// handle balance deductions, freezing funds, or higher-level commit management - those
157/// responsibilities are delegated to upper layers of the [`Commitment`] framework.
158///
159/// It only defines **low-level, unchecked operations** - callers are
160/// responsible for ensuring validity and equilibrium before invoking these
161/// functions.
162///
163/// ### Generics
164/// - **Proprietor** - the entity (e.g. account, vault, or manager)
165/// controlling the asset.
166/// - **Pallet** - the public struct implementing [`Commitment`] traits
167/// and [`LazyBalance`], ensuring consistent asset accounting across the
168/// commitment system.
169pub trait CommitDeposit<Proprietor, Pallet>
170where
171    Pallet: LazyBalance<
172            Asset = <Pallet as InspectAsset<Proprietor>>::Asset,
173            Variant = Pallet::Position,
174            Id = Pallet::Digest,
175        > + DigestModel<Proprietor>
176        + CommitVariant<Proprietor>,
177{
178    /// Type representing a "Receipt" of the deposit towards the
179    /// digest (direct) at the time of commitment.
180    ///
181    /// A receipt acts as a claimable bill over the digest's balance,
182    /// capturing the state at the time of commitment. This allows
183    /// commitments to be resolved accurately later, even if the
184    /// underlying balance changes.
185    ///
186    /// Effectively serves as a versioned claim tied to a specific
187    /// commitment.
188    type Receipt;
189
190    /// Deposits a value to a fully resolved/wrapped digest model and it's
191    /// specified balance variant.
192    ///
193    /// This function assumes the digest has already been resolved and wrapped
194    /// appropriately, so it directly handles the act of **only depositing**
195    /// the given value under the specified reason.
196    ///
197    /// This is a **low-level** function that only records the deposit to the
198    /// digest model. It does **not** perform balance deductions or handle
199    /// commit-level operations such as freezing funds or storing commitment
200    /// records. Any such logic must be handled at a higher level.
201    ///
202    /// Some digests such as indexes and pools may not require a `variant`, yet
203    /// direct requires it, so its kept reagrdless and the caller must acknowledge
204    /// that.
205    ///
206    /// ## Returns
207    /// - `Ok((Receipt, Asset))` containing the deposit's state and the
208    /// actual deposit value.
209    /// - `Err(DispatchError)` if the deposit fails
210    fn deposit_to(
211        who: &Proprietor,
212        reason: &Pallet::Reason,
213        digest_model: &Pallet::Model,
214        value: <Pallet as InspectAsset<Proprietor>>::Asset,
215        variant: &Pallet::Position,
216        qualifier: &Pallet::Intent,
217    ) -> Result<(Self::Receipt, <Pallet as InspectAsset<Proprietor>>::Asset), DispatchError>;
218
219    /// Deposits a committed asset into a given digest of variant for
220    /// a specified reason.
221    ///
222    /// This is a **low-level** function that only records the deposit to
223    /// the digest. It does **not** perform balance deductions or handle
224    /// commit-level operations such as freezing funds or storing commitment
225    /// records. Any such logic must be handled at a higher level.
226    ///
227    /// ## Returns
228    /// - `Ok((Receipt, Asset))` containing the deposit's state and the
229    /// actual deposit value.
230    /// - `Err(DispatchError)` if the deposit fails
231    fn deposit_to_digest(
232        who: &Proprietor,
233        reason: &Pallet::Reason,
234        digest: &Pallet::Digest,
235        value: <Pallet as InspectAsset<Proprietor>>::Asset,
236        variant: &Pallet::Position,
237        qualifier: &Pallet::Intent,
238    ) -> Result<(Self::Receipt, <Pallet as InspectAsset<Proprietor>>::Asset), DispatchError>;
239
240    /// Deposits a committed asset into a given index for a specified reason.
241    ///
242    /// This is a **low-level** function that only records the deposit to the index.
243    /// It does **not** perform balance deductions or handle commit-level operations
244    /// such as freezing funds or storing commitment records.  
245    /// Any such logic must be handled at a higher level.
246    ///
247    /// ## Returns
248    /// - `Ok((Receipt, Asset))` containing the deposit's state and the
249    /// actual deposit value.
250    /// - `Err(DispatchError)` if the deposit fails
251    fn deposit_to_index(
252        who: &Proprietor,
253        reason: &Pallet::Reason,
254        index_of: &Pallet::Digest,
255        value: <Pallet as InspectAsset<Proprietor>>::Asset,
256        variant: &Pallet::Position,
257        qualifier: &Pallet::Intent,
258    ) -> Result<(Self::Receipt, <Pallet as InspectAsset<Proprietor>>::Asset), DispatchError>;
259
260    /// Deposits a committed asset into a given pool of a variant for a specified reason.
261    ///
262    /// This is a **low-level** function that only records the deposit to the pool.
263    /// It does **not** perform balance deductions or handle commit-level operations
264    /// such as freezing funds or storing commitment records.  
265    /// Any such logic must be handled at a higher level.
266    ///
267    /// ## Returns
268    /// - `Ok((Receipt, Asset))` containing the deposit's state and the
269    /// actual deposit value.
270    /// - `Err(DispatchError)` if the deposit fails
271    fn deposit_to_pool(
272        who: &Proprietor,
273        reason: &Pallet::Reason,
274        pool_of: &Pallet::Digest,
275        value: <Pallet as InspectAsset<Proprietor>>::Asset,
276        variant: &Pallet::Position,
277        qualifier: &Pallet::Intent,
278    ) -> Result<(Self::Receipt, <Pallet as InspectAsset<Proprietor>>::Asset), DispatchError>;
279}
280
281// ===============================================================================
282// ```````````````````````````````` COMMIT WITHDRAW ``````````````````````````````
283// ===============================================================================
284
285/// Provides low-level withdrawal operations for commitment systems, enabling proprietors
286/// to extract committed assets from digests, indexes, and pools for a given reason.
287///
288/// This trait focuses solely on **withdrawing committed values**. It does **not**
289/// handle higher-level operations such as unfreezing funds, updating commitment records,
290/// or enforcing variant rules - those responsibilities are delegated to upper layers
291/// of the [`Commitment`] framework.
292///
293/// It only defines **low-level, unchecked operations** - callers are
294/// responsible for ensuring validity and equilibrium before invoking these
295/// functions.
296///
297/// ### Generics
298/// - **Proprietor** - the entity (e.g. account, vault, or manager)
299/// controlling the asset.
300/// - **Pallet** - the public struct implementing [`Commitment`] traits
301/// and [`LazyBalance`], ensuring consistent asset accounting across the
302/// commitment system.
303pub trait CommitWithdraw<Proprietor, Pallet>: CommitBalance<Proprietor, Pallet>
304where
305    Pallet: LazyBalance<
306            Asset = <Pallet as InspectAsset<Proprietor>>::Asset,
307            Variant = Pallet::Position,
308            Id = Pallet::Digest,
309        > + DigestModel<Proprietor>
310        + CommitVariant<Proprietor>,
311{
312    /// Withdraws the proprietor's value of a commitment done to a resolved/wrapped
313    /// digest model for a given reason.
314    ///
315    /// This function assumes the digest has already been resolved and wrapped appropriately,
316    /// so it directly handles the act of **only withdrawing** its total committed value
317    /// under the specified reason.
318    ///
319    /// This is a **low-level** function that only withdraws to the given proprietor.
320    /// It does **not** perform commit-level operations such as unfreezing funds or
321    /// updating commitment records, nor variant validation.  
322    /// Any such logic must be handled at a higher level.
323    ///
324    /// ## Returns
325    /// - `Ok(Imbalance)` containing the withdrawal imbalance
326    /// - `Err(DispatchError)` if the withdrawal fails
327    fn withdraw_for(
328        who: &Proprietor,
329        reason: &Pallet::Reason,
330        digest_model: &Pallet::Model,
331        variant: &Pallet::Position,
332    ) -> Result<Self::Imbalance, DispatchError>;
333
334    /// Withdraws the proprietor's value of a commitment to the given digest
335    /// of variant for a specified reason.
336    ///
337    /// This is a **low-level** function that only withdraws to the given proprietor.
338    /// It does **not** perform commit-level operations such as unfreezing funds or
339    /// updating commitment records.  
340    /// Any such logic must be handled at a higher level.
341    ///
342    /// ## Returns
343    /// - `Ok(Imbalance)` containing the withdrawal imbalance
344    /// - `Err(DispatchError)` if the withdrawal fails
345    fn withdraw_from_digest(
346        who: &Proprietor,
347        reason: &Pallet::Reason,
348        digest: &Pallet::Digest,
349        variant: &Pallet::Position,
350    ) -> Result<Self::Imbalance, DispatchError>;
351
352    /// Withdraws the proprietor's value of a commitment to the given index
353    /// digest of variant for a specified reason.
354    ///
355    /// This is a **low-level** function that only withdraws to the given proprietor.
356    /// It does **not** perform commit-level operations such as unfreezing funds or
357    /// updating commitment records.  
358    /// Any such logic must be handled at a higher level.
359    ///
360    /// ## Returns
361    /// - `Ok(Imbalance)` containing the withdrawal imbalance
362    /// - `Err(DispatchError)` if the withdrawal fails
363    fn withdraw_from_index(
364        who: &Proprietor,
365        reason: &Pallet::Reason,
366        index_of: &Pallet::Digest,
367        variant: &Pallet::Position,
368    ) -> Result<Self::Imbalance, DispatchError>;
369
370    /// Withdraws the proprietor's value of a commitment to the given pool digest of variant
371    /// for a specified reason.
372    ///
373    /// This is a **low-level** function that only withdraws to the given proprietor.
374    /// It does **not** perform commit-level operations such as unfreezing funds or
375    /// updating commitment records.  
376    /// Any such logic must be handled at a higher level.
377    ///
378    /// ## Returns
379    /// - `Ok(Imbalance)` containing the withdrawal imbalance
380    /// - `Err(DispatchError)` if the withdrawal fails
381    fn withdraw_from_pool(
382        who: &Proprietor,
383        reason: &Pallet::Reason,
384        pool_of: &Pallet::Digest,
385        variant: &Pallet::Position,
386    ) -> Result<Self::Imbalance, DispatchError>;
387}
388
389// ===============================================================================
390// ``````````````````````````````` COMMIT OPERATIONS `````````````````````````````
391// ===============================================================================
392
393/// Defines the core operations for managing commitments within digest models.
394///
395/// This trait provides a unified interface for placing, raising, and resolving
396/// commitments across all digest variants - direct, index, and pool.
397///
398/// This trait defines **low-level, unchecked operations** - callers are
399/// responsible for ensuring validity and equilibrium before invoking these
400/// functions.
401///
402/// ### Generics
403/// - **Proprietor** - the entity (e.g. account, vault, or manager)
404/// controlling the asset.
405/// - **Pallet** - the public struct implementing [`Commitment`] traits
406/// and [`LazyBalance`], ensuring consistent asset accounting across the
407/// commitment system.
408pub trait CommitOps<Proprietor, Pallet>
409where
410    Pallet: LazyBalance<
411            Asset = <Pallet as InspectAsset<Proprietor>>::Asset,
412            Variant = Pallet::Position,
413            Id = Pallet::Digest,
414        > + DigestModel<Proprietor>
415        + CommitVariant<Proprietor>,
416{
417    /// Places a commitment using a fully resolved/wrapped digest model and
418    /// a specified digest's balance variant.
419    ///
420    /// This function assumes the digest has already been found-valid and wrapped
421    /// appropriately, so it directly handles the act of **only committing** the
422    /// given value under the specified reason.
423    ///
424    /// It only defines **low-level, unchecked operations** - callers are
425    /// responsible for ensuring validity and equilibrium before invoking this
426    /// function.
427    ///
428    /// ## Returns
429    /// - `Ok(Asset)` containing the committed amount
430    /// - `Err(DispatchError)` if the commitment fails
431    fn place_commit_of(
432        who: &Proprietor,
433        reason: &Pallet::Reason,
434        digest_model: &Pallet::Model,
435        value: <Pallet as InspectAsset<Proprietor>>::Asset,
436        variant: &Pallet::Position,
437        qualifier: &Pallet::Intent,
438    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
439
440    /// Places a commitment for a **direct digest** under a given reason and variant.
441    ///
442    /// This function handles the placement of a commitment when the digest is a
443    /// valid, single, direct item (not an index or pool). It records the committed
444    /// value associated with the specific reason and digest, respecting the
445    /// commitment rules.
446    ///
447    /// It only defines **low-level, unchecked operations** - callers are
448    /// responsible for ensuring validity and equilibrium before invoking this
449    /// function.
450    ///
451    /// ## Returns
452    /// - `Ok(Asset)` containing the committed amount
453    /// - `Err(DispatchError)` if the commitment fails
454    fn place_digest_commit(
455        who: &Proprietor,
456        reason: &Pallet::Reason,
457        digest: &Pallet::Digest,
458        value: <Pallet as InspectAsset<Proprietor>>::Asset,
459        variant: &Pallet::Position,
460        qualifier: &Pallet::Intent,
461    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
462
463    /// Places a commitment for a **index digest** under a given reason
464    /// and variant.
465    ///
466    /// This function handles the placement of a commitment when the digest
467    /// is a index. It records the committed value associated respecting
468    /// the commitment rules - "One Reason, One Digest Commit" and uses high
469    /// level structures to bypass it safely.
470    ///
471    /// It only defines **low-level, unchecked operations** - callers are
472    /// responsible for ensuring validity and equilibrium before invoking this
473    /// function.
474    ///
475    /// ## Returns
476    /// - `Ok(Asset)` containing the committed amount
477    /// - `Err(DispatchError)` if the commitment fails
478    fn place_index_commit(
479        who: &Proprietor,
480        reason: &Pallet::Reason,
481        index_of: &Pallet::Digest,
482        value: <Pallet as InspectAsset<Proprietor>>::Asset,
483        variant: &Pallet::Position,
484        qualifier: &Pallet::Intent,
485    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
486
487    /// Places a commitment for a **pool digest** under a given
488    /// reason and variant.
489    ///
490    /// This function handles the placement of a commitment when
491    /// the digest is a pool. It records the committed value associated
492    /// respecting the commitment rules- "One Reason, One Digest Commit"
493    /// and uses high level structures to bypass it safely.
494    ///
495    /// It only defines **low-level, unchecked operations** - callers are
496    /// responsible for ensuring validity and equilibrium before invoking this
497    /// function.
498    ///
499    /// ## Returns
500    /// - `Ok(Asset)` containing the committed amount
501    /// - `Err(DispatchError)` if the commitment fails
502    fn place_pool_commit(
503        who: &Proprietor,
504        reason: &Pallet::Reason,
505        pool_of: &Pallet::Digest,
506        value: <Pallet as InspectAsset<Proprietor>>::Asset,
507        variant: &Pallet::Position,
508        qualifier: &Pallet::Intent,
509    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
510
511    /// Raises an existing commitment by adding a new commitment
512    /// instance.
513    ///
514    /// Commitments are immutable; each raise adds a new commit
515    /// instance - by shareing semantics with existing commit of the reason.
516    /// How accumulation is handled depends on the context: direct digest,
517    /// index, or pool.
518    ///
519    /// It only defines **low-level, unchecked operations** - callers are
520    /// responsible for ensuring validity and equilibrium before invoking this
521    /// function.
522    ///
523    /// ## Returns
524    /// - `Ok(Asset)` containing the raised amount
525    /// - `Err(DispatchError)` if the raise operation fails
526    fn raise_commit_of(
527        who: &Proprietor,
528        reason: &Pallet::Reason,
529        digest_model: &Pallet::Model,
530        value: <Pallet as InspectAsset<Proprietor>>::Asset,
531        qualifier: &Pallet::Intent,
532    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
533
534    /// Adds a new instance of a commitment for a direct digest.
535    ///
536    /// Commitments are immutable and cannot be changed once created. This
537    /// enforces invariants by adding new commit instances to the same
538    /// digest and reason.
539    ///
540    /// It only defines **low-level, unchecked operations** - callers are
541    /// responsible for ensuring validity and equilibrium before invoking this
542    /// function.
543    ///
544    /// ## Returns
545    /// - `Ok(Asset)` containing the raised amount
546    /// - `Err(DispatchError)` if the raise operation fails
547    fn raise_digest_commit(
548        who: &Proprietor,
549        reason: &Pallet::Reason,
550        digest: &Pallet::Digest,
551        value: <Pallet as InspectAsset<Proprietor>>::Asset,
552        qualifier: &Pallet::Intent,
553    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
554
555    /// Adds a new instance of a commitment for an index digest.
556    ///
557    /// Commitments are immutable and cannot be changed once created. This
558    /// enforces invariants by adding new commit instances to the same
559    /// index digest and reason.
560    ///
561    /// It only defines **low-level, unchecked operations** - callers are
562    /// responsible for ensuring validity and equilibrium before invoking this
563    /// function.
564    ///
565    /// ## Returns
566    /// - `Ok(Asset)` containing the raised amount
567    /// - `Err(DispatchError)` if the raise operation fails
568    fn raise_index_commit(
569        who: &Proprietor,
570        reason: &Pallet::Reason,
571        index_of: &Pallet::Digest,
572        value: <Pallet as InspectAsset<Proprietor>>::Asset,
573        qualifier: &Pallet::Intent,
574    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
575
576    /// Adds a new instance of a commitment for a pool digest.
577    ///
578    /// The pool should release and recover itself, adding the raised value.
579    /// It may also record instances of commits for the proprietor to the pool rather
580    /// than to its slot digest, since it collectively manages funds for commitments by
581    /// the pool itself acting like a pseudo-proprietor.
582    ///
583    /// It only defines **low-level, unchecked operations** - callers are
584    /// responsible for ensuring validity and equilibrium before invoking this
585    /// function.
586    ///
587    /// ## Returns
588    /// - `Ok(Asset)` containing the raised amount
589    /// - `Err(DispatchError)` if the raise operation fails
590    fn raise_pool_commit(
591        who: &Proprietor,
592        reason: &Pallet::Reason,
593        pool_of: &Pallet::Digest,
594        value: <Pallet as InspectAsset<Proprietor>>::Asset,
595        qualifier: &Pallet::Intent,
596    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
597
598    /// Resolves and finalizes a commitment for a fully resolved digest model.
599    ///
600    /// This method closes the commitment and provides the final withdrawn asset value
601    /// from the commitment to the reason.
602    ///
603    /// It only defines **low-level, unchecked operations** - callers are
604    /// responsible for ensuring validity and equilibrium before invoking this
605    /// function.
606    ///
607    /// ## Returns
608    /// - `Ok(Asset)` containing the resolved commitment value
609    /// - `Err(DispatchError)` if resolution fails
610    fn resolve_commit_of(
611        who: &Proprietor,
612        reason: &Pallet::Reason,
613        digest_model: &Pallet::Model,
614    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
615
616    /// Resolves and finalizes a commitment for a direct digest.
617    ///
618    /// This method closes the direct digest commitment and provides the
619    /// final withdrawn asset value from the commitment to the reason.
620    ///
621    /// It only defines **low-level, unchecked operations** - callers are
622    /// responsible for ensuring validity and equilibrium before invoking this
623    /// function.
624    ///
625    /// ## Returns
626    /// - `Ok(Asset)` containing the resolved commitment value
627    /// - `Err(DispatchError)` if resolution fails
628    fn resolve_digest_commit(
629        who: &Proprietor,
630        reason: &Pallet::Reason,
631        digest: &Pallet::Digest,
632    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
633
634    /// Resolves and finalizes a commitment for an index digest.
635    ///
636    /// This method closes the index digest commitment and provides the
637    /// final withdrawn asset value from the commitment to the reason.
638    ///
639    /// It only defines **low-level, unchecked operations** - callers are
640    /// responsible for ensuring validity and equilibrium before invoking this
641    /// function.
642    ///
643    /// ## Returns
644    /// - `Ok(Asset)` containing the resolved commitment value
645    /// - `Err(DispatchError)` if resolution fails
646    fn resolve_index_commit(
647        who: &Proprietor,
648        reason: &Pallet::Reason,
649        index_of: &Pallet::Digest,
650    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
651
652    /// Resolves and finalizes a commitment for a pool digest.
653    ///
654    /// This method closes the pool digest commitment and provides the
655    /// final withdrawn asset value from the commitment to the reason.
656    ///
657    /// It only defines **low-level, unchecked operations** - callers are
658    /// responsible for ensuring validity and equilibrium before invoking this
659    /// function.
660    ///
661    /// ## Returns
662    /// - `Ok(Asset)` containing the resolved commitment value
663    /// - `Err(DispatchError)` if resolution fails
664    fn resolve_pool_commit(
665        who: &Proprietor,
666        reason: &Pallet::Reason,
667        pool_of: &Pallet::Digest,
668    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
669
670    /// Sets the total asset value for a given reason.
671    ///
672    /// This is a **low-level function** and should only be used
673    /// when equilibrium is maintained, meaning the value being set must
674    /// correctly reflect the committed state of the system for the reason.
675    fn set_total_value(reason: &Pallet::Reason, value: <Pallet as InspectAsset<Proprietor>>::Asset);
676
677    /// Adds a given asset value to the total value for the specified reason.
678    ///
679    /// It only defines **low-level, unchecked operations** - callers are
680    /// responsible for ensuring validity and equilibrium before invoking this
681    /// function.
682    ///
683    /// ## Returns
684    /// - `Ok(())` if the addition succeeds
685    /// - `Err(DispatchError)` with `Overflow` if adding causes overflow
686    fn add_to_total_value(
687        reason: &Pallet::Reason,
688        value: <Pallet as InspectAsset<Proprietor>>::Asset,
689    ) -> DispatchResult {
690        let current = Pallet::get_total_value(reason);
691        let new_total = current
692            .checked_add(&value)
693            .ok_or(DispatchError::Arithmetic(ArithmeticError::Overflow))?;
694
695        Self::set_total_value(reason, new_total);
696        Ok(())
697    }
698
699    /// Subtracts a given asset value from the total value for the
700    /// specified reason.
701    ///
702    /// It only defines **low-level, unchecked operations** - callers are
703    /// responsible for ensuring validity and equilibrium before invoking
704    /// this function.
705    ///
706    /// ### Returns
707    /// - `Ok(())` if the subtraction succeeds
708    /// - `Err(DispatchError)` with `Underflow` if subtraction would
709    /// underflow
710    fn sub_from_total_value(
711        reason: &Pallet::Reason,
712        value: <Pallet as InspectAsset<Proprietor>>::Asset,
713    ) -> DispatchResult {
714        let current = Pallet::get_total_value(reason);
715        let new_total = current
716            .checked_sub(&value)
717            .ok_or(DispatchError::Arithmetic(ArithmeticError::Underflow))?;
718
719        Self::set_total_value(reason, new_total);
720        Ok(())
721    }
722}
723
724// ===============================================================================
725// ```````````````````````````````` COMMIT INSPECT ```````````````````````````````
726// ===============================================================================
727
728/// Provides inspection and querying capabilities for committed
729/// values across digests, indexes, and pools for a given proprietor.
730///
731/// This trait allows retrieving **real-time committed values** without
732/// altering state, supporting precise accounting and auditability.
733///
734/// This trait defines **low-level, unchecked operations** - callers are
735/// responsible for ensuring validity and equilibrium before invoking these
736/// functions.
737///
738/// ### Generics
739/// - **Proprietor** - the entity (e.g. account, vault, or manager)
740/// controlling the asset.
741/// - **Pallet** - the public struct implementing [`Commitment`] traits
742/// and [`LazyBalance`], ensuring consistent asset accounting across the
743/// commitment system.
744pub trait CommitInspect<Proprietor, Pallet>
745where
746    Pallet: LazyBalance<Asset = <Pallet as InspectAsset<Proprietor>>::Asset, Id = Pallet::Digest>
747        + DigestModel<Proprietor>
748        + Commitment<Proprietor>,
749{
750    /// Retrieves the real-time commitment value for a fully
751    /// resolved digest model.
752    ///
753    /// Aggregates all individual commit instances associated with
754    /// the digest model for the given proprietor and reason,
755    /// returning a single live value.
756    ///
757    /// ## Returns
758    /// - `Ok(Asset)` containing the total committed value for the digest model
759    /// - `Err(DispatchError)` if the value cannot be determined
760    fn commit_value_of(
761        who: &Proprietor,
762        reason: &Pallet::Reason,
763        digest_model: &Pallet::Model,
764    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
765
766    /// Retrieves the real-time commitment value for a direct digest.
767    ///
768    /// Returns the total value proprietor commit holds under the given
769    /// reason for the direct digest.
770    ///
771    /// ## Returns
772    /// - `Ok(Asset)` containing the committed value for the digest
773    /// - `Err(DispatchError)` if value cannot be retrieved
774    fn digest_commit_value(
775        who: &Proprietor,
776        reason: &Pallet::Reason,
777        digest: &Pallet::Digest,
778    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
779
780    /// Retrieves the real-time commitment value for an index digest.
781    ///
782    /// Computes the aggregate value across all entries contained
783    /// in the index for the specified proprietor and reason.
784    ///
785    /// ## Returns
786    /// - `Ok(Asset)` containing the total committed value across
787    /// all index entries
788    /// - `Err(DispatchError)` if value cannot be calculated
789    fn index_commit_value(
790        who: &Proprietor,
791        reason: &Pallet::Reason,
792        index_of: &Pallet::Digest,
793    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
794
795    /// Retrieves the real-time commitment value for a specific
796    /// entry within an index.
797    ///
798    /// Provides the real-time value for a single entry digest within
799    /// the index, reflecting the proprietor's commitment to that
800    /// specific entry.
801    ///
802    /// ## Returns
803    /// - `Ok(Asset)` containing the committed value for the entry
804    /// - `Err(DispatchError)` if value cannot be retrieved
805    fn index_entry_commit_value(
806        who: &Proprietor,
807        reason: &Pallet::Reason,
808        index_of: &Pallet::Digest,
809        entry_of: &Pallet::Digest,
810    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
811
812    /// Retrieves the real-time commitment value for
813    /// a **pool digest**.
814    ///
815    /// Aggregates the values of all slots under the pool for
816    /// the proprietor.
817    ///
818    /// ## Returns
819    /// - `Ok(Asset)` containing the total committed value
820    /// across all pool slots
821    /// - `Err(DispatchError)` if value cannot be calculated
822    fn pool_commit_value(
823        who: &Proprietor,
824        reason: &Pallet::Reason,
825        pool_of: &Pallet::Digest,
826    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
827
828    /// Retrieves the committed value of a specific slot for a
829    /// particular proprietor.
830    ///
831    /// Aggregates the proprietor's commitment to that slot within the
832    /// pool in real-time, showing their individual exposure to the slot.
833    ///
834    /// ### Returns
835    /// - `Ok(Asset)` containing the proprietor's committed value for the slot
836    /// - `Err(DispatchError)` if the slot does not exist or value cannot be
837    /// retrieved
838    fn pool_slot_commit_value(
839        who: &Proprietor,
840        reason: &Pallet::Reason,
841        pool_of: &Pallet::Digest,
842        slot_of: &Pallet::Digest,
843    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
844
845    /// Queries the real-time value of commitments for a given reason.
846    ///
847    /// This function calculates the current committed value based on the
848    /// provided parameters:
849    /// - If `digest_model` is provided, only values associated with that specific
850    /// digest model are included
851    /// - If `digest_model` is `None`, the total value across all relevant digests
852    /// for the reason is returned
853    ///
854    /// ## Returns
855    /// - `Ok(Asset)` containing the calculated total asset value
856    /// - `Err(DispatchError)` if the query fails or the value cannot be determined
857    fn value_of(
858        digest_model: Option<&Pallet::Model>,
859        reason: &Pallet::Reason,
860    ) -> Result<<Pallet as InspectAsset<Proprietor>>::Asset, DispatchError>;
861}
862
863// ===============================================================================
864// ``````````````````````````````` POOL OPERATIONS ```````````````````````````````
865// ===============================================================================
866
867/// Defines operational behavior for managing pooled balances within a commitment system.
868///
869/// A `PoolOps` implementation extends [`PoolVariant`] to provide concrete
870/// management logic for a proprietor's pooled balances, where a pool may act
871/// as a *single committing authority* maintaining aggregate or managed funds.
872///
873/// Unlike indexes (which represent discrete digests committed on behalf of a proprietor),
874/// pools aggregate balances and resolve them collectively, acting as a unified
875/// resource manager.
876///
877/// This trait defines **low-level, unchecked operations** - callers are
878/// responsible for ensuring validity and equilibrium before invoking these
879/// functions.
880///
881/// ### Generics
882/// - **Proprietor** - the entity (e.g. account, vault, or manager)
883/// controlling the asset.
884/// - **Pallet** - the public struct implementing [`Commitment`] traits
885/// and [`LazyBalance`], ensuring consistent asset accounting across the
886/// commitment system.
887pub trait PoolOps<Proprietor, Pallet>
888where
889    Pallet: LazyBalance<
890            Asset = <Pallet as InspectAsset<Proprietor>>::Asset,
891            Variant = Pallet::Position,
892            Id = Pallet::Digest,
893        > + PoolVariant<Proprietor>,
894{
895    /// The balance type associated with the pool.
896    type PoolBalance;
897
898    /// Releases a pool's balance, resetting it to its default state.
899    ///
900    /// Releasing a pool means resolving all active commit digests from this single balance,
901    /// similar in concept to resolving a commit.
902    ///
903    /// - The release-recovery should be **immediate** at the calling site - safety must
904    /// be ensured by the caller.
905    /// - Pools differ from indexes: while indexes resolve multiple digests per proprietor,
906    ///   pools resolve from a *single managed balance* representing aggregated commitments.
907    ///
908    /// It only defines **low-level, unchecked operations** - callers are
909    /// responsible for ensuring validity and equilibrium before invoking this
910    /// function.
911    ///
912    /// ## Returns
913    /// - `Ok(PoolBalance)` containing the resolved pool balance
914    /// - `Err(DispatchError)` if the release operation fails
915    fn release_pool(
916        reason: &Pallet::Reason,
917        pool_of: &Pallet::Digest,
918    ) -> Result<Self::PoolBalance, DispatchError>;
919
920    /// Recovers a pool's state after a prior release via [`PoolOps::release_pool`].
921    ///
922    /// This function restores the pool's state following balance mutation or reconciliation.
923    /// Should only be invoked after the pool has been released via [`PoolOps::release_pool`].
924    ///
925    /// It only defines **low-level, unchecked operations** - callers are
926    /// responsible for ensuring validity and equilibrium before invoking this
927    /// function.
928    ///
929    /// ## Returns
930    /// - `Ok(())` if the pool state was successfully recovered
931    /// - `Err(DispatchError)` if recovery fails
932    fn recover_pool(
933        reason: &Pallet::Reason,
934        pool_of: &Pallet::Digest,
935        balance: &Self::PoolBalance,
936    ) -> DispatchResult;
937
938    /// Removes a slot from a pool and updates the pool's state accordingly.
939    ///
940    /// This operation ensures that:
941    /// - The slot represented by `slot_of` is removed from the pool.
942    /// - The pool's collective balance is released and then recovered to reflect
943    ///   the updated state after removal.
944    ///
945    /// Automatically updates the pool's internal representation of managed funds.
946    ///
947    /// It only defines **low-level, unchecked operations** - callers are
948    /// responsible for ensuring validity and equilibrium before invoking this
949    /// function.
950    ///
951    /// ### Returns
952    /// - `Ok(())` if the slot was successfully removed and pool state updated
953    /// - `Err(DispatchError)` if the operation fails
954    fn remove_pool_slot(
955        who: &Proprietor,
956        reason: &Pallet::Reason,
957        pool_of: &Pallet::Digest,
958        slot_of: &Pallet::Digest,
959    ) -> DispatchResult;
960
961    /// Sets or updates a slot within a pool and synchronizes the pool's state.
962    ///
963    /// This operation may:
964    /// - Add a new slot to the pool.
965    /// - Update an existing slot's `shares` or `variant`.
966    /// - Trigger a pool release and recovery cycle to ensure
967    ///   the pool's balance reflects the new slot configuration.
968    ///
969    /// It only defines **low-level, unchecked operations** - callers are
970    /// responsible for ensuring validity and equilibrium before invoking this
971    /// function.
972    ///
973    /// ## Behavior
974    /// - Ensures slot state consistency within the pool.
975    /// - Used for slot creation, update, or reallocation of pool shares.
976    ///
977    /// ### Returns
978    /// - `Ok(())` if the slot was successfully set and pool state synchronized
979    /// - `Err(DispatchError)` if the operation fails
980    fn set_pool_slot(
981        who: &Proprietor,
982        reason: &Pallet::Reason,
983        pool_of: &Pallet::Digest,
984        slot_of: &Pallet::Digest,
985        shares: Pallet::Shares,
986        variant: &Pallet::Position,
987    ) -> DispatchResult;
988}
989
990// ===============================================================================
991// ``````````````````````````````` INDEX OPERATIONS ``````````````````````````````
992// ===============================================================================
993
994/// Defines operational behavior for managing indexed digests within a commitment system.
995///
996/// An `IndexOps` implementation extends [`IndexVariant`] to provide concrete
997/// management logic for a proprietor's indexed commitments, where an index acts
998/// as a container of discrete digest entries.
999///
1000/// Unlike pools (which aggregate balances collectively), indexes represent
1001/// *structured groupings* of digests that can be individually set or removed,
1002/// allowing for fine-grained commit management.
1003///
1004/// This trait defines **low-level, unchecked operations** - callers are
1005/// responsible for ensuring validity and equilibrium before invoking these
1006/// functions.
1007///
1008/// ### Generics
1009/// - **Proprietor** - the entity (e.g. account, vault, or manager)
1010/// controlling the asset.
1011/// - **Pallet** - the public struct implementing [`Commitment`] traits
1012/// and [`LazyBalance`], ensuring consistent asset accounting across the
1013/// commitment system.
1014pub trait IndexOps<Proprietor, Pallet>
1015where
1016    Pallet: LazyBalance<
1017            Asset = <Pallet as InspectAsset<Proprietor>>::Asset,
1018            Variant = Pallet::Position,
1019            Id = Pallet::Digest,
1020        > + IndexVariant<Proprietor>,
1021{
1022    /// Removes a digest entry from an index for the given proprietor and reason.
1023    ///
1024    /// Since indexes are immutable, this operation creates a new index without
1025    /// the specified entry and generates a new digest for it. The caller is
1026    /// responsible for managing the lifecycle of the old index digest.
1027    ///
1028    /// This is a **low-level, unchecked operation** - callers must ensure
1029    /// equilibrium and invariant safety before calling.
1030    ///
1031    /// ## Returns
1032    /// - `Ok(Digest)` containing the new index digest after entry removal
1033    /// - `Err(DispatchError)` if the operation fails
1034    fn remove_index_entry(
1035        who: &Proprietor,
1036        reason: &Pallet::Reason,
1037        index_of: &Pallet::Digest,
1038        entry_of: &Pallet::Digest,
1039    ) -> Result<Pallet::Digest, DispatchError>;
1040
1041    /// Sets or updates a digest entry within an index and returns the new index digest.
1042    ///
1043    /// Since indexes are immutable, this operation creates a new index with the updated
1044    /// entry configuration (shares and variant) and generates a new digest for it.
1045    /// If the entry exists, it is updated; otherwise, it is added.
1046    ///
1047    /// This is a **low-level, unchecked operation** - callers must ensure
1048    /// equilibrium and invariant safety before calling.
1049    ///
1050    /// ## Returns
1051    /// - `Ok(Digest)` containing the new index digest after entry modification
1052    /// - `Err(DispatchError)` if the operation fails
1053    fn set_index_entry(
1054        who: &Proprietor,
1055        reason: &Pallet::Reason,
1056        index_of: &Pallet::Digest,
1057        entry_of: &Pallet::Digest,
1058        shares: Pallet::Shares,
1059        variant: &Pallet::Position,
1060    ) -> Result<Pallet::Digest, DispatchError>;
1061}