use std::collections::BTreeSet;
use bitcoin::OutPoint;
use rgb::fungible::allocation::{AllocationMap, AllocationValueMap, AllocationValueVec};
use rgb::prelude::*;
use seals::txout::ExplicitSeal;
use super::schema::{OwnedRightType, TransitionType};
use super::Asset;
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display, Error)]
#[display(doc_comments)]
pub enum Error {
UnrelatedInput(OutPoint),
InputsNotEqualOutputs,
InsufficientIssueAllowance {
allowed: AtomicValue,
requested: AtomicValue,
},
SupplyMismatch {
assigned: AtomicValue,
requested: AtomicValue,
},
UnknownSeals(BTreeSet<OutPoint>),
}
impl Asset {
pub fn inflate(
&self,
_closing: BTreeSet<OutPoint>,
_next_inflation: AllocationValueMap,
_allocations: AllocationValueVec,
) -> Result<Transition, Error> {
todo!()
}
pub fn epoch(
&self,
_closing: OutPoint,
_next_epoch: Option<ExplicitSeal>,
_burning_seal: Option<ExplicitSeal>,
) -> Result<Transition, Error> {
todo!()
}
pub fn burn(
&self,
_closing: OutPoint,
_burned_value: AtomicValue,
_burned_utxos: BTreeSet<OutPoint>,
_next_burn: Option<ExplicitSeal>,
) -> Result<Transition, Error> {
todo!()
}
pub fn burn_replace(
&self,
_closing: OutPoint,
_burned_value: AtomicValue,
_burned_utxos: BTreeSet<OutPoint>,
_next_burn: Option<ExplicitSeal>,
_allocations: AllocationValueVec,
) -> Result<Transition, Error> {
todo!()
}
pub fn transfer(
&self,
inputs: BTreeSet<OutPoint>,
payment: EndpointValueMap,
change: SealValueMap,
) -> Result<Transition, Error> {
let mut input_usto = Vec::<OwnedValue>::new();
for outpoint in inputs {
let coins = self.outpoint_coins(outpoint);
if coins.is_empty() {
Err(Error::UnrelatedInput(outpoint))?
}
input_usto.extend(coins);
}
let input_amounts: Vec<_> = input_usto.iter().map(|coin| coin.state).collect();
let total_inputs = input_amounts
.iter()
.fold(0u64, |acc, coin| acc + coin.value);
let total_outputs = change.sum() + payment.sum();
if total_inputs != total_outputs {
Err(Error::InputsNotEqualOutputs)?
}
let assignments = type_map! {
OwnedRightType::Assets =>
TypedAssignments::zero_balanced(input_amounts, change, payment)
};
let mut parent = ParentOwnedRights::default();
for coin in input_usto {
parent
.entry(coin.outpoint.node_id)
.or_insert_with(|| empty!())
.entry(OwnedRightType::Assets.into())
.or_insert_with(|| empty!())
.push(coin.outpoint.no);
}
let transition = Transition::with(
TransitionType::Transfer,
empty!(),
empty!(),
assignments.into(),
empty!(),
parent,
);
Ok(transition)
}
}