Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion Thirdweb.Tests/Thirdweb.Extensions/Thirdweb.Extensions.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,18 @@ public async Task GetNFT_721()
Assert.NotEmpty(nft.Owner);
Assert.Equal(NFTType.ERC721, nft.Type);
Assert.True(nft.Supply == 1);
Assert.Null(nft.QuantityOwned);
Assert.True(nft.QuantityOwned == 1);
}

[Fact(Timeout = 120000)]
public async Task GetNFT_721_NoOwner()
{
var contract = await this.GetTokenERC721Contract();
var nft = await contract.ERC721_GetNFT(0, false);
Assert.Equal(Constants.ADDRESS_ZERO, nft.Owner);
Assert.Equal(NFTType.ERC721, nft.Type);
Assert.True(nft.Supply == 1);
Assert.True(nft.QuantityOwned == 1);
}

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

[Fact(Timeout = 120000)]
public async Task GetAllNFTs_721_NoOwner()
{
var contract = await this.GetTokenERC721Contract();
var nfts = await contract.ERC721_GetAllNFTs(fillOwner: false);
Assert.NotNull(nfts);
Assert.NotEmpty(nfts);
Assert.True(nfts.All(nft => nft.Owner == Constants.ADDRESS_ZERO));
}

[Fact(Timeout = 120000)]
public async Task GetAllNFTs_721_ExceedTotalSupply()
{
Expand Down Expand Up @@ -984,6 +1005,15 @@ public async Task GetNFT_1155()
Assert.True(nft.Supply >= 0);
}

[Fact(Timeout = 120000)]
public async Task GetNFT_1155_NoSupply()
{
var contract = await this.GetTokenERC1155Contract();
var nft = await contract.ERC1155_GetNFT(0, false);
Assert.Equal(NFTType.ERC1155, nft.Type);
Assert.True(nft.Supply == -1);
}

[Fact(Timeout = 120000)]
public async Task GetAllNFTs_1155()
{
Expand All @@ -993,6 +1023,16 @@ public async Task GetAllNFTs_1155()
Assert.NotEmpty(nfts);
}

[Fact(Timeout = 120000)]
public async Task GetAllNFTs_1155_NoSupply()
{
var contract = await this.GetTokenERC1155Contract();
var nfts = await contract.ERC1155_GetAllNFTs(fillSupply: false);
Assert.NotNull(nfts);
Assert.NotEmpty(nfts);
Assert.True(nfts.All(nft => nft.Supply == -1));
}

[Fact(Timeout = 120000)]
public async Task GetAllNFTs_1155_ExceedTotalSupply()
{
Expand Down
4 changes: 2 additions & 2 deletions Thirdweb/Thirdweb.Extensions/ThirdwebExtensions.Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public struct NFT
public NFTMetadata Metadata { get; set; }

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

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

/// <summary>
/// Gets or sets the quantity owned by the user.
/// Gets or sets the quantity owned by the user. This is only applicable for ERC1155 tokens.
/// </summary>
public BigInteger? QuantityOwned { get; set; }
}
Expand Down
67 changes: 41 additions & 26 deletions Thirdweb/Thirdweb.Extensions/ThirdwebExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1177,9 +1177,10 @@ public static async Task<BigInteger> ERC1155_TotalSupply(this ThirdwebContract c
/// </summary>
/// <param name="contract">The contract to interact with.</param>
/// <param name="tokenId">The ID of the token.</param>
/// <param name="fillOwner">A boolean indicating whether to fill the owner details. Defaults to true.</param>
/// <returns>A task representing the asynchronous operation, with an NFT result containing the token details.</returns>
/// <exception cref="ArgumentNullException">Thrown when the contract is null.</exception>
public static async Task<NFT> ERC721_GetNFT(this ThirdwebContract contract, BigInteger tokenId)
public static async Task<NFT> ERC721_GetNFT(this ThirdwebContract contract, BigInteger tokenId, bool fillOwner = true)
{
if (contract == null)
{
Expand All @@ -1198,14 +1199,17 @@ public static async Task<NFT> ERC721_GetNFT(this ThirdwebContract contract, BigI
}
metadata.Id = tokenId.ToString();

string owner;
try
{
owner = await contract.ERC721_OwnerOf(tokenId).ConfigureAwait(false);
}
catch (Exception)
var owner = Constants.ADDRESS_ZERO;
if (fillOwner)
{
owner = Constants.ADDRESS_ZERO;
try
{
owner = await contract.ERC721_OwnerOf(tokenId).ConfigureAwait(false);
}
catch (Exception)
{
owner = Constants.ADDRESS_ZERO;
}
}

return new NFT
Expand All @@ -1214,6 +1218,7 @@ public static async Task<NFT> ERC721_GetNFT(this ThirdwebContract contract, BigI
Owner = owner,
Type = NFTType.ERC721,
Supply = 1,
QuantityOwned = 1
};
}

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

var allNfts = await Task.WhenAll(nftTasks).ConfigureAwait(false);
Expand Down Expand Up @@ -1322,9 +1328,10 @@ public static async Task<List<NFT>> ERC721_GetOwnedNFTs(this ThirdwebContract co
/// </summary>
/// <param name="contract">The contract to interact with.</param>
/// <param name="tokenId">The ID of the token.</param>
/// <param name="fillSupply">A boolean indicating whether to fill the supply. Defaults to true if not specified.</param>
/// <returns>A task representing the asynchronous operation, with an NFT result containing the token details.</returns>
/// <exception cref="ArgumentNullException">Thrown when the contract is null.</exception>
public static async Task<NFT> ERC1155_GetNFT(this ThirdwebContract contract, BigInteger tokenId)
public static async Task<NFT> ERC1155_GetNFT(this ThirdwebContract contract, BigInteger tokenId, bool fillSupply = true)
{
if (contract == null)
{
Expand All @@ -1342,21 +1349,24 @@ public static async Task<NFT> ERC1155_GetNFT(this ThirdwebContract contract, Big
metadata = new NFTMetadata { Description = e.Message };
}
metadata.Id = tokenId.ToString();
var owner = string.Empty;
BigInteger supply;
try
{
supply = await contract.ERC1155_TotalSupply(tokenId).ConfigureAwait(false);
}
catch (Exception)

var supply = BigInteger.MinusOne;
if (fillSupply)
{
supply = BigInteger.MinusOne;
try
{
supply = await contract.ERC1155_TotalSupply(tokenId).ConfigureAwait(false);
}
catch (Exception)
{
supply = BigInteger.MinusOne;
}
}

return new NFT
{
Metadata = metadata,
Owner = owner,
Owner = "",
Type = NFTType.ERC1155,
Supply = supply,
};
Expand All @@ -1368,31 +1378,32 @@ public static async Task<NFT> ERC1155_GetNFT(this ThirdwebContract contract, Big
/// <param name="contract">The contract to interact with.</param>
/// <param name="startTokenId">The starting token ID (inclusive). Defaults to 0 if not specified.</param>
/// <param name="count">The number of tokens to retrieve. Defaults to the 100 if not specified.</param>
/// <param name="fillSupply">A boolean indicating whether to fill the supply. Defaults to true if not specified.</param>
/// <returns>A task representing the asynchronous operation, with a list of NFT results containing the token details.</returns>
/// <exception cref="ArgumentNullException">Thrown when the contract is null.</exception>
public static async Task<List<NFT>> ERC1155_GetAllNFTs(this ThirdwebContract contract, int startTokenId = 0, int count = 100)
public static async Task<List<NFT>> ERC1155_GetAllNFTs(this ThirdwebContract contract, int startTokenId = 0, int count = 100, bool fillSupply = true)
{
if (contract == null)
{
throw new ArgumentNullException(nameof(contract));
}

BigInteger totalSupply;
BigInteger totalCount;
try
{
// Not part of IERC1155 so we fallback just in case
totalSupply = await contract.ERC1155_TotalSupply().ConfigureAwait(false);
totalCount = await contract.ERC1155_TotalSupply().ConfigureAwait(false);
}
catch
{
totalSupply = int.MaxValue;
totalCount = int.MaxValue;
}
count = Math.Min(count, (int)(totalSupply - startTokenId));
count = Math.Min(count, (int)(totalCount - startTokenId));

var nftTasks = new List<Task<NFT>>();
for (var i = startTokenId; i < startTokenId + count; i++)
{
nftTasks.Add(contract.ERC1155_GetNFT(i));
nftTasks.Add(contract.ERC1155_GetNFT(i, fillSupply));
}

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

var ownerNfts = await Task.WhenAll(ownerNftTasks).ConfigureAwait(false);
for (var i = 0; i < ownerNfts.Length; i++)
{
ownerNfts[i].QuantityOwned = balanceOfBatch[i];
}
return ownerNfts.ToList();
}

Expand Down
Loading