Added support for different currencies in wallet accounts price calculation (#18078)
This commit: - adds support for different currencies in token price calculation in the new wallet UI. - fixes the token units and prices displayed in the individual account screen Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
This commit is contained in:
parent
16a52b38e8
commit
ed53fecf47
|
@ -15,5 +15,6 @@
|
||||||
(multiaccounts.update/multiaccount-update
|
(multiaccounts.update/multiaccount-update
|
||||||
:currency
|
:currency
|
||||||
currency
|
currency
|
||||||
{})
|
;; on changing currency, we should fetch tokens prices again
|
||||||
|
{:on-success #(rf/dispatch [:wallet/get-wallet-token])})
|
||||||
(prices/update-prices)))
|
(prices/update-prices)))
|
||||||
|
|
|
@ -105,6 +105,7 @@
|
||||||
|
|
||||||
(def ^:const profile-default-color :blue)
|
(def ^:const profile-default-color :blue)
|
||||||
(def ^:const profile-name-max-length 24)
|
(def ^:const profile-name-max-length 24)
|
||||||
|
(def ^:const profile-default-currency :usd)
|
||||||
|
|
||||||
(def ^:const profile-pictures-show-to-contacts-only 1)
|
(def ^:const profile-pictures-show-to-contacts-only 1)
|
||||||
(def ^:const profile-pictures-show-to-everyone 2)
|
(def ^:const profile-pictures-show-to-everyone 2)
|
||||||
|
|
|
@ -35,11 +35,12 @@
|
||||||
[]
|
[]
|
||||||
(let [selected-tab (reagent/atom first-tab-id)]
|
(let [selected-tab (reagent/atom first-tab-id)]
|
||||||
(fn []
|
(fn []
|
||||||
(let [{:keys [name color balance watch-only?]} (rf/sub [:wallet/current-viewing-account])]
|
(let [{:keys [name color balance watch-only?]} (rf/sub [:wallet/current-viewing-account])
|
||||||
|
currency-symbol (rf/sub [:profile/currency-symbol])]
|
||||||
[rn/view {:style {:flex 1}}
|
[rn/view {:style {:flex 1}}
|
||||||
[account-switcher/view {:on-press #(rf/dispatch [:wallet/close-account-page])}]
|
[account-switcher/view {:on-press #(rf/dispatch [:wallet/close-account-page])}]
|
||||||
[quo/account-overview
|
[quo/account-overview
|
||||||
{:current-value (utils/prettify-balance balance)
|
{:current-value (utils/prettify-balance currency-symbol balance)
|
||||||
:account-name name
|
:account-name name
|
||||||
:account (if watch-only? :watched-address :default)
|
:account (if watch-only? :watched-address :default)
|
||||||
:customization-color color}]
|
:customization-color color}]
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
(first (string/split full-name #" ")))
|
(first (string/split full-name #" ")))
|
||||||
|
|
||||||
(defn prettify-balance
|
(defn prettify-balance
|
||||||
[balance]
|
[currency-symbol balance]
|
||||||
(let [valid-balance? (and balance
|
(let [valid-balance? (and balance
|
||||||
(or (number? balance) (.-toFixed balance)))]
|
(or (number? balance) (.-toFixed balance)))]
|
||||||
(as-> balance $
|
(as-> balance $
|
||||||
(if valid-balance? $ 0)
|
(if valid-balance? $ 0)
|
||||||
(.toFixed $ 2)
|
(.toFixed $ 2)
|
||||||
(str "$" $))))
|
(str currency-symbol $))))
|
||||||
|
|
||||||
(defn get-derivation-path
|
(defn get-derivation-path
|
||||||
[number-of-accounts]
|
[number-of-accounts]
|
||||||
|
@ -60,15 +60,18 @@
|
||||||
|
|
||||||
(defn total-token-fiat-value
|
(defn total-token-fiat-value
|
||||||
"Returns the total token fiat value taking into account all token's chains."
|
"Returns the total token fiat value taking into account all token's chains."
|
||||||
[{:keys [market-values-per-currency] :as token}]
|
[currency {:keys [market-values-per-currency] :as token}]
|
||||||
(let [usd-price (-> market-values-per-currency :usd :price)
|
(let [price (get-in market-values-per-currency
|
||||||
|
[currency :price]
|
||||||
|
(get-in market-values-per-currency
|
||||||
|
[constants/profile-default-currency :price]))
|
||||||
total-units-in-all-chains (total-token-units-in-all-chains token)]
|
total-units-in-all-chains (total-token-units-in-all-chains token)]
|
||||||
(money/crypto->fiat total-units-in-all-chains usd-price)))
|
(money/crypto->fiat total-units-in-all-chains price)))
|
||||||
|
|
||||||
(defn calculate-balance-for-account
|
(defn calculate-balance-for-account
|
||||||
[{:keys [tokens] :as _account}]
|
[currency {:keys [tokens] :as _account}]
|
||||||
(->> tokens
|
(->> tokens
|
||||||
(map total-token-fiat-value)
|
(map #(total-token-fiat-value currency %))
|
||||||
(reduce money/add)))
|
(reduce money/add)))
|
||||||
|
|
||||||
(defn network-list
|
(defn network-list
|
||||||
|
|
|
@ -100,14 +100,21 @@
|
||||||
(let [addresses (->> (get-in db [:wallet :accounts])
|
(let [addresses (->> (get-in db [:wallet :accounts])
|
||||||
vals
|
vals
|
||||||
(map :address))]
|
(map :address))]
|
||||||
{:fx [[:json-rpc/call
|
{:db (assoc-in db [:wallet :ui :tokens-loading?] true)
|
||||||
|
:fx [[:json-rpc/call
|
||||||
[{:method "wallet_getWalletToken"
|
[{:method "wallet_getWalletToken"
|
||||||
:params [addresses]
|
:params [addresses]
|
||||||
:on-success [:wallet/store-wallet-token]
|
:on-success [:wallet/store-wallet-token]
|
||||||
:on-error #(log/info "failed to get wallet token "
|
:on-error [:wallet/get-wallet-token-failed addresses]}]]]})))
|
||||||
{:error %
|
|
||||||
:event :wallet/get-wallet-token
|
(rf/reg-event-fx
|
||||||
:params addresses})}]]]})))
|
:wallet/get-wallet-token-failed
|
||||||
|
(fn [{:keys [db]} [params 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)}))
|
||||||
|
|
||||||
(defn- fix-balances-per-chain
|
(defn- fix-balances-per-chain
|
||||||
[token]
|
[token]
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
(let [on-press #(js/alert "Not implemented yet")
|
(let [on-press #(js/alert "Not implemented yet")
|
||||||
total-balance-formatted (.toFixed (:total-balance token) 2)
|
total-balance-formatted (.toFixed (:total-balance token) 2)
|
||||||
balance-fiat-formatted (.toFixed (:total-balance-fiat token) 2)
|
balance-fiat-formatted (.toFixed (:total-balance-fiat token) 2)
|
||||||
currency-symbol "$"]
|
currency-symbol (rf/sub [:profile/currency-symbol])]
|
||||||
[quo/token-network
|
[quo/token-network
|
||||||
{:token (:symbol token)
|
{:token (:symbol token)
|
||||||
:label (:name token)
|
:label (:name token)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.fleet.core :as fleet]
|
[status-im.fleet.core :as fleet]
|
||||||
[status-im.multiaccounts.db :as multiaccounts.db]
|
[status-im.multiaccounts.db :as multiaccounts.db]
|
||||||
|
[status-im.utils.currency :as currency]
|
||||||
[status-im.wallet.utils :as wallet.utils]
|
[status-im.wallet.utils :as wallet.utils]
|
||||||
[status-im2.constants :as constants]
|
[status-im2.constants :as constants]
|
||||||
[utils.address :as address]
|
[utils.address :as address]
|
||||||
|
@ -18,6 +19,19 @@
|
||||||
(fn [{:keys [customization-color]}]
|
(fn [{:keys [customization-color]}]
|
||||||
(or customization-color constants/profile-default-color)))
|
(or customization-color constants/profile-default-color)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
:profile/currency
|
||||||
|
:<- [:profile/profile]
|
||||||
|
(fn [{:keys [currency]}]
|
||||||
|
(or currency constants/profile-default-currency)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
:profile/currency-symbol
|
||||||
|
:<- [:profile/currency]
|
||||||
|
(fn [currency-id]
|
||||||
|
(-> (get currency/currencies currency-id)
|
||||||
|
:symbol)))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:profile/onboarding-placeholder-avatar
|
:profile/onboarding-placeholder-avatar
|
||||||
:<- [:mediaserver/port]
|
:<- [:mediaserver/port]
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
(ns status-im2.subs.profile-test
|
||||||
|
(:require [cljs.test :refer [is testing use-fixtures]]
|
||||||
|
[re-frame.db :as rf-db]
|
||||||
|
status-im2.subs.root
|
||||||
|
[test-helpers.unit :as h]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(use-fixtures :each
|
||||||
|
{:before #(reset! rf-db/app-db {})})
|
||||||
|
|
||||||
|
(def sample-profile
|
||||||
|
{:keycard-pairing nil
|
||||||
|
:send-push-notifications? true
|
||||||
|
:send-status-updates? true
|
||||||
|
:key-uid "0x2285f5c1ffd94ade0aa3568bff85f6c06f2860391ba65ccf56276cbc6829a22a"
|
||||||
|
:backup-enabled? true
|
||||||
|
:address "0x70F8913fbE0Ca5687F1Fb73068944d6e99B27804"
|
||||||
|
:mnemonic "lucky veteran business source debris large priority color endless answer strong pave"
|
||||||
|
:preview-privacy? true
|
||||||
|
:identicon ""
|
||||||
|
:use-mailservers? true
|
||||||
|
:signing-phrase "polo rush vest"
|
||||||
|
:url-unfurling-mode 1
|
||||||
|
:custom-bootnodes-enabled? {}
|
||||||
|
:log-level "INFO"
|
||||||
|
:profile-pictures-visibility 2
|
||||||
|
:messages-from-contacts-only false
|
||||||
|
:pinned-mailservers {}
|
||||||
|
:eip1581-address "0x15636c0aa4036b9f984e8998db085328795b26d8"
|
||||||
|
:images [{:keyUid "0x2285f5c1ffd94ade0aa3568bff85f6c06f2860391ba65ccf56276cbc6829a22a"
|
||||||
|
:type "large"
|
||||||
|
:uri "data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJC="
|
||||||
|
:width 240
|
||||||
|
:height 240
|
||||||
|
:fileSize 15973
|
||||||
|
:resizeTarget 240
|
||||||
|
:clock 0}
|
||||||
|
{:keyUid "0x2285f5c1ffd94ade0aa3568bff85f6c06f2860391ba65ccf56276cbc6829a22a"
|
||||||
|
:type "thumbnail"
|
||||||
|
:uri "data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJC="
|
||||||
|
:width 80
|
||||||
|
:height 240
|
||||||
|
:fileSize 2558
|
||||||
|
:resizeTarget 80
|
||||||
|
:clock 0}]
|
||||||
|
:name "Plush Shiny Songbird"
|
||||||
|
:latest-derived-path 0
|
||||||
|
:compressed-key "zQ3shS6tp3NsQT4RSUFtnTqnBQzC5kt2SZzxZmnPEiNkHetwj"
|
||||||
|
:wallet-legacy/visible-tokens {:mainnet #{:SNT}}
|
||||||
|
:kdfIterations 3200
|
||||||
|
:ens-name? false
|
||||||
|
:emoji-hash ["👮" "🧑🏿🏭" "📬" "👰♀️" "🦚" "💳" "👨🏿🍳" "☝️" "🤰🏾" "🍊" "☁️" "☔" "👷🏽" "🤹🏾"]
|
||||||
|
:wallet-root-address "0x704c9a261b918cb8e522f7fc2bc477c12d0c74ac"
|
||||||
|
:last-backup 1701832050
|
||||||
|
:link-previews-enabled-sites #{}
|
||||||
|
:networks/networks {}
|
||||||
|
:wakuv2-config {:Port 0
|
||||||
|
:DataDir ""
|
||||||
|
:LightClient true
|
||||||
|
:AutoUpdate true
|
||||||
|
:MaxMessageSize 0
|
||||||
|
:KeepAliveInterval 0
|
||||||
|
:Nameserver ""
|
||||||
|
:UseShardAsDefaultTopic false
|
||||||
|
:PeerExchange true
|
||||||
|
:StoreCapacity 0
|
||||||
|
:UDPPort 0
|
||||||
|
:EnableStore false
|
||||||
|
:EnableFilterFullNode false
|
||||||
|
:Enabled true
|
||||||
|
:EnableConfirmations false
|
||||||
|
:Host "0.0.0.0"
|
||||||
|
:CustomNodes {}
|
||||||
|
:FullNode false
|
||||||
|
:EnableDiscV5 true
|
||||||
|
:DiscoveryLimit 20
|
||||||
|
:StoreSeconds 0}
|
||||||
|
:current-user-visibility-status {:clock 1701798568
|
||||||
|
:text ""
|
||||||
|
:status-type 1}
|
||||||
|
:gifs/api-key ""
|
||||||
|
:currency :usd
|
||||||
|
:gifs/favorite-gifs nil
|
||||||
|
:customization-color :magenta
|
||||||
|
:default-sync-period 777600
|
||||||
|
:photo-path ""
|
||||||
|
:dapps-address "0x52fB56556A039244CED121AFB9ec829788Db78c8"
|
||||||
|
:custom-bootnodes {}
|
||||||
|
:display-name "Alisher Y"
|
||||||
|
:gifs/recent-gifs nil
|
||||||
|
:appearance 0
|
||||||
|
:link-preview-request-enabled true
|
||||||
|
:profile-pictures-show-to 2
|
||||||
|
:timestamp 1701798892
|
||||||
|
:device-name ""
|
||||||
|
:colorId 2
|
||||||
|
:networks/current-network "mainnet_rpc"
|
||||||
|
:mutual-contact-enabled? false
|
||||||
|
:public-key
|
||||||
|
"0x0445b4d3a20f9fcf95b9e669857f83a073e7fdb7b79d0ac03ffb601d6889c413fa86282a2b2bed46ecf7d499807c1567549367a4eaa2b7b925067d44562d93cfa6"
|
||||||
|
:colorHash [[3 25] [4 3] [5 4] [2 0] [1 10] [5 2] [2 4] [1 17] [3 23] [2 19] [4 1]]
|
||||||
|
:installation-id "cee7e269-1ca7-4468-a1dd-e60e5cfb0894"})
|
||||||
|
|
||||||
|
(h/deftest-sub :profile/currency
|
||||||
|
[sub-name]
|
||||||
|
(testing "returns the selected currency of user"
|
||||||
|
(swap! rf-db/app-db #(assoc % :profile/profile sample-profile))
|
||||||
|
(is (match? :usd (rf/sub [sub-name])))))
|
||||||
|
|
||||||
|
(h/deftest-sub :profile/currency-symbol
|
||||||
|
[sub-name]
|
||||||
|
(testing "returns the symbol of the user's selected currency"
|
||||||
|
(swap! rf-db/app-db #(assoc % :profile/profile sample-profile))
|
||||||
|
(is (match? "$" (rf/sub [sub-name])))))
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im2.subs.wallet.wallet
|
(ns status-im2.subs.wallet.wallet
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
[re-frame.core :as rf]
|
[re-frame.core :as rf]
|
||||||
|
[status-im2.constants :as constants]
|
||||||
[status-im2.contexts.wallet.common.utils :as utils]
|
[status-im2.contexts.wallet.common.utils :as utils]
|
||||||
[utils.number]))
|
[utils.number]))
|
||||||
|
|
||||||
|
@ -69,23 +70,25 @@
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/balances
|
:wallet/balances
|
||||||
:<- [:wallet/accounts]
|
:<- [:wallet/accounts]
|
||||||
(fn [accounts]
|
:<- [:profile/currency]
|
||||||
|
(fn [[accounts currency]]
|
||||||
(zipmap (map :address accounts)
|
(zipmap (map :address accounts)
|
||||||
(map utils/calculate-balance-for-account accounts))))
|
(map #(utils/calculate-balance-for-account currency %) accounts))))
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/account-cards-data
|
:wallet/account-cards-data
|
||||||
:<- [:wallet/accounts]
|
:<- [:wallet/accounts]
|
||||||
:<- [:wallet/balances]
|
:<- [:wallet/balances]
|
||||||
:<- [:wallet/tokens-loading?]
|
:<- [:wallet/tokens-loading?]
|
||||||
(fn [[accounts balances tokens-loading?]]
|
:<- [:profile/currency-symbol]
|
||||||
|
(fn [[accounts balances tokens-loading? currency-symbol]]
|
||||||
(mapv (fn [{:keys [color address watch-only?] :as account}]
|
(mapv (fn [{:keys [color address watch-only?] :as account}]
|
||||||
(assoc account
|
(assoc account
|
||||||
:customization-color color
|
:customization-color color
|
||||||
:type (if watch-only? :watch-only :empty)
|
:type (if watch-only? :watch-only :empty)
|
||||||
:on-press #(rf/dispatch [:wallet/navigate-to-account address])
|
:on-press #(rf/dispatch [:wallet/navigate-to-account address])
|
||||||
:loading? tokens-loading?
|
:loading? tokens-loading?
|
||||||
:balance (utils/prettify-balance (get balances address))))
|
:balance (utils/prettify-balance currency-symbol (get balances address))))
|
||||||
accounts)))
|
accounts)))
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
|
@ -131,31 +134,32 @@
|
||||||
(remove #(:watch-only? %) accounts)))
|
(remove #(:watch-only? %) accounts)))
|
||||||
|
|
||||||
(defn- calc-token-value
|
(defn- calc-token-value
|
||||||
[{:keys [market-values-per-currency] :as item} chain-id]
|
[{:keys [market-values-per-currency] :as token} color currency currency-symbol]
|
||||||
(let [crypto-value (utils/token-value-in-chain item chain-id)
|
(let [token-units (utils/total-token-units-in-all-chains token)
|
||||||
market-values (:usd market-values-per-currency)
|
fiat-value (utils/total-token-fiat-value currency token)
|
||||||
{:keys [price change-pct-24hour]} market-values
|
market-values (get market-values-per-currency
|
||||||
fiat-change (utils/calculate-fiat-change crypto-value change-pct-24hour)]
|
currency
|
||||||
(when (and crypto-value (seq (:name item)))
|
(get market-values-per-currency
|
||||||
{:token (keyword (string/lower-case (:symbol item)))
|
constants/profile-default-currency))
|
||||||
:token-name (:name item)
|
{:keys [change-pct-24hour]} market-values]
|
||||||
:state :default
|
{:token (:symbol token)
|
||||||
:status (cond
|
:token-name (:name token)
|
||||||
(pos? change-pct-24hour) :positive
|
:state :default
|
||||||
(neg? change-pct-24hour) :negative
|
:status (cond
|
||||||
:else :empty)
|
(pos? change-pct-24hour) :positive
|
||||||
:customization-color :blue
|
(neg? change-pct-24hour) :negative
|
||||||
:values {:crypto-value crypto-value
|
:else :empty)
|
||||||
:fiat-value (utils/prettify-balance (* crypto-value price))
|
:customization-color color
|
||||||
:percentage-change (.toFixed change-pct-24hour 2)
|
:values {:crypto-value token-units
|
||||||
:fiat-change (utils/prettify-balance fiat-change)}})))
|
:fiat-value (utils/prettify-balance currency-symbol fiat-value)}}))
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/account-token-values
|
:wallet/account-token-values
|
||||||
:<- [:wallet/current-viewing-account]
|
:<- [:wallet/current-viewing-account]
|
||||||
:<- [:chain-id]
|
:<- [:profile/currency]
|
||||||
(fn [[current-account chain-id]]
|
:<- [:profile/currency-symbol]
|
||||||
(mapv #(calc-token-value % chain-id) (:tokens current-account))))
|
(fn [[{:keys [tokens color]} currency currency-symbol]]
|
||||||
|
(mapv #(calc-token-value % color currency currency-symbol) tokens)))
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/network-preference-details
|
:wallet/network-preference-details
|
||||||
|
|
Loading…
Reference in New Issue