Skip to main content

iris_chat_protocol/
lib.rs

1mod protocol_engine;
2mod storage;
3
4use nostr::{Alphabet, SingleLetterTag, UnsignedEvent};
5use nostr::{Event, Filter, Keys, Kind, PublicKey, Timestamp};
6use nostr_double_ratchet::{
7    AuthorizedDevice, DevicePubkey as NdrDevicePubkey, DeviceRoster, DomainError,
8    Error as NdrError, GroupIncomingEvent, GroupManagerSnapshot, GroupPairwiseCommand,
9    GroupPayloadCodec, GroupPendingFanout, GroupPreparedPublish, GroupPreparedSend, GroupProtocol,
10    GroupSenderKeyHandleResult, GroupSenderKeyMessage, GroupSnapshot, Invite, MessageEnvelope,
11    OwnerPubkey as NdrOwnerPubkey, PreparedSend, ProtocolContext, RelayGap, SenderKeyRepairRequest,
12    SessionManager, SessionManagerSnapshot, SessionState, UnixSeconds as NdrUnixSeconds,
13};
14use nostr_double_ratchet_nostr::{
15    group_sender_key_message_event, invite_response_event, message_event,
16    parse_group_sender_key_message_event, parse_group_sender_key_message_event_unchecked,
17    parse_invite_event, parse_invite_response_event, parse_message_event, JsonGroupPayloadCodecV1,
18    NostrGroupManager,
19};
20use nostr_double_ratchet_pairwise_codec as pairwise_codec;
21use rand::rngs::OsRng;
22use serde::{Deserialize, Serialize};
23use std::collections::{BTreeMap, HashSet};
24use std::sync::{Arc, Mutex};
25use std::time::{SystemTime, UNIX_EPOCH};
26
27pub use nostr_double_ratchet_nostr::{
28    is_app_keys_event, AppKeys, APP_KEYS_EVENT_KIND, CHAT_MESSAGE_KIND, CHAT_SETTINGS_KIND,
29    GROUP_SENDER_KEY_MESSAGE_KIND, INVITE_EVENT_KIND, INVITE_RESPONSE_KIND, MESSAGE_EVENT_KIND,
30    REACTION_KIND, RECEIPT_KIND,
31};
32pub use nostr_double_ratchet_runtime::StorageAdapter;
33pub use protocol_engine::*;
34pub use storage::SqliteStorageAdapter;
35
36const DEVICE_INVITE_DISCOVERY_LOOKBACK_SECS: u64 = 30 * 24 * 60 * 60;
37const DEVICE_INVITE_DISCOVERY_LIMIT: usize = 256;
38const NDR_APP_KEYS_D_TAG: &str = "double-ratchet/app-keys";
39const NDR_INVITES_L_TAG: &str = "double-ratchet/invites";
40pub const PROTOCOL_SENDER_KEY_REPAIR_RETRY_DELAYS_SECS: [u64; 5] = [10, 30, 60, 60, 60];
41
42fn protocol_sender_key_repair_retry_delay_secs(sent_request_count: u32) -> u64 {
43    let index = sent_request_count
44        .saturating_sub(1)
45        .min((PROTOCOL_SENDER_KEY_REPAIR_RETRY_DELAYS_SECS.len() - 1) as u32)
46        as usize;
47    PROTOCOL_SENDER_KEY_REPAIR_RETRY_DELAYS_SECS[index]
48}
49
50fn protocol_sender_key_repair_next_retry_at(
51    now: NdrUnixSeconds,
52    sent_request_count: u32,
53) -> NdrUnixSeconds {
54    NdrUnixSeconds(
55        now.get()
56            .saturating_add(protocol_sender_key_repair_retry_delay_secs(
57                sent_request_count,
58            )),
59    )
60}
61
62pub type SharedConnection = Arc<Mutex<rusqlite::Connection>>;
63
64#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
65pub struct UnixSeconds(pub u64);
66
67impl UnixSeconds {
68    pub fn get(self) -> u64 {
69        self.0
70    }
71}
72
73fn unix_now() -> UnixSeconds {
74    UnixSeconds(
75        SystemTime::now()
76            .duration_since(UNIX_EPOCH)
77            .unwrap_or_default()
78            .as_secs(),
79    )
80}