Skip to content

Commit 711fd19

Browse files
authored
fix(wallet): "Not enough assets" case in send screen (#21425)
* Make `->bignumbers` more general * Fix case when there are not enough assets to pay gas fees: - Fix the UI to match Figma - Fix logic to handle the case - Perform refactoring to surrounding code
1 parent d58553f commit 711fd19

File tree

5 files changed

+314
-282
lines changed

5 files changed

+314
-282
lines changed

src/status_im/contexts/wallet/send/events.cljs

+135-120
Original file line numberDiff line numberDiff line change
@@ -28,95 +28,108 @@
2828
{:fx [[:dispatch [:wallet/stop-get-suggested-routes]]
2929
[:dispatch [:wallet/clean-suggested-routes]]]}))
3030

31-
(rf/reg-event-fx :wallet/suggested-routes-success
32-
(fn [{:keys [db]} [suggested-routes-data]]
33-
(let [chosen-route (:best suggested-routes-data)
34-
{:keys [token collectible token-display-name
35-
receiver-networks
36-
receiver-network-values
37-
sender-network-values tx-type
38-
disabled-from-chain-ids
39-
from-locked-amounts]} (get-in db [:wallet :ui :send])
40-
token-decimals (if collectible 0 (:decimals token))
41-
native-token? (and token (= token-display-name "ETH"))
42-
routes-available? (pos? (count chosen-route))
43-
token-networks (:networks token)
44-
token-networks-ids (when token-networks
45-
(map #(:chain-id %) token-networks))
46-
from-network-amounts-by-chain (send-utils/network-amounts-by-chain
47-
{:route chosen-route
48-
:token-decimals token-decimals
49-
:native-token? native-token?
50-
:receiver? false})
51-
to-network-amounts-by-chain (send-utils/network-amounts-by-chain
52-
{:route chosen-route
53-
:token-decimals token-decimals
54-
:native-token? native-token?
55-
:receiver? true})
56-
sender-possible-chain-ids (map :chain-id sender-network-values)
57-
sender-network-values (if routes-available?
58-
(send-utils/network-amounts
59-
{:network-values
60-
(if (= tx-type :tx/bridge)
61-
from-network-amounts-by-chain
62-
(send-utils/add-zero-values-to-network-values
63-
from-network-amounts-by-chain
64-
sender-possible-chain-ids))
65-
:disabled-chain-ids disabled-from-chain-ids
66-
:receiver-networks receiver-networks
67-
:token-networks-ids token-networks-ids
68-
:from-locked-amounts from-locked-amounts
69-
:tx-type tx-type
70-
:receiver? false})
71-
(send-utils/reset-loading-network-amounts-to-zero
72-
sender-network-values))
73-
receiver-network-values (if routes-available?
74-
(send-utils/network-amounts
75-
{:network-values to-network-amounts-by-chain
76-
:disabled-chain-ids disabled-from-chain-ids
77-
:receiver-networks receiver-networks
78-
:token-networks-ids token-networks-ids
79-
:tx-type tx-type
80-
:receiver? true})
81-
(cond->
31+
(defn- add-not-enough-assets-data
32+
[send-data chosen-route]
33+
(-> send-data
34+
(assoc :route chosen-route
35+
:loading-suggested-routes? false
36+
:suggested-routes {:best []}
37+
:enough-assets? false)
38+
(update :sender-network-values send-utils/reset-loading-network-amounts-to-zero)
39+
(update :receiver-network-values send-utils/reset-loading-network-amounts-to-zero)))
40+
41+
(rf/reg-event-fx
42+
:wallet/suggested-routes-success
43+
(fn [{:keys [db]} [suggested-routes-data enough-assets?]]
44+
(if-not enough-assets?
45+
{:db (update-in db [:wallet :ui :send] add-not-enough-assets-data (:best suggested-routes-data))}
46+
(let [chosen-route (:best suggested-routes-data)
47+
{:keys [token collectible token-display-name
48+
receiver-networks
49+
receiver-network-values
50+
sender-network-values tx-type
51+
disabled-from-chain-ids
52+
from-locked-amounts]} (get-in db [:wallet :ui :send])
53+
token-decimals (if collectible 0 (:decimals token))
54+
native-token? (and token (= token-display-name "ETH"))
55+
routes-available? (pos? (count chosen-route))
56+
token-networks (:networks token)
57+
token-networks-ids (when token-networks
58+
(map #(:chain-id %) token-networks))
59+
from-network-amounts-by-chain (send-utils/network-amounts-by-chain
60+
{:route chosen-route
61+
:token-decimals token-decimals
62+
:native-token? native-token?
63+
:receiver? false})
64+
to-network-amounts-by-chain (send-utils/network-amounts-by-chain
65+
{:route chosen-route
66+
:token-decimals token-decimals
67+
:native-token? native-token?
68+
:receiver? true})
69+
sender-possible-chain-ids (map :chain-id sender-network-values)
70+
sender-network-values (if routes-available?
71+
(send-utils/network-amounts
72+
{:network-values
73+
(if (= tx-type :tx/bridge)
74+
from-network-amounts-by-chain
75+
(send-utils/add-zero-values-to-network-values
76+
from-network-amounts-by-chain
77+
sender-possible-chain-ids))
78+
:disabled-chain-ids disabled-from-chain-ids
79+
:receiver-networks receiver-networks
80+
:token-networks-ids token-networks-ids
81+
:from-locked-amounts from-locked-amounts
82+
:tx-type tx-type
83+
:receiver? false})
8284
(send-utils/reset-loading-network-amounts-to-zero
83-
receiver-network-values)
84-
85-
(not= tx-type :tx/bridge)
86-
send-utils/safe-add-type-edit))
87-
network-links (when routes-available?
88-
(send-utils/network-links chosen-route
89-
sender-network-values
90-
receiver-network-values))]
91-
{:db (update-in db
92-
[:wallet :ui :send]
93-
assoc
94-
:suggested-routes suggested-routes-data
95-
:route chosen-route
96-
:from-values-by-chain from-network-amounts-by-chain
97-
:to-values-by-chain to-network-amounts-by-chain
98-
:sender-network-values sender-network-values
99-
:receiver-network-values receiver-network-values
100-
:network-links network-links
101-
:loading-suggested-routes? false)})))
102-
103-
(rf/reg-event-fx :wallet/suggested-routes-error
85+
sender-network-values))
86+
receiver-network-values (if routes-available?
87+
(send-utils/network-amounts
88+
{:network-values to-network-amounts-by-chain
89+
:disabled-chain-ids disabled-from-chain-ids
90+
:receiver-networks receiver-networks
91+
:token-networks-ids token-networks-ids
92+
:tx-type tx-type
93+
:receiver? true})
94+
(cond->
95+
(send-utils/reset-loading-network-amounts-to-zero
96+
receiver-network-values)
97+
98+
(not= tx-type :tx/bridge)
99+
send-utils/safe-add-type-edit))
100+
network-links (when routes-available?
101+
(send-utils/network-links chosen-route
102+
sender-network-values
103+
receiver-network-values))]
104+
{:db (update-in db
105+
[:wallet :ui :send]
106+
assoc
107+
:suggested-routes suggested-routes-data
108+
:route chosen-route
109+
:from-values-by-chain from-network-amounts-by-chain
110+
:to-values-by-chain to-network-amounts-by-chain
111+
:sender-network-values sender-network-values
112+
:receiver-network-values receiver-network-values
113+
:network-links network-links
114+
:loading-suggested-routes? false
115+
:enough-assets? true)}))))
116+
117+
(rf/reg-event-fx
118+
:wallet/suggested-routes-error
104119
(fn [{:keys [db]} [error-message]]
105-
(let [cleaned-sender-network-values (-> (get-in db [:wallet :ui :send :sender-network-values])
106-
(send-utils/reset-loading-network-amounts-to-zero))
107-
cleaned-receiver-network-values (-> (get-in db [:wallet :ui :send :receiver-network-values])
108-
(send-utils/reset-loading-network-amounts-to-zero))]
109-
{:db (-> db
110-
(update-in [:wallet :ui :send] dissoc :route)
111-
(assoc-in [:wallet :ui :send :sender-network-values] cleaned-sender-network-values)
112-
(assoc-in [:wallet :ui :send :receiver-network-values] cleaned-receiver-network-values)
113-
(assoc-in [:wallet :ui :send :loading-suggested-routes?] false)
114-
(assoc-in [:wallet :ui :send :suggested-routes] {:best []}))
115-
:fx [[:dispatch
116-
[:toasts/upsert
117-
{:id :send-transaction-error
118-
:type :negative
119-
:text error-message}]]]})))
120+
{:db (-> db
121+
(update-in [:wallet :ui :send] dissoc :route)
122+
(update-in [:wallet :ui :send :sender-network-values]
123+
send-utils/reset-loading-network-amounts-to-zero)
124+
(update-in [:wallet :ui :send :receiver-network-values]
125+
send-utils/reset-loading-network-amounts-to-zero)
126+
(assoc-in [:wallet :ui :send :loading-suggested-routes?] false)
127+
(assoc-in [:wallet :ui :send :suggested-routes] {:best []}))
128+
:fx [[:dispatch
129+
[:toasts/upsert
130+
{:id :send-transaction-error
131+
:type :negative
132+
:text error-message}]]]}))
120133

121134
(rf/reg-event-fx :wallet/clean-send-address
122135
(fn [{:keys [db]}]
@@ -378,8 +391,7 @@
378391
from-locked-amounts bridge-to-chain-id]
379392
:or {token updated-token}} (get-in db [:wallet :ui :send])
380393
test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?])
381-
networks ((if test-networks-enabled? :test :prod)
382-
(get-in db [:wallet :networks]))
394+
networks (get-in db [:wallet :networks (if test-networks-enabled? :test :prod)])
383395
network-chain-ids (map :chain-id networks)
384396
token-decimal (when token (:decimals token))
385397
token-id (utils/format-token-id token collectible)
@@ -509,40 +521,43 @@
509521
[routes]
510522
(map data-store/new->old-route-path routes))
511523

524+
(def ^:private best-routes-fix
525+
(comp ->old-route-paths
526+
remove-invalid-bonder-fees-routes
527+
remove-multichain-routes))
528+
529+
(def ^:private candidates-fix
530+
(comp ->old-route-paths remove-invalid-bonder-fees-routes))
531+
532+
(defn- fix-routes
533+
[data]
534+
(-> data
535+
(data-store/rpc->suggested-routes)
536+
(update :best best-routes-fix)
537+
(update :candidates candidates-fix)))
538+
512539
(rf/reg-event-fx
513540
:wallet/handle-suggested-routes
514541
(fn [{:keys [db]} [data]]
515-
(let [swap? (get-in db [:wallet :ui :swap])
516-
{:keys [code details] :as error-response} (-> data :ErrorResponse)
517-
skip-processing-suggested-routes? (get-in db
518-
[:wallet :ui :send
519-
:skip-processing-suggested-routes?])
520-
process-response? (and (not swap?)
521-
(not skip-processing-suggested-routes?))]
522-
(if (and (not swap?) error-response)
523-
(let [error-message (if (= code "0") "An error occurred" details)]
524-
(log/error "failed to get suggested routes (async)"
525-
{:event :wallet/handle-suggested-routes
526-
:error error-message})
527-
{:fx [(cond
528-
swap?
529-
[:dispatch [:wallet/swap-proposal-error error-message]]
530-
process-response?
531-
[:dispatch [:wallet/suggested-routes-error error-message]])]})
532-
(let [best-routes-fix (comp ->old-route-paths
533-
remove-invalid-bonder-fees-routes
534-
remove-multichain-routes)
535-
candidates-fix (comp ->old-route-paths
536-
remove-invalid-bonder-fees-routes)
537-
routes (-> data
538-
(data-store/rpc->suggested-routes)
539-
(update :best best-routes-fix)
540-
(update :candidates candidates-fix))]
541-
{:fx [(cond
542-
swap?
543-
[:dispatch [:wallet/swap-proposal-success routes]]
544-
process-response?
545-
[:dispatch [:wallet/suggested-routes-success routes]])]})))))
542+
(let [{send :send swap? :swap} (-> db :wallet :ui)
543+
skip-processing-routes? (:skip-processing-suggested-routes? send)]
544+
(when (or swap? (not skip-processing-routes?))
545+
(let [{error-code :code
546+
:as error} (:ErrorResponse data)
547+
enough-assets? (not (and (:Best data) (= error-code "WR-002")))
548+
failure? (and error enough-assets? (not swap?))
549+
error-message (if (zero? error-code) "An error occurred" (:details error))]
550+
(when failure?
551+
(log/error "failed to get suggested routes (async)"
552+
{:event :wallet/handle-suggested-routes
553+
:error error-message}))
554+
{:fx [[:dispatch
555+
(cond
556+
(and failure? swap?) [:wallet/swap-proposal-error error-message]
557+
failure? [:wallet/suggested-routes-error error-message]
558+
swap? [:wallet/swap-proposal-success (fix-routes data)]
559+
:else [:wallet/suggested-routes-success (fix-routes data)
560+
enough-assets?])]]})))))
546561

547562
(rf/reg-event-fx :wallet/add-authorized-transaction
548563
(fn [{:keys [db]} [transaction]]

src/status_im/contexts/wallet/send/input_amount/component_spec.cljs

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
:mixedcase-address "0x7bcDfc75c431"
4242
:public-key "0x04371e2d9d66b82f056bc128064"
4343
:removed false}
44+
:wallet/current-viewing-account-color :purple
45+
:wallet/wallet-send-enough-assets? true
4446
:wallet/wallet-send-token {:symbol :eth
4547
:networks [{:source 879
4648
:short-name "eth"

0 commit comments

Comments
 (0)