Skip to content

Commit

Permalink
Merge pull request #418 from yieldprotocol/fix/check-nft-owner
Browse files Browse the repository at this point in the history
fix: check nft owner
  • Loading branch information
marcomariscal authored Aug 11, 2023
2 parents cdb7e22 + 1d33a90 commit a7f1b13
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 71 deletions.
17 changes: 3 additions & 14 deletions src/components/cactiComponents/HeaderResponse.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { useEffect, useState } from 'react';
import {
ArrowTopRightOnSquareIcon,
ChevronDownIcon,
ChevronUpIcon,
} from '@heroicons/react/24/outline';
import { findProjectByName, shortenAddress } from '@/utils';
import projectList from '@/utils/ProjectList.json';
import Avatar from '../Avatar';
import { ArrowTopRightOnSquareIcon } from '@heroicons/react/24/outline';
import { findProjectByName } from '@/utils';
import { ResponseWrap } from './helpers/layout';

const navigateToExternalUrl = ({ url }: { url: string | URL }) => {
Expand All @@ -25,9 +19,6 @@ export const HeaderResponse = (props: any) => {
const project = findProjectByName(props.projectName);
setProject(project);
}
// if (props.projectName==='user') {
// setProject({name: 'user', logo: '/images/user.png', url: 'https://app.cacti.finance/'})
// }
}, [props.projectName]);

const url = project?.url || props.altUrl;
Expand All @@ -36,10 +27,8 @@ export const HeaderResponse = (props: any) => {
<ResponseWrap classNameExtra="group">
<div className="flex w-full justify-between px-1">
<div className="flex items-center space-x-4">
{project?.logo || props.altImageUrl ? (
{(project?.logo || props.altImageUrl) && (
<img className="avatar" src={project.logo || props.altImageUrl} alt="projectLogo" />
) : (
<Avatar actor={'user'} />
)}
<div>{props.text}</div>
</div>
Expand Down
23 changes: 15 additions & 8 deletions src/components/experimental_/widgets/nft/BuyNft.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import axios from 'axios';
import { BigNumber, BigNumberish, ethers } from 'ethers';
// @ts-ignore TODO: fix this
import * as JSONbigint from 'json-bigint';
import { useAccount } from 'wagmi';
import { Address, useAccount } from 'wagmi';
import SeaportAbi from '@/abi/SeaportAbi.json';
import { NftOwner } from '@/components/CheckNftOwner';
import { ActionResponse, HeaderResponse } from '@/components/cactiComponents';
import { ImageVariant } from '@/components/cactiComponents/ImageResponse';
import { TxBasicParams } from '@/components/cactiComponents/hooks/useSubmitTx';
import useNft from '@/hooks/useNft';
import { Order } from '@/types';
import { ConnectFirst } from '../helpers/ConnectFirst';
import { NftAsset } from './NftAsset';
Expand Down Expand Up @@ -62,8 +62,14 @@ const fetchFulfillParams = async (
export const BuyNft = ({ nftAddress, tokenId }: { nftAddress: string; tokenId: string }) => {
// // The new owner will be the receiver
const { address: account } = useAccount();
//const addRecentTransaction = useAddRecentTransaction();
// const { refetch: refetchBal } = useBalance();
const {
data: { isOwner },
refetchOwner,
} = useNft({
address: nftAddress as Address,
tokenId: +tokenId,
network: 'ethereum-mainnet',
});

// fetchListing possible states:
// If order array is empty, show the NFT is not currently for sale
Expand Down Expand Up @@ -127,8 +133,8 @@ export const BuyNft = ({ nftAddress, tokenId }: { nftAddress: string; tokenId: s
<ConnectFirst>
<HeaderResponse text={`Buy NFT`} projectName={'Opensea Seaport'} />
<NftAsset
address={nftAddress}
tokenId={tokenId}
address={nftAddress as Address}
tokenId={+tokenId}
network="ethereum-mainnet"
variant={ImageVariant.SHOWCASE}
price={
Expand All @@ -138,8 +144,9 @@ export const BuyNft = ({ nftAddress, tokenId }: { nftAddress: string; tokenId: s
<ActionResponse
txParams={tx}
approvalParams={undefined}
label={notForSale ? 'Item not for sale' : 'Purchase NFT'}
disabled={isExpired || notForSale}
label={isOwner ? 'Already Owner' : notForSale ? 'Item not for sale' : 'Purchase NFT'}
disabled={isExpired || notForSale || isOwner}
onSuccess={async () => await refetchOwner()}
/>
</ConnectFirst>
);
Expand Down
55 changes: 11 additions & 44 deletions src/components/experimental_/widgets/nft/NftAsset.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,21 @@
import { useQuery } from 'react-query';
import { useAsset } from '@center-inc/react';
import axios from 'axios';
import { Network } from '@center-inc/react';
import { Address } from 'wagmi';
import { ImageResponse } from '@/components/cactiComponents';
import { ImageVariant } from '@/components/cactiComponents/ImageResponse';
import { InlineChip } from '@/components/cactiComponents/InlineChip';
import { ETHEREUM_NETWORK } from '@/utils/constants';
import useNft from '@/hooks/useNft';

export interface NftAssetProps {
network: string;
address: string;
tokenId: string | number;
network: Network;
address: Address;
tokenId: number;
collectionName?: string;
name?: string;
previewImageUrl?: string;

variant?: ImageVariant; // widget variant

price?: string;
}

const fetchNftAsset = async (
nftAddress: string,
tokenId: string,
network: string = ETHEREUM_NETWORK
) => {
return axios
.get(`https://api.center.dev/v1/${network}/${nftAddress}/${tokenId}`, {
// .get(`https://api.center.app/v2/${network}/${nftAddress}/nft/${tokenId}/metadata`,{
headers: {
Accept: 'application/json',
'X-API-Key': process.env.NEXT_PUBLIC_CENTER_APP_KEY || 'test',
},
})
.then((res) => {
console.log(res.data);
return res.data;
})
.catch((err) => {
console.log(err);
});
};

export const NftAsset = ({
network,
address,
Expand All @@ -51,31 +26,23 @@ export const NftAsset = ({
variant,
price,
}: NftAssetProps) => {
const {
data: nftData,
error,
isLoading,
} = useQuery(
['NftAsset', address, tokenId],
async () => fetchNftAsset(address, tokenId.toString(), network)
);
const { data: nftData } = useNft({ network, address, tokenId });

return (
<ImageResponse
description={nftData?.description}
image={nftData?.smallPreviewImageUrl || previewImageUrl}
image={nftData.smallPreviewImageUrl || previewImageUrl}
imageTags={
variant === ImageVariant.SHOWCASE
? [`Token Id: ${tokenId}`, `${network.replace('-mainnet', '')}`]
: []
}
title={nftData?.name || name}
subTitle={nftData?.collection?.name || nftData?.collectionName || collectionName}
title={nftData.name || name}
subTitle={nftData.collectionName || collectionName}
imageLink={`https://center.app/${network}/collections/${address}/${tokenId}`}
variant={variant}
>
{variant === ImageVariant.SHOWCASE && (
<div className="text-xs">{nftData?.metadata?.description}</div>
<div className="text-xs">{nftData.metadata?.description}</div>
)}
{price && (
<InlineChip
Expand Down
11 changes: 6 additions & 5 deletions src/components/experimental_/widgets/nft/NftCollection.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Network, useCollection } from '@center-inc/react';
import { Address } from 'wagmi';
import { ImageResponse } from '@/components/cactiComponents';
import { ImageVariant } from '@/components/cactiComponents/ImageResponse';
import ListContainer from '../../containers/ListContainer';
import { NftAsset} from './NftAsset';
import { Widget } from '../../MessageTranslator_';
import ListContainer from '../../containers/ListContainer';
import { NftAsset } from './NftAsset';

interface NftCollectionContainerProps {
network: Network;
Expand Down Expand Up @@ -43,10 +44,10 @@ export const NftCollection = ({
* */
const assets = assetsIdsToShow.map((asset, i) =>
typeof asset === 'number' ? (
<NftAsset network={network} address={address} tokenId={asset} key={asset} /> // if just a number, use it as tokenId
<NftAsset network={network} address={address as Address} tokenId={asset} key={asset} /> // if just a number, use it as tokenId
) : (
<Widget key={asset.params.tokenId || `${i}` } widget={asset} />
)
<Widget key={asset.params.tokenId || `${i}`} widget={asset} />
)
);

return (
Expand Down
88 changes: 88 additions & 0 deletions src/hooks/useNft.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { useQuery } from 'react-query';
import { Network } from '@center-inc/react';
import axios from 'axios';
import { BigNumber } from 'ethers';
import { Address, erc721ABI, useAccount } from 'wagmi';
import { readContract } from 'wagmi/actions';
import { ETHEREUM_NETWORK } from '@/utils/constants';

interface NftRes {
address: string;
collectionName: string;
collection_name: string;
mediumPreviewImageUrl: string;
metadata: {
attributes: {
trait_type: string;
value: string;
}[];
description: string;
image: string;
name: string;
tokenId: number;
};
name: string;
smallPreviewImageUrl: string;
small_preview_image_url: string;
tokenId: string;
token_id: string;
url: string;
owner?: Address;
isOwner?: boolean;
}

const useNft = ({
address,
tokenId,
network,
}: {
address: Address;
tokenId: number;
network: Network;
}) => {
const { address: account } = useAccount();
const fetchNft = async (
nftAddress: string,
tokenId: number,
network: string = ETHEREUM_NETWORK
) => {
const { data } = await axios.get<NftRes>(
`https://api.center.dev/v1/${network}/${nftAddress}/${tokenId}`,
{
headers: {
Accept: 'application/json',
'X-API-Key': process.env.NEXT_PUBLIC_CENTER_APP_KEY || 'test',
},
}
);
return data;
};

const { data: centerData, ...rest } = useQuery({
queryKey: ['nft', address, tokenId, network],
queryFn: async () => await fetchNft(address, tokenId, network),
refetchOnWindowFocus: false,
});

const { data: owner, refetch: refetchOwner } = useQuery({
queryKey: ['nftOwner', address, tokenId, network],
queryFn: async () =>
await readContract({
address,
abi: erc721ABI,
functionName: 'ownerOf',
args: [BigNumber.from(tokenId)],
}),
refetchOnWindowFocus: false,
});

const data = { ...centerData, owner, isOwner: owner === account };

return {
data,
...rest,
refetchOwner,
};
};

export default useNft;

0 comments on commit a7f1b13

Please sign in to comment.