[BUG #1990] Improved amount validation in wallet/send screen

This commit is contained in:
Julien Eluard 2017-10-04 16:05:57 +02:00 committed by Roman Volosovskyi
parent 10752aeb5e
commit 23eeadf95a
16 changed files with 182 additions and 183 deletions

1
.env
View File

@ -1,5 +1,4 @@
TESTFAIRY_ENABLED=0
WALLET_WIP_ENABLED=1
NOTIFICATIONS_WIP_ENABLED=1
DEBUG_LOGS_ENABLED=1
STUB_STATUS_GO=0

View File

@ -1,5 +1,4 @@
TESTFAIRY_ENABLED=1
WALLET_WIP_ENABLED=1
NOTIFICATIONS_WIP_ENABLED=1
DEBUG_LOGS_ENABLED=1
STUB_STATUS_GO=0

View File

@ -1,4 +1,3 @@
TESTFAIRY_ENABLED=0
WALLET_WIP_ENABLED=0
NOTIFICATIONS_WIP_ENABLED=0
DEBUG_LOGS_ENABLED=0

View File

@ -3,46 +3,34 @@
[status-im.components.react :as react]
[status-im.utils.platform :as platform]))
(defn- button [{:keys [on-press style text text-style disabled? fit-to-text?]}]
(defn button-text [{:keys [disabled? text-style]} label]
[react/text {:style (merge (button.styles/button-text disabled?)
text-style)
:font (if platform/android? :medium :default)
:uppercase? (get-in platform/platform-specific [:uppercase?])}
label])
(defn button [{:keys [on-press style disabled? fit-to-text?] :as props} label]
[react/touchable-highlight (merge {:underlay-color button.styles/border-color-high}
(when-not fit-to-text?
{:style button.styles/button-container})
(when (and on-press
(not disabled?))
(when (and on-press (not disabled?))
{:on-press on-press}))
[react/view {:style (merge (button.styles/button disabled?)
style)}
[react/text {:style (merge (button.styles/button-text disabled?)
text-style)
:font :medium
:uppercase? platform/android?}
text]]])
[button-text props
label]]])
(defn primary-button [{:keys [style text-style] :as m}]
(button (assoc m
(defn primary-button [{:keys [style text-style] :as m} label]
[button (assoc m
:fit-to-text? true
:style (merge button.styles/primary-button style)
:text-style (merge button.styles/primary-button-text text-style))))
:text-style (merge button.styles/primary-button-text text-style))
label])
(defn secondary-button [{:keys [style text-style] :as m}]
(button (assoc m
(defn secondary-button [{:keys [style text-style] :as m} label]
[button (assoc m
:fit-to-text? true
:style (merge button.styles/secondary-button style)
:text-style (merge button.styles/secondary-button-text text-style))))
(defn- position [i v]
(cond
(zero? i) :first
(= i (dec (count v))) :last
:else :other))
(defn buttons
([v] (buttons nil v))
([{:keys [style button-text-style]} v]
[react/view {:style (merge button.styles/buttons-container style)}
(doall
(map-indexed
(fn [i m] ^{:key i} [button (merge m
{:style (button.styles/button-bar (position i v))
:text-style button-text-style})])
v))]))
:text-style (merge button.styles/secondary-button-text text-style))
label])

View File

@ -362,6 +362,7 @@
:wallet-total-value "Total value"
:wallet-settings "Wallet Settings"
:signing-phrase-description "Sign the transaction by entering your password. Make sure that the words above match your secret signing phrase"
:wallet-insufficient-funds "Insufficient funds"
:request-transaction "Request Transaction"
:send-request "Send request"
:share "Share"
@ -385,7 +386,7 @@
:view-transaction-details "View Transaction Details"
:transaction-description "If you want to be sure you transaction will not be compromised wait until it gets at least 10 block confirmations"
:transaction-sent "Transaction Sent"
:transaction-moved-text "The transaction has ben successfully moved to “Unsigned”"
:transaction-moved-text "The transaction has been successfully moved to “Unsigned”"
:transaction-moved-title "Transaction Moved"
:sign-later-title "Sign Transaction Later?"
:sign-later-text "You will be able to sign in in the transaction history"
@ -398,7 +399,8 @@
:wallet-choose-from-contacts "Choose From Contacts"
:wallet-address-from-clipboard "Use Address From Clipboard"
:wallet-browse-photos "Browse Photos"
:validation-amount-invalid-number "Amount is not valid number"
:validation-amount-invalid "Amount is not valid"
:validation-amount-invalid-number "Amount is not a valid number"
:validation-amount-is-too-precise "Amount is too precise. The smallest unit you can send is 1 Wei (1x10^-18 ETH)"

View File

@ -7,6 +7,7 @@
[reagent.core :as reagent]
[status-im.components.icons.vector-icons :as vector-icons]
[status-im.components.animation :as animation]
[status-im.utils.money :as money]
[status-im.utils.platform :as platform]
[status-im.ui.screens.wallet.components.animations :as animations]))
@ -73,16 +74,18 @@
;;TODO (andrey) this should be choose component with the list of wallets
(views/defview choose-wallet [& [style]]
(views/letsubs [eth-balance [:eth-balance]]
(views/letsubs [balance [:balance]]
[react/view
[react/text {:style styles/label} (i18n/label :t/wallet)]
[react/view (merge styles/wallet-container
style)
[react/text {:style styles/wallet-name} "Main wallet"]
[react/text {:style styles/wallet-name} (i18n/label :t/main-wallet)]
[react/text {:style styles/wallet-value
:number-of-lines 1
:ellipsizeMode :middle}
(str eth-balance " ETH")]]]))
(if balance
(money/wei->str :eth balance)
"...")]]]))
(defn network-label
([n] (network-label [{} n]))

View File

@ -24,9 +24,12 @@
(let [amount' (string/replace amount #"," ".")
amount-splited (string/split amount' #"[.]")]
(cond
(or (nil? amount) (= amount "") (= amount "0") (re-matches #"0[,.]0*$" amount))
(or (nil? amount) (= amount "") (re-matches #"0[,.]0*$" amount))
nil
(= amount "0")
(i18n/label :t/validation-amount-invalid)
(or (js/isNaN (js/parseFloat amount'))
(try (when (<= (.toWei web3 amount' "ether") 0) true)
(catch :default err true)))

View File

@ -12,11 +12,13 @@
[status-im.i18n :as i18n]
[status-im.react-native.resources :as resources]
[status-im.utils.config :as config]
[status-im.utils.utils :as utils]
[status-im.utils.money :as money]
[status-im.utils.platform :as platform]
[status-im.utils.utils :as utils]
[status-im.ui.screens.wallet.main.styles :as styles]
[status-im.ui.screens.wallet.styles :as wallet.styles]
[status-im.components.styles :as components.styles]
[status-im.components.button.styles :as button.styles]
[status-im.ui.screens.wallet.views :as wallet.views]))
(defn- show-not-implemented! []
@ -59,6 +61,11 @@
(str (when pos-change? "+") change "%")
"-%")]]))
(defn- wallet-send []
(rf/dispatch [:navigate-to :wallet-send-transaction])
(when platform/android?
(rf/dispatch [:request-permissions [:camera]])))
(defn main-section [usd-value change error-message]
[react/view {:style styles/main-section}
(when error-message
@ -71,17 +78,13 @@
[react/text {:style styles/value-variation-title}
(i18n/label :t/wallet-total-value)]
[change-display change]]
[btn/buttons {:style styles/buttons :button-text-style styles/main-button-text}
[{:text (i18n/label :t/wallet-send)
:on-press #(do (rf/dispatch [:navigate-to :wallet-send-transaction])
(when platform/android?
(rf/dispatch [:request-permissions [:camera]])))
:disabled? (not config/wallet-wip-enabled?)}
{:text (i18n/label :t/wallet-request)
:on-press #(rf/dispatch [:navigate-to :wallet-request-transaction])
:disabled? (not config/wallet-wip-enabled?)}
{:text (i18n/label :t/wallet-exchange)
:disabled? true}]]]])
[react/view {:style (merge button.styles/buttons-container styles/buttons) :button-text-style styles/main-button-text}
[btn/button {:on-press wallet-send :style (button.styles/button-bar :first)}
(i18n/label :t/wallet-send)]
[btn/button {:on-press #(rf/dispatch [:navigate-to :wallet-request-transaction]) :style (button.styles/button-bar :other)}
(i18n/label :t/wallet-request)]
[btn/button {:disabled? true :style (button.styles/button-bar :last)}
(i18n/label :t/wallet-exchange)]]]])
(defn- token->image [id]
(case id
@ -115,14 +118,14 @@
(let [{:keys [source style]} (token->image id)]
[list/item-image source style])
[react/view {:style styles/asset-item-value-container}
[react/text {:style styles/asset-item-value} (str amount)]
[react/text {:style styles/asset-item-value} (str (money/wei->ether amount))]
[react/text {:style styles/asset-item-currency
:uppercase? true}
id]]]]
[add-asset]))
(defn asset-section [eth prices-loading? balance-loading?]
(let [assets [{:id "eth" :currency :eth :amount eth}]]
(defn asset-section [balance prices-loading? balance-loading?]
(let [assets [{:id "eth" :currency :eth :amount balance}]]
[react/view {:style styles/asset-section}
[react/text {:style styles/asset-section-title} (i18n/label :t/wallet-assets)]
[list/flat-list
@ -132,7 +135,7 @@
:refreshing (boolean (or prices-loading? balance-loading?))}]]))
(defview wallet []
(letsubs [eth-balance [:eth-balance]
(letsubs [balance [:balance]
portfolio-value [:portfolio-value]
portfolio-change [:portfolio-change]
prices-loading? [:prices-loading?]
@ -142,4 +145,4 @@
[toolbar-view]
[react/view components.styles/flex
[main-section portfolio-value portfolio-change error-message]
[asset-section eth-balance prices-loading? balance-loading?]]]))
[asset-section balance prices-loading? balance-loading?]]]))

View File

@ -99,7 +99,7 @@
:wallet/keys [send-transaction]
:accounts/keys [accounts current-account-id] :as db} :db} [_ later?]]
(let [{:keys [amount transaction-id password]} send-transaction
amount' (money/to-wei (string/replace amount #"," "."))]
amount-in-wei (money/to-wei (string/replace amount #"," "."))]
(if transaction-id
{::accept-transaction {:id transaction-id
:password password
@ -110,7 +110,7 @@
::send-transaction {:web3 web3
:from (get-in accounts [current-account-id :address])
:to (:to-address send-transaction)
:value amount'}}))))
:value amount-in-wei}}))))
(handlers/register-handler-fx
:wallet/discard-transaction

View File

@ -1,27 +1,24 @@
(ns status-im.ui.screens.wallet.send.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [clojure.string :as str]
[status-im.components.react :as react]
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.components.button.view :as button]
[status-im.components.animation :as animation]
[status-im.components.icons.vector-icons :as vector-icons]
[status-im.components.react :as react]
[status-im.components.status-bar :as status-bar]
[status-im.components.styles :as components.styles]
[status-im.components.toolbar-new.actions :as act]
[status-im.components.toolbar-new.view :as toolbar]
[status-im.components.camera :as camera]
[status-im.utils.utils :as utils]
[status-im.i18n :as i18n]
[status-im.ui.screens.wallet.send.styles :as send.styles]
[status-im.components.icons.vector-icons :as vector-icons]
[reagent.core :as r]
[status-im.utils.money :as money]
[status-im.utils.platform :as platform]
[status-im.ui.screens.wallet.request.styles :as request.styles]
[status-im.ui.screens.wallet.send.styles :as styles]
[status-im.ui.screens.wallet.components.views :as components]
[status-im.components.styles :as components.styles]
[status-im.components.icons.vector-icons :as vi]
[status-im.components.animation :as animation]
[status-im.ui.screens.wallet.styles :as wallet.styles]
[status-im.ui.screens.wallet.send.animations :as send.animations]))
[status-im.ui.screens.wallet.send.animations :as send.animations]
[status-im.ui.screens.wallet.send.styles :as send.styles]))
(defn toolbar-view [signing?]
[toolbar/toolbar2 {:style wallet.styles/toolbar}
@ -45,24 +42,22 @@
bottom-value (animation/create-value -250)
opacity-value (animation/create-value 0)]
{:component-did-mount #(send.animations/animate-sign-panel opacity-value bottom-value)}
[react/animated-view {:style (styles/animated-sign-panel bottom-value)}
[react/animated-view {:style (styles/sign-panel opacity-value)}
[react/view styles/signing-phrase-container
[react/text {:style styles/signing-phrase} signing-phrase]]
[react/text {:style styles/signing-phrase-description} (i18n/label :t/signing-phrase-description)]
[react/view styles/password-container
[react/animated-view {:style (send.styles/animated-sign-panel bottom-value)}
[react/animated-view {:style (send.styles/sign-panel opacity-value)}
[react/view send.styles/signing-phrase-container
[react/text {:style send.styles/signing-phrase} signing-phrase]]
[react/text {:style send.styles/signing-phrase-description} (i18n/label :t/signing-phrase-description)]
[react/view send.styles/password-container
[react/text-input
{:auto-focus true
:secure-text-entry true
:placeholder (i18n/label :t/enter-password)
:placeholder-text-color "#939ba1"
:on-change-text #(do
(re-frame/dispatch [:set-in [:wallet/send-transaction :password] %]))
:style styles/password}]]]
:on-change-text #(re-frame/dispatch [:set-in [:wallet/send-transaction :password] %])
:style send.styles/password}]]]
(when wrong-password?
[components/tooltip (i18n/label :t/wrong-password)])]))
(defview signing-buttons []
(letsubs [sign-enabled? [:wallet.send/sign-password-enabled?]]
[react/view wallet.styles/buttons-container
@ -73,52 +68,64 @@
[react/touchable-highlight {:on-press #(re-frame/dispatch [:wallet/sign-transaction])}
[react/view (wallet.styles/button-container sign-enabled?)
[components/button-text (i18n/label :t/transactions-sign-transaction)]
[vi/icon :icons/forward {:color :white :container-style wallet.styles/forward-icon-container}]]]]))
[vector-icons/icon :icons/forward {:color :white :container-style wallet.styles/forward-icon-container}]]]]))
(defview sign-buttons []
(letsubs [sign-enabled? [:wallet.send/sign-enabled?]]
(defn sign-enabled? [amount-error to-address amount]
(and
(nil? amount-error)
(not (nil? to-address)) (not= to-address "")
(not (nil? amount)) (not= amount "")))
(defn- sign-buttons [amount-error to-address amount sufficient-funds?]
(let [sign-enabled? (sign-enabled? amount-error to-address amount)
immediate-sign-enabled? (and sign-enabled? sufficient-funds?)]
[react/view wallet.styles/buttons-container
(when sign-enabled?
[react/touchable-highlight {:on-press sign-later}
[react/view (wallet.styles/button-container sign-enabled?)
[components/button-text (i18n/label :t/transactions-sign-later)]]])
[react/view components.styles/flex]
[react/touchable-highlight {:on-press (when sign-enabled? #(re-frame/dispatch [:set-in [:wallet/send-transaction :signing?] true]))}
[react/view (wallet.styles/button-container sign-enabled?)
[react/touchable-highlight {:on-press (when immediate-sign-enabled? #(re-frame/dispatch [:set-in [:wallet/send-transaction :signing?] true]))}
[react/view (wallet.styles/button-container immediate-sign-enabled?)
[components/button-text (i18n/label :t/transactions-sign-transaction)]
[vi/icon :icons/forward {:color :white :container-style wallet.styles/forward-icon-container}]]]]))
[vector-icons/icon :icons/forward {:color :white :container-style wallet.styles/forward-icon-container}]]]]))
(defn- sufficient-funds? [amount balance]
(<= amount (money/wei->ether balance)))
(defview send-transaction []
(letsubs [amount [:get-in [:wallet/send-transaction :amount]]
(letsubs [balance [:balance]
amount [:get-in [:wallet/send-transaction :amount]]
amount-error [:get-in [:wallet/send-transaction :amount-error]]
signing? [:get-in [:wallet/send-transaction :signing?]]
to-address [:get-in [:wallet/send-transaction :to-address]]
to-name [:get-in [:wallet/send-transaction :to-name]]]
[react/keyboard-avoiding-view wallet.styles/wallet-modal-container
[react/view components.styles/flex
[status-bar/status-bar {:type :wallet}]
[toolbar-view signing?]
[react/scroll-view {:keyboardShouldPersistTaps :always}
(let [sufficient-funds? (sufficient-funds? amount balance)]
[react/keyboard-avoiding-view wallet.styles/wallet-modal-container
[react/view components.styles/flex
[react/view wallet.styles/choose-participant-container
[components/choose-recipient {:address to-address
:name to-name
:on-press #(re-frame/dispatch [:navigate-to :choose-recipient])}]]
[react/view wallet.styles/choose-wallet-container
[components/choose-wallet]]
[react/view wallet.styles/amount-container
[components/amount-input
{:error amount-error
:input-options {:auto-focus true
:default-value amount
:on-change-text #(do
(re-frame/dispatch [:set-in [:wallet/send-transaction :amount] %])
(re-frame/dispatch [:wallet-validate-amount]))}}]
[react/view wallet.styles/choose-currency-container
[components/choose-currency wallet.styles/choose-currency]]]]]
[components/separator]
(if signing?
[signing-buttons]
[sign-buttons])
(when signing?
[sign-panel])]]))
[status-bar/status-bar {:type :wallet}]
[toolbar-view signing?]
[react/scroll-view {:keyboardShouldPersistTaps :always}
[react/view components.styles/flex
[react/view wallet.styles/choose-participant-container
[components/choose-recipient {:address to-address
:name to-name
:on-press #(re-frame/dispatch [:navigate-to :choose-recipient])}]]
[react/view wallet.styles/choose-wallet-container
[components/choose-wallet]]
[react/view wallet.styles/amount-container
[components/amount-input
{:error (or amount-error (when-not sufficient-funds? (i18n/label :t/wallet-insufficient-funds)))
:input-options {:auto-focus true
:default-value amount
:on-change-text #(let [value (string/trim %)]
(re-frame/dispatch [:set-in [:wallet/send-transaction :amount] value])
(re-frame/dispatch [:wallet-validate-amount]))}}]
[react/view wallet.styles/choose-currency-container
[components/choose-currency wallet.styles/choose-currency]]]]]
[components/separator]
(if signing?
[signing-buttons]
[sign-buttons amount-error to-address amount sufficient-funds?])
(when signing?
[sign-panel])]])))

View File

@ -25,13 +25,6 @@
(or (get-in wallet [:errors :balance-update])
(get-in wallet [:errors :prices-update]))))
(reg-sub :eth-balance
:<- [:balance]
(fn [balance]
(if balance
(money/wei->ether balance)
"...")))
(reg-sub :portfolio-value
:<- [:balance]
:<- [:price]

View File

@ -92,50 +92,50 @@
;; transaction details
(def transaction-details-row
(def details-row
{:flex-direction :row
:margin-vertical 5})
(def transaction-details-item-label
(def details-item-label
{:flex 1
:margin-right 10
:color styles/color-gray4
:font-size 14})
(def transaction-details-item-value-wrapper
(def details-item-value-wrapper
{:flex 5})
(def transaction-details-item-value
(def details-item-value
{:font-size 14
:color styles/color-black})
(def transaction-details-item-extra-value
(def details-item-extra-value
{:font-size 14
:color styles/color-gray4})
(def transaction-details-header
(def details-header
{:margin-horizontal 16
:margin-top 10
:flex-direction :row})
(def transaction-details-header-icon
(def details-header-icon
{:margin-vertical 7})
(def transaction-details-header-infos
(def details-header-infos
{:flex 1
:flex-direction :column
:margin-left 12
:margin-vertical 7})
(def transaction-details-header-value
(def details-header-value
{:font-size 16
:color styles/color-black})
(def transaction-details-header-date
(def details-header-date
{:font-size 14
:color styles/color-gray4})
(def transaction-details-block
(def details-block
{:margin-horizontal 16})
(def progress-bar
@ -152,17 +152,17 @@
:background-color styles/color-blue2
:opacity 0.30})
(def transaction-details-confirmations-count
(def details-confirmations-count
{:color styles/color-black
:font-size 15
:margin-vertical 2})
(def transaction-details-confirmations-helper-text
(def details-confirmations-helper-text
{:color styles/color-gray4
:font-size 14
:margin-vertical 2})
(def transaction-details-separator
(def details-separator
{:background-color styles/color-light-gray3
:height 1
:margin-vertical 10})

View File

@ -26,12 +26,11 @@
(group-by :type (vals transactions))))
(defn format-unsigned-transaction [{:keys [message-id gas-price] :as transaction}]
(-> transaction
(update :value money/wei->ether)
(assoc :type :unsigned
:confirmations 0
:symbol "ETH"
:hash message-id)))
(assoc transaction
:type :unsigned
:confirmations 0
:symbol "ETH"
:hash message-id))
(reg-sub :wallet.transactions/unsigned-transactions
:<- [:transactions]

View File

@ -13,6 +13,7 @@
[status-im.i18n :as i18n]
[status-im.ui.screens.wallet.transactions.styles :as transactions.styles]
[status-im.ui.screens.wallet.views :as wallet.views]
[status-im.utils.money :as money]
[status-im.utils.utils :as utils])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
@ -98,7 +99,7 @@
[list/item
[list/item-icon (transaction-type->icon (keyword type))]
[list/item-content
(str value " " symbol)
(money/wei->str :eth value)
(if (inbound? type)
(str (i18n/label :t/from) " " from)
(str (i18n/label :t/to) " " to))
@ -205,66 +206,70 @@
[toolbar-view view-id unsigned-transactions-count]
[main-section view-id tabs]])))
(defn transaction-details-header [{:keys [value date type]}]
[react/view {:style transactions.styles/transaction-details-header}
[react/view {:style transactions.styles/transaction-details-header-icon}
(defn- pretty-print-asset [symbol amount]
(case symbol
"ETH" (if amount (money/wei->str :eth amount) "...")))
(defn details-header [{:keys [value date type symbol]}]
[react/view {:style transactions.styles/details-header}
[react/view {:style transactions.styles/details-header-icon}
[list/item-icon (transaction-type->icon type)]]
[react/view {:style transactions.styles/transaction-details-header-infos}
[react/text {:style transactions.styles/transaction-details-header-value} (str value " ETH")]
[react/text {:style transactions.styles/transaction-details-header-date} date]]])
[react/view {:style transactions.styles/details-header-infos}
[react/text {:style transactions.styles/details-header-value} (pretty-print-asset symbol value)]
[react/text {:style transactions.styles/details-header-date} date]]])
(defn progress-bar [progress]
[react/view {:style transactions.styles/progress-bar}
[react/view {:style (transactions.styles/progress-bar-done progress)}]
[react/view {:style (transactions.styles/progress-bar-todo (- 100 progress))}]])
(defn transaction-details-confirmations [confirmations confirmations-progress]
[react/view {:style transactions.styles/transaction-details-block}
(defn details-confirmations [confirmations confirmations-progress]
[react/view {:style transactions.styles/details-block}
[progress-bar confirmations-progress]
[react/text {:style transactions.styles/transaction-details-confirmations-count}
[react/text {:style transactions.styles/details-confirmations-count}
(str confirmations " " (i18n/label :t/confirmations))]
[react/text {:style transactions.styles/transaction-details-confirmations-helper-text}
[react/text {:style transactions.styles/details-confirmations-helper-text}
(i18n/label :t/confirmations-helper-text)]])
(defn transaction-details-list-row
(defn details-list-row
([label value]
(transaction-details-list-row label value nil))
(details-list-row label value nil))
([label value extra-value]
[react/view {:style transactions.styles/transaction-details-row}
[react/text {:style transactions.styles/transaction-details-item-label} (i18n/label label)]
[react/view {:style transactions.styles/transaction-details-item-value-wrapper}
[react/text {:style transactions.styles/transaction-details-item-value} (str value)]
[react/text {:style transactions.styles/transaction-details-item-extra-value} (str extra-value)]]]))
[react/view {:style transactions.styles/details-row}
[react/text {:style transactions.styles/details-item-label} (i18n/label label)]
[react/view {:style transactions.styles/details-item-value-wrapper}
[react/text {:style transactions.styles/details-item-value} (str value)]
[react/text {:style transactions.styles/details-item-extra-value} (str extra-value)]]]))
(defn transaction-details-list [{:keys [block hash from from-wallet to to-wallet gas-limit gas-price-gwei gas-price-eth gas-used cost nonce data]}]
[react/view {:style transactions.styles/transaction-details-block}
[transaction-details-list-row :t/block block]
[transaction-details-list-row :t/hash hash]
[transaction-details-list-row :t/from (or from-wallet from) (when from-wallet from)]
[transaction-details-list-row :t/to (or to-wallet to) (when to-wallet to)]
[transaction-details-list-row :t/gas-limit gas-limit]
[transaction-details-list-row :t/gas-price gas-price-gwei gas-price-eth]
[transaction-details-list-row :t/gas-used gas-used]
[transaction-details-list-row :t/cost-fee cost]
[transaction-details-list-row :t/nonce nonce]
[transaction-details-list-row :t/data data]])
(defn details-list [{:keys [block hash from from-wallet to to-wallet gas-limit gas-price-gwei gas-price-eth gas-used cost nonce data]}]
[react/view {:style transactions.styles/details-block}
[details-list-row :t/block block]
[details-list-row :t/hash hash]
[details-list-row :t/from (or from-wallet from) (when from-wallet from)]
[details-list-row :t/to (or to-wallet to) (when to-wallet to)]
[details-list-row :t/gas-limit gas-limit]
[details-list-row :t/gas-price gas-price-gwei gas-price-eth]
[details-list-row :t/gas-used gas-used]
[details-list-row :t/cost-fee cost]
[details-list-row :t/nonce nonce]
[details-list-row :t/data data]])
(defn details-action [hash url]
[(actions/opts [{:text (i18n/label :t/copy-transaction-hash) :value #(react/copy-to-clipboard hash)}
{:text (i18n/label :t/open-on-etherscan) :value #(.openURL react/linking url)}])])
(defview transaction-details []
(letsubs [{:keys [hash url type] :as transaction-details} [:wallet.transactions/transaction-details]
confirmations [:wallet.transactions.details/confirmations]
confirmations-progress [:wallet.transactions.details/confirmations-progress]]
(letsubs [{:keys [hash url type] :as transactions} [:wallet.transactions/details]
confirmations [:wallet.transactions.details/confirmations]
confirmations-progress [:wallet.transactions.details/confirmations-progress]]
[react/view {:style styles/flex}
[status-bar/status-bar]
[toolbar/toolbar2 {}
toolbar/default-nav-back
[toolbar/content-title (i18n/label :t/transaction-details)]
[toolbar/content-title (i18n/label :t/details)]
[toolbar/actions (details-action hash url)]]
[react/scroll-view {:style transactions.styles/main-section}
[transaction-details-header transaction-details]
[transaction-details-confirmations confirmations confirmations-progress]
[react/view {:style transactions.styles/transaction-details-separator}]
[transaction-details-list transaction-details]]]))
[details-header transactions]
[details-confirmations confirmations confirmations-progress]
[react/view {:style transactions.styles/details-separator}]
[details-list transactions]]]))

View File

@ -10,7 +10,6 @@
(defn enabled? [v] (= "1" v))
(def testfairy-enabled? (enabled? (get-config :TESTFAIRY_ENABLED)))
(def wallet-wip-enabled? (enabled? (get-config :WALLET_WIP_ENABLED 0)))
(def notifications-wip-enabled? (enabled? (get-config :NOTIFICATIONS_WIP_ENABLED 0)))
(def stub-status-go? (enabled? (get-config :STUB_STATUS_GO 0)))
(def network-switching-enabled? (enabled? (get-config :NETWORK_SWITCHING 0)))

View File

@ -18,9 +18,9 @@
(str "https://" network-subdomain ".etherscan.io/api?module=account&action=txlist&address=0x"
account "&startblock=0&endblock=99999999&sort=desc&apikey=YourApiKeyToken?q=json")))
(defn format-transaction [account {:keys [value timeStamp blockNumber hash from to gas gasPrice gasUsed nonce confirmations input]}]
(defn- format-transaction [account {:keys [value timeStamp blockNumber hash from to gas gasPrice gasUsed nonce confirmations input]}]
(let [inbound? (= (str "0x" account) to)]
{:value (money/wei->ether value)
{:value value
;; timestamp is in seconds, we convert it in ms
:timestamp (str timeStamp "000")
:symbol "ETH"
@ -36,7 +36,7 @@
:confirmations confirmations
:data input}))
(defn format-transactions-response [response account]
(defn- format-transactions-response [response account]
(->> response
types/json->clj
:result