Skip to content

Commit

Permalink
feature: implement private-key import for missing key-pair
Browse files Browse the repository at this point in the history
  • Loading branch information
seanstrom committed Jun 7, 2024
1 parent 453dee3 commit f7e314d
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
[keypair])
on-import-seed-phrase (rn/use-callback
#(rf/dispatch [:open-modal :screen/settings.import-seed-phrase keypair])
[keypair])
on-import-private-key (rn/use-callback
#(rf/dispatch [:open-modal :screen/settings.import-private-key keypair])
[keypair])]
[:<>
[quo/drawer-top drawer-props]
Expand All @@ -48,7 +51,11 @@
:seed {:icon :i/seed
:accessibility-label :import-seed-phrase
:label (i18n/label :t/import-by-entering-recovery-phrase)
:on-press #(on-import-seed-phrase keypair)}
:on-press on-import-seed-phrase}
:key {:icon :i/key
:accessibility-label :import-private-key
:label (i18n/label :t/import-by-entering-private-key)
:on-press on-import-private-key}
nil))
{:icon :i/edit
:accessibility-label :rename-key-pair
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.import-private-key.style)

(def form-container
{:row-gap 8
:padding-top 8
:padding-horizontal 20})

(def full-layout {:flex 1})

(defn page-container
[insets]
{:position :absolute
:top 0
:bottom (:bottom insets)
:left 0
:right 0})

(def slide-container
{:padding-horizontal 20
:padding-vertical 12
:margin-top :auto
:flex-direction :row})

(def page-top
{:margin-top 2})
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.import-private-key.view
(:require
[clojure.string :as string]
[quo.core :as quo]
[react-native.clipboard :as clipboard]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[status-im.common.standard-authentication.core :as standard-auth]
[status-im.contexts.settings.wallet.keypairs-and-accounts.import-private-key.style :as style]
[status-im.contexts.wallet.common.validation :as validation]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.security.core :as security]))

(defn navigate-back
[]
(rf/dispatch [:navigate-back]))

(defn view
[]
(let [blur? true
insets (safe-area/get-insets)
keypair (rf/sub [:get-screen-params])
customization-color (rf/sub [:profile/customization-color])
[private-key set-private-key] (rn/use-state "")
[flow-state set-flow-state] (rn/use-state nil)
error? (case flow-state
(:incorrect-private-key
:invalid-private-key) true
false)
clear-errors (rn/use-callback
#(set-flow-state nil))
show-invalid (rn/use-callback
#(set-flow-state :invalid-private-key))
show-correct (rn/use-callback
#(set-flow-state :correct-private-key))
show-incorrect (rn/use-callback
#(set-flow-state :incorrect-private-key))
verify-private-key (rn/use-callback
(fn [input]
(rf/dispatch [:wallet/verify-private-key-for-keypair
(:key-uid keypair)
(security/mask-data input)
show-correct
show-incorrect]))
[keypair])
validate-private-key (rn/use-callback
(debounce/debounce
(fn [input]
(if-not (validation/private-key? input)
(show-invalid)
(do (clear-errors)
(verify-private-key input))))
500)
[verify-private-key])
on-change (rn/use-callback
(fn [input]
(set-private-key input)
(validate-private-key input))
[validate-private-key])
on-paste (rn/use-callback
#(clipboard/get-string
(fn [clipboard]
(when-not (empty? clipboard)
(on-change clipboard))))
[on-change])
on-import-error (rn/use-callback
(fn [_error]
(rf/dispatch [:hide-bottom-sheet])
(show-invalid)))
on-import-success (rn/use-callback
(fn []
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:navigate-back]))
[])
on-auth-success (rn/use-callback
(fn [password]
(rf/dispatch [:wallet/import-keypair-by-private-key
{:keypair-key-uid (:key-uid keypair)
:private-key (security/mask-data private-key)
:password password
:on-success on-import-success
:on-error on-import-error}]))
[keypair private-key on-import-success on-import-error])]
[quo/overlay {:type :shell}
[rn/view {:style style/full-layout}
[rn/keyboard-avoiding-view {:style (style/page-container insets)}
[quo/page-nav
{:margin-top (:top insets)
:background :blur
:icon-name :i/close
:on-press navigate-back}]
[quo/page-top
{:blur? true
:container-style style/page-top
:title (i18n/label :t/import-private-key)
:description :context-tag
:context-tag {:type :icon
:icon :i/password
:size 24
:context (:name keypair)}}]
[rn/view {:style style/form-container}
[quo/input
{:accessibility-label :import-private-key
:placeholder (i18n/label :t/enter-private-key-placeholder)
:label (i18n/label :t/private-key)
:type :password
:blur? blur?
:error? error?
:return-key-type :done
:auto-focus true
:on-change-text on-change
:button (when (empty? private-key)
{:on-press on-paste
:text (i18n/label :t/paste)})
:default-value private-key}]
(when flow-state
[quo/info-message
{:type (if (= flow-state :correct-private-key)
:success
:error)
:size :default
:icon :i/info}
(case flow-state
:correct-private-key (i18n/label :t/correct-private-key)
:invalid-private-key (i18n/label :t/invalid-private-key)
:incorrect-private-key (i18n/label :t/incorrect-private-key {:name (:name keypair)})
nil)])]

[rn/view {:style style/slide-container}
[standard-auth/slide-button
{:blur? true
:size :size-48
:customization-color customization-color
:track-text (i18n/label :t/slide-to-import)
:on-auth-success on-auth-success
:auth-button-label (i18n/label :t/import-key-pair)
:auth-button-icon-left :i/key
:disabled? (or error? (string/blank? private-key))
:dependencies [on-auth-success]}]]]]]))
6 changes: 6 additions & 0 deletions src/status_im/navigation/screens.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
[status-im.contexts.profile.settings.view :as settings]
[status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.view :as
encrypted-key-pair-qr]
[status-im.contexts.settings.wallet.keypairs-and-accounts.import-private-key.view :as
import-private-key]
[status-im.contexts.settings.wallet.keypairs-and-accounts.import-seed-phrase.view :as
import-seed-phrase]
[status-im.contexts.settings.wallet.keypairs-and-accounts.rename.view :as keypair-rename]
Expand Down Expand Up @@ -553,6 +555,10 @@
:options options/transparent-screen-options
:component import-seed-phrase/view}

{:name :screen/settings.import-private-key
:options options/transparent-screen-options
:component import-private-key/view}

{:name :screen/settings.network-settings
:options options/transparent-modal-screen-options
:component network-settings/view}
Expand Down

0 comments on commit f7e314d

Please sign in to comment.