fedimint_mint_common/
common.rs

1use std::fmt::Debug;
2
3use bitcoin_hashes::{Hash, sha256};
4use fedimint_core::encoding::{Decodable, Encodable};
5use fedimint_core::secp256k1;
6use secp256k1::{Keypair, Message, PublicKey, SECP256K1, Secp256k1, Signing, Verification};
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Serialize, Deserialize, Encodable, Decodable)]
10pub struct BackupRequest {
11    pub id: PublicKey,
12    #[serde(with = "fedimint_core::hex::serde")]
13    pub payload: Vec<u8>,
14    pub timestamp: std::time::SystemTime,
15}
16
17impl BackupRequest {
18    fn hash(&self) -> sha256::Hash {
19        self.consensus_hash()
20    }
21
22    pub fn sign(self, keypair: &Keypair) -> anyhow::Result<SignedBackupRequest> {
23        let signature =
24            SECP256K1.sign_schnorr(&Message::from_digest(*self.hash().as_ref()), keypair);
25
26        Ok(SignedBackupRequest {
27            request: self,
28            signature,
29        })
30    }
31}
32
33#[derive(Debug, Serialize, Deserialize)]
34pub struct SignedBackupRequest {
35    #[serde(flatten)]
36    request: BackupRequest,
37    #[serde(with = "::fedimint_core::encoding::as_hex")]
38    pub signature: fedimint_core::secp256k1::schnorr::Signature,
39}
40
41impl SignedBackupRequest {
42    pub fn verify_valid<C>(&self, ctx: &Secp256k1<C>) -> Result<&BackupRequest, secp256k1::Error>
43    where
44        C: Signing + Verification,
45    {
46        ctx.verify_schnorr(
47            &self.signature,
48            &Message::from_digest_slice(&self.request.hash().to_byte_array()).expect("Can't fail"),
49            &self.request.id.x_only_public_key().0,
50        )?;
51
52        Ok(&self.request)
53    }
54}