Add pin screen for new wallet accounts for Keycard

Signed-off-by: Vitaliy Vlasov <siphiuel@gmail.com>
This commit is contained in:
Vitaliy Vlasov 2019-11-14 12:43:32 +02:00
parent 4096487637
commit acaea38551
No known key found for this signature in database
GPG Key ID: A7D57C347F2B2964
15 changed files with 189 additions and 73 deletions

View File

@ -140,6 +140,7 @@ var TopLevel = {
"exec" : function () {},
"execute" : function () {},
"exists" : function () {},
"exportKeyWithPath" : function () {},
"extPost" : function () {},
"extractGroupMembershipSignatures" : function () {},
"identicon": function() {},

View File

@ -38,7 +38,7 @@
"react-native-screens": "^1.0.0-alpha.23",
"react-native-shake": "^3.3.1",
"react-native-splash-screen": "^3.2.0",
"react-native-status-keycard": "^2.5.14",
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#v2.5.17",
"react-native-svg": "^9.8.4",
"react-native-touch-id": "^4.4.1",
"react-native-webview": "^6.11.1",

View File

@ -4900,10 +4900,9 @@ react-native-splash-screen@^3.2.0:
resolved "https://registry.yarnpkg.com/react-native-splash-screen/-/react-native-splash-screen-3.2.0.tgz#d47ec8557b1ba988ee3ea98d01463081b60fff45"
integrity sha512-Ls9qiNZzW/OLFoI25wfjjAcrf2DZ975hn2vr6U9gyuxi2nooVbzQeFoQS5vQcbCt9QX5NY8ASEEAtlLdIa6KVg==
react-native-status-keycard@^2.5.14:
version "2.5.14"
resolved "https://registry.yarnpkg.com/react-native-status-keycard/-/react-native-status-keycard-2.5.14.tgz#105ac4642ae3df777b87020dd5d484445fff46ba"
integrity sha512-qt8+BcDMwtjhAwVahF5WryeLRU0auUcYrRhCci+O6rX/Roz0a+NHZ8a23NAducvNco7uOBuleYL7yyhMbwxXQw==
"react-native-status-keycard@git+https://github.com/status-im/react-native-status-keycard.git#v2.5.17":
version "2.5.17"
resolved "git+https://github.com/status-im/react-native-status-keycard.git#8fb12850d72918d3e89e4fcfc8fa699c2ce3f203"
react-native-svg@^9.8.4:
version "9.11.1"

View File

@ -173,6 +173,14 @@
(then #(re-frame/dispatch [:hardwallet.callback/on-remove-key-success %]))
(catch #(re-frame/dispatch [:hardwallet.callback/on-remove-key-error (error-object->map %)]))))
(defn export-key
[{:keys [pin pairing path]}]
(log/debug "[keycard] export-key pairing:" pairing "pin:" pin "path:" path)
(.. keycard
(exportKeyWithPath pairing pin path)
(then #(re-frame/dispatch [:hardwallet.callback/on-export-key-success %]))
(catch #(re-frame/dispatch [:hardwallet.callback/on-export-key-error (error-object->map %)]))))
(defn unpair-and-delete
[{:keys [pin pairing]}]
(log/debug "[keycard] unpair-and-delete")

View File

@ -4,6 +4,7 @@
[status-im.multiaccounts.create.core :as multiaccounts.create]
[status-im.multiaccounts.logout.core :as multiaccounts.logout]
[status-im.ethereum.core :as ethereum]
[status-im.ui.components.colors :as colors]
[status-im.ethereum.mnemonic :as mnemonic]
[status-im.i18n :as i18n]
[status-im.ui.screens.navigation :as navigation]
@ -972,6 +973,55 @@
(navigation/navigate-to-cofx :keycard-connection-lost nil))
(show-wrong-keycard-alert 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
(clear-on-card-connected))))
(def pin-mismatch-error #"Unexpected error SW, 0x63C\d+")
(fx/defn 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-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)}}
(set-on-card-connected :wallet.accounts/generate-new-keycard-account)
(navigation/navigate-to-cofx :keycard-connection-lost nil))
(re-matches 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)
(get-application-info (get-pairing db) nil))
:else (show-wrong-keycard-alert cofx true))))
(fx/defn on-delete-success
[{:keys [db] :as cofx}]
(let [key-uid (get-in db [:multiaccount :key-uid])]
@ -1131,22 +1181,12 @@
:error-label :t/puk-mismatch
:enter-step :puk
:puk []})}))
(fx/defn 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}}))
(defn- tag-lost-exception? [code error]
(or
(= code "android.nfc.TagLostException")
(= error "Tag was lost.")))
(def pin-mismatch-error #"Unexpected error SW, 0x63C\d+")
(fx/defn on-verify-pin-success
[{:keys [db] :as cofx}]
(let [on-verified (get-in db [:hardwallet :pin :on-verified])
@ -1166,32 +1206,34 @@
(defn on-verify-pin-error
[{:keys [db] :as cofx} error]
(let [tag-was-lost? (= "Tag was lost." (:error error))
setup? (boolean (get-in db [:hardwallet :setup-step]))]
setup? (boolean (get-in db [:hardwallet :setup-step]))
exporting? (get-in db [:hardwallet :on-export-success])]
(log/debug "[hardwallet] verify pin error" error)
(fx/merge cofx
(when 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)}}
(set-on-card-connected :hardwallet/verify-pin)
(navigation/navigate-to-cofx (if setup?
:keycard-connection-lost-setup
:keycard-connection-lost) nil))
(if (re-matches 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})}
(when-not setup?
(navigation/navigate-to-cofx :enter-pin-settings nil))
(get-application-info (get-pairing db) nil))
(show-wrong-keycard-alert true))))))
(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)}}
(set-on-card-connected :hardwallet/verify-pin)
(navigation/navigate-to-cofx (if setup?
:keycard-connection-lost-setup
:keycard-connection-lost) nil))
(re-matches 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})}
(when-not setup?
(if exporting?
(navigation/navigate-back)
(navigation/navigate-to-cofx :enter-pin-settings nil)))
(get-application-info (get-pairing db) nil))
:else (show-wrong-keycard-alert true))))
(fx/defn on-change-pin-success
[{:keys [db] :as cofx}]
@ -1275,14 +1317,15 @@
card-connected? (get-in db [:hardwallet :card-connected?])
setup? (boolean (get-in db [:hardwallet :setup-step]))]
(if card-connected?
{:db (assoc-in db [:hardwallet :pin :status] :verifying)
:hardwallet/verify-pin {:pin pin
:pairing pairing}}
(fx/merge cofx
{:db (assoc-in db [:hardwallet :pin :status] :verifying)
:hardwallet/verify-pin {:pin pin
:pairing pairing}})
(fx/merge cofx
(set-on-card-connected :hardwallet/verify-pin)
(navigation/navigate-to-cofx (if setup?
:keycard-connection-lost-setup
:keycard-connection-lost) nil)))))
:keycard-processing) nil)))))
(defn unblock-pin
[{:keys [db] :as cofx}]
@ -1403,6 +1446,31 @@
(navigation/navigate-to-cofx :keycard-recovery-recovering nil)
(navigation/navigate-to-cofx :keycard-connection-lost-setup nil)))))
(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 (vector->string (get-in db [:hardwallet :pin :export-key]))
pairing (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)
(set-on-card-connected :wallet.accounts/generate-new-keycard-account))
(fx/merge cofx
(set-on-card-connected :wallet.accounts/generate-new-keycard-account)
(navigation/navigate-to-cofx :keycard-processing nil)))))
; PIN enter steps:
; login - PIN is used to login
; sign - PIN for transaction sign
@ -1439,6 +1507,10 @@
(= pin-code-length numbers-entered))
(verify-pin)
(and (= enter-step :export-key)
(= pin-code-length numbers-entered))
(generate-new-keycard-account)
(and (= enter-step :sign)
(= pin-code-length numbers-entered))
(prepare-to-sign)
@ -1984,3 +2056,4 @@
(assoc-in [:signing/sign :keycard-step] :pin))}
(get-application-info (get-pairing db) nil)))
(show-wrong-keycard-alert true)))))

View File

@ -78,6 +78,10 @@
:hardwallet/remove-key-with-unpair
card/remove-key-with-unpair)
(re-frame/reg-fx
:hardwallet/export-key
card/export-key)
(re-frame/reg-fx
:hardwallet/unpair-and-delete
card/unpair-and-delete)

View File

@ -214,6 +214,7 @@
:enter-pin-settings (hardwallet/enter-pin-screen-did-load %)
:enter-pin-modal (hardwallet/enter-pin-screen-did-load %)
:keycard-login-pin (hardwallet/enter-pin-screen-did-load %)
:add-new-account-pin (hardwallet/enter-pin-screen-did-load %)
:hardwallet-connect (hardwallet/hardwallet-connect-screen-did-load %)
:hardwallet-connect-sign (hardwallet/hardwallet-connect-screen-did-load %)
:hardwallet-connect-settings (hardwallet/hardwallet-connect-screen-did-load %)

View File

@ -152,6 +152,9 @@
(defn pairing []
(loading :t/keycard-onboarding-pairing-header))
(defn processing []
(loading :t/processing))
(defn welcome []
[react/view {:flex 1
:justify-content :space-between

View File

@ -10,6 +10,7 @@
:add-new-account :default
:add-watch-account :default
:add-new-account-password :default
:add-new-account-pin :default
:about-app :default
:help-center :default
:advanced-settings :default
@ -27,4 +28,4 @@
:wallet-settings-assets :default
:wallet-add-custom-token :default
:currency-settings :default
:backup-seed :default})
:backup-seed :default})

View File

@ -41,5 +41,6 @@
(concat [:keycard-settings
:reset-card
:keycard-connection-lost
:keycard-processing
:enter-pin-settings]))
:config {:initialRouteName :my-profile}})

View File

@ -101,6 +101,7 @@
:keycard-nfc-on keycard/nfc-on
:keycard-connection-lost keycard/connection-lost
:keycard-connection-lost-setup keycard/connection-lost-setup
:keycard-processing keycard/processing
:keycard-recovery-intro keycard.recovery/intro
:keycard-recovery-start keycard.recovery/start
:keycard-recovery-pair keycard.recovery/pair
@ -181,6 +182,7 @@
:add-new-account add-account/add-account
:add-watch-account add-account/add-watch-account
:add-new-account-password add-account/password
:add-new-account-pin add-account/pin
:account-added account-settings/account-added
:account-settings account-settings/account-settings})

View File

@ -1,20 +1,25 @@
(ns status-im.ui.screens.routing.wallet-stack)
(ns status-im.ui.screens.routing.wallet-stack
(:require [status-im.utils.config :as config]))
(def wallet-stack
{:name :wallet-stack
:screens [:wallet
:wallet-account
:add-new-account
:add-watch-account
:add-new-account-password
:account-added
:account-settings
:collectibles-list
:wallet-onboarding-setup
:wallet-transaction-details
:wallet-settings-hook
:wallet-settings-assets
:wallet-add-custom-token
:wallet-custom-token-details
:currency-settings]
:screens (cond-> [:wallet
:wallet-account
:add-new-account
:add-watch-account
:add-new-account-password
:add-new-account-pin
:account-added
:account-settings
:collectibles-list
:wallet-onboarding-setup
:wallet-transaction-details
:wallet-settings-hook
:wallet-settings-assets
:wallet-add-custom-token
:wallet-custom-token-details
:currency-settings]
config/hardwallet-enabled?
(concat [:keycard-connection-lost
:keycard-processing]))
:config {:initialRouteName :wallet}})

View File

@ -156,16 +156,13 @@
[icons/icon :main-icons/send {:color :white}]]]]))
(views/defview accounts []
(views/letsubs [{:keys [keycard-pairing]} [:multiaccount]
accounts [:multiaccount/accounts]]
(views/letsubs [accounts [:multiaccount/accounts]]
[react/scroll-view {:horizontal true}
[react/view {:flex-direction :row :padding-top 11 :padding-bottom 12}
(for [account accounts]
^{:key account}
[account-card account])
;; TODO: enable keycard support for adding new accounts
(when-not keycard-pairing
[add-card])]]))
[add-card]]]))
(defn accounts-overview []
[react/view {:flex 1}

View File

@ -1,6 +1,7 @@
(ns status-im.ui.screens.wallet.add-new.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [status-im.ui.components.react :as react]
[status-im.ui.screens.hardwallet.pin.views :as pin.views]
[status-im.i18n :as i18n]
[re-frame.core :as re-frame]
[status-im.ui.components.colors :as colors]
@ -85,6 +86,20 @@
:on-press #(re-frame/dispatch [:wallet.accounts/add-watch-account])
:disabled? (not (ethereum/address? address))}}]]))
(defview pin []
(letsubs [pin [:hardwallet/pin]
status [:hardwallet/pin-status]
error-label [:hardwallet/pin-error-label]]
[react/keyboard-avoiding-view {:style {:flex 1}}
[topbar/topbar]
[pin.views/pin-view
{:pin pin
:status status
:title-label :t/current-pin
:description-label :t/current-pin-description
:error-label error-label
:step :export-key}]]))
(defview password []
(letsubs [{:keys [error]} [:add-account]
entered-password (reagent/atom "")]
@ -111,4 +126,4 @@
:right {:type :next
:label :t/generate-account
:on-press #(re-frame/dispatch [:wallet.accounts/generate-new-account @entered-password])
:disabled? (not (spec/valid? ::multiaccounts.db/password @entered-password))}}]]))
:disabled? (not (spec/valid? ::multiaccounts.db/password @entered-password))}}]]))

View File

@ -41,9 +41,9 @@
(fn [result]
(let [{:keys [publicKey address]}
(get (types/json->clj result) (keyword path))]
(re-frame/dispatch [::account-generated
{:name (str "Account " path-num)
:address address
(re-frame/dispatch [:wallet.accounts/account-generated
{:name (str "Account " path-num)
:address address
:public-key publicKey
:path (str constants/path-wallet-root "/" path-num)
:color (rand-nth colors/account-colors)}])))))))))))))
@ -79,7 +79,7 @@
{:error (i18n/label :t/add-account-incorrect-password)})})
(fx/defn account-generated
{:events [::account-generated]}
{:events [:wallet.accounts/account-generated]}
[{:keys [db] :as cofx} account]
(fx/merge cofx
{:db (update db :add-account assoc :account account :step :generated)}
@ -138,9 +138,15 @@
(fx/defn start-adding-new-account
{:events [:wallet.accounts/start-adding-new-account]}
[{:keys [db] :as cofx} {:keys [type] :as add-account}]
(let [screen (case type :generate :add-new-account-password :watch :add-watch-account)]
(let [{:keys [keycard-pairing]} (:multiaccount db)
screen (case type
:generate (if keycard-pairing :add-new-account-pin
:add-new-account-password)
:watch :add-watch-account)]
(fx/merge cofx
{:db (assoc db :add-account add-account)}
{:db (cond-> (assoc db :add-account add-account)
keycard-pairing
(assoc-in [:hardwallet :pin :enter-step] :export-key))}
(navigation/navigate-to-cofx screen nil))))
(fx/defn enter-phrase-next-pressed