/* * settings_sync.h — NIP-78 (kind 30078) settings sync for sovereign_browser * * Syncs user-configurable, device-independent settings across all devices * the user logs in on. Uses a single shared kind 30078 addressable event * with d-tag "user-settings" (the same event used by ~/lt/client and * ~/lt/didactyl). The content is NIP-44 encrypted (self-to-self) JSON * with a "global" namespace (shared agent provider catalog) and per-app * namespaces (e.g. "sovereign_browser", "client", "didactyl"). * * sovereign_browser writes only the "sovereign_browser" and "global.agent" * namespaces; other apps' namespaces are preserved via read-modify-write. * * Device-specific settings (agent port, allowed origins, session restore, * security toggles) are NOT synced — they stay local only. * * See plans/cross-project-agent-sync.md for the full design. */ #ifndef SETTINGS_SYNC_H #define SETTINGS_SYNC_H #include /* nostr_signer_t is needed for the init function */ #include "nostr_core/nostr_signer.h" #ifdef __cplusplus extern "C" { #endif /* The d-tag identifier used for the shared kind 30078 user-settings event. * This is shared with ~/lt/client and ~/lt/didactyl. */ #define SETTINGS_SYNC_D_TAG "user-settings" /* The legacy d-tag used before the migration to the shared event. */ #define SETTINGS_SYNC_D_TAG_LEGACY "sovereign_browser" /* The Nostr kind for arbitrary custom app data (NIP-78). */ #define SETTINGS_SYNC_KIND 30078 /* * Initialize the settings sync module. Stores the signer + pubkey * references for later publish/merge operations. * * signer — the user's nostr_signer_t (NULL for read-only/no-login) * pubkey_hex — the user's hex pubkey (64 chars, may be NULL) * * Call after login and after shortcuts_load() / settings_load(). */ void settings_sync_init(nostr_signer_t *signer, const char *pubkey_hex); /* * Serialize all syncable settings + shortcuts, NIP-44 encrypt to self, * build and sign a kind 30078 event, publish to bootstrap relays, and * store in SQLite. Debounced internally (500ms) so rapid edits coalesce * into a single publish. * * Safe to call from the main thread. No-op if no signer is available * (read-only / no-login mode). */ void settings_sync_publish(void); /* * Decrypt and merge settings from a fetched kind 30078 event. * Called by the relay fetch thread after login. Compares the event's * created_at to the last-synced timestamp; if the Nostr event is newer, * overwrites local db_kv values and reloads in-memory bindings. * * event — a cJSON object representing a kind 30078 event with * d-tag "user-settings" (or the legacy "sovereign_browser" * d-tag, which is migrated to the new format on merge). * * Returns 0 on success, -1 on error / not applicable. */ int settings_sync_merge_from_nostr(const void *event_cjson); /* * Update the signer reference (e.g. after switching identity). */ void settings_sync_set_signer(nostr_signer_t *signer, const char *pubkey_hex); #ifdef __cplusplus } #endif #endif /* SETTINGS_SYNC_H */