From e4a6e2b2f13a3064453f149400027fc706c79f0c Mon Sep 17 00:00:00 2001 From: David May <85513542+davidleomay@users.noreply.github.com> Date: Tue, 27 Jan 2026 03:15:58 +0100 Subject: [PATCH] fix: various fixes (#3055) --- src/integration/exchange/dto/mexc.dto.ts | 15 +++++++ .../exchange/services/mexc.service.ts | 27 +++++++++++ .../payment/services/swiss-qr.service.ts | 45 ++++++++++++------- .../services/transaction-request.service.ts | 2 +- .../integration/pricing-juice.service.ts | 2 +- 5 files changed, 72 insertions(+), 19 deletions(-) diff --git a/src/integration/exchange/dto/mexc.dto.ts b/src/integration/exchange/dto/mexc.dto.ts index 5696074c4c..679c91e8f2 100644 --- a/src/integration/exchange/dto/mexc.dto.ts +++ b/src/integration/exchange/dto/mexc.dto.ts @@ -111,3 +111,18 @@ export interface MexcTrade { isBuyerMaker: boolean; isBestMatch: boolean; } + +export interface MexcMyTrade { + symbol: string; + id: number; + orderId: number; + price: string; + qty: string; + quoteQty: string; + commission: string; + commissionAsset: string; + time: number; + isBuyer: boolean; + isMaker: boolean; + isBestMatch: boolean; +} diff --git a/src/integration/exchange/services/mexc.service.ts b/src/integration/exchange/services/mexc.service.ts index d2d9d50287..cd8762b83c 100644 --- a/src/integration/exchange/services/mexc.service.ts +++ b/src/integration/exchange/services/mexc.service.ts @@ -10,6 +10,7 @@ import { Deposit, DepositStatus, MexcExchangeInfo, + MexcMyTrade, MexcOrderBook, MexcSymbol, MexcTrade, @@ -261,4 +262,30 @@ export class MexcService extends ExchangeService { if (precision === 0) return 1; return parseFloat('0.' + '0'.repeat(precision - 1) + '1'); } + + async getTrades(from: string, to: string, since?: Date): Promise { + const pair = await this.getPair(from, to); + + const params: Record = { symbol: pair.replace('/', '') }; + if (since) params.startTime = since.getTime().toString(); + + const data = await this.request('GET', 'myTrades', params); + + return data.map((t) => ({ + id: t.id?.toString(), + info: t, + timestamp: t.time, + datetime: new Date(t.time).toISOString(), + symbol: pair, + order: t.orderId?.toString(), + type: undefined, + side: t.isBuyer ? 'buy' : 'sell', + takerOrMaker: t.isMaker ? 'maker' : 'taker', + price: parseFloat(t.price), + amount: parseFloat(t.qty), + cost: parseFloat(t.quoteQty), + fee: t.commission ? { cost: parseFloat(t.commission), currency: t.commissionAsset } : undefined, + fees: t.commission ? [{ cost: parseFloat(t.commission), currency: t.commissionAsset }] : [], + })); + } } diff --git a/src/subdomains/supporting/payment/services/swiss-qr.service.ts b/src/subdomains/supporting/payment/services/swiss-qr.service.ts index eb566113ea..9c7ba32e00 100644 --- a/src/subdomains/supporting/payment/services/swiss-qr.service.ts +++ b/src/subdomains/supporting/payment/services/swiss-qr.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { BadRequestException, Injectable } from '@nestjs/common'; import { I18nService } from 'nestjs-i18n'; import PDFDocument from 'pdfkit'; import { Config } from 'src/config/config'; @@ -59,11 +59,6 @@ export class SwissQRService { throw new Error('PDF invoice is only available for CHF and EUR transactions'); } - // Use EUR-specific IBAN for EUR invoices - if (currency === 'EUR') { - bankInfo = { ...bankInfo, iban: 'CH8583019DFXSWISSEURX' }; - } - const data = this.generateQrData(amount, currency, bankInfo, reference, request.userData); const userLanguage = request.userData.language.symbol.toUpperCase(); @@ -508,30 +503,38 @@ export class SwissQRService { } const outputAsset = transaction.buyCrypto?.outputAsset; + const fiatAmount = transaction.buyCrypto?.inputAmount; + const quantity = transaction.buyCrypto?.outputAmount; + if (!outputAsset || fiatAmount == null || quantity == null) + throw new BadRequestException('Missing invoice information'); return { - quantity: transaction.buyCrypto?.outputAmount, + quantity, description: { assetDescription: outputAsset.description ?? outputAsset.name, assetName: outputAsset.name, assetBlockchain: outputAsset.blockchain, }, - fiatAmount: transaction.buyCrypto?.inputAmount, + fiatAmount, ...titleAndDate, }; } case TransactionType.SELL: { const inputAsset = transaction.buyFiat?.cryptoInput?.asset; + const fiatAmount = transaction.buyFiat?.outputAmount; + const quantity = transaction.buyFiat?.inputAmount; + if (!inputAsset || fiatAmount == null || quantity == null) + throw new BadRequestException('Missing invoice information'); return { - quantity: transaction.buyFiat?.inputAmount, + quantity, description: { assetDescription: inputAsset.description ?? inputAsset.name, assetName: inputAsset.name, assetBlockchain: inputAsset.blockchain, }, - fiatAmount: transaction.buyFiat?.outputAmount, + fiatAmount, ...titleAndDate, }; } @@ -539,36 +542,44 @@ export class SwissQRService { case TransactionType.SWAP: { const sourceAsset = transaction.buyCrypto?.cryptoInput?.asset; const targetAsset = transaction.buyCrypto?.outputAsset; + const fiatAmount = currency === 'CHF' ? transaction.buyCrypto?.amountInChf : transaction.buyCrypto?.amountInEur; + const quantity = transaction.buyCrypto?.inputAmount; + const targetAmount = transaction.buyCrypto?.outputAmount; + if (!sourceAsset || !targetAsset || fiatAmount == null || quantity == null || targetAmount == null) + throw new BadRequestException('Missing invoice information'); return { - quantity: transaction.buyCrypto?.inputAmount, + quantity, description: { sourceDescription: sourceAsset.description ?? sourceAsset.name, sourceName: sourceAsset.name, sourceBlockchain: sourceAsset.blockchain, - targetAmount: transaction.buyCrypto?.outputAmount, + targetAmount, targetDescription: targetAsset.description ?? targetAsset.name, targetName: targetAsset.name, targetBlockchain: targetAsset.blockchain, }, - fiatAmount: currency === 'CHF' ? transaction.buyCrypto?.amountInChf : transaction.buyCrypto?.amountInEur, + fiatAmount, ...titleAndDate, }; } case TransactionType.REFERRAL: { const targetBlockchain = transaction.refReward?.targetBlockchain; - if (!targetBlockchain) throw new Error('Missing blockchain information for referral'); + if (!targetBlockchain) throw new BadRequestException('Missing invoice information'); const asset = await this.assetService.getNativeAsset(targetBlockchain); - if (!asset) throw new Error(`Native asset not found for blockchain ${targetBlockchain}`); + if (!asset) throw new BadRequestException('Missing invoice information'); + const fiatAmount = currency === 'CHF' ? transaction.refReward?.amountInChf : transaction.refReward?.amountInEur; + const quantity = transaction.refReward?.outputAmount; + if (fiatAmount == null || quantity == null) throw new BadRequestException('Missing invoice information'); return { - quantity: transaction.refReward?.outputAmount, + quantity, description: { assetName: asset.name, assetBlockchain: targetBlockchain, }, - fiatAmount: currency === 'CHF' ? transaction.refReward?.amountInChf : transaction.refReward?.amountInEur, + fiatAmount, ...titleAndDate, }; } diff --git a/src/subdomains/supporting/payment/services/transaction-request.service.ts b/src/subdomains/supporting/payment/services/transaction-request.service.ts index b50d6b85ad..373a0af4a1 100644 --- a/src/subdomains/supporting/payment/services/transaction-request.service.ts +++ b/src/subdomains/supporting/payment/services/transaction-request.service.ts @@ -338,7 +338,7 @@ export class TransactionRequestService { .where('tr.type IN (:...types)', { types: [TransactionRequestType.SELL, TransactionRequestType.SWAP] }) .andWhere('tr.status = :status', { status: TransactionRequestStatus.CREATED }) .andWhere('tr.created > :created', { created }) - .andWhere('d.blockchains = :blockchain', { blockchain }) + .andWhere('d.blockchains LIKE :blockchain', { blockchain: `%${blockchain}%` }) .getRawMany<{ address: string }>() .then((transactionRequests) => transactionRequests.map((deposit) => deposit.address)); } diff --git a/src/subdomains/supporting/pricing/services/integration/pricing-juice.service.ts b/src/subdomains/supporting/pricing/services/integration/pricing-juice.service.ts index aac4a82283..2182d8278f 100644 --- a/src/subdomains/supporting/pricing/services/integration/pricing-juice.service.ts +++ b/src/subdomains/supporting/pricing/services/integration/pricing-juice.service.ts @@ -18,7 +18,7 @@ export class PricingJuiceService extends PricingProvider implements OnModuleInit PricingJuiceService.BTC, ]; - private static readonly CONTRACT_FEE = 0.01; + private static readonly CONTRACT_FEE = 0.02; private juiceService: JuiceService; private krakenService: KrakenService;