1pub mod http;
2pub mod network;
3pub mod signature;
4
5use crate::{
6 Error, PublicError,
7 cdk::{candid::CandidType, types::Principal},
8 dto::canister::CanisterStatusView,
9 log::Topic,
10 ops::ic::{call::CallOps, mgmt::MgmtOps},
11};
12use serde::de::DeserializeOwned;
13
14pub enum CallWait {
19 Bounded,
20 Unbounded,
21}
22
23pub struct CallBuilder {
28 pid: Principal,
29 method: String,
30 wait: CallWait,
31}
32
33impl CallBuilder {
34 #[must_use]
35 pub const fn bounded(mut self) -> Self {
36 self.wait = CallWait::Bounded;
37 self
38 }
39
40 #[must_use]
41 pub const fn unbounded(mut self) -> Self {
42 self.wait = CallWait::Unbounded;
43 self
44 }
45
46 pub async fn with_arg<R, A>(self, arg: A) -> Result<R, PublicError>
47 where
48 R: CandidType + DeserializeOwned,
49 A: CandidType,
50 {
51 let call = match self.wait {
52 CallWait::Bounded => CallOps::bounded_wait(self.pid, &self.method),
53 CallWait::Unbounded => CallOps::unbounded_wait(self.pid, &self.method),
54 };
55
56 let response = call
57 .try_with_arg(arg)
58 .map_err(|e| map_internal_error(Error::from(e)))?
59 .execute()
60 .await
61 .map_err(|e| map_internal_error(Error::from(e)))?;
62
63 response
64 .candid::<R>()
65 .map_err(|e| map_internal_error(Error::from(e)))
66 }
67}
68
69pub async fn canister_status(pid: Principal) -> Result<CanisterStatusView, PublicError> {
70 MgmtOps::canister_status(pid)
71 .await
72 .map_err(map_internal_error)
73}
74
75fn map_internal_error(err: Error) -> PublicError {
76 crate::log!(Topic::Rpc, Error, "api.ic failed: {err:?}");
78 PublicError::from(err)
79}