From 56e6979c9b4956c8a536ec61add41315f6c5458c Mon Sep 17 00:00:00 2001 From: Andrey Shovkoplyas Date: Mon, 17 Jun 2019 11:41:37 +0200 Subject: [PATCH] [#8348] [Multi-Account] Account overview + individual wallet UI --- .../src/status_im/ui/components/react.cljs | 11 +- resources/icons/main/language.svg | 5 +- resources/icons/main/token.svg | 1 + resources/icons/main/watch.svg | 1 + .../chat/commands/impl/transactions.cljs | 2 +- src/status_im/ethereum/tokens.cljs | 1 + src/status_im/events.cljs | 21 +- src/status_im/subs.cljs | 41 +++- .../ui/components/icons/vector_icons.cljs | 2 + .../ui/components/list_item/views.cljs | 67 +++--- .../ui/components/status_bar/view.cljs | 1 + src/status_im/ui/screens/events.cljs | 10 - .../ui/screens/profile/user/views.cljs | 8 +- .../ui/screens/routing/profile_stack.cljs | 1 - src/status_im/ui/screens/routing/screens.cljs | 11 +- .../ui/screens/routing/wallet_stack.cljs | 4 +- src/status_im/ui/screens/signing/sheets.cljs | 4 +- src/status_im/ui/screens/signing/views.cljs | 2 +- src/status_im/ui/screens/views.cljs | 7 +- .../ui/screens/wallet/account/styles.cljs | 22 ++ .../ui/screens/wallet/account/views.cljs | 112 ++++++++++ .../ui/screens/wallet/accounts/sheets.cljs | 65 ++++++ .../ui/screens/wallet/accounts/styles.cljs | 35 +++ .../ui/screens/wallet/accounts/views.cljs | 166 ++++++++++++++ .../wallet/choose_recipient/events.cljs | 122 ----------- .../wallet/choose_recipient/views.cljs | 1 - .../collectibles/cryptokitties/events.cljs | 31 --- .../collectibles/cryptostrikers/events.cljs | 12 -- .../wallet/collectibles/etheremon/events.cljs | 12 -- .../screens/wallet/collectibles/events.cljs | 74 ------- .../wallet/collectibles/kudos/events.cljs | 45 ---- .../wallet/collectibles/superrare/events.cljs | 41 ---- .../ui/screens/wallet/components/styles.cljs | 16 +- .../ui/screens/wallet/components/views.cljs | 15 +- .../screens/wallet/custom_tokens/views.cljs | 2 +- .../ui/screens/wallet/main/styles.cljs | 123 ----------- .../ui/screens/wallet/main/views.cljs | 201 ----------------- .../ui/screens/wallet/onboarding/styles.cljs | 93 -------- .../ui/screens/wallet/onboarding/views.cljs | 132 ------------ .../ui/screens/wallet/request/events.cljs | 34 --- .../ui/screens/wallet/request/views.cljs | 10 +- .../ui/screens/wallet/send/events.cljs | 43 ---- .../ui/screens/wallet/send/styles.cljs | 48 +---- .../ui/screens/wallet/send/views.cljs | 3 - .../ui/screens/wallet/settings/views.cljs | 51 +++-- src/status_im/ui/screens/wallet/styles.cljs | 15 -- .../screens/wallet/transaction_fee/views.cljs | 102 --------- .../wallet/transaction_sent/styles.cljs | 15 -- .../wallet/transaction_sent/views.cljs | 69 ------ src/status_im/wallet/accounts/core.cljs | 16 ++ .../wallet/choose_recipient/core.cljs | 122 +++++++++++ src/status_im/wallet/collectibles/core.cljs | 203 ++++++++++++++++++ src/status_im/wallet/core.cljs | 105 ++++++--- src/status_im/wallet/custom_tokens/core.cljs | 1 - .../{ui/screens => }/wallet/utils.cljs | 2 +- translations/en.json | 12 +- 56 files changed, 986 insertions(+), 1385 deletions(-) create mode 100644 resources/icons/main/token.svg create mode 100644 resources/icons/main/watch.svg create mode 100644 src/status_im/ui/screens/wallet/account/styles.cljs create mode 100644 src/status_im/ui/screens/wallet/account/views.cljs create mode 100644 src/status_im/ui/screens/wallet/accounts/sheets.cljs create mode 100644 src/status_im/ui/screens/wallet/accounts/styles.cljs create mode 100644 src/status_im/ui/screens/wallet/accounts/views.cljs delete mode 100644 src/status_im/ui/screens/wallet/choose_recipient/events.cljs delete mode 100644 src/status_im/ui/screens/wallet/collectibles/cryptokitties/events.cljs delete mode 100644 src/status_im/ui/screens/wallet/collectibles/cryptostrikers/events.cljs delete mode 100644 src/status_im/ui/screens/wallet/collectibles/etheremon/events.cljs delete mode 100644 src/status_im/ui/screens/wallet/collectibles/events.cljs delete mode 100644 src/status_im/ui/screens/wallet/collectibles/kudos/events.cljs delete mode 100644 src/status_im/ui/screens/wallet/collectibles/superrare/events.cljs delete mode 100644 src/status_im/ui/screens/wallet/main/styles.cljs delete mode 100644 src/status_im/ui/screens/wallet/main/views.cljs delete mode 100644 src/status_im/ui/screens/wallet/onboarding/styles.cljs delete mode 100644 src/status_im/ui/screens/wallet/onboarding/views.cljs delete mode 100644 src/status_im/ui/screens/wallet/request/events.cljs delete mode 100644 src/status_im/ui/screens/wallet/send/events.cljs delete mode 100644 src/status_im/ui/screens/wallet/styles.cljs delete mode 100644 src/status_im/ui/screens/wallet/transaction_fee/views.cljs delete mode 100644 src/status_im/ui/screens/wallet/transaction_sent/styles.cljs delete mode 100644 src/status_im/ui/screens/wallet/transaction_sent/views.cljs create mode 100644 src/status_im/wallet/accounts/core.cljs create mode 100644 src/status_im/wallet/choose_recipient/core.cljs create mode 100644 src/status_im/wallet/collectibles/core.cljs rename src/status_im/{ui/screens => }/wallet/utils.cljs (95%) diff --git a/components/src/status_im/ui/components/react.cljs b/components/src/status_im/ui/components/react.cljs index 97465a17ca2a..b1954caf730f 100644 --- a/components/src/status_im/ui/components/react.cljs +++ b/components/src/status_im/ui/components/react.cljs @@ -299,8 +299,7 @@ (let [props (merge props {:background-color (case current-view - (:wallet - :wallet-send-transaction + (:wallet-send-transaction :wallet-request-transaction :wallet-send-assets :wallet-request-assets @@ -308,8 +307,6 @@ :recent-recipients :wallet-send-transaction-request :contact-code - :wallet-modal - :wallet-onboarding-setup-modal :wallet-settings-hook) colors/blue @@ -318,11 +315,9 @@ "#2f3031" colors/white)}) - bottom-background (when (#{:wallet - :recent-recipients + bottom-background (when (#{:recent-recipients :wallet-send-assets - :wallet-request-assets - :wallet-modal} current-view) + :wallet-request-assets} current-view) [view {:background-color colors/white :position :absolute :bottom 0 diff --git a/resources/icons/main/language.svg b/resources/icons/main/language.svg index 075e596a00d9..997a73d761f9 100644 --- a/resources/icons/main/language.svg +++ b/resources/icons/main/language.svg @@ -1,4 +1 @@ - - - - + \ No newline at end of file diff --git a/resources/icons/main/token.svg b/resources/icons/main/token.svg new file mode 100644 index 000000000000..8c64e54be5d0 --- /dev/null +++ b/resources/icons/main/token.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/icons/main/watch.svg b/resources/icons/main/watch.svg new file mode 100644 index 000000000000..56eb9680481c --- /dev/null +++ b/resources/icons/main/watch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/status_im/chat/commands/impl/transactions.cljs b/src/status_im/chat/commands/impl/transactions.cljs index 8a18e07caec5..f0efc0ddfada 100644 --- a/src/status_im/chat/commands/impl/transactions.cljs +++ b/src/status_im/chat/commands/impl/transactions.cljs @@ -17,7 +17,7 @@ [status-im.ui.components.list.views :as list] [status-im.ui.components.react :as react] [status-im.ui.components.svgimage :as svgimage] - [status-im.ui.screens.wallet.utils :as wallet.utils] + [status-im.wallet.utils :as wallet.utils] [status-im.utils.datetime :as datetime] [status-im.utils.money :as money] [status-im.utils.platform :as platform] diff --git a/src/status_im/ethereum/tokens.cljs b/src/status_im/ethereum/tokens.cljs index 361e1404b604..bc94b1313462 100644 --- a/src/status_im/ethereum/tokens.cljs +++ b/src/status_im/ethereum/tokens.cljs @@ -535,6 +535,7 @@ :custom []}) +;; TODO all these should be improved, we don't need to recalculate this each time, it can be done only once (defn tokens-for "makes sure all addresses are lower-case TODO: token list should be speced and not accept non-lower-cased addresses" diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index 524ebf2f2874..afbacae5aeaf 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -41,6 +41,9 @@ [status-im.stickers.core :as stickers] [status-im.transport.core :as transport] [status-im.transport.message.core :as transport.message] + status-im.wallet.choose-recipient.core + status-im.wallet.collectibles.core + status-im.wallet.accounts.core [status-im.ui.components.bottom-sheet.core :as bottom-sheet] [status-im.ui.components.react :as react] [status-im.ui.screens.add-new.new-chat.db :as new-chat.db] @@ -58,7 +61,9 @@ [status-im.wallet.custom-tokens.core :as custom-tokens] [status-im.wallet.db :as wallet.db] [status-im.web3.core :as web3] - [taoensso.timbre :as log])) + [taoensso.timbre :as log] + [status-im.chat.commands.sending :as commands.sending] + [status-im.utils.money :as money])) ;; init module @@ -1997,4 +2002,16 @@ (re-frame/reg-fx :dismiss-keyboard (fn [] - (react/dismiss-keyboard!))) \ No newline at end of file + (react/dismiss-keyboard!))) + +(handlers/register-handler-fx + :wallet-send-request + (fn [{:keys [db] :as cofx} [_ public-key amount symbol decimals]] + (assert public-key) + (let [request-command (get-in db [:id->command ["request" #{:personal-chats}]])] + (fx/merge cofx + (chat/start-chat public-key nil) + (commands.sending/send public-key + request-command + {:asset (name symbol) + :amount (str (money/internal->formatted amount symbol decimals))}))))) \ No newline at end of file diff --git a/src/status_im/subs.cljs b/src/status_im/subs.cljs index 0a9464324e06..f6d1376787d9 100644 --- a/src/status_im/subs.cljs +++ b/src/status_im/subs.cljs @@ -30,7 +30,7 @@ [status-im.ui.screens.mobile-network-settings.utils :as mobile-network-utils] - [status-im.ui.screens.wallet.utils :as wallet.utils] + [status-im.wallet.utils :as wallet.utils] [status-im.utils.build :as build] [status-im.utils.config :as config] [status-im.utils.datetime :as datetime] @@ -1016,6 +1016,21 @@ "0")) "..."))) +(re-frame/reg-sub + :wallet/sorted-chain-tokens + :<- [:wallet/all-tokens] + :<- [:ethereum/chain-keyword] + (fn [[all-tokens chain]] + (tokens/sorted-tokens-for all-tokens chain))) + +(re-frame/reg-sub + :wallet/grouped-chain-tokens + :<- [:wallet/sorted-chain-tokens] + :<- [:wallet/visible-tokens-symbols] + (fn [[all-tokens visible-tokens]] + (let [vt-set (set visible-tokens)] + (group-by :custom? (map #(assoc % :checked? (boolean (get vt-set (keyword (:symbol %))))) all-tokens))))) + (re-frame/reg-sub :wallet/balance-loading? :<- [:wallet] @@ -1053,6 +1068,30 @@ (fn [[balance visible-assets]] (map #(assoc % :amount (get balance (:symbol %))) visible-assets))) +(defn update-value [balance prices currency] + (fn [{:keys [symbol decimals] :as token}] + (let [price (get-in prices [symbol (-> currency :code keyword) :price])] + (assoc token + :price price + :value (when (and balance price) + (-> (money/internal->formatted (get balance symbol) symbol decimals) + (money/crypto->fiat price) + (money/with-precision 2) + str + (i18n/format-currency (:code currency)))))))) + +(re-frame/reg-sub + :wallet/visible-assets-with-values + :<- [:wallet/visible-assets-with-amount] + :<- [:prices] + :<- [:wallet/currency] + :<- [:balance] + (fn [[assets prices currency balance]] + (let [{:keys [tokens nfts]} (group-by #(if (:nft? %) :nfts :tokens) assets) + tokens-with-values (map (update-value balance prices currency) tokens)] + {:tokens tokens-with-values + :nfts nfts}))) + (re-frame/reg-sub :wallet/transferrable-assets-with-amount :<- [:wallet/visible-assets-with-amount] diff --git a/src/status_im/ui/components/icons/vector_icons.cljs b/src/status_im/ui/components/icons/vector_icons.cljs index e7dad7fdbf2d..d11df7420b85 100644 --- a/src/status_im/ui/components/icons/vector_icons.cljs +++ b/src/status_im/ui/components/icons/vector_icons.cljs @@ -202,6 +202,8 @@ :main-icons/wallet (components.svg/slurp-svg "./resources/icons/main/wallet.svg") :main-icons/warning (components.svg/slurp-svg "./resources/icons/main/warning.svg") :main-icons/wnode (components.svg/slurp-svg "./resources/icons/main/mailserver.svg") + :main-icons/watch (components.svg/slurp-svg "./resources/icons/main/watch.svg") + :main-icons/token (components.svg/slurp-svg "./resources/icons/main/token.svg") ;; Tiny icons :tiny-icons/tiny-arrow-down (components.svg/slurp-svg "./resources/icons/tiny/tiny_arrow_down.svg") :tiny-icons/tiny-check (components.svg/slurp-svg "./resources/icons/tiny/tiny_check.svg") diff --git a/src/status_im/ui/components/list_item/views.cljs b/src/status_im/ui/components/list_item/views.cljs index 048ec9972d19..91ae5c1bf120 100644 --- a/src/status_im/ui/components/list_item/views.cljs +++ b/src/status_im/ui/components/list_item/views.cljs @@ -12,7 +12,7 @@ ; theme - optional :default, :wallet -(defn list-item [{:keys [title subtitle accessories image image-path type theme on-press error] :or {type :default theme :default}}] +(defn list-item [{:keys [title subtitle accessories image image-path type theme on-press error content] :or {type :default theme :default}}] (let [small? (= :small type)] [react/touchable-highlight {:on-press on-press :disabled (not on-press)} [react/view {:style (styles/container small?)} @@ -27,38 +27,45 @@ [react/image {:source (utils.image/source image-path) :style (styles/photo 40)}]]) ;;Title - [react/view {:style {:margin-left 16 :margin-right 16}} - [react/text {:style (styles/title small? subtitle) - :number-of-lines 1 - :ellipsize-mode :tail} - title] - ;;Subtitle - (when subtitle - [react/text {:style styles/subtitle + (when title + [react/view {:style {:margin-left 16 :margin-right 16}} + [react/text {:style (styles/title small? subtitle) :number-of-lines 1 :ellipsize-mode :tail} - subtitle])] - ;;Accessories + title] + ;;Subtitle + (when subtitle + [react/text {:style styles/subtitle + :number-of-lines 1 + :ellipsize-mode :tail} + subtitle])]) + ;;Content + (when content + (if (vector? content) + content + [content])) [react/view {:flex 1}] + ;;Accessories (for [accessory accessories] - (with-meta - (cond - (= :chevron accessory) - [react/view - [icons/icon :main-icons/next {:color colors/gray-transparent-40}]] - (= :check accessory) - [react/view - [icons/icon :main-icons/check {:color colors/gray}]] - :else - [react/view {:padding-right 8 :flex-shrink 1} - (cond - (string? accessory) - [react/text {:style styles/accessory-text} - accessory] - (vector? accessory) - accessory - :else - [accessory])]) - {:key accessory})) + (when-not (nil? accessory) + (with-meta + (cond + (= :chevron accessory) + [react/view + [icons/icon :main-icons/next {:color colors/gray-transparent-40}]] + (= :check accessory) + [react/view + [icons/icon :main-icons/check {:color colors/gray}]] + :else + [react/view {:margin-right 8 :flex-shrink 1} + (cond + (string? accessory) + [react/text {:style styles/accessory-text :number-of-lines 1} + accessory] + (vector? accessory) + accessory + :else + [accessory])]) + {:key accessory}))) (when error [tooltip/tooltip error styles/error])]])) diff --git a/src/status_im/ui/components/status_bar/view.cljs b/src/status_im/ui/components/status_bar/view.cljs index 8da4fee8c107..9946ebafa18a 100644 --- a/src/status_im/ui/components/status_bar/view.cljs +++ b/src/status_im/ui/components/status_bar/view.cljs @@ -71,6 +71,7 @@ :wallet-onboarding-setup-modal {:type :modal-wallet} :wallet-send-transaction-modal {:type :modal-wallet} :wallet-settings-assets {:type :wallet} + :wallet-account {:type :wallet} :wallet-add-custom-token {:type :wallet} :wallet-sign-message-modal {:type :modal-wallet} :wallet-settings-hook {:type :wallet} diff --git a/src/status_im/ui/screens/events.cljs b/src/status_im/ui/screens/events.cljs index b040b30c7444..573369c9a387 100644 --- a/src/status_im/ui/screens/events.cljs +++ b/src/status_im/ui/screens/events.cljs @@ -9,15 +9,6 @@ status-im.web3.events status-im.ui.screens.add-new.new-chat.navigation status-im.ui.screens.profile.events - status-im.ui.screens.wallet.collectibles.events - status-im.ui.screens.wallet.send.events - status-im.ui.screens.wallet.request.events - status-im.ui.screens.wallet.choose-recipient.events - status-im.ui.screens.wallet.collectibles.cryptokitties.events - status-im.ui.screens.wallet.collectibles.cryptostrikers.events - status-im.ui.screens.wallet.collectibles.etheremon.events - status-im.ui.screens.wallet.collectibles.superrare.events - status-im.ui.screens.wallet.collectibles.kudos.events status-im.ui.screens.wallet.navigation status-im.utils.keychain.events [re-frame.core :as re-frame] @@ -31,7 +22,6 @@ [status-im.utils.handlers :as handlers] [status-im.utils.http :as http] [status-im.utils.utils :as utils] - [status-im.wallet.core :as wallet] [status-im.i18n :as i18n] [status-im.biometric-auth.core :as biometric-auth] [status-im.constants :as const])) diff --git a/src/status_im/ui/screens/profile/user/views.cljs b/src/status_im/ui/screens/profile/user/views.cljs index 23d4249c6748..c8f6a6e0ca28 100644 --- a/src/status_im/ui/screens/profile/user/views.cljs +++ b/src/status_im/ui/screens/profile/user/views.cljs @@ -104,8 +104,7 @@ :value value}])) (defn- my-profile-settings [{:keys [seed-backed-up? mnemonic]} - {:keys [settings] :as account} - currency + {:keys [settings]} logged-in? extensions] (let [show-backup-seed? (and (not seed-backed-up?) (not (string/blank? mnemonic))) @@ -116,11 +115,6 @@ :action-fn #(re-frame/dispatch [:profile.ui/ens-names-button-pressed]) :accessibility-label :ens-names-button}] [profile.components/settings-item-separator] - [profile.components/settings-item {:label-kw :t/main-currency - :value (:code currency) - :action-fn #(re-frame/dispatch [:navigate-to :currency-settings]) - :accessibility-label :currency-button}] - [profile.components/settings-item-separator] (when (and config/hardwallet-enabled? platform/android?) [profile.components/settings-item {:label-kw :t/status-keycard diff --git a/src/status_im/ui/screens/routing/profile_stack.cljs b/src/status_im/ui/screens/routing/profile_stack.cljs index fa8ad5227ba8..7877d8a95766 100644 --- a/src/status_im/ui/screens/routing/profile_stack.cljs +++ b/src/status_im/ui/screens/routing/profile_stack.cljs @@ -25,7 +25,6 @@ :edit-network :log-level-settings :fleet-settings - :currency-settings :mobile-network-settings :backup-seed :tribute-to-talk diff --git a/src/status_im/ui/screens/routing/screens.cljs b/src/status_im/ui/screens/routing/screens.cljs index 33bbd0a1abeb..150f09a06829 100644 --- a/src/status_im/ui/screens/routing/screens.cljs +++ b/src/status_im/ui/screens/routing/screens.cljs @@ -54,13 +54,13 @@ [status-im.ui.screens.stickers.views :as stickers] [status-im.ui.screens.wallet.collectibles.views :as collectibles] [status-im.ui.screens.wallet.components.views :as wallet.components] - [status-im.ui.screens.wallet.main.views :as wallet.main] - [status-im.ui.screens.wallet.onboarding.views :as wallet.onboarding] [status-im.ui.screens.wallet.request.views :as request] [status-im.ui.screens.wallet.send.views :as send] [status-im.ui.screens.wallet.settings.views :as wallet-settings] [status-im.ui.screens.wallet.transactions.views :as wallet-transactions] - [status-im.ui.screens.wallet.custom-tokens.views :as custom-tokens])) + [status-im.ui.screens.wallet.custom-tokens.views :as custom-tokens] + [status-im.ui.screens.wallet.accounts.views :as wallet.accounts] + [status-im.ui.screens.wallet.account.views :as wallet.account])) (def all-screens {:login login/login @@ -102,10 +102,9 @@ :tribute-learn-more [:modal tr-to-talk/learn-more] :chat-modal [:modal chat/chat-modal] :show-extension-modal [:modal extensions.module/show-extension-modal-view] - :wallet-onboarding-setup-modal [:modal wallet.onboarding/modal] - :wallet wallet.main/wallet + :wallet wallet.accounts/accounts-overview + :wallet-account wallet.account/account :collectibles-list collectibles/collectibles-list - :wallet-onboarding-setup wallet.onboarding/screen :contact-code wallet.components/contact-code :wallet-send-transaction send/send-transaction :recent-recipients wallet.components/recent-recipients diff --git a/src/status_im/ui/screens/routing/wallet_stack.cljs b/src/status_im/ui/screens/routing/wallet_stack.cljs index 35d86d875e6f..124a5ef75de3 100644 --- a/src/status_im/ui/screens/routing/wallet_stack.cljs +++ b/src/status_im/ui/screens/routing/wallet_stack.cljs @@ -3,6 +3,7 @@ (def wallet-stack {:name :wallet-stack :screens [:wallet + :wallet-account :collectibles-list :wallet-onboarding-setup :contact-code @@ -25,5 +26,6 @@ :extension-screen-holder :wallet-settings-assets :wallet-add-custom-token - :wallet-custom-token-details] + :wallet-custom-token-details + :currency-settings] :config {:initialRouteName :wallet}}) diff --git a/src/status_im/ui/screens/signing/sheets.cljs b/src/status_im/ui/screens/signing/sheets.cljs index 93f353e21a76..c7b25db88821 100644 --- a/src/status_im/ui/screens/signing/sheets.cljs +++ b/src/status_im/ui/screens/signing/sheets.cljs @@ -10,7 +10,7 @@ (views/defview fee-bottom-sheet [fee-display-symbol] (views/letsubs [{gas-edit :gas gas-price-edit :gasPrice max-fee :max-fee} [:signing/edit-fee]] [react/view - [react/view {:style {:margin-horizontal 16 :margin-vertical 8}} + [react/view {:style {:margin-horizontal 16 :margin-top 8}} [react/text {:style {:typography :title-bold}} (i18n/label :t/network-fee)] [react/view {:style {:flex-direction :row :margin-top 8}} [react/view {:flex 1} @@ -35,7 +35,7 @@ :auto-focus false}]] [react/view {:margin-top 58 :margin-left 10} [react/text (i18n/label :t/gwei)]]] - [react/view {:margin-vertical 28 :align-items :center} + [react/view {:margin-vertical 16 :align-items :center} [react/text {:style {:color colors/gray}} (i18n/label :t/wallet-transaction-total-fee)] [react/view {:height 8}] [react/nested-text {:style {:font-size 17}} diff --git a/src/status_im/ui/screens/signing/views.cljs b/src/status_im/ui/screens/signing/views.cljs index e26f22fd7184..76d80c92b254 100644 --- a/src/status_im/ui/screens/signing/views.cljs +++ b/src/status_im/ui/screens/signing/views.cljs @@ -7,7 +7,7 @@ [reagent.core :as reagent] [status-im.ui.components.list-item.views :as list-item] [status-im.ui.components.button.view :as button] - [status-im.ui.screens.wallet.utils :as wallet.utils] + [status-im.wallet.utils :as wallet.utils] [status-im.ui.components.list.views :as list] [status-im.ui.components.chat-icon.screen :as chat-icon] [status-im.ui.components.icons.vector-icons :as icons] diff --git a/src/status_im/ui/screens/views.cljs b/src/status_im/ui/screens/views.cljs index 0b7b9c250fc0..e6e30837ad6e 100644 --- a/src/status_im/ui/screens/views.cljs +++ b/src/status_im/ui/screens/views.cljs @@ -14,7 +14,12 @@ [status-im.ui.screens.mobile-network-settings.view :as mobile-network-settings] [status-im.ui.screens.home.sheet.views :as home.sheet] [status-im.ui.screens.routing.core :as routing] - [status-im.ui.screens.signing.views :as signing])) + [status-im.ui.screens.signing.views :as signing] + status-im.ui.screens.wallet.collectibles.etheremon.views + status-im.ui.screens.wallet.collectibles.cryptostrikers.views + status-im.ui.screens.wallet.collectibles.cryptokitties.views + status-im.ui.screens.wallet.collectibles.superrare.views + status-im.ui.screens.wallet.collectibles.kudos.views)) (defonce rand-label (when js/goog.DEBUG (rand/id))) diff --git a/src/status_im/ui/screens/wallet/account/styles.cljs b/src/status_im/ui/screens/wallet/account/styles.cljs new file mode 100644 index 000000000000..67db08c6805d --- /dev/null +++ b/src/status_im/ui/screens/wallet/account/styles.cljs @@ -0,0 +1,22 @@ +(ns status-im.ui.screens.wallet.account.styles + (:require [status-im.ui.components.colors :as colors])) + +(defn card [window-width] + {:width (- window-width 64) :height 161 + :background-color colors/blue + :shadow-offset {:width 0 :height 2} + :shadow-radius 8 + :shadow-opacity 1 + :shadow-color "rgba(0, 9, 26, 0.12)" + :elevation 2 + :border-radius 8 + :justify-content :space-between}) + +(def divider + {:height 52 + :width 1 + :background-color (colors/alpha colors/black 0.2) + :shadow-offset {:width 0 :height 2} + :shadow-radius 8 + :shadow-opacity 1 + :shadow-color "rgba(0, 9, 26, 0.12)"}) \ No newline at end of file diff --git a/src/status_im/ui/screens/wallet/account/views.cljs b/src/status_im/ui/screens/wallet/account/views.cljs new file mode 100644 index 000000000000..ff84d7a4a27c --- /dev/null +++ b/src/status_im/ui/screens/wallet/account/views.cljs @@ -0,0 +1,112 @@ +(ns status-im.ui.screens.wallet.account.views + (:require-macros [status-im.utils.views :as views]) + (:require [status-im.ui.components.react :as react] + [status-im.ui.components.status-bar.view :as status-bar] + [status-im.ui.components.toolbar.view :as toolbar] + [status-im.ui.components.colors :as colors] + [re-frame.core :as re-frame] + [status-im.ui.screens.wallet.accounts.views :as accounts] + [status-im.ui.screens.wallet.accounts.sheets :as sheets] + [reagent.core :as reagent] + [status-im.ui.components.bottom-bar.styles :as tabs.styles] + [status-im.ui.components.list.views :as list] + [status-im.i18n :as i18n] + [status-im.ui.components.icons.vector-icons :as icons] + [status-im.ui.screens.wallet.account.styles :as styles] + [status-im.ui.screens.wallet.transactions.views :as history] + [status-im.ethereum.core :as ethereum])) + +(def state (reagent/atom {:tab :assets})) + +(defn toolbar-view [title] + [react/view + [status-bar/status-bar] + [toolbar/toolbar {:transparent? true} + toolbar/default-nav-back + [toolbar/content-title title] + [toolbar/actions + [{:icon :main-icons/more + :icon-opts {:color :black} + :handler #(re-frame/dispatch [:bottom-sheet/show-sheet + {:content sheets/account-settings + :content-height 130}])}]]]]) + +(defn button [label icon handler] + [react/touchable-highlight {:on-press handler :style {:flex 1}} + [react/view {:flex 1 :align-items :center :justify-content :center} + [react/view {:flex-direction :row :align-items :center} + [icons/icon icon {:color colors/white}] + [react/text {:style {:margin-left 8 :color colors/white}} label]]]]) + +(views/defview account-card [] + (views/letsubs [currency [:wallet/currency] + portfolio-value [:portfolio-value] + window-width [:dimensions/window-width] + {:keys [address]} [:account/account]] + [react/view {:style (styles/card window-width)} + [react/view {:padding 16 :padding-bottom 12 :flex 1 :justify-content :space-between} + [react/nested-text {:style {:color colors/white-transparent :line-height 38 + :font-weight "600" :font-size 32}} + (accounts/total-tilde portfolio-value) + [{:style {:color colors/white}} portfolio-value] + " " + (:code currency)] + [react/text {:number-of-lines 1 :ellipsize-mode :middle + :style {:width (/ window-width 3) + :line-height 22 :font-size 13 + :font-family "monospace" + :color (colors/alpha colors/white 0.7)}} + (ethereum/normalized-address address)]] + [react/view {:position :absolute :top 12 :right 12} + [react/touchable-highlight {:on-press #(re-frame/dispatch [:wallet.accounts/share])} + [icons/icon :main-icons/share {:color colors/white}]]] + [react/view {:height 52 :background-color (colors/alpha colors/black 0.2) + :border-bottom-right-radius 8 :border-bottom-left-radius 8 :flex-direction :row} + [button (i18n/label :t/wallet-send) :main-icons/send #(re-frame/dispatch [:navigate-to :wallet-send-transaction])] + [react/view {:style styles/divider}] + [button (i18n/label :t/receive) :main-icons/receive #(re-frame/dispatch [:navigate-to :wallet-request-transaction])]]])) + +(views/defview transactions [] + (views/letsubs [{:keys [transaction-history-sections]} + [:wallet.transactions.history/screen]] + [history/history-list transaction-history-sections])) + +(views/defview assets-and-collections [] + (views/letsubs [{:keys [tokens nfts]} [:wallet/visible-assets-with-values] + currency [:wallet/currency]] + (let [{:keys [tab]} @state] + [react/view {:flex 1} + [react/view {:flex-direction :row :margin-bottom 8 :padding-horizontal 4} + [accounts/tab-title state :assets (i18n/label :t/wallet-assets) (= tab :assets)] + (when (seq nfts) + [accounts/tab-title state :nft (i18n/label :t/wallet-collectibles) (= tab :nft)]) + [accounts/tab-title state :history (i18n/label :t/history) (= tab :history)]] + (cond + (= tab :assets) + [list/flat-list {:data tokens + :default-separator? false + :key-fn :name + :footer [react/view + {:style {:height tabs.styles/tabs-diff + :align-self :stretch}}] + :render-fn (accounts/render-asset (:code currency))}] + (= tab :nft) + [list/flat-list {:data nfts + :default-separator? false + :key-fn :name + :footer [react/view + {:style {:height tabs.styles/tabs-diff + :align-self :stretch}}] + :render-fn accounts/render-collectible}] + (= tab :history) + [transactions])]))) + +(defn account [] + [react/view {:flex 1 :background-color colors/white} + [toolbar-view "Status account"] + [react/scroll-view + [react/view {:padding-left 16} + [react/scroll-view {:horizontal true} + [react/view {:flex-direction :row :padding-top 8 :padding-bottom 12} + [account-card]]]] + [assets-and-collections]]]) \ No newline at end of file diff --git a/src/status_im/ui/screens/wallet/accounts/sheets.cljs b/src/status_im/ui/screens/wallet/accounts/sheets.cljs new file mode 100644 index 000000000000..62a3d6f514c5 --- /dev/null +++ b/src/status_im/ui/screens/wallet/accounts/sheets.cljs @@ -0,0 +1,65 @@ +(ns status-im.ui.screens.wallet.accounts.sheets + (:require [re-frame.core :as re-frame] + [status-im.ui.components.action-button.action-button :as action-button] + [status-im.ui.components.react :as react] + [status-im.i18n :as i18n] + [status-im.ui.components.colors :as colors])) + +(defn hide-sheet-and-dispatch [event] + (re-frame/dispatch [:bottom-sheet/hide-sheet]) + (re-frame/dispatch event)) + +(defn accounts-options [seed-backed-up?] + (fn [] + [react/view + [action-button/action-button {:label (i18n/label :t/wallet-manage-assets) + :icon :main-icons/token + :icon-opts {:color :blue} + :on-press #(hide-sheet-and-dispatch [:navigate-to :wallet-settings-assets])}] + [action-button/action-button {:label (i18n/label :t/set-currency) + :icon :main-icons/language + :icon-opts {:color :blue} + :on-press #(hide-sheet-and-dispatch [:navigate-to :currency-settings])}] + [action-button/action-button-disabled {:label (i18n/label :t/view-signing) + :icon :main-icons/info + :icon-opts {:color :blue}}] + (when-not seed-backed-up? + [action-button/action-button {:label (i18n/label :t/wallet-backup-recovery-title) + :icon :main-icons/security + :icon-opts {:color colors/red} + :label-style {:color colors/red} + :cyrcle-color (colors/alpha colors/red 0.1) + :on-press #(hide-sheet-and-dispatch [:navigate-to :backup-seed])}])])) + +(defn send-receive [] + [react/view + [action-button/action-button {:label (i18n/label :t/wallet-send) + :icon :main-icons/send + :accessibility-label :send-transaction-button + :icon-opts {:color :blue} + :on-press #(hide-sheet-and-dispatch [:navigate-to :wallet-send-transaction])}] + [action-button/action-button {:label (i18n/label :t/receive) + :icon :main-icons/receive + :accessibility-label :receive-transaction-button + :icon-opts {:color :blue} + :on-press #(hide-sheet-and-dispatch [:navigate-to :wallet-request-transaction])}]]) + +(defn add-account [] + [react/view + [action-button/action-button-disabled {:label (i18n/label :t/add-an-account) + :icon :main-icons/add + :icon-opts {:color :blue} + :on-press #(hide-sheet-and-dispatch [:navigate-to :wallet-send-transaction])}] + [action-button/action-button-disabled {:label (i18n/label :t/add-a-watch-account) + :icon :main-icons/watch + :icon-opts {:color :blue} + :on-press #(hide-sheet-and-dispatch [:navigate-to :wallet-request-transaction])}]]) + +(defn account-settings [] + [react/view + [action-button/action-button-disabled {:label (i18n/label :t/account-settings) + :icon :main-icons/info + :icon-opts {:color :blue}}] + [action-button/action-button-disabled {:label (i18n/label :t/export-account) + :icon :main-icons/copy + :icon-opts {:color :blue}}]]) \ No newline at end of file diff --git a/src/status_im/ui/screens/wallet/accounts/styles.cljs b/src/status_im/ui/screens/wallet/accounts/styles.cljs new file mode 100644 index 000000000000..57fdeafb3845 --- /dev/null +++ b/src/status_im/ui/screens/wallet/accounts/styles.cljs @@ -0,0 +1,35 @@ +(ns status-im.ui.screens.wallet.accounts.styles + (:require [status-im.ui.components.colors :as colors])) + +(def card + {:width 156 + :height 145 + :background-color colors/blue + :shadow-offset {:width 0 :height 2} + :shadow-radius 8 + :shadow-opacity 1 + :shadow-color "rgba(0, 9, 26, 0.12)" + :elevation 2 + :border-radius 8 + :justify-content :space-between + :padding 12 + :padding-bottom 6 + :margin-top 5 + :margin-bottom 5}) + +(def add-card + {:width 156 + :height 145 + :margin-left 16 + :margin-top 5 + :margin-right 5 + :margin-bottom 5 + :background-color colors/white + :shadow-offset {:width 0 :height 2} + :shadow-radius 8 + :shadow-opacity 1 + :shadow-color "rgba(0, 9, 26, 0.12)" + :elevation 2 + :border-radius 8 + :justify-content :center + :align-items :center}) diff --git a/src/status_im/ui/screens/wallet/accounts/views.cljs b/src/status_im/ui/screens/wallet/accounts/views.cljs new file mode 100644 index 000000000000..ef46ddb35fa6 --- /dev/null +++ b/src/status_im/ui/screens/wallet/accounts/views.cljs @@ -0,0 +1,166 @@ +(ns status-im.ui.screens.wallet.accounts.views + (:require-macros [status-im.utils.views :as views]) + (:require [status-im.ui.components.react :as react] + [status-im.ui.components.status-bar.view :as status-bar] + [status-im.ui.components.icons.vector-icons :as icons] + [status-im.ui.components.toolbar.styles :as toolbar.styles] + [status-im.ui.components.colors :as colors] + [status-im.i18n :as i18n] + [status-im.ui.components.list.views :as list] + [status-im.ui.components.chat-icon.screen :as chat-icon] + [status-im.ui.components.list-item.views :as list-item] + [status-im.wallet.utils :as wallet.utils] + [status-im.ui.components.bottom-bar.styles :as tabs.styles] + [reagent.core :as reagent] + [status-im.utils.money :as money] + [re-frame.core :as re-frame] + [status-im.ui.screens.wallet.accounts.sheets :as sheets] + [status-im.ethereum.core :as ethereum] + [status-im.ui.screens.wallet.accounts.styles :as styles])) + +(def state (reagent/atom {:tab :assets})) + +(defn total-tilde [value] + (when (and (not= "0" value) (not= "..." value)) "~")) + +(views/defview account-card [name] + (views/letsubs [currency [:wallet/currency] + portfolio-value [:portfolio-value] + {:keys [address]} [:account/account]] + [react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :wallet-account]) + :on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet + {:content sheets/send-receive + :content-height 130}])} + [react/view {:style styles/card} + [react/view {:flex-direction :row :align-items :center :justify-content :space-between} + [react/nested-text {:style {:color colors/white-transparent :font-weight "500"}} + (total-tilde portfolio-value) + [{:style {:color colors/white}} portfolio-value] + " " + (:code currency)] + [react/touchable-highlight {:on-press #(re-frame/dispatch [:wallet.accounts/share])} + [icons/icon :main-icons/share {:color colors/white}]]] + [react/view + [react/text {:style {:color colors/white :font-weight "500" :line-height 22}} name] + [react/text {:number-of-lines 1 :ellipsize-mode :middle + :style {:line-height 22 :font-size 13 + :font-family "monospace" + :color (colors/alpha colors/white 0.7)}} + (ethereum/normalized-address address)]]]])) + +(defn add-card [] + [react/touchable-highlight {:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet + {:content sheets/add-account + :content-height 130}])} + [react/view {:style styles/add-card} + [react/view {:width 40 :height 40 :justify-content :center :border-radius 20 + :align-items :center :background-color (colors/alpha colors/blue 0.1) :margin-bottom 8} + [icons/icon :main-icons/add {:color colors/blue}]] + [react/text {:style {:color colors/blue}} (i18n/label :t/add-account)]]]) + +(defn tab-title [state key label active?] + [react/view {:align-items :center} + [react/touchable-highlight {:on-press #(swap! state assoc :tab key) + :underlay-color colors/gray-lighter + :style {:border-radius 8}} + [react/view {:padding-horizontal 12 :padding-vertical 9} + [react/text {:style {:font-weight "500" :color (if active? colors/black colors/gray) :line-height 22}} + label]]] + (when active? + [react/view {:width 24 :height 3 :border-radius 4 :background-color colors/blue}])]) + +(defn render-asset [currency] + (fn [{:keys [icon decimals amount color value] :as token}] + [list-item/list-item + {:content [react/view {:style {:margin-horizontal 16 :justify-content :center :flex-shrink 1}} + [react/view {:flex-direction :row} + [react/text {:style {:font-weight "500" :flex-shrink 0.5} :number-of-lines 1 :ellipsize-mode :tail} + (wallet.utils/format-amount amount decimals)] + [react/text {:style {:font-weight "500" :color colors/gray :margin-left 6} + :number-of-lines 1} + (wallet.utils/display-symbol token)]] + [react/text {:style {:color colors/gray}} (str value " " currency)]] + :image (if icon + [list/item-image icon] + [chat-icon/custom-icon-view-list (:name token) color])}])) + +(defn render-collectible [{:keys [name icon amount] :as collectible}] + (let [items-number (money/to-fixed amount) + details? (pos? items-number)] + [react/touchable-highlight + (when details? + {:on-press #(re-frame/dispatch [:show-collectibles-list collectible])}) + [list-item/list-item + {:title (wallet.utils/display-symbol collectible) + :subtitle name + :image [list/item-image icon] + :accessories [items-number :chevron]}]])) + +(views/defview assets-and-collections [] + (views/letsubs [{:keys [tokens nfts]} [:wallet/visible-assets-with-values] + currency [:wallet/currency]] + (let [{:keys [tab]} @state] + [react/view {:flex 1} + [react/view {:flex-direction :row :margin-bottom 8 :margin-horizontal 4} + [tab-title state :assets (i18n/label :t/wallet-assets) (= tab :assets)] + [tab-title state :nft (i18n/label :t/wallet-collectibles) (= tab :nft)]] + (if (= tab :assets) + [list/flat-list {:data tokens + :default-separator? false + :key-fn :name + :footer [react/view + {:style {:height tabs.styles/tabs-diff + :align-self :stretch}}] + :render-fn (render-asset (:code currency))}] + (if (seq nfts) + [list/flat-list {:data nfts + :default-separator? false + :key-fn :name + :footer [react/view + {:style {:height tabs.styles/tabs-diff + :align-self :stretch}}] + :render-fn render-collectible}] + [react/view {:align-items :center :margin-top 32} + [react/text {:style {:color colors/gray}} + (i18n/label :t/no-collectibles)]]))]))) + +(views/defview total-value [] + (views/letsubs [currency [:wallet/currency] + portfolio-value [:portfolio-value]] + [react/view + [react/nested-text {:style {:font-size 32 :color colors/gray :font-weight "600"}} + (total-tilde portfolio-value) + [{:style {:color colors/black}} portfolio-value] + " " + (:code currency)] + [react/text {:style {:color colors/gray}} (i18n/label :t/wallet-total-value)]])) + +(views/defview accounts-options [] + (views/letsubs [{:keys [seed-backed-up?]} [:account/account]] + [react/view {:flex-direction :row :align-items :center} + [react/view {:flex 1 :padding-left 16} + (when-not seed-backed-up? + [react/view {:flex-direction :row :align-items :center} + [react/view {:width 14 :height 14 :background-color colors/gray :border-radius 7 :align-items :center + :justify-content :center :margin-right 9} + [react/text {:style {:color colors/white :font-size 13 :font-weight "700"}} "!"]] + [react/text {:style {:color colors/gray}} (i18n/label :t/back-up-your-seed-phrase)]])] + [react/touchable-highlight {:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet + {:content (sheets/accounts-options seed-backed-up?) + :content-height (if seed-backed-up? 190 250)}])} + [react/view {:height toolbar.styles/toolbar-height :width toolbar.styles/toolbar-height :align-items :center + :justify-content :center} + [icons/icon :main-icons/more]]]])) + +(defn accounts-overview [] + [react/view {:flex 1} + [status-bar/status-bar] + [react/scroll-view + [accounts-options] + [react/view {:margin-top 8 :padding-horizontal 16} + [total-value] + [react/scroll-view {:horizontal true} + [react/view {:flex-direction :row :padding-top 11 :padding-bottom 12} + [account-card "Status account"] + [add-card]]]] + [assets-and-collections]]]) \ No newline at end of file diff --git a/src/status_im/ui/screens/wallet/choose_recipient/events.cljs b/src/status_im/ui/screens/wallet/choose_recipient/events.cljs deleted file mode 100644 index bb0fae988ab7..000000000000 --- a/src/status_im/ui/screens/wallet/choose_recipient/events.cljs +++ /dev/null @@ -1,122 +0,0 @@ -(ns status-im.ui.screens.wallet.choose-recipient.events - (:require [re-frame.core :as re-frame] - [status-im.constants :as constants] - [status-im.contact.db :as contact.db] - [status-im.ethereum.core :as ethereum] - [status-im.ethereum.eip55 :as eip55] - [status-im.ethereum.eip681 :as eip681] - [status-im.ethereum.ens :as ens] - [status-im.i18n :as i18n] - [status-im.utils.handlers :as handlers] - [status-im.utils.money :as money])) - -(handlers/register-handler-fx - :wallet/toggle-flashlight - (fn [{:keys [db]}] - (let [flashlight-state (get-in db [:wallet :send-transaction :camera-flashlight]) - toggled-state (if (= :on flashlight-state) :off :on)] - {:db (assoc-in db [:wallet :send-transaction :camera-flashlight] toggled-state)}))) - -(defn- find-address-name [db address] - (:name (contact.db/find-contact-by-address (:contacts/contacts db) address))) - -(defn- fill-request-details [db {:keys [address name value symbol gas gasPrice public-key from-chat?]} request?] - {:pre [(not (nil? address))]} - (let [name (or name (find-address-name db address)) - data-path (if request? - [:wallet :request-transaction] - [:wallet :send-transaction])] - (update-in db data-path - (fn [{old-symbol :symbol :as old-transaction}] - (let [symbol-changed? (not= old-symbol symbol)] - (cond-> (assoc old-transaction :to address :to-name name :public-key public-key) - value (assoc :amount value) - symbol (assoc :symbol symbol) - (and gas symbol-changed?) (assoc :gas (money/bignumber gas)) - from-chat? (assoc :from-chat? from-chat?) - (and gasPrice symbol-changed?) - (assoc :gas-price (money/bignumber gasPrice)) - (and symbol (not gasPrice) symbol-changed?) - (assoc :gas-price (ethereum/estimate-gas symbol)))))))) - -(defn- extract-details - "First try to parse as EIP681 URI, if not assume this is an address directly. - Returns a map containing at least the `address` and `chain-id` keys" - [s chain-id all-tokens] - (or (let [m (eip681/parse-uri s)] - (merge m (eip681/extract-request-details m all-tokens))) - (when (ethereum/address? s) - {:address s :chain-id chain-id}))) - -;; NOTE(janherich) - whenever changing assets, we want to clear the previusly set amount/amount-text -(defn changed-asset [{:keys [db] :as fx} old-symbol new-symbol] - (-> fx - (merge {:wallet/update-gas-price - {:success-event :wallet/update-gas-price-success - :edit? false}}) - (assoc-in [:db :wallet :send-transaction :amount] nil) - (assoc-in [:db :wallet :send-transaction :amount-text] nil) - (assoc-in [:db :wallet :send-transaction :asset-error] - (i18n/label :t/changed-asset-warning {:old old-symbol :new new-symbol})))) - -(defn changed-amount-warning [fx old-amount new-amount] - (assoc-in fx [:db :wallet :send-transaction :amount-error] - (i18n/label :t/changed-amount-warning {:old old-amount :new new-amount}))) - -(defn use-default-eth-gas [fx] - (assoc-in fx [:db :wallet :send-transaction :gas] - (ethereum/default-transaction-gas))) - -(re-frame/reg-fx - :resolve-address - (fn [{:keys [registry ens-name cb]}] - (ens/get-addr registry ens-name cb))) - -(handlers/register-handler-fx - :wallet.send/set-recipient - (fn [{:keys [db]} [_ recipient]] - (let [chain (ethereum/chain-keyword db)] - (if (ens/is-valid-eth-name? recipient) - {:resolve-address {:registry (get ens/ens-registries chain) - :ens-name recipient - :cb #(re-frame/dispatch [:wallet.send/set-recipient %])}} - (if (ethereum/address? recipient) - (let [checksum (eip55/address->checksum recipient)] - (if (eip55/valid-address-checksum? checksum) - {:db (assoc-in db [:wallet :send-transaction :to] checksum) - :dispatch [:navigate-back]} - {:ui/show-error (i18n/label :t/wallet-invalid-address-checksum {:data recipient})})) - {:ui/show-error (i18n/label :t/wallet-invalid-address {:data recipient})}))))) - -(handlers/register-handler-fx - :wallet/fill-request-from-url - (fn [{{:keys [network] :wallet/keys [all-tokens] :as db} :db} [_ data origin]] - (let [current-chain-id (get-in constants/default-networks [network :config :NetworkId]) - {:keys [address chain-id] :as details} (extract-details data current-chain-id all-tokens) - valid-network? (boolean (= current-chain-id chain-id)) - previous-state (get-in db [:wallet :send-transaction]) - old-symbol (:symbol previous-state) - new-symbol (:symbol details) - old-amount (:amount previous-state) - new-amount (:value details) - new-gas (:gas details) - symbol-changed? (and old-symbol new-symbol (not= old-symbol new-symbol))] - (cond-> {:db db} - (not= :deep-link origin) (assoc :dispatch [:navigate-back]) ;; Only navigate-back when called from within wallet - (and address valid-network?) (update :db #(fill-request-details % details false)) - symbol-changed? (changed-asset old-symbol new-symbol) - (and old-amount new-amount (not= old-amount new-amount)) (changed-amount-warning old-amount new-amount) - ;; NOTE(goranjovic) - the next line is there is because QR code scanning switches the amount to ETH - ;; automatically, so we need to update the gas limit accordingly. The check for origin screen is there - ;; so that we wouldn't also switch gas limit to ETH specific if the user pastes address as text. - ;; We need to check if address is defined so that we wouldn't trigger this behavior when invalid QR is scanned - ;; (e.g. public-key) - (and address (= origin :qr) (not new-gas) symbol-changed?) (use-default-eth-gas) - (not address) (assoc :ui/show-error (i18n/label :t/wallet-invalid-address {:data data})) - (and address (not valid-network?)) (assoc :ui/show-error (i18n/label :t/wallet-invalid-chain-id {:data data :chain current-chain-id})))))) - -(handlers/register-handler-fx - :wallet/fill-request-from-contact - (fn [{db :db} [_ {:keys [address name public-key]} request?]] - {:db (fill-request-details db {:address address :name name :public-key public-key} request?) - :dispatch [:navigate-back]})) diff --git a/src/status_im/ui/screens/wallet/choose_recipient/views.cljs b/src/status_im/ui/screens/wallet/choose_recipient/views.cljs index 594cb490ba23..660c6fb684f5 100644 --- a/src/status_im/ui/screens/wallet/choose_recipient/views.cljs +++ b/src/status_im/ui/screens/wallet/choose_recipient/views.cljs @@ -9,7 +9,6 @@ [status-im.ui.components.status-bar.view :as status-bar] [status-im.ui.components.toolbar.actions :as actions] [status-im.ui.components.toolbar.view :as toolbar] - [status-im.ui.components.colors :as colors] [status-im.ui.screens.wallet.choose-recipient.styles :as styles] [status-im.utils.platform :as platform])) diff --git a/src/status_im/ui/screens/wallet/collectibles/cryptokitties/events.cljs b/src/status_im/ui/screens/wallet/collectibles/cryptokitties/events.cljs deleted file mode 100644 index d615e97c7c92..000000000000 --- a/src/status_im/ui/screens/wallet/collectibles/cryptokitties/events.cljs +++ /dev/null @@ -1,31 +0,0 @@ -(ns status-im.ui.screens.wallet.collectibles.cryptokitties.events - (:require [status-im.utils.handlers :as handlers] - [status-im.ui.screens.wallet.collectibles.events :as collectibles] - [status-im.utils.http :as http])) - -(def ck :CK) - -(handlers/register-handler-fx - :load-kitties - (fn [{db :db} [_ ids]] - {:db db - :http-get-n (mapv (fn [id] - {:url (str "https://api.cryptokitties.co/kitties/" id) - :success-event-creator (fn [o] - [:load-collectible-success ck {id (http/parse-payload o)}]) - :failure-event-creator (fn [o] - [:load-collectible-failure ck {id (http/parse-payload o)}])}) - ids)})) - -;; TODO(andrey) Each HTTP call will return up to 100 kitties. Maybe we need to implement some kind of paging later -(defmethod collectibles/load-collectibles-fx ck [_ _ items-number address _] - {:http-get {:url (str "https://api.cryptokitties.co/kitties?offset=0&limit=" - items-number - "&owner_wallet_address=" - address - "&parents=false") - :success-event-creator (fn [o] - [:load-kitties (map :id (:kitties (http/parse-payload o)))]) - :failure-event-creator (fn [o] - [:load-collectibles-failure (http/parse-payload o)]) - :timeout-ms 10000}}) diff --git a/src/status_im/ui/screens/wallet/collectibles/cryptostrikers/events.cljs b/src/status_im/ui/screens/wallet/collectibles/cryptostrikers/events.cljs deleted file mode 100644 index 049f246c135f..000000000000 --- a/src/status_im/ui/screens/wallet/collectibles/cryptostrikers/events.cljs +++ /dev/null @@ -1,12 +0,0 @@ -(ns status-im.ui.screens.wallet.collectibles.cryptostrikers.events - (:require [status-im.ui.screens.wallet.collectibles.events :as collectibles] - [status-im.utils.http :as http])) - -(def strikers :STRK) - -(defmethod collectibles/load-collectible-fx strikers [_ _ id] - {:http-get {:url (str "https://us-central1-cryptostrikers-prod.cloudfunctions.net/cards/" id) - :success-event-creator (fn [o] - [:load-collectible-success strikers {id (http/parse-payload o)}]) - :failure-event-creator (fn [o] - [:load-collectible-failure strikers {id (http/parse-payload o)}])}}) \ No newline at end of file diff --git a/src/status_im/ui/screens/wallet/collectibles/etheremon/events.cljs b/src/status_im/ui/screens/wallet/collectibles/etheremon/events.cljs deleted file mode 100644 index 6d127588508b..000000000000 --- a/src/status_im/ui/screens/wallet/collectibles/etheremon/events.cljs +++ /dev/null @@ -1,12 +0,0 @@ -(ns status-im.ui.screens.wallet.collectibles.etheremon.events - (:require [status-im.ui.screens.wallet.collectibles.events :as collectibles] - [status-im.utils.http :as http])) - -(def emona :EMONA) - -(defmethod collectibles/load-collectible-fx emona [_ _ id] - {:http-get {:url (str "https://www.etheremon.com/api/monster/get_data?monster_ids=" id) - :success-event-creator (fn [o] - [:load-collectible-success emona (:data (http/parse-payload o))]) - :failure-event-creator (fn [o] - [:load-collectible-failure emona {id (http/parse-payload o)}])}}) \ No newline at end of file diff --git a/src/status_im/ui/screens/wallet/collectibles/events.cljs b/src/status_im/ui/screens/wallet/collectibles/events.cljs deleted file mode 100644 index 03a3b6af3644..000000000000 --- a/src/status_im/ui/screens/wallet/collectibles/events.cljs +++ /dev/null @@ -1,74 +0,0 @@ -(ns status-im.ui.screens.wallet.collectibles.events - (:require [re-frame.core :as re-frame] - [status-im.browser.core :as browser] - [status-im.constants :as constants] - [status-im.ethereum.core :as ethereum] - [status-im.ethereum.erc721 :as erc721] - [status-im.ethereum.tokens :as tokens] - [status-im.utils.handlers :as handlers] - [status-im.utils.money :as money])) - -(defmulti load-collectible-fx (fn [_ symbol _] symbol)) - -(defmethod load-collectible-fx :default [_ _ _] nil) - -(defmulti load-collectibles-fx (fn [_ symbol _ _] symbol)) - -(defmethod load-collectibles-fx :default [all-tokens symbol items-number address chain-id] - {:load-collectibles-fx [all-tokens symbol items-number address chain-id]}) - -(handlers/register-handler-fx - :show-collectibles-list - (fn [{:keys [db]} [_ address {:keys [symbol amount] :as collectible}]] - (let [chain-id (get-in constants/default-networks [(:network db) :config :NetworkId]) - all-tokens (:wallet/all-tokens db) - items-number (money/to-number amount) - loaded-items-number (count (get-in db [:collectibles symbol]))] - (merge (when (not= items-number loaded-items-number) - (load-collectibles-fx all-tokens symbol items-number address chain-id)) - {:dispatch [:navigate-to :collectibles-list collectible]})))) - -(defn load-token [i items-number contract address symbol] - (when (< i items-number) - (erc721/token-of-owner-by-index contract address i - (fn [response] - (load-token (inc i) items-number contract address symbol) - (re-frame/dispatch [:load-collectible symbol (.toNumber response)]))))) - -(re-frame/reg-fx - :load-collectibles-fx - (fn [[all-tokens symbol items-number address chain-id]] - (let [chain (ethereum/chain-id->chain-keyword chain-id) - contract (:address (tokens/symbol->token all-tokens chain symbol))] - (load-token 0 items-number contract address symbol)))) - -(handlers/register-handler-fx - :load-collectible - (fn [cofx [_ symbol token-id]] - (load-collectible-fx cofx symbol token-id))) - -(handlers/register-handler-fx - :store-collectibles - (fn [{db :db} [_ symbol collectibles]] - {:db (update-in db [:collectibles symbol] merge - (reduce #(assoc %1 (:tokenId %2) %2) {} collectibles))})) - -(handlers/register-handler-fx - :load-collectible-success - (fn [{db :db} [_ symbol collectibles]] - {:db (update-in db [:collectibles symbol] merge collectibles)})) - -(handlers/register-handler-fx - :load-collectibles-failure - (fn [{db :db} [_ reason]] - {:db (update-in db [:collectibles symbol :errors] merge reason)})) - -(handlers/register-handler-fx - :load-collectible-failure - (fn [{db :db} [_]] - {:db db})) - -(handlers/register-handler-fx - :open-collectible-in-browser - (fn [cofx [_ url]] - (browser/open-url cofx url))) diff --git a/src/status_im/ui/screens/wallet/collectibles/kudos/events.cljs b/src/status_im/ui/screens/wallet/collectibles/kudos/events.cljs deleted file mode 100644 index c7f980765b7d..000000000000 --- a/src/status_im/ui/screens/wallet/collectibles/kudos/events.cljs +++ /dev/null @@ -1,45 +0,0 @@ -(ns status-im.ui.screens.wallet.collectibles.kudos.events - (:require [clojure.string :as string] - [re-frame.core :as re-frame] - [status-im.constants :as constants] - [status-im.ethereum.core :as ethereum] - [status-im.ethereum.erc721 :as erc721] - [status-im.ethereum.tokens :as tokens] - [status-im.ui.screens.wallet.collectibles.events :as collectibles] - [status-im.utils.handlers :as handlers] - [status-im.utils.http :as http])) - -(def kudos :KDO) - -(defmethod collectibles/load-collectible-fx kudos [{db :db} symbol id] - (let [chain-id (get-in constants/default-networks [(:network db) :config :NetworkId]) - all-tokens (:wallet/all-tokens db)] - {:erc721-token-uri [all-tokens symbol id chain-id]})) - -(re-frame/reg-fx - :erc721-token-uri - (fn [[all-tokens symbol tokenId chain-id]] - (let [chain (ethereum/chain-id->chain-keyword chain-id) - contract (:address (tokens/symbol->token all-tokens chain symbol))] - (erc721/token-uri contract - tokenId - #(re-frame/dispatch [:token-uri-success - tokenId - (when % - (subs % (.indexOf % "http")))]))))) ;; extra chars in rinkeby - -(handlers/register-handler-fx - :token-uri-success - (fn [_ [_ tokenId token-uri]] - {:http-get {:url - token-uri - :success-event-creator - (fn [o] - [:load-collectible-success kudos {tokenId (update (http/parse-payload o) - :image - string/replace - #"http:" - "https:")}]) ;; http in mainnet - :failure-event-creator - (fn [o] - [:load-collectible-failure kudos {tokenId (http/parse-payload o)}])}})) diff --git a/src/status_im/ui/screens/wallet/collectibles/superrare/events.cljs b/src/status_im/ui/screens/wallet/collectibles/superrare/events.cljs deleted file mode 100644 index 383562b88198..000000000000 --- a/src/status_im/ui/screens/wallet/collectibles/superrare/events.cljs +++ /dev/null @@ -1,41 +0,0 @@ -(ns status-im.ui.screens.wallet.collectibles.superrare.events - (:require [status-im.ethereum.core :as ethereum] - [status-im.ui.screens.wallet.collectibles.events :as collectibles] - [status-im.utils.http :as http] - [status-im.utils.types :as types])) - -(def superrare :SUPR) - -(defmethod collectibles/load-collectible-fx superrare [_ _ ids] - {:http-get-n (mapv (fn [id] - {:url id - :success-event-creator (fn [o] - [:load-collectible-success superrare {id (http/parse-payload o)}]) - :failure-event-creator (fn [o] - [:load-collectible-failure superrare {id (http/parse-payload o)}])}) - ids)}) - -(def graphql-url "https://api.pixura.io/graphql") - -(defn graphql-query [address] - (str "{ - collectiblesByOwner: allErc721Tokens(condition: {owner: \"" address "\"}) { - collectibles: nodes { - tokenId, - metadata: erc721MetadatumByTokenId { - metadataUri, - description, - name, - imageUri - }}}}")) - -(defmethod collectibles/load-collectibles-fx superrare [_ _ _ address _] - {:http-post {:url graphql-url - :data (types/clj->json {:query (graphql-query (ethereum/naked-address address))}) - :opts {:headers {"Content-Type" "application/json"}} - :success-event-creator (fn [{:keys [response-body]}] - [:store-collectibles superrare - (get-in (http/parse-payload response-body) [:data :collectiblesByOwner :collectibles])]) - :failure-event-creator (fn [{:keys [response-body]}] - [:load-collectibles-failure (http/parse-payload response-body)]) - :timeout-ms 10000}}) diff --git a/src/status_im/ui/screens/wallet/components/styles.cljs b/src/status_im/ui/screens/wallet/components/styles.cljs index e90e0a8ac1f9..11292c5ad645 100644 --- a/src/status_im/ui/screens/wallet/components/styles.cljs +++ b/src/status_im/ui/screens/wallet/components/styles.cljs @@ -3,8 +3,6 @@ (:require [status-im.ui.components.colors :as colors] [status-im.ui.components.styles :as styles])) -;; Components - (def cartouche-container {:flex 1 :margin-top 16 @@ -31,18 +29,6 @@ :justify-content :space-between :align-items :center}) -(def cartouche-text-wrapper - {:flex-direction :row - :justify-content :space-between - :padding-horizontal 15 - :padding-vertical 15}) - -(def cartouche-primary-text - {:color colors/white}) - -(def cartouche-secondary-text - {:color colors/white-transparent}) - (def text-content {:color colors/white}) @@ -193,4 +179,4 @@ :background-color colors/white-light-transparent}) (def button-text - {:color colors/white}) + {:color colors/white}) \ No newline at end of file diff --git a/src/status_im/ui/screens/wallet/components/views.cljs b/src/status_im/ui/screens/wallet/components/views.cljs index 6f4af222fa49..af52821ccda9 100644 --- a/src/status_im/ui/screens/wallet/components/views.cljs +++ b/src/status_im/ui/screens/wallet/components/views.cljs @@ -25,7 +25,7 @@ :as choose-recipient] [status-im.ui.screens.wallet.components.styles :as styles] - [status-im.ui.screens.wallet.utils :as wallet.utils] + [status-im.wallet.utils :as wallet.utils] [status-im.utils.core :as utils.core] [status-im.utils.money :as money] [status-im.utils.utils :as utils.utils]) @@ -90,19 +90,6 @@ [vector-icons/icon icon (merge {:color :white} icon-opts)]] content)]]])]) -(defn- cartouche-primary-text [s] - [react/text {:style styles/cartouche-primary-text} - s]) - -(defn cartouche-secondary-text [s] - [react/text {:style styles/cartouche-secondary-text} - s]) - -(defn cartouche-text-content [primary secondary] - [react/view styles/cartouche-text-wrapper - [cartouche-primary-text primary] - [cartouche-secondary-text secondary]]) - (defn view-asset [symbol] [react/view [react/i18n-text {:style styles/label :key :wallet-asset}] diff --git a/src/status_im/ui/screens/wallet/custom_tokens/views.cljs b/src/status_im/ui/screens/wallet/custom_tokens/views.cljs index d4f789f7443b..d170b8e8e048 100644 --- a/src/status_im/ui/screens/wallet/custom_tokens/views.cljs +++ b/src/status_im/ui/screens/wallet/custom_tokens/views.cljs @@ -8,7 +8,7 @@ [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.wallet.utils :as wallet.utils] [status-im.i18n :as i18n] [status-im.ui.components.action-button.action-button :as action-button])) diff --git a/src/status_im/ui/screens/wallet/main/styles.cljs b/src/status_im/ui/screens/wallet/main/styles.cljs deleted file mode 100644 index cd2af7cca1e2..000000000000 --- a/src/status_im/ui/screens/wallet/main/styles.cljs +++ /dev/null @@ -1,123 +0,0 @@ -(ns status-im.ui.screens.wallet.main.styles - (:require-macros [status-im.utils.styles :refer [defstyle]]) - (:require [status-im.ui.components.colors :as colors])) - -;; Main section - -(defstyle main-section - {:flex 1}) - -(defstyle scroll-bottom - {:background-color colors/white - :zIndex -1 - :position :absolute - :left 0 - :right 0 - :android {:height 0} - :ios {:height 9999}}) - -(def backup-seed-phrase-container - {:flex-direction :row - :background-color colors/black-transparent - :margin 16 - :border-radius 8 - :padding-top 10 - :padding-bottom 10 - :padding-horizontal 16}) - -(def backup-seed-phrase-title - {:color colors/white}) - -(def backup-seed-phrase-description - {:color colors/white-transparent}) - -(def total-balance-text - {:text-align :center - :padding-top 49 - :padding-bottom 38 - :background-color colors/blue - :color colors/white-transparent - :font-size 32}) - -(def total-balance-value - {:font-weight "700" - :color colors/white}) - -(def total-balance-currency - {:font-weight "700"}) - -(def snackbar-container - {:background-color colors/gray}) - -(def snackbar-text - {:color colors/white - :margin-horizontal 50 - :margin-vertical 10 - :text-align :center}) - -;; Actions section - -(def action - {:background-color colors/white-transparent - :width 40 - :height 40 - :border-radius 50}) - -(def action-label - {:color :white}) - -(def action-separator - {:height 1 - :background-color colors/white-light-transparent - :margin-left 70}) - -;; Assets section - -(def asset-section - {:flex 1 - :padding-top 5 - :padding-bottom 20}) - -(def asset-section-header - {:color colors/gray - :margin-left 16 - :margin-top 7 - :margin-bottom 3}) - -(def asset-item-container - {:flex 1 - :flex-direction :row - :align-items :center - :justify-content :space-between}) - -(def asset-item-value-container - {:flex 1 - :flex-direction :row - :align-items :center}) - -(def asset-item-value - {:flex -1 - :font-size 16}) - -(def asset-item-currency - {:font-size 16 - :color colors/gray - :margin-left 6}) - -(def asset-item-price - {:font-size 16 - :color colors/gray - :margin-left 6}) - -(def wallet-address - {:color colors/white - :text-align :center}) - -(def address-section - {:flex-grow 1 - :align-items :center - :padding 20}) - -(def modal-history - {:flex 1 - :background-color :white}) diff --git a/src/status_im/ui/screens/wallet/main/views.cljs b/src/status_im/ui/screens/wallet/main/views.cljs deleted file mode 100644 index 7aad3a550ee1..000000000000 --- a/src/status_im/ui/screens/wallet/main/views.cljs +++ /dev/null @@ -1,201 +0,0 @@ -(ns status-im.ui.screens.wallet.main.views - (:require-macros [status-im.utils.views :as views]) - (:require [reagent.core :as reagent] - [re-frame.core :as re-frame] - [status-im.i18n :as i18n] - [status-im.ui.components.colors :as colors] - [status-im.ui.components.list.views :as list] - [status-im.ui.components.react :as react] - [status-im.ui.components.toolbar.view :as toolbar] - [status-im.ui.components.icons.vector-icons :as vector-icons] - [status-im.ui.screens.wallet.onboarding.views :as onboarding.views] - [status-im.ui.screens.wallet.styles :as wallet.styles] - [status-im.ui.screens.wallet.main.styles :as styles] - [status-im.ui.screens.wallet.settings.views :as settings] - [status-im.ui.screens.wallet.utils :as wallet.utils] - [status-im.utils.money :as money] - [status-im.utils.platform :as platform] - [status-im.ui.components.toolbar.actions :as action] - status-im.ui.screens.wallet.collectibles.etheremon.views - status-im.ui.screens.wallet.collectibles.cryptostrikers.views - status-im.ui.screens.wallet.collectibles.cryptokitties.views - status-im.ui.screens.wallet.collectibles.superrare.views - status-im.ui.screens.wallet.collectibles.kudos.views - [status-im.ui.components.status-bar.view :as status-bar.view] - [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?] - [react/view - [status-bar.view/status-bar {:type :modal-wallet}] - [toolbar/toolbar {:transparent? true} - [toolbar/nav-button (action/close-white action/default-handler)] - [toolbar/content-wrapper] - [toolbar/actions - [{:icon (if modal-history? :main-icons/wallet :main-icons/two-arrows) - :icon-opts {:color :white - :accessibility-label (if modal-history? :wallet-modal-button :transaction-history-button)} - :handler #(re-frame/dispatch [:set-in [:wallet :modal-history?] (not modal-history?)])}]]]]) - -(defn- total-section [value currency] - [react/nested-text {:style styles/total-balance-text} - (when (and - (not= "0" value) - (not= "..." value)) - "~") - [{:style styles/total-balance-value - :accessibility-label :total-amount-value-text} - value] - [{:style styles/total-balance-currency - :accessibility-label :total-amount-currency-text} - (str " " (:code currency))]]) - -(defn- backup-seed-phrase [] - [react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :backup-seed]) - :style {:background-color colors/blue} - :underlay-color colors/blue} - [react/view {:style styles/backup-seed-phrase-container} - [react/view - [react/i18n-text {:style styles/backup-seed-phrase-title - :key :wallet-backup-recovery-title}] - [react/i18n-text {:style styles/backup-seed-phrase-description - :key :wallet-backup-recovery-description}]] - [react/view {:style {:flex 1}}] - [react/view {:style {:align-items :center - :justify-content :center}} - [vector-icons/icon :main-icons/next {:color colors/white}]]]]) - -(def actions - [{:label (i18n/label :t/wallet-send) - :accessibility-label :send-transaction-button - :icon :main-icons/send - :action #(re-frame/dispatch [:navigate-to :wallet-send-transaction])} - {:label (i18n/label :t/receive) - :accessibility-label :receive-transaction-button - :icon :main-icons/receive - :action #(re-frame/dispatch [:navigate-to :wallet-request-transaction])} - {:label (i18n/label :t/transaction-history) - :accessibility-label :transaction-history-button - :icon :main-icons/history - :action #(re-frame/dispatch [:navigate-to :transactions-history])}]) - -(defn- render-asset [currency] - (fn [{:keys [symbol icon decimals amount color] :as token}] - (let [asset-value (re-frame/subscribe [:asset-value symbol decimals (-> currency :code keyword)])] - [react/view {:style styles/asset-item-container} - [list/item - (if icon - [list/item-image icon] - [chat-icon/custom-icon-view-list (:name token) color]) - [react/view {:style styles/asset-item-value-container} - [react/text {:style styles/asset-item-value - :number-of-lines 1 - :ellipsize-mode :tail - :accessibility-label (str (-> symbol name clojure.string/lower-case) "-asset-value-text")} - (wallet.utils/format-amount amount decimals)] - [react/text {:style styles/asset-item-currency - :number-of-lines 1} - (wallet.utils/display-symbol token)]] - [react/text {:style styles/asset-item-price - :number-of-lines 1} - (or @asset-value "...")]]]))) - -(def item-icon-forward - [list/item-icon {:icon :main-icons/next - :style {:width 12} - :icon-opts {:color :gray}}]) - -(defn- render-collectible [address-hex {:keys [symbol name icon amount] :as collectible}] - (let [items-number (money/to-fixed amount) - details? (pos? items-number)] - [react/touchable-highlight - (when details? - {:on-press #(re-frame/dispatch [:show-collectibles-list address-hex collectible])}) - [react/view {:style styles/asset-item-container} - [list/item - [list/item-image icon] - [react/view {:style styles/asset-item-value-container} - [react/text {:style styles/asset-item-value - :number-of-lines 1 - :ellipsize-mode :tail - :accessibility-label (str (-> symbol clojure.core/name clojure.string/lower-case) - "-collectible-value-text")} - (or items-number "...")] - [react/text {:style styles/asset-item-currency - :number-of-lines 1} - name]] - (when details? - item-icon-forward)]]])) - -(defn group-assets [v] - (group-by #(if (:nft? %) :nfts :tokens) v)) - -(defn- asset-section [assets currency address-hex] - (let [{:keys [tokens nfts]} (group-assets assets)] - [list/section-list - {:scroll-enabled false - :style styles/asset-section - :key-fn (comp str :symbol) - :render-section-header-fn (fn [{:keys [title data]}] - (when (not-empty data) - [react/text {:style styles/asset-section-header} - title])) - :sections [{:title (i18n/label :t/wallet-assets) - :key :assets - :data tokens - :render-fn (render-asset currency)} - {:title (i18n/label :t/wallet-collectibles) - :key :collectibles - :data nfts - :render-fn #(render-collectible address-hex %)}]}])) - -(defn snackbar [error-message] - [react/view styles/snackbar-container - [react/text {:style styles/snackbar-text} - (i18n/label error-message)]]) - -(views/defview wallet-root [modal?] - (views/letsubs [assets [:wallet/visible-assets-with-amount] - currency [:wallet/currency] - portfolio-value [:portfolio-value] - {:keys [seed-backed-up?]} [:account/account] - error-message [:wallet/error-message] - address-hex [:account/hex-address]] - [react/view styles/main-section - [status-bar.view/status-bar {:type :wallet-tab}] - [settings/toolbar-view] - [react/scroll-view {:end-fill-color - colors/white - :refresh-control - (reagent/as-element - [(react/refresh-control) {:on-refresh #(re-frame/dispatch [:wallet.ui/pull-to-refresh]) - :tint-color :white - :refreshing false}])} - (if error-message - [snackbar error-message] - [total-section portfolio-value currency]) - ;; this view is a hack to hide the 1px high white line gap on android - (when platform/android? - [react/view {:style {:background-color colors/blue - :height 1 - :margin -1}}]) - (when (and (not modal?) - (not seed-backed-up?) - (some (fn [{:keys [amount]}] - (and amount (not (.isZero amount)))) - assets)) - [backup-seed-phrase]) - [react/view {:style {:background-color colors/blue}} - [list/flat-list - {:data actions - :key-fn (fn [_ i] (str i)) - :render-fn #(list/render-action % {:action-label-style {:font-size 17}})}]] - [asset-section assets currency address-hex] - (when platform/ios? - [react/view {:style styles/scroll-bottom}])]])) - -(views/defview wallet [] - (views/letsubs [{:keys [wallet-set-up-passed?]} [:account/account]] - (if (not wallet-set-up-passed?) - [onboarding.views/onboarding] - [wallet-root]))) diff --git a/src/status_im/ui/screens/wallet/onboarding/styles.cljs b/src/status_im/ui/screens/wallet/onboarding/styles.cljs deleted file mode 100644 index 25795573be22..000000000000 --- a/src/status_im/ui/screens/wallet/onboarding/styles.cljs +++ /dev/null @@ -1,93 +0,0 @@ -(ns status-im.ui.screens.wallet.onboarding.styles - (:require [status-im.ui.components.colors :as colors])) - -(def border-top-justify - {:justify-content :space-between - :flex 1}) - -(def signing-phrase - {:background-color colors/white - :border-radius 8 - :flex-direction :row}) - -(def signing-word - {:flex 1 - :height 66 - :border-left-color "#ECECF0" - :border-left-width 1 - :align-items :center - :justify-content :center}) - -(def signing-word-text - {:typography :main-semibold}) - -(def bottom-buttons - {:background-color colors/blue - :padding-vertical 8}) - -(def got-it-button-text - {:padding-horizontal 0}) - -(def modal - {:flex 1 - :background-color colors/blue}) - -(def bottom-button-container - {:flex-direction :row, - :border-top-width 1 - :background-color colors/blue - :border-top-color colors/white-light-transparent}) - -(def explanation-container - {:margin-top 40 - :margin-left 2 - :margin-right 2 - :align-items :center}) - -(def super-safe-text - {:typography :header - :color colors/white - :margin-bottom 12}) - -(def super-safe-explainer-text - {:color colors/white - :text-align :center - :margin-bottom 30}) - -;; onboarding screen styles - -(def root - {:flex 1 - :background-color colors/blue - :align-items :center - :justify-content :center - :padding-horizontal 30}) - -(def onboarding-image-container - {:flex 1 - :align-items :center - :justify-content :center}) - -(def onboarding-image - {:width 285 - :height 312}) - -(def onboarding-title - {:typography :header - :text-align :center - :color colors/white}) - -(def onboarding-text - {:margin-top 8 - :margin-bottom 32 - :font-size 14 - :text-align :center - :color colors/white-transparent}) - -(def set-up-button - {:flex-direction :row - :background-color (colors/alpha colors/black 0.1) - :margin-bottom 32}) - -(def set-up-button-label - {:color colors/white}) diff --git a/src/status_im/ui/screens/wallet/onboarding/views.cljs b/src/status_im/ui/screens/wallet/onboarding/views.cljs deleted file mode 100644 index be7fba0b70d0..000000000000 --- a/src/status_im/ui/screens/wallet/onboarding/views.cljs +++ /dev/null @@ -1,132 +0,0 @@ -(ns status-im.ui.screens.wallet.onboarding.views - (:require - [clojure.string :as string] - [re-frame.core :as re-frame] - [status-im.i18n :as i18n] - [status-im.react-native.resources :as resources] - [status-im.ui.components.button.view :as button] - [status-im.ui.components.colors :as colors] - [status-im.ui.components.common.common :as components.common] - [status-im.ui.components.icons.vector-icons :as vector-icons] - [status-im.ui.components.react :as react] - [status-im.ui.components.status-bar.view :as status-bar] - [status-im.ui.components.styles :as components.styles] - [status-im.ui.components.toolbar.actions :as actions] - [status-im.ui.screens.wallet.components.views :as wallet.components] - [status-im.ui.screens.wallet.onboarding.styles :as styles] - [status-im.utils.utils :as utils]) - (:require-macros [status-im.utils.views :as views])) - -(defn display-confirmation [on-accept] - (utils/show-confirmation - {:title (i18n/label :t/wallet-set-up-confirm-title) - :content (i18n/label :t/wallet-set-up-confirm-description) - :cancel-button-text (i18n/label :t/see-it-again) - :confirm-button-text (i18n/label :t/got-it) - :on-accept on-accept})) - -(defn info-bubble [text] - ;; keeping styles inline here as we are going to - ;; want to move this somewhere for reuse. - [react/view {:style {:padding-top 10 - :align-items :center}} - [react/view {:style {:align-items :center - :position :absolute - :top 0 - :width 34 - :zIndex 1 - :background-color colors/blue}} - [vector-icons/icon :main-icons/info {:color colors/white}]] - [react/view - {:style {:border-color (colors/alpha colors/white 0.6) - :border-width 1 - :border-radius 8 - :padding-top 15 - :padding-bottom 15 - :padding-left 20 - :padding-right 20 - :align-items :center}} - [react/text - {:style {:color (colors/alpha colors/white 0.6) - :text-align :center}} - text]]]) - -(defn toolbar [] - ^{:key "toolbar"} - [wallet.components/toolbar - {:transparent? true} - (actions/back-white #(re-frame/dispatch [:wallet.setup.ui/navigate-back-pressed])) - (i18n/label :t/wallet-set-up-title)]) - -(defn main-panel [signing-phrase on-confirm] - (let [signing-words (string/split signing-phrase #" ")] - ^{:key "main-panel-view"} - [react/view {:style styles/border-top-justify} - [react/view] ;; crappy way to vertically center things - [react/view {:style {:padding-left 36 :padding-right 36}} - [react/view {:style styles/signing-phrase - :accessibility-label :signing-phrase} - (map - (fn [word container-style] - ^{:key (str "signing-word-" word)} - [react/view container-style - [react/text {:style styles/signing-word-text - :number-of-lines 1} - word]]) - signing-words - (cons - (dissoc styles/signing-word - :border-left-color - :border-left-width) - (repeat styles/signing-word)) - (cons true (repeat false)))] - [react/view {:style styles/explanation-container} - [react/text {:style styles/super-safe-text} - (i18n/label :t/wallet-set-up-safe-transactions-title)] - [react/text - {:style styles/super-safe-explainer-text} - (i18n/label :t/wallet-set-up-signing-explainer)] - (info-bubble - (i18n/label :t/wallet-set-up-signing-explainer-warning))]] - [react/view {:style styles/bottom-button-container} - [button/button {:on-press on-confirm - :text-style styles/got-it-button-text - :style {:padding-vertical 9} - :accessibility-label :done-button - :fit-to-text? false} - (i18n/label :t/got-it) - nil]]])) - -(views/defview screen [] - (views/letsubs [{:keys [signing-phrase]} [:account/account]] - [wallet.components/simple-screen - {:avoid-keyboard? true} - (toolbar) - (main-panel - signing-phrase - (partial display-confirmation #(re-frame/dispatch [:accounts.ui/wallet-set-up-confirmed false])))])) - -(views/defview modal [] - (views/letsubs [{:keys [signing-phrase]} [:account/account]] - [react/view styles/modal - [status-bar/status-bar {:type :modal-wallet}] - [react/view components.styles/flex - (toolbar) - (main-panel - signing-phrase - (partial display-confirmation #(re-frame/dispatch [:accounts.ui/wallet-set-up-confirmed true])))]])) - -(defn onboarding [] - [react/view styles/root - [react/view {:style styles/onboarding-image-container} - [react/image {:source (resources/get-image :wallet-welcome) - :style styles/onboarding-image}]] - [react/text {:style styles/onboarding-title} - (i18n/label :t/wallet-onboarding-title)] - [react/text {:style styles/onboarding-text} - (i18n/label :t/wallet-onboarding-description)] - [components.common/button - {:button-style styles/set-up-button - :label-style styles/set-up-button-label - :on-press #(re-frame/dispatch [:navigate-to :wallet-onboarding-setup]) - :label (i18n/label :t/wallet-onboarding-set-up)}]]) diff --git a/src/status_im/ui/screens/wallet/request/events.cljs b/src/status_im/ui/screens/wallet/request/events.cljs deleted file mode 100644 index 8bd068112763..000000000000 --- a/src/status_im/ui/screens/wallet/request/events.cljs +++ /dev/null @@ -1,34 +0,0 @@ -(ns status-im.ui.screens.wallet.request.events - (:require [status-im.chat.commands.sending :as commands-sending] - [status-im.chat.models :as chat-model] - [status-im.utils.fx :as fx] - [status-im.utils.handlers :as handlers] - [status-im.utils.money :as money] - [status-im.wallet.db :as wallet.db])) - -(handlers/register-handler-fx - :wallet-send-request - (fn [{:keys [db] :as cofx} [_ public-key amount symbol decimals]] - (assert public-key) - (let [request-command (get-in db [:id->command ["request" #{:personal-chats}]])] - (fx/merge cofx - (chat-model/start-chat public-key nil) - (commands-sending/send public-key - request-command - {:asset (name symbol) - :amount (str (money/internal->formatted amount symbol decimals))}))))) - -(handlers/register-handler-fx - :wallet.request/set-and-validate-amount - (fn [{:keys [db]} [_ amount symbol decimals]] - (let [{:keys [value error]} (wallet.db/parse-amount amount decimals)] - {:db (-> db - (assoc-in [:wallet :request-transaction :amount] (money/formatted->internal value symbol decimals)) - (assoc-in [:wallet :request-transaction :amount-text] amount) - (assoc-in [:wallet :request-transaction :amount-error] error))}))) - -(handlers/register-handler-fx - :wallet.request/set-symbol - (fn [{:keys [db]} [_ symbol]] - {:db (-> db - (assoc-in [:wallet :request-transaction :symbol] symbol))})) diff --git a/src/status_im/ui/screens/wallet/request/views.cljs b/src/status_im/ui/screens/wallet/request/views.cljs index 1f7cf0ece257..e2c7ff8a6614 100644 --- a/src/status_im/ui/screens/wallet/request/views.cljs +++ b/src/status_im/ui/screens/wallet/request/views.cljs @@ -1,6 +1,5 @@ (ns status-im.ui.screens.wallet.request.views (:require [re-frame.core :as re-frame] - [status-im.ethereum.core :as ethereum] [status-im.ethereum.eip55 :as eip55] [status-im.ethereum.eip681 :as eip681] [status-im.ethereum.tokens :as tokens] @@ -16,16 +15,13 @@ [status-im.ui.components.toolbar.view :as toolbar] [status-im.ui.screens.wallet.components.views :as wallet.components] [status-im.ui.screens.wallet.request.styles :as styles] - [status-im.ui.screens.wallet.utils :as wallet.utils] + [status-im.wallet.utils :as wallet.utils] [status-im.utils.utils :as utils]) (:require-macros [status-im.utils.views :as views])) -;; Request screen - (views/defview send-transaction-request [] ;; TODO(jeluard) both send and request flows should be merged (views/letsubs [chain [:ethereum/chain-keyword] - {:keys [to to-name public-key]} [:wallet.send/transaction] {:keys [amount amount-error amount-text symbol to to-name public-key]} [:wallet.request/transaction] network-status [:network-status] @@ -65,8 +61,6 @@ (i18n/label :t/send-request) [vector-icons/icon :main-icons/next {:color :white}]]]]]))) -;; Main screen - (defn send-transaction-request-button [value] [button/primary-button {:on-press #(re-frame/dispatch [:navigate-to :wallet-send-transaction-request]) :style styles/send-request @@ -92,4 +86,4 @@ :footer-button send-transaction-request-button :value (eip681/generate-uri address-hex {:chain-id chain-id}) :hint (i18n/label :t/request-qr-legend) - :legend (eip55/address->checksum address-hex)}]]])) + :legend (eip55/address->checksum address-hex)}]]])) \ No newline at end of file diff --git a/src/status_im/ui/screens/wallet/send/events.cljs b/src/status_im/ui/screens/wallet/send/events.cljs deleted file mode 100644 index 77af62b27ddf..000000000000 --- a/src/status_im/ui/screens/wallet/send/events.cljs +++ /dev/null @@ -1,43 +0,0 @@ -(ns status-im.ui.screens.wallet.send.events - (:require [status-im.utils.handlers :as handlers] - [status-im.utils.money :as money] - [status-im.wallet.db :as wallet.db] - [status-im.ethereum.tokens :as tokens] - [status-im.ethereum.abi-spec :as abi-spec] - [status-im.ethereum.core :as ethereum] - [status-im.signing.core :as signing])) - -(defn set-and-validate-amount-db [db amount symbol decimals] - (let [{:keys [value error]} (wallet.db/parse-amount amount decimals)] - (-> db - (assoc-in [:wallet :send-transaction :amount] (money/formatted->internal value symbol decimals)) - (assoc-in [:wallet :send-transaction :amount-text] amount) - (assoc-in [:wallet :send-transaction :amount-error] error)))) - -(handlers/register-handler-fx - :wallet.send/set-and-validate-amount - (fn [{:keys [db]} [_ amount symbol decimals]] - {:db (set-and-validate-amount-db db amount symbol decimals)})) - -(handlers/register-handler-fx - :wallet.send/set-symbol - (fn [{:keys [db]} [_ symbol]] - {:db (-> db - (assoc-in [:wallet :send-transaction :symbol] symbol) - (assoc-in [:wallet :send-transaction :amount] nil) - (assoc-in [:wallet :send-transaction :amount-text] nil) - (assoc-in [:wallet :send-transaction :asset-error] nil))})) - -(handlers/register-handler-fx - :wallet.ui/sign-transaction-button-clicked - (fn [{:keys [db] :as cofx} _] - (let [{:keys [to symbol amount]} (get-in cofx [:db :wallet :send-transaction]) - {:keys [symbol address]} (tokens/asset-for (:wallet/all-tokens db) (keyword (:chain db)) symbol) - amount-hex (str "0x" (abi-spec/number-to-hex amount)) - to-norm (ethereum/normalized-address to)] - (signing/sign cofx {:tx-obj (if (= symbol :ETH) - {:to to-norm - :value amount-hex} - {:to (ethereum/normalized-address address) - :data (abi-spec/encode "transfer(address,uint256)" [to-norm amount-hex])}) - :on-result [:navigate-back]})))) \ No newline at end of file diff --git a/src/status_im/ui/screens/wallet/send/styles.cljs b/src/status_im/ui/screens/wallet/send/styles.cljs index 3e9a25e2aa12..34e1690f9300 100644 --- a/src/status_im/ui/screens/wallet/send/styles.cljs +++ b/src/status_im/ui/screens/wallet/send/styles.cljs @@ -1,7 +1,6 @@ (ns status-im.ui.screens.wallet.send.styles (:require-macros [status-im.utils.styles :refer [defstyle]]) (:require [status-im.ui.components.colors :as colors] - [status-im.ui.components.styles :as styles] [status-im.ui.screens.wallet.components.styles :as wallet.components.styles])) (def send-transaction-form @@ -21,14 +20,6 @@ :padding-top 12 :padding-horizontal 12}) -(def spinner-container - {:position :absolute - :left 0 - :top 0 - :right 0 - :bottom 0 - :justify-content :center}) - (def signing-phrase-container {:border-radius 8 :height 36 @@ -69,48 +60,14 @@ :padding 8 :align-items :center}) -(def advanced-button-wrapper - {:align-items :center}) - -(def advanced-wrapper - {:margin-top 24 - :margin-bottom 16}) - -(def gas-container-wrapper - {:flex 1 - :flex-direction :row}) - -(def gas-input-wrapper - {:align-items :center - :justify-content :space-between - :flex-direction :row}) - -(def advanced-options-text-wrapper - {:flex 1 - :flex-direction :row - :justify-content :space-between - :margin-vertical 15}) - (def advanced-label {:text-align-vertical :center :margin-left 4}) -(def advanced-fees-text - {:color colors/white}) - -(def advanced-fees-details-text - {:color colors/white-transparent}) - -(def transaction-fee-block-wrapper - {:flex-direction :row}) - (def transaction-fee-info {:flex-direction :row :margin 15}) -(def transaction-fee-info-text-wrapper - {:flex-shrink 1}) - (def transaction-fee-info-icon {:border-radius 25 :width 25 @@ -136,12 +93,9 @@ {:background-color colors/blue :padding-vertical 8}) -(def fee-buttons - {:background-color colors/blue}) - (def password-error-tooltip {:bottom-value 15 :color colors/red-light}) (defstyle gas-input-error-tooltip - {:android {:bottom-value -38}}) + {:android {:bottom-value -38}}) \ No newline at end of file diff --git a/src/status_im/ui/screens/wallet/send/views.cljs b/src/status_im/ui/screens/wallet/send/views.cljs index 8c9f6ead0b1d..a83a4d08761a 100644 --- a/src/status_im/ui/screens/wallet/send/views.cljs +++ b/src/status_im/ui/screens/wallet/send/views.cljs @@ -13,7 +13,6 @@ [status-im.ui.components.styles :as components.styles] [status-im.ui.components.toolbar.view :as toolbar] [status-im.ui.screens.wallet.components.views :as wallet.components] - [status-im.ui.screens.wallet.main.views :as wallet.main.views] [status-im.ui.screens.wallet.send.styles :as styles] [status-im.ui.components.toolbar.actions :as actions])) @@ -51,8 +50,6 @@ :ref #(reset! scroll %) :on-content-size-change #(when (and scroll @scroll) (.scrollToEnd @scroll))} - (when-not online? - [wallet.main.views/snackbar :t/error-cant-send-transaction-offline]) [react/view styles/send-transaction-form [wallet.components/recipient-selector {:address to diff --git a/src/status_im/ui/screens/wallet/settings/views.cljs b/src/status_im/ui/screens/wallet/settings/views.cljs index ab0b893a0fd8..bf207fcc0cbc 100644 --- a/src/status_im/ui/screens/wallet/settings/views.cljs +++ b/src/status_im/ui/screens/wallet/settings/views.cljs @@ -42,9 +42,9 @@ :cyrcle-color (colors/alpha colors/red 0.1) :on-press #(hide-sheet-and-dispatch [:wallet.custom-token.ui/remove-pressed token])}])])) -(defn- render-token [{:keys [symbol name icon color custom?] :as token} visible-tokens] +(defn- render-token [{:keys [symbol name icon color custom? checked?] :as token}] [list/list-item-with-checkbox - {:checked? (contains? visible-tokens (keyword symbol)) + {:checked? checked? :on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet {:content (custom-token-actions-view token) :content-height (if custom? 128 68)}]) :on-value-change #(re-frame/dispatch [:wallet.settings/toggle-visible-token (keyword symbol) %])} @@ -57,31 +57,28 @@ [list/item-secondary symbol]]]]) (defview manage-assets [] - (letsubs [chain [:ethereum/chain-keyword] - visible-tokens [:wallet/visible-tokens-symbols] - all-tokens [:wallet/all-tokens]] - (let [{custom-tokens true default-tokens nil} (group-by :custom? (tokens/sorted-tokens-for all-tokens chain))] - [react/view (merge components.styles/flex {:background-color :white}) - [status-bar/status-bar] - [toolbar] - [react/view {:style components.styles/flex} - [list/section-list - {:header [react/view {:margin-top 16} - [action-button/action-button {:label (i18n/label :t/add-custom-token) - :icon :main-icons/add - :icon-opts {:color :blue} - :on-press #(re-frame/dispatch [:navigate-to :wallet-add-custom-token])}]] - :sections (concat - (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)}]]]))) + (letsubs [{custom-tokens true default-tokens nil} [:wallet/grouped-chain-tokens]] + [react/view (merge components.styles/flex {:background-color :white}) + [status-bar/status-bar] + [toolbar] + [react/view {:style components.styles/flex} + [list/section-list + {:header [react/view {:margin-top 16} + [action-button/action-button {:label (i18n/label :t/add-custom-token) + :icon :main-icons/add + :icon-opts {:color :blue} + :on-press #(re-frame/dispatch [:navigate-to :wallet-add-custom-token])}]] + :sections (concat + (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}]]])) (defn- create-payload [address] {:address (ethereum/normalized-address address)}) diff --git a/src/status_im/ui/screens/wallet/styles.cljs b/src/status_im/ui/screens/wallet/styles.cljs deleted file mode 100644 index bb9dff8a5814..000000000000 --- a/src/status_im/ui/screens/wallet/styles.cljs +++ /dev/null @@ -1,15 +0,0 @@ -(ns status-im.ui.screens.wallet.styles - (:require-macros [status-im.utils.styles :refer [defstyle]]) - (:require [status-im.ui.components.colors :as colors])) - -;; wallet - -(defn button-container [enabled?] - (merge {:flex-direction :row - :align-items :center} - (when-not enabled? - {:opacity 0.4}))) - -(def wallet-modal-container - {:flex 1 - :background-color colors/blue}) diff --git a/src/status_im/ui/screens/wallet/transaction_fee/views.cljs b/src/status_im/ui/screens/wallet/transaction_fee/views.cljs deleted file mode 100644 index 100c5df75c09..000000000000 --- a/src/status_im/ui/screens/wallet/transaction_fee/views.cljs +++ /dev/null @@ -1,102 +0,0 @@ -(ns status-im.ui.screens.wallet.transaction-fee.views - (:require [re-frame.core :as re-frame] - [status-im.ethereum.core :as ethereum] - [status-im.ethereum.tokens :as tokens] - [status-im.i18n :as i18n] - [status-im.ui.components.bottom-buttons.view :as bottom-buttons] - [status-im.ui.components.button.view :as button] - [status-im.ui.components.colors :as colors] - [status-im.ui.components.react :as react] - [status-im.ui.components.styles :as components.styles] - [status-im.ui.components.toolbar.actions :as act] - [status-im.ui.components.toolbar.view :as toolbar] - [status-im.ui.components.tooltip.views :as tooltip] - [status-im.ui.screens.wallet.components.views :as components] - [status-im.ui.screens.wallet.send.styles :as styles] - [status-im.ui.screens.wallet.utils :as wallet.utils] - [status-im.utils.money :as money]) - (:require-macros [status-im.utils.views :refer [defview letsubs]])) - -(defn- toolbar [title] - [toolbar/toolbar - {:style {:border-bottom-color colors/white-light-transparent}} - [toolbar/nav-button (act/close-white act/default-handler)] - [toolbar/content-title {:color :white} title]]) - -(defview transaction-fee [] - (letsubs [send-transaction [:wallet.send/transaction] - chain [:ethereum/chain-keyword] - {gas-edit :gas - max-fee :max-fee - gas-price-edit :gas-price} [:wallet/edit] - all-tokens [:wallet/all-tokens]] - (let [{:keys [amount symbol]} send-transaction - gas (:value gas-edit) - gas-price (:value gas-price-edit) - native-currency (tokens/native-currency chain) - {:keys [decimals] :as token} (tokens/asset-for all-tokens chain symbol)] - [components/simple-screen {:status-bar-type :modal-wallet} - [toolbar (i18n/label :t/wallet-transaction-fee)] - [react/view components.styles/flex - [react/view {:flex-direction :row} - - [react/view styles/gas-container-wrapper - [components/cartouche {} - (i18n/label :t/gas-limit) - [react/view styles/gas-input-wrapper - [react/text-input (merge styles/transaction-fee-input - {:on-change-text #(re-frame/dispatch [:wallet.send/edit-value :gas %]) - :default-value gas - :accessibility-label :gas-limit-input})]]] - (when (:invalid? gas-edit) - [tooltip/tooltip (i18n/label :t/invalid-number) styles/gas-input-error-tooltip])] - - [react/view styles/gas-container-wrapper - [components/cartouche {} - (i18n/label :t/gas-price) - [react/view styles/gas-input-wrapper - [react/text-input (merge styles/transaction-fee-input - {:on-change-text #(re-frame/dispatch [:wallet.send/edit-value :gas-price %]) - :default-value gas-price - :accessibility-label :gas-price-input})] - [components/cartouche-secondary-text - (i18n/label :t/gwei)]]] - (when (:invalid? gas-price-edit) - [tooltip/tooltip - (i18n/label (if (= :invalid-number (:invalid? gas-price-edit)) - :t/invalid-number - :t/wallet-send-min-wei)) - styles/gas-input-error-tooltip])]] - - [react/view styles/transaction-fee-info - [react/view styles/transaction-fee-info-icon - [react/text {:style styles/transaction-fee-info-icon-text} "?"]] - [react/view styles/transaction-fee-info-text-wrapper - [react/i18n-text {:style styles/advanced-fees-text - :key :wallet-transaction-fee-details}]]] - [components/separator] - [react/view styles/transaction-fee-block-wrapper - [components/cartouche {:disabled? true} - (i18n/label :t/amount) - [react/view {:accessibility-label :amount-input} - [components/cartouche-text-content - (str (money/to-fixed (money/internal->formatted amount symbol decimals))) - (wallet.utils/display-symbol token)]]] - [components/cartouche {:disabled? true} - (i18n/label :t/wallet-transaction-total-fee) - [react/view {:accessibility-label :total-fee-input} - [components/cartouche-text-content - (str max-fee " " (wallet.utils/display-symbol native-currency))]]]] - - [bottom-buttons/bottom-buttons styles/fee-buttons - [button/button {:on-press #(re-frame/dispatch [:wallet.send/reset-gas-default]) - :accessibility-label :reset-to-default-button} - (i18n/label :t/reset-default)] - [button/button {:on-press #(do (re-frame/dispatch [:wallet.send/set-gas-details - (:value-number gas-edit) - (:value-number gas-price-edit)]) - (act/default-handler)) - :accessibility-label :done-button - :disabled? (or (:invalid? gas-edit) - (:invalid? gas-price-edit))} - (i18n/label :t/done)]]]]))) diff --git a/src/status_im/ui/screens/wallet/transaction_sent/styles.cljs b/src/status_im/ui/screens/wallet/transaction_sent/styles.cljs deleted file mode 100644 index 5d985aa89a3d..000000000000 --- a/src/status_im/ui/screens/wallet/transaction_sent/styles.cljs +++ /dev/null @@ -1,15 +0,0 @@ -(ns status-im.ui.screens.wallet.transaction-sent.styles - (:require [status-im.ui.components.colors :as colors] - [status-im.utils.platform :as platform])) - -(def transaction-sent - {:typography :header - :color colors/white - :margin-bottom 8}) - -(def transaction-sent-description - {:typography :title - :color (colors/alpha colors/white 0.6) - :text-align :center - :padding-horizontal 30 - :margin-bottom 35}) diff --git a/src/status_im/ui/screens/wallet/transaction_sent/views.cljs b/src/status_im/ui/screens/wallet/transaction_sent/views.cljs deleted file mode 100644 index 28c1d9081833..000000000000 --- a/src/status_im/ui/screens/wallet/transaction_sent/views.cljs +++ /dev/null @@ -1,69 +0,0 @@ -(ns status-im.ui.screens.wallet.transaction-sent.views - (:require-macros [status-im.utils.views :refer [defview letsubs]]) - (:require [status-im.ui.components.react :as react] - [status-im.ui.components.status-bar.view :as status-bar] - [status-im.ui.components.icons.vector-icons :as vi] - [status-im.react-native.resources :as resources] - [status-im.ui.screens.wallet.transaction-sent.styles :as styles] - [re-frame.core :as re-frame] - [status-im.i18n :as i18n] - [status-im.utils.platform :as platform] - [status-im.ui.components.colors :as colors])) - -(defn- ok-circle [] - [react/view {:background-color colors/black-transparent - :width 160 - :height 160 - :border-radius 81 - :align-items :center - :justify-content :center} - [react/view {:background-color colors/white - :width 80 - :height 80 - :border-radius 41 - :shadow-radius 4 - :shadow-offset {:width 0 :height 2} - :shadow-opacity 0.8 - :shadow-color "rgba(43, 59, 71, 0.12)" - :align-items :center - :justify-content :center} - [vi/icon :tiny-icons/tiny-check {:color colors/blue}]]]) - -(defn- transaction-sent-message [] - [react/view {:align-items :center} - [react/text {:style styles/transaction-sent - :accessibility-label :transaction-sent-text} - (i18n/label :t/transaction-sent)] - [react/i18n-text {:style styles/transaction-sent-description - :key :transaction-description}]]) - -(defn- bottom-action-button [on-next] - [react/touchable-highlight {:on-press on-next - :style {:border-top-width 1 - :border-color colors/white-light-transparent} - :accessibility-label :got-it-button} - [react/view {:align-items :center - :padding-vertical 18} - [react/text {:style {:color colors/white}} - (i18n/label :t/done)]]]) - -(defn- sent-screen [{:keys [on-next]}] - {:pre [(fn? on-next)]} - [react/view {:flex 1} - [react/view {:flex 0.7}] ;; spacer - [react/view {:align-items :center} (ok-circle)] - [react/view {:flex 1}] ;; spacer - (transaction-sent-message) - (bottom-action-button on-next)]) - -(defview transaction-sent [] - (letsubs [chat-id [:chats/current-chat-id]] - [react/view {:flex 1 :background-color colors/blue} - [status-bar/status-bar {:type :transparent}] - (sent-screen {:on-next #(re-frame/dispatch [:close-transaction-sent-screen chat-id])})])) - -(defview transaction-sent-modal [] - (letsubs [chat-id [:chats/current-chat-id]] - [react/view {:flex 1 :background-color colors/blue} - [status-bar/status-bar {:type :modal-wallet}] - (sent-screen {:on-next #(re-frame/dispatch [:close-transaction-sent-screen chat-id])})])) diff --git a/src/status_im/wallet/accounts/core.cljs b/src/status_im/wallet/accounts/core.cljs new file mode 100644 index 000000000000..ae8c559171ce --- /dev/null +++ b/src/status_im/wallet/accounts/core.cljs @@ -0,0 +1,16 @@ +(ns status-im.wallet.accounts.core + (:require [re-frame.core :as re-frame] + [status-im.ethereum.core :as ethereum] + [status-im.utils.fx :as fx] + [status-im.ethereum.eip55 :as eip55] + [status-im.ui.components.list-selection :as list-selection])) + +(re-frame/reg-fx + :list.selection/open-share + (fn [obj] + (list-selection/open-share obj))) + +(fx/defn set-symbol-request + {:events [:wallet.accounts/share]} + [{:keys [db]}] + {:list.selection/open-share {:message (eip55/address->checksum (ethereum/current-address db))}}) \ No newline at end of file diff --git a/src/status_im/wallet/choose_recipient/core.cljs b/src/status_im/wallet/choose_recipient/core.cljs new file mode 100644 index 000000000000..69de7317460f --- /dev/null +++ b/src/status_im/wallet/choose_recipient/core.cljs @@ -0,0 +1,122 @@ +(ns status-im.wallet.choose-recipient.core + (:require [re-frame.core :as re-frame] + [status-im.constants :as constants] + [status-im.contact.db :as contact.db] + [status-im.ethereum.core :as ethereum] + [status-im.ethereum.eip55 :as eip55] + [status-im.ethereum.eip681 :as eip681] + [status-im.ethereum.ens :as ens] + [status-im.i18n :as i18n] + [status-im.utils.money :as money] + [status-im.utils.fx :as fx])) + +(fx/defn toggle-flashlight + {:events [:wallet/toggle-flashlight]} + [{:keys [db]}] + (let [flashlight-state (get-in db [:wallet :send-transaction :camera-flashlight]) + toggled-state (if (= :on flashlight-state) :off :on)] + {:db (assoc-in db [:wallet :send-transaction :camera-flashlight] toggled-state)})) + +(defn- find-address-name [db address] + (:name (contact.db/find-contact-by-address (:contacts/contacts db) address))) + +(defn- fill-request-details [db {:keys [address name value symbol gas gasPrice public-key from-chat?]} request?] + {:pre [(not (nil? address))]} + (let [name (or name (find-address-name db address)) + data-path (if request? + [:wallet :request-transaction] + [:wallet :send-transaction])] + (update-in db data-path + (fn [{old-symbol :symbol :as old-transaction}] + (let [symbol-changed? (not= old-symbol symbol)] + (cond-> (assoc old-transaction :to address :to-name name :public-key public-key) + value (assoc :amount value) + symbol (assoc :symbol symbol) + (and gas symbol-changed?) (assoc :gas (money/bignumber gas)) + from-chat? (assoc :from-chat? from-chat?) + (and gasPrice symbol-changed?) + (assoc :gas-price (money/bignumber gasPrice)) + (and symbol (not gasPrice) symbol-changed?) + (assoc :gas-price (ethereum/estimate-gas symbol)))))))) + +(defn- extract-details + "First try to parse as EIP681 URI, if not assume this is an address directly. + Returns a map containing at least the `address` and `chain-id` keys" + [s chain-id all-tokens] + (or (let [m (eip681/parse-uri s)] + (merge m (eip681/extract-request-details m all-tokens))) + (when (ethereum/address? s) + {:address s :chain-id chain-id}))) + +;; NOTE(janherich) - whenever changing assets, we want to clear the previusly set amount/amount-text +(defn changed-asset [{:keys [db] :as fx} old-symbol new-symbol] + (-> fx + (merge {:wallet/update-gas-price + {:success-event :wallet/update-gas-price-success + :edit? false}}) + (assoc-in [:db :wallet :send-transaction :amount] nil) + (assoc-in [:db :wallet :send-transaction :amount-text] nil) + (assoc-in [:db :wallet :send-transaction :asset-error] + (i18n/label :t/changed-asset-warning {:old old-symbol :new new-symbol})))) + +(defn changed-amount-warning [fx old-amount new-amount] + (assoc-in fx [:db :wallet :send-transaction :amount-error] + (i18n/label :t/changed-amount-warning {:old old-amount :new new-amount}))) + +(defn use-default-eth-gas [fx] + (assoc-in fx [:db :wallet :send-transaction :gas] + (ethereum/default-transaction-gas))) + +(re-frame/reg-fx + :resolve-address + (fn [{:keys [registry ens-name cb]}] + (ens/get-addr registry ens-name cb))) + +(fx/defn set-recipient + {:events [:wallet.send/set-recipient]} + [{:keys [db]} recipient] + (let [chain (ethereum/chain-keyword db)] + (if (ens/is-valid-eth-name? recipient) + {:resolve-address {:registry (get ens/ens-registries chain) + :ens-name recipient + :cb #(re-frame/dispatch [:wallet.send/set-recipient %])}} + (if (ethereum/address? recipient) + (let [checksum (eip55/address->checksum recipient)] + (if (eip55/valid-address-checksum? checksum) + {:db (assoc-in db [:wallet :send-transaction :to] checksum) + :dispatch [:navigate-back]} + {:ui/show-error (i18n/label :t/wallet-invalid-address-checksum {:data recipient})})) + {:ui/show-error (i18n/label :t/wallet-invalid-address {:data recipient})})))) + +(fx/defn fill-request-from-url + {:events [:wallet/fill-request-from-url]} + [{{:keys [network] :wallet/keys [all-tokens] :as db} :db} data origin] + (let [current-chain-id (get-in constants/default-networks [network :config :NetworkId]) + {:keys [address chain-id] :as details} (extract-details data current-chain-id all-tokens) + valid-network? (boolean (= current-chain-id chain-id)) + previous-state (get-in db [:wallet :send-transaction]) + old-symbol (:symbol previous-state) + new-symbol (:symbol details) + old-amount (:amount previous-state) + new-amount (:value details) + new-gas (:gas details) + symbol-changed? (and old-symbol new-symbol (not= old-symbol new-symbol))] + (cond-> {:db db} + (not= :deep-link origin) (assoc :dispatch [:navigate-back]) ;; Only navigate-back when called from within wallet + (and address valid-network?) (update :db #(fill-request-details % details false)) + symbol-changed? (changed-asset old-symbol new-symbol) + (and old-amount new-amount (not= old-amount new-amount)) (changed-amount-warning old-amount new-amount) + ;; NOTE(goranjovic) - the next line is there is because QR code scanning switches the amount to ETH + ;; automatically, so we need to update the gas limit accordingly. The check for origin screen is there + ;; so that we wouldn't also switch gas limit to ETH specific if the user pastes address as text. + ;; We need to check if address is defined so that we wouldn't trigger this behavior when invalid QR is scanned + ;; (e.g. public-key) + (and address (= origin :qr) (not new-gas) symbol-changed?) (use-default-eth-gas) + (not address) (assoc :ui/show-error (i18n/label :t/wallet-invalid-address {:data data})) + (and address (not valid-network?)) (assoc :ui/show-error (i18n/label :t/wallet-invalid-chain-id {:data data :chain current-chain-id}))))) + +(fx/defn fill-request-from-contact + {:events [:wallet/fill-request-from-contact]} + [{db :db} {:keys [address name public-key]} request?] + {:db (fill-request-details db {:address address :name name :public-key public-key} request?) + :dispatch [:navigate-back]}) \ No newline at end of file diff --git a/src/status_im/wallet/collectibles/core.cljs b/src/status_im/wallet/collectibles/core.cljs new file mode 100644 index 000000000000..41b53a242b15 --- /dev/null +++ b/src/status_im/wallet/collectibles/core.cljs @@ -0,0 +1,203 @@ +(ns status-im.wallet.collectibles.core + (:require [re-frame.core :as re-frame] + [status-im.browser.core :as browser] + [status-im.constants :as constants] + [status-im.ethereum.core :as ethereum] + [status-im.ethereum.erc721 :as erc721] + [status-im.ethereum.tokens :as tokens] + [status-im.utils.handlers :as handlers] + [status-im.utils.money :as money] + [status-im.utils.http :as http] + [clojure.string :as string] + [status-im.utils.types :as types])) + +;;TODO: REPLACE ALL HANDLERS BY FX/DEFN + +(defmulti load-collectible-fx (fn [_ symbol _] symbol)) + +(defmethod load-collectible-fx :default [_ _ _] nil) + +(defmulti load-collectibles-fx (fn [_ symbol _ _] symbol)) + +(defmethod load-collectibles-fx :default [all-tokens symbol items-number address chain-id] + {:load-collectibles-fx [all-tokens symbol items-number address chain-id]}) + +(defn load-token [i items-number contract address symbol] + (when (< i items-number) + (erc721/token-of-owner-by-index contract address i + (fn [response] + (load-token (inc i) items-number contract address symbol) + (re-frame/dispatch [:load-collectible symbol response]))))) + +(re-frame/reg-fx + :load-collectibles-fx + (fn [[all-tokens symbol items-number address chain-id]] + (let [chain (ethereum/chain-id->chain-keyword chain-id) + contract (:address (tokens/symbol->token all-tokens chain symbol))] + (load-token 0 items-number contract address symbol)))) + +(handlers/register-handler-fx + :show-collectibles-list + (fn [{:keys [db]} [_ {:keys [symbol amount] :as collectible}]] + (let [chain-id (get-in constants/default-networks [(:network db) :config :NetworkId]) + all-tokens (:wallet/all-tokens db) + items-number (money/to-number amount) + loaded-items-number (count (get-in db [:collectibles symbol]))] + (merge (when (not= items-number loaded-items-number) + (load-collectibles-fx all-tokens symbol items-number (ethereum/current-address db) chain-id)) + {:dispatch [:navigate-to :collectibles-list collectible]})))) + +;; Crypto Kitties +(def ck :CK) + +(handlers/register-handler-fx + :load-kitties + (fn [{db :db} [_ ids]] + {:db db + :http-get-n (mapv (fn [id] + {:url (str "https://api.cryptokitties.co/kitties/" id) + :success-event-creator (fn [o] + [:load-collectible-success ck {id (http/parse-payload o)}]) + :failure-event-creator (fn [o] + [:load-collectible-failure ck {id (http/parse-payload o)}])}) + ids)})) + +;; TODO(andrey) Each HTTP call will return up to 100 kitties. Maybe we need to implement some kind of paging later +(defmethod load-collectibles-fx ck [_ _ items-number address _] + {:http-get {:url (str "https://api.cryptokitties.co/kitties?offset=0&limit=" + items-number + "&owner_wallet_address=" + address + "&parents=false") + :success-event-creator (fn [o] + [:load-kitties (map :id (:kitties (http/parse-payload o)))]) + :failure-event-creator (fn [o] + [:load-collectibles-failure (http/parse-payload o)]) + :timeout-ms 10000}}) + +;; Crypto Strikers +(def strikers :STRK) + +(defmethod load-collectible-fx strikers [_ _ id] + {:http-get {:url (str "https://us-central1-cryptostrikers-prod.cloudfunctions.net/cards/" id) + :success-event-creator (fn [o] + [:load-collectible-success strikers {id (http/parse-payload o)}]) + :failure-event-creator (fn [o] + [:load-collectible-failure strikers {id (http/parse-payload o)}])}}) + +;;Etheremona +(def emona :EMONA) + +(defmethod load-collectible-fx emona [_ _ id] + {:http-get {:url (str "https://www.etheremon.com/api/monster/get_data?monster_ids=" id) + :success-event-creator (fn [o] + [:load-collectible-success emona (:data (http/parse-payload o))]) + :failure-event-creator (fn [o] + [:load-collectible-failure emona {id (http/parse-payload o)}])}}) + +;;Kudos +(def kudos :KDO) + +(defmethod load-collectible-fx kudos [{db :db} symbol id] + (let [chain-id (get-in constants/default-networks [(:network db) :config :NetworkId]) + all-tokens (:wallet/all-tokens db)] + {:erc721-token-uri [all-tokens symbol id chain-id]})) + +(re-frame/reg-fx + :erc721-token-uri + (fn [[all-tokens symbol tokenId chain-id]] + (let [chain (ethereum/chain-id->chain-keyword chain-id) + contract (:address (tokens/symbol->token all-tokens chain symbol))] + (erc721/token-uri contract + tokenId + #(re-frame/dispatch [:token-uri-success + tokenId + (when % + (subs % (.indexOf % "http")))]))))) ;; extra chars in rinkeby + +;;Superrare +(def superrare :SUPR) + +(defmethod load-collectible-fx superrare [_ _ ids] + {:http-get-n (mapv (fn [id] + {:url id + :success-event-creator (fn [o] + [:load-collectible-success superrare {id (http/parse-payload o)}]) + :failure-event-creator (fn [o] + [:load-collectible-failure superrare {id (http/parse-payload o)}])}) + ids)}) + +(def graphql-url "https://api.pixura.io/graphql") + +(defn graphql-query [address] + (str "{ + collectiblesByOwner: allErc721Tokens(condition: {owner: \"" address "\"}) { + collectibles: nodes { + tokenId, + metadata: erc721MetadatumByTokenId { + metadataUri, + description, + name, + imageUri + }}}}")) + +(defmethod load-collectibles-fx superrare [_ _ _ address _] + {:http-post {:url graphql-url + :data (types/clj->json {:query (graphql-query (ethereum/naked-address address))}) + :opts {:headers {"Content-Type" "application/json"}} + :success-event-creator (fn [{:keys [response-body]}] + [:store-collectibles superrare + (get-in (http/parse-payload response-body) [:data :collectiblesByOwner :collectibles])]) + :failure-event-creator (fn [{:keys [response-body]}] + [:load-collectibles-failure (http/parse-payload response-body)]) + :timeout-ms 10000}}) + +(handlers/register-handler-fx + :token-uri-success + (fn [_ [_ tokenId token-uri]] + {:http-get {:url + token-uri + :success-event-creator + (fn [o] + [:load-collectible-success kudos {tokenId (update (http/parse-payload o) + :image + string/replace + #"http:" + "https:")}]) ;; http in mainnet + :failure-event-creator + (fn [o] + [:load-collectible-failure kudos {tokenId (http/parse-payload o)}])}})) + +;; + + +(handlers/register-handler-fx + :load-collectible + (fn [cofx [_ symbol token-id]] + (load-collectible-fx cofx symbol token-id))) + +(handlers/register-handler-fx + :store-collectibles + (fn [{db :db} [_ symbol collectibles]] + {:db (update-in db [:collectibles symbol] merge + (reduce #(assoc %1 (:tokenId %2) %2) {} collectibles))})) + +(handlers/register-handler-fx + :load-collectible-success + (fn [{db :db} [_ symbol collectibles]] + {:db (update-in db [:collectibles symbol] merge collectibles)})) + +(handlers/register-handler-fx + :load-collectibles-failure + (fn [{db :db} [_ reason]] + {:db (update-in db [:collectibles symbol :errors] merge reason)})) + +(handlers/register-handler-fx + :load-collectible-failure + (fn [{db :db} [_]] + {:db db})) + +(handlers/register-handler-fx + :open-collectible-in-browser + (fn [cofx [_ url]] + (browser/open-url cofx url))) \ No newline at end of file diff --git a/src/status_im/wallet/core.cljs b/src/status_im/wallet/core.cljs index ee9f01c4626e..daa5550f8cea 100644 --- a/src/status_im/wallet/core.cljs +++ b/src/status_im/wallet/core.cljs @@ -3,20 +3,43 @@ [re-frame.core :as re-frame] [status-im.accounts.update.core :as accounts.update] [status-im.constants :as constants] - [status-im.ethereum.abi-spec :as abi-spec] [status-im.ethereum.core :as ethereum] [status-im.ethereum.json-rpc :as json-rpc] [status-im.ethereum.tokens :as tokens] [status-im.i18n :as i18n] [status-im.ui.screens.navigation :as navigation] - [status-im.ui.screens.wallet.utils :as wallet.utils] + [status-im.wallet.utils :as wallet.utils] [status-im.utils.config :as config] [status-im.utils.core :as utils.core] [status-im.utils.fx :as fx] [status-im.utils.money :as money] [status-im.utils.prices :as prices] [status-im.utils.utils :as utils.utils] - [taoensso.timbre :as log])) + [taoensso.timbre :as log] + [status-im.wallet.db :as wallet.db] + [status-im.ethereum.abi-spec :as abi-spec] + [status-im.signing.core :as signing])) + +(re-frame/reg-fx + :wallet/get-balance + (fn [{:keys [account-id on-success on-error]}] + (json-rpc/call + {:method "eth_getBalance" + :params [account-id "latest"] + :on-success on-success + :on-error on-error}))) + +;; TODO(oskarth): At some point we want to get list of relevant +;; assets to get prices for +(re-frame/reg-fx + :wallet/get-prices + (fn [{:keys [from to mainnet? success-event error-event chaos-mode?]}] + (prices/get-prices from + to + mainnet? + #(re-frame/dispatch [success-event %]) + #(re-frame/dispatch [error-event %]) + chaos-mode?))) (defn assoc-error-message [db error-type err] (assoc-in db [:wallet :errors error-type] (or err :unknown-error))) @@ -48,29 +71,6 @@ {:db (assoc-in db [:wallet :current-transaction] hash)} (navigation/navigate-to-cofx :wallet-transaction-details nil))) -;; FX - -(re-frame/reg-fx - :wallet/get-balance - (fn [{:keys [account-id on-success on-error]}] - (json-rpc/call - {:method "eth_getBalance" - :params [account-id "latest"] - :on-success on-success - :on-error on-error}))) - -;; TODO(oskarth): At some point we want to get list of relevant -;; assets to get prices for -(re-frame/reg-fx - :wallet/get-prices - (fn [{:keys [from to mainnet? success-event error-event chaos-mode?]}] - (prices/get-prices from - to - mainnet? - #(re-frame/dispatch [success-event %]) - #(re-frame/dispatch [error-event %]) - chaos-mode?))) - (defn- validate-token-name! [{:keys [address symbol name]}] (json-rpc/eth-call @@ -161,6 +161,7 @@ [{:keys [db] :as cofx}] (let [custom-tokens (get-in db [:account/account :settings :wallet :custom-tokens]) chain (ethereum/chain-keyword db) + ;;TODO why do we need all tokens ? chain can be changed only through relogin all-tokens (merge-with merge (utils.core/map-values #(utils.core/index-by :address %) @@ -300,4 +301,54 @@ (fx/merge cofx (toggle-visible-token symbol true) ;;TODO(goranjovic): move `update-token-balance-success` function to wallet models - (update-token-balance symbol balance))) \ No newline at end of file + (update-token-balance symbol balance))) + +(defn set-and-validate-amount-db [db amount symbol decimals] + (let [{:keys [value error]} (wallet.db/parse-amount amount decimals)] + (-> db + (assoc-in [:wallet :send-transaction :amount] (money/formatted->internal value symbol decimals)) + (assoc-in [:wallet :send-transaction :amount-text] amount) + (assoc-in [:wallet :send-transaction :amount-error] error)))) + +(fx/defn set-and-validate-amount + {:events [:wallet.send/set-and-validate-amount]} + [{:keys [db]} amount symbol decimals] + {:db (set-and-validate-amount-db db amount symbol decimals)}) + +(fx/defn set-symbol + {:events [:wallet.send/set-symbol]} + [{:keys [db]} symbol] + {:db (-> db + (assoc-in [:wallet :send-transaction :symbol] symbol) + (assoc-in [:wallet :send-transaction :amount] nil) + (assoc-in [:wallet :send-transaction :amount-text] nil) + (assoc-in [:wallet :send-transaction :asset-error] nil))}) + +(fx/defn sign-transaction-button-clicked + {:events [:wallet.ui/sign-transaction-button-clicked]} + [{:keys [db] :as cofx}] + (let [{:keys [to symbol amount]} (get-in cofx [:db :wallet :send-transaction]) + {:keys [symbol address]} (tokens/asset-for (:wallet/all-tokens db) (keyword (:chain db)) symbol) + amount-hex (str "0x" (abi-spec/number-to-hex amount)) + to-norm (ethereum/normalized-address to)] + (signing/sign cofx {:tx-obj (if (= symbol :ETH) + {:to to-norm + :value amount-hex} + {:to (ethereum/normalized-address address) + :data (abi-spec/encode "transfer(address,uint256)" [to-norm amount-hex])}) + :on-result [:navigate-back]}))) + +(fx/defn set-and-validate-amount-request + {:events [:wallet.request/set-and-validate-amount]} + [{:keys [db]} amount symbol decimals] + (let [{:keys [value error]} (wallet.db/parse-amount amount decimals)] + {:db (-> db + (assoc-in [:wallet :request-transaction :amount] (money/formatted->internal value symbol decimals)) + (assoc-in [:wallet :request-transaction :amount-text] amount) + (assoc-in [:wallet :request-transaction :amount-error] error))})) + +(fx/defn set-symbol-request + {:events [:wallet.request/set-symbol]} + [{:keys [db]} symbol] + {:db (-> db + (assoc-in [:wallet :request-transaction :symbol] symbol))}) \ No newline at end of file diff --git a/src/status_im/wallet/custom_tokens/core.cljs b/src/status_im/wallet/custom_tokens/core.cljs index 43b2c5aafbd9..c0dae7f2e56c 100644 --- a/src/status_im/wallet/custom_tokens/core.cljs +++ b/src/status_im/wallet/custom_tokens/core.cljs @@ -2,7 +2,6 @@ (:require [clojure.string :as string] [re-frame.core :as re-frame] [status-im.ethereum.core :as ethereum] - [status-im.ethereum.decode :as decode] [status-im.ethereum.json-rpc :as json-rpc] [status-im.i18n :as i18n] [status-im.ui.components.colors :as colors] diff --git a/src/status_im/ui/screens/wallet/utils.cljs b/src/status_im/wallet/utils.cljs similarity index 95% rename from src/status_im/ui/screens/wallet/utils.cljs rename to src/status_im/wallet/utils.cljs index ad3d51dc41bf..a197ee922f92 100644 --- a/src/status_im/ui/screens/wallet/utils.cljs +++ b/src/status_im/wallet/utils.cljs @@ -1,4 +1,4 @@ -(ns status-im.ui.screens.wallet.utils +(ns status-im.wallet.utils (:require [status-im.utils.money :as money])) (defn format-amount [amount decimals] diff --git a/translations/en.json b/translations/en.json index 7fd03bdec656..736cf75ee155 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1073,5 +1073,15 @@ "signing-phrase" : "Signing phrase", "network-fee" : "Network fee", "sign-with-password" : "Sign with password", - "signing-a-message" : "Signing a message" + "signing-a-message" : "Signing a message", + "add-account" : "Add account", + "add-an-account" : "Add an account", + "back-up-your-seed-phrase" : "Back up your seed phrase", + "add-a-watch-account" : "Add a watch-only account", + "account-settings" : "Account settings", + "export-account" : "Export account", + "set-currency" : "Set currency", + "view-signing" : "View signing phrase", + "history" : "History", + "no-collectibles" : "No collectibles available" }