121 lines
4.1 KiB
TypeScript
121 lines
4.1 KiB
TypeScript
import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
|
|
import {
|
|
WithdrawalEventConsumerService,
|
|
WithdrawalRequestedPayload,
|
|
} from '@/infrastructure/kafka/withdrawal-event-consumer.service';
|
|
import { EventPublisherService } from '@/infrastructure/kafka/event-publisher.service';
|
|
|
|
/**
|
|
* Withdrawal Requested Event Handler
|
|
*
|
|
* Handles withdrawal requests from wallet-service.
|
|
* For now, logs the event and publishes a status update.
|
|
*
|
|
* Future implementation will:
|
|
* 1. Create TransactionRequest record
|
|
* 2. Request MPC signing
|
|
* 3. Broadcast to blockchain
|
|
* 4. Monitor confirmation
|
|
*/
|
|
@Injectable()
|
|
export class WithdrawalRequestedHandler implements OnModuleInit {
|
|
private readonly logger = new Logger(WithdrawalRequestedHandler.name);
|
|
|
|
constructor(
|
|
private readonly withdrawalEventConsumer: WithdrawalEventConsumerService,
|
|
private readonly eventPublisher: EventPublisherService,
|
|
) {}
|
|
|
|
onModuleInit() {
|
|
this.withdrawalEventConsumer.onWithdrawalRequested(
|
|
this.handleWithdrawalRequested.bind(this),
|
|
);
|
|
this.logger.log(`[INIT] WithdrawalRequestedHandler registered`);
|
|
}
|
|
|
|
/**
|
|
* Handle withdrawal requested event from wallet-service
|
|
*
|
|
* Current implementation: Log and acknowledge
|
|
* TODO: Implement full blockchain transaction flow
|
|
*/
|
|
private async handleWithdrawalRequested(
|
|
payload: WithdrawalRequestedPayload,
|
|
): Promise<void> {
|
|
this.logger.log(`[HANDLE] Received WithdrawalRequested event`);
|
|
this.logger.log(`[HANDLE] orderNo: ${payload.orderNo}`);
|
|
this.logger.log(`[HANDLE] accountSequence: ${payload.accountSequence}`);
|
|
this.logger.log(`[HANDLE] userId: ${payload.userId}`);
|
|
this.logger.log(`[HANDLE] chainType: ${payload.chainType}`);
|
|
this.logger.log(`[HANDLE] toAddress: ${payload.toAddress}`);
|
|
this.logger.log(`[HANDLE] amount: ${payload.amount}`);
|
|
this.logger.log(`[HANDLE] fee: ${payload.fee}`);
|
|
this.logger.log(`[HANDLE] netAmount: ${payload.netAmount}`);
|
|
|
|
try {
|
|
// TODO: Full implementation steps:
|
|
// 1. Validate the withdrawal request
|
|
// 2. Get system hot wallet address for the chain
|
|
// 3. Create TransactionRequest record
|
|
// 4. Request MPC signing
|
|
// 5. After signed, broadcast to blockchain
|
|
// 6. Monitor for confirmation
|
|
// 7. Publish status updates back to wallet-service
|
|
|
|
// For now, just log that we received it
|
|
this.logger.log(
|
|
`[PROCESS] Withdrawal ${payload.orderNo} received for processing`,
|
|
);
|
|
this.logger.log(
|
|
`[PROCESS] Chain: ${payload.chainType}, To: ${payload.toAddress}, Amount: ${payload.netAmount} USDT`,
|
|
);
|
|
|
|
// Publish acknowledgment event (wallet-service can listen for status updates)
|
|
await this.eventPublisher.publish({
|
|
eventType: 'blockchain.withdrawal.received',
|
|
toPayload: () => ({
|
|
orderNo: payload.orderNo,
|
|
accountSequence: payload.accountSequence,
|
|
status: 'RECEIVED',
|
|
message: 'Withdrawal request received by blockchain-service',
|
|
}),
|
|
eventId: `wd-received-${payload.orderNo}-${Date.now()}`,
|
|
occurredAt: new Date(),
|
|
});
|
|
|
|
this.logger.log(
|
|
`[COMPLETE] Withdrawal ${payload.orderNo} acknowledged`,
|
|
);
|
|
|
|
// NOTE: Actual blockchain transaction implementation would go here
|
|
// This would involve:
|
|
// - Creating a TransactionRequest aggregate
|
|
// - Calling MPC service for signing
|
|
// - Broadcasting the signed transaction
|
|
// - Monitoring for confirmations
|
|
// - Publishing final status (CONFIRMED or FAILED)
|
|
|
|
} catch (error) {
|
|
this.logger.error(
|
|
`[ERROR] Failed to process withdrawal ${payload.orderNo}`,
|
|
error,
|
|
);
|
|
|
|
// Publish failure event
|
|
await this.eventPublisher.publish({
|
|
eventType: 'blockchain.withdrawal.failed',
|
|
toPayload: () => ({
|
|
orderNo: payload.orderNo,
|
|
accountSequence: payload.accountSequence,
|
|
status: 'FAILED',
|
|
error: error instanceof Error ? error.message : 'Unknown error',
|
|
}),
|
|
eventId: `wd-failed-${payload.orderNo}-${Date.now()}`,
|
|
occurredAt: new Date(),
|
|
});
|
|
|
|
throw error;
|
|
}
|
|
}
|
|
}
|