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 (ns status-im.ui.screens.accounts.events
(:require [re-frame.core :as re-frame] (: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 :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.create.navigation
[status-im.ui.screens.accounts.utils :as accounts.utils] [status-im.ui.screens.accounts.utils :as accounts.utils]
[status-im.data-store.accounts :as accounts-store] [status-im.ui.screens.accounts.models :as models]))
[status-im.ui.screens.navigation :as navigation]
[status-im.ui.screens.wallet.settings.models :as wallet.settings.models]))
;;;; COFX ;;;; COFX
(re-frame/reg-cofx (re-frame/reg-cofx
::get-signing-phrase ::get-signing-phrase
(fn [coeffects _] (fn [cofx _]
(assoc coeffects :signing-phrase (signing-phrase/generate)))) (models/get-signing-phrase cofx)))
(re-frame/reg-cofx (re-frame/reg-cofx
::get-status ::get-status
(fn [coeffects _] (fn [cofx _]
(assoc coeffects :status (rand-nth statuses/data)))) (models/get-status cofx)))
;;;; FX ;;;; FX
(re-frame/reg-fx (re-frame/reg-fx
::create-account :create-account
(fn [password] models/create-account!)
(status/create-account
password
#(re-frame/dispatch [::account-created (json->clj %) password]))))
;;;; Handlers ;;;; Handlers
(handlers/register-handler-fx (handlers/register-handler-fx
:create-account :create-account
(fn [{{:accounts/keys [create] :as db} :db} _] (fn [cofx _]
{:db (update db :accounts/create assoc :step :account-creating :error nil) (models/create-account cofx)))
::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)]}))
(handlers/register-handler-fx (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)] [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]] (fn [cofx [result password]]
(let [normalized-address (utils.hex/normalize-hex address) (models/on-account-created result password cofx)))
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}]})))
(handlers/register-handler-fx (handlers/register-handler-fx
:send-account-update-if-needed :send-account-update-if-needed
(fn [{:keys [db now] :as cofx} _] (fn [cofx _]
(let [{:keys [last-updated]} (:account/account db) (models/send-account-update-if-needed cofx)))
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)))))
(handlers/register-handler-fx (handlers/register-handler-fx
:account-set-name :account-set-name
(fn [{{:accounts/keys [create] :as db} :db :as cofx} _] (fn [cofx _]
(handlers-macro/merge-fx cofx (models/account-set-name cofx)))
{:db (assoc db :accounts/create {:show-welcome? true})
:dispatch-n [[:navigate-to-clean :home]
[:request-notifications]]}
(accounts.utils/account-update {:name (:name create)}))))
(handlers/register-handler-fx (handlers/register-handler-fx
:account-set-input-text :account-set-input-text
(fn [{db :db} [_ input-key text]] (fn [cofx [_ input-key text]]
{:db (update db :accounts/create merge {input-key text :error nil})})) (models/account-set-input-text input-key text cofx)))
(handlers/register-handler-fx (handlers/register-handler-fx
:update-sign-in-time :update-sign-in-time
@ -132,44 +63,20 @@
(handlers/register-handler-fx (handlers/register-handler-fx
:show-mainnet-is-default-alert :show-mainnet-is-default-alert
(fn [{:keys [db]}] (fn [cofx]
(let [enter-name-screen? (= :enter-name (get-in db [:accounts/create :step])) (models/show-mainnet-is-default-alert cofx)))
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]))))))
(handlers/register-handler-fx (handlers/register-handler-fx
:reset-account-creation :reset-account-creation
(fn [{db :db} _] (fn [cofx _]
{:db (update db :accounts/create assoc :step :enter-password :password nil :password-confirm nil :error nil)})) (models/reset-account-creation cofx)))
(handlers/register-handler-fx (handlers/register-handler-fx
:switch-dev-mode :switch-dev-mode
(fn [cofx [_ dev-mode]] (fn [cofx [_ dev-mode]]
(accounts.utils/account-update {:dev-mode? dev-mode} cofx))) (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 (handlers/register-handler-fx
:wallet-set-up-passed :wallet-set-up-passed
(fn [{:keys [db] :as cofx} [_ modal?]] (fn [cofx [_ modal?]]
(handlers-macro/merge-fx (models/wallet-set-up-passed modal? cofx)))
cofx
(wallet-set-up-passed db modal?)
(wallet.settings.models/wallet-autoconfig-tokens)
(accounts.utils/account-update {:wallet-set-up-passed? true}))))

View File

@ -1,160 +1,55 @@
(ns status-im.ui.screens.accounts.login.events (ns status-im.ui.screens.accounts.login.events
(:require status-im.ui.screens.accounts.login.navigation (:require status-im.ui.screens.accounts.login.navigation
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[status-im.utils.handlers :refer [register-handler-db register-handler-fx]] [status-im.utils.handlers :as handlers]
[taoensso.timbre :as log] [status-im.ui.screens.accounts.login.models :as models]))
[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]))
;;;; FX ;;;; FX
(re-frame/reg-fx ::stop-node (fn [] (status/stop-node))) (re-frame/reg-fx :stop-node models/stop-node!)
(re-frame/reg-fx (re-frame/reg-fx
::login :login
(fn [[address password]] (fn [[address password]]
(status/login address password #(re-frame/dispatch [:login-handler % address])))) (models/login! address password)))
(re-frame/reg-fx (re-frame/reg-fx
::clear-web-data :clear-web-data
(fn [] models/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])))))
(re-frame/reg-fx (re-frame/reg-fx
::change-account :change-account
(fn [[address]] (fn [[address]]
(handle-change-account address))) (models/handle-change-account! address)))
;;;; Handlers ;;;; Handlers
(register-handler-fx (handlers/register-handler-fx
:open-login :open-login
(fn [{db :db} [_ address photo-path name]] (fn [cofx [_ address photo-path name]]
{:db (update db (models/open-login address photo-path name cofx)))
:accounts/login assoc
:address address
:photo-path photo-path
:name name)
:dispatch [:navigate-to :login]}))
(defn wrap-with-login-account-fx [db address password] (handlers/register-handler-fx
{:db db :login-account-internal
::login [address password]}) (fn [cofx [_ address password]]
(models/login-account-internal address password cofx)))
(register-handler-fx (handlers/register-handler-fx
::login-account :start-node
(fn [{db :db} [_ address password]] (fn [cofx [_ address password]]
(wrap-with-login-account-fx (models/start-node address password cofx)))
(assoc db :node/after-start nil)
address password)))
(defn add-custom-bootnodes [config network all-bootnodes] (handlers/register-handler-fx
(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
:login-account :login-account
login-account) (fn [cofx [_ address password]]
(models/login-account address password cofx)))
(register-handler-fx (handlers/register-handler-fx
:login-handler :login-handler
(fn [{db :db} [_ login-result address]] (fn [cofx [_ login-result address]]
(let [data (json->clj login-result) (models/login-handler login-result address cofx)))
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)}))))
(register-handler-fx (handlers/register-handler-fx
:change-account-handler :change-account-handler
(fn [{{:keys [view-id] :as db} :db :as cofx} [_ address]] (fn [cofx [_ address]]
{:db (cond-> (dissoc db :accounts/login) (models/change-account-handler address cofx)))
(= 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,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 (ns status-im.ui.screens.accounts.recover.events
(:require (:require status-im.ui.screens.accounts.recover.navigation
status-im.ui.screens.accounts.recover.navigation [re-frame.core :as re-frame]
[clojure.string :as string] [status-im.ui.screens.accounts.recover.models :as models]
[re-frame.core :as re-frame] [status-im.utils.handlers :as handlers]))
[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]))
;;;; FX ;;;; FX
(re-frame/reg-fx (re-frame/reg-fx
::recover-account-fx :recover-account-fx
(fn [[masked-passphrase password]] (fn [[masked-passphrase password]]
(status/recover-account (models/recover-account-fx! masked-passphrase password)))
(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 ;;;; Handlers
(handlers/register-handler-fx (handlers/register-handler-fx
:account-recovered :account-recovered
(fn [{:keys [db]} [_ result password]] (fn [cofx [_ result password]]
(let [data (types/json->clj result) (models/on-account-recovered result password cofx)))
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]}]))))))
(handlers/register-handler-fx (handlers/register-handler-fx
:account-recovered-navigate :account-recovered-navigate
(fn [{:keys [db]}] (fn [cofx]
{:db (assoc-in db [:accounts/recover :processing] false) (models/account-recovered-navigate cofx)))
:dispatch-n [[:navigate-to-clean :home]
[:request-notifications]]}))
(handlers/register-handler-fx (handlers/register-handler-fx
:recover-account :recover-account
(fn [{:keys [db]} [_ masked-passphrase password]] (fn [cofx [_ masked-passphrase password]]
{:db (assoc-in db [:accounts/recover :processing] true) (models/recover-account masked-passphrase password cofx)))
::recover-account-fx [masked-passphrase password]}))

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 (ns status-im.ui.screens.bootnodes-settings.events
(:require [re-frame.core :as re-frame] (:require [status-im.utils.handlers :as handlers]
[status-im.utils.handlers :as handlers]
[status-im.utils.handlers-macro :as handlers-macro] [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.ui.screens.bootnodes-settings.edit-bootnode.events))
[status-im.transport.core :as transport]
status-im.ui.screens.bootnodes-settings.edit-bootnode.events
[status-im.utils.ethereum.core :as ethereum]))
(defn toggle-custom-bootnodes [value {:keys [db] :as cofx}] (defn toggle-custom-bootnodes [value {:keys [db] :as cofx}]
(let [network (get-in db [:account/account :network]) (let [network (get-in db [:account/account :network])
settings (get-in db [:account/account :settings])] settings (get-in db [:account/account :settings])]
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
(accounts-events/update-settings (accounts.models/update-settings
(assoc-in settings [:bootnodes network] value) (assoc-in settings [:bootnodes network] value)
[:logout])))) [:logout]))))

View File

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

View File

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

View File

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

View File

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