Skip to content

Commit 957b895

Browse files
authored
Improve NFT Metadata & Filters (#99)
1 parent 1fef151 commit 957b895

File tree

3 files changed

+84
-29
lines changed

3 files changed

+84
-29
lines changed

Thirdweb.Tests/Thirdweb.Extensions/Thirdweb.Extensions.Tests.cs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,18 @@ public async Task GetNFT_721()
890890
Assert.NotEmpty(nft.Owner);
891891
Assert.Equal(NFTType.ERC721, nft.Type);
892892
Assert.True(nft.Supply == 1);
893-
Assert.Null(nft.QuantityOwned);
893+
Assert.True(nft.QuantityOwned == 1);
894+
}
895+
896+
[Fact(Timeout = 120000)]
897+
public async Task GetNFT_721_NoOwner()
898+
{
899+
var contract = await this.GetTokenERC721Contract();
900+
var nft = await contract.ERC721_GetNFT(0, false);
901+
Assert.Equal(Constants.ADDRESS_ZERO, nft.Owner);
902+
Assert.Equal(NFTType.ERC721, nft.Type);
903+
Assert.True(nft.Supply == 1);
904+
Assert.True(nft.QuantityOwned == 1);
894905
}
895906

896907
[Fact(Timeout = 120000)]
@@ -902,6 +913,16 @@ public async Task GetAllNFTs_721()
902913
Assert.NotEmpty(nfts);
903914
}
904915

916+
[Fact(Timeout = 120000)]
917+
public async Task GetAllNFTs_721_NoOwner()
918+
{
919+
var contract = await this.GetTokenERC721Contract();
920+
var nfts = await contract.ERC721_GetAllNFTs(fillOwner: false);
921+
Assert.NotNull(nfts);
922+
Assert.NotEmpty(nfts);
923+
Assert.True(nfts.All(nft => nft.Owner == Constants.ADDRESS_ZERO));
924+
}
925+
905926
[Fact(Timeout = 120000)]
906927
public async Task GetAllNFTs_721_ExceedTotalSupply()
907928
{
@@ -984,6 +1005,15 @@ public async Task GetNFT_1155()
9841005
Assert.True(nft.Supply >= 0);
9851006
}
9861007

1008+
[Fact(Timeout = 120000)]
1009+
public async Task GetNFT_1155_NoSupply()
1010+
{
1011+
var contract = await this.GetTokenERC1155Contract();
1012+
var nft = await contract.ERC1155_GetNFT(0, false);
1013+
Assert.Equal(NFTType.ERC1155, nft.Type);
1014+
Assert.True(nft.Supply == -1);
1015+
}
1016+
9871017
[Fact(Timeout = 120000)]
9881018
public async Task GetAllNFTs_1155()
9891019
{
@@ -993,6 +1023,16 @@ public async Task GetAllNFTs_1155()
9931023
Assert.NotEmpty(nfts);
9941024
}
9951025

1026+
[Fact(Timeout = 120000)]
1027+
public async Task GetAllNFTs_1155_NoSupply()
1028+
{
1029+
var contract = await this.GetTokenERC1155Contract();
1030+
var nfts = await contract.ERC1155_GetAllNFTs(fillSupply: false);
1031+
Assert.NotNull(nfts);
1032+
Assert.NotEmpty(nfts);
1033+
Assert.True(nfts.All(nft => nft.Supply == -1));
1034+
}
1035+
9961036
[Fact(Timeout = 120000)]
9971037
public async Task GetAllNFTs_1155_ExceedTotalSupply()
9981038
{

Thirdweb/Thirdweb.Extensions/ThirdwebExtensions.Types.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ public struct NFT
157157
public NFTMetadata Metadata { get; set; }
158158

159159
/// <summary>
160-
/// Gets or sets the owner address of the NFT.
160+
/// Gets or sets the owner address of the NFT. This is only applicable for ERC721 tokens.
161161
/// </summary>
162162
public string Owner { get; set; }
163163

@@ -172,7 +172,7 @@ public struct NFT
172172
public BigInteger? Supply { get; set; }
173173

174174
/// <summary>
175-
/// Gets or sets the quantity owned by the user.
175+
/// Gets or sets the quantity owned by the user. This is only applicable for ERC1155 tokens.
176176
/// </summary>
177177
public BigInteger? QuantityOwned { get; set; }
178178
}

Thirdweb/Thirdweb.Extensions/ThirdwebExtensions.cs

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,9 +1177,10 @@ public static async Task<BigInteger> ERC1155_TotalSupply(this ThirdwebContract c
11771177
/// </summary>
11781178
/// <param name="contract">The contract to interact with.</param>
11791179
/// <param name="tokenId">The ID of the token.</param>
1180+
/// <param name="fillOwner">A boolean indicating whether to fill the owner details. Defaults to true.</param>
11801181
/// <returns>A task representing the asynchronous operation, with an NFT result containing the token details.</returns>
11811182
/// <exception cref="ArgumentNullException">Thrown when the contract is null.</exception>
1182-
public static async Task<NFT> ERC721_GetNFT(this ThirdwebContract contract, BigInteger tokenId)
1183+
public static async Task<NFT> ERC721_GetNFT(this ThirdwebContract contract, BigInteger tokenId, bool fillOwner = true)
11831184
{
11841185
if (contract == null)
11851186
{
@@ -1198,14 +1199,17 @@ public static async Task<NFT> ERC721_GetNFT(this ThirdwebContract contract, BigI
11981199
}
11991200
metadata.Id = tokenId.ToString();
12001201

1201-
string owner;
1202-
try
1203-
{
1204-
owner = await contract.ERC721_OwnerOf(tokenId).ConfigureAwait(false);
1205-
}
1206-
catch (Exception)
1202+
var owner = Constants.ADDRESS_ZERO;
1203+
if (fillOwner)
12071204
{
1208-
owner = Constants.ADDRESS_ZERO;
1205+
try
1206+
{
1207+
owner = await contract.ERC721_OwnerOf(tokenId).ConfigureAwait(false);
1208+
}
1209+
catch (Exception)
1210+
{
1211+
owner = Constants.ADDRESS_ZERO;
1212+
}
12091213
}
12101214

12111215
return new NFT
@@ -1214,6 +1218,7 @@ public static async Task<NFT> ERC721_GetNFT(this ThirdwebContract contract, BigI
12141218
Owner = owner,
12151219
Type = NFTType.ERC721,
12161220
Supply = 1,
1221+
QuantityOwned = 1
12171222
};
12181223
}
12191224

@@ -1223,9 +1228,10 @@ public static async Task<NFT> ERC721_GetNFT(this ThirdwebContract contract, BigI
12231228
/// <param name="contract">The contract to interact with.</param>
12241229
/// <param name="startTokenId">The starting token ID (inclusive). Defaults to 0 if not specified.</param>
12251230
/// <param name="count">The number of tokens to retrieve. Defaults to 100 if not specified.</param>
1231+
/// <param name="fillOwner">A boolean indicating whether to fill the owner details. Defaults to true.</param>
12261232
/// <returns>A task representing the asynchronous operation, with a list of NFT results containing the token details.</returns>
12271233
/// <exception cref="ArgumentNullException">Thrown when the contract is null.</exception>
1228-
public static async Task<List<NFT>> ERC721_GetAllNFTs(this ThirdwebContract contract, int startTokenId = 0, int count = 100)
1234+
public static async Task<List<NFT>> ERC721_GetAllNFTs(this ThirdwebContract contract, int startTokenId = 0, int count = 100, bool fillOwner = true)
12291235
{
12301236
if (contract == null)
12311237
{
@@ -1238,7 +1244,7 @@ public static async Task<List<NFT>> ERC721_GetAllNFTs(this ThirdwebContract cont
12381244
var nftTasks = new List<Task<NFT>>();
12391245
for (var i = startTokenId; i < startTokenId + count; i++)
12401246
{
1241-
nftTasks.Add(contract.ERC721_GetNFT(i));
1247+
nftTasks.Add(contract.ERC721_GetNFT(i, fillOwner));
12421248
}
12431249

12441250
var allNfts = await Task.WhenAll(nftTasks).ConfigureAwait(false);
@@ -1322,9 +1328,10 @@ public static async Task<List<NFT>> ERC721_GetOwnedNFTs(this ThirdwebContract co
13221328
/// </summary>
13231329
/// <param name="contract">The contract to interact with.</param>
13241330
/// <param name="tokenId">The ID of the token.</param>
1331+
/// <param name="fillSupply">A boolean indicating whether to fill the supply. Defaults to true if not specified.</param>
13251332
/// <returns>A task representing the asynchronous operation, with an NFT result containing the token details.</returns>
13261333
/// <exception cref="ArgumentNullException">Thrown when the contract is null.</exception>
1327-
public static async Task<NFT> ERC1155_GetNFT(this ThirdwebContract contract, BigInteger tokenId)
1334+
public static async Task<NFT> ERC1155_GetNFT(this ThirdwebContract contract, BigInteger tokenId, bool fillSupply = true)
13281335
{
13291336
if (contract == null)
13301337
{
@@ -1342,21 +1349,24 @@ public static async Task<NFT> ERC1155_GetNFT(this ThirdwebContract contract, Big
13421349
metadata = new NFTMetadata { Description = e.Message };
13431350
}
13441351
metadata.Id = tokenId.ToString();
1345-
var owner = string.Empty;
1346-
BigInteger supply;
1347-
try
1348-
{
1349-
supply = await contract.ERC1155_TotalSupply(tokenId).ConfigureAwait(false);
1350-
}
1351-
catch (Exception)
1352+
1353+
var supply = BigInteger.MinusOne;
1354+
if (fillSupply)
13521355
{
1353-
supply = BigInteger.MinusOne;
1356+
try
1357+
{
1358+
supply = await contract.ERC1155_TotalSupply(tokenId).ConfigureAwait(false);
1359+
}
1360+
catch (Exception)
1361+
{
1362+
supply = BigInteger.MinusOne;
1363+
}
13541364
}
13551365

13561366
return new NFT
13571367
{
13581368
Metadata = metadata,
1359-
Owner = owner,
1369+
Owner = "",
13601370
Type = NFTType.ERC1155,
13611371
Supply = supply,
13621372
};
@@ -1368,31 +1378,32 @@ public static async Task<NFT> ERC1155_GetNFT(this ThirdwebContract contract, Big
13681378
/// <param name="contract">The contract to interact with.</param>
13691379
/// <param name="startTokenId">The starting token ID (inclusive). Defaults to 0 if not specified.</param>
13701380
/// <param name="count">The number of tokens to retrieve. Defaults to the 100 if not specified.</param>
1381+
/// <param name="fillSupply">A boolean indicating whether to fill the supply. Defaults to true if not specified.</param>
13711382
/// <returns>A task representing the asynchronous operation, with a list of NFT results containing the token details.</returns>
13721383
/// <exception cref="ArgumentNullException">Thrown when the contract is null.</exception>
1373-
public static async Task<List<NFT>> ERC1155_GetAllNFTs(this ThirdwebContract contract, int startTokenId = 0, int count = 100)
1384+
public static async Task<List<NFT>> ERC1155_GetAllNFTs(this ThirdwebContract contract, int startTokenId = 0, int count = 100, bool fillSupply = true)
13741385
{
13751386
if (contract == null)
13761387
{
13771388
throw new ArgumentNullException(nameof(contract));
13781389
}
13791390

1380-
BigInteger totalSupply;
1391+
BigInteger totalCount;
13811392
try
13821393
{
13831394
// Not part of IERC1155 so we fallback just in case
1384-
totalSupply = await contract.ERC1155_TotalSupply().ConfigureAwait(false);
1395+
totalCount = await contract.ERC1155_TotalSupply().ConfigureAwait(false);
13851396
}
13861397
catch
13871398
{
1388-
totalSupply = int.MaxValue;
1399+
totalCount = int.MaxValue;
13891400
}
1390-
count = Math.Min(count, (int)(totalSupply - startTokenId));
1401+
count = Math.Min(count, (int)(totalCount - startTokenId));
13911402

13921403
var nftTasks = new List<Task<NFT>>();
13931404
for (var i = startTokenId; i < startTokenId + count; i++)
13941405
{
1395-
nftTasks.Add(contract.ERC1155_GetNFT(i));
1406+
nftTasks.Add(contract.ERC1155_GetNFT(i, fillSupply));
13961407
}
13971408

13981409
var allNfts = await Task.WhenAll(nftTasks).ConfigureAwait(false);
@@ -1454,6 +1465,10 @@ public static async Task<List<NFT>> ERC1155_GetOwnedNFTs(this ThirdwebContract c
14541465
}
14551466

14561467
var ownerNfts = await Task.WhenAll(ownerNftTasks).ConfigureAwait(false);
1468+
for (var i = 0; i < ownerNfts.Length; i++)
1469+
{
1470+
ownerNfts[i].QuantityOwned = balanceOfBatch[i];
1471+
}
14571472
return ownerNfts.ToList();
14581473
}
14591474

0 commit comments

Comments
 (0)