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
|
||||
:currency
|
||||
currency
|
||||
{})
|
||||
;; on changing currency, we should fetch tokens prices again
|
||||
{:on-success #(rf/dispatch [:wallet/get-wallet-token])})
|
||||
(prices/update-prices)))
|
||||
|
|
|
@ -105,6 +105,7 @@
|
|||
|
||||
(def ^:const profile-default-color :blue)
|
||||
(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-everyone 2)
|
||||
|
|
|
@ -35,11 +35,12 @@
|
|||
[]
|
||||
(let [selected-tab (reagent/atom first-tab-id)]
|
||||
(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}}
|
||||
[account-switcher/view {:on-press #(rf/dispatch [:wallet/close-account-page])}]
|
||||
[quo/account-overview
|
||||
{:current-value (utils/prettify-balance balance)
|
||||
{:current-value (utils/prettify-balance currency-symbol balance)
|
||||
:account-name name
|
||||
:account (if watch-only? :watched-address :default)
|
||||
:customization-color color}]
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
(first (string/split full-name #" ")))
|
||||
|
||||
(defn prettify-balance
|
||||
[balance]
|
||||
[currency-symbol balance]
|
||||
(let [valid-balance? (and balance
|
||||
(or (number? balance) (.-toFixed balance)))]
|
||||
(as-> balance $
|
||||
(if valid-balance? $ 0)
|
||||
(.toFixed $ 2)
|
||||
(str "$" $))))
|
||||
(str currency-symbol $))))
|
||||
|
||||
(defn get-derivation-path
|
||||
[number-of-accounts]
|
||||
|
@ -60,15 +60,18 @@
|
|||
|
||||
(defn total-token-fiat-value
|
||||
"Returns the total token fiat value taking into account all token's chains."
|
||||
[{:keys [market-values-per-currency] :as token}]
|
||||
(let [usd-price (-> market-values-per-currency :usd :price)
|
||||
[currency {:keys [market-values-per-currency] :as token}]
|
||||
(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)]
|
||||
(money/crypto->fiat total-units-in-all-chains usd-price)))
|
||||
(money/crypto->fiat total-units-in-all-chains price)))
|
||||
|
||||
(defn calculate-balance-for-account
|
||||
[{:keys [tokens] :as _account}]
|
||||
[currency {:keys [tokens] :as _account}]
|
||||
(->> tokens
|
||||
(map total-token-fiat-value)
|
||||
(map #(total-token-fiat-value currency %))
|
||||
(reduce money/add)))
|
||||
|
||||
(defn network-list
|
||||
|
|
|
@ -100,14 +100,21 @@
|
|||
(let [addresses (->> (get-in db [:wallet :accounts])
|
||||
vals
|
||||
(map :address))]
|
||||
{:fx [[:json-rpc/call
|
||||
{: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 #(log/info "failed to get wallet token "
|
||||
{:error %
|
||||
:event :wallet/get-wallet-token
|
||||
:params addresses})}]]]})))
|
||||
:on-error [:wallet/get-wallet-token-failed addresses]}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
: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
|
||||
[token]
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
(let [on-press #(js/alert "Not implemented yet")
|
||||
total-balance-formatted (.toFixed (:total-balance token) 2)
|
||||
balance-fiat-formatted (.toFixed (:total-balance-fiat token) 2)
|
||||
currency-symbol "$"]
|
||||
currency-symbol (rf/sub [:profile/currency-symbol])]
|
||||
[quo/token-network
|
||||
{:token (:symbol token)
|
||||
:label (:name token)
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
[re-frame.core :as re-frame]
|
||||
[status-im.fleet.core :as fleet]
|
||||
[status-im.multiaccounts.db :as multiaccounts.db]
|
||||
[status-im.utils.currency :as currency]
|
||||
[status-im.wallet.utils :as wallet.utils]
|
||||
[status-im2.constants :as constants]
|
||||
[utils.address :as address]
|
||||
|
@ -18,6 +19,19 @@
|
|||
(fn [{:keys [customization-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
|
||||
:profile/onboarding-placeholder-avatar
|
||||
:<- [: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
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as rf]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.wallet.common.utils :as utils]
|
||||
[utils.number]))
|
||||
|
||||
|
@ -69,23 +70,25 @@
|
|||
(rf/reg-sub
|
||||
:wallet/balances
|
||||
:<- [:wallet/accounts]
|
||||
(fn [accounts]
|
||||
:<- [:profile/currency]
|
||||
(fn [[accounts currency]]
|
||||
(zipmap (map :address accounts)
|
||||
(map utils/calculate-balance-for-account accounts))))
|
||||
(map #(utils/calculate-balance-for-account currency %) accounts))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/account-cards-data
|
||||
:<- [:wallet/accounts]
|
||||
:<- [:wallet/balances]
|
||||
:<- [: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}]
|
||||
(assoc account
|
||||
:customization-color color
|
||||
:type (if watch-only? :watch-only :empty)
|
||||
:on-press #(rf/dispatch [:wallet/navigate-to-account address])
|
||||
:loading? tokens-loading?
|
||||
:balance (utils/prettify-balance (get balances address))))
|
||||
:balance (utils/prettify-balance currency-symbol (get balances address))))
|
||||
accounts)))
|
||||
|
||||
(rf/reg-sub
|
||||
|
@ -131,31 +134,32 @@
|
|||
(remove #(:watch-only? %) accounts)))
|
||||
|
||||
(defn- calc-token-value
|
||||
[{:keys [market-values-per-currency] :as item} chain-id]
|
||||
(let [crypto-value (utils/token-value-in-chain item chain-id)
|
||||
market-values (:usd market-values-per-currency)
|
||||
{:keys [price change-pct-24hour]} market-values
|
||||
fiat-change (utils/calculate-fiat-change crypto-value change-pct-24hour)]
|
||||
(when (and crypto-value (seq (:name item)))
|
||||
{:token (keyword (string/lower-case (:symbol item)))
|
||||
:token-name (:name item)
|
||||
:state :default
|
||||
:status (cond
|
||||
(pos? change-pct-24hour) :positive
|
||||
(neg? change-pct-24hour) :negative
|
||||
:else :empty)
|
||||
:customization-color :blue
|
||||
:values {:crypto-value crypto-value
|
||||
:fiat-value (utils/prettify-balance (* crypto-value price))
|
||||
:percentage-change (.toFixed change-pct-24hour 2)
|
||||
:fiat-change (utils/prettify-balance fiat-change)}})))
|
||||
[{:keys [market-values-per-currency] :as token} color currency currency-symbol]
|
||||
(let [token-units (utils/total-token-units-in-all-chains token)
|
||||
fiat-value (utils/total-token-fiat-value currency token)
|
||||
market-values (get market-values-per-currency
|
||||
currency
|
||||
(get market-values-per-currency
|
||||
constants/profile-default-currency))
|
||||
{:keys [change-pct-24hour]} market-values]
|
||||
{:token (:symbol token)
|
||||
:token-name (:name token)
|
||||
:state :default
|
||||
:status (cond
|
||||
(pos? change-pct-24hour) :positive
|
||||
(neg? change-pct-24hour) :negative
|
||||
:else :empty)
|
||||
:customization-color color
|
||||
:values {:crypto-value token-units
|
||||
:fiat-value (utils/prettify-balance currency-symbol fiat-value)}}))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/account-token-values
|
||||
:<- [:wallet/current-viewing-account]
|
||||
:<- [:chain-id]
|
||||
(fn [[current-account chain-id]]
|
||||
(mapv #(calc-token-value % chain-id) (:tokens current-account))))
|
||||
:<- [:profile/currency]
|
||||
:<- [:profile/currency-symbol]
|
||||
(fn [[{:keys [tokens color]} currency currency-symbol]]
|
||||
(mapv #(calc-token-value % color currency currency-symbol) tokens)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/network-preference-details
|
||||
|
|
Loading…
Reference in New Issue