/// <summary>
        /// Refresh the messages list
        /// </summary>
        /// <param name="innfts"></param>
        /// <returns></returns>
        public async Task RefreshMessages(List <INFT> innfts)
        {
            if (!PublicKeyFound)
            {
                var bobPubKey = await NFTHelpers.GetPubKeyFromLastFoundTx(Address);

                if (bobPubKey.Item1)
                {
                    PublicKey      = bobPubKey.Item2;
                    PublicKeyFound = true;
                }
                else
                {
                    PublicKeyFound = false;
                }
            }
            var msgs = await NFTHelpers.LoadAddressNFTMessages(Address, AccountAddress, NFTs);

            lock (_lock)
            {
                NFTMessages = msgs;
            }
            // add related messages from main account
            await AddAccoundMessages(innfts);

            if (AccountSecret != null)
            {
                await DecryptMessages();
            }

            NFTMessages = NFTMessages.OrderBy(m => m.Time).Reverse().ToList();
        }
        /// <summary>
        /// Find and parse origin data
        /// </summary>
        /// <param name="lastmetadata"></param>
        /// <returns></returns>
        public override async Task ParseOriginData(IDictionary <string, string> lastmetadata)
        {
            var nftData = await NFTHelpers.LoadNFTOriginData(Utxo, true);

            if (nftData != null)
            {
                ParseCommon(nftData.NFTMetadata);

                ParsePrice(lastmetadata);
                await ParseDogeftInfo(lastmetadata);

                ParseSoldInfo(lastmetadata);
                SourceTxId    = nftData.SourceTxId;
                NFTOriginTxId = nftData.NFTOriginTxId;

                ParseSpecific(nftData.NFTMetadata);

                Used = nftData.Used;
                AddUsedTags();

                MintAuthorAddress = await NeblioTransactionHelpers.GetTransactionSender(NFTOriginTxId);

                IsLoaded = true;
            }
        }
Example #3
0
        /*
         * public static async Task<(bool,(OwnershipVerificationCodeDto,byte[]))> GetQRCode(string txid, EncryptionKey key)
         * {
         *  var signature = await GetCode(txid, key);
         *  if (signature.Item1)
         *  {
         *      var dto = new OwnershipVerificationCodeDto();
         *      dto.TxId = txid;
         *      dto.Signature = signature.Item2;
         *      var dtos = JsonConvert.SerializeObject(dto);
         *      if (dtos != null)
         *      {
         *          QRCodeData qrCodeData = qrGenerator.CreateQrCode(dtos, QRCodeGenerator.ECCLevel.Q);
         *          var qrCode = new BitmapByteQRCode(qrCodeData);
         *          var g = qrCode.GetGraphic(20);
         *          return (true, (dto, g));
         *      }
         *  }
         *  return (false, (null, null));
         * }
         */

        public static async Task <OwnershipVerificationResult> VerifyOwner(OwnershipVerificationCodeDto dto)
        {
            var msg = CreateMessage(dto.TxId);
            var res = await NFTHelpers.GetNFTWithOwner(dto.TxId);

            if (res.Item1)
            {
                //var ownerpubkey = await NFTHelpers.GetPubKeyFromProfileNFTTx(res.Item2.Owner);

                /*var ownerpubkey = await NFTHelpers.GetPubKeyFromLastFoundTx(res.Item2.Owner);
                 * if (!ownerpubkey.Item1)
                 *  return new OwnershipVerificationResult()
                 *  {
                 *      Owner = res.Item2.Owner,
                 *      Sender = res.Item2.Sender,
                 *      NFT = res.Item2.NFT,
                 *      Message = msg,
                 *      VerifyResult = "Cannot get owner pubkey. He probably did not allow this function."
                 *  };*/

                var r = await ECDSAProvider.VerifyMessage(msg, dto.Signature, res.Item2.Owner);

                if (r.Item1)
                {
                    return(new OwnershipVerificationResult()
                    {
                        Owner = res.Item2.Owner,
                        Sender = res.Item2.Sender,
                        NFT = res.Item2.NFT,
                        Message = msg,
                        VerifyResult = "Verified. This is owner. Signature is valid."
                    });
                }
                else
                {
                    if (r.Item2 != null)
                    {
                        return new OwnershipVerificationResult()
                               {
                                   Owner        = res.Item2.Owner,
                                   Sender       = res.Item2.Sender,
                                   NFT          = res.Item2.NFT,
                                   Message      = msg,
                                   VerifyResult = "Not Owner of NFT or provided signature is no longer valid."
                               }
                    }
                    ;
                }
            }
            return(new OwnershipVerificationResult()
            {
                VerifyResult = "Not Valid input."
            });
        }
        /// <summary>
        /// Add messages from the main account to the list
        /// This will combine list of received and sent messages to one list
        /// </summary>
        /// <param name="innfts"></param>
        /// <returns></returns>
        public async Task AddAccoundMessages(List <INFT> innfts)
        {
            var msgs = await NFTHelpers.LoadAddressNFTMessages(Address, AccountAddress, innfts);

            lock (_lock)
            {
                foreach (var m in msgs)
                {
                    NFTMessages.Add(m);
                }
            }
        }
        /// <summary>
        /// Reload the data
        /// </summary>
        /// <returns></returns>
        public async Task Reload()
        {
            NFTs = await NFTHelpers.LoadAddressNFTs(Address, null, NFTs.ToList());

            if (NFTs == null)
            {
                NFTs = new List <INFT>();
            }

            if (NFTs.Count > 0)
            {
                Profile = await CoruzantNFTHelpers.FindCoruzantProfileNFT(NFTs);
            }
        }
        /// <summary>
        /// Get last data for the Event NFT related to this NFT Ticket
        /// </summary>
        /// <returns></returns>
        public async Task LoadEventNFT()
        {
            if (string.IsNullOrEmpty(NFTOriginTxId))
            {
                return;
            }

            var nft = await NFTHelpers.FindEventOnTheAddress(EventAddress, EventId);

            if (nft != null)
            {
                EventNFTForTheTicket = nft as EventNFT;
            }
        }
        /// <summary>
        /// Get last data of this NFT
        /// </summary>
        /// <returns></returns>
        public async Task GetLastData()
        {
            var nftData = await NFTHelpers.LoadLastData(Utxo);
            if (nftData != null)
            {
                ParseCommon(nftData.NFTMetadata);

                ParsePrice(nftData.NFTMetadata);

                SourceTxId = nftData.SourceTxId;
                NFTOriginTxId = nftData.NFTOriginTxId;
                ParseSpecific(nftData.NFTMetadata);
            }
        }
Example #8
0
        /// <summary>
        /// Parse origin data of the NFT
        /// </summary>
        /// <param name="lastmetadata"></param>
        /// <returns></returns>
        public override async Task ParseOriginData(IDictionary <string, string> lastmetadata)
        {
            var nftData = await NFTHelpers.LoadNFTOriginData(Utxo);

            if (nftData != null)
            {
                ParseCommon(lastmetadata);

                SourceTxId    = nftData.SourceTxId;
                NFTOriginTxId = nftData.NFTOriginTxId;

                ParseSpecific(lastmetadata);
            }
        }
        public async Task GetLastData()
        {
            await GetPartner();

            var nftData = await NFTHelpers.LoadLastData(Utxo);

            if (nftData != null)
            {
                ParseCommon(nftData.NFTMetadata);

                SourceTxId    = nftData.SourceTxId;
                NFTOriginTxId = nftData.NFTOriginTxId;
                IsLoaded      = true;
            }
        }
        public override async Task ParseOriginData(IDictionary <string, string> lastmetadata)
        {
            await GetPartner();

            var nftData = await NFTHelpers.LoadNFTOriginData(Utxo);

            if (nftData != null)
            {
                ParseCommon(nftData.NFTMetadata);

                SourceTxId    = nftData.SourceTxId;
                NFTOriginTxId = nftData.NFTOriginTxId;
                IsLoaded      = true;
            }
        }
        /// <summary>
        /// Find and parse origin data
        /// </summary>
        /// <param name="lastmetadata"></param>
        /// <returns></returns>
        public override async Task ParseOriginData(IDictionary <string, string> lastmetadata)
        {
            var nftData = await NFTHelpers.LoadNFTOriginData(Utxo);

            if (nftData != null)
            {
                ParseCommon(nftData.NFTMetadata);
                ParsePrice(lastmetadata);
                await ParseDogeftInfo(lastmetadata);

                ParseSoldInfo(lastmetadata);

                SourceTxId    = nftData.SourceTxId;
                NFTOriginTxId = nftData.NFTOriginTxId;
                IsLoaded      = true;
            }
        }
 public string ActualImageLinkFromNFT(INFT nft)
 {
     if (nft.DataItems != null && nft.DataItems.Count >= 0)
     {
         foreach (var item in nft.DataItems)
         {
             if (item.IsMain)
             {
                 return(NFTHelpers.GetIPFSLinkFromHash(item.Hash));
             }
         }
         if (nft.DataItems.Count > 0)
         {
             var il = NFTHelpers.GetIPFSLinkFromHash(nft.DataItems.FirstOrDefault()?.Hash);
             return(!string.IsNullOrEmpty(il) ? il : GetImageUrl());
         }
     }
     return(GetImageUrl());
 }
        /// <summary>
        /// Reload the NFTs
        /// </summary>
        /// <param name="innfts"></param>
        /// <returns></returns>
        public async Task Reload(List <INFT> innfts)
        {
            if (string.IsNullOrEmpty(Address))
            {
                return;
            }

            NFTs = await NFTHelpers.LoadAddressNFTs(Address, null, NFTs.ToList(), justMessages : true);

            if (NFTs == null)
            {
                NFTs = new List <INFT>();
            }

            //if (NFTs.Count > 0)
            //    Profile = await NFTHelpers.FindProfileNFT(NFTs);

            await RefreshMessages(innfts);
        }
Example #14
0
        /// <summary>
        /// Obtain the Shared secret based on the Neblio Address and Neblio Private Key
        /// </summary>
        /// <param name="bobAddress">Neblio Address of the receiver</param>
        /// <param name="secret">Private Key of the sender in the form of the BitcoinSecret</param>
        /// <param name="bobPublicKey">Bob public key</param>
        /// <returns></returns>
        public static async Task <(bool, string)> GetSharedSecret(string bobAddress, BitcoinSecret secret, PubKey bobPublicKey = null)
        {
            if (secret == null || (string.IsNullOrEmpty(bobAddress) && bobPublicKey == null))
            {
                return(false, "Input parameters cannot be empty or null.");
            }

            var aliceadd = secret.PubKey.GetAddress(ScriptPubKeyType.Legacy, NeblioTransactionHelpers.Network);
            var bpkey    = secret.PubKey;

            if (aliceadd.ToString() != bobAddress.ToString())
            {
                if (bobPublicKey == null)
                {
                    var bobPubKey = await NFTHelpers.GetPubKeyFromLastFoundTx(bobAddress);

                    if (!bobPubKey.Item1)
                    {
                        return(false, "Cannot find public key, input address did not have any spent transations for key extraction.");
                    }
                    else
                    {
                        bpkey = bobPubKey.Item2;
                    }
                }
                else
                {
                    bpkey = bobPublicKey;
                }
            }

            var sharedKey = bpkey.GetSharedPubkey(secret.PrivateKey);

            if (sharedKey == null || string.IsNullOrEmpty(sharedKey.Hash.ToString()))
            {
                return(false, "Cannot create shared secret from keys.");
            }
            else
            {
                return(true, SecurityUtils.ComputeSha256Hash(sharedKey.Hash.ToString()));
            }
        }
        public async Task <string> UploadInfura(IFormFile file)
        {
            if (file == null)
            {
                return("Error. Provided null file.");
            }

            using var stream = file.OpenReadStream();
            try
            {
                var imageLink = await NFTHelpers.UploadInfura(stream, file.FileName);

                return(imageLink);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error during uploading the image to the IPFS." + ex.Message);
            }
            return(string.Empty);
        }
        /// <summary>
        /// Get last data of this NFT
        /// </summary>
        /// <returns></returns>
        public async Task GetLastData()
        {
            var nftData = await NFTHelpers.LoadLastData(Utxo);

            if (nftData != null)
            {
                ParseCommon(nftData.NFTMetadata);

                ParsePrice(nftData.NFTMetadata);

                SourceTxId    = nftData.SourceTxId;
                NFTOriginTxId = nftData.NFTOriginTxId;

                if (string.IsNullOrEmpty(Link) && !string.IsNullOrEmpty(ImageLink))
                {
                    Link = ImageLink;
                }
                IsLoaded = true;
            }
        }
        /// <summary>
        /// Get last data of this NFT
        /// </summary>
        /// <returns></returns>
        public async Task GetLastData()
        {
            var nftData = await NFTHelpers.LoadLastData(Utxo);

            if (nftData != null)
            {
                ParseCommon(nftData.NFTMetadata);

                ParsePrice(nftData.NFTMetadata);

                SourceTxId    = nftData.SourceTxId;
                NFTOriginTxId = nftData.NFTOriginTxId;

                ParseSpecific(nftData.NFTMetadata);
                MintAuthorAddress = await NeblioTransactionHelpers.GetTransactionSender(NFTOriginTxId);

                Used = nftData.Used;
                AddUsedTags();

                IsLoaded = true;
            }
        }
        /// <summary>
        /// Check if the NFT contains the ImageData in bytes.
        /// If not, it will download it from IPFS and then convert as image base64 string
        /// </summary>
        /// <returns></returns>
        public async Task <string> GetImage()
        {
            if (NFT == null)
            {
                return(EmptyImage);
            }

            if (NFT.ImageData != null && NFT.ImageData.Length > 0)
            {
                return("data:image;base64," + Convert.ToBase64String(NFT.ImageData));
            }
            else if (NFT.ImageData == null && !string.IsNullOrEmpty(NFT.ImageLink))
            {
                var imd = await NFTHelpers.IPFSDownloadFromInfuraAsync(NFTHelpers.GetHashFromIPFSLink(NFT.ImageLink));

                if (imd != null)
                {
                    NFT.ImageData = imd;
                    return("data:image;base64," + Convert.ToBase64String(imd));
                }
            }

            return(EmptyImage);
        }
        protected override async Task ExecuteAsync(CancellationToken stopToken)
        {
            await Task.Delay(1);

            var neblioAddressForShop        = string.Empty;
            var neblioDepositAddressForShop = string.Empty;
            var dogeAddressForShop          = string.Empty;
            var dogeDepositAddressForShop   = string.Empty;

            MainDataContext.IsAPIWithCredentials          = settings.GetValue <bool>("IsAPIWithCredentials", true);
            MainDataContext.LoadAllVENFTOwnersWithAllNFTs = settings.GetValue <bool>("LoadAllVENFTOwnersWithAllNFTs", false);
            var loadWithInWebAssemblyLimits = settings.GetValue <bool>("LoadWithInWebAssemblyLimits", false);

            MainDataContext.IpfsSecret    = settings.GetValue <string>("IpfsSecret", string.Empty);
            MainDataContext.IpfsProjectID = settings.GetValue <string>("IpfsProjectID", string.Empty);
            if (!string.IsNullOrEmpty(MainDataContext.IpfsSecret) && !string.IsNullOrEmpty(MainDataContext.IpfsProjectID))
            {
                NFTHelpers.LoadConnectionInfo(MainDataContext.IpfsProjectID, MainDataContext.IpfsSecret);
            }

            var acc = new List <string>();

            settings.GetSection("ObservedAccounts").Bind(acc);
            if (acc != null)
            {
                MainDataContext.ObservedAccounts = acc;
            }

            try
            {
                /*
                 * var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "keys.json");
                 * if (!FileHelpers.IsFileExists(path))
                 * {
                 *  Console.WriteLine("Missing keys.json file. Cannot continue without at least one root Neblio account.");
                 *  return;
                 * }
                 * var skeys = FileHelpers.ReadTextFromFile(path);
                 * var keys = JsonConvert.DeserializeObject<List<AccountExportDto>>(skeys);
                 */
                var keys = new List <AccountExportDto>();
                settings.GetSection("keys").Bind(keys);
                if (keys == null || keys.Count == 0)
                {
                    //log.Error("Missing keys in settigns. Cannot continue without at least one root Neblio account.");
                    Console.WriteLine("Missing keys in settigns. Cannot continue without at least one root Neblio account.");
                    return;
                }

                Console.WriteLine("------------------------------------");
                Console.WriteLine("-----------Loading Accounts---------");
                Console.WriteLine("------------------------------------");

                if (keys != null)
                {
                    foreach (var k in keys)
                    {
                        if (!string.IsNullOrEmpty(k.Address))
                        {
                            if (!k.IsDogeAccount)
                            {
                                var add = NeblioTransactionHelpers.ValidateNeblioAddress(k.Address);
                                if (!string.IsNullOrEmpty(add))
                                {
                                    Console.WriteLine("");
                                    Console.WriteLine("=========Neblio Main Account========");
                                    Console.WriteLine($"Loading Neblio address {k.Address}...");
                                    if (string.IsNullOrEmpty(k.Name))
                                    {
                                        k.Name = NeblioTransactionHelpers.ShortenAddress(k.Address);
                                    }

                                    var account             = new NeblioAccount();
                                    EncryptedBackupDto bckp = null;
                                    if (FileHelpers.IsFileExists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, k.Address + "-backup.json")))
                                    {
                                        var b = FileHelpers.ReadTextFromFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, k.Address + "-backup.json"));
                                        if (!string.IsNullOrEmpty(b))
                                        {
                                            bckp = JsonConvert.DeserializeObject <EncryptedBackupDto>(b);
                                            Console.WriteLine($"Backup data found for this account. It will be loaded based on VENFT backup.");
                                        }
                                    }

                                    (bool, string)dbackup = (false, string.Empty);
                                    (bool, string)dpass   = (false, string.Empty);
                                    if (await account.LoadAccount(k.Password, k.EKey, k.Address)) // fill your password
                                    {
                                        if (k.ConnectToMainShop && k.IsReceivingAccount)
                                        {
                                            neblioAddressForShop = k.Address;
                                        }
                                        else if (k.ConnectToMainShop && k.IsDepositAccount)
                                        {
                                            neblioDepositAddressForShop = k.Address;
                                        }

                                        if (bckp != null)
                                        {
                                            var dadd = await ECDSAProvider.DecryptMessage(bckp.eadd, account.Secret);

                                            dbackup = await ECDSAProvider.DecryptMessage(bckp.edata, account.Secret);

                                            dpass = await ECDSAProvider.DecryptMessage(bckp.epass, account.Secret);

                                            if (dpass.Item1 && dadd.Item1 && dadd.Item1)
                                            {
                                                Console.WriteLine($"Loading Neblio address {k.Address} from VENFT Backup...");
                                                if (await account.LoadAccountFromVENFTBackup(dpass.Item2, dbackup.Item2))
                                                {
                                                    Console.WriteLine($"Neblio address {k.Address} initialized.");
                                                }
                                                else
                                                {
                                                    Console.WriteLine($"Cannot load VENFT backup for address {k.Address}.");
                                                }
                                            }
                                        }

                                        // this is block autostart of the IoT Devices NFTs...add this to appsettings.json   "LoadWithInWebAssemblyLimits": true,
                                        account.RunningAsVENFTBlazorApp = loadWithInWebAssemblyLimits;

                                        VEDLDataContext.Accounts.TryAdd(k.Address, account);
                                        VEDLDataContext.AdminAddresses.Add(k.Address);

                                        if (dbackup.Item1 && dpass.Item1)
                                        {
                                            try
                                            {
                                                var bdto = JsonConvert.DeserializeObject <BackupDataDto>(dbackup.Item2);
                                                if (bdto != null && !string.IsNullOrEmpty(bdto.DogeAddress))
                                                {
                                                    Console.WriteLine($"Backup for main address {k.Address} contains also Dogecoin address {bdto.DogeAddress}. It will be imported.");
                                                    var dogeAccount = new DogeAccount();
                                                    var res         = await dogeAccount.LoadAccount(dpass.Item2, bdto.DogeKey, bdto.DogeAddress);

                                                    VEDLDataContext.DogeAccounts.TryAdd(bdto.DogeAddress, dogeAccount);
                                                    Console.WriteLine($"Dogecoin address {bdto.DogeAddress} initialized.");
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                //log.Error("Canno init doge account" + ex.Message);
                                                Console.WriteLine("Cannot init doge account" + ex.Message);
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                var dadd = DogeTransactionHelpers.ValidateDogeAddress(k.Address);
                                if (dadd.Success)
                                {
                                    Console.WriteLine("");
                                    Console.WriteLine("========Dogecoin Main Account=======");
                                    Console.WriteLine($"Loading Dogecoin address {k.Address}...");
                                    var dogeacc = new DogeAccount();
                                    if (await dogeacc.LoadAccount(k.Password, k.EKey, k.Address))
                                    {
                                        VEDLDataContext.DogeAccounts.TryAdd(dogeacc.Address, dogeacc);
                                    }
                                    Console.WriteLine($"Dogecoin address {k.Address} initialized.");
                                    if (k.ConnectToMainShop && k.IsReceivingAccount)
                                    {
                                        dogeAddressForShop = k.Address;
                                    }
                                    else if (k.ConnectToMainShop && k.IsDepositAccount)
                                    {
                                        dogeDepositAddressForShop = k.Address;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //log.Error("Canno load the keys. " + ex.Message);
                Console.WriteLine("Cannot load the keys. " + ex.Message);
            }

            await Task.Delay(5000);

            Console.WriteLine("------------------------------------");
            Console.WriteLine("Loading NFT Hashes...");
            await AccountHandler.ReloadNFTHashes();

            Console.WriteLine($"Count of NFTHashes: {VEDLDataContext.NFTHashs.Count}.");

            Console.WriteLine("");
            Console.WriteLine("------------------------------------");
            Console.WriteLine("---------WooCommerce Shop-----------");
            Console.WriteLine("------------------------------------");

            try
            {
                VEDLDataContext.WooCommerceStoreUrl      = settings.GetValue <string>("WooCommerceStoreUrl");
                VEDLDataContext.WooCommerceStoreAPIKey   = settings.GetValue <string>("WooCommerceStoreAPIKey");
                VEDLDataContext.WooCommerceStoreSecret   = settings.GetValue <string>("WooCommerceStoreSecret");
                VEDLDataContext.WooCommerceStoreJWTToken = settings.GetValue <string>("WooCommerceStoreJWT");
                VEDLDataContext.WooCommerceStoreCheckoutFieldCustomerNeblioAddress = settings.GetValue <string>("WooCommerceStoreCheckoutFieldCustomerNeblioAddress");
                VEDLDataContext.WooCommerceStoreSendDogeToAuthor = settings.GetValue <bool>("WooCommerceStoreSendDogeToAuthor", false);
                VEDLDataContext.AllowDispatchNFTOrders           = settings.GetValue <bool>("AllowDispatchNFTOrders", false);
                try
                {
                    settings.GetSection("DepositSchemes").Bind(VEDLDataContext.DepositSchemes);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Cannot load the deposit schemes. " + ex.Message);
                }

                if (VEDLDataContext.DepositSchemes.Count == 0)
                {
                    Console.WriteLine("!!!Cannot load the deposit schemes!!!");
                }

                if (!string.IsNullOrEmpty(VEDLDataContext.WooCommerceStoreUrl) &&
                    !string.IsNullOrEmpty(VEDLDataContext.WooCommerceStoreAPIKey) &&
                    !string.IsNullOrEmpty(VEDLDataContext.WooCommerceStoreSecret))
                {
                    Console.WriteLine("Initializing WooCommerce Shop...");
                    Console.WriteLine("API Url: " + VEDLDataContext.WooCommerceStoreUrl);
                    if (await WooCommerceHelpers.InitStoreApiConnection(VEDLDataContext.WooCommerceStoreUrl,
                                                                        VEDLDataContext.WooCommerceStoreAPIKey,
                                                                        VEDLDataContext.WooCommerceStoreSecret,
                                                                        VEDLDataContext.WooCommerceStoreJWTToken, true))
                    {
                        Console.WriteLine("WooCommerce Shop Initialized correctly.");
                        Console.WriteLine($"- Number of Products: {WooCommerceHelpers.Shop.Products.Count}");
                        Console.WriteLine($"- Number of Orders: {WooCommerceHelpers.Shop.Orders.Count}");
                        Console.WriteLine("------------------------------------");
                        if (!string.IsNullOrEmpty(dogeAddressForShop))
                        {
                            await WooCommerceHelpers.Shop.ConnectDogeAccount(dogeAddressForShop);

                            Console.WriteLine($"Connecting Dogecoin address {dogeAddressForShop} to the WooCommerce Shop main input account.");
                        }
                        if (!string.IsNullOrEmpty(dogeDepositAddressForShop) && dogeAddressForShop != dogeDepositAddressForShop)
                        {
                            WooCommerceHelpers.Shop.ConnectedDepositDogeAccountAddress = dogeDepositAddressForShop;
                            Console.WriteLine($"Connecting Dogecoin address {dogeDepositAddressForShop} to the WooCommerce Shop as deposit account.");
                        }
                        if (!string.IsNullOrEmpty(dogeDepositAddressForShop) && !string.IsNullOrEmpty(dogeAddressForShop) && dogeAddressForShop == dogeDepositAddressForShop)
                        {
                            Console.WriteLine($"Input doge address and deposit address cannot be same.");
                        }

                        if (string.IsNullOrEmpty(WooCommerceHelpers.Shop.ConnectedDogeAccountAddress))
                        {
                            if (!string.IsNullOrEmpty(neblioAddressForShop))
                            {
                                await WooCommerceHelpers.Shop.ConnectNeblioAccount(neblioAddressForShop);

                                Console.WriteLine($"Connecting Neblio address {neblioAddressForShop} to the WooCommerce Shop main input account.");
                            }
                            if (!string.IsNullOrEmpty(neblioDepositAddressForShop) && neblioAddressForShop != dogeDepositAddressForShop)
                            {
                                await WooCommerceHelpers.Shop.ConnectDepositNeblioAccount(neblioDepositAddressForShop);

                                Console.WriteLine($"Connecting Neblio address {neblioDepositAddressForShop} to the WooCommerce Shop as deposit account.");
                            }
                            if (!string.IsNullOrEmpty(neblioDepositAddressForShop) && !string.IsNullOrEmpty(neblioAddressForShop) && neblioAddressForShop == neblioDepositAddressForShop)
                            {
                                Console.WriteLine($"Input Neblio address and deposit address cannot be same.");
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("Cannot init the WooCommerce API.");
                        //log.Warn("Canno init WooCommerce API.");
                    }
                }
            }
            catch (Exception ex)
            {
                //log.Error("Canno init WooCommerce API. " + ex.Message);
                Console.WriteLine("Cannot init the WooCommerce API." + ex.Message);
            }

            Console.WriteLine("------------------------------------");
            Console.WriteLine("--------Starting main cycle---------");
            Console.WriteLine("------------------------------------");
            try
            {
                var VENFTOwnersRefreshDefault = 3600;
                var VENFTOwnersRefresh        = 100;
                var NFTHashsRefreshDefault    = 100;
                var NFTHashsRefresh           = 10;


                _ = Task.Run(async() =>
                {
                    Console.WriteLine("Loading Observing addresses...");
                    // load observed addresses
                    if (MainDataContext.ObservedAccounts.Count > 0)
                    {
                        for (var i = 0; i < MainDataContext.ObservedAccounts.Count; i++)
                        {
                            try
                            {
                                var tab = new VEDriversLite.Bookmarks.ActiveTab(MainDataContext.ObservedAccounts[i]);
                                tab.MaxLoadedNFTItems = 1500;
                                await tab.StartRefreshing(10000, false, true);
                                MainDataContext.ObservedAccountsTabs.TryAdd(tab.Address, tab);
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("Cannot start observing of account: " + MainDataContext.ObservedAccounts[i]);
                            }
                        }
                    }

                    Console.WriteLine("Running...");
                    while (!stopToken.IsCancellationRequested)
                    {
                        await Task.Delay(1000);

                        /*
                         * if (VENFTOwnersRefresh <= 0)
                         * {
                         *  try
                         *  {
                         *      var owns = await NeblioTransactionHelpers.GetTokenOwners(NFTHelpers.TokenId);
                         *      if (owns != null)
                         *      {
                         *          var ow = new Dictionary<string, TokenOwnerDto>();
                         *          foreach (var o in owns)
                         *              ow.Add(o.Address, o);
                         *          MainDataContext.VENFTTokenOwners = ow;
                         *          VENFTOwnersRefresh = VENFTOwnersRefreshDefault;
                         *      }
                         *  }
                         *  catch(Exception ex)
                         *  {
                         *      log.Error("Cannot refresh VENFT Owners. " + ex.Message);
                         *      Console.WriteLine("Cannot refresh VENFT Owners");
                         *  }
                         * }
                         * else
                         * {
                         *  VENFTOwnersRefresh--;
                         * }*/

                        try
                        {
                            if (NFTHashsRefresh <= 0)
                            {
                                if (await AccountHandler.ReloadNFTHashes())
                                {
                                    NFTHashsRefresh = NFTHashsRefreshDefault;
                                }
                            }
                            else
                            {
                                NFTHashsRefresh--;
                            }
                        }
                        catch (Exception ex)
                        {
                            //log.Error("Cannot reload the NFT Hashes. " + ex.Message);
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                //log.Error("Fatal error in main loop. " + ex.Message);
                lifetime.StopApplication();
            }
        }