Add seed phrase flow & customization color

This commit is contained in:
Jamie Caprani 2023-03-13 10:02:25 +00:00 committed by Andrea Maria Piana
parent 3b034265c0
commit 2f19badc6c
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
13 changed files with 213 additions and 32 deletions

View File

@ -335,7 +335,17 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
}
@ReactMethod
public void restoreAccountAndLogin(final String restoreAccountRequest) {
Log.d(TAG, "restoreAccountAndLogin");
String result = Statusgo.restoreAccountAndLogin(restoreAccountRequest);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "restoreAccountAndLogin success: " + result);
Log.d(TAG, "Geth node started");
} else {
Log.e(TAG, "restoreAccountAndLogin failed: " + result);
}
}
@ReactMethod
public void saveAccountAndLogin(final String multiaccountData, final String password, final String settings, final String config, final String accountsData) {

View File

@ -974,6 +974,13 @@ RCT_EXPORT_METHOD(createAccountAndLogin:(NSString *)request) {
StatusgoCreateAccountAndLogin(request);
}
RCT_EXPORT_METHOD(restoreAccountAndLogin:(NSString *)request) {
#if DEBUG
NSLog(@"restoreAccountAndLogin() method called");
#endif
StatusgoRestoreAccountAndLogin(request);
}
RCT_EXPORT_METHOD(generateAliasAndIdenticonAsync:(NSString *)publicKey
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG

View File

@ -202,7 +202,7 @@
(defn words-count
[s]
(if (empty? s)
nil
0
(-> s
passphrase->words
count)))

View File

@ -95,6 +95,10 @@
[request]
(.createAccountAndLogin ^js (status) (types/clj->json request)))
(defn restore-account-and-login
[request]
(.restoreAccountAndLogin ^js (status) (types/clj->json request)))
(defn export-db
"NOTE: beware, the password has to be sha3 hashed"
[key-uid account-data hashed-password callback]

View File

@ -295,3 +295,5 @@
(def ^:const everyone-mention-id "0x00001")
(def ^:const empty-category-id :communities/not-categorized)
(def ^:const seed-phrase-valid-length #{12 18 24})

View File

@ -1,9 +1,9 @@
(ns status-im2.contexts.onboarding.create-profile.view
(:require [clojure.string :as string]
[utils.i18n :as i18n]
[quo2.core :as quo]
(:require [quo2.core :as quo]
[clojure.string :as string]
[quo2.foundations.colors :as colors]
[status-im2.contexts.onboarding.create-profile.style :as style]
[utils.i18n :as i18n]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.contexts.onboarding.common.background.view :as background]

View File

@ -0,0 +1,14 @@
(ns status-im2.contexts.onboarding.enter-seed-phrase.style
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]))
(def page-container
{:padding-top (if platform/ios? 44 0)
:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:background-color colors/neutral-80-opa-80-blur})
(def navigation-bar {:height 56})

View File

@ -0,0 +1,79 @@
(ns status-im2.contexts.onboarding.enter-seed-phrase.view
(:require [quo2.core :as quo]
[quo.core :as quo1]
[clojure.string :as string]
[status-im.ethereum.mnemonic :as mnemonic]
[status-im2.constants :as constants]
[utils.security.core :as security]
[utils.re-frame :as rf]
[reagent.core :as reagent]
[react-native.core :as rn]
[status-im2.contexts.onboarding.enter-seed-phrase.style :as style]
[status-im2.contexts.onboarding.common.background.view :as background]
[utils.i18n :as i18n]))
(defn navigation-bar
[]
[rn/view {:style style/navigation-bar}
[quo/page-nav
{:align-mid? true
:left-section {:type :blur-bg
:icon :i/arrow-left
:icon-override-theme :dark
:on-press #(rf/dispatch [:navigate-back])}
:mid-section {:type :text-only :main-text ""}}]])
(def button-disabled?
(comp not constants/seed-phrase-valid-length mnemonic/words-count))
(defn clean-seed-phrase
[s]
(as-> s $
(string/lower-case $)
(string/split $ #"\s")
(filter #(not (string/blank? %)) $)
(string/join " " $)))
(defn page
[]
(let [seed-phrase (reagent/atom "")
error-message (reagent/atom "")
on-invalid-seed-phrase #(reset! error-message (i18n/label :t/custom-seed-phrase))]
(fn []
[rn/view {:style style/page-container}
[navigation-bar]
[rn/view {:style {:padding-horizontal 20}}
[quo/text
{:weight :bold
:align :center}
(i18n/label :t/use-recovery-phrase)]
[quo/text
(i18n/label-pluralize (mnemonic/words-count @seed-phrase) :t/words-n)]
[:<>
[quo1/text-input
{:on-change-text (fn [t]
(reset! seed-phrase (clean-seed-phrase t))
(reset! error-message ""))
:auto-focus true
:accessibility-label :passphrase-input
:placeholder (i18n/label :t/seed-phrase-placeholder)
:show-cancel false
:bottom-value 40
:multiline true
:auto-correct false
:keyboard-type :visible-password
:monospace true}]]
[quo/button
{:disabled (button-disabled? @seed-phrase)
:on-press #(rf/dispatch [:onboarding-2/seed-phrase-entered
(security/mask-data @seed-phrase)
on-invalid-seed-phrase])}
(i18n/label :t/continue)]
(when (seq @error-message)
[quo/text @error-message])]])))
(defn enter-seed-phrase
[]
[rn/view {:style {:flex 1}}
[background/view true]
[page]])

View File

@ -2,6 +2,7 @@
(:require
[utils.re-frame :as rf]
[re-frame.core :as re-frame]
[status-im.utils.types :as types]
[status-im2.config :as config]
[clojure.string :as string]
[utils.security.core :as security]
@ -9,27 +10,32 @@
[status-im.ethereum.core :as ethereum]))
(re-frame/reg-fx
::create-account-and-login
:multiaccount/create-account-and-login
(fn [request]
(status/create-account-and-login request)))
(rf/defn on-delete-profile-success
{:events [:onboarding-2/on-delete-profile-success]}
[{:keys [db]} key-uid]
{:db (update-in db [:multiaccounts/multiaccounts] dissoc key-uid)})
(re-frame/reg-fx
:multiaccount/validate-mnemonic
(fn [[mnemonic on-success on-error]]
(status/validate-mnemonic
(security/safe-unmask-data mnemonic)
(fn [result]
(let [{:keys [error]} (types/json->clj result)]
(if (seq error)
(when on-error (on-error error))
(on-success mnemonic)))))))
(re-frame/reg-fx
:multiaccount/restore-account-and-login
(fn [request]
(status/restore-account-and-login request)))
(rf/defn profile-data-set
{:events [:onboarding-2/profile-data-set]}
[{:keys [db]} onboarding-data]
{:db (assoc db :onboarding-2/profile onboarding-data)
{:db (update db :onboarding-2/profile merge onboarding-data)
:dispatch [:navigate-to :create-profile-password]})
(rf/defn password-set
{:events [:onboarding-2/password-set]}
[{:keys [db]} password]
{:db (assoc-in db [:onboarding-2/profile :password] password)
:dispatch [:navigate-to :enable-biometrics]})
(defn strip-file-prefix
[path]
(when path
@ -39,14 +45,20 @@
{:events [:onboarding-2/create-account-and-login]}
[{:keys [db]}]
(let [{:keys [display-name
seed-phrase
password
image-path
color]} (:onboarding-2/profile db)
log-enabled? (boolean (not-empty config/log-level))
effect (if seed-phrase
:multiaccount/restore-account-and-login
:multiaccount/create-account-and-login)
request {:displayName display-name
:password (ethereum/sha3 (security/safe-unmask-data password))
:mnemonic (when seed-phrase
(security/safe-unmask-data seed-phrase))
:imagePath (strip-file-prefix image-path)
:color color
:customizationColor color
:backupDisabledDataDir (status/backup-disabled-data-dir)
:rootKeystoreDir (status/keystore-dir)
;; Temporary fix until https://github.com/status-im/status-go/issues/3024 is
@ -60,8 +72,40 @@
:verifyENSURL config/verify-ens-url
:verifyENSContractAddress config/verify-ens-contract-address
:verifyTransactionChainID config/verify-transaction-chain-id}]
{::create-account-and-login request
:dispatch [:navigate-to :generating-keys]
:db (-> db
(dissoc :onboarding-2/profile)
(assoc :onboarding-2/new-account? true))}))
{effect request
:dispatch [:navigate-to :generating-keys]
:db (-> db
(dissoc :onboarding-2/profile)
(assoc :onboarding-2/new-account? true))}))
(rf/defn on-delete-profile-success
{:events [:onboarding-2/on-delete-profile-success]}
[{:keys [db]} key-uid]
{:db (update-in db [:multiaccounts/multiaccounts] dissoc key-uid)})
(rf/defn password-set
{:events [:onboarding-2/password-set]}
[{:keys [db]} password]
{:db (assoc-in db [:onboarding-2/profile :password] password)
:dispatch [:navigate-to :enable-biometrics]})
(rf/defn seed-phrase-entered
{:events [:onboarding-2/seed-phrase-entered]}
[_ seed-phrase on-error]
{:multiaccount/validate-mnemonic [seed-phrase
#(re-frame/dispatch [:onboarding-2/seed-phrase-validated
seed-phrase])
on-error]})
(rf/defn seed-phrase-validated
{:events [:onboarding-2/seed-phrase-validated]}
[{:keys [db]} seed-phrase]
{:db (assoc-in db [:onboarding-2/profile :seed-phrase] seed-phrase)
:dispatch [:navigate-to :create-profile]})
(rf/defn navigate-to-create-profile
{:events [:onboarding-2/navigate-to-create-profile]}
[{:keys [db]}]
;; Restart the flow
{:db (dissoc db :onboarding-2/profile)
:dispatch [:navigate-to :create-profile]})

View File

@ -49,7 +49,7 @@
(* 2 56) ;; two other list items
(* 2 16) ;; spacing between items
220) ;; extra spacing (top bar)
:on-press #(rf/dispatch [:navigate-to :create-profile])}]
:on-press #(rf/dispatch [:onboarding-2/navigate-to-create-profile])}]
[rn/view {:style style/subtitle-container}
[quo/text
@ -69,11 +69,18 @@
[rn/view {:style style/space-between-suboptions}]
[quo/small-option-card
{:variant :icon
:title (i18n/label :t/use-recovery-phrase)
:title "Temporary (old) recover phrase flow"
:subtitle (i18n/label :t/use-recovery-phrase-subtitle)
:image (resources/get-image :ethereum-address)
:on-press #(rf/dispatch [::multiaccounts.recover/enter-phrase-pressed])}]
[rn/view {:style style/space-between-suboptions}]
[quo/small-option-card
{:variant :icon
:title (i18n/label :t/use-recovery-phrase)
:subtitle (i18n/label :t/use-recovery-phrase-subtitle)
:image (resources/get-image :ethereum-address)
:on-press #(rf/dispatch [:navigate-to :enter-seed-phrase])}]
[rn/view {:style style/space-between-suboptions}]
[quo/small-option-card
{:variant :icon
:title (i18n/label :t/use-keycard)

View File

@ -52,16 +52,23 @@
(keychain/get-auth-method (:key-uid multiaccount))))
(navigation/init-root cofx :intro))))
(defn rpc->multiaccount
[{:keys [customizationColor keycard-pairing] :as multiaccount}]
(-> multiaccount
(dissoc :customizationColor)
(assoc :customization-color (keyword customizationColor))
(assoc :keycard-pairing
(when-not
(string/blank? keycard-pairing)
keycard-pairing))))
(rf/defn initialize-multiaccounts
{:events [:setup/initialize-multiaccounts]}
[{:keys [db] :as cofx} all-multiaccounts {:keys [logout?]}]
(let [multiaccounts (reduce (fn [acc
{:keys [key-uid keycard-pairing]
:as multiaccount}]
(-> (assoc acc key-uid multiaccount)
(assoc-in [key-uid :keycard-pairing]
(when-not (string/blank? keycard-pairing)
keycard-pairing))))
(assoc acc key-uid (rpc->multiaccount multiaccount)))
{}
all-multiaccounts)]
(rf/merge cofx

View File

@ -22,6 +22,7 @@
[status-im2.contexts.onboarding.sign-in.view :as sign-in]
[status-im2.contexts.onboarding.syncing.syncing-devices.view :as syncing-devices]
[status-im2.contexts.onboarding.generating-keys.view :as generating-keys]
[status-im2.contexts.onboarding.enter-seed-phrase.view :as enter-seed-phrase]
[status-im2.contexts.onboarding.profiles.view :as profiles]
[status-im2.contexts.quo-preview.main :as quo.preview]
[status-im2.contexts.shell.view :as shell]
@ -168,6 +169,12 @@
:insets {:top false}
:component generating-keys/generating-keys}
{:name :enter-seed-phrase
:options {:statusBar {:style :light}
:topBar {:visible false}
:navigationBar {:backgroundColor colors/black}}
:insets {:top false}
:component enter-seed-phrase/enter-seed-phrase}
{:name :enable-notifications
:options {:statusBar {:style :light}

View File

@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v0.140.0",
"commit-sha1": "7cd7430d3141b08f7c455d7918f4160ea8fd0559",
"src-sha256": "0lgkzrl7zas9mxpngksmh5r26j5811x9xxx9byrcqnyirmks3622"
"version": "v0.140.1",
"commit-sha1": "e2082bf5bdd2c43bf1f140ddc4d3eece6de88bc0",
"src-sha256": "1gfykjs51862kbfjqr2sslsdhmn4j19hj67zr34gm3xdcy9ci0xx"
}