Skip to content

Commit

Permalink
refactor: remove combined asset model, closes #48
Browse files Browse the repository at this point in the history
  • Loading branch information
fbwoolf committed May 21, 2024
1 parent 9b77421 commit 2c2d61d
Show file tree
Hide file tree
Showing 78 changed files with 908 additions and 1,079 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
"@dlc-link/dlc-tools": "1.1.1",
"@fungible-systems/zone-file": "2.0.0",
"@hirosystems/token-metadata-api-client": "1.2.0",
"@leather-wallet/models": "0.4.5",
"@leather-wallet/models": "0.6.1",
"@leather-wallet/tokens": "0.0.15",
"@ledgerhq/hw-transport-webusb": "6.27.19",
"@noble/hashes": "1.3.2",
Expand Down
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 3 additions & 6 deletions src/app/common/hooks/balance/use-total-balance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function useTotalBalance({ btcAddress, stxAddress }: UseTotalBalanceArgs)

// get btc balance
const {
btcCryptoAssetBalance,
balance: btcBalance,
isLoading: isLoadingBtcBalance,
isFetching: isFetchingBtcBalance,
isInitialLoading: isInititalLoadingBtcBalance,
Expand All @@ -37,10 +37,7 @@ export function useTotalBalance({ btcAddress, stxAddress }: UseTotalBalanceArgs)
return useMemo(() => {
// calculate total balance
const stxUsdAmount = baseCurrencyAmountInQuote(stxBalance, stxMarketData);
const btcUsdAmount = baseCurrencyAmountInQuote(
btcCryptoAssetBalance.availableBalance,
btcMarketData
);
const btcUsdAmount = baseCurrencyAmountInQuote(btcBalance.availableBalance, btcMarketData);

const totalBalance = { ...stxUsdAmount, amount: stxUsdAmount.amount.plus(btcUsdAmount.amount) };
return {
Expand All @@ -56,7 +53,7 @@ export function useTotalBalance({ btcAddress, stxAddress }: UseTotalBalanceArgs)
}, [
stxBalance,
stxMarketData,
btcCryptoAssetBalance.availableBalance,
btcBalance.availableBalance,
btcMarketData,
isLoading,
isLoadingBtcBalance,
Expand Down
8 changes: 4 additions & 4 deletions src/app/components/balance/btc-balance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import { formatMoney } from '@app/common/money/format-money';
import { Caption } from '@app/ui/components/typography/caption';

import { BitcoinNativeSegwitAccountLoader } from '../loaders/bitcoin-account-loader';
import { BtcCryptoAssetLoader } from '../loaders/btc-crypto-asset-loader';
import { BtcBalanceLoader } from '../loaders/btc-balance-loader';

export function BtcBalance() {
return (
<BitcoinNativeSegwitAccountLoader current>
{signer => (
<BtcCryptoAssetLoader address={signer.address}>
{asset => <Caption>{formatMoney(asset.balance.availableBalance)}</Caption>}
</BtcCryptoAssetLoader>
<BtcBalanceLoader address={signer.address}>
{balance => <Caption>{formatMoney(balance.availableBalance)}</Caption>}
</BtcBalanceLoader>
)}
</BitcoinNativeSegwitAccountLoader>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
determineUtxosForSpendAll,
} from '@app/common/transactions/bitcoin/coinselect/local-coin-selection';
import { useCurrentNativeSegwitUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks';
import { useCurrentBtcAvailableBalanceNativeSegwit } from '@app/query/bitcoin/balance/btc-balance-native-segwit.hooks';
import { useCurrentBtcCryptoAssetBalanceNativeSegwit } from '@app/query/bitcoin/balance/btc-balance-native-segwit.hooks';
import { useCryptoCurrencyMarketDataMeanAverage } from '@app/query/common/market-data/market-data.hooks';

export const MAX_FEE_RATE_MULTIPLIER = 50;
Expand All @@ -22,15 +22,17 @@ interface UseBitcoinCustomFeeArgs {
}

export function useBitcoinCustomFee({ amount, isSendingMax, recipients }: UseBitcoinCustomFeeArgs) {
const { balance } = useCurrentBtcAvailableBalanceNativeSegwit();
const { balance } = useCurrentBtcCryptoAssetBalanceNativeSegwit();
const { data: utxos = [] } = useCurrentNativeSegwitUtxos();
const btcMarketData = useCryptoCurrencyMarketDataMeanAverage('BTC');

return useCallback(
(feeRate: number) => {
if (!feeRate || !utxos.length) return { fee: 0, fiatFeeValue: '' };

const satAmount = isSendingMax ? balance.amount.toNumber() : amount.amount.toNumber();
const satAmount = isSendingMax
? balance.availableBalance.amount.toNumber()
: amount.amount.toNumber();

const determineUtxosArgs = {
amount: satAmount,
Expand All @@ -49,6 +51,6 @@ export function useBitcoinCustomFee({ amount, isSendingMax, recipients }: UseBit
)}`,
};
},
[utxos, isSendingMax, balance.amount, amount.amount, recipients, btcMarketData]
[utxos, isSendingMax, balance.availableBalance.amount, amount.amount, recipients, btcMarketData]
);
}
10 changes: 6 additions & 4 deletions src/app/components/bitcoin-fees-list/use-bitcoin-fees-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
determineUtxosForSpend,
determineUtxosForSpendAll,
} from '@app/common/transactions/bitcoin/coinselect/local-coin-selection';
import { useCurrentBtcAvailableBalanceNativeSegwit } from '@app/query/bitcoin/balance/btc-balance-native-segwit.hooks';
import { useCurrentBtcCryptoAssetBalanceNativeSegwit } from '@app/query/bitcoin/balance/btc-balance-native-segwit.hooks';
import { UtxoResponseItem } from '@app/query/bitcoin/bitcoin-client';
import { useAverageBitcoinFeeRates } from '@app/query/bitcoin/fees/fee-estimates.hooks';
import { useCryptoCurrencyMarketDataMeanAverage } from '@app/query/common/market-data/market-data.hooks';
Expand Down Expand Up @@ -43,7 +43,7 @@ export function useBitcoinFeesList({
recipient,
utxos,
}: UseBitcoinFeesListArgs) {
const { balance } = useCurrentBtcAvailableBalanceNativeSegwit();
const { balance } = useCurrentBtcCryptoAssetBalanceNativeSegwit();
const btcMarketData = useCryptoCurrencyMarketDataMeanAverage('BTC');
const { data: feeRates, isLoading } = useAverageBitcoinFeeRates();

Expand All @@ -57,7 +57,9 @@ export function useBitcoinFeesList({
if (!feeRates || !utxos.length) return [];

const determineUtxosDefaultArgs = {
recipients: [{ address: recipient, amount: isSendingMax ? balance : amount }],
recipients: [
{ address: recipient, amount: isSendingMax ? balance.availableBalance : amount },
],
utxos,
};

Expand Down Expand Up @@ -116,7 +118,7 @@ export function useBitcoinFeesList({
}

return feesArr;
}, [feeRates, utxos, isSendingMax, balance, amount, recipient, btcMarketData]);
}, [feeRates, utxos, recipient, isSendingMax, balance.availableBalance, amount, btcMarketData]);

return {
feesList,
Expand Down
89 changes: 42 additions & 47 deletions src/app/components/crypto-asset-item/crypto-asset-item.layout.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { ReactNode } from 'react';

import type { CryptoAssetBalance } from '@leather-wallet/models';
import { Box, Flex, styled } from 'leather-styles/jsx';

import { spamFilter } from '@app/common/utils/spam-filter';
import type { AccountCryptoAssetWithDetails } from '@app/query/models/crypto-asset.model';
import { BulletSeparator } from '@app/ui/components/bullet-separator/bullet-separator';
import { ItemLayout } from '@app/ui/components/item-layout/item-layout';
import { SkeletonLoader } from '@app/ui/components/skeleton-loader/skeleton-loader';
Expand All @@ -14,81 +12,78 @@ import { Pressable } from '@app/ui/pressable/pressable';
import { parseCryptoAssetBalance } from './crypto-asset-item.layout.utils';

interface CryptoAssetItemLayoutProps {
additionalBalanceInfo?: ReactNode;
additionalBalanceInfoAsFiat?: ReactNode;
asset: AccountCryptoAssetWithDetails;
caption?: string;
balance: CryptoAssetBalance;
captionLeft: string;
captionRightBulletInfo?: React.ReactNode;
contractId?: string;
fiatBalance?: string;
icon: React.ReactNode;
isLoading?: boolean;
name: string;
onClick?(asset: AccountCryptoAssetWithDetails): void;
rightElement?: React.ReactNode;
onSelectAsset?(symbol: string, contractId?: string): void;
titleLeft: string;
titleRightBulletInfo?: React.ReactNode;
}
export function CryptoAssetItemLayout({
additionalBalanceInfo,
additionalBalanceInfoAsFiat,
asset,
caption,
balance,
captionLeft,
captionRightBulletInfo,
contractId,
fiatBalance,
icon,
isLoading = false,
name,
onClick,
rightElement,
onSelectAsset,
titleLeft,
titleRightBulletInfo,
}: CryptoAssetItemLayoutProps) {
const { dataTestId, formattedBalance } = parseCryptoAssetBalance(asset.balance);
const { availableBalance } = asset.balance;
const title = spamFilter(name);
const { availableBalance, dataTestId, formattedBalance } = parseCryptoAssetBalance(balance);

const titleRight = (
<SkeletonLoader width="126px" isLoading={isLoading}>
{rightElement ? (
rightElement
) : (
<BasicTooltip
asChild
label={formattedBalance.isAbbreviated ? availableBalance.amount.toString() : undefined}
side="left"
>
<styled.span data-testid={title} textStyle="label.02">
{formattedBalance.value} {additionalBalanceInfo}
</styled.span>
</BasicTooltip>
)}
<BasicTooltip
asChild
label={formattedBalance.isAbbreviated ? availableBalance.amount.toString() : undefined}
side="left"
>
<Flex alignItems="center" gap="space.02" textStyle="label.02">
<BulletSeparator>
<styled.span>{formattedBalance.value}</styled.span>
{titleRightBulletInfo}
</BulletSeparator>
</Flex>
</BasicTooltip>
</SkeletonLoader>
);

const captionRight = (
<SkeletonLoader width="78px" isLoading={isLoading}>
{!rightElement && (
<Caption>
<Flex alignItems="center" gap="space.02" color="inherit">
<BulletSeparator>
<Caption>{availableBalance.amount.toNumber() > 0 ? fiatBalance : null}</Caption>
{additionalBalanceInfoAsFiat}
</BulletSeparator>
</Flex>
</Caption>
)}
<Flex alignItems="center" color="ink.text-subdued" gap="space.02">
<BulletSeparator>
<Caption>{availableBalance.amount.toNumber() > 0 ? fiatBalance : null}</Caption>
{captionRightBulletInfo}
</BulletSeparator>
</Flex>
</SkeletonLoader>
);

const isInteractive = !!onClick;
const isInteractive = !!onSelectAsset;

const content = (
<ItemLayout
flagImg={icon}
titleLeft={title}
captionLeft={caption ?? availableBalance.symbol}
titleLeft={spamFilter(titleLeft)}
captionLeft={captionLeft}
titleRight={titleRight}
captionRight={captionRight}
/>
);

if (isInteractive)
return (
<Pressable data-testid={dataTestId} onClick={() => onClick(asset)} my="space.02">
<Pressable
data-testid={dataTestId}
onClick={() => onSelectAsset(availableBalance.symbol, contractId)}
my="space.02"
>
{content}
</Pressable>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@ import type { CryptoAssetBalance } from '@leather-wallet/models';
import { CryptoAssetSelectors } from '@tests/selectors/crypto-asset.selectors';

import { formatBalance } from '@app/common/format-balance';
import { ftDecimals } from '@app/common/stacks-utils';
import { formatMoneyWithoutSymbol } from '@app/common/money/format-money';

export function parseCryptoAssetBalance(balance: CryptoAssetBalance) {
const { availableBalance } = balance;

const amount = ftDecimals(availableBalance.amount, availableBalance.decimals);
const amount = formatMoneyWithoutSymbol(availableBalance);
const dataTestId = CryptoAssetSelectors.CryptoAssetListItem.replace(
'{symbol}',
availableBalance.symbol.toLowerCase()
availableBalance.symbol
);
const formattedBalance = formatBalance(amount);

return {
availableBalance,
dataTestId,
formattedBalance,
};
Expand Down
16 changes: 12 additions & 4 deletions src/app/components/loaders/brc20-tokens-loader.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { useBrc20AccountCryptoAssetsWithDetails } from '@app/query/bitcoin/ordinals/brc20/brc20-tokens.hooks';
import type { Brc20AccountCryptoAssetWithDetails } from '@app/query/models/crypto-asset.model';
import type { Brc20CryptoAssetInfo, CryptoAssetBalance, MarketData } from '@leather-wallet/models';

import { useBrc20Tokens } from '@app/query/bitcoin/ordinals/brc20/brc20-tokens.hooks';

interface Brc20TokensLoaderProps {
children(tokens: Brc20AccountCryptoAssetWithDetails[]): React.ReactNode;
children(
tokens: {
balance: CryptoAssetBalance;
info: Brc20CryptoAssetInfo;
holderAddress: string;
marketData: MarketData;
}[]
): React.ReactNode;
}
export function Brc20TokensLoader({ children }: Brc20TokensLoaderProps) {
const tokens = useBrc20AccountCryptoAssetsWithDetails();
const tokens = useBrc20Tokens();
return children(tokens);
}
12 changes: 12 additions & 0 deletions src/app/components/loaders/btc-balance-loader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { BtcCryptoAssetBalance } from '@leather-wallet/models';

import { useBtcCryptoAssetBalanceNativeSegwit } from '@app/query/bitcoin/balance/btc-balance-native-segwit.hooks';

interface BtcBalanceLoaderProps {
address: string;
children(balance: BtcCryptoAssetBalance, isInitialLoading: boolean): React.ReactNode;
}
export function BtcBalanceLoader({ address, children }: BtcBalanceLoaderProps) {
const { balance, isInitialLoading } = useBtcCryptoAssetBalanceNativeSegwit(address);
return children(balance, isInitialLoading);
}
11 changes: 0 additions & 11 deletions src/app/components/loaders/btc-crypto-asset-loader.tsx

This file was deleted.

7 changes: 4 additions & 3 deletions src/app/components/loaders/runes-loader.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { RuneToken } from '@app/query/bitcoin/bitcoin-client';
import type { CryptoAssetBalance, RuneCryptoAssetInfo } from '@leather-wallet/models';

import { useRuneTokens } from '@app/query/bitcoin/runes/runes.hooks';

interface RunesLoaderProps {
addresses: string[];
children(runes: RuneToken[]): React.ReactNode;
children(runes: { balance: CryptoAssetBalance; info: RuneCryptoAssetInfo }[]): React.ReactNode;
}
export function RunesLoader({ addresses, children }: RunesLoaderProps) {
const runes = useRuneTokens(addresses);
const { runes = [] } = useRuneTokens(addresses);
return children(runes);
}
15 changes: 15 additions & 0 deletions src/app/components/loaders/sip10-tokens-loader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {
type Sip10TokenAssetDetails,
useFilteredSip10Tokens,
} from '@app/query/stacks/sip10/sip10-tokens.hooks';
import type { Sip10CryptoAssetFilter } from '@app/query/stacks/sip10/sip10-tokens.utils';

interface Sip10TokensLoaderProps {
address: string;
filter: Sip10CryptoAssetFilter;
children(isLoading: boolean, tokens: Sip10TokenAssetDetails[]): React.ReactNode;
}
export function Sip10TokensLoader({ address, filter, children }: Sip10TokensLoaderProps) {
const { isInitialLoading, tokens = [] } = useFilteredSip10Tokens({ address, filter });
return children(isInitialLoading, tokens);
}
Loading

0 comments on commit 2c2d61d

Please sign in to comment.