diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 02b774ee..75d9045c 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -13,7 +13,7 @@ services: volumes: - nodeguard_postgres_data:/var/lib/postgresql/data ports: - - 25432:5432 + - 5432:5432 nbxplorer: restart: unless-stopped diff --git a/src/Automapper/MapperProfile.cs b/src/Automapper/MapperProfile.cs index a0b79e1d..4ab5e5ab 100644 --- a/src/Automapper/MapperProfile.cs +++ b/src/Automapper/MapperProfile.cs @@ -62,7 +62,7 @@ public MapperProfile() .ForMember(x => x.UserRequestor, opt => opt.Ignore()) .ForMember(x => x.UTXOs, opt => opt.Ignore()); - CreateMap() + CreateMap() .ForMember(x => x.TxId, opt => opt.MapFrom(x => x.Outpoint.Hash.ToString())) .ForMember(x => x.OutputIndex, opt => opt.MapFrom(x => x.Outpoint.N)) .ForMember(x => x.SatsAmount, opt => opt.MapFrom(x => ((Money)x.Value).Satoshi)); diff --git a/src/Data/ApplicationDbContext.cs b/src/Data/ApplicationDbContext.cs index f0ed1dd3..ba341aec 100644 --- a/src/Data/ApplicationDbContext.cs +++ b/src/Data/ApplicationDbContext.cs @@ -106,7 +106,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) public DbSet InternalWallets { get; set; } - public DbSet FMUTXOs { get; set; } + public DbSet UTXOs { get; set; } public DbSet LiquidityRules { get; set; } diff --git a/src/Data/Models/ChannelOperationRequest.cs b/src/Data/Models/ChannelOperationRequest.cs index 17e8e226..2269eed3 100644 --- a/src/Data/Models/ChannelOperationRequest.cs +++ b/src/Data/Models/ChannelOperationRequest.cs @@ -137,7 +137,7 @@ public decimal Amount public bool IsChannelPrivate { get; set; } - public List Utxos { get; set; } + public List Utxos { get; set; } #endregion Relationships diff --git a/src/Data/Models/FMUTXO.cs b/src/Data/Models/UTXO.cs similarity index 89% rename from src/Data/Models/FMUTXO.cs rename to src/Data/Models/UTXO.cs index 81a3942d..05fa1ad3 100644 --- a/src/Data/Models/FMUTXO.cs +++ b/src/Data/Models/UTXO.cs @@ -22,7 +22,7 @@ namespace NodeGuard.Data.Models /// /// UTXO entity in the NodeGuard /// - public class FMUTXO : Entity, IEquatable + public class UTXO : Entity, IEquatable { public string TxId { get; set; } @@ -48,7 +48,7 @@ public override bool Equals(object? obj) return base.Equals(obj); } - public bool Equals(FMUTXO? other) + public bool Equals(UTXO? other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; @@ -60,12 +60,12 @@ public override int GetHashCode() return HashCode.Combine(TxId, OutputIndex, SatsAmount); } - public static bool operator ==(FMUTXO? left, FMUTXO? right) + public static bool operator ==(UTXO? left, UTXO? right) { return Equals(left, right); } - public static bool operator !=(FMUTXO? left, FMUTXO? right) + public static bool operator !=(UTXO? left, UTXO? right) { return !Equals(left, right); } diff --git a/src/Data/Models/WalletWithdrawalRequest.cs b/src/Data/Models/WalletWithdrawalRequest.cs index 72ec8e84..c585c359 100644 --- a/src/Data/Models/WalletWithdrawalRequest.cs +++ b/src/Data/Models/WalletWithdrawalRequest.cs @@ -199,7 +199,7 @@ public bool Equals(WalletWithdrawalRequest? other) public List WalletWithdrawalRequestPSBTs { get; set; } - public List UTXOs { get; set; } + public List UTXOs { get; set; } #endregion Relationships diff --git a/src/Data/Repositories/ChannelOperationRequestRepository.cs b/src/Data/Repositories/ChannelOperationRequestRepository.cs index e6f7de72..c9dd821e 100644 --- a/src/Data/Repositories/ChannelOperationRequestRepository.cs +++ b/src/Data/Repositories/ChannelOperationRequestRepository.cs @@ -158,7 +158,7 @@ public async Task> GetUnsignedPendingRequestsByUse return _repository.Update(strippedType, applicationDbContext); } - public async Task<(bool, string?)> AddUTXOs(IBitcoinRequest type, List utxos) + public async Task<(bool, string?)> AddUTXOs(IBitcoinRequest type, List utxos) { if (type == null) throw new ArgumentNullException(nameof(type)); if (utxos.Count == 0) throw new ArgumentException("Value cannot be an empty collection.", nameof(utxos)); @@ -197,11 +197,11 @@ public async Task> GetUnsignedPendingRequestsByUse return result; } - public async Task<(bool, List?)> GetUTXOs(IBitcoinRequest request) + public async Task<(bool, List?)> GetUTXOs(IBitcoinRequest request) { await using var applicationDbContext = await _dbContextFactory.CreateDbContextAsync(); - (bool, List?) result = (true, null); + (bool, List?) result = (true, null); try { var channelOperationRequest = await applicationDbContext.ChannelOperationRequests diff --git a/src/Data/Repositories/Interfaces/IBitcoinRequestRepository.cs b/src/Data/Repositories/Interfaces/IBitcoinRequestRepository.cs index cc5bb588..bace9a47 100644 --- a/src/Data/Repositories/Interfaces/IBitcoinRequestRepository.cs +++ b/src/Data/Repositories/Interfaces/IBitcoinRequestRepository.cs @@ -29,7 +29,7 @@ public interface IBitcoinRequestRepository /// /// /// - Task<(bool, string?)> AddUTXOs(IBitcoinRequest type, List utxos); + Task<(bool, string?)> AddUTXOs(IBitcoinRequest type, List utxos); - public Task<(bool, List?)> GetUTXOs(IBitcoinRequest type); + public Task<(bool, List?)> GetUTXOs(IBitcoinRequest type); } \ No newline at end of file diff --git a/src/Data/Repositories/Interfaces/IFMUTXORepository.cs b/src/Data/Repositories/Interfaces/IUTXORepository.cs similarity index 68% rename from src/Data/Repositories/Interfaces/IFMUTXORepository.cs rename to src/Data/Repositories/Interfaces/IUTXORepository.cs index 2fca9d75..c57797aa 100644 --- a/src/Data/Repositories/Interfaces/IFMUTXORepository.cs +++ b/src/Data/Repositories/Interfaces/IUTXORepository.cs @@ -21,25 +21,25 @@ namespace NodeGuard.Data.Repositories.Interfaces; -public interface IFMUTXORepository +public interface IUTXORepository { - Task GetById(int id); + Task GetById(int id); - Task> GetAll(); + Task> GetAll(); - Task<(bool, string?)> AddAsync(FMUTXO type); + Task<(bool, string?)> AddAsync(UTXO type); - Task<(bool, string?)> AddRangeAsync(List type); + Task<(bool, string?)> AddRangeAsync(List type); - (bool, string?) Remove(FMUTXO type); + (bool, string?) Remove(UTXO type); - (bool, string?) RemoveRange(List types); + (bool, string?) RemoveRange(List types); - (bool, string?) Update(FMUTXO type); + (bool, string?) Update(UTXO type); /// /// Gets the current list of UTXOs locked on requests ChannelOperationRequest / WalletWithdrawalRequest by passing its id if wants to remove it from the resulting set /// /// - Task> GetLockedUTXOs(int? ignoredWalletWithdrawalRequestId = null, int? ignoredChannelOperationRequestId = null); + Task> GetLockedUTXOs(int? ignoredWalletWithdrawalRequestId = null, int? ignoredChannelOperationRequestId = null); } \ No newline at end of file diff --git a/src/Data/Repositories/FUTXORepository.cs b/src/Data/Repositories/UTXORepository.cs similarity index 83% rename from src/Data/Repositories/FUTXORepository.cs rename to src/Data/Repositories/UTXORepository.cs index 1dccd1b1..8cfd7939 100644 --- a/src/Data/Repositories/FUTXORepository.cs +++ b/src/Data/Repositories/UTXORepository.cs @@ -23,14 +23,14 @@ namespace NodeGuard.Data.Repositories { - public class FUTXORepository : IFMUTXORepository + public class UTXORepository : IUTXORepository { - private readonly IRepository _repository; - private readonly ILogger _logger; + private readonly IRepository _repository; + private readonly ILogger _logger; private readonly IDbContextFactory _dbContextFactory; - public FUTXORepository(IRepository repository, - ILogger logger, + public UTXORepository(IRepository repository, + ILogger logger, IDbContextFactory dbContextFactory) { _repository = repository; @@ -38,19 +38,19 @@ public FUTXORepository(IRepository repository, _dbContextFactory = dbContextFactory; } - public async Task GetById(int id) + public async Task GetById(int id) { await using var applicationDbContext = await _dbContextFactory.CreateDbContextAsync(); - return await applicationDbContext.FMUTXOs.FirstOrDefaultAsync(x => x.Id == id); + return await applicationDbContext.UTXOs.FirstOrDefaultAsync(x => x.Id == id); } - public async Task> GetAll() + public async Task> GetAll() { throw new NotImplementedException(); } - public async Task<(bool, string?)> AddAsync(FMUTXO type) + public async Task<(bool, string?)> AddAsync(UTXO type) { await using var applicationDbContext = await _dbContextFactory.CreateDbContextAsync(); @@ -59,28 +59,28 @@ public async Task> GetAll() return await _repository.AddAsync(type, applicationDbContext); } - public async Task<(bool, string?)> AddRangeAsync(List type) + public async Task<(bool, string?)> AddRangeAsync(List type) { await using var applicationDbContext = await _dbContextFactory.CreateDbContextAsync(); return await _repository.AddRangeAsync(type, applicationDbContext); } - public (bool, string?) Remove(FMUTXO type) + public (bool, string?) Remove(UTXO type) { using var applicationDbContext = _dbContextFactory.CreateDbContext(); return _repository.Remove(type, applicationDbContext); } - public (bool, string?) RemoveRange(List types) + public (bool, string?) RemoveRange(List types) { using var applicationDbContext = _dbContextFactory.CreateDbContext(); return _repository.RemoveRange(types, applicationDbContext); } - public (bool, string?) Update(FMUTXO type) + public (bool, string?) Update(UTXO type) { using var applicationDbContext = _dbContextFactory.CreateDbContext(); @@ -89,11 +89,11 @@ public async Task> GetAll() return _repository.Update(type, applicationDbContext); } - public async Task> GetLockedUTXOs(int? ignoredWalletWithdrawalRequestId = null, int? ignoredChannelOperationRequestId = null) + public async Task> GetLockedUTXOs(int? ignoredWalletWithdrawalRequestId = null, int? ignoredChannelOperationRequestId = null) { await using var applicationDbContext = await _dbContextFactory.CreateDbContextAsync(); - var walletWithdrawalRequestsLockedUTXOs = new List(); + var walletWithdrawalRequestsLockedUTXOs = new List(); if (ignoredWalletWithdrawalRequestId == null) { walletWithdrawalRequestsLockedUTXOs = await applicationDbContext.WalletWithdrawalRequests @@ -116,7 +116,7 @@ public async Task> GetLockedUTXOs(int? ignoredWalletWithdrawalReque .SelectMany(x => x.UTXOs).ToListAsync(); } - var channelOperationRequestsLockedUTXOs = new List(); + var channelOperationRequestsLockedUTXOs = new List(); if (ignoredChannelOperationRequestId == null) { diff --git a/src/Data/Repositories/WalletWithdrawalRequestRepository.cs b/src/Data/Repositories/WalletWithdrawalRequestRepository.cs index 958b6ec7..8a59ac94 100644 --- a/src/Data/Repositories/WalletWithdrawalRequestRepository.cs +++ b/src/Data/Repositories/WalletWithdrawalRequestRepository.cs @@ -194,7 +194,7 @@ public async Task> GetAllUnsignedPendingRequests() return _repository.Update(strippedType, applicationDbContext); } - public async Task<(bool, string?)> AddUTXOs(IBitcoinRequest type, List utxos) + public async Task<(bool, string?)> AddUTXOs(IBitcoinRequest type, List utxos) { if (type == null) throw new ArgumentNullException(nameof(type)); if (utxos.Count == 0) throw new ArgumentException("Value cannot be an empty collection.", nameof(utxos)); @@ -233,11 +233,11 @@ public async Task> GetAllUnsignedPendingRequests() return result; } - public async Task<(bool, List?)> GetUTXOs(IBitcoinRequest request) + public async Task<(bool, List?)> GetUTXOs(IBitcoinRequest request) { await using var applicationDbContext = await _dbContextFactory.CreateDbContextAsync(); - (bool, List?) result = (true, null); + (bool, List?) result = (true, null); try { var walletWithdrawalRequest = await applicationDbContext.WalletWithdrawalRequests diff --git a/src/Helpers/LightningHelper.cs b/src/Helpers/LightningHelper.cs index 9ff27374..6c07433d 100644 --- a/src/Helpers/LightningHelper.cs +++ b/src/Helpers/LightningHelper.cs @@ -23,6 +23,7 @@ using NBitcoin; using NBXplorer; using NBXplorer.Models; +using UTXO = NBXplorer.Models.UTXO; namespace NodeGuard.Helpers { diff --git a/src/Migrations/20240619150443_RemoveFMReferences.Designer.cs b/src/Migrations/20240619150443_RemoveFMReferences.Designer.cs new file mode 100644 index 00000000..1edde025 --- /dev/null +++ b/src/Migrations/20240619150443_RemoveFMReferences.Designer.cs @@ -0,0 +1,1261 @@ +// +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using NodeGuard.Data; +using NodeGuard.Helpers; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace NodeGuard.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20240619150443_RemoveFMReferences")] + partial class RemoveFMReferences + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("ApplicationUserNode", b => + { + b.Property("NodesId") + .HasColumnType("integer"); + + b.Property("UsersId") + .HasColumnType("text"); + + b.HasKey("NodesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("ApplicationUserNode"); + }); + + modelBuilder.Entity("ChannelOperationRequestUTXO", b => + { + b.Property("ChannelOperationRequestsId") + .HasColumnType("integer"); + + b.Property("UtxosId") + .HasColumnType("integer"); + + b.HasKey("ChannelOperationRequestsId", "UtxosId"); + + b.HasIndex("UtxosId"); + + b.ToTable("ChannelOperationRequestUTXO"); + }); + + modelBuilder.Entity("KeyWallet", b => + { + b.Property("KeysId") + .HasColumnType("integer"); + + b.Property("WalletsId") + .HasColumnType("integer"); + + b.HasKey("KeysId", "WalletsId"); + + b.HasIndex("WalletsId"); + + b.ToTable("KeyWallet"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(21) + .HasColumnType("character varying(21)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("PhoneNumber") + .HasColumnType("text"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + + b.HasDiscriminator("Discriminator").HasValue("IdentityUser"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("text"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.APIToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreationDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorId") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExpirationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("IsBlocked") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("TokenHash") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdateDatetime") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.ToTable("ApiTokens"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.Channel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BtcCloseAddress") + .HasColumnType("text"); + + b.Property("ChanId") + .HasColumnType("numeric(20,0)"); + + b.Property("CreatedByNodeGuard") + .HasColumnType("boolean"); + + b.Property("CreationDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("DestinationNodeId") + .HasColumnType("integer"); + + b.Property("FundingTx") + .IsRequired() + .HasColumnType("text"); + + b.Property("FundingTxOutputIndex") + .HasColumnType("bigint"); + + b.Property("IsAutomatedLiquidityEnabled") + .HasColumnType("boolean"); + + b.Property("IsPrivate") + .HasColumnType("boolean"); + + b.Property("SatsAmount") + .HasColumnType("bigint"); + + b.Property("SourceNodeId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("UpdateDatetime") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("DestinationNodeId"); + + b.HasIndex("SourceNodeId"); + + b.ToTable("Channels"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.ChannelOperationRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AmountCryptoUnit") + .HasColumnType("integer"); + + b.Property("Changeless") + .HasColumnType("boolean"); + + b.Property("ChannelId") + .HasColumnType("integer"); + + b.Property("ClosingReason") + .HasColumnType("text"); + + b.Property("CreationDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("DestNodeId") + .HasColumnType("integer"); + + b.Property("FeeRate") + .HasColumnType("numeric"); + + b.Property("IsChannelPrivate") + .HasColumnType("boolean"); + + b.Property("MempoolRecommendedFeesType") + .HasColumnType("integer"); + + b.Property("RequestType") + .HasColumnType("integer"); + + b.Property("SatsAmount") + .HasColumnType("bigint"); + + b.Property("SourceNodeId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property>("StatusLogs") + .HasColumnType("jsonb"); + + b.Property("TxId") + .HasColumnType("text"); + + b.Property("UpdateDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("text"); + + b.Property("WalletId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("DestNodeId"); + + b.HasIndex("SourceNodeId"); + + b.HasIndex("UserId"); + + b.HasIndex("WalletId"); + + b.ToTable("ChannelOperationRequests"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.ChannelOperationRequestPSBT", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ChannelOperationRequestId") + .HasColumnType("integer"); + + b.Property("CreationDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("IsFinalisedPSBT") + .HasColumnType("boolean"); + + b.Property("IsInternalWalletPSBT") + .HasColumnType("boolean"); + + b.Property("IsTemplatePSBT") + .HasColumnType("boolean"); + + b.Property("PSBT") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdateDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserSignerId") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ChannelOperationRequestId"); + + b.HasIndex("UserSignerId"); + + b.ToTable("ChannelOperationRequestPSBTs"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.InternalWallet", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreationDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("DerivationPath") + .IsRequired() + .HasColumnType("text"); + + b.Property("MasterFingerprint") + .HasColumnType("text"); + + b.Property("MnemonicString") + .HasColumnType("text"); + + b.Property("UpdateDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("XPUB") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("InternalWallets"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.Key", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreationDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("InternalWalletId") + .HasColumnType("integer"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsBIP39ImportedKey") + .HasColumnType("boolean"); + + b.Property("IsCompromised") + .HasColumnType("boolean"); + + b.Property("MasterFingerprint") + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Path") + .HasColumnType("text"); + + b.Property("UpdateDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("text"); + + b.Property("XPUB") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("InternalWalletId"); + + b.HasIndex("UserId"); + + b.ToTable("Keys"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.LiquidityRule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ChannelId") + .HasColumnType("integer"); + + b.Property("CreationDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("IsReverseSwapWalletRule") + .HasColumnType("boolean"); + + b.Property("MinimumLocalBalance") + .HasColumnType("numeric"); + + b.Property("MinimumRemoteBalance") + .HasColumnType("numeric"); + + b.Property("NodeId") + .HasColumnType("integer"); + + b.Property("RebalanceTarget") + .HasColumnType("numeric"); + + b.Property("ReverseSwapAddress") + .HasColumnType("text"); + + b.Property("ReverseSwapWalletId") + .HasColumnType("integer"); + + b.Property("SwapWalletId") + .HasColumnType("integer"); + + b.Property("UpdateDatetime") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId") + .IsUnique(); + + b.HasIndex("NodeId"); + + b.HasIndex("ReverseSwapWalletId"); + + b.HasIndex("SwapWalletId"); + + b.ToTable("LiquidityRules"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.Node", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AutosweepEnabled") + .HasColumnType("boolean"); + + b.Property("ChannelAdminMacaroon") + .HasColumnType("text"); + + b.Property("CreationDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("Endpoint") + .HasColumnType("text"); + + b.Property("IsNodeDisabled") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("PubKey") + .IsRequired() + .HasColumnType("text"); + + b.Property("ReturningFundsWalletId") + .HasColumnType("integer"); + + b.Property("UpdateDatetime") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("PubKey") + .IsUnique(); + + b.HasIndex("ReturningFundsWalletId"); + + b.ToTable("Nodes"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.UTXO", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreationDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("OutputIndex") + .HasColumnType("bigint"); + + b.Property("SatsAmount") + .HasColumnType("bigint"); + + b.Property("TxId") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdateDatetime") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("UTXOs"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.Wallet", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BIP39Seedphrase") + .HasColumnType("text"); + + b.Property("CreationDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("ImportedOutputDescriptor") + .HasColumnType("text"); + + b.Property("InternalWalletId") + .HasColumnType("integer"); + + b.Property("InternalWalletMasterFingerprint") + .HasColumnType("text"); + + b.Property("InternalWalletSubDerivationPath") + .HasColumnType("text"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsBIP39Imported") + .HasColumnType("boolean"); + + b.Property("IsCompromised") + .HasColumnType("boolean"); + + b.Property("IsFinalised") + .HasColumnType("boolean"); + + b.Property("IsHotWallet") + .HasColumnType("boolean"); + + b.Property("IsUnSortedMultiSig") + .HasColumnType("boolean"); + + b.Property("MofN") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("ReferenceId") + .HasColumnType("text"); + + b.Property("UpdateDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("WalletAddressType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("InternalWalletId"); + + b.HasIndex("InternalWalletSubDerivationPath", "InternalWalletMasterFingerprint") + .IsUnique(); + + b.ToTable("Wallets"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.WalletWithdrawalRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Amount") + .HasColumnType("numeric"); + + b.Property("Changeless") + .HasColumnType("boolean"); + + b.Property("CreationDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("CustomFeeRate") + .HasColumnType("numeric"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("DestinationAddress") + .IsRequired() + .HasColumnType("text"); + + b.Property("MempoolRecommendedFeesType") + .HasColumnType("integer"); + + b.Property("RejectCancelDescription") + .HasColumnType("text"); + + b.Property("RequestMetadata") + .HasColumnType("text"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TxId") + .HasColumnType("text"); + + b.Property("UpdateDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserRequestorId") + .HasColumnType("text"); + + b.Property("WalletId") + .HasColumnType("integer"); + + b.Property("WithdrawAllFunds") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("UserRequestorId"); + + b.HasIndex("WalletId"); + + b.ToTable("WalletWithdrawalRequests"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.WalletWithdrawalRequestPSBT", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreationDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("IsFinalisedPSBT") + .HasColumnType("boolean"); + + b.Property("IsInternalWalletPSBT") + .HasColumnType("boolean"); + + b.Property("IsTemplatePSBT") + .HasColumnType("boolean"); + + b.Property("PSBT") + .IsRequired() + .HasColumnType("text"); + + b.Property("SignerId") + .HasColumnType("text"); + + b.Property("UpdateDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("WalletWithdrawalRequestId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("SignerId"); + + b.HasIndex("WalletWithdrawalRequestId"); + + b.ToTable("WalletWithdrawalRequestPSBTs"); + }); + + modelBuilder.Entity("UTXOWalletWithdrawalRequest", b => + { + b.Property("UTXOsId") + .HasColumnType("integer"); + + b.Property("WalletWithdrawalRequestsId") + .HasColumnType("integer"); + + b.HasKey("UTXOsId", "WalletWithdrawalRequestsId"); + + b.HasIndex("WalletWithdrawalRequestsId"); + + b.ToTable("UTXOWalletWithdrawalRequest"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.ApplicationUser", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.HasDiscriminator().HasValue("ApplicationUser"); + }); + + modelBuilder.Entity("ApplicationUserNode", b => + { + b.HasOne("NodeGuard.Data.Models.Node", null) + .WithMany() + .HasForeignKey("NodesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("NodeGuard.Data.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ChannelOperationRequestUTXO", b => + { + b.HasOne("NodeGuard.Data.Models.ChannelOperationRequest", null) + .WithMany() + .HasForeignKey("ChannelOperationRequestsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("NodeGuard.Data.Models.UTXO", null) + .WithMany() + .HasForeignKey("UtxosId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("KeyWallet", b => + { + b.HasOne("NodeGuard.Data.Models.Key", null) + .WithMany() + .HasForeignKey("KeysId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("NodeGuard.Data.Models.Wallet", null) + .WithMany() + .HasForeignKey("WalletsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.APIToken", b => + { + b.HasOne("NodeGuard.Data.Models.ApplicationUser", "Creator") + .WithMany() + .HasForeignKey("CreatorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Creator"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.Channel", b => + { + b.HasOne("NodeGuard.Data.Models.Node", "DestinationNode") + .WithMany() + .HasForeignKey("DestinationNodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("NodeGuard.Data.Models.Node", "SourceNode") + .WithMany() + .HasForeignKey("SourceNodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DestinationNode"); + + b.Navigation("SourceNode"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.ChannelOperationRequest", b => + { + b.HasOne("NodeGuard.Data.Models.Channel", "Channel") + .WithMany("ChannelOperationRequests") + .HasForeignKey("ChannelId"); + + b.HasOne("NodeGuard.Data.Models.Node", "DestNode") + .WithMany("ChannelOperationRequestsAsDestination") + .HasForeignKey("DestNodeId"); + + b.HasOne("NodeGuard.Data.Models.Node", "SourceNode") + .WithMany("ChannelOperationRequestsAsSource") + .HasForeignKey("SourceNodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("NodeGuard.Data.Models.ApplicationUser", "User") + .WithMany("ChannelOperationRequests") + .HasForeignKey("UserId"); + + b.HasOne("NodeGuard.Data.Models.Wallet", "Wallet") + .WithMany("ChannelOperationRequestsAsSource") + .HasForeignKey("WalletId"); + + b.Navigation("Channel"); + + b.Navigation("DestNode"); + + b.Navigation("SourceNode"); + + b.Navigation("User"); + + b.Navigation("Wallet"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.ChannelOperationRequestPSBT", b => + { + b.HasOne("NodeGuard.Data.Models.ChannelOperationRequest", "ChannelOperationRequest") + .WithMany("ChannelOperationRequestPsbts") + .HasForeignKey("ChannelOperationRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("NodeGuard.Data.Models.ApplicationUser", "UserSigner") + .WithMany() + .HasForeignKey("UserSignerId"); + + b.Navigation("ChannelOperationRequest"); + + b.Navigation("UserSigner"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.Key", b => + { + b.HasOne("NodeGuard.Data.Models.InternalWallet", "InternalWallet") + .WithMany() + .HasForeignKey("InternalWalletId"); + + b.HasOne("NodeGuard.Data.Models.ApplicationUser", "User") + .WithMany("Keys") + .HasForeignKey("UserId"); + + b.Navigation("InternalWallet"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.LiquidityRule", b => + { + b.HasOne("NodeGuard.Data.Models.Channel", "Channel") + .WithMany("LiquidityRules") + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("NodeGuard.Data.Models.Node", "Node") + .WithMany() + .HasForeignKey("NodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("NodeGuard.Data.Models.Wallet", "ReverseSwapWallet") + .WithMany("LiquidityRulesAsReverseSwapWallet") + .HasForeignKey("ReverseSwapWalletId"); + + b.HasOne("NodeGuard.Data.Models.Wallet", "SwapWallet") + .WithMany("LiquidityRulesAsSwapWallet") + .HasForeignKey("SwapWalletId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Channel"); + + b.Navigation("Node"); + + b.Navigation("ReverseSwapWallet"); + + b.Navigation("SwapWallet"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.Node", b => + { + b.HasOne("NodeGuard.Data.Models.Wallet", "ReturningFundsWallet") + .WithMany() + .HasForeignKey("ReturningFundsWalletId"); + + b.Navigation("ReturningFundsWallet"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.Wallet", b => + { + b.HasOne("NodeGuard.Data.Models.InternalWallet", "InternalWallet") + .WithMany() + .HasForeignKey("InternalWalletId"); + + b.Navigation("InternalWallet"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.WalletWithdrawalRequest", b => + { + b.HasOne("NodeGuard.Data.Models.ApplicationUser", "UserRequestor") + .WithMany("WalletWithdrawalRequests") + .HasForeignKey("UserRequestorId"); + + b.HasOne("NodeGuard.Data.Models.Wallet", "Wallet") + .WithMany() + .HasForeignKey("WalletId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("UserRequestor"); + + b.Navigation("Wallet"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.WalletWithdrawalRequestPSBT", b => + { + b.HasOne("NodeGuard.Data.Models.ApplicationUser", "Signer") + .WithMany() + .HasForeignKey("SignerId"); + + b.HasOne("NodeGuard.Data.Models.WalletWithdrawalRequest", "WalletWithdrawalRequest") + .WithMany("WalletWithdrawalRequestPSBTs") + .HasForeignKey("WalletWithdrawalRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Signer"); + + b.Navigation("WalletWithdrawalRequest"); + }); + + modelBuilder.Entity("UTXOWalletWithdrawalRequest", b => + { + b.HasOne("NodeGuard.Data.Models.UTXO", null) + .WithMany() + .HasForeignKey("UTXOsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("NodeGuard.Data.Models.WalletWithdrawalRequest", null) + .WithMany() + .HasForeignKey("WalletWithdrawalRequestsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.Channel", b => + { + b.Navigation("ChannelOperationRequests"); + + b.Navigation("LiquidityRules"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.ChannelOperationRequest", b => + { + b.Navigation("ChannelOperationRequestPsbts"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.Node", b => + { + b.Navigation("ChannelOperationRequestsAsDestination"); + + b.Navigation("ChannelOperationRequestsAsSource"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.Wallet", b => + { + b.Navigation("ChannelOperationRequestsAsSource"); + + b.Navigation("LiquidityRulesAsReverseSwapWallet"); + + b.Navigation("LiquidityRulesAsSwapWallet"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.WalletWithdrawalRequest", b => + { + b.Navigation("WalletWithdrawalRequestPSBTs"); + }); + + modelBuilder.Entity("NodeGuard.Data.Models.ApplicationUser", b => + { + b.Navigation("ChannelOperationRequests"); + + b.Navigation("Keys"); + + b.Navigation("WalletWithdrawalRequests"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Migrations/20240619150443_RemoveFMReferences.cs b/src/Migrations/20240619150443_RemoveFMReferences.cs new file mode 100644 index 00000000..e51e35b7 --- /dev/null +++ b/src/Migrations/20240619150443_RemoveFMReferences.cs @@ -0,0 +1,188 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace NodeGuard.Migrations +{ + /// + public partial class RemoveFMReferences : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ChannelOperationRequestFMUTXO"); + + migrationBuilder.DropTable( + name: "FMUTXOWalletWithdrawalRequest"); + + migrationBuilder.DropTable( + name: "FMUTXOs"); + + migrationBuilder.CreateTable( + name: "UTXOs", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + TxId = table.Column(type: "text", nullable: false), + OutputIndex = table.Column(type: "bigint", nullable: false), + SatsAmount = table.Column(type: "bigint", nullable: false), + CreationDatetime = table.Column(type: "timestamp with time zone", nullable: false), + UpdateDatetime = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UTXOs", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ChannelOperationRequestUTXO", + columns: table => new + { + ChannelOperationRequestsId = table.Column(type: "integer", nullable: false), + UtxosId = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ChannelOperationRequestUTXO", x => new { x.ChannelOperationRequestsId, x.UtxosId }); + table.ForeignKey( + name: "FK_ChannelOperationRequestUTXO_ChannelOperationRequests_Channe~", + column: x => x.ChannelOperationRequestsId, + principalTable: "ChannelOperationRequests", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ChannelOperationRequestUTXO_UTXOs_UtxosId", + column: x => x.UtxosId, + principalTable: "UTXOs", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UTXOWalletWithdrawalRequest", + columns: table => new + { + UTXOsId = table.Column(type: "integer", nullable: false), + WalletWithdrawalRequestsId = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UTXOWalletWithdrawalRequest", x => new { x.UTXOsId, x.WalletWithdrawalRequestsId }); + table.ForeignKey( + name: "FK_UTXOWalletWithdrawalRequest_UTXOs_UTXOsId", + column: x => x.UTXOsId, + principalTable: "UTXOs", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_UTXOWalletWithdrawalRequest_WalletWithdrawalRequests_Wallet~", + column: x => x.WalletWithdrawalRequestsId, + principalTable: "WalletWithdrawalRequests", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ChannelOperationRequestUTXO_UtxosId", + table: "ChannelOperationRequestUTXO", + column: "UtxosId"); + + migrationBuilder.CreateIndex( + name: "IX_UTXOWalletWithdrawalRequest_WalletWithdrawalRequestsId", + table: "UTXOWalletWithdrawalRequest", + column: "WalletWithdrawalRequestsId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ChannelOperationRequestUTXO"); + + migrationBuilder.DropTable( + name: "UTXOWalletWithdrawalRequest"); + + migrationBuilder.DropTable( + name: "UTXOs"); + + migrationBuilder.CreateTable( + name: "FMUTXOs", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + CreationDatetime = table.Column(type: "timestamp with time zone", nullable: false), + OutputIndex = table.Column(type: "bigint", nullable: false), + SatsAmount = table.Column(type: "bigint", nullable: false), + TxId = table.Column(type: "text", nullable: false), + UpdateDatetime = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_FMUTXOs", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ChannelOperationRequestFMUTXO", + columns: table => new + { + ChannelOperationRequestsId = table.Column(type: "integer", nullable: false), + UtxosId = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ChannelOperationRequestFMUTXO", x => new { x.ChannelOperationRequestsId, x.UtxosId }); + table.ForeignKey( + name: "FK_ChannelOperationRequestFMUTXO_ChannelOperationRequests_Chan~", + column: x => x.ChannelOperationRequestsId, + principalTable: "ChannelOperationRequests", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ChannelOperationRequestFMUTXO_FMUTXOs_UtxosId", + column: x => x.UtxosId, + principalTable: "FMUTXOs", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "FMUTXOWalletWithdrawalRequest", + columns: table => new + { + UTXOsId = table.Column(type: "integer", nullable: false), + WalletWithdrawalRequestsId = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_FMUTXOWalletWithdrawalRequest", x => new { x.UTXOsId, x.WalletWithdrawalRequestsId }); + table.ForeignKey( + name: "FK_FMUTXOWalletWithdrawalRequest_FMUTXOs_UTXOsId", + column: x => x.UTXOsId, + principalTable: "FMUTXOs", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_FMUTXOWalletWithdrawalRequest_WalletWithdrawalRequests_Wall~", + column: x => x.WalletWithdrawalRequestsId, + principalTable: "WalletWithdrawalRequests", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ChannelOperationRequestFMUTXO_UtxosId", + table: "ChannelOperationRequestFMUTXO", + column: "UtxosId"); + + migrationBuilder.CreateIndex( + name: "IX_FMUTXOWalletWithdrawalRequest_WalletWithdrawalRequestsId", + table: "FMUTXOWalletWithdrawalRequest", + column: "WalletWithdrawalRequestsId"); + } + } +} diff --git a/src/Migrations/ApplicationDbContextModelSnapshot.cs b/src/Migrations/ApplicationDbContextModelSnapshot.cs index d36ea2e0..f9f4f8fa 100644 --- a/src/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/src/Migrations/ApplicationDbContextModelSnapshot.cs @@ -39,7 +39,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("ApplicationUserNode"); }); - modelBuilder.Entity("ChannelOperationRequestFMUTXO", b => + modelBuilder.Entity("ChannelOperationRequestUTXO", b => { b.Property("ChannelOperationRequestsId") .HasColumnType("integer"); @@ -51,22 +51,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("UtxosId"); - b.ToTable("ChannelOperationRequestFMUTXO"); - }); - - modelBuilder.Entity("FMUTXOWalletWithdrawalRequest", b => - { - b.Property("UTXOsId") - .HasColumnType("integer"); - - b.Property("WalletWithdrawalRequestsId") - .HasColumnType("integer"); - - b.HasKey("UTXOsId", "WalletWithdrawalRequestsId"); - - b.HasIndex("WalletWithdrawalRequestsId"); - - b.ToTable("FMUTXOWalletWithdrawalRequest"); + b.ToTable("ChannelOperationRequestUTXO"); }); modelBuilder.Entity("KeyWallet", b => @@ -511,35 +496,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("ChannelOperationRequestPSBTs"); }); - modelBuilder.Entity("NodeGuard.Data.Models.FMUTXO", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("CreationDatetime") - .HasColumnType("timestamp with time zone"); - - b.Property("OutputIndex") - .HasColumnType("bigint"); - - b.Property("SatsAmount") - .HasColumnType("bigint"); - - b.Property("TxId") - .IsRequired() - .HasColumnType("text"); - - b.Property("UpdateDatetime") - .HasColumnType("timestamp with time zone"); - - b.HasKey("Id"); - - b.ToTable("FMUTXOs"); - }); - modelBuilder.Entity("NodeGuard.Data.Models.InternalWallet", b => { b.Property("Id") @@ -732,6 +688,35 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Nodes"); }); + modelBuilder.Entity("NodeGuard.Data.Models.UTXO", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreationDatetime") + .HasColumnType("timestamp with time zone"); + + b.Property("OutputIndex") + .HasColumnType("bigint"); + + b.Property("SatsAmount") + .HasColumnType("bigint"); + + b.Property("TxId") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdateDatetime") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("UTXOs"); + }); + modelBuilder.Entity("NodeGuard.Data.Models.Wallet", b => { b.Property("Id") @@ -911,6 +896,21 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("WalletWithdrawalRequestPSBTs"); }); + modelBuilder.Entity("UTXOWalletWithdrawalRequest", b => + { + b.Property("UTXOsId") + .HasColumnType("integer"); + + b.Property("WalletWithdrawalRequestsId") + .HasColumnType("integer"); + + b.HasKey("UTXOsId", "WalletWithdrawalRequestsId"); + + b.HasIndex("WalletWithdrawalRequestsId"); + + b.ToTable("UTXOWalletWithdrawalRequest"); + }); + modelBuilder.Entity("NodeGuard.Data.Models.ApplicationUser", b => { b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); @@ -933,7 +933,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired(); }); - modelBuilder.Entity("ChannelOperationRequestFMUTXO", b => + modelBuilder.Entity("ChannelOperationRequestUTXO", b => { b.HasOne("NodeGuard.Data.Models.ChannelOperationRequest", null) .WithMany() @@ -941,28 +941,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("NodeGuard.Data.Models.FMUTXO", null) + b.HasOne("NodeGuard.Data.Models.UTXO", null) .WithMany() .HasForeignKey("UtxosId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); - modelBuilder.Entity("FMUTXOWalletWithdrawalRequest", b => - { - b.HasOne("NodeGuard.Data.Models.FMUTXO", null) - .WithMany() - .HasForeignKey("UTXOsId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("NodeGuard.Data.Models.WalletWithdrawalRequest", null) - .WithMany() - .HasForeignKey("WalletWithdrawalRequestsId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - modelBuilder.Entity("KeyWallet", b => { b.HasOne("NodeGuard.Data.Models.Key", null) @@ -1211,6 +1196,21 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("WalletWithdrawalRequest"); }); + modelBuilder.Entity("UTXOWalletWithdrawalRequest", b => + { + b.HasOne("NodeGuard.Data.Models.UTXO", null) + .WithMany() + .HasForeignKey("UTXOsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("NodeGuard.Data.Models.WalletWithdrawalRequest", null) + .WithMany() + .HasForeignKey("WalletWithdrawalRequestsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + modelBuilder.Entity("NodeGuard.Data.Models.Channel", b => { b.Navigation("ChannelOperationRequests"); diff --git a/src/Pages/ChannelRequests.razor b/src/Pages/ChannelRequests.razor index 23be98ff..f6259d70 100644 --- a/src/Pages/ChannelRequests.razor +++ b/src/Pages/ChannelRequests.razor @@ -8,6 +8,7 @@ @using Google.Protobuf @using NBXplorer.Models @using NodeGuard.Helpers; +@using UTXO = NBXplorer.Models.UTXO @attribute [Authorize(Roles = "FinanceManager, Superadmin, NodeManager")] Channel Operation Requests diff --git a/src/Pages/Withdrawals.razor b/src/Pages/Withdrawals.razor index a3275bbf..a7928ea9 100644 --- a/src/Pages/Withdrawals.razor +++ b/src/Pages/Withdrawals.razor @@ -10,6 +10,7 @@ @using Newtonsoft.Json @using NodeGuard.Helpers; @using Polly +@using UTXO = NBXplorer.Models.UTXO @attribute [Authorize(Roles = "Superadmin,NodeManager,FinanceManager")] diff --git a/src/Program.cs b/src/Program.cs index 79479bdc..48d12a6f 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -105,7 +105,7 @@ public static void Main(string[] args) builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); - builder.Services.AddTransient(); + builder.Services.AddTransient(); builder.Services .AddTransient(); builder.Services.AddTransient(); diff --git a/src/Rpc/NodeGuardService.cs b/src/Rpc/NodeGuardService.cs index 1b092d75..d83c459b 100644 --- a/src/Rpc/NodeGuardService.cs +++ b/src/Rpc/NodeGuardService.cs @@ -16,6 +16,7 @@ using Quartz; using LiquidityRule = NodeGuard.Data.Models.LiquidityRule; using Node = Nodeguard.Node; +using UTXO = NBXplorer.Models.UTXO; using Wallet = NodeGuard.Data.Models.Wallet; namespace NodeGuard.Rpc; @@ -71,7 +72,7 @@ public class NodeGuardService : Nodeguard.NodeGuardService.NodeGuardServiceBase, private readonly ICoinSelectionService _coinSelectionService; private readonly IScheduler _scheduler; private readonly ILightningService _lightningService; - private readonly IFMUTXORepository _fmutxoRepository; + private readonly IUTXORepository _utxoRepository; public NodeGuardService(ILogger logger, ILiquidityRuleRepository liquidityRuleRepository, @@ -86,7 +87,7 @@ public NodeGuardService(ILogger logger, IChannelRepository channelRepository, ICoinSelectionService coinSelectionService, ILightningService lightningService, - IFMUTXORepository fmutxoRepository + IUTXORepository utxoRepository ) { _logger = logger; @@ -102,7 +103,7 @@ IFMUTXORepository fmutxoRepository _channelRepository = channelRepository; _coinSelectionService = coinSelectionService; _lightningService = lightningService; - _fmutxoRepository = fmutxoRepository; + _utxoRepository = utxoRepository; _scheduler = Task.Run(() => _schedulerFactory.GetScheduler()).Result; } @@ -891,7 +892,7 @@ public override async Task GetAvailableUtxos(GetAvail throw new Exception("Derivation strategy not found for wallet with id {walletId}"); } - var lockedUtxos = await _fmutxoRepository.GetLockedUTXOs(); + var lockedUtxos = await _utxoRepository.GetLockedUTXOs(); var utxos = await _nbXplorerService.GetUTXOsByLimitAsync( derivationStrategy, coinSelectionStrategy, diff --git a/src/Services/BitcoinService.cs b/src/Services/BitcoinService.cs index 8b62d6fb..d1ebea93 100644 --- a/src/Services/BitcoinService.cs +++ b/src/Services/BitcoinService.cs @@ -27,6 +27,7 @@ using NBXplorer.DerivationStrategy; using NBXplorer.Models; using NSubstitute.Exceptions; +using UTXO = NodeGuard.Data.Models.UTXO; // ReSharper disable All @@ -256,7 +257,7 @@ await _coinSelectionService.GetTxInputCoins(availableUTXOs, walletWithdrawalRequ } // We "lock" the PSBT to the channel operation request by adding to its UTXOs collection for later checking - var utxos = selectedUTXOs.Select(x => _mapper.Map(x)).ToList(); + var utxos = selectedUTXOs.Select(x => _mapper.Map(x)).ToList(); var addUTXOSOperation = await _walletWithdrawalRequestRepository.AddUTXOs(walletWithdrawalRequest, utxos); if (!addUTXOSOperation.Item1) diff --git a/src/Services/CoinSelectionService.cs b/src/Services/CoinSelectionService.cs index 1a4af232..02eb9c06 100644 --- a/src/Services/CoinSelectionService.cs +++ b/src/Services/CoinSelectionService.cs @@ -25,6 +25,7 @@ using NBitcoin; using NBXplorer.DerivationStrategy; using NBXplorer.Models; +using UTXO = NodeGuard.Data.Models.UTXO; namespace NodeGuard.Services; @@ -34,7 +35,7 @@ public interface ICoinSelectionService /// Gets the UTXOs for a wallet that are not locked in other transactions /// /// - public Task> GetAvailableUTXOsAsync(DerivationStrategyBase derivationStrategy); + public Task> GetAvailableUTXOsAsync(DerivationStrategyBase derivationStrategy); /// /// Gets the UTXOs for a wallet that are not locked in other transactions, but with a limit @@ -45,31 +46,31 @@ public interface ICoinSelectionService /// /// /// - public Task> GetAvailableUTXOsAsync(DerivationStrategyBase derivationStrategy, CoinSelectionStrategy strategy, int limit, long amount, long closestTo); + public Task> GetAvailableUTXOsAsync(DerivationStrategyBase derivationStrategy, CoinSelectionStrategy strategy, int limit, long amount, long closestTo); /// /// Gets the UTXOs that are not locked in other transactions related to the outpoints /// /// /// - public Task> GetUTXOsByOutpointAsync(DerivationStrategyBase derivationStrategy, List outPoints); + public Task> GetUTXOsByOutpointAsync(DerivationStrategyBase derivationStrategy, List outPoints); /// /// Locks the UTXOs for using in a specific transaction /// /// /// - public Task LockUTXOs(List selectedUTXOs, IBitcoinRequest bitcoinRequest, BitcoinRequestType requestType); + public Task LockUTXOs(List selectedUTXOs, IBitcoinRequest bitcoinRequest, BitcoinRequestType requestType); /// /// Gets the locked UTXOs from a request /// /// /// - public Task> GetLockedUTXOsForRequest(IBitcoinRequest bitcoinRequest, BitcoinRequestType requestType); + public Task> GetLockedUTXOsForRequest(IBitcoinRequest bitcoinRequest, BitcoinRequestType requestType); - public Task<(List coins, List selectedUTXOs)> GetTxInputCoins( - List availableUTXOs, + public Task<(List coins, List selectedUTXOs)> GetTxInputCoins( + List availableUTXOs, IBitcoinRequest request, DerivationStrategyBase derivationStrategy); } @@ -78,7 +79,7 @@ public class CoinSelectionService: ICoinSelectionService { private readonly ILogger _logger; private readonly IMapper _mapper; - private readonly IFMUTXORepository _fmutxoRepository; + private readonly IUTXORepository _utxoRepository; private readonly INBXplorerService _nbXplorerService; private readonly IChannelOperationRequestRepository _channelOperationRequestRepository; private readonly IWalletWithdrawalRequestRepository _walletWithdrawalRequestRepository; @@ -86,7 +87,7 @@ public class CoinSelectionService: ICoinSelectionService public CoinSelectionService( ILogger logger, IMapper mapper, - IFMUTXORepository fmutxoRepository, + IUTXORepository utxoRepository, INBXplorerService nbXplorerService, IChannelOperationRequestRepository channelOperationRequestRepository, IWalletWithdrawalRequestRepository walletWithdrawalRequestRepository @@ -94,7 +95,7 @@ IWalletWithdrawalRequestRepository walletWithdrawalRequestRepository { _logger = logger; _mapper = mapper; - _fmutxoRepository = fmutxoRepository; + _utxoRepository = utxoRepository; _nbXplorerService = nbXplorerService; _channelOperationRequestRepository = channelOperationRequestRepository; _walletWithdrawalRequestRepository = walletWithdrawalRequestRepository; @@ -110,10 +111,10 @@ private IBitcoinRequestRepository GetRepository(BitcoinRequestType requestType) }; } - public async Task LockUTXOs(List selectedUTXOs, IBitcoinRequest bitcoinRequest, BitcoinRequestType requestType) + public async Task LockUTXOs(List selectedUTXOs, IBitcoinRequest bitcoinRequest, BitcoinRequestType requestType) { // We "lock" the PSBT to the channel operation request by adding to its UTXOs collection for later checking - var utxos = selectedUTXOs.Select(x => _mapper.Map(x)).ToList(); + var utxos = selectedUTXOs.Select(x => _mapper.Map(x)).ToList(); var addUTXOsOperation = await GetRepository(requestType).AddUTXOs(bitcoinRequest, utxos); if (!addUTXOsOperation.Item1) @@ -123,7 +124,7 @@ public async Task LockUTXOs(List selectedUTXOs, IBitcoinRequest bitcoinReq } } - public async Task> GetLockedUTXOsForRequest(IBitcoinRequest bitcoinRequest, BitcoinRequestType requestType) + public async Task> GetLockedUTXOsForRequest(IBitcoinRequest bitcoinRequest, BitcoinRequestType requestType) { var getUTXOsOperation = await GetRepository(requestType).GetUTXOs(bitcoinRequest); if (!getUTXOsOperation.Item1 || getUTXOsOperation.Item2 == null) @@ -140,15 +141,15 @@ public async Task> GetLockedUTXOsForRequest(IBitcoinRequest bitcoinRe return utxos.Confirmed.UTXOs.Where(utxo => lockedUTXOsList.Contains(utxo.Outpoint.ToString())).ToList(); } - private async Task> FilterUnlockedUTXOs(UTXOChanges? utxoChanges) + private async Task> FilterUnlockedUTXOs(UTXOChanges? utxoChanges) { - var lockedUTXOs = await _fmutxoRepository.GetLockedUTXOs(); + var lockedUTXOs = await _utxoRepository.GetLockedUTXOs(); utxoChanges.RemoveDuplicateUTXOs(); - var availableUTXOs = new List(); + var availableUTXOs = new List(); foreach (var utxo in utxoChanges.Confirmed.UTXOs) { - var fmUtxo = _mapper.Map(utxo); + var fmUtxo = _mapper.Map(utxo); if (lockedUTXOs.Contains(fmUtxo)) { @@ -163,13 +164,13 @@ private async Task> FilterUnlockedUTXOs(UTXOChanges? utxoChanges) return availableUTXOs; } - public async Task> GetAvailableUTXOsAsync(DerivationStrategyBase derivationStrategy) + public async Task> GetAvailableUTXOsAsync(DerivationStrategyBase derivationStrategy) { var utxoChanges = await _nbXplorerService.GetUTXOsAsync(derivationStrategy); return await FilterUnlockedUTXOs(utxoChanges); } - public async Task> GetAvailableUTXOsAsync(DerivationStrategyBase derivationStrategy, CoinSelectionStrategy strategy, int limit, long amount, long closestTo) + public async Task> GetAvailableUTXOsAsync(DerivationStrategyBase derivationStrategy, CoinSelectionStrategy strategy, int limit, long amount, long closestTo) { UTXOChanges utxoChanges; if (Constants.NBXPLORER_ENABLE_CUSTOM_BACKEND) @@ -190,8 +191,8 @@ public async Task> GetAvailableUTXOsAsync(DerivationStrategyBase deri /// /// /// - public async Task<(List coins, List selectedUTXOs)> GetTxInputCoins( - List availableUTXOs, + public async Task<(List coins, List selectedUTXOs)> GetTxInputCoins( + List availableUTXOs, IBitcoinRequest request, DerivationStrategyBase derivationStrategy) { @@ -203,7 +204,7 @@ public async Task> GetAvailableUTXOsAsync(DerivationStrategyBase deri return (coins, selectedUTXOs); } - public async Task> GetUTXOsByOutpointAsync(DerivationStrategyBase derivationStrategy, List outPoints) + public async Task> GetUTXOsByOutpointAsync(DerivationStrategyBase derivationStrategy, List outPoints) { var utxos = await _nbXplorerService.GetUTXOsAsync(derivationStrategy); utxos.RemoveDuplicateUTXOs(); diff --git a/src/Shared/UTXOSelectorModal.razor b/src/Shared/UTXOSelectorModal.razor index f20d320b..a7979a40 100644 --- a/src/Shared/UTXOSelectorModal.razor +++ b/src/Shared/UTXOSelectorModal.razor @@ -2,6 +2,7 @@ @using NBXplorer.DerivationStrategy @using NBitcoin @using Humanizer; +@using UTXO = NBXplorer.Models.UTXO @inject ICoinSelectionService _CoinSelectionService @inject IJSRuntime JsRuntime @inject IToastService ToastService diff --git a/test/NodeGuard.Tests/Data/Repositories/FUTXORepositoryTests.cs b/test/NodeGuard.Tests/Data/Repositories/UtxoRepositoryTests.cs similarity index 81% rename from test/NodeGuard.Tests/Data/Repositories/FUTXORepositoryTests.cs rename to test/NodeGuard.Tests/Data/Repositories/UtxoRepositoryTests.cs index d900e42c..21bb75d5 100644 --- a/test/NodeGuard.Tests/Data/Repositories/FUTXORepositoryTests.cs +++ b/test/NodeGuard.Tests/Data/Repositories/UtxoRepositoryTests.cs @@ -4,7 +4,7 @@ namespace NodeGuard.Data.Repositories; -public class FUTXORepositoryTests +public class UtxoRepositoryTests { private readonly Random _random = new(); @@ -24,7 +24,7 @@ private Mock> SetupDbContextFactory() public async Task GetLockedUTXOs_emptyArgs() { var dbContextFactory = SetupDbContextFactory(); - var futxoRepository = new FUTXORepository(null, null, dbContextFactory.Object); + var futxoRepository = new UTXORepository(null, null, dbContextFactory.Object); var context = await dbContextFactory.Object.CreateDbContextAsync(); @@ -33,12 +33,12 @@ public async Task GetLockedUTXOs_emptyArgs() Description = "1", DestinationAddress = "1", Status = WalletWithdrawalRequestStatus.Pending, - UTXOs = new List { new () { TxId = "1"} } + UTXOs = new List { new () { TxId = "1"} } }); context.ChannelOperationRequests.Add(new ChannelOperationRequest { Status = ChannelOperationRequestStatus.Pending, - Utxos = new List { new () { TxId = "2"} } + Utxos = new List { new () { TxId = "2"} } }); await context.SaveChangesAsync(); @@ -50,7 +50,7 @@ public async Task GetLockedUTXOs_emptyArgs() public async Task GetLockedUTXOs_ignoreWithdrawals() { var dbContextFactory = SetupDbContextFactory(); - var futxoRepository = new FUTXORepository(null, null, dbContextFactory.Object); + var futxoRepository = new UTXORepository(null, null, dbContextFactory.Object); var context = dbContextFactory.Object.CreateDbContext(); @@ -60,13 +60,13 @@ public async Task GetLockedUTXOs_ignoreWithdrawals() Description = "1", DestinationAddress = "1", Status = WalletWithdrawalRequestStatus.Pending, - UTXOs = new List { new () { TxId = "1"} } + UTXOs = new List { new () { TxId = "1"} } }); context.ChannelOperationRequests.Add(new ChannelOperationRequest { Id = 2, Status = ChannelOperationRequestStatus.Pending, - Utxos = new List { new () { TxId = "2"} } + Utxos = new List { new () { TxId = "2"} } }); await context.SaveChangesAsync(); @@ -79,7 +79,7 @@ public async Task GetLockedUTXOs_ignoreWithdrawals() public async Task GetLockedUTXOs_ignoreChannels() { var dbContextFactory = SetupDbContextFactory(); - var futxoRepository = new FUTXORepository(null, null, dbContextFactory.Object); + var futxoRepository = new UTXORepository(null, null, dbContextFactory.Object); var context = dbContextFactory.Object.CreateDbContext(); @@ -89,13 +89,13 @@ public async Task GetLockedUTXOs_ignoreChannels() Description = "1", DestinationAddress = "1", Status = WalletWithdrawalRequestStatus.Pending, - UTXOs = new List { new () { TxId = "1"} } + UTXOs = new List { new () { TxId = "1"} } }); context.ChannelOperationRequests.Add(new ChannelOperationRequest { Id = 2, Status = ChannelOperationRequestStatus.Pending, - Utxos = new List { new () { TxId = "2"} } + Utxos = new List { new () { TxId = "2"} } }); await context.SaveChangesAsync(); @@ -108,7 +108,7 @@ public async Task GetLockedUTXOs_ignoreChannels() public async Task GetLockedUTXOs_failedChannels() { var dbContextFactory = SetupDbContextFactory(); - var futxoRepository = new FUTXORepository(null, null, dbContextFactory.Object); + var futxoRepository = new UTXORepository(null, null, dbContextFactory.Object); var context = dbContextFactory.Object.CreateDbContext(); @@ -118,13 +118,13 @@ public async Task GetLockedUTXOs_failedChannels() Description = "1", DestinationAddress = "1", Status = WalletWithdrawalRequestStatus.Failed, - UTXOs = new List { new () { TxId = "1"} } + UTXOs = new List { new () { TxId = "1"} } }); context.ChannelOperationRequests.Add(new ChannelOperationRequest { Id = 2, Status = ChannelOperationRequestStatus.Pending, - Utxos = new List { new () { TxId = "2"} } + Utxos = new List { new () { TxId = "2"} } }); await context.SaveChangesAsync(); @@ -137,7 +137,7 @@ public async Task GetLockedUTXOs_failedChannels() public async Task GetLockedUTXOs_failedCWithdrawals() { var dbContextFactory = SetupDbContextFactory(); - var futxoRepository = new FUTXORepository(null, null, dbContextFactory.Object); + var futxoRepository = new UTXORepository(null, null, dbContextFactory.Object); var context = dbContextFactory.Object.CreateDbContext(); @@ -147,13 +147,13 @@ public async Task GetLockedUTXOs_failedCWithdrawals() Description = "1", DestinationAddress = "1", Status = WalletWithdrawalRequestStatus.Pending, - UTXOs = new List { new () { TxId = "1"} } + UTXOs = new List { new () { TxId = "1"} } }); context.ChannelOperationRequests.Add(new ChannelOperationRequest { Id = 2, Status = ChannelOperationRequestStatus.Failed, - Utxos = new List { new () { TxId = "2"} } + Utxos = new List { new () { TxId = "2"} } }); await context.SaveChangesAsync(); diff --git a/test/NodeGuard.Tests/Helpers/LightningHelperTests.cs b/test/NodeGuard.Tests/Helpers/LightningHelperTests.cs index 126aa2eb..4f5ba7ea 100644 --- a/test/NodeGuard.Tests/Helpers/LightningHelperTests.cs +++ b/test/NodeGuard.Tests/Helpers/LightningHelperTests.cs @@ -23,6 +23,7 @@ using NodeGuard.TestHelpers; using NBitcoin; using NBXplorer.Models; +using UTXO = NBXplorer.Models.UTXO; namespace NodeGuard.Tests { diff --git a/test/NodeGuard.Tests/Rpc/NodeGuardServiceTests.cs b/test/NodeGuard.Tests/Rpc/NodeGuardServiceTests.cs index 39c21d17..8821f3c5 100644 --- a/test/NodeGuard.Tests/Rpc/NodeGuardServiceTests.cs +++ b/test/NodeGuard.Tests/Rpc/NodeGuardServiceTests.cs @@ -38,6 +38,7 @@ using Key = NodeGuard.Data.Models.Key; using LiquidityRule = NodeGuard.Data.Models.LiquidityRule; using Node = NodeGuard.Data.Models.Node; +using UTXO = NBXplorer.Models.UTXO; using Wallet = NodeGuard.Data.Models.Wallet; namespace NodeGuard.Rpc diff --git a/test/NodeGuard.Tests/Services/BitcoinServiceTests.cs b/test/NodeGuard.Tests/Services/BitcoinServiceTests.cs index c14f3967..d31f66da 100644 --- a/test/NodeGuard.Tests/Services/BitcoinServiceTests.cs +++ b/test/NodeGuard.Tests/Services/BitcoinServiceTests.cs @@ -10,6 +10,7 @@ using NBXplorer.Models; using NSubstitute.Exceptions; using Key = NodeGuard.Data.Models.Key; +using UTXO = NodeGuard.Data.Models.UTXO; namespace NodeGuard.Services; @@ -144,14 +145,14 @@ async Task GenerateTemplatePSBT_LegacyMultiSigSucceeds() var walletWithdrawalRequestRepository = new Mock(); var walletWithdrawalRequestPsbtRepository = new Mock(); - var fmutxoRepository = new Mock(); + var fmutxoRepository = new Mock(); var nbXplorerService = new Mock(); var mapper = new Mock(); walletWithdrawalRequestRepository .Setup((w) => w.GetById(It.IsAny())) .ReturnsAsync(withdrawalRequest); walletWithdrawalRequestRepository - .Setup((w) => w.AddUTXOs(It.IsAny(), It.IsAny>())) + .Setup((w) => w.AddUTXOs(It.IsAny(), It.IsAny>())) .ReturnsAsync((true, null)); walletWithdrawalRequestPsbtRepository .Setup((w) => w.AddAsync(It.IsAny())) @@ -168,9 +169,9 @@ async Task GenerateTemplatePSBT_LegacyMultiSigSucceeds() { Confirmed = new UTXOChange() { - UTXOs = new List() + UTXOs = new List() { - new UTXO() + new NBXplorer.Models.UTXO() { Outpoint = new OutPoint(), Value = new Money((long)10000000), @@ -182,7 +183,7 @@ async Task GenerateTemplatePSBT_LegacyMultiSigSucceeds() }); fmutxoRepository .Setup(x => x.GetLockedUTXOs(null, null)) - .ReturnsAsync(new List()); + .ReturnsAsync(new List()); var coinSelectionService = new CoinSelectionService(_logger, mapper.Object, fmutxoRepository.Object, nbXplorerService.Object, null, walletWithdrawalRequestRepository.Object); var bitcoinService = new BitcoinService(_logger, mapper.Object, walletWithdrawalRequestRepository.Object, walletWithdrawalRequestPsbtRepository.Object, null, null, nbXplorerService.Object, coinSelectionService); @@ -212,14 +213,14 @@ async Task GenerateTemplatePSBT_MultiSigSucceeds() var walletWithdrawalRequestRepository = new Mock(); var walletWithdrawalRequestPsbtRepository = new Mock(); - var fmutxoRepository = new Mock(); + var fmutxoRepository = new Mock(); var nbXplorerService = new Mock(); var mapper = new Mock(); walletWithdrawalRequestRepository .Setup((w) => w.GetById(It.IsAny())) .ReturnsAsync(withdrawalRequest); walletWithdrawalRequestRepository - .Setup((w) => w.AddUTXOs(It.IsAny(), It.IsAny>())) + .Setup((w) => w.AddUTXOs(It.IsAny(), It.IsAny>())) .ReturnsAsync((true, null)); walletWithdrawalRequestPsbtRepository .Setup((w) => w.AddAsync(It.IsAny())) @@ -236,9 +237,9 @@ async Task GenerateTemplatePSBT_MultiSigSucceeds() { Confirmed = new UTXOChange() { - UTXOs = new List() + UTXOs = new List() { - new UTXO() + new NBXplorer.Models.UTXO() { Outpoint = new OutPoint(), Value = new Money((long)10000000), @@ -250,7 +251,7 @@ async Task GenerateTemplatePSBT_MultiSigSucceeds() }); fmutxoRepository .Setup(x => x.GetLockedUTXOs(null , null)) - .ReturnsAsync(new List()); + .ReturnsAsync(new List()); var coinSelectionService = new CoinSelectionService(_logger, mapper.Object, fmutxoRepository.Object, nbXplorerService.Object, null, walletWithdrawalRequestRepository.Object); @@ -281,14 +282,14 @@ async Task GenerateTemplatePSBT_SingleSigSucceeds() var walletWithdrawalRequestRepository = new Mock(); var walletWithdrawalRequestPsbtRepository = new Mock(); - var fmutxoRepository = new Mock(); + var fmutxoRepository = new Mock(); var nbXplorerService = new Mock(); var mapper = new Mock(); walletWithdrawalRequestRepository .Setup((w) => w.GetById(It.IsAny())) .ReturnsAsync(withdrawalRequest); walletWithdrawalRequestRepository - .Setup((w) => w.AddUTXOs(It.IsAny(), It.IsAny>())) + .Setup((w) => w.AddUTXOs(It.IsAny(), It.IsAny>())) .ReturnsAsync((true, null)); walletWithdrawalRequestPsbtRepository .Setup((w) => w.AddAsync(It.IsAny())) @@ -305,9 +306,9 @@ async Task GenerateTemplatePSBT_SingleSigSucceeds() { Confirmed = new UTXOChange() { - UTXOs = new List() + UTXOs = new List() { - new UTXO() + new NBXplorer.Models.UTXO() { Value = new Money((long)10000000), ScriptPubKey = wallet.GetDerivationStrategy().GetDerivation(KeyPath.Parse("0/0")).ScriptPubKey, @@ -318,7 +319,7 @@ async Task GenerateTemplatePSBT_SingleSigSucceeds() }); fmutxoRepository .Setup(x => x.GetLockedUTXOs(null, null)) - .ReturnsAsync(new List()); + .ReturnsAsync(new List()); var coinSelectionService = new CoinSelectionService(_logger, mapper.Object, fmutxoRepository.Object, nbXplorerService.Object, null, walletWithdrawalRequestRepository.Object); @@ -337,9 +338,9 @@ async Task GenerateTemplatePSBT_Changeless_SingleSigSucceeds() { // Arrange var wallet = CreateWallet.SingleSig(_internalWallet); - var utxos = new List() + var utxos = new List() { - new UTXO() + new NBXplorer.Models.UTXO() { Value = new Money((long)10000000), ScriptPubKey = wallet.GetDerivationStrategy().GetDerivation(KeyPath.Parse("0/0")).ScriptPubKey, @@ -362,14 +363,14 @@ async Task GenerateTemplatePSBT_Changeless_SingleSigSucceeds() var walletWithdrawalRequestRepository = new Mock(); var walletWithdrawalRequestPsbtRepository = new Mock(); - var fmutxoRepository = new Mock(); + var fmutxoRepository = new Mock(); var nbXplorerService = new Mock(); var mapper = new Mock(); walletWithdrawalRequestRepository .Setup((w) => w.GetById(It.IsAny())) .ReturnsAsync(withdrawalRequest); walletWithdrawalRequestRepository - .Setup((w) => w.AddUTXOs(It.IsAny(), It.IsAny>())) + .Setup((w) => w.AddUTXOs(It.IsAny(), It.IsAny>())) .ReturnsAsync((true, null)); walletWithdrawalRequestPsbtRepository .Setup((w) => w.AddAsync(It.IsAny())) @@ -390,7 +391,7 @@ async Task GenerateTemplatePSBT_Changeless_SingleSigSucceeds() } }); - var fmUtxos = utxos.Select(x => new FMUTXO() { TxId = x.Outpoint.Hash.ToString(), OutputIndex = 1}).ToList(); + var fmUtxos = utxos.Select(x => new UTXO() { TxId = x.Outpoint.Hash.ToString(), OutputIndex = 1}).ToList(); fmutxoRepository .Setup(x => x.GetLockedUTXOs(null, null)) .ReturnsAsync(fmUtxos); @@ -457,9 +458,9 @@ async Task PerformWithdrawal_SingleSigSucceeds() { Confirmed = new UTXOChange() { - UTXOs = new List() + UTXOs = new List() { - new UTXO() + new NBXplorer.Models.UTXO() { Value = new Money((long)10000000), ScriptPubKey = wallet.GetDerivationStrategy().GetDerivation(KeyPath.Parse("0/0")).ScriptPubKey, @@ -537,9 +538,9 @@ async Task PerformWithdrawal_MultiSigSucceeds() { Confirmed = new UTXOChange() { - UTXOs = new List() + UTXOs = new List() { - new UTXO() + new NBXplorer.Models.UTXO() { Value = new Money((long)10000000), ScriptPubKey = wallet.GetDerivationStrategy().GetDerivation(KeyPath.Parse("0/0")).ScriptPubKey, @@ -617,9 +618,9 @@ async Task PerformWithdrawal_LegacyMultiSigSucceeds() { Confirmed = new UTXOChange() { - UTXOs = new List() + UTXOs = new List() { - new UTXO() + new NBXplorer.Models.UTXO() { Value = new Money((long)10000000), ScriptPubKey = wallet.GetDerivationStrategy().GetDerivation(KeyPath.Parse("0/0")).ScriptPubKey, diff --git a/test/NodeGuard.Tests/Services/LightningServiceTests.cs b/test/NodeGuard.Tests/Services/LightningServiceTests.cs index 5e95b447..872d2883 100644 --- a/test/NodeGuard.Tests/Services/LightningServiceTests.cs +++ b/test/NodeGuard.Tests/Services/LightningServiceTests.cs @@ -32,6 +32,7 @@ using NBXplorer.DerivationStrategy; using Microsoft.EntityFrameworkCore; using Channel = NodeGuard.Data.Models.Channel; +using UTXO = NBXplorer.Models.UTXO; namespace NodeGuard.Services {