[#3958] implemented transactions queue

Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
Andrey Shovkoplyas 2018-05-01 14:24:17 +03:00
parent f73338b88e
commit dc4e1569cf
No known key found for this signature in database
GPG Key ID: EAAB7C8622D860A4
4 changed files with 103 additions and 93 deletions

View File

@ -10,7 +10,8 @@
(spec/def :wallet/send (spec/keys :req-un [:wallet.send/recipient])) (spec/def :wallet/send (spec/keys :req-un [:wallet.send/recipient]))
(spec/def :wallet/wallet (spec/keys :opt-un [:wallet/send-transaction :wallet/request-transaction])) (spec/def :wallet/wallet (spec/keys :opt-un [:wallet/send-transaction :wallet/request-transaction
:wallet/transactions-queue]))
;; Placeholder namespace for wallet specs, which are a WIP depending on data ;; Placeholder namespace for wallet specs, which are a WIP depending on data
;; model we decide on for balances, prices, etc. ;; model we decide on for balances, prices, etc.

View File

@ -104,69 +104,84 @@
(fn [_ _] (fn [_ _]
{::show-transaction-moved true})) {::show-transaction-moved true}))
(defn prepare-transaction [{:keys [id message_id args]} now]
;;NOTE(goranjovic): the transactions started from chat using /send command
;; are only in ether, so this parameter defaults to ETH
(let [{:keys [from to value symbol data gas gasPrice] :or {symbol :ETH}} args]
{:id id
:from from
:to to
:to-name (when (nil? to)
(i18n/label :t/new-contract))
:symbol symbol
:value (money/bignumber (or value 0))
:data data
:gas (when (seq gas)
(money/bignumber (money/to-decimal gas)))
:gas-price (when (seq gasPrice)
(money/bignumber (money/to-decimal gasPrice)))
:timestamp now
:message-id message_id}))
;;TRANSACTION QUEUED signal from status-go ;;TRANSACTION QUEUED signal from status-go
(handlers/register-handler-fx (handlers/register-handler-fx
:sign-request-queued :sign-request-queued
(fn [{:keys [db]} [_ transaction]]
{:db (update-in db [:wallet :transactions-queue] conj transaction)
:dispatch [:check-transactions-queue]}))
(handlers/register-handler-fx
:check-transactions-queue
[(re-frame/inject-cofx :now)] [(re-frame/inject-cofx :now)]
(fn [{:keys [db now]} [_ {:keys [id message_id method args]}]] (fn [{:keys [db now]} _]
(cond (let [{:keys [send-transaction transactions-queue]} (:wallet db)
{:keys [id method args] :as queued-transaction} (last transactions-queue)
db' (update-in db [:wallet :transactions-queue] drop-last)]
(when (and (not (:id send-transaction)) queued-transaction)
(cond
;;SEND TRANSACTION
(= method constants/web3-send-transaction)
(= method constants/web3-send-transaction) (let [{:keys [gas gasPrice]} args
;;NOTE(goranjovic): the transactions started from chat using /send command transaction (prepare-transaction queued-transaction now)
;; are only in ether, so this parameter defaults to ETH sending-from-bot-or-dapp? (not (get-in db [:wallet :send-transaction :waiting-signal?]))
(let [{:keys [from to value symbol data gas gasPrice] :or {symbol :ETH}} args new-db (assoc-in db' [:wallet :transactions-unsigned id] transaction)
;;TODO (andrey) revisit this map later (this map from old transactions, idk if we need all these fields) sending-db {:id id
transaction {:id id :method method
:from from :from-chat? sending-from-bot-or-dapp?}]
:to to (if sending-from-bot-or-dapp?
:to-name (when (nil? to) ;;SENDING FROM BOT (CHAT) OR DAPP
(i18n/label :t/new-contract)) {:db (assoc-in new-db [:wallet :send-transaction] sending-db) ; we need to completely reset sending state here
:symbol symbol :dispatch-n [[:update-wallet]
:value (money/bignumber (or value 0)) [:navigate-to-modal :wallet-send-transaction-modal]
:data data (when-not (seq gas)
:gas (when (seq gas) [:wallet/update-estimated-gas transaction])
(money/bignumber (money/to-decimal gas))) (when-not (seq gasPrice)
:gas-price (when (seq gasPrice) [:wallet/update-gas-price])]}
(money/bignumber (money/to-decimal gasPrice))) ;;WALLET SEND SCREEN WAITING SIGNAL
:timestamp now (let [{:keys [later? password]} (get-in db [:wallet :send-transaction])
:message-id message_id} new-db' (update-in new-db [:wallet :send-transaction] merge sending-db)] ; just update sending state as we are in wallet flow
sending-from-bot-or-dapp? (not (get-in db [:wallet :send-transaction :waiting-signal?])) (if later?
new-db (assoc-in db [:wallet :transactions-unsigned id] transaction) ;;SIGN LATER
sending-db {:id id {:db (assoc-in new-db' [:wallet :send-transaction :waiting-signal?] false)
:method method :dispatch [:navigate-back]
:from-chat? sending-from-bot-or-dapp?}] ::show-transaction-moved false}
(if sending-from-bot-or-dapp? ;;SIGN NOW
;;SENDING FROM BOT (CHAT) OR DAPP {:db new-db'
{:db (assoc-in new-db [:wallet :send-transaction] sending-db) ; we need to completely reset sending state here ::accept-transaction {:id id
:dispatch-n [[:update-wallet] :password password
[:navigate-to-modal :wallet-send-transaction-modal] :on-completed on-transactions-completed}}))))
(when-not (seq gas) ;;SIGN MESSAGE
[:wallet/update-estimated-gas transaction]) (= method constants/web3-personal-sign)
(when-not (seq gasPrice)
[:wallet/update-gas-price])]}
;;WALLET SEND SCREEN WAITING SIGNAL
(let [{:keys [later? password]} (get-in db [:wallet :send-transaction])
new-db' (update-in new-db [:wallet :send-transaction] merge sending-db)] ; just update sending state as we are in wallet flow
(if later?
;;SIGN LATER
{:db (assoc-in new-db' [:wallet :send-transaction :waiting-signal?] false)
:dispatch [:navigate-back]
::show-transaction-moved false}
;;SIGN NOW
{:db new-db'
::accept-transaction {:id id
:password password
:on-completed on-transactions-completed}}))))
(= method constants/web3-personal-sign) (let [{:keys [data]} args
data' (transport.utils/to-utf8 data)]
(let [{:keys [data]} args (if data'
data' (transport.utils/to-utf8 data)] {:db (-> db'
(when data' (assoc-in [:wallet :transactions-unsigned id] {:data data' :id id})
{:db (-> db (assoc-in [:wallet :send-transaction] {:id id :method method}))
(assoc-in [:wallet :transactions-unsigned id] {:data data' :id id}) :dispatch [:navigate-to-modal :wallet-sign-message-modal]}
(assoc-in [:wallet :send-transaction] {:id id :method method})) {:db db'})))))))
:dispatch [:navigate-to-modal :wallet-sign-message-modal]})))))
(defn this-transaction-signing? [id signing-id view-id modal] (defn this-transaction-signing? [id signing-id view-id modal]
(and (= signing-id id) (and (= signing-id id)
@ -188,6 +203,7 @@
;;NO ERROR, DISCARDED, TIMEOUT or DEFAULT ERROR ;;NO ERROR, DISCARDED, TIMEOUT or DEFAULT ERROR
(if (this-transaction-signing? id (:id send-transaction) view-id modal) (if (this-transaction-signing? id (:id send-transaction) view-id modal)
(cond-> {:db (-> db (cond-> {:db (-> db
(assoc-in [:wallet :transactions-queue] nil)
(update-in [:wallet :transactions-unsigned] dissoc id) (update-in [:wallet :transactions-unsigned] dissoc id)
(update-in [:wallet :send-transaction] merge clear-send-properties)) (update-in [:wallet :send-transaction] merge clear-send-properties))
:dispatch [:navigate-back]} :dispatch [:navigate-back]}
@ -333,3 +349,11 @@
:db (update-in db [:wallet :edit] :db (update-in db [:wallet :edit]
assoc assoc
:gas (ethereum/estimate-gas (get-in db [:wallet :send-transaction :symbol])))})) :gas (ethereum/estimate-gas (get-in db [:wallet :send-transaction :symbol])))}))
(handlers/register-handler-fx
:close-transaction-sent-screen
(fn [{:keys [db]} _]
{:dispatch (if (= :wallet-send-transaction (second (:navigation-stack db)))
[:navigate-to-clean :wallet]
[:navigate-back])
:dispatch-later [{:ms 400 :dispatch [:check-transactions-queue]}]}))

View File

@ -3,13 +3,6 @@
[status-im.utils.money :as money] [status-im.utils.money :as money]
[status-im.utils.hex :as utils.hex])) [status-im.utils.hex :as utils.hex]))
(re-frame/reg-sub :wallet.sent/close-transaction-screen-event
:<- [:get :navigation-stack]
(fn [navigation-stack]
(case (second navigation-stack)
:wallet-send-transaction [:navigate-to-clean :wallet]
[:navigate-back])))
(re-frame/reg-sub ::send-transaction (re-frame/reg-sub ::send-transaction
:<- [:wallet] :<- [:wallet]
(fn [wallet] (fn [wallet]

View File

@ -12,34 +12,26 @@
[status-im.utils.platform :as platform])) [status-im.utils.platform :as platform]))
(defview transaction-sent [& [modal?]] (defview transaction-sent [& [modal?]]
(letsubs [close-transaction-screen-event [:wallet.sent/close-transaction-screen-event]] [react/view wallet.styles/wallet-modal-container
[react/view wallet.styles/wallet-modal-container [status-bar/status-bar {:type (if modal? :modal-wallet :transparent)}]
[status-bar/status-bar {:type (if modal? :modal-wallet :transparent)}] [react/view styles/transaction-sent-container
[react/view styles/transaction-sent-container [react/view styles/ok-icon-container
[react/view styles/ok-icon-container [vi/icon :icons/ok {:color components.styles/color-blue4}]]
[vi/icon :icons/ok {:color components.styles/color-blue4}]] [react/text {:style styles/transaction-sent
[react/text {:style styles/transaction-sent :font (if platform/android? :medium :default)
:font (if platform/android? :medium :default) :accessibility-label :transaction-sent-text}
:accessibility-label :transaction-sent-text} (i18n/label :t/transaction-sent)]
(i18n/label :t/transaction-sent)] [react/view styles/gap]
[react/view styles/gap] [react/text {:style styles/transaction-sent-description} (i18n/label :t/transaction-description)]]
[react/text {:style styles/transaction-sent-description} (i18n/label :t/transaction-description)]] [react/view components.styles/flex]
[react/view components.styles/flex] [components/separator]
;; TODO (andrey) uncomment when will be implemented [react/touchable-highlight {:on-press #(re-frame/dispatch [:close-transaction-sent-screen])
#_[react/touchable-highlight {:on-press #()}; TODO (andrey) #(re-frame/dispatch [:navigate-to-clean :wallet-transaction-details])} :accessibility-label :got-it-button}
[react/view styles/transaction-details-container [react/view styles/got-it-container
[react/text {:style styles/transaction-details [react/text {:style styles/got-it
:font (if platform/android? :medium :default) :font (if platform/android? :medium :default)
:uppercase? true} :uppercase? true}
(i18n/label :t/view-transaction-details)]]] (i18n/label :t/got-it)]]]])
[components/separator]
[react/touchable-highlight {:on-press #(re-frame/dispatch close-transaction-screen-event)
:accessibility-label :got-it-button}
[react/view styles/got-it-container
[react/text {:style styles/got-it
:font (if platform/android? :medium :default)
:uppercase? true}
(i18n/label :t/got-it)]]]]))
(defview transaction-sent-modal [] (defview transaction-sent-modal []
[transaction-sent true]) [transaction-sent true])