use ic_cdk::api::management_canister::provisional::CanisterIdRecord;
use crate::identity::CanisterId;
use super::{types::CallError, unwrap_call_result};
#[derive(candid::CandidType, candid::Deserialize, Debug)]
pub struct WalletReceiveResult {
accepted: u64,
}
#[inline]
pub fn wallet_balance() -> candid::Nat {
return candid::Nat::from(ic_cdk::api::canister_balance128()); }
pub fn wallet_receive<F>(callback: F) -> WalletReceiveResult
where
F: Fn(u128),
{
let available = ic_cdk::api::call::msg_cycles_available128();
if available == 0 {
return WalletReceiveResult { accepted: 0 };
}
let accepted = ic_cdk::api::call::msg_cycles_accept128(available);
assert!(accepted == available);
callback(accepted);
WalletReceiveResult {
accepted: accepted as u64,
}
}
pub async fn deposit_cycles(canister_id: CanisterId, cycles: u128) -> Result<(), String> {
let call_result = ic_cdk::api::management_canister::main::deposit_cycles(
CanisterIdRecord { canister_id },
cycles,
)
.await;
if call_result.is_err() {
let err = call_result.unwrap_err();
return Result::Err(format!(
"canister: {} deposit_cycles {} failed: {:?} {}",
canister_id.to_text(),
cycles,
err.0,
err.1
));
}
Result::Ok(())
}
pub async fn call_wallet_balance(canister_id: &CanisterId) -> candid::Nat {
let call_result: Result<(candid::Nat,), CallError> =
ic_cdk::api::call::call(canister_id.clone(), "wallet_balance", ()).await;
unwrap_call_result(canister_id, "wallet_balance", call_result)
}
pub async fn call_wallet_receive(canister_id: &CanisterId, cycles: u64) -> WalletReceiveResult {
let call_result: Result<(WalletReceiveResult,), CallError> =
ic_cdk::api::call::call_with_payment(canister_id.clone(), "wallet_receive", (), cycles)
.await;
unwrap_call_result(canister_id, "wallet_receive", call_result)
}