use std::collections::BTreeMap;
use amplify::MultiError;
use sonic_callreq::StateName;
use sonicapi::{CoreParams, OpBuilder};
use strict_types::StrictVal;
use ultrasonic::{AuthToken, CellAddr, CellLock, Opid};
use crate::{AcceptError, Ledger, Stock};
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Satisfaction {
pub name: StateName,
pub witness: StrictVal,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CallParams {
#[cfg_attr(feature = "serde", serde(flatten))]
pub core: CoreParams,
pub using: BTreeMap<CellAddr, Option<Satisfaction>>,
pub reading: Vec<CellAddr>,
}
pub struct DeedBuilder<'c, S: Stock> {
pub(super) builder: OpBuilder,
pub(super) ledger: &'c mut Ledger<S>,
}
impl<S: Stock> DeedBuilder<'_, S> {
pub fn reading(mut self, addr: CellAddr) -> Self {
self.builder = self.builder.access(addr);
self
}
pub fn using(mut self, addr: CellAddr) -> Self {
self.builder = self.builder.destroy(addr);
self
}
pub fn satisfying(mut self, addr: CellAddr, name: impl Into<StateName>, witness: StrictVal) -> Self {
let api = &self.ledger.articles().default_api();
let types = &self.ledger.articles().types();
self.builder = self
.builder
.destroy_satisfy(addr, name, witness, api, types);
self
}
pub fn append(mut self, name: impl Into<StateName>, data: StrictVal, raw: Option<StrictVal>) -> Self {
let api = &self.ledger.articles().default_api();
let types = &self.ledger.articles().types();
self.builder = self.builder.add_global(name, data, raw, api, types);
self
}
pub fn assign(
mut self,
name: impl Into<StateName>,
auth: AuthToken,
data: StrictVal,
lock: Option<CellLock>,
) -> Self {
let api = &self.ledger.articles().default_api();
let types = &self.ledger.articles().types();
self.builder = self.builder.add_owned(name, auth, data, lock, api, types);
self
}
pub fn commit<'a>(self) -> Result<Opid, MultiError<AcceptError, S::Error>>
where Self: 'a {
let deed = self.builder.finalize();
let opid = deed.opid();
self.ledger.apply_verify(deed, true)?;
self.ledger.commit_transaction();
Ok(opid)
}
}