From 7e6a2d08e2978a462a828f6df69c0b062a1395c2 Mon Sep 17 00:00:00 2001 From: Umar Bolatov Date: Sun, 17 Apr 2022 19:20:15 -0700 Subject: [PATCH] Add label filter for onchain tx API endpoint (#3588) * Add label filter for onchain tx API endpoint close #3587 * Add Swagger docs * Add test for filtering by transaction label --- .../BTCPayServerClient.OnChainWallet.cs | 5 ++++- BTCPayServer.Tests/GreenfieldAPITests.cs | 3 +++ .../GreenfieldStoreOnChainWalletsController.cs | 18 ++++++++++++++++++ .../GreenField/LocalBTCPayServerClient.cs | 2 +- ...wagger.template.stores-wallet.on-chain.json | 10 ++++++++++ 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/BTCPayServer.Client/BTCPayServerClient.OnChainWallet.cs b/BTCPayServer.Client/BTCPayServerClient.OnChainWallet.cs index 64b7f430a..e58371464 100644 --- a/BTCPayServer.Client/BTCPayServerClient.OnChainWallet.cs +++ b/BTCPayServer.Client/BTCPayServerClient.OnChainWallet.cs @@ -55,7 +55,7 @@ namespace BTCPayServer.Client } public virtual async Task> ShowOnChainWalletTransactions( - string storeId, string cryptoCode, TransactionStatus[] statusFilter = null, + string storeId, string cryptoCode, TransactionStatus[] statusFilter = null, string labelFilter = null, CancellationToken token = default) { var query = new Dictionary(); @@ -63,6 +63,9 @@ namespace BTCPayServer.Client { query.Add(nameof(statusFilter), statusFilter); } + if (labelFilter != null) { + query.Add(nameof(labelFilter), labelFilter); + } var response = await _httpClient.SendAsync( CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions", query), token); diff --git a/BTCPayServer.Tests/GreenfieldAPITests.cs b/BTCPayServer.Tests/GreenfieldAPITests.cs index 115406319..a153cec41 100644 --- a/BTCPayServer.Tests/GreenfieldAPITests.cs +++ b/BTCPayServer.Tests/GreenfieldAPITests.cs @@ -2163,6 +2163,9 @@ namespace BTCPayServer.Tests new[] { TransactionStatus.Unconfirmed }), data => data.TransactionHash == txdata.TransactionHash); Assert.Contains( await client.ShowOnChainWalletTransactions(walletId.StoreId, walletId.CryptoCode), data => data.TransactionHash == txdata.TransactionHash); + Assert.Contains( + await client.ShowOnChainWalletTransactions(walletId.StoreId, walletId.CryptoCode, null, "test label"), data => data.TransactionHash == txdata.TransactionHash); + await tester.WaitForEvent(async () => { diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldStoreOnChainWalletsController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldStoreOnChainWalletsController.cs index 3ef3ec37f..a428976bf 100644 --- a/BTCPayServer/Controllers/GreenField/GreenfieldStoreOnChainWalletsController.cs +++ b/BTCPayServer/Controllers/GreenField/GreenfieldStoreOnChainWalletsController.cs @@ -173,6 +173,7 @@ namespace BTCPayServer.Controllers.Greenfield string storeId, string cryptoCode, [FromQuery] TransactionStatus[]? statusFilter = null, + [FromQuery] string? labelFilter = null, [FromQuery] int skip = 0, [FromQuery] int limit = int.MaxValue ) @@ -202,6 +203,23 @@ namespace BTCPayServer.Controllers.Greenfield filteredFlatList.AddRange(txs.ReplacedTransactions.Transactions); } + if (labelFilter != null) + { + filteredFlatList = filteredFlatList.Where(information => + { + walletTransactionsInfoAsync.TryGetValue(information.TransactionId.ToString(), out var transactionInfo); + + if (transactionInfo != null) + { + return transactionInfo.Labels.ContainsKey(labelFilter); + } + else + { + return false; + } + }).ToList(); + } + var result = filteredFlatList.Skip(skip).Take(limit).Select(information => { walletTransactionsInfoAsync.TryGetValue(information.TransactionId.ToString(), out var transactionInfo); diff --git a/BTCPayServer/Controllers/GreenField/LocalBTCPayServerClient.cs b/BTCPayServer/Controllers/GreenField/LocalBTCPayServerClient.cs index 129aeb0a3..57ce927d7 100644 --- a/BTCPayServer/Controllers/GreenField/LocalBTCPayServerClient.cs +++ b/BTCPayServer/Controllers/GreenField/LocalBTCPayServerClient.cs @@ -782,7 +782,7 @@ namespace BTCPayServer.Controllers.Greenfield } public override async Task> ShowOnChainWalletTransactions( - string storeId, string cryptoCode, TransactionStatus[] statusFilter = null, + string storeId, string cryptoCode, TransactionStatus[] statusFilter = null, string labelFilter = null, CancellationToken token = default) { return GetFromActionResult>( diff --git a/BTCPayServer/wwwroot/swagger/v1/swagger.template.stores-wallet.on-chain.json b/BTCPayServer/wwwroot/swagger/v1/swagger.template.stores-wallet.on-chain.json index 4ba0b02c8..16ff32124 100644 --- a/BTCPayServer/wwwroot/swagger/v1/swagger.template.stores-wallet.on-chain.json +++ b/BTCPayServer/wwwroot/swagger/v1/swagger.template.stores-wallet.on-chain.json @@ -277,6 +277,16 @@ } } }, + { + "name": "labelFilter", + "in": "query", + "required": false, + "description": "Transaction label to filter by", + "schema": { + "type": "string" + }, + "example": "invoice" + }, { "name": "skip", "in": "query",