(ns ^{:doc "API to init and stop whisper messaging"} status-im.transport.core (:require [re-frame.core :as re-frame] [status-im.constants :as constants] [status-im.data-store.transport :as transport-store] [status-im.transport.handlers :as transport.handlers] [status-im.transport.inbox :as inbox] status-im.transport.filters [status-im.transport.utils :as transport.utils] [status-im.utils.handlers :as handlers] [status-im.utils.handlers-macro :as handlers-macro] [taoensso.timbre :as log])) (defn init-whisper "Initialises whisper protocol by: - adding fixed shh discovery filter - restoring existing symetric keys along with their unique filters - (optionally) initializing offline inboxing" [current-account-id {:keys [db web3] :as cofx}] (log/debug :init-whisper) (when-let [public-key (get-in db [:account/account :public-key])] (let [sym-key-added-callback (fn [chat-id sym-key sym-key-id] (re-frame/dispatch [::sym-key-added {:chat-id chat-id :sym-key sym-key :sym-key-id sym-key-id}])) topic (transport.utils/get-topic constants/contact-discovery)] (handlers-macro/merge-fx cofx {:shh/add-discovery-filter {:web3 web3 :private-key-id public-key :topic topic} :shh/restore-sym-keys {:web3 web3 :transport (:transport/chats db) :on-success sym-key-added-callback}} (inbox/connect-to-mailserver) (transport.handlers/resend-contact-messages))))) ;;TODO (yenda) remove once go implements persistence ;;Since symkeys are not persisted, we restore them via add sym-keys, ;;this is the callback that is called when a key has been restored for a particular chat. ;;it saves the sym-key-id in app-db to send messages later ;;and starts a filter to receive messages (handlers/register-handler-fx ::sym-key-added (fn [{:keys [db]} [_ {:keys [chat-id sym-key sym-key-id]}]] (let [web3 (:web3 db) {:keys [topic] :as chat} (get-in db [:transport/chats chat-id])] {:db (assoc-in db [:transport/chats chat-id :sym-key-id] sym-key-id) :data-store/tx [(transport-store/save-transport-tx {:chat-id chat-id :chat (assoc chat :sym-key-id sym-key-id)})] :shh/add-filter {:web3 web3 :sym-key-id sym-key-id :topic topic :chat-id chat-id}}))) ;;TODO (yenda) uncomment and rework once go implements persistence #_(doseq [[chat-id {:keys [sym-key-id topic] :as chat}] transport] (when sym-key-id (filters/add-filter! web3 {:symKeyID sym-key-id :topics [topic]} (fn [js-error js-message] (re-frame/dispatch [:protocol/receive-whisper-message js-error js-message chat-id]))))) (defn stop-whisper "Stops whisper protocol by removing all existing shh filters It is necessary to remove the filters because status-go there isn't currently a logout feature in status-go to clean-up after logout. When logging out of account A and logging in account B, account B would receive account A messages without this." [{:keys [db]}] (let [{:transport/keys [chats discovery-filter]} db chat-filters (mapv :filter (vals chats)) all-filters (conj chat-filters discovery-filter)] {:shh/remove-filters all-filters}))