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