Skip to main content

canic_core/dto/
rpc.rs

1use crate::dto::prelude::*;
2
3//
4// Request
5//
6// Root orchestration request.
7//
8
9#[derive(CandidType, Clone, Debug, Deserialize)]
10pub enum Request {
11    AcknowledgePlacementReceipt(AcknowledgePlacementReceiptRequest),
12    AllocatePlacementChild(CreateCanisterRequest),
13    CreateCanister(CreateCanisterRequest),
14    RecycleCanister(RecycleCanisterRequest),
15    Cycles(CyclesRequest),
16}
17
18impl Request {
19    // acknowledge_placement_receipt
20    //
21    // Build a root request that releases one durably consumed placement receipt.
22    #[must_use]
23    pub const fn acknowledge_placement_receipt(
24        request: AcknowledgePlacementReceiptRequest,
25    ) -> Self {
26        Self::AcknowledgePlacementReceipt(request)
27    }
28
29    // allocate_placement_child
30    //
31    // Build a retained root request for receipt-backed placement allocation.
32    #[must_use]
33    pub const fn allocate_placement_child(request: CreateCanisterRequest) -> Self {
34        Self::AllocatePlacementChild(request)
35    }
36
37    // create_canister
38    //
39    // Build a root request for canister provisioning.
40    #[must_use]
41    pub const fn create_canister(request: CreateCanisterRequest) -> Self {
42        Self::CreateCanister(request)
43    }
44
45    // recycle_canister
46    //
47    // Build a root request for recycling one child canister back into the pool.
48    #[must_use]
49    pub const fn recycle_canister(request: RecycleCanisterRequest) -> Self {
50        Self::RecycleCanister(request)
51    }
52
53    // cycles
54    //
55    // Build a root request for requesting/transferring cycles.
56    #[must_use]
57    pub const fn cycles(request: CyclesRequest) -> Self {
58        Self::Cycles(request)
59    }
60}
61
62//
63// AcknowledgePlacementReceiptRequest
64//
65// Placement-receipt acknowledgement payload.
66//
67
68#[derive(CandidType, Clone, Debug, Deserialize)]
69pub struct AcknowledgePlacementReceiptRequest {
70    pub operation_id: [u8; 32],
71    pub metadata: Option<RootRequestMetadata>,
72}
73
74//
75// RootRequestMetadata
76//
77// Replay metadata.
78//
79
80#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
81pub struct RootRequestMetadata {
82    pub request_id: [u8; 32],
83    pub ttl_ns: u64,
84}
85
86//
87// CreateCanisterRequest
88//
89// Create-canister payload.
90//
91
92#[derive(CandidType, Clone, Debug, Deserialize)]
93pub struct CreateCanisterRequest {
94    pub canister_role: CanisterRole,
95    pub parent: CreateCanisterParent,
96    pub extra_arg: Option<Vec<u8>>,
97    pub metadata: Option<RootRequestMetadata>,
98}
99
100//
101// CreateCanisterParent
102//
103// Parent selection.
104//
105
106#[derive(CandidType, Clone, Debug, Deserialize)]
107pub enum CreateCanisterParent {
108    Root,
109    // Use the requesting canister.
110    ThisCanister,
111    // Use the caller's parent.
112    Parent,
113    Canister(Principal),
114    Directory(CanisterRole),
115}
116
117//
118// RecycleCanisterRequest
119//
120// Recycle-one-child payload.
121//
122
123#[derive(CandidType, Clone, Debug, Deserialize)]
124pub struct RecycleCanisterRequest {
125    pub allocation_operation_id: [u8; 32],
126    pub canister_pid: Principal,
127    pub metadata: Option<RootRequestMetadata>,
128}
129
130//
131// CyclesRequest
132//
133// Cycles payload.
134//
135
136#[derive(CandidType, Clone, Debug, Deserialize)]
137pub struct CyclesRequest {
138    pub cycles: u128,
139    pub metadata: Option<RootRequestMetadata>,
140}
141
142//
143// Response
144//
145// Root response payload.
146//
147
148#[derive(CandidType, Clone, Debug, Deserialize, Serialize)]
149pub enum Response {
150    AcknowledgePlacementReceipt,
151    CreateCanister(CreateCanisterResponse),
152    RecycleCanister,
153    Cycles(CyclesResponse),
154}
155
156//
157// CreateCanisterResponse
158// Result of creating and installing a new canister.
159//
160
161#[derive(CandidType, Clone, Debug, Deserialize, Serialize)]
162pub struct CreateCanisterResponse {
163    pub new_canister_pid: Principal,
164}
165
166//
167// CyclesFundingPreflightResponse
168// Typed caller-owned context for a request rejected before any cycles transfer.
169//
170
171#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
172pub enum CyclesFundingPreflightResponse {
173    ChildBudgetExhausted {
174        remaining_child_budget: u128,
175        max_per_child: u128,
176    },
177    CooldownActive {
178        retry_after_secs: u64,
179    },
180    ParentFundingUnavailable {
181        approved_cycles: u128,
182    },
183}
184
185//
186// CyclesResponse
187// Typed outcome of requesting cycles from the current parent.
188//
189
190#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
191pub enum CyclesResponse {
192    PreflightRejected(CyclesFundingPreflightResponse),
193    Transferred { cycles_transferred: u128 },
194}
195
196impl CyclesResponse {
197    /// Return the transferred amount only for a completed funding effect.
198    #[must_use]
199    pub const fn cycles_transferred(self) -> Option<u128> {
200        match self {
201            Self::Transferred { cycles_transferred } => Some(cycles_transferred),
202            Self::PreflightRejected(_) => None,
203        }
204    }
205}