Fetch transactions state from etherscan every 15 seconds if there are any unconfirmed transactions Signed-off-by: Dmitry Novotochinov <dmitry.novot@gmail.com>
This commit is contained in:
parent
0e502ac5b8
commit
2d6fdc0ecc
|
@ -6,7 +6,8 @@
|
|||
[status-im.constants :as constants]
|
||||
[status-im.utils.clocks :as utils.clocks]
|
||||
[status-im.utils.handlers :as handlers]
|
||||
[status-im.utils.handlers-macro :as handlers-macro]))
|
||||
[status-im.utils.handlers-macro :as handlers-macro]
|
||||
[status-im.wallet.transactions :as wallet.transactions]))
|
||||
|
||||
;;;; Handlers
|
||||
|
||||
|
@ -46,7 +47,7 @@
|
|||
(let [{:keys [command params]} content
|
||||
tx-hash (:tx-hash params)]
|
||||
(handlers-macro/merge-fx cofx
|
||||
(message-model/update-transactions command tx-hash {:with-delay? true})
|
||||
(wallet.transactions/store-chat-transaction-hash tx-hash)
|
||||
(request-command-message-data message)))
|
||||
;; regular non command message, we can add it right away
|
||||
(message-model/receive message cofx))))
|
||||
|
|
|
@ -433,16 +433,6 @@
|
|||
:show? true}
|
||||
chat)))
|
||||
|
||||
;; dispatch :update-transactions to update confirmations count
|
||||
;; to verify tx initiated with /send command is confirmed
|
||||
(defn update-transactions [command-name tx-hash {:keys [with-delay?]} _]
|
||||
(when (and tx-hash
|
||||
(= command-name constants/command-send))
|
||||
(cond-> {:dispatch [:update-transactions]}
|
||||
with-delay?
|
||||
(assoc :dispatch-later [{:ms constants/command-send-status-update-interval-ms
|
||||
:dispatch [:update-transactions]}]))))
|
||||
|
||||
(defn send-command
|
||||
[{{:keys [current-public-key chats chain prices] :as db} :db :keys [now] :as cofx} params]
|
||||
(let [{{:keys [handler-data to-message command] :as content} :command chat-id :chat-id} params
|
||||
|
@ -456,8 +446,7 @@
|
|||
(upsert-and-send (prepare-command-message current-public-key chat now request content
|
||||
chain currency prices tx-hash))
|
||||
(console-events/console-respond-command-messages command handler-data)
|
||||
(requests-events/request-answered chat-id to-message)
|
||||
(update-transactions command-name tx-hash {:with-delay? false}))))
|
||||
(requests-events/request-answered chat-id to-message))))
|
||||
|
||||
(defn invoke-console-command-handler
|
||||
[{:keys [db] :as cofx} {:keys [command] :as command-params}]
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
[status-im.utils.platform :as platform]
|
||||
[status-im.utils.gfycat.core :as gfycat]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.constants :as const]))
|
||||
[status-im.constants :as const]
|
||||
[status-im.wallet.transactions :as transactions]))
|
||||
|
||||
(reg-sub :get-chats :chats)
|
||||
|
||||
|
@ -405,7 +406,7 @@
|
|||
(fn [db [_ tx-hash]]
|
||||
(-> (get-in db [:wallet :transactions tx-hash :confirmations] "0")
|
||||
(js/parseInt)
|
||||
(pos?))))
|
||||
(>= transactions/confirmations-count-threshold))))
|
||||
|
||||
(reg-sub
|
||||
:wallet-transaction-exists?
|
||||
|
|
|
@ -60,7 +60,6 @@
|
|||
(letsubs [confirmed? [:transaction-confirmed? tx-hash]
|
||||
tx-exists? [:wallet-transaction-exists? tx-hash]]
|
||||
[react/touchable-highlight {:on-press #(when tx-exists?
|
||||
(re-frame/dispatch [:update-transactions])
|
||||
(re-frame/dispatch [:show-transaction-details tx-hash]))}
|
||||
[react/view style/command-send-status-container
|
||||
[vector-icons/icon (if confirmed? :icons/check :icons/dots)
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
:discover-current-dapp {}
|
||||
:tags []
|
||||
:sync-state :done
|
||||
:app-state "active"
|
||||
:wallet.transactions constants/default-wallet-transactions
|
||||
:wallet-selected-asset {}
|
||||
:prices {}
|
||||
|
@ -77,6 +78,8 @@
|
|||
|
||||
(spec/def ::mailserver-status (spec/nilable keyword?))
|
||||
|
||||
(spec/def ::app-state string?)
|
||||
|
||||
;;;;NODE
|
||||
|
||||
(spec/def ::sync-listening-started (spec/nilable boolean?))
|
||||
|
@ -231,6 +234,7 @@
|
|||
::sync-data
|
||||
::network
|
||||
::chain
|
||||
::app-state
|
||||
:navigation/view-id
|
||||
:navigation/navigation-stack
|
||||
:navigation/prev-tab-view-id
|
||||
|
|
|
@ -377,6 +377,7 @@
|
|||
[:process-pending-messages]
|
||||
[:update-wallet]
|
||||
[:update-transactions]
|
||||
[:sync-wallet-transactions]
|
||||
[:get-fcm-token]
|
||||
[:update-sign-in-time]]
|
||||
(seq events-after) (into events-after))}))
|
||||
|
@ -489,10 +490,11 @@
|
|||
|
||||
(handlers/register-handler-fx
|
||||
:app-state-change
|
||||
(fn [{{:keys [network-status mailserver-status]} :db :as cofx} [_ state]]
|
||||
(fn [{:keys [db] :as cofx} [_ state]]
|
||||
(let [app-coming-from-background? (= state "active")]
|
||||
(handlers-macro/merge-fx cofx
|
||||
{::app-state-change-fx state}
|
||||
{::app-state-change-fx state
|
||||
:db (assoc db :app-state state)}
|
||||
(inbox/request-messages app-coming-from-background?)))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
status-im.ui.screens.wallet.request.events
|
||||
[status-im.constants :as constants]
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
[status-im.utils.money :as money]))
|
||||
[status-im.utils.money :as money]
|
||||
[status-im.wallet.transactions :as wallet.transactions]))
|
||||
|
||||
(defn get-balance [{:keys [web3 account-id on-success on-error]}]
|
||||
(if (and web3 account-id)
|
||||
|
@ -141,22 +142,8 @@
|
|||
|
||||
(handlers/register-handler-fx
|
||||
:update-transactions
|
||||
(fn [{{:keys [network network-status web3] :as db} :db} _]
|
||||
(when-not (= network-status :offline)
|
||||
(let [network (get-in db [:account/account :networks network])
|
||||
chain (ethereum/network->chain-keyword network)]
|
||||
(when-not (= :custom chain)
|
||||
(let [all-tokens (tokens/tokens-for chain)
|
||||
token-addresses (map :address all-tokens)]
|
||||
{:get-transactions {:account-id (get-in db [:account/account :address])
|
||||
:token-addresses token-addresses
|
||||
:chain chain
|
||||
:web3 web3
|
||||
:success-event :update-transactions-success
|
||||
:error-event :update-transactions-fail}
|
||||
:db (-> db
|
||||
(clear-error-message :transactions-update)
|
||||
(assoc-in [:wallet :transactions-loading?] true))}))))))
|
||||
(fn [cofx _]
|
||||
(wallet.transactions/run-update cofx)))
|
||||
|
||||
(defn combine-entries [transaction token-transfer]
|
||||
(merge transaction (select-keys token-transfer [:symbol :from :to :value :type :token :transfer])))
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
[status-im.constants :as constants]
|
||||
[status-im.transport.utils :as transport.utils]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.ui.screens.navigation :as navigation]))
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
[status-im.wallet.transactions :as wallet.transactions]))
|
||||
|
||||
;;;; FX
|
||||
|
||||
|
@ -467,3 +468,10 @@
|
|||
(fn [{:keys [db]} [_ chat-id]]
|
||||
{:dispatch [:navigate-back]
|
||||
:dispatch-later [{:ms 400 :dispatch [:check-transactions-queue]}]}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:sync-wallet-transactions
|
||||
(fn [cofx _]
|
||||
(handlers-macro/merge-fx cofx
|
||||
(wallet.transactions/load-missing-chat-transactions)
|
||||
(wallet.transactions/sync))))
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(ns status-im.utils.transactions
|
||||
(:require [status-im.utils.http :as http]
|
||||
[status-im.utils.types :as types]))
|
||||
[status-im.utils.types :as types]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn- get-network-subdomain [chain]
|
||||
(case chain
|
||||
|
@ -55,6 +56,8 @@
|
|||
{})))
|
||||
|
||||
(defn get-transactions [chain account on-success on-error]
|
||||
(http/get (get-transaction-url chain account)
|
||||
(let [url (get-transaction-url chain account)]
|
||||
(log/debug "HTTP GET" url)
|
||||
(http/get url
|
||||
#(on-success (format-transactions-response % account))
|
||||
on-error))
|
||||
on-error)))
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
(ns status-im.wallet.transactions
|
||||
(:require [clojure.set :as set]
|
||||
[status-im.utils.datetime :as time]
|
||||
[status-im.utils.ethereum.tokens :as tokens]
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
[status-im.utils.handlers-macro :as handlers-macro]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def sync-interval-ms 15000)
|
||||
(def confirmations-count-threshold 12)
|
||||
|
||||
;; Detects if some of the transactions have less than 12 confirmations
|
||||
(defn- have-unconfirmed-transactions? [cofx]
|
||||
(->> (get-in cofx [:db :wallet :transactions])
|
||||
vals
|
||||
(map :confirmations)
|
||||
(map int)
|
||||
(some #(< % confirmations-count-threshold))))
|
||||
|
||||
(defn- wallet-transactions-set [db]
|
||||
(-> db
|
||||
(get-in [:wallet :transactions])
|
||||
keys
|
||||
set))
|
||||
|
||||
;; Detects if some of missing chat transactions are missing from wallet
|
||||
(defn- have-missing-chat-transactions? [{:keys [db]}]
|
||||
(let [chat-transactions (get-in db [:wallet :chat-transactions])]
|
||||
(not= (count chat-transactions)
|
||||
(count (set/intersection
|
||||
chat-transactions
|
||||
(wallet-transactions-set db))))))
|
||||
|
||||
(defn- schedule-sync [cofx]
|
||||
{:utils/dispatch-later [{:ms sync-interval-ms
|
||||
:dispatch [:sync-wallet-transactions]}]})
|
||||
|
||||
(defn store-chat-transaction-hash [tx-hash {:keys [db]}]
|
||||
{:db (update-in db [:wallet :chat-transactions] conj tx-hash)})
|
||||
|
||||
(defn- missing-chat-transactions [{:keys [db] :as cofx}]
|
||||
(let [chat-transactions (->> db
|
||||
:chats
|
||||
vals
|
||||
(remove :public?)
|
||||
(mapcat :messages)
|
||||
vals
|
||||
flatten
|
||||
(filter #(= "command" (:content-type %)))
|
||||
(map #(get-in % [:content :params :tx-hash]))
|
||||
(filter identity)
|
||||
set)]
|
||||
(set/difference
|
||||
chat-transactions
|
||||
(wallet-transactions-set db))))
|
||||
|
||||
; Find missing chat transactions
|
||||
; and store them at [:wallet :chat-transactions]
|
||||
; to be used later by have-missing-chat-transactions? on every sync request
|
||||
(defn load-missing-chat-transactions [{:keys [db] :as cofx}]
|
||||
(when (nil? (get-in db [:wallet :chat-transactions]))
|
||||
{:db (assoc-in db
|
||||
[:wallet :chat-transactions]
|
||||
(missing-chat-transactions cofx))}))
|
||||
|
||||
(defn run-update [{{:keys [network network-status web3] :as db} :db}]
|
||||
(when (not= network-status :offline)
|
||||
(let [network (get-in db [:account/account :networks network])
|
||||
chain (ethereum/network->chain-keyword network)]
|
||||
(when-not (= :custom chain)
|
||||
(let [all-tokens (tokens/tokens-for chain)
|
||||
token-addresses (map :address all-tokens)]
|
||||
(log/debug "Syncing transactions data..")
|
||||
{:get-transactions {:account-id (get-in db [:account/account :address])
|
||||
:token-addresses token-addresses
|
||||
:chain chain
|
||||
:web3 web3
|
||||
:success-event :update-transactions-success
|
||||
:error-event :update-transactions-fail}
|
||||
:db (-> db
|
||||
(update-in [:wallet :errors] dissoc :transactions-update)
|
||||
(assoc-in [:wallet :transactions-loading?] true)
|
||||
(assoc-in [:wallet :transactions-last-updated-at] (time/timestamp)))})))))
|
||||
|
||||
(defn- time-to-sync? [cofx]
|
||||
(let [last-updated-at (get-in cofx [:db :wallet :transactions-last-updated-at])]
|
||||
(or (nil? last-updated-at)
|
||||
(< sync-interval-ms
|
||||
(- (time/timestamp) last-updated-at)))))
|
||||
|
||||
; Fetch updated data for any unconfirmed transactions or incoming chat transactions missing in wallet
|
||||
; and schedule new recurring sync request
|
||||
(defn sync [{:keys [db] :as cofx}]
|
||||
(let [in-progress? (get-in db [:wallet :transactions-loading?])
|
||||
{:keys [app-state network-status]} db]
|
||||
(if (and (not= network-status :offline)
|
||||
(= app-state "active")
|
||||
(not in-progress?)
|
||||
(time-to-sync? cofx)
|
||||
(or (have-unconfirmed-transactions? cofx)
|
||||
(have-missing-chat-transactions? cofx)))
|
||||
(handlers-macro/merge-fx cofx
|
||||
(run-update)
|
||||
(schedule-sync))
|
||||
(schedule-sync cofx))))
|
|
@ -0,0 +1,138 @@
|
|||
(ns status-im.test.wallet.transactions
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.utils.datetime :as time]
|
||||
[status-im.wallet.transactions :as wallet.transactions]))
|
||||
|
||||
(deftest test-store-chat-transaction-hash
|
||||
(is (= (wallet.transactions/store-chat-transaction-hash "0x318f566edd98eb29965067d3394c555050bf9f8e20183792c7f1a6bbc1bb34db"
|
||||
{:db {:wallet {:chat-transactions #{"0x0873923e4d8b39ccfeb8c1af9701a9da02fdc76947a48de7c5df1540f77fdc5b"}}}})
|
||||
{:db {:wallet {:chat-transactions #{"0x0873923e4d8b39ccfeb8c1af9701a9da02fdc76947a48de7c5df1540f77fdc5b" "0x318f566edd98eb29965067d3394c555050bf9f8e20183792c7f1a6bbc1bb34db"}}}})))
|
||||
|
||||
(deftest test-load-missing-chat-transactions
|
||||
(is (= (wallet.transactions/load-missing-chat-transactions {:db {:wallet {:transactions {"0x318f566edd98eb29965067d3394c555050bf9f8e20183792c7f1a6bbc1bb34db"
|
||||
{:confirmations "15"}}}
|
||||
:chats {"0x0462203ba96495c4caed83b46b01fe9b8f27af300f46cc944c6c47141969337ecfc4566dd5910323763816d350d3256a3d8f2f2a6536cfa120733aeea2efb11860"
|
||||
{:messages {"0xfc6e31d35f5a722b8aa185c8c7d1cd798e546e8dcd97adcc8305ca1a3c044f0d"
|
||||
{:content-type "command"
|
||||
:content {:params {:tx-hash "0x0873923e4d8b39ccfeb8c1af9701a9da02fdc76947a48de7c5df1540f77fdc5b"}}}}}
|
||||
"0x04d9bbe8e00318a70108980b45ba45c91cd406cdd7ffeb043be0ce4ec026fed3854515345b4bbce4c1694cc99240ee5fda93101ca861c3ceef548dedb5ec2a983a"
|
||||
{:messages {"0x1f8a9472997b58435a43776ec5a89a12e42891f71064fd890ef3d87dda41fabf"
|
||||
{:content-type "command"
|
||||
:content {:params {:tx-hash "0x318f566edd98eb29965067d3394c555050bf9f8e20183792c7f1a6bbc1bb34db"}}}}}}}})
|
||||
|
||||
{:db {:wallet {:transactions {"0x318f566edd98eb29965067d3394c555050bf9f8e20183792c7f1a6bbc1bb34db"
|
||||
{:confirmations "15"}}
|
||||
:chat-transactions #{"0x0873923e4d8b39ccfeb8c1af9701a9da02fdc76947a48de7c5df1540f77fdc5b"}}
|
||||
:chats {"0x0462203ba96495c4caed83b46b01fe9b8f27af300f46cc944c6c47141969337ecfc4566dd5910323763816d350d3256a3d8f2f2a6536cfa120733aeea2efb11860"
|
||||
{:messages {"0xfc6e31d35f5a722b8aa185c8c7d1cd798e546e8dcd97adcc8305ca1a3c044f0d"
|
||||
{:content-type "command"
|
||||
:content {:params {:tx-hash "0x0873923e4d8b39ccfeb8c1af9701a9da02fdc76947a48de7c5df1540f77fdc5b"}}}}}
|
||||
"0x04d9bbe8e00318a70108980b45ba45c91cd406cdd7ffeb043be0ce4ec026fed3854515345b4bbce4c1694cc99240ee5fda93101ca861c3ceef548dedb5ec2a983a"
|
||||
{:messages {"0x1f8a9472997b58435a43776ec5a89a12e42891f71064fd890ef3d87dda41fabf"
|
||||
{:content-type "command"
|
||||
:content {:params {:tx-hash "0x318f566edd98eb29965067d3394c555050bf9f8e20183792c7f1a6bbc1bb34db"}}}}}}}})))
|
||||
|
||||
(deftest test-sync
|
||||
(with-redefs [time/timestamp (constantly 1531734120829)]
|
||||
(testing "update in progress"
|
||||
(is (= (wallet.transactions/sync {:db {:app-state "active"
|
||||
:network-status :online
|
||||
:wallet {:transactions {"0x59bd7cca850671c6bd2b6f2f75e001d8b7a1a254f0ba4a5660041ba7c2f19295"
|
||||
{:confirmations "0"}}
|
||||
:transactions-loading? true}}})
|
||||
{:utils/dispatch-later [{:ms wallet.transactions/sync-interval-ms
|
||||
:dispatch [:sync-wallet-transactions]}]})))
|
||||
(testing "app is offline"
|
||||
(is (= (wallet.transactions/sync {:db {:app-state "active"
|
||||
:network-status :offline
|
||||
:wallet {:transactions {"0x59bd7cca850671c6bd2b6f2f75e001d8b7a1a254f0ba4a5660041ba7c2f19295"
|
||||
{:confirmations "0"}}}}})
|
||||
{:utils/dispatch-later [{:ms wallet.transactions/sync-interval-ms
|
||||
:dispatch [:sync-wallet-transactions]}]})))
|
||||
(testing "app is in background"
|
||||
(is (= (wallet.transactions/sync {:db {:app-state "background"
|
||||
:network-status :online
|
||||
:wallet {:transactions {"0x59bd7cca850671c6bd2b6f2f75e001d8b7a1a254f0ba4a5660041ba7c2f19295"
|
||||
{:confirmations "0"}}}}})
|
||||
{:utils/dispatch-later [{:ms wallet.transactions/sync-interval-ms
|
||||
:dispatch [:sync-wallet-transactions]}]})))
|
||||
(testing "last request was made recently"
|
||||
(is (= (wallet.transactions/sync {:db {:app-state "active"
|
||||
:network-status :online
|
||||
:wallet {:transactions {"0x59bd7cca850671c6bd2b6f2f75e001d8b7a1a254f0ba4a5660041ba7c2f19295"
|
||||
{:confirmations "10"}}
|
||||
:transactions-last-updated-at 1531734119729
|
||||
:transactions-loading? false}}})
|
||||
{:utils/dispatch-later [{:ms wallet.transactions/sync-interval-ms
|
||||
:dispatch [:sync-wallet-transactions]}]})))
|
||||
(testing "transaction has 0 confirmations"
|
||||
(is (= (wallet.transactions/sync {:db {:app-state "active"
|
||||
:network-status :online
|
||||
:wallet {:transactions {"0x59bd7cca850671c6bd2b6f2f75e001d8b7a1a254f0ba4a5660041ba7c2f19295"
|
||||
{:confirmations "0"}}
|
||||
:transactions-loading? false}}})
|
||||
{:get-transactions {:account-id nil
|
||||
:token-addresses (),
|
||||
:chain nil
|
||||
:web3 nil
|
||||
:success-event :update-transactions-success
|
||||
:error-event :update-transactions-fail}
|
||||
:db {:app-state "active"
|
||||
:network-status :online
|
||||
:wallet {:transactions {"0x59bd7cca850671c6bd2b6f2f75e001d8b7a1a254f0ba4a5660041ba7c2f19295"
|
||||
{:confirmations "0"}}
|
||||
:transactions-loading? true
|
||||
:transactions-last-updated-at 1531734120829
|
||||
:errors nil}}
|
||||
:utils/dispatch-later [{:ms wallet.transactions/sync-interval-ms
|
||||
:dispatch [:sync-wallet-transactions]}]})))
|
||||
(testing "transaction has 10 confirmations"
|
||||
(is (= (wallet.transactions/sync {:db {:app-state "active"
|
||||
:network-status :online
|
||||
:wallet {:transactions {"0x59bd7cca850671c6bd2b6f2f75e001d8b7a1a254f0ba4a5660041ba7c2f19295"
|
||||
{:confirmations "10"}}
|
||||
:transactions-loading? false}}})
|
||||
{:get-transactions {:account-id nil
|
||||
:token-addresses (),
|
||||
:chain nil
|
||||
:web3 nil
|
||||
:success-event :update-transactions-success
|
||||
:error-event :update-transactions-fail}
|
||||
:db {:app-state "active"
|
||||
:network-status :online
|
||||
:wallet {:transactions {"0x59bd7cca850671c6bd2b6f2f75e001d8b7a1a254f0ba4a5660041ba7c2f19295"
|
||||
{:confirmations "10"}}
|
||||
:transactions-loading? true
|
||||
:transactions-last-updated-at 1531734120829
|
||||
:errors nil}}
|
||||
:utils/dispatch-later [{:ms wallet.transactions/sync-interval-ms
|
||||
:dispatch [:sync-wallet-transactions]}]})))
|
||||
(testing "chat transaction is missing from wallet transactions"
|
||||
(is (= (wallet.transactions/sync {:db {:app-state "active"
|
||||
:network-status :online
|
||||
:wallet {:transactions {"0x59bd7cca850671c6bd2b6f2f75e001d8b7a1a254f0ba4a5660041ba7c2f19295"
|
||||
{:confirmations "15"}
|
||||
"0x318f566edd98eb29965067d3394c555050bf9f8e20183792c7f1a6bbc1bb34db"
|
||||
{:confirmations "20"}}
|
||||
:chat-transactions #{"0x0873923e4d8b39ccfeb8c1af9701a9da02fdc76947a48de7c5df1540f77fdc5b"
|
||||
"0x318f566edd98eb29965067d3394c555050bf9f8e20183792c7f1a6bbc1bb34db"}
|
||||
:transactions-loading? false}}})
|
||||
{:get-transactions {:account-id nil
|
||||
:token-addresses (),
|
||||
:chain nil
|
||||
:web3 nil
|
||||
:success-event :update-transactions-success
|
||||
:error-event :update-transactions-fail}
|
||||
:db {:app-state "active"
|
||||
:network-status :online
|
||||
:wallet {:transactions {"0x59bd7cca850671c6bd2b6f2f75e001d8b7a1a254f0ba4a5660041ba7c2f19295"
|
||||
{:confirmations "15"}
|
||||
"0x318f566edd98eb29965067d3394c555050bf9f8e20183792c7f1a6bbc1bb34db"
|
||||
{:confirmations "20"}}
|
||||
:chat-transactions #{"0x0873923e4d8b39ccfeb8c1af9701a9da02fdc76947a48de7c5df1540f77fdc5b"
|
||||
"0x318f566edd98eb29965067d3394c555050bf9f8e20183792c7f1a6bbc1bb34db"}
|
||||
:transactions-loading? true
|
||||
:transactions-last-updated-at 1531734120829
|
||||
:errors nil}}
|
||||
:utils/dispatch-later [{:ms wallet.transactions/sync-interval-ms
|
||||
:dispatch [:sync-wallet-transactions]}]})))))
|
Loading…
Reference in New Issue