* 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:
parent
a74c934936
commit
45df308dd0
|
@ -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
|
||||||
|
|
|
@ -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 +)))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)))))
|
||||||
|
|
|
@ -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])))))
|
||||||
|
|
Loading…
Reference in New Issue