feat(wallet): sync saved addresses (#20546)
This commit adds syncing saved addresses across paired devices whenever a new saved address is added or an existing one is edited or removed. Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
This commit is contained in:
parent
ef9cc55501
commit
0581fc2f9d
|
@ -21,6 +21,7 @@
|
|||
[status-im.contexts.chat.messenger.messages.pin.events :as messages.pin]
|
||||
[status-im.contexts.communities.events :as communities]
|
||||
[status-im.contexts.shell.activity-center.events :as activity-center]
|
||||
[status-im.contexts.wallet.data-store :as wallet.data-store]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
|
@ -56,6 +57,7 @@
|
|||
^js accounts (.-accounts response-js)
|
||||
^js ens-username-details-js (.-ensUsernameDetails response-js)
|
||||
^js customization-color-js (.-customizationColor response-js)
|
||||
^js saved-addresses-js (.-savedAddresses response-js)
|
||||
sync-handler (when-not process-async process-response)]
|
||||
(cond
|
||||
|
||||
|
@ -199,6 +201,13 @@
|
|||
(models.visibility-status-updates/sync-visibility-status-update
|
||||
current-visibility-status-clj)))
|
||||
|
||||
(seq saved-addresses-js)
|
||||
(let [saved-addresses (-> saved-addresses-js types/js->clj wallet.data-store/rpc->saved-addresses)]
|
||||
(js-delete response-js "savedAddresses")
|
||||
(rf/merge cofx
|
||||
{:fx [[:dispatch [:wallet/reconcile-saved-addresses saved-addresses]]]}
|
||||
(process-next response-js sync-handler)))
|
||||
|
||||
(seq ens-username-details-js)
|
||||
(let [ens-username-details-clj (types/js->clj ens-username-details-js)]
|
||||
(js-delete response-js "ensUsernameDetails")
|
||||
|
|
|
@ -23,15 +23,29 @@
|
|||
|
||||
(rf/reg-event-fx :wallet/save-address save-address)
|
||||
|
||||
(defn- update-saved-addresses
|
||||
[saved-addresses-db new-saved-addresses]
|
||||
(reduce
|
||||
(fn [acc {:keys [address removed? test?] :as saved-address}]
|
||||
(let [db-key (if test? :test :prod)]
|
||||
(if removed?
|
||||
(update acc db-key dissoc address)
|
||||
(assoc-in acc [db-key address] saved-address))))
|
||||
(or saved-addresses-db
|
||||
{:test {}
|
||||
:prod {}})
|
||||
new-saved-addresses))
|
||||
|
||||
(defn reconcile-saved-addresses
|
||||
[{:keys [db]} [saved-addresses]]
|
||||
{:db (update-in db [:wallet :saved-addresses] update-saved-addresses saved-addresses)})
|
||||
|
||||
(rf/reg-event-fx :wallet/reconcile-saved-addresses reconcile-saved-addresses)
|
||||
|
||||
(defn get-saved-addresses-success
|
||||
[{:keys [db]} [raw-saved-addresses]]
|
||||
(let [saved-addresses (reduce
|
||||
(fn [result {:keys [address test?] :as saved-address}]
|
||||
(assoc-in result [(if test? :test :prod) address] saved-address))
|
||||
{:test {}
|
||||
:prod {}}
|
||||
(data-store/rpc->saved-addresses raw-saved-addresses))]
|
||||
{:db (assoc-in db [:wallet :saved-addresses] saved-addresses)}))
|
||||
[_ [raw-saved-addresses]]
|
||||
(let [saved-addresses (data-store/rpc->saved-addresses raw-saved-addresses)]
|
||||
{:fx [[:dispatch [:wallet/reconcile-saved-addresses saved-addresses]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/get-saved-addresses-success get-saved-addresses-success)
|
||||
|
||||
|
@ -52,15 +66,17 @@
|
|||
(rf/reg-event-fx :wallet/get-saved-addresses get-saved-addresses)
|
||||
|
||||
(defn delete-saved-address-success
|
||||
[_ [toast-message]]
|
||||
{:fx [[:dispatch [:wallet/get-saved-addresses]]
|
||||
[:dispatch [:hide-bottom-sheet]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text toast-message}]}]]})
|
||||
[{:keys [db]} [{:keys [address test-networks-enabled? toast-message]}]]
|
||||
(let [db-key (if test-networks-enabled? :test :prod)
|
||||
saved-address (get-in db [:wallet :saved-addresses db-key address])]
|
||||
{:fx [[:dispatch [:wallet/reconcile-saved-addresses [(assoc saved-address :removed? true)]]]
|
||||
[:dispatch [:hide-bottom-sheet]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text toast-message}]}]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/delete-saved-address-success delete-saved-address-success)
|
||||
|
||||
|
@ -82,7 +98,10 @@
|
|||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_deleteSavedAddress"
|
||||
:params [address test-networks-enabled?]
|
||||
:on-success [:wallet/delete-saved-address-success toast-message]
|
||||
:on-success [:wallet/delete-saved-address-success
|
||||
{:address address
|
||||
:test-networks-enabled? test-networks-enabled?
|
||||
:toast-message toast-message}]
|
||||
:on-error [:wallet/delete-saved-address-failed]}]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/delete-saved-address delete-saved-address)
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
(:require
|
||||
[cljs.test :refer-macros [deftest is testing]]
|
||||
matcher-combinators.test
|
||||
[status-im.contexts.settings.wallet.saved-addresses.events :as events]))
|
||||
[status-im.contexts.settings.wallet.saved-addresses.events :as events]
|
||||
[status-im.contexts.wallet.data-store :as data-store]))
|
||||
|
||||
(deftest get-saved-addresses-test
|
||||
(testing "get saved addresses - dispatches RPC call"
|
||||
|
@ -15,7 +16,7 @@
|
|||
:on-error [:wallet/saved-addresses-rpc-error :get-saved-addresses]}]]]]
|
||||
(is (match? expected-fx result-fx)))))
|
||||
|
||||
(def saved-address-1
|
||||
(def saved-address-rpc-1
|
||||
{:isTest false
|
||||
:address "0x1"
|
||||
:mixedcaseAddress "0x1"
|
||||
|
@ -26,21 +27,45 @@
|
|||
:colorId "purple"
|
||||
:removed false})
|
||||
|
||||
(def saved-address-1
|
||||
{:test? true
|
||||
:address "0x1"
|
||||
:mixedcase-address "0x1"
|
||||
:chain-short-names "eth:oeth:"
|
||||
:network-preferences-names `(:mainnet :optimism)
|
||||
:name "Bob"
|
||||
:created-at 1716826714
|
||||
:ens ""
|
||||
:ens? false
|
||||
:customization-color :blue
|
||||
:removed? false})
|
||||
|
||||
(def saved-address-2
|
||||
{:isTest true
|
||||
:address "0x2"
|
||||
:mixedcaseAddress "0x2"
|
||||
:chainShortNames "eth:arb1:oeth:"
|
||||
:name "Bob"
|
||||
:createdAt 1716826714
|
||||
:ens ""
|
||||
:colorId "blue"
|
||||
:removed false})
|
||||
{:test? false
|
||||
:address "0x2"
|
||||
:mixedcase-address "0x2"
|
||||
:chain-short-names "eth:arb1:oeth:"
|
||||
:network-preferences-names `(:mainnet :arbitrum :optimism)
|
||||
:name "Alicia Keys"
|
||||
:created-at 1716826806
|
||||
:ens "alicia.eth"
|
||||
:ens? true
|
||||
:customization-color :purple
|
||||
:removed? false})
|
||||
|
||||
(deftest get-saved-addresses-success-test
|
||||
(let [cofx {:db {}}
|
||||
raw-saved-addresses [saved-address-rpc-1]
|
||||
effects (events/get-saved-addresses-success cofx [raw-saved-addresses])
|
||||
saved-addresses (data-store/rpc->saved-addresses raw-saved-addresses)
|
||||
result-fx (:fx effects)
|
||||
expected-fx [[:dispatch [:wallet/reconcile-saved-addresses saved-addresses]]]]
|
||||
(is (match? expected-fx result-fx))))
|
||||
|
||||
(deftest reconcile-saved-addresses-test
|
||||
(testing "no saved addresses"
|
||||
(let [cofx {:db {}}
|
||||
effects (events/get-saved-addresses-success cofx nil)
|
||||
effects (events/reconcile-saved-addresses cofx nil)
|
||||
result-db (:db effects)
|
||||
expected-db {:wallet {:saved-addresses {:test {}
|
||||
:prod {}}}}]
|
||||
|
@ -48,15 +73,15 @@
|
|||
|
||||
(testing "one test saved address"
|
||||
(let [cofx {:db {}}
|
||||
effects (events/get-saved-addresses-success cofx [[saved-address-2]])
|
||||
effects (events/reconcile-saved-addresses cofx [[saved-address-1]])
|
||||
result-db (:db effects)
|
||||
expected-db {:wallet {:saved-addresses
|
||||
{:test {"0x2" {:test? true
|
||||
:address "0x2"
|
||||
:mixedcase-address "0x2"
|
||||
:chain-short-names "eth:arb1:oeth:"
|
||||
{:test {"0x1" {:test? true
|
||||
:address "0x1"
|
||||
:mixedcase-address "0x1"
|
||||
:chain-short-names "eth:oeth:"
|
||||
:ens? false
|
||||
:network-preferences-names `(:mainnet :arbitrum :optimism)
|
||||
:network-preferences-names `(:mainnet :optimism)
|
||||
:name "Bob"
|
||||
:created-at 1716826714
|
||||
:ens ""
|
||||
|
@ -67,29 +92,73 @@
|
|||
|
||||
(testing "two saved addresses (test and prod)"
|
||||
(let [cofx {:db {}}
|
||||
effects (events/get-saved-addresses-success cofx [[saved-address-1 saved-address-2]])
|
||||
effects (events/reconcile-saved-addresses cofx [[saved-address-1 saved-address-2]])
|
||||
result-db (:db effects)
|
||||
expected-db {:wallet {:saved-addresses
|
||||
{:test {"0x2" {:test? true
|
||||
:address "0x2"
|
||||
:mixedcase-address "0x2"
|
||||
:chain-short-names "eth:arb1:oeth:"
|
||||
:network-preferences-names `(:mainnet :arbitrum :optimism)
|
||||
{:test {"0x1" {:test? true
|
||||
:address "0x1"
|
||||
:mixedcase-address "0x1"
|
||||
:chain-short-names "eth:oeth:"
|
||||
:ens? false
|
||||
:network-preferences-names `(:mainnet :optimism)
|
||||
:name "Bob"
|
||||
:created-at 1716826714
|
||||
:ens ""
|
||||
:customization-color :blue
|
||||
:removed? false}}
|
||||
:prod {"0x1" {:test? false
|
||||
:address "0x1"
|
||||
:mixedcase-address "0x1"
|
||||
:prod {"0x2" {:test? false
|
||||
:address "0x2"
|
||||
:mixedcase-address "0x2"
|
||||
:chain-short-names "eth:arb1:oeth:"
|
||||
:network-preferences-names `(:mainnet :arbitrum :optimism)
|
||||
:ens? false
|
||||
:name "Amy"
|
||||
:ens? true
|
||||
:name "Alicia Keys"
|
||||
:created-at 1716826806
|
||||
:ens ""
|
||||
:ens "alicia.eth"
|
||||
:customization-color :purple
|
||||
:removed? false}}}}}]
|
||||
(is (match? expected-db result-db))))
|
||||
|
||||
(testing "remove a test saved addresses"
|
||||
(let [cofx {:db {:wallet {:saved-addresses
|
||||
{:test {"0x1" {:test? true
|
||||
:address "0x1"
|
||||
:mixedcase-address "0x1"
|
||||
:chain-short-names "eth:oeth:"
|
||||
:ens? false
|
||||
:network-preferences-names `(:mainnet :optimism)
|
||||
:name "Bob"
|
||||
:created-at 1716826714
|
||||
:ens ""
|
||||
:customization-color :blue
|
||||
:removed? false}}
|
||||
:prod {"0x2" {:test? false
|
||||
:address "0x2"
|
||||
:mixedcase-address "0x2"
|
||||
:chain-short-names "eth:arb1:oeth:"
|
||||
:network-preferences-names `(:mainnet :arbitrum
|
||||
:optimism)
|
||||
:ens? true
|
||||
:name "Alicia Keys"
|
||||
:created-at 1716826806
|
||||
:ens "alicia.eth"
|
||||
:customization-color :purple
|
||||
:removed? false}}}}}}
|
||||
effects (events/reconcile-saved-addresses cofx
|
||||
[[(assoc saved-address-1 :removed? true)
|
||||
saved-address-2]])
|
||||
result-db (:db effects)
|
||||
expected-db {:wallet {:saved-addresses
|
||||
{:test {}
|
||||
:prod {"0x2" {:test? false
|
||||
:address "0x2"
|
||||
:mixedcase-address "0x2"
|
||||
:chain-short-names "eth:arb1:oeth:"
|
||||
:network-preferences-names `(:mainnet :arbitrum :optimism)
|
||||
:ens? true
|
||||
:name "Alicia Keys"
|
||||
:created-at 1716826806
|
||||
:ens "alicia.eth"
|
||||
:customization-color :purple
|
||||
:removed? false}}}}}]
|
||||
(is (match? expected-db result-db)))))
|
||||
|
@ -141,7 +210,10 @@
|
|||
expected-fx [[:json-rpc/call
|
||||
[{:method "wakuext_deleteSavedAddress"
|
||||
:params [address test-networks-enabled?]
|
||||
:on-success [:wallet/delete-saved-address-success toast-message]
|
||||
:on-success [:wallet/delete-saved-address-success
|
||||
{:address address
|
||||
:test-networks-enabled? test-networks-enabled?
|
||||
:toast-message toast-message}]
|
||||
:on-error [:wallet/delete-saved-address-failed]}]]]]
|
||||
(is (match? expected-fx result-fx)))))
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@
|
|||
:on-press open-show-address-qr
|
||||
:accessibility-label :show-address-qr-code}
|
||||
{:icon :i/edit
|
||||
:label (i18n/label :t/edit-account)
|
||||
:label (i18n/label :t/edit-details)
|
||||
:blur? true
|
||||
:on-press open-edit-saved-address
|
||||
:accessibility-label :edit-saved-address}
|
||||
|
|
|
@ -154,7 +154,7 @@
|
|||
:colorId :customization-color
|
||||
:mixedcaseAddress :mixedcase-address
|
||||
:removed :removed?})
|
||||
(update :customization-color keyword)
|
||||
(update :customization-color (comp keyword string/lower-case))
|
||||
add-keys-to-saved-address))
|
||||
|
||||
(defn rpc->saved-addresses
|
||||
|
|
|
@ -2507,6 +2507,7 @@
|
|||
"disconnect-dapp-success": "{{dapp}} disconnected from {{account}}",
|
||||
"disconnect-dapp-fail": "Failed to disconnect {{dapp}} from {{account}}",
|
||||
"edit-account": "Edit account",
|
||||
"edit-details": "Edit details",
|
||||
"share-account": "Share account",
|
||||
"remove-account": "Remove account",
|
||||
"select-another-account": "Select another account",
|
||||
|
|
Loading…
Reference in New Issue