[#17823] Refactor tokens data app-db (#17880)

* Refactor edit-account view and events:

 - Fix `(fn [])` code style.
 - Avoid overriding clojure.core/type by destructuring the `:type` key.
 - Split the toast callback to a different function.
 - `:wallet/save-account` receives `:on-success` instead of `:callback` to improve readability.

* Refactor app-db for `:wallet/tokens` & `:wallet/tokens-loading?`

- Remove the root sub `:wallet/tokens-loading?`, now it's in app-db in `[:wallet :ui :tokens-loading?]`.
- Remove the root subs `:wallet/tokens`, now the value is returned along with the account data by the sub
  `:wallet/accounts`, it's stored in app-db in `[:wallet :address "0x..." :tokens]`.
- Fix the format of the token data returned by the endpoint `"wallet_getWalletToken"` and the fn `js->clj`,
    - Addresses are no longer keywords (since keywords mustn't start with a number).
    - Keys are now kebab-case.
    - Chain-ids are no longer keywords, now they are integers.
- Update tests.

* Move logic to calculate `:wallet/balances` and change value returned

- Move logic to `status-im2.contexts.wallet.common.utils`
- The `:wallet/balances` value returned by the sub had the following structure:
  [{:address "0x1...", :balance 12345}
   {:address "0x2...", :balance 67890} ...]
  This required a helper function to get the balance for an address (`get-balance-by-address`)
  It has been changed to a map:
  {"0x1..." 12345
   "0x2..." 67890, ...}
  So now we don't need a helper function (just the hashmap itself or `clojure.core/get`).
- Because of the previous change, now the `get-balance-by-address` has been removed.
- The function `get-account-by-address` has zero uses, so it has been removed.
- The test for the sub has been updated.

* Create sub `:wallet/account-cards-data`

This sub returns a vector of maps to render the account cards in the wallet page.
This logic was previously in the `view` namespace, but it was completely calculated from
the subs `:wallet/accounts`, `:wallet/balances` and `:wallet/tokens-loading?`, so it was
clear that's a derived value.
This commit is contained in:
Ulises Manuel 2023-11-14 10:54:26 -06:00 committed by GitHub
parent a74c934936
commit 45df308dd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 237 additions and 236 deletions

View File

@ -73,12 +73,12 @@
(data-store.settings/rpc->settings settings) (data-store.settings/rpc->settings settings)
profile-overview (profile.rpc/rpc->profiles-overview account)] profile-overview (profile.rpc/rpc->profiles-overview account)]
(rf/merge cofx (rf/merge cofx
{:db (assoc db {:db (-> db
:chats/loading? true (assoc :chats/loading? true
:networks/current-network current-network :networks/current-network current-network
:wallet/tokens-loading? true
:networks/networks (merge networks config/default-networks-by-id) :networks/networks (merge networks config/default-networks-by-id)
:profile/profile (merge profile-overview settings))} :profile/profile (merge profile-overview settings))
(assoc-in [:wallet :ui :tokens-loading?] true))}
(notifications/load-preferences) (notifications/load-preferences)
(data-store.chats/fetch-chats-preview (data-store.chats/fetch-chats-preview
{:on-success {:on-success

View File

@ -1,22 +1,12 @@
(ns status-im2.contexts.wallet.common.utils (ns status-im2.contexts.wallet.common.utils
(:require [clojure.string :as string] (:require [clojure.string :as string]
[status-im2.constants :as constants])) [status-im2.constants :as constants]
[utils.number]))
(defn get-first-name (defn get-first-name
[full-name] [full-name]
(first (string/split full-name #" "))) (first (string/split full-name #" ")))
(defn get-balance-by-address
[balances address]
(->> balances
(filter #(= (:address %) address))
first
:balance))
(defn get-account-by-address
[accounts address]
(some #(when (= (:address %) address) %) accounts))
(defn prettify-balance (defn prettify-balance
[balance] [balance]
(str "$" (.toFixed (if (number? balance) balance 0) 2))) (str "$" (.toFixed (if (number? balance) balance 0) 2)))
@ -32,3 +22,24 @@
[number-of-accounts] [number-of-accounts]
(let [path (get-derivation-path number-of-accounts)] (let [path (get-derivation-path number-of-accounts)]
(format-derivation-path path))) (format-derivation-path path)))
(defn- calculate-raw-balance
[raw-balance decimals]
(if-let [n (utils.number/parse-int raw-balance nil)]
(/ n (Math/pow 10 (utils.number/parse-int decimals)))
0))
(defn- total-token-value-in-all-chains
[{:keys [balances-per-chain decimals]}]
(->> balances-per-chain
(vals)
(map #(calculate-raw-balance (:raw-balance %) decimals))
(reduce +)))
(defn calculate-balance
[tokens-in-account]
(->> tokens-in-account
(map (fn [token]
(* (total-token-value-in-all-chains token)
(-> token :market-values-per-currency :usd :price))))
(reduce +)))

View File

@ -4,29 +4,33 @@
[quo.theme :as quo.theme] [quo.theme :as quo.theme]
[react-native.core :as rn] [react-native.core :as rn]
[reagent.core :as reagent] [reagent.core :as reagent]
[status-im2.contexts.wallet.common.screen-base.create-or-edit-account.view :as [status-im2.contexts.wallet.common.screen-base.create-or-edit-account.view
create-or-edit-account] :as create-or-edit-account]
[status-im2.contexts.wallet.common.sheets.network-preferences.view :as network-preferences] [status-im2.contexts.wallet.common.sheets.network-preferences.view
:as network-preferences]
[status-im2.contexts.wallet.edit-account.style :as style] [status-im2.contexts.wallet.edit-account.style :as style]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.re-frame :as rf])) [utils.re-frame :as rf]))
(defn- save-account (defn- show-save-account-toast
[{:keys [theme type value account]}] [updated-key theme]
(let [edited-account-data (assoc account type value) (let [message (case updated-key
message (case type
:name :t/edit-wallet-account-name-updated-message :name :t/edit-wallet-account-name-updated-message
:color :t/edit-wallet-account-colour-updated-message :color :t/edit-wallet-account-colour-updated-message
:emoji :t/edit-wallet-account-emoji-updated-message :emoji :t/edit-wallet-account-emoji-updated-message
nil) nil)]
callback #(rf/dispatch [:toasts/upsert (rf/dispatch [:toasts/upsert
{:id :edit-account {:id :edit-account
:icon :i/correct :icon :i/correct
:icon-color (colors/resolve-color :success theme) :icon-color (colors/resolve-color :success theme)
:text (i18n/label message)}])] :text (i18n/label message)}])))
(defn- save-account
[{:keys [account updated-key new-value theme]}]
(let [edited-account-data (assoc account updated-key new-value)]
(rf/dispatch [:wallet/save-account (rf/dispatch [:wallet/save-account
{:account edited-account-data {:account edited-account-data
:callback callback}]))) :on-success #(show-save-account-toast updated-key theme)}])))
(defn- view-internal (defn- view-internal
[{:keys [theme]}] [{:keys [theme]}]
@ -35,20 +39,20 @@
on-change-color (fn [edited-color {:keys [color] :as account}] on-change-color (fn [edited-color {:keys [color] :as account}]
(when (not= edited-color color) (when (not= edited-color color)
(save-account {:account account (save-account {:account account
:type :color :updated-key :color
:value edited-color :new-value edited-color
:theme theme}))) :theme theme})))
on-change-emoji (fn [edited-emoji {:keys [emoji] :as account}] on-change-emoji (fn [edited-emoji {:keys [emoji] :as account}]
(when (not= edited-emoji emoji) (when (not= edited-emoji emoji)
(save-account {:account account (save-account {:account account
:type :emoji :updated-key :emoji
:value edited-emoji :new-value edited-emoji
:theme theme}))) :theme theme})))
on-confirm-name (fn [account] on-confirm-name (fn [account]
(rn/dismiss-keyboard!) (rn/dismiss-keyboard!)
(save-account {:account account (save-account {:account account
:type :name :updated-key :name
:value @edited-account-name :new-value @edited-account-name
:theme theme}))] :theme theme}))]
(fn [] (fn []
(let [{:keys [name emoji address color] (let [{:keys [name emoji address color]
@ -82,7 +86,8 @@
:right-icon :i/advanced :right-icon :i/advanced
:card? true :card? true
:title (i18n/label :t/address) :title (i18n/label :t/address)
:custom-subtitle (fn [] [quo/address-text :custom-subtitle (fn []
[quo/address-text
{:networks [{:network-name :ethereum :short-name "eth"} {:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "opt"} {:network-name :optimism :short-name "opt"}
{:network-name :arbitrum :short-name "arb1"}] {:network-name :arbitrum :short-name "arb1"}]
@ -90,9 +95,9 @@
:format :long}]) :format :long}])
:on-press (fn [] :on-press (fn []
(rf/dispatch [:show-bottom-sheet (rf/dispatch [:show-bottom-sheet
{:content (fn [] [network-preferences/view {:content (fn []
{:on-save #(js/alert [network-preferences/view
"calling on save")}])}])) {:on-save #(js/alert "calling on save")}])}]))
:container-style style/data-item}]])))) :container-style style/data-item}]]))))
(def view (quo.theme/with-theme view-internal)) (def view (quo.theme/with-theme view-internal))

View File

@ -11,6 +11,7 @@
[taoensso.timbre :as log] [taoensso.timbre :as log]
[utils.ethereum.chain :as chain] [utils.ethereum.chain :as chain]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.number]
[utils.re-frame :as rf] [utils.re-frame :as rf]
[utils.security.core :as security] [utils.security.core :as security]
[utils.transforms :as types])) [utils.transforms :as types]))
@ -40,7 +41,8 @@
{:db (update db :wallet dissoc :current-viewing-account-address) {:db (update db :wallet dissoc :current-viewing-account-address)
:fx [[:dispatch [:navigate-back]]]})) :fx [[:dispatch [:navigate-back]]]}))
(rf/reg-event-fx :wallet/get-accounts-success (rf/reg-event-fx
:wallet/get-accounts-success
(fn [{:keys [db]} [accounts]] (fn [{:keys [db]} [accounts]]
(let [wallet-db (get db :wallet) (let [wallet-db (get db :wallet)
new-account? (:new-account? wallet-db) new-account? (:new-account? wallet-db)
@ -61,7 +63,8 @@
{:dispatch [:wallet/navigate-to-account navigate-to-account] {:dispatch [:wallet/navigate-to-account navigate-to-account]
:ms 300}]]))))) :ms 300}]])))))
(rf/reg-event-fx :wallet/get-accounts (rf/reg-event-fx
:wallet/get-accounts
(fn [_] (fn [_]
{:fx [[:json-rpc/call {:fx [[:json-rpc/call
[{:method "accounts_getAccounts" [{:method "accounts_getAccounts"
@ -72,35 +75,54 @@
(rf/reg-event-fx (rf/reg-event-fx
:wallet/save-account :wallet/save-account
(fn [_ [{:keys [account callback]}]] (fn [_ [{:keys [account on-success]}]]
{:fx [[:json-rpc/call {:fx [[:json-rpc/call
[{:method "accounts_saveAccount" [{:method "accounts_saveAccount"
:params [(data-store/<-account account)] :params [(data-store/<-account account)]
:on-success (fn [] :on-success (fn []
(rf/dispatch [:wallet/get-accounts]) (rf/dispatch [:wallet/get-accounts])
(when (fn? callback) (when (fn? on-success)
(callback))) (on-success)))
:on-error #(log/info "failed to save account " :on-error #(log/info "failed to save account "
{:error % {:error %
:event :wallet/save-account})}]]]})) :event :wallet/save-account})}]]]}))
(rf/reg-event-fx :wallet/get-wallet-token (rf/reg-event-fx
:wallet/get-wallet-token
(fn [{:keys [db]}] (fn [{:keys [db]}]
(let [addresses (map :address (vals (get-in db [:wallet :accounts])))] (let [addresses (->> (get-in db [:wallet :accounts])
vals
(map :address))]
{:fx [[:json-rpc/call {:fx [[:json-rpc/call
[{:method "wallet_getWalletToken" [{:method "wallet_getWalletToken"
:params [addresses] :params [addresses]
:on-success [:wallet/get-wallet-token-success] :on-success [:wallet/store-wallet-token]
:on-error #(log/info "failed to get wallet token " :on-error #(log/info "failed to get wallet token "
{:error % {:error %
:event :wallet/get-wallet-token :event :wallet/get-wallet-token
:params addresses})}]]]}))) :params addresses})}]]]})))
(rf/reg-event-fx :wallet/get-wallet-token-success (defn- fix-chain-id-keys
(fn [{:keys [db]} [tokens]] [token]
{:db (assoc db (update token :balances-per-chain update-keys (comp utils.number/parse-int name)))
:wallet/tokens tokens
:wallet/tokens-loading? false)})) (rf/reg-event-fx
:wallet/store-wallet-token
(fn [{:keys [db]} [raw-tokens-data]]
(let [tokens (-> raw-tokens-data
(update-keys name)
(update-vals #(cske/transform-keys csk/->kebab-case %))
(update-vals #(mapv fix-chain-id-keys %)))
add-tokens (fn [stored-accounts tokens-per-account]
(reduce-kv (fn [accounts address tokens-data]
(if (accounts address)
(update accounts address assoc :tokens tokens-data)
accounts))
stored-accounts
tokens-per-account))]
{:db (-> db
(update-in [:wallet :accounts] add-tokens tokens)
(assoc-in [:wallet :ui :tokens-loading?] false))})))
(rf/defn scan-address-success (rf/defn scan-address-success
{:events [:wallet/scan-address-success]} {:events [:wallet/scan-address-success]}
@ -122,7 +144,8 @@
:on-success on-success :on-success on-success
:on-error #(log/info "failed to derive address " %)}]]]}))) :on-error #(log/info "failed to derive address " %)}]]]})))
(rf/reg-event-fx :wallet/add-account (rf/reg-event-fx
:wallet/add-account
(fn [{:keys [db]} [password {:keys [emoji account-name color]} {:keys [public-key address path]}]] (fn [{:keys [db]} [password {:keys [emoji account-name color]} {:keys [public-key address path]}]]
(let [key-uid (get-in db [:profile/profile :key-uid]) (let [key-uid (get-in db [:profile/profile :key-uid])
sha3-pwd (native-module/sha3 (security/safe-unmask-data password)) sha3-pwd (native-module/sha3 (security/safe-unmask-data password))
@ -146,11 +169,12 @@
:on-success [:wallet/get-accounts] :on-success [:wallet/get-accounts]
:on-error #(log/info "failed to create account " %)}]]]}))) :on-error #(log/info "failed to create account " %)}]]]})))
(rf/reg-event-fx :wallet/derive-address-and-add-account (rf/reg-event-fx
:wallet/derive-address-and-add-account
(fn [_ [password account-details]] (fn [_ [password account-details]]
(let [on-success (fn [derived-adress-details] (let [on-success (fn [derived-address-details]
(rf/dispatch [:wallet/add-account password account-details (rf/dispatch [:wallet/add-account password account-details
(first derived-adress-details)]))] (first derived-address-details)]))]
{:fx [[:dispatch [:wallet/create-derived-addresses password account-details on-success]]]}))) {:fx [[:dispatch [:wallet/create-derived-addresses password account-details on-success]]]})))
(rf/defn get-ethereum-chains (rf/defn get-ethereum-chains
@ -199,7 +223,8 @@
(rf/reg-event-fx :wallet/clear-stored-collectibles clear-stored-collectibles) (rf/reg-event-fx :wallet/clear-stored-collectibles clear-stored-collectibles)
(rf/reg-event-fx :wallet/request-collectibles (rf/reg-event-fx
:wallet/request-collectibles
(fn [{:keys [db]} [{:keys [start-at-index new-request?]}]] (fn [{:keys [db]} [{:keys [start-at-index new-request?]}]]
(let [request-id 0 (let [request-id 0
collectibles-filter nil collectibles-filter nil

View File

@ -8,7 +8,6 @@
[status-im2.contexts.wallet.common.activity-tab.view :as activity] [status-im2.contexts.wallet.common.activity-tab.view :as activity]
[status-im2.contexts.wallet.common.collectibles-tab.view :as collectibles] [status-im2.contexts.wallet.common.collectibles-tab.view :as collectibles]
[status-im2.contexts.wallet.common.temp :as temp] [status-im2.contexts.wallet.common.temp :as temp]
[status-im2.contexts.wallet.common.utils :as utils]
[status-im2.contexts.wallet.home.style :as style] [status-im2.contexts.wallet.home.style :as style]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.re-frame :as rf])) [utils.re-frame :as rf]))
@ -28,9 +27,9 @@
:on-press #(rf/dispatch [:navigate-to :add-address-to-watch]) :on-press #(rf/dispatch [:navigate-to :add-address-to-watch])
:add-divider? true}]]]) :add-divider? true}]]])
(defn- add-account-placeholder (defn- new-account-card-data
[color] []
{:customization-color color {:customization-color (rf/sub [:profile/customization-color])
:on-press #(rf/dispatch [:show-bottom-sheet {:content new-account}]) :on-press #(rf/dispatch [:show-bottom-sheet {:content new-account}])
:type :add-account}) :type :add-account})
@ -39,21 +38,6 @@
{:id :collectibles :label (i18n/label :t/collectibles) :accessibility-label :collectibles-tab} {:id :collectibles :label (i18n/label :t/collectibles) :accessibility-label :collectibles-tab}
{:id :activity :label (i18n/label :t/activity) :accessibility-label :activity-tab}]) {:id :activity :label (i18n/label :t/activity) :accessibility-label :activity-tab}])
(defn account-cards
[{:keys [accounts loading? balances profile-color]}]
(let [accounts-with-balances
(mapv
(fn [{:keys [color address] :as account}]
(assoc account
:customization-color color
:type :empty
:on-press #(rf/dispatch [:wallet/navigate-to-account address])
:loading? loading?
:balance (utils/prettify-balance
(utils/get-balance-by-address balances address))))
accounts)]
(conj accounts-with-balances (add-account-placeholder profile-color))))
(defn view (defn view
[] []
(rf/dispatch [:wallet/request-collectibles (rf/dispatch [:wallet/request-collectibles
@ -62,14 +46,10 @@
(let [top (safe-area/get-top) (let [top (safe-area/get-top)
selected-tab (reagent/atom (:id (first tabs-data)))] selected-tab (reagent/atom (:id (first tabs-data)))]
(fn [] (fn []
(let [accounts (rf/sub [:wallet/accounts]) (let [networks (rf/sub [:wallet/network-details])
loading? (rf/sub [:wallet/tokens-loading?]) account-cards-data (rf/sub [:wallet/account-cards-data])
balances (rf/sub [:wallet/balances]) cards (conj account-cards-data (new-account-card-data))]
profile-color (rf/sub [:profile/customization-color]) [rn/view {:style {:margin-top top :flex 1}}
networks (rf/sub [:wallet/network-details])]
[rn/view
{:style {:margin-top top
:flex 1}}
[common.top-nav/view] [common.top-nav/view]
[rn/view {:style style/overview-container} [rn/view {:style style/overview-container}
[quo/wallet-overview (temp/wallet-overview-state networks)]] [quo/wallet-overview (temp/wallet-overview-state networks)]]
@ -80,10 +60,7 @@
[rn/flat-list [rn/flat-list
{:style style/accounts-list {:style style/accounts-list
:content-container-style style/accounts-list-container :content-container-style style/accounts-list-container
:data (account-cards {:accounts accounts :data cards
:loading? loading?
:balances balances
:profile-color profile-color})
:horizontal true :horizontal true
:separator [rn/view {:style {:width 12}}] :separator [rn/view {:style {:width 12}}]
:render-fn quo/account-card :render-fn quo/account-card

View File

@ -145,10 +145,6 @@
(reg-root-key-sub :communities/selected-tab :communities/selected-tab) (reg-root-key-sub :communities/selected-tab :communities/selected-tab)
(reg-root-key-sub :contract-communities :contract-communities) (reg-root-key-sub :contract-communities :contract-communities)
;;wallet
(reg-root-key-sub :wallet/tokens :wallet/tokens)
(reg-root-key-sub :wallet/tokens-loading? :wallet/tokens-loading?)
;;activity center ;;activity center
(reg-root-key-sub :activity-center :activity-center) (reg-root-key-sub :activity-center :activity-center)

View File

@ -1,36 +1,19 @@
(ns status-im2.subs.wallet.wallet (ns status-im2.subs.wallet.wallet
(:require [re-frame.core :as re-frame] (:require [re-frame.core :as rf]
[status-im2.contexts.wallet.common.utils :as utils] [status-im2.contexts.wallet.common.utils :as utils]
[utils.number])) [utils.number]))
(defn- calculate-raw-balance (rf/reg-sub
[raw-balance decimals] :wallet/ui
(if-let [n (utils.number/parse-int raw-balance nil)] :<- [:wallet]
(/ n (Math/pow 10 (utils.number/parse-int decimals))) :-> :ui)
0))
(defn- total-per-token (rf/reg-sub
[item] :wallet/tokens-loading?
(reduce (fn [ac balances] :<- [:wallet/ui]
(+ (calculate-raw-balance (:rawBalance balances) :-> :tokens-loading?)
(:decimals item))
ac))
0
(vals (:balancesPerChain item))))
(defn- calculate-balance (rf/reg-sub
[address tokens]
(let [token (get tokens (keyword address))
result (reduce
(fn [acc item]
(let [total-values (* (total-per-token item)
(get-in item [:marketValuesPerCurrency :USD :price]))]
(+ acc total-values)))
0
token)]
result))
(re-frame/reg-sub
:wallet/accounts :wallet/accounts
:<- [:wallet] :<- [:wallet]
:-> #(->> % :-> #(->> %
@ -38,20 +21,33 @@
vals vals
(sort-by :position))) (sort-by :position)))
(re-frame/reg-sub (rf/reg-sub
:wallet/balances :wallet/balances
:<- [:wallet/accounts] :<- [:wallet/accounts]
:<- [:wallet/tokens] (fn [accounts]
(fn [[accounts tokens]] (zipmap (map :address accounts)
(for [{:keys [address]} accounts] (map #(-> % :tokens utils/calculate-balance) accounts))))
{:address address
:balance (calculate-balance address tokens)})))
(re-frame/reg-sub (rf/reg-sub
:wallet/account-cards-data
:<- [:wallet/accounts]
:<- [:wallet/balances]
:<- [:wallet/tokens-loading?]
(fn [[accounts balances tokens-loading?]]
(mapv (fn [{:keys [color address] :as account}]
(assoc account
:customization-color color
:type :empty
:on-press #(rf/dispatch [:wallet/navigate-to-account address])
:loading? tokens-loading?
:balance (utils/prettify-balance (get balances address))))
accounts)))
(rf/reg-sub
:wallet/current-viewing-account :wallet/current-viewing-account
:<- [:wallet] :<- [:wallet]
:<- [:wallet/balances] :<- [:wallet/balances]
(fn [[{:keys [current-viewing-account-address] :as wallet} balances]] (fn [[{:keys [current-viewing-account-address] :as wallet} balances]]
(-> wallet (-> wallet
(get-in [:accounts current-viewing-account-address]) (get-in [:accounts current-viewing-account-address])
(assoc :balance (utils/get-balance-by-address balances current-viewing-account-address))))) (assoc :balance (get balances current-viewing-account-address)))))

View File

@ -8,43 +8,35 @@
(use-fixtures :each (use-fixtures :each
{:before #(reset! rf-db/app-db {})}) {:before #(reset! rf-db/app-db {})})
(def tokens (def tokens-0x1
{:0x1 [{:decimals 1 [{:decimals 1
:symbol "ETH" :symbol "ETH"
:name "Ether" :name "Ether"
:balancesPerChain {:1 {:rawBalance "20" :balances-per-chain {1 {:raw-balance "20" :has-error false}
:hasError false} 2 {:raw-balance "10" :has-error false}}
:2 {:rawBalance "10" :market-values-per-currency {:usd {:price 1000}}}
:hasError false}}
:marketValuesPerCurrency {:USD {:price 1000}}} ;; total should be 3000
{:decimals 2 {:decimals 2
:symbol "DAI" :symbol "DAI"
:name "Dai Stablecoin" :name "Dai Stablecoin"
:balancesPerChain {:1 {:rawBalance "100" :balances-per-chain {1 {:raw-balance "100" :has-error false}
:hasError false} 2 {:raw-balance "150" :has-error false}}
:2 {:rawBalance "150" :market-values-per-currency {:usd {:price 100}}}])
:hasError false}}
:marketValuesPerCurrency {:USD {:price 100}}}] ;; total should be 250 (def tokens-0x2
:0x2 [{:decimals 3 [{:decimals 3
:symbol "ETH" :symbol "ETH"
:name "Ether" :name "Ether"
:balancesPerChain {:1 {:rawBalance "2500" :balances-per-chain {1 {:raw-balance "2500" :has-error false}
:hasError false} 2 {:raw-balance "3000" :has-error false}
:2 {:rawBalance "3000" 3 {:raw-balance "<nil>" :has-error false}}
:hasError false} :market-values-per-currency {:usd {:price 200}}}
:3 {:rawBalance "<nil>"
:hasError false}}
:marketValuesPerCurrency {:USD {:price 200}}} ;; total should be 1100
{:decimals 10 {:decimals 10
:symbol "DAI" :symbol "DAI"
:name "Dai Stablecoin" :name "Dai Stablecoin"
:balancesPerChain {:1 {:rawBalance "10000000000" :balances-per-chain {1 {:raw-balance "10000000000" :has-error false}
:hasError false} 2 {:raw-balance "0" :has-error false}
:2 {:rawBalance "0" 3 {:raw-balance "<nil>" :has-error false}}
:hasError false} :market-values-per-currency {:usd {:price 1000}}}])
:3 {:rawBalance "<nil>"
:hasError false}}
:marketValuesPerCurrency {:USD {:price 1000}}}]}) ;; total should be 1000
(def accounts (def accounts
{"0x1" {:path "m/44'/60'/0'/0/0" {"0x1" {:path "m/44'/60'/0'/0/0"
@ -65,7 +57,8 @@
:operable "fully" :operable "fully"
:mixedcase-address "0x7bcDfc75c431" :mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064" :public-key "0x04371e2d9d66b82f056bc128064"
:removed false} :removed false
:tokens tokens-0x1}
"0x2" {:path "m/44'/60'/0'/0/1" "0x2" {:path "m/44'/60'/0'/0/1"
:emoji "💎" :emoji "💎"
:key-uid "0x2f5ea39" :key-uid "0x2f5ea39"
@ -84,29 +77,24 @@
:operable "fully" :operable "fully"
:mixedcase-address "0x7bcDfc75c431" :mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064" :public-key "0x04371e2d9d66b82f056bc128064"
:removed false}}) :removed false
:tokens tokens-0x2}})
(h/deftest-sub :wallet/balances (h/deftest-sub :wallet/balances
[sub-name] [sub-name]
(testing "returns seq of maps containing :address and :balance" (testing "a map: address->balance"
(swap! rf-db/app-db #(-> % (swap! rf-db/app-db #(assoc-in % [:wallet :accounts] accounts))
(assoc-in [:wallet :accounts] accounts)
(assoc :wallet/tokens tokens))) (is (= {"0x1" 3250 "0x2" 2100}
(is (= `({:address "0x1"
:balance 3250}
{:address "0x2"
:balance 2100})
(rf/sub [sub-name]))))) (rf/sub [sub-name])))))
(h/deftest-sub :wallet/accounts (h/deftest-sub :wallet/accounts
[sub-name] [sub-name]
(testing "returns all accounts without balance" (testing "returns all accounts without balance"
(swap! rf-db/app-db (swap! rf-db/app-db #(assoc-in % [:wallet :accounts] accounts))
#(-> %
(assoc-in [:wallet :accounts] accounts)
(assoc :wallet/tokens tokens)))
(is (is
(= `({:path "m/44'/60'/0'/0/0" (= (list {:path "m/44'/60'/0'/0/0"
:emoji "😃" :emoji "😃"
:key-uid "0x2f5ea39" :key-uid "0x2f5ea39"
:address "0x1" :address "0x1"
@ -124,7 +112,8 @@
:operable "fully" :operable "fully"
:mixedcase-address "0x7bcDfc75c431" :mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064" :public-key "0x04371e2d9d66b82f056bc128064"
:removed false} :removed false
:tokens tokens-0x1}
{:path "m/44'/60'/0'/0/1" {:path "m/44'/60'/0'/0/1"
:emoji "💎" :emoji "💎"
:key-uid "0x2f5ea39" :key-uid "0x2f5ea39"
@ -143,7 +132,8 @@
:operable "fully" :operable "fully"
:mixedcase-address "0x7bcDfc75c431" :mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064" :public-key "0x04371e2d9d66b82f056bc128064"
:removed false}) :removed false
:tokens tokens-0x2})
(rf/sub [sub-name]))))) (rf/sub [sub-name])))))
(h/deftest-sub :wallet/current-viewing-account (h/deftest-sub :wallet/current-viewing-account
@ -152,8 +142,8 @@
(swap! rf-db/app-db (swap! rf-db/app-db
#(-> % #(-> %
(assoc-in [:wallet :accounts] accounts) (assoc-in [:wallet :accounts] accounts)
(assoc-in [:wallet :current-viewing-account-address] "0x1") (assoc-in [:wallet :current-viewing-account-address] "0x1")))
(assoc :wallet/tokens tokens)))
(is (is
(= {:path "m/44'/60'/0'/0/0" (= {:path "m/44'/60'/0'/0/0"
:emoji "😃" :emoji "😃"
@ -174,5 +164,6 @@
:mixedcase-address "0x7bcDfc75c431" :mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064" :public-key "0x04371e2d9d66b82f056bc128064"
:removed false :removed false
:balance 3250} :balance 3250
:tokens tokens-0x1}
(rf/sub [sub-name]))))) (rf/sub [sub-name])))))