eip1559 changes

This commit is contained in:
Roman Volosovskyi 2021-06-14 14:34:12 +03:00 committed by Andrea Maria Piana
parent fe0a67dc65
commit 1e4c1a5598
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
15 changed files with 681 additions and 53 deletions

1
.env
View File

@ -29,3 +29,4 @@ APN_TOPIC=im.status.ethereum.pr
COMMUNITIES_ENABLED=1
DATABASE_MANAGEMENT_ENABLED=1
METRICS_ENABLED=0
EIP1559_ENABLED=1

View File

@ -23,6 +23,7 @@
"eth_getTransactionByHash" {}
"eth_getTransactionReceipt" {}
"eth_getBlockByNumber" {}
"eth_maxPriorityFeePerGas" {}
"eth_newBlockFilter" {:subscription? true}
"eth_newFilter" {:subscription? true}
"eth_getCode" {}

View File

@ -36,7 +36,8 @@
[status-im.utils.mobile-sync :as utils.mobile-sync]
[status-im.async-storage.core :as async-storage]
[status-im.notifications-center.core :as notifications-center]
[status-im.navigation :as navigation]))
[status-im.navigation :as navigation]
[status-im.signing.eip1559 :as eip1559]))
(re-frame/reg-fx
::initialize-communities-enabled
@ -277,6 +278,10 @@
(assoc :networks/current-network current-network
:networks/networks networks
:multiaccount multiaccount))
::eip1559/check-eip1559-activation
{:network-id network-id
:on-enabled #(log/info "eip1550 is activated")
:on-disabled #(log/info "eip1559 is not activated")}
::initialize-wallet
(fn [accounts custom-tokens favourites]
(re-frame/dispatch [::initialize-wallet

View File

@ -21,7 +21,8 @@
[status-im.wallet.prices :as prices]
[status-im.wallet.core :as wallet]
[taoensso.timbre :as log]
[clojure.set :as clojure.set]))
[clojure.set :as clojure.set]
[status-im.signing.eip1559 :as eip1559]))
(re-frame/reg-fx
:signing/send-transaction-fx
@ -92,7 +93,7 @@
{:events [:signing.ui/sign-is-pressed]}
[{{:signing/keys [sign tx] :as db} :db :as cofx}]
(let [{:keys [in-progress? password]} sign
{:keys [tx-obj gas gasPrice message]} tx
{:keys [tx-obj gas gasPrice maxPriorityFeePerGas maxFeePerGas message]} tx
hashed-password (ethereum/sha3 (security/safe-unmask-data password))]
(if message
(sign-message cofx)
@ -100,7 +101,11 @@
(when gas
{:gas (str "0x" (abi-spec/number-to-hex gas))})
(when gasPrice
{:gasPrice (str "0x" (abi-spec/number-to-hex gasPrice))}))]
{:gasPrice (str "0x" (abi-spec/number-to-hex gasPrice))})
(when maxPriorityFeePerGas
{:maxPriorityFeePerGas (str "0x" (abi-spec/number-to-hex maxPriorityFeePerGas))})
(when maxFeePerGas
{:maxFeePerGas (str "0x" (abi-spec/number-to-hex maxFeePerGas))}))]
(when-not in-progress?
{:db (update db :signing/sign assoc :error nil :in-progress? true)
:signing/send-transaction-fx {:tx-obj tx-obj-to-send
@ -192,17 +197,21 @@
{:to to
:contact {:address (ethereum/normalized-hex to)}})))))
(defn prepare-tx [db {{:keys [data gas gasPrice] :as tx-obj} :tx-obj :as tx}]
(defn prepare-tx [db {{:keys [data gas gasPrice maxFeePerGas maxPriorityFeePerGas] :as tx-obj} :tx-obj :as tx}]
(merge
tx
(parse-tx-obj db tx-obj)
{:data data
:gas (when gas (money/bignumber gas))
:gasPrice (when gasPrice (money/bignumber gasPrice))}))
{:data data
:gas (when gas (money/bignumber gas))
:gasPrice (when gasPrice (money/bignumber gasPrice))
:maxFeePerGas (when maxFeePerGas
(money/bignumber maxFeePerGas))
:maxPriorityFeePerGas (when maxPriorityFeePerGas
(money/bignumber maxPriorityFeePerGas))}))
(fx/defn show-sign [{:keys [db] :as cofx}]
(let [{:signing/keys [queue]} db
{{:keys [gas gasPrice] :as tx-obj} :tx-obj {:keys [data typed? pinless?] :as message} :message :as tx} (last queue)
{{:keys [gas gasPrice maxFeePerGas] :as tx-obj} :tx-obj {:keys [data typed? pinless?] :as message} :message :as tx} (last queue)
keycard-multiaccount? (boolean (get-in db [:multiaccount :keycard-pairing]))
wallet-set-up-passed? (get-in db [:multiaccount :wallet-set-up-passed?])]
(if message
@ -240,10 +249,12 @@
:signing/update-estimated-gas {:obj (dissoc tx-obj :gasPrice)
:success-event :signing/update-estimated-gas-success
:error-event :signing/update-estimated-gas-error}})
#(when-not gasPrice
#(when-not (or maxFeePerGas gasPrice)
{:db (assoc-in (:db %) [:signing/edit-fee :gas-price-loading?] true)
:signing/update-gas-price {:success-event :signing/update-gas-price-success
:error-event :signing/update-gas-price-error}})))))
:error-event :signing/update-gas-price-error
:network-id (get-in (ethereum/current-network db)
[:config :NetworkId])}})))))
(fx/defn check-queue [{:keys [db] :as cofx}]
(let [{:signing/keys [tx queue]} db]
@ -485,7 +496,7 @@
(fx/defn sign-transaction-button-clicked
{:events [:wallet.ui/sign-transaction-button-clicked]}
[{:keys [db] :as cofx} {:keys [to amount from token gas gasPrice]}]
[{:keys [db] :as cofx} {:keys [to amount from token gas gasPrice maxFeePerGas maxPriorityFeePerGas]}]
(let [{:keys [symbol address]} token
amount-hex (str "0x" (abi-spec/number-to-hex amount))
to-norm (ethereum/normalized-hex (if (string? to) to (:address to)))
@ -493,10 +504,16 @@
(fx/merge cofx
{:db (dissoc db :wallet/prepare-transaction)}
(sign
{:tx-obj (merge {:from from-address
;;gas and gasPrice from qr (eip681)
:gas gas
:gasPrice gasPrice}
{:tx-obj (merge (if (eip1559/sync-enabled?)
{:from from-address
:gas gas
;; per eip1559
:maxFeePerGas maxFeePerGas
:maxPriorityFeePerGas maxPriorityFeePerGas}
{:from from-address
;;gas and gasPrice from qr (eip681)
:gas gas
:gasPrice gasPrice})
(if (= symbol :ETH)
{:to to-norm
:value amount-hex}

View File

@ -29,6 +29,8 @@
{:from {:address nil}
:gas nil
:gasPrice nil
:maxFeePerGas nil
:maxPriorityFeePerGas nil
:data nil
:to to
:contact {:address to}
@ -54,6 +56,8 @@
{:from {:address nil}
:gas nil
:gasPrice nil
:maxFeePerGas nil
:maxPriorityFeePerGas nil
:data data
:to contract
:contact {:address contract}}))))))))))

View File

@ -0,0 +1,64 @@
(ns status-im.signing.eip1559
(:require [re-frame.core :as re-frame]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.utils.config :as config]
[status-im.utils.money :as money]))
(def activation-blocks
{"123" (money/bignumber 0)})
(defonce activated? (atom {}))
(defonce activated-on-current-network? (atom nil))
(defn get-activation-block [network-id]
(get activation-blocks (str network-id)))
(defn on-block [network-id callback header]
(let [london-activated?
(boolean
(and
(get-activation-block network-id)
(money/greater-than-or-equals
(money/bignumber (:number header))
(get-activation-block network-id))))]
(swap! activated? assoc network-id london-activated?)
(reset! activated-on-current-network? london-activated?)
(callback london-activated?)))
(defn check-activation [network-id callback]
(json-rpc/call
{:method "eth_getBlockByNumber"
:params ["latest" false]
:on-success (partial on-block network-id callback)
:on-error #(callback nil)}))
(defn sync-enabled? []
(and config/eip1559-enabled?
@activated-on-current-network?))
(defn enabled? [network-id enabled-callback disabled-callback]
(let [london-activated? (get @activated? network-id)]
(cond
(not config/eip1559-enabled?)
(disabled-callback)
(nil? london-activated?)
(check-activation
network-id
(fn [activated?]
(if activated?
(enabled-callback)
(disabled-callback))))
london-activated?
(enabled-callback)
:else
(disabled-callback))))
(re-frame/reg-fx
::check-eip1559-activation
(fn [{:keys [network-id on-enabled on-disabled]}]
(enabled? network-id on-enabled on-disabled)))

View File

@ -4,7 +4,10 @@
[status-im.i18n.i18n :as i18n]
[status-im.bottom-sheet.core :as bottom-sheet]
[status-im.utils.fx :as fx]
[status-im.utils.money :as money]))
[status-im.utils.money :as money]
[status-im.signing.eip1559 :as eip1559]
[taoensso.timbre :as log]
[status-im.popover.core :as popover]))
(def min-gas-price-wei ^js (money/bignumber 1))
@ -59,10 +62,92 @@
(assoc key data)
edit-max-fee)))
(def minimum-priority-fee
(money/wei-> :gwei (money/->wei :gwei 1)))
(def average-priority-fee
(money/wei-> :gwei (money/->wei :gwei 1.5)))
(defn validate-max-fee [db]
(let [{:keys [maxFeePerGas maxPriorityFeePerGas]} (get db :signing/edit-fee)
latest-base-fee (money/wei-> :gwei
(money/bignumber
(get db :wallet/latest-base-fee)))
fee-error (cond
(or (:error maxFeePerGas)
(:error maxPriorityFeePerGas))
nil
(money/greater-than latest-base-fee
(:value-number maxFeePerGas))
{:label (i18n/label :t/below-base-fee)
:severity :error}
(money/greater-than (:value-number maxPriorityFeePerGas)
(money/sub (:value-number maxFeePerGas)
latest-base-fee))
{:label (i18n/label :t/reduced-tip)
:severity :error})]
(if fee-error
(assoc-in db [:signing/edit-fee :maxFeePerGas :fee-error] fee-error)
(update-in db [:signing/edit-fee :maxFeePerGas] dissoc :fee-error))))
(defn validate-max-priority-fee [db]
(let [{:keys [maxPriorityFeePerGas]} (get db :signing/edit-fee)
fee-error (cond
(:error maxPriorityFeePerGas)
nil
(money/greater-than minimum-priority-fee
(:value-number maxPriorityFeePerGas))
{:label (i18n/label :t/low-tip)
:severity :error}
(money/greater-than average-priority-fee
(:value-number maxPriorityFeePerGas))
{:label (i18n/label :t/lower-than-average-tip)
:severity :error})]
(if fee-error
(assoc-in db [:signing/edit-fee :maxPriorityFeePerGas :fee-error] fee-error)
(update-in db [:signing/edit-fee :maxPriorityFeePerGas] dissoc :fee-error))))
(defn validate-eip1559-fees [db]
(if (eip1559/sync-enabled?)
(reduce
(fn [acc f]
(f acc))
db
[validate-max-fee
validate-max-priority-fee])
db))
(fx/defn edit-value
{:events [:signing.edit-fee.ui/edit-value]}
[{:keys [db]} key value]
{:db (update db :signing/edit-fee build-edit key value)})
{:db (-> db
(update :signing/edit-fee build-edit key value)
validate-eip1559-fees)})
(fx/defn set-priority-fee
{:events [:signing.edit-fee.ui/set-priority-fee]}
[{:keys [db]} value]
(let [{:keys [maxFeePerGas maxPriorityFeePerGas]}
(get db :signing/edit-fee)
latest-base-fee (get db :wallet/latest-base-fee)
max-fee-value (:value-number maxFeePerGas)
max-priority-fee-value (:value-number maxPriorityFeePerGas)
new-value (money/bignumber value)
fee-without-tip (money/sub max-fee-value max-priority-fee-value)
base-fee (money/wei-> :gwei (money/bignumber latest-base-fee))
new-max-fee-value
(money/to-fixed
(if (money/greater-than base-fee fee-without-tip)
(money/add new-value base-fee)
(money/add new-value fee-without-tip)))]
{:db (-> db
(update :signing/edit-fee build-edit :maxPriorityFeePerGas value)
(update :signing/edit-fee build-edit :maxFeePerGas new-max-fee-value)
validate-eip1559-fees)}))
(fx/defn update-estimated-gas-success
{:events [:signing/update-estimated-gas-success]}
@ -93,29 +178,87 @@
(fx/defn open-fee-sheet
{:events [:signing.ui/open-fee-sheet]}
[{{:signing/keys [tx] :as db} :db :as cofx} sheet-opts]
(let [{:keys [gas gasPrice]} tx
edit-fee (-> {}
(build-edit :gas (money/to-fixed gas))
(build-edit :gasPrice (money/to-fixed (money/wei-> :gwei gasPrice))))]
(let [{:keys [gas gasPrice maxFeePerGas maxPriorityFeePerGas]} tx
max-fee (money/to-fixed (money/wei-> :gwei maxFeePerGas))
max-priority-fee (money/to-fixed (money/wei-> :gwei maxPriorityFeePerGas))
edit-fee (reduce (partial apply build-edit)
{}
{:gas (money/to-fixed gas)
:gasPrice (money/to-fixed (money/wei-> :gwei gasPrice))
:maxFeePerGas max-fee
:maxPriorityFeePerGas max-priority-fee})]
(fx/merge cofx
{:db (assoc db :signing/edit-fee edit-fee)}
(bottom-sheet/show-bottom-sheet {:view sheet-opts}))))
(fx/defn submit-fee
{:events [:signing.edit-fee.ui/submit]}
[{{:signing/keys [edit-fee] :as db} :db :as cofx}]
(let [{:keys [gas gasPrice]} edit-fee]
(fx/merge cofx
{:db (update db :signing/tx assoc :gas (:value-number gas) :gasPrice (:value-number gasPrice))}
(bottom-sheet/hide-bottom-sheet))))
[{{:signing/keys [edit-fee] :as db} :db :as cofx} force?]
(let [{:keys [gas gasPrice maxFeePerGas maxPriorityFeePerGas]} edit-fee
errors?
(keep
(fn [[k {:keys [fee-error]}]]
(when (= :error (:severity fee-error))
[k fee-error]))
edit-fee)]
(if (and (seq errors?)
(not force?))
(popover/show-popover cofx {:view :fees-warning})
(fx/merge cofx
{:db (update db :signing/tx assoc
:gas (:value-number gas)
:gasPrice (:value-number gasPrice)
:maxFeePerGas (money/->wei :gwei (:value-number maxFeePerGas))
:maxPriorityFeePerGas (money/->wei :gwei (:value-number maxPriorityFeePerGas)))}
(bottom-sheet/hide-bottom-sheet)))))
(re-frame/reg-fx
:signing/update-gas-price
(fn [{:keys [success-event error-event]}]
(json-rpc/call
{:method "eth_gasPrice"
:on-success #(re-frame/dispatch [success-event %])
:on-error #(re-frame/dispatch [error-event %])})))
(fn [{:keys [success-event error-event network-id] :as params}]
(eip1559/enabled?
network-id
(fn []
(json-rpc/call
{:method "eth_getBlockByNumber"
:params ["latest" false]
:on-success #(re-frame/dispatch [::header-fetched
(assoc params :header %)])
:on-error #(re-frame/dispatch [error-event %])}))
(fn []
(json-rpc/call
{:method "eth_gasPrice"
:on-success #(re-frame/dispatch [success-event %])
:on-error #(re-frame/dispatch [error-event %])})))))
(fx/defn header-fetched
{:events [::header-fetched]}
[_ {:keys [error-event] :as params}]
{::json-rpc/call
[{:method "eth_maxPriorityFeePerGas"
:on-success #(re-frame/dispatch [::max-priority-fee-per-gas-fetched
(assoc params :max-priority-fee %)])
:on-error (if error-event
#(re-frame/dispatch [error-event %])
#(log/error "Can't fetch header" %))}]})
(def london-block-gas-limit (money/bignumber 30000000))
(defn check-base-fee [{:keys [gasUsed baseFeePerGas]}]
{:base-fee baseFeePerGas
:spike? (or (money/greater-than-or-equals
(money/bignumber 0)
(money/bignumber gasUsed))
(money/greater-than-or-equals
(money/bignumber gasUsed)
(money/bignumber london-block-gas-limit)))})
(fx/defn max-priority-fee-per-gas-fetched
{:events [::max-priority-fee-per-gas-fetched]}
[_ {:keys [success-event header max-priority-fee]}]
(let [{:keys [base-fee spike?]} (check-base-fee header)]
{:dispatch [success-event {:base-fee base-fee
:max-priority-fee max-priority-fee
:spike? spike?}]}))
(re-frame/reg-fx
:signing/update-estimated-gas

View File

@ -39,6 +39,7 @@
[status-im.chat.models.mentions :as mentions]
[status-im.notifications.core :as notifications]
[status-im.utils.currency :as currency]
[status-im.signing.eip1559 :as eip1559]
[clojure.set :as clojure.set]))
;; TOP LEVEL ===========================================================================================================
@ -163,7 +164,8 @@
(reg-root-key-sub :wallet/refreshing-history? :wallet/refreshing-history?)
(reg-root-key-sub :wallet/fetching-error :wallet/fetching-error)
(reg-root-key-sub :wallet/non-archival-node :wallet/non-archival-node)
(reg-root-key-sub :wallet/latest-base-fee :wallet/latest-base-fee)
(reg-root-key-sub :wallet/latest-priority-fee :wallet/latest-priority-fee)
;;commands
(reg-root-key-sub :commands/select-account :commands/select-account)
@ -2494,8 +2496,29 @@
(re-frame/reg-sub
:signing/fee
:<- [:signing/tx]
(fn [{:keys [gas gasPrice]}]
(signing.gas/calculate-max-fee gas gasPrice)))
(fn [{:keys [gas gasPrice maxFeePerGas]}]
(signing.gas/calculate-max-fee gas (or maxFeePerGas gasPrice))))
(re-frame/reg-sub
:signing/currencies
:<- [:prices]
:<- [:wallet/currency]
:<- [:ethereum/native-currency]
(fn [[prices {:keys [code]} {:keys [symbol]}]]
[(name symbol)
code
(get-in prices [symbol (keyword code) :price])]))
(re-frame/reg-sub
:signing/priority-fee-suggestions-range
:<- [:wallet/latest-priority-fee]
(fn [latest-fee]
[0 (->> latest-fee
money/bignumber
(money/wei-> :gwei)
(money/mul (money/bignumber 2))
money/to-fixed
js/parseFloat)]))
(re-frame/reg-sub
:signing/phrase
@ -2568,12 +2591,13 @@
[(re-frame/subscribe [:signing/tx])
(re-frame/subscribe [:balance address])])
(fn [[{:keys [amount token gas gasPrice approve? gas-error-message]} balance]]
(if (and amount token (not approve?))
(let [amount-bn (money/formatted->internal (money/bignumber amount) (:symbol token) (:decimals token))
amount-error (or (get-amount-error amount (:decimals token))
(get-sufficient-funds-error balance (:symbol token) amount-bn))]
(merge amount-error (get-sufficient-gas-error gas-error-message balance (:symbol token) amount-bn gas gasPrice)))
(get-sufficient-gas-error gas-error-message balance nil nil gas gasPrice))))
(when-not (eip1559/sync-enabled?)
(if (and amount token (not approve?))
(let [amount-bn (money/formatted->internal (money/bignumber amount) (:symbol token) (:decimals token))
amount-error (or (get-amount-error amount (:decimals token))
(get-sufficient-funds-error balance (:symbol token) amount-bn))]
(merge amount-error (get-sufficient-gas-error gas-error-message balance (:symbol token) amount-bn gas gasPrice)))
(get-sufficient-gas-error gas-error-message balance nil nil gas gasPrice)))))
(re-frame/reg-sub
:wallet.send/prepare-transaction-with-balance

View File

@ -20,7 +20,8 @@
[status-im.ui.components.colors :as colors]
[status-im.ui.screens.keycard.views :as keycard.views]
[status-im.ui.screens.keycard.frozen-card.view :as frozen-card]
[status-im.ui.screens.chat.message.pinned-message :as pinned-message]))
[status-im.ui.screens.chat.message.pinned-message :as pinned-message]
[status-im.ui.screens.signing.sheets :as signing-sheets]))
(defn hide-panel-anim
[bottom-anim-value alpha-value window-height]
@ -177,6 +178,9 @@
(= :pin-limit view)
[pinned-message/pin-limit-popover]
(= :fees-warning view)
[signing-sheets/fees-warning]
:else
[view])]]]]])))})))

View File

@ -4,7 +4,13 @@
[re-frame.core :as re-frame]
[status-im.i18n.i18n :as i18n]
[quo.core :as quo]
[status-im.ui.components.colors :as colors]))
[quo.design-system.colors :as quo-colors]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.slider :as slider]
[status-im.utils.money :as money]
[status-im.ui.components.icons.icons :as icons]
[clojure.string :as clojure.string]
[status-im.signing.gas :as gas]))
(views/defview fee-bottom-sheet [fee-display-symbol]
(views/letsubs [{gas-edit :gas gas-price-edit :gasPrice max-fee :max-fee} [:signing/edit-fee]]
@ -60,3 +66,296 @@
:on-press #(re-frame/dispatch [:signing.edit-fee.ui/submit])
:disabled (or (:error gas-edit) (:error gas-price-edit))}
(i18n/label :t/update)]]]))
(declare fee-bottom-sheet-eip1559)
(defn fee-bottom-sheet-eip1559-custom [fee-display-symbol]
(let [{gas-edit :gas
max-fee-per-gas-edit :maxFeePerGas
max-priority-fee-per-gas-edit :maxPriorityFeePerGas}
@(re-frame/subscribe [:signing/edit-fee])
base-fee @(re-frame/subscribe [:wallet/latest-base-fee])
[fee-currency fiat-currency price]
@(re-frame/subscribe [:signing/currencies])
fee-eth
(if (and (:value-number gas-edit)
(:value-number max-fee-per-gas-edit))
(money/mul
(money/wei->ether
(money/->wei :gwei (:value-number max-fee-per-gas-edit)))
(:value-number gas-edit))
(money/bignumber 0))]
[react/view
[react/view {:style {:margin-horizontal 16 :margin-top 8}}
[react/text {:style {:typography :title-bold}} (i18n/label :t/max-priority-fee)]
[react/text {:style {:color (quo-colors/get-color :text-02)
:margin-top 12}}
(i18n/label :t/miners-higher-fee)]
[react/view
{:style {:margin-top 12
:flex-direction :row
:align-items :center
:justify-content :space-between}}
[quo/text (i18n/label :t/current-base-fee)]
[quo/text
(money/to-fixed (money/wei-> :gwei base-fee))
" "
(i18n/label :t/gwei)]]]
[react/view {:margin-vertical 12
:margin-horizontal 16
:height 1
:background-color colors/gray-lighter}]
[react/view
{:margin-horizontal 16
:margin-top 4
:margin-bottom 26}
[quo/text-input
{:label (i18n/label :t/gas-amount-limit)
:error (:error gas-edit)
:default-value (:value gas-edit)
:on-change-text #(re-frame/dispatch [:signing.edit-fee.ui/edit-value :gas %])
:show-cancel false}]]
[react/view
{:margin-horizontal 16
:margin-top 4
:margin-bottom 26}
[quo/text-input
{:label (i18n/label :t/per-gas-tip-limit)
:error (or (:error max-priority-fee-per-gas-edit)
(get-in max-priority-fee-per-gas-edit [:fee-error :label]))
:default-value (:value max-priority-fee-per-gas-edit)
:on-change-text #(re-frame/dispatch [:signing.edit-fee.ui/edit-value :maxPriorityFeePerGas %])
:show-cancel false
:after {:component [quo/text
{:style {:color (quo-colors/get-color :text-02)}}
(i18n/label :t/gwei)]}}]]
[react/view
{:margin-horizontal 16
:margin-top 4
:margin-bottom 12}
[quo/text-input
{:label (i18n/label :t/per-gas-price-limit)
:error (or (:error max-fee-per-gas-edit)
(get-in max-fee-per-gas-edit [:fee-error :label]))
:default-value (:value max-fee-per-gas-edit)
:on-change-text #(re-frame/dispatch [:signing.edit-fee.ui/edit-value :maxFeePerGas %])
:show-cancel false
:after {:component [quo/text
{:style {:color (quo-colors/get-color :text-02)}}
(i18n/label :t/gwei)]}}]]
[react/view {:margin-vertical 12
:height 1
:background-color colors/gray-lighter}]
[react/view
{:style {:margin-top 4
:margin-horizontal 16
:flex-direction :row
:align-items :center
:justify-content :space-between}}
[quo/text (i18n/label :t/maximum-fee) ":"]
[react/view
{:style {:flex-direction :row
:align-items :center
:justify-content :flex-end}}
[quo/text
{:style {:margin-right 6
:color (quo-colors/get-color :text-02)}}
(str (money/to-fixed fee-eth 6) " " fee-currency)]
[quo/text
(money/to-fixed (money/mul fee-eth (money/bignumber price)) 2)
" "
fiat-currency]]]
[react/text {:style {:color (quo-colors/get-color :text-02)
:margin 16}}
(i18n/label :t/fee-explanation)]
[react/view
{:style {:margin-left 12
:margin-right 16
:flex-direction :row
:align-items :center
:justify-content :space-between}}
[quo/button
{:type :secondary
:on-press #(re-frame/dispatch
[:bottom-sheet/show-sheet
{:content (fn []
[fee-bottom-sheet-eip1559 fee-display-symbol])
:content-height 270}])}
(i18n/label :t/see-suggestions)]
[quo/button
{:type :primary
:on-press #(re-frame/dispatch [:signing.edit-fee.ui/submit])
:theme :accent}
(i18n/label :t/save)]]]))
(defn fee-bottom-sheet-eip1559 [fee-display-symbol]
(let [{priority-fee-edit :maxPriorityFeePerGas
fee-edit :maxFeePerGas
gas :gas}
@(re-frame/subscribe [:signing/edit-fee])
[min-value max-value]
@(re-frame/subscribe [:signing/priority-fee-suggestions-range])
[fee-currency fiat-currency price] @(re-frame/subscribe [:signing/currencies])
fee-eth
(if (and (:value-number gas)
(:value-number fee-edit))
(money/mul
(money/wei->ether
(money/->wei :gwei (:value-number fee-edit)))
(:value-number gas))
(money/bignumber 0))]
[react/view
[react/view {:style {:margin-horizontal 16 :margin-top 8}}
[react/text {:style {:typography :title-bold}} (i18n/label :t/max-priority-fee)]
[react/text {:style {:color (quo-colors/get-color :text-02)
:margin-top 12}}
(i18n/label :t/miners-higher-fee)]
[quo/text {:style {:margin-horizontal 8
:margin-top 24}
:size :large}
(clojure.string/join
" "
[(money/to-fixed fee-eth 6)
fee-currency
"•"
(money/to-fixed (money/mul fee-eth (money/bignumber price)) 2)
fiat-currency])]
[slider/animated-slider
{:style {:margin-horizontal 5
:margin-vertical 4}
:minimumValue min-value
:value (js/parseFloat (:value priority-fee-edit))
:onValueChange #(re-frame/dispatch [:signing.edit-fee.ui/set-priority-fee (str %)])
:maximumValue max-value
:minimumTrackTintColor (quo-colors/get-color :icon-04)}]
[react/view
{:style {:margin-horizontal 8
:flex-direction :row
:align-items :center
:justify-content :space-between}}
[react/text {:style {:color (quo-colors/get-color :text-02)}} (i18n/label :t/slow)]
[react/text {:style {:color (quo-colors/get-color :text-02)}} (i18n/label :t/optimal)]
[react/text {:style {:color (quo-colors/get-color :text-02)}} (i18n/label :t/fast)]]]
[react/view
{:style {:margin-left 12
:margin-right 16
:margin-top 38}
:flex-direction :row
:align-items :center
:justify-content :space-between}
[quo/button
{:type :secondary
:on-press #(re-frame/dispatch
[:bottom-sheet/show-sheet
{:content (fn []
[fee-bottom-sheet-eip1559-custom fee-display-symbol])
:content-height 270}])}
(i18n/label :t/set-custom-fee)]
[quo/button
{:type :primary
:theme :accent
:on-press #(re-frame/dispatch [:signing.edit-fee.ui/submit])}
(i18n/label :t/save)]]]))
(defn gwei [val]
(str val " " (i18n/label :t/gwei)))
(defn fees-warning []
(let [base-fee @(re-frame/subscribe [:wallet/latest-base-fee])
base-fee-gwei (money/wei-> :gwei (money/bignumber base-fee))
priority-fee @(re-frame/subscribe [:wallet/latest-priority-fee])
priority-fee-gwei (money/wei-> :gwei (money/bignumber priority-fee))
{priority-fee-edit :maxPriorityFeePerGas
fee-edit :maxFeePerGas}
@(re-frame/subscribe [:signing/edit-fee])]
[react/view
[react/view {:margin-top 24
:margin-horizontal 24
:margin-bottom 32
:align-items :center}
[react/view {:background-color colors/blue-light
:width 32
:height 32
:border-radius 16
:align-items :center
:justify-content :center}
[icons/icon :main-icons/warning {:color colors/black}]]
[react/text {:style {:typography :title-bold
:margin-top 16
:margin-bottom 8}}
(i18n/label :t/are-you-sure)]
[react/text {:style {:color colors/gray
:text-align :center
:margin-horizontal 24}}
(i18n/label :t/bad-fees-description)]]
[react/view
{:style {:flex-direction :row
:justify-content :space-between
:margin-horizontal 32}}
[react/text (i18n/label :t/current-base-fee)]
[react/text (gwei (money/to-fixed base-fee-gwei 2))]]
[react/view
{:style {:flex-direction :row
:justify-content :space-between
:margin-horizontal 32}}
[react/text (i18n/label :t/current-minimum-tip)]
[react/text (gwei gas/minimum-priority-fee)]]
[react/view
{:style {:flex-direction :row
:justify-content :space-between
:margin-horizontal 32}}
[react/text (i18n/label :t/current-average-tip)]
[react/text (gwei (money/to-fixed priority-fee-gwei 2))]]
[react/view {:margin-vertical 16
:height 1
:background-color colors/gray-lighter}]
[react/view
{:style {:flex-direction :row
:justify-content :space-between
:margin-horizontal 32
:color :red}}
[react/text {:style {:color (quo-colors/get-color :negative-01)}}
(i18n/label :t/your-tip-limit)]
[react/text {:style {:color (quo-colors/get-color :negative-01)}}
(gwei (money/to-fixed (:value-number priority-fee-edit) 2))]]
[react/view
{:style {:flex-direction :row
:justify-content :space-between
:margin-horizontal 32}}
[react/text {:style {:color (quo-colors/get-color :negative-01)}}
(i18n/label :t/your-price-limit)]
[react/text {:style {:color (quo-colors/get-color :negative-01)}}
(gwei (money/to-fixed (:value-number fee-edit) 2))]]
[react/view {:style
{:background-color colors/gray-lighter
:padding-horizontal 32
:padding-vertical 16
:margin-vertical 16}}
[react/view
{:style {:flex-direction :row
:justify-content :space-between}}
[react/text (i18n/label :t/suggested-min-tip)]
[react/text (gwei gas/minimum-priority-fee)]]
[react/view
{:style {:flex-direction :row
:justify-content :space-between}}
[react/text (i18n/label :t/suggested-price-limit)]
[react/text (gwei (money/to-fixed (money/add base-fee-gwei priority-fee-gwei) 2))]]]
[react/view
{:style {:align-items :center
:justify-content :center
:margin-top 8}}
[quo/button
{:type :primary
:on-press #(re-frame/dispatch [:hide-popover])}
(i18n/label :t/change-tip)]]
[react/view
{:style {:align-items :center
:justify-content :center
:margin-top 8
:margin-bottom 16}}
[quo/button
{:type :secondary
:on-press #(do (re-frame/dispatch [:hide-popover])
(re-frame/dispatch [:signing.edit-fee.ui/submit true]))}
(i18n/label :t/continue-anyway)]]]))

View File

@ -25,7 +25,8 @@
[status-im.ui.screens.keycard.pin.views :as pin.views]
[status-im.ui.components.bottom-panel.views :as bottom-panel]
[status-im.utils.utils :as utils]
[reagent.core :as reagent]))
[reagent.core :as reagent]
[status-im.signing.eip1559 :as eip1559]))
(defn separator []
[react/view {:height 1 :background-color colors/gray-lighter}])
@ -383,7 +384,10 @@
[react/text {:style {:color colors/gray}} (str " " (:code wallet-currency))]]))
:on-press #(re-frame/dispatch
[:signing.ui/open-fee-sheet
{:content (fn [] [sheets/fee-bottom-sheet fee-display-symbol])
{:content (fn []
(if (eip1559/sync-enabled?)
[sheets/fee-bottom-sheet-eip1559 fee-display-symbol]
[sheets/fee-bottom-sheet fee-display-symbol]))
:content-height 270}])}])))
(views/defview network-item []

View File

@ -49,6 +49,7 @@
(def database-management-enabled? (enabled? (get-config :DATABASE_MANAGEMENT_ENABLED "0")))
(def debug-webview? (enabled? (get-config :DEBUG_WEBVIEW "0")))
(def metrics-enabled? (enabled? (get-config :METRICS_ENABLED "0")))
(def eip1559-enabled? (enabled? (get-config :EIP1559_ENABLED "0")))
;; CONFIG VALUES
(def log-level

View File

@ -33,9 +33,20 @@
(new BigNumber (normalize (str n)))
(catch :default _ nil))))
(defn greater-than-or-equals
[bn1 bn2]
(.greaterThanOrEqualTo bn1 bn2))
(defn greater-than
[bn1 bn2]
(.greaterThan bn1 bn2))
(defn sub [bn1 bn2]
(.sub bn1 bn2))
(defn valid? [^js bn]
(when bn
(.greaterThanOrEqualTo bn 0)))
(greater-than-or-equals bn 0)))
(defn from-decimal [n]
(when n
@ -62,9 +73,13 @@
(when-let [^js bn (bignumber n)]
(.times bn (eth-units unit))))
(defn to-fixed [^js bn]
(when bn
(.toFixed bn)))
(defn to-fixed
([^js bn]
(when bn
(.toFixed bn)))
([^js bn b]
(when bn
(.toFixed bn b))))
(defn to-number [^js bn]
(when bn
@ -154,3 +169,9 @@
(crypto->fiat (get-in prices [from to :price] ^js (bignumber 0)))
(with-precision 2)
str))
(defn add [bn1 n2]
(.add bn1 n2))
(defn mul [bn1 bn2]
(.mul bn1 bn2))

View File

@ -27,6 +27,7 @@
status-im.wallet.recipient.core
[status-im.async-storage.core :as async-storage]
[status-im.popover.core :as popover.core]
[status-im.signing.eip1559 :as eip1559]
[clojure.set :as clojure.set]))
(defn get-balance
@ -380,7 +381,16 @@
(fx/defn wallet-send-gas-price-success
{:events [:wallet.send/update-gas-price-success]}
[{db :db} price]
{:db (assoc-in db [:wallet/prepare-transaction :gasPrice] price)})
(if (eip1559/sync-enabled?)
(let [{:keys [base-fee max-priority-fee]} price
max-priority-fee-bn (money/bignumber max-priority-fee)]
{:db (-> db
(update :wallet/prepare-transaction assoc
:maxFeePerGas (money/to-hex (money/add max-priority-fee-bn base-fee))
:maxPriorityFeePerGas max-priority-fee)
(assoc :wallet/latest-base-fee base-fee
:wallet/latest-priority-fee max-priority-fee))})
{:db (assoc-in db [:wallet/prepare-transaction :gasPrice] price)}))
(fx/defn set-max-amount
{:events [:wallet.send/set-max-amount]}
@ -468,7 +478,9 @@
{:events [::recipient-address-resolved]}
[{:keys [db]} address]
{:db (assoc-in db [:wallet/prepare-transaction :to :address] address)
:signing/update-gas-price {:success-event :wallet.send/update-gas-price-success}})
:signing/update-gas-price {:success-event :wallet.send/update-gas-price-success
:network-id (get-in (ethereum/current-network db)
[:config :NetworkId])}})
(fx/defn prepare-transaction-from-chat
{:events [:wallet/prepare-transaction-from-chat]}
@ -521,7 +533,9 @@
:symbol :ETH
:from-chat? false})
:dispatch [:open-modal :prepare-send-transaction]
:signing/update-gas-price {:success-event :wallet.send/update-gas-price-success}})
:signing/update-gas-price {:success-event :wallet.send/update-gas-price-success
:network-id (get-in (ethereum/current-network db)
[:config :NetworkId])}})
(fx/defn cancel-transaction-command
{:events [:wallet/cancel-transaction-command]}

View File

@ -1608,5 +1608,31 @@
},
"pinned-messages-empty": "Pinned messages will appear here. To pin a message, press and hold it and tap `Pin`",
"pinned-by": "Pinned by",
"pin-limit-reached": "Pin limit reached. Unpin a previous message first."
"pin-limit-reached": "Pin limit reached. Unpin a previous message first.",
"max-fee": "Max fee",
"max-priority-fee": "Max priority fee",
"miners-higher-fee": "Miners will likely inlcude your transaction earlier if you pay a higher fee.",
"gas-amount-limit": "Gas amount limit",
"per-gas-tip-limit": "Per-gas tip limit",
"per-gas-price-limit": "Per-gas price limit",
"current-base-fee": "Current base fee",
"fee-explanation": "Maximum overall price for the transaction. If the block base fee exceeds this, it will be included in a following block with a lower base fee.",
"slow": "Slow",
"optimal": "Optimal",
"fast": "Fast",
"see-suggestions": "See suggestions",
"maximum-fee": "Maximum fee",
"low-tip": "tip is too low",
"lower-than-average-tip": "lower than average tip",
"below-base-fee": "max fee below base fee",
"reduced-tip": "priority tip will be reduced",
"are-you-sure": "Are you sure?",
"bad-fees-description": "Your priority fee is below our suggested parameters.",
"change-tip": "Change tip",
"current-minimum-tip": "Current minimum tip",
"current-average-tip": "Current average tip",
"your-tip-limit": "Your tip limit",
"your-price-limit": "Your price limit",
"suggested-min-tip": "Suggested min. tip",
"suggested-price-limit": "Suggested price limit"
}