mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2026-01-06 23:54:28 +01:00
Properly map addresses to invoice, use new nbxplorer
This commit is contained in:
@@ -14,7 +14,7 @@ services:
|
|||||||
- nbxplorer
|
- nbxplorer
|
||||||
|
|
||||||
nbxplorer:
|
nbxplorer:
|
||||||
image: nicolasdorier/nbxplorer:1.0.0.14
|
image: nicolasdorier/nbxplorer:1.0.0.16
|
||||||
ports:
|
ports:
|
||||||
- "32838:32838"
|
- "32838:32838"
|
||||||
expose:
|
expose:
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
<PackageReference Include="NBitcoin" Version="4.0.0.38" />
|
<PackageReference Include="NBitcoin" Version="4.0.0.38" />
|
||||||
<PackageReference Include="NBitpayClient" Version="1.0.0.9" />
|
<PackageReference Include="NBitpayClient" Version="1.0.0.9" />
|
||||||
<PackageReference Include="DBreeze" Version="1.87.0" />
|
<PackageReference Include="DBreeze" Version="1.87.0" />
|
||||||
<PackageReference Include="NBXplorer.Client" Version="1.0.0.14" />
|
<PackageReference Include="NBXplorer.Client" Version="1.0.0.16" />
|
||||||
<PackageReference Include="NicolasDorier.CommandLine" Version="1.0.0.1" />
|
<PackageReference Include="NicolasDorier.CommandLine" Version="1.0.0.1" />
|
||||||
<PackageReference Include="NicolasDorier.CommandLine.Configuration" Version="1.0.0.2" />
|
<PackageReference Include="NicolasDorier.CommandLine.Configuration" Version="1.0.0.2" />
|
||||||
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.13" />
|
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.13" />
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ namespace BTCPayServer.Configuration
|
|||||||
|
|
||||||
db = new DBreezeEngine(CreateDBPath(opts, "AddressMapping"));
|
db = new DBreezeEngine(CreateDBPath(opts, "AddressMapping"));
|
||||||
_Resources.Add(db);
|
_Resources.Add(db);
|
||||||
Wallet = new BTCPayWallet(Explorer, db);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CreateDBPath(BTCPayServerOptions opts, string name)
|
private static string CreateDBPath(BTCPayServerOptions opts, string name)
|
||||||
@@ -113,11 +112,6 @@ namespace BTCPayServer.Configuration
|
|||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
public BTCPayWallet Wallet
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
public ApplicationDbContextFactory DBFactory
|
public ApplicationDbContextFactory DBFactory
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ namespace BTCPayServer.Controllers
|
|||||||
entity.DepositAddress = await _Wallet.ReserveAddressAsync(derivationStrategy);
|
entity.DepositAddress = await _Wallet.ReserveAddressAsync(derivationStrategy);
|
||||||
|
|
||||||
entity = await _InvoiceRepository.CreateInvoiceAsync(store.Id, entity);
|
entity = await _InvoiceRepository.CreateInvoiceAsync(store.Id, entity);
|
||||||
await _Wallet.MapAsync(entity.DepositAddress, entity.Id);
|
await _Wallet.MapAsync(entity.DepositAddress.ScriptPubKey, entity.Id);
|
||||||
await _Watcher.WatchAsync(entity.Id);
|
await _Watcher.WatchAsync(entity.Id);
|
||||||
var resp = entity.EntityToDTO();
|
var resp = entity.EntityToDTO();
|
||||||
return new DataWrapper<InvoiceResponse>(resp) { Facade = "pos/invoice" };
|
return new DataWrapper<InvoiceResponse>(resp) { Facade = "pos/invoice" };
|
||||||
|
|||||||
25
BTCPayServer/Data/AddressInvoiceData.cs
Normal file
25
BTCPayServer/Data/AddressInvoiceData.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Data
|
||||||
|
{
|
||||||
|
public class AddressInvoiceData
|
||||||
|
{
|
||||||
|
public string Address
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvoiceData InvoiceData
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string InvoiceDataId
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,6 +46,11 @@ namespace BTCPayServer.Data
|
|||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DbSet<AddressInvoiceData> AddressInvoices
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
public DbSet<SettingData> Settings
|
public DbSet<SettingData> Settings
|
||||||
{
|
{
|
||||||
get; set;
|
get; set;
|
||||||
@@ -86,6 +91,9 @@ namespace BTCPayServer.Data
|
|||||||
.HasOne(pt => pt.StoreData)
|
.HasOne(pt => pt.StoreData)
|
||||||
.WithMany(t => t.UserStores)
|
.WithMany(t => t.UserStores)
|
||||||
.HasForeignKey(pt => pt.StoreDataId);
|
.HasForeignKey(pt => pt.StoreDataId);
|
||||||
|
|
||||||
|
builder.Entity<AddressInvoiceData>()
|
||||||
|
.HasKey(o => o.Address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ using Microsoft.AspNetCore.Identity;
|
|||||||
using BTCPayServer.Models;
|
using BTCPayServer.Models;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using BTCPayServer.Services.Wallets;
|
||||||
|
|
||||||
namespace BTCPayServer.Hosting
|
namespace BTCPayServer.Hosting
|
||||||
{
|
{
|
||||||
@@ -111,7 +112,7 @@ namespace BTCPayServer.Hosting
|
|||||||
services.TryAddSingleton<Network>(o => o.GetRequiredService<BTCPayServerOptions>().Network);
|
services.TryAddSingleton<Network>(o => o.GetRequiredService<BTCPayServerOptions>().Network);
|
||||||
services.TryAddSingleton<ApplicationDbContextFactory>(o => o.GetRequiredService<BTCPayServerRuntime>().DBFactory);
|
services.TryAddSingleton<ApplicationDbContextFactory>(o => o.GetRequiredService<BTCPayServerRuntime>().DBFactory);
|
||||||
services.TryAddSingleton<StoreRepository>();
|
services.TryAddSingleton<StoreRepository>();
|
||||||
services.TryAddSingleton(o => o.GetRequiredService<BTCPayServerRuntime>().Wallet);
|
services.TryAddSingleton<BTCPayWallet>();
|
||||||
services.TryAddSingleton<CurrencyNameTable>();
|
services.TryAddSingleton<CurrencyNameTable>();
|
||||||
services.TryAddSingleton<IFeeProvider>(o => new NBXplorerFeeProvider()
|
services.TryAddSingleton<IFeeProvider>(o => new NBXplorerFeeProvider()
|
||||||
{
|
{
|
||||||
|
|||||||
392
BTCPayServer/Migrations/20171006013443_AddressMapping.Designer.cs
generated
Normal file
392
BTCPayServer/Migrations/20171006013443_AddressMapping.Designer.cs
generated
Normal file
@@ -0,0 +1,392 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using BTCPayServer.Data;
|
||||||
|
using BTCPayServer.Servcices.Invoices;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.Internal;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ApplicationDbContext))]
|
||||||
|
[Migration("20171006013443_AddressMapping")]
|
||||||
|
partial class AddressMapping
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.0.0-rtm-26452");
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.AddressInvoiceData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Address")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("InvoiceDataId");
|
||||||
|
|
||||||
|
b.HasKey("Address");
|
||||||
|
|
||||||
|
b.HasIndex("InvoiceDataId");
|
||||||
|
|
||||||
|
b.ToTable("AddressInvoices");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<byte[]>("Blob");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("Created");
|
||||||
|
|
||||||
|
b.Property<string>("CustomerEmail");
|
||||||
|
|
||||||
|
b.Property<string>("ExceptionStatus");
|
||||||
|
|
||||||
|
b.Property<string>("ItemCode");
|
||||||
|
|
||||||
|
b.Property<string>("OrderId");
|
||||||
|
|
||||||
|
b.Property<string>("Status");
|
||||||
|
|
||||||
|
b.Property<string>("StoreDataId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("StoreDataId");
|
||||||
|
|
||||||
|
b.ToTable("Invoices");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.PaymentData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<byte[]>("Blob");
|
||||||
|
|
||||||
|
b.Property<string>("InvoiceDataId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("InvoiceDataId");
|
||||||
|
|
||||||
|
b.ToTable("Payments");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.RefundAddressesData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<byte[]>("Blob");
|
||||||
|
|
||||||
|
b.Property<string>("InvoiceDataId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("InvoiceDataId");
|
||||||
|
|
||||||
|
b.ToTable("RefundAddresses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.SettingData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Settings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.StoreData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("DerivationStrategy");
|
||||||
|
|
||||||
|
b.Property<int>("SpeedPolicy");
|
||||||
|
|
||||||
|
b.Property<byte[]>("StoreCertificate");
|
||||||
|
|
||||||
|
b.Property<string>("StoreName");
|
||||||
|
|
||||||
|
b.Property<string>("StoreWebsite");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Stores");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.UserStore", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("ApplicationUserId");
|
||||||
|
|
||||||
|
b.Property<string>("StoreDataId");
|
||||||
|
|
||||||
|
b.Property<string>("Role");
|
||||||
|
|
||||||
|
b.HasKey("ApplicationUserId", "StoreDataId");
|
||||||
|
|
||||||
|
b.HasIndex("StoreDataId");
|
||||||
|
|
||||||
|
b.ToTable("UserStore");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Models.ApplicationUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken();
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed");
|
||||||
|
|
||||||
|
b.Property<bool>("RequiresEmailConfirmation");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("UserNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken();
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("RoleNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.AddressInvoiceData", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("InvoiceDataId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("StoreDataId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.PaymentData", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||||
|
.WithMany("Payments")
|
||||||
|
.HasForeignKey("InvoiceDataId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.RefundAddressesData", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||||
|
.WithMany("RefundAddresses")
|
||||||
|
.HasForeignKey("InvoiceDataId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.UserStore", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Models.ApplicationUser", "ApplicationUser")
|
||||||
|
.WithMany("UserStores")
|
||||||
|
.HasForeignKey("ApplicationUserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
|
||||||
|
.WithMany("UserStores")
|
||||||
|
.HasForeignKey("StoreDataId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Models.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Models.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("BTCPayServer.Models.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Models.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
BTCPayServer/Migrations/20171006013443_AddressMapping.cs
Normal file
41
BTCPayServer/Migrations/20171006013443_AddressMapping.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Migrations
|
||||||
|
{
|
||||||
|
public partial class AddressMapping : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AddressInvoices",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Address = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
InvoiceDataId = table.Column<string>(type: "TEXT", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AddressInvoices", x => x.Address);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AddressInvoices_Invoices_InvoiceDataId",
|
||||||
|
column: x => x.InvoiceDataId,
|
||||||
|
principalTable: "Invoices",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AddressInvoices_InvoiceDataId",
|
||||||
|
table: "AddressInvoices",
|
||||||
|
column: "InvoiceDataId");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AddressInvoices");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,20 @@ namespace BTCPayServer.Migrations
|
|||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "2.0.0-rtm-26452");
|
.HasAnnotation("ProductVersion", "2.0.0-rtm-26452");
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.AddressInvoiceData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Address")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("InvoiceDataId");
|
||||||
|
|
||||||
|
b.HasKey("Address");
|
||||||
|
|
||||||
|
b.HasIndex("InvoiceDataId");
|
||||||
|
|
||||||
|
b.ToTable("AddressInvoices");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
|
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("Id")
|
b.Property<string>("Id")
|
||||||
@@ -286,6 +300,13 @@ namespace BTCPayServer.Migrations
|
|||||||
b.ToTable("AspNetUserTokens");
|
b.ToTable("AspNetUserTokens");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.AddressInvoiceData", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("InvoiceDataId");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
|
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
|
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ using System.Threading;
|
|||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using Hangfire;
|
using Hangfire;
|
||||||
|
using BTCPayServer.Services.Wallets;
|
||||||
|
|
||||||
namespace BTCPayServer.Servcices.Invoices
|
namespace BTCPayServer.Servcices.Invoices
|
||||||
{
|
{
|
||||||
@@ -21,11 +22,14 @@ namespace BTCPayServer.Servcices.Invoices
|
|||||||
ExplorerClient _ExplorerClient;
|
ExplorerClient _ExplorerClient;
|
||||||
DerivationStrategyFactory _DerivationFactory;
|
DerivationStrategyFactory _DerivationFactory;
|
||||||
InvoiceNotificationManager _NotificationManager;
|
InvoiceNotificationManager _NotificationManager;
|
||||||
|
BTCPayWallet _Wallet;
|
||||||
|
|
||||||
public InvoiceWatcher(ExplorerClient explorerClient,
|
public InvoiceWatcher(ExplorerClient explorerClient,
|
||||||
InvoiceRepository invoiceRepository,
|
InvoiceRepository invoiceRepository,
|
||||||
|
BTCPayWallet wallet,
|
||||||
InvoiceNotificationManager notificationManager)
|
InvoiceNotificationManager notificationManager)
|
||||||
{
|
{
|
||||||
|
_Wallet = wallet ?? throw new ArgumentNullException(nameof(wallet));
|
||||||
_ExplorerClient = explorerClient ?? throw new ArgumentNullException(nameof(explorerClient));
|
_ExplorerClient = explorerClient ?? throw new ArgumentNullException(nameof(explorerClient));
|
||||||
_DerivationFactory = new DerivationStrategyFactory(_ExplorerClient.Network);
|
_DerivationFactory = new DerivationStrategyFactory(_ExplorerClient.Network);
|
||||||
_InvoiceRepository = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository));
|
_InvoiceRepository = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository));
|
||||||
@@ -93,10 +97,18 @@ namespace BTCPayServer.Servcices.Invoices
|
|||||||
{
|
{
|
||||||
var strategy = _DerivationFactory.Parse(invoice.DerivationStrategy);
|
var strategy = _DerivationFactory.Parse(invoice.DerivationStrategy);
|
||||||
changes = await _ExplorerClient.SyncAsync(strategy, changes, false, _Cts.Token).ConfigureAwait(false);
|
changes = await _ExplorerClient.SyncAsync(strategy, changes, false, _Cts.Token).ConfigureAwait(false);
|
||||||
|
|
||||||
|
var utxos = changes.Confirmed.UTXOs.Concat(changes.Unconfirmed.UTXOs).ToArray();
|
||||||
|
var invoiceIds = utxos.Select(u => _Wallet.GetInvoiceId(u.Output.ScriptPubKey)).ToArray();
|
||||||
|
utxos =
|
||||||
|
utxos
|
||||||
|
.Where((u,i) => invoiceIds[i].GetAwaiter().GetResult() == invoice.Id)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
shouldWait = false; //should not wait, Sync is blocking call
|
shouldWait = false; //should not wait, Sync is blocking call
|
||||||
|
|
||||||
List<Coin> receivedCoins = new List<Coin>();
|
List<Coin> receivedCoins = new List<Coin>();
|
||||||
foreach(var received in changes.Confirmed.UTXOs.Concat(changes.Unconfirmed.UTXOs))
|
foreach(var received in utxos)
|
||||||
if(received.Output.ScriptPubKey == invoice.DepositAddress.ScriptPubKey)
|
if(received.Output.ScriptPubKey == invoice.DepositAddress.ScriptPubKey)
|
||||||
receivedCoins.Add(new Coin(received.Outpoint, received.Output));
|
receivedCoins.Add(new Coin(received.Outpoint, received.Output));
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using DBreeze;
|
using NBitcoin;
|
||||||
using NBitcoin;
|
|
||||||
using NBXplorer;
|
using NBXplorer;
|
||||||
using NBXplorer.DerivationStrategy;
|
using NBXplorer.DerivationStrategy;
|
||||||
using System;
|
using System;
|
||||||
@@ -7,24 +6,25 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Data;
|
||||||
|
|
||||||
namespace BTCPayServer.Services.Wallets
|
namespace BTCPayServer.Services.Wallets
|
||||||
{
|
{
|
||||||
public class BTCPayWallet
|
public class BTCPayWallet
|
||||||
{
|
{
|
||||||
private ExplorerClient _Client;
|
private ExplorerClient _Client;
|
||||||
private DBreezeEngine _Engine;
|
|
||||||
private Serializer _Serializer;
|
private Serializer _Serializer;
|
||||||
private DerivationStrategyFactory _DerivationStrategyFactory;
|
private DerivationStrategyFactory _DerivationStrategyFactory;
|
||||||
|
ApplicationDbContextFactory _DBFactory;
|
||||||
|
|
||||||
public BTCPayWallet(ExplorerClient client, DBreezeEngine dbreeze)
|
public BTCPayWallet(ExplorerClient client, ApplicationDbContextFactory factory)
|
||||||
{
|
{
|
||||||
if(client == null)
|
if(client == null)
|
||||||
throw new ArgumentNullException(nameof(client));
|
throw new ArgumentNullException(nameof(client));
|
||||||
if(dbreeze == null)
|
if(factory == null)
|
||||||
throw new ArgumentNullException(nameof(dbreeze));
|
throw new ArgumentNullException(nameof(factory));
|
||||||
_Client = client;
|
_Client = client;
|
||||||
_Engine = dbreeze;
|
_DBFactory = factory;
|
||||||
_Serializer = new NBXplorer.Serializer(_Client.Network);
|
_Serializer = new NBXplorer.Serializer(_Client.Network);
|
||||||
_DerivationStrategyFactory = new DerivationStrategyFactory(_Client.Network);
|
_DerivationStrategyFactory = new DerivationStrategyFactory(_Client.Network);
|
||||||
}
|
}
|
||||||
@@ -33,30 +33,34 @@ namespace BTCPayServer.Services.Wallets
|
|||||||
public async Task<BitcoinAddress> ReserveAddressAsync(string walletIdentifier)
|
public async Task<BitcoinAddress> ReserveAddressAsync(string walletIdentifier)
|
||||||
{
|
{
|
||||||
var pathInfo = await _Client.GetUnusedAsync(_DerivationStrategyFactory.Parse(walletIdentifier), DerivationFeature.Deposit, 0, true).ConfigureAwait(false);
|
var pathInfo = await _Client.GetUnusedAsync(_DerivationStrategyFactory.Parse(walletIdentifier), DerivationFeature.Deposit, 0, true).ConfigureAwait(false);
|
||||||
using(var tx = _Engine.GetTransaction())
|
return pathInfo.ScriptPubKey.GetDestinationAddress(_DerivationStrategyFactory.Network);
|
||||||
{
|
|
||||||
var pathInfoBytes = ToBytes(pathInfo);
|
|
||||||
tx.Insert(AddressToKeyInfo, pathInfo.Address.ToString(), pathInfoBytes);
|
|
||||||
tx.Commit();
|
|
||||||
}
|
|
||||||
return pathInfo.Address;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task TrackAsync(string walletIdentifier)
|
public Task TrackAsync(string walletIdentifier)
|
||||||
{
|
{
|
||||||
await _Client.SyncAsync(_DerivationStrategyFactory.Parse(walletIdentifier), null, null, true).ConfigureAwait(false);
|
return _Client.TrackAsync(_DerivationStrategyFactory.Parse(walletIdentifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
const string AddressToId = "AtI";
|
public async Task<string> GetInvoiceId(Script scriptPubKey)
|
||||||
const string AddressToKeyInfo = "AtK";
|
|
||||||
public Task MapAsync(BitcoinAddress address, string id)
|
|
||||||
{
|
{
|
||||||
using(var tx = _Engine.GetTransaction())
|
using(var db = _DBFactory.CreateContext())
|
||||||
{
|
{
|
||||||
tx.Insert(AddressToId, address.ToString(), id);
|
var result = await db.AddressInvoices.FindAsync(scriptPubKey.Hash.ToString());
|
||||||
tx.Commit();
|
return result?.InvoiceDataId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task MapAsync(Script address, string invoiceId)
|
||||||
|
{
|
||||||
|
using(var db = _DBFactory.CreateContext())
|
||||||
|
{
|
||||||
|
db.AddressInvoices.Add(new AddressInvoiceData()
|
||||||
|
{
|
||||||
|
Address = address.Hash.ToString(),
|
||||||
|
InvoiceDataId = invoiceId
|
||||||
|
});
|
||||||
|
await db.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
return Task.FromResult(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] ToBytes<T>(T obj)
|
private byte[] ToBytes<T>(T obj)
|
||||||
|
|||||||
Reference in New Issue
Block a user