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; } } }
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); } } }