feat(swap): add metrics for swaps (#21485)

Signed-off-by: Brian Sztamfater <brian@status.im>
This commit is contained in:
Brian Sztamfater 2024-10-29 12:01:47 -03:00 committed by GitHub
parent 4f53a2b11e
commit 6d7697870d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 169 additions and 56 deletions

View File

@ -561,7 +561,7 @@
:error error-message})) :error error-message}))
{:fx [[:dispatch {:fx [[:dispatch
(cond (cond
(and failure? swap?) [:wallet/swap-proposal-error error-message] (and failure? swap?) [:wallet/swap-proposal-error error]
failure? [:wallet/suggested-routes-error error-message] failure? [:wallet/suggested-routes-error error-message]
swap? [:wallet/swap-proposal-success (fix-routes data)] swap? [:wallet/swap-proposal-success (fix-routes data)]
:else [:wallet/suggested-routes-success (fix-routes data) :else [:wallet/suggested-routes-success (fix-routes data)

View File

@ -27,12 +27,14 @@
:test-networks-enabled? test-networks-enabled? :test-networks-enabled? test-networks-enabled?
:token-symbol (get-in data [:asset-to-pay :symbol])})) :token-symbol (get-in data [:asset-to-pay :symbol])}))
network' (or network network' (or network
(swap-utils/select-network asset-to-pay))] (swap-utils/select-network asset-to-pay))
start-point (if open-new-screen? :action-menu :swap-button)]
{:db (-> db {:db (-> db
(assoc-in [:wallet :ui :swap :asset-to-pay] asset-to-pay) (assoc-in [:wallet :ui :swap :asset-to-pay] asset-to-pay)
(assoc-in [:wallet :ui :swap :asset-to-receive] asset-to-receive) (assoc-in [:wallet :ui :swap :asset-to-receive] asset-to-receive)
(assoc-in [:wallet :ui :swap :network] network') (assoc-in [:wallet :ui :swap :network] network')
(assoc-in [:wallet :ui :swap :launch-screen] view-id)) (assoc-in [:wallet :ui :swap :launch-screen] view-id)
(assoc-in [:wallet :ui :swap :start-point] start-point))
:fx (if network' :fx (if network'
[[:dispatch [:wallet/switch-current-viewing-account (:address account)]] [[:dispatch [:wallet/switch-current-viewing-account (:address account)]]
[:dispatch [:dispatch
@ -40,6 +42,13 @@
[:open-modal :screen/wallet.setup-swap] [:open-modal :screen/wallet.setup-swap]
[:navigate-to-within-stack [:navigate-to-within-stack
[:screen/wallet.setup-swap :screen/wallet.swap-select-asset-to-pay]])] [:screen/wallet.setup-swap :screen/wallet.swap-select-asset-to-pay]])]
[:dispatch
[:centralized-metrics/track :metric/swap-start
{:network (:chain-id network)
:pay_token (:symbol asset-to-pay)
:receive_token (:symbol asset-to-receive)
:start_point start-point
:launch_screen view-id}]]
[:dispatch [:wallet.swap/set-default-slippage]]] [:dispatch [:wallet.swap/set-default-slippage]]]
[[:dispatch [[:dispatch
[:show-bottom-sheet [:show-bottom-sheet
@ -57,22 +66,36 @@
(rf/reg-event-fx :wallet.swap/select-asset-to-pay (rf/reg-event-fx :wallet.swap/select-asset-to-pay
(fn [{:keys [db]} [{:keys [token]}]] (fn [{:keys [db]} [{:keys [token]}]]
{:db (update-in db (let [previous-token (get-in db [:wallet :ui :swap :asset-to-pay])
[:wallet :ui :swap] network (get-in db [:wallet :ui :swap :network])]
#(-> % {:db (update-in db
(assoc :asset-to-pay token) [:wallet :ui :swap]
(dissoc :amount #(-> %
:amount-hex (assoc :asset-to-pay token)
:last-request-uuid (dissoc :amount
:swap-proposal :amount-hex
:error-response :last-request-uuid
:loading-swap-proposal? :swap-proposal
:approval-transaction-id :error-response
:approved-amount)))})) :loading-swap-proposal?
:approval-transaction-id
:approved-amount)))
:fx [[:dispatch
[:centralized-metrics/track :metric/swap-asset-to-pay-changed
{:network (:chain-id network)
:previous_token (:symbol previous-token)
:new_token (:symbol token)}]]]})))
(rf/reg-event-fx :wallet.swap/select-asset-to-receive (rf/reg-event-fx :wallet.swap/select-asset-to-receive
(fn [{:keys [db]} [{:keys [token]}]] (fn [{:keys [db]} [{:keys [token]}]]
{:db (assoc-in db [:wallet :ui :swap :asset-to-receive] token)})) (let [previous-token (get-in db [:wallet :ui :swap :asset-to-receive])
network (get-in db [:wallet :ui :swap :network])]
{:db (assoc-in db [:wallet :ui :swap :asset-to-receive] token)
:fx [[:dispatch
[:centralized-metrics/track :metric/swap-asset-to-receive-changed
{:network (:chain-id network)
:previous_token (:symbol previous-token)
:new_token (:symbol token)}]]]})))
(rf/reg-event-fx :wallet.swap/set-default-slippage (rf/reg-event-fx :wallet.swap/set-default-slippage
(fn [{:keys [db]}] (fn [{:keys [db]}]
@ -132,9 +155,15 @@
:last-request-uuid request-uuid :last-request-uuid request-uuid
:amount amount :amount amount
:amount-hex amount-in-hex :amount-hex amount-in-hex
:loading-swap-proposal? true) :loading-swap-proposal? true
:initial-response? true)
clean-approval-transaction? clean-approval-transaction?
(dissoc :approval-transaction-id :approved-amount :swap-proposal))) (dissoc :approval-transaction-id :approved-amount :swap-proposal)))
:fx [[:dispatch
[:centralized-metrics/track :metric/swap-proposal-start
{:network swap-chain-id
:pay_token pay-token-id
:receive_token receive-token-id}]]]
:json-rpc/call [{:method "wallet_getSuggestedRoutesAsync" :json-rpc/call [{:method "wallet_getSuggestedRoutesAsync"
:params params :params params
:on-error (fn [error] :on-error (fn [error]
@ -148,6 +177,10 @@
(fn [{:keys [db]} [swap-proposal]] (fn [{:keys [db]} [swap-proposal]]
(let [last-request-uuid (get-in db [:wallet :ui :swap :last-request-uuid]) (let [last-request-uuid (get-in db [:wallet :ui :swap :last-request-uuid])
amount-hex (get-in db [:wallet :ui :swap :amount-hex]) amount-hex (get-in db [:wallet :ui :swap :amount-hex])
asset-to-pay (get-in db [:wallet :ui :swap :asset-to-pay])
asset-to-receive (get-in db [:wallet :ui :swap :asset-to-receive])
network (get-in db [:wallet :ui :swap :network])
initial-response? (get-in db [:wallet :ui :swap :initial-response?])
view-id (:view-id db) view-id (:view-id db)
request-uuid (:uuid swap-proposal) request-uuid (:uuid swap-proposal)
best-routes (:best swap-proposal) best-routes (:best swap-proposal)
@ -163,22 +196,45 @@
:swap-proposal (when-not (empty? best-routes) :swap-proposal (when-not (empty? best-routes)
(assoc (first best-routes) :uuid request-uuid)) (assoc (first best-routes) :uuid request-uuid))
:error-response error-response :error-response error-response
:loading-swap-proposal? false)} :loading-swap-proposal? false
:initial-response? false)}
(and initial-response? (seq best-routes))
(assoc :fx
[[:dispatch
[:centralized-metrics/track :metric/swap-proposal-received
{:network (:chain-id network)
:pay_token (:symbol asset-to-pay)
:receive_token (:symbol asset-to-receive)}]]])
(and initial-response? (empty? best-routes))
(assoc :fx
[[:dispatch
[:centralized-metrics/track :metric/swap-proposal-failed
{:error (:code error-response)}]]])
;; Router is unstable and it can return a swap proposal and after auto-refetching it can ;; Router is unstable and it can return a swap proposal and after auto-refetching it can
;; return an error. Ideally this shouldn't happen, but adding this behavior so if the ;; return an error. Ideally this shouldn't happen, but adding this behavior so if the
;; user is in swap confirmation screen or in token approval confirmation screen, we ;; user is in swap confirmation screen or in token approval confirmation screen, we
;; navigate back to setup swap screen so proper error is displayed. ;; navigate back to setup swap screen so proper error is displayed.
(and (empty? best-routes) (= view-id :screen/wallet.swap-set-spending-cap)) (and (empty? best-routes) (= view-id :screen/wallet.swap-set-spending-cap))
(assoc :fx [[:dismiss-modal :screen/wallet.swap-set-spending-cap]]) (assoc :fx
[[:dispatch
[:centralized-metrics/track :metric/swap-proposal-failed
{:error (:code error-response)}]]
[:dismiss-modal :screen/wallet.swap-set-spending-cap]])
(and (empty? best-routes) (= view-id :screen/wallet.swap-confirmation)) (and (empty? best-routes) (= view-id :screen/wallet.swap-confirmation))
(assoc :fx [[:navigate-back]])))))) (assoc :fx
[[:dispatch
[:centralized-metrics/track :metric/swap-proposal-failed
{:error (:code error-response)}]]
[:navigate-back]]))))))
(rf/reg-event-fx :wallet/swap-proposal-error (rf/reg-event-fx :wallet/swap-proposal-error
(fn [{:keys [db]} [error-message]] (fn [{:keys [db]} [error-response]]
{:db (-> db {:db (-> db
(update-in [:wallet :ui :swap] dissoc :route :swap-proposal) (update-in [:wallet :ui :swap] dissoc :route :swap-proposal)
(assoc-in [:wallet :ui :swap :loading-swap-proposal?] false) (assoc-in [:wallet :ui :swap :loading-swap-proposal?] false)
(assoc-in [:wallet :ui :swap :error-response] error-message))})) (assoc-in [:wallet :ui :swap :error-response] error-response))
:fx [[:dispatch
[:centralized-metrics/track :metric/swap-proposal-failed {:error (:code error-response)}]]]}))
(rf/reg-event-fx :wallet/stop-get-swap-proposal (rf/reg-event-fx :wallet/stop-get-swap-proposal
(fn [] (fn []
@ -279,16 +335,25 @@
(-> amount-out (-> amount-out
(number/hex->whole receive-token-decimals) (number/hex->whole receive-token-decimals)
(money/to-fixed receive-token-decimals)))] (money/to-fixed receive-token-decimals)))]
(rf/dispatch [:centralized-metrics/track
(if approval-required?
:metric/swap-approval-execution-start
:metric/swap-transaction-execution-start)
(cond-> {:network swap-chain-id
:pay_token token-id-from}
(not approval-required?)
(assoc :receive_token token-id-to))])
(rf/dispatch [:wallet.swap/add-authorized-transaction (rf/dispatch [:wallet.swap/add-authorized-transaction
(cond-> {:transaction result (cond-> {:transaction result
:approval-transaction? :approval-transaction?
approval-required?} approval-required?}
(not approval-required?) (not approval-required?)
(assoc :swap-data (assoc :swap-data
{:pay-token-symbol token-id-from {:pay-token-symbol token-id-from
:pay-amount amount :pay-amount amount
:receive-token-symbol token-id-to :receive-token-symbol token-id-to
:receive-amount receive-amount}))]) :receive-amount receive-amount
:swap-chain-id swap-chain-id}))])
(rf/dispatch [:hide-bottom-sheet]) (rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:dismiss-modal (rf/dispatch [:dismiss-modal
(if approval-required? (if approval-required?
@ -308,6 +373,15 @@
:receive-amount receive-amount})}] :receive-amount receive-amount})}]
500))))) 500)))))
:on-error (fn [error] :on-error (fn [error]
(rf/dispatch [:centralized-metrics/track
(if approval-required?
:metric/swap-approval-execution-failed
:metric/swap-transaction-execution-failed)
(cond-> {:network swap-chain-id
:error error
:pay_token token-id-from}
(not approval-required?)
(assoc :receive_token token-id-to))])
(log/error "failed swap transaction" (log/error "failed swap transaction"
{:event :wallet/swap-transaction {:event :wallet/swap-transaction
:error error :error error
@ -342,19 +416,26 @@
(rf/reg-event-fx :wallet.swap/approve-transaction-update (rf/reg-event-fx :wallet.swap/approve-transaction-update
(fn [{:keys [db]} [{:keys [status]}]] (fn [{:keys [db]} [{:keys [status]}]]
(let [{:keys [amount asset-to-pay swap-proposal]} (get-in db [:wallet :ui :swap]) (let [{:keys [amount asset-to-pay swap-proposal
provider-name (:bridge-name swap-proposal) network]} (get-in db [:wallet :ui :swap])
token-symbol (:symbol asset-to-pay) provider-name (:bridge-name swap-proposal)
current-viewing-account-address (get-in db token-symbol (:symbol asset-to-pay)
[:wallet :current-viewing-account-address]) swap-chain-id (:chain-id network)
account-name (get-in db current-viewing-account-address (get-in db
[:wallet :accounts [:wallet :current-viewing-account-address])
current-viewing-account-address :name]) account-name (get-in db
transaction-confirmed-or-failed? (#{:confirmed :failed} status) [:wallet :accounts
transaction-confirmed? (= status :confirmed)] current-viewing-account-address :name])
transaction-confirmed-or-failed? (#{:confirmed :failed} status)
transaction-confirmed? (= status :confirmed)]
(when transaction-confirmed-or-failed? (when transaction-confirmed-or-failed?
(cond-> {:fx (cond-> {:fx
[[:dispatch [[:dispatch
[:centralized-metrics/track :metric/swap-approval-execution-finished
{:network swap-chain-id
:pay_token token-symbol
:succeeded transaction-confirmed?}]]
[:dispatch
[:toasts/upsert [:toasts/upsert
{:id :approve-transaction-update {:id :approve-transaction-update
:type (if transaction-confirmed? :positive :negative) :type (if transaction-confirmed? :positive :negative)
@ -377,16 +458,23 @@
(rf/reg-event-fx :wallet.swap/swap-transaction-update (rf/reg-event-fx :wallet.swap/swap-transaction-update
(fn [{:keys [db]} [{:keys [tx-hash status]}]] (fn [{:keys [db]} [{:keys [tx-hash status]}]]
(let [{:keys [pay-amount pay-token-symbol (let [{:keys [pay-amount pay-token-symbol
receive-amount receive-token-symbol]} (get-in db receive-amount receive-token-symbol
[:wallet :transactions tx-hash swap-chain-id]} (get-in db
:swap-data]) [:wallet :transactions tx-hash
transaction-confirmed-or-failed? (#{:confirmed :failed} status) :swap-data])
transaction-confirmed? (= status :confirmed)] transaction-confirmed-or-failed? (#{:confirmed :failed} status)
transaction-confirmed? (= status :confirmed)]
(when transaction-confirmed-or-failed? (when transaction-confirmed-or-failed?
{:db (-> db {:db (-> db
(update-in [:wallet :swap-transaction-ids] disj tx-hash) (update-in [:wallet :swap-transaction-ids] disj tx-hash)
(update-in [:wallet :transactions] dissoc tx-hash)) (update-in [:wallet :transactions] dissoc tx-hash))
:fx [[:dispatch :fx [[:dispatch
[:centralized-metrics/track :metric/swap-transaction-execution-finished
{:network swap-chain-id
:pay_token pay-token-symbol
:receive_token receive-token-symbol
:succeeded transaction-confirmed?}]]
[:dispatch
[:toasts/upsert [:toasts/upsert
{:id :swap-transaction-update {:id :swap-transaction-update
:type (if transaction-confirmed? :positive :negative) :type (if transaction-confirmed? :positive :negative)
@ -401,13 +489,13 @@
(rf/reg-event-fx :wallet.swap/flip-assets (rf/reg-event-fx :wallet.swap/flip-assets
(fn [{:keys [db]}] (fn [{:keys [db]}]
(let [{:keys [asset-to-pay asset-to-receive (let [{:keys [asset-to-pay asset-to-receive
swap-proposal amount]} (get-in db [:wallet :ui :swap]) swap-proposal amount network]} (get-in db [:wallet :ui :swap])
receive-token-decimals (:decimals asset-to-receive) receive-token-decimals (:decimals asset-to-receive)
amount-out (when swap-proposal (:amount-out swap-proposal)) amount-out (when swap-proposal (:amount-out swap-proposal))
receive-amount (when amount-out receive-amount (when amount-out
(-> amount-out (-> amount-out
(number/hex->whole receive-token-decimals) (number/hex->whole receive-token-decimals)
(money/to-fixed receive-token-decimals)))] (money/to-fixed receive-token-decimals)))]
{:db (update-in db {:db (update-in db
[:wallet :ui :swap] [:wallet :ui :swap]
#(-> % #(-> %
@ -420,7 +508,17 @@
:loading-swap-proposal? :loading-swap-proposal?
:last-request-uuid :last-request-uuid
:approved-amount :approved-amount
:approval-transaction-id)))}))) :approval-transaction-id)))
:fx [[:dispatch
[:centralized-metrics/track :metric/swap-asset-to-pay-changed
{:network (:chain-id network)
:previous_token (:symbol asset-to-pay)
:new_token (:symbol asset-to-receive)}]]
[:dispatch
[:centralized-metrics/track :metric/swap-asset-to-receive-changed
{:network (:chain-id network)
:previous_token (:symbol asset-to-receive)
:new_token (:symbol asset-to-pay)}]]]})))
(rf/reg-event-fx :wallet/end-swap-flow (rf/reg-event-fx :wallet/end-swap-flow
(fn [{:keys [db]}] (fn [{:keys [db]}]

View File

@ -40,6 +40,7 @@
(let [[search-text set-search-text] (rn/use-state "") (let [[search-text set-search-text] (rn/use-state "")
on-change-text #(set-search-text %) on-change-text #(set-search-text %)
on-close (fn [] on-close (fn []
(rf/dispatch [:centralized-metrics/track :metric/swap-closed])
(rf/dispatch [:wallet/clean-swap]) (rf/dispatch [:wallet/clean-swap])
(rf/dispatch [:navigate-back]))] (rf/dispatch [:navigate-back]))]
[rn/safe-area-view {:style style/container} [rn/safe-area-view {:style style/container}

View File

@ -29,7 +29,9 @@
(def ^:private default-token-symbol "ETH") (def ^:private default-token-symbol "ETH")
(defn- on-close (defn- on-close
[] [start-point]
(when (= start-point :action-menu)
(rf/dispatch [:centralized-metrics/track :metric/swap-closed]))
(rf/dispatch [:wallet/clean-swap-proposal {:clean-approval-transaction? true}]) (rf/dispatch [:wallet/clean-swap-proposal {:clean-approval-transaction? true}])
(events-helper/navigate-back)) (events-helper/navigate-back))
@ -263,16 +265,22 @@
:text error-text} :text error-text}
pay-input-error? pay-input-error?
(merge {:action? true (merge {:action? true
:on-button-press #(rf/dispatch [:show-bottom-sheet :on-button-press (fn []
{:content buy-token/view}]) (rf/dispatch [:centralized-metrics/track
:metric/swap-buy-assets])
(rf/dispatch [:show-bottom-sheet
{:content buy-token/view}]))
:button-text (i18n/label :t/add-assets)}) :button-text (i18n/label :t/add-assets)})
(= error-response-code (= error-response-code
constants/router-error-code-not-enough-native-balance) constants/router-error-code-not-enough-native-balance)
(merge {:action? true (merge {:action? true
:on-button-press #(rf/dispatch :on-button-press (fn []
[:show-bottom-sheet (rf/dispatch [:centralized-metrics/track
{:content (fn [] :metric/swap-buy-eth])
[buy-token/view])}]) (rf/dispatch
[:show-bottom-sheet
{:content (fn []
[buy-token/view])}]))
:button-text (i18n/label :t/add-eth)}))] :button-text (i18n/label :t/add-eth)}))]
(when (or pay-input-error? error-response) (when (or pay-input-error? error-response)
[quo/alert-banner props]))) [quo/alert-banner props])))
@ -337,6 +345,7 @@
asset-to-pay (rf/sub [:wallet/swap-asset-to-pay]) asset-to-pay (rf/sub [:wallet/swap-asset-to-pay])
asset-to-receive (rf/sub [:wallet/swap-asset-to-receive]) asset-to-receive (rf/sub [:wallet/swap-asset-to-receive])
network (rf/sub [:wallet/swap-network]) network (rf/sub [:wallet/swap-network])
start-point (rf/sub [:wallet/swap-start-point])
pay-input-amount (controlled-input/input-value pay-input-state) pay-input-amount (controlled-input/input-value pay-input-state)
pay-token-decimals (:decimals asset-to-pay) pay-token-decimals (:decimals asset-to-pay)
pay-token-balance-selected-chain (number/convert-to-whole-number pay-token-balance-selected-chain (number/convert-to-whole-number
@ -463,7 +472,7 @@
[asset-to-receive]) [asset-to-receive])
[rn/view {:style style/container} [rn/view {:style style/container}
[account-switcher/view [account-switcher/view
{:on-press on-close {:on-press #(on-close start-point)
:icon-name :i/arrow-left :icon-name :i/arrow-left
:margin-top (safe-area/get-top) :margin-top (safe-area/get-top)
:switcher-type :select-account :switcher-type :select-account

View File

@ -27,6 +27,11 @@
:<- [:wallet/swap] :<- [:wallet/swap]
:-> :network) :-> :network)
(rf/reg-sub
:wallet/swap-start-point
:<- [:wallet/swap]
:-> :start-point)
(rf/reg-sub (rf/reg-sub
:wallet/swap-error-response :wallet/swap-error-response
:<- [:wallet/swap] :<- [:wallet/swap]