From 520f6ad354f67d9e992c98b698ee1abffad8313b Mon Sep 17 00:00:00 2001 From: Goran Jovic Date: Fri, 22 Feb 2019 13:52:16 +0100 Subject: [PATCH] refactor #7263 - decoupled sign message flow from send transaction flow Signed-off-by: Igor Mandrigin --- src/status_im/models/wallet.cljs | 5 - src/status_im/ui/screens/routing/screens.cljs | 3 +- .../ui/screens/wallet/send/events.cljs | 42 ++++--- .../ui/screens/wallet/send/subs.cljs | 1 - .../ui/screens/wallet/send/views.cljs | 29 +---- .../ui/screens/wallet/sign_message/views.cljs | 108 ++++++++++++++++++ 6 files changed, 138 insertions(+), 50 deletions(-) create mode 100644 src/status_im/ui/screens/wallet/sign_message/views.cljs diff --git a/src/status_im/models/wallet.cljs b/src/status_im/models/wallet.cljs index 5bb9930878..aecec8bbe5 100644 --- a/src/status_im/models/wallet.cljs +++ b/src/status_im/models/wallet.cljs @@ -178,11 +178,6 @@ (when on-error {:dispatch (conj on-error message)}))))) -(defn transform-data-for-message [{:keys [method] :as transaction}] - (cond-> transaction - (= method constants/web3-personal-sign) - (update :data transport.utils/to-utf8))) - (defn clear-error-message [db error-type] (update-in db [:wallet :errors] dissoc error-type)) diff --git a/src/status_im/ui/screens/routing/screens.cljs b/src/status_im/ui/screens/routing/screens.cljs index 25c24af4aa..5dc4eb3f7c 100644 --- a/src/status_im/ui/screens/routing/screens.cljs +++ b/src/status_im/ui/screens/routing/screens.cljs @@ -18,6 +18,7 @@ [status-im.ui.screens.wallet.main.views :as wallet.main] [status-im.ui.screens.wallet.collectibles.views :as collectibles] [status-im.ui.screens.wallet.send.views :as send] + [status-im.ui.screens.wallet.sign-message.views :as sign-message] [status-im.ui.screens.wallet.request.views :as request] [status-im.ui.screens.wallet.components.views :as wallet.components] [status-im.ui.screens.wallet.onboarding.views :as wallet.onboarding] @@ -96,7 +97,7 @@ :wallet-transaction-sent-modal [:modal transaction-sent/transaction-sent-modal] :wallet-transaction-fee [:modal wallet.transaction-fee/transaction-fee] :wallet-onboarding-setup-modal [:modal wallet.onboarding/modal] - :wallet-sign-message-modal [:modal send/sign-message-modal] + :wallet-sign-message-modal [:modal sign-message/sign-message-modal] :wallet wallet.main/wallet :collectibles-list collectibles/collectibles-list :wallet-onboarding-setup wallet.onboarding/screen diff --git a/src/status_im/ui/screens/wallet/send/events.cljs b/src/status_im/ui/screens/wallet/send/events.cljs index 32e22db1eb..a79fcb74e6 100644 --- a/src/status_im/ui/screens/wallet/send/events.cljs +++ b/src/status_im/ui/screens/wallet/send/events.cljs @@ -19,7 +19,8 @@ [status-im.utils.security :as security] [status-im.utils.types :as types] [status-im.utils.utils :as utils] - [status-im.utils.config :as config])) + [status-im.utils.config :as config] + [status-im.transport.utils :as transport.utils])) ;;;; FX @@ -74,15 +75,14 @@ ;; SIGN MESSAGE (handlers/register-handler-fx :wallet/sign-message - (fn [{db :db} _] - (let [{:keys [data from password]} (get-in db [:wallet :send-transaction])] - {:db (assoc-in db [:wallet :send-transaction :in-progress?] true) - ::sign-message {:params {:data data + (fn [_ [_ screen-params]] + (let [{:keys [data from password]} screen-params] + {::sign-message {:params {:data data :password (security/safe-unmask-data password) :account from} - :on-completed #(re-frame/dispatch [::transaction-completed (types/json->clj %)])}}))) + :on-completed #(re-frame/dispatch [::sign-message-completed screen-params (types/json->clj %)])}}))) -;; SEND TRANSACTION (SIGN MESSAGE) CALLBACK +;; SEND TRANSACTION CALLBACK (handlers/register-handler-fx ::transaction-completed (fn [{:keys [db now] :as cofx} [_ {:keys [result error]}]] @@ -106,6 +106,18 @@ :amount amount-text :tx-hash result}]})))))) +;; SIGN MESSAGE CALLBACK +(handlers/register-handler-fx + ::sign-message-completed + (fn [{:keys [db now] :as cofx} [_ {:keys [on-result id method]} {:keys [result error]}]] + (let [db' (assoc-in db [:wallet :send-transaction :in-progress?] false)] + (if error + ;; ERROR + (models.wallet/handle-transaction-error (assoc cofx :db db') error) + ;; RESULT + (if on-result + {:dispatch (conj on-result id result method)}))))) + ;; DISCARD TRANSACTION (handlers/register-handler-fx :wallet/discard-transaction @@ -148,14 +160,14 @@ (= method constants/web3-personal-sign) (let [[address data] (models.wallet/normalize-sign-message-params params)] (if (and address data) - (let [db'' (assoc-in db' [:wallet :send-transaction] - {:id (str (or id message-id)) - :from address - :data data - :on-result [:wallet.dapp/transaction-on-result message-id] - :on-error [:wallet.dapp/transaction-on-error message-id] - :method method})] - (navigation/navigate-to-cofx {:db db''} :wallet-sign-message-modal nil)) + (let [screen-params {:id (str (or id message-id)) + :from address + :data data + :decoded-data (transport.utils/to-utf8 data) + :on-result [:wallet.dapp/transaction-on-result message-id] + :on-error [:wallet.dapp/transaction-on-error message-id] + :method method}] + (navigation/navigate-to-cofx {:db db'} :wallet-sign-message-modal screen-params)) {:db db'}))))))) (handlers/register-handler-fx diff --git a/src/status_im/ui/screens/wallet/send/subs.cljs b/src/status_im/ui/screens/wallet/send/subs.cljs index 63bc84c421..c3d04af789 100644 --- a/src/status_im/ui/screens/wallet/send/subs.cljs +++ b/src/status_im/ui/screens/wallet/send/subs.cljs @@ -86,7 +86,6 @@ :<- [:balance] (fn [[{:keys [amount symbol] :as transaction} balance]] (-> transaction - (models.wallet/transform-data-for-message) (models.wallet/add-max-fee) (check-sufficient-funds balance symbol amount) (check-sufficient-gas balance symbol amount)))) diff --git a/src/status_im/ui/screens/wallet/send/views.cljs b/src/status_im/ui/screens/wallet/send/views.cljs index f6c7a31d31..4c97e38c9a 100644 --- a/src/status_im/ui/screens/wallet/send/views.cljs +++ b/src/status_im/ui/screens/wallet/send/views.cljs @@ -237,31 +237,4 @@ [status-bar/status-bar {:type :modal-wallet}] [toolbar true (i18n/label :t/send-transaction)] [react/i18n-text {:style styles/empty-text - :key :unsigned-transaction-expired}]]]))) - -;; SIGN MESSAGE FROM DAPP -(defview sign-message-modal [] - (letsubs [{:keys [data in-progress?]} [:wallet.send/transaction] - network-status [:network-status]] - [wallet.components/simple-screen {:status-bar-type :modal-wallet} - [toolbar true (i18n/label :t/sign-message)] - [react/view components.styles/flex - [react/scroll-view - (when (= network-status :offline) - [wallet.main.views/snackbar :t/error-cant-sign-message-offline]) - [react/view styles/send-transaction-form - [wallet.components/cartouche {:disabled? true} - (i18n/label :t/message) - [components/amount-input - {:disabled? true - :input-options {:multiline true - :height 100} - :amount-text data} - nil]]]] - [enter-password-buttons false - #(re-frame/dispatch [:wallet/discard-transaction-navigate-back]) - #(re-frame/dispatch [:wallet/sign-message]) - :t/transactions-sign] - [password-input-panel :t/signing-message-phrase-description false] - (when in-progress? - [react/view styles/processing-view])]])) + :key :unsigned-transaction-expired}]]]))) \ No newline at end of file diff --git a/src/status_im/ui/screens/wallet/sign_message/views.cljs b/src/status_im/ui/screens/wallet/sign_message/views.cljs new file mode 100644 index 0000000000..8efa5dce39 --- /dev/null +++ b/src/status_im/ui/screens/wallet/sign_message/views.cljs @@ -0,0 +1,108 @@ +(ns status-im.ui.screens.wallet.sign-message.views + (:require-macros [status-im.utils.views :refer [defview letsubs]]) + (:require [re-frame.core :as re-frame] + [status-im.i18n :as i18n] + [status-im.ui.components.react :as react] + [status-im.ui.components.styles :as components.styles] + [status-im.ui.screens.wallet.components.views :as components] + [status-im.ui.screens.wallet.components.views :as wallet.components] + [status-im.ui.screens.wallet.send.styles :as styles] + [status-im.ui.screens.wallet.main.views :as wallet.main.views] + [status-im.ui.components.toolbar.actions :as actions] + [status-im.ui.components.toolbar.view :as toolbar] + [status-im.ui.screens.wallet.styles :as wallet.styles] + [status-im.ui.components.bottom-buttons.view :as bottom-buttons] + [status-im.ui.components.button.view :as button] + [status-im.ui.components.icons.vector-icons :as vector-icons] + [status-im.ui.components.colors :as colors] + [status-im.ui.components.animation :as animation] + [status-im.ui.screens.wallet.send.animations :as send.animations] + [status-im.utils.security :as security] + [status-im.ui.components.tooltip.views :as tooltip] + [reagent.core :as reagent])) + +(defn- toolbar [modal? title] + (let [action (if modal? actions/close-white actions/back-white)] + [toolbar/toolbar {:style wallet.styles/toolbar} + [toolbar/nav-button (action (if modal? + #(re-frame/dispatch [:wallet/discard-transaction-navigate-back]) + #(actions/default-handler)))] + [toolbar/content-title {:color :white} title]])) + +(defview enter-password-buttons [value-atom spinning? cancel-handler sign-handler sign-label] + (letsubs [network-status [:network-status]] + (let [password (:password @value-atom) + sign-enabled? (and (not (nil? password)) (not= password ""))] + [bottom-buttons/bottom-buttons + styles/sign-buttons + [button/button {:style components.styles/flex + :on-press cancel-handler + :accessibility-label :cancel-button} + (i18n/label :t/cancel)] + [button/button {:style (wallet.styles/button-container sign-enabled?) + :on-press sign-handler + :disabled? (or spinning? + (not sign-enabled?) + (= :offline network-status)) + :accessibility-label :sign-transaction-button} + (i18n/label sign-label) + [vector-icons/icon :main-icons/next {:color colors/white}]]]))) + +(defview password-input-panel [value-atom message-label spinning?] + (letsubs [account [:account/account] + signing-phrase (:signing-phrase @account) + bottom-value (animation/create-value -250) + opacity-value (animation/create-value 0)] + {:component-did-mount #(send.animations/animate-sign-panel opacity-value bottom-value)} + [react/animated-view {:style (styles/animated-sign-panel bottom-value)} + (when (:wrong-password? value-atom) + [tooltip/tooltip (i18n/label :t/wrong-password) styles/password-error-tooltip]) + [react/animated-view {:style (styles/sign-panel opacity-value)} + [react/view styles/spinner-container + (when spinning? + [react/activity-indicator {:animating true + :size :large}])] + [react/view styles/signing-phrase-container + [react/text {:style styles/signing-phrase + :accessibility-label :signing-phrase-text} + signing-phrase]] + [react/i18n-text {:style styles/signing-phrase-description :key message-label}] + [react/view {:style styles/password-container + :important-for-accessibility :no-hide-descendants} + [react/text-input + {:auto-focus true + :secure-text-entry true + :placeholder (i18n/label :t/enter-password) + :placeholder-text-color colors/gray + :on-change-text #(swap! value-atom assoc :password (security/mask-data %)) + :style styles/password + :accessibility-label :enter-password-input + :auto-capitalize :none}]]]])) + +;; SIGN MESSAGE FROM DAPP +(defview sign-message-modal [] + (letsubs [value-atom (reagent/atom nil) + {:keys [decoded-data in-progress?] :as screen-params} [:get-screen-params :wallet-sign-message-modal] + network-status [:network-status]] + [wallet.components/simple-screen {:status-bar-type :modal-wallet} + [toolbar true (i18n/label :t/sign-message)] + [react/view components.styles/flex + [react/scroll-view + (when (= network-status :offline) + [wallet.main.views/snackbar :t/error-cant-sign-message-offline]) + [react/view styles/send-transaction-form + [wallet.components/cartouche {:disabled? true} + (i18n/label :t/message) + [components/amount-input + {:disabled? true + :input-options {:multiline true + :height 100} + :amount-text decoded-data} + nil]]]] + [enter-password-buttons value-atom false + #(re-frame/dispatch [:wallet/discard-transaction-navigate-back]) + #(re-frame/dispatch [:wallet/sign-message (merge screen-params @value-atom)]) + :t/transactions-sign] + [password-input-panel value-atom :t/signing-message-phrase-description false] + (when in-progress? + [react/view styles/processing-view])]]))