diff --git a/src/Data/Repositories/WalletWithdrawalRequestRepository.cs b/src/Data/Repositories/WalletWithdrawalRequestRepository.cs index 919102be..9f2a2079 100644 --- a/src/Data/Repositories/WalletWithdrawalRequestRepository.cs +++ b/src/Data/Repositories/WalletWithdrawalRequestRepository.cs @@ -82,7 +82,16 @@ public async Task> GetByReferenceIds(List { await using var applicationDbContext = await _dbContextFactory.CreateDbContextAsync(); - return await applicationDbContext.WalletWithdrawalRequests.Where(wr => !string.IsNullOrEmpty(wr.ReferenceId) && referenceIds.Contains(wr.ReferenceId)).ToListAsync(); + // RBF replacements inherit the reference id of the request they replace, so a reference id can match a whole + // chain of requests. Only the latest one of each chain reflects the current status of the withdrawal. + var requests = await applicationDbContext.WalletWithdrawalRequests + .Where(wr => !string.IsNullOrEmpty(wr.ReferenceId) && referenceIds.Contains(wr.ReferenceId)) + .ToListAsync(); + + return requests + .GroupBy(wr => wr.ReferenceId!) + .Select(g => g.OrderByDescending(wr => wr.Id).First()) + .ToList(); } public async Task GetByTxHash(string txHash) diff --git a/src/Services/WithdrawalRequestService.cs b/src/Services/WithdrawalRequestService.cs index 498c4d5e..5491f291 100644 --- a/src/Services/WithdrawalRequestService.cs +++ b/src/Services/WithdrawalRequestService.cs @@ -244,6 +244,8 @@ private async Task CreateReplacementAsync(int originalR CustomFeeRate = newFeeRate, UserRequestorId = original.UserRequestorId, RequestMetadata = original.RequestMetadata, + // The replacement represents the same external request, so callers can keep tracking it by reference id. + ReferenceId = original.ReferenceId, BumpingWalletWithdrawalRequestId = original.Id, IsRbfCancellation = cancellation, WalletId = original.WalletId,