diff --git a/src/status_im/common/standard_authentication/events.cljs b/src/status_im/common/standard_authentication/events.cljs index 669ef3f525..9f9b44d62e 100644 --- a/src/status_im/common/standard_authentication/events.cljs +++ b/src/status_im/common/standard_authentication/events.cljs @@ -22,12 +22,7 @@ [(if keycard? (if keycard-supported? [:effects.keycard/call-on-auth-success on-auth-success] - [:effects.utils/show-popup - {:title "This feature is not supported yet " - :content - "Keycard support is limited to logging in - and signing the sending transaction. - Use Status Desktop to access all functions."}]) + [:dispatch [:keycard/feature-unavailable-show]]) [:effects.biometric/check-if-available {:key-uid key-uid :on-success #(rf/dispatch [:standard-auth/authorize-with-biometric args]) diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index b2168b93b2..f8fb037956 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -329,6 +329,7 @@ (def ^:const privacy-policy-link "https://status.im/privacy-policy/") (def ^:const terms-of-service-link "https://status.im/terms-of-use") (def ^:const create-account-link "https://status.app/help/wallet/create-wallet-accounts") +(def ^:const mobile-upvote-link "https://status-mobile.featureupvote.com") (def ^:const visibility-status-unknown 0) (def ^:const visibility-status-automatic 1) diff --git a/src/status_im/contexts/keycard/feature_unavailable/events.cljs b/src/status_im/contexts/keycard/feature_unavailable/events.cljs new file mode 100644 index 0000000000..091c60348c --- /dev/null +++ b/src/status_im/contexts/keycard/feature_unavailable/events.cljs @@ -0,0 +1,9 @@ +(ns status-im.contexts.keycard.feature-unavailable.events + (:require + [status-im.contexts.keycard.feature-unavailable.view :as feature-unavailable] + [utils.re-frame :as rf])) + +(rf/reg-event-fx + :keycard/feature-unavailable-show + (fn [_] + {:fx [[:dispatch [:show-bottom-sheet {:content feature-unavailable/view}]]]})) diff --git a/src/status_im/contexts/keycard/feature_unavailable/view.cljs b/src/status_im/contexts/keycard/feature_unavailable/view.cljs new file mode 100644 index 0000000000..a0dec7d5e4 --- /dev/null +++ b/src/status_im/contexts/keycard/feature_unavailable/view.cljs @@ -0,0 +1,28 @@ +(ns status-im.contexts.keycard.feature-unavailable.view + (:require + [quo.core :as quo] + [status-im.constants :as constants] + [utils.i18n :as i18n] + [utils.re-frame :as rf])) + +(defn on-upvote + [] + (rf/dispatch [:open-url constants/mobile-upvote-link])) + +(defn view + [] + [:<> + [quo/drawer-top + {:title (i18n/label :t/feature-unavailable) + :description (i18n/label :t/feature-unavailable-for-keycard-description)}] + [quo/information-box + {:type :default + :icon :i/info + :style {:margin-top 8 :margin-horizontal 20}} + [:<> + (i18n/label :t/feature-unavailable-info) + [quo/text + {:style {:text-decoration-line :underline} + :size :paragraph-2 + :on-press on-upvote} + (i18n/label :t/upvote-it)]]]]) diff --git a/src/status_im/contexts/wallet/common/account_switcher/view.cljs b/src/status_im/contexts/wallet/common/account_switcher/view.cljs index df8c7874d5..fe5c5612b2 100644 --- a/src/status_im/contexts/wallet/common/account_switcher/view.cljs +++ b/src/status_im/contexts/wallet/common/account_switcher/view.cljs @@ -30,7 +30,8 @@ type :no-title}}] (let [{:keys [color emoji watch-only?]} (rf/sub [:wallet/current-viewing-account]) networks (rf/sub [:wallet/selected-network-details]) - sending-collectible? (rf/sub [:wallet/sending-collectible?])] + sending-collectible? (rf/sub [:wallet/sending-collectible?]) + keycard? (rf/sub [:wallet/selected-keypair-keycard?])] [quo/page-nav {:type type :icon-name icon-name @@ -45,7 +46,10 @@ (not watch-only?) show-dapps-button?) {:icon-name :i/dapps - :on-press #(rf/dispatch [:navigate-to :screen/wallet.connected-dapps])}) + :on-press #(rf/dispatch + (if keycard? + [:keycard/feature-unavailable-show] + [:navigate-to :screen/wallet.connected-dapps]))}) (when-not sending-collectible? {:content-type :account-switcher :customization-color color diff --git a/src/status_im/contexts/wallet/data_store.cljs b/src/status_im/contexts/wallet/data_store.cljs index 1ff6d923ae..e17bed38c9 100644 --- a/src/status_im/contexts/wallet/data_store.cljs +++ b/src/status_im/contexts/wallet/data_store.cljs @@ -291,3 +291,10 @@ (cske/transform-keys transforms/->kebab-case-keyword) (map #(assoc % :unique-id (collectible-utils/get-collectible-unique-id %))) vec)) + +(defn selected-keypair-keycard? + [db] + (let [keypairs (get-in db [:wallet :keypairs]) + selected-keypair-uid (get-in db [:wallet :ui :create-account :selected-keypair-uid]) + keypair (get keypairs selected-keypair-uid)] + (boolean (seq (:keycards keypair))))) diff --git a/src/status_im/contexts/wallet/data_store_test.cljs b/src/status_im/contexts/wallet/data_store_test.cljs index 851c70bfdd..6b30f15748 100644 --- a/src/status_im/contexts/wallet/data_store_test.cljs +++ b/src/status_im/contexts/wallet/data_store_test.cljs @@ -231,3 +231,37 @@ :wallet true :default-account? true})]}}} (sut/reconcile-keypairs [raw-keypair-profile]))))) + +(def mock-db + {:wallet {:keypairs + {"0x123" {:type "key" + :key-uid "0x123" + :keycards [{:id "keycard1"}]} + "0x456" {:type "key" + :key-uid "0x456" + :keycards []}} + :ui {:create-account {:selected-keypair-uid "0x123"}}}}) + +(deftest selected-keypair-keycard?-test + (testing "returns true when the selected keypair has keycards" + (is (true? (sut/selected-keypair-keycard? mock-db)))) + + (testing "returns false when the selected keypair does not have keycards" + (let [db (assoc-in mock-db [:wallet :ui :create-account :selected-keypair-uid] "0x456")] + (is (false? (sut/selected-keypair-keycard? db))))) + + (testing "returns false when the selected keypair does not exist" + (let [db (assoc-in mock-db [:wallet :ui :create-account :selected-keypair-uid] "0x789")] + (is (false? (sut/selected-keypair-keycard? db))))) + + (testing "returns false when keypairs map is empty" + (let [db (assoc-in mock-db [:wallet :keypairs] {})] + (is (false? (sut/selected-keypair-keycard? db))))) + + (testing "returns false when no keypair is selected" + (let [db (assoc-in mock-db [:wallet :ui :create-account :selected-keypair-uid] nil)] + (is (false? (sut/selected-keypair-keycard? db))))) + + (testing "returns false when db does not contain wallet data" + (let [db {}] + (is (false? (sut/selected-keypair-keycard? db)))))) diff --git a/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs b/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs index 397f79cfc9..0b8845c589 100644 --- a/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs +++ b/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs @@ -102,6 +102,7 @@ :wallet/wallet-send-tx-type :tx/send :wallet/wallet-send-fee-fiat-formatted "$5,00" :wallet/sending-collectible? false + :wallet/selected-keypair-keycard? false :wallet/send-total-amount-formatted "250 ETH" :wallet/total-amount (money/bignumber "250") :wallet/prices-per-token {:ETH {:usd 10}} diff --git a/src/status_im/contexts/wallet/wallet_connect/events/session_proposals.cljs b/src/status_im/contexts/wallet/wallet_connect/events/session_proposals.cljs index bde85c4dd9..09b790e79f 100644 --- a/src/status_im/contexts/wallet/wallet_connect/events/session_proposals.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/events/session_proposals.cljs @@ -2,6 +2,7 @@ (:require [clojure.string :as string] [re-frame.core :as rf] [react-native.wallet-connect :as wallet-connect] + [status-im.contexts.wallet.data-store :as wallet-data-store] [status-im.contexts.wallet.wallet-connect.utils.data-store :as data-store] [status-im.contexts.wallet.wallet-connect.utils.networks :as networks] @@ -30,11 +31,17 @@ expired? (-> parsed-uri :expiryTimestamp uri/timestamp-expired?) - version-supported? (uri/version-supported? version)] - (if (or (not valid-wc-uri?) - (not version-supported?) - (= network-status :offline) - expired?) + version-supported? (uri/version-supported? version) + keycard? (wallet-data-store/selected-keypair-keycard? db)] + (cond + + keycard? + {:fx [[:dispatch [:keycard/feature-unavailable-show]]]} + + (or (not valid-wc-uri?) + (not version-supported?) + (= network-status :offline) + expired?) {:fx [[:dispatch [:toasts/upsert {:type :negative @@ -54,6 +61,8 @@ :else (i18n/label :t/something-went-wrong))}]]]} + + :else {:fx [[:dispatch [:wallet-connect/pair scanned-text]]]})))) (rf/reg-event-fx diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index 8665edf21d..3b1f2ee3c4 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -27,6 +27,7 @@ status-im.contexts.contact.blocking.events status-im.contexts.keycard.effects status-im.contexts.keycard.events + status-im.contexts.keycard.feature-unavailable.events status-im.contexts.network.effects status-im.contexts.network.events status-im.contexts.onboarding.common.overlay.events diff --git a/src/status_im/subs/wallet/wallet.cljs b/src/status_im/subs/wallet/wallet.cljs index 63d510646f..2b56325af5 100644 --- a/src/status_im/subs/wallet/wallet.cljs +++ b/src/status_im/subs/wallet/wallet.cljs @@ -286,6 +286,12 @@ :<- [:wallet/create-account] :-> :selected-keypair-uid) +(rf/reg-sub + :wallet/selected-keypair-keycard? + :<- [:wallet/selected-keypair] + (fn [{:keys [keycards]}] + (boolean (seq keycards)))) + (rf/reg-sub :wallet/selected-keypair :<- [:wallet/keypairs] diff --git a/src/status_im/subs/wallet/wallet_test.cljs b/src/status_im/subs/wallet/wallet_test.cljs index b5854ee842..ca751782e2 100644 --- a/src/status_im/subs/wallet/wallet_test.cljs +++ b/src/status_im/subs/wallet/wallet_test.cljs @@ -1133,3 +1133,25 @@ "0") :has-error false}}}]}})) (is (false? (rf/sub [sub-name]))))) + +(h/deftest-sub :wallet/selected-keypair-keycard? + [sub-name] + (testing "returns true if the selected keypair has keycards" + (swap! rf-db/app-db + #(assoc-in % + [:wallet :keypairs] + {:keypair-1 {:id :keypair-1 + :keycards [:keycard-1 :keycard-2]}})) + (swap! rf-db/app-db + #(assoc-in % [:wallet :ui :create-account :selected-keypair-uid] :keypair-1)) + (is (true? (rf/sub [sub-name])))) + + (testing "returns false if the selected keypair has no keycards" + (swap! rf-db/app-db + #(assoc-in % + [:wallet :keypairs] + {:keypair-2 {:id :keypair-2 + :keycards []}})) + (swap! rf-db/app-db + #(assoc-in % [:wallet :ui :create-account :selected-keypair-uid] :keypair-2)) + (is (false? (rf/sub [sub-name]))))) diff --git a/translations/en.json b/translations/en.json index 879643f444..14618718c0 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1037,6 +1037,9 @@ "favourite-description": "Your favourite websites will appear here", "favourites": "Favourites", "favourites-empty": "Addresses added to favourites will appear here", + "feature-unavailable": "Feature unavailable", + "feature-unavailable-for-keycard-description": "It’s not currently supported for Keycard users.", + "feature-unavailable-info": "If you'd like this feature on mobile, feel free to ", "featured": "Featured", "feb": "Feb", "fee-cap": "Fee cap", @@ -2719,6 +2722,7 @@ "update-to-see-sticker": "Update to latest version to see a nice sticker here!", "updates-to-tos": "Updates to Terms of Use", "updates-to-tos-desc": "Before you continue, please review the Terms of Use and confirm you take full responsibility for how you use the app.", + "upvote-it": "upvote it", "url": "URL", "usage-data-shared-from-all-profiles": "Usage data will be shared from all profiles added to device. ", "usd-currency": "USD",