Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5a48dc06d | ||
|
|
4c604abe5b | ||
|
|
de4e233884 |
@@ -118,13 +118,61 @@
|
||||
"M2.79504 9.01494C2.89473 8.85584 3.00297 8.70977 3.11963 8.5761C3.90594 7.67512 4.97212 7.45024 5.99992 7.45024C7.02772 7.45024 8.0939 7.67512 8.88021 8.5761C8.99688 8.70978 9.10512 8.85585 9.2048 9.01495C8.9501 9.28561 8.66149 9.52401 8.34577 9.72335C8.25403 9.55824 8.15512 9.41818 8.05145 9.29939C7.56503 8.74204 6.88121 8.55024 5.99992 8.55024C5.11862 8.55024 4.43481 8.74204 3.94839 9.29939C3.84472 9.41818 3.74582 9.55824 3.65408 9.72334C3.33835 9.524 3.04975 9.2856 2.79504 9.01494ZM5.99992 3.5502C5.47525 3.5502 5.04992 3.97552 5.04992 4.5002C5.04992 5.02487 5.47525 5.4502 5.99992 5.4502C6.52459 5.4502 6.94992 5.02487 6.94992 4.5002C6.94992 3.97552 6.52459 3.5502 5.99992 3.5502ZM3.94992 4.5002C3.94992 3.36801 4.86773 2.4502 5.99992 2.4502C7.1321 2.4502 8.04992 3.36801 8.04992 4.5002C8.04992 5.63238 7.1321 6.5502 5.99992 6.5502C4.86773 6.5502 3.94992 5.63238 3.94992 4.5002Z"
|
||||
:fill color-2}]])
|
||||
|
||||
(defn- contact-20
|
||||
[{:keys [color color-2]
|
||||
:or {color colors/neutral-100
|
||||
color-2 colors/white}
|
||||
:as props}]
|
||||
[container props
|
||||
[svg/circle
|
||||
{:cx 10
|
||||
:cy 10
|
||||
:r 7.5
|
||||
:fill color}]
|
||||
[svg/path
|
||||
{:d
|
||||
"M8.65002 7.99998C8.65002 7.25439 9.25443 6.64998 10 6.64998C10.7456 6.64998 11.35 7.25439 11.35 7.99998C11.35 8.74556 10.7456 9.34998 10 9.34998C9.25443 9.34998 8.65002 8.74556 8.65002 7.99998ZM10 5.34998C8.53646 5.34998 7.35002 6.53642 7.35002 7.99998C7.35002 9.46353 8.53646 10.65 10 10.65C11.4636 10.65 12.65 9.46353 12.65 7.99998C12.65 6.53642 11.4636 5.34998 10 5.34998ZM10 13.65C8.67557 13.65 7.53064 14.4186 6.98692 15.5341C6.60094 15.3235 6.23942 15.0737 5.90771 14.79C6.69408 13.3369 8.23179 12.35 10 12.35C11.7682 12.35 13.306 13.3369 14.0923 14.79C13.7606 15.0737 13.3991 15.3235 13.0131 15.5341C12.4694 14.4186 11.3245 13.65 10 13.65Z"
|
||||
:fill color-2}]])
|
||||
|
||||
(defn- verified-20
|
||||
[{:keys [color color-2]
|
||||
:or {color colors/neutral-100
|
||||
color-2 colors/white}
|
||||
:as props}]
|
||||
[container props
|
||||
[svg/path
|
||||
{:d
|
||||
"M18 10C18 8.77003 17.1118 7.74751 15.9418 7.53891C16.6216 6.56407 16.5267 5.21294 15.6569 4.34321C14.7872 3.47344 13.436 3.37852 12.4611 4.05845C12.2526 2.88834 11.23 2 10 2C8.77 2 7.74747 2.88827 7.53889 4.05832C6.56406 3.37846 5.21292 3.47339 4.34318 4.34313C3.47343 5.21288 3.3785 6.56404 4.05839 7.53888C2.88831 7.74743 2 8.76998 2 10C2 11.23 2.88824 12.2525 4.05826 12.4611C3.3784 13.4359 3.47333 14.7871 4.34307 15.6568C5.21284 16.5266 6.56403 16.6215 7.53887 15.9416C7.74741 17.1117 8.76996 18 10 18C11.23 18 12.2525 17.1117 12.4611 15.9417C13.4359 16.6215 14.7871 16.5266 15.6568 15.6569C16.5265 14.7871 16.6215 13.436 15.9416 12.4611C17.1117 12.2526 18 11.23 18 10Z"
|
||||
:fill color}]
|
||||
[svg/path
|
||||
{:d "M7.25 10.75L9.25 12.25L12.75 7.75"
|
||||
:stroke color-2
|
||||
:stroke-width "1.2"}]])
|
||||
|
||||
(defn- untrustworthy-20
|
||||
[{:keys [color color-2]
|
||||
:or {color colors/neutral-100
|
||||
color-2 colors/white}
|
||||
:as props}]
|
||||
[container props
|
||||
[svg/path
|
||||
{:d "M10 2L15.6569 4.34315L18 10L15.6569 15.6569L10 18L4.34315 15.6569L2 10L4.34315 4.34315L10 2Z"
|
||||
:fill color}]
|
||||
[svg/path
|
||||
{:d
|
||||
"M10.75 5.5L10.55 11.5H9.45L9.25 5.5H10.75ZM10 13C10.4142 13 10.75 13.3358 10.75 13.75C10.75 14.1642 10.4142 14.5 10 14.5C9.58579 14.5 9.25 14.1642 9.25 13.75C9.25 13.3358 9.58579 13 10 13Z"
|
||||
:fill color-2}]])
|
||||
|
||||
(def ^:private icons
|
||||
{:i/clear-20 clear-20
|
||||
:i/dropdown-20 dropdown-20
|
||||
:i/pullup-20 pullup-20
|
||||
:i/dropdown-12 dropdown-12
|
||||
:i/pullup-12 pullup-12
|
||||
:i/contact-12 contact-12})
|
||||
{:i/clear-20 clear-20
|
||||
:i/dropdown-20 dropdown-20
|
||||
:i/pullup-20 pullup-20
|
||||
:i/dropdown-12 dropdown-12
|
||||
:i/pullup-12 pullup-12
|
||||
:i/contact-12 contact-12
|
||||
:i/contact-20 contact-20
|
||||
:i/verified-20 verified-20
|
||||
:i/untrustworthy-20 untrustworthy-20})
|
||||
|
||||
(defn- append-to-keyword
|
||||
[k & xs]
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
(ns quo.components.text-combinations.username.component-spec
|
||||
(:require [quo.components.text-combinations.username.view :as username]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(defn test-all-status
|
||||
[component-to-render component-props]
|
||||
(h/test "Verified status"
|
||||
(h/render [component-to-render (assoc component-props :status :verified)])
|
||||
(h/is-truthy (h/get-by-label-text :username-status-icon)))
|
||||
|
||||
(h/test "Contact status"
|
||||
(h/render [component-to-render (assoc component-props :status :contact)])
|
||||
(h/is-truthy (h/get-by-label-text :username-status-icon)))
|
||||
|
||||
(h/test "Untrustworthy status"
|
||||
(h/render [component-to-render (assoc component-props :status :untrustworthy)])
|
||||
(h/is-truthy (h/get-by-label-text :username-status-icon)))
|
||||
|
||||
(h/test "Untrustworthy contact status"
|
||||
(h/render [component-to-render (assoc component-props :status :untrustworthy-contact)])
|
||||
(let [icons (h/get-all-by-label-text :username-status-icon)]
|
||||
(h/is-truthy (aget icons 0))
|
||||
(h/is-truthy (aget icons 1))))
|
||||
|
||||
(h/test "Blocked status"
|
||||
(h/render [component-to-render (assoc component-props :status :blocked)])
|
||||
(h/is-truthy (h/get-by-label-text :username-status-icon))))
|
||||
|
||||
(h/describe "Text combinations - Username"
|
||||
(h/test "Renders default"
|
||||
(h/render [username/view {:username "Test username"}])
|
||||
(h/is-truthy (h/get-by-text "Test username")))
|
||||
|
||||
(h/describe "Render different :name-type values"
|
||||
(h/describe "default"
|
||||
(let [props {:name-type :default
|
||||
:username "Test username"}]
|
||||
|
||||
(h/test "default render"
|
||||
(h/render [username/view props])
|
||||
(h/is-truthy (h/get-by-text "Test username")))
|
||||
|
||||
(h/describe "All status are rendered"
|
||||
(test-all-status username/view props))))
|
||||
|
||||
(h/describe "ens"
|
||||
(let [props {:name-type :ens
|
||||
:username "test-username.eth"}]
|
||||
|
||||
(h/test "no status render"
|
||||
(h/render [username/view props])
|
||||
(h/is-truthy (h/get-by-text "test-username.eth")))
|
||||
|
||||
(h/describe "All status are rendered"
|
||||
(test-all-status username/view props))))
|
||||
|
||||
(h/describe "nickname"
|
||||
(let [props {:name-type :nickname
|
||||
:username "Nickname"
|
||||
:name "Real name"}]
|
||||
|
||||
(h/test "no status render"
|
||||
(h/render [username/view props])
|
||||
(h/is-truthy (h/get-by-text "Nickname"))
|
||||
(h/is-truthy (h/get-by-text "Real name")))
|
||||
|
||||
(h/describe "All status are rendered"
|
||||
(test-all-status username/view props))))))
|
||||
@@ -0,0 +1,30 @@
|
||||
(ns quo.components.text-combinations.username.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def container
|
||||
{:flex-direction :row
|
||||
:height 32})
|
||||
|
||||
(def username-text-container
|
||||
{:flex-direction :row
|
||||
:align-items :flex-end})
|
||||
|
||||
(defn real-name-text
|
||||
[theme blur?]
|
||||
{:color (if blur?
|
||||
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
(colors/theme-colors colors/neutral-60 colors/neutral-40 theme))})
|
||||
|
||||
(defn real-name-dot
|
||||
[theme blur?]
|
||||
(assoc (real-name-text theme blur?) :margin-horizontal 6))
|
||||
|
||||
(defn status-icon-container
|
||||
[name-type status]
|
||||
(cond-> {:flex-direction :row
|
||||
:margin-left 4}
|
||||
(#{:default :ens} name-type) (assoc :margin-top 8
|
||||
:margin-bottom 4)
|
||||
(= :nickname name-type) (assoc :margin-top 10
|
||||
:margin-bottom 2)
|
||||
(= status :untrustworthy-contact) (assoc :margin-right 2)))
|
||||
@@ -0,0 +1,57 @@
|
||||
(ns quo.components.text-combinations.username.view
|
||||
(:require [quo.components.icon :as icon]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.text-combinations.username.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- username-text
|
||||
[{:keys [theme name-type username blur?]
|
||||
real-name :name}]
|
||||
[rn/view {:style style/username-text-container}
|
||||
[text/text
|
||||
{:size :heading-1
|
||||
:weight :semi-bold}
|
||||
username]
|
||||
(when (= name-type :nickname)
|
||||
[:<>
|
||||
[text/text
|
||||
{:style (style/real-name-dot theme blur?)
|
||||
:size :paragraph-1
|
||||
:weight :medium}
|
||||
"∙"]
|
||||
[text/text
|
||||
{:style (style/real-name-text theme blur?)
|
||||
:size :paragraph-1
|
||||
:weight :medium}
|
||||
real-name]])])
|
||||
|
||||
(defn- icon-20
|
||||
[icon-name theme color]
|
||||
[icon/icon icon-name
|
||||
{:accessibility-label :username-status-icon
|
||||
:size 20
|
||||
:color (colors/resolve-color color theme)}])
|
||||
|
||||
(defn status-icon
|
||||
[{:keys [theme name-type status]
|
||||
:or {name-type :default}}]
|
||||
[rn/view {:style (style/status-icon-container name-type status)}
|
||||
(case status
|
||||
:verified [icon-20 :i/verified theme :success]
|
||||
:contact [icon-20 :i/contact theme :blue]
|
||||
:untrustworthy [icon-20 :i/untrustworthy theme :danger]
|
||||
:blocked [icon-20 :i/block theme :danger]
|
||||
:untrustworthy-contact [:<>
|
||||
[icon-20 :i/untrustworthy theme :danger]
|
||||
[icon-20 :i/contact theme :blue]]
|
||||
nil)])
|
||||
|
||||
(defn view-internal
|
||||
[props]
|
||||
[rn/view {:style style/container}
|
||||
[username-text props]
|
||||
[status-icon props]])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -6,14 +6,14 @@
|
||||
(h/describe "Wallet: Token Input"
|
||||
(h/test "Token label renders"
|
||||
(h/render [token-input/view
|
||||
{:token :snt
|
||||
{:token {:symbol "snt"}
|
||||
:currency :eur
|
||||
:conversion 1}])
|
||||
(h/is-truthy (h/get-by-text "SNT")))
|
||||
|
||||
(h/test "Amount renders"
|
||||
(h/render [token-input/view
|
||||
{:token :snt
|
||||
{:token {:symbol "snt"}
|
||||
:currency :eur
|
||||
:conversion 1}])
|
||||
(h/is-truthy (h/get-by-text "€0.00"))))
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
:align-items :flex-end}}
|
||||
[rn/image
|
||||
{:style style/token
|
||||
:source (resources/get-token token)}]
|
||||
:source (resources/get-token (keyword (string/lower-case token)))}]
|
||||
[rn/text-input
|
||||
(cond-> {:auto-focus true
|
||||
:ref #(reset! input-ref %)
|
||||
|
||||
@@ -141,6 +141,7 @@
|
||||
quo.components.tags.token-tag.view
|
||||
quo.components.text-combinations.channel-name.view
|
||||
quo.components.text-combinations.standard-title.view
|
||||
quo.components.text-combinations.username.view
|
||||
quo.components.text-combinations.view
|
||||
quo.components.wallet.account-card.view
|
||||
quo.components.wallet.account-origin.view
|
||||
@@ -385,6 +386,7 @@
|
||||
(def channel-name quo.components.text-combinations.channel-name.view/view)
|
||||
(def standard-title quo.components.text-combinations.standard-title.view/view)
|
||||
(def text-combinations quo.components.text-combinations.view/view)
|
||||
(def username quo.components.text-combinations.username.view/view)
|
||||
|
||||
;;;; Wallet
|
||||
(def account-card quo.components.wallet.account-card.view/view)
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
[quo.components.tags.summary-tag.component-spec]
|
||||
[quo.components.tags.tiny-tag.component-spec]
|
||||
[quo.components.text-combinations.channel-name.component-spec]
|
||||
[quo.components.text-combinations.username.component-spec]
|
||||
[quo.components.wallet.account-card.component-spec]
|
||||
[quo.components.wallet.account-origin.component-spec]
|
||||
[quo.components.wallet.account-overview.component-spec]
|
||||
|
||||
@@ -285,10 +285,6 @@
|
||||
(get-in colors-map [color suffix]))))
|
||||
|
||||
(defn- resolve-color*
|
||||
"(resolve-color color theme opacity)
|
||||
color hex string or keyword (resolves from custom, network and semantic colors)
|
||||
theme :light/:dark
|
||||
opacity 0-100 (optional) - if set theme is ignored and goes to 50 suffix internally"
|
||||
([color theme]
|
||||
(resolve-color* color theme nil))
|
||||
([color theme opacity]
|
||||
@@ -300,7 +296,12 @@
|
||||
suffix (get-from-colors-map suffix)
|
||||
opacity (alpha (/ opacity 100))))))
|
||||
|
||||
(def resolve-color (memoize resolve-color*))
|
||||
(def resolve-color
|
||||
"(resolve-color color theme opacity)
|
||||
color hex string or keyword (resolves from custom, network and semantic colors)
|
||||
theme :light/:dark
|
||||
opacity 0-100 (optional) - if set theme is ignored and goes to 50 suffix internally"
|
||||
(memoize resolve-color*))
|
||||
|
||||
(def ^{:deprecated true :superseded-by "resolve-color"}
|
||||
custom-color
|
||||
|
||||
@@ -172,8 +172,7 @@
|
||||
:use-mailservers? true
|
||||
:recovered recovered}
|
||||
config/default-multiaccount)
|
||||
;; The address from which we derive any chat
|
||||
;; account/encryption keys
|
||||
;; The address from which we derive any chat account/encryption keys
|
||||
eip1581-address
|
||||
(assoc :eip1581-address eip1581-address)
|
||||
save-mnemonic?
|
||||
|
||||
@@ -393,3 +393,15 @@
|
||||
|
||||
(def ^:const status-address-domain ".stateofus.eth")
|
||||
(def ^:const eth-address-domain ".eth")
|
||||
|
||||
(def ^:const gas-rate-low 0)
|
||||
(def ^:const gas-rate-medium 1)
|
||||
(def ^:const gas-rate-high 2)
|
||||
|
||||
(def ^:const send-type-transfer 0)
|
||||
(def ^:const send-type-ens-register 1)
|
||||
(def ^:const send-type-ens-release 2)
|
||||
(def ^:const send-type-ens-set-pub-key 3)
|
||||
(def ^:const send-type-stickers-buy 4)
|
||||
(def ^:const send-type-bridge 5)
|
||||
(def ^:const send-type-erc-721-transfer 6)
|
||||
|
||||
@@ -166,6 +166,7 @@
|
||||
[status-im2.contexts.quo-preview.text-combinations.preview :as
|
||||
text-combinations]
|
||||
[status-im2.contexts.quo-preview.text-combinations.standard-title :as standard-title]
|
||||
[status-im2.contexts.quo-preview.text-combinations.username :as username]
|
||||
[status-im2.contexts.quo-preview.wallet.account-card :as account-card]
|
||||
[status-im2.contexts.quo-preview.wallet.account-origin :as account-origin]
|
||||
[status-im2.contexts.quo-preview.wallet.account-overview :as
|
||||
@@ -461,7 +462,9 @@
|
||||
{:name :channel-name
|
||||
:component channel-name/view}
|
||||
{:name :standard-title
|
||||
:component standard-title/view}]
|
||||
:component standard-title/view}
|
||||
{:name :username
|
||||
:component username/view}]
|
||||
:wallet [{:name :account-card :component account-card/view}
|
||||
{:name :account-origin :component account-origin/view}
|
||||
{:name :account-overview
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
(ns status-im2.contexts.quo-preview.text-combinations.username
|
||||
(:require [quo.core :as quo]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
|
||||
(def descriptor
|
||||
[{:key :name-type
|
||||
:type :select
|
||||
:options [{:key :default}
|
||||
{:key :ens
|
||||
:value "ENS"}
|
||||
{:key :nickname}]}
|
||||
{:key :username
|
||||
:type :text}
|
||||
{:key :name
|
||||
:type :text}
|
||||
{:key :status
|
||||
:type :select
|
||||
:options [{:key nil
|
||||
:value "(Nothing)"}
|
||||
{:key :verified}
|
||||
{:key :contact}
|
||||
{:key :untrustworthy}
|
||||
{:key :untrustworthy-contact}
|
||||
{:key :blocked}]}
|
||||
{:key :blur?
|
||||
:type :boolean}])
|
||||
|
||||
(defn- set-username-based-on-name-type
|
||||
[_ ratom {previous-type :name-type} {new-type :name-type}]
|
||||
(when (not= previous-type new-type)
|
||||
(swap! ratom assoc
|
||||
:username
|
||||
(if (= new-type :ens)
|
||||
"juan.eth"
|
||||
"Juanito Mdz"))))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [state (reagent/atom {:name-type :default
|
||||
:username "Juanito Mdz"
|
||||
:name "Juan Méndez"
|
||||
:status nil
|
||||
:blur? true})
|
||||
_ (add-watch state :on-state-change set-username-based-on-name-type)]
|
||||
(fn []
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
:descriptor descriptor
|
||||
:show-blur-background? true
|
||||
:blur? (:blur? @state)}
|
||||
[quo/username @state]])))
|
||||
@@ -15,6 +15,7 @@
|
||||
(defn get-derivation-path
|
||||
[number-of-accounts]
|
||||
(str constants/path-wallet-root "/" number-of-accounts))
|
||||
|
||||
(defn format-derivation-path
|
||||
[path]
|
||||
(string/replace path "/" " / "))
|
||||
@@ -43,12 +44,15 @@
|
||||
(when balance-in-chain
|
||||
(calculate-raw-balance (:raw-balance balance-in-chain) decimals))))
|
||||
|
||||
(defn calculate-balance-for-token
|
||||
[token]
|
||||
(* (total-token-value-in-all-chains token)
|
||||
(-> token :market-values-per-currency :usd :price)))
|
||||
|
||||
(defn calculate-balance
|
||||
[tokens-in-account]
|
||||
(->> tokens-in-account
|
||||
(map (fn [token]
|
||||
(* (total-token-value-in-all-chains token)
|
||||
(-> token :market-values-per-currency :usd :price))))
|
||||
(map #(calculate-balance-for-token %))
|
||||
(reduce +)))
|
||||
|
||||
(defn network-list
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
(ns status-im2.contexts.wallet.send.events
|
||||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[status-im2.constants :as constants]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.datetime :as datetime]
|
||||
[utils.money :as money]
|
||||
[utils.number]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/reg-event-fx :wallet/suggested-routes-success
|
||||
(fn [{:keys [db]} [suggested-routes timestamp]]
|
||||
(when (= (get-in db [:wallet :ui :send :suggested-routes-call-timestamp]) timestamp)
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :suggested-routes] suggested-routes)
|
||||
(assoc-in [:wallet :ui :send :route] (first (:Best suggested-routes)))
|
||||
(assoc-in [:wallet :ui :send :loading-suggested-routes?] false))})))
|
||||
|
||||
(rf/reg-event-fx :wallet/suggested-routes-error
|
||||
(fn [{:keys [db]} [_error]]
|
||||
{:db (-> db
|
||||
(update-in [:wallet :ui :send] dissoc :suggested-routes)
|
||||
(update-in [:wallet :ui :send] dissoc :route)
|
||||
(assoc-in [:wallet :ui :send :loading-suggested-routes?] false))}))
|
||||
|
||||
(rf/reg-event-fx :wallet/clean-suggested-routes
|
||||
(fn [{:keys [db]}]
|
||||
{:db (-> db
|
||||
(update-in [:wallet :ui :send] dissoc :suggested-routes)
|
||||
(update-in [:wallet :ui :send] dissoc :route)
|
||||
(update-in [:wallet :ui :send] dissoc :loading-suggested-routes?))}))
|
||||
|
||||
(rf/reg-event-fx :wallet/select-send-address
|
||||
(fn [{:keys [db]} [address]]
|
||||
{:db (assoc-in db [:wallet :ui :send :to-address] address)}))
|
||||
|
||||
(rf/reg-event-fx :wallet/send-select-token
|
||||
(fn [{:keys [db]} [token stack-id]]
|
||||
{:db (assoc-in db [:wallet :ui :send :token] token)
|
||||
:fx [[:navigate-to-within-stack [:wallet-send-input-amount stack-id]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/send-select-amount
|
||||
(fn [{:keys [db]} [amount stack-id]]
|
||||
{:db (assoc-in db [:wallet :ui :send :amount] amount)
|
||||
:fx [[:navigate-to-within-stack [:wallet-transaction-confirmation stack-id]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/get-suggested-routes
|
||||
(fn [{:keys [db]} [amount]]
|
||||
(let [wallet-address (get-in db [:wallet :current-viewing-account-address])
|
||||
token (get-in db [:wallet :ui :send :token])
|
||||
to-address (get-in db [:wallet :ui :send :to-address])
|
||||
token-decimal (:decimals token)
|
||||
token-id (:symbol token)
|
||||
network-preferences [constants/mainnet-chain-id]
|
||||
gas-rates constants/gas-rate-low
|
||||
amount-in (money/mul (money/bignumber amount)
|
||||
(money/from-decimal token-decimal))
|
||||
from-address wallet-address
|
||||
request-params [constants/send-type-transfer
|
||||
from-address
|
||||
to-address
|
||||
(money/to-hex amount-in)
|
||||
token-id
|
||||
[]
|
||||
[]
|
||||
network-preferences
|
||||
gas-rates
|
||||
{}]
|
||||
timestamp (datetime/timestamp)]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :loading-suggested-routes?] true)
|
||||
(assoc-in [:wallet :ui :send :suggested-routes-call-timestamp]
|
||||
timestamp))
|
||||
:json-rpc/call [{:method "wallet_getSuggestedRoutes"
|
||||
:params request-params
|
||||
:on-success (fn [suggested-routes]
|
||||
(rf/dispatch [:wallet/suggested-routes-success suggested-routes
|
||||
timestamp]))
|
||||
:on-error (fn [error]
|
||||
(rf/dispatch [:wallet/suggested-routes-error error])
|
||||
(log/error "failed to get suggested routes"
|
||||
{:event :wallet/get-suggested-routes
|
||||
:error error
|
||||
:params request-params}))}]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/send-transaction
|
||||
(fn [{:keys [db]} [password]]
|
||||
(let [route (get-in db [:wallet :ui :send :route])
|
||||
from-address (get-in db [:wallet :current-viewing-account-address])
|
||||
to-address (get-in db [:wallet :ui :send :to-address])
|
||||
from (:From route)
|
||||
token (get-in db [:wallet :ui :send :token])
|
||||
token-id (:symbol token)
|
||||
from-asset token-id
|
||||
to-asset token-id
|
||||
bridge-name (:BridgeName route)
|
||||
chain-id (:chainId from)
|
||||
multi-transaction-command {:fromAddress from-address
|
||||
:toAddress to-address
|
||||
:fromAsset from-asset
|
||||
:toAsset to-asset
|
||||
:fromAmount (:AmountOut route)
|
||||
:type 0}
|
||||
transaction-bridge
|
||||
[{:BridgeName bridge-name
|
||||
:ChainID chain-id
|
||||
:TransferTx {:From from-address
|
||||
:To to-address
|
||||
:Gas (money/to-hex (:GasAmount route))
|
||||
:GasPrice (money/to-hex (money/->wei :gwei
|
||||
(:gasPrice (:GasFees route))))
|
||||
:Value (:AmountOut route)
|
||||
:Nonce nil
|
||||
:MaxFeePerGas (money/to-hex
|
||||
(money/->wei :gwei
|
||||
(:maxFeePerGasMedium (:GasFees route))))
|
||||
:MaxPriorityFeePerGas (money/to-hex (money/->wei :gwei
|
||||
(:maxPriorityFeePerGas
|
||||
(:GasFees
|
||||
route))))
|
||||
:Input ""
|
||||
:Data "0x"}}]
|
||||
sha3-pwd (native-module/sha3 (str (security/safe-unmask-data password)))
|
||||
request-params [multi-transaction-command transaction-bridge sha3-pwd]]
|
||||
{:json-rpc/call [{:method "wallet_createMultiTransaction"
|
||||
:params request-params
|
||||
:on-success #(rf/dispatch [:dismiss-modal :wallet-select-address])
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to send transaction"
|
||||
{:event :wallet/send-transaction
|
||||
:error error
|
||||
:params request-params}))}]})))
|
||||
@@ -17,7 +17,13 @@
|
||||
:short-name "eth"
|
||||
:network-name :ethereum
|
||||
:chain-id 1
|
||||
:related-chain-id 5}]})
|
||||
:related-chain-id 5}]
|
||||
:wallet {:ui {:send {:token {:symbol "ETH"
|
||||
:decimals 18
|
||||
:total-balance 1
|
||||
:total-balance-fiat 10
|
||||
:loading-suggested-routes? false
|
||||
:route {}}}}}})
|
||||
|
||||
(h/describe "Send > input amount screen"
|
||||
(h/test "Default render"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.wallet.send.input-amount.style :as style]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -47,71 +48,88 @@
|
||||
current))
|
||||
|
||||
(defn- f-view-internal
|
||||
[{:keys [token limit rate]}]
|
||||
(let [bottom (safe-area/get-bottom)
|
||||
{:keys [currency]} (rf/sub [:profile/profile])
|
||||
networks (rf/sub [:wallet/network-details])
|
||||
;; Temporary values
|
||||
token (or token :eth)
|
||||
conversion-rate (or rate 10)
|
||||
limit-crypto (or limit 2860000.32)
|
||||
limit-fiat (* limit-crypto conversion-rate)
|
||||
input-value (reagent/atom "")
|
||||
current-limit (reagent/atom {:amount limit-crypto
|
||||
:currency token})
|
||||
handle-swap (fn [crypto?]
|
||||
(let [num-value (parse-double @input-value)]
|
||||
(reset! current-limit (if crypto?
|
||||
{:amount limit-crypto
|
||||
:currency token}
|
||||
{:amount limit-fiat
|
||||
:currency currency}))
|
||||
(when (> num-value (:amount @current-limit))
|
||||
(reset! input-value ""))))
|
||||
handle-keyboard-press (fn [v]
|
||||
(let [current-value @input-value
|
||||
new-value (make-new-input current-value v)
|
||||
num-value (or (parse-double new-value) 0)]
|
||||
(when (<= num-value (:amount @current-limit))
|
||||
(reset! input-value new-value)
|
||||
(reagent/flush))))
|
||||
handle-delete (fn [_]
|
||||
(swap! input-value #(subs % 0 (dec (count %))))
|
||||
(reagent/flush))
|
||||
handle-on-change (fn [v]
|
||||
(when (valid-input? @input-value v)
|
||||
(let [num-value (or (parse-double v) 0)
|
||||
current-limit-amount (:amount @current-limit)]
|
||||
(if (> num-value current-limit-amount)
|
||||
(reset! input-value (str current-limit-amount))
|
||||
(reset! input-value v))
|
||||
(reagent/flush))))]
|
||||
[{:keys [rate]}]
|
||||
(let [bottom (safe-area/get-bottom)
|
||||
{:keys [currency]} (rf/sub [:profile/profile])
|
||||
networks (rf/sub [:wallet/network-details])
|
||||
wallet-send (get-in (rf/sub [:wallet]) [:ui :send])
|
||||
token (:token wallet-send)
|
||||
token-symbol (:symbol token)
|
||||
limit-crypto (:total-balance token)
|
||||
limit-fiat (:total-balance-fiat token)
|
||||
conversion-rate (or rate 10)
|
||||
input-value (reagent/atom "")
|
||||
current-limit (reagent/atom {:amount limit-crypto
|
||||
:currency token-symbol})
|
||||
loading-suggested-routes? (:loading-suggested-routes? wallet-send)
|
||||
handle-swap (fn [crypto?]
|
||||
(let [num-value (parse-double @input-value)]
|
||||
(reset! current-limit (if crypto?
|
||||
{:amount limit-crypto
|
||||
:currency token-symbol}
|
||||
{:amount limit-fiat
|
||||
:currency currency}))
|
||||
(when (> num-value (:amount @current-limit))
|
||||
(reset! input-value ""))))
|
||||
handle-keyboard-press (fn [v]
|
||||
(let [current-value @input-value
|
||||
new-value (make-new-input current-value v)
|
||||
num-value (or (parse-double new-value) 0)]
|
||||
(when (and (not loading-suggested-routes?)
|
||||
(<= num-value (:amount @current-limit)))
|
||||
(reset! input-value new-value)
|
||||
(reagent/flush))))
|
||||
handle-delete (fn [_]
|
||||
(when-not loading-suggested-routes?
|
||||
(swap! input-value #(subs % 0 (dec (count %))))
|
||||
(reagent/flush)))
|
||||
handle-on-change (fn [v]
|
||||
(when (valid-input? @input-value v)
|
||||
(let [num-value (or (parse-double v) 0)
|
||||
current-limit-amount (:amount @current-limit)]
|
||||
(if (> num-value current-limit-amount)
|
||||
(reset! input-value (str current-limit-amount))
|
||||
(reset! input-value v))
|
||||
(reagent/flush))))]
|
||||
(fn [{:keys [on-confirm]
|
||||
:or {on-confirm #(js/alert "Confirmed")}}]
|
||||
(let [limit-label (make-limit-label @current-limit)
|
||||
input-num-value (parse-double @input-value)
|
||||
confirm-disabled? (or
|
||||
(empty? @input-value)
|
||||
(<= input-num-value 0)
|
||||
(> input-num-value (:amount @current-limit)))]
|
||||
:or {on-confirm #(rf/dispatch [:wallet/send-select-amount @input-value
|
||||
:wallet-send-input-amount])}}]
|
||||
(let [limit-label (make-limit-label @current-limit)
|
||||
input-num-value (parse-double @input-value)
|
||||
route (get-in (rf/sub [:wallet]) [:ui :send :route])
|
||||
loading-suggested-routes? (get-in (rf/sub [:wallet]) [:ui :send :loading-suggested-routes?])
|
||||
confirm-disabled? (or
|
||||
(nil? route)
|
||||
(empty? @input-value)
|
||||
(<= input-num-value 0)
|
||||
(> input-num-value (:amount @current-limit)))]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!))
|
||||
app-keyboard-listener (.addEventListener rn/app-state "change" dismiss-keyboard-fn)]
|
||||
#(.remove app-keyboard-listener))))
|
||||
(rn/use-effect (fn []
|
||||
(rf/dispatch [:wallet/clean-suggested-routes])
|
||||
(when-not (or
|
||||
(empty? @input-value)
|
||||
(<= input-num-value 0)
|
||||
(> input-num-value (:amount @current-limit)))
|
||||
(debounce/debounce-and-dispatch [:wallet/get-suggested-routes @input-value]
|
||||
100)))
|
||||
[@input-value])
|
||||
[rn/view
|
||||
{:style style/screen}
|
||||
[quo/page-nav
|
||||
{:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:on-press #(rf/dispatch [:navigate-back-within-stack :wallet-send-input-amount])
|
||||
:right-side :account-switcher
|
||||
:account-switcher {:customization-color :yellow
|
||||
:emoji "🎮"
|
||||
:on-press #(js/alert "Switch account")}}]
|
||||
[quo/token-input
|
||||
{:container-style style/input-container
|
||||
:token token
|
||||
:token token-symbol
|
||||
:currency currency
|
||||
:networks networks
|
||||
:title (i18n/label :t/send-limit {:limit limit-label})
|
||||
@@ -122,7 +140,16 @@
|
||||
:on-change-text (fn [text]
|
||||
(handle-on-change text))}]
|
||||
;; Network routing content to be added
|
||||
[rn/scroll-view]
|
||||
[rn/scroll-view
|
||||
{:content-container-style {:flex-grow 1
|
||||
:align-items :center
|
||||
:justify-content :center}}
|
||||
(cond loading-suggested-routes?
|
||||
[quo/text "Loading routes"]
|
||||
(and (not loading-suggested-routes?) route)
|
||||
[quo/text "Route found"]
|
||||
(and (not loading-suggested-routes?) (nil? route))
|
||||
[quo/text "Route not found"])]
|
||||
[quo/bottom-actions
|
||||
{:actions :1-action
|
||||
:button-one-label (i18n/label :t/confirm)
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
[input-value input-focused?]
|
||||
(fn []
|
||||
(let [scanned-address (rf/sub [:wallet/scanned-address])
|
||||
send-address (rf/sub [:wallet/send-address])
|
||||
send-address (get-in (rf/sub [:wallet]) [:ui :send :to-address])
|
||||
valid-ens-or-address? (rf/sub [:wallet/valid-ens-or-address?])
|
||||
chain-id (rf/sub [:chain-id])
|
||||
contacts (rf/sub [:contacts/active])]
|
||||
|
||||
@@ -19,10 +19,13 @@
|
||||
(defn- asset-component
|
||||
[]
|
||||
(fn [token _ _ _]
|
||||
(let [on-press #(js/alert "Not implemented yet")
|
||||
(let [on-press
|
||||
#(if (= (:symbol token) "ETH")
|
||||
(rf/dispatch [:wallet/send-select-token token :wallet-select-asset])
|
||||
(js/alert "Only ETH transfers are allowed."))
|
||||
total-balance-formatted (.toFixed (:total-balance token) 2)
|
||||
balance-fiat-formatted (.toFixed (:total-balance-fiat token) 2)
|
||||
currency-symbol "$"]
|
||||
balance-fiat-formatted (.toFixed (:total-balance-fiat token) 2)
|
||||
currency-symbol "$"]
|
||||
[quo/token-network
|
||||
{:token (quo.resources/get-token (keyword (string/lower-case (:symbol token))))
|
||||
:label (:name token)
|
||||
|
||||
@@ -5,14 +5,15 @@
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.common.standard-authentication.core :as standard-auth]
|
||||
[status-im2.contexts.wallet.send.transaction-confirmation.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- transaction-title
|
||||
[]
|
||||
[token amount account to-address]
|
||||
[rn/view {:style style/content-container}
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
[quo/text
|
||||
@@ -22,7 +23,7 @@
|
||||
:accessibility-label :send-label}
|
||||
(i18n/label :t/send)]
|
||||
[quo/summary-tag
|
||||
{:label "150 ETH"
|
||||
{:label (str amount " " (:symbol token))
|
||||
:type :token
|
||||
:image-source (quo.resources/get-token :eth)}]]
|
||||
[rn/view
|
||||
@@ -35,10 +36,10 @@
|
||||
:accessibility-label :send-label}
|
||||
(i18n/label :t/from)]
|
||||
[quo/summary-tag
|
||||
{:label "Collectibles vault"
|
||||
{:label (:name account)
|
||||
:type :account
|
||||
:emoji "🍑"
|
||||
:customization-color :purple}]]
|
||||
:emoji (:emoji account)
|
||||
:customization-color (:color account)}]]
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
:margin-top 4}}
|
||||
@@ -49,13 +50,11 @@
|
||||
:accessibility-label :send-label}
|
||||
(i18n/label :t/to)]
|
||||
[quo/summary-tag
|
||||
{:label "Mark Libot"
|
||||
:type :user
|
||||
:image-source (resources/get-mock-image :user-picture-male4)
|
||||
:customization-color :magenta}]]])
|
||||
{:type :address
|
||||
:label (utils/get-shortened-address to-address)}]]])
|
||||
|
||||
(defn- transaction-from
|
||||
[status-account-props theme]
|
||||
[amount account-props theme]
|
||||
[rn/view
|
||||
{:style {:padding-horizontal 20
|
||||
:padding-bottom 16}}
|
||||
@@ -68,13 +67,13 @@
|
||||
[quo/summary-info
|
||||
{:type :status-account
|
||||
:networks? true
|
||||
:values {:ethereum 150
|
||||
:optimism 50
|
||||
:arbitrum 25}
|
||||
:account-props status-account-props}]])
|
||||
:values {:ethereum amount
|
||||
:optimism 0
|
||||
:arbitrum 0}
|
||||
:account-props account-props}]])
|
||||
|
||||
(defn- transaction-to
|
||||
[user-props theme]
|
||||
[amount user-props theme]
|
||||
[rn/view
|
||||
{:style {:padding-horizontal 20
|
||||
:padding-bottom 16}}
|
||||
@@ -87,13 +86,13 @@
|
||||
[quo/summary-info
|
||||
{:type :user
|
||||
:networks? true
|
||||
:values {:ethereum 150
|
||||
:optimism 50
|
||||
:arbitrum 25}
|
||||
:values {:ethereum amount
|
||||
:optimism 0
|
||||
:arbitrum 0}
|
||||
:account-props user-props}]])
|
||||
|
||||
(defn- transaction-details
|
||||
[theme]
|
||||
[estimated-time-min max-fees-eth token amount to-address theme]
|
||||
[rn/view
|
||||
{:style {:padding-horizontal 20
|
||||
:padding-bottom 16}}
|
||||
@@ -116,7 +115,7 @@
|
||||
:status :default
|
||||
:size :small
|
||||
:title (i18n/label :t/est-time)
|
||||
:subtitle "3-5 min"}]
|
||||
:subtitle (str estimated-time-min " min")}]
|
||||
[quo/data-item
|
||||
{:container-style {:flex 1
|
||||
:height 36}
|
||||
@@ -128,7 +127,7 @@
|
||||
:status :default
|
||||
:size :small
|
||||
:title (i18n/label :t/max-fees)
|
||||
:subtitle "€188,70"}]
|
||||
:subtitle (str "$" max-fees-eth)}]
|
||||
[quo/data-item
|
||||
{:container-style {:flex 1
|
||||
:height 36}
|
||||
@@ -139,35 +138,42 @@
|
||||
:label :none
|
||||
:status :default
|
||||
:size :small
|
||||
:title (i18n/label :t/user-gets {:name "Mark"})
|
||||
:subtitle "149.99 ETH"}]]])
|
||||
:title (i18n/label :t/user-gets {:name (utils/get-shortened-address to-address)})
|
||||
:subtitle (str amount " " (:symbol token))}]]])
|
||||
|
||||
(defn- f-view-internal
|
||||
[_]
|
||||
(let [reset-slider? (reagent/atom false)
|
||||
margin-top (safe-area/get-top)
|
||||
biometric-auth? true
|
||||
on-close #(rf/dispatch [:navigate-back-within-stack :wallet-select-asset])
|
||||
status-account-props {:customization-color :purple
|
||||
:size 32
|
||||
:emoji "🍑"
|
||||
:type :default
|
||||
:name "Collectibles vault"
|
||||
:address "0x0ah...78b"}
|
||||
user-props {:full-name "M L"
|
||||
:status-indicator? false
|
||||
:size :small
|
||||
:ring-background (resources/get-mock-image :ring)
|
||||
:customization-color :blue
|
||||
:name "Mark Libot"
|
||||
:address "0x0ah...78b"
|
||||
:status-account (merge status-account-props
|
||||
{:size 16
|
||||
:name "New house"
|
||||
:emoji "🍔"})}]
|
||||
(let [margin-top (safe-area/get-top)
|
||||
biometric-auth? false
|
||||
on-close #(rf/dispatch [:navigate-back-within-stack :wallet-select-asset])
|
||||
send-transaction-data (get-in (rf/sub [:wallet]) [:ui :send])
|
||||
token (:token send-transaction-data)
|
||||
amount (:amount send-transaction-data)
|
||||
route (:route send-transaction-data)
|
||||
estimated-time-min (:EstimatedTime route)
|
||||
max-fees-eth 5.28 ; calculate gas price in fiat
|
||||
to-address (:to-address send-transaction-data)
|
||||
account (rf/sub [:wallet/current-viewing-account])
|
||||
account-props {:customization-color (:color account)
|
||||
:size 32
|
||||
:emoji (:emoji account)
|
||||
:type :default
|
||||
:name (:name account)
|
||||
:address (utils/get-shortened-address (:address account))}
|
||||
user-props {:full-name "M L"
|
||||
:status-indicator? false
|
||||
:size :small
|
||||
:ring-background (resources/get-mock-image :ring)
|
||||
:customization-color :blue
|
||||
:name "Mark Libot"
|
||||
:address "0x0ah...78b"
|
||||
:status-account (merge account-props
|
||||
{:size 16
|
||||
:name "New house"
|
||||
:emoji "🍔"})}]
|
||||
(fn [{:keys [theme]}]
|
||||
[rn/view {:style {:flex 1}}
|
||||
[quo/gradient-cover {:customization-color :purple}]
|
||||
[quo/gradient-cover {:customization-color (:color account)}]
|
||||
[rn/view {:style (style/container margin-top)}
|
||||
[quo/page-nav
|
||||
{:icon-name :i/arrow-left
|
||||
@@ -176,18 +182,18 @@
|
||||
:right-side [{:icon-name :i/advanced
|
||||
:on-press (fn callback [] nil)
|
||||
:accessibility-label "Advanced"}]}]
|
||||
[transaction-title]
|
||||
[transaction-from status-account-props theme]
|
||||
[transaction-to user-props theme]
|
||||
[transaction-details theme]
|
||||
[transaction-title token amount account to-address]
|
||||
[transaction-from amount account-props theme]
|
||||
[transaction-to amount user-props theme]
|
||||
[transaction-details estimated-time-min max-fees-eth token amount to-address theme]
|
||||
[rn/view {:style style/slide-button-container}
|
||||
[quo/slide-button
|
||||
{:size :size/s-48
|
||||
:customization-color :purple
|
||||
:on-reset (when @reset-slider? #(reset! reset-slider? false))
|
||||
:on-complete #(js/alert "Not implemented yet")
|
||||
:track-icon (if biometric-auth? :i/face-id :password)
|
||||
:track-text (i18n/label :t/slide-to-send)}]]]])))
|
||||
[standard-auth/slide-button
|
||||
{:size :size-40
|
||||
:track-text (i18n/label :t/slide-to-send)
|
||||
:customization-color (:color account)
|
||||
:on-enter-password #(rf/dispatch [:wallet/send-transaction %])
|
||||
:biometric-auth? biometric-auth?
|
||||
:auth-button-label (i18n/label :t/confirm)}]]]])))
|
||||
|
||||
(defn view-internal
|
||||
[props]
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
status-im2.contexts.shell.share.events
|
||||
status-im2.contexts.syncing.events
|
||||
status-im2.contexts.wallet.events
|
||||
status-im2.contexts.wallet.send.events
|
||||
[status-im2.db :as db]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
|
||||
@@ -156,7 +156,6 @@
|
||||
(reg-root-key-sub :wallet/scanned-address :wallet/scanned-address)
|
||||
(reg-root-key-sub :wallet/local-suggestions :wallet/local-suggestions)
|
||||
(reg-root-key-sub :wallet/valid-ens-or-address? :wallet/valid-ens-or-address?)
|
||||
(reg-root-key-sub :wallet/send-address :wallet/send-address)
|
||||
|
||||
;;debug
|
||||
(when js/goog.DEBUG
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
:<- [:wallet/balances]
|
||||
:<- [:wallet/tokens-loading?]
|
||||
(fn [[accounts balances tokens-loading?]]
|
||||
(mapv (fn [{:keys [color address type] :as account}]
|
||||
(mapv (fn [{:keys [color address] :as account}]
|
||||
(assoc account
|
||||
:customization-color color
|
||||
:type (if (= type :watch) :watch-only :empty)
|
||||
@@ -75,7 +75,7 @@
|
||||
(assoc token
|
||||
:networks (utils/network-list token networks)
|
||||
:total-balance (utils/total-token-value-in-all-chains token)
|
||||
:total-balance-fiat (utils/calculate-balance token)))
|
||||
:total-balance-fiat (utils/calculate-balance-for-token token)))
|
||||
(:tokens account))
|
||||
|
||||
sorted-tokens
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
;; 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
|
||||
;; Different tokens can have different number of allowed decimals, so it's necessary to include the
|
||||
;; decimals parameter
|
||||
;; to get the amount scale right.
|
||||
|
||||
@@ -205,10 +205,14 @@
|
||||
(with-precision 2)
|
||||
str))
|
||||
|
||||
(defn add
|
||||
(defn- add*
|
||||
[bn1 n2]
|
||||
(.add ^js bn1 n2))
|
||||
|
||||
(def add
|
||||
"Add with defaults, this version is able to receive `nil` and takes them as 0."
|
||||
(fnil add* (bignumber 0) (bignumber 0)))
|
||||
|
||||
(defn mul
|
||||
[bn1 bn2]
|
||||
(.mul ^js bn1 bn2))
|
||||
|
||||
Reference in New Issue
Block a user