feat: fetch inscription by output in separate query

This commit is contained in:
alter-eggo
2023-08-03 17:57:32 +04:00
committed by Anastasios
parent a01071fa1f
commit 281e1386a0
10 changed files with 72 additions and 63 deletions

View File

@@ -18,8 +18,11 @@ import { openInNewTab } from '@app/common/utils/open-in-new-tab';
import { usePressable } from '@app/components/item-hover';
import { IncreaseFeeButton } from '@app/components/stacks-transaction-item/increase-fee-button';
import { TransactionTitle } from '@app/components/transaction/transaction-title';
import { createInscriptionInfoUrl } from '@app/query/bitcoin/ordinals/inscription.hooks';
import { useInscriptionByOutput } from '@app/query/bitcoin/ordinals/use-inscription-by-output';
import {
convertInscriptionToSupportedInscriptionType,
createInscriptionInfoUrl,
} from '@app/query/bitcoin/ordinals/inscription.hooks';
import { useGetInscriptionsByOutputQuery } from '@app/query/bitcoin/ordinals/use-inscription-by-output.query';
import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { CaptionDotSeparator } from '../caption-dot-separator';
@@ -40,7 +43,13 @@ export function BitcoinTransactionItem({ transaction, ...rest }: BitcoinTransact
const navigate = useNavigate();
const { whenWallet } = useWalletType();
const { data: inscriptionData } = useInscriptionByOutput(transaction);
const { data: inscriptionData } = useGetInscriptionsByOutputQuery(transaction, {
select(data) {
const inscription = data.results[0];
if (!inscription) return;
return convertInscriptionToSupportedInscriptionType(inscription);
},
});
const bitcoinAddress = useCurrentAccountNativeSegwitAddressIndexZero();
const { handleOpenTxLink } = useExplorerLink();

View File

@@ -4,6 +4,8 @@ import {
whenInscriptionType,
} from '@shared/models/inscription.model';
import { HIRO_INSCRIPTIONS_API_URL } from '@app/query/query-config';
import { useGetInscriptionQuery } from './inscription.query';
export function createInscriptionInfoUrl(id: string) {
@@ -15,13 +17,13 @@ export function convertInscriptionToSupportedInscriptionType(inscription: Inscri
return whenInscriptionType<SupportedInscription>(inscription.content_type, {
image: () => ({
infoUrl: createInscriptionInfoUrl(inscription.id),
src: `https://api.hiro.so/ordinals/v1/inscriptions/${inscription.id}/content`,
src: `${HIRO_INSCRIPTIONS_API_URL}/${inscription.id}/content`,
type: 'image',
title,
...inscription,
}),
text: () => ({
contentSrc: `https://api.hiro.so/ordinals/v1/inscriptions/${inscription.id}/content`,
contentSrc: `${HIRO_INSCRIPTIONS_API_URL}/${inscription.id}/content`,
infoUrl: createInscriptionInfoUrl(inscription.id),
type: 'text',
title,

View File

@@ -2,7 +2,7 @@ import { useQueries, useQuery } from '@tanstack/react-query';
import { Inscription } from '@shared/models/inscription.model';
import { AppUseQueryConfig } from '@app/query/query-config';
import { AppUseQueryConfig, HIRO_INSCRIPTIONS_API_URL } from '@app/query/query-config';
import { QueryPrefixes } from '@app/query/query-prefixes';
const inscriptionQueryOptions = {
@@ -15,7 +15,7 @@ const inscriptionQueryOptions = {
*/
export function fetchInscription() {
return async (id: string) => {
const res = await fetch(`https://api.hiro.so/ordinals/v1/inscriptions/${id}`);
const res = await fetch(`${HIRO_INSCRIPTIONS_API_URL}/${id}`);
if (!res.ok) throw new Error('Error retrieving inscription metadata');
const data = await res.json();
return data as Inscription;

View File

@@ -2,6 +2,8 @@ import axios from 'axios';
import { InscriptionResponseItem } from '@shared/models/inscription.model';
import { HIRO_INSCRIPTIONS_API_URL } from '@app/query/query-config';
export async function fetchInscripionById(id: string) {
return axios.get<InscriptionResponseItem>(`https://api.hiro.so/ordinals/v1/inscriptions/${id}`);
return axios.get<InscriptionResponseItem>(`${HIRO_INSCRIPTIONS_API_URL}}/${id}`);
}

View File

@@ -0,0 +1,32 @@
import { useQuery } from '@tanstack/react-query';
import { BitcoinTx } from '@shared/models/transactions/bitcoin-transaction.model';
import { AppUseQueryConfig } from '@app/query/query-config';
import { FetchInscriptionResp, fetchInscriptionByParam } from './use-inscription-by-param';
const weekInMs = 1000 * 60 * 60 * 24 * 7;
const inscriptionsByOutputQueryOptions = {
staleTime: weekInMs,
cacheTime: weekInMs,
} as const;
export function useGetInscriptionsByOutputQuery<T extends unknown = FetchInscriptionResp>(
transaction: BitcoinTx,
options?: AppUseQueryConfig<FetchInscriptionResp, T>
) {
const inputsLength = transaction.vin.length;
const index = inputsLength === 1 ? 0 : inputsLength - 2;
const isPending = !transaction.status.confirmed;
const id = isPending ? transaction.vin[index].txid : transaction.txid;
const param = `output=${id}:${index}`;
return useQuery({
enabled: !!param,
queryKey: ['inscription-by-param', isPending, param],
queryFn: () => fetchInscriptionByParam()(param),
...inscriptionsByOutputQueryOptions,
...options,
});
}

View File

@@ -1,19 +0,0 @@
import { BitcoinTx } from '@shared/models/transactions/bitcoin-transaction.model';
import { convertInscriptionToSupportedInscriptionType } from './inscription.hooks';
import { useGetInscriptionByParamQuery } from './use-inscription-by-param.query';
export function useInscriptionByOutput(transaction: BitcoinTx) {
const inputsLength = transaction.vin.length;
const index = inputsLength === 1 ? 0 : inputsLength - 2;
const isPending = !transaction.status.confirmed;
const id = isPending ? transaction.vin[index].txid : transaction.txid;
return useGetInscriptionByParamQuery(`output=${id}:${index}`, {
select(data) {
const inscription = data.results[0];
if (!inscription) return;
return convertInscriptionToSupportedInscriptionType(inscription);
},
});
}

View File

@@ -1,35 +0,0 @@
import { useQuery } from '@tanstack/react-query';
import { Paginated } from '@shared/models/api-types';
import { Inscription } from '@shared/models/inscription.model';
import { AppUseQueryConfig } from '@app/query/query-config';
const inscriptionQueryOptions = {
staleTime: Infinity,
cacheTime: Infinity,
} as const;
function fetchInscriptionByParam() {
return async (param: string) => {
const res = await fetch(`https://api.hiro.so/ordinals/v1/inscriptions?${param}`);
if (!res.ok) throw new Error('Error retrieving inscription metadata');
const data = await res.json();
return data as Paginated<Inscription[]>;
};
}
type FetchInscriptionResp = Awaited<ReturnType<ReturnType<typeof fetchInscriptionByParam>>>;
export function useGetInscriptionByParamQuery<T extends unknown = FetchInscriptionResp>(
param: string,
options?: AppUseQueryConfig<FetchInscriptionResp, T>
) {
return useQuery({
enabled: !!param,
queryKey: ['inscription-by-param', param],
queryFn: () => fetchInscriptionByParam()(param),
...inscriptionQueryOptions,
...options,
});
}

View File

@@ -0,0 +1,15 @@
import { Paginated } from '@shared/models/api-types';
import { Inscription } from '@shared/models/inscription.model';
import { HIRO_INSCRIPTIONS_API_URL } from '@app/query/query-config';
export function fetchInscriptionByParam() {
return async (param: string) => {
const res = await fetch(`${HIRO_INSCRIPTIONS_API_URL}?${param}`);
if (!res.ok) throw new Error('Error retrieving inscription metadata');
const data = await res.json();
return data as Paginated<Inscription[]>;
};
}
export type FetchInscriptionResp = Awaited<ReturnType<ReturnType<typeof fetchInscriptionByParam>>>;

View File

@@ -6,6 +6,7 @@ import { InscriptionResponseItem } from '@shared/models/inscription.model';
import { ensureArray } from '@shared/utils';
import { createNumArrayOfRange } from '@app/common/utils';
import { HIRO_INSCRIPTIONS_API_URL } from '@app/query/query-config';
import { QueryPrefixes } from '@app/query/query-prefixes';
import { useCurrentAccountNativeSegwitIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useCurrentTaprootAccount } from '@app/store/accounts/blockchain/bitcoin/taproot-account.hooks';
@@ -41,7 +42,7 @@ async function fetchInscriptions(addresses: string | string[], offset = 0, limit
params.append('limit', limit.toString());
params.append('offset', offset.toString());
const res = await fetch('https://api.hiro.so/ordinals/v1/inscriptions?' + params.toString());
const res = await fetch(`${HIRO_INSCRIPTIONS_API_URL}?${params.toString()}`);
if (!res.ok) throw new Error('Error retrieving inscription metadata');
const data = await res.json();
return data as InscriptionsQueryResponse;

View File

@@ -9,3 +9,5 @@ export type AppUseQueryConfig<QueryFnData, Response> = Pick<
UseQueryOptions<QueryFnData, unknown, Response>,
AllowedReactQueryConfigOptions
>;
export const HIRO_INSCRIPTIONS_API_URL = 'https://api.hiro.so/ordinals/v1/inscriptions';