[Feature] Wallet - Network based assets and fiat balance calculation (#19150)
This commit: (UI changes) - adds the feature to filter assets (tokens and collectibles) and balances based on networks - fixes network color for eth not shown on the multichain address (e.g. Account Options bottom sheet) - fixes blur type in the confirm button in the network preferences sheet - fixes the User ability to unselect all networks in the network preferences sheet - fixes account address and color not shown in network-preferences sheet on Shell > Share Multichain address - added STT token image (Non-UI changes) - Refactors the functions used for balance calculations and network details Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
This commit is contained in:
parent
5fc23816a6
commit
9ba6c6262e
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
|
@ -456,7 +456,9 @@
|
|||
(def ^:const optimism-network-name :optimism)
|
||||
(def ^:const arbitrum-network-name :arbitrum)
|
||||
|
||||
(def ^:const default-network-names #{mainnet-network-name optimism-network-name arbitrum-network-name})
|
||||
(def ^:const default-network-names [mainnet-network-name optimism-network-name arbitrum-network-name])
|
||||
|
||||
(def ^:const default-network-count (count default-network-names))
|
||||
|
||||
(def ^:const chain-id-separator ":")
|
||||
|
||||
|
|
|
@ -33,7 +33,10 @@
|
|||
(assoc :test-ID stack-id
|
||||
:icon icon
|
||||
:icon-color-anim icon-color
|
||||
:on-press #(animation/bottom-tab-on-press stack-id true)
|
||||
:on-press (fn []
|
||||
(when-not (= stack-id :wallet-stack)
|
||||
(rf/dispatch [:wallet/reset-selected-networks]))
|
||||
(animation/bottom-tab-on-press stack-id true))
|
||||
:accessibility-label (str (name stack-id) "-tab")
|
||||
:customization-color customization-color))]))
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
[status-im.contexts.shell.jump-to.constants :as shell.constants]
|
||||
[status-im.contexts.shell.jump-to.state :as state]
|
||||
[status-im.contexts.shell.jump-to.utils :as utils]
|
||||
[status-im.contexts.wallet.home.view :as wallet-new]
|
||||
[status-im.contexts.wallet.home.view :as wallet]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn load-stack?
|
||||
|
@ -32,7 +32,7 @@
|
|||
(case stack-id
|
||||
:communities-stack [:f> communities/view]
|
||||
:chats-stack [:f> chat/view]
|
||||
:wallet-stack [wallet-new/view]
|
||||
:wallet-stack [wallet/view]
|
||||
:browser-stack [browser.stack/browser-stack]
|
||||
[:<>])])
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
:on-text-long-press #(rf/dispatch [:share/copy-text-and-show-toast
|
||||
{:text-to-copy universal-profile-url
|
||||
:post-copy-message (i18n/label :t/link-to-profile-copied)}])
|
||||
:profile-picture (:uri (profile.utils/photo profile))
|
||||
:profile-picture (profile.utils/photo profile)
|
||||
:full-name (profile.utils/displayed-name profile)
|
||||
:customization-color customization-color}]]
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
[react-native.platform :as platform]
|
||||
[react-native.share :as share]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.shell.share.style :as style]
|
||||
[status-im.contexts.shell.share.wallet.style :as wallet-style]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
|
@ -33,25 +34,28 @@
|
|||
:isNewTask true})))
|
||||
|
||||
(defn- open-preferences
|
||||
[selected-networks]
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:content
|
||||
(fn []
|
||||
[network-preferences/view
|
||||
{:blur? true
|
||||
:selected-networks (set @selected-networks)
|
||||
:on-save (fn [chain-ids]
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(reset! selected-networks (map #(get utils/id->network %)
|
||||
chain-ids)))}])}]))
|
||||
[selected-networks account]
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:content (fn []
|
||||
[network-preferences/view
|
||||
{:blur? true
|
||||
:selected-networks (set @selected-networks)
|
||||
:account account
|
||||
:button-label (i18n/label :t/display)
|
||||
:on-save (fn [chain-ids]
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(reset! selected-networks (map #(get utils/id->network %)
|
||||
chain-ids)))}])}]))
|
||||
|
||||
(defn- wallet-qr-code-item
|
||||
[{:keys [account index]}]
|
||||
(let [{window-width :width} (rn/get-window)
|
||||
selected-networks (reagent/atom [:ethereum :optimism :arbitrum])
|
||||
selected-networks (reagent/atom constants/default-network-names)
|
||||
wallet-type (reagent/atom :legacy)
|
||||
on-settings-press #(open-preferences selected-networks)
|
||||
on-settings-press #(open-preferences selected-networks account)
|
||||
on-legacy-press #(reset! wallet-type :legacy)
|
||||
on-multichain-press #(reset! wallet-type :multichain)]
|
||||
(fn []
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
[react-native.safe-area :as safe-area]
|
||||
[react-native.share :as share]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.account.share-address.style :as style]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.sheets.network-preferences.view :as network-preferences]
|
||||
|
@ -34,13 +35,13 @@
|
|||
[selected-networks]
|
||||
(let [on-save (fn [chain-ids]
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(reset! selected-networks (map #(if (= % 1) :mainnet (utils/id->network %))
|
||||
chain-ids)))
|
||||
(reset! selected-networks (map utils/id->network chain-ids)))
|
||||
sheet-content (fn []
|
||||
[network-preferences/view
|
||||
{:blur? true
|
||||
:selected-networks (set @selected-networks)
|
||||
:on-save on-save}])]
|
||||
:on-save on-save
|
||||
:button-label (i18n/label :t/display)}])]
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
|
@ -53,7 +54,7 @@
|
|||
wallet-type (reagent/atom :legacy)
|
||||
;; Design team is yet to confirm the default selected networks here. Should be the current
|
||||
;; selected for the account or all the networks always
|
||||
selected-networks (reagent/atom [:mainnet :optimism :arbitrum])
|
||||
selected-networks (reagent/atom constants/default-network-names)
|
||||
on-settings-press #(open-preferences selected-networks)
|
||||
on-legacy-press #(reset! wallet-type :legacy)
|
||||
on-multichain-press #(reset! wallet-type :multichain)]
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
|
||||
(defn view
|
||||
[]
|
||||
(let [tokens-loading? (rf/sub [:wallet/tokens-loading?])
|
||||
tokens (rf/sub [:wallet/account-token-values])]
|
||||
(let [tokens-loading? (rf/sub [:wallet/tokens-loading?])
|
||||
tokens (rf/sub [:wallet/current-viewing-account-token-values])
|
||||
{:keys [watch-only?]} (rf/sub [:wallet/current-viewing-account])]
|
||||
(if tokens-loading?
|
||||
[quo/skeleton-list
|
||||
{:content :assets
|
||||
|
@ -18,4 +19,5 @@
|
|||
{:render-fn token-value/view
|
||||
:style {:flex 1}
|
||||
:data tokens
|
||||
:render-data {:watch-only? watch-only?}
|
||||
:content-container-style {:padding-horizontal 8}}])))
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
(defn view
|
||||
[{:keys [selected-tab]}]
|
||||
(let [collectible-list (rf/sub [:wallet/current-viewing-account-collectibles])]
|
||||
(let [collectible-list (rf/sub [:wallet/current-viewing-account-collectibles-in-selected-networks])]
|
||||
[rn/view {:style {:flex 1}}
|
||||
(case selected-tab
|
||||
:assets [assets/view]
|
||||
|
|
|
@ -14,20 +14,20 @@
|
|||
(defn- bridge-token-component
|
||||
[]
|
||||
(fn [{:keys [chain-id network-name]} token]
|
||||
(let [network (rf/sub [:wallet/network-details-by-chain-id chain-id])
|
||||
currency (rf/sub [:profile/currency])
|
||||
currency-symbol (rf/sub [:profile/currency-symbol])
|
||||
all-balances (:balances-per-chain token)
|
||||
balance-for-chain (utils/get-balance-for-chain all-balances chain-id)
|
||||
crypto-formatted (or (:balance balance-for-chain) "0.00")
|
||||
fiat-value (utils/token-fiat-value currency
|
||||
(or (:balance balance-for-chain) 0)
|
||||
token)
|
||||
fiat-formatted (utils/get-standard-fiat-format crypto-formatted currency-symbol fiat-value)]
|
||||
(let [network (rf/sub [:wallet/network-details-by-chain-id chain-id])
|
||||
currency (rf/sub [:profile/currency])
|
||||
currency-symbol (rf/sub [:profile/currency-symbol])
|
||||
balance (utils/calculate-total-token-balance token [chain-id])
|
||||
crypto-value (utils/get-standard-crypto-format token balance)
|
||||
fiat-value (utils/calculate-token-fiat-value
|
||||
{:currency currency
|
||||
:balance balance
|
||||
:token token})
|
||||
fiat-formatted (utils/get-standard-fiat-format crypto-value currency-symbol fiat-value)]
|
||||
[quo/network-list
|
||||
{:label (name network-name)
|
||||
:network-image (quo.resources/get-network (:network-name network))
|
||||
:token-value (str crypto-formatted " " (:symbol token))
|
||||
:token-value (str crypto-value " " (:symbol token))
|
||||
:fiat-value fiat-formatted
|
||||
:on-press #(rf/dispatch [:wallet/select-bridge-network
|
||||
{:network-chain-id chain-id
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
(ns status-im.contexts.wallet.common.account-switcher.view
|
||||
(:require [quo.core :as quo]
|
||||
[status-im.contexts.wallet.sheets.account-options.view :as account-options]
|
||||
[status-im.contexts.wallet.sheets.network-filter.view :as network-filter]
|
||||
[status-im.contexts.wallet.sheets.select-account.view :as select-account]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.re-frame :as rf]))
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[status-im.contexts.wallet.sheets.account-options.view :as account-options]
|
||||
[status-im.contexts.wallet.sheets.network-filter.view :as network-filter]
|
||||
[status-im.contexts.wallet.sheets.select-account.view :as select-account]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn get-bottom-sheet-args
|
||||
[switcher-type]
|
||||
|
@ -20,7 +20,7 @@
|
|||
accessibility-label :top-bar
|
||||
switcher-type :account-options}}]
|
||||
(let [{:keys [color emoji watch-only?]} (rf/sub [:wallet/current-viewing-account])
|
||||
networks (rf/sub [:wallet/network-details])]
|
||||
networks (rf/sub [:wallet/selected-network-details])]
|
||||
[quo/page-nav
|
||||
{:type (or type :no-title)
|
||||
:icon-name icon-name
|
||||
|
@ -29,10 +29,7 @@
|
|||
:on-press on-press
|
||||
:accessibility-label accessibility-label
|
||||
:networks networks
|
||||
:networks-on-press #(ff/alert ::ff/wallet.network-filter
|
||||
(fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content network-filter/view}])))
|
||||
:networks-on-press #(rf/dispatch [:show-bottom-sheet {:content network-filter/view}])
|
||||
:right-side :account-switcher
|
||||
:account-switcher {:customization-color color
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
|
|
|
@ -6,10 +6,12 @@
|
|||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- asset-component
|
||||
[token _ _ {:keys [currency currency-symbol on-token-press]}]
|
||||
(let [token-units (utils/total-token-units-in-all-chains token)
|
||||
crypto-formatted (utils/get-standard-crypto-format token token-units)
|
||||
fiat-value (utils/total-token-fiat-value currency token)
|
||||
[{:keys [total-balance] :as token} _ _ {:keys [currency currency-symbol on-token-press]}]
|
||||
(let [fiat-value (utils/calculate-token-fiat-value
|
||||
{:currency currency
|
||||
:balance total-balance
|
||||
:token token})
|
||||
crypto-formatted (utils/get-standard-crypto-format token total-balance)
|
||||
fiat-formatted (utils/get-standard-fiat-format crypto-formatted currency-symbol fiat-value)]
|
||||
[quo/token-network
|
||||
{:token (:symbol token)
|
||||
|
@ -21,7 +23,7 @@
|
|||
|
||||
(defn view
|
||||
[{:keys [search-text on-token-press]}]
|
||||
(let [filtered-tokens (rf/sub [:wallet/tokens-filtered search-text])
|
||||
(let [filtered-tokens (rf/sub [:wallet/current-viewing-account-tokens-filtered search-text])
|
||||
currency (rf/sub [:profile/currency])
|
||||
currency-symbol (rf/sub [:profile/currency-symbol])]
|
||||
[rn/flat-list
|
||||
|
|
|
@ -43,37 +43,3 @@
|
|||
:image :icon-avatar
|
||||
:image-props {:icon (status.resources/get-service-image :latamex)}
|
||||
:on-press #(rn/open-url "https://latamex.com")}])
|
||||
|
||||
(defn bridge-token-list
|
||||
[networks-list]
|
||||
[{:token :snt
|
||||
:name "Status"
|
||||
:token-value "0.00 SNT"
|
||||
:fiat-value "€0.00"
|
||||
:networks networks-list
|
||||
:state :default
|
||||
:symbol "STT"
|
||||
:customization-color :blue}
|
||||
{:token :eth
|
||||
:name "Ethereum"
|
||||
:token-value "0.00 ETH"
|
||||
:fiat-value "€0.00"
|
||||
:networks networks-list
|
||||
:state :default
|
||||
:symbol "ETH"
|
||||
:customization-color :blue}
|
||||
{:token :dai
|
||||
:name "Dai"
|
||||
:token-value "0.00 DAI"
|
||||
:fiat-value "€0.00"
|
||||
:networks networks-list
|
||||
:state :default
|
||||
:symbol "DAI"
|
||||
:customization-color :blue}])
|
||||
|
||||
(def secret-phrase
|
||||
["witch" "collapse" "practice" "feed" "shame" "open" "lion"
|
||||
"collapse" "umbrella" "fabric" "sadness" "obligue"])
|
||||
(def random-words
|
||||
["cousin" "roof" "minute" "swallow" "wing" "motion" "stomach"
|
||||
"abuse" "banner" "noble" "poet" "wrist"])
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
(defn token-value-drawer
|
||||
[token]
|
||||
(let [token-data (first (rf/sub [:wallet/tokens-filtered (:token token)]))]
|
||||
(let [token-data (first (rf/sub [:wallet/current-viewing-account-tokens-filtered (:token token)]))]
|
||||
[:<>
|
||||
[quo/action-drawer
|
||||
[[{:icon :i/buy
|
||||
|
@ -41,13 +41,12 @@
|
|||
:on-press #(js/alert "to be implemented")}]]]]))
|
||||
|
||||
(defn view
|
||||
[item]
|
||||
(let [{:keys [watch-only?]} (rf/sub [:wallet/current-viewing-account])]
|
||||
[quo/token-value
|
||||
(cond-> item
|
||||
(not watch-only?)
|
||||
(assoc :on-long-press
|
||||
#(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn [] [token-value-drawer item])
|
||||
:selected-item (fn [] [quo/token-value item])}])))]))
|
||||
[item _ _ {:keys [watch-only?]}]
|
||||
[quo/token-value
|
||||
(cond-> item
|
||||
(not watch-only?)
|
||||
(assoc :on-long-press
|
||||
#(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn [] [token-value-drawer item])
|
||||
:selected-item (fn [] [quo/token-value item])}])))])
|
||||
|
|
|
@ -86,61 +86,48 @@
|
|||
(str "<" (remove-trailing-zeroes (.toFixed one-cent-value decimals-count)))
|
||||
(remove-trailing-zeroes (.toFixed token-units decimals-count))))))
|
||||
|
||||
(defn total-token-units-in-all-chains
|
||||
[{:keys [balances-per-chain decimals] :as _token}]
|
||||
(-> balances-per-chain
|
||||
(total-raw-balance-in-all-chains)
|
||||
(money/token->unit decimals)))
|
||||
(defn get-market-value
|
||||
[currency {:keys [market-values-per-currency]}]
|
||||
(or (get-in market-values-per-currency
|
||||
[currency :price])
|
||||
(get-in market-values-per-currency
|
||||
[constants/profile-default-currency :price])
|
||||
;; NOTE: adding fallback value (zero) in case prices are
|
||||
;; unavailable and to prevent crash on calculating fiat value
|
||||
0))
|
||||
|
||||
(defn- filter-chains
|
||||
[balances-per-chain chain-ids]
|
||||
(if chain-ids
|
||||
(select-keys balances-per-chain chain-ids)
|
||||
balances-per-chain))
|
||||
|
||||
(defn calculate-total-token-balance
|
||||
([token]
|
||||
(calculate-total-token-balance token nil))
|
||||
([{:keys [balances-per-chain decimals]} chain-ids]
|
||||
(-> balances-per-chain
|
||||
(filter-chains chain-ids)
|
||||
(total-raw-balance-in-all-chains)
|
||||
(money/token->unit decimals))))
|
||||
|
||||
(defn get-account-by-address
|
||||
[accounts address]
|
||||
(some #(when (= (:address %) address) %) accounts))
|
||||
|
||||
(defn total-token-fiat-value
|
||||
"Returns the total token fiat value taking into account all token's chains."
|
||||
[currency {:keys [market-values-per-currency] :as token}]
|
||||
(let [price (or (get-in market-values-per-currency
|
||||
[currency :price])
|
||||
(get-in market-values-per-currency
|
||||
[constants/profile-default-currency :price])
|
||||
;; NOTE: adding fallback value (zero) in case prices are
|
||||
;; unavailable and to prevent crash on calculating fiat value
|
||||
0)
|
||||
total-units-in-all-chains (total-token-units-in-all-chains token)]
|
||||
(money/crypto->fiat total-units-in-all-chains price)))
|
||||
|
||||
(defn token-fiat-value
|
||||
"Returns the fiat value for a single token on a given network."
|
||||
[currency raw-balance {:keys [market-values-per-currency]}]
|
||||
(let [price (or (get-in market-values-per-currency
|
||||
[currency :price])
|
||||
(get-in market-values-per-currency
|
||||
[constants/profile-default-currency :price])
|
||||
0)]
|
||||
(money/crypto->fiat raw-balance price)))
|
||||
|
||||
(defn calculate-balance-for-account
|
||||
[currency {:keys [tokens] :as _account}]
|
||||
(->> tokens
|
||||
(map #(total-token-fiat-value currency %))
|
||||
(reduce money/add)))
|
||||
|
||||
(defn calculate-balance-for-token
|
||||
[token]
|
||||
(money/bignumber
|
||||
(money/mul (total-token-units-in-all-chains token)
|
||||
(-> token :market-values-per-currency :usd :price))))
|
||||
|
||||
(defn calculate-balance
|
||||
[tokens-in-account]
|
||||
(->> tokens-in-account
|
||||
(map #(calculate-balance-for-token %))
|
||||
(reduce +)))
|
||||
(defn calculate-token-fiat-value
|
||||
"Returns the token fiat value for provided raw balance"
|
||||
[{:keys [currency balance token]}]
|
||||
(let [price (get-market-value currency token)]
|
||||
(money/crypto->fiat balance price)))
|
||||
|
||||
(defn calculate-balance-from-tokens
|
||||
[{:keys [currency tokens]}]
|
||||
[{:keys [currency tokens chain-ids]}]
|
||||
(->> tokens
|
||||
(map #(total-token-fiat-value currency %))
|
||||
(map #(calculate-token-fiat-value
|
||||
{:currency currency
|
||||
:balance (calculate-total-token-balance % chain-ids)
|
||||
:token %}))
|
||||
(reduce money/add)))
|
||||
|
||||
(defn- add-balances-per-chain
|
||||
|
@ -191,38 +178,54 @@
|
|||
address))
|
||||
|
||||
(def id->network
|
||||
{constants/ethereum-mainnet-chain-id :ethereum
|
||||
constants/ethereum-goerli-chain-id :ethereum
|
||||
constants/ethereum-sepolia-chain-id :ethereum
|
||||
constants/optimism-mainnet-chain-id :optimism
|
||||
constants/optimism-goerli-chain-id :optimism
|
||||
constants/optimism-sepolia-chain-id :optimism
|
||||
constants/arbitrum-mainnet-chain-id :arbitrum
|
||||
constants/arbitrum-goerli-chain-id :arbitrum
|
||||
constants/arbitrum-sepolia-chain-id :arbitrum})
|
||||
{constants/ethereum-mainnet-chain-id constants/mainnet-network-name
|
||||
constants/ethereum-goerli-chain-id constants/mainnet-network-name
|
||||
constants/ethereum-sepolia-chain-id constants/mainnet-network-name
|
||||
constants/optimism-mainnet-chain-id constants/optimism-network-name
|
||||
constants/optimism-goerli-chain-id constants/optimism-network-name
|
||||
constants/optimism-sepolia-chain-id constants/optimism-network-name
|
||||
constants/arbitrum-mainnet-chain-id constants/arbitrum-network-name
|
||||
constants/arbitrum-goerli-chain-id constants/arbitrum-network-name
|
||||
constants/arbitrum-sepolia-chain-id constants/arbitrum-network-name})
|
||||
|
||||
(defn- get-chain-id
|
||||
[testnet-enabled? goerli-enabled?]
|
||||
[{:keys [mainnet-chain-id sepolia-chain-id goerli-chain-id testnet-enabled? goerli-enabled?]}]
|
||||
(cond
|
||||
(and testnet-enabled? goerli-enabled?)
|
||||
{:eth constants/ethereum-goerli-chain-id
|
||||
:opt constants/optimism-goerli-chain-id
|
||||
:arb1 constants/arbitrum-goerli-chain-id}
|
||||
goerli-chain-id
|
||||
|
||||
testnet-enabled?
|
||||
{:eth constants/ethereum-sepolia-chain-id
|
||||
:opt constants/optimism-sepolia-chain-id
|
||||
:arb1 constants/arbitrum-sepolia-chain-id}
|
||||
sepolia-chain-id
|
||||
|
||||
:else
|
||||
{:eth constants/ethereum-mainnet-chain-id
|
||||
:opt constants/optimism-mainnet-chain-id
|
||||
:arb1 constants/arbitrum-mainnet-chain-id}))
|
||||
mainnet-chain-id))
|
||||
|
||||
(defn short-name->id
|
||||
[short-name testnet-enabled? goerli-enabled?]
|
||||
(let [chain-id-map (get-chain-id testnet-enabled? goerli-enabled?)]
|
||||
(get chain-id-map short-name)))
|
||||
(defn network->chain-id
|
||||
[{:keys [network testnet-enabled? goerli-enabled?]}]
|
||||
(condp contains? (keyword network)
|
||||
#{constants/mainnet-network-name (keyword constants/mainnet-short-name)}
|
||||
(get-chain-id
|
||||
{:mainnet-chain-id constants/ethereum-mainnet-chain-id
|
||||
:sepolia-chain-id constants/ethereum-sepolia-chain-id
|
||||
:goerli-chain-id constants/ethereum-goerli-chain-id
|
||||
:testnet-enabled? testnet-enabled?
|
||||
:goerli-enabled? goerli-enabled?})
|
||||
|
||||
#{constants/optimism-network-name (keyword constants/optimism-short-name)}
|
||||
(get-chain-id
|
||||
{:mainnet-chain-id constants/optimism-mainnet-chain-id
|
||||
:sepolia-chain-id constants/optimism-sepolia-chain-id
|
||||
:goerli-chain-id constants/optimism-goerli-chain-id
|
||||
:testnet-enabled? testnet-enabled?
|
||||
:goerli-enabled? goerli-enabled?})
|
||||
|
||||
#{constants/arbitrum-network-name (keyword constants/arbitrum-short-name)}
|
||||
(get-chain-id
|
||||
{:mainnet-chain-id constants/arbitrum-mainnet-chain-id
|
||||
:sepolia-chain-id constants/arbitrum-sepolia-chain-id
|
||||
:goerli-chain-id constants/arbitrum-goerli-chain-id
|
||||
:testnet-enabled? testnet-enabled?
|
||||
:goerli-enabled? goerli-enabled?})))
|
||||
|
||||
(defn get-standard-fiat-format
|
||||
[crypto-value currency-symbol fiat-value]
|
||||
|
@ -241,8 +244,11 @@
|
|||
(defn calculate-token-value
|
||||
"This function returns token values in the props of token-value (quo) component"
|
||||
[{:keys [token color currency currency-symbol]}]
|
||||
(let [token-units (total-token-units-in-all-chains token)
|
||||
fiat-value (total-token-fiat-value currency token)
|
||||
(let [balance (calculate-total-token-balance token)
|
||||
fiat-value (calculate-token-fiat-value
|
||||
{:currency currency
|
||||
:balance balance
|
||||
:token token})
|
||||
market-values (or (get-in token [:market-values-per-currency currency])
|
||||
(get-in token
|
||||
[:market-values-per-currency
|
||||
|
@ -250,7 +256,7 @@
|
|||
{:keys [price change-pct-24hour]} market-values
|
||||
formatted-token-price (prettify-balance currency-symbol price)
|
||||
percentage-change (prettify-percentage-change change-pct-24hour)
|
||||
crypto-value (get-standard-crypto-format token token-units)
|
||||
crypto-value (get-standard-crypto-format token balance)
|
||||
fiat-value (get-standard-fiat-format crypto-value
|
||||
currency-symbol
|
||||
fiat-value)]
|
||||
|
@ -280,15 +286,10 @@
|
|||
(let [split-result (string/split input-string #"0x")]
|
||||
[(first split-result) (str "0x" (second split-result))]))
|
||||
|
||||
(defn get-balance-for-chain
|
||||
[data chain-id]
|
||||
(some #(when (= chain-id (:chain-id %)) %) (vals data)))
|
||||
|
||||
(defn make-network-item
|
||||
"This function generates props for quo/category component item"
|
||||
[{:keys [network-name] :as _network}
|
||||
{:keys [title color on-change networks state label-props] :as _options}]
|
||||
(cond-> {:title (or title (string/capitalize (name network-name)))
|
||||
[{:keys [network-name color on-change networks state label-props]}]
|
||||
(cond-> {:title (string/capitalize (name network-name))
|
||||
:image :icon-avatar
|
||||
:image-props {:icon (resources/get-network network-name)
|
||||
:size :size-20}
|
||||
|
@ -315,3 +316,21 @@
|
|||
|
||||
:else
|
||||
constants/mainnet-chain-ids))
|
||||
|
||||
(defn filter-tokens-in-chains
|
||||
[tokens chain-ids]
|
||||
(map #(update % :balances-per-chain select-keys chain-ids) tokens))
|
||||
|
||||
(defn calculate-balances-per-chain
|
||||
[{:keys [tokens currency currency-symbol]}]
|
||||
(->
|
||||
(reduce (fn [acc {:keys [balances-per-chain decimals] :as token}]
|
||||
(let [currency-value (get-market-value currency token)
|
||||
fiat-balance-per-chain (update-vals balances-per-chain
|
||||
#(-> (money/token->unit (:raw-balance %)
|
||||
decimals)
|
||||
(money/crypto->fiat currency-value)))]
|
||||
(merge-with money/add acc fiat-balance-per-chain)))
|
||||
{}
|
||||
tokens)
|
||||
(update-vals #(prettify-balance currency-symbol %))))
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
(ns status-im.contexts.wallet.common.utils-test
|
||||
(:require [cljs.test :refer [deftest is testing]]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[utils.money :as money]))
|
||||
(:require
|
||||
[cljs.test :refer [deftest is testing]]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[utils.money :as money]))
|
||||
|
||||
(deftest test-get-first-name
|
||||
(testing "get-first-name function"
|
||||
|
@ -28,7 +30,6 @@
|
|||
(is (= (utils/format-derivation-path "m/44'/60'/0'/0/0") "m / 44' / 60' / 0' / 0 / 0"))
|
||||
(is (= (utils/format-derivation-path "m/44'/60'/0'/0/123") "m / 44' / 60' / 0' / 0 / 123"))))
|
||||
|
||||
|
||||
(deftest test-get-formatted-derivation-path
|
||||
(testing "get-formatted-derivation-path function"
|
||||
(is (= (utils/get-formatted-derivation-path 5) "m / 44' / 60' / 0' / 0 / 5"))
|
||||
|
@ -70,13 +71,13 @@
|
|||
token-units)
|
||||
"<2")))))
|
||||
|
||||
(deftest test-total-token-units-in-all-chains
|
||||
(testing "total-token-units-in-all-chains function"
|
||||
(deftest test-calculate-total-token-balance
|
||||
(testing "calculate-total-token-balance function"
|
||||
(let [token {:balances-per-chain {1 {:raw-balance (money/bignumber 100)}
|
||||
10 {:raw-balance (money/bignumber 200)}
|
||||
42161 {:raw-balance (money/bignumber 300)}}
|
||||
:decimals 2}]
|
||||
(is (money/equal-to (utils/total-token-units-in-all-chains token) 6.0)))))
|
||||
(is (money/equal-to (utils/calculate-total-token-balance token) 6.0)))))
|
||||
|
||||
(deftest test-get-account-by-address
|
||||
(testing "get-account-by-address function"
|
||||
|
@ -115,3 +116,20 @@
|
|||
(is (= (utils/prettify-percentage-change 1.113454) "1.11"))
|
||||
(is (= (utils/prettify-percentage-change -0.35) "0.35"))
|
||||
(is (= (utils/prettify-percentage-change -0.78234) "0.78"))))
|
||||
|
||||
(deftest test-network->chain-id
|
||||
(testing "network->chain-id function"
|
||||
(is (= (utils/network->chain-id {:network :mainnet :testnet-enabled? false :goerli-enabled? false})
|
||||
constants/ethereum-mainnet-chain-id))
|
||||
(is (= (utils/network->chain-id {:network :eth :testnet-enabled? true :goerli-enabled? false})
|
||||
constants/ethereum-sepolia-chain-id))
|
||||
(is (= (utils/network->chain-id {:network "optimism" :testnet-enabled? true :goerli-enabled? false})
|
||||
constants/optimism-sepolia-chain-id))
|
||||
(is (= (utils/network->chain-id {:network "opt" :testnet-enabled? false :goerli-enabled? true})
|
||||
constants/optimism-mainnet-chain-id))
|
||||
(is (= (utils/network->chain-id {:network :opt :testnet-enabled? true :goerli-enabled? true})
|
||||
constants/optimism-goerli-chain-id))
|
||||
(is (= (utils/network->chain-id {:network :arb1 :testnet-enabled? false :goerli-enabled? false})
|
||||
constants/arbitrum-mainnet-chain-id))
|
||||
(is (= (utils/network->chain-id {:network :arbitrum :testnet-enabled? true :goerli-enabled? false})
|
||||
constants/arbitrum-sepolia-chain-id))))
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
(ns status-im.contexts.wallet.db
|
||||
(:require [status-im.constants :as constants]))
|
||||
|
||||
(def network-filter-defaults
|
||||
{:selector-state :default
|
||||
:selected-networks (set constants/default-network-names)})
|
||||
|
||||
(def defaults
|
||||
{:ui {:network-filter network-filter-defaults}})
|
|
@ -3,9 +3,11 @@
|
|||
[clojure.string :as string]
|
||||
[react-native.background-timer :as background-timer]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.accounts.add-account.address-to-watch.events]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.data-store :as data-store]
|
||||
[status-im.contexts.wallet.db :as db]
|
||||
[status-im.contexts.wallet.events.collectibles]
|
||||
[status-im.contexts.wallet.item-types :as item-types]
|
||||
[taoensso.timbre :as log]
|
||||
|
@ -443,3 +445,33 @@
|
|||
:type :negative
|
||||
:text (i18n/label :t/provider-is-down {:chains chain-names})
|
||||
:duration 10000}]]])})))
|
||||
|
||||
(defn reset-selected-networks
|
||||
[{:keys [db]}]
|
||||
{:db (assoc-in db [:wallet :ui :network-filter] db/network-filter-defaults)})
|
||||
|
||||
(rf/reg-event-fx :wallet/reset-selected-networks reset-selected-networks)
|
||||
|
||||
(defn update-selected-networks
|
||||
[{:keys [db]} [network-name]]
|
||||
(let [selected-networks (get-in db [:wallet :ui :network-filter :selected-networks])
|
||||
selector-state (get-in db [:wallet :ui :network-filter :selector-state])
|
||||
contains-network? (contains? selected-networks network-name)
|
||||
update-fn (if contains-network? disj conj)
|
||||
networks-count (count selected-networks)]
|
||||
(cond (= selector-state :default)
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :network-filter :selected-networks] #{network-name})
|
||||
(assoc-in [:wallet :ui :network-filter :selector-state] :changed))}
|
||||
|
||||
;; reset the list
|
||||
;; - if user is removing the last network in the list
|
||||
;; - if all networks is selected
|
||||
(or (and (= networks-count 1) contains-network?)
|
||||
(and (= (inc networks-count) constants/default-network-count) (not contains-network?)))
|
||||
{:fx [[:dispatch [:wallet/reset-selected-networks]]]}
|
||||
|
||||
:else
|
||||
{:db (update-in db [:wallet :ui :network-filter :selected-networks] update-fn network-name)})))
|
||||
|
||||
(rf/reg-event-fx :wallet/update-selected-networks update-selected-networks)
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
(:require
|
||||
[cljs.test :refer-macros [deftest is testing]]
|
||||
matcher-combinators.test
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.db :as db]
|
||||
[status-im.contexts.wallet.events :as events]
|
||||
[status-im.contexts.wallet.events.collectibles :as collectibles]))
|
||||
|
||||
|
@ -73,3 +75,46 @@
|
|||
effects (collectibles/store-last-collectible-details {:db db} [last-collectible])
|
||||
result-db (:db effects)]
|
||||
(is (match? result-db expected-db)))))
|
||||
|
||||
(deftest reset-selected-networks
|
||||
(testing "reset-selected-networks"
|
||||
(let [db {:wallet {}}
|
||||
expected-db {:wallet db/defaults}
|
||||
effects (events/reset-selected-networks {:db db})
|
||||
result-db (:db effects)]
|
||||
(is (match? result-db expected-db)))))
|
||||
|
||||
(deftest update-selected-networks
|
||||
(testing "update-selected-networks"
|
||||
(let [db {:wallet {:ui {:network-filter {:selected-networks
|
||||
#{constants/optimism-network-name}
|
||||
:selector-state :changed}}}}
|
||||
network-name constants/arbitrum-network-name
|
||||
expected-db {:wallet {:ui {:network-filter {:selected-networks
|
||||
#{constants/optimism-network-name
|
||||
network-name}
|
||||
:selector-state :changed}}}}
|
||||
props [network-name]
|
||||
effects (events/update-selected-networks {:db db} props)
|
||||
result-db (:db effects)]
|
||||
(is (match? result-db expected-db))))
|
||||
|
||||
(testing "update-selected-networks > if all networks is already selected, update to incoming network"
|
||||
(let [db {:wallet db/defaults}
|
||||
network-name constants/arbitrum-network-name
|
||||
expected-db {:wallet {:ui {:network-filter {:selected-networks #{network-name}
|
||||
:selector-state :changed}}}}
|
||||
props [network-name]
|
||||
effects (events/update-selected-networks {:db db} props)
|
||||
result-db (:db effects)]
|
||||
(is (match? result-db expected-db))))
|
||||
|
||||
(testing "update-selected-networks > reset on removing last network"
|
||||
(let [db {:wallet {:ui {:network-filter {:selected-networks
|
||||
#{constants/optimism-network-name}
|
||||
:selector-state :changed}}}}
|
||||
expected-fx [[:dispatch [:wallet/reset-selected-networks]]]
|
||||
props [constants/optimism-network-name]
|
||||
effects (events/update-selected-networks {:db db} props)
|
||||
result-fx (:fx effects)]
|
||||
(is (match? result-fx expected-fx)))))
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
(defn view
|
||||
[]
|
||||
(let [tokens-loading? (rf/sub [:wallet/tokens-loading?])
|
||||
{:keys [tokens]} (rf/sub [:wallet/aggregated-tokens-and-balance])]
|
||||
{:keys [tokens]} (rf/sub [:wallet/aggregated-token-values-and-balance])]
|
||||
(if tokens-loading?
|
||||
[quo/skeleton-list
|
||||
{:content :assets
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
(defn view
|
||||
[{:keys [selected-tab]}]
|
||||
(let [collectible-list (rf/sub [:wallet/all-collectibles-list])
|
||||
(let [collectible-list (rf/sub [:wallet/all-collectibles-list-in-selected-networks])
|
||||
request-collectibles #(rf/dispatch
|
||||
[:wallet/request-collectibles-for-all-accounts {}])]
|
||||
[rn/view {:style style/container}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
[status-im.contexts.wallet.home.style :as style]
|
||||
[status-im.contexts.wallet.home.tabs.view :as tabs]
|
||||
[status-im.contexts.wallet.sheets.network-filter.view :as network-filter]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
|
@ -41,18 +40,16 @@
|
|||
(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?])
|
||||
networks (rf/sub [:wallet/network-details])
|
||||
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))
|
||||
|
||||
{:keys [formatted-balance]} (rf/sub [:wallet/aggregated-tokens-and-balance])]
|
||||
{:keys [formatted-balance]} (rf/sub [:wallet/aggregated-token-values-and-balance])]
|
||||
(rn/use-effect (fn []
|
||||
(when (and @account-list-ref (pos? (count cards)))
|
||||
(.scrollToOffset ^js @account-list-ref
|
||||
#js
|
||||
{:animated true
|
||||
:offset 0}
|
||||
)))
|
||||
:offset 0})))
|
||||
[(count cards)])
|
||||
[rn/view {:style (style/home-container)}
|
||||
[common.top-nav/view]
|
||||
|
@ -63,10 +60,7 @@
|
|||
:metrics :none
|
||||
:balance formatted-balance
|
||||
:networks networks
|
||||
:dropdown-on-press #(ff/alert ::ff/wallet.network-filter
|
||||
(fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content network-filter/view}])))}]]
|
||||
:dropdown-on-press #(rf/dispatch [:show-bottom-sheet {:content network-filter/view}])}]]
|
||||
[quo/wallet-graph {:time-frame :empty}]
|
||||
[rn/flat-list
|
||||
{:ref #(reset! account-list-ref %)
|
||||
|
|
|
@ -53,12 +53,16 @@
|
|||
:wallet/select-send-address
|
||||
(fn [{:keys [db]} [{:keys [address recipient stack-id start-flow?]}]]
|
||||
(let [[prefix to-address] (utils/split-prefix-and-address address)
|
||||
test-net? (get-in db [:profile/profile :test-networks-enabled?])
|
||||
testnet-enabled? (get-in db [:profile/profile :test-networks-enabled?])
|
||||
goerli-enabled? (get-in db [:profile/profile :is-goerli-enabled?])
|
||||
prefix-seq (string/split prefix #":")
|
||||
selected-networks (->> prefix-seq
|
||||
(remove string/blank?)
|
||||
(mapv #(utils/short-name->id (keyword %) test-net? goerli-enabled?)))]
|
||||
(mapv
|
||||
#(utils/network->chain-id
|
||||
{:network %
|
||||
:testnet-enabled? testnet-enabled?
|
||||
:goerli-enabled? goerli-enabled?})))]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :recipient] (or recipient address))
|
||||
(assoc-in [:wallet :ui :send :to-address] to-address)
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
|
||||
(def sub-mocks
|
||||
{:profile/profile {:currency :usd}
|
||||
:wallet/network-details [{:source 525
|
||||
:wallet/selected-network-details [{:source 525
|
||||
:short-name "eth"
|
||||
:network-name :ethereum
|
||||
:network-name :mainnet
|
||||
:chain-id 1
|
||||
:related-chain-id 5}]
|
||||
:wallet/current-viewing-account {:path "m/44'/60'/0'/0/1"
|
||||
|
@ -30,7 +30,7 @@
|
|||
:color :purple
|
||||
:hidden false
|
||||
:prod-preferred-chain-ids #{1 10 42161}
|
||||
:network-preferences-names #{:ethereum :arbitrum
|
||||
:network-preferences-names #{:mainnet :arbitrum
|
||||
:optimism}
|
||||
:position 1
|
||||
:clock 1698945829328
|
||||
|
|
|
@ -236,9 +236,10 @@
|
|||
(utils/get-standard-crypto-format native-token
|
||||
fee-in-native-token))
|
||||
fee-in-fiat (when-not confirm-disabled?
|
||||
(utils/token-fiat-value fiat-currency
|
||||
fee-in-native-token
|
||||
native-token))
|
||||
(utils/calculate-token-fiat-value
|
||||
{:currency fiat-currency
|
||||
:balance fee-in-native-token
|
||||
:token native-token}))
|
||||
currency-symbol (rf/sub [:profile/currency-symbol])
|
||||
fee-formatted (when fee-in-fiat
|
||||
(utils/get-standard-fiat-format fee-in-crypto-formatted
|
||||
|
|
|
@ -2,21 +2,12 @@
|
|||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.contexts.wallet.send.select-address.tabs.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- render-account-item
|
||||
[{:keys [color address] :as account}]
|
||||
[quo/account-item
|
||||
{:account-props (assoc account :customization-color color)
|
||||
:on-press #(rf/dispatch [:wallet/select-send-address
|
||||
{:address address
|
||||
:recipient account
|
||||
:stack-id :screen/wallet.select-address}])}])
|
||||
|
||||
(defn my-accounts
|
||||
[theme]
|
||||
(let [other-accounts (rf/sub [:wallet/accounts-without-current-viewing-account])]
|
||||
|
@ -26,11 +17,15 @@
|
|||
:description (i18n/label :t/here-is-a-cat-in-a-box-instead)
|
||||
:image (resources/get-themed-image :cat-in-box theme)
|
||||
:container-style style/empty-container-style}]
|
||||
[gesture/flat-list
|
||||
{:data other-accounts
|
||||
:render-fn render-account-item
|
||||
:content-container-style style/my-accounts-container
|
||||
:shows-vertical-scroll-indicator false}])))
|
||||
(into [rn/view {:style style/my-accounts-container}]
|
||||
(map (fn [{:keys [color address] :as account}]
|
||||
[quo/account-item
|
||||
{:account-props (assoc account :customization-color color)
|
||||
:on-press #(rf/dispatch [:wallet/select-send-address
|
||||
{:address address
|
||||
:recipient account
|
||||
:stack-id :screen/wallet.select-address}])}]))
|
||||
other-accounts))))
|
||||
|
||||
(defn view-internal
|
||||
[{:keys [selected-tab theme]}]
|
||||
|
|
|
@ -1,54 +1,48 @@
|
|||
(ns status-im.contexts.wallet.sheets.network-filter.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [state (reagent/atom :default)
|
||||
networks-selected (reagent/atom #{})
|
||||
toggle-network (fn [network-name]
|
||||
(reset! state :changed)
|
||||
(if (contains? @networks-selected
|
||||
network-name)
|
||||
(swap! networks-selected disj
|
||||
network-name)
|
||||
(swap! networks-selected conj
|
||||
network-name)))
|
||||
get-networks (fn []
|
||||
(if (= @state :default)
|
||||
constants/default-network-names
|
||||
@networks-selected))]
|
||||
(fn []
|
||||
(let [color (rf/sub [:profile/customization-color])
|
||||
network-details (rf/sub [:wallet/network-details])
|
||||
mainnet (first network-details)
|
||||
layer-2-networks (rest network-details)]
|
||||
[:<>
|
||||
[quo/drawer-top {:title (i18n/label :t/select-networks)}]
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:data [(utils/make-network-item mainnet
|
||||
{:state @state
|
||||
:title (i18n/label :t/mainnet)
|
||||
:color color
|
||||
:networks (get-networks)
|
||||
:on-change #(toggle-network (:network-name
|
||||
mainnet))
|
||||
:label-props "$0.00"})]}]
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:label (i18n/label :t/layer-2)
|
||||
:data (mapv (fn [network]
|
||||
(utils/make-network-item network
|
||||
{:state @state
|
||||
:color color
|
||||
:networks (get-networks)
|
||||
:on-change #(toggle-network (:network-name
|
||||
network))
|
||||
:label-props "$0.00"}))
|
||||
layer-2-networks)}]]))))
|
||||
(let [selected-networks (rf/sub [:wallet/selected-networks])
|
||||
selector-state (rf/sub [:wallet/network-filter-selector-state])
|
||||
color (rf/sub [:profile/customization-color])
|
||||
network-details (rf/sub [:wallet/network-details])
|
||||
viewing-account? (rf/sub [:wallet/viewing-account?])
|
||||
balance-per-chain (if viewing-account?
|
||||
(rf/sub [:wallet/current-viewing-account-fiat-balance-per-chain])
|
||||
(rf/sub [:wallet/aggregated-fiat-balance-per-chain]))
|
||||
mainnet (first network-details)
|
||||
layer-2-networks (rest network-details)]
|
||||
[:<>
|
||||
[quo/drawer-top {:title (i18n/label :t/select-networks)}]
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:data [(utils/make-network-item
|
||||
{:state selector-state
|
||||
:network-name (:network-name mainnet)
|
||||
:color color
|
||||
:networks selected-networks
|
||||
:label-props (get balance-per-chain (:chain-id mainnet))
|
||||
:on-change #(rf/dispatch
|
||||
[:wallet/update-selected-networks
|
||||
(:network-name
|
||||
mainnet)])})]}]
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:label (i18n/label :t/layer-2)
|
||||
:data (mapv (fn [network]
|
||||
(utils/make-network-item
|
||||
{:state selector-state
|
||||
:network-name (:network-name network)
|
||||
:color color
|
||||
:networks selected-networks
|
||||
:label-props (get balance-per-chain (:chain-id network))
|
||||
:on-change #(rf/dispatch
|
||||
[:wallet/update-selected-networks
|
||||
(:network-name
|
||||
network)])}))
|
||||
layer-2-networks)}]]))
|
||||
|
|
|
@ -4,31 +4,37 @@
|
|||
[quo.theme :as quo.theme]
|
||||
[react-native.blur :as blur]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.sheets.network-preferences.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [selected-networks watch-only?]}]
|
||||
[{:keys [selected-networks account watch-only?]}]
|
||||
(let [state (reagent/atom :default)
|
||||
{:keys [color address
|
||||
network-preferences-names]} (rf/sub [:wallet/current-viewing-account])
|
||||
network-preferences-names]} (or account (rf/sub [:wallet/current-viewing-account]))
|
||||
initial-network-preferences-names (or selected-networks network-preferences-names)
|
||||
network-preferences-names-state (reagent/atom #{})
|
||||
toggle-network (fn [network-name]
|
||||
(reset! state :changed)
|
||||
(if (contains? @network-preferences-names-state
|
||||
network-name)
|
||||
(swap! network-preferences-names-state disj
|
||||
network-name)
|
||||
(swap! network-preferences-names-state conj
|
||||
network-name)))
|
||||
(let [contains-network? (contains?
|
||||
@network-preferences-names-state
|
||||
network-name)
|
||||
update-fn (if contains-network? disj conj)
|
||||
networks-count (count
|
||||
@network-preferences-names-state)]
|
||||
(if (and (= networks-count 1) contains-network?)
|
||||
(reset! network-preferences-names-state
|
||||
(set constants/default-network-names))
|
||||
(swap! network-preferences-names-state update-fn
|
||||
network-name))))
|
||||
get-current-preferences-names (fn []
|
||||
(if (= @state :default)
|
||||
initial-network-preferences-names
|
||||
@network-preferences-names-state))]
|
||||
(fn [{:keys [on-save blur? theme]}]
|
||||
(fn [{:keys [on-save blur? theme button-label]}]
|
||||
(let [network-details (rf/sub [:wallet/network-details])
|
||||
mainnet (first network-details)
|
||||
layer-2-networks (rest network-details)
|
||||
|
@ -70,30 +76,30 @@
|
|||
[quo/category
|
||||
{:list-type :settings
|
||||
:blur? blur?
|
||||
:data [(utils/make-network-item mainnet
|
||||
{:state @state
|
||||
:title (i18n/label :t/mainnet)
|
||||
:color color
|
||||
:blur? blur?
|
||||
:networks (get-current-preferences-names)
|
||||
:on-change #(toggle-network (:network-name
|
||||
mainnet))})]}]
|
||||
:data [(utils/make-network-item {:state @state
|
||||
:network-name (:network-name mainnet)
|
||||
:color color
|
||||
:blur? blur?
|
||||
:networks (get-current-preferences-names)
|
||||
:on-change #(toggle-network (:network-name
|
||||
mainnet))})]}]
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:blur? blur?
|
||||
:label (i18n/label :t/layer-2)
|
||||
:data (mapv (fn [network]
|
||||
(utils/make-network-item network
|
||||
{:state @state
|
||||
:color color
|
||||
:blur? blur?
|
||||
:networks (get-current-preferences-names)
|
||||
:on-change #(toggle-network (:network-name
|
||||
network))}))
|
||||
(utils/make-network-item {:state @state
|
||||
:network-name (:network-name network)
|
||||
:color color
|
||||
:blur? blur?
|
||||
:networks (get-current-preferences-names)
|
||||
:on-change #(toggle-network (:network-name
|
||||
network))}))
|
||||
layer-2-networks)}]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/display)
|
||||
:blur? blur?
|
||||
:button-one-label (or button-label (i18n/label :t/update))
|
||||
:button-one-props {:disabled? (= @state :default)
|
||||
:on-press (fn []
|
||||
(let [chain-ids (map :chain-id current-networks)]
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
(:require
|
||||
[legacy.status-im.fleet.core :as fleet]
|
||||
[react-native.core :as rn]
|
||||
[status-im.contexts.shell.activity-center.events :as activity-center]))
|
||||
[status-im.contexts.shell.activity-center.events :as activity-center]
|
||||
[status-im.contexts.wallet.db :as wallet]))
|
||||
|
||||
;; initial state of app-db
|
||||
(def app-db
|
||||
|
@ -18,6 +19,7 @@
|
|||
:sync-state :done
|
||||
:link-previews-whitelist []
|
||||
:app-state "active"
|
||||
:wallet wallet/defaults
|
||||
:peers-count 0
|
||||
:node-info {}
|
||||
:peers-summary []
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
{::wallet.bridge-token (enabled-in-env? :FLAG_BRIDGE_TOKEN_ENABLED)
|
||||
::wallet.edit-derivation-path (enabled-in-env? :FLAG_EDIT_DERIVATION_PATH)
|
||||
::wallet.remove-account (enabled-in-env? :FLAG_REMOVE_ACCOUNT_ENABLED)
|
||||
::wallet.network-filter (enabled-in-env? :FLAG_NETWORK_FILTER_ENABLED)
|
||||
::community.edit-account-selection (enabled-in-env? :FLAG_EDIT_ACCOUNT_SELECTION_ENABLED)}))
|
||||
|
||||
(defn feature-flags [] @feature-flags-config)
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
[clojure.string :as string]
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
(defn- filter-collectibles-in-chains
|
||||
[collectibles chain-ids]
|
||||
(filter #(contains? chain-ids (get-in % [:id :contract-id :chain-id])) collectibles))
|
||||
|
||||
(defn- svg-animation?
|
||||
[url media-type]
|
||||
(and (not (string/blank? url))
|
||||
|
@ -44,6 +48,13 @@
|
|||
(fn [current-account]
|
||||
(-> current-account :collectibles add-collectibles-preview-url)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/current-viewing-account-collectibles-in-selected-networks
|
||||
:<- [:wallet/current-viewing-account-collectibles]
|
||||
:<- [:wallet/selected-networks->chain-ids]
|
||||
(fn [[collectibles chain-ids]]
|
||||
(filter-collectibles-in-chains collectibles chain-ids)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/all-collectibles-list
|
||||
:<- [:wallet]
|
||||
|
@ -61,6 +72,13 @@
|
|||
(remove nil?)
|
||||
(add-collectibles-preview-url)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/all-collectibles-list-in-selected-networks
|
||||
:<- [:wallet/all-collectibles-list]
|
||||
:<- [:wallet/selected-networks->chain-ids]
|
||||
(fn [[all-collectibles chain-ids]]
|
||||
(filter-collectibles-in-chains all-collectibles chain-ids)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/current-viewing-account-collectibles-filtered
|
||||
:<- [:wallet/current-viewing-account-collectibles]
|
||||
|
|
|
@ -35,17 +35,17 @@
|
|||
|
||||
(defn get-network-details
|
||||
[chain-id]
|
||||
(case chain-id
|
||||
(constants/ethereum-mainnet-chain-id constants/ethereum-goerli-chain-id
|
||||
constants/ethereum-sepolia-chain-id)
|
||||
(condp contains? chain-id
|
||||
#{constants/ethereum-mainnet-chain-id constants/ethereum-goerli-chain-id
|
||||
constants/ethereum-sepolia-chain-id}
|
||||
mainnet-network-details
|
||||
|
||||
(constants/arbitrum-mainnet-chain-id constants/arbitrum-goerli-chain-id
|
||||
constants/arbitrum-sepolia-chain-id)
|
||||
#{constants/arbitrum-mainnet-chain-id constants/arbitrum-goerli-chain-id
|
||||
constants/arbitrum-sepolia-chain-id}
|
||||
arbitrum-network-details
|
||||
|
||||
(constants/optimism-mainnet-chain-id constants/optimism-goerli-chain-id
|
||||
constants/optimism-sepolia-chain-id)
|
||||
#{constants/optimism-mainnet-chain-id constants/optimism-goerli-chain-id
|
||||
constants/optimism-sepolia-chain-id}
|
||||
optimism-network-details
|
||||
|
||||
nil))
|
||||
|
@ -55,13 +55,12 @@
|
|||
:<- [:wallet/networks-by-mode]
|
||||
(fn [networks]
|
||||
(->> networks
|
||||
(keep
|
||||
(fn [{:keys [chain-id related-chain-id layer test?]}]
|
||||
(let [network-details (get-network-details (if test? related-chain-id chain-id))]
|
||||
(assoc network-details
|
||||
:chain-id chain-id
|
||||
:related-chain-id related-chain-id
|
||||
:layer layer))))
|
||||
(map
|
||||
(fn [{:keys [chain-id related-chain-id layer]}]
|
||||
(assoc (get-network-details chain-id)
|
||||
:chain-id chain-id
|
||||
:related-chain-id related-chain-id
|
||||
:layer layer)))
|
||||
(sort-by (juxt :layer :short-name)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
|
@ -69,3 +68,12 @@
|
|||
:<- [:wallet/network-details]
|
||||
(fn [networks [_ chain-id]]
|
||||
(some #(when (= chain-id (:chain-id %)) %) networks)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/selected-network-details
|
||||
:<- [:wallet/network-details]
|
||||
:<- [:wallet/selected-networks]
|
||||
(fn [[network-details selected-networks]]
|
||||
(filter
|
||||
#(contains? selected-networks (:network-name %))
|
||||
network-details)))
|
||||
|
|
|
@ -44,11 +44,32 @@
|
|||
:<- [:wallet/ui]
|
||||
:-> :create-account)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/network-filter
|
||||
:<- [:wallet/ui]
|
||||
:-> :network-filter)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/selected-networks
|
||||
:<- [:wallet/network-filter]
|
||||
:-> :selected-networks)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/network-filter-selector-state
|
||||
:<- [:wallet/network-filter]
|
||||
:-> :selector-state)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/current-viewing-account-address
|
||||
:<- [:wallet]
|
||||
:-> :current-viewing-account-address)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/viewing-account?
|
||||
:<- [:wallet/current-viewing-account-address]
|
||||
(fn [address]
|
||||
(boolean address)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/wallet-send-to-address
|
||||
:<- [:wallet/wallet-send]
|
||||
|
@ -104,6 +125,18 @@
|
|||
:<- [:wallet/create-account]
|
||||
:-> :selected-keypair-uid)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/selected-networks->chain-ids
|
||||
:<- [:wallet/selected-networks]
|
||||
:<- [:profile/test-networks-enabled?]
|
||||
:<- [:profile/is-goerli-enabled?]
|
||||
(fn [[selected-networks testnet-enabled? goerli-enabled?]]
|
||||
(set (map #(utils/network->chain-id
|
||||
{:network %
|
||||
:testnet-enabled? testnet-enabled?
|
||||
:goerli-enabled? goerli-enabled?})
|
||||
selected-networks))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/accounts
|
||||
:<- [:wallet]
|
||||
|
@ -131,17 +164,21 @@
|
|||
set))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/balances
|
||||
:wallet/balances-in-selected-networks
|
||||
:<- [:wallet/accounts]
|
||||
:<- [:profile/currency]
|
||||
(fn [[accounts currency]]
|
||||
:<- [:wallet/selected-networks->chain-ids]
|
||||
(fn [[accounts currency chain-ids]]
|
||||
(zipmap (map :address accounts)
|
||||
(map #(utils/calculate-balance-for-account currency %) accounts))))
|
||||
(map #(utils/calculate-balance-from-tokens {:currency currency
|
||||
:tokens (:tokens %)
|
||||
:chain-ids chain-ids})
|
||||
accounts))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/account-cards-data
|
||||
:<- [:wallet/accounts]
|
||||
:<- [:wallet/balances]
|
||||
:<- [:wallet/balances-in-selected-networks]
|
||||
:<- [:wallet/tokens-loading?]
|
||||
:<- [:profile/currency-symbol]
|
||||
(fn [[accounts balances tokens-loading? currency-symbol]]
|
||||
|
@ -158,7 +195,7 @@
|
|||
:wallet/current-viewing-account
|
||||
:<- [:wallet/accounts]
|
||||
:<- [:wallet/current-viewing-account-address]
|
||||
:<- [:wallet/balances]
|
||||
:<- [:wallet/balances-in-selected-networks]
|
||||
:<- [:profile/currency-symbol]
|
||||
(fn [[accounts current-viewing-account-address balances currency-symbol]]
|
||||
(let [balance (get balances current-viewing-account-address)
|
||||
|
@ -169,15 +206,21 @@
|
|||
:formatted-balance formatted-balance)))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/tokens-filtered
|
||||
:wallet/current-viewing-account-tokens-in-selected-networks
|
||||
:<- [:wallet/current-viewing-account]
|
||||
:<- [:wallet/selected-networks->chain-ids]
|
||||
(fn [[{:keys [tokens]} chain-ids]]
|
||||
(utils/filter-tokens-in-chains tokens chain-ids)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/current-viewing-account-tokens-filtered
|
||||
:<- [:wallet/current-viewing-account]
|
||||
:<- [:wallet/network-details]
|
||||
(fn [[account networks] [_ query]]
|
||||
(let [tokens (map (fn [token]
|
||||
(assoc token
|
||||
:networks (utils/network-list token networks)
|
||||
:total-balance (utils/total-token-units-in-all-chains token)
|
||||
:total-balance-fiat (utils/calculate-balance-for-token token)))
|
||||
:networks (utils/network-list token networks)
|
||||
:total-balance (utils/calculate-total-token-balance token)))
|
||||
(:tokens account))
|
||||
sorted-tokens (sort-by :name compare tokens)
|
||||
filtered-tokens (filter #(or (string/starts-with? (string/lower-case (:name %))
|
||||
|
@ -194,9 +237,8 @@
|
|||
(fn [[account networks] [_ token-symbol]]
|
||||
(let [tokens (map (fn [token]
|
||||
(assoc token
|
||||
:networks (utils/network-list token networks)
|
||||
:total-balance (utils/total-token-units-in-all-chains token)
|
||||
:total-balance-fiat (utils/calculate-balance-for-token token)))
|
||||
:networks (utils/network-list token networks)
|
||||
:total-balance (utils/calculate-total-token-balance token)))
|
||||
(:tokens account))
|
||||
token (first (filter #(= (string/lower-case (:symbol %))
|
||||
(string/lower-case token-symbol))
|
||||
|
@ -214,14 +256,15 @@
|
|||
:wallet/accounts-without-watched-accounts
|
||||
:<- [:wallet/accounts-with-customization-color]
|
||||
(fn [accounts]
|
||||
(remove #(:watch-only? %) accounts)))
|
||||
(remove :watch-only? accounts)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/account-token-values
|
||||
:wallet/current-viewing-account-token-values
|
||||
:<- [:wallet/current-viewing-account]
|
||||
:<- [:wallet/current-viewing-account-tokens-in-selected-networks]
|
||||
:<- [:profile/currency]
|
||||
:<- [:profile/currency-symbol]
|
||||
(fn [[{:keys [tokens color]} currency currency-symbol]]
|
||||
(fn [[{:keys [color]} tokens currency currency-symbol]]
|
||||
(mapv #(utils/calculate-token-value {:token %
|
||||
:color color
|
||||
:currency currency
|
||||
|
@ -235,8 +278,15 @@
|
|||
(utils/aggregate-tokens-for-all-accounts accounts)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/aggregated-tokens-and-balance
|
||||
:wallet/aggregated-tokens-in-selected-networks
|
||||
:<- [:wallet/aggregated-tokens]
|
||||
:<- [:wallet/selected-networks->chain-ids]
|
||||
(fn [[aggregated-tokens chain-ids]]
|
||||
(utils/filter-tokens-in-chains aggregated-tokens chain-ids)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/aggregated-token-values-and-balance
|
||||
:<- [:wallet/aggregated-tokens-in-selected-networks]
|
||||
:<- [:profile/customization-color]
|
||||
:<- [:profile/currency]
|
||||
:<- [:profile/currency-symbol]
|
||||
|
@ -287,3 +337,25 @@
|
|||
:wallet/valid-ens-or-address?
|
||||
:<- [:wallet/search-address]
|
||||
:-> :valid-ens-or-address?)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/aggregated-fiat-balance-per-chain
|
||||
:<- [:wallet/aggregated-tokens]
|
||||
:<- [:profile/currency]
|
||||
:<- [:profile/currency-symbol]
|
||||
(fn [[aggregated-tokens currency currency-symbol]]
|
||||
(utils/calculate-balances-per-chain
|
||||
{:tokens aggregated-tokens
|
||||
:currency currency
|
||||
:currency-symbol currency-symbol})))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/current-viewing-account-fiat-balance-per-chain
|
||||
:<- [:wallet/current-viewing-account]
|
||||
:<- [:profile/currency]
|
||||
:<- [:profile/currency-symbol]
|
||||
(fn [[{:keys [tokens]} currency currency-symbol]]
|
||||
(utils/calculate-balances-per-chain
|
||||
{:tokens tokens
|
||||
:currency currency
|
||||
:currency-symbol currency-symbol})))
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
(ns status-im.subs.wallet.wallet-test
|
||||
(:require [cljs.test :refer [is testing use-fixtures]]
|
||||
[re-frame.db :as rf-db]
|
||||
[status-im.subs.root]
|
||||
[test-helpers.unit :as h]
|
||||
[utils.money :as money]
|
||||
[utils.re-frame :as rf]))
|
||||
(:require
|
||||
[cljs.test :refer [is testing use-fixtures]]
|
||||
[re-frame.db :as rf-db]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.db :as db]
|
||||
[status-im.subs.root]
|
||||
[test-helpers.unit :as h]
|
||||
[utils.money :as money]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(use-fixtures :each
|
||||
{:before #(reset! rf-db/app-db {})})
|
||||
|
@ -13,47 +16,75 @@
|
|||
[{:decimals 1
|
||||
:symbol "ETH"
|
||||
:name "Ether"
|
||||
:balances-per-chain {1 {:raw-balance (money/bignumber "20") :has-error false}
|
||||
2 {:raw-balance (money/bignumber "10") :has-error false}}
|
||||
:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance (money/bignumber "20")
|
||||
:has-error false}
|
||||
constants/optimism-mainnet-chain-id {:raw-balance (money/bignumber "10")
|
||||
:has-error false}}
|
||||
:market-values-per-currency {:usd {:price 1000}}}
|
||||
{:decimals 2
|
||||
:symbol "DAI"
|
||||
:name "Dai Stablecoin"
|
||||
:balances-per-chain {1 {:raw-balance (money/bignumber "100") :has-error false}
|
||||
2 {:raw-balance (money/bignumber "150") :has-error false}
|
||||
3 {:raw-balance nil :has-error false}}
|
||||
:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||
"100")
|
||||
:has-error false}
|
||||
constants/optimism-mainnet-chain-id {:raw-balance (money/bignumber
|
||||
"150")
|
||||
:has-error false}
|
||||
constants/arbitrum-mainnet-chain-id {:raw-balance nil :has-error false}}
|
||||
:market-values-per-currency {:usd {:price 100}}}])
|
||||
|
||||
(def tokens-0x2
|
||||
[{:decimals 3
|
||||
:symbol "ETH"
|
||||
:name "Ether"
|
||||
:balances-per-chain {1 {:raw-balance (money/bignumber "2500") :has-error false}
|
||||
2 {:raw-balance (money/bignumber "3000") :has-error false}
|
||||
3 {:raw-balance (money/bignumber "<nil>") :has-error false}}
|
||||
:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||
"2500")
|
||||
:has-error false}
|
||||
constants/optimism-mainnet-chain-id {:raw-balance (money/bignumber
|
||||
"3000")
|
||||
:has-error false}
|
||||
constants/arbitrum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||
"<nil>")
|
||||
:has-error false}}
|
||||
:market-values-per-currency {:usd {:price 200}}}
|
||||
{:decimals 10
|
||||
:symbol "DAI"
|
||||
:name "Dai Stablecoin"
|
||||
:balances-per-chain {1 {:raw-balance (money/bignumber "10000000000") :has-error false}
|
||||
2 {:raw-balance (money/bignumber "0") :has-error false}
|
||||
3 {:raw-balance (money/bignumber "<nil>") :has-error false}}
|
||||
:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||
"10000000000")
|
||||
:has-error false}
|
||||
constants/optimism-mainnet-chain-id {:raw-balance (money/bignumber "0")
|
||||
:has-error false}
|
||||
constants/arbitrum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||
"<nil>")
|
||||
:has-error false}}
|
||||
:market-values-per-currency {:usd {:price 1000}}}])
|
||||
|
||||
(def tokens-0x3
|
||||
[{:decimals 3
|
||||
:symbol "ETH"
|
||||
:name "Ether"
|
||||
:balances-per-chain {1 {:raw-balance (money/bignumber "5000") :has-error false}
|
||||
2 {:raw-balance (money/bignumber "2000") :has-error false}
|
||||
3 {:raw-balance (money/bignumber "<nil>") :has-error false}}
|
||||
:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||
"5000")
|
||||
:has-error false}
|
||||
constants/optimism-mainnet-chain-id {:raw-balance (money/bignumber
|
||||
"2000")
|
||||
:has-error false}
|
||||
constants/arbitrum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||
"<nil>")
|
||||
:has-error false}}
|
||||
:market-values-per-currency {:usd {:price 200}}}
|
||||
{:decimals 10
|
||||
:symbol "DAI"
|
||||
:name "Dai Stablecoin"
|
||||
:balances-per-chain {1 {:raw-balance (money/bignumber "10000000000") :has-error false}
|
||||
2 {:raw-balance (money/bignumber "0") :has-error false}
|
||||
3 {:raw-balance (money/bignumber "<nil>") :has-error false}}
|
||||
:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||
"10000000000")
|
||||
:has-error false}
|
||||
constants/optimism-mainnet-chain-id {:raw-balance (money/bignumber "0")
|
||||
:has-error false}
|
||||
constants/arbitrum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||
"<nil>")
|
||||
:has-error false}}
|
||||
:market-values-per-currency {:usd {:price 1000}}}])
|
||||
|
||||
(def accounts
|
||||
|
@ -148,10 +179,12 @@
|
|||
:chain-id 10
|
||||
:layer 2}]})
|
||||
|
||||
(h/deftest-sub :wallet/balances
|
||||
(h/deftest-sub :wallet/balances-in-selected-networks
|
||||
[sub-name]
|
||||
(testing "a map: address->balance"
|
||||
(swap! rf-db/app-db #(assoc-in % [:wallet :accounts] accounts))
|
||||
(swap! rf-db/app-db #(-> %
|
||||
(assoc :wallet db/defaults)
|
||||
(assoc-in [:wallet :accounts] accounts)))
|
||||
(let [result (rf/sub [sub-name])
|
||||
balance-0x1 (money/bignumber 3250)
|
||||
balance-0x2 (money/bignumber 2100)
|
||||
|
@ -166,6 +199,7 @@
|
|||
(testing "returns all accounts without balance"
|
||||
(swap! rf-db/app-db
|
||||
#(-> %
|
||||
(assoc :wallet db/defaults)
|
||||
(assoc-in [:wallet :accounts] accounts)
|
||||
(assoc-in [:wallet :networks] network-data)))
|
||||
(is
|
||||
|
@ -250,6 +284,7 @@
|
|||
(testing "returns current account with balance base"
|
||||
(swap! rf-db/app-db
|
||||
#(-> %
|
||||
(assoc :wallet db/defaults)
|
||||
(assoc-in [:wallet :accounts] accounts)
|
||||
(assoc-in [:wallet :current-viewing-account-address] "0x1")
|
||||
(assoc-in [:wallet :networks] network-data)))
|
||||
|
@ -462,10 +497,12 @@
|
|||
(is (match? 2 (count result)))
|
||||
(is (money/equal-to (money/bignumber 7520) eth-mainnet-raw-balance)))))
|
||||
|
||||
(h/deftest-sub :wallet/aggregated-tokens-and-balance
|
||||
(h/deftest-sub :wallet/aggregated-token-values-and-balance
|
||||
[sub-name]
|
||||
(testing "returns aggregated tokens (in quo/token-value props) and balances from all accounts"
|
||||
(swap! rf-db/app-db #(assoc-in % [:wallet :accounts] accounts))
|
||||
(swap! rf-db/app-db #(-> %
|
||||
(assoc :wallet db/defaults)
|
||||
(assoc-in [:wallet :accounts] accounts)))
|
||||
(let [{:keys [formatted-balance tokens]} (rf/sub [sub-name])]
|
||||
(is (match? 2 (count tokens)))
|
||||
(is (match? "$4506.00" formatted-balance)))))
|
||||
|
@ -542,3 +579,99 @@
|
|||
(swap! rf-db/app-db
|
||||
#(assoc-in % [:wallet :ui :create-account :selected-keypair-uid] "key-uid"))
|
||||
(is (= "key-uid" (rf/sub [sub-name])))))
|
||||
|
||||
(h/deftest-sub :wallet/current-viewing-account-tokens-filtered
|
||||
[sub-name]
|
||||
(testing "current viewing tokens filtered"
|
||||
(swap! rf-db/app-db
|
||||
#(-> %
|
||||
(assoc-in [:wallet :accounts] accounts)
|
||||
(assoc-in [:wallet :networks] network-data)
|
||||
(assoc-in [:wallet :current-viewing-account-address] "0x2")
|
||||
(assoc-in [:profile/profile :currency] :usd)))
|
||||
(is (match? (count (rf/sub [sub-name ""])) 2))
|
||||
(is (match? (count (rf/sub [sub-name "et"])) 1))))
|
||||
|
||||
(h/deftest-sub :wallet/selected-networks->chain-ids
|
||||
[sub-name]
|
||||
(testing "selected networks -> chain-ids - All networks"
|
||||
(swap! rf-db/app-db #(assoc % :wallet db/defaults))
|
||||
(is
|
||||
(match? (sort [constants/ethereum-mainnet-chain-id constants/arbitrum-mainnet-chain-id
|
||||
constants/optimism-mainnet-chain-id])
|
||||
(sort (rf/sub [sub-name])))))
|
||||
(testing "selected networks -> chain-ids - specific network"
|
||||
(swap! rf-db/app-db #(assoc-in %
|
||||
[:wallet :ui :network-filter :selected-networks]
|
||||
#{constants/optimism-network-name}))
|
||||
(is
|
||||
(match? (sort [constants/optimism-mainnet-chain-id])
|
||||
(sort (rf/sub [sub-name]))))))
|
||||
|
||||
|
||||
(h/deftest-sub :wallet/current-viewing-account-tokens-in-selected-networks
|
||||
[sub-name]
|
||||
(testing "current account tokens in selected networks"
|
||||
(swap! rf-db/app-db
|
||||
#(-> %
|
||||
(assoc-in [:wallet :ui :network-filter :selected-networks] #{constants/arbitrum-network-name})
|
||||
(assoc-in [:wallet :accounts] accounts)
|
||||
(assoc-in [:wallet :current-viewing-account-address] "0x1")
|
||||
(assoc-in [:wallet :networks] network-data)))
|
||||
|
||||
(let [result (rf/sub [sub-name])
|
||||
token (nth result 1)
|
||||
chains (-> token
|
||||
:balances-per-chain
|
||||
keys)]
|
||||
(is (match? (count chains) 1))
|
||||
(is (match? (first chains) constants/arbitrum-mainnet-chain-id)))))
|
||||
|
||||
(h/deftest-sub :wallet/aggregated-tokens-in-selected-networks
|
||||
[sub-name]
|
||||
(testing "aggregated tokens in selected networks"
|
||||
(swap! rf-db/app-db
|
||||
#(-> %
|
||||
(assoc-in [:wallet :ui :network-filter :selected-networks] #{constants/optimism-network-name})
|
||||
(assoc-in [:wallet :accounts] accounts)
|
||||
(assoc-in [:wallet :networks] network-data)))
|
||||
|
||||
(let [result (rf/sub [sub-name])
|
||||
token (first result)
|
||||
chains (-> token
|
||||
:balances-per-chain
|
||||
keys)]
|
||||
(is (match? (count chains) 1))
|
||||
(is (match? (first chains) constants/optimism-mainnet-chain-id)))))
|
||||
|
||||
(h/deftest-sub :wallet/aggregated-fiat-balance-per-chain
|
||||
[sub-name]
|
||||
(testing "aggregated fiat balance per chain"
|
||||
(swap! rf-db/app-db
|
||||
#(-> %
|
||||
(assoc-in [:wallet :accounts] accounts)
|
||||
(assoc-in [:wallet :networks] network-data)
|
||||
(assoc-in [:profile/profile :currency] :usd)))
|
||||
|
||||
(let [result (rf/sub [sub-name])
|
||||
chains (keys result)]
|
||||
(is (match? (count chains) 3))
|
||||
(is (match? (get result constants/ethereum-mainnet-chain-id) "$3504.00"))
|
||||
(is (match? (get result constants/optimism-mainnet-chain-id) "$1002.00")))))
|
||||
|
||||
(h/deftest-sub :wallet/current-viewing-account-fiat-balance-per-chain
|
||||
[sub-name]
|
||||
(testing "current viewing account fiat balance per chain"
|
||||
(swap! rf-db/app-db
|
||||
#(-> %
|
||||
(assoc-in [:wallet :accounts] accounts)
|
||||
(assoc-in [:wallet :networks] network-data)
|
||||
(assoc-in [:wallet :current-viewing-account-address] "0x2")
|
||||
(assoc-in [:profile/profile :currency] :usd)))
|
||||
|
||||
(let [result (rf/sub [sub-name])
|
||||
chains (keys result)]
|
||||
(is (match? (count chains) 3))
|
||||
(is (match? (get result constants/ethereum-mainnet-chain-id) "$1500.00"))
|
||||
(is (match? (get result constants/optimism-mainnet-chain-id) "$600.00"))
|
||||
(is (match? (get result constants/arbitrum-mainnet-chain-id) "$0.00")))))
|
||||
|
|
Loading…
Reference in New Issue