mirror of
https://github.com/zhigang1992/wallet.git
synced 2026-05-13 20:06:51 +08:00
feat: stamps collectibles, closes #3589
This commit is contained in:
@@ -9,6 +9,7 @@ import { useConfigNftMetadataEnabled } from '@app/query/common/hiro-config/hiro-
|
||||
|
||||
import { AddCollectible } from './components/add-collectible';
|
||||
import { Ordinals } from './components/bitcoin/ordinals';
|
||||
import { Stamps } from './components/bitcoin/stamps';
|
||||
import { CollectiblesLayout } from './components/collectibes.layout';
|
||||
import { StacksCryptoAssets } from './components/stacks/stacks-crypto-assets';
|
||||
import { TaprootBalanceDisplayer } from './components/taproot-balance-displayer';
|
||||
@@ -40,6 +41,7 @@ export function Collectibles() {
|
||||
<>
|
||||
<AddCollectible />
|
||||
<Ordinals />
|
||||
<Stamps />
|
||||
</>
|
||||
),
|
||||
ledger: null,
|
||||
|
||||
20
src/app/features/collectibles/components/bitcoin/stamp.tsx
Normal file
20
src/app/features/collectibles/components/bitcoin/stamp.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import { openInNewTab } from '@app/common/utils/open-in-new-tab';
|
||||
import { Stamp as BitcoinStamp } from '@app/query/bitcoin/stamps/stamp-collection.query';
|
||||
|
||||
import { CollectibleImage } from '../_collectible-types/collectible-image';
|
||||
|
||||
const stampChainAssetUrl = 'https://stampchain.io/asset.html?stampNumber=';
|
||||
|
||||
export function Stamp(props: { bitcoinStamp: BitcoinStamp }) {
|
||||
const { bitcoinStamp } = props;
|
||||
|
||||
return (
|
||||
<CollectibleImage
|
||||
key={bitcoinStamp.stamp}
|
||||
onClickCallToAction={() => openInNewTab(`${stampChainAssetUrl}${bitcoinStamp.stamp}`)}
|
||||
src={bitcoinStamp.stamp_url}
|
||||
subtitle="Bitcoin Stamp"
|
||||
title={`# ${bitcoinStamp.stamp}`}
|
||||
/>
|
||||
);
|
||||
}
|
||||
33
src/app/features/collectibles/components/bitcoin/stamps.tsx
Normal file
33
src/app/features/collectibles/components/bitcoin/stamps.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
|
||||
import { useStampsByAddressQuery } from '@app/query/bitcoin/stamps/stamps-by-address.query';
|
||||
import { useCurrentBtcNativeSegwitAccountAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
|
||||
|
||||
import { Stamp } from './stamp';
|
||||
|
||||
export function Stamps() {
|
||||
const currentAccountBtcAddress = useCurrentBtcNativeSegwitAccountAddressIndexZero();
|
||||
const { data: stamps } = useStampsByAddressQuery(currentAccountBtcAddress);
|
||||
const analytics = useAnalytics();
|
||||
|
||||
useEffect(() => {
|
||||
if (!stamps) return;
|
||||
if (stamps.length > 0) {
|
||||
void analytics.track('view_collectibles', {
|
||||
stamps_count: stamps.length,
|
||||
});
|
||||
void analytics.identify({ stamps_count: stamps.length });
|
||||
}
|
||||
}, [analytics, stamps]);
|
||||
|
||||
if (!stamps) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
{stamps.map(s => (
|
||||
<Stamp bitcoinStamp={s} key={s.tx_hash} />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -3,16 +3,16 @@ import { useQuery } from '@tanstack/react-query';
|
||||
import { AppUseQueryConfig } from '@app/query/query-config';
|
||||
import { QueryPrefixes } from '@app/query/query-prefixes';
|
||||
|
||||
interface Stamp {
|
||||
message_index: number;
|
||||
block_index: number;
|
||||
timestamp: number;
|
||||
tx_hash: string;
|
||||
export interface Stamp {
|
||||
asset: string;
|
||||
tx_index: number;
|
||||
block_index: number;
|
||||
message_index: number;
|
||||
stamp: number;
|
||||
stamp_mimetype: string;
|
||||
stamp_url: string;
|
||||
stamp: number;
|
||||
timestamp: number;
|
||||
tx_hash: string;
|
||||
tx_index: number;
|
||||
}
|
||||
|
||||
async function fetchStampCollection() {
|
||||
|
||||
31
src/app/query/bitcoin/stamps/stamps-by-address.query.ts
Normal file
31
src/app/query/bitcoin/stamps/stamps-by-address.query.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import { AppUseQueryConfig } from '@app/query/query-config';
|
||||
import { QueryPrefixes } from '@app/query/query-prefixes';
|
||||
|
||||
import { Stamp } from './stamp-collection.query';
|
||||
|
||||
const stampsByAddressQueryOptions = {
|
||||
staleTime: Infinity,
|
||||
cacheTime: Infinity,
|
||||
} as const;
|
||||
|
||||
async function fetchStampsByAddress(address: string): Promise<Stamp[]> {
|
||||
return fetch(`https://stampchain.io/api/stamps?wallet_address=${address}`).then(res =>
|
||||
res.json()
|
||||
);
|
||||
}
|
||||
|
||||
type FetchStampsByAddressResp = Awaited<ReturnType<typeof fetchStampsByAddress>>;
|
||||
|
||||
export function useStampsByAddressQuery<T extends unknown = FetchStampsByAddressResp>(
|
||||
address: string,
|
||||
options?: AppUseQueryConfig<FetchStampsByAddressResp, T>
|
||||
) {
|
||||
return useQuery({
|
||||
queryKey: [QueryPrefixes.StampsByAddress],
|
||||
queryFn: () => fetchStampsByAddress(address),
|
||||
...stampsByAddressQueryOptions,
|
||||
...options,
|
||||
});
|
||||
}
|
||||
@@ -12,4 +12,5 @@ export enum QueryPrefixes {
|
||||
GetNftMetadata = 'get-nft-metadata',
|
||||
|
||||
StampCollection = 'stamp-collection',
|
||||
StampsByAddress = 'stamps-by-address',
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user