Compare commits
2 Commits
checkout-g
...
feat/add-s
Author | SHA1 | Date | |
---|---|---|---|
3968a2250c | |||
8b964230ab |
BTCPayServer.Abstractions
BTCPayServer.Client
BTCPayServer.Client.csprojBTCPayServerClient.APIKeys.csBTCPayServerClient.Apps.csBTCPayServerClient.Authorization.csBTCPayServerClient.Health.csBTCPayServerClient.Invoices.csBTCPayServerClient.LNURLPayPaymentMethods.csBTCPayServerClient.Lightning.Internal.csBTCPayServerClient.Lightning.Store.csBTCPayServerClient.LightningAddresses.csBTCPayServerClient.LightningNetworkPaymentMethods.csBTCPayServerClient.Misc.csBTCPayServerClient.Notifications.csBTCPayServerClient.OnChainPaymentMethods.csBTCPayServerClient.OnChainWallet.Objects.csBTCPayServerClient.OnChainWallet.csBTCPayServerClient.PaymentRequests.csBTCPayServerClient.PayoutProcessors.csBTCPayServerClient.PullPayments.csBTCPayServerClient.ServerInfo.csBTCPayServerClient.StoreEmail.csBTCPayServerClient.StorePaymentMethods.csBTCPayServerClient.StorePayoutProcessors.csBTCPayServerClient.StoreRatesConfiguration.csBTCPayServerClient.StoreUsers.csBTCPayServerClient.Stores.csBTCPayServerClient.Users.csBTCPayServerClient.Webhooks.csBTCPayServerClient.csGreenFieldAPIException.csGreenFieldValidationException.cs
JsonConverters
Models
AppBaseData.csApplicationUserData.csCreateAppRequest.csCreateApplicationUserRequest.csCreateOnChainTransactionRequest.csCreatePullPaymentRequest.csCrowdfundAppData.csGenerateOnChainWalletRequest.csGenericPaymentMethodData.csGreenfieldAPIError.csGreenfieldValidationError.csInvoiceData.csInvoiceExceptionStatus.csInvoicePaymentMethodDataModel.csLNURLPayPaymentMethodBaseData.csLNURLPayPaymentMethodData.csLightningAddressData.csLightningNetworkPaymentMethodBaseData.csLightningNetworkPaymentMethodData.csNotificationSettingsData.csOnChainPaymentMethodBaseData.csOnChainPaymentMethodData.csOnChainPaymentMethodDataWithSensitiveData.csOnChainWalletUTXOData.csPaymentRequestBaseData.csPointOfSaleAppData.csPullPaymentBaseData.csStoreBaseData.csUpdateApplicationUserRequest.csUpdateLightningNetworkPaymentMethodRequest.csUpdateNotificationSettingsRequest.csUpdateOnChainPaymentMethodRequest.csWebhookInvoiceEvent.cs
BTCPayServer.Common
BTCPayServer.Data
ApplicationDbContext.csApplicationDbContextFactory.csBTCPayServer.Data.csproj
DBScripts
DBScriptsMigration.csData
APIKeyData.csAddressInvoiceData.csAppData.csApplicationUser.csFido2Credential.csFormData.csInvoiceData.Migration.csInvoiceData.csInvoiceEventData.csLightingAddressData.csMigrationExtensions.csNotificationData.csPaymentData.Migration.csPaymentData.csPaymentRequestData.csPayoutData.Migration.csPayoutData.csPayoutProcessorData.csPullPaymentData.csSettingData.csStoreData.csStoreRole.csStoreSettingData.csWalletObjectData.csWalletObjectLinkData.csWebhookData.csWebhookDeliveryData.cs
Migrations
20170913143004_Init.cs20170926073744_Settings.cs20170926084408_RequiresEmailConfirmation.cs20171006013443_AddressMapping.cs20171010082424_Tokens.cs20171012020112_PendingInvoices.cs20171023101754_StoreBlob.cs20171024163354_RenewUsedAddresses.cs20171105235734_PaymentAccounted.cs20171221054550_AltcoinSupport.cs20180106095215_DerivationStrategies.cs20180109021122_defaultcrypto.cs20180114123253_events.cs20180402095640_appdata.cs20180429083930_legacyapikey.cs20180719095626_CanDeleteStores.cs20190121133309_AddPaymentRequests.cs20190219032533_AppsTagging.cs20190225091644_AddOpenIddict.cs20190324141717_AddFiles.cs20190425081749_AddU2fDevices.cs20190701082105_sort_paymentrequests.cs20190802142637_WalletData.cs20200110064617_OpenIddictUpdate.cs20200119130108_ExtendApiKeys.cs20200224134444_Remove_OpenIddict.cs20200225133433_AddApiKeyLabel.cs20200402065615_AddApiKeyBlob.cs20200507092343_AddArchivedToInvoice.cs20200625064111_refundnotificationpullpayments.cs20200901161733_AddInvoiceEventLogSeverity.cs20201002145033_AddCreateDateToUser.cs20201007090617_u2fDeviceCascade.cs20201208054211_invoicesorderindex.cs20210314092253_Fido2Credentials.cs20220311135252_AddPayoutProcessors.cs20220414132313_AddLightningAddress.cs20220610090843_AddSettingsToStore.cs20220929132704_label.cs20221128062447_jsonb.cs20230123062447_migrateoldratesource.cs20230125085242_AddForms.cs20230130040047_blob2.cs20230130062447_jsonb2.cs20230315062447_fixmaxlength.cs20230504125505_StoreRoles.cs20230529135505_WebhookDeliveriesCleanup.cs20231121031609_removecurrentrefund.cs20231219031609_appssettingstojson.cs20240220000000_FixWalletObjectsWithEmptyWalletId.cs20240229000000_PayoutAndPullPaymentToJsonBlob.cs20240229092905_AddManagerAndEmployeeToStoreRoles.cs20240304003640_addinvoicecolumns.cs20240317024757_payments_refactor.cs20240405004015_cleanup_invoice_events.cs20240405052858_cleanup_address_invoices.cs20240508015052_fileid.csApplicationDbContextModelSnapshot.cs
MigrationsExtensions.csBTCPayServer.PluginPacker
BTCPayServer.Rating
BTCPayServer.Tests
AltcoinTests
BTCPayServer.Tests.csprojBTCPayServerTester.csCheckoutUITests.csCheckoutv2Tests.csFastTests.csGreenfieldAPITests.csPayJoinTests.csPaymentRequestTests.csSeleniumTester.csSeleniumTests.csServerTester.csTestAccount.csTestData
ThirdPartyTests.csUnitTest1.csUtilitiesTests.csdocker-compose.altcoins.ymldocker-compose.ymlsetup-dev-basics.shBTCPayServer
BTCPayServer.csprojProgram.csPoliciesSettings.csPrettyNameProvider.csUnresolvedUri.csVaultClient.csWalletId.cs
Blazor
Components
AppTopItems
Icon
InvoiceStatus
MainLogo
MainNav
StoreLightningBalance
StoreRecentInvoices
StoreRecentTransactions
StoreSelector
StoreWalletBalance
TruncateCenter
WalletNav
Configuration
Controllers
BitpayInvoiceController.csBitpayRateController.cs
GreenField
GreenfieldAppsController.csGreenfieldInvoiceController.csGreenfieldLightningNodeApiController.Internal.csGreenfieldLightningNodeApiController.Store.csGreenfieldLightningNodeApiController.csGreenfieldNotificationsController.csGreenfieldPaymentRequestsController.csGreenfieldPayoutProcessorsController.csGreenfieldPullPaymentController.csGreenfieldServerInfoController.csGreenfieldStoreAutomatedLightningPayoutProcessorsController.csGreenfieldStoreAutomatedOnChainPayoutProcessorsController.csGreenfieldStoreLNURLPayPaymentMethodsController.csGreenfieldStoreLightningAddressesController.csGreenfieldStoreLightningNetworkPaymentMethodsController.csGreenfieldStoreOnChainPaymentMethodsController.WalletGeneration.csGreenfieldStoreOnChainPaymentMethodsController.csGreenfieldStoreOnChainWalletsController.csGreenfieldStorePaymentMethodsController.csGreenfieldStorePayoutProcessorsController.csGreenfieldStoreRatesConfigurationController.csGreenfieldStoreRatesController.csGreenfieldStoresController.csGreenfieldUsersController.csLocalBTCPayServerClient.cs
UIAppsController.csUIHomeController.csUIInvoiceController.Testing.csUIInvoiceController.UI.csUIInvoiceController.csUILNURLAuthController.csUILNURLController.csUIManageController.csUINotificationsController.csUIPaymentRequestController.csUIPublicLightningNodeInfoController.csUIPullPaymentController.Boltcard.csUIPullPaymentController.csUIReportsController.CheatMode.csUIReportsController.csUIServerController.Roles.csUIServerController.Users.csUIServerController.csUIStorePullPaymentsController.PullPayments.csUIStoresController.Dashboard.csUIStoresController.Email.csUIStoresController.Integrations.csUIStoresController.LightningLike.csUIStoresController.Onchain.csUIStoresController.Rates.csUIStoresController.Roles.csUIStoresController.Settings.csUIStoresController.Tokens.csUIStoresController.Users.csUIStoresController.csUIUserStoresController.csUIVaultController.csUIWalletsController.PSBT.csUIWalletsController.csData
AddressInvoiceDataExtensions.csBlobSerializer.csIHasBlobExtensions.csInvoiceDataExtensions.csPaymentDataExtensions.cs
DefaultRules.csDerivationSchemeSettings.csPayouts
PullPayments
StoreBlob.csStoreDataExtensions.csEvents
Extensions.csExtensions
Fido2
Filters
Forms
HandlersDictionary.csHostedServices
BitpayIPNSender.csBlobMigratorHostedService.csCleanupWebhookDeliveriesTask.csDbMigrationsHostedService.csInvoiceBlobMigratorHostedService.csInvoiceWatcher.csPayoutBlobMigratorHostedService.csPullPaymentHostedService.csRatesHostedService.csTransactionLabelMarkerHostedService.cs
Webhooks
Hosting
JsonConverters
ModelBinders
Models
BitpayCreateInvoiceRequest.csInvoiceResponse.cs
InvoicingModels
ManageViewModels
NotificationViewModels
PaymentRequestViewModels
ServerViewModels
StoreBrandingViewModel.csStoreViewModels
CheckoutAppearanceViewModel.csGeneralSettingsViewModel.csRatesViewModel.csStoreDerivationScheme.csStoreLightningNode.csStoreUsersViewModel.cs
ViewPullPaymentModel.csWalletViewModels
PaymentRequest
Payments
Bitcoin
BitcoinLikeOnChainPaymentMethod.csBitcoinLikePaymentData.csBitcoinLikePaymentHandler.csBitcoinPaymentLinkExtension.csBitcoinPaymentMethodBitpayAPIExtension.csBitcoinPaymentMethodViewExtension.csBitcoinPaymentModelExtension.csBitcoinPaymentPromptDetails.csNBXplorerListener.cs
IPaymentLinkExtension.csIPaymentMethodBitpayAPIExtension.csIPaymentMethodDetails.csIPaymentMethodHandler.csIPaymentMethodViewExtension.csIPaymentModelExtension.csISupportedPaymentMethod.csLNURLPay
LNURLPayPaymentHandler.csLNURLPayPaymentLinkExtension.csLNURLPayPaymentMethodBitpayAPIExtension.csLNURLPayPaymentMethodDetails.csLNURLPayPaymentModelExtension.csLNURLPaySupportedPaymentMethod.csLNURLPaymentMethodConfig.csLNURLPaymentMethodViewExtension.csPaymentTypes.LNURL.cs
Lightning
LightningExtensions.csLightningLikePaymentData.csLightningLikePaymentHandler.csLightningLikePaymentMethodDetails.csLightningListener.csLightningPaymentLinkExtension.csLightningPaymentMethodBitpayAPIExtension.csLightningPaymentMethodViewExtension.csLightningPaymentModelExtension.csLightningPendingPayoutListener.csLightningSupportedPaymentMethod.csLigthningPaymentPromptDetails.cs
PayJoin
PaymentMethodExtensions.csPaymentMethodId.csPaymentTypes.Bitcoin.csPaymentTypes.Lightning.csPaymentTypes.csPayoutProcessors
BaseAutomatedPayoutProcessor.csIPayoutProcessorFactory.cs
Lightning
LightningAutomatedPayoutProcessor.csLightningAutomatedPayoutSenderFactory.csUILightningAutomatedPayoutProcessorsController.cs
OnChain
OnChainAutomatedPayoutProcessor.csOnChainAutomatedPayoutSenderFactory.csUIOnChainAutomatedPayoutProcessorsController.cs
PayoutProcessorService.csPayoutProcessorsExtensions.csUIPayoutProcessorsController.csPayouts
Plugins
Altcoins
AltcoinsPlugin.BGold.csAltcoinsPlugin.Dash.csAltcoinsPlugin.Dogecoin.csAltcoinsPlugin.Groestlcoin.csAltcoinsPlugin.Litecoin.csAltcoinsPlugin.Monacoin.cs
Liquid
Monero
AltcoinsPlugin.Monero.cs
RPC/Models
Zcash
Bitcoin
Crowdfund
NFC
PluginBuilderClient.csPluginManager.csPointOfSale
Shopify
Properties
SearchString.csServices
Altcoins
Monero
MoneroLikeExtensions.cs
Payments
MoneroLikeOnChainPaymentMethodDetails.csMoneroLikePaymentData.csMoneroLikePaymentMethodHandler.csMoneroPaymentLinkExtension.csMoneroPaymentModelExtension.csMoneroPaymentType.csMoneroSupportedPaymentMethod.cs
Services
UI
Zcash
Apps
BTCPayNetworkJsonSerializerSettings.csCheater.csFees
InvoiceActivator.csInvoices
InvoiceEntity.csInvoiceRepository.csPaymentBlob.csPaymentCreation.csPaymentMethodDictionary.csPaymentMethodHandlerDictionary.csPaymentService.cs
LanguageService.csMigrationSettings.csNotifications
Blobs
ExternalPayoutTransactionNotification.csInviteAcceptedNotification.csInvoiceEventNotification.csPayoutNotification.cs
NotificationManager.csNotificationSender.csReporting
LegacyInvoiceExportReportProvider.csOnChainWalletReportProvider.csPaymentsReportProvider.csPayoutsReportProvider.csProductsReportProvider.csRefundsReportProvider.cs
Stores
ThemesSettings.csTransactionLinkProviders.csUriResolver.csUserService.csWalletFileParsing
BSMSWalletFileParser.csElectrumWalletFileParser.csNBXDerivGenericWalletFileParser.csOutputDescriptorWalletFileParser.csWasabiWalletFileParser.cs
WalletRepository.csWallets
Views
Shared
Bitcoin
BitcoinLikeMethodCheckout-v2.cshtmlBitcoinLikeMethodCheckout.cshtmlViewBitcoinLikePaymentData.cshtml
CreateOrEditRole.cshtmlCrowdfund
EmailsBody.cshtmlEmailsTest.cshtmlLNURL
LayoutHead.cshtmlLayoutHeadStoreBranding.cshtmlLayoutHeadTheme.cshtmlLightning
LightningLikeMethodCheckout-v2.cshtmlLightningLikeMethodCheckout.cshtmlViewLightningLikePaymentData.cshtml
ListRoles.cshtmlMonero
NFC
PayButton
PointOfSale
PosData.cshtmlShopify
ShowQR.cshtmlTemplateEditor.cshtmlVaultElements.cshtmlZcash
_Footer.cshtml_LayoutSimple.cshtml_NavLayout.cshtml_StoreHeader.cshtmlUIAccount
ForgotPassword.cshtmlLogin.cshtmlLoginWith2fa.cshtmlLoginWithFido2.cshtmlRegister.cshtmlSetPassword.cshtml
UIApps
UIFido2
UIForms
UIHome
UIInvoice
Checkout-Body.cshtmlCheckout-Cheating.cshtmlCheckout.cshtmlCheckoutV2.cshtmlCreateInvoice.cshtmlInvoice.cshtmlInvoiceReceipt.cshtmlInvoiceReceiptPrint.cshtmlListInvoices.cshtmlListInvoicesPaymentsPartial.cshtml_RefundModal.cshtml
UILNURL
UILNURLAuth
UILightning
UILightningAutomatedPayoutProcessors
UIManage
APIKeys.cshtmlAddApiKey.cshtmlAuthorizeAPIKey.cshtmlChangePassword.cshtmlEnableAuthenticator.cshtmlGenerateRecoveryCodes.cshtmlIndex.cshtmlLoginCodes.cshtmlNotificationSettings.cshtmlSetPassword.cshtmlTwoFactorAuthentication.cshtml_Nav.cshtml_ViewStart.cshtml
UIMoneroLikeStore
UINotifications
UIOnChainAutomatedPayoutProcessors
UIPaymentRequest
UIPayoutProcessors
UIPublicLightningNodeInfo
UIPullPayment
UIReports
UIServer
Branding.cshtmlCLightningRestServices.cshtmlConfiguratorService.cshtmlCreateTemporaryFileUrl.cshtmlCreateUser.cshtmlDynamicDnsService.cshtmlDynamicDnsServices.cshtmlEditAmazonS3StorageProvider.cshtmlEditAzureBlobStorageStorageProvider.cshtmlEditFileSystemStorageProvider.cshtmlEditGoogleCloudStorageStorageProvider.cshtmlEmails.cshtmlFiles.cshtmlLightningChargeServices.cshtmlLightningWalletServices.cshtmlListPlugins.cshtmlListStores.cshtmlListUsers.cshtmlLndSeedBackup.cshtmlLndServices.cshtmlLogs.cshtmlMaintenance.cshtmlP2PService.cshtmlPolicies.cshtmlRPCService.cshtmlSSHService.cshtmlServerNavPages.csServices.cshtmlStorage.cshtmlUser.cshtml_Nav.cshtml_ViewStart.cshtml
UIShopify
UIStorePullPayments
UIStores
CheckoutAppearance.cshtmlCreateToken.cshtmlDashboard.cshtmlGeneralSettings.cshtmlGenerateWallet.cshtmlGenerateWalletOptions.cshtml
ImportWallet
ImportWalletOptions.cshtmlLightning.cshtmlLightningSettings.cshtmlListTokens.cshtmlModifyWebhook.cshtmlRates.cshtmlRequestPairing.cshtmlSetupWallet.cshtmlShowToken.cshtmlStoreEmailSettings.cshtmlStoreEmails.cshtmlStoreUsers.cshtmlTestWebhook.cshtmlWalletSettings.cshtmlWebhooks.cshtml_Nav.cshtmlUIUserStores
UIWallets
CoinSelection.cshtmlListWallets.cshtmlSignWithSeed.cshtmlWalletLabels.cshtmlWalletReceive.cshtmlWalletRescan.cshtmlWalletSend.cshtmlWalletSigningOptions.cshtmlWalletTransactions.cshtml_Nav.cshtml_PSBTInfo.cshtml_WalletTransactionsList.cshtml
UIZcashLikeStore
wwwroot
checkout-v2
checkout
crowdfund
img
js
locales
am-ET.jsonar.jsonaz.jsonbg-BG.jsonbs-BA.jsonca-ES.jsoncs-CZ.jsonda-DK.jsonde-DE.jsonel-GR.jsonen.jsones-ES.jsonfa.jsonfi-FI.jsonfr-FR.jsonhe.jsonhi.jsonhr-HR.jsonhu-HU.jsonhy.jsonid.jsonis-IS.jsonit-IT.jsonja-JP.jsonka.jsonkk-KZ.jsonko.jsonlv.jsonnl-NL.jsonno.jsonnp-NP.jsonpl.jsonpt-BR.jsonpt-PT.jsonro.jsonru-RU.jsonsk-SK.jsonsl-SI.jsonsr.jsonsv.jsonth-TH.jsontr.jsonuk-UA.jsonvi-VN.jsonzh-SG.jsonzh-SP.jsonzh-TW.jsonzu.json
main
payment-request
pos
shopify
swagger/v1
swagger.template.apps.jsonswagger.template.invoices.jsonswagger.template.jsonswagger.template.notifications.jsonswagger.template.payment-requests.jsonswagger.template.payout-processors.jsonswagger.template.pull-payments.jsonswagger.template.stores-lightning-addresses.jsonswagger.template.stores-payment-methods.jsonswagger.template.stores-payment-methods.lightning-network.jsonswagger.template.stores-payment-methods.lnurl.jsonswagger.template.stores-payment-methods.on-chain.jsonswagger.template.stores.jsonswagger.template.users.jsonswagger.template.webhooks.json
vendor
bootstrap
font-awesome
css
fonts
FontAwesome.otffontawesome-webfont.eotfontawesome-webfont.svgfontawesome-webfont.ttffontawesome-webfont.wofffontawesome-webfont.woff2
less
animated.lessbordered-pulled.lesscore.lessfixed-width.lessfont-awesome.lessicons.lesslarger.lesslist.lessmixins.lesspath.lessrotated-flipped.lessscreen-reader.lessstacked.lessvariables.less
scss
Build
Changelog.mdDockerfiledocs
@ -32,8 +32,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HtmlSanitizer" Version="8.0.838" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.5" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.1" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.0-beta.2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BTCPayServer.Client\BTCPayServer.Client.csproj" />
|
||||
|
@ -1,11 +1,10 @@
|
||||
using System;
|
||||
using System.Data.Common;
|
||||
using BTCPayServer.Abstractions.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Npgsql;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Migrations.Operations;
|
||||
|
||||
@ -14,16 +13,15 @@ namespace BTCPayServer.Abstractions.Contracts
|
||||
public abstract class BaseDbContextFactory<T> where T : DbContext
|
||||
{
|
||||
private readonly IOptions<DatabaseOptions> _options;
|
||||
private readonly string _migrationTableName;
|
||||
private readonly string _schemaPrefix;
|
||||
|
||||
public BaseDbContextFactory(IOptions<DatabaseOptions> options, string migrationTableName)
|
||||
public BaseDbContextFactory(IOptions<DatabaseOptions> options, string schemaPrefix)
|
||||
{
|
||||
_options = options;
|
||||
_migrationTableName = migrationTableName;
|
||||
_schemaPrefix = schemaPrefix;
|
||||
}
|
||||
|
||||
public T CreateContext() => CreateContext(null);
|
||||
public abstract T CreateContext(Action<NpgsqlDbContextOptionsBuilder> npgsqlOptionsAction = null);
|
||||
public abstract T CreateContext();
|
||||
class CustomNpgsqlMigrationsSqlGenerator : NpgsqlMigrationsSqlGenerator
|
||||
{
|
||||
#pragma warning disable EF1001 // Internal EF Core API usage.
|
||||
@ -68,27 +66,47 @@ namespace BTCPayServer.Abstractions.Contracts
|
||||
}
|
||||
}
|
||||
|
||||
public void ConfigureBuilder(DbContextOptionsBuilder builder) => ConfigureBuilder(builder, null);
|
||||
public void ConfigureBuilder(DbContextOptionsBuilder builder, Action<NpgsqlDbContextOptionsBuilder> npgsqlOptionsAction = null)
|
||||
public void ConfigureBuilder(DbContextOptionsBuilder builder)
|
||||
{
|
||||
builder
|
||||
.UseNpgsql(_options.Value.ConnectionString, o =>
|
||||
switch (_options.Value.DatabaseType)
|
||||
{
|
||||
o.EnableRetryOnFailure(10);
|
||||
o.SetPostgresVersion(12, 0);
|
||||
npgsqlOptionsAction?.Invoke(o);
|
||||
var mainSearchPath = GetSearchPath(_options.Value.ConnectionString);
|
||||
var schemaPrefix = string.IsNullOrEmpty(_migrationTableName) ? "__EFMigrationsHistory" : _migrationTableName;
|
||||
o.MigrationsHistoryTable(schemaPrefix, mainSearchPath);
|
||||
})
|
||||
.ReplaceService<IMigrationsSqlGenerator, CustomNpgsqlMigrationsSqlGenerator>();
|
||||
case DatabaseType.Sqlite:
|
||||
builder.UseSqlite(_options.Value.ConnectionString, o =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_schemaPrefix))
|
||||
{
|
||||
o.MigrationsHistoryTable(_schemaPrefix);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case DatabaseType.Postgres:
|
||||
builder
|
||||
.UseNpgsql(_options.Value.ConnectionString, o =>
|
||||
{
|
||||
o.EnableRetryOnFailure(10);
|
||||
o.SetPostgresVersion(12, 0);
|
||||
if (!string.IsNullOrEmpty(_schemaPrefix))
|
||||
{
|
||||
o.MigrationsHistoryTable(_schemaPrefix);
|
||||
}
|
||||
})
|
||||
.ReplaceService<IMigrationsSqlGenerator, CustomNpgsqlMigrationsSqlGenerator>();
|
||||
break;
|
||||
case DatabaseType.MySQL:
|
||||
builder.UseMySql(_options.Value.ConnectionString, ServerVersion.AutoDetect(_options.Value.ConnectionString), o =>
|
||||
{
|
||||
o.EnableRetryOnFailure(10);
|
||||
|
||||
if (!string.IsNullOrEmpty(_schemaPrefix))
|
||||
{
|
||||
o.MigrationsHistoryTable(_schemaPrefix);
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
private string GetSearchPath(string connectionString)
|
||||
{
|
||||
var connectionStringBuilder = new NpgsqlConnectionStringBuilder(connectionString);
|
||||
var searchPaths = connectionStringBuilder.SearchPath?.Split(',');
|
||||
return searchPaths is not { Length: > 0 } ? null : searchPaths[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,5 @@ namespace BTCPayServer.Abstractions.Contracts
|
||||
public string Body { get; set; }
|
||||
public string ActionLink { get; set; }
|
||||
public bool Seen { get; set; }
|
||||
public string StoreId { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -36,17 +36,6 @@ public static class HttpRequestExtensions
|
||||
request.Path.ToUriComponent());
|
||||
}
|
||||
|
||||
public static string GetCurrentUrlWithQueryString(this HttpRequest request)
|
||||
{
|
||||
return string.Concat(
|
||||
request.Scheme,
|
||||
"://",
|
||||
request.Host.ToUriComponent(),
|
||||
request.PathBase.ToUriComponent(),
|
||||
request.Path.ToUriComponent(),
|
||||
request.QueryString.ToUriComponent());
|
||||
}
|
||||
|
||||
public static string GetCurrentPath(this HttpRequest request)
|
||||
{
|
||||
return string.Concat(
|
||||
|
@ -12,7 +12,7 @@ namespace BTCPayServer.Abstractions.Extensions
|
||||
private const string ACTIVE_CATEGORY_KEY = "ActiveCategory";
|
||||
private const string ACTIVE_PAGE_KEY = "ActivePage";
|
||||
private const string ACTIVE_ID_KEY = "ActiveId";
|
||||
private const string ACTIVE_CLASS = "active";
|
||||
private const string ActivePageClass = "active";
|
||||
|
||||
public enum DateDisplayFormat
|
||||
{
|
||||
@ -55,63 +55,50 @@ namespace BTCPayServer.Abstractions.Extensions
|
||||
viewData[ACTIVE_CATEGORY_KEY] = activeCategory;
|
||||
}
|
||||
|
||||
public static bool IsActiveCategory(this ViewDataDictionary viewData, string category, object id = null)
|
||||
{
|
||||
if (!viewData.ContainsKey(ACTIVE_CATEGORY_KEY)) return false;
|
||||
var activeId = viewData[ACTIVE_ID_KEY];
|
||||
var activeCategory = viewData[ACTIVE_CATEGORY_KEY]?.ToString();
|
||||
var categoryMatch = category.Equals(activeCategory, StringComparison.InvariantCultureIgnoreCase);
|
||||
var idMatch = id == null || activeId == null || id.Equals(activeId);
|
||||
return categoryMatch && idMatch;
|
||||
}
|
||||
|
||||
public static bool IsActiveCategory<T>(this ViewDataDictionary viewData, T category, object id = null)
|
||||
public static string IsActiveCategory<T>(this ViewDataDictionary viewData, T category, object id = null)
|
||||
{
|
||||
return IsActiveCategory(viewData, category.ToString(), id);
|
||||
}
|
||||
|
||||
public static bool IsActivePage(this ViewDataDictionary viewData, string page, string category, object id = null)
|
||||
public static string IsActiveCategory(this ViewDataDictionary viewData, string category, object id = null)
|
||||
{
|
||||
if (!viewData.ContainsKey(ACTIVE_PAGE_KEY)) return false;
|
||||
if (!viewData.ContainsKey(ACTIVE_CATEGORY_KEY))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var activeId = viewData[ACTIVE_ID_KEY];
|
||||
var activeCategory = viewData[ACTIVE_CATEGORY_KEY]?.ToString();
|
||||
var categoryMatch = category.Equals(activeCategory, StringComparison.InvariantCultureIgnoreCase);
|
||||
var idMatch = id == null || activeId == null || id.Equals(activeId);
|
||||
return categoryMatch && idMatch ? ActivePageClass : null;
|
||||
}
|
||||
|
||||
public static string IsActivePage<T>(this ViewDataDictionary viewData, T page, object id = null)
|
||||
where T : IConvertible
|
||||
{
|
||||
return IsActivePage(viewData, page.ToString(), page.GetType().ToString(), id);
|
||||
}
|
||||
|
||||
public static string IsActivePage<T>(this ViewDataDictionary viewData, IEnumerable<T> pages, object id = null)
|
||||
where T : IConvertible
|
||||
{
|
||||
return pages.Any(page => IsActivePage(viewData, page.ToString(), page.GetType().ToString(), id) == ActivePageClass)
|
||||
? ActivePageClass
|
||||
: null;
|
||||
}
|
||||
|
||||
public static string IsActivePage(this ViewDataDictionary viewData, string page, string category, object id = null)
|
||||
{
|
||||
if (!viewData.ContainsKey(ACTIVE_PAGE_KEY))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var activeId = viewData[ACTIVE_ID_KEY];
|
||||
var activePage = viewData[ACTIVE_PAGE_KEY]?.ToString();
|
||||
var activeCategory = viewData[ACTIVE_CATEGORY_KEY]?.ToString();
|
||||
var categoryAndPageMatch = page.Equals(activePage, StringComparison.InvariantCultureIgnoreCase) &&
|
||||
(category == null || activeCategory != null && activeCategory.Equals(category, StringComparison.InvariantCultureIgnoreCase));
|
||||
var categoryAndPageMatch = (category == null || activeCategory.Equals(category, StringComparison.InvariantCultureIgnoreCase)) && page.Equals(activePage, StringComparison.InvariantCultureIgnoreCase);
|
||||
var idMatch = id == null || activeId == null || id.Equals(activeId);
|
||||
return categoryAndPageMatch && idMatch;
|
||||
}
|
||||
|
||||
public static bool IsActivePage<T>(this ViewDataDictionary viewData, IEnumerable<T> pages, object id = null)
|
||||
where T : IConvertible
|
||||
{
|
||||
return pages.Any(page => ActivePageClass(viewData, page.ToString(), page.GetType().ToString(), id) == ACTIVE_CLASS);
|
||||
}
|
||||
|
||||
public static string ActiveCategoryClass<T>(this ViewDataDictionary viewData, T category, object id = null)
|
||||
{
|
||||
return ActiveCategoryClass(viewData, category.ToString(), id);
|
||||
}
|
||||
|
||||
public static string ActiveCategoryClass(this ViewDataDictionary viewData, string category, object id = null)
|
||||
{
|
||||
return IsActiveCategory(viewData, category, id) ? ACTIVE_CLASS : null;
|
||||
}
|
||||
|
||||
public static string ActivePageClass<T>(this ViewDataDictionary viewData, T page, object id = null)
|
||||
where T : IConvertible
|
||||
{
|
||||
return ActivePageClass(viewData, page.ToString(), page.GetType().ToString(), id);
|
||||
}
|
||||
|
||||
public static string ActivePageClass(this ViewDataDictionary viewData, string page, string category, object id = null)
|
||||
{
|
||||
return IsActivePage(viewData, page, category, id) ? ACTIVE_CLASS : null;
|
||||
}
|
||||
|
||||
public static string ActivePageClass<T>(this ViewDataDictionary viewData, IEnumerable<T> pages, object id = null) where T : IConvertible
|
||||
{
|
||||
return IsActivePage(viewData, pages, id) ? ACTIVE_CLASS : null;
|
||||
return categoryAndPageMatch && idMatch ? ActivePageClass : null;
|
||||
}
|
||||
|
||||
public static HtmlString ToBrowserDate(this DateTimeOffset date, string netFormat, string jsDateFormat = "short", string jsTimeFormat = "short")
|
||||
|
@ -2,6 +2,7 @@ namespace BTCPayServer.Abstractions.Models
|
||||
{
|
||||
public class DatabaseOptions
|
||||
{
|
||||
public DatabaseType DatabaseType { get; set; }
|
||||
public string ConnectionString { get; set; }
|
||||
}
|
||||
}
|
||||
|
9
BTCPayServer.Abstractions/Models/DatabaseType.cs
Normal file
9
BTCPayServer.Abstractions/Models/DatabaseType.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace BTCPayServer.Abstractions.Models
|
||||
{
|
||||
public enum DatabaseType
|
||||
{
|
||||
Sqlite,
|
||||
Postgres,
|
||||
MySQL,
|
||||
}
|
||||
}
|
@ -31,7 +31,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.5.1" />
|
||||
<PackageReference Include="NBitcoin" Version="7.0.37" />
|
||||
<PackageReference Include="NBitcoin" Version="7.0.34" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -1,44 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<ApiKeyData> GetCurrentAPIKeyInfo(CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<ApiKeyData>("api/v1/api-keys/current", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<ApiKeyData> GetCurrentAPIKeyInfo(CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/api-keys/current"), token);
|
||||
return await HandleResponse<ApiKeyData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<ApiKeyData> CreateAPIKey(CreateApiKeyRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<ApiKeyData>("api/v1/api-keys", request, HttpMethod.Post, token);
|
||||
}
|
||||
public virtual async Task<ApiKeyData> CreateAPIKey(CreateApiKeyRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/api-keys", bodyPayload: request, method: HttpMethod.Post), token);
|
||||
return await HandleResponse<ApiKeyData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<ApiKeyData> CreateAPIKey(string userId, CreateApiKeyRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<ApiKeyData>($"api/v1/users/{userId}/api-keys", request, HttpMethod.Post, token);
|
||||
}
|
||||
public virtual async Task<ApiKeyData> CreateAPIKey(string userId, CreateApiKeyRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{userId}/api-keys",
|
||||
bodyPayload: request, method: HttpMethod.Post), token);
|
||||
return await HandleResponse<ApiKeyData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task RevokeCurrentAPIKeyInfo(CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest("api/v1/api-keys/current", null, HttpMethod.Delete, token);
|
||||
}
|
||||
public virtual async Task RevokeCurrentAPIKeyInfo(CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/api-keys/current", null, HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task RevokeAPIKey(string apikey, CancellationToken token = default)
|
||||
{
|
||||
if (apikey == null) throw new ArgumentNullException(nameof(apikey));
|
||||
await SendHttpRequest($"api/v1/api-keys/{apikey}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
public virtual async Task RevokeAPIKey(string userId, string apikey, CancellationToken token = default)
|
||||
{
|
||||
if (apikey == null) throw new ArgumentNullException(nameof(apikey));
|
||||
if (userId is null) throw new ArgumentNullException(nameof(userId));
|
||||
await SendHttpRequest($"api/v1/users/{userId}/api-keys/{apikey}", null, HttpMethod.Delete, token);
|
||||
public virtual async Task RevokeAPIKey(string apikey, CancellationToken token = default)
|
||||
{
|
||||
if (apikey == null)
|
||||
throw new ArgumentNullException(nameof(apikey));
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/api-keys/{apikey}", null, HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
public virtual async Task RevokeAPIKey(string userId, string apikey, CancellationToken token = default)
|
||||
{
|
||||
if (apikey == null)
|
||||
throw new ArgumentNullException(nameof(apikey));
|
||||
if (userId is null)
|
||||
throw new ArgumentNullException(nameof(userId));
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{userId}/api-keys/{apikey}", null, HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,63 +4,100 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<PointOfSaleAppData> CreatePointOfSaleApp(string storeId,
|
||||
PointOfSaleAppRequest request, CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<PointOfSaleAppData>($"api/v1/stores/{storeId}/apps/pos", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<CrowdfundAppData> CreateCrowdfundApp(string storeId,
|
||||
CrowdfundAppRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<CrowdfundAppData>($"api/v1/stores/{storeId}/apps/crowdfund", request, HttpMethod.Post, token);
|
||||
}
|
||||
public virtual async Task<PointOfSaleAppData> CreatePointOfSaleApp(string storeId,
|
||||
CreatePointOfSaleAppRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/apps/pos", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<PointOfSaleAppData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<PointOfSaleAppData> UpdatePointOfSaleApp(string appId,
|
||||
PointOfSaleAppRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<PointOfSaleAppData>($"api/v1/apps/pos/{appId}", request, HttpMethod.Put, token);
|
||||
}
|
||||
public virtual async Task<CrowdfundAppData> CreateCrowdfundApp(string storeId,
|
||||
CreateCrowdfundAppRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/apps/crowdfund", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<CrowdfundAppData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<AppBaseData> GetApp(string appId, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
||||
return await SendHttpRequest<AppBaseData>($"api/v1/apps/{appId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<PointOfSaleAppData> UpdatePointOfSaleApp(string appId,
|
||||
CreatePointOfSaleAppRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/apps/pos/{appId}", bodyPayload: request,
|
||||
method: HttpMethod.Put), token);
|
||||
return await HandleResponse<PointOfSaleAppData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<AppBaseData[]> GetAllApps(string storeId, CancellationToken token = default)
|
||||
{
|
||||
if (storeId == null) throw new ArgumentNullException(nameof(storeId));
|
||||
return await SendHttpRequest<AppBaseData[]>($"api/v1/stores/{storeId}/apps", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<AppDataBase> GetApp(string appId, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null)
|
||||
throw new ArgumentNullException(nameof(appId));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/apps/{appId}",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<AppDataBase>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<AppBaseData[]> GetAllApps(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<AppBaseData[]>("api/v1/apps", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<AppDataBase[]> GetAllApps(string storeId, CancellationToken token = default)
|
||||
{
|
||||
if (storeId == null)
|
||||
throw new ArgumentNullException(nameof(storeId));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/apps",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<AppDataBase[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<PointOfSaleAppData> GetPosApp(string appId, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
||||
return await SendHttpRequest<PointOfSaleAppData>($"api/v1/apps/pos/{appId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<AppDataBase[]> GetAllApps(CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/apps",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<AppDataBase[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<CrowdfundAppData> GetCrowdfundApp(string appId, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
||||
return await SendHttpRequest<CrowdfundAppData>($"api/v1/apps/crowdfund/{appId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<PointOfSaleAppData> GetPosApp(string appId, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null)
|
||||
throw new ArgumentNullException(nameof(appId));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/apps/pos/{appId}",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<PointOfSaleAppData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task DeleteApp(string appId, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
||||
await SendHttpRequest($"api/v1/apps/{appId}", null, HttpMethod.Delete, token);
|
||||
public virtual async Task<CrowdfundAppData> GetCrowdfundApp(string appId, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null)
|
||||
throw new ArgumentNullException(nameof(appId));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/apps/crowdfund/{appId}",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<CrowdfundAppData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task DeleteApp(string appId, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null)
|
||||
throw new ArgumentNullException(nameof(appId));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/apps/{appId}",
|
||||
method: HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public static Uri GenerateAuthorizeUri(Uri btcpayHost, string[] permissions, bool strict = true,
|
||||
bool selectiveStores = false, (string ApplicationIdentifier, Uri Redirect) applicationDetails = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
var result = new UriBuilder(btcpayHost) { Path = "api-keys/authorize" };
|
||||
AppendPayloadToQuery(result,
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{"strict", strict}, {"selectiveStores", selectiveStores}, {"permissions", permissions}
|
||||
});
|
||||
|
||||
if (applicationDetails.Redirect != null)
|
||||
public static Uri GenerateAuthorizeUri(Uri btcpayHost, string[] permissions, bool strict = true,
|
||||
bool selectiveStores = false, (string ApplicationIdentifier, Uri Redirect) applicationDetails = default)
|
||||
{
|
||||
AppendPayloadToQuery(result, new KeyValuePair<string, object>("redirect", applicationDetails.Redirect));
|
||||
if (!string.IsNullOrEmpty(applicationDetails.ApplicationIdentifier))
|
||||
{
|
||||
AppendPayloadToQuery(result, new KeyValuePair<string, object>("applicationIdentifier", applicationDetails.ApplicationIdentifier));
|
||||
}
|
||||
}
|
||||
var result = new UriBuilder(btcpayHost);
|
||||
result.Path = "api-keys/authorize";
|
||||
|
||||
return result.Uri;
|
||||
AppendPayloadToQuery(result,
|
||||
new Dictionary<string, object>()
|
||||
{
|
||||
{"strict", strict}, {"selectiveStores", selectiveStores}, {"permissions", permissions}
|
||||
});
|
||||
|
||||
if (applicationDetails.Redirect != null)
|
||||
{
|
||||
AppendPayloadToQuery(result, new KeyValuePair<string, object>("redirect", applicationDetails.Redirect));
|
||||
if (!string.IsNullOrEmpty(applicationDetails.ApplicationIdentifier))
|
||||
{
|
||||
AppendPayloadToQuery(result, new KeyValuePair<string, object>("applicationIdentifier", applicationDetails.ApplicationIdentifier));
|
||||
}
|
||||
}
|
||||
|
||||
return result.Uri;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<ApiHealthData> GetHealth(CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<ApiHealthData>("api/v1/health", null, HttpMethod.Get, token);
|
||||
public virtual async Task<ApiHealthData> GetHealth(CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/health"), token);
|
||||
return await HandleResponse<ApiHealthData>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,95 +7,139 @@ using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<IEnumerable<InvoiceData>> GetInvoices(string storeId, string[] orderId = null,
|
||||
InvoiceStatus[] status = null,
|
||||
DateTimeOffset? startDate = null,
|
||||
DateTimeOffset? endDate = null,
|
||||
string textSearch = null,
|
||||
bool includeArchived = false,
|
||||
int? skip = null,
|
||||
int? take = null,
|
||||
CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object> { { nameof(includeArchived), includeArchived } };
|
||||
if (startDate is { } s)
|
||||
queryPayload.Add(nameof(startDate), Utils.DateTimeToUnixTime(s));
|
||||
if (endDate is { } e)
|
||||
queryPayload.Add(nameof(endDate), Utils.DateTimeToUnixTime(e));
|
||||
if (orderId != null)
|
||||
queryPayload.Add(nameof(orderId), orderId);
|
||||
if (textSearch != null)
|
||||
queryPayload.Add(nameof(textSearch), textSearch);
|
||||
if (status != null)
|
||||
queryPayload.Add(nameof(status), status.Select(s => s.ToString().ToLower()).ToArray());
|
||||
if (skip != null)
|
||||
queryPayload.Add(nameof(skip), skip);
|
||||
if (take != null)
|
||||
queryPayload.Add(nameof(take), take);
|
||||
public virtual async Task<IEnumerable<InvoiceData>> GetInvoices(string storeId, string[] orderId = null,
|
||||
InvoiceStatus[] status = null,
|
||||
DateTimeOffset? startDate = null,
|
||||
DateTimeOffset? endDate = null,
|
||||
string textSearch = null,
|
||||
bool includeArchived = false,
|
||||
int? skip = null,
|
||||
int? take = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
Dictionary<string, object> queryPayload = new Dictionary<string, object>();
|
||||
queryPayload.Add(nameof(includeArchived), includeArchived);
|
||||
|
||||
return await SendHttpRequest<IEnumerable<InvoiceData>>($"api/v1/stores/{storeId}/invoices", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
if (startDate is DateTimeOffset s)
|
||||
queryPayload.Add(nameof(startDate), Utils.DateTimeToUnixTime(s));
|
||||
|
||||
public virtual async Task<InvoiceData> GetInvoice(string storeId, string invoiceId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/invoices/{invoiceId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<InvoicePaymentMethodDataModel[]> GetInvoicePaymentMethods(string storeId, string invoiceId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<InvoicePaymentMethodDataModel[]>($"api/v1/stores/{storeId}/invoices/{invoiceId}/payment-methods", null, HttpMethod.Get, token);
|
||||
}
|
||||
if (endDate is DateTimeOffset e)
|
||||
queryPayload.Add(nameof(endDate), Utils.DateTimeToUnixTime(e));
|
||||
|
||||
public virtual async Task ArchiveInvoice(string storeId, string invoiceId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
if (orderId != null)
|
||||
queryPayload.Add(nameof(orderId), orderId);
|
||||
if (textSearch != null)
|
||||
queryPayload.Add(nameof(textSearch), textSearch);
|
||||
if (status != null)
|
||||
queryPayload.Add(nameof(status), status.Select(s => s.ToString().ToLower()).ToArray());
|
||||
|
||||
public virtual async Task<InvoiceData> CreateInvoice(string storeId,
|
||||
CreateInvoiceRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/invoices", request, HttpMethod.Post, token);
|
||||
}
|
||||
if (skip != null)
|
||||
{
|
||||
queryPayload.Add(nameof(skip), skip);
|
||||
}
|
||||
|
||||
public virtual async Task<InvoiceData> UpdateInvoice(string storeId, string invoiceId,
|
||||
UpdateInvoiceRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/invoices/{invoiceId}", request, HttpMethod.Put, token);
|
||||
}
|
||||
if (take != null)
|
||||
{
|
||||
queryPayload.Add(nameof(take), take);
|
||||
}
|
||||
|
||||
public virtual async Task<InvoiceData> MarkInvoiceStatus(string storeId, string invoiceId,
|
||||
MarkInvoiceStatusRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
if (request.Status != InvoiceStatus.Settled && request.Status != InvoiceStatus.Invalid) throw new ArgumentOutOfRangeException(nameof(request.Status), "Status can only be Invalid or Complete");
|
||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/invoices/{invoiceId}/status", request, HttpMethod.Post, token);
|
||||
}
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/invoices",
|
||||
queryPayload), token);
|
||||
return await HandleResponse<IEnumerable<InvoiceData>>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<InvoiceData> UnarchiveInvoice(string storeId, string invoiceId, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/invoices/{invoiceId}/unarchive", null, HttpMethod.Post, token);
|
||||
}
|
||||
public virtual async Task<InvoiceData> GetInvoice(string storeId, string invoiceId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}"), token);
|
||||
return await HandleResponse<InvoiceData>(response);
|
||||
}
|
||||
public virtual async Task<InvoicePaymentMethodDataModel[]> GetInvoicePaymentMethods(string storeId, string invoiceId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}/payment-methods"), token);
|
||||
return await HandleResponse<InvoicePaymentMethodDataModel[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task ActivateInvoicePaymentMethod(string storeId, string invoiceId, string paymentMethod, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}/payment-methods/{paymentMethod}/activate", null, HttpMethod.Post, token);
|
||||
}
|
||||
public virtual async Task ArchiveInvoice(string storeId, string invoiceId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}",
|
||||
method: HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<PullPaymentData> RefundInvoice(
|
||||
string storeId,
|
||||
string invoiceId,
|
||||
RefundInvoiceRequest request,
|
||||
CancellationToken token = default
|
||||
)
|
||||
{
|
||||
return await SendHttpRequest<PullPaymentData>($"api/v1/stores/{storeId}/invoices/{invoiceId}/refund", request, HttpMethod.Post, token);
|
||||
public virtual async Task<InvoiceData> CreateInvoice(string storeId,
|
||||
CreateInvoiceRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/invoices", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<InvoiceData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<InvoiceData> UpdateInvoice(string storeId, string invoiceId,
|
||||
UpdateInvoiceRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}", bodyPayload: request,
|
||||
method: HttpMethod.Put), token);
|
||||
return await HandleResponse<InvoiceData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<InvoiceData> MarkInvoiceStatus(string storeId, string invoiceId,
|
||||
MarkInvoiceStatusRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
if (request.Status != InvoiceStatus.Settled && request.Status != InvoiceStatus.Invalid)
|
||||
throw new ArgumentOutOfRangeException(nameof(request.Status), "Status can only be Invalid or Complete");
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}/status", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<InvoiceData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<InvoiceData> UnarchiveInvoice(string storeId, string invoiceId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}/unarchive",
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<InvoiceData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task ActivateInvoicePaymentMethod(string storeId, string invoiceId, string paymentMethod, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}/payment-methods/{paymentMethod}/activate",
|
||||
method: HttpMethod.Post), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<PullPaymentData> RefundInvoice(
|
||||
string storeId,
|
||||
string invoiceId,
|
||||
RefundInvoiceRequest request,
|
||||
CancellationToken token = default
|
||||
)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}/refund", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<PullPaymentData>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<IEnumerable<LNURLPayPaymentMethodData>>
|
||||
GetStoreLNURLPayPaymentMethods(string storeId, bool? enabled = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var query = new Dictionary<string, object>();
|
||||
if (enabled != null)
|
||||
{
|
||||
query.Add(nameof(enabled), enabled);
|
||||
}
|
||||
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LNURLPay",
|
||||
query), token);
|
||||
return await HandleResponse<IEnumerable<LNURLPayPaymentMethodData>>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LNURLPayPaymentMethodData> GetStoreLNURLPayPaymentMethod(
|
||||
string storeId,
|
||||
string cryptoCode, CancellationToken token = default)
|
||||
{
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LNURLPay/{cryptoCode}"), token);
|
||||
return await HandleResponse<LNURLPayPaymentMethodData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveStoreLNURLPayPaymentMethod(string storeId,
|
||||
string cryptoCode, CancellationToken token = default)
|
||||
{
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LNURLPay/{cryptoCode}",
|
||||
method: HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LNURLPayPaymentMethodData> UpdateStoreLNURLPayPaymentMethod(
|
||||
string storeId,
|
||||
string cryptoCode, LNURLPayPaymentMethodData paymentMethod,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LNURLPay/{cryptoCode}",
|
||||
bodyPayload: paymentMethod, method: HttpMethod.Put), token);
|
||||
return await HandleResponse<LNURLPayPaymentMethodData>(response);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,101 +5,142 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<LightningNodeInformationData> GetLightningNodeInfo(string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<LightningNodeInformationData>($"api/v1/server/lightning/{cryptoCode}/info", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<LightningNodeBalanceData>($"api/v1/server/lightning/{cryptoCode}/balance", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task ConnectToLightningNode(string cryptoCode, ConnectToNodeRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
await SendHttpRequest($"api/v1/server/lightning/{cryptoCode}/connect", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<LightningChannelData>> GetLightningNodeChannels(string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<LightningChannelData>>($"api/v1/server/lightning/{cryptoCode}/channels", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task OpenLightningChannel(string cryptoCode, OpenLightningChannelRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/server/lightning/{cryptoCode}/channels", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<string> GetLightningDepositAddress(string cryptoCode, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<string>($"api/v1/server/lightning/{cryptoCode}/address", null, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData> PayLightningInvoice(string cryptoCode, PayLightningInvoiceRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<LightningPaymentData>($"api/v1/server/lightning/{cryptoCode}/invoices/pay", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData> GetLightningPayment(string cryptoCode,
|
||||
string paymentHash, CancellationToken token = default)
|
||||
{
|
||||
if (paymentHash == null) throw new ArgumentNullException(nameof(paymentHash));
|
||||
return await SendHttpRequest<LightningPaymentData>($"api/v1/server/lightning/{cryptoCode}/payments/{paymentHash}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData> GetLightningInvoice(string cryptoCode,
|
||||
string invoiceId, CancellationToken token = default)
|
||||
{
|
||||
if (invoiceId == null) throw new ArgumentNullException(nameof(invoiceId));
|
||||
return await SendHttpRequest<LightningInvoiceData>($"api/v1/server/lightning/{cryptoCode}/invoices/{invoiceId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string cryptoCode,
|
||||
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (pendingOnly is bool v)
|
||||
public virtual async Task<LightningNodeInformationData> GetLightningNodeInfo(string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
queryPayload.Add("pendingOnly", v.ToString());
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/info",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningNodeInformationData>(response);
|
||||
}
|
||||
if (offsetIndex is > 0)
|
||||
{
|
||||
queryPayload.Add("offsetIndex", offsetIndex);
|
||||
}
|
||||
return await SendHttpRequest<LightningInvoiceData[]>($"api/v1/server/lightning/{cryptoCode}/invoices", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData[]> GetLightningPayments(string cryptoCode,
|
||||
bool? includePending = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (includePending is bool v)
|
||||
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
queryPayload.Add("includePending", v.ToString());
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/balance",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningNodeBalanceData>(response);
|
||||
}
|
||||
if (offsetIndex is > 0)
|
||||
{
|
||||
queryPayload.Add("offsetIndex", offsetIndex);
|
||||
}
|
||||
return await SendHttpRequest<LightningPaymentData[]>($"api/v1/server/lightning/{cryptoCode}/payments", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string cryptoCode, CreateLightningInvoiceRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<LightningInvoiceData>($"api/v1/server/lightning/{cryptoCode}/invoices", request, HttpMethod.Post, token);
|
||||
public virtual async Task ConnectToLightningNode(string cryptoCode, ConnectToNodeRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/connect", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<LightningChannelData>> GetLightningNodeChannels(string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/channels",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<IEnumerable<LightningChannelData>>(response);
|
||||
}
|
||||
|
||||
public virtual async Task OpenLightningChannel(string cryptoCode, OpenLightningChannelRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/channels", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<string> GetLightningDepositAddress(string cryptoCode, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/address", method: HttpMethod.Post), token);
|
||||
return await HandleResponse<string>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData> PayLightningInvoice(string cryptoCode, PayLightningInvoiceRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/invoices/pay", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<LightningPaymentData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData> GetLightningPayment(string cryptoCode,
|
||||
string paymentHash, CancellationToken token = default)
|
||||
{
|
||||
if (paymentHash == null)
|
||||
throw new ArgumentNullException(nameof(paymentHash));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/payments/{paymentHash}",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningPaymentData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData> GetLightningInvoice(string cryptoCode,
|
||||
string invoiceId, CancellationToken token = default)
|
||||
{
|
||||
if (invoiceId == null)
|
||||
throw new ArgumentNullException(nameof(invoiceId));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/invoices/{invoiceId}",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningInvoiceData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string cryptoCode,
|
||||
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (pendingOnly is bool v)
|
||||
{
|
||||
queryPayload.Add("pendingOnly", v.ToString());
|
||||
}
|
||||
if (offsetIndex is > 0)
|
||||
{
|
||||
queryPayload.Add("offsetIndex", offsetIndex);
|
||||
}
|
||||
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/invoices", queryPayload), token);
|
||||
return await HandleResponse<LightningInvoiceData[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData[]> GetLightningPayments(string cryptoCode,
|
||||
bool? includePending = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (includePending is bool v)
|
||||
{
|
||||
queryPayload.Add("includePending", v.ToString());
|
||||
}
|
||||
if (offsetIndex is > 0)
|
||||
{
|
||||
queryPayload.Add("offsetIndex", offsetIndex);
|
||||
}
|
||||
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/payments", queryPayload), token);
|
||||
return await HandleResponse<LightningPaymentData[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string cryptoCode, CreateLightningInvoiceRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/invoices", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<LightningInvoiceData>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,102 +5,144 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<LightningNodeInformationData> GetLightningNodeInfo(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<LightningNodeInformationData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/info", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<LightningNodeBalanceData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/balance", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task ConnectToLightningNode(string storeId, string cryptoCode, ConnectToNodeRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/connect", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<LightningChannelData>> GetLightningNodeChannels(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<LightningChannelData>>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/channels", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task OpenLightningChannel(string storeId, string cryptoCode, OpenLightningChannelRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/channels", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<string> GetLightningDepositAddress(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<string>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/address", null, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData> PayLightningInvoice(string storeId, string cryptoCode, PayLightningInvoiceRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<LightningPaymentData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices/pay", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData> GetLightningPayment(string storeId, string cryptoCode,
|
||||
string paymentHash, CancellationToken token = default)
|
||||
{
|
||||
if (paymentHash == null) throw new ArgumentNullException(nameof(paymentHash));
|
||||
return await SendHttpRequest<LightningPaymentData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/payments/{paymentHash}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData> GetLightningInvoice(string storeId, string cryptoCode,
|
||||
string invoiceId, CancellationToken token = default)
|
||||
{
|
||||
if (invoiceId == null) throw new ArgumentNullException(nameof(invoiceId));
|
||||
return await SendHttpRequest<LightningInvoiceData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices/{invoiceId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string storeId, string cryptoCode,
|
||||
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (pendingOnly is bool v)
|
||||
public virtual async Task<LightningNodeInformationData> GetLightningNodeInfo(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
queryPayload.Add("pendingOnly", v.ToString());
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/info",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningNodeInformationData>(response);
|
||||
}
|
||||
if (offsetIndex is > 0)
|
||||
{
|
||||
queryPayload.Add("offsetIndex", offsetIndex);
|
||||
}
|
||||
return await SendHttpRequest<LightningInvoiceData[]>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData[]> GetLightningPayments(string storeId, string cryptoCode,
|
||||
bool? includePending = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (includePending is bool v)
|
||||
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
queryPayload.Add("includePending", v.ToString());
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/balance",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningNodeBalanceData>(response);
|
||||
}
|
||||
if (offsetIndex is > 0)
|
||||
{
|
||||
queryPayload.Add("offsetIndex", offsetIndex);
|
||||
}
|
||||
return await SendHttpRequest<LightningPaymentData[]>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/payments", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string storeId, string cryptoCode,
|
||||
CreateLightningInvoiceRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<LightningInvoiceData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices", request, HttpMethod.Post, token);
|
||||
public virtual async Task ConnectToLightningNode(string storeId, string cryptoCode, ConnectToNodeRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/connect", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<LightningChannelData>> GetLightningNodeChannels(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/channels",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<IEnumerable<LightningChannelData>>(response);
|
||||
}
|
||||
|
||||
public virtual async Task OpenLightningChannel(string storeId, string cryptoCode, OpenLightningChannelRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/channels", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<string> GetLightningDepositAddress(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/address", method: HttpMethod.Post),
|
||||
token);
|
||||
return await HandleResponse<string>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData> PayLightningInvoice(string storeId, string cryptoCode, PayLightningInvoiceRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices/pay", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<LightningPaymentData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData> GetLightningPayment(string storeId, string cryptoCode,
|
||||
string paymentHash, CancellationToken token = default)
|
||||
{
|
||||
if (paymentHash == null)
|
||||
throw new ArgumentNullException(nameof(paymentHash));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/payments/{paymentHash}",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningPaymentData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData> GetLightningInvoice(string storeId, string cryptoCode,
|
||||
string invoiceId, CancellationToken token = default)
|
||||
{
|
||||
if (invoiceId == null)
|
||||
throw new ArgumentNullException(nameof(invoiceId));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices/{invoiceId}",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningInvoiceData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string storeId, string cryptoCode,
|
||||
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (pendingOnly is bool v)
|
||||
{
|
||||
queryPayload.Add("pendingOnly", v.ToString());
|
||||
}
|
||||
if (offsetIndex is > 0)
|
||||
{
|
||||
queryPayload.Add("offsetIndex", offsetIndex);
|
||||
}
|
||||
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices", queryPayload), token);
|
||||
return await HandleResponse<LightningInvoiceData[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData[]> GetLightningPayments(string storeId, string cryptoCode,
|
||||
bool? includePending = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (includePending is bool v)
|
||||
{
|
||||
queryPayload.Add("includePending", v.ToString());
|
||||
}
|
||||
if (offsetIndex is > 0)
|
||||
{
|
||||
queryPayload.Add("offsetIndex", offsetIndex);
|
||||
}
|
||||
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/payments", queryPayload), token);
|
||||
return await HandleResponse<LightningPaymentData[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string storeId, string cryptoCode,
|
||||
CreateLightningInvoiceRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<LightningInvoiceData>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,32 +3,46 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<LightningAddressData[]> GetStoreLightningAddresses(string storeId,
|
||||
CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<LightningAddressData[]>($"api/v1/stores/{storeId}/lightning-addresses", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<LightningAddressData[]> GetStoreLightningAddresses(string storeId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning-addresses",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningAddressData[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningAddressData> GetStoreLightningAddress(string storeId, string username,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<LightningAddressData>($"api/v1/stores/{storeId}/lightning-addresses/{username}", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<LightningAddressData> GetStoreLightningAddress(string storeId, string username,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning-addresses/{username}",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningAddressData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveStoreLightningAddress(string storeId, string username,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/lightning-addresses/{username}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
public virtual async Task RemoveStoreLightningAddress(string storeId, string username,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning-addresses/{username}",
|
||||
method: HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningAddressData> AddOrUpdateStoreLightningAddress(string storeId,
|
||||
string username, LightningAddressData data,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<LightningAddressData>($"api/v1/stores/{storeId}/lightning-addresses/{username}", data, HttpMethod.Post, token);
|
||||
public virtual async Task<LightningAddressData> AddOrUpdateStoreLightningAddress(string storeId,
|
||||
string username, LightningAddressData data,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning-addresses/{username}",
|
||||
method: HttpMethod.Post, bodyPayload: data), token);
|
||||
|
||||
return await HandleResponse<LightningAddressData>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<IEnumerable<LightningNetworkPaymentMethodData>>
|
||||
GetStoreLightningNetworkPaymentMethods(string storeId, bool? enabled = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var query = new Dictionary<string, object>();
|
||||
if (enabled != null)
|
||||
{
|
||||
query.Add(nameof(enabled), enabled);
|
||||
}
|
||||
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LightningNetwork",
|
||||
query), token);
|
||||
return await HandleResponse<IEnumerable<LightningNetworkPaymentMethodData>>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningNetworkPaymentMethodData> GetStoreLightningNetworkPaymentMethod(
|
||||
string storeId,
|
||||
string cryptoCode, CancellationToken token = default)
|
||||
{
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LightningNetwork/{cryptoCode}"), token);
|
||||
return await HandleResponse<LightningNetworkPaymentMethodData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveStoreLightningNetworkPaymentMethod(string storeId,
|
||||
string cryptoCode, CancellationToken token = default)
|
||||
{
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LightningNetwork/{cryptoCode}",
|
||||
method: HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningNetworkPaymentMethodData> UpdateStoreLightningNetworkPaymentMethod(
|
||||
string storeId,
|
||||
string cryptoCode, UpdateLightningNetworkPaymentMethodRequest paymentMethod,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LightningNetwork/{cryptoCode}",
|
||||
bodyPayload: paymentMethod, method: HttpMethod.Put), token);
|
||||
return await HandleResponse<LightningNetworkPaymentMethodData>(response);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +1,23 @@
|
||||
using System.Net.Http;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<PermissionMetadata[]> GetPermissionMetadata(CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<PermissionMetadata[]>("misc/permissions", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<Language[]> GetAvailableLanguages(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<Language[]>("misc/lang", null, HttpMethod.Get, token);
|
||||
public virtual async Task<PermissionMetadata[]> GetPermissionMetadata(CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest("misc/permissions"), token);
|
||||
return await HandleResponse<PermissionMetadata[]>(response);
|
||||
}
|
||||
public virtual async Task<Language[]> GetAvailableLanguages(CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest("misc/lang"), token);
|
||||
return await HandleResponse<Language[]>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<IEnumerable<NotificationData>> GetNotifications(bool? seen = null, int? skip = null,
|
||||
int? take = null, CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (seen != null)
|
||||
queryPayload.Add(nameof(seen), seen);
|
||||
if (skip != null)
|
||||
queryPayload.Add(nameof(skip), skip);
|
||||
if (take != null)
|
||||
queryPayload.Add(nameof(take), take);
|
||||
return await SendHttpRequest<IEnumerable<NotificationData>>("api/v1/users/me/notifications", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<IEnumerable<NotificationData>> GetNotifications(bool? seen = null, int? skip = null,
|
||||
int? take = null, CancellationToken token = default)
|
||||
{
|
||||
Dictionary<string, object> queryPayload = new Dictionary<string, object>();
|
||||
|
||||
public virtual async Task<NotificationData> GetNotification(string notificationId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<NotificationData>($"api/v1/users/me/notifications/{notificationId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
if (seen != null)
|
||||
queryPayload.Add(nameof(seen), seen);
|
||||
if (skip != null)
|
||||
queryPayload.Add(nameof(skip), skip);
|
||||
if (take != null)
|
||||
queryPayload.Add(nameof(take), take);
|
||||
|
||||
public virtual async Task<NotificationData> UpdateNotification(string notificationId, bool? seen,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<NotificationData>($"api/v1/users/me/notifications/{notificationId}", new UpdateNotification { Seen = seen }, HttpMethod.Put, token);
|
||||
}
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/users/me/notifications",
|
||||
queryPayload), token);
|
||||
|
||||
public virtual async Task<NotificationSettingsData> GetNotificationSettings(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<NotificationSettingsData>("api/v1/users/me/notification-settings", null, HttpMethod.Get, token);
|
||||
}
|
||||
return await HandleResponse<IEnumerable<NotificationData>>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<NotificationSettingsData> UpdateNotificationSettings(UpdateNotificationSettingsRequest request, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<NotificationSettingsData>("api/v1/users/me/notification-settings", request, HttpMethod.Put, token);
|
||||
}
|
||||
public virtual async Task<NotificationData> GetNotification(string notificationId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/users/me/notifications/{notificationId}"), token);
|
||||
return await HandleResponse<NotificationData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveNotification(string notificationId, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/users/me/notifications/{notificationId}", null, HttpMethod.Delete, token);
|
||||
public virtual async Task<NotificationData> UpdateNotification(string notificationId, bool? seen,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/users/me/notifications/{notificationId}",
|
||||
method: HttpMethod.Put, bodyPayload: new UpdateNotification() { Seen = seen }), token);
|
||||
return await HandleResponse<NotificationData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveNotification(string notificationId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/users/me/notifications/{notificationId}",
|
||||
method: HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,37 +3,92 @@ using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<OnChainPaymentMethodPreviewResultData>
|
||||
PreviewProposedStoreOnChainPaymentMethodAddresses(
|
||||
string storeId, string paymentMethodId, string derivationScheme, int offset = 0,
|
||||
int amount = 10,
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<IEnumerable<OnChainPaymentMethodData>> GetStoreOnChainPaymentMethods(string storeId,
|
||||
bool? enabled = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<UpdatePaymentMethodRequest, OnChainPaymentMethodPreviewResultData>($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}/preview",
|
||||
new Dictionary<string, object> { { "offset", offset }, { "amount", amount } },
|
||||
new UpdatePaymentMethodRequest { Config = JValue.CreateString(derivationScheme) },
|
||||
HttpMethod.Post, token);
|
||||
}
|
||||
{
|
||||
var query = new Dictionary<string, object>();
|
||||
if (enabled != null)
|
||||
{
|
||||
query.Add(nameof(enabled), enabled);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainPaymentMethodPreviewResultData> PreviewStoreOnChainPaymentMethodAddresses(
|
||||
string storeId, string paymentMethodId, int offset = 0, int amount = 10,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<OnChainPaymentMethodPreviewResultData>($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}/preview",
|
||||
new Dictionary<string, object> { { "offset", offset }, { "amount", amount } }, HttpMethod.Get, token);
|
||||
}
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain",
|
||||
query), token);
|
||||
return await HandleResponse<IEnumerable<OnChainPaymentMethodData>>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<GenerateOnChainWalletResponse> GenerateOnChainWallet(string storeId,
|
||||
string paymentMethodId, GenerateOnChainWalletRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<GenerateOnChainWalletResponse>($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}/generate", request, HttpMethod.Post, token);
|
||||
}
|
||||
public virtual async Task<OnChainPaymentMethodData> GetStoreOnChainPaymentMethod(string storeId,
|
||||
string cryptoCode, CancellationToken token = default)
|
||||
{
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}"), token);
|
||||
return await HandleResponse<OnChainPaymentMethodData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveStoreOnChainPaymentMethod(string storeId,
|
||||
string cryptoCode, CancellationToken token = default)
|
||||
{
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}",
|
||||
method: HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainPaymentMethodData> UpdateStoreOnChainPaymentMethod(string storeId,
|
||||
string cryptoCode, UpdateOnChainPaymentMethodRequest paymentMethod,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}",
|
||||
bodyPayload: paymentMethod, method: HttpMethod.Put), token);
|
||||
return await HandleResponse<OnChainPaymentMethodData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainPaymentMethodPreviewResultData>
|
||||
PreviewProposedStoreOnChainPaymentMethodAddresses(
|
||||
string storeId, string cryptoCode, UpdateOnChainPaymentMethodRequest paymentMethod, int offset = 0,
|
||||
int amount = 10,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/preview",
|
||||
bodyPayload: paymentMethod,
|
||||
queryPayload: new Dictionary<string, object>() { { "offset", offset }, { "amount", amount } },
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<OnChainPaymentMethodPreviewResultData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainPaymentMethodPreviewResultData> PreviewStoreOnChainPaymentMethodAddresses(
|
||||
string storeId, string cryptoCode, int offset = 0, int amount = 10,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/preview",
|
||||
queryPayload: new Dictionary<string, object>() { { "offset", offset }, { "amount", amount } },
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<OnChainPaymentMethodPreviewResultData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainPaymentMethodDataWithSensitiveData> GenerateOnChainWallet(string storeId,
|
||||
string cryptoCode, GenerateOnChainWalletRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/generate",
|
||||
bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<OnChainPaymentMethodDataWithSensitiveData>(response);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,62 +1,82 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<OnChainWalletObjectData> GetOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId, bool? includeNeighbourData = null, CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
var parameters = new Dictionary<string, object>();
|
||||
if (includeNeighbourData is bool v)
|
||||
parameters.Add("includeNeighbourData", v);
|
||||
try
|
||||
public virtual async Task<OnChainWalletObjectData> GetOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId, bool? includeNeighbourData = null, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<OnChainWalletObjectData>($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}", parameters, HttpMethod.Get, token);
|
||||
Dictionary<string, object> parameters = new Dictionary<string, object>();
|
||||
if (includeNeighbourData is bool v)
|
||||
parameters.Add("includeNeighbourData", v);
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}", parameters, method: HttpMethod.Get), token);
|
||||
try
|
||||
{
|
||||
return await HandleResponse<OnChainWalletObjectData>(response);
|
||||
}
|
||||
catch (GreenfieldAPIException err) when (err.APIError.Code == "wallet-object-not-found")
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (GreenfieldAPIException err) when (err.APIError.Code == "wallet-object-not-found")
|
||||
public virtual async Task<OnChainWalletObjectData[]> GetOnChainWalletObjects(string storeId, string cryptoCode, GetWalletObjectsRequest query = null, CancellationToken token = default)
|
||||
{
|
||||
return null;
|
||||
Dictionary<string, object> parameters = new Dictionary<string, object>();
|
||||
if (query?.Type is string s)
|
||||
parameters.Add("type", s);
|
||||
if (query?.Ids is string[] ids)
|
||||
parameters.Add("ids", ids);
|
||||
if (query?.IncludeNeighbourData is bool v)
|
||||
parameters.Add("includeNeighbourData", v);
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects", parameters, method: HttpMethod.Get), token);
|
||||
return await HandleResponse<OnChainWalletObjectData[]>(response);
|
||||
}
|
||||
public virtual async Task RemoveOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}", method: HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
public virtual async Task<OnChainWalletObjectData> AddOrUpdateOnChainWalletObject(string storeId, string cryptoCode, AddOnChainWalletObjectRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects", method: HttpMethod.Post, bodyPayload: request), token);
|
||||
return await HandleResponse<OnChainWalletObjectData>(response);
|
||||
}
|
||||
public virtual async Task AddOrUpdateOnChainWalletLink(string storeId, string cryptoCode,
|
||||
OnChainWalletObjectId objectId,
|
||||
AddOnChainWalletObjectLinkRequest request = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}/links", method: HttpMethod.Post, bodyPayload: request), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
public virtual async Task RemoveOnChainWalletLinks(string storeId, string cryptoCode,
|
||||
OnChainWalletObjectId objectId,
|
||||
OnChainWalletObjectId link,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}/links/{link.Type}/{link.Id}", method: HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
}
|
||||
public virtual async Task<OnChainWalletObjectData[]> GetOnChainWalletObjects(string storeId, string cryptoCode, GetWalletObjectsRequest query = null, CancellationToken token = default)
|
||||
{
|
||||
Dictionary<string, object> parameters = new Dictionary<string, object>();
|
||||
if (query?.Type is string s)
|
||||
parameters.Add("type", s);
|
||||
if (query?.Ids is string[] ids)
|
||||
parameters.Add("ids", ids);
|
||||
if (query?.IncludeNeighbourData is bool v)
|
||||
parameters.Add("includeNeighbourData", v);
|
||||
return await SendHttpRequest<OnChainWalletObjectData[]>($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects", parameters, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task RemoveOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
public virtual async Task<OnChainWalletObjectData> AddOrUpdateOnChainWalletObject(string storeId, string cryptoCode, AddOnChainWalletObjectRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<OnChainWalletObjectData>($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task AddOrUpdateOnChainWalletLink(string storeId, string cryptoCode,
|
||||
OnChainWalletObjectId objectId,
|
||||
AddOnChainWalletObjectLinkRequest request = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}/links", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveOnChainWalletLinks(string storeId, string cryptoCode,
|
||||
OnChainWalletObjectId objectId,
|
||||
OnChainWalletObjectId link,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}/links/{link.Type}/{link.Id}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
}
|
||||
|
@ -7,105 +7,138 @@ using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<OnChainWalletOverviewData> ShowOnChainWalletOverview(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<OnChainWalletOverviewData>($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<OnChainWalletFeeRateData> GetOnChainFeeRate(string storeId, string cryptoCode, int? blockTarget = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var queryParams = new Dictionary<string, object>();
|
||||
if (blockTarget != null)
|
||||
public virtual async Task<OnChainWalletOverviewData> ShowOnChainWalletOverview(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
queryParams.Add("blockTarget", blockTarget);
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet"), token);
|
||||
return await HandleResponse<OnChainWalletOverviewData>(response);
|
||||
}
|
||||
return await SendHttpRequest<OnChainWalletFeeRateData>($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/feeRate", queryParams, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainWalletAddressData> GetOnChainWalletReceiveAddress(string storeId, string cryptoCode, bool forceGenerate = false,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<OnChainWalletAddressData>($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/address", new Dictionary<string, object>
|
||||
public virtual async Task<OnChainWalletFeeRateData> GetOnChainFeeRate(string storeId, string cryptoCode, int? blockTarget = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
{"forceGenerate", forceGenerate}
|
||||
}, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task UnReserveOnChainWalletReceiveAddress(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/address", null, HttpMethod.Delete, token);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<OnChainWalletTransactionData>> ShowOnChainWalletTransactions(
|
||||
string storeId, string cryptoCode, TransactionStatus[] statusFilter = null, string labelFilter = null, int skip = 0,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var query = new Dictionary<string, object>();
|
||||
if (statusFilter?.Any() is true)
|
||||
{
|
||||
query.Add(nameof(statusFilter), statusFilter);
|
||||
Dictionary<string, object> queryParams = new Dictionary<string, object>();
|
||||
if (blockTarget != null)
|
||||
{
|
||||
queryParams.Add("blockTarget", blockTarget);
|
||||
}
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/feeRate", queryParams), token);
|
||||
return await HandleResponse<OnChainWalletFeeRateData>(response);
|
||||
}
|
||||
if (labelFilter != null)
|
||||
|
||||
public virtual async Task<OnChainWalletAddressData> GetOnChainWalletReceiveAddress(string storeId, string cryptoCode, bool forceGenerate = false,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
query.Add(nameof(labelFilter), labelFilter);
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/address", new Dictionary<string, object>()
|
||||
{
|
||||
{"forceGenerate", forceGenerate}
|
||||
}), token);
|
||||
return await HandleResponse<OnChainWalletAddressData>(response);
|
||||
}
|
||||
if (skip != 0)
|
||||
|
||||
public virtual async Task UnReserveOnChainWalletReceiveAddress(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
query.Add(nameof(skip), skip);
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/address", method: HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
return await SendHttpRequest<IEnumerable<OnChainWalletTransactionData>>($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions", query, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainWalletTransactionData> GetOnChainWalletTransaction(
|
||||
string storeId, string cryptoCode, string transactionId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<OnChainWalletTransactionData>($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions/{transactionId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainWalletTransactionData> PatchOnChainWalletTransaction(
|
||||
string storeId, string cryptoCode, string transactionId,
|
||||
PatchOnChainTransactionRequest request,
|
||||
bool force = false, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<PatchOnChainTransactionRequest, OnChainWalletTransactionData>($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions/{transactionId}",
|
||||
new Dictionary<string, object> { {"force", force} }, request, HttpMethod.Patch, token);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<OnChainWalletUTXOData>> GetOnChainWalletUTXOs(string storeId,
|
||||
string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<OnChainWalletUTXOData>>($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/utxos", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainWalletTransactionData> CreateOnChainTransaction(string storeId,
|
||||
string cryptoCode, CreateOnChainTransactionRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (!request.ProceedWithBroadcast)
|
||||
public virtual async Task<IEnumerable<OnChainWalletTransactionData>> ShowOnChainWalletTransactions(
|
||||
string storeId, string cryptoCode, TransactionStatus[] statusFilter = null, string labelFilter = null, int skip = 0,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(request.ProceedWithBroadcast),
|
||||
"Please use CreateOnChainTransactionButDoNotBroadcast when wanting to only create the transaction");
|
||||
var query = new Dictionary<string, object>();
|
||||
if (statusFilter?.Any() is true)
|
||||
{
|
||||
query.Add(nameof(statusFilter), statusFilter);
|
||||
}
|
||||
if (labelFilter != null)
|
||||
{
|
||||
query.Add(nameof(labelFilter), labelFilter);
|
||||
}
|
||||
if (skip != 0)
|
||||
{
|
||||
query.Add(nameof(skip), skip);
|
||||
}
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions", query), token);
|
||||
return await HandleResponse<IEnumerable<OnChainWalletTransactionData>>(response);
|
||||
}
|
||||
return await SendHttpRequest<OnChainWalletTransactionData>($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<Transaction> CreateOnChainTransactionButDoNotBroadcast(string storeId,
|
||||
string cryptoCode, CreateOnChainTransactionRequest request, Network network,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request.ProceedWithBroadcast)
|
||||
public virtual async Task<OnChainWalletTransactionData> GetOnChainWalletTransaction(
|
||||
string storeId, string cryptoCode, string transactionId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(request.ProceedWithBroadcast),
|
||||
"Please use CreateOnChainTransaction when wanting to also broadcast the transaction");
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions/{transactionId}"), token);
|
||||
return await HandleResponse<OnChainWalletTransactionData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainWalletTransactionData> PatchOnChainWalletTransaction(
|
||||
string storeId, string cryptoCode, string transactionId,
|
||||
PatchOnChainTransactionRequest request,
|
||||
bool force = false, CancellationToken token = default)
|
||||
{
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions/{transactionId}", queryPayload: new Dictionary<string, object>()
|
||||
{
|
||||
{"force", force}
|
||||
}, bodyPayload: request, HttpMethod.Patch), token);
|
||||
return await HandleResponse<OnChainWalletTransactionData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<OnChainWalletUTXOData>> GetOnChainWalletUTXOs(string storeId,
|
||||
string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/utxos"), token);
|
||||
return await HandleResponse<IEnumerable<OnChainWalletUTXOData>>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainWalletTransactionData> CreateOnChainTransaction(string storeId,
|
||||
string cryptoCode, CreateOnChainTransactionRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (!request.ProceedWithBroadcast)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(request.ProceedWithBroadcast),
|
||||
"Please use CreateOnChainTransactionButDoNotBroadcast when wanting to only create the transaction");
|
||||
}
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions", null, request, HttpMethod.Post), token);
|
||||
return await HandleResponse<OnChainWalletTransactionData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<Transaction> CreateOnChainTransactionButDoNotBroadcast(string storeId,
|
||||
string cryptoCode, CreateOnChainTransactionRequest request, Network network,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request.ProceedWithBroadcast)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(request.ProceedWithBroadcast),
|
||||
"Please use CreateOnChainTransaction when wanting to also broadcast the transaction");
|
||||
}
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions", null, request, HttpMethod.Post), token);
|
||||
return Transaction.Parse(await HandleResponse<string>(response), network);
|
||||
}
|
||||
return Transaction.Parse(await SendHttpRequest<string>($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions", request, HttpMethod.Post, token), network);
|
||||
}
|
||||
}
|
||||
|
@ -5,49 +5,72 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<IEnumerable<PaymentRequestData>> GetPaymentRequests(string storeId,
|
||||
bool includeArchived = false,
|
||||
CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<PaymentRequestData>>($"api/v1/stores/{storeId}/payment-requests",
|
||||
new Dictionary<string, object> { { nameof(includeArchived), includeArchived } }, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<IEnumerable<PaymentRequestData>> GetPaymentRequests(string storeId,
|
||||
bool includeArchived = false,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests",
|
||||
new Dictionary<string, object>() { { nameof(includeArchived), includeArchived } }), token);
|
||||
return await HandleResponse<IEnumerable<PaymentRequestData>>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<PaymentRequestData> GetPaymentRequest(string storeId, string paymentRequestId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<PaymentRequestData>($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<PaymentRequestData> GetPaymentRequest(string storeId, string paymentRequestId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}"), token);
|
||||
return await HandleResponse<PaymentRequestData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task ArchivePaymentRequest(string storeId, string paymentRequestId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
public virtual async Task ArchivePaymentRequest(string storeId, string paymentRequestId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}",
|
||||
method: HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<Client.Models.InvoiceData> PayPaymentRequest(string storeId, string paymentRequestId, PayPaymentRequestRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
if (storeId is null) throw new ArgumentNullException(nameof(storeId));
|
||||
if (paymentRequestId is null) throw new ArgumentNullException(nameof(paymentRequestId));
|
||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}/pay", request, HttpMethod.Post, token);
|
||||
}
|
||||
public virtual async Task<Client.Models.InvoiceData> PayPaymentRequest(string storeId, string paymentRequestId, PayPaymentRequestRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
if (storeId is null)
|
||||
throw new ArgumentNullException(nameof(storeId));
|
||||
if (paymentRequestId is null)
|
||||
throw new ArgumentNullException(nameof(paymentRequestId));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}/pay", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<Client.Models.InvoiceData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<PaymentRequestData> CreatePaymentRequest(string storeId,
|
||||
CreatePaymentRequestRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<PaymentRequestData>($"api/v1/stores/{storeId}/payment-requests", request, HttpMethod.Post, token);
|
||||
}
|
||||
public virtual async Task<PaymentRequestData> CreatePaymentRequest(string storeId,
|
||||
CreatePaymentRequestRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<PaymentRequestData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<PaymentRequestData> UpdatePaymentRequest(string storeId, string paymentRequestId,
|
||||
UpdatePaymentRequestRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<PaymentRequestData>($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}", request, HttpMethod.Put, token);
|
||||
public virtual async Task<PaymentRequestData> UpdatePaymentRequest(string storeId, string paymentRequestId,
|
||||
UpdatePaymentRequestRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}", bodyPayload: request,
|
||||
method: HttpMethod.Put), token);
|
||||
return await HandleResponse<PaymentRequestData>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,18 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<PayoutProcessorData>>("api/v1/payout-processors", null, HttpMethod.Get, token);
|
||||
public virtual async Task<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/payout-processors"), token);
|
||||
return await HandleResponse<IEnumerable<PayoutProcessorData>>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,90 +5,113 @@ using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<PullPaymentData> CreatePullPayment(string storeId, CreatePullPaymentRequest request, CancellationToken cancellationToken = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<PullPaymentData>($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments", request, HttpMethod.Post, cancellationToken);
|
||||
}
|
||||
public virtual async Task<PullPaymentData> CreatePullPayment(string storeId, CreatePullPaymentRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments", bodyPayload: request, method: HttpMethod.Post), cancellationToken);
|
||||
return await HandleResponse<PullPaymentData>(response);
|
||||
}
|
||||
public virtual async Task<PullPaymentData> GetPullPayment(string pullPaymentId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}", method: HttpMethod.Get), cancellationToken);
|
||||
return await HandleResponse<PullPaymentData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<PullPaymentData> GetPullPayment(string pullPaymentId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<PullPaymentData>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}", null, HttpMethod.Get, cancellationToken);
|
||||
}
|
||||
public virtual async Task<RegisterBoltcardResponse> RegisterBoltcard(string pullPaymentId, RegisterBoltcardRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/boltcards", bodyPayload: request, method: HttpMethod.Post), cancellationToken);
|
||||
return await HandleResponse<RegisterBoltcardResponse>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<RegisterBoltcardResponse> RegisterBoltcard(string pullPaymentId, RegisterBoltcardRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<RegisterBoltcardResponse>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/boltcards", request, HttpMethod.Post, cancellationToken);
|
||||
}
|
||||
public virtual async Task<PullPaymentData[]> GetPullPayments(string storeId, bool includeArchived = false, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Dictionary<string, object> query = new Dictionary<string, object>();
|
||||
query.Add("includeArchived", includeArchived);
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments", queryPayload: query, method: HttpMethod.Get), cancellationToken);
|
||||
return await HandleResponse<PullPaymentData[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<PullPaymentData[]> GetPullPayments(string storeId, bool includeArchived = false, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var query = new Dictionary<string, object> { { "includeArchived", includeArchived } };
|
||||
return await SendHttpRequest<PullPaymentData[]>($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments", query, HttpMethod.Get, cancellationToken);
|
||||
}
|
||||
public virtual async Task ArchivePullPayment(string storeId, string pullPaymentId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}", method: HttpMethod.Delete), cancellationToken);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task ArchivePullPayment(string storeId, string pullPaymentId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}", null, HttpMethod.Delete, cancellationToken);
|
||||
}
|
||||
public virtual async Task<PayoutData[]> GetPayouts(string pullPaymentId, bool includeCancelled = false, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Dictionary<string, object> query = new Dictionary<string, object>();
|
||||
query.Add("includeCancelled", includeCancelled);
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", queryPayload: query, method: HttpMethod.Get), cancellationToken);
|
||||
return await HandleResponse<PayoutData[]>(response);
|
||||
}
|
||||
public virtual async Task<PayoutData[]> GetStorePayouts(string storeId, bool includeCancelled = false, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Dictionary<string, object> query = new Dictionary<string, object>();
|
||||
query.Add("includeCancelled", includeCancelled);
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payouts", queryPayload: query, method: HttpMethod.Get), cancellationToken);
|
||||
return await HandleResponse<PayoutData[]>(response);
|
||||
}
|
||||
public virtual async Task<PayoutData> CreatePayout(string pullPaymentId, CreatePayoutRequest payoutRequest, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post), cancellationToken);
|
||||
return await HandleResponse<PayoutData>(response);
|
||||
}
|
||||
public virtual async Task<PayoutData> GetPullPaymentPayout(string pullPaymentId, string payoutId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts/{payoutId}", method: HttpMethod.Get), cancellationToken);
|
||||
return await HandleResponse<PayoutData>(response);
|
||||
}
|
||||
public virtual async Task<PayoutData> GetStorePayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payouts/{payoutId}", method: HttpMethod.Get), cancellationToken);
|
||||
return await HandleResponse<PayoutData>(response);
|
||||
}
|
||||
public virtual async Task<PayoutData> CreatePayout(string storeId, CreatePayoutThroughStoreRequest payoutRequest, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post), cancellationToken);
|
||||
return await HandleResponse<PayoutData>(response);
|
||||
}
|
||||
public virtual async Task CancelPayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}", method: HttpMethod.Delete), cancellationToken);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
public virtual async Task<PayoutData> ApprovePayout(string storeId, string payoutId, ApprovePayoutRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}", bodyPayload: request, method: HttpMethod.Post), cancellationToken);
|
||||
return await HandleResponse<PayoutData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<PayoutData[]> GetPayouts(string pullPaymentId, bool includeCancelled = false, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var query = new Dictionary<string, object> { { "includeCancelled", includeCancelled } };
|
||||
return await SendHttpRequest<PayoutData[]>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", query, HttpMethod.Get, cancellationToken);
|
||||
}
|
||||
public virtual async Task MarkPayoutPaid(string storeId, string payoutId,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest(
|
||||
$"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}/mark-paid",
|
||||
method: HttpMethod.Post), cancellationToken);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
public virtual async Task MarkPayout(string storeId, string payoutId, MarkPayoutRequest request,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest(
|
||||
$"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}/mark",
|
||||
method: HttpMethod.Post, bodyPayload: request), cancellationToken);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<PayoutData[]> GetStorePayouts(string storeId, bool includeCancelled = false, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var query = new Dictionary<string, object> { { "includeCancelled", includeCancelled } };
|
||||
return await SendHttpRequest<PayoutData[]>($"api/v1/stores/{storeId}/payouts", queryPayload: query, method: HttpMethod.Get, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PayoutData> CreatePayout(string pullPaymentId, CreatePayoutRequest payoutRequest, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<PayoutData>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", bodyPayload: payoutRequest, HttpMethod.Post, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PayoutData> GetPullPaymentPayout(string pullPaymentId, string payoutId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<PayoutData>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts/{payoutId}", null, HttpMethod.Get, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PayoutData> GetStorePayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<PayoutData>($"api/v1/stores/{storeId}/payouts/{payoutId}", null, HttpMethod.Get, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PayoutData> CreatePayout(string storeId, CreatePayoutThroughStoreRequest payoutRequest, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<PayoutData>($"api/v1/stores/{storeId}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task CancelPayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}", null, HttpMethod.Delete, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PayoutData> ApprovePayout(string storeId, string payoutId, ApprovePayoutRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<PayoutData>($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}", request, HttpMethod.Post, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task MarkPayoutPaid(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}/mark-paid", null, HttpMethod.Post, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task MarkPayout(string storeId, string payoutId, MarkPayoutRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}/mark", request, HttpMethod.Post, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PullPaymentLNURL> GetPullPaymentLNURL(string pullPaymentId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<PullPaymentLNURL>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/lnurl", null, HttpMethod.Get, cancellationToken);
|
||||
public virtual async Task<PullPaymentLNURL> GetPullPaymentLNURL(string pullPaymentId,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest(
|
||||
$"/api/v1/pull-payments/{pullPaymentId}/lnurl",
|
||||
method: HttpMethod.Get), cancellationToken);
|
||||
return await HandleResponse<PullPaymentLNURL>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<ServerInfoData> GetServerInfo(CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<ServerInfoData>("api/v1/server/info", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<ServerInfoData> GetServerInfo(CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/server/info"), token);
|
||||
return await HandleResponse<ServerInfoData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<List<RoleData>> GetServerRoles(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<List<RoleData>>("api/v1/server/roles", null, HttpMethod.Get, token);
|
||||
public virtual async Task<List<RoleData>> GetServerRoles(CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/server/roles"), token);
|
||||
return await HandleResponse<List<RoleData>>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,22 +3,35 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<EmailSettingsData> GetStoreEmailSettings(string storeId, CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<EmailSettingsData>($"api/v1/stores/{storeId}/email", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<EmailSettingsData> GetStoreEmailSettings(string storeId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/email", method: HttpMethod.Get),
|
||||
token);
|
||||
return await HandleResponse<EmailSettingsData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<EmailSettingsData> UpdateStoreEmailSettings(string storeId, EmailSettingsData request, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<EmailSettingsData>($"api/v1/stores/{storeId}/email", request, method: HttpMethod.Put, token);
|
||||
}
|
||||
public virtual async Task<EmailSettingsData> UpdateStoreEmailSettings(string storeId, EmailSettingsData request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/email", bodyPayload: request, method: HttpMethod.Put),
|
||||
token);
|
||||
return await HandleResponse<EmailSettingsData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task SendEmail(string storeId, SendEmailRequest request, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/email/send", request, HttpMethod.Post, token);
|
||||
public virtual async Task SendEmail(string storeId, SendEmailRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/email/send", bodyPayload: request, method: HttpMethod.Post),
|
||||
token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,27 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<GenericPaymentMethodData> UpdateStorePaymentMethod(string storeId, string paymentMethodId, UpdatePaymentMethodRequest request, CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<GenericPaymentMethodData>($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}", request, HttpMethod.Put, token);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveStorePaymentMethod(string storeId, string paymentMethodId)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}", null, HttpMethod.Delete, CancellationToken.None);
|
||||
}
|
||||
|
||||
public virtual async Task<GenericPaymentMethodData> GetStorePaymentMethod(string storeId, string paymentMethodId, bool? includeConfig = null, CancellationToken token = default)
|
||||
{
|
||||
var query = new Dictionary<string, object>();
|
||||
if (includeConfig != null)
|
||||
public virtual async Task<Dictionary<string, GenericPaymentMethodData>> GetStorePaymentMethods(string storeId,
|
||||
bool? enabled = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
query.Add(nameof(includeConfig), includeConfig);
|
||||
}
|
||||
return await SendHttpRequest<GenericPaymentMethodData>($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}", query, HttpMethod.Get, token);
|
||||
}
|
||||
var query = new Dictionary<string, object>();
|
||||
if (enabled != null)
|
||||
{
|
||||
query.Add(nameof(enabled), enabled);
|
||||
}
|
||||
|
||||
public virtual async Task<GenericPaymentMethodData[]> GetStorePaymentMethods(string storeId, bool? onlyEnabled = null, bool? includeConfig = null, CancellationToken token = default)
|
||||
{
|
||||
var query = new Dictionary<string, object>();
|
||||
if (onlyEnabled != null)
|
||||
{
|
||||
query.Add(nameof(onlyEnabled), onlyEnabled);
|
||||
var response =
|
||||
await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods",
|
||||
query), token);
|
||||
return await HandleResponse<Dictionary<string, GenericPaymentMethodData>>(response);
|
||||
}
|
||||
if (includeConfig != null)
|
||||
{
|
||||
query.Add(nameof(includeConfig), includeConfig);
|
||||
}
|
||||
|
||||
return await SendHttpRequest<GenericPaymentMethodData[]>($"api/v1/stores/{storeId}/payment-methods", query, HttpMethod.Get, token);
|
||||
}
|
||||
}
|
||||
|
@ -5,37 +5,44 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(string storeId, CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<PayoutProcessorData>>($"api/v1/stores/{storeId}/payout-processors", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(string storeId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors"), token);
|
||||
return await HandleResponse<IEnumerable<PayoutProcessorData>>(response);
|
||||
}
|
||||
public virtual async Task RemovePayoutProcessor(string storeId, string processor, string paymentMethod, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/{processor}/{paymentMethod}", null, HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task RemovePayoutProcessor(string storeId, string processor, string paymentMethod, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/payout-processors/{processor}/{paymentMethod}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
public virtual async Task<IEnumerable<LightningAutomatedPayoutSettings>> GetStoreLightningAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory{(paymentMethod is null ? string.Empty : $"/{paymentMethod}")}"), token);
|
||||
return await HandleResponse<IEnumerable<LightningAutomatedPayoutSettings>>(response);
|
||||
}
|
||||
public virtual async Task<LightningAutomatedPayoutSettings> UpdateStoreLightningAutomatedPayoutProcessors(string storeId, string paymentMethod, LightningAutomatedPayoutSettings request, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory/{paymentMethod}", null, request, HttpMethod.Put), token);
|
||||
return await HandleResponse<LightningAutomatedPayoutSettings>(response);
|
||||
}
|
||||
public virtual async Task<OnChainAutomatedPayoutSettings> UpdateStoreOnChainAutomatedPayoutProcessors(string storeId, string paymentMethod, OnChainAutomatedPayoutSettings request, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory/{paymentMethod}", null, request, HttpMethod.Put), token);
|
||||
return await HandleResponse<OnChainAutomatedPayoutSettings>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<LightningAutomatedPayoutSettings>> GetStoreLightningAutomatedPayoutProcessors(string storeId, string? paymentMethod = null, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<LightningAutomatedPayoutSettings>>($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory{(paymentMethod is null ? string.Empty : $"/{paymentMethod}")}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningAutomatedPayoutSettings> UpdateStoreLightningAutomatedPayoutProcessors(string storeId, string paymentMethod, LightningAutomatedPayoutSettings request, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<LightningAutomatedPayoutSettings>($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory/{paymentMethod}", request, HttpMethod.Put, token);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainAutomatedPayoutSettings> UpdateStoreOnChainAutomatedPayoutProcessors(string storeId, string paymentMethod, OnChainAutomatedPayoutSettings request, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<OnChainAutomatedPayoutSettings>($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory/{paymentMethod}", request, HttpMethod.Put, token);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<OnChainAutomatedPayoutSettings>> GetStoreOnChainAutomatedPayoutProcessors(string storeId, string? paymentMethod = null, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<OnChainAutomatedPayoutSettings>>($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory{(paymentMethod is null ? string.Empty : $"/{paymentMethod}")}", null, HttpMethod.Get, token);
|
||||
public virtual async Task<IEnumerable<OnChainAutomatedPayoutSettings>> GetStoreOnChainAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory{(paymentMethod is null ? string.Empty : $"/{paymentMethod}")}"), token);
|
||||
return await HandleResponse<IEnumerable<OnChainAutomatedPayoutSettings>>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,34 +4,61 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<StoreRateConfiguration> GetStoreRateConfiguration(string storeId, CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<StoreRateConfiguration>($"api/v1/stores/{storeId}/rates/configuration", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<StoreRateConfiguration> GetStoreRateConfiguration(string storeId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/rates/configuration", method: HttpMethod.Get),
|
||||
token);
|
||||
return await HandleResponse<StoreRateConfiguration>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<List<RateSource>> GetRateSources(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<List<RateSource>>("misc/rate-sources", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<List<RateSource>> GetRateSources(
|
||||
CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"misc/rate-sources", method: HttpMethod.Get),
|
||||
token);
|
||||
return await HandleResponse<List<RateSource>>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<StoreRateConfiguration> UpdateStoreRateConfiguration(string storeId, StoreRateConfiguration request, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<StoreRateConfiguration>($"api/v1/stores/{storeId}/rates/configuration", request, HttpMethod.Put, token);
|
||||
}
|
||||
public virtual async Task<StoreRateConfiguration> UpdateStoreRateConfiguration(string storeId,
|
||||
StoreRateConfiguration request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/rates/configuration", bodyPayload: request,
|
||||
method: HttpMethod.Put),
|
||||
token);
|
||||
return await HandleResponse<StoreRateConfiguration>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<List<StoreRateResult>> PreviewUpdateStoreRateConfiguration(string storeId, StoreRateConfiguration request, string[] currencyPair = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = currencyPair == null ? null : new Dictionary<string, object> { { "currencyPair", currencyPair } };
|
||||
return await SendHttpRequest<StoreRateConfiguration, List<StoreRateResult>>($"api/v1/stores/{storeId}/rates/configuration/preview", queryPayload, request, HttpMethod.Post, token);
|
||||
}
|
||||
public virtual async Task<List<StoreRateResult>> PreviewUpdateStoreRateConfiguration(string storeId,
|
||||
StoreRateConfiguration request,
|
||||
string[] currencyPair,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/rates/configuration/preview", bodyPayload: request,
|
||||
queryPayload: new Dictionary<string, object>() { { "currencyPair", currencyPair } },
|
||||
method: HttpMethod.Post),
|
||||
token);
|
||||
return await HandleResponse<List<StoreRateResult>>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<List<StoreRateResult>> GetStoreRates(string storeId, string[] currencyPair = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = currencyPair == null ? null : new Dictionary<string, object> { { "currencyPair", currencyPair } };
|
||||
return await SendHttpRequest<List<StoreRateResult>>($"api/v1/stores/{storeId}/rates", queryPayload, HttpMethod.Get, token);
|
||||
public virtual async Task<List<StoreRateResult>> GetStoreRates(string storeId, string[] currencyPair,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/rates",
|
||||
queryPayload: new Dictionary<string, object>() { { "currencyPair", currencyPair } },
|
||||
method: HttpMethod.Get),
|
||||
token);
|
||||
return await HandleResponse<List<StoreRateResult>>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,28 +5,40 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<List<RoleData>> GetStoreRoles(string storeId, CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<List<RoleData>>($"api/v1/stores/{storeId}/roles", null, HttpMethod.Get,token);
|
||||
}
|
||||
public virtual async Task<List<RoleData>> GetStoreRoles(string storeId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/roles"), token);
|
||||
return await HandleResponse<List<RoleData>>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<StoreUserData>> GetStoreUsers(string storeId, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<StoreUserData>>($"api/v1/stores/{storeId}/users", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<IEnumerable<StoreUserData>> GetStoreUsers(string storeId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/users"), token);
|
||||
return await HandleResponse<IEnumerable<StoreUserData>>(response);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveStoreUser(string storeId, string userId, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/users/{userId}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
public virtual async Task RemoveStoreUser(string storeId, string userId, CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/users/{userId}", method: HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task AddStoreUser(string storeId, StoreUserData request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
await SendHttpRequest<StoreUserData>($"api/v1/stores/{storeId}/users", request, HttpMethod.Post, token);
|
||||
public virtual async Task AddStoreUser(string storeId, StoreUserData request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
using var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/users", bodyPayload: request, method: HttpMethod.Post),
|
||||
token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,36 +5,47 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<IEnumerable<StoreData>> GetStores(CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<StoreData>>("api/v1/stores", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<IEnumerable<StoreData>> GetStores(CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/stores"), token);
|
||||
return await HandleResponse<IEnumerable<StoreData>>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<StoreData> GetStore(string storeId, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<StoreData>($"api/v1/stores/{storeId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<StoreData> GetStore(string storeId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}"), token);
|
||||
return await HandleResponse<StoreData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveStore(string storeId, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
public virtual async Task RemoveStore(string storeId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}", method: HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<StoreData> CreateStore(CreateStoreRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<StoreData>("api/v1/stores", request, HttpMethod.Post, token);
|
||||
}
|
||||
public virtual async Task<StoreData> CreateStore(CreateStoreRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/stores", bodyPayload: request, method: HttpMethod.Post), token);
|
||||
return await HandleResponse<StoreData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<StoreData> UpdateStore(string storeId, UpdateStoreRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
if (storeId == null) throw new ArgumentNullException(nameof(storeId));
|
||||
return await SendHttpRequest<StoreData>($"api/v1/stores/{storeId}", request, HttpMethod.Put, token);
|
||||
}
|
||||
public virtual async Task<StoreData> UpdateStore(string storeId, UpdateStoreRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
if (storeId == null)
|
||||
throw new ArgumentNullException(nameof(storeId));
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}", bodyPayload: request, method: HttpMethod.Put), token);
|
||||
return await HandleResponse<StoreData>(response);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -4,58 +4,60 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<ApplicationUserData> GetCurrentUser(CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<ApplicationUserData>("api/v1/users/me", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<ApplicationUserData> GetCurrentUser(CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/users/me"), token);
|
||||
return await HandleResponse<ApplicationUserData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<ApplicationUserData> UpdateCurrentUser(UpdateApplicationUserRequest request, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<ApplicationUserData>("api/v1/users/me", request, HttpMethod.Put, token);
|
||||
}
|
||||
public virtual async Task<ApplicationUserData> CreateUser(CreateApplicationUserRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/users", null, request, HttpMethod.Post), token);
|
||||
return await HandleResponse<ApplicationUserData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<ApplicationUserData> CreateUser(CreateApplicationUserRequest request, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<ApplicationUserData>("api/v1/users", request, HttpMethod.Post, token);
|
||||
}
|
||||
public virtual async Task DeleteUser(string userId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{userId}", null, HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task DeleteUser(string userId, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/users/{userId}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
public virtual async Task<ApplicationUserData> GetUserByIdOrEmail(string idOrEmail, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{idOrEmail}", null, HttpMethod.Get), token);
|
||||
return await HandleResponse<ApplicationUserData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<ApplicationUserData> GetUserByIdOrEmail(string idOrEmail, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<ApplicationUserData>($"api/v1/users/{idOrEmail}", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<bool> LockUser(string idOrEmail, bool locked, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{idOrEmail}/lock", null,
|
||||
new LockUserRequest { Locked = locked }, HttpMethod.Post), token);
|
||||
await HandleResponse(response);
|
||||
return response.IsSuccessStatusCode;
|
||||
}
|
||||
|
||||
public virtual async Task<bool> LockUser(string idOrEmail, bool locked, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{idOrEmail}/lock", null,
|
||||
new LockUserRequest { Locked = locked }, HttpMethod.Post), token);
|
||||
await HandleResponse(response);
|
||||
return response.IsSuccessStatusCode;
|
||||
}
|
||||
public virtual async Task<bool> ApproveUser(string idOrEmail, bool approved, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{idOrEmail}/approve", null,
|
||||
new ApproveUserRequest { Approved = approved }, HttpMethod.Post), token);
|
||||
await HandleResponse(response);
|
||||
return response.IsSuccessStatusCode;
|
||||
}
|
||||
|
||||
public virtual async Task<bool> ApproveUser(string idOrEmail, bool approved, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{idOrEmail}/approve", null,
|
||||
new ApproveUserRequest { Approved = approved }, HttpMethod.Post), token);
|
||||
await HandleResponse(response);
|
||||
return response.IsSuccessStatusCode;
|
||||
}
|
||||
public virtual async Task<ApplicationUserData[]> GetUsers(CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/", null, HttpMethod.Get), token);
|
||||
return await HandleResponse<ApplicationUserData[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<ApplicationUserData[]> GetUsers(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<ApplicationUserData[]>("api/v1/users/", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task DeleteCurrentUser(CancellationToken token = default)
|
||||
{
|
||||
await DeleteUser("me", token);
|
||||
public virtual async Task DeleteCurrentUser(CancellationToken token = default)
|
||||
{
|
||||
await DeleteUser("me", token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,56 +3,61 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public virtual async Task<StoreWebhookData> CreateWebhook(string storeId, CreateStoreWebhookRequest create, CancellationToken token = default)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
return await SendHttpRequest<StoreWebhookData>($"api/v1/stores/{storeId}/webhooks", create, HttpMethod.Post, token);
|
||||
}
|
||||
public virtual async Task<StoreWebhookData> CreateWebhook(string storeId, Client.Models.CreateStoreWebhookRequest create, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks", bodyPayload: create, method: HttpMethod.Post), token);
|
||||
return await HandleResponse<StoreWebhookData>(response);
|
||||
}
|
||||
public virtual async Task<StoreWebhookData> GetWebhook(string storeId, string webhookId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}"), token);
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||
return null;
|
||||
return await HandleResponse<StoreWebhookData>(response);
|
||||
}
|
||||
public virtual async Task<StoreWebhookData> UpdateWebhook(string storeId, string webhookId, Models.UpdateStoreWebhookRequest update, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}", bodyPayload: update, method: HttpMethod.Put), token);
|
||||
return await HandleResponse<StoreWebhookData>(response);
|
||||
}
|
||||
public virtual async Task<bool> DeleteWebhook(string storeId, string webhookId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}", method: HttpMethod.Delete), token);
|
||||
return response.IsSuccessStatusCode;
|
||||
}
|
||||
public virtual async Task<StoreWebhookData[]> GetWebhooks(string storeId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks"), token);
|
||||
return await HandleResponse<StoreWebhookData[]>(response);
|
||||
}
|
||||
public virtual async Task<WebhookDeliveryData[]> GetWebhookDeliveries(string storeId, string webhookId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries"), token);
|
||||
return await HandleResponse<WebhookDeliveryData[]>(response);
|
||||
}
|
||||
public virtual async Task<WebhookDeliveryData> GetWebhookDelivery(string storeId, string webhookId, string deliveryId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}"), token);
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||
return null;
|
||||
return await HandleResponse<WebhookDeliveryData>(response);
|
||||
}
|
||||
public virtual async Task<string> RedeliverWebhook(string storeId, string webhookId, string deliveryId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}/redeliver", null, HttpMethod.Post), token);
|
||||
return await HandleResponse<string>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<StoreWebhookData> GetWebhook(string storeId, string webhookId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}"), token);
|
||||
return response.StatusCode == System.Net.HttpStatusCode.NotFound ? null : await HandleResponse<StoreWebhookData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<StoreWebhookData> UpdateWebhook(string storeId, string webhookId, UpdateStoreWebhookRequest update, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<StoreWebhookData>($"api/v1/stores/{storeId}/webhooks/{webhookId}", update, HttpMethod.Put, token);
|
||||
}
|
||||
|
||||
public virtual async Task<bool> DeleteWebhook(string storeId, string webhookId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}", method: HttpMethod.Delete), token);
|
||||
return response.IsSuccessStatusCode;
|
||||
}
|
||||
|
||||
public virtual async Task<StoreWebhookData[]> GetWebhooks(string storeId, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<StoreWebhookData[]>($"api/v1/stores/{storeId}/webhooks", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<WebhookDeliveryData[]> GetWebhookDeliveries(string storeId, string webhookId, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<WebhookDeliveryData[]>($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<WebhookDeliveryData> GetWebhookDelivery(string storeId, string webhookId, string deliveryId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}"), token);
|
||||
return response.StatusCode == System.Net.HttpStatusCode.NotFound ? null : await HandleResponse<WebhookDeliveryData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<string> RedeliverWebhook(string storeId, string webhookId, string deliveryId, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<string>($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}/redeliver", null, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<WebhookEvent> GetWebhookDeliveryRequest(string storeId, string webhookId, string deliveryId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}/request"), token);
|
||||
return response.StatusCode == System.Net.HttpStatusCode.NotFound ? null : await HandleResponse<WebhookEvent>(response);
|
||||
public virtual async Task<WebhookEvent> GetWebhookDeliveryRequest(string storeId, string webhookId, string deliveryId, CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}/request"), token);
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||
return null;
|
||||
return await HandleResponse<WebhookEvent>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,179 +9,154 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
private readonly string _apiKey;
|
||||
private readonly Uri _btcpayHost;
|
||||
private readonly string _username;
|
||||
private readonly string _password;
|
||||
protected readonly HttpClient _httpClient;
|
||||
public Uri Host => _btcpayHost;
|
||||
|
||||
public string APIKey => _apiKey;
|
||||
|
||||
public BTCPayServerClient(Uri btcpayHost, HttpClient httpClient = null)
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
if (btcpayHost == null) throw new ArgumentNullException(nameof(btcpayHost));
|
||||
_btcpayHost = btcpayHost;
|
||||
_httpClient = httpClient ?? new HttpClient();
|
||||
}
|
||||
private readonly string _apiKey;
|
||||
private readonly Uri _btcpayHost;
|
||||
private readonly string _username;
|
||||
private readonly string _password;
|
||||
private readonly HttpClient _httpClient;
|
||||
public Uri Host => _btcpayHost;
|
||||
|
||||
public BTCPayServerClient(Uri btcpayHost, string APIKey, HttpClient httpClient = null)
|
||||
{
|
||||
_apiKey = APIKey;
|
||||
_btcpayHost = btcpayHost;
|
||||
_httpClient = httpClient ?? new HttpClient();
|
||||
}
|
||||
public string APIKey => _apiKey;
|
||||
|
||||
public BTCPayServerClient(Uri btcpayHost, string username, string password, HttpClient httpClient = null)
|
||||
{
|
||||
_apiKey = APIKey;
|
||||
_btcpayHost = btcpayHost;
|
||||
_username = username;
|
||||
_password = password;
|
||||
_httpClient = httpClient ?? new HttpClient();
|
||||
}
|
||||
|
||||
protected async Task HandleResponse(HttpResponseMessage message)
|
||||
{
|
||||
if (!message.IsSuccessStatusCode && message.Content?.Headers?.ContentType?.MediaType?.StartsWith("application/json", StringComparison.OrdinalIgnoreCase) is true)
|
||||
public BTCPayServerClient(Uri btcpayHost, HttpClient httpClient = null)
|
||||
{
|
||||
if (message.StatusCode == System.Net.HttpStatusCode.UnprocessableEntity)
|
||||
if (btcpayHost == null)
|
||||
throw new ArgumentNullException(nameof(btcpayHost));
|
||||
_btcpayHost = btcpayHost;
|
||||
_httpClient = httpClient ?? new HttpClient();
|
||||
}
|
||||
public BTCPayServerClient(Uri btcpayHost, string APIKey, HttpClient httpClient = null)
|
||||
{
|
||||
_apiKey = APIKey;
|
||||
_btcpayHost = btcpayHost;
|
||||
_httpClient = httpClient ?? new HttpClient();
|
||||
}
|
||||
|
||||
public BTCPayServerClient(Uri btcpayHost, string username, string password, HttpClient httpClient = null)
|
||||
{
|
||||
_apiKey = APIKey;
|
||||
_btcpayHost = btcpayHost;
|
||||
_username = username;
|
||||
_password = password;
|
||||
_httpClient = httpClient ?? new HttpClient();
|
||||
}
|
||||
|
||||
protected async Task HandleResponse(HttpResponseMessage message)
|
||||
{
|
||||
if (!message.IsSuccessStatusCode && message.Content?.Headers?.ContentType?.MediaType?.StartsWith("application/json", StringComparison.OrdinalIgnoreCase) is true)
|
||||
{
|
||||
var aa = await message.Content.ReadAsStringAsync();
|
||||
var err = JsonConvert.DeserializeObject<Models.GreenfieldValidationError[]>(aa);
|
||||
throw new GreenfieldValidationException(err);
|
||||
if (message.StatusCode == System.Net.HttpStatusCode.UnprocessableEntity)
|
||||
{
|
||||
var aa = await message.Content.ReadAsStringAsync();
|
||||
var err = JsonConvert.DeserializeObject<Models.GreenfieldValidationError[]>(aa);
|
||||
throw new GreenfieldValidationException(err);
|
||||
}
|
||||
if (message.StatusCode == System.Net.HttpStatusCode.Forbidden)
|
||||
{
|
||||
var err = JsonConvert.DeserializeObject<Models.GreenfieldPermissionAPIError>(await message.Content.ReadAsStringAsync());
|
||||
throw new GreenfieldAPIException((int)message.StatusCode, err);
|
||||
}
|
||||
else
|
||||
{
|
||||
var err = JsonConvert.DeserializeObject<Models.GreenfieldAPIError>(await message.Content.ReadAsStringAsync());
|
||||
if (err.Code != null)
|
||||
throw new GreenfieldAPIException((int)message.StatusCode, err);
|
||||
}
|
||||
}
|
||||
if (message.StatusCode == System.Net.HttpStatusCode.Forbidden)
|
||||
message.EnsureSuccessStatusCode();
|
||||
}
|
||||
|
||||
protected async Task<T> HandleResponse<T>(HttpResponseMessage message)
|
||||
{
|
||||
await HandleResponse(message);
|
||||
var str = await message.Content.ReadAsStringAsync();
|
||||
return JsonConvert.DeserializeObject<T>(str);
|
||||
}
|
||||
|
||||
public async Task<T> SendHttpRequest<T>(string path,
|
||||
Dictionary<string, object> queryPayload = null,
|
||||
HttpMethod method = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var resp = await _httpClient.SendAsync(CreateHttpRequest(path, queryPayload, method), cancellationToken);
|
||||
return await HandleResponse<T>(resp);
|
||||
}
|
||||
public async Task<T> SendHttpRequest<T>(string path,
|
||||
object bodyPayload = null,
|
||||
HttpMethod method = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var resp = await _httpClient.SendAsync(CreateHttpRequest(path: path, bodyPayload: bodyPayload, method: method), cancellationToken);
|
||||
return await HandleResponse<T>(resp);
|
||||
}
|
||||
protected virtual HttpRequestMessage CreateHttpRequest(string path,
|
||||
Dictionary<string, object> queryPayload = null,
|
||||
HttpMethod method = null)
|
||||
{
|
||||
UriBuilder uriBuilder = new UriBuilder(_btcpayHost) { Path = path };
|
||||
if (queryPayload != null && queryPayload.Any())
|
||||
{
|
||||
var err = JsonConvert.DeserializeObject<Models.GreenfieldPermissionAPIError>(await message.Content.ReadAsStringAsync());
|
||||
throw new GreenfieldAPIException((int)message.StatusCode, err);
|
||||
AppendPayloadToQuery(uriBuilder, queryPayload);
|
||||
}
|
||||
|
||||
var httpRequest = new HttpRequestMessage(method ?? HttpMethod.Get, uriBuilder.Uri);
|
||||
if (_apiKey != null)
|
||||
httpRequest.Headers.Authorization = new AuthenticationHeaderValue("token", _apiKey);
|
||||
else if (!string.IsNullOrEmpty(_username))
|
||||
{
|
||||
httpRequest.Headers.Authorization = new AuthenticationHeaderValue("Basic", System.Convert.ToBase64String(Encoding.ASCII.GetBytes(_username + ":" + _password)));
|
||||
}
|
||||
|
||||
|
||||
return httpRequest;
|
||||
}
|
||||
|
||||
protected virtual HttpRequestMessage CreateHttpRequest<T>(string path,
|
||||
Dictionary<string, object> queryPayload = null,
|
||||
T bodyPayload = default, HttpMethod method = null)
|
||||
{
|
||||
var request = CreateHttpRequest(path, queryPayload, method);
|
||||
if (typeof(T).IsPrimitive || !EqualityComparer<T>.Default.Equals(bodyPayload, default(T)))
|
||||
{
|
||||
request.Content = new StringContent(JsonConvert.SerializeObject(bodyPayload), Encoding.UTF8, "application/json");
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
public static void AppendPayloadToQuery(UriBuilder uri, KeyValuePair<string, object> keyValuePair)
|
||||
{
|
||||
if (uri.Query.Length > 1)
|
||||
uri.Query += "&";
|
||||
|
||||
UriBuilder uriBuilder = uri;
|
||||
if (!(keyValuePair.Value is string) &&
|
||||
keyValuePair.Value.GetType().GetInterfaces().Contains((typeof(IEnumerable))))
|
||||
{
|
||||
foreach (var item in (IEnumerable)keyValuePair.Value)
|
||||
{
|
||||
uriBuilder.Query = uriBuilder.Query + Uri.EscapeDataString(keyValuePair.Key) + "=" +
|
||||
Uri.EscapeDataString(item.ToString()) + "&";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var err = JsonConvert.DeserializeObject<Models.GreenfieldAPIError>(await message.Content.ReadAsStringAsync());
|
||||
if (err.Code != null)
|
||||
throw new GreenfieldAPIException((int)message.StatusCode, err);
|
||||
}
|
||||
}
|
||||
message.EnsureSuccessStatusCode();
|
||||
}
|
||||
|
||||
protected virtual async Task<T> HandleResponse<T>(HttpResponseMessage message)
|
||||
{
|
||||
await HandleResponse(message);
|
||||
var str = await message.Content.ReadAsStringAsync();
|
||||
return JsonConvert.DeserializeObject<T>(str);
|
||||
}
|
||||
|
||||
public virtual async Task SendHttpRequest(string path,
|
||||
Dictionary<string, object> queryPayload = null,
|
||||
HttpMethod method = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var resp = await _httpClient.SendAsync(CreateHttpRequest(path, queryPayload, method), cancellationToken);
|
||||
await HandleResponse(resp);
|
||||
}
|
||||
|
||||
public virtual async Task<T> SendHttpRequest<T>(string path,
|
||||
Dictionary<string, object> queryPayload = null,
|
||||
HttpMethod method = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var resp = await _httpClient.SendAsync(CreateHttpRequest(path, queryPayload, method), cancellationToken);
|
||||
return await HandleResponse<T>(resp);
|
||||
}
|
||||
|
||||
public virtual async Task SendHttpRequest(string path,
|
||||
object bodyPayload = null,
|
||||
HttpMethod method = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var resp = await _httpClient.SendAsync(CreateHttpRequest(path: path, bodyPayload: bodyPayload, method: method), cancellationToken);
|
||||
await HandleResponse(resp);
|
||||
}
|
||||
|
||||
protected virtual async Task<T> SendHttpRequest<T>(string path,
|
||||
object bodyPayload = null,
|
||||
HttpMethod method = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var resp = await _httpClient.SendAsync(CreateHttpRequest(path: path, bodyPayload: bodyPayload, method: method), cancellationToken);
|
||||
return await HandleResponse<T>(resp);
|
||||
}
|
||||
|
||||
protected virtual async Task<TRes> SendHttpRequest<TReq, TRes>(string path,
|
||||
Dictionary<string, object> queryPayload = null,
|
||||
TReq bodyPayload = default, HttpMethod method = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var resp = await _httpClient.SendAsync(CreateHttpRequest(path: path, bodyPayload: bodyPayload, queryPayload: queryPayload, method: method), cancellationToken);
|
||||
return await HandleResponse<TRes>(resp);
|
||||
}
|
||||
|
||||
protected virtual HttpRequestMessage CreateHttpRequest(string path,
|
||||
Dictionary<string, object> queryPayload = null,
|
||||
HttpMethod method = null)
|
||||
{
|
||||
var uriBuilder = new UriBuilder(_btcpayHost);
|
||||
uriBuilder.Path += (uriBuilder.Path.EndsWith("/") || path.StartsWith("/") ? "" : "/") + path;
|
||||
if (queryPayload != null && queryPayload.Any())
|
||||
{
|
||||
AppendPayloadToQuery(uriBuilder, queryPayload);
|
||||
}
|
||||
|
||||
var httpRequest = new HttpRequestMessage(method ?? HttpMethod.Get, uriBuilder.Uri);
|
||||
if (_apiKey != null)
|
||||
httpRequest.Headers.Authorization = new AuthenticationHeaderValue("token", _apiKey);
|
||||
else if (!string.IsNullOrEmpty(_username))
|
||||
{
|
||||
httpRequest.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(_username + ":" + _password)));
|
||||
}
|
||||
|
||||
return httpRequest;
|
||||
}
|
||||
|
||||
protected virtual HttpRequestMessage CreateHttpRequest<T>(string path,
|
||||
Dictionary<string, object> queryPayload = null,
|
||||
T bodyPayload = default, HttpMethod method = null)
|
||||
{
|
||||
var request = CreateHttpRequest(path, queryPayload, method);
|
||||
if (typeof(T).IsPrimitive || !EqualityComparer<T>.Default.Equals(bodyPayload, default(T)))
|
||||
{
|
||||
request.Content = new StringContent(JsonConvert.SerializeObject(bodyPayload), Encoding.UTF8, "application/json");
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
public static void AppendPayloadToQuery(UriBuilder uri, KeyValuePair<string, object> keyValuePair)
|
||||
{
|
||||
if (uri.Query.Length > 1)
|
||||
uri.Query += "&";
|
||||
|
||||
UriBuilder uriBuilder = uri;
|
||||
if (!(keyValuePair.Value is string) &&
|
||||
keyValuePair.Value.GetType().GetInterfaces().Contains((typeof(IEnumerable))))
|
||||
{
|
||||
foreach (var item in (IEnumerable)keyValuePair.Value)
|
||||
{
|
||||
uriBuilder.Query = uriBuilder.Query + Uri.EscapeDataString(keyValuePair.Key) + "=" +
|
||||
Uri.EscapeDataString(item.ToString()) + "&";
|
||||
Uri.EscapeDataString(keyValuePair.Value.ToString()) + "&";
|
||||
}
|
||||
uri.Query = uri.Query.Trim('&');
|
||||
}
|
||||
else
|
||||
{
|
||||
uriBuilder.Query = uriBuilder.Query + Uri.EscapeDataString(keyValuePair.Key) + "=" +
|
||||
Uri.EscapeDataString(keyValuePair.Value.ToString()) + "&";
|
||||
}
|
||||
uri.Query = uri.Query.Trim('&');
|
||||
}
|
||||
|
||||
public static void AppendPayloadToQuery(UriBuilder uri, Dictionary<string, object> payload)
|
||||
{
|
||||
if (uri.Query.Length > 1)
|
||||
uri.Query += "&";
|
||||
foreach (KeyValuePair<string, object> keyValuePair in payload)
|
||||
public static void AppendPayloadToQuery(UriBuilder uri, Dictionary<string, object> payload)
|
||||
{
|
||||
AppendPayloadToQuery(uri, keyValuePair);
|
||||
if (uri.Query.Length > 1)
|
||||
uri.Query += "&";
|
||||
foreach (KeyValuePair<string, object> keyValuePair in payload)
|
||||
{
|
||||
AppendPayloadToQuery(uri, keyValuePair);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public class GreenfieldAPIException : Exception
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public GreenfieldAPIException(int httpCode, Models.GreenfieldAPIError error) : base(error.Message)
|
||||
public class GreenfieldAPIException : Exception
|
||||
{
|
||||
if (error == null) throw new ArgumentNullException(nameof(error));
|
||||
HttpCode = httpCode;
|
||||
APIError = error;
|
||||
public GreenfieldAPIException(int httpCode, Models.GreenfieldAPIError error) : base(error.Message)
|
||||
{
|
||||
if (error == null)
|
||||
throw new ArgumentNullException(nameof(error));
|
||||
HttpCode = httpCode;
|
||||
APIError = error;
|
||||
}
|
||||
public Models.GreenfieldAPIError APIError { get; }
|
||||
public int HttpCode { get; set; }
|
||||
}
|
||||
public Models.GreenfieldAPIError APIError { get; }
|
||||
public int HttpCode { get; set; }
|
||||
}
|
||||
|
@ -2,25 +2,27 @@ using System;
|
||||
using System.Text;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public class GreenfieldValidationException : Exception
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public GreenfieldValidationException(GreenfieldValidationError[] errors) : base(BuildMessage(errors))
|
||||
public class GreenfieldValidationException : Exception
|
||||
{
|
||||
ValidationErrors = errors;
|
||||
}
|
||||
|
||||
private static string BuildMessage(GreenfieldValidationError[] errors)
|
||||
{
|
||||
if (errors == null) throw new ArgumentNullException(nameof(errors));
|
||||
var builder = new StringBuilder();
|
||||
foreach (var error in errors)
|
||||
public GreenfieldValidationException(Models.GreenfieldValidationError[] errors) : base(BuildMessage(errors))
|
||||
{
|
||||
builder.AppendLine($"{error.Path}: {error.Message}");
|
||||
ValidationErrors = errors;
|
||||
}
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public GreenfieldValidationError[] ValidationErrors { get; }
|
||||
private static string BuildMessage(GreenfieldValidationError[] errors)
|
||||
{
|
||||
if (errors == null)
|
||||
throw new ArgumentNullException(nameof(errors));
|
||||
StringBuilder builder = new StringBuilder();
|
||||
foreach (var error in errors)
|
||||
{
|
||||
builder.AppendLine($"{error.Path}: {error.Message}");
|
||||
}
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public Models.GreenfieldValidationError[] ValidationErrors { get; }
|
||||
}
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
using NBitcoin;
|
||||
using NBitcoin.DataEncoders;
|
||||
using NBitcoin.JsonConverters;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace BTCPayServer.Client.JsonConverters
|
||||
{
|
||||
public class SaneOutpointJsonConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return typeof(OutPoint).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo());
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
return null;
|
||||
|
||||
if (reader.TokenType != JsonToken.String)
|
||||
throw new JsonObjectException($"Unexpected json token type, expected is {JsonToken.String} and actual is {reader.TokenType}", reader);
|
||||
try
|
||||
{
|
||||
if (!OutPoint.TryParse((string)reader.Value, out var outpoint))
|
||||
throw new JsonObjectException("Invalid bitcoin object of type OutPoint", reader);
|
||||
return outpoint;
|
||||
}
|
||||
catch (EndOfStreamException)
|
||||
{
|
||||
}
|
||||
throw new JsonObjectException("Invalid bitcoin object of type OutPoint", reader);
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
if (value is { })
|
||||
writer.WriteValue(value.ToString());
|
||||
}
|
||||
}
|
||||
}
|
@ -58,8 +58,6 @@ namespace BTCPayServer.Client.JsonConverters
|
||||
return null;
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
if (reader.TokenType == JsonToken.String && TimeSpan.TryParse(reader.Value?.ToString(), out var res))
|
||||
return res;
|
||||
if (reader.TokenType != JsonToken.Integer)
|
||||
throw new JsonObjectException("Invalid timespan, expected integer", reader);
|
||||
return ToTimespan((long)reader.Value);
|
||||
|
@ -1,21 +0,0 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Client.Models;
|
||||
|
||||
public class AppBaseData
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string AppType { get; set; }
|
||||
public string AppName { get; set; }
|
||||
public string StoreId { get; set; }
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? Archived { get; set; }
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset Created { get; set; }
|
||||
}
|
||||
|
||||
public interface IAppRequest
|
||||
{
|
||||
public string AppName { get; set; }
|
||||
}
|
@ -14,16 +14,6 @@ namespace BTCPayServer.Client.Models
|
||||
/// the email AND username of the user
|
||||
/// </summary>
|
||||
public string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// the name of the user
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// the image url of the user
|
||||
/// </summary>
|
||||
public string ImageUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the user has verified their email
|
||||
|
88
BTCPayServer.Client/Models/CreateAppRequest.cs
Normal file
88
BTCPayServer.Client/Models/CreateAppRequest.cs
Normal file
@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public enum PosViewType
|
||||
{
|
||||
Static,
|
||||
Cart,
|
||||
Light,
|
||||
Print
|
||||
}
|
||||
|
||||
public class CreateAppRequest
|
||||
{
|
||||
public string AppName { get; set; }
|
||||
public string AppType { get; set; }
|
||||
}
|
||||
|
||||
public class CreatePointOfSaleAppRequest : CreateAppRequest
|
||||
{
|
||||
public string Currency { get; set; } = null;
|
||||
public string Title { get; set; } = null;
|
||||
public string Description { get; set; } = null;
|
||||
public string Template { get; set; } = null;
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public PosViewType DefaultView { get; set; }
|
||||
public bool ShowItems { get; set; } = false;
|
||||
public bool ShowCustomAmount { get; set; } = false;
|
||||
public bool ShowDiscount { get; set; } = false;
|
||||
public bool ShowSearch { get; set; } = true;
|
||||
public bool ShowCategories { get; set; } = true;
|
||||
public bool EnableTips { get; set; } = false;
|
||||
public string CustomAmountPayButtonText { get; set; } = null;
|
||||
public string FixedAmountPayButtonText { get; set; } = null;
|
||||
public string TipText { get; set; } = null;
|
||||
public string CustomCSSLink { get; set; } = null;
|
||||
public string NotificationUrl { get; set; } = null;
|
||||
public string RedirectUrl { get; set; } = null;
|
||||
public bool? RedirectAutomatically { get; set; } = null;
|
||||
public bool? RequiresRefundEmail { get; set; } = null;
|
||||
public bool? Archived { get; set; } = null;
|
||||
public string FormId { get; set; } = null;
|
||||
public string EmbeddedCSS { get; set; } = null;
|
||||
}
|
||||
|
||||
public enum CrowdfundResetEvery
|
||||
{
|
||||
Never,
|
||||
Hour,
|
||||
Day,
|
||||
Month,
|
||||
Year
|
||||
}
|
||||
|
||||
public class CreateCrowdfundAppRequest : CreateAppRequest
|
||||
{
|
||||
public string Title { get; set; } = null;
|
||||
public bool? Enabled { get; set; } = null;
|
||||
public bool? EnforceTargetAmount { get; set; } = null;
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset? StartDate { get; set; } = null;
|
||||
public string TargetCurrency { get; set; } = null;
|
||||
public string Description { get; set; } = null;
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset? EndDate { get; set; } = null;
|
||||
public decimal? TargetAmount { get; set; } = null;
|
||||
public string CustomCSSLink { get; set; } = null;
|
||||
public string MainImageUrl { get; set; } = null;
|
||||
public string EmbeddedCSS { get; set; } = null;
|
||||
public string NotificationUrl { get; set; } = null;
|
||||
public string Tagline { get; set; } = null;
|
||||
public string PerksTemplate { get; set; } = null;
|
||||
public bool? SoundsEnabled { get; set; } = null;
|
||||
public string DisqusShortname { get; set; } = null;
|
||||
public bool? AnimationsEnabled { get; set; } = null;
|
||||
public int? ResetEveryAmount { get; set; } = null;
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public CrowdfundResetEvery ResetEvery { get; set; } = CrowdfundResetEvery.Never;
|
||||
public bool? DisplayPerksValue { get; set; } = null;
|
||||
public bool? DisplayPerksRanking { get; set; } = null;
|
||||
public bool? SortPerksByPopularity { get; set; } = null;
|
||||
public bool? Archived { get; set; } = null;
|
||||
public string[] Sounds { get; set; } = null;
|
||||
public string[] AnimationColors { get; set; } = null;
|
||||
}
|
||||
}
|
@ -2,16 +2,6 @@ namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public class CreateApplicationUserRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// the name of the new user
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// the image url of the new user
|
||||
/// </summary>
|
||||
public string ImageUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// the email AND username of the new user
|
||||
/// </summary>
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using BTCPayServer.Client.JsonConverters;
|
||||
using BTCPayServer.JsonConverters;
|
||||
using NBitcoin;
|
||||
using NBitcoin.JsonConverters;
|
||||
@ -22,7 +21,7 @@ namespace BTCPayServer.Client.Models
|
||||
public bool ProceedWithPayjoin { get; set; } = true;
|
||||
public bool ProceedWithBroadcast { get; set; } = true;
|
||||
public bool NoChange { get; set; } = false;
|
||||
[JsonProperty(ItemConverterType = typeof(SaneOutpointJsonConverter))]
|
||||
[JsonProperty(ItemConverterType = typeof(OutpointJsonConverter))]
|
||||
public List<OutPoint> SelectedInputs { get; set; } = null;
|
||||
public List<CreateOnChainTransactionRequestDestination> Destinations { get; set; }
|
||||
[JsonProperty("rbf")]
|
||||
|
@ -12,6 +12,8 @@ namespace BTCPayServer.Client.Models
|
||||
[JsonProperty(ItemConverterType = typeof(NumericStringJsonConverter))]
|
||||
public decimal Amount { get; set; }
|
||||
public string Currency { get; set; }
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||
public TimeSpan? Period { get; set; }
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Days))]
|
||||
[JsonProperty("BOLT11Expiration")]
|
||||
public TimeSpan? BOLT11Expiration { get; set; }
|
||||
|
@ -1,55 +0,0 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace BTCPayServer.Client.Models;
|
||||
|
||||
public abstract class CrowdfundBaseData : AppBaseData
|
||||
{
|
||||
public string? Title { get; set; }
|
||||
public bool? Enabled { get; set; }
|
||||
public bool? EnforceTargetAmount { get; set; }
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset? StartDate { get; set; }
|
||||
public string? TargetCurrency { get; set; }
|
||||
public string? Description { get; set; }
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset? EndDate { get; set; }
|
||||
public decimal? TargetAmount { get; set; }
|
||||
public string? MainImageUrl { get; set; }
|
||||
public string? NotificationUrl { get; set; }
|
||||
public string? Tagline { get; set; }
|
||||
public bool? DisqusEnabled { get; set; }
|
||||
public string? DisqusShortname { get; set; }
|
||||
public bool? SoundsEnabled { get; set; }
|
||||
public bool? AnimationsEnabled { get; set; }
|
||||
public int? ResetEveryAmount { get; set; }
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public CrowdfundResetEvery? ResetEvery { get; set; }
|
||||
public bool? DisplayPerksValue { get; set; }
|
||||
public bool? DisplayPerksRanking { get; set; }
|
||||
public bool? SortPerksByPopularity { get; set; }
|
||||
public string[]? Sounds { get; set; }
|
||||
public string[]? AnimationColors { get; set; }
|
||||
public string? FormId { get; set; }
|
||||
}
|
||||
|
||||
public class CrowdfundAppData : CrowdfundBaseData
|
||||
{
|
||||
public object? Perks { get; set; }
|
||||
}
|
||||
|
||||
public class CrowdfundAppRequest : CrowdfundBaseData, IAppRequest
|
||||
{
|
||||
public string? PerksTemplate { get; set; }
|
||||
}
|
||||
|
||||
public enum CrowdfundResetEvery
|
||||
{
|
||||
Never,
|
||||
Hour,
|
||||
Day,
|
||||
Month,
|
||||
Year
|
||||
}
|
@ -1,10 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using BTCPayServer.Client.JsonConverters;
|
||||
using BTCPayServer.Client.Models;
|
||||
using NBitcoin;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
@ -25,16 +22,4 @@ namespace BTCPayServer.Client
|
||||
public bool ImportKeysToRPC { get; set; }
|
||||
public bool SavePrivateKeys { get; set; }
|
||||
}
|
||||
public class GenerateOnChainWalletResponse : GenericPaymentMethodData
|
||||
{
|
||||
public class ConfigData
|
||||
{
|
||||
public string AccountDerivation { get; set; }
|
||||
[JsonExtensionData]
|
||||
IDictionary<string, JToken> AdditionalData { get; set; }
|
||||
}
|
||||
[JsonConverter(typeof(MnemonicJsonConverter))]
|
||||
public Mnemonic Mnemonic { get; set; }
|
||||
public new ConfigData Config { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,9 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public class GenericPaymentMethodData
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public JToken Config { get; set; }
|
||||
public string PaymentMethodId { get; set; }
|
||||
}
|
||||
public class UpdatePaymentMethodRequest
|
||||
{
|
||||
public UpdatePaymentMethodRequest()
|
||||
{
|
||||
|
||||
}
|
||||
public bool? Enabled { get; set; }
|
||||
public JToken Config { get; set; }
|
||||
public object Data { get; set; }
|
||||
public string CryptoCode { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,8 @@ namespace BTCPayServer.Client.Models
|
||||
public GreenfieldAPIError(string code, string message)
|
||||
{
|
||||
code = code ?? "generic-error";
|
||||
if (message == null) throw new ArgumentNullException(nameof(message));
|
||||
if (message == null)
|
||||
throw new ArgumentNullException(nameof(message));
|
||||
Code = code;
|
||||
Message = message;
|
||||
}
|
||||
|
@ -6,12 +6,14 @@ namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public GreenfieldValidationError()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
public GreenfieldValidationError(string path, string message)
|
||||
{
|
||||
if (path == null) throw new ArgumentNullException(nameof(path));
|
||||
if (message == null) throw new ArgumentNullException(nameof(message));
|
||||
if (path == null)
|
||||
throw new ArgumentNullException(nameof(path));
|
||||
if (message == null)
|
||||
throw new ArgumentNullException(nameof(message));
|
||||
Path = path;
|
||||
Message = message;
|
||||
}
|
||||
|
@ -83,7 +83,9 @@ namespace BTCPayServer.Client.Models
|
||||
public string RedirectURL { get; set; }
|
||||
|
||||
public bool? RedirectAutomatically { get; set; }
|
||||
public bool? RequiresRefundEmail { get; set; } = null;
|
||||
public string DefaultLanguage { get; set; }
|
||||
public CheckoutType? CheckoutType { get; set; }
|
||||
public bool? LazyPaymentMethods { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ public enum InvoiceExceptionStatus
|
||||
PaidLate,
|
||||
PaidPartial,
|
||||
Marked,
|
||||
Invalid,
|
||||
PaidOver
|
||||
}
|
||||
|
||||
|
@ -29,12 +29,13 @@ namespace BTCPayServer.Client.Models
|
||||
public decimal Amount { get; set; }
|
||||
|
||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||
public decimal PaymentMethodFee { get; set; }
|
||||
public decimal NetworkFee { get; set; }
|
||||
|
||||
public List<Payment> Payments { get; set; }
|
||||
public string PaymentMethodId { get; set; }
|
||||
public JToken AdditionalData { get; set; }
|
||||
public string Currency { get; set; }
|
||||
public string PaymentMethod { get; set; }
|
||||
|
||||
public string CryptoCode { get; set; }
|
||||
public JObject AdditionalData { get; set; }
|
||||
|
||||
public class Payment
|
||||
{
|
||||
|
17
BTCPayServer.Client/Models/LNURLPayPaymentMethodBaseData.cs
Normal file
17
BTCPayServer.Client/Models/LNURLPayPaymentMethodBaseData.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public class LNURLPayPaymentMethodBaseData
|
||||
{
|
||||
public bool UseBech32Scheme { get; set; }
|
||||
|
||||
[JsonProperty("lud12Enabled")]
|
||||
public bool LUD12Enabled { get; set; }
|
||||
|
||||
public LNURLPayPaymentMethodBaseData()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
27
BTCPayServer.Client/Models/LNURLPayPaymentMethodData.cs
Normal file
27
BTCPayServer.Client/Models/LNURLPayPaymentMethodData.cs
Normal file
@ -0,0 +1,27 @@
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public class LNURLPayPaymentMethodData : LNURLPayPaymentMethodBaseData
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the payment method is enabled
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Crypto code of the payment method
|
||||
/// </summary>
|
||||
public string CryptoCode { get; set; }
|
||||
|
||||
public LNURLPayPaymentMethodData()
|
||||
{
|
||||
}
|
||||
|
||||
public LNURLPayPaymentMethodData(string cryptoCode, bool enabled, bool useBech32Scheme, bool lud12Enabled)
|
||||
{
|
||||
Enabled = enabled;
|
||||
CryptoCode = cryptoCode;
|
||||
UseBech32Scheme = useBech32Scheme;
|
||||
LUD12Enabled = lud12Enabled;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,3 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Client.Models;
|
||||
|
||||
public class LightningAddressData
|
||||
@ -8,5 +6,5 @@ public class LightningAddressData
|
||||
public string CurrencyCode { get; set; }
|
||||
public decimal? Min { get; set; }
|
||||
public decimal? Max { get; set; }
|
||||
public JObject InvoiceMetadata { get; set; }
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public class LightningNetworkPaymentMethodBaseData
|
||||
{
|
||||
|
||||
public string ConnectionString { get; set; }
|
||||
public LightningNetworkPaymentMethodBaseData()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public class LightningNetworkPaymentMethodData : LightningNetworkPaymentMethodBaseData
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the payment method is enabled
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Crypto code of the payment method
|
||||
/// </summary>
|
||||
public string CryptoCode { get; set; }
|
||||
|
||||
public LightningNetworkPaymentMethodData()
|
||||
{
|
||||
}
|
||||
|
||||
public LightningNetworkPaymentMethodData(string cryptoCode, string connectionString, bool enabled, string paymentMethod)
|
||||
{
|
||||
Enabled = enabled;
|
||||
CryptoCode = cryptoCode;
|
||||
ConnectionString = connectionString;
|
||||
PaymentMethod = paymentMethod;
|
||||
}
|
||||
|
||||
public string PaymentMethod { get; set; }
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BTCPayServer.Client.Models;
|
||||
|
||||
public class NotificationSettingsData
|
||||
{
|
||||
public List<NotificationSettingsItemData> Notifications { get; set; }
|
||||
}
|
||||
|
||||
public class NotificationSettingsItemData
|
||||
{
|
||||
public string Identifier { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
}
|
24
BTCPayServer.Client/Models/OnChainPaymentMethodBaseData.cs
Normal file
24
BTCPayServer.Client/Models/OnChainPaymentMethodBaseData.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using NBitcoin;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public class OnChainPaymentMethodBaseData
|
||||
{
|
||||
/// <summary>
|
||||
/// The derivation scheme
|
||||
/// </summary>
|
||||
public string DerivationScheme { get; set; }
|
||||
|
||||
public string Label { get; set; }
|
||||
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.KeyPathJsonConverter))]
|
||||
public RootedKeyPath AccountKeyPath { get; set; }
|
||||
|
||||
public OnChainPaymentMethodBaseData()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
47
BTCPayServer.Client/Models/OnChainPaymentMethodData.cs
Normal file
47
BTCPayServer.Client/Models/OnChainPaymentMethodData.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public class OnChainPaymentMethodDataPreview : OnChainPaymentMethodBaseData
|
||||
{
|
||||
/// <summary>
|
||||
/// Crypto code of the payment method
|
||||
/// </summary>
|
||||
public string CryptoCode { get; set; }
|
||||
|
||||
public OnChainPaymentMethodDataPreview()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public OnChainPaymentMethodDataPreview(string cryptoCode, string derivationScheme, string label, RootedKeyPath accountKeyPath)
|
||||
{
|
||||
Label = label;
|
||||
AccountKeyPath = accountKeyPath;
|
||||
CryptoCode = cryptoCode;
|
||||
DerivationScheme = derivationScheme;
|
||||
}
|
||||
}
|
||||
|
||||
public class OnChainPaymentMethodData : OnChainPaymentMethodDataPreview
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the payment method is enabled
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
public string PaymentMethod { get; set; }
|
||||
|
||||
public OnChainPaymentMethodData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public OnChainPaymentMethodData(string cryptoCode, string derivationScheme, bool enabled, string label, RootedKeyPath accountKeyPath, string paymentMethod) :
|
||||
base(cryptoCode, derivationScheme, label, accountKeyPath)
|
||||
{
|
||||
Enabled = enabled;
|
||||
PaymentMethod = paymentMethod;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
using BTCPayServer.Client.JsonConverters;
|
||||
using NBitcoin;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public class OnChainPaymentMethodDataWithSensitiveData : OnChainPaymentMethodData
|
||||
{
|
||||
public OnChainPaymentMethodDataWithSensitiveData()
|
||||
{
|
||||
}
|
||||
|
||||
public OnChainPaymentMethodDataWithSensitiveData(string cryptoCode, string derivationScheme, bool enabled,
|
||||
string label, RootedKeyPath accountKeyPath, Mnemonic mnemonic, string paymentMethod) : base(cryptoCode, derivationScheme, enabled,
|
||||
label, accountKeyPath, paymentMethod)
|
||||
{
|
||||
Mnemonic = mnemonic;
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(MnemonicJsonConverter))]
|
||||
public Mnemonic Mnemonic { get; set; }
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BTCPayServer.Client.JsonConverters;
|
||||
using BTCPayServer.JsonConverters;
|
||||
using NBitcoin;
|
||||
using NBitcoin.JsonConverters;
|
||||
@ -13,7 +12,7 @@ namespace BTCPayServer.Client.Models
|
||||
public string Comment { get; set; }
|
||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||
public decimal Amount { get; set; }
|
||||
[JsonConverter(typeof(SaneOutpointJsonConverter))]
|
||||
[JsonConverter(typeof(OutpointJsonConverter))]
|
||||
public OutPoint Outpoint { get; set; }
|
||||
public string Link { get; set; }
|
||||
#pragma warning disable CS0612 // Type or member is obsolete
|
||||
|
@ -17,6 +17,9 @@ namespace BTCPayServer.Client.Models
|
||||
public string Title { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Email { get; set; }
|
||||
|
||||
public string EmbeddedCSS { get; set; }
|
||||
public string CustomCSSLink { get; set; }
|
||||
public bool AllowCustomPaymentAmounts { get; set; }
|
||||
|
||||
[JsonExtensionData]
|
||||
|
@ -1,50 +1,72 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Client.Models;
|
||||
|
||||
public abstract class PointOfSaleBaseData : AppBaseData
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public string? Title { get; set; }
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public PosViewType? DefaultView { get; set; }
|
||||
public bool? ShowItems { get; set; }
|
||||
public bool? ShowCustomAmount { get; set; }
|
||||
public bool? ShowDiscount { get; set; }
|
||||
public bool? ShowSearch { get; set; }
|
||||
public bool? ShowCategories { get; set; }
|
||||
public bool? EnableTips { get; set; }
|
||||
public string? Currency { get; set; }
|
||||
public string? FixedAmountPayButtonText { get; set; }
|
||||
public string? CustomAmountPayButtonText { get; set; }
|
||||
public string? TipText { get; set; }
|
||||
public string? NotificationUrl { get; set; }
|
||||
public string? RedirectUrl { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool? RedirectAutomatically { get; set; }
|
||||
public int[]? CustomTipPercentages { get; set; }
|
||||
public string? FormId { get; set; }
|
||||
[JsonExtensionData]
|
||||
public IDictionary<string, JToken> AdditionalData { get; set; } = new Dictionary<string, JToken>();
|
||||
}
|
||||
public class AppDataBase
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string AppType { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string StoreId { get; set; }
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? Archived { get; set; }
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset Created { get; set; }
|
||||
}
|
||||
|
||||
public class PointOfSaleAppData : PointOfSaleBaseData
|
||||
{
|
||||
public object? Items { get; set; }
|
||||
}
|
||||
public class PointOfSaleAppData : AppDataBase
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string DefaultView { get; set; }
|
||||
public bool ShowItems { get; set; }
|
||||
public bool ShowCustomAmount { get; set; }
|
||||
public bool ShowDiscount { get; set; }
|
||||
public bool ShowSearch { get; set; }
|
||||
public bool ShowCategories { get; set; }
|
||||
public bool EnableTips { get; set; }
|
||||
public string Currency { get; set; }
|
||||
public object Items { get; set; }
|
||||
public string FixedAmountPayButtonText { get; set; }
|
||||
public string CustomAmountPayButtonText { get; set; }
|
||||
public string TipText { get; set; }
|
||||
public string CustomCSSLink { get; set; }
|
||||
public string NotificationUrl { get; set; }
|
||||
public string RedirectUrl { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string EmbeddedCSS { get; set; }
|
||||
public bool? RedirectAutomatically { get; set; }
|
||||
public bool? RequiresRefundEmail { get; set; }
|
||||
}
|
||||
|
||||
public class PointOfSaleAppRequest : PointOfSaleBaseData, IAppRequest
|
||||
{
|
||||
public string? Template { get; set; }
|
||||
}
|
||||
|
||||
public enum PosViewType
|
||||
{
|
||||
Static,
|
||||
Cart,
|
||||
Light,
|
||||
Print
|
||||
public class CrowdfundAppData : AppDataBase
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public bool EnforceTargetAmount { get; set; }
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset? StartDate { get; set; }
|
||||
public string TargetCurrency { get; set; }
|
||||
public string Description { get; set; }
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset? EndDate { get; set; }
|
||||
public decimal? TargetAmount { get; set; }
|
||||
public string CustomCSSLink { get; set; }
|
||||
public string MainImageUrl { get; set; }
|
||||
public string EmbeddedCSS { get; set; }
|
||||
public string NotificationUrl { get; set; }
|
||||
public string Tagline { get; set; }
|
||||
public object Perks { get; set; }
|
||||
public bool DisqusEnabled { get; set; }
|
||||
public string DisqusShortname { get; set; }
|
||||
public bool SoundsEnabled { get; set; }
|
||||
public bool AnimationsEnabled { get; set; }
|
||||
public int ResetEveryAmount { get; set; }
|
||||
public string ResetEvery { get; set; }
|
||||
public bool DisplayPerksValue { get; set; }
|
||||
public bool DisplayPerksRanking { get; set; }
|
||||
public bool SortPerksByPopularity { get; set; }
|
||||
public string[] Sounds { get; set; }
|
||||
public string[] AnimationColors { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ namespace BTCPayServer.Client.Models
|
||||
public string Currency { get; set; }
|
||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||
public decimal Amount { get; set; }
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||
public TimeSpan? Period { get; set; }
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Days))]
|
||||
[JsonProperty("BOLT11Expiration")]
|
||||
public TimeSpan BOLT11Expiration { get; set; }
|
||||
|
@ -16,11 +16,6 @@ namespace BTCPayServer.Client.Models
|
||||
|
||||
public string Website { get; set; }
|
||||
|
||||
public string BrandColor { get; set; }
|
||||
public string LogoUrl { get; set; }
|
||||
public string CssUrl { get; set; }
|
||||
public string PaymentSoundUrl { get; set; }
|
||||
|
||||
public string SupportUrl { get; set; }
|
||||
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||
@ -41,6 +36,11 @@ namespace BTCPayServer.Client.Models
|
||||
public double PaymentTolerance { get; set; } = 0;
|
||||
public bool AnyoneCanCreateInvoice { get; set; }
|
||||
public string DefaultCurrency { get; set; }
|
||||
public bool RequiresRefundEmail { get; set; }
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public CheckoutType? CheckoutType { get; set; }
|
||||
|
||||
public bool LightningAmountInSatoshi { get; set; }
|
||||
public bool LightningPrivateRouteHints { get; set; }
|
||||
@ -61,6 +61,10 @@ namespace BTCPayServer.Client.Models
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string DefaultLang { get; set; } = "en";
|
||||
|
||||
public string CustomLogo { get; set; }
|
||||
|
||||
public string CustomCSS { get; set; }
|
||||
|
||||
public string HtmlTitle { get; set; }
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
@ -90,6 +94,12 @@ namespace BTCPayServer.Client.Models
|
||||
public IDictionary<string, JToken> AdditionalData { get; set; }
|
||||
}
|
||||
|
||||
public enum CheckoutType
|
||||
{
|
||||
V1,
|
||||
V2
|
||||
}
|
||||
|
||||
public enum NetworkFeeMode
|
||||
{
|
||||
MultiplePaymentsOnly,
|
||||
|
@ -1,29 +0,0 @@
|
||||
namespace BTCPayServer.Client.Models;
|
||||
|
||||
public class UpdateApplicationUserRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// the name of the user
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// the image url of the user
|
||||
/// </summary>
|
||||
public string ImageUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// the email AND username of the user
|
||||
/// </summary>
|
||||
public string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// current password of the user
|
||||
/// </summary>
|
||||
public string CurrentPassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// new password of the user
|
||||
/// </summary>
|
||||
public string NewPassword { get; set; }
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public class UpdateLightningNetworkPaymentMethodRequest : LightningNetworkPaymentMethodBaseData
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the payment method is enabled
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
public UpdateLightningNetworkPaymentMethodRequest()
|
||||
{
|
||||
}
|
||||
|
||||
public UpdateLightningNetworkPaymentMethodRequest(string connectionString, bool enabled)
|
||||
{
|
||||
Enabled = enabled;
|
||||
ConnectionString = connectionString;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BTCPayServer.Client.Models;
|
||||
|
||||
public class UpdateNotificationSettingsRequest
|
||||
{
|
||||
public List<string> Disabled { get; set; }
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public class UpdateOnChainPaymentMethodRequest : OnChainPaymentMethodBaseData
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the payment method is enabled
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
public UpdateOnChainPaymentMethodRequest()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public UpdateOnChainPaymentMethodRequest(bool enabled, string derivationScheme, string label, RootedKeyPath accountKeyPath)
|
||||
{
|
||||
Enabled = enabled;
|
||||
Label = label;
|
||||
AccountKeyPath = accountKeyPath;
|
||||
DerivationScheme = derivationScheme;
|
||||
}
|
||||
}
|
||||
}
|
@ -91,7 +91,7 @@ namespace BTCPayServer.Client.Models
|
||||
}
|
||||
|
||||
public bool AfterExpiration { get; set; }
|
||||
public string PaymentMethodId { get; set; }
|
||||
public string PaymentMethod { get; set; }
|
||||
public InvoicePaymentMethodDataModel.Payment Payment { get; set; }
|
||||
}
|
||||
|
||||
|
@ -130,11 +130,6 @@ namespace BTCPayServer
|
||||
{
|
||||
return transactionInformationSet;
|
||||
}
|
||||
|
||||
public string GetTrackedDestination(Script scriptPubKey)
|
||||
{
|
||||
return scriptPubKey.Hash.ToString() + "#" + CryptoCode.ToUpperInvariant();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BTCPayNetworkBase
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
<PackageReference Include="NBXplorer.Client" Version="4.3.1" />
|
||||
<PackageReference Include="NBXplorer.Client" Version="4.3.0" />
|
||||
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="2.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(Altcoins)' != 'true'">
|
||||
|
@ -12,22 +12,35 @@ namespace BTCPayServer.Data
|
||||
{
|
||||
public ApplicationDbContext CreateDbContext(string[] args)
|
||||
{
|
||||
|
||||
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
|
||||
// Same as launchsettings.json, it's connecting to the docker's postgres.
|
||||
builder.UseNpgsql("User ID=postgres;Include Error Detail=true;Host=127.0.0.1;Port=39372;Database=btcpayserver");
|
||||
return new ApplicationDbContext(builder.Options);
|
||||
|
||||
builder.UseSqlite("Data Source=temp.db");
|
||||
|
||||
return new ApplicationDbContext(builder.Options, true);
|
||||
}
|
||||
}
|
||||
|
||||
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
|
||||
{
|
||||
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
|
||||
private readonly bool _designTime;
|
||||
|
||||
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, bool designTime = false)
|
||||
: base(options)
|
||||
{
|
||||
_designTime = designTime;
|
||||
}
|
||||
#nullable enable
|
||||
public async Task<string?> GetMigrationState()
|
||||
{
|
||||
return (await Settings.FromSqlRaw("SELECT \"Id\", \"Value\" FROM \"Settings\" WHERE \"Id\"='MigrationData'").AsNoTracking().FirstOrDefaultAsync())?.Value;
|
||||
}
|
||||
#nullable restore
|
||||
public DbSet<AddressInvoiceData> AddressInvoices { get; set; }
|
||||
public DbSet<APIKeyData> ApiKeys { get; set; }
|
||||
public DbSet<AppData> Apps { get; set; }
|
||||
public DbSet<StoredFile> Files { get; set; }
|
||||
public DbSet<InvoiceEventData> InvoiceEvents { get; set; }
|
||||
public DbSet<InvoiceSearchData> InvoiceSearches { get; set; }
|
||||
public DbSet<InvoiceWebhookDeliveryData> InvoiceWebhookDeliveries { get; set; }
|
||||
public DbSet<InvoiceData> Invoices { get; set; }
|
||||
@ -63,6 +76,13 @@ namespace BTCPayServer.Data
|
||||
public DbSet<PayoutProcessorData> PayoutProcessors { get; set; }
|
||||
public DbSet<FormData> Forms { get; set; }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
var isConfigured = optionsBuilder.Options.Extensions.OfType<RelationalOptionsExtension>().Any();
|
||||
if (!isConfigured)
|
||||
optionsBuilder.UseSqlite("Data Source=temp.db");
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
@ -74,6 +94,7 @@ namespace BTCPayServer.Data
|
||||
APIKeyData.OnModelCreating(builder, Database);
|
||||
AppData.OnModelCreating(builder, Database);
|
||||
//StoredFile.OnModelCreating(builder);
|
||||
InvoiceEventData.OnModelCreating(builder);
|
||||
InvoiceSearchData.OnModelCreating(builder);
|
||||
InvoiceWebhookDeliveryData.OnModelCreating(builder);
|
||||
InvoiceData.OnModelCreating(builder, Database);
|
||||
@ -108,6 +129,28 @@ namespace BTCPayServer.Data
|
||||
WebhookData.OnModelCreating(builder, Database);
|
||||
FormData.OnModelCreating(builder, Database);
|
||||
StoreRole.OnModelCreating(builder, Database);
|
||||
|
||||
|
||||
if (Database.IsSqlite() && !_designTime)
|
||||
{
|
||||
// SQLite does not have proper support for DateTimeOffset via Entity Framework Core, see the limitations
|
||||
// here: https://docs.microsoft.com/en-us/ef/core/providers/sqlite/limitations#query-limitations
|
||||
// To work around this, when the Sqlite database provider is used, all model properties of type DateTimeOffset
|
||||
// use the DateTimeOffsetToBinaryConverter
|
||||
// Based on: https://github.com/aspnet/EntityFrameworkCore/issues/10784#issuecomment-415769754
|
||||
// This only supports millisecond precision, but should be sufficient for most use cases.
|
||||
foreach (var entityType in builder.Model.GetEntityTypes())
|
||||
{
|
||||
var properties = entityType.ClrType.GetProperties().Where(p => p.PropertyType == typeof(DateTimeOffset));
|
||||
foreach (var property in properties)
|
||||
{
|
||||
builder
|
||||
.Entity(entityType.Name)
|
||||
.Property(property.Name)
|
||||
.HasConversion(new Microsoft.EntityFrameworkCore.Storage.ValueConversion.DateTimeOffsetToBinaryConverter());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ using BTCPayServer.Abstractions.Contracts;
|
||||
using BTCPayServer.Abstractions.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure;
|
||||
|
||||
namespace BTCPayServer.Data
|
||||
{
|
||||
@ -15,11 +14,10 @@ namespace BTCPayServer.Data
|
||||
{
|
||||
}
|
||||
|
||||
public override ApplicationDbContext CreateContext(Action<NpgsqlDbContextOptionsBuilder> npgsqlOptionsAction = null)
|
||||
public override ApplicationDbContext CreateContext()
|
||||
{
|
||||
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
|
||||
builder.AddInterceptors(Data.InvoiceData.MigrationInterceptor.Instance);
|
||||
ConfigureBuilder(builder, npgsqlOptionsAction);
|
||||
ConfigureBuilder(builder);
|
||||
return new ApplicationDbContext(builder.Options);
|
||||
}
|
||||
}
|
||||
|
@ -3,18 +3,14 @@
|
||||
<Import Project="../Build/Common.csproj" />
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.5">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.5" />
|
||||
<PackageReference Include="NBitcoin.Altcoins" Version="3.0.24" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BTCPayServer.Abstractions\BTCPayServer.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\BTCPayServer.Client\BTCPayServer.Client.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="DBScripts\*.sql" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -1,301 +0,0 @@
|
||||
CREATE TABLE "AddressInvoices" (
|
||||
"Address" text NOT NULL,
|
||||
"InvoiceDataId" text,
|
||||
"CreatedTime" timestamp with time zone
|
||||
);
|
||||
CREATE TABLE "ApiKeys" (
|
||||
"Id" character varying(50) NOT NULL,
|
||||
"StoreId" character varying(50),
|
||||
"Permissions" text,
|
||||
"Type" integer DEFAULT 0 NOT NULL,
|
||||
"UserId" character varying(50),
|
||||
"Label" text
|
||||
);
|
||||
CREATE TABLE "Apps" (
|
||||
"Id" text NOT NULL,
|
||||
"AppType" text,
|
||||
"Created" timestamp with time zone NOT NULL,
|
||||
"Name" text,
|
||||
"Settings" text,
|
||||
"StoreDataId" text,
|
||||
"TagAllInvoices" boolean DEFAULT false NOT NULL
|
||||
);
|
||||
CREATE TABLE "AspNetRoleClaims" (
|
||||
"Id" integer NOT NULL,
|
||||
"ClaimType" text,
|
||||
"ClaimValue" text,
|
||||
"RoleId" text NOT NULL
|
||||
);
|
||||
CREATE TABLE "AspNetRoles" (
|
||||
"Id" text NOT NULL,
|
||||
"ConcurrencyStamp" text,
|
||||
"Name" character varying(256),
|
||||
"NormalizedName" character varying(256)
|
||||
);
|
||||
CREATE TABLE "AspNetUserClaims" (
|
||||
"Id" integer NOT NULL,
|
||||
"ClaimType" text,
|
||||
"ClaimValue" text,
|
||||
"UserId" text NOT NULL
|
||||
);
|
||||
CREATE TABLE "AspNetUserLogins" (
|
||||
"LoginProvider" character varying(255) NOT NULL,
|
||||
"ProviderKey" character varying(255) NOT NULL,
|
||||
"ProviderDisplayName" text,
|
||||
"UserId" text NOT NULL
|
||||
);
|
||||
CREATE TABLE "AspNetUserRoles" (
|
||||
"UserId" text NOT NULL,
|
||||
"RoleId" text NOT NULL
|
||||
);
|
||||
CREATE TABLE "AspNetUserTokens" (
|
||||
"UserId" text NOT NULL,
|
||||
"LoginProvider" character varying(64) NOT NULL,
|
||||
"Name" character varying(64) NOT NULL,
|
||||
"Value" text
|
||||
);
|
||||
CREATE TABLE "AspNetUsers" (
|
||||
"Id" text NOT NULL,
|
||||
"AccessFailedCount" integer NOT NULL,
|
||||
"ConcurrencyStamp" text,
|
||||
"Email" character varying(256),
|
||||
"EmailConfirmed" boolean NOT NULL,
|
||||
"LockoutEnabled" boolean NOT NULL,
|
||||
"LockoutEnd" timestamp with time zone,
|
||||
"NormalizedEmail" character varying(256),
|
||||
"NormalizedUserName" character varying(256),
|
||||
"PasswordHash" text,
|
||||
"PhoneNumber" text,
|
||||
"PhoneNumberConfirmed" boolean NOT NULL,
|
||||
"SecurityStamp" text,
|
||||
"TwoFactorEnabled" boolean NOT NULL,
|
||||
"UserName" character varying(256),
|
||||
"RequiresEmailConfirmation" boolean DEFAULT false NOT NULL
|
||||
);
|
||||
CREATE TABLE "Files" (
|
||||
"Id" text NOT NULL,
|
||||
"FileName" text,
|
||||
"StorageFileName" text,
|
||||
"Timestamp" timestamp with time zone NOT NULL,
|
||||
"ApplicationUserId" text
|
||||
);
|
||||
CREATE TABLE "HistoricalAddressInvoices" (
|
||||
"InvoiceDataId" text NOT NULL,
|
||||
"Address" text NOT NULL,
|
||||
"Assigned" timestamp with time zone NOT NULL,
|
||||
"UnAssigned" timestamp with time zone,
|
||||
"CryptoCode" text
|
||||
);
|
||||
CREATE TABLE "InvoiceEvents" (
|
||||
"InvoiceDataId" text NOT NULL,
|
||||
"UniqueId" text NOT NULL,
|
||||
"Message" text,
|
||||
"Timestamp" timestamp with time zone NOT NULL
|
||||
);
|
||||
CREATE TABLE "Invoices" (
|
||||
"Id" text NOT NULL,
|
||||
"Blob" bytea,
|
||||
"Created" timestamp with time zone NOT NULL,
|
||||
"CustomerEmail" text,
|
||||
"ExceptionStatus" text,
|
||||
"ItemCode" text,
|
||||
"OrderId" text,
|
||||
"Status" text,
|
||||
"StoreDataId" text
|
||||
);
|
||||
CREATE TABLE "PairedSINData" (
|
||||
"Id" text NOT NULL,
|
||||
"Label" text,
|
||||
"PairingTime" timestamp with time zone NOT NULL,
|
||||
"SIN" text,
|
||||
"StoreDataId" text
|
||||
);
|
||||
CREATE TABLE "PairingCodes" (
|
||||
"Id" text NOT NULL,
|
||||
"DateCreated" timestamp with time zone NOT NULL,
|
||||
"Expiration" timestamp with time zone NOT NULL,
|
||||
"Facade" text,
|
||||
"Label" text,
|
||||
"SIN" text,
|
||||
"StoreDataId" text,
|
||||
"TokenValue" text
|
||||
);
|
||||
CREATE TABLE "PaymentRequests" (
|
||||
"Id" text NOT NULL,
|
||||
"StoreDataId" text,
|
||||
"Status" integer NOT NULL,
|
||||
"Blob" bytea,
|
||||
"Created" timestamp with time zone DEFAULT '1970-01-01 00:00:00+00'::timestamp with time zone NOT NULL
|
||||
);
|
||||
CREATE TABLE "Payments" (
|
||||
"Id" text NOT NULL,
|
||||
"Blob" bytea,
|
||||
"InvoiceDataId" text,
|
||||
"Accounted" boolean DEFAULT false NOT NULL
|
||||
);
|
||||
CREATE TABLE "PendingInvoices" (
|
||||
"Id" text NOT NULL
|
||||
);
|
||||
CREATE TABLE "RefundAddresses" (
|
||||
"Id" text NOT NULL,
|
||||
"Blob" bytea,
|
||||
"InvoiceDataId" text
|
||||
);
|
||||
CREATE TABLE "Settings" (
|
||||
"Id" text NOT NULL,
|
||||
"Value" text
|
||||
);
|
||||
CREATE TABLE "Stores" (
|
||||
"Id" text NOT NULL,
|
||||
"DerivationStrategy" text,
|
||||
"SpeedPolicy" integer NOT NULL,
|
||||
"StoreCertificate" bytea,
|
||||
"StoreName" text,
|
||||
"StoreWebsite" text,
|
||||
"StoreBlob" bytea,
|
||||
"DerivationStrategies" text,
|
||||
"DefaultCrypto" text
|
||||
);
|
||||
CREATE TABLE "U2FDevices" (
|
||||
"Id" text NOT NULL,
|
||||
"Name" text,
|
||||
"KeyHandle" bytea NOT NULL,
|
||||
"PublicKey" bytea NOT NULL,
|
||||
"AttestationCert" bytea NOT NULL,
|
||||
"Counter" integer NOT NULL,
|
||||
"ApplicationUserId" text
|
||||
);
|
||||
CREATE TABLE "UserStore" (
|
||||
"ApplicationUserId" text NOT NULL,
|
||||
"StoreDataId" text NOT NULL,
|
||||
"Role" text
|
||||
);
|
||||
CREATE TABLE "WalletTransactions" (
|
||||
"WalletDataId" text NOT NULL,
|
||||
"TransactionId" text NOT NULL,
|
||||
"Labels" text,
|
||||
"Blob" bytea
|
||||
);
|
||||
CREATE TABLE "Wallets" (
|
||||
"Id" text NOT NULL,
|
||||
"Blob" bytea
|
||||
);
|
||||
ALTER TABLE ONLY "AddressInvoices"
|
||||
ADD CONSTRAINT "PK_AddressInvoices" PRIMARY KEY ("Address");
|
||||
ALTER TABLE ONLY "ApiKeys"
|
||||
ADD CONSTRAINT "PK_ApiKeys" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "Apps"
|
||||
ADD CONSTRAINT "PK_Apps" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "AspNetRoleClaims"
|
||||
ADD CONSTRAINT "PK_AspNetRoleClaims" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "AspNetRoles"
|
||||
ADD CONSTRAINT "PK_AspNetRoles" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "AspNetUserClaims"
|
||||
ADD CONSTRAINT "PK_AspNetUserClaims" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "AspNetUserLogins"
|
||||
ADD CONSTRAINT "PK_AspNetUserLogins" PRIMARY KEY ("LoginProvider", "ProviderKey");
|
||||
ALTER TABLE ONLY "AspNetUserRoles"
|
||||
ADD CONSTRAINT "PK_AspNetUserRoles" PRIMARY KEY ("UserId", "RoleId");
|
||||
ALTER TABLE ONLY "AspNetUserTokens"
|
||||
ADD CONSTRAINT "PK_AspNetUserTokens" PRIMARY KEY ("UserId", "LoginProvider", "Name");
|
||||
ALTER TABLE ONLY "AspNetUsers"
|
||||
ADD CONSTRAINT "PK_AspNetUsers" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "Files"
|
||||
ADD CONSTRAINT "PK_Files" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "HistoricalAddressInvoices"
|
||||
ADD CONSTRAINT "PK_HistoricalAddressInvoices" PRIMARY KEY ("InvoiceDataId", "Address");
|
||||
ALTER TABLE ONLY "InvoiceEvents"
|
||||
ADD CONSTRAINT "PK_InvoiceEvents" PRIMARY KEY ("InvoiceDataId", "UniqueId");
|
||||
ALTER TABLE ONLY "Invoices"
|
||||
ADD CONSTRAINT "PK_Invoices" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "PairedSINData"
|
||||
ADD CONSTRAINT "PK_PairedSINData" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "PairingCodes"
|
||||
ADD CONSTRAINT "PK_PairingCodes" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "PaymentRequests"
|
||||
ADD CONSTRAINT "PK_PaymentRequests" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "Payments"
|
||||
ADD CONSTRAINT "PK_Payments" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "PendingInvoices"
|
||||
ADD CONSTRAINT "PK_PendingInvoices" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "RefundAddresses"
|
||||
ADD CONSTRAINT "PK_RefundAddresses" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "Settings"
|
||||
ADD CONSTRAINT "PK_Settings" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "Stores"
|
||||
ADD CONSTRAINT "PK_Stores" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "U2FDevices"
|
||||
ADD CONSTRAINT "PK_U2FDevices" PRIMARY KEY ("Id");
|
||||
ALTER TABLE ONLY "UserStore"
|
||||
ADD CONSTRAINT "PK_UserStore" PRIMARY KEY ("ApplicationUserId", "StoreDataId");
|
||||
ALTER TABLE ONLY "WalletTransactions"
|
||||
ADD CONSTRAINT "PK_WalletTransactions" PRIMARY KEY ("WalletDataId", "TransactionId");
|
||||
ALTER TABLE ONLY "Wallets"
|
||||
ADD CONSTRAINT "PK_Wallets" PRIMARY KEY ("Id");
|
||||
CREATE INDEX "EmailIndex" ON "AspNetUsers" USING btree ("NormalizedEmail");
|
||||
CREATE INDEX "IX_AddressInvoices_InvoiceDataId" ON "AddressInvoices" USING btree ("InvoiceDataId");
|
||||
CREATE INDEX "IX_ApiKeys_StoreId" ON "ApiKeys" USING btree ("StoreId");
|
||||
CREATE INDEX "IX_ApiKeys_UserId" ON "ApiKeys" USING btree ("UserId");
|
||||
CREATE INDEX "IX_Apps_StoreDataId" ON "Apps" USING btree ("StoreDataId");
|
||||
CREATE INDEX "IX_AspNetRoleClaims_RoleId" ON "AspNetRoleClaims" USING btree ("RoleId");
|
||||
CREATE INDEX "IX_AspNetUserClaims_UserId" ON "AspNetUserClaims" USING btree ("UserId");
|
||||
CREATE INDEX "IX_AspNetUserLogins_UserId" ON "AspNetUserLogins" USING btree ("UserId");
|
||||
CREATE INDEX "IX_AspNetUserRoles_RoleId" ON "AspNetUserRoles" USING btree ("RoleId");
|
||||
CREATE INDEX "IX_Files_ApplicationUserId" ON "Files" USING btree ("ApplicationUserId");
|
||||
CREATE INDEX "IX_Invoices_StoreDataId" ON "Invoices" USING btree ("StoreDataId");
|
||||
CREATE INDEX "IX_PairedSINData_SIN" ON "PairedSINData" USING btree ("SIN");
|
||||
CREATE INDEX "IX_PairedSINData_StoreDataId" ON "PairedSINData" USING btree ("StoreDataId");
|
||||
CREATE INDEX "IX_PaymentRequests_Status" ON "PaymentRequests" USING btree ("Status");
|
||||
CREATE INDEX "IX_PaymentRequests_StoreDataId" ON "PaymentRequests" USING btree ("StoreDataId");
|
||||
CREATE INDEX "IX_Payments_InvoiceDataId" ON "Payments" USING btree ("InvoiceDataId");
|
||||
CREATE INDEX "IX_RefundAddresses_InvoiceDataId" ON "RefundAddresses" USING btree ("InvoiceDataId");
|
||||
CREATE INDEX "IX_U2FDevices_ApplicationUserId" ON "U2FDevices" USING btree ("ApplicationUserId");
|
||||
CREATE INDEX "IX_UserStore_StoreDataId" ON "UserStore" USING btree ("StoreDataId");
|
||||
CREATE UNIQUE INDEX "RoleNameIndex" ON "AspNetRoles" USING btree ("NormalizedName");
|
||||
CREATE UNIQUE INDEX "UserNameIndex" ON "AspNetUsers" USING btree ("NormalizedUserName");
|
||||
ALTER TABLE ONLY "AddressInvoices"
|
||||
ADD CONSTRAINT "FK_AddressInvoices_Invoices_InvoiceDataId" FOREIGN KEY ("InvoiceDataId") REFERENCES "Invoices"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "ApiKeys"
|
||||
ADD CONSTRAINT "FK_ApiKeys_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "ApiKeys"
|
||||
ADD CONSTRAINT "FK_ApiKeys_Stores_StoreId" FOREIGN KEY ("StoreId") REFERENCES "Stores"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "Apps"
|
||||
ADD CONSTRAINT "FK_Apps_Stores_StoreDataId" FOREIGN KEY ("StoreDataId") REFERENCES "Stores"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "AspNetRoleClaims"
|
||||
ADD CONSTRAINT "FK_AspNetRoleClaims_AspNetRoles_RoleId" FOREIGN KEY ("RoleId") REFERENCES "AspNetRoles"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "AspNetUserClaims"
|
||||
ADD CONSTRAINT "FK_AspNetUserClaims_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "AspNetUserLogins"
|
||||
ADD CONSTRAINT "FK_AspNetUserLogins_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "AspNetUserRoles"
|
||||
ADD CONSTRAINT "FK_AspNetUserRoles_AspNetRoles_RoleId" FOREIGN KEY ("RoleId") REFERENCES "AspNetRoles"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "AspNetUserRoles"
|
||||
ADD CONSTRAINT "FK_AspNetUserRoles_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "AspNetUserTokens"
|
||||
ADD CONSTRAINT "FK_AspNetUserTokens_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "Files"
|
||||
ADD CONSTRAINT "FK_Files_AspNetUsers_ApplicationUserId" FOREIGN KEY ("ApplicationUserId") REFERENCES "AspNetUsers"("Id") ON DELETE RESTRICT;
|
||||
ALTER TABLE ONLY "HistoricalAddressInvoices"
|
||||
ADD CONSTRAINT "FK_HistoricalAddressInvoices_Invoices_InvoiceDataId" FOREIGN KEY ("InvoiceDataId") REFERENCES "Invoices"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "InvoiceEvents"
|
||||
ADD CONSTRAINT "FK_InvoiceEvents_Invoices_InvoiceDataId" FOREIGN KEY ("InvoiceDataId") REFERENCES "Invoices"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "Invoices"
|
||||
ADD CONSTRAINT "FK_Invoices_Stores_StoreDataId" FOREIGN KEY ("StoreDataId") REFERENCES "Stores"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "PairedSINData"
|
||||
ADD CONSTRAINT "FK_PairedSINData_Stores_StoreDataId" FOREIGN KEY ("StoreDataId") REFERENCES "Stores"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "PaymentRequests"
|
||||
ADD CONSTRAINT "FK_PaymentRequests_Stores_StoreDataId" FOREIGN KEY ("StoreDataId") REFERENCES "Stores"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "Payments"
|
||||
ADD CONSTRAINT "FK_Payments_Invoices_InvoiceDataId" FOREIGN KEY ("InvoiceDataId") REFERENCES "Invoices"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "PendingInvoices"
|
||||
ADD CONSTRAINT "FK_PendingInvoices_Invoices_Id" FOREIGN KEY ("Id") REFERENCES "Invoices"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "RefundAddresses"
|
||||
ADD CONSTRAINT "FK_RefundAddresses_Invoices_InvoiceDataId" FOREIGN KEY ("InvoiceDataId") REFERENCES "Invoices"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "U2FDevices"
|
||||
ADD CONSTRAINT "FK_U2FDevices_AspNetUsers_ApplicationUserId" FOREIGN KEY ("ApplicationUserId") REFERENCES "AspNetUsers"("Id") ON DELETE RESTRICT;
|
||||
ALTER TABLE ONLY "UserStore"
|
||||
ADD CONSTRAINT "FK_UserStore_AspNetUsers_ApplicationUserId" FOREIGN KEY ("ApplicationUserId") REFERENCES "AspNetUsers"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "UserStore"
|
||||
ADD CONSTRAINT "FK_UserStore_Stores_StoreDataId" FOREIGN KEY ("StoreDataId") REFERENCES "Stores"("Id") ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY "WalletTransactions"
|
||||
ADD CONSTRAINT "FK_WalletTransactions_Wallets_WalletDataId" FOREIGN KEY ("WalletDataId") REFERENCES "Wallets"("Id") ON DELETE CASCADE;
|
@ -1,37 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace BTCPayServer.Data
|
||||
{
|
||||
public abstract class DBScriptsMigration : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
foreach (var script in GetType().GetCustomAttributes<DBScriptAttribute>().OrderBy(n => n.ScriptName))
|
||||
{
|
||||
var name = Assembly.GetExecutingAssembly().GetManifestResourceNames()
|
||||
.First(s => s.EndsWith("." + script.ScriptName, StringComparison.Ordinal));
|
||||
var stream = Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceStream(name);
|
||||
using var reader = new StreamReader(stream, Encoding.UTF8);
|
||||
migrationBuilder.Sql(reader.ReadToEnd());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
||||
public class DBScriptAttribute : Attribute
|
||||
{
|
||||
public DBScriptAttribute(string scriptName)
|
||||
{
|
||||
ScriptName = scriptName;
|
||||
}
|
||||
public string ScriptName { get; set; }
|
||||
}
|
||||
}
|
@ -41,9 +41,12 @@ namespace BTCPayServer.Data
|
||||
builder.Entity<APIKeyData>()
|
||||
.HasIndex(o => o.StoreId);
|
||||
|
||||
builder.Entity<APIKeyData>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<APIKeyData>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,9 +6,15 @@ namespace BTCPayServer.Data
|
||||
{
|
||||
public class AddressInvoiceData
|
||||
{
|
||||
/// <summary>
|
||||
/// Some crypto currencies share same address prefix
|
||||
/// For not having exceptions thrown by two address on different network, we suffix by "#CRYPTOCODE"
|
||||
/// </summary>
|
||||
[Obsolete("Use GetHash instead")]
|
||||
public string Address { get; set; }
|
||||
public InvoiceData InvoiceData { get; set; }
|
||||
public string InvoiceDataId { get; set; }
|
||||
public DateTimeOffset? CreatedTime { get; set; }
|
||||
|
||||
|
||||
internal static void OnModelCreating(ModelBuilder builder)
|
||||
|
@ -25,9 +25,12 @@ namespace BTCPayServer.Data
|
||||
builder.Entity<AppData>()
|
||||
.HasOne(a => a.StoreData);
|
||||
|
||||
builder.Entity<AppData>()
|
||||
.Property(o => o.Settings)
|
||||
.HasColumnType("JSONB");
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<AppData>()
|
||||
.Property(o => o.Settings)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
}
|
||||
|
||||
// utility methods
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Data
|
||||
{
|
||||
@ -18,7 +19,7 @@ namespace BTCPayServer.Data
|
||||
public List<APIKeyData> APIKeys { get; set; }
|
||||
public DateTimeOffset? Created { get; set; }
|
||||
public string DisabledNotifications { get; set; }
|
||||
|
||||
|
||||
public List<NotificationData> Notifications { get; set; }
|
||||
public List<UserStore> UserStores { get; set; }
|
||||
public List<Fido2Credential> Fido2Credentials { get; set; }
|
||||
@ -34,17 +35,17 @@ namespace BTCPayServer.Data
|
||||
builder.Entity<ApplicationUser>()
|
||||
.HasMany<IdentityUserRole<string>>(user => user.UserRoles)
|
||||
.WithOne().HasForeignKey(role => role.UserId);
|
||||
|
||||
builder.Entity<ApplicationUser>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<ApplicationUser>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UserBlob
|
||||
{
|
||||
public bool ShowInvoiceStatusChangeHint { get; set; }
|
||||
public string ImageUrl { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -30,10 +30,12 @@ namespace BTCPayServer.Data
|
||||
.HasOne(o => o.ApplicationUser)
|
||||
.WithMany(i => i.Fido2Credentials)
|
||||
.HasForeignKey(i => i.ApplicationUserId).OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.Entity<Fido2Credential>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<Fido2Credential>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
}
|
||||
|
||||
public ApplicationUser ApplicationUser { get; set; }
|
||||
|
@ -21,8 +21,11 @@ public class FormData
|
||||
.WithMany(o => o.Forms).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<FormData>().HasIndex(o => o.StoreId);
|
||||
|
||||
builder.Entity<FormData>()
|
||||
.Property(o => o.Config)
|
||||
.HasColumnType("JSONB");
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<FormData>()
|
||||
.Property(o => o.Config)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,394 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.IO.Compression;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
using BTCPayServer.Migrations;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
|
||||
|
||||
namespace BTCPayServer.Data
|
||||
{
|
||||
public partial class InvoiceData
|
||||
{
|
||||
/// <summary>
|
||||
/// We have a migration running in the background that will migrate the data from the old blob to the new blob
|
||||
/// Meanwhile, we need to make sure that invoices which haven't been migrated yet are migrated on the fly.
|
||||
/// </summary>
|
||||
public class MigrationInterceptor : IMaterializationInterceptor
|
||||
{
|
||||
public static readonly MigrationInterceptor Instance = new MigrationInterceptor();
|
||||
public object InitializedInstance(MaterializationInterceptionData materializationData, object entity)
|
||||
{
|
||||
if (entity is InvoiceData invoiceData && invoiceData.Currency is null)
|
||||
{
|
||||
invoiceData.Migrate();
|
||||
}
|
||||
else if (entity is PaymentData paymentData && paymentData.Currency is null)
|
||||
{
|
||||
paymentData.Migrate();
|
||||
}
|
||||
else if (entity is PayoutData payoutData && payoutData.Currency is null)
|
||||
{
|
||||
payoutData.Migrate();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
static HashSet<string> superflousProperties = new HashSet<string>()
|
||||
{
|
||||
"availableAddressHashes",
|
||||
"events",
|
||||
"refunds",
|
||||
"paidAmount",
|
||||
"historicalAddresses",
|
||||
"refundable",
|
||||
"status",
|
||||
"exceptionStatus",
|
||||
"storeId",
|
||||
"id",
|
||||
"txFee",
|
||||
"refundMail",
|
||||
"rate",
|
||||
"depositAddress",
|
||||
"currency",
|
||||
"price",
|
||||
"payments",
|
||||
"orderId",
|
||||
"buyerInformation",
|
||||
"productInformation",
|
||||
"derivationStrategy",
|
||||
"archived",
|
||||
"isUnderPaid",
|
||||
"requiresRefundEmail",
|
||||
"invoiceTime",
|
||||
"checkoutType",
|
||||
"customLogo",
|
||||
"customCSS"
|
||||
};
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
public void Migrate()
|
||||
{
|
||||
if (Currency is not null)
|
||||
return;
|
||||
if (Blob is not (null or { Length: 0 }))
|
||||
{
|
||||
Blob2 = MigrationExtensions.Unzip(Blob);
|
||||
Blob = null;
|
||||
}
|
||||
var blob = JObject.Parse(Blob2);
|
||||
if (blob["cryptoData"]?["BTC"] is not (null or { Type: JTokenType.Null }))
|
||||
{
|
||||
blob.Move(["rate"], ["cryptoData", "BTC", "rate"]);
|
||||
blob.Move(["txFee"], ["cryptoData", "BTC", "txFee"]);
|
||||
}
|
||||
blob.Move(["customerEmail"], ["metadata", "buyerEmail"]);
|
||||
foreach (var prop in (blob["cryptoData"] as JObject)?.Properties()?.ToList() ?? [])
|
||||
{
|
||||
// We should only change data for onchain
|
||||
if (prop.Name.Contains('_', StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (prop.Value is JObject pm)
|
||||
{
|
||||
pm.Remove("depositAddress");
|
||||
pm.Remove("feeRate");
|
||||
pm.Remove("txFee");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (prop.Value is JObject o)
|
||||
{
|
||||
o.ConvertNumberToString("rate");
|
||||
if (o["paymentMethod"] is JObject pm)
|
||||
{
|
||||
if (pm["networkFeeRate"] is null)
|
||||
pm["networkFeeRate"] = o["feeRate"] ?? 0.0m;
|
||||
if (pm["networkFeeMode"] is JValue { Type: JTokenType.Integer, Value: 0 or 0L })
|
||||
pm.Remove("networkFeeMode");
|
||||
if (pm["networkFeeMode"] is JValue { Type: JTokenType.Integer, Value: 2 or 2L })
|
||||
pm["networkFeeRate"] = 0.0m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var metadata = blob.Property("metadata")?.Value as JObject;
|
||||
if (metadata is null)
|
||||
{
|
||||
metadata = new JObject();
|
||||
blob.Add("metadata", metadata);
|
||||
}
|
||||
foreach (var prop in (blob["buyerInformation"] as JObject)?.Properties()?.ToList() ?? [])
|
||||
{
|
||||
if (prop.Value?.Value<string>() is not null)
|
||||
blob.Move(["buyerInformation", prop.Name], ["metadata", prop.Name]);
|
||||
}
|
||||
foreach (var prop in (blob["productInformation"] as JObject)?.Properties()?.ToList() ?? [])
|
||||
{
|
||||
if (prop.Name is "price" or "currency")
|
||||
blob.Move(["productInformation", prop.Name], [prop.Name]);
|
||||
else if (prop.Value?.Value<string>() is not null)
|
||||
blob.Move(["productInformation", prop.Name], ["metadata", prop.Name]);
|
||||
}
|
||||
blob.Move(["orderId"], ["metadata", "orderId"]);
|
||||
foreach (string prop in new string[] { "posData", "defaultLanguage", "notificationEmail", "notificationURL", "storeSupportUrl", "redirectURL" })
|
||||
{
|
||||
blob.RemoveIfNull(prop);
|
||||
}
|
||||
blob.RemoveIfValue<bool>("fullNotifications", false);
|
||||
if (blob["receiptOptions"] is JObject receiptOptions)
|
||||
{
|
||||
foreach (string prop in new string[] { "showQR", "enabled", "showPayments" })
|
||||
{
|
||||
receiptOptions.RemoveIfNull(prop);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (blob.Property("paymentTolerance") is JProperty { Value: { Type: JTokenType.Float } pv } prop)
|
||||
{
|
||||
if (pv.Value<decimal>() == 0.0m)
|
||||
prop.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
var posData = blob.Move(["posData"], ["metadata", "posData"]);
|
||||
if (posData is not null && posData.Value?.Type is JTokenType.String)
|
||||
{
|
||||
try
|
||||
{
|
||||
posData.Value = JObject.Parse(posData.Value<string>());
|
||||
}
|
||||
catch
|
||||
{
|
||||
posData.Remove();
|
||||
}
|
||||
}
|
||||
if (posData?.Type is JTokenType.Null)
|
||||
posData.Remove();
|
||||
|
||||
if (blob["derivationStrategies"] is JValue { Type: JTokenType.String } v)
|
||||
blob["derivationStrategies"] = JObject.Parse(v.Value<string>());
|
||||
if (blob["derivationStrategies"] is JObject derivations)
|
||||
{
|
||||
foreach (var prop in derivations.Properties().ToList())
|
||||
{
|
||||
// We should only change data for onchain
|
||||
if (prop.Name.Contains('_', StringComparison.OrdinalIgnoreCase))
|
||||
continue;
|
||||
if (prop.Value is JValue
|
||||
{
|
||||
Type: JTokenType.String,
|
||||
Value: String { Length: > 0 } val
|
||||
})
|
||||
{
|
||||
if (val[0] == '{')
|
||||
derivations[prop.Name] = JObject.Parse(val);
|
||||
else
|
||||
{
|
||||
if (val.Contains('-', StringComparison.OrdinalIgnoreCase))
|
||||
derivations[prop.Name] = new JObject() { ["accountDerivation"] = val };
|
||||
else
|
||||
derivations[prop.Name] = null;
|
||||
}
|
||||
}
|
||||
if (prop.Value is JObject derivation)
|
||||
{
|
||||
derivations[prop.Name] = derivation["accountDerivation"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (blob["derivationStrategies"] is null && blob["derivationStrategy"] is not null)
|
||||
{
|
||||
// If it's NBX derivation strategy, keep it. Else just give up, it might be Electrum format and we shouldn't support
|
||||
// that anymore in the backend for long...
|
||||
if (blob["derivationStrategy"]?.Value<string>().Contains('-', StringComparison.OrdinalIgnoreCase) is true)
|
||||
blob.Move(["derivationStrategy"], ["derivationStrategies", "BTC"]);
|
||||
else
|
||||
{
|
||||
blob.Remove("derivationStrategy");
|
||||
blob.Add("derivationStrategies", new JObject() { ["BTC"] = null });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (blob["type"]?.Value<string>() is "Standard")
|
||||
blob.Remove("type");
|
||||
foreach (var prop in new string[] { "extendedNotifications", "lazyPaymentMethods", "lazyPaymentMethods", "redirectAutomatically" })
|
||||
{
|
||||
if (blob[prop]?.Value<bool>() is false)
|
||||
blob.Remove(prop);
|
||||
}
|
||||
|
||||
blob.ConvertNumberToString("price");
|
||||
Currency = blob["currency"].Value<string>();
|
||||
var isTopup = blob["type"]?.Value<string>() is "TopUp";
|
||||
var amount = decimal.Parse(blob["price"].Value<string>(), CultureInfo.InvariantCulture);
|
||||
Amount = isTopup && amount == 0 ? null : decimal.Parse(blob["price"].Value<string>(), CultureInfo.InvariantCulture);
|
||||
CustomerEmail = null;
|
||||
foreach (var prop in superflousProperties)
|
||||
blob.Property(prop)?.Remove();
|
||||
if (blob["speedPolicy"] is JValue { Type: JTokenType.Integer, Value: 0 or 0L })
|
||||
blob.Remove("speedPolicy");
|
||||
blob.TryAdd("internalTags", new JArray());
|
||||
blob.TryAdd("receiptOptions", new JObject());
|
||||
|
||||
foreach (var prop in ((JObject)blob["cryptoData"]).Properties())
|
||||
{
|
||||
if (prop.Name.EndsWith("_LightningLike", StringComparison.OrdinalIgnoreCase) ||
|
||||
prop.Name.EndsWith("_LNURLPAY", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (prop.Value["paymentMethod"]?["PaymentHash"] is JObject)
|
||||
prop.Value["paymentMethod"]["PaymentHash"] = JValue.CreateNull();
|
||||
if (prop.Value["paymentMethod"]?["Preimage"] is JObject)
|
||||
prop.Value["paymentMethod"]["Preimage"] = JValue.CreateNull();
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var prop in ((JObject)blob["cryptoData"]).Properties())
|
||||
{
|
||||
var crypto = prop.Name.Split(['_', '-']).First();
|
||||
if (blob.Move(["cryptoData", prop.Name, "rate"], ["rates", crypto]) is not null)
|
||||
((JObject)blob["rates"]).ConvertNumberToString(crypto);
|
||||
}
|
||||
blob.Move(["cryptoData"], ["prompts"]);
|
||||
var prompts = ((JObject)blob["prompts"]);
|
||||
foreach (var prop in prompts.Properties().ToList())
|
||||
{
|
||||
((JObject)blob["prompts"]).RenameProperty(prop.Name, MigrationExtensions.MigratePaymentMethodId(prop.Name));
|
||||
}
|
||||
blob["derivationStrategies"] = blob["derivationStrategies"] ?? new JObject();
|
||||
foreach (var prop in ((JObject)blob["derivationStrategies"]).Properties().ToList())
|
||||
{
|
||||
((JObject)blob["derivationStrategies"]).RenameProperty(prop.Name, MigrationExtensions.MigratePaymentMethodId(prop.Name));
|
||||
}
|
||||
|
||||
foreach (var prop in prompts.Properties())
|
||||
{
|
||||
var prompt = prop.Value as JObject;
|
||||
if (prompt is null)
|
||||
continue;
|
||||
prompt["currency"] = prop.Name.Split('-').First();
|
||||
prompt.RemoveIfNull("depositAddress");
|
||||
prompt.RemoveIfNull("txFee");
|
||||
prompt.RemoveIfNull("feeRate");
|
||||
|
||||
prompt.RenameProperty("depositAddress", "destination");
|
||||
prompt.RenameProperty("txFee", "paymentMethodFee");
|
||||
|
||||
var divisibility = MigrationExtensions.GetDivisibility(prop.Name);
|
||||
prompt.Add("divisibility", divisibility);
|
||||
if (prompt["paymentMethodFee"] is { Type: JTokenType.Integer } paymentMethodFee)
|
||||
{
|
||||
prompt["paymentMethodFee"] = ((decimal)paymentMethodFee.Value<long>() / (decimal)Math.Pow(10, divisibility)).ToString(CultureInfo.InvariantCulture);
|
||||
prompt.RemoveIfValue<string>("paymentMethodFee", "0");
|
||||
}
|
||||
prompt.Move(["paymentMethod"], ["details"]);
|
||||
prompt.Move(["feeRate"], ["details", "recommendedFeeRate"]);
|
||||
prompt.Move(["details", "networkFeeRate"], ["details", "paymentMethodFeeRate"]);
|
||||
prompt.Move(["details", "networkFeeMode"], ["details", "feeMode"]);
|
||||
if ((prompt["details"]?["Activated"])?.Value<bool>() is bool activated)
|
||||
{
|
||||
((JObject)prompt["details"]).Remove("Activated");
|
||||
prompt["inactive"] = !activated;
|
||||
prompt.RemoveIfValue<bool>("inactive", false);
|
||||
}
|
||||
if ((prompt["details"]?["activated"])?.Value<bool>() is bool activated2)
|
||||
{
|
||||
((JObject)prompt["details"]).Remove("activated");
|
||||
prompt["inactive"] = !activated2;
|
||||
prompt.RemoveIfValue<bool>("inactive", false);
|
||||
}
|
||||
var details = prompt["details"] as JObject ?? new JObject();
|
||||
details.RemoveIfValue<bool>("payjoinEnabled", false);
|
||||
details.RemoveIfNull("feeMode");
|
||||
if (details["feeMode"] is not (null or { Type: JTokenType.Null }))
|
||||
{
|
||||
details["feeMode"] = details["feeMode"].Value<int>() switch
|
||||
{
|
||||
1 => "Always",
|
||||
2 => "Never",
|
||||
_ => null
|
||||
};
|
||||
details.RemoveIfNull("feeMode");
|
||||
}
|
||||
|
||||
details.RemoveIfNull("BOLT11");
|
||||
details.RemoveIfNull("address");
|
||||
details.RemoveIfNull("Address");
|
||||
prompt.Move(["details", "BOLT11"], ["destination"]);
|
||||
prompt.Move(["details", "address"], ["destination"]);
|
||||
prompt.Move(["details", "Address"], ["destination"]);
|
||||
prompt.RenameProperty("Address", "destination");
|
||||
prompt.RenameProperty("BOLT11", "destination");
|
||||
|
||||
details.Remove("LightningSupportedPaymentMethod");
|
||||
foreach (var o in detailsRemoveDefault)
|
||||
details.RemoveIfNull(o);
|
||||
details.RemoveIfValue<decimal>("recommendedFeeRate", 0.0m);
|
||||
details.RemoveIfValue<decimal>("paymentMethodFeeRate", 0.0m);
|
||||
if (prop.Name.EndsWith("-CHAIN"))
|
||||
blob.Move(["derivationStrategies", prop.Name], ["prompts", prop.Name, "details", "accountDerivation"]);
|
||||
|
||||
var camel = new CamelCaseNamingStrategy();
|
||||
foreach (var p in details.Properties().ToList())
|
||||
{
|
||||
var camelName = camel.GetPropertyName(p.Name, false);
|
||||
if (camelName != p.Name)
|
||||
details.RenameProperty(p.Name, camelName);
|
||||
}
|
||||
}
|
||||
|
||||
if (blob["defaultPaymentMethod"] is not (null or { Type : JTokenType.Null }))
|
||||
blob["defaultPaymentMethod"] = MigrationExtensions.MigratePaymentMethodId(blob["defaultPaymentMethod"].Value<string>());
|
||||
blob.Remove("derivationStrategies");
|
||||
Status = Status switch
|
||||
{
|
||||
"new" => "New",
|
||||
"paid" => "Processing",
|
||||
"complete" or "confirmed" => "Settled",
|
||||
"expired" => "Expired",
|
||||
null or "invalid" => "Invalid",
|
||||
_ => throw new NotSupportedException($"Unknown Status for invoice ({Status})")
|
||||
};
|
||||
ExceptionStatus = ExceptionStatus switch
|
||||
{
|
||||
"marked" => "Marked",
|
||||
"paidLate" => "PaidLate",
|
||||
"paidPartial" => "PaidPartial",
|
||||
"paidOver" => "PaidOver",
|
||||
null or "" => "",
|
||||
_ => throw new NotSupportedException($"Unknown ExceptionStatus for invoice ({ExceptionStatus})")
|
||||
};
|
||||
blob["version"] = 3;
|
||||
Blob2 = blob.ToString(Formatting.None);
|
||||
}
|
||||
static string[] detailsRemoveDefault =
|
||||
[
|
||||
"paymentMethodFeeRate",
|
||||
"keyPath",
|
||||
"BOLT11",
|
||||
"NodeInfo",
|
||||
"Preimage",
|
||||
"InvoiceId",
|
||||
"PaymentHash",
|
||||
"ProvidedComment",
|
||||
"GeneratedBoltAmount",
|
||||
"ConsumedLightningAddress",
|
||||
"PayRequest"
|
||||
];
|
||||
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
}
|
||||
}
|
@ -1,21 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
||||
namespace BTCPayServer.Data
|
||||
{
|
||||
public partial class InvoiceData : IHasBlobUntyped
|
||||
public class InvoiceData : IHasBlobUntyped
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Currency { get; set; }
|
||||
public decimal? Amount { get; set; }
|
||||
|
||||
public string StoreDataId { get; set; }
|
||||
public StoreData StoreData { get; set; }
|
||||
|
||||
public DateTimeOffset Created { get; set; }
|
||||
public List<PaymentData> Payments { get; set; }
|
||||
public List<InvoiceEventData> Events { get; set; }
|
||||
|
||||
[Obsolete("Use Blob2 instead")]
|
||||
public byte[] Blob { get; set; }
|
||||
@ -24,7 +25,6 @@ namespace BTCPayServer.Data
|
||||
public string OrderId { get; set; }
|
||||
public string Status { get; set; }
|
||||
public string ExceptionStatus { get; set; }
|
||||
[Obsolete("Unused")]
|
||||
public string CustomerEmail { get; set; }
|
||||
public List<AddressInvoiceData> AddressInvoices { get; set; }
|
||||
public bool Archived { get; set; }
|
||||
@ -43,12 +43,13 @@ namespace BTCPayServer.Data
|
||||
builder.Entity<InvoiceData>().HasIndex(o => o.StoreDataId);
|
||||
builder.Entity<InvoiceData>().HasIndex(o => o.OrderId);
|
||||
builder.Entity<InvoiceData>().HasIndex(o => o.Created);
|
||||
builder.Entity<InvoiceData>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
builder.Entity<InvoiceData>()
|
||||
.Property(o => o.Amount)
|
||||
.HasColumnType("NUMERIC");
|
||||
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<InvoiceData>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,10 +6,28 @@ namespace BTCPayServer.Data
|
||||
public class InvoiceEventData
|
||||
{
|
||||
public string InvoiceDataId { get; set; }
|
||||
public InvoiceData InvoiceData { get; set; }
|
||||
public string UniqueId { get; set; }
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
public string Message { get; set; }
|
||||
public EventSeverity Severity { get; set; } = EventSeverity.Info;
|
||||
|
||||
|
||||
internal static void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
builder.Entity<InvoiceEventData>()
|
||||
.HasOne(o => o.InvoiceData)
|
||||
.WithMany(i => i.Events).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<InvoiceEventData>()
|
||||
.HasKey(o => new
|
||||
{
|
||||
o.InvoiceDataId,
|
||||
#pragma warning disable CS0618
|
||||
o.UniqueId
|
||||
#pragma warning restore CS0618
|
||||
});
|
||||
}
|
||||
|
||||
public enum EventSeverity
|
||||
{
|
||||
Info,
|
||||
|
@ -27,9 +27,12 @@ public class LightningAddressData : IHasBlob<LightningAddressDataBlob>
|
||||
.IsRequired()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<LightningAddressData>().HasKey(o => o.Username);
|
||||
builder.Entity<LightningAddressData>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<LightningAddressData>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,151 +0,0 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO.Compression;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace BTCPayServer.Data
|
||||
{
|
||||
public static class MigrationExtensions
|
||||
{
|
||||
public static JProperty? Move(this JObject blob, string[] pathFrom, string[] pathTo)
|
||||
{
|
||||
var from = GetProperty(blob, pathFrom, false);
|
||||
if (from is null)
|
||||
return null;
|
||||
var to = GetProperty(blob, pathTo, true);
|
||||
to!.Value = from.Value;
|
||||
from.Remove();
|
||||
return to;
|
||||
}
|
||||
|
||||
public static void RenameProperty(this JObject o, string oldName, string newName)
|
||||
{
|
||||
var p = o.Property(oldName);
|
||||
if (p is null)
|
||||
return;
|
||||
RenameProperty(ref p, newName);
|
||||
}
|
||||
public static void RenameProperty(ref JProperty ls, string newName)
|
||||
{
|
||||
if (ls.Name != newName)
|
||||
{
|
||||
var parent = ls.Parent;
|
||||
ls.Remove();
|
||||
ls = new JProperty(newName, ls.Value);
|
||||
parent!.Add(ls);
|
||||
}
|
||||
}
|
||||
|
||||
public static JProperty? GetProperty(this JObject blob, string[] pathFrom, bool createIfNotExists)
|
||||
{
|
||||
var current = blob;
|
||||
for (int i = 0; i < pathFrom.Length - 1; i++)
|
||||
{
|
||||
if (current.TryGetValue(pathFrom[i], out var value) && value is JObject jObject)
|
||||
{
|
||||
current = jObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!createIfNotExists)
|
||||
return null;
|
||||
JProperty? prop = null;
|
||||
for (int ii = i; ii < pathFrom.Length; ii++)
|
||||
{
|
||||
var newProp = new JProperty(pathFrom[ii], new JObject());
|
||||
if (prop is null)
|
||||
current.Add(newProp);
|
||||
else
|
||||
prop.Value = new JObject(newProp);
|
||||
prop = newProp;
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
var result = current.Property(pathFrom[pathFrom.Length - 1]);
|
||||
if (result is null && createIfNotExists)
|
||||
{
|
||||
result = new JProperty(pathFrom[pathFrom.Length - 1], null as object);
|
||||
current.Add(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public static CamelCaseNamingStrategy Camel = new CamelCaseNamingStrategy();
|
||||
public static void RemoveIfNull(this JObject blob, string propName)
|
||||
{
|
||||
if (blob.Property(propName)?.Value.Type is JTokenType.Null)
|
||||
blob.Remove(propName);
|
||||
}
|
||||
public static void RemoveIfValue<T>(this JObject conf, string propName, T v)
|
||||
{
|
||||
var p = conf.Property(propName);
|
||||
if (p is null)
|
||||
return;
|
||||
if (p.Value is JValue { Type: JTokenType.Null })
|
||||
{
|
||||
if (EqualityComparer<T>.Default.Equals(default, v))
|
||||
p.Remove();
|
||||
}
|
||||
else if (p.Value is JValue jv)
|
||||
{
|
||||
if (EqualityComparer<T>.Default.Equals(jv.Value<T>(), v))
|
||||
{
|
||||
p.Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ConvertNumberToString(this JObject o, string prop)
|
||||
{
|
||||
if (o[prop]?.Type is JTokenType.Float)
|
||||
o[prop] = o[prop]!.Value<decimal>().ToString(CultureInfo.InvariantCulture);
|
||||
if (o[prop]?.Type is JTokenType.Integer)
|
||||
o[prop] = o[prop]!.Value<long>().ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
public static string Unzip(byte[] bytes)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream(bytes);
|
||||
using GZipStream gzip = new GZipStream(ms, CompressionMode.Decompress);
|
||||
StreamReader reader = new StreamReader(gzip, Encoding.UTF8);
|
||||
var unzipped = reader.ReadToEnd();
|
||||
return unzipped;
|
||||
}
|
||||
|
||||
public static int GetDivisibility(string paymentMethodId)
|
||||
{
|
||||
var splitted = paymentMethodId.Split('-');
|
||||
return (CryptoCode: splitted[0], Type: splitted[1]) switch
|
||||
{
|
||||
{ Type: "LN" } or { Type: "LNURL" } => 11,
|
||||
{ Type: "CHAIN", CryptoCode: var code } when code == "XMR" => 12,
|
||||
{ Type: "CHAIN" } => 8,
|
||||
_ => 8
|
||||
};
|
||||
}
|
||||
|
||||
public static string MigratePaymentMethodId(string paymentMethodId)
|
||||
{
|
||||
var splitted = paymentMethodId.Split(new[] { '_', '-' });
|
||||
if (splitted is [var cryptoCode, var paymentType])
|
||||
{
|
||||
return paymentType switch
|
||||
{
|
||||
"BTCLike" => $"{cryptoCode}-CHAIN",
|
||||
"LightningLike" or "LightningNetwork" => $"{cryptoCode}-LN",
|
||||
"LNURLPAY" => $"{cryptoCode}-LNURL",
|
||||
_ => throw new NotSupportedException("Unknown payment type " + paymentType)
|
||||
};
|
||||
}
|
||||
if (splitted.Length == 1)
|
||||
return $"{splitted[0]}-CHAIN";
|
||||
throw new NotSupportedException("Unknown payment id " + paymentMethodId);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
|
||||
namespace BTCPayServer.Data
|
||||
{
|
||||
@ -22,15 +23,19 @@ namespace BTCPayServer.Data
|
||||
public byte[] Blob { get; set; }
|
||||
public string Blob2 { get; set; }
|
||||
|
||||
|
||||
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||
{
|
||||
builder.Entity<NotificationData>()
|
||||
.HasOne(o => o.ApplicationUser)
|
||||
.WithMany(n => n.Notifications)
|
||||
.HasForeignKey(k => k.ApplicationUserId).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<NotificationData>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<NotificationData>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,179 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Migrations;
|
||||
using NBitcoin;
|
||||
using NBitcoin.Altcoins;
|
||||
using NBitcoin.DataEncoders;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Data
|
||||
{
|
||||
public partial class PaymentData
|
||||
{
|
||||
public void Migrate()
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
if (Currency is not null)
|
||||
return;
|
||||
if (Blob is not (null or { Length: 0 }))
|
||||
{
|
||||
Blob2 = MigrationExtensions.Unzip(Blob);
|
||||
Blob = null;
|
||||
}
|
||||
var blob = JObject.Parse(Blob2);
|
||||
if (blob["cryptoPaymentDataType"] is null)
|
||||
blob["cryptoPaymentDataType"] = "BTCLike";
|
||||
if (blob["cryptoCode"] is null)
|
||||
blob["cryptoCode"] = "BTC";
|
||||
|
||||
if (blob["receivedTime"] is null)
|
||||
blob.Move(["receivedTimeMs"], ["receivedTime"]);
|
||||
else
|
||||
{
|
||||
// Convert number of seconds to number of milliseconds
|
||||
var timeSeconds = (ulong)(long)blob["receivedTime"].Value<long>();
|
||||
var date = NBitcoin.Utils.UnixTimeToDateTime(timeSeconds);
|
||||
blob["receivedTime"] = DateTimeToMilliUnixTime(date.UtcDateTime);
|
||||
}
|
||||
|
||||
var cryptoCode = blob["cryptoCode"].Value<string>();
|
||||
Type = cryptoCode + "_" + blob["cryptoPaymentDataType"].Value<string>();
|
||||
Type = MigrationExtensions.MigratePaymentMethodId(Type);
|
||||
var divisibility = MigrationExtensions.GetDivisibility(Type);
|
||||
Currency = blob["cryptoCode"].Value<string>();
|
||||
blob.Remove("cryptoCode");
|
||||
blob.Remove("cryptoPaymentDataType");
|
||||
|
||||
JObject cryptoData;
|
||||
if (blob["cryptoPaymentData"] is null)
|
||||
{
|
||||
cryptoData = new JObject();
|
||||
blob["cryptoPaymentData"] = cryptoData;
|
||||
cryptoData["RBF"] = true;
|
||||
cryptoData["confirmationCount"] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cryptoData = JObject.Parse(blob["cryptoPaymentData"].Value<string>());
|
||||
foreach (var prop in cryptoData.Properties().ToList())
|
||||
{
|
||||
if (prop.Name is "rbf")
|
||||
cryptoData.RenameProperty("rbf", "RBF");
|
||||
else if (prop.Name is "bolT11")
|
||||
cryptoData.RenameProperty("bolT11", "BOLT11");
|
||||
else
|
||||
cryptoData.RenameProperty(prop.Name, MigrationExtensions.Camel.GetPropertyName(prop.Name, false));
|
||||
}
|
||||
}
|
||||
blob.Remove("cryptoPaymentData");
|
||||
cryptoData["outpoint"] = blob["outpoint"];
|
||||
if (blob["output"] is not (null or { Type: JTokenType.Null }))
|
||||
{
|
||||
// Old versions didn't track addresses, so we take it from output.
|
||||
// We don't know the network for sure but better having something than nothing in destination.
|
||||
// If signet/testnet crash we don't really care anyway.
|
||||
// Also, only LTC was supported at this time.
|
||||
Network network = (cryptoCode switch { "LTC" => (INetworkSet)Litecoin.Instance, _ => Bitcoin.Instance }).Mainnet;
|
||||
var txout = network.Consensus.ConsensusFactory.CreateTxOut();
|
||||
txout.ReadWrite(Encoders.Hex.DecodeData(blob["output"].Value<string>()), network);
|
||||
cryptoData["value"] = txout.Value.Satoshi;
|
||||
blob["destination"] = txout.ScriptPubKey.GetDestinationAddress(network)?.ToString();
|
||||
}
|
||||
blob.Remove("output");
|
||||
blob.Remove("outpoint");
|
||||
// Convert from sats to btc
|
||||
if (cryptoData["value"] is not (null or { Type: JTokenType.Null }))
|
||||
{
|
||||
var v = cryptoData["value"].Value<long>();
|
||||
Amount = (decimal)v / (decimal)Money.COIN;
|
||||
cryptoData.Remove("value");
|
||||
|
||||
blob["paymentMethodFee"] = blob["networkFee"];
|
||||
blob.RemoveIfValue<decimal>("paymentMethodFee", 0.0m);
|
||||
blob.ConvertNumberToString("paymentMethodFee");
|
||||
blob.Remove("networkFee");
|
||||
blob.RemoveIfNull("paymentMethodFee");
|
||||
}
|
||||
// Convert from millisats to btc
|
||||
else if (cryptoData["amount"] is not (null or { Type: JTokenType.Null }))
|
||||
{
|
||||
var v = cryptoData["amount"].Value<long>();
|
||||
Amount = (decimal)v / (decimal)Math.Pow(10.0, divisibility);
|
||||
cryptoData.Remove("amount");
|
||||
}
|
||||
if (cryptoData["address"] is not (null or { Type: JTokenType.Null }))
|
||||
{
|
||||
blob["destination"] = cryptoData["address"];
|
||||
cryptoData.Remove("address");
|
||||
}
|
||||
if (cryptoData["BOLT11"] is not (null or { Type: JTokenType.Null }))
|
||||
{
|
||||
blob["destination"] = cryptoData["BOLT11"];
|
||||
cryptoData.Remove("BOLT11");
|
||||
}
|
||||
if (cryptoData["outpoint"] is not (null or { Type: JTokenType.Null }))
|
||||
{
|
||||
// Convert to format txid-n
|
||||
cryptoData["outpoint"] = OutPoint.Parse(cryptoData["outpoint"].Value<string>()).ToString();
|
||||
}
|
||||
if (Accounted is false)
|
||||
Status = PaymentStatus.Unaccounted;
|
||||
else if (cryptoData["confirmationCount"] is { Type: JTokenType.Integer })
|
||||
{
|
||||
var confirmationCount = cryptoData["confirmationCount"].Value<int>();
|
||||
// Technically, we should use the invoice's speed policy, however it's not on our
|
||||
// scope and is good enough for majority of cases.
|
||||
Status = confirmationCount > 0 ? PaymentStatus.Settled : PaymentStatus.Processing;
|
||||
if (cryptoData["LockTime"] is { Type: JTokenType.Integer })
|
||||
{
|
||||
var lockTime = cryptoData["LockTime"].Value<int>();
|
||||
if (confirmationCount < lockTime)
|
||||
Status = PaymentStatus.Processing;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = PaymentStatus.Settled;
|
||||
}
|
||||
Created = MilliUnixTimeToDateTime(blob["receivedTime"].Value<long>());
|
||||
cryptoData.RemoveIfValue<bool>("rbf", false);
|
||||
cryptoData.Remove("legacy");
|
||||
cryptoData.Remove("networkFee");
|
||||
cryptoData.Remove("paymentType");
|
||||
cryptoData.RemoveIfNull("outpoint");
|
||||
cryptoData.RemoveIfValue<bool>("RBF", false);
|
||||
|
||||
blob.Remove("receivedTime");
|
||||
blob.Remove("accounted");
|
||||
blob.Remove("networkFee");
|
||||
blob["details"] = cryptoData;
|
||||
blob["divisibility"] = divisibility;
|
||||
blob["version"] = 2;
|
||||
Blob2 = blob.ToString(Formatting.None);
|
||||
Accounted = null;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
}
|
||||
|
||||
static readonly DateTimeOffset unixRef = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
|
||||
public static long DateTimeToMilliUnixTime(in DateTime time)
|
||||
{
|
||||
var date = ((DateTimeOffset)time).ToUniversalTime();
|
||||
long v = (long)(date - unixRef).TotalMilliseconds;
|
||||
if (v < 0)
|
||||
throw new FormatException("Invalid datetime (less than 1/1/1970)");
|
||||
return v;
|
||||
}
|
||||
public static DateTimeOffset MilliUnixTimeToDateTime(long value)
|
||||
{
|
||||
var v = value;
|
||||
if (v < 0)
|
||||
throw new FormatException("Invalid datetime (less than 1/1/1970)");
|
||||
return unixRef + TimeSpan.FromMilliseconds(v);
|
||||
}
|
||||
}
|
||||
}
|
@ -4,32 +4,17 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
||||
namespace BTCPayServer.Data
|
||||
{
|
||||
public enum PaymentStatus
|
||||
public class PaymentData : IHasBlobUntyped
|
||||
{
|
||||
Processing,
|
||||
Settled,
|
||||
Unaccounted
|
||||
}
|
||||
public partial class PaymentData : IHasBlobUntyped
|
||||
{
|
||||
/// <summary>
|
||||
/// The date of creation of the payment
|
||||
/// Note that while it is a nullable field, our migration
|
||||
/// process ensure it is populated.
|
||||
/// </summary>
|
||||
public DateTimeOffset? Created { get; set; }
|
||||
public string Id { get; set; }
|
||||
public string InvoiceDataId { get; set; }
|
||||
public string Currency { get; set; }
|
||||
public decimal? Amount { get; set; }
|
||||
public InvoiceData InvoiceData { get; set; }
|
||||
[Obsolete("Use Blob2 instead")]
|
||||
public byte[] Blob { get; set; }
|
||||
public string Blob2 { get; set; }
|
||||
public string Type { get; set; }
|
||||
[Obsolete("Use Status instead")]
|
||||
public bool? Accounted { get; set; }
|
||||
public PaymentStatus? Status { get; set; }
|
||||
public bool Accounted { get; set; }
|
||||
|
||||
|
||||
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||
{
|
||||
@ -38,15 +23,12 @@ namespace BTCPayServer.Data
|
||||
.WithMany(i => i.Payments).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<PaymentData>()
|
||||
.HasIndex(o => o.InvoiceDataId);
|
||||
builder.Entity<PaymentData>()
|
||||
.Property(o => o.Status)
|
||||
.HasConversion<string>();
|
||||
builder.Entity<PaymentData>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
builder.Entity<PaymentData>()
|
||||
.Property(o => o.Amount)
|
||||
.HasColumnType("NUMERIC");
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<PaymentData>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,9 +32,12 @@ namespace BTCPayServer.Data
|
||||
builder.Entity<PaymentRequestData>()
|
||||
.HasIndex(o => o.Status);
|
||||
|
||||
builder.Entity<PaymentRequestData>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<PaymentRequestData>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BTCPayServer.Data
|
||||
{
|
||||
public partial class PayoutData
|
||||
{
|
||||
public void Migrate()
|
||||
{
|
||||
PayoutMethodId = MigrationExtensions.MigratePaymentMethodId(PayoutMethodId);
|
||||
// Could only be BTC-LN or BTC-CHAIN, so we extract the crypto currency
|
||||
Currency = PayoutMethodId.Split('-')[0];
|
||||
}
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Data
|
||||
{
|
||||
public partial class PayoutData
|
||||
public class PayoutData
|
||||
{
|
||||
[Key]
|
||||
[MaxLength(30)]
|
||||
@ -18,13 +18,12 @@ namespace BTCPayServer.Data
|
||||
public DateTimeOffset Date { get; set; }
|
||||
public string PullPaymentDataId { get; set; }
|
||||
public string StoreDataId { get; set; }
|
||||
public string Currency { get; set; }
|
||||
public PullPaymentData PullPaymentData { get; set; }
|
||||
[MaxLength(20)]
|
||||
public PayoutState State { get; set; }
|
||||
[MaxLength(20)]
|
||||
[Required]
|
||||
public string PayoutMethodId { get; set; }
|
||||
public string PaymentMethodId { get; set; }
|
||||
public string Blob { get; set; }
|
||||
public string Proof { get; set; }
|
||||
#nullable enable
|
||||
@ -48,12 +47,44 @@ namespace BTCPayServer.Data
|
||||
builder.Entity<PayoutData>()
|
||||
.HasIndex(x => new { DestinationId = x.Destination, x.State });
|
||||
|
||||
builder.Entity<PayoutData>()
|
||||
.Property(o => o.Blob)
|
||||
.HasColumnType("JSONB");
|
||||
builder.Entity<PayoutData>()
|
||||
.Property(o => o.Proof)
|
||||
.HasColumnType("JSONB");
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<PayoutData>()
|
||||
.Property(o => o.Blob)
|
||||
.HasColumnType("JSONB");
|
||||
builder.Entity<PayoutData>()
|
||||
.Property(o => o.Proof)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
else if (databaseFacade.IsMySql())
|
||||
{
|
||||
builder.Entity<PayoutData>()
|
||||
.Property(o => o.Blob)
|
||||
.HasConversion(new ValueConverter<string, byte[]>
|
||||
(
|
||||
convertToProviderExpression: (str) => Encoding.UTF8.GetBytes(str),
|
||||
convertFromProviderExpression: (bytes) => Encoding.UTF8.GetString(bytes)
|
||||
));
|
||||
builder.Entity<PayoutData>()
|
||||
.Property(o => o.Proof)
|
||||
.HasConversion(new ValueConverter<string, byte[]>
|
||||
(
|
||||
convertToProviderExpression: (str) => Encoding.UTF8.GetBytes(str),
|
||||
convertFromProviderExpression: (bytes) => Encoding.UTF8.GetString(bytes)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// utility methods
|
||||
public bool IsInPeriod(PullPaymentData pp, DateTimeOffset now)
|
||||
{
|
||||
var period = pp.GetPeriod(now);
|
||||
if (period is { } p)
|
||||
{
|
||||
return p.Start <= Date && (p.End is not { } end || Date < end);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,9 +29,12 @@ public class PayoutProcessorData : IHasBlobUntyped
|
||||
.HasOne(o => o.Store)
|
||||
.WithMany(data => data.PayoutProcessors).OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.Entity<PayoutProcessorData>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<PayoutProcessorData>()
|
||||
.Property(o => o.Blob2)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
|
@ -4,13 +4,11 @@ using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BTCPayServer.Abstractions.Extensions;
|
||||
using BTCPayServer.Client.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using NBitcoin;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace BTCPayServer.Data
|
||||
{
|
||||
@ -24,6 +22,7 @@ namespace BTCPayServer.Data
|
||||
public StoreData StoreData { get; set; }
|
||||
[MaxLength(50)]
|
||||
public string StoreId { get; set; }
|
||||
public long? Period { get; set; }
|
||||
public DateTimeOffset StartDate { get; set; }
|
||||
public DateTimeOffset? EndDate { get; set; }
|
||||
public bool Archived { get; set; }
|
||||
@ -39,9 +38,22 @@ namespace BTCPayServer.Data
|
||||
.HasOne(o => o.StoreData)
|
||||
.WithMany(o => o.PullPayments).OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.Entity<PullPaymentData>()
|
||||
.Property(o => o.Blob)
|
||||
.HasColumnType("JSONB");
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<PullPaymentData>()
|
||||
.Property(o => o.Blob)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
else if (databaseFacade.IsMySql())
|
||||
{
|
||||
builder.Entity<PullPaymentData>()
|
||||
.Property(o => o.Blob)
|
||||
.HasConversion(new ValueConverter<string, byte[]>
|
||||
(
|
||||
convertToProviderExpression: (str) => Encoding.UTF8.GetBytes(str),
|
||||
convertFromProviderExpression: (bytes) => Encoding.UTF8.GetString(bytes)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public (DateTimeOffset Start, DateTimeOffset? End)? GetPeriod(DateTimeOffset now)
|
||||
@ -50,25 +62,27 @@ namespace BTCPayServer.Data
|
||||
return null;
|
||||
if (EndDate is DateTimeOffset end && now >= end)
|
||||
return null;
|
||||
return (StartDate, EndDate);
|
||||
DateTimeOffset startPeriod = StartDate;
|
||||
DateTimeOffset? endPeriod = null;
|
||||
if (Period is long periodSeconds)
|
||||
{
|
||||
var period = TimeSpan.FromSeconds(periodSeconds);
|
||||
var timeToNow = now - StartDate;
|
||||
var periodCount = (long)timeToNow.TotalSeconds / (long)period.TotalSeconds;
|
||||
startPeriod = StartDate + (period * periodCount);
|
||||
endPeriod = startPeriod + period;
|
||||
}
|
||||
if (EndDate is DateTimeOffset end2 &&
|
||||
((endPeriod is null) ||
|
||||
(endPeriod is DateTimeOffset endP && endP > end2)))
|
||||
endPeriod = end2;
|
||||
return (startPeriod, endPeriod);
|
||||
}
|
||||
|
||||
public bool HasStarted()
|
||||
{
|
||||
return HasStarted(DateTimeOffset.UtcNow);
|
||||
}
|
||||
public TimeSpan? EndsIn() => EndsIn(DateTimeOffset.UtcNow);
|
||||
public TimeSpan? EndsIn(DateTimeOffset now)
|
||||
{
|
||||
if (EndDate is DateTimeOffset e)
|
||||
{
|
||||
var resetIn = (e - now);
|
||||
if (resetIn < TimeSpan.Zero)
|
||||
resetIn = TimeSpan.Zero;
|
||||
return resetIn;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public bool HasStarted(DateTimeOffset now)
|
||||
{
|
||||
return StartDate <= now;
|
||||
@ -96,6 +110,32 @@ namespace BTCPayServer.Data
|
||||
|
||||
public static class PayoutExtensions
|
||||
{
|
||||
public static IQueryable<PayoutData> GetPayoutInPeriod(this IQueryable<PayoutData> payouts, PullPaymentData pp)
|
||||
{
|
||||
return GetPayoutInPeriod(payouts, pp, DateTimeOffset.UtcNow);
|
||||
}
|
||||
public static IQueryable<PayoutData> GetPayoutInPeriod(this IQueryable<PayoutData> payouts, PullPaymentData pp, DateTimeOffset now)
|
||||
{
|
||||
var request = payouts.Where(p => p.PullPaymentDataId == pp.Id);
|
||||
var period = pp.GetPeriod(now);
|
||||
if (period is { } p)
|
||||
{
|
||||
var start = p.Start;
|
||||
if (p.End is DateTimeOffset end)
|
||||
{
|
||||
return request.Where(p => p.Date >= start && p.Date < end);
|
||||
}
|
||||
else
|
||||
{
|
||||
return request.Where(p => p.Date >= start);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return request.Where(p => false);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetStateString(this PayoutState state)
|
||||
{
|
||||
switch (state)
|
||||
|
@ -11,9 +11,12 @@ namespace BTCPayServer.Data
|
||||
|
||||
public static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||
{
|
||||
builder.Entity<SettingData>()
|
||||
.Property(o => o.Value)
|
||||
.HasColumnType("JSONB");
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<SettingData>()
|
||||
.Property(o => o.Value)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user