Skip to content

Commit

Permalink
bitcoin balance fetching
Browse files Browse the repository at this point in the history
  • Loading branch information
nuo-xu committed Apr 17, 2024
1 parent 1e129aa commit 04c2f87
Show file tree
Hide file tree
Showing 17 changed files with 750 additions and 210 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ struct Filters {
Preferences.Wallet.nonSelectedAccountsFilter.value =
accounts
.filter({ !$0.isSelected })
.map(\.model.address)
.map(\.model.filterAccountKey)
Preferences.Wallet.nonSelectedNetworksFilter.value =
networks
.filter({ !$0.isSelected })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class AccountActivityStore: ObservableObject, WalletObserverStore {
private let blockchainRegistry: BraveWalletBlockchainRegistry
private let solTxManagerProxy: BraveWalletSolanaTxManagerProxy
private let ipfsApi: IpfsAPI
private let bitcoinWalletService: BraveWalletBitcoinWalletService
private let assetManager: WalletUserAssetManagerType
/// Cache for storing `BlockchainToken`s that are not in user assets or our token registry.
/// This could occur with a dapp creating a transaction.
Expand Down Expand Up @@ -75,6 +76,7 @@ class AccountActivityStore: ObservableObject, WalletObserverStore {
blockchainRegistry: BraveWalletBlockchainRegistry,
solTxManagerProxy: BraveWalletSolanaTxManagerProxy,
ipfsApi: IpfsAPI,
bitcoinWalletService: BraveWalletBitcoinWalletService,
userAssetManager: WalletUserAssetManagerType
) {
self.account = account
Expand All @@ -88,6 +90,7 @@ class AccountActivityStore: ObservableObject, WalletObserverStore {
self.blockchainRegistry = blockchainRegistry
self.solTxManagerProxy = solTxManagerProxy
self.ipfsApi = ipfsApi
self.bitcoinWalletService = bitcoinWalletService
self.assetManager = userAssetManager
self._isSwapSupported = .init(
wrappedValue: account.coin == .eth || account.coin == .sol
Expand Down Expand Up @@ -223,10 +226,25 @@ class AccountActivityStore: ObservableObject, WalletObserverStore {
)

self.isLoadingAccountFiat = true
let tokenBalances = await self.rpcService.fetchBalancesForTokens(
account: account,
networkAssets: allUserNetworkAssets
)
var tokenBalances: [String: Double] = [:]
if account.coin == .btc {
let networkAsset = allUserNetworkAssets.first {
$0.network.supportedKeyrings.contains(account.keyringId.rawValue as NSNumber)
}
if let btc = networkAsset?.tokens.first,
let btcBalance = await self.bitcoinWalletService.fetchBTCBalance(
accountId: account.accountId
)
{
tokenBalances = [btc.id: btcBalance]
}
} else {
tokenBalances = await self.rpcService.fetchBalancesForTokens(
account: account,
networkAssets: allUserNetworkAssets
)
tokenBalanceCache.merge(with: tokenBalances)
}
tokenBalanceCache.merge(with: tokenBalances)

// fetch price for every user asset
Expand Down
43 changes: 30 additions & 13 deletions ios/brave-ios/Sources/BraveWallet/Crypto/Stores/AccountsStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class AccountsStore: ObservableObject, WalletObserverStore {

let currencyFormatter: NumberFormatter = .usdCurrencyFormatter

/// Cache of token balances for each account. [account.address: [token.id: balance]]
/// Cache of token balances for each account. [account.cacheBalanceKey: [token.id: balance]]
private var tokenBalancesCache: [String: [String: Double]] = [:]
/// Cache of prices for each token. The key is the token's `assetRatioId`.
private var pricesCache: [String: String] = [:]
Expand All @@ -42,6 +42,7 @@ class AccountsStore: ObservableObject, WalletObserverStore {
private let rpcService: BraveWalletJsonRpcService
private let walletService: BraveWalletBraveWalletService
private let assetRatioService: BraveWalletAssetRatioService
private let bitcoinWalletService: BraveWalletBitcoinWalletService
private let userAssetManager: WalletUserAssetManagerType

private var keyringServiceObserver: KeyringServiceObserver?
Expand All @@ -56,12 +57,14 @@ class AccountsStore: ObservableObject, WalletObserverStore {
rpcService: BraveWalletJsonRpcService,
walletService: BraveWalletBraveWalletService,
assetRatioService: BraveWalletAssetRatioService,
bitcoinWalletService: BraveWalletBitcoinWalletService,
userAssetManager: WalletUserAssetManagerType
) {
self.keyringService = keyringService
self.rpcService = rpcService
self.walletService = walletService
self.assetRatioService = assetRatioService
self.bitcoinWalletService = bitcoinWalletService
self.userAssetManager = userAssetManager
self.setupObservers()
}
Expand Down Expand Up @@ -143,11 +146,25 @@ class AccountsStore: ObservableObject, WalletObserverStore {
body: { group in
for account in accounts {
group.addTask {
let balancesForTokens: [String: Double] = await self.rpcService.fetchBalancesForTokens(
account: account,
networkAssets: allNetworkAssets
)
return [account.address: balancesForTokens]
var balancesForTokens: [String: Double] = [:]
if account.coin == .btc {
let networkAssets = allNetworkAssets.first {
$0.network.supportedKeyrings.contains(account.keyringId.rawValue as NSNumber)
}
if let btc = networkAssets?.tokens.first,
let btcBalance = await self.bitcoinWalletService.fetchBTCBalance(
accountId: account.accountId
)
{
balancesForTokens = [btc.id: btcBalance]
}
} else {
balancesForTokens = await self.rpcService.fetchBalancesForTokens(
account: account,
networkAssets: allNetworkAssets
)
}
return [account.cacheBalanceKey: balancesForTokens]
}
}
return await group.reduce(
Expand All @@ -159,13 +176,13 @@ class AccountsStore: ObservableObject, WalletObserverStore {
}
)
for account in accounts {
if let updatedBalancesForAccount = balancesForAccounts[account.address] {
if let updatedBalancesForAccount = balancesForAccounts[account.cacheBalanceKey] {
// if balance fetch failed that we already have cached, don't overwrite existing
if var existing = self.tokenBalancesCache[account.address] {
if var existing = self.tokenBalancesCache[account.cacheBalanceKey] {
existing.merge(with: updatedBalancesForAccount)
self.tokenBalancesCache[account.address] = existing
self.tokenBalancesCache[account.cacheBalanceKey] = existing
} else {
self.tokenBalancesCache[account.address] = updatedBalancesForAccount
self.tokenBalancesCache[account.cacheBalanceKey] = updatedBalancesForAccount
}
}
}
Expand Down Expand Up @@ -223,7 +240,7 @@ class AccountsStore: ObservableObject, WalletObserverStore {
for account: BraveWallet.AccountInfo,
tokens: [BraveWallet.BlockchainToken]
) -> [BraveWallet.BlockchainToken] {
guard let tokenBalancesForAccount = tokenBalancesCache[account.address] else {
guard let tokenBalancesForAccount = tokenBalancesCache[account.cacheBalanceKey] else {
return []
}
var tokensFiatForAccount: [(token: BraveWallet.BlockchainToken, fiat: Double)] = []
Expand All @@ -247,7 +264,7 @@ class AccountsStore: ObservableObject, WalletObserverStore {
for account: BraveWallet.AccountInfo,
tokens: [BraveWallet.BlockchainToken]
) -> Double {
guard let accountBalanceCache = tokenBalancesCache[account.address] else { return 0 }
guard let accountBalanceCache = tokenBalancesCache[account.cacheBalanceKey] else { return 0 }
return accountBalanceCache.keys.reduce(0.0) { partialResult, tokenId in
guard let tokenBalanceForAccount = tokenBalanceForAccount(tokenId: tokenId, account: account)
else {
Expand All @@ -271,7 +288,7 @@ class AccountsStore: ObservableObject, WalletObserverStore {
tokenId: String,
account: BraveWallet.AccountInfo
) -> Double? {
tokenBalancesCache[account.address]?[tokenId]
tokenBalancesCache[account.cacheBalanceKey]?[tokenId]
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class AssetDetailStore: ObservableObject, WalletObserverStore {
private let solTxManagerProxy: BraveWalletSolanaTxManagerProxy
private let ipfsApi: IpfsAPI
private let swapService: BraveWalletSwapService
private let bitcoinWalletService: BraveWalletBitcoinWalletService
private let assetManager: WalletUserAssetManagerType
/// A list of tokens that are supported with the current selected network for all supported
/// on-ramp providers.
Expand Down Expand Up @@ -138,6 +139,7 @@ class AssetDetailStore: ObservableObject, WalletObserverStore {
solTxManagerProxy: BraveWalletSolanaTxManagerProxy,
ipfsApi: IpfsAPI,
swapService: BraveWalletSwapService,
bitcoinWalletService: BraveWalletBitcoinWalletService,
userAssetManager: WalletUserAssetManagerType,
assetDetailType: AssetDetailType
) {
Expand All @@ -150,6 +152,7 @@ class AssetDetailStore: ObservableObject, WalletObserverStore {
self.solTxManagerProxy = solTxManagerProxy
self.ipfsApi = ipfsApi
self.swapService = swapService
self.bitcoinWalletService = bitcoinWalletService
self.assetManager = userAssetManager
self.assetDetailType = assetDetailType

Expand Down Expand Up @@ -456,19 +459,26 @@ class AssetDetailStore: ObservableObject, WalletObserverStore {
@MainActor group -> [AccountBalance] in
for accountAssetViewModel in accountAssetViewModels {
group.addTask { @MainActor in
let balance = await self.rpcService.balance(
for: token,
in: accountAssetViewModel.account,
network: network
)
return [AccountBalance(accountAssetViewModel.account, balance)]
var tokenBalance: Double?
if accountAssetViewModel.account.coin == .btc {
tokenBalance = await self.bitcoinWalletService.fetchBTCBalance(
accountId: accountAssetViewModel.account.accountId
)
} else {
tokenBalance = await self.rpcService.balance(
for: token,
in: accountAssetViewModel.account,
network: network
)
}
return [AccountBalance(accountAssetViewModel.account, tokenBalance)]
}
}
return await group.reduce([AccountBalance](), { $0 + $1 })
}
for tokenBalance in tokenBalances {
if let index = accountAssetViewModels.firstIndex(where: {
$0.account.address == tokenBalance.account.address
$0.account.cacheBalanceKey == tokenBalance.account.cacheBalanceKey
}) {
accountAssetViewModels[index].decimalBalance = tokenBalance.balance ?? 0.0
accountAssetViewModels[index].balance = String(format: "%.4f", tokenBalance.balance ?? 0.0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ public class CryptoStore: ObservableObject, WalletObserverStore {
keyringService: keyringService,
rpcService: rpcService,
walletService: walletService,
txService: txService
txService: txService,
bitcoinWalletService: bitcoinWalletService
)
self.origin = origin

Expand All @@ -184,6 +185,7 @@ public class CryptoStore: ObservableObject, WalletObserverStore {
assetRatioService: assetRatioService,
blockchainRegistry: blockchainRegistry,
ipfsApi: ipfsApi,
bitcoinWalletService: bitcoinWalletService,
userAssetManager: userAssetManager
)
self.nftStore = .init(
Expand Down Expand Up @@ -213,6 +215,7 @@ public class CryptoStore: ObservableObject, WalletObserverStore {
rpcService: rpcService,
walletService: walletService,
assetRatioService: assetRatioService,
bitcoinWalletService: bitcoinWalletService,
userAssetManager: userAssetManager
)
self.marketStore = .init(
Expand Down Expand Up @@ -504,6 +507,7 @@ public class CryptoStore: ObservableObject, WalletObserverStore {
solTxManagerProxy: solTxManagerProxy,
ipfsApi: ipfsApi,
swapService: swapService,
bitcoinWalletService: bitcoinWalletService,
userAssetManager: userAssetManager,
assetDetailType: assetDetailType
)
Expand Down Expand Up @@ -541,6 +545,7 @@ public class CryptoStore: ObservableObject, WalletObserverStore {
blockchainRegistry: blockchainRegistry,
solTxManagerProxy: solTxManagerProxy,
ipfsApi: ipfsApi,
bitcoinWalletService: bitcoinWalletService,
userAssetManager: userAssetManager
)
accountActivityStore = store
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ public class NFTStore: ObservableObject, WalletObserverStore {
return Filters(
accounts: allAccounts.map { account in
.init(
isSelected: !nonSelectedAccountAddresses.contains(where: { $0 == account.address }),
isSelected: !nonSelectedAccountAddresses.contains(where: {
$0 == account.filterAccountKey
}),
model: account
)
},
Expand Down
Loading

0 comments on commit 04c2f87

Please sign in to comment.