Separate hardwallet events into multiple ns
Signed-off-by: Gheorghe Pinzaru <feross95@gmail.com>
This commit is contained in:
parent
9a713148c7
commit
f18e7d746b
|
@ -26,7 +26,6 @@
|
|||
[status-im.ethereum.transactions.core :as ethereum.transactions]
|
||||
[status-im.fleet.core :as fleet]
|
||||
[status-im.group-chats.core :as group-chats]
|
||||
[status-im.hardwallet.core :as hardwallet]
|
||||
[status-im.signing.keycard :as signing.keycard]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.init.core :as init]
|
||||
|
@ -65,6 +64,7 @@
|
|||
[status-im.wallet.db :as wallet.db]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.utils.money :as money]
|
||||
status-im.hardwallet.core
|
||||
status-im.popover.core))
|
||||
|
||||
;; init module
|
||||
|
@ -598,183 +598,11 @@
|
|||
|
||||
;; hardwallet module
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-register-card-events
|
||||
(fn [cofx [_ listeners]]
|
||||
(hardwallet/on-register-card-events cofx listeners)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/get-application-info
|
||||
(fn [cofx _]
|
||||
(hardwallet/get-application-info cofx nil nil)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-get-application-info-success
|
||||
(fn [cofx [_ info on-success]]
|
||||
(hardwallet/on-get-application-info-success cofx info on-success)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-get-application-info-error
|
||||
(fn [cofx [_ error]]
|
||||
(hardwallet/on-get-application-info-error cofx error)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/check-nfc-support-success
|
||||
(fn [cofx [_ supported?]]
|
||||
(hardwallet/set-nfc-supported cofx supported?)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-card-connected
|
||||
(fn [cofx [_ data]]
|
||||
(hardwallet/on-card-connected cofx data)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-card-disconnected
|
||||
(fn [cofx [_ data]]
|
||||
(hardwallet/on-card-disconnected cofx data)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-init-card-success
|
||||
(fn [cofx [_ secrets]]
|
||||
(hardwallet/on-init-card-success cofx secrets)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-init-card-error
|
||||
(fn [cofx [_ error]]
|
||||
(hardwallet/on-init-card-error cofx error)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-install-applet-and-init-card-error
|
||||
(fn [cofx [_ error]]
|
||||
(hardwallet/on-install-applet-and-init-card-error cofx error)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-pair-success
|
||||
(fn [cofx [_ pairing]]
|
||||
(hardwallet/on-pair-success cofx pairing)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-pair-error
|
||||
(fn [cofx [_ error]]
|
||||
(hardwallet/on-pair-error cofx error)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-generate-mnemonic-success
|
||||
(fn [cofx [_ mnemonic]]
|
||||
(hardwallet/on-generate-mnemonic-success cofx mnemonic)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-generate-mnemonic-error
|
||||
(fn [cofx [_ error]]
|
||||
(hardwallet/on-generate-mnemonic-error cofx error)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-generate-and-load-key-success
|
||||
[(re-frame/inject-cofx :random-guid-generator)
|
||||
(re-frame/inject-cofx ::multiaccounts.create/get-signing-phrase)]
|
||||
(fn [cofx [_ data]]
|
||||
(hardwallet/on-generate-and-load-key-success cofx data)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-generate-and-load-key-error
|
||||
(fn [cofx [_ error]]
|
||||
(hardwallet/on-generate-and-load-key-error cofx error)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-unblock-pin-success
|
||||
(fn [cofx _]
|
||||
(hardwallet/on-unblock-pin-success cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-unblock-pin-error
|
||||
(fn [cofx [_ error]]
|
||||
(hardwallet/on-unblock-pin-error cofx error)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-verify-pin-success
|
||||
(fn [cofx _]
|
||||
(hardwallet/on-verify-pin-success cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-verify-pin-error
|
||||
(fn [cofx [_ error]]
|
||||
(hardwallet/on-verify-pin-error cofx error)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-change-pin-success
|
||||
(fn [cofx _]
|
||||
(hardwallet/on-change-pin-success cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-change-pin-error
|
||||
(fn [cofx [_ error]]
|
||||
(hardwallet/on-change-pin-error cofx error)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-unpair-success
|
||||
(fn [cofx _]
|
||||
(hardwallet/on-unpair-success cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-unpair-error
|
||||
(fn [cofx [_ error]]
|
||||
(hardwallet/on-unpair-error cofx error)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-delete-success
|
||||
(fn [cofx _]
|
||||
(hardwallet/on-delete-success cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-delete-error
|
||||
(fn [cofx [_ error]]
|
||||
(hardwallet/on-delete-error cofx error)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-remove-key-success
|
||||
(fn [cofx _]
|
||||
(hardwallet/on-remove-key-success cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-remove-key-error
|
||||
(fn [cofx [_ error]]
|
||||
(hardwallet/on-remove-key-error cofx error)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-get-keys-success
|
||||
(fn [cofx [_ data]]
|
||||
(hardwallet/on-get-keys-success cofx data)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-get-keys-error
|
||||
(fn [cofx [_ error]]
|
||||
(hardwallet/on-get-keys-error cofx error)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.callback/on-sign-error
|
||||
(fn [cofx [_ error]]
|
||||
(hardwallet/on-sign-error cofx error)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/password-option-pressed
|
||||
(fn [cofx _]
|
||||
(hardwallet/password-option-pressed cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/go-to-settings-button-pressed
|
||||
(fn [_ _]
|
||||
{:hardwallet/open-nfc-settings nil}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/begin-setup-button-pressed
|
||||
(fn [cofx _]
|
||||
(hardwallet/begin-setup-button-pressed cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/start-installation
|
||||
(fn [cofx _]
|
||||
(hardwallet/start-installation cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/pair-card-button-pressed
|
||||
(fn [{:keys [db]} _]
|
||||
|
@ -785,21 +613,6 @@
|
|||
(fn [{:keys [db]} [_ pair-code]]
|
||||
{:db (assoc-in db [:hardwallet :secrets :password] pair-code)}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/pair-code-next-button-pressed
|
||||
(fn [cofx]
|
||||
(hardwallet/pair-code-next-button-pressed cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/recovery-phrase-next-button-pressed
|
||||
(fn [cofx _]
|
||||
(hardwallet/recovery-phrase-next-button-pressed cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/recovery-phrase-confirm-word-next-button-pressed
|
||||
(fn [cofx _]
|
||||
(hardwallet/recovery-phrase-confirm-word cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/recovery-phrase-confirm-word-back-button-pressed
|
||||
(fn [{:keys [db]} _]
|
||||
|
@ -810,87 +623,17 @@
|
|||
(fn [{:keys [db]} [_ input]]
|
||||
{:db (assoc-in db [:hardwallet :recovery-phrase :input-word] input)}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/recovery-phrase-confirm-pressed
|
||||
(fn [cofx _]
|
||||
(hardwallet/load-loading-keys-screen cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/load-loading-keys-screen
|
||||
(fn [cofx _]
|
||||
(hardwallet/load-loading-keys-screen cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/recovery-phrase-cancel-pressed
|
||||
(fn [{:keys [db]} _]
|
||||
{:db (assoc-in db [:hardwallet :setup-step] :recovery-phrase)}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/load-generating-mnemonic-screen
|
||||
(fn [cofx _]
|
||||
(hardwallet/load-generating-mnemonic-screen cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/pair
|
||||
(fn [cofx _]
|
||||
(hardwallet/pair cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/verify-pin
|
||||
(fn [cofx _]
|
||||
(hardwallet/verify-pin cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/change-pin
|
||||
(fn [cofx _]
|
||||
(hardwallet/change-pin cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/success-button-pressed
|
||||
(fn [cofx _]
|
||||
(hardwallet/success-button-pressed cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/pin-numpad-button-pressed
|
||||
(fn [cofx [_ number step]]
|
||||
(hardwallet/update-pin cofx number step)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/enter-pin-navigate-back-button-clicked
|
||||
(fn [cofx _]
|
||||
(hardwallet/enter-pin-navigate-back-button-clicked cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/hardwallet-connect-navigate-back-button-clicked
|
||||
(fn [cofx _]
|
||||
(hardwallet/hardwallet-connect-navigate-back-button-clicked cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/process-pin-input
|
||||
(fn [cofx _]
|
||||
(hardwallet/process-pin-input cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/pin-numpad-delete-button-pressed
|
||||
(fn [{:keys [db]} [_ step]]
|
||||
(when-not (empty? (get-in db [:hardwallet :pin step]))
|
||||
{:db (update-in db [:hardwallet :pin step] pop)})))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/card-ready-next-button-pressed
|
||||
(fn [cofx _]
|
||||
(hardwallet/card-ready-next-button-pressed cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/proceed-to-generate-mnemonic
|
||||
(fn [cofx _]
|
||||
(hardwallet/proceed-to-generate-mnemonic cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/generate-mnemonic
|
||||
(fn [cofx _]
|
||||
(hardwallet/generate-mnemonic cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/create-pin-button-pressed
|
||||
(fn [{:keys [db]} _]
|
||||
|
@ -898,76 +641,6 @@
|
|||
(assoc-in [:hardwallet :setup-step] :pin)
|
||||
(assoc-in [:hardwallet :pin :enter-step] :original))}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet.ui/error-button-pressed
|
||||
(fn [cofx _]
|
||||
(hardwallet/error-button-pressed cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:keycard-settings.ui/change-pin-pressed
|
||||
(fn [cofx _]
|
||||
(hardwallet/change-pin-pressed cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/proceed-to-change-pin
|
||||
(fn [cofx _]
|
||||
(hardwallet/proceed-to-change-pin cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:keycard-settings.ui/unpair-card-pressed
|
||||
(fn [cofx _]
|
||||
(hardwallet/unpair-card-pressed cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:keycard-settings.ui/unpair-card-confirmed
|
||||
(fn [cofx _]
|
||||
(hardwallet/unpair-card-confirmed cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/unpair
|
||||
(fn [cofx _]
|
||||
(hardwallet/unpair cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:keycard-settings.ui/reset-card-pressed
|
||||
(fn [cofx _]
|
||||
(hardwallet/reset-card-pressed cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:keycard-settings.ui/reset-card-next-button-pressed
|
||||
(fn [cofx _]
|
||||
(hardwallet/reset-card-next-button-pressed cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/proceed-to-reset-card
|
||||
(fn [cofx _]
|
||||
(hardwallet/proceed-to-reset-card cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/unpair-and-delete
|
||||
(fn [cofx _]
|
||||
(hardwallet/unpair-and-delete cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/remove-key-with-unpair
|
||||
(fn [cofx _]
|
||||
(hardwallet/remove-key-with-unpair cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/navigate-to-enter-pin-screen
|
||||
(fn [cofx _]
|
||||
(hardwallet/navigate-to-enter-pin-screen cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/navigate-to-reset-card-screen
|
||||
(fn [cofx _]
|
||||
(hardwallet/navigate-to-reset-card-screen cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:hardwallet/unblock-pin
|
||||
(fn [cofx _]
|
||||
(hardwallet/unblock-pin cofx)))
|
||||
|
||||
;; browser module
|
||||
|
||||
(handlers/register-handler-fx
|
||||
|
@ -1141,13 +814,6 @@
|
|||
(fn [cofx [_ chat-id]]
|
||||
(group-chats/join-chat cofx chat-id)))
|
||||
|
||||
;; profile module
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:profile.ui/keycard-settings-button-pressed
|
||||
(fn [cofx]
|
||||
(hardwallet/navigate-to-keycard-settings cofx)))
|
||||
|
||||
;; transport module
|
||||
|
||||
(handlers/register-handler-fx
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
(ns status-im.hardwallet.change-pin
|
||||
(:require [status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
[status-im.hardwallet.onboarding :as onboarding]
|
||||
[status-im.multiaccounts.logout.core :as multiaccounts.logout]
|
||||
[status-im.utils.fx :as fx]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.hardwallet.common :as common]))
|
||||
|
||||
(fx/defn change-pin-pressed
|
||||
{:events [:keycard-settings.ui/change-pin-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pin-retry-counter (get-in db [:hardwallet :application-info :pin-retry-counter])
|
||||
enter-step (if (zero? pin-retry-counter) :puk :current)]
|
||||
(fx/merge cofx
|
||||
{:db
|
||||
(assoc-in db [:hardwallet :pin] {:enter-step enter-step
|
||||
:current []
|
||||
:puk []
|
||||
:original []
|
||||
:confirmation []
|
||||
:status nil
|
||||
:error-label nil
|
||||
:on-verified :hardwallet/proceed-to-change-pin})}
|
||||
(common/navigate-to-enter-pin-screen))))
|
||||
|
||||
(fx/defn proceed-to-change-pin
|
||||
{:events [:hardwallet/proceed-to-change-pin]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :pin :enter-step] :original)
|
||||
(assoc-in [:hardwallet :pin :status] nil))}
|
||||
(navigation/navigate-to-cofx :enter-pin-settings nil)))
|
||||
|
||||
(fx/defn change-pin
|
||||
{:events [:hardwallet/change-pin]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pairing (common/get-pairing db)
|
||||
new-pin (common/vector->string (get-in db [:hardwallet :pin :original]))
|
||||
current-pin (common/vector->string (get-in db [:hardwallet :pin :current]))
|
||||
setup-step (get-in db [:hardwallet :setup-step])
|
||||
card-connected? (get-in db [:hardwallet :card-connected?])]
|
||||
(if (= setup-step :pin)
|
||||
(onboarding/load-preparing-screen cofx)
|
||||
(if card-connected?
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :pin :status] :verifying)
|
||||
:hardwallet/change-pin {:new-pin new-pin
|
||||
:current-pin current-pin
|
||||
:pairing pairing}})
|
||||
(fx/merge cofx
|
||||
(common/set-on-card-connected :hardwallet/change-pin)
|
||||
(navigation/navigate-to-cofx :hardwallet-connect nil))))))
|
||||
|
||||
(fx/defn on-change-pin-success
|
||||
{:events [:hardwallet.callback/on-change-pin-success]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pin (get-in db [:hardwallet :pin :original])]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :pin] {:status nil
|
||||
:login pin
|
||||
:confirmation []
|
||||
:error-label nil})
|
||||
:utils/show-popup {:title ""
|
||||
:content (i18n/label :t/pin-changed)}}
|
||||
(common/clear-on-card-connected)
|
||||
(when (:multiaccounts/login db)
|
||||
(navigation/navigate-to-cofx :keycard-login-pin nil))
|
||||
(when (:multiaccounts/login db)
|
||||
(common/get-keys-from-keycard))
|
||||
(when (:multiaccount/multiaccount db)
|
||||
(multiaccounts.logout/logout)))))
|
||||
|
||||
(fx/defn on-change-pin-error
|
||||
{:events [:hardwallet.callback/on-change-pin-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(log/debug "[hardwallet] change pin error" error)
|
||||
(let [tag-was-lost? (= "Tag was lost." (:error error))]
|
||||
(fx/merge cofx
|
||||
(if tag-was-lost?
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :pin :status] nil)
|
||||
:utils/show-popup {:title (i18n/label :t/error)
|
||||
:content (i18n/label :t/cannot-read-card)}}
|
||||
(common/set-on-card-connected :hardwallet/change-pin)
|
||||
(navigation/navigate-to-cofx :hardwallet-connect nil))
|
||||
(if (re-matches common/pin-mismatch-error (:error error))
|
||||
(fx/merge cofx
|
||||
{:db (update-in db [:hardwallet :pin] merge {:status :error
|
||||
:enter-step :current
|
||||
:puk []
|
||||
:current []
|
||||
:original []
|
||||
:confirmation []
|
||||
:sign []
|
||||
:error-label :t/pin-mismatch})}
|
||||
(navigation/navigate-to-cofx :enter-pin-settings nil)
|
||||
(common/get-application-info (common/get-pairing db) nil))
|
||||
(common/show-wrong-keycard-alert true))))))
|
|
@ -0,0 +1,385 @@
|
|||
(ns status-im.hardwallet.common
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.utils.types :as types]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.utils.keychain.core :as keychain]
|
||||
[status-im.hardwallet.nfc :as nfc]))
|
||||
|
||||
(def default-pin "000000")
|
||||
|
||||
(def pin-mismatch-error #"Unexpected error SW, 0x63C\d+")
|
||||
|
||||
(fx/defn dispatch-event
|
||||
[_ event]
|
||||
{:dispatch [event]})
|
||||
|
||||
(defn vector->string
|
||||
"Converts numbers stored in vector into string,
|
||||
e.g. [1 2 3 4 5 6] -> \"123456\""
|
||||
[v]
|
||||
(apply str v))
|
||||
|
||||
(defn hardwallet-supported? []
|
||||
(and config/hardwallet-enabled?
|
||||
platform/android?
|
||||
(nfc/nfc-supported?)))
|
||||
|
||||
(defn get-card-state
|
||||
[{:keys [has-master-key?
|
||||
applet-installed?
|
||||
initialized?
|
||||
free-pairing-slots
|
||||
paired?]}]
|
||||
(cond
|
||||
|
||||
(not applet-installed?)
|
||||
:blank
|
||||
|
||||
(not initialized?)
|
||||
:pre-init
|
||||
|
||||
(not has-master-key?)
|
||||
:init
|
||||
|
||||
has-master-key?
|
||||
:multiaccount
|
||||
|
||||
(and (not paired?)
|
||||
(zero? free-pairing-slots))
|
||||
:no-pairing-slots))
|
||||
|
||||
(defn- tag-lost? [error]
|
||||
(= error "Tag was lost."))
|
||||
|
||||
(defn find-multiaccount-by-keycard-instance-uid
|
||||
[db keycard-instance-uid]
|
||||
(when keycard-instance-uid
|
||||
(->> (:multiaccounts/multiaccounts db)
|
||||
vals
|
||||
(filter #(= keycard-instance-uid (:keycard-instance-uid %)))
|
||||
first)))
|
||||
|
||||
(defn find-multiaccount-by-key-uid
|
||||
[db key-uid]
|
||||
(when key-uid
|
||||
(->> (:multiaccounts/multiaccounts db)
|
||||
vals
|
||||
(filter #(= (ethereum/normalized-hex key-uid) (:key-uid %)))
|
||||
first)))
|
||||
|
||||
(defn get-pairing
|
||||
([db]
|
||||
(get-pairing db (get-in db [:hardwallet :application-info :key-uid])))
|
||||
([db key-uid]
|
||||
(or
|
||||
(get-in db [:multiaccount :keycard-pairing])
|
||||
(get-in db [:hardwallet :secrets :pairing])
|
||||
(when key-uid
|
||||
(:keycard-pairing
|
||||
(find-multiaccount-by-key-uid db key-uid))))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:hardwallet/set-nfc-supported
|
||||
(fn [supported?]
|
||||
(nfc/set-nfc-supported? supported?)))
|
||||
|
||||
(fx/defn listen-to-hardware-back-button
|
||||
[{:keys [db]}]
|
||||
(when-not (get-in db [:hardwallet :back-button-listener])
|
||||
{:hardwallet/listen-to-hardware-back-button nil}))
|
||||
|
||||
(fx/defn remove-listener-to-hardware-back-button
|
||||
[{:keys [db]}]
|
||||
(when-let [listener (get-in db [:hardwallet :back-button-listener])]
|
||||
{:hardwallet/remove-listener-to-hardware-back-button listener}))
|
||||
|
||||
(fx/defn set-on-card-connected
|
||||
[{:keys [db]} on-connect]
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :on-card-connected] on-connect)
|
||||
(assoc-in [:hardwallet :last-on-card-connected] nil))})
|
||||
|
||||
(fx/defn stash-on-card-connected
|
||||
[{:keys [db]}]
|
||||
(let [on-connect (get-in db [:hardwallet :on-card-connected])]
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :last-on-card-connected] on-connect)
|
||||
(assoc-in [:hardwallet :on-card-connected] nil))}))
|
||||
|
||||
(fx/defn restore-on-card-connected
|
||||
[{:keys [db]}]
|
||||
(let [on-connect (or
|
||||
(get-in db [:hardwallet :on-card-connected])
|
||||
(get-in db [:hardwallet :last-on-card-connected]))]
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :on-card-connected] on-connect)
|
||||
(assoc-in [:hardwallet :last-on-card-connect] nil))}))
|
||||
|
||||
(fx/defn clear-on-card-connected
|
||||
[{:keys [db]}]
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :on-card-connected] nil)
|
||||
(assoc-in [:hardwallet :last-on-card-connected] nil))})
|
||||
|
||||
(fx/defn set-on-card-read
|
||||
[{:keys [db]} on-connect]
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :on-card-read] on-connect)
|
||||
(assoc-in [:hardwallet :last-on-card-read] nil))})
|
||||
|
||||
(fx/defn stash-on-card-read
|
||||
[{:keys [db]}]
|
||||
(let [on-connect (get-in db [:hardwallet :on-card-read])]
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :last-on-card-read] on-connect)
|
||||
(assoc-in [:hardwallet :on-card-read] nil))}))
|
||||
|
||||
(fx/defn restore-on-card-read
|
||||
[{:keys [db]}]
|
||||
(let [on-connect (or
|
||||
(get-in db [:hardwallet :on-card-read])
|
||||
(get-in db [:hardwallet :last-on-card-read]))]
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :on-card-read] on-connect)
|
||||
(assoc-in [:hardwallet :last-on-card-connect] nil))}))
|
||||
|
||||
(fx/defn clear-on-card-read
|
||||
[{:keys [db]}]
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :on-card-read] nil)
|
||||
(assoc-in [:hardwallet :last-on-card-read] nil))})
|
||||
|
||||
(fx/defn on-add-listener-to-hardware-back-button
|
||||
"Adds listener to hardware back button on Android.
|
||||
During keycard setup we show user a warning that setup will be cancelled
|
||||
when back button pressed. This prevents user from going back during setup
|
||||
flow as some of the actions changing keycard step could not be repeated."
|
||||
{:events [:hardwallet/add-listener-to-hardware-back-button]}
|
||||
[{:keys [db]} listener]
|
||||
{:db (assoc-in db [:hardwallet :back-button-listener] listener)})
|
||||
|
||||
(fx/defn show-wrong-keycard-alert
|
||||
[_ card-connected?]
|
||||
(when card-connected?
|
||||
{:utils/show-popup {:title (i18n/label :t/wrong-card)
|
||||
:content (i18n/label :t/wrong-card-text)}}))
|
||||
|
||||
(fx/defn unauthorized-operation
|
||||
[{:keys [db] :as cofx}]
|
||||
(fx/merge cofx
|
||||
{:utils/show-popup {:title ""
|
||||
:content (i18n/label :t/keycard-unauthorized-operation)}}
|
||||
(clear-on-card-connected)
|
||||
(navigation/navigate-to-cofx :keycard-settings nil)))
|
||||
|
||||
(fx/defn navigate-to-enter-pin-screen
|
||||
{:events [:hardwallet/navigate-to-enter-pin-screen]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [key-uid (get-in db [:hardwallet :application-info :key-uid])
|
||||
multiaccount-key-uid (get-in db [:multiaccount :key-uid])
|
||||
keycard-multiaccount? (boolean (get-in db [:multiaccount :keycard-pairing]))]
|
||||
(if (or (nil? keycard-multiaccount?)
|
||||
(and key-uid
|
||||
(= key-uid multiaccount-key-uid)))
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :pin :current] [])}
|
||||
(navigation/navigate-to-cofx :enter-pin-settings nil))
|
||||
(unauthorized-operation cofx))))
|
||||
|
||||
(defn- tag-lost-exception? [code error]
|
||||
(or
|
||||
(= code "android.nfc.TagLostException")
|
||||
(= error "Tag was lost.")))
|
||||
|
||||
(fx/defn process-error [{:keys [db]} code error]
|
||||
(when-not (tag-lost-exception? code error)
|
||||
{:db (assoc-in db [:hardwallet :setup-step] :error)}))
|
||||
|
||||
(fx/defn get-keys-from-keycard
|
||||
[{:keys [db]}]
|
||||
(let [key-uid (get-in db [:multiaccounts/login :key-uid])
|
||||
pairing (get-in db [:multiaccounts/multiaccounts key-uid :keycard-pairing])
|
||||
pin (string/join (get-in db [:hardwallet :pin :login]))]
|
||||
(when (and pairing
|
||||
(seq pin))
|
||||
{:db (assoc-in db [:hardwallet :pin :status] :verifying)
|
||||
:hardwallet/get-keys {:pairing pairing
|
||||
:pin pin}})))
|
||||
|
||||
(fx/defn on-get-keys-success
|
||||
{:events [:hardwallet.callback/on-get-keys-success]}
|
||||
[{:keys [db] :as cofx} data]
|
||||
(let [{:keys [key-uid encryption-public-key whisper-private-key] :as account-data} (js->clj data :keywordize-keys true)
|
||||
{:keys [photo-path name]} (get-in db [:multiaccounts/multiaccounts key-uid])
|
||||
key-uid (get-in db [:hardwallet :application-info :key-uid])
|
||||
multiaccount-data (types/clj->json {:name name
|
||||
:key-uid key-uid
|
||||
:photo-path photo-path})
|
||||
save-keys? (get-in db [:multiaccounts/login :save-password?])]
|
||||
(fx/merge
|
||||
cofx
|
||||
{:db
|
||||
(-> db
|
||||
(assoc-in [:hardwallet :pin :status] nil)
|
||||
(assoc-in [:hardwallet :pin :login] [])
|
||||
(assoc-in [:hardwallet :multiaccount]
|
||||
(update account-data :whisper-public-key ethereum/normalized-hex))
|
||||
(assoc-in [:hardwallet :flow] nil)
|
||||
(update :multiaccounts/login assoc
|
||||
:password encryption-public-key
|
||||
:key-uid key-uid
|
||||
:photo-path photo-path
|
||||
:name name))
|
||||
|
||||
:hardwallet/get-application-info {:pairing (get-pairing db key-uid)}
|
||||
:hardwallet/login-with-keycard {:multiaccount-data multiaccount-data
|
||||
:password encryption-public-key
|
||||
:chat-key whisper-private-key}}
|
||||
(when save-keys?
|
||||
(keychain/save-hardwallet-keys key-uid encryption-public-key whisper-private-key))
|
||||
(clear-on-card-connected)
|
||||
(clear-on-card-read))))
|
||||
|
||||
(fx/defn on-get-keys-error
|
||||
{:events [:hardwallet.callback/on-get-keys-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(log/debug "[hardwallet] get keys error: " error)
|
||||
(let [tag-was-lost? (= "Tag was lost." (:error error))
|
||||
key-uid (get-in db [:hardwallet :application-info :key-uid])
|
||||
flow (get-in db [:hardwallet :flow])]
|
||||
(if tag-was-lost?
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :pin :status] nil)}
|
||||
(navigation/navigate-to-cofx :keycard-connection-lost nil))
|
||||
(if (re-matches pin-mismatch-error (:error error))
|
||||
(fx/merge cofx
|
||||
{:hardwallet/get-application-info {:pairing (get-pairing db key-uid)}
|
||||
:db (update-in db [:hardwallet :pin] merge {:status :error
|
||||
:login []
|
||||
:import-multiaccount []
|
||||
:error-label :t/pin-mismatch})}
|
||||
(if (= flow :import)
|
||||
(navigation/navigate-to-cofx :keycard-recovery-pin nil)
|
||||
(navigation/navigate-to-cofx :keycard-login-pin nil)))
|
||||
(show-wrong-keycard-alert true)))))
|
||||
|
||||
;; Get application info
|
||||
|
||||
(fx/defn get-application-info
|
||||
{:events [:hardwallet/get-application-info]}
|
||||
[{:keys [db]} pairing on-card-read]
|
||||
(let [key-uid (get-in db [:hardwallet :application-info :key-uid])
|
||||
pairing' (or pairing
|
||||
(when key-uid
|
||||
(get-pairing db key-uid)))]
|
||||
{:hardwallet/get-application-info {:pairing pairing'
|
||||
:on-success on-card-read}}))
|
||||
|
||||
(fx/defn on-get-application-info-success
|
||||
{:events [:hardwallet.callback/on-get-application-info-success]}
|
||||
[{:keys [db] :as cofx} info on-success]
|
||||
(let [info' (-> info
|
||||
(js->clj :keywordize-keys true)
|
||||
(update :key-uid ethereum/normalized-hex))
|
||||
{:keys [pin-retry-counter puk-retry-counter]} info'
|
||||
view-id (:view-id db)
|
||||
connect-screen? (contains? #{:hardwallet-connect
|
||||
:hardwallet-connect-sign
|
||||
:hardwallet-connect-settings} view-id)
|
||||
{:keys [on-card-read]} (:hardwallet db)
|
||||
on-success' (or on-success on-card-read)
|
||||
enter-step (if (zero? pin-retry-counter)
|
||||
:puk
|
||||
(get-in db [:hardwallet :pin :enter-step]))]
|
||||
(log/debug "[hardwallet] on-get-application-info-success"
|
||||
"connect-screen?" connect-screen?
|
||||
"on-success" on-success')
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :pin :enter-step] enter-step)
|
||||
(update-in [:hardwallet :pin :error-label] #(if (= :puk enter-step)
|
||||
:t/enter-puk-code-description
|
||||
%))
|
||||
(assoc-in [:hardwallet :application-info] info')
|
||||
(assoc-in [:hardwallet :application-info :applet-installed?] true)
|
||||
(assoc-in [:hardwallet :application-info-error] nil))}
|
||||
(stash-on-card-read)
|
||||
(if (zero? puk-retry-counter)
|
||||
{:utils/show-popup {:title (i18n/label :t/error)
|
||||
:content (i18n/label :t/keycard-blocked)}}
|
||||
(when on-success'
|
||||
(dispatch-event on-success'))))))
|
||||
|
||||
(fx/defn on-get-application-info-error
|
||||
{:events [:hardwallet.callback/on-get-application-info-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(log/debug "[hardwallet] application info error " error)
|
||||
(let [on-card-read (get-in db [:hardwallet :on-card-read])
|
||||
on-card-connected (get-in db [:hardwallet :on-card-connected])
|
||||
connect-screen? (= (:view-id db) :hardwallet-connect)
|
||||
login? (= on-card-read :hardwallet/login-with-keycard)
|
||||
tag-was-lost? (= "Tag was lost." (:error error))]
|
||||
(if tag-was-lost?
|
||||
(navigation/navigate-to-cofx cofx :keycard-connection-lost nil)
|
||||
(if login?
|
||||
(fx/merge cofx
|
||||
(clear-on-card-read)
|
||||
(navigation/navigate-to-cofx :not-keycard nil))
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :application-info-error] error)}
|
||||
(when (= on-card-connected :hardwallet/prepare-to-sign)
|
||||
(show-wrong-keycard-alert true))
|
||||
(when-not connect-screen?
|
||||
(clear-on-card-read))
|
||||
(when on-card-read
|
||||
(dispatch-event on-card-read)))))))
|
||||
|
||||
(fx/defn on-card-connected
|
||||
{:events [:hardwallet.callback/on-card-connected]}
|
||||
[{:keys [db] :as cofx} _]
|
||||
(log/debug "[hardwallet] card connected")
|
||||
(let [instance-uid (get-in db [:hardwallet :application-info :instance-uid])
|
||||
key-uid (get-in db [:hardwallet :application-info :key-uid])
|
||||
accounts-screen? (= :multiaccounts (:view-id db))
|
||||
should-read-instance-uid? (nil? instance-uid)
|
||||
on-card-connected (get-in db [:hardwallet :on-card-connected])
|
||||
on-card-read (cond
|
||||
should-read-instance-uid? :hardwallet/get-application-info
|
||||
:else (get-in db [:hardwallet :on-card-read]))
|
||||
pairing (get-pairing db key-uid)]
|
||||
(log/debug "[hardwallet] on-card-connected"
|
||||
"on-card-connected" on-card-connected
|
||||
"on-card-read" on-card-read)
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :card-connected?] true)
|
||||
(assoc-in [:hardwallet :card-read-in-progress?] (boolean on-card-read)))}
|
||||
(when on-card-connected
|
||||
(dispatch-event on-card-connected))
|
||||
(stash-on-card-connected)
|
||||
(when (and on-card-read
|
||||
(nil? on-card-connected))
|
||||
(get-application-info pairing on-card-read)))))
|
||||
|
||||
(fx/defn on-card-disconnected
|
||||
{:events [:hardwallet.callback/on-card-disconnected]}
|
||||
[{:keys [db] :as cofx} _]
|
||||
(log/debug "[hardwallet] card disconnected ")
|
||||
(let [setup-running? (get-in db [:hardwallet :setup-step])
|
||||
on-card-connected (get-in db [:hardwallet :on-card-connected])]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :card-connected?] false)
|
||||
(assoc-in [:hardwallet :card-read-in-progress?] false))}
|
||||
(restore-on-card-connected)
|
||||
(restore-on-card-read)
|
||||
(when (and setup-running?
|
||||
on-card-connected)
|
||||
(navigation/navigate-to-cofx :keycard-connection-lost-setup nil)))))
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,79 @@
|
|||
(ns status-im.hardwallet.delete-key
|
||||
(:require [status-im.multiaccounts.logout.core :as multiaccounts.logout]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
[status-im.utils.fx :as fx]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.hardwallet.common :as common]))
|
||||
|
||||
(fx/defn on-delete-success
|
||||
{:events [:hardwallet.callback/on-delete-success]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [key-uid (get-in db [:multiaccount :key-uid])]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(update :multiaccounts/multiaccounts dissoc key-uid)
|
||||
(assoc-in [:hardwallet :secrets] nil)
|
||||
(assoc-in [:hardwallet :application-info] nil)
|
||||
(assoc-in [:hardwallet :pin] {:status nil
|
||||
:error-label nil
|
||||
:on-verified nil}))
|
||||
;;FIXME delete multiaccount
|
||||
:utils/show-popup {:title ""
|
||||
:content (i18n/label :t/card-reseted)}}
|
||||
(common/clear-on-card-connected)
|
||||
(multiaccounts.logout/logout))))
|
||||
|
||||
(fx/defn on-delete-error
|
||||
{:events [:hardwallet.callback/on-delete-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(log/debug "[hardwallet] delete error" error)
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :pin] {:status nil
|
||||
:error-label nil
|
||||
:on-verified nil})
|
||||
:hardwallet/get-application-info nil
|
||||
:utils/show-popup {:title ""
|
||||
:content (i18n/label :t/something-went-wrong)}}
|
||||
(common/clear-on-card-connected)
|
||||
(navigation/navigate-to-cofx :keycard-settings nil)))
|
||||
|
||||
(fx/defn reset-card-pressed
|
||||
{:events [:keycard-settings.ui/reset-card-pressed]}
|
||||
[cofx]
|
||||
(navigation/navigate-to-cofx cofx :reset-card nil))
|
||||
|
||||
(fx/defn delete-card
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [key-uid (get-in db [:hardwallet :application-info :key-uid])
|
||||
multiaccount-key-uid (get-in db [:multiaccount :key-uid])]
|
||||
(if (and key-uid
|
||||
(= key-uid multiaccount-key-uid))
|
||||
{:hardwallet/delete nil}
|
||||
(common/unauthorized-operation cofx))))
|
||||
|
||||
(fx/defn navigate-to-reset-card-screen
|
||||
{:events [:hardwallet/navigate-to-reset-card-screen]}
|
||||
[cofx]
|
||||
(navigation/navigate-to-cofx cofx :reset-card nil))
|
||||
|
||||
(fx/defn reset-card-next-button-pressed
|
||||
{:events [:keycard-settings.ui/reset-card-next-button-pressed]}
|
||||
[{:keys [db]}]
|
||||
{:db (assoc-in db [:hardwallet :reset-card :disabled?] true)
|
||||
:dispatch [:hardwallet/proceed-to-reset-card]})
|
||||
|
||||
(fx/defn proceed-to-reset-card
|
||||
{:events [:hardwallet/proceed-to-reset-card]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pin-retry-counter (get-in db [:hardwallet :application-info :pin-retry-counter])
|
||||
enter-step (if (zero? pin-retry-counter) :puk :current)]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :pin] {:enter-step enter-step
|
||||
:current []
|
||||
:puk []
|
||||
:status nil
|
||||
:error-label nil
|
||||
:on-verified :hardwallet/remove-key-with-unpair})}
|
||||
(common/set-on-card-connected :hardwallet/navigate-to-enter-pin-screen)
|
||||
(common/navigate-to-enter-pin-screen))))
|
|
@ -0,0 +1,45 @@
|
|||
(ns status-im.hardwallet.export-key
|
||||
(:require [status-im.utils.fx :as fx]
|
||||
[re-frame.core :as re-frame]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
[status-im.hardwallet.common :as common]))
|
||||
|
||||
(fx/defn on-export-key-error
|
||||
{:events [:hardwallet.callback/on-export-key-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(log/debug "[hardwallet] export key error" error)
|
||||
(let [tag-was-lost? (= "Tag was lost." (:error error))]
|
||||
(cond tag-was-lost?
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :pin :status] nil)
|
||||
:utils/show-popup {:title (i18n/label :t/error)
|
||||
:content (i18n/label :t/cannot-read-card)}}
|
||||
(common/set-on-card-connected :wallet.accounts/generate-new-keycard-account)
|
||||
(navigation/navigate-to-cofx :keycard-connection-lost nil))
|
||||
(re-matches common/pin-mismatch-error (:error error))
|
||||
(fx/merge cofx
|
||||
{:db (update-in db [:hardwallet :pin] merge {:status :error
|
||||
:enter-step :export-key
|
||||
:puk []
|
||||
:current []
|
||||
:original []
|
||||
:confirmation []
|
||||
:sign []
|
||||
:error-label :t/pin-mismatch})}
|
||||
(navigation/navigate-back)
|
||||
(common/get-application-info (common/get-pairing db) nil))
|
||||
:else (common/show-wrong-keycard-alert cofx true))))
|
||||
|
||||
(fx/defn on-export-key-success
|
||||
{:events [:hardwallet.callback/on-export-key-success]}
|
||||
[{:keys [db] :as cofx} pubkey]
|
||||
(let [multiaccount-address (get-in db [:multiaccount :address])
|
||||
instance-uid (get-in db [:hardwallet :application-info :instance-uid])
|
||||
callback-fn (get-in db [:hardwallet :on-export-success])
|
||||
pairings (get-in db [:hardwallet :pairings])
|
||||
event-to-dispatch (callback-fn pubkey)]
|
||||
(re-frame/dispatch event-to-dispatch)
|
||||
(fx/merge cofx
|
||||
(common/clear-on-card-connected))))
|
|
@ -118,6 +118,7 @@
|
|||
(then #(re-frame/dispatch [:hardwallet.callback/on-retrieve-pairings-success
|
||||
(types/deserialize %)]))))))
|
||||
|
||||
;; TODO: Should act differently on different views
|
||||
(re-frame/reg-fx
|
||||
:hardwallet/listen-to-hardware-back-button
|
||||
;;NOTE: not done in view because effect should happen under different conditions and is not dependent on
|
||||
|
@ -133,3 +134,12 @@
|
|||
:hardwallet/remove-listener-to-hardware-back-button
|
||||
(fn [listener]
|
||||
(.remove listener)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:hardwallet/generate-name-and-photo
|
||||
(fn [{:keys [public-key on-success]}]
|
||||
(status/gfycat-identicon-async
|
||||
public-key
|
||||
(fn [whisper-name photo-path]
|
||||
(re-frame/dispatch
|
||||
[on-success whisper-name photo-path])))))
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
(ns status-im.hardwallet.login
|
||||
(:require [status-im.ethereum.core :as ethereum]
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.utils.types :as types]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.hardwallet.common :as common]
|
||||
[status-im.hardwallet.recovery :as recovery]
|
||||
[status-im.hardwallet.onboarding :as onboarding]
|
||||
status-im.hardwallet.fx
|
||||
[status-im.ui.components.bottom-sheet.core :as bottom-sheet]))
|
||||
|
||||
(fx/defn login-got-it-pressed
|
||||
{:events [:keycard.login.ui/got-it-pressed
|
||||
:keycard.login.ui/dismiss-pressed
|
||||
:keycard.login.pin.ui/cancel-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(fx/merge cofx
|
||||
{:db db}
|
||||
(navigation/navigate-to-cofx :multiaccounts nil)))
|
||||
|
||||
(fx/defn login-pin-more-icon-pressed
|
||||
{:events [:keycard.login.pin.ui/more-icon-pressed]}
|
||||
[cofx]
|
||||
(bottom-sheet/show-bottom-sheet cofx {:view :keycard.login/more}))
|
||||
|
||||
(fx/defn login-create-key-pressed
|
||||
{:events [:keycard.login.ui/create-new-key-pressed]}
|
||||
[cofx]
|
||||
(fx/merge cofx
|
||||
(bottom-sheet/hide-bottom-sheet)
|
||||
(onboarding/start-onboarding-flow)))
|
||||
|
||||
(fx/defn login-add-key-pressed
|
||||
{:events [:keycard.login.ui/add-key-pressed]}
|
||||
[cofx]
|
||||
(recovery/start-import-flow cofx))
|
||||
|
||||
(fx/defn login-remember-me-changed
|
||||
{:events [:keycard.login.ui/remember-me-changed]}
|
||||
[{:keys [db] :as cofx} value]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :remember-me?] value)}))
|
||||
|
||||
(fx/defn login-pair-card-pressed
|
||||
{:events [:keycard.login.ui/pair-card-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(log/debug "[hardwallet] load-pair-card-pressed")
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :flow] :login)}
|
||||
(navigation/navigate-to-cofx :keycard-recovery-pair nil)))
|
||||
|
||||
(fx/defn login-with-keycard
|
||||
{:events [:hardwallet/login-with-keycard]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [application-info (get-in db [:hardwallet :application-info])
|
||||
key-uid (get-in db [:hardwallet :application-info :key-uid])
|
||||
multiaccount (get-in db [:multiaccounts/multiaccounts (get-in db [:multiaccounts/login :key-uid])])
|
||||
multiaccount-key-uid (get multiaccount :key-uid)
|
||||
multiaccount-mismatch? (or (nil? multiaccount)
|
||||
(not= multiaccount-key-uid key-uid))
|
||||
pairing (:keycard-pairing multiaccount)]
|
||||
(cond
|
||||
(empty? application-info)
|
||||
(navigation/navigate-to-cofx cofx :not-keycard nil)
|
||||
|
||||
(empty? key-uid)
|
||||
(navigation/navigate-to-cofx cofx :keycard-blank nil)
|
||||
|
||||
multiaccount-mismatch?
|
||||
(navigation/navigate-to-cofx cofx :keycard-wrong nil)
|
||||
|
||||
(empty? pairing)
|
||||
(navigation/navigate-to-cofx cofx :keycard-unpaired nil)
|
||||
|
||||
:else
|
||||
(common/get-keys-from-keycard cofx))))
|
||||
|
||||
(fx/defn proceed-to-login
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{:keys [card-connected? nfc-enabled?]} (:hardwallet db)]
|
||||
(if nfc-enabled?
|
||||
(fx/merge cofx
|
||||
(common/set-on-card-connected :hardwallet/get-application-info)
|
||||
(common/set-on-card-read :hardwallet/login-with-keycard)
|
||||
(if card-connected?
|
||||
(login-with-keycard)
|
||||
(navigation/navigate-to-cofx :keycard-login-connect-card nil)))
|
||||
(navigation/navigate-to-cofx cofx :keycard-nfc-on nil))))
|
||||
|
||||
(fx/defn on-hardwallet-keychain-keys
|
||||
{:events [:multiaccounts.login.callback/get-hardwallet-keys-success]}
|
||||
[{:keys [db] :as cofx} key-uid [encryption-public-key whisper-private-key :as creds]]
|
||||
(if (nil? creds)
|
||||
(navigation/navigate-to-cofx cofx :keycard-login-pin nil)
|
||||
(let [{:keys [photo-path name]} (get-in db [:multiaccounts/multiaccounts key-uid])
|
||||
multiaccount-data (types/clj->json {:name name
|
||||
:key-uid key-uid
|
||||
:photo-path photo-path})
|
||||
account-data {:key-uid key-uid
|
||||
:encryption-public-key encryption-public-key
|
||||
:whisper-private-key whisper-private-key}]
|
||||
{:db
|
||||
(-> db
|
||||
(assoc-in [:hardwallet :pin :status] nil)
|
||||
(assoc-in [:hardwallet :pin :login] [])
|
||||
(assoc-in [:hardwallet :multiaccount]
|
||||
(update account-data :whisper-public-key ethereum/normalized-hex))
|
||||
(assoc-in [:hardwallet :flow] nil)
|
||||
(update :multiaccounts/login assoc
|
||||
:password encryption-public-key
|
||||
:key-uid key-uid
|
||||
:photo-path photo-path
|
||||
:name name
|
||||
:save-password? true))
|
||||
:hardwallet/login-with-keycard
|
||||
{:multiaccount-data multiaccount-data
|
||||
:password encryption-public-key
|
||||
:chat-key whisper-private-key}})))
|
||||
|
||||
(fx/defn on-login-success
|
||||
{:events [:keycard.login.callback/login-success]}
|
||||
[_ result]
|
||||
(log/debug "loginWithKeycard success: " result))
|
|
@ -0,0 +1,90 @@
|
|||
(ns status-im.hardwallet.mnemonic
|
||||
(:require [clojure.string :as string]
|
||||
[status-im.ethereum.mnemonic :as mnemonic]
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
[status-im.utils.fx :as fx]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.hardwallet.common :as common]
|
||||
status-im.hardwallet.fx))
|
||||
|
||||
(fx/defn on-generate-mnemonic-success
|
||||
{:events [:hardwallet.callback/on-generate-mnemonic-success]}
|
||||
[{:keys [db] :as cofx} mnemonic]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :setup-step] :recovery-phrase)
|
||||
(assoc-in [:hardwallet :secrets :mnemonic] mnemonic))}
|
||||
(common/clear-on-card-connected)
|
||||
(navigation/navigate-to-cofx :keycard-onboarding-recovery-phrase nil)))
|
||||
|
||||
(fx/defn set-mnemonic
|
||||
{:events [:test-mnemonic]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [selected-id (get-in db [:intro-wizard :selected-id])
|
||||
accounts (get-in db [:intro-wizard :multiaccounts])
|
||||
mnemonic (->> accounts
|
||||
(filter (fn [{:keys [id]}]
|
||||
(= id selected-id)))
|
||||
first
|
||||
:mnemonic)]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :secrets :mnemonic] mnemonic)}
|
||||
(on-generate-mnemonic-success mnemonic))))
|
||||
|
||||
(fx/defn generate-mnemonic
|
||||
{:events [:hardwallet/generate-mnemonic]}
|
||||
[cofx]
|
||||
(let [{:keys [pairing]} (get-in cofx [:db :hardwallet :secrets])]
|
||||
{:hardwallet/generate-mnemonic {:pairing pairing
|
||||
:words (string/join "\n" mnemonic/dictionary)}}))
|
||||
|
||||
(fx/defn proceed-with-generating-mnemonic
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pin (or (get-in db [:hardwallet :secrets :pin])
|
||||
(common/vector->string (get-in db [:hardwallet :pin :current])))]
|
||||
(if (empty? pin)
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :pin] {:enter-step :current
|
||||
:on-verified :hardwallet/generate-mnemonic
|
||||
:current []})}
|
||||
(navigation/navigate-to-cofx :keycard-onboarding-pin nil))
|
||||
(generate-mnemonic cofx))))
|
||||
|
||||
(fx/defn load-generating-mnemonic-screen
|
||||
{:events [:hardwallet/load-generating-mnemonic-screen]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [card-connected? (get-in db [:hardwallet :card-connected?])]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :setup-step] :generating-mnemonic)}
|
||||
(common/set-on-card-connected :hardwallet/load-generating-mnemonic-screen)
|
||||
(if card-connected?
|
||||
(common/dispatch-event :hardwallet/generate-mnemonic)
|
||||
(navigation/navigate-to-cofx :hardwallet-connect nil)))))
|
||||
|
||||
(fx/defn on-generate-mnemonic-error
|
||||
{:events [:hardwallet.callback/on-generate-mnemonic-error]}
|
||||
[{:keys [db] :as cofx} {:keys [error code]}]
|
||||
(log/debug "[hardwallet] generate mnemonic error: " error)
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :setup-error] error)}
|
||||
(common/set-on-card-connected :hardwallet/load-generating-mnemonic-screen)
|
||||
(common/process-error code error)))
|
||||
|
||||
(fx/defn proceed-to-generate-mnemonic
|
||||
{:events [:hardwallet/proceed-to-generate-mnemonic]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(if (= (get-in db [:hardwallet :flow]) :create)
|
||||
(load-generating-mnemonic-screen cofx)
|
||||
{:db (assoc-in db [:hardwallet :setup-step] :recovery-phrase)}))
|
||||
|
||||
(fx/defn load-loading-keys-screen
|
||||
{:events [:hardwallet.ui/recovery-phrase-confirm-pressed
|
||||
:hardwallet/load-loading-keys-screen]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [card-connected? (get-in db [:hardwallet :card-connected?])]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :setup-step] :loading-keys)}
|
||||
(common/set-on-card-connected :hardwallet/load-loading-keys-screen)
|
||||
(if card-connected?
|
||||
(common/dispatch-event :hardwallet/generate-and-load-key)
|
||||
(navigation/navigate-to-cofx :hardwallet-connect nil)))))
|
|
@ -0,0 +1,335 @@
|
|||
(ns status-im.hardwallet.onboarding
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.hardwallet.common :as common]
|
||||
[status-im.hardwallet.mnemonic :as mnemonic]
|
||||
[taoensso.timbre :as log]
|
||||
status-im.hardwallet.fx
|
||||
[status-im.ui.components.react :as react]))
|
||||
|
||||
(fx/defn begin-setup-button-pressed
|
||||
{:keys [:hardwallet.ui/begin-setup-button-pressed]}
|
||||
[{:keys [db]}]
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :setup-step] :pin)
|
||||
(assoc-in [:hardwallet :pin :enter-step] :original)
|
||||
(assoc-in [:hardwallet :pin :original] [])
|
||||
(assoc-in [:hardwallet :pin :confirmation] []))})
|
||||
|
||||
(fx/defn start-installation
|
||||
{:events [:hardwallet/start-installation]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [card-state (get-in db [:hardwallet :card-state])
|
||||
pin (common/vector->string (get-in db [:hardwallet :pin :original]))]
|
||||
(case card-state
|
||||
|
||||
:pre-init
|
||||
{:hardwallet/init-card pin}
|
||||
|
||||
(do
|
||||
(log/debug (str "Cannot start keycard installation from state: " card-state))
|
||||
(fx/merge cofx
|
||||
{:utils/show-popup {:title (i18n/label :t/error)
|
||||
:content (i18n/label :t/something-went-wrong)}}
|
||||
(navigation/navigate-to-cofx :hardwallet-authentication-method nil))))))
|
||||
|
||||
(fx/defn load-preparing-screen
|
||||
{:events [:hardwallet/load-preparing-screen]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [card-connected? (get-in db [:hardwallet :card-connected?])]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :setup-step] :preparing)}
|
||||
(common/set-on-card-connected :hardwallet/load-preparing-screen)
|
||||
(when card-connected?
|
||||
(navigation/navigate-to-cofx :keycard-onboarding-preparing nil))
|
||||
(if card-connected?
|
||||
(common/dispatch-event :hardwallet/start-installation)
|
||||
(navigation/navigate-to-cofx :keycard-connection-lost-setup nil)))))
|
||||
|
||||
(fx/defn load-pairing-screen
|
||||
{:events [:hardwallet/load-pairing-screen
|
||||
:keycard.onboarding.puk-code.ui/confirm-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [card-connected? (get-in db [:hardwallet :card-connected?])]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :setup-step] :pairing)}
|
||||
(common/set-on-card-connected :hardwallet/load-pairing-screen)
|
||||
(when card-connected?
|
||||
(navigation/navigate-to-cofx :keycard-pairing nil))
|
||||
(if card-connected?
|
||||
(common/dispatch-event :hardwallet/pair)
|
||||
(navigation/navigate-to-cofx :keycard-connection-lost-setup nil)))))
|
||||
|
||||
(fx/defn puk-code-next-pressed
|
||||
{:events [:keycard.onboarding.puk-code.ui/next-pressed]}
|
||||
[_]
|
||||
{:ui/show-confirmation {:title (i18n/label :t/secret-keys-confirmation-title)
|
||||
:content (i18n/label :t/secret-keys-confirmation-text)
|
||||
:confirm-button-text (i18n/label :t/yes)
|
||||
:cancel-button-text (i18n/label :t/cancel)
|
||||
:on-accept #(re-frame/dispatch [:keycard.onboarding.puk-code.ui/confirm-pressed])
|
||||
:on-cancel #()}})
|
||||
|
||||
(fx/defn load-finishing-screen
|
||||
{:events [:keycard.onboarding.recovery-phrase-confirm-word2.ui/next-pressed
|
||||
:hardwallet/load-finishing-screen]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [card-connected? (get-in db [:hardwallet :card-connected?])]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :setup-step] :loading-keys)}
|
||||
(common/set-on-card-connected :hardwallet/load-finishing-screen)
|
||||
(when card-connected?
|
||||
(navigation/navigate-to-cofx :keycard-onboarding-finishing nil))
|
||||
(if card-connected?
|
||||
(common/dispatch-event :hardwallet/generate-and-load-key)
|
||||
(navigation/navigate-to-cofx :keycard-connection-lost-setup nil)))))
|
||||
|
||||
(fx/defn recovery-phrase-learn-more-pressed
|
||||
{:events [:keycard.onboarding.recovery-phrase.ui/learn-more-pressed]}
|
||||
[_]
|
||||
(.openURL react/linking "https://keycard.status.im"))
|
||||
|
||||
(fx/defn recovery-phrase-next-pressed
|
||||
{:events [:keycard.onboarding.recovery-phrase.ui/next-pressed
|
||||
:hardwallet.ui/recovery-phrase-next-button-pressed]}
|
||||
[_]
|
||||
{:ui/show-confirmation {:title (i18n/label :t/keycard-recovery-phrase-confirmation-title)
|
||||
:content (i18n/label :t/keycard-recovery-phrase-confirmation-text)
|
||||
:confirm-button-text (i18n/label :t/yes)
|
||||
:cancel-button-text (i18n/label :t/cancel)
|
||||
:on-accept #(re-frame/dispatch [:keycard.onboarding.recovery-phrase.ui/confirm-pressed])
|
||||
:on-cancel #()}})
|
||||
|
||||
(fx/defn recovery-phrase-start-confirmation
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [mnemonic (get-in db [:hardwallet :secrets :mnemonic])
|
||||
[word1 word2] (shuffle (map-indexed vector (clojure.string/split mnemonic #" ")))
|
||||
word1 (zipmap [:idx :word] word1)
|
||||
word2 (zipmap [:idx :word] word2)]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :setup-step] :recovery-phrase-confirm-word1)
|
||||
(assoc-in [:hardwallet :recovery-phrase :step] :word1)
|
||||
(assoc-in [:hardwallet :recovery-phrase :confirm-error] nil)
|
||||
(assoc-in [:hardwallet :recovery-phrase :input-word] nil)
|
||||
(assoc-in [:hardwallet :recovery-phrase :word1] word1)
|
||||
(assoc-in [:hardwallet :recovery-phrase :word2] word2))}
|
||||
(common/remove-listener-to-hardware-back-button))))
|
||||
|
||||
(fx/defn recovery-phrase-confirm-pressed
|
||||
{:events [:keycard.onboarding.recovery-phrase.ui/confirm-pressed]}
|
||||
[cofx]
|
||||
(fx/merge cofx
|
||||
(recovery-phrase-start-confirmation)
|
||||
(navigation/navigate-to-cofx :keycard-onboarding-recovery-phrase-confirm-word1 nil)))
|
||||
|
||||
(fx/defn recovery-phrase-next-word
|
||||
[{:keys [db]}]
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :recovery-phrase :step] :word2)
|
||||
(assoc-in [:hardwallet :recovery-phrase :confirm-error] nil)
|
||||
(assoc-in [:hardwallet :recovery-phrase :input-word] nil)
|
||||
(assoc-in [:hardwallet :setup-step] :recovery-phrase-confirm-word2))})
|
||||
|
||||
(fx/defn recovery-phrase-confirm-word-back-pressed
|
||||
{:events [:keycard.onboarding.recovery-phrase-confirm-word.ui/back-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(if (= (:view-id db) :keycard-onboarding-recovery-phrase-confirm-word1)
|
||||
(navigation/navigate-to-cofx cofx :keycard-onboarding-recovery-phrase nil)
|
||||
(navigation/navigate-to-cofx cofx :keycard-onboarding-recovery-phrase-confirm-word1 nil)))
|
||||
|
||||
(fx/defn proceed-with-generating-key
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pin (get-in db [:hardwallet :secrets :pin]
|
||||
(common/vector->string (get-in db [:hardwallet :pin :current])))]
|
||||
(if (empty? pin)
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :pin] {:enter-step :current
|
||||
:on-verified :hardwallet/generate-and-load-key
|
||||
:current []})}
|
||||
(navigation/navigate-to-cofx :keycard-onboarding-pin nil))
|
||||
(load-finishing-screen cofx))))
|
||||
|
||||
(fx/defn recovery-phrase-confirm-word-next-pressed
|
||||
{:events [:keycard.onboarding.recovery-phrase-confirm-word.ui/next-pressed
|
||||
:keycard.onboarding.recovery-phrase-confirm-word.ui/input-submitted]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [step (get-in db [:hardwallet :recovery-phrase :step])
|
||||
input-word (get-in db [:hardwallet :recovery-phrase :input-word])
|
||||
{:keys [word]} (get-in db [:hardwallet :recovery-phrase step])]
|
||||
(if (= word input-word)
|
||||
(if (= (:view-id db) :keycard-onboarding-recovery-phrase-confirm-word1)
|
||||
(fx/merge cofx
|
||||
(recovery-phrase-next-word)
|
||||
(navigation/navigate-to-cofx :keycard-onboarding-recovery-phrase-confirm-word2 nil))
|
||||
(proceed-with-generating-key cofx))
|
||||
{:db (assoc-in db [:hardwallet :recovery-phrase :confirm-error] (i18n/label :t/wrong-word))})))
|
||||
|
||||
(fx/defn recovery-phrase-confirm-word-input-changed
|
||||
{:events [:keycard.onboarding.recovery-phrase-confirm-word.ui/input-changed]}
|
||||
[{:keys [db]} input]
|
||||
{:db (assoc-in db [:hardwallet :recovery-phrase :input-word] input)})
|
||||
|
||||
(fx/defn pair-code-input-changed
|
||||
{:events [:keycard.onboarding.pair.ui/input-changed]}
|
||||
[{:keys [db]} input]
|
||||
{:db (assoc-in db [:hardwallet :secrets :password] input)})
|
||||
|
||||
(fx/defn keycard-option-pressed
|
||||
{:events [:onboarding.ui/keycard-option-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [flow (get-in db [:hardwallet :flow])]
|
||||
(fx/merge cofx
|
||||
{:hardwallet/check-nfc-enabled nil}
|
||||
(if (= flow :import)
|
||||
(navigation/navigate-to-cofx :keycard-recovery-intro nil)
|
||||
(navigation/navigate-to-cofx :keycard-onboarding-intro nil)))))
|
||||
|
||||
(fx/defn start-onboarding-flow
|
||||
{:events [:keycard/start-onboarding-flow]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :flow] :create)
|
||||
:hardwallet/check-nfc-enabled nil}
|
||||
(navigation/navigate-to-cofx :keycard-onboarding-intro nil)))
|
||||
|
||||
(fx/defn open-nfc-settings-pressed
|
||||
{:events [:keycard.onboarding.nfc-on/open-nfc-settings-pressed]}
|
||||
[_]
|
||||
{:hardwallet/open-nfc-settings nil})
|
||||
|
||||
(defn- show-recover-confirmation []
|
||||
{:ui/show-confirmation {:title (i18n/label :t/are-you-sure?)
|
||||
:content (i18n/label :t/are-you-sure-description)
|
||||
:confirm-button-text (clojure.string/upper-case (i18n/label :t/yes))
|
||||
:cancel-button-text (i18n/label :t/see-it-again)
|
||||
:on-accept #(re-frame/dispatch [:hardwallet.ui/recovery-phrase-confirm-pressed])
|
||||
:on-cancel #(re-frame/dispatch [:hardwallet.ui/recovery-phrase-cancel-pressed])}})
|
||||
|
||||
(fx/defn recovery-phrase-confirm-word
|
||||
{:events [:hardwallet.ui/recovery-phrase-confirm-word-next-button-pressed]}
|
||||
[{:keys [db]}]
|
||||
(let [step (get-in db [:hardwallet :recovery-phrase :step])
|
||||
input-word (get-in db [:hardwallet :recovery-phrase :input-word])
|
||||
{:keys [word]} (get-in db [:hardwallet :recovery-phrase step])]
|
||||
(if (= word input-word)
|
||||
(if (= step :word1)
|
||||
(recovery-phrase-next-word db)
|
||||
(show-recover-confirmation))
|
||||
{:db (assoc-in db [:hardwallet :recovery-phrase :confirm-error] (i18n/label :t/wrong-word))})))
|
||||
|
||||
(fx/defn card-ready-next-button-pressed
|
||||
{:events [:hardwallet.ui/card-ready-next-button-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pin (get-in db [:hardwallet :secrets :pin])
|
||||
pin-already-set? (boolean pin)]
|
||||
(if pin-already-set?
|
||||
(if (= (get-in db [:hardwallet :flow]) :create)
|
||||
(mnemonic/load-generating-mnemonic-screen cofx)
|
||||
{:db (assoc-in db [:hardwallet :setup-step] :recovery-phrase)})
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :setup-step] :pin)
|
||||
(assoc-in [:hardwallet :pin :enter-step] :current)
|
||||
(assoc-in [:hardwallet :pin :on-verified] :hardwallet/proceed-to-generate-mnemonic)
|
||||
(assoc-in [:hardwallet :pin :current] [])
|
||||
(assoc-in [:hardwallet :pin :original] nil))}))))
|
||||
|
||||
(fx/defn recovery-phrase-next-button-pressed
|
||||
[{:keys [db] :as cofx}]
|
||||
(if (= (get-in db [:hardwallet :flow]) :create)
|
||||
(recovery-phrase-start-confirmation cofx)
|
||||
(let [mnemonic (get-in db [:multiaccounts/recover :passphrase])]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :secrets :mnemonic] mnemonic)}
|
||||
(mnemonic/load-loading-keys-screen)))))
|
||||
|
||||
(fx/defn on-install-applet-and-init-card-success
|
||||
{:events [:hardwallet.callback/on-install-applet-and-init-card-success
|
||||
:hardwallet.callback/on-init-card-success]}
|
||||
[{:keys [db] :as cofx} secrets]
|
||||
(let [secrets' (js->clj secrets :keywordize-keys true)]
|
||||
(fx/merge cofx
|
||||
{:hardwallet/get-application-info nil
|
||||
:db (-> db
|
||||
(assoc-in [:hardwallet :card-state] :init)
|
||||
(assoc-in [:hardwallet :setup-step] :secret-keys)
|
||||
(update-in [:hardwallet :secrets] merge secrets'))}
|
||||
(common/clear-on-card-connected)
|
||||
(common/listen-to-hardware-back-button)
|
||||
(navigation/navigate-to-cofx :keycard-onboarding-puk-code nil))))
|
||||
|
||||
(fx/defn on-install-applet-and-init-card-error
|
||||
{:events [:hardwallet.callback/on-install-applet-and-init-card-error
|
||||
:hardwallet.callback/on-init-card-error]}
|
||||
[{:keys [db] :as cofx} {:keys [code error]}]
|
||||
(log/debug "[hardwallet] install applet and init card error: " error)
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :setup-error] error)}
|
||||
(common/set-on-card-connected :hardwallet/load-preparing-screen)
|
||||
(common/process-error code error)))
|
||||
|
||||
(fx/defn generate-and-load-key
|
||||
{:events [:hardwallet/generate-and-load-key]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{:keys [mnemonic pairing pin]} (get-in db [:hardwallet :secrets])
|
||||
{:keys [selected-id multiaccounts]} (:intro-wizard db)
|
||||
user-selected-mnemonic (->> multiaccounts
|
||||
(filter #(= (:id %) selected-id))
|
||||
first
|
||||
:mnemonic)
|
||||
recovery-mnemonic (get-in db [:intro-wizard :passphrase])
|
||||
mnemonic' (or user-selected-mnemonic mnemonic recovery-mnemonic)
|
||||
pin' (or pin (common/vector->string (get-in db [:hardwallet :pin :current])))]
|
||||
(fx/merge cofx
|
||||
{:hardwallet/generate-and-load-key {:mnemonic mnemonic'
|
||||
:pairing pairing
|
||||
:pin pin'}}
|
||||
(navigation/navigate-to-cofx :keycard-onboarding-finishing nil))))
|
||||
|
||||
(fx/defn begin-setup-pressed
|
||||
{:events [:keycard.onboarding.intro.ui/begin-setup-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [nfc-enabled? (get-in db [:hardwallet :nfc-enabled?])
|
||||
flow (get-in db [:hardwallet :flow])]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(update :hardwallet
|
||||
dissoc :secrets :card-state :multiaccount-wallet-address
|
||||
:multiaccount-whisper-public-key
|
||||
:application-info)
|
||||
(assoc-in [:hardwallet :setup-step] :begin)
|
||||
(assoc-in [:hardwallet :pin :on-verified] nil))}
|
||||
(common/set-on-card-connected :hardwallet/get-application-info)
|
||||
(common/set-on-card-read :hardwallet/check-card-state)
|
||||
(if nfc-enabled?
|
||||
(if (= flow :import)
|
||||
(navigation/navigate-to-cofx :keycard-recovery-start nil)
|
||||
(navigation/navigate-to-cofx :keycard-onboarding-start nil))
|
||||
(navigation/navigate-to-cofx :keycard-nfc-on nil)))))
|
||||
|
||||
(fx/defn cancel-setup-pressed
|
||||
{:events [:keycard.onboarding.ui/cancel-pressed
|
||||
:hardwallet/back-button-pressed
|
||||
:keycard.onboarding.recovery-phrase.ui/cancel-pressed
|
||||
:keycard.onboarding.connection-lost-setup.ui/cancel-setup-pressed]}
|
||||
[_]
|
||||
{:ui/show-confirmation {:title (i18n/label :t/keycard-cancel-setup-title)
|
||||
:content (i18n/label :t/keycard-cancel-setup-text)
|
||||
:confirm-button-text (i18n/label :t/yes)
|
||||
:cancel-button-text (i18n/label :t/no)
|
||||
:on-accept #(re-frame/dispatch [:keycard.onboarding.ui/cancel-confirm-pressed])
|
||||
:on-cancel #()}})
|
||||
|
||||
(fx/defn cancel-setup-confirm-pressed
|
||||
{:events [:keycard.onboarding.ui/cancel-confirm-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(fx/merge cofx
|
||||
(common/remove-listener-to-hardware-back-button)
|
||||
(navigation/navigate-reset {:index 0
|
||||
:actions [{:routeName (if (seq (:multiaccounts/multiaccounts db))
|
||||
:multiaccounts
|
||||
:intro)}]})))
|
|
@ -0,0 +1,259 @@
|
|||
(ns status-im.hardwallet.recovery
|
||||
(:require [status-im.ui.screens.navigation :as navigation]
|
||||
[status-im.utils.datetime :as utils.datetime]
|
||||
[status-im.multiaccounts.create.core :as multiaccounts.create]
|
||||
[status-im.utils.fx :as fx]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.hardwallet.common :as common]
|
||||
status-im.hardwallet.fx
|
||||
[status-im.constants :as constants]
|
||||
[status-im.ethereum.eip55 :as eip55]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.ui.components.bottom-sheet.core :as bottom-sheet]))
|
||||
|
||||
(fx/defn pair* [_ password]
|
||||
{:hardwallet/pair {:password password}})
|
||||
|
||||
(fx/defn pair
|
||||
{:events [:hardwallet/pair]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{:keys [password]} (get-in cofx [:db :hardwallet :secrets])
|
||||
card-connected? (get-in db [:hardwallet :card-connected?])]
|
||||
(fx/merge cofx
|
||||
(common/set-on-card-connected :hardwallet/pair)
|
||||
(when card-connected?
|
||||
(pair* password))
|
||||
(if card-connected?
|
||||
(navigation/navigate-to-cofx :keycard-pairing nil)
|
||||
(navigation/navigate-to-cofx :keycard-connection-lost-setup nil)))))
|
||||
|
||||
(fx/defn pair-code-next-button-pressed
|
||||
{:events [:keycard.onboarding.pair.ui/input-submitted
|
||||
:hardwallet.ui/pair-code-next-button-pressed
|
||||
:keycard.onboarding.pair.ui/next-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pairing (get-in db [:hardwallet :secrets :pairing])
|
||||
paired-on (get-in db [:hardwallet :secrets :paired-on] (utils.datetime/timestamp))]
|
||||
(fx/merge cofx
|
||||
(if pairing
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :setup-step] :import-multiaccount)
|
||||
(assoc-in [:hardwallet :secrets :paired-on] paired-on))}
|
||||
(pair)))))
|
||||
|
||||
(fx/defn load-pair-screen
|
||||
[{:keys [db] :as cofx}]
|
||||
(log/debug "[hardwallet] load-pair-screen")
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :setup-step] :pair))
|
||||
:dispatch [:bottom-sheet/hide-sheet]}
|
||||
(common/listen-to-hardware-back-button)
|
||||
(navigation/navigate-to-cofx :keycard-recovery-pair nil)))
|
||||
|
||||
(fx/defn keycard-storage-selected-for-recovery
|
||||
{:events [:recovery.ui/keycard-storage-selected]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :flow] :recovery)}
|
||||
(navigation/navigate-to-cofx :keycard-recovery-enter-mnemonic nil)))
|
||||
|
||||
(fx/defn start-import-flow
|
||||
{:events [:hardwallet/recover-with-keycard-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :flow] :import)
|
||||
:hardwallet/check-nfc-enabled nil}
|
||||
(bottom-sheet/hide-bottom-sheet)
|
||||
(navigation/navigate-to-cofx :keycard-recovery-intro nil)))
|
||||
|
||||
(fx/defn access-key-pressed
|
||||
{:events [:multiaccounts.recover.ui/recover-multiaccount-button-pressed]}
|
||||
[_]
|
||||
{:dispatch [:bottom-sheet/show-sheet :recover-sheet]})
|
||||
|
||||
(fx/defn recovery-keycard-selected
|
||||
{:events [:recovery.ui/keycard-option-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :flow] :recovery)
|
||||
:hardwallet/check-nfc-enabled nil}
|
||||
(navigation/navigate-to-cofx :keycard-onboarding-intro nil)))
|
||||
|
||||
(fx/defn begin-setup-pressed
|
||||
{:events [:keycard.recovery.intro.ui/begin-recovery-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [nfc-enabled? (get-in db [:hardwallet :nfc-enabled?])
|
||||
flow (get-in db [:hardwallet :flow])]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(update :hardwallet
|
||||
dissoc :secrets :card-state :multiaccount-wallet-address
|
||||
:multiaccount-whisper-public-key
|
||||
:application-info)
|
||||
(assoc-in [:hardwallet :setup-step] :begin)
|
||||
(assoc-in [:hardwallet :pin :on-verified] nil))}
|
||||
(common/set-on-card-connected :hardwallet/get-application-info)
|
||||
(common/set-on-card-read :hardwallet/check-card-state)
|
||||
(if nfc-enabled?
|
||||
(if (= flow :import)
|
||||
(navigation/navigate-to-cofx :keycard-recovery-start nil)
|
||||
(navigation/navigate-to-cofx :keycard-onboarding-start nil))
|
||||
(navigation/navigate-to-cofx :keycard-nfc-on nil)))))
|
||||
|
||||
(fx/defn recovery-success-finish-pressed
|
||||
{:events [:keycard.recovery.success/finish-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(fx/merge cofx
|
||||
{:db (update db :hardwallet dissoc
|
||||
:multiaccount-wallet-address
|
||||
:multiaccount-whisper-public-key)}
|
||||
(navigation/navigate-to-cofx :welcome nil)))
|
||||
|
||||
(fx/defn recovery-no-key
|
||||
{:events [:keycard.recovery.no-key.ui/generate-key-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :flow] :create)
|
||||
:hardwallet/check-nfc-enabled nil}
|
||||
(multiaccounts.create/intro-wizard)))
|
||||
|
||||
(fx/defn create-keycard-multiaccount
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{{:keys [multiaccount secrets flow]} :hardwallet} db
|
||||
{:keys [address
|
||||
name
|
||||
photo-path
|
||||
public-key
|
||||
whisper-public-key
|
||||
wallet-public-key
|
||||
wallet-root-public-key
|
||||
whisper-address
|
||||
wallet-address
|
||||
wallet-root-address
|
||||
whisper-private-key
|
||||
encryption-public-key
|
||||
instance-uid
|
||||
key-uid]} multiaccount
|
||||
{:keys [pairing paired-on]} secrets
|
||||
{:keys [name photo-path]}
|
||||
(if (nil? name)
|
||||
;; name might have been generated during recovery via passphrase
|
||||
(get-in db [:intro-wizard :derived constants/path-whisper-keyword])
|
||||
{:name name
|
||||
:photo-path photo-path})]
|
||||
;; if a name is still `nil` we have to generate it before multiaccount's
|
||||
;; creation otherwise spec validation will fail
|
||||
(if (nil? name)
|
||||
{::generate-name-and-photo whisper-public-key}
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :setup-step] nil)
|
||||
(assoc :intro-wizard nil))}
|
||||
(multiaccounts.create/on-multiaccount-created
|
||||
{:derived {constants/path-wallet-root-keyword
|
||||
{:public-key wallet-root-public-key
|
||||
:address (eip55/address->checksum wallet-root-address)}
|
||||
constants/path-whisper-keyword
|
||||
{:public-key whisper-public-key
|
||||
:address (eip55/address->checksum whisper-address)
|
||||
:name name
|
||||
:photo-path photo-path}
|
||||
constants/path-default-wallet-keyword
|
||||
{:public-key wallet-public-key
|
||||
:address (eip55/address->checksum wallet-address)}}
|
||||
:address address
|
||||
:public-key public-key
|
||||
:keycard-instance-uid instance-uid
|
||||
:key-uid (ethereum/normalized-hex key-uid)
|
||||
:keycard-pairing pairing
|
||||
:keycard-paired-on paired-on
|
||||
:chat-key whisper-private-key}
|
||||
encryption-public-key
|
||||
{})
|
||||
(if (= flow :import)
|
||||
(navigation/navigate-to-cofx :keycard-recovery-success nil)
|
||||
(navigation/navigate-to-cofx :welcome nil))))))
|
||||
|
||||
(fx/defn on-generate-and-load-key-success
|
||||
{:events [:hardwallet.callback/on-generate-and-load-key-success]
|
||||
:interceptors [(re-frame/inject-cofx :random-guid-generator)
|
||||
(re-frame/inject-cofx ::multiaccounts.create/get-signing-phrase)]}
|
||||
[{:keys [db random-guid-generator] :as cofx} data]
|
||||
(let [account-data (js->clj data :keywordize-keys true)]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :multiaccount]
|
||||
(-> account-data
|
||||
(update :address ethereum/normalized-hex)
|
||||
(update :whisper-address ethereum/normalized-hex)
|
||||
(update :wallet-address ethereum/normalized-hex)
|
||||
(update :wallet-root-address ethereum/normalized-hex)
|
||||
(update :public-key ethereum/normalized-hex)
|
||||
(update :whisper-public-key ethereum/normalized-hex)
|
||||
(update :wallet-public-key ethereum/normalized-hex)
|
||||
(update :wallet-root-public-key ethereum/normalized-hex)
|
||||
(update :instance-uid #(get-in db [:hardwallet :multiaccount :instance-uid] %))))
|
||||
(assoc-in [:hardwallet :multiaccount-wallet-address] (:wallet-address account-data))
|
||||
(assoc-in [:hardwallet :multiaccount-whisper-public-key] (:whisper-public-key account-data))
|
||||
(assoc-in [:hardwallet :application-info :key-uid] (:key-uid account-data))
|
||||
(update :hardwallet dissoc :recovery-phrase)
|
||||
(update-in [:hardwallet :secrets] dissoc :pin :puk :password)
|
||||
(assoc :multiaccounts/new-installation-id (random-guid-generator))
|
||||
(update-in [:hardwallet :secrets] dissoc :mnemonic))}
|
||||
(common/clear-on-card-connected)
|
||||
(common/remove-listener-to-hardware-back-button)
|
||||
(create-keycard-multiaccount))))
|
||||
|
||||
(fx/defn on-generate-and-load-key-error
|
||||
{:events [:hardwallet.callback/on-generate-and-load-key-error]}
|
||||
[{:keys [db] :as cofx} {:keys [error code]}]
|
||||
(log/debug "[hardwallet] generate and load key error: " error)
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :setup-error] error)}
|
||||
(common/set-on-card-connected :hardwallet/load-loading-keys-screen)
|
||||
(common/process-error code error)))
|
||||
|
||||
(fx/defn import-multiaccount
|
||||
{:events [:hardwallet/import-multiaccount]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{:keys [pairing]} (get-in db [:hardwallet :secrets])
|
||||
instance-uid (get-in db [:hardwallet :application-info :instance-uid])
|
||||
key-uid (get-in db [:hardwallet :application-info :key-uid])
|
||||
pairing' (or pairing (common/get-pairing db key-uid))
|
||||
pin (common/vector->string (get-in db [:hardwallet :pin :import-multiaccount]))]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :multiaccount :instance-uid] instance-uid)
|
||||
(assoc-in [:hardwallet :secrets] {:pairing pairing'
|
||||
:paired-on (utils.datetime/timestamp)}))
|
||||
:hardwallet/get-keys {:pairing pairing'
|
||||
:pin pin
|
||||
:on-success :hardwallet.callback/on-generate-and-load-key-success}})))
|
||||
|
||||
(fx/defn load-recovering-key-screen
|
||||
{:events [:hardwallet/load-recovering-key-screen]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :pin] {:enter-step :import-multiaccount
|
||||
:import-multiaccount []
|
||||
:current []}))}
|
||||
(common/listen-to-hardware-back-button)
|
||||
(navigation/navigate-to-cofx :keycard-recovery-pin nil)))
|
||||
|
||||
(fx/defn on-name-and-photo-generated
|
||||
{:events [::on-name-and-photo-generated]
|
||||
:interceptors [(re-frame/inject-cofx :random-guid-generator)
|
||||
(re-frame/inject-cofx ::multiaccounts.create/get-signing-phrase)]}
|
||||
[{:keys [db] :as cofx} whisper-name photo-path]
|
||||
(fx/merge
|
||||
cofx
|
||||
{:db (update-in db [:hardwallet :multiaccount]
|
||||
(fn [multiacc]
|
||||
(assoc multiacc
|
||||
:name whisper-name
|
||||
:photo-path photo-path)))}
|
||||
(create-keycard-multiaccount)))
|
|
@ -0,0 +1,107 @@
|
|||
(ns status-im.hardwallet.sign
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.utils.types :as types]
|
||||
[status-im.i18n :as i18n]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.hardwallet.common :as common]))
|
||||
|
||||
(fx/defn sign
|
||||
{:events [:hardwallet/sign]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [card-connected? (get-in db [:hardwallet :card-connected?])
|
||||
pairing (common/get-pairing db)
|
||||
multiaccount-keycard-instance-uid (get-in db [:multiaccount :keycard-instance-uid])
|
||||
instance-uid (get-in db [:hardwallet :application-info :instance-uid])
|
||||
keycard-match? (= multiaccount-keycard-instance-uid instance-uid)
|
||||
hash (get-in db [:hardwallet :hash])
|
||||
pin (common/vector->string (get-in db [:hardwallet :pin :sign]))]
|
||||
(if (and card-connected?
|
||||
keycard-match?)
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :card-read-in-progress?] true)
|
||||
(assoc-in [:hardwallet :pin :status] :verifying))
|
||||
:hardwallet/sign {:hash (ethereum/naked-address hash)
|
||||
:pairing pairing
|
||||
:pin pin}}
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:signing/sign :keycard-step] :signing)}
|
||||
(common/set-on-card-connected :hardwallet/sign)
|
||||
(when-not keycard-match?
|
||||
(common/show-wrong-keycard-alert card-connected?))))))
|
||||
|
||||
(fx/defn prepare-to-sign
|
||||
{:events [:hardwallet/prepare-to-sign]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [card-connected? (get-in db [:hardwallet :card-connected?])
|
||||
pairing (common/get-pairing db)]
|
||||
(if card-connected?
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:signing/sign :keycard-step] :signing)}
|
||||
(common/get-application-info pairing :hardwallet/sign))
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:signing/sign :keycard-step] :connect)}
|
||||
(common/set-on-card-connected :hardwallet/prepare-to-sign)))))
|
||||
|
||||
(fx/defn sign-message-completed
|
||||
[_ signature]
|
||||
(let [signature' (-> signature
|
||||
; add 27 to last byte
|
||||
; https://github.com/ethereum/go-ethereum/blob/master/internal/ethapi/api.go#L431
|
||||
(clojure.string/replace-first #"00$", "1b")
|
||||
(clojure.string/replace-first #"01$", "1c")
|
||||
(ethereum/normalized-hex))]
|
||||
{:dispatch
|
||||
[:signing/sign-message-completed (types/clj->json {:result signature'})]}))
|
||||
|
||||
(fx/defn send-transaction-with-signature
|
||||
[_ data]
|
||||
{:send-transaction-with-signature data})
|
||||
|
||||
(fx/defn on-sign-success
|
||||
{:events [:hardwallet.callback/on-sign-success]}
|
||||
[{:keys [db] :as cofx} signature]
|
||||
(log/debug "[hardwallet] sign success: " signature)
|
||||
(let [transaction (get-in db [:hardwallet :transaction])
|
||||
tx-obj (select-keys transaction [:from :to :value :gas :gasPrice])]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :pin :sign] [])
|
||||
(assoc-in [:hardwallet :pin :status] nil)
|
||||
(assoc-in [:hardwallet :hash] nil)
|
||||
(assoc-in [:hardwallet :transaction] nil))}
|
||||
(common/clear-on-card-connected)
|
||||
(common/get-application-info (common/get-pairing db) nil)
|
||||
(if transaction
|
||||
(send-transaction-with-signature {:transaction (types/clj->json transaction)
|
||||
:signature signature
|
||||
:on-completed #(re-frame/dispatch [:signing/transaction-completed % tx-obj])})
|
||||
(sign-message-completed signature)))))
|
||||
|
||||
(fx/defn on-sign-error
|
||||
{:events [:hardwallet.callback/on-sign-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(log/debug "[hardwallet] sign error: " error)
|
||||
(let [tag-was-lost? (= "Tag was lost." (:error error))]
|
||||
(fx/merge cofx
|
||||
(when tag-was-lost?
|
||||
(fn [{:keys [db] :as cofx}]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :pin :status] nil)
|
||||
(assoc-in [:signing/sign :keycard-step] :connect))
|
||||
:utils/show-popup {:title (i18n/label :t/error)
|
||||
:content (i18n/label :t/cannot-read-card)}}
|
||||
(common/set-on-card-connected :hardwallet/prepare-to-sign))))
|
||||
(if (re-matches common/pin-mismatch-error (:error error))
|
||||
(fn [{:keys [db] :as cofx}]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(update-in [:hardwallet :pin] merge {:status :error
|
||||
:sign []
|
||||
:error-label :t/pin-mismatch})
|
||||
(assoc-in [:signing/sign :keycard-step] :pin))}
|
||||
(common/get-application-info (common/get-pairing db) nil)))
|
||||
(common/show-wrong-keycard-alert true)))))
|
|
@ -0,0 +1,142 @@
|
|||
(ns status-im.hardwallet.unpair
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[status-im.multiaccounts.logout.core :as multiaccounts.logout]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
[status-im.utils.fx :as fx]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.hardwallet.common :as common]))
|
||||
|
||||
(fx/defn unpair-card-pressed
|
||||
{:events [:keycard-settings.ui/unpair-card-pressed]}
|
||||
[_]
|
||||
{:ui/show-confirmation {:title (i18n/label :t/unpair-card)
|
||||
:content (i18n/label :t/unpair-card-confirmation)
|
||||
:confirm-button-text (i18n/label :t/yes)
|
||||
:cancel-button-text (i18n/label :t/no)
|
||||
:on-accept #(re-frame/dispatch [:keycard-settings.ui/unpair-card-confirmed])
|
||||
:on-cancel #()}})
|
||||
|
||||
(fx/defn unpair-card-confirmed
|
||||
{:events [:keycard-settings.ui/unpair-card-confirmed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pin-retry-counter (get-in db [:hardwallet :application-info :pin-retry-counter])
|
||||
enter-step (if (zero? pin-retry-counter) :puk :current)]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :pin] {:enter-step enter-step
|
||||
:current []
|
||||
:puk []
|
||||
:status nil
|
||||
:error-label nil
|
||||
:on-verified :hardwallet/unpair})}
|
||||
(common/navigate-to-enter-pin-screen))))
|
||||
|
||||
(fx/defn unpair
|
||||
{:events [:hardwallet/unpair]}
|
||||
[{:keys [db]}]
|
||||
(let [pin (common/vector->string (get-in db [:hardwallet :pin :current]))
|
||||
pairing (common/get-pairing db)]
|
||||
{:hardwallet/unpair {:pin pin
|
||||
:pairing pairing}}))
|
||||
|
||||
(fx/defn unpair-and-delete
|
||||
{:events [:hardwallet/unpair-and-delete]}
|
||||
[{:keys [db]}]
|
||||
(let [pin (common/vector->string (get-in db [:hardwallet :pin :current]))
|
||||
pairing (common/get-pairing db)]
|
||||
{:hardwallet/unpair-and-delete {:pin pin
|
||||
:pairing pairing}}))
|
||||
|
||||
(fx/defn remove-pairing-from-multiaccount
|
||||
[cofx {:keys [remove-instance-uid?]}]
|
||||
(fx/merge cofx
|
||||
(multiaccounts.update/multiaccount-update
|
||||
:keycard-pairing nil {})
|
||||
(multiaccounts.update/multiaccount-update
|
||||
:keycard-paired-on nil {})
|
||||
(when remove-instance-uid?
|
||||
(multiaccounts.update/multiaccount-update
|
||||
:keycard-instance-uid nil {}))))
|
||||
|
||||
(fx/defn on-unpair-success
|
||||
{:events [:hardwallet.callback/on-unpair-success]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [instance-uid (get-in db [:hardwallet :application-info :instance-uid])
|
||||
pairings (get-in db [:hardwallet :pairings])]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :secrets] nil)
|
||||
(update-in [:hardwallet :pairings] dissoc (keyword instance-uid))
|
||||
(assoc-in [:hardwallet :pin] {:status nil
|
||||
:error-label nil
|
||||
:on-verified nil}))
|
||||
:hardwallet/persist-pairings (dissoc pairings (keyword instance-uid))
|
||||
:utils/show-popup {:title ""
|
||||
:content (i18n/label :t/card-unpaired)}}
|
||||
(common/clear-on-card-connected)
|
||||
(remove-pairing-from-multiaccount nil)
|
||||
(navigation/navigate-to-cofx :keycard-settings nil))))
|
||||
|
||||
(fx/defn on-unpair-error
|
||||
{:events [:hardwallet.callback/on-unpair-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(log/debug "[hardwallet] unpair error" error)
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :pin] {:status nil
|
||||
:error-label nil
|
||||
:on-verified nil})
|
||||
:hardwallet/get-application-info nil
|
||||
:utils/show-popup {:title ""
|
||||
:content (i18n/label :t/something-went-wrong)}}
|
||||
(common/clear-on-card-connected)
|
||||
(navigation/navigate-to-cofx :keycard-settings nil)))
|
||||
|
||||
(fx/defn remove-key-with-unpair
|
||||
{:events [:hardwallet/remove-key-with-unpair]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pin (common/vector->string (get-in db [:hardwallet :pin :current]))
|
||||
pairing (common/get-pairing db)
|
||||
card-connected? (get-in db [:hardwallet :card-connected?])]
|
||||
(if card-connected?
|
||||
{:hardwallet/remove-key-with-unpair {:pin pin
|
||||
:pairing pairing}}
|
||||
(fx/merge cofx
|
||||
(common/set-on-card-connected :hardwallet/remove-key-with-unpair)
|
||||
(navigation/navigate-to-cofx :keycard-connection-lost nil)))))
|
||||
|
||||
(fx/defn on-remove-key-success
|
||||
{:events [:hardwallet.callback/on-remove-key-success]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [key-uid (get-in db [:multiaccount :key-uid])
|
||||
instance-uid (get-in db [:hardwallet :application-info :instance-uid])
|
||||
pairings (get-in db [:hardwallet :pairings])]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(update :multiaccounts/multiaccounts dissoc key-uid)
|
||||
(assoc-in [:hardwallet :secrets] nil)
|
||||
(update-in [:hardwallet :pairings] dissoc (keyword instance-uid))
|
||||
(assoc-in [:hardwallet :whisper-public-key] nil)
|
||||
(assoc-in [:hardwallet :wallet-address] nil)
|
||||
(assoc-in [:hardwallet :application-info] nil)
|
||||
(assoc-in [:hardwallet :pin] {:status nil
|
||||
:error-label nil
|
||||
:on-verified nil}))
|
||||
:hardwallet/persist-pairings (dissoc pairings (keyword instance-uid))
|
||||
;;FIXME delete multiaccount
|
||||
:utils/show-popup {:title ""
|
||||
:content (i18n/label :t/card-reseted)}}
|
||||
(common/clear-on-card-connected)
|
||||
(multiaccounts.logout/logout))))
|
||||
|
||||
(fx/defn on-remove-key-error
|
||||
{:events [:hardwallet.callback/on-remove-key-error]}
|
||||
[{:keys [db] :as cofx} error]
|
||||
(log/debug "[hardwallet] remove key error" error)
|
||||
(let [tag-was-lost? (= "Tag was lost." (:error error))]
|
||||
(fx/merge cofx
|
||||
(if tag-was-lost?
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :pin :status] nil)}
|
||||
(common/set-on-card-connected :hardwallet/remove-key-with-unpair))
|
||||
(common/show-wrong-keycard-alert true)))))
|
|
@ -0,0 +1,33 @@
|
|||
(ns status-im.hardwallet.wallet
|
||||
(:require [status-im.ethereum.core :as ethereum]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.hardwallet.common :as common]
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.ethereum.eip55 :as eip55]))
|
||||
|
||||
(fx/defn generate-new-keycard-account
|
||||
{:events [:wallet.accounts/generate-new-keycard-account]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [path-num (inc (get-in db [:multiaccount :latest-derived-path]))
|
||||
path (str constants/path-wallet-root "/" path-num)
|
||||
card-connected? (get-in db [:hardwallet :card-connected?])
|
||||
pin (common/vector->string (get-in db [:hardwallet :pin :export-key]))
|
||||
pairing (common/get-pairing db)]
|
||||
(if card-connected?
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:hardwallet :on-export-success]
|
||||
#(vector :wallet.accounts/account-generated
|
||||
{:name (str "Account " path-num)
|
||||
;; Strip leading 04 prefix denoting uncompressed key format
|
||||
:address (eip55/address->checksum (str "0x" (ethereum/public-key->address (subs % 2))))
|
||||
:public-key (str "0x" %)
|
||||
:path path
|
||||
:color (rand-nth colors/account-colors)}))
|
||||
:hardwallet/export-key {:pin pin :pairing pairing :path path}}
|
||||
(navigation/navigate-to-cofx :keycard-processing nil)
|
||||
(common/set-on-card-connected :wallet.accounts/generate-new-keycard-account))
|
||||
(fx/merge cofx
|
||||
(common/set-on-card-connected :wallet.accounts/generate-new-keycard-account)
|
||||
(navigation/navigate-to-cofx :keycard-processing nil)))))
|
|
@ -68,7 +68,6 @@
|
|||
::open-multiaccounts #(re-frame/dispatch [::initialize-multiaccounts % {:logout? false}])
|
||||
:ui/listen-to-window-dimensions-change nil
|
||||
::network/listen-to-network-info nil
|
||||
:hardwallet/register-card-events nil
|
||||
:hardwallet/check-nfc-support nil
|
||||
:hardwallet/check-nfc-enabled nil
|
||||
:hardwallet/retrieve-pairings nil}
|
||||
|
|
|
@ -87,27 +87,26 @@
|
|||
{::store-multiaccount [selected-id hashed-password callback]}))
|
||||
|
||||
(fx/defn prepare-intro-wizard
|
||||
[{:keys [db] :as cofx} first-time-setup?]
|
||||
[{:keys [db] :as cofx}]
|
||||
{:db (assoc db :intro-wizard {:step :generate-key
|
||||
:weak-password? true
|
||||
:back-action :intro-wizard/navigate-back
|
||||
:forward-action :intro-wizard/step-forward-pressed
|
||||
:encrypt-with-password? true
|
||||
:first-time-setup? first-time-setup?})})
|
||||
:encrypt-with-password? true})})
|
||||
|
||||
(fx/defn intro-wizard
|
||||
{:events [:multiaccounts.create.ui/intro-wizard]}
|
||||
[{:keys [db] :as cofx} first-time-setup?]
|
||||
[{:keys [db] :as cofx}]
|
||||
(fx/merge cofx
|
||||
{:db (update db :hardwallet dissoc :flow)}
|
||||
(prepare-intro-wizard first-time-setup?)
|
||||
(prepare-intro-wizard)
|
||||
(navigation/navigate-to-cofx :create-multiaccount-generate-key nil)))
|
||||
|
||||
(fx/defn get-new-key
|
||||
{:events [:multiaccounts.create.ui/get-new-key]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(fx/merge cofx
|
||||
(prepare-intro-wizard false)
|
||||
(prepare-intro-wizard)
|
||||
(bottom-sheet/hide-bottom-sheet)
|
||||
(navigation/navigate-to-cofx :create-multiaccount-generate-key nil)))
|
||||
|
||||
|
|
|
@ -161,7 +161,6 @@
|
|||
:next-button-disabled? true
|
||||
:weak-password? true
|
||||
:encrypt-with-password? true
|
||||
:first-time-setup? false
|
||||
:back-action :intro-wizard/navigate-back
|
||||
:forward-action :multiaccounts.recover/enter-phrase-next-pressed})
|
||||
(update :hardwallet dissoc :flow))}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
(ns status-im.ui.screens.hardwallet.settings.subs
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.hardwallet.core :as core]
|
||||
[status-im.hardwallet.common :as common]
|
||||
[status-im.utils.datetime :as utils.datetime]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
|
@ -12,7 +12,7 @@
|
|||
(re-frame/reg-sub
|
||||
:keycard-pairing
|
||||
(fn [db]
|
||||
(core/get-pairing db)))
|
||||
(common/get-pairing db)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:keycard-multiaccount-pairing
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
:text :intro-text3}] window-height]
|
||||
[react/view styles/buttons-container
|
||||
[components.common/button {:button-style (assoc styles/bottom-button :margin-bottom 16)
|
||||
:on-press #(re-frame/dispatch [:multiaccounts.create.ui/intro-wizard true])
|
||||
:on-press #(re-frame/dispatch [:multiaccounts.create.ui/intro-wizard])
|
||||
:label (i18n/label :t/get-started)}]
|
||||
[components.common/button {:button-style (assoc styles/bottom-button :margin-bottom 24)
|
||||
:on-press #(re-frame/dispatch [:multiaccounts.recover.ui/recover-multiaccount-button-pressed])
|
||||
|
|
Loading…
Reference in New Issue