import keycard

Signed-off-by: Dmitry Novotochinov <dmitry.novot@gmail.com>
This commit is contained in:
Dmitry Novotochinov 2019-07-10 14:05:29 +03:00
parent b9ab37019d
commit d8645e2859
No known key found for this signature in database
GPG Key ID: 43D1DAF5AD39C927
16 changed files with 694 additions and 275 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -1225,26 +1225,6 @@
(fn [cofx _]
(hardwallet/proceed-to-generate-mnemonic cofx)))
(handlers/register-handler-fx
:hardwallet.ui/import-multiaccount-back-button-pressed
(fn [cofx _]
(hardwallet/import-multiaccount-back-button-pressed cofx)))
(handlers/register-handler-fx
:hardwallet.ui/import-multiaccount-next-button-pressed
(fn [cofx _]
(hardwallet/import-multiaccount-next-button-pressed cofx)))
(handlers/register-handler-fx
:hardwallet/load-importing-multiaccount-screen
(fn [cofx _]
(hardwallet/load-importing-multiaccount-screen cofx)))
(handlers/register-handler-fx
:hardwallet/import-multiaccount
(fn [cofx _]
(hardwallet/import-multiaccount cofx)))
(handlers/register-handler-fx
:hardwallet/generate-mnemonic
(fn [cofx _]

View File

@ -35,7 +35,8 @@
(.removeAllListeners (event-emitter) event)))
(defn register-card-events []
(when (and config/hardwallet-enabled?)
(when (and config/hardwallet-enabled?
platform/android?)
(remove-event-listeners)

View File

@ -123,6 +123,12 @@
paired?]}]
(cond
(not applet-installed?)
:blank
(not initialized?)
:pre-init
(and (not paired?)
(zero? free-pairing-slots))
:no-pairing-slots
@ -131,12 +137,6 @@
(pos? free-pairing-slots))
:not-paired
(not applet-installed?)
:blank
(not initialized?)
:pre-init
(not has-master-key?)
:init
@ -172,7 +172,7 @@
(navigation/navigate-to-cofx :keycard-onboarding-preparing nil))
(if card-connected?
(dispatch-event :hardwallet/start-installation)
(navigation/navigate-to-cofx :keycard-onboarding-connection-lost nil)))))
(navigation/navigate-to-cofx :keycard-connection-lost nil)))))
(fx/defn load-pin-screen
[{:keys [db] :as cofx}]
@ -189,7 +189,7 @@
(fx/merge cofx
{:db (-> db
(assoc-in [:hardwallet :setup-step] :pair))}
(navigation/navigate-to-cofx :keycard-onboarding-pair nil)))
(navigation/navigate-to-cofx :keycard-recovery-pair nil)))
(fx/defn load-pairing-screen
{:events [:hardwallet/load-pairing-screen
@ -201,10 +201,10 @@
(assoc-in [:hardwallet :setup-step] :pairing)
(assoc-in [:hardwallet :on-card-connected] :hardwallet/load-pairing-screen))}
(when card-connected?
(navigation/navigate-to-cofx :keycard-onboarding-pairing nil))
(navigation/navigate-to-cofx :keycard-pairing nil))
(if card-connected?
(dispatch-event :hardwallet/pair)
(navigation/navigate-to-cofx :keycard-onboarding-connection-lost nil)))))
(navigation/navigate-to-cofx :keycard-connection-lost nil)))))
(fx/defn puk-code-next-pressed
{:events [:keycard.onboarding.puk-code.ui/next-pressed]}
@ -246,7 +246,7 @@
(navigation/navigate-to-cofx :keycard-onboarding-finishing nil))
(if card-connected?
(dispatch-event :hardwallet/generate-and-load-key)
(navigation/navigate-to-cofx :keycard-onboarding-connection-lost nil)))))
(navigation/navigate-to-cofx :keycard-connection-lost nil)))))
(fx/defn recovery-phrase-learn-more-pressed
{:events [:keycard.onboarding.recovery-phrase.ui/learn-more-pressed]}
@ -339,6 +339,15 @@
[{:keys [db]} input]
{:db (assoc-in db [:hardwallet :secrets :password] input)})
(fx/defn load-recovery-pin-screen
[{:keys [db] :as cofx}]
(fx/merge cofx
{:db (-> db
(assoc-in [:hardwallet :pin] {:enter-step :import-multiaccount
:import-multiaccount []
:current []}))}
(navigation/navigate-to-cofx :keycard-recovery-pin nil)))
(fx/defn check-card-state
[{:keys [db] :as cofx}]
(let [app-info (get-in db [:hardwallet :application-info])
@ -354,14 +363,20 @@
{:db db'}
(set-setup-step card-state)
(when (= card-state :pre-init)
(load-pin-screen))
(when (= card-state :not-paired)
(if (= flow :import)
(navigation/navigate-to-cofx :keycard-recovery-no-key nil)
(load-pin-screen)))
(when (and (= card-state :not-paired)
(= flow :import))
(load-pair-screen))
(when (= card-state :blank)
(show-no-keycard-applet-alert))
(when (and (= card-state :multiaccount)
(#{:create :recovery} flow))
(show-keycard-has-multiaccount-alert)))
(if (= flow :import)
(navigation/navigate-to-cofx :keycard-recovery-no-key nil)
(show-no-keycard-applet-alert)))
(when (= card-state :multiaccount)
(if (#{:create :recovery} flow)
(show-keycard-has-multiaccount-alert)
(load-recovery-pin-screen))))
{:db db'})))
(fx/defn navigate-to-keycard-settings
@ -393,22 +408,32 @@
(navigation/navigate-to-cofx :hardwallet-authentication-method nil))
(multiaccounts.create/intro-wizard cofx false)))
(fx/defn navigate-to-enter-mnemonic
{:events [:multiaccounts.recover.ui/recover-multiaccount-button-pressed]}
(fx/defn keycard-storage-selected-for-recovery
{:events [:recovery.ui/keycard-storage-selected]}
[{:keys [db] :as cofx}]
(if (hardwallet-supported? cofx)
(fx/merge cofx
{:db (assoc-in db [:hardwallet :flow] :recovery)}
(navigation/navigate-to-cofx :keycard-recovery-enter-mnemonic nil))
(multiaccounts.recover/navigate-to-recover-multiaccount-screen cofx)))
(navigation/navigate-to-cofx :keycard-recovery-enter-mnemonic nil)))
(fx/defn recover-with-keycard-pressed
{:events [:recovery.ui/recover-with-keycard-pressed]}
[{:keys [db] :as cofx}]
(fx/merge cofx
{:db (assoc-in db [:hardwallet :flow] :import)
:hardwallet/check-nfc-enabled nil}
(navigation/navigate-to-cofx :keycard-recovery-intro nil)))
(fx/defn access-key-pressed
{:events [:multiaccounts.recover.ui/recover-multiaccount-button-pressed]}
[cofx]
(multiaccounts.recover/navigate-to-recover-multiaccount-screen cofx))
(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
:hardwallet/register-card-events nil}
:hardwallet/check-nfc-enabled nil}
(navigation/navigate-to-cofx :keycard-onboarding-intro nil)))
;NOTE to be removed when Recovery flow will be implemented
@ -607,7 +632,6 @@
(fx/defn status-hardwallet-option-pressed [{:keys [db] :as cofx}]
(fx/merge cofx
{:hardwallet/check-nfc-enabled nil
:hardwallet/register-card-events nil
:db (-> db
(assoc-in [:hardwallet :setup-step] :begin)
(assoc-in [:hardwallet :on-card-connected] :hardwallet/get-application-info)
@ -618,17 +642,27 @@
(fx/defn keycard-option-pressed
{:events [:onboarding.ui/keycard-option-pressed]}
[{:keys [db] :as cofx}]
(let [flow (get-in db [:hardwallet :flow] :create)]
(let [flow (get-in db [:hardwallet :flow])]
(fx/merge cofx
{:db (assoc-in db [:hardwallet :flow] flow)
:hardwallet/check-nfc-enabled nil
:hardwallet/register-card-events nil}
(navigation/navigate-to-cofx :keycard-onboarding-intro nil))))
{: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 recovery-generate-key-pressed
{: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}
(navigation/navigate-to-cofx :keycard-onboarding-intro nil)))
(fx/defn begin-setup-pressed
{:events [:keycard.onboarding.intro.ui/begin-setup-pressed]}
{:events [:keycard.onboarding.intro.ui/begin-setup-pressed
:keycard.recovery.intro.ui/begin-recovery-pressed]}
[{:keys [db] :as cofx}]
(let [nfc-enabled? (get-in db [:hardwallet :nfc-enabled?])]
(let [nfc-enabled? (get-in db [:hardwallet :nfc-enabled?])
flow (get-in db [:hardwallet :flow])]
(fx/merge cofx
{:db (-> db
(assoc-in [:hardwallet :setup-step] :begin)
@ -636,8 +670,10 @@
(assoc-in [:hardwallet :on-card-read] :hardwallet/check-card-state)
(assoc-in [:hardwallet :pin :on-verified] nil))}
(if nfc-enabled?
(navigation/navigate-to-cofx :keycard-onboarding-start nil)
(navigation/navigate-to-cofx :keycard-onboarding-nfc-on nil)))))
(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 open-nfc-settings-pressed
{:events [:keycard.onboarding.nfc-on/open-nfc-settings-pressed]}
@ -647,16 +683,28 @@
(fx/defn on-check-nfc-enabled-success
{:events [:hardwallet.callback/check-nfc-enabled-success]}
[{:keys [db] :as cofx} nfc-enabled?]
(let [flow (get-in db [:hardwallet :flow])]
(fx/merge cofx
{:db (assoc-in db [:hardwallet :nfc-enabled?] nfc-enabled?)}
(when (and nfc-enabled?
(= (:view-id db)
:keycard-onboarding-nfc-on))
(navigation/navigate-to-cofx :keycard-onboarding-start nil))))
:keycard-nfc-on))
(if (= flow :import)
(navigation/navigate-to-cofx :keycard-recovery-start nil)
(navigation/navigate-to-cofx :keycard-onboarding-start nil))))))
(fx/defn success-button-pressed [cofx]
(navigation/navigate-to-cofx cofx :home 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 :home nil)))
(fx/defn change-pin-pressed
[{:keys [db] :as cofx}]
(let [pin-retry-counter (get-in db [:hardwallet :application-info :pin-retry-counter])
@ -854,8 +902,8 @@
(when card-connected?
(pair* password))
(if card-connected?
(navigation/navigate-to-cofx :keycard-onboarding-pairing nil)
(navigation/navigate-to-cofx :keycard-onboarding-connection-lost nil)))))
(navigation/navigate-to-cofx :keycard-pairing nil)
(navigation/navigate-to-cofx :keycard-connection-lost nil)))))
(fx/defn pair-code-next-button-pressed
{:events [:keycard.onboarding.pair.ui/input-submitted
@ -1192,6 +1240,7 @@
(assoc-in [:hardwallet :on-card-connected] :hardwallet/prepare-to-sign))}))))
(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])
@ -1206,18 +1255,18 @@
:pin pin
:on-success :hardwallet.callback/on-generate-and-load-key-success}})))
(fx/defn load-importing-multiaccount-screen
(fx/defn load-recovering-key-screen
{:events [:hardwallet/load-recovering-key-screen]}
[{:keys [db] :as cofx}]
(let [card-connected? (get-in db [:hardwallet :card-connected?])]
(fx/merge cofx
{:db (-> db
(assoc-in [:hardwallet :on-card-connected] :hardwallet/load-importing-multiaccount-screen)
(assoc-in [:hardwallet :setup-step] :importing-multiaccount))}
(assoc-in [:hardwallet :on-card-connected] :hardwallet/load-recovering-key-screen))}
(when card-connected?
(import-multiaccount))
(navigation/navigate-to-cofx (if card-connected?
:hardwallet-setup
:hardwallet-connect) nil))))
(dispatch-event :hardwallet/import-multiaccount))
(if card-connected?
(navigation/navigate-to-cofx :keycard-recovery-recovering nil)
(navigation/navigate-to-cofx :keycard-connection-lost nil)))))
; PIN enter steps:
; login - PIN is used to login
@ -1246,10 +1295,9 @@
(= default-pin (vector->string pin)))
(pin-enter-error :t/cannot-use-default-pin)
(and (= setup-step :import-multiaccount)
(= enter-step :import-multiaccount)
(and (= enter-step :import-multiaccount)
(= pin-code-length numbers-entered))
(load-importing-multiaccount-screen)
(load-recovering-key-screen)
(and (= enter-step :current)
(= pin-code-length numbers-entered))
@ -1338,7 +1386,7 @@
(assoc-in [:hardwallet :card-read-in-progress?] false))}
(when (and setup-running?
on-card-connected)
(navigation/navigate-to-cofx :hardwallet-connect nil)))))
(navigation/navigate-to-cofx :keycard-connection-lost nil)))))
(fx/defn begin-setup-button-pressed
[{:keys [db]}]
@ -1380,7 +1428,7 @@
(fx/defn process-error [{:keys [db] :as cofx} code error]
(if (tag-lost-exception? code error)
(navigation/navigate-to-cofx cofx :hardwallet-connect nil)
(navigation/navigate-to-cofx cofx :keycard-connection-lost nil)
{:db (assoc-in db [:hardwallet :setup-step] :error)}))
(fx/defn on-install-applet-and-init-card-error
@ -1424,19 +1472,24 @@
(set-multiaccount-pairing multiaccount pairing paired-on))
(when (= flow :recovery)
(proceed-with-generating-key))
(when (= flow :import)
(load-recovery-pin-screen))
(when (= flow :create)
(generate-mnemonic)))))
(fx/defn on-pair-error
[{:keys [db] :as cofx} {:keys [error code]}]
(log/debug "[hardwallet] pair error: " error)
(let [setup-step (get-in db [:hardwallet :setup-step])]
(let [setup-step (get-in db [:hardwallet :setup-step])
flow (get-in db [:hardwallet :flow])]
(fx/merge cofx
{:db (-> db
(assoc-in [:hardwallet :setup-error] (i18n/label :t/invalid-pairing-password))
(assoc-in [:hardwallet :on-card-connected] (if (= setup-step :pairing)
:hardwallet/load-pairing-screen
:hardwallet/pair)))}
(when (= flow :import)
(navigation/navigate-to-cofx :keycard-recovery-pair nil))
(when (not= setup-step :enter-pair-code)
(process-error code error)))))
@ -1531,7 +1584,7 @@
(fx/defn create-keycard-multiaccount
[{:keys [db] :as cofx}]
(let [{{:keys [multiaccount secrets]} :hardwallet} db
(let [{{:keys [multiaccount secrets flow]} :hardwallet} db
{:keys [whisper-public-key
wallet-address
encryption-public-key
@ -1551,24 +1604,31 @@
encryption-public-key
{:seed-backed-up? true
:login? true})
(navigation/navigate-to-cofx :keycard-welcome nil))))
(if (= flow :import)
(navigation/navigate-to-cofx :keycard-recovery-success nil)
(navigation/navigate-to-cofx :keycard-welcome nil)))))
(fx/defn on-generate-and-load-key-success
[{:keys [db random-guid-generator] :as cofx} data]
(let [multiaccount-data (js->clj data :keywordize-keys true)]
(let [account-data (js->clj data :keywordize-keys true)
flow (get-in db [:hardwallet :flow])]
(fx/merge cofx
{:db (-> db
(assoc-in [:hardwallet :multiaccount] (-> multiaccount-data
(assoc-in [:hardwallet :multiaccount] (-> account-data
(update :whisper-public-key #(str "0x" %))
(update :instance-uid #(get-in db [:hardwallet :multiaccount :instance-uid] %))))
(assoc-in [:hardwallet :application-info :key-uid] (:key-uid multiaccount-data))
(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))
(assoc-in [:hardwallet :on-card-connected] nil)
(update :hardwallet dissoc :recovery-phrase)
(update-in [:hardwallet :secrets] dissoc :pin :puk :password)
(assoc :node/on-ready :create-keycard-multiaccount)
(assoc :multiaccounts/new-installation-id (random-guid-generator))
(update-in [:hardwallet :secrets] dissoc :mnemonic))}
(node/initialize nil))))
(node/initialize nil)
(when-not (= flow :import)
(navigation/navigate-to-cofx :keycard-welcome nil)))))
(fx/defn on-generate-and-load-key-error
[{:keys [db] :as cofx} {:keys [error code]}]
@ -1581,14 +1641,15 @@
(fx/defn on-get-keys-success
[{:keys [db] :as cofx} data]
(let [{:keys [wallet-address encryption-public-key] :as multiaccount-data} (js->clj data :keywordize-keys true)
(let [{:keys [wallet-address encryption-public-key] :as account-data} (js->clj data :keywordize-keys true)
{:keys [photo-path name]} (get-in db [:multiaccounts/multiaccounts wallet-address])
instance-uid (get-in db [:hardwallet :application-info :instance-uid])]
(fx/merge cofx
{:db (-> db
(assoc-in [:hardwallet :pin :status] nil)
(assoc-in [:hardwallet :pin :login] [])
(assoc-in [:hardwallet :multiaccount] (update multiaccount-data :whisper-public-key #(str "0x" %)))
(assoc-in [:hardwallet :multiaccount] (update account-data :whisper-public-key #(str "0x" %)))
(assoc-in [:hardwallet :flow] nil)
(update :multiaccounts/login assoc
:password encryption-public-key
:address wallet-address
@ -1602,7 +1663,8 @@
[{:keys [db] :as cofx} error]
(log/debug "[hardwallet] get keys error: " error)
(let [tag-was-lost? (= "Tag was lost." (:error error))
instance-uid (get-in db [:hardwallet :application-info :instance-uid])]
instance-uid (get-in db [:hardwallet :application-info :instance-uid])
flow (get-in db [:hardwallet :flow])]
(if tag-was-lost?
(fx/merge cofx
{:db (assoc-in db [:hardwallet :pin :status] nil)
@ -1614,8 +1676,11 @@
{:hardwallet/get-application-info {:pairing (get-pairing db instance-uid)}
:db (update-in db [:hardwallet :pin] merge {:status :error
:login []
:import-multiaccount []
:error-label :t/pin-mismatch})}
(navigation/navigate-to-cofx :enter-pin-login nil))
(if (= flow :import)
(navigation/navigate-to-cofx :keycard-recovery-pin nil)
(navigation/navigate-to-cofx :enter-pin-login nil)))
(show-wrong-keycard-alert cofx true)))))
(fx/defn send-transaction-with-signature

View File

@ -228,9 +228,8 @@
(= (get-in cofx [:db :view-id])
:create-multiaccount))
(defn finishing-hardwallet-setup? [cofx]
(= (get-in cofx [:db :view-id])
:keycard-welcome))
(defn- keycard-setup? [cofx]
(boolean (get-in cofx [:db :hardwallet :flow])))
(fx/defn initialize-multiaccount [{:keys [db] :as cofx} address]
(let [stored-pns (:push-notifications/stored db)]
@ -246,7 +245,7 @@
(stickers/init-stickers-packs)
(multiaccounts.update/update-sign-in-time)
#(when-not (or (creating-multiaccount? %)
(finishing-hardwallet-setup? %))
(keycard-setup? %))
(login-only-events % address stored-pns)))))
(re-frame/reg-fx

View File

@ -135,6 +135,16 @@
:dispatch [:multiaccounts.logout.ui/logout-confirmed]}))
(fx/defn finish-keycard-setup
[{:keys [db] :as cofx}]
(let [flow (get-in db [:hardwallet :flow])]
(when flow
(fx/merge cofx
{:db (update db :hardwallet dissoc :flow)}
(if (= :import flow)
(navigation/navigate-to-cofx :keycard-recovery-success nil)
(navigation/navigate-to-cofx :home nil))))))
(fx/defn user-login-callback
{:events [:multiaccounts.login.callback/login-success]
:interceptors [(re-frame/inject-cofx :web3/get-web3)
@ -173,6 +183,7 @@
(protocol/initialize-protocol)
(universal-links/process-stored-event)
(chaos-mode/check-chaos-mode)
(finish-keycard-setup)
(when-not platform/desktop?
(initialize-wallet)))
(multiaccount-and-db-password-do-not-match cofx error)))))

View File

@ -18,9 +18,11 @@
:keycard-lock (js-require/js-require "./resources/images/ui/keycard-lock.png")
:keycard (js-require/js-require "./resources/images/ui/keycard.png")
:keycard-logo (js-require/js-require "./resources/images/ui/keycard-logo.png")
:keycard-empty (js-require/js-require "./resources/images/ui/keycard-empty.png")
:keycard-phone (js-require/js-require "./resources/images/ui/keycard-phone.png")
:keycard-connection (js-require/js-require "./resources/images/ui/keycard-connection.png")
:keycard-nfc-on (js-require/js-require "./resources/images/ui/keycard-nfc-on.png")
:status-logo (js-require/js-require "./resources/images/ui/status-logo.png")
:hold-card-animation (js-require/js-require "./resources/images/ui/hold-card-animation.gif")
:warning-sign (js-require/js-require "./resources/images/ui/warning-sign.png")
:phone-nfc-on (js-require/js-require "./resources/images/ui/phone-nfc-on.png")

View File

@ -78,3 +78,18 @@
:hardwallet-application-info-error
(fn [db]
(get-in db [:hardwallet :application-info-error])))
(re-frame/reg-sub
:hardwallet-multiaccount
(fn [db]
(get-in db [:hardwallet :multiaccount])))
(re-frame/reg-sub
:hardwallet-multiaccount-wallet-address
(fn [db]
(str "0x" (get-in db [:hardwallet :multiaccount-wallet-address]))))
(re-frame/reg-sub
:hardwallet-multiaccount-whisper-public-key
(fn [db]
(str "0x" (get-in db [:hardwallet :multiaccount-whisper-public-key]))))

View File

@ -1,7 +1,8 @@
(ns status-im.ui.screens.keycard.onboarding.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [status-im.ui.components.react :as react]
[status-im.ui.screens.keycard.onboarding.styles :as styles]
[status-im.ui.screens.keycard.styles :as styles]
[status-im.ui.screens.keycard.views :as views]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.icons.vector-icons :as vector-icons]
@ -223,113 +224,11 @@
{:on-press #(re-frame/dispatch [:keycard.onboarding.puk-code.ui/next-pressed])
:forward? true}]]]]]]))
(defn- loading [title-label]
[react/view styles/container
[toolbar/toolbar {:transparent? true
:style {:margin-top 32}}
nil nil]
[react/view {:flex 1
:flex-direction :column
:justify-content :space-between
:align-items :center}
[react/view {:flex-direction :column
:align-items :center}
[react/view {:margin-top 16}
[react/activity-indicator {:animating true
:size :large}]]
[react/view {:margin-top 16}
[react/text {:style {:typography :header
:text-align :center}}
(i18n/label title-label)]]
[react/view {:margin-top 16
:width 311}
[react/text {:style {:color colors/gray
:text-align :center}}
(i18n/label :t/this-will-take-few-seconds)]]]
[react/view {:flex 1
:align-items :center
:justify-content :center}
[react/image {:source (resources/get-image :keycard-phone)
:resize-mode :center
:style {:width 160
:height 170}}]
[react/view {:margin-top 10}
[react/text {:style {:text-align :center
:color colors/gray}}
(i18n/label :t/hold-card)]]]]])
(defn preparing []
(loading :t/keycard-onboarding-preparing-header))
(defn pairing []
(loading :t/keycard-onboarding-pairing-header))
(views/loading :t/keycard-onboarding-preparing-header))
(defn finishing []
(loading :t/keycard-onboarding-finishing-header))
(defn connection-lost []
[react/view {:flex 1
:justify-content :center
:align-items :center
:background-color "rgba(4, 4, 15, 0.4)"}
[react/view {:background-color colors/white
:height 478
:width "85%"
:border-radius 16
:flex-direction :column
:justify-content :space-between
:align-items :center}
[react/view {:margin-top 32}
[react/text {:style {:typography :title-bold
:text-align :center}}
(i18n/label :t/connection-with-the-card-lost)]
[react/view {:margin-top 16}
[react/text {:style {:color colors/gray
:text-align :center}}
(i18n/label :t/connection-with-the-card-lost-text)]]]
[react/view {:margin-top 16}
[react/image {:source (resources/get-image :keycard-connection)
:resize-mode :center
:style {:width 200
:height 200}}]]
[react/view {:margin-bottom 43}
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:keycard.onboarding.connection-lost.ui/cancel-setup-pressed])}
[react/text {:style {:color colors/red
:text-align :center}}
(i18n/label :t/cancel-keycard-setup)]]]]])
(defn nfc-on []
[react/view styles/container
[toolbar/toolbar
{:transparent? true
:style {:margin-top 32}}
toolbar/default-nav-back
nil]
[react/view {:flex 1
:flex-direction :column
:justify-content :space-between
:align-items :center}
[react/view {:flex-direction :column
:align-items :center}
[react/view {:margin-top 16}
[react/text {:style {:typography :header}}
(i18n/label :t/turn-nfc-on)]]]
[react/view
[react/view {:align-items :center
:justify-content :center}
[react/image {:source (resources/get-image :keycard-nfc-on)
:style {:width 170
:height 170}}]]]
[react/view
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:keycard.onboarding.nfc-on/open-nfc-settings-pressed])}
[react/text {:style {:font-size 15
:line-height 22
:color colors/blue
:text-align :center
:margin-bottom 30}}
(i18n/label :t/open-nfc-settings)]]]]])
(views/loading :t/keycard-onboarding-finishing-header))
(defview pin []
(letsubs [pin [:hardwallet/pin]
@ -360,7 +259,7 @@
(i18n/label (if (= :original enter-step)
:t/intro-wizard-title4
:t/intro-wizard-title5))]]]
[status-im.ui.screens.hardwallet.pin.views/pin-view
[pin.views/pin-view
{:pin pin
:status status
:error-label error-label
@ -496,62 +395,6 @@
:disabled? (empty? input-word)
:forward? true}]]]]])))
(defview pair []
(letsubs [pair-code [:hardwallet-pair-code]
error [:hardwallet-setup-error]
width [:dimensions/window-width]
ref (atom nil)]
[react/view styles/container
[toolbar/toolbar
{:transparent? true
:style {:margin-top 32}}
[toolbar/nav-text
{:handler #(re-frame/dispatch [:keycard.onboarding.ui/cancel-pressed])
:style {:padding-left 21}}
(i18n/label :t/cancel)]
[react/text {:style {:color colors/gray}}
(i18n/label :t/step-i-of-n {:step "3"
:number "3"})]]
[react/view {:flex 1
:flex-direction :column
:justify-content :space-between
:align-items :center}
[react/view {:flex-direction :column
:align-items :center}
[react/view {:margin-top 16}
[react/text {:style {:typography :header
:text-align :center}}
(i18n/label :t/enter-pair-code)]]
[react/view {:margin-top 16
:width "85%"
:align-items :center}
[react/text {:style {:color colors/gray
:text-align :center}}
(i18n/label :t/enter-pair-code-description)]]]
[react/view
[text-input/text-input-with-label
{:on-change-text #(re-frame/dispatch [:keycard.onboarding.pair.ui/input-changed %])
:auto-focus true
:on-submit-editing #(re-frame/dispatch [:keycard.onboarding.pair.ui/input-submitted])
:error error
:placeholder nil
:container {:background-color :white}
:style {:background-color :white
:height 24
:typography :header}}]]
[react/view {:flex-direction :row
:justify-content :space-between
:align-items :center
:width "100%"
:height 86}
[react/view]
[react/view {:margin-right 20}
[components.common/bottom-button
{:on-press #(re-frame/dispatch [:keycard.onboarding.pair.ui/next-pressed])
:label (i18n/label :t/pair-card)
:disabled? (empty? pair-code)
:forward? true}]]]]]))
;NOTE temporary screen, to be removed after Recovery will be implemented
(defview enter-mnemonic []
(letsubs [mnemonic [:hardwallet-mnemonic]]

View File

@ -0,0 +1,320 @@
(ns status-im.ui.screens.keycard.recovery.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [status-im.ui.components.react :as react]
[status-im.ui.screens.keycard.styles :as styles]
[status-im.ui.screens.keycard.views :as views]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.i18n :as i18n]
[re-frame.core :as re-frame]
[status-im.react-native.resources :as resources]
[status-im.ui.components.common.common :as components.common]
[status-im.ui.components.text-input.view :as text-input]
[status-im.utils.gfycat.core :as gfy]
[status-im.utils.identicon :as identicon]
[status-im.utils.core :as utils.core]
[status-im.ui.screens.hardwallet.pin.views :as pin.views]
[status-im.ui.components.tooltip.views :as tooltip]))
(defn intro []
[react/view styles/container
[toolbar/toolbar
{:transparent? true
:style {:margin-top 32}}
toolbar/default-nav-back
nil]
[react/view {:flex 1
:flex-direction :column
:justify-content :space-between
:align-items :center}
[react/view {:flex-direction :column
:align-items :center}
[react/view {:margin-top 16
:width 311}
[react/text {:style {:typography :header
:text-align :center}}
(i18n/label :t/keycard-recovery-intro-header)]]
[react/view {:margin-top 16
:width 311}
[react/text {:style {:font-size 15
:line-height 22
:color colors/gray
:text-align :center}}
(i18n/label :t/keycard-recovery-intro-text)]]
[react/view {:margin-top 33}
[react/touchable-highlight {:on-press #(.openURL (react/linking) "https://keycard.status.im")}
[react/view {:flex-direction :row
:align-items :center
:justify-content :center}
[react/text {:style {:text-align :center
:color colors/blue}}
(i18n/label :t/learn-more-about-keycard)]
[vector-icons/icon :tiny-icons/tiny-external {:color colors/blue
:container-style {:margin-left 5}}]]]]]
[react/view
[react/view {:align-items :center
:justify-content :center}
[react/image {:source (resources/get-image :keycard)
:style {:width 144
:height 114}}]]]
[react/view {:margin-bottom 50}
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:keycard.recovery.intro.ui/begin-recovery-pressed])}
[react/view {:background-color colors/gray-background
:align-items :center
:justify-content :center
:flex-direction :row
:width 133
:height 44
:border-radius 10}
[react/text {:style {:color colors/blue}}
(i18n/label :t/keycard-recovery-intro-button-text)]]]]]])
(defn start []
[react/view styles/container
[toolbar/toolbar
{:transparent? true
:style {:margin-top 32}}
toolbar/default-nav-back
nil]
[react/view {:flex 1
:flex-direction :column
:justify-content :space-between
:align-items :center}
[react/view {:flex-direction :column
:align-items :center}
[react/view {:margin-top 16}
[react/text {:style {:typography :header
:text-align :center}}
(i18n/label :t/keycard-onboarding-start-header)]]
[react/view {:margin-top 16
:width 311}
[react/text {:style {:font-size 15
:line-height 22
:color colors/gray
:text-align :center}}
(i18n/label :t/keycard-onboarding-start-text)]]]
[react/view {:flex 1
:flex-direction :column
:align-items :center
:justify-content :center}
[react/view
[react/image {:source (resources/get-image :keycard-phone)
:resize-mode :center
:style {:width 160
:height 170}}]]]]])
(defn pairing []
(views/loading :t/keycard-onboarding-pairing-header))
(defview pin []
(letsubs [pin [:hardwallet/pin]
status [:hardwallet/pin-status]
error-label [:hardwallet/pin-error-label]]
[react/view styles/container
[toolbar/toolbar
{:transparent? true
:style {:margin-top 32}}
[toolbar/nav-text
{:handler #(re-frame/dispatch [:keycard.onboarding.ui/cancel-pressed])
:style {:padding-left 21}}
(i18n/label :t/cancel)]
[react/text {:style {:color colors/gray}}
(i18n/label :t/step-i-of-n {:number 2
:step 2})]]
[react/view {:flex 1
:flex-direction :column
:justify-content :space-between
:align-items :center}
[react/view {:flex-direction :column
:align-items :center}
[react/view {:margin-top 16}
[react/text {:style {:typography :header
:text-align :center}}
(i18n/label :t/enter-your-code)]]]
[pin.views/pin-view
{:pin pin
:status status
:error-label error-label
:step :import-multiaccount}]]]))
(defview pair []
(letsubs [pair-code [:hardwallet-pair-code]
error [:hardwallet-setup-error]
width [:dimensions/window-width]
ref (atom nil)]
[react/view styles/container
[toolbar/toolbar
{:transparent? true
:style {:margin-top 32}}
[toolbar/nav-text
{:handler #(re-frame/dispatch [:keycard.onboarding.ui/cancel-pressed])
:style {:padding-left 21}}
(i18n/label :t/cancel)]
[react/text {:style {:color colors/gray}}
(i18n/label :t/step-i-of-n {:number 2
:step 1})]]
[react/view {:flex 1
:flex-direction :column
:justify-content :space-between
:align-items :center}
[react/view {:flex-direction :column
:align-items :center}
[react/view {:margin-top 16}
[react/text {:style {:typography :header
:text-align :center}}
(i18n/label :t/enter-pair-code)]]
[react/view {:margin-top 16
:width "85%"
:align-items :center}
[react/text {:style {:color colors/gray
:text-align :center}}
(i18n/label :t/enter-pair-code-description)]]]
[react/view
[text-input/text-input-with-label
{:on-change-text #(re-frame/dispatch [:keycard.onboarding.pair.ui/input-changed %])
:auto-focus true
:on-submit-editing #(re-frame/dispatch [:keycard.onboarding.pair.ui/input-submitted])
:placeholder nil
:container {:background-color :white}
:style {:background-color :white
:height 24
:typography :header}}]
[react/view {:margin-top 5
:width 250}
[tooltip/tooltip error]]]
[react/view {:flex-direction :row
:justify-content :space-between
:align-items :center
:width "100%"
:height 86}
[react/view]
[react/view {:margin-right 20}
[components.common/bottom-button
{:on-press #(re-frame/dispatch [:keycard.onboarding.pair.ui/next-pressed])
:label (i18n/label :t/pair-card)
:disabled? (empty? pair-code)
:forward? true}]]]]]))
(defn recovering []
(views/loading :t/recovering-key))
(defview success []
(letsubs [address [:hardwallet-multiaccount-wallet-address]
whisper-public-key [:hardwallet-multiaccount-whisper-public-key]]
[react/view styles/container
[toolbar/toolbar
{:transparent? true
:style {:margin-top 32}}
nil
nil]
[react/view {:flex 1
:flex-direction :column
:justify-content :space-between
:align-items :center}
[react/view {:flex-direction :column
:align-items :center}
[react/view {:margin-top 16}
[react/text {:style {:typography :header
:text-align :center}}
(i18n/label :t/keycard-recovery-success-header)]]]
[react/view {:flex-direction :column
:flex 1
:justify-content :center
:align-items :center}
[react/view {:margin-horizontal 16
:flex-direction :column}
[react/view {:justify-content :center
:align-items :center
:margin-bottom 11}
[react/image {:source {:uri (identicon/identicon whisper-public-key)}
:style {:width 61
:height 61
:border-radius 30
:border-width 1
:border-color (colors/alpha colors/black 0.1)}}]]
[react/text {:style {:text-align :center
:color colors/black
:font-weight "500"}
:number-of-lines 1
:ellipsize-mode :middle}
(gfy/generate-gfy whisper-public-key)]
[react/text {:style {:text-align :center
:margin-top 4
:color colors/gray
:font-family "monospace"}
:number-of-lines 1
:ellipsize-mode :middle}
(utils.core/truncate-str address 14 true)]]]
[react/view {:margin-bottom 50}
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:keycard.recovery.success/finish-pressed])}
[react/view {:background-color colors/gray-background
:align-items :center
:justify-content :center
:flex-direction :row
:width 133
:height 44
:border-radius 10}
[react/text {:style {:color colors/blue}}
(i18n/label :t/finish)]]]]]]))
(defview no-key []
(letsubs [card-state [:hardwallet-card-state]]
[react/view styles/container
[toolbar/toolbar
{:transparent? true
:style {:margin-top 32}}
nil
nil]
[react/view {:flex 1
:flex-direction :column
:justify-content :space-between
:align-items :center}
[react/view {:flex-direction :column
:align-items :center}
[react/view {:margin-top 16}
[react/text {:style {:typography :header
:text-align :center}}
(i18n/label :t/keycard-recovery-no-key-header)]]
[react/view {:margin-top 16
:width "85%"
:align-items :center}
[react/text {:style {:color colors/gray
:text-align :center}}
(i18n/label :t/keycard-recovery-no-key-text)]]]
[react/view {:flex-direction :column
:flex 1
:justify-content :center
:align-items :center}
[react/view {:margin-horizontal 16
:flex-direction :column}
[react/view {:align-items :center
:justify-content :center}
(if (= card-state :init)
[react/image {:source (resources/get-image :keycard)
:style {:width 144
:height 114}}]
[react/image {:source (resources/get-image :keycard-empty)
:style {:width 165
:height 110}}])]]]
[react/view {:margin-bottom 50}
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:keycard.recovery.no-key.ui/generate-key-pressed])}
[react/view {:background-color colors/gray-background
:align-items :center
:justify-content :center
:flex-direction :row
:width 190
:height 44
:border-radius 10}
[react/text {:style {:color colors/blue}}
(i18n/label :t/generate-new-key)]]]
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:keycard.onboarding.ui/cancel-pressed])}
[react/text {:style {:text-align :center
:padding-top 27
:color colors/blue}}
(i18n/label :t/cancel)]]]]]))

View File

@ -1,4 +1,4 @@
(ns status-im.ui.screens.keycard.onboarding.styles
(ns status-im.ui.screens.keycard.styles
(:require [status-im.ui.components.colors :as colors]))
(def container

View File

@ -0,0 +1,140 @@
(ns status-im.ui.screens.keycard.views
(:require [status-im.ui.components.react :as react]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.screens.keycard.styles :as styles]
[status-im.i18n :as i18n]
[status-im.ui.components.colors :as colors]
[status-im.react-native.resources :as resources]
[re-frame.core :as re-frame]
[status-im.ui.components.common.common :as components.common]
[status-im.ui.components.status-bar.view :as status-bar]))
(defn connection-lost []
[react/view {:flex 1
:justify-content :center
:align-items :center
:background-color colors/gray-transparent-40}
[react/view {:background-color colors/white
:height 478
:width "85%"
:border-radius 16
:flex-direction :column
:justify-content :space-between
:align-items :center}
[react/view {:margin-top 32}
[react/text {:style {:typography :title-bold
:text-align :center}}
(i18n/label :t/connection-with-the-card-lost)]
[react/view {:margin-top 16}
[react/text {:style {:color colors/gray
:text-align :center}}
(i18n/label :t/connection-with-the-card-lost-text)]]]
[react/view {:margin-top 16}
[react/image {:source (resources/get-image :keycard-connection)
:resize-mode :center
:style {:width 200
:height 200}}]]
[react/view {:margin-bottom 43}
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:keycard.onboarding.connection-lost.ui/cancel-setup-pressed])}
[react/text {:style {:color colors/red
:text-align :center}}
(i18n/label :t/cancel-keycard-setup)]]]]])
(defn nfc-on []
[react/view styles/container
[toolbar/toolbar
{:transparent? true
:style {:margin-top 32}}
toolbar/default-nav-back
nil]
[react/view {:flex 1
:flex-direction :column
:justify-content :space-between
:align-items :center}
[react/view {:flex-direction :column
:align-items :center}
[react/view {:margin-top 16}
[react/text {:style {:typography :header}}
(i18n/label :t/turn-nfc-on)]]]
[react/view
[react/view {:align-items :center
:justify-content :center}
[react/image {:source (resources/get-image :keycard-nfc-on)
:style {:width 170
:height 170}}]]]
[react/view
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:keycard.onboarding.nfc-on/open-nfc-settings-pressed])}
[react/text {:style {:font-size 15
:line-height 22
:color colors/blue
:text-align :center
:margin-bottom 30}}
(i18n/label :t/open-nfc-settings)]]]]])
(defn loading [title-label]
[react/view styles/container
[toolbar/toolbar {:transparent? true
:style {:margin-top 32}}
nil nil]
[react/view {:flex 1
:flex-direction :column
:justify-content :space-between
:align-items :center}
[react/view {:flex-direction :column
:align-items :center}
[react/view {:margin-top 16}
[react/activity-indicator {:animating true
:size :large}]]
[react/view {:margin-top 16}
[react/text {:style {:typography :header
:text-align :center}}
(i18n/label title-label)]]
[react/view {:margin-top 16
:width 311}
[react/text {:style {:font-size 15
:line-height 22
:color colors/gray
:text-align :center}}
(i18n/label :t/this-will-take-few-seconds)]]]
[react/view {:flex 1
:align-items :center
:justify-content :center}
[react/image {:source (resources/get-image :keycard-phone)
:resize-mode :center
:style {:width 160
:height 170}}]
[react/view {:margin-top 10}
[react/text {:style {:text-align :center
:color colors/gray
:font-size 15
:line-height 22}}
(i18n/label :t/hold-card)]]]]])
(defn pairing []
(loading :t/keycard-onboarding-pairing-header))
(defn welcome []
[react/view {:flex 1
:justify-content :space-between
:align-items :center
:flex-direction :column}
[react/view]
[react/view {:align-items :center}
[react/image {:source (resources/get-image :status-logo)
:resize-mode :center
:style {:width 64
:height 64}}]
[react/view {:margin-top 24}
[react/i18n-text {:style {:typography :header
:text-align :center}
:key :welcome-to-status}]]
[react/view {:margin-top 16}
[react/i18n-text {:style {:text-align :center
:margin-horizontal 39
:color colors/gray}
:key :welcome-screen-text}]]]
[react/view {:align-items :center :margin-bottom 52}
[react/activity-indicator {:size :large
:animating true}]]])

View File

@ -14,20 +14,26 @@
:enter-pin-login
:hardwallet-setup
:hardwallet-success
:keycard-connection-lost
:keycard-nfc-on
:keycard-pairing
:keycard-onboarding-intro
:keycard-onboarding-start
:keycard-onboarding-puk-code
:keycard-onboarding-preparing
:keycard-onboarding-pairing
:keycard-onboarding-finishing
:keycard-onboarding-connection-lost
:keycard-onboarding-pin
:keycard-onboarding-pair
:keycard-onboarding-nfc-on
:keycard-onboarding-recovery-phrase
:keycard-onboarding-recovery-phrase-confirm-word1
:keycard-onboarding-recovery-phrase-confirm-word2
:keycard-recovery-enter-mnemonic})
:keycard-recovery-enter-mnemonic
:keycard-recovery-intro
:keycard-recovery-start
:keycard-recovery-pair
:keycard-recovery-recovering
:keycard-recovery-success
:keycard-recovery-no-key
:keycard-recovery-pin})
(defn login-stack [view-id]
{:name :login-stack
@ -55,19 +61,25 @@
(update :screens conj
:intro
:intro-wizard
:keycard-connection-lost
:keycard-nfc-on
:keycard-pairing
:keycard-onboarding-intro
:keycard-onboarding-start
:keycard-onboarding-puk-code
:keycard-onboarding-preparing
:keycard-onboarding-pairing
:keycard-onboarding-finishing
:keycard-onboarding-connection-lost
:keycard-onboarding-pin
:keycard-onboarding-pair
:keycard-onboarding-nfc-on
:keycard-onboarding-recovery-phrase
:keycard-onboarding-recovery-phrase-confirm-word1
:keycard-onboarding-recovery-phrase-confirm-word2
:keycard-recovery-enter-mnemonic)
:keycard-recovery-enter-mnemonic
:keycard-recovery-intro
:keycard-recovery-start
:keycard-recovery-pair
:keycard-recovery-recovering
:keycard-recovery-success
:keycard-recovery-no-key
:keycard-recovery-pin)
(assoc :name :intro-stack)
(assoc :config {:initialRouteName :intro})))

View File

@ -30,6 +30,8 @@
[status-im.ui.screens.hardwallet.setup.views :as hardwallet.setup]
[status-im.ui.screens.hardwallet.success.views :as hardwallet.success]
[status-im.ui.screens.keycard.onboarding.views :as keycard.onboarding]
[status-im.ui.screens.keycard.recovery.views :as keycard.recovery]
[status-im.ui.screens.keycard.views :as keycard]
[status-im.ui.screens.help-center.views :as help-center]
[status-im.ui.screens.home.views :as home]
[status-im.ui.screens.intro.views :as intro]
@ -87,16 +89,22 @@
:keycard-onboarding-start keycard.onboarding/start
:keycard-onboarding-puk-code keycard.onboarding/puk-code
:keycard-onboarding-preparing keycard.onboarding/preparing
:keycard-onboarding-pairing keycard.onboarding/pairing
:keycard-onboarding-finishing keycard.onboarding/finishing
:keycard-onboarding-connection-lost keycard.onboarding/connection-lost
:keycard-onboarding-pin keycard.onboarding/pin
:keycard-onboarding-pair keycard.onboarding/pair
:keycard-onboarding-nfc-on keycard.onboarding/nfc-on
:keycard-onboarding-recovery-phrase keycard.onboarding/recovery-phrase
:keycard-onboarding-recovery-phrase-confirm-word1 keycard.onboarding/recovery-phrase-confirm-word
:keycard-onboarding-recovery-phrase-confirm-word2 keycard.onboarding/recovery-phrase-confirm-word
:keycard-recovery-enter-mnemonic keycard.onboarding/enter-mnemonic
:keycard-pairing keycard/pairing
:keycard-nfc-on keycard/nfc-on
:keycard-connection-lost keycard/connection-lost
:keycard-recovery-intro keycard.recovery/intro
:keycard-recovery-start keycard.recovery/start
:keycard-recovery-pair keycard.recovery/pair
:keycard-recovery-recovering keycard.recovery/recovering
:keycard-recovery-success keycard.recovery/success
:keycard-recovery-no-key keycard.recovery/no-key
:keycard-recovery-pin keycard.recovery/pin
:home home/home-wrapper
:chat chat/chat
:select-chat chat/select-chat
@ -172,7 +180,7 @@
:keycard-settings hardwallet.settings/keycard-settings
:mobile-network-settings mobile-network-settings/mobile-network-settings
:welcome [:modal home/welcome]
:keycard-welcome [:modal home/welcome]})
:keycard-welcome keycard/welcome})
(defn get-screen [screen]
(get all-screens screen #(throw (str "Screen " screen " is not defined."))))

View File

@ -926,6 +926,7 @@
"reset-card-description": "This operation will reset card to initial state. It will erase all card data including private keys. Operation is not reversible.",
"unpair-card": "Unpair card",
"pair-card": "Pair card",
"pair-this-card": "Pair this card",
"card-unpaired": "Card has been unpaired from current device",
"card-reseted": "Card has been reseted",
"unpair-card-confirmation": "This operation will unpair card from current device. Requires PIN authorization. Do you want to proceed?",
@ -951,6 +952,7 @@
"complete-exclamation": "Complete!",
"complete-hardwallet-setup": "This card is now an essential part your multiaccount security. Transactions can't be sent without it.",
"okay": "Okay",
"dismiss": "Dismiss",
"initialization": "Initialization",
"puk-and-pair-codes": "PUK and pair codes",
"pairing": "Pairing",
@ -1222,9 +1224,30 @@
"keycard-onboarding-recovery-phrase-header": "Backup “Seed” phrase",
"keycard-onboarding-recovery-phrase-text": "For your eyes only. This is the magical seed used to generate your key.",
"keycard-onboarding-recovery-phrase-description": "With this Seed phrase you can always get your key back. Write the Seed phrase down. Keep it safe, offline, and separate from this device.",
"keycard-recovery-intro-header": "Recover a key stored on keycard",
"keycard-recovery-intro-text": "If you generated a key using a keycard before and now want to use this key on this device",
"keycard-recovery-intro-button-text": "Begin recovery",
"keycard-recovery-success-header": "Your key has been\n successfully recovered",
"keycard-recovery-no-key-header": "Theres nothing to \nrecover here",
"keycard-recovery-no-key-text": "Your Keycard has no key stored on it. In order to use it, generate a new key and choose your Keycard to store the key",
"keycard-recovery-phrase-confirmation-title": "Written the Seed phrase down?",
"keycard-recovery-phrase-confirmation-text": "You cannot do this later. Without the Seed phrase you will not be able to access your key or any assets associated with it if you loose your device.",
"keycard-recovery-phrase-confirm-header": "Confirm “Seed” phrase",
"keycard-cancel-setup-title": "Dangerous operation",
"keycard-cancel-setup-text": "This will cancel keycard setup. It's highly recommended to finish the setup in order to use keycard. Do you really want to cancel?"
"keycard-cancel-setup-text": "This will cancel keycard setup. It's highly recommended to finish the setup in order to use keycard. Do you really want to cancel?",
"recovering-key": "Recovering key...",
"generate-new-key": "Generate a new key",
"enter-your-code": "Enter your 6-digit code",
"finish": "Finish",
"welcome-screen-text": "Set up your wallet, invite friends to chat\n and browse popular dapps!",
"blank-keycard-title": "Looks like youve tapped \na blank keycard",
"blank-keycard-text": "You can proceed with your keycard once you've generated your keys and name",
"wrong-keycard-title": "Looks like youve tapped \na wrong keycard",
"wrong-keycard-text": "The Keycard you tapped is not associated with this phone",
"unpaired-keycard-title": "Looks like your card has been unpaired",
"unpaired-keycard-text": "The Keycard you tapped is not associated with this phone",
"not-keycard-title": "Not a Keycard",
"not-keycard-text": "The card you used is not a Keycard. You need to purchase a Keycard to use it",
"recover-key": "Recover key",
"remember-me": "Remember me"
}