Label Factory (#1516)

* Label Factory

* fix typo and format
This commit is contained in:
Andrew Camilleri 2020-04-28 09:53:34 +02:00 committed by GitHub
parent b31fb1a269
commit 3a2970a495
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 155 additions and 108 deletions

View File

@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
namespace BTCPayServer.Data
{
@ -14,100 +17,9 @@ namespace BTCPayServer.Data
public byte[] Blob { get; set; }
}
public class Label
{
public Label(string value, string color)
{
if (value == null)
throw new ArgumentNullException(nameof(value));
if (color == null)
throw new ArgumentNullException(nameof(color));
if (value.StartsWith("{"))
{
var jObj = JObject.Parse(value);
if (jObj.ContainsKey("value"))
{
switch (jObj["value"].Value<string>())
{
case "invoice":
Value = "invoice";
Tooltip = $"Received through an invoice ({jObj["id"].Value<string>()})";
Link = jObj.ContainsKey("id") ? $"/invoices/{jObj["id"].Value<string>()}" : "";
break;
case "pj-exposed":
Value = "payjoin-exposed";
Tooltip = $"This utxo was exposed through a payjoin proposal for an invoice ({jObj["id"].Value<string>()})";
Link = jObj.ContainsKey("id") ? $"/invoices/{jObj["id"].Value<string>()}" : "";
break;
default:
Value = value;
break;
}
}
}
else
{
Value = value;
}
RawValue = value;
Color = color;
}
public string Value { get; }
public string RawValue { get; }
public string Color { get; }
public string Link { get; }
public string Tooltip { get; }
public override bool Equals(object obj)
{
Label item = obj as Label;
if (item == null)
return false;
return Value.Equals(item.Value, StringComparison.OrdinalIgnoreCase);
}
public static bool operator ==(Label a, Label b)
{
if (System.Object.ReferenceEquals(a, b))
return true;
if (((object)a == null) || ((object)b == null))
return false;
return a.Value == b.Value;
}
public static bool operator !=(Label a, Label b)
{
return !(a == b);
}
public override int GetHashCode()
{
return Value.GetHashCode(StringComparison.OrdinalIgnoreCase);
}
}
public class WalletBlobInfo
{
public Dictionary<string, string> LabelColors { get; set; } = new Dictionary<string, string>();
public IEnumerable<Label> GetLabels(WalletTransactionInfo transactionInfo)
{
foreach (var label in transactionInfo.Labels)
{
if (LabelColors.TryGetValue(label, out var color))
{
yield return new Label(label, color);
}
}
}
public IEnumerable<Label> GetLabels()
{
foreach (var kv in LabelColors)
{
yield return new Label(kv.Key, kv.Value);
}
}
}
}

View File

@ -16,6 +16,7 @@ using BTCPayServer.Models.WalletViewModels;
using BTCPayServer.Payments;
using BTCPayServer.Security;
using BTCPayServer.Services;
using BTCPayServer.Services.Labels;
using BTCPayServer.Services.Rates;
using BTCPayServer.Services.Stores;
using BTCPayServer.Services.Wallets;
@ -52,6 +53,7 @@ namespace BTCPayServer.Controllers
private readonly SettingsRepository _settingsRepository;
private readonly DelayedTransactionBroadcaster _broadcaster;
private readonly PayjoinClient _payjoinClient;
private readonly LabelFactory _labelFactory;
public RateFetcher RateFetcher { get; }
CurrencyNameTable _currencyTable;
@ -71,7 +73,8 @@ namespace BTCPayServer.Controllers
EventAggregator eventAggregator,
SettingsRepository settingsRepository,
DelayedTransactionBroadcaster broadcaster,
PayjoinClient payjoinClient)
PayjoinClient payjoinClient,
LabelFactory labelFactory)
{
_currencyTable = currencyTable;
Repository = repo;
@ -90,6 +93,7 @@ namespace BTCPayServer.Controllers
_settingsRepository = settingsRepository;
_broadcaster = broadcaster;
_payjoinClient = payjoinClient;
_labelFactory = labelFactory;
}
// Borrowed from https://github.com/ManageIQ/guides/blob/master/labels.md
@ -144,7 +148,7 @@ namespace BTCPayServer.Controllers
if (addlabel != null)
{
addlabel = addlabel.Trim().TrimStart('{').ToLowerInvariant().Replace(',',' ').Truncate(MaxLabelSize);
var labels = walletBlobInfo.GetLabels();
var labels = _labelFactory.GetLabels(walletBlobInfo, Request);
if (!walletTransactionsInfo.TryGetValue(transactionId, out var walletTransactionInfo))
{
walletTransactionInfo = new WalletTransactionInfo();
@ -286,7 +290,7 @@ namespace BTCPayServer.Controllers
if (walletTransactionsInfo.TryGetValue(tx.TransactionId.ToString(), out var transactionInfo))
{
var labels = walletBlob.GetLabels(transactionInfo);
var labels = _labelFactory.GetLabels(walletBlob, transactionInfo, Request);
vm.Labels.AddRange(labels);
model.Labels.AddRange(labels);
vm.Comment = transactionInfo.Comment;
@ -491,7 +495,7 @@ namespace BTCPayServer.Controllers
Outpoint = coin.OutPoint.ToString(),
Amount = coin.Value.GetValue(network),
Comment = info?.Comment,
Labels = info == null? null :walletBlobAsync.GetLabels(info),
Labels = info == null? null : _labelFactory.GetLabels(walletBlobAsync, info, Request),
Link = string.Format(CultureInfo.InvariantCulture, network.BlockExplorerLink, coin.OutPoint.Hash.ToString())
};
}).ToArray();

View File

@ -30,5 +30,14 @@ namespace Microsoft.AspNetCore.Mvc
values: new { id = paymentRequestId},
scheme, host, pathbase);
}
public static string InvoiceLink(this LinkGenerator urlHelper, string invoiceId, string scheme, HostString host, string pathbase)
{
return urlHelper.GetUriByAction(
action: nameof(InvoiceController.Invoice),
controller: "Invoice",
values: new { invoiceId = invoiceId},
scheme, host, pathbase);
}
}
}

View File

@ -45,6 +45,7 @@ using Microsoft.AspNetCore.Authorization;
using BTCPayServer.Security.Bitpay;
using Serilog;
using BTCPayServer.Security.GreenField;
using BTCPayServer.Services.Labels;
namespace BTCPayServer.Hosting
{
@ -66,6 +67,7 @@ namespace BTCPayServer.Hosting
services.AddPayJoinServices();
services.AddMoneroLike();
services.TryAddSingleton<SettingsRepository>();
services.TryAddSingleton<LabelFactory>();
services.TryAddSingleton<TorServices>();
services.TryAddSingleton<SocketFactory>();
services.TryAddSingleton<LightningClientFactoryService>();

View File

@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BTCPayServer.Data;
using BTCPayServer.Services;
using BTCPayServer.Services.Labels;
namespace BTCPayServer.Models.WalletViewModels
{

View File

@ -1,10 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using BTCPayServer.Data;
using NBXplorer.Models;
using BTCPayServer.Services.Labels;
namespace BTCPayServer.Models.WalletViewModels
{

View File

@ -0,0 +1,44 @@
using System;
namespace BTCPayServer.Services.Labels
{
public class Label
{
internal Label()
{
}
public string Value { get; internal set; }
public string RawValue { get; internal set; }
public string Color { get; internal set; }
public string Link { get; internal set; }
public string Tooltip { get; internal set; }
public override bool Equals(object obj)
{
Label item = obj as Label;
if (item == null)
return false;
return Value.Equals(item.Value, StringComparison.OrdinalIgnoreCase);
}
public static bool operator ==(Label a, Label b)
{
if (System.Object.ReferenceEquals(a, b))
return true;
if (((object)a == null) || ((object)b == null))
return false;
return a.Value == b.Value;
}
public static bool operator !=(Label a, Label b)
{
return !(a == b);
}
public override int GetHashCode()
{
return Value.GetHashCode(StringComparison.OrdinalIgnoreCase);
}
}
}

View File

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using BTCPayServer.Data;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Services.Labels
{
public class LabelFactory
{
private readonly LinkGenerator _linkGenerator;
public LabelFactory(LinkGenerator linkGenerator)
{
_linkGenerator = linkGenerator;
}
public IEnumerable<Label> GetLabels(WalletBlobInfo walletBlobInfo, WalletTransactionInfo transactionInfo,
HttpRequest request)
{
foreach (var label in transactionInfo.Labels)
{
if (walletBlobInfo.LabelColors.TryGetValue(label, out var color))
{
yield return CreateLabel(label, color, request);
}
}
}
public IEnumerable<Label> GetLabels(WalletBlobInfo walletBlobInfo, HttpRequest request)
{
foreach (var kv in walletBlobInfo.LabelColors)
{
yield return CreateLabel(kv.Key, kv.Value, request);
}
}
private Label CreateLabel(string value, string color, HttpRequest request)
{
if (value == null)
throw new ArgumentNullException(nameof(value));
if (color == null)
throw new ArgumentNullException(nameof(color));
if (value.StartsWith("{"))
{
var jObj = JObject.Parse(value);
if (jObj.ContainsKey("value"))
{
var id = jObj.ContainsKey("id") ? jObj["id"].Value<string>() : string.Empty;
switch (jObj["value"].Value<string>())
{
case "invoice":
return new Label()
{
RawValue = value,
Value = "invoice",
Color = color,
Tooltip = $"Received through an invoice ({id})",
Link = string.IsNullOrEmpty(id)
? null
: _linkGenerator.InvoiceLink(id, request.Scheme, request.Host, request.PathBase)
};
case "pj-exposed":
return new Label()
{
RawValue = value,
Value = "payjoin-exposed",
Color = color,
Tooltip = $"This utxo was exposed through a payjoin proposal for an invoice ({id})",
Link = string.IsNullOrEmpty(id)
? null
: _linkGenerator.InvoiceLink(id, request.Scheme, request.Host, request.PathBase)
};
}
}
}
return new Label() {RawValue = value, Value = value, Color = color};
}
}
}