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