srb_trfc/
types.rs

1use soroban_sdk::{contracttype, xdr::ToXdr, Address, BytesN, Env, String, Vec};
2
3#[contracttype]
4#[derive(Clone, Debug, PartialEq, Eq)]
5pub struct WeightedSigner {
6    pub signer: BytesN<32>, // Ed25519 public key
7    pub weight: u128,
8}
9
10#[contracttype]
11#[derive(Clone, Debug, PartialEq, Eq)]
12pub struct WeightedSigners {
13    pub signers: Vec<WeightedSigner>,
14    pub threshold: u128,
15    pub nonce: BytesN<32>,
16}
17
18/// `ProofSignature` represents an optional signature from a signer.
19/// Since Soroban doesn't support use of `Option` in it's contract interfaces,
20/// we use this enum instead.
21#[contracttype]
22#[derive(Clone, Debug, PartialEq, Eq)]
23pub enum ProofSignature {
24    Signed(BytesN<64>), // Ed25519 signature
25    Unsigned,
26}
27
28/// `ProofSigner` represents a signer in a proof. If the signer submitted a signature,
29/// and if it is being included in the proof to meet the threshold, then a `ProofSignature` is attached.
30/// Otherwise, the `ProofSignature` is `Unsigned`.
31#[contracttype]
32#[derive(Clone, Debug, PartialEq, Eq)]
33pub struct ProofSigner {
34    pub signer: WeightedSigner,
35    pub signature: ProofSignature,
36}
37
38/// `Proof` represents a proof that a set of signers have signed a message.
39/// All weighted signers are included in the along with a signature, if they have signed the message,
40/// until threshold is met.
41#[contracttype]
42#[derive(Clone, Debug, PartialEq, Eq)]
43pub struct Proof {
44    pub signers: Vec<ProofSigner>,
45    pub threshold: u128,
46    pub nonce: BytesN<32>,
47}
48
49#[contracttype]
50#[derive(Clone, Debug, Eq, PartialEq)]
51pub enum CommandType {
52    ApproveMessages,
53    RotateSigners,
54}
55
56#[contracttype]
57#[derive(Clone, Debug, Eq, PartialEq)]
58pub struct Message {
59    pub source_chain: String,
60    pub message_id: String,
61    pub source_address: String,
62    pub contract_address: Address,
63    pub payload_hash: BytesN<32>,
64}
65
66impl WeightedSigners {
67    pub fn hash(&self, env: &Env) -> BytesN<32> {
68        env.crypto().keccak256(&self.clone().to_xdr(env)).into()
69    }
70
71    pub fn signers_rotation_hash(&self, env: &Env) -> BytesN<32> {
72        env.crypto()
73            .keccak256(&(CommandType::RotateSigners, self.clone()).to_xdr(env))
74            .into()
75    }
76}
77
78impl Proof {
79    /// Get the weighted signers from the proof.
80    pub fn weighted_signers(&self) -> WeightedSigners {
81        let mut signers = Vec::new(self.signers.env());
82
83        for ProofSigner { signer, .. } in self.signers.iter() {
84            signers.push_back(signer);
85        }
86
87        WeightedSigners {
88            signers,
89            threshold: self.threshold,
90            nonce: self.nonce.clone(),
91        }
92    }
93}