feat(wallet): Skip From page while sending an asset only owned by one account (#20773)
- Update tests - Omit from page while sending a token in home page - Hide send and bridge option for not owned tokens - Fix subscription to return accounts owning an asset
This commit is contained in:
parent
8597b899bd
commit
e4639c153f
|
@ -262,7 +262,7 @@
|
|||
|
||||
can-edit-addresses? (rf/sub [:communities/can-edit-shared-addresses? id])
|
||||
|
||||
wallet-accounts (rf/sub [:wallet/operable-accounts-without-watched-accounts])
|
||||
wallet-accounts (rf/sub [:wallet/operable-accounts])
|
||||
joined (rf/sub [:communities/community-joined id])
|
||||
unmodified-addresses-to-reveal (rf/sub [:communities/addresses-to-reveal id])
|
||||
[addresses-to-reveal set-addresses-to-reveal] (rn/use-state unmodified-addresses-to-reveal)
|
||||
|
|
|
@ -16,14 +16,14 @@
|
|||
:right-icon :i/external})
|
||||
|
||||
(defn- action-send
|
||||
[send-params]
|
||||
[send-params entry-point]
|
||||
{:icon :i/send
|
||||
:accessibility-label :send
|
||||
:label (i18n/label :t/send)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(rf/dispatch [:wallet/clean-send-data])
|
||||
(rf/dispatch [:wallet/set-token-to-send send-params]))})
|
||||
(rf/dispatch [:wallet/set-token-to-send send-params entry-point]))})
|
||||
|
||||
(defn- action-receive
|
||||
[selected-account?]
|
||||
|
@ -66,36 +66,41 @@
|
|||
:on-press #(js/alert "to be implemented")})
|
||||
|
||||
(defn token-value-drawer
|
||||
[token watch-only?]
|
||||
[token watch-only? entry-point]
|
||||
(let [token-symbol (:token token)
|
||||
token-data (first (rf/sub [:wallet/current-viewing-account-tokens-filtered
|
||||
token-symbol]))
|
||||
selected-account? (rf/sub [:wallet/current-viewing-account-address])
|
||||
token-owners (rf/sub [:wallet/operable-addresses-with-token-symbol token-symbol])
|
||||
send-or-bridge-params (if selected-account?
|
||||
{:token token-data
|
||||
:stack-id :screen/wallet.accounts
|
||||
:start-flow? true}
|
||||
:start-flow? true
|
||||
:owners token-owners}
|
||||
{:token-symbol token-symbol
|
||||
:stack-id :wallet-stack
|
||||
:start-flow? true})]
|
||||
:start-flow? true
|
||||
:owners token-owners})]
|
||||
[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)
|
||||
(action-send send-or-bridge-params)
|
||||
(when (seq token-owners)
|
||||
(action-send send-or-bridge-params entry-point))
|
||||
(action-receive selected-account?)
|
||||
(when (ff/enabled? ::ff/wallet.swap) (action-swap))
|
||||
(action-bridge send-or-bridge-params)]))]]))
|
||||
(when (seq (seq token-owners))
|
||||
(action-bridge send-or-bridge-params))]))]]))
|
||||
|
||||
(defn view
|
||||
[item _ _ {:keys [watch-only?]}]
|
||||
[item _ _ {:keys [watch-only? entry-point]}]
|
||||
[quo/token-value
|
||||
(cond-> item
|
||||
(or (not watch-only?) (ff/enabled? ::ff/wallet.long-press-watch-only-asset))
|
||||
(assoc :on-long-press
|
||||
#(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn [] [token-value-drawer item watch-only?])
|
||||
{:content (fn [] [token-value-drawer item watch-only? entry-point])
|
||||
:selected-item (fn [] [quo/token-value item])}])))])
|
||||
|
|
|
@ -65,10 +65,21 @@
|
|||
{:db (assoc-in db [:wallet :current-viewing-account-address] address)}))
|
||||
|
||||
(rf/reg-event-fx :wallet/clean-current-viewing-account
|
||||
(fn [{:keys [db]}]
|
||||
(let [just-completed-transaction? (get-in db [:wallet :ui :send :just-completed-transaction?])]
|
||||
(when-not just-completed-transaction?
|
||||
{:db (update db :wallet dissoc :current-viewing-account-address)}))))
|
||||
(fn [{:keys [db]} [ignore-just-completed-transaction?]]
|
||||
(let [{:keys [entry-point just-completed-transaction?]} (-> db :wallet :ui :send)
|
||||
entry-point-wallet-home? (= entry-point :wallet-stack)]
|
||||
{:db (cond-> db
|
||||
(and (not entry-point)
|
||||
(not ignore-just-completed-transaction?)
|
||||
(not just-completed-transaction?))
|
||||
(update :wallet dissoc :current-viewing-account-address)
|
||||
|
||||
entry-point-wallet-home?
|
||||
(update-in [:wallet :ui :send] dissoc :entry-point)
|
||||
|
||||
(and entry-point-wallet-home?
|
||||
(not just-completed-transaction?))
|
||||
(update :wallet dissoc :current-viewing-account-address))})))
|
||||
|
||||
(rf/reg-event-fx :wallet/close-account-page
|
||||
(fn [{:keys [db]}]
|
||||
|
|
|
@ -18,4 +18,5 @@
|
|||
[rn/flat-list
|
||||
{:render-fn token-value/view
|
||||
:data tokens
|
||||
:render-data {:entry-point :wallet-stack}
|
||||
:content-container-style style/list-container}])))
|
||||
|
|
|
@ -193,25 +193,35 @@
|
|||
|
||||
(rf/reg-event-fx
|
||||
:wallet/set-token-to-send
|
||||
(fn [{:keys [db]} [{:keys [token-symbol token stack-id start-flow?]}]]
|
||||
(fn [{:keys [db]} [{:keys [token-symbol token stack-id start-flow? owners]} entry-point]]
|
||||
;; `token` is a map extracted from the sender, but in the wallet home page we don't know the
|
||||
;; sender yet, so we only provide the `token-symbol`, later in
|
||||
;; `:wallet/select-from-account` the `token` key will be set.
|
||||
(let [{token-networks :networks} token
|
||||
receiver-networks (get-in db [:wallet :ui :send :receiver-networks])
|
||||
token-networks-ids (mapv #(:chain-id %) token-networks)
|
||||
token-not-supported-in-receiver-networks? (not-any? (set receiver-networks)
|
||||
token-networks-ids)]
|
||||
(when (or token token-symbol)
|
||||
(let [{:keys [networks]} token
|
||||
receiver-networks (get-in db [:wallet :ui :send :receiver-networks])
|
||||
token-networks-ids (map :chain-id networks)
|
||||
unsupported-token? (not-any? (set receiver-networks) token-networks-ids)
|
||||
unique-owner (when (= (count owners) 1)
|
||||
(first owners))
|
||||
unique-owner-tokens (get-in db [:wallet :accounts unique-owner :tokens])
|
||||
token-data (or token
|
||||
(when (and token-symbol unique-owner)
|
||||
(some #(when (= (:symbol %) token-symbol) %)
|
||||
unique-owner-tokens)))]
|
||||
(when (or token-data token-symbol)
|
||||
{:db (cond-> db
|
||||
:always (update-in [:wallet :ui :send] dissoc :collectible)
|
||||
:always (assoc-in
|
||||
[:wallet :ui :send :token-not-supported-in-receiver-networks?]
|
||||
token-not-supported-in-receiver-networks?)
|
||||
token (assoc-in [:wallet :ui :send :token] token)
|
||||
token (assoc-in [:wallet :ui :send :token-display-name]
|
||||
(:symbol token))
|
||||
token-symbol (assoc-in [:wallet :ui :send :token-symbol] token-symbol))
|
||||
:always (update-in [:wallet :ui :send]
|
||||
#(-> %
|
||||
(dissoc :collectible)
|
||||
(assoc :token-not-supported-in-receiver-networks?
|
||||
unsupported-token?)))
|
||||
token-symbol (assoc-in [:wallet :ui :send :token-symbol] token-symbol)
|
||||
token-data (update-in [:wallet :ui :send]
|
||||
#(assoc %
|
||||
:token token-data
|
||||
:token-display-name (:symbol token-data)))
|
||||
unique-owner (assoc-in [:wallet :current-viewing-account-address] unique-owner)
|
||||
entry-point (assoc-in [:wallet :ui :send :entry-point] entry-point))
|
||||
:fx [[:dispatch [:wallet/clean-suggested-routes]]
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
|
@ -225,9 +235,9 @@
|
|||
(let [{token-networks :networks
|
||||
token-symbol :symbol} token
|
||||
receiver-networks (get-in db [:wallet :ui :send :receiver-networks])
|
||||
token-networks-ids (mapv #(:chain-id %) token-networks)
|
||||
token-not-supported-in-receiver-networks? (not (some (set receiver-networks)
|
||||
token-networks-ids))]
|
||||
token-networks-ids (map :chain-id token-networks)
|
||||
token-not-supported-in-receiver-networks? (not-any? (set receiver-networks)
|
||||
token-networks-ids)]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :token] token)
|
||||
(assoc-in [:wallet :ui :send :token-display-name] token-symbol)
|
||||
|
@ -256,7 +266,9 @@
|
|||
(rf/reg-event-fx
|
||||
:wallet/set-collectible-to-send
|
||||
(fn [{db :db} [{:keys [collectible current-screen start-flow?]}]]
|
||||
(let [collection-data (:collection-data collectible)
|
||||
(let [viewing-account? (some? (-> db :wallet :current-viewing-account-address))
|
||||
entry-point (when-not viewing-account? :wallet-stack)
|
||||
collection-data (:collection-data collectible)
|
||||
collectible-data (:collectible-data collectible)
|
||||
contract-type (:contract-type collectible)
|
||||
tx-type (if (= contract-type constants/wallet-contract-type-erc-1155)
|
||||
|
@ -271,6 +283,7 @@
|
|||
|
||||
collectible
|
||||
(str (:name collection-data) " #" collectible-id))
|
||||
owner-address (-> collectible :ownership first :address)
|
||||
collectible-tx (-> db
|
||||
(update-in [:wallet :ui :send] dissoc :token)
|
||||
(assoc-in [:wallet :ui :send :collectible] collectible)
|
||||
|
@ -278,7 +291,14 @@
|
|||
(assoc-in [:wallet :ui :send :tx-type] tx-type))
|
||||
recipient-set? (-> db :wallet :ui :send :recipient)]
|
||||
{:db (cond-> collectible-tx
|
||||
one-collectible? (assoc-in [:wallet :ui :send :amount] 1))
|
||||
:always
|
||||
(assoc-in [:wallet :ui :send :entry-point] entry-point)
|
||||
|
||||
(not viewing-account?)
|
||||
(assoc-in [:wallet :current-viewing-account-address] owner-address)
|
||||
|
||||
one-collectible?
|
||||
(assoc-in [:wallet :ui :send :amount] 1))
|
||||
:fx [(when (and one-collectible? recipient-set?)
|
||||
[:dispatch [:wallet/get-suggested-routes {:amount 1}]])
|
||||
[:dispatch
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
{:on-press #(rf/dispatch [:navigate-back])
|
||||
:margin-top (safe-area/get-top)
|
||||
:switcher-type :select-account}]}
|
||||
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/from-label)
|
||||
:title-accessibility-label :title-label}]
|
||||
|
|
|
@ -177,7 +177,9 @@
|
|||
(rf/dispatch [:wallet/clean-selected-collectible])
|
||||
(rf/dispatch [:wallet/clean-send-address])
|
||||
(rf/dispatch [:wallet/clean-disabled-from-networks])
|
||||
(rf/dispatch [:wallet/select-address-tab nil]))
|
||||
(rf/dispatch [:wallet/select-address-tab nil])
|
||||
(rf/dispatch [:wallet/clean-current-viewing-account
|
||||
:ignore-just-complete-transaction]))
|
||||
on-change-tab #(rf/dispatch [:wallet/select-address-tab %])
|
||||
input-value (reagent/atom "")
|
||||
input-focused? (reagent/atom false)]
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
(defn view
|
||||
[]
|
||||
(let [selected-account-address (rf/sub [:wallet/current-viewing-account-address])
|
||||
accounts (rf/sub [:wallet/operable-accounts-without-watched-accounts])]
|
||||
accounts (rf/sub [:wallet/operable-accounts])]
|
||||
[:<>
|
||||
[quo/drawer-top {:title (i18n/label :t/select-account)}]
|
||||
[gesture/flat-list
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
|
||||
(defn- accounts-list
|
||||
[]
|
||||
(let [accounts (rf/sub [:wallet/operable-accounts-without-watched-accounts])
|
||||
(let [accounts (rf/sub [:wallet/operable-accounts])
|
||||
selected-address (rf/sub [:wallet-connect/current-proposal-address])]
|
||||
[rn/view {:style style/account-switcher-list}
|
||||
(for [{:keys [address] :as account} accounts]
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
|
||||
(re-frame/reg-sub :communities/accounts-to-reveal
|
||||
(fn [[_ community-id]]
|
||||
[(re-frame/subscribe [:wallet/operable-accounts-without-watched-accounts])
|
||||
[(re-frame/subscribe [:wallet/operable-accounts])
|
||||
(re-frame/subscribe [:communities/addresses-to-reveal community-id])])
|
||||
(fn [[accounts addresses] _]
|
||||
(filter #(contains? addresses (:address %))
|
||||
|
@ -61,7 +61,7 @@
|
|||
|
||||
(re-frame/reg-sub :communities/airdrop-account
|
||||
(fn [[_ community-id]]
|
||||
[(re-frame/subscribe [:wallet/operable-accounts-without-watched-accounts])
|
||||
[(re-frame/subscribe [:wallet/operable-accounts])
|
||||
(re-frame/subscribe [:communities/airdrop-address community-id])])
|
||||
(fn [[accounts airdrop-address] _]
|
||||
(->> accounts
|
||||
|
|
|
@ -134,10 +134,12 @@
|
|||
(:chain-id %))))
|
||||
(map :chain-id)
|
||||
set)]
|
||||
(assoc token
|
||||
:networks (network-utils/network-list token networks)
|
||||
:available-balance (utils/calculate-total-token-balance token)
|
||||
:total-balance (utils/calculate-total-token-balance token enabled-from-chain-ids)))))
|
||||
(some-> token
|
||||
(assoc :networks (network-utils/network-list token networks)
|
||||
:available-balance (utils/calculate-total-token-balance token)
|
||||
:total-balance (utils/calculate-total-token-balance
|
||||
token
|
||||
enabled-from-chain-ids))))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/wallet-send-token-symbol
|
||||
|
@ -464,22 +466,47 @@
|
|||
keep-operable-accounts)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/operable-accounts-without-watched-accounts
|
||||
:wallet/operable-accounts
|
||||
:<- [:wallet/accounts-without-watched-accounts]
|
||||
keep-operable-accounts)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/operable-addresses-tokens-with-positive-balance
|
||||
:<- [:wallet/operable-accounts]
|
||||
(fn [accounts]
|
||||
(let [positive-balance-in-any-chain? (fn [{:keys [balances-per-chain]}]
|
||||
(->> balances-per-chain
|
||||
(map (comp :raw-balance val))
|
||||
(some pos?)))]
|
||||
(as-> accounts $
|
||||
(group-by :address $)
|
||||
(update-vals $ #(filter positive-balance-in-any-chain? (:tokens (first %))))))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/accounts-with-current-asset
|
||||
:<- [:wallet/operable-accounts-without-watched-accounts]
|
||||
:<- [:wallet/operable-accounts]
|
||||
:<- [:wallet/operable-addresses-tokens-with-positive-balance]
|
||||
:<- [:wallet/wallet-send-token-symbol]
|
||||
:<- [:wallet/wallet-send-token]
|
||||
(fn [[accounts token-symbol token]]
|
||||
(let [asset-symbol (or token-symbol (:symbol token))]
|
||||
(if asset-symbol
|
||||
(filter (fn [account]
|
||||
(some #(= (:symbol %) asset-symbol) (:tokens account)))
|
||||
accounts)
|
||||
accounts))))
|
||||
(fn [[accounts addresses-tokens token-symbol token]]
|
||||
(if-let [asset-symbol (or token-symbol (:symbol token))]
|
||||
(let [addresses-with-asset (as-> addresses-tokens $
|
||||
(update-vals $ #(set (map :symbol %)))
|
||||
(keep (fn [[address token-symbols]]
|
||||
(when (token-symbols asset-symbol) address))
|
||||
$)
|
||||
(set $))]
|
||||
(filter #(addresses-with-asset (:address %)) accounts))
|
||||
accounts)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/operable-addresses-with-token-symbol
|
||||
:<- [:wallet/operable-addresses-tokens-with-positive-balance]
|
||||
(fn [addresses-tokens [_ token-symbol]]
|
||||
(keep (fn [[address tokens]]
|
||||
(some #(when (= (:symbol %) token-symbol) address)
|
||||
tokens))
|
||||
addresses-tokens)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/account-tab
|
||||
|
|
|
@ -13,16 +13,22 @@
|
|||
{:before #(reset! rf-db/app-db {})})
|
||||
|
||||
(def ^:private accounts-with-tokens
|
||||
{:0x1 {:tokens [{:symbol "ETH"} {:symbol "SNT"}]
|
||||
{:0x1 {:tokens [{:symbol "ETH"
|
||||
:balances-per-chain {1 {:raw-balance "100"}}}
|
||||
{:symbol "SNT"
|
||||
:balances-per-chain {1 {:raw-balance "100"}}}]
|
||||
:network-preferences-names #{}
|
||||
:customization-color nil
|
||||
:operable? true
|
||||
:operable :fully}
|
||||
:0x2 {:tokens [{:symbol "SNT"}]
|
||||
:operable :fully
|
||||
:address "0x1"}
|
||||
:0x2 {:tokens [{:symbol "SNT"
|
||||
:balances-per-chain {1 {:raw-balance "200"}}}]
|
||||
:network-preferences-names #{}
|
||||
:customization-color nil
|
||||
:operable? true
|
||||
:operable :partially}})
|
||||
:operable :partially
|
||||
:address "0x2"}})
|
||||
|
||||
(def tokens-0x1
|
||||
[{:decimals 1
|
||||
|
@ -495,11 +501,15 @@
|
|||
(assoc-in [:wallet :ui :send :token-symbol] "ETH")))
|
||||
(let [result (rf/sub [sub-name])]
|
||||
(is (match? result
|
||||
[{:tokens [{:symbol "ETH"} {:symbol "SNT"}]
|
||||
[{:tokens [{:symbol "ETH"
|
||||
:balances-per-chain {1 {:raw-balance "100"}}}
|
||||
{:symbol "SNT"
|
||||
:balances-per-chain {1 {:raw-balance "100"}}}]
|
||||
:network-preferences-names #{}
|
||||
:customization-color nil
|
||||
:operable? true
|
||||
:operable :fully}]))))
|
||||
:operable :fully
|
||||
:address "0x1"}]))))
|
||||
|
||||
(testing "returns the accounts list with the current asset using token"
|
||||
(swap! rf-db/app-db
|
||||
|
@ -508,11 +518,15 @@
|
|||
(assoc-in [:wallet :ui :send :token] {:symbol "ETH"})))
|
||||
(let [result (rf/sub [sub-name])]
|
||||
(is (match? result
|
||||
[{:tokens [{:symbol "ETH"} {:symbol "SNT"}]
|
||||
[{:tokens [{:symbol "ETH"
|
||||
:balances-per-chain {1 {:raw-balance "100"}}}
|
||||
{:symbol "SNT"
|
||||
:balances-per-chain {1 {:raw-balance "100"}}}]
|
||||
:network-preferences-names #{}
|
||||
:customization-color nil
|
||||
:operable? true
|
||||
:operable :fully}]))))
|
||||
:operable :fully
|
||||
:address "0x1"}]))))
|
||||
|
||||
(testing
|
||||
"returns the full accounts list with the current asset using token-symbol if each account has the asset"
|
||||
|
|
Loading…
Reference in New Issue