Skip to content

Commit 2bf3e6c

Browse files
authored
Swaps: Get full list of supported tokens from backend (#21139)
* 20380 Fetch tokens * Address updates * Events update * Events test
1 parent babcd96 commit 2bf3e6c

File tree

14 files changed

+570
-61
lines changed

14 files changed

+570
-61
lines changed

src/status_im/common/json_rpc/events.cljs

+12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
(:require
33
[clojure.string :as string]
44
[native-module.core :as native-module]
5+
[promesa.core :as promesa]
56
[re-frame.core :as re-frame]
67
[react-native.background-timer :as background-timer]
78
[taoensso.timbre :as log]
@@ -89,6 +90,17 @@
8990
(rf/dispatch (conj on-success result request-id))
9091
(on-success result request-id)))))))))))
9192

93+
(defn call-async
94+
"Helper to handle RPC calls to status-go as promises"
95+
[method js-response? & args]
96+
(promesa/create
97+
(fn [p-resolve p-reject]
98+
(call {:method method
99+
:params args
100+
:on-success p-resolve
101+
:on-error p-reject
102+
:js-response js-response?}))))
103+
92104
(re-frame/reg-fx
93105
:json-rpc/call
94106
(fn [params]

src/status_im/contexts/profile/login/events.cljs

+2
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@
9898
[:settings/get-currencies]
9999
(when (ff/enabled? ::ff/wallet.wallet-connect)
100100
[:dispatch [:wallet-connect/init]])
101+
(when (ff/enabled? ::ff/wallet.swap)
102+
[:dispatch [:wallet.tokens/get-token-list]])
101103
(when notifications-enabled?
102104
[:effects/push-notifications-enable])]})))
103105

src/status_im/contexts/wallet/common/validation.cljs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
[s]
77
(and (not (string/blank? s))
88
(boolean (re-find constants/regx-ens s))))
9+
910
(defn private-key?
1011
[s]
1112
(or (re-find constants/regx-private-key-hex s)

src/status_im/contexts/wallet/events.cljs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
[status-im.contexts.wallet.data-store :as data-store]
1515
[status-im.contexts.wallet.db :as db]
1616
[status-im.contexts.wallet.item-types :as item-types]
17+
[status-im.contexts.wallet.tokens.events]
1718
[taoensso.timbre :as log]
1819
[utils.collection]
1920
[utils.ethereum.chain :as chain]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
(ns status-im.contexts.wallet.tokens.data)
2+
3+
(defn- tokens-by-key
4+
[{:keys [key-fn added-tokens source-name tokens chain-ids]}]
5+
(reduce
6+
(fn [acc {:keys [address chainId decimals name image verified] :as token}]
7+
(if (some #{chainId} chain-ids)
8+
(let [k (key-fn token)]
9+
(assoc acc
10+
k
11+
{:key k
12+
:name name
13+
:symbol (:symbol token)
14+
:sources (if-let [added-token (get added-tokens k)]
15+
(conj (:sources added-token) source-name)
16+
[source-name])
17+
:chain-id chainId
18+
:address address
19+
:decimals decimals
20+
:image image
21+
:type (if (= name "native") :native :erc20)
22+
:community-id (get-in token [:communityData :id])
23+
:verified? verified}))
24+
acc))
25+
{}
26+
tokens))
27+
28+
(defn tokens-by-address
29+
[props]
30+
(tokens-by-key (assoc props
31+
:key-fn
32+
(fn [{:keys [chainId address]}]
33+
(str chainId "-" address)))))
34+
35+
(defn tokens-by-symbol
36+
[props]
37+
(tokens-by-key (assoc props
38+
:key-fn
39+
(fn [{:keys [address] :as token}]
40+
(if (get-in token [:communityData :id])
41+
address
42+
(:symbol token))))))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
(ns status-im.contexts.wallet.tokens.effects
2+
(:require [promesa.core :as promesa]
3+
[status-im.contexts.wallet.tokens.rpc :as rpc]
4+
[utils.re-frame :as rf]))
5+
6+
(rf/reg-fx
7+
:effects.wallet.tokens/fetch-market-values
8+
(fn [{:keys [symbols currency on-success on-error]}]
9+
(-> (rpc/fetch-market-values symbols currency)
10+
(promesa/then (partial rf/call-continuation on-success))
11+
(promesa/catch (partial rf/call-continuation on-error)))))
12+
13+
(rf/reg-fx
14+
:effects.wallet.tokens/fetch-details
15+
(fn [{:keys [symbols on-success on-error]}]
16+
(-> (rpc/fetch-details symbols)
17+
(promesa/then (partial rf/call-continuation on-success))
18+
(promesa/catch (partial rf/call-continuation on-error)))))
19+
20+
(rf/reg-fx
21+
:effects.wallet.tokens/fetch-prices
22+
(fn [{:keys [symbols currencies on-success on-error]}]
23+
(-> (rpc/fetch-prices symbols currencies)
24+
(promesa/then (partial rf/call-continuation on-success))
25+
(promesa/catch (partial rf/call-continuation on-error)))))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
(ns status-im.contexts.wallet.tokens.events
2+
(:require [re-frame.core :as rf]
3+
[status-im.constants :as constants]
4+
[status-im.contexts.wallet.tokens.data :as tokens-data]
5+
[status-im.contexts.wallet.tokens.effects]
6+
[taoensso.timbre :as log]
7+
[utils.address]
8+
[utils.ethereum.chain :as chain]))
9+
10+
(rf/reg-event-fx
11+
:wallet.tokens/get-token-list
12+
(fn [{:keys [db]}]
13+
{:db (assoc-in db [:wallet :ui :loading :token-list] true)
14+
:fx [[:json-rpc/call
15+
[{:method "wallet_getTokenList"
16+
:params []
17+
:on-success [:wallet.tokens/store-token-list]
18+
:on-error [:wallet.tokens/get-token-list-failed]}]]]}))
19+
20+
(defn store-token-list
21+
[{:keys [db]} [{:keys [data]}]]
22+
(let [chain-ids (chain/chain-ids db)
23+
tokens (reduce (fn [{:keys [by-address by-symbol] :as data}
24+
{:keys [name source version tokens]}]
25+
(-> data
26+
(update :sources
27+
conj
28+
{:name name
29+
:source source
30+
:version version
31+
:tokens-count (count tokens)})
32+
(update :by-address
33+
merge
34+
(tokens-data/tokens-by-address
35+
{:added-tokens by-address
36+
:source-name name
37+
:tokens tokens
38+
:chain-ids chain-ids}))
39+
(update :by-symbol
40+
merge
41+
(tokens-data/tokens-by-symbol
42+
{:added-tokens by-symbol
43+
:source-name name
44+
:tokens tokens
45+
:chain-ids chain-ids}))))
46+
{:sources []
47+
:by-address {}
48+
:by-symbol {}}
49+
data)
50+
symbols (->> tokens
51+
:by-symbol
52+
keys
53+
(remove utils.address/address?))]
54+
{:fx [[:effects.wallet.tokens/fetch-market-values
55+
{:symbols symbols
56+
:currency constants/profile-default-currency
57+
:on-success [:wallet.tokens/store-market-values]
58+
:on-error [:wallet.tokens/fetch-market-values-failed]}]
59+
[:effects.wallet.tokens/fetch-details
60+
{:symbols symbols
61+
:on-success [:wallet.tokens/store-details]
62+
:on-error [:wallet.tokens/fetch-details-failed]}]
63+
[:effects.wallet.tokens/fetch-prices
64+
{:symbols symbols
65+
:currencies [constants/profile-default-currency]
66+
:on-success [:wallet.tokens/store-prices]
67+
:on-error [:wallet.tokens/fetch-prices-failed]}]]
68+
:db (-> db
69+
(assoc-in [:wallet :tokens]
70+
{:sources (:sources tokens)
71+
:by-address (-> tokens :by-address vals)
72+
:by-symbol (-> tokens :by-symbol vals)})
73+
(assoc-in [:wallet :ui :loading]
74+
{:token-list false
75+
:market-values true
76+
:details true
77+
:prices true}))}))
78+
79+
(rf/reg-event-fx :wallet.tokens/store-token-list store-token-list)
80+
81+
(rf/reg-event-fx
82+
:wallet.tokens/get-token-list-failed
83+
(fn [{:keys [db]} [error]]
84+
(log/info "failed to get wallet tokens "
85+
{:error error
86+
:event :wallet.tokens/get-token-list})
87+
{:db (assoc-in db [:wallet :ui :loading :token-list] false)}))
88+
89+
(rf/reg-event-fx
90+
:wallet.tokens/store-market-values
91+
(fn [{:keys [db]} [raw-data]]
92+
(let [market-values (reduce (fn [acc [token data]]
93+
(assoc acc
94+
token
95+
{:market-cap (:MKTCAP data)
96+
:high-day (:HIGHDAY data)
97+
:low-day (:LOWDAY data)
98+
:change-pct-hour (:CHANGEPCTHOUR data)
99+
:change-pct-day (:CHANGEPCTDAY data)
100+
:change-pct-24h (:CHANGEPCT24HOUR data)
101+
:change-24h (:CHANGE24HOUR data)}))
102+
{}
103+
raw-data)]
104+
{:db (-> db
105+
(assoc-in [:wallet :tokens :market-values-per-token] market-values)
106+
(assoc-in [:wallet :ui :loading :market-values] false))})))
107+
108+
(rf/reg-event-fx
109+
:wallet.tokens/fetch-market-values-failed
110+
(fn [{:keys [db]} [error]]
111+
(log/info "failed to get wallet market values "
112+
{:error error
113+
:event :wallet.tokens/fetch-market-values})
114+
{:db (assoc-in db [:wallet :ui :loading :market-values] false)}))
115+
116+
(rf/reg-event-fx
117+
:wallet.tokens/store-details
118+
(fn [{:keys [db]} [details]]
119+
{:db (-> db
120+
(assoc-in [:wallet :tokens :details-per-token] details)
121+
(assoc-in [:wallet :ui :loading :details] false))}))
122+
123+
(rf/reg-event-fx
124+
:wallet.tokens/fetch-details-failed
125+
(fn [{:keys [db]} [error]]
126+
(log/info "failed to get wallet details "
127+
{:error error
128+
:event :wallet.tokens/fetch-details})
129+
{:db (assoc-in db [:wallet :ui :loading :details] false)}))
130+
131+
(rf/reg-event-fx
132+
:wallet.tokens/store-prices
133+
(fn [{:keys [db]} [prices]]
134+
{:db (-> db
135+
(assoc-in [:wallet :tokens :prices-per-token] prices)
136+
(assoc-in [:wallet :ui :loading :prices] false))}))
137+
138+
(rf/reg-event-fx
139+
:wallet.tokens/fetch-prices-failed
140+
(fn [{:keys [db]} [error]]
141+
(log/info "failed to get wallet prices "
142+
{:error error
143+
:event :wallet.tokens/fetch-prices})
144+
{:db (assoc-in db [:wallet :ui :loading :prices] false)}))

0 commit comments

Comments
 (0)