use std::borrow::Cow;
use serde::{Deserialize, Serialize};
use tari_template_lib::types::{
ComponentAddress,
EntityId,
ObjectKey,
SubstateOwnerRule,
TemplateAddress,
access_rules::ComponentAccessRules,
crypto::RistrettoPublicKeyBytes,
};
use crate::{
hashing::{EngineHashDomainLabel, hasher32},
indexed_value::{IndexedValueError, IndexedWellKnownTypes},
ownership::Ownership,
substate::SubstateId,
};
pub fn derive_component_address_from_public_key(
template_address: &TemplateAddress,
public_key: &RistrettoPublicKeyBytes,
) -> ComponentAddress {
let address = hasher32(EngineHashDomainLabel::ComponentAddress)
.chain(template_address)
.chain(public_key)
.result();
let key = ObjectKey::from_array(address.leading_bytes());
ComponentAddress::new(key)
}
#[derive(Debug, Clone, Serialize, Deserialize, borsh::BorshSerialize)]
#[cfg_attr(feature = "ts", derive(ts_rs::TS), ts(export))]
pub struct ComponentHeader {
pub template_address: TemplateAddress,
pub module_name: String,
pub owner_rule: SubstateOwnerRule,
pub access_rules: ComponentAccessRules,
pub entity_id: EntityId,
pub body: ComponentBody,
}
impl ComponentHeader {
pub fn into_component(self) -> ComponentBody {
self.body
}
pub fn state(&self) -> &tari_bor::Value {
&self.body.state
}
pub fn into_state(self) -> tari_bor::Value {
self.body.state
}
pub fn as_ownership(&self) -> Ownership<'_> {
Ownership {
owner_rule: Cow::Borrowed(&self.owner_rule),
}
}
pub fn owner_public_key(&self) -> Option<&RistrettoPublicKeyBytes> {
self.owner_rule.owned_by_public_key()
}
pub fn access_rules(&self) -> &ComponentAccessRules {
&self.access_rules
}
pub fn set_access_rules(&mut self, access_rules: ComponentAccessRules) -> &mut Self {
self.access_rules = access_rules;
self
}
pub fn set_template_address(&mut self, template_address: TemplateAddress) -> &mut Self {
self.template_address = template_address;
self
}
pub fn contains_substate(&self, address: &SubstateId) -> Result<bool, IndexedValueError> {
let found = IndexedWellKnownTypes::value_contains_substate(self.state(), address)?;
Ok(found)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, borsh::BorshSerialize)]
#[cfg_attr(feature = "ts", derive(ts_rs::TS), ts(export))]
pub struct ComponentBody {
#[serde(with = "ootle_serde::cbor_value")]
#[cfg_attr(feature = "ts", ts(type = "any"))]
#[borsh(serialize_with = "crate::borsh::serialize_cbor_value")]
pub state: tari_bor::Value,
}
impl ComponentBody {
pub const fn empty() -> Self {
Self {
state: tari_bor::Value::Null,
}
}
pub const fn from_cbor_value(state: tari_bor::Value) -> Self {
Self { state }
}
pub fn set(&mut self, state: tari_bor::Value) -> &mut Self {
self.state = state;
self
}
pub fn to_indexed_well_known_types(&self) -> Result<IndexedWellKnownTypes, IndexedValueError> {
IndexedWellKnownTypes::from_value(&self.state)
}
}