Compare commits

...
Author SHA1 Message Date
Milad 2c019a1b7e fix(wallet): draft 2024-07-25 18:17:16 +02:00
Lungu Cristian cee21241d4 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
2024-07-25 11:21:31 +03:00
Icaro Motta 60ad7c8a29 chore(tests): New match-strict? cljs.test directive (#20825)
Equality checks in tests using = give a bad experience by default on test
failures containing nested data structures. We use the cljs.test directive
match? from matcher-combinators library to help compare nested structures. The
problem with match? is that its default matcher for maps (embeds) can be too
permissive, and this causes surprises.

Here we upgrade matcher-combinators to latest, where a new matcher called
nested-equals is available. This matcher won't allow extra keys in maps. This
matcher eliminates the need for manually adding nested equals matchers as we
have to do currently.

- Upgrades matcher-combinators from 3.8.8 to 3.9.1 (latest as of 2024-07-19)

What changes?

When asserting in tests, we now have the option to use match-strict? or match?.
Both directives are available by integrating with cljs.test. The code
implementing the new match-strict? directive was 100% copied from the library
matcher-combinators because we need to wrap the expected value ourselves with
matcher-combinators.matchers/nested-equals. It's ugly code, but it's how we can
integrate with cljs.test/assert-expr.
2024-07-24 23:06:41 -03:00
Mohamed Javid 4989c92780 fix_: Adding own address as saved addresses (#20839)
This commit:

- prevents the user from saving their wallet address as the saved address
- fixes button not capturing taps when the keyboard is open in saved address flows

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2024-07-24 19:46:59 +05:30
27 changed files with 418 additions and 302 deletions
+2 -1
View File
@@ -74,7 +74,8 @@
;; https://github.com/borkdude/clj-kondo/issues/867
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY
number
legacy.status-im.test-helpers/restore-app-db]}
legacy.status-im.test-helpers/restore-app-db
(cljs.test/is [match-strict?])]}
:unresolved-var {:level :error}
:unsorted-required-namespaces {:level :error}
:unused-alias {:level :warning}
+3 -3
View File
@@ -711,11 +711,11 @@
},
{
"path": "nubank/matcher-combinators/3.8.8/matcher-combinators-3.8.8",
"path": "nubank/matcher-combinators/3.9.1/matcher-combinators-3.9.1",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "4c94bd510f0c18a20191e46dd6becedebc640bbd",
"sha256": "0wpla2hx0s4mda58ndyd8938zmnz1gyhgfr6pzfphy27xfbvsssl"
"sha1": "f0830a112cae8ee931a90d9f39214a0ed4d44150",
"sha256": "1rjcgqhms84xmnhs7sqcd3b2dpa37mmzgz2yz33yz2rdb9skl96g"
}
},
+1 -1
View File
@@ -77,7 +77,7 @@ net/cgrand/macrovich/0.2.1/macrovich-0.2.1.jar
net/java/dev/jna/jna/5.12.1/jna-5.12.1.jar
nrepl/bencode/1.1.0/bencode-1.1.0.jar
nrepl/nrepl/1.0.0/nrepl-1.0.0.jar
nubank/matcher-combinators/3.8.8/matcher-combinators-3.8.8.jar
nubank/matcher-combinators/3.9.1/matcher-combinators-3.9.1.jar
org/apache/ant/ant/1.10.11/ant-1.10.11.jar
org/apache/ant/ant-launcher/1.10.11/ant-launcher-1.10.11.jar
org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.jar
+1 -1
View File
@@ -19,7 +19,7 @@
[cider/piggieback "0.4.1"]
[org.slf4j/slf4j-nop "2.0.9"]
[re-frisk-remote "1.6.0"]
[nubank/matcher-combinators "3.8.8"]
[nubank/matcher-combinators "3.9.1"]
;; Use the same version specified in the Nix dependency.
[clj-kondo/clj-kondo "2024.03.13"]
-1
View File
@@ -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?)))
-2
View File
@@ -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)
+1 -1
View File
@@ -127,7 +127,7 @@
[:app-state
:current-chat-id
:network
:network-status
:network/status
:peers-summary
:sync-state
:view-id
+1 -1
View File
@@ -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 {}})
+1 -1
View File
@@ -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?)))
@@ -7,6 +7,7 @@
[react-native.safe-area :as safe-area]
[status-im.common.floating-button-page.view :as floating-button-page]
[status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.style :as style]
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.common.validation :as validation]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
@@ -18,20 +19,21 @@
(defn- validate-input
[account-addresses saved-addresses user-input]
(cond
(string/blank? user-input)
nil
(let [[_ address-without-prefix] (utils/split-prefix-and-address user-input)]
(cond
(string/blank? user-input)
nil
(contains? saved-addresses user-input)
:existing-saved-address
(contains? saved-addresses address-without-prefix)
:existing-saved-address
(contains? account-addresses user-input)
:own-account
(contains? account-addresses address-without-prefix)
:own-account
(not
(or (validation/eth-address? user-input)
(validation/ens-name? user-input)))
:invalid-address-or-ens))
(not
(or (validation/eth-address? user-input)
(validation/ens-name? user-input)))
:invalid-address-or-ens)))
(defn- address-input
[{:keys [input-value on-change-text paste-into-input clear-input]}]
@@ -93,8 +95,9 @@
(defn- existing-saved-address
[{:keys [address]}]
(let [{:keys [name customization-color chain-short-names ens ens?]}
(rf/sub [:wallet/saved-address-by-address address])]
(let [[_ address-without-prefix] (utils/split-prefix-and-address address)
{:keys [name customization-color chain-short-names ens ens?]}
(rf/sub [:wallet/saved-address-by-address address-without-prefix])]
[rn/view {:style style/existing-saved-address-container}
[quo/text
{:size :paragraph-1
@@ -105,7 +108,7 @@
{:blur? true
:active-state? true
:user-props {:name name
:address (str chain-short-names address)
:address (str chain-short-names address-without-prefix)
:ens (when ens? ens)
:customization-color customization-color
:blur? true}
@@ -168,20 +171,21 @@
(rn/use-mount #(rf/dispatch [:wallet/clear-address-to-save]))
[quo/overlay {:type :shell}
[floating-button-page/view
{:footer-container-padding 0
:header [quo/page-nav
{:type :no-title
:icon-name :i/close
:behind-overlay? true
:on-press navigate-back
:margin-top (safe-area/get-top)
:accessibility-label :add-address-to-save-page-nav}]
:footer (when (= view-id :screen/settings.add-address-to-save)
[quo/button
{:customization-color profile-color
:disabled? button-disabled?
:on-press on-press-continue}
(i18n/label :t/continue)])}
{:footer-container-padding 0
:keyboard-should-persist-taps :handled
:header [quo/page-nav
{:type :no-title
:icon-name :i/close
:behind-overlay? true
:on-press navigate-back
:margin-top (safe-area/get-top)
:accessibility-label :add-address-to-save-page-nav}]
:footer (when (= view-id :screen/settings.add-address-to-save)
[quo/button
{:customization-color profile-color
:disabled? button-disabled?
:on-press on-press-continue}
(i18n/label :t/continue)])}
[quo/page-top
{:container-style style/header-container
:blur? true
@@ -105,24 +105,25 @@
[ens ens? open-network-preferences address-text])]
[quo/overlay {:type :shell}
[floating-button-page/view
{:footer-container-padding (if edit? (+ (safe-area/get-bottom) 12) 0)
:header [quo/page-nav
{:type :no-title
:background :blur
:icon-name (if edit? :i/close :i/arrow-left)
:on-press navigate-back
:margin-top (when-not edit? (safe-area/get-top))
:accessibility-label :save-address-page-nav}]
:footer [quo/button
{:accessibility-label :save-address-button
:type :primary
:customization-color address-color
:disabled? (string/blank? address-label)
:on-press on-press-save}
(i18n/label :t/save-address)]
:customization-color address-color
:gradient-cover? true
:shell-overlay? true}
{:footer-container-padding (if edit? (+ (safe-area/get-bottom) 12) 0)
:keyboard-should-persist-taps :handled
:header [quo/page-nav
{:type :no-title
:background :blur
:icon-name (if edit? :i/close :i/arrow-left)
:on-press navigate-back
:margin-top (when-not edit? (safe-area/get-top))
:accessibility-label :save-address-page-nav}]
:footer [quo/button
{:accessibility-label :save-address-button
:type :primary
:customization-color address-color
:disabled? (string/blank? address-label)
:on-press on-press-save}
(i18n/label :t/save-address)]
:customization-color address-color
:gradient-cover? true
:shell-overlay? true}
[quo/wallet-user-avatar
{:full-name (if (string/blank? address-label)
placeholder
@@ -1,7 +1,6 @@
(ns status-im.contexts.wallet.data-store-test
(:require
[cljs.test :refer-macros [deftest is testing]]
[matcher-combinators.matchers :as matchers]
matcher-combinators.test
[status-im.contexts.wallet.data-store :as sut]))
@@ -162,82 +161,73 @@
(deftest reconcile-keypairs-test
(testing "reconcile-keypairs represents updated key pairs and accounts"
(is
(match?
(matchers/match-with
[set? matchers/set-equals
map? matchers/equals]
{:removed-keypair-ids #{}
:removed-account-addresses #{}
:updated-accounts-by-address {"1x123" (merge account
{:key-uid "0x123"
:address "1x123"})
"1x456" (merge account
{:key-uid "0x456"
:address "1x456"
:operable? false
:operable :no})}
:updated-keypairs-by-id {"0x123" {:key-uid "0x123"
:type :seed
:lowest-operability :fully
:accounts [(merge account
{:key-uid "0x123"
:address "1x123"})]}
"0x456" {:key-uid "0x456"
:type :key
:lowest-operability :no
:accounts [(merge account
{:key-uid "0x456"
:address "1x456"
:operable? false
:operable :no})]}}})
(match-strict?
{:removed-keypair-ids #{}
:removed-account-addresses #{}
:updated-accounts-by-address {"1x123" (merge account
{:key-uid "0x123"
:address "1x123"})
"1x456" (merge account
{:key-uid "0x456"
:address "1x456"
:operable? false
:operable :no})}
:updated-keypairs-by-id {"0x123" {:key-uid "0x123"
:type :seed
:lowest-operability :fully
:accounts [(merge account
{:key-uid "0x123"
:address "1x123"})]}
"0x456" {:key-uid "0x456"
:type :key
:lowest-operability :no
:accounts [(merge account
{:key-uid "0x456"
:address "1x456"
:operable? false
:operable :no})]}}}
(sut/reconcile-keypairs [raw-keypair-seed-phrase
raw-keypair-private-key]))))
(testing "reconcile-keypairs represents removed key pairs and accounts"
(is
(match?
(matchers/match-with
[set? matchers/set-equals
map? matchers/equals]
{:removed-keypair-ids #{"0x456"}
:removed-account-addresses #{"1x456"}
:updated-accounts-by-address {"1x123" (merge account
{:key-uid "0x123"
:address "1x123"})}
:updated-keypairs-by-id {"0x123" {:key-uid "0x123"
:type :seed
:lowest-operability :fully
:accounts [(merge account
{:key-uid "0x123"
:address "1x123"})]}}})
(match-strict?
{:removed-keypair-ids #{"0x456"}
:removed-account-addresses #{"1x456"}
:updated-accounts-by-address {"1x123" (merge account
{:key-uid "0x123"
:address "1x123"})}
:updated-keypairs-by-id {"0x123" {:key-uid "0x123"
:type :seed
:lowest-operability :fully
:accounts [(merge account
{:key-uid "0x123"
:address "1x123"})]}}}
(sut/reconcile-keypairs [raw-keypair-seed-phrase
(assoc raw-keypair-private-key :removed true)]))))
(testing "reconcile-keypairs ignores chat accounts inside updated accounts"
(is
(match?
(matchers/match-with
[set? matchers/set-equals
map? matchers/equals]
{:removed-keypair-ids #{}
:removed-account-addresses #{}
:updated-accounts-by-address {"2x000" (merge account
{:key-uid "0x000"
:address "2x000"
:chat false
:wallet true
:default-account? true})}
:updated-keypairs-by-id {"0x000" {:key-uid "0x000"
:type :profile
:lowest-operability :fully
:accounts [(merge account
{:key-uid "0x000"
:address "1x000"
:chat true
:wallet false
:default-account? false})
(merge account
{:key-uid "0x000"
:address "2x000"
:chat false
:wallet true
:default-account? true})]}}})
(match-strict?
{:removed-keypair-ids #{}
:removed-account-addresses #{}
:updated-accounts-by-address {"2x000" (merge account
{:key-uid "0x000"
:address "2x000"
:chat false
:wallet true
:default-account? true})}
:updated-keypairs-by-id {"0x000" {:key-uid "0x000"
:type :profile
:lowest-operability :fully
:accounts [(merge account
{:key-uid "0x000"
:address "1x000"
:chat true
:wallet false
:default-account? false})
(merge account
{:key-uid "0x000"
:address "2x000"
:chat false
:wallet true
:default-account? true})]}}}
(sut/reconcile-keypairs [raw-keypair-profile])))))
@@ -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 []
{:fx [[:effects.wallet-connect/init
{:on-success #(rf/dispatch [:wallet-connect/on-init-success %])
:on-fail #(rf/dispatch [:wallet-connect/on-init-fail %])}]]}))
(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 %])}]]}
;; 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,17 +128,20 @@
(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)]
{:fx [[:effects.wallet-connect/disconnect
{:web3-wallet web3-wallet
:topic topic
:reason (wallet-connect/get-sdk-error
constants/wallet-connect-user-disconnected-reason-key)
:on-fail on-fail
:on-success (fn []
(rf/dispatch [:wallet-connect/disconnect-session topic])
(when on-success
(on-success)))}]]})))
(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
:reason (wallet-connect/get-sdk-error
constants/wallet-connect-user-disconnected-reason-key)
:on-fail on-fail
:on-success (fn []
(rf/dispatch [:wallet-connect/disconnect-session topic])
(when on-success
(on-success)))}]]}
{:fx [[:dispatch [:wallet-connect/no-internet-toast]]]}))))
(rf/reg-event-fx
:wallet-connect/pair
@@ -141,51 +156,57 @@
(rf/reg-event-fx
:wallet-connect/approve-session
(fn [{:keys [db]}]
(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
:supported-namespaces supported-namespaces
:on-success (fn [approved-session]
(log/info "Wallet Connect session approved")
(rf/dispatch [:wallet-connect/reset-current-session-proposal])
(rf/dispatch [:wallet-connect/persist-session approved-session]))
:on-fail (fn [error]
(log/error "Wallet Connect session approval failed"
{:error error
:event :wallet-connect/approve-session})
(rf/dispatch
[:wallet-connect/reset-current-session-proposal]))}]
[:dispatch [:dismiss-modal :screen/wallet.wallet-connect-session-proposal]]]})))
(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))
network-status (:network/status db)]
(if (= network-status :online)
{:fx [[:effects.wallet-connect/approve-session
{:web3-wallet web3-wallet
:proposal current-proposal
:networks session-networks
:accounts accounts
:on-success (fn [approved-session]
(log/info "Wallet Connect session approved")
(rf/dispatch [:wallet-connect/reset-current-session-proposal])
(rf/dispatch [:wallet-connect/persist-session approved-session]))
:on-fail (fn [error]
(log/error "Wallet Connect session approval failed"
{:error error
:event :wallet-connect/approve-session})
(rf/dispatch
[:wallet-connect/reset-current-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,16 +257,18 @@
(rf/reg-event-fx
:wallet-connect/fetch-persisted-sessions-success
(fn [{:keys [db]} [sessions]]
(let [sessions' (mapv (fn [{:keys [sessionJson] :as session}]
(assoc session
:accounts
(-> sessionJson
types/json->clj
:namespaces
:eip155
:accounts)))
sessions)]
{:fx [[:dispatch [:wallet-connect/fetch-active-sessions]]]
(let [network-status (:network/status db)
sessions' (mapv (fn [{:keys [sessionJson] :as session}]
(assoc session
:accounts
(-> sessionJson
types/json->clj
:namespaces
:eip155
:accounts)))
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 [_ _]
{:fx [[:json-rpc/call
[{:method "wallet_getWalletConnectActiveSessions"
;; This is the activeSince timestamp to avoid expired sessions
;; 0 means, return everything
:params [0]
:on-success [:wallet-connect/fetch-persisted-sessions-success]
:on-error [:wallet-connect/fetch-persisted-sessions-fail]}]]]}))
(fn [{:keys [now]} _]
(let [current-timestamp (quot now 1000)]
{:fx [[:json-rpc/call
[{:method "wallet_getWalletConnectActiveSessions"
;; 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]}]]]})))
(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,26 +14,34 @@
(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)]
[rn/view {:style style/content-container}
(into [rn/view
{:style style/data-items-container}]
children)
[rn/view {:style style/auth-container}
[standard-authentication/slide-button
{:size :size-48
:track-text slide-button-text
:disabled? disabled?
:customization-color customization-color
:on-auth-success on-auth-success
:auth-button-label (i18n/label :t/confirm)}]]
[rn/view {:style style/warning-container}
[quo/text
{:size :paragraph-2
:style {:color (if (= theme :dark)
colors/white-opa-70
colors/neutral-80-opa-70)}
:weight :medium}
warning-label]]]))
[:<>
(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}]
children)
[rn/view {:style style/auth-container}
[standard-authentication/slide-button
{:size :size-48
:track-text slide-button-text
:disabled? (or offline? (seq error-text))
:customization-color customization-color
:on-auth-success on-auth-success
:auth-button-label (i18n/label :t/confirm)}]]
[rn/view {:style style/warning-container}
[quo/text
{:size :paragraph-2
:style {:color (if (= theme :dark)
colors/white-opa-70
colors/neutral-80-opa-70)}
:weight :medium}
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
: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}
: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)))}
[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
: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}
: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)))}
[quo/data-item
{:status :default
:card? false
+2 -1
View File
@@ -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
+6
View File
@@ -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)))
+4
View File
@@ -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)
+47
View File
@@ -0,0 +1,47 @@
(ns test-helpers.matchers
"Internal use. Don't require it directly."
(:require
[cljs.test :as test]
[matcher-combinators.core :as core]
[matcher-combinators.matchers :as matchers]
[matcher-combinators.parser]
[matcher-combinators.result :as result]))
;; This implementation is identical to `match?`, but wraps the expected value
;; with `nested-equals`. This differs from the default `embeds` matcher on maps,
;; where extra map keys are considered valid.
(defmethod test/assert-expr 'match-strict?
[_ msg form]
`(let [args# (list ~@(rest form))
[matcher# actual#] args#]
(cond
(not (= 2 (count args#)))
(test/do-report
{:type :fail
:message ~msg
:expected (symbol "`match-strict?` expects 2 arguments: a `matcher` and the `actual`")
:actual (symbol (str (count args#) " were provided: " '~form))})
(core/matcher? matcher#)
(let [result# (core/match (matchers/nested-equals matcher#) actual#)]
(test/do-report
(if (core/indicates-match? result#)
{:type :pass
:message ~msg
:expected '~form
:actual (list 'match? matcher# actual#)}
(with-file+line-info
{:type :fail
:message ~msg
:expected '~form
:actual (tagged-for-pretty-printing (list '~'not (list 'match? matcher# actual#))
result#)
:markup (::result/value result#)}))))
:else
(test/do-report
{:type :fail
:message ~msg
:expected (str "The first argument of `match-strict?` "
"needs to be a matcher (implement the match protocol)")
:actual '~form}))))
+24
View File
@@ -0,0 +1,24 @@
(ns test-helpers.matchers
"Some vars in this namespace solely exist to support the matchers.clj file."
(:require-macros test-helpers.matchers)
(:require
[cljs.test :as t]
[matcher-combinators.parser]
[matcher-combinators.printer :as printer]
[matcher-combinators.result :as result]))
(defrecord Mismatch [summary match-result])
(defn tagged-for-pretty-printing
[actual-summary result]
(->Mismatch actual-summary result))
(extend-protocol IPrintWithWriter
Mismatch
(-pr-writer [this writer _]
(-write writer (printer/as-string (-> this :match-result ::result/value)))))
(defn with-file+line-info
[report]
(merge (t/file-and-line (js/Error.) 4)
report))
+4 -1
View File
@@ -12,7 +12,10 @@
[re-frame.events :as rf-events]
[re-frame.registrar :as rf-registrar]
[re-frame.subs :as rf-subs]
[taoensso.timbre :as log]))
[taoensso.timbre :as log]
;; We must require this namespace to register the custom cljs.test directive `match-strict?`.
test-helpers.matchers))
(defn db
"A simple wrapper to get the latest value from the app db."
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v0.182.37",
"commit-sha1": "4a43b2b2bebe45df2100d1a5c5034105d93e50b8",
"src-sha256": "0f5mm7lx6s2qcy9xpa9v7piqb60yazi6p677fy105yz7hg731cw6"
"version": "milad/implement-color-migration",
"commit-sha1": "7f52f8222ad11efde806c88d85c0e13103969cf0",
"src-sha256": "19h9izh8mk0lli0db803nd9gw1f9vx5n1k36n8pivr2rqnml1l16"
}
+1
View File
@@ -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",