use miden_client::Serializable;
use miden_objects::Word;
use miden_objects::account::{Account, AccountId};
use crate::error::{MultisigError, Result};
#[derive(Debug, Clone)]
pub struct MultisigAccount {
account: Account,
psm_endpoint: String,
}
impl MultisigAccount {
pub fn new(account: Account, psm_endpoint: impl Into<String>) -> Self {
Self {
account,
psm_endpoint: psm_endpoint.into(),
}
}
pub fn id(&self) -> AccountId {
self.account.id()
}
pub fn nonce(&self) -> u64 {
self.account.nonce().as_int()
}
pub fn commitment(&self) -> Word {
self.account.commitment()
}
pub fn psm_endpoint(&self) -> &str {
&self.psm_endpoint
}
pub fn inner(&self) -> &Account {
&self.account
}
pub fn into_inner(self) -> Account {
self.account
}
pub fn threshold(&self) -> Result<u32> {
let slot_value = self
.account
.storage()
.get_item(0)
.map_err(|e| MultisigError::AccountStorage(e.to_string()))?;
Ok(slot_value[0].as_int() as u32)
}
pub fn num_signers(&self) -> Result<u32> {
let slot_value = self
.account
.storage()
.get_item(0)
.map_err(|e| MultisigError::AccountStorage(e.to_string()))?;
Ok(slot_value[1].as_int() as u32)
}
pub fn cosigner_commitments(&self) -> Vec<Word> {
let mut commitments = Vec::new();
let key_zero = Word::from([0u32, 0, 0, 0]);
let first_entry = self.account.storage().get_map_item(1, key_zero);
if first_entry.is_err() || first_entry.as_ref().unwrap() == &Word::default() {
return commitments;
}
let mut index = 0u32;
loop {
let key = Word::from([index, 0, 0, 0]);
match self.account.storage().get_map_item(1, key) {
Ok(value) if value != Word::default() => {
commitments.push(value);
index += 1;
}
_ => break,
}
}
commitments
}
pub fn cosigner_commitments_hex(&self) -> Vec<String> {
self.cosigner_commitments()
.into_iter()
.map(|word| format!("0x{}", hex::encode(word.to_bytes())))
.collect()
}
pub fn is_cosigner(&self, commitment: &Word) -> bool {
self.cosigner_commitments().contains(commitment)
}
pub fn psm_enabled(&self) -> Result<bool> {
let slot_value = self
.account
.storage()
.get_item(4)
.map_err(|e| MultisigError::AccountStorage(e.to_string()))?;
Ok(slot_value[0].as_int() == 1)
}
pub fn psm_commitment(&self) -> Result<Word> {
let key = Word::from([0u32, 0, 0, 0]);
self.account
.storage()
.get_map_item(5, key)
.map_err(|e| MultisigError::AccountStorage(e.to_string()))
}
}