diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index c1d25bce46..580d8a17b6 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -140,10 +140,7 @@ (defn default-account-settings [] {:wallet {:visible-tokens {:testnet #{:STT :ATT} - :mainnet #{:SNT}}} - :wnode {:testnet (rand-nth (keys (:testnet default-wnodes))) - :mainnet (rand-nth (keys (:mainnet default-wnodes))) - :rinkeby (rand-nth (keys (:rinkeby default-wnodes)))}}) + :mainnet #{:SNT}}}}) (def currencies {:aed {:id :aed :code "AED" :display-name (i18n/label :t/currency-display-name-aed) :symbol "د.إ"} diff --git a/src/status_im/models/mailserver.cljs b/src/status_im/models/mailserver.cljs index 967a1a6835..729acf11be 100644 --- a/src/status_im/models/mailserver.cljs +++ b/src/status_im/models/mailserver.cljs @@ -3,6 +3,7 @@ [clojure.string :as string] [status-im.utils.handlers-macro :as handlers-macro] [status-im.utils.ethereum.core :as ethereum] + [status-im.models.network :as models.network] [status-im.data-store.mailservers :as data-store.mailservers])) (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})") @@ -20,23 +21,6 @@ (defn valid-enode-address? [address] (re-matches enode-address-regex address)) -(defn- get-chain [db] - (let [network (get (:networks (:account/account db)) (:network db))] - (ethereum/network->chain-keyword network))) - -(defn- address->mailserver [address] - (let [[enode password url :as response] (extract-url-components address)] - (cond-> {:address (if (seq response) - (str "enode://" enode "@" url) - address) - :user-defined true} - password (assoc :password password)))) - -(defn- build [id mailserver-name address] - (assoc (address->mailserver address) - :id (string/replace id "-" "") - :name mailserver-name)) - (defn build-url [address password] (let [[initial host] (extract-address-components address)] (str "enode://" initial ":" password "@" host))) @@ -53,12 +37,37 @@ :name (string/blank? value) :url (not (valid-enode-url? value)))})}) -(defn connected? [id {:keys [db]}] - (let [current-id (get-in db [:account/account :settings :wnode (get-chain db)])] - (= current-id id))) +(defn- address->mailserver [address] + (let [[enode password url :as response] (extract-url-components address)] + (cond-> {:address (if (seq response) + (str "enode://" enode "@" url) + address) + :user-defined true} + password (assoc :password password)))) -(defn fetch [id {:keys [db]}] - (get-in db [:inbox/wnodes (get-chain db) id])) +(defn- build [id mailserver-name address] + (assoc (address->mailserver address) + :id (string/replace id "-" "") + :name mailserver-name)) + +(defn connected? [id {:keys [db]}] + (= (:inbox/current-id db) id)) + +(defn fetch [id {:keys [db] :as cofx}] + (get-in db [:inbox/wnodes (models.network/get-chain cofx) id])) + +(defn fetch-current [{:keys [db] :as cofx}] + (fetch (:inbox/current-id db) cofx)) + +(defn selected-or-random-id + "Use the preferred mailserver if set & exists, otherwise picks one randomly" + [{:keys [db] :as cofx}] + (let [chain (models.network/get-chain cofx) + preference (get-in db [:account/account :settings :wnode chain])] + (if (and preference + (fetch preference cofx)) + preference + (-> db :inbox/wnodes chain keys rand-nth)))) (def default? (comp not :user-defined fetch)) @@ -66,9 +75,21 @@ (when-not (or (default? id cofx) (connected? id cofx)) - {:db (update-in db [:inbox/wnodes (get-chain db)] dissoc id) + {:db (update-in db [:inbox/wnodes (models.network/get-chain cofx)] dissoc id) :data-store/tx [(data-store.mailservers/delete-tx id)]})) +(defn set-current-mailserver [{:keys [db] :as cofx}] + {:db (assoc db :inbox/current-id (selected-or-random-id cofx))}) + +(defn add-custom-mailservers [mailservers {:keys [db]}] + {:db (reduce (fn [db {:keys [id chain] :as mailserver}] + (assoc-in db [:inbox/wnodes (keyword chain) id] + (-> mailserver + (dissoc :chain) + (assoc :user-defined true)))) + db + mailservers)}) + (defn edit [id {:keys [db] :as cofx}] (let [{:keys [id address diff --git a/src/status_im/models/network.cljs b/src/status_im/models/network.cljs index 7332b44bf2..664fe8ed2e 100644 --- a/src/status_im/models/network.cljs +++ b/src/status_im/models/network.cljs @@ -45,6 +45,10 @@ :name network-name :config config})) +(defn get-chain [{:keys [db]}] + (let [network (get (:networks (:account/account db)) (:network db))] + (ethereum/network->chain-keyword network))) + (defn set-input [input-key value {:keys [db]}] {:db (-> db (update-in [:networks/manage input-key] assoc :value value) diff --git a/src/status_im/protocol/handlers.cljs b/src/status_im/protocol/handlers.cljs index bd4b17cafd..c42946229b 100644 --- a/src/status_im/protocol/handlers.cljs +++ b/src/status_im/protocol/handlers.cljs @@ -43,7 +43,7 @@ :web3 web3 :rpc-url (or ethereum-rpc-url constants/ethereum-rpc-url) :transport/chats transport)} - (transport.inbox/add-custom-mailservers mailservers) + (transport.inbox/initialize-offline-inbox mailservers) (transport/init-whisper current-account-id))) ;;; INITIALIZE PROTOCOL (handlers/register-handler-fx diff --git a/src/status_im/transport/inbox.cljs b/src/status_im/transport/inbox.cljs index d84e218245..121924ab49 100644 --- a/src/status_im/transport/inbox.cljs +++ b/src/status_im/transport/inbox.cljs @@ -15,6 +15,7 @@ [status-im.data-store.accounts :as accounts-store] [status-im.utils.handlers-macro :as handlers-macro] [status-im.data-store.core :as data-store] + [status-im.models.mailserver :as models.mailserver] [status-im.ui.screens.accounts.events :as accounts] [status-im.data-store.transport :as transport-store])) @@ -80,14 +81,6 @@ chain (ethereum/network->chain-keyword network)] {:db (assoc-in db [:inbox/wnodes chain id :sym-key-id] sym-key-id)})) -(defn get-current-wnode [db] - (let [network (get (:networks (:account/account db)) (:network db)) - chain (ethereum/network->chain-keyword network) - wnode-id (get-in db [:account/account :settings :wnode chain])] - (get-in db [:inbox/wnodes chain wnode-id]))) - -(def get-current-wnode-address (comp :address get-current-wnode)) - (defn registered-peer? [peers enode] (let [peer-ids (into #{} (map :id) peers) enode-id (transport.utils/extract-enode-id enode)] @@ -193,7 +186,7 @@ mailserver-status is changed to error if it is not connected by then" [{:keys [db] :as cofx}] (let [web3 (:web3 db) - {:keys [address] :as wnode} (get-current-wnode db) + {:keys [address] :as wnode} (models.mailserver/fetch-current cofx) peers-summary (:peers-summary db) connected? (registered-peer? peers-summary address)] (when config/offline-inbox-enabled? @@ -216,7 +209,7 @@ (when (and (:account/account db) config/offline-inbox-enabled?) (let [{:keys [peers-summary peers-count]} db - wnode (get-current-wnode-address db) + wnode (:address (models.mailserver/fetch-current cofx)) mailserver-was-registered? (registered-peer? previous-summary wnode) mailserver-is-registered? (registered-peer? peers-summary @@ -257,7 +250,7 @@ (defn request-messages ([{:keys [db now] :as cofx}] - (let [wnode (get-current-wnode db) + (let [wnode (models.mailserver/fetch-current cofx) web3 (:web3 db) now-in-s (quot now 1000) last-request (or @@ -283,7 +276,7 @@ (request-messages cofx)))) (defn request-chat-history [chat-id {:keys [db now] :as cofx}] - (let [wnode (get-current-wnode db) + (let [wnode (models.mailserver/fetch-current cofx) web3 (:web3 db) topic (get-in db [:transport/chats chat-id :topic]) now-in-s (quot now 1000)] @@ -305,15 +298,6 @@ (update-mailserver-status :connected) (request-messages)))) -(defn add-custom-mailservers [mailservers {:keys [db]}] - {:db (reduce (fn [db {:keys [id chain] :as mailserver}] - (assoc-in db [:inbox/wnodes (keyword chain) id] - (-> mailserver - (dissoc :chain) - (assoc :user-defined true)))) - db - mailservers)}) - (handlers/register-handler-fx :inbox/get-sym-key-success (fn [{:keys [db] :as cofx} [_ wnode sym-key-id]] @@ -368,6 +352,11 @@ :chat (assoc (get-in db [:transport/chats chat-id]) :fetch-history? false)})]}) +(defn initialize-offline-inbox [custom-mailservers cofx] + (handlers-macro/merge-fx cofx + (models.mailserver/add-custom-mailservers custom-mailservers) + (models.mailserver/set-current-mailserver))) + (handlers/register-handler-fx :inbox/check-fetching (fn [{:keys [db now] :as cofx} [_ last-request chat-id]] diff --git a/src/status_im/ui/screens/db.cljs b/src/status_im/ui/screens/db.cljs index 4d10120720..d8ea156bcd 100644 --- a/src/status_im/ui/screens/db.cljs +++ b/src/status_im/ui/screens/db.cljs @@ -127,6 +127,7 @@ (spec/def ::peers-count (spec/nilable integer?)) (spec/def ::peers-summary (spec/nilable vector?)) (spec/def :inbox/fetching? (spec/nilable boolean?)) +(spec/def :inbox/current-id (spec/nilable string?)) ;;;;NODE @@ -174,6 +175,7 @@ :node/after-stop :inbox/wnodes :inbox/last-received + :inbox/current-id :inbox/fetching? :browser/browsers :browser/options diff --git a/src/status_im/ui/screens/offline_messaging_settings/subs.cljs b/src/status_im/ui/screens/offline_messaging_settings/subs.cljs index f33360e48e..a10be1d26f 100644 --- a/src/status_im/ui/screens/offline_messaging_settings/subs.cljs +++ b/src/status_im/ui/screens/offline_messaging_settings/subs.cljs @@ -4,11 +4,8 @@ [status-im.utils.ethereum.core :as ethereum])) (re-frame/reg-sub :settings/current-wnode - :<- [:network] - :<- [:get-current-account] - (fn [[network current-account]] - (let [chain (ethereum/network->chain-keyword network)] - (get-in current-account [:settings :wnode chain])))) + (fn [db _] + (:inbox/current-id db))) (re-frame/reg-sub :settings/network-wnodes :<- [:network] diff --git a/test/cljs/status_im/test/models/mailserver.cljs b/test/cljs/status_im/test/models/mailserver.cljs index a0eb4c8a0c..25c60af531 100644 --- a/test/cljs/status_im/test/models/mailserver.cljs +++ b/test/cljs/status_im/test/models/mailserver.cljs @@ -114,15 +114,11 @@ (-> actual :dispatch))))))))) (deftest connected-mailserver - (testing "it returns true when set in settings" - (let [cofx {:db {:network "mainnet_rpc" - :account/account {:settings {:wnode {:mainnet "a"}} - :networks {"mainnet_rpc" - {:config {:NetworkId 1}}}} - :inbox/wnodes {:mainnet {"a" {:id "a" - :name "old-name" - :address "enode://old-id:old-password@url:port"}}}}}] - (is (model/connected? "a" cofx))))) + (testing "it returns true when set in inbox/current-id" + (let [cofx {:db {:inbox/current-id "a"}}] + (is (model/connected? "a" cofx)))) + (testing "it returns false otherwise" + (is (not (model/connected? "a" {}))))) (deftest fetch-mailserver (testing "it fetches the mailserver from the db" @@ -134,6 +130,48 @@ :address "enode://old-id:old-password@url:port"}}}}}] (is (model/fetch "a" cofx))))) +(deftest fetch-current-mailserver + (testing "it fetches the mailserver from the db with corresponding id" + (let [cofx {:db {:network "mainnet_rpc" + :account/account {:networks {"mainnet_rpc" + {:config {:NetworkId 1}}}} + :inbox/current-id "a" + :inbox/wnodes {:mainnet {"a" {:id "a" + :name "old-name" + :address "enode://old-id:old-password@url:port"}}}}}] + (is (model/fetch-current cofx))))) + +(deftest set-current-mailserver + (with-redefs [rand-nth (comp last sort)] + (let [cofx {:db {:network "mainnet_rpc" + :account/account {:networks {"mainnet_rpc" + {:config {:NetworkId 1}}}} + :inbox/current-id "a" + :inbox/wnodes {:mainnet {"a" {} + "b" {} + "c" {} + "d" {}}}}}] + (testing "the user has already a preference" + (let [cofx (assoc-in cofx + [:db :account/account :settings] + {:wnode {:mainnet "a"}})] + (testing "the mailserver exists" + (testing "it sets the preferred mailserver" + (is (= "a" (-> (model/set-current-mailserver cofx) + :db + :inbox/current-id))))) + (testing "the mailserver does not exists" + (let [cofx (update-in cofx [:db :inbox/wnodes :mainnet] dissoc "a")] + (testing "sets a random mailserver" + (is (= "d" (-> (model/set-current-mailserver cofx) + :db + :inbox/current-id)))))))) + (testing "the user has not set an explicit preference" + (testing "it sets a random mailserver" + (is (= "d" (-> (model/set-current-mailserver cofx) + :db + :inbox/current-id)))))))) + (deftest delete-mailserver (testing "the user is not connected to the mailserver" (let [cofx {:random-id "random-id" @@ -224,8 +262,6 @@ (is (= 1 (count (:data-store/tx actual))))) (testing "it logs the user out if connected to the current mailserver" (let [actual (model/upsert (assoc-in cofx - [:db :account/account :settings] - {:wnode - {:mainnet "a"}}))] + [:db :inbox/current-id] "a"))] (is (= [:logout] (-> actual :data-store/tx first :success-event)))))))) diff --git a/test/cljs/status_im/test/transport/core.cljs b/test/cljs/status_im/test/transport/core.cljs index d1a580c1dd..b50f29027d 100644 --- a/test/cljs/status_im/test/transport/core.cljs +++ b/test/cljs/status_im/test/transport/core.cljs @@ -4,7 +4,10 @@ [status-im.transport.core :as transport])) (deftest init-whisper - (let [cofx {:db {:account/account {:public-key "1"}}}] + (let [cofx {:db {:network "mainnet_rpc" + :account/account + {:networks {"mainnet_rpc" {:config {:NetworkId 1}}} + :public-key "1"}}}] (testing "it adds the discover filter" (is (= (:shh/add-discovery-filter (protocol.handlers/initialize-protocol cofx []))))) (testing "it restores the sym-keys" @@ -40,4 +43,6 @@ ms-2 ms-3])] (is (= expected-wnodes - (get-in (protocol.handlers/initialize-protocol cofx-with-ms []) [:db :inbox/wnodes]))))))) + (get-in + (protocol.handlers/initialize-protocol cofx-with-ms []) + [:db :inbox/wnodes]))))))) diff --git a/test/cljs/status_im/test/transport/inbox.cljs b/test/cljs/status_im/test/transport/inbox.cljs index a940cf363b..ffdeb761d6 100644 --- a/test/cljs/status_im/test/transport/inbox.cljs +++ b/test/cljs/status_im/test/transport/inbox.cljs @@ -9,8 +9,8 @@ :peers-summary (if registered-peer? [{:id "wnode-id"}] []) - :account/account {:networks constants/default-networks - :settings {:wnode {:mainnet "mailserver-a"}}} + :account/account {:networks constants/default-networks} + :inbox/current-id "mailserver-a" :inbox/wnodes {:mainnet {"mailserver-a" {:sym-key-id sym-key :address "enode://wnode-id@ip"}}}}}) @@ -46,6 +46,7 @@ (deftest connect-to-mailserver (let [db {:network "mainnet" + :inbox/current-id "wnodeid" :inbox/wnodes {:mainnet {"wnodeid" {:address "wnode-address" :password "wnode-password"}}} @@ -70,13 +71,13 @@ (deftest request-messages (let [db {:network "mainnet" :mailserver-status :connected + :inbox/current-id "wnodeid" :inbox/wnodes {:mainnet {"wnodeid" {:address "wnode-address" :sym-key-id "something" :password "wnode-password"}}} :account/account - {:settings {:wnode {:mainnet "wnodeid"}} - :networks {"mainnet" {:config {:NetworkId 1}}}}} + {:networks {"mainnet" {:config {:NetworkId 1}}}}} cofx {:db db :now 1000000000}] (testing "inbox is ready" (testing "last-request is set"