From bda232badad8acee4196e2a4d51c513a87cb0b6b Mon Sep 17 00:00:00 2001 From: Parvesh Monu Date: Tue, 20 Aug 2024 19:31:42 +0530 Subject: [PATCH] Implement seed phrase fallback flow https://github.com/status-im/status-go/compare/9e7d1303...51279988 --- src/legacy/status_im/pairing/core.cljs | 29 ++++++- .../common/new_device_sheet/style.cljs | 23 ++++++ .../common/new_device_sheet/view.cljs | 76 +++++++++++++++++++ .../onboarding/common/overlay/events.cljs | 14 ++++ src/status_im/contexts/onboarding/events.cljs | 38 ++++++---- .../onboarding/syncing/progress/view.cljs | 49 +++++++++--- .../contexts/profile/login/events.cljs | 2 + .../contexts/profile/recover/events.cljs | 17 +++-- src/status_im/contexts/syncing/events.cljs | 23 +++++- src/status_im/subs/profile.cljs | 5 ++ status-go-version.json | 6 +- translations/en.json | 3 + 12 files changed, 243 insertions(+), 42 deletions(-) create mode 100644 src/status_im/common/new_device_sheet/style.cljs create mode 100644 src/status_im/common/new_device_sheet/view.cljs diff --git a/src/legacy/status_im/pairing/core.cljs b/src/legacy/status_im/pairing/core.cljs index 916ab2de3df3..d0dd08ea56b3 100644 --- a/src/legacy/status_im/pairing/core.cljs +++ b/src/legacy/status_im/pairing/core.cljs @@ -4,6 +4,7 @@ [re-frame.core :as re-frame] [react-native.platform :as utils.platform] [status-im.common.json-rpc.events :as json-rpc] + [status-im.common.new-device-sheet.view :as new-device-sheet] [status-im.config :as config] [status-im.navigation.events :as navigation] [taoensso.timbre :as log] @@ -220,6 +221,11 @@ :name (:name metadata) :device-type (:deviceType metadata))}) +(defn should-show-syncing-pop-up? + [db installations] + (and (:syncing/pairing-process-initiated? db) + (first (filter #(not (get-in db [:pairing/installations (:id %)])) installations)))) + (rf/defn handle-installations [{:keys [db]} installations] {:db (update db @@ -228,7 +234,10 @@ (fn [acc {:keys [id] :as i}] (update acc id merge (installation<-rpc i))) % - installations))}) + installations)) + :fx [(when-let [new-installation (should-show-syncing-pop-up? db installations)] + [:dispatch + [:show-bottom-sheet {:content (fn [] [new-device-sheet/view (:id new-installation)])}]])]}) (rf/defn load-installations {:events [:pairing.callback/get-our-installations-success]} @@ -243,6 +252,24 @@ {} installations))}) +(rf/defn finish-seed-phrase-fallback-syncing + {:events [:pairing/finish-seed-phrase-fallback-syncing]} + [{:keys [db]}] + {:fx [[:dispatch [:show-bottom-sheet {:content (fn [] [new-device-sheet/view-2])}]] + [:json-rpc/call + [{:method "wakuext_finishPairingThroughSeedPhraseProcess" + :params [{:installationId (:syncing/installation-id db)}] + :js-response true + :on-success #(rf/dispatch [:sanitize-messages-and-process-response %])}]]]}) + +(rf/defn pair-and-sync + {:events [:pairing/pair-and-sync]} + [cofx installation-id] + {:fx [[:json-rpc/call + [{:method "wakuext_enableAndSyncInstallation" + :params [{:installationId installation-id}] + :on-success #(log/debug "successfully synced devices")}]]]}) + (rf/defn enable-installation-success {:events [:pairing.callback/enable-installation-success]} [cofx installation-id] diff --git a/src/status_im/common/new_device_sheet/style.cljs b/src/status_im/common/new_device_sheet/style.cljs new file mode 100644 index 000000000000..9d71a9df0660 --- /dev/null +++ b/src/status_im/common/new_device_sheet/style.cljs @@ -0,0 +1,23 @@ +(ns status-im.common.new-device-sheet.style + (:require [quo.foundations.colors :as colors])) + +(def heading + {:padding-left 20 + :padding-bottom 8}) + +(def message + {:padding-horizontal 20 + :padding-top 4}) + +(def warning + {:margin-horizontal 20 + :margin-top 10}) + +(def drawer-container + {:padding-horizontal 13 + :padding-top 16}) + +(def settings-subtext + {:color colors/white-opa-70 + :align-self :center + :margin-bottom 12}) diff --git a/src/status_im/common/new_device_sheet/view.cljs b/src/status_im/common/new_device_sheet/view.cljs new file mode 100644 index 000000000000..97044ce496de --- /dev/null +++ b/src/status_im/common/new_device_sheet/view.cljs @@ -0,0 +1,76 @@ +(ns status-im.common.new-device-sheet.view + (:require + [quo.core :as quo] + [react-native.core :as rn] + [status-im.common.new-device-sheet.style :as style] + [utils.i18n :as i18n] + [utils.re-frame :as rf] + [utils.user-actions :as user-actions])) + +(defn- pair-and-sync + [installation-id] + (rf/dispatch [:pairing/pair-and-sync installation-id]) + (user-actions/hide-bottom-sheet)) + +(defn view + [installation-id] + (rn/use-mount user-actions/dismiss-keyboard) + [:<> + [quo/text + {:weight :semi-bold + :size :heading-2 + :accessibility-label :new-device-sheet-heading + :style style/heading} + (i18n/label :t/pair-new-device-and-sync)] + [quo/text + {:weight :regular + :size :paragraph-1 + :accessibility-label :new-device-sheet-message + :style style/message} + (i18n/label :t/new-device-detected)] + [quo/text + {:weight :semi-bold + :size :heading-2 + :accessibility-label :new-device-installation-id + :style style/heading} + installation-id] + [quo/bottom-actions + {:actions :two-actions + :blur? true + :container-style {:margin-top 12} + :button-two-label (i18n/label :t/cancel) + :button-two-props {:type :grey + :on-press user-actions/hide-bottom-sheet} + :button-one-label (i18n/label :t/pair-and-sync) + :button-one-props {:on-press #(pair-and-sync installation-id)}}]]) + +(defn view-2 + [] + (let [installation-id (rf/sub [:profile/installation-id])] + (rn/use-mount user-actions/dismiss-keyboard) + [:<> + [quo/text + {:weight :semi-bold + :size :heading-2 + :accessibility-label :new-device-sheet-heading + :style style/heading} + (i18n/label :t/pair-new-device-and-sync)] + [quo/text + {:weight :regular + :size :paragraph-1 + :accessibility-label :new-device-sheet-message + :style style/message} + (i18n/label :t/new-device-detected)] + [quo/text + {:weight :semi-bold + :size :heading-2 + :accessibility-label :new-device-installation-id + :style style/heading} + installation-id] + [quo/bottom-actions + {:actions :one-action + :blur? true + :container-style {:margin-top 12} + :button-one-label (i18n/label :t/close) + :button-one-props {:type :grey + :on-press user-actions/hide-bottom-sheet}}]])) diff --git a/src/status_im/contexts/onboarding/common/overlay/events.cljs b/src/status_im/contexts/onboarding/common/overlay/events.cljs index 42f07ade1df9..57b387e73a75 100644 --- a/src/status_im/contexts/onboarding/common/overlay/events.cljs +++ b/src/status_im/contexts/onboarding/common/overlay/events.cljs @@ -17,3 +17,17 @@ {:events [:onboarding/overlay-dismiss]} [_] {:onboarding/overlay-dismiss-fx nil}) + +(re-frame/reg-fx + :onboarding/overlay-show-fx + (fn [] + (when-let [blur-show-fn @overlay/blur-show-fn-atom] + (blur-show-fn)) + (when-let [push-animation-fn @profiles/push-animation-fn-atom] + (push-animation-fn)))) + +(rf/defn overlay-show + {:events [:onboarding/overlay-show]} + [_] + {:onboarding/overlay-show-fx nil}) + diff --git a/src/status_im/contexts/onboarding/events.cljs b/src/status_im/contexts/onboarding/events.cljs index e368cabdbb0f..284c37fea4e8 100644 --- a/src/status_im/contexts/onboarding/events.cljs +++ b/src/status_im/contexts/onboarding/events.cljs @@ -125,25 +125,31 @@ mnemonic key-uid])) on-error]}) +;; TODO: clear syncing data if key-uid does not match (rf/defn seed-phrase-validated {:events [:onboarding/seed-phrase-validated]} [{:keys [db]} seed-phrase key-uid] - (if (contains? (:profile/profiles-overview db) key-uid) - {:effects.utils/show-confirmation - {:title (i18n/label :t/multiaccount-exists-title) - :content (i18n/label :t/multiaccount-exists-content) - :confirm-button-text (i18n/label :t/unlock) - :on-accept (fn [] - (re-frame/dispatch [:pop-to-root :screen/profile.profiles]) - (re-frame/dispatch - [:profile/profile-selected key-uid])) - :on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}} - {:db (assoc-in db [:onboarding/profile :seed-phrase] seed-phrase) - :dispatch [:navigate-to-within-stack - [:screen/onboarding.create-profile - (get db - :onboarding/navigated-to-enter-seed-phrase-from-screen - :screen/onboarding.new-to-status)]]})) + (let [next-screen (if (and (seq (:syncing/key-uid db)) + (= (:syncing/key-uid db) key-uid)) + :screen/onboarding.create-profile-password + :screen/onboarding.create-profile)] + + (if (contains? (:profile/profiles-overview db) key-uid) + {:effects.utils/show-confirmation + {:title (i18n/label :t/multiaccount-exists-title) + :content (i18n/label :t/multiaccount-exists-content) + :confirm-button-text (i18n/label :t/unlock) + :on-accept (fn [] + (re-frame/dispatch [:pop-to-root :screen/profile.profiles]) + (re-frame/dispatch + [:profile/profile-selected key-uid])) + :on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}} + {:db (assoc-in db [:onboarding/profile :seed-phrase] seed-phrase) + :dispatch [:navigate-to-within-stack + [next-screen + (get db + :onboarding/navigated-to-enter-seed-phrase-from-screen + :screen/onboarding.new-to-status)]]}))) (rf/defn navigate-to-create-profile {:events [:onboarding/navigate-to-create-profile]} diff --git a/src/status_im/contexts/onboarding/syncing/progress/view.cljs b/src/status_im/contexts/onboarding/syncing/progress/view.cljs index c32a0f98b508..633e72b2829f 100644 --- a/src/status_im/contexts/onboarding/syncing/progress/view.cljs +++ b/src/status_im/contexts/onboarding/syncing/progress/view.cljs @@ -5,6 +5,7 @@ [status-im.common.resources :as resources] [status-im.contexts.onboarding.common.background.view :as background] [status-im.contexts.onboarding.syncing.progress.style :as style] + [utils.debounce :as debounce] [utils.i18n :as i18n] [utils.re-frame :as rf])) @@ -25,17 +26,42 @@ :title-accessibility-label :progress-screen-title :description-accessibility-label :progress-screen-sub-title}]) +(defn navigate-to-enter-seed-phrase + [view-id] + (if (= view-id :screen/onboarding.syncing-progress-intro) + (do + (rf/dispatch [:navigate-back-to :screen/onboarding.sync-or-recover-profile]) + (debounce/debounce-and-dispatch + [:onboarding/navigate-to-sign-in-by-seed-phrase :screen/onboarding.sync-or-recover-profile] + 300)) + (do + (rf/dispatch [:navigate-back]) + (debounce/debounce-and-dispatch [:onboarding/overlay-show] 100) + (debounce/debounce-and-dispatch [:open-modal :screen/onboarding.new-to-status] 200) + (debounce/debounce-and-dispatch + [:onboarding/navigate-to-sign-in-by-seed-phrase :screen/onboarding.new-to-status] + 300)))) + (defn try-again-button - [profile-color] - [quo/button - {:on-press (fn [] - (rf/dispatch [:syncing/clear-states]) - (rf/dispatch [:navigate-back])) - :accessibility-label :try-again-later-button - :customization-color profile-color - :size 40 - :container-style style/try-again-button} - (i18n/label :t/try-again)]) + [profile-color logged-in?] + (let [view-id (rf/sub [:view-id])] + [rn/view + (when-not logged-in? + [quo/button + {:on-press #(navigate-to-enter-seed-phrase view-id) + :accessibility-label :try-seed-phrase-button + :customization-color profile-color + :container-style style/try-again-button} + (i18n/label :t/enter-seed-phrase)]) + [quo/button + {:on-press (fn [] + (rf/dispatch [:syncing/clear-states]) + (rf/dispatch [:navigate-back])) + :accessibility-label :try-again-later-button + :customization-color profile-color + :size 40 + :container-style style/try-again-button} + (i18n/label :t/try-again)]])) (defn- illustration [pairing-progress?] @@ -47,6 +73,7 @@ (defn view [in-onboarding?] (let [pairing-status (rf/sub [:pairing/pairing-status]) + logged-in? (rf/sub [:multiaccount/logged-in?]) pairing-progress? (pairing-progress pairing-status) profile-color (or (:color (rf/sub [:onboarding/profile])) (rf/sub [:profile/customization-color]))] @@ -58,7 +85,7 @@ [page-title pairing-progress?] [illustration pairing-progress?] (when-not (pairing-progress pairing-status) - [try-again-button profile-color])])) + [try-again-button profile-color logged-in?])])) (defn view-onboarding [] diff --git a/src/status_im/contexts/profile/login/events.cljs b/src/status_im/contexts/profile/login/events.cljs index 58e755f6410e..588b648d3d87 100644 --- a/src/status_im/contexts/profile/login/events.cljs +++ b/src/status_im/contexts/profile/login/events.cljs @@ -133,6 +133,8 @@ (rf/dispatch [:chats-list/load-success result]) (rf/dispatch [:communities/get-user-requests-to-join]) (rf/dispatch [:profile.login/get-chats-callback]))}] + (when (:syncing/installation-id db) + [:dispatch [:pairing/finish-seed-phrase-fallback-syncing]]) (when-not new-account? [:dispatch [:universal-links/process-stored-event]])]}))) diff --git a/src/status_im/contexts/profile/recover/events.cljs b/src/status_im/contexts/profile/recover/events.cljs index 045b4679ef4c..f7c631d11b9d 100644 --- a/src/status_im/contexts/profile/recover/events.cljs +++ b/src/status_im/contexts/profile/recover/events.cljs @@ -2,6 +2,7 @@ (:require [native-module.core :as native-module] [status-im.common.emoji-picker.utils :as emoji-picker.utils] + [status-im.constants :as constants] [status-im.contexts.profile.config :as profile.config] status-im.contexts.profile.recover.effects [utils.re-frame :as rf] @@ -17,11 +18,11 @@ (assoc-in [:syncing :login-sha3-password] login-sha3-password)) :effects.profile/restore-and-login - (merge (profile.config/create) - {:displayName display-name - :mnemonic (security/safe-unmask-data seed-phrase) - :password login-sha3-password - :imagePath (profile.config/strip-file-prefix image-path) - :customizationColor color - :emoji (emoji-picker.utils/random-emoji) - :fetchBackup true})})) + (assoc (profile.config/create) + :displayName display-name + :mnemonic (security/safe-unmask-data seed-phrase) + :password login-sha3-password + :imagePath (profile.config/strip-file-prefix image-path) + :customizationColor (or color constants/profile-default-color) + :emoji (emoji-picker.utils/random-emoji) + :fetchBackup true)})) diff --git a/src/status_im/contexts/syncing/events.cljs b/src/status_im/contexts/syncing/events.cljs index 87c69c6acfb3..d4b3e554629b 100644 --- a/src/status_im/contexts/syncing/events.cljs +++ b/src/status_im/contexts/syncing/events.cljs @@ -26,13 +26,29 @@ (log/info "[local-pairing] input-connection-string-for-bootstrapping callback" {:response res :event :syncing/input-connection-string-for-bootstrapping}) - (let [error (when (sync-utils/extract-error res) - (str "generic-error: " res))] - (when (some? error) + (let [response (transforms/json->clj res) + installation-id (:installationId response) + key-uid (:keyUID response) + error (:error response)] + (when (seq installation-id) + (rf/dispatch [:syncing/set-syncing-installation-id installation-id key-uid])) + (when (seq error) (rf/dispatch [:toasts/upsert {:type :negative :text error}])))) +(rf/defn initiate-pairing-process + {:events [:syncing/initiate-pairing-process]} + [{:keys [db]}] + {:db (assoc db :syncing/pairing-process-initiated? true)}) + +(rf/defn set-syncing-installation-id + {:events [:syncing/set-syncing-installation-id]} + [{:keys [db]} installation-id key-uid] + {:db (assoc db + :syncing/key-uid key-uid + :syncing/installation-id installation-id)}) + (rf/defn preflight-outbound-check-for-local-pairing {:events [:syncing/preflight-outbound-check]} [_ set-checks-passed] @@ -67,6 +83,7 @@ (when (sync-utils/valid-connection-string? response) (on-valid-connection-string response) (rf/dispatch [:syncing/update-role constants/local-pairing-role-sender]) + (rf/dispatch [:syncing/initiate-pairing-process]) (rf/dispatch [:hide-bottom-sheet])))] (when-not (and error (string/blank? error)) (let [key-uid (get-in db [:profile/profile :key-uid]) diff --git a/src/status_im/subs/profile.cljs b/src/status_im/subs/profile.cljs index c7f3b26c2215..1f408bde8045 100644 --- a/src/status_im/subs/profile.cljs +++ b/src/status_im/subs/profile.cljs @@ -257,6 +257,11 @@ (fn [{:keys [preview-privacy?]}] (boolean preview-privacy?))) +(re-frame/reg-sub :profile/installation-id + :<- [:profile/profile] + (fn [{:keys [installation-id]}] + installation-id)) + (defn- replace-multiaccount-image-uri [profile ens-names port font-file avatar-opts theme] (let [{:keys [key-uid ens-name? images diff --git a/status-go-version.json b/status-go-version.json index 1b9df8afd876..63c5f3d3aae1 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": "v0.184.46", - "commit-sha1": "9e7d13039e50eeb815e7fa7082080d2ec5c81493", - "src-sha256": "02f8s7bfq8wavdkqg4wpraan4j3vi1p8h1r22ngzp9nxfwjif8xr" + "version": "feat/enable_sync_fallback", + "commit-sha1": "51279988115c2d9f541df149d00612528883d9cc", + "src-sha256": "1r4p2jizwwvqi8jih2rd9hf89xzhvvzsy7iins2sskkivhly1a2d" } diff --git a/translations/en.json b/translations/en.json index 3dd2b241cb55..1e87da4bb440 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1634,6 +1634,7 @@ "new-community-title": "New community", "new-contact": "New contact", "new-contract": "New Contract", + "new-device-detected": "A new device has been detected. You can see device ID below and on your other device. Only confirm the request if device ID matches.", "new-favourite": "New favourite", "new-group": "New group", "new-group-chat": "New group chat", @@ -1799,12 +1800,14 @@ "page-camera-request-blocked": "camera requests blocked. To enable camera requests go to Settings", "page-would-like-to-use-camera": "would like to use your camera", "pair": "Pair", + "pair-and-sync": "Pair and Sync", "pair-card": "Pair to this device", "pair-code": "Pair code", "pair-code-explanation": "Pairs card to a different device (up to 5) to unlock keys and sign transactions with the same Keycard", "pair-code-placeholder": "Pair code...", "pair-device-toast": "Device successfully paired", "pair-devices": "Pair devices", + "pair-new-device-and-sync": "Pair new device and sync profile", "pair-this-card": "Pair this card", "pair-this-device": "Advertise device", "pair-this-device-description": "Pair your devices to sync contacts and chats between them",