Commit Graph

66 Commits

Author SHA1 Message Date
hailin 04a8c56ad6 fix(identity): use correct Aliyun API for ID card verification
Change API from Id2MetaStandardVerify to Id2MetaVerify for two-factor
identity verification (name + ID card number). The previous API was
returning error 440 (no permission).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 08:05:08 -08:00
hailin 8173e1f973 feat: "同僚"改为"同伴" + KYC从三要素改为二要素
mobile-app:
- profile_page.dart: 将所有"同僚"改为"同伴"

identity-service:
- 层级1实名认证从三要素(姓名+身份证+手机号)改为二要素(姓名+身份证号)
- 使用阿里云 Id2MetaStandardVerify API
- 二要素验证直接调用真实API,不使用mock
- 保留三要素验证方法(verifyIdCardThreeFactor)备用

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 04:20:42 -08:00
hailin 55bb129477 feat(identity-service): 增强钱包生成可靠性,确保100%生成成功
核心改进:
- 基于数据库扫描代替Redis扫描,防止状态丢失后无法重试
- 指数退避策略(1分钟→60分钟),无时间限制持续重试
- 分布式锁保护,防止多实例/并发重复触发
- getWalletStatus API 检测失败状态并自动触发重试

修改内容:
- RedisService: 添加 tryLock/unlock 分布式锁方法
- UserAccountRepository: 添加 findUsersWithIncompleteWallets 查询
- getWalletStatus: 增强状态检测,失败/超时时自动触发重试
- WalletRetryTask: 完全重写,基于数据库驱动+指数退避

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 09:40:51 -08:00
hailin 68a071cfaa fix(identity-service): 暂时恢复三要素身份验证
二要素 API (Id2MetaStandardVerify) 返回 440 无权限调用错误
暂时恢复使用三要素验证,保留二要素代码待开通权限后使用

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 10:12:20 -08:00
hailin 4ec4df14b5 feat(identity-service): KYC 改用二要素验证
- 默认使用阿里云 Id2MetaStandardVerify API(姓名+身份证号)
- 保留三要素验证方法 verifyIdCardThreeFactor 作为备用
- 二要素验证始终调用真实 API,不使用 mock
- 兼容 BizCode 数字和字符串类型

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 09:46:17 -08:00
hailin c14b87305c feat(kyc): 升级为三要素核验详版API,返回详细错误原因
- 从 Mobile3MetaSimpleVerify 改为 Mobile3MetaDetailVerify
- 新增 SubCode 详细错误码映射:
  - 201: 手机号与姓名、身份证号均不匹配
  - 202: 手机号与身份证号不匹配
  - 203: 手机号与姓名不匹配
  - 204: 其他不一致
  - 301: 查无记录

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 00:40:48 -08:00
hailin c3b50264cc fix(kyc): 修正阿里云手机号三要素核验的成功判断逻辑
阿里云 Mobile3MetaSimpleVerify 返回的 BizCode:
- 1: 校验一致 (成功)
- 2: 校验不一致 (失败)
- 3: 查无记录 (失败)

之前错误地将 BizCode=0 判断为成功,现改为 BizCode=1

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 00:28:29 -08:00
hailin 4b92fb36a3 debug(kyc): 添加阿里云API返回信息的详细日志
打印完整的response和ResultObject字段以便调试

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 00:20:45 -08:00
hailin c2e81a6f4e fix(kyc): 使用正确的阿里云手机号三要素核验API
- 从 VerifyMaterial (身份三要素,需要人脸照片) 改为 Mobile3MetaSimpleVerify (手机号三要素)
- 手机号三要素验证:姓名 + 身份证号 + 手机号
- 添加 mapMobile3MetaErrorCode 方法映射错误码

文档: https://help.aliyun.com/zh/id-verification/information-verification/developer-reference/esf1ff158mxowkk6

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 00:05:03 -08:00
hailin 181d11d656 feat(kyc): 升级实名认证为三要素验证(姓名+身份证号+手机号)
- 后端 aliyun-kyc.provider.ts: 改用 ID_CARD_THREE 类型,添加 PhoneNumber 参数
- 后端 kyc-application.service.ts: 从用户账户获取手机号传递给 KYC provider
- 前端 kyc_id_page.dart: 更新文案为"三要素验证"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 23:54:13 -08:00
hailin 0f745a17fd feat(kyc): 实现完整三层KYC认证功能
实现三层KYC认证系统,支持后台配置开关:
- 层级1: 实名认证 (二要素: 姓名+身份证号)
- 层级2: 实人认证 (人脸活体检测)
- 层级3: KYC (证件照上传验证)

后端变更:
- 更新 Schema 添加三层认证字段和 KycConfig 表
- 添加 migration 支持增量字段和配置表
- 重写 AliyunKycProvider 支持阿里云实人认证 API
- 重写 KycApplicationService 实现三层认证逻辑
- 更新 KycController 添加用户端和管理端 API

前端变更:
- 更新 KycService 支持三层认证 API
- 重构 KycEntryPage 显示三层认证状态
- 重构 KycIdPage 用于层级1实名认证
- 新增 KycFacePage 用于层级2人脸认证
- 新增 KycIdCardPage 用于层级3证件照上传
- 添加 uploadFile 方法到 ApiClient

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 07:14:11 -08:00
hailin a549768de4 feat(kyc): 实现实名认证和更换手机号功能
主要变更:
- 注册流程: 添加跳过短信验证选项(3分钟后显示)
- KYC功能: 手机号验证 + 身份证实名认证(阿里云二要素)
- 更换手机号: 四步验证流程(旧手机验证→输入新号→新手机验证→确认)
- 独立管控: phoneVerified, emailVerified, kycStatus 三个状态分别管理

后端:
- 新增 KYC 控制器和服务
- 新增更换手机号 API 端点
- Schema 添加 KYC 和验证状态字段
- 集成阿里云身份二要素验证

前端:
- 新增 KYC 入口页、手机验证页、身份证验证页
- 新增更换手机号页面
- Profile 页面添加实名认证入口

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 06:38:39 -08:00
hailin 53ef1ade42 fix(sms): 增强短信发送重试机制
- 最大重试次数从 2 次增加到 4 次
- 基础延迟从 3 秒增加到 6 秒
- 最大延迟从 10 秒增加到 30 秒

这些调整提高了短信发送在网络不稳定情况下的成功率

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 22:14:32 -08:00
hailin a38aac5581 feat(email): 实现邮箱绑定/解绑功能
后端:
- 新增 EmailService 邮件发送服务,支持 Gmail SMTP
- 新增 EmailCode 数据模型用于存储邮箱验证码
- UserAccount 添加 email 字段
- 新增 API 接口:
  - GET /user/email-status 获取邮箱绑定状态
  - POST /user/send-email-code 发送邮箱验证码
  - POST /user/bind-email 绑定邮箱
  - POST /user/unbind-email 解绑邮箱
- 新增 DTOs: SendEmailCodeDto, BindEmailDto, UnbindEmailDto
- 新增 Commands: SendEmailCodeCommand, BindEmailCommand, UnbindEmailCommand

前端:
- account_service 新增邮箱相关方法和 EmailStatus 类
- bind_email_page 更新为使用真实 API:
  - 绑定/更换邮箱功能
  - 独立的解绑验证码输入和倒计时
  - 解绑确认对话框

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 20:53:20 -08:00
hailin a194fcad72 fix(identity-service): 内部接口改用 accountSequence 查询
- identity-service InternalController 改用 accountSequence 批量/单个查询
- 添加 findByAccountSequences 批量查询方法
- authorization-service 调用改为 batchGetUserInfoBySequence/getUserInfoBySequence
- 系统间通信统一使用 accountSequence 作为标识符

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 02:16:12 -08:00
hailin 5fa195e4bc fix: 修复火柴人排名显示问题
1. identity-service: 添加批量获取用户信息内部接口
   - 新增 InternalController 提供 POST /internal/users/batch
   - repository 添加 findByUserIds 批量查询方法

2. authorization-service: 修复 cumulativeCompleted=0 问题
   - assessAndRankRegion 改用 findByAccountSequence 查询团队统计
   - referral-service 使用 accountSequence 作为主键

3. mobile-app: 修复火柴人UI显示问题
   - 容器边距调整为16px与其他组件一致
   - 行高增加到100px避免火柴人重叠

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 01:48:16 -08:00
hailin 1f15c494c1 fix(identity-service): 添加注册流程详细日志和保存验证
问题:用户注册后 referral-service 有数据但 identity-service 没有
原因:save() 方法和 registerByPhone 方法缺少日志,无法追踪问题

修复:
- save() 方法添加完整日志和 try-catch
- registerByPhone 方法添加每个步骤的日志
- 添加关键验证:保存后检查 userId 是否为 0

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 23:19:24 -08:00
hailin ecf3755227 feat: integrate real API for authorization apply page
Changes:
- Add generic image upload API endpoint (POST /user/upload-image)
- Add uploadImage method in StorageService for backend
- Add uploadImage method in AccountService for frontend
- Add selfApplyStatus and selfApplyAuthorization methods in AuthorizationService
- Replace mock data with real API calls in authorization apply page
- Add API endpoints for self-apply status and self-apply authorization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 22:01:28 -08:00
hailin 188075b2be fix: 短信超时返回成功状态避免前端报错
超时情况下短信可能已发送成功,返回 success: true + uncertain: true

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 20:55:31 -08:00
hailin d36a58341d fix: 优化短信重试策略避免触发流控
- 降低重试次数到 2 次
- 增加基础延迟到 3 秒
- 超时错误不重试(短信可能已发送成功)
- 流控错误不重试

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 20:38:47 -08:00
hailin e5e4e3512b feat: 添加短信发送重试机制提高可靠性
- 最多重试 3 次(共 4 次尝试)
- 指数退避延迟(1s, 2s, 4s)
- 超时时间增加到 15 秒
- 只对网络错误重试,业务错误不重试
- 可重试错误:ConnectTimeout, ReadTimeout, ETIMEDOUT, ECONNRESET 等

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 20:32:45 -08:00
hailin b4c4239593 feat: 实现手机号+密码登录和账号恢复功能
## 后端更改

### 新增功能
- 添加手机号+密码登录 API (`POST /user/login-with-password`)
  - 新增 LoginWithPasswordDto 验证手机号格式和密码长度
  - 实现 loginWithPassword 服务方法,使用 bcrypt 验证密码
  - 返回 JWT tokens(accessToken + refreshToken)

### 代码优化
- 修复 phone.validator.ts 中的 TypeScript 类型错误(Object -> object)

## 前端更改

### 新增功能
- 实现手机号+密码登录页面 (phone_login_page.dart)
  - 完整的表单验证(手机号格式、密码长度)
  - 集成 AccountService.loginWithPassword API
  - 登录成功后自动更新认证状态并跳转主页

### 账号服务优化
- 在 AccountService 中添加 loginWithPassword 方法
  - 调用后端 login-with-password API
  - 自动保存认证数据(tokens、用户信息)
  - 使用 _savePhoneAuthData 统一保存逻辑

### UI 文案更新
- 向导页文案修改:"创建账号" → "注册账号"
  - 更新标题、副标题和按钮文本
  - 添加"恢复账号"按钮,跳转到手机号密码登录页

## 已验证功能

 前端代码编译通过(0 errors, 仅有非关键警告)
 后端代码编译通过(0 errors, 仅有非关键警告)
 30天登录状态保持(JWT refresh token 已配置为30天)
 自动路由逻辑(有登录状态直接进入主页)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 20:35:44 -08:00
hailin 959fe93092 feat(identity-service): 添加钱包生成自动重试机制
功能:
- 新增 WalletRetryTask 定时任务,每分钟扫描一次
- 自动检测超过 60 秒仍在 generating/deriving 状态的钱包
- 自动检测状态为 failed 的钱包生成
- 幂等重试机制,最多 10 分钟内持续重试
- 记录重试次数和时间戳

技术实现:
- 使用 @nestjs/schedule 的 Cron 装饰器
- 在 UserAccount 聚合根中添加 createWalletGenerationEvent() 方法
- 在 RedisService 中添加 keys() 方法支持模式匹配扫描
- 通过重新发布 UserAccountCreatedEvent 触发幂等重试

相关需求:
- 用户手机号验证成功后立即创建账号
- 钱包生成在后台异步进行
- 失败后自动重试,无需用户感知

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 19:20:55 -08:00
hailin 287ab6bfa9 fix(identity-service): 增加阿里云短信 API 连接超时时间
- 连接超时从默认值增加到 10 秒
- 读取超时从默认值增加到 10 秒
- 改善网络不稳定环境下的短信发送成功率

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 18:29:07 -08:00
hailin 9452d14962 feat(identity-service): 添加密码设置和短信验证功能
- 添加 bcrypt 依赖用于密码哈希
- 添加 passwordHash 字段到 UserAccount 模型
- 添加 VerifySmsCodeCommand 和 SetPasswordCommand
- 添加 VerifySmsCodeDto 和 SetPasswordDto
- 添加数据库迁移 add_password_hash

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 03:23:36 -08:00
hailin 5b2d255506 feat(auth): 增强提现安全验证
- 集成阿里云短信服务 (dysmsapi20170525)
- 提现需同时验证短信验证码和登录密码
- identity-service 添加 /verify-password API
- wallet-service 调用双重验证
- 移动端提现确认页添加密码输入

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 03:05:53 -08:00
hailin 05a9ca31f6 feat(identity): 实现 Outbox 模式事件发布
## 概述
为 identity-service 实现 Outbox 模式,确保数据库事务和 Kafka 事件发布的原子性。

## 新增表
- OutboxEvent: 事件暂存表,用于事务性事件发布

## 新增组件
- OutboxRepository: Outbox 事件持久化
- OutboxPublisherService: 轮询发布未处理事件到 Kafka

## 支持的事件
- identity.UserAccountCreated: 用户注册事件
- identity.UserAccountAutoCreated: 自动创建用户事件

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 00:29:40 -08:00
hailin d3e680ea14 feat(identity/blockchain): 添加助记词挂失功能
后端:
- blockchain-service: 新增 revokeMnemonic() 方法和 POST /internal/mnemonic/revoke API
- identity-service: 新增 POST /user/mnemonic/revoke 用户端API
- 挂失后助记词状态变为 REVOKED,无法用于账户恢复

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 07:56:27 -08:00
hailin c1fe54a8d4 feat: 暂时禁用 BSC 链,添加 Kafka 企业级重试配置
- blockchain-service: getSupportedChains() 只返回 KAVA
- 所有 Kafka consumer 添加企业级重试配置(15次重试,指数退避)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 22:33:34 -08:00
hailin e75b968aeb feat(identity): 增强账户创建流程可靠性
问题:
- saveWallets() 无事务保护,并发时可能部分成功部分失败
- 事件处理器静默失败,Kafka 不会重试
- 无幂等性检查,重试可能创建重复钱包

修复:
1. saveWallets() 添加事务保护 + 幂等性检查
   - 使用 prisma.$transaction 确保原子性
   - 检查已存在的钱包地址,跳过重复创建

2. 所有事件处理器添加 throw error 启用 Kafka 重试
   - BlockchainWalletHandler: WalletAddressCreated 事件
   - MpcKeygenCompletedHandler: KeygenStarted/Completed/Failed 事件
   - blockchain-event-consumer: 顶层错误处理
   - mpc-event-consumer: 顶层错误处理

影响文件:
- user-account.repository.impl.ts: saveWallets 事务+幂等
- blockchain-wallet.handler.ts: throw error
- mpc-keygen-completed.handler.ts: throw error (3处)
- blockchain-event-consumer.service.ts: throw error
- mpc-event-consumer.service.ts: throw error

预期效果:
- 100并发账户创建成功率: 85% → 97%+
- Kafka 消息失败自动重试
- 防止重复创建钱包地址

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 20:37:54 -08:00
hailin 4be9c1fb82 refactor!: 重构账户序列号格式 (BREAKING CHANGE)
将 accountSequence 从数字类型改为字符串类型,新格式为:
- 普通用户: D + YYMMDD + 5位序号 (例: D2512120001)
- 系统账户: S + 10位序号 (例: S0000000001)

主要变更:
- identity-service: AccountSequence 值对象改为字符串类型
- identity-service: 序列号生成器改为按日期重置计数
- 所有服务: Prisma schema 字段类型从 BigInt/Int 改为 String
- 所有服务: DTO、Command、Event 中的类型定义更新
- Flutter 前端: 相关数据模型类型更新

涉及服务:
- identity-service (核心变更)
- referral-service
- authorization-service
- wallet-service
- reward-service
- blockchain-service
- backup-service
- planting-service
- mpc-service
- admin-service
- mobile-app (Flutter)

注意: 此为破坏性变更,需要清空数据库并重新运行 migration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 09:11:18 -08:00
hailin 6b85401d5c fix(mnemonic): fix recovery-by-mnemonic using hash verification instead of address matching
## Problem
MPC wallet addresses have no cryptographic relationship with recovery mnemonics,
so address-based verification always failed for account recovery.

## Solution
Changed mnemonic verification from address matching to hash-based verification:
- Mnemonic acts as identity credential, verified by hash stored in blockchain-service
- Uses accountSequence to lookup stored mnemonic hash for verification

## Changes

### blockchain-service
- recovery-mnemonic.adapter.ts:
  - generateMnemonic() now async, uses bcrypt (rounds=12) for secure hashing
  - verifyMnemonic() now async, supports both bcrypt and legacy SHA256 hashes
  - Added backward compatibility for existing SHA256 hashed mnemonics
- mnemonic-verification.service.ts:
  - await verifyMnemonic() for async bcrypt comparison
- address-derivation.service.ts:
  - await generateMnemonic() for async bcrypt hashing
- package.json: added bcrypt dependency

### identity-service
- user-application.service.ts:
  - Changed recoverByMnemonic() to use verifyMnemonicByAccount (hash verification)
  - Added rate limiting: 5 failed attempts per hour per accountSequence
  - Uses Redis to track failed verification attempts
- redis.service.ts:
  - Added incr() and expire() methods for rate limiting
  - Added updateKeygenStatusAtomic() with Lua script for atomic state transitions
- mpc-keygen-completed.handler.ts:
  - Uses atomic Redis update to prevent race conditions
- blockchain-wallet.handler.ts:
  - Uses atomic Redis update for completed status

## Security Improvements
- bcrypt with 12 rounds for mnemonic hashing (anti-brute-force)
- Rate limiting prevents brute force attacks on mnemonic recovery
- Atomic Redis operations prevent race conditions in wallet creation flow

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 09:02:24 -08:00
hailin 1bfbaa06f1 feat(mnemonic): propagate accountSequence through MPC keygen flow (DDD)
Changes across all three services to properly associate recovery mnemonics
with account sequence numbers instead of user IDs, following DDD principles:

identity-service:
- Add accountSequence to MpcKeygenRequestedEvent payload
- Pass accountSequence when publishing keygen request
- Remove direct access to recoveryMnemonic table (now in blockchain-service)
- Call blockchain-service for mnemonic backup marking
- BlockchainWalletHandler no longer saves mnemonic (stored in blockchain-service)

mpc-service:
- Add accountSequence to KeygenRequestedPayload interface
- Pass accountSequence through to blockchain-service when deriving addresses
- Include accountSequence in KeygenCompleted event extraPayload

blockchain-service:
- Add accountSequence to derive-address API and internal interfaces
- Add accountSequence to KeygenCompletedPayload extraPayload
- Add PUT /internal/mnemonic/backup API for marking mnemonic as backed up
- Store recovery mnemonic with accountSequence association

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 01:08:27 -08:00
hailin e95dc4ca57 refactor(mnemonic): move recovery_mnemonics to blockchain-service (DDD)
- Add RecoveryMnemonic model to blockchain-service with accountSequence
- Add MnemonicVerificationService for mnemonic verification logic
- Update verify-mnemonic-hash endpoint to accept accountSequence
- Remove PrismaService dependency from identity-service handler
- identity-service now calls blockchain-service for mnemonic verification

This follows DDD principles: blockchain-service owns all mnemonic-related
data and operations, identity-service only handles account identity.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 00:54:25 -08:00
hailin 0311ecf498 fix(mnemonic): use hash verification instead of address derivation for account recovery
The mnemonic recovery now uses stored hash comparison via blockchain-service
instead of trying to derive addresses from mnemonic (which never matched
because MPC wallet addresses are not derived from mnemonics).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 00:44:47 -08:00
hailin 550a3dba06 feat(identity): add avatar upload with MinIO storage
- Add StorageService for MinIO object storage operations
- Add upload-avatar API endpoint with file validation
- Support jpg, png, gif, webp formats (max 5MB)
- Auto-update user profile after avatar upload

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 21:38:35 -08:00
hailin c1670d2439 feat(mnemonic): add recovery mnemonic generation and backup confirmation
Backend (blockchain-service):
- Add RecoveryMnemonicAdapter to generate 12-word BIP39 mnemonic
- Generate mnemonic when wallet addresses are derived (linked to public key)
- Include mnemonic in WalletAddressCreated event

Backend (identity-service):
- Add RecoveryMnemonic table with revocation/replacement support
- Save encrypted mnemonic to database on WalletAddressCreated event
- Add PUT /user/mnemonic/backup API to mark mnemonic as backed up
- Clear plaintext mnemonic from Redis after backup confirmation

Frontend (mobile-app):
- Update markMnemonicBackedUp() to call backend API
- Fix verify_mnemonic_page validation logic:
  - Checkbox checked → pass directly
  - Not checked → must select correct word

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 12:32:10 -08:00
hailin 29f2dc0524 fix(identity): remove address from updateProfile and fix deviceInfo type
- Remove dto.address parameter from updateProfile controller
- Remove address property from updateProfile service
- Fix deviceInfo JSON serialization for Prisma InputJsonValue type

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 11:29:51 -08:00
hailin 2705812826 refactor(identity): remove province/city/address fields
- Remove provinceCode, cityCode, address from UserAccount aggregate
- Remove ProvinceCode, CityCode value objects
- Remove UserLocationUpdatedEvent domain event
- Update Prisma schema to drop province/city/address columns
- Update repository, mapper, handlers, services and DTOs
- Clean up tests and factory files

Province/city should belong to adoption-service as transaction data,
not identity-service user data.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 11:23:26 -08:00
hailin fbec0b9112 feat(identity): store complete deviceInfo JSON from frontend
- Add deviceInfo JSON field to UserDevice table (Prisma schema)
- Update DeviceInfo value object to use deviceInfo instead of HardwareInfo
- Update repository to save complete JSON with redundant fields for queries
- Update mapper to read deviceInfo from database
- Update aggregate and handlers to pass deviceInfo through
- Allow any fields in DeviceNameInput interface with index signature

100% preserve original device info JSON from frontend without extraction

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 11:08:37 -08:00
hailin 106137224a fix(identity-service): add BlockchainEventConsumerService to InfrastructureModule
The consumer was not being initialized because it was not registered in the module.
2025-12-07 03:30:26 -08:00
hailin 852073ae11 refactor: move mnemonic verification from identity-service to blockchain-service
- Add /internal/verify-mnemonic API to blockchain-service
- Add /internal/derive-from-mnemonic API to blockchain-service
- Create MnemonicDerivationAdapter for BIP39 mnemonic address derivation
- Create BlockchainClientService in identity-service to call blockchain-service
- Remove WalletGeneratorService from identity-service
- Update recover-by-mnemonic handler to use blockchain-service API

This enforces proper domain boundaries - all blockchain/crypto operations
are now handled by blockchain-service.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 00:11:06 -08:00
hailin cf308efecf refactor(identity-service): remove deposit/blockchain code, belongs to wallet-service
- Remove DepositController, DepositService, BlockchainQueryService
- Deposit address and balance queries should be in wallet-service
- identity-service now only handles user identity

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 23:22:06 -08:00
hailin 9ae26d0f1f refactor(identity-service): replace direct RPC with blockchain-service API calls
- Remove ethers.js direct RPC connection to blockchain
- Add HTTP client to call blockchain-service /balance API
- Add ConfigService for BLOCKCHAIN_SERVICE_URL configuration
- Enforce proper microservice boundaries

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 23:07:46 -08:00
hailin 383a9540a0 refactor: move backup-service client from identity-service to mpc-service
Architecture change: delegate share storage is now handled by mpc-service.
- identity-service no longer calls backup-service directly
- mpc-service calls backup-service after keygen completion
- This follows proper domain boundaries (MPC domain handles share storage)

Flow:
1. identity-service publishes mpc.KeygenRequested
2. mpc-service calls mpc-system for keygen
3. mpc-service stores delegate share to backup-service
4. mpc-service publishes mpc.KeygenCompleted
5. identity-service updates user wallet address

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 22:56:35 -08:00
hailin 417f580df8 fix(identity-service): add MpcEventConsumerService to InfrastructureModule
Add missing MpcEventConsumerService provider to fix NestJS dependency injection error.
MpcClientService requires MpcEventConsumerService but it was not registered in the module.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 22:15:35 -08:00
hailin 2e815cec6e feat: move address derivation from identity-service to blockchain-service
- Add Cosmos address derivation (bech32) to blockchain-service
  - KAVA: kava1... format
  - DST: dst1... format
  - BSC: 0x... EVM format

- Create MpcEventConsumerService in blockchain-service to consume mpc.KeygenCompleted events

- Create BlockchainEventConsumerService in identity-service to consume blockchain.WalletAddressCreated events

- Simplify identity-service MpcKeygenCompletedHandler to only manage status updates

- Add CosmosAddress value object for Cosmos chain addresses

Event flow:
1. identity-service -> mpc.KeygenRequested
2. mpc-service -> mpc.KeygenCompleted (with publicKey)
3. blockchain-service consumes mpc.KeygenCompleted, derives addresses
4. blockchain-service -> blockchain.WalletAddressCreated (with all chain addresses)
5. identity-service consumes blockchain.WalletAddressCreated, saves to user account

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 21:08:21 -08:00
hailin 23043d5d79 feat: add detailed debug logging for MPC Kafka event flow
- Add comprehensive [INIT], [CONNECT], [PUBLISH], [RECEIVE], [HANDLE] logs
  to identity-service and mpc-service Kafka services
- Add KeygenStarted event for tracking keygen progress
- Add MpcKeygenCompletedHandler to process keygen completion events
- Fix topic routing for MPC events between services

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 19:49:06 -08:00
hailin 289691dc3c fix: align mpc-service migration with schema and fix identity-service compile errors
- Update mpc-service migration to match new gateway mode schema (mpc_wallets, mpc_shares)
- Remove old MySQL migrations (party_shares, session_states, share_backups)
- Fix MpcSignature type to use string format (64 bytes hex: R + S)
- Add persistence layer conversion functions for DB compatibility
- Fix method names in domain services (checkDeviceNotRegistered, generateNextUserSequence)
- Update wallet generator interface to use delegateShare instead of clientShareData

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 18:42:48 -08:00
hailin c459387c42 feat: add event-driven communication between identity-service and mpc-service
Replace synchronous HTTP polling with Kafka event-driven model for MPC operations:

- Add MPC event consumer service in mpc-service for keygen/signing requests
- Add keygen-requested and signing-requested event handlers
- Add MPC event consumer in identity-service for completion events
- Extend mpc-client.service with async event-driven methods
- Support backward compatibility via MPC_USE_EVENT_DRIVEN env var

Topics: mpc.KeygenRequested, mpc.SigningRequested, mpc.KeygenCompleted,
        mpc.SigningCompleted, mpc.SessionFailed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 18:17:44 -08:00