From f5c18ae7a9cf395fbdbcd83c425ca0c58f780b5e Mon Sep 17 00:00:00 2001 From: yenda Date: Thu, 9 May 2019 21:51:41 +0200 Subject: [PATCH] [feature] use subscriptions for tokens - removes fetching of last 100000 blocks of token transfers from the wallet pull loop - fetches the last 100000 blocks of token transfers at startup - replaces pulling by subscriptions to ethlogs for token transfers --- STATUS_GO_SHA256 | 2 +- STATUS_GO_VERSION | 2 +- src/status_im/accounts/login/core.cljs | 2 +- src/status_im/accounts/logout/core.cljs | 10 +- src/status_im/ethereum/subscriptions.cljs | 203 ++++++++++++++++-- .../transactions/core.cljs} | 186 +--------------- src/status_im/events.cljs | 30 +-- src/status_im/init/core.cljs | 25 +-- src/status_im/signals/core.cljs | 1 + src/status_im/subs.cljs | 2 +- src/status_im/ui/screens/wallet/events.cljs | 12 +- .../ui/screens/wallet/send/events.cljs | 9 +- test/cljs/status_im/test/sign_in/flow.cljs | 8 +- .../status_im/test/wallet/transactions.cljs | 23 +- 14 files changed, 249 insertions(+), 266 deletions(-) rename src/status_im/{models/transactions.cljs => ethereum/transactions/core.cljs} (54%) diff --git a/STATUS_GO_SHA256 b/STATUS_GO_SHA256 index 8f0d9840a8..9484c62978 100644 --- a/STATUS_GO_SHA256 +++ b/STATUS_GO_SHA256 @@ -1,3 +1,3 @@ ## DO NOT EDIT THIS FILE BY HAND. USE `scripts/update-status-go.sh ` instead -0cj202bj2rwfrw327gibj8hj8i94ciyp3hkq2hck9l6711qlhpnb +0049i6znvl45hc651bqyzwgmzlv0fp40maggfjsrv13q5avd0g6d diff --git a/STATUS_GO_VERSION b/STATUS_GO_VERSION index 0f57894068..6162c3d599 100644 --- a/STATUS_GO_VERSION +++ b/STATUS_GO_VERSION @@ -1,3 +1,3 @@ ## DO NOT EDIT THIS FILE BY HAND. USE `scripts/update-status-go.sh ` instead -v0.25.0-beta.0 +v0.25.0-beta.1 diff --git a/src/status_im/accounts/login/core.cljs b/src/status_im/accounts/login/core.cljs index 5e4252efd4..e3b8ae5405 100644 --- a/src/status_im/accounts/login/core.cljs +++ b/src/status_im/accounts/login/core.cljs @@ -4,9 +4,9 @@ [status-im.chaos-mode.core :as chaos-mode] [status-im.data-store.core :as data-store] [status-im.ethereum.subscriptions :as ethereum.subscriptions] + [status-im.ethereum.transactions.core :as transactions] [status-im.fleet.core :as fleet] [status-im.i18n :as i18n] - [status-im.models.transactions :as transactions] [status-im.models.wallet :as models.wallet] [status-im.native-module.core :as status] [status-im.node.core :as node] diff --git a/src/status_im/accounts/logout/core.cljs b/src/status_im/accounts/logout/core.cljs index f1c9c3b82e..e891f311da 100644 --- a/src/status_im/accounts/logout/core.cljs +++ b/src/status_im/accounts/logout/core.cljs @@ -1,12 +1,12 @@ (ns status-im.accounts.logout.core (:require [re-frame.core :as re-frame] + [status-im.chaos-mode.core :as chaos-mode] + [status-im.ethereum.transactions.core :as transactions] [status-im.i18n :as i18n] - [status-im.transport.core :as transport] - [status-im.utils.fx :as fx] - [status-im.models.transactions :as transactions] - [status-im.node.core :as node] [status-im.init.core :as init] - [status-im.chaos-mode.core :as chaos-mode])) + [status-im.node.core :as node] + [status-im.transport.core :as transport] + [status-im.utils.fx :as fx])) (fx/defn logout [{:keys [db] :as cofx}] diff --git a/src/status_im/ethereum/subscriptions.cljs b/src/status_im/ethereum/subscriptions.cljs index 6570bf6335..6b67002388 100644 --- a/src/status_im/ethereum/subscriptions.cljs +++ b/src/status_im/ethereum/subscriptions.cljs @@ -1,32 +1,76 @@ (ns status-im.ethereum.subscriptions (:require [clojure.string :as string] [re-frame.core :as re-frame] + [status-im.constants :as constants] [status-im.ethereum.decode :as decode] [status-im.native-module.core :as status] + [status-im.utils.ethereum.core :as ethereum] + [status-im.utils.ethereum.tokens :as tokens] [status-im.utils.fx :as fx] + [status-im.utils.types :as types] [taoensso.timbre :as log])) -(defn get-block-by-hash [block-hash callback] +;; NOTE: this is the safe block range that can be +;; queried from infura rpc gateway without getting timeouts +;; determined experimentally by @goranjovic +(def block-query-limit 100000) + +(defn get-latest-block [callback] (status/call-private-rpc - (.stringify js/JSON (clj->js {:jsonrpc "2.0" - :id 1 - :method "eth_getBlockByHash" - :params [block-hash false]})) + (types/json->clj {:jsonrpc "2.0" + :id 1 + :method "eth_blockNumber" + :params []}) (fn [response] (if (string/blank? response) (log/warn :web3-response-error) (callback (-> (.parse js/JSON response) (js->clj :keywordize-keys true) :result - :number decode/uint)))))) +(defn get-block-by-hash [block-hash callback] + (status/call-private-rpc + (types/json->clj {:jsonrpc "2.0" + :id 1 + :method "eth_getBlockByHash" + :params [block-hash false]}) + (fn [response] + (if (string/blank? response) + (log/warn :web3-response-error) + (callback (-> (.parse js/JSON response) + (js->clj :keywordize-keys true) + :result + (update :number decode/uint) + (update :timestamp decode/uint))))))) + +(defn- get-token-transfer-logs + [from-block {:keys [chain-tokens direction from to]} callback] + (status/call-private-rpc + (types/json->clj {:jsonrpc "2.0" + :id 2 + :method "eth_getLogs" + :params + [{:address (keys chain-tokens) + :fromBlock from-block + :topics [constants/event-transfer-hash from to]}]}) + (fn [response] + (if (string/blank? response) + (log/warn :web3-response-error) + (callback (-> (.parse js/JSON response) + (js->clj :keywordize-keys true) + :result)))))) + (fx/defn handle-signal [cofx {:keys [subscription_id data] :as event}] (if-let [handler (get-in cofx [:db :ethereum/subscriptions subscription_id])] (handler data) (log/warn ::unknown-subscription :event event))) +(fx/defn handle-error + [cofx {:keys [subscription_id data] :as event}] + (log/error ::error event)) + (fx/defn register-subscription [{:keys [db]} id handler] {:db (assoc-in db [:ethereum/subscriptions id] handler)}) @@ -38,10 +82,10 @@ (defn subscribe-signal [filter params callback] (status/call-private-rpc - (.stringify js/JSON (clj->js {:jsonrpc "2.0" - :id 1 - :method "eth_subscribeSignal" - :params [filter, params]})) + (types/clj->json {:jsonrpc "2.0" + :id 1 + :method "eth_subscribeSignal" + :params [filter params]}) (fn [response] (if (string/blank? response) (log/error ::subscription-unknown-error :filter filter :params params) @@ -54,6 +98,100 @@ result callback]))))))) +(defn- add-padding [address] + {:pre [(string? address)]} + (str "0x000000000000000000000000" (subs address 2))) + +(defn- remove-padding [topic] + {:pre [(string? topic)]} + (str "0x" (subs topic 26))) + +(defn- parse-transaction-entries [timestamp chain-tokens direction transfers] + {:pre [(integer? timestamp) + (map? chain-tokens) + (every? (fn [[k v]] (and (string? k) (map? v))) chain-tokens) + (keyword? direction) + (every? map? transfers)]} + (into {} + (keep identity + (for [transfer transfers] + (when-let [token (->> transfer :address (get chain-tokens))] + (when-not (:nft? token) + [(:transactionHash transfer) + {:block (str (-> transfer :blockNumber ethereum/hex->bignumber)) + :hash (:transactionHash transfer) + :symbol (:symbol token) + :from (some-> transfer :topics second remove-padding) + :to (some-> transfer :topics last remove-padding) + :value (-> transfer :data ethereum/hex->bignumber) + :type direction + :gas-price nil + :nonce nil + :data nil + :gas-limit nil + :timestamp (str (* timestamp 1000)) + :gas-used nil + ;; NOTE(goranjovic) - metadata on the type of token: contains name, symbol, decimas, address. + :token token + ;; NOTE(goranjovic) - if an event has been emitted, we can say there was no error + :error? false + ;; NOTE(goranjovic) - just a flag we need when we merge this entry with the existing entry in + ;; the app, e.g. transaction info with gas details, or a previous transfer entry with old + ;; confirmations count. + :transfer true}])))))) + +(letfn [(combine-entries [transaction token-transfer] + (merge transaction (select-keys token-transfer [:symbol :from :to :value :type :token :transfer]))) + (tx-and-transfer? [tx1 tx2] + (and (not (:transfer tx1)) (:transfer tx2))) + (both-transfer? + [tx1 tx2] + (and (:transfer tx1) (:transfer tx2)))] + (defn- dedupe-transactions [tx1 tx2] + (cond (tx-and-transfer? tx1 tx2) (combine-entries tx1 tx2) + (tx-and-transfer? tx2 tx1) (combine-entries tx2 tx1) + :else tx2))) + +(fx/defn new-transactions + [{:keys [db]} transactions] + {:db (update-in db + [:wallet :transactions] + #(merge-with dedupe-transactions % transactions))}) + +(defn transactions-handler + [{:keys [chain-tokens from to direction]}] + (fn [transfers] + (let [transfers-by-block (group-by :blockHash transfers)] + (doseq [[block-hash block-transfers] transfers-by-block] + (get-block-by-hash + block-hash + (fn [{:keys [timestamp]}] + (let [transactions (parse-transaction-entries timestamp + chain-tokens + direction + block-transfers)] + (when (not-empty transactions) + (re-frame/dispatch [:ethereum.signal/new-transactions + transactions]))))))))) + +;; Here we are querying event logs for Transfer events. +;; +;; The parameters are as follows: +;; - address - token smart contract address +;; - fromBlock - we need to specify it, since default is latest +;; - topics[0] - hash code of the Transfer event signature +;; - topics[1] - address of token sender with leading zeroes padding up to 32 bytes +;; - topics[2] - address of token sender with leading zeroes padding up to 32 bytes +(defn new-token-transaction-filter + [{:keys [chain-tokens from to] :as args}] + (subscribe-signal + "eth_newFilter" + [{:fromBlock "latest" + :toBlock "latest" + :address (keys chain-tokens) + :topics [constants/event-transfer-hash from to]}] + (transactions-handler args))) + (defn new-block-filter [] (subscribe-signal @@ -61,15 +199,50 @@ (fn [[block-hash]] (get-block-by-hash block-hash - (fn [block-number] - (when block-number + (fn [block] + (when-let [block-number (:number block)] (re-frame/dispatch [:ethereum.signal/new-block block-number]))))))) +(defn get-from-block + [current-block-number] + (-> current-block-number + (- block-query-limit) + (max 0) + ethereum/int->hex)) + (re-frame/reg-fx - :ethereum.subscriptions/new-block-filter + :ethereum.subscriptions/token-transactions + (fn [{:keys [address] :as args}] + (let [inbound-args (merge args + {:direction :inbound + :to address}) + outbound-args (merge args + {:direction :outbound + :from address})] + ;; fetch 2 weeks of history until transactions are persisted + (get-latest-block + (fn [current-block-number] + (let [from-block (get-from-block current-block-number)] + (get-token-transfer-logs from-block inbound-args + (transactions-handler inbound-args)) + (get-token-transfer-logs from-block outbound-args + (transactions-handler outbound-args))))) + ;; start inbound and outbound token transaction subscriptions + (new-token-transaction-filter inbound-args) + (new-token-transaction-filter outbound-args)))) + +(re-frame/reg-fx + :ethereum.subscriptions/new-block new-block-filter) (fx/defn initialize - [cofx] - {:ethereum.subscriptions/new-block-filter nil}) + [{:keys [db] :as cofx}] + (let [{:keys [:account/account :wallet/all-tokens network]} db + chain (ethereum/network->chain-keyword (get-in account [:networks network])) + chain-tokens (into {} (map (juxt :address identity) + (tokens/tokens-for all-tokens chain))) + padded-address (add-padding (ethereum/normalized-address (:address account)))] + {:ethereum.subscriptions/new-block nil + :ethereum.subscriptions/token-transactions {:chain-tokens chain-tokens + :address padded-address}})) diff --git a/src/status_im/models/transactions.cljs b/src/status_im/ethereum/transactions/core.cljs similarity index 54% rename from src/status_im/models/transactions.cljs rename to src/status_im/ethereum/transactions/core.cljs index 1b46207a42..da3b113422 100644 --- a/src/status_im/models/transactions.cljs +++ b/src/status_im/ethereum/transactions/core.cljs @@ -1,166 +1,19 @@ -(ns status-im.models.transactions +(ns status-im.ethereum.transactions.core (:require [clojure.set :as set] - [cljs.core.async :as async] [clojure.string :as string] + [re-frame.core :as re-frame] + re-frame.db [status-im.utils.async :as async-util] [status-im.utils.ethereum.core :as ethereum] - [status-im.constants :as constants] - [status-im.native-module.core :as status] [status-im.utils.ethereum.tokens :as tokens] + [status-im.utils.fx :as fx] [status-im.utils.http :as http] [status-im.utils.types :as types] - [taoensso.timbre :as log] - [status-im.utils.fx :as fx] - [re-frame.core :as re-frame] - [re-frame.db] - [status-im.utils.config :as config]) - (:require-macros - [cljs.core.async.macros :refer [go-loop go]])) + [taoensso.timbre :as log])) (def sync-interval-ms 15000) (def sync-timeout-ms 20000) (def confirmations-count-threshold 12) -(def block-query-limit 100000) - -;; ---------------------------------------------------------------------------- -;; token transfer event logs from eth-node -;; ---------------------------------------------------------------------------- - -(defn- parse-json [s] - {:pre [(string? s)]} - (try - (let [res (-> s - js/JSON.parse - (js->clj :keywordize-keys true))] - (if (= (:error res) "") - {:result true} - res)) - (catch :default e - {:error (.-message e)}))) - -(defn- add-padding [address] - {:pre [(string? address)]} - (str "0x000000000000000000000000" (subs address 2))) - -(defn- remove-padding [topic] - {:pre [(string? topic)]} - (str "0x" (subs topic 26))) - -(defn- parse-transaction-entries [current-block-number block-info chain-tokens direction transfers] - {:pre [(integer? current-block-number) (map? block-info) - (map? chain-tokens) (every? (fn [[k v]] (and (string? k) (map? v))) chain-tokens) - (keyword? direction) - (every? map? transfers)]} - (into {} - (keep identity - (for [transfer transfers] - (when-let [token (->> transfer :address (get chain-tokens))] - (when-not (:nft? token) - [(:transactionHash transfer) - {:block (-> block-info :number str) - :hash (:transactionHash transfer) - :symbol (:symbol token) - :from (some-> transfer :topics second remove-padding) - :to (some-> transfer :topics last remove-padding) - :value (-> transfer :data ethereum/hex->bignumber) - :type direction - - :confirmations (str (- current-block-number (-> transfer :blockNumber ethereum/hex->int))) - - :gas-price nil - :nonce nil - :data nil - - :gas-limit nil - :timestamp (-> block-info :timestamp (* 1000) str) - - :gas-used nil - - ;; NOTE(goranjovic) - metadata on the type of token: contains name, symbol, decimas, address. - :token token - - ;; NOTE(goranjovic) - if an event has been emitted, we can say there was no error - :error? false - - ;; NOTE(goranjovic) - just a flag we need when we merge this entry with the existing entry in - ;; the app, e.g. transaction info with gas details, or a previous transfer entry with old - ;; confirmations count. - :transfer true}])))))) - -(defn- add-block-info [web3 current-block-number chain-tokens direction result success-fn] - {:pre [web3 (integer? current-block-number) (map? chain-tokens) (keyword? direction) - (every? map? result) - (fn? success-fn)]} - (let [transfers-by-block (group-by :blockNumber result)] - (doseq [[block-number transfers] transfers-by-block] - (ethereum/get-block-info web3 (ethereum/hex->int block-number) - (fn [block-info] - (if-not (map? block-info) - (log/error "Request for block info failed") - (success-fn (parse-transaction-entries current-block-number - block-info - chain-tokens - direction - transfers)))))))) - -(defn- response-handler [web3 current-block-number chain-tokens direction error-fn success-fn] - (fn handle-response - ([response] - #_(log/debug "Token transaction logs recieved --" (pr-str response)) - (let [{:keys [error result]} (parse-json response)] - (handle-response error result))) - ([error result] - (if error - (error-fn error) - (add-block-info web3 current-block-number chain-tokens direction result success-fn))))) - -(defn- limited-from-block [current-block-number latest-block-checked] - {:pre [(integer? current-block-number)] - ;; needs to be a positive etherium hex - :post [(string? %) (string/starts-with? % "0x")]} - (if latest-block-checked - (-> latest-block-checked (- confirmations-count-threshold) ethereum/int->hex) - (-> current-block-number (- block-query-limit) (max 0) ethereum/int->hex))) - -;; Here we are querying event logs for Transfer events. -;; -;; The parameters are as follows: -;; - address - token smart contract address -;; - fromBlock - we need to specify it, since default is latest -;; - topics[0] - hash code of the Transfer event signature -;; - topics[1] - address of token sender with leading zeroes padding up to 32 bytes -;; - topics[2] - address of token sender with leading zeroes padding up to 32 bytes -;; - -(defonce latest-block-checked (atom nil)) - -(defn- get-token-transfer-logs - ;; NOTE(goranjovic): here we use direct JSON-RPC calls to get event logs because of web3 event issues with infura - ;; we still use web3 to get other data, such as block info - [web3 current-block-number from-block chain-tokens direction address cb] - {:pre [web3 (integer? current-block-number) (map? chain-tokens) (keyword? direction) (string? address) (fn? cb)]} - (let [[from to] (if (= :inbound direction) - [nil (add-padding (ethereum/normalized-address address))] - [(add-padding (ethereum/normalized-address address)) nil]) - args {:jsonrpc "2.0" - :id 2 - :method constants/web3-get-logs - :params [{:address (keys chain-tokens) - :fromBlock from-block - :topics [constants/event-transfer-hash from to]}]} - payload (.stringify js/JSON (clj->js args))] - (status/call-private-rpc payload - (response-handler web3 current-block-number chain-tokens direction ethereum/handle-error cb)))) - -(defn- get-token-transactions - [web3 chain-tokens address cb] - {:pre [web3 (map? chain-tokens) (string? address) (fn? cb)]} - (ethereum/get-block-number web3 - (fn [current-block-number] - (let [from-block (limited-from-block current-block-number @latest-block-checked)] - (reset! latest-block-checked current-block-number) - (get-token-transfer-logs web3 current-block-number from-block chain-tokens :inbound address cb) - (get-token-transfer-logs web3 current-block-number from-block chain-tokens :outbound address cb))))) ;; -------------------------------------------------------------------------- ;; etherscan transactions @@ -199,8 +52,7 @@ (defn- format-transaction [account {:keys [value timeStamp blockNumber hash from to - gas gasPrice gasUsed nonce confirmations - input isError]}] + gas gasPrice gasUsed nonce input isError]}] (let [inbound? (= (str "0x" account) to) error? (= "1" isError)] {:value value @@ -218,7 +70,6 @@ :gas-price gasPrice :gas-used gasUsed :nonce nonce - :confirmations confirmations :data input})) (defn- format-transactions-response [response account] @@ -249,11 +100,7 @@ account-address success-fn error-fn - chaos-mode?) - (get-token-transactions web3 - chain-tokens - account-address - success-fn)) + chaos-mode?)) ;; ----------------------------------------------------------------------------- ;; Helpers functions that help determine if a background sync should execute @@ -302,21 +149,8 @@ (map :tx-hash) set)))) -;; Seq[transaction] -> truthy -(defn- have-unconfirmed-transactions? - "Detects if some of the transactions have less than 12 confirmations" - [transactions] - {:pre [(every? string? (map :confirmations transactions))]} - (->> transactions - (map :confirmations) - (map int) - (some #(< % confirmations-count-threshold)))) - (letfn [(combine-entries [transaction token-transfer] (merge transaction (select-keys token-transfer [:symbol :from :to :value :type :token :transfer]))) - (update-confirmations [tx1 tx2] - (assoc tx1 :confirmations (str (max (int (:confirmations tx1)) - (int (:confirmations tx2)))))) (tx-and-transfer? [tx1 tx2] (and (not (:transfer tx1)) (:transfer tx2))) (both-transfer? @@ -325,7 +159,6 @@ (defn- dedupe-transactions [tx1 tx2] (cond (tx-and-transfer? tx1 tx2) (combine-entries tx1 tx2) (tx-and-transfer? tx2 tx1) (combine-entries tx2 tx1) - (both-transfer? tx1 tx2) (update-confirmations tx1 tx2) :else tx2))) ;; ---------------------------------------------------------------------------- @@ -382,14 +215,11 @@ transaction-map (:transactions wallet) transaction-ids (set (keys transaction-map)) chaos-mode? (get-in account [:settings :chaos-mode?])] - (if-not (or @latest-block-checked - (have-unconfirmed-transactions? (vals transaction-map)) - (not-empty (set/difference chat-transaction-ids transaction-ids))) + (if-not (not-empty (set/difference chat-transaction-ids transaction-ids)) (done-fn) (transactions-query-helper web3 all-tokens account-address chain done-fn chaos-mode?)))))) (defn- start-sync! [{:keys [:account/account network web3] :as options}] - (reset! latest-block-checked nil) (let [account-address (:address account)] (when @polling-executor (async-util/async-periodic-stop! @polling-executor)) diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index 88d3304af7..ac4229d65f 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -2054,17 +2054,6 @@ (fn [cofx _] (bottom-sheet/hide-bottom-sheet cofx))) -;; ethereum subscriptions events -(handlers/register-handler-fx - :ethereum.callback/subscription-success - (fn [cofx [_ id handler]] - (ethereum.subscriptions/register-subscription cofx id handler))) - -(handlers/register-handler-fx - :ethereum.signal/new-block - (fn [cofx [_ block-number]] - (ethereum.subscriptions/new-block cofx block-number))) - ;;custom tokens (handlers/register-handler-fx @@ -2120,4 +2109,21 @@ (fx/merge cofx (custom-tokens/remove-custom-token token) (when navigate-back? - (navigation/navigate-back))))) \ No newline at end of file + (navigation/navigate-back))))) + +;; ethereum subscriptions events + +(handlers/register-handler-fx + :ethereum.callback/subscription-success + (fn [cofx [_ id handler]] + (ethereum.subscriptions/register-subscription cofx id handler))) + +(handlers/register-handler-fx + :ethereum.signal/new-block + (fn [cofx [_ block-number]] + (ethereum.subscriptions/new-block cofx block-number))) + +(handlers/register-handler-fx + :ethereum.signal/new-transactions + (fn [cofx [_ transactions]] + (ethereum.subscriptions/new-transactions cofx transactions))) diff --git a/src/status_im/init/core.cljs b/src/status_im/init/core.cljs index 9d99fd91d3..b717262dc7 100644 --- a/src/status_im/init/core.cljs +++ b/src/status_im/init/core.cljs @@ -1,37 +1,28 @@ (ns status-im.init.core (:require [re-frame.core :as re-frame] - [status-im.chat.models.loading :as chat-loading] - [status-im.accounts.core :as accounts.core] [status-im.accounts.login.core :as accounts.login] [status-im.accounts.update.core :as accounts.update] - [status-im.constants :as constants] - [status-im.react-native.js-dependencies :as rn-dependencies] + [status-im.browser.core :as browser] + [status-im.chat.models :as chat-model] + [status-im.contact.core :as contact] [status-im.data-store.core :as data-store] [status-im.data-store.realm.core :as realm] [status-im.extensions.registry :as extensions.registry] [status-im.i18n :as i18n] - [status-im.browser.core :as browser] - [status-im.contact.core :as contact] [status-im.models.dev-server :as models.dev-server] - [status-im.protocol.core :as protocol] - [status-im.pairing.core :as pairing] - [status-im.models.transactions :as transactions] - [status-im.models.wallet :as models.wallet] [status-im.native-module.core :as status] [status-im.node.core :as node] [status-im.notifications.core :as notifications] + [status-im.pairing.core :as pairing] + [status-im.react-native.js-dependencies :as rn-dependencies] + [status-im.stickers.core :as stickers] [status-im.ui.screens.db :refer [app-db]] [status-im.ui.screens.navigation :as navigation] - [status-im.utils.config :as config] [status-im.utils.ethereum.core :as ethereum] + [status-im.utils.fx :as fx] [status-im.utils.keychain.core :as keychain] [status-im.utils.platform :as platform] - [status-im.utils.utils :as utils] - [taoensso.timbre :as log] - [status-im.utils.fx :as fx] - [status-im.chat.models :as chat-model] - [status-im.accounts.db :as accounts.db] - [status-im.stickers.core :as stickers])) + [taoensso.timbre :as log])) (defn init-store! "Try to decrypt the database, move on if successful otherwise go back to diff --git a/src/status_im/signals/core.cljs b/src/status_im/signals/core.cljs index 9a14862225..548365872e 100644 --- a/src/status_im/signals/core.cljs +++ b/src/status_im/signals/core.cljs @@ -74,4 +74,5 @@ "messages.decrypt.failed" (contact-recovery/handle-contact-recovery-fx cofx (:sender event)) "discovery.summary" (summary cofx event) "subscriptions.data" (ethereum.subscriptions/handle-signal cofx event) + "subscriptions.error" (ethereum.subscriptions/handle-error cofx event) (log/debug "Event " type " not handled")))) diff --git a/src/status_im/subs.cljs b/src/status_im/subs.cljs index 3d095acbb0..48774cc556 100644 --- a/src/status_im/subs.cljs +++ b/src/status_im/subs.cljs @@ -10,9 +10,9 @@ [status-im.chat.db :as chat.db] [status-im.constants :as constants] [status-im.contact.db :as contact.db] + [status-im.ethereum.transactions.core :as transactions] [status-im.fleet.core :as fleet] [status-im.i18n :as i18n] - [status-im.models.transactions :as transactions] [status-im.models.wallet :as models.wallet] [status-im.ui.components.bottom-bar.styles :as tabs.styles] [status-im.ui.components.toolbar.styles :as toolbar.styles] diff --git a/src/status_im/ui/screens/wallet/events.cljs b/src/status_im/ui/screens/wallet/events.cljs index 3fd74858b3..fd221da199 100644 --- a/src/status_im/ui/screens/wallet/events.cljs +++ b/src/status_im/ui/screens/wallet/events.cljs @@ -1,19 +1,19 @@ (ns status-im.ui.screens.wallet.events (:require [re-frame.core :as re-frame] - [status-im.models.transactions :as wallet.transactions] + [status-im.ethereum.transactions.core :as transactions] + [status-im.i18n :as i18n] [status-im.models.wallet :as models] [status-im.ui.screens.navigation :as navigation] status-im.ui.screens.wallet.navigation [status-im.utils.ethereum.core :as ethereum] [status-im.utils.ethereum.erc20 :as erc20] [status-im.utils.ethereum.tokens :as tokens] + [status-im.utils.fx :as fx] [status-im.utils.handlers :as handlers] [status-im.utils.money :as money] [status-im.utils.prices :as prices] - [taoensso.timbre :as log] - [status-im.utils.fx :as fx] - [status-im.i18n :as i18n] - [status-im.utils.utils :as utils.utils])) + [status-im.utils.utils :as utils.utils] + [taoensso.timbre :as log])) (defn get-balance [{:keys [web3 account-id on-success on-error]}] (if (and web3 account-id) @@ -146,7 +146,7 @@ (handlers/register-handler-fx :update-transactions (fn [{:keys [db]} _] - {::wallet.transactions/sync-transactions-now + {::transactions/sync-transactions-now (select-keys db [:network-status :account/account :wallet/all-tokens :app-state :network :web3])})) diff --git a/src/status_im/ui/screens/wallet/send/events.cljs b/src/status_im/ui/screens/wallet/send/events.cljs index f8bf32cfee..82e901a89a 100644 --- a/src/status_im/ui/screens/wallet/send/events.cljs +++ b/src/status_im/ui/screens/wallet/send/events.cljs @@ -1,13 +1,11 @@ (ns status-im.ui.screens.wallet.send.events (:require [re-frame.core :as re-frame] [status-im.chat.commands.sending :as commands-sending] - [status-im.chat.models.message :as models.message] - [status-im.chat.models :as chat.models] [status-im.constants :as constants] [status-im.i18n :as i18n] - [status-im.models.transactions :as wallet.transactions] [status-im.models.wallet :as models.wallet] [status-im.native-module.core :as status] + [status-im.transport.utils :as transport.utils] [status-im.ui.screens.navigation :as navigation] [status-im.ui.screens.wallet.db :as wallet.db] [status-im.utils.ethereum.core :as ethereum] @@ -18,10 +16,7 @@ [status-im.utils.money :as money] [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.transport.utils :as transport.utils] - [status-im.hardwallet.core :as hardwallet])) + [status-im.utils.utils :as utils])) ;;;; FX diff --git a/test/cljs/status_im/test/sign_in/flow.cljs b/test/cljs/status_im/test/sign_in/flow.cljs index 065511c945..29eede285e 100644 --- a/test/cljs/status_im/test/sign_in/flow.cljs +++ b/test/cljs/status_im/test/sign_in/flow.cljs @@ -2,11 +2,11 @@ "The main purpose of these tests is to signal that some steps of the sign in flow has been changed. Such changes should be reflected in both these tests and documents which describe the whole \"sign in\" flow." - (:require [cljs.test :refer-macros [deftest is are testing]] + (:require [cljs.test :refer-macros [deftest is testing]] [status-im.accounts.login.core :as login.core] [status-im.events :as events] - [status-im.test.sign-in.data :as data] - [status-im.signals.core :as signals])) + [status-im.signals.core :as signals] + [status-im.test.sign-in.data :as data])) (deftest on-password-input-submitted (testing @@ -205,7 +205,7 @@ (is (contains? efx :web3/get-syncing)) (is (contains? efx :get-tokens-balance)) (is (contains? efx :get-prices)) - (is (contains? efx :status-im.models.transactions/start-sync-transactions)))))) + (is (contains? efx :status-im.ethereum.transactions.core/start-sync-transactions)))))) (deftest login-failed (testing diff --git a/test/cljs/status_im/test/wallet/transactions.cljs b/test/cljs/status_im/test/wallet/transactions.cljs index 789b788b32..f64ef4e571 100644 --- a/test/cljs/status_im/test/wallet/transactions.cljs +++ b/test/cljs/status_im/test/wallet/transactions.cljs @@ -1,21 +1,8 @@ (ns status-im.test.wallet.transactions - (:require [cljs.test :refer-macros [deftest is testing async run-tests]] - [cljs.core.async.impl.protocols :refer [closed?]] - [status-im.utils.datetime :as time] - [status-im.utils.http :as http] - [status-im.models.transactions :as transactions] - [goog.Uri :as goog-uri])) - -(deftest have-unconfirmed-transactions - (is (transactions/have-unconfirmed-transactions? - [{:confirmations "0"}])) - (is (transactions/have-unconfirmed-transactions? - [{:confirmations "11"}])) - (is (transactions/have-unconfirmed-transactions? - [{:confirmations "200"} - {:confirmations "0"}])) - (is (not (transactions/have-unconfirmed-transactions? - [{:confirmations "12"}])))) + (:require [cljs.test :refer-macros [deftest is]] + [goog.Uri :as goog-uri] + [status-im.ethereum.transactions.core :as transactions] + [status-im.utils.http :as http])) (deftest chat-map->transaction-ids (is (= #{} (transactions/chat-map->transaction-ids "testnet_rpc" {}))) @@ -222,7 +209,7 @@ (deftest etherscan-transactions (let [ky-set #{:block :hash :symbol :gas-price :value :gas-limit :type - :confirmations :gas-used :from :timestamp :nonce :to :data}] + :gas-used :from :timestamp :nonce :to :data}] (with-redefs [http/get (fn [url success-fn error-fn] (success-fn mock-etherscan-success-response))] (let [result (atom nil)]