Skip to content

Commit

Permalink
feat: added base implementation of WC connect flow
Browse files Browse the repository at this point in the history
  • Loading branch information
clauxx committed May 8, 2024
1 parent 10f5f9e commit 22bd3da
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/status_im/constants.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,12 @@
(def regx-starts-with-uuid #"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")
(def regx-full-or-partial-address #"^0x[a-fA-F0-9]{1,40}$")

;; Wallet Connect
(def ^:const optimism-crosschain-id "eip155:10")
(def ^:const wallet-connect-supported-methods ["eth_sendTransaction" "personal_sign"])
(def ^:const wallet-connect-supported-events ["accountsChanged" "chainChanged"])
(def ^:const wallet-connect-session-proposal-event "session_proposal")

(def ^:const dapp-permission-contact-code "contact-code")
(def ^:const dapp-permission-web3 "web3")
(def ^:const dapp-permission-qr-code "qr-code")
Expand Down
3 changes: 3 additions & 0 deletions src/status_im/contexts/profile/login/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
[status-im.constants :as constants]
status-im.contexts.profile.login.effects
[status-im.contexts.profile.rpc :as profile.rpc]
[status-im.feature-flags :as ff]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
Expand Down Expand Up @@ -104,6 +105,8 @@
[:chat.ui/request-link-preview-whitelist]
[:visibility-status-updates/fetch]
[:switcher-cards/fetch]
(when (ff/enabled? ::ff/wallet.wallet-connect)
[:dispatch [:wallet-connect/init]])
(when-not (:universal-links/handling db)
[:effects.chat/open-last-chat key-uid])
(when notifications-enabled?
Expand Down
43 changes: 43 additions & 0 deletions src/status_im/contexts/wallet/wallet_connect/effects.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
(ns status-im.contexts.wallet.wallet-connect.effects
(:require [re-frame.core :as rf]
[status-im.contexts.wallet.wallet-connect.utils :as wallet-connect.utils]
[taoensso.timbre :as log]))

(rf/reg-fx
:effects.wallet-connect/init
(fn [{:keys [on-success on-fail]}]
(-> (wallet-connect.utils/init)
(.then on-success)
(.catch on-fail))))

(rf/reg-fx
:effects.wallet-connect/register-event-listener
(fn [web3-wallet wc-event handler]
(.on web3-wallet
wc-event
(fn [js-proposal]
(-> js-proposal
(js->clj :keywordize-keys true)
handler)))))

(rf/reg-fx
:effects.wallet-connect/pair
(fn [{:keys [web3-wallet url on-success on-fail]}]
(-> (.. web3-wallet -core -pairing)
(.pair (clj->js {:uri url}))
(.then on-success)
(.catch on-fail))))

(rf/reg-fx
:effects.wallet-connect/approve-session
(fn [{:keys [web3-wallet proposal supported-namespaces]}]
(let [{:keys [params id]} proposal
approved-namespaces (wallet-connect.utils/build-approved-namespaces params
supported-namespaces)]
(-> (.approveSession web3-wallet
(clj->js {:id id
:namespaces approved-namespaces}))
(.then #(log/info "Wallet Connect session approved"))
(.catch #(log/error "Wallet Connect session approve failed"
{:error %
:event :effects.wallet-connect/approve-session}))))))
71 changes: 71 additions & 0 deletions src/status_im/contexts/wallet/wallet_connect/events.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
(ns status-im.contexts.wallet.wallet-connect.events
(:require [re-frame.core :as rf]
[status-im.constants :as constants]
status-im.contexts.wallet.wallet-connect.effects
[status-im.contexts.wallet.wallet-connect.utils :as wallet-connect.utils]
[taoensso.timbre :as log]))

(rf/reg-event-fx
:wallet-connect/init
(fn []
{:fx [[:effects.wallet-connect/init
{:on-success #(rf/dispatch [:wallet-connect/on-init-success %])
:on-fail #(rf/dispatch [:wallet-connect/on-init-fail %])}]]}))

(rf/reg-event-fx
:wallet-connect/on-init-success
(fn [{:keys [db]} [web3-wallet]]
{:db (assoc db :wallet-connect/web3-wallet web3-wallet)
:fx [[:dispatch [:wallet-connect/register-event-listeners]]]}))

(rf/reg-event-fx
:wallet-connect/register-event-listeners
(fn [{:keys [db]}]
(let [web3-wallet (get db :wallet-connect/web3-wallet)]
{:fx [[:effects.wallet-connect/register-event-listener
web3-wallet
constants/wallet-connect-session-proposal-event
#(rf/dispatch [:wallet-connect/on-session-proposal %])]]})))

(rf/reg-event-fx
:wallet-connect/on-init-fail
(fn [error]
(log/error "Failed to initialize Wallet Connect"
{:error error
:event :wallet-connect/on-init-fail})))

(rf/reg-event-fx
:wallet-connect/on-session-proposal
(fn [{:keys [db]} [proposal]]
{:db (assoc db :wallet-connect/current-proposal proposal)}))

(rf/reg-event-fx
:wallet-connect/pair
(fn [{:keys [db]} [url]]
(let [web3-wallet (get db :wallet-connect/web3-wallet)]
{:fx [[:effects.wallet-connect/pair
{:web3-wallet web3-wallet
:url url
:on-fail #(log/error "Failed to pair with dApp")
:on-success #(log/info "dApp paired successfully")}]]})))

(rf/reg-event-fx
:wallet-connect/approve-session
(fn [{:keys [db]}]
;; NOTE: hardcoding optimism for the base implementation
(let [crosschain-ids [constants/optimism-crosschain-id]
web3-wallet (get db :wallet-connect/web3-wallet)
current-proposal (get db :wallet-connect/current-proposal)
accounts (get-in db [:wallet :accounts])
address (-> accounts keys first)
formatted-address (wallet-connect.utils/format-address (first crosschain-ids)
address)
supported-namespaces (clj->js {:eip155
{:chains crosschain-ids
:methods constants/wallet-connect-supported-methods
:events constants/wallet-connect-supported-events
:accounts [formatted-address]}})]
{:fx [[:effects.wallet-connect/approve-session
{:web3-wallet web3-wallet
:proposal current-proposal
:supported-namespaces supported-namespaces}]]})))
16 changes: 15 additions & 1 deletion src/status_im/contexts/wallet/wallet_connect/utils.cljs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
(ns status-im.contexts.wallet.wallet-connect.utils
(:require ["@walletconnect/core" :refer [Core]]
;; NOTE: Not sorting namespaces since @walletconnect/react-native-compat should be the first
#_{:clj-kondo/ignore [:unsorted-required-namespaces]}
(:require ["@walletconnect/react-native-compat"]
["@walletconnect/core" :refer [Core]]
["@walletconnect/web3wallet" :refer [Web3Wallet]]
["@walletconnect/utils" :refer [buildApprovedNamespaces]]
[status-im.config :as config]
[utils.i18n :as i18n]))

Expand All @@ -23,3 +27,13 @@
(Web3Wallet.init
(clj->js {:core core
:metadata wallet-connect-metadata}))))

(defn build-approved-namespaces
[proposal supported-namespaces]
(buildApprovedNamespaces
(clj->js {:proposal proposal
:supportedNamespaces supported-namespaces})))

(defn format-address
[chain-id address]
(str chain-id ":" address))
1 change: 1 addition & 0 deletions src/status_im/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
status-im.contexts.wallet.events
status-im.contexts.wallet.send.events
status-im.contexts.wallet.signals
status-im.contexts.wallet.wallet-connect.events
[status-im.db :as db]
status-im.navigation.effects
status-im.navigation.events
Expand Down
4 changes: 4 additions & 0 deletions src/status_im/subs/root.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@
;;wallet
(reg-root-key-sub :wallet :wallet)

;;wallet-connect
(reg-root-key-sub :wallet-connect/web3-wallet :wallet-connect/web3-wallet)
(reg-root-key-sub :wallet-connect/current-proposal :wallet-connect/current-proposal)

;;biometrics
(reg-root-key-sub :biometrics :biometrics)

Expand Down

0 comments on commit 22bd3da

Please sign in to comment.