[#21132] refactor: improve send transaction content in wc flow (#21266)

This commit is contained in:
Mohsen 2024-09-30 15:11:56 +03:00 committed by GitHub
parent b97e2df2fb
commit 60fc4f1b9a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 182 additions and 51 deletions

View File

@ -619,3 +619,12 @@
(def router-error-code-not-enough-liquidity "WPP-038") (def router-error-code-not-enough-liquidity "WPP-038")
(def router-error-code-price-impact-too-high "WPP-039") (def router-error-code-price-impact-too-high "WPP-039")
(def router-error-code-not-enough-native-balance "WR-002") (def router-error-code-not-enough-native-balance "WR-002")
(def ^:const wallet-transaction-estimation
{:unknown 0
:less-than-one-minute 1
:less-than-three-minutes 2
:less-than-five-minutes 3
:more-than-five-minutes 4})
(def ^:const wallet-connect-transaction-refresh-interval-ms 10000)

View File

@ -493,3 +493,13 @@
:available-balance (calculate-total-token-balance token) :available-balance (calculate-total-token-balance token)
:total-balance (calculate-total-token-balance token chain-ids))) :total-balance (calculate-total-token-balance token chain-ids)))
tokens)) tokens))
(defn estimated-time-format
"Formats the estimated time for a transaction"
[estimated-time]
(condp = estimated-time
(:unknown constants/wallet-transaction-estimation) ">5"
(:less-than-one-minute constants/wallet-transaction-estimation) "<1"
(:less-than-three-minutes constants/wallet-transaction-estimation) "1-3"
(:less-than-five-minutes constants/wallet-transaction-estimation) "3-5"
">5"))

View File

@ -2,7 +2,6 @@
(:require [cljs-bean.core :as bean] (:require [cljs-bean.core :as bean]
[clojure.string :as string] [clojure.string :as string]
[native-module.core :as native-module] [native-module.core :as native-module]
[re-frame.core :as rf]
[status-im.constants :as constants] [status-im.constants :as constants]
[status-im.contexts.wallet.wallet-connect.utils.data-store :as [status-im.contexts.wallet.wallet-connect.utils.data-store :as
data-store] data-store]
@ -11,6 +10,7 @@
[status-im.contexts.wallet.wallet-connect.utils.transactions :as transactions] [status-im.contexts.wallet.wallet-connect.utils.transactions :as transactions]
[taoensso.timbre :as log] [taoensso.timbre :as log]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.transforms :as transforms])) [utils.transforms :as transforms]))
(rf/reg-event-fx (rf/reg-event-fx
@ -37,7 +37,9 @@
(assoc-in [:wallet-connect/current-request :response-sent?] false)) (assoc-in [:wallet-connect/current-request :response-sent?] false))
:fx [(condp = method :fx [(condp = method
constants/wallet-connect-eth-send-transaction-method constants/wallet-connect-eth-send-transaction-method
[:dispatch [:wallet-connect/process-eth-send-transaction]] [:dispatch
[:wallet-connect/process-eth-send-transaction
{:on-success (fn [] (rf/dispatch [:wallet-connect/show-request-modal]))}]]
constants/wallet-connect-eth-sign-method constants/wallet-connect-eth-sign-method
[:dispatch [:wallet-connect/process-eth-sign]] [:dispatch [:wallet-connect/process-eth-sign]]
@ -94,22 +96,25 @@
:raw-data prepared-tx :raw-data prepared-tx
:transaction tx :transaction tx
:chain-id chain-id :chain-id chain-id
:display-data display-data) :display-data display-data)})))
:fx [[:dispatch [:wallet-connect/show-request-modal]]]})))
(rf/reg-event-fx (rf/reg-event-fx
:wallet-connect/process-eth-send-transaction :wallet-connect/process-eth-send-transaction
(fn [{:keys [db]}] (fn [{:keys [db]} [{:keys [on-success]}]]
(let [event (data-store/get-db-current-request-event db) (let [event (data-store/get-db-current-request-event db)
tx (-> event data-store/get-request-params first) tx (-> event data-store/get-request-params first)
chain-id (-> event chain-id (-> event
(get-in [:params :chainId]) (get-in [:params :chainId])
networks/eip155->chain-id)] networks/eip155->chain-id)]
(when tx
{:fx [[:effects.wallet-connect/prepare-transaction {:fx [[:effects.wallet-connect/prepare-transaction
{:tx tx {:tx tx
:chain-id chain-id :chain-id chain-id
:on-success #(rf/dispatch [:wallet-connect/prepare-transaction-success % chain-id]) :on-success (fn [data]
:on-error #(rf/dispatch [:wallet-connect/on-processing-error %])}]]}))) (rf/dispatch [:wallet-connect/prepare-transaction-success data chain-id])
(when on-success
(rf/call-continuation on-success)))
:on-error #(rf/dispatch [:wallet-connect/on-processing-error %])}]]}))))
(rf/reg-event-fx (rf/reg-event-fx
:wallet-connect/process-eth-sign-transaction :wallet-connect/process-eth-sign-transaction

View File

@ -4,6 +4,7 @@
[quo.theme] [quo.theme]
[react-native.core :as rn] [react-native.core :as rn]
[status-im.common.standard-authentication.core :as standard-authentication] [status-im.common.standard-authentication.core :as standard-authentication]
[status-im.contexts.wallet.sheets.buy-token.view :as buy-token]
[status-im.contexts.wallet.wallet-connect.modals.common.footer.style :as style] [status-im.contexts.wallet.wallet-connect.modals.common.footer.style :as style]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.re-frame :as rf])) [utils.re-frame :as rf]))
@ -14,17 +15,25 @@
(rf/dispatch [:wallet-connect/respond-current-session password])) (rf/dispatch [:wallet-connect/respond-current-session password]))
(defn view (defn view
[{:keys [warning-label slide-button-text error-text]} & children] [{:keys [warning-label slide-button-text error-state]} & children]
(let [{:keys [customization-color]} (rf/sub [:wallet-connect/current-request-account-details]) (let [{:keys [customization-color]} (rf/sub [:wallet-connect/current-request-account-details])
offline? (rf/sub [:network/offline?]) offline? (rf/sub [:network/offline?])
theme (quo.theme/use-theme)] theme (quo.theme/use-theme)]
[:<> [:<>
(when (or offline? error-text) (when (or offline? error-state)
[quo/alert-banner [quo/alert-banner
{:action? false {:action? (when error-state true)
:text (if offline? :text (if offline?
(i18n/label :t/wallet-connect-no-internet-warning) (i18n/label :t/wallet-connect-no-internet-warning)
error-text)}]) (i18n/label (condp = error-state
:not-enough-assets-to-pay-gas-fees
:t/not-enough-assets-to-pay-gas-fees
:not-enough-assets
:t/not-enough-assets-for-transaction)))
:button-text (i18n/label :t/buy-eth)
:on-button-press #(rf/dispatch [:show-bottom-sheet
{:content buy-token/view}])}])
[rn/view {:style style/content-container} [rn/view {:style style/content-container}
(into [rn/view (into [rn/view
{:style style/data-items-container}] {:style style/data-items-container}]
@ -33,7 +42,7 @@
[standard-authentication/slide-button [standard-authentication/slide-button
{:size :size-48 {:size :size-48
:track-text slide-button-text :track-text slide-button-text
:disabled? (or offline? (seq error-text)) :disabled? (or offline? error-state)
:customization-color customization-color :customization-color customization-color
:on-auth-success on-auth-success :on-auth-success on-auth-success
:auth-button-label (i18n/label :t/confirm)}]] :auth-button-label (i18n/label :t/confirm)}]]

View File

@ -1,5 +1,6 @@
(ns status-im.contexts.wallet.wallet-connect.modals.common.style (ns status-im.contexts.wallet.wallet-connect.modals.common.style
(:require [status-im.constants :as constants])) (:require [quo.foundations.colors :as colors]
[status-im.constants :as constants]))
(defn container (defn container
[bottom] [bottom]
@ -20,4 +21,14 @@
(def data-item (def data-item
{:flex 1 {:flex 1
:background-color :transparent}) :background-color :transparent
:margin-bottom 8
:margin-top 2})
(def data-item-container
{:padding 10
:margin-top 10.5
:margin-bottom 0
:border-width 1
:border-color colors/neutral-10
:border-radius 16})

View File

@ -2,7 +2,9 @@
(:require [quo.core :as quo] (:require [quo.core :as quo]
[quo.theme] [quo.theme]
[react-native.core :as rn] [react-native.core :as rn]
[react-native.gesture :as gesture]
[react-native.safe-area :as safe-area] [react-native.safe-area :as safe-area]
[status-im.constants :as constants]
[status-im.contexts.wallet.wallet-connect.modals.common.data-block.view :as data-block] [status-im.contexts.wallet.wallet-connect.modals.common.data-block.view :as data-block]
[status-im.contexts.wallet.wallet-connect.modals.common.fees-data-item.view :as [status-im.contexts.wallet.wallet-connect.modals.common.fees-data-item.view :as
fees-data-item] fees-data-item]
@ -10,9 +12,43 @@
[status-im.contexts.wallet.wallet-connect.modals.common.header.view :as header] [status-im.contexts.wallet.wallet-connect.modals.common.header.view :as header]
[status-im.contexts.wallet.wallet-connect.modals.common.page-nav.view :as page-nav] [status-im.contexts.wallet.wallet-connect.modals.common.page-nav.view :as page-nav]
[status-im.contexts.wallet.wallet-connect.modals.common.style :as style] [status-im.contexts.wallet.wallet-connect.modals.common.style :as style]
[status-im.contexts.wallet.wallet-connect.utils.transactions :as transaction-utils]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.re-frame :as rf])) [utils.re-frame :as rf]))
(defn- refetch-transaction
[]
(rf/dispatch [:wallet-connect/process-eth-send-transaction]))
(def tabs-data
[{:id :tab/data :label (i18n/label :t/data)}
{:id :tab/hex :label (i18n/label :t/hex)}])
(defn- render-item
[props]
(let [[label value] props]
[quo/data-item
{:card? false
:container-style style/data-item
:title (str (name label) ":")
:subtitle value}]))
(defn- tab-view
[selected-tab]
(let [{:keys [transaction]} (rf/sub [:wallet-connect/current-request])
transaction-items (rn/use-memo #(-> transaction
(transaction-utils/transaction-hex-values->number)
(transaction-utils/transactions->display-array))
[transaction])]
[:<>
(case selected-tab
:tab/data [gesture/flat-list
{:data transaction-items
:content-container-style style/data-item-container
:render-fn render-item
:shows-vertical-scroll-indicator false}]
:tab/hex [data-block/view])]))
(defn view (defn view
[] []
(let [bottom (safe-area/get-bottom) (let [bottom (safe-area/get-bottom)
@ -21,8 +57,26 @@
dapp (rf/sub [:wallet-connect/current-request-dapp]) dapp (rf/sub [:wallet-connect/current-request-dapp])
network (rf/sub [:wallet-connect/current-request-network]) network (rf/sub [:wallet-connect/current-request-network])
{:keys [max-fees-fiat-formatted {:keys [max-fees-fiat-formatted
error-state]} (rf/sub [:wallet-connect/current-request-transaction-information])] error-state estimated-time]} (rf/sub
(rn/use-unmount #(rf/dispatch [:wallet-connect/on-request-modal-dismissed])) [:wallet-connect/current-request-transaction-information])
[selected-tab set-selected-tab] (rn/use-state (:id (first tabs-data)))
on-change-tab #(set-selected-tab %)
refetch-interval-ref (rn/use-ref nil)
clear-interval (rn/use-callback (fn []
(when (.-current refetch-interval-ref)
(js/clearInterval
(.-current refetch-interval-ref))))
[refetch-interval-ref])]
(rn/use-mount
(fn []
(clear-interval)
(set! (.-current refetch-interval-ref)
(js/setInterval refetch-transaction constants/wallet-connect-transaction-refresh-interval-ms))))
(rn/use-unmount (fn []
(clear-interval)
(rf/dispatch [:wallet-connect/on-request-modal-dismissed])))
[rn/view {:style (style/container bottom)} [rn/view {:style (style/container bottom)}
[quo/gradient-cover {:customization-color customization-color}] [quo/gradient-cover {:customization-color customization-color}]
[page-nav/view [page-nav/view
@ -33,17 +87,17 @@
{:label (i18n/label :t/wallet-connect-send-transaction-header) {:label (i18n/label :t/wallet-connect-send-transaction-header)
:dapp dapp :dapp dapp
:account account}] :account account}]
[data-block/view]] [quo/segmented-control
{:size 32
:blur? false
:default-active :tab/data
:data tabs-data
:on-change on-change-tab}]
[tab-view selected-tab]]
[footer/view [footer/view
{:warning-label (i18n/label :t/wallet-connect-sign-warning) {:warning-label (i18n/label :t/wallet-connect-sign-warning)
:slide-button-text (i18n/label :t/slide-to-send) :slide-button-text (i18n/label :t/slide-to-send)
:error-text (when error-state :error-state error-state}
(i18n/label (condp = error-state
:not-enough-assets-to-pay-gas-fees
:t/not-enough-assets-to-pay-gas-fees
:not-enough-assets
:t/not-enough-assets)))}
[quo/data-item [quo/data-item
{:status :default {:status :default
:card? false :card? false
@ -54,5 +108,12 @@
:subtitle (:full-name network)}] :subtitle (:full-name network)}]
[fees-data-item/view [fees-data-item/view
{:fees max-fees-fiat-formatted {:fees max-fees-fiat-formatted
:fees-error error-state}]]]])) :fees-error error-state}]
[quo/data-item
{:card? false
:container-style style/data-item
:title (i18n/label :t/est-time)
:subtitle (if estimated-time
(i18n/label :t/time-in-mins {:minutes estimated-time})
(i18n/label :t/unknown))}]]]]))

View File

@ -57,3 +57,8 @@
[chain-id] [chain-id]
(-> (rpc-events/call-async "wallet_getSuggestedFees" true chain-id) (-> (rpc-events/call-async "wallet_getSuggestedFees" true chain-id)
(promesa/then transforms/js->clj))) (promesa/then transforms/js->clj)))
(defn wallet-get-transaction-estimated-time
[chain-id max-fee-per-gas]
(-> (rpc-events/call-async "wallet_getTransactionEstimatedTime" true chain-id max-fee-per-gas)
(promesa/then transforms/js->clj)))

View File

@ -51,12 +51,16 @@
(transforms/js-stringify 0))) (transforms/js-stringify 0)))
(defn beautify-transaction (defn beautify-transaction
[tx]
(-> tx
clj->js
(js/JSON.stringify nil 2)))
(defn transaction-hex-values->number
[tx] [tx]
(let [hex->number #(-> % (subs 2) native-module/hex-to-number)] (let [hex->number #(-> % (subs 2) native-module/hex-to-number)]
(-> tx (-> tx
(format-tx-hex-values hex->number) (format-tx-hex-values hex->number))))
clj->js
(js/JSON.stringify nil 2))))
(defn- gwei->hex (defn- gwei->hex
[gwei] [gwei]
@ -121,10 +125,14 @@
tx-priority tx-priority
suggested-fees) suggested-fees)
prepare-transaction-for-rpc prepare-transaction-for-rpc
(rpc/wallet-build-transaction chain-id))] (rpc/wallet-build-transaction chain-id))
estimated-time (rpc/wallet-get-transaction-estimated-time
chain-id
(:maxPriorityFeePerGas suggested-fees))]
{:tx-args tx-args {:tx-args tx-args
:tx-hash message-to-sign :tx-hash message-to-sign
:suggested-fees suggested-fees})) :suggested-fees suggested-fees
:estimated-time estimated-time}))
(defn sign-transaction (defn sign-transaction
[password address tx-hash tx-args chain-id] [password address tx-hash tx-args chain-id]
@ -141,3 +149,11 @@
tx-args tx-args
signature)] signature)]
tx)) tx))
(defn transactions->display-array
[data]
(remove (fn [[k v]]
(or (= v "0x")
(= k :MultiTransactionID)
(= k :Symbol)))
data))

View File

@ -58,16 +58,19 @@
max-fees-fiat (wallet-utils/calculate-token-fiat-value {:currency currency max-fees-fiat (wallet-utils/calculate-token-fiat-value {:currency currency
:balance max-fees-ether :balance max-fees-ether
:token eth-token}) :token eth-token})
max-fees-fiat-formatted (-> (wallet-utils/get-standard-crypto-format eth-token max-fees-ether) max-fees-fiat-formatted (-> (wallet-utils/get-standard-crypto-format eth-token
max-fees-ether)
(wallet-utils/get-standard-fiat-format currency-symbol (wallet-utils/get-standard-fiat-format currency-symbol
max-fees-fiat)) max-fees-fiat))
balance (-> eth-token balance (-> eth-token
(get-in [:balances-per-chain chain-id :raw-balance]) (get-in [:balances-per-chain chain-id :raw-balance])
money/bignumber) money/bignumber)
tx-value (money/bignumber (:value transaction)) tx-value (money/bignumber (:value transaction))
total-transaction-value (money/add max-fees-wei tx-value)] total-transaction-value (money/add max-fees-wei tx-value)
estimated-time-formatted (wallet-utils/estimated-time-format (:estimated-time transaction))]
{:total-transaction-value total-transaction-value {:total-transaction-value total-transaction-value
:balance balance :balance balance
:estimated-time estimated-time-formatted
:max-fees max-fees-wei :max-fees max-fees-wei
:max-fees-fiat-value max-fees-fiat :max-fees-fiat-value max-fees-fiat
:max-fees-fiat-formatted max-fees-fiat-formatted :max-fees-fiat-formatted max-fees-fiat-formatted

View File

@ -1124,6 +1124,7 @@
"help-improve-status": "Help improve Status", "help-improve-status": "Help improve Status",
"help-us-improve-status": "Help us improve Status", "help-us-improve-status": "Help us improve Status",
"here-is-a-cat-in-a-box-instead": "Heres a cat in a box instead", "here-is-a-cat-in-a-box-instead": "Heres a cat in a box instead",
"hex": "Hex",
"hide": "Hide", "hide": "Hide",
"hide-content-when-switching-apps": "Block screenshots", "hide-content-when-switching-apps": "Block screenshots",
"hide-content-when-switching-apps-ios": "Hide preview", "hide-content-when-switching-apps-ios": "Hide preview",
@ -1737,6 +1738,7 @@
"not-connected-nodes": "Not connected to a status node", "not-connected-nodes": "Not connected to a status node",
"not-connected-to-peers": "Not connected to any peers", "not-connected-to-peers": "Not connected to any peers",
"not-enough-assets": "Not enough assets to complete transaction", "not-enough-assets": "Not enough assets to complete transaction",
"not-enough-assets-for-transaction": "Not enough assets for transaction",
"not-enough-assets-to-pay-gas-fees": "Not enough assets to pay gas fees", "not-enough-assets-to-pay-gas-fees": "Not enough assets to pay gas fees",
"not-enough-liquidity": "Not enough liquidity. Lower token amount or try again later.", "not-enough-liquidity": "Not enough liquidity. Lower token amount or try again later.",
"not-enough-snt": "Not enough SNT", "not-enough-snt": "Not enough SNT",