wallet: main screen live data binding
Initial utility for live data binding in the new wallet. - Add prices namespace to get fiat prices from Cryptocompare - Events to init wallet balance and load prices - Listen to these events in wallet main view - Show accurate ETH balance, USD value and %change from yesterday - Enable wallet tab in Jenkins
This commit is contained in:
parent
55fd200c71
commit
8ac1535dab
|
@ -1 +1,2 @@
|
|||
TESTFAIRY_ENABLED=1
|
||||
WALLET_TAB_ENABLED=1
|
|
@ -36,6 +36,8 @@
|
|||
:discover-search-tags '()
|
||||
:tags []
|
||||
:sync-state :done
|
||||
:wallet {}
|
||||
:prices {}
|
||||
:network "testnet"})
|
||||
|
||||
;;;;GLOBAL
|
||||
|
@ -172,4 +174,6 @@
|
|||
:discoveries/tags
|
||||
:discoveries/current-tag
|
||||
:discoveries/request-discoveries-timer
|
||||
:discoveries/new-discover]))
|
||||
:discoveries/new-discover
|
||||
:wallet/wallet
|
||||
:prices/prices]))
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
status-im.ui.screens.navigation
|
||||
status-im.ui.screens.profile.events
|
||||
status-im.ui.screens.qr-scanner.events
|
||||
|
||||
status-im.ui.screens.wallet.events
|
||||
[re-frame.core :refer [dispatch reg-fx]]
|
||||
[status-im.components.status :as status]
|
||||
[status-im.components.permissions :as permissions]
|
||||
|
@ -163,7 +163,8 @@
|
|||
[:send-account-update-if-needed]
|
||||
[:start-requesting-discoveries]
|
||||
[:remove-old-discoveries!]
|
||||
[:set :accounts/creating-account? false]]}))
|
||||
[:set :accounts/creating-account? false]
|
||||
[:init-wallet]]}))
|
||||
|
||||
(register-handler-fx
|
||||
:check-console-chat
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
(ns status-im.ui.screens.wallet.db)
|
||||
|
||||
;; Placeholder namespace for wallet specs, which are a WIP depending on data
|
||||
;; model we decide on for balances, prices, etc.
|
||||
|
||||
;; TODO(oskarth): spec for balance as BigNumber
|
||||
;; TODO(oskarth): Spec for prices as as: {:from ETH, :to USD, :price 290.11, :last-day 304.17}
|
|
@ -0,0 +1,75 @@
|
|||
(ns status-im.ui.screens.wallet.events
|
||||
(:require [re-frame.core :as re-frame :refer [dispatch reg-fx]]
|
||||
[status-im.utils.handlers :as handlers]
|
||||
[status-im.utils.prices :as prices]))
|
||||
|
||||
(defn get-balance [{:keys [web3 account-id on-success on-error]}]
|
||||
(if (and web3 account-id)
|
||||
(.getBalance
|
||||
(.-eth web3)
|
||||
account-id
|
||||
(fn [err resp]
|
||||
(if-not err
|
||||
(on-success resp)
|
||||
(on-error err))))
|
||||
(on-error "web3 or account-id not available")))
|
||||
|
||||
;; FX
|
||||
|
||||
(reg-fx
|
||||
:get-balance
|
||||
(fn [{:keys [web3 account-id success-event error-event]}]
|
||||
(get-balance
|
||||
{:web3 web3
|
||||
:account-id account-id
|
||||
:on-success #(dispatch [success-event %])
|
||||
:on-error #(dispatch [error-event %])})))
|
||||
|
||||
(reg-fx
|
||||
:get-prices
|
||||
(fn [{:keys [from to success-event error-event]}]
|
||||
(prices/get-prices
|
||||
from
|
||||
to
|
||||
#(dispatch [success-event %])
|
||||
#(dispatch [error-event %]))))
|
||||
|
||||
;; Handlers
|
||||
|
||||
;; TODO(oskarth): At some point we want to get list of relevant assets to get prices for
|
||||
(handlers/register-handler-fx
|
||||
:load-prices
|
||||
(fn [{{:keys [wallet] :as db} :db} [_ a]]
|
||||
{:get-prices {:from "ETH"
|
||||
:to "USD"
|
||||
:success-event :update-prices
|
||||
:error-event :update-prices-fail}}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:init-wallet
|
||||
(fn [{{:keys [web3 accounts/current-account-id] :as db} :db} [_ a]]
|
||||
{:get-balance {:web3 web3
|
||||
:account-id current-account-id
|
||||
:success-event :update-balance
|
||||
:error-event :update-balance-fail}
|
||||
:dispatch [:load-prices]}))
|
||||
|
||||
(handlers/register-handler-db
|
||||
:update-balance
|
||||
(fn [db [_ balance]]
|
||||
(assoc db :wallet {:balance balance})))
|
||||
|
||||
(handlers/register-handler-db
|
||||
:update-prices
|
||||
(fn [db [_ prices]]
|
||||
(assoc db :prices prices)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:update-balance-fail
|
||||
(fn [_ [_ err]]
|
||||
(.log js/console "Unable to get balance: " err)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:update-prices-fail
|
||||
(fn [_ [_ err]]
|
||||
(.log js/console "Unable to get prices: " err)))
|
|
@ -1,5 +1,5 @@
|
|||
(ns status-im.ui.screens.wallet.main.views
|
||||
(:require-macros [status-im.utils.views :refer [defview]])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as rf]
|
||||
[status-im.components.common.common :as common]
|
||||
|
@ -11,7 +11,8 @@
|
|||
[status-im.i18n :as i18n]
|
||||
[status-im.utils.listview :as lw]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.ui.screens.wallet.main.styles :as st]))
|
||||
[status-im.ui.screens.wallet.main.styles :as st]
|
||||
[status-im.utils.money :as money]))
|
||||
|
||||
(defn toolbar-title []
|
||||
[rn/view {:style st/toolbar-title-container}
|
||||
|
@ -31,16 +32,17 @@
|
|||
:custom-content [toolbar-title]
|
||||
:custom-action [toolbar-buttons]}])
|
||||
|
||||
(defn main-section []
|
||||
;; TODO(oskarth): Whatever triggers the "in progress" animation should also trigger wallet-init or load-prices event.
|
||||
(defn main-section [usd-value change]
|
||||
[rn/view {:style st/main-section}
|
||||
[rn/view {:style st/total-balance-container}
|
||||
[rn/view {:style st/total-balance}
|
||||
[rn/text {:style st/total-balance-value} "12.43"]
|
||||
[rn/text {:style st/total-balance-value} usd-value]
|
||||
[rn/text {:style st/total-balance-currency} "USD"]]
|
||||
[rn/view {:style st/value-variation}
|
||||
[rn/text {:style st/value-variation-title} "Total value"]
|
||||
[rn/view {:style st/today-variation-container}
|
||||
[rn/text {:style st/today-variation} "+5.43%"]]]
|
||||
[rn/text {:style st/today-variation} change]]]
|
||||
[btn/buttons st/buttons
|
||||
[{:text "Send"
|
||||
:on-press #(rf/dispatch [:navigate-to :wallet-send-transaction])}
|
||||
|
@ -72,20 +74,46 @@
|
|||
[rn/view
|
||||
[asset-list-item row]]]))
|
||||
|
||||
(defn asset-section []
|
||||
(let [assets {"eth" {:currency :eth :amount 0.445}
|
||||
"snt" {:currency :snt :amount 1}
|
||||
"gno" {:currency :gno :amount 0.024794}}]
|
||||
(def assets-example-map
|
||||
{"eth" {:currency :eth :amount 0.445}
|
||||
"snt" {:currency :snt :amount 1}
|
||||
"gno" {:currency :gno :amount 0.024794}})
|
||||
|
||||
;; NOTE(oskarth): In development, replace assets with assets-example-map
|
||||
;; to check multiple assets being rendered
|
||||
(defn asset-section [eth]
|
||||
(let [assets {"eth" {:currency :eth :amount eth}}]
|
||||
[rn/view {:style st/asset-section}
|
||||
[rn/text {:style st/asset-section-title} "Assets"]
|
||||
[rn/list-view {:dataSource (lw/to-datasource assets)
|
||||
:renderSeparator (when platform/ios? (render-separator-fn (count assets)))
|
||||
:renderRow render-row-fn}]]))
|
||||
|
||||
(defn eth-balance [{:keys [balance]}]
|
||||
(when balance
|
||||
(money/wei->ether balance)))
|
||||
|
||||
(defn portfolio-value [{:keys [balance]} {:keys [price]}]
|
||||
(when (and balance price)
|
||||
(-> (money/wei->ether balance)
|
||||
(money/eth->usd price)
|
||||
(money/with-precision 2)
|
||||
str)))
|
||||
|
||||
(defn portfolio-change [{:keys [price last-day]}]
|
||||
(when (and price last-day)
|
||||
(-> (money/percent-change price last-day)
|
||||
(money/with-precision 2)
|
||||
(str "%"))))
|
||||
|
||||
(defview wallet []
|
||||
[]
|
||||
[rn/view {:style st/wallet-container}
|
||||
[toolbar-view]
|
||||
[rn/scroll-view
|
||||
[main-section]
|
||||
[asset-section]]])
|
||||
(letsubs [wallet [:get :wallet]
|
||||
prices [:get :prices]]
|
||||
(let [eth (or (eth-balance wallet) "...")
|
||||
usd (or (portfolio-value wallet prices) "...")
|
||||
change (or (portfolio-change prices) "-%")]
|
||||
[rn/view {:style st/wallet-container}
|
||||
[toolbar-view]
|
||||
[rn/scroll-view
|
||||
[main-section usd change]
|
||||
[asset-section eth]]])))
|
||||
|
|
|
@ -29,3 +29,14 @@
|
|||
|
||||
(defn fee-value [gas gas-price]
|
||||
(.times (bignumber gas) (bignumber gas-price)))
|
||||
|
||||
(defn eth->usd [eth usd-price]
|
||||
(.times (bignumber eth) (bignumber usd-price)))
|
||||
|
||||
(defn percent-change [from to]
|
||||
(-> (.dividedBy (bignumber from) (bignumber to))
|
||||
(.minus 1)
|
||||
(.times 100)))
|
||||
|
||||
(defn with-precision [n decimals]
|
||||
(.round (bignumber n) decimals))
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
(ns status-im.utils.prices
|
||||
(:require [status-im.utils.utils :as utils]
|
||||
[status-im.utils.types :as types]))
|
||||
|
||||
;; Responsible for interacting with Cryptocompare API to get current prices for
|
||||
;; currencies and tokens.
|
||||
;;
|
||||
;; No tests since fetch API (via http-get) relies on `window` being available.
|
||||
;;
|
||||
;; Example usage:
|
||||
;; (get-prices "ETH" "USD" println print)
|
||||
|
||||
(def api-url "https://min-api.cryptocompare.com/data")
|
||||
|
||||
(defn- gen-price-url [fsyms tsyms]
|
||||
(str api-url "/pricemultifull?fsyms=" fsyms "&tsyms=" tsyms))
|
||||
|
||||
(defn- format-price-resp [from to resp]
|
||||
(let [raw (:RAW (types/json->clj resp))
|
||||
entry (get-in raw [(keyword from) (keyword to)])]
|
||||
{:from from
|
||||
:to to
|
||||
:price (:PRICE entry)
|
||||
:last-day (:OPEN24HOUR entry)}))
|
||||
|
||||
(defn get-prices [from to on-success on-error]
|
||||
(utils/http-get
|
||||
(gen-price-url from to)
|
||||
(fn [resp] (on-success (format-price-resp from to resp)))
|
||||
on-error))
|
Loading…
Reference in New Issue