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

View File

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

View File

@ -3,7 +3,8 @@
(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
:width "100%"
:justify-content (if route-loaded? :space-between :center) :justify-content (if route-loaded? :space-between :center)
:height (when (or loading-suggested-routes? route-loaded?) 52) :height (when (or loading-suggested-routes? route-loaded?) 52)
:padding-horizontal 12 :margin-horizontal 5
:padding-top 7 :padding-top 7
:padding-bottom 8 :margin-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})
(defn section-label (defn section-label
[theme] [theme]

View File

@ -166,27 +166,16 @@
(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
{: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 [rn/view
{:style (style/details-container {:style (style/details-container
{:loading-suggested-routes? loading-suggested-routes? {:loading-suggested-routes? loading-suggested-routes?
:route-loaded? route-loaded? :route-loaded? route-loaded?})}
:theme theme})}
(cond (cond
loading-suggested-routes? loading-suggested-routes?
[rn/activity-indicator {:style {:align-self :center}}] [rn/activity-indicator {:style {:flex 1}}]
route-loaded? route-loaded?
[:<> [:<>
[data-item [data-item
@ -194,9 +183,7 @@
:subtitle (i18n/label :t/time-in-mins {:minutes (str estimated-time-min)})}] :subtitle (i18n/label :t/time-in-mins {:minutes (str estimated-time-min)})}]
[data-item [data-item
{:title (i18n/label :t/max-fees) {:title (i18n/label :t/max-fees)
:subtitle (i18n/label :t/amount-with-currency-symbol :subtitle max-fees}]
{:amount (str max-fees)
:symbol currency-symbol})}]
[data-item [data-item
{:title (if (= transaction-type :tx/bridge) {:title (if (= transaction-type :tx/bridge)
(i18n/label :t/bridged-to (i18n/label :t/bridged-to
@ -205,7 +192,7 @@
:subtitle (str amount " " token-display-name)}]] :subtitle (str amount " " token-display-name)}]]
:else :else
[quo/text {:style {:align-self :center}} [quo/text {:style {:align-self :center}}
(i18n/label :t/no-routes-found-confirmation)])]])) (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,7 +238,17 @@
: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 [:<>
[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 [standard-auth/slide-button
{:size :size-48 {:size :size-48
:track-text (if (= transaction-type :tx/bridge) :track-text (if (= transaction-type :tx/bridge)
@ -258,7 +260,7 @@
[:wallet/send-transaction [:wallet/send-transaction
(security/safe-unmask-data (security/safe-unmask-data
%)]) %)])
:auth-button-label (i18n/label :t/confirm)}]) :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}]]]]))))

View File

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

View File

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