public async Task CanCreateInvoiceUsingConnectionString()
        {
            ILightningClientFactory factory = new LightningClientFactory(Tester.Network);

            var connectionStrings = Docker
                ? new[]
            {
                "type=charge;server=http://api-token:foiewnccewuify@charge:9112",
                "type=lnd-rest;server=https://lnd_dest:8080;allowinsecure=true",
                "type=clightning;server=tcp://lightningd:9835",
                "type=eclair;server=http://eclair:8080;password=bukkake;bitcoin-host=bitcoind:43782;bitcoin-auth=ceiwHEbqWI83:DwubwWsoo3"
            }
                : new[]
            {
                "type=charge;server=http://api-token:[email protected]:37462",
                "type=lnd-rest;server=https://127.0.0.1:42802;allowinsecure=true",
                "type=clightning;server=tcp://127.0.0.1:48532",
                "type=eclair;server=http://127.0.0.1:4570;password=bukkake;bitcoin-host=127.0.0.1:37393;bitcoin-auth=ceiwHEbqWI83:DwubwWsoo3"
            };

            foreach (var connectionString in connectionStrings)
            {
                ILightningClient client = factory.Create(connectionString);
                var createdInvoice      = await client.CreateInvoice(10000, "CanCreateInvoice", TimeSpan.FromMinutes(5));

                var retrievedInvoice = await client.GetInvoice(createdInvoice.Id);

                AssertUnpaid(createdInvoice);
                AssertUnpaid(retrievedInvoice);
            }
        }
        public static async Task CreateChannel(RPCClient cashCow, ILightningClient sender, ILightningClient dest)
        {
            var destInfo = await dest.GetInfo();

            var destInvoice = await dest.CreateInvoice(1000, "EnsureConnectedToDestination", TimeSpan.FromSeconds(5000));

            while (true)
            {
                var result = await sender.Pay(destInvoice.BOLT11);

                if (result.Result == PayResult.CouldNotFindRoute)
                {
                    var openChannel = await sender.OpenChannel(new OpenChannelRequest()
                    {
                        NodeInfo      = destInfo.NodeInfoList[0],
                        ChannelAmount = Money.Satoshis(16777215),
                        FeeRate       = new FeeRate(1UL, 1)
                    });

                    if (openChannel.Result == OpenChannelResult.CannotAffordFunding)
                    {
                        var address = await sender.GetDepositAddress();

                        try
                        {
                            await cashCow.SendToAddressAsync(address, Money.Coins(1.0m), null, null, true);
                        }
                        catch (RPCException ex) when(ex.RPCCode == RPCErrorCode.RPC_WALLET_INSUFFICIENT_FUNDS || ex.RPCCode == RPCErrorCode.RPC_WALLET_ERROR)
                        {
                            await cashCow.GenerateAsync(1);

                            await cashCow.SendToAddressAsync(address, Money.Coins(1.0m), null, null, true);
                        }
                        await cashCow.GenerateAsync(10);
                        await WaitLNSynched(cashCow, sender);
                        await WaitLNSynched(cashCow, dest);
                    }
                    if (openChannel.Result == OpenChannelResult.PeerNotConnected)
                    {
                        await sender.ConnectTo(destInfo.NodeInfoList[0]);
                    }
                    if (openChannel.Result == OpenChannelResult.NeedMoreConf)
                    {
                        await cashCow.GenerateAsync(6);
                        await WaitLNSynched(cashCow, sender);
                        await WaitLNSynched(cashCow, dest);
                    }
                    if (openChannel.Result == OpenChannelResult.AlreadyExists)
                    {
                        await Task.Delay(1000);
                    }
                }
                else if (result.Result == PayResult.Ok)
                {
                    break;
                }
            }
        }
Example #3
0
        public async Task CanCreateInvoiceUsingConnectionString()
        {
            ILightningClientFactory factory = new LightningClientFactory(Tester.Network);

            foreach (var connectionString in new[]
            {
                "type=charge;server=http://api-token:[email protected]:37462",
                "type=lnd-rest;server=https://127.0.0.1:42802;allowinsecure=true",
                "type=clightning;server=tcp://127.0.0.1:48532"
            })
            {
                ILightningClient client = factory.Create(connectionString);
                var createdInvoice      = await client.CreateInvoice(10000, "CanCreateInvoice", TimeSpan.FromMinutes(5));

                var retrievedInvoice = await client.GetInvoice(createdInvoice.Id);

                AssertUnpaid(createdInvoice);
                AssertUnpaid(retrievedInvoice);
            }
        }
Example #4
0
        public async Task CanCreateInvoiceUsingConnectionString()
        {
            ILightningClientFactory factory = new LightningClientFactory(Tester.Network);

            var connectionStrings = Docker
                                ? new[]
            {
                "type=charge;server=http://api-token:foiewnccewuify@charge:9112;allowinsecure=true",
                "type=lnd-rest;server=http://lnd_dest:8080;allowinsecure=true",
                "type=clightning;server=tcp://lightningd:9835",
                "type=eclair;server=http://eclair:8080;password=bukkake"
            }
                                : new[]
            {
                "type=charge;server=http://api-token:[email protected]:37462;allowinsecure=true",
                "type=lnd-rest;server=http://127.0.0.1:42802;allowinsecure=true",
                "type=clightning;server=tcp://127.0.0.1:48532",
                "type=eclair;server=http://127.0.0.1:4570;password=bukkake"
            };

            var clientTypes = Tester.GetLightningClients().Select(l => l.Client.GetType()).ToArray();

            foreach (var connectionString in connectionStrings)
            {
                ILightningClient client = factory.Create(connectionString);
                if (!clientTypes.Contains(client.GetType()))
                {
                    continue;
                }
                var createdInvoice = await client.CreateInvoice(10000, "CanCreateInvoice", TimeSpan.FromMinutes(5));

                var retrievedInvoice = await client.GetInvoice(createdInvoice.Id);

                AssertUnpaid(createdInvoice);
                AssertUnpaid(retrievedInvoice);
            }
        }
Example #5
0
        public static async Task CreateChannel(RPCClient cashCow, ILightningClient sender, ILightningClient dest)
        {
            var destInfo = await dest.GetInfo();

            var destInvoice = await dest.CreateInvoice(1000, "EnsureConnectedToDestination", TimeSpan.FromSeconds(5000));

            while (true)
            {
                int payErrors = 0;
                var result    = await Pay(sender, destInvoice.BOLT11);

                Logs.LogInformation($"Pay Result: {result.Result} {result.ErrorDetail}");
                if (result.Result == PayResult.Ok)
                {
                    break;
                }
                else if (result.Result == PayResult.CouldNotFindRoute)
                {
                    // check channels that are in process of opening, to prevent double channel open
                    await Task.Delay(100);

                    var pendingChannels = await sender.ListChannels();

                    if (pendingChannels.Any(a => a.RemoteNode == destInfo.NodeInfoList[0].NodeId))
                    {
                        Logs.LogInformation($"Channel to {destInfo.NodeInfoList[0]} is already open(ing)");

                        Logs.LogInformation($"Attempting to reconnect Result: {await sender.ConnectTo(destInfo.NodeInfoList.First())}");

                        await cashCow.GenerateAsync(1);
                        await WaitLNSynched(cashCow, sender);
                        await WaitLNSynched(cashCow, dest);

                        continue;
                    }

                    Logs.LogInformation($"Opening channel to {destInfo.NodeInfoList[0]}");
                    var openChannel = await sender.OpenChannel(new OpenChannelRequest()
                    {
                        NodeInfo      = destInfo.NodeInfoList[0],
                        ChannelAmount = Money.Satoshis(16777215),
                        FeeRate       = new FeeRate(1UL, 1)
                    });

                    Logs.LogInformation($"Channel opening result: {openChannel.Result}");
                    if (openChannel.Result == OpenChannelResult.CannotAffordFunding)
                    {
                        var address = await sender.GetDepositAddress();

                        try
                        {
                            await cashCow.SendToAddressAsync(address, Money.Coins(1.0m), new SendToAddressParameters()
                            {
                                Replaceable = true
                            });
                        }
                        catch (RPCException ex) when(ex.RPCCode == RPCErrorCode.RPC_WALLET_INSUFFICIENT_FUNDS || ex.RPCCode == RPCErrorCode.RPC_WALLET_ERROR)
                        {
                            await cashCow.GenerateAsync(1);

                            await cashCow.SendToAddressAsync(address, Money.Coins(1.0m), new SendToAddressParameters()
                            {
                                Replaceable = true
                            });
                        }
                        await cashCow.GenerateAsync(10);
                        await WaitLNSynched(cashCow, sender);
                        await WaitLNSynched(cashCow, dest);
                    }
                    if (openChannel.Result == OpenChannelResult.PeerNotConnected)
                    {
                        await sender.ConnectTo(destInfo.NodeInfoList[0]);
                    }
                    if (openChannel.Result == OpenChannelResult.NeedMoreConf)
                    {
                        await cashCow.GenerateAsync(6);
                        await WaitLNSynched(cashCow, sender);
                        await WaitLNSynched(cashCow, dest);
                    }
                    if (openChannel.Result == OpenChannelResult.AlreadyExists)
                    {
                        await Task.Delay(1000);
                    }
                    if (openChannel.Result == OpenChannelResult.Ok)
                    {
                        // generate one block and a bit more time to confirm channel opening
                        await cashCow.GenerateAsync(1);
                        await WaitLNSynched(cashCow, sender);
                        await WaitLNSynched(cashCow, dest);

                        await Task.Delay(500);
                    }
                }
                else
                {
                    if (payErrors++ > 10)
                    {
                        throw new Exception($"Couldn't establish payment channel after {payErrors} repeated tries");
                    }

                    await Task.Delay(1000);
                }
            }
        }