Ensure that keycard flows continue when card is already connected

This commit ensures that a user can flawlessly interact with a keycard,
regardless of the moment when the card was tapped to the device. To make
it so:
- in case if the card was tapped before the interaction the user doesn't
  need to re-connect card to continue
- in case if the connection with the card was lost during the interaction
  the application restarts that interaction as soon as the card was
  connected again (unless the user canceled the flow)
This commit is contained in:
Roman Volosovskyi 2020-03-13 14:42:26 +02:00
parent 947b1c2b2e
commit 61d465a343
No known key found for this signature in database
GPG Key ID: 0238A4B5ECEE70DE
15 changed files with 288 additions and 216 deletions

View File

@ -37,7 +37,7 @@
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(fx/merge cofx (fx/merge cofx
(common/clear-pin) (common/clear-pin)
(common/hide-pair-sheet) (common/hide-connection-sheet)
(if (get-in db [:hardwallet :pin :puk-restore?]) (if (get-in db [:hardwallet :pin :puk-restore?])
(navigation/navigate-to-cofx :multiaccounts nil) (navigation/navigate-to-cofx :multiaccounts nil)
(navigation/navigate-to-cofx :keycard-settings nil)))) (navigation/navigate-to-cofx :keycard-settings nil))))
@ -45,22 +45,30 @@
(fx/defn change-pin (fx/defn change-pin
{:events [:hardwallet/change-pin]} {:events [:hardwallet/change-pin]}
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [pairing (common/get-pairing db) (let [setup-step (get-in db [:hardwallet :setup-step])]
new-pin (common/vector->string (get-in db [:hardwallet :pin :original])) (log/debug "[hardwallet] change-pin"
current-pin (common/vector->string (get-in db [:hardwallet :pin :current])) "setup-step" setup-step)
setup-step (get-in db [:hardwallet :setup-step])
card-connected? (get-in db [:hardwallet :card-connected?])]
(if (= setup-step :pin) (if (= setup-step :pin)
(onboarding/load-preparing-screen cofx) (onboarding/load-preparing-screen cofx)
(if card-connected? (common/show-connection-sheet
(fx/merge cofx cofx
{:sheet-options {:on-cancel [::on-cancel]}
:on-card-connected :hardwallet/change-pin
:handler
(fn [{: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]))]
(fx/merge
cofx
{:db (assoc-in db [:hardwallet :pin :status] :verifying) {:db (assoc-in db [:hardwallet :pin :status] :verifying)
:hardwallet/change-pin {:new-pin new-pin
:hardwallet/change-pin
{:new-pin new-pin
:current-pin current-pin :current-pin current-pin
:pairing pairing}}) :pairing pairing}})))}))))
(fx/merge cofx
(common/set-on-card-connected :hardwallet/change-pin)
(common/show-pair-sheet {:on-cancel [::on-cancel]}))))))
(fx/defn on-change-pin-success (fx/defn on-change-pin-success
{:events [:hardwallet.callback/on-change-pin-success]} {:events [:hardwallet.callback/on-change-pin-success]}
@ -74,7 +82,7 @@
:error-label nil}) :error-label nil})
:utils/show-popup {:title "" :utils/show-popup {:title ""
:content (i18n/label :t/pin-changed)}} :content (i18n/label :t/pin-changed)}}
(common/hide-pair-sheet) (common/hide-connection-sheet)
(if puk-restore? (if puk-restore?
(navigation/navigate-to-cofx :multiaccounts nil) (navigation/navigate-to-cofx :multiaccounts nil)
(navigation/navigate-to-cofx :keycard-settings nil)) (navigation/navigate-to-cofx :keycard-settings nil))

View File

@ -104,6 +104,7 @@
(fx/defn set-on-card-connected (fx/defn set-on-card-connected
[{:keys [db]} on-connect] [{:keys [db]} on-connect]
(log/debug "[hardwallet] set-on-card-connected" on-connect)
{:db (-> db {:db (-> db
(assoc-in [:hardwallet :on-card-connected] on-connect) (assoc-in [:hardwallet :on-card-connected] on-connect)
(assoc-in [:hardwallet :last-on-card-connected] nil))}) (assoc-in [:hardwallet :last-on-card-connected] nil))})
@ -111,6 +112,7 @@
(fx/defn stash-on-card-connected (fx/defn stash-on-card-connected
[{:keys [db]}] [{:keys [db]}]
(let [on-connect (get-in db [:hardwallet :on-card-connected])] (let [on-connect (get-in db [:hardwallet :on-card-connected])]
(log/debug "[hardwallet] stash-on-card-connected" on-connect)
{:db (-> db {:db (-> db
(assoc-in [:hardwallet :last-on-card-connected] on-connect) (assoc-in [:hardwallet :last-on-card-connected] on-connect)
(assoc-in [:hardwallet :on-card-connected] nil))})) (assoc-in [:hardwallet :on-card-connected] nil))}))
@ -120,18 +122,21 @@
(let [on-connect (or (let [on-connect (or
(get-in db [:hardwallet :on-card-connected]) (get-in db [:hardwallet :on-card-connected])
(get-in db [:hardwallet :last-on-card-connected]))] (get-in db [:hardwallet :last-on-card-connected]))]
(log/debug "[hardwallet] restore-on-card-connected" on-connect)
{:db (-> db {:db (-> db
(assoc-in [:hardwallet :on-card-connected] on-connect) (assoc-in [:hardwallet :on-card-connected] on-connect)
(assoc-in [:hardwallet :last-on-card-connect] nil))})) (assoc-in [:hardwallet :last-on-card-connect] nil))}))
(fx/defn clear-on-card-connected (fx/defn clear-on-card-connected
[{:keys [db]}] [{:keys [db]}]
(log/debug "[hardwallet] clear-on-card-connected")
{:db (-> db {:db (-> db
(assoc-in [:hardwallet :on-card-connected] nil) (assoc-in [:hardwallet :on-card-connected] nil)
(assoc-in [:hardwallet :last-on-card-connected] nil))}) (assoc-in [:hardwallet :last-on-card-connected] nil))})
(fx/defn set-on-card-read (fx/defn set-on-card-read
[{:keys [db]} on-connect] [{:keys [db]} on-connect]
(log/debug "[hardwallet] set-on-card-read" on-connect)
{:db (-> db {:db (-> db
(assoc-in [:hardwallet :on-card-read] on-connect) (assoc-in [:hardwallet :on-card-read] on-connect)
(assoc-in [:hardwallet :last-on-card-read] nil))}) (assoc-in [:hardwallet :last-on-card-read] nil))})
@ -139,6 +144,7 @@
(fx/defn stash-on-card-read (fx/defn stash-on-card-read
[{:keys [db]}] [{:keys [db]}]
(let [on-connect (get-in db [:hardwallet :on-card-read])] (let [on-connect (get-in db [:hardwallet :on-card-read])]
(log/debug "[hardwallet] stash-on-card-read" on-connect)
{:db (-> db {:db (-> db
(assoc-in [:hardwallet :last-on-card-read] on-connect) (assoc-in [:hardwallet :last-on-card-read] on-connect)
(assoc-in [:hardwallet :on-card-read] nil))})) (assoc-in [:hardwallet :on-card-read] nil))}))
@ -148,12 +154,14 @@
(let [on-connect (or (let [on-connect (or
(get-in db [:hardwallet :on-card-read]) (get-in db [:hardwallet :on-card-read])
(get-in db [:hardwallet :last-on-card-read]))] (get-in db [:hardwallet :last-on-card-read]))]
(log/debug "[hardwallet] restore-on-card-read" on-connect)
{:db (-> db {:db (-> db
(assoc-in [:hardwallet :on-card-read] on-connect) (assoc-in [:hardwallet :on-card-read] on-connect)
(assoc-in [:hardwallet :last-on-card-connect] nil))})) (assoc-in [:hardwallet :last-on-card-connect] nil))}))
(fx/defn clear-on-card-read (fx/defn clear-on-card-read
[{:keys [db]}] [{:keys [db]}]
(log/debug "[hardwallet] clear-on-card-read")
{:db (-> db {:db (-> db
(assoc-in [:hardwallet :on-card-read] nil) (assoc-in [:hardwallet :on-card-read] nil)
(assoc-in [:hardwallet :last-on-card-read] nil))}) (assoc-in [:hardwallet :last-on-card-read] nil))})
@ -166,26 +174,36 @@
:on-connect ::on-card-connected :on-connect ::on-card-connected
:on-disconnect ::on-card-disconnected}))) :on-disconnect ::on-card-disconnected})))
(fx/defn show-pair-sheet (fx/defn show-connection-sheet
[cofx {:keys [on-cancel] [{:keys [db] :as cofx} {:keys [on-card-connected on-card-read handler]
:or {on-cancel [::cancel-sheet-confirm]}}] {:keys [on-cancel]
(log/debug "[hardwallet] show-pair-sheet") :or {on-cancel [::cancel-sheet-confirm]}}
(let [connected? (get-in cofx [:db :hardwallet :card-connected?])] :sheet-options}]
(fx/merge cofx (assert (keyword? on-card-connected))
(assert (fn? handler))
(let [connected? (get-in db [:hardwallet :card-connected?])]
(log/debug "[hardwallet] show-sheet-with-connection-check"
"card-connected?" connected?)
(fx/merge
cofx
{:dismiss-keyboard true} {:dismiss-keyboard true}
(bottom-sheet/show-bottom-sheet (bottom-sheet/show-bottom-sheet
{:view {:show-handle? false {:view {:show-handle? false
:backdrop-dismiss? false :backdrop-dismiss? false
:disable-drag? true :disable-drag? true
:content (keycard-sheet-content on-cancel :content (keycard-sheet-content on-cancel connected?)}})
connected?)}})))) (when on-card-read
(set-on-card-read on-card-read))
(set-on-card-connected on-card-connected)
(when connected?
(stash-on-card-connected))
(when connected?
handler))))
(fx/defn hide-pair-sheet (fx/defn hide-connection-sheet
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(fx/merge cofx (fx/merge cofx
{:db (-> db {:db (assoc-in db [:hardwallet :card-read-in-progress?] false)}
(assoc-in [:hardwallet :card-connected?] false)
(assoc-in [:hardwallet :card-read-in-progress?] false))}
(restore-on-card-connected) (restore-on-card-connected)
(restore-on-card-read) (restore-on-card-read)
(bottom-sheet/hide-bottom-sheet))) (bottom-sheet/hide-bottom-sheet)))
@ -211,7 +229,7 @@
:hardwallet/back-button-pressed]} :hardwallet/back-button-pressed]}
[cofx] [cofx]
(fx/merge cofx (fx/merge cofx
(hide-pair-sheet) (hide-connection-sheet)
(clear-pin))) (clear-pin)))
(fx/defn cancel-sheet (fx/defn cancel-sheet
@ -320,7 +338,7 @@
(keychain/save-hardwallet-keys key-uid encryption-public-key whisper-private-key)) (keychain/save-hardwallet-keys key-uid encryption-public-key whisper-private-key))
(clear-on-card-connected) (clear-on-card-connected)
(clear-on-card-read) (clear-on-card-read)
(hide-pair-sheet)))) (hide-connection-sheet))))
(fx/defn on-get-keys-error (fx/defn on-get-keys-error
{:events [:hardwallet.callback/on-get-keys-error]} {:events [:hardwallet.callback/on-get-keys-error]}
@ -338,7 +356,7 @@
:login [] :login []
:import-multiaccount [] :import-multiaccount []
:error-label :t/pin-mismatch})} :error-label :t/pin-mismatch})}
(hide-pair-sheet) (hide-connection-sheet)
(when (= flow :import) (when (= flow :import)
(navigation/navigate-to-cofx :keycard-recovery-pin nil))) (navigation/navigate-to-cofx :keycard-recovery-pin nil)))
(show-wrong-keycard-alert true))))) (show-wrong-keycard-alert true)))))
@ -350,6 +368,8 @@
[{:keys [db]} pairing on-card-read] [{:keys [db]} pairing on-card-read]
(let [key-uid (get-in db [:hardwallet :application-info :key-uid]) (let [key-uid (get-in db [:hardwallet :application-info :key-uid])
pairing' (or pairing (some->> key-uid (get-pairing db)))] pairing' (or pairing (some->> key-uid (get-pairing db)))]
(log/debug "[hardwallet] get-application-info"
"pairing" pairing')
{:hardwallet/get-application-info {:pairing pairing' {:hardwallet/get-application-info {:pairing pairing'
:on-success on-card-read}})) :on-success on-card-read}}))
@ -410,7 +430,6 @@
(fx/defn on-card-connected (fx/defn on-card-connected
{:events [::on-card-connected]} {:events [::on-card-connected]}
[{:keys [db] :as cofx} _] [{:keys [db] :as cofx} _]
(log/debug "[hardwallet] card connected")
(let [instance-uid (get-in db [:hardwallet :application-info :instance-uid]) (let [instance-uid (get-in db [:hardwallet :application-info :instance-uid])
key-uid (get-in db [:hardwallet :application-info :key-uid]) key-uid (get-in db [:hardwallet :application-info :key-uid])
should-read-instance-uid? (nil? instance-uid) should-read-instance-uid? (nil? instance-uid)
@ -419,9 +438,9 @@
should-read-instance-uid? :hardwallet/get-application-info should-read-instance-uid? :hardwallet/get-application-info
:else (get-in db [:hardwallet :on-card-read])) :else (get-in db [:hardwallet :on-card-read]))
pairing (get-pairing db key-uid)] pairing (get-pairing db key-uid)]
(log/debug "[hardwallet] on-card-connected" (log/debug "[hardwallet] on-card-connected" on-card-connected
"on-card-connected" on-card-connected
"on-card-read" on-card-read) "on-card-read" on-card-read)
(when on-card-connected
(fx/merge cofx (fx/merge cofx
{:db (-> db {:db (-> db
(assoc-in [:hardwallet :card-read-in-progress?] (boolean on-card-read)))} (assoc-in [:hardwallet :card-read-in-progress?] (boolean on-card-read)))}
@ -430,12 +449,12 @@
(stash-on-card-connected) (stash-on-card-connected)
(when (and on-card-read (when (and on-card-read
(nil? on-card-connected)) (nil? on-card-connected))
(get-application-info pairing on-card-read))))) (get-application-info pairing on-card-read))))))
(fx/defn on-card-disconnected (fx/defn on-card-disconnected
{:events [::on-card-disconnected]} {:events [::on-card-disconnected]}
[{:keys [db] :as cofx} _] [{:keys [db] :as cofx} _]
(log/debug "[hardwallet] card disconnected ") (log/debug "[hardwallet] card disconnected")
(fx/merge cofx (fx/merge cofx
{:db (-> db {:db (-> db
(assoc-in [:hardwallet :card-read-in-progress?] false))} (assoc-in [:hardwallet :card-read-in-progress?] false))}

View File

@ -140,7 +140,7 @@
:puk [] :puk []
:puk-restore? true :puk-restore? true
:error-label nil}))} :error-label nil}))}
(common/hide-pair-sheet) (common/hide-connection-sheet)
(navigation/navigate-to-cofx :enter-pin-settings nil)))) (navigation/navigate-to-cofx :enter-pin-settings nil))))
(fx/defn on-unblock-pin-error (fx/defn on-unblock-pin-error
@ -156,7 +156,7 @@
:error-label :t/puk-mismatch :error-label :t/puk-mismatch
:enter-step :puk :enter-step :puk
:puk []})} :puk []})}
(common/hide-pair-sheet))))) (common/hide-connection-sheet)))))
(fx/defn dispatch-on-verified-event (fx/defn dispatch-on-verified-event
[{:keys [db]} event] [{:keys [db]} event]
@ -177,7 +177,7 @@
;; now for simplicity do not hide bottom sheet when generating key ;; now for simplicity do not hide bottom sheet when generating key
;; but should be refactored. ;; but should be refactored.
(when-not (= on-verified :hardwallet/generate-and-load-key) (when-not (= on-verified :hardwallet/generate-and-load-key)
(common/hide-pair-sheet)) (common/hide-connection-sheet))
(when-not (contains? #{:hardwallet/unpair (when-not (contains? #{:hardwallet/unpair
:hardwallet/generate-and-load-key :hardwallet/generate-and-load-key
:hardwallet/remove-key-with-unpair :hardwallet/remove-key-with-unpair
@ -204,7 +204,7 @@
:confirmation [] :confirmation []
:sign [] :sign []
:error-label :t/pin-mismatch})} :error-label :t/pin-mismatch})}
(common/hide-pair-sheet) (common/hide-connection-sheet)
(when-not setup? (when-not setup?
(if exporting? (if exporting?
(navigation/navigate-back) (navigation/navigate-back)
@ -212,39 +212,41 @@
(common/get-application-info (common/get-pairing db) nil)) (common/get-application-info (common/get-pairing db) nil))
(fx/merge cofx (fx/merge cofx
(common/hide-pair-sheet) (common/hide-connection-sheet)
(common/show-wrong-keycard-alert true)))))) (common/show-wrong-keycard-alert true))))))
(fx/defn verify-pin (fx/defn verify-pin
{:events [:hardwallet/verify-pin]} {:events [:hardwallet/verify-pin]}
[{:keys [db] :as cofx}] [cofx]
(common/show-connection-sheet
cofx
{:on-card-connected :hardwallet/verify-pin
:handler
(fn [{:keys [db] :as cofx}]
(let [pin (common/vector->string (get-in db [:hardwallet :pin :current])) (let [pin (common/vector->string (get-in db [:hardwallet :pin :current]))
pairing (common/get-pairing db) pairing (common/get-pairing db)]
card-connected? (get-in db [:hardwallet :card-connected?])] (fx/merge
(if card-connected? cofx
(fx/merge cofx
{:db (assoc-in db [:hardwallet :pin :status] :verifying) {:db (assoc-in db [:hardwallet :pin :status] :verifying)
:hardwallet/verify-pin {:pin pin :hardwallet/verify-pin {:pin pin
:pairing pairing}}) :pairing pairing}})))}))
(fx/merge cofx
(common/set-on-card-connected :hardwallet/verify-pin)
(common/show-pair-sheet {})))))
(fx/defn unblock-pin (fx/defn unblock-pin
{:events [:hardwallet/unblock-pin]} {:events [:hardwallet/unblock-pin]}
[{:keys [db] :as cofx}] [cofx]
(common/show-connection-sheet
cofx
{:on-card-connected :hardwallet/unblock-pin
:handler
(fn [{:keys [db]}]
(let [puk (common/vector->string (get-in db [:hardwallet :pin :puk])) (let [puk (common/vector->string (get-in db [:hardwallet :pin :puk]))
key-uid (get-in db [:hardwallet :application-info :key-uid]) key-uid (get-in db [:hardwallet :application-info :key-uid])
card-connected? (get-in db [:hardwallet :card-connected?])
pairing (common/get-pairing db key-uid)] pairing (common/get-pairing db key-uid)]
(if card-connected?
{:db (assoc-in db [:hardwallet :pin :status] :verifying) {:db (assoc-in db [:hardwallet :pin :status] :verifying)
:hardwallet/unblock-pin {:puk puk :hardwallet/unblock-pin
{:puk puk
:new-pin common/default-pin :new-pin common/default-pin
:pairing pairing}} :pairing pairing}}))}))
(fx/merge cofx
(common/set-on-card-connected :hardwallet/unblock-pin)
(common/show-pair-sheet {})))))
(def pin-code-length 6) (def pin-code-length 6)
(def puk-code-length 12) (def puk-code-length 12)
@ -377,7 +379,7 @@
(assoc-in [:hardwallet :setup-step] next-step) (assoc-in [:hardwallet :setup-step] next-step)
(assoc-in [:hardwallet :secrets :pairing] pairing) (assoc-in [:hardwallet :secrets :pairing] pairing)
(assoc-in [:hardwallet :secrets :paired-on] paired-on))} (assoc-in [:hardwallet :secrets :paired-on] paired-on))}
(common/hide-pair-sheet) (common/hide-connection-sheet)
(when multiaccount (when multiaccount
(set-multiaccount-pairing multiaccount pairing paired-on)) (set-multiaccount-pairing multiaccount pairing paired-on))
(when (= flow :login) (when (= flow :login)
@ -405,7 +407,7 @@
(common/set-on-card-connected (if (= setup-step :pairing) (common/set-on-card-connected (if (= setup-step :pairing)
:hardwallet/load-pairing-screen :hardwallet/load-pairing-screen
:hardwallet/pair)) :hardwallet/pair))
(common/hide-pair-sheet) (common/hide-connection-sheet)
(when (= flow :import) (when (= flow :import)
(navigation/navigate-to-cofx :keycard-recovery-pair nil)) (navigation/navigate-to-cofx :keycard-recovery-pair nil))
(when (not= setup-step :enter-pair-code) (when (not= setup-step :enter-pair-code)
@ -444,7 +446,7 @@
(fx/merge cofx (fx/merge cofx
{:db (assoc-in db [:hardwallet :card-state] card-state)} {:db (assoc-in db [:hardwallet :card-state] card-state)}
(set-setup-step card-state) (set-setup-step card-state)
(common/hide-pair-sheet) (common/hide-connection-sheet)
(when (and flow (when (and flow
(= card-state :init)) (= card-state :init))
@ -485,7 +487,7 @@
(fx/defn on-card-disconnected (fx/defn on-card-disconnected
{:events [:hardwallet.callback/on-card-disconnected]} {:events [:hardwallet.callback/on-card-disconnected]}
[{:keys [db]} _] [{:keys [db]} _]
(log/debug "[hardwallet] card disconnected ") (log/debug "[hardwallet] card disconnected")
{:db (assoc-in db [:hardwallet :card-connected?] false)}) {:db (assoc-in db [:hardwallet :card-connected?] false)})
(fx/defn on-register-card-events (fx/defn on-register-card-events

View File

@ -24,14 +24,14 @@
:sign [] :sign []
:export-key [] :export-key []
:error-label :t/pin-mismatch})} :error-label :t/pin-mismatch})}
(common/hide-pair-sheet) (common/hide-connection-sheet)
(common/get-application-info (common/get-pairing db) nil)) (common/get-application-info (common/get-pairing db) nil))
:else :else
(fx/merge cofx (fx/merge cofx
(common/show-wrong-keycard-alert true) (common/show-wrong-keycard-alert true)
(common/clear-pin) (common/clear-pin)
(common/hide-pair-sheet))))) (common/hide-connection-sheet)))))
(fx/defn on-export-key-success (fx/defn on-export-key-success
{:events [:hardwallet.callback/on-export-key-success]} {:events [:hardwallet.callback/on-export-key-success]}
@ -40,4 +40,4 @@
(fx/merge cofx (fx/merge cofx
{:dispatch (callback-fn pubkey)} {:dispatch (callback-fn pubkey)}
(common/clear-pin) (common/clear-pin)
(common/hide-pair-sheet)))) (common/hide-connection-sheet))))

View File

@ -62,36 +62,36 @@
(cond (cond
(empty? application-info) (empty? application-info)
(fx/merge cofx (fx/merge cofx
(common/hide-pair-sheet) (common/hide-connection-sheet)
(navigation/navigate-to-cofx :not-keycard nil)) (navigation/navigate-to-cofx :not-keycard nil))
(empty? key-uid) (empty? key-uid)
(fx/merge cofx (fx/merge cofx
(common/hide-pair-sheet) (common/hide-connection-sheet)
(navigation/navigate-to-cofx :keycard-blank nil)) (navigation/navigate-to-cofx :keycard-blank nil))
multiaccount-mismatch? multiaccount-mismatch?
(fx/merge cofx (fx/merge cofx
(common/hide-pair-sheet) (common/hide-connection-sheet)
(navigation/navigate-to-cofx :keycard-wrong nil)) (navigation/navigate-to-cofx :keycard-wrong nil))
(empty? pairing) (empty? pairing)
(fx/merge cofx (fx/merge cofx
(common/hide-pair-sheet) (common/hide-connection-sheet)
(navigation/navigate-to-cofx :keycard-unpaired nil)) (navigation/navigate-to-cofx :keycard-unpaired nil))
:else :else
(common/get-keys-from-keycard cofx)))) (common/get-keys-from-keycard cofx))))
(fx/defn proceed-to-login (fx/defn proceed-to-login
[{:keys [db] :as cofx}] [cofx]
(let [{:keys [card-connected?]} (:hardwallet db)] (log/debug "[hardwallet] proceed-to-login")
(fx/merge cofx (common/show-connection-sheet
(common/set-on-card-connected :hardwallet/get-application-info) cofx
(common/set-on-card-read :hardwallet/login-with-keycard) {:sheet-options {:on-cancel [::common/cancel-sheet-confirm]}
(if card-connected? :on-card-connected :hardwallet/get-application-info
(login-with-keycard) :on-card-read :hardwallet/login-with-keycard
(common/show-pair-sheet {:on-cancel [::common/cancel-sheet-confirm]}))))) :handler (common/get-application-info nil :hardwallet/login-with-keycard)}))
(fx/defn on-hardwallet-keychain-keys (fx/defn on-hardwallet-keychain-keys
{:events [:multiaccounts.login.callback/get-hardwallet-keys-success]} {:events [:multiaccounts.login.callback/get-hardwallet-keys-success]}

View File

@ -53,13 +53,12 @@
(fx/defn load-generating-mnemonic-screen (fx/defn load-generating-mnemonic-screen
{:events [:hardwallet/load-generating-mnemonic-screen]} {:events [:hardwallet/load-generating-mnemonic-screen]}
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [card-connected? (get-in db [:hardwallet :card-connected?])] (fx/merge
(fx/merge cofx cofx
{:db (assoc-in db [:hardwallet :setup-step] :generating-mnemonic)} {:db (assoc-in db [:hardwallet :setup-step] :generating-mnemonic)}
(common/set-on-card-connected :hardwallet/load-generating-mnemonic-screen) (common/show-connection-sheet
(if card-connected? {:on-card-connected :hardwallet/load-generating-mnemonic-screen
(common/dispatch-event :hardwallet/generate-mnemonic) :handler (common/dispatch-event :hardwallet/generate-mnemonic)})))
(common/show-pair-sheet {})))))
(fx/defn on-generate-mnemonic-error (fx/defn on-generate-mnemonic-error
{:events [:hardwallet.callback/on-generate-mnemonic-error]} {:events [:hardwallet.callback/on-generate-mnemonic-error]}
@ -81,10 +80,9 @@
{:events [:hardwallet.ui/recovery-phrase-confirm-pressed {:events [:hardwallet.ui/recovery-phrase-confirm-pressed
:hardwallet/load-loading-keys-screen]} :hardwallet/load-loading-keys-screen]}
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [card-connected? (get-in db [:hardwallet :card-connected?])] (fx/merge
(fx/merge cofx cofx
{:db (assoc-in db [:hardwallet :setup-step] :loading-keys)} {:db (assoc-in db [:hardwallet :setup-step] :loading-keys)}
(common/set-on-card-connected :hardwallet/load-loading-keys-screen) (common/show-connection-sheet
(if card-connected? {:on-card-connected :hardwallet/load-loading-keys-screen
(common/dispatch-event :hardwallet/generate-and-load-key) :handler (common/dispatch-event :hardwallet/generate-and-load-key)})))
(common/show-pair-sheet {})))))

View File

@ -38,26 +38,24 @@
(fx/defn load-preparing-screen (fx/defn load-preparing-screen
{:events [:hardwallet/load-preparing-screen]} {:events [:hardwallet/load-preparing-screen]}
[{:keys [db] :as cofx}] [cofx]
(let [card-connected? (get-in db [:hardwallet :card-connected?])] (common/show-connection-sheet
(fx/merge cofx cofx
{:db (assoc-in db [:hardwallet :setup-step] :preparing)} {:sheet-options {:on-cancel [::cancel-pressed]}
(common/set-on-card-connected :hardwallet/load-preparing-screen) :on-card-connected :hardwallet/load-preparing-screen
(if card-connected? :handler start-installation}))
(start-installation)
(common/show-pair-sheet {:on-cancel [::cancel-pressed]})))))
(fx/defn load-pairing-screen (fx/defn load-pairing-screen
{:events [:hardwallet/load-pairing-screen {:events [:hardwallet/load-pairing-screen
:keycard.onboarding.puk-code.ui/confirm-pressed]} :keycard.onboarding.puk-code.ui/confirm-pressed]}
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [card-connected? (get-in db [:hardwallet :card-connected?])] (fx/merge
(fx/merge cofx cofx
{:db (assoc-in db [:hardwallet :setup-step] :pairing)} {:db (assoc-in db [:hardwallet :setup-step] :pairing)}
(common/set-on-card-connected :hardwallet/load-pairing-screen) (common/show-connection-sheet
(if card-connected? {:sheet-options {:on-cancel [::cancel-pressed]}
(common/dispatch-event :hardwallet/pair) :on-card-connected :hardwallet/load-pairing-screen
(common/show-pair-sheet {:on-cancel [::cancel-pressed]}))))) :handler (common/dispatch-event :hardwallet/pair)})))
(fx/defn puk-code-next-pressed (fx/defn puk-code-next-pressed
{:events [:keycard.onboarding.puk-code.ui/next-pressed]} {:events [:keycard.onboarding.puk-code.ui/next-pressed]}
@ -73,13 +71,13 @@
{:events [:keycard.onboarding.recovery-phrase-confirm-word2.ui/next-pressed {:events [:keycard.onboarding.recovery-phrase-confirm-word2.ui/next-pressed
:hardwallet/load-finishing-screen]} :hardwallet/load-finishing-screen]}
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [card-connected? (get-in db [:hardwallet :card-connected?])] (fx/merge
(fx/merge cofx cofx
{:db (assoc-in db [:hardwallet :setup-step] :loading-keys)} {:db (assoc-in db [:hardwallet :setup-step] :loading-keys)}
(common/set-on-card-connected :hardwallet/load-finishing-screen) (common/show-connection-sheet
(if card-connected? {:sheet-options {:on-cancel [::cancel-pressed]}
(common/dispatch-event :hardwallet/generate-and-load-key) :on-card-connected :hardwallet/load-finishing-screen
(common/show-pair-sheet {:on-cancel [::cancel-pressed]}))))) :handler (common/dispatch-event :hardwallet/generate-and-load-key)})))
(fx/defn recovery-phrase-learn-more-pressed (fx/defn recovery-phrase-learn-more-pressed
{:events [:keycard.onboarding.recovery-phrase.ui/learn-more-pressed]} {:events [:keycard.onboarding.recovery-phrase.ui/learn-more-pressed]}
@ -254,7 +252,7 @@
(assoc-in [:hardwallet :card-state] :init) (assoc-in [:hardwallet :card-state] :init)
(assoc-in [:hardwallet :setup-step] :secret-keys) (assoc-in [:hardwallet :setup-step] :secret-keys)
(update-in [:hardwallet :secrets] merge secrets'))} (update-in [:hardwallet :secrets] merge secrets'))}
(common/hide-pair-sheet) (common/hide-connection-sheet)
(common/listen-to-hardware-back-button) (common/listen-to-hardware-back-button)
(navigation/navigate-replace-cofx :keycard-onboarding-puk-code nil)))) (navigation/navigate-replace-cofx :keycard-onboarding-puk-code nil))))
@ -288,7 +286,8 @@
(fx/defn begin-setup-pressed (fx/defn begin-setup-pressed
{:events [:keycard.onboarding.intro.ui/begin-setup-pressed]} {:events [:keycard.onboarding.intro.ui/begin-setup-pressed]}
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(fx/merge cofx (fx/merge
cofx
{:db (-> db {:db (-> db
(update :hardwallet (update :hardwallet
dissoc :secrets :card-state :multiaccount-wallet-address dissoc :secrets :card-state :multiaccount-wallet-address
@ -296,9 +295,10 @@
:application-info) :application-info)
(assoc-in [:hardwallet :setup-step] :begin) (assoc-in [:hardwallet :setup-step] :begin)
(assoc-in [:hardwallet :pin :on-verified] nil))} (assoc-in [:hardwallet :pin :on-verified] nil))}
(common/set-on-card-connected :hardwallet/get-application-info) (common/show-connection-sheet
(common/set-on-card-read :hardwallet/check-card-state) {:on-card-connected :hardwallet/get-application-info
(common/show-pair-sheet {}))) :on-card-read :hardwallet/check-card-state
:handler (common/get-application-info nil :hardwallet/check-card-state)})))
(fx/defn cancel-confirm (fx/defn cancel-confirm
{:events [::cancel-confirm]} {:events [::cancel-confirm]}

View File

@ -18,14 +18,12 @@
(fx/defn pair (fx/defn pair
{:events [:hardwallet/pair]} {:events [:hardwallet/pair]}
[{:keys [db] :as cofx}] [cofx]
(let [{:keys [password]} (get-in cofx [:db :hardwallet :secrets]) (let [{:keys [password]} (get-in cofx [:db :hardwallet :secrets])]
card-connected? (get-in db [:hardwallet :card-connected?])] (common/show-connection-sheet
(fx/merge cofx cofx
(common/set-on-card-connected :hardwallet/pair) {:on-card-connected :hardwallet/pair
(if card-connected? :handler (pair* password)})))
(pair* password)
(common/show-pair-sheet {})))))
(fx/defn pair-code-next-button-pressed (fx/defn pair-code-next-button-pressed
{:events [:keycard.onboarding.pair.ui/input-submitted {:events [:keycard.onboarding.pair.ui/input-submitted
@ -100,7 +98,8 @@
(fx/defn begin-setup-pressed (fx/defn begin-setup-pressed
{:events [:keycard.recovery.intro.ui/begin-recovery-pressed]} {:events [:keycard.recovery.intro.ui/begin-recovery-pressed]}
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(fx/merge cofx (fx/merge
cofx
{:db (-> db {:db (-> db
(update :hardwallet (update :hardwallet
dissoc :secrets :card-state :multiaccount-wallet-address dissoc :secrets :card-state :multiaccount-wallet-address
@ -108,9 +107,11 @@
:application-info) :application-info)
(assoc-in [:hardwallet :setup-step] :begin) (assoc-in [:hardwallet :setup-step] :begin)
(assoc-in [:hardwallet :pin :on-verified] nil))} (assoc-in [:hardwallet :pin :on-verified] nil))}
(common/set-on-card-connected :hardwallet/get-application-info) (common/show-connection-sheet
(common/set-on-card-read :hardwallet/check-card-state) {:on-card-connected :hardwallet/get-application-info
(common/show-pair-sheet {:on-cancel [::cancel-pressed]}))) :on-card-read :hardwallet/check-card-state
:sheet-options {:on-cancel [::cancel-pressed]}
:handler (common/get-application-info nil :hardwallet/check-card-state)})))
(fx/defn recovery-success-finish-pressed (fx/defn recovery-success-finish-pressed
{:events [:keycard.recovery.success/finish-pressed]} {:events [:keycard.recovery.success/finish-pressed]}
@ -215,7 +216,7 @@
(assoc :multiaccounts/new-installation-id (random-guid-generator)) (assoc :multiaccounts/new-installation-id (random-guid-generator))
(update-in [:hardwallet :secrets] dissoc :mnemonic))} (update-in [:hardwallet :secrets] dissoc :mnemonic))}
(common/remove-listener-to-hardware-back-button) (common/remove-listener-to-hardware-back-button)
(common/hide-pair-sheet) (common/hide-connection-sheet)
(create-keycard-multiaccount)))) (create-keycard-multiaccount))))
(fx/defn on-generate-and-load-key-error (fx/defn on-generate-and-load-key-error
@ -247,13 +248,11 @@
(fx/defn load-recovering-key-screen (fx/defn load-recovering-key-screen
{:events [:hardwallet/load-recovering-key-screen]} {:events [:hardwallet/load-recovering-key-screen]}
[{:keys [db] :as cofx}] [cofx]
(let [card-connected? (get-in db [:hardwallet :card-connected?])] (common/show-connection-sheet
(fx/merge cofx cofx
(common/set-on-card-connected :hardwallet/load-recovering-key-screen) {:on-card-connected :hardwallet/load-recovering-key-screen
(if card-connected? :handler (common/dispatch-event :hardwallet/import-multiaccount)}))
(common/dispatch-event :hardwallet/import-multiaccount)
(common/show-pair-sheet {})))))
(fx/defn on-name-and-photo-generated (fx/defn on-name-and-photo-generated
{:events [::on-name-and-photo-generated] {:events [::on-name-and-photo-generated]

View File

@ -34,15 +34,11 @@
(fx/defn prepare-to-sign (fx/defn prepare-to-sign
{:events [:hardwallet/prepare-to-sign]} {:events [:hardwallet/prepare-to-sign]}
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [card-connected? (get-in db [:hardwallet :card-connected?]) (let [pairing (common/get-pairing db)]
pairing (common/get-pairing db)] (common/show-connection-sheet
(fx/merge cofx cofx
(if card-connected? {:on-card-connected :hardwallet/prepare-to-sign
(common/get-application-info pairing :hardwallet/sign) :handler (common/get-application-info pairing :hardwallet/sign)})))
(fn [cofx]
(fx/merge cofx
(common/set-on-card-connected :hardwallet/prepare-to-sign)
(common/show-pair-sheet {})))))))
(fx/defn sign-message-completed (fx/defn sign-message-completed
[_ signature] [_ signature]
@ -73,7 +69,7 @@
(assoc-in [:hardwallet :transaction] nil))} (assoc-in [:hardwallet :transaction] nil))}
(common/clear-on-card-connected) (common/clear-on-card-connected)
(common/get-application-info (common/get-pairing db) nil) (common/get-application-info (common/get-pairing db) nil)
(common/hide-pair-sheet) (common/hide-connection-sheet)
(if transaction (if transaction
(send-transaction-with-signature {:transaction (types/clj->json transaction) (send-transaction-with-signature {:transaction (types/clj->json transaction)
:signature signature :signature signature
@ -93,8 +89,8 @@
:sign [] :sign []
:error-label :t/pin-mismatch}) :error-label :t/pin-mismatch})
(assoc-in [:signing/sign :keycard-step] :pin))} (assoc-in [:signing/sign :keycard-step] :pin))}
(common/hide-pair-sheet) (common/hide-connection-sheet)
(common/get-application-info (common/get-pairing db) nil)) (common/get-application-info (common/get-pairing db) nil))
(fx/merge cofx (fx/merge cofx
(common/hide-pair-sheet) (common/hide-connection-sheet)
(common/show-wrong-keycard-alert true)))))) (common/show-wrong-keycard-alert true))))))

View File

@ -94,16 +94,17 @@
(fx/defn remove-key-with-unpair (fx/defn remove-key-with-unpair
{:events [:hardwallet/remove-key-with-unpair]} {:events [:hardwallet/remove-key-with-unpair]}
[{:keys [db] :as cofx}] [cofx]
(common/show-connection-sheet
cofx
{:on-card-connected :hardwallet/remove-key-with-unpair
:handler
(fn [{:keys [db]}]
(let [pin (common/vector->string (get-in db [:hardwallet :pin :current])) (let [pin (common/vector->string (get-in db [:hardwallet :pin :current]))
pairing (common/get-pairing db) pairing (common/get-pairing db)]
card-connected? (get-in db [:hardwallet :card-connected?])] {:hardwallet/remove-key-with-unpair
(if card-connected? {:pin pin
{:hardwallet/remove-key-with-unpair {:pin pin :pairing pairing}}))}))
:pairing pairing}}
(fx/merge cofx
(common/set-on-card-connected :hardwallet/remove-key-with-unpair)
(common/show-pair-sheet {})))))
(fx/defn on-remove-key-success (fx/defn on-remove-key-success
{:events [:hardwallet.callback/on-remove-key-success]} {:events [:hardwallet.callback/on-remove-key-success]}

View File

@ -1,6 +1,5 @@
(ns status-im.hardwallet.wallet (ns status-im.hardwallet.wallet
(:require [status-im.ethereum.core :as ethereum] (:require [status-im.ethereum.core :as ethereum]
[status-im.ui.components.colors :as colors]
[status-im.utils.fx :as fx] [status-im.utils.fx :as fx]
[status-im.hardwallet.common :as common] [status-im.hardwallet.common :as common]
[status-im.constants :as constants] [status-im.constants :as constants]
@ -11,19 +10,23 @@
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [path-num (inc (get-in db [:multiaccount :latest-derived-path])) (let [path-num (inc (get-in db [:multiaccount :latest-derived-path]))
path (str constants/path-wallet-root "/" path-num) 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])) pin (common/vector->string (get-in db [:hardwallet :pin :export-key]))
pairing (common/get-pairing db)] pairing (common/get-pairing db)]
(if card-connected? (common/show-connection-sheet
(fx/merge cofx cofx
{:db (assoc-in db [:hardwallet :on-export-success] {:on-card-connected :hardwallet/load-loading-keys-screen
:handler
(fn [cofx]
(fx/merge
cofx
{:db
(assoc-in
db [:hardwallet :on-export-success]
#(vector :wallet.accounts/account-stored #(vector :wallet.accounts/account-stored
{;; Strip leading 04 prefix denoting uncompressed key format {;; Strip leading 04 prefix denoting uncompressed key format
:address (eip55/address->checksum (str "0x" (ethereum/public-key->address (subs % 2)))) :address (eip55/address->checksum (str "0x" (ethereum/public-key->address (subs % 2))))
:public-key (str "0x" %) :public-key (str "0x" %)
:path path})) :path path}))
:hardwallet/export-key {:pin pin :pairing pairing :path path}} :hardwallet/export-key {:pin pin :pairing pairing :path path}}
(common/set-on-card-connected :wallet.accounts/generate-new-keycard-account)) (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)
(common/show-pair-sheet {})))))

View File

@ -310,7 +310,7 @@
(assoc-in [:hardwallet :pin :status] nil) (assoc-in [:hardwallet :pin :status] nil)
(dissoc :signing/tx :signing/in-progress? :signing/sign))} (dissoc :signing/tx :signing/in-progress? :signing/sign))}
(check-queue) (check-queue)
(hardwallet.common/hide-pair-sheet) (hardwallet.common/hide-connection-sheet)
(hardwallet.common/clear-pin) (hardwallet.common/clear-pin)
#(when on-error #(when on-error
{:dispatch (conj on-error "transaction was cancelled by user")})))) {:dispatch (conj on-error "transaction was cancelled by user")}))))

View File

@ -5,7 +5,8 @@
[status-im.ui.components.animation :as animation] [status-im.ui.components.animation :as animation]
[status-im.hardwallet.card :as keycard-nfc] [status-im.hardwallet.card :as keycard-nfc]
[status-im.react-native.resources :as resources] [status-im.react-native.resources :as resources]
[status-im.ui.components.colors :as colors])) [status-im.ui.components.colors :as colors]
[taoensso.timbre :as log]))
(defn circle [{:keys [animation-value color size]}] (defn circle [{:keys [animation-value color size]}]
[react/animated-view [react/animated-view

View File

@ -0,0 +1,43 @@
(ns status-im.test.hardwallet.common
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.hardwallet.common :as common]))
(deftest test-show-connection-sheet
(testing "the card is not connected yet"
(let [db {:hardwallet {:card-connected? false}}
res (common/show-connection-sheet
{:db db}
{:on-card-connected :do-something
:handler (fn [{:keys [db]}]
{:db (assoc db :some-key :some-value)})})]
(is (= :do-something
(get-in res [:db :hardwallet :on-card-connected])))
(is (nil? (get-in res [:db :some-key])))
(is (true? (get-in res [:db :bottom-sheet/show?])))))
(testing "the card is connected before the interaction"
(let [db {:hardwallet {:card-connected? true}}
res (common/show-connection-sheet
{:db db}
{:on-card-connected :do-something
:handler (fn [{:keys [db]}]
{:db (assoc db :some-key :some-value)})})]
(is (nil? (get-in res [:db :hardwallet :on-card-connected])))
(is (= :do-something
(get-in res [:db :hardwallet :last-on-card-connected])))
(is (= :some-value (get-in res [:db :some-key])))
(is (true? (get-in res [:db :bottom-sheet/show?])))))
(testing "on-card-connected is not specified"
(is
(thrown?
js/Error
(common/show-connection-sheet
{:db {}}
{:handler (fn [_])}))))
(testing "handler is not specified"
(is
(thrown?
js/Error
(common/show-connection-sheet
{:db {}}
{:on-card-connected :do-something})))))

View File

@ -21,6 +21,7 @@
[status-im.test.ethereum.stateofus] [status-im.test.ethereum.stateofus]
[status-im.test.fleet.core] [status-im.test.fleet.core]
[status-im.test.hardwallet.core] [status-im.test.hardwallet.core]
[status-im.test.hardwallet.common]
[status-im.test.i18n] [status-im.test.i18n]
[status-im.test.mailserver.core] [status-im.test.mailserver.core]
[status-im.test.mailserver.topics] [status-im.test.mailserver.topics]
@ -92,6 +93,7 @@
'status-im.test.ethereum.stateofus 'status-im.test.ethereum.stateofus
'status-im.test.fleet.core 'status-im.test.fleet.core
'status-im.test.hardwallet.core 'status-im.test.hardwallet.core
'status-im.test.hardwallet.common
'status-im.test.i18n 'status-im.test.i18n
'status-im.test.mailserver.core 'status-im.test.mailserver.core
'status-im.test.mailserver.topics 'status-im.test.mailserver.topics