mirror of
https://github.com/status-im/status-mobile.git
synced 2025-01-12 17:54:32 +00:00
Add seed phrase flow & customization color
This commit is contained in:
parent
3b034265c0
commit
2f19badc6c
@ -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
|
@ReactMethod
|
||||||
public void saveAccountAndLogin(final String multiaccountData, final String password, final String settings, final String config, final String accountsData) {
|
public void saveAccountAndLogin(final String multiaccountData, final String password, final String settings, final String config, final String accountsData) {
|
||||||
|
@ -974,6 +974,13 @@ RCT_EXPORT_METHOD(createAccountAndLogin:(NSString *)request) {
|
|||||||
StatusgoCreateAccountAndLogin(request);
|
StatusgoCreateAccountAndLogin(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(restoreAccountAndLogin:(NSString *)request) {
|
||||||
|
#if DEBUG
|
||||||
|
NSLog(@"restoreAccountAndLogin() method called");
|
||||||
|
#endif
|
||||||
|
StatusgoRestoreAccountAndLogin(request);
|
||||||
|
}
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(generateAliasAndIdenticonAsync:(NSString *)publicKey
|
RCT_EXPORT_METHOD(generateAliasAndIdenticonAsync:(NSString *)publicKey
|
||||||
callback:(RCTResponseSenderBlock)callback) {
|
callback:(RCTResponseSenderBlock)callback) {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
@ -202,7 +202,7 @@
|
|||||||
(defn words-count
|
(defn words-count
|
||||||
[s]
|
[s]
|
||||||
(if (empty? s)
|
(if (empty? s)
|
||||||
nil
|
0
|
||||||
(-> s
|
(-> s
|
||||||
passphrase->words
|
passphrase->words
|
||||||
count)))
|
count)))
|
||||||
|
@ -95,6 +95,10 @@
|
|||||||
[request]
|
[request]
|
||||||
(.createAccountAndLogin ^js (status) (types/clj->json request)))
|
(.createAccountAndLogin ^js (status) (types/clj->json request)))
|
||||||
|
|
||||||
|
(defn restore-account-and-login
|
||||||
|
[request]
|
||||||
|
(.restoreAccountAndLogin ^js (status) (types/clj->json request)))
|
||||||
|
|
||||||
(defn export-db
|
(defn export-db
|
||||||
"NOTE: beware, the password has to be sha3 hashed"
|
"NOTE: beware, the password has to be sha3 hashed"
|
||||||
[key-uid account-data hashed-password callback]
|
[key-uid account-data hashed-password callback]
|
||||||
|
@ -295,3 +295,5 @@
|
|||||||
(def ^:const everyone-mention-id "0x00001")
|
(def ^:const everyone-mention-id "0x00001")
|
||||||
|
|
||||||
(def ^:const empty-category-id :communities/not-categorized)
|
(def ^:const empty-category-id :communities/not-categorized)
|
||||||
|
|
||||||
|
(def ^:const seed-phrase-valid-length #{12 18 24})
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
(ns status-im2.contexts.onboarding.create-profile.view
|
(ns status-im2.contexts.onboarding.create-profile.view
|
||||||
(:require [clojure.string :as string]
|
(:require [quo2.core :as quo]
|
||||||
[utils.i18n :as i18n]
|
[clojure.string :as string]
|
||||||
[quo2.core :as quo]
|
|
||||||
[quo2.foundations.colors :as colors]
|
[quo2.foundations.colors :as colors]
|
||||||
[status-im2.contexts.onboarding.create-profile.style :as style]
|
[status-im2.contexts.onboarding.create-profile.style :as style]
|
||||||
|
[utils.i18n :as i18n]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im2.contexts.onboarding.common.background.view :as background]
|
[status-im2.contexts.onboarding.common.background.view :as background]
|
||||||
|
@ -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})
|
@ -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]])
|
@ -2,6 +2,7 @@
|
|||||||
(:require
|
(:require
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
|
[status-im.utils.types :as types]
|
||||||
[status-im2.config :as config]
|
[status-im2.config :as config]
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[utils.security.core :as security]
|
[utils.security.core :as security]
|
||||||
@ -9,27 +10,32 @@
|
|||||||
[status-im.ethereum.core :as ethereum]))
|
[status-im.ethereum.core :as ethereum]))
|
||||||
|
|
||||||
(re-frame/reg-fx
|
(re-frame/reg-fx
|
||||||
::create-account-and-login
|
:multiaccount/create-account-and-login
|
||||||
(fn [request]
|
(fn [request]
|
||||||
(status/create-account-and-login request)))
|
(status/create-account-and-login request)))
|
||||||
|
|
||||||
(rf/defn on-delete-profile-success
|
(re-frame/reg-fx
|
||||||
{:events [:onboarding-2/on-delete-profile-success]}
|
:multiaccount/validate-mnemonic
|
||||||
[{:keys [db]} key-uid]
|
(fn [[mnemonic on-success on-error]]
|
||||||
{:db (update-in db [:multiaccounts/multiaccounts] dissoc key-uid)})
|
(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
|
(rf/defn profile-data-set
|
||||||
{:events [:onboarding-2/profile-data-set]}
|
{:events [:onboarding-2/profile-data-set]}
|
||||||
[{:keys [db]} onboarding-data]
|
[{: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]})
|
: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
|
(defn strip-file-prefix
|
||||||
[path]
|
[path]
|
||||||
(when path
|
(when path
|
||||||
@ -39,14 +45,20 @@
|
|||||||
{:events [:onboarding-2/create-account-and-login]}
|
{:events [:onboarding-2/create-account-and-login]}
|
||||||
[{:keys [db]}]
|
[{:keys [db]}]
|
||||||
(let [{:keys [display-name
|
(let [{:keys [display-name
|
||||||
|
seed-phrase
|
||||||
password
|
password
|
||||||
image-path
|
image-path
|
||||||
color]} (:onboarding-2/profile db)
|
color]} (:onboarding-2/profile db)
|
||||||
log-enabled? (boolean (not-empty config/log-level))
|
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
|
request {:displayName display-name
|
||||||
:password (ethereum/sha3 (security/safe-unmask-data password))
|
:password (ethereum/sha3 (security/safe-unmask-data password))
|
||||||
|
:mnemonic (when seed-phrase
|
||||||
|
(security/safe-unmask-data seed-phrase))
|
||||||
:imagePath (strip-file-prefix image-path)
|
:imagePath (strip-file-prefix image-path)
|
||||||
:color color
|
:customizationColor color
|
||||||
:backupDisabledDataDir (status/backup-disabled-data-dir)
|
:backupDisabledDataDir (status/backup-disabled-data-dir)
|
||||||
:rootKeystoreDir (status/keystore-dir)
|
:rootKeystoreDir (status/keystore-dir)
|
||||||
;; Temporary fix until https://github.com/status-im/status-go/issues/3024 is
|
;; Temporary fix until https://github.com/status-im/status-go/issues/3024 is
|
||||||
@ -60,8 +72,40 @@
|
|||||||
:verifyENSURL config/verify-ens-url
|
:verifyENSURL config/verify-ens-url
|
||||||
:verifyENSContractAddress config/verify-ens-contract-address
|
:verifyENSContractAddress config/verify-ens-contract-address
|
||||||
:verifyTransactionChainID config/verify-transaction-chain-id}]
|
:verifyTransactionChainID config/verify-transaction-chain-id}]
|
||||||
{::create-account-and-login request
|
{effect request
|
||||||
:dispatch [:navigate-to :generating-keys]
|
:dispatch [:navigate-to :generating-keys]
|
||||||
:db (-> db
|
:db (-> db
|
||||||
(dissoc :onboarding-2/profile)
|
(dissoc :onboarding-2/profile)
|
||||||
(assoc :onboarding-2/new-account? true))}))
|
(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]})
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
(* 2 56) ;; two other list items
|
(* 2 56) ;; two other list items
|
||||||
(* 2 16) ;; spacing between items
|
(* 2 16) ;; spacing between items
|
||||||
220) ;; extra spacing (top bar)
|
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}
|
[rn/view {:style style/subtitle-container}
|
||||||
[quo/text
|
[quo/text
|
||||||
@ -69,11 +69,18 @@
|
|||||||
[rn/view {:style style/space-between-suboptions}]
|
[rn/view {:style style/space-between-suboptions}]
|
||||||
[quo/small-option-card
|
[quo/small-option-card
|
||||||
{:variant :icon
|
{:variant :icon
|
||||||
:title (i18n/label :t/use-recovery-phrase)
|
:title "Temporary (old) recover phrase flow"
|
||||||
:subtitle (i18n/label :t/use-recovery-phrase-subtitle)
|
:subtitle (i18n/label :t/use-recovery-phrase-subtitle)
|
||||||
:image (resources/get-image :ethereum-address)
|
:image (resources/get-image :ethereum-address)
|
||||||
:on-press #(rf/dispatch [::multiaccounts.recover/enter-phrase-pressed])}]
|
:on-press #(rf/dispatch [::multiaccounts.recover/enter-phrase-pressed])}]
|
||||||
[rn/view {:style style/space-between-suboptions}]
|
[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
|
[quo/small-option-card
|
||||||
{:variant :icon
|
{:variant :icon
|
||||||
:title (i18n/label :t/use-keycard)
|
:title (i18n/label :t/use-keycard)
|
||||||
|
@ -52,16 +52,23 @@
|
|||||||
(keychain/get-auth-method (:key-uid multiaccount))))
|
(keychain/get-auth-method (:key-uid multiaccount))))
|
||||||
(navigation/init-root cofx :intro))))
|
(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
|
(rf/defn initialize-multiaccounts
|
||||||
{:events [:setup/initialize-multiaccounts]}
|
{:events [:setup/initialize-multiaccounts]}
|
||||||
[{:keys [db] :as cofx} all-multiaccounts {:keys [logout?]}]
|
[{:keys [db] :as cofx} all-multiaccounts {:keys [logout?]}]
|
||||||
(let [multiaccounts (reduce (fn [acc
|
(let [multiaccounts (reduce (fn [acc
|
||||||
{:keys [key-uid keycard-pairing]
|
{:keys [key-uid keycard-pairing]
|
||||||
:as multiaccount}]
|
:as multiaccount}]
|
||||||
(-> (assoc acc key-uid multiaccount)
|
(assoc acc key-uid (rpc->multiaccount multiaccount)))
|
||||||
(assoc-in [key-uid :keycard-pairing]
|
|
||||||
(when-not (string/blank? keycard-pairing)
|
|
||||||
keycard-pairing))))
|
|
||||||
{}
|
{}
|
||||||
all-multiaccounts)]
|
all-multiaccounts)]
|
||||||
(rf/merge cofx
|
(rf/merge cofx
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
[status-im2.contexts.onboarding.sign-in.view :as sign-in]
|
[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.syncing.syncing-devices.view :as syncing-devices]
|
||||||
[status-im2.contexts.onboarding.generating-keys.view :as generating-keys]
|
[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.onboarding.profiles.view :as profiles]
|
||||||
[status-im2.contexts.quo-preview.main :as quo.preview]
|
[status-im2.contexts.quo-preview.main :as quo.preview]
|
||||||
[status-im2.contexts.shell.view :as shell]
|
[status-im2.contexts.shell.view :as shell]
|
||||||
@ -168,6 +169,12 @@
|
|||||||
:insets {:top false}
|
:insets {:top false}
|
||||||
:component generating-keys/generating-keys}
|
: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
|
{:name :enable-notifications
|
||||||
:options {:statusBar {:style :light}
|
:options {:statusBar {:style :light}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||||
"owner": "status-im",
|
"owner": "status-im",
|
||||||
"repo": "status-go",
|
"repo": "status-go",
|
||||||
"version": "v0.140.0",
|
"version": "v0.140.1",
|
||||||
"commit-sha1": "7cd7430d3141b08f7c455d7918f4160ea8fd0559",
|
"commit-sha1": "e2082bf5bdd2c43bf1f140ddc4d3eece6de88bc0",
|
||||||
"src-sha256": "0lgkzrl7zas9mxpngksmh5r26j5811x9xxx9byrcqnyirmks3622"
|
"src-sha256": "1gfykjs51862kbfjqr2sslsdhmn4j19hj67zr34gm3xdcy9ci0xx"
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user