🎛️ Account switcher UI for Wallet Connect sessions (#20573)
* 🎛️ Account switcher UI for Wallet Connect sessions * 😢 Remove repl workflow * 🔀 Merge current-proposal request and account * ❌ Remove redundant test * 🐛 Lint fix --------- Co-authored-by: Lungu Cristian <lungucristian95@gmail.com>
This commit is contained in:
parent
b650591e58
commit
b021b1e20a
|
@ -53,10 +53,22 @@
|
|||
(rf/reg-event-fx
|
||||
:wallet-connect/on-session-proposal
|
||||
(fn [{:keys [db]} [proposal]]
|
||||
(log/info "Received Wallet Connect session proposal: " {:id (:id proposal)})
|
||||
{:db (assoc db :wallet-connect/current-proposal proposal)
|
||||
:fx [[:dispatch
|
||||
[:open-modal :screen/wallet.wallet-connect-session-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]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-session-request
|
||||
|
@ -69,6 +81,11 @@
|
|||
(fn [{:keys [db]}]
|
||||
{:db (dissoc db :wallet-connect/current-proposal)}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/set-current-proposal-address
|
||||
(fn [{:keys [db]} [address]]
|
||||
{:db (assoc-in db [:wallet-connect/current-proposal :address] address)}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/reset-current-request
|
||||
(fn [{:keys [db]}]
|
||||
|
@ -119,39 +136,34 @@
|
|||
(rf/reg-event-fx
|
||||
:wallet-connect/approve-session
|
||||
(fn [{:keys [db]}]
|
||||
(let [web3-wallet (get db :wallet-connect/web3-wallet)
|
||||
current-proposal (get db :wallet-connect/current-proposal)
|
||||
accounts (get-in db [:wallet :accounts])
|
||||
supported-chain-ids (->> db
|
||||
chain/chain-ids
|
||||
(map wallet-connect-core/chain-id->eip155)
|
||||
vec)
|
||||
;; 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
|
||||
address (-> accounts keys first)
|
||||
accounts (-> (partial wallet-connect-core/format-eip155-address 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-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}})]
|
||||
{:fx [[:effects.wallet-connect/approve-session
|
||||
{:web3-wallet web3-wallet
|
||||
:proposal current-proposal
|
||||
:proposal current-proposal-request
|
||||
:supported-namespaces supported-namespaces
|
||||
:on-success (fn []
|
||||
(log/info "Wallet Connect session approved")
|
||||
(let [metadata (-> current-proposal :params :proposer :metadata)]
|
||||
(let [metadata
|
||||
(-> current-proposal-request :params :proposer :metadata)]
|
||||
(rf/dispatch [:wallet-connect/reset-current-session-proposal])
|
||||
(rf/dispatch [:wallet-connect/persist-session
|
||||
{:id (:id current-proposal)
|
||||
{:id (:id current-proposal-request)
|
||||
:dapp-name (:name metadata)
|
||||
:dapp-url (:url metadata)
|
||||
:session-info current-proposal}])))
|
||||
:session-info current-proposal-request}])))
|
||||
:on-fail (fn [error]
|
||||
(log/error "Wallet Connect session approval failed"
|
||||
{:error error
|
||||
|
|
|
@ -24,3 +24,10 @@
|
|||
|
||||
(def approval-li-spacer
|
||||
{:width 8})
|
||||
|
||||
(def account-switcher-title
|
||||
{:padding-horizontal 20})
|
||||
|
||||
(def account-switcher-list
|
||||
{:margin-top 8
|
||||
:padding-horizontal 8})
|
||||
|
|
|
@ -51,36 +51,79 @@
|
|||
{:source (quo.resources/get-network :optimism)}
|
||||
{:source (quo.resources/get-network :arbitrum)}])
|
||||
|
||||
(defn- set-current-proposal-address
|
||||
[acc]
|
||||
(fn []
|
||||
(rf/dispatch [:wallet-connect/set-current-proposal-address (:address acc)])
|
||||
(rf/dispatch [:hide-bottom-sheet])))
|
||||
|
||||
(defn- accounts-list
|
||||
[]
|
||||
(let [accounts (rf/sub [:wallet/accounts-without-watched-accounts])
|
||||
selected-address (rf/sub [:wallet-connect/current-proposal-address])]
|
||||
[rn/view {:style style/account-switcher-list}
|
||||
(for [account accounts]
|
||||
^{:key (-> account :address str)}
|
||||
[quo/account-item
|
||||
{:type :default
|
||||
:state (if (and selected-address
|
||||
(= (account :address)
|
||||
selected-address))
|
||||
:selected
|
||||
:default)
|
||||
:account-props account
|
||||
:on-press (set-current-proposal-address account)}])]))
|
||||
|
||||
(defn- account-switcher-sheet
|
||||
[]
|
||||
[:<>
|
||||
[rn/view {:style style/account-switcher-title}
|
||||
[quo/text
|
||||
{:size :heading-2
|
||||
:weight :semi-bold
|
||||
:accessibility-label "select-account-title"}
|
||||
(i18n/label :t/select-account)]]
|
||||
[accounts-list]])
|
||||
|
||||
(defn- show-account-switcher-bottom-sheet
|
||||
[]
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content account-switcher-sheet}]))
|
||||
|
||||
(defn- connection-category
|
||||
[]
|
||||
(let [{:keys [name emoji customization-color]} (first (rf/sub
|
||||
[:wallet/accounts-without-watched-accounts]))
|
||||
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 #(js/alert "Not yet implemented")
|
||||
: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 [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")]
|
||||
[quo/category
|
||||
{:blur? false
|
||||
:list-type :data-item
|
||||
|
|
|
@ -111,10 +111,15 @@
|
|||
:wallet-connect/session-proposer
|
||||
:<- [:wallet-connect/current-proposal]
|
||||
(fn [proposal]
|
||||
(-> proposal :params :proposer)))
|
||||
(-> proposal :request :params :proposer)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/session-proposer-name
|
||||
:<- [:wallet-connect/session-proposer]
|
||||
(fn [proposer]
|
||||
(-> proposer :metadata :name)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/current-proposal-address
|
||||
(fn [db]
|
||||
(get-in db [:wallet-connect/current-proposal :address])))
|
||||
|
|
|
@ -45,8 +45,8 @@
|
|||
[sub-name]
|
||||
(testing "Return the session proposer public key and metadata"
|
||||
(swap! rf-db/app-db
|
||||
assoc
|
||||
:wallet-connect/current-proposal
|
||||
assoc-in
|
||||
[:wallet-connect/current-proposal :request]
|
||||
sample-session)
|
||||
|
||||
(let [proposer (rf/sub [sub-name])]
|
||||
|
@ -60,9 +60,23 @@
|
|||
[sub-name]
|
||||
(testing "Return only the name of the session proposer"
|
||||
(swap! rf-db/app-db
|
||||
assoc
|
||||
:wallet-connect/current-proposal
|
||||
assoc-in
|
||||
[:wallet-connect/current-proposal :request]
|
||||
sample-session)
|
||||
|
||||
(is (= (-> sample-session :params :proposer :metadata :name)
|
||||
(rf/sub [sub-name])))))
|
||||
|
||||
(h/deftest-sub :wallet-connect/current-proposal-address
|
||||
[sub-name]
|
||||
(testing "Return the current proposal account address"
|
||||
(let [address "0x1234567890abcdef"]
|
||||
|
||||
(swap! rf-db/app-db assoc-in [:wallet-connect/current-proposal :address] address)
|
||||
|
||||
(is (= address (rf/sub [sub-name]))))
|
||||
|
||||
(testing "Return nil when there is no current proposal account"
|
||||
(swap! rf-db/app-db assoc-in [:wallet-connect/current-proposal :address] nil)
|
||||
|
||||
(is (nil? (rf/sub [sub-name]))))))
|
||||
|
|
Loading…
Reference in New Issue