Compare commits

...
Author SHA1 Message Date
Prem Chaitanya Prathi f399b7887c fix: filter bad peer removal and missing message verifier fixes 2024-12-19 16:10:52 +05:30
Mohamed Javid 0f036ca9c4 fix_: slider reset in standard authentication (#21831)
This commit fixes the slider-button doesn't reset after the completion of slider in standard authentication with keycard keypairs.

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2024-12-17 17:46:16 +05:30
flexsurfer c19128e8b1 [#21828] Close the flows for adding accounts in keycard accounts (#21829) 2024-12-16 17:49:59 +01:00
Brian Sztamfater 8d615801d1 feat_: optimize endpoint calls when fetching balances (#21802)
Signed-off-by: Brian Sztamfater <brian@status.im>
2024-12-16 12:11:09 -03:00
Mohsen 4f6e1897fe [#21135] fix: handle unsupported wallet address (#21820) 2024-12-16 17:54:16 +03:00
Ulises ManuelandShivek Khurana 93b5f8d180 Hide viewing community token requirements under a feature flag (#21814)
Co-authored-by: Shivek Khurana <khuranashivek@outlook.com>
2024-12-16 18:17:06 +05:30
Parvesh Monu 0e607dc293 fix Privacy policy button in learn more sheet open terms-of-use sheet (#21823) 2024-12-16 15:42:17 +05:30
flexsurfer 9ced0e4131 [#21708] [Android] Login with Keycard stucks on Preparing screen from time to time (#21811) 2024-12-13 19:57:26 +01:00
Sean Hagstrom 55ee800e18 feature: add keycard metric events (#21794)
This change adds some metrics events for tracking when keycard users have reached an unavailable feature, when keycard users have successfully logged in, and when keycard users have succeeded or failed to migrate to keycard.
2024-12-12 09:21:09 -08:00
29 changed files with 273 additions and 190 deletions
+1 -1
View File
@@ -66,7 +66,7 @@
"react-native-shake": "^3.3.1",
"react-native-share": "10.0.2",
"react-native-static-safe-area-insets": "^2.2.0",
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.6.3",
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.6.4",
"react-native-svg": "13.10.0",
"react-native-webview": "13.6.3",
"react-syntax-highlighter": "^15.5.0"
+4
View File
@@ -71,6 +71,10 @@
[callback]
(.addListener ^js event-emitter "keyCardOnDisconnected" callback))
(defn on-card-new-pairing
[callback]
(.addListener ^js event-emitter "keyCardNewPairing" callback))
(defn on-nfc-user-cancelled
[callback]
(.addListener ^js event-emitter "keyCardOnNFCUserCancelled" callback))
@@ -15,8 +15,7 @@
auth-method (rf/sub [:auth-method])
biometric-auth? (= auth-method constants/auth-method-biometric)
on-complete-callback (rn/use-callback
(fn [reset-slider-fn]
(js/setTimeout #(reset-slider-fn false) 500)
(fn []
(rf/dispatch [:standard-auth/authorize
{:auth-button-icon-left auth-button-icon-left
:theme theme
@@ -26,13 +25,19 @@
:on-auth-fail on-auth-fail
:auth-button-label auth-button-label}]))
(vec (conj dependencies on-auth-success on-auth-fail)))
on-complete (or on-complete on-complete-callback)
on-slider-complete (rn/use-callback
(fn [reset-slider-fn]
(js/setTimeout #(reset-slider-fn false) 500)
(if (fn? on-complete)
(on-complete)
(on-complete-callback)))
[on-complete on-complete-callback])
biometric-type (rf/sub [:biometrics/supported-type])]
[quo/slide-button
{:container-style container-style
:size size
:customization-color customization-color
:on-complete on-complete
:on-complete on-slider-complete
:track-icon (if biometric-auth?
(biometric/get-icon-by-type biometric-type)
:password)
@@ -53,7 +53,13 @@
(conj (navigation-event (name view-id)))
(= :screen/onboarding.syncing-results view-id)
(conj (key-value-event "onboarding-completed")))))
(conj (key-value-event "onboarding-completed"))
(= :screen/keycard.migrate.success view-id)
(conj (key-value-event "keycard-migration-succeeded"))
(= :screen/keycard.migrate.fail view-id)
(conj (key-value-event "keycard-migration-failed")))))
(defn navigated-to-collectibles-tab-event
[location]
@@ -10,72 +10,73 @@
[status-im.contexts.communities.actions.community-rules.view :as community-rules]
[status-im.contexts.communities.actions.permissions-sheet.view :as permissions-sheet]
[status-im.contexts.communities.utils :as communities.utils]
[status-im.feature-flags :as ff]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn view
[]
(let [theme (quo.theme/use-theme)
{id :community-id} (rf/sub [:get-screen-params])
(let [theme (quo.theme/use-theme)
{id :community-id} (rf/sub [:get-screen-params])
{:keys [name color images joined]} (rf/sub [:communities/community id])
has-permissions? (rf/sub [:communities/has-permissions? id])
airdrop-account (rf/sub [:communities/airdrop-account id])
revealed-accounts (rf/sub [:communities/accounts-to-reveal id])
revealed-accounts-count (count revealed-accounts)
wallet-accounts-count (count (rf/sub [:wallet/operable-accounts]))
addresses-shared-text (if (= revealed-accounts-count wallet-accounts-count)
(i18n/label :t/all-addresses)
(i18n/label-pluralize
revealed-accounts-count
:t/address-count))
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
highest-role-text (i18n/label (communities.utils/role->translation-key
highest-permission-role
:t/member))
can-edit-addresses? (rf/sub [:communities/can-edit-shared-addresses? id])
navigate-back (rn/use-callback #(rf/dispatch [:navigate-back]))
show-addresses-for-permissions
(rn/use-callback
(fn []
(if can-edit-addresses?
(rf/dispatch [:open-modal :addresses-for-permissions {:community-id id}])
(rf/dispatch [:show-bottom-sheet
{:community-id id
:content (fn [] [addresses-for-permissions/view])}])))
[can-edit-addresses?])
show-airdrop-addresses
(rn/use-callback
(fn []
(if can-edit-addresses?
(rf/dispatch [:open-modal :address-for-airdrop {:community-id id}])
(rf/dispatch [:show-bottom-sheet
{:community-id id
:content (fn [] [airdrop-addresses/view])}])))
[can-edit-addresses?])
confirm-choices
(rn/use-callback
(fn []
(rf/dispatch
[:standard-auth/authorize
{:auth-button-label (if can-edit-addresses?
(i18n/label :t/edit-shared-addresses)
(i18n/label :t/request-to-join))
:on-auth-success (fn [password]
(rf/dispatch
[:communities/request-to-join-with-addresses
{:community-id id
:password password}]))}])
(navigate-back))
[can-edit-addresses?])
open-permission-sheet
(rn/use-callback (fn []
(rf/dispatch [:show-bottom-sheet
{:content (fn [] [permissions-sheet/view id])}]))
[id])]
has-permissions? (rf/sub [:communities/has-permissions? id])
airdrop-account (rf/sub [:communities/airdrop-account id])
revealed-accounts (rf/sub [:communities/accounts-to-reveal id])
revealed-accounts-count (count revealed-accounts)
wallet-accounts-count (count (rf/sub [:wallet/operable-accounts]))
addresses-shared-text (if (= revealed-accounts-count wallet-accounts-count)
(i18n/label :t/all-addresses)
(i18n/label-pluralize
revealed-accounts-count
:t/address-count))
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
highest-role-text (i18n/label (communities.utils/role->translation-key
highest-permission-role
:t/member))
can-edit-addresses? (rf/sub [:communities/can-edit-shared-addresses? id])
navigate-back (rn/use-callback #(rf/dispatch [:navigate-back]))
show-addresses-for-permissions (rn/use-callback
(fn []
(if can-edit-addresses?
(rf/dispatch [:open-modal :addresses-for-permissions
{:community-id id}])
(rf/dispatch [:show-bottom-sheet
{:community-id id
:content
addresses-for-permissions/view}])))
[can-edit-addresses?])
show-airdrop-addresses (rn/use-callback
(fn []
(if can-edit-addresses?
(rf/dispatch [:open-modal :address-for-airdrop
{:community-id id}])
(rf/dispatch [:show-bottom-sheet
{:community-id id
:content airdrop-addresses/view}])))
[can-edit-addresses?])
confirm-choices (rn/use-callback
(fn []
(rf/dispatch
[:standard-auth/authorize
{:auth-button-label (if can-edit-addresses?
(i18n/label
:t/edit-shared-addresses)
(i18n/label :t/request-to-join))
:on-auth-success
(fn [password]
(rf/dispatch
[:communities/request-to-join-with-addresses
{:community-id id
:password password}]))}])
(navigate-back))
[can-edit-addresses?])
open-permission-sheet (rn/use-callback
(fn []
(rf/dispatch
[:show-bottom-sheet
{:content (fn []
[permissions-sheet/view id])}]))
[id])]
(rn/use-mount
(fn []
(rf/dispatch [:communities/initialize-permission-addresses id])))
@@ -86,7 +87,7 @@
:icon-name :i/close
:on-press navigate-back
:accessibility-label :back-button}
has-permissions?
(and has-permissions? (ff/enabled? ::ff/community.view-token-requirements))
(assoc :right-side
[{:icon-left :i/unlocked
:on-press open-permission-sheet
@@ -7,6 +7,7 @@
[status-im.constants :as constants]
[status-im.contexts.communities.actions.addresses-for-permissions.style :as style]
[status-im.contexts.communities.actions.permissions-sheet.view :as permissions-sheet]
[status-im.feature-flags :as ff]
[utils.i18n :as i18n]
[utils.money :as money]
[utils.re-frame :as rf]))
@@ -122,23 +123,23 @@
(defn- page-top
[{:keys [community-id identical-choices? can-edit-addresses?]}]
(let [{:keys [name logo color]} (rf/sub [:communities/for-context-tag community-id])
has-permissions? (rf/sub [:communities/has-permissions? community-id])
confirm-discard-changes
(rn/use-callback
(fn []
(if identical-choices?
(rf/dispatch [:dismiss-modal :addresses-for-permissions])
(rf/dispatch [:show-bottom-sheet
{:content (fn [] [confirm-discard-drawer
community-id])}])))
[identical-choices? community-id])
open-permission-sheet
(rn/use-callback (fn []
(rf/dispatch [:show-bottom-sheet
{:content (fn [] [permissions-sheet/view
community-id])}]))
[community-id])]
has-permissions? (rf/sub [:communities/has-permissions? community-id])
confirm-discard-changes (rn/use-callback
(fn []
(if identical-choices?
(rf/dispatch [:dismiss-modal :addresses-for-permissions])
(rf/dispatch [:show-bottom-sheet
{:content (fn []
[confirm-discard-drawer
community-id])}])))
[identical-choices? community-id])
open-permission-sheet (rn/use-callback
(fn []
(rf/dispatch [:show-bottom-sheet
{:content (fn []
[permissions-sheet/view
community-id])}]))
[community-id])]
[:<>
(when can-edit-addresses?
[quo/page-nav
@@ -161,7 +162,7 @@
:community-name name
:community-logo logo
:customization-color color}
has-permissions?
(and has-permissions? (ff/enabled? ::ff/community.view-token-requirements))
(assoc :button-icon :i/info
:button-type :grey
:on-button-press open-permission-sheet))])]))
@@ -40,7 +40,8 @@
:right-icon :i/chevron-right
:accessibility-label :view-token-gating
:on-press #(rf/dispatch [:show-bottom-sheet
{:content (fn [] [permissions-sheet/view id])
{:content (fn []
[permissions-sheet/view id])
:padding-bottom-override 16}])
:label (i18n/label :t/view-token-gating)})
@@ -146,7 +147,9 @@
[{:keys [id join-pending? spectated? token-gated? intro-message test-networks-enabled?]}]
(let [common [(show-qr id) (share-community id)]
specific (cond
(and token-gated? (not test-networks-enabled?))
(and token-gated?
(not test-networks-enabled?)
(ff/enabled? ::ff/community.view-token-requirements))
[(invite-contacts id) (view-token-gating id)]
token-gated?
@@ -172,7 +175,8 @@
[{:keys [id token-gated? muted? muted-till color intro-message]}]
[[(view-members id)
(view-rules id intro-message)
(when token-gated? (view-token-gating id))
(when (and token-gated? (ff/enabled? ::ff/community.view-token-requirements))
(view-token-gating id))
(when (ff/enabled? ::ff/community.edit-account-selection)
(edit-shared-addresses id))
(mark-as-read id)
@@ -30,7 +30,8 @@
{:keys [color name images]} (rf/sub [:communities/community id])
keycard? (rf/sub [:keycard/keycard-profile?])
keycard-feature-unavailable (rn/use-callback
#(rf/dispatch [:keycard/feature-unavailable-show]))]
#(rf/dispatch [:keycard/feature-unavailable-show
{:feature-name :community.request-to-join}]))]
[rn/safe-area-view {:flex 1}
[gesture/scroll-view {:style style/container}
[rn/view style/page-container
@@ -147,7 +147,8 @@
[:show-bottom-sheet {:content token-gated-communities-info}])
keycard? (rf/sub [:keycard/keycard-profile?])
keycard-feature-unavailable (rn/use-callback
#(rf/dispatch [:keycard/feature-unavailable-show]))]
#(rf/dispatch [:keycard/feature-unavailable-show
{:feature-name :community.request-to-join}]))]
(cond
networks-not-supported?
+3 -1
View File
@@ -8,7 +8,8 @@
[status-im.contexts.keycard.utils :as keycard.utils]
[status-im.contexts.profile.config :as profile.config]
[utils.hex :as hex]
[utils.re-frame :as rf]))
[utils.re-frame :as rf]
[utils.transforms :as transforms]))
(defonce ^:private active-listeners (atom []))
@@ -24,6 +25,7 @@
(reset! active-listeners
[(keycard/on-card-connected #(rf/dispatch [:keycard/on-card-connected]))
(keycard/on-card-disconnected #(rf/dispatch [:keycard/on-card-disconnected]))
(keycard/on-card-new-pairing #(rf/dispatch [:keycard/on-card-new-pairing (transforms/js->clj %)]))
(when platform/ios?
(keycard/on-nfc-user-cancelled #(rf/dispatch [:keycard.ios/on-nfc-user-cancelled])))
(when platform/ios?
+12 -13
View File
@@ -25,21 +25,22 @@
:fx [(when-let [event (get-in db [:keycard :on-card-disconnected-event-vector])]
[:dispatch event])]}))
(rf/reg-event-fx :keycard/on-card-new-pairing
(fn [{:keys [db]} [{:keys [pairing instanceUID]}]]
(when (and instanceUID pairing)
(let [pairings (get-in db [:keycard :pairings])
new-pairings (assoc pairings
instanceUID
{:pairing pairing
:paired-on (utils.datetime/timestamp)})]
{:db (assoc-in db [:keycard :pairings] new-pairings)
:keycard/persist-pairings new-pairings}))))
(rf/reg-event-fx :keycard/on-retrieve-pairings-success
(fn [{:keys [db]} [pairings]]
{:db (assoc-in db [:keycard :pairings] pairings)
:fx [[:effects.keycard/set-pairing-to-keycard pairings]]}))
(rf/reg-event-fx :keycard/update-pairings
(fn [{:keys [db]} [instance-uid pairing]]
(let [pairings (get-in db [:keycard :pairings])
new-pairings (assoc pairings
instance-uid
{:pairing pairing
:paired-on (utils.datetime/timestamp)})]
{:db (assoc-in db [:keycard :pairings] new-pairings)
:keycard/persist-pairings new-pairings})))
(rf/reg-event-fx :keycard/on-action-with-pin-error
(fn [{:keys [db]} [error]]
(let [tag-was-lost? (keycard.utils/tag-lost? (:error error))
@@ -126,10 +127,8 @@
(rf/reg-event-fx :keycard/get-application-info
(fn [_ [{:keys [key-uid on-success on-error]}]]
{:effects.keycard/get-application-info
{:on-success (fn [{:keys [instance-uid new-pairing] :as app-info}]
{:on-success (fn [app-info]
(rf/dispatch [:keycard/update-application-info app-info])
(when (and instance-uid new-pairing)
(rf/dispatch [:keycard/update-pairings instance-uid new-pairing]))
(if-let [error (keycard.utils/validate-application-info key-uid app-info)]
(if on-error
(on-error error)
@@ -1,12 +1,27 @@
(ns status-im.contexts.keycard.feature-unavailable.events
(:require
[status-im.constants :as constants]
[status-im.contexts.keycard.feature-unavailable.view :as feature-unavailable]
[utils.re-frame :as rf]))
(rf/reg-event-fx
:keycard/feature-unavailable-upvote
(fn [_ [{:keys [feature-name]}]]
{:fx [[:dispatch [:open-url constants/mobile-upvote-link]]
[:dispatch
[:centralized-metrics/track
:metric/feature-unavailable-upvote
{:feature-name feature-name}]]]}))
(rf/reg-event-fx
:keycard/feature-unavailable-show
(fn [_ [options]]
(fn [_ [{:keys [feature-name theme] :as options}]]
{:fx [[:dispatch
[:show-bottom-sheet
{:theme (:theme options)
:content feature-unavailable/view}]]]}))
{:theme theme
:content (fn []
(feature-unavailable/view options))}]]
[:dispatch
[:centralized-metrics/track
:metric/feature-unavailable
{:feature-name feature-name}]]]}))
@@ -1,16 +1,15 @@
(ns status-im.contexts.keycard.feature-unavailable.view
(:require
[quo.core :as quo]
[status-im.constants :as constants]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn on-upvote
[]
(rf/dispatch [:open-url constants/mobile-upvote-link]))
[feature-name]
(rf/dispatch [:keycard/feature-unavailable-upvote {:feature-name feature-name}]))
(defn view
[]
[{:keys [feature-name]}]
[:<>
[quo/drawer-top
{:title (i18n/label :t/feature-unavailable)
@@ -24,5 +23,5 @@
[quo/text
{:style {:text-decoration-line :underline}
:size :paragraph-2
:on-press on-upvote}
:on-press #(on-upvote feature-name)}
(i18n/label :t/upvote-it)]]]])
@@ -4,7 +4,7 @@
[quo.foundations.colors :as colors]
[quo.theme]
[react-native.core :as rn]
[status-im.common.terms.view :as terms]
[status-im.common.privacy.view :as privacy]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -26,7 +26,7 @@
[quo/text
{:size :paragraph-2
:weight :bold
:on-press #(rf/dispatch [:show-bottom-sheet {:content terms/terms-of-use :shell? true}])}
:on-press #(rf/dispatch [:show-bottom-sheet {:content privacy/privacy-statement :shell? true}])}
(i18n/label :t/more-details-in-privacy-policy-2)]]])
(defn- bullet-points
@@ -47,7 +47,8 @@
settings
{:log-level log-level}))
(assoc-in [:activity-center :loading?] true)
(dissoc :centralized-metrics/onboarding-enabled?))]
(dissoc :centralized-metrics/onboarding-enabled?))
keycard? (get-in new-db [:profile/profile :keycard-pairing])]
{:db (cond-> new-db
pairing-completed? (dissoc :syncing))
:fx (into [[:json-rpc/call
@@ -75,8 +76,10 @@
[:effects.chat/open-last-chat (:key-uid profile-overview)])
(when (:centralized-metrics/onboarding-enabled? db)
[:dispatch [:profile.settings/toggle-telemetry true]])]
[:dispatch [:profile.settings/toggle-telemetry true]])
(when keycard?
[:dispatch [:centralized-metrics/track :metric/keycard-login]])]
(cond
pairing-completed?
[[:dispatch [:update-theme-and-init-root :screen/onboarding.syncing-results]]]
@@ -10,7 +10,9 @@
[button-label theme keycard-profile?]
(fn []
(if keycard-profile?
(rf/dispatch [:keycard/feature-unavailable-show {:theme :dark}])
(rf/dispatch [:keycard/feature-unavailable-show
{:theme :dark
:feature-name :settings.enable-biometrics}])
(rf/dispatch
[:standard-auth/authorize-with-password
{:blur? true
@@ -10,7 +10,6 @@
[status-im.feature-flags :as ff]
[utils.address :as utils-address]
[utils.debounce :as debounce]
[utils.ethereum.eip.eip681 :as eip681]
[utils.i18n :as i18n]
[utils.url :as url]))
@@ -28,13 +27,6 @@
(let [index (string/index-of scanned-text "#")]
(subs scanned-text (inc index))))
(defn eip681-address?
[scanned-text]
(-> scanned-text
eip681/parse-uri
:address
boolean))
(defn pairing-qr-code?
[_]
false)
@@ -88,10 +80,10 @@
(debounce/debounce-and-dispatch [:generic-scanner/scan-success address] 300)
(debounce/debounce-and-dispatch [:shell/change-tab :wallet-stack] 300))
(eip681-address? scanned-text)
(utils-address/eip-681-address? scanned-text)
(do
(debounce/debounce-and-dispatch [:wallet-legacy/request-uri-parsed
(eip681/parse-uri scanned-text)]
(debounce/debounce-and-dispatch [:generic-scanner/scan-success
(utils-address/eip-681-address->eth-address scanned-text)]
300)
(debounce/debounce-and-dispatch [:shell/change-tab :wallet-stack] 300))
@@ -41,8 +41,10 @@
other-devices)
keycard? (rf/sub [:keycard/keycard-profile?])
keycard-feature-unavailable (rn/use-callback
#(rf/dispatch [:keycard/feature-unavailable-show
{:theme :dark}]))]
#(rf/dispatch
[:keycard/feature-unavailable-show
{:theme :dark
:feature-name :settings.setup-syncing}]))]
[quo/overlay {:type :shell :top-inset? true}
[quo/page-nav
{:type :no-title
@@ -48,7 +48,8 @@
{:icon-name :i/dapps
:on-press #(rf/dispatch
(if keycard?
[:keycard/feature-unavailable-show]
[:keycard/feature-unavailable-show
{:feature-name :wallet.show-connected-dapps}]
[:navigate-to :screen/wallet.connected-dapps]))})
(when-not sending-collectible?
{:content-type :account-switcher
@@ -13,7 +13,7 @@
{:title (i18n/label :t/scan-qr)
:subtitle (i18n/label :t/scan-an-address-qr-code)
:error-message (i18n/label :t/oops-this-qr-does-not-contain-an-address)
:validate-fn #(utils-address/supported-address? %)
:validate-fn #(utils-address/supported-scan-address? %)
:on-success-scan (fn [result]
(let [address (utils-address/supported-address->eth-address result)]
(when on-result (on-result address))
+36 -23
View File
@@ -114,7 +114,7 @@
(rf/reg-event-fx
:wallet/fetch-assets-for-address
(fn [_ [address]]
{:fx [[:dispatch [:wallet/get-wallet-token-for-account address]]
{:fx [[:dispatch [:wallet/get-wallet-token-for-accounts [address]]]
[:dispatch [:wallet/request-collectibles-for-account address]]]}))
(defn- reconcile-accounts
@@ -204,34 +204,42 @@
(rf/reg-event-fx :wallet/get-wallet-token-for-all-accounts
(fn [{:keys [db]}]
{:fx (->> (get-in db [:wallet :accounts])
vals
(mapv
(fn [{:keys [address]}]
[:dispatch [:wallet/get-wallet-token-for-account address]])))}))
(let [addresses (->> (get-in db [:wallet :accounts])
(vals)
(keep :address)
(vec))]
{:fx [[:dispatch [:wallet/get-wallet-token-for-accounts addresses]]]})))
(rf/reg-event-fx :wallet/get-wallet-token-for-account
(fn [{:keys [db]} [address]]
{:db (assoc-in db [:wallet :ui :tokens-loading address] true)
(rf/reg-event-fx :wallet/get-wallet-token-for-accounts
(fn [{:keys [db]} [addresses]]
{:db (reduce
(fn [db address]
(assoc-in db [:wallet :ui :tokens-loading address] true))
db
addresses)
:fx [[:json-rpc/call
[{:method "wallet_fetchOrGetCachedWalletBalances"
:params [[address] true]
:on-success [:wallet/store-wallet-token address]
:on-error [:wallet/get-wallet-token-for-account-failed address]}]]]}))
:params [addresses true]
:on-success [:wallet/store-wallet-token addresses]
:on-error [:wallet/get-wallet-token-for-accounts-failed addresses]}]]]}))
(rf/reg-event-fx
:wallet/get-wallet-token-for-account-failed
(fn [{:keys [db]} [address error]]
:wallet/get-wallet-token-for-accounts-failed
(fn [{:keys [db]} [addresses error]]
(log/info "failed to get wallet token "
{:error error
:event :wallet/get-wallet-token-for-account
:params address})
:event :wallet/get-wallet-token-for-accounts
:params addresses})
{:fx [[:dispatch [:wallet/get-last-wallet-token-update-if-needed]]]
:db (assoc-in db [:wallet :ui :tokens-loading address] false)}))
:db (reduce
(fn [db address]
(assoc-in db [:wallet :ui :tokens-loading address] false))
db
addresses)}))
(rf/reg-event-fx
:wallet/store-wallet-token
(fn [{:keys [db]} [address raw-tokens-data]]
(fn [{:keys [db]} [addresses raw-tokens-data]]
(let [supported-chains-by-token-symbol (get-in db [:wallet :tokens :supported-chains-by-symbol])
profile-currency (get-in db [:profile/profile :currency])
tokens (data-store/rpc->tokens raw-tokens-data
@@ -244,13 +252,18 @@
accounts))
stored-accounts
tokens-per-account))
symbols (reduce-kv (fn [acc _ v]
(into acc (map :symbol v)))
#{}
tokens)]
symbols (reduce-kv
(fn [acc _ tokens-data]
(into acc (map :symbol tokens-data)))
#{}
tokens)]
{:db (-> db
(update-in [:wallet :accounts] add-tokens tokens)
(assoc-in [:wallet :ui :tokens-loading address] false))
((fn [db]
(reduce (fn [db address]
(assoc-in db [:wallet :ui :tokens-loading address] false))
db
addresses))))
:fx [[:dispatch [:wallet/get-last-wallet-token-update-if-needed]]
[:effects.wallet.tokens/fetch-market-values
{:symbols symbols
@@ -116,20 +116,19 @@
address-2 "0x2"]
(reset! rf-db/app-db {:wallet {:accounts {address-1 {:address address-1}
address-2 {:address address-2}}}})
(is (match? [[:dispatch [:wallet/get-wallet-token-for-account address-1]]
[:dispatch [:wallet/get-wallet-token-for-account address-2]]]
(is (match? [[:dispatch [:wallet/get-wallet-token-for-accounts [address-1 address-2]]]]
(:fx (dispatch [event-id]))))))
(h/deftest-event :wallet/get-wallet-token-for-account
(h/deftest-event :wallet/get-wallet-token-for-accounts
[event-id dispatch]
(let [expected-effects {:db {:wallet {:ui {:tokens-loading {address true}}}}
:fx [[:json-rpc/call
[{:method "wallet_fetchOrGetCachedWalletBalances"
:params [[address] true]
:on-success [:wallet/store-wallet-token address]
:on-error [:wallet/get-wallet-token-for-account-failed
address]}]]]}]
(is (match? expected-effects (dispatch [event-id address])))))
:on-success [:wallet/store-wallet-token [address]]
:on-error [:wallet/get-wallet-token-for-accounts-failed
[address]]}]]]}]
(is (match? expected-effects (dispatch [event-id [address]])))))
(h/deftest-event :wallet/reconcile-keypairs
[event-id dispatch]
+18 -13
View File
@@ -15,19 +15,24 @@
(defn new-account
[]
[quo/action-drawer
[[{:icon :i/add
:accessibility-label :start-a-new-chat
:label (i18n/label :t/add-account)
:sub-label (i18n/label :t/add-account-description)
:on-press #(rf/dispatch [:navigate-to :screen/wallet.create-account])}
(when (ff/enabled? ::ff/wallet.add-watched-address)
{:icon :i/reveal
:accessibility-label :add-a-contact
:label (i18n/label :t/add-address-to-watch)
:sub-label (i18n/label :t/add-address-to-watch-description)
:on-press #(rf/dispatch [:navigate-to :screen/wallet.add-address-to-watch])
:add-divider? true})]]])
(let [keycard? (rf/sub [:keycard/keycard-profile?])]
[quo/action-drawer
[[{:icon :i/add
:accessibility-label :start-a-new-chat
:label (i18n/label :t/add-account)
:sub-label (i18n/label :t/add-account-description)
:on-press (fn []
(if keycard?
(rf/dispatch [:keycard/feature-unavailable-show
{:feature-name :wallet.new-account}])
(rf/dispatch [:navigate-to :screen/wallet.create-account])))}
(when (ff/enabled? ::ff/wallet.add-watched-address)
{:icon :i/reveal
:accessibility-label :add-a-contact
:label (i18n/label :t/add-address-to-watch)
:sub-label (i18n/label :t/add-address-to-watch-description)
:on-press #(rf/dispatch [:navigate-to :screen/wallet.add-address-to-watch])
:add-divider? true})]]]))
(defn- new-account-card-data
[]
@@ -36,7 +36,9 @@
(cond
keycard?
{:fx [[:dispatch [:keycard/feature-unavailable-show]]]}
{:fx [[:dispatch
[:keycard/feature-unavailable-show
{:feature-name :wallet.scan-dapp-connection}]]]}
(or (not valid-wc-uri?)
(not version-supported?)
+2 -2
View File
@@ -11,13 +11,13 @@
(def ^:private initial-flags
{::community.edit-account-selection (enabled-in-env? :FLAG_EDIT_ACCOUNT_SELECTION_ENABLED)
::community.view-token-requirements (enabled-in-env? :FLAG_VIEW_TOKEN_REQUIREMENTS)
;; Feature toggled (off by default) because the desktop app disabled this
;; feature and we want both clients in sync. We keep the code because it
;; works and we may re-enable it by default.
::profile-pictures-visibility (enabled-in-env? :FLAG_PROFILE_PICTURES_VISIBILITY_ENABLED)
::settings.import-all-keypairs (enabled-in-env?
:FLAG_WALLET_SETTINGS_IMPORT_ALL_KEYPAIRS)
::settings.import-all-keypairs (enabled-in-env? :FLAG_WALLET_SETTINGS_IMPORT_ALL_KEYPAIRS)
::wallet.add-watched-address (enabled-in-env? :FLAG_ADD_WATCHED_ADDRESS)
::wallet.advanced-sending (enabled-in-env? :FLAG_ADVANCED_SENDING)
::wallet.assets-modal-hide (enabled-in-env? :FLAG_ASSETS_MODAL_HIDE)
+23 -1
View File
@@ -2,7 +2,8 @@
(:require
[clojure.string :as string]
[native-module.core :as native-module]
[utils.ethereum.eip.eip55 :as eip55]))
[utils.ethereum.eip.eip55 :as eip55]
[utils.ethereum.eip.eip681 :as eip681]))
(def hex-prefix "0x")
@@ -105,11 +106,23 @@
[address]
(re-find regx-eip-3770-address address))
(defn eip-681-address?
[scanned-text]
(-> scanned-text
eip681/parse-uri
:address
boolean))
(defn supported-address?
[s]
(boolean (or (eip-3770-address? s)
(metamask-address? s))))
(defn supported-scan-address?
[s]
(boolean (or (eip-681-address? s)
(supported-address? s))))
(defn metamask-address->eip-3770-address
[metamask-address]
(when-let [[_ address metamask-network-suffix] (split-metamask-address metamask-address)]
@@ -129,9 +142,18 @@
[eip-3770-address]
(extract-address-without-chains-info eip-3770-address))
(defn eip-681-address->eth-address
[eip-681-address]
(-> eip-681-address
eip681/parse-uri
:address))
(defn supported-address->eth-address
[address]
(cond
(eip-681-address? address)
(eip-681-address->eth-address address)
(eip-3770-address? address)
(eip-3770-address->eth-address address)
+10 -6
View File
@@ -6,7 +6,7 @@
e.g. ethereum:0x1234@1/transfer?to=0x5678&value=1e18&gas=5000"
(:require
[clojure.string :as string]
[utils.address :as address]
[native-module.core :as native-module]
[utils.ens.core :as utils.ens]
[utils.ethereum.chain :as chain]))
@@ -18,6 +18,10 @@
(def parameter-separator "&")
(def key-value-separator "=")
(defn- address?
[address]
(native-module/address? address))
(def uri-pattern
(re-pattern (str scheme scheme-separator "([^" query-separator "]*)(?:\\" query-separator "(.*))?")))
(def authority-path-pattern
@@ -63,16 +67,16 @@
Invalid URI will be parsed as `nil`."
[s]
(when (string? s)
(if (address/address? s)
(if (address? s)
{:address s}
(let [[_ authority-path query] (re-find uri-pattern s)]
(when authority-path
(let [[_ raw-address chain-id function-name] (re-find authority-path-pattern authority-path)]
(when (or (or (utils.ens/is-valid-eth-name? raw-address) (address/address? raw-address))
(when (or (or (utils.ens/is-valid-eth-name? raw-address) (address? raw-address))
(when (string/starts-with? raw-address "pay-")
(let [pay-address (string/replace-first raw-address "pay-" "")]
(or (utils.ens/is-valid-eth-name? pay-address)
(address/address? pay-address)))))
(address? pay-address)))))
(let [address (if (string/starts-with? raw-address "pay-")
(string/replace-first raw-address "pay-" "")
raw-address)]
@@ -80,7 +84,7 @@
(let [contract-address (get-in arguments [:function-arguments :address])]
(if-not (or (not contract-address)
(or (utils.ens/is-valid-eth-name? contract-address)
(address/address? contract-address)))
(address? contract-address)))
nil
(merge {:address address
:chain-id (if chain-id
@@ -98,7 +102,7 @@
"Generate a EIP 681 URI based on `address` and a map (keywords / {bignumbers/strings} ) of extra properties.
No validation of address format is performed."
[address {:keys [chain-id function-name function-arguments] :as m}]
(when (address/address? address)
(when (address? address)
(let [parameters (dissoc (into {} (filter second m)) :chain-id)] ;; filter nil values
(str scheme
scheme-separator
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v7.0.0",
"commit-sha1": "84493728d9ac41553297e8084943c1429cdfe59a",
"src-sha256": "11dwdlk9svmc6f8wmya43fis9jfigvh5idxpiwmia9gkad1zal6y"
"version": "8acd48240bfeacd119bb4a41985f52be5ef00038",
"commit-sha1": "8acd48240bfeacd119bb4a41985f52be5ef00038",
"src-sha256": "0hn350bxs14gnm39dg9x588142nj7n79k313487y659yk1142ksx"
}
+2 -2
View File
@@ -9584,9 +9584,9 @@ react-native-static-safe-area-insets@^2.2.0:
resolved "https://registry.yarnpkg.com/react-native-static-safe-area-insets/-/react-native-static-safe-area-insets-2.2.0.tgz#dd86b6a38f43964fac8df8c0e6bc8e062527786c"
integrity sha512-TLTW2e2kRK3COSK8gMZzwp4wHguFCtcO18itDLn5av/xQblXt9ylu84o+qD9aKJCBfvtNzGOvqqTKqC5GJRZ/g==
"react-native-status-keycard@git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.6.3":
"react-native-status-keycard@git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.6.4":
version "2.6.2"
resolved "git+https://github.com/status-im/react-native-status-keycard.git#735bed7f9838b87712f1fd2978208186d28ea61c"
resolved "git+https://github.com/status-im/react-native-status-keycard.git#e78f46de10d65cfef2df2f62b6f41e64e0c332b9"
react-native-svg@13.10.0:
version "13.10.0"