using System; using System.Globalization; using System.Net.Http; using System.Threading.Tasks; using BTCPayServer.Abstractions.Constants; using BTCPayServer.Plugins.LiquidPlus.Models; using BTCPayServer.Plugins.LiquidPlus.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using NBitcoin; using Newtonsoft.Json.Linq; namespace BTCPayServer.Plugins.LiquidPlus.Controllers { [Route("plugins/liquid/admin-settings")] [Authorize(Policy = BTCPayServer.Client.Policies.CanModifyServerSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public class CustomLiquidAssetsController : Controller { private readonly CustomLiquidAssetsRepository _liquidAssetsRepository; private readonly IHttpClientFactory _httpClientFactory; public CustomLiquidAssetsController(CustomLiquidAssetsRepository liquidAssetsRepository, IHttpClientFactory httpClientFactory) { _liquidAssetsRepository = liquidAssetsRepository; _httpClientFactory = httpClientFactory; } [HttpGet("")] public IActionResult Assets() { return View(new CustomLiquidAssetsViewModel() { Items = (_liquidAssetsRepository.Get()).Items, PendingChanges = _liquidAssetsRepository.ChangesPending }); } [HttpPost("")] public async Task Assets(CustomLiquidAssetsViewModel model, string command = null, string import = null) { if (command == "add") { ModelState.Clear(); model.Items.Add(new CustomLiquidAssetsSettings.LiquidAssetConfiguration()); return View(model); } if (command?.StartsWith("remove", StringComparison.InvariantCultureIgnoreCase) is true) { ModelState.Clear(); var index = int.Parse( command.Substring(command.IndexOf(":", StringComparison.InvariantCultureIgnoreCase) + 1), CultureInfo.InvariantCulture); model.Items.RemoveAt(index); return View(model); } if (import != null) { try { if (!uint256.TryParse(import, out var _)) { TempData["ErrorMessage"] = "Asset Id to import was invalid."; return View(model); } var data = JObject.Parse(await _httpClientFactory.CreateClient() .GetStringAsync($"https://blockstream.info/liquid/api/asset/{import}")); model.Items.Add(new CustomLiquidAssetsSettings.LiquidAssetConfiguration() { DisplayName = data["name"].Value(), Divisibility = data["precision"].Value(), AssetId = data["asset_id"].Value(), CryptoCode = data["ticker"].Value().Replace("-", "").Replace("_", "") }); } catch (Exception) { TempData["ErrorMessage"] = "Asset Id to import was invalid."; return View(model); } } for (int i = 0; i < model.Items.Count; i++) { if (!string.IsNullOrEmpty(model.Items[i].AssetId) && !uint256.TryParse(model.Items[i].AssetId, out var x)) { var inputName = string.Format(CultureInfo.InvariantCulture, "Items[{0}].", i.ToString(CultureInfo.InvariantCulture)) + nameof(CustomLiquidAssetsSettings.LiquidAssetConfiguration.AssetId); ModelState.AddModelError(inputName, "Invalid asset id format"); } } if (!ModelState.IsValid) { return View(model); } await _liquidAssetsRepository.Set(model); return RedirectToAction(nameof(Assets)); } } }