public ChannelInfoResponse Get(string cryptoCode) { var n = _networkProvider.GetByCryptoCode(cryptoCode.ToLowerInvariant()); var peer = _peerManagerProvider.TryGetPeerManager(n); var details = peer.ChannelManager.ListChannels(_pool); return(new ChannelInfoResponse { Details = details }); }
public ActionResult <ChannelInfoResponse> Get(string cryptoCode) { var n = _networkProvider.GetByCryptoCode(cryptoCode.ToLowerInvariant()); var peer = _peerManagerProvider.TryGetPeerManager(n); if (peer is null) { return(BadRequest($"cyrptocode: {cryptoCode} not supported")); } var details = peer.ChannelManager.ListChannels(_pool); return(new ChannelInfoResponse { Details = details }); }
public NetworkGraph DescribeGraph() { var n = _networkProvider.GetByCryptoCode(config.ChainConfiguration[0].CryptoCode); var peerMan = _peerManagerProvider.GetPeerManager(n); return(peerMan.GetNetworkGraph(_pool)); }
public async Task <JsonResult> GetWalletInfo(string cryptoCode) { var n = _networkProvider.GetByCryptoCode(cryptoCode); var derivationStrategy = await _walletService.GetOurDerivationStrategyAsync(n); var balance = await _walletService.GetBalanceAsync(n); var outboundCaps = _peerManagerProvider.GetPeerManager(n).ChannelManager.ListChannels(_pool) .Select(c => c.OutboundCapacityMSat).ToArray(); var offChainBalance = outboundCaps.Length == 0 ? 0 : outboundCaps.Aggregate((x, acc) => x + acc); var resp = new WalletInfo { DerivationStrategy = derivationStrategy, OnChainBalanceSatoshis = balance, OffChainBalanceMSat = offChainBalance }; return(new JsonResult(resp, _repositoryProvider.GetSerializer(n).Options)); }
public void RepositorySerializerTest(string cryptoCode) { var networkProvider = new NRustLightningNetworkProvider(NetworkType.Regtest); var ser = new RepositorySerializer(networkProvider.GetByCryptoCode(cryptoCode)); // utxo response var resp = new UTXOChangesWithMetadata(); var confirmed = new UTXOChangeWithSpentOutput(); var unconfirmed = new UTXOChangeWithSpentOutput(); confirmed.SpentOutPoint = new List <OutPoint>() { OutPoint.Zero }; var coinBaseTx = Transaction.Parse( "020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401750101ffffffff0200f2052a0100000017a914d4bb8bf5f987cd463a2f5e6e4f04618c7aaed1b5870000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", Network.RegTest); var utxo = new UTXO(new NBXplorer.Models.UTXO(coinBaseTx.Outputs.AsCoins().First())); Assert.NotNull(JsonSerializer.Serialize(utxo, ser.Options)); confirmed.UTXO = new List <UTXOChangeWithMetadata>() { new UTXOChangeWithMetadata(utxo, UTXOKind.UserDeposit, new AddressTrackedSource(coinBaseTx.Outputs[0].ScriptPubKey.GetDestinationAddress(Network.RegTest))) }; resp.Confirmed = confirmed; resp.UnConfirmed = unconfirmed; var res = JsonSerializer.Serialize(resp, ser.Options); Assert.NotNull(res); }
/// <summary> /// Start bitcoind and nbxplorer in the backgroud. /// </summary> /// <param name="dockerFixture"></param> /// <param name="output"></param> /// <param name="caller"></param> /// <returns></returns> public static async Task <ExplorerClient> StartExplorerFixtureAsync(this DockerFixture dockerFixture, string caller) { var ports = new int[2]; Support.Utils.FindEmptyPort(ports); var dataPath = Path.GetFullPath(caller); if (!Directory.Exists(dataPath)) { Directory.CreateDirectory(dataPath); } else { Directory.Delete(dataPath, true); Directory.CreateDirectory(dataPath); } var env = new Dictionary <string, object>() { { "BITCOIND_RPC_AUTH", Constants.BitcoindRPCAuth }, { "BITCOIND_RPC_USER", Constants.BitcoindRPCUser }, { "BITCOIND_RPC_PASS", Constants.BitcoindRPCPass }, { "BITCOIND_RPC_PORT", ports[0] }, { "NBXPLORER_PORT", ports[1] }, { "DATA_PATH", dataPath } }; var envFile = Path.Join(dataPath, "env.sh"); using (TextWriter w = File.AppendText(envFile)) { foreach (var kv in env) { w.WriteLine($"export {kv.Key}='{kv.Value}'"); } } await dockerFixture.InitAsync(() => new DockerFixtureOptions { DockerComposeFiles = new[] { "docker-compose.base.yml" }, EnvironmentVariables = env, DockerComposeDownArgs = "--remove-orphans --volumes", // we need this because c-lightning is not working well with bind mount. // If we use volume mount instead, this is the only way to recreate the volume at runtime. DockerComposeUpArgs = "--renew-anon-volumes", StartupTimeoutSecs = 400, LogFilePath = Path.Join(dataPath, "docker-compose.log"), CustomUpTest = o => { return (o.Any(x => x.Contains("BTC: Node state changed: NBXplorerSynching => Ready"))); // nbx is up } }); var networkProvider = new NRustLightningNetworkProvider(NetworkType.Regtest); var btcNetwork = networkProvider.GetByCryptoCode("BTC"); return(new ExplorerClient(btcNetwork.NbXplorerNetwork, new Uri($"http://localhost:{ports[1]}"))); }
public async Task <JsonResult> Invoice(string cryptoCode, [FromBody] InvoiceCreationOption option) { var n = _networkProvider.GetByCryptoCode(cryptoCode); var invoice = await _invoiceRepository.GetNewInvoice(n, option); var resp = new InvoiceResponse { Invoice = invoice }; return(new JsonResult(resp, _repositoryProvider.GetSerializer(n).Options)); }
public ExplorerClient GetClient(string cryptoCode) { return(new ExplorerClient(_networkProvider.GetByCryptoCode(cryptoCode).NbXplorerNetwork)); }
public static async Task <Clients> StartLNTestFixtureAsync(this DockerFixture dockerFixture, string caller, bool useCachedData = false) { var ports = new int[5]; Support.Utils.FindEmptyPort(ports); var dataPath = Path.GetFullPath(caller); if (Directory.Exists(dataPath) && !useCachedData) { Directory.Delete(dataPath, true); } Directory.CreateDirectory(dataPath); var env = new Dictionary <string, object>() { { "BITCOIND_RPC_AUTH", Constants.BitcoindRPCAuth }, { "BITCOIND_RPC_USER", Constants.BitcoindRPCUser }, { "BITCOIND_RPC_PASS", Constants.BitcoindRPCPass }, { "BITCOIND_RPC_PORT", ports[0] }, { "LND_REST_PORT", ports[1] }, { "LIGHTNINGD_RPC_PORT", ports[2] }, { "HTTP_PORT", ports[3] }, { "NBXPLORER_PORT", ports[4] }, { "DATA_PATH", dataPath } }; var envFile = Path.Join(dataPath, "env.sh"); using (TextWriter w = File.AppendText(envFile)) { foreach (var kv in env) { w.WriteLine($"export {kv.Key}='{kv.Value}'"); } } await dockerFixture.InitAsync(() => new DockerFixtureOptions { DockerComposeFiles = new[] { "docker-compose.yml" }, EnvironmentVariables = env, DockerComposeDownArgs = "--remove-orphans --volumes", // we need this because c-lightning is not working well with bind mount. // If we use volume mount instead, this is the only way to recreate the volume at runtime. DockerComposeUpArgs = "--renew-anon-volumes", StartupTimeoutSecs = 400, LogFilePath = Path.Join(dataPath, "docker-compose.log"), CustomUpTest = o => { return (o.Any(x => x.Contains("Now listening on: http://0.0.0.0:9735")) && // nrustlightning is up o.Any(x => x.Contains("PeerManagerProvider started")) && // ditto o.Any(x => x.Contains("Server started with public key")) && // lightningd is up o.Any(x => x.Contains("BTC: Node state changed: NBXplorerSynching => Ready")) && // nbx is up o.Any(x => x.Contains("BTCN: Server listening on"))); // lnd is up } }); var networkProvider = new NRustLightningNetworkProvider(NetworkType.Regtest); var btcNetwork = networkProvider.GetByCryptoCode("BTC"); var lndMacaroonPath = Path.Join(dataPath, ".lnd", "chain", "bitcoin", "regtest", "admin.macaroon"); var lndTlsCertThumbPrint = GetCertificateFingerPrintHex(Path.Join(dataPath, ".lnd", "tls.cert")); var clients = new Clients( new RPCClient($"{Constants.BitcoindRPCUser}:{Constants.BitcoindRPCPass}", new Uri($"http://localhost:{ports[0]}"), NBitcoin.Network.RegTest), (LndClient)LightningClientFactory.CreateClient($"type=lnd-rest;macaroonfilepath={lndMacaroonPath};certthumbprint={lndTlsCertThumbPrint};server=https://localhost:{ports[1]}", NBitcoin.Network.RegTest), (CLightningClient)LightningClientFactory.CreateClient($"type=clightning;server=tcp://127.0.0.1:{ports[2]}", NBitcoin.Network.RegTest), new NRustLightningClient($"http://localhost:{ports[3]}", btcNetwork), new ExplorerClient(btcNetwork.NbXplorerNetwork, new Uri($"http://localhost:{ports[4]}")) ); return(clients); }
static async Task Main(string[] args) { var command = CommandLine.GetRootCommand(); command.Handler = CommandHandler.Create((ParseResult pr) => { Console.WriteLine($"Calling handler"); Network?network; var n = pr.RootCommandResult.ValueForOption <string>("network"); network = n == "mainnet" ? Network.Main : n == "testnet" ? Network.TestNet : n == "regtest" ? Network.RegTest : null; if (network is null) { if (pr.RootCommandResult.ValueForOption <bool>("testnet")) { network = Network.TestNet; } else if (pr.RootCommandResult.ValueForOption <bool>("regtest")) { network = Network.RegTest; } } if (network is null) { network = Network.Main; } var ip = pr.RootCommandResult.ValueForOption <string>("rpcip"); if (String.IsNullOrEmpty(ip)) { ip = "127.0.0.1"; } var networkProvider = new NRustLightningNetworkProvider(network.NetworkType); var nrustLightningNetwork = networkProvider.GetByCryptoCode(pr.RootCommandResult.ValueForOption <string>("cryptocode") ?? "btc"); var port = pr.RootCommandResult.ValueForOption <int>("rpcport"); if (port == 0) { port = 80; } var baseUrl = $"http://{ip}:{port}"; var client = new NRustLightningClient(baseUrl, nrustLightningNetwork); var subCommand = pr.CommandResult.Symbol.Name; Console.WriteLine($"Subcomamnd is {subCommand}"); if (subCommand == SubCommands.GetInfo) { var nodeInfo = client.GetInfoAsync().Result; Console.WriteLine(nodeInfo.ConnectionString); } else { throw new ArgumentException($"Unknown sub command {subCommand}"); } return; }); var commandLine = new CommandLineBuilder(command).UseDefaults() .Build(); await commandLine.InvokeAsync(args); }
public void CanConvertJsonTypes() { var invoice = "lnbc1p0vhtzvpp5akajlfqdj6ek7eeh4kae6gc05fz9j99n8jadatqt4fmlwwxwx4zsnp4q2uqg2j52gxtxg5d0v928h5pll95ynsaek2csgfg26tvuzydgjrwgdqhdehjqer9wd3hy6tsw35k7msna3vtx"; var paymentRequest = PaymentRequest.Parse(invoice); var resp = new InvoiceResponse() { Invoice = paymentRequest.ResultValue }; var j = JsonSerializer.Serialize(resp); JsonSerializer.Deserialize <InvoiceResponse>(j); var invoiceResponseRaw = "{\"invoice\":\"lnbc1p0vma42pp5t2v5ehyay3x9g8769gqkrhmdlqjq0kc8ksqfxu3xjw7s2y96jegqnp4q2uqg2j52gxtxg5d0v928h5pll95ynsaek2csgfg26tvuzydgjrwgdqhdehjqer9wd3hy6tsw35k7ms3xhenl\"}"; JsonSerializer.Deserialize <InvoiceResponse>(invoiceResponseRaw); var conf = UserConfig.GetDefault(); j = JsonSerializer.Serialize(conf); var v = JsonSerializer.Deserialize <UserConfig>(j); Assert.Equal(conf.ChannelOptions.AnnouncedChannel, v.ChannelOptions.AnnouncedChannel); var openChannelRequest = new OpenChannelRequest(); j = JsonSerializer.Serialize(openChannelRequest); var conv = JsonSerializer.Deserialize <OpenChannelRequest>(j); Assert.Equal(openChannelRequest.OverrideConfig, conv.OverrideConfig); // with custom config openChannelRequest.OverrideConfig = UserConfig.GetDefault(); j = JsonSerializer.Serialize(openChannelRequest); // Don't know why but we must specify option here. var opt = new JsonSerializerOptions(); opt.Converters.Add(new NullableStructConverterFactory()); conv = JsonSerializer.Deserialize <OpenChannelRequest>(j, opt); Assert.True(conv.OverrideConfig.HasValue); Assert.Equal(openChannelRequest.OverrideConfig.Value.ChannelOptions.AnnouncedChannel, conv.OverrideConfig.Value.ChannelOptions.AnnouncedChannel); j = "{\"TheirNetworkKey\":\"024a8b7fc86957537bb365cc0242255582d3d40a5532489f67e700a89bcac2f010\",\"ChannelValueSatoshis\":100000,\"PushMSat\":1000,\"OverrideConfig\":null}"; openChannelRequest = JsonSerializer.Deserialize <OpenChannelRequest>(j, new JsonSerializerOptions() { Converters = { new HexPubKeyConverter() } }); Assert.Equal(100000UL, openChannelRequest.ChannelValueSatoshis); Assert.Equal(1000UL, openChannelRequest.PushMSat); Assert.NotNull(openChannelRequest.TheirNetworkKey); // wallet info j = "{\"DerivationStrategy\":\"tpubDBte1PdX36pt167AFbKpHwFJqZAVVRuJSadZ49LdkX5JJbJCNDc8JQ7w5GdaDZcUXm2SutgwjRuufwq4q4soePD4fPKSZCUhqDDarKRCUen\",\"OnChainBalanceSatoshis\":0}"; var networkProvider = new NRustLightningNetworkProvider(NetworkType.Regtest); var btcNetwork = networkProvider.GetByCryptoCode("BTC"); var walletInfo = JsonSerializer.Deserialize <WalletInfo>(j, new JsonSerializerOptions { Converters = { new DerivationStrategyJsonConverter(btcNetwork.NbXplorerNetwork.DerivationStrategyFactory) } }); // FeatureBit var featureBit = FeatureBit.TryParse("0b000000100100000100000000").ResultValue; var opts = new JsonSerializerOptions() { Converters = { new FeatureBitJsonConverter() } }; j = JsonSerializer.Serialize(featureBit, opts); Assert.Contains("prettyPrint", j); var featureBit2 = JsonSerializer.Deserialize <FeatureBit>(j, opts); Assert.Equal(featureBit, featureBit2); }
public async Task RepositoryTest() { using var tester = DBTrieRepositoryTester.Create(); // 1. Check invoice Equality var networkProvider = new NRustLightningNetworkProvider(NetworkType.Regtest); var network = networkProvider.GetByCryptoCode("BTC"); var nodeSecret = new Key(); var nodeId = Primitives.NodeId.NewNodeId(nodeSecret.PubKey); Primitives.PaymentPreimage paymentPreimage = Primitives.PaymentPreimage.Create(RandomUtils.GetBytes(32)); var taggedFields = new List <TaggedField> { TaggedField.NewPaymentHashTaggedField(paymentPreimage.Hash), TaggedField.NewNodeIdTaggedField((nodeId)), TaggedField.NewDescriptionTaggedField("Test invoice") }; var t = new TaggedFields(taggedFields.ToFSharpList()); var invoiceR = PaymentRequest.TryCreate(network.BOLT11InvoicePrefix, FSharpOption <LNMoney> .None, DateTimeOffset.UtcNow, nodeId, t, nodeSecret); if (invoiceR.IsError) { throw new Exception(invoiceR.ErrorValue); } var invoice = invoiceR.ResultValue; await tester.Repository.SetInvoice(invoice); var invoice2 = await tester.Repository.GetInvoice(paymentPreimage.Hash); Assert.Equal(invoice.ToString(), invoice2.ToString()); // 2. preimage await tester.Repository.SetPreimage(paymentPreimage); var preimage2 = await tester.Repository.GetPreimage(paymentPreimage.Hash); Assert.Equal(paymentPreimage, preimage2); // 3. remote endpoint var ipEndpoint = IPEndPoint.Parse("192.168.0.1:9735"); var dnsEndPointA = NBitcoin.Utils.ParseEndpoint("lightningd-a:9735", 9735); var dnsEndPointB = NBitcoin.Utils.ParseEndpoint("lightningd-b:8888", 9735); await tester.Repository.SetRemoteEndPoint(ipEndpoint); await tester.Repository.SetRemoteEndPoint(dnsEndPointA); await tester.Repository.SetRemoteEndPoint(dnsEndPointB); var endpoints = await tester.Repository.GetAllRemoteEndPoint().ToListAsync(); Assert.Contains(ipEndpoint, endpoints); Assert.Contains(dnsEndPointA, endpoints); Assert.Contains(dnsEndPointB, endpoints); var(chanMan, readArgs, chanMon, monitorReadArgs) = GetTestChannelManager(); // 4. channel manager await tester.Repository.SetChannelManager(chanMan, CancellationToken.None); var items = await tester.Repository.GetChannelManager(readArgs); Assert.True(items.HasValue); var(_, chanMan2) = items.Value; Assert.True(chanMan.Serialize(_pool).SequenceEqual(chanMan2.Serialize(_pool))); // 5. channel monitor await tester.Repository.SetManyChannelMonitor(chanMon); var items2 = await tester.Repository.GetManyChannelMonitor(monitorReadArgs); Assert.True(items2.HasValue); var(chanMon2, _) = items2.Value; Assert.True(chanMon.Serialize(_pool).SequenceEqual(chanMon2.Serialize(_pool))); }