Skip to content

Commit 4f65b2d

Browse files
committed
fix: account list coa account display
1 parent 39fd96f commit 4f65b2d

File tree

1 file changed

+96
-12
lines changed

1 file changed

+96
-12
lines changed

app/src/main/java/com/flowfoundation/wallet/page/account/AccountListViewModel.kt

Lines changed: 96 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@ import com.flowfoundation.wallet.manager.walletdata.COAWallet
1313
import com.flowfoundation.wallet.manager.walletdata.ChildWallet
1414
import com.flowfoundation.wallet.manager.walletdata.EOAWallet
1515
import com.flowfoundation.wallet.manager.walletdata.FlowWallet
16+
import com.flowfoundation.wallet.network.ApiService
17+
import com.flowfoundation.wallet.network.retrofitApi
1618
import com.flowfoundation.wallet.page.main.model.WalletAccountData
1719
import com.flowfoundation.wallet.page.main.model.LinkedAccountData
1820
import com.flowfoundation.wallet.utils.formatLargeBalanceNumber
1921
import com.flowfoundation.wallet.utils.ioScope
2022
import kotlinx.coroutines.flow.MutableStateFlow
2123
import kotlinx.coroutines.flow.StateFlow
2224
import kotlinx.coroutines.flow.asStateFlow
25+
import java.math.BigDecimal
2326

2427
class AccountListViewModel : ViewModel(), OnEmojiUpdate {
2528

@@ -32,6 +35,11 @@ class AccountListViewModel : ViewModel(), OnEmojiUpdate {
3235
private val _hiddenAccounts = MutableStateFlow<Set<String>>(emptySet())
3336
val hiddenAccounts: StateFlow<Set<String>> = _hiddenAccounts.asStateFlow()
3437

38+
private val service by lazy { retrofitApi().create(ApiService::class.java) }
39+
40+
// Cache for verified EVM addresses that should be included in linkedAccounts
41+
private val verifiedEvmAddresses = mutableSetOf<String>()
42+
3543
init {
3644
AccountEmojiManager.addListener(this)
3745
}
@@ -47,6 +55,7 @@ class AccountListViewModel : ViewModel(), OnEmojiUpdate {
4755

4856
val addressList = mutableListOf<String>()
4957
val accounts = mutableListOf<WalletAccountData>()
58+
val pendingEvmAddresses = mutableListOf<Pair<String, String>>() // EVM address to wallet address mapping
5059

5160
walletNodes.forEach { mainNode ->
5261
when (mainNode) {
@@ -86,17 +95,22 @@ class AccountListViewModel : ViewModel(), OnEmojiUpdate {
8695
is COAWallet -> {
8796
val evmAddress = linkedWallet.address
8897
addressList.add(evmAddress)
89-
val linkedEmojiInfo = AccountEmojiManager.getEmojiByAddress(evmAddress)
90-
linkedAccounts.add(
91-
LinkedAccountData(
92-
address = evmAddress,
93-
name = linkedEmojiInfo.emojiName,
94-
icon = null,
95-
emojiId = linkedEmojiInfo.emojiId,
96-
isSelected = WalletManager.selectedWalletAddress().equals(evmAddress, ignoreCase = true),
97-
isCOAAccount = true
98+
// Restore logic: Only add if verified, otherwise add to pending
99+
if (evmAddress !in verifiedEvmAddresses) {
100+
pendingEvmAddresses.add(Pair(evmAddress, mainNode.address))
101+
} else {
102+
val linkedEmojiInfo = AccountEmojiManager.getEmojiByAddress(evmAddress)
103+
linkedAccounts.add(
104+
LinkedAccountData(
105+
address = evmAddress,
106+
name = linkedEmojiInfo.emojiName,
107+
icon = null,
108+
emojiId = linkedEmojiInfo.emojiId,
109+
isSelected = WalletManager.selectedWalletAddress().equals(evmAddress, ignoreCase = true),
110+
isCOAAccount = true
111+
)
98112
)
99-
)
113+
}
100114
}
101115
}
102116
}
@@ -131,18 +145,88 @@ class AccountListViewModel : ViewModel(), OnEmojiUpdate {
131145
}
132146

133147
if (refreshBalance) {
134-
fetchAllBalances(addressList)
148+
fetchAllBalances(addressList, pendingEvmAddresses)
135149
}
136150
}
137151
}
138152

139-
private fun fetchAllBalances(addressList: List<String>) {
153+
private fun fetchAllBalances(addressList: List<String>, pendingEvmAddresses: List<Pair<String, String>> = emptyList()) {
140154
ioScope {
141155
val balanceMap = cadenceGetAllFlowBalance(addressList) ?: return@ioScope
142156
val formattedBalanceMap = balanceMap.mapValues { (_, balance) ->
143157
"${balance.formatLargeBalanceNumber(isAbbreviation = true)} FLOW"
144158
}
145159
_balanceMap.value = formattedBalanceMap
160+
161+
// Check each pending EVM address
162+
pendingEvmAddresses.forEach { (evmAddress, walletAddress) ->
163+
val evmBalance = balanceMap[evmAddress]
164+
val hasBalance = evmBalance != null && evmBalance > BigDecimal.ZERO
165+
var hasNFTs = false
166+
167+
if (!hasBalance) {
168+
try {
169+
val nftResponse = service.getEVMNFTCollections(evmAddress)
170+
val totalNftCount = nftResponse.data?.sumOf { it.count ?: 0 } ?: 0
171+
hasNFTs = nftResponse.data?.isNotEmpty() == true && totalNftCount > 0
172+
} catch (e: Exception) {
173+
// Ignore NFT API errors
174+
}
175+
}
176+
177+
if (hasBalance || hasNFTs) {
178+
// Add EVM address to linked accounts
179+
val currentAccounts = _accounts.value.toMutableList()
180+
val walletAccount = currentAccounts.find { it.address == walletAddress }
181+
walletAccount?.let { account ->
182+
// Check if EVM address already exists in linked accounts
183+
val alreadyExists = account.linkedAccounts.any { it.address == evmAddress }
184+
if (!alreadyExists) {
185+
val emojiInfo = AccountEmojiManager.getEmojiByAddress(evmAddress)
186+
val updatedLinkedAccounts = account.linkedAccounts.toMutableList()
187+
updatedLinkedAccounts.add(
188+
LinkedAccountData(
189+
address = evmAddress,
190+
name = emojiInfo.emojiName,
191+
icon = null,
192+
emojiId = emojiInfo.emojiId,
193+
isSelected = WalletManager.selectedWalletAddress().equals(evmAddress, ignoreCase = true),
194+
isCOAAccount = true
195+
)
196+
)
197+
val updatedAccount = account.copy(linkedAccounts = updatedLinkedAccounts)
198+
val accountIndex = currentAccounts.indexOfFirst { it.address == walletAddress }
199+
if (accountIndex >= 0) {
200+
currentAccounts[accountIndex] = updatedAccount
201+
_accounts.value = currentAccounts
202+
}
203+
}
204+
// Add to verified cache for future refreshWalletList calls
205+
verifiedEvmAddresses.add(evmAddress)
206+
}
207+
} else {
208+
// Remove EVM address from linked accounts if it no longer has assets
209+
// (Though typically it wouldn't be there yet if it was pending,
210+
// this handles the case where it might have been removed or balance drained)
211+
val currentAccounts = _accounts.value.toMutableList()
212+
val walletAccount = currentAccounts.find { it.address == walletAddress }
213+
walletAccount?.let { account ->
214+
val existingLinkedAccount = account.linkedAccounts.find { it.address == evmAddress }
215+
if (existingLinkedAccount != null) {
216+
val updatedLinkedAccounts = account.linkedAccounts.toMutableList()
217+
updatedLinkedAccounts.removeAll { it.address == evmAddress }
218+
val updatedAccount = account.copy(linkedAccounts = updatedLinkedAccounts)
219+
val accountIndex = currentAccounts.indexOfFirst { it.address == walletAddress }
220+
if (accountIndex >= 0) {
221+
currentAccounts[accountIndex] = updatedAccount
222+
_accounts.value = currentAccounts
223+
}
224+
}
225+
}
226+
// Remove from verified cache
227+
verifiedEvmAddresses.remove(evmAddress)
228+
}
229+
}
146230
}
147231
}
148232

0 commit comments

Comments
 (0)