use std::sync::Arc;
use near_api_types::{AccountId, Data, NearToken, StorageBalance, StorageBalanceInternal};
use serde_json::json;
use crate::{
Signer,
common::query::{CallResultHandler, PostprocessHandler, RequestBuilder},
contract::ContractTransactBuilder,
transactions::ConstructTransaction,
};
#[derive(Clone, Debug)]
pub struct StorageDeposit(crate::Contract);
impl StorageDeposit {
pub const fn on_contract(contract_id: AccountId) -> Self {
Self(crate::Contract(contract_id))
}
pub const fn contract_id(&self) -> &AccountId {
self.0.account_id()
}
pub fn as_contract(&self) -> crate::contract::Contract {
self.0.clone()
}
#[allow(clippy::type_complexity)]
pub fn view_account_storage(
&self,
account_id: AccountId,
) -> RequestBuilder<
PostprocessHandler<
Data<Option<StorageBalance>>,
CallResultHandler<Option<StorageBalanceInternal>>,
>,
> {
self.0
.call_function(
"storage_balance_of",
json!({
"account_id": account_id,
}),
)
.read_only()
.map(|storage: Data<Option<StorageBalanceInternal>>| {
storage.map(|option_storage| {
option_storage.map(|data| StorageBalance {
available: data.available,
total: data.total,
locked: NearToken::from_yoctonear(
data.total.as_yoctonear() - data.available.as_yoctonear(),
),
})
})
})
}
pub fn deposit(
&self,
receiver_account_id: AccountId,
amount: NearToken,
) -> StorageDepositBuilder {
StorageDepositBuilder {
contract: self.0.clone(),
account_id: receiver_account_id,
amount,
registration_only: false,
}
}
pub fn withdraw(&self, account_id: AccountId, amount: NearToken) -> ConstructTransaction {
self.0
.call_function("storage_withdraw", json!({ "amount": amount }))
.transaction()
.deposit(NearToken::from_yoctonear(1))
.with_signer_account(account_id)
}
pub fn unregister(&self) -> StorageUnregisterBuilder {
StorageUnregisterBuilder {
contract: self.0.clone(),
force: false,
}
}
}
#[derive(Clone, Debug)]
pub struct StorageDepositBuilder {
contract: crate::Contract,
account_id: AccountId,
amount: NearToken,
registration_only: bool,
}
impl StorageDepositBuilder {
pub const fn registration_only(mut self) -> Self {
self.registration_only = true;
self
}
pub fn into_transaction(self) -> ContractTransactBuilder {
let args = if self.registration_only {
json!({
"account_id": self.account_id.to_string(),
"registration_only": true,
})
} else {
json!({
"account_id": self.account_id.to_string(),
})
};
self.contract
.call_function("storage_deposit", args)
.transaction()
.deposit(self.amount)
}
pub fn with_signer(
self,
signer_id: AccountId,
signer: Arc<Signer>,
) -> crate::common::send::ExecuteSignedTransaction {
self.into_transaction().with_signer(signer_id, signer)
}
}
#[derive(Clone, Debug)]
pub struct StorageUnregisterBuilder {
contract: crate::Contract,
force: bool,
}
impl StorageUnregisterBuilder {
pub const fn force(mut self) -> Self {
self.force = true;
self
}
pub fn into_transaction(self) -> ContractTransactBuilder {
let args = if self.force {
json!({ "force": true })
} else {
json!({})
};
self.contract
.call_function("storage_unregister", args)
.transaction()
.deposit(NearToken::from_yoctonear(1))
}
pub fn with_signer(
self,
signer_id: AccountId,
signer: Arc<Signer>,
) -> crate::common::send::ExecuteSignedTransaction {
self.into_transaction().with_signer(signer_id, signer)
}
}