use std::collections::{BTreeMap, BTreeSet};
use serde::{Deserialize, Serialize};
use tari_crypto::ristretto::RistrettoPublicKey;
use tari_template_lib::{
args::VaultFreezeFlags,
types::{
Amount,
NonFungibleId,
ResourceAddress,
ResourceType,
VaultId,
confidential::ConfidentialWithdrawProof,
crypto::PedersenCommitmentBytes,
},
};
use crate::{
bucket::Bucket,
crypto::OutputBody,
proof::{ContainerRef, LockedResource, Proof},
resource_container::{ResourceContainer, ResourceError},
};
#[derive(
Debug, Clone, minicbor::Encode, minicbor::Decode, minicbor::CborLen, Serialize, Deserialize, borsh::BorshSerialize,
)]
#[cfg_attr(feature = "ts", derive(ts_rs::TS), ts(export))]
pub struct Vault {
#[n(0)]
resource_container: ResourceContainer,
#[n(1)]
#[cbor(default)]
#[serde(default)]
freeze_flags: VaultFreezeFlags,
}
impl Vault {
pub fn new(resource: ResourceContainer) -> Self {
Self {
resource_container: resource,
freeze_flags: VaultFreezeFlags::empty(),
}
}
pub fn deposit(&mut self, bucket: Bucket) -> Result<(), ResourceError> {
self.resource_container.deposit(bucket.into_resource_container())?;
Ok(())
}
pub fn withdraw<T: Into<Amount>>(&mut self, amount: T) -> Result<ResourceContainer, ResourceError> {
self.resource_container.withdraw(amount.into())
}
pub fn withdraw_non_fungibles(
&mut self,
ids: &BTreeSet<NonFungibleId>,
) -> Result<ResourceContainer, ResourceError> {
self.resource_container.withdraw_by_ids(ids)
}
pub fn withdraw_confidential(
&mut self,
proof: ConfidentialWithdrawProof,
view_key: Option<&RistrettoPublicKey>,
) -> Result<ResourceContainer, ResourceError> {
self.resource_container.withdraw_confidential(proof, view_key)
}
pub fn recall_all(&mut self) -> Result<ResourceContainer, ResourceError> {
self.resource_container.withdraw_all()
}
pub fn recall_confidential<T: Into<Amount>>(
&mut self,
commitments: &BTreeSet<PedersenCommitmentBytes>,
revealed_amount: T,
) -> Result<ResourceContainer, ResourceError> {
self.resource_container
.recall_confidential_commitments(commitments, revealed_amount.into())
}
pub fn set_freeze(&mut self, flags: VaultFreezeFlags) {
self.freeze_flags = flags;
}
pub fn unfreeze(&mut self) {
self.set_freeze(VaultFreezeFlags::empty());
}
pub fn freeze_flags(&self) -> VaultFreezeFlags {
self.freeze_flags
}
pub fn balance(&self) -> Amount {
self.resource_container.unlocked_amount()
}
pub fn locked_balance(&self) -> Amount {
self.resource_container.locked_amount()
}
pub fn get_commitment_count(&self) -> u64 {
self.resource_container.get_commitment_count()
}
pub fn get_confidential_commitments(&self) -> Option<&BTreeMap<PedersenCommitmentBytes, OutputBody>> {
self.resource_container.get_confidential_commitments()
}
pub fn resource_address(&self) -> &ResourceAddress {
self.resource_container.resource_address()
}
pub fn resource_type(&self) -> ResourceType {
self.resource_container.resource_type()
}
pub fn get_non_fungible_ids(&self) -> &BTreeSet<NonFungibleId> {
self.resource_container.non_fungible_token_ids()
}
pub fn resource_container_mut(&mut self) -> &mut ResourceContainer {
&mut self.resource_container
}
pub fn lock_all(&mut self, vault_id: VaultId) -> Result<LockedResource, ResourceError> {
let locked_resource = self.resource_container.lock_all()?;
Ok(LockedResource::new(ContainerRef::Vault(vault_id), locked_resource))
}
pub fn lock_by_non_fungible_ids(
&mut self,
vault_id: VaultId,
ids: BTreeSet<NonFungibleId>,
) -> Result<LockedResource, ResourceError> {
let locked_resource = self.resource_container.lock_by_non_fungible_ids(ids)?;
Ok(LockedResource::new(ContainerRef::Vault(vault_id), locked_resource))
}
pub fn lock_by_amount<T: Into<Amount>>(
&mut self,
vault_id: VaultId,
amount: T,
) -> Result<LockedResource, ResourceError> {
let locked_resource = self.resource_container.lock_by_amount(amount.into())?;
Ok(LockedResource::new(ContainerRef::Vault(vault_id), locked_resource))
}
pub fn unlock(&mut self, proof: Proof) -> Result<(), ResourceError> {
self.resource_container.unlock(proof.into_resource_container())
}
}