Skip to content
A .NET implementation of the Lightning Network
C#
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
NLightning.Bitcoind
NLightning.Console
NLightning.Test
NLightning
.gitignore
LICENSE
NLightning.sln
NLightning.sln.DotSettings
README.md

README.md

NLightning

NLightning is a library to connect, synchronize, send and receive payments with the lightning network.

Current implementation uses bitcoind (with -txindex) as backend.

⚠ NLightning is in an early development stage, do not use with real funds!

Features:

  • DNS bootstrap
  • Download and synchronize network view
  • Open channels
  • Mutual and unilateral closing of channels
  • Handle penalty and remote unilateral close
  • Send and receive payments
  • SPV wallet support (BIP 157, BIP 158)
  • Backup channels
  • Support watchtowers

Supported platforms:

  • .NET Core (Linux, MacOS, Windows)

Not yet supported:

  • Xamarin iOS
  • Xamarin Android

Dependencies:

  • NBitcoin
  • EFCore
  • Portable.BouncyCastle
  • System.Reactive
  • Microsoft Extensions (Logging)
  • DnsClient
  • xUnit, Moq

Usage

Configuration

ECKeyPair localLightningKey = new ECKeyPair("<node private key>", true);
ECKeyPair walletKey = new ECKeyPair("<wallet private key>", true);

LightningNode node = new LightningNode(localLightningKey, walletKey, NetworkParameters.BitcoinTestnet);

node.ConfigureServices(services =>
{
    // by default NLightning loads the configuration from a nlightning.json file located in the working directory.
    // if you want to load your own configuration instead add it to the services:
    // services.AddSingleton(new ConfigurationBuilder()
    //                       .SetBasePath(Directory.GetCurrentDirectory())
    //                       .AddJsonFile("my-config.json", true, true));
        
    // we use bitcoind (with -txindex) as backend
    services.AddSingleton<IBlockchainClientService, BitcoindClientService>();
    
    // configure logging
    services.AddLogging(logging => logging.SetMinimumLevel(LogLevel.Debug)
                                          .AddConsole(options => options.IncludeScopes = false)
                                          .AddDebug()
                                          .AddFilter("Microsoft.EntityFrameworkCore", LogLevel.Warning));
    
    // configure network db (gossip data)
    // we support sqlite, but others should work as well
    services.AddDbContext<NetworkPersistenceContext>(options => options.UseSqlite("Data Source=network.db"));
    
    // configure local db (channel and peer data) 
    // private keys are stored here
    services.AddDbContext<LocalPersistenceContext>(options => options.UseSqlite("Data Source=local.db"));
});

// Start all services.
node.Initialize();

Configuration Entities: BitcoindClientConfiguration, BlockchainConfiguration, ChannelConfiguration, NetworkViewConfiguration, PeerConfiguration

Connect to a node

IPeerService peerService = node.Services.GetService<IPeerService>();
NodeAddress nodeAddress = NodeAddress.Parse("<publickey@ip:port>");
IPeer peer = peerService.AddPeer(nodeAddress, persist: true, reconnect: true);

Open a channel

var channelEstablishmentService = node.Services.GetService<IChannelEstablishmentService>();
channelEstablishmentService.SuccessProvider.Subscribe(peerAndChannel =>
{
    // $"Opened a channel (ID: {peerAndChannel.Channel.ChannelId} with peer {peerAndChannel.Peer.NodeAddress}";  
});

// Open a channel with a funding of 25000 Satoshis
channelEstablishmentService.OpenChannel(peer, 25000);

Get all active channels and updates

IChannelService channelService = node.Services.GetService<IChannelService>();
var activeChannels = channelService.Channels.Where(c => c.Active);
var channelStateService = node.Services.GetService<IChannelStateService>();
channelStateService.ChannelActiveStateChangedProvider
    .Where(c => c.Active)
    .Subscribe(channel =>
    {
        // Channel is active
    });

Close a channel

IChannelCloseService closeService = node.Services.GetService<IChannelCloseService>();

// mutual close, if peer is not available do an unilateral close:
closeService.Close(channel, unilateralCloseOnUnavailability: true);

// unilateral close:
closeService.UnilateralClose(channel);

Get all channels and nodes in the network

var networkViewService = node.Services.GetService<INetworkViewService>();
var networkChannels = networkViewService.View.GetChannels();
var networkNodes = networkViewService.View.GetNodes();
You can’t perform that action at this time.