Skip to content

Commit 9ef178b

Browse files
committed
[#21578] Keycard - Factory reset a Keycard
1 parent 6ffdaa4 commit 9ef178b

File tree

8 files changed

+175
-14
lines changed

8 files changed

+175
-14
lines changed

src/status_im/contexts/keycard/effects.cljs

+4
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@
5252
(fn [args]
5353
(keycard/export-key (keycard.utils/wrap-handlers args))))
5454

55+
(rf/reg-fx :effects.keycard/factory-reset
56+
(fn [args]
57+
(keycard/factory-reset (keycard.utils/wrap-handlers args))))
58+
5559
(rf/reg-fx :effects.keycard/sign
5660
(fn [args]
5761
(-> (keycard/sign args)

src/status_im/contexts/keycard/error/view.cljs

+15-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
(:require [quo.core :as quo]
33
[react-native.core :as rn]
44
[status-im.common.events-helper :as events-helper]
5+
[status-im.contexts.keycard.factory-reset.view :as factory-reset]
56
[utils.i18n :as i18n]
67
[utils.re-frame :as rf]))
78

@@ -31,7 +32,17 @@
3132
:description-text description}]
3233
[rn/view {:style {:margin-horizontal 20}}
3334
[quo/keycard {:holder-name ""}]
34-
[quo/information-box
35-
{:type :default
36-
:style {:margin-top 20}}
37-
(i18n/label :t/unlock-reset-instructions)]]]))
35+
(when (not= :keycard/error.keycard-blank error)
36+
[:<>
37+
[quo/section-label
38+
{:section (i18n/label :t/what-you-can-do) :container-style {:padding-vertical 8}}]
39+
[quo/settings-item
40+
{:title (i18n/label :t/factory-reset)
41+
:image :icon
42+
:image-props :i/placeholder
43+
:action :arrow
44+
:description :text
45+
:description-props {:text (i18n/label :t/remove-keycard-content)}
46+
:on-press (fn []
47+
(rf/dispatch [:show-bottom-sheet
48+
{:content factory-reset/sheet}]))}]])]]))

src/status_im/contexts/keycard/events.cljs

+4
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@
6868
(fn [_ [data]]
6969
{:effects.keycard/export-key data}))
7070

71+
(rf/reg-event-fx :keycard/factory-reset
72+
(fn [_ [data]]
73+
{:effects.keycard/factory-reset data}))
74+
7175
(rf/reg-event-fx :keycard/connect-derive-address-and-add-account
7276
(fn [_ [{:keys [pin derivation-path key-uid account-preferences]}]]
7377
{:fx [[:dispatch
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
(ns status-im.contexts.keycard.factory-reset.view
2+
(:require [quo.core :as quo]
3+
[react-native.core :as rn]
4+
[status-im.common.events-helper :as events-helper]
5+
[utils.i18n :as i18n]
6+
[utils.re-frame :as rf]))
7+
8+
(defn- reset-card
9+
[]
10+
(rf/dispatch
11+
[:keycard/factory-reset
12+
{:on-success (fn []
13+
(rf/dispatch [:navigate-back])
14+
(rf/dispatch [:keycard/disconnect])
15+
(rf/dispatch [:open-modal :screen/keycard.factory-reset.success]))
16+
:on-failure (fn []
17+
(rf/dispatch [:navigate-back])
18+
(rf/dispatch [:keycard/disconnect])
19+
(rf/dispatch [:open-modal :screen/keycard.factory-reset.fail]))}]))
20+
21+
(defn- connect-and-reset
22+
[key-uid]
23+
(rf/dispatch
24+
[:keycard/connect
25+
{:key-uid key-uid
26+
:on-success reset-card
27+
:on-error (fn [error]
28+
(if (or (= error :keycard/error.keycard-wrong-profile)
29+
(= error :keycard/error.keycard-blank))
30+
(do
31+
(rf/dispatch [:navigate-back])
32+
(rf/dispatch [:keycard/on-application-info-error error]))
33+
(reset-card)))}]))
34+
35+
(defn success-view
36+
[]
37+
[:<>
38+
[quo/page-nav
39+
{:icon-name :i/close
40+
:on-press events-helper/navigate-back}]
41+
[quo/page-top
42+
{:title (i18n/label :t/keycard-reset-success)
43+
:description :text
44+
:description-text (i18n/label :t/keycard-empty-ready)}]
45+
[rn/view {:style {:flex 1}}]
46+
[rn/view {:padding-horizontal 20}
47+
[quo/button {:on-press events-helper/navigate-back}
48+
(i18n/label :t/done)]]])
49+
50+
(defn failed-view
51+
[]
52+
[:<>
53+
[quo/page-nav
54+
{:icon-name :i/close
55+
:on-press events-helper/navigate-back}]
56+
[quo/page-top
57+
{:title (i18n/label :t/keycard-reset-failed)}]
58+
[rn/view {:style {:flex 1}}]
59+
[rn/view {:padding-horizontal 20}
60+
[quo/button {:on-press events-helper/navigate-back}
61+
(i18n/label :t/try-again)]]])
62+
63+
(defn sheet
64+
[]
65+
(let [customization-color (rf/sub [:profile/customization-color])
66+
key-uid (rf/sub [:keycard/key-uid])
67+
[checked? set-checked] (rn/use-state false)]
68+
[:<>
69+
[quo/drawer-top {:title (i18n/label :t/factory-reset-keycard)}]
70+
[quo/text
71+
{:style {:padding-horizontal 20
72+
:padding-top 8
73+
:padding-bottom 8}}
74+
(i18n/label :t/factory-reset-warning)]
75+
[quo/disclaimer
76+
{:checked? checked?
77+
:container-style {:margin-horizontal 20}
78+
:on-change #(set-checked (not checked?))}
79+
(i18n/label :t/key-pair-erased)]
80+
[quo/bottom-actions
81+
{:actions :two-actions
82+
:button-one-label (i18n/label :t/continue)
83+
:button-one-props {:disabled? (not checked?)
84+
:customization-color customization-color
85+
:on-press (fn []
86+
(rf/dispatch [:hide-bottom-sheet])
87+
(connect-and-reset key-uid))}
88+
:button-two-label (i18n/label :t/cancel)
89+
:button-two-props {:type :grey
90+
:on-press (fn []
91+
(rf/dispatch [:hide-bottom-sheet]))}}]]))

src/status_im/contexts/settings/keycard/view.cljs

+32-9
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,42 @@
3030
:style style/keycard-owner-name}
3131
profile-name]]]])
3232

33+
(defn- check-keycard
34+
[]
35+
(rf/dispatch
36+
[:keycard/connect
37+
{:on-error
38+
(fn [error]
39+
(if (= error :keycard/error.keycard-wrong-profile)
40+
(rf/dispatch [:keycard/on-application-info-error error])
41+
(rf/dispatch [:keycard/on-application-info-error error])))}]))
42+
3343
(defn registered-keycards
3444
[]
3545
(let [keycards (rf/sub [:keycard/registered-keycards])]
3646
[:<>
37-
[quo/divider-label
38-
{:counter? false
39-
:tight? true
40-
:blur? true}
41-
(i18n/label :t/registered-keycards)]
42-
[rn/view {:style style/registered-keycards-container}
43-
(for [keycard keycards]
44-
^{:key (:keycard-uid keycard)}
45-
[registered-keycard keycard])]]))
47+
[rn/view {:style {:flex 1}}
48+
[quo/divider-label
49+
{:counter? false
50+
:tight? true
51+
:blur? true}
52+
(i18n/label :t/registered-keycards)]
53+
[rn/view {:style style/registered-keycards-container}
54+
(for [keycard keycards]
55+
^{:key (:keycard-uid keycard)}
56+
[registered-keycard keycard])]]
57+
[quo/text
58+
{:size :heading-2
59+
:weight :semi-bold
60+
:style {:margin-left 20}}
61+
(i18n/label :t/scan-keycard-actions)]
62+
[quo/divider-label (i18n/label :t/tips-scan-keycard)]
63+
[quo/markdown-list {:description (i18n/label :t/remove-phone-case)}]
64+
[quo/markdown-list {:description (i18n/label :t/keep-card-steady)}]
65+
[quo/bottom-actions
66+
{:actions :one-action
67+
:button-one-label (i18n/label :t/ready-to-scan)
68+
:button-one-props {:on-press check-keycard}}]]))
4669

4770
(defn view
4871
[]

src/status_im/navigation/screens.cljs

+14-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
[status-im.contexts.keycard.create.view :as keycard.create]
3636
[status-im.contexts.keycard.empty.view :as keycard.empty]
3737
[status-im.contexts.keycard.error.view :as keycard.error]
38+
[status-im.contexts.keycard.factory-reset.view :as keycard.factory-reset]
3839
[status-im.contexts.keycard.migrate.fail.view :as keycard.migrate.fail]
3940
[status-im.contexts.keycard.migrate.profile-keys.view :as keycard.migrate.profile-keys]
4041
[status-im.contexts.keycard.migrate.re-encrypting.view :as keycard.re-encrypting]
@@ -964,7 +965,19 @@
964965
{:name :screen/keycard.create.ready-to-add
965966
:metrics {:track? true}
966967
:options {:insets {:top? true :bottom? true}}
967-
:component keycard.create/ready-to-add}])
968+
:component keycard.create/ready-to-add}
969+
970+
{:name :screen/keycard.factory-reset.success
971+
:metrics {:track? true}
972+
:options {:theme :dark
973+
:insets {:top? true :bottom? true}}
974+
:component keycard.factory-reset/success-view}
975+
976+
{:name :screen/keycard.factory-reset.fail
977+
:metrics {:track? true}
978+
:options {:theme :dark
979+
:insets {:top? true :bottom? true}}
980+
:component keycard.factory-reset/failed-view}])
968981

969982
(defn screens
970983
[]

src/status_im/subs/keycard.cljs

+6
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,9 @@
8282
:<- [:keycard]
8383
(fn [keycard]
8484
(get-in keycard [:application-info :initialized?])))
85+
86+
(rf/reg-sub
87+
:keycard/key-uid
88+
:<- [:keycard]
89+
(fn [keycard]
90+
(get-in keycard [:application-info :key-uid])))

translations/en.json

+9
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,9 @@
10281028
"export-key": "Export private key",
10291029
"external-link": "External link",
10301030
"external-storage-denied": "Access to external storage is denied",
1031+
"factory-reset": "Factory reset",
1032+
"factory-reset-keycard": "Factory reset this Keycard",
1033+
"factory-reset-warning": "All data will be erased from the Keycard. Please ensure you have a backup of your recovery phrase before proceeding with the factory reset.",
10311034
"failed": "Failed",
10321035
"failed-on": "Failed on",
10331036
"failed-to-fetch-community": "Failed to fetch community",
@@ -1346,6 +1349,7 @@
13461349
"key-name-error-taken": "Key pair name already in use",
13471350
"key-name-error-too-short": "Key pair name must be at least {{count}} characters",
13481351
"key-on-device": "Private key is saved on this device",
1352+
"key-pair-erased": "Key pair will be erased from Keycard",
13491353
"key-pair-imported-successfully": "{{name}} key pair imported successfully",
13501354
"key-pair-migrated-successfully": "Profile key pair successfully migrated",
13511355
"key-pair-name-updated": "Key pair name updated",
@@ -1369,6 +1373,7 @@
13691373
"keycard-desc": "Own a Keycard? Store your keys on it; you’ll need it for transactions",
13701374
"keycard-dont-ask-card": "Don't ask for card to sign in",
13711375
"keycard-empty": "Keycard is empty",
1376+
"keycard-empty-ready": "Keycard is empty and ready to be used",
13721377
"keycard-enter-new-passcode": "Enter new passcode {{step}}/2",
13731378
"keycard-error-description": "Connect the card again to continue",
13741379
"keycard-error-title": "Connection lost",
@@ -1427,7 +1432,9 @@
14271432
"keycard-redeem-title": "Redeem to",
14281433
"keycard-redeem-tx": "Redeem assets",
14291434
"keycard-redeem-tx-desc": "Tap the card to sign and receive assets",
1435+
"keycard-reset-failed": "Failed to reset Keycard",
14301436
"keycard-reset-passcode": "Reset passcode",
1437+
"keycard-reset-success": "Keycard has been reset",
14311438
"keycard-success-description": "You may remove the card now",
14321439
"keycard-success-title": "Success",
14331440
"keycard-unauthorized-operation": "You're unauthorized to perform this operation.\n Please tap valid card and try again.",
@@ -2140,6 +2147,7 @@
21402147
"remove-from-contacts-text": "By removing a user from your contact list you do not hide your wallet address from them",
21412148
"remove-group": "Remove group",
21422149
"remove-key-pair-and-derived-accounts": "Remove key pair and derived accounts",
2150+
"remove-keycard-content": "Remove all content from this Keycard",
21432151
"remove-network": "Remove network",
21442152
"remove-nickname": "Remove nickname",
21452153
"remove-nickname-toast": "You have removed {{secondary-name}}'s nickname",
@@ -2232,6 +2240,7 @@
22322240
"scan-an-address-qr-code": "Scan an address QR code",
22332241
"scan-key-pairs-qr-code": "Scan key pairs QR code",
22342242
"scan-keycard": "Scan Keycard",
2243+
"scan-keycard-actions": "Scan Keycard to see available actions",
22352244
"scan-or-enter-a-sync-code": "Scan or enter a sync code",
22362245
"scan-or-enter-sync-code": "Scan or enter sync code",
22372246
"scan-or-enter-sync-code-seen-on-this-device": "Scan or enter sync code seen on this device",

0 commit comments

Comments
 (0)