Skip to content

Commit

Permalink
feat: add aggregate SIP-10 balances to home screen, ref LEA-1726
Browse files Browse the repository at this point in the history
  • Loading branch information
pete-watters committed Jan 17, 2025
1 parent 25a037a commit b89614b
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 13 deletions.
4 changes: 4 additions & 0 deletions apps/mobile/src/components/widgets/tokens/tokens-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export function AllAccountBalances() {
<BitcoinBalance />
<StacksBalance />
<Sip10Balance />
{/* TODO:
- need to limit to 5 items here, maybe use a size? or else limit to 3 SIP10s for now
- RunesBalance
*/}
</>
);
}
Expand Down
24 changes: 11 additions & 13 deletions apps/mobile/src/features/balances/stacks/sip10-balance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,17 @@ export function Sip10Balance() {
// TODO: handle balance loading & error states
if (data.state !== 'success') return;

return data.value?.addressBalances.map(balances =>
balances.sip10s.map((balance, index) => (
<Sip10TokenBalance
key={`${balance.asset.symbol}-${index}`}
symbol={balance.asset.symbol}
name={balance.asset.name}
availableBalance={balance.sip10.availableBalance}
fiatBalance={balance.usd.totalBalance}
px="5"
py="3"
/>
))
);
return data.value?.aggregateBalances.map((balance, index) => (
<Sip10TokenBalance
key={`${balance.asset.symbol}-${index}`}
symbol={balance.asset.symbol}
name={balance.asset.name}
availableBalance={balance.sip10.availableBalance}
fiatBalance={balance.usd.totalBalance}
px="5"
py="3"
/>
));
}
interface Sip10BalanceByAccountProps {
accountIndex: number;
Expand Down
5 changes: 5 additions & 0 deletions packages/services/src/balances/sip10-balances.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { Sip10AssetService } from '../assets/sip10-asset.service';
import { HiroStacksApiClient } from '../infrastructure/api/hiro/hiro-stacks-api.client';
import { MarketDataService } from '../market-data/market-data.service';
import { getAggregateSip10Balances } from './sip10-balances.utils';

export interface Sip10AssetBalance {
asset: Sip10CryptoAssetInfo;
Expand All @@ -25,6 +26,7 @@ export interface Sip10AddressBalance {
export interface Sip10AggregateBalance {
usd: CryptoAssetBalance;
addressBalances: Sip10AddressBalance[];
aggregateBalances: Sip10AssetBalance[];
}

export interface Sip10BalancesService {
Expand All @@ -50,7 +52,10 @@ export function createSip10BalancesService(
const totalUsdBalance = aggregateBaseCryptoAssetBalances(addressBalances.map(r => r.usd));
return {
usd: totalUsdBalance,
// TODO: ask Alex about removing this as we don't use it now
// maybe it is caching in the query for single account?
addressBalances,
aggregateBalances: getAggregateSip10Balances(addressBalances),
};
}

Expand Down
53 changes: 53 additions & 0 deletions packages/services/src/balances/sip10-balances.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { BaseCryptoAssetBalance } from '@leather.io/models';
import { sumMoney } from '@leather.io/utils';

import { Sip10AssetBalance } from './sip10-balances.service';

interface SumBaseCryptoAssetBalance {
initialBalance: BaseCryptoAssetBalance;
accumulatedBalance: BaseCryptoAssetBalance;
}

function sumBalances({
initialBalance,
accumulatedBalance,
}: SumBaseCryptoAssetBalance): BaseCryptoAssetBalance {
return {
...initialBalance,
totalBalance: sumMoney([initialBalance.totalBalance, accumulatedBalance.totalBalance]),
inboundBalance: sumMoney([initialBalance.inboundBalance, accumulatedBalance.inboundBalance]),
outboundBalance: sumMoney([initialBalance.outboundBalance, accumulatedBalance.outboundBalance]),
pendingBalance: sumMoney([initialBalance.pendingBalance, accumulatedBalance.pendingBalance]),
availableBalance: sumMoney([
initialBalance.availableBalance,
accumulatedBalance.availableBalance,
]),
};
}

export function getAggregateSip10Balances(
addressBalances: { sip10s: Sip10AssetBalance[] }[]
): Sip10AssetBalance[] {
return addressBalances
.flatMap(entry => entry.sip10s)
.reduce((acc, balance) => {
const existingBalance = acc.find(b => b.asset.symbol === balance.asset.symbol);
if (existingBalance) {
existingBalance.sip10 = sumBalances({
initialBalance: existingBalance.sip10,
accumulatedBalance: balance.sip10,
});
existingBalance.usd = sumBalances({
initialBalance: existingBalance.usd,
accumulatedBalance: balance.usd,
});
} else {
acc.push({
asset: balance.asset,
sip10: balance.sip10,
usd: balance.usd,
});
}
return acc;
}, [] as Sip10AssetBalance[]);
}

0 comments on commit b89614b

Please sign in to comment.