mirror of
https://github.com/zhigang1992/wallet.git
synced 2026-01-12 22:53:27 +08:00
feat: fetch inscription by output in separate query
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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}`);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
}
|
||||
@@ -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);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -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,
|
||||
});
|
||||
}
|
||||
15
src/app/query/bitcoin/ordinals/use-inscription-by-param.ts
Normal file
15
src/app/query/bitcoin/ordinals/use-inscription-by-param.ts
Normal 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>>>;
|
||||
@@ -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;
|
||||
|
||||
@@ -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';
|
||||
|
||||
Reference in New Issue
Block a user