Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(wallet): Bitcoin Balance Fetching #23117

Merged
merged 3 commits into from
Apr 22, 2024
Merged

Conversation

nuo-xu
Copy link
Contributor

@nuo-xu nuo-xu commented Apr 17, 2024

Resolves brave/brave-browser#36966

iOS starts fetching bitcoin balance for bitcoin accounts both mainnet and testnet usingBraveWalletBitcoinWalletService
Wallet will display using availableBalance. pendingBalance UI will be handled in brave/brave-browser#37640

Submitter Checklist:

  • I confirm that no security/privacy review is needed and no other type of reviews are needed, or that I have requested them
  • There is a ticket for my issue
  • Used Github auto-closing keywords in the PR description above
  • Wrote a good PR/commit description
  • Squashed any review feedback or "fixup" commits before merge, so that history is a record of what happened in the repo, not your PR
  • Added appropriate labels (QA/Yes or QA/No; release-notes/include or release-notes/exclude; OS/...) to the associated issue
  • Checked the PR locally:
    • npm run test -- brave_browser_tests, npm run test -- brave_unit_tests wiki
    • npm run presubmit wiki, npm run gn_check, npm run tslint
  • Ran git rebase master (if needed)

Reviewer Checklist:

  • A security review is not needed, or a link to one is included in the PR description
  • New files have MPL-2.0 license header
  • Adequate test coverage exists to prevent regressions
  • Major classes, functions and non-trivial code blocks are well-commented
  • Changes in component dependencies are properly reflected in gn
  • Code follows the style guide
  • Test plan is specified in PR before merging

After-merge Checklist:

Test Plan:

In order to test this PR, you need to set up a feature flag in two ways:

If you are building this PR locally on your Xcode, duplicate Debug scheme and add --enable-features=BraveWalletBitcoin in your Arguments Passed On Launch, then build.
If you are testing using a TF build. Add BraveWalletBitcoin under Settings/BraveCore Switches/Enable Features (Enable Enable Features and a fresh launch is required)

1. Check bitcoin balance displaying

Bitcoin balance will be displayed in

  1. wallet panel
  2. portfolio
  3. asset details
  4. accounts tab
  5. account details

you can either create a new bitcoin and check if balance is correctly displayed as $0.00
or you can restore a wallet with bitcoin accounts that have balances and check if balance is correctly displayed with the right amount.

2. Check bitcoin accounts in filter selection

  1. open brave wallet and create a wallet if you dont have any
  2. create multiple bitcoin account either on mainnet or testnet
  3. in Portfolio, select group by account, save changes
  4. observe portfolio is now displaying in group by account
  5. make some changes on bitcoin account selection in filter
  6. check if Portfolio display or hide bitcoin account correctly.

@nuo-xu nuo-xu added CI/skip-android Do not run CI builds for Android CI/skip-macos-x64 Do not run CI builds for macOS x64 CI/skip-windows-x64 Do not run CI builds for Windows x64 labels Apr 17, 2024
@nuo-xu nuo-xu force-pushed the wallet/ios-bitcoin-balance branch from f75f76b to efee4f6 Compare April 17, 2024 03:07
@nuo-xu nuo-xu force-pushed the wallet/ios-bitcoin-balance branch from efee4f6 to 04c2f87 Compare April 17, 2024 15:19
@nuo-xu nuo-xu marked this pull request as ready for review April 17, 2024 16:41
@nuo-xu nuo-xu requested a review from a team as a code owner April 17, 2024 16:41
}
}
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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not specific to Bitcoin, but we need to update balance to be a Double or BDouble on this view model and format as a String in UI code instead of view model. Right now the totalBalance computed property uses this string to calculate the total balance, but this value is rounded to 4 decimal places, however total balance is being displayed with 6 decimal places.
So if I have a balance of 0.00001 BTC it will show as 0.000000 BTC total balance.

Since this isn't specific to Bitcoin, I opened a separate issue for this rounding bug:
brave/brave-browser#37670

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is actually an idea somehere deep in backlog to return balance in weis, satoshis, lamports, etc. So any rounding happens only when we want to display that balance on screen.
Using double in money related ares is discouraged in general

Comment on lines 36 to 37
/// Cache of token balances for each account. [account.cacheBalanceKey: [token.id: balance]]
private var tokenBalancesCache: [String: [String: Double]] = [:]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a thing like branded types in typescrpit but for swift?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think thats typealias in swift. i will update. thanks!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nuo-xu I'm not sure a typealias would work the same here, maybe I am misunderstanding. A typealias would essentially be typealias TokenBalanceKey = String, but would only validate the type a String, not validate the key is the expected value/format (both address and accountId.uniqueKey are String type).

I think better approach for us would be

  1. dropping tokenBalancesCache from each store/view model & fetch from cache when balance is needed
    • Not sure we need to fetch from CoreData cache, then cache again in the store/view model. If we need in memory cache dictionary likely better in WalletUserAssetManager itself so all stores/view models can share it.
  2. Add helper methods as needed in WalletUserAssetManager which accept a BlockchainToken, AccountInfo, etc. so the cache manager itself has control of the keys used in the cache(s).
    • We already have some/most of these I believe

pseudocode:

func getBalances(for account: BraveWallet.AccountInfo) -> Double? {
    return balancesCache[account.accountId.uniqueKey]
}

Comment on lines 48 to 59
let availableSatoshiString = String(btcBalance.availableBalance)
let formatter = WeiFormatter(decimalFormatStyle: .decimals(precision: 8))
if let valueString = formatter.decimalString(
for: availableSatoshiString,
radix: .decimal,
decimals: 8
) {
return Double(valueString)
} else {
return nil
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In most contexts we need total balance, in a context of send screen we need available balance. For desktop ui there is also a popup which shows all three lines of complex BTC balance.
FYI

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i will update this using totalBalance. we have a separate issue to integrate bitcoin balance full info brave/brave-browser#37640
will keep in mind to use availableBalance in send tx.
thanks!

Copy link
Contributor

[puLL-Merge] - brave/brave-core@23117

Description

This PR updates the codebase to use account.accountId.uniqueKey (account.id) instead of account.address as the cache key for various account-related data. It also integrates fetching Bitcoin balances using the BraveWalletBitcoinWalletService.

Changes

Changes

  • FiltersDisplaySettingsView.swift: Update to use account.id instead of account.address when filtering non-selected accounts.
  • AccountActivityStore.swift, AccountsStore.swift, AssetDetailStore.swift, NFTDetailStore.swift, NFTStore.swift, PortfolioStore.swift, SelectAccountTokenStore.swift:
    • Update to use account.id as cache key instead of account.address for token balances and other account-related data.
    • Integrate fetching Bitcoin balances using BraveWalletBitcoinWalletService for Bitcoin accounts.
  • CryptoStore.swift: Pass bitcoinWalletService to various stores during initialization.
  • BitcoinWalletServiceExtensions.swift: Add fetchBTCBalance method to fetch BTC balance for a given account ID and balance type.
  • WalletPreferences.swift: Add migrateCacheKeyCompleted preference to track migration of cache key from account.address to account.id.
  • WalletUserAssetManager.swift:
    • Migrate cache key on keyring unlock if not already done.
    • Use BraveWalletBitcoinWalletService to fetch BTC balances for Bitcoin accounts.
  • WalletUserAssetBalance.swift: Add updateAccountAddress method to update accountAddress for a given account during migration.
  • Various test files: Update tests to use account.id and integrate Bitcoin balance fetching.

Security Hotspots

  1. Ensure that the migration from account.address to account.id is thoroughly tested and does not result in any data loss or inconsistencies. Verify that all relevant caches and preferences are properly migrated.
  2. Carefully review the integration of BraveWalletBitcoinWalletService to fetch Bitcoin balances. Ensure that the service is reliable, secure, and returns accurate balance data.
  3. Verify that the updated caching mechanism using account.id maintains data integrity and does not introduce any unintended side effects or performance issues.

@nuo-xu nuo-xu merged commit cb0f714 into master Apr 22, 2024
19 checks passed
@nuo-xu nuo-xu deleted the wallet/ios-bitcoin-balance branch April 22, 2024 20:08
@github-actions github-actions bot added this to the 1.67.x - Nightly milestone Apr 22, 2024
Copy link
Member

@kdenhartog kdenhartog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for post merge sec review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI/skip-android Do not run CI builds for Android CI/skip-macos-x64 Do not run CI builds for macOS x64 CI/skip-windows-x64 Do not run CI builds for Windows x64 puLL-Merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Wallet: Fetching Bitcoin Balance
4 participants