feat(dao): scaffold aldabra-dao crate (Phase 1 reads)
Adds a 4th workspace crate `aldabra-dao` for native Agora-on-Cardano DAO interaction. Multi-DAO from day one — DaoConfig per DAO at \$ALDABRA_DATA/daos/<name>.json + .active selector. Sulkta DAO and any community Agora deployment (Bob's DAO, Alice's DAO) are first-class. Phase 0 type port complete: - StakeDatum, StakeRedeemer, ProposalAction, ProposalLock, Credential - ProposalDatum, ProposalRedeemer, ProposalStatus, ProposalThresholds, ProposalTimingConfig, ProposalVotes - GovernorDatum, GovernorRedeemer - All Constr indices verified against Agora source makeIsDataIndexed + EnumIsData declarations (Stake/Proposal/Governor/Action/Status all cross-referenced) - Round-trip tests for every type Phase 1 read surface (this commit): - DaoStore: DaoConfig load/save/list/remove + active-DAO selector with first-register-becomes-active UX. 8 unit tests. - DaoReader trait + KoiosDaoReader impl for get_governor + list_stakes. list_proposals stubbed pending Phase 4 proposal-script-address discovery. - Stake address sharing handled: list_stakes filters on gov_token_policy (the shared MLabs stakes addr serves many DAOs). Stubs for upcoming phases: - agora/treasury.rs (Phase 4 — treasury spend helpers) - agora/authority_token.rs (Phase 4 — GAT mint/burn) - agora/reference_scripts.rs (Phase 2/3 — independent script-hash discovery per Sulkta's choice 2026-05-05; computed locally, never trust MLabs registry) - builder/mod.rs (per-operation Plutus tx builders, populated phase-by-phase) Spec doc + decisions: internal notes in workspace. Effects map (`ProposalDatum.effects`) kept as raw PlutusData for round-trip integrity until Phase 4 (proposal create) needs typed access. ExUnits strategy locked: Koios tx_evaluate from day one (no hardcoded values). Wired up in Phase 2 alongside reference-script discovery.
This commit is contained in:
parent
0a658cc4de
commit
50658ea51b
15 changed files with 2018 additions and 3 deletions
52
crates/aldabra-dao/src/error.rs
Normal file
52
crates/aldabra-dao/src/error.rs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
//! Crate-wide error type.
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
/// Anything that can go wrong inside `aldabra-dao`.
|
||||
///
|
||||
/// Boundary rule: `DaoError` does NOT wrap `aldabra_core::WalletError` or
|
||||
/// `aldabra_chain::ChainError` directly — those sit at different layers.
|
||||
/// Convert to a [`DaoError::Backend`] string via the `?`-helper at call sites
|
||||
/// to keep the public error surface flat for MCP consumers.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DaoError {
|
||||
/// Per-DAO config file is missing, malformed, or names a DAO we don't have.
|
||||
#[error("dao config: {0}")]
|
||||
Config(String),
|
||||
|
||||
/// Bech32 / address parse failure.
|
||||
#[error("address: {0}")]
|
||||
Address(String),
|
||||
|
||||
/// PlutusData encode/decode failure — the on-chain datum didn't match
|
||||
/// the shape we expected.
|
||||
#[error("datum: {0}")]
|
||||
Datum(String),
|
||||
|
||||
/// CBOR encode/decode failure (lower-level than [`Self::Datum`]).
|
||||
#[error("cbor: {0}")]
|
||||
Cbor(String),
|
||||
|
||||
/// Backend (Koios / submit) returned an error.
|
||||
#[error("backend: {0}")]
|
||||
Backend(String),
|
||||
|
||||
/// We couldn't find a required reference-script UTxO on chain.
|
||||
#[error("reference script not found: {0}")]
|
||||
RefScript(String),
|
||||
|
||||
/// Caller asked for something the DAO can't provide right now (no active
|
||||
/// proposal, no stake registered, locked stake, etc).
|
||||
#[error("invalid state: {0}")]
|
||||
State(String),
|
||||
|
||||
/// I/O error against the DAO config dir or similar.
|
||||
#[error("io: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
/// JSON serialization failure for [`crate::config::DaoConfig`].
|
||||
#[error("json: {0}")]
|
||||
Json(#[from] serde_json::Error),
|
||||
}
|
||||
|
||||
pub type DaoResult<T> = Result<T, DaoError>;
|
||||
Loading…
Add table
Add a link
Reference in a new issue