Skip to main content

iris_chat_protocol/
lib.rs

1mod direct_messages;
2mod nearby;
3mod protocol_engine;
4mod storage;
5
6use nostr::UnsignedEvent;
7use nostr::{Event, Keys, Kind, PublicKey, Timestamp};
8use nostr_double_ratchet::{
9    group_sender_key_message_event, invite_response_event, is_group_roster_fact_event,
10    parse_group_roster_fact_event, parse_group_sender_key_message_event,
11    parse_group_sender_key_message_event_unchecked, project_group_roster_fact_events,
12    GroupEventManager, JsonGroupPayloadCodecV1,
13};
14use nostr_double_ratchet::{
15    AuthorizedDevice, Delivery, DevicePubkey as NdrDevicePubkey, DeviceRecordSnapshot,
16    DeviceRoster, DomainError, Error as NdrError, GroupIncomingEvent, GroupManagerSnapshot,
17    GroupPairwiseCommand, GroupPayloadCodec, GroupPendingFanout, GroupPreparedPublish,
18    GroupPreparedSend, GroupProtocol, GroupSenderKeyHandleResult, GroupSenderKeyMessage,
19    GroupSnapshot, MessageEnvelope, OwnerPubkey as NdrOwnerPubkey, PreparedSend, ProtocolContext,
20    SenderKeyRepairRequest, SessionManager, UserRecordSnapshot,
21};
22use nostr_double_ratchet_pairwise_codec as pairwise_codec;
23use rand::rngs::OsRng;
24use serde::{Deserialize, Serialize};
25use std::collections::{BTreeMap, BTreeSet, HashSet};
26use std::sync::{Arc, Mutex};
27use std::time::{SystemTime, UNIX_EPOCH};
28
29pub use direct_messages::{
30    DirectChatSnapshot, DirectInviteAcceptanceOutcome, DirectMessageCommand, DirectMessageDelivery,
31    DirectMessageService, DirectMessageSnapshot, DirectThreadSnapshot,
32};
33pub use nearby::{
34    decode_nearby_envelope_frame, decode_nearby_envelope_json, decode_nearby_frame_json,
35    encode_nearby_envelope_frame, encode_nearby_envelope_json, encode_nearby_frame_json,
36    nearby_frame_body_len_from_header, read_nearby_frame, NearbyEnvelope, NearbyFrameAssembler,
37    NearbyInventoryItem, NEARBY_ENVELOPE_VERSION, NEARBY_FRAME_HEADER_BYTES,
38    NEARBY_MAX_FRAME_BODY_BYTES,
39};
40pub use nostr_double_ratchet::{
41    build_group_roster_fact_filter, build_protocol_discovery_filters, group_roster_unsigned_event,
42    invite_unsigned_event, invite_url, is_app_keys_event, parse_invite_event,
43    parse_invite_response_event, parse_invite_url, parse_message_event, AppKeys, DeviceEntry,
44    GroupRosterFact, APP_KEYS_EVENT_KIND, CHAT_MESSAGE_KIND, CHAT_SETTINGS_KIND,
45    GROUP_ROSTER_FACT_KIND, GROUP_ROSTER_FACT_SCHEMA, GROUP_ROSTER_FACT_TYPE,
46    GROUP_SENDER_KEY_MESSAGE_KIND, INVITE_EVENT_KIND, INVITE_LIST_LABEL, INVITE_RESPONSE_KIND,
47    MESSAGE_EVENT_KIND, REACTION_KIND, RECEIPT_KIND,
48};
49pub use nostr_double_ratchet::{
50    Invite, SessionManagerSnapshot, SessionState, UnixSeconds as NdrUnixSeconds,
51};
52pub use protocol_engine::*;
53pub use storage::{
54    DebouncedFileStorage, FileStorageAdapter, InMemoryStorage, SqliteStorageAdapter,
55    StorageAdapter, StorageError, StorageResult,
56};
57
58const GROUP_ROSTER_FACT_EVENT_HISTORY_LIMIT: usize = 256;
59pub const PROTOCOL_SENDER_KEY_REPAIR_RETRY_DELAYS_SECS: [u64; 5] = [10, 30, 60, 60, 60];
60
61fn protocol_sender_key_repair_retry_delay_secs(sent_request_count: u32) -> u64 {
62    let index = sent_request_count
63        .saturating_sub(1)
64        .min((PROTOCOL_SENDER_KEY_REPAIR_RETRY_DELAYS_SECS.len() - 1) as u32)
65        as usize;
66    PROTOCOL_SENDER_KEY_REPAIR_RETRY_DELAYS_SECS[index]
67}
68
69fn protocol_sender_key_repair_next_retry_at(
70    now: NdrUnixSeconds,
71    sent_request_count: u32,
72) -> NdrUnixSeconds {
73    NdrUnixSeconds(
74        now.get()
75            .saturating_add(protocol_sender_key_repair_retry_delay_secs(
76                sent_request_count,
77            )),
78    )
79}
80
81pub type SharedConnection = Arc<Mutex<rusqlite::Connection>>;
82
83#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
84pub struct UnixSeconds(pub u64);
85
86impl UnixSeconds {
87    pub fn get(self) -> u64 {
88        self.0
89    }
90}
91
92fn unix_now() -> UnixSeconds {
93    UnixSeconds(
94        SystemTime::now()
95            .duration_since(UNIX_EPOCH)
96            .unwrap_or_default()
97            .as_secs(),
98    )
99}