103 lines
3.0 KiB
TypeScript
103 lines
3.0 KiB
TypeScript
/**
|
|
* Deposit Controller
|
|
*
|
|
* Provides deposit-related endpoints for the mobile app.
|
|
* Queries on-chain USDT balances for user's monitored addresses.
|
|
*/
|
|
|
|
import { Controller, Get, Logger, Inject, UseGuards, Req } from '@nestjs/common';
|
|
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagger';
|
|
import { Request } from 'express';
|
|
import { BalanceQueryService } from '@/application/services/balance-query.service';
|
|
import { ChainTypeEnum } from '@/domain/enums';
|
|
import {
|
|
IMonitoredAddressRepository,
|
|
MONITORED_ADDRESS_REPOSITORY,
|
|
} from '@/domain/repositories/monitored-address.repository.interface';
|
|
import { JwtAuthGuard } from '@/shared/guards/jwt-auth.guard';
|
|
|
|
interface JwtPayload {
|
|
userId: string;
|
|
accountSequence: string;
|
|
deviceId: string;
|
|
}
|
|
|
|
interface UsdtBalanceDto {
|
|
chainType: string;
|
|
address: string;
|
|
balance: string;
|
|
rawBalance: string;
|
|
decimals: number;
|
|
}
|
|
|
|
interface DepositBalancesResponseDto {
|
|
kava: UsdtBalanceDto | null;
|
|
bsc: UsdtBalanceDto | null;
|
|
}
|
|
|
|
@ApiTags('Deposit')
|
|
@Controller('deposit')
|
|
export class DepositController {
|
|
private readonly logger = new Logger(DepositController.name);
|
|
|
|
constructor(
|
|
private readonly balanceService: BalanceQueryService,
|
|
@Inject(MONITORED_ADDRESS_REPOSITORY)
|
|
private readonly monitoredAddressRepo: IMonitoredAddressRepository,
|
|
) {}
|
|
|
|
@Get('balances')
|
|
@UseGuards(JwtAuthGuard)
|
|
@ApiBearerAuth()
|
|
@ApiOperation({ summary: '查询用户 USDT 余额' })
|
|
@ApiResponse({ status: 200, description: '余额信息' })
|
|
async getBalances(@Req() req: Request): Promise<DepositBalancesResponseDto> {
|
|
const user = (req as Request & { user: JwtPayload }).user;
|
|
const userId = BigInt(user.userId);
|
|
|
|
this.logger.log(`Querying deposit balances for user ${userId}`);
|
|
|
|
// Get user's monitored addresses
|
|
const addresses = await this.monitoredAddressRepo.findByUserId(userId);
|
|
|
|
const response: DepositBalancesResponseDto = {
|
|
kava: null,
|
|
bsc: null,
|
|
};
|
|
|
|
// Query balance for each chain
|
|
for (const addr of addresses) {
|
|
try {
|
|
const chainType = addr.chainType;
|
|
const addressStr = addr.address.toString();
|
|
const chainTypeStr = chainType.toString();
|
|
|
|
const balance = await this.balanceService.getBalance(chainType, addressStr);
|
|
|
|
const balanceDto: UsdtBalanceDto = {
|
|
chainType: chainTypeStr,
|
|
address: addressStr,
|
|
balance: balance.usdtBalance,
|
|
rawBalance: balance.usdtRawBalance,
|
|
decimals: balance.usdtDecimals,
|
|
};
|
|
|
|
if (chainTypeStr === ChainTypeEnum.KAVA) {
|
|
response.kava = balanceDto;
|
|
} else if (chainTypeStr === ChainTypeEnum.BSC) {
|
|
response.bsc = balanceDto;
|
|
}
|
|
} catch (error) {
|
|
this.logger.error(`Error querying balance for ${addr.chainType}:${addr.address}`, error);
|
|
}
|
|
}
|
|
|
|
this.logger.log(
|
|
`Balance query complete for user ${userId}: ` +
|
|
`KAVA=${response.kava?.balance || '0'}, BSC=${response.bsc?.balance || '0'}`,
|
|
);
|
|
|
|
return response;
|
|
}
|
|
}
|