feat: show estimated fees when calculating route (#18309)
Signed-off-by: Brian Sztamfater <brian@status.im>
This commit is contained in:
parent
f1db73d149
commit
ab73c7e56a
|
@ -121,7 +121,7 @@
|
||||||
{:accessibility-label :data-item
|
{:accessibility-label :data-item
|
||||||
:disabled (not icon-right?)
|
:disabled (not icon-right?)
|
||||||
:on-press on-press
|
:on-press on-press
|
||||||
:style (merge container-style (style/container size card? blur? theme))}
|
:style (merge (style/container size card? blur? theme) container-style)}
|
||||||
[left-side props]
|
[left-side props]
|
||||||
(when (and (= :default status) (not= :small size))
|
(when (and (= :default status) (not= :small size))
|
||||||
[right-side
|
[right-side
|
||||||
|
|
|
@ -218,7 +218,7 @@
|
||||||
(defn get-standard-fiat-format
|
(defn get-standard-fiat-format
|
||||||
[crypto-value currency-symbol fiat-value]
|
[crypto-value currency-symbol fiat-value]
|
||||||
(if (string/includes? crypto-value "<")
|
(if (string/includes? crypto-value "<")
|
||||||
"<$0.01"
|
(str "<" currency-symbol "0.01")
|
||||||
(prettify-balance currency-symbol fiat-value)))
|
(prettify-balance currency-symbol fiat-value)))
|
||||||
|
|
||||||
(defn prettify-percentage-change
|
(defn prettify-percentage-change
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
(ns status-im.contexts.wallet.common.utils.send
|
||||||
|
(:require [utils.money :as money]))
|
||||||
|
|
||||||
|
(defn calculate-gas-fee
|
||||||
|
[data]
|
||||||
|
(let [gas-amount (money/bignumber (get data :gas-amount))
|
||||||
|
gas-fees (get data :gas-fees)
|
||||||
|
eip1559-enabled? (get gas-fees :eip1559-enabled)
|
||||||
|
billion (money/bignumber "1000000000")]
|
||||||
|
(if eip1559-enabled?
|
||||||
|
(let [base-fee (money/bignumber (get gas-fees :base-fee))
|
||||||
|
priority-fee (money/bignumber (get gas-fees :max-priority-fee-per-gas))
|
||||||
|
fee-with-tip (money/bignumber (money/add base-fee priority-fee))
|
||||||
|
total-gas-fee (money/mul gas-amount fee-with-tip)]
|
||||||
|
(money/with-precision (money/div total-gas-fee billion) 10))
|
||||||
|
(let [gas-price (money/bignumber (get gas-fees :gas-price))
|
||||||
|
total-gas-fee (money/mul gas-amount gas-price)]
|
||||||
|
(money/with-precision (money/div total-gas-fee billion) 10)))))
|
|
@ -0,0 +1,22 @@
|
||||||
|
(ns status-im.contexts.wallet.common.utils.send-test
|
||||||
|
(:require [cljs.test :refer [deftest is testing]]
|
||||||
|
[status-im.contexts.wallet.common.utils.send :as utils]
|
||||||
|
[utils.money :as money]))
|
||||||
|
|
||||||
|
(deftest test-calculate-gas-fee
|
||||||
|
(testing "Test calculate-gas-fee function with EIP-1559 enabled"
|
||||||
|
(let [data-eip1559-enabled {:gas-amount "23487"
|
||||||
|
:gas-fees {:base-fee "32.325296406"
|
||||||
|
:max-priority-fee-per-gas "0.011000001"
|
||||||
|
:eip1559-enabled true}}
|
||||||
|
expected-eip1559-enabled-result (money/bignumber 0.0007594826)]
|
||||||
|
(is (money/equal-to (utils/calculate-gas-fee data-eip1559-enabled)
|
||||||
|
expected-eip1559-enabled-result)))
|
||||||
|
|
||||||
|
(testing "Test calculate-gas-fee function with EIP-1559 disabled"
|
||||||
|
(let [data-eip1559-disabled {:gas-amount "23487"
|
||||||
|
:gas-fees {:gas-price "32.375609968"
|
||||||
|
:eip1559-enabled false}}
|
||||||
|
expected-eip1559-disabled-result (money/bignumber 0.000760406)]
|
||||||
|
(is (money/equal-to (utils/calculate-gas-fee data-eip1559-disabled)
|
||||||
|
expected-eip1559-disabled-result))))))
|
|
@ -43,10 +43,22 @@
|
||||||
:total-balance 100
|
:total-balance 100
|
||||||
:market-values-per-currency {:usd {:price 10}}}
|
:market-values-per-currency {:usd {:price 10}}}
|
||||||
:wallet/wallet-send-loading-suggested-routes? false
|
:wallet/wallet-send-loading-suggested-routes? false
|
||||||
:wallet/wallet-send-route {:route []}
|
:wallet/wallet-send-route {:from {:chainid 1
|
||||||
|
:native-currency-symbol "ETH"}
|
||||||
|
:to {:chain-id 1
|
||||||
|
:native-currency-symbol "ETH"}
|
||||||
|
:gas-amount "23487"
|
||||||
|
:gas-fees {:base-fee "32.325296406"
|
||||||
|
:max-priority-fee-per-gas "0.011000001"
|
||||||
|
:eip1559-enabled true}}
|
||||||
:wallet/wallet-send-suggested-routes {:candidates []}
|
:wallet/wallet-send-suggested-routes {:candidates []}
|
||||||
:wallet/wallet-send-selected-networks []
|
:wallet/wallet-send-selected-networks []
|
||||||
:navigation/current-screen-id :wallet-send-input-amount})
|
:navigation/current-screen-id :wallet-send-input-amount
|
||||||
|
:wallet/wallet-send-to-address "0x04371e2d9d66b82f056bc128064"
|
||||||
|
:profile/currency-symbol "$"
|
||||||
|
:wallet/token-by-symbol {:symbol :eth
|
||||||
|
:total-balance 100
|
||||||
|
:market-values-per-currency {:usd {:price 10}}}})
|
||||||
|
|
||||||
(defn- render
|
(defn- render
|
||||||
[component]
|
[component]
|
||||||
|
|
|
@ -10,3 +10,26 @@
|
||||||
(defn keyboard-container
|
(defn keyboard-container
|
||||||
[bottom]
|
[bottom]
|
||||||
{:padding-bottom bottom})
|
{:padding-bottom bottom})
|
||||||
|
|
||||||
|
(def estimated-fees-container
|
||||||
|
{:height 48
|
||||||
|
:width "100%"
|
||||||
|
:flex-direction :row
|
||||||
|
:align-items :center
|
||||||
|
:padding-horizontal 20
|
||||||
|
:padding-top 8})
|
||||||
|
|
||||||
|
(def estimated-fees-content-container
|
||||||
|
{:align-items :center
|
||||||
|
:height 40})
|
||||||
|
|
||||||
|
(def fees-data-item
|
||||||
|
{:flex 1
|
||||||
|
:height 40
|
||||||
|
:margin-horizontal 16
|
||||||
|
:background-color :transparent})
|
||||||
|
|
||||||
|
(def amount-data-item
|
||||||
|
{:flex 1
|
||||||
|
:height 40
|
||||||
|
:background-color :transparent})
|
||||||
|
|
|
@ -8,8 +8,10 @@
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
|
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
|
||||||
[status-im.contexts.wallet.common.utils :as utils]
|
[status-im.contexts.wallet.common.utils :as utils]
|
||||||
|
[status-im.contexts.wallet.common.utils.send :as send-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]
|
||||||
|
[utils.address :as address]
|
||||||
[utils.debounce :as debounce]
|
[utils.debounce :as debounce]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
@ -90,6 +92,34 @@
|
||||||
(let [size (count s)]
|
(let [size (count s)]
|
||||||
(str (subs s 0 (dec idx)) (subs s idx size))))
|
(str (subs s 0 (dec idx)) (subs s idx size))))
|
||||||
|
|
||||||
|
(defn- estimated-fees
|
||||||
|
[{:keys [loading-suggested-routes? fees amount receiver]}]
|
||||||
|
[rn/view {:style style/estimated-fees-container}
|
||||||
|
[rn/view {:style style/estimated-fees-content-container}
|
||||||
|
[quo/button
|
||||||
|
{:icon-only? true
|
||||||
|
:type :outline
|
||||||
|
:size 32
|
||||||
|
:inner-style {:opacity 1}
|
||||||
|
:accessibility-label :advanced-button
|
||||||
|
:disabled? loading-suggested-routes?
|
||||||
|
:on-press #(js/alert "Not implemented yet")}
|
||||||
|
:i/advanced]]
|
||||||
|
[quo/data-item
|
||||||
|
{:container-style style/fees-data-item
|
||||||
|
:label :none
|
||||||
|
:status (if loading-suggested-routes? :loading :default)
|
||||||
|
:size :small
|
||||||
|
:title (i18n/label :t/fees)
|
||||||
|
:subtitle fees}]
|
||||||
|
[quo/data-item
|
||||||
|
{:container-style style/amount-data-item
|
||||||
|
:label :none
|
||||||
|
:status (if loading-suggested-routes? :loading :default)
|
||||||
|
:size :small
|
||||||
|
:title (i18n/label :t/user-gets {:name receiver})
|
||||||
|
:subtitle amount}]])
|
||||||
|
|
||||||
(defn- f-view-internal
|
(defn- f-view-internal
|
||||||
;; crypto-decimals, limit-crypto and initial-crypto-currency? args are needed
|
;; crypto-decimals, limit-crypto and initial-crypto-currency? args are needed
|
||||||
;; for component tests only
|
;; for component tests only
|
||||||
|
@ -169,6 +199,7 @@
|
||||||
loading-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
|
loading-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
|
||||||
suggested-routes (rf/sub [:wallet/wallet-send-suggested-routes])
|
suggested-routes (rf/sub [:wallet/wallet-send-suggested-routes])
|
||||||
route (rf/sub [:wallet/wallet-send-route])
|
route (rf/sub [:wallet/wallet-send-route])
|
||||||
|
to-address (rf/sub [:wallet/wallet-send-to-address])
|
||||||
on-confirm (or default-on-confirm handle-on-confirm)
|
on-confirm (or default-on-confirm handle-on-confirm)
|
||||||
crypto-decimals (or default-crypto-decimals
|
crypto-decimals (or default-crypto-decimals
|
||||||
(utils/get-crypto-decimals-count token))
|
(utils/get-crypto-decimals-count token))
|
||||||
|
@ -184,7 +215,24 @@
|
||||||
(empty? @input-value)
|
(empty? @input-value)
|
||||||
(<= input-num-value 0)
|
(<= input-num-value 0)
|
||||||
(> input-num-value current-limit))
|
(> input-num-value current-limit))
|
||||||
amount-text (str @input-value " " token-symbol)]
|
amount-text (str @input-value " " token-symbol)
|
||||||
|
native-currency-symbol (when-not confirm-disabled?
|
||||||
|
(get-in route [:from :native-currency-symbol]))
|
||||||
|
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-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/token-fiat-value fiat-currency
|
||||||
|
fee-in-native-token
|
||||||
|
native-token))
|
||||||
|
currency-symbol (rf/sub [:profile/currency-symbol])
|
||||||
|
fee-formatted (when fee-in-fiat
|
||||||
|
(utils/get-standard-fiat-format fee-in-crypto-formatted
|
||||||
|
currency-symbol
|
||||||
|
fee-in-fiat))]
|
||||||
(rn/use-effect
|
(rn/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
(let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!))
|
(let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!))
|
||||||
|
@ -226,6 +274,12 @@
|
||||||
:token token
|
:token token
|
||||||
:input-value @input-value
|
:input-value @input-value
|
||||||
:fetch-routes #(fetch-routes % current-limit)}]
|
:fetch-routes #(fetch-routes % current-limit)}]
|
||||||
|
(when (or loading-routes? route)
|
||||||
|
[estimated-fees
|
||||||
|
{:loading-suggested-routes? loading-routes?
|
||||||
|
:fees fee-formatted
|
||||||
|
:amount amount-text
|
||||||
|
:receiver (address/get-shortened-key to-address)}])
|
||||||
[quo/bottom-actions
|
[quo/bottom-actions
|
||||||
{:actions :one-action
|
{:actions :one-action
|
||||||
:button-one-label (i18n/label :t/confirm)
|
:button-one-label (i18n/label :t/confirm)
|
||||||
|
|
|
@ -160,6 +160,22 @@
|
||||||
sorted-tokens)]
|
sorted-tokens)]
|
||||||
filtered-tokens)))
|
filtered-tokens)))
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/token-by-symbol
|
||||||
|
:<- [:wallet/current-viewing-account]
|
||||||
|
:<- [:wallet/network-details]
|
||||||
|
(fn [[account networks] [_ token-symbol]]
|
||||||
|
(let [tokens (map (fn [token]
|
||||||
|
(assoc token
|
||||||
|
:networks (utils/network-list token networks)
|
||||||
|
:total-balance (utils/total-token-units-in-all-chains token)
|
||||||
|
:total-balance-fiat (utils/calculate-balance-for-token token)))
|
||||||
|
(:tokens account))
|
||||||
|
token (first (filter #(= (string/lower-case (:symbol %))
|
||||||
|
(string/lower-case token-symbol))
|
||||||
|
tokens))]
|
||||||
|
token)))
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/accounts-without-current-viewing-account
|
:wallet/accounts-without-current-viewing-account
|
||||||
:<- [:wallet/accounts]
|
:<- [:wallet/accounts]
|
||||||
|
|
|
@ -2493,5 +2493,6 @@
|
||||||
"confirm-the-position": "Confirm the position of certain words in your recovery phrase",
|
"confirm-the-position": "Confirm the position of certain words in your recovery phrase",
|
||||||
"do-not-cheat": "Don't try to cheat",
|
"do-not-cheat": "Don't try to cheat",
|
||||||
"do-not-cheat-description": "These 12 words give access to all of your funds so it is important that you write them in the correct order, take it seriously.",
|
"do-not-cheat-description": "These 12 words give access to all of your funds so it is important that you write them in the correct order, take it seriously.",
|
||||||
"see-recovery-phrase-again": "See recovery phrase again"
|
"see-recovery-phrase-again": "See recovery phrase again",
|
||||||
|
"fees": "Fees"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue