Skip to content

Commit aad2012

Browse files
committed
chore: improvements on all tokens list
Instead of using all tokens (atm there are ~15k unique tokens that the app operates with) in all parts of the app, a new token list, containing only tokens of interest, is being used. There is also a new list containing all tokens introduced that will be used in places where we really need all tokens, like drop-down list for Swap.
1 parent c0be920 commit aad2012

File tree

24 files changed

+305
-195
lines changed

24 files changed

+305
-195
lines changed

src/app/modules/main/wallet_section/accounts/module.nim

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ method load*(self: Module) =
100100

101101
self.events.on(SIGNAL_TOKENS_MARKET_VALUES_UPDATED) do(e:Args):
102102
self.refreshAllWalletAccountsBalances()
103+
self.events.on(SIGNAL_TOKENS_PRICES_UPDATED) do(e:Args):
104+
self.refreshAllWalletAccountsBalances()
103105
self.events.on(SIGNAL_CURRENCY_FORMATS_UPDATED) do(e:Args):
104106
self.refreshAllWalletAccountsBalances()
105107
self.events.on(SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT) do(e:Args):

src/app/modules/main/wallet_section/all_tokens/controller.nim

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,14 @@ proc getHistoricalDataForToken*(self: Controller, tokenKey: string, currency: st
7070
proc getAllTokenLists*(self: Controller): var seq[TokenListItem] =
7171
return self.tokenService.getAllTokenLists()
7272

73-
proc getAllTokenGroups*(self: Controller): var seq[TokenGroupItem] =
74-
return self.tokenService.getAllTokenGroups()
73+
proc buildGroupsForChain*(self: Controller, chainId: int) =
74+
self.tokenService.buildGroupsForChain(chainId)
75+
76+
proc getGroupsForChain*(self: Controller): var seq[TokenGroupItem] =
77+
return self.tokenService.getGroupsForChain()
78+
79+
proc getGroupsOfInterest*(self: Controller): var seq[TokenGroupItem] =
80+
return self.tokenService.getGroupsOfInterest()
7581

7682
proc getTokenDetails*(self: Controller, tokenKey: string): TokenDetailsItem =
7783
return self.tokenService.getTokenDetails(tokenKey)

src/app/modules/main/wallet_section/all_tokens/io_interface.nim

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ method getTokensModelDataSource*(self: AccessInterface): TokensModelDataSource {
6060
method getTokenGroupsModelDataSource*(self: AccessInterface): TokenGroupsModelDataSource {.base.} =
6161
raise newException(ValueError, "No implementation available")
6262

63+
method getTokenGroupsForChainModelDataSource*(self: AccessInterface): TokenGroupsModelDataSource {.base.} =
64+
raise newException(ValueError, "No implementation available")
65+
6366
method getTokenMarketValuesDataSource*(self: AccessInterface): TokenMarketValuesDataSource {.base.} =
6467
raise newException(ValueError, "No implementation available")
6568

@@ -75,6 +78,9 @@ method getTokenPreferencesJson*(self: AccessInterface): string {.base.} =
7578
method viewDidLoad*(self: AccessInterface) {.base.} =
7679
raise newException(ValueError, "No implementation available")
7780

81+
method buildGroupsForChain*(self: AccessInterface, chainId: int) {.base.} =
82+
raise newException(ValueError, "No implementation available")
83+
7884
method filterChanged*(self: AccessInterface, addresses: seq[string]) {.base.} =
7985
raise newException(ValueError, "No implementation available")
8086

src/app/modules/main/wallet_section/all_tokens/module.nim

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ method load*(self: Module) =
5353
self.events.on(SIGNAL_TOKENS_LIST_UPDATED) do(e: Args):
5454
self.view.modelsUpdated()
5555
self.view.emitTokenListUpdatedAtSignal()
56-
self.events.on(SIGNAL_TOKENS_DETAILS_ABOUT_TO_BE_UPDATED) do(e: Args):
57-
self.view.tokensDetailsAboutToUpdate()
5856
self.events.on(SIGNAL_TOKENS_DETAILS_UPDATED) do(e: Args):
5957
self.view.tokensDetailsUpdated()
6058
self.events.on(SIGNAL_TOKENS_MARKET_VALUES_ABOUT_TO_BE_UPDATED) do(e: Args):
@@ -103,7 +101,17 @@ method getTokenListsModelDataSource*(self: Module): TokenListsModelDataSource =
103101

104102
method getTokenGroupsModelDataSource*(self: Module): TokenGroupsModelDataSource =
105103
return (
106-
getAllTokenGroups: proc(): var seq[TokenGroupItem] = self.controller.getAllTokenGroups(),
104+
getAllTokenGroups: proc(): var seq[TokenGroupItem] = self.controller.getGroupsOfInterest(),
105+
getTokenDetails: proc(tokenKey: string): TokenDetailsItem = self.controller.getTokenDetails(tokenKey),
106+
getTokenPreferences: proc(groupKey: string): TokenPreferencesItem = self.controller.getTokenPreferences(groupKey),
107+
getCommunityTokenDescription: proc(chainId: int, address: string): string = self.controller.getCommunityTokenDescription(chainId, address),
108+
getTokensDetailsLoading: proc(): bool = self.controller.getTokensDetailsLoading(),
109+
getTokensMarketValuesLoading: proc(): bool = self.controller.getTokensMarketValuesLoading(),
110+
)
111+
112+
method getTokenGroupsForChainModelDataSource*(self: Module): TokenGroupsModelDataSource =
113+
return (
114+
getAllTokenGroups: proc(): var seq[TokenGroupItem] = self.controller.getGroupsForChain(),
107115
getTokenDetails: proc(tokenKey: string): TokenDetailsItem = self.controller.getTokenDetails(tokenKey),
108116
getTokenPreferences: proc(groupKey: string): TokenPreferencesItem = self.controller.getTokenPreferences(groupKey),
109117
getCommunityTokenDescription: proc(chainId: int, address: string): string = self.controller.getCommunityTokenDescription(chainId, address),
@@ -119,6 +127,9 @@ method getTokenMarketValuesDataSource*(self: Module): TokenMarketValuesDataSourc
119127
getTokensMarketValuesLoading: proc(): bool = self.controller.getTokensMarketValuesLoading(),
120128
)
121129

130+
method buildGroupsForChain*(self: Module, chainId: int) =
131+
self.controller.buildGroupsForChain(chainId)
132+
122133
method filterChanged*(self: Module, addresses: seq[string]) =
123134
if addresses == self.addresses:
124135
return

src/app/modules/main/wallet_section/all_tokens/token_groups_model.nim

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,21 @@ QtObject:
3030
tokensModel: TokensModel
3131
marketValuesDelegate: io_interface.TokenMarketValuesDataSource
3232
tokenMarketDetails: seq[MarketDetailsItem]
33+
allowEmptyMarketDetails: bool
3334

3435
proc setup(self: TokenGroupsModel)
3536
proc delete(self: TokenGroupsModel)
3637
proc newTokenGroupsModel*(
3738
delegate: io_interface.TokenGroupsModelDataSource,
38-
marketValuesDelegate: io_interface.TokenMarketValuesDataSource
39+
marketValuesDelegate: io_interface.TokenMarketValuesDataSource,
40+
allowEmptyMarketDetails: bool
3941
): TokenGroupsModel =
4042
new(result, delete)
4143
result.setup
4244
result.delegate = delegate
4345
result.marketValuesDelegate = marketValuesDelegate
4446
result.tokenMarketDetails = @[]
47+
result.allowEmptyMarketDetails = allowEmptyMarketDetails
4548

4649
method rowCount(self: TokenGroupsModel, index: QModelIndex = nil): int =
4750
return self.delegate.getAllTokenGroups().len
@@ -81,7 +84,7 @@ QtObject:
8184
if not index.isValid:
8285
return
8386
if index.row < 0 or index.row >= self.delegate.getAllTokenGroups().len or
84-
index.row >= self.tokenMarketDetails.len:
87+
(not self.allowEmptyMarketDetails and index.row >= self.tokenMarketDetails.len):
8588
return
8689

8790
let item = self.delegate.getAllTokenGroups()[index.row]
@@ -122,6 +125,8 @@ QtObject:
122125
let tokenKey = item.tokens[0].key
123126
return newQVariant(self.delegate.getTokenDetails(tokenKey).description)
124127
of ModelRole.MarketDetails:
128+
if self.allowEmptyMarketDetails:
129+
return newQVariant("")
125130
return newQVariant(self.tokenMarketDetails[index.row])
126131
of ModelRole.DetailsLoading:
127132
return newQVariant(self.delegate.getTokensDetailsLoading())
@@ -134,6 +139,11 @@ QtObject:
134139

135140
proc modelsUpdated*(self: TokenGroupsModel) =
136141
self.beginResetModel()
142+
defer: self.endResetModel()
143+
144+
if self.allowEmptyMarketDetails:
145+
return
146+
137147
self.tokenMarketDetails = @[]
138148
let tokensList = self.delegate.getAllTokenGroups()
139149
let currencyFormat = self.marketValuesDelegate.getCurrentCurrencyFormat()
@@ -145,9 +155,10 @@ QtObject:
145155
self.marketValuesDelegate.getMarketValuesForToken(tokenKey),
146156
currencyFormat)
147157
self.tokenMarketDetails.add(item)
148-
self.endResetModel()
149158

150159
proc tokensMarketValuesUpdated*(self: TokenGroupsModel) =
160+
if self.allowEmptyMarketDetails:
161+
return
151162
if not self.delegate.getTokensMarketValuesLoading():
152163
for marketDetails in self.tokenMarketDetails:
153164
marketDetails.updateTokenPrice(self.marketValuesDelegate.getPriceForToken(marketDetails.tokenKey))
@@ -162,15 +173,6 @@ QtObject:
162173
defer: lastindex.delete
163174
self.dataChanged(index, lastindex, @[ModelRole.MarketDetailsLoading.int])
164175

165-
proc tokensDetailsAboutToUpdate*(self: TokenGroupsModel) =
166-
let tokenGroupsListLength = self.delegate.getAllTokenGroups().len
167-
if tokenGroupsListLength > 0:
168-
let index = self.createIndex(0, 0, nil)
169-
let lastindex = self.createIndex(tokenGroupsListLength-1, 0, nil)
170-
defer: index.delete
171-
defer: lastindex.delete
172-
self.dataChanged(index, lastindex, @[ModelRole.Description.int, ModelRole.WebsiteUrl.int, ModelRole.DetailsLoading.int])
173-
174176
proc tokensDetailsUpdated*(self: TokenGroupsModel) =
175177
let tokenGroupsListLength = self.delegate.getAllTokenGroups().len
176178
if tokenGroupsListLength > 0:
@@ -181,6 +183,8 @@ QtObject:
181183
self.dataChanged(index, lastindex, @[ModelRole.Description.int, ModelRole.WebsiteUrl.int, ModelRole.DetailsLoading.int])
182184

183185
proc currencyFormatsUpdated*(self: TokenGroupsModel) =
186+
if self.allowEmptyMarketDetails:
187+
return
184188
let currencyFormat = self.marketValuesDelegate.getCurrentCurrencyFormat()
185189
for marketDetails in self.tokenMarketDetails:
186190
marketDetails.updateCurrencyFormat(currencyFormat)

src/app/modules/main/wallet_section/all_tokens/view.nim

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ QtObject:
99
marketHistoryIsLoading: bool
1010

1111
tokenListsModel: TokenListsModel
12-
tokenGroupsModel: TokenGroupsModel
12+
tokenGroupsModel: TokenGroupsModel # refers to tokens of interest for active networks mode
13+
tokenGroupsForChainModel: TokenGroupsModel # refers to all tokens for a specific chain
1314

1415
## Forward declaration
1516
proc modelsUpdated*(self: View)
@@ -23,12 +24,22 @@ QtObject:
2324
result.tokenListsModel = newTokenListsModel(delegate.getTokenListsModelDataSource())
2425
result.tokenGroupsModel = newTokenGroupsModel(
2526
delegate.getTokenGroupsModelDataSource(),
26-
delegate.getTokenMarketValuesDataSource())
27+
delegate.getTokenMarketValuesDataSource(),
28+
allowEmptyMarketDetails = false)
29+
result.tokenGroupsForChainModel = newTokenGroupsModel(
30+
delegate.getTokenGroupsForChainModelDataSource(),
31+
delegate.getTokenMarketValuesDataSource(),
32+
allowEmptyMarketDetails = true) # We allow empty market details for the tokenGroupsForChainModel, because it is
33+
# used for the swap input panel where market details are not needed, also updating it would be a performance bottleneck.
2734

2835
proc load*(self: View) =
2936
self.modelsUpdated()
3037
self.delegate.viewDidLoad()
3138

39+
proc buildGroupsForChain*(self: View, chainId: int) {.slot.} =
40+
self.delegate.buildGroupsForChain(chainId)
41+
self.tokenGroupsForChainModel.modelsUpdated()
42+
3243
proc marketHistoryIsLoadingChanged*(self: View) {.signal.}
3344
proc getMarketHistoryIsLoading(self: View): QVariant {.slot.} =
3445
return newQVariant(self.marketHistoryIsLoading)
@@ -67,6 +78,13 @@ QtObject:
6778
read = getTokenListsModel
6879
notify = tokenListsModelChanged
6980

81+
proc tokenGroupsForChainModelChanged*(self: View) {.signal.}
82+
proc getTokenGroupsForChainModel(self: View): QVariant {.slot.} =
83+
return newQVariant(self.tokenGroupsForChainModel)
84+
QtProperty[QVariant] tokenGroupsForChainModel:
85+
read = getTokenGroupsForChainModel
86+
notify = tokenGroupsForChainModelChanged
87+
7088
proc tokenGroupsModelChanged*(self: View) {.signal.}
7189
proc getTokenGroupsModel(self: View): QVariant {.slot.} =
7290
return newQVariant(self.tokenGroupsModel)
@@ -77,16 +95,14 @@ QtObject:
7795
proc modelsUpdated*(self: View) =
7896
self.tokenListsModel.modelsUpdated()
7997
self.tokenGroupsModel.modelsUpdated()
98+
self.tokenGroupsForChainModel.modelsUpdated()
8099

81100
proc tokensMarketValuesUpdated*(self: View) =
82101
self.tokenGroupsModel.tokensMarketValuesUpdated()
83102

84103
proc tokensMarketValuesAboutToUpdate*(self: View) =
85104
self.tokenGroupsModel.tokensMarketValuesAboutToUpdate()
86105

87-
proc tokensDetailsAboutToUpdate*(self: View) =
88-
self.tokenGroupsModel.tokensDetailsAboutToUpdate()
89-
90106
proc tokensDetailsUpdated*(self: View) =
91107
self.tokenGroupsModel.tokensDetailsUpdated()
92108

src/app/modules/main/wallet_section/assets/controller.nim

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ proc newController*(
2929
proc delete*(self: Controller) =
3030
discard
3131

32-
proc buildAllTokens*(self: Controller, addresses: seq[string]) =
33-
self.walletAccountService.buildAllTokens(addresses, forceRefresh = false)
34-
3532
proc init*(self: Controller) =
3633
let walletAddresses = self.walletAccountService.getWalletAddresses()
3734
discard

src/app/modules/main/wallet_section/assets/module.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,4 @@ method getGroupedAccountAssetsDataSource*(self: Module): GroupedAccountAssetsDat
7575
)
7676

7777
method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int]) =
78-
self.controller.buildAllTokens(addresses)
78+
discard

src/app_service/service/token/service.nim

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ QtObject:
4242
# local storage, fulfilled by need, empty at the start
4343
tokensForBridgingViaHop: Table[string, bool] # [tokenKey, bool]
4444
# local storage
45-
allTokensByKey: Table[string, TokenItem] # [tokenKey, TokenItem]
46-
allGroupsByKey: Table[string, TokenGroupItem] # [tokenGroupKey, TokenGroupItem]
47-
allGroups: seq[TokenGroupItem]
45+
tokensOfInterestByKey: Table[string, TokenItem] # [tokenKey, TokenItem]
46+
groupsOfInterestByKey: Table[string, TokenGroupItem] # [tokenGroupKey, TokenGroupItem]
47+
groupsOfInterest: seq[TokenGroupItem] # refers to groups for tokens of interest
48+
groupsForChain: seq[TokenGroupItem] # refers to groups for a specific chain
4849
allTokenLists: seq[TokenListItem] # TODO: remove this, fetch async when needed, don't store it
4950
tokenDetailsTable: Table[string, TokenDetailsItem] # [tokenKey, TokenDetailsItem]
5051
tokenMarketValuesTable: Table[string, TokenMarketValuesItem] # [tokenKey, TokenMarketValuesItem]
@@ -86,8 +87,8 @@ QtObject:
8687
result.networkService = networkService
8788
result.settingsService = settingsService
8889

89-
result.allTokensByKey = initTable[string, TokenItem]()
90-
result.allGroupsByKey = initTable[string, TokenGroupItem]()
90+
result.tokensOfInterestByKey = initTable[string, TokenItem]()
91+
result.groupsOfInterestByKey = initTable[string, TokenGroupItem]()
9192
result.tokenDetailsTable = initTable[string, TokenDetailsItem]()
9293
result.tokenMarketValuesTable = initTable[string, TokenMarketValuesItem]()
9394
result.tokenPriceTable = initTable[string, float64]()

src/app_service/service/token/service_main.nim

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,24 @@ proc rebuildMarketData*(self: Service) =
88
proc refreshTokens(self: Service) =
99
self.allTokenLists = getAllTokenLists()
1010

11-
self.allTokensByKey.clear()
12-
self.allGroupsByKey.clear()
13-
let allTokens = getTokensForActiveNetworksMode()
14-
for token in allTokens:
11+
# build groups of interest
12+
self.tokensOfInterestByKey.clear()
13+
self.groupsOfInterestByKey.clear()
14+
15+
var tokens = getTokensOfInterestForActiveNetworksMode()
16+
for token in tokens:
1517
let groupKey = token.groupKey
16-
self.allTokensByKey[token.key] = token
17-
if not self.allGroupsByKey.hasKey(groupKey):
18-
self.allGroupsByKey[groupKey] = TokenGroupItem(
18+
self.tokensOfInterestByKey[token.key] = token
19+
if not self.groupsOfInterestByKey.hasKey(groupKey):
20+
self.groupsOfInterestByKey[groupKey] = TokenGroupItem(
1921
key: groupKey,
2022
name: token.name,
2123
symbol: token.symbol,
2224
decimals: token.decimals,
2325
logoUri: token.logoUri
2426
)
25-
self.allGroupsByKey[groupKey].addToken(token)
26-
self.allGroups = toSeq(self.allGroupsByKey.values)
27+
self.groupsOfInterestByKey[groupKey].addToken(token)
28+
self.groupsOfInterest = toSeq(self.groupsOfInterestByKey.values)
2729

2830
self.rebuildMarketData()
2931
self.fetchTokensDetails() # TODO: if the only place where we can see these details is account's details page, we should fetch this on demand, no need to have local cache
@@ -37,7 +39,7 @@ proc init*(self: Service) =
3739
# this is the delay before the first call to the callback, this is an action that doesn't need to be called immediately, but it's pretty expensive in terms of time/performances
3840
# for example `wallet-tick-reload` event is emitted for every single chain-account pair, and at the app start can be more such signals received from the statusgo side if the balance have changed.
3941
# Means it the app contains more accounts the likelihood of having more `wallet-tick-reload` signals is higher, so we need to delay the rebuildMarketData call to avoid unnecessary calls.
40-
delayMs = 1500,
42+
delayMs = 1000,
4143
checkIntervalMs = 500)
4244
self.rebuildMarketDataDebouncer.registerCall0(callback = proc() = self.rebuildMarketDataInternal())
4345

@@ -61,8 +63,30 @@ proc init*(self: Service) =
6163
proc getCurrency*(self: Service): string =
6264
return self.settingsService.getCurrency()
6365

64-
proc getAllTokenGroups*(self: Service): var seq[TokenGroupItem] =
65-
return self.allGroups
66+
proc getGroupsOfInterest*(self: Service): var seq[TokenGroupItem] =
67+
return self.groupsOfInterest
68+
69+
proc buildGroupsForChain*(self: Service, chainId: int) =
70+
if chainId <= 0:
71+
warn "invalid chainId", chainId = chainId
72+
return
73+
var allTokens = getTokensByChain(chainId)
74+
var groupsByTokenKey = initTable[string, TokenGroupItem]()
75+
for token in allTokens:
76+
let groupKey = token.groupKey
77+
if not groupsByTokenKey.hasKey(groupKey):
78+
groupsByTokenKey[groupKey] = TokenGroupItem(
79+
key: groupKey,
80+
name: token.name,
81+
symbol: token.symbol,
82+
decimals: token.decimals,
83+
logoUri: token.logoUri
84+
)
85+
groupsByTokenKey[groupKey].addToken(token)
86+
self.groupsForChain = toSeq(groupsByTokenKey.values)
87+
88+
proc getGroupsForChain*(self: Service): var seq[TokenGroupItem] =
89+
return self.groupsForChain
6690

6791
proc getAllTokenLists*(self: Service): var seq[TokenListItem] =
6892
return self.allTokenLists
@@ -76,22 +100,22 @@ proc getAllCommunityTokens*(self: Service): var seq[TokenItem] =
76100
proc getTokenByKey*(self: Service, key: string): TokenItem =
77101
if key.isEmptyOrWhitespace or not key.toLower.contains("-0x"):
78102
return nil
79-
if self.allTokensByKey.hasKey(key):
80-
return self.allTokensByKey[key]
103+
if self.tokensOfInterestByKey.hasKey(key):
104+
return self.tokensOfInterestByKey[key]
81105
let tokens = getTokensByKeys(@[key])
82106
if tokens.len > 0:
83-
self.allTokensByKey[key] = tokens[0]
84-
return self.allTokensByKey[key]
107+
self.tokensOfInterestByKey[key] = tokens[0]
108+
return self.tokensOfInterestByKey[key]
85109
return nil
86110

87111
proc getTokenByChainAddress*(self: Service, chainId: int, address: string): TokenItem =
88112
let key = common_utils.createTokenKey(chainId, address)
89113
return self.getTokenByKey(key)
90114

91115
proc getTokensByGroupKey*(self: Service, groupKey: string): seq[TokenItem] =
92-
if not self.allGroupsByKey.hasKey(groupKey):
116+
if not self.groupsOfInterestByKey.hasKey(groupKey):
93117
return @[]
94-
return self.allGroupsByKey[groupKey].tokens
118+
return self.groupsOfInterestByKey[groupKey].tokens
95119

96120
proc getTokenByGroupKeyAndChainId*(self: Service, groupKey: string, chainId: int): TokenItem =
97121
let tokens = self.getTokensByGroupKey(groupKey)
@@ -146,9 +170,9 @@ proc updateTokenPrices*(self: Service, updatedPrices: Table[string, float64]) =
146170
self.events.emit(SIGNAL_TOKENS_PRICES_UPDATED, Args())
147171

148172
proc addNewCommunityToken*(self: Service, token: TokenItem) =
149-
if self.allGroupsByKey.hasKey(token.groupKey):
150-
let tokens = self.allGroupsByKey[token.groupKey].tokens
173+
if self.groupsOfInterestByKey.hasKey(token.groupKey):
174+
let tokens = self.groupsOfInterestByKey[token.groupKey].tokens
151175
for t in tokens:
152176
if t.key == token.key:
153177
return
154-
self.refreshTokens()
178+
self.refreshTokens()

0 commit comments

Comments
 (0)