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: balances service, closes LEA-1707 LEA-1793 LEA-1761 #671

Merged
merged 1 commit into from
Dec 3, 2024

Conversation

alexp3y
Copy link
Contributor

@alexp3y alexp3y commented Dec 2, 2024

Implements a BTC balance service and applies it in mobile.

  • BTC balances include the total of both the Segwit + Taproot account.
  • Service does not yet filter out pending balances or protected balances (inscriptions, runes, etc..).
  • Uneconomical balances are filtered out using a basic/temporary rule of <10k sats.
  • Includes rework to CryptoAssetBalance model.
  • Creates a new LeatherApiClient
  • Closes LEA-1793
  • Closes LEA-1761

We will continue to extend service-based balances functionality from here, including the incorporation of STX and other asset balances, and additional UTXO filtering logic.

A modest reorganization of the CryptoAssetBalance model is included to move globally shared sub-balance fields (total, inbound, outbound, pending, available) to the base entity, and keep only asset-specific sub-balances on child entities e.g. (BTC -> protected, uneconomical) and (STX -> locked, unlocked, availableUnlocked).

Issue LEA-1793 has been corrected incidentally by refactoring to use the new BTC balance service.

This also fixes the Market Data decimal precision issue LEA-1761. We represent all balance amounts in the smallest unit of the currency (sats, cents, etc..). The fix ensures that native asset pricing information fetched by third-party API (usually represented in USD) are faithfully converted to cents in the MarketDataService.

Copy link

codecov bot commented Dec 2, 2024

Codecov Report

Attention: Patch coverage is 1.58730% with 248 lines in your changes missing coverage. Please review.

Project coverage is 29.29%. Comparing base (44fd6cf) to head (052f083).
Report is 4 commits behind head on dev.

Files with missing lines Patch % Lines
.../services/src/balances/bitcoin-balances.service.ts 0.00% 67 Missing ⚠️
packages/utils/src/assets/balance-helpers.ts 6.66% 56 Missing ⚠️
packages/services/src/inversify.config.ts 0.00% 29 Missing ⚠️
...c/infrastructure/api/leather/leather-api.client.ts 0.00% 23 Missing ⚠️
...infrastructure/api/hiro/hiro-request-priorities.ts 0.00% 21 Missing ⚠️
.../infrastructure/api/hiro/hiro-stacks-api.client.ts 0.00% 16 Missing ⚠️
...es/services/src/balances/bitcoin-balances.utils.ts 0.00% 12 Missing ⚠️
...rc/infrastructure/api/hiro/hiro-leather-headers.ts 0.00% 9 Missing ⚠️
...es/services/src/market-data/market-data.service.ts 0.00% 7 Missing ⚠️
packages/services/src/index.ts 0.00% 2 Missing ⚠️
... and 5 more
Additional details and impacted files
@@            Coverage Diff             @@
##              dev     #671      +/-   ##
==========================================
- Coverage   30.25%   29.29%   -0.97%     
==========================================
  Files         177      185       +8     
  Lines        6924     7165     +241     
  Branches      471      478       +7     
==========================================
+ Hits         2095     2099       +4     
- Misses       4829     5066     +237     
Files with missing lines Coverage Δ
...c/infrastructure/api/hiro/hiro-stacks-api.utils.ts 0.00% <ø> (ø)
packages/utils/src/index.ts 31.37% <ø> (ø)
packages/query/src/bitcoin/runes/runes.utils.ts 10.00% <0.00%> (ø)
...uery/src/bitcoin/stamps/stamps-by-address.hooks.ts 0.00% <0.00%> (ø)
...kages/query/src/stacks/stx20/stx20-tokens.hooks.ts 0.00% <0.00%> (ø)
...a/fungible-tokens/fungible-token-metadata.hooks.ts 0.00% <0.00%> (ø)
packages/services/src/index.ts 0.00% <0.00%> (ø)
...vices/src/infrastructure/cache/http-cache.utils.ts 0.00% <0.00%> (ø)
...es/services/src/market-data/market-data.service.ts 0.00% <0.00%> (ø)
...rc/infrastructure/api/hiro/hiro-leather-headers.ts 0.00% <0.00%> (ø)
... and 7 more
Components Coverage Δ
bitcoin 72.90% <ø> (ø)
query 12.65% <0.00%> (ø)
utils 44.60% <6.66%> (-4.59%) ⬇️
crypto 68.21% <ø> (ø)
stacks 72.68% <ø> (ø)

return useQueries({ queries, combine });
const { isLoading, data } = useBtcBalanceQuery(descriptors);
return {
availableBalance: !isLoading && data ? data.balanceBtc.availableBalance : createMoney(0, 'BTC'),
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we return null / undefined here if !data?

We need to get rid of these 0 balance fallbacks and handle them more gracefully, only showing 0 if we have data and it is 0

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@pete-watters Because the output of this query is already being used in several places, all of which would need to be refactored to accept and propogate Money | null, maybe this is better-suited for a follow-on where we can rethink how to propogate loading states (or nulls) into balance components?

Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds fine with me, just wanted to mention it. It can be tackled in https://linear.app/leather-io/issue/LEA-1726/handle-balance-loading-state-elegantly

@alexp3y alexp3y marked this pull request as ready for review December 2, 2024 10:54
@alexp3y alexp3y changed the title feat: balances service feat: balances service, closes LEA-1707 LEA-1793 LEA-1761 Dec 2, 2024
Copy link

linear bot commented Dec 2, 2024

protectedBalanceBtc,
uneconomicalBalanceBtc
),
balanceUsd: createBtcCryptoAssetBalance(
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we know for sure that we always want the fiat balance in USD? I know we have a settings pref for conversion unit, so are we intending for this to be customizable?

Copy link
Contributor

Choose a reason for hiding this comment

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

In the future we want to support multi currencies but that setting is not connected yet and I started deliberately labelling balances with USD to make this clearer as in i18nFormatCurrency we have it hardcoded to only accept USD anyway:

export function i18nFormatCurrency(quantity: Money, decimals: number = 2) {
  if (quantity.symbol !== 'USD') throw new Error('Cannot format non-USD amounts');
  const currencyFormatter = new Intl.NumberFormat('en-US', {

I agree it should be more scalable and offer alternative currencies but that's a whole other initiative and for now I think balanceUsd is more apt as it can't be anything else

Copy link
Contributor

Choose a reason for hiding this comment

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

@alexp3y - is the market data currently only supporting USD anyway?

Just thinking we could add a project for updating both extension + mobile to support multi currency in the future. (Probably far in the future)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@fbwoolf @pete-watters At the moment, yeah. USD is the default (and sometimes only) option returned by the pricing APIs used by MarketDataService, so I didn't add support for customisation.

When I go through the rest of the balances work I'll investigate and spec out what it will take to accommodate the fiat preference setting in @leather.io/services (i.e. balances and market data).

Copy link
Contributor

@pete-watters pete-watters left a comment

Choose a reason for hiding this comment

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

Great work here @alexp3y 🎉

It would be good to add some unit tests while things are fresh in your mind but I'm happy to merge as is and add those when migrating Stacks balances here.

For now this is a big improvement so I think we should merge include it to a release candidate for Leatherhood

@alexp3y alexp3y added this pull request to the merge queue Dec 3, 2024
Merged via the queue into dev with commit 85e13f0 Dec 3, 2024
13 checks passed
@alexp3y alexp3y deleted the feat/balance-service branch December 3, 2024 10:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants