< Summary - Combined Code Coverage

Information
Class: NLightning.Infrastructure.Bitcoin.Wallet.BitcoinChainService
Assembly: NLightning.Infrastructure.Bitcoin
File(s): /home/runner/work/NLightning/NLightning/src/NLightning.Infrastructure.Bitcoin/Wallet/BitcoinChainService.cs
Tag: 57_24045730253
Line coverage
0%
Covered lines: 0
Uncovered lines: 48
Coverable lines: 48
Total lines: 116
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 6
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)0%620%
SendTransactionAsync()0%2040%
GetTransactionAsync()100%210%
GetCurrentBlockHeightAsync()100%210%
GetBlockAsync()100%210%
GetTransactionConfirmationsAsync()100%210%

File(s)

/home/runner/work/NLightning/NLightning/src/NLightning.Infrastructure.Bitcoin/Wallet/BitcoinChainService.cs

#LineLine coverage
 1using System.Net;
 2using Microsoft.Extensions.Logging;
 3using Microsoft.Extensions.Options;
 4using NBitcoin;
 5using NBitcoin.RPC;
 6
 7namespace NLightning.Infrastructure.Bitcoin.Wallet;
 8
 9using Domain.Node.Options;
 10using Interfaces;
 11using Options;
 12
 13public class BitcoinChainService : IBitcoinChainService
 14{
 15    private readonly RPCClient _rpcClient;
 16    private readonly ILogger<BitcoinChainService> _logger;
 17
 018    public BitcoinChainService(IOptions<BitcoinOptions> bitcoinOptions, ILogger<BitcoinChainService> logger,
 019                               IOptions<NodeOptions> nodeOptions)
 20    {
 021        _logger = logger;
 022        var network = Network.GetNetwork(nodeOptions.Value.BitcoinNetwork) ?? Network.Main;
 23
 024        var rpcCredentials = new RPCCredentialString
 025        {
 026            UserPassword = new NetworkCredential(bitcoinOptions.Value.RpcUser, bitcoinOptions.Value.RpcPassword)
 027        };
 28
 029        _rpcClient = new RPCClient(rpcCredentials, bitcoinOptions.Value.RpcEndpoint, network);
 030        _rpcClient.GetBlockchainInfo();
 031    }
 32
 33    public async Task<uint256> SendTransactionAsync(Transaction transaction)
 34    {
 35        try
 36        {
 037            if (_logger.IsEnabled(LogLevel.Information))
 038                _logger.LogInformation("Broadcasting transaction {TxId}", transaction.GetHash());
 39
 040            var result = await _rpcClient.SendRawTransactionAsync(transaction);
 41
 042            if (_logger.IsEnabled(LogLevel.Information))
 043                _logger.LogInformation("Successfully broadcast transaction {TxId}", result);
 44
 045            return result;
 46        }
 047        catch (Exception ex)
 48        {
 049            _logger.LogError(ex, "Failed to broadcast transaction {TxId}", transaction.GetHash());
 050            throw;
 51        }
 052    }
 53
 54    public async Task<Transaction?> GetTransactionAsync(uint256 txId)
 55    {
 56        try
 57        {
 058            return await _rpcClient.GetRawTransactionAsync(new uint256(txId), false);
 59        }
 060        catch (RPCException ex) when (ex.RPCCode == RPCErrorCode.RPC_INVALID_ADDRESS_OR_KEY)
 61        {
 062            return null; // Transaction not found
 63        }
 064        catch (Exception ex)
 65        {
 066            _logger.LogError(ex, "Failed to get transaction {TxId}", txId);
 067            throw;
 68        }
 069    }
 70
 71    public async Task<uint> GetCurrentBlockHeightAsync()
 72    {
 73        try
 74        {
 075            var blockCount = await _rpcClient.GetBlockCountAsync();
 076            return (uint)blockCount;
 77        }
 078        catch (Exception ex)
 79        {
 080            _logger.LogError(ex, "Failed to get current block height");
 081            throw;
 82        }
 083    }
 84
 85    public async Task<Block?> GetBlockAsync(uint height)
 86    {
 87        try
 88        {
 089            var blockHash = await _rpcClient.GetBlockHashAsync((int)height);
 090            return await _rpcClient.GetBlockAsync(blockHash);
 91        }
 092        catch (Exception ex)
 93        {
 094            _logger.LogError(ex, "Failed to get block at height {Height}", height);
 095            throw;
 96        }
 097    }
 98
 99    public async Task<uint> GetTransactionConfirmationsAsync(uint256 txId)
 100    {
 101        try
 102        {
 0103            var txInfo = await _rpcClient.GetRawTransactionInfoAsync(new uint256(txId));
 0104            return txInfo.Confirmations;
 105        }
 0106        catch (RPCException ex) when (ex.RPCCode == RPCErrorCode.RPC_INVALID_ADDRESS_OR_KEY)
 107        {
 0108            return 0; // Transaction not found
 109        }
 0110        catch (Exception ex)
 111        {
 0112            _logger.LogError(ex, "Failed to get confirmations for transaction {TxId}", txId);
 0113            throw;
 114        }
 0115    }
 116}