diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index e5598b1c1e..10c2a08f8d 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -13,7 +13,7 @@ (def text-content-type "text/plain") (def content-type-log-message "log-message") (def content-type-command "command") -(def content-type-command-request "command-request") +(def content-type-command-request "command-request") (def content-type-status "status") (def min-password-length 6) @@ -82,10 +82,15 @@ (when config/mainnet-networks-enabled? mainnet-networks)))) ;; adamb's status-cluster enode -(def default-wnode {:name "Status mailserver" - :address "enode://08d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b@163.172.177.138:40404"}) +(def default-wnode "main") -(def default-wnodes [default-wnode]) +(def default-wnodes + {"main" {:id "main" + :name "Status mailserver" + :address "enode://08d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b@163.172.177.138:40404"} + "test" {:id "test" + :name "Status mailserver (test)" + :address "enode://e2fdcf8a55d9d1ab75b492c3b9a99c206cf5ceede3db716033d0605205218c9d9a406d04b3460f4e8a64f16907ab78ba88e0e46324568bf58b3329e2c5483faa@163.172.177.138:30353"}}) ;; TODO(oskarth): Determine if this is the correct topic or not (def inbox-topic "0xaabb11ee") diff --git a/src/status_im/data_store/realm/schemas/base/core.cljs b/src/status_im/data_store/realm/schemas/base/core.cljs index 6f15ae0d76..4c0acba8cd 100644 --- a/src/status_im/data_store/realm/schemas/base/core.cljs +++ b/src/status_im/data_store/realm/schemas/base/core.cljs @@ -3,7 +3,8 @@ [status-im.data-store.realm.schemas.base.v2.core :as v2] [status-im.data-store.realm.schemas.base.v3.core :as v3] [status-im.data-store.realm.schemas.base.v4.core :as v4] - [status-im.data-store.realm.schemas.base.v5.core :as v5])) + [status-im.data-store.realm.schemas.base.v5.core :as v5] + [status-im.data-store.realm.schemas.base.v6.core :as v6])) ; put schemas ordered by version (def schemas [{:schema v1/schema @@ -20,4 +21,7 @@ :migration v4/migration} {:schema v5/schema :schemaVersion 5 - :migration v5/migration}]) \ No newline at end of file + :migration v5/migration} + {:schema v6/schema + :schemaVersion 6 + :migration v6/migration}]) diff --git a/src/status_im/data_store/realm/schemas/base/v6/account.cljs b/src/status_im/data_store/realm/schemas/base/v6/account.cljs new file mode 100644 index 0000000000..9e6ea5ef07 --- /dev/null +++ b/src/status_im/data_store/realm/schemas/base/v6/account.cljs @@ -0,0 +1,34 @@ +(ns status-im.data-store.realm.schemas.base.v6.account + (:require [taoensso.timbre :as log] + [status-im.constants :as constants])) + +(def schema {:name :account + :primaryKey :address + :properties {:address :string + :public-key :string + :updates-public-key {:type :string + :optional true} + :updates-private-key {:type :string + :optional true} + :name {:type :string :optional true} + :phone {:type :string :optional true} + :email {:type :string :optional true} + :status {:type :string :optional true} + :debug? {:type :bool :default false} + :photo-path :string + :signing-phrase {:type :string} + :last-updated {:type :int :default 0} + :signed-up? {:type :bool + :default false} + :network :string + :networks {:type :list + :objectType :network} + :wnode :string + :settings {:type :string}}}) + +(defn migration [_old-realm new-realm] + (log/debug "migrating account schema v6") + (let [accounts (.objects new-realm "account")] + (dotimes [i (.-length accounts)] + (let [account (aget accounts i)] + (aset account "wnode" constants/default-wnode))))) diff --git a/src/status_im/data_store/realm/schemas/base/v6/core.cljs b/src/status_im/data_store/realm/schemas/base/v6/core.cljs new file mode 100644 index 0000000000..af40cb79cc --- /dev/null +++ b/src/status_im/data_store/realm/schemas/base/v6/core.cljs @@ -0,0 +1,11 @@ +(ns status-im.data-store.realm.schemas.base.v6.core + (:require [status-im.data-store.realm.schemas.base.v4.network :as network] + [status-im.data-store.realm.schemas.base.v6.account :as account] + [taoensso.timbre :as log])) + +(def schema [network/schema + account/schema]) + +(defn migration [old-realm new-realm] + (log/debug "migrating v6 base database: " old-realm new-realm) + (account/migration old-realm new-realm)) diff --git a/src/status_im/protocol/handlers.cljs b/src/status_im/protocol/handlers.cljs index 51878704ae..b89e2f0eb8 100644 --- a/src/status_im/protocol/handlers.cljs +++ b/src/status_im/protocol/handlers.cljs @@ -17,7 +17,7 @@ [status-im.chat.models.message :as models.message] [status-im.protocol.web3.inbox :as inbox] [status-im.protocol.web3.keys :as web3.keys] - [status-im.utils.datetime :as datetime] + [status-im.utils.datetime :as datetime] [taoensso.timbre :as log] [status-im.native-module.core :as status] [clojure.string :as string] @@ -274,14 +274,16 @@ :initialize-offline-inbox (fn [{:keys [db]} [_ web3]] (log/info "offline inbox: initialize") - (let [wnode (get-in db [:inbox/wnode :address])] + (let [wnode-id (get db :inbox/wnode) + wnode (get-in db [:inbox/wnodes wnode-id :address])] {::add-peer {:wnode wnode :web3 web3}}))) (handlers/register-handler-fx ::add-peer-success (fn [{:keys [db]} [_ web3 response]] - (let [wnode (get-in db [:inbox/wnode :address])] + (let [wnode-id (get db :inbox/wnode) + wnode (get-in db [:inbox/wnodes wnode-id :address])] (log/info "offline inbox: add-peer response" wnode response) {::fetch-peers {:wnode wnode :web3 web3 @@ -290,7 +292,8 @@ (handlers/register-handler-fx ::fetch-peers-success (fn [{:keys [db]} [_ web3 peers retries]] - (let [wnode (get-in db [:inbox/wnode :address])] + (let [wnode-id (get db :inbox/wnode) + wnode (get-in db [:inbox/wnodes wnode-id :address])] (log/info "offline inbox: fetch-peers response" peers) (if (inbox/registered-peer? peers wnode) {::mark-trusted-peer {:wnode wnode @@ -298,14 +301,15 @@ :peers peers}} (do (log/info "Peer" wnode "is not registered. Retrying fetch peers.") - {::fetch-peers {:wnode wnode - :web3 web3 + {::fetch-peers {:wnode wnode + :web3 web3 :retries (inc retries)}}))))) (handlers/register-handler-fx ::mark-trusted-peer-success (fn [{:keys [db]} [_ web3 response]] - (let [wnode (get-in db [:inbox/wnode :address]) + (let [wnode-id (get db :inbox/wnode) + wnode (get-in db [:inbox/wnodes wnode-id :address]) password (:inbox/password db)] (log/info "offline inbox: mark-trusted-peer response" wnode response) {::get-sym-key {:password password @@ -317,8 +321,9 @@ ::get-sym-key-success (fn [{:keys [db]} [_ web3 sym-key-id]] (log/info "offline inbox: get-sym-key response" sym-key-id) - (let [wnode (get-in db [:inbox/wnode :address]) - topic (:inbox/topic db)] + (let [wnode-id (get db :inbox/wnode) + wnode (get-in db [:inbox/wnodes wnode-id :address]) + topic (:inbox/topic db)] {::request-messages {:wnode wnode :topic topic :sym-key-id sym-key-id @@ -424,7 +429,7 @@ ;;; MESSAGES -(defn- transform-protocol-message [{:keys [from to payload]}] +(defn- transform-protocol-message [{:keys [from to payload]}] (merge payload {:from from :to to :chat-id (or (:group-id payload) from)})) @@ -439,7 +444,7 @@ (or ack-of-message message-id)) (handlers/register-handler-fx - :incoming-message + :incoming-message (fn [{:keys [db]} [_ type {:keys [payload ttl id] :as message}]] (let [message-id (or id (:message-id payload))] (when-not (cache/exists? message-id type) @@ -473,7 +478,7 @@ :discoveries-response {:dispatch [:discoveries-response-received message]} :profile {:dispatch [:contact-update-received message]} :update-keys {:dispatch [:update-keys-received message]} - :online {:dispatch [:contact-online-received message]} + :online {:dispatch [:contact-online-received message]} nil)] (when (nil? route-fx) (log/debug "Unknown message type" type)) (cache/add! processed-message) @@ -487,19 +492,19 @@ (fn [{:keys [db get-stored-message]} [{:keys [from sent-from payload]} status]] (let [message-identifier (get-message-id payload) chat-identifier (or (:group-id payload) from) - message-db-path [:chats chat-identifier :messages message-identifier] - from-id (or sent-from from) + message-db-path [:chats chat-identifier :messages message-identifier] + from-id (or sent-from from) message (or (get-in db message-db-path) (and (get (:not-loaded-message-ids db) message-identifier) (get-stored-message message-identifier)))] - ;; proceed with updating status if chat is in db, status is not the same and message was not already seen + ;; proceed with updating status if chat is in db, status is not the same and message was not already seen (when (and message (get-in db [:chats chat-identifier]) (not= status (get-in message [:user-statuses from-id])) (not (models.message/message-seen-by? message from-id))) (let [statuses (assoc (:user-statuses message) from-id status)] (cond-> {:update-message {:message-id message-identifier - :user-statuses statuses}} + :user-statuses statuses}} (get-in db message-db-path) (assoc :db (assoc-in db (conj message-db-path :user-statuses) statuses)))))))) @@ -527,7 +532,7 @@ ;; Get timestamp from message root level. ;; Root level "timestamp" is a unix ts in seconds. timestamp' (or (:payload timestamp) - (* 1000 timestamp))] + (* 1000 timestamp))] (if-not existing-contact (let [contact (assoc contact :pending? true)] {:dispatch-n [[:add-contacts [contact]] diff --git a/src/status_im/translations/en.cljs b/src/status_im/translations/en.cljs index af4bdc85ae..6e43642f87 100644 --- a/src/status_im/translations/en.cljs +++ b/src/status_im/translations/en.cljs @@ -399,6 +399,7 @@ :close-app-title "Warning!" :close-app-content "The app will stop and close. When you reopen it, the selected network will be used" :close-app-button "Confirm" + :connect-wnode-content "Connect to {{name}}?" ;; browser :browser "Browser" diff --git a/src/status_im/ui/screens/accounts/db.cljs b/src/status_im/ui/screens/accounts/db.cljs index b46efd8861..c6160eb1e6 100644 --- a/src/status_im/ui/screens/accounts/db.cljs +++ b/src/status_im/ui/screens/accounts/db.cljs @@ -18,6 +18,7 @@ (spec/def :account/status (spec/nilable string?)) (spec/def :account/network (spec/nilable string?)) (spec/def :account/networks (spec/nilable :networks/networks)) +(spec/def :account/wnode (spec/nilable string?)) (spec/def :account/settings (spec/nilable (spec/map-of keyword? any?))) (spec/def :account/phone (spec/nilable string?)) (spec/def :account/signing-phrase :global/not-empty-string) @@ -28,7 +29,8 @@ :opt-un [:account/debug? :account/status :account/last-updated :account/updates-private-key :account/updates-public-key :account/email :account/signed-up? :account/network - :account/phone :account/networks :account/settings])) + :account/phone :account/networks :account/settings + :account/wnode])) (spec/def :accounts/accounts (spec/nilable (spec/map-of :account/address :accounts/account))) diff --git a/src/status_im/ui/screens/accounts/events.cljs b/src/status_im/ui/screens/accounts/events.cljs index 0628153082..2a144cdf85 100644 --- a/src/status_im/ui/screens/accounts/events.cljs +++ b/src/status_im/ui/screens/accounts/events.cljs @@ -92,11 +92,12 @@ (defn add-account "Takes db and new account, creates map of effects describing adding account to database and realm" - [{:keys [network] :networks/keys [networks] :as db} {:keys [address] :as account}] + [{:keys [network inbox/wnode] :networks/keys [networks] :as db} {:keys [address] :as account}] (let [enriched-account (assoc account - :network network + :network network :networks networks - :address address)] + :wnode wnode + :address address)] {:db (assoc-in db [:accounts/accounts address] enriched-account) ::save-account enriched-account})) diff --git a/src/status_im/ui/screens/accounts/login/events.cljs b/src/status_im/ui/screens/accounts/login/events.cljs index b4ab5598f6..de2651e3f2 100644 --- a/src/status_im/ui/screens/accounts/login/events.cljs +++ b/src/status_im/ui/screens/accounts/login/events.cljs @@ -9,7 +9,8 @@ [status-im.native-module.core :as status] [status-im.constants :refer [console-chat-id]] [status-im.utils.config :as config] - [status-im.utils.utils :as utils])) + [status-im.utils.utils :as utils] + [status-im.constants :as constants])) ;;;; FX @@ -70,6 +71,9 @@ {:network network :config config})) +(defn get-wnode-by-address [db address] + (get-in db [:accounts/accounts address :wnode] constants/default-wnode)) + (defn wrap-with-initialize-geth-fx [db address password] (let [{:keys [network config]} (get-network-by-address db address)] {:initialize-geth-fx config @@ -92,8 +96,10 @@ (fn [{{:keys [network status-node-started?] :as db} :db} [_ address password account-creation?]] (let [{account-network :network} (get-network-by-address db address) + wnode (get-wnode-by-address db address) db' (-> db (assoc :accounts/account-creation? account-creation?) + (assoc :inbox/wnode wnode) (assoc-in [:accounts/login :processing] true)) wrap-fn (cond (not status-node-started?) wrap-with-initialize-geth-fx diff --git a/src/status_im/ui/screens/db.cljs b/src/status_im/ui/screens/db.cljs index 1738471079..3ca7c64173 100644 --- a/src/status_im/ui/screens/db.cljs +++ b/src/status_im/ui/screens/db.cljs @@ -49,6 +49,7 @@ :network constants/default-network :networks/networks constants/default-networks :inbox/wnode constants/default-wnode + :inbox/wnodes constants/default-wnodes :inbox/topic constants/inbox-topic :inbox/password constants/inbox-password :my-profile/editing? false}) @@ -132,6 +133,7 @@ :node/after-start :node/after-stop :inbox/wnode + :inbox/wnodes :inbox/topic :inbox/password :browser/browsers @@ -176,7 +178,7 @@ :chat/message-data :chat/message-status :chat/selected-participants - :chat/chat-loaded-callbacks + :chat/chat-loaded-callbacks :chat/public-group-topic :chat/confirmation-code-sms-listener :chat/messages diff --git a/src/status_im/ui/screens/events.cljs b/src/status_im/ui/screens/events.cljs index 9ebb394b3a..61cc98bb67 100644 --- a/src/status_im/ui/screens/events.cljs +++ b/src/status_im/ui/screens/events.cljs @@ -24,6 +24,7 @@ status-im.ui.screens.wallet.choose-recipient.events status-im.ui.screens.browser.events status-im.ui.screens.add-new.open-dapp.events + status-im.ui.screens.offline-messaging-settings.events [re-frame.core :as re-frame] [status-im.native-module.core :as status] [status-im.ui.components.react :as react] @@ -250,8 +251,10 @@ (fn [{:keys [accounts/accounts contacts/contacts networks/networks network network-status view-id navigation-stack chats access-scope->commands-responses layout-height - status-module-initialized? status-node-started?] - :or [network (get app-db :network)] + status-module-initialized? status-node-started? + inbox/wnode] + :or [network (get app-db :network) + wnode (get app-db :inbox/wnode)] :as db} [_ address]] (let [console-contact (get contacts console-chat-id)] (cond-> (assoc app-db @@ -270,7 +273,8 @@ :accounts/creating-account? false :networks/networks networks :network-status network-status - :network network) + :network network + :inbox/wnode wnode) console-contact (assoc :contacts/contacts {console-chat-id console-contact}))))) diff --git a/src/status_im/ui/screens/offline_messaging_settings/db.cljs b/src/status_im/ui/screens/offline_messaging_settings/db.cljs index 85593858b2..5c4418465c 100644 --- a/src/status_im/ui/screens/offline_messaging_settings/db.cljs +++ b/src/status_im/ui/screens/offline_messaging_settings/db.cljs @@ -5,8 +5,13 @@ (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})") (spec/def ::not-blank-string (spec/and string? seq)) + (spec/def :wnode/address (spec/and string? #(re-matches enode-address-regex %))) (spec/def :wnode/name ::not-blank-string) +(spec/def :wnode/id ::not-blank-string) +(spec/def :wnode/wnode (allowed-keys :req-un [:wnode/address :wnode/name :wnode/id])) + (spec/def :inbox/topic ::not-blank-string) (spec/def :inbox/password ::not-blank-string) -(spec/def :inbox/wnode (allowed-keys :req-un [:wnode/address :wnode/name])) +(spec/def :inbox/wnode ::not-blank-string) +(spec/def :inbox/wnodes (spec/nilable (spec/map-of :wnode/id :wnode/wnode))) diff --git a/src/status_im/ui/screens/offline_messaging_settings/events.cljs b/src/status_im/ui/screens/offline_messaging_settings/events.cljs new file mode 100644 index 0000000000..0eb2f6a707 --- /dev/null +++ b/src/status_im/ui/screens/offline_messaging_settings/events.cljs @@ -0,0 +1,23 @@ +(ns status-im.ui.screens.offline-messaging-settings.events + (:require [re-frame.core :refer [dispatch]] + [status-im.utils.handlers :as handlers] + [status-im.ui.screens.accounts.events :as accounts-events] + [status-im.i18n :as i18n])) + +(handlers/register-handler-fx + ::save-wnode + (fn [{:keys [db now]} [_ wnode]] + (-> (accounts-events/account-update {:db db} + {:wnode wnode :last-updated now}) + (merge {:dispatch [:navigate-to-clean :accounts] + :stop-whisper nil})))) + +(handlers/register-handler-fx + :connect-wnode + (fn [{:keys [db now]} [_ wnode]] + {:show-confirmation {:title (i18n/label :t/close-app-title) + :content (i18n/label :t/connect-wnode-content + {:name (get-in db [:inbox/wnodes wnode :name])}) + :confirm-button-text (i18n/label :t/close-app-button) + :on-accept #(dispatch [::save-wnode wnode]) + :on-cancel nil}})) diff --git a/src/status_im/ui/screens/offline_messaging_settings/views.cljs b/src/status_im/ui/screens/offline_messaging_settings/views.cljs index a735dd2053..9903f403a3 100644 --- a/src/status_im/ui/screens/offline_messaging_settings/views.cljs +++ b/src/status_im/ui/screens/offline_messaging_settings/views.cljs @@ -1,5 +1,6 @@ (ns status-im.ui.screens.offline-messaging-settings.views - (:require [status-im.constants :as constants] + (:require [re-frame.core :as re-frame] + [status-im.constants :as constants] [status-im.i18n :as i18n] [status-im.ui.components.common.common :as common] [status-im.ui.components.icons.vector-icons :as vector-icons] @@ -11,23 +12,19 @@ [status-im.utils.platform :as platform] [taoensso.timbre :as log] [reagent.core :as reagent]) - (:require-macros [status-im.utils.views :as views])) - -(defn- add-wnode [] - ;; TODO:(dmitryn) to be added in #2751 - (log/info "add wnode not implemented")) + (:require-macros [status-im.utils.views :refer [defview letsubs]])) (defn- wnode-icon [connected?] [react/view (styles/wnode-icon connected?) [vector-icons/icon :icons/wnode {:color (if connected? :white :gray)}]]) (defn- render-row [current-wnode] - (fn [{:keys [address name] :as row} _ _] - (let [connected? (= address (:address current-wnode))] + (fn [{:keys [address name id] :as row} _ _] + (let [connected? (= id current-wnode)] [react/list-item ^{:key row} [react/touchable-highlight - {:on-press add-wnode} + {:on-press #(re-frame/dispatch [:connect-wnode id])} [react/view styles/wnode-item [wnode-icon connected?] [react/view styles/wnode-item-inner @@ -53,10 +50,9 @@ [common/list-footer] [common/bottom-shadow]]]) -(views/defview offline-messaging-settings [] - ;; TODO:(dmitryn) store wnodes in user account, but now use defaults for MVP - (let [current-wnode constants/default-wnode - wnodes constants/default-wnodes] +(defview offline-messaging-settings [] + (letsubs [current-wnode [:get :inbox/wnode] + wnodes [:get :inbox/wnodes]] [react/view {:flex 1} [status-bar/status-bar] [toolbar/simple-toolbar (i18n/label :t/offline-messaging-settings)] @@ -66,7 +62,7 @@ ;; TODO(dmitryn) migrate to :header/:footer properties of flat-list ;; after merge of https://github.com/status-im/status-react/pull/2297/ [render-header wnodes] - [list/flat-list {:data wnodes + [list/flat-list {:data (vals wnodes) :separator? false :render-fn (render-row current-wnode) :ListFooterComponent (reagent/as-element (render-footer)) diff --git a/test/cljs/status_im/test/accounts/events.cljs b/test/cljs/status_im/test/accounts/events.cljs index 08d5266bdb..82c217e7de 100644 --- a/test/cljs/status_im/test/accounts/events.cljs +++ b/test/cljs/status_im/test/accounts/events.cljs @@ -26,6 +26,7 @@ :status "be the hero of your own journey" :network constants/default-network :networks constants/default-networks + :wnode constants/default-wnode :public-key "0x049b3a8c04f2c5bccda91c1f5e6434ae72957e93a31c0301b4563eda1d6ce419f63c503ebaee143115f96c1f04f232a7a22ca0454e9ee3d579ad1f870315b151d0"}) (def new-account @@ -38,6 +39,7 @@ :status "the future starts today, not tomorrow" :network constants/default-network :networks constants/default-networks + :wnode constants/default-wnode :signing-phrase "long loan limo" :public-key "0x04f5722fba79eb36d73263417531007f43d13af76c6233573a8e3e60f667710611feba0785d751b50609bfc0b7cef35448875c5392c0a91948c95798a0ce600847"})