diff --git a/src/status_im/contexts/wallet/wallet_connect/core.cljs b/src/status_im/contexts/wallet/wallet_connect/core.cljs index 1a2f994461..00c568b603 100644 --- a/src/status_im/contexts/wallet/wallet_connect/core.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/core.cljs @@ -3,6 +3,7 @@ [clojure.string :as string] [native-module.core :as native-module] [status-im.constants :as constants] + [status-im.contexts.wallet.common.utils.networks :as networks] [utils.security.core :as security] [utils.string] [utils.transforms :as transforms])) @@ -101,7 +102,7 @@ networks (get-in db [:wallet :networks (if test-mode? :test :prod)])] (mapv #(-> % :chain-id) networks))) -(defn add-full-testnet-name +(defn- add-full-testnet-name "Updates the `:full-name` key with the full testnet name if using testnet `:chain-id`.\n e.g. `{:full-name \"Mainnet\"}` -> `{:full-name \"Mainnet Sepolia\"`}`" [network] @@ -112,6 +113,12 @@ constants/goerli-chain-ids (add-testnet-name constants/goerli-full-name) network))) +(defn chain-id->network-details + [chain-id] + (-> chain-id + (networks/get-network-details) + (add-full-testnet-name))) + (defn event-should-be-handled? [db {:keys [topic]}] (some #(= topic %) diff --git a/src/status_im/contexts/wallet/wallet_connect/modals/common/page_nav/view.cljs b/src/status_im/contexts/wallet/wallet_connect/modals/common/page_nav/view.cljs index b16a526223..0a35fb8778 100644 --- a/src/status_im/contexts/wallet/wallet_connect/modals/common/page_nav/view.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/modals/common/page_nav/view.cljs @@ -7,6 +7,6 @@ [quo/page-nav {:icon-name :i/close :background :blur - :on-press #(do (rf/dispatch [:navigate-back]) + :on-press #(do (rf/dispatch [:wallet-connect/dismiss-request-modal]) (rf/dispatch [:wallet-connect/reject-session-request])) :accessibility-label accessibility-label}]) diff --git a/src/status_im/contexts/wallet/wallet_connect/processing_events.cljs b/src/status_im/contexts/wallet/wallet_connect/processing_events.cljs index 33adb4fc1d..f432ee7c2e 100644 --- a/src/status_im/contexts/wallet/wallet_connect/processing_events.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/processing_events.cljs @@ -5,8 +5,10 @@ [re-frame.core :as rf] [status-im.constants :as constants] [status-im.contexts.wallet.wallet-connect.core :as wallet-connect-core] + [status-im.contexts.wallet.wallet-connect.signing :as signing] [status-im.contexts.wallet.wallet-connect.transactions :as transactions] [taoensso.timbre :as log] + [utils.i18n :as i18n] [utils.transforms :as transforms])) (rf/reg-event-fx @@ -122,15 +124,30 @@ :wallet-connect/process-sign-typed (fn [{:keys [db]}] (let [[address raw-data] (wallet-connect-core/get-db-current-request-params db) - parsed-data (try (-> raw-data - transforms/js-parse + parsed-raw-data (transforms/js-parse raw-data) + session-chain-id (-> (wallet-connect-core/get-db-current-request-event db) + (get-in [:params :chainId]) + wallet-connect-core/eip155->chain-id) + data-chain-id (-> parsed-raw-data + transforms/js->clj + signing/typed-data-chain-id) + parsed-data (try (-> parsed-raw-data (transforms/js-dissoc :types :primaryType) (transforms/js-stringify 2)) (catch js/Error _ nil))] - (if (nil? parsed-data) + (cond + (nil? parsed-data) {:fx [[:dispatch [:wallet-connect/on-processing-error (ex-info "Failed to parse JSON typed data" {:data raw-data})]]]} + + (not= session-chain-id data-chain-id) + {:fx [[:dispatch + [:wallet-connect/wrong-typed-data-chain-id + {:expected-chain-id session-chain-id + :wrong-chain-id data-chain-id}]]]} + + :else {:db (update-in db [:wallet-connect/current-request] assoc @@ -139,19 +156,39 @@ :raw-data raw-data) :fx [[:dispatch [:wallet-connect/show-request-modal]]]})))) +(rf/reg-event-fx + :wallet-connect/wrong-typed-data-chain-id + (fn [_ [{:keys [expected-chain-id wrong-chain-id]}]] + (let [wrong-network-name (-> wrong-chain-id + wallet-connect-core/chain-id->network-details + :full-name) + expected-network-name (-> expected-chain-id + wallet-connect-core/chain-id->network-details + :full-name) + toast-message (i18n/label :t/wallet-connect-typed-data-wrong-chain-id-warning + {:wrong-chain wrong-network-name + :expected-chain expected-network-name})] + {:fx [[:dispatch + [:toasts/upsert + {:type :negative + :theme :dark + :text toast-message}]] + [:dispatch + [:wallet-connect/on-processing-error + (ex-info "Can't proceed signing typed data due to wrong chain-id included in the data" + {:expected-chain-id expected-chain-id + :wrong-chain-id wrong-chain-id})]]]}))) + ;; TODO: we should reject a request if processing fails (rf/reg-event-fx :wallet-connect/on-processing-error (fn [{:keys [db]} [error]] (let [{:keys [address event]} (get db :wallet-connect/current-request) - method (wallet-connect-core/get-request-method event) - screen (wallet-connect-core/method-to-screen method)] + method (wallet-connect-core/get-request-method event)] (log/error "Failed to process Wallet Connect request" {:error error :address address :method method :wallet-connect-event event :event :wallet-connect/on-processing-error}) - - {:fx [[:dispatch [:dismiss-modal screen]] - [:dispatch [:wallet-connect/reset-current-request]]]}))) + {:fx [[:dispatch [:wallet-connect/reject-session-request]]]}))) diff --git a/src/status_im/contexts/wallet/wallet_connect/responding_events.cljs b/src/status_im/contexts/wallet/wallet_connect/responding_events.cljs index 16c2c9a6e7..a487c09911 100644 --- a/src/status_im/contexts/wallet/wallet_connect/responding_events.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/responding_events.cljs @@ -39,7 +39,7 @@ :data raw-data :rpc-method rpc-method :on-error #(rf/dispatch [:wallet-connect/on-sign-error %]) - :on-success #(rf/dispatch [:wallet-connect/send-response {:result %}])}]]}))) + :on-success #(rf/dispatch [:wallet-connect/finish-session-request %])}]]}))) (rf/reg-event-fx :wallet-connect/respond-sign-typed-data @@ -53,7 +53,7 @@ :chain-id chain-id :version typed-data-version :on-error #(rf/dispatch [:wallet-connect/on-sign-error %]) - :on-success #(rf/dispatch [:wallet-connect/send-response {:result %}])}]]}))) + :on-success #(rf/dispatch [:wallet-connect/finish-session-request %])}]]}))) (rf/reg-event-fx :wallet-connect/respond-send-transaction-data @@ -67,7 +67,7 @@ :tx-hash tx-hash :tx-args tx-args :on-error #(rf/dispatch [:wallet-connect/on-sign-error %]) - :on-success #(rf/dispatch [:wallet-connect/send-response {:result %}])}]]}))) + :on-success #(rf/dispatch [:wallet-connect/finish-session-request %])}]]}))) (rf/reg-event-fx :wallet-connect/respond-sign-transaction-data @@ -81,15 +81,13 @@ :tx-hash tx-hash :tx-params tx-args :on-error #(rf/dispatch [:wallet-connect/on-sign-error %]) - :on-success #(rf/dispatch [:wallet-connect/send-response {:result %}])}]]}))) + :on-success #(rf/dispatch [:wallet-connect/finish-session-request %])}]]}))) -;; TODO: should reject if "signing" fails (rf/reg-event-fx :wallet-connect/on-sign-error (fn [{:keys [db]} [error]] (let [{:keys [raw-data address event]} (get db :wallet-connect/current-request) - method (wallet-connect-core/get-request-method event) - screen (wallet-connect-core/method-to-screen method)] + method (wallet-connect-core/get-request-method event)] (log/error "Failed to sign Wallet Connect request" {:error error :address address @@ -97,15 +95,14 @@ :method method :wallet-connect-event event :event :wallet-connect/on-sign-error}) - {:fx [[:dispatch [:dismiss-modal screen]] - [:dispatch [:wallet-connect/reset-current-request]]]}))) + {:fx [[:dispatch [:wallet-connect/reject-session-request]] + [:dispatch [:wallet-connect/dismiss-request-modal]]]}))) (rf/reg-event-fx :wallet-connect/send-response (fn [{:keys [db]} [{:keys [result error]}]] (let [{:keys [id topic] :as event} (get-in db [:wallet-connect/current-request :event]) method (wallet-connect-core/get-request-method event) - screen (wallet-connect-core/method-to-screen method) web3-wallet (get db :wallet-connect/web3-wallet)] {:fx [[:effects.wallet-connect/respond-session-request {:web3-wallet web3-wallet @@ -119,13 +116,26 @@ :method method :event :wallet-connect/send-response :wallet-connect-event event}) - (rf/dispatch [:dismiss-modal screen]) (rf/dispatch [:wallet-connect/reset-current-request])) :on-success (fn [] (log/info "Successfully sent Wallet Connect response to dApp") - (rf/dispatch [:dismiss-modal screen]) (rf/dispatch [:wallet-connect/reset-current-request]))}]]}))) +(rf/reg-event-fx + :wallet-connect/dismiss-request-modal + (fn [{:keys [db]} _] + (let [screen (-> db + (get-in [:wallet-connect/current-request :event]) + wallet-connect-core/get-request-method + wallet-connect-core/method-to-screen)] + {:fx [[:dispatch [:dismiss-modal screen]]]}))) + +(rf/reg-event-fx + :wallet-connect/finish-session-request + (fn [_ [result]] + {:fx [[:dispatch [:wallet-connect/send-response {:result result}]] + [:dispatch [:wallet-connect/dismiss-request-modal]]]})) + (rf/reg-event-fx :wallet-connect/reject-session-proposal (fn [{:keys [db]} _] @@ -143,6 +153,8 @@ ;; - Unsupported WC version ;; - Invalid params from dapps ;; - Unsupported method +;; - Failed processing of request +;; - Failed "responding" (signing or sending message/transaction) (rf/reg-event-fx :wallet-connect/reject-session-request (fn [_ _] diff --git a/src/status_im/contexts/wallet/wallet_connect/signing.cljs b/src/status_im/contexts/wallet/wallet_connect/signing.cljs index 29ecec1021..575661a902 100644 --- a/src/status_im/contexts/wallet/wallet_connect/signing.cljs +++ b/src/status_im/contexts/wallet/wallet_connect/signing.cljs @@ -6,6 +6,20 @@ [utils.hex :as hex] [utils.transforms :as transforms])) +(defn typed-data-chain-id + "Returns the `:chain-id` from typed data if it's present and if the EIP712 domain defines it. Without + the `:chain-id` in the domain type, it will not be signed as part of the typed-data." + [typed-data] + (let [chain-id-type? (->> typed-data + :types + :EIP712Domain + (some #(= "chainId" (:name %)))) + data-chain-id (-> typed-data + :domain + :chainId)] + (when chain-id-type? + data-chain-id))) + (defn eth-sign [password address data] (-> {:data data diff --git a/src/status_im/subs/wallet/wallet_connect.cljs b/src/status_im/subs/wallet/wallet_connect.cljs index eae794c7c7..ea1eaf96ac 100644 --- a/src/status_im/subs/wallet/wallet_connect.cljs +++ b/src/status_im/subs/wallet/wallet_connect.cljs @@ -2,7 +2,6 @@ (:require [clojure.string :as string] [re-frame.core :as rf] [status-im.contexts.wallet.common.utils :as wallet-utils] - [status-im.contexts.wallet.common.utils.networks :as networks] [status-im.contexts.wallet.wallet-connect.core :as wallet-connect-core] [status-im.contexts.wallet.wallet-connect.transactions :as transactions] [utils.money :as money] @@ -70,10 +69,7 @@ (rf/reg-sub :wallet-connect/current-request-network :<- [:wallet-connect/chain-id] - (fn [chain-id] - (-> chain-id - (networks/get-network-details) - (wallet-connect-core/add-full-testnet-name)))) + wallet-connect-core/chain-id->network-details) (rf/reg-sub :wallet-connect/transaction-args diff --git a/translations/en.json b/translations/en.json index cf047a9325..f94d2463a6 100644 --- a/translations/en.json +++ b/translations/en.json @@ -2642,6 +2642,7 @@ "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-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", "wallet-connect-wrong-qr": "It’s not a WalletConnect QR",