[#8585] Add watch only account

This commit is contained in:
Andrey Shovkoplyas 2019-11-18 10:29:30 +01:00
parent 15d9e7be86
commit 4bffdede81
No known key found for this signature in database
GPG Key ID: EAAB7C8622D860A4
18 changed files with 213 additions and 117 deletions

View File

@ -181,7 +181,7 @@
(reg-root-key-sub :intro-wizard-state :intro-wizard) (reg-root-key-sub :intro-wizard-state :intro-wizard)
(reg-root-key-sub :popover/popover :popover/popover) (reg-root-key-sub :popover/popover :popover/popover)
(reg-root-key-sub :generate-account :generate-account) (reg-root-key-sub :add-account :add-account)
(reg-root-key-sub :keycard :hardwallet) (reg-root-key-sub :keycard :hardwallet)
@ -511,6 +511,12 @@
(fn [multiaccounts] (fn [multiaccounts]
(> (count multiaccounts) 1))) (> (count multiaccounts) 1)))
(re-frame/reg-sub
:accounts-without-watch-only
:<- [:multiaccount]
(fn [macc]
(filter #(not= (:type %) :watch) (:accounts macc))))
;;CHAT ============================================================================================================== ;;CHAT ==============================================================================================================
(re-frame/reg-sub (re-frame/reg-sub

View File

@ -1,12 +1,15 @@
(ns status-im.ui.components.toolbar (ns status-im.ui.components.toolbar
(:require [status-im.ui.components.react :as react] (:require [status-im.ui.components.react :as react]
[status-im.ui.components.button :as button])) [status-im.ui.components.button :as button]
[status-im.ui.components.colors :as colors]))
(defn toolbar [{:keys [center left right]}] (defn toolbar [{:keys [center left right show-border?]}]
(if center (if center
[react/view {:height 52 :align-items :center :justify-content :center} [react/view (merge {:height 52 :align-items :center :justify-content :center}
(when show-border? {:border-top-width 1 :border-top-color colors/gray-lighter}))
[button/button center]] [button/button center]]
[react/view {:height 52 :align-items :center :flex-direction :row} [react/view (merge {:height 52 :align-items :center :flex-direction :row}
(when show-border? {:border-top-width 1 :border-top-color colors/gray-lighter}))
(when left (when left
[button/button left]) [button/button left])
[react/view {:flex 1}] [react/view {:flex 1}]

View File

@ -98,7 +98,7 @@
(views/defview select-account [] (views/defview select-account []
(views/letsubs [height [:dimensions/window-height] (views/letsubs [height [:dimensions/window-height]
{:keys [accounts]} [:multiaccount] accounts [:accounts-without-watch-only]
{:keys [name color] :as dapps-account} [:dapps-account]] {:keys [name color] :as dapps-account} [:dapps-account]]
[react/view {:position :absolute [react/view {:position :absolute
:z-index 2 :z-index 2

View File

@ -86,7 +86,7 @@
(views/defview navigation [url can-go-back? can-go-forward? dapps-account] (views/defview navigation [url can-go-back? can-go-forward? dapps-account]
(views/letsubs [height [:dimensions/window-height] (views/letsubs [height [:dimensions/window-height]
{:keys [accounts]} [:multiaccount]] accounts [:accounts-without-watch-only]]
[react/view styles/navbar [react/view styles/navbar
[react/touchable-highlight {:on-press #(re-frame/dispatch [:browser.ui/previous-page-button-pressed]) [react/touchable-highlight {:on-press #(re-frame/dispatch [:browser.ui/previous-page-button-pressed])
:disabled (not can-go-back?) :disabled (not can-go-back?)

View File

@ -311,4 +311,4 @@
::collectibles ::collectibles
:registry/registry :registry/registry
::two-pane-ui-enabled? ::two-pane-ui-enabled?
::generate-account])) ::add-account]))

View File

@ -14,7 +14,6 @@
[status-im.ui.components.list.views :as list] [status-im.ui.components.list.views :as list]
[status-im.ui.components.radio :as radio] [status-im.ui.components.radio :as radio]
[status-im.ui.components.react :as react] [status-im.ui.components.react :as react]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.components.toolbar.actions :as actions] [status-im.ui.components.toolbar.actions :as actions]
[status-im.ui.components.toolbar.view :as toolbar] [status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.screens.chat.message.message :as message] [status-im.ui.screens.chat.message.message :as message]

View File

@ -545,14 +545,11 @@
(defview wizard-enter-phrase [] (defview wizard-enter-phrase []
(letsubs [wizard-state [:intro-wizard/enter-phrase]] (letsubs [wizard-state [:intro-wizard/enter-phrase]]
[react/keyboard-avoiding-view {:style {:flex 1}} [react/keyboard-avoiding-view {:style {:flex 1}}
[toolbar/toolbar [toolbar/toolbar {:style {:border-bottom-width 0}}
{:style {:border-bottom-width 0
:margin-top 16}}
(toolbar/nav-button (toolbar/nav-button
(actions/back #(re-frame/dispatch [:intro-wizard/navigate-back]))) (actions/back #(re-frame/dispatch [:intro-wizard/navigate-back])))
nil] nil]
[react/view {:style {:flex 1 [react/view {:style {:flex 1 :justify-content :space-between}}
:justify-content :space-between}}
[top-bar {:step :enter-phrase}] [top-bar {:step :enter-phrase}]
[enter-phrase wizard-state] [enter-phrase wizard-state]
[bottom-bar (merge {:step :enter-phrase [bottom-bar (merge {:step :enter-phrase

View File

@ -8,6 +8,7 @@
:new-public-chat :default :new-public-chat :default
:wallet-account :default :wallet-account :default
:add-new-account :default :add-new-account :default
:add-watch-account :default
:add-new-account-password :default :add-new-account-password :default
:about-app :default :about-app :default
:help-center :default :help-center :default

View File

@ -182,6 +182,7 @@
:welcome [:modal home/welcome] :welcome [:modal home/welcome]
:keycard-welcome keycard/welcome :keycard-welcome keycard/welcome
:add-new-account add-account/add-account :add-new-account add-account/add-account
:add-watch-account add-account/add-watch-account
:add-new-account-password add-account/password :add-new-account-password add-account/password
:account-added account-settings/account-added :account-added account-settings/account-added
:account-settings account-settings/account-settings}) :account-settings account-settings/account-settings})

View File

@ -5,6 +5,7 @@
:screens [:wallet :screens [:wallet
:wallet-account :wallet-account
:add-new-account :add-new-account
:add-watch-account
:add-new-account-password :add-new-account-password
:account-added :account-added
:account-settings :account-settings

View File

@ -39,7 +39,7 @@
[icons/icon icon {:color colors/white}] [icons/icon icon {:color colors/white}]
[react/text {:style {:margin-left 8 :color colors/white}} label]]]]) [react/text {:style {:margin-left 8 :color colors/white}} label]]]])
(views/defview account-card [{:keys [address color] :as account}] (views/defview account-card [{:keys [address color type] :as account}]
(views/letsubs [currency [:wallet/currency] (views/letsubs [currency [:wallet/currency]
portfolio-value [:account-portfolio-value address] portfolio-value [:account-portfolio-value address]
window-width [:dimensions/window-width]] window-width [:dimensions/window-width]]
@ -62,10 +62,13 @@
:accessibility-label :share-wallet-address-icon}]]] :accessibility-label :share-wallet-address-icon}]]]
[react/view {:height 52 :background-color colors/black-transparent-20 [react/view {:height 52 :background-color colors/black-transparent-20
:border-bottom-right-radius 8 :border-bottom-left-radius 8 :flex-direction :row} :border-bottom-right-radius 8 :border-bottom-left-radius 8 :flex-direction :row}
[button (if (= type :watch)
(i18n/label :t/wallet-send) [react/view {:flex 1 :align-items :center :justify-content :center}
:main-icons/send [react/text {:style {:margin-left 8 :color colors/white}} "Watch-only"]]
#(re-frame/dispatch [:wallet/prepare-transaction-from-wallet account])] [button
(i18n/label :t/wallet-send)
:main-icons/send
#(re-frame/dispatch [:wallet/prepare-transaction-from-wallet account])])
[react/view {:style styles/divider}] [react/view {:style styles/divider}]
[button [button
(i18n/label :t/receive) (i18n/label :t/receive)

View File

@ -33,7 +33,7 @@
:type :secondary}}]])) :type :secondary}}]]))
(defview account-added [] (defview account-added []
(letsubs [{:keys [account]} [:generate-account]] (letsubs [{:keys [account]} [:add-account]]
[react/keyboard-avoiding-view {:flex 1} [react/keyboard-avoiding-view {:flex 1}
[react/scroll-view {:keyboard-should-persist-taps :handled [react/scroll-view {:keyboard-should-persist-taps :handled
:style {:margin-top 70 :flex 1}} :style {:margin-top 70 :flex 1}}
@ -51,20 +51,22 @@
{:label (i18n/label :t/account-name) {:label (i18n/label :t/account-name)
:auto-focus false :auto-focus false
:default-value (:name account) :default-value (:name account)
:on-change-text #(re-frame/dispatch [:set-in [:generate-account :account :name] %])}] :placeholder (i18n/label :t/account-name)
:on-change-text #(re-frame/dispatch [:set-in [:add-account :account :name] %])}]
[react/text {:style {:margin-top 30}} (i18n/label :t/account-color)] [react/text {:style {:margin-top 30}} (i18n/label :t/account-color)]
[react/touchable-highlight [react/touchable-highlight
{:on-press #(re-frame/dispatch [:show-popover {:on-press #(re-frame/dispatch [:show-popover
{:view [colors-popover (:color account) {:view [colors-popover (:color account)
(fn [new-color] (fn [new-color]
(re-frame/dispatch [:set-in [:generate-account :account :color] new-color]) (re-frame/dispatch [:set-in [:add-account :account :color] new-color])
(re-frame/dispatch [:hide-popover]))] (re-frame/dispatch [:hide-popover]))]
:style {:max-height "60%"}}])} :style {:max-height "60%"}}])}
[react/view {:height 52 :margin-top 12 :background-color (:color account) :border-radius 8 [react/view {:height 52 :margin-top 12 :background-color (:color account) :border-radius 8
:align-items :flex-end :justify-content :center :padding-right 12} :align-items :flex-end :justify-content :center :padding-right 12}
[icons/icon :main-icons/dropdown {:color colors/white}]]]]] [icons/icon :main-icons/dropdown {:color colors/white}]]]]]
[toolbar/toolbar [toolbar/toolbar
{:right {:type :next {:show-border? true
:right {:type :next
:label (i18n/label :t/finish) :label (i18n/label :t/finish)
:on-press #(re-frame/dispatch [:wallet.accounts/save-generated-account]) :on-press #(re-frame/dispatch [:wallet.accounts/save-generated-account])
:disabled? (string/blank? (:name account))}}]])) :disabled? (string/blank? (:name account))}}]]))
@ -77,7 +79,7 @@
value)]) value)])
(defview account-settings [] (defview account-settings []
(letsubs [{:keys [address color path] :as account} [:current-account] (letsubs [{:keys [address color path type] :as account} [:current-account]
new-account (reagent/atom nil)] new-account (reagent/atom nil)]
[react/keyboard-avoiding-view {:flex 1} [react/keyboard-avoiding-view {:flex 1}
[topbar/toolbar {} [topbar/toolbar {}
@ -109,13 +111,15 @@
:border-radius 8 :border-radius 8
:align-items :flex-end :justify-content :center :padding-right 12} :align-items :flex-end :justify-content :center :padding-right 12}
[icons/icon :main-icons/dropdown {:color colors/white}]]] [icons/icon :main-icons/dropdown {:color colors/white}]]]
[property (i18n/label :t/type) (i18n/label :t/on-status-tree)] [property (i18n/label :t/type) (case type :watch "Watch-only" (i18n/label :t/on-status-tree))]
[property (i18n/label :t/wallet-address) [property (i18n/label :t/wallet-address)
[copyable-text/copyable-text-view [copyable-text/copyable-text-view
{:copied-text address} {:copied-text address}
[react/text {:style {:margin-top 6 :font-family "monospace"}} address]]] [react/text {:style {:margin-top 6 :font-family "monospace"}} address]]]
[property (i18n/label :t/derivation-path) (when-not (= type :watch)
[copyable-text/copyable-text-view [property (i18n/label :t/derivation-path)
{:copied-text path} [copyable-text/copyable-text-view
[react/text {:style {:margin-top 6 :font-family "monospace"}} path]]] {:copied-text path}
[property (i18n/label :t/storage) (i18n/label :t/this-device)]]]])) [react/text {:style {:margin-top 6 :font-family "monospace"}} path]]])
(when-not (= type :watch)
[property (i18n/label :t/storage) (i18n/label :t/this-device)])]]]))

View File

@ -35,14 +35,15 @@
:accessibility-label :wallet-backup-recovery-title :accessibility-label :wallet-backup-recovery-title
:on-press #(hide-sheet-and-dispatch [:navigate-to :backup-seed])}])])) :on-press #(hide-sheet-and-dispatch [:navigate-to :backup-seed])}])]))
(defn send-receive [account] (defn send-receive [account type]
[react/view [react/view
[list-item/list-item (when-not (= type :watch)
{:theme :action [list-item/list-item
:title :t/wallet-send {:theme :action
:icon :main-icons/send :title :t/wallet-send
:accessibility-label :send-transaction-button :icon :main-icons/send
:on-press #(hide-sheet-and-dispatch [:wallet/prepare-transaction-from-wallet account])}] :accessibility-label :send-transaction-button
:on-press #(hide-sheet-and-dispatch [:wallet/prepare-transaction-from-wallet account])}])
[list-item/list-item [list-item/list-item
{:theme :action {:theme :action
:title :t/receive :title :t/receive
@ -63,7 +64,7 @@
{:theme :action {:theme :action
:title :t/add-a-watch-account :title :t/add-a-watch-account
:icon :main-icons/watch :icon :main-icons/watch
:disabled? true}]]) :on-press #(hide-sheet-and-dispatch [:wallet.accounts/start-adding-new-account {:type :watch}])}]])
(defn account-settings [] (defn account-settings []
[react/view [react/view

View File

@ -17,16 +17,17 @@
(def state (reagent/atom {:tab :assets})) (def state (reagent/atom {:tab :assets}))
(views/defview account-card [{:keys [name color address] :as account}] (views/defview account-card [{:keys [name color address type] :as account}]
(views/letsubs [currency [:wallet/currency] (views/letsubs [currency [:wallet/currency]
portfolio-value [:account-portfolio-value address]] portfolio-value [:account-portfolio-value address]]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :wallet-account account]) [react/touchable-highlight
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet {:on-press #(re-frame/dispatch [:navigate-to :wallet-account account])
{:content (fn [] [sheets/send-receive account]) :on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet
:content-height 130}])} {:content (fn [] [sheets/send-receive account type])
:content-height 130}])}
[react/view {:style (styles/card color)} [react/view {:style (styles/card color)}
[react/view {:flex-direction :row :align-items :center :justify-content :space-between} [react/view {:flex-direction :row :align-items :center :justify-content :space-between}
[react/nested-text {:style {:color colors/white-transparent :font-weight "500"}} [react/nested-text {:style {:color colors/white-transparent :font-weight "500" :flex-shrink 1}}
[{:style {:color colors/white}} portfolio-value] [{:style {:color colors/white}} portfolio-value]
" " " "
(:code currency)] (:code currency)]

View File

@ -1,26 +1,28 @@
(ns status-im.ui.screens.wallet.add-new.views (ns status-im.ui.screens.wallet.add-new.views
(:require-macros [status-im.utils.views :refer [defview letsubs]]) (:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [status-im.ui.components.react :as react] (:require [status-im.ui.components.react :as react]
[status-im.ui.components.toolbar.view :as toolbar] [status-im.ui.components.toolbar.view :as topbar]
[status-im.i18n :as i18n] [status-im.i18n :as i18n]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[status-im.ui.components.colors :as colors] [status-im.ui.components.colors :as colors]
[status-im.ui.components.list-item.views :as list-item] [status-im.ui.components.list-item.views :as list-item]
[status-im.ui.components.common.common :as components.common]
[reagent.core :as reagent] [reagent.core :as reagent]
[cljs.spec.alpha :as spec] [cljs.spec.alpha :as spec]
[status-im.multiaccounts.db :as multiaccounts.db])) [status-im.multiaccounts.db :as multiaccounts.db]
[status-im.ui.components.toolbar :as toolbar]
[status-im.ui.components.styles :as components.styles]
[status-im.ethereum.core :as ethereum]))
(defn add-account [] (defn add-account []
[react/view {:flex 1} [react/view {:flex 1}
[toolbar/toolbar {:transparent? true} toolbar/default-nav-back nil] [topbar/simple-toolbar]
[react/scroll-view {:keyboard-should-persist-taps :handled [react/scroll-view {:keyboard-should-persist-taps :handled
:style {:flex 1}} :style {:flex 1}}
[react/view {:align-items :center :padding-horizontal 40} [react/view {:align-items :center :padding-horizontal 40 :margin-bottom 52}
[react/text {:style {:typography :header :margin-top 16}} (i18n/label :t/add-an-account)] [react/text {:style {:typography :header :margin-top 16}}
(i18n/label :t/add-an-account)]
[react/text {:style {:color colors/gray :text-align :center :margin-top 16 :line-height 22}} [react/text {:style {:color colors/gray :text-align :center :margin-top 16 :line-height 22}}
(i18n/label :t/add-account-description)]] (i18n/label :t/add-account-description)]]
[react/view {:height 52}]
[list-item/list-item [list-item/list-item
{:type :section-header {:type :section-header
:title :t/default}] :title :t/default}]
@ -29,40 +31,83 @@
:theme :action :theme :action
:icon :main-icons/add :icon :main-icons/add
:accessories [:chevron] :accessories [:chevron]
:on-press :on-press #(re-frame/dispatch [:wallet.accounts/start-adding-new-account {:type :generate}])}]
#(re-frame/dispatch [list-item/list-item
[:navigate-to :add-new-account-password])}]]]) {:type :section-header
:container-margin-top 24
:title "Advanced"}]
[list-item/list-item
{:title "Enter a seed phrase"
:theme :action
:icon :main-icons/add
:accessories [:chevron]
:disabled? true
:on-press #(re-frame/dispatch [:wallet.accounts/start-adding-new-account {:type :seed}])}]
[list-item/list-item
{:title "Enter a private key"
:theme :action
:icon :main-icons/add
:accessories [:chevron]
:disabled? true
:on-press #(re-frame/dispatch [:wallet.accounts/start-adding-new-account {:type :key}])}]]])
(def input-container
{:flex-direction :row
:align-items :center
:border-radius components.styles/border-radius
:height 52
:margin 16
:padding-horizontal 16
:background-color colors/gray-lighter})
(defview add-watch-account []
(letsubs [{:keys [address]} [:add-account]]
[react/keyboard-avoiding-view {:flex 1}
[topbar/simple-toolbar]
[react/view {:flex 1
:justify-content :space-between
:align-items :center :margin-horizontal 16}
[react/view
[react/text {:style {:typography :header :margin-top 16}} "Add a watch-only address"]
[react/text {:style {:color colors/gray :text-align :center :margin-vertical 16}}
"Enter the address to watch"]]
[react/view {:align-items :center :flex 1 :flex-direction :row}
[react/text-input {:auto-focus true
:multiline true
:text-align :center
:placeholder "Enter address"
:style {:typography :header :flex 1}
:on-change-text #(re-frame/dispatch [:set-in [:add-account :address] %])}]]]
[toolbar/toolbar
{:show-border? true
:right {:type :next
:label "Next"
:on-press #(re-frame/dispatch [:wallet.accounts/add-watch-account])
:disabled? (not (ethereum/address? address))}}]]))
(defview password [] (defview password []
(letsubs [{:keys [error]} [:generate-account] (letsubs [{:keys [error]} [:add-account]
entered-password (reagent/atom "")] entered-password (reagent/atom "")]
[react/keyboard-avoiding-view {:style {:flex 1}} [react/keyboard-avoiding-view {:style {:flex 1}}
[toolbar/toolbar {:transparent? true} toolbar/default-nav-back nil] [topbar/simple-toolbar]
[react/view {:flex 1} [react/view {:flex 1
[react/view {:style {:flex 1 :justify-content :space-between
:justify-content :space-between :align-items :center :margin-horizontal 16}
:align-items :center :margin-horizontal 16}} [react/text {:style {:typography :header :margin-top 16}} (i18n/label :t/enter-your-password)]
[react/text {:style {:typography :header :margin-top 16}} (i18n/label :t/enter-your-password)] [react/view {:justify-content :center :flex 1}
[react/view {:style {:justify-content :center :flex 1}} [react/text-input {:secure-text-entry true
[react/text-input {:secure-text-entry true :auto-focus true
:auto-focus true :text-align :center
:text-align :center :placeholder ""
:placeholder "" :style {:typography :header}
:style {:typography :header} :on-change-text #(reset! entered-password %)}]
:on-change-text #(reset! entered-password %)}] (when error
(when error [react/text {:style {:text-align :center :color colors/red :margin-top 76}} error])]
[react/text {:style {:text-align :center :color colors/red :margin-top 76}} error])] [react/text {:style {:color colors/gray :text-align :center :margin-bottom 16}}
[react/text {:style {:color colors/gray :text-align :center :margin-bottom 16}} (i18n/label :t/to-encrypt-enter-password)]]
(i18n/label :t/to-encrypt-enter-password)]] [toolbar/toolbar
[react/view {:style {:flex-direction :row {:show-border? true
:justify-content :flex-end :right {:type :next
:align-self :stretch :label :t/generate-account
:padding-vertical 16 :on-press #(re-frame/dispatch [:wallet.accounts/generate-new-account @entered-password])
:border-top-width 1 :disabled? (not (spec/valid? ::multiaccounts.db/password @entered-password))}}]]))
:border-top-color colors/gray-lighter
:padding-right 12}}
[components.common/bottom-button {:label (i18n/label :t/generate-account)
:on-press #(re-frame/dispatch
[:wallet.accounts/generate-new-account @entered-password])
:disabled? (not (spec/valid? ::multiaccounts.db/password @entered-password))
:forward? true}]]]]))

View File

@ -17,4 +17,4 @@
(defmethod navigation/preload-data! :add-new-account (defmethod navigation/preload-data! :add-new-account
[db [event]] [db [event]]
(dissoc db :generate-account)) (dissoc db :add-account))

View File

@ -27,8 +27,9 @@
:on-press #(re-frame/dispatch [:wallet.send/set-field field account])}])) :on-press #(re-frame/dispatch [:wallet.send/set-field field account])}]))
(views/defview accounts-list [field] (views/defview accounts-list [field]
(views/letsubs [{:keys [accounts]} [:multiaccount]] (views/letsubs [{:keys [accounts]} [:multiaccount]
[list/flat-list {:data accounts accounts-whithout-watch [:accounts-without-watch-only]]
[list/flat-list {:data (if (= :to field) accounts accounts-whithout-watch)
:key-fn :address :key-fn :address
:render-fn (render-account field)}])) :render-fn (render-account field)}]))

View File

@ -42,11 +42,11 @@
(let [{:keys [public-key address]} (let [{:keys [public-key address]}
(get (types/json->clj result) (keyword path))] (get (types/json->clj result) (keyword path))]
(re-frame/dispatch [::account-generated (re-frame/dispatch [::account-generated
{:name (str "Account " path-num) {:name (str "Account " path-num)
:address address :address address
:public-key public-key :public-key public-key
:path (str constants/path-wallet-root "/" path-num) :path (str constants/path-wallet-root "/" path-num)
:color (rand-nth colors/account-colors)}]))))))))))))) :color (rand-nth colors/account-colors)}])))))))))))))
(fx/defn set-symbol-request (fx/defn set-symbol-request
{:events [:wallet.accounts/share]} {:events [:wallet.accounts/share]}
@ -57,42 +57,41 @@
{:events [:wallet.accounts/generate-new-account]} {:events [:wallet.accounts/generate-new-account]}
[{:keys [db]} password] [{:keys [db]} password]
(let [wallet-root-address (get-in db [:multiaccount :wallet-root-address]) (let [wallet-root-address (get-in db [:multiaccount :wallet-root-address])
path-num (inc (get-in db [:multiaccount :latest-derived-path]))] path-num (inc (get-in db [:multiaccount :latest-derived-path]))]
(when-not (get-in db [:generate-account :step]) (when-not (get-in db [:add-account :step])
{:db (assoc-in db [:generate-account :step] :generating) {:db (assoc-in db [:add-account :step] :generating)
::generate-account {:derivation-info (if wallet-root-address ::generate-account {:derivation-info (if wallet-root-address
;; Use the walllet-root-address for stored on disk keys ;; Use the walllet-root-address for stored on disk keys
;; This needs to be the RELATIVE path to the key used to derive ;; This needs to be the RELATIVE path to the key used to derive
{:path (str "m/" path-num) {:path (str "m/" path-num)
:address wallet-root-address} :address wallet-root-address}
;; Fallback on the master account for keycards, use the absolute path ;; Fallback on the master account for keycards, use the absolute path
{:path (str constants/path-wallet-root "/" path-num) {:path (str constants/path-wallet-root "/" path-num)
:address (get-in db [:multiaccount :address])}) :address (get-in db [:multiaccount :address])})
:path-num path-num :path-num path-num
:hashed-password (ethereum/sha3 password)}}))) :hashed-password (ethereum/sha3 password)}})))
(fx/defn generate-new-account-error (fx/defn generate-new-account-error
{:events [::generate-new-account-error]} {:events [::generate-new-account-error]}
[{:keys [db]} password] [{:keys [db]} password]
{:db (assoc db {:db (assoc db
:generate-account :add-account
{:error (i18n/label :t/add-account-incorrect-password)})}) {:error (i18n/label :t/add-account-incorrect-password)})})
(fx/defn account-generated (fx/defn account-generated
{:events [::account-generated]} {:events [::account-generated]}
[{:keys [db] :as cofx} account] [{:keys [db] :as cofx} account]
(fx/merge cofx (fx/merge cofx
{:db (assoc db :generate-account {:account account {:db (update db :add-account assoc :account account :step :generated)}
:step :generated})}
(navigation/navigate-to-cofx :account-added nil))) (navigation/navigate-to-cofx :account-added nil)))
(fx/defn save-account (fx/defn save-account
{:events [:wallet.accounts/save-account]} {:events [:wallet.accounts/save-account]}
[{:keys [db] :as cofx} account {:keys [name color]}] [{:keys [db] :as cofx} account {:keys [name color]}]
(let [{:keys [accounts]} (:multiaccount db) (let [{:keys [accounts]} (:multiaccount db)
new-account (cond-> account new-account (cond-> account
name (assoc :name name) name (assoc :name name)
color (assoc :color color)) color (assoc :color color))
new-accounts (replace {account new-account} accounts)] new-accounts (replace {account new-account} accounts)]
(multiaccounts.update/multiaccount-update cofx {:accounts new-accounts} nil))) (multiaccounts.update/multiaccount-update cofx {:accounts new-accounts} nil)))
@ -100,14 +99,48 @@
{:events [:wallet.accounts/save-generated-account]} {:events [:wallet.accounts/save-generated-account]}
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [{:keys [accounts latest-derived-path]} (:multiaccount db) (let [{:keys [accounts latest-derived-path]} (:multiaccount db)
{:keys [account]} (:generate-account db)] {:keys [account path type]} (:add-account db)]
(when account (when account
(fx/merge cofx (fx/merge cofx
{::json-rpc/call [{:method "accounts_saveAccounts" {::json-rpc/call [{:method "accounts_saveAccounts"
:params [[account]] :params [[account]]
:on-success #()}] :on-success #()}]
:db (dissoc db :generate-account)} :db (dissoc db :add-account)}
(multiaccounts.update/multiaccount-update {:accounts (conj accounts account) (multiaccounts.update/multiaccount-update
:latest-derived-path (inc latest-derived-path)} nil) (merge {:accounts (conj accounts account)}
(when (= type :generate)
{:latest-derived-path (max (int path) latest-derived-path)}))
nil)
(wallet/update-balances nil) (wallet/update-balances nil)
(navigation/navigate-to-cofx :wallet nil))))) (navigation/navigate-to-cofx :wallet nil)))))
(fx/defn start-adding-new-account
{:events [:wallet.accounts/start-adding-new-account]}
[{:keys [db] :as cofx} {:keys [type] :as add-account}]
(let [screen (case type :generate :add-new-account-password :watch :add-watch-account)]
(fx/merge cofx
{:db (assoc db :add-account add-account)}
(navigation/navigate-to-cofx screen nil))))
(fx/defn enter-phrase-next-pressed
{:events [:wallet.accounts/enter-phrase-next-pressed]}
[{:keys [db] :as cofx}]
(fx/merge cofx
{:db (-> db
(dissoc :intro-wizard)
(assoc-in [:add-account :seed] (get-in db [:intro-wizard :passphrase])))}
(navigation/navigate-to-cofx :add-new-account-password nil)))
(fx/defn add-watch-account
{:events [:wallet.accounts/add-watch-account]}
[{:keys [db] :as cofx}]
(let [address (get-in db [:add-account :address])]
(fx/merge cofx
{:db (assoc-in db [:add-account :account]
{:name ""
:address (eip55/address->checksum (ethereum/normalized-hex address))
:public-key nil
:path ""
:type :watch
:color (rand-nth colors/account-colors)})}
(navigation/navigate-to-cofx :account-added nil))))