Skip to content

Commit

Permalink
refactor: remove use spendable utxos hook
Browse files Browse the repository at this point in the history
  • Loading branch information
alter-eggo committed Jan 29, 2024
1 parent 625bfe5 commit 0c36db3
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 87 deletions.
20 changes: 6 additions & 14 deletions src/app/common/hooks/balance/btc/use-btc-balance.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
import { useMemo } from 'react';

import BigNumber from 'bignumber.js';

import { createMoney } from '@shared/models/money.model';

import { baseCurrencyAmountInQuote, subtractMoney } from '@app/common/money/calculate-money';
import { baseCurrencyAmountInQuote } from '@app/common/money/calculate-money';
import { i18nFormatCurrency } from '@app/common/money/format-money';
import { createBitcoinCryptoCurrencyAssetTypeWrapper } from '@app/query/bitcoin/address/address.utils';
import { useBitcoinPendingTransactionsBalance } from '@app/query/bitcoin/address/transactions-by-address.hooks';
import { useNativeSegwitBalance } from '@app/query/bitcoin/balance/btc-native-segwit-balance.hooks';
import { useCryptoCurrencyMarketData } from '@app/query/common/market-data/market-data.hooks';

export function useBtcAssetBalance(btcAddress: string) {
const btcMarketData = useCryptoCurrencyMarketData('BTC');
const btcAssetBalance = useNativeSegwitBalance(btcAddress);
const { data: pendingBalance } = useBitcoinPendingTransactionsBalance(btcAddress);
const availableBalance = subtractMoney(
btcAssetBalance.balance,
pendingBalance ?? createMoney(new BigNumber(0), 'BTC')
);

return useMemo(
() => ({
Expand All @@ -27,11 +17,13 @@ export function useBtcAssetBalance(btcAddress: string) {
btcUsdBalance: i18nFormatCurrency(
baseCurrencyAmountInQuote(btcAssetBalance.balance, btcMarketData)
),
btcAvailableAssetBalance: createBitcoinCryptoCurrencyAssetTypeWrapper(availableBalance),
btcAvailableAssetBalance: createBitcoinCryptoCurrencyAssetTypeWrapper(
btcAssetBalance.balance
),
btcAvailableUsdBalance: i18nFormatCurrency(
baseCurrencyAmountInQuote(availableBalance, btcMarketData)
baseCurrencyAmountInQuote(btcAssetBalance.balance, btcMarketData)
),
}),
[btcAddress, btcAssetBalance, btcMarketData, availableBalance]
[btcAddress, btcAssetBalance, btcMarketData]
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
determineUtxosForSpend,
determineUtxosForSpendAll,
} from '@app/common/transactions/bitcoin/coinselect/local-coin-selection';
import { useCurrentNativeSegwitAccountSpendableUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks';
import { useCurrentNativeSegwitUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks';
import { useCurrentNativeSegwitAddressBalance } from '@app/query/bitcoin/balance/btc-native-segwit-balance.hooks';
import { useCryptoCurrencyMarketData } from '@app/query/common/market-data/market-data.hooks';

Expand All @@ -21,7 +21,7 @@ interface UseBitcoinCustomFeeArgs {
}
export function useBitcoinCustomFee({ amount, isSendingMax, recipient }: UseBitcoinCustomFeeArgs) {
const balance = useCurrentNativeSegwitAddressBalance();
const { data: utxos = [] } = useCurrentNativeSegwitAccountSpendableUtxos();
const { data: utxos = [] } = useCurrentNativeSegwitUtxos();
const btcMarketData = useCryptoCurrencyMarketData('BTC');

return useCallback(
Expand Down
4 changes: 2 additions & 2 deletions src/app/pages/rpc-send-transfer/use-rpc-send-transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { RouteUrls } from '@shared/route-urls';
import { useDefaultRequestParams } from '@app/common/hooks/use-default-request-search-params';
import { useOnMount } from '@app/common/hooks/use-on-mount';
import { initialSearchParams } from '@app/common/initial-search-params';
import { useCurrentNativeSegwitAccountSpendableUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks';
import { useCurrentNativeSegwitUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks';

export function useRpcSendTransferRequestParams() {
const defaultParams = useDefaultRequestParams();
Expand All @@ -24,7 +24,7 @@ export function useRpcSendTransferRequestParams() {
export function useRpcSendTransfer() {
const navigate = useNavigate();
const { address, amount, origin } = useRpcSendTransferRequestParams();
const { data: utxos = [], refetch } = useCurrentNativeSegwitAccountSpendableUtxos();
const { data: utxos = [], refetch } = useCurrentNativeSegwitUtxos();

// Forcing a refetch to ensure UTXOs are fresh
useOnMount(() => refetch());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { OrdinalSendFormValues } from '@shared/models/form.model';

import { determineUtxosForSpend } from '@app/common/transactions/bitcoin/coinselect/local-coin-selection';
import { createCounter } from '@app/common/utils/counter';
import { useCurrentNativeSegwitAccountSpendableUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks';
import { useCurrentNativeSegwitUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks';
import { UtxoWithDerivationPath } from '@app/query/bitcoin/bitcoin-client';
import { useBitcoinScureLibNetworkConfig } from '@app/store/accounts/blockchain/bitcoin/bitcoin-keychain';
import { useCurrentAccountNativeSegwitSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
Expand All @@ -20,7 +20,7 @@ export function useGenerateUnsignedOrdinalTx(inscriptionInput: UtxoWithDerivatio
const createTaprootSigner = useCurrentAccountTaprootSigner();
const createNativeSegwitSigner = useCurrentAccountNativeSegwitSigner();
const networkMode = useBitcoinScureLibNetworkConfig();
const { data: nativeSegwitUtxos } = useCurrentNativeSegwitAccountSpendableUtxos();
const { data: nativeSegwitUtxos } = useCurrentNativeSegwitUtxos();

function coverFeeFromAdditionalUtxos(values: OrdinalSendFormValues) {
if (getAddressInfo(values.inscription.address).type === AddressType.p2wpkh) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
import { tokenAmountValidator } from '@app/common/validation/forms/amount-validators';
import { currencyAmountValidator } from '@app/common/validation/forms/currency-validators';
import { useUpdatePersistedSendFormValues } from '@app/features/popup-send-form-restoration/use-update-persisted-send-form-values';
import { useCurrentNativeSegwitAccountSpendableUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks';
import { useCurrentNativeSegwitUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks';
import { useCurrentAccountNativeSegwitIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useCurrentNetwork } from '@app/store/networks/networks.selectors';

Expand All @@ -44,7 +44,7 @@ export function useBrc20SendForm({ balance, tick, decimals }: UseBrc20SendFormAr
const navigate = useNavigate();
const currentNetwork = useCurrentNetwork();
const nativeSegwitSigner = useCurrentAccountNativeSegwitIndexZeroSigner();
const { data: utxos = [], refetch } = useCurrentNativeSegwitAccountSpendableUtxos();
const { data: utxos = [], refetch } = useCurrentNativeSegwitUtxos();

// Forcing a refetch to ensure UTXOs are fresh
useOnMount(() => refetch());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
currencyAmountValidator,
} from '@app/common/validation/forms/currency-validators';
import { useUpdatePersistedSendFormValues } from '@app/features/popup-send-form-restoration/use-update-persisted-send-form-values';
import { useCurrentNativeSegwitAccountSpendableUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks';
import { useCurrentNativeSegwitUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks';
import { useNativeSegwitBalance } from '@app/query/bitcoin/balance/btc-native-segwit-balance.hooks';
import { useCurrentAccountNativeSegwitIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useCurrentNetwork } from '@app/store/networks/networks.selectors';
Expand All @@ -34,7 +34,7 @@ export function useBtcSendForm() {
const formRef = useRef<FormikProps<BitcoinSendFormValues>>(null);
const currentNetwork = useCurrentNetwork();
const nativeSegwitSigner = useCurrentAccountNativeSegwitIndexZeroSigner();
const { data: utxos = [], refetch } = useCurrentNativeSegwitAccountSpendableUtxos();
const { data: utxos = [], refetch } = useCurrentNativeSegwitUtxos();
const btcCryptoCurrencyAssetBalance = useNativeSegwitBalance(nativeSegwitSigner.address);
const sendFormNavigate = useSendFormNavigate();
const calcMaxSpend = useCalculateMaxBitcoinSpend();
Expand Down
32 changes: 0 additions & 32 deletions src/app/query/bitcoin/address/transactions-by-address.hooks.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import { useCallback } from 'react';

import { createMoney } from '@shared/models/money.model';
import { BitcoinTx } from '@shared/models/transactions/bitcoin-transaction.model';

import { sumNumbers } from '@app/common/math/helpers';

import { UtxoResponseItem } from '../bitcoin-client';
import {
useGetBitcoinTransactionsByAddressQuery,
useGetBitcoinTransactionsByAddressesQuery,
} from './transactions-by-address.query';
import { useAllSpendableUtxosByAddress } from './utxos-by-address.hooks';

function useFilterAddressPendingTransactions() {
return useCallback((txs: BitcoinTx[]) => {
Expand Down Expand Up @@ -53,32 +50,3 @@ export function calculateOutboundPendingTxsValue(pendingTxs: BitcoinTx[], addres

return sumInputs.minus(sumOutputs).toNumber();
}

// filter out pending txs that have inputs that are not in the utxos list to prevent double extraction
function filterMissingUtxosPendingTxs(
pendingTxs: BitcoinTx[],
utxos: UtxoResponseItem[],
address: string
) {
return pendingTxs.filter(tx => {
return tx.vin.every(input => {
return (
utxos.some(utxo => utxo.txid === input.txid) &&
address === input.prevout.scriptpubkey_address
);
});
});
}

export function useBitcoinPendingTransactionsBalance(address: string) {
const filterPendingTransactions = useFilterAddressPendingTransactions();
const { data: utxos } = useAllSpendableUtxosByAddress(address);

return useGetBitcoinTransactionsByAddressQuery(address, {
select(txs) {
const pendingTxs = filterPendingTransactions(txs);
const filteredTxs = filterMissingUtxosPendingTxs(pendingTxs, utxos || [], address);
return createMoney(calculateOutboundPendingTxsValue(filteredTxs, address), 'BTC');
},
});
}
82 changes: 53 additions & 29 deletions src/app/query/bitcoin/address/utxos-by-address.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,62 @@ export function filterUtxosWithInscriptions(
);
}

const defaultArgs = {
filterInscriptionUtxos: true,
filterPendingTxsUtxos: true,
};

/**
* Warning: ⚠️ These are **all** UTXOs, including Stamped and Inscribed UTXOs.
* You should probably use `useCurrentNativeSegwitAccountSpendableUtxos` instead.
* Warning: ⚠️ To avoid spending inscriptions, when using UTXOs
* we set `filterInscriptionUtxos` and `filterPendingTxsUtxos` to true
*/
export function useCurrentNativeSegwitUtxos() {
export function useCurrentNativeSegwitUtxos(args = defaultArgs) {
const { filterInscriptionUtxos, filterPendingTxsUtxos } = args;

const nativeSegwitSigner = useCurrentAccountNativeSegwitIndexZeroSigner();
return useGetUtxosByAddressQuery(nativeSegwitSigner.address);
const address = nativeSegwitSigner.address;

return useNativeSegwitUtxosByAddress({
address,
filterInscriptionUtxos,
filterPendingTxsUtxos,
});
}

interface UseFilterUtxosByAddressArgs {
address: string;
filterInscriptionUtxos: boolean;
filterPendingTxsUtxos: boolean;
}

type filterUtxoFunctionType = (utxos: UtxoResponseItem[]) => UtxoResponseItem[];

export function useNativeSegwitUtxosByAddress({
address,
filterInscriptionUtxos,
filterPendingTxsUtxos,
}: UseFilterUtxosByAddressArgs) {
const filterOutInscriptions = useFilterInscriptionsByAddress(address);
const filterOutPendingTxsUtxos = useFilterPendingUtxosByAddress(address);

return useGetUtxosByAddressQuery(address, {
select(utxos) {
const filters = [];
if (filterPendingTxsUtxos) {
filters.push(filterOutPendingTxsUtxos);
}

if (filterInscriptionUtxos) {
filters.push(filterOutInscriptions);
}

return filters.reduce(
(filteredUtxos: UtxoResponseItem[], filterFunc: filterUtxoFunctionType) =>
filterFunc(filteredUtxos),
utxos
);
},
});
}

function useFilterInscriptionsByAddress(address: string) {
Expand Down Expand Up @@ -66,28 +115,3 @@ function useFilterPendingUtxosByAddress(address: string) {
[address, pendingInputs]
);
}

export function useAllSpendableUtxosByAddress(address: string) {
const filterOutInscriptions = useFilterInscriptionsByAddress(address);
return useGetUtxosByAddressQuery(address, {
select(utxos) {
return filterOutInscriptions(utxos);
},
});
}

function useSpendableAndNotPendingUtxosByAddress(address: string) {
const filterOutInscriptions = useFilterInscriptionsByAddress(address);
const filterOutPendingTxsUtxos = useFilterPendingUtxosByAddress(address);

return useGetUtxosByAddressQuery(address, {
select(utxos) {
return filterOutPendingTxsUtxos(filterOutInscriptions(utxos));
},
});
}

export function useCurrentNativeSegwitAccountSpendableUtxos() {
const nativeSegwitSigner = useCurrentAccountNativeSegwitIndexZeroSigner();
return useSpendableAndNotPendingUtxosByAddress(nativeSegwitSigner.address);
}
8 changes: 6 additions & 2 deletions src/app/query/bitcoin/balance/btc-balance.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ import { isUndefined } from '@shared/utils';

import { sumNumbers } from '@app/common/math/helpers';

import { useAllSpendableUtxosByAddress } from '../address/utxos-by-address.hooks';
import { useNativeSegwitUtxosByAddress } from '../address/utxos-by-address.hooks';

export function useGetBitcoinBalanceByAddress(address: string) {
const { data: utxos } = useAllSpendableUtxosByAddress(address);
const { data: utxos } = useNativeSegwitUtxosByAddress({
address,
filterInscriptionUtxos: true,
filterPendingTxsUtxos: true,
});

return useMemo(() => {
if (isUndefined(utxos)) return createMoney(new BigNumber(0), 'BTC');
Expand Down

0 comments on commit 0c36db3

Please sign in to comment.