feat: calculate and show max fees on transaction confirmation page (#20133)
Signed-off-by: Brian Sztamfater <brian@status.im>
This commit is contained in:
parent
47f6bda563
commit
a63ea3290e
|
@ -96,7 +96,8 @@
|
|||
:layer 1}]
|
||||
:wallet/wallet-send-enabled-from-chain-ids [1]
|
||||
:wallet/wallet-send-amount nil
|
||||
:wallet/wallet-send-tx-type :tx/send})
|
||||
:wallet/wallet-send-tx-type :tx/send
|
||||
:wallet/wallet-send-fee-fiat-formatted "$5,00"})
|
||||
|
||||
(h/describe "Send > input amount screen"
|
||||
(h/setup-restorable-re-frame)
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.send.input-amount.style :as style]
|
||||
[status-im.contexts.wallet.send.routes.view :as routes]
|
||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||
[status-im.contexts.wallet.sheets.unpreferred-networks-alert.view :as unpreferred-networks-alert]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
|
@ -227,22 +226,8 @@
|
|||
native-token (when native-currency-symbol
|
||||
(rf/sub [:wallet/token-by-symbol
|
||||
native-currency-symbol]))
|
||||
fee-in-native-token (when-not confirm-disabled?
|
||||
(send-utils/calculate-full-route-gas-fee route))
|
||||
fee-in-crypto-formatted (when fee-in-native-token
|
||||
(utils/get-standard-crypto-format
|
||||
native-token
|
||||
fee-in-native-token))
|
||||
fee-in-fiat (when-not confirm-disabled?
|
||||
(utils/calculate-token-fiat-value
|
||||
{:currency fiat-currency
|
||||
:balance fee-in-native-token
|
||||
:token native-token}))
|
||||
fee-formatted (when fee-in-fiat
|
||||
(utils/get-standard-fiat-format
|
||||
fee-in-crypto-formatted
|
||||
currency-symbol
|
||||
fee-in-fiat))
|
||||
fee-formatted (rf/sub [:wallet/wallet-send-fee-fiat-formatted
|
||||
native-token])
|
||||
show-select-asset-sheet #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn []
|
||||
|
@ -349,7 +334,7 @@
|
|||
sender-network-values
|
||||
token-not-supported-in-receiver-networks?)
|
||||
[token-not-available token-symbol receiver-networks token-networks])
|
||||
(when (or loading-routes? fee-formatted)
|
||||
(when (or loading-routes? route)
|
||||
[estimated-fees
|
||||
{:loading-routes? loading-routes?
|
||||
:fees fee-formatted
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def detail-item
|
||||
{:flex 1
|
||||
:height 36})
|
||||
{:flex 1
|
||||
:height 36
|
||||
:background-color :transparent})
|
||||
|
||||
(def content-container
|
||||
{:padding-top 12
|
||||
|
@ -14,22 +15,14 @@
|
|||
{:margin-right 4})
|
||||
|
||||
(defn details-container
|
||||
[{:keys [loading-suggested-routes? route-loaded? theme]}]
|
||||
{:flex-direction :row
|
||||
:justify-content (if route-loaded? :space-between :center)
|
||||
:height (when (or loading-suggested-routes? route-loaded?) 52)
|
||||
:padding-horizontal 12
|
||||
:padding-top 7
|
||||
:padding-bottom 8
|
||||
:border-radius 16
|
||||
:border-width 1
|
||||
:border-color (if (or loading-suggested-routes? route-loaded?)
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-90 theme)
|
||||
:transparent)})
|
||||
|
||||
(def details-title-container
|
||||
{:padding-horizontal 20
|
||||
:padding-bottom 16})
|
||||
[{:keys [loading-suggested-routes? route-loaded?]}]
|
||||
{:flex-direction :row
|
||||
:width "100%"
|
||||
:justify-content (if route-loaded? :space-between :center)
|
||||
:height (when (or loading-suggested-routes? route-loaded?) 52)
|
||||
:margin-horizontal 5
|
||||
:padding-top 7
|
||||
:margin-bottom 8})
|
||||
|
||||
(defn section-label
|
||||
[theme]
|
||||
|
|
|
@ -166,46 +166,33 @@
|
|||
|
||||
(defn- transaction-details
|
||||
[{:keys [estimated-time-min max-fees token-display-name amount to-network route
|
||||
transaction-type
|
||||
theme]}]
|
||||
(let [currency-symbol (rf/sub [:profile/currency-symbol])
|
||||
route-loaded? (and route (seq route))
|
||||
transaction-type]}]
|
||||
(let [route-loaded? (and route (seq route))
|
||||
loading-suggested-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])]
|
||||
[rn/view
|
||||
{:style style/details-title-container}
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (style/section-label theme)
|
||||
:accessibility-label :summary-from-label}
|
||||
(i18n/label :t/details)]
|
||||
[rn/view
|
||||
{:style (style/details-container
|
||||
{:loading-suggested-routes? loading-suggested-routes?
|
||||
:route-loaded? route-loaded?
|
||||
:theme theme})}
|
||||
(cond
|
||||
loading-suggested-routes?
|
||||
[rn/activity-indicator {:style {:align-self :center}}]
|
||||
route-loaded?
|
||||
[:<>
|
||||
[data-item
|
||||
{:title (i18n/label :t/est-time)
|
||||
:subtitle (i18n/label :t/time-in-mins {:minutes (str estimated-time-min)})}]
|
||||
[data-item
|
||||
{:title (i18n/label :t/max-fees)
|
||||
:subtitle (i18n/label :t/amount-with-currency-symbol
|
||||
{:amount (str max-fees)
|
||||
:symbol currency-symbol})}]
|
||||
[data-item
|
||||
{:title (if (= transaction-type :tx/bridge)
|
||||
(i18n/label :t/bridged-to
|
||||
{:network (:abbreviated-name to-network)})
|
||||
(i18n/label :t/recipient-gets))
|
||||
:subtitle (str amount " " token-display-name)}]]
|
||||
:else
|
||||
[quo/text {:style {:align-self :center}}
|
||||
(i18n/label :t/no-routes-found-confirmation)])]]))
|
||||
{:style (style/details-container
|
||||
{:loading-suggested-routes? loading-suggested-routes?
|
||||
:route-loaded? route-loaded?})}
|
||||
(cond
|
||||
loading-suggested-routes?
|
||||
[rn/activity-indicator {:style {:flex 1}}]
|
||||
route-loaded?
|
||||
[:<>
|
||||
[data-item
|
||||
{:title (i18n/label :t/est-time)
|
||||
:subtitle (i18n/label :t/time-in-mins {:minutes (str estimated-time-min)})}]
|
||||
[data-item
|
||||
{:title (i18n/label :t/max-fees)
|
||||
:subtitle max-fees}]
|
||||
[data-item
|
||||
{:title (if (= transaction-type :tx/bridge)
|
||||
(i18n/label :t/bridged-to
|
||||
{:network (:abbreviated-name to-network)})
|
||||
(i18n/label :t/recipient-gets))
|
||||
:subtitle (str amount " " token-display-name)}]]
|
||||
:else
|
||||
[quo/text {:style {:align-self :center}}
|
||||
(i18n/label :t/no-routes-found-confirmation)])]))
|
||||
|
||||
(defn view
|
||||
[_]
|
||||
|
@ -222,12 +209,17 @@
|
|||
(get-in collectible [:preview-url :uri]))
|
||||
transaction-type (:tx-type send-transaction-data)
|
||||
estimated-time-min (reduce + (map :estimated-time route))
|
||||
max-fees "-"
|
||||
first-route (first route)
|
||||
native-currency-symbol (get-in first-route [:from :native-currency-symbol])
|
||||
native-token (when native-currency-symbol
|
||||
(rf/sub [:wallet/token-by-symbol native-currency-symbol]))
|
||||
fee-formatted (rf/sub [:wallet/wallet-send-fee-fiat-formatted native-token])
|
||||
account (rf/sub [:wallet/current-viewing-account])
|
||||
account-color (:color account)
|
||||
bridge-to-network (when bridge-to-chain-id
|
||||
(rf/sub [:wallet/network-details-by-chain-id
|
||||
bridge-to-chain-id]))
|
||||
loading-suggested-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
|
||||
from-account-props {:customization-color account-color
|
||||
:size 32
|
||||
:emoji (:emoji account)
|
||||
|
@ -246,19 +238,29 @@
|
|||
:margin-top (safe-area/get-top)
|
||||
:background :blur
|
||||
:accessibility-label :top-bar}]
|
||||
:footer (when (and route (seq route))
|
||||
[standard-auth/slide-button
|
||||
{:size :size-48
|
||||
:track-text (if (= transaction-type :tx/bridge)
|
||||
(i18n/label :t/slide-to-bridge)
|
||||
(i18n/label :t/slide-to-send))
|
||||
:container-style {:z-index 2}
|
||||
:customization-color account-color
|
||||
:on-auth-success #(rf/dispatch
|
||||
[:wallet/send-transaction
|
||||
(security/safe-unmask-data
|
||||
%)])
|
||||
:auth-button-label (i18n/label :t/confirm)}])
|
||||
:footer [:<>
|
||||
[transaction-details
|
||||
{:estimated-time-min estimated-time-min
|
||||
:max-fees fee-formatted
|
||||
:token-display-name token-display-name
|
||||
:amount amount
|
||||
:to-network bridge-to-network
|
||||
:theme theme
|
||||
:route route
|
||||
:transaction-type transaction-type}]
|
||||
(when (and (not loading-suggested-routes?) route (seq route))
|
||||
[standard-auth/slide-button
|
||||
{:size :size-48
|
||||
:track-text (if (= transaction-type :tx/bridge)
|
||||
(i18n/label :t/slide-to-bridge)
|
||||
(i18n/label :t/slide-to-send))
|
||||
:container-style {:z-index 2}
|
||||
:customization-color account-color
|
||||
:on-auth-success #(rf/dispatch
|
||||
[:wallet/send-transaction
|
||||
(security/safe-unmask-data
|
||||
%)])
|
||||
:auth-button-label (i18n/label :t/confirm)}])]
|
||||
:gradient-cover? true
|
||||
:customization-color (:color account)}
|
||||
[rn/view
|
||||
|
@ -291,13 +293,4 @@
|
|||
from-account-props
|
||||
user-props)
|
||||
:network-values to-values-by-chain
|
||||
:theme theme}]
|
||||
[transaction-details
|
||||
{:estimated-time-min estimated-time-min
|
||||
:max-fees max-fees
|
||||
:token-display-name token-display-name
|
||||
:amount amount
|
||||
:to-network bridge-to-network
|
||||
:theme theme
|
||||
:route route
|
||||
:transaction-type transaction-type}]]]]))))
|
||||
:theme theme}]]]]))))
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||
[status-im.subs.wallet.add-account.address-to-watch]
|
||||
[utils.number]
|
||||
[utils.security.core :as security]))
|
||||
|
@ -574,3 +575,23 @@
|
|||
:<- [:wallet/wallet-send-enabled-networks]
|
||||
(fn [send-enabled-networks]
|
||||
(map :chain-id send-enabled-networks)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/wallet-send-fee-fiat-formatted
|
||||
:<- [:wallet/wallet-send-route]
|
||||
:<- [:profile/currency]
|
||||
:<- [:profile/currency-symbol]
|
||||
(fn [[route currency currency-symbol] [_ token-for-fees]]
|
||||
(let [fee-in-native-token (send-utils/calculate-full-route-gas-fee route)
|
||||
fee-in-crypto-formatted (utils/get-standard-crypto-format
|
||||
token-for-fees
|
||||
fee-in-native-token)
|
||||
fee-in-fiat (utils/calculate-token-fiat-value
|
||||
{:currency currency
|
||||
:balance fee-in-native-token
|
||||
:token token-for-fees})
|
||||
fee-formatted (utils/get-standard-fiat-format
|
||||
fee-in-crypto-formatted
|
||||
currency-symbol
|
||||
fee-in-fiat)]
|
||||
fee-formatted)))
|
||||
|
|
|
@ -187,6 +187,12 @@
|
|||
:chain-id 10
|
||||
:layer 2}]})
|
||||
|
||||
(def route-data
|
||||
[{:gas-amount "25000"
|
||||
:gas-fees {:max-fee-per-gas-medium "4"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "0"}}])
|
||||
|
||||
(h/deftest-sub :wallet/balances-in-selected-networks
|
||||
[sub-name]
|
||||
(testing "a map: address->balance"
|
||||
|
@ -890,3 +896,19 @@
|
|||
(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")))))
|
||||
|
||||
(h/deftest-sub :wallet/wallet-send-fee-fiat-formatted
|
||||
[sub-name]
|
||||
(testing "wallet send fee calculated and formatted in fiat"
|
||||
(swap! rf-db/app-db
|
||||
#(-> %
|
||||
(assoc-in [:wallet :ui :send :route] route-data)
|
||||
(assoc-in [:profile/profile :currency] :usd)
|
||||
(assoc-in [:profile/profile :currency-symbol] "$")))
|
||||
|
||||
(let [token-for-fees {:decimals 18
|
||||
:symbol "ETH"
|
||||
:name "Ether"
|
||||
:market-values-per-currency {:usd {:price 10000}}}
|
||||
result (rf/sub [sub-name token-for-fees])]
|
||||
(is (match? result "$1.00")))))
|
||||
|
|
Loading…
Reference in New Issue