diff --git a/src/interface/contract.rs b/src/interface/contract.rs index 2f92e710..b19a9923 100644 --- a/src/interface/contract.rs +++ b/src/interface/contract.rs @@ -22,12 +22,13 @@ use std::borrow::Borrow; use std::collections::{BTreeSet, HashMap, HashSet}; +use amplify::Wrapper; use rgb::validation::Scripts; use rgb::{ AssignmentType, AttachId, ContractId, OpId, Opout, Schema, State, StateData, XOutputSeal, XWitnessId, STATE_DATA_MAX_LEN, }; -use strict_encoding::{FieldName, SerializeError}; +use strict_encoding::{FieldName, SerializeError, StrictDeserialize}; use strict_types::{typify, SemId, StrictVal, TypeSystem}; use crate::contract::{Allocation, WitnessInfo}; @@ -58,14 +59,27 @@ pub enum ContractError { derive(Serialize, Deserialize), serde(crate = "serde_crate", rename_all = "camelCase") )] -pub struct Output { +pub struct Output { pub opout: Opout, pub seal: XOutputSeal, - pub state: StrictVal, + pub state: T, pub attach_id: Option, pub witness: Option, } +impl From for Output { + fn from(a: Allocation) -> Self { + Output { + opout: a.opout, + seal: a.seal, + state: T::from_strict_serialized(a.state.data.to_inner()) + .expect("data in stash are not valid"), + attach_id: a.state.attach, + witness: a.witness, + } + } +} + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Display)] #[cfg_attr( feature = "serde", @@ -286,6 +300,19 @@ impl ContractIface { .map(|a| self.allocation_to_output(a))) } + pub fn outputs_typed<'c, T: StrictDeserialize + 'c>( + &'c self, + name: impl Into, + filter: impl AssignmentsFilter + 'c, + ) -> Result> + 'c, ContractError> { + let type_id = self.assignment_type(name)?; + Ok(self + .allocations(filter) + .filter(move |a| a.opout.ty == type_id) + .cloned() + .map(Output::from)) + } + pub fn history( &self, filter_outpoints: impl AssignmentsFilter,