Wallet Connect session establish networks (#20576)
* feat: showing supported networks in wc connection * feat: added :large size for quo/data-item * feat: added required networks check
This commit is contained in:
parent
b021b1e20a
commit
ac4ffd83db
|
@ -6,8 +6,14 @@
|
|||
[{:keys [size card? blur? actionable? theme]}]
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:padding-vertical (when (= size :default) 8)
|
||||
:padding-horizontal (when (= size :default) 12)
|
||||
:padding-vertical (case size
|
||||
:default 8
|
||||
:large 12
|
||||
nil)
|
||||
:padding-horizontal (case size
|
||||
:default 12
|
||||
:large 16
|
||||
nil)
|
||||
:border-radius 16
|
||||
:border-width (when (and card? (not= size :small)) 1)
|
||||
:background-color (if blur?
|
||||
|
@ -24,15 +30,27 @@
|
|||
|
||||
(defn loading-container
|
||||
[size blur? theme]
|
||||
{:width (if (= size :default) 132 72)
|
||||
:height (if (= size :default) 16 10)
|
||||
{:width (case size
|
||||
:large 132
|
||||
:small 72
|
||||
132)
|
||||
:height (case size
|
||||
:large 16
|
||||
:small 10
|
||||
16)
|
||||
:background-color (if blur?
|
||||
colors/white-opa-5
|
||||
(colors/theme-colors colors/neutral-5
|
||||
colors/neutral-90
|
||||
theme))
|
||||
:border-radius (if (= size :default) 6 3)
|
||||
:margin-vertical (if (= size :default) 4 3)})
|
||||
:border-radius (case size
|
||||
:large 6
|
||||
:small 3
|
||||
6)
|
||||
:margin-vertical (case size
|
||||
:large 4
|
||||
:small 3
|
||||
4)})
|
||||
|
||||
(def subtitle-container
|
||||
{:flex-direction :row
|
||||
|
|
|
@ -55,7 +55,8 @@
|
|||
{:type :select
|
||||
:key :size
|
||||
:options [{:key :default}
|
||||
{:key :small}]}])
|
||||
{:key :small}
|
||||
{:key :large}]}])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
|
|
|
@ -45,6 +45,10 @@
|
|||
[db]
|
||||
(get-in db [:wallet-connect/current-request :event]))
|
||||
|
||||
(defn get-session-dapp-metadata
|
||||
[proposal]
|
||||
(get-in proposal [:params :proposer :metadata]))
|
||||
|
||||
(defn get-db-current-request-params
|
||||
[db]
|
||||
(-> db
|
||||
|
@ -61,3 +65,32 @@
|
|||
(->> password
|
||||
security/safe-unmask-data
|
||||
(f data address))))
|
||||
|
||||
(defn get-proposal-networks
|
||||
[proposal]
|
||||
(let [required-namespaces (get-in proposal [:params :requiredNamespaces])
|
||||
optional-namespaces (get-in proposal [:params :optionalNamespaces])]
|
||||
(->> [required-namespaces optional-namespaces]
|
||||
(map #(get-in % [:eip155 :chains]))
|
||||
(apply concat)
|
||||
(into #{}))))
|
||||
|
||||
(defn proposal-networks-intersection
|
||||
[proposal supported-networks]
|
||||
(let [proposed-networks (get-proposal-networks proposal)]
|
||||
(->> supported-networks
|
||||
(filter #(->> %
|
||||
chain-id->eip155
|
||||
(contains? proposed-networks))))))
|
||||
|
||||
(defn required-networks-supported?
|
||||
[proposal supported-networks]
|
||||
(let [required-networks (get-in proposal [:params :requiredNamespaces :eip155 :chains])
|
||||
supported-eip155 (set (map chain-id->eip155 supported-networks))]
|
||||
(every? #(contains? supported-eip155 %) required-networks)))
|
||||
|
||||
(defn get-networks-by-mode
|
||||
[db]
|
||||
(let [test-mode? (get-in db [:profile/profile :test-networks-enabled?])
|
||||
networks (get-in db [:wallet :networks (if test-mode? :test :prod)])]
|
||||
(mapv #(-> % :chain-id) networks)))
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
status-im.contexts.wallet.wallet-connect.responding-events
|
||||
[status-im.contexts.wallet.wallet-connect.utils :as wc-utils]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.ethereum.chain :as chain]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(rf/reg-event-fx
|
||||
|
@ -53,22 +52,37 @@
|
|||
(rf/reg-event-fx
|
||||
:wallet-connect/on-session-proposal
|
||||
(fn [{:keys [db]} [proposal]]
|
||||
(let [accounts (get-in db [:wallet :accounts])
|
||||
without-watched (remove :watch-only? (vals accounts))]
|
||||
(log/info "Received Wallet Connect session proposal: " {:id (:id proposal)})
|
||||
{:db (assoc db
|
||||
;; NOTE: for now using the first account, but should be using the account selected
|
||||
;; by the user on the connection screen. The default would depend on where the
|
||||
;; connection started from:
|
||||
;; - global scanner -> first account in list
|
||||
;; - wallet account dapps -> account that is selected
|
||||
:wallet-connect/current-proposal
|
||||
{:request proposal
|
||||
:address (-> without-watched
|
||||
first
|
||||
:address)})
|
||||
:fx [[:dispatch
|
||||
[:open-modal :screen/wallet.wallet-connect-session-proposal]]]})))
|
||||
(log/info "Received Wallet Connect session proposal: " {:id (:id proposal)})
|
||||
(let [accounts (get-in db [:wallet :accounts])
|
||||
without-watched (remove :watch-only? (vals accounts))
|
||||
networks (wallet-connect-core/get-networks-by-mode db)
|
||||
session-networks (wallet-connect-core/proposal-networks-intersection proposal
|
||||
networks)
|
||||
required-networks-supported? (wallet-connect-core/required-networks-supported? proposal
|
||||
networks)]
|
||||
(if required-networks-supported?
|
||||
{:db (update db
|
||||
:wallet-connect/current-proposal assoc
|
||||
:request proposal
|
||||
:session-networks session-networks
|
||||
:address (-> without-watched
|
||||
first
|
||||
:address)
|
||||
)
|
||||
:fx [[:dispatch
|
||||
[:open-modal :screen/wallet.wallet-connect-session-proposal]]]}
|
||||
{:fx [[:dispatch
|
||||
[:wallet-connect/session-networks-unsupported proposal]]]}))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/session-networks-unsupported
|
||||
(fn [_ [proposal]]
|
||||
(let [{:keys [name]} (wallet-connect-core/get-session-dapp-metadata proposal)]
|
||||
{:fx [[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type :negative
|
||||
:theme :dark
|
||||
:text (i18n/label :t/wallet-connect-networks-not-supported {:dapp name})}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-session-request
|
||||
|
@ -136,34 +150,33 @@
|
|||
(rf/reg-event-fx
|
||||
:wallet-connect/approve-session
|
||||
(fn [{:keys [db]}]
|
||||
(let [web3-wallet (get db :wallet-connect/web3-wallet)
|
||||
current-proposal-request (get-in db [:wallet-connect/current-proposal :request])
|
||||
supported-chain-ids (->> db
|
||||
chain/chain-ids
|
||||
(map wallet-connect-core/chain-id->eip155)
|
||||
vec)
|
||||
current-address (get-in db [:wallet-connect/current-proposal :address])
|
||||
accounts (-> (partial wallet-connect-core/format-eip155-address current-address)
|
||||
(map supported-chain-ids))
|
||||
supported-namespaces (clj->js {:eip155
|
||||
{:chains supported-chain-ids
|
||||
:methods constants/wallet-connect-supported-methods
|
||||
:events constants/wallet-connect-supported-events
|
||||
:accounts accounts}})]
|
||||
(let [web3-wallet (get db :wallet-connect/web3-wallet)
|
||||
current-proposal (get-in db [:wallet-connect/current-proposal :request])
|
||||
session-networks (->> (get-in db [:wallet-connect/current-proposal :session-networks])
|
||||
(map wallet-connect-core/chain-id->eip155)
|
||||
vec)
|
||||
current-address (get-in db [:wallet-connect/current-proposal :address])
|
||||
accounts (-> (partial wallet-connect-core/format-eip155-address current-address)
|
||||
(map session-networks))
|
||||
supported-namespaces (clj->js {:eip155
|
||||
{:chains session-networks
|
||||
:methods constants/wallet-connect-supported-methods
|
||||
:events constants/wallet-connect-supported-events
|
||||
:accounts accounts}})]
|
||||
{:fx [[:effects.wallet-connect/approve-session
|
||||
{:web3-wallet web3-wallet
|
||||
:proposal current-proposal-request
|
||||
:proposal current-proposal
|
||||
:supported-namespaces supported-namespaces
|
||||
:on-success (fn []
|
||||
(log/info "Wallet Connect session approved")
|
||||
(let [metadata
|
||||
(-> current-proposal-request :params :proposer :metadata)]
|
||||
(let [metadata (wallet-connect-core/get-session-dapp-metadata
|
||||
current-proposal)]
|
||||
(rf/dispatch [:wallet-connect/reset-current-session-proposal])
|
||||
(rf/dispatch [:wallet-connect/persist-session
|
||||
{:id (:id current-proposal-request)
|
||||
{:id (:id current-proposal)
|
||||
:dapp-name (:name metadata)
|
||||
:dapp-url (:url metadata)
|
||||
:session-info current-proposal-request}])))
|
||||
:session-info current-proposal}])))
|
||||
:on-fail (fn [error]
|
||||
(log/error "Wallet Connect session approval failed"
|
||||
{:error error
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
(ns status-im.contexts.wallet.wallet-connect.session-proposal.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.foundations.resources :as quo.resources]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
|
@ -45,11 +45,9 @@
|
|||
[quo/text label]])
|
||||
labels)]))
|
||||
|
||||
(defn- get-placeholder-networks
|
||||
[]
|
||||
[{:source (quo.resources/get-network :ethereum)}
|
||||
{:source (quo.resources/get-network :optimism)}
|
||||
{:source (quo.resources/get-network :arbitrum)}])
|
||||
(defn- format-network-name
|
||||
[network]
|
||||
(-> network :network-name name string/capitalize))
|
||||
|
||||
(defn- set-current-proposal-address
|
||||
[acc]
|
||||
|
@ -93,37 +91,41 @@
|
|||
|
||||
(defn- connection-category
|
||||
[]
|
||||
(let [address (rf/sub [:wallet-connect/current-proposal-address])
|
||||
{:keys
|
||||
[name
|
||||
customization-color
|
||||
emoji]} (rf/sub [:wallet-connect/account-details-by-address address])
|
||||
data-item-common-props {:blur? false
|
||||
:description :default
|
||||
:card? false
|
||||
:label :preview
|
||||
:status :default
|
||||
:size :default}
|
||||
account-data-item-props (assoc data-item-common-props
|
||||
:right-content {:type :accounts
|
||||
:size :size-32
|
||||
:data [{:emoji emoji
|
||||
:customization-color
|
||||
customization-color}]}
|
||||
:on-press show-account-switcher-bottom-sheet
|
||||
:title (i18n/label :t/account-title)
|
||||
:subtitle name
|
||||
:icon-right? true
|
||||
:right-icon :i/chevron-right
|
||||
:icon-color colors/neutral-10)
|
||||
networks-data-item-props (assoc data-item-common-props
|
||||
:right-content {:type :network
|
||||
:data
|
||||
(get-placeholder-networks)}
|
||||
:title (i18n/label :t/networks)
|
||||
;; TODO. The quo component for data-item
|
||||
;; does not support showing networks yet
|
||||
:subtitle "Networks placeholder")]
|
||||
(let [{:keys [session-networks
|
||||
all-networks-in-session?]} (rf/sub
|
||||
[:wallet-connect/session-proposal-network-details])
|
||||
address (rf/sub [:wallet-connect/current-proposal-address])
|
||||
{:keys [name customization-color emoji]} (rf/sub [:wallet-connect/account-details-by-address
|
||||
address])
|
||||
network-names (->> session-networks
|
||||
(map format-network-name)
|
||||
(string/join ", "))
|
||||
network-images (mapv :source session-networks)
|
||||
data-item-common-props {:blur? false
|
||||
:description :default
|
||||
:card? false
|
||||
:label :preview
|
||||
:status :default
|
||||
:size :large}
|
||||
account-data-item-props (assoc data-item-common-props
|
||||
:right-content {:type :accounts
|
||||
:size :size-32
|
||||
:data [{:emoji emoji
|
||||
:customization-color
|
||||
customization-color}]}
|
||||
:on-press show-account-switcher-bottom-sheet
|
||||
:title (i18n/label :t/account-title)
|
||||
:subtitle name
|
||||
:icon-right? true
|
||||
:right-icon :i/chevron-right
|
||||
:icon-color colors/neutral-10)
|
||||
networks-data-item-props (assoc data-item-common-props
|
||||
:right-content {:type :network
|
||||
:data network-images}
|
||||
:title (i18n/label :t/networks)
|
||||
:subtitle (if all-networks-in-session?
|
||||
(i18n/label :t/all-networks)
|
||||
network-names))]
|
||||
[quo/category
|
||||
{:blur? false
|
||||
:list-type :data-item
|
||||
|
|
|
@ -108,10 +108,20 @@
|
|||
:else nil)})))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/session-proposer
|
||||
:wallet-connect/current-proposal-request
|
||||
:<- [:wallet-connect/current-proposal]
|
||||
:-> :request)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/session-proposal-networks
|
||||
:<- [:wallet-connect/current-proposal]
|
||||
:-> :session-networks)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/session-proposer
|
||||
:<- [:wallet-connect/current-proposal-request]
|
||||
(fn [proposal]
|
||||
(-> proposal :request :params :proposer)))
|
||||
(-> proposal :params :proposer)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/session-proposer-name
|
||||
|
@ -119,6 +129,18 @@
|
|||
(fn [proposer]
|
||||
(-> proposer :metadata :name)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/session-proposal-network-details
|
||||
:<- [:wallet-connect/session-proposal-networks]
|
||||
:<- [:wallet/network-details]
|
||||
(fn [[session-networks network-details]]
|
||||
(let [supported-networks (map :chain-id network-details)
|
||||
session-networks (filterv #(contains? (set session-networks) (:chain-id %))
|
||||
network-details)
|
||||
all-networks-in-session? (= (count supported-networks) (count session-networks))]
|
||||
{:session-networks session-networks
|
||||
:all-networks-in-session? all-networks-in-session?})))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/current-proposal-address
|
||||
(fn [db]
|
||||
|
|
|
@ -8,38 +8,39 @@
|
|||
[utils.re-frame :as rf]))
|
||||
|
||||
(def sample-session
|
||||
{:id 1716798889093634
|
||||
:params
|
||||
{:id 1716798889093634
|
||||
:pairingTopic "9b18e1348817a548bbc97f9b4a09278f4fdf7c984e4a61ddf461bd1f57710d33"
|
||||
:expiryTimestamp 1716799189
|
||||
:requiredNamespaces {}
|
||||
:optionalNamespaces {:eip155
|
||||
{:chains ["eip155:1" "eip155:42161" "eip155:137" "eip155:43114" "eip155:56"
|
||||
"eip155:10" "eip155:100"
|
||||
"eip155:324" "eip155:7777777" "eip155:8453" "eip155:42220"
|
||||
"eip155:1313161554" "eip155:11155111" "eip155:11155420"]
|
||||
:methods ["personal_sign" "eth_accounts" "eth_requestAccounts"
|
||||
"eth_sendRawTransaction" "eth_sendTransaction"
|
||||
"eth_sign" "eth_signTransaction" "eth_signTypedData"
|
||||
"eth_signTypedData_v3" "eth_signTypedData_v4"
|
||||
"wallet_addEthereumChain" "wallet_getCallsStatus"
|
||||
"wallet_getCapabilities" "wallet_getPermissions"
|
||||
"wallet_registerOnboarding" "wallet_requestPermissions"
|
||||
"wallet_scanQRCode" "wallet_sendCalls"
|
||||
"wallet_showCallsStatus" "wallet_switchEthereumChain"
|
||||
"wallet_watchAsset"]
|
||||
:events ["chainChanged" "accountsChanged"]}}
|
||||
:relays [{:protocol "irn"}]
|
||||
:proposer {:publicKey "cddea055b8974d93380e6c7e72110145506c06524047866f8034f3db0990137a"
|
||||
:metadata {:name "Web3Modal"
|
||||
:description "Web3Modal Laboratory"
|
||||
:url "https://lab.web3modal.com"
|
||||
:icons ["https://avatars.githubusercontent.com/u/37784886"]}}}
|
||||
:verifyContext {:verified {:verifyUrl "https://verify.walletconnect.com"
|
||||
:validation "VALID"
|
||||
:origin "https://lab.web3modal.com"
|
||||
:isScam false}}})
|
||||
{:session-proposal
|
||||
{:id 1716798889093634
|
||||
:params
|
||||
{:id 1716798889093634
|
||||
:pairingTopic "9b18e1348817a548bbc97f9b4a09278f4fdf7c984e4a61ddf461bd1f57710d33"
|
||||
:expiryTimestamp 1716799189
|
||||
:requiredNamespaces {}
|
||||
:optionalNamespaces {:eip155
|
||||
{:chains ["eip155:1" "eip155:42161" "eip155:137" "eip155:43114" "eip155:56"
|
||||
"eip155:10" "eip155:100"
|
||||
"eip155:324" "eip155:7777777" "eip155:8453" "eip155:42220"
|
||||
"eip155:1313161554" "eip155:11155111" "eip155:11155420"]
|
||||
:methods ["personal_sign" "eth_accounts" "eth_requestAccounts"
|
||||
"eth_sendRawTransaction" "eth_sendTransaction"
|
||||
"eth_sign" "eth_signTransaction" "eth_signTypedData"
|
||||
"eth_signTypedData_v3" "eth_signTypedData_v4"
|
||||
"wallet_addEthereumChain" "wallet_getCallsStatus"
|
||||
"wallet_getCapabilities" "wallet_getPermissions"
|
||||
"wallet_registerOnboarding" "wallet_requestPermissions"
|
||||
"wallet_scanQRCode" "wallet_sendCalls"
|
||||
"wallet_showCallsStatus" "wallet_switchEthereumChain"
|
||||
"wallet_watchAsset"]
|
||||
:events ["chainChanged" "accountsChanged"]}}
|
||||
:relays [{:protocol "irn"}]
|
||||
:proposer {:publicKey "cddea055b8974d93380e6c7e72110145506c06524047866f8034f3db0990137a"
|
||||
:metadata {:name "Web3Modal"
|
||||
:description "Web3Modal Laboratory"
|
||||
:url "https://lab.web3modal.com"
|
||||
:icons ["https://avatars.githubusercontent.com/u/37784886"]}}}
|
||||
:verifyContext {:verified {:verifyUrl "https://verify.walletconnect.com"
|
||||
:validation "VALID"
|
||||
:origin "https://lab.web3modal.com"
|
||||
:isScam false}}}})
|
||||
|
||||
(h/deftest-sub :wallet-connect/session-proposer
|
||||
[sub-name]
|
||||
|
@ -54,6 +55,7 @@
|
|||
(-> sample-session :params :proposer :publicKey)))
|
||||
|
||||
(is (= (-> proposer :metadata :url)
|
||||
|
||||
(-> sample-session :params :proposer :metadata :url))))))
|
||||
|
||||
(h/deftest-sub :wallet-connect/session-proposer-name
|
||||
|
|
|
@ -214,6 +214,7 @@
|
|||
"airdrop-addresses": "Address for airdrops",
|
||||
"join-as": "Join as {{role}}",
|
||||
"all-addresses": "All addresses",
|
||||
"all-networks": "All networks",
|
||||
"for-airdrops": "For airdrops",
|
||||
"members-label": "Members",
|
||||
"open-membership": "Open membership",
|
||||
|
@ -2043,6 +2044,7 @@
|
|||
"wallet-connect-sign-message-warning": "Sign messages only if you trust the dApp",
|
||||
"wallet-connect-send-transaction-warning": "Send transactions only if you trust the dApp",
|
||||
"wallet-connect-sign-transaction-warning": "Sign transactions only if you trust the dApp",
|
||||
"wallet-connect-networks-not-supported": "{{dapp}} requires an unsupported network.",
|
||||
"reject": "Reject",
|
||||
"manage-connections": "Manage connections from within Application Connections",
|
||||
"contact-request-was-ignored": "Contact request ignored",
|
||||
|
|
Loading…
Reference in New Issue