use async_trait::async_trait;
use num_bigint::BigUint;
use strum::IntoStaticStr;
use tonlib_core::cell::ArcCell;
use tonlib_core::TonAddress;
use crate::contract::{MapStackError, TonContractError, TonContractInterface};
#[derive(Debug, Clone)]
pub struct WalletData {
pub balance: BigUint,
pub owner_address: TonAddress,
pub master_address: TonAddress,
pub wallet_code: ArcCell,
}
#[derive(IntoStaticStr)]
#[strum(serialize_all = "snake_case")]
enum JettonWalletMethods {
GetWalletData,
}
#[async_trait]
pub trait JettonWalletContract: TonContractInterface {
async fn get_wallet_data(&self) -> Result<WalletData, TonContractError> {
const WALLET_DATA_STACK_ELEMENTS: usize = 4;
let method: &str = JettonWalletMethods::GetWalletData.into();
let address = self.address().clone();
let res = self.run_get_method(method, Vec::new()).await?;
let stack = res.stack;
if stack.len() >= WALLET_DATA_STACK_ELEMENTS {
let balance = stack[0].get_biguint().map_stack_error(method, &address)?;
let owner_address = stack[1].get_address().map_stack_error(method, &address)?;
let master_address = stack[2].get_address().map_stack_error(method, &address)?;
let wallet_code = stack[3].get_cell().map_stack_error(method, &address)?;
Ok(WalletData {
balance,
owner_address,
master_address,
wallet_code,
})
} else {
Err(TonContractError::InvalidMethodResultStackSize {
method: method.to_string(),
address: self.address().clone(),
actual: stack.len(),
expected: WALLET_DATA_STACK_ELEMENTS,
})
}
}
}
impl<T> JettonWalletContract for T where T: TonContractInterface {}