From 3cb50f21a03b26a46191470d313d61e4d5e76632 Mon Sep 17 00:00:00 2001 From: kaushalya4s5s7 Date: Sun, 11 Jan 2026 16:06:55 +0530 Subject: [PATCH 1/3] purchase notify update for negative values --- .../src/database/schemas/purchase.schema.ts | 1 + .../marketplace/dto/notify-purchase.dto.ts | 6 +- .../services/purchase-tracker.service.ts | 62 ++++++++++++++++--- 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/packages/backend/src/database/schemas/purchase.schema.ts b/packages/backend/src/database/schemas/purchase.schema.ts index 4c7e017..b047356 100644 --- a/packages/backend/src/database/schemas/purchase.schema.ts +++ b/packages/backend/src/database/schemas/purchase.schema.ts @@ -40,6 +40,7 @@ export class Purchase { assetName?: string; industry?: string; riskTier?: string; + type?: 'PURCHASE' | 'DEPOSIT'; // Track if this is a purchase or deposit }; // Timestamps (automatically added by Mongoose with timestamps: true) diff --git a/packages/backend/src/modules/marketplace/dto/notify-purchase.dto.ts b/packages/backend/src/modules/marketplace/dto/notify-purchase.dto.ts index 66490f2..f68edef 100644 --- a/packages/backend/src/modules/marketplace/dto/notify-purchase.dto.ts +++ b/packages/backend/src/modules/marketplace/dto/notify-purchase.dto.ts @@ -1,4 +1,4 @@ -import { IsString, IsNotEmpty, IsNumberString, IsOptional } from 'class-validator'; +import { IsString, IsNotEmpty, IsNumberString, IsOptional, Matches } from 'class-validator'; export class NotifyPurchaseDto { @IsString() @@ -9,9 +9,9 @@ export class NotifyPurchaseDto { @IsNotEmpty() assetId!: string; - @IsNumberString() + @Matches(/^-?\d+$/, { message: 'amount must be a valid number string (can be negative)' }) @IsNotEmpty() - amount!: string; // Token amount purchased (in wei) + amount!: string; // Token amount purchased (in wei) - can be negative @IsOptional() @IsNumberString() diff --git a/packages/backend/src/modules/marketplace/services/purchase-tracker.service.ts b/packages/backend/src/modules/marketplace/services/purchase-tracker.service.ts index fb465bc..7273258 100644 --- a/packages/backend/src/modules/marketplace/services/purchase-tracker.service.ts +++ b/packages/backend/src/modules/marketplace/services/purchase-tracker.service.ts @@ -48,7 +48,58 @@ export class PurchaseTrackerService { throw new ConflictException('Purchase already recorded'); } - // Validate transaction on-chain + // Get asset details + const asset = await this.assetModel.findOne({ assetId: dto.assetId }); + if (!asset) { + throw new BadRequestException('Asset not found'); + } + + // Check if this is a deposit (negative amount) or a purchase (positive amount) + const isDeposit = dto.amount.startsWith('-'); + + if (isDeposit) { + // Handle token deposit to contract (balance decrease) + this.logger.log(`Processing token deposit (balance decrease): ${dto.amount}`); + + // Convert amount to wei (if not already in wei) + const amountWithoutSign = dto.amount.substring(1); // Remove negative sign + const depositAmountInWei = (BigInt(amountWithoutSign) * BigInt(10 ** 18)).toString(); + const blockNumber = dto.blockNumber ? parseInt(dto.blockNumber) : 0; + + // Record as a negative purchase to track balance decrease + const purchase = await this.purchaseModel.create({ + txHash: dto.txHash, + assetId: dto.assetId, + investorWallet: investorWallet.toLowerCase(), // Store as negative in wei + tokenAddress: asset.token?.address || '', + amount: '-' + depositAmountInWei, + price: '0', // No price for deposits + totalPayment: '0', // No payment for deposits + blockNumber: blockNumber, + blockTimestamp: new Date(), + status: 'CONFIRMED', + metadata: { + assetName: `${asset.metadata?.invoiceNumber} - ${asset.metadata?.buyerName}`, + industry: asset.metadata?.industry, + riskTier: asset.metadata?.riskTier, + type: 'DEPOSIT', // Mark as deposit + }, + }); + + this.logger.log(`Token deposit recorded: ${purchase._id}, amount in wei: -${depositAmountInWei}`); + + return { + success: true, + purchaseId: purchase._id, + assetId: dto.assetId, + amount: '-' + depositAmountInWei, + totalPayment: '0', + tokenAddress: asset.token?.address, + type: 'DEPOSIT', + }; + } + + // Handle normal purchase (positive amount) - validate on-chain const purchaseData = await this.validatePurchaseTransaction( dto.txHash as Hash, dto.assetId, @@ -59,12 +110,6 @@ export class PurchaseTrackerService { throw new BadRequestException('Invalid purchase transaction'); } - // Get asset details - const asset = await this.assetModel.findOne({ assetId: dto.assetId }); - if (!asset) { - throw new BadRequestException('Asset not found'); - } - // Record purchase in database const purchase = await this.purchaseModel.create({ txHash: dto.txHash, @@ -86,7 +131,7 @@ export class PurchaseTrackerService { this.logger.log(`Purchase recorded: ${purchase._id}`); - // Update asset.listing.sold with verified amount from transaction + // Update asset.listing.sold with verified amount from transaction (only for purchases, not deposits) try { const currentSold = BigInt(asset.listing?.sold || '0'); const purchasedAmount = BigInt(purchaseData.amount); @@ -335,6 +380,7 @@ export class PurchaseTrackerService { const existing = portfolioMap.get(purchase.assetId); if (existing) { + // Add purchase amount (works with both positive purchases and negative deposits) existing.totalAmount = (BigInt(existing.totalAmount) + BigInt(purchase.amount)).toString(); existing.totalInvested = (BigInt(existing.totalInvested) + BigInt(purchase.totalPayment)).toString(); existing.purchaseCount += 1; From 97ecad4c504cb1ac4cc6744c30e419025d9ac233 Mon Sep 17 00:00:00 2001 From: kaushalya4s5s7 Date: Sun, 11 Jan 2026 18:33:53 +0530 Subject: [PATCH 2/3] removed unused toektype checking throguh asset model, updated correctle looking into onchain event --- .../controllers/solvency.controller.ts | 6 +++--- .../services/solvency-blockchain.service.ts | 19 +++++++++++++++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/packages/backend/src/modules/solvency/controllers/solvency.controller.ts b/packages/backend/src/modules/solvency/controllers/solvency.controller.ts index 0aba9ce..e3c2ce2 100644 --- a/packages/backend/src/modules/solvency/controllers/solvency.controller.ts +++ b/packages/backend/src/modules/solvency/controllers/solvency.controller.ts @@ -244,15 +244,15 @@ export class SolvencyController { throw new BadRequestException('Position does not belong to authenticated user'); } - // Auto-detect token type based on Asset collection - const tokenType = await this.positionService.determineTokenType(positionData.collateralToken); + // Use token type directly from blockchain (0 = RWA, 1 = PRIVATE_ASSET) + const tokenType = positionData.tokenType === 0 ? 'RWA' : 'PRIVATE_ASSET'; // Sync database record (update if exists, create if not) const position = await this.positionService.syncPosition( positionId, positionData.user, positionData.collateralToken, - tokenType, + tokenType as any, positionData.collateralAmount.toString(), positionData.tokenValueUSD.toString(), dto.txHash, diff --git a/packages/backend/src/modules/solvency/services/solvency-blockchain.service.ts b/packages/backend/src/modules/solvency/services/solvency-blockchain.service.ts index 8dc3dc3..af663bd 100644 --- a/packages/backend/src/modules/solvency/services/solvency-blockchain.service.ts +++ b/packages/backend/src/modules/solvency/services/solvency-blockchain.service.ts @@ -154,6 +154,8 @@ export class SolvencyBlockchainService { usdcBorrowed: bigint; tokenValueUSD: bigint; createdAt: bigint; + liquidatedAt: bigint; + creditLineId: bigint; active: boolean; tokenType: number; }> { @@ -169,6 +171,17 @@ export class SolvencyBlockchainService { args: [BigInt(positionId)], }) as any; + this.logger.log(`Position user retrieved for ID ${position[0]}`); + this.logger.log(`Position collateral token: ${position[1]}`); + this.logger.log(`Position collateral amount: ${position[2]}`); + this.logger.log(`Position USDC borrowed: ${position[3]}`); + this.logger.log(`Position token value USD: ${position[4]}`); + this.logger.log(`Position created at: ${position[5]}`); + this.logger.log(`Position liquidated at: ${position[6]}`); + this.logger.log(`Position credit line ID: ${position[7]}`); + this.logger.log(`Position active: ${position[8]}`); + this.logger.log(`Position token type: ${position[9]}`); + return { user: position[0], collateralToken: position[1], @@ -176,8 +189,10 @@ export class SolvencyBlockchainService { usdcBorrowed: position[3], tokenValueUSD: position[4], createdAt: position[5], - active: position[6], - tokenType: position[7], + liquidatedAt: position[6], + creditLineId: position[7], + active: position[8], + tokenType: position[9], }; } From 502b150a1e8b90d10823212cdd5c98498ca62dd7 Mon Sep 17 00:00:00 2001 From: kaushalya4s5s7 Date: Sun, 11 Jan 2026 20:52:27 +0530 Subject: [PATCH 3/3] declared teh type purchase in purchase model --- .../services/purchase-tracker.service.ts | 64 +++---------------- 1 file changed, 10 insertions(+), 54 deletions(-) diff --git a/packages/backend/src/modules/marketplace/services/purchase-tracker.service.ts b/packages/backend/src/modules/marketplace/services/purchase-tracker.service.ts index 7273258..cc313d1 100644 --- a/packages/backend/src/modules/marketplace/services/purchase-tracker.service.ts +++ b/packages/backend/src/modules/marketplace/services/purchase-tracker.service.ts @@ -48,58 +48,7 @@ export class PurchaseTrackerService { throw new ConflictException('Purchase already recorded'); } - // Get asset details - const asset = await this.assetModel.findOne({ assetId: dto.assetId }); - if (!asset) { - throw new BadRequestException('Asset not found'); - } - - // Check if this is a deposit (negative amount) or a purchase (positive amount) - const isDeposit = dto.amount.startsWith('-'); - - if (isDeposit) { - // Handle token deposit to contract (balance decrease) - this.logger.log(`Processing token deposit (balance decrease): ${dto.amount}`); - - // Convert amount to wei (if not already in wei) - const amountWithoutSign = dto.amount.substring(1); // Remove negative sign - const depositAmountInWei = (BigInt(amountWithoutSign) * BigInt(10 ** 18)).toString(); - const blockNumber = dto.blockNumber ? parseInt(dto.blockNumber) : 0; - - // Record as a negative purchase to track balance decrease - const purchase = await this.purchaseModel.create({ - txHash: dto.txHash, - assetId: dto.assetId, - investorWallet: investorWallet.toLowerCase(), // Store as negative in wei - tokenAddress: asset.token?.address || '', - amount: '-' + depositAmountInWei, - price: '0', // No price for deposits - totalPayment: '0', // No payment for deposits - blockNumber: blockNumber, - blockTimestamp: new Date(), - status: 'CONFIRMED', - metadata: { - assetName: `${asset.metadata?.invoiceNumber} - ${asset.metadata?.buyerName}`, - industry: asset.metadata?.industry, - riskTier: asset.metadata?.riskTier, - type: 'DEPOSIT', // Mark as deposit - }, - }); - - this.logger.log(`Token deposit recorded: ${purchase._id}, amount in wei: -${depositAmountInWei}`); - - return { - success: true, - purchaseId: purchase._id, - assetId: dto.assetId, - amount: '-' + depositAmountInWei, - totalPayment: '0', - tokenAddress: asset.token?.address, - type: 'DEPOSIT', - }; - } - - // Handle normal purchase (positive amount) - validate on-chain + // Validate transaction on-chain const purchaseData = await this.validatePurchaseTransaction( dto.txHash as Hash, dto.assetId, @@ -110,6 +59,12 @@ export class PurchaseTrackerService { throw new BadRequestException('Invalid purchase transaction'); } + // Get asset details + const asset = await this.assetModel.findOne({ assetId: dto.assetId }); + if (!asset) { + throw new BadRequestException('Asset not found'); + } + // Record purchase in database const purchase = await this.purchaseModel.create({ txHash: dto.txHash, @@ -126,12 +81,14 @@ export class PurchaseTrackerService { assetName: `${asset.metadata?.invoiceNumber} - ${asset.metadata?.buyerName}`, industry: asset.metadata?.industry, riskTier: asset.metadata?.riskTier, + type: 'PURCHASE', // Mark as purchase + }, }); this.logger.log(`Purchase recorded: ${purchase._id}`); - // Update asset.listing.sold with verified amount from transaction (only for purchases, not deposits) + // Update asset.listing.sold with verified amount from transaction try { const currentSold = BigInt(asset.listing?.sold || '0'); const purchasedAmount = BigInt(purchaseData.amount); @@ -380,7 +337,6 @@ export class PurchaseTrackerService { const existing = portfolioMap.get(purchase.assetId); if (existing) { - // Add purchase amount (works with both positive purchases and negative deposits) existing.totalAmount = (BigInt(existing.totalAmount) + BigInt(purchase.amount)).toString(); existing.totalInvested = (BigInt(existing.totalInvested) + BigInt(purchase.totalPayment)).toString(); existing.purchaseCount += 1;