Skip to content

Commit aa541d8

Browse files
committed
Handle token by index
1 parent 1abab4c commit aa541d8

File tree

3 files changed

+41
-9
lines changed
  • apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts
  • packages/thirdweb/src/extensions/erc721/read

3 files changed

+41
-9
lines changed

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/token-id.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export const TokenIdPage: React.FC<TokenIdPageProps> = ({
8585
contract,
8686
tokenId: BigInt(tokenId || 0),
8787
includeOwner: true,
88+
ignoreTokenIndex: true,
8889
},
8990
);
9091

@@ -222,7 +223,11 @@ export const TokenIdPage: React.FC<TokenIdPageProps> = ({
222223
<GridItem colSpan={8}>
223224
<CopyTextButton
224225
textToCopy={nft.id?.toString()}
225-
textToShow={nft.id?.toString()}
226+
textToShow={
227+
nft.id?.toString().length > 8
228+
? `${nft.id.toString().slice(0, 4)}...${nft.id.toString().slice(-4)}`
229+
: nft.id?.toString()
230+
}
226231
tooltip="Token ID"
227232
copyIconPosition="right"
228233
/>

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/table.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ export const NFTGetAllTable: React.FC<ContractOverviewNFTGetAllProps> = ({
5959
const cols: Column<NFT>[] = [
6060
{
6161
Header: "Token Id",
62-
accessor: (row) => row.id?.toString(),
62+
accessor: (row) =>
63+
row.id?.toString().length > 8
64+
? `${row.id.toString().slice(0, 4)}...${row.id.toString().slice(-4)}`
65+
: row.id?.toString(),
6366
Cell: (cell: CellProps<NFT, string>) => <p>{cell.value}</p>,
6467
},
6568
{

packages/thirdweb/src/extensions/erc721/read/getNFT.ts

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { type Abi, toFunctionSelector } from "viem";
2+
import { resolveContractAbi } from "../../../contract/actions/resolve-abi.js";
13
import type { BaseTransactionOptions } from "../../../transaction/types.js";
24
import { fetchTokenMetadata } from "../../../utils/nft/fetchTokenMetadata.js";
35
import { type NFT, parseNFT } from "../../../utils/nft/parseNft.js";
@@ -6,6 +8,10 @@ import {
68
type TokenURIParams,
79
tokenURI,
810
} from "../__generated__/IERC721A/read/tokenURI.js";
11+
import {
12+
isTokenByIndexSupported,
13+
tokenByIndex,
14+
} from "../__generated__/IERC721Enumerable/read/tokenByIndex.js";
915

1016
export { isTokenURISupported as isGetNFTSupported } from "../__generated__/IERC721A/read/tokenURI.js";
1117

@@ -19,6 +25,10 @@ export type GetNFTParams = Prettify<
1925
* Whether to include the owner of the NFT.
2026
*/
2127
includeOwner?: boolean;
28+
/**
29+
* Whether to check tokenId by index.
30+
*/
31+
ignoreTokenIndex?: boolean;
2232
}
2333
>;
2434

@@ -39,24 +49,38 @@ export type GetNFTParams = Prettify<
3949
export async function getNFT(
4050
options: BaseTransactionOptions<GetNFTParams>,
4151
): Promise<NFT> {
52+
const abi = await resolveContractAbi<Abi>(options.contract);
53+
const selectors = abi
54+
.filter((f) => f.type === "function")
55+
.map((f) => toFunctionSelector(f));
56+
const hasTokenByIndex = isTokenByIndexSupported(selectors);
57+
58+
let tokenId = options.tokenId;
59+
if (!options.ignoreTokenIndex && hasTokenByIndex) {
60+
tokenId = await tokenByIndex({
61+
contract: options.contract,
62+
index: options.tokenId,
63+
});
64+
}
65+
4266
const [uri, owner] = await Promise.all([
43-
tokenURI(options).catch(() => null),
67+
tokenURI({ contract: options.contract, tokenId }).catch(() => null),
4468
options.includeOwner
4569
? import("../__generated__/IERC721A/read/ownerOf.js")
46-
.then((m) => m.ownerOf(options))
70+
.then((m) => m.ownerOf({ contract: options.contract, tokenId }))
4771
.catch(() => null)
4872
: null,
4973
]);
5074

5175
if (!uri?.trim()) {
5276
return parseNFT(
5377
{
54-
id: options.tokenId,
78+
id: tokenId,
5579
type: "ERC721",
5680
uri: "",
5781
},
5882
{
59-
tokenId: options.tokenId,
83+
tokenId,
6084
tokenUri: "",
6185
type: "ERC721",
6286
owner,
@@ -67,15 +91,15 @@ export async function getNFT(
6791
return parseNFT(
6892
await fetchTokenMetadata({
6993
client: options.contract.client,
70-
tokenId: options.tokenId,
94+
tokenId,
7195
tokenUri: uri,
7296
}).catch(() => ({
73-
id: options.tokenId,
97+
id: tokenId,
7498
type: "ERC721",
7599
uri,
76100
})),
77101
{
78-
tokenId: options.tokenId,
102+
tokenId: tokenId,
79103
tokenUri: uri,
80104
type: "ERC721",
81105
owner,

0 commit comments

Comments
 (0)