[bug] fix #2128 No feedback on insufficient funds from unsigned
- move current unsigned-transaction to wallet - move some logic from view to subscriptions and events
This commit is contained in:
parent
f4082951b7
commit
0707af2ad6
|
@ -6,12 +6,12 @@
|
|||
(handlers/register-handler-db
|
||||
:wallet/toggle-flashlight
|
||||
(fn [db]
|
||||
(let [flashlight-state (get-in db [:wallet/send-transaction :camera-flashlight])
|
||||
(let [flashlight-state (get-in db [:wallet :send-transaction :camera-flashlight])
|
||||
toggled-state (if (= :on flashlight-state) :off :on)]
|
||||
(assoc-in db [:wallet/send-transaction :camera-flashlight] toggled-state))))
|
||||
(assoc-in db [:wallet :send-transaction :camera-flashlight] toggled-state))))
|
||||
|
||||
(defn choose-address-and-name [db address name amount]
|
||||
(update db :wallet/send-transaction assoc :to-address address :to-name name :amount amount))
|
||||
(update-in db [:wallet :send-transaction] assoc :to-address address :to-name name :amount amount))
|
||||
|
||||
(defn- extract-details
|
||||
"First try to parse as EIP67 URI, if not assume this is an address directly.
|
||||
|
@ -28,13 +28,13 @@
|
|||
;; isAddress works with or without address with leading '0x'
|
||||
valid-address? (.isAddress web3 address)]
|
||||
(cond-> {:db db}
|
||||
(= :choose-recipient view-id) (assoc :dispatch [:navigate-back])
|
||||
valid-address? (update :db #(choose-address-and-name % address name (:value m)))
|
||||
(not valid-address?) (assoc :show-error (i18n/label :t/wallet-invalid-address {:data data}))))))
|
||||
(= :choose-recipient view-id) (assoc :dispatch [:navigate-back])
|
||||
valid-address? (update :db #(choose-address-and-name % address name (:value m)))
|
||||
(not valid-address?) (assoc :show-error (i18n/label :t/wallet-invalid-address {:data data}))))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet-open-send-transaction
|
||||
(fn [{db :db} [_ address name]]
|
||||
{:db (choose-address-and-name db address name nil)
|
||||
:dispatch-n [[:navigate-back]
|
||||
[:navigate-back]]}))
|
||||
[:navigate-back]]}))
|
||||
|
|
|
@ -71,18 +71,18 @@
|
|||
:style (styles/corner-right-bottom min-dimension)}]]))
|
||||
|
||||
(defview choose-recipient []
|
||||
(letsubs [camera-dimensions [:camera-dimensions]
|
||||
camera-flashlight [:camera-flashlight]
|
||||
camera-permitted? [:get-in [:wallet/send-transaction :camera-permitted?]]]
|
||||
(letsubs [camera-dimensions [:wallet.send/camera-dimensions]
|
||||
camera-flashlight [:wallet.send/camera-flashlight]
|
||||
camera-permitted? [:wallet.send/camera-permitted?]]
|
||||
[react/view {:style styles/wallet-container}
|
||||
[status-bar/status-bar {:type :wallet}]
|
||||
[toolbar-view camera-flashlight]
|
||||
[react/view {:style styles/qr-container
|
||||
:pointerEvents :none
|
||||
:on-layout #(let [layout (.. % -nativeEvent -layout)]
|
||||
(re-frame/dispatch [:set-in [:wallet/send-transaction :camera-dimensions]
|
||||
{:width (.-width layout)
|
||||
:height (.-height layout)}]))}
|
||||
[react/view {:style styles/qr-container
|
||||
:pointerEvents :none
|
||||
:on-layout #(let [layout (.. % -nativeEvent -layout)]
|
||||
(re-frame/dispatch [:wallet.send/set-camera-dimensions
|
||||
{:width (.-width layout)
|
||||
:height (.-height layout)}]))}
|
||||
(when (or platform/android?
|
||||
camera-permitted?)[camera/camera {:style styles/preview
|
||||
:aspect :fill
|
||||
|
|
|
@ -21,37 +21,29 @@
|
|||
[react/text {:style styles/tooltip-text} label]]
|
||||
[vector-icons/icon :icons/tooltip-triangle {:color :white :style styles/tooltip-triangle}]]]))
|
||||
|
||||
;;TODO (andrey) temporary, should be removed later
|
||||
(defn amount-input-disabled [amount]
|
||||
[react/view components.styles/flex
|
||||
[react/text {:style styles/label} (i18n/label :t/amount)]
|
||||
[react/view styles/amount-text-input-container
|
||||
[react/view (merge (styles/amount-container false) styles/container-disabled)
|
||||
[react/text-input
|
||||
{:editable false
|
||||
:default-value amount
|
||||
:style styles/text-input}]]]])
|
||||
|
||||
(defn amount-input []
|
||||
(let [active? (reagent/atom false)]
|
||||
(fn [& [{:keys [input-options style error]}]]
|
||||
(fn [& [{:keys [input-options style error disabled?]}]]
|
||||
(let [{:keys [on-focus on-blur]} input-options]
|
||||
[react/view components.styles/flex
|
||||
[react/text {:style styles/label} (i18n/label :t/amount)]
|
||||
[react/view styles/amount-text-input-container
|
||||
[react/view (merge (styles/amount-container @active?) style)
|
||||
[react/view (merge (styles/amount-container @active?) (if disabled? styles/container-disabled style))
|
||||
[react/text-input
|
||||
(merge
|
||||
{:keyboard-type :numeric
|
||||
:placeholder "0.000"
|
||||
:placeholder-text-color "#ffffff66"
|
||||
:selection-color :white
|
||||
:style styles/text-input
|
||||
:on-focus #(do (reset! active? true)
|
||||
(when on-focus (on-focus)))
|
||||
:on-blur #(do (reset! active? false)
|
||||
(when on-blur (on-blur)))}
|
||||
(dissoc input-options :on-focus :on-blur))]]
|
||||
{:style styles/text-input}
|
||||
(if disabled?
|
||||
{:editable false}
|
||||
{:keyboard-type :numeric
|
||||
:placeholder "0.000"
|
||||
:placeholder-text-color "#ffffff66"
|
||||
:selection-color :white
|
||||
:style styles/text-input
|
||||
:on-focus #(do (reset! active? true)
|
||||
(when on-focus (on-focus)))
|
||||
:on-blur #(do (reset! active? false)
|
||||
(when on-blur (on-blur)))})
|
||||
(dissoc input-options :on-focus :on-blur))]]
|
||||
(when-not (nil? error)
|
||||
[tooltip error])]]))))
|
||||
|
||||
|
@ -124,4 +116,4 @@
|
|||
(defn button-text [label]
|
||||
[react/text {:style styles/button-text
|
||||
:font (if platform/android? :medium :default)
|
||||
:uppercase? (get-in platform/platform-specific [:uppercase?])} label])
|
||||
:uppercase? (get-in platform/platform-specific [:uppercase?])} label])
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
|
||||
(spec/def :wallet/send (spec/keys :req-un [:wallet.send/recipient]))
|
||||
|
||||
(spec/def :wallet/wallet (spec/keys :opt [:wallet/error]))
|
||||
(spec/def :wallet/wallet (spec/keys :opt [:wallet/error]
|
||||
:opt-un [ :wallet/send-transaction]))
|
||||
|
||||
;; Placeholder namespace for wallet specs, which are a WIP depending on data
|
||||
;; model we decide on for balances, prices, etc.
|
||||
|
@ -36,4 +37,4 @@
|
|||
(i18n/label :t/validation-amount-invalid-number)
|
||||
|
||||
(too-precise-amount? normalized-amount)
|
||||
(i18n/label :t/validation-amount-is-too-precise)))))
|
||||
(i18n/label :t/validation-amount-is-too-precise)))))
|
||||
|
|
|
@ -137,6 +137,13 @@
|
|||
{:db (assoc-in db [:wallet :current-transaction] hash)
|
||||
:dispatch [:navigate-to :wallet-transaction-details]}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet/show-sign-transaction
|
||||
(fn [{:keys [db]} [_ id from-chat?]]
|
||||
{:db (assoc-in db [:wallet :send-transaction] {:id id
|
||||
:from-chat? from-chat?})
|
||||
:dispatch [:navigate-to-modal :wallet-send-transaction-modal]}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet/discard-unsigned-transaction
|
||||
(fn [_ [_ transaction-id]]
|
||||
|
@ -148,4 +155,4 @@
|
|||
{:show-confirmation {:title (i18n/label :t/transactions-delete)
|
||||
:content (i18n/label :t/transactions-delete-content)
|
||||
:confirm-button-text (i18n/label :t/confirm)
|
||||
:on-accept #(re-frame/dispatch [:wallet/discard-unsigned-transaction transaction-id])}}))
|
||||
:on-accept #(re-frame/dispatch [:wallet/discard-unsigned-transaction transaction-id])}}))
|
||||
|
|
|
@ -20,8 +20,4 @@
|
|||
[db [event]]
|
||||
(if (= event :navigate-back)
|
||||
db
|
||||
(dissoc db :wallet/send-transaction)))
|
||||
|
||||
(defmethod navigation/preload-data! :wallet-send-transaction-modal
|
||||
[db [_ _ value]]
|
||||
(assoc db :wallet/send-transaction value))
|
||||
(update db :wallet dissoc :send-transaction)))
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
(spec/def ::amount-error (spec/nilable string?))
|
||||
(spec/def ::password (spec/nilable string?))
|
||||
(spec/def ::wrong-password? (spec/nilable boolean?))
|
||||
(spec/def ::transaction-id (spec/nilable string?))
|
||||
(spec/def ::id (spec/nilable string?))
|
||||
(spec/def ::waiting-signal? (spec/nilable boolean?))
|
||||
(spec/def ::signing? (spec/nilable boolean?))
|
||||
(spec/def ::later? (spec/nilable boolean?))
|
||||
|
@ -18,10 +18,10 @@
|
|||
(spec/def ::camera-flashlight #{:on :off})
|
||||
(spec/def ::camera-permitted? boolean?)
|
||||
(spec/def ::in-progress? boolean?)
|
||||
(spec/def ::from-chat? boolean?)
|
||||
(spec/def ::from-chat? (spec/nilable boolean?))
|
||||
|
||||
(spec/def :wallet/send-transaction (allowed-keys
|
||||
:opt-un [::amount ::to-address ::to-name ::amount-error ::password
|
||||
::waiting-signal? ::signing? ::transaction-id ::later?
|
||||
::waiting-signal? ::signing? ::id ::later?
|
||||
::camera-dimensions ::camera-flashlight ::in-progress?
|
||||
::wrong-password? ::camera-permitted? ::from-chat?]))
|
||||
|
|
|
@ -34,13 +34,13 @@
|
|||
|
||||
(handlers/register-handler-fx
|
||||
:wallet/set-and-validate-amount
|
||||
(fn [{{:wallet/keys [send-transaction] :as db} :db} [_ amount]]
|
||||
(fn [{:keys [db]} [_ amount]]
|
||||
(let [error (wallet.db/get-amount-validation-error amount)]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet/send-transaction :amount] amount)
|
||||
(assoc-in [:wallet/send-transaction :amount-error] error))})))
|
||||
(assoc-in [:wallet :send-transaction :amount] amount)
|
||||
(assoc-in [:wallet :send-transaction :amount-error] error))})))
|
||||
|
||||
(def ^:private clear-send-properties {:transaction-id nil
|
||||
(def ^:private clear-send-properties {:id nil
|
||||
:wrong-password? false
|
||||
:waiting-signal? false
|
||||
:from-chat? false})
|
||||
|
@ -49,11 +49,11 @@
|
|||
::transaction-completed
|
||||
(fn [{db :db} [_ {:keys [id response]}]]
|
||||
(let [{:keys [hash error]} response
|
||||
db' (assoc-in db [:wallet/send-transaction :in-progress?] false)]
|
||||
db' (assoc-in db [:wallet :send-transaction :in-progress?] false)]
|
||||
(if-not (and error (string? error) (not (string/blank? error)))
|
||||
{:db (-> db'
|
||||
(update-in [:wallet :transactions-unsigned] dissoc id)
|
||||
(update :wallet/send-transaction merge clear-send-properties))
|
||||
(update-in [:wallet :send-transaction] merge clear-send-properties))
|
||||
:dispatch [:navigate-to :wallet-transaction-sent]}
|
||||
{:db db'}))))
|
||||
|
||||
|
@ -66,13 +66,13 @@
|
|||
::transaction-modal-completed
|
||||
(fn [{db :db} [_ {:keys [id response]}]]
|
||||
(let [{:keys [hash error]} response
|
||||
db' (assoc-in db [:wallet/send-transaction :in-progress?] false)
|
||||
db' (assoc-in db [:wallet :send-transaction :in-progress?] false)
|
||||
has-error? (and error (string? error) (not (string/blank? error)))]
|
||||
(if has-error?
|
||||
{:db db'}
|
||||
{:db (-> db'
|
||||
(update-in [:wallet :transactions-unsigned] dissoc id)
|
||||
(update :wallet/send-transaction merge clear-send-properties))
|
||||
(update-in [:wallet :send-transaction] merge clear-send-properties))
|
||||
:dispatch [:navigate-back]}))))
|
||||
|
||||
(defn on-transactions-modal-completed [raw-results]
|
||||
|
@ -82,56 +82,51 @@
|
|||
|
||||
(handlers/register-handler-fx
|
||||
:wallet.send-transaction/transaction-queued
|
||||
(fn [{{:wallet/keys [send-transaction] :as db} :db} _]
|
||||
(let [{:keys [later? password transaction-id]} send-transaction]
|
||||
(fn [{:keys [db]} _]
|
||||
(let [{:keys [later? password id]} (get-in db [:wallet :send-transaction])]
|
||||
(if later?
|
||||
{:db (assoc-in db [:wallet/send-transaction :waiting-signal?] false)
|
||||
{:db (assoc-in db [:wallet :send-transaction :waiting-signal?] false)
|
||||
:dispatch [:navigate-back]
|
||||
::show-transaction-moved nil}
|
||||
{::accept-transaction {:id transaction-id
|
||||
{::accept-transaction {:id id
|
||||
:password password
|
||||
:on-completed on-transactions-completed}}))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet/sign-transaction
|
||||
(fn [{{:keys [web3]
|
||||
:wallet/keys [send-transaction]
|
||||
:accounts/keys [accounts current-account-id] :as db} :db} [_ later?]]
|
||||
(let [{:keys [amount transaction-id password]} send-transaction]
|
||||
(if transaction-id
|
||||
{::accept-transaction {:id transaction-id
|
||||
(let [{:keys [amount id password to-address]} (get-in db [:wallet :send-transaction])]
|
||||
(if id
|
||||
{::accept-transaction {:id id
|
||||
:password password
|
||||
:on-completed on-transactions-completed}
|
||||
:db (assoc-in db [:wallet/send-transaction :in-progress?] true)}
|
||||
{:db (update db :wallet/send-transaction assoc
|
||||
:waiting-signal? true
|
||||
:later? later?
|
||||
:in-progress? true)
|
||||
:db (assoc-in db [:wallet :send-transaction :in-progress?] true)}
|
||||
{:db (update-in db [:wallet :send-transaction] assoc
|
||||
:waiting-signal? true
|
||||
:later? later?
|
||||
:in-progress? true)
|
||||
::send-transaction {:web3 web3
|
||||
:from (get-in accounts [current-account-id :address])
|
||||
:to (:to-address send-transaction)
|
||||
:to to-address
|
||||
:value (money/to-wei (money/normalize amount))}}))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet/sign-transaction-modal
|
||||
(fn [{{:keys [web3]
|
||||
:wallet/keys [send-transaction]
|
||||
:accounts/keys [accounts current-account-id] :as db} :db} [_ later?]]
|
||||
(let [{:keys [transaction-id password]} send-transaction]
|
||||
{:db (assoc-in db [:wallet/send-transaction :in-progress?] true)
|
||||
::accept-transaction {:id transaction-id
|
||||
(let [{:keys [id password]} (get-in db [:wallet :send-transaction])]
|
||||
{:db (assoc-in db [:wallet :send-transaction :in-progress?] true)
|
||||
::accept-transaction {:id id
|
||||
:password password
|
||||
:on-completed on-transactions-modal-completed}})))
|
||||
|
||||
(defn discard-transaction
|
||||
[{{:wallet/keys [send-transaction] :as db} :db}]
|
||||
(let [{:keys [transaction-id]} send-transaction]
|
||||
(merge {:db (update db :wallet/send-transaction assoc
|
||||
:signing? false
|
||||
:transaction-id nil
|
||||
:wrong-password? false)}
|
||||
(when transaction-id
|
||||
{:discard-transaction transaction-id}))))
|
||||
[{:keys [db]}]
|
||||
(let [{:keys [id]} (get-in db [:wallet :send-transaction])]
|
||||
(merge {:db (update-in db [:wallet :send-transaction] merge clear-send-properties)}
|
||||
(when id
|
||||
{:discard-transaction id}))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet/discard-transaction
|
||||
|
@ -147,7 +142,22 @@
|
|||
|
||||
(handlers/register-handler-fx
|
||||
:wallet/cancel-signing-modal
|
||||
(fn [{{:wallet/keys [send-transaction] :as db} :db} _]
|
||||
(let [{:keys [transaction-id]} send-transaction]
|
||||
{:db (update-in db [:wallet/send-transaction]
|
||||
assoc :signing? false :wrong-password? false)})))
|
||||
(fn [{:keys [db]} _]
|
||||
{:db (update-in db [:wallet :send-transaction] assoc
|
||||
:signing? false
|
||||
:wrong-password? false)}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet.send/set-camera-dimensions
|
||||
(fn [{:keys [db]} [_ camera-dimensions]]
|
||||
{:db (assoc-in db [:wallet :send-transaction :camera-dimensions] camera-dimensions)}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet.send/set-password
|
||||
(fn [{:keys [db]} [_ password]]
|
||||
{:db (assoc-in db [:wallet :send-transaction :password] password)}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet.send/set-signing?
|
||||
(fn [{:keys [db]} [_ signing?]]
|
||||
{:db (assoc-in db [:wallet :send-transaction :signing?] signing?)}))
|
||||
|
|
|
@ -1,27 +1,76 @@
|
|||
(ns status-im.ui.screens.wallet.send.subs
|
||||
(:require [re-frame.core :as re-frame]))
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.utils.money :as money]
|
||||
[status-im.utils.hex :as utils.hex]))
|
||||
|
||||
(re-frame/reg-sub :camera-dimensions
|
||||
(fn [db]
|
||||
(get-in db [:wallet/send-transaction :camera-dimensions])))
|
||||
(re-frame/reg-sub ::send-transaction
|
||||
:<- [:wallet]
|
||||
(fn [wallet]
|
||||
(:send-transaction wallet)))
|
||||
|
||||
(re-frame/reg-sub :camera-flashlight
|
||||
(fn [db]
|
||||
(get-in db [:wallet/send-transaction :camera-flashlight])))
|
||||
(re-frame/reg-sub :wallet.send/camera-dimensions
|
||||
:<- [::send-transaction]
|
||||
(fn [send-transaction]
|
||||
(:camera-dimensions send-transaction)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet.send/sign-enabled?
|
||||
:<- [:get-in [:wallet/send-transaction :amount]]
|
||||
:<- [:get-in [:wallet/send-transaction :to-address]]
|
||||
:<- [:get-in [:wallet/send-transaction :amount-error]]
|
||||
(fn [[amount to-address amount-error]]
|
||||
(and
|
||||
(nil? amount-error)
|
||||
(not (nil? to-address)) (not= to-address "")
|
||||
(not (nil? amount)) (not= amount ""))))
|
||||
(re-frame/reg-sub :wallet.send/camera-flashlight
|
||||
:<- [::send-transaction]
|
||||
(fn [send-transaction]
|
||||
(:camera-flashlight send-transaction)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet.send/sign-password-enabled?
|
||||
:<- [:get-in [:wallet/send-transaction :password]]
|
||||
(fn [password]
|
||||
(re-frame/reg-sub :wallet.send/camera-permitted?
|
||||
:<- [::send-transaction]
|
||||
(fn [send-transaction]
|
||||
(:camera-permitted? send-transaction)))
|
||||
|
||||
(re-frame/reg-sub :wallet.send/wrong-password?
|
||||
:<- [::send-transaction]
|
||||
(fn [send-transaction]
|
||||
(:wrong-password? send-transaction)))
|
||||
|
||||
(re-frame/reg-sub :wallet.send/sign-password-enabled?
|
||||
:<- [::send-transaction]
|
||||
(fn [{:keys [password]}]
|
||||
(and (not (nil? password)) (not= password ""))))
|
||||
|
||||
(re-frame/reg-sub ::unsigned-transactions
|
||||
:<- [:wallet]
|
||||
(fn [wallet]
|
||||
(:transactions-unsigned wallet)))
|
||||
|
||||
(re-frame/reg-sub ::unsigned-transaction
|
||||
:<- [::send-transaction]
|
||||
:<- [::unsigned-transactions]
|
||||
(fn [[send-transaction unsigned-transactions]]
|
||||
(when-let [unsigned-transaction (get unsigned-transactions
|
||||
(:id send-transaction))]
|
||||
(merge send-transaction
|
||||
unsigned-transaction))))
|
||||
|
||||
(defn sign-enabled? [amount-error to-address amount]
|
||||
(and
|
||||
(nil? amount-error)
|
||||
(not (nil? to-address)) (not= to-address "")
|
||||
(not (nil? amount)) (not= amount "")))
|
||||
|
||||
(re-frame/reg-sub :wallet.send/transaction
|
||||
:<- [::send-transaction]
|
||||
:<- [:balance]
|
||||
(fn [[{:keys [amount to] :as transaction} balance]]
|
||||
(assoc transaction :sufficient-funds? (or (nil? amount)
|
||||
(money/sufficient-funds? amount balance)))))
|
||||
|
||||
(re-frame/reg-sub :wallet.send/unsigned-transaction
|
||||
:<- [::unsigned-transaction]
|
||||
:<- [:contacts/by-address]
|
||||
:<- [:balance]
|
||||
(fn [[{:keys [value to] :as transaction} contacts balance]]
|
||||
(when transaction
|
||||
(let [contact (contacts (utils.hex/normalize-hex to))
|
||||
amount (str (.toFixed (money/wei->ether value)))
|
||||
sufficient-funds? (money/sufficient-funds? amount balance)]
|
||||
(cond-> (assoc transaction
|
||||
:amount amount
|
||||
:sufficient-funds? sufficient-funds?)
|
||||
contact (assoc :to-name (:name contact)))))))
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
(ns status-im.ui.screens.wallet.send.views
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.components.animation :as animation]
|
||||
[status-im.components.camera :as camera]
|
||||
[status-im.components.common.common :as common]
|
||||
[status-im.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.components.react :as react]
|
||||
[status-im.components.status-bar :as status-bar]
|
||||
[status-im.components.styles :as components.styles]
|
||||
[status-im.components.toolbar-new.actions :as act]
|
||||
[status-im.components.toolbar-new.view :as toolbar]
|
||||
[status-im.components.camera :as camera]
|
||||
[status-im.components.common.common :as common]
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.wallet.components.views :as components]
|
||||
[status-im.ui.screens.wallet.send.animations :as send.animations]
|
||||
[status-im.ui.screens.wallet.send.styles :as send.styles]
|
||||
[status-im.ui.screens.wallet.styles :as wallet.styles]
|
||||
[status-im.utils.money :as money]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.ui.screens.wallet.request.styles :as request.styles]
|
||||
[status-im.ui.screens.wallet.components.views :as components]
|
||||
[status-im.ui.screens.wallet.styles :as wallet.styles]
|
||||
[status-im.ui.screens.wallet.send.animations :as send.animations]
|
||||
[status-im.ui.screens.wallet.send.styles :as send.styles]))
|
||||
[status-im.utils.utils :as utils])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
||||
(defn toolbar-view [signing?]
|
||||
[toolbar/toolbar2 {:style wallet.styles/toolbar}
|
||||
|
@ -29,30 +28,30 @@
|
|||
|
||||
(defn sign-later []
|
||||
(utils/show-question
|
||||
(i18n/label :t/sign-later-title)
|
||||
(i18n/label :t/sign-later-text)
|
||||
#(re-frame/dispatch [:wallet/sign-transaction true])))
|
||||
(i18n/label :t/sign-later-title)
|
||||
(i18n/label :t/sign-later-text)
|
||||
#(re-frame/dispatch [:wallet/sign-transaction true])))
|
||||
|
||||
(defview sign-panel []
|
||||
(letsubs [account [:get-current-account]
|
||||
wrong-password? [:get-in [:wallet/send-transaction :wrong-password?]]
|
||||
wrong-password? [:wallet.send/wrong-password?]
|
||||
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 (send.styles/animated-sign-panel bottom-value)}
|
||||
[react/animated-view {:style (send.styles/sign-panel opacity-value)}
|
||||
[react/view send.styles/signing-phrase-container
|
||||
[react/text {:style send.styles/signing-phrase} signing-phrase]]
|
||||
[react/text {:style send.styles/signing-phrase-description} (i18n/label :t/signing-phrase-description)]
|
||||
[react/view send.styles/password-container
|
||||
[react/text-input
|
||||
{:auto-focus true
|
||||
:secure-text-entry true
|
||||
:placeholder (i18n/label :t/enter-password)
|
||||
:placeholder-text-color "#939ba1"
|
||||
:on-change-text #(re-frame/dispatch [:set-in [:wallet/send-transaction :password] %])
|
||||
:style send.styles/password}]]]
|
||||
[react/animated-view {:style (send.styles/sign-panel opacity-value)}
|
||||
[react/view send.styles/signing-phrase-container
|
||||
[react/text {:style send.styles/signing-phrase} signing-phrase]]
|
||||
[react/text {:style send.styles/signing-phrase-description} (i18n/label :t/signing-phrase-description)]
|
||||
[react/view send.styles/password-container
|
||||
[react/text-input
|
||||
{:auto-focus true
|
||||
:secure-text-entry true
|
||||
:placeholder (i18n/label :t/enter-password)
|
||||
:placeholder-text-color "#939ba1"
|
||||
:on-change-text #(re-frame/dispatch [:wallet.send/set-password %])
|
||||
:style send.styles/password}]]]
|
||||
(when wrong-password?
|
||||
[components/tooltip (i18n/label :t/wrong-password)])]))
|
||||
|
||||
|
@ -73,9 +72,9 @@
|
|||
|
||||
(defn sign-enabled? [amount-error to-address amount]
|
||||
(and
|
||||
(nil? amount-error)
|
||||
(not (nil? to-address)) (not= to-address "")
|
||||
(not (nil? amount)) (not= amount "")))
|
||||
(nil? amount-error)
|
||||
(not (nil? to-address)) (not= to-address "")
|
||||
(not (nil? amount)) (not= amount "")))
|
||||
|
||||
;; "Sign Later" and "Sign Transaction >" buttons
|
||||
(defn- sign-buttons [amount-error to-address amount sufficient-funds? sign-later-handler]
|
||||
|
@ -88,31 +87,22 @@
|
|||
[components/button-text (i18n/label :t/transactions-sign-later)]]])
|
||||
[react/view components.styles/flex]
|
||||
[react/touchable-highlight {:style wallet.styles/button
|
||||
:on-press (when immediate-sign-enabled? #(re-frame/dispatch [:set-in [:wallet/send-transaction :signing?] true]))}
|
||||
:on-press (when immediate-sign-enabled? #(re-frame/dispatch [:wallet.send/set-signing? true]))}
|
||||
[react/view (wallet.styles/button-container immediate-sign-enabled?)
|
||||
[components/button-text (i18n/label :t/transactions-sign-transaction)]
|
||||
[vector-icons/icon :icons/forward {:color :white :container-style wallet.styles/forward-icon-container}]]]]))
|
||||
|
||||
(defn sufficient-funds? [amount-in-eth balance]
|
||||
(.greaterThanOrEqualTo balance (money/bignumber (money/to-wei amount-in-eth))))
|
||||
|
||||
(defn request-camera-permissions []
|
||||
(when platform/android?
|
||||
(re-frame/dispatch [:request-permissions [:camera]]))
|
||||
(camera/request-access
|
||||
(fn [permitted?]
|
||||
(re-frame/dispatch [:set-in [:wallet/send-transaction :camera-permitted?] permitted?])
|
||||
(re-frame/dispatch [:set-in [:wallet :send-transaction :camera-permitted?] permitted?])
|
||||
(re-frame/dispatch [:navigate-to :choose-recipient]))))
|
||||
|
||||
(defview send-transaction []
|
||||
(letsubs [balance [:balance]
|
||||
amount [:get-in [:wallet/send-transaction :amount]]
|
||||
amount-error [:get-in [:wallet/send-transaction :amount-error]]
|
||||
signing? [:get-in [:wallet/send-transaction :signing?]]
|
||||
to-address [:get-in [:wallet/send-transaction :to-address]]
|
||||
to-name [:get-in [:wallet/send-transaction :to-name]]
|
||||
in-progress? [:get-in [:wallet/send-transaction :in-progress?]]]
|
||||
(let [sufficient-funds? (or (nil? amount) (sufficient-funds? amount balance))]
|
||||
(letsubs [transaction [:wallet.send/transaction]]
|
||||
(let [{:keys [amount amount-error signing? to-address to-name in-progress? sufficient-funds?]} transaction]
|
||||
[react/keyboard-avoiding-view wallet.styles/wallet-modal-container
|
||||
[react/view components.styles/flex
|
||||
[status-bar/status-bar {:type :wallet}]
|
||||
|
@ -154,37 +144,34 @@
|
|||
[toolbar/content-title {:color :white} (i18n/label :t/send-transaction)]])
|
||||
|
||||
(defview send-transaction-modal []
|
||||
(letsubs [amount [:get-in [:wallet/send-transaction :amount]]
|
||||
amount-error [:get-in [:wallet/send-transaction :amount-error]]
|
||||
signing? [:get-in [:wallet/send-transaction :signing?]]
|
||||
to-address [:get-in [:wallet/send-transaction :to-address]]
|
||||
to-name [:get-in [:wallet/send-transaction :to-name]]
|
||||
recipient [:contact-by-address @to-name]
|
||||
in-progress? [:get-in [:wallet/send-transaction :in-progress?]]
|
||||
from-chat? [:get-in [:wallet/send-transaction :from-chat?]]]
|
||||
[react/keyboard-avoiding-view wallet.styles/wallet-modal-container
|
||||
[react/view components.styles/flex
|
||||
[status-bar/status-bar {:type :modal-wallet}]
|
||||
[toolbar-modal from-chat?]
|
||||
[common/network-info {:text-color :white}]
|
||||
[react/scroll-view {:keyboardShouldPersistTaps :always}
|
||||
(letsubs [transaction [:wallet.send/unsigned-transaction]]
|
||||
(let [{:keys [amount amount-error signing? to to-name sufficient-funds? in-progress? from-chat?]} transaction]
|
||||
[react/keyboard-avoiding-view wallet.styles/wallet-modal-container
|
||||
[react/view components.styles/flex
|
||||
[react/view wallet.styles/choose-participant-container
|
||||
[components/choose-recipient-disabled {:address to-address
|
||||
:name (:name recipient)}]]
|
||||
[react/view wallet.styles/choose-wallet-container
|
||||
[components/choose-wallet]]
|
||||
[react/view wallet.styles/amount-container
|
||||
[components/amount-input-disabled amount]
|
||||
[react/view wallet.styles/choose-currency-container
|
||||
[components/choose-currency wallet.styles/choose-currency]]]]]
|
||||
[components/separator]
|
||||
(if signing?
|
||||
[signing-buttons
|
||||
#(re-frame/dispatch [:wallet/cancel-signing-modal])
|
||||
#(re-frame/dispatch [:wallet/sign-transaction-modal])
|
||||
in-progress?]
|
||||
[sign-buttons amount-error to-address amount true #(re-frame/dispatch [:navigate-back])])
|
||||
(when signing?
|
||||
[sign-panel])]
|
||||
(when in-progress? [react/view send.styles/processing-view])]))
|
||||
[status-bar/status-bar {:type :modal-wallet}]
|
||||
[toolbar-modal from-chat?]
|
||||
[common/network-info {:text-color :white}]
|
||||
[react/scroll-view {:keyboardShouldPersistTaps :always}
|
||||
[react/view components.styles/flex
|
||||
[react/view wallet.styles/choose-participant-container
|
||||
[components/choose-recipient-disabled {:address to
|
||||
:name to-name}]]
|
||||
[react/view wallet.styles/choose-wallet-container
|
||||
[components/choose-wallet]]
|
||||
[react/view wallet.styles/amount-container
|
||||
[components/amount-input
|
||||
{:error (when-not sufficient-funds? (i18n/label :t/wallet-insufficient-funds))
|
||||
:disabled? true
|
||||
:input-options {:default-value amount}}]
|
||||
[react/view wallet.styles/choose-currency-container
|
||||
[components/choose-currency wallet.styles/choose-currency]]]]]
|
||||
[components/separator]
|
||||
(if signing?
|
||||
[signing-buttons
|
||||
#(re-frame/dispatch [:wallet/cancel-signing-modal])
|
||||
#(re-frame/dispatch [:wallet/sign-transaction-modal])
|
||||
in-progress?]
|
||||
[sign-buttons amount-error to amount sufficient-funds? #(re-frame/dispatch [:navigate-back])])
|
||||
(when signing?
|
||||
[sign-panel])
|
||||
(when in-progress? [react/view send.styles/processing-view])]])))
|
||||
|
|
|
@ -21,39 +21,35 @@
|
|||
|
||||
;;Handlers
|
||||
|
||||
;TRANSACTION QUEUED signal from status-go
|
||||
;;TRANSACTION QUEUED signal from status-go
|
||||
(handlers/register-handler-fx
|
||||
:transaction-queued
|
||||
[(re-frame/inject-cofx :now)]
|
||||
(fn [{{:wallet/keys [send-transaction] :as db} :db now :now} [_ {:keys [id message_id args] :as transaction}]]
|
||||
(fn [{:keys [db now]} [_ {:keys [id message_id args] :as transaction}]]
|
||||
(if (transaction-valid? transaction)
|
||||
(let [{:keys [from to value data gas gasPrice]} args]
|
||||
(let [;;TODO (andrey) revisit this map later (this map from old transactions, idk if we need all these fields)
|
||||
transaction {:id id
|
||||
:from from
|
||||
:to to
|
||||
:value (money/bignumber value)
|
||||
:data data
|
||||
:gas (money/to-decimal gas)
|
||||
:gas-price (money/to-decimal gasPrice)
|
||||
:timestamp now
|
||||
:message-id message_id}]
|
||||
(merge
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :transactions-unsigned id] transaction)
|
||||
(assoc-in [:wallet/send-transaction :transaction-id] id))}
|
||||
(if (:waiting-signal? send-transaction)
|
||||
;;sending from wallet
|
||||
{:dispatch [:wallet.send-transaction/transaction-queued id]}
|
||||
;;sending from chat
|
||||
{:dispatch [:navigate-to-modal :wallet-send-transaction-modal {:amount (str (money/wei->ether value))
|
||||
:transaction-id id
|
||||
:to-address to
|
||||
:to-name to
|
||||
:from-chat? true}]}))))
|
||||
(let [{:keys [from to value data gas gasPrice]} args
|
||||
;;TODO (andrey) revisit this map later (this map from old transactions, idk if we need all these fields)
|
||||
transaction {:id id
|
||||
:from from
|
||||
:to to
|
||||
:value (money/bignumber value)
|
||||
:data data
|
||||
:gas (money/to-decimal gas)
|
||||
:gas-price (money/to-decimal gasPrice)
|
||||
:timestamp now
|
||||
:message-id message_id}]
|
||||
(merge
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :transactions-unsigned id] transaction)
|
||||
(assoc-in [:wallet :send-transaction :id] id))}
|
||||
(if (get-in db [:wallet :send-transaction :waiting-signal?])
|
||||
;;sending from wallet
|
||||
{:dispatch [:wallet.send-transaction/transaction-queued id]}
|
||||
;;sending from chat
|
||||
{:dispatch [:navigate-to-modal :wallet-send-transaction-modal id :from-chat]})))
|
||||
{:discard-transaction id})))
|
||||
|
||||
;TRANSACTION FAILED signal from status-go
|
||||
;;TRANSACTION FAILED signal from status-go
|
||||
(handlers/register-handler-fx
|
||||
:transaction-failed
|
||||
(fn [{{:accounts/keys [accounts current-account-id] :as db} :db} [_ {:keys [id args message_id error_code error_message] :as event}]]
|
||||
|
@ -63,7 +59,7 @@
|
|||
|
||||
;;WRONG PASSWORD
|
||||
constants/send-transaction-password-error-code
|
||||
{:db (assoc-in db [:wallet/send-transaction :wrong-password?] true)}
|
||||
{:db (assoc-in db [:wallet :send-transaction :wrong-password?] true)}
|
||||
|
||||
;;TODO (andrey) something weird here below, revisit
|
||||
;;DISCARDED
|
||||
|
@ -73,6 +69,6 @@
|
|||
|
||||
;;NO ERROR, TIMEOUT or DEFAULT ERROR
|
||||
(merge
|
||||
{:db (update-in db [:wallet :transactions-unsigned] dissoc id)}
|
||||
(when (and message_id (= current-account-address transaction-initiator-address))
|
||||
{:dispatch [:set-chat-ui-props {:validation-messages error_message}]}))))))
|
||||
{:db (update-in db [:wallet :transactions-unsigned] dissoc id)}
|
||||
(when (and message_id (= current-account-address transaction-initiator-address))
|
||||
{:dispatch [:set-chat-ui-props {:validation-messages error_message}]}))))))
|
||||
|
|
|
@ -160,10 +160,3 @@
|
|||
(if (>= confirmations max-confirmations)
|
||||
100
|
||||
(* 100 (/ confirmations max-confirmations))))))
|
||||
|
||||
(reg-sub :contact-by-address
|
||||
:<- [:contacts/by-address]
|
||||
(fn [contacts [_ address]]
|
||||
(let [address' (when address
|
||||
(utils.hex/normalize-hex address))]
|
||||
(contacts address'))))
|
||||
|
|
|
@ -50,12 +50,7 @@
|
|||
(defn action-buttons [{:keys [id to value] :as transaction}]
|
||||
[react/view {:style transactions.styles/action-buttons}
|
||||
[button/primary-button {:style {:margin-right 12}
|
||||
:on-press #(re-frame/dispatch [:navigate-to-modal
|
||||
:wallet-send-transaction-modal
|
||||
{:amount (str (money/wei->ether value))
|
||||
:transaction-id id
|
||||
:to-address to
|
||||
:to-name to}])}
|
||||
:on-press #(re-frame/dispatch [:wallet/show-sign-transaction id])}
|
||||
(i18n/label :t/transactions-sign)]
|
||||
[button/secondary-button {:on-press #(on-delete-transaction transaction)}
|
||||
(i18n/label :t/delete)]])
|
||||
|
|
|
@ -85,3 +85,6 @@
|
|||
|
||||
(defn with-precision [n decimals]
|
||||
(.round (bignumber n) decimals))
|
||||
|
||||
(defn sufficient-funds? [amount-in-eth balance]
|
||||
(.greaterThanOrEqualTo balance (bignumber (to-wei amount-in-eth))))
|
||||
|
|
Loading…
Reference in New Issue