Skip to main content

canic_core/api/rpc/
mod.rs

1use crate::{
2    cdk::{candid::CandidType, types::Principal},
3    dto::{
4        capability::{
5            NonrootCyclesCapabilityEnvelopeV1, NonrootCyclesCapabilityResponseV1,
6            RootCapabilityEnvelopeV1, RootCapabilityResponseV1,
7        },
8        error::Error,
9        rpc::{CreateCanisterParent, CreateCanisterResponse, CyclesResponse},
10    },
11    ids::CanisterRole,
12    workflow::rpc::{capability, request::RpcRequestWorkflow},
13};
14
15///
16/// RpcApi
17///
18/// Public, user-callable wrappers for Canic's internal RPC workflows.
19///
20/// These functions:
21/// - form part of the public API surface
22/// - are safe to call from downstream canister `lib.rs` code
23/// - return [`Error`] suitable for IC boundaries
24///
25/// Internally, they delegate to workflow-level RPC implementations,
26/// preserving the layering:
27///
28///   user canister -> api -> workflow -> ops -> infra
29///
30/// Workflow preserves typed internal failures; conversion to [`Error`] happens
31/// exclusively at this API boundary.
32///
33
34pub struct RpcApi;
35
36impl RpcApi {
37    /// Compute the canonical root capability hash used for proof binding.
38    pub fn root_capability_hash(
39        target_canister: Principal,
40        capability_version: u16,
41        capability: &crate::dto::rpc::Request,
42    ) -> Result<[u8; 32], Error> {
43        capability::root_capability_hash(target_canister, capability_version, capability)
44    }
45
46    /// Dispatch the full root capability envelope verifier/orchestrator path.
47    pub async fn response_capability_v1_root(
48        envelope: RootCapabilityEnvelopeV1,
49    ) -> Result<RootCapabilityResponseV1, Error> {
50        capability::response_capability_v1_root(envelope)
51            .await
52            .map_err(Error::from)
53    }
54
55    /// Dispatch the non-root structural cycles capability path.
56    pub async fn response_capability_v1_nonroot(
57        envelope: NonrootCyclesCapabilityEnvelopeV1,
58    ) -> Result<NonrootCyclesCapabilityResponseV1, Error> {
59        capability::response_capability_v1_nonroot(envelope)
60            .await
61            .map_err(Error::from)
62    }
63
64    pub async fn create_canister_request<A>(
65        canister_role: &CanisterRole,
66        parent: CreateCanisterParent,
67        extra: Option<A>,
68    ) -> Result<CreateCanisterResponse, Error>
69    where
70        A: CandidType + Send + Sync,
71    {
72        RpcRequestWorkflow::create_canister_request(canister_role, parent, extra)
73            .await
74            .map_err(Error::from)
75    }
76
77    pub async fn upgrade_canister_request(canister_pid: Principal) -> Result<(), Error> {
78        RpcRequestWorkflow::upgrade_canister_request(canister_pid)
79            .await
80            .map_err(Error::from)
81    }
82
83    pub async fn request_cycles(cycles: u128) -> Result<CyclesResponse, Error> {
84        RpcRequestWorkflow::request_cycles(cycles)
85            .await
86            .map_err(Error::from)
87    }
88}