From 308ed37f43b30ccee22e85596c33f66fa4520e2c Mon Sep 17 00:00:00 2001 From: Collins <46327225+CollinsMunene@users.noreply.github.com> Date: Mon, 17 Feb 2025 19:15:37 +0300 Subject: [PATCH] feat(backend): Check quote expiry in outgoing payment worker (#3141) (#3173) * feat(backend):Check quote expiry in outgoing payment worker (#3141) * feat:add test to quote expiry check * feat:run code pnpm format --- .../open_payments/payment/outgoing/errors.ts | 5 ++++- .../payment/outgoing/lifecycle.ts | 5 +++++ .../payment/outgoing/service.test.ts | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/open_payments/payment/outgoing/errors.ts b/packages/backend/src/open_payments/payment/outgoing/errors.ts index b8b6945a84..9e8d80d4e9 100644 --- a/packages/backend/src/open_payments/payment/outgoing/errors.ts +++ b/packages/backend/src/open_payments/payment/outgoing/errors.ts @@ -110,5 +110,8 @@ export enum LifecycleError { MissingBalance = 'MissingBalance', MissingQuote = 'MissingQuote', MissingExpiration = 'MissingExpiration', - Unauthorized = 'Unauthorized' + Unauthorized = 'Unauthorized', + + // To be thrown when a Quote has expired + QuoteExpired = 'QuoteExpired' } diff --git a/packages/backend/src/open_payments/payment/outgoing/lifecycle.ts b/packages/backend/src/open_payments/payment/outgoing/lifecycle.ts index 4f0034839a..4509821990 100644 --- a/packages/backend/src/open_payments/payment/outgoing/lifecycle.ts +++ b/packages/backend/src/open_payments/payment/outgoing/lifecycle.ts @@ -17,6 +17,11 @@ export async function handleSending( ): Promise { if (!payment.quote) throw LifecycleError.MissingQuote + // Check if the current time is greater than or equal to when the Quote should be expiring + if (Date.now() >= payment.quote.expiresAt.getTime()) { + throw LifecycleError.QuoteExpired + } + const receiver = await deps.receiverService.get(payment.receiver) // TODO: Query TigerBeetle transfers by code to distinguish sending debits from withdrawals diff --git a/packages/backend/src/open_payments/payment/outgoing/service.test.ts b/packages/backend/src/open_payments/payment/outgoing/service.test.ts index a87bf31c9c..647fe26425 100644 --- a/packages/backend/src/open_payments/payment/outgoing/service.test.ts +++ b/packages/backend/src/open_payments/payment/outgoing/service.test.ts @@ -1792,6 +1792,25 @@ describe('OutgoingPaymentService', (): void => { LifecycleError.DestinationAssetConflict ) }) + + test('QuoteExpired (current time is greater than the payment quote expiration time)', async (): Promise => { + const createdPayment = await setup({ + receiver, + debitAmount, + method: 'ilp' + }) + + // Test case for `expiresAt` in the past (greater than current time) + await createdPayment.quote.$query(knex).patch({ + expiresAt: new Date(Date.now() - 60 * 60 * 1000) // 1 hour ago + }) + + await processNext( + createdPayment.id, + OutgoingPaymentState.Failed, + LifecycleError.QuoteExpired + ) + }) }) describe('fund', (): void => {