1#![allow(clippy::derive_partial_eq_without_eq)]
2
3macro_rules! include_proto {
5 ($package:tt) => {
6 include!(concat!(env!("OUT_DIR"), "/", $package, ".rs"));
7 };
8}
9
10pub mod directory {
11 include_proto!("m10.directory");
12 use core::fmt;
13 use core::str::FromStr;
14
15 #[derive(Debug)]
16 pub struct InvalidAliasType();
17
18 impl fmt::Display for InvalidAliasType {
19 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
20 f.write_str("invalid alias type")
21 }
22 }
23
24 impl std::error::Error for InvalidAliasType {}
25
26 impl FromStr for alias::Type {
27 type Err = InvalidAliasType;
28 fn from_str(s: &str) -> Result<Self, Self::Err> {
29 match s {
30 "handle" => Ok(alias::Type::Handle),
31 "email" => Ok(alias::Type::Email),
32 "phone" => Ok(alias::Type::Phone),
33 _ => Err(InvalidAliasType()),
34 }
35 }
36 }
37
38 impl AsRef<str> for alias::Type {
39 fn as_ref(&self) -> &str {
40 match self {
41 alias::Type::Handle => "handle",
42 alias::Type::Email => "email",
43 alias::Type::Phone => "phone",
44 }
45 }
46 }
47
48 impl fmt::Display for alias::Type {
49 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
50 f.write_str(self.as_ref())
51 }
52 }
53}
54
55pub mod sdk {
56 include_proto!("m10.sdk");
57
58 pub const FILE_DESCRIPTOR_SET_BYTES: &[u8] =
59 include_bytes!(concat!(env!("OUT_DIR"), "/m10.sdk.bin"));
60 pub static FILE_DESCRIPTOR_SET: once_cell::sync::Lazy<prost_types::FileDescriptorSet> =
61 once_cell::sync::Lazy::new(|| {
62 prost::Message::decode(FILE_DESCRIPTOR_SET_BYTES).expect("file descriptor parse failed")
63 });
64
65 pub mod model {
66 include_proto!("m10.sdk.model");
67 pub const FILE_DESCRIPTOR_SET_BYTES: &[u8] =
68 include_bytes!(concat!(env!("OUT_DIR"), "/m10.model.pb"));
69 pub static FILE_DESCRIPTOR_SET: once_cell::sync::Lazy<prost_types::FileDescriptorSet> =
70 once_cell::sync::Lazy::new(|| {
71 prost::Message::decode(FILE_DESCRIPTOR_SET_BYTES)
72 .expect("file descriptor parse failed")
73 });
74 }
75 pub mod transaction {
76 include_proto!("m10.sdk.transaction");
77 }
78 pub mod metadata {
79 include_proto!("m10.sdk.metadata");
80 }
81 pub use metadata::*;
82 pub use model::*;
83 use prost::Message;
84 pub use transaction::*;
85
86 use core::{fmt, str};
87
88 pub use crate::Collection;
89 use crate::{sdk, Pack};
90
91 impl Eq for RedeemableToken {}
92
93 impl PartialOrd for RedeemableToken {
94 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
95 Some(self.cmp(other))
96 }
97 }
98
99 impl Ord for RedeemableToken {
100 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
101 match (self.data.as_ref(), other.data.as_ref()) {
102 (None, None) => std::cmp::Ordering::Equal,
103 (Some(_), None) => std::cmp::Ordering::Greater,
104 (None, Some(_)) => std::cmp::Ordering::Less,
105 (Some(s), Some(o)) => s.id.cmp(&o.id),
106 }
107 }
108 }
109
110 impl Pack for AccountSet {
111 const COLLECTION: Collection = Collection::AccountSets;
112 fn set_id(&mut self, id: Vec<u8>) {
113 self.id = id;
114 }
115 fn id(&self) -> &[u8] {
116 &self.id
117 }
118 }
119
120 impl Pack for AccountMetadata {
121 const COLLECTION: Collection = Collection::AccountMetadata;
122 fn set_id(&mut self, id: Vec<u8>) {
123 self.id = id;
124 }
125 fn id(&self) -> &[u8] {
126 &self.id
127 }
128 }
129
130 impl Pack for Bank {
131 const COLLECTION: Collection = Collection::Banks;
132 fn set_id(&mut self, id: Vec<u8>) {
133 self.id = id;
134 }
135 fn id(&self) -> &[u8] {
136 &self.id
137 }
138 }
139
140 use transaction_data::Data;
141
142 impl From<CreateTransfer> for Data {
143 fn from(create_transfer: CreateTransfer) -> Self {
144 Self::Transfer(create_transfer)
145 }
146 }
147
148 impl From<CreateLedgerAccount> for Data {
149 fn from(request: CreateLedgerAccount) -> Self {
150 Self::CreateLedgerAccount(request)
151 }
152 }
153
154 impl From<SetFreezeState> for Data {
155 fn from(request: SetFreezeState) -> Self {
156 Self::SetFreezeState(request)
157 }
158 }
159
160 impl From<SetInstrument> for Data {
161 fn from(request: SetInstrument) -> Self {
162 Self::SetInstrument(request)
163 }
164 }
165
166 impl From<SetBalanceLimit> for Data {
167 fn from(request: SetBalanceLimit) -> Self {
168 Self::SetBalanceLimit(request)
169 }
170 }
171
172 impl From<InvokeAction> for Data {
173 fn from(request: InvokeAction) -> Self {
174 Self::InvokeAction(request)
175 }
176 }
177
178 impl From<CommitTransfer> for Data {
179 fn from(request: CommitTransfer) -> Self {
180 Self::CommitTransfer(request)
181 }
182 }
183
184 impl From<CreateToken> for Data {
185 fn from(request: CreateToken) -> Self {
186 Self::CreateToken(request)
187 }
188 }
189
190 impl From<RedeemToken> for Data {
191 fn from(request: RedeemToken) -> Self {
192 Self::RedeemToken(request)
193 }
194 }
195
196 impl From<sdk::DocumentOperations> for Data {
197 fn from(operations: sdk::DocumentOperations) -> Self {
198 Self::DocumentOperations(operations)
199 }
200 }
201
202 impl From<Vec<sdk::Operation>> for Data {
203 fn from(operations: Vec<sdk::Operation>) -> Self {
204 Self::from(sdk::DocumentOperations { operations })
205 }
206 }
207
208 impl From<sdk::Operation> for Data {
209 fn from(operation: sdk::Operation) -> Self {
210 Self::from(vec![operation])
211 }
212 }
213
214 impl From<CreateLedgerTransfers> for Contract {
215 fn from(transfers: CreateLedgerTransfers) -> Self {
216 Self {
217 transactions: transfers.encode_to_vec(),
218 ..Default::default()
219 }
220 }
221 }
222
223 impl TransactionResponse {
224 pub fn tx_error(self) -> Result<Self, TransactionError> {
225 match self.error {
226 Some(err) => Err(err),
227 None => Ok(self),
228 }
229 }
230 }
231
232 impl fmt::Display for TransactionError {
233 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
234 write!(f, "{:?}: {}", self.code(), self.message)
235 }
236 }
237
238 impl std::error::Error for TransactionError {}
239
240 impl From<prost::bytes::Bytes> for Value {
241 fn from(bytes: prost::bytes::Bytes) -> Value {
242 Value {
243 value: Some(value::Value::BytesValue(bytes)),
244 }
245 }
246 }
247
248 impl Operation {
249 pub fn insert<D: Pack>(document: D) -> Self {
250 Self {
251 operation: Some(operation::Operation::InsertDocument(
252 operation::InsertDocument {
253 collection: D::COLLECTION.to_string(),
254 document: document.pack(),
255 },
256 )),
257 }
258 }
259
260 pub fn delete<D: Pack>(id: Vec<u8>) -> Self {
261 Self {
262 operation: Some(operation::Operation::DeleteDocument(
263 operation::DeleteDocument {
264 collection: D::COLLECTION.to_string(),
265 primary_key: Some(bytes::Bytes::from(id).into()),
266 },
267 )),
268 }
269 }
270
271 pub fn new_index<D: Pack>(path: Vec<String>) -> Self {
272 Self {
273 operation: Some(operation::Operation::InsertIndex(operation::InsertIndex {
274 collection: D::COLLECTION.to_string(),
275 path: path.join("."),
276 })),
277 }
278 }
279
280 pub fn new_collection(
281 name: String,
282 descriptor_name: String,
283 index_metadata: Vec<IndexMetadata>,
284 ) -> Self {
285 Self {
286 operation: Some(operation::Operation::InsertCollection(CollectionMetadata {
287 name,
288 descriptor_name,
289 file_descriptor_set: Some(crate::sdk::FILE_DESCRIPTOR_SET.clone()),
290 primary_key_path: "id".to_string(),
291 index_metadata,
292 })),
293 }
294 }
295 }
296
297 impl Signature {
298 pub fn verify(&self, message: &[u8]) -> Result<(), TransactionError> {
299 let Signature {
300 signature,
301 public_key,
302 algorithm,
303 } = self;
304
305 let alg = signature::Algorithm::try_from(*algorithm).map_err(|_| TransactionError {
306 code: transaction_error::Code::BadRequest.into(),
307 message: "Unsupported Algorithm".to_owned(),
308 })?;
309
310 let key = match alg {
311 signature::Algorithm::P256Sha256Asn1 => ring::signature::UnparsedPublicKey::new(
312 &ring::signature::ECDSA_P256_SHA256_ASN1,
313 public_key,
314 ),
315 signature::Algorithm::Ed25519 => {
316 ring::signature::UnparsedPublicKey::new(&ring::signature::ED25519, public_key)
317 }
318 };
319
320 key.verify(message, signature)
321 .map_err(|_| TransactionError {
322 code: transaction_error::Code::InvalidSignature.into(),
323 message: String::new(),
324 })?;
325
326 Ok(())
327 }
328 }
329
330 impl Pack for RoleBinding {
331 const COLLECTION: Collection = Collection::RoleBindings;
332 fn set_id(&mut self, id: Vec<u8>) {
333 self.id = bytes::Bytes::from(id);
334 }
335 fn id(&self) -> &[u8] {
336 &self.id
337 }
338 }
339
340 impl Pack for Role {
341 const COLLECTION: Collection = Collection::Roles;
342 fn set_id(&mut self, id: Vec<u8>) {
343 self.id = bytes::Bytes::from(id);
344 }
345 fn id(&self) -> &[u8] {
346 &self.id
347 }
348 }
349}
350
351pub mod health {
352 include_proto!("grpc.health.v1");
353}
354
355pub mod metadata;
356mod pack;
357
358pub mod prost {
360 pub use prost::*;
361 pub use prost_types::*;
362}
363pub use metadata::*;
364pub use pack::{Collection, Pack};
365
366use prost_types::Any;
367use serde::{Deserialize, Serialize};
368use serde_with::{DeserializeAs, SerializeAs};
369
370pub struct AnySerDeCompat;
371
372#[derive(Serialize)]
373struct AnySerializeWrapper<'a> {
374 pub type_url: &'a str,
375 pub value: &'a [u8],
376}
377
378#[derive(Deserialize)]
379struct AnyDeserializeWrapper {
380 pub type_url: String,
381 pub value: Vec<u8>,
382}
383
384impl SerializeAs<Any> for AnySerDeCompat {
385 fn serialize_as<S>(source: &Any, serializer: S) -> Result<S::Ok, S::Error>
386 where
387 S: serde::Serializer,
388 {
389 AnySerializeWrapper {
390 type_url: &source.type_url,
391 value: &source.value,
392 }
393 .serialize(serializer)
394 }
395}
396
397impl<'de> DeserializeAs<'de, Any> for AnySerDeCompat {
398 fn deserialize_as<D>(deserializer: D) -> Result<Any, D::Error>
399 where
400 D: serde::Deserializer<'de>,
401 {
402 let AnyDeserializeWrapper { type_url, value } =
403 AnyDeserializeWrapper::deserialize(deserializer)?;
404 Ok(Any { type_url, value })
405 }
406}