Skip to content

Instantly share code, notes, and snippets.

@nothingalike
Created February 18, 2021 19:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nothingalike/57dab80924ebfa50454a14cb8b0bebac to your computer and use it in GitHub Desktop.
Save nothingalike/57dab80924ebfa50454a14cb8b0bebac to your computer and use it in GitHub Desktop.

CardanoSharp EFCore Library

https://github.com/CardanoSharp/CardanoSharp.DbSync.EFCore

Postgres Function and Trigger

This is for getting new Metadata

CREATE OR REPLACE FUNCTION notify_tx_metadata_insert()
RETURNS trigger AS $$
BEGIN
  PERFORM pg_notify(
    'tx_metadata_insert',
    json_build_object(
      'operation', TG_OP,
      'record', row_to_json(NEW)
    )::text
  );

  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER tx_metadata_insert
AFTER INSERT
ON public.tx_metadata 
FOR EACH ROW
EXECUTE PROCEDURE notify_tx_metadata_insert()

.NET Code

When setting up a .NET Project, select Worker Service. Add the CardanoSharp.DbSync.EFCore project to your solution. Then add a reference to the CardanoSharp.DbSync.EFCore to your Worker Service.

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CardanoSharp.DbSync.EntityFramework;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace LIFT.Worker
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddDbContext<CardanoContext>(options =>
                            options.UseNpgsql(hostContext.Configuration.GetConnectionString("Cardano")));

                    services.AddHostedService<Worker>();
                });
    }
}

Worker.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CardanoSharp.DbSync.EntityFramework;
using CardanoSharp.DbSync.EFCore.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;

namespace LIFT.Worker
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        private readonly IConfiguration _configuration;
        private readonly IServiceScopeFactory _scopeFactory;

        public Worker(
            ILogger<Worker> logger,
            IConfiguration configuration, 
            IServiceScopeFactory scopeFactory)
        {
            _logger = logger;
            _configuration = configuration;
            _scopeFactory = scopeFactory;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                using (var conn = new NpgsqlConnection(_configuration.GetConnectionString("Cardano")))
                {

                    conn.Open();
                    conn.Notification += async (o, e) =>
                    {
                        using (var scope = _scopeFactory.CreateScope())
                        {
                            var cardanoContext = scope.ServiceProvider.GetRequiredService<CardanoContext>();
                            //Console.WriteLine("Received Notification");
                            var payload = JsonConvert.DeserializeObject<PostgresRecord>(e.Payload);
                            var txMetadatum = await cardanoContext
                                .TxMetadata
                                .Include(x => x.Tx)
                                .FirstOrDefaultAsync(x => x.Id == Convert.ToInt32(payload.Record["id"]));


                            _logger.LogInformation($"Metadata Key: {txMetadatum.Key}");
                            _logger.LogInformation($"Metadata Json: {txMetadatum.Json}");
                            _logger.LogInformation($"Tx Hash: {txMetadatum.Tx.Hash.GetHex()}");
                        };
                    };

                    using (var cmd = new NpgsqlCommand("LISTEN ma_tx_mint_insert", conn))
                    {
                        cmd.ExecuteNonQuery();
                    }

                    while (true)
                    {
                        conn.Wait();   // Thread will block here
                    }
                }
            }
        }
    }

    public class PostgresRecord
    {
        public string Operation { get; set; }
        public Dictionary<string, object> Record { get; set; }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment