Skip to content

Commit

Permalink
Swap flows (launch from home / launch from account)
Browse files Browse the repository at this point in the history
  • Loading branch information
alwx committed Sep 19, 2024
1 parent b323d77 commit 5c725d9
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 74 deletions.
81 changes: 36 additions & 45 deletions src/status_im/contexts/wallet/common/token_value/view.cljs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
(ns status-im.contexts.wallet.common.token-value.view
(:require [quo.core :as quo]
[status-im.common.not-implemented :as not-implemented]
[status-im.contexts.wallet.send.utils :as send-utils]
[status-im.contexts.wallet.sheets.buy-token.view :as buy-token]
[status-im.feature-flags :as ff]
Expand All @@ -18,15 +17,15 @@
:right-icon :i/external})

(defn- action-send
[send-params entry-point]
[{:keys [disabled?] :as params} entry-point]
{:icon :i/send
:accessibility-label :send
:label (i18n/label :t/send)
:disabled? (:disabled? send-params)
:disabled? disabled?
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:wallet/clean-send-data])
(rf/dispatch [:wallet/set-token-to-send send-params entry-point]))})
(rf/dispatch [:wallet/set-token-to-send params entry-point]))})

(defn- action-receive
[selected-account?]
Expand All @@ -38,21 +37,24 @@
#(rf/dispatch [:open-modal :screen/share-shell {:initial-tab :wallet}]))})

(defn- action-bridge
[bridge-params]
[{:keys [bridge-disabled?] :as params}]
{:icon :i/bridge
:accessibility-label :bridge
:label (i18n/label :t/bridge)
:disabled? (:bridge-disabled? bridge-params)
:disabled? bridge-disabled?
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:wallet/bridge-select-token bridge-params]))})
(rf/dispatch [:wallet/bridge-select-token params]))})

(defn- action-swap
[]
[{:keys [token token-symbol]}]
{:icon :i/swap
:accessibility-label :swap
:label (i18n/label :t/swap)
:on-press #(not-implemented/alert)})
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:wallet.swap/start
{:asset-to-pay (or token {:symbol token-symbol})}]))})

(defn- action-manage-tokens
[watch-only?]
Expand All @@ -71,47 +73,36 @@

(defn token-value-drawer
[token watch-only? entry-point]
(let [token-symbol (:token token)
token-data (first (rf/sub [:wallet/current-viewing-account-tokens-filtered
{:query token-symbol}]))
fiat-unformatted-value (get-in token [:values :fiat-unformatted-value])
has-balance? (money/greater-than fiat-unformatted-value (money/bignumber "0"))
selected-account? (rf/sub [:wallet/current-viewing-account-address])
token-owners (rf/sub [:wallet/operable-addresses-with-token-symbol token-symbol])
send-params (if selected-account?
{:token token-data
:stack-id :screen/wallet.accounts
:disabled? (not has-balance?)
:start-flow? true
:owners token-owners}
{:token-symbol token-symbol
:stack-id :wallet-stack
:start-flow? true
:owners token-owners})
bridge-params (if selected-account?
{:token token-data
:bridge-disabled? (or (not has-balance?)
(send-utils/bridge-disabled? token-symbol))
:stack-id :screen/wallet.accounts
:start-flow? true
:owners token-owners}
{:token-symbol token-symbol
:bridge-disabled? (send-utils/bridge-disabled? token-symbol)
:stack-id :wallet-stack
:start-flow? true
:owners token-owners})]
(let [token-symbol (:token token)
token-data (first (rf/sub [:wallet/current-viewing-account-tokens-filtered
{:query token-symbol}]))
selected-account (rf/sub [:wallet/current-viewing-account-address])
token-owners (rf/sub [:wallet/operable-addresses-with-token-symbol token-symbol])
params (merge {:start-flow? true
:owners token-owners}
(if selected-account
{:token token-data
:stack-id :screen/wallet.accounts
:has-balance? (-> (get-in token [:values :fiat-unformatted-value])
(money/greater-than (money/bignumber "0")))}
{:token-symbol token-symbol
:stack-id :wallet-stack}))]
[quo/action-drawer
[(cond->> [(when (ff/enabled? ::ff/wallet.assets-modal-manage-tokens)
(action-manage-tokens watch-only?))
(when (ff/enabled? ::ff/wallet.assets-modal-hide)
(action-hide))]
(not watch-only?) (concat [(action-buy)
(when (seq token-owners)
(action-send send-params entry-point))
(action-receive selected-account?)
(when (ff/enabled? ::ff/wallet.swap) (action-swap))
(when (seq (seq token-owners))
(action-bridge bridge-params))]))]]))
(not watch-only?)
(concat [(action-buy)
(when (seq token-owners)
(action-send params entry-point))
(action-receive selected-account)
(when (ff/enabled? ::ff/wallet.swap)
(action-swap params))
(when (seq (seq token-owners))
(action-bridge (assoc params
:bridge-disabled?
(send-utils/bridge-disabled? token-symbol))))]))]]))

(defn view
[item _ _ {:keys [watch-only? entry-point]}]
Expand Down
46 changes: 31 additions & 15 deletions src/status_im/contexts/wallet/swap/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,51 @@
[utils.number :as number]))

(rf/reg-event-fx :wallet.swap/start
(fn [{:keys [db]} [{:keys [asset-to-pay asset-to-receive network]}]]
(let [asset-to-receive' (or asset-to-receive
(swap-utils/select-asset-to-receive
(:wallet db)
(:profile/profile db)
asset-to-pay))
network' (or network
(swap-utils/select-network asset-to-pay))]
(fn [{:keys [db]} [{:keys [asset-to-pay asset-to-receive network navigate-within-stack?]}]]
(let [{:keys [wallet]} db
test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?])
account (swap-utils/wallet-account wallet)
asset-to-pay' (if (:networks asset-to-pay)
asset-to-pay
(swap-utils/select-asset-to-pay-by-symbol
{:wallet wallet
:account account
:test-networks-enabled? test-networks-enabled?
:token-symbol (:symbol asset-to-pay)}))
asset-to-receive' (or asset-to-receive
(swap-utils/select-default-asset-to-receive
{:wallet wallet
:account account
:test-networks-enabled? test-networks-enabled?
:asset-to-pay asset-to-pay'}))
network' (or network
(swap-utils/select-network asset-to-pay'))]
{: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 :network] network'))
:fx (if network'
[[:dispatch
[:navigate-to-within-stack
[:screen/wallet.setup-swap :screen/wallet.swap-select-asset-to-pay]]]
[[:dispatch [:wallet/switch-current-viewing-account (:address account)]]
[:dispatch
(if navigate-within-stack?
[:navigate-to-within-stack
[:screen/wallet.setup-swap :screen/wallet.swap-select-asset-to-pay]]
[:navigate-to :screen/wallet.setup-swap])]
[:dispatch [:wallet.swap/set-default-slippage]]]
[[:dispatch
[:show-bottom-sheet
{:content (fn []
[network-selection/view
{:token-symbol (:symbol asset-to-pay)
{:token-symbol (:symbol asset-to-pay')
:on-select-network (fn [network]
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch
[:wallet.swap/start
{:asset-to-pay asset-to-pay
{:asset-to-pay asset-to-pay'
:asset-to-receive asset-to-receive'
:network network}]))}])}]]])})))
:network network
:navigate-within-stack?
navigate-within-stack?}]))}])}]]])})))

(rf/reg-event-fx :wallet.swap/select-asset-to-pay
(fn [{:keys [db]} [{:keys [token]}]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
(defn- assets-view
[search-text on-change-text]
(let [on-token-press (fn [token]
(rf/dispatch [:wallet.swap/start {:asset-to-pay token}]))]
(rf/dispatch [:wallet.swap/start
{:asset-to-pay token
:navigate-within-stack? true}]))]
[:<>
[search-input search-text on-change-text]
[asset-list/view
Expand Down
66 changes: 53 additions & 13 deletions src/status_im/contexts/wallet/swap/utils.cljs
Original file line number Diff line number Diff line change
@@ -1,24 +1,64 @@
(ns status-im.contexts.wallet.swap.utils
(:require
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.common.utils.networks :as network-utils]))
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.common.utils.networks :as network-utils]))

(defn select-asset-to-receive
[wallet profile asset-to-pay]
(let [wallet-address (get-in wallet [:current-viewing-account-address])
account (-> wallet
:accounts
vals
(utils/get-account-by-address wallet-address))
test-networks-enabled? (get profile :test-networks-enabled?)
networks (-> (get-in wallet
[:wallet :networks (if test-networks-enabled? :test :prod)])
(network-utils/sorted-networks-with-details))]
(defn- first-operable-account
[accounts]
(->> accounts
vals
(remove :watch-only?)
(filter :operable?)
(sort-by :position)
first))

(defn wallet-account
"Picks the account that's gonna be used for the swap operation.
It's gonna be either the preselected account defined by
`[:wallet :current-viewing-account-address]` in `db`
or the first operable account."
[wallet]
(let [wallet-address (get wallet :current-viewing-account-address)]
(if wallet-address
(-> wallet
:accounts
vals
(utils/get-account-by-address wallet-address))
(-> wallet :accounts first-operable-account))))

(defn select-asset-to-pay-by-symbol
"Selects an asset to pay by token symbol.
It's used for cases when only token symbol is available and the information
about token needs to be extracted from the database.
That happens when token is being selected on the home screen and
it basically indicates that no account pre-selection was made."
[{:keys [wallet account test-networks-enabled? token-symbol]}]
(let [networks (-> (get-in wallet [:networks (if test-networks-enabled? :test :prod)])
(network-utils/sorted-networks-with-details))
token (->> account
:tokens
(filter #(= token-symbol (:symbol %)))
first)]
(assoc token :networks (network-utils/network-list token networks))))

(defn select-default-asset-to-receive
"Selects an asset to receive if it was not provided explicitly.
The principle of how the asset is being selected is simple: we get the
whole list, remove the currently selected `asset-to-pay` from it, and choose
the first one of what's left."
[{:keys [wallet account test-networks-enabled? asset-to-pay]}]
(let [networks (-> (get-in wallet [:networks (if test-networks-enabled? :test :prod)])
(network-utils/sorted-networks-with-details))]
(->> (utils/tokens-with-balance (:tokens account) networks nil)
(remove #(= (:symbol %) (:symbol asset-to-pay)))
first)))

(defn select-network
"Chooses the network.
Usually user needs to do the selection first and if the selection was done
then the list of networks for the defined token will always contain
one entry. Otherwise `nil` will be returned from here which will serve
as an indicator that the network selector needs to be displayed."
[{:keys [networks]}]
(when (= (count networks) 1)
(first networks)))

0 comments on commit 5c725d9

Please sign in to comment.