add creation of backup keycards
Signed-off-by: Michele Balistreri <michele@bitgamma.com>
This commit is contained in:
parent
be0ad943ea
commit
f0827ff624
|
@ -0,0 +1,40 @@
|
||||||
|
(ns status-im.keycard.backup-key
|
||||||
|
(:require [status-im.utils.fx :as fx]
|
||||||
|
[status-im.ethereum.mnemonic :as mnemonic]
|
||||||
|
[status-im.multiaccounts.recover.core :as multiaccounts.recover]
|
||||||
|
[status-im.navigation :as navigation]
|
||||||
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
|
(fx/defn backup-card-pressed
|
||||||
|
{:events [:keycard-settings.ui/backup-card-pressed]}
|
||||||
|
[{:keys [db] :as cofx}]
|
||||||
|
(log/debug "[keycard] start backup")
|
||||||
|
(fx/merge cofx
|
||||||
|
{:db (-> db
|
||||||
|
(assoc-in [:keycard :creating-backup?] true))}
|
||||||
|
(navigation/navigate-to-cofx :seed-phrase nil)))
|
||||||
|
|
||||||
|
(fx/defn start-keycard-backup
|
||||||
|
{:events [::start-keycard-backup]}
|
||||||
|
[{:keys [db] :as cofx}]
|
||||||
|
{::multiaccounts.recover/import-multiaccount {:passphrase (-> db
|
||||||
|
:multiaccounts/key-storage
|
||||||
|
:seed-phrase
|
||||||
|
mnemonic/sanitize-passphrase)
|
||||||
|
:password nil
|
||||||
|
:success-event ::create-backup-card}})
|
||||||
|
(fx/defn create-backup-card
|
||||||
|
{:events [::create-backup-card]}
|
||||||
|
[{:keys [db] :as cofx} root-data derived-data]
|
||||||
|
(fx/merge cofx
|
||||||
|
{:db (-> db
|
||||||
|
(update :intro-wizard
|
||||||
|
assoc
|
||||||
|
:root-key root-data
|
||||||
|
:derived derived-data
|
||||||
|
:recovering? true
|
||||||
|
:selected-storage-type :advanced)
|
||||||
|
(assoc-in [:keycard :flow] :recovery)
|
||||||
|
(update :multiaccounts/key-storage dissoc :seed-phrase))
|
||||||
|
:dismiss-keyboard nil}
|
||||||
|
(navigation/navigate-to-cofx :keycard-onboarding-intro nil)))
|
|
@ -5,6 +5,7 @@
|
||||||
status-im.keycard.delete-key
|
status-im.keycard.delete-key
|
||||||
status-im.keycard.export-key
|
status-im.keycard.export-key
|
||||||
status-im.keycard.unpair
|
status-im.keycard.unpair
|
||||||
|
status-im.keycard.backup-key
|
||||||
[status-im.keycard.login :as login]
|
[status-im.keycard.login :as login]
|
||||||
[status-im.keycard.mnemonic :as mnemonic]
|
[status-im.keycard.mnemonic :as mnemonic]
|
||||||
[status-im.keycard.onboarding :as onboarding]
|
[status-im.keycard.onboarding :as onboarding]
|
||||||
|
@ -65,8 +66,9 @@
|
||||||
"instance-uid" instance-uid)
|
"instance-uid" instance-uid)
|
||||||
(if (= flow :import)
|
(if (= flow :import)
|
||||||
(navigation/navigate-to-cofx cofx :keycard-recovery-no-key nil)
|
(navigation/navigate-to-cofx cofx :keycard-recovery-no-key nil)
|
||||||
(let [pairing-data (get-in db [:keycard :pairings instance-uid])]
|
(let [pairing-data (get-in db [:keycard :pairings (keyword instance-uid)])
|
||||||
(if pairing-data
|
paired? (get-in db [:keycard :application-info :paired?])]
|
||||||
|
(if paired?
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
{:db (update-in db [:keycard :secrets] merge pairing-data)}
|
{:db (update-in db [:keycard :secrets] merge pairing-data)}
|
||||||
(common/listen-to-hardware-back-button)
|
(common/listen-to-hardware-back-button)
|
||||||
|
|
|
@ -197,12 +197,20 @@
|
||||||
(navigation/navigate-to-cofx (if platform/android?
|
(navigation/navigate-to-cofx (if platform/android?
|
||||||
:notifications-settings :welcome) nil))))))
|
:notifications-settings :welcome) nil))))))
|
||||||
|
|
||||||
|
(fx/defn on-backup-success
|
||||||
|
[{:keys [db] :as cofx}]
|
||||||
|
(fx/merge cofx
|
||||||
|
{:utils/show-popup {:title (i18n/label :t/keycard-backup-success-title)
|
||||||
|
:content (i18n/label :t/keycard-backup-success-body)}}
|
||||||
|
(navigation/navigate-to-cofx :keycard-settings nil)))
|
||||||
|
|
||||||
(fx/defn on-generate-and-load-key-success
|
(fx/defn on-generate-and-load-key-success
|
||||||
{:events [:keycard.callback/on-generate-and-load-key-success]
|
{:events [:keycard.callback/on-generate-and-load-key-success]
|
||||||
:interceptors [(re-frame/inject-cofx :random-guid-generator)
|
:interceptors [(re-frame/inject-cofx :random-guid-generator)
|
||||||
(re-frame/inject-cofx ::multiaccounts.create/get-signing-phrase)]}
|
(re-frame/inject-cofx ::multiaccounts.create/get-signing-phrase)]}
|
||||||
[{:keys [db random-guid-generator] :as cofx} data]
|
[{:keys [db random-guid-generator] :as cofx} data]
|
||||||
(let [account-data (js->clj data :keywordize-keys true)]
|
(let [account-data (js->clj data :keywordize-keys true)
|
||||||
|
backup? (get-in db [:keycard :creating-backup?])]
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
{:db (-> db
|
{:db (-> db
|
||||||
(assoc-in [:keycard :multiaccount]
|
(assoc-in [:keycard :multiaccount]
|
||||||
|
@ -222,12 +230,13 @@
|
||||||
(assoc-in [:keycard :application-info :key-uid]
|
(assoc-in [:keycard :application-info :key-uid]
|
||||||
(ethereum/normalized-hex (:key-uid account-data)))
|
(ethereum/normalized-hex (:key-uid account-data)))
|
||||||
(update :keycard dissoc :recovery-phrase)
|
(update :keycard dissoc :recovery-phrase)
|
||||||
|
(update :keycard dissoc :creating-backup?)
|
||||||
(update-in [:keycard :secrets] dissoc :pin :puk :password)
|
(update-in [:keycard :secrets] dissoc :pin :puk :password)
|
||||||
(assoc :multiaccounts/new-installation-id (random-guid-generator))
|
(assoc :multiaccounts/new-installation-id (random-guid-generator))
|
||||||
(update-in [:keycard :secrets] dissoc :mnemonic))}
|
(update-in [:keycard :secrets] dissoc :mnemonic))}
|
||||||
(common/remove-listener-to-hardware-back-button)
|
(common/remove-listener-to-hardware-back-button)
|
||||||
(common/hide-connection-sheet)
|
(common/hide-connection-sheet)
|
||||||
(create-keycard-multiaccount))))
|
(if backup? (on-backup-success) (create-keycard-multiaccount)))))
|
||||||
|
|
||||||
(fx/defn on-generate-and-load-key-error
|
(fx/defn on-generate-and-load-key-error
|
||||||
{:events [:keycard.callback/on-generate-and-load-key-error]}
|
{:events [:keycard.callback/on-generate-and-load-key-error]}
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
[status-im.popover.core :as popover]
|
[status-im.popover.core :as popover]
|
||||||
[status-im.utils.fx :as fx]
|
[status-im.utils.fx :as fx]
|
||||||
[status-im.utils.security :as security]
|
[status-im.utils.security :as security]
|
||||||
[status-im.utils.types :as types]))
|
[status-im.utils.types :as types]
|
||||||
|
[status-im.keycard.backup-key :as keycard.backup]))
|
||||||
|
|
||||||
(fx/defn key-and-storage-management-pressed
|
(fx/defn key-and-storage-management-pressed
|
||||||
"This event can be dispatched before login and from profile and needs to redirect accordingly"
|
"This event can be dispatched before login and from profile and needs to redirect accordingly"
|
||||||
|
@ -53,6 +54,14 @@
|
||||||
[cofx _]
|
[cofx _]
|
||||||
(popover/show-popover cofx {:view :seed-key-uid-mismatch}))
|
(popover/show-popover cofx {:view :seed-key-uid-mismatch}))
|
||||||
|
|
||||||
|
(fx/defn key-uid-matches
|
||||||
|
{:events [::key-uid-matches]}
|
||||||
|
[{:keys [db] :as cofx} _]
|
||||||
|
(let [backup? (get-in db [:keycard :creating-backup?])]
|
||||||
|
(if backup?
|
||||||
|
(keycard.backup/start-keycard-backup cofx)
|
||||||
|
(navigation/navigate-to-cofx cofx :storage nil))))
|
||||||
|
|
||||||
(defn validate-seed-against-key-uid
|
(defn validate-seed-against-key-uid
|
||||||
"Check if the key-uid was generated with the given seed-phrase"
|
"Check if the key-uid was generated with the given seed-phrase"
|
||||||
[{:keys [import-mnemonic-fn on-success on-error]} {:keys [seed-phrase key-uid]}]
|
[{:keys [import-mnemonic-fn on-success on-error]} {:keys [seed-phrase key-uid]}]
|
||||||
|
@ -70,7 +79,7 @@
|
||||||
::validate-seed-against-key-uid
|
::validate-seed-against-key-uid
|
||||||
(partial validate-seed-against-key-uid
|
(partial validate-seed-against-key-uid
|
||||||
{:import-mnemonic-fn native-module/multiaccount-import-mnemonic
|
{:import-mnemonic-fn native-module/multiaccount-import-mnemonic
|
||||||
:on-success #(re-frame/dispatch [:navigate-to :storage])
|
:on-success #(re-frame/dispatch [::key-uid-matches])
|
||||||
:on-error #(re-frame/dispatch [::show-seed-key-uid-mismatch-error-popup])}))
|
:on-error #(re-frame/dispatch [::show-seed-key-uid-mismatch-error-popup])}))
|
||||||
|
|
||||||
(fx/defn seed-phrase-validated
|
(fx/defn seed-phrase-validated
|
||||||
|
@ -85,7 +94,7 @@
|
||||||
(popover/show-popover cofx {:view :custom-seed-phrase})
|
(popover/show-popover cofx {:view :custom-seed-phrase})
|
||||||
{::validate-seed-against-key-uid {:seed-phrase (-> db :multiaccounts/key-storage :seed-phrase)
|
{::validate-seed-against-key-uid {:seed-phrase (-> db :multiaccounts/key-storage :seed-phrase)
|
||||||
;; Unique key-uid of the account for which we are going to move keys
|
;; Unique key-uid of the account for which we are going to move keys
|
||||||
:key-uid (-> db :multiaccounts/login :key-uid)}})))
|
:key-uid (or (-> db :multiaccounts/login :key-uid) (-> db :multiaccount :key-uid))}})))
|
||||||
|
|
||||||
(fx/defn choose-storage-pressed
|
(fx/defn choose-storage-pressed
|
||||||
{:events [::choose-storage-pressed]}
|
{:events [::choose-storage-pressed]}
|
||||||
|
|
|
@ -95,19 +95,15 @@
|
||||||
:on-press #(re-frame/dispatch [:keycard-settings.ui/change-pin-pressed])}]
|
:on-press #(re-frame/dispatch [:keycard-settings.ui/change-pin-pressed])}]
|
||||||
;; TODO(rasom): uncomment this when unpairing will be enabled
|
;; TODO(rasom): uncomment this when unpairing will be enabled
|
||||||
;; https://github.com/status-im/status-react/issues/9227
|
;; https://github.com/status-im/status-react/issues/9227
|
||||||
|
[quo/list-item {:icon :main-icons/keycard
|
||||||
|
:size :small
|
||||||
|
:title (i18n/label :t/keycard-backup)
|
||||||
|
:accessibility-label "create-backup-keycard"
|
||||||
|
:on-press #(re-frame/dispatch [:keycard-settings.ui/backup-card-pressed])}]
|
||||||
#_[quo/list-item {:icon :main-icons/close
|
#_[quo/list-item {:icon :main-icons/close
|
||||||
:size :small
|
:size :small
|
||||||
:title (i18n/label :t/unpair-card)
|
:title (i18n/label :t/unpair-card)
|
||||||
:on-press #(re-frame/dispatch [:keycard-settings.ui/unpair-card-pressed])}]])])]
|
:on-press #(re-frame/dispatch [:keycard-settings.ui/unpair-card-pressed])}]])])]]]))
|
||||||
; NOTE: Reset card is hidden until multiaccount removal will be implemented
|
|
||||||
#_(when pairing
|
|
||||||
[react/view {:margin-bottom 35
|
|
||||||
:margin-left 16}
|
|
||||||
[quo/list-item {:icon :main-icons/warning
|
|
||||||
:theme :negative
|
|
||||||
:size :small
|
|
||||||
:title (i18n/label :t/reset-card)
|
|
||||||
:on-press #(re-frame/dispatch [:keycard-settings.ui/reset-card-pressed])}]])]]))
|
|
||||||
|
|
||||||
(defn reset-pin []
|
(defn reset-pin []
|
||||||
[keycard.views/login-pin
|
[keycard.views/login-pin
|
||||||
|
|
|
@ -103,7 +103,8 @@
|
||||||
|
|
||||||
(defview seed-phrase []
|
(defview seed-phrase []
|
||||||
(letsubs
|
(letsubs
|
||||||
[{:keys [seed-word-count seed-shape-invalid?]} [:multiaccounts/key-storage]]
|
[{:keys [seed-word-count seed-shape-invalid?]} [:multiaccounts/key-storage]
|
||||||
|
{:keys [creating-backup?]} [:keycard]]
|
||||||
[react/keyboard-avoiding-view {:flex 1}
|
[react/keyboard-avoiding-view {:flex 1}
|
||||||
[local-topbar (i18n/label :t/enter-seed-phrase)]
|
[local-topbar (i18n/label :t/enter-seed-phrase)]
|
||||||
[multiaccounts.views/seed-phrase-input
|
[multiaccounts.views/seed-phrase-input
|
||||||
|
@ -122,7 +123,7 @@
|
||||||
(nil? seed-shape-invalid?))
|
(nil? seed-shape-invalid?))
|
||||||
:on-press #(re-frame/dispatch [::multiaccounts.key-storage/choose-storage-pressed])
|
:on-press #(re-frame/dispatch [::multiaccounts.key-storage/choose-storage-pressed])
|
||||||
:after :main-icons/next}
|
:after :main-icons/next}
|
||||||
(i18n/label :t/choose-storage)]}]]))
|
(i18n/label (if creating-backup? :t/next :t/choose-storage))]}]]))
|
||||||
|
|
||||||
(defn keycard-subtitle []
|
(defn keycard-subtitle []
|
||||||
[react/view
|
[react/view
|
||||||
|
@ -197,7 +198,8 @@
|
||||||
(i18n/label :t/confirm)]}]]]))
|
(i18n/label :t/confirm)]}]]]))
|
||||||
|
|
||||||
(defview seed-key-uid-mismatch-popover []
|
(defview seed-key-uid-mismatch-popover []
|
||||||
(letsubs [{:keys [name]} [:multiaccounts/login]]
|
(letsubs [{:keys [name]} [:multiaccounts/login]
|
||||||
|
{logged-in-name :name} [:multiaccount]]
|
||||||
[react/view {:margin-top 24
|
[react/view {:margin-top 24
|
||||||
:margin-horizontal 24
|
:margin-horizontal 24
|
||||||
:align-items :center}
|
:align-items :center}
|
||||||
|
@ -215,7 +217,7 @@
|
||||||
[react/view
|
[react/view
|
||||||
[react/text {:style (into styles/popover-text
|
[react/text {:style (into styles/popover-text
|
||||||
{:margin-bottom 16})}
|
{:margin-bottom 16})}
|
||||||
(i18n/label :t/seed-key-uid-mismatch-desc-1 {:multiaccount-name name})]
|
(i18n/label :t/seed-key-uid-mismatch-desc-1 {:multiaccount-name (or name logged-in-name)})]
|
||||||
[react/text {:style styles/popover-text}
|
[react/text {:style styles/popover-text}
|
||||||
(i18n/label :t/seed-key-uid-mismatch-desc-2)]]]
|
(i18n/label :t/seed-key-uid-mismatch-desc-2)]]]
|
||||||
[react/view {:margin-vertical 24
|
[react/view {:margin-vertical 24
|
||||||
|
|
|
@ -27,7 +27,12 @@
|
||||||
[status-im.ui.screens.status.new.views :as status.new]
|
[status-im.ui.screens.status.new.views :as status.new]
|
||||||
[status-im.ui.screens.browser.bookmarks.views :as bookmarks]
|
[status-im.ui.screens.browser.bookmarks.views :as bookmarks]
|
||||||
[status-im.ui.screens.routing.status-stack :as status-stack]
|
[status-im.ui.screens.routing.status-stack :as status-stack]
|
||||||
[status-im.ui.screens.communities.invite :as communities.invite]))
|
[status-im.ui.screens.communities.invite :as communities.invite]
|
||||||
|
[status-im.ui.screens.keycard.onboarding.views :as keycard.onboarding]
|
||||||
|
[status-im.ui.screens.keycard.recovery.views :as keycard.recovery]
|
||||||
|
[status-im.keycard.core :as keycard.core]
|
||||||
|
[status-im.ui.screens.keycard.views :as keycard]
|
||||||
|
[status-im.ui.screens.multiaccounts.key-storage.views :as key-storage.views]))
|
||||||
|
|
||||||
(defonce main-stack (navigation/create-stack))
|
(defonce main-stack (navigation/create-stack))
|
||||||
(defonce bottom-tabs (navigation/create-bottom-tabs))
|
(defonce bottom-tabs (navigation/create-bottom-tabs))
|
||||||
|
@ -55,7 +60,8 @@
|
||||||
:component profile-stack/profile-stack}]])
|
:component profile-stack/profile-stack}]])
|
||||||
|
|
||||||
(views/defview get-main-component [_]
|
(views/defview get-main-component [_]
|
||||||
(views/letsubs [logged-in? [:multiaccount/logged-in?]]
|
(views/letsubs [logged-in? [:multiaccount/logged-in?]
|
||||||
|
keycard-account? [:multiaccounts/keycard-account?]]
|
||||||
[main-stack (merge {:header-mode :none}
|
[main-stack (merge {:header-mode :none}
|
||||||
;; https://github.com/react-navigation/react-navigation/issues/6520
|
;; https://github.com/react-navigation/react-navigation/issues/6520
|
||||||
(when platform/ios?
|
(when platform/ios?
|
||||||
|
@ -170,4 +176,26 @@
|
||||||
(when config/quo-preview-enabled?
|
(when config/quo-preview-enabled?
|
||||||
[{:name :quo-preview
|
[{:name :quo-preview
|
||||||
:insets {:top false :bottom false}
|
:insets {:top false :bottom false}
|
||||||
:component quo.preview/preview-stack}]))]))
|
:component quo.preview/preview-stack}])
|
||||||
|
|
||||||
|
(when keycard-account?
|
||||||
|
[{:name :keycard-onboarding-intro
|
||||||
|
:back-handler keycard.core/onboarding-intro-back-handler
|
||||||
|
:component keycard.onboarding/intro}
|
||||||
|
{:name :keycard-onboarding-puk-code
|
||||||
|
:back-handler :noop
|
||||||
|
:component keycard.onboarding/puk-code}
|
||||||
|
{:name :keycard-onboarding-pin
|
||||||
|
:back-handler :noop
|
||||||
|
:component keycard.onboarding/pin}
|
||||||
|
{:name :keycard-recovery-pair
|
||||||
|
:back-handler :noop
|
||||||
|
:component keycard.recovery/pair}
|
||||||
|
{:name :seed-phrase
|
||||||
|
:component key-storage.views/seed-phrase}
|
||||||
|
{:name :keycard-recovery-pin
|
||||||
|
:component keycard.recovery/pin}
|
||||||
|
{:name :keycard-wrong
|
||||||
|
:component keycard/wrong}
|
||||||
|
{:name :not-keycard
|
||||||
|
:component keycard/not-keycard}]))]))
|
||||||
|
|
|
@ -1211,6 +1211,9 @@
|
||||||
"keycard-error-description": "Connect the card again to continue",
|
"keycard-error-description": "Connect the card again to continue",
|
||||||
"keycard-success-title": "Success",
|
"keycard-success-title": "Success",
|
||||||
"keycard-success-description": "You may remove the card now",
|
"keycard-success-description": "You may remove the card now",
|
||||||
|
"keycard-backup": "Create a backup Keycard",
|
||||||
|
"keycard-backup-success-title": "Backup successful",
|
||||||
|
"keycard-backup-success-body": "Backup card created successfully. You can now use it with your account just like the primary card.",
|
||||||
"type-a-message": "Message",
|
"type-a-message": "Message",
|
||||||
"ulc-enabled": "ULC enabled",
|
"ulc-enabled": "ULC enabled",
|
||||||
"unable-to-read-this-code": "Unable to read this code",
|
"unable-to-read-this-code": "Unable to read this code",
|
||||||
|
|
Loading…
Reference in New Issue