diff --git a/Thirdweb.Tests/Thirdweb.Extensions/Thirdweb.Extensions.Tests.cs b/Thirdweb.Tests/Thirdweb.Extensions/Thirdweb.Extensions.Tests.cs index 681202b2..a5c7d8e9 100644 --- a/Thirdweb.Tests/Thirdweb.Extensions/Thirdweb.Extensions.Tests.cs +++ b/Thirdweb.Tests/Thirdweb.Extensions/Thirdweb.Extensions.Tests.cs @@ -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)] @@ -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() { @@ -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() { @@ -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() { diff --git a/Thirdweb/Thirdweb.Extensions/ThirdwebExtensions.Types.cs b/Thirdweb/Thirdweb.Extensions/ThirdwebExtensions.Types.cs index 20737f82..6dcc782d 100644 --- a/Thirdweb/Thirdweb.Extensions/ThirdwebExtensions.Types.cs +++ b/Thirdweb/Thirdweb.Extensions/ThirdwebExtensions.Types.cs @@ -157,7 +157,7 @@ public struct NFT public NFTMetadata Metadata { get; set; } /// - /// 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. /// public string Owner { get; set; } @@ -172,7 +172,7 @@ public struct NFT public BigInteger? Supply { get; set; } /// - /// 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. /// public BigInteger? QuantityOwned { get; set; } } diff --git a/Thirdweb/Thirdweb.Extensions/ThirdwebExtensions.cs b/Thirdweb/Thirdweb.Extensions/ThirdwebExtensions.cs index 26cb9083..311b1347 100644 --- a/Thirdweb/Thirdweb.Extensions/ThirdwebExtensions.cs +++ b/Thirdweb/Thirdweb.Extensions/ThirdwebExtensions.cs @@ -1177,9 +1177,10 @@ public static async Task ERC1155_TotalSupply(this ThirdwebContract c /// /// The contract to interact with. /// The ID of the token. + /// A boolean indicating whether to fill the owner details. Defaults to true. /// A task representing the asynchronous operation, with an NFT result containing the token details. /// Thrown when the contract is null. - public static async Task ERC721_GetNFT(this ThirdwebContract contract, BigInteger tokenId) + public static async Task ERC721_GetNFT(this ThirdwebContract contract, BigInteger tokenId, bool fillOwner = true) { if (contract == null) { @@ -1198,14 +1199,17 @@ public static async Task 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 @@ -1214,6 +1218,7 @@ public static async Task ERC721_GetNFT(this ThirdwebContract contract, BigI Owner = owner, Type = NFTType.ERC721, Supply = 1, + QuantityOwned = 1 }; } @@ -1223,9 +1228,10 @@ public static async Task ERC721_GetNFT(this ThirdwebContract contract, BigI /// The contract to interact with. /// The starting token ID (inclusive). Defaults to 0 if not specified. /// The number of tokens to retrieve. Defaults to 100 if not specified. + /// A boolean indicating whether to fill the owner details. Defaults to true. /// A task representing the asynchronous operation, with a list of NFT results containing the token details. /// Thrown when the contract is null. - public static async Task> ERC721_GetAllNFTs(this ThirdwebContract contract, int startTokenId = 0, int count = 100) + public static async Task> ERC721_GetAllNFTs(this ThirdwebContract contract, int startTokenId = 0, int count = 100, bool fillOwner = true) { if (contract == null) { @@ -1238,7 +1244,7 @@ public static async Task> ERC721_GetAllNFTs(this ThirdwebContract cont var nftTasks = new List>(); 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); @@ -1322,9 +1328,10 @@ public static async Task> ERC721_GetOwnedNFTs(this ThirdwebContract co /// /// The contract to interact with. /// The ID of the token. + /// A boolean indicating whether to fill the supply. Defaults to true if not specified. /// A task representing the asynchronous operation, with an NFT result containing the token details. /// Thrown when the contract is null. - public static async Task ERC1155_GetNFT(this ThirdwebContract contract, BigInteger tokenId) + public static async Task ERC1155_GetNFT(this ThirdwebContract contract, BigInteger tokenId, bool fillSupply = true) { if (contract == null) { @@ -1342,21 +1349,24 @@ public static async Task 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, }; @@ -1368,31 +1378,32 @@ public static async Task ERC1155_GetNFT(this ThirdwebContract contract, Big /// The contract to interact with. /// The starting token ID (inclusive). Defaults to 0 if not specified. /// The number of tokens to retrieve. Defaults to the 100 if not specified. + /// A boolean indicating whether to fill the supply. Defaults to true if not specified. /// A task representing the asynchronous operation, with a list of NFT results containing the token details. /// Thrown when the contract is null. - public static async Task> ERC1155_GetAllNFTs(this ThirdwebContract contract, int startTokenId = 0, int count = 100) + public static async Task> 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>(); 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); @@ -1454,6 +1465,10 @@ public static async Task> 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(); }