[#21335] feat: add dapp analytics

This commit is contained in:
Mohsen 2024-10-01 18:46:23 +03:00
parent 3a4b58f32f
commit ff9cbbe405
No known key found for this signature in database
GPG Key ID: 20BACCB8426033CE
10 changed files with 293 additions and 92 deletions

View File

@ -14,11 +14,18 @@
(defn centralized-metrics-interceptor
[context]
(when-let [event (tracking/tracked-event (interceptor/get-coeffect context :event))]
(log/debug "tracking event" event)
(when (push-event? (interceptor/get-coeffect context :db))
(native-module/add-centralized-metric event)))
context)
(let [rf-event (interceptor/get-coeffect context :event)
rf-db (interceptor/get-effect context :db)
metrics-event-data (get rf-db :centralized-metrics/event-data)
metrics-event (tracking/tracked-event {:rf-event rf-event
:metrics-data metrics-event-data})]
(when metrics-event
(log/info "tracking event" metrics-event)
(when (push-event? rf-db)
(native-module/add-centralized-metric metrics-event)))
(interceptor/assoc-effect context
:db
(if metrics-event (dissoc rf-db :centralized-metrics/event-data) rf-db))))
(def interceptor
(interceptor/->interceptor

View File

@ -17,8 +17,8 @@
(testing "processes context correctly"
(with-redefs [tracking/tracked-event (fn [_] {:metric "mocked-event"})
events/push-event? (fn [_] true)]
(let [context {:coeffects {:event [:some-event]
:db {:centralized-metrics/enabled? true}}}]
(let [context {:coeffects {:event [:some-event]}
:effects {:db {:centralized-metrics/enabled? true}}}]
(is (= context (events/centralized-metrics-interceptor context)))))))
(h/deftest-event :centralized-metrics/toggle-centralized-metrics

View File

@ -4,20 +4,20 @@
[react-native.platform :as platform]))
(defn key-value-event
[event-name val-key value]
[event-name event-value]
{:metric
{:eventName event-name
:platform platform/os
:appVersion build/app-short-version
:eventValue {val-key value}}})
:eventValue event-value}})
(defn user-journey-event
[action]
(key-value-event "user-journey" :action action))
(key-value-event "user-journey" {:action action}))
(defn navigation-event
[view-id]
(key-value-event "navigation" :viewId view-id))
(key-value-event "navigation" {:viewId view-id}))
(def ^:const app-started-event "app-started")
@ -51,15 +51,65 @@
(navigation-event (name view-id))))
(defn tracked-event
[[event-name second-parameter]]
(case event-name
:profile/get-profiles-overview-success
(user-journey-event app-started-event)
[{:keys [rf-event metrics-data]}]
(let [[event-name second-parameter] rf-event]
(case event-name
:profile/get-profiles-overview-success
(user-journey-event app-started-event)
:centralized-metrics/toggle-centralized-metrics
(key-value-event "events.metrics-enabled" :enabled second-parameter)
:centralized-metrics/toggle-centralized-metrics
(key-value-event "events.metrics-enabled" {:enabled second-parameter})
:set-view-id
(track-view-id-event second-parameter)
:set-view-id
(track-view-id-event second-parameter)
nil))
:wallet-connect/approve-session-success
(key-value-event "dapp-session"
(merge metrics-data
{:action :approved
:result :success}))
:wallet-connect/approve-session-fail
(key-value-event "dapp-session"
(merge metrics-data
{:action :approved
:result :fail}))
:wallet-connect/reject-session-proposal-success
(key-value-event "dapp-session"
(merge metrics-data
{:action :rejected
:result :success}))
:wallet-connect/reject-session-proposal-fail
(key-value-event "dapp-session"
(merge metrics-data
{:action :rejected
:result :fail}))
:wallet-connect/disconnect-dapp-success
(key-value-event "dapp-disconnected"
(merge metrics-data
{:result :success}))
:wallet-connect/disconnect-dapp-fail
(key-value-event "dapp-disconnected"
(merge metrics-data
{:result :fail}))
:wallet-connect/on-new-session
(key-value-event "dapp-connected" metrics-data)
:wallet-connect/respond-sign-message-success
(key-value-event "dapp-sign" (merge metrics-data {:result :success}))
:wallet-connect/on-sign-error
(key-value-event "dapp-sign" (merge metrics-data {:result :fail}))
:wallet-connect/respond-send-transaction-success
(key-value-event "dapp-send" (merge metrics-data {:result :success}))
:wallet-connect/respond-send-transaction-error
(key-value-event "dapp-send" (merge metrics-data {:result :fail}))
nil)))

View File

@ -18,7 +18,7 @@
:platform platform-os
:appVersion app-version
:eventValue {val-key value}}}]
(is (= expected (tracking/key-value-event event-name val-key value))))))
(is (= expected (tracking/key-value-event event-name {val-key value}))))))
(deftest user-journey-event-test
(testing "creates correct user journey event"
@ -63,17 +63,17 @@
:platform platform-os
:appVersion app-version
:eventValue {:action tracking/app-started-event}}}
(tracking/tracked-event [:profile/get-profiles-overview-success])))
(tracking/tracked-event {:rf-event [:profile/get-profiles-overview-success]})))
(is (= {:metric
{:eventName "events.metrics-enabled"
:platform platform-os
:appVersion app-version
:eventValue {:enabled true}}}
(tracking/tracked-event [:centralized-metrics/toggle-centralized-metrics true])))
(tracking/tracked-event {:rf-event [:centralized-metrics/toggle-centralized-metrics true]})))
(is (= {:metric
{:eventName "navigation"
:platform platform-os
:appVersion app-version
:eventValue {:viewId "wallet-stack"}}}
(tracking/tracked-event [:set-view-id :wallet-stack])))
(is (nil? (tracking/tracked-event [:unknown-event])))))
(tracking/tracked-event {:rf-event [:set-view-id :wallet-stack]})))
(is (nil? (tracking/tracked-event {:rf-event [:unknown-event]})))))

View File

@ -19,21 +19,9 @@
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch
[:wallet-connect/disconnect-dapp
{:topic topic
:on-success (fn []
(rf/dispatch [:toasts/upsert
{:id :dapp-disconnect-success
:type :positive
:text (i18n/label :t/disconnect-dapp-success
{:dapp name
:account (:name wallet-account)})}]))
:on-fail (fn []
(rf/dispatch [:toasts/upsert
{:id :dapp-disconnect-failure
:type :negative
:text (i18n/label :t/disconnect-dapp-fail
{:dapp name
:account (:name wallet-account)})}]))}]))
{:topic topic
:wallet-account wallet-account
:name name}]))
(defn- on-dapp-disconnect-press
[wallet-account dapp]

View File

@ -1,7 +1,6 @@
(ns status-im.contexts.wallet.wallet-connect.events.effects
(:require
[promesa.core :as promesa]
[re-frame.core :as rf]
[react-native.wallet-connect :as wallet-connect]
[status-im.config :as config]
[status-im.constants :as constants]
@ -10,6 +9,7 @@
[status-im.contexts.wallet.wallet-connect.utils.transactions :as transactions]
[status-im.contexts.wallet.wallet-connect.utils.typed-data :as typed-data]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.security.core :as security]))
(rf/reg-fx
@ -45,8 +45,8 @@
:effects.wallet-connect/disconnect
(fn [{:keys [web3-wallet topic on-success on-fail]}]
(-> (sessions/disconnect web3-wallet topic)
(promesa/then on-success)
(promesa/catch on-fail))))
(promesa/then (partial rf/call-continuation on-success))
(promesa/catch (partial rf/call-continuation on-fail)))))
(rf/reg-fx
:effects.wallet-connect/approve-session
@ -56,8 +56,8 @@
:proposal-request proposal-request
:address address
:session-networks session-networks})
(promesa/then on-success)
(promesa/catch on-fail))))
(promesa/then (partial rf/call-continuation on-success))
(promesa/catch (partial rf/call-continuation on-fail)))))
(rf/reg-fx
:effects.wallet-connect/sign-message
@ -72,8 +72,8 @@
(signing/eth-sign password address data)
(signing/personal-sign password address data))
(promesa/then on-success)
(promesa/catch on-error)))))
(promesa/then (partial rf/call-continuation on-success))
(promesa/catch (partial rf/call-continuation on-error))))))
(rf/reg-fx
:effects.wallet-connect/prepare-transaction
@ -103,8 +103,8 @@
tx-hash
tx-args
chain-id)
(promesa/then on-success)
(promesa/catch on-error))))
(promesa/then (partial rf/call-continuation on-success))
(promesa/catch (partial rf/call-continuation on-error)))))
(rf/reg-fx
:effects.wallet-connect/sign-typed-data
@ -114,8 +114,8 @@
data
chain-id
version)
(promesa/then on-success)
(promesa/catch on-error))))
(promesa/then (partial rf/call-continuation on-success))
(promesa/catch (partial rf/call-continuation on-error)))))
(rf/reg-fx
:effects.wallet-connect/respond-session-request
@ -139,8 +139,8 @@
{:web3-wallet web3-wallet
:id id
:reason reason})
(promesa/then on-success)
(promesa/catch on-error)))))
(promesa/then (partial rf/call-continuation on-success))
(promesa/catch (partial rf/call-continuation on-error))))))
(rf/reg-fx
:effects.wallet-connect/get-sessions

View File

@ -135,34 +135,68 @@
:proposal-request current-proposal
:session-networks session-networks
:address current-address
:on-success #(rf/dispatch [:wallet-connect/approve-session-success %])
:on-fail #(rf/dispatch [:wallet-connect/approve-session-error %])}])
:on-success (fn [approved-session]
(rf/dispatch [:wallet-connect/approve-session-success
approved-session
current-proposal]))
:on-fail (fn [error]
(rf/dispatch [:wallet-connect/approve-session-fail error
current-proposal]))}])
[:dispatch [:dismiss-modal :screen/wallet.wallet-connect-session-proposal]]]}
{:fx [[:dispatch [:wallet-connect/no-internet-toast]]]}))))
(rf/reg-event-fx :wallet-connect/approve-session-success
(fn [_ [session]]
(log/info "Wallet Connect session approved")
{:fx [[:dispatch [:wallet-connect/on-new-session session]]
[:dispatch [:wallet-connect/reset-current-session-proposal]]
[:dispatch [:wallet-connect/redirect-to-dapp (data-store/get-dapp-redirect-url session)]]]}))
(fn [{:keys [db]} [session proposal]]
(let [[dapp-name networks] (data-store/get-dapp-name-and-networks db proposal)]
(log/info "Wallet Connect session approved")
{:db (assoc db
:centralized-metrics/event-data
{:dapp_name dapp-name
:networks networks})
:fx [[:dispatch [:wallet-connect/on-new-session session]]
[:dispatch [:wallet-connect/reset-current-session-proposal]]
[:dispatch [:wallet-connect/redirect-to-dapp (data-store/get-dapp-redirect-url session)]]]})))
(rf/reg-event-fx :wallet-connect/approve-session-error
(fn [_ [error]]
(log/error "Wallet Connect session approval failed"
{:error error
:event :wallet-connect/approve-session})
{:fx [[:dispatch [:wallet-connect/reset-current-session-proposal]]]}))
(rf/reg-event-fx :wallet-connect/approve-session-fail
(fn [{:keys [db]} [error proposal]]
(let [[dapp-name networks] (data-store/get-dapp-name-and-networks db proposal)]
(log/error "Wallet Connect session approval failed"
{:error error
:event :wallet-connect/approve-session})
{:db (assoc db
:centralized-metrics/event-data
{:dapp_name dapp-name
:networks networks})
:fx [[:dispatch [:wallet-connect/reset-current-session-proposal]]]})))
(rf/reg-event-fx
:wallet-connect/reject-session-proposal
(fn [{:keys [db]} [proposal]]
(let [web3-wallet (get db :wallet-connect/web3-wallet)
{:keys [request response-sent?]} (:wallet-connect/current-proposal db)]
{:keys [request response-sent?]} (:wallet-connect/current-proposal db)
current-proposal (or proposal request)]
{:fx [(when-not response-sent?
[:effects.wallet-connect/reject-session-proposal
{:web3-wallet web3-wallet
:proposal (or proposal request)
:on-success #(log/info "Wallet Connect session proposal rejected")
:on-error #(log/error "Wallet Connect unable to reject session proposal")}])
:on-success [:wallet-connect/reject-session-proposal-success current-proposal]
:on-error [:wallet-connect/reject-session-proposal-fail current-proposal]}])
[:dispatch [:wallet-connect/reset-current-session-proposal]]]})))
(rf/reg-event-fx :wallet-connect/reject-session-proposal-success
(fn [{:keys [db]} [proposal]]
(let [[dapp-name networks] (data-store/get-dapp-name-and-networks db proposal)]
(log/info "Wallet Connect session proposal rejected")
{:db (assoc db
:centralized-metrics/event-data
{:dapp_name dapp-name
:networks networks})})))
(rf/reg-event-fx :wallet-connect/reject-session-proposal-fail
(fn [{:keys [db]} [proposal]]
(let [[dapp-name networks] (data-store/get-dapp-name-and-networks db proposal)]
(log/info "Wallet Connect unable to reject session proposal")
{:db (assoc db
:centralized-metrics/event-data
{:dapp_name dapp-name
:networks networks})})))

View File

@ -42,6 +42,16 @@
constants/wallet-connect-eth-sign-typed-v4-method
[:dispatch [:wallet-connect/respond-sign-typed-data password :v4]])]}))))
(rf/reg-event-fx :wallet-connect/respond-sign-message-success
(fn [{:keys [db]} [result]]
(let [[dapp-name networks] (data-store/get-dapp-name-and-networks db)]
(log/info "Successfully signed Wallet Connect request")
{:db (assoc db
:centralized-metrics/event-data
{:dapp_name dapp-name
:networks networks})
:fx [[:dispatch [:wallet-connect/finish-session-request result]]]})))
(rf/reg-event-fx
:wallet-connect/respond-sign-message
(fn [{:keys [db]} [password rpc-method]]
@ -51,8 +61,8 @@
:address address
:data raw-data
:rpc-method rpc-method
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
:on-success #(rf/dispatch [:wallet-connect/finish-session-request %])}]]})))
:on-error [:wallet-connect/on-sign-error]
:on-success [:wallet-connect/respond-sign-message-success]}]]})))
(rf/reg-event-fx
:wallet-connect/respond-sign-typed-data
@ -65,8 +75,32 @@
:data raw-data
:chain-id chain-id
:version typed-data-version
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
:on-success #(rf/dispatch [:wallet-connect/finish-session-request %])}]]})))
:on-error [:wallet-connect/on-sign-error]
:on-success [:wallet-connect/respond-sign-message-success]}]]})))
(rf/reg-event-fx :wallet-connect/respond-send-transaction-error
(fn [{:keys [db]}]
(let [[dapp-name networks] (data-store/get-dapp-name-and-networks db)]
(log/error "Failed to send transaction request to Wallet connect")
{:db (assoc db
:centralized-metrics/event-data
{:dapp_name dapp-name
:networks networks})
:fx [[:dispatch [:wallet-connect/dismiss-request-modal]]
[:dispatch
[:toasts/upsert
{:type :negative
:text (i18n/label :t/something-went-wrong)}]]]})))
(rf/reg-event-fx :wallet-connect/respond-send-transaction-success
(fn [{:keys [db]} [result]]
(let [[dapp-name networks] (data-store/get-dapp-name-and-networks db)]
(log/info "Successfully sent transaction request to Wallet connect")
{:db (assoc db
:centralized-metrics/event-data
{:dapp_name dapp-name
:networks networks})
:fx [[:dispatch [:wallet-connect/finish-session-request result]]]})))
(rf/reg-event-fx
:wallet-connect/respond-send-transaction-data
@ -79,8 +113,8 @@
:chain-id chain-id
:tx-hash tx-hash
:tx-args tx-args
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
:on-success #(rf/dispatch [:wallet-connect/finish-session-request %])}]]})))
:on-error [:wallet-connect/respond-send-transaction-error]
:on-success [:wallet-connect/respond-send-transaction-success]}]]})))
(rf/reg-event-fx
:wallet-connect/respond-sign-transaction-data
@ -93,14 +127,15 @@
:chain-id chain-id
:tx-hash tx-hash
:tx-params tx-args
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
:on-success #(rf/dispatch [:wallet-connect/finish-session-request %])}]]})))
:on-error [:wallet-connect/on-sign-error]
:on-success [:wallet-connect/respond-sign-message-success]}]]})))
(rf/reg-event-fx
:wallet-connect/on-sign-error
(fn [{:keys [db]} [error]]
(let [{:keys [raw-data address event]} (get db :wallet-connect/current-request)
method (data-store/get-request-method event)]
method (data-store/get-request-method event)
[dapp-name networks] (data-store/get-dapp-name-and-networks db)]
(log/error "Failed to sign Wallet Connect request"
{:error error
:address address
@ -108,7 +143,11 @@
:method method
:wallet-connect-event event
:event :wallet-connect/on-sign-error})
{:fx [[:dispatch [:wallet-connect/dismiss-request-modal]]
{:db (assoc db
:centralized-metrics/event-data
{:dapp_name dapp-name
:networks networks})
:fx [[:dispatch [:wallet-connect/dismiss-request-modal]]
[:dispatch
[:toasts/upsert
{:type :negative

View File

@ -1,5 +1,7 @@
(ns status-im.contexts.wallet.wallet-connect.events.sessions
(:require [re-frame.core :as rf]
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
data-store]
[status-im.contexts.wallet.wallet-connect.utils.networks :as networks]
[status-im.contexts.wallet.wallet-connect.utils.sessions :as sessions]
[taoensso.timbre :as log]
@ -16,9 +18,39 @@
:on-success [:wallet-connect/delete-session topic]
:on-error #(log/info "Wallet Connect session persistence failed" %)}]]]})))
(rf/reg-event-fx :wallet-connect/disconnect-dapp-success
(fn [{:keys [db]} [wallet-account topic dapp-name]]
(log/info "Wallet Connect dApp session disconnected successfully")
{:db (assoc db
:centralized-metrics/event-data
{:dapp_name dapp-name})
:fx [[:dispatch
[:toasts/upsert
{:id :dapp-disconnect-success
:type :positive
:text (i18n/label :t/disconnect-dapp-success
{:dapp dapp-name
:account (:name wallet-account)})}]]
[:dispatch [:wallet-connect/delete-session topic]]]}))
(rf/reg-event-fx :wallet-connect/disconnect-dapp-fail
(fn [{:keys [db]} [wallet-account topic dapp-name]]
(log/info "Wallet Connect dApp session disconnected failed")
{:db (assoc db
:centralized-metrics/event-data
{:dapp_name dapp-name})
:fx [[:dispatch
[:toasts/upsert
{:id :dapp-disconnect-failure
:type :negative
:text (i18n/label :t/disconnect-dapp-fail
{:dapp dapp-name
:account (:name wallet-account)})}]]
[:dispatch [:wallet-connect/disconnect-persisted-session topic]]]}))
(rf/reg-event-fx
:wallet-connect/disconnect-dapp
(fn [{:keys [db]} [{:keys [topic on-success on-fail]}]]
(fn [{:keys [db]} [{:keys [wallet-account topic name]}]]
(let [web3-wallet (get db :wallet-connect/web3-wallet)
network-status (:network/status db)]
(log/info "Disconnecting dApp session" topic)
@ -26,12 +58,8 @@
{:fx [[:effects.wallet-connect/disconnect
{:web3-wallet web3-wallet
:topic topic
:on-fail on-fail
:on-success (fn []
(log/info "Successfully disconnected dApp session" topic)
(rf/dispatch [:wallet-connect/delete-session topic])
(when on-success
(on-success)))}]]}
:on-fail [:wallet-connect/disconnect-dapp-fail wallet-account topic name]
:on-success [:wallet-connect/disconnect-dapp-success wallet-account topic name]}]]}
{:fx [[:dispatch [:wallet-connect/no-internet-toast]]]}))))
(rf/reg-event-fx
@ -71,12 +99,22 @@
(rf/reg-event-fx
:wallet-connect/on-new-session
(fn [{:keys [db]} [new-session]]
{:db (update db
:wallet-connect/sessions
(fn [sessions]
(->> new-session
sessions/sdk-session->db-session
(conj sessions))))}))
(let [[dapp-name networks] (data-store/get-dapp-name-and-networks db new-session)
total-connected-dapps (-> db
:wallet-connect/sessions
count
inc)]
{:db (-> db
(update
:wallet-connect/sessions
(fn [sessions]
(->> new-session
sessions/sdk-session->db-session
(conj sessions))))
(assoc :centralized-metrics/event-data
{:dapp_name dapp-name
:networks networks
:total_connected_dapps total-connected-dapps}))})))
(rf/reg-event-fx
:wallet-connect/delete-session

View File

@ -73,3 +73,48 @@
(-> db
get-db-current-request-event
get-request-params))
(defn- find-networks
[current-request current-proposal request db]
(cond
current-request
(get-in current-request [:params :chainId])
current-proposal
(->> (get-in db [:wallet-connect/current-proposal :session-networks])
vec
(string/join ","))
request
(->> (or (get-in request [:params :requiredNamespaces :eip155 :chains])
(get-in request [:requiredNamespaces :eip155 :chains]))
vec
(string/join ","))
:else
[]))
(defn- find-url
[current-request current-proposal request]
(cond
current-request
(get-in current-request [:verifyContext :verified :origin])
current-proposal
(get-in current-proposal [:params :proposer :metadata :url])
request
(or (get-in request [:params :proposer :metadata :url])
(get-in request [:peer :metadata :url]))
:else
nil))
(defn get-dapp-name-and-networks
[db & [request]]
(let [current-request (get-in db [:wallet-connect/current-request :event])
current-proposal (get-in db [:wallet-connect/current-proposal :request])
session-networks (find-networks current-request current-proposal request db)
dapp-url (find-url current-request current-proposal request)
dapp-name (compute-dapp-name nil dapp-url)]
[dapp-name session-networks]))