/// <inheritdoc />
        public void WatchNFTContract(string contractAddress)
        {
            int watchFromHeight = this.network.IsTest() ? 3000000 : 3400000;

            if (!this.NFTContractCollection.Exists(x => x.ContractAddress == contractAddress))
            {
                NFTContractModel model = new NFTContractModel()
                {
                    ContractAddress   = contractAddress,
                    LastUpdatedBlock  = watchFromHeight,
                    OwnedIDsByAddress = new Dictionary <string, List <long> >()
                };

                this.NFTContractCollection.Upsert(model);
            }
        }
        private async Task IndexNFTsContinuouslyAsync()
        {
            await Task.Delay(1);

            try
            {
                while (!this.cancellation.Token.IsCancellationRequested)
                {
                    List <string> contracts = this.NFTContractCollection.FindAll().Select(x => x.ContractAddress).ToList();

                    foreach (string contractAddr in contracts)
                    {
                        if (this.cancellation.Token.IsCancellationRequested)
                        {
                            break;
                        }

                        NFTContractModel currentContract = this.NFTContractCollection.FindOne(x => x.ContractAddress == contractAddr);

                        ChainedHeader chainTip = this.chainIndexer.Tip;

                        List <ReceiptResponse> receipts = this.smartContractTransactionService.ReceiptSearch(
                            contractAddr, "TransferLog", null, currentContract.LastUpdatedBlock + 1, null);

                        if ((receipts == null) || (receipts.Count == 0))
                        {
                            currentContract.LastUpdatedBlock = chainTip.Height;
                            this.NFTContractCollection.Upsert(currentContract);
                            continue;
                        }

                        int lastReceiptHeight = 0;
                        if (receipts.Any())
                        {
                            lastReceiptHeight = (int)receipts.Last().BlockNumber.Value;
                        }

                        currentContract.LastUpdatedBlock = new List <int>()
                        {
                            chainTip.Height, lastReceiptHeight
                        }.Max();

                        List <TransferLog> transferLogs = new List <TransferLog>(receipts.Count);

                        foreach (ReceiptResponse receiptRes in receipts)
                        {
                            LogData log     = receiptRes.Logs.First().Log;
                            string  jsonLog = JsonConvert.SerializeObject(log);

                            TransferLogRoot infoObj = JsonConvert.DeserializeObject <TransferLogRoot>(jsonLog);
                            transferLogs.Add(infoObj.Data);
                        }

                        foreach (TransferLog transferInfo in transferLogs)
                        {
                            if ((transferInfo.From != null) && currentContract.OwnedIDsByAddress.ContainsKey(transferInfo.From))
                            {
                                currentContract.OwnedIDsByAddress[transferInfo.From].Remove(transferInfo.TokenId);

                                if (currentContract.OwnedIDsByAddress[transferInfo.From].Count == 0)
                                {
                                    currentContract.OwnedIDsByAddress.Remove(transferInfo.From);
                                }
                            }

                            if (!currentContract.OwnedIDsByAddress.ContainsKey(transferInfo.To))
                            {
                                currentContract.OwnedIDsByAddress.Add(transferInfo.To, new List <long>());
                            }

                            currentContract.OwnedIDsByAddress[transferInfo.To].Add(transferInfo.TokenId);
                        }

                        this.NFTContractCollection.Upsert(currentContract);
                    }

                    try
                    {
                        await Task.Delay(TimeSpan.FromSeconds(3), this.cancellation.Token);
                    }
                    catch (TaskCanceledException)
                    {
                    }
                }
            }
            catch (Exception e)
            {
                this.logger.LogError(e.ToString());
            }
        }
        public NFTContractModel GetAllNFTOwnersByContractAddress(string contractAddress)
        {
            NFTContractModel currentContract = this.NFTContractCollection.FindOne(x => x.ContractAddress == contractAddress);

            return(currentContract);
        }