feat(wallet)!: process wallet accounts from backup on account recovery (#20160)
This commit: - adds a feature to process backed-up wallet data on account recovery (without the necessity to re-login) - refactors keypair data store functions - refactors wallet event to support calling for single account/address Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
This commit is contained in:
parent
a3e713bbf0
commit
9c7cb0fe93
|
@ -105,6 +105,12 @@
|
|||
"waku.backedup.settings"
|
||||
{:fx [[:dispatch [:profile/update-setting-from-backup (transforms/js->clj event-js)]]]}
|
||||
|
||||
"waku.backedup.keypair"
|
||||
{:fx [[:dispatch [:wallet/process-keypair-from-backup (transforms/js->clj event-js)]]]}
|
||||
|
||||
"waku.backedup.watch-only-account"
|
||||
{:fx [[:dispatch [:wallet/process-watch-only-account-from-backup (transforms/js->clj event-js)]]]}
|
||||
|
||||
"mediaserver.started"
|
||||
{:db (assoc db :mediaserver/port (oops/oget event-js :port))}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
(defn view
|
||||
[]
|
||||
(let [tokens-loading? (rf/sub [:wallet/tokens-loading?])
|
||||
(let [tokens-loading? (rf/sub [:wallet/current-viewing-account-tokens-loading?])
|
||||
tokens (rf/sub [:wallet/current-viewing-account-token-values])
|
||||
{:keys [watch-only?]} (rf/sub [:wallet/current-viewing-account])]
|
||||
(if tokens-loading?
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
|
||||
(defn get-keypairs-success
|
||||
[{:keys [db]} [keypairs]]
|
||||
(let [parsed-keypairs (data-store/parse-keypairs keypairs)
|
||||
default-key-uid (:key-uid (first parsed-keypairs))]
|
||||
(let [parsed-keypairs (data-store/rpc->keypairs keypairs)
|
||||
default-key-uid (:key-uid (some #(when (= (:type %) :profile) %) parsed-keypairs))]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :keypairs] parsed-keypairs)
|
||||
(assoc-in [:wallet :ui :create-account :selected-keypair-uid] default-key-uid))}))
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
(->> given-accounts
|
||||
(filter (fn [{:keys [path]}]
|
||||
(not (string/starts-with? path constants/path-eip1581))))
|
||||
(map (fn [{:keys [customization-color emoji name address]}]
|
||||
{:account-props {:customization-color customization-color
|
||||
(map (fn [{:keys [color emoji name address]}]
|
||||
{:account-props {:customization-color color
|
||||
:size 32
|
||||
:emoji emoji
|
||||
:type :default
|
||||
|
@ -48,20 +48,21 @@
|
|||
:action :none}))))
|
||||
|
||||
(defn- keypair
|
||||
[item index _
|
||||
[item _ _
|
||||
{:keys [profile-picture compressed-key selected-key-uid set-selected-key-uid customization-color]}]
|
||||
(let [accounts (parse-accounts (:accounts item))]
|
||||
(let [profile-keypair? (= (:type item) :profile)
|
||||
accounts (parse-accounts (:accounts item))]
|
||||
[quo/keypair
|
||||
{:customization-color customization-color
|
||||
:profile-picture (when (zero? index) profile-picture)
|
||||
:profile-picture (when profile-keypair? profile-picture)
|
||||
:status-indicator false
|
||||
:type (if (zero? index) :default-keypair :other)
|
||||
:type (if profile-keypair? :default-keypair :other)
|
||||
:stored :on-device
|
||||
:on-options-press #(js/alert "Options pressed")
|
||||
:action :selector
|
||||
:blur? false
|
||||
:details {:full-name (:name item)
|
||||
:address (when (zero? index)
|
||||
:address (when profile-keypair?
|
||||
(utils/get-shortened-compressed-key compressed-key))}
|
||||
:on-press #(set-selected-key-uid (:key-uid item))
|
||||
:accounts accounts
|
||||
|
|
|
@ -110,6 +110,20 @@
|
|||
new-request? (update-in [:wallet :accounts] update-vals #(dissoc % :collectibles)))
|
||||
:fx collectible-requests})))
|
||||
|
||||
(defn request-new-collectibles-for-account-from-signal
|
||||
[{:keys [db]} [address]]
|
||||
(let [pending-requests (get-in db [:wallet :ui :collectibles :pending-requests] 0)
|
||||
[request-id] (get-unique-collectible-request-id 1)]
|
||||
{:db (assoc-in db [:wallet :ui :collectibles :pending-requests] (inc pending-requests))
|
||||
:fx [[:dispatch
|
||||
[:wallet/request-new-collectibles-for-account
|
||||
{:request-id request-id
|
||||
:account address
|
||||
:amount collectibles-request-batch-size}]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/request-new-collectibles-for-account-from-signal
|
||||
request-new-collectibles-for-account-from-signal)
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/request-collectibles-for-current-viewing-account
|
||||
(fn [{:keys [db]} _]
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
(ns status-im.contexts.wallet.collectible.events-test
|
||||
(:require
|
||||
[cljs.test :refer-macros [deftest is testing]]
|
||||
matcher-combinators.test
|
||||
[status-im.contexts.wallet.collectible.events :as events]))
|
||||
|
||||
(deftest store-collectibles-test
|
||||
(testing "flush-collectibles"
|
||||
(let [collectible-1 {:collectible-data {:image-url "https://..." :animation-url "https://..."}
|
||||
:ownership [{:address "0x1"
|
||||
:balance "1"}]}
|
||||
collectible-2 {:collectible-data {:image-url "" :animation-url "https://..."}
|
||||
:ownership [{:address "0x1"
|
||||
:balance "1"}]}
|
||||
collectible-3 {:collectible-data {:image-url "" :animation-url nil}
|
||||
:ownership [{:address "0x2"
|
||||
:balance "1"}]}
|
||||
db {:wallet {:ui {:collectibles {:pending-requests 0
|
||||
:fetched {"0x1" [collectible-1
|
||||
collectible-2]
|
||||
"0x2" [collectible-3]}}}
|
||||
:accounts {"0x1" {}
|
||||
"0x3" {}}}}
|
||||
expected-db {:wallet {:ui {:collectibles {}}
|
||||
:accounts {"0x1" {:collectibles (list collectible-1 collectible-2)}
|
||||
"0x2" {:collectibles (list collectible-3)}
|
||||
"0x3" {}}}}
|
||||
result-db (:db (events/flush-collectibles {:db db}))]
|
||||
|
||||
(is (match? result-db expected-db)))))
|
||||
|
||||
(deftest clear-stored-collectibles-test
|
||||
(let [db {:wallet {:accounts {"0x1" {:collectibles [{:id 1} {:id 2}]}
|
||||
"0x2" {"some other stuff" "with any value"
|
||||
:collectibles [{:id 3}]}
|
||||
"0x3" {}}}}]
|
||||
(testing "clear-stored-collectibles"
|
||||
(let [expected-db {:wallet {:accounts {"0x1" {}
|
||||
"0x2" {"some other stuff" "with any value"}
|
||||
"0x3" {}}}}
|
||||
effects (events/clear-stored-collectibles {:db db})
|
||||
result-db (:db effects)]
|
||||
|
||||
(is (match? result-db expected-db))))))
|
||||
|
||||
(deftest store-last-collectible-details-test
|
||||
(testing "store-last-collectible-details"
|
||||
(let [db {:wallet {}}
|
||||
last-collectible {:description "Pandaria"
|
||||
:image-url "https://..."}
|
||||
expected-db {:wallet {:last-collectible-details {:description "Pandaria"
|
||||
:image-url "https://..."}}}
|
||||
effects (events/store-last-collectible-details {:db db}
|
||||
[last-collectible])
|
||||
result-db (:db effects)]
|
||||
(is (match? result-db expected-db)))))
|
||||
|
||||
(deftest request-new-collectibles-for-account-from-signal-test
|
||||
(testing "request new collectibles for account from signal"
|
||||
(let [db {:wallet {}}
|
||||
address "0x1"
|
||||
expected {:db {:wallet {:ui {:collectibles {:pending-requests 1}}}}
|
||||
:fx [[:dispatch
|
||||
[:wallet/request-new-collectibles-for-account
|
||||
{:request-id 0
|
||||
:account address
|
||||
:amount events/collectibles-request-batch-size}]]]}
|
||||
effects (events/request-new-collectibles-for-account-from-signal {:db db}
|
||||
[address])]
|
||||
(is (match? expected effects)))))
|
|
@ -1,6 +1,5 @@
|
|||
(ns status-im.contexts.wallet.data-store
|
||||
(:require
|
||||
[camel-snake-kebab.core :as csk]
|
||||
[camel-snake-kebab.extras :as cske]
|
||||
[clojure.set :as set]
|
||||
[clojure.string :as string]
|
||||
|
@ -22,7 +21,9 @@
|
|||
|
||||
(defn add-keys-to-account
|
||||
[account]
|
||||
(assoc account :watch-only? (= (:type account) :watch)))
|
||||
(-> account
|
||||
(assoc :watch-only? (= (:type account) :watch))
|
||||
(assoc :default-account? (:wallet account))))
|
||||
|
||||
(defn- sanitize-emoji
|
||||
"As Desktop uses Twemoji, the emoji received can be an img tag
|
||||
|
@ -44,9 +45,11 @@
|
|||
(update :test-preferred-chain-ids chain-ids-string->set)
|
||||
(update :type keyword)
|
||||
(update :operable keyword)
|
||||
(update :color #(if (seq %) (keyword %) constants/account-default-customization-color))
|
||||
(update :color
|
||||
#(if (and (not (keyword? %)) (string/blank? %))
|
||||
constants/account-default-customization-color
|
||||
(keyword %)))
|
||||
(update :emoji sanitize-emoji)
|
||||
(assoc :default-account? (:wallet account))
|
||||
add-keys-to-account))
|
||||
|
||||
(defn rpc->accounts
|
||||
|
@ -107,36 +110,33 @@
|
|||
:nativeCurrencySymbol :native-currency-symbol
|
||||
:nativeCurrencyName :native-currency-symbol})))
|
||||
|
||||
(defn sort-keypairs
|
||||
[keypairs]
|
||||
(sort-by #(if (some (fn [account]
|
||||
(string/starts-with? (:path account) constants/path-eip1581))
|
||||
(:accounts %))
|
||||
0
|
||||
1)
|
||||
keypairs))
|
||||
(defn get-keypair-lowest-operability
|
||||
[{:keys [accounts]}]
|
||||
(cond
|
||||
(some #(= (:operable %) :no) accounts)
|
||||
:no
|
||||
|
||||
(defn sort-and-rename-keypairs
|
||||
[keypairs]
|
||||
(let [sorted-keypairs (sort-keypairs keypairs)]
|
||||
(map (fn [item]
|
||||
(update item
|
||||
:accounts
|
||||
(fn [accounts]
|
||||
(map
|
||||
(fn [{:keys [colorId] :as account}]
|
||||
(assoc account
|
||||
:customization-color
|
||||
(if (seq colorId)
|
||||
(keyword colorId)
|
||||
:blue)))
|
||||
accounts))))
|
||||
sorted-keypairs)))
|
||||
(some #(= (:operable %) :partially) accounts)
|
||||
:partially
|
||||
|
||||
(defn parse-keypairs
|
||||
:else
|
||||
:fully))
|
||||
|
||||
(defn- add-keys-to-keypair
|
||||
[keypair]
|
||||
(assoc keypair :lowest-operability (get-keypair-lowest-operability keypair)))
|
||||
|
||||
(defn rpc->keypair
|
||||
[keypair]
|
||||
(-> keypair
|
||||
(update :type keyword)
|
||||
(update :accounts #(map rpc->account %))
|
||||
add-keys-to-keypair))
|
||||
|
||||
(defn rpc->keypairs
|
||||
[keypairs]
|
||||
(let [renamed-data (sort-and-rename-keypairs keypairs)]
|
||||
(cske/transform-keys csk/->kebab-case-keyword renamed-data)))
|
||||
(->> (map rpc->keypair keypairs)
|
||||
(sort-by #(if (= (:type %) :profile) 0 1))))
|
||||
|
||||
(defn- add-keys-to-saved-address
|
||||
[saved-address]
|
||||
|
|
|
@ -6,5 +6,4 @@
|
|||
:selected-networks (set constants/default-network-names)})
|
||||
|
||||
(def defaults
|
||||
{:ui {:network-filter network-filter-defaults
|
||||
:tokens-loading? true}})
|
||||
{:ui {:network-filter network-filter-defaults}})
|
||||
|
|
|
@ -57,19 +57,27 @@
|
|||
{:fx [[:dispatch [:wallet/clean-current-viewing-account]]
|
||||
[:dispatch [:pop-to-root :shell-stack]]]}))
|
||||
|
||||
(defn log-rpc-error
|
||||
[_ [{:keys [event params]} error]]
|
||||
(log/warn (str "[wallet] Failed to " event)
|
||||
{:params params
|
||||
:error error}))
|
||||
|
||||
(rf/reg-event-fx :wallet/log-rpc-error log-rpc-error)
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/get-accounts-success
|
||||
(fn [{:keys [db]} [accounts]]
|
||||
(let [wallet-accounts (filter #(not (:chat %)) accounts)
|
||||
(let [wallet-accounts (data-store/rpc->accounts accounts)
|
||||
wallet-db (get db :wallet)
|
||||
new-account? (:new-account? wallet-db)
|
||||
navigate-to-account (:navigate-to-account wallet-db)]
|
||||
{:db (assoc-in db
|
||||
[:wallet :accounts]
|
||||
(utils.collection/index-by :address (data-store/rpc->accounts wallet-accounts)))
|
||||
:fx [[:dispatch [:wallet/get-wallet-token]]
|
||||
(utils.collection/index-by :address wallet-accounts))
|
||||
:fx [[:dispatch [:wallet/get-wallet-token-for-all-accounts]]
|
||||
[:dispatch [:wallet/request-collectibles-for-all-accounts {:new-request? true}]]
|
||||
[:dispatch [:wallet/check-recent-history]]
|
||||
[:dispatch [:wallet/check-recent-history-for-all-accounts]]
|
||||
(when new-account?
|
||||
[:dispatch [:wallet/navigate-to-new-account navigate-to-account]])]})))
|
||||
|
||||
|
@ -79,9 +87,16 @@
|
|||
{:fx [[:json-rpc/call
|
||||
[{:method "accounts_getAccounts"
|
||||
:on-success [:wallet/get-accounts-success]
|
||||
:on-error #(log/info "failed to get accounts "
|
||||
{:error %
|
||||
:event :wallet/get-accounts})}]]]}))
|
||||
:on-error [:wallet/log-rpc-error {:event :wallet/get-accounts}]}]]]}))
|
||||
|
||||
(defn process-account-from-signal
|
||||
[{:keys [db]} [{:keys [address] :as account}]]
|
||||
{:db (assoc-in db [:wallet :accounts address] (data-store/rpc->account account))
|
||||
:fx [[:dispatch [:wallet/get-wallet-token-for-account address]]
|
||||
[:dispatch [:wallet/request-new-collectibles-for-account-from-signal address]]
|
||||
[:dispatch [:wallet/check-recent-history-for-account address]]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/process-account-from-signal process-account-from-signal)
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/save-account
|
||||
|
@ -93,9 +108,7 @@
|
|||
(rf/dispatch [:wallet/get-accounts])
|
||||
(when (fn? on-success)
|
||||
(on-success)))
|
||||
:on-error #(log/info "failed to save account "
|
||||
{:error %
|
||||
:event :wallet/save-account})}]]]}))
|
||||
:on-error [:wallet/log-rpc-error {:event :wallet/save-account}]}]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/show-account-deleted-toast
|
||||
|
@ -125,35 +138,41 @@
|
|||
[{:method "accounts_deleteAccount"
|
||||
:params [address]
|
||||
:on-success [:wallet/remove-account-success toast-message]
|
||||
:on-error #(log/info "failed to remove account "
|
||||
{:error %
|
||||
:event :wallet/remove-account})}]]]}))
|
||||
:on-error [:wallet/log-rpc-error {:event :wallet/remove-account}]}]]]}))
|
||||
|
||||
(defn get-wallet-token-for-all-accounts
|
||||
[{:keys [db]}]
|
||||
{:fx (->> (get-in db [:wallet :accounts])
|
||||
vals
|
||||
(mapv
|
||||
(fn [{:keys [address]}]
|
||||
[:dispatch [:wallet/get-wallet-token-for-account address]])))})
|
||||
|
||||
(rf/reg-event-fx :wallet/get-wallet-token-for-all-accounts get-wallet-token-for-all-accounts)
|
||||
|
||||
(defn get-wallet-token-for-account
|
||||
[{:keys [db]} [address]]
|
||||
{:db (assoc-in db [:wallet :ui :tokens-loading address] true)
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "wallet_getWalletToken"
|
||||
:params [[address]]
|
||||
:on-success [:wallet/store-wallet-token address]
|
||||
:on-error [:wallet/get-wallet-token-for-account-failed address]}]]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/get-wallet-token-for-account get-wallet-token-for-account)
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/get-wallet-token
|
||||
(fn [{:keys [db]}]
|
||||
(let [addresses (->> (get-in db [:wallet :accounts])
|
||||
vals
|
||||
(map :address))]
|
||||
{:db (assoc-in db [:wallet :ui :tokens-loading?] true)
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "wallet_getWalletToken"
|
||||
:params [addresses]
|
||||
:on-success [:wallet/store-wallet-token]
|
||||
:on-error [:wallet/get-wallet-token-failed addresses]}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/get-wallet-token-failed
|
||||
(fn [{:keys [db]} [params error]]
|
||||
:wallet/get-wallet-token-for-account-failed
|
||||
(fn [{:keys [db]} [address error]]
|
||||
(log/info "failed to get wallet token "
|
||||
{:error error
|
||||
:event :wallet/get-wallet-token
|
||||
:params params})
|
||||
{:db (assoc-in db [:wallet :ui :tokens-loading?] false)}))
|
||||
:event :wallet/get-wallet-token-for-account
|
||||
:params address})
|
||||
{:db (assoc-in db [:wallet :ui :tokens-loading address] false)}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/store-wallet-token
|
||||
(fn [{:keys [db]} [raw-tokens-data]]
|
||||
(fn [{:keys [db]} [address raw-tokens-data]]
|
||||
(let [tokens (data-store/rpc->tokens raw-tokens-data)
|
||||
add-tokens (fn [stored-accounts tokens-per-account]
|
||||
(reduce-kv (fn [accounts address tokens-data]
|
||||
|
@ -164,7 +183,7 @@
|
|||
tokens-per-account))]
|
||||
{:db (-> db
|
||||
(update-in [:wallet :accounts] add-tokens tokens)
|
||||
(assoc-in [:wallet :ui :tokens-loading?] false))})))
|
||||
(assoc-in [:wallet :ui :tokens-loading address] false))})))
|
||||
|
||||
(rf/defn scan-address-success
|
||||
{:events [:wallet/scan-address-success]}
|
||||
|
@ -209,7 +228,9 @@
|
|||
(security/safe-unmask-data password))
|
||||
account-config]
|
||||
:on-success [:wallet/add-account-success lowercase-address]
|
||||
:on-error #(log/info "failed to create account " % account-config)}]]]})))
|
||||
:on-error [:wallet/log-rpc-error
|
||||
{:event :wallet/add-account
|
||||
:params account-config}]}]]]})))
|
||||
|
||||
(defn get-keypairs
|
||||
[_]
|
||||
|
@ -217,7 +238,7 @@
|
|||
[{:method "accounts_getKeypairs"
|
||||
:params []
|
||||
:on-success [:wallet/get-keypairs-success]
|
||||
:on-error #(log/info "failed to get keypairs " %)}]]]})
|
||||
:on-error [:wallet/log-rpc-error {:event :wallet/get-keypairs}]}]]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/get-keypairs get-keypairs)
|
||||
|
||||
|
@ -254,7 +275,7 @@
|
|||
[{:method "wallet_getEthereumChains"
|
||||
:params []
|
||||
:on-success [:wallet/get-ethereum-chains-success]
|
||||
:on-error #(log/info "failed to get networks " %)}]}))
|
||||
:on-error [:wallet/log-rpc-error {:event :wallet/get-ethereum-chains}]}]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/get-ethereum-chains-success
|
||||
|
@ -354,29 +375,34 @@
|
|||
|
||||
(rf/reg-event-fx :wallet/reload
|
||||
(fn [_]
|
||||
{:fx [[:dispatch-n [[:wallet/get-wallet-token]]]]}))
|
||||
{:fx [[:dispatch [:wallet/get-wallet-token-for-all-accounts]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/start-wallet
|
||||
(fn [_]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wallet_startWallet"
|
||||
:on-error #(log/info "failed to start wallet"
|
||||
{:error %
|
||||
:event :wallet/start-wallet})}]]]}))
|
||||
:on-error [:wallet/log-rpc-error {:event :wallet/start-wallet}]}]]]}))
|
||||
|
||||
(defn check-recent-history-for-all-accounts
|
||||
[{:keys [db]}]
|
||||
{:fx (->> (get-in db [:wallet :accounts])
|
||||
vals
|
||||
(mapv (fn [{:keys [address]}]
|
||||
[:dispatch [:wallet/check-recent-history-for-account address]])))})
|
||||
|
||||
(rf/reg-event-fx :wallet/check-recent-history-for-all-accounts check-recent-history-for-all-accounts)
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/check-recent-history
|
||||
(fn [{:keys [db]}]
|
||||
(let [addresses (->> (get-in db [:wallet :accounts])
|
||||
vals
|
||||
(map :address))
|
||||
chain-ids (chain/chain-ids db)]
|
||||
:wallet/check-recent-history-for-account
|
||||
(fn [{:keys [db]} [address]]
|
||||
(let [chain-ids (chain/chain-ids db)
|
||||
params [chain-ids [address]]]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wallet_checkRecentHistoryForChainIDs"
|
||||
:params [chain-ids addresses]
|
||||
:on-error #(log/info "failed to check recent history"
|
||||
{:error %
|
||||
:event :wallet/check-recent-history})}]]]})))
|
||||
:params params
|
||||
:on-error [:wallet/log-rpc-error
|
||||
{:event :wallet/check-recent-history-for-account
|
||||
:params params}]}]]]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/initialize
|
||||
(fn []
|
||||
|
@ -496,9 +522,9 @@
|
|||
;; https://github.com/status-im/status-mobile/issues/19864
|
||||
:method "wallet_filterActivityAsync"
|
||||
:params request-params
|
||||
:on-error #(log/info "failed to fetch activities"
|
||||
{:error %
|
||||
:event :wallet/fetch-activities})}]]]})))
|
||||
:on-error [:wallet/log-rpc-error
|
||||
{:event :wallet/fetch-activities
|
||||
:params request-params}]}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/activity-filtering-done
|
||||
|
@ -523,9 +549,7 @@
|
|||
{:fx [[:json-rpc/call
|
||||
[{:method "wallet_getCryptoOnRamps"
|
||||
:on-success [:wallet/get-crypto-on-ramps-success]
|
||||
:on-error #(log/info "failed to fetch crypto on ramps"
|
||||
{:error %
|
||||
:event :wallet/get-crypto-on-ramps})}]]]}))
|
||||
:on-error [:wallet/log-rpc-error {:event :wallet/get-crypto-on-ramps}]}]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/resolve-ens
|
||||
|
@ -536,3 +560,27 @@
|
|||
:params [chain-id ens]
|
||||
:on-success on-success
|
||||
:on-error on-error}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/process-keypair-from-backup
|
||||
(fn [{:keys [db]} [{:keys [backedUpKeypair]}]]
|
||||
(let [{:keys [key-uid accounts]} backedUpKeypair
|
||||
keypairs-db (get-in db [:wallet :keypairs])
|
||||
updated-keypairs (-> (filter #(not= (:key-uid %) key-uid) keypairs-db)
|
||||
(conj backedUpKeypair)
|
||||
data-store/rpc->keypairs)
|
||||
accounts-fx (mapv (fn [{:keys [chat] :as account}]
|
||||
;; We exclude the chat account from the profile keypair
|
||||
;; for fetching the assets
|
||||
(when-not chat
|
||||
[:dispatch
|
||||
[:wallet/process-account-from-signal
|
||||
account]]))
|
||||
accounts)]
|
||||
{:db (assoc-in db [:wallet :keypairs] updated-keypairs)
|
||||
:fx accounts-fx})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/process-watch-only-account-from-backup
|
||||
(fn [_ [{:keys [backedUpWatchOnlyAccount]}]]
|
||||
{:fx [[:dispatch [:wallet/process-account-from-signal backedUpWatchOnlyAccount]]]}))
|
||||
|
|
|
@ -3,10 +3,55 @@
|
|||
[cljs.test :refer-macros [deftest is testing]]
|
||||
matcher-combinators.test
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.collectible.events :as collectible-events]
|
||||
[status-im.contexts.wallet.events :as events]))
|
||||
|
||||
(def address "0x2f88d65f3cb52605a54a833ae118fb1363acccd2")
|
||||
(def address "0x2ee6138eb9344a8b76eca3cf7554a06c82a1e2d8")
|
||||
|
||||
(def raw-account
|
||||
{:path "m/44'/60'/0'/0/0"
|
||||
:emoji "🛃"
|
||||
:key-uid "0xf9b4dc40911638052ef9cbed6e8ac689198d8f11d2235c5d62e2457c1503dc4f"
|
||||
:address address
|
||||
:wallet true
|
||||
:name "Ethereum account"
|
||||
:createdAt 1716548742000
|
||||
:type "generated"
|
||||
:chat false
|
||||
:prodPreferredChainIds "1:42161"
|
||||
:hidden false
|
||||
:position 0
|
||||
:clock 1712315009484
|
||||
:testPreferredChainIds "11155111:421614"
|
||||
:colorId "purple"
|
||||
:operable "fully"
|
||||
:mixedcase-address "0x2Ee6138eb9344a8b76Eca3cf7554A06C82A1e2D8"
|
||||
:public-key
|
||||
"0x04ee7c47e4b68cc05dcd3377cbd5cde6be3c89fcf20a981e55e0285ed63a50f51f8b423465eee134c51bb0255e6041e9e5b006054b0fa72a7c76942a5a1a3f4e7e"
|
||||
:removed false})
|
||||
|
||||
(def account
|
||||
{:path "m/44'/60'/0'/0/0"
|
||||
:emoji "🛃"
|
||||
:key-uid "0xf9b4dc40911638052ef9cbed6e8ac689198d8f11d2235c5d62e2457c1503dc4f"
|
||||
:address address
|
||||
:color :purple
|
||||
:wallet true
|
||||
:default-account? true
|
||||
:name "Ethereum account"
|
||||
:type :generated
|
||||
:chat false
|
||||
:test-preferred-chain-ids #{11155111 421614}
|
||||
:watch-only? false
|
||||
:hidden false
|
||||
:prod-preferred-chain-ids #{1 42161}
|
||||
:position 0
|
||||
:clock 1712315009484
|
||||
:created-at 1716548742000
|
||||
:operable :fully
|
||||
:mixedcase-address "0x2Ee6138eb9344a8b76Eca3cf7554A06C82A1e2D8"
|
||||
:public-key
|
||||
"0x04ee7c47e4b68cc05dcd3377cbd5cde6be3c89fcf20a981e55e0285ed63a50f51f8b423465eee134c51bb0255e6041e9e5b006054b0fa72a7c76942a5a1a3f4e7e"
|
||||
:removed false})
|
||||
|
||||
(deftest scan-address-success-test
|
||||
(let [db {}]
|
||||
|
@ -25,57 +70,6 @@
|
|||
result-db (:db effects)]
|
||||
(is (match? result-db expected-db))))))
|
||||
|
||||
(deftest store-collectibles-test
|
||||
(testing "flush-collectibles"
|
||||
(let [collectible-1 {:collectible-data {:image-url "https://..." :animation-url "https://..."}
|
||||
:ownership [{:address "0x1"
|
||||
:balance "1"}]}
|
||||
collectible-2 {:collectible-data {:image-url "" :animation-url "https://..."}
|
||||
:ownership [{:address "0x1"
|
||||
:balance "1"}]}
|
||||
collectible-3 {:collectible-data {:image-url "" :animation-url nil}
|
||||
:ownership [{:address "0x2"
|
||||
:balance "1"}]}
|
||||
db {:wallet {:ui {:collectibles {:pending-requests 0
|
||||
:fetched {"0x1" [collectible-1
|
||||
collectible-2]
|
||||
"0x2" [collectible-3]}}}
|
||||
:accounts {"0x1" {}
|
||||
"0x3" {}}}}
|
||||
expected-db {:wallet {:ui {:collectibles {}}
|
||||
:accounts {"0x1" {:collectibles (list collectible-1 collectible-2)}
|
||||
"0x2" {:collectibles (list collectible-3)}
|
||||
"0x3" {}}}}
|
||||
result-db (:db (collectible-events/flush-collectibles {:db db}))]
|
||||
|
||||
(is (match? result-db expected-db)))))
|
||||
|
||||
(deftest clear-stored-collectibles-test
|
||||
(let [db {:wallet {:accounts {"0x1" {:collectibles [{:id 1} {:id 2}]}
|
||||
"0x2" {"some other stuff" "with any value"
|
||||
:collectibles [{:id 3}]}
|
||||
"0x3" {}}}}]
|
||||
(testing "clear-stored-collectibles"
|
||||
(let [expected-db {:wallet {:accounts {"0x1" {}
|
||||
"0x2" {"some other stuff" "with any value"}
|
||||
"0x3" {}}}}
|
||||
effects (collectible-events/clear-stored-collectibles {:db db})
|
||||
result-db (:db effects)]
|
||||
|
||||
(is (match? result-db expected-db))))))
|
||||
|
||||
(deftest store-last-collectible-details-test
|
||||
(testing "store-last-collectible-details"
|
||||
(let [db {:wallet {}}
|
||||
last-collectible {:description "Pandaria"
|
||||
:image-url "https://..."}
|
||||
expected-db {:wallet {:last-collectible-details {:description "Pandaria"
|
||||
:image-url "https://..."}}}
|
||||
effects (collectible-events/store-last-collectible-details {:db db}
|
||||
[last-collectible])
|
||||
result-db (:db effects)]
|
||||
(is (match? result-db expected-db)))))
|
||||
|
||||
(deftest reset-selected-networks-test
|
||||
(testing "reset-selected-networks"
|
||||
(let [db {:wallet {}}
|
||||
|
@ -122,3 +116,51 @@
|
|||
effects (events/update-selected-networks {:db db} props)
|
||||
result-fx (:fx effects)]
|
||||
(is (match? result-fx expected-fx)))))
|
||||
|
||||
(deftest get-wallet-token-for-all-accounts-test
|
||||
(testing "get wallet token for all accounts"
|
||||
(let [address-1 "0x1"
|
||||
address-2 "0x2"
|
||||
cofx {:db {:wallet {:accounts {address-1 {:address address-1}
|
||||
address-2 {:address address-2}}}}}
|
||||
effects (events/get-wallet-token-for-all-accounts cofx)
|
||||
result-fx (:fx effects)
|
||||
expected-fx [[:dispatch [:wallet/get-wallet-token-for-account address-1]]
|
||||
[:dispatch [:wallet/get-wallet-token-for-account address-2]]]]
|
||||
(is (match? expected-fx result-fx)))))
|
||||
|
||||
(deftest get-wallet-token-for-account-test
|
||||
(testing "get wallet token for account"
|
||||
(let [cofx {:db {}}
|
||||
effects (events/get-wallet-token-for-account cofx [address])
|
||||
expected-effects {:db {:wallet {:ui {:tokens-loading {address true}}}}
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "wallet_getWalletToken"
|
||||
:params [[address]]
|
||||
:on-success [:wallet/store-wallet-token address]
|
||||
:on-error [:wallet/get-wallet-token-for-account-failed
|
||||
address]}]]]}]
|
||||
(is (match? expected-effects effects)))))
|
||||
|
||||
(deftest check-recent-history-for-all-accounts-test
|
||||
(testing "check recent history for all accounts"
|
||||
(let [address-1 "0x1"
|
||||
address-2 "0x2"
|
||||
cofx {:db {:wallet {:accounts {address-1 {:address address-1}
|
||||
address-2 {:address address-2}}}}}
|
||||
effects (events/check-recent-history-for-all-accounts cofx)
|
||||
result-fx (:fx effects)
|
||||
expected-fx [[:dispatch [:wallet/check-recent-history-for-account address-1]]
|
||||
[:dispatch [:wallet/check-recent-history-for-account address-2]]]]
|
||||
(is (match? expected-fx result-fx)))))
|
||||
|
||||
(deftest process-account-from-signal-test
|
||||
(testing "process account from signal"
|
||||
(let [cofx {:db {:wallet {:accounts {}}}}
|
||||
effects (events/process-account-from-signal cofx [raw-account])
|
||||
expected-effects {:db {:wallet {:accounts {address account}}}
|
||||
:fx [[:dispatch [:wallet/get-wallet-token-for-account address]]
|
||||
[:dispatch
|
||||
[:wallet/request-new-collectibles-for-account-from-signal address]]
|
||||
[:dispatch [:wallet/check-recent-history-for-account address]]]}]
|
||||
(is (match? expected-effects effects)))))
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
(defn view
|
||||
[]
|
||||
(let [tokens-loading? (rf/sub [:wallet/tokens-loading?])
|
||||
(let [tokens-loading? (rf/sub [:wallet/home-tokens-loading?])
|
||||
{:keys [tokens]} (rf/sub [:wallet/aggregated-token-values-and-balance])]
|
||||
(if tokens-loading?
|
||||
[quo/skeleton-list
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
[]
|
||||
(let [[selected-tab set-selected-tab] (rn/use-state (:id (first tabs-data)))
|
||||
account-list-ref (rn/use-ref-atom nil)
|
||||
tokens-loading? (rf/sub [:wallet/tokens-loading?])
|
||||
tokens-loading? (rf/sub [:wallet/home-tokens-loading?])
|
||||
networks (rf/sub [:wallet/selected-network-details])
|
||||
account-cards-data (rf/sub [:wallet/account-cards-data])
|
||||
cards (conj account-cards-data (new-account-card-data))
|
||||
|
|
|
@ -40,6 +40,4 @@
|
|||
"wallet-activity-filtering-done" {:fx [[:dispatch
|
||||
[:wallet/activity-filtering-done
|
||||
(transforms/js->clj event-js)]]]}
|
||||
(log/debug ::unknown-wallet-event
|
||||
:type event-type
|
||||
:event (transforms/js->clj event-js))))))
|
||||
(log/debug ::unknown-wallet-event :type event-type)))))
|
||||
|
|
|
@ -39,9 +39,25 @@
|
|||
:-> :scanned-address)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/tokens-loading?
|
||||
:wallet/tokens-loading
|
||||
:<- [:wallet/ui]
|
||||
:-> :tokens-loading?)
|
||||
:-> :tokens-loading)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/home-tokens-loading?
|
||||
:<- [:wallet/tokens-loading]
|
||||
(fn [tokens-loading]
|
||||
(->> tokens-loading
|
||||
vals
|
||||
(some true?)
|
||||
boolean)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/current-viewing-account-tokens-loading?
|
||||
:<- [:wallet/tokens-loading]
|
||||
:<- [:wallet/current-viewing-account-address]
|
||||
(fn [[tokens-loading current-viewing-account-address]]
|
||||
(get tokens-loading current-viewing-account-address)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/create-account
|
||||
|
@ -218,9 +234,9 @@
|
|||
:or {networks []
|
||||
size 32}}]
|
||||
(->> accounts
|
||||
(keep (fn [{:keys [path customization-color emoji name address]}]
|
||||
(keep (fn [{:keys [path color emoji name address]}]
|
||||
(when-not (string/starts-with? path constants/path-eip1581)
|
||||
{:account-props {:customization-color customization-color
|
||||
{:account-props {:customization-color color
|
||||
:size size
|
||||
:emoji emoji
|
||||
:type :default
|
||||
|
@ -233,8 +249,8 @@
|
|||
(defn- format-settings-missing-keypair-accounts
|
||||
[accounts]
|
||||
(->> accounts
|
||||
(map (fn [{:keys [customization-color emoji]}]
|
||||
{:customization-color customization-color
|
||||
(map (fn [{:keys [color emoji]}]
|
||||
{:customization-color color
|
||||
:emoji emoji
|
||||
:type :default}))))
|
||||
|
||||
|
@ -311,15 +327,15 @@
|
|||
:wallet/account-cards-data
|
||||
:<- [:wallet/accounts]
|
||||
:<- [:wallet/balances-in-selected-networks]
|
||||
:<- [:wallet/tokens-loading?]
|
||||
:<- [:wallet/tokens-loading]
|
||||
:<- [:profile/currency-symbol]
|
||||
(fn [[accounts balances tokens-loading? currency-symbol]]
|
||||
(fn [[accounts balances tokens-loading currency-symbol]]
|
||||
(mapv (fn [{:keys [color address watch-only?] :as account}]
|
||||
(assoc account
|
||||
:customization-color color
|
||||
:type (if watch-only? :watch-only :empty)
|
||||
:on-press #(rf/dispatch [:wallet/navigate-to-account address])
|
||||
:loading? tokens-loading?
|
||||
:loading? (get tokens-loading address)
|
||||
:balance (utils/prettify-balance currency-symbol (get balances address))))
|
||||
accounts)))
|
||||
|
||||
|
|
|
@ -609,46 +609,46 @@
|
|||
(rf/sub [sub-name])))))
|
||||
|
||||
(def chat-account
|
||||
{:path "m/43'/60'/1581'/0'/0"
|
||||
:emoji ""
|
||||
:key-uid "abc"
|
||||
:address "address-1"
|
||||
:color-id ""
|
||||
:wallet false
|
||||
:name "My Profile"
|
||||
:type "generated"
|
||||
:chat true
|
||||
:customization-color :blue
|
||||
:hidden false
|
||||
:removed false})
|
||||
{:path "m/43'/60'/1581'/0'/0"
|
||||
:emoji ""
|
||||
:key-uid "abc"
|
||||
:address "address-1"
|
||||
:color-id ""
|
||||
:wallet false
|
||||
:name "My Profile"
|
||||
:type "generated"
|
||||
:chat true
|
||||
:color :blue
|
||||
:hidden false
|
||||
:removed false})
|
||||
|
||||
(def operable-wallet-account
|
||||
{:path "m/44'/60'/0'/0/0"
|
||||
:emoji "🤡"
|
||||
:key-uid "abc"
|
||||
:address "address-2"
|
||||
:wallet true
|
||||
:name "My Account"
|
||||
:type "generated"
|
||||
:chat false
|
||||
:customization-color :primary
|
||||
:hidden false
|
||||
:operable :fully
|
||||
:removed false})
|
||||
{:path "m/44'/60'/0'/0/0"
|
||||
:emoji "🤡"
|
||||
:key-uid "abc"
|
||||
:address "address-2"
|
||||
:wallet true
|
||||
:name "My Account"
|
||||
:type "generated"
|
||||
:chat false
|
||||
:color :primary
|
||||
:hidden false
|
||||
:operable :fully
|
||||
:removed false})
|
||||
|
||||
(def inoperable-wallet-account
|
||||
{:path "m/44'/60'/0'/0/0"
|
||||
:emoji "🧠"
|
||||
:key-uid "def"
|
||||
:address "address-3"
|
||||
:wallet true
|
||||
:name "My Other Account"
|
||||
:type "generated"
|
||||
:chat false
|
||||
:customization-color :primary
|
||||
:hidden false
|
||||
:operable :no
|
||||
:removed false})
|
||||
{:path "m/44'/60'/0'/0/0"
|
||||
:emoji "🧠"
|
||||
:key-uid "def"
|
||||
:address "address-3"
|
||||
:wallet true
|
||||
:name "My Other Account"
|
||||
:type "generated"
|
||||
:chat false
|
||||
:color :primary
|
||||
:hidden false
|
||||
:operable :no
|
||||
:removed false})
|
||||
|
||||
(def default-keypair-accounts
|
||||
{:key-uid "abc"
|
||||
|
@ -686,14 +686,13 @@
|
|||
{:missing [{:name (:name seed-phrase-keypair-accounts)
|
||||
:key-uid (:key-uid seed-phrase-keypair-accounts)
|
||||
:type (keyword (:type seed-phrase-keypair-accounts))
|
||||
:accounts [{:customization-color (:customization-color inoperable-wallet-account)
|
||||
:accounts [{:customization-color (:color inoperable-wallet-account)
|
||||
:emoji (:emoji inoperable-wallet-account)
|
||||
:type :default}]}]
|
||||
:operable [{:name (:name default-keypair-accounts)
|
||||
:key-uid (:key-uid default-keypair-accounts)
|
||||
:type (keyword (:type default-keypair-accounts))
|
||||
:accounts [{:account-props {:customization-color (:customization-color
|
||||
operable-wallet-account)
|
||||
:accounts [{:account-props {:customization-color (:color operable-wallet-account)
|
||||
:size 32
|
||||
:emoji (:emoji operable-wallet-account)
|
||||
:type :default
|
||||
|
@ -717,7 +716,7 @@
|
|||
[:wallet :accounts]
|
||||
{(:address operable-wallet-account) operable-wallet-account}))))
|
||||
|
||||
(let [{:keys [customization-color
|
||||
(let [{:keys [color
|
||||
name
|
||||
address
|
||||
emoji]} operable-wallet-account
|
||||
|
@ -730,7 +729,7 @@
|
|||
:operable [{:name (:name default-keypair-accounts)
|
||||
:key-uid (:key-uid default-keypair-accounts)
|
||||
:type (keyword (:type default-keypair-accounts))
|
||||
:accounts [{:account-props {:customization-color customization-color
|
||||
:accounts [{:account-props {:customization-color color
|
||||
:size size-option
|
||||
:emoji emoji
|
||||
:type :default
|
||||
|
@ -763,8 +762,7 @@
|
|||
:operable [{:name (:name default-keypair-accounts)
|
||||
:key-uid (:key-uid default-keypair-accounts)
|
||||
:type (keyword (:type default-keypair-accounts))
|
||||
:accounts [{:account-props {:customization-color (:customization-color
|
||||
operable-wallet-account)
|
||||
:accounts [{:account-props {:customization-color (:color operable-wallet-account)
|
||||
:size 32
|
||||
:emoji (:emoji operable-wallet-account)
|
||||
:type :default
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
|
||||
(defn wallet-loaded?
|
||||
[]
|
||||
(not @(rf/subscribe [:wallet/tokens-loading?])))
|
||||
(not @(rf/subscribe [:wallet/home-tokens-loading?])))
|
||||
|
||||
(defn assert-messenger-started
|
||||
[]
|
||||
|
|
Loading…
Reference in New Issue