mirror of
https://github.com/status-im/status-mobile.git
synced 2025-02-26 15:21:08 +00:00
[#7983] Basic user added ERC-20 support
Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
parent
543ccb69e8
commit
23b04288f1
@ -286,7 +286,6 @@
|
|||||||
:wallet-sign-message-modal
|
:wallet-sign-message-modal
|
||||||
:contact-code
|
:contact-code
|
||||||
:wallet-onboarding-setup
|
:wallet-onboarding-setup
|
||||||
:wallet-settings-assets
|
|
||||||
:wallet-modal
|
:wallet-modal
|
||||||
:wallet-onboarding-setup-modal
|
:wallet-onboarding-setup-modal
|
||||||
:wallet-settings-hook)
|
:wallet-settings-hook)
|
||||||
@ -301,7 +300,6 @@
|
|||||||
:recent-recipients
|
:recent-recipients
|
||||||
:wallet-send-assets
|
:wallet-send-assets
|
||||||
:wallet-request-assets
|
:wallet-request-assets
|
||||||
:wallet-settings-assets
|
|
||||||
:wallet-modal} current-view)
|
:wallet-modal} current-view)
|
||||||
[view {:background-color colors/white
|
[view {:background-color colors/white
|
||||||
:position :absolute
|
:position :absolute
|
||||||
|
@ -23,17 +23,21 @@
|
|||||||
[status-im.ui.screens.wallet.db :as wallet.db]
|
[status-im.ui.screens.wallet.db :as wallet.db]
|
||||||
[status-im.ui.screens.wallet.choose-recipient.events :as choose-recipient.events]
|
[status-im.ui.screens.wallet.choose-recipient.events :as choose-recipient.events]
|
||||||
[status-im.ui.screens.navigation :as navigation]
|
[status-im.ui.screens.navigation :as navigation]
|
||||||
[status-im.ui.screens.wallet.utils :as wallet.utils]))
|
[status-im.ui.screens.wallet.utils :as wallet.utils]
|
||||||
|
[status-im.ui.components.chat-icon.screen :as chat-icon]))
|
||||||
|
|
||||||
;; common `send/request` functionality
|
;; common `send/request` functionality
|
||||||
|
|
||||||
(defn- render-asset [{:keys [name symbol amount decimals] :as asset}]
|
(defn- render-asset [{:keys [name symbol amount decimals icon color] :as asset}]
|
||||||
[react/touchable-highlight
|
[react/touchable-highlight
|
||||||
{:on-press #(re-frame/dispatch [:chat.ui/set-command-parameter (wallet.utils/display-symbol asset)])}
|
{:on-press #(re-frame/dispatch [:chat.ui/set-command-parameter (wallet.utils/display-symbol asset)])}
|
||||||
[react/view transactions-styles/asset-container
|
[react/view transactions-styles/asset-container
|
||||||
[react/view transactions-styles/asset-main
|
[react/view transactions-styles/asset-main
|
||||||
[react/image {:source (-> asset :icon :source)
|
(if icon
|
||||||
:style transactions-styles/asset-icon}]
|
[react/image {:source (:source icon)
|
||||||
|
:style transactions-styles/asset-icon}]
|
||||||
|
[react/view {:style transactions-styles/asset-icon}
|
||||||
|
[chat-icon/custom-icon-view-list name color 30]])
|
||||||
[react/text (wallet.utils/display-symbol asset)]
|
[react/text (wallet.utils/display-symbol asset)]
|
||||||
[react/text {:style transactions-styles/asset-name} name]]
|
[react/text {:style transactions-styles/asset-name} name]]
|
||||||
;;TODO(goranjovic) : temporarily disabled to fix https://github.com/status-im/status-react/issues/4963
|
;;TODO(goranjovic) : temporarily disabled to fix https://github.com/status-im/status-react/issues/4963
|
||||||
|
@ -4,3 +4,7 @@
|
|||||||
(defn uint
|
(defn uint
|
||||||
[hex]
|
[hex]
|
||||||
(first (abi-spec/decode hex ["uint"])))
|
(first (abi-spec/decode hex ["uint"])))
|
||||||
|
|
||||||
|
(defn string
|
||||||
|
[hex]
|
||||||
|
(first (abi-spec/decode hex ["string"])))
|
||||||
|
@ -57,7 +57,8 @@
|
|||||||
[status-im.utils.logging.core :as logging]
|
[status-im.utils.logging.core :as logging]
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
[status-im.web3.core :as web3]
|
[status-im.web3.core :as web3]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]
|
||||||
|
[status-im.wallet.custom-tokens.core :as custom-tokens]))
|
||||||
|
|
||||||
;; init module
|
;; init module
|
||||||
|
|
||||||
@ -2057,3 +2058,52 @@
|
|||||||
:ethereum.signal/new-block
|
:ethereum.signal/new-block
|
||||||
(fn [cofx [_ block-number]]
|
(fn [cofx [_ block-number]]
|
||||||
(ethereum.subscriptions/new-block cofx block-number)))
|
(ethereum.subscriptions/new-block cofx block-number)))
|
||||||
|
|
||||||
|
;;custom tokens
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:wallet.custom-token/decimals-result
|
||||||
|
(fn [cofx [_ result]]
|
||||||
|
(custom-tokens/decimals-result cofx result)))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:wallet.custom-token/symbol-result
|
||||||
|
(fn [cofx [_ contract result]]
|
||||||
|
(custom-tokens/symbol-result cofx contract result)))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:wallet.custom-token/name-result
|
||||||
|
(fn [cofx [_ contract result]]
|
||||||
|
(custom-tokens/name-result cofx contract result)))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:wallet.custom-token/balance-result
|
||||||
|
(fn [cofx [_ contract result]]
|
||||||
|
(custom-tokens/balance-result cofx contract result)))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:wallet.custom-token/total-supply-result
|
||||||
|
(fn [cofx [_ contract result]]
|
||||||
|
(custom-tokens/total-supply-result cofx contract result)))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:wallet.custom-token/contract-address-is-pasted
|
||||||
|
(fn [cofx [_ contract]]
|
||||||
|
(custom-tokens/contract-address-is-changed cofx contract)))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:wallet.custom-token.ui/contract-address-paste
|
||||||
|
(fn [_ _]
|
||||||
|
{:wallet.custom-token/contract-address-paste nil}))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:wallet.custom-token.ui/field-is-edited
|
||||||
|
(fn [cofx [_ field-key value]]
|
||||||
|
(custom-tokens/field-is-edited cofx field-key value)))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:wallet.custom-token.ui/add-pressed
|
||||||
|
(fn [cofx _]
|
||||||
|
(fx/merge cofx
|
||||||
|
(custom-tokens/add-pressed)
|
||||||
|
(navigation/navigate-back))))
|
||||||
|
@ -186,12 +186,15 @@
|
|||||||
|
|
||||||
(fx/defn initialize-tokens
|
(fx/defn initialize-tokens
|
||||||
[{:keys [db]}]
|
[{:keys [db]}]
|
||||||
(let [network-id (get-in db [:account/account :network])
|
(let [network-id (get-in db [:account/account :network])
|
||||||
network (get-in db [:account/account :networks network-id])
|
network (get-in db [:account/account :networks network-id])
|
||||||
chain (ethereum/network->chain-keyword network)]
|
custom-tokens (get-in db [:account/account :settings :wallet :custom-tokens])
|
||||||
|
chain (ethereum/network->chain-keyword network)]
|
||||||
(merge
|
(merge
|
||||||
{:db (assoc db :wallet/all-tokens
|
{:db (assoc db :wallet/all-tokens
|
||||||
(utils.core/map-values #(utils.core/index-by :address %) tokens/all-default-tokens))}
|
(merge-with merge
|
||||||
|
(utils.core/map-values #(utils.core/index-by :address %) tokens/all-default-tokens)
|
||||||
|
custom-tokens))}
|
||||||
(when config/erc20-contract-warnings-enabled?
|
(when config/erc20-contract-warnings-enabled?
|
||||||
{:wallet/validate-tokens {:web3 (:web3 db)
|
{:wallet/validate-tokens {:web3 (:web3 db)
|
||||||
:tokens (get tokens/all-default-tokens chain)}}))))
|
:tokens (get tokens/all-default-tokens chain)}}))))
|
||||||
|
@ -150,6 +150,7 @@
|
|||||||
(reg-root-key-sub :wallet/all-tokens :wallet/all-tokens)
|
(reg-root-key-sub :wallet/all-tokens :wallet/all-tokens)
|
||||||
(reg-root-key-sub :prices-loading? :prices-loading?)
|
(reg-root-key-sub :prices-loading? :prices-loading?)
|
||||||
(reg-root-key-sub :wallet.transactions :wallet.transactions)
|
(reg-root-key-sub :wallet.transactions :wallet.transactions)
|
||||||
|
(reg-root-key-sub :wallet/custom-token-screen :wallet/custom-token-screen)
|
||||||
|
|
||||||
;;ethereum
|
;;ethereum
|
||||||
(reg-root-key-sub :ethereum/current-block :ethereum/current-block)
|
(reg-root-key-sub :ethereum/current-block :ethereum/current-block)
|
||||||
@ -1001,7 +1002,7 @@
|
|||||||
(fn [[network visible-tokens-symbols all-tokens]]
|
(fn [[network visible-tokens-symbols all-tokens]]
|
||||||
(let [chain (ethereum/network->chain-keyword network)]
|
(let [chain (ethereum/network->chain-keyword network)]
|
||||||
(conj (filter #(contains? visible-tokens-symbols (:symbol %))
|
(conj (filter #(contains? visible-tokens-symbols (:symbol %))
|
||||||
(tokens/sorted-tokens-for all-tokens (ethereum/network->chain-keyword network)))
|
(tokens/sorted-tokens-for all-tokens chain))
|
||||||
(tokens/native-currency chain)))))
|
(tokens/native-currency chain)))))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
|
@ -81,6 +81,12 @@
|
|||||||
:default-chat-icon-text styles/default-chat-icon-text}
|
:default-chat-icon-text styles/default-chat-icon-text}
|
||||||
hide-dapp?])
|
hide-dapp?])
|
||||||
|
|
||||||
|
(defn custom-icon-view-list
|
||||||
|
[name color & [size]]
|
||||||
|
[react/view (styles/container-list-size (or size 40))
|
||||||
|
[default-chat-icon name {:default-chat-icon (styles/default-chat-icon-profile color (or size 40))
|
||||||
|
:default-chat-icon-text styles/default-chat-icon-text}]])
|
||||||
|
|
||||||
(defn contact-icon-view
|
(defn contact-icon-view
|
||||||
[{:keys [photo-path name dapp?]} {:keys [container] :as styles}]
|
[{:keys [photo-path name dapp?]} {:keys [container] :as styles}]
|
||||||
[react/view container
|
[react/view container
|
||||||
|
@ -180,6 +180,10 @@
|
|||||||
{:width 40
|
{:width 40
|
||||||
:height 40})
|
:height 40})
|
||||||
|
|
||||||
|
(defn container-list-size [size]
|
||||||
|
{:width size
|
||||||
|
:height size})
|
||||||
|
|
||||||
(def container-chat-toolbar
|
(def container-chat-toolbar
|
||||||
{:width 36
|
{:width 36
|
||||||
:height 36})
|
:height 36})
|
||||||
|
@ -68,19 +68,20 @@
|
|||||||
on-press
|
on-press
|
||||||
forward?
|
forward?
|
||||||
back?]}]
|
back?]}]
|
||||||
[react/touchable-highlight {:on-press on-press :disabled disabled?}
|
(let [color (if disabled? colors/gray colors/blue)]
|
||||||
[react/view (styles/bottom-button disabled?)
|
[react/touchable-highlight {:on-press on-press :disabled disabled?}
|
||||||
(when back?
|
[react/view styles/bottom-button
|
||||||
[vector-icons/icon :main-icons/back {:color colors/blue
|
(when back?
|
||||||
:container-style {:align-self :baseline}}])
|
[vector-icons/icon :main-icons/back {:color color
|
||||||
[react/text {:style styles/bottom-button-label
|
:container-style {:align-self :baseline}}])
|
||||||
:accessibility-label accessibility-label}
|
[react/text {:style {:color color}
|
||||||
(or label (i18n/label :t/next))]
|
:accessibility-label accessibility-label}
|
||||||
(when forward?
|
(or label (i18n/label :t/next))]
|
||||||
[vector-icons/icon :main-icons/next {:color colors/blue}])]])
|
(when forward?
|
||||||
|
[vector-icons/icon :main-icons/next {:color color}])]]))
|
||||||
|
|
||||||
(defn button [{:keys [on-press label background? button-style label-style disabled?] :or {background? true disabled false}}]
|
(defn button [{:keys [on-press label background? button-style label-style disabled?] :or {background? true disabled? false}}]
|
||||||
[react/touchable-highlight {:style (styles/button button-style background? disabled?)
|
[react/touchable-highlight {:style (styles/button button-style background? disabled?)
|
||||||
:on-press on-press
|
:on-press on-press
|
||||||
:disabled disabled?}
|
:disabled disabled?}
|
||||||
[react/text {:style (merge styles/button-label label-style)}
|
[react/text {:style (merge styles/button-label label-style)}
|
||||||
@ -89,8 +90,8 @@
|
|||||||
(defn red-button [props]
|
(defn red-button [props]
|
||||||
[react/view {:align-items :center}
|
[react/view {:align-items :center}
|
||||||
[button (merge props
|
[button (merge props
|
||||||
{:label-style {:color colors/red :font-size 15}
|
{:label-style {:color colors/red :font-size 15}
|
||||||
:button-style {:padding-horizontal 32 :background-color colors/red-light}})]])
|
:button-style {:padding-horizontal 32 :background-color colors/red-light}})]])
|
||||||
|
|
||||||
(defn counter
|
(defn counter
|
||||||
([value] (counter nil value))
|
([value] (counter nil value))
|
||||||
|
@ -103,13 +103,9 @@
|
|||||||
:width icon-size
|
:width icon-size
|
||||||
:height icon-size})
|
:height icon-size})
|
||||||
|
|
||||||
(defn bottom-button [disabled?]
|
(def bottom-button
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
:align-items :center
|
:align-items :center})
|
||||||
:opacity (if disabled? 0.4 1)})
|
|
||||||
|
|
||||||
(def bottom-button-label
|
|
||||||
{:color colors/blue})
|
|
||||||
|
|
||||||
(defn button [style background? disabled?]
|
(defn button [style background? disabled?]
|
||||||
(merge
|
(merge
|
||||||
|
7
src/status_im/ui/components/list_header/views.cljs
Normal file
7
src/status_im/ui/components/list_header/views.cljs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
(ns status-im.ui.components.list-header.views
|
||||||
|
(:require [status-im.ui.components.react :as react]
|
||||||
|
[status-im.ui.components.colors :as colors]))
|
||||||
|
|
||||||
|
(defn list-header [title]
|
||||||
|
[react/view {:style {:padding-top 14 :padding-bottom 4 :padding-horizontal 16}}
|
||||||
|
[react/text {:style {:color colors/gray}} title]])
|
@ -70,7 +70,8 @@
|
|||||||
:wallet-transaction-fee {:type :modal-wallet}
|
:wallet-transaction-fee {:type :modal-wallet}
|
||||||
:wallet-onboarding-setup-modal {:type :modal-wallet}
|
:wallet-onboarding-setup-modal {:type :modal-wallet}
|
||||||
:wallet-send-transaction-modal {:type :modal-wallet}
|
:wallet-send-transaction-modal {:type :modal-wallet}
|
||||||
:wallet-settings-assets {:type :modal-wallet}
|
:wallet-settings-assets {:type :wallet}
|
||||||
|
:wallet-add-custom-token {:type :wallet}
|
||||||
:wallet-sign-message-modal {:type :modal-wallet}
|
:wallet-sign-message-modal {:type :modal-wallet}
|
||||||
:wallet-settings-hook {:type :wallet}
|
:wallet-settings-hook {:type :wallet}
|
||||||
:wallet-transaction-sent {:type :transparent}
|
:wallet-transaction-sent {:type :transparent}
|
||||||
|
@ -3,20 +3,26 @@
|
|||||||
(:require [status-im.ui.components.colors :as colors]
|
(:require [status-im.ui.components.colors :as colors]
|
||||||
[status-im.utils.platform :as p]))
|
[status-im.utils.platform :as p]))
|
||||||
|
|
||||||
(def label
|
(defn label [editable]
|
||||||
{:font-size 14})
|
(merge
|
||||||
|
{:margin-vertical 10}
|
||||||
|
(when-not editable {:color colors/gray})))
|
||||||
|
|
||||||
(defn input-container [height]
|
(defn input-container [height editable]
|
||||||
{:padding 16
|
(merge
|
||||||
:justify-content :center
|
{:padding 16
|
||||||
:margin-vertical 8
|
:justify-content :center
|
||||||
:height (or height 52)
|
:height (or height 52)
|
||||||
:border-radius 8
|
:border-radius 8
|
||||||
:background-color colors/gray-lighter})
|
:background-color (when editable colors/gray-lighter)}
|
||||||
|
(when-not editable
|
||||||
|
{:border-color colors/gray-lighter
|
||||||
|
:border-width 1})))
|
||||||
|
|
||||||
(defstyle input
|
(defstyle input
|
||||||
{:padding 0
|
{:padding 0
|
||||||
:desktop {:height 52}})
|
:text-align-vertical :top
|
||||||
|
:desktop {:height 52}})
|
||||||
|
|
||||||
(defn error [label?]
|
(defn error [label?]
|
||||||
{:bottom-value (if label? -20 0)
|
{:bottom-value (if label? -20 0)
|
||||||
|
@ -6,20 +6,20 @@
|
|||||||
[status-im.ui.components.tooltip.views :as tooltip]))
|
[status-im.ui.components.tooltip.views :as tooltip]))
|
||||||
|
|
||||||
(defn merge-container-styles
|
(defn merge-container-styles
|
||||||
[height container]
|
[height container editable]
|
||||||
(let [merged-styles (merge (styles/input-container height) container)]
|
(let [merged-styles (merge (styles/input-container height editable) container)]
|
||||||
;; `:background-color` can't be nil; in this case the app will crash.
|
;; `:background-color` can't be nil; in this case the app will crash.
|
||||||
;; Nevertheless, we need to be able to remove background if necessary.
|
;; Nevertheless, we need to be able to remove background if necessary.
|
||||||
(if (nil? (:background-color merged-styles))
|
(if (nil? (:background-color merged-styles))
|
||||||
(dissoc merged-styles :background-color)
|
(dissoc merged-styles :background-color)
|
||||||
merged-styles)))
|
merged-styles)))
|
||||||
|
|
||||||
(defn text-input-with-label [{:keys [label content error style height container text] :as props}]
|
(defn text-input-with-label [{:keys [label content error style height container text editable] :as props :or {editable true}}]
|
||||||
[react/view
|
[react/view
|
||||||
(when label
|
(when label
|
||||||
[react/text {:style styles/label}
|
[react/text {:style (styles/label editable)}
|
||||||
label])
|
label])
|
||||||
[react/view {:style (merge-container-styles height container)}
|
[react/view {:style (merge-container-styles height container editable)}
|
||||||
[react/text-input
|
[react/text-input
|
||||||
(merge
|
(merge
|
||||||
{:style (merge styles/input style)
|
{:style (merge styles/input style)
|
||||||
|
@ -198,6 +198,7 @@
|
|||||||
(spec/def :stickers/selected-pack (spec/nilable any?))
|
(spec/def :stickers/selected-pack (spec/nilable any?))
|
||||||
(spec/def :stickers/recent (spec/nilable vector?))
|
(spec/def :stickers/recent (spec/nilable vector?))
|
||||||
(spec/def :extensions/profile (spec/nilable any?))
|
(spec/def :extensions/profile (spec/nilable any?))
|
||||||
|
(spec/def :wallet/custom-token-screen (spec/nilable map?))
|
||||||
|
|
||||||
(spec/def ::db (spec/keys :opt [:contacts/contacts
|
(spec/def ::db (spec/keys :opt [:contacts/contacts
|
||||||
:contacts/new-identity
|
:contacts/new-identity
|
||||||
@ -273,7 +274,8 @@
|
|||||||
:stickers/packs-pendning
|
:stickers/packs-pendning
|
||||||
:bottom-sheet/show?
|
:bottom-sheet/show?
|
||||||
:bottom-sheet/view
|
:bottom-sheet/view
|
||||||
:extensions/profile]
|
:extensions/profile
|
||||||
|
:wallet/custom-token-screen]
|
||||||
:opt-un [::modal
|
:opt-un [::modal
|
||||||
::was-modal?
|
::was-modal?
|
||||||
::rpc-url
|
::rpc-url
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
:enter-pin-modal
|
:enter-pin-modal
|
||||||
:hardwallet-connect-modal
|
:hardwallet-connect-modal
|
||||||
:selection-modal-screen
|
:selection-modal-screen
|
||||||
:wallet-settings-assets
|
|
||||||
:wallet-transaction-fee
|
:wallet-transaction-fee
|
||||||
:wallet-transactions-filter
|
:wallet-transactions-filter
|
||||||
:profile-qr-viewer
|
:profile-qr-viewer
|
||||||
|
@ -77,7 +77,8 @@
|
|||||||
[status-im.ui.screens.wallet.transaction-sent.views
|
[status-im.ui.screens.wallet.transaction-sent.views
|
||||||
:as
|
:as
|
||||||
transaction-sent]
|
transaction-sent]
|
||||||
[status-im.ui.screens.wallet.transactions.views :as wallet-transactions]))
|
[status-im.ui.screens.wallet.transactions.views :as wallet-transactions]
|
||||||
|
[status-im.ui.screens.wallet.custom-tokens.views :as custom-tokens]))
|
||||||
|
|
||||||
(def all-screens
|
(def all-screens
|
||||||
{:login login/login
|
{:login login/login
|
||||||
@ -142,7 +143,8 @@
|
|||||||
:wallet-transaction-details wallet-transactions/transaction-details
|
:wallet-transaction-details wallet-transactions/transaction-details
|
||||||
:wallet-settings-hook wallet-settings/settings-hook
|
:wallet-settings-hook wallet-settings/settings-hook
|
||||||
:selection-modal-screen [:modal screens.extensions/selection-modal-screen]
|
:selection-modal-screen [:modal screens.extensions/selection-modal-screen]
|
||||||
:wallet-settings-assets [:modal wallet-settings/manage-assets]
|
:wallet-settings-assets wallet-settings/manage-assets
|
||||||
|
:wallet-add-custom-token custom-tokens/add-custom-token
|
||||||
:wallet-transactions-filter [:modal wallet-transactions/filter-history]
|
:wallet-transactions-filter [:modal wallet-transactions/filter-history]
|
||||||
:my-profile profile.user/my-profile
|
:my-profile profile.user/my-profile
|
||||||
:my-profile-ext-settings profile.user/extensions-settings
|
:my-profile-ext-settings profile.user/extensions-settings
|
||||||
|
@ -24,5 +24,7 @@
|
|||||||
:transactions-history
|
:transactions-history
|
||||||
:wallet-transaction-details
|
:wallet-transaction-details
|
||||||
:wallet-settings-hook
|
:wallet-settings-hook
|
||||||
:extension-screen-holder]
|
:extension-screen-holder
|
||||||
|
:wallet-settings-assets
|
||||||
|
:wallet-add-custom-token]
|
||||||
:config {:initialRouteName :wallet}})
|
:config {:initialRouteName :wallet}})
|
||||||
|
@ -28,7 +28,8 @@
|
|||||||
[status-im.ui.components.toolbar.view :as toolbar]
|
[status-im.ui.components.toolbar.view :as toolbar]
|
||||||
[status-im.ui.components.status-bar.view :as status-bar]
|
[status-im.ui.components.status-bar.view :as status-bar]
|
||||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||||
[status-im.utils.ethereum.eip55 :as eip55]))
|
[status-im.utils.ethereum.eip55 :as eip55]
|
||||||
|
[status-im.ui.components.chat-icon.screen :as chat-icon]))
|
||||||
|
|
||||||
;; Wallet tab has a different coloring scheme (dark) that forces color changes (background, text)
|
;; Wallet tab has a different coloring scheme (dark) that forces color changes (background, text)
|
||||||
;; It might be replaced by some theme mechanism
|
;; It might be replaced by some theme mechanism
|
||||||
@ -115,12 +116,14 @@
|
|||||||
:request :wallet.request/set-symbol
|
:request :wallet.request/set-symbol
|
||||||
(throw (str "Unknown type: " k))))
|
(throw (str "Unknown type: " k))))
|
||||||
|
|
||||||
(defn- render-token [{:keys [symbol name icon decimals amount] :as token} type]
|
(defn- render-token [{:keys [symbol name icon decimals amount color] :as token} type]
|
||||||
[list/touchable-item #(do (re-frame/dispatch [(type->handler type) symbol])
|
[list/touchable-item #(do (re-frame/dispatch [(type->handler type) symbol])
|
||||||
(re-frame/dispatch [:navigate-back]))
|
(re-frame/dispatch [:navigate-back]))
|
||||||
[react/view
|
[react/view
|
||||||
[list/item
|
[list/item
|
||||||
[list/item-image icon]
|
(if icon
|
||||||
|
[list/item-image icon]
|
||||||
|
[chat-icon/custom-icon-view-list name color])
|
||||||
[list/item-content
|
[list/item-content
|
||||||
[react/view {:flex-direction :row}
|
[react/view {:flex-direction :row}
|
||||||
[react/text {:style styles/text}
|
[react/text {:style styles/text}
|
||||||
@ -155,14 +158,16 @@
|
|||||||
(views/letsubs [balance [:balance]
|
(views/letsubs [balance [:balance]
|
||||||
network [:network]
|
network [:network]
|
||||||
all-tokens [:wallet/all-tokens]]
|
all-tokens [:wallet/all-tokens]]
|
||||||
(let [{:keys [name icon decimals] :as token} (tokens/asset-for all-tokens (ethereum/network->chain-keyword network) symbol)]
|
(let [{:keys [name icon decimals color] :as token} (tokens/asset-for all-tokens (ethereum/network->chain-keyword network) symbol)]
|
||||||
(when name
|
(when name
|
||||||
[react/view
|
[react/view
|
||||||
[cartouche {:disabled? disabled? :on-press #(re-frame/dispatch [:navigate-to (type->view type)])}
|
[cartouche {:disabled? disabled? :on-press #(re-frame/dispatch [:navigate-to (type->view type)])}
|
||||||
(i18n/label :t/wallet-asset)
|
(i18n/label :t/wallet-asset)
|
||||||
[react/view {:style styles/asset-content-container
|
[react/view {:style styles/asset-content-container
|
||||||
:accessibility-label :choose-asset-button}
|
:accessibility-label :choose-asset-button}
|
||||||
[list/item-image (assoc icon :style styles/asset-icon :image-style {:width 32 :height 32})]
|
(if icon
|
||||||
|
[list/item-image (assoc icon :style styles/asset-icon :image-style {:width 32 :height 32})]
|
||||||
|
[chat-icon/custom-icon-view-list name color 32])
|
||||||
[react/view styles/asset-text-content
|
[react/view styles/asset-text-content
|
||||||
[react/view styles/asset-label-content
|
[react/view styles/asset-label-content
|
||||||
[react/text {:style (merge styles/text-content styles/asset-label)}
|
[react/text {:style (merge styles/text-content styles/asset-label)}
|
||||||
|
101
src/status_im/ui/screens/wallet/custom_tokens/views.cljs
Normal file
101
src/status_im/ui/screens/wallet/custom_tokens/views.cljs
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
(ns status-im.ui.screens.wallet.custom-tokens.views
|
||||||
|
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||||
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[status-im.ui.components.colors :as colors]
|
||||||
|
[status-im.ui.components.react :as react]
|
||||||
|
[status-im.ui.components.toolbar.view :as toolbar]
|
||||||
|
[status-im.ui.components.status-bar.view :as status-bar]
|
||||||
|
[status-im.ui.components.text-input.view :as text-input]
|
||||||
|
[status-im.ui.components.common.common :as components.common]
|
||||||
|
[clojure.string :as string]
|
||||||
|
[status-im.ui.screens.wallet.utils :as wallet.utils]
|
||||||
|
[status-im.i18n :as i18n]))
|
||||||
|
|
||||||
|
(def debounce-timers (atom {}))
|
||||||
|
|
||||||
|
(defn debounce-and-save [field-key value]
|
||||||
|
(let [timeout (get @debounce-timers field-key)]
|
||||||
|
(when timeout (js/clearTimeout timeout))
|
||||||
|
(swap! debounce-timers assoc field-key
|
||||||
|
(js/setTimeout
|
||||||
|
#(re-frame/dispatch [:wallet.custom-token.ui/field-is-edited field-key (string/trim value)])
|
||||||
|
500))))
|
||||||
|
|
||||||
|
(defview add-custom-token []
|
||||||
|
(letsubs [{:keys [contract name symbol balance decimals in-progress? error error-name error-symbol]}
|
||||||
|
[:wallet/custom-token-screen]]
|
||||||
|
[react/keyboard-avoiding-view {:flex 1 :background-color :white}
|
||||||
|
[status-bar/status-bar]
|
||||||
|
[toolbar/toolbar nil
|
||||||
|
toolbar/default-nav-back
|
||||||
|
[toolbar/content-title
|
||||||
|
(i18n/label :t/add-custom-token)]]
|
||||||
|
[react/scroll-view {:keyboard-should-persist-taps :handled :style {:flex 1 :margin-top 8 :padding-horizontal 16}}
|
||||||
|
[react/view {:style {:flex-direction :row :justify-content :space-between :padding-vertical 10}}
|
||||||
|
[react/text (i18n/label :t/contract-address)]
|
||||||
|
(if in-progress?
|
||||||
|
[react/view {:flex-direction :row :justify-content :center}
|
||||||
|
[react/view {:height 20}
|
||||||
|
[react/activity-indicator {:width 24 :height 24 :animating true}]]
|
||||||
|
[react/text {:style {:color colors/gray :margin-left 5}}
|
||||||
|
(i18n/label :t/processing)]])]
|
||||||
|
(when-not in-progress?
|
||||||
|
;;tooltip covers button
|
||||||
|
[react/view {:position :absolute :z-index 1000 :right 0 :top 10}
|
||||||
|
[react/touchable-highlight {:on-press #(re-frame/dispatch [:wallet.custom-token.ui/contract-address-paste])}
|
||||||
|
[react/text {:style {:color colors/blue}}
|
||||||
|
(i18n/label :t/paste)]]])
|
||||||
|
[text-input/text-input-with-label
|
||||||
|
{:on-change-text #(debounce-and-save :contract %)
|
||||||
|
:error error
|
||||||
|
:default-value contract
|
||||||
|
:multiline true
|
||||||
|
:height 78
|
||||||
|
:placeholder (i18n/label :t/specify-address)}]
|
||||||
|
[react/view {:height 16}]
|
||||||
|
[text-input/text-input-with-label
|
||||||
|
{:on-change-text #(debounce-and-save :name %)
|
||||||
|
:label (i18n/label :t/name)
|
||||||
|
:default-value name
|
||||||
|
:error error-name
|
||||||
|
:placeholder (i18n/label :t/name-of-token)}]
|
||||||
|
[react/view {:height 16}]
|
||||||
|
[react/view {:style {:flex-direction :row}}
|
||||||
|
[react/view {:flex 1}
|
||||||
|
[text-input/text-input-with-label
|
||||||
|
{:on-change-text #(debounce-and-save :symbol %)
|
||||||
|
:label (i18n/label :t/symbol)
|
||||||
|
:error error-symbol
|
||||||
|
:default-value symbol
|
||||||
|
:placeholder "ABC"}]]
|
||||||
|
[react/view {:flex 1 :margin-left 33}
|
||||||
|
[text-input/text-input-with-label
|
||||||
|
{:label (i18n/label :t/decimals)
|
||||||
|
:on-change-text #(debounce-and-save :decimals %)
|
||||||
|
:default-value decimals
|
||||||
|
:keyboard-type :number-pad
|
||||||
|
:max-length 2
|
||||||
|
:placeholder "18"}]]]
|
||||||
|
[react/view {:height 16}]
|
||||||
|
[text-input/text-input-with-label
|
||||||
|
{:label (i18n/label :t/balance)
|
||||||
|
:default-value (when (and balance decimals)
|
||||||
|
(wallet.utils/format-amount balance decimals))
|
||||||
|
:editable false
|
||||||
|
:placeholder (i18n/label :t/no-tokens-found)}]]
|
||||||
|
[react/view {:style {:height 1 :background-color colors/gray-lighter}}]
|
||||||
|
[react/view {:flex-direction :row
|
||||||
|
:margin-horizontal 12
|
||||||
|
:margin-vertical 15
|
||||||
|
:align-items :center}
|
||||||
|
|
||||||
|
[react/view {:style {:flex 1}}]
|
||||||
|
[components.common/bottom-button
|
||||||
|
{:forward? true
|
||||||
|
:label (i18n/label :t/add)
|
||||||
|
:disabled? (boolean
|
||||||
|
(or in-progress?
|
||||||
|
error error-name error-symbol
|
||||||
|
(string/blank? contract) (string/blank? name)
|
||||||
|
(string/blank? symbol) (string/blank? decimals)))
|
||||||
|
:on-press #(re-frame/dispatch [:wallet.custom-token.ui/add-pressed])}]]]))
|
@ -22,7 +22,8 @@
|
|||||||
status-im.ui.screens.wallet.collectibles.superrare.views
|
status-im.ui.screens.wallet.collectibles.superrare.views
|
||||||
status-im.ui.screens.wallet.collectibles.kudos.views
|
status-im.ui.screens.wallet.collectibles.kudos.views
|
||||||
[status-im.ui.components.status-bar.view :as status-bar.view]
|
[status-im.ui.components.status-bar.view :as status-bar.view]
|
||||||
[status-im.ui.screens.wallet.transactions.views :as transactions.views]))
|
[status-im.ui.screens.wallet.transactions.views :as transactions.views]
|
||||||
|
[status-im.ui.components.chat-icon.screen :as chat-icon]))
|
||||||
|
|
||||||
(defn toolbar-modal [modal-history?]
|
(defn toolbar-modal [modal-history?]
|
||||||
[react/view
|
[react/view
|
||||||
@ -79,11 +80,13 @@
|
|||||||
:action #(re-frame/dispatch [:navigate-to :transactions-history])}])
|
:action #(re-frame/dispatch [:navigate-to :transactions-history])}])
|
||||||
|
|
||||||
(defn- render-asset [currency]
|
(defn- render-asset [currency]
|
||||||
(fn [{:keys [symbol symbol-display icon decimals amount] :as token}]
|
(fn [{:keys [symbol icon decimals amount color] :as token}]
|
||||||
(let [asset-value (re-frame/subscribe [:asset-value symbol decimals (-> currency :code keyword)])]
|
(let [asset-value (re-frame/subscribe [:asset-value symbol decimals (-> currency :code keyword)])]
|
||||||
[react/view {:style styles/asset-item-container}
|
[react/view {:style styles/asset-item-container}
|
||||||
[list/item
|
[list/item
|
||||||
[list/item-image icon]
|
(if icon
|
||||||
|
[list/item-image icon]
|
||||||
|
[chat-icon/custom-icon-view-list (:name token) color])
|
||||||
[react/view {:style styles/asset-item-value-container}
|
[react/view {:style styles/asset-item-value-container}
|
||||||
[react/text {:style styles/asset-item-value
|
[react/text {:style styles/asset-item-value
|
||||||
:number-of-lines 1
|
:number-of-lines 1
|
||||||
|
@ -54,3 +54,7 @@
|
|||||||
(do
|
(do
|
||||||
(re-frame/dispatch [:wallet/update-gas-price])
|
(re-frame/dispatch [:wallet/update-gas-price])
|
||||||
(assoc-in db [:wallet :send-transaction] transaction-send-default))))
|
(assoc-in db [:wallet :send-transaction] transaction-send-default))))
|
||||||
|
|
||||||
|
(defmethod navigation/preload-data! :wallet-add-custom-token
|
||||||
|
[db [event]]
|
||||||
|
(dissoc db :wallet/custom-token-screen))
|
@ -11,11 +11,21 @@
|
|||||||
(conj (or ids #{}) id)
|
(conj (or ids #{}) id)
|
||||||
(disj ids id)))
|
(disj ids id)))
|
||||||
|
|
||||||
(fx/defn toggle-visible-token [{{:account/keys [account]} :db :as cofx} symbol checked?]
|
(defn update-toggle-in-settings [{{:account/keys [account]} :db} symbol checked?]
|
||||||
(let [network (get (:networks account) (:network account))
|
(let [network (get (:networks account) (:network account))
|
||||||
chain (ethereum/network->chain-keyword network)
|
chain (ethereum/network->chain-keyword network)
|
||||||
settings (get account :settings)
|
settings (get account :settings)]
|
||||||
new-settings (update-in settings [:wallet :visible-tokens chain] #(set-checked % symbol checked?))]
|
(update-in settings [:wallet :visible-tokens chain] #(set-checked % symbol checked?))))
|
||||||
|
|
||||||
|
(fx/defn toggle-visible-token [cofx symbol checked?]
|
||||||
|
(let [new-settings (update-toggle-in-settings cofx symbol checked?)]
|
||||||
|
(accounts.update/update-settings cofx new-settings {})))
|
||||||
|
|
||||||
|
(fx/defn add-custom-token [{{:account/keys [account]} :db :as cofx} {:keys [symbol address] :as token}]
|
||||||
|
(let [network (get (:networks account) (:network account))
|
||||||
|
chain (ethereum/network->chain-keyword network)
|
||||||
|
settings (update-toggle-in-settings cofx symbol true)
|
||||||
|
new-settings (assoc-in settings [:wallet :custom-tokens chain address] token)]
|
||||||
(accounts.update/update-settings cofx new-settings {})))
|
(accounts.update/update-settings cofx new-settings {})))
|
||||||
|
|
||||||
(fx/defn configure-token-balance-and-visibility [cofx symbol balance]
|
(fx/defn configure-token-balance-and-visibility [cofx symbol balance]
|
||||||
|
@ -9,17 +9,28 @@
|
|||||||
[status-im.ui.components.toolbar.view :as toolbar]
|
[status-im.ui.components.toolbar.view :as toolbar]
|
||||||
[status-im.ui.components.toolbar.actions :as toolbar.actions]
|
[status-im.ui.components.toolbar.actions :as toolbar.actions]
|
||||||
[status-im.ui.components.status-bar.view :as status-bar]
|
[status-im.ui.components.status-bar.view :as status-bar]
|
||||||
[status-im.ui.screens.wallet.styles :as wallet.styles]
|
|
||||||
[status-im.utils.ethereum.core :as ethereum]
|
[status-im.utils.ethereum.core :as ethereum]
|
||||||
[status-im.utils.ethereum.tokens :as tokens]
|
[status-im.utils.ethereum.tokens :as tokens]
|
||||||
[status-im.ui.components.toolbar.actions :as actions]))
|
[status-im.ui.components.toolbar.actions :as actions]
|
||||||
|
[status-im.ui.components.action-button.action-button :as action-button]
|
||||||
|
[status-im.ui.components.list-header.views :as list-header]
|
||||||
|
[status-im.ui.components.chat-icon.screen :as chat-icon]))
|
||||||
|
|
||||||
(defn- render-token [{:keys [symbol name icon]} visible-tokens]
|
(defn toolbar []
|
||||||
|
[toolbar/toolbar nil
|
||||||
|
[toolbar/nav-button
|
||||||
|
(toolbar.actions/back #(re-frame/dispatch [:update-wallet-and-nav-back]))]
|
||||||
|
[toolbar/content-title
|
||||||
|
(i18n/label :t/wallet-assets)]])
|
||||||
|
|
||||||
|
(defn- render-token [{:keys [symbol name icon color]} visible-tokens]
|
||||||
[list/list-item-with-checkbox
|
[list/list-item-with-checkbox
|
||||||
{:checked? (contains? visible-tokens (keyword symbol))
|
{:checked? (contains? visible-tokens (keyword symbol))
|
||||||
:on-value-change #(re-frame/dispatch [:wallet.settings/toggle-visible-token (keyword symbol) %])}
|
:on-value-change #(re-frame/dispatch [:wallet.settings/toggle-visible-token (keyword symbol) %])}
|
||||||
[list/item
|
[list/item
|
||||||
[list/item-image icon]
|
(if icon
|
||||||
|
[list/item-image icon]
|
||||||
|
[chat-icon/custom-icon-view-list name color])
|
||||||
[list/item-content
|
[list/item-content
|
||||||
[list/item-primary name]
|
[list/item-primary name]
|
||||||
[list/item-secondary symbol]]]])
|
[list/item-secondary symbol]]]])
|
||||||
@ -28,26 +39,35 @@
|
|||||||
(letsubs [network [:network]
|
(letsubs [network [:network]
|
||||||
visible-tokens [:wallet/visible-tokens-symbols]
|
visible-tokens [:wallet/visible-tokens-symbols]
|
||||||
all-tokens [:wallet/all-tokens]]
|
all-tokens [:wallet/all-tokens]]
|
||||||
[react/view (merge components.styles/flex {:background-color :white})
|
(let [chain-key (ethereum/network->chain-keyword network)
|
||||||
[status-bar/status-bar {:type :modal-wallet}]
|
{custom-tokens true default-tokens nil} (group-by :custom? (tokens/sorted-tokens-for all-tokens chain-key))]
|
||||||
[toolbar/toolbar
|
[react/view (merge components.styles/flex {:background-color :white})
|
||||||
{:style {:background-color colors/blue
|
[status-bar/status-bar]
|
||||||
:border-bottom-width 0}}
|
[toolbar]
|
||||||
[toolbar/nav-button
|
[react/view {:style {:flex 1 :padding-top 16}}
|
||||||
(toolbar.actions/close-white #(re-frame/dispatch [:update-wallet-and-nav-back]))]
|
[action-button/action-button {:label (i18n/label :t/add-custom-token)
|
||||||
[toolbar/content-title {:color colors/white}
|
:icon :main-icons/add
|
||||||
(i18n/label :t/wallet-assets)]]
|
:icon-opts {:color :blue}
|
||||||
[react/view {:style components.styles/flex}
|
:on-press #(re-frame/dispatch [:navigate-to :wallet-add-custom-token])}]
|
||||||
[list/flat-list {:data (tokens/sorted-tokens-for all-tokens (ethereum/network->chain-keyword network))
|
[list/section-list
|
||||||
:key-fn (comp str :symbol)
|
{:sections (concat
|
||||||
:render-fn #(render-token % visible-tokens)}]]]))
|
(when (seq custom-tokens)
|
||||||
|
[{:title (i18n/label :t/custom)
|
||||||
|
:data custom-tokens}])
|
||||||
|
[{:title (i18n/label :t/default)
|
||||||
|
:data default-tokens}])
|
||||||
|
:key-fn :address
|
||||||
|
:stickySectionHeadersEnabled false
|
||||||
|
:render-section-header-fn (fn [{:keys [title data]}]
|
||||||
|
[list-header/list-header title])
|
||||||
|
:render-fn #(render-token % visible-tokens)}]]])))
|
||||||
|
|
||||||
(defn- create-payload [address]
|
(defn- create-payload [address]
|
||||||
{:address (ethereum/normalized-address address)})
|
{:address (ethereum/normalized-address address)})
|
||||||
|
|
||||||
(defview settings-hook []
|
(defview settings-hook []
|
||||||
(letsubs [{:keys [label view on-close]} [:get-screen-params :wallet-settings-hook]
|
(letsubs [{:keys [label view on-close]} [:get-screen-params :wallet-settings-hook]
|
||||||
{address :address} [:account/account]]
|
{address :address} [:account/account]]
|
||||||
[react/keyboard-avoiding-view {:style {:flex 1 :background-color colors/blue}}
|
[react/keyboard-avoiding-view {:style {:flex 1 :background-color colors/blue}}
|
||||||
[status-bar/status-bar {:type :wallet}]
|
[status-bar/status-bar {:type :wallet}]
|
||||||
[toolbar/toolbar
|
[toolbar/toolbar
|
||||||
@ -69,7 +89,7 @@
|
|||||||
(re-frame/dispatch [:navigate-to :wallet-settings-hook m]))})
|
(re-frame/dispatch [:navigate-to :wallet-settings-hook m]))})
|
||||||
|
|
||||||
(defview toolbar-view []
|
(defview toolbar-view []
|
||||||
(letsubs [settings [:wallet/settings]
|
(letsubs [settings [:wallet/settings]
|
||||||
{address :address} [:account/account]]
|
{address :address} [:account/account]]
|
||||||
[toolbar/toolbar {:style {:background-color colors/blue
|
[toolbar/toolbar {:style {:background-color colors/blue
|
||||||
:border-bottom-width 0}}
|
:border-bottom-width 0}}
|
||||||
|
@ -57,6 +57,9 @@
|
|||||||
(defn network->chain-keyword [network]
|
(defn network->chain-keyword [network]
|
||||||
(chain-id->chain-keyword (network->chain-id network)))
|
(chain-id->chain-keyword (network->chain-id network)))
|
||||||
|
|
||||||
|
(defn get-chain-keyword [db]
|
||||||
|
(network->chain-keyword (get-in db [:account/account :networks (:network db)])))
|
||||||
|
|
||||||
(defn network->chain-name [network]
|
(defn network->chain-name [network]
|
||||||
(-> network
|
(-> network
|
||||||
network->chain-keyword
|
network->chain-keyword
|
||||||
|
131
src/status_im/wallet/custom_tokens/core.cljs
Normal file
131
src/status_im/wallet/custom_tokens/core.cljs
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
(ns status-im.wallet.custom-tokens.core
|
||||||
|
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||||
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[status-im.i18n :as i18n]
|
||||||
|
[status-im.ui.components.colors :as colors]
|
||||||
|
[status-im.ui.components.react :as react]
|
||||||
|
[status-im.utils.ethereum.core :as ethereum]
|
||||||
|
[clojure.string :as string]
|
||||||
|
[status-im.ethereum.decode :as decode]
|
||||||
|
[status-im.utils.fx :as fx]
|
||||||
|
[status-im.ui.screens.wallet.settings.models :as models]))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
:wallet.custom-token/get-decimals
|
||||||
|
(fn [contract]
|
||||||
|
(ethereum/call
|
||||||
|
(ethereum/call-params contract "decimals()")
|
||||||
|
#(re-frame/dispatch [:wallet.custom-token/decimals-result %]))))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
:wallet.custom-token/get-symbol
|
||||||
|
(fn [contract]
|
||||||
|
(ethereum/call
|
||||||
|
(ethereum/call-params contract "symbol()")
|
||||||
|
#(re-frame/dispatch [:wallet.custom-token/symbol-result contract %]))))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
:wallet.custom-token/get-balance
|
||||||
|
(fn [[contract address]]
|
||||||
|
(ethereum/call
|
||||||
|
(ethereum/call-params contract "balanceOf(address)" (ethereum/normalized-address address))
|
||||||
|
#(re-frame/dispatch [:wallet.custom-token/balance-result contract %]))))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
:wallet.custom-token/get-name
|
||||||
|
(fn [contract]
|
||||||
|
(ethereum/call
|
||||||
|
(ethereum/call-params contract "name()")
|
||||||
|
#(re-frame/dispatch [:wallet.custom-token/name-result contract %]))))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
:wallet.custom-token/get-total-supply
|
||||||
|
(fn [contract]
|
||||||
|
(ethereum/call
|
||||||
|
(ethereum/call-params contract "totalSupply()")
|
||||||
|
#(re-frame/dispatch [:wallet.custom-token/total-supply-result contract %]))))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
:wallet.custom-token/contract-address-paste
|
||||||
|
(fn []
|
||||||
|
(react/get-from-clipboard #(re-frame/dispatch [:wallet.custom-token/contract-address-is-pasted (string/trim %)]))))
|
||||||
|
|
||||||
|
(defn field-exists? [{:wallet/keys [all-tokens] :as db} field-key field-value]
|
||||||
|
(let [chain-key (ethereum/get-chain-keyword db)]
|
||||||
|
(some #(= field-value (get % field-key)) (vals (get all-tokens chain-key)))))
|
||||||
|
|
||||||
|
(fx/defn total-supply-result [{:keys [db]} contract result]
|
||||||
|
(if (and (string? result) (string/starts-with? result "0x") (> (count result) 2))
|
||||||
|
{:wallet.custom-token/get-balance [contract (get-in db [:account/account :address])]}
|
||||||
|
{:db (update db :wallet/custom-token-screen merge {:in-progress? nil :error (i18n/label :t/wrong-contract)})}))
|
||||||
|
|
||||||
|
(defn token-in-list? [{:wallet/keys [all-tokens] :as db} contract]
|
||||||
|
(let [chain-key (ethereum/get-chain-keyword db)
|
||||||
|
addresses (set (map string/lower-case (keys (get all-tokens chain-key))))]
|
||||||
|
(not (nil? (get addresses (string/lower-case contract))))))
|
||||||
|
|
||||||
|
(fx/defn contract-address-is-changed [{:keys [db]} contract]
|
||||||
|
(if (ethereum/address? contract)
|
||||||
|
(if (token-in-list? db contract)
|
||||||
|
{:db (assoc db :wallet/custom-token-screen {:contract contract :error (i18n/label :t/already-have-asset)})}
|
||||||
|
{:db (assoc db :wallet/custom-token-screen {:contract contract :in-progress? true})
|
||||||
|
:wallet.custom-token/get-total-supply contract})
|
||||||
|
{:db (assoc db :wallet/custom-token-screen {:contract contract :error (i18n/label :t/wrong-address)})}))
|
||||||
|
|
||||||
|
(fx/defn decimals-result [{:keys [db]} result]
|
||||||
|
{:db (update db :wallet/custom-token-screen merge {:decimals (str (decode/uint result))
|
||||||
|
:in-progress? nil})})
|
||||||
|
|
||||||
|
(fx/defn symbol-result [{:keys [db]} contract result]
|
||||||
|
(let [token-symbol (decode/string result)
|
||||||
|
symbol-exists? (field-exists? db :symbol (keyword token-symbol))]
|
||||||
|
{:db
|
||||||
|
(update db :wallet/custom-token-screen merge
|
||||||
|
{:symbol token-symbol
|
||||||
|
:error-symbol (when symbol-exists?
|
||||||
|
(i18n/label :t/you-already-have-an-asset {:value token-symbol}))})
|
||||||
|
:wallet.custom-token/get-decimals
|
||||||
|
contract}))
|
||||||
|
|
||||||
|
(fx/defn name-result [{:keys [db]} contract result]
|
||||||
|
(let [token-name (decode/string result)
|
||||||
|
name-exists? (field-exists? db :name token-name)]
|
||||||
|
{:db
|
||||||
|
(update db :wallet/custom-token-screen merge
|
||||||
|
{:name token-name
|
||||||
|
:error-name (when name-exists?
|
||||||
|
(i18n/label :t/you-already-have-an-asset {:value token-name}))})
|
||||||
|
:wallet.custom-token/get-symbol
|
||||||
|
contract}))
|
||||||
|
|
||||||
|
(fx/defn balance-result [{:keys [db]} contract result]
|
||||||
|
(if (and (string? result) (string/starts-with? result "0x") (> (count result) 2))
|
||||||
|
{:db (assoc-in db [:wallet/custom-token-screen :balance] (str (decode/uint result)))
|
||||||
|
:wallet.custom-token/get-name contract}
|
||||||
|
{:db (update db :wallet/custom-token-screen merge {:in-progress? nil :error (i18n/label :t/wrong-contract)})}))
|
||||||
|
|
||||||
|
(fx/defn add-pressed [{:keys [db] :as cofx}]
|
||||||
|
(let [{:keys [contract name symbol decimals]} (get db :wallet/custom-token-screen)
|
||||||
|
chain-key (ethereum/get-chain-keyword db)
|
||||||
|
symbol (keyword symbol)
|
||||||
|
new-token {:address contract :name name :symbol symbol :custom? true
|
||||||
|
:decimals (int decimals) :color (rand-nth colors/chat-colors)}]
|
||||||
|
(fx/merge (assoc-in cofx [:db :wallet/all-tokens chain-key contract] new-token)
|
||||||
|
(models/add-custom-token new-token))))
|
||||||
|
|
||||||
|
(fx/defn field-is-edited [{:keys [db] :as cofx} field-key value]
|
||||||
|
(case field-key
|
||||||
|
:contract (contract-address-is-changed cofx value)
|
||||||
|
:name {:db (update db :wallet/custom-token-screen merge
|
||||||
|
{field-key
|
||||||
|
value
|
||||||
|
:error-name
|
||||||
|
(when (field-exists? db field-key value)
|
||||||
|
(i18n/label :t/you-already-have-an-asset {:value value}))})}
|
||||||
|
:symbol {:db (update db :wallet/custom-token-screen merge
|
||||||
|
{field-key
|
||||||
|
value
|
||||||
|
:error-symbol
|
||||||
|
(when (field-exists? db field-key (keyword value))
|
||||||
|
(i18n/label :t/you-already-have-an-asset {:value value}))})}
|
||||||
|
:decimals {:db (assoc-in db [:wallet/custom-token-screen :decimals] value)}))
|
@ -1029,5 +1029,20 @@
|
|||||||
"dapps-can-access" : "ÐApps can access my wallet and contact code",
|
"dapps-can-access" : "ÐApps can access my wallet and contact code",
|
||||||
"require-my-permission" : "Require my permission",
|
"require-my-permission" : "Require my permission",
|
||||||
"might-break" : "Might break some ÐApps",
|
"might-break" : "Might break some ÐApps",
|
||||||
"always-allow" : "Always allow"
|
"always-allow" : "Always allow",
|
||||||
|
"you-already-have-an-asset" : "You already have an asset {{value}}",
|
||||||
|
"add-custom-token" : "Add custom token",
|
||||||
|
"contract-address" : "Contract address",
|
||||||
|
"processing" : "Processing",
|
||||||
|
"paste" : "Paste",
|
||||||
|
"specify-address" : "Specify address",
|
||||||
|
"name-of-token" : "The name of your token",
|
||||||
|
"symbol" : "Symbol",
|
||||||
|
"decimals" : "Decimals",
|
||||||
|
"balance" : "Balance",
|
||||||
|
"no-tokens-found" : "No tokens found",
|
||||||
|
"wrong-contract" :"Wrong contract",
|
||||||
|
"already-have-asset" : "You already have this asset",
|
||||||
|
"wrong-address" : "Wrong address",
|
||||||
|
"default" : "Default"
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user