|
22 | 22 | use std::collections::{BTreeSet, HashSet};
|
23 | 23 | use std::ops::Deref;
|
24 | 24 |
|
25 |
| -use amplify::confinement::{LargeOrdMap, LargeVec, SmallVec}; |
| 25 | +use amplify::confinement::{LargeOrdMap, LargeVec, SmallVec, U16}; |
26 | 26 | use bp::Outpoint;
|
27 | 27 | use rgb::{
|
28 |
| - AssetTag, AssignmentType, AttachId, BlindingFactor, ContractId, ContractState, FungibleOutput, |
29 |
| - MediaType, RevealedAttach, RevealedData, WitnessId, XOutpoint, XOutputSeal, |
| 28 | + AssetTag, AssignmentType, AttachId, BlindingFactor, ContractId, ContractState, DataOutput, |
| 29 | + FungibleOutput, MediaType, RevealedAttach, RevealedData, WitnessId, XOutpoint, XOutputSeal, |
30 | 30 | };
|
31 |
| -use strict_encoding::FieldName; |
| 31 | +use strict_encoding::{FieldName, StrictDeserialize}; |
32 | 32 | use strict_types::typify::TypedVal;
|
33 | 33 | use strict_types::{decode, StrictVal};
|
34 | 34 |
|
| 35 | +use super::rgb21::Allocation; |
35 | 36 | use crate::interface::{IfaceId, IfaceImpl};
|
36 | 37 |
|
37 | 38 | #[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)]
|
@@ -123,6 +124,28 @@ impl From<&FungibleOutput> for FungibleAllocation {
|
123 | 124 | }
|
124 | 125 | }
|
125 | 126 |
|
| 127 | +#[derive(Clone, Eq, PartialEq, Debug)] |
| 128 | +pub struct DataAllocation { |
| 129 | + pub owner: XOutputSeal, |
| 130 | + pub witness: AllocationWitness, |
| 131 | + pub value: Allocation, |
| 132 | +} |
| 133 | + |
| 134 | +impl From<DataOutput> for DataAllocation { |
| 135 | + fn from(out: DataOutput) -> Self { Self::from(&out) } |
| 136 | +} |
| 137 | + |
| 138 | +impl From<&DataOutput> for DataAllocation { |
| 139 | + fn from(out: &DataOutput) -> Self { |
| 140 | + DataAllocation { |
| 141 | + owner: out.seal, |
| 142 | + witness: out.witness.into(), |
| 143 | + value: Allocation::from_strict_serialized::<U16>(out.state.as_ref().to_owned()) |
| 144 | + .expect("invalid allocation data"), |
| 145 | + } |
| 146 | + } |
| 147 | +} |
| 148 | + |
126 | 149 | pub trait OutpointFilter {
|
127 | 150 | fn include_output(&self, output: impl Into<XOutpoint>) -> bool;
|
128 | 151 | }
|
@@ -237,6 +260,26 @@ impl ContractIface {
|
237 | 260 | Ok(LargeVec::try_from_iter(state).expect("same or smaller collection size"))
|
238 | 261 | }
|
239 | 262 |
|
| 263 | + pub fn data( |
| 264 | + &self, |
| 265 | + name: impl Into<FieldName>, |
| 266 | + filter: &impl OutpointFilter, |
| 267 | + ) -> Result<LargeVec<DataAllocation>, ContractError> { |
| 268 | + let name = name.into(); |
| 269 | + let type_id = self |
| 270 | + .iface |
| 271 | + .assignments_type(&name) |
| 272 | + .ok_or(ContractError::FieldNameUnknown(name))?; |
| 273 | + let state = self |
| 274 | + .state |
| 275 | + .data() |
| 276 | + .iter() |
| 277 | + .filter(|outp| outp.opout.ty == type_id) |
| 278 | + .filter(|outp| filter.include_output(outp.seal)) |
| 279 | + .map(DataAllocation::from); |
| 280 | + Ok(LargeVec::try_from_iter(state).expect("same or smaller collection size")) |
| 281 | + } |
| 282 | + |
240 | 283 | // TODO: Add rights, attachments and structured data APIs
|
241 | 284 | pub fn outpoint(
|
242 | 285 | &self,
|
|
0 commit comments