< Summary - Combined Code Coverage

Information
Class: NLightning.Infrastructure.Bitcoin.Encoders.Bech32Encoder
Assembly: NLightning.Infrastructure.Bitcoin
File(s): /home/runner/work/nlightning/nlightning/src/NLightning.Infrastructure.Bitcoin/Encoders/Bech32Encoder.cs
Tag: 36_15743069263
Line coverage
89%
Covered lines: 25
Uncovered lines: 3
Coverable lines: 28
Total lines: 86
Line coverage: 89.2%
Branch coverage
71%
Covered branches: 10
Total branches: 14
Branch coverage: 71.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)50%22100%
EncodeLightningInvoice(...)100%22100%
DecodeLightningInvoice(...)70%10.461083.33%

File(s)

/home/runner/work/nlightning/nlightning/src/NLightning.Infrastructure.Bitcoin/Encoders/Bech32Encoder.cs

#LineLine coverage
 1using System.Text;
 2using NBitcoin.DataEncoders;
 3
 4namespace NLightning.Infrastructure.Bitcoin.Encoders;
 5
 6using Domain.Constants;
 7using Domain.Utils;
 8
 9/// <summary>
 10/// Bech32 encoder for lightning invoices
 11/// </summary>
 12/// <param name="hrp">The Human Readable Part</param>
 15613internal sealed class Bech32Encoder(string? hrp = null) : NBitcoin.DataEncoders.Bech32Encoder(hrp is null ? Encoding.UTF
 14{
 15    /// <summary>
 16    /// Encode the lightning invoice into a bech32 string
 17    /// </summary>
 18    /// <param name="bitWriter">Bit writer to write to</param>
 19    /// <param name="signature">Signature to encode</param>
 20    /// <returns>String representing the invoice</returns>
 21    internal string EncodeLightningInvoice(BitWriter bitWriter, byte[] signature)
 22    {
 23        // Convert to 5 bits per byte
 7224        var convertedSignature = ConvertBits(signature.AsReadOnly(), 8, 5);
 7225        var convertedData = ConvertBits(bitWriter.ToArray().AsReadOnly(), 8, 5);
 26
 27        // Check for padding
 7228        var expectedLength = bitWriter.TotalBits / 5;
 7229        if (convertedData.Length != expectedLength)
 30        {
 7231            convertedData = convertedData[..expectedLength];
 32        }
 33
 7234        var invoiceData = new byte[104 + convertedData.Length];
 7235        convertedData.CopyTo(invoiceData, 0);
 7236        convertedSignature.CopyTo(invoiceData, convertedData.Length);
 37
 7238        return EncodeData(invoiceData, Bech32EncodingType.BECH32);
 39    }
 40
 41    /// <summary>
 42    /// Decode the lightning invoice from a bech32 string
 43    /// </summary>
 44    /// <param name="invoiceString">String representing the invoice</param>
 45    /// <param name="data">Data part of the invoice</param>
 46    /// <param name="signature">Signature part of the invoice</param>
 47    /// <param name="hrp">Human Readable Part of the invoice</param>
 48    internal static void DecodeLightningInvoice(string invoiceString, out byte[] data, out byte[] signature, out string 
 49    {
 50        // Be lenient and covert it all to lower case
 9251        invoiceString = invoiceString.ToLowerInvariant();
 52
 53        // Validate the prefix
 9254        if (!invoiceString.StartsWith(InvoiceConstants.Prefix))
 55        {
 456            throw new ArgumentException("Missing prefix in invoice", nameof(invoiceString));
 57        }
 58
 59        // Extract human readable part
 8860        var separatorIndex = invoiceString.LastIndexOf(InvoiceConstants.Separator);
 61        switch (separatorIndex)
 62        {
 63            case -1:
 464                throw new ArgumentException("Invalid invoice format", nameof(invoiceString));
 65            case 0:
 066                throw new ArgumentException("Missing human readable part in invoice", nameof(invoiceString));
 67            case > 21:
 068                throw new ArgumentException("Human readable part too long in invoice", nameof(invoiceString));
 69        }
 70
 8471        hrp = invoiceString[..separatorIndex];
 8472        var bech32 = new Bech32Encoder(invoiceString[..separatorIndex])
 8473        {
 8474            StrictLength = false
 8475        };
 8476        var invoiceData = bech32.DecodeDataRaw(invoiceString, out var encodingType);
 77
 8078        if (encodingType != Bech32EncodingType.BECH32)
 79        {
 080            throw new ArgumentException("Invalid encoding type in invoice", nameof(invoiceString));
 81        }
 82
 8083        signature = bech32.ConvertBits(invoiceData.AsSpan()[(invoiceData.Length - 104)..], 5, 8);
 7684        data = bech32.ConvertBits(invoiceData.AsSpan()[..(invoiceData.Length - 104)], 5, 8);
 7685    }
 86}