diff --git a/crates/aldabra-core/src/plutus_mint.rs b/crates/aldabra-core/src/plutus_mint.rs index 682e404..658d489 100644 --- a/crates/aldabra-core/src/plutus_mint.rs +++ b/crates/aldabra-core/src/plutus_mint.rs @@ -95,6 +95,16 @@ pub struct PlutusMintArgs<'a> { /// Optional inline datum on the recipient output. Required for /// any send to a Plutus script address. pub dest_inline_datum_cbor: Option<&'a [u8]>, + /// PKH hashes to add to the tx body's `required_signers` field. + /// On Babbage+, Plutus's `TxInfo.signatories` is populated ONLY + /// from `required_signers` — VKey witnesses alone are not enough + /// for any `pauthorizedBy` / `txSignedBy` check inside a script. + /// MCP layer always passes this wallet's payment-key pkh; pass + /// extra entries for cosigners. Empty slice = scripts that don't + /// check signatories (e.g. Agora's GST policy). + /// Caught 2026-05-07 on Agora's stake-policy bootstrap on preprod + /// — script erred because owner pkh was absent from signatories. + pub additional_signers: &'a [Hash<28>], } fn parse_address(bech32: &str) -> Result { @@ -586,6 +596,10 @@ fn prepare_plutus_mint( .fee(fee) .network_id(network_id); + for pkh in args.additional_signers { + staging = staging.disclosed_signer(*pkh); + } + // Plutus V1/V2/V3 each need their cost-model wired via // language_view so pallas computes script_data_hash on the tx // body. Without it, chain rejects with PPViewHashesDontMatch. @@ -785,6 +799,7 @@ mod tests { dest_lovelace: 3_000_000, dest_extra_assets: &[], dest_inline_datum_cbor: Some(&UNIT_DATUM_CBOR), + additional_signers: &[], }; let err = build_signed_plutus_mint( &payment, @@ -816,6 +831,7 @@ mod tests { dest_lovelace: 3_000_000, dest_extra_assets: &[], dest_inline_datum_cbor: Some(&UNIT_DATUM_CBOR), + additional_signers: &[], }; let err = build_signed_plutus_mint( &payment, @@ -857,6 +873,7 @@ mod tests { dest_lovelace: 3_000_000, dest_extra_assets: &[], dest_inline_datum_cbor: Some(&UNIT_DATUM_CBOR), + additional_signers: &[], }; let err = build_signed_plutus_mint( &payment, @@ -895,6 +912,7 @@ mod tests { dest_lovelace: 3_000_000, dest_extra_assets: &[], dest_inline_datum_cbor: Some(&UNIT_DATUM_CBOR), + additional_signers: &[], }; // V3 cost model is required for staging language_view; test // ProtocolParams::default() should provide one for preprod. diff --git a/crates/aldabra-mcp/src/tools.rs b/crates/aldabra-mcp/src/tools.rs index 727eba3..cb06d94 100644 --- a/crates/aldabra-mcp/src/tools.rs +++ b/crates/aldabra-mcp/src/tools.rs @@ -1654,6 +1654,8 @@ impl WalletService { } }; + let wallet_pkh = self.inner.payment_key.public_key_hash(); + let signers = [wallet_pkh]; let core_args = CorePlutusMintArgs { required_inputs: &required, policy_cbor: &policy_cbor, @@ -1665,6 +1667,7 @@ impl WalletService { dest_lovelace, dest_extra_assets: &core_extras, dest_inline_datum_cbor: datum_bytes.as_deref(), + additional_signers: &signers, }; let unsigned = build_unsigned_plutus_mint(