diff --git a/packages/models/src/fees/stacks-fees.model.ts b/packages/models/src/fees/stacks-fees.model.ts index ee15f3901..daa7ffe45 100644 --- a/packages/models/src/fees/stacks-fees.model.ts +++ b/packages/models/src/fees/stacks-fees.model.ts @@ -4,16 +4,3 @@ export interface StacksFeeEstimate { fee: Money; feeRate: number; } - -export interface ApiFeeEstimation { - fee: number; - fee_rate: number; -} - -export interface StacksTxFeeEstimation { - cost_scalar_change_by_byte: number; - estimated_cost: object; - estimated_cost_scalar: number; - estimations: ApiFeeEstimation[]; - error?: string; -} diff --git a/packages/query/index.ts b/packages/query/index.ts index 60316b3c8..2e9095d58 100644 --- a/packages/query/index.ts +++ b/packages/query/index.ts @@ -43,7 +43,6 @@ export * from './src/common/market-data/vendors/coingecko-market-data.query'; export * from './src/common/remote-config/remote-config.query'; export * from './src/stacks/balance/account-balance.hooks'; export * from './src/stacks/balance/account-balance.query'; -export * from './src/stacks/bns/bns.hooks'; export * from './src/stacks/bns/bns.query'; export * from './src/stacks/bns/bns.utils'; export * from './src/stacks/contract/contract.hooks'; @@ -74,9 +73,7 @@ export * from './src/stacks/transactions/transactions-by-id.query'; export * from './src/stacks/transactions/transactions-with-transfers.hooks'; export * from './src/stacks/transactions/transactions-with-transfers.query'; export * from './src/leather-query-provider'; -export * from './types/account'; export * from './types/api-types'; -export * from './types/contract-types'; export * from './types/inscription'; export * from './types/remote-config'; export * from './types/utxo'; diff --git a/packages/query/package.json b/packages/query/package.json index dd259df35..c9993de2d 100644 --- a/packages/query/package.json +++ b/packages/query/package.json @@ -42,11 +42,10 @@ "@scure/base": "1.1.6", "@scure/bip32": "1.4.0", "@scure/btc-signer": "1.3.2", - "@stacks/blockchain-api-client": "6.3.4", - "@stacks/stacks-blockchain-api-types": "6.3.4", "@stacks/common": "6.13.0", "@stacks/connect": "7.4.0", "@stacks/rpc-client": "1.0.3", + "@stacks/stacks-blockchain-api-types": "6.3.4", "@stacks/transactions": "6.15.0", "@tanstack/query-sync-storage-persister": "4.35.7", "@tanstack/react-query": "4.35.7", diff --git a/packages/query/src/common/alex-sdk/alex-sdk.hooks.ts b/packages/query/src/common/alex-sdk/alex-sdk.hooks.ts index bcbb19dba..589bfe8a2 100644 --- a/packages/query/src/common/alex-sdk/alex-sdk.hooks.ts +++ b/packages/query/src/common/alex-sdk/alex-sdk.hooks.ts @@ -1,5 +1,9 @@ import { useCallback } from 'react'; +import { Currency, type TokenInfo } from 'alex-sdk'; +import { AlexSDK } from 'alex-sdk'; +import BigNumber from 'bignumber.js'; + import { MarketData, Money, createMarketData, createMarketPair } from '@leather-wallet/models'; import { convertAmountToFractionalUnit, @@ -8,9 +12,6 @@ import { isDefined, sortAssetsByName, } from '@leather-wallet/utils'; -import { Currency, type TokenInfo } from 'alex-sdk'; -import { AlexSDK } from 'alex-sdk'; -import BigNumber from 'bignumber.js'; import { useStxAvailableUnlockedBalance } from '../../stacks/balance/account-balance.hooks'; import { useTransferableSip10Tokens } from '../../stacks/sip10/sip10-tokens.hooks'; diff --git a/packages/query/src/hiro-rate-limiter.ts b/packages/query/src/hiro-rate-limiter.ts index 010db50b5..07505e6b9 100644 --- a/packages/query/src/hiro-rate-limiter.ts +++ b/packages/query/src/hiro-rate-limiter.ts @@ -1,5 +1,7 @@ import PQueue from 'p-queue'; +import { HIRO_API_BASE_URL_TESTNET } from '@leather-wallet/models'; + import { useCurrentNetworkState } from './leather-query-provider'; const hiroStacksMainnetApiLimiter = new PQueue({ @@ -25,3 +27,8 @@ export function useHiroApiRateLimiter(): PQueue { return hiroStacksTestnetApiLimiter; } } + +export function getHiroApiRateLimiter(url: string): PQueue { + if (url.includes(HIRO_API_BASE_URL_TESTNET)) return hiroStacksTestnetApiLimiter; + return hiroStacksMainnetApiLimiter; +} diff --git a/packages/query/src/stacks/balance/account-balance.hooks.ts b/packages/query/src/stacks/balance/account-balance.hooks.ts index bb6abbbca..3e84aa42f 100644 --- a/packages/query/src/stacks/balance/account-balance.hooks.ts +++ b/packages/query/src/stacks/balance/account-balance.hooks.ts @@ -1,12 +1,13 @@ +import BigNumber from 'bignumber.js'; + import type { Money, StxCryptoAssetBalance } from '@leather-wallet/models'; import { createMoney, subtractMoney, sumMoney } from '@leather-wallet/utils'; -import BigNumber from 'bignumber.js'; import { - type AccountBalanceStxKeys, - type AddressBalanceResponse, + AccountBalanceStxKeys, + AddressBalanceResponse, accountBalanceStxKeys, -} from '../../../types/account'; +} from '../hiro-api-types'; import { useMempoolTxsInboundBalance, useMempoolTxsOutboundBalance, @@ -48,7 +49,6 @@ export function useStxCryptoAssetBalance(address: string) { }); } -// useCurrentStxAvailableUnlockedBalance export function useStxAvailableUnlockedBalance(address: string) { return useStxCryptoAssetBalance(address).data?.unlockedBalance ?? createMoney(0, 'STX'); } diff --git a/packages/query/src/stacks/balance/account-balance.query.ts b/packages/query/src/stacks/balance/account-balance.query.ts index 93c325acd..5fe13b32c 100644 --- a/packages/query/src/stacks/balance/account-balance.query.ts +++ b/packages/query/src/stacks/balance/account-balance.query.ts @@ -1,7 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { AddressBalanceResponse } from '../../../types/account'; -import { useHiroApiRateLimiter } from '../../hiro-rate-limiter'; import { useCurrentNetworkState } from '../../leather-query-provider'; import { AppUseQueryConfig } from '../../query-config'; import { StacksClient, useStacksClient } from '../stacks-client'; @@ -15,17 +13,7 @@ const balanceQueryOptions = { } as const; function fetchAccountBalance(client: StacksClient, signal?: AbortSignal) { - return async (principal: string) => { - // Coercing type with client-side one that's more accurate - return client.accountsApi.getAccountBalance( - { - principal, - }, - { - signal, - } - ) as Promise; - }; + return async (address: string) => client.getAccountBalance(address, signal); } type FetchAccountBalanceResp = Awaited>>; @@ -35,18 +23,12 @@ export function useStacksAccountBalanceQuery ) { const client = useStacksClient(); - const limiter = useHiroApiRateLimiter(); const network = useCurrentNetworkState(); return useQuery({ enabled: !!address, queryKey: ['get-address-stx-balance', address, network.id], - queryFn: async ({ signal }) => { - return limiter.add(() => fetchAccountBalance(client, signal)(address), { - signal, - throwOnTimeout: true, - }); - }, + queryFn: async ({ signal }) => fetchAccountBalance(client, signal)(address), ...balanceQueryOptions, ...options, }); diff --git a/packages/query/src/stacks/bns/bns.hooks.ts b/packages/query/src/stacks/bns/bns.hooks.ts deleted file mode 100644 index 2bf4524b8..000000000 --- a/packages/query/src/stacks/bns/bns.hooks.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { useGetBnsNamesOwnedByAddress } from './bns.query'; - -export function useCurrentAccountNames(address: string) { - return useGetBnsNamesOwnedByAddress(address, { - select: resp => resp.names ?? [], - }); -} diff --git a/packages/query/src/stacks/bns/bns.query.ts b/packages/query/src/stacks/bns/bns.query.ts index e053a0f1e..9c04fe802 100644 --- a/packages/query/src/stacks/bns/bns.query.ts +++ b/packages/query/src/stacks/bns/bns.query.ts @@ -1,11 +1,10 @@ import { BnsNamesOwnByAddressResponse } from '@stacks/stacks-blockchain-api-types'; import { useQuery } from '@tanstack/react-query'; -import { useHiroApiRateLimiter } from '../../hiro-rate-limiter'; import { useCurrentNetworkState } from '../../leather-query-provider'; import { AppUseQueryConfig } from '../../query-config'; import { QueryPrefixes } from '../../query-prefixes'; -import { StacksClient, useStacksClient } from '../stacks-client'; +import { useStacksClient } from '../stacks-client'; import { fetchNamesForAddress } from './bns.utils'; const staleTime = 24 * 60 * 60 * 1000; // 24 hours @@ -18,43 +17,17 @@ const bnsQueryOptions = { refetchOnReconnect: false, } as const; -type BnsNameFetcher = (address: string) => Promise; - -interface GetBnsNameFetcherFactoryArgs { - client: StacksClient; - isTestnet: boolean; - signal?: AbortSignal; -} - -function getBnsNameFetcherFactory({ - client, - isTestnet, - signal, -}: GetBnsNameFetcherFactoryArgs): BnsNameFetcher { - return async (address: string) => { - return fetchNamesForAddress({ client, address, isTestnet, signal }); - }; -} - -type BnsNameFetcherResp = Awaited>>; - -export function useGetBnsNamesOwnedByAddress( +export function useGetBnsNamesOwnedByAddressQuery( address: string, - options?: AppUseQueryConfig + options?: AppUseQueryConfig ) { const client = useStacksClient(); - const limiter = useHiroApiRateLimiter(); const { isTestnet } = useCurrentNetworkState(); + return useQuery({ enabled: address !== '', queryKey: [QueryPrefixes.BnsNamesByAddress, address], - queryFn: async ({ signal }) => { - return limiter.add(() => fetchNamesForAddress({ client, address, isTestnet, signal }), { - signal, - priority: 2, - throwOnTimeout: true, - }); - }, + queryFn: async ({ signal }) => fetchNamesForAddress({ client, address, isTestnet, signal }), ...bnsQueryOptions, ...options, }); diff --git a/packages/query/src/stacks/bns/bns.utils.ts b/packages/query/src/stacks/bns/bns.utils.ts index c1f57bde2..41576cdaf 100644 --- a/packages/query/src/stacks/bns/bns.utils.ts +++ b/packages/query/src/stacks/bns/bns.utils.ts @@ -1,5 +1,4 @@ import { parseZoneFile } from '@fungible-systems/zone-file'; -import { isString, isUndefined } from '@leather-wallet/utils'; import { asciiToBytes, bytesToAscii } from '@stacks/common'; import { BnsNamesOwnByAddressResponse } from '@stacks/stacks-blockchain-api-types'; import { @@ -17,6 +16,8 @@ import { } from '@stacks/transactions'; import { principalToString } from '@stacks/transactions/dist/esm/clarity/types/principalCV'; +import { isString, isUndefined } from '@leather-wallet/utils'; + import { StacksClient } from '../stacks-client'; const bnsContractConsts = { @@ -33,18 +34,16 @@ async function fetchBnsxName( try { const addressCV = standardPrincipalCV(address); const addressHex = cvToHex(addressCV); - const res = await client.smartContractsApi.callReadOnlyFunction( - { - ...bnsContractConsts, - functionName: 'get-primary-name', - tip: 'latest', - readOnlyFunctionArgs: { - sender: address, - arguments: [addressHex], - }, + const res = await client.callReadOnlyFunction({ + ...bnsContractConsts, + functionName: 'get-primary-name', + tip: 'latest', + readOnlyFunctionArgs: { + sender: address, + arguments: [addressHex], }, - { signal } - ); + signal, + }); if (!res.okay || !res.result) return null; const { result } = res; // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion @@ -79,7 +78,7 @@ async function fetchBnsxOwner(client: StacksClient, fqn: string): Promise { const fetchFromApi = async () => { - return client.namesApi.getNamesOwnedByAddress({ address, blockchain: 'stacks' }, { signal }); + return client.getNamesOwnedByAddress(address, signal); }; if (isTestnet) { return fetchFromApi(); @@ -144,7 +143,7 @@ export async function fetchNamesForAddress({ */ export async function fetchNameOwner(client: StacksClient, name: string, isTestnet: boolean) { const fetchFromApi = async () => { - const res = await client.namesApi.getNameInfo({ name }); + const res = await client.getNameInfo(name); if (isUndefined(res.address)) return null; if (!isString(res.address) || res.address.length === 0) return null; return res.address; @@ -169,7 +168,7 @@ export async function fetchBtcNameOwner( name: string ): Promise { try { - const nameResponse = await client.namesApi.getNameInfo({ name }); + const nameResponse = await client.getNameInfo(name); const zonefile = parseZoneFile(nameResponse.zonefile); if (!zonefile.txt) return null; const btcRecord = zonefile.txt.find(record => record.name === '_btc._addr'); diff --git a/packages/query/src/stacks/contract/contract.hooks.ts b/packages/query/src/stacks/contract/contract.hooks.ts index 00c4ac712..21fb4df20 100644 --- a/packages/query/src/stacks/contract/contract.hooks.ts +++ b/packages/query/src/stacks/contract/contract.hooks.ts @@ -1,10 +1,10 @@ import type { ContractCallPayload, TransactionPayload } from '@stacks/connect'; import type { ContractInterfaceFunction } from '@stacks/rpc-client'; -import { useGetContractInterface } from './contract.query'; +import { useGetContractInterfaceQuery } from './contract.query'; export function useContractInterface(transactionRequest: ContractCallPayload | null) { - return useGetContractInterface(transactionRequest).data; + return useGetContractInterfaceQuery(transactionRequest).data; } export function useContractFunction(transactionRequest: TransactionPayload | null) { diff --git a/packages/query/src/stacks/contract/contract.query.ts b/packages/query/src/stacks/contract/contract.query.ts index a28bb0094..b4bf58471 100644 --- a/packages/query/src/stacks/contract/contract.query.ts +++ b/packages/query/src/stacks/contract/contract.query.ts @@ -1,28 +1,16 @@ import { type ContractCallPayload, TransactionTypes } from '@stacks/connect'; import { useQuery } from '@tanstack/react-query'; -import type { ContractInterfaceResponseWithFunctions } from '../../../types/contract-types'; -import { useHiroApiRateLimiter } from '../../hiro-rate-limiter'; import { useStacksClient } from '../stacks-client'; -export function useGetContractInterface(transactionRequest: ContractCallPayload | null) { - const { smartContractsApi } = useStacksClient(); - const limiter = useHiroApiRateLimiter(); +export function useGetContractInterfaceQuery(transactionRequest: ContractCallPayload | null) { + const client = useStacksClient(); async function fetchContractInterface() { if (!transactionRequest || transactionRequest?.txType !== TransactionTypes.ContractCall) return; const contractAddress = transactionRequest.contractAddress; const contractName = transactionRequest.contractName; - return limiter.add( - () => - smartContractsApi.getContractInterface({ - contractAddress, - contractName, - }) as unknown as Promise, - { - throwOnTimeout: true, - } - ); + return client.getContractInterface(contractAddress, contractName); } return useQuery({ diff --git a/packages/query/src/stacks/fees/fees.hooks.ts b/packages/query/src/stacks/fees/fees.hooks.ts index 864f667fe..75888d72e 100644 --- a/packages/query/src/stacks/fees/fees.hooks.ts +++ b/packages/query/src/stacks/fees/fees.hooks.ts @@ -1,21 +1,17 @@ import { useMemo } from 'react'; -import { - FeeCalculationTypes, - Fees, - Money, - StacksFeeEstimate, - StacksTxFeeEstimation, -} from '@leather-wallet/models'; -import { createMoney } from '@leather-wallet/utils'; import { StacksTransaction } from '@stacks/transactions'; +import { FeeCalculationTypes, Fees, Money, StacksFeeEstimate } from '@leather-wallet/models'; +import { createMoney } from '@leather-wallet/utils'; + import { useConfigFeeEstimationsMaxEnabled, useConfigFeeEstimationsMaxValues, useConfigFeeEstimationsMinEnabled, useConfigFeeEstimationsMinValues, } from '../../common/remote-config/remote-config.query'; +import { StacksTxFeeEstimation } from '../hiro-api-types'; import { useGetStacksTransactionFeeEstimationQuery } from './fees.query'; import { defaultFeesMaxValuesAsMoney, @@ -56,7 +52,7 @@ function parseStacksTxFeeEstimationResponse({ minValues, txByteLength, }: ParseStacksTxFeeEstimationResponseArgs): Fees { - if (!!feeEstimation.error) return defaultStacksFees; + if (feeEstimation.error) return defaultStacksFees; if (txByteLength && feeEstimationQueryFailedSilently(feeEstimation)) { return { blockchain: 'stacks', @@ -72,7 +68,7 @@ function parseStacksTxFeeEstimationResponse({ }; }); - if (feeEstimation.estimations && feeEstimation.estimations.length) { + if (feeEstimation.estimations?.length) { const feeEstimationsWithCappedValues = getFeeEstimationsWithCappedValues( stacksFeeEstimates, maxValues, diff --git a/packages/query/src/stacks/fees/fees.query.ts b/packages/query/src/stacks/fees/fees.query.ts index de4dfabb5..4fea0964c 100644 --- a/packages/query/src/stacks/fees/fees.query.ts +++ b/packages/query/src/stacks/fees/fees.query.ts @@ -1,31 +1,13 @@ -import { StacksTxFeeEstimation } from '@leather-wallet/models'; import { useQuery } from '@tanstack/react-query'; -import axios from 'axios'; -import PQueue from 'p-queue'; -import { useHiroApiRateLimiter } from '../../hiro-rate-limiter'; -import { useCurrentNetworkState } from '../../leather-query-provider'; import { AppUseQueryConfig } from '../../query-config'; +import { StacksTxFeeEstimation } from '../hiro-api-types'; +import { StacksClient, useStacksClient } from '../stacks-client'; import { defaultApiFeeEstimations } from './fees.utils'; -function fetchTransactionFeeEstimation(currentNetwork: any, limiter: PQueue) { - return async (estimatedLen: number | null, transactionPayload: string) => { - const resp = await limiter.add( - () => - axios.post( - currentNetwork.chain.stacks.url + '/v2/fees/transaction', - { - estimated_len: estimatedLen, - transaction_payload: transactionPayload, - } - ), - { - priority: 2, - throwOnTimeout: true, - } - ); - return resp.data; - }; +function fetchTransactionFeeEstimation(client: StacksClient) { + return async (estimatedLen: number | null, transactionPayload: string) => + client.postFeeTransaction(estimatedLen, transactionPayload); } type FetchTransactionFeeEstimationResp = Awaited< @@ -39,18 +21,14 @@ export function useGetStacksTransactionFeeEstimationQuery< transactionPayload: string, options?: AppUseQueryConfig ) { - const currentNetwork = useCurrentNetworkState(); - const limiter = useHiroApiRateLimiter(); + const client = useStacksClient(); return useQuery({ enabled: transactionPayload !== '', queryKey: ['stacks-tx-fee-estimation', transactionPayload], queryFn: async () => { try { - return await fetchTransactionFeeEstimation(currentNetwork, limiter)( - estimatedLen, - transactionPayload - ); + return await fetchTransactionFeeEstimation(client)(estimatedLen, transactionPayload); } catch (err) { return { cost_scalar_change_by_byte: 0, diff --git a/packages/query/src/stacks/fees/fees.utils.ts b/packages/query/src/stacks/fees/fees.utils.ts index 30cd53989..c19959214 100644 --- a/packages/query/src/stacks/fees/fees.utils.ts +++ b/packages/query/src/stacks/fees/fees.utils.ts @@ -1,17 +1,13 @@ -import { DEFAULT_FEE_RATE } from '@leather-wallet/constants'; -import { - ApiFeeEstimation, - FeeCalculationTypes, - Fees, - Money, - StacksFeeEstimate, - StacksTxFeeEstimation, -} from '@leather-wallet/models'; -import { createMoney } from '@leather-wallet/utils'; import { bytesToHex } from '@stacks/common'; import { StacksTransaction, serializePayload } from '@stacks/transactions'; import { BigNumber } from 'bignumber.js'; +import { DEFAULT_FEE_RATE } from '@leather-wallet/constants'; +import { FeeCalculationTypes, Fees, Money, StacksFeeEstimate } from '@leather-wallet/models'; +import { createMoney } from '@leather-wallet/utils'; + +import { FeeEstimation, StacksTxFeeEstimation } from '../hiro-api-types'; + const defaultFeesMaxValues = [500000, 750000, 2000000]; const defaultFeesMinValues = [2500, 3000, 3500]; @@ -26,7 +22,7 @@ export const defaultFeesMinValuesAsMoney = [ createMoney(defaultFeesMinValues[2], 'STX'), ]; -export const defaultApiFeeEstimations: ApiFeeEstimation[] = [ +export const defaultApiFeeEstimations: FeeEstimation[] = [ { fee: defaultFeesMinValues[0], fee_rate: 0 }, { fee: defaultFeesMinValues[1], fee_rate: 0 }, { fee: defaultFeesMinValues[2], fee_rate: 0 }, @@ -72,9 +68,8 @@ export function getFeeEstimationsWithCappedValues( feeEstimation.fee.amount.isLessThan(feeEstimationsMinValues[index].amount) ) { return { fee: feeEstimationsMinValues[index], feeRate: 0 }; - } else { - return feeEstimation; } + return feeEstimation; }); } diff --git a/packages/query/src/stacks/fetch-wrapper.ts b/packages/query/src/stacks/fetch-wrapper.ts deleted file mode 100644 index 4bd48bbbb..000000000 --- a/packages/query/src/stacks/fetch-wrapper.ts +++ /dev/null @@ -1,48 +0,0 @@ -import axios from 'axios'; - -// import { analytics } from '@shared/utils/analytics'; - -const leatherHeaders: HeadersInit = { - // TODO #40: Need VERSION? - // 'x-leather-version': VERSION, - 'x-hiro-product': 'leather', -}; - -function isErrorCode(statusCode: number) { - return statusCode >= 400; -} - -function trackApiError(url: string, statusCode: number) { - // TODO #40: Use analytics here? - // eslint-disable-next-line no-console - console.log('api_error', { origin: new URL(url).origin, statusCode, url }); - // void analytics.track('api_error', { origin: new URL(url).origin, statusCode, url }); -} - -/** - * @deprecated Use `axios` directly instead. Fetch only needed for interaction - * with generated stacks blockchain api library - */ -export async function wrappedFetch(input: RequestInfo, init: RequestInit = {}) { - const initHeaders = init.headers || {}; - // eslint-disable-next-line no-restricted-globals - const resp = await fetch(input, { - ...init, - credentials: 'omit', - headers: { ...initHeaders, ...leatherHeaders }, - }); - if (isErrorCode(resp.status)) trackApiError(resp.url, resp.status); - 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/packages/query/types/account.ts b/packages/query/src/stacks/hiro-api-types.ts similarity index 64% rename from packages/query/types/account.ts rename to packages/query/src/stacks/hiro-api-types.ts index aff58502f..ad21be977 100644 --- a/packages/query/types/account.ts +++ b/packages/query/src/stacks/hiro-api-types.ts @@ -1,3 +1,5 @@ +import { ContractInterfaceFunction } from '@stacks/rpc-client'; +import { ContractInterfaceResponse } from '@stacks/stacks-blockchain-api-types'; import type { AddressTokenOfferingLocked } from '@stacks/stacks-blockchain-api-types/generated'; type SelectedKeys = @@ -54,3 +56,33 @@ export interface AddressBalanceResponse { >; token_offering_locked?: AddressTokenOfferingLocked; } + +export type ContractInterfaceResponseWithFunctions = Omit< + ContractInterfaceResponse, + 'functions' +> & { + functions: ContractInterfaceFunction[]; +}; + +export interface FeeEstimation { + fee: number; + fee_rate: number; +} + +export interface StacksTxFeeEstimation { + cost_scalar_change_by_byte: number; + estimated_cost: object; + estimated_cost_scalar: number; + estimations: FeeEstimation[]; + error?: string; +} + +export interface NonFungibleTokenHoldingListResult { + asset_identifier: string; + block_height: number; + tx_id: string; + value: { + hex: string; + repr: string; + }; +} diff --git a/packages/query/src/stacks/info/block-time.query.ts b/packages/query/src/stacks/info/block-time.query.ts index 99374160f..ad5e48402 100644 --- a/packages/query/src/stacks/info/block-time.query.ts +++ b/packages/query/src/stacks/info/block-time.query.ts @@ -7,7 +7,7 @@ export function useGetStackNetworkBlockTimeQuery() { return useQuery({ queryKey: ['stacks-block-time'], - queryFn: () => client.infoApi.getNetworkBlockTimes(), + queryFn: () => client.getNetworkBlockTimes(), refetchOnWindowFocus: false, refetchOnMount: false, }); diff --git a/packages/query/src/stacks/leather-headers.ts b/packages/query/src/stacks/leather-headers.ts new file mode 100644 index 000000000..656d55453 --- /dev/null +++ b/packages/query/src/stacks/leather-headers.ts @@ -0,0 +1,12 @@ +import axios from 'axios'; + +const leatherHeaders: HeadersInit = { + 'x-hiro-product': 'leather', +}; + +axios.interceptors.request.use(request => { + if (request.url?.includes('hiro.so')) + Object.entries(leatherHeaders).forEach(([key, value]) => request.headers.set(key, value)); + + return request; +}); diff --git a/packages/query/src/stacks/mempool/mempool.hooks.ts b/packages/query/src/stacks/mempool/mempool.hooks.ts index 27c4e911f..61d7aeb4c 100644 --- a/packages/query/src/stacks/mempool/mempool.hooks.ts +++ b/packages/query/src/stacks/mempool/mempool.hooks.ts @@ -1,8 +1,9 @@ import { useMemo } from 'react'; -import { increaseValueByOneMicroStx, microStxToStx } from '@leather-wallet/utils'; import { MempoolTransaction } from '@stacks/stacks-blockchain-api-types'; +import { increaseValueByOneMicroStx, isDefined, microStxToStx } from '@leather-wallet/utils'; + import { useTransactionsById } from '../transactions/transactions-by-id.query'; import { useStacksConfirmedTransactions } from '../transactions/transactions-with-transfers.hooks'; import { useAccountMempoolQuery } from './mempool.query'; @@ -33,7 +34,8 @@ export function useStacksPendingTransactions(address: string) { } return true; }) - .filter(tx => !!tx) as MempoolTransaction[], + .filter(tx => !!tx) + .filter(isDefined) as MempoolTransaction[], }; }, [txs, query]); } diff --git a/packages/query/src/stacks/mempool/mempool.query.ts b/packages/query/src/stacks/mempool/mempool.query.ts index 6d333f60a..33ce669c9 100644 --- a/packages/query/src/stacks/mempool/mempool.query.ts +++ b/packages/query/src/stacks/mempool/mempool.query.ts @@ -1,26 +1,17 @@ import { MempoolTransactionListResponse } from '@stacks/stacks-blockchain-api-types'; import { UseQueryResult, useQuery } from '@tanstack/react-query'; -import { useHiroApiRateLimiter } from '../../hiro-rate-limiter'; import { useStacksClient } from '../stacks-client'; export function useAccountMempoolQuery( address: string ): UseQueryResult { const client = useStacksClient(); - const limiter = useHiroApiRateLimiter(); - - async function accountMempoolFetcher() { - return limiter.add( - () => client.transactionsApi.getAddressMempoolTransactions({ address, limit: 50 }), - { throwOnTimeout: true } - ); - } return useQuery({ enabled: !!address, queryKey: ['account-mempool', address], - queryFn: accountMempoolFetcher, + queryFn: () => client.getAddressMempoolTransactions(address), refetchOnWindowFocus: false, }); } diff --git a/packages/query/src/stacks/mempool/mempool.utils.ts b/packages/query/src/stacks/mempool/mempool.utils.ts index 163cdd46e..f2ec640f6 100644 --- a/packages/query/src/stacks/mempool/mempool.utils.ts +++ b/packages/query/src/stacks/mempool/mempool.utils.ts @@ -1,10 +1,11 @@ -import { createMoney, sumNumbers } from '@leather-wallet/utils'; import type { MempoolTokenTransferTransaction, MempoolTransaction, Transaction, } from '@stacks/stacks-blockchain-api-types'; +import { createMoney, sumNumbers } from '@leather-wallet/utils'; + type PendingTransactionType = 'inbound' | 'outbound'; function getInboundPendingTxs( diff --git a/packages/query/src/stacks/network/network.query.ts b/packages/query/src/stacks/network/network.query.ts index 1866f9d7c..ad72e920d 100644 --- a/packages/query/src/stacks/network/network.query.ts +++ b/packages/query/src/stacks/network/network.query.ts @@ -1,8 +1,6 @@ import { useQuery } from '@tanstack/react-query'; -import axios from 'axios'; -import PQueue from 'p-queue'; -import { useHiroApiRateLimiter } from '../../hiro-rate-limiter'; +import { useStacksClient } from '../stacks-client'; const staleTime = 15 * 60 * 1000; // 15 min @@ -14,21 +12,12 @@ const networkStatusQueryOptions = { refetchOnReconnect: false, } as const; -async function getNetworkStatusFetcher(url: string, limiter: PQueue) { - const resp = await limiter.add(() => axios.get(url, { timeout: 30000 }), { - throwOnTimeout: true, - priority: 1, - }); - - return resp.data; -} - export function useGetNetworkStatus(url: string) { - const limiter = useHiroApiRateLimiter(); + const client = useStacksClient(); return useQuery({ queryKey: ['network-status', url], - queryFn: () => getNetworkStatusFetcher(url, limiter), + queryFn: () => client.getNetworkStatus(url), ...networkStatusQueryOptions, }); } diff --git a/packages/query/src/stacks/nonce/account-nonces.query.ts b/packages/query/src/stacks/nonce/account-nonces.query.ts index b5d555a6b..7c6f31278 100644 --- a/packages/query/src/stacks/nonce/account-nonces.query.ts +++ b/packages/query/src/stacks/nonce/account-nonces.query.ts @@ -1,7 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import type PQueue from 'p-queue'; -import { useHiroApiRateLimiter } from '../../hiro-rate-limiter'; import { useCurrentNetworkState } from '../../leather-query-provider'; import type { AppUseQueryConfig } from '../../query-config'; import { type StacksClient, useStacksClient } from '../stacks-client'; @@ -12,14 +10,8 @@ const queryOptions = { refetchOnWindowFocus: 'always', } as const; -function fetchAccountNonces(client: StacksClient, limiter: PQueue) { - return async (address: string) => { - if (!address) return; - - return limiter.add(() => client.accountsApi.getAccountNonces({ principal: address }), { - throwOnTimeout: true, - }); - }; +function fetchAccountNonces(client: StacksClient) { + return async (address: string) => client.getAccountNonces(address); } type FetchAccountNoncesResp = Awaited>>; @@ -30,12 +22,11 @@ export function useGetAccountNoncesQuery fetchAccountNonces(client, limiter)(address), + queryFn: () => fetchAccountNonces(client)(address), ...queryOptions, ...options, }); diff --git a/packages/query/src/stacks/nonce/account-nonces.utils.ts b/packages/query/src/stacks/nonce/account-nonces.utils.ts index 03c2a0a51..3efead55a 100644 --- a/packages/query/src/stacks/nonce/account-nonces.utils.ts +++ b/packages/query/src/stacks/nonce/account-nonces.utils.ts @@ -1,5 +1,8 @@ -import type { AddressNonces } from '@stacks/blockchain-api-client/lib/generated'; -import type { MempoolTransaction, Transaction } from '@stacks/stacks-blockchain-api-types'; +import type { + AddressNonces, + MempoolTransaction, + Transaction, +} from '@stacks/stacks-blockchain-api-types'; enum NonceTypes { apiSuggestedNonce = 'api-suggested-nonce', diff --git a/packages/query/src/stacks/sip10/sip10-tokens.utils.ts b/packages/query/src/stacks/sip10/sip10-tokens.utils.ts index 30bf076ca..148be3b3b 100644 --- a/packages/query/src/stacks/sip10/sip10-tokens.utils.ts +++ b/packages/query/src/stacks/sip10/sip10-tokens.utils.ts @@ -1,4 +1,5 @@ import type { FtMetadataResponse } from '@hirosystems/token-metadata-api-client'; + import type { CryptoAssetBalance, Sip10CryptoAssetInfo } from '@leather-wallet/models'; import { getPrincipalFromContractId, getTicker, isUndefined } from '@leather-wallet/utils'; diff --git a/packages/query/src/stacks/stacks-client.ts b/packages/query/src/stacks/stacks-client.ts index 02eff9c35..40473dc4a 100644 --- a/packages/query/src/stacks/stacks-client.ts +++ b/packages/query/src/stacks/stacks-client.ts @@ -1,91 +1,227 @@ -import { TokensApi } from '@hirosystems/token-metadata-api-client'; -import { STX20_API_BASE_URL_MAINNET } from '@leather-wallet/models'; -import { - AccountsApi, - BlocksApi, - Configuration, - type ConfigurationParameters, - FaucetsApi, - FeesApi, - FungibleTokensApi, - InfoApi, - NamesApi, - NonFungibleTokensApi, - RosettaApi, - SearchApi, - SmartContractsApi, - TransactionsApi, -} from '@stacks/blockchain-api-client'; +import { FtMetadataResponse, NftMetadataResponse } from '@hirosystems/token-metadata-api-client'; +import type { + AddressNonces, + AddressTransactionsWithTransfersListResponse, + BnsGetNameInfoResponse, + BnsNamesOwnByAddressResponse, + GetRawTransactionResult, + MempoolTransaction, + MempoolTransactionListResponse, + NetworkBlockTimesResponse, + ReadOnlyFunctionArgs, + ReadOnlyFunctionSuccessResponse, + Transaction, +} from '@stacks/stacks-blockchain-api-types'; import axios from 'axios'; +import { DEFAULT_LIST_LIMIT } from '@leather-wallet/constants'; +import { STX20_API_BASE_URL_MAINNET } from '@leather-wallet/models'; + +import { Paginated } from '../../types/api-types'; +import { getHiroApiRateLimiter } from '../hiro-rate-limiter'; import { useLeatherNetwork } from '../leather-query-provider'; -import { wrappedFetch as fetchApi } from './fetch-wrapper'; +import type { + AddressBalanceResponse, + ContractInterfaceResponseWithFunctions, + NonFungibleTokenHoldingListResult, + StacksTxFeeEstimation, +} from './hiro-api-types'; +import type { Stx20BalanceResponse } from './stx20-api-types'; -export interface Stx20Balance { - ticker: string; - balance: string; - updateDate: string; -} +type NonFungibleTokenHoldingsResponse = Paginated; -interface Stx20BalanceResponse { - address: string; - balances: Stx20Balance[]; +export interface CallReadOnlyFunctionArgs { + contractAddress: string; + contractName: string; + functionName: string; + readOnlyFunctionArgs: ReadOnlyFunctionArgs; + tip?: string; + signal?: AbortSignal; } -function Stx20Api() { - const url = STX20_API_BASE_URL_MAINNET; +export function stacksClient(basePath: string) { + const rateLimiter = getHiroApiRateLimiter(basePath); return { + async getAccountBalance(address: string, signal?: AbortSignal) { + const resp = await rateLimiter.add( + () => + axios.get(`${basePath}/extended/v1/address/${address}/balances`, { + signal, + }), + { signal, throwOnTimeout: true } + ); + return resp.data; + }, + async getAccountNonces(address: string, signal?: AbortSignal) { + const resp = await rateLimiter.add( + () => + axios.get(`${basePath}/extended/v1/address/${address}/nonces`, { signal }), + { throwOnTimeout: true } + ); + return resp.data; + }, + // TODO: Need to replace, this endpoint has been deprecated + async getAccountTransactionsWithTransfers(address: string, signal?: AbortSignal) { + const resp = await rateLimiter.add( + () => + axios.get( + `${basePath}/extended/v1/address/${address}/transactions_with_transfers?limit=${DEFAULT_LIST_LIMIT}`, + { signal } + ), + { throwOnTimeout: true } + ); + return resp.data; + }, + async postFeeTransaction(estimatedLen: number | null, transactionPayload: string) { + const resp = await rateLimiter.add( + () => + axios.post(`${basePath}/v2/fees/transaction`, { + estimated_len: estimatedLen, + transaction_payload: transactionPayload, + }), + { + priority: 2, + throwOnTimeout: true, + } + ); + return resp.data; + }, + async getNetworkBlockTimes() { + const resp = await rateLimiter.add( + () => + axios.get(`${basePath}/extended/v1/info/network_block_times`), + { throwOnTimeout: true } + ); + return resp.data; + }, + async getNamesOwnedByAddress(address: string, signal?: AbortSignal) { + const resp = await rateLimiter.add( + () => + axios.get(`${basePath}/v1/addresses/stacks/${address}`, { + signal, + }), + { priority: 2, signal, throwOnTimeout: true } + ); + return resp.data; + }, + async getNameInfo(name: string, signal?: AbortSignal) { + const resp = await rateLimiter.add( + () => + axios.get(`${basePath}/v1/names/${name}`, { + signal, + }), + { throwOnTimeout: true } + ); + return resp.data; + }, + async getNetworkStatus(url: string) { + const resp = await rateLimiter.add(() => axios.get(url, { timeout: 30000 }), { + throwOnTimeout: true, + priority: 1, + }); + + return resp.data; + }, + async getNftHoldings(address: string) { + const resp = await rateLimiter.add( + () => + axios.get( + `${basePath}/extended/v1/tokens/nft/holdings?principal=${address}&limit=${DEFAULT_LIST_LIMIT}` + ), + { throwOnTimeout: true } + ); + return resp.data; + }, + async getAddressMempoolTransactions(address: string) { + const resp = await rateLimiter.add( + () => + axios.get( + `${basePath}/extended/v2/addresses/${address}/transactions?limit=${DEFAULT_LIST_LIMIT}` + ), + { throwOnTimeout: true } + ); + return resp.data; + }, + async getRawTransactionById(txId: string) { + const resp = await rateLimiter.add( + () => axios.get(`${basePath}/extended/v1/tx/${txId}/raw`), + { throwOnTimeout: true } + ); + return resp.data; + }, + async getTransactionById(txId: string) { + const resp = await rateLimiter.add( + () => axios.get(`${basePath}/extended/v1/tx/${txId}`), + { throwOnTimeout: true } + ); + return resp.data; + }, + async getFtMetadata(address: string) { + const resp = await rateLimiter.add( + () => axios.get(`${basePath}/metadata/v1/ft/${address}`), + { throwOnTimeout: true } + ); + return resp.data; + }, + async getNftMetadata(address: string, tokenId: number) { + const resp = await rateLimiter.add( + () => axios.get(`${basePath}/metadata/v1/nft/${address}/${tokenId}`), + { throwOnTimeout: true } + ); + return resp.data; + }, + async callReadOnlyFunction({ + contractAddress, + contractName, + functionName, + readOnlyFunctionArgs, + tip, + signal, + }: CallReadOnlyFunctionArgs) { + const resp = await rateLimiter.add( + () => + axios.post( + `${basePath}/v2/contracts/call-read/${contractAddress}/${contractName}/${functionName}?tip=${tip}`, + { + ...readOnlyFunctionArgs, + signal, + } + ), + { signal, throwOnTimeout: true } + ); + return resp.data; + }, + async getContractInterface( + contractAddress: string, + contractName: string, + signal?: AbortSignal + ) { + const resp = await rateLimiter.add( + () => + axios.get( + `${basePath}/v2/contracts/interface/${contractAddress}/${contractName}`, + { + signal, + } + ), + { throwOnTimeout: true } + ); + return resp.data; + }, async getStx20Balances(address: string) { - const resp = await axios.get(`${url}/balance/${address}`); + const resp = await axios.get( + `${STX20_API_BASE_URL_MAINNET}/balance/${address}` + ); return resp.data.balances; }, }; } -export interface StacksClient { - smartContractsApi: SmartContractsApi; - accountsApi: AccountsApi; - infoApi: InfoApi; - transactionsApi: TransactionsApi; - blocksApi: BlocksApi; - faucetsApi: FaucetsApi; - namesApi: NamesApi; - feesApi: FeesApi; - searchApi: SearchApi; - rosettaApi: RosettaApi; - fungibleTokensApi: FungibleTokensApi; - nonFungibleTokensApi: NonFungibleTokensApi; - tokensApi: TokensApi; - stx20Api: ReturnType; -} - -export function stacksClient(configParams: ConfigurationParameters): StacksClient { - const config = new Configuration(configParams); - - return { - smartContractsApi: new SmartContractsApi(config), - accountsApi: new AccountsApi(config), - infoApi: new InfoApi(config), - transactionsApi: new TransactionsApi(config), - blocksApi: new BlocksApi(config), - faucetsApi: new FaucetsApi(config), - namesApi: new NamesApi(config), - feesApi: new FeesApi(config), - searchApi: new SearchApi(config), - rosettaApi: new RosettaApi(config), - fungibleTokensApi: new FungibleTokensApi(config), - nonFungibleTokensApi: new NonFungibleTokensApi(config), - tokensApi: new TokensApi({ basePath: config.basePath }), - stx20Api: Stx20Api(), - }; -} +export type StacksClient = ReturnType; export function useStacksClient() { const network = useLeatherNetwork(); - return stacksClient({ - basePath: network.chain.stacks.url, - fetchApi, - }); + return stacksClient(network.chain.stacks.url); } diff --git a/packages/query/src/stacks/stx20-api-types.ts b/packages/query/src/stacks/stx20-api-types.ts new file mode 100644 index 000000000..73f21854c --- /dev/null +++ b/packages/query/src/stacks/stx20-api-types.ts @@ -0,0 +1,10 @@ +export interface Stx20Balance { + ticker: string; + balance: string; + updateDate: string; +} + +export interface Stx20BalanceResponse { + address: string; + balances: Stx20Balance[]; +} diff --git a/packages/query/src/stacks/stx20/stx20-tokens.hooks.ts b/packages/query/src/stacks/stx20/stx20-tokens.hooks.ts index 1f98c7290..b8c2296e0 100644 --- a/packages/query/src/stacks/stx20/stx20-tokens.hooks.ts +++ b/packages/query/src/stacks/stx20/stx20-tokens.hooks.ts @@ -1,8 +1,9 @@ +import BigNumber from 'bignumber.js'; + import { type Stx20CryptoAssetInfo, createCryptoAssetBalance } from '@leather-wallet/models'; import { createMoney } from '@leather-wallet/utils'; -import BigNumber from 'bignumber.js'; -import type { Stx20Balance } from '../stacks-client'; +import type { Stx20Balance } from '../stx20-api-types'; import { useStx20BalancesQuery } from './stx20-tokens.query'; function createStx20CryptoAssetInfo(stx20Balance: Stx20Balance): Stx20CryptoAssetInfo { diff --git a/packages/query/src/stacks/stx20/stx20-tokens.query.ts b/packages/query/src/stacks/stx20/stx20-tokens.query.ts index 7d97c5a1b..326e8444e 100644 --- a/packages/query/src/stacks/stx20/stx20-tokens.query.ts +++ b/packages/query/src/stacks/stx20/stx20-tokens.query.ts @@ -2,8 +2,9 @@ import { ChainID } from '@stacks/transactions'; import { useQuery } from '@tanstack/react-query'; import { useCurrentNetworkState } from '../../leather-query-provider'; -import { AppUseQueryConfig } from '../../query-config'; -import { type Stx20Balance, useStacksClient } from '../stacks-client'; +import type { AppUseQueryConfig } from '../../query-config'; +import { useStacksClient } from '../stacks-client'; +import type { Stx20Balance } from '../stx20-api-types'; export function useStx20BalancesQuery( address: string, @@ -15,7 +16,7 @@ export function useStx20BalancesQuery( return useQuery({ enabled: network.chain.stacks.chainId === ChainID.Mainnet, queryKey: ['stx20-balances', address], - queryFn: () => client.stx20Api.getStx20Balances(address), + queryFn: () => client.getStx20Balances(address), ...options, }); } diff --git a/packages/query/src/stacks/token-metadata/fungible-tokens/fungible-token-metadata.query.ts b/packages/query/src/stacks/token-metadata/fungible-tokens/fungible-token-metadata.query.ts index 791f94425..d31e097f6 100644 --- a/packages/query/src/stacks/token-metadata/fungible-tokens/fungible-token-metadata.query.ts +++ b/packages/query/src/stacks/token-metadata/fungible-tokens/fungible-token-metadata.query.ts @@ -1,12 +1,11 @@ -import { createCryptoAssetBalance } from '@leather-wallet/models'; -import { createMoney, getPrincipalFromContractId, getTicker } from '@leather-wallet/utils'; import { useQueries, useQuery } from '@tanstack/react-query'; import BigNumber from 'bignumber.js'; -import PQueue from 'p-queue'; -import { AddressBalanceResponse } from '../../../../types/account'; -import { useHiroApiRateLimiter } from '../../../hiro-rate-limiter'; +import { createCryptoAssetBalance } from '@leather-wallet/models'; +import { createMoney, getPrincipalFromContractId, getTicker } from '@leather-wallet/utils'; + import { useCurrentNetworkState } from '../../../leather-query-provider'; +import { AddressBalanceResponse } from '../../hiro-api-types'; import { createSip10CryptoAssetInfo } from '../../sip10/sip10-tokens.utils'; import { type StacksClient, useStacksClient } from '../../stacks-client'; import { getStacksContractIdStringParts } from '../../temp-utils'; @@ -25,22 +24,19 @@ const queryOptions = { retry: 0, } as const; -function fetchFungibleTokenMetadata(client: StacksClient, limiter: PQueue) { +function fetchFungibleTokenMetadata(client: StacksClient) { return (principal: string) => async () => { - return limiter.add(() => client.tokensApi.getFtMetadata(principal), { - throwOnTimeout: true, - }) as unknown as FtAssetResponse; + return client.getFtMetadata(principal) as unknown as FtAssetResponse; }; } export function useGetFungibleTokenMetadataQuery(principal: string) { const client = useStacksClient(); const network = useCurrentNetworkState(); - const limiter = useHiroApiRateLimiter(); return useQuery({ queryKey: ['get-ft-metadata', principal, network.chain.stacks.url], - queryFn: fetchFungibleTokenMetadata(client, limiter)(principal), + queryFn: fetchFungibleTokenMetadata(client)(principal), ...queryOptions, }); } @@ -50,7 +46,6 @@ export function useGetFungibleTokensBalanceMetadataQuery( ) { const client = useStacksClient(); const network = useCurrentNetworkState(); - const limiter = useHiroApiRateLimiter(); return useQueries({ queries: Object.entries(ftBalances).map(([key, value]) => { @@ -58,7 +53,7 @@ export function useGetFungibleTokensBalanceMetadataQuery( return { enabled: !!principal, queryKey: ['get-ft-metadata', principal, network.chain.stacks.url], - queryFn: fetchFungibleTokenMetadata(client, limiter)(principal), + queryFn: fetchFungibleTokenMetadata(client)(principal), select: (resp: FtAssetResponse) => { if (!(resp && isFtAsset(resp))) return; const { contractAssetName } = getStacksContractIdStringParts(key); @@ -80,7 +75,6 @@ export function useGetFungibleTokensBalanceMetadataQuery( export function useGetFungibleTokensMetadataQuery(keys: string[]) { const client = useStacksClient(); const network = useCurrentNetworkState(); - const limiter = useHiroApiRateLimiter(); return useQueries({ queries: keys.map(key => { @@ -88,7 +82,7 @@ export function useGetFungibleTokensMetadataQuery(keys: string[]) { return { enabled: !!principal, queryKey: ['get-ft-metadata', principal, network.chain.stacks.url], - queryFn: fetchFungibleTokenMetadata(client, limiter)(principal), + queryFn: fetchFungibleTokenMetadata(client)(principal), select: (resp: FtAssetResponse) => { if (!(resp && isFtAsset(resp))) return; return createSip10CryptoAssetInfo(key, resp); diff --git a/packages/query/src/stacks/token-metadata/non-fungible-tokens/non-fungible-token-holdings.query.ts b/packages/query/src/stacks/token-metadata/non-fungible-tokens/non-fungible-token-holdings.query.ts index e21eaee83..2f3497f4b 100644 --- a/packages/query/src/stacks/token-metadata/non-fungible-tokens/non-fungible-token-holdings.query.ts +++ b/packages/query/src/stacks/token-metadata/non-fungible-tokens/non-fungible-token-holdings.query.ts @@ -1,54 +1,29 @@ import { useQuery } from '@tanstack/react-query'; -import PQueue from 'p-queue'; -import { Paginated } from '../../../../types/api-types'; -import { useHiroApiRateLimiter } from '../../../hiro-rate-limiter'; import { useCurrentNetworkState } from '../../../leather-query-provider'; import { QueryPrefixes } from '../../../query-prefixes'; import { StacksClient, useStacksClient } from '../../stacks-client'; const staleTime = 15 * 60 * 1000; // 15 min -interface NonFungibleTokenHoldingListResult { - asset_identifier: string; - value: { - hex: string; - repr: string; - }; - block_height: number; - tx_id: string; -} - const queryOptions = { cacheTime: staleTime, staleTime, refetchhOnFocus: false } as const; -type FetchNonFungibleTokenHoldingsResp = Paginated; - -function fetchNonFungibleTokenHoldings(client: StacksClient, limiter: PQueue) { +function fetchNonFungibleTokenHoldings(client: StacksClient) { return async (address: string) => { if (!address) return; - return limiter.add( - () => - client.nonFungibleTokensApi.getNftHoldings({ - principal: address, - limit: 50, - }) as unknown as Promise, - { - throwOnTimeout: true, - } - ); + return client.getNftHoldings(address); }; } -function makeNonFungibleTokenHoldingsQuery( +export function createNonFungibleTokenHoldingsQuery( address: string, network: string, - client: StacksClient, - limiter: PQueue + client: StacksClient ) { return { enabled: !!address, queryKey: [QueryPrefixes.GetNftHoldings, address, network], - queryFn: () => fetchNonFungibleTokenHoldings(client, limiter)(address), + queryFn: () => fetchNonFungibleTokenHoldings(client)(address), ...queryOptions, }; } @@ -56,9 +31,6 @@ function makeNonFungibleTokenHoldingsQuery( export function useGetNonFungibleTokenHoldingsQuery(address: string) { const client = useStacksClient(); const network = useCurrentNetworkState(); - const limiter = useHiroApiRateLimiter(); - return useQuery( - makeNonFungibleTokenHoldingsQuery(address, network.chain.stacks.url, client, limiter) - ); + return useQuery(createNonFungibleTokenHoldingsQuery(address, network.chain.stacks.url, client)); } diff --git a/packages/query/src/stacks/token-metadata/non-fungible-tokens/non-fungible-token-metadata.query.ts b/packages/query/src/stacks/token-metadata/non-fungible-tokens/non-fungible-token-metadata.query.ts index 4b63962b9..776ab19c5 100644 --- a/packages/query/src/stacks/token-metadata/non-fungible-tokens/non-fungible-token-metadata.query.ts +++ b/packages/query/src/stacks/token-metadata/non-fungible-tokens/non-fungible-token-metadata.query.ts @@ -1,8 +1,8 @@ -import { getPrincipalFromContractId } from '@leather-wallet/utils'; import { hexToCV } from '@stacks/transactions'; import { type UseQueryResult, useQueries } from '@tanstack/react-query'; -import { useHiroApiRateLimiter } from '../../../hiro-rate-limiter'; +import { getPrincipalFromContractId } from '@leather-wallet/utils'; + import { QueryPrefixes } from '../../../query-prefixes'; import { useStacksClient } from '../../stacks-client'; import type { NftAssetResponse } from '../token-metadata.utils'; @@ -27,7 +27,6 @@ export function useGetNonFungibleTokenMetadataListQuery( address: string ): UseQueryResult[] { const client = useStacksClient(); - const limiter = useHiroApiRateLimiter(); const nftHoldings = useGetNonFungibleTokenHoldingsQuery(address); return useQueries({ @@ -38,11 +37,7 @@ export function useGetNonFungibleTokenMetadataListQuery( return { enabled: !!tokenId, queryKey: [QueryPrefixes.GetNftMetadata, principal, tokenId], - queryFn: async () => { - return limiter.add(() => client.tokensApi.getNftMetadata(principal, tokenId), { - throwOnTimeout: true, - }); - }, + queryFn: () => client.getNftMetadata(principal, tokenId), retry(_count: number, error: Response) { if (statusCodeNotFoundOrNotProcessable(error.status)) return false; return true; diff --git a/packages/query/src/stacks/token-metadata/token-metadata.utils.ts b/packages/query/src/stacks/token-metadata/token-metadata.utils.ts index 9d8858f89..febac02a9 100644 --- a/packages/query/src/stacks/token-metadata/token-metadata.utils.ts +++ b/packages/query/src/stacks/token-metadata/token-metadata.utils.ts @@ -1,4 +1,4 @@ -import { +import type { FtMetadataResponse, NftMetadataResponse, NotFoundErrorResponse, diff --git a/packages/query/src/stacks/transactions/transactions-by-id.query.ts b/packages/query/src/stacks/transactions/transactions-by-id.query.ts index 5275fa0dc..e0857f95c 100644 --- a/packages/query/src/stacks/transactions/transactions-by-id.query.ts +++ b/packages/query/src/stacks/transactions/transactions-by-id.query.ts @@ -1,7 +1,5 @@ -import { MempoolTransaction, Transaction } from '@stacks/stacks-blockchain-api-types/generated'; import { useQueries, useQuery } from '@tanstack/react-query'; -import { useHiroApiRateLimiter } from '../../hiro-rate-limiter'; import { useStacksClient } from '../stacks-client'; const options = { @@ -13,15 +11,9 @@ const options = { export function useTransactionsById(txids: string[]) { const client = useStacksClient(); - const limiter = useHiroApiRateLimiter(); async function transactionByIdFetcher(txId: string) { - return limiter.add( - () => client.transactionsApi.getTransactionById({ txId }) as unknown as MempoolTransaction, - { - throwOnTimeout: true, - } - ); + return client.getTransactionById(txId); } return useQueries({ @@ -37,17 +29,9 @@ export function useTransactionsById(txids: string[]) { export function useTransactionById(txid: string) { const client = useStacksClient(); - const limiter = useHiroApiRateLimiter(); + async function transactionByIdFetcher(txId: string) { - return limiter.add( - () => - client.transactionsApi.getTransactionById({ txId }) as unknown as - | Transaction - | MempoolTransaction, - { - throwOnTimeout: true, - } - ); + return client.getTransactionById(txId); } return useQuery({ diff --git a/packages/query/src/stacks/transactions/transactions-with-transfers.query.ts b/packages/query/src/stacks/transactions/transactions-with-transfers.query.ts index 92caf5a90..1de8e83fd 100644 --- a/packages/query/src/stacks/transactions/transactions-with-transfers.query.ts +++ b/packages/query/src/stacks/transactions/transactions-with-transfers.query.ts @@ -1,12 +1,9 @@ -import { DEFAULT_LIST_LIMIT } from '@leather-wallet/constants'; -import { AddressTransactionsWithTransfersListResponse } from '@stacks/stacks-blockchain-api-types'; -import { UseQueryOptions, UseQueryResult, useQuery } from '@tanstack/react-query'; +import { useQuery } from '@tanstack/react-query'; -import { useHiroApiRateLimiter } from '../../hiro-rate-limiter'; import { useCurrentNetworkState } from '../../leather-query-provider'; -import { useStacksClient } from '../stacks-client'; +import { StacksClient, useStacksClient } from '../stacks-client'; -const queryOptions: UseQueryOptions = { +const queryOptions = { staleTime: 60 * 1000, refetchInterval: 30_000, refetchOnMount: false, @@ -14,30 +11,18 @@ const queryOptions: UseQueryOptions = { refetchOnWindowFocus: true, }; +function fetchAccountTxsWithTransfers(client: StacksClient, signal?: AbortSignal) { + return async (address: string) => client.getAccountTransactionsWithTransfers(address, signal); +} + export function useGetAccountTransactionsWithTransfersQuery(address: string) { - const { chain } = useCurrentNetworkState(); + const network = useCurrentNetworkState(); const client = useStacksClient(); - const limiter = useHiroApiRateLimiter(); - - async function fetchAccountTxsWithTransfers(signal?: AbortSignal) { - if (!address) return; - return limiter.add( - () => - client.accountsApi.getAccountTransactionsWithTransfers({ - principal: address, - limit: DEFAULT_LIST_LIMIT, - }), - { - signal, - throwOnTimeout: true, - } - ); - } return useQuery({ - enabled: !!address && !!chain.stacks.url, - queryKey: ['account-txs-with-transfers', address, chain.stacks.url], - queryFn: ({ signal }) => fetchAccountTxsWithTransfers(signal), + enabled: !!address && !!network.chain.stacks.url, + queryKey: ['account-txs-with-transfers', address, network.chain.stacks.url], + queryFn: ({ signal }) => fetchAccountTxsWithTransfers(client, signal)(address), ...queryOptions, - }) as UseQueryResult; + }); } diff --git a/packages/query/types/contract-types.ts b/packages/query/types/contract-types.ts deleted file mode 100644 index 84eb7fce5..000000000 --- a/packages/query/types/contract-types.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ContractInterfaceFunction } from '@stacks/rpc-client'; -import { ContractInterfaceResponse } from '@stacks/stacks-blockchain-api-types'; - -export type ContractInterfaceResponseWithFunctions = Omit< - ContractInterfaceResponse, - 'functions' -> & { - functions: ContractInterfaceFunction[]; -}; diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index b4960848f..338c13946 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,6 +1,7 @@ +import { BigNumber } from 'bignumber.js'; + import { KEBAB_REGEX } from '@leather-wallet/constants'; import type { NetworkModes } from '@leather-wallet/models'; -import { BigNumber } from 'bignumber.js'; export { createCounter } from './counter'; export * from './math'; diff --git a/packages/utils/src/sort-assets.ts b/packages/utils/src/sort-assets.ts index 46a176269..a8a66beb9 100644 --- a/packages/utils/src/sort-assets.ts +++ b/packages/utils/src/sort-assets.ts @@ -1,4 +1,4 @@ -import { Money } from '@leather-wallet/models'; +import type { Money } from '@leather-wallet/models'; export function sortAssetsByName(assets: T) { return assets diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 36fb09871..f4ec62ae3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -477,9 +477,6 @@ importers: '@scure/btc-signer': specifier: 1.3.2 version: 1.3.2 - '@stacks/blockchain-api-client': - specifier: 6.3.4 - version: 6.3.4 '@stacks/common': specifier: 6.13.0 version: 6.13.0 @@ -3586,15 +3583,9 @@ packages: '@sinonjs/fake-timers@10.3.0': resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} - '@socket.io/component-emitter@3.0.0': - resolution: {integrity: sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q==} - '@stacks/auth@6.15.0': resolution: {integrity: sha512-foL5tXWGhOxtU8t/sGnQB+mFPYL22Zy+kZvdhce/qwev+whx/DhJJtwdF9xnFk3ZZ9XE0dQGwxiddE/q7GZ7Pw==} - '@stacks/blockchain-api-client@6.3.4': - resolution: {integrity: sha512-4O9qe7m2XKG8PNZ9n5cvhji95IDZ29WO1X2ICgeBPdGc5Y0WGmo0wgIFAROh37pGSkBJsuJjy15ICdP47iy8+w==} - '@stacks/common@6.13.0': resolution: {integrity: sha512-wwzyihjaSdmL6NxKvDeayy3dqM0L0Q2sawmdNtzJDi0FnXuJGm5PeapJj7bEfcI9XwI7Bw5jZoC6mCn9nc5YIw==} @@ -4421,9 +4412,6 @@ packages: '@types/uuid@9.0.8': resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} - '@types/ws@7.4.7': - resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} - '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -5019,9 +5007,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - backo2@1.0.2: - resolution: {integrity: sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==} - balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -5612,9 +5597,6 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true - cross-fetch@3.1.5: - resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==} - cross-fetch@3.1.8: resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} @@ -6084,13 +6066,6 @@ packages: endent@2.1.0: resolution: {integrity: sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w==} - engine.io-client@6.1.1: - resolution: {integrity: sha512-V05mmDo4gjimYW+FGujoGmmmxRaDsrVr7AXA3ZIfa04MWM1jOfZfUwou0oNqhNwy/votUDvGDt4JA4QF4e0b4g==} - - engine.io-parser@5.0.7: - resolution: {integrity: sha512-P+jDFbvK6lE3n1OL+q9KuzdOFWkkZ/cMV9gol/SbVfpyqfvrfrFTOFJ6fQm2VC3PZHlU3QPhVwmbsCnauHF2MQ==} - engines: {node: '>=10.0.0'} - enhanced-resolve@5.16.0: resolution: {integrity: sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==} engines: {node: '>=10.13.0'} @@ -6390,9 +6365,6 @@ packages: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} - eventemitter3@4.0.7: - resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} @@ -6974,9 +6946,6 @@ packages: has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} - has-cors@1.1.0: - resolution: {integrity: sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==} - has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} @@ -7825,9 +7794,6 @@ packages: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} - jsonrpc-lite@2.2.0: - resolution: {integrity: sha512-/cbbSxtZWs1O7R4tWqabrCM/t3N8qKUZMAg9IUqpPvUs6UyRvm6pCNYkskyKN/XU0UgffW+NY2ZRr8t0AknX7g==} - jsontokens@4.0.1: resolution: {integrity: sha512-+MO415LEN6M+3FGsRz4wU20g7N2JA+2j9d9+pGaNJHviG4L8N0qzavGyENw6fJqsq9CcrHOIL6iWX5yeTZ86+Q==} @@ -8539,15 +8505,6 @@ packages: node-fetch-native@1.6.4: resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} - node-fetch@2.6.7: - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -8834,12 +8791,6 @@ packages: parse5@7.1.2: resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} - parseqs@0.0.6: - resolution: {integrity: sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==} - - parseuri@0.0.6: - resolution: {integrity: sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==} - parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} @@ -9987,14 +9938,6 @@ packages: snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} - socket.io-client@4.4.1: - resolution: {integrity: sha512-N5C/L5fLNha5Ojd7Yeb/puKcPWWcoB/A09fEjjNsg91EDVr5twk/OEyO6VT9dlLSUNY85NpW6KBhVMvaLKQ3vQ==} - engines: {node: '>=10.0.0'} - - socket.io-parser@4.1.2: - resolution: {integrity: sha512-j3kk71QLJuyQ/hh5F/L2t1goqzdTL0gvDzuhTuNSwihfuFUrcSji0qFZmJJPtG6Rmug153eOPsUizeirf1IIog==} - engines: {node: '>=10.0.0'} - source-map-js@1.2.0: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} @@ -11189,18 +11132,6 @@ packages: utf-8-validate: optional: true - ws@7.5.6: - resolution: {integrity: sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==} - engines: {node: '>=8.3.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - ws@7.5.9: resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} engines: {node: '>=8.3.0'} @@ -11225,18 +11156,6 @@ packages: utf-8-validate: optional: true - ws@8.2.3: - resolution: {integrity: sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - xcode@3.0.1: resolution: {integrity: sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==} engines: {node: '>=10.0.0'} @@ -11264,10 +11183,6 @@ packages: xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - xmlhttprequest-ssl@2.0.0: - resolution: {integrity: sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==} - engines: {node: '>=0.4.0'} - xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -11324,9 +11239,6 @@ packages: yauzl@2.10.0: resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - yeast@0.1.2: - resolution: {integrity: sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==} - yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -15438,8 +15350,6 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 - '@socket.io/component-emitter@3.0.0': {} - '@stacks/auth@6.15.0': dependencies: '@stacks/common': 6.13.0 @@ -15451,21 +15361,6 @@ snapshots: transitivePeerDependencies: - encoding - '@stacks/blockchain-api-client@6.3.4': - dependencies: - '@stacks/stacks-blockchain-api-types': 6.3.4 - '@types/ws': 7.4.7 - cross-fetch: 3.1.5 - eventemitter3: 4.0.7 - jsonrpc-lite: 2.2.0 - socket.io-client: 4.4.1 - ws: 7.5.6 - transitivePeerDependencies: - - bufferutil - - encoding - - supports-color - - utf-8-validate - '@stacks/common@6.13.0': dependencies: '@types/bn.js': 5.1.5 @@ -17094,10 +16989,6 @@ snapshots: '@types/uuid@9.0.8': {} - '@types/ws@7.4.7': - dependencies: - '@types/node': 20.14.0 - '@types/yargs-parser@21.0.3': {} '@types/yargs@15.0.19': @@ -17902,8 +17793,6 @@ snapshots: babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.6) - backo2@1.0.2: {} - balanced-match@1.0.2: {} base-x@3.0.9: @@ -18563,12 +18452,6 @@ snapshots: - supports-color - ts-node - cross-fetch@3.1.5: - dependencies: - node-fetch: 2.6.7 - transitivePeerDependencies: - - encoding - cross-fetch@3.1.8: dependencies: node-fetch: 2.7.0 @@ -19119,24 +19002,6 @@ snapshots: fast-json-parse: 1.0.3 objectorarray: 1.0.5 - engine.io-client@6.1.1: - dependencies: - '@socket.io/component-emitter': 3.0.0 - debug: 4.3.5 - engine.io-parser: 5.0.7 - has-cors: 1.1.0 - parseqs: 0.0.6 - parseuri: 0.0.6 - ws: 8.2.3 - xmlhttprequest-ssl: 2.0.0 - yeast: 0.1.2 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - engine.io-parser@5.0.7: {} - enhanced-resolve@5.16.0: dependencies: graceful-fs: 4.2.11 @@ -19613,8 +19478,6 @@ snapshots: event-target-shim@5.0.1: {} - eventemitter3@4.0.7: {} - eventemitter3@5.0.1: {} events@3.3.0: {} @@ -20540,8 +20403,6 @@ snapshots: has-bigints@1.0.2: {} - has-cors@1.1.0: {} - has-flag@3.0.0: {} has-flag@4.0.0: {} @@ -21569,8 +21430,6 @@ snapshots: jsonparse@1.3.1: {} - jsonrpc-lite@2.2.0: {} - jsontokens@4.0.1: dependencies: '@noble/hashes': 1.4.0 @@ -22430,10 +22289,6 @@ snapshots: node-fetch-native@1.6.4: {} - node-fetch@2.6.7: - dependencies: - whatwg-url: 5.0.0 - node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 @@ -22739,10 +22594,6 @@ snapshots: dependencies: entities: 4.5.0 - parseqs@0.0.6: {} - - parseuri@0.0.6: {} - parseurl@1.3.3: {} pascal-case@3.1.2: @@ -24112,26 +23963,6 @@ snapshots: dot-case: 3.0.4 tslib: 2.6.2 - socket.io-client@4.4.1: - dependencies: - '@socket.io/component-emitter': 3.0.0 - backo2: 1.0.2 - debug: 4.3.5 - engine.io-client: 6.1.1 - parseuri: 0.0.6 - socket.io-parser: 4.1.2 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - socket.io-parser@4.1.2: - dependencies: - '@socket.io/component-emitter': 3.0.0 - debug: 4.3.5 - transitivePeerDependencies: - - supports-color - source-map-js@1.2.0: {} source-map-support@0.5.13: @@ -25349,14 +25180,10 @@ snapshots: dependencies: async-limiter: 1.0.1 - ws@7.5.6: {} - ws@7.5.9: {} ws@8.17.0: {} - ws@8.2.3: {} - xcode@3.0.1: dependencies: simple-plist: 1.3.1 @@ -25377,8 +25204,6 @@ snapshots: xmlchars@2.2.0: {} - xmlhttprequest-ssl@2.0.0: {} - xtend@4.0.2: {} y18n@4.0.3: {} @@ -25440,8 +25265,6 @@ snapshots: buffer-crc32: 0.2.13 fd-slicer: 1.1.0 - yeast@0.1.2: {} - yocto-queue@0.1.0: {} yocto-queue@1.0.0: {}