Wallet: ENS (#18000)

* wallet: ens
This commit is contained in:
Omar Basem 2023-12-07 08:00:56 +04:00 committed by GitHub
parent aa89ebdb93
commit f692ae2222
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 84 additions and 51 deletions

View File

@ -61,14 +61,10 @@
value (reagent/atom "") value (reagent/atom "")
focused? (atom false)] focused? (atom false)]
(fn [{:keys [scanned-value theme blur? on-change-text on-blur on-focus on-clear on-scan on-detect-ens (fn [{:keys [scanned-value theme blur? on-change-text on-blur on-focus on-clear on-scan on-detect-ens
on-detect-address on-detect-address address-regex valid-ens-or-address?]}]
ens-regex address-regex
valid-ens-or-address?]}]
(let [on-change (fn [text] (let [on-change (fn [text]
(when (not= @value text) (when (not= @value text)
(let [ens? (when ens-regex (let [address? (when address-regex
(boolean (re-matches ens-regex text)))
address? (when address-regex
(boolean (re-matches address-regex text)))] (boolean (re-matches address-regex text)))]
(if (> (count text) 0) (if (> (count text) 0)
(reset! status :typing) (reset! status :typing)
@ -76,9 +72,9 @@
(reset! value text) (reset! value text)
(when on-change-text (when on-change-text
(on-change-text text)) (on-change-text text))
(when (and ens? on-detect-ens) (when (and on-detect-ens (> (count text) 0))
(reset! status :loading) (reset! status :loading)
(on-detect-ens text)) (on-detect-ens text #(reset! status :typing)))
(when (and address? on-detect-address) (when (and address? on-detect-address)
(reset! status :loading) (reset! status :loading)
(on-detect-address text))))) (on-detect-address text)))))

View File

@ -390,3 +390,6 @@
(def ^:const account-default-customization-color :blue) (def ^:const account-default-customization-color :blue)
(def ^:const wallet-account-name-max-length 20) (def ^:const wallet-account-name-max-length 20)
(def ^:const status-address-domain ".stateofus.eth")
(def ^:const eth-address-domain ".eth")

View File

@ -7,9 +7,11 @@
[quo.foundations.colors :as colors] [quo.foundations.colors :as colors]
[react-native.background-timer :as background-timer] [react-native.background-timer :as background-timer]
[status-im2.common.data-store.wallet :as data-store] [status-im2.common.data-store.wallet :as data-store]
[status-im2.contexts.wallet.item-types :as item-types]
[status-im2.contexts.wallet.temp :as temp] [status-im2.contexts.wallet.temp :as temp]
[taoensso.timbre :as log] [taoensso.timbre :as log]
[utils.ethereum.chain :as chain] [utils.ethereum.chain :as chain]
[utils.ethereum.eip.eip55 :as eip55]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.number] [utils.number]
[utils.re-frame :as rf] [utils.re-frame :as rf]
@ -327,6 +329,45 @@
{:event :wallet/get-collectible-details-done {:event :wallet/get-collectible-details-done
:response response}))))) :response response})))))
(rf/reg-event-fx :wallet/find-ens
(fn [{:keys [db]} [input contacts chain-id cb]]
(let [result (if (empty? input)
[]
(filter #(string/starts-with? (or (:ens-name %) "") input) contacts))]
(if (and input (empty? result))
(rf/dispatch [:wallet/search-ens input chain-id cb ".stateofus.eth"])
{:db (assoc db
:wallet/local-suggestions
(map #(assoc % :type item-types/saved-address) result)
:wallet/valid-ens-or-address? (not-empty result))}))))
(rf/reg-event-fx :wallet/search-ens
(fn [_ [input chain-id cb domain]]
(let [ens (if (string/includes? input ".") input (str input domain))]
{:fx [[:json-rpc/call
[{:method "ens_addressOf"
:params [chain-id ens]
:on-success #(rf/dispatch [:wallet/set-ens-address % ens])
:on-error (fn []
(if (= domain ".stateofus.eth")
(rf/dispatch [:wallet/search-ens input chain-id cb ".eth"])
(do
(rf/dispatch [:wallet/set-ens-address nil ens])
(cb))))}]]]})))
(rf/reg-event-fx :wallet/set-ens-address
(fn [{:keys [db]} [result ens]]
{:db (assoc db
:wallet/local-suggestions (if result
[{:type item-types/address
:ens ens
:address (eip55/address->checksum result)
:networks [:ethereum :optimism]}]
[])
:wallet/valid-ens-or-address? (boolean result))}))
(rf/reg-event-fx :wallet/fetch-address-suggestions (rf/reg-event-fx :wallet/fetch-address-suggestions
(fn [{:keys [db]} [address]] (fn [{:keys [db]} [address]]
{:db (assoc db {:db (assoc db

View File

@ -1,9 +1,7 @@
(ns status-im2.contexts.wallet.send.select-address.style) (ns status-im2.contexts.wallet.send.select-address.style)
(defn container (def container
[margin-top] {:flex 1})
{:flex 1
:margin-top margin-top})
(def title-container (def title-container
{:margin-horizontal 20 {:margin-horizontal 20

View File

@ -4,7 +4,6 @@
[quo.foundations.colors :as colors] [quo.foundations.colors :as colors]
[quo.theme :as quo.theme] [quo.theme :as quo.theme]
[react-native.core :as rn] [react-native.core :as rn]
[react-native.safe-area :as safe-area]
[reagent.core :as reagent] [reagent.core :as reagent]
[status-im2.constants :as constants] [status-im2.constants :as constants]
[status-im2.contexts.wallet.common.account-switcher.view :as account-switcher] [status-im2.contexts.wallet.common.account-switcher.view :as account-switcher]
@ -49,12 +48,11 @@
(fn [] (fn []
(let [scanned-address (rf/sub [:wallet/scanned-address]) (let [scanned-address (rf/sub [:wallet/scanned-address])
send-address (rf/sub [:wallet/send-address]) send-address (rf/sub [:wallet/send-address])
valid-ens-or-address? (rf/sub [:wallet/valid-ens-or-address?])] valid-ens-or-address? (rf/sub [:wallet/valid-ens-or-address?])
chain-id (rf/sub [:chain-id])
contacts (rf/sub [:contacts/active])]
[quo/address-input [quo/address-input
{:on-focus (fn [] {:on-focus #(reset! input-focused? true)
(when (empty? @input-value)
(rf/dispatch [:wallet/clean-local-suggestions]))
(reset! input-focused? true))
:on-blur #(reset! input-focused? false) :on-blur #(reset! input-focused? false)
:on-scan (fn [] :on-scan (fn []
(rn/dismiss-keyboard!) (rn/dismiss-keyboard!)
@ -62,22 +60,19 @@
:ens-regex constants/regx-ens :ens-regex constants/regx-ens
:address-regex constants/regx-address :address-regex constants/regx-address
:scanned-value (or send-address scanned-address) :scanned-value (or send-address scanned-address)
:on-detect-ens #(debounce/debounce-and-dispatch
[:wallet/validate-ens %]
300)
:on-detect-address #(debounce/debounce-and-dispatch :on-detect-address #(debounce/debounce-and-dispatch
[:wallet/validate-address %] [:wallet/validate-address %]
300) 300)
:on-detect-ens (fn [text cb]
(debounce/debounce-and-dispatch
[:wallet/find-ens text contacts chain-id cb]
300))
:on-change-text (fn [text] :on-change-text (fn [text]
(let [starts-like-eth-address (re-matches (when-not (= scanned-address text)
constants/regx-full-or-partial-address (rf/dispatch [:wallet/clean-scanned-address]))
text)] (when (empty? text)
(when-not (= scanned-address text) (rf/dispatch [:wallet/clean-local-suggestions]))
(rf/dispatch [:wallet/clean-scanned-address])) (reset! input-value text))
(if starts-like-eth-address
(rf/dispatch [:wallet/fetch-address-suggestions text])
(rf/dispatch [:wallet/clean-local-suggestions]))
(reset! input-value text)))
:valid-ens-or-address? valid-ens-or-address?}]))) :valid-ens-or-address? valid-ens-or-address?}])))
(defn- ens-linked-address (defn- ens-linked-address
@ -90,8 +85,8 @@
^{:key (str network)} ^{:key (str network)}
[quo/text [quo/text
{:size :paragraph-2 {:size :paragraph-2
:style {:color (colors/resolve-color (:network-name network) theme)}} :style {:color (colors/resolve-color network theme)}}
(str (:short-name network) ":")]) (str (subs (name network) 0 3) ":")])
networks) networks)
[quo/text [quo/text
{:size :paragraph-2 {:size :paragraph-2
@ -101,14 +96,20 @@
(defn- suggestion-component (defn- suggestion-component
[] []
(fn [{:keys [type ens address accounts] :as local-suggestion} _ _ _] (fn [{:keys [type ens address accounts primary-name public-key ens-name color] :as local-suggestion} _
_ _]
(let [props {:on-press (fn [] (let [props {:on-press (fn []
(let [address (if accounts (:address (first accounts)) address)] (let [address (if accounts (:address (first accounts)) address)]
(when-not ens (rf/dispatch [:wallet/select-send-address address])))) (when-not ens (rf/dispatch [:wallet/select-send-address address]))))
:active-state? false}] :active-state? false}]
(cond (cond
(= type types/saved-address) (= type types/saved-address)
[quo/saved-address (merge props {:user-props local-suggestion})] [quo/saved-address
(merge props
{:user-props {:name primary-name
:address public-key
:ens ens-name
:customization-color color}})]
(= type types/saved-contact-address) (= type types/saved-contact-address)
[quo/saved-contact-address (merge props local-suggestion)] [quo/saved-contact-address (merge props local-suggestion)]
(and (not ens) (= type types/address)) (and (not ens) (= type types/address))
@ -132,8 +133,7 @@
(defn- f-view-internal (defn- f-view-internal
[] []
(let [margin-top (safe-area/get-top) (let [selected-tab (reagent/atom (:id (first tabs-data)))
selected-tab (reagent/atom (:id (first tabs-data)))
on-close (fn [] on-close (fn []
(rf/dispatch [:wallet/clean-scanned-address]) (rf/dispatch [:wallet/clean-scanned-address])
(rf/dispatch [:wallet/clean-local-suggestions]) (rf/dispatch [:wallet/clean-local-suggestions])
@ -143,8 +143,12 @@
input-focused? (reagent/atom false)] input-focused? (reagent/atom false)]
(fn [] (fn []
(let [valid-ens-or-address? (boolean (rf/sub [:wallet/valid-ens-or-address?]))] (let [valid-ens-or-address? (boolean (rf/sub [:wallet/valid-ens-or-address?]))]
(rn/use-effect (fn []
(fn []
(rf/dispatch [:wallet/clean-scanned-address])
(rf/dispatch [:wallet/clean-local-suggestions]))))
[rn/scroll-view [rn/scroll-view
{:content-container-style (style/container margin-top) {:content-container-style style/container
:keyboard-should-persist-taps :handled :keyboard-should-persist-taps :handled
:scroll-enabled false} :scroll-enabled false}
[account-switcher/view {:on-press on-close}] [account-switcher/view {:on-press on-close}]
@ -168,10 +172,7 @@
:type :primary :type :primary
:disabled? (not valid-ens-or-address?) :disabled? (not valid-ens-or-address?)
:container-style style/button :container-style style/button
:on-press (fn [] :on-press #(js/alert "Not implemented yet")}
(rf/dispatch [:wallet/select-send-address @input-value])
(rf/dispatch [:navigate-to-within-stack
[:wallet-select-asset :wallet-select-address]]))}
(i18n/label :t/continue)])] (i18n/label :t/continue)])]
[:<> [:<>
[quo/tabs [quo/tabs

View File

@ -7,6 +7,7 @@
[react-native.core :as rn] [react-native.core :as rn]
[react-native.safe-area :as safe-area] [react-native.safe-area :as safe-area]
[reagent.core :as reagent] [reagent.core :as reagent]
[status-im2.contexts.wallet.common.account-switcher.view :as account-switcher]
[status-im2.contexts.wallet.send.select-asset.style :as style] [status-im2.contexts.wallet.send.select-asset.style :as style]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.re-frame :as rf])) [utils.re-frame :as rf]))
@ -76,15 +77,7 @@
{:content-container-style {:flex 1} {:content-container-style {:flex 1}
:keyboard-should-persist-taps :handled :keyboard-should-persist-taps :handled
:scroll-enabled false} :scroll-enabled false}
[quo/page-nav [account-switcher/view {:on-press on-close}]
{:icon-name :i/arrow-left
:on-press on-close
:accessibility-label :top-bar
:right-side :account-switcher
:account-switcher {:customization-color :purple
:on-press #(js/alert "Not implemented yet")
:state :default
:emoji "🍑"}}]
[quo/text-combinations [quo/text-combinations
{:title (i18n/label :t/select-asset) {:title (i18n/label :t/select-asset)
:container-style style/title-container :container-style style/title-container

View File

@ -306,7 +306,8 @@
:component wallet-send-input-amount/view} :component wallet-send-input-amount/view}
{:name :wallet-select-address {:name :wallet-select-address
:options {:modalPresentationStyle :overCurrentContext} :options {:modalPresentationStyle :overCurrentContext
:insets {:top? true}}
:component wallet-select-address/view} :component wallet-select-address/view}
{:name :wallet-select-asset {:name :wallet-select-asset