Skip to main content

canic_core/dto/icrc21/
mod.rs

1//! Module: dto::icrc21
2//!
3//! Responsibility: ICRC-21 Canister Call Consent Message Candid DTOs.
4//! Does not own: consent policy, wallet UX, or application authorization.
5//! Boundary: mirrors the external ICRC-21 surface for Canic callers.
6
7//
8// Keep these DTOs local rather than importing icrc-ledger-types. That crate
9// pulls in broad dependencies and an older ic-stable-structures version.
10//
11mod errors;
12
13pub use errors::*;
14
15use crate::dto::prelude::*;
16
17//
18// ConsentInfo
19//
20
21#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
22pub struct ConsentInfo {
23    pub consent_message: ConsentMessage,
24    pub metadata: ConsentMessageMetadata,
25}
26
27//
28// ConsentMessage
29//
30
31#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
32pub enum ConsentMessage {
33    GenericDisplayMessage(String),
34    FieldsDisplayMessage(FieldsDisplay),
35}
36
37//
38// ConsentMessageMetadata
39//
40
41#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
42pub struct ConsentMessageMetadata {
43    pub language: String,
44    pub utc_offset_minutes: Option<i16>,
45}
46
47//
48// ConsentMessageRequest
49//
50
51#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
52pub struct ConsentMessageRequest {
53    pub method: String,
54    pub arg: Vec<u8>,
55    pub user_preferences: ConsentMessageSpec,
56}
57
58//
59// ConsentMessageResponse
60// Wrapper capturing the ok/error variants from an ICRC-21 consent request.
61//
62
63#[derive(CandidType, Deserialize)]
64pub enum ConsentMessageResponse {
65    Ok(ConsentInfo),
66    Err(Icrc21Error),
67}
68
69impl From<Result<ConsentInfo, Icrc21Error>> for ConsentMessageResponse {
70    fn from(res: Result<ConsentInfo, Icrc21Error>) -> Self {
71        match res {
72            Ok(info) => Self::Ok(info),
73            Err(err) => Self::Err(err),
74        }
75    }
76}
77
78//
79// ConsentMessageSpec
80//
81
82#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
83pub struct ConsentMessageSpec {
84    pub metadata: ConsentMessageMetadata,
85    pub device_spec: Option<DisplayMessageType>,
86}
87
88//
89// DisplayMessageType
90//
91
92#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
93pub enum DisplayMessageType {
94    GenericDisplay,
95    FieldsDisplay,
96}
97
98//
99// FieldsDisplay
100//
101
102#[derive(CandidType, Clone, Debug, Default, Deserialize, Eq, PartialEq)]
103pub struct FieldsDisplay {
104    pub intent: String,
105    pub fields: Vec<(String, Value)>,
106}
107
108//
109// Value
110//
111
112#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
113pub enum Value {
114    TokenAmount {
115        decimals: u8,
116        amount: u64,
117        symbol: String,
118    },
119    TimestampSeconds {
120        amount: u64,
121    },
122    DurationSeconds {
123        amount: u64,
124    },
125    Text {
126        content: String,
127    },
128}