-
Notifications
You must be signed in to change notification settings - Fork 10
/
ICRC-21.did
156 lines (141 loc) · 7.87 KB
/
ICRC-21.did
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Canister interface specification for ICRC-21.
// See https://github.com/dfinity/wg-identity-authentication/blob/main/topics/ICRC-21/icrc_21_consent_msg.md
type icrc21_consent_message_metadata = record {
// BCP-47 language tag. See https://www.rfc-editor.org/rfc/bcp/bcp47.txt
language: text;
// The users local timezone offset in minutes from UTC.
// Applicable when converting timestamps to human-readable format.
//
// If absent in the request, the canister should fallback to the UTC timezone when creating the consent message.
// If absent in the response, the canister is indicating that the consent message is not timezone sensitive.
utc_offset_minutes: opt int16;
};
type icrc21_consent_message_spec = record {
// Metadata of the consent message.
metadata: icrc21_consent_message_metadata;
// Information about the device responsible for presenting the consent message to the user.
// If absent in the request, the canister should fallback to one of the values defined in this spec (ICRC-21).
device_spec: opt variant {
// A generic display able to handle large documents and do line wrapping and pagination / scrolling.
// Text must be Markdown formatted, no external resources (e.g. images) are allowed.
GenericDisplay;
// Simple display able to handle lines of text with a maximum number of characters per line.
// Multiple pages can be used if the text does no fit on a single page.
// Text must be plain text without any embedded formatting elements.
LineDisplay: record {
// Maximum number of characters that can be displayed per line.
characters_per_line: nat16;
// Maximum number of lines that can be displayed at once on a single page.
lines_per_page: nat16;
};
};
};
type icrc21_consent_message_request = record {
// Method name of the canister call.
method: text;
// Argument of the canister call.
arg: blob;
// User preferences with regards to the consent message presented to the end-user.
user_preferences: icrc21_consent_message_spec;
};
type icrc21_consent_message = variant {
// Message for a generic display able to handle large documents and do proper line wrapping and pagination / scrolling.
// Uses Markdown formatting, no external resources (e.g. images) are allowed.
GenericDisplayMessage: text;
// Message for a simple display able to handle pages with multiple lines of text with a fixed maximum number of
// characters per line.
// Multiple pages can be used if the text does no fit on a single page.
// Uses plain text, without any embedded formatting elements.
LineDisplayMessage: record {
pages: vec record {
// Lines of text to be displayed on a single page.
// Must not have more entries (lines) than specified in the icrc21_consent_message_spec.
// Lines must not exceed the number of characters per line specified in the icrc21_consent_message_spec.
lines: vec text;
};
};
};
type icrc21_consent_info = record {
// Consent message describing in a human-readable format what the call will do.
//
// The message should adhere as close as possible to the user_preferences specified in the consent_message_spec
// of the icrc21_consent_message_request.
// If the message is not available for the given user_preferences any fallback message should be used. Providing a
// message should be preferred over sending an icrc21_error.
// The metadata must match the consent_message provided.
//
// The message should be short and concise.
// It should only contain information that is:
// * relevant to the user
// * relevant given the canister call argument
//
// The message must fit the following context shown to
// the user on the signer UI:
// ┌─────────────────────────────────┐
// │ Approve the following action? │
// │ ┌───────────────────────────┐ │
// │ │ <consent_message> │ │
// │ └───────────────────────────┘ │
// │ ┌───────────┐ ┌───────────┐ │
// │ │ Reject │ │ Approve │ │
// │ └───────────┘ └───────────┘ │
// └─────────────────────────────────┘
consent_message: icrc21_consent_message;
// Metadata of the consent_message.
metadata: icrc21_consent_message_metadata;
};
type icrc21_error_info = record {
// Human readable technical description of the error intended for developers, not the end-user.
description: text;
};
type icrc21_error = variant {
// The canister does not support this call (i.e. it will lead to a rejection or error response).
// Reasons might be (non-exhaustive list):
// * the canister call is malformed (e.g. wrong method name, argument cannot be decoded)
// * the arguments exceed certain bounds
//
// The developer should provide more information about the error using the description in icrc21_error_info.
UnsupportedCanisterCall: icrc21_error_info;
// The canister cannot produce a consent message for this call.
// Reasons might be (non-exhaustive list):
// * it is an internal call not intended for end-users
// * the canister developer has not yet implemented a consent message for this call
//
// The developer should provide more information about the error using the description in icrc21_error_info.
ConsentMessageUnavailable: icrc21_error_info;
// The canister did not provide a consent message for because payment was missing or insufficient.
//
// This error is used to account for payment extensions to be added in the future:
// While small consent messages are easy and cheap to provide, this might not generally be the case for all consent
// messages. To avoid future breaking changes, when introducing a payment flow, this error is already introduced
// even though there no standardized payment flow yet.
InsufficientPayment: icrc21_error_info;
// Any error not covered by the above variants.
GenericError: record {
// Machine parsable error. Can be chosen by the target canister but should indicate the error category.
error_code: nat;
// Human readable technical description of the error intended for developers, not the end-user.
description: text;
};
};
type icrc21_consent_message_response = variant {
// The call is ok, consent message is provided.
Ok: icrc21_consent_info;
// The call is not ok, error is provided.
Err: icrc21_error;
};
service : {
// Returns a human-readable consent message for the given canister call.
//
// This call must not require authentication (i.e. must be available for the anonymous sender).
// If the call is made with a non-anonymous identity, the response may be tailored to the identity.
//
// This is currently an update call. As soon as secure (replicated) query calls are available, this will be changed to such a replicated query call.
icrc21_canister_call_consent_message: (icrc21_consent_message_request) -> (icrc21_consent_message_response);
// Returns a list of supported standards that this canister implements.
// The result must include an entry for ICRC-21:
// record { name = "ICRC-21"; url = "https://github.com/dfinity/ICRC/blob/main/ICRCs/ICRC-21/ICRC-21.md" }
//
// See ICRC-10 for more information: https://github.com/dfinity/ICRC/blob/main/ICRCs/ICRC-10/ICRC-10.md
icrc10_supported_standards : () -> (vec record { name : text; url : text }) query;
}