From 625bfe52ef83a1842bf2206ccd709c9253dcc25d Mon Sep 17 00:00:00 2001 From: Edgar Khanzadian Date: Fri, 26 Jan 2024 17:14:14 +0400 Subject: [PATCH 1/4] fix: make coinbase global --- config/wallet-config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/wallet-config.json b/config/wallet-config.json index 59003569c28..3e8cd0241b9 100644 --- a/config/wallet-config.json +++ b/config/wallet-config.json @@ -5,7 +5,7 @@ }, "activeFiatProviders": { "coinbase": { - "availableRegions": "inside-usa-only", + "availableRegions": "global", "enabled": true, "hasFastCheckoutProcess": true, "hasTradingFees": true, From 0c36db342707eedb257a6d0ea306f00e459cdba2 Mon Sep 17 00:00:00 2001 From: alter-eggo Date: Fri, 26 Jan 2024 14:58:39 +0400 Subject: [PATCH 2/4] refactor: remove use spendable utxos hook --- .../hooks/balance/btc/use-btc-balance.ts | 20 ++--- .../hooks/use-bitcoin-custom-fee.tsx | 4 +- .../use-rpc-send-transfer.ts | 4 +- .../hooks/use-generate-ordinal-tx.ts | 4 +- .../form/brc-20/use-brc20-send-form.tsx | 4 +- .../form/btc/use-btc-send-form.tsx | 4 +- .../address/transactions-by-address.hooks.ts | 32 -------- .../bitcoin/address/utxos-by-address.hooks.ts | 82 ++++++++++++------- .../bitcoin/balance/btc-balance.hooks.ts | 8 +- 9 files changed, 75 insertions(+), 87 deletions(-) diff --git a/src/app/common/hooks/balance/btc/use-btc-balance.ts b/src/app/common/hooks/balance/btc/use-btc-balance.ts index 8c8f5deec8b..37e2a70cd0a 100644 --- a/src/app/common/hooks/balance/btc/use-btc-balance.ts +++ b/src/app/common/hooks/balance/btc/use-btc-balance.ts @@ -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( () => ({ @@ -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] ); } diff --git a/src/app/components/bitcoin-custom-fee/hooks/use-bitcoin-custom-fee.tsx b/src/app/components/bitcoin-custom-fee/hooks/use-bitcoin-custom-fee.tsx index 241ba369370..7c8ad19ad1d 100644 --- a/src/app/components/bitcoin-custom-fee/hooks/use-bitcoin-custom-fee.tsx +++ b/src/app/components/bitcoin-custom-fee/hooks/use-bitcoin-custom-fee.tsx @@ -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'; @@ -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( diff --git a/src/app/pages/rpc-send-transfer/use-rpc-send-transfer.ts b/src/app/pages/rpc-send-transfer/use-rpc-send-transfer.ts index ca4ec6d4810..7db9404ffda 100644 --- a/src/app/pages/rpc-send-transfer/use-rpc-send-transfer.ts +++ b/src/app/pages/rpc-send-transfer/use-rpc-send-transfer.ts @@ -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(); @@ -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()); diff --git a/src/app/pages/send/ordinal-inscription/hooks/use-generate-ordinal-tx.ts b/src/app/pages/send/ordinal-inscription/hooks/use-generate-ordinal-tx.ts index dbfec69afde..78688b02f82 100644 --- a/src/app/pages/send/ordinal-inscription/hooks/use-generate-ordinal-tx.ts +++ b/src/app/pages/send/ordinal-inscription/hooks/use-generate-ordinal-tx.ts @@ -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'; @@ -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) { diff --git a/src/app/pages/send/send-crypto-asset-form/form/brc-20/use-brc20-send-form.tsx b/src/app/pages/send/send-crypto-asset-form/form/brc-20/use-brc20-send-form.tsx index 6bd72eb217f..687bc7cc3af 100644 --- a/src/app/pages/send/send-crypto-asset-form/form/brc-20/use-brc20-send-form.tsx +++ b/src/app/pages/send/send-crypto-asset-form/form/brc-20/use-brc20-send-form.tsx @@ -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'; @@ -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()); diff --git a/src/app/pages/send/send-crypto-asset-form/form/btc/use-btc-send-form.tsx b/src/app/pages/send/send-crypto-asset-form/form/btc/use-btc-send-form.tsx index 037be8222a2..96752eeb437 100644 --- a/src/app/pages/send/send-crypto-asset-form/form/btc/use-btc-send-form.tsx +++ b/src/app/pages/send/send-crypto-asset-form/form/btc/use-btc-send-form.tsx @@ -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'; @@ -34,7 +34,7 @@ export function useBtcSendForm() { const formRef = useRef>(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(); diff --git a/src/app/query/bitcoin/address/transactions-by-address.hooks.ts b/src/app/query/bitcoin/address/transactions-by-address.hooks.ts index 862e81db879..05ded11c2a8 100644 --- a/src/app/query/bitcoin/address/transactions-by-address.hooks.ts +++ b/src/app/query/bitcoin/address/transactions-by-address.hooks.ts @@ -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[]) => { @@ -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'); - }, - }); -} diff --git a/src/app/query/bitcoin/address/utxos-by-address.hooks.ts b/src/app/query/bitcoin/address/utxos-by-address.hooks.ts index 46534ba95a4..5407c57f2c0 100644 --- a/src/app/query/bitcoin/address/utxos-by-address.hooks.ts +++ b/src/app/query/bitcoin/address/utxos-by-address.hooks.ts @@ -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) { @@ -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); -} diff --git a/src/app/query/bitcoin/balance/btc-balance.hooks.ts b/src/app/query/bitcoin/balance/btc-balance.hooks.ts index 99d6724f33a..15cfd4078de 100644 --- a/src/app/query/bitcoin/balance/btc-balance.hooks.ts +++ b/src/app/query/bitcoin/balance/btc-balance.hooks.ts @@ -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'); From d13a678c490fd4e556277d5ac003c3b72aa0132e Mon Sep 17 00:00:00 2001 From: alter-eggo Date: Mon, 29 Jan 2024 17:03:18 +0400 Subject: [PATCH 3/4] fix: no btc signer in ledger mode, ref #4873 --- .../use-transferable-asset-balances.hooks.ts | 8 +--- .../balance/bitcoin-balance-loader.tsx | 13 ++++++ .../choose-crypto-asset/crypto-asset-list.tsx | 45 +++++++++++++------ .../choose-asset-to-fund.tsx | 11 +---- .../choose-crypto-asset.tsx | 3 -- 5 files changed, 49 insertions(+), 31 deletions(-) create mode 100644 src/app/components/balance/bitcoin-balance-loader.tsx diff --git a/src/app/common/hooks/use-transferable-asset-balances.hooks.ts b/src/app/common/hooks/use-transferable-asset-balances.hooks.ts index dac2ffdd232..4eddb7d909f 100644 --- a/src/app/common/hooks/use-transferable-asset-balances.hooks.ts +++ b/src/app/common/hooks/use-transferable-asset-balances.hooks.ts @@ -2,18 +2,14 @@ import { useMemo } from 'react'; import type { AllTransferableCryptoAssetBalances } from '@shared/models/crypto-asset-balance.model'; -import { useNativeSegwitBalance } from '@app/query/bitcoin/balance/btc-native-segwit-balance.hooks'; import { useTransferableStacksFungibleTokenAssetBalances } from '@app/query/stacks/balance/stacks-ft-balances.hooks'; import { createStacksCryptoCurrencyAssetTypeWrapper } from '@app/query/stacks/balance/stacks-ft-balances.utils'; -import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks'; import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks'; import { useStxBalance } from './balance/stx/use-stx-balance'; export function useAllTransferableCryptoAssetBalances(): AllTransferableCryptoAssetBalances[] { const account = useCurrentStacksAccount(); - const currentBtcAddress = useCurrentAccountNativeSegwitAddressIndexZero(); - const btcCryptoCurrencyAssetBalance = useNativeSegwitBalance(currentBtcAddress); const { availableBalance: availableStxBalance } = useStxBalance(); const stxCryptoCurrencyAssetBalance = createStacksCryptoCurrencyAssetTypeWrapper( @@ -24,6 +20,6 @@ export function useAllTransferableCryptoAssetBalances(): AllTransferableCryptoAs ); return useMemo(() => { - return [btcCryptoCurrencyAssetBalance, stxCryptoCurrencyAssetBalance, ...stacksFtAssetBalances]; - }, [btcCryptoCurrencyAssetBalance, stacksFtAssetBalances, stxCryptoCurrencyAssetBalance]); + return [stxCryptoCurrencyAssetBalance, ...stacksFtAssetBalances]; + }, [stacksFtAssetBalances, stxCryptoCurrencyAssetBalance]); } diff --git a/src/app/components/balance/bitcoin-balance-loader.tsx b/src/app/components/balance/bitcoin-balance-loader.tsx new file mode 100644 index 00000000000..b4f77a3e0dc --- /dev/null +++ b/src/app/components/balance/bitcoin-balance-loader.tsx @@ -0,0 +1,13 @@ +import { BitcoinCryptoCurrencyAssetBalance } from '@shared/models/crypto-asset-balance.model'; + +import { useNativeSegwitBalance } from '@app/query/bitcoin/balance/btc-native-segwit-balance.hooks'; + +interface BitcoinBalanceLoaderProps { + address: string; + children(balance: BitcoinCryptoCurrencyAssetBalance): React.ReactNode; +} + +export function BitcoinBalanceLoader({ address, children }: BitcoinBalanceLoaderProps) { + const btcCryptoCurrencyAssetBalance = useNativeSegwitBalance(address); + return children(btcCryptoCurrencyAssetBalance); +} diff --git a/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx b/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx index 48dbaac5e9d..fd1fb2f0e0f 100644 --- a/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx +++ b/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx @@ -2,26 +2,39 @@ import type { AllTransferableCryptoAssetBalances } from '@shared/models/crypto-a import { StacksFungibleTokenAsset } from '@shared/models/crypto-asset.model'; import { useWalletType } from '@app/common/use-wallet-type'; +import { BitcoinNativeSegwitAccountLoader } from '@app/components/account/bitcoin-account-loader'; +import { BitcoinBalanceLoader } from '@app/components/balance/bitcoin-balance-loader'; +import { Brc20TokensLoader } from '@app/components/brc20-tokens-loader'; import { Brc20TokenAssetList } from '@app/components/crypto-assets/bitcoin/brc20-token-asset-list/brc20-token-asset-list'; -import { Brc20Token } from '@app/query/bitcoin/ordinals/brc20/brc20-tokens.query'; +import { BtcIcon } from '@app/ui/components/icons/btc-icon'; +import { CryptoCurrencyAssetItem } from '../crypto-currency-asset/crypto-currency-asset-item'; import { CryptoAssetListItem } from './crypto-asset-list-item'; import { CryptoAssetListLayout } from './crypto-asset-list.layout'; interface CryptoAssetListProps { cryptoAssetBalances: AllTransferableCryptoAssetBalances[]; onItemClick(cryptoAssetBalance: AllTransferableCryptoAssetBalances): void; - brc20Tokens?: Brc20Token[]; } -export function CryptoAssetList({ - cryptoAssetBalances, - onItemClick, - brc20Tokens, -}: CryptoAssetListProps) { +export function CryptoAssetList({ cryptoAssetBalances, onItemClick }: CryptoAssetListProps) { const { whenWallet } = useWalletType(); return ( + + {signer => ( + + {balance => ( + } + onClick={() => onItemClick(balance)} + isPressable + /> + )} + + )} + {cryptoAssetBalances.map(cryptoAssetBalance => ( onItemClick(cryptoAssetBalance)} @@ -32,12 +45,18 @@ export function CryptoAssetList({ } /> ))} - {brc20Tokens - ? whenWallet({ - software: , - ledger: null, - }) - : null} + {whenWallet({ + software: ( + + {() => ( + + {brc20Tokens => } + + )} + + ), + ledger: null, + })} ); } diff --git a/src/app/pages/fund/choose-asset-to-fund/choose-asset-to-fund.tsx b/src/app/pages/fund/choose-asset-to-fund/choose-asset-to-fund.tsx index 6ed18bca538..3745bd094c2 100644 --- a/src/app/pages/fund/choose-asset-to-fund/choose-asset-to-fund.tsx +++ b/src/app/pages/fund/choose-asset-to-fund/choose-asset-to-fund.tsx @@ -5,7 +5,6 @@ import { AllTransferableCryptoAssetBalances } from '@shared/models/crypto-asset- import { RouteUrls } from '@shared/route-urls'; import { isDefined } from '@shared/utils'; -import { useBtcCryptoCurrencyAssetBalance } from '@app/common/hooks/balance/btc/use-btc-crypto-currency-asset-balance'; import { useStxCryptoCurrencyAssetBalance } from '@app/common/hooks/balance/stx/use-stx-crypto-currency-asset-balance'; import { useRouteHeader } from '@app/common/hooks/use-route-header'; import { useWalletType } from '@app/common/use-wallet-type'; @@ -16,14 +15,8 @@ import { ModalHeader } from '@app/components/modal-header'; import { useCheckLedgerBlockchainAvailable } from '@app/store/accounts/blockchain/utils'; export function ChooseCryptoAssetToFund() { - const btcCryptoCurrencyAssetBalance = useBtcCryptoCurrencyAssetBalance(); const stxCryptoCurrencyAssetBalance = useStxCryptoCurrencyAssetBalance(); - const cryptoCurrencyAssetBalances = useMemo( - () => [btcCryptoCurrencyAssetBalance, stxCryptoCurrencyAssetBalance], - [btcCryptoCurrencyAssetBalance, stxCryptoCurrencyAssetBalance] - ); - const { whenWallet } = useWalletType(); const navigate = useNavigate(); @@ -31,13 +24,13 @@ export function ChooseCryptoAssetToFund() { const filteredCryptoAssetBalances = useMemo( () => - cryptoCurrencyAssetBalances.filter(isDefined).filter(assetBalance => + [stxCryptoCurrencyAssetBalance].filter(isDefined).filter(assetBalance => whenWallet({ ledger: checkBlockchainAvailable(assetBalance?.blockchain), software: true, }) ), - [cryptoCurrencyAssetBalances, checkBlockchainAvailable, whenWallet] + [stxCryptoCurrencyAssetBalance, checkBlockchainAvailable, whenWallet] ); useRouteHeader( navigate(RouteUrls.Home)} title=" " />); diff --git a/src/app/pages/send/choose-crypto-asset/choose-crypto-asset.tsx b/src/app/pages/send/choose-crypto-asset/choose-crypto-asset.tsx index 14bf7580719..5e8c25d976b 100644 --- a/src/app/pages/send/choose-crypto-asset/choose-crypto-asset.tsx +++ b/src/app/pages/send/choose-crypto-asset/choose-crypto-asset.tsx @@ -4,7 +4,6 @@ import { useNavigate } from 'react-router-dom'; import { AllTransferableCryptoAssetBalances } from '@shared/models/crypto-asset-balance.model'; import { RouteUrls } from '@shared/route-urls'; -import { useBrc20Tokens } from '@app/common/hooks/use-brc20-tokens'; import { useRouteHeader } from '@app/common/hooks/use-route-header'; import { useAllTransferableCryptoAssetBalances } from '@app/common/hooks/use-transferable-asset-balances.hooks'; import { useWalletType } from '@app/common/use-wallet-type'; @@ -16,7 +15,6 @@ import { useCheckLedgerBlockchainAvailable } from '@app/store/accounts/blockchai export function ChooseCryptoAsset() { const allTransferableCryptoAssetBalances = useAllTransferableCryptoAssetBalances(); - const brc20Tokens = useBrc20Tokens(); const { whenWallet } = useWalletType(); const navigate = useNavigate(); @@ -49,7 +47,6 @@ export function ChooseCryptoAsset() { navigateToSendForm(cryptoAssetBalance)} - brc20Tokens={brc20Tokens} cryptoAssetBalances={allTransferableCryptoAssetBalances.filter(asset => whenWallet({ ledger: checkBlockchainAvailable(asset.blockchain), From 68c557f7dbb9a309d3587910b7680ff1e8105fda Mon Sep 17 00:00:00 2001 From: kyranjamie Date: Mon, 29 Jan 2024 15:55:09 +0100 Subject: [PATCH 4/4] refactor: limit query opts, add hiro header --- src/app/common/api/fetch-wrapper.ts | 8 ++++++++ src/app/query/stacks/contract/contract.query.ts | 2 ++ .../stacks/transactions/transactions-by-id.query.ts | 9 +++++++++ .../transactions/transactions-with-transfers.query.ts | 9 +++++---- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/app/common/api/fetch-wrapper.ts b/src/app/common/api/fetch-wrapper.ts index 11b3a4bc1b9..fd52ace03b9 100644 --- a/src/app/common/api/fetch-wrapper.ts +++ b/src/app/common/api/fetch-wrapper.ts @@ -4,6 +4,7 @@ import { analytics } from '@shared/utils/analytics'; const leatherHeaders: HeadersInit = { 'x-leather-version': VERSION, + 'x-hiro-product': 'leather', }; function isErrorCode(statusCode: number) { @@ -30,6 +31,13 @@ export async function wrappedFetch(input: RequestInfo, init: RequestInit = {}) { return resp; } +axios.interceptors.request.use(request => { + if (request.url?.includes('hiro.so')) + Object.entries(leatherHeaders).forEach(([key, value]) => request.headers.set(key, value)); + + return request; +}); + axios.interceptors.response.use(response => { if (isErrorCode(response.status)) trackApiError(response.config.url ?? '', response.status); return response; diff --git a/src/app/query/stacks/contract/contract.query.ts b/src/app/query/stacks/contract/contract.query.ts index bdb0c4bbc5c..84a3508352c 100644 --- a/src/app/query/stacks/contract/contract.query.ts +++ b/src/app/query/stacks/contract/contract.query.ts @@ -30,5 +30,7 @@ export function useGetContractInterface(transactionRequest: ContractCallPayload transactionRequest?.contractAddress, ], queryFn: fetchContractInterface, + staleTime: 30 * 60 * 1000, + refetchOnWindowFocus: false, }); } diff --git a/src/app/query/stacks/transactions/transactions-by-id.query.ts b/src/app/query/stacks/transactions/transactions-by-id.query.ts index 4c96fe5ea05..305d0612637 100644 --- a/src/app/query/stacks/transactions/transactions-by-id.query.ts +++ b/src/app/query/stacks/transactions/transactions-by-id.query.ts @@ -5,6 +5,13 @@ import { useStacksClientUnanchored } from '@app/store/common/api-clients.hooks'; import { useHiroApiRateLimiter } from '../rate-limiter'; +const options = { + staleTime: 30 * 1000, + refetchOnMount: false, + refetchOnReconnect: false, + refetchOnWindowFocus: true, +} as const; + export function useTransactionsById(txids: string[]) { const client = useStacksClientUnanchored(); const limiter = useHiroApiRateLimiter(); @@ -19,6 +26,7 @@ export function useTransactionsById(txids: string[]) { return { queryKey: ['transaction-by-id', txid], queryFn: () => transactionByIdFetcher(txid), + ...options, }; }), }); @@ -37,5 +45,6 @@ export function useTransactionById(txid: string) { return useQuery({ queryKey: ['transaction-by-id', txid], queryFn: () => transactionByIdFetcher(txid), + ...options, }); } diff --git a/src/app/query/stacks/transactions/transactions-with-transfers.query.ts b/src/app/query/stacks/transactions/transactions-with-transfers.query.ts index a726831b0e1..b6520778b14 100644 --- a/src/app/query/stacks/transactions/transactions-with-transfers.query.ts +++ b/src/app/query/stacks/transactions/transactions-with-transfers.query.ts @@ -10,10 +10,11 @@ import { useCurrentNetworkState } from '@app/store/networks/networks.hooks'; import { useHiroApiRateLimiter } from '../rate-limiter'; const queryOptions: UseQueryOptions = { - refetchInterval: 10_000, - refetchOnMount: 'always', - refetchOnReconnect: 'always', - refetchOnWindowFocus: 'always', + staleTime: 60 * 1000, + refetchInterval: 30_000, + refetchOnMount: false, + refetchOnReconnect: false, + refetchOnWindowFocus: true, }; export function useGetAccountTransactionsWithTransfersQuery() {