Skip to content

Commit

Permalink
[#18817] Import private key: UI for key pair name
Browse files Browse the repository at this point in the history
Move files

Fix label

Enable feature and fix auto-focus

Add events and subs
  • Loading branch information
Rende11 committed Apr 30, 2024
1 parent 8c26125 commit cfef154
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 49 deletions.
Expand Up @@ -90,3 +90,25 @@
(cske/transform-keys transforms/->kebab-case-keyword derived-address)))}))

(rf/reg-event-fx :wallet/get-derived-addresses-success get-derived-addresses-success)

;; Import private key

(rf/reg-event-fx
:wallet.import-private-key/set-private-key
(fn [{:keys [db]} [value]]
{:db (assoc-in db [:wallet :ui :import-private-key :private-key] value)}))

(rf/reg-event-fx
:wallet.import-private-key/set-public-address
(fn [{:keys [db]} [value]]
{:db (assoc-in db [:wallet :ui :import-private-key :public-address] value)}))

(rf/reg-event-fx
:wallet.import-private-key/set-key-pair-name
(fn [{:keys [db]} [value]]
{:db (assoc-in db [:wallet :ui :import-private-key :key-pair-name] value)}))

(rf/reg-event-fx
:wallet.import-private-key/clear-data
(fn [{:keys [db]} _]
{:db (update-in db [:wallet :ui] dissoc :import-private-key)}))
@@ -0,0 +1,12 @@
(ns status-im.contexts.wallet.add-account.create-account.import-private-key.add-key-pair-name.style)

(def top
{:margin-top 2})

(def input
{:padding-top 12
:padding-horizontal 20})

(def error
{:padding-horizontal 20
:padding-vertical 8})
@@ -0,0 +1,77 @@
(ns status-im.contexts.wallet.add-account.create-account.import-private-key.add-key-pair-name.view
(:require
[quo.core :as quo]
[react-native.core :as rn]
[status-im.common.floating-button-page.view :as floating-button-page]
[status-im.common.validation.general :as validators]
[status-im.contexts.wallet.add-account.create-account.import-private-key.add-key-pair-name.style :as
style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))

(def keypair-name-max-length 15)
(def keypair-name-min-length 5)

(def error-messages
{:too-long (i18n/label :t/key-name-error-length)
:too-short (i18n/label :t/key-name-error-too-short {:count keypair-name-min-length})
:emoji (i18n/label :t/key-name-error-emoji)
:special-char (i18n/label :t/key-name-error-special-char)})

(defn view
[]
(let [customization-color (rf/sub [:profile/customization-color])
key-pair-name (rf/sub [:wallet.import-private-key/key-pair-name])
[error set-error] (rn/use-state)
on-change-text (rn/use-callback
(fn [value]
(rf/dispatch [:wallet.import-private-key/set-key-pair-name value])
(cond
(validators/has-emojis? value)
(set-error :emoji)

(validators/has-special-characters? value)
(set-error :special-char)

(> (count value) keypair-name-max-length)
(set-error :too-long)

(and (seq value) (< (count value) keypair-name-min-length))
(set-error :too-short)

:else (set-error nil))))

disabled? (or (some? error) (empty? key-pair-name))]
[rn/view {:flex 1}
[floating-button-page/view
{:customization-color customization-color
:header [quo/page-nav
{:background :white
:type :no-title
:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back])}]
:footer [quo/button
{:customization-color customization-color
:disabled? disabled?
:on-press prn}
(i18n/label :t/continue)]}
[quo/page-top
{:title (i18n/label :t/key-pair-name)
:description :text
:description-text (i18n/label :t/key-pair-name-desc)
:container-style style/top}]
[quo/input
{:label (i18n/label :t/key-pair-name)
:placeholder (i18n/label :t/key-pair-name-placeholder)
:char-limit keypair-name-max-length
:auto-focus true
:container-style style/input
:on-change-text on-change-text
:error? error}]
(when error
[quo/info-message
{:type :error
:size :default
:icon :i/info
:container-style style/error}
(get error-messages error)])]]))
@@ -1,4 +1,4 @@
(ns status-im.contexts.wallet.add-account.create-account.import-private-key.style
(ns status-im.contexts.wallet.add-account.create-account.import-private-key.private-key.style
(:require [quo.foundations.colors :as colors]))

(def input
Expand Down
@@ -1,56 +1,60 @@
(ns status-im.contexts.wallet.add-account.create-account.import-private-key.view
(ns status-im.contexts.wallet.add-account.create-account.import-private-key.private-key.view
(:require
[quo.core :as quo]
[quo.theme :as theme]
[react-native.clipboard :as clipboard]
[react-native.core :as rn]
[status-im.common.floating-button-page.view :as floating-button-page]
[status-im.contexts.wallet.add-account.create-account.import-private-key.style :as style]
[status-im.contexts.wallet.add-account.create-account.import-private-key.private-key.style :as style]
[status-im.contexts.wallet.common.validation :as v]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))

(defn- address-input
[{:keys [input-value set-input-value set-flow-state error?]}]
(let [check-address (rn/use-callback
(debounce/debounce (fn [v]
(if (empty? v)
(set-flow-state nil)
;; TODO check for validation
(if-not (v/private-key? v)
(set-flow-state :invalid-private-key)
;; TODO add real requests
(do
(set-flow-state :scanning)
(js/setTimeout
set-flow-state
400
(rand-nth [:active-address :inactive-address]))))))
500))
on-change (rn/use-callback
(fn [v]
(set-input-value v)
(check-address v)))
on-paste (rn/use-callback
(fn []
(clipboard/get-string
(fn [clipboard]
(when-not (empty? clipboard)
(on-change clipboard))))))]
[{:keys [input-value set-flow-state error?]}]
(let [check-address
(rn/use-callback
(debounce/debounce
(fn [v]
(if (empty? v)
(set-flow-state nil)
;; TODO check for validation
(if-not (v/private-key? v)
(set-flow-state :invalid-private-key)
;; TODO add real requests
(do
(set-flow-state :scanning)
;; TODO get real address
(rf/dispatch [:wallet.import-private-key/set-public-address
"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"])
(js/setTimeout set-flow-state 400 (rand-nth [:active-address :inactive-address]))))))
500))

on-change (rn/use-callback
(fn [v]
(rf/dispatch [:wallet.import-private-key/set-private-key v])
(check-address v)))
on-paste (rn/use-callback
(fn []
(clipboard/get-string
(fn [clipboard]
(when-not (empty? clipboard)
(on-change clipboard))))))]
[quo/input
{:accessibility-label :add-address-to-watch
{:accessibility-label :import-private-key
:placeholder (i18n/label :t/enter-private-key-placeholder)
:container-style style/input
:label (i18n/label :t/private-key)
:type :password
:error? error?
:return-key-type :done
:auto-focus true
:on-change-text on-change
:button (when (empty? input-value)
{:on-press on-paste
:text (i18n/label :t/paste)})
:value input-value}]))
:default-value input-value}]))

(defn- activity-indicator
[state]
Expand Down Expand Up @@ -86,11 +90,13 @@

(defn view
[]
(let [theme (theme/use-theme)
customization-color (rf/sub [:profile/customization-color])
[input-value set-input-value] (rn/use-state "")
[flow-state set-flow-state] (rn/use-state)
error? (= :invalid-private-key flow-state)]
(let [theme (theme/use-theme)
customization-color (rf/sub [:profile/customization-color])
private-key (rf/sub [:wallet.import-private-key/private-key])
public-address (rf/sub [:wallet.import-private-key/public-address])
[flow-state set-flow-state] (rn/use-state)
error? (= :invalid-private-key flow-state)]
(rn/use-mount #(rf/dispatch [:wallet.import-private-key/clear-data]))
[rn/view {:flex 1}
[floating-button-page/view
{:customization-color customization-color
Expand All @@ -108,26 +114,26 @@
(i18n/label :t/import-private-key-info)])
[quo/button
{:customization-color customization-color
:disabled? (or (empty? input-value) error?)
:on-press #()}
:disabled? (or (empty? private-key) error?)
:on-press #(rf/dispatch [:navigate-to
:screen/wallet.add-key-pair-name])}
(i18n/label :t/continue)]]}
[quo/page-top
{:container-style style/page-top
:title (i18n/label :t/import-private-key)
:description :text
:description-text (i18n/label :t/enter-private-key)}]
[address-input
{:input-value input-value
:set-input-value set-input-value
:set-flow-state set-flow-state
:error? error?}]
{:input-value private-key
:set-flow-state set-flow-state
:error? error?}]
(when (#{:scanning :active-address :inactive-address} flow-state)
[rn/view {:style style/key-section}
[quo/section-label
{:section (i18n/label :t/private-key-public-address)
:container-style style/section-label}]
;; TODO Get real address
[rn/view {:style (style/public-address flow-state theme)}
[quo/text "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"]]])
(when (seq input-value)
(when (seq public-address)
[rn/view {:style (style/public-address flow-state theme)}
[quo/text public-address]])])
(when (seq private-key)
[activity-indicator flow-state])]]))
Expand Up @@ -26,7 +26,7 @@
{:icon :i/key
:accessibility-label :import-private-key
:label (i18n/label :t/import-private-key)
:on-press (when (ff/enabled? ::wallet.import-private-key)
:on-press (when (or true (ff/enabled? ::wallet.import-private-key))
#(rf/dispatch [:navigate-to :screen/wallet.import-private-key]))}]]])

(defn- parse-accounts
Expand Down
8 changes: 7 additions & 1 deletion src/status_im/navigation/screens.cljs
Expand Up @@ -73,7 +73,9 @@
[status-im.contexts.wallet.add-account.add-address-to-watch.view :as wallet-add-address-to-watch]
[status-im.contexts.wallet.add-account.create-account.edit-derivation-path.view :as
wallet-edit-derivation-path]
[status-im.contexts.wallet.add-account.create-account.import-private-key.view :as
[status-im.contexts.wallet.add-account.create-account.import-private-key.add-key-pair-name.view :as
wallet-add-key-pair-name]
[status-im.contexts.wallet.add-account.create-account.import-private-key.private-key.view :as
wallet-import-private-key]
[status-im.contexts.wallet.add-account.create-account.new-keypair.backup-recovery-phrase.view :as
wallet-backup-recovery-phrase]
Expand Down Expand Up @@ -406,6 +408,10 @@
:options {:insets {:top? true}}
:component wallet-import-private-key/view}

{:name :screen/wallet.add-key-pair-name
:options {:insets {:top? true}}
:component wallet-add-key-pair-name/view}

{:name :screen/wallet.collectible
:component wallet-collectible/view}

Expand Down
20 changes: 20 additions & 0 deletions src/status_im/subs/wallet/add_account/import_private_key.cljs
@@ -0,0 +1,20 @@
(ns status-im.subs.wallet.add-account.import-private-key
(:require [re-frame.core :as rf]))

(rf/reg-sub
:wallet.import-private-key/private-key
:<- [:wallet/ui]
(fn [ui _]
(get-in ui [:import-private-key :private-key])))

(rf/reg-sub
:wallet.import-private-key/public-address
:<- [:wallet/ui]
(fn [ui _]
(get-in ui [:import-private-key :public-address])))

(rf/reg-sub
:wallet.import-private-key/key-pair-name
:<- [:wallet/ui]
(fn [ui _]
(get-in ui [:import-private-key :key-pair-name])))
1 change: 1 addition & 0 deletions src/status_im/subs/wallet/wallet.cljs
Expand Up @@ -4,6 +4,7 @@
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.common.utils.networks :as network-utils]
[status-im.subs.wallet.add-account.address-to-watch]
[status-im.subs.wallet.add-account.import-private-key]
[utils.number]))

(defn- filter-networks
Expand Down
6 changes: 5 additions & 1 deletion translations/en.json
Expand Up @@ -2576,6 +2576,7 @@
"key-name-error-length": "Key name too long",
"key-name-error-emoji": "Emojis are not allowed",
"key-name-error-special-char": "Special characters are not allowed",
"key-name-error-too-short": "Key pair name must be at least {{count}} characters",
"display": "Display",
"testnet-mode-enabled": "Testnet mode enabled",
"online-community-member": "Online",
Expand All @@ -2594,5 +2595,8 @@
"this-account-has-no-activity": "This account has no activity",
"this-address-has-activity": "This address has activity",
"scanning-for-activity": "Scanning for activity...",
"send-community-link": "Send community link"
"send-community-link": "Send community link",
"key-pair-name": "Key pair name",
"key-pair-name-desc": "Name key pair for your own personal reference",
"key-pair-name-placeholder": "Collectibles account, Old vault...."
}

0 comments on commit cfef154

Please sign in to comment.