feat(wallet): Add a new saved address with ENS (#20384)

This commit adds a feature to add new saved addresses with ENS

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
This commit is contained in:
Mohamed Javid 2024-06-07 19:47:06 +05:30 committed by GitHub
parent cedd4900d5
commit a3e713bbf0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 139 additions and 94 deletions

View File

@ -8,6 +8,7 @@
[status-im.common.floating-button-page.view :as floating-button-page]
[status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.style :as style]
[status-im.contexts.wallet.common.validation :as validation]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@ -18,7 +19,7 @@
(defn- validate-input
[account-addresses saved-addresses user-input]
(cond
(or (nil? user-input) (= user-input ""))
(string/blank? user-input)
nil
(contains? saved-addresses user-input)
@ -89,7 +90,7 @@
(defn- existing-saved-address
[{:keys [address]}]
(let [{:keys [name customization-color chain-short-names ens has-ens?]}
(let [{:keys [name customization-color chain-short-names ens ens?]}
(rf/sub [:wallet/saved-address-by-address
address])]
[rn/view {:style style/existing-saved-address-container}
@ -103,43 +104,65 @@
:active-state? true
:user-props {:name name
:address (str chain-short-names address)
:ens (when has-ens? ens)
:ens (when ens? ens)
:customization-color customization-color
:blur? true}
:container-style style/saved-address-item}]]))
(defn view
[]
(let [profile-color (rf/sub [:profile/customization-color])
accounts-addresses (rf/sub [:wallet/addresses])
saved-addresses-addresses (rf/sub [:wallet/saved-addresses-addresses])
[input-value set-input-value] (rn/use-state nil)
[error set-error] (rn/use-state nil)
error? (some? error)
validate #(validate-input accounts-addresses
saved-addresses-addresses
%)
clear-input (rn/use-callback
(fn []
(set-input-value nil)
(set-error nil)))
on-change-text (rn/use-callback
(fn [new-value]
(let [lowercase-value (string/lower-case new-value)]
(set-error (validate lowercase-value))
(set-input-value lowercase-value))))
paste-into-input (rn/use-callback #(clipboard/get-string
(fn [clipboard-text]
(on-change-text clipboard-text))))
on-press-continue (rn/use-callback
(fn []
(rf/dispatch [:wallet/set-address-to-save
{:address input-value}])
(rf/dispatch
[:navigate-to-within-stack
[:screen/settings.save-address
:screen/settings.add-address-to-save]]))
[input-value])]
(let [profile-color (rf/sub [:profile/customization-color])
accounts-addresses (rf/sub [:wallet/addresses])
saved-addresses-addresses (rf/sub [:wallet/saved-addresses-addresses])
[address-or-ens set-address-or-ens] (rn/use-state "")
[ens-address set-ens-address] (rn/use-state "")
[error set-error] (rn/use-state nil)
error? (some? error)
ens-name? (validation/ens-name? address-or-ens)
address (if ens-name? ens-address address-or-ens)
button-disabled? (or (string/blank? address-or-ens)
(and ens-name? (string/blank? ens-address))
error?)
validate #(validate-input accounts-addresses
saved-addresses-addresses
%)
clear-input (rn/use-callback
(fn []
(set-address-or-ens "")
(set-ens-address "")
(set-error nil)))
on-ens-resolve (rn/use-callback
(fn [resolved-address]
(set-error (validate resolved-address))
(set-ens-address resolved-address)))
on-change-text (rn/use-callback
(fn [new-value]
(let [trimmed-value (string/trim new-value)]
(set-error (validate (string/lower-case trimmed-value)))
(set-address-or-ens trimmed-value)
(set-ens-address "")
(when (validation/ens-name? trimmed-value)
(debounce/debounce-and-dispatch
[:wallet/resolve-ens
{:ens new-value
:on-success on-ens-resolve
:on-error #(set-error :ens-not-registered)}]
300)))))
paste-into-input (rn/use-callback #(clipboard/get-string
(fn [clipboard-text]
(on-change-text clipboard-text))))
on-press-continue (rn/use-callback
(fn []
(rf/dispatch
[:wallet/set-address-to-save
{:address address
:ens address-or-ens
:ens? ens-name?}])
(rf/dispatch
[:navigate-to-within-stack
[:screen/settings.save-address
:screen/settings.add-address-to-save]]))
[address ens-name? address-or-ens])]
(rn/use-unmount #(rf/dispatch [:wallet/clear-address-to-save]))
[quo/overlay {:type :shell}
[floating-button-page/view
@ -153,8 +176,7 @@
:accessibility-label :add-address-to-save-page-nav}]
:footer [quo/button
{:customization-color profile-color
:disabled? (or (string/blank? input-value)
error?)
:disabled? button-disabled?
:on-press on-press-continue}
(i18n/label :t/continue)]}
[quo/page-top
@ -164,7 +186,7 @@
:description :text
:description-text (i18n/label :t/add-address-to-save-description)}]
[address-input
{:input-value input-value
{:input-value address-or-ens
:on-change-text on-change-text
:paste-into-input paste-into-input
:clear-input clear-input}]
@ -172,4 +194,4 @@
[:<>
[error-view {:error error}]
(when (= error :existing-saved-address)
[existing-saved-address {:address input-value}])])]]))
[existing-saved-address {:address address}])])]]))

View File

@ -55,7 +55,7 @@
:address "0x2"
:mixedcase-address "0x2"
:chain-short-names "eth:arb1:oeth:"
:has-ens? false
:ens? false
:network-preferences-names `(:mainnet :arbitrum :optimism)
:name "Bob"
:created-at 1716826714
@ -75,7 +75,7 @@
:mixedcase-address "0x2"
:chain-short-names "eth:arb1:oeth:"
:network-preferences-names `(:mainnet :arbitrum :optimism)
:has-ens? false
:ens? false
:name "Bob"
:created-at 1716826714
:ens ""
@ -86,7 +86,7 @@
:mixedcase-address "0x1"
:chain-short-names "eth:arb1:oeth:"
:network-preferences-names `(:mainnet :arbitrum :optimism)
:has-ens? false
:ens? false
:name "Amy"
:created-at 1716826806
:ens ""

View File

@ -35,7 +35,7 @@
(defn view
[]
(let [{:keys [address]} (rf/sub [:wallet/saved-address])
(let [{:keys [address ens ens?]} (rf/sub [:wallet/saved-address])
[network-prefixes address-without-prefix] (utils/split-prefix-and-address address)
[address-label set-address-label] (rn/use-state "")
[address-color set-address-color] (rn/use-state (rand-nth colors/account-colors))
@ -46,6 +46,13 @@
selected-networks)
[selected-networks])
placeholder (i18n/label :t/address-name)
address-text (rn/use-callback
(fn []
[quo/address-text
{:full-address? true
:address (str chain-short-names address-without-prefix)
:format :long}])
[address-without-prefix chain-short-names])
open-network-preferences (rn/use-callback
(fn []
(rf/dispatch
@ -68,11 +75,29 @@
:on-error
[:wallet/add-saved-address-failed]
:name address-label
:ens ens
:address address-without-prefix
:customization-color address-color
:chain-short-names chain-short-names}]))
[address-without-prefix chain-short-names address-label
address-color])]
address-color])
data-item-props (rn/use-memo
#(cond-> {:status :default
:size :default
:subtitle-type :default
:label :none
:blur? true
:icon-right? true
:right-icon :i/advanced
:card? true
:title (i18n/label :t/address)
:subtitle ens
:custom-subtitle address-text
:on-press open-network-preferences
:container-style style/data-item}
ens?
(dissoc :custom-subtitle))
[ens ens? open-network-preferences address-text])]
[quo/overlay {:type :shell}
[floating-button-page/view
{:footer-container-padding 0
@ -125,22 +150,4 @@
[quo/divider-line
{:blur? true
:container-style style/color-picker-bottom-divider}]
[quo/data-item
{:status :default
:size :default
:subtitle-type :default
:label :none
:blur? true
:icon-right? true
:right-icon :i/advanced
:card? true
:title (i18n/label :t/address)
:custom-subtitle (rn/use-callback
(fn []
[quo/address-text
{:full-address? true
:address (str chain-short-names address-without-prefix)
:format :long}])
[selected-networks address])
:on-press open-network-preferences
:container-style style/data-item}]]]))
[quo/data-item data-item-props]]]))

View File

@ -2,6 +2,7 @@
(:require
[clojure.string :as string]
[quo.core :as quo]
[quo.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.platform :as platform]
[status-im.common.not-implemented :as not-implemented]
@ -52,10 +53,11 @@
open-remove-confirmation-sheet (rn/use-callback
#(rf/dispatch
[:show-bottom-sheet
{:theme :dark
:shell? true
:content (fn []
[remove-address/view opts])}])
{:theme :dark
:shell? true
:blur-background colors/bottom-sheet-background-blur
:content (fn []
[remove-address/view opts])}])
[opts])
open-show-address-qr (rn/use-callback
#(rf/dispatch [:open-modal

View File

@ -1,6 +1,7 @@
(ns status-im.contexts.settings.wallet.saved-addresses.view
(:require
[quo.core :as quo]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
@ -20,27 +21,29 @@
:container-style style/empty-container-style}]))
(defn- saved-address
[{:keys [name address chain-short-names customization-color has-ens? ens network-preferences-names]}]
[{:keys [name address chain-short-names customization-color ens? ens network-preferences-names]}]
(let [full-address (str chain-short-names address)
on-press-saved-address (rn/use-callback
#(rf/dispatch
[:show-bottom-sheet
{:theme :dark
:shell? true
:content (fn []
[address-options/view
{:address address
:chain-short-names chain-short-names
:full-address full-address
:name name
:network-preferences-names network-preferences-names
:customization-color customization-color}])}])
{:theme :dark
:shell? true
:blur-background colors/bottom-sheet-background-blur
:content (fn []
[address-options/view
{:address address
:chain-short-names chain-short-names
:full-address full-address
:name name
:network-preferences-names
network-preferences-names
:customization-color customization-color}])}])
[address chain-short-names full-address name customization-color])]
[quo/saved-address
{:blur? true
:user-props {:name name
:address full-address
:ens (when has-ens? ens)
:ens (when ens? ens)
:customization-color customization-color
:blur? true}
:container-style {:margin-horizontal 8}
@ -88,12 +91,13 @@
:icon :i/add
:container-style style/title-container}]
[rn/section-list
{:key-fn :title
:sticky-section-headers-enabled false
:render-section-header-fn header
:render-section-footer-fn footer
:sections saved-addresses
:render-fn saved-address
:separator [rn/view {:style {:height 4}}]
:content-container-style {:flex-grow 1}
:empty-component [empty-state]}]]))
{:key-fn :title
:shows-vertical-scroll-indicator false
:sticky-section-headers-enabled false
:render-section-header-fn header
:render-section-footer-fn footer
:sections saved-addresses
:render-fn saved-address
:separator [rn/view {:style {:height 4}}]
:content-container-style {:flex-grow 1}
:empty-component [empty-state]}]]))

View File

@ -1,6 +1,6 @@
(ns status-im.contexts.wallet.common.validation
(:require [status-im.constants :as constants]))
(defn ens-name? [s] (re-find constants/regx-ens s))
(defn ens-name? [s] (boolean (re-find constants/regx-ens s)))
(defn eth-address? [s] (re-find constants/regx-multichain-address s))
(defn private-key? [s] (re-find constants/regx-private-key s))

View File

@ -143,7 +143,7 @@
(-> saved-address
(assoc :network-preferences-names
(network-utils/network-preference-prefix->network-names (:chain-short-names saved-address)))
(assoc :has-ens? (not (string/blank? (:ens saved-address))))))
(assoc :ens? (not (string/blank? (:ens saved-address))))))
(defn rpc->saved-address
[saved-address]

View File

@ -526,3 +526,13 @@
:on-error #(log/info "failed to fetch crypto on ramps"
{:error %
:event :wallet/get-crypto-on-ramps})}]]]}))
(rf/reg-event-fx
:wallet/resolve-ens
(fn [{db :db} [{:keys [ens on-success on-error]}]]
(let [chain-id (network-utils/network->chain-id db constants/mainnet-network-name)]
{:fx [[:json-rpc/call
[{:method "ens_addressOf"
:params [chain-id ens]
:on-success on-success
:on-error on-error}]]]})))

View File

@ -9,7 +9,7 @@
:address "0x1"
:mixedcase-address "0x1"
:chain-short-names "eth:arb1:oeth:"
:has-ens? false
:ens? false
:network-preferences-names #{:arbitrum
:optimism
:mainnet}
@ -22,7 +22,7 @@
:address "0x2"
:mixedcase-address "0x2"
:chain-short-names "eth:"
:has-ens? false
:ens? false
:network-preferences-names #{:mainnet}
:name "Bob"
:created-at 1716828825
@ -33,7 +33,7 @@
:address "0x1"
:mixedcase-address "0x1"
:chain-short-names "eth:"
:has-ens? false
:ens? false
:network-preferences-names #{:mainnet}
:name "Alice"
:created-at 1716826745
@ -44,7 +44,7 @@
:address "0x2"
:mixedcase-address "0x2"
:chain-short-names "eth:arb1:oeth:"
:has-ens? false
:ens? false
:network-preferences-names #{:arbitrum
:optimism
:mainnet}
@ -61,7 +61,7 @@
:address "0x1"
:mixedcase-address "0x1"
:chain-short-names "eth:"
:has-ens? false
:ens? false
:network-preferences-names #{:mainnet}
:name "Alice"
:created-at 1716826745
@ -74,7 +74,7 @@
:address "0x2"
:mixedcase-address "0x2"
:chain-short-names "eth:arb1:oeth:"
:has-ens? false
:ens? false
:network-preferences-names #{:arbitrum
:optimism
:mainnet}