feat: calculate and show max fees on transaction confirmation page (#20133)

Signed-off-by: Brian Sztamfater <brian@status.im>
This commit is contained in:
Brian Sztamfater 2024-05-28 18:16:47 -03:00 committed by GitHub
parent 47f6bda563
commit a63ea3290e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 114 additions and 99 deletions

View File

@ -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)

View File

@ -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

View File

@ -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]

View File

@ -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}]]]]))))

View File

@ -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)))

View File

@ -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")))))