cat_gateway/service/common/objects/cardano/
registration_info.rs

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
//! Defines API schemas of [CIP-36](https://cips.cardano.org/cip/CIP-36/) registration type.

use poem_openapi::{types::Example, Object, Union};

use crate::service::{
    api::cardano::types::{Nonce, PaymentAddress, PublicVotingInfo, TxId},
    common::objects::cardano::hash::Hash,
    utilities::as_hex_string,
};

/// The Voting power and voting key of a Delegated voter.
#[derive(Object)]
struct Delegation {
    /// Voting key.
    #[oai(validator(min_length = "66", max_length = "66", pattern = "0x[0-9a-f]{64}"))]
    voting_key: String,

    /// Delegation power assigned to the voting key.
    #[oai(validator(minimum(value = "0"), maximum(value = "9223372036854775807")))]
    power: i64,
}

/// Represents a list of delegations.
#[derive(Object)]
struct Delegations {
    /// A list of delegations.
    #[oai(validator(max_items = "100"))]
    delegations: Vec<Delegation>,
}

/// Voting `Key` for a direct voter (not delegated).
#[derive(Object)]
struct DirectVoter {
    /// Voting key.
    #[oai(validator(min_length = "66", max_length = "66", pattern = "0x[0-9a-f]{64}"))]
    voting_key: String,
}

/// The type of the Voting Key.
#[derive(Union)]
#[oai(discriminator_name = "type", one_of = true)]
enum VotingInfo {
    /// direct voting key
    Direct(DirectVoter),
    /// delegations
    Delegated(Delegations),
}

/// User's [CIP-36](https://cips.cardano.org/cip/CIP-36/) registration info.
#[derive(Object)]
#[oai(example = true)]
pub(crate) struct RegistrationInfo {
    /// Rewards address.
    #[oai(validator(min_length = "2", max_length = "116", pattern = "0x[0-9a-f]*"))]
    rewards_address: String,

    /// Transaction hash in which the [CIP-36](https://cips.cardano.org/cip/CIP-36/) registration is made.
    tx_hash: Hash,

    /// Registration nonce.
    // TODO(bkioshn): https://github.com/input-output-hk/catalyst-voices/issues/239
    #[oai(validator(minimum(value = "0"), maximum(value = "9223372036854775807")))]
    nonce: Nonce,

    /// Voting info.
    voting_info: VotingInfo,
}

impl RegistrationInfo {
    /// Creates a new `RegistrationInfo`
    #[allow(dead_code)]
    pub(crate) fn new(
        tx_hash: TxId, rewards_address: &PaymentAddress, voting_info: PublicVotingInfo,
        nonce: Nonce,
    ) -> Self {
        let voting_info = match voting_info {
            PublicVotingInfo::Direct(voting_key) => {
                VotingInfo::Direct(DirectVoter {
                    voting_key: as_hex_string(voting_key.bytes()),
                })
            },
            PublicVotingInfo::Delegated(delegations) => {
                VotingInfo::Delegated(Delegations {
                    delegations: delegations
                        .into_iter()
                        .map(|(voting_key, power)| {
                            Delegation {
                                voting_key: as_hex_string(voting_key.bytes()),
                                power,
                            }
                        })
                        .collect(),
                })
            },
        };
        Self {
            tx_hash: tx_hash.into(),
            rewards_address: as_hex_string(rewards_address),
            nonce,
            voting_info,
        }
    }
}

impl Example for RegistrationInfo {
    #[allow(clippy::expect_used)]
    fn example() -> Self {
        Self {
            rewards_address: "0xe0f9722f71d23654387ec1389fe253d380653f4f7e7305a80cf5c4dfa1"
                .to_string(),
            tx_hash: hex::decode(
                "27551498616e8da138780350a7cb8c18ef72cb01b0a6d40c785d095bcc8b1973",
            )
            .expect("Invalid hex")
            .into(),
            nonce: 11_623_850,
            voting_info: VotingInfo::Delegated(Delegations {
                delegations: vec![Delegation {
                    voting_key:
                        "0xb16f03d67e95ddd321df4bee8658901eb183d4cb5623624ff5edd7fe54f8e857"
                            .to_string(),
                    power: 1,
                }],
            }),
        }
    }
}