diff --git a/src/status_im/contexts/wallet/events.cljs b/src/status_im/contexts/wallet/events.cljs index 8e17276b68c0..160ed2e0b8fc 100644 --- a/src/status_im/contexts/wallet/events.cljs +++ b/src/status_im/contexts/wallet/events.cljs @@ -5,6 +5,7 @@ [react-native.platform :as platform] [status-im.constants :as constants] [status-im.contexts.settings.wallet.events] + [status-im.contexts.wallet.common.utils :as utils] [status-im.contexts.wallet.common.utils.networks :as network-utils] [status-im.contexts.wallet.data-store :as data-store] [status-im.contexts.wallet.db :as db] @@ -42,8 +43,19 @@ [:dispatch [:wallet/show-account-created-toast address]]]})) (rf/reg-event-fx :wallet/switch-current-viewing-account - (fn [{:keys [db]} [address]] - {:db (assoc-in db [:wallet :current-viewing-account-address] address)})) + (fn [{:keys [db]} [{:keys [address network-details update-balance?]}]] + (let [current-token (-> db :wallet :ui :send :token) + token (when (and current-token update-balance?) + ;; When this flow has started in the wallet home page, we know the + ;; token or collectible to send, but we don't know from which + ;; account, so we extract the token data from the picked account. + (let [token (utils/get-token-from-account db (:symbol current-token) address)] + (assoc token + :networks (network-utils/network-list token network-details) + :total-balance (utils/calculate-total-token-balance token))))] + {:db (cond-> db + :always (assoc-in [:wallet :current-viewing-account-address] address) + token (assoc-in [:wallet :ui :send :token] token))}))) (rf/reg-event-fx :wallet/clean-current-viewing-account (fn [{:keys [db]}] diff --git a/src/status_im/contexts/wallet/send/events.cljs b/src/status_im/contexts/wallet/send/events.cljs index 3a95683b8c12..e7023930d1e1 100644 --- a/src/status_im/contexts/wallet/send/events.cljs +++ b/src/status_im/contexts/wallet/send/events.cljs @@ -26,60 +26,80 @@ (rf/reg-event-fx :wallet/suggested-routes-success (fn [{:keys [db]} [suggested-routes timestamp]] (when (= (get-in db [:wallet :ui :send :suggested-routes-call-timestamp]) timestamp) - (let [suggested-routes-data (cske/transform-keys transforms/->kebab-case-keyword - suggested-routes) - chosen-route (:best suggested-routes-data) - token (get-in db [:wallet :ui :send :token]) - collectible (get-in db [:wallet :ui :send :collectible]) - token-display-name (get-in db [:wallet :ui :send :token-display-name]) - receiver-networks (get-in db [:wallet :ui :send :receiver-networks]) - receiver-network-values (get-in db [:wallet :ui :send :receiver-network-values]) - sender-network-values (get-in db [:wallet :ui :send :sender-network-values]) - tx-type (get-in db [:wallet :ui :send :tx-type]) - disabled-from-chain-ids (or (get-in db [:wallet :ui :send :disabled-from-chain-ids]) []) - token-decimals (if collectible 0 (:decimals token)) - native-token? (and token (= token-display-name "ETH")) - routes-available? (pos? (count chosen-route)) - token-networks (:networks token) - token-networks-ids (when token-networks (mapv #(:chain-id %) token-networks)) - from-network-amounts-by-chain (send-utils/network-amounts-by-chain {:route chosen-route - :token-decimals - token-decimals - :native-token? - native-token? - :receiver? false}) - from-network-values-for-ui (send-utils/network-values-for-ui from-network-amounts-by-chain) - to-network-amounts-by-chain (send-utils/network-amounts-by-chain {:route chosen-route - :token-decimals - token-decimals - :native-token? - native-token? - :receiver? true}) - to-network-values-for-ui (send-utils/network-values-for-ui to-network-amounts-by-chain) - sender-network-values (if routes-available? - (send-utils/network-amounts - {:network-values from-network-values-for-ui - :disabled-chain-ids disabled-from-chain-ids - :receiver-networks receiver-networks - :token-networks-ids token-networks-ids - :tx-type tx-type - :receiver? false}) - (send-utils/reset-network-amounts-to-zero - sender-network-values)) - receiver-network-values (if routes-available? - (send-utils/network-amounts - {:network-values to-network-values-for-ui - :disabled-chain-ids disabled-from-chain-ids - :receiver-networks receiver-networks - :token-networks-ids token-networks-ids - :tx-type tx-type - :receiver? true}) - (send-utils/reset-network-amounts-to-zero - receiver-network-values)) - network-links (when routes-available? - (send-utils/network-links chosen-route - sender-network-values - receiver-network-values))] + (let [suggested-routes-data (cske/transform-keys + transforms/->kebab-case-keyword + suggested-routes) + chosen-route (:best suggested-routes-data) + token (get-in db [:wallet :ui :send :token]) + collectible (get-in db [:wallet :ui :send :collectible]) + token-display-name (get-in db + [:wallet :ui :send :token-display-name]) + receiver-networks (get-in db [:wallet :ui :send :receiver-networks]) + receiver-network-values (get-in db + [:wallet :ui :send + :receiver-network-values]) + sender-network-values (get-in db + [:wallet :ui :send + :sender-network-values]) + tx-type (get-in db [:wallet :ui :send :tx-type]) + disabled-from-chain-ids (or (get-in db + [:wallet :ui :send + :disabled-from-chain-ids]) + []) + token-decimals (if collectible 0 (:decimals token)) + native-token? (and token (= token-display-name "ETH")) + routes-available? (pos? (count chosen-route)) + token-networks (:networks token) + token-networks-ids (when token-networks + (mapv #(:chain-id %) token-networks)) + from-network-amounts-by-chain (send-utils/network-amounts-by-chain + {:route chosen-route + :token-decimals + token-decimals + :native-token? + native-token? + :receiver? false}) + from-network-values-for-ui (send-utils/network-values-for-ui + from-network-amounts-by-chain) + sender-possible-chain-ids (mapv :chain-id sender-network-values) + from-network-values-for-ui-with-zero-values (send-utils/add-zero-values-to-network-values + from-network-values-for-ui + sender-possible-chain-ids) + to-network-amounts-by-chain (send-utils/network-amounts-by-chain + {:route chosen-route + :token-decimals + token-decimals + :native-token? + native-token? + :receiver? true}) + to-network-values-for-ui (send-utils/network-values-for-ui + to-network-amounts-by-chain) + sender-network-values (if routes-available? + (send-utils/network-amounts + {:network-values + from-network-values-for-ui-with-zero-values + :disabled-chain-ids disabled-from-chain-ids + :receiver-networks receiver-networks + :token-networks-ids token-networks-ids + :tx-type tx-type + :receiver? false}) + (send-utils/reset-network-amounts-to-zero + sender-network-values)) + receiver-network-values (if routes-available? + (send-utils/network-amounts + {:network-values to-network-values-for-ui + :disabled-chain-ids disabled-from-chain-ids + :receiver-networks receiver-networks + :token-networks-ids token-networks-ids + :tx-type tx-type + :receiver? true}) + (send-utils/reset-network-amounts-to-zero + receiver-network-values)) + network-links (when routes-available? + (send-utils/network-links + chosen-route + sender-network-values + receiver-network-values))] {:db (-> db (assoc-in [:wallet :ui :send :suggested-routes] suggested-routes-data) (assoc-in [:wallet :ui :send :route] chosen-route) @@ -338,32 +358,42 @@ :tx/bridge constants/send-type-bridge constants/send-type-transfer) balances-per-chain (when token (:balances-per-chain token)) - token-available-networks-for-suggested-routes + sender-token-available-networks-for-suggested-routes (when token (send-utils/token-available-networks-for-suggested-routes {:balances-per-chain balances-per-chain :disabled-chain-ids - disabled-from-chain-ids})) + disabled-from-chain-ids + :only-with-balance? true})) + receiver-token-available-networks-for-suggested-routes + (when token + (send-utils/token-available-networks-for-suggested-routes {:balances-per-chain + balances-per-chain + :disabled-chain-ids + disabled-from-chain-ids + :only-with-balance? false})) token-networks-ids (when token (mapv #(:chain-id %) (:networks token))) - sender-network-values (when token-available-networks-for-suggested-routes + sender-network-values (when sender-token-available-networks-for-suggested-routes (send-utils/loading-network-amounts - {:valid-networks (if (= transaction-type :tx/bridge) - (filter - #(not= bridge-to-chain-id %) - token-available-networks-for-suggested-routes) - token-available-networks-for-suggested-routes) + {:valid-networks + (if (= transaction-type :tx/bridge) + (filter + #(not= bridge-to-chain-id %) + sender-token-available-networks-for-suggested-routes) + sender-token-available-networks-for-suggested-routes) :disabled-chain-ids disabled-from-chain-ids - :receiver-networks receiver-networks + :receiver-networks receiver-networks :token-networks-ids token-networks-ids - :tx-type transaction-type - :receiver? false})) - receiver-network-values (when token-available-networks-for-suggested-routes + :tx-type transaction-type + :receiver? false})) + receiver-network-values (when receiver-token-available-networks-for-suggested-routes (send-utils/loading-network-amounts - {:valid-networks (if (= transaction-type :tx/bridge) - (filter - #(= bridge-to-chain-id %) - token-available-networks-for-suggested-routes) - token-available-networks-for-suggested-routes) + {:valid-networks + (if (= transaction-type :tx/bridge) + (filter + #(= bridge-to-chain-id %) + receiver-token-available-networks-for-suggested-routes) + receiver-token-available-networks-for-suggested-routes) :disabled-chain-ids disabled-from-chain-ids :receiver-networks receiver-networks :token-networks-ids token-networks-ids @@ -600,7 +630,11 @@ (assoc-in [:wallet :ui :send :token] token) (update-in [:wallet :ui :send] dissoc :token-symbol)) db) - :fx [[:dispatch [:wallet/switch-current-viewing-account address]] + :fx [[:dispatch + [:wallet/switch-current-viewing-account + {:address address + :network-details network-details + :update-balance? false}]] [:dispatch [:wallet/wizard-navigate-forward {:current-screen stack-id diff --git a/src/status_im/contexts/wallet/send/utils.cljs b/src/status_im/contexts/wallet/send/utils.cljs index fff924c4d0d4..32a79aafbe23 100644 --- a/src/status_im/contexts/wallet/send/utils.cljs +++ b/src/status_im/contexts/wallet/send/utils.cljs @@ -67,10 +67,24 @@ {} amounts)) +(defn add-zero-values-to-network-values + [network-values all-possible-chain-ids] + (reduce + (fn [acc chain-id] + (let [route-value (get network-values chain-id)] + (assoc acc chain-id (or route-value (money/bignumber "0"))))) + {} + all-possible-chain-ids)) + (defn token-available-networks-for-suggested-routes - [{:keys [balances-per-chain disabled-chain-ids]}] + [{:keys [balances-per-chain disabled-chain-ids only-with-balance?]}] (let [disabled-set (set disabled-chain-ids)] (->> balances-per-chain + (filter (fn [[_ {:keys [raw-balance]}]] + (or (not only-with-balance?) + (and only-with-balance? + (and (money/bignumber? raw-balance) + (money/greater-than raw-balance (money/bignumber "0"))))))) (filter (fn [[_ {:keys [chain-id]}]] (not (contains? disabled-set chain-id)))) (map first)))) diff --git a/src/status_im/contexts/wallet/sheets/account_options/view.cljs b/src/status_im/contexts/wallet/sheets/account_options/view.cljs index 4ad607292713..5a53dbb6279e 100644 --- a/src/status_im/contexts/wallet/sheets/account_options/view.cljs +++ b/src/status_im/contexts/wallet/sheets/account_options/view.cljs @@ -16,7 +16,7 @@ [utils.re-frame :as rf])) (defn- render-account-item - [{:keys [name emoji color address watch-only?]}] + [{:keys [name emoji color address watch-only?]} _ _ {:keys [network-details]}] [quo/account-item {:account-props (cond-> {:name name :emoji emoji @@ -27,7 +27,10 @@ (assoc :type :watch-only)) :title-icon (when watch-only? :i/reveal) :on-press (fn [] - (rf/dispatch [:wallet/switch-current-viewing-account address]) + (rf/dispatch [:wallet/switch-current-viewing-account + {:address address + :network-details network-details + :update-balance? true}]) (rf/dispatch [:hide-bottom-sheet]))}]) (defn- options @@ -111,12 +114,14 @@ (fn [] (let [theme (quo.theme/use-theme) accounts (rf/sub [:wallet/accounts-without-current-viewing-account]) - show-account-selector? (pos? (count accounts))] + show-account-selector? (pos? (count accounts)) + network-details (rf/sub [:wallet/network-details])] [:<> (when show-account-selector? [gesture/flat-list {:data accounts :render-fn render-account-item + :render-data {:network-details network-details} :content-container-style (style/list-container @options-height) :shows-vertical-scroll-indicator false}]) [options diff --git a/src/status_im/contexts/wallet/sheets/select_account/view.cljs b/src/status_im/contexts/wallet/sheets/select_account/view.cljs index 5a3df1d0f05f..ece930ae532e 100644 --- a/src/status_im/contexts/wallet/sheets/select_account/view.cljs +++ b/src/status_im/contexts/wallet/sheets/select_account/view.cljs @@ -7,25 +7,30 @@ [utils.re-frame :as rf])) (defn- render-account-item - [{:keys [color address] :as account} _ _ {:keys [selected-account-address]}] + [{:keys [color address] :as account} _ _ {:keys [selected-account-address network-details]}] [quo/account-item {:type :default :account-props (assoc account :customization-color color) :customization-color color :state (if (= address selected-account-address) :selected :default) :on-press (fn [] - (rf/dispatch [:wallet/switch-current-viewing-account address]) + (rf/dispatch [:wallet/switch-current-viewing-account + {:address address + :network-details network-details + :update-balance? true}]) (rf/dispatch [:hide-bottom-sheet]))}]) (defn view [] (let [selected-account-address (rf/sub [:wallet/current-viewing-account-address]) - accounts (rf/sub [:wallet/accounts-without-watched-accounts])] + accounts (rf/sub [:wallet/accounts-without-watched-accounts]) + network-details (rf/sub [:wallet/network-details])] [:<> [quo/drawer-top {:title (i18n/label :t/select-account)}] [gesture/flat-list {:data accounts :render-fn render-account-item - :render-data {:selected-account-address selected-account-address} + :render-data {:selected-account-address selected-account-address + :network-details network-details} :content-container-style style/list-container :shows-vertical-scroll-indicator false}]]))