diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index f201f2443f..96427f8c79 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -290,6 +290,14 @@ (def ^:const wallet-connect-user-rejected-error-key "USER_REJECTED") (def ^:const wallet-connect-user-disconnected-reason-key "USER_DISCONNECTED") (def ^:const wallet-connect-user-rejected-chains-error-key "USER_REJECTED_CHAINS") +(def ^:const wallet-connect-message-signing-methods + #{wallet-connect-personal-sign-method + wallet-connect-eth-sign-typed-method + wallet-connect-eth-sign-method + wallet-connect-eth-sign-typed-v4-method}) +(def ^:const wallet-connect-transaction-methods + #{wallet-connect-eth-send-transaction-method + wallet-connect-eth-sign-transaction-method}) (def ^:const transaction-pending-type-wallet-connect-transfer "WalletConnectTransfer") 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 2a35edd3a8..bde85c4dd9 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 @@ -143,10 +143,15 @@ (rf/reg-event-fx :wallet-connect/approve-session-success (fn [{:keys [db]} [session]] (log/info "Successfully approved WalletConnect session" session) - (let [total-connected-dapps (data-store/get-total-connected-dapps db)] + (let [total-connected-dapps (data-store/get-total-connected-dapps db) + dapp-name (data-store/get-dapp-name session)] {:fx [[:dispatch [:wallet-connect/on-new-session session]] [:dispatch [:wallet-connect/reset-current-session-proposal]] [:dispatch [:wallet-connect/redirect-to-dapp (data-store/get-dapp-redirect-url session)]] + [:dispatch + [:toasts/upsert + {:type :positive + :text (i18n/label :t/wallet-connect-proposal-approved-toast {:dapp dapp-name})}]] [:dispatch [:centralized-metrics/track :metric/dapp-session-proposal {:action :approved @@ -157,7 +162,11 @@ (log/error "Wallet Connect session approval failed" {:error error :event :wallet-connect/approve-session}) - {:fx [[:dispatch [:wallet-connect/reset-current-session-proposal]]]})) + {:fx [[:dispatch [:wallet-connect/reset-current-session-proposal]] + [:dispatch + [:toasts/upsert + {:type :negative + :text (i18n/label :t/wallet-connect-something-went-wrong)}]]]})) (rf/reg-event-fx :wallet-connect/reject-session-proposal @@ -165,13 +174,21 @@ (let [web3-wallet (get db :wallet-connect/web3-wallet) {:keys [request response-sent?]} (:wallet-connect/current-proposal db) networks (networks/get-proposal-networks (or proposal request)) - rejected? (nil? proposal)] + rejected? (nil? proposal) + dapp-name (-> (data-store/get-session-dapp-metadata (or proposal + request)) + :name)] {:fx (concat (when-not response-sent? [[:effects.wallet-connect/reject-session-proposal {:web3-wallet web3-wallet :proposal (or proposal request) - :on-success #(log/info "Wallet Connect session proposal rejected") + :on-success (fn [] + (log/info "Wallet Connect session proposal rejected") + (rf/dispatch [:toasts/upsert + {:type :positive + :text (i18n/label :t/wallet-connect-proposal-rejected-toast + {:dapp dapp-name})}])) :on-error #(log/error "Wallet Connect unable to reject session proposal")}] [:dispatch [:centralized-metrics/track :metric/dapp-session-proposal diff --git a/src/status_im/contexts/wallet/wallet_connect/events/session_responses.cljs b/src/status_im/contexts/wallet/wallet_connect/events/session_responses.cljs index 91d0f8ec7a..258911be72 100644 --- a/src/status_im/contexts/wallet/wallet_connect/events/session_responses.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/events/session_responses.cljs @@ -112,7 +112,7 @@ [:dispatch [:toasts/upsert {:type :negative - :text (i18n/label :t/something-went-wrong)}]]]}))) + :text (i18n/label :t/wallet-connect-something-went-wrong)}]]]}))) (rf/reg-event-fx :wallet-connect/send-response @@ -162,14 +162,24 @@ (rf/reg-event-fx :wallet-connect/finish-session-request (fn [{:keys [db]} [result]] - (let [event (get-in db [:wallet-connect/current-request :event]) - method (data-store/get-request-method event)] + (let [event (get-in db [:wallet-connect/current-request :event]) + method (data-store/get-request-method event) + toast-text (condp contains? method + constants/wallet-connect-message-signing-methods + (i18n/label :t/wallet-connect-message-request-success-toast) + + constants/wallet-connect-transaction-methods + (i18n/label :t/wallet-connect-transaction-request-success-toast))] {:fx [[:dispatch [:centralized-metrics/track :metric/dapp-session-response {:method method :approved true}]] [:dispatch [:wallet-connect/send-response {:result result}]] - [:dispatch [:wallet-connect/dismiss-request-modal]]]}))) + [:dispatch [:wallet-connect/dismiss-request-modal]] + [:dispatch + [:toasts/upsert + {:type :positive + :text toast-text}]]]}))) ;; NOTE: Currently we only reject a session if the user dismissed a modal ;; without accepting the session first. @@ -182,8 +192,11 @@ (rf/reg-event-fx :wallet-connect/on-request-modal-dismissed (fn [{:keys [db]}] - (let [{:keys [response-sent? event]} (get db :wallet-connect/current-request) - method (data-store/get-request-method event)] + (let [{:keys [response-sent? event] :as request} (get db :wallet-connect/current-request) + method (data-store/get-request-method event) + dapp (->> (get db :wallet-connect/sessions) + (data-store/get-current-request-dapp request) + :name)] {:fx (concat (when-not response-sent? [[:dispatch @@ -194,5 +207,10 @@ [:wallet-connect/send-response {:request event :error (wallet-connect/get-sdk-error - constants/wallet-connect-user-rejected-error-key)}]]]) + constants/wallet-connect-user-rejected-error-key)}]] + [:dispatch + [:toasts/upsert + {:type :positive + :text (i18n/label :t/wallet-connect-sign-request-rejected-toast + {:dapp dapp})}]]]) [[:dispatch [:wallet-connect/reset-current-request]]])}))) diff --git a/src/status_im/contexts/wallet/wallet_connect/events/sessions.cljs b/src/status_im/contexts/wallet/wallet_connect/events/sessions.cljs index e084cb84f0..ba64e8d604 100644 --- a/src/status_im/contexts/wallet/wallet_connect/events/sessions.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/events/sessions.cljs @@ -1,5 +1,7 @@ (ns status-im.contexts.wallet.wallet-connect.events.sessions (:require [re-frame.core :as rf] + [status-im.contexts.wallet.wallet-connect.utils.data-store :as + data-store] [status-im.contexts.wallet.wallet-connect.utils.networks :as networks] [status-im.contexts.wallet.wallet-connect.utils.sessions :as sessions] [taoensso.timbre :as log] @@ -8,16 +10,26 @@ (rf/reg-event-fx :wallet-connect/on-session-delete (fn [{:keys [db]} [{:keys [topic] :as event}]] - (when (networks/event-should-be-handled? db event) - (log/info "Received Wallet Connect session delete from the SDK: " event) - {:fx [[:json-rpc/call - [{:method "wallet_disconnectWalletConnectSession" - :params [topic] - :on-success [:wallet-connect/delete-session topic] - :on-error #(log/info "Wallet Connect session persistence failed" %)}]] - [:dispatch - [:centralized-metrics/track - :metric/dapp-session-disconnected]]]}))) + (let [session (data-store/get-session-by-topic db topic) + account-name (-> (data-store/get-account-by-session db session) + :name)] + (when (networks/event-should-be-handled? db event) + (log/info "Received Wallet Connect session delete from the SDK: " event) + {:fx [[:json-rpc/call + [{:method "wallet_disconnectWalletConnectSession" + :params [topic] + :on-success [:wallet-connect/delete-session topic] + :on-error #(log/info "Wallet Connect session persistence failed" %)}]] + [:dispatch + [:toasts/upsert + {:id :dapp-disconnect-success + :type :positive + :text (i18n/label :t/disconnect-dapp-success + {:dapp (:name session) + :account account-name})}]] + [:dispatch + [:centralized-metrics/track + :metric/dapp-session-disconnected]]]})))) (rf/reg-event-fx :wallet-connect/disconnect-dapp diff --git a/src/status_im/contexts/wallet/wallet_connect/utils/data_store.cljs b/src/status_im/contexts/wallet/wallet_connect/utils/data_store.cljs index e51d751c53..491468cf4c 100644 --- a/src/status_im/contexts/wallet/wallet_connect/utils/data_store.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/utils/data_store.cljs @@ -2,6 +2,8 @@ (:require [clojure.string :as string] [status-im.constants :as constants] + [status-im.contexts.wallet.common.utils :as wallet-utils] + [status-im.contexts.wallet.common.utils.networks :as network-utils] utils.string [utils.transforms :as transforms])) @@ -68,6 +70,10 @@ [session] (get-in session [:peer :metadata :redirect :native])) +(defn get-dapp-name + [session] + (get-in session [:peer :metadata :name])) + (defn get-db-current-request-params [db] (-> db @@ -80,3 +86,17 @@ :wallet-connect/sessions count inc)) + +(defn get-session-by-topic + [db topic] + (->> db + :wallet-connect/sessions + (filter #(= (:topic %) topic)) + first)) + +(defn get-account-by-session + [db session] + (let [accounts (get-in db [:wallet :accounts]) + session-account-address (first (:accounts session)) + [_ address] (network-utils/split-network-full-address session-account-address)] + (wallet-utils/get-account-by-address (vals accounts) address))) diff --git a/src/status_im/contexts/wallet/wallet_connect/utils/data_store_test.cljs b/src/status_im/contexts/wallet/wallet_connect/utils/data_store_test.cljs index a019b27f31..54b7d569fc 100644 --- a/src/status_im/contexts/wallet/wallet_connect/utils/data_store_test.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/utils/data_store_test.cljs @@ -1,7 +1,10 @@ (ns status-im.contexts.wallet.wallet-connect.utils.data-store-test (:require [cljs.test :refer-macros [deftest is testing]] - [status-im.contexts.wallet.wallet-connect.utils.data-store :as sut])) + [clojure.string :as string] + [status-im.contexts.wallet.common.utils.networks :as network-utils] + [status-im.contexts.wallet.wallet-connect.utils.data-store :as sut] + [utils.string])) (deftest get-current-request-dapp-test (testing "returns the correct dapp based on the request's origin" @@ -39,3 +42,44 @@ (testing "handles nil sessions correctly" (let [db {:wallet-connect/sessions nil}] (is (= 1 (sut/get-total-connected-dapps db)))))) + +(deftest get-session-by-topic-test + (testing "returns the correct session based on the topic" + (let [db {:wallet-connect/sessions [{:topic "topic1" :url "https://dapp1.com"} + {:topic "topic2" :url "https://dapp2.com"}]} + topic "topic1"] + (is (= {:topic "topic1" :url "https://dapp1.com"} + (sut/get-session-by-topic db topic))))) + + (testing "returns nil if no matching session is found" + (let [db {:wallet-connect/sessions [{:topic "topic1" :url "https://dapp1.com"}]} + topic "topic2"] + (is (nil? (sut/get-session-by-topic db topic))))) + + (testing "handles nil sessions correctly" + (let [db {:wallet-connect/sessions nil} + topic "topic1"] + (is (nil? (sut/get-session-by-topic db topic))))) + + (testing "handles empty sessions correctly" + (let [db {:wallet-connect/sessions []} + topic "topic1"] + (is (nil? (sut/get-session-by-topic db topic)))))); + +(deftest get-account-by-session-test + (testing "get-account-by-session function" + (let [db {:wallet {:accounts {"0x123" {:address "0x123"} + "0x456" {:address "0x456"} + "0x789" {:address "0x789"}}}} + session {:accounts ["network:0x456"]}] + (with-redefs [network-utils/split-network-full-address (fn [addr] + (string/split addr #":"))] + (is (= (sut/get-account-by-session db session) {:address "0x456"})))) + + (let [db {:wallet {:accounts {"0x123" {:address "0x123"} + "0x456" {:address "0x456"} + "0x789" {:address "0x789"}}}} + session {:accounts ["network:0x999"]}] + (with-redefs [network-utils/split-network-full-address (fn [addr] + (string/split addr #":"))] + (is (= (sut/get-account-by-session db session) nil)))))) diff --git a/translations/en.json b/translations/en.json index 3874173d30..14e18e7245 100644 --- a/translations/en.json +++ b/translations/en.json @@ -2760,10 +2760,13 @@ "wallet-connect-connections-error": "Failed to get dApps connections", "wallet-connect-go-back": "Go back to your browser or dapp", "wallet-connect-label": "WalletConnect", + "wallet-connect-message-request-success-toast": "Message signed, go back to the dApp", "wallet-connect-networks-not-supported": "{{dapp}} requires an unsupported network.", "wallet-connect-no-internet-warning": "Oops, you have no internet. Try again later!", + "wallet-connect-proposal-approved-toast": "Connected to {{dapp}}, go back to the dApp", "wallet-connect-proposal-description": "By connecting you allow {{name}} to retrieve your account address and enable Web3", "wallet-connect-proposal-expired": "WalletConnect proposal has expired", + "wallet-connect-proposal-rejected-toast": "Connection request from {{dapp}} declined", "wallet-connect-proposal-title": "Would like to connect with your wallet", "wallet-connect-qr-expired": "WalletConnect QR has expired", "wallet-connect-request-expired": "WalletConnect request has expired", @@ -2771,9 +2774,12 @@ "wallet-connect-send-transaction-warning": "Send transactions only if you trust the dApp", "wallet-connect-sign-message-header": "wants you to sign the message with", "wallet-connect-sign-message-warning": "Sign messages only if you trust the dApp", + "wallet-connect-sign-request-rejected-toast": "{{dapp}} sign request rejected", "wallet-connect-sign-transaction-header": "wants you to sign this transaction with", "wallet-connect-sign-transaction-warning": "Sign transactions only if you trust the dApp", "wallet-connect-sign-warning": "Sign only if you trust the dApp", + "wallet-connect-something-went-wrong": "Oops, something went wrong with this request", + "wallet-connect-transaction-request-success-toast": "Transaction signed, go back to the dApp", "wallet-connect-typed-data-wrong-chain-id-warning": "Wrong network in the request data. Expected '{{expected-chain}}', but got '{{wrong-chain}}'", "wallet-connect-version-not-supported": "WalletConnect version {{version}} is not supported", "wallet-connect-via": "via",