feat(wallet): Add new saved address from wallet settings (#20304)

This commit adds flow for adding new saved addresses from wallet settings

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
This commit is contained in:
Mohamed Javid 2024-06-04 23:49:16 +05:30 committed by GitHub
parent 00d288fb94
commit 577dc16188
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 495 additions and 162 deletions

View File

@ -44,14 +44,14 @@
:monospace? - boolean (default: false) - use monospace font
:lowercase? - boolean (default: false) - lowercase text
:neutral? - boolean (default: false) - use neutral colors variant"
[{:keys [full-name customization-color size monospace? lowercase? neutral?]
[{:keys [full-name customization-color size monospace? lowercase? neutral? container-style]
:or {size biggest-possible}}]
(let [theme (quo.theme/use-theme)
circle-size (:size (size properties))
small? (check-if-size-small size)
initials (utils.string/get-initials full-name (if small? 1 2))]
[rn/view
{:style (style/container circle-size customization-color neutral? theme)}
{:style (merge (style/container circle-size customization-color neutral? theme) container-style)}
[text/text
{:accessibility-label :wallet-user-avatar
:size (:font-size (size properties))

View File

@ -0,0 +1,30 @@
(ns status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.style
(:require [quo.foundations.colors :as colors]))
(def header-container
{:padding-bottom 8})
(def input-container
{:flex-direction :row
:margin-horizontal 20})
(def input
{:flex 1
:margin-right 12})
(def scan-button
{:margin-top 26})
(def info-message
{:margin-top 8
:margin-left 20})
(def existing-saved-address-container
{:padding-horizontal 20
:padding-vertical 12})
(def existing-saved-address-text
{:color colors/white-opa-40})
(def saved-address-item
{:margin-top 4})

View File

@ -0,0 +1,174 @@
(ns status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.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.floating-button-page.view :as floating-button-page]
[status-im.common.not-implemented :as not-implemented]
[status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.style :as style]
[status-im.contexts.wallet.common.validation :as validation]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- navigate-back
[]
(rf/dispatch [:navigate-back]))
(defn- validate-input
[account-addresses saved-addresses user-input]
(cond
(or (nil? user-input) (= user-input ""))
nil
(contains? saved-addresses user-input)
:existing-saved-address
(contains? account-addresses user-input)
:own-account
(not
(or (validation/eth-address? user-input)
(validation/ens-name? user-input)))
:invalid-address-or-ens))
(defn- address-input
[{:keys [input-value on-change-text paste-into-input clear-input]}]
(let [empty-input? (string/blank? input-value)]
[rn/view {:style style/input-container}
[quo/input
{:accessibility-label :add-address-to-save
:placeholder (i18n/label :t/address-placeholder)
:container-style style/input
:blur? true
:label (i18n/label :t/address-or-ens-name)
:auto-capitalize :none
:multiline? true
:on-clear clear-input
:return-key-type :done
:clearable? (not empty-input?)
:on-change-text on-change-text
:button (when empty-input?
{:on-press paste-into-input
:text (i18n/label :t/paste)})
:value input-value}]
[quo/button
{:type :outline
:on-press not-implemented/alert
:container-style style/scan-button
:background :blur
:size 40
:icon-only? true}
:i/scan]]))
(defn- error-view
[{:keys [error]}]
(let [error-msg (condp = error
:existing-saved-address
(i18n/label :t/this-address-is-already-saved)
:own-account
(i18n/label :t/you-cannot-add-your-own-account-as-a-saved-address)
:invalid-address-or-ens
(i18n/label :t/this-is-not-an-eth-address-or-ens-name)
:ens-not-registered
(i18n/label :t/this-ens-name-is-not-registered-yet)
nil)]
(when error-msg
[quo/info-message
{:accessibility-label :error-message
:size :default
:icon :i/info
:type :error
:style style/info-message}
error-msg])))
(defn- existing-saved-address
[{:keys [address]}]
(let [{:keys [name customization-color chain-short-names ens has-ens?]}
(rf/sub [:wallet/saved-address-by-address
address])]
[rn/view {:style style/existing-saved-address-container}
[quo/text
{:size :paragraph-1
:weight :medium
:style style/existing-saved-address-text}
(i18n/label :t/existing-saved-address)]
[quo/saved-address
{:blur? true
:active-state? true
:user-props {:name name
:address (str chain-short-names address)
:ens (when has-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])]
(rn/use-unmount #(rf/dispatch [:wallet/clear-address-to-save]))
[quo/overlay {:type :shell}
[floating-button-page/view
{:footer-container-padding 0
:header [quo/page-nav
{:type :no-title
:icon-name :i/close
:behind-overlay? true
:on-press navigate-back
:margin-top (safe-area/get-top)
:accessibility-label :add-address-to-save-page-nav}]
:footer [quo/button
{:customization-color profile-color
:disabled? (or (string/blank? input-value)
error?)
:on-press on-press-continue}
(i18n/label :t/continue)]}
[quo/page-top
{:container-style style/header-container
:blur? true
:title (i18n/label :t/add-address)
:description :text
:description-text (i18n/label :t/add-address-to-save-description)}]
[address-input
{:input-value input-value
:on-change-text on-change-text
:paste-into-input paste-into-input
:clear-input clear-input}]
(when error?
[:<>
[error-view {:error error}]
(when (= error :existing-saved-address)
[existing-saved-address {:address input-value}])])]]))

View File

@ -1,20 +1,12 @@
(ns status-im.contexts.settings.wallet.saved-addresses.events
(:require
[status-im.constants :as constants]
[status-im.contexts.wallet.data-store :as data-store]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(defn save-address
[{:keys [db]}
[{:keys [address name customization-color on-success on-error chain-short-names ens]
:or {on-success (fn [])
on-error (fn [])
name ""
customization-color constants/account-default-customization-color
ens ""
;; the chain short names should be a string like eth: or eth:arb:oeth:
chain-short-names (str constants/mainnet-short-name ":")}}]]
[{:keys [address name customization-color on-success on-error chain-short-names ens]}]]
(let [test-networks-enabled? (boolean (get-in db [:profile/profile :test-networks-enabled?]))
address-to-save {:address address
:name name
@ -93,3 +85,39 @@
:on-error [:wallet/delete-saved-address-failed]}]]]}))
(rf/reg-event-fx :wallet/delete-saved-address delete-saved-address)
(defn add-saved-address-success
[_ [toast-message]]
{:fx [[:dispatch [:wallet/get-saved-addresses]]
[:dispatch [:navigate-back-to :screen/settings.saved-addresses]]
[:dispatch-later
{:ms 100
:dispatch [:toasts/upsert
{:type :positive
:theme :dark
:text toast-message}]}]]})
(rf/reg-event-fx :wallet/add-saved-address-success add-saved-address-success)
(defn add-saved-address-failed
[_ [error]]
{:fx [[:dispatch [:wallet/saved-addresses-rpc-error :add-save-address error]]
[:dispatch
[:toasts/upsert
{:type :negative
:theme :dark
:text error}]]]})
(rf/reg-event-fx :wallet/add-saved-address-failed add-saved-address-failed)
(defn set-address-to-save
[{:keys [db]} [args]]
{:db (assoc-in db [:wallet :ui :saved-address] args)})
(rf/reg-event-fx :wallet/set-address-to-save set-address-to-save)
(defn clear-address-to-save
[{:keys [db]}]
{:db (update-in db [:wallet :ui] dissoc :saved-address)})
(rf/reg-event-fx :wallet/clear-address-to-save clear-address-to-save)

View File

@ -150,3 +150,20 @@
:on-success [:wallet/delete-saved-address-success toast-message]
:on-error [:wallet/delete-saved-address-failed]}]]]]
(is (match? expected-fx result-fx)))))
(deftest add-saved-address-success-test
(testing "add saved address success test - gets saved addresses, dismiss modals and dispatch toast"
(let [cofx {:db {}}
toast-message "Address saved"
effects (events/add-saved-address-success cofx [toast-message])
result-fx (:fx effects)
expected-fx [[:dispatch [:wallet/get-saved-addresses]]
[:dispatch [:navigate-back-to :screen/settings.saved-addresses]]
[:dispatch-later
{:ms 100
:dispatch [:toasts/upsert
{:type :positive
:theme :dark
:text toast-message}]}]]]
(is (= (count result-fx) 3))
(is (match? expected-fx result-fx)))))

View File

@ -0,0 +1,31 @@
(ns status-im.contexts.settings.wallet.saved-addresses.save-address.style)
(def title-input
{:padding-horizontal 20
:padding-top 12
:padding-bottom 16})
(def avatar
{:margin-horizontal 20
:margin-top 12})
(def color-picker-top-divider
{:margin-bottom 12})
(def section-label
{:padding-horizontal 20
:padding-bottom 4})
(def color-picker
{:padding-horizontal 20
:padding-vertical 12})
(def color-picker-bottom-divider
{:margin-top 8
:margin-bottom 12})
(def data-item
{:margin-horizontal 20
:padding-vertical 8
:margin-top 8
:margin-bottom 12})

View File

@ -0,0 +1,113 @@
(ns status-im.contexts.settings.wallet.saved-addresses.save-address.view
(:require
[clojure.string :as string]
[quo.core :as quo]
[quo.foundations.colors :as colors]
[quo.theme]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[status-im.common.floating-button-page.view :as floating-button-page]
[status-im.common.not-implemented :as not-implemented]
[status-im.constants :as constants]
[status-im.contexts.settings.wallet.saved-addresses.save-address.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- navigate-back
[]
(rf/dispatch [:navigate-back]))
(defn- extract-address
[address]
(re-find constants/regx-address-contains address))
(defn view
[]
(let [{:keys [address]} (rf/sub [:wallet/saved-address])
[address-label set-address-label] (rn/use-state "")
[address-color set-address-color] (rn/use-state (rand-nth colors/account-colors))
placeholder (i18n/label :t/address-name)
on-press-save (rn/use-callback
(fn []
(let [address-without-prefix (extract-address address)]
(rf/dispatch [:wallet/save-address
{:on-success
[:wallet/add-saved-address-success
(i18n/label :t/address-saved)]
:on-error
[:wallet/add-saved-address-failed]
:name address-label
:address address-without-prefix
:customization-color address-color}])))
[address address-label address-color])]
[quo/overlay {:type :shell}
[floating-button-page/view
{:footer-container-padding 0
:header [quo/page-nav
{:type :no-title
:background :blur
:icon-name :i/arrow-left
:on-press navigate-back
:margin-top (safe-area/get-top)
:accessibility-label :save-address-page-nav}]
:footer [quo/button
{:accessibility-label :save-address-button
:type :primary
:customization-color address-color
:disabled? (string/blank? address-label)
:on-press on-press-save}
(i18n/label :t/save-address)]
:customization-color address-color
:gradient-cover? true}
[quo/wallet-user-avatar
{:full-name (if (string/blank? address-label)
placeholder
address-label)
:customization-color address-color
:blur? true
:size :size-80
:container-style style/avatar}]
[quo/title-input
{:blur? true
:auto-focus true
:max-length 24
:size :heading-1
:placeholder placeholder
:default-value address-label
:on-change-text set-address-label
:customization-color address-color
:container-style style/title-input}]
[quo/divider-line
{:blur? true
:container-style style/color-picker-top-divider}]
[quo/section-label
{:section (i18n/label :t/colour)
:blur? true
:container-style style/section-label}]
[quo/color-picker
{:default-selected address-color
:on-change set-address-color
:blur? true
:container-style style/color-picker}]
[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 address
:format :long}])
[address])
:on-press not-implemented/alert
:container-style style/data-item}]]]))

View File

@ -36,7 +36,8 @@
:customization-color customization-color}])}])
[address chain-short-names full-address name customization-color])]
[quo/saved-address
{:user-props {:name name
{:blur? true
:user-props {:name name
:address full-address
:ens (when has-ens? ens)
:customization-color customization-color
@ -59,6 +60,11 @@
[]
(rf/dispatch [:navigate-back]))
(defn- add-address-to-save
[]
(rf/dispatch [:navigate-to-within-stack
[:screen/settings.add-address-to-save :screen/settings.saved-addresses]]))
(defn view
[]
(let [inset-top (safe-area/get-top)
@ -77,6 +83,7 @@
{:title (i18n/label :t/saved-addresses)
:accessibility-label :saved-addresses-header
:right :action
:on-press add-address-to-save
:customization-color customization-color
:icon :i/add}]]
[rn/section-list

View File

@ -150,7 +150,7 @@
(i18n/label :t/continue)]}
[quo/page-top
{:container-style style/header-container
:title (i18n/label :t/add-address)
:title (i18n/label :t/add-address-to-watch)
:description :text
:description-text (i18n/label :t/enter-eth)}]
[:f> address-input

View File

@ -23,8 +23,8 @@
:on-press #(rf/dispatch [:navigate-to :screen/wallet.create-account])}
{:icon :i/reveal
:accessibility-label :add-a-contact
:label (i18n/label :t/add-address)
:sub-label (i18n/label :t/add-address-description)
:label (i18n/label :t/add-address-to-watch)
:sub-label (i18n/label :t/add-address-to-watch-description)
:on-press #(rf/dispatch [:navigate-to :screen/wallet.add-address-to-watch])
:add-divider? true}]]])

View File

@ -1,39 +0,0 @@
(ns status-im.contexts.wallet.save-address.style)
(def title-input-container
{:padding-horizontal 20
:padding-top 12
:padding-bottom 16})
(def account-avatar-container
{:padding-horizontal 20
:padding-top 12})
(def color-picker-top-divider
{:margin-bottom 12})
(def color-picker-container
{:padding-vertical 12})
(def section-container
{:padding-horizontal 20
:padding-bottom 4})
(def color-picker
{:padding-horizontal 20
:padding-top 12})
(def color-picker-bottom-divider
{:padding-top 8
:padding-bottom 12})
(def save-address-button
{:padding-horizontal 20})
(def data-item
{:margin-horizontal 20
:padding-vertical 8})
(def address-container
{:padding-top 8
:padding-bottom 12})

View File

@ -1,90 +0,0 @@
(ns status-im.contexts.wallet.save-address.view
(:require
[clojure.string :as string]
[quo.core :as quo]
[quo.theme]
[react-native.core :as rn]
[status-im.common.floating-button-page.view :as floating-button-page]
[status-im.contexts.wallet.save-address.style :as style]
[status-im.contexts.wallet.sheets.network-preferences.view
:as network-preferences]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- address-view
[]
(let [network-details (rf/sub [:wallet/network-preference-details])
address (rf/sub [:wallet/wallet-send-to-address])]
[rn/view {:style style/address-container}
[quo/data-item
{:status :default
:size :default
:subtitle-type :default
:label :none
:blur? false
:icon-right? true
:right-icon :i/advanced
:card? true
:title (i18n/label :t/address)
:custom-subtitle (rn/use-callback
(fn [] [quo/address-text
{:networks network-details
:address address
:format :long}]))
:on-press (rn/use-callback
(fn []
(rf/dispatch [:show-bottom-sheet
{:content
(fn []
[network-preferences/view
{:on-save (fn [])}])}])))
:container-style style/data-item}]]))
(defn view
[]
(let [[address-label set-address-label] (rn/use-state "")
[address-color set-address-color] (rn/use-state :blue)
placeholder (i18n/label :t/address-name)]
[floating-button-page/view
{:footer-container-padding 0
:header [quo/page-nav
{:type :no-title
:background :blur
:icon-name :i/close
:on-press (rn/use-callback #(rf/dispatch [:navigate-back]))
:accessibility-label :save-address-top-bar}]
:footer [quo/button
{:accessibility-label :save-address-button
:type :primary
:container-style style/save-address-button}
(i18n/label :t/save-address)]
:customization-color address-color
:gradient-cover? true}
[rn/view
{:style style/account-avatar-container}
[quo/user-avatar
{:full-name (if (string/blank? address-label)
placeholder
address-label)
:customization-color address-color
:size :big}]]
[quo/title-input
{:blur? true
:auto-focus true
:max-length 24
:size :heading-1
:placeholder placeholder
:default-value address-label
:on-change-text set-address-label
:customization-color address-color
:container-style style/title-input-container}]
[quo/divider-line {:container-style style/color-picker-top-divider}]
[quo/section-label
{:section (i18n/label :t/colour)
:container-style style/section-container}]
[quo/color-picker
{:default-selected address-color
:on-change set-address-color
:container-style style/color-picker}]
[quo/divider-line {:container-style style/color-picker-bottom-divider}]
[address-view]]))

View File

@ -36,7 +36,9 @@
:icon-left :i/contact-book
:accessibility-label :save-address
:on-press (rn/use-callback
#(rf/dispatch [:open-modal :screen/wallet.save-address]))}
#(rf/dispatch [:open-modal
:screen/settings.save-address
{:address send-to-address}]))}
:button-one-label (i18n/label :t/done)
:button-one-props {:customization-color color
:type :primary

View File

@ -63,6 +63,9 @@
[status-im.contexts.settings.wallet.keypairs-and-accounts.scan-qr.view :as scan-keypair-qr]
[status-im.contexts.settings.wallet.keypairs-and-accounts.view :as keypairs-and-accounts]
[status-im.contexts.settings.wallet.network-settings.view :as network-settings]
[status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.view :as
wallet-add-address-to-save]
[status-im.contexts.settings.wallet.saved-addresses.save-address.view :as wallet-save-address]
[status-im.contexts.settings.wallet.saved-addresses.view :as saved-addresses-settings]
[status-im.contexts.settings.wallet.wallet-options.view :as wallet-options]
[status-im.contexts.shell.activity-center.view :as activity-center]
@ -98,7 +101,6 @@
[status-im.contexts.wallet.collectible.view :as wallet-collectible]
[status-im.contexts.wallet.common.scan-account.view :as wallet-scan-address]
[status-im.contexts.wallet.connected-dapps.view :as wallet-connected-dapps]
[status-im.contexts.wallet.save-address.view :as wallet-save-address]
[status-im.contexts.wallet.send.from.view :as wallet-select-from]
[status-im.contexts.wallet.send.select-address.view :as wallet-select-address]
[status-im.contexts.wallet.send.select-asset.view :as wallet-select-asset]
@ -450,10 +452,6 @@
:options options/transparent-screen-options
:component wallet-share-address/view}
{:name :screen/wallet.save-address
:options {:sheet? true}
:component wallet-save-address/view}
{:name :screen/wallet.send-input-amount
:options {:modalPresentationStyle :overCurrentContext
:insets {:top? true
@ -540,6 +538,14 @@
:options options/transparent-modal-screen-options
:component network-settings/view}
{:name :screen/settings.save-address
:options options/transparent-modal-screen-options
:component wallet-save-address/view}
{:name :screen/settings.add-address-to-save
:options options/transparent-modal-screen-options
:component wallet-add-address-to-save/view}
{:name :screen/settings-messages
:options options/transparent-modal-screen-options
:component settings.messages/view}

View File

@ -3,32 +3,49 @@
[clojure.string :as string]
[re-frame.core :as rf]))
(rf/reg-sub
:wallet/saved-address
:<- [:wallet/ui]
:-> :saved-address)
(rf/reg-sub
:wallet/saved-addresses
:<- [:wallet]
:-> :saved-addresses)
(rf/reg-sub
:wallet/address-saved?
:<- [:wallet]
(fn [wallet [address]]
(some #(= address (:address %))
(:saved-addresses wallet))))
(rf/reg-sub
:wallet/saved-addresses-by-network-mode
:<- [:wallet/saved-addresses]
:<- [:profile/test-networks-enabled?]
(fn [[saved-addresses test-networks-enabled?]]
(vals (get saved-addresses (if test-networks-enabled? :test :prod)))))
(get saved-addresses (if test-networks-enabled? :test :prod))))
(rf/reg-sub
:wallet/address-saved?
:<- [:wallet/saved-addresses-by-network-mode]
(fn [saved-addresses [_ address]]
(contains? saved-addresses address)))
(rf/reg-sub
:wallet/grouped-saved-addresses
:<- [:wallet/saved-addresses-by-network-mode]
(fn [saved-addresses]
(->> saved-addresses
vals
(sort-by :name)
(group-by #(string/upper-case (first (:name %))))
(map (fn [[k v]]
{:title k
:data v})))))
(rf/reg-sub
:wallet/saved-addresses-addresses
:<- [:wallet/saved-addresses-by-network-mode]
(fn [saved-addresses]
(-> saved-addresses keys set)))
(rf/reg-sub
:wallet/saved-address-by-address
:<- [:wallet/saved-addresses-by-network-mode]
(fn [saved-addresses [_ address]]
(get saved-addresses address)))

View File

@ -91,7 +91,17 @@
#(-> %
(assoc-in [:wallet :saved-addresses] saved-addresses-db)
(assoc-in [:profile/profile :test-networks-enabled?] true)))
(is (= (vals (:test saved-addresses-db)) (rf/sub [sub-name])))))
(is (= (:test saved-addresses-db) (rf/sub [sub-name])))))
(h/deftest-sub :wallet/address-saved?
[sub-name]
(testing "returns boolean if given address is saved"
(swap! rf-db/app-db
#(-> %
(assoc-in [:wallet :saved-addresses] saved-addresses-db)
(assoc-in [:profile/profile :test-networks-enabled?] false)))
(is (true? (rf/sub [sub-name "0x1"])))
(is (false? (rf/sub [sub-name "0x3"])))))
(h/deftest-sub :wallet/grouped-saved-addresses
[sub-name]
@ -101,3 +111,22 @@
(assoc-in [:wallet :saved-addresses] saved-addresses-db)
(assoc-in [:profile/profile :test-networks-enabled?] false)))
(is (= grouped-saved-addresses-data (rf/sub [sub-name])))))
(h/deftest-sub :wallet/saved-addresses-addresses
[sub-name]
(testing "returns saved addresses addresses set"
(swap! rf-db/app-db
#(-> %
(assoc-in [:wallet :saved-addresses] saved-addresses-db)
(assoc-in [:profile/profile :test-networks-enabled?] true)))
(is (= (-> saved-addresses-db :test keys set) (rf/sub [sub-name])))))
(h/deftest-sub :wallet/saved-address-by-address
[sub-name]
(testing "returns a saved address"
(let [address "0x1"]
(swap! rf-db/app-db
#(-> %
(assoc-in [:wallet :saved-addresses] saved-addresses-db)
(assoc-in [:profile/profile :test-networks-enabled?] false)))
(is (= (get-in saved-addresses-db [:prod address]) (rf/sub [sub-name address]))))))

View File

@ -2423,8 +2423,8 @@
"days": "Days",
"add-account": "Add account",
"add-account-description": "Create new or import existing account",
"add-address": "Add address to watch",
"add-address-description": "Watch a public address or ENS name",
"add-address-to-watch": "Add address to watch",
"add-address-to-watch-description": "Watch a public address or ENS name",
"colour": "Colour",
"origin": "Origin",
"slide-to-sign": "Slide to sign",
@ -2673,5 +2673,13 @@
"saved-address-removed": "Saved address removed",
"remove-address": "Remove address",
"remove-saved-address": "Remove saved address",
"remove-saved-address-description": "Transaction history relating to this address will no longer be labelled {{name}}."
"remove-saved-address-description": "Transaction history relating to this address will no longer be labelled {{name}}.",
"add-address": "Add address",
"add-address-to-save-description": "Paste, scan or type ETH address or ENS name",
"existing-saved-address": "Existing saved address",
"this-is-not-an-eth-address-or-ens-name": "This is not an Ethereum address or ENS name",
"you-cannot-add-your-own-account-as-a-saved-address": "You cannot add your own account as a saved address",
"this-address-is-already-saved": "This address is already saved",
"this-ens-name-is-not-registered-yet": "This ENS name is not registered yet",
"address-saved": "Address saved"
}