feat(escrow_wip): MCP escrow spend-tool surface (deposit/agree/veto/settle/refund_timeout)
Five new MCP tools wrapping the four Plutus V3 spend builders shipped
earlier in this branch:
- escrow_deposit_unsigned → Deposit redeemer (continuing-output state)
- escrow_agree_unsigned → Agree redeemer (Open → Agreed{at=upper}, both sign)
- escrow_veto_unsigned → Veto redeemer (Agreed → multi-output refund)
- escrow_settle_unsigned → Settle redeemer (Agreed → recipient payout)
- escrow_refund_timeout_unsigned → Refund redeemer (Open after open_deadline → multi-output refund)
Each takes the existing escrow UTxO ref + lovelace + datum_cbor_hex
(caller pulls via chain_address_info), the V3 validator UPLC
(inline hex OR file-path to dodge the >4500-char MCP transport bug),
the redeemer-specific args, and fee_lovelace. Validity windows
default to 30 min from chain tip; agree's window auto-clamps to
open_deadline_ms when needed.
Helper additions:
- EscrowDatum::from_cbor_hex on aldabra-dao keeps pallas-codec /
pallas-primitives direct deps OUT of aldabra-mcp.
- decode_pkh28, resolve_validator_required, build_escrow_spend_in,
fetch_tip_slot_ms in tools.rs — small helpers shared by all 5
spend tools.
Drops the [features] section on aldabra-mcp's Cargo.toml. rmcp 0.1.5's
#[tool(tool_box)] macro scans the impl AST and references every
#[tool]-annotated method's generated wrapper regardless of cfg
eligibility — cfg-on-method gating fails to compile when the feature
is off because the macro emits unresolved symbol references. Pivot:
always-pull aldabra-dao/escrow_wip via the dep itself. The runtime
gate is the "WIP — UNAUDITED:" prefix in every tool description plus
the "wip_warning" field in JSON responses; the dao crate's escrow_wip
feature still gates downstream Rust consumers that want source-level
opt-out.
Verified: aldabra-mcp builds clean (default + release). 132 aldabra-
dao tests pass under --features escrow_wip including all 35 escrow
builder tests. Release binary produced.
This commit is contained in:
parent
54a90a5f8d
commit
ef38ff0e57
3 changed files with 606 additions and 12 deletions
|
|
@ -264,6 +264,29 @@ impl EscrowDatum {
|
|||
acc
|
||||
}
|
||||
|
||||
/// Decode an EscrowDatum from a hex-encoded CBOR string. The
|
||||
/// caller's source is typically the inline_datum field returned by
|
||||
/// `chain_address_info` / Koios. Whitespace is stripped before
|
||||
/// parsing.
|
||||
///
|
||||
/// Surfaced so MCP layers can stay free of pallas-codec /
|
||||
/// pallas-primitives direct deps — they pass hex through, this
|
||||
/// crate owns the decoding.
|
||||
pub fn from_cbor_hex(hex_str: &str) -> DaoResult<Self> {
|
||||
use pallas_codec::minicbor;
|
||||
use pallas_primitives::PlutusData;
|
||||
let cleaned: String = hex_str.chars().filter(|c| !c.is_whitespace()).collect();
|
||||
let bytes = hex::decode(&cleaned).map_err(|e| {
|
||||
DaoError::Datum(format!("EscrowDatum::from_cbor_hex hex decode: {e}"))
|
||||
})?;
|
||||
let pd: PlutusData = minicbor::decode(&bytes).map_err(|e| {
|
||||
DaoError::Datum(format!(
|
||||
"EscrowDatum::from_cbor_hex parse as PlutusData: {e}"
|
||||
))
|
||||
})?;
|
||||
Self::from_plutus_data(&pd)
|
||||
}
|
||||
|
||||
/// Look up a deposit entry by contributor PKH.
|
||||
pub fn deposit_for(&self, pkh: &[u8; PKH_LEN]) -> Option<&EscrowDeposit> {
|
||||
self.deposits.iter().find(|d| &d.contributor == pkh)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue