< Summary

Class:DCL.Helpers.NFT.NFTUtils
Assembly:NFTHelper
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Helpers/NFTUtils/NFTUtils.cs
Covered lines:32
Uncovered lines:23
Coverable lines:55
Total lines:177
Line coverage:58.1% (32 of 55)
Covered branches:0
Total branches:0
Covered methods:4
Total methods:6
Method coverage:66.6% (4 of 6)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
FetchNFTsFromOwner()0%42600%
FetchNFTInfo()0%16.676033.33%
FetchNFTInfoSingleAsset()0%16.676033.33%
GetMarket()0%4.074083.33%
GetMarket()0%20400%
TryParseUrn(...)0%33092%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Helpers/NFTUtils/NFTUtils.cs

#LineLine coverage
 1using MainScripts.DCL.ServiceProviders.OpenSea.Interfaces;
 2using System;
 3using System.Collections;
 4
 5namespace DCL.Helpers.NFT
 6{
 7    public static class NFTUtils
 8    {
 9        /// <summary>
 10        /// Fetch NFT from owner
 11        /// </summary>
 12        /// <param name="address">owner address</param>
 13        /// <param name="onSuccess">success callback</param>
 14        /// <param name="onError">error callback</param>
 15        /// <returns>IEnumerator</returns>
 16        public static IEnumerator FetchNFTsFromOwner(string address, Action<OwnNFTInfo> onSuccess, Action<string> onErro
 17        {
 018            IOpenSea selectedMarket = null;
 019            yield return GetMarket(address, (mkt) => selectedMarket = mkt);
 20
 021            if (selectedMarket != null)
 22            {
 023                yield return selectedMarket.FetchNFTsFromOwner(address, onSuccess, onError);
 24            }
 25            else
 26            {
 027                onError?.Invoke($"Market not found for asset {address}");
 28            }
 029        }
 30
 31        /// <summary>
 32        /// Fetch NFT. Request is added to a batch of requests to reduce the amount of request to the api.
 33        /// NOTE: for ERC1155 result does not contain the array of owners and sell price for this asset
 34        /// </summary>
 35        /// <param name="chain">chain network id</param>
 36        /// <param name="assetContractAddress">asset contract address</param>
 37        /// <param name="tokenId">asset token id</param>
 38        /// <param name="onSuccess">success callback</param>
 39        /// <param name="onError">error callback</param>
 40        /// <returns>IEnumerator</returns>
 41        public static IEnumerator FetchNFTInfo(string chain, string assetContractAddress, string tokenId, Action<NFTInfo
 42        {
 243            IOpenSea selectedMarket = null;
 444            yield return GetMarket(chain, assetContractAddress, tokenId, (mkt) => selectedMarket = mkt);
 45
 046            if (selectedMarket != null)
 47            {
 048                yield return selectedMarket.FetchNFTInfo(chain, assetContractAddress, tokenId, onSuccess, onError);
 49            }
 50            else
 51            {
 052                onError?.Invoke($"Market not found for asset {assetContractAddress}/{tokenId}");
 53            }
 054        }
 55
 56        /// <summary>
 57        /// Fetch NFT. Request is fetch directly to the api instead of batched with other requests in a single query.
 58        /// Please try to use `FetchNFTInfo` if ownership info is not relevant for your use case.
 59        /// NOTE: result it does contain the array of owners for ERC1155 NFTs
 60        /// </summary>
 61        /// <param name="chain">chain network id</param>
 62        /// <param name="assetContractAddress">asset contract address</param>
 63        /// <param name="tokenId">asset token id</param>
 64        /// <param name="onSuccess">success callback</param>
 65        /// <param name="onError">error callback</param>
 66        /// <returns>IEnumerator</returns>
 67        public static IEnumerator FetchNFTInfoSingleAsset(string chain, string assetContractAddress, string tokenId, Act
 68        {
 269            IOpenSea selectedMarket = null;
 470            yield return GetMarket(chain, assetContractAddress, tokenId, (mkt) => selectedMarket = mkt);
 71
 072            if (selectedMarket != null)
 73            {
 074                yield return selectedMarket.FetchNFTInfo(chain, assetContractAddress, tokenId, onSuccess, onError);
 75            }
 76            else
 77            {
 078                onError?.Invoke($"Market not found for asset {assetContractAddress}/{tokenId}");
 79            }
 080        }
 81
 82        // NOTE: this method doesn't make sense now, but it will when support for other market is added
 83        public static IEnumerator GetMarket(string chain, string assetContractAddress, string tokenId, Action<IOpenSea> 
 84        {
 485            IServiceProviders serviceProviders = Environment.i.platform.serviceProviders;
 486            IOpenSea openSea = null;
 87
 488            if (serviceProviders != null)
 089                openSea = serviceProviders.openSea;
 90
 491            onSuccess?.Invoke(openSea);
 492            yield break;
 93        }
 94
 95        public static IEnumerator GetMarket(string assetContractAddress, Action<IOpenSea> onSuccess)
 96        {
 097            IServiceProviders serviceProviders = Environment.i.platform.serviceProviders;
 098            IOpenSea openSea = null;
 99
 0100            if (serviceProviders != null)
 0101                openSea = serviceProviders.openSea;
 102
 0103            onSuccess?.Invoke(openSea);
 0104            yield break;
 105        }
 106
 107        /// <summary>
 108        /// Parses URNs with the format "urn:decentraland:{CHAIN}:{CONTRACT_STANDARD}:{CONTRACT_ADDRESS}:{TOKEN_ID}"
 109        /// and if successful stores the contract address and token ID in their corresponding reference parameters.
 110        /// example: urn:decentraland:ethereum:erc721:0x00...000:123
 111        /// </summary>
 112        /// <param name="urn">the raw URN of the NFT asset</param>
 113        /// <param name="chain">if successful the chain network id is stored in this reference parameter</param>
 114        /// <param name="contractAddress">if successful the contract address is stored in this reference parameter</para
 115        /// <param name="tokenId">if successful the token id is stored in this reference parameter</param>
 116        /// <returns>bool</returns>
 117        // TODO: update this method when support for wearables/emotes/etc urn is added
 118        public static bool TryParseUrn(string urn, out string chain, out string contractAddress, out string tokenId)
 119        {
 120            const char SEPARATOR = ':';
 121            const string DCL_URN_ID = "urn:decentraland";
 122            const string COLLECTIONS_THIRDPARTY = "collections-thirdparty";
 123
 13124            contractAddress = string.Empty;
 13125            tokenId = string.Empty;
 13126            chain = string.Empty;
 127
 128            try
 129            {
 13130                var urnSpan = urn.AsSpan();
 131
 132                // 1: "urn:decentraland"
 13133                if (!urnSpan.Slice(0, DCL_URN_ID.Length).Equals(DCL_URN_ID, StringComparison.Ordinal))
 1134                    return false;
 10135                urnSpan = urnSpan.Slice(DCL_URN_ID.Length + 1);
 136
 137                // 2: chain/network
 10138                var chainSpan = urnSpan.Slice(0, urnSpan.IndexOf(SEPARATOR));
 10139                urnSpan = urnSpan.Slice(chainSpan.Length + 1);
 140
 141                // 3: contract standard
 10142                var contractStandardSpan = urnSpan.Slice(0, urnSpan.IndexOf(SEPARATOR));
 10143                urnSpan = urnSpan.Slice(contractStandardSpan.Length + 1);
 144
 145                // check if wearables is third-party
 10146                if (contractStandardSpan.ToString().Equals(COLLECTIONS_THIRDPARTY, StringComparison.Ordinal))
 147                {
 148                    // 4: contract address
 0149                    var contractAddressSpan = urnSpan;
 0150                    contractAddress = contractAddressSpan.ToString();
 151
 152                    // NOTE: Third Party wearables do not have token id at the moment
 153                }
 154                else
 155                {
 156                    // 4: contract address
 10157                    var contractAddressSpan = urnSpan.Slice(0, urnSpan.IndexOf(SEPARATOR));
 7158                    urnSpan = urnSpan.Slice(contractAddressSpan.Length + 1);
 159
 160                    // 5: token id
 7161                    var tokenIdSpan = urnSpan;
 7162                    contractAddress = contractAddressSpan.ToString();
 7163                    tokenId = tokenIdSpan.ToString();
 164                }
 165
 7166                chain = chainSpan.ToString();
 7167                return true;
 168            }
 5169            catch (Exception e)
 170            {
 171                // ignored
 5172            }
 173
 5174            return false;
 8175        }
 176    }
 177}