feat(mining-blockchain): 支持 eUSDT 和 fUSDT 独立做市商钱包

- 新增 EUSDT_MARKET_MAKER_USERNAME/ADDRESS 配置
- 新增 FUSDT_MARKET_MAKER_USERNAME/ADDRESS 配置
- mpc-signing.client.ts: 分离 eUSDT 和 fUSDT 做市商签名方法
- erc20-transfer.service.ts: 根据代币类型选择对应钱包转账
- transfer.controller.ts: 更新余额查询和状态接口

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-01-28 19:05:15 -08:00
parent aa33803d08
commit 3b95a8a332
5 changed files with 213 additions and 86 deletions

View File

@ -282,9 +282,12 @@ services:
# C2C Bot 热钱包 (MPC) # C2C Bot 热钱包 (MPC)
HOT_WALLET_USERNAME: ${HOT_WALLET_USERNAME:-} HOT_WALLET_USERNAME: ${HOT_WALLET_USERNAME:-}
HOT_WALLET_ADDRESS: ${HOT_WALLET_ADDRESS:-} HOT_WALLET_ADDRESS: ${HOT_WALLET_ADDRESS:-}
# 做市商钱包 (MPC) - 用于 eUSDT/fUSDT 转账 # eUSDT (积分股) 做市商钱包 (MPC)
MARKET_MAKER_MPC_USERNAME: ${MARKET_MAKER_MPC_USERNAME:-} EUSDT_MARKET_MAKER_USERNAME: ${EUSDT_MARKET_MAKER_USERNAME:-}
MARKET_MAKER_WALLET_ADDRESS: ${MARKET_MAKER_WALLET_ADDRESS:-} EUSDT_MARKET_MAKER_ADDRESS: ${EUSDT_MARKET_MAKER_ADDRESS:-}
# fUSDT (积分值) 做市商钱包 (MPC)
FUSDT_MARKET_MAKER_USERNAME: ${FUSDT_MARKET_MAKER_USERNAME:-}
FUSDT_MARKET_MAKER_ADDRESS: ${FUSDT_MARKET_MAKER_ADDRESS:-}
# 区块扫描配置 # 区块扫描配置
BLOCK_SCAN_INTERVAL_MS: ${BLOCK_SCAN_INTERVAL_MS:-5000} BLOCK_SCAN_INTERVAL_MS: ${BLOCK_SCAN_INTERVAL_MS:-5000}
BLOCK_CONFIRMATIONS_REQUIRED: ${BLOCK_CONFIRMATIONS_REQUIRED:-12} BLOCK_CONFIRMATIONS_REQUIRED: ${BLOCK_CONFIRMATIONS_REQUIRED:-12}

View File

@ -77,13 +77,20 @@ HOT_WALLET_USERNAME=c2c-bot-wallet
HOT_WALLET_ADDRESS= HOT_WALLET_ADDRESS=
# ============================================================================= # =============================================================================
# 做市商 MPC 钱包(用于 eUSDT/fUSDT 转账) # eUSDT (积分股) 做市商 MPC 钱包
# ============================================================================= # =============================================================================
# 做市商 MPC 用户名(用于签名转账交易) # MPC 用户名(用于签名转账交易)
MARKET_MAKER_MPC_USERNAME= EUSDT_MARKET_MAKER_USERNAME=
# 钱包地址EVM 地址)
EUSDT_MARKET_MAKER_ADDRESS=
# 做市商钱包地址EVM 地址) # =============================================================================
MARKET_MAKER_WALLET_ADDRESS= # fUSDT (积分值) 做市商 MPC 钱包
# =============================================================================
# MPC 用户名(用于签名转账交易)
FUSDT_MARKET_MAKER_USERNAME=
# 钱包地址EVM 地址)
FUSDT_MARKET_MAKER_ADDRESS=
# ============================================================================= # =============================================================================
# 区块扫描配置 # 区块扫描配置

View File

@ -138,11 +138,11 @@ export class TransferController {
} }
@Get('eusdt/balance') @Get('eusdt/balance')
@ApiOperation({ summary: '查询做市商钱包 eUSDT积分股余额' }) @ApiOperation({ summary: '查询 eUSDT 做市商钱包余额' })
@ApiResponse({ status: 200, description: '余额信息', type: BalanceResponseDto }) @ApiResponse({ status: 200, description: '余额信息', type: BalanceResponseDto })
async getEusdtBalance(): Promise<BalanceResponseDto> { async getEusdtBalance(): Promise<BalanceResponseDto> {
const address = this.erc20TransferService.getMarketMakerAddress(ChainTypeEnum.KAVA); const address = this.erc20TransferService.getEusdtMarketMakerAddress(ChainTypeEnum.KAVA);
const balance = await this.erc20TransferService.getMarketMakerTokenBalance(ChainTypeEnum.KAVA, 'EUSDT'); const balance = await this.erc20TransferService.getEusdtMarketMakerTokenBalance(ChainTypeEnum.KAVA);
return { return {
address: address || '', address: address || '',
@ -177,11 +177,11 @@ export class TransferController {
} }
@Get('fusdt/balance') @Get('fusdt/balance')
@ApiOperation({ summary: '查询做市商钱包 fUSDT积分值余额' }) @ApiOperation({ summary: '查询 fUSDT 做市商钱包余额' })
@ApiResponse({ status: 200, description: '余额信息', type: BalanceResponseDto }) @ApiResponse({ status: 200, description: '余额信息', type: BalanceResponseDto })
async getFusdtBalance(): Promise<BalanceResponseDto> { async getFusdtBalance(): Promise<BalanceResponseDto> {
const address = this.erc20TransferService.getMarketMakerAddress(ChainTypeEnum.KAVA); const address = this.erc20TransferService.getFusdtMarketMakerAddress(ChainTypeEnum.KAVA);
const balance = await this.erc20TransferService.getMarketMakerTokenBalance(ChainTypeEnum.KAVA, 'FUSDT'); const balance = await this.erc20TransferService.getFusdtMarketMakerTokenBalance(ChainTypeEnum.KAVA);
return { return {
address: address || '', address: address || '',
@ -195,13 +195,19 @@ export class TransferController {
@Get('market-maker/status') @Get('market-maker/status')
@ApiOperation({ summary: '检查做市商转账服务状态' }) @ApiOperation({ summary: '检查做市商转账服务状态' })
@ApiResponse({ status: 200, description: '服务状态' }) @ApiResponse({ status: 200, description: '服务状态' })
async getMarketMakerStatus(): Promise<{ configured: boolean; marketMakerAddress: string | null }> { async getMarketMakerStatus(): Promise<{
const configured = this.erc20TransferService.isMarketMakerConfigured(ChainTypeEnum.KAVA); eusdt: { configured: boolean; address: string | null };
const marketMakerAddress = this.erc20TransferService.getMarketMakerAddress(ChainTypeEnum.KAVA); fusdt: { configured: boolean; address: string | null };
}> {
return { return {
configured, eusdt: {
marketMakerAddress, configured: this.erc20TransferService.isEusdtMarketMakerConfigured(ChainTypeEnum.KAVA),
address: this.erc20TransferService.getEusdtMarketMakerAddress(ChainTypeEnum.KAVA),
},
fusdt: {
configured: this.erc20TransferService.isFusdtMarketMakerConfigured(ChainTypeEnum.KAVA),
address: this.erc20TransferService.getFusdtMarketMakerAddress(ChainTypeEnum.KAVA),
},
}; };
} }
} }

View File

@ -38,10 +38,14 @@ export interface IMpcSigningClient {
isConfigured(): boolean; isConfigured(): boolean;
getHotWalletAddress(): string; getHotWalletAddress(): string;
signMessage(messageHash: string): Promise<string>; signMessage(messageHash: string): Promise<string>;
// 做市商钱包 // eUSDT (积分股) 做市商钱包
isMarketMakerConfigured(): boolean; isEusdtMarketMakerConfigured(): boolean;
getMarketMakerAddress(): string; getEusdtMarketMakerAddress(): string;
signMessageAsMarketMaker(messageHash: string): Promise<string>; signMessageAsEusdtMarketMaker(messageHash: string): Promise<string>;
// fUSDT (积分值) 做市商钱包
isFusdtMarketMakerConfigured(): boolean;
getFusdtMarketMakerAddress(): string;
signMessageAsFusdtMarketMaker(messageHash: string): Promise<string>;
} }
export const MPC_SIGNING_CLIENT = Symbol('MPC_SIGNING_CLIENT'); export const MPC_SIGNING_CLIENT = Symbol('MPC_SIGNING_CLIENT');
@ -58,8 +62,10 @@ export class Erc20TransferService {
private readonly providers: Map<ChainTypeEnum, JsonRpcProvider> = new Map(); private readonly providers: Map<ChainTypeEnum, JsonRpcProvider> = new Map();
// C2C Bot 热钱包地址 // C2C Bot 热钱包地址
private readonly hotWalletAddress: string; private readonly hotWalletAddress: string;
// 做市商钱包地址 // eUSDT (积分股) 做市商钱包地址
private readonly marketMakerAddress: string; private readonly eusdtMarketMakerAddress: string;
// fUSDT (积分值) 做市商钱包地址
private readonly fusdtMarketMakerAddress: string;
private mpcSigningClient: IMpcSigningClient | null = null; private mpcSigningClient: IMpcSigningClient | null = null;
constructor( constructor(
@ -67,7 +73,8 @@ export class Erc20TransferService {
private readonly chainConfig: ChainConfigService, private readonly chainConfig: ChainConfigService,
) { ) {
this.hotWalletAddress = this.configService.get<string>('HOT_WALLET_ADDRESS', ''); this.hotWalletAddress = this.configService.get<string>('HOT_WALLET_ADDRESS', '');
this.marketMakerAddress = this.configService.get<string>('MARKET_MAKER_WALLET_ADDRESS', ''); this.eusdtMarketMakerAddress = this.configService.get<string>('EUSDT_MARKET_MAKER_ADDRESS', '');
this.fusdtMarketMakerAddress = this.configService.get<string>('FUSDT_MARKET_MAKER_ADDRESS', '');
this.initializeProviders(); this.initializeProviders();
} }
@ -99,11 +106,18 @@ export class Erc20TransferService {
this.logger.warn('[INIT] HOT_WALLET_ADDRESS not configured, C2C transfers will fail'); this.logger.warn('[INIT] HOT_WALLET_ADDRESS not configured, C2C transfers will fail');
} }
// 检查做市商钱包地址配置 // 检查 eUSDT 做市商钱包地址配置
if (this.marketMakerAddress) { if (this.eusdtMarketMakerAddress) {
this.logger.log(`[INIT] Market Maker wallet address configured: ${this.marketMakerAddress}`); this.logger.log(`[INIT] eUSDT Market Maker address configured: ${this.eusdtMarketMakerAddress}`);
} else { } else {
this.logger.warn('[INIT] MARKET_MAKER_WALLET_ADDRESS not configured, Market Maker transfers will fail'); this.logger.warn('[INIT] EUSDT_MARKET_MAKER_ADDRESS not configured');
}
// 检查 fUSDT 做市商钱包地址配置
if (this.fusdtMarketMakerAddress) {
this.logger.log(`[INIT] fUSDT Market Maker address configured: ${this.fusdtMarketMakerAddress}`);
} else {
this.logger.warn('[INIT] FUSDT_MARKET_MAKER_ADDRESS not configured');
} }
} }
@ -116,10 +130,17 @@ export class Erc20TransferService {
} }
/** /**
* * eUSDT
*/ */
getMarketMakerAddress(chainType: ChainTypeEnum): string | null { getEusdtMarketMakerAddress(chainType: ChainTypeEnum): string | null {
return this.marketMakerAddress || null; return this.eusdtMarketMakerAddress || null;
}
/**
* fUSDT
*/
getFusdtMarketMakerAddress(chainType: ChainTypeEnum): string | null {
return this.fusdtMarketMakerAddress || null;
} }
/** /**
@ -585,12 +606,21 @@ export class Erc20TransferService {
} }
/** /**
* * eUSDT
*/ */
isMarketMakerConfigured(chainType: ChainTypeEnum): boolean { isEusdtMarketMakerConfigured(chainType: ChainTypeEnum): boolean {
return this.providers.has(chainType) && return this.providers.has(chainType) &&
!!this.marketMakerAddress && !!this.eusdtMarketMakerAddress &&
!!this.mpcSigningClient?.isMarketMakerConfigured(); !!this.mpcSigningClient?.isEusdtMarketMakerConfigured();
}
/**
* fUSDT
*/
isFusdtMarketMakerConfigured(chainType: ChainTypeEnum): boolean {
return this.providers.has(chainType) &&
!!this.fusdtMarketMakerAddress &&
!!this.mpcSigningClient?.isFusdtMarketMakerConfigured();
} }
/** /**
@ -608,10 +638,14 @@ export class Erc20TransferService {
toAddress: string, toAddress: string,
amount: string, amount: string,
): Promise<TransferResult> { ): Promise<TransferResult> {
const tokenName = tokenType === 'EUSDT' ? '积分股' : tokenType === 'FUSDT' ? '积分值' : 'dUSDT'; // 根据代币类型选择对应的做市商钱包
this.logger.log(`[MM-TRANSFER] Starting Market Maker ${tokenType} (${tokenName}) transfer`); const isEusdt = tokenType === 'EUSDT';
const marketMakerAddress = isEusdt ? this.eusdtMarketMakerAddress : this.fusdtMarketMakerAddress;
const tokenName = isEusdt ? '积分股' : '积分值';
this.logger.log(`[MM-TRANSFER] Starting ${tokenType} (${tokenName}) Market Maker transfer`);
this.logger.log(`[MM-TRANSFER] Chain: ${chainType}`); this.logger.log(`[MM-TRANSFER] Chain: ${chainType}`);
this.logger.log(`[MM-TRANSFER] From: ${this.marketMakerAddress}`); this.logger.log(`[MM-TRANSFER] From: ${marketMakerAddress}`);
this.logger.log(`[MM-TRANSFER] To: ${toAddress}`); this.logger.log(`[MM-TRANSFER] To: ${toAddress}`);
this.logger.log(`[MM-TRANSFER] Amount: ${amount} ${tokenType}`); this.logger.log(`[MM-TRANSFER] Amount: ${amount} ${tokenType}`);
@ -622,14 +656,23 @@ export class Erc20TransferService {
return { success: false, error }; return { success: false, error };
} }
if (!this.mpcSigningClient || !this.mpcSigningClient.isMarketMakerConfigured()) { // 检查对应钱包是否配置
const error = 'Market Maker MPC signing not configured'; if (isEusdt) {
this.logger.error(`[MM-TRANSFER] ${error}`); if (!this.mpcSigningClient || !this.mpcSigningClient.isEusdtMarketMakerConfigured()) {
return { success: false, error }; const error = 'eUSDT Market Maker MPC signing not configured';
this.logger.error(`[MM-TRANSFER] ${error}`);
return { success: false, error };
}
} else {
if (!this.mpcSigningClient || !this.mpcSigningClient.isFusdtMarketMakerConfigured()) {
const error = 'fUSDT Market Maker MPC signing not configured';
this.logger.error(`[MM-TRANSFER] ${error}`);
return { success: false, error };
}
} }
if (!this.marketMakerAddress) { if (!marketMakerAddress) {
const error = 'Market Maker wallet address not configured'; const error = `${tokenType} Market Maker wallet address not configured`;
this.logger.error(`[MM-TRANSFER] ${error}`); this.logger.error(`[MM-TRANSFER] ${error}`);
return { success: false, error }; return { success: false, error };
} }
@ -655,7 +698,7 @@ export class Erc20TransferService {
this.logger.log(`[MM-TRANSFER] Amount in wei: ${amountInWei.toString()}`); this.logger.log(`[MM-TRANSFER] Amount in wei: ${amountInWei.toString()}`);
// 检查余额 // 检查余额
const balance = await contract.balanceOf(this.marketMakerAddress); const balance = await contract.balanceOf(marketMakerAddress);
this.logger.log(`[MM-TRANSFER] Market Maker balance: ${formatUnits(balance, decimals)} ${tokenType}`); this.logger.log(`[MM-TRANSFER] Market Maker balance: ${formatUnits(balance, decimals)} ${tokenType}`);
if (balance < amountInWei) { if (balance < amountInWei) {
@ -666,7 +709,7 @@ export class Erc20TransferService {
// 构建交易 // 构建交易
this.logger.log(`[MM-TRANSFER] Building transaction...`); this.logger.log(`[MM-TRANSFER] Building transaction...`);
const nonce = await provider.getTransactionCount(this.marketMakerAddress); const nonce = await provider.getTransactionCount(marketMakerAddress);
const feeData = await provider.getFeeData(); const feeData = await provider.getFeeData();
// ERC20 transfer 的 calldata // ERC20 transfer 的 calldata
@ -674,7 +717,7 @@ export class Erc20TransferService {
// 估算 gas // 估算 gas
const gasEstimate = await provider.estimateGas({ const gasEstimate = await provider.estimateGas({
from: this.marketMakerAddress, from: marketMakerAddress,
to: contractAddress, to: contractAddress,
data: transferData, data: transferData,
}); });
@ -715,9 +758,11 @@ export class Erc20TransferService {
const unsignedTxHash = tx.unsignedHash; const unsignedTxHash = tx.unsignedHash;
this.logger.log(`[MM-TRANSFER] Unsigned tx hash: ${unsignedTxHash}`); this.logger.log(`[MM-TRANSFER] Unsigned tx hash: ${unsignedTxHash}`);
// 使用做市商 MPC 钱包签名 // 使用对应的做市商 MPC 钱包签名
this.logger.log(`[MM-TRANSFER] Requesting Market Maker MPC signature...`); this.logger.log(`[MM-TRANSFER] Requesting ${tokenType} Market Maker MPC signature...`);
const signatureHex = await this.mpcSigningClient.signMessageAsMarketMaker(unsignedTxHash); const signatureHex = isEusdt
? await this.mpcSigningClient!.signMessageAsEusdtMarketMaker(unsignedTxHash)
: await this.mpcSigningClient!.signMessageAsFusdtMarketMaker(unsignedTxHash);
this.logger.log(`[MM-TRANSFER] MPC signature obtained: ${signatureHex.slice(0, 20)}...`); this.logger.log(`[MM-TRANSFER] MPC signature obtained: ${signatureHex.slice(0, 20)}...`);
// 解析签名 // 解析签名
@ -733,7 +778,7 @@ export class Erc20TransferService {
const testSig = Signature.from({ r, s, yParity }); const testSig = Signature.from({ r, s, yParity });
const recoveredAddress = recoverAddress(unsignedTxHash, testSig); const recoveredAddress = recoverAddress(unsignedTxHash, testSig);
if (recoveredAddress.toLowerCase() === this.marketMakerAddress.toLowerCase()) { if (recoveredAddress.toLowerCase() === marketMakerAddress.toLowerCase()) {
this.logger.log(`[MM-TRANSFER] Found correct yParity: ${yParity}`); this.logger.log(`[MM-TRANSFER] Found correct yParity: ${yParity}`);
signature = testSig; signature = testSig;
break; break;
@ -786,25 +831,50 @@ export class Erc20TransferService {
} }
/** /**
* * eUSDT
*/ */
async getMarketMakerTokenBalance(chainType: ChainTypeEnum, tokenType: TokenType): Promise<string> { async getEusdtMarketMakerTokenBalance(chainType: ChainTypeEnum): Promise<string> {
const provider = this.providers.get(chainType); const provider = this.providers.get(chainType);
if (!provider) { if (!provider) {
throw new Error(`Provider not configured for chain: ${chainType}`); throw new Error(`Provider not configured for chain: ${chainType}`);
} }
if (!this.marketMakerAddress) { if (!this.eusdtMarketMakerAddress) {
throw new Error('Market Maker wallet address not configured'); throw new Error('eUSDT Market Maker wallet address not configured');
} }
const contractAddress = this.getTokenContract(chainType, tokenType); const contractAddress = this.getTokenContract(chainType, 'EUSDT');
if (!contractAddress) { if (!contractAddress) {
throw new Error(`Token ${tokenType} not configured for chain ${chainType}`); throw new Error(`eUSDT not configured for chain ${chainType}`);
} }
const contract = new Contract(contractAddress, ERC20_TRANSFER_ABI, provider); const contract = new Contract(contractAddress, ERC20_TRANSFER_ABI, provider);
const balance = await contract.balanceOf(this.marketMakerAddress); const balance = await contract.balanceOf(this.eusdtMarketMakerAddress);
const decimals = await contract.decimals();
return formatUnits(balance, decimals);
}
/**
* fUSDT
*/
async getFusdtMarketMakerTokenBalance(chainType: ChainTypeEnum): Promise<string> {
const provider = this.providers.get(chainType);
if (!provider) {
throw new Error(`Provider not configured for chain: ${chainType}`);
}
if (!this.fusdtMarketMakerAddress) {
throw new Error('fUSDT Market Maker wallet address not configured');
}
const contractAddress = this.getTokenContract(chainType, 'FUSDT');
if (!contractAddress) {
throw new Error(`fUSDT not configured for chain ${chainType}`);
}
const contract = new Contract(contractAddress, ERC20_TRANSFER_ABI, provider);
const balance = await contract.balanceOf(this.fusdtMarketMakerAddress);
const decimals = await contract.decimals(); const decimals = await contract.decimals();
return formatUnits(balance, decimals); return formatUnits(balance, decimals);

View File

@ -42,9 +42,12 @@ export class MpcSigningClient implements OnModuleInit {
// C2C Bot 热钱包 // C2C Bot 热钱包
private readonly hotWalletUsername: string; private readonly hotWalletUsername: string;
private readonly hotWalletAddress: string; private readonly hotWalletAddress: string;
// 做市商 MPC 钱包 // eUSDT (积分股) 做市商钱包
private readonly marketMakerUsername: string; private readonly eusdtMarketMakerUsername: string;
private readonly marketMakerAddress: string; private readonly eusdtMarketMakerAddress: string;
// fUSDT (积分值) 做市商钱包
private readonly fusdtMarketMakerUsername: string;
private readonly fusdtMarketMakerAddress: string;
private readonly signingTimeoutMs: number = 300000; // 5 minutes private readonly signingTimeoutMs: number = 300000; // 5 minutes
// 待处理的签名请求回调 Map<sessionId, { resolve, reject, timeout }> // 待处理的签名请求回调 Map<sessionId, { resolve, reject, timeout }>
@ -62,9 +65,12 @@ export class MpcSigningClient implements OnModuleInit {
// C2C Bot 热钱包配置 // C2C Bot 热钱包配置
this.hotWalletUsername = this.configService.get<string>('HOT_WALLET_USERNAME', ''); this.hotWalletUsername = this.configService.get<string>('HOT_WALLET_USERNAME', '');
this.hotWalletAddress = this.configService.get<string>('HOT_WALLET_ADDRESS', ''); this.hotWalletAddress = this.configService.get<string>('HOT_WALLET_ADDRESS', '');
// 做市商 MPC 钱包配置 // eUSDT (积分股) 做市商钱包配置
this.marketMakerUsername = this.configService.get<string>('MARKET_MAKER_MPC_USERNAME', ''); this.eusdtMarketMakerUsername = this.configService.get<string>('EUSDT_MARKET_MAKER_USERNAME', '');
this.marketMakerAddress = this.configService.get<string>('MARKET_MAKER_WALLET_ADDRESS', ''); this.eusdtMarketMakerAddress = this.configService.get<string>('EUSDT_MARKET_MAKER_ADDRESS', '');
// fUSDT (积分值) 做市商钱包配置
this.fusdtMarketMakerUsername = this.configService.get<string>('FUSDT_MARKET_MAKER_USERNAME', '');
this.fusdtMarketMakerAddress = this.configService.get<string>('FUSDT_MARKET_MAKER_ADDRESS', '');
if (!this.hotWalletUsername) { if (!this.hotWalletUsername) {
this.logger.warn('[INIT] HOT_WALLET_USERNAME not configured (C2C Bot disabled)'); this.logger.warn('[INIT] HOT_WALLET_USERNAME not configured (C2C Bot disabled)');
@ -72,15 +78,16 @@ export class MpcSigningClient implements OnModuleInit {
if (!this.hotWalletAddress) { if (!this.hotWalletAddress) {
this.logger.warn('[INIT] HOT_WALLET_ADDRESS not configured (C2C Bot disabled)'); this.logger.warn('[INIT] HOT_WALLET_ADDRESS not configured (C2C Bot disabled)');
} }
if (!this.marketMakerUsername) { if (!this.eusdtMarketMakerUsername || !this.eusdtMarketMakerAddress) {
this.logger.warn('[INIT] MARKET_MAKER_MPC_USERNAME not configured (Market Maker signing disabled)'); this.logger.warn('[INIT] eUSDT Market Maker not configured');
} }
if (!this.marketMakerAddress) { if (!this.fusdtMarketMakerUsername || !this.fusdtMarketMakerAddress) {
this.logger.warn('[INIT] MARKET_MAKER_WALLET_ADDRESS not configured (Market Maker disabled)'); this.logger.warn('[INIT] fUSDT Market Maker not configured');
} }
this.logger.log(`[INIT] C2C Bot Wallet: ${this.hotWalletAddress || '(not configured)'}`); this.logger.log(`[INIT] C2C Bot Wallet: ${this.hotWalletAddress || '(not configured)'}`);
this.logger.log(`[INIT] Market Maker Wallet: ${this.marketMakerAddress || '(not configured)'}`); this.logger.log(`[INIT] eUSDT Market Maker: ${this.eusdtMarketMakerAddress || '(not configured)'}`);
this.logger.log(`[INIT] fUSDT Market Maker: ${this.fusdtMarketMakerAddress || '(not configured)'}`);
this.logger.log(`[INIT] Using Kafka event-driven signing`); this.logger.log(`[INIT] Using Kafka event-driven signing`);
} }
@ -99,10 +106,17 @@ export class MpcSigningClient implements OnModuleInit {
} }
/** /**
* * eUSDT
*/ */
isMarketMakerConfigured(): boolean { isEusdtMarketMakerConfigured(): boolean {
return !!this.marketMakerUsername && !!this.marketMakerAddress; return !!this.eusdtMarketMakerUsername && !!this.eusdtMarketMakerAddress;
}
/**
* fUSDT
*/
isFusdtMarketMakerConfigured(): boolean {
return !!this.fusdtMarketMakerUsername && !!this.fusdtMarketMakerAddress;
} }
/** /**
@ -120,17 +134,31 @@ export class MpcSigningClient implements OnModuleInit {
} }
/** /**
* * eUSDT
*/ */
getMarketMakerAddress(): string { getEusdtMarketMakerAddress(): string {
return this.marketMakerAddress; return this.eusdtMarketMakerAddress;
} }
/** /**
* MPC * eUSDT MPC
*/ */
getMarketMakerUsername(): string { getEusdtMarketMakerUsername(): string {
return this.marketMakerUsername; return this.eusdtMarketMakerUsername;
}
/**
* fUSDT
*/
getFusdtMarketMakerAddress(): string {
return this.fusdtMarketMakerAddress;
}
/**
* fUSDT MPC
*/
getFusdtMarketMakerUsername(): string {
return this.fusdtMarketMakerUsername;
} }
/** /**
@ -147,16 +175,29 @@ export class MpcSigningClient implements OnModuleInit {
} }
/** /**
* 使 * 使 eUSDT
* *
* @param messageHash (hex string with 0x prefix) * @param messageHash (hex string with 0x prefix)
* @returns (hex string) * @returns (hex string)
*/ */
async signMessageAsMarketMaker(messageHash: string): Promise<string> { async signMessageAsEusdtMarketMaker(messageHash: string): Promise<string> {
if (!this.marketMakerUsername) { if (!this.eusdtMarketMakerUsername) {
throw new Error('Market maker MPC username not configured'); throw new Error('eUSDT Market Maker MPC username not configured');
} }
return this.signMessageWithUsername(this.marketMakerUsername, messageHash); return this.signMessageWithUsername(this.eusdtMarketMakerUsername, messageHash);
}
/**
* 使 fUSDT
*
* @param messageHash (hex string with 0x prefix)
* @returns (hex string)
*/
async signMessageAsFusdtMarketMaker(messageHash: string): Promise<string> {
if (!this.fusdtMarketMakerUsername) {
throw new Error('fUSDT Market Maker MPC username not configured');
}
return this.signMessageWithUsername(this.fusdtMarketMakerUsername, messageHash);
} }
/** /**