public async Task <TxDetails> LoadTxDetails(string txid, NeblioAccount account) { var tinfo = await NeblioTransactionHelpers.GetTransactionInfo(txid); string sender = await NeblioTransactionHelpers.GetTransactionSender(txid, tinfo); bool fromAnotherAccount = true; bool fromSubAccount = true; if (sender == account.Address) { sender = "Main Account"; fromAnotherAccount = false; fromSubAccount = false; } else if (account.SubAccounts.TryGetValue(sender, out var sacc)) { if (!string.IsNullOrEmpty(sacc.Name)) { sender = sacc.Name; } else { sender = sacc.BookmarkFromAccount.Name; } fromAnotherAccount = false; fromSubAccount = true; } string rec = await NeblioTransactionHelpers.GetTransactionReceiver(txid, tinfo); string receiver = string.Empty; var recbkm = account.IsInTheBookmarks(rec); if (rec == account.Address) { receiver = "Main Account"; } else if (recbkm.Item1) { receiver = recbkm.Item2.Name; } if (string.IsNullOrEmpty(receiver)) { receiver = NeblioTransactionHelpers.ShortenAddress(rec); } var time = TimeHelpers.UnixTimestampToDateTime((double)tinfo.Blocktime); return(new TxDetails() { FromAnotherAccount = fromAnotherAccount, FromSubAccount = fromSubAccount, Info = tinfo, Receiver = receiver, Sender = sender, Time = time, }); }
/// <summary> /// Load info about the Utxo /// </summary> /// <returns></returns> /// <exception cref="Exception"></exception> public async Task LoadInfo() { if (string.IsNullOrEmpty(Utxo.Txid)) { throw new Exception("Cannot load Info. Utxo txid is empty."); } TokenInfo.Clear(); TotalTokens = 0; if (Utxo.Tokens.Count > 0) { foreach (var tok in Utxo.Tokens) { var ti = await NeblioTransactionHelpers.GetTokenMetadata(tok.TokenId); if (ti != null) { TokenInfo.Add(ti); TotalTokens += (int)tok.Amount; } } } TxInfo = await NeblioTransactionHelpers.GetTransactionInfo(Utxo.Txid); }
private static async Task GetTxDetails() { Console.WriteLine("Input Tx Id Hash"); var txid = Console.ReadLine(); var txinfo = await NeblioTransactionHelpers.GetTransactionInfo(txid); // sign it with loaded account Console.WriteLine("Timestamp"); Console.WriteLine(TimeHelpers.UnixTimestampToDateTime((double)txinfo.Blocktime)); Console.WriteLine("Number of confirmations: "); Console.WriteLine(txinfo.Confirmations); Console.WriteLine("--------------"); Console.WriteLine("Vins:"); txinfo.Vin.ToList().ForEach(v => { Console.WriteLine($"Vin of value: {v.ValueSat} Nebl sat. from txid: {v.Txid} and vout index {v.Vout}"); }); Console.WriteLine("-------------"); Console.WriteLine("--------------"); Console.WriteLine("Vouts:"); txinfo.Vout.ToList().ForEach(v => { Console.WriteLine($"Vout index {v.N} of value: {v.Value} Nebl sat. to receiver scrupt pub key {v.ScriptPubKey?.Addresses?.FirstOrDefault()}"); }); Console.WriteLine("-------------"); }
public static async Task <VerifyNFTTicketDto> LoadNFTTicketToVerify(OwnershipVerificationCodeDto dto, string eventId, List <string> allowedMintingAddresses) { if (string.IsNullOrEmpty(dto.TxId)) { throw new Exception("Utxo id must be provided."); } if (string.IsNullOrEmpty(dto.Signature)) { throw new Exception("Signature id must be provided."); } if (string.IsNullOrEmpty(eventId)) { throw new Exception("Event Id must be provided."); } if (allowedMintingAddresses == null || allowedMintingAddresses.Count == 0) { throw new Exception("You must provide list of allowed minting addresses."); } var msg = CreateMessage(dto.TxId); // create verification message ASAP because of time relation var txi = await NeblioTransactionHelpers.GetTransactionInfo(dto.TxId); var Time = TimeHelpers.UnixTimestampToDateTime((double)txi.Blocktime); bool isYesterdayOrOlder = DateTime.Today - Time.Date >= TimeSpan.FromDays(1); if (isYesterdayOrOlder) { throw new Exception("This ticket was used earlier than today. Or it is not used at all."); } var metadata = await NeblioTransactionHelpers.GetTransactionMetadata(NFTHelpers.TokenId, dto.TxId); if (metadata.TryGetValue("NFT", out var isnft)) { if (isnft != "true") { throw new Exception("This is not NFT"); } } if (metadata.TryGetValue("Type", out var type)) { if (type != "NFT Ticket") { throw new Exception("This is not NFT Ticket"); } } if (metadata.TryGetValue("EventId", out var nfteventId)) { if (nfteventId != eventId) { throw new Exception("Event Id on the ticket does not match the requested."); } } if (metadata.TryGetValue("Used", out var used)) { if (used != "true") { throw new Exception("This NFT Ticket is not used."); } } else { throw new Exception("This NFT Ticket is not used."); } var tx = Transaction.Parse(txi.Hex, NeblioTransactionHelpers.Network); var outDto = new VerifyNFTTicketDto(); if (tx != null && tx.Outputs.Count > 0 && tx.Inputs.Count > 0) { var outp = tx.Outputs[0]; var inpt = tx.Inputs[0]; if (outp != null && inpt != null) { var scr = outp.ScriptPubKey; var add = scr.GetDestinationAddress(NeblioTransactionHelpers.Network); var addi = inpt.ScriptSig.GetSignerAddress(NeblioTransactionHelpers.Network); if (add != addi) { throw new Exception("This ticket was not used on this address."); } var pubkey = inpt.ScriptSig.GetAllPubKeys().FirstOrDefault(); if (pubkey == null) { throw new Exception("Cannot Load the owner Public Key."); } // verify of the signature of the NFT var verres = await ECDSAProvider.VerifyMessage(msg, dto.Signature, pubkey); //var vmsg = await ECDSAProvider.VerifyMessage(msg, dto.Signature, pubkey); if (!verres.Item1) { throw new Exception("Signature of the NFT is not valid."); } // check if the NFT is still as utxo on the address var utxos = await NeblioTransactionHelpers.GetAddressUtxosObjects(add.ToString()); if (utxos.FirstOrDefault(u => (u.Txid == dto.TxId && u.Value == 10000 && u.Tokens.Count > 0 && u.Tokens.FirstOrDefault()?.Amount == 1)) == null) { throw new Exception("This ticket is not available on the address as spendable."); } // check if in previous transaction the ticket was unused var prevmeta = await NeblioTransactionHelpers.GetTransactionMetadata(NFTHelpers.TokenId, inpt.PrevOut.Hash.ToString()); if (prevmeta.TryGetValue("NFT", out var isprevnft)) { if (isprevnft != "true") { throw new Exception("This is not NFT"); } } if (prevmeta.TryGetValue("Type", out var prevtype)) { if (prevtype != "NFT Ticket") { throw new Exception("This is not NFT Ticket"); } } if (prevmeta.TryGetValue("EventId", out var prevnfteventId)) { if (prevnfteventId != eventId) { throw new Exception("Event Id on the ticket does not match the requested."); } } if (prevmeta.TryGetValue("Used", out var prevused)) { if (prevused == "true") { throw new Exception("This NFT Ticket was already used in previous transaction."); } } // todo track origin for check minting address var res = await VerifyNFTTicketOrigin(inpt.PrevOut.Hash.ToString(), eventId, allowedMintingAddresses); if (!res.Item1) { throw new Exception($"Ticket was not minted on allowed address. The origin is from: {res.Item2.Item2}"); } outDto.IsMintedByAllowedAddress = true; outDto.MintAddress = res.Item2.Item2; var nft = new TicketNFT(""); await nft.LoadLastData(metadata); // fill with already loaded the newest NFT metadata nft.Time = Time; outDto.IsSignatureValid = true; outDto.NFT = nft; outDto.OwnerAddress = add.ToString(); outDto.IsUsedOnSameAddress = true; outDto.OwnerPubKey = pubkey; outDto.TxId = dto.TxId; } } return(outDto); }
public static async Task <(bool, (string, string))> VerifyNFTTicketOrigin(string txid, string eventId, List <string> allowedMintingAddresses) { var found = false; var intxid = txid; var mintingAddress = string.Empty; while (!found) { var info = await NeblioTransactionHelpers.GetTransactionInfo(intxid); if (info != null && info.Vin != null && info.Vin.Count > 0) { var vin = info.Vin.ToArray()?[0]; if (vin.Tokens != null && vin.Tokens.Count > 0) { var vintok = vin.Tokens.ToArray()?[0]; if (vintok != null) { var meta = await NeblioTransactionHelpers.GetTransactionMetadata(NFTHelpers.TokenId, intxid); if (meta.TryGetValue("NFT", out var isnft)) { if (isnft != "true") { throw new Exception("This is not NFT"); } } if (meta.TryGetValue("Type", out var type)) { if (type != "NFT Ticket") { throw new Exception("This is not NFT Ticket"); } } if (meta.TryGetValue("EventId", out var nfteventId)) { if (nfteventId != eventId) { throw new Exception($"Event Id on the ticket does not match the requested. Found during search for origin. Explored TxId {intxid}."); } } if (meta.TryGetValue("Used", out var used)) { if (used == "true") { throw new Exception($"This NFT Ticket is already used. Found during search for origin. Used TxId {intxid}."); } } if (vintok.Amount > 1) { mintingAddress = vin.PreviousOutput.Addresses.ToArray()?[0]; if (!string.IsNullOrEmpty(mintingAddress)) { if (allowedMintingAddresses.Contains(mintingAddress)) { return(true, (intxid, mintingAddress)); } } found = true; } else if (vintok.Amount == 1) { intxid = vin.Txid; } } } } } return(false, (intxid, mintingAddress)); }
private async Task CheckNeblioPayments() { if (VEDLDataContext.Accounts.TryGetValue(ConnectedNeblioAccountAddress, out var account)) { var utxos = new NeblioAPI.Utxos[account.Utxos.Count]; lock (_lock) { account.Utxos.CopyTo(utxos); } var completedOrdersUtxos = new List <NeblioAPI.Utxos>(); foreach (var u in utxos) { if (u != null) { var info = await NeblioTransactionHelpers.GetTransactionInfo(u.Txid); if (info != null && info.Confirmations > 1) { var msg = NeblioTransactionHelpers.ParseNeblioMessage(info); if (msg.Item1) { //var split = msg.Item2.Split('-'); var ordkey = msg.Item2; if (!string.IsNullOrEmpty(ordkey)) { if (Orders.TryGetValue(ordkey, out var ord)) { if (ord.statusclass == OrderStatus.pending && ord.currency == "NBL") { Console.WriteLine($"Order {ord.id}, {ord.order_key} received Neblio payment in value {u.Value}."); try { if (((double)u.Value / NeblioTransactionHelpers.FromSatToMainRatio) >= Convert.ToDouble(ord.total, CultureInfo.InvariantCulture)) { Console.WriteLine($"Order {ord.id}, {ord.order_key} payment has correct amount and it is moved to processing state."); if (AllowDispatchNFTOrders) { var add = await GetNeblioAddressFromOrderMetadata(ord); if (add.Item1) { Console.WriteLine($"Order {ord.id}, {ord.order_key} Neblio Address in the order is correct."); ord.statusclass = OrderStatus.processing; ord.transaction_id = $"{u.Txid}:{u.Index}"; ord.date_paid = TimeHelpers.UnixTimestampToDateTime((double)u.Blocktime); var o = await UpdateOrder(ord); } } else { ord.statusclass = OrderStatus.processing; ord.transaction_id = $"{u.Txid}:{u.Index}"; ord.date_paid = TimeHelpers.UnixTimestampToDateTime((double)u.Blocktime); var o = await UpdateOrder(ord); } } else { if (((double)u.Value / NeblioTransactionHelpers.FromSatToMainRatio) > 0.009) { Console.WriteLine($"Order {ord.id}, {ord.order_key} payment is not correct amount. It is sent back to the sender."); var done = false; var attempts = 50; while (!done) { try { var nres = await account.SendNeblioPayment(account.Address, ((double)u.Value / NeblioTransactionHelpers.FromSatToMainRatio) - 0.0002, $"Order {ord.order_key} cannot be processed. Wrong sent amount."); done = nres.Item1; if (done) { Console.WriteLine($"Order {ord.id}, {ord.order_key} incorrect received payment sent back with txid: {nres.Item2}"); ord.meta_data.Add(new ProductMetadata() { key = "Incorrect Received Payment", value = $"Neblio-{nres.Item2}" }); var o = await UpdateOrder(ord); } if (!nres.Item1) { await Task.Delay(5000); } } catch { await Task.Delay(5000); } attempts--; if (attempts < 0) { break; } } } } } catch (Exception ex) { Console.WriteLine("Cannot send update of the order." + ex.Message); } } else if (ord.statusclass == OrderStatus.completed && completedOrdersUtxos.Count <= 10 && !string.IsNullOrEmpty(ConnectedDepositNeblioAccountAddress)) { completedOrdersUtxos.Add(u); } } } } } } await Task.Delay(50);//wait at least 50ms before next request to the api. } if (completedOrdersUtxos.Count > 5 && !string.IsNullOrEmpty(ConnectedDepositNeblioAccountAddress)) { var totalAmount = 0.0; foreach (var cu in completedOrdersUtxos) { totalAmount += Convert.ToDouble(cu.Value, CultureInfo.InvariantCulture); } if (totalAmount >= 3) { Console.WriteLine($"Sending completed orders payments Utxos to deposit address."); Console.WriteLine($"Total amount is {totalAmount} - 0.0002 Neblio for the fee."); var done = false; var attempts = 50; while (!done) { try { var dres = await account.SendMultipleInputNeblioPayment(ConnectedDepositNeblioAccountAddress, totalAmount - 0.0002, completedOrdersUtxos, $"Transfer of completed orders payment."); done = dres.Item1; if (done) { completedOrdersUtxos.Clear(); Console.WriteLine($"Paymenents for completed orders transfered with txid: {dres.Item2}"); } if (!dres.Item1) { await Task.Delay(5000); } } catch { await Task.Delay(5000); } attempts--; if (attempts < 0) { break; } } } } } }
/// <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); }