1use crate::crypto::{CryptoProvider, DefaultProvider, PrivateIdentity};
4use crate::{PeerId, Result};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
8#[serde(rename_all = "snake_case")]
9pub enum SpaceKind {
10 Private,
11 InviteOnly,
12 Public,
13 Ephemeral,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct SpaceRecord {
18 pub name: String,
19 pub kind: SpaceKind,
20 pub members: Vec<PeerId>,
21 pub retention: String,
22 pub created_at: u64,
23 pub founder: PeerId,
24 #[serde(with = "serde_bytes")]
25 pub signature: [u8; 64],
26}
27
28impl SpaceRecord {
29 pub fn issue(
30 author: &PrivateIdentity,
31 name: String,
32 kind: SpaceKind,
33 members: Vec<PeerId>,
34 retention: String,
35 now: u64,
36 ) -> Self {
37 let mut rec = Self {
38 name,
39 kind,
40 members,
41 retention,
42 created_at: now,
43 founder: author.peer_id,
44 signature: [0; 64],
45 };
46 rec.signature = DefaultProvider.sign(&author.signing_key(), &rec.preimage());
47 rec
48 }
49
50 pub fn preimage(&self) -> Vec<u8> {
51 let mut b = Vec::from(&b"ddp-space-v2"[..]);
52 b.extend_from_slice(self.name.as_bytes());
53 b.extend_from_slice(self.founder.as_bytes());
54 b.extend_from_slice(&self.created_at.to_be_bytes());
55 b
56 }
57
58 pub fn verify(&self, founder_pk: &[u8; 32]) -> Result<()> {
59 DefaultProvider.verify(founder_pk, &self.preimage(), &self.signature)
60 }
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct SpaceInvite {
65 pub space: String,
66 pub invitee: Option<PeerId>,
67 pub issued_by: PeerId,
68 pub created_at: u64,
69 #[serde(with = "serde_bytes")]
70 pub signature: [u8; 64],
71}
72
73impl SpaceInvite {
74 pub fn issue(
75 author: &PrivateIdentity,
76 space: String,
77 invitee: Option<PeerId>,
78 now: u64,
79 ) -> Self {
80 let mut inv = Self {
81 space,
82 invitee,
83 issued_by: author.peer_id,
84 created_at: now,
85 signature: [0; 64],
86 };
87 let mut msg = Vec::from(&b"ddp-space-invite-v2"[..]);
88 msg.extend_from_slice(inv.space.as_bytes());
89 msg.extend_from_slice(author.peer_id.as_bytes());
90 inv.signature = DefaultProvider.sign(&author.signing_key(), &msg);
91 inv
92 }
93}