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