mirror of
https://github.com/status-im/status-react.git
synced 2025-02-19 22:28:40 +00:00
Move status-im.utils.money to utils.money (#16573)
This commit is contained in:
parent
645a5b312b
commit
88c4521321
@ -1,5 +1,5 @@
|
|||||||
(ns status-im.ethereum.decode
|
(ns status-im.ethereum.decode
|
||||||
(:require [status-im.utils.money :as money]))
|
(:require [utils.money :as money]))
|
||||||
|
|
||||||
(defn uint
|
(defn uint
|
||||||
[hex]
|
[hex]
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
[status-im.ethereum.core :as ethereum]
|
[status-im.ethereum.core :as ethereum]
|
||||||
[status-im.ethereum.ens :as ens]
|
[status-im.ethereum.ens :as ens]
|
||||||
[status-im.ethereum.tokens :as tokens]
|
[status-im.ethereum.tokens :as tokens]
|
||||||
[status-im.utils.money :as money]))
|
[utils.money :as money]))
|
||||||
|
|
||||||
(def scheme "ethereum")
|
(def scheme "ethereum")
|
||||||
(def scheme-separator ":")
|
(def scheme-separator ":")
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
(ns status-im.ethereum.eip681-test
|
(ns status-im.ethereum.eip681-test
|
||||||
(:require [cljs.test :refer-macros [deftest is] :as test]
|
(:require [cljs.test :refer-macros [deftest is] :as test]
|
||||||
[status-im.ethereum.eip681 :as eip681]
|
[status-im.ethereum.eip681 :as eip681]
|
||||||
[status-im.utils.money :as money]))
|
[utils.money :as money]))
|
||||||
|
|
||||||
(deftest parse-uri
|
(deftest parse-uri
|
||||||
(is (= nil (eip681/parse-uri nil)))
|
(is (= nil (eip681/parse-uri nil)))
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
[status-im.ethereum.core :as ethereum]
|
[status-im.ethereum.core :as ethereum]
|
||||||
[status-im.keycard.common :as common]
|
[status-im.keycard.common :as common]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[status-im.utils.money :as money]
|
[utils.money :as money]
|
||||||
[status-im.utils.types :as types]
|
[status-im.utils.types :as types]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
@ -38,8 +38,8 @@
|
|||||||
{:db (assoc-in db [:signing/sign :keycard-step] :signing)}
|
{:db (assoc-in db [:signing/sign :keycard-step] :signing)}
|
||||||
(common/set-on-card-connected :keycard/sign))
|
(common/set-on-card-connected :keycard/sign))
|
||||||
|
|
||||||
(pos? keycard-pin-retries) ; if 0, get-application-info will have already closed the connection
|
(pos? keycard-pin-retries) ; if 0, get-application-info will have already closed the
|
||||||
; sheet and opened the frozen card popup
|
; connection sheet and opened the frozen card popup
|
||||||
{:db (-> db
|
{:db (-> db
|
||||||
(assoc-in [:keycard :card-read-in-progress?] true)
|
(assoc-in [:keycard :card-read-in-progress?] true)
|
||||||
(assoc-in [:keycard :pin :status] :verifying))
|
(assoc-in [:keycard :pin :status] :verifying))
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[status-im.notifications.android :as pn-android]
|
[status-im.notifications.android :as pn-android]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[status-im.utils.money :as money]
|
[utils.money :as money]
|
||||||
[status-im.utils.types :as types]
|
[status-im.utils.types :as types]
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
[react-native.core :as rn]))
|
[react-native.core :as rn]))
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
[status-im.signing.keycard :as signing.keycard]
|
[status-im.signing.keycard :as signing.keycard]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[status-im.utils.hex :as utils.hex]
|
[status-im.utils.hex :as utils.hex]
|
||||||
[status-im.utils.money :as money]
|
[utils.money :as money]
|
||||||
[status-im.utils.types :as types]
|
[status-im.utils.types :as types]
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
[status-im.wallet.core :as wallet]
|
[status-im.wallet.core :as wallet]
|
||||||
@ -313,8 +313,8 @@
|
|||||||
{:events [:sign/send-transaction-message]}
|
{:events [:sign/send-transaction-message]}
|
||||||
[cofx chat-id value contract transaction-hash signature]
|
[cofx chat-id value contract transaction-hash signature]
|
||||||
{:json-rpc/call [{:method "wakuext_sendTransaction"
|
{:json-rpc/call [{:method "wakuext_sendTransaction"
|
||||||
;; We make sure `value` is serialized as string, and not
|
;; We make sure `value` is serialized as string, and not as an integer or
|
||||||
;; as an integer or big-int
|
;; big-int
|
||||||
:params [chat-id (str value) contract transaction-hash
|
:params [chat-id (str value) contract transaction-hash
|
||||||
(or (:result (types/json->clj signature))
|
(or (:result (types/json->clj signature))
|
||||||
(ethereum/normalized-hex signature))]
|
(ethereum/normalized-hex signature))]
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
[status-im.popover.core :as popover]
|
[status-im.popover.core :as popover]
|
||||||
[status-im.signing.eip1559 :as eip1559]
|
[status-im.signing.eip1559 :as eip1559]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[status-im.utils.money :as money]
|
[utils.money :as money]
|
||||||
[status-im2.common.json-rpc.events :as json-rpc]
|
[status-im2.common.json-rpc.events :as json-rpc]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
@ -336,7 +336,7 @@
|
|||||||
(let [sorted-v (sort-by
|
(let [sorted-v (sort-by
|
||||||
identity
|
identity
|
||||||
(fn [a b]
|
(fn [a b]
|
||||||
(status-im.utils.money/greater-than b a))
|
(utils.money/greater-than b a))
|
||||||
v)]
|
v)]
|
||||||
(reduce
|
(reduce
|
||||||
(fn [acc p]
|
(fn [acc p]
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
[status-im.signing.gas :as gas]
|
[status-im.signing.gas :as gas]
|
||||||
[status-im.ui.components.icons.icons :as icons]
|
[status-im.ui.components.icons.icons :as icons]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.utils.money :as money]))
|
[utils.money :as money]))
|
||||||
|
|
||||||
(views/defview fee-bottom-sheet
|
(views/defview fee-bottom-sheet
|
||||||
[fee-display-symbol]
|
[fee-display-symbol]
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.screens.stickers.styles :as styles]
|
[status-im.ui.screens.stickers.styles :as styles]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[status-im.utils.money :as money])
|
[utils.money :as money])
|
||||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||||
|
|
||||||
(defn cache
|
(defn cache
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
[status-im.ui.screens.wallet.components.views :as components]
|
[status-im.ui.screens.wallet.components.views :as components]
|
||||||
[status-im.ui.screens.wallet.send.sheets :as sheets]
|
[status-im.ui.screens.wallet.send.sheets :as sheets]
|
||||||
[status-im.ui.screens.wallet.send.styles :as styles]
|
[status-im.ui.screens.wallet.send.styles :as styles]
|
||||||
[status-im.utils.money :as money]
|
[utils.money :as money]
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
[status-im.wallet.utils :as wallet.utils]))
|
[status-im.wallet.utils :as wallet.utils]))
|
||||||
|
|
||||||
|
@ -1,223 +0,0 @@
|
|||||||
(ns status-im.utils.money
|
|
||||||
(:require ["bignumber.js" :as BigNumber]
|
|
||||||
[clojure.string :as string]))
|
|
||||||
|
|
||||||
;; The BigNumber version included in web3 sometimes hangs when dividing large
|
|
||||||
;; numbers Hence we want to use these functions instead of fromWei etc, which
|
|
||||||
;; come bundled with web3. See
|
|
||||||
;; https://github.com/MikeMcl/bignumber.js/issues/120 for this regression being
|
|
||||||
;; introduced in some JS environments. It is fixed in the MikeMcl/bignumber.js
|
|
||||||
;; repo, but not in the web3 BigNumber fork:
|
|
||||||
;; https://github.com/ethereum/web3.js/issues/877
|
|
||||||
;;
|
|
||||||
;; Additionally, while it is possible to use the BigNumber constructor without
|
|
||||||
;; stringifying the number, this only works up to some 15 significant digits:
|
|
||||||
;; https://github.com/MikeMcl/bignumber.js/issues/120
|
|
||||||
;;
|
|
||||||
;; Lastly, notice the bad rounding for native Javascript numbers above 17 digits
|
|
||||||
;; that may result in errors earlier up the call chain. Ideally all money-related
|
|
||||||
;; sensitive functions should be moved into this namespace to check for such
|
|
||||||
;; matters:
|
|
||||||
;; (str 111122223333441239) => "111122223333441230"
|
|
||||||
|
|
||||||
(defn normalize
|
|
||||||
"A normalized string representation of an amount"
|
|
||||||
[s]
|
|
||||||
{:pre [(or (nil? s) (string? s))]}
|
|
||||||
(when s
|
|
||||||
(string/replace (string/trim s) #"," ".")))
|
|
||||||
|
|
||||||
(defn bignumber
|
|
||||||
[n]
|
|
||||||
(when n
|
|
||||||
(try
|
|
||||||
(new BigNumber (normalize (str n)))
|
|
||||||
(catch :default _ nil))))
|
|
||||||
|
|
||||||
(defn greater-than-or-equals
|
|
||||||
[^js bn1 ^js bn2]
|
|
||||||
(.greaterThanOrEqualTo bn1 bn2))
|
|
||||||
|
|
||||||
(defn greater-than
|
|
||||||
[bn1 bn2]
|
|
||||||
(.greaterThan ^js bn1 bn2))
|
|
||||||
|
|
||||||
(defn equal-to
|
|
||||||
[bn1 bn2]
|
|
||||||
(.eq ^js bn1 bn2))
|
|
||||||
|
|
||||||
(defn sub
|
|
||||||
[bn1 bn2]
|
|
||||||
(.sub ^js bn1 bn2))
|
|
||||||
|
|
||||||
(defn valid?
|
|
||||||
[^js bn]
|
|
||||||
(when bn
|
|
||||||
(greater-than-or-equals bn 0)))
|
|
||||||
|
|
||||||
(defn from-decimal
|
|
||||||
[n]
|
|
||||||
(when n
|
|
||||||
(str "1" (string/join (repeat n "0")))))
|
|
||||||
|
|
||||||
(def eth-units
|
|
||||||
{:wei (bignumber "1")
|
|
||||||
:kwei (bignumber (from-decimal 3))
|
|
||||||
:mwei (bignumber (from-decimal 6))
|
|
||||||
:gwei (bignumber (from-decimal 9))
|
|
||||||
:szabo (bignumber (from-decimal 12))
|
|
||||||
:finney (bignumber (from-decimal 15))
|
|
||||||
:eth (bignumber (from-decimal 18))
|
|
||||||
:keth (bignumber (from-decimal 21))
|
|
||||||
:meth (bignumber (from-decimal 24))
|
|
||||||
:geth (bignumber (from-decimal 27))
|
|
||||||
:teth (bignumber (from-decimal 30))})
|
|
||||||
|
|
||||||
(defn wei->
|
|
||||||
[unit n]
|
|
||||||
(when-let [^js bn (bignumber n)]
|
|
||||||
(.dividedBy bn (eth-units unit))))
|
|
||||||
|
|
||||||
(defn ->wei
|
|
||||||
[unit n]
|
|
||||||
(when-let [^js bn (bignumber n)]
|
|
||||||
(.times bn (eth-units unit))))
|
|
||||||
|
|
||||||
(defn to-fixed
|
|
||||||
([^js bn]
|
|
||||||
(when bn
|
|
||||||
(.toFixed bn)))
|
|
||||||
([^js bn b]
|
|
||||||
(when bn
|
|
||||||
(.toFixed bn b))))
|
|
||||||
|
|
||||||
(defn to-number
|
|
||||||
[^js bn]
|
|
||||||
(when bn
|
|
||||||
(.toNumber bn)))
|
|
||||||
|
|
||||||
(defn to-string
|
|
||||||
([^js bn]
|
|
||||||
(to-string bn 10))
|
|
||||||
([^js bn base]
|
|
||||||
(when bn
|
|
||||||
(.toString bn base))))
|
|
||||||
|
|
||||||
(defn to-hex
|
|
||||||
[^js bn]
|
|
||||||
(str "0x" (to-string bn 16)))
|
|
||||||
|
|
||||||
(defn wei->str
|
|
||||||
([unit n display-unit]
|
|
||||||
(str (to-fixed (wei-> unit n)) " " display-unit))
|
|
||||||
([unit n] (wei->str unit n (string/upper-case (name unit)))))
|
|
||||||
|
|
||||||
(defn wei->ether
|
|
||||||
[n]
|
|
||||||
(wei-> :eth n))
|
|
||||||
|
|
||||||
(defn wei->gwei
|
|
||||||
[n]
|
|
||||||
(wei-> :gwei n))
|
|
||||||
|
|
||||||
(defn ether->wei
|
|
||||||
[^js bn]
|
|
||||||
(when bn
|
|
||||||
(.times bn ^js (bignumber 1e18))))
|
|
||||||
|
|
||||||
(defn token->unit
|
|
||||||
[n decimals]
|
|
||||||
(when-let [^js bn (bignumber n)]
|
|
||||||
(when-let [d (from-decimal decimals)]
|
|
||||||
(.dividedBy bn ^js (bignumber d)))))
|
|
||||||
|
|
||||||
(defn unit->token
|
|
||||||
[n decimals]
|
|
||||||
(when-let [^js bn (bignumber n)]
|
|
||||||
(when-let [d (from-decimal decimals)]
|
|
||||||
(.times bn ^js (bignumber d)))))
|
|
||||||
|
|
||||||
;;NOTE(goranjovic) - We have two basic representations of values that refer to cryptocurrency amounts:
|
|
||||||
;;formatted and
|
|
||||||
;; internal. Formatted representation is the one we show on screens and include in reports, whereas
|
|
||||||
;; internal
|
|
||||||
;; representation is the one that we pass on to ethereum network for execution, transfer, etc.
|
|
||||||
;; The difference between the two depends on the number of decimals, i.e. internal representation is
|
|
||||||
;; expressed in terms
|
|
||||||
;; of a whole number of smallest divisible parts of the formatted value.
|
|
||||||
;;
|
|
||||||
;; E.g. for Ether, it's smallest part is wei or 10^(-18) of 1 ether
|
|
||||||
;; for arbitrary ERC20 token the smallest part is 10^(-decimals) of 1 token
|
|
||||||
;;
|
|
||||||
;; Different tokens can have different number of allowed decimals, so it's neccessary to include the
|
|
||||||
;; decimals parameter
|
|
||||||
;; to get the amount scale right.
|
|
||||||
|
|
||||||
(defn formatted->internal
|
|
||||||
[n symbol decimals]
|
|
||||||
(if (= :ETH symbol)
|
|
||||||
(ether->wei n)
|
|
||||||
(unit->token n decimals)))
|
|
||||||
|
|
||||||
(defn internal->formatted
|
|
||||||
[n symbol decimals]
|
|
||||||
(if (= :ETH symbol)
|
|
||||||
(wei->ether n)
|
|
||||||
(token->unit n decimals)))
|
|
||||||
|
|
||||||
(defn fee-value
|
|
||||||
[gas gas-price]
|
|
||||||
(.times ^js (bignumber gas) ^js (bignumber gas-price)))
|
|
||||||
|
|
||||||
(defn crypto->fiat
|
|
||||||
[crypto fiat-price]
|
|
||||||
(when-let [^js bn (bignumber crypto)]
|
|
||||||
(.times bn ^js (bignumber fiat-price))))
|
|
||||||
|
|
||||||
(defn percent-change
|
|
||||||
[from to]
|
|
||||||
(let [^js bnf (bignumber from)
|
|
||||||
^js bnt (bignumber to)]
|
|
||||||
(when (and bnf bnt)
|
|
||||||
(-> ^js (.dividedBy bnf bnt)
|
|
||||||
^js (.minus 1)
|
|
||||||
^js (.times 100)))))
|
|
||||||
|
|
||||||
(defn with-precision
|
|
||||||
[n decimals]
|
|
||||||
(when-let [^js bn (bignumber n)]
|
|
||||||
(.round bn decimals)))
|
|
||||||
|
|
||||||
(defn sufficient-funds?
|
|
||||||
[^js amount ^js balance]
|
|
||||||
(when (and amount balance)
|
|
||||||
(.greaterThanOrEqualTo balance amount)))
|
|
||||||
|
|
||||||
(defn fiat-amount-value
|
|
||||||
[amount-str from to prices]
|
|
||||||
(-> amount-str
|
|
||||||
(js/parseFloat)
|
|
||||||
bignumber
|
|
||||||
(crypto->fiat (get-in prices [from to] ^js (bignumber 0)))
|
|
||||||
(with-precision 2)
|
|
||||||
str))
|
|
||||||
|
|
||||||
(defn add
|
|
||||||
[bn1 n2]
|
|
||||||
(.add ^js bn1 n2))
|
|
||||||
|
|
||||||
(defn mul
|
|
||||||
[bn1 bn2]
|
|
||||||
(.mul ^js bn1 bn2))
|
|
||||||
|
|
||||||
(defn mul-and-round
|
|
||||||
[bn1 bn2]
|
|
||||||
(.round (.mul ^js bn1 bn2) 0))
|
|
||||||
|
|
||||||
(defn div
|
|
||||||
[bn1 bn2]
|
|
||||||
(.dividedBy ^js bn1 bn2))
|
|
||||||
|
|
||||||
(defn div-and-round
|
|
||||||
[bn1 bn2]
|
|
||||||
(.round (.dividedBy ^js bn1 bn2) 0))
|
|
@ -1,23 +0,0 @@
|
|||||||
(ns status-im.utils.money-test
|
|
||||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
|
||||||
[status-im.utils.money :as money]))
|
|
||||||
|
|
||||||
(deftest wei->ether
|
|
||||||
(testing "Numeric input, 15 significant digits"
|
|
||||||
(is (= (str (money/wei->ether 111122223333444000))
|
|
||||||
"0.111122223333444")))
|
|
||||||
(testing "String input, 18 significant digits"
|
|
||||||
(is (= (str (money/wei->ether "111122223333441239"))
|
|
||||||
"0.111122223333441239"))))
|
|
||||||
|
|
||||||
(deftest valid?
|
|
||||||
(is (not (true? (money/valid? nil))))
|
|
||||||
(is (true? (money/valid? (money/bignumber 0))))
|
|
||||||
(is (true? (money/valid? (money/bignumber 1))))
|
|
||||||
(is (not (true? (money/valid? (money/bignumber -1))))))
|
|
||||||
|
|
||||||
(deftest normalize
|
|
||||||
(is (= nil (money/normalize nil)))
|
|
||||||
(is (= "1" (money/normalize " 1 ")))
|
|
||||||
(is (= "1.1" (money/normalize "1.1")))
|
|
||||||
(is (= "1.1" (money/normalize "1,1"))))
|
|
@ -10,7 +10,7 @@
|
|||||||
[status-im.router.core :as router]
|
[status-im.router.core :as router]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[status-im.utils.http :as http]
|
[status-im.utils.http :as http]
|
||||||
[status-im.utils.money :as money]
|
[utils.money :as money]
|
||||||
[status-im.utils.universal-links.utils :as links]
|
[status-im.utils.universal-links.utils :as links]
|
||||||
[status-im.utils.wallet-connect :as wallet-connect]
|
[status-im.utils.wallet-connect :as wallet-connect]
|
||||||
[status-im2.navigation.events :as navigation]))
|
[status-im2.navigation.events :as navigation]))
|
||||||
@ -118,8 +118,7 @@
|
|||||||
{:events [:wallet/parse-eip681-uri-and-resolve-ens]}
|
{:events [:wallet/parse-eip681-uri-and-resolve-ens]}
|
||||||
[{db :db :as cofx} {:keys [message uri paths ens-names error]} ignore-url]
|
[{db :db :as cofx} {:keys [message uri paths ens-names error]} ignore-url]
|
||||||
(if-not error
|
(if-not error
|
||||||
;; first we get a vector of ens-names to resolve and a vector of paths of
|
;; first we get a vector of ens-names to resolve and a vector of paths of these names
|
||||||
;; these names
|
|
||||||
(if (empty? ens-names)
|
(if (empty? ens-names)
|
||||||
;; if there are no ens-names, we dispatch request-uri-parsed immediately
|
;; if there are no ens-names, we dispatch request-uri-parsed immediately
|
||||||
(request-uri-parsed cofx message uri)
|
(request-uri-parsed cofx message uri)
|
||||||
@ -130,8 +129,7 @@
|
|||||||
(fn [addresses]
|
(fn [addresses]
|
||||||
(re-frame/dispatch
|
(re-frame/dispatch
|
||||||
[:wallet/request-uri-parsed
|
[:wallet/request-uri-parsed
|
||||||
;; we replace ens-names at their path in the message by their
|
;; we replace ens-names at their path in the message by their actual address
|
||||||
;; actual address
|
|
||||||
(reduce (fn [message [path address]]
|
(reduce (fn [message [path address]]
|
||||||
(assoc-in message path address))
|
(assoc-in message path address))
|
||||||
message
|
message
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
[status-im.utils.core :as utils.core]
|
[status-im.utils.core :as utils.core]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[utils.datetime :as datetime]
|
[utils.datetime :as datetime]
|
||||||
[status-im.utils.money :as money]
|
[utils.money :as money]
|
||||||
[status-im.utils.utils :as utils.utils]
|
[status-im.utils.utils :as utils.utils]
|
||||||
[status-im.wallet.db :as wallet.db]
|
[status-im.wallet.db :as wallet.db]
|
||||||
[status-im.wallet.prices :as prices]
|
[status-im.wallet.prices :as prices]
|
||||||
@ -247,8 +247,8 @@
|
|||||||
assets (get visible-tokens chain)
|
assets (get visible-tokens chain)
|
||||||
tokens (->> (vals all-tokens)
|
tokens (->> (vals all-tokens)
|
||||||
(remove #(or (:hidden? %)
|
(remove #(or (:hidden? %)
|
||||||
;;if not scan-all-tokens? remove not visible
|
;;if not scan-all-tokens? remove not
|
||||||
;;tokens
|
;;visible tokens
|
||||||
(and (not scan-all-tokens?)
|
(and (not scan-all-tokens?)
|
||||||
(not (get assets (:symbol %))))))
|
(not (get assets (:symbol %))))))
|
||||||
(reduce (fn [acc {:keys [address symbol]}]
|
(reduce (fn [acc {:keys [address symbol]}]
|
||||||
@ -1141,8 +1141,7 @@
|
|||||||
eip55/address->checksum)
|
eip55/address->checksum)
|
||||||
type
|
type
|
||||||
(update :type keyword))]
|
(update :type keyword))]
|
||||||
;; if the account is the default wallet we
|
;; if the account is the default wallet we put it first in the list
|
||||||
;; put it first in the list
|
|
||||||
(if wallet
|
(if wallet
|
||||||
(into [account] acc)
|
(into [account] acc)
|
||||||
(conj acc account)))))
|
(conj acc account)))))
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
(ns status-im.wallet.db
|
(ns status-im.wallet.db
|
||||||
(:require [utils.i18n :as i18n]
|
(:require [utils.i18n :as i18n]
|
||||||
[status-im.utils.money :as money]
|
[utils.money :as money]
|
||||||
[status-im.utils.priority-map :refer [empty-transaction-map]]))
|
[status-im.utils.priority-map :refer [empty-transaction-map]]))
|
||||||
|
|
||||||
(defn- too-precise-amount?
|
(defn- too-precise-amount?
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
(ns status-im.wallet.db-test
|
(ns status-im.wallet.db-test
|
||||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[status-im.utils.money :as money]
|
[utils.money :as money]
|
||||||
[status-im.wallet.db :as wallet.db]))
|
[status-im.wallet.db :as wallet.db]))
|
||||||
|
|
||||||
(deftest test-too-precise-amount?
|
(deftest test-too-precise-amount?
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
(ns status-im.wallet.utils
|
(ns status-im.wallet.utils
|
||||||
(:require [status-im.utils.money :as money]))
|
(:require [utils.money :as money]))
|
||||||
|
|
||||||
(defn format-amount
|
(defn format-amount
|
||||||
[amount decimals]
|
[amount decimals]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.ens.core :as ens]
|
[status-im.ens.core :as ens]
|
||||||
[status-im.ethereum.core :as ethereum]
|
[status-im.ethereum.core :as ethereum]
|
||||||
[status-im.utils.money :as money]))
|
[utils.money :as money]))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:multiaccount/usernames
|
:multiaccount/usernames
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
[status-im.ethereum.tokens :as tokens]
|
[status-im.ethereum.tokens :as tokens]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[status-im.signing.gas :as signing.gas]
|
[status-im.signing.gas :as signing.gas]
|
||||||
[status-im.utils.money :as money]
|
[utils.money :as money]
|
||||||
[status-im.wallet.db :as wallet.db]))
|
[status-im.wallet.db :as wallet.db]))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[status-im.notifications.core :as notifications]
|
[status-im.notifications.core :as notifications]
|
||||||
[utils.datetime :as datetime]
|
[utils.datetime :as datetime]
|
||||||
[status-im.utils.money :as money]
|
[utils.money :as money]
|
||||||
[status-im.wallet.db :as wallet.db]
|
[status-im.wallet.db :as wallet.db]
|
||||||
[status-im.wallet.utils :as wallet.utils]))
|
[status-im.wallet.utils :as wallet.utils]))
|
||||||
|
|
||||||
@ -69,11 +69,12 @@
|
|||||||
(reduce (fn [acc [hash transaction]]
|
(reduce (fn [acc [hash transaction]]
|
||||||
(assoc acc
|
(assoc acc
|
||||||
hash
|
hash
|
||||||
(enrich-transaction transaction contacts native-currency))) ;;TODO this doesn't look
|
(enrich-transaction transaction contacts native-currency))) ;;TODO this doesn't
|
||||||
;;good for performance,
|
;;look good for
|
||||||
;;we need to calculate
|
;;performance, we
|
||||||
;;this only once for each
|
;;need to calculate
|
||||||
;;transaction
|
;;this only once for
|
||||||
|
;;each transaction
|
||||||
{}
|
{}
|
||||||
transactions)))
|
transactions)))
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
[status-im.ethereum.core :as ethereum]
|
[status-im.ethereum.core :as ethereum]
|
||||||
[status-im.ethereum.tokens :as tokens]
|
[status-im.ethereum.tokens :as tokens]
|
||||||
[status-im.utils.currency :as currency]
|
[status-im.utils.currency :as currency]
|
||||||
[status-im.utils.money :as money]
|
[utils.money :as money]
|
||||||
[status-im2.config :as config]
|
[status-im2.config :as config]
|
||||||
[utils.i18n :as i18n]))
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
(:require [cljs.test :refer [deftest is testing]]
|
(:require [cljs.test :refer [deftest is testing]]
|
||||||
[re-frame.db :as rf-db]
|
[re-frame.db :as rf-db]
|
||||||
[test-helpers.unit :as h]
|
[test-helpers.unit :as h]
|
||||||
[status-im.utils.money :as money]
|
[utils.money :as money]
|
||||||
[status-im2.subs.wallet.wallet :as wallet]
|
[status-im2.subs.wallet.wallet :as wallet]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
@ -35,11 +35,194 @@
|
|||||||
(new BigNumber (normalize (str n)))
|
(new BigNumber (normalize (str n)))
|
||||||
(catch :default _ nil))))
|
(catch :default _ nil))))
|
||||||
|
|
||||||
|
(defn greater-than-or-equals
|
||||||
|
[^js bn1 ^js bn2]
|
||||||
|
(.greaterThanOrEqualTo bn1 bn2))
|
||||||
|
|
||||||
|
(defn greater-than
|
||||||
|
[bn1 bn2]
|
||||||
|
(.greaterThan ^js bn1 bn2))
|
||||||
|
|
||||||
|
(defn equal-to
|
||||||
|
[bn1 bn2]
|
||||||
|
(.eq ^js bn1 bn2))
|
||||||
|
|
||||||
|
(defn sub
|
||||||
|
[bn1 bn2]
|
||||||
|
(.sub ^js bn1 bn2))
|
||||||
|
|
||||||
|
(defn valid?
|
||||||
|
[^js bn]
|
||||||
|
(when bn
|
||||||
|
(greater-than-or-equals bn 0)))
|
||||||
|
|
||||||
|
(defn from-decimal
|
||||||
|
[n]
|
||||||
|
(when n
|
||||||
|
(str "1" (string/join (repeat n "0")))))
|
||||||
|
|
||||||
|
(def eth-units
|
||||||
|
{:wei (bignumber "1")
|
||||||
|
:kwei (bignumber (from-decimal 3))
|
||||||
|
:mwei (bignumber (from-decimal 6))
|
||||||
|
:gwei (bignumber (from-decimal 9))
|
||||||
|
:szabo (bignumber (from-decimal 12))
|
||||||
|
:finney (bignumber (from-decimal 15))
|
||||||
|
:eth (bignumber (from-decimal 18))
|
||||||
|
:keth (bignumber (from-decimal 21))
|
||||||
|
:meth (bignumber (from-decimal 24))
|
||||||
|
:geth (bignumber (from-decimal 27))
|
||||||
|
:teth (bignumber (from-decimal 30))})
|
||||||
|
|
||||||
|
(defn wei->
|
||||||
|
[unit n]
|
||||||
|
(when-let [^js bn (bignumber n)]
|
||||||
|
(.dividedBy bn (eth-units unit))))
|
||||||
|
|
||||||
|
(defn ->wei
|
||||||
|
[unit n]
|
||||||
|
(when-let [^js bn (bignumber n)]
|
||||||
|
(.times bn (eth-units unit))))
|
||||||
|
|
||||||
|
(defn to-fixed
|
||||||
|
([^js bn]
|
||||||
|
(when bn
|
||||||
|
(.toFixed bn)))
|
||||||
|
([^js bn b]
|
||||||
|
(when bn
|
||||||
|
(.toFixed bn b))))
|
||||||
|
|
||||||
|
(defn to-number
|
||||||
|
[^js bn]
|
||||||
|
(when bn
|
||||||
|
(.toNumber bn)))
|
||||||
|
|
||||||
|
(defn to-string
|
||||||
|
([^js bn]
|
||||||
|
(to-string bn 10))
|
||||||
|
([^js bn base]
|
||||||
|
(when bn
|
||||||
|
(.toString bn base))))
|
||||||
|
|
||||||
|
(defn to-hex
|
||||||
|
[^js bn]
|
||||||
|
(str "0x" (to-string bn 16)))
|
||||||
|
|
||||||
|
(defn wei->str
|
||||||
|
([unit n display-unit]
|
||||||
|
(str (to-fixed (wei-> unit n)) " " display-unit))
|
||||||
|
([unit n] (wei->str unit n (string/upper-case (name unit)))))
|
||||||
|
|
||||||
|
(defn wei->ether
|
||||||
|
[n]
|
||||||
|
(wei-> :eth n))
|
||||||
|
|
||||||
|
(defn wei->gwei
|
||||||
|
[n]
|
||||||
|
(wei-> :gwei n))
|
||||||
|
|
||||||
|
(defn ether->wei
|
||||||
|
[^js bn]
|
||||||
|
(when bn
|
||||||
|
(.times bn ^js (bignumber 1e18))))
|
||||||
|
|
||||||
|
(defn token->unit
|
||||||
|
[n decimals]
|
||||||
|
(when-let [^js bn (bignumber n)]
|
||||||
|
(when-let [d (from-decimal decimals)]
|
||||||
|
(.dividedBy bn ^js (bignumber d)))))
|
||||||
|
|
||||||
|
(defn unit->token
|
||||||
|
[n decimals]
|
||||||
|
(when-let [^js bn (bignumber n)]
|
||||||
|
(when-let [d (from-decimal decimals)]
|
||||||
|
(.times bn ^js (bignumber d)))))
|
||||||
|
|
||||||
|
;;NOTE(goranjovic) - We have two basic representations of values that refer to cryptocurrency amounts:
|
||||||
|
;;formatted and
|
||||||
|
;; internal. Formatted representation is the one we show on screens and include in reports, whereas
|
||||||
|
;; internal
|
||||||
|
;; representation is the one that we pass on to ethereum network for execution, transfer, etc.
|
||||||
|
;; The difference between the two depends on the number of decimals, i.e. internal representation is
|
||||||
|
;; expressed in terms
|
||||||
|
;; of a whole number of smallest divisible parts of the formatted value.
|
||||||
|
;;
|
||||||
|
;; E.g. for Ether, it's smallest part is wei or 10^(-18) of 1 ether
|
||||||
|
;; for arbitrary ERC20 token the smallest part is 10^(-decimals) of 1 token
|
||||||
|
;;
|
||||||
|
;; Different tokens can have different number of allowed decimals, so it's neccessary to include the
|
||||||
|
;; decimals parameter
|
||||||
|
;; to get the amount scale right.
|
||||||
|
|
||||||
|
(defn formatted->internal
|
||||||
|
[n symbol decimals]
|
||||||
|
(if (= :ETH symbol)
|
||||||
|
(ether->wei n)
|
||||||
|
(unit->token n decimals)))
|
||||||
|
|
||||||
|
(defn internal->formatted
|
||||||
|
[n symbol decimals]
|
||||||
|
(if (= :ETH symbol)
|
||||||
|
(wei->ether n)
|
||||||
|
(token->unit n decimals)))
|
||||||
|
|
||||||
|
(defn fee-value
|
||||||
|
[gas gas-price]
|
||||||
|
(.times ^js (bignumber gas) ^js (bignumber gas-price)))
|
||||||
|
|
||||||
|
(defn crypto->fiat
|
||||||
|
[crypto fiat-price]
|
||||||
|
(when-let [^js bn (bignumber crypto)]
|
||||||
|
(.times bn ^js (bignumber fiat-price))))
|
||||||
|
|
||||||
|
(defn percent-change
|
||||||
|
[from to]
|
||||||
|
(let [^js bnf (bignumber from)
|
||||||
|
^js bnt (bignumber to)]
|
||||||
|
(when (and bnf bnt)
|
||||||
|
(-> ^js (.dividedBy bnf bnt)
|
||||||
|
^js (.minus 1)
|
||||||
|
^js (.times 100)))))
|
||||||
|
|
||||||
(defn with-precision
|
(defn with-precision
|
||||||
[n decimals]
|
[n decimals]
|
||||||
(when-let [^js bn (bignumber n)]
|
(when-let [^js bn (bignumber n)]
|
||||||
(.round bn decimals)))
|
(.round bn decimals)))
|
||||||
|
|
||||||
|
(defn sufficient-funds?
|
||||||
|
[^js amount ^js balance]
|
||||||
|
(when (and amount balance)
|
||||||
|
(.greaterThanOrEqualTo balance amount)))
|
||||||
|
|
||||||
|
(defn fiat-amount-value
|
||||||
|
[amount-str from to prices]
|
||||||
|
(-> amount-str
|
||||||
|
(js/parseFloat)
|
||||||
|
bignumber
|
||||||
|
(crypto->fiat (get-in prices [from to] ^js (bignumber 0)))
|
||||||
|
(with-precision 2)
|
||||||
|
str))
|
||||||
|
|
||||||
|
(defn add
|
||||||
|
[bn1 n2]
|
||||||
|
(.add ^js bn1 n2))
|
||||||
|
|
||||||
|
(defn mul
|
||||||
|
[bn1 bn2]
|
||||||
|
(.mul ^js bn1 bn2))
|
||||||
|
|
||||||
|
(defn mul-and-round
|
||||||
|
[bn1 bn2]
|
||||||
|
(.round (.mul ^js bn1 bn2) 0))
|
||||||
|
|
||||||
|
(defn div
|
||||||
|
[bn1 bn2]
|
||||||
|
(.dividedBy ^js bn1 bn2))
|
||||||
|
|
||||||
|
(defn div-and-round
|
||||||
|
[bn1 bn2]
|
||||||
|
(.round (.dividedBy ^js bn1 bn2) 0))
|
||||||
|
|
||||||
(defn format-amount
|
(defn format-amount
|
||||||
"Format `amount` to thousands or millions. Return nil if `amount` is not truthy."
|
"Format `amount` to thousands or millions. Return nil if `amount` is not truthy."
|
||||||
[amount]
|
[amount]
|
||||||
|
@ -1,7 +1,21 @@
|
|||||||
(ns utils.money-test
|
(ns utils.money-test
|
||||||
(:require [cljs.test :refer-macros [deftest is are]]
|
(:require [cljs.test :refer-macros [deftest testing is are]]
|
||||||
[utils.money :as money]))
|
[utils.money :as money]))
|
||||||
|
|
||||||
|
(deftest wei->ether
|
||||||
|
(testing "Numeric input, 15 significant digits"
|
||||||
|
(is (= (str (money/wei->ether 111122223333444000))
|
||||||
|
"0.111122223333444")))
|
||||||
|
(testing "String input, 18 significant digits"
|
||||||
|
(is (= (str (money/wei->ether "111122223333441239"))
|
||||||
|
"0.111122223333441239"))))
|
||||||
|
|
||||||
|
(deftest valid?
|
||||||
|
(is (not (true? (money/valid? nil))))
|
||||||
|
(is (true? (money/valid? (money/bignumber 0))))
|
||||||
|
(is (true? (money/valid? (money/bignumber 1))))
|
||||||
|
(is (not (true? (money/valid? (money/bignumber -1))))))
|
||||||
|
|
||||||
(deftest normalize
|
(deftest normalize
|
||||||
(is (= nil (money/normalize nil)))
|
(is (= nil (money/normalize nil)))
|
||||||
(is (= "1" (money/normalize " 1 ")))
|
(is (= "1" (money/normalize " 1 ")))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user