diff --git a/resources/images/tokens/mainnet/SUPRR.png b/resources/images/tokens/mainnet/SUPRR.png new file mode 100644 index 0000000000..7d8faa483d Binary files /dev/null and b/resources/images/tokens/mainnet/SUPRR.png differ diff --git a/src/status_im/ethereum/tokens.cljs b/src/status_im/ethereum/tokens.cljs index a726cb829e..4e683bccd4 100644 --- a/src/status_im/ethereum/tokens.cljs +++ b/src/status_im/ethereum/tokens.cljs @@ -485,6 +485,10 @@ :nft? true :name "SupeRare" :address "0x41a322b28d0ff354040e2cbc676f0320d8c8850d"} + {:symbol :SUPRR + :nft? true + :name "SuperRare" + :address "0xb932a70a57673d89f4acffbe830e8ed7f75fb9e0"} {:symbol :KDO :nft? true :name "KudosToken" diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index 0673e31696..efbc7db4b5 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -48,7 +48,6 @@ [taoensso.timbre :as log] status-im.waku.core status-im.wallet.choose-recipient.core - status-im.wallet.collectibles.core status-im.wallet.accounts.core status-im.popover.core [status-im.keycard.core :as keycard] diff --git a/src/status_im/ui/screens/routing/wallet_stack.cljs b/src/status_im/ui/screens/routing/wallet_stack.cljs index 15381cda4f..2d7610db6d 100644 --- a/src/status_im/ui/screens/routing/wallet_stack.cljs +++ b/src/status_im/ui/screens/routing/wallet_stack.cljs @@ -1,6 +1,5 @@ (ns status-im.ui.screens.routing.wallet-stack (:require [status-im.ui.screens.currency-settings.views :as currency-settings] - [status-im.ui.screens.wallet.collectibles.views :as collectibles] [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] @@ -29,8 +28,6 @@ :component add-account/pin} {:name :account-settings :component account-settings/account-settings} - {:name :collectibles-list - :component collectibles/collectibles-list} {:name :wallet-transaction-details :component wallet-transactions/transaction-details} {:name :wallet-settings-assets diff --git a/src/status_im/ui/screens/views.cljs b/src/status_im/ui/screens/views.cljs index d3a1f74de6..f30140666c 100644 --- a/src/status_im/ui/screens/views.cljs +++ b/src/status_im/ui/screens/views.cljs @@ -15,11 +15,6 @@ [status-im.ui.screens.multiaccounts.recover.views :as recover.views] [status-im.ui.screens.wallet.send.views :as wallet] [status-im.ui.components.status-bar.view :as statusbar] - 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.colors :as colors] [status-im.keycard.test-menu :as keycard.test-menu] [quo.core :as quo] diff --git a/src/status_im/ui/screens/wallet/account/views.cljs b/src/status_im/ui/screens/wallet/account/views.cljs index f8496a583f..0c1ea522cd 100644 --- a/src/status_im/ui/screens/wallet/account/views.cljs +++ b/src/status_im/ui/screens/wallet/account/views.cljs @@ -80,26 +80,38 @@ colors/white-persist #(re-frame/dispatch [:show-popover {:view :share-account :address address}])]]])) -(defn render-collectible [address] - (fn [{:keys [name icon amount] :as collectible}] - (let [items-number (money/to-fixed amount) - details? (pos? items-number)] - [quo/list-item - {:title (wallet.utils/display-symbol collectible) - :subtitle name - :icon [list/item-image icon] - :on-press (when details? - #(re-frame/dispatch - [:show-collectibles-list collectible address])) - :chevron :true - :accessory :text - :accessory-text items-number}]))) +(defn render-collectible [{:keys [name icon amount] :as collectible}] + (let [items-number (money/to-fixed amount)] + [quo/list-item + {:title (wallet.utils/display-symbol collectible) + :subtitle name + :icon [list/item-image icon] + :accessory :text + :accessory-text items-number}])) (views/defview transactions [address] (views/letsubs [{:keys [transaction-history-sections]} [:wallet.transactions.history/screen address]] [history/history-list transaction-history-sections address])) +(defn collectibles-link [] + [react/touchable-highlight + {:on-press #(re-frame/dispatch [:browser.ui/open-url "https://opensea.io/account/"])} + [react/view + {:style {:flex 1 + :padding-horizontal 14 + :flex-direction :row + :align-items :center + :background-color colors/blue-light + :height 52}} + [icons/tiny-icon + :tiny-icons/tiny-external + {:color colors/blue + :container-style {:margin-right 5}}] + [react/text + {:style {:color colors/blue}} + (i18n/label :t/check-on-opensea)]]]) + (views/defview assets-and-collections [address] (views/letsubs [{:keys [tokens nfts]} [:wallet/visible-assets-with-values address] currency [:wallet/currency]] @@ -116,14 +128,16 @@ :key-fn :name :render-fn (accounts/render-asset (:code currency))}] (= tab :nft) - (if (seq nfts) - [list/flat-list {:data nfts - :default-separator? false - :key-fn :name - :render-fn (render-collectible address)}] - [react/view {:align-items :center :margin-top 32} - [react/text {:style {:color colors/gray}} - (i18n/label :t/no-collectibles)]]) + [react/view + [collectibles-link] + (if (seq nfts) + [list/flat-list {:data nfts + :default-separator? false + :key-fn :name + :render-fn render-collectible}] + [react/view {:align-items :center :margin-top 32} + [react/text {:style {:color colors/gray}} + (i18n/label :t/no-collectibles)]])] (= tab :history) [transactions address])]))) diff --git a/src/status_im/ui/screens/wallet/collectibles/cryptokitties/views.cljs b/src/status_im/ui/screens/wallet/collectibles/cryptokitties/views.cljs deleted file mode 100644 index 153c8b0c68..0000000000 --- a/src/status_im/ui/screens/wallet/collectibles/cryptokitties/views.cljs +++ /dev/null @@ -1,27 +0,0 @@ -(ns status-im.ui.screens.wallet.collectibles.cryptokitties.views - (:require [re-frame.core :as re-frame] - [status-im.i18n :as i18n] - [status-im.ui.components.react :as react] - [status-im.ui.screens.wallet.collectibles.styles :as styles] - [status-im.ui.screens.wallet.collectibles.views :as collectibles] - [status-im.ui.components.svgimage :as svgimage] - [quo.core :as quo])) - -(defmethod collectibles/render-collectible :CK [_ {:keys [id name bio image_url]}] - [react/view {:style styles/details} - [react/view {:style styles/details-text} - [svgimage/svgimage {:style styles/details-image - :source {:uri image_url}}] - [react/view {:flex 1} - [react/text {:style styles/details-name} - (or name (i18n/label :t/cryptokitty-name {:id id}))] - [react/text {:number-of-lines 3 - :ellipsize-mode :tail} - bio]]] - [quo/list-item - {:theme :accent - :title (i18n/label :t/view-cryptokitties) - :icon :main-icons/address - :accessibility-label :open-collectible-button - :on-press #(re-frame/dispatch [:open-collectible-in-browser - (str "https://www.cryptokitties.co/kitty/" id)])}]]) diff --git a/src/status_im/ui/screens/wallet/collectibles/cryptostrikers/views.cljs b/src/status_im/ui/screens/wallet/collectibles/cryptostrikers/views.cljs deleted file mode 100644 index b7f07806b0..0000000000 --- a/src/status_im/ui/screens/wallet/collectibles/cryptostrikers/views.cljs +++ /dev/null @@ -1,26 +0,0 @@ -(ns status-im.ui.screens.wallet.collectibles.cryptostrikers.views - (:require [re-frame.core :as re-frame] - [status-im.ui.components.react :as react] - [status-im.ui.screens.wallet.collectibles.styles :as styles] - [status-im.ui.components.svgimage :as svgimage] - [status-im.ui.screens.wallet.collectibles.views :as collectibles] - [status-im.i18n :as i18n] - [quo.core :as quo])) - -(defmethod collectibles/render-collectible :STRK [_ {:keys [external_url description name image]}] - [react/view {:style styles/details} - [react/view {:style styles/details-text} - [svgimage/svgimage {:style styles/details-image - :source {:uri image - :k 1.4}}] - [react/view {:flex 1 :justify-content :center} - [react/text {:style styles/details-name} - name] - [react/text - description]]] - [quo/list-item - {:theme :accent - :title (i18n/label :t/view-cryptostrikers) - :icon :main-icons/address - :accessibility-label :open-collectible-button - :on-press #(re-frame/dispatch [:open-collectible-in-browser external_url])}]]) diff --git a/src/status_im/ui/screens/wallet/collectibles/etheremon/views.cljs b/src/status_im/ui/screens/wallet/collectibles/etheremon/views.cljs deleted file mode 100644 index a977fc992b..0000000000 --- a/src/status_im/ui/screens/wallet/collectibles/etheremon/views.cljs +++ /dev/null @@ -1,26 +0,0 @@ -(ns status-im.ui.screens.wallet.collectibles.etheremon.views - (:require [re-frame.core :as re-frame] - [status-im.ui.components.react :as react] - [status-im.ui.screens.wallet.collectibles.styles :as styles] - [status-im.ui.components.svgimage :as svgimage] - [status-im.ui.screens.wallet.collectibles.views :as collectibles] - [status-im.i18n :as i18n] - [quo.core :as quo])) - -(defmethod collectibles/render-collectible :EMONA [_ {:keys [user_defined_name image class_id]}] - [react/view {:style styles/details} - [react/view {:style styles/details-text} - [react/view {:flex 1} - [svgimage/svgimage {:style styles/details-image - :source {:uri image - :k 2}}]] - [react/view {:flex 1 :justify-content :center} - [react/text {:style styles/details-name} - user_defined_name]]] - [quo/list-item - {:theme :accent - :title (i18n/label :t/view-etheremon) - :icon :main-icons/address - :accessibility-label :open-collectible-button - :on-press #(re-frame/dispatch [:open-collectible-in-browser - (str "https://www.etheremon.com/#/mons/" class_id)])}]]) diff --git a/src/status_im/ui/screens/wallet/collectibles/kudos/views.cljs b/src/status_im/ui/screens/wallet/collectibles/kudos/views.cljs deleted file mode 100644 index ecffecf040..0000000000 --- a/src/status_im/ui/screens/wallet/collectibles/kudos/views.cljs +++ /dev/null @@ -1,26 +0,0 @@ -(ns status-im.ui.screens.wallet.collectibles.kudos.views - (:require [status-im.ui.screens.wallet.collectibles.views :as collectibles] - [status-im.ui.components.react :as react] - [status-im.ui.screens.wallet.collectibles.styles :as styles] - [status-im.ui.components.svgimage :as svgimage] - [re-frame.core :as re-frame] - [status-im.i18n :as i18n] - [quo.core :as quo])) - -(defmethod collectibles/render-collectible :KDO [_ {:keys [external_url description name image]}] - [react/view {:style styles/details} - [react/view {:style styles/details-text} - [svgimage/svgimage {:style styles/details-image - :source {:uri image - :k 1.4}}] - [react/view {:flex 1 :justify-content :center} - [react/text {:style styles/details-name} - name] - [react/text - description]]] - [quo/list-item - {:theme :accent - :title (i18n/label :t/view-gitcoin) - :icon :main-icons/address - :accessibility-label :open-collectible-button - :on-press #(re-frame/dispatch [:open-collectible-in-browser external_url])}]]) diff --git a/src/status_im/ui/screens/wallet/collectibles/styles.cljs b/src/status_im/ui/screens/wallet/collectibles/styles.cljs deleted file mode 100644 index fdb491ed2e..0000000000 --- a/src/status_im/ui/screens/wallet/collectibles/styles.cljs +++ /dev/null @@ -1,27 +0,0 @@ -(ns status-im.ui.screens.wallet.collectibles.styles) - -(def default-collectible - {:padding-left 10 - :padding-vertical 20}) - -(def loading-indicator - {:flex 1 - :align-items :center - :justify-content :center}) - -(def details - {:padding-vertical 10}) - -(def details-text - {:flex 1 - :flex-direction :row - :align-items :center - :padding-horizontal 16}) - -(def details-name - {:text-align-vertical :center - :margin-bottom 10}) - -(def details-image - {:flex 1 - :margin 10}) diff --git a/src/status_im/ui/screens/wallet/collectibles/superrare/views.cljs b/src/status_im/ui/screens/wallet/collectibles/superrare/views.cljs deleted file mode 100644 index 8505a0230c..0000000000 --- a/src/status_im/ui/screens/wallet/collectibles/superrare/views.cljs +++ /dev/null @@ -1,26 +0,0 @@ -(ns status-im.ui.screens.wallet.collectibles.superrare.views - (:require [re-frame.core :as re-frame] - [status-im.i18n :as i18n] - [status-im.ui.components.react :as react] - [status-im.ui.screens.wallet.collectibles.styles :as styles] - [status-im.ui.screens.wallet.collectibles.views :as collectibles] - [quo.core :as quo])) - -(defmethod collectibles/render-collectible :SUPR [_ {tokenId :tokenId {:keys [description name imageUri]} :metadata}] - [react/view {:style styles/details} - [react/view {:style styles/details-text} - [react/image {:style (merge {:resize-mode :contain :width 100 :height 100} styles/details-image) - :source {:uri imageUri - :k 1.4}}] - [react/view {:flex 1 :justify-content :center} - [react/text {:style styles/details-name} - name] - [react/text - description]]] - [quo/list-item - {:theme :accent - :title (i18n/label :t/view-superrare) - :icon :main-icons/address - :accessibility-label :open-collectible-button - :on-press #(re-frame/dispatch [:open-collectible-in-browser - (str "https://superrare.co/artwork/" name "-" tokenId)])}]]) diff --git a/src/status_im/ui/screens/wallet/collectibles/views.cljs b/src/status_im/ui/screens/wallet/collectibles/views.cljs deleted file mode 100644 index 379d3382e7..0000000000 --- a/src/status_im/ui/screens/wallet/collectibles/views.cljs +++ /dev/null @@ -1,34 +0,0 @@ -(ns status-im.ui.screens.wallet.collectibles.views - (:require-macros [status-im.utils.views :refer [defview letsubs]]) - (:require [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.styles :as component.styles] - [status-im.ui.screens.wallet.collectibles.styles :as styles] - [status-im.ui.components.topbar :as topbar])) - -(defmulti render-collectible (fn [symbol _] symbol)) - -(defmethod render-collectible :default [symbol {:keys [id name]}] - [react/view {:style styles/default-collectible} - [react/text (str (clojure.core/name symbol) " #" (or id name))]]) - -(defview collectibles-list [] - (letsubs [{:keys [name symbol]} [:get-screen-params] - collectibles [:screen-collectibles]] - [react/view {:style component.styles/flex} - [topbar/topbar {:title name}] - (cond - (nil? collectibles) - [react/view {:style styles/loading-indicator} - [react/activity-indicator {:animating true :size :large :color colors/blue}]] - (seq collectibles) - [list/flat-list {:data collectibles - :key-fn (comp str :id) - :render-fn #(render-collectible symbol %)}] - :else - ;; Should never happen. Less confusing to debug new NFT support. - [react/view {:style styles/loading-indicator} - [react/text (i18n/label :t/error)]])])) - diff --git a/src/status_im/wallet/collectibles/core.cljs b/src/status_im/wallet/collectibles/core.cljs deleted file mode 100644 index e96d03e027..0000000000 --- a/src/status_im/wallet/collectibles/core.cljs +++ /dev/null @@ -1,197 +0,0 @@ -(ns status-im.wallet.collectibles.core - (:require [re-frame.core :as re-frame] - [status-im.browser.core :as browser] - [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] - {:load-collectibles-fx [all-tokens symbol items-number address]}) - -(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]] - (let [contract (:address (tokens/symbol->token all-tokens symbol))] - (load-token 0 items-number contract address symbol)))) - -(handlers/register-handler-fx - :show-collectibles-list - (fn [{:keys [db]} [_ {:keys [symbol amount] :as collectible} address]] - (let [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)) - {:dispatch [:navigate-to :collectibles-list collectible]})))) - -;; Crypto Kitties -(def ck :CK) - -(handlers/register-handler-fx - :load-kitties - (fn [{db :db} [_ ids]] - {:db (update-in db [:collectibles] merge {ck (sorted-map-by >)}) - :http-get-n (mapv (fn [id] - {:url (str "https://api.cryptokitties.co/kitties/" id) - :on-success (fn [o] - (re-frame/dispatch [:load-collectible-success ck {id (http/parse-payload o)}])) - :on-error (fn [o] - (re-frame/dispatch [:load-collectible-failure ck {id (http/parse-payload o)}]))}) - ids)})) - -(defmethod load-collectibles-fx ck [_ _ items-number address _] - {:http-get-n (mapv (fn [offset] - {:url (str "https://api.cryptokitties.co/kitties?limit=20&offset=" - offset - "&owner_wallet_address=" - address - "&parents=false") - :on-success (fn [o] - (re-frame/dispatch [:load-kitties (map :id (:kitties (http/parse-payload o)))])) - :on-error (fn [o] - (re-frame/dispatch [:load-collectibles-failure (http/parse-payload o)])) - :timeout-ms 10000}) - (range 0 items-number 20))}) ;; Cryptokitties API limited to 20 items per request - -;; Crypto Strikers -(def strikers :STRK) - -(defmethod load-collectible-fx strikers [_ _ id] - {:http-get {:url (str "https://us-central1-cryptostrikers-prod.cloudfunctions.net/cards/" id) - :on-success (fn [o] - (re-frame/dispatch [:load-collectible-success strikers {id (http/parse-payload o)}])) - :on-error (fn [o] - (re-frame/dispatch [: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) - :on-success (fn [o] - (re-frame/dispatch [:load-collectible-success emona (:data (http/parse-payload o))])) - :on-error (fn [o] - (re-frame/dispatch [:load-collectible-failure emona {id (http/parse-payload o)}]))}}) - -;;Kudos -(def kudos :KDO) - -(defmethod load-collectible-fx kudos [{db :db} symbol id] - {:erc721-token-uri [(:wallet/all-tokens db) symbol id]}) - -(re-frame/reg-fx - :erc721-token-uri - (fn [[all-tokens symbol tokenId]] - (let [contract (:address (tokens/symbol->token all-tokens symbol))] - (erc721/token-uri contract - tokenId - #(re-frame/dispatch [:token-uri-success - tokenId - (when % - (subs % (.indexOf ^js % "http")))]))))) ;; extra chars in rinkeby - -;;Superrare -(def superrare :SUPR) - -(defmethod load-collectible-fx superrare [_ _ ids] - {:http-get-n (mapv (fn [id] - {:url id - :on-success (fn [o] - (re-frame/dispatch [:load-collectible-success superrare {id (http/parse-payload o)}])) - :on-error (fn [o] - (re-frame/dispatch [: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"}} - :on-success (fn [{:keys [response-body]}] - (re-frame/dispatch [:store-collectibles superrare - (get-in (http/parse-payload response-body) - [:data :collectiblesByOwner :collectibles])])) - :on-error (fn [{:keys [response-body]}] - (re-frame/dispatch [: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 - :on-success - (fn [o] - (re-frame/dispatch [:load-collectible-success kudos - {tokenId (update (http/parse-payload o) - :image - string/replace - #"http:" - "https:")}])) ;; http in mainnet - :on-error - (fn [o] - (re-frame/dispatch [: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))) diff --git a/src/status_im/wallet/core.cljs b/src/status_im/wallet/core.cljs index 332f8577c5..ff5b08b9fd 100644 --- a/src/status_im/wallet/core.cljs +++ b/src/status_im/wallet/core.cljs @@ -88,7 +88,7 @@ (defn- validate-token-symbol! [{:keys [address symbol]}] - (when-not (= symbol :DCN) ;; ignore this symbol because it has weird symbol + (when-not (or (= symbol :DCN) (= symbol :SUPRR)) ;; ignore this symbol because it has weird symbol (json-rpc/eth-call {:contract address :method "symbol()" diff --git a/translations/en.json b/translations/en.json index ab929eacd2..d616329dc7 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1203,6 +1203,7 @@ "cant-report-bug": "Can't report a bug", "mail-should-be-configured": "Mail client should be configured", "check-on-etherscan": "Check on etherscan", + "check-on-opensea": "Check on opensea", "transactions-load-more": "Load more", "private-key": "Private key", "generate-an-account": "Generate an account",