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