mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-18 22:44:29 +01:00
GreenField: Add FeeRate To Wallets API (#2375)
* GreenField: Add FeeRate To Wallets API closes #1846 * make dedicated endpoint for fee rate * remove unused call
This commit is contained in:
@@ -19,6 +19,19 @@ namespace BTCPayServer.Client
|
|||||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/Onchain/{cryptoCode}/wallet"), token);
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/Onchain/{cryptoCode}/wallet"), token);
|
||||||
return await HandleResponse<OnChainWalletOverviewData>(response);
|
return await HandleResponse<OnChainWalletOverviewData>(response);
|
||||||
}
|
}
|
||||||
|
public virtual async Task<OnChainWalletFeeRateData> GetOnChainFeeRate(string storeId, string cryptoCode, int? blockTarget = null,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task<OnChainWalletAddressData> GetOnChainWalletReceiveAddress(string storeId, string cryptoCode, bool forceGenerate = false,
|
public virtual async Task<OnChainWalletAddressData> GetOnChainWalletReceiveAddress(string storeId, string cryptoCode, bool forceGenerate = false,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
|
|||||||
12
BTCPayServer.Client/Models/OnChainWalletFeeRateData.cs
Normal file
12
BTCPayServer.Client/Models/OnChainWalletFeeRateData.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using NBitcoin;
|
||||||
|
using NBitcoin.JsonConverters;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Client.Models
|
||||||
|
{
|
||||||
|
public class OnChainWalletFeeRateData
|
||||||
|
{
|
||||||
|
[JsonConverter(typeof(FeeRateJsonConverter))]
|
||||||
|
public FeeRate FeeRate { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,6 @@ namespace BTCPayServer.Client.Models
|
|||||||
{
|
{
|
||||||
public class OnChainWalletOverviewData
|
public class OnChainWalletOverviewData
|
||||||
{
|
{
|
||||||
|
|
||||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||||
public decimal Balance { get; set; }
|
public decimal Balance { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1435,6 +1435,10 @@ namespace BTCPayServer.Tests
|
|||||||
var overview = await client.ShowOnChainWalletOverview(walletId.StoreId, walletId.CryptoCode );
|
var overview = await client.ShowOnChainWalletOverview(walletId.StoreId, walletId.CryptoCode );
|
||||||
Assert.Equal(0m, overview.Balance);
|
Assert.Equal(0m, overview.Balance);
|
||||||
|
|
||||||
|
|
||||||
|
var fee = await client.GetOnChainFeeRate(walletId.StoreId, walletId.CryptoCode );
|
||||||
|
Assert.NotNull( fee.FeeRate);
|
||||||
|
|
||||||
await AssertHttpError(403, async () =>
|
await AssertHttpError(403, async () =>
|
||||||
{
|
{
|
||||||
await viewOnlyClient.GetOnChainWalletReceiveAddress(walletId.StoreId, walletId.CryptoCode );
|
await viewOnlyClient.GetOnChainWalletReceiveAddress(walletId.StoreId, walletId.CryptoCode );
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ namespace BTCPayServer.Controllers.GreenField
|
|||||||
private readonly DelayedTransactionBroadcaster _delayedTransactionBroadcaster;
|
private readonly DelayedTransactionBroadcaster _delayedTransactionBroadcaster;
|
||||||
private readonly EventAggregator _eventAggregator;
|
private readonly EventAggregator _eventAggregator;
|
||||||
private readonly WalletReceiveService _walletReceiveService;
|
private readonly WalletReceiveService _walletReceiveService;
|
||||||
|
private readonly IFeeProviderFactory _feeProviderFactory;
|
||||||
|
|
||||||
public StoreOnChainWalletsController(
|
public StoreOnChainWalletsController(
|
||||||
IAuthorizationService authorizationService,
|
IAuthorizationService authorizationService,
|
||||||
@@ -57,7 +58,8 @@ namespace BTCPayServer.Controllers.GreenField
|
|||||||
PayjoinClient payjoinClient,
|
PayjoinClient payjoinClient,
|
||||||
DelayedTransactionBroadcaster delayedTransactionBroadcaster,
|
DelayedTransactionBroadcaster delayedTransactionBroadcaster,
|
||||||
EventAggregator eventAggregator,
|
EventAggregator eventAggregator,
|
||||||
WalletReceiveService walletReceiveService)
|
WalletReceiveService walletReceiveService,
|
||||||
|
IFeeProviderFactory feeProviderFactory)
|
||||||
{
|
{
|
||||||
_authorizationService = authorizationService;
|
_authorizationService = authorizationService;
|
||||||
_btcPayWalletProvider = btcPayWalletProvider;
|
_btcPayWalletProvider = btcPayWalletProvider;
|
||||||
@@ -71,6 +73,7 @@ namespace BTCPayServer.Controllers.GreenField
|
|||||||
_delayedTransactionBroadcaster = delayedTransactionBroadcaster;
|
_delayedTransactionBroadcaster = delayedTransactionBroadcaster;
|
||||||
_eventAggregator = eventAggregator;
|
_eventAggregator = eventAggregator;
|
||||||
_walletReceiveService = walletReceiveService;
|
_walletReceiveService = walletReceiveService;
|
||||||
|
_feeProviderFactory = feeProviderFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||||
@@ -87,6 +90,21 @@ namespace BTCPayServer.Controllers.GreenField
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||||
|
[HttpGet("~/api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/feerate")]
|
||||||
|
public async Task<IActionResult> GetOnChainFeeRate(string storeId, string cryptoCode, int? blockTarget = null)
|
||||||
|
{
|
||||||
|
if (IsInvalidWalletRequest(cryptoCode, out BTCPayNetwork network,
|
||||||
|
out DerivationSchemeSettings derivationScheme, out IActionResult actionResult)) return actionResult;
|
||||||
|
|
||||||
|
var feeRateTarget = blockTarget?? Store.GetStoreBlob().RecommendedFeeBlockTarget;
|
||||||
|
return Ok(new OnChainWalletFeeRateData()
|
||||||
|
{
|
||||||
|
FeeRate = await _feeProviderFactory.CreateFeeProvider(network)
|
||||||
|
.GetFeeRateAsync(feeRateTarget),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||||
[HttpGet("~/api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/address")]
|
[HttpGet("~/api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/address")]
|
||||||
public async Task<IActionResult> GetOnChainWalletReceiveAddress(string storeId, string cryptoCode, bool forceGenerate = false)
|
public async Task<IActionResult> GetOnChainWalletReceiveAddress(string storeId, string cryptoCode, bool forceGenerate = false)
|
||||||
@@ -332,7 +350,7 @@ namespace BTCPayServer.Controllers.GreenField
|
|||||||
"You are sending your entire balance, you should subtract the fees from a destination", this);
|
"You are sending your entire balance, you should subtract the fees from a destination", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
var minRelayFee = this._nbXplorerDashboard.Get(network.CryptoCode).Status.BitcoinStatus?.MinRelayTxFee ??
|
var minRelayFee = _nbXplorerDashboard.Get(network.CryptoCode).Status.BitcoinStatus?.MinRelayTxFee ??
|
||||||
new FeeRate(1.0m);
|
new FeeRate(1.0m);
|
||||||
if (request.FeeRate != null && request.FeeRate < minRelayFee)
|
if (request.FeeRate != null && request.FeeRate < minRelayFee)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -56,6 +56,72 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/v1/stores/{storeId}/payment-methods/OnChain/{cryptoCode}/wallet/feeRate": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Store Wallet (On Chain)"
|
||||||
|
],
|
||||||
|
"summary": "Get store on-chain wallet overview",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "storeId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"description": "The store to fetch",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cryptoCode",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"description": "The crypto code of the payment method to fetch",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "blockTarget",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"description": "The number of blocks away you are willing to target for confirmation. Defaults to the wallet's configured `RecommendedFeeBlockTarget`",
|
||||||
|
"schema": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Get wallet onchain fee rate",
|
||||||
|
"operationId": "StoreOnChainWallets_GetOnChainFeeRate",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "fee rate",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/OnChainWalletFeeRateData"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "If you are authenticated but forbidden to view the specified store"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "The key is not found for this store/wallet"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"API Key": [
|
||||||
|
"btcpay.store.canmodifystoresettings"
|
||||||
|
],
|
||||||
|
"Basic": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v1/stores/{storeId}/payment-methods/OnChain/{cryptoCode}/wallet/address": {
|
"/api/v1/stores/{storeId}/payment-methods/OnChain/{cryptoCode}/wallet/address": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@@ -449,6 +515,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"OnChainWalletFeeRateData": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"feeRate": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "decimal",
|
||||||
|
"description": "The fee rate (sats per byte) based on the wallet's configured recommended block confirmation target"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"OnChainWalletAddressData": {
|
"OnChainWalletAddressData": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
|||||||
Reference in New Issue
Block a user