Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f399b7887c | ||
|
|
0f036ca9c4 | ||
|
|
c19128e8b1 | ||
|
|
8d615801d1 | ||
|
|
4f6e1897fe | ||
|
|
93b5f8d180 | ||
|
|
0e607dc293 | ||
|
|
9ced0e4131 | ||
|
|
55ee800e18 |
+1
-1
@@ -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"
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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?)
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
|
||||
@@ -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,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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user