diff --git a/src/status_im/contexts/keycard/check/view.cljs b/src/status_im/contexts/keycard/check/view.cljs index a69fdc2b35..64c798464a 100644 --- a/src/status_im/contexts/keycard/check/view.cljs +++ b/src/status_im/contexts/keycard/check/view.cljs @@ -8,22 +8,23 @@ (defn view [] - [:<> - [quo/page-nav - {:icon-name :i/arrow-left - :on-press events-helper/navigate-back}] - [quo/page-top - {:title (i18n/label :t/check-keycard) - :description :text - :description-text (i18n/label :t/see-keycard-ready)}] - [rn/view {:style {:flex 1 :align-items :center :justify-content :center}} - [rn/image - {:resize-mode :contain - :source (resources/get-image :check-your-keycard)}]] - [quo/divider-label (i18n/label :t/tips-scan-keycard)] - [quo/markdown-list {:description (i18n/label :t/remove-phone-case)}] - [quo/markdown-list {:description (i18n/label :t/keep-card-steady)}] - [quo/bottom-actions - {:actions :one-action - :button-one-label (i18n/label :t/ready-to-scan) - :button-one-props {:on-press #(rf/dispatch [:keycard/migration.check-empty-card])}}]]) + (let [{:keys [on-press]} (rf/sub [:get-screen-params])] + [:<> + [quo/page-nav + {:icon-name :i/arrow-left + :on-press events-helper/navigate-back}] + [quo/page-top + {:title (i18n/label :t/check-keycard) + :description :text + :description-text (i18n/label :t/see-keycard-ready)}] + [rn/view {:style {:flex 1 :align-items :center :justify-content :center}} + [rn/image + {:resize-mode :contain + :source (resources/get-image :check-your-keycard)}]] + [quo/divider-label (i18n/label :t/tips-scan-keycard)] + [quo/markdown-list {:description (i18n/label :t/remove-phone-case)}] + [quo/markdown-list {:description (i18n/label :t/keep-card-steady)}] + [quo/bottom-actions + {:actions :one-action + :button-one-label (i18n/label :t/ready-to-scan) + :button-one-props {:on-press on-press}}]])) diff --git a/src/status_im/contexts/keycard/effects.cljs b/src/status_im/contexts/keycard/effects.cljs index 05bebd4777..0051c60dd3 100644 --- a/src/status_im/contexts/keycard/effects.cljs +++ b/src/status_im/contexts/keycard/effects.cljs @@ -40,6 +40,14 @@ (fn [args] (keycard/get-keys (keycard.utils/wrap-handlers args)))) +(rf/reg-fx :effects.keycard/get-more-keys + (fn [args] + (keycard/import-keys (keycard.utils/wrap-handlers args)))) + +(rf/reg-fx :effects.keycard/export-key + (fn [args] + (keycard/export-key (keycard.utils/wrap-handlers args)))) + (rf/reg-fx :effects.keycard/sign (fn [args] (keycard/sign (keycard.utils/wrap-handlers args)))) diff --git a/src/status_im/contexts/keycard/events.cljs b/src/status_im/contexts/keycard/events.cljs index 19add51959..60ee834124 100644 --- a/src/status_im/contexts/keycard/events.cljs +++ b/src/status_im/contexts/keycard/events.cljs @@ -41,8 +41,7 @@ (fn [{:keys [db]} [error]] (let [tag-was-lost? (keycard.utils/tag-lost? (:error error)) pin-retries-count (keycard.utils/pin-retries (:error error))] - (if (or tag-was-lost? (nil? pin-retries-count)) - {:db (assoc-in db [:keycard :pin :status] nil)} + (when-not (or tag-was-lost? (nil? pin-retries-count)) {:db (-> db (assoc-in [:keycard :application-info :pin-retry-counter] pin-retries-count) (assoc-in [:keycard :pin :status] :error)) @@ -56,9 +55,22 @@ (fn [_ [data]] {:effects.keycard/get-keys data})) +(rf/reg-event-fx :keycard/get-more-keys + (fn [_ [data]] + {:effects.keycard/get-more-keys data})) + +(rf/reg-event-fx :keycard/export-key + (fn [_ [data]] + {:effects.keycard/export-key data})) + (rf/reg-event-fx :keycard/cancel-connection (fn [{:keys [db]}] - {:db (update db :keycard dissoc :on-card-connected-event-vector :on-nfc-cancelled-event-vector)})) + {:db (update db + :keycard + dissoc + :card-connected? + :on-card-connected-event-vector + :on-nfc-cancelled-event-vector)})) (rf/reg-event-fx :keycard/disconnect (fn [_ _] @@ -95,11 +107,12 @@ (on-error error) (rf/dispatch [:keycard/on-application-info-error error])) (when on-success (on-success app-info)))) - :on-error (fn [] - (if on-error - (on-error :keycard/error.not-keycard) - (rf/dispatch [:keycard/on-application-info-error - :keycard/error.not-keycard])))}})) + :on-failure (fn [error] + (when-not (keycard.utils/tag-lost? (:error error)) + (if on-error + (on-error :keycard/error.not-keycard) + (rf/dispatch [:keycard/on-application-info-error + :keycard/error.not-keycard]))))}})) (rf/reg-event-fx :keycard/connect (fn [{:keys [db]} [{:keys [key-uid on-success on-error on-connect-event-vector]}]] diff --git a/src/status_im/contexts/keycard/login/events.cljs b/src/status_im/contexts/keycard/login/events.cljs index bb6026bd00..1f4524eabf 100644 --- a/src/status_im/contexts/keycard/login/events.cljs +++ b/src/status_im/contexts/keycard/login/events.cljs @@ -1,5 +1,8 @@ (ns status-im.contexts.keycard.login.events - (:require [utils.re-frame :as rf])) + (:require [status-im.constants :as constants] + [status-im.contexts.profile.config :as profile.config] + [utils.address :as address] + [utils.re-frame :as rf])) (rf/reg-event-fx :keycard.login/on-get-keys-success (fn [{:keys [db]} [data]] @@ -35,3 +38,60 @@ {:password encryption-public-key :whisper-private-key whisper-private-key :key-uid key-uid}]]})))) + +(rf/reg-event-fx :keycard.login/check-card + (fn [] + {:fx [[:dispatch + [:keycard/connect + {:on-error + (fn [error] + (if (= error :keycard/error.keycard-wrong-profile) + (do + (rf/dispatch [:keycard/disconnect]) + (rf/dispatch [:open-modal :screen/keycard.pin.enter + {:on-complete #(rf/dispatch [:keycard.login/prepare-for-profile-recovery + %])}])) + (rf/dispatch [:keycard/on-application-info-error error])))}]]]})) + +(rf/reg-event-fx :keycard.login/prepare-for-profile-recovery + (fn [{:keys [db]} [pin]] + {:fx [[:dispatch + [:keycard/connect + {:key-uid (get-in db [:keycard :application-info :key-uid]) + :on-success (fn [] + (rf/dispatch + [:keycard/get-more-keys + {:pin pin + :on-success #(rf/dispatch [:keycard.login/recover-profile-and-login %]) + :on-failure #(rf/dispatch [:keycard/on-action-with-pin-error %])}]))}]]]})) + +(rf/reg-event-fx :keycard.login/recover-profile-and-login + (fn [{:keys [db]} + [{:keys [key-uid encryption-public-key whisper-private-key instance-uid whisper-public-key + whisper-address address wallet-public-key wallet-address wallet-root-address]}]] + (let [{:keys [pairing]} (get-in db [:keycard :pairings instance-uid])] + {:db + (-> db + (assoc :onboarding/recovered-account? true) + (assoc-in [:syncing :login-sha3-password] encryption-public-key)) + + :fx [[:dispatch [:keycard/disconnect]] + [:dispatch [:navigate-to :screen/onboarding.preparing-status]] + [:effects.profile/restore-and-login + (assoc (profile.config/create) + :keycardInstanceUID instance-uid + :keycardPairingKey pairing + :keycard {:keyUID key-uid + :address (address/normalized-hex address) + :whisperPrivateKey (address/normalized-hex whisper-private-key) + :whisperPublicKey (address/normalized-hex whisper-public-key) + :whisperAddress (address/normalized-hex whisper-address) + :walletPublicKey (address/normalized-hex wallet-public-key) + :walletAddress (address/normalized-hex wallet-address) + :walletRootAddress (address/normalized-hex wallet-root-address) + :encryptionPublicKey encryption-public-key + :eip1581Address ""} + :displayName "" + :password encryption-public-key + :customizationColor constants/profile-default-color + :fetchBackup true)]]}))) diff --git a/src/status_im/contexts/keycard/nfc/events.cljs b/src/status_im/contexts/keycard/nfc/events.cljs index b2cb461f43..aca4073242 100644 --- a/src/status_im/contexts/keycard/nfc/events.cljs +++ b/src/status_im/contexts/keycard/nfc/events.cljs @@ -20,8 +20,6 @@ (rf/reg-event-fx :keycard.ios/on-nfc-user-cancelled (fn [{:keys [db]}] - {:db (-> db - (assoc-in [:keycard :pin :status] nil) - (assoc-in [:keycard :on-nfc-cancelled-event-vector] nil)) + {:db (assoc-in db [:keycard :on-nfc-cancelled-event-vector] nil) :fx [(when-let [on-nfc-cancelled-event-vector (get-in db [:keycard :on-nfc-cancelled-event-vector])] [:dispatch on-nfc-cancelled-event-vector])]})) diff --git a/src/status_im/contexts/keycard/pin/view.cljs b/src/status_im/contexts/keycard/pin/view.cljs index 27c2732abe..6563ed0146 100644 --- a/src/status_im/contexts/keycard/pin/view.cljs +++ b/src/status_im/contexts/keycard/pin/view.cljs @@ -1,5 +1,6 @@ (ns status-im.contexts.keycard.pin.view - (:require [quo.core :as quo] + (:require [clojure.string :as string] + [quo.core :as quo] [react-native.core :as rn] [status-im.constants :as constants] [utils.i18n :as i18n] @@ -20,7 +21,7 @@ :number-of-filled-pins (count text) :error? error? :info (when error? - (if error-message + (if (not (string/blank? error-message)) error-message (i18n/label :t/pin-retries-left {:number pin-retry-counter})))}]] [quo/numbered-keyboard diff --git a/src/status_im/contexts/keycard/utils.cljs b/src/status_im/contexts/keycard/utils.cljs index 6abbf84d11..6742650e91 100644 --- a/src/status_im/contexts/keycard/utils.cljs +++ b/src/status_im/contexts/keycard/utils.cljs @@ -15,6 +15,7 @@ (or (= error "Tag was lost.") (= error "NFCError:100") + (= error "Malformed card response") (re-matches #".*NFCError:100.*" error))) (defn validate-application-info @@ -28,12 +29,6 @@ (not has-master-key?) :keycard/error.keycard-blank - (not= profile-key-uid key-uid) - :keycard/error.keycard-wrong-profile - - (not paired?) - :keycard/error.keycard-unpaired - (and (zero? pin-retry-counter) (or (nil? puk-retry-counter) (pos? puk-retry-counter))) @@ -42,6 +37,12 @@ (zero? puk-retry-counter) :keycard/error.keycard-locked + (not paired?) + :keycard/error.keycard-unpaired + + (not= profile-key-uid key-uid) + :keycard/error.keycard-wrong-profile + :else nil)) diff --git a/src/status_im/contexts/onboarding/create_or_sync_profile/view.cljs b/src/status_im/contexts/onboarding/create_or_sync_profile/view.cljs index 98432e790c..5266b03baa 100644 --- a/src/status_im/contexts/onboarding/create_or_sync_profile/view.cljs +++ b/src/status_im/contexts/onboarding/create_or_sync_profile/view.cljs @@ -6,7 +6,6 @@ [react-native.safe-area :as safe-area] [status-im.common.check-before-syncing.view :as check-before-syncing] [status-im.common.metrics-confirmation-modal.view :as metrics-modal] - [status-im.common.not-implemented :as not-implemented] [status-im.common.resources :as resources] [status-im.config :as config] [status-im.contexts.onboarding.create-or-sync-profile.style :as style] @@ -109,14 +108,17 @@ :image (resources/get-image :ethereum-address) :on-press nav-to-seed-phrase-with-cur-screen}] [rn/view {:style style/space-between-suboptions}] - (when config/show-not-implemented-features? - [quo/small-option-card - {:variant :icon - :title (i18n/label :t/use-keycard) - :subtitle (i18n/label :t/use-keycard-subtitle) - :accessibility-label :use-keycard-option-card - :image (resources/get-image :use-keycard) - :on-press status-im.common.not-implemented/alert}])]])) + [quo/small-option-card + {:variant :icon + :title (i18n/label :t/use-keycard) + :subtitle (i18n/label :t/profile-keys-on-keycard) + :accessibility-label :use-keycard-option-card + :image (resources/get-image :use-keycard) + :on-press (fn [] + (rf/dispatch [:open-modal :screen/keycard.check + {:on-press + #(rf/dispatch + [:keycard.login/check-card])}]))}]]])) (defn- navigate-back [] diff --git a/src/status_im/contexts/profile/settings/list_items.cljs b/src/status_im/contexts/profile/settings/list_items.cljs index 5f735d6069..f7ec70d71b 100644 --- a/src/status_im/contexts/profile/settings/list_items.cljs +++ b/src/status_im/contexts/profile/settings/list_items.cljs @@ -1,7 +1,6 @@ (ns status-im.contexts.profile.settings.list-items (:require [status-im.common.not-implemented :as not-implemented] [status-im.config :as config] - [status-im.feature-flags :as ff] [utils.i18n :as i18n] [utils.re-frame :as rf])) @@ -55,13 +54,12 @@ :image :icon :blur? true :action :arrow}) - (when (ff/enabled? ::ff/keycard.migrate-profile) - {:title (i18n/label :t/keycard) - :on-press #(rf/dispatch [:open-modal :screen/settings.keycard]) - :image-props :i/keycard - :image :icon - :blur? true - :action :arrow})] + {:title (i18n/label :t/keycard) + :on-press #(rf/dispatch [:open-modal :screen/settings.keycard]) + :image-props :i/keycard + :image :icon + :blur? true + :action :arrow}] [{:title (i18n/label :t/privacy-and-security) :on-press #(rf/dispatch [:open-modal :screen/settings-privacy-and-security]) :image-props :i/privacy diff --git a/src/status_im/contexts/settings/keycard/view.cljs b/src/status_im/contexts/settings/keycard/view.cljs index b6e274304d..9ad176645f 100644 --- a/src/status_im/contexts/settings/keycard/view.cljs +++ b/src/status_im/contexts/settings/keycard/view.cljs @@ -43,4 +43,8 @@ :subtitle (i18n/label :t/ready-keycard) :accessibility-label :setup-keycard :image (resources/get-image :use-keycard) - :on-press #(rf/dispatch [:open-modal :screen/keycard.check])}]])])) + :on-press (fn [] + (rf/dispatch [:open-modal :screen/keycard.check + {:on-press + #(rf/dispatch + [:keycard/migration.check-empty-card])}]))}]])])) diff --git a/src/status_im/feature_flags.cljs b/src/status_im/feature_flags.cljs index 0b8a7394ce..61a5e083e9 100644 --- a/src/status_im/feature_flags.cljs +++ b/src/status_im/feature_flags.cljs @@ -30,8 +30,7 @@ ::wallet.long-press-watch-only-asset (enabled-in-env? :FLAG_LONG_PRESS_WATCH_ONLY_ASSET_ENABLED) ::wallet.saved-addresses (enabled-in-env? :WALLET_SAVED_ADDRESSES) ::wallet.wallet-connect (enabled-in-env? :FLAG_WALLET_CONNECT_ENABLED) - ::wallet.custom-network-amounts (enabled-in-env? :FLAG_WALLET_CUSTOM_NETWORK_AMOUNTS_ENABLED) - ::keycard.migrate-profile false}) + ::wallet.custom-network-amounts (enabled-in-env? :FLAG_WALLET_CUSTOM_NETWORK_AMOUNTS_ENABLED)}) (defonce ^:private feature-flags-config (reagent/atom initial-flags)) diff --git a/status-go-version.json b/status-go-version.json index 0ca1ab73a7..5d4531fb4c 100644 --- a/status-go-version.json +++ b/status-go-version.json @@ -3,7 +3,7 @@ "_comment": "Instead use: scripts/update-status-go.sh ", "owner": "status-im", "repo": "status-go", - "version": "v3.8.0", - "commit-sha1": "b3dbe91b5fab4fdab475ee94549629a6d2988ccc", - "src-sha256": "0p104qd799rwhiqxfdkd6gh4phsby6zyay98mv0sapjxim3nz4xi" + "version": "v3.9.0", + "commit-sha1": "79e662e4a563d650358e778871dc20ed71b0eb33", + "src-sha256": "035hz6pn0hkbb2383bdzmzdg214yjkv3aax6bq3dzvyxz002p0m7" } diff --git a/translations/en.json b/translations/en.json index eab2b399fe..3736ddbcd1 100644 --- a/translations/en.json +++ b/translations/en.json @@ -2010,6 +2010,7 @@ "profile-deleted-keycard": "You can now restore another key pair on your Keycard", "profile-deleted-title": "Profile deleted", "profile-details": "Profile details", + "profile-keys-on-keycard": "If your profile keys are stored on a Keycard", "profile-name": "Profile name", "profile-name-is-too-long": "Profile name is too long", "profile-not-found": "Profile not found",