refactor - extracted all model functions from accounts events

Signed-off-by: Goran Jovic <goranjovic@gmail.com>
This commit is contained in:
Goran Jovic 2018-08-05 09:55:44 +02:00
parent 7144339b16
commit c216a378e4
No known key found for this signature in database
GPG Key ID: D429D1A9B2EB8A8E
12 changed files with 434 additions and 364 deletions

View File

@ -1,124 +1,55 @@
(ns status-im.ui.screens.accounts.events
(:require [re-frame.core :as re-frame]
[taoensso.timbre :as log]
[status-im.native-module.core :as status]
[status-im.utils.types :refer [json->clj]]
[status-im.utils.identicon :refer [identicon]]
[clojure.string :as str]
[status-im.i18n :as i18n]
[status-im.utils.config :as config]
[status-im.utils.utils :as utils]
[status-im.utils.datetime :as time]
[status-im.utils.handlers :as handlers]
[status-im.utils.handlers-macro :as handlers-macro]
[status-im.ui.screens.accounts.statuses :as statuses]
[status-im.utils.signing-phrase.core :as signing-phrase]
[status-im.utils.gfycat.core :refer [generate-gfy]]
[status-im.utils.hex :as utils.hex]
[status-im.constants :as constants]
status-im.ui.screens.accounts.create.navigation
[status-im.ui.screens.accounts.utils :as accounts.utils]
[status-im.data-store.accounts :as accounts-store]
[status-im.ui.screens.navigation :as navigation]
[status-im.ui.screens.wallet.settings.models :as wallet.settings.models]))
[status-im.ui.screens.accounts.models :as models]))
;;;; COFX
(re-frame/reg-cofx
::get-signing-phrase
(fn [coeffects _]
(assoc coeffects :signing-phrase (signing-phrase/generate))))
(fn [cofx _]
(models/get-signing-phrase cofx)))
(re-frame/reg-cofx
::get-status
(fn [coeffects _]
(assoc coeffects :status (rand-nth statuses/data))))
(fn [cofx _]
(models/get-status cofx)))
;;;; FX
(re-frame/reg-fx
::create-account
(fn [password]
(status/create-account
password
#(re-frame/dispatch [::account-created (json->clj %) password]))))
:create-account
models/create-account!)
;;;; Handlers
(handlers/register-handler-fx
:create-account
(fn [{{:accounts/keys [create] :as db} :db} _]
{:db (update db :accounts/create assoc :step :account-creating :error nil)
::create-account (:password create)}))
(defn add-account
"Takes db and new account, creates map of effects describing adding account to database and realm"
[{:networks/keys [networks] :as db} {:keys [address] :as account}]
(let [enriched-account (assoc account
:network config/default-network
:networks networks
:address address)]
{:db (assoc-in db [:accounts/accounts address] enriched-account)
:data-store/base-tx [(accounts-store/save-account-tx enriched-account)]}))
(fn [cofx _]
(models/create-account cofx)))
(handlers/register-handler-fx
::account-created
:account-created
[re-frame/trim-v (re-frame/inject-cofx ::get-signing-phrase) (re-frame/inject-cofx ::get-status)]
(fn [{:keys [signing-phrase status db] :as cofx} [{:keys [pubkey address mnemonic]} password]]
(let [normalized-address (utils.hex/normalize-hex address)
account {:public-key pubkey
:address normalized-address
:name (generate-gfy pubkey)
:status status
:signed-up? true
:photo-path (identicon pubkey)
:signing-phrase signing-phrase
:mnemonic mnemonic
:settings (constants/default-account-settings)}]
(log/debug "account-created")
(when-not (str/blank? pubkey)
(-> (add-account db account)
(assoc :dispatch [:login-account normalized-address password]))))))
(defn load-accounts [{:keys [db all-accounts]}]
(let [accounts (->> all-accounts
(map (fn [{:keys [address] :as account}]
[address account]))
(into {}))]
{:db (assoc db :accounts/accounts accounts)}))
(defn update-settings
([settings cofx] (update-settings settings nil cofx))
([settings success-event {{:keys [account/account] :as db} :db :as cofx}]
(let [new-account (assoc account :settings settings)]
{:db (assoc db :account/account new-account)
:data-store/base-tx [{:transaction (accounts-store/save-account-tx new-account)
:success-event success-event}]})))
(fn [cofx [result password]]
(models/on-account-created result password cofx)))
(handlers/register-handler-fx
:send-account-update-if-needed
(fn [{:keys [db now] :as cofx} _]
(let [{:keys [last-updated]} (:account/account db)
needs-update? (> (- now last-updated) time/week)]
(log/info "Need to send account-update: " needs-update?)
(when needs-update?
;; TODO(janherich): this is very strange and misleading, need to figure out why it'd necessary to update
;; account with network update when last update was more then week ago
(accounts.utils/account-update nil cofx)))))
(fn [cofx _]
(models/send-account-update-if-needed cofx)))
(handlers/register-handler-fx
:account-set-name
(fn [{{:accounts/keys [create] :as db} :db :as cofx} _]
(handlers-macro/merge-fx cofx
{:db (assoc db :accounts/create {:show-welcome? true})
:dispatch-n [[:navigate-to-clean :home]
[:request-notifications]]}
(accounts.utils/account-update {:name (:name create)}))))
(fn [cofx _]
(models/account-set-name cofx)))
(handlers/register-handler-fx
:account-set-input-text
(fn [{db :db} [_ input-key text]]
{:db (update db :accounts/create merge {input-key text :error nil})}))
(fn [cofx [_ input-key text]]
(models/account-set-input-text input-key text cofx)))
(handlers/register-handler-fx
:update-sign-in-time
@ -132,44 +63,20 @@
(handlers/register-handler-fx
:show-mainnet-is-default-alert
(fn [{:keys [db]}]
(let [enter-name-screen? (= :enter-name (get-in db [:accounts/create :step]))
shown? (get-in db [:account/account :mainnet-warning-shown?])]
(when (and config/mainnet-warning-enabled?
(not shown?)
(not enter-name-screen?))
(utils/show-popup
(i18n/label :mainnet-is-default-alert-title)
(i18n/label :mainnet-is-default-alert-text)
#(re-frame/dispatch [:update-mainnet-warning-shown]))))))
(fn [cofx]
(models/show-mainnet-is-default-alert cofx)))
(handlers/register-handler-fx
:reset-account-creation
(fn [{db :db} _]
{:db (update db :accounts/create assoc :step :enter-password :password nil :password-confirm nil :error nil)}))
(fn [cofx _]
(models/reset-account-creation cofx)))
(handlers/register-handler-fx
:switch-dev-mode
(fn [cofx [_ dev-mode]]
(accounts.utils/account-update {:dev-mode? dev-mode} cofx)))
(defn chat-send? [transaction]
(and (seq transaction)
(not (:in-progress? transaction))
(:from-chat? transaction)))
(defn wallet-set-up-passed [db modal? cofx]
(let [transaction (get-in db [:wallet :send-transaction])]
(cond modal? {:dispatch [:navigate-to-modal :wallet-send-transaction-modal]}
(chat-send? transaction) {:db (navigation/navigate-back db)
:dispatch [:navigate-to :wallet-send-transaction-chat]}
:else {:db (navigation/navigate-back db)})))
(handlers/register-handler-fx
:wallet-set-up-passed
(fn [{:keys [db] :as cofx} [_ modal?]]
(handlers-macro/merge-fx
cofx
(wallet-set-up-passed db modal?)
(wallet.settings.models/wallet-autoconfig-tokens)
(accounts.utils/account-update {:wallet-set-up-passed? true}))))
(fn [cofx [_ modal?]]
(models/wallet-set-up-passed modal? cofx)))

View File

@ -1,160 +1,55 @@
(ns status-im.ui.screens.accounts.login.events
(:require status-im.ui.screens.accounts.login.navigation
[re-frame.core :as re-frame]
[status-im.utils.handlers :refer [register-handler-db register-handler-fx]]
[taoensso.timbre :as log]
[status-im.utils.types :refer [json->clj]]
[status-im.data-store.core :as data-store]
[status-im.native-module.core :as status]
[status-im.utils.config :as config]
[status-im.utils.keychain.core :as keychain]
[status-im.utils.utils :as utils]
[status-im.utils.universal-links.core :as universal-links]))
[status-im.utils.handlers :as handlers]
[status-im.ui.screens.accounts.login.models :as models]))
;;;; FX
(re-frame/reg-fx ::stop-node (fn [] (status/stop-node)))
(re-frame/reg-fx :stop-node models/stop-node!)
(re-frame/reg-fx
::login
:login
(fn [[address password]]
(status/login address password #(re-frame/dispatch [:login-handler % address]))))
(models/login! address password)))
(re-frame/reg-fx
::clear-web-data
(fn []
(status/clear-web-data)))
(defn change-account! [address encryption-key]
(data-store/change-account address encryption-key)
(re-frame/dispatch [:change-account-handler address]))
(defn handle-change-account [address]
;; No matter what is the keychain we use, as checks are done on decrypting base
(.. (keychain/safe-get-encryption-key)
(then (partial change-account! address))
(catch (fn [error]
;; If all else fails we fallback to showing initial error
(re-frame/dispatch [:initialize-app "" :decryption-failed])))))
:clear-web-data
models/clear-web-data!)
(re-frame/reg-fx
::change-account
:change-account
(fn [[address]]
(handle-change-account address)))
(models/handle-change-account! address)))
;;;; Handlers
(register-handler-fx
(handlers/register-handler-fx
:open-login
(fn [{db :db} [_ address photo-path name]]
{:db (update db
:accounts/login assoc
:address address
:photo-path photo-path
:name name)
:dispatch [:navigate-to :login]}))
(fn [cofx [_ address photo-path name]]
(models/open-login address photo-path name cofx)))
(defn wrap-with-login-account-fx [db address password]
{:db db
::login [address password]})
(handlers/register-handler-fx
:login-account-internal
(fn [cofx [_ address password]]
(models/login-account-internal address password cofx)))
(register-handler-fx
::login-account
(fn [{db :db} [_ address password]]
(wrap-with-login-account-fx
(assoc db :node/after-start nil)
address password)))
(handlers/register-handler-fx
:start-node
(fn [cofx [_ address password]]
(models/start-node address password cofx)))
(defn add-custom-bootnodes [config network all-bootnodes]
(let [bootnodes (as-> all-bootnodes $
(get $ network)
(vals $)
(map :address $))]
(if (seq bootnodes)
(assoc config :ClusterConfig {:Enabled true
:BootNodes bootnodes})
config)))
(defn get-network-by-address [db address]
(let [accounts (get db :accounts/accounts)
{:keys [network
settings
bootnodes
networks]} (get accounts address)
use-custom-bootnodes (get-in settings [:bootnodes network])
config (cond-> (get-in networks [network :config])
(and
config/bootnodes-settings-enabled?
use-custom-bootnodes)
(add-custom-bootnodes network bootnodes))]
{:use-custom-bootnodes use-custom-bootnodes
:network network
:config config}))
(defn wrap-with-initialize-geth-fx [db address password]
(let [{:keys [network config]} (get-network-by-address db address)]
{:initialize-geth-fx config
:db (assoc db :network network
:node/after-start [::login-account address password])}))
(register-handler-fx
::start-node
(fn [{db :db} [_ address password]]
(wrap-with-initialize-geth-fx
(assoc db :node/after-stop nil)
address password)))
(defn wrap-with-stop-node-fx [db address password]
{:db (assoc db :node/after-stop [::start-node address password])
::stop-node nil})
(defn- restart-node? [account-network network use-custom-bootnodes]
(or (not= account-network network)
(and config/bootnodes-settings-enabled?
use-custom-bootnodes)))
(defn login-account [{{:keys [network status-node-started?] :as db} :db} [_ address password]]
(let [{use-custom-bootnodes :use-custom-bootnodes
account-network :network} (get-network-by-address db address)
db' (-> db
(assoc-in [:accounts/login :processing] true))
wrap-fn (cond (not status-node-started?)
wrap-with-initialize-geth-fx
(not (restart-node? account-network
network
use-custom-bootnodes))
wrap-with-login-account-fx
:else
wrap-with-stop-node-fx)]
(wrap-fn db' address password)))
(register-handler-fx
(handlers/register-handler-fx
:login-account
login-account)
(fn [cofx [_ address password]]
(models/login-account address password cofx)))
(register-handler-fx
(handlers/register-handler-fx
:login-handler
(fn [{db :db} [_ login-result address]]
(let [data (json->clj login-result)
error (:error data)
success (zero? (count error))
db' (assoc-in db [:accounts/login :processing] false)]
(if success
{:db db
::clear-web-data nil
::change-account [address]}
{:db (assoc-in db' [:accounts/login :error] error)}))))
(fn [cofx [_ login-result address]]
(models/login-handler login-result address cofx)))
(register-handler-fx
(handlers/register-handler-fx
:change-account-handler
(fn [{{:keys [view-id] :as db} :db :as cofx} [_ address]]
{:db (cond-> (dissoc db :accounts/login)
(= view-id :create-account)
(assoc-in [:accounts/create :step] :enter-name))
:dispatch [:initialize-account address
(when (not= view-id :create-account)
[[:navigate-to-clean :home]
(universal-links/stored-url-event cofx)])]}))
(fn [cofx [_ address]]
(models/change-account-handler address cofx)))

View File

@ -0,0 +1,134 @@
(ns status-im.ui.screens.accounts.login.models
(:require status-im.ui.screens.accounts.login.navigation
[re-frame.core :as re-frame]
[status-im.utils.types :as types]
[status-im.data-store.core :as data-store]
[status-im.native-module.core :as status]
[status-im.utils.config :as config]
[status-im.utils.keychain.core :as keychain]
[status-im.utils.universal-links.core :as universal-links]))
;;;; FX
(defn stop-node! [] (status/stop-node))
(defn login! [address password]
(status/login address password #(re-frame/dispatch [:login-handler % address])))
(defn clear-web-data! []
(status/clear-web-data))
(defn- change-account! [address encryption-key]
(data-store/change-account address encryption-key)
(re-frame/dispatch [:change-account-handler address]))
(defn handle-change-account! [address]
;; No matter what is the keychain we use, as checks are done on decrypting base
(.. (keychain/safe-get-encryption-key)
(then (partial change-account! address))
(catch (fn [error]
;; If all else fails we fallback to showing initial error
(re-frame/dispatch [:initialize-app "" :decryption-failed])))))
;;;; Handlers
(defn open-login [address photo-path name {db :db}]
{:db (update db
:accounts/login assoc
:address address
:photo-path photo-path
:name name)
:dispatch [:navigate-to :login]})
(defn wrap-with-login-account-fx [db address password]
{:db db
:login [address password]})
(defn login-account-internal [address password {db :db}]
(wrap-with-login-account-fx
(assoc db :node/after-start nil)
address password))
(defn- add-custom-bootnodes [config network all-bootnodes]
(let [bootnodes (as-> all-bootnodes $
(get $ network)
(vals $)
(map :address $))]
(if (seq bootnodes)
(assoc config :ClusterConfig {:Enabled true
:BootNodes bootnodes})
config)))
(defn- get-network-by-address [db address]
(let [accounts (get db :accounts/accounts)
{:keys [network
settings
bootnodes
networks]} (get accounts address)
use-custom-bootnodes (get-in settings [:bootnodes network])
config (cond-> (get-in networks [network :config])
(and
config/bootnodes-settings-enabled?
use-custom-bootnodes)
(add-custom-bootnodes network bootnodes))]
{:use-custom-bootnodes use-custom-bootnodes
:network network
:config config}))
(defn- wrap-with-initialize-geth-fx [db address password]
(let [{:keys [network config]} (get-network-by-address db address)]
{:initialize-geth-fx config
:db (assoc db
:network network
:node/after-start [:login-account-internal address password])}))
(defn start-node [address password {db :db}]
(wrap-with-initialize-geth-fx
(assoc db :node/after-stop nil)
address password))
(defn- wrap-with-stop-node-fx [db address password]
{:db (assoc db :node/after-stop [:start-node address password])
:stop-node nil})
(defn- restart-node? [account-network network use-custom-bootnodes]
(or (not= account-network network)
(and config/bootnodes-settings-enabled?
use-custom-bootnodes)))
(defn login-account [address password {{:keys [network status-node-started?] :as db} :db}]
(let [{use-custom-bootnodes :use-custom-bootnodes
account-network :network} (get-network-by-address db address)
db' (-> db
(assoc-in [:accounts/login :processing] true))
wrap-fn (cond (not status-node-started?)
wrap-with-initialize-geth-fx
(not (restart-node? account-network
network
use-custom-bootnodes))
wrap-with-login-account-fx
:else
wrap-with-stop-node-fx)]
(wrap-fn db' address password)))
(defn login-handler [login-result address {db :db}]
(let [data (types/json->clj login-result)
error (:error data)
success (zero? (count error))
db' (assoc-in db [:accounts/login :processing] false)]
(if success
{:db db
:clear-web-data nil
:change-account [address]}
{:db (assoc-in db' [:accounts/login :error] error)})))
(defn change-account-handler [address {{:keys [view-id] :as db} :db :as cofx}]
{:db (cond-> (dissoc db :accounts/login)
(= view-id :create-account)
(assoc-in [:accounts/create :step] :enter-name))
:dispatch [:initialize-account address
(when (not= view-id :create-account)
[[:navigate-to-clean :home]
(universal-links/stored-url-event cofx)])]})

View File

@ -0,0 +1,136 @@
(ns status-im.ui.screens.accounts.models
(:require [re-frame.core :as re-frame]
[taoensso.timbre :as log]
[status-im.native-module.core :as status]
[status-im.utils.types :as types]
[status-im.utils.identicon :as identicon]
[clojure.string :as str]
[status-im.i18n :as i18n]
[status-im.utils.config :as config]
[status-im.utils.utils :as utils]
[status-im.utils.datetime :as time]
[status-im.utils.handlers-macro :as handlers-macro]
[status-im.ui.screens.accounts.statuses :as statuses]
[status-im.utils.signing-phrase.core :as signing-phrase]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.hex :as utils.hex]
[status-im.constants :as constants]
status-im.ui.screens.accounts.create.navigation
[status-im.ui.screens.accounts.utils :as accounts.utils]
[status-im.data-store.accounts :as accounts-store]
[status-im.ui.screens.navigation :as navigation]
[status-im.ui.screens.wallet.settings.models :as wallet.settings.models]))
;;;; COFX
(defn get-signing-phrase [cofx]
(assoc cofx :signing-phrase (signing-phrase/generate)))
(defn get-status [cofx]
(assoc cofx :status (rand-nth statuses/data)))
;;;; FX
(defn create-account! [password]
(status/create-account
password
#(re-frame/dispatch [:account-created (types/json->clj %) password])))
;;;; Handlers
(defn create-account [{{:accounts/keys [create] :as db} :db}]
{:db (update db :accounts/create assoc :step :account-creating :error nil)
:create-account (:password create)})
(defn- add-account
"Takes db and new account, creates map of effects describing adding account to database and realm"
[{:networks/keys [networks] :as db} {:keys [address] :as account}]
(let [enriched-account (assoc account
:network config/default-network
:networks networks
:address address)]
{:db (assoc-in db [:accounts/accounts address] enriched-account)
:data-store/base-tx [(accounts-store/save-account-tx enriched-account)]}))
(defn on-account-created [{:keys [pubkey address mnemonic]} password {:keys [signing-phrase status db]}]
(let [normalized-address (utils.hex/normalize-hex address)
account {:public-key pubkey
:address normalized-address
:name (gfycat/generate-gfy pubkey)
:status status
:signed-up? true
:photo-path (identicon/identicon pubkey)
:signing-phrase signing-phrase
:mnemonic mnemonic
:settings (constants/default-account-settings)}]
(log/debug "account-created")
(when-not (str/blank? pubkey)
(-> (add-account db account)
(assoc :dispatch [:login-account normalized-address password])))))
(defn load-accounts [{:keys [db all-accounts]}]
(let [accounts (->> all-accounts
(map (fn [{:keys [address] :as account}]
[address account]))
(into {}))]
{:db (assoc db :accounts/accounts accounts)}))
(defn update-settings
([settings cofx] (update-settings settings nil cofx))
([settings success-event {{:keys [account/account] :as db} :db :as cofx}]
(let [new-account (assoc account :settings settings)]
{:db (assoc db :account/account new-account)
:data-store/base-tx [{:transaction (accounts-store/save-account-tx new-account)
:success-event success-event}]})))
(defn send-account-update-if-needed [{:keys [db now] :as cofx}]
(let [{:keys [last-updated]} (:account/account db)
needs-update? (> (- now last-updated) time/week)]
(log/info "Need to send account-update: " needs-update?)
(when needs-update?
;; TODO(janherich): this is very strange and misleading, need to figure out why it'd necessary to update
;; account with network update when last update was more then week ago
(accounts.utils/account-update nil cofx))))
(defn account-set-name [{{:accounts/keys [create] :as db} :db :as cofx}]
(handlers-macro/merge-fx cofx
{:db (assoc db :accounts/create {:show-welcome? true})
:dispatch-n [[:navigate-to-clean :home]
[:request-notifications]]}
(accounts.utils/account-update {:name (:name create)})))
(defn account-set-input-text [input-key text {db :db}]
{:db (update db :accounts/create merge {input-key text :error nil})})
(defn show-mainnet-is-default-alert [{:keys [db]}]
(let [enter-name-screen? (= :enter-name (get-in db [:accounts/create :step]))
shown? (get-in db [:account/account :mainnet-warning-shown?])]
(when (and config/mainnet-warning-enabled?
(not shown?)
(not enter-name-screen?))
(utils/show-popup
(i18n/label :mainnet-is-default-alert-title)
(i18n/label :mainnet-is-default-alert-text)
#(re-frame/dispatch [:update-mainnet-warning-shown])))))
(defn reset-account-creation [{db :db}]
{:db (update db :accounts/create assoc :step :enter-password :password nil :password-confirm nil :error nil)})
(defn- chat-send? [transaction]
(and (seq transaction)
(not (:in-progress? transaction))
(:from-chat? transaction)))
(defn continue-after-wallet-onboarding [db modal? cofx]
(let [transaction (get-in db [:wallet :send-transaction])]
(cond modal? {:dispatch [:navigate-to-modal :wallet-send-transaction-modal]}
(chat-send? transaction) {:db (navigation/navigate-back db)
:dispatch [:navigate-to :wallet-send-transaction-chat]}
:else {:db (navigation/navigate-back db)})))
(defn wallet-set-up-passed [modal? {:keys [db] :as cofx}]
(handlers-macro/merge-fx
cofx
(continue-after-wallet-onboarding db modal?)
(wallet.settings.models/wallet-autoconfig-tokens)
(accounts.utils/account-update {:wallet-set-up-passed? true})))

View File

@ -1,70 +1,29 @@
(ns status-im.ui.screens.accounts.recover.events
(:require
status-im.ui.screens.accounts.recover.navigation
[clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.native-module.core :as status]
[status-im.ui.screens.accounts.events :as accounts-events]
[status-im.utils.types :as types]
[status-im.utils.identicon :as identicon]
[status-im.utils.handlers :as handlers]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.security :as security]
[status-im.utils.signing-phrase.core :as signing-phrase]
[status-im.utils.hex :as utils.hex]
[status-im.constants :as constants]))
(:require status-im.ui.screens.accounts.recover.navigation
[re-frame.core :as re-frame]
[status-im.ui.screens.accounts.recover.models :as models]
[status-im.utils.handlers :as handlers]))
;;;; FX
(re-frame/reg-fx
::recover-account-fx
:recover-account-fx
(fn [[masked-passphrase password]]
(status/recover-account
(security/unmask masked-passphrase)
password
(fn [result]
;; here we deserialize result, dissoc mnemonic and serialize the result again
;; because we want to have information about the result printed in logs, but
;; don't want secure data to be printed
(let [data (-> (types/json->clj result)
(dissoc :mnemonic)
(types/clj->json))]
(re-frame/dispatch [:account-recovered data password]))))))
(models/recover-account-fx! masked-passphrase password)))
;;;; Handlers
(handlers/register-handler-fx
:account-recovered
(fn [{:keys [db]} [_ result password]]
(let [data (types/json->clj result)
public-key (:pubkey data)
address (-> data :address utils.hex/normalize-hex)
phrase (signing-phrase/generate)
account {:public-key public-key
:address address
:name (gfycat/generate-gfy public-key)
:photo-path (identicon/identicon public-key)
:mnemonic ""
:signed-up? true
:signing-phrase phrase
:settings (constants/default-account-settings)
:wallet-set-up-passed? false
:seed-backed-up? true}]
(when-not (string/blank? public-key)
(-> db
(accounts-events/add-account account)
(assoc :dispatch [:login-account address password])
(assoc :dispatch-later [{:ms 2000 :dispatch [:account-recovered-navigate]}]))))))
(fn [cofx [_ result password]]
(models/on-account-recovered result password cofx)))
(handlers/register-handler-fx
:account-recovered-navigate
(fn [{:keys [db]}]
{:db (assoc-in db [:accounts/recover :processing] false)
:dispatch-n [[:navigate-to-clean :home]
[:request-notifications]]}))
(fn [cofx]
(models/account-recovered-navigate cofx)))
(handlers/register-handler-fx
:recover-account
(fn [{:keys [db]} [_ masked-passphrase password]]
{:db (assoc-in db [:accounts/recover :processing] true)
::recover-account-fx [masked-passphrase password]}))
(fn [cofx [_ masked-passphrase password]]
(models/recover-account masked-passphrase password cofx)))

View File

@ -0,0 +1,60 @@
(ns status-im.ui.screens.accounts.recover.models
(:require status-im.ui.screens.accounts.recover.navigation
[clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.native-module.core :as status]
[status-im.ui.screens.accounts.models :as accounts.models]
[status-im.utils.types :as types]
[status-im.utils.identicon :as identicon]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.security :as security]
[status-im.utils.signing-phrase.core :as signing-phrase]
[status-im.utils.hex :as utils.hex]
[status-im.constants :as constants]))
;;;; FX
(defn recover-account-fx! [masked-passphrase password]
(status/recover-account
(security/unmask masked-passphrase)
password
(fn [result]
;; here we deserialize result, dissoc mnemonic and serialize the result again
;; because we want to have information about the result printed in logs, but
;; don't want secure data to be printed
(let [data (-> (types/json->clj result)
(dissoc :mnemonic)
(types/clj->json))]
(re-frame/dispatch [:account-recovered data password])))))
;;;; Handlers
(defn on-account-recovered [result password {:keys [db]}]
(let [data (types/json->clj result)
public-key (:pubkey data)
address (-> data :address utils.hex/normalize-hex)
phrase (signing-phrase/generate)
account {:public-key public-key
:address address
:name (gfycat/generate-gfy public-key)
:photo-path (identicon/identicon public-key)
:mnemonic ""
:signed-up? true
:signing-phrase phrase
:settings (constants/default-account-settings)
:wallet-set-up-passed? false
:seed-backed-up? true}]
(when-not (string/blank? public-key)
(-> db
(accounts.models/add-account account)
(assoc :dispatch [:login-account address password])
(assoc :dispatch-later [{:ms 2000 :dispatch [:account-recovered-navigate]}])))))
(defn account-recovered-navigate [{:keys [db]}]
{:db (assoc-in db [:accounts/recover :processing] false)
:dispatch-n [[:navigate-to-clean :home]
[:request-notifications]]})
(defn recover-account [masked-passphrase password {:keys [db]}]
{:db (assoc-in db [:accounts/recover :processing] true)
:recover-account-fx [masked-passphrase password]})

View File

@ -1,18 +1,14 @@
(ns status-im.ui.screens.bootnodes-settings.events
(:require [re-frame.core :as re-frame]
[status-im.utils.handlers :as handlers]
(:require [status-im.utils.handlers :as handlers]
[status-im.utils.handlers-macro :as handlers-macro]
[status-im.ui.screens.accounts.events :as accounts-events]
[status-im.i18n :as i18n]
[status-im.transport.core :as transport]
status-im.ui.screens.bootnodes-settings.edit-bootnode.events
[status-im.utils.ethereum.core :as ethereum]))
[status-im.ui.screens.accounts.models :as accounts.models]
status-im.ui.screens.bootnodes-settings.edit-bootnode.events))
(defn toggle-custom-bootnodes [value {:keys [db] :as cofx}]
(let [network (get-in db [:account/account :network])
settings (get-in db [:account/account :settings])]
(handlers-macro/merge-fx cofx
(accounts-events/update-settings
(accounts.models/update-settings
(assoc-in settings [:bootnodes network] value)
[:logout]))))

View File

@ -1,5 +1,5 @@
(ns status-im.ui.screens.currency-settings.events
(:require [status-im.ui.screens.accounts.events :as accounts]
(:require [status-im.ui.screens.accounts.models :as accounts.models]
[status-im.utils.handlers :as handlers]
[status-im.utils.handlers-macro :as handlers-macro]
[status-im.ui.screens.wallet.events :as wallet.events]))
@ -10,5 +10,5 @@
(let [settings (get-in db [:account/account :settings])
new-settings (assoc-in settings [:wallet :currency] currency)]
(handlers-macro/merge-fx cofx
(accounts/update-settings new-settings)
(accounts.models/update-settings new-settings)
(wallet.events/update-wallet)))))

View File

@ -3,7 +3,7 @@
status-im.network.events
[status-im.transport.handlers :as transport.handlers]
status-im.protocol.handlers
[status-im.ui.screens.accounts.events :as accounts.events]
[status-im.ui.screens.accounts.models :as accounts.models]
status-im.ui.screens.accounts.login.events
status-im.ui.screens.accounts.recover.events
[status-im.ui.screens.contacts.events :as contacts]
@ -276,7 +276,7 @@
{:dispatch-n
[[:listen-to-network-status]
[:initialize-geth]]}
(accounts.events/load-accounts)
(accounts.models/load-accounts)
(initialize-views))))
(handlers/register-handler-fx

View File

@ -2,9 +2,8 @@
(:require [re-frame.core :as re-frame]
[status-im.utils.handlers :as handlers]
[status-im.utils.handlers-macro :as handlers-macro]
[status-im.ui.screens.accounts.events :as accounts-events]
[status-im.ui.screens.accounts.models :as accounts.models]
[status-im.i18n :as i18n]
[status-im.transport.core :as transport]
status-im.ui.screens.offline-messaging-settings.edit-mailserver.events
[status-im.utils.ethereum.core :as ethereum]))
@ -13,7 +12,7 @@
(fn [{:keys [db now] :as cofx} [_ chain wnode]]
(let [settings (get-in db [:account/account :settings])]
(handlers-macro/merge-fx cofx
(accounts-events/update-settings
(accounts.models/update-settings
(assoc-in settings [:wnode chain] wnode)
[:logout])))))

View File

@ -1,14 +1,14 @@
(ns status-im.ui.screens.wallet.settings.events
(:require [status-im.ui.screens.wallet.settings.models :as models]
[status-im.ui.screens.accounts.events :as accounts]
[status-im.ui.screens.accounts.models :as accounts.models]
[status-im.utils.handlers :as handlers]))
(handlers/register-handler-fx
:wallet.settings/toggle-visible-token
(fn [cofx [_ symbol checked?]]
(models/toggle-visible-token symbol checked? accounts/update-settings cofx)))
(models/toggle-visible-token symbol checked? accounts.models/update-settings cofx)))
(handlers/register-handler-fx
:configure-token-balance-and-visibility
(fn [cofx [_ symbol balance]]
(models/configure-token-balance-and-visibility symbol balance accounts/update-settings cofx)))
(models/configure-token-balance-and-visibility symbol balance accounts.models/update-settings cofx)))

View File

@ -1,7 +1,7 @@
(ns status-im.test.ui.screens.accounts.login.events
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.utils.config :as config]
[status-im.ui.screens.accounts.login.events :as events]))
[status-im.ui.screens.accounts.login.models :as models]))
(deftest login-account
(let [mainnet-account {:network "mainnet_rpc"
@ -14,43 +14,37 @@
:accounts/accounts accounts}}]
(testing "status-go has not started"
(let [actual (events/login-account initial-db [nil "testnet" "password"])]
(let [actual (models/login-account "testnet" "password" initial-db)]
(testing "it starts status-node if it has not started"
(is (= {:NetworkId 3}
(:initialize-geth-fx
actual))))
(testing "it logins the user after the node started"
(is (= [::events/login-account "testnet" "password"] (get-in actual [:db :node/after-start]))))))
(is (= [:login-account-internal "testnet" "password"] (get-in actual [:db :node/after-start]))))))
(testing "status-go has started & the user is on mainnet"
(let [db (assoc-in initial-db [:db :status-node-started?] true)
actual (events/login-account
db
[nil "mainnet" "password"])]
actual (models/login-account "mainnet" "password" db)]
(testing "it does not start status-node if it has already started"
(is (not (:initialize-geth-fx actual))))
(testing "it logs in the user"
(is (= ["mainnet" "password"] (::events/login actual))))))
(is (= ["mainnet" "password"] (:login actual))))))
(testing "the user has selected a different network"
(testing "status-go has started"
(let [db (assoc-in initial-db [:db :status-node-started?] true)
actual (events/login-account
db
[nil "testnet" "password"])]
actual (models/login-account "testnet" "password" db)]
(testing "it dispatches start-node"
(is (get-in actual [:db :node/after-stop] [::events/start-node "testnet" "password"])))
(is (get-in actual [:db :node/after-stop] [:start-node "testnet" "password"])))
(testing "it stops status-node"
(is (contains? actual ::events/stop-node)))))
(is (contains? actual :stop-node)))))
(testing "status-go has not started"
(let [actual (events/login-account
initial-db
[nil "testnet" "password"])]
(let [actual (models/login-account "testnet" "password" initial-db)]
(testing "it starts status-node"
(is (= {:NetworkId 3} (:initialize-geth-fx actual))))
(testing "it logins the user after the node started"
(is (= [::events/login-account "testnet" "password"] (get-in actual [:db :node/after-start])))))))
(is (= [:login-account-internal "testnet" "password"] (get-in actual [:db :node/after-start])))))))
(testing "custom bootnodes"
(let [custom-bootnodes {"a" {:id "a"
@ -69,64 +63,54 @@
bootnodes-db
[:db :accounts/accounts "mainnet" :settings]
{:bootnodes {"mainnet_rpc" true}})
actual (events/login-account
bootnodes-enabled-db
[nil "mainnet" "password"])]
actual (models/login-account "mainnet" "password" bootnodes-enabled-db)]
(testing "status-node has started"
(let [db (assoc-in bootnodes-enabled-db [:db :status-node-started?] true)
actual (events/login-account
db
[nil "mainnet" "password"])]
actual (models/login-account "mainnet" "password" db)]
(testing "it dispatches start-node"
(is (get-in actual [:db :node/after-stop] [::events/start-node "testnet" "password"])))
(is (get-in actual [:db :node/after-stop] [:start-node "testnet" "password"])))
(testing "it stops status-node"
(is (contains? actual ::events/stop-node)))))
(is (contains? actual :stop-node)))))
(testing "status-node has not started"
(let [actual (events/login-account
bootnodes-enabled-db
[nil "mainnet" "password"])]
(let [actual (models/login-account "mainnet" "password" bootnodes-enabled-db)]
(testing "it adds bootnodes to the config"
(is (= {:ClusterConfig {:Enabled true
:BootNodes ["address-a" "address-b"]}
:NetworkId 1} (:initialize-geth-fx actual))))
(testing "it logins the user after the node started"
(is (= [::events/login-account "mainnet" "password"] (get-in actual [:db :node/after-start]))))))))
(is (= [:login-account-internal "mainnet" "password"] (get-in actual [:db :node/after-start]))))))))
(testing "custom bootnodes not enabled"
(testing "status-node has started"
(let [db (assoc-in bootnodes-db [:db :status-node-started?] true)
actual (events/login-account
db
[nil "mainnet" "password"])]
actual (models/login-account "mainnet" "password" db)]
(testing "it does not start status-node if it has already started"
(is (not (:initialize-geth-fx actual))))
(testing "it logs in the user"
(is (= ["mainnet" "password"] (::events/login actual))))))
(is (= ["mainnet" "password"] (:login actual))))))
(testing "status-node has not started"
(let [actual (events/login-account
bootnodes-db
[nil "mainnet" "password"])]
(let [actual (models/login-account "mainnet" "password" bootnodes-db)]
(testing "it starts status-node without custom bootnodes"
(is (= {:NetworkId 1} (:initialize-geth-fx actual))))
(testing "it logins the user after the node started"
(is (= [::events/login-account "mainnet" "password"] (get-in actual [:db :node/after-start])))))))))))
(is (= [:login-account-internal "mainnet" "password"] (get-in actual [:db :node/after-start])))))))))))
(deftest restart-node?
(testing "custom bootnodes is toggled off"
(with-redefs [config/bootnodes-settings-enabled? false]
(testing "it returns true when the network is different"
(is (events/restart-node? "mainnet_rpc" "mainnet" true)))
(is (models/restart-node? "mainnet_rpc" "mainnet" true)))
(testing "it returns false when the network is the same"
(is (not (events/restart-node? "mainnet" "mainnet" true))))))
(is (not (models/restart-node? "mainnet" "mainnet" true))))))
(testing "custom bootnodes is toggled on"
(with-redefs [config/bootnodes-settings-enabled? true]
(testing "the user is not using custom bootnodes"
(testing "it returns true when the network is different"
(is (events/restart-node? "mainnet_rpc" "mainnet" false)))
(is (models/restart-node? "mainnet_rpc" "mainnet" false)))
(testing "it returns false when the network is the same"
(is (not (events/restart-node? "mainnet" "mainnet" false)))))
(is (not (models/restart-node? "mainnet" "mainnet" false)))))
(testing "the user is using custom bootnodes"
(testing "it returns true when the network is different"
(is (events/restart-node? "mainnet" "mainnet" true)))
(is (models/restart-node? "mainnet" "mainnet" true)))
(testing "it returns true when the network is the same"
(is (events/restart-node? "mainnet_rpc" "mainnet" true)))))))
(is (models/restart-node? "mainnet_rpc" "mainnet" true)))))))