feat!: add key pairs and accounts settings to wallet settings (#20464)
* tweak: use support blur colors for action drawer icons * tweak: support blur colors for drawer-top icon * tweak: support blur colors for account list inside keypair component * tweak: use blur colors for missing-keypair bottom sheet actions * feat: remove feature-flag for key-pairs and accounts inside wallet settings * fix: ensure key-pairs-and-accounts settings are visible * tweak: display key-pair rename screen as full-screen modal * tweak: animate key-pair scanning screen as modal * fix: do not allow user to rename key-pair to an existing key-pair name * fix: ensure we visualise the validation error for key-pair name that is too long * fix: ensure we can see the recovery-phrase suggestions when testnet-mode is active * tweak: show recovery-phrase errors when keyboard is hidden * fix: ensure we do not re-hash password * fix: ensure we call `on-close` function when successfully handling biometrics auth * fix: ensure we clear error states when editing the recovery-phrase input * fix: use blur styles for standard authentication password input * chore: add labels for qr validation * tweak: handle display import-qr error and allow for re-scanning * tweak: update blur background for all bottom-sheets * chore: add feature-flag for import-all key-pairs button for missing key-pairs * tidy: remove unused variable * fix: ensure layout for android is correct when entering seed-phrase in testnet-mode * fix: ensure we return the updated db when updating the db with backup key-pair * tweak: coerce nil to empty string * tweak: change validation error message for short key-pair name * tweak: hide the options icon for the default key-pair inside key-pairs and accounts settings
This commit is contained in:
parent
6931fd0052
commit
256f3f8f24
|
@ -8,10 +8,11 @@
|
||||||
[react-native.core :as rn]))
|
[react-native.core :as rn]))
|
||||||
|
|
||||||
(defn- get-icon-color
|
(defn- get-icon-color
|
||||||
[danger? theme]
|
[blur? danger? theme]
|
||||||
(if danger?
|
(cond
|
||||||
(colors/theme-colors colors/danger-50 colors/danger-60 theme)
|
danger? (colors/theme-colors colors/danger-50 colors/danger-60 theme)
|
||||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
|
blur? colors/white-opa-70
|
||||||
|
:else (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
|
||||||
|
|
||||||
(defn- divider
|
(defn- divider
|
||||||
[theme blur?]
|
[theme blur?]
|
||||||
|
@ -51,7 +52,7 @@
|
||||||
:accessible true
|
:accessible true
|
||||||
:style (style/left-icon sub-label)}
|
:style (style/left-icon sub-label)}
|
||||||
[icon/icon icon
|
[icon/icon icon
|
||||||
{:color (or icon-color (get-icon-color danger? theme))
|
{:color (or icon-color (get-icon-color blur? danger? theme))
|
||||||
:no-color no-icon-color?
|
:no-color no-icon-color?
|
||||||
:size 20}]])
|
:size 20}]])
|
||||||
[rn/view
|
[rn/view
|
||||||
|
@ -84,7 +85,7 @@
|
||||||
:accessible true
|
:accessible true
|
||||||
:accessibility-label :right-icon-for-action}
|
:accessibility-label :right-icon-for-action}
|
||||||
[icon/icon right-icon
|
[icon/icon right-icon
|
||||||
{:color (get-icon-color danger? theme)
|
{:color (get-icon-color blur? danger? theme)
|
||||||
:size 20}]])
|
:size 20}]])
|
||||||
(when (= state :selected)
|
(when (= state :selected)
|
||||||
[rn/view {:style style/right-icon}
|
[rn/view {:style style/right-icon}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
(defn- left-image
|
(defn- left-image
|
||||||
[{:keys [type customization-color account-avatar-emoji account-avatar-type icon-avatar
|
[{:keys [type customization-color account-avatar-emoji account-avatar-type icon-avatar
|
||||||
profile-picture]}]
|
profile-picture blur?]}]
|
||||||
(case type
|
(case type
|
||||||
:account [account-avatar/view
|
:account [account-avatar/view
|
||||||
{:customization-color customization-color
|
{:customization-color customization-color
|
||||||
|
@ -28,6 +28,7 @@
|
||||||
:keypair [icon-avatar/icon-avatar
|
:keypair [icon-avatar/icon-avatar
|
||||||
{:icon icon-avatar
|
{:icon icon-avatar
|
||||||
:border? true
|
:border? true
|
||||||
|
:blur? blur?
|
||||||
:color :neutral}]
|
:color :neutral}]
|
||||||
|
|
||||||
:default-keypair [user-avatar/user-avatar
|
:default-keypair [user-avatar/user-avatar
|
||||||
|
@ -213,6 +214,7 @@
|
||||||
[rn/view {:style style/left-container}
|
[rn/view {:style style/left-container}
|
||||||
[left-image
|
[left-image
|
||||||
{:type type
|
{:type type
|
||||||
|
:blur? blur?
|
||||||
:customization-color customization-color
|
:customization-color customization-color
|
||||||
:account-avatar-emoji account-avatar-emoji
|
:account-avatar-emoji account-avatar-emoji
|
||||||
:account-avatar-type account-avatar-type
|
:account-avatar-type account-avatar-type
|
||||||
|
|
|
@ -31,7 +31,8 @@
|
||||||
:size :paragraph-2}
|
:size :paragraph-2}
|
||||||
(:name account-props)]
|
(:name account-props)]
|
||||||
[address-text/view
|
[address-text/view
|
||||||
{:networks networks
|
{:blur? blur?
|
||||||
|
:networks networks
|
||||||
:address (:address account-props)
|
:address (:address account-props)
|
||||||
:format :short}]]]
|
:format :short}]]]
|
||||||
(when (= action :icon)
|
(when (= action :icon)
|
||||||
|
|
|
@ -47,12 +47,13 @@
|
||||||
:accessibility-label :title}
|
:accessibility-label :title}
|
||||||
[text/text {:weight :semi-bold}
|
[text/text {:weight :semi-bold}
|
||||||
(if (= type :default-keypair) (keypair-string full-name) full-name)]
|
(if (= type :default-keypair) (keypair-string full-name) full-name)]
|
||||||
(if (= action :selector)
|
(case action
|
||||||
[selectors/view
|
:none nil
|
||||||
{:type :radio
|
:selector [selectors/view
|
||||||
:checked? selected?
|
{:type :radio
|
||||||
:blur? blur?
|
:checked? selected?
|
||||||
:customization-color customization-color}]
|
:blur? blur?
|
||||||
|
:customization-color customization-color}]
|
||||||
[rn/pressable {:on-press on-options-press}
|
[rn/pressable {:on-press on-options-press}
|
||||||
[icon/icon :i/options
|
[icon/icon :i/options
|
||||||
{:color (if blur?
|
{:color (if blur?
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
[utils.i18n :as i18n]))
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
(defn title-view
|
(defn title-view
|
||||||
[{:keys [keypairs blur? on-import-press]}]
|
[{:keys [keypairs blur? on-import-press show-import-all?]}]
|
||||||
(let [theme (quo.theme/use-theme)]
|
(let [theme (quo.theme/use-theme)]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:accessibility-label :title
|
{:accessibility-label :title
|
||||||
|
@ -29,12 +29,13 @@
|
||||||
:style {:color colors/warning-60}}
|
:style {:color colors/warning-60}}
|
||||||
(i18n/label :t/amount-missing-keypairs
|
(i18n/label :t/amount-missing-keypairs
|
||||||
{:amount (str (count keypairs))})]
|
{:amount (str (count keypairs))})]
|
||||||
[button/button
|
(when show-import-all?
|
||||||
{:type :outline
|
[button/button
|
||||||
:background :blur
|
{:type :outline
|
||||||
:size 24
|
:background :blur
|
||||||
:on-press on-import-press}
|
:size 24
|
||||||
(i18n/label :t/import)]]
|
:on-press on-import-press}
|
||||||
|
(i18n/label :t/import)])]
|
||||||
[text/text
|
[text/text
|
||||||
{:size :paragraph-2
|
{:size :paragraph-2
|
||||||
:style (style/subtitle blur? theme)}
|
:style (style/subtitle blur? theme)}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
(ns status-im.common.bottom-sheet.style
|
(ns status-im.common.bottom-sheet.style
|
||||||
(:require
|
(:require
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]))
|
||||||
[react-native.platform :as platform]))
|
|
||||||
|
|
||||||
(def ^:private sheet-border-radius 20)
|
(def ^:private sheet-border-radius 20)
|
||||||
|
|
||||||
|
@ -22,11 +21,8 @@
|
||||||
:left 0
|
:left 0
|
||||||
:right 0})
|
:right 0})
|
||||||
|
|
||||||
(defn shell-bg
|
(def shell-bg
|
||||||
[blur-background]
|
{:background-color colors/bottom-sheet-background-blur
|
||||||
{:background-color (if blur-background
|
|
||||||
blur-background
|
|
||||||
(if platform/ios? colors/white-opa-5 colors/neutral-100-opa-90))
|
|
||||||
:flex 1})
|
:flex 1})
|
||||||
|
|
||||||
(def shell-bg-container
|
(def shell-bg-container
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [hide? insets]}
|
[{:keys [hide? insets]}
|
||||||
{:keys [content selected-item padding-bottom-override border-radius on-close shell?
|
{:keys [content selected-item padding-bottom-override border-radius on-close shell?
|
||||||
gradient-cover? customization-color hide-handle? blur-radius blur-background]
|
gradient-cover? customization-color hide-handle? blur-radius]
|
||||||
:or {border-radius 12}}]
|
:or {border-radius 12}}]
|
||||||
(let [theme (quo.theme/use-theme)
|
(let [theme (quo.theme/use-theme)
|
||||||
{window-height :height} (rn/get-window)
|
{window-height :height} (rn/get-window)
|
||||||
|
@ -134,7 +134,7 @@
|
||||||
(when shell?
|
(when shell?
|
||||||
[rn/view {:style style/shell-bg-container}
|
[rn/view {:style style/shell-bg-container}
|
||||||
[quo/blur
|
[quo/blur
|
||||||
{:style (style/shell-bg blur-background)
|
{:style style/shell-bg
|
||||||
:blur-radius (or blur-radius 20)
|
:blur-radius (or blur-radius 20)
|
||||||
:blur-amount 32
|
:blur-amount 32
|
||||||
:blur-type :transparent
|
:blur-type :transparent
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
(ns status-im.common.enter-seed-phrase.style
|
(ns status-im.common.enter-seed-phrase.style
|
||||||
(:require
|
(:require [react-native.platform :as platform]))
|
||||||
[react-native.safe-area :as safe-area]))
|
|
||||||
|
|
||||||
(def full-layout {:flex 1})
|
(def full-layout {:flex 1})
|
||||||
|
|
||||||
|
@ -11,6 +10,13 @@
|
||||||
:left 0
|
:left 0
|
||||||
:right 0})
|
:right 0})
|
||||||
|
|
||||||
|
(defn recovery-phrase-container
|
||||||
|
[{:keys [banner-offset insets keyboard-shown?]}]
|
||||||
|
{:flex 1
|
||||||
|
:padding-bottom (if keyboard-shown?
|
||||||
|
(when platform/ios? banner-offset)
|
||||||
|
(:bottom insets))})
|
||||||
|
|
||||||
(def form-container
|
(def form-container
|
||||||
{:flex 1
|
{:flex 1
|
||||||
:padding-horizontal 20
|
:padding-horizontal 20
|
||||||
|
@ -29,9 +35,7 @@
|
||||||
:margin-top 12
|
:margin-top 12
|
||||||
:margin-horizontal -20})
|
:margin-horizontal -20})
|
||||||
|
|
||||||
(defn continue-button
|
(def continue-button
|
||||||
[keyboard-shown?]
|
{:margin-top :auto})
|
||||||
{:margin-top :auto
|
|
||||||
:margin-bottom (when-not keyboard-shown? (safe-area/get-bottom))})
|
|
||||||
|
|
||||||
(def keyboard-container {:margin-top :auto})
|
(def keyboard-container {:margin-top :auto})
|
||||||
|
|
|
@ -96,7 +96,7 @@
|
||||||
(take 7)))
|
(take 7)))
|
||||||
|
|
||||||
(defn recovery-phrase-screen
|
(defn recovery-phrase-screen
|
||||||
[{:keys [keypair title recovering-keypair? render-controls]}]
|
[{:keys [banner-offset initial-insets keypair title recovering-keypair? render-controls]}]
|
||||||
(reagent/with-let [keyboard-shown? (reagent/atom false)
|
(reagent/with-let [keyboard-shown? (reagent/atom false)
|
||||||
keyboard-show-listener (.addListener rn/keyboard
|
keyboard-show-listener (.addListener rn/keyboard
|
||||||
"keyboardDidShow"
|
"keyboardDidShow"
|
||||||
|
@ -114,7 +114,8 @@
|
||||||
seed-phrase (reagent/atom "")
|
seed-phrase (reagent/atom "")
|
||||||
on-change-seed-phrase (fn [new-phrase]
|
on-change-seed-phrase (fn [new-phrase]
|
||||||
(when @invalid-seed-phrase?
|
(when @invalid-seed-phrase?
|
||||||
(reset! invalid-seed-phrase? false)
|
(reset! invalid-seed-phrase? false))
|
||||||
|
(when @incorrect-seed-phrase?
|
||||||
(reset! incorrect-seed-phrase? false))
|
(reset! incorrect-seed-phrase? false))
|
||||||
(reset! seed-phrase new-phrase))
|
(reset! seed-phrase new-phrase))
|
||||||
on-submit (fn []
|
on-submit (fn []
|
||||||
|
@ -161,7 +162,10 @@
|
||||||
button-disabled? (or error-state?
|
button-disabled? (or error-state?
|
||||||
(not (constants/seed-phrase-valid-length word-count))
|
(not (constants/seed-phrase-valid-length word-count))
|
||||||
(not all-words-valid?))]
|
(not all-words-valid?))]
|
||||||
[:<>
|
[rn/view
|
||||||
|
{:style (style/recovery-phrase-container {:insets initial-insets
|
||||||
|
:banner-offset banner-offset
|
||||||
|
:keyboard-shown? @keyboard-shown?})}
|
||||||
[recovery-phrase-form
|
[recovery-phrase-form
|
||||||
{:title title
|
{:title title
|
||||||
:keypair keypair
|
:keypair keypair
|
||||||
|
@ -172,18 +176,18 @@
|
||||||
(if (fn? render-controls)
|
(if (fn? render-controls)
|
||||||
(render-controls {:submit-disabled? button-disabled?
|
(render-controls {:submit-disabled? button-disabled?
|
||||||
:keyboard-shown? @keyboard-shown?
|
:keyboard-shown? @keyboard-shown?
|
||||||
:container-style (style/continue-button @keyboard-shown?)
|
:container-style style/continue-button
|
||||||
:prepare-seed-phrase secure-clean-seed-phrase
|
:prepare-seed-phrase secure-clean-seed-phrase
|
||||||
:focus-input focus-input
|
:focus-input focus-input
|
||||||
:seed-phrase (security/mask-data @seed-phrase)
|
:seed-phrase (security/mask-data @seed-phrase)
|
||||||
:set-incorrect-seed-phrase set-incorrect-seed-phrase})
|
:set-incorrect-seed-phrase set-incorrect-seed-phrase})
|
||||||
[quo/button
|
[quo/button
|
||||||
{:container-style (style/continue-button @keyboard-shown?)
|
{:container-style style/continue-button
|
||||||
:type :primary
|
:type :primary
|
||||||
:disabled? button-disabled?
|
:disabled? button-disabled?
|
||||||
:on-press on-submit}
|
:on-press on-submit}
|
||||||
(i18n/label :t/continue)])]
|
(i18n/label :t/continue)])]
|
||||||
(when @keyboard-shown?
|
(when (or @keyboard-shown? error-state?)
|
||||||
[rn/view {:style style/keyboard-container}
|
[rn/view {:style style/keyboard-container}
|
||||||
[quo/predictive-keyboard
|
[quo/predictive-keyboard
|
||||||
{:type suggestions-state
|
{:type suggestions-state
|
||||||
|
@ -197,7 +201,8 @@
|
||||||
|
|
||||||
(defn screen
|
(defn screen
|
||||||
[{:keys [initial-insets title keypair navigation-icon recovering-keypair? render-controls]}]
|
[{:keys [initial-insets title keypair navigation-icon recovering-keypair? render-controls]}]
|
||||||
(let [{navigation-bar-top :top} initial-insets]
|
(let [{navigation-bar-top :top} initial-insets
|
||||||
|
banner-offset (rf/sub [:alert-banners/top-margin])]
|
||||||
[rn/view {:style style/full-layout}
|
[rn/view {:style style/full-layout}
|
||||||
[rn/keyboard-avoiding-view {:style style/page-container}
|
[rn/keyboard-avoiding-view {:style style/page-container}
|
||||||
[quo/page-nav
|
[quo/page-nav
|
||||||
|
@ -210,6 +215,8 @@
|
||||||
{:title title
|
{:title title
|
||||||
:keypair keypair
|
:keypair keypair
|
||||||
:render-controls render-controls
|
:render-controls render-controls
|
||||||
|
:banner-offset banner-offset
|
||||||
|
:initial-insets initial-insets
|
||||||
:recovering-keypair? recovering-keypair?}]]]))
|
:recovering-keypair? recovering-keypair?}]]]))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
|
|
|
@ -195,7 +195,7 @@
|
||||||
true)
|
true)
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [title subtitle validate-fn on-success-scan error-message share-button?]}]
|
[{:keys [title subtitle validate-fn on-success-scan error-message share-button? import-keypair?]}]
|
||||||
(let [insets (safe-area/get-insets)
|
(let [insets (safe-area/get-insets)
|
||||||
qr-code-succeed? (reagent/atom false)
|
qr-code-succeed? (reagent/atom false)
|
||||||
qr-view-finder (reagent/atom {})
|
qr-view-finder (reagent/atom {})
|
||||||
|
@ -233,7 +233,9 @@
|
||||||
:set-qr-code-succeeded (fn [value]
|
:set-qr-code-succeeded (fn [value]
|
||||||
(when on-success-scan
|
(when on-success-scan
|
||||||
(on-success-scan value))
|
(on-success-scan value))
|
||||||
(rf/dispatch [:navigate-back]))
|
(if import-keypair?
|
||||||
|
(set-rescan-timeout)
|
||||||
|
(rf/dispatch [:navigate-back])))
|
||||||
:set-rescan-timeout set-rescan-timeout}])
|
:set-rescan-timeout set-rescan-timeout}])
|
||||||
[rn/view {:style (style/root-container (:top insets))}
|
[rn/view {:style (style/root-container (:top insets))}
|
||||||
[header
|
[header
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
:size 24}]]
|
:size 24}]]
|
||||||
[password-input/view
|
[password-input/view
|
||||||
{:on-press-biometrics on-press-biometrics
|
{:on-press-biometrics on-press-biometrics
|
||||||
|
:blur? true
|
||||||
:processing processing
|
:processing processing
|
||||||
:error error
|
:error error
|
||||||
:default-password password
|
:default-password password
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
(rf/reg-event-fx :standard-auth/authorize authorize)
|
(rf/reg-event-fx :standard-auth/authorize authorize)
|
||||||
|
|
||||||
(defn authorize-with-biometric
|
(defn authorize-with-biometric
|
||||||
[_ [{:keys [on-auth-success on-auth-fail] :as args}]]
|
[_ [{:keys [on-auth-success on-auth-fail on-close] :as args}]]
|
||||||
(let [args-with-biometric-btn
|
(let [args-with-biometric-btn
|
||||||
(assoc args
|
(assoc args
|
||||||
:on-press-biometric
|
:on-press-biometric
|
||||||
|
@ -31,7 +31,10 @@
|
||||||
{:prompt-message (i18n/label :t/biometric-auth-confirm-message)
|
{:prompt-message (i18n/label :t/biometric-auth-confirm-message)
|
||||||
:on-cancel #(rf/dispatch [:standard-auth/authorize-with-password
|
:on-cancel #(rf/dispatch [:standard-auth/authorize-with-password
|
||||||
args-with-biometric-btn])
|
args-with-biometric-btn])
|
||||||
:on-success #(rf/dispatch [:standard-auth/on-biometric-success on-auth-success])
|
:on-success (fn []
|
||||||
|
(when (fn? on-close)
|
||||||
|
(on-close))
|
||||||
|
(rf/dispatch [:standard-auth/on-biometric-success on-auth-success]))
|
||||||
:on-fail (fn [err]
|
:on-fail (fn [err]
|
||||||
(rf/dispatch [:standard-auth/authorize-with-password
|
(rf/dispatch [:standard-auth/authorize-with-password
|
||||||
args-with-biometric-btn])
|
args-with-biometric-btn])
|
||||||
|
|
|
@ -14,10 +14,12 @@
|
||||||
(> (-> s str string/trim count) constants/key-pair-name-max-length))
|
(> (-> s str string/trim count) constants/key-pair-name-max-length))
|
||||||
|
|
||||||
(defn validation-keypair-name
|
(defn validation-keypair-name
|
||||||
[s]
|
[s existing-keypair-names]
|
||||||
(cond
|
(cond
|
||||||
(string/blank? s) nil
|
(string/blank? s) nil
|
||||||
(validators/has-emojis? s) (i18n/label :t/key-name-error-emoji)
|
(validators/has-emojis? s) (i18n/label :t/key-name-error-emoji)
|
||||||
(validators/has-special-characters? s) (i18n/label :t/key-name-error-special-char)
|
(validators/has-special-characters? s) (i18n/label :t/key-name-error-special-char)
|
||||||
(keypair-too-short? s) (i18n/label :t/your-key-pair-name-is-too-short)
|
(keypair-too-short? s) (i18n/label :t/key-name-error-too-short
|
||||||
(keypair-too-long? s) (i18n/label :t/your-key-pair-name-is-too-long)))
|
{:count constants/key-pair-name-min-length})
|
||||||
|
(keypair-too-long? s) (i18n/label :t/your-key-pair-name-is-too-long)
|
||||||
|
(contains? existing-keypair-names s) (i18n/label :t/key-name-error-taken)))
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
(:require
|
(:require
|
||||||
[cljs.test :refer-macros [deftest are]]
|
[cljs.test :refer-macros [deftest are]]
|
||||||
[status-im.common.validation.keypair :as keypair-validator]
|
[status-im.common.validation.keypair :as keypair-validator]
|
||||||
|
[status-im.constants :as constants]
|
||||||
[utils.i18n :as i18n]))
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
(deftest keypair-name-too-short-test
|
(deftest keypair-name-too-short-test
|
||||||
|
@ -18,10 +19,12 @@
|
||||||
|
|
||||||
(deftest validation-keypair-name-test
|
(deftest validation-keypair-name-test
|
||||||
(are [arg expected]
|
(are [arg expected]
|
||||||
(= (keypair-validator/validation-keypair-name arg) expected)
|
(= (keypair-validator/validation-keypair-name arg #{"Collection"}) expected)
|
||||||
nil nil
|
nil nil
|
||||||
"" nil
|
"" nil
|
||||||
"name !" (i18n/label :t/key-name-error-special-char)
|
"name !" (i18n/label :t/key-name-error-special-char)
|
||||||
"Hello 😊" (i18n/label :t/key-name-error-emoji)
|
"Hello 😊" (i18n/label :t/key-name-error-emoji)
|
||||||
"abc" (i18n/label :t/your-key-pair-name-is-too-short)
|
"abc" (i18n/label :t/key-name-error-too-short
|
||||||
|
{:count constants/key-pair-name-min-length})
|
||||||
|
"Collection" (i18n/label :t/key-name-error-taken)
|
||||||
(apply str (repeat 25 "a")) (i18n/label :t/your-key-pair-name-is-too-long)))
|
(apply str (repeat 25 "a")) (i18n/label :t/your-key-pair-name-is-too-long)))
|
||||||
|
|
|
@ -92,23 +92,28 @@
|
||||||
(rf/reg-event-fx :wallet/make-keypairs-accounts-fully-operable make-keypairs-accounts-fully-operable)
|
(rf/reg-event-fx :wallet/make-keypairs-accounts-fully-operable make-keypairs-accounts-fully-operable)
|
||||||
|
|
||||||
(defn connection-string-for-import-keypair
|
(defn connection-string-for-import-keypair
|
||||||
[{:keys [db]} [{:keys [sha3-pwd keypairs-key-uids connection-string]}]]
|
[{:keys [db]} [{:keys [sha3-pwd keypairs-key-uids connection-string on-success]}]]
|
||||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||||
{:fx [[:effects.syncing/import-keypairs-keystores
|
{:fx [[:effects.syncing/import-keypairs-keystores
|
||||||
{:key-uid key-uid
|
{:key-uid key-uid
|
||||||
:sha3-pwd sha3-pwd
|
:sha3-pwd sha3-pwd
|
||||||
:keypairs-key-uids keypairs-key-uids
|
:keypairs-key-uids keypairs-key-uids
|
||||||
:connection-string connection-string
|
:connection-string connection-string
|
||||||
:on-success #(rf/dispatch [:wallet/make-keypairs-accounts-fully-operable %])
|
:on-success (fn [key-uids]
|
||||||
:on-fail #(rf/dispatch [:toasts/upsert
|
(rf/call-continuation on-success)
|
||||||
{:type :negative
|
(rf/dispatch [:wallet/make-keypairs-accounts-fully-operable key-uids]))
|
||||||
:theme :dark
|
:on-fail (fn [error]
|
||||||
:text %}])}]]}))
|
(log/error "failed to import missing key pairs with connection string"
|
||||||
|
{:error error})
|
||||||
|
(rf/dispatch [:toasts/upsert
|
||||||
|
{:type :negative
|
||||||
|
:theme :dark
|
||||||
|
:text (i18n/label :t/incorrect-qr-code)}]))}]]}))
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet/connection-string-for-import-keypair connection-string-for-import-keypair)
|
(rf/reg-event-fx :wallet/connection-string-for-import-keypair connection-string-for-import-keypair)
|
||||||
|
|
||||||
(defn success-keypair-qr-scan
|
(defn success-keypair-qr-scan
|
||||||
[_ [connection-string keypairs-key-uids]]
|
[_ [connection-string keypairs-key-uids on-import-success]]
|
||||||
{:fx [[:dispatch
|
{:fx [[:dispatch
|
||||||
[:standard-auth/authorize-with-password
|
[:standard-auth/authorize-with-password
|
||||||
{:blur? true
|
{:blur? true
|
||||||
|
@ -120,7 +125,8 @@
|
||||||
[:wallet/connection-string-for-import-keypair
|
[:wallet/connection-string-for-import-keypair
|
||||||
{:connection-string connection-string
|
{:connection-string connection-string
|
||||||
:keypairs-key-uids keypairs-key-uids
|
:keypairs-key-uids keypairs-key-uids
|
||||||
:sha3-pwd password}]))}]]]})
|
:sha3-pwd password
|
||||||
|
:on-success on-import-success}]))}]]]})
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet/success-keypair-qr-scan success-keypair-qr-scan)
|
(rf/reg-event-fx :wallet/success-keypair-qr-scan success-keypair-qr-scan)
|
||||||
|
|
||||||
|
@ -146,7 +152,7 @@
|
||||||
{:fx [[:json-rpc/call
|
{:fx [[:json-rpc/call
|
||||||
[{:method "accounts_makePrivateKeyKeypairFullyOperable"
|
[{:method "accounts_makePrivateKeyKeypairFullyOperable"
|
||||||
:params [(security/safe-unmask-data private-key)
|
:params [(security/safe-unmask-data private-key)
|
||||||
(-> password security/safe-unmask-data native-module/sha3)]
|
(security/safe-unmask-data password)]
|
||||||
:on-success on-success
|
:on-success on-success
|
||||||
:on-error on-error}]]]})
|
:on-error on-error}]]]})
|
||||||
|
|
||||||
|
|
|
@ -41,31 +41,37 @@
|
||||||
[quo/action-drawer
|
[quo/action-drawer
|
||||||
[(when has-paired-device
|
[(when has-paired-device
|
||||||
(if-not missing-keypair?
|
(if-not missing-keypair?
|
||||||
[{:icon :i/qr-code
|
[{:blur? true
|
||||||
|
:icon :i/qr-code
|
||||||
:accessibility-label :show-key-pr-qr
|
:accessibility-label :show-key-pr-qr
|
||||||
:label (i18n/label :t/show-encrypted-qr-of-key-pairs)
|
:label (i18n/label :t/show-encrypted-qr-of-key-pairs)
|
||||||
:on-press on-show-qr}]
|
:on-press on-show-qr}]
|
||||||
[{:icon :i/scan
|
[{:blur? true
|
||||||
|
:icon :i/scan
|
||||||
:accessibility-label :import-by-scan-qr
|
:accessibility-label :import-by-scan-qr
|
||||||
:label (i18n/label :t/import-by-scanning-encrypted-qr)
|
:label (i18n/label :t/import-by-scanning-encrypted-qr)
|
||||||
:on-press on-scan-qr}]))
|
:on-press on-scan-qr}]))
|
||||||
(when (= (:type drawer-props) :keypair)
|
(when (= (:type drawer-props) :keypair)
|
||||||
[(when missing-keypair?
|
[(when missing-keypair?
|
||||||
(case (:type keypair)
|
(case (:type keypair)
|
||||||
:seed {:icon :i/seed
|
:seed {:blur? true
|
||||||
|
:icon :i/seed
|
||||||
:accessibility-label :import-seed-phrase
|
:accessibility-label :import-seed-phrase
|
||||||
:label (i18n/label :t/import-by-entering-recovery-phrase)
|
:label (i18n/label :t/import-by-entering-recovery-phrase)
|
||||||
:on-press on-import-seed-phrase}
|
:on-press on-import-seed-phrase}
|
||||||
:key {:icon :i/key
|
:key {:blur? true
|
||||||
|
:icon :i/key
|
||||||
:accessibility-label :import-private-key
|
:accessibility-label :import-private-key
|
||||||
:label (i18n/label :t/import-by-entering-private-key)
|
:label (i18n/label :t/import-by-entering-private-key)
|
||||||
:on-press on-import-private-key}
|
:on-press on-import-private-key}
|
||||||
nil))
|
nil))
|
||||||
{:icon :i/edit
|
{:blur? true
|
||||||
|
:icon :i/edit
|
||||||
:accessibility-label :rename-key-pair
|
:accessibility-label :rename-key-pair
|
||||||
:label (i18n/label :t/rename-key-pair)
|
:label (i18n/label :t/rename-key-pair)
|
||||||
:on-press on-rename-keypair}
|
:on-press on-rename-keypair}
|
||||||
{:icon :i/delete
|
{:blur? true
|
||||||
|
:icon :i/delete
|
||||||
:accessibility-label :remove-key-pair
|
:accessibility-label :remove-key-pair
|
||||||
:add-divider? true
|
:add-divider? true
|
||||||
:danger? true
|
:danger? true
|
||||||
|
|
|
@ -11,13 +11,16 @@
|
||||||
[]
|
[]
|
||||||
(let [keypairs-key-uids (rf/sub [:get-screen-params])
|
(let [keypairs-key-uids (rf/sub [:get-screen-params])
|
||||||
on-success-scan (rn/use-callback (fn [scanned-text]
|
on-success-scan (rn/use-callback (fn [scanned-text]
|
||||||
(rf/dispatch [:wallet/success-keypair-qr-scan scanned-text
|
(rf/dispatch [:wallet/success-keypair-qr-scan
|
||||||
keypairs-key-uids])
|
scanned-text
|
||||||
|
keypairs-key-uids
|
||||||
|
[:navigate-back]])
|
||||||
[keypairs-key-uids]))]
|
[keypairs-key-uids]))]
|
||||||
[scan-qr-code/view
|
[scan-qr-code/view
|
||||||
{:title (i18n/label :t/scan-key-pairs-qr-code)
|
{:title (i18n/label :t/scan-key-pairs-qr-code)
|
||||||
:subtitle (i18n/label :t/find-it-in-setting)
|
:subtitle (i18n/label :t/find-it-in-setting)
|
||||||
:share-button? false
|
:share-button? false
|
||||||
|
:import-keypair? true
|
||||||
:validate-fn sync-utils/valid-connection-string?
|
:validate-fn sync-utils/valid-connection-string?
|
||||||
:error-message (i18n/label :t/invalid-qr)
|
:error-message (i18n/label :t/invalid-key-pair-qr)
|
||||||
:on-success-scan on-success-scan}]))
|
:on-success-scan on-success-scan}]))
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
{:margin-bottom 8})
|
{:margin-bottom 8})
|
||||||
|
|
||||||
(def bottom-action
|
(def bottom-action
|
||||||
{:margin-horizontal -20})
|
{:margin-horizontal -20
|
||||||
|
:margin-vertical -12})
|
||||||
|
|
||||||
(def error-container
|
(def error-container
|
||||||
{:margin-left 20
|
{:margin-left 20
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
|
[react-native.safe-area :as safe-area]
|
||||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||||
[status-im.common.validation.keypair :as keypair-validator]
|
[status-im.common.validation.keypair :as keypair-validator]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
|
@ -14,19 +15,24 @@
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [{:keys [name key-uid]} (rf/sub [:get-screen-params])
|
(let [insets (safe-area/get-insets)
|
||||||
|
{existing-keypair-name :name
|
||||||
|
:keys [key-uid]} (rf/sub [:get-screen-params])
|
||||||
|
existing-keypair-names (rf/sub [:wallet/keypair-names])
|
||||||
customization-color (rf/sub [:profile/customization-color])
|
customization-color (rf/sub [:profile/customization-color])
|
||||||
[unsaved-keypair-name set-unsaved-keypair-name] (rn/use-state name)
|
[unsaved-keypair-name set-unsaved-keypair-name] (rn/use-state existing-keypair-name)
|
||||||
[error-msg set-error-msg] (rn/use-state nil)
|
[error-msg set-error-msg] (rn/use-state nil)
|
||||||
[typing? set-typing?] (rn/use-state false)
|
[typing? set-typing?] (rn/use-state false)
|
||||||
validate-keypair-name (rn/use-callback
|
validate-keypair-name (rn/use-callback
|
||||||
(debounce/debounce
|
(debounce/debounce
|
||||||
(fn [name]
|
(fn [input-name]
|
||||||
(set-error-msg
|
(set-error-msg
|
||||||
(keypair-validator/validation-keypair-name
|
(keypair-validator/validation-keypair-name
|
||||||
name))
|
input-name
|
||||||
|
existing-keypair-names))
|
||||||
(set-typing? false))
|
(set-typing? false))
|
||||||
300))
|
300)
|
||||||
|
[existing-keypair-names])
|
||||||
on-change-text (rn/use-callback (fn [text]
|
on-change-text (rn/use-callback (fn [text]
|
||||||
(set-typing? true)
|
(set-typing? true)
|
||||||
(set-unsaved-keypair-name
|
(set-unsaved-keypair-name
|
||||||
|
@ -40,45 +46,57 @@
|
||||||
:keypair-name
|
:keypair-name
|
||||||
unsaved-keypair-name}])
|
unsaved-keypair-name}])
|
||||||
[unsaved-keypair-name key-uid])]
|
[unsaved-keypair-name key-uid])]
|
||||||
[floating-button-page/view
|
[quo/overlay {:type :shell}
|
||||||
{:header [quo/page-nav
|
[floating-button-page/view
|
||||||
{:icon-name :i/close
|
{:footer-container-padding 0
|
||||||
:on-press navigate-back
|
:blur? true
|
||||||
:accessibility-label :top-bar}]
|
:header [quo/page-nav
|
||||||
:footer [quo/bottom-actions
|
{:margin-top (:top insets)
|
||||||
{:actions :one-action
|
:icon-name :i/close
|
||||||
:button-one-label (i18n/label :t/save)
|
:background :blur
|
||||||
:button-one-props {:disabled? (or typing?
|
:on-press navigate-back
|
||||||
(string/blank? unsaved-keypair-name)
|
:accessibility-label :top-bar}]
|
||||||
(not (string/blank? error-msg)))
|
:footer [quo/bottom-actions
|
||||||
:customization-color customization-color
|
{:actions :one-action
|
||||||
:on-press on-save}
|
:blur? true
|
||||||
:container-style style/bottom-action}]}
|
:button-one-label (i18n/label :t/save)
|
||||||
[quo/page-top
|
:button-one-props {:blur? true
|
||||||
{:container-style style/header-container
|
:disabled? (or typing?
|
||||||
:title (i18n/label :t/rename-key-pair)
|
(= existing-keypair-name
|
||||||
:description :context-tag
|
unsaved-keypair-name)
|
||||||
:context-tag {:type :icon
|
(string/blank?
|
||||||
:size 24
|
unsaved-keypair-name)
|
||||||
:context name
|
(not (string/blank?
|
||||||
:icon :i/seed-phrase}}]
|
error-msg)))
|
||||||
[quo/input
|
:customization-color customization-color
|
||||||
{:container-style {:margin-horizontal 20}
|
:on-press on-save}
|
||||||
:placeholder (i18n/label :t/keypair-name-input-placeholder)
|
:container-style style/bottom-action}]}
|
||||||
:label (i18n/label :t/keypair-name)
|
[quo/page-top
|
||||||
:default-value unsaved-keypair-name
|
{:container-style style/header-container
|
||||||
:char-limit constants/key-pair-name-max-length
|
:title (i18n/label :t/rename-key-pair)
|
||||||
:max-length constants/key-pair-name-max-length
|
:description :context-tag
|
||||||
:auto-focus true
|
:blur? true
|
||||||
:clearable? (not (string/blank? unsaved-keypair-name))
|
:context-tag {:type :icon
|
||||||
:on-clear on-clear
|
:size 24
|
||||||
:on-change-text on-change-text
|
:context existing-keypair-name
|
||||||
:error? (not (string/blank? error-msg))}]
|
:icon :i/seed-phrase}}]
|
||||||
(when-not (string/blank? error-msg)
|
[quo/input
|
||||||
[quo/info-message
|
{:blur? true
|
||||||
{:type :error
|
:container-style {:margin-horizontal 20}
|
||||||
:size :default
|
:placeholder (i18n/label :t/keypair-name-input-placeholder)
|
||||||
:icon :i/info
|
:label (i18n/label :t/keypair-name)
|
||||||
:container-style style/error-container}
|
:default-value unsaved-keypair-name
|
||||||
error-msg])]))
|
:char-limit constants/key-pair-name-max-length
|
||||||
|
:auto-focus true
|
||||||
|
:clearable? (not (string/blank? unsaved-keypair-name))
|
||||||
|
:on-clear on-clear
|
||||||
|
:on-change-text on-change-text
|
||||||
|
:error? (not (string/blank? error-msg))}]
|
||||||
|
(when-not (string/blank? error-msg)
|
||||||
|
[quo/info-message
|
||||||
|
{:type :error
|
||||||
|
:size :default
|
||||||
|
:icon :i/info
|
||||||
|
:container-style style/error-container}
|
||||||
|
error-msg])]]))
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.view
|
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.view
|
||||||
(:require [quo.core :as quo]
|
(:require [quo.core :as quo]
|
||||||
[quo.foundations.colors :as colors]
|
|
||||||
[quo.theme]
|
[quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.safe-area :as safe-area]
|
[react-native.safe-area :as safe-area]
|
||||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.actions.view :as actions]
|
[status-im.contexts.settings.wallet.keypairs-and-accounts.actions.view :as actions]
|
||||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.style :as style]
|
[status-im.contexts.settings.wallet.keypairs-and-accounts.style :as style]
|
||||||
|
[status-im.feature-flags :as ff]
|
||||||
[utils.address :as utils]
|
[utils.address :as utils]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
@ -17,13 +17,12 @@
|
||||||
(defn on-options-press
|
(defn on-options-press
|
||||||
[{:keys [drawer-props keypair]}]
|
[{:keys [drawer-props keypair]}]
|
||||||
(rf/dispatch [:show-bottom-sheet
|
(rf/dispatch [:show-bottom-sheet
|
||||||
{:content (fn [] [actions/view
|
{:content (fn [] [actions/view
|
||||||
{:drawer-props drawer-props
|
{:drawer-props drawer-props
|
||||||
:keypair keypair}])
|
:keypair keypair}])
|
||||||
|
|
||||||
:blur-background colors/bottom-sheet-background-blur
|
:theme (:theme drawer-props)
|
||||||
:theme (:theme drawer-props)
|
:shell? true}]))
|
||||||
:shell? true}]))
|
|
||||||
|
|
||||||
(defn options-drawer-props
|
(defn options-drawer-props
|
||||||
[{{:keys [name]} :keypair
|
[{{:keys [name]} :keypair
|
||||||
|
@ -70,7 +69,7 @@
|
||||||
{:blur? true
|
{:blur? true
|
||||||
:status-indicator false
|
:status-indicator false
|
||||||
:stored :on-device
|
:stored :on-device
|
||||||
:action :options
|
:action (if default-keypair? :none :options)
|
||||||
:accounts accounts
|
:accounts accounts
|
||||||
:customization-color customization-color
|
:customization-color customization-color
|
||||||
:container-style style/keypair-container-style
|
:container-style style/keypair-container-style
|
||||||
|
@ -83,17 +82,16 @@
|
||||||
(defn on-missing-keypair-options-press
|
(defn on-missing-keypair-options-press
|
||||||
[_event keypair-data]
|
[_event keypair-data]
|
||||||
(rf/dispatch [:show-bottom-sheet
|
(rf/dispatch [:show-bottom-sheet
|
||||||
{:theme :dark
|
{:theme :dark
|
||||||
:shell? true
|
:shell? true
|
||||||
:blur-background colors/bottom-sheet-background-blur
|
:content (fn [] [actions/view
|
||||||
:content (fn [] [actions/view
|
{:keypair keypair-data
|
||||||
{:keypair keypair-data
|
:drawer-props (options-drawer-props
|
||||||
:drawer-props (options-drawer-props
|
{:theme :dark
|
||||||
{:theme :dark
|
:type :keypair
|
||||||
:type :keypair
|
:stored :missing
|
||||||
:stored :missing
|
:blur? true
|
||||||
:blur? true
|
:keypair keypair-data})}])}]))
|
||||||
:keypair keypair-data})}])}]))
|
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
|
@ -127,6 +125,7 @@
|
||||||
:header (when (seq missing-keypairs)
|
:header (when (seq missing-keypairs)
|
||||||
[quo/missing-keypairs
|
[quo/missing-keypairs
|
||||||
{:blur? true
|
{:blur? true
|
||||||
|
:show-import-all? (ff/enabled? ::ff/settings.import-all-keypairs)
|
||||||
:keypairs missing-keypairs
|
:keypairs missing-keypairs
|
||||||
:on-import-press on-import-press
|
:on-import-press on-import-press
|
||||||
:container-style style/missing-keypairs-container-style
|
:container-style style/missing-keypairs-container-style
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
(ns status-im.contexts.settings.wallet.network-settings.view
|
(ns status-im.contexts.settings.wallet.network-settings.view
|
||||||
(:require [quo.core :as quo]
|
(:require [quo.core :as quo]
|
||||||
[quo.foundations.colors :as colors]
|
|
||||||
[quo.foundations.resources :as resources]
|
[quo.foundations.resources :as resources]
|
||||||
[quo.theme]
|
[quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
|
@ -80,12 +79,11 @@
|
||||||
(defn on-change-testnet
|
(defn on-change-testnet
|
||||||
[{:keys [enable? blur? theme]}]
|
[{:keys [enable? blur? theme]}]
|
||||||
(rf/dispatch [:show-bottom-sheet
|
(rf/dispatch [:show-bottom-sheet
|
||||||
{:content (fn [] [testnet/view
|
{:content (fn [] [testnet/view
|
||||||
{:enable? enable?
|
{:enable? enable?
|
||||||
:blur? blur?}])
|
:blur? blur?}])
|
||||||
:theme theme
|
:theme theme
|
||||||
:shell? blur?
|
:shell? blur?}]))
|
||||||
:blur-background colors/bottom-sheet-background-blur}]))
|
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
(:require
|
(:require
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[quo.foundations.colors :as colors]
|
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.platform :as platform]
|
[react-native.platform :as platform]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
|
@ -52,11 +51,10 @@
|
||||||
open-remove-confirmation-sheet (rn/use-callback
|
open-remove-confirmation-sheet (rn/use-callback
|
||||||
#(rf/dispatch
|
#(rf/dispatch
|
||||||
[:show-bottom-sheet
|
[:show-bottom-sheet
|
||||||
{:theme :dark
|
{:theme :dark
|
||||||
:shell? true
|
:shell? true
|
||||||
:blur-background colors/bottom-sheet-background-blur
|
:content (fn []
|
||||||
:content (fn []
|
[remove-address/view opts])}])
|
||||||
[remove-address/view opts])}])
|
|
||||||
[opts])
|
[opts])
|
||||||
open-show-address-qr (rn/use-callback
|
open-show-address-qr (rn/use-callback
|
||||||
#(rf/dispatch [:open-modal
|
#(rf/dispatch [:open-modal
|
||||||
|
|
|
@ -16,11 +16,10 @@
|
||||||
|
|
||||||
(defn basic-settings-options
|
(defn basic-settings-options
|
||||||
[]
|
[]
|
||||||
[(when (ff/enabled? ::ff/settings.keypairs-and-accounts)
|
[{:title (i18n/label :t/keypairs-and-accounts)
|
||||||
{:title (i18n/label :t/keypairs-and-accounts)
|
:blur? true
|
||||||
:blur? true
|
:on-press open-keypairs-and-accounts-settings-modal
|
||||||
:on-press open-keypairs-and-accounts-settings-modal
|
:action :arrow}
|
||||||
:action :arrow})
|
|
||||||
(when (ff/enabled? ::ff/settings.saved-addresses)
|
(when (ff/enabled? ::ff/settings.saved-addresses)
|
||||||
{:title (i18n/label :t/saved-addresses)
|
{:title (i18n/label :t/saved-addresses)
|
||||||
:blur? true
|
:blur? true
|
||||||
|
@ -74,7 +73,5 @@
|
||||||
[quo/page-top
|
[quo/page-top
|
||||||
{:title (i18n/label :t/wallet)
|
{:title (i18n/label :t/wallet)
|
||||||
:title-accessibility-label :wallet-settings-header}]
|
:title-accessibility-label :wallet-settings-header}]
|
||||||
(when (or (ff/enabled? ::ff/settings.keypairs-and-accounts)
|
[basic-settings]
|
||||||
(ff/enabled? ::ff/settings.saved-addresses))
|
|
||||||
[basic-settings])
|
|
||||||
[advanced-settings]]))
|
[advanced-settings]]))
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
(fn [resolver rejecter]
|
(fn [resolver rejecter]
|
||||||
(json-rpc/call {:method "accounts_makeSeedPhraseKeypairFullyOperable"
|
(json-rpc/call {:method "accounts_makeSeedPhraseKeypairFullyOperable"
|
||||||
:params [(security/safe-unmask-data mnemonic)
|
:params [(security/safe-unmask-data mnemonic)
|
||||||
(-> password security/safe-unmask-data native-module/sha3)]
|
(security/safe-unmask-data password)]
|
||||||
:on-error (fn [error]
|
:on-error (fn [error]
|
||||||
(rejecter (ex-info (str error) {:error error})))
|
(rejecter (ex-info (str error) {:error error})))
|
||||||
:on-success (fn [value]
|
:on-success (fn [value]
|
||||||
|
|
|
@ -529,18 +529,17 @@
|
||||||
:wallet/process-keypair-from-backup
|
:wallet/process-keypair-from-backup
|
||||||
(fn [{:keys [db]} [{:keys [backedUpKeypair]}]]
|
(fn [{:keys [db]} [{:keys [backedUpKeypair]}]]
|
||||||
(let [{:keys [key-uid accounts]} backedUpKeypair
|
(let [{:keys [key-uid accounts]} backedUpKeypair
|
||||||
updated-keypairs (assoc-in db
|
accounts-fx
|
||||||
[:wallet :keypairs key-uid]
|
(mapv (fn [{:keys [chat] :as account}]
|
||||||
(data-store/rpc->keypair backedUpKeypair))
|
;; We exclude the chat account from the profile keypair for fetching the assets
|
||||||
accounts-fx (mapv (fn [{:keys [chat] :as account}]
|
(when-not chat
|
||||||
;; We exclude the chat account from the profile keypair
|
[:dispatch
|
||||||
;; for fetching the assets
|
[:wallet/process-account-from-signal
|
||||||
(when-not chat
|
account]]))
|
||||||
[:dispatch
|
accounts)]
|
||||||
[:wallet/process-account-from-signal
|
{:db (assoc-in db
|
||||||
account]]))
|
[:wallet :keypairs key-uid]
|
||||||
accounts)]
|
(data-store/rpc->keypair backedUpKeypair))
|
||||||
{:db (assoc-in db [:wallet :keypairs] updated-keypairs)
|
|
||||||
:fx accounts-fx})))
|
:fx accounts-fx})))
|
||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
|
|
||||||
(def ^:private initial-flags
|
(def ^:private initial-flags
|
||||||
{::community.edit-account-selection (enabled-in-env? :FLAG_EDIT_ACCOUNT_SELECTION_ENABLED)
|
{::community.edit-account-selection (enabled-in-env? :FLAG_EDIT_ACCOUNT_SELECTION_ENABLED)
|
||||||
::settings.keypairs-and-accounts (enabled-in-env?
|
|
||||||
:FLAG_WALLET_SETTINGS_KEYPAIRS_AND_ACCOUNTS_ENABLED)
|
|
||||||
::settings.saved-addresses (enabled-in-env?
|
::settings.saved-addresses (enabled-in-env?
|
||||||
:FLAG_WALLET_SETTINGS_SAVED_ADDRESSES_ENABLED)
|
:FLAG_WALLET_SETTINGS_SAVED_ADDRESSES_ENABLED)
|
||||||
|
::settings.import-all-keypairs (enabled-in-env?
|
||||||
|
:FLAG_WALLET_SETTINGS_IMPORT_ALL_KEYPAIRS)
|
||||||
::shell.jump-to (enabled-in-env? :ENABLE_JUMP_TO)
|
::shell.jump-to (enabled-in-env? :ENABLE_JUMP_TO)
|
||||||
::wallet.advanced-sending (enabled-in-env? :FLAG_ADVANCED_SENDING)
|
::wallet.advanced-sending (enabled-in-env? :FLAG_ADVANCED_SENDING)
|
||||||
::wallet.assets-modal-hide (enabled-in-env? :FLAG_ASSETS_MODAL_HIDE)
|
::wallet.assets-modal-hide (enabled-in-env? :FLAG_ASSETS_MODAL_HIDE)
|
||||||
|
|
|
@ -542,7 +542,7 @@
|
||||||
:component wallet-options/view}
|
:component wallet-options/view}
|
||||||
|
|
||||||
{:name :screen/settings.rename-keypair
|
{:name :screen/settings.rename-keypair
|
||||||
:options (assoc options/dark-screen :sheet? true)
|
:options options/transparent-screen-options
|
||||||
:component keypair-rename/view}
|
:component keypair-rename/view}
|
||||||
|
|
||||||
{:name :screen/settings.encrypted-keypair-qr
|
{:name :screen/settings.encrypted-keypair-qr
|
||||||
|
@ -558,7 +558,7 @@
|
||||||
:component keypairs-and-accounts/view}
|
:component keypairs-and-accounts/view}
|
||||||
|
|
||||||
{:name :screen/settings.scan-keypair-qr
|
{:name :screen/settings.scan-keypair-qr
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-screen-options
|
||||||
:component scan-keypair-qr/view}
|
:component scan-keypair-qr/view}
|
||||||
|
|
||||||
{:name :screen/settings.missing-keypair.import-seed-phrase
|
{:name :screen/settings.missing-keypair.import-seed-phrase
|
||||||
|
|
|
@ -205,6 +205,12 @@
|
||||||
(fn [{:keys [keypairs]}]
|
(fn [{:keys [keypairs]}]
|
||||||
(vals keypairs)))
|
(vals keypairs)))
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/keypair-names
|
||||||
|
:<- [:wallet/keypairs-list]
|
||||||
|
(fn [keypairs]
|
||||||
|
(set (map :name keypairs))))
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/selected-keypair-uid
|
:wallet/selected-keypair-uid
|
||||||
:<- [:wallet/create-account]
|
:<- [:wallet/create-account]
|
||||||
|
@ -244,7 +250,7 @@
|
||||||
size 32}}]
|
size 32}}]
|
||||||
(->> accounts
|
(->> accounts
|
||||||
(keep (fn [{:keys [path color emoji name address]}]
|
(keep (fn [{:keys [path color emoji name address]}]
|
||||||
(when-not (string/starts-with? path constants/path-eip1581)
|
(when-not (string/starts-with? (str path) constants/path-eip1581)
|
||||||
{:account-props {:customization-color color
|
{:account-props {:customization-color color
|
||||||
:size size
|
:size size
|
||||||
:emoji emoji
|
:emoji emoji
|
||||||
|
|
|
@ -643,18 +643,20 @@
|
||||||
:removed false})
|
:removed false})
|
||||||
|
|
||||||
(def profile-key-pair-key-uid "abc")
|
(def profile-key-pair-key-uid "abc")
|
||||||
|
(def profile-key-pair-name "My Profile")
|
||||||
(def seed-phrase-key-pair-key-uid "def")
|
(def seed-phrase-key-pair-key-uid "def")
|
||||||
|
(def seed-phrase-key-pair-name "My Key Pair")
|
||||||
|
|
||||||
(def profile-keypair
|
(def profile-keypair
|
||||||
{:key-uid profile-key-pair-key-uid
|
{:key-uid profile-key-pair-key-uid
|
||||||
:name "My Profile"
|
:name profile-key-pair-name
|
||||||
:type :profile
|
:type :profile
|
||||||
:lowest-operability :fully
|
:lowest-operability :fully
|
||||||
:accounts []})
|
:accounts []})
|
||||||
|
|
||||||
(def seed-phrase-keypair
|
(def seed-phrase-keypair
|
||||||
{:key-uid seed-phrase-key-pair-key-uid
|
{:key-uid seed-phrase-key-pair-key-uid
|
||||||
:name "My Key Pair"
|
:name seed-phrase-key-pair-name
|
||||||
:type :seed
|
:type :seed
|
||||||
:lowest-operability :no
|
:lowest-operability :no
|
||||||
:accounts []})
|
:accounts []})
|
||||||
|
@ -676,6 +678,14 @@
|
||||||
(is (= 2 (count result)))
|
(is (= 2 (count result)))
|
||||||
(is (match? expected result))))
|
(is (match? expected result))))
|
||||||
|
|
||||||
|
(h/deftest-sub :wallet/keypair-names
|
||||||
|
[sub-name]
|
||||||
|
(swap! rf-db/app-db assoc-in
|
||||||
|
[:wallet :keypairs]
|
||||||
|
{profile-key-pair-key-uid profile-keypair
|
||||||
|
seed-phrase-key-pair-key-uid seed-phrase-keypair})
|
||||||
|
(is (match? #{seed-phrase-key-pair-name profile-key-pair-name} (rf/sub [sub-name]))))
|
||||||
|
|
||||||
(h/deftest-sub :wallet/settings-keypairs-accounts
|
(h/deftest-sub :wallet/settings-keypairs-accounts
|
||||||
[sub-name]
|
[sub-name]
|
||||||
(testing "returns formatted key-pairs and accounts"
|
(testing "returns formatted key-pairs and accounts"
|
||||||
|
|
|
@ -1302,6 +1302,8 @@
|
||||||
"scan-with-status-app": "Scan with the Status app on another device",
|
"scan-with-status-app": "Scan with the Status app on another device",
|
||||||
"scan-key-pairs-qr-code": "Scan key pairs QR code",
|
"scan-key-pairs-qr-code": "Scan key pairs QR code",
|
||||||
"invalid-qr": "Oops! This QR doesn’t work with Status",
|
"invalid-qr": "Oops! This QR doesn’t work with Status",
|
||||||
|
"invalid-key-pair-qr": "This does not look like a key pair QR code",
|
||||||
|
"incorrect-qr-code": "This is not the QR code you are looking for",
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
"search-discover-communities": "Search communities or categories",
|
"search-discover-communities": "Search communities or categories",
|
||||||
"secret-keys-confirmation-text": "You will need them to continue to use your Keycard in case you ever lose your phone.",
|
"secret-keys-confirmation-text": "You will need them to continue to use your Keycard in case you ever lose your phone.",
|
||||||
|
@ -2639,6 +2641,7 @@
|
||||||
"max": "Max: {{number}}",
|
"max": "Max: {{number}}",
|
||||||
"your-key-pair-name-is-too-long": "Your key pair name is too long",
|
"your-key-pair-name-is-too-long": "Your key pair name is too long",
|
||||||
"your-key-pair-name-is-too-short": "Your key pair name is too short",
|
"your-key-pair-name-is-too-short": "Your key pair name is too short",
|
||||||
|
"key-name-error-taken": "Key pair name already in use",
|
||||||
"key-name-error-length": "Key name too long",
|
"key-name-error-length": "Key name too long",
|
||||||
"key-name-error-emoji": "Emojis are not allowed",
|
"key-name-error-emoji": "Emojis are not allowed",
|
||||||
"key-name-error-special-char": "Special characters are not allowed",
|
"key-name-error-special-char": "Special characters are not allowed",
|
||||||
|
|
Loading…
Reference in New Issue