/// <summary> /// Clone the NFT /// </summary> /// <param name="NFT">input NFT to clone</param> /// <param name="asType">Force the type of the output NFT</param> /// <param name="type">specify the type - you must turn on asType flag</param> /// <returns>INFT compatible object cloned from source</returns> public static async Task <INFT> CloneNFT(INFT NFT, bool asType = false, NFTTypes type = NFTTypes.Image) { if (!asType) { type = NFT.Type; } INFT nft = null; switch (type) { case NFTTypes.Image: nft = new ImageNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.Profile: nft = new ProfileNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.Post: nft = new PostNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.Music: nft = new MusicNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.Payment: nft = new PaymentNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.Receipt: nft = new ReceiptNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.Invoice: nft = new InvoiceNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.Order: nft = new OrderNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.Product: nft = new ProductNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.Message: nft = new MessageNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.Ticket: nft = new TicketNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.Event: nft = new EventNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.CoruzantArticle: nft = new CoruzantArticleNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.CoruzantProfile: nft = new CoruzantProfileNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.Device: nft = new DeviceNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.IoTDevice: nft = new IoTDeviceNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.Protocol: nft = new ProtocolNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.HWSrc: nft = new HWSrcNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.FWSrc: nft = new FWSrcNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.SWSrc: nft = new SWSrcNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.MechSrc: nft = new MechSrcNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.IoTMessage: nft = new IoTMessageNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.Xray: nft = new XrayNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); case NFTTypes.XrayImage: nft = new XrayImageNFT(NFT.Utxo); await nft.Fill(NFT); return(nft); } return(null); }
/// <summary> /// Load the NFT based on the data from the cache /// </summary> /// <param name="metadata">Metadata from cache of NFTs</param> /// <param name="utxo">Utxo of the NFT</param> /// <param name="utxoindex">Utxo Index of the NFT</param> /// <param name="txinfo">preloaded txinfo</param> /// <param name="asType">Force the output type</param> /// <param name="type">Specify the output type - you must set asType flag</param> /// <returns>INFT compatible object</returns> public static async Task <INFT> GetNFTFromCacheMetadata(IDictionary <string, string> metadata, string utxo, int utxoindex, NeblioAPI.GetTransactionInfoResponse txinfo = null, bool asType = false, NFTTypes type = NFTTypes.Image) { if (!asType) { try { type = ParseNFTType(metadata); } catch (Exception ex) { Console.WriteLine($"Cannot load Type of NFT from cache. " + ex.Message); return(null); } } if (type == NFTTypes.IoTDevice) { return(null); } if (utxoindex == 1 && metadata.TryGetValue("ReceiptFromPaymentUtxo", out var rfp)) { if (!string.IsNullOrEmpty(rfp)) { type = NFTTypes.Receipt; } } if (txinfo == null) { txinfo = await NeblioTransactionHelpers.GetTransactionInfo(utxo); if (txinfo == null) { return(null); } if (txinfo.Vout == null) { return(null); } } var tokid = string.Empty; try { var tid = txinfo.Vout.ToList()[utxoindex]?.Tokens.ToList()[0]?.TokenId; tokid = tid; if (string.IsNullOrEmpty(tokid)) { tokid = NFTHelpers.TokenId; } } catch (Exception ex) { Console.WriteLine("Cannot parse token Id from NFT. " + ex.Message); return(null); } INFT nft = null; switch (type) { case NFTTypes.Image: nft = new ImageNFT(utxo); break; case NFTTypes.Profile: nft = new ProfileNFT(utxo); break; case NFTTypes.Post: nft = new PostNFT(utxo); break; case NFTTypes.Music: nft = new MusicNFT(utxo); break; case NFTTypes.Payment: nft = new PaymentNFT(utxo); break; case NFTTypes.Receipt: nft = new ReceiptNFT(utxo); break; case NFTTypes.Invoice: nft = new InvoiceNFT(utxo); break; case NFTTypes.Order: nft = new OrderNFT(utxo); break; case NFTTypes.Product: nft = new ProductNFT(utxo); break; case NFTTypes.Message: nft = new MessageNFT(utxo); break; case NFTTypes.Ticket: nft = new TicketNFT(utxo); break; case NFTTypes.Event: nft = new EventNFT(utxo); break; case NFTTypes.CoruzantArticle: nft = new CoruzantArticleNFT(utxo); break; case NFTTypes.CoruzantProfile: nft = new CoruzantProfileNFT(utxo); break; case NFTTypes.Device: nft = new DeviceNFT(utxo); break; case NFTTypes.IoTDevice: nft = new IoTDeviceNFT(utxo); break; case NFTTypes.Protocol: nft = new ProtocolNFT(utxo); break; case NFTTypes.HWSrc: nft = new HWSrcNFT(utxo); break; case NFTTypes.FWSrc: nft = new FWSrcNFT(utxo); break; case NFTTypes.SWSrc: nft = new SWSrcNFT(utxo); break; case NFTTypes.MechSrc: nft = new MechSrcNFT(utxo); break; case NFTTypes.IoTMessage: nft = new IoTMessageNFT(utxo); break; case NFTTypes.Xray: nft = new XrayNFT(utxo); break; case NFTTypes.XrayImage: nft = new XrayImageNFT(utxo); break; } if (nft != null) { nft.Time = TimeHelpers.UnixTimestampToDateTime((double)txinfo.Blocktime); nft.Utxo = utxo; nft.UtxoIndex = utxoindex; nft.TxDetails = txinfo; nft.TokenId = tokid; nft.IsLoaded = true; await nft.LoadLastData(metadata); if (nft.Type == NFTTypes.Message) { (nft as MessageNFT).Decrypted = false; } if (nft.Type == NFTTypes.IoTMessage) { (nft as IoTMessageNFT).Decrypted = false; } if (nft.Type == NFTTypes.IoTDevice) { (nft as IoTDeviceNFT).DecryptedSetting = false; } return(nft); } else { return(null); } }
/// <summary> /// Create and load the NFT from the transaction hash /// </summary> /// <param name="tokenId">Optional. If you know please provide to speed up the loading.</param> /// <param name="utxo">NFT transaction hash</param> /// <param name="utxoindex">Index of the NFT output. This is important for NFTs from multimint.</param> /// <param name="time">already parsed time</param> /// <param name="wait">await load - obsolete</param> /// <param name="loadJustType">load just specific type of NFT</param> /// <param name="justType">specify the type of the NFT which can be load - you must turn on justType flag</param> /// <param name="skipTheType">skip some type of NFT</param> /// <param name="skipType">specify the type of NFT which should be skipped - you must turn on skipTheType flag</param> /// <param name="address">Specify address of owner</param> /// <param name="txinfo">if you have loaded txinfo provide it to speed up the loading</param> /// <returns>INFT compatible object</returns> public static async Task <INFT> GetNFT(string tokenId, string utxo, int utxoindex = 0, double time = 0, bool wait = false, bool loadJustType = false, NFTTypes justType = NFTTypes.Image, bool skipTheType = false, NFTTypes skipType = NFTTypes.Image, string address = "", NeblioAPI.GetTransactionInfoResponse txinfo = null) { NFTTypes type = NFTTypes.Image; INFT nft = null; if (txinfo == null) { txinfo = await NeblioTransactionHelpers.GetTransactionInfo(utxo); } if (txinfo == null) { return(null); } if (txinfo.Vout == null) { return(null); } var tokid = tokenId; try { var tid = txinfo.Vout.ToList()[utxoindex]?.Tokens.ToList()[0]; if (tid == null) { return(null); } if (tid.Amount > 1) { return(null); } tokid = tid.TokenId; if (string.IsNullOrEmpty(tokid)) { tokid = NFTHelpers.TokenId; } } catch { return(null); } if (VEDLDataContext.AllowCache && tokid == NFTHelpers.TokenId) { // try to load it from cache try { if (VEDLDataContext.NFTCache.TryGetValue($"{utxo}:{utxoindex}", out var cachedMetadata)) { cachedMetadata.LastAccess = DateTime.UtcNow; cachedMetadata.NumberOfReads++; Console.WriteLine($"Loading {utxo}:{utxoindex} NFT from cache."); if (cachedMetadata.NFTType == NFTTypes.Receipt) { Console.WriteLine($"NFT Receipt"); } nft = await GetNFTFromCacheMetadata(cachedMetadata.Metadata, utxo, utxoindex, txinfo, true, cachedMetadata.NFTType); if (nft != null) { Console.WriteLine($"Loading {utxo}:{utxoindex} NFT from cache done."); } if (nft != null) { return(nft); } else { Console.WriteLine($"Loading {utxo}:{utxoindex} NFT from cache was not possible!"); } } } catch (Exception ex) { Console.WriteLine("Cannot load NFT from cache. " + ex.Message); return(null); } } var meta = await NeblioTransactionHelpers.GetTransactionMetadata(tokid, utxo); if (meta == null) { return(null); } else if (meta.Count == 0 || meta.Count == 1) { return(null); } try { if (!meta.TryGetValue("NFT", out var nftt)) { return(null); } else if (nftt != "true") { return(null); } type = ParseNFTType(meta); } catch (Exception ex) { Console.WriteLine($"Cannot load Type of NFT {utxo}. " + ex.Message); if (meta.TryGetValue("SourceUtxo", out var sourceutxo)) { type = NFTTypes.Image; } else { return(null); } } if (utxoindex == 1 && meta.TryGetValue("ReceiptFromPaymentUtxo", out var rfp)) { if (!string.IsNullOrEmpty(rfp)) { type = NFTTypes.Receipt; } } if (loadJustType) { if (justType != type) { return(null); } } if (skipTheType) { if (skipType == type || (skipType == NFTTypes.Message && type == NFTTypes.IoTMessage)) { return(null); } } var Time = TimeHelpers.UnixTimestampToDateTime(time); switch (type) { case NFTTypes.Image: nft = new ImageNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; //if (wait) await nft.ParseOriginData(meta); //else //nft.ParseOriginData(meta); nft.ParsePrice(meta); break; case NFTTypes.Profile: nft = new ProfileNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; await(nft as ProfileNFT).LoadLastData(meta); return(nft); case NFTTypes.Post: nft = new PostNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; await(nft as PostNFT).LoadLastData(meta); break; case NFTTypes.Music: nft = new MusicNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; //await ponft.ParseOriginData(); if (wait) { await nft.ParseOriginData(meta); } else { nft.ParseOriginData(meta); } nft.ParsePrice(meta); break; case NFTTypes.Payment: nft = new PaymentNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; await(nft as PaymentNFT).LoadLastData(meta); break; case NFTTypes.Receipt: nft = new ReceiptNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; await(nft as ReceiptNFT).LoadLastData(meta); break; case NFTTypes.Invoice: nft = new InvoiceNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; await(nft as InvoiceNFT).LoadLastData(meta); break; case NFTTypes.Order: nft = new OrderNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; await(nft as OrderNFT).LoadLastData(meta); break; case NFTTypes.Product: nft = new ProductNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; await(nft as ProductNFT).LoadLastData(meta); break; case NFTTypes.Message: nft = new MessageNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; await(nft as MessageNFT).LoadLastData(meta); break; case NFTTypes.Ticket: nft = new TicketNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; if (wait) { await nft.ParseOriginData(meta); } else { nft.ParseOriginData(meta); } nft.ParsePrice(meta); break; case NFTTypes.Event: nft = new EventNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; if (wait) { await nft.ParseOriginData(meta); } else { nft.ParseOriginData(meta); } nft.ParsePrice(meta); break; case NFTTypes.CoruzantArticle: nft = new CoruzantArticleNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; if (wait) { await(nft as CoruzantArticleNFT).LoadLastData(meta); } else { (nft as CoruzantArticleNFT).LoadLastData(meta); } nft.ParsePrice(meta); break; case NFTTypes.CoruzantProfile: nft = new CoruzantProfileNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; if (wait) { await(nft as CoruzantProfileNFT).LoadLastData(meta); } else { (nft as CoruzantProfileNFT).LoadLastData(meta); } break; case NFTTypes.Device: nft = new DeviceNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; if (wait) { await(nft as DeviceNFT).LoadLastData(meta); } else { (nft as DeviceNFT).LoadLastData(meta); } break; case NFTTypes.IoTDevice: nft = new IoTDeviceNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; if (wait) { await(nft as IoTDeviceNFT).LoadLastData(meta); } else { (nft as IoTDeviceNFT).LoadLastData(meta); } break; case NFTTypes.Protocol: nft = new ProtocolNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; if (wait) { await(nft as ProtocolNFT).LoadLastData(meta); } else { (nft as ProtocolNFT).LoadLastData(meta); } break; case NFTTypes.HWSrc: nft = new HWSrcNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; if (wait) { await(nft as HWSrcNFT).LoadLastData(meta); } else { (nft as HWSrcNFT).LoadLastData(meta); } break; case NFTTypes.FWSrc: nft = new FWSrcNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; if (wait) { await(nft as FWSrcNFT).LoadLastData(meta); } else { (nft as FWSrcNFT).LoadLastData(meta); } break; case NFTTypes.SWSrc: nft = new SWSrcNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; if (wait) { await(nft as SWSrcNFT).LoadLastData(meta); } else { (nft as SWSrcNFT).LoadLastData(meta); } break; case NFTTypes.MechSrc: nft = new MechSrcNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; if (wait) { await(nft as MechSrcNFT).LoadLastData(meta); } else { (nft as MechSrcNFT).LoadLastData(meta); } break; case NFTTypes.IoTMessage: nft = new IoTMessageNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; await(nft as IoTMessageNFT).LoadLastData(meta); break; case NFTTypes.Xray: nft = new XrayNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; await(nft as XrayNFT).LoadLastData(meta); break; case NFTTypes.XrayImage: nft = new XrayImageNFT(utxo); nft.TokenId = tokid; nft.Time = Time; nft.TxDetails = txinfo; nft.UtxoIndex = utxoindex; await(nft as XrayImageNFT).LoadLastData(meta); break; } if (VEDLDataContext.AllowCache && tokid == NFTHelpers.TokenId && VEDLDataContext.NFTCache.Count < VEDLDataContext.MaxCachedItems) { if (nft.Type != NFTTypes.IoTDevice) { try { var mtd = await nft.GetMetadata(); if (!VEDLDataContext.NFTCache.TryGetValue($"{nft.Utxo}:{nft.UtxoIndex}", out var m)) { VEDLDataContext.NFTCache.TryAdd($"{nft.Utxo}:{nft.UtxoIndex}", new Dto.NFTCacheDto() { Address = address, NFTType = nft.Type, Metadata = mtd, Utxo = nft.Utxo, UtxoIndex = nft.UtxoIndex, NumberOfReads = 0, LastAccess = DateTime.UtcNow, FirstSave = DateTime.UtcNow }); } } catch (Exception ex) { Console.WriteLine($"Cannot load NFT {utxo} of type {nft.TypeText} to NFTCache dictionary. " + ex.Message); } } } return(nft); }