feat (wallet): add ability to create new account (#17496)
This commit is contained in:
parent
ab2ad0ec12
commit
56492949f1
|
@ -765,7 +765,7 @@ SPEC CHECKSUMS:
|
|||
RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e
|
||||
RNPermissions: ad71dd4f767ec254f2cd57592fbee02afee75467
|
||||
RNReactNativeHapticFeedback: 2566b468cc8d0e7bb2f84b23adc0f4614594d071
|
||||
RNReanimated: b2dc21e263319892469d656dc58fc26fb03eadab
|
||||
RNReanimated: 62e43ee6baafb9ba3d3af1857d7fd23a1d41bff0
|
||||
RNShare: d82e10f6b7677f4b0048c23709bd04098d5aee6c
|
||||
RNStaticSafeAreaInsets: 055ddbf5e476321720457cdaeec0ff2ba40ec1b8
|
||||
RNSVG: 80584470ff1ffc7994923ea135a3e5ad825546b9
|
||||
|
@ -777,6 +777,6 @@ SPEC CHECKSUMS:
|
|||
TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4
|
||||
Yoga: d24d6184b6b85f742536bd93bd07d69d7b9bb4c1
|
||||
|
||||
PODFILE CHECKSUM: 6a5f0e6776ce4ef6193032d077947117ace77a87
|
||||
PODFILE CHECKSUM: 84b749023e1c988c133d7a6ec09d125536e4a4fd
|
||||
|
||||
COCOAPODS: 1.12.0
|
||||
|
|
|
@ -9,10 +9,8 @@
|
|||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[{:keys [on-enter-password button-label]}]
|
||||
(let [{:keys [key-uid display-name
|
||||
customization-color]
|
||||
:as account} (rf/sub [:profile/multiaccount])
|
||||
[{:keys [on-enter-password button-label button-icon-left customization-color]}]
|
||||
(let [{:keys [key-uid display-name] :as account} (rf/sub [:profile/multiaccount])
|
||||
{:keys [error processing password]} (rf/sub [:profile/login])
|
||||
sign-in-enabled? (rf/sub [:sign-in-enabled?])
|
||||
profile-picture (multiaccounts/displayed-photo account)]
|
||||
|
@ -45,7 +43,7 @@
|
|||
:type :primary
|
||||
:customization-color (or customization-color :primary)
|
||||
:accessibility-label :login-button
|
||||
:icon-left :i/reveal
|
||||
:icon-left button-icon-left
|
||||
:disabled? (or (not sign-in-enabled?) processing)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:set-in [:profile/login :key-uid] key-uid])
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
(defn authorize
|
||||
[{:keys [on-enter-password biometric-auth? on-auth-success on-auth-fail on-close
|
||||
fallback-button-label theme blur?]}]
|
||||
auth-button-label theme blur? customization-color auth-button-icon-left]}]
|
||||
(biometric/get-supported-type
|
||||
(fn [biometric-type]
|
||||
(if (and biometric-auth? biometric-type)
|
||||
|
@ -43,8 +43,10 @@
|
|||
:shell? blur?
|
||||
:content (fn []
|
||||
[enter-password/view
|
||||
{:on-enter-password on-enter-password
|
||||
:button-label fallback-button-label}])}]))))))
|
||||
{:customization-color customization-color
|
||||
:on-enter-password on-enter-password
|
||||
:button-icon-left auth-button-icon-left
|
||||
:button-label auth-button-label}])}]))))))
|
||||
|
||||
(defn- view-internal
|
||||
[_]
|
||||
|
@ -53,26 +55,31 @@
|
|||
(fn [{:keys [biometric-auth?
|
||||
track-text
|
||||
customization-color
|
||||
fallback-button-label
|
||||
auth-button-label
|
||||
on-enter-password
|
||||
on-auth-success
|
||||
on-auth-fail
|
||||
auth-button-icon-left
|
||||
size
|
||||
theme
|
||||
blur?]}]
|
||||
blur?
|
||||
container-style]}]
|
||||
[rn/view {:style {:flex 1}}
|
||||
[quo/slide-button
|
||||
{:size size
|
||||
:container-style container-style
|
||||
:customization-color customization-color
|
||||
:on-reset (when @reset-slider? #(reset! reset-slider? false))
|
||||
:on-complete #(authorize {:on-close on-close
|
||||
:auth-button-icon-left auth-button-icon-left
|
||||
:theme theme
|
||||
:blur? blur?
|
||||
:customization-color customization-color
|
||||
:on-enter-password on-enter-password
|
||||
:biometric-auth? biometric-auth?
|
||||
:on-auth-success on-auth-success
|
||||
:on-auth-fail on-auth-fail
|
||||
:fallback-button-label fallback-button-label})
|
||||
:auth-button-label auth-button-label})
|
||||
:track-icon (if biometric-auth? :i/face-id :password)
|
||||
:track-text track-text}]])))
|
||||
|
||||
|
|
|
@ -188,14 +188,16 @@
|
|||
native-module/sha3)]
|
||||
{:json-rpc/call [{:method "accounts_verifyPassword"
|
||||
:params [hashed-password]
|
||||
:on-success #(do (rf/dispatch [:profile.login/verified-database-password %]) (cb))
|
||||
:on-success #(rf/dispatch [:profile.login/verified-database-password % cb])
|
||||
:on-error #(log/error "accounts_verifyPassword error" %)}]}))
|
||||
|
||||
(rf/defn verify-database-password-success
|
||||
{:events [:profile.login/verified-database-password]}
|
||||
[{:keys [db] :as cofx} valid?]
|
||||
[{:keys [db] :as cofx} valid? callback]
|
||||
(if valid?
|
||||
(do
|
||||
(when (fn? callback)
|
||||
(callback))
|
||||
{:db (update db
|
||||
:profile/login
|
||||
dissoc
|
||||
|
|
|
@ -126,7 +126,8 @@
|
|||
:customization-color customization-color
|
||||
:on-enter-password on-enter-password
|
||||
:biometric-auth? false
|
||||
:fallback-button-label (i18n/label :t/reveal-sync-code)}]])]]
|
||||
:auth-button-label (i18n/label :t/reveal-sync-code)
|
||||
:auth-button-icon-left :i/reveal}]])]]
|
||||
[rn/view {:style style/sync-code}
|
||||
[quo/divider-label {:tight? false} (i18n/label :t/have-a-sync-code?)]
|
||||
[quo/action-drawer
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
[react-native.core :as rn]
|
||||
[status-im2.common.resources :as status.resources]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.wallet.common.utils :as utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
|
@ -112,35 +111,6 @@
|
|||
:account :default
|
||||
:customization-color :blue})
|
||||
|
||||
(defn keypair-string
|
||||
[full-name]
|
||||
(let [first-name (utils/get-first-name full-name)]
|
||||
(i18n/label :t/keypair-title {:name first-name})))
|
||||
|
||||
(defn create-account-state
|
||||
[name]
|
||||
[{:title (keypair-string name)
|
||||
:image :avatar
|
||||
:image-props {:full-name "A Y"
|
||||
:size :xxs
|
||||
:customization-color :blue}
|
||||
:action :button
|
||||
:action-props {:on-press #(js/alert "Button pressed!")
|
||||
:button-text (i18n/label :t/edit)
|
||||
:alignment :flex-start}
|
||||
:description :text
|
||||
:description-props {:text (i18n/label :t/on-device)}}
|
||||
{:title (i18n/label :t/derivation-path)
|
||||
:image :icon
|
||||
:image-props :i/derivated-path
|
||||
:action :button
|
||||
:action-props {:on-press #(js/alert "Button pressed!")
|
||||
:button-text (i18n/label :t/edit)
|
||||
:icon-left :i/placeholder
|
||||
:alignment :flex-start}
|
||||
:description :text
|
||||
:description-props {:text (string/replace constants/path-default-wallet #"/" " / ")}}])
|
||||
|
||||
(def network-names [:ethereum :optimism :arbitrum])
|
||||
|
||||
(def address "0x39cf6E0Ba4C4530735616e1Ee7ff5FbCB726fBd4")
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
(ns status-im2.contexts.wallet.common.utils
|
||||
(:require
|
||||
[clojure.string :as string]))
|
||||
(:require [clojure.string :as string]
|
||||
[status-im2.constants :as constants]))
|
||||
|
||||
(defn get-first-name
|
||||
[full-name]
|
||||
(first (string/split full-name #" ")))
|
||||
|
||||
(defn get-derivation-path
|
||||
[number-of-accounts]
|
||||
(str constants/path-wallet-root "/" number-of-accounts))
|
||||
|
|
|
@ -5,20 +5,44 @@
|
|||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.wallet.common.temp :as temp]
|
||||
[status-im2.common.standard-authentication.standard-auth.view :as standard-auth]
|
||||
[status-im2.contexts.wallet.common.utils :as utils]
|
||||
[status-im2.contexts.wallet.create-account.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def diamond-emoji "\uD83D\uDC8E")
|
||||
|
||||
(defn keypair-string
|
||||
[full-name]
|
||||
(let [first-name (utils/get-first-name full-name)]
|
||||
(i18n/label :t/keypair-title {:name first-name})))
|
||||
|
||||
(defn get-keypair-data
|
||||
[name derivation-path]
|
||||
[{:title (keypair-string name)
|
||||
:button-props {:title (i18n/label :t/edit)}
|
||||
:left-icon :i/placeholder
|
||||
:description :text
|
||||
:description-props {:text (i18n/label :t/on-device)}}
|
||||
{:title (i18n/label :t/derivation-path)
|
||||
:button-props {:title (i18n/label :t/edit)}
|
||||
:left-icon :i/derivated-path
|
||||
:description :text
|
||||
:description-props {:text derivation-path}}])
|
||||
|
||||
(defn- view-internal
|
||||
[]
|
||||
(let [top (safe-area/get-top)
|
||||
bottom (safe-area/get-bottom)
|
||||
account-color (reagent/atom :blue)
|
||||
emoji (reagent/atom diamond-emoji)
|
||||
number-of-accounts (count (rf/sub [:profile/wallet-accounts]))
|
||||
account-name (reagent/atom (i18n/label :t/default-account-name
|
||||
{:number (inc number-of-accounts)}))
|
||||
derivation-path (reagent/atom (utils/get-derivation-path number-of-accounts))
|
||||
{:keys [public-key]} (rf/sub [:profile/profile])
|
||||
on-change-text #(reset! account-name %)
|
||||
display-name (first (rf/sub [:contacts/contact-two-names-by-identity public-key]))]
|
||||
(fn [{:keys [theme]}]
|
||||
[rn/view
|
||||
|
@ -50,12 +74,13 @@
|
|||
(reset! emoji selected-emoji))}])
|
||||
:container-style style/reaction-button-container} :i/reaction]]
|
||||
[quo/title-input
|
||||
{:color :red
|
||||
{:customization-color @account-color
|
||||
:placeholder "Type something here"
|
||||
:on-change-text on-change-text
|
||||
:max-length 24
|
||||
:blur? true
|
||||
:disabled? false
|
||||
:default-value "Account 2"
|
||||
:default-value @account-name
|
||||
:container-style style/title-input-container}]
|
||||
[quo/divider-line]
|
||||
[rn/view
|
||||
|
@ -74,13 +99,20 @@
|
|||
[quo/category
|
||||
{:list-type :settings
|
||||
:label (i18n/label :t/origin)
|
||||
:data (temp/create-account-state display-name)}]
|
||||
[quo/slide-button
|
||||
{:track-text (i18n/label :t/slide-to-sign)
|
||||
:track-icon :face-id
|
||||
:data (get-keypair-data display-name @derivation-path)}]
|
||||
[standard-auth/view
|
||||
{:size :size-48
|
||||
:track-text (i18n/label :t/slide-to-create-account)
|
||||
:customization-color @account-color
|
||||
:on-complete (fn []
|
||||
(js/alert "Functionality not implemented"))
|
||||
:on-enter-password (fn [entered-password]
|
||||
(rf/dispatch [:wallet/derive-address-and-add-account
|
||||
entered-password
|
||||
{:emoji @emoji
|
||||
:color @account-color
|
||||
:path @derivation-path
|
||||
:account-name @account-name}]))
|
||||
:biometric-auth? false
|
||||
:auth-button-label (i18n/label :t/confirm)
|
||||
:container-style (style/slide-button-container bottom)}]])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
(ns status-im2.contexts.wallet.events
|
||||
(:require [utils.re-frame :as rf]))
|
||||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/defn scan-address-success
|
||||
{:events [:wallet/scan-address-success]}
|
||||
|
@ -10,3 +14,40 @@
|
|||
{:events [:wallet/clean-scanned-address]}
|
||||
[{:keys [db]}]
|
||||
{:db (dissoc db :wallet/scanned-address)})
|
||||
|
||||
(rf/reg-event-fx :wallet/create-derived-addresses
|
||||
(fn [{:keys [db]} [password {:keys [path]} on-success]]
|
||||
(let [{:keys [wallet-root-address]} (:profile/profile db)
|
||||
sha3-pwd (native-module/sha3 (str (security/safe-unmask-data password)))]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wallet_getDerivedAddresses"
|
||||
:params [sha3-pwd wallet-root-address [path]]
|
||||
:on-success on-success
|
||||
:on-error #(log/info "failed to derive address " %)}]]]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/add-account
|
||||
(fn [{:keys [db]} [password {:keys [emoji account-name color]} {:keys [public-key address path]}]]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])
|
||||
sha3-pwd (native-module/sha3 (security/safe-unmask-data password))
|
||||
account-config {:key-uid key-uid
|
||||
:wallet false
|
||||
:chat false
|
||||
:type :generated
|
||||
:name account-name
|
||||
:emoji emoji
|
||||
:path path
|
||||
:address address
|
||||
:public-key public-key
|
||||
:colorID color}]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "accounts_addAccount"
|
||||
:params [sha3-pwd account-config]
|
||||
:on-success #(rf/dispatch [:navigate-to :wallet-accounts])
|
||||
:on-error #(log/info "failed to create account " %)}]]]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/derive-address-and-add-account
|
||||
(fn [_ [password account-details]]
|
||||
(let [on-success (fn [derived-adress-details]
|
||||
(rf/dispatch [:wallet/add-account password account-details
|
||||
(first derived-adress-details)]))]
|
||||
{:fx [[:dispatch [:wallet/create-derived-addresses password account-details on-success]]]})))
|
||||
|
|
|
@ -146,3 +146,4 @@
|
|||
|
||||
;;wallet
|
||||
(reg-root-key-sub :wallet/scanned-address :wallet/scanned-address)
|
||||
(reg-root-key-sub :wallet/create-account :wallet/create-account)
|
||||
|
|
|
@ -83,3 +83,5 @@
|
|||
(def reg-fx re-frame/reg-fx)
|
||||
|
||||
(def dispatch-sync re-frame/dispatch-sync)
|
||||
|
||||
(def reg-event-fx re-frame/reg-event-fx)
|
||||
|
|
|
@ -433,6 +433,7 @@
|
|||
"decline": "Decline",
|
||||
"decryption-failed-content": "An error occured decrypting your data. You might need to erase your old data and generate a new account. Tap “Apply” to erase or “Cancel” to try again",
|
||||
"default": "Default",
|
||||
"default-account-name": "Account {{number}}",
|
||||
"delete": "Delete",
|
||||
"delete-and-leave-group": "Delete and leave group",
|
||||
"delete-bootnode": "Delete bootnode",
|
||||
|
@ -1893,6 +1894,7 @@
|
|||
"select-token-to-swap": "Select token to Swap",
|
||||
"select-token-to-receive": "Select token to receive",
|
||||
"slide-to-reveal-code": "Slide to reveal code",
|
||||
"slide-to-create-account": "Slide to create account",
|
||||
"minimum-received": "Minimum received",
|
||||
"powered-by-paraswap": "Powered by Paraswap",
|
||||
"priority": "Priority",
|
||||
|
@ -2360,5 +2362,6 @@
|
|||
"network-preferences": "Network preferences",
|
||||
"network-preferences-desc": "Select which network this address is happy to receive funds on",
|
||||
"layer-2": "Layer 2",
|
||||
"manage-tokens": "Manage tokens"
|
||||
"manage-tokens": "Manage tokens",
|
||||
"sign transactions": "sign transactions"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue