parent
ac78dea8ef
commit
abd2b43ce6
|
@ -55,7 +55,7 @@
|
|||
:action :selector
|
||||
:details other-details}]
|
||||
theme)
|
||||
(h/is-truthy (h/get-by-label-text :radio-on)))
|
||||
(h/is-truthy (h/get-by-label-text :radio-off)))
|
||||
|
||||
(h/test "Options action renders"
|
||||
(h/render-with-theme-provider [keypair/view
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(ns quo.components.wallet.keypair.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(defn container
|
||||
[{:keys [blur? customization-color theme selected?]}]
|
||||
|
@ -34,3 +35,8 @@
|
|||
{:color (if blur?
|
||||
colors/white-opa-40
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})
|
||||
|
||||
(defn dot
|
||||
[blur? theme]
|
||||
(merge (subtitle blur? theme)
|
||||
{:bottom (if platform/ios? 2 -2)}))
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[reagent.core :as reagent]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
|
@ -60,7 +59,7 @@
|
|||
:accessibility-label :options-button}]])]))
|
||||
|
||||
(defn details-view
|
||||
[{:keys [details stored blur? theme]}]
|
||||
[{:keys [details stored type blur? theme]}]
|
||||
(let [{:keys [address]} details]
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
|
@ -70,10 +69,11 @@
|
|||
{:size :paragraph-2
|
||||
:style (style/subtitle blur? theme)}
|
||||
address]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style (merge (style/subtitle blur? theme) {:bottom (if platform/ios? 2 -2)})}
|
||||
" ∙ "]
|
||||
(when (= type :default-keypair)
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style (style/dot blur? theme)}
|
||||
" ∙ "])
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style (style/subtitle blur? theme)}
|
||||
|
@ -87,8 +87,8 @@
|
|||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}]])]))
|
||||
|
||||
(defn- view-internal
|
||||
[]
|
||||
(let [selected? (reagent/atom true)]
|
||||
[{:keys [default-selected?]}]
|
||||
(let [selected? (reagent/atom default-selected?)]
|
||||
(fn [{:keys [accounts action container-style] :as props}]
|
||||
[rn/pressable
|
||||
{:style (merge (style/container (merge props {:selected? @selected?})) container-style)
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
secret-phrase (reagent/atom [])
|
||||
random-phrase (reagent/atom [])]
|
||||
(fn []
|
||||
(rn/use-effect
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
(native-module/get-random-mnemonic #(reset! secret-phrase (string/split % #"\s")))
|
||||
(native-module/get-random-mnemonic #(reset! random-phrase (string/split % #"\s")))))
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
(ns status-im.contexts.wallet.create-account.select-keypair.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.profile.utils :as profile.utils]
|
||||
[status-im.contexts.wallet.create-account.select-keypair.style :as style]
|
||||
[utils.address :as utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn keypair-options
|
||||
(defn- keypair-options
|
||||
[]
|
||||
[quo/action-drawer
|
||||
[[{:icon :i/add
|
||||
|
@ -26,25 +28,51 @@
|
|||
:accessibility-label :import-private-key
|
||||
:label (i18n/label :t/import-private-key)}]]])
|
||||
|
||||
(def accounts
|
||||
[{:account-props {:customization-color :turquoise
|
||||
:size 32
|
||||
:emoji "\uD83C\uDFB2"
|
||||
:type :default
|
||||
:name "Trip to Vegas"
|
||||
:address "0x0ah...71a"}
|
||||
:networks [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "opt"}]
|
||||
:state :default
|
||||
:action :none}])
|
||||
(defn- parse-accounts
|
||||
[given-accounts]
|
||||
(->> given-accounts
|
||||
(filter (fn [{:keys [path]}]
|
||||
(not (string/starts-with? path constants/path-eip1581))))
|
||||
(map (fn [{:keys [customization-color emoji name address]}]
|
||||
{:account-props {:customization-color customization-color
|
||||
:size 32
|
||||
:emoji emoji
|
||||
:type :default
|
||||
:name name
|
||||
:address address}
|
||||
:networks [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "opt"}
|
||||
{:network-name :arbitrum :short-name "arb1"}]
|
||||
:state :default
|
||||
:action :none}))))
|
||||
|
||||
(defn- keypair
|
||||
[item index _ {:keys [profile-picture compressed-key]}]
|
||||
(let [main-account (first (:accounts item))
|
||||
color (:customization-color main-account)
|
||||
accounts (parse-accounts (:accounts item))]
|
||||
[quo/keypair
|
||||
{:customization-color color
|
||||
:profile-picture (when (zero? index) profile-picture)
|
||||
:status-indicator false
|
||||
:type (if (zero? index) :default-keypair :other)
|
||||
:stored :on-device
|
||||
:on-options-press #(js/alert "Options pressed")
|
||||
:action :selector
|
||||
:blur? false
|
||||
:details {:full-name (:name item)
|
||||
:address (when (zero? index)
|
||||
(utils/get-shortened-compressed-key compressed-key))}
|
||||
:accounts accounts
|
||||
:default-selected? (zero? index)
|
||||
:container-style {:margin-horizontal 20
|
||||
:margin-vertical 8}}]))
|
||||
(defn view
|
||||
[]
|
||||
(let [{:keys [public-key compressed-key
|
||||
customization-color]} (rf/sub [:profile/profile])
|
||||
[display-name _] (rf/sub [:contacts/contact-two-names-by-identity public-key])
|
||||
profile-with-image (rf/sub [:profile/profile-with-image])
|
||||
profile-picture (profile.utils/photo profile-with-image)]
|
||||
(let [{:keys [compressed-key customization-color]} (rf/sub [:profile/profile])
|
||||
profile-with-image (rf/sub [:profile/profile-with-image])
|
||||
keypairs (rf/sub [:wallet/keypairs])
|
||||
profile-picture (profile.utils/photo profile-with-image)]
|
||||
[rn/view {:style {:flex 1}}
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
|
@ -60,20 +88,12 @@
|
|||
[:show-bottom-sheet {:content keypair-options}])}
|
||||
:description :text
|
||||
:description-text (i18n/label :t/keypairs-description)}]
|
||||
[quo/keypair
|
||||
{:customization-color customization-color
|
||||
:profile-picture profile-picture
|
||||
:status-indicator false
|
||||
:type :default-keypair
|
||||
:stored :on-device
|
||||
:on-options-press #(js/alert "Options pressed")
|
||||
:action :selector
|
||||
:blur? false
|
||||
:details {:full-name display-name
|
||||
:address (utils/get-shortened-compressed-key compressed-key)}
|
||||
:accounts accounts
|
||||
:container-style {:margin-horizontal 20
|
||||
:margin-vertical 8}}]
|
||||
[rn/flat-list
|
||||
{:data keypairs
|
||||
:render-fn keypair
|
||||
:render-data {:profile-picture profile-picture
|
||||
:compressed-key compressed-key}
|
||||
:content-container-style {:padding-bottom 60}}]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/confirm-account-origin)
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
(ns status-im.contexts.wallet.create-account.utils)
|
||||
|
||||
(defn prepare-new-keypair
|
||||
[{:keys [new-keypair address account-name account-color emoji derivation-path]}]
|
||||
(assoc new-keypair
|
||||
:name (:keypair-name new-keypair)
|
||||
:key-uid (:keyUid new-keypair)
|
||||
:type :seed
|
||||
:derived-from address
|
||||
:accounts [{:keypair-name (:keypair-name new-keypair)
|
||||
:key-uid (:keyUid new-keypair)
|
||||
:seed-phrase (:mnemonic new-keypair)
|
||||
:public-key (:publicKey new-keypair)
|
||||
:name account-name
|
||||
:type :seed
|
||||
:emoji emoji
|
||||
:colorID account-color
|
||||
:path derivation-path
|
||||
:address (:address new-keypair)}]))
|
|
@ -13,13 +13,14 @@
|
|||
[status-im.contexts.wallet.common.sheets.account-origin.view :as account-origin]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.create-account.style :as style]
|
||||
[status-im.feature-flags :as ff]
|
||||
[status-im.contexts.wallet.create-account.utils :as create-account.utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.responsiveness :refer [iphone-11-Pro-20-pixel-from-width]]
|
||||
[utils.security.core :as security]
|
||||
[utils.string]))
|
||||
|
||||
|
||||
(defn- get-keypair-data
|
||||
[primary-name derivation-path account-color {:keys [keypair-name]}]
|
||||
[{:title (or keypair-name (i18n/label :t/keypair-title {:name primary-name}))
|
||||
|
@ -30,9 +31,8 @@
|
|||
:size :xxs
|
||||
:customization-color account-color})
|
||||
:action (when-not keypair-name :button)
|
||||
:action-props {:on-press #(ff/alert ::ff/wallet.edit-default-keypair
|
||||
(fn []
|
||||
(rf/dispatch [:navigate-to :wallet-select-keypair])))
|
||||
:action-props {:on-press (fn []
|
||||
(rf/dispatch [:navigate-to :wallet-select-keypair]))
|
||||
:button-text (i18n/label :t/edit)
|
||||
:alignment :flex-start}
|
||||
:description :text
|
||||
|
@ -50,22 +50,23 @@
|
|||
|
||||
(defn- f-view
|
||||
[]
|
||||
(let [top (safe-area/get-top)
|
||||
bottom (safe-area/get-bottom)
|
||||
account-color (reagent/atom (rand-nth colors/account-colors))
|
||||
emoji (reagent/atom (emoji-picker.utils/random-emoji))
|
||||
number-of-accounts (count (rf/sub [:wallet/accounts-without-watched-accounts]))
|
||||
account-name (reagent/atom "")
|
||||
placeholder (i18n/label :t/default-account-placeholder
|
||||
{: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 %)
|
||||
primary-name (first (rf/sub [:contacts/contact-two-names-by-identity public-key]))
|
||||
{window-width :width} (rn/get-window)]
|
||||
(let [top (safe-area/get-top)
|
||||
bottom (safe-area/get-bottom)
|
||||
account-color (reagent/atom (rand-nth colors/account-colors))
|
||||
emoji (reagent/atom (emoji-picker.utils/random-emoji))
|
||||
number-of-accounts (count (rf/sub [:wallet/accounts-without-watched-accounts]))
|
||||
account-name (reagent/atom "")
|
||||
placeholder (i18n/label :t/default-account-placeholder
|
||||
{:number (inc number-of-accounts)})
|
||||
derivation-path (reagent/atom (utils/get-derivation-path number-of-accounts))
|
||||
{:keys [public-key address]} (rf/sub [:profile/profile])
|
||||
on-change-text #(reset! account-name %)
|
||||
primary-name (first (rf/sub [:contacts/contact-two-names-by-identity
|
||||
public-key]))
|
||||
{window-width :width} (rn/get-window)]
|
||||
(fn [{:keys [theme]}]
|
||||
(let [{:keys [new-keypair]} (rf/sub [:wallet/create-account])]
|
||||
(rn/use-effect (fn [] #(rf/dispatch [:wallet/clear-new-keypair])))
|
||||
(rn/use-unmount #(rf/dispatch [:wallet/clear-new-keypair]))
|
||||
[rn/view {:style {:flex 1}}
|
||||
[quo/page-nav
|
||||
{:type :no-title
|
||||
|
@ -127,7 +128,18 @@
|
|||
:customization-color @account-color
|
||||
:on-auth-success (fn [entered-password]
|
||||
(if new-keypair
|
||||
(js/alert "Feature under development")
|
||||
(rf/dispatch
|
||||
[:wallet/add-keypair-and-create-account
|
||||
{:sha3-pwd (security/safe-unmask-data
|
||||
entered-password)
|
||||
:new-keypair (create-account.utils/prepare-new-keypair
|
||||
{:new-keypair new-keypair
|
||||
:address address
|
||||
:account-name @account-name
|
||||
:account-color @account-color
|
||||
:emoji @emoji
|
||||
:derivation-path
|
||||
@derivation-path})}])
|
||||
(rf/dispatch [:wallet/derive-address-and-add-account
|
||||
{:sha3-pwd (security/safe-unmask-data
|
||||
entered-password)
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
(assoc account :watch-only? (= (:type account) :watch)))
|
||||
|
||||
(defn- sanitize-emoji
|
||||
"As Desktop uses Twemoji, the emoji received can be an img tag
|
||||
with raw emoji in alt attribute. This function help us to extract
|
||||
"As Desktop uses Twemoji, the emoji received can be an img tag
|
||||
with raw emoji in alt attribute. This function help us to extract
|
||||
the emoji from it as mobile doesn't support HTML rendering and Twemoji"
|
||||
[emoji]
|
||||
(if (string/starts-with? emoji "<img")
|
||||
|
@ -104,3 +104,23 @@
|
|||
:blockExplorerUrl :block-explorer-url
|
||||
:nativeCurrencySymbol :native-currency-symbol
|
||||
:nativeCurrencyName :native-currency-symbol})))
|
||||
|
||||
(defn rename-color-id-in-data
|
||||
[data]
|
||||
(map (fn [item]
|
||||
(update item
|
||||
:accounts
|
||||
(fn [accounts]
|
||||
(map (fn [account]
|
||||
(let [renamed-account (set/rename-keys account
|
||||
{:colorId :customization-color})]
|
||||
(if (contains? account :colorId)
|
||||
renamed-account
|
||||
(assoc renamed-account :customization-color :blue))))
|
||||
accounts))))
|
||||
data))
|
||||
|
||||
(defn parse-keypairs
|
||||
[keypairs]
|
||||
(let [renamed-data (rename-color-id-in-data keypairs)]
|
||||
(cske/transform-keys csk/->kebab-case-keyword renamed-data)))
|
||||
|
|
|
@ -202,6 +202,35 @@
|
|||
(first derived-address-details)]))]
|
||||
{:fx [[:dispatch [:wallet/create-derived-addresses account-details on-success]]]})))
|
||||
|
||||
(defn add-keypair-and-create-account
|
||||
[_ [{:keys [sha3-pwd new-keypair]}]]
|
||||
(let [lowercase-address (if (:address new-keypair)
|
||||
(string/lower-case (:address new-keypair))
|
||||
(:address new-keypair))]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "accounts_addKeypair"
|
||||
:params [sha3-pwd new-keypair]
|
||||
:on-success [:wallet/add-account-success lowercase-address]
|
||||
:on-error #(log/info "failed to create keypair " %)}]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/add-keypair-and-create-account add-keypair-and-create-account)
|
||||
|
||||
(defn get-keypairs
|
||||
[_]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "accounts_getKeypairs"
|
||||
:params []
|
||||
:on-success [:wallet/get-keypairs-success]
|
||||
:on-error #(log/info "failed to get keypairs " %)}]]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/get-keypairs get-keypairs)
|
||||
|
||||
(defn get-keypairs-success
|
||||
[{:keys [db]} [keypairs]]
|
||||
{:db (assoc-in db [:wallet :keypairs] (data-store/parse-keypairs keypairs))})
|
||||
|
||||
(rf/reg-event-fx :wallet/get-keypairs-success get-keypairs-success)
|
||||
|
||||
(rf/reg-event-fx :wallet/bridge-select-token
|
||||
(fn [{:keys [db]} [{:keys [token stack-id]}]]
|
||||
(let [to-address (get-in db [:wallet :current-viewing-account-address])]
|
||||
|
@ -371,7 +400,8 @@
|
|||
(fn []
|
||||
{:fx [[:dispatch [:wallet/start-wallet]]
|
||||
[:dispatch [:wallet/get-ethereum-chains]]
|
||||
[:dispatch [:wallet/get-accounts]]]}))
|
||||
[:dispatch [:wallet/get-accounts]]
|
||||
[:dispatch [:wallet/get-keypairs]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/share-account
|
||||
(fn [_ [{:keys [content title]}]]
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
effects (events/clear-new-keypair {:db db})]
|
||||
(is (match? (:db effects) expected-db))))
|
||||
|
||||
|
||||
(deftest store-collectibles
|
||||
(testing "(displayable-collectible?) helper function"
|
||||
(let [expected-results [[true
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
(defonce ^:private feature-flags-config
|
||||
(reagent/atom
|
||||
{::wallet.edit-default-keypair (enabled-in-env? :FLAG_EDIT_DEFAULT_KEYPAIR_ENABLED)
|
||||
{::wallet.edit-default-keypair true
|
||||
::wallet.bridge-token (enabled-in-env? :FLAG_BRIDGE_TOKEN_ENABLED)
|
||||
::wallet.remove-account (enabled-in-env? :FLAG_REMOVE_ACCOUNT_ENABLED)
|
||||
::wallet.network-filter (enabled-in-env? :FLAG_NETWORK_FILTER_ENABLED)
|
||||
|
|
|
@ -93,6 +93,11 @@
|
|||
:<- [:wallet/ui]
|
||||
:-> :watch-address-activity-state)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/keypairs
|
||||
:<- [:wallet]
|
||||
:-> :keypairs)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/accounts
|
||||
:<- [:wallet]
|
||||
|
|
|
@ -497,3 +497,15 @@
|
|||
(get "0x3")
|
||||
(assoc :network-preferences-names #{}))]
|
||||
(rf/sub [sub-name])))))
|
||||
|
||||
(def keypairs
|
||||
[{:key-uid "abc"}])
|
||||
|
||||
(h/deftest-sub :wallet/keypairs
|
||||
[sub-name]
|
||||
(testing "returns all keypairs"
|
||||
(swap! rf-db/app-db
|
||||
#(assoc-in % [:wallet :keypairs] keypairs))
|
||||
(is
|
||||
(= keypairs
|
||||
(rf/sub [sub-name])))))
|
||||
|
|
Loading…
Reference in New Issue