Skip to main content

canic_cdk/spec/standards/icrc/icrc21/
mod.rs

1//! The [ICRC-21](https://github.com/dfinity/wg-identity-authentication/blob/main/topics/ICRC-21/icrc_21_consent_msg.md)
2//! Canister Call Consent Messages standard.
3
4//
5// NOTE: We're using the code directly as importing the icrc-ledger-types is not
6// currently a good idea.  It's got a lot of bloated dependencies and an older version
7// of ic-stable-structures
8//
9mod errors;
10
11pub use errors::*;
12
13use crate::spec::prelude::*;
14
15//
16// ConsentResult
17// (type alias)
18//
19
20pub type ConsentResult = Result<ConsentInfo, Icrc21Error>;
21
22//
23// ConsentInfo
24//
25
26#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
27pub struct ConsentInfo {
28    pub consent_message: ConsentMessage,
29    pub metadata: ConsentMessageMetadata,
30}
31
32//
33// ConsentMessage
34//
35
36#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
37pub enum ConsentMessage {
38    GenericDisplayMessage(String),
39    FieldsDisplayMessage(FieldsDisplay),
40}
41
42//
43// ConsentMessageMetadata
44//
45
46#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
47pub struct ConsentMessageMetadata {
48    pub language: String,
49    pub utc_offset_minutes: Option<i16>,
50}
51
52//
53// ConsentMessageRequest
54//
55
56#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
57pub struct ConsentMessageRequest {
58    pub method: String,
59    pub arg: Vec<u8>,
60    pub user_preferences: ConsentMessageSpec,
61}
62
63//
64// ConsentMessageResponse
65// Wrapper capturing the ok/error variants from an ICRC-21 consent request.
66//
67
68#[derive(CandidType, Deserialize)]
69pub enum ConsentMessageResponse {
70    Ok(ConsentInfo),
71    Err(Icrc21Error),
72}
73
74impl From<ConsentResult> for ConsentMessageResponse {
75    fn from(res: ConsentResult) -> Self {
76        match res {
77            Ok(info) => Self::Ok(info),
78            Err(err) => Self::Err(err),
79        }
80    }
81}
82
83//
84// ConsentMessageSpec
85//
86
87#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
88pub struct ConsentMessageSpec {
89    pub metadata: ConsentMessageMetadata,
90    pub device_spec: Option<DisplayMessageType>,
91}
92
93//
94// DisplayMessageType
95//
96
97#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
98pub enum DisplayMessageType {
99    GenericDisplay,
100    FieldsDisplay,
101}
102
103//
104// FieldsDisplay
105//
106
107#[derive(CandidType, Clone, Debug, Default, Deserialize, Eq, PartialEq)]
108pub struct FieldsDisplay {
109    pub intent: String,
110    pub fields: Vec<(String, Value)>,
111}
112
113//
114// Value
115//
116
117#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
118pub enum Value {
119    TokenAmount {
120        decimals: u8,
121        amount: u64,
122        symbol: String,
123    },
124    TimestampSeconds {
125        amount: u64,
126    },
127    DurationSeconds {
128        amount: u64,
129    },
130    Text {
131        content: String,
132    },
133}