From 1147466362ceedf9912cc3e0672cd75f4ad86c37 Mon Sep 17 00:00:00 2001 From: yenda Date: Wed, 4 Sep 2019 16:43:01 +0200 Subject: [PATCH] integrate status-go mailserver api --- src/status_im/data_store/core.cljs | 9 +- src/status_im/data_store/mailservers.cljs | 69 ++++------- src/status_im/ethereum/json_rpc.cljs | 5 +- src/status_im/mailserver/core.cljs | 112 +++++++++--------- src/status_im/multiaccounts/login/core.cljs | 13 +- src/status_im/protocol/core.cljs | 53 +++++++-- src/status_im/transport/core.cljs | 1 + test/cljs/status_im/test/mailserver/core.cljs | 12 +- test/cljs/status_im/test/transport/core.cljs | 40 +++---- 9 files changed, 169 insertions(+), 145 deletions(-) diff --git a/src/status_im/data_store/core.cljs b/src/status_im/data_store/core.cljs index 063b510b46..203a4b53dd 100644 --- a/src/status_im/data_store/core.cljs +++ b/src/status_im/data_store/core.cljs @@ -201,10 +201,11 @@ (fx/defn handle-change-multiaccount-success {:events [::multiaccount-change-success] - :interceptors [(re-frame/inject-cofx :data-store/get-all-mailservers) - (re-frame/inject-cofx :data-store/mailserver-topics)]} - [cofx] - (protocol/initialize-protocol cofx)) + :interceptors [(re-frame/inject-cofx :data-store/mailserver-topics) + (re-frame/inject-cofx :data-store/all-chat-requests-ranges)]} + [{:data-store/keys [mailserver-topics mailserver-ranges] :as cofx}] + (protocol/initialize-protocol cofx {:mailserver-topics mailserver-topics + :mailserver-ranges mailserver-ranges})) (defn change-multiaccount! [address password create-database-if-not-exist?] diff --git a/src/status_im/data_store/mailservers.cljs b/src/status_im/data_store/mailservers.cljs index 533206682b..2bd7a9190b 100644 --- a/src/status_im/data_store/mailservers.cljs +++ b/src/status_im/data_store/mailservers.cljs @@ -1,27 +1,19 @@ (ns status-im.data-store.mailservers (:require [cljs.tools.reader.edn :as edn] [re-frame.core :as re-frame] - [taoensso.timbre :as log] - [status-im.utils.fx :as fx] + [status-im.data-store.realm.core :as core] [status-im.ethereum.json-rpc :as json-rpc] - [status-im.data-store.realm.core :as core])) + [status-im.utils.fx :as fx] + [taoensso.timbre :as log])) -(re-frame/reg-cofx - :data-store/get-all-mailservers - (fn [cofx _] - (assoc cofx :data-store/mailservers (mapv #(-> % - (update :id keyword) - (update :fleet keyword)) - (-> @core/account-realm - (core/get-all :mailserver) - (core/all-clj :mailserver)))))) - -(defn mailserver-request-gaps->rpc [{:keys [chat-id] :as gap}] +(defn mailserver-request-gaps->rpc + [{:keys [chat-id] :as gap}] (-> gap (assoc :chatId chat-id) (dissoc :chat-id))) -(fx/defn load-gaps [cofx chat-id success-fn] +(fx/defn load-gaps + [cofx chat-id success-fn] {::json-rpc/call [{:method "mailservers_getMailserverRequestGaps" :params [chat-id] :on-success #(let [indexed-gaps (reduce (fn [acc {:keys [id] :as g}] @@ -31,41 +23,29 @@ (success-fn chat-id indexed-gaps)) :on-failure #(log/error "failed to fetch gaps" %)}]}) -(fx/defn save-gaps [cofx gaps] +(fx/defn save-gaps + [cofx gaps] {::json-rpc/call [{:method "mailservers_addMailserverRequestGaps" :params [(map mailserver-request-gaps->rpc gaps)] :on-success #(log/info "saved gaps successfully") :on-failure #(log/error "failed to save gap" %)}]}) -(fx/defn delete-gaps [cofx ids] +(fx/defn delete-gaps + [cofx ids] {::json-rpc/call [{:method "mailservers_deleteMailserverRequestGaps" :params [ids] :on-success #(log/info "deleted gaps successfully") :on-failure #(log/error "failed to delete gap" %)}]}) -(fx/defn delete-gaps-by-chat-id [cofx chat-id] +(fx/defn delete-gaps-by-chat-id + [cofx chat-id] {::json-rpc/call [{:method "mailservers_deleteMailserverRequestGapsByChatID" :params [chat-id] :on-success #(log/info "deleted gaps successfully") :on-failure #(log/error "failed to delete gap" %)}]}) -(defn save-tx - "Returns tx function for saving a mailserver" - [{:keys [id] :as mailserver}] - (fn [realm] - (core/create realm - :mailserver - mailserver - true))) - -(defn delete-tx - "Returns tx function for deleting a mailserver" - [id] - (fn [realm] - (core/delete realm - (core/get-by-field realm :mailserver :id (name id))))) - -(defn deserialize-mailserver-topic [serialized-mailserver-topic] +(defn deserialize-mailserver-topic + [serialized-mailserver-topic] (-> serialized-mailserver-topic (update :chat-ids edn/read-string))) @@ -109,15 +89,16 @@ (log/debug "saving ranges" chat-requests-range) (core/create realm :chat-requests-range chat-requests-range true))) -(re-frame/reg-fx - ::all-chat-requests-ranges - (fn [on-success] - (on-success (reduce (fn [acc {:keys [chat-id] :as range}] - (assoc acc chat-id range)) - {} - (-> @core/account-realm - (core/get-all :chat-requests-range) - (core/all-clj :chat-requests-range)))))) +(re-frame/reg-cofx + :data-store/all-chat-requests-ranges + (fn [cofx _] + (assoc cofx :data-store/mailserver-ranges + (reduce (fn [acc {:keys [chat-id] :as range}] + (assoc acc chat-id range)) + {} + (-> @core/account-realm + (core/get-all :chat-requests-range) + (core/all-clj :chat-requests-range)))))) (defn delete-range [chat-id] diff --git a/src/status_im/ethereum/json_rpc.cljs b/src/status_im/ethereum/json_rpc.cljs index abfb8845b7..339fe9eb5f 100644 --- a/src/status_im/ethereum/json_rpc.cljs +++ b/src/status_im/ethereum/json_rpc.cljs @@ -75,7 +75,10 @@ "settings_getConfigs" {} "settings_saveNodeConfig" {} "accounts_getAccounts" {} - "accounts_saveAccounts" {}}) + "accounts_saveAccounts" {} + "mailservers_addMailserver" {} + "mailservers_getMailservers" {} + "mailservers_deleteMailserver" {}}) (defn call [{:keys [method params on-success on-error] :as p}] diff --git a/src/status_im/mailserver/core.cljs b/src/status_im/mailserver/core.cljs index 30ab4146b9..971fa7d73a 100644 --- a/src/status_im/mailserver/core.cljs +++ b/src/status_im/mailserver/core.cljs @@ -1,27 +1,28 @@ (ns ^{:doc "Mailserver events and API"} status-im.mailserver.core - (:require [re-frame.core :as re-frame] - [status-im.multiaccounts.model :as multiaccounts.model] - [status-im.fleet.core :as fleet] - [status-im.native-module.core :as status] - [status-im.utils.platform :as platform] - [status-im.transport.utils :as transport.utils] - [status-im.utils.fx :as fx] - [status-im.utils.utils :as utils] - [taoensso.timbre :as log] - [status-im.transport.db :as transport.db] - [status-im.transport.message.protocol :as protocol] - [clojure.string :as string] - [status-im.ethereum.json-rpc :as json-rpc] - [status-im.mailserver.topics :as mailserver.topics] - [status-im.mailserver.constants :as constants] + (:require [clojure.string :as string] + [re-frame.core :as re-frame] [status-im.data-store.mailservers :as data-store.mailservers] + [status-im.ethereum.json-rpc :as json-rpc] + [status-im.fleet.core :as fleet] [status-im.i18n :as i18n] - [status-im.utils.handlers :as handlers] + [status-im.mailserver.constants :as constants] + [status-im.mailserver.topics :as mailserver.topics] + [status-im.multiaccounts.model :as multiaccounts.model] [status-im.multiaccounts.update.core :as multiaccounts.update] + [status-im.native-module.core :as status] + [status-im.transport.message.protocol :as protocol] + [status-im.transport.utils :as transport.utils] + [status-im.ui.screens.mobile-network-settings.utils + :as + mobile-network-utils] [status-im.ui.screens.navigation :as navigation] - [status-im.ui.screens.mobile-network-settings.utils :as mobile-network-utils] - [status-im.utils.random :as rand])) + [status-im.utils.fx :as fx] + [status-im.utils.handlers :as handlers] + [status-im.utils.platform :as platform] + [status-im.utils.random :as rand] + [status-im.utils.utils :as utils] + [taoensso.timbre :as log])) ;; How do mailserver work ? ;; @@ -86,16 +87,6 @@ {:db (assoc db :mailserver/current-id (selected-or-random-id cofx))}) -(fx/defn add-custom-mailservers - [{:keys [db]} mailservers] - {:db (reduce (fn [db {:keys [id fleet] :as mailserver}] - (assoc-in db [:mailserver/mailservers fleet id] - (-> mailserver - (dissoc :fleet) - (assoc :user-defined true)))) - db - mailservers)}) - (defn add-peer! [enode] (status/add-peer enode (handlers/response-handler #(log/debug "mailserver: add-peer success" %) @@ -904,10 +895,9 @@ {:mailserver/decrease-limit []})))))) (fx/defn initialize-mailserver - [cofx custom-mailservers] + [cofx] (fx/merge cofx {:mailserver/set-limit constants/default-limit} - (add-custom-mailservers custom-mailservers) (set-current-mailserver))) (def enode-address-regex #"enode://[a-zA-Z0-9]+\@\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b:(\d{1,5})") @@ -957,17 +947,20 @@ (def default? (comp not :user-defined fetch)) (fx/defn edit [{:keys [db] :as cofx} id] - (let [{:keys [id - address - password - name]} (fetch cofx id) - url (when address (build-url address password))] + (let [{:keys [id address password name]} (fetch cofx id) + url (when address (build-url address password))] (fx/merge cofx (set-input :id id) (set-input :url (str url)) (set-input :name (str name)) (navigation/navigate-to-cofx :edit-mailserver nil)))) +(defn mailserver->rpc + [mailserver current-fleet] + (-> mailserver + (assoc :fleet (name current-fleet)) + (update :id name))) + (fx/defn upsert [{{:mailserver.edit/keys [mailserver] :keys [multiaccount] :as db} :db random-id-generator :random-id-generator :as cofx}] @@ -982,23 +975,37 @@ {:db (-> db (dissoc :mailserver.edit/mailserver) (assoc-in [:mailserver/mailservers current-fleet (:id mailserver)] mailserver)) - :data-store/tx [{:transaction - (data-store.mailservers/save-tx (assoc - mailserver - :fleet - current-fleet)) - ;; we naively logout if the user is connected to the edited mailserver - :success-event (when current [:multiaccounts.logout.ui/logout-confirmed])}] + ::json-rpc/call + [{:method "mailservers_addMailserver" + :params [(mailserver->rpc mailserver current-fleet)] + :on-success (fn [] + ;; we naively logout if the user is connected to + ;; the edited mailserver + (when current + (re-frame/dispatch + [:multiaccounts.logout.ui/logout-confirmed])) + (log/debug "saved mailserver" id "successfuly")) + :on-failure #(log/error "failed to save mailserver" id %)}] :dispatch [:navigate-back]})) +(defn can-delete? + [cofx id] + (not (or (default? cofx id) + (connected? cofx id)))) + (fx/defn delete [{:keys [db] :as cofx} id] - (merge (when-not (or - (default? cofx id) - (connected? cofx id)) - {:db (update-in db [:mailserver/mailservers (fleet/current-fleet db)] dissoc id) - :data-store/tx [(data-store.mailservers/delete-tx id)]}) - {:dispatch [:navigate-back]})) + (if (can-delete? cofx id) + {:db (update-in db + [:mailserver/mailservers (fleet/current-fleet db)] + dissoc id) + ::json-rpc/call + [{:method "mailservers_deleteMailserver" + :params [(name id)] + :on-success #(log/debug "deleted mailserver" id) + :on-failure #(log/error "failed to delete mailserver" id %)}] + :dispatch [:navigate-back]} + {:dispatch [:navigate-back]})) (fx/defn show-connection-confirmation [{:keys [db]} mailserver-id] @@ -1055,15 +1062,6 @@ (fx/merge cofx (multiaccounts.update/update-settings (assoc-in settings [:mailserver current-fleet] mailserver-id) {})))) -(fx/defn ranges-loaded - {:events [::ranges-loaded]} - [{:keys [db]} ranges] - {:db (assoc db :mailserver/ranges ranges)}) - -(fx/defn initialize-ranges - [{:keys [db]}] - {::data-store.mailservers/all-chat-requests-ranges - #(re-frame/dispatch [::ranges-loaded %])}) (fx/defn load-gaps-fx [{:keys [db] :as cofx} chat-id] (when-not (get-in db [:chats chat-id :gaps-loaded?]) diff --git a/src/status_im/multiaccounts/login/core.cljs b/src/status_im/multiaccounts/login/core.cljs index bdde4a368f..1d4b39a977 100644 --- a/src/status_im/multiaccounts/login/core.cljs +++ b/src/status_im/multiaccounts/login/core.cljs @@ -8,6 +8,7 @@ [status-im.contact.core :as contact] [status-im.data-store.core :as data-store] [status-im.ethereum.json-rpc :as json-rpc] + [status-im.protocol.core :as protocol] [status-im.ethereum.transactions.core :as transactions] [status-im.fleet.core :as fleet] [status-im.i18n :as i18n] @@ -26,7 +27,8 @@ [status-im.utils.universal-links.core :as universal-links] [status-im.utils.utils :as utils] [status-im.wallet.core :as wallet] - [taoensso.timbre :as log])) + [taoensso.timbre :as log] + [status-im.mailserver.core :as mailserver])) (def rpc-endpoint "https://goerli.infura.io/v3/f315575765b14720b32382a61a89341a") (def contract-address "0xfbf4c8e2B41fAfF8c616a0E49Fb4365a5355Ffaf") @@ -138,6 +140,9 @@ :networks/networks networks :multiaccount multiaccount) :notifications/request-notifications-permissions nil} + ;; NOTE: initializing mailserver depends on user mailserver + ;; preference which is why we wait for config callback + (protocol/initialize-protocol {:default-mailserver true}) (universal-links/process-stored-event) (check-network-version network-id) (chat.loading/initialize-chats) @@ -161,6 +166,8 @@ :on-success #(re-frame/dispatch [::initialize-browsers %])} {:method "permissions_getDappPermissions" :on-success #(re-frame/dispatch [::initialize-dapp-permissions %])} + {:method "mailservers_getMailservers" + :on-success #(re-frame/dispatch [::protocol/initialize-protocol {:mailservers (or % [])}])} {:method "settings_getConfigs" :params [["multiaccount" "current-network" "networks"]] :on-success #(re-frame/dispatch [::get-config-callback % stored-pns])}]} @@ -201,6 +208,10 @@ :params ["current-network" current-network] :on-success #()}]} (finish-keycard-setup) + (protocol/initialize-protocol {:mailservers [] + :mailserver-ranges {} + :mailserver-topics {} + :default-mailserver true}) (mobile-network/on-network-status-change) (chaos-mode/check-chaos-mode) (when-not platform/desktop? diff --git a/src/status_im/protocol/core.cljs b/src/status_im/protocol/core.cljs index 688ac6cd27..18ae2db67a 100644 --- a/src/status_im/protocol/core.cljs +++ b/src/status_im/protocol/core.cljs @@ -34,13 +34,48 @@ (update-sync-state error sync) (node/update-sync-state error sync))) +(defn add-custom-mailservers + [db custom-mailservers] + (reduce (fn [db {:keys [fleet] :as mailserver}] + (let [{:keys [id] :as mailserver} + (-> mailserver + (update :id keyword) + (dissoc :fleet) + (assoc :user-defined true))] + (assoc-in db + [:mailserver/mailservers (keyword fleet) id] + mailserver))) + db + custom-mailservers)) + (fx/defn initialize-protocol - [{:data-store/keys [mailserver-topics mailservers] :keys [db] :as cofx}] - (fx/merge cofx - {:db (assoc db - :rpc-url constants/ethereum-rpc-url - :mailserver/topics mailserver-topics)} - (tribute-to-talk/init) - (mailserver/initialize-ranges) - (mailserver/initialize-mailserver mailservers) - (transport/init-whisper))) + {:events [::initialize-protocol]} + [{:keys [db] :as cofx} + {:keys [mailserver-ranges mailserver-topics mailservers] :as data}] + ;; NOTE: we need to wait for `:mailservers` `:mailserver-ranges` and + ;; `:mailserver-topics` before we can proceed to init whisper + ;; since those are populated by separate events, we check here + ;; that everything has been initialized before moving forward + (let [initialization-protocol (apply conj (get db :initialization-protocol #{}) + (keys data)) + initialization-complete? (= initialization-protocol + #{:mailservers + :mailserver-ranges + :mailserver-topics + :default-mailserver})] + (fx/merge cofx + {:db (cond-> db + mailserver-ranges + (assoc :mailserver/ranges mailserver-ranges) + mailserver-topics + (assoc :mailserver/topics mailserver-topics) + mailservers + (add-custom-mailservers mailservers) + initialization-complete? + (assoc :rpc-url constants/ethereum-rpc-url) + initialization-complete? + (dissoc :initialization-protocol) + (not initialization-complete?) + (assoc :initialization-protocol initialization-protocol))} + (when initialization-complete? + (transport/init-whisper))))) diff --git a/src/status_im/transport/core.cljs b/src/status_im/transport/core.cljs index 5ac932b21d..afb1117189 100644 --- a/src/status_im/transport/core.cljs +++ b/src/status_im/transport/core.cljs @@ -42,6 +42,7 @@ (fetch-node-info-fx) (pairing/init) (publisher/start-fx) + (mailserver/initialize-mailserver) (mailserver/connect-to-mailserver))) (fx/defn stop-whisper diff --git a/test/cljs/status_im/test/mailserver/core.cljs b/test/cljs/status_im/test/mailserver/core.cljs index 6f4aaf6c26..01783c8f21 100644 --- a/test/cljs/status_im/test/mailserver/core.cljs +++ b/test/cljs/status_im/test/mailserver/core.cljs @@ -1,5 +1,6 @@ (ns status-im.test.mailserver.core (:require [cljs.test :refer-macros [deftest is testing]] + [status-im.ethereum.json-rpc :as json-rpc] [status-im.transport.utils :as utils] [status-im.mailserver.core :as mailserver] [status-im.mailserver.constants :as constants] @@ -257,7 +258,7 @@ (testing "it removes the mailserver from the list" (is (not (mailserver/fetch actual "a")))) (testing "it stores it in the db" - (is (= 1 (count (:data-store/tx actual))))))) + (is (= 1 (count (::json-rpc/call actual))))))) (testing "the mailserver is not user-defined" (let [cofx {:random-id-generator (constantly "random-id") :db {:mailserver/mailservers {:eth.beta {"a" {:id "a" @@ -295,7 +296,7 @@ (is (= [:navigate-back] (:dispatch actual)))) (testing "it stores it in the db" - (is (= 1 (count (:data-store/tx actual))))))) + (is (= 1 (count (::json-rpc/call actual))))))) (testing "existing mailserver" (let [cofx {:random-id-generator (constantly "random-id") :db {:mailserver.edit/mailserver {:id {:value :a} @@ -317,12 +318,7 @@ :user-defined true}}} (get-in actual [:db :mailserver/mailservers])))) (testing "it stores it in the db" - (is (= 1 (count (:data-store/tx actual))))) - (testing "it logs the user out if connected to the current mailserver" - (let [actual (mailserver/upsert (assoc-in cofx - [:db :mailserver/current-id] :a))] - (is (= [:multiaccounts.logout.ui/logout-confirmed] - (-> actual :data-store/tx first :success-event)))))))) + (is (= 1 (count (::json-rpc/call actual)))))))) (defn cofx-fixtures [sym-key registered-peer?] {:db {:mailserver/state :connected diff --git a/test/cljs/status_im/test/transport/core.cljs b/test/cljs/status_im/test/transport/core.cljs index 7a550e4f5b..35e12b34ee 100644 --- a/test/cljs/status_im/test/transport/core.cljs +++ b/test/cljs/status_im/test/transport/core.cljs @@ -8,42 +8,40 @@ (deftest init-whisper (let [cofx {:db {:multiaccount {:public-key "1"}}}] (testing "custom mailservers" - (let [ms-1 {:id "1" + (let [ms-1 {:id :a :fleet :eth.beta :name "name-1" :address "address-1" :password "password-1"} - ms-2 {:id "2" + ms-2 {:id :b :fleet :eth.beta :name "name-2" :address "address-2" :password "password-2"} - ms-3 {:id "3" + ms-3 {:id :c :fleet :eth.test :name "name-3" :address "address-3" :password "password-3"} - expected-mailservers {:eth.beta {"1" (-> ms-1 - (dissoc :fleet) - (assoc :user-defined true)) - "2" (-> ms-2 - (dissoc ms-2 :fleet) - (assoc :user-defined true))} - :eth.test {"3" (-> ms-3 - (dissoc :fleet) - (assoc :user-defined true))}} - cofx-with-ms (assoc cofx - :data-store/mailservers - [ms-1 - ms-2 - ms-3])] + expected-mailservers {:eth.beta {:a (-> ms-1 + (dissoc :fleet) + (assoc :user-defined true)) + :b (-> ms-2 + (dissoc ms-2 :fleet) + (assoc :user-defined true))} + :eth.test {:c (-> ms-3 + (dissoc :fleet) + (assoc :user-defined true))}}] (is (= expected-mailservers (-> (get-in - (protocol/initialize-protocol cofx-with-ms) + (protocol/initialize-protocol cofx {:mailservers [ms-1 ms-2 ms-3] + :mailserver-ranges {} + :mailserver-topics {} + :default-mailserver true}) [:db :mailserver/mailservers]) - (update-in [:eth.beta "1"] dissoc :generating-sym-key?) - (update-in [:eth.beta "2"] dissoc :generating-sym-key?) - (update-in [:eth.test "3"] dissoc :generating-sym-key?)))))))) + (update-in [:eth.beta :a] dissoc :generating-sym-key?) + (update-in [:eth.beta :b] dissoc :generating-sym-key?) + (update-in [:eth.test :c] dissoc :generating-sym-key?)))))))) (def sig "0x04325367620ae20dd878dbb39f69f02c567d789dd21af8a88623dc5b529827c2812571c380a2cd8236a2851b8843d6486481166c39debf60a5d30b9099c66213e4")