WalletConnect no internet edge-cases (#20826)
* feat: only initialize wc if internet online * feat: no internet toast for session establishment * feat: no internet banner on session requests * feat: reloading walletconnect on connection change * fix: re-initialize only when previously failed to * fix: removed legacy net-info ns * ref: renamed :network-status to :network/status * ref: moved network subs to own "category" * fix: device network fx args * fix: tests & showing persisted dapps when offline * fix: addressed review comments * fix: rebase issues * fix: linting * fix: usage of web3-wallet (#20864) * fix: moved networks to contextx and renaming * ref: moved building supported namespaces into fx
This commit is contained in:
parent
60ad7c8a29
commit
cee21241d4
|
@ -18,7 +18,6 @@
|
|||
legacy.status-im.multiaccounts.logout.core
|
||||
[legacy.status-im.multiaccounts.model :as multiaccounts.model]
|
||||
legacy.status-im.multiaccounts.update.core
|
||||
legacy.status-im.network.net-info
|
||||
legacy.status-im.pairing.core
|
||||
legacy.status-im.profile.core
|
||||
legacy.status-im.search.core
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
(ns legacy.status-im.network.net-info
|
||||
(:require
|
||||
["@react-native-community/netinfo" :default net-info]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn change-network-status
|
||||
[{:keys [db] :as cofx} is-connected?]
|
||||
(rf/merge cofx
|
||||
{:db (assoc db :network-status (if is-connected? :online :offline))}))
|
||||
|
||||
(rf/defn change-network-type
|
||||
[{:keys [db] :as cofx} network-type expensive?]
|
||||
(rf/merge cofx
|
||||
{:db (assoc db :network/type network-type)
|
||||
:network/notify-status-go [network-type expensive?]
|
||||
:dispatch [:mobile-network/on-network-status-change]}))
|
||||
|
||||
(rf/defn handle-network-info-change
|
||||
{:events [::network-info-changed]}
|
||||
[{:keys [db] :as cofx} {:keys [isConnected type details] :as state}]
|
||||
(let [old-network-status (:network-status db)
|
||||
old-network-type (:network/type db)
|
||||
connectivity-status (if isConnected :online :offline)
|
||||
status-changed? (= connectivity-status old-network-status)
|
||||
type-changed? (= type old-network-type)]
|
||||
(log/debug "[net-info]"
|
||||
"old-network-status" old-network-status
|
||||
"old-network-type" old-network-type
|
||||
"connectivity-status" connectivity-status
|
||||
"type" type
|
||||
"details" details)
|
||||
(rf/merge cofx
|
||||
(when-not status-changed?
|
||||
(change-network-status isConnected))
|
||||
(when-not type-changed?
|
||||
(change-network-type type (:is-connection-expensive details))))))
|
||||
|
||||
(defn add-net-info-listener
|
||||
[]
|
||||
(when net-info
|
||||
(.addEventListener ^js net-info
|
||||
#(re-frame/dispatch [::network-info-changed
|
||||
(js->clj % :keywordize-keys true)]))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:network/listen-to-network-info
|
||||
(fn []
|
||||
(add-net-info-listener)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:network/notify-status-go
|
||||
(fn [[network-type expensive?]]
|
||||
(native-module/connection-change network-type expensive?)))
|
|
@ -15,8 +15,6 @@
|
|||
(reg-root-key-sub :visibility-status-updates :visibility-status-updates)
|
||||
(reg-root-key-sub :fleets/custom-fleets :custom-fleets)
|
||||
(reg-root-key-sub :ui/search :ui/search)
|
||||
(reg-root-key-sub :network/type :network/type)
|
||||
(reg-root-key-sub :network-status :network-status)
|
||||
(reg-root-key-sub :peer-stats/count :peer-stats/count)
|
||||
(reg-root-key-sub :peers-summary :peers-summary)
|
||||
(reg-root-key-sub :web3-node-version :web3-node-version)
|
||||
|
|
|
@ -127,7 +127,7 @@
|
|||
[:app-state
|
||||
:current-chat-id
|
||||
:network
|
||||
:network-status
|
||||
:network/status
|
||||
:peers-summary
|
||||
:sync-state
|
||||
:view-id
|
||||
|
|
|
@ -171,7 +171,7 @@
|
|||
#js
|
||||
{:getEnforcing {}})
|
||||
|
||||
(def net-info #js {})
|
||||
(def net-info #js {:addEventListener identity})
|
||||
(def react-native-biometrics #js {:default {}})
|
||||
(def react-native-static-safe-area-insets #js {:default {}})
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
(oops/ocall wc-utils
|
||||
"buildApprovedNamespaces"
|
||||
(bean/->js {:proposal proposal
|
||||
:supportedNamespaces supported-namespaces})))
|
||||
:supportedNamespaces (clj->js supported-namespaces)})))
|
||||
|
||||
;; Get an error from this list:
|
||||
;; https://github.com/WalletConnect/walletconnect-monorepo/blob/c6e9529418a0c81d4efcc6ac4e61f242a50b56c5/packages/utils/src/errors.ts
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
(ns status-im.contexts.networks.events
|
||||
(:require
|
||||
["@react-native-community/netinfo" :default net-info]
|
||||
[native-module.core :as native-module]
|
||||
[status-im.feature-flags :as ff]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.network/listen-to-network-info
|
||||
(fn []
|
||||
(when net-info
|
||||
(.addEventListener ^js net-info
|
||||
#(rf/dispatch [:network/on-state-change
|
||||
(js->clj % :keywordize-keys true)])))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:network/on-state-change
|
||||
(fn [{:keys [db]} [{:keys [isConnected type details]}]]
|
||||
(let [old-network-status (:network/status db)
|
||||
old-network-type (:network/type db)
|
||||
connectivity-status (if isConnected :online :offline)
|
||||
status-changed? (not= connectivity-status old-network-status)
|
||||
type-changed? (not= type old-network-type)
|
||||
is-connection-expensive? (:is-connection-expensive details)]
|
||||
(log/debug "[net-info]"
|
||||
"old-network-status" old-network-status
|
||||
"old-network-type" old-network-type
|
||||
"connectivity-status" connectivity-status
|
||||
"type" type
|
||||
"details" details)
|
||||
{:fx [(when status-changed?
|
||||
[:dispatch [:network/on-network-status-change isConnected]])
|
||||
(when type-changed?
|
||||
[:dispatch [:network/on-network-type-change type is-connection-expensive?]])]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:network/on-network-type-change
|
||||
(fn [{:keys [db]} [network-type expensive?]]
|
||||
{:db (assoc db :network/type network-type)
|
||||
:fx [[:effects.network/notify-status-go network-type expensive?]
|
||||
[:dispatch [:mobile-network/on-network-status-change]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:network/on-network-status-change
|
||||
(fn [{:keys [db]} [is-connected?]]
|
||||
(let [network-status (if is-connected? :online :offline)]
|
||||
{:db (assoc db :network/status network-status)
|
||||
:fx [(when (ff/enabled? ::ff/wallet.wallet-connect)
|
||||
[:dispatch [:wallet-connect/reload-on-network-change is-connected?]])]})))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.network/notify-status-go
|
||||
(fn [network-type expensive?]
|
||||
(native-module/connection-change network-type expensive?)))
|
|
@ -50,11 +50,15 @@
|
|||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/approve-session
|
||||
(fn [{:keys [web3-wallet proposal supported-namespaces on-success on-fail]}]
|
||||
(fn [{:keys [web3-wallet proposal networks accounts on-success on-fail]}]
|
||||
(let [{:keys [params id]} proposal
|
||||
approved-namespaces (wallet-connect/build-approved-namespaces
|
||||
params
|
||||
supported-namespaces)]
|
||||
approved-namespaces (->> {:eip155
|
||||
{:chains networks
|
||||
:accounts accounts
|
||||
:methods constants/wallet-connect-supported-methods
|
||||
:events constants/wallet-connect-supported-events}}
|
||||
(wallet-connect/build-approved-namespaces
|
||||
params))]
|
||||
(-> (wallet-connect/approve-session
|
||||
{:web3-wallet web3-wallet
|
||||
:id id
|
||||
|
|
|
@ -13,10 +13,14 @@
|
|||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/init
|
||||
(fn []
|
||||
(fn [{:keys [db]}]
|
||||
(let [network-status (:network/status db)]
|
||||
(if (= network-status :online)
|
||||
{:fx [[:effects.wallet-connect/init
|
||||
{:on-success #(rf/dispatch [:wallet-connect/on-init-success %])
|
||||
:on-fail #(rf/dispatch [:wallet-connect/on-init-fail %])}]]}))
|
||||
:on-fail #(rf/dispatch [:wallet-connect/on-init-fail %])}]]}
|
||||
;; NOTE: when offline, fetching persistent sessions only
|
||||
{:fx [[:dispatch [:wallet-connect/fetch-persisted-sessions]]]}))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-init-success
|
||||
|
@ -25,6 +29,14 @@
|
|||
:fx [[:dispatch [:wallet-connect/register-event-listeners]]
|
||||
[:dispatch [:wallet-connect/fetch-persisted-sessions]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/reload-on-network-change
|
||||
(fn [{:keys [db]} [is-connected?]]
|
||||
(let [logged-in? (-> db :profile/profile boolean)
|
||||
web3-wallet-missing? (-> db :wallet-connect/web3-wallet boolean not)]
|
||||
(when (and is-connected? logged-in? web3-wallet-missing?)
|
||||
{:fx [[:dispatch [:wallet-connect/init]]]}))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/register-event-listeners
|
||||
(fn [{:keys [db]}]
|
||||
|
@ -77,12 +89,12 @@
|
|||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/session-networks-unsupported
|
||||
(fn [_ [proposal]]
|
||||
(fn [{:keys [db]} [proposal]]
|
||||
(let [{:keys [name]} (wallet-connect-core/get-session-dapp-metadata proposal)]
|
||||
{:fx [[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type :negative
|
||||
:theme :dark
|
||||
:theme (:theme db)
|
||||
:text (i18n/label :t/wallet-connect-networks-not-supported {:dapp name})}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
|
@ -116,7 +128,9 @@
|
|||
(rf/reg-event-fx
|
||||
:wallet-connect/disconnect-dapp
|
||||
(fn [{:keys [db]} [{:keys [topic on-success on-fail]}]]
|
||||
(let [web3-wallet (get db :wallet-connect/web3-wallet)]
|
||||
(let [web3-wallet (get db :wallet-connect/web3-wallet)
|
||||
network-status (:network/status db)]
|
||||
(if (= network-status :online)
|
||||
{:fx [[:effects.wallet-connect/disconnect
|
||||
{:web3-wallet web3-wallet
|
||||
:topic topic
|
||||
|
@ -126,7 +140,8 @@
|
|||
:on-success (fn []
|
||||
(rf/dispatch [:wallet-connect/disconnect-session topic])
|
||||
(when on-success
|
||||
(on-success)))}]]})))
|
||||
(on-success)))}]]}
|
||||
{:fx [[:dispatch [:wallet-connect/no-internet-toast]]]}))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/pair
|
||||
|
@ -149,15 +164,13 @@
|
|||
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}})]
|
||||
network-status (:network/status db)]
|
||||
(if (= network-status :online)
|
||||
{:fx [[:effects.wallet-connect/approve-session
|
||||
{:web3-wallet web3-wallet
|
||||
:proposal current-proposal
|
||||
:supported-namespaces supported-namespaces
|
||||
:networks session-networks
|
||||
:accounts accounts
|
||||
:on-success (fn [approved-session]
|
||||
(log/info "Wallet Connect session approved")
|
||||
(rf/dispatch [:wallet-connect/reset-current-session-proposal])
|
||||
|
@ -168,24 +181,32 @@
|
|||
:event :wallet-connect/approve-session})
|
||||
(rf/dispatch
|
||||
[:wallet-connect/reset-current-session-proposal]))}]
|
||||
[:dispatch [:dismiss-modal :screen/wallet.wallet-connect-session-proposal]]]})))
|
||||
[:dispatch [:dismiss-modal :screen/wallet.wallet-connect-session-proposal]]]}
|
||||
{:fx [[:dispatch [:wallet-connect/no-internet-toast]]]}))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-scan-connection
|
||||
(fn [_ [scanned-text]]
|
||||
(let [parsed-uri (wallet-connect/parse-uri scanned-text)
|
||||
(fn [{:keys [db]} [scanned-text]]
|
||||
(let [network-status (:network/status db)
|
||||
parsed-uri (wallet-connect/parse-uri scanned-text)
|
||||
version (:version parsed-uri)
|
||||
valid-wc-uri? (wc-utils/valid-wc-uri? parsed-uri)
|
||||
expired? (-> parsed-uri
|
||||
:expiryTimestamp
|
||||
wc-utils/timestamp-expired?)
|
||||
version-supported? (wc-utils/version-supported? version)]
|
||||
(if (or (not valid-wc-uri?) expired? (not version-supported?))
|
||||
(if (or (not valid-wc-uri?)
|
||||
(not version-supported?)
|
||||
(= network-status :offline)
|
||||
expired?)
|
||||
{:fx [[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type :negative
|
||||
:theme :dark
|
||||
:text (cond (not valid-wc-uri?)
|
||||
:text (cond (= network-status :offline)
|
||||
(i18n/label :t/wallet-connect-no-internet-warning)
|
||||
|
||||
(not valid-wc-uri?)
|
||||
(i18n/label :t/wallet-connect-wrong-qr)
|
||||
|
||||
expired?
|
||||
|
@ -236,7 +257,8 @@
|
|||
(rf/reg-event-fx
|
||||
:wallet-connect/fetch-persisted-sessions-success
|
||||
(fn [{:keys [db]} [sessions]]
|
||||
(let [sessions' (mapv (fn [{:keys [sessionJson] :as session}]
|
||||
(let [network-status (:network/status db)
|
||||
sessions' (mapv (fn [{:keys [sessionJson] :as session}]
|
||||
(assoc session
|
||||
:accounts
|
||||
(-> sessionJson
|
||||
|
@ -245,7 +267,8 @@
|
|||
:eip155
|
||||
:accounts)))
|
||||
sessions)]
|
||||
{:fx [[:dispatch [:wallet-connect/fetch-active-sessions]]]
|
||||
{:fx [(when (= network-status :online)
|
||||
[:dispatch [:wallet-connect/fetch-active-sessions]])]
|
||||
:db (assoc db :wallet-connect/sessions sessions')})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
|
@ -256,14 +279,14 @@
|
|||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/fetch-persisted-sessions
|
||||
(fn [_ _]
|
||||
(fn [{:keys [now]} _]
|
||||
(let [current-timestamp (quot now 1000)]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wallet_getWalletConnectActiveSessions"
|
||||
;; This is the activeSince timestamp to avoid expired sessions
|
||||
;; 0 means, return everything
|
||||
:params [0]
|
||||
;; NOTE: This is the activeSince timestamp to avoid expired sessions
|
||||
:params [current-timestamp]
|
||||
:on-success [:wallet-connect/fetch-persisted-sessions-success]
|
||||
:on-error [:wallet-connect/fetch-persisted-sessions-fail]}]]]}))
|
||||
:on-error [:wallet-connect/fetch-persisted-sessions-fail]}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/persist-session
|
||||
|
@ -290,3 +313,12 @@
|
|||
:params [topic]
|
||||
:on-success #(log/info "Wallet Connect session disconnected")
|
||||
:on-error #(log/info "Wallet Connect session persistence failed" %)}]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/no-internet-toast
|
||||
(fn [{:keys [db]}]
|
||||
{:fx [[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type :negative
|
||||
:theme (:theme db)
|
||||
:text (i18n/label :t/wallet-connect-no-internet-warning)}]]]}))
|
||||
|
|
|
@ -14,9 +14,17 @@
|
|||
(rf/dispatch [:wallet-connect/respond-current-session password]))
|
||||
|
||||
(defn view
|
||||
[{:keys [warning-label slide-button-text disabled?]} & children]
|
||||
[{:keys [warning-label slide-button-text error-text]} & children]
|
||||
(let [{:keys [customization-color]} (rf/sub [:wallet-connect/current-request-account-details])
|
||||
offline? (rf/sub [:network/offline?])
|
||||
theme (quo.theme/use-theme)]
|
||||
[:<>
|
||||
(when (or offline? error-text)
|
||||
[quo/alert-banner
|
||||
{:action? false
|
||||
:text (if offline?
|
||||
(i18n/label :t/wallet-connect-no-internet-warning)
|
||||
error-text)}])
|
||||
[rn/view {:style style/content-container}
|
||||
(into [rn/view
|
||||
{:style style/data-items-container}]
|
||||
|
@ -25,7 +33,7 @@
|
|||
[standard-authentication/slide-button
|
||||
{:size :size-48
|
||||
:track-text slide-button-text
|
||||
:disabled? disabled?
|
||||
:disabled? (or offline? (seq error-text))
|
||||
:customization-color customization-color
|
||||
:on-auth-success on-auth-success
|
||||
:auth-button-label (i18n/label :t/confirm)}]]
|
||||
|
@ -36,4 +44,4 @@
|
|||
colors/white-opa-70
|
||||
colors/neutral-80-opa-70)}
|
||||
:weight :medium}
|
||||
warning-label]]]))
|
||||
warning-label]]]]))
|
||||
|
|
|
@ -33,19 +33,16 @@
|
|||
:dapp dapp
|
||||
:account account}]
|
||||
[data-block/view]]
|
||||
(when error-state
|
||||
[quo/alert-banner
|
||||
{:action? false
|
||||
:text (i18n/label (condp = error-state
|
||||
[footer/view
|
||||
{:warning-label (i18n/label :t/wallet-connect-sign-warning)
|
||||
:slide-button-text (i18n/label :t/slide-to-send)
|
||||
:error-text (when error-state
|
||||
(i18n/label (condp = error-state
|
||||
:not-enough-assets-to-pay-gas-fees
|
||||
:t/not-enough-assets-to-pay-gas-fees
|
||||
|
||||
:not-enough-assets
|
||||
:t/not-enough-assets))}])
|
||||
[footer/view
|
||||
{:warning-label (i18n/label :t/wallet-connect-sign-warning)
|
||||
:slide-button-text (i18n/label :t/slide-to-send)
|
||||
:disabled? error-state}
|
||||
:t/not-enough-assets)))}
|
||||
[quo/data-item
|
||||
{:status :default
|
||||
:card? false
|
||||
|
|
|
@ -32,19 +32,16 @@
|
|||
:dapp dapp
|
||||
:account account}]
|
||||
[data-block/view]]
|
||||
(when error-state
|
||||
[quo/alert-banner
|
||||
{:action? false
|
||||
:text (i18n/label (condp = error-state
|
||||
[footer/view
|
||||
{:warning-label (i18n/label :t/wallet-connect-sign-warning)
|
||||
:slide-button-text (i18n/label :t/slide-to-sign)
|
||||
:error-text (when error-state
|
||||
(i18n/label (condp = error-state
|
||||
:not-enough-assets-to-pay-gas-fees
|
||||
:t/not-enough-assets-to-pay-gas-fees
|
||||
|
||||
:not-enough-assets
|
||||
:t/not-enough-assets))}])
|
||||
[footer/view
|
||||
{:warning-label (i18n/label :t/wallet-connect-sign-warning)
|
||||
:slide-button-text (i18n/label :t/slide-to-sign)
|
||||
:disabled? error-state}
|
||||
:t/not-enough-assets)))}
|
||||
[quo/data-item
|
||||
{:status :default
|
||||
:card? false
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
status-im.contexts.contact.blocking.events
|
||||
status-im.contexts.keycard.effects
|
||||
status-im.contexts.keycard.events
|
||||
status-im.contexts.networks.events
|
||||
status-im.contexts.onboarding.common.overlay.events
|
||||
status-im.contexts.onboarding.events
|
||||
status-im.contexts.profile.events
|
||||
|
@ -57,7 +58,7 @@
|
|||
cofx
|
||||
{:db db/app-db
|
||||
:theme/init-theme nil
|
||||
:network/listen-to-network-info nil
|
||||
:effects.network/listen-to-network-info nil
|
||||
:effects.biometric/get-supported-type nil
|
||||
:effects.keycard/register-card-events nil
|
||||
:effects.keycard/check-nfc-enabled nil
|
||||
|
|
|
@ -151,3 +151,9 @@
|
|||
:<- [:toasts]
|
||||
(fn [toasts [_ toast-id & cursor]]
|
||||
(get-in toasts (into [:toasts toast-id] cursor))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:network/offline?
|
||||
:<- [:network/status]
|
||||
(fn [status]
|
||||
(= status :offline)))
|
||||
|
|
|
@ -44,6 +44,10 @@
|
|||
;;push notifications
|
||||
(reg-root-key-sub :push-notifications/preferences :push-notifications/preferences)
|
||||
|
||||
;;device
|
||||
(reg-root-key-sub :network/status :network/status)
|
||||
(reg-root-key-sub :network/type :network/type)
|
||||
|
||||
;;general
|
||||
(reg-root-key-sub :messenger/started? :messenger/started?)
|
||||
(reg-root-key-sub :animations :animations)
|
||||
|
|
|
@ -2632,6 +2632,7 @@
|
|||
"wallet-connect-go-back": "Go back to your browser or dapp",
|
||||
"wallet-connect-label": "WalletConnect",
|
||||
"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-description": "By connecting you allow {{name}} to retrieve your account address and enable Web3",
|
||||
"wallet-connect-proposal-title": "Would like to connect with your wallet",
|
||||
"wallet-connect-qr-expired": "WalletConnect QR has expired",
|
||||
|
|
Loading…
Reference in New Issue