Compare commits

...
3 Commits
9 changed files with 94 additions and 22 deletions
@@ -250,6 +250,10 @@ export class OrderService {
amountFiat: deliveryCost
});
if (!shippingInvoice) {
throw new InternalServerErrorException('Failed to issue shipping invoice');
}
await this.orderRepo.update(orderId, {
shippingInvoice: { id: shippingInvoice.id },
quotedAt
@@ -110,6 +110,6 @@ describe('deriveInvoiceState', () => {
moneroDetails: undefined,
payments: [{ amountAtomic: '1000', confirmations: 10 }]
})
).toThrow('Invoice is missing Monero required confirmations');
).toThrow('Invoice is missing xmr required confirmations');
});
});
@@ -0,0 +1,34 @@
import { PaymentMethod } from '../../modules/payment/types/PaymentMethod';
import { getConfirmationBasedInvoiceDetails } from './getConfirmationBasedInvoiceDetails';
describe('getConfirmationBasedInvoiceDetails', () => {
it('returns monero details for XMR invoices', () => {
const moneroDetails = { requiredConfirmations: 3 };
expect(
getConfirmationBasedInvoiceDetails({
paymentMethod: PaymentMethod.Xmr,
moneroDetails
})
).toBe(moneroDetails);
});
it('returns bitcoin details for BTC invoices', () => {
const btcDetails = { requiredConfirmations: 6 };
expect(
getConfirmationBasedInvoiceDetails({
paymentMethod: PaymentMethod.Btc,
btcDetails
})
).toBe(btcDetails);
});
it('returns undefined for unsupported payment methods', () => {
expect(
getConfirmationBasedInvoiceDetails({
paymentMethod: 'eth' as PaymentMethod
})
).toBeUndefined();
});
});
@@ -0,0 +1,16 @@
import { PaymentMethod } from '../../modules/payment/types/PaymentMethod';
import type { ConfirmationBasedInvoiceDetails } from './types/ConfirmationBasedInvoiceDetails';
import type { InvoiceStateInput } from './types/InvoiceStateInput';
export const getConfirmationBasedInvoiceDetails = (
invoice: Pick<InvoiceStateInput, 'paymentMethod' | 'moneroDetails' | 'btcDetails'>
): ConfirmationBasedInvoiceDetails | null | undefined => {
switch (invoice.paymentMethod) {
case PaymentMethod.Xmr:
return invoice.moneroDetails;
case PaymentMethod.Btc:
return invoice.btcDetails;
default:
return undefined;
}
};
@@ -17,14 +17,32 @@ describe('resolveInvoiceRequiredConfirmations', () => {
paymentMethod: PaymentMethod.Xmr,
moneroDetails: null
})
).toThrow('Invoice is missing Monero required confirmations');
).toThrow('Invoice is missing xmr required confirmations');
});
it('returns required confirmations for BTC invoices', () => {
expect(
resolveInvoiceRequiredConfirmations({
paymentMethod: PaymentMethod.Btc,
btcDetails: { requiredConfirmations: 6 }
})
).toBe(6);
});
it('throws when bitcoin details are missing', () => {
expect(() =>
resolveInvoiceRequiredConfirmations({
paymentMethod: PaymentMethod.Btc,
btcDetails: null
})
).toThrow('Invoice is missing btc required confirmations');
});
it('throws for unsupported payment methods', () => {
expect(() =>
resolveInvoiceRequiredConfirmations({
paymentMethod: 'btc' as PaymentMethod
paymentMethod: 'eth' as PaymentMethod
})
).toThrow('Unsupported payment method: btc');
).toThrow('Invoice is missing eth required confirmations');
});
});
@@ -1,18 +1,14 @@
import { PaymentMethod } from '../../modules/payment/types/PaymentMethod';
import type { InvoiceConfirmationsInput } from './types/InvoiceConfirmationsInput';
import { getConfirmationBasedInvoiceDetails } from './getConfirmationBasedInvoiceDetails';
export const resolveInvoiceRequiredConfirmations = (invoice: InvoiceConfirmationsInput): number => {
switch (invoice.paymentMethod) {
case PaymentMethod.Xmr: {
const requiredConfirmations = invoice.moneroDetails?.requiredConfirmations;
const details = getConfirmationBasedInvoiceDetails(invoice);
if (requiredConfirmations === undefined) {
throw new Error('Invoice is missing Monero required confirmations');
}
const requiredConfirmations = details?.requiredConfirmations;
return requiredConfirmations;
}
default:
throw new Error(`Unsupported payment method: ${String(invoice.paymentMethod)}`);
if (requiredConfirmations === undefined) {
throw new Error(`Invoice is missing ${invoice.paymentMethod} required confirmations`);
}
return requiredConfirmations;
};
@@ -0,0 +1,3 @@
export type ConfirmationBasedInvoiceDetails = {
requiredConfirmations: number;
};
@@ -1,7 +1,6 @@
import type { PaymentMethod } from '../../../modules/payment/types/PaymentMethod';
import type { InvoiceStateInput } from './InvoiceStateInput';
export type InvoiceConfirmationsInput = {
paymentMethod: PaymentMethod;
payments?: { confirmations: number }[];
moneroDetails?: { requiredConfirmations: number } | null;
};
export type InvoiceConfirmationsInput = Pick<
InvoiceStateInput,
'paymentMethod' | 'moneroDetails' | 'btcDetails' | 'payments'
>;
@@ -1,9 +1,11 @@
import type { PaymentMethod } from '../../../modules/payment/types/PaymentMethod';
import type { ConfirmationBasedInvoiceDetails } from './ConfirmationBasedInvoiceDetails';
export type InvoiceStateInput = {
paymentMethod: PaymentMethod;
expectedTotalAtomic: string;
expiresAt: Date;
payments?: { confirmations: number; amountAtomic: string }[];
moneroDetails?: { requiredConfirmations: number } | null;
moneroDetails?: ConfirmationBasedInvoiceDetails | null;
btcDetails?: ConfirmationBasedInvoiceDetails | null;
};