Commit Graph

36 Commits

Author SHA1 Message Date
hailin 8532bf6945 fix(blockchain): use amountFormatted to rebuild TokenAmount from DB
Previously used amount (raw) with hardcoded 18 decimals, which caused
incorrect formatting for USDT (6 decimals). Now uses amountFormatted
which is already correctly formatted during deposit detection.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 12:22:32 -08:00
hailin db3e0ba1bd fix(blockchain): fix deposit stuck in CONFIRMING status
The updateConfirmations logic only checked for DETECTED status
when confirming, so deposits that transitioned to CONFIRMING
would never be confirmed even with enough confirmations.

Changed condition to accept both DETECTED and CONFIRMING status.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 12:19:29 -08:00
hailin 5e670e64b3 fix(blockchain): read token decimals from contract for deposit detection
Previously decimals were hardcoded to 18, causing incorrect amount parsing
for USDT which uses 6 decimals. Now reads decimals() from ERC20 contract
when processing deposits.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 11:57:34 -08:00
hailin 12116ff164 feat(blockchain): add deposit repair service and controller
Add internal APIs to diagnose and repair historical deposit issues:
- GET /internal/deposit-repair/diagnose - Query unnotified deposits
- POST /internal/deposit-repair/repair/:depositId - Repair single deposit
- POST /internal/deposit-repair/repair-all - Batch repair all pending deposits
- POST /internal/deposit-repair/reset-failed-outbox - Reset failed outbox events

The repair service creates new outbox events for CONFIRMED deposits
that were never notified to wallet-service.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 02:19:46 -08:00
hailin 49fc68297b fix(blockchain): fix TypeScript compilation errors
- Fix brokers type narrowing issue in deposit-ack-consumer.service.ts
- Add Prisma.InputJsonValue type cast for payload in outbox-event.repository.impl.ts

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 22:11:28 -08:00
hailin 075c9aaa48 feat(blockchain): implement Outbox Pattern for reliable event delivery
Implement Outbox Pattern with consumer ACK to ensure 100% reliable event
delivery between blockchain-service and wallet-service:

blockchain-service:
- Add OutboxEvent model to Prisma schema with status tracking
- Create outbox repository interface and implementation
- Modify deposit-detection.service to write events to outbox
- Add outbox-publisher.service with cron jobs for publishing/retry
- Add deposit-ack-consumer.service to receive ACK from wallet-service
- Add publishRaw method to event-publisher.service

wallet-service:
- Modify deposit-confirmed.handler to send ACK after successful processing
- Add wallet.deposit.credited topic mapping for ACK events

Event flow:
1. Deposit detected → written to outbox (status: PENDING)
2. Outbox publisher sends to Kafka → status: SENT
3. wallet-service processes and sends ACK → status: ACKED
4. Events without ACK are retried with exponential backoff

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 21:47:31 -08:00
hailin 2e6f22e9d8 fix(blockchain): read token decimals from contract instead of hardcoding
The balance display was incorrect because decimals were hardcoded to 18,
but USDT uses 6 decimals. Now reads decimals() from the ERC20 contract.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 06:10:36 -08:00
hailin 001b6501a0 feat(deposit): add deposit balance API and Kafka consumer for deposit events
Blockchain Service:
- Add /api/v1/deposit/balances endpoint to query on-chain USDT balances
- Add JWT authentication (passport, passport-jwt)
- Add JwtStrategy, JwtAuthGuard, Public decorator

Wallet Service:
- Add Kafka consumer for blockchain.deposits topic
- Add DepositConfirmedHandler to process deposit events and update wallet balance

Infrastructure:
- Add JWT_SECRET env var to blockchain-service in docker-compose.yml
- Add blockchain-service routes to Kong API Gateway

Frontend:
- Fix deposit_service.dart API path (remove duplicate /api prefix)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 02:29:31 -08:00
hailin cf7230457f feat(blockchain-service): KAVA EVM address derivation and system accounts support
## Address Derivation Changes
- Change KAVA from Cosmos bech32 (kava1...) to EVM format (0x...)
- KAVA now uses same EVM address as BSC for deposit monitoring
- Add KAVA to evmChains set for automatic monitoring registration

## Database Schema Updates (Migration: 20241208000000)
- MonitoredAddress: add address_type, account_sequence, system_account_type,
  system_account_id, region_code columns
- DepositTransaction: add address_type, account_sequence, system_account_type,
  system_account_id columns
- Make user_id nullable for system account support
- Create recovery_mnemonics table for account recovery
- Add indexes: idx_account_sequence, idx_type_active, idx_system_account_type,
  idx_deposit_account, and recovery_mnemonics indexes

## New Features
- Withdrawal request handler and Kafka consumer
- Test USDT deployment scripts for KAVA and BSC
- Smart contracts for TestUSDT token

## Infrastructure Updates
- Update mappers for new schema fields
- Update application and infrastructure modules

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 21:45:34 -08:00
hailin 3c2144ad7c feat(deposit): add accountSequence correlation and testnet support
blockchain-service:
- Add accountSequence to monitored_addresses and deposit_transactions
- Support BSC/KAVA testnet via NETWORK_MODE environment variable
- Add chain config service with testnet RPC endpoints
- Update deposit detection with accountSequence propagation

wallet-service:
- Add accountSequence to wallet_accounts and ledger_entries
- Fix JWT strategy to match identity-service token format
- Update deposit handling with accountSequence correlation
- Add repository methods for accountSequence-based queries

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 10:26:01 -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 d983525aa5 fix(wallet): resolve account creation and wallet status query issues
This commit fixes three critical bugs that prevented the wallet creation
flow from completing successfully:

1. mpc-service: extraPayload not included in Kafka messages
   - KeygenCompletedEvent's extraPayload (containing userId, accountSequence,
     username, derivedAddresses) was being set dynamically but not serialized
   - identity-service received events without userId and skipped processing
   - Fix: Merge extraPayload into the published payload in event-publisher

2. mpc-service: KAFKA_BROKERS hostname mismatch
   - mpc-service used KAFKA_BROKERS=rwa-kafka:29092
   - Kafka advertises itself as kafka:29092 in cluster metadata
   - During consumer group rebalance, mpc-service couldn't connect to
     the coordinator address returned by Kafka
   - Fix: Use kafka:29092 to match Kafka's advertised listener

3. blockchain-service: recovery_mnemonics table missing
   - RecoveryMnemonic model exists in schema.prisma but not in migration
   - prisma migrate deploy found no pending migrations
   - Address derivation failed with "table does not exist" error
   - Fix: Use prisma db push instead of migrate deploy to sync schema

Tested: E2E flow now completes successfully
- POST /user/auto-create creates account
- MPC keygen completes and publishes event with extraPayload
- blockchain-service derives addresses and saves recovery mnemonic
- GET /user/wallet returns status=ready with 3 addresses and mnemonic

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 07:57:17 -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 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 667ca1527a feat(blockchain-service): add Prisma migration files
Add initial migration 20241207000000_init with all database tables:
- monitored_addresses
- deposit_transactions
- block_checkpoints
- transaction_requests
- blockchain_events

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 09:08:31 -08:00
hailin 3dc0fb15d8 feat(blockchain-service): add Prisma migration for init schema
- Create migration 20241207000000_init with all 5 tables
- Tables: monitored_addresses, deposit_transactions, block_checkpoints, transaction_requests, blockchain_events
- Mark migration as applied to existing database

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 08:23:14 -08:00
hailin b25a893d37 docs(config): update .env.example files for production deployment
- Update all .env.example files with production topology documentation
- Add network configuration for Server A (119.145.15.38/192.168.1.100) and Server B (192.168.1.111)
- Document service ports and connection URLs for all microservices
- Add architecture diagrams in comments for easy reference
- Include security notes and key generation commands

Files updated:
- backend/services/.env.example (main config)
- backend/services/identity-service/.env.example
- backend/services/mpc-service/.env.example
- backend/services/blockchain-service/.env.example
- backend/mpc-system/.env.example
- backend/api-gateway/.env.example
- backend/infrastructure/.env.example

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 04:55:21 -08:00
hailin 34fc008f9d fix(blockchain-service): add global API prefix and increase healthcheck start_period
- Add app.setGlobalPrefix('api/v1') to main.ts so health endpoint
  is at /api/v1/health consistent with other services
- Increase healthcheck start_period to 60s to allow time for
  Prisma migrations on first startup

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 01:20:35 -08:00
hailin be6abd3034 fix(blockchain-service): standardize Dockerfile with other services
- Use node:20-slim instead of alpine for OpenSSL compatibility
- Add startup script with prisma migrate/push
- Increase healthcheck start-period to 60s
- Add non-root user for security

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 01:17:55 -08:00
hailin 1125dd98ef fix(blockchain-service): auto-create database and run migrations on startup
- Add rwa_blockchain to init-databases.sh script
- Change Dockerfile CMD to run prisma db push before starting app

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 01:14:50 -08:00
hailin e20e3cb7af fix(blockchain-service): add openssl and curl for Prisma and healthcheck 2025-12-07 01:09:25 -08:00
hailin 9eb2d5a206 fix(blockchain-service): import DomainModule for ConfirmationPolicyService 2025-12-07 01:06:45 -08:00
hailin dba9d16074 . 2025-12-07 00:40:19 -08:00
hailin 6451cd6fc3 refactor: unify docker-compose configs to use shared infrastructure
All microservices now use the shared rwa-network and connect to:
- rwa-postgres: Shared PostgreSQL database server
- rwa-redis: Shared Redis cache
- rwa-kafka: Shared Kafka message broker

Each service's docker-compose.yml now only defines the application
container and uses `networks: external: true` to connect to the
shared infrastructure defined in the root docker-compose.yml.

This prevents duplicate infrastructure containers and ensures all
services can communicate via Kafka and share the same Redis/PostgreSQL.

Services updated:
- admin-service
- backup-service
- blockchain-service
- identity-service
- leaderboard-service
- mpc-service
- presence-service

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 00:35:56 -08:00
hailin ce281b0657 fix(blockchain-service): install @scure/bip39 dependency
Add @scure/bip39 package for mnemonic-based address derivation.
Package.json already had the dependency listed but node_modules was missing it.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 00:25:27 -08:00
hailin bbd8a701a8 fix(blockchain-service): add @scure/bip39 dependency 2025-12-07 00:20:49 -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 39804aa981 fix(mobile-app): update share link domain to rwaapi.szaiai.com
Changed invite share URLs from rwa-durian.app to rwaapi.szaiai.com

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 21:15:55 -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 50388c1115 feat(blockchain-service): implement complete blockchain service with DDD + Hexagonal architecture
- Domain layer: ChainType, EvmAddress, TxHash, TokenAmount, BlockNumber value objects
- Domain events: DepositDetected, DepositConfirmed, WalletAddressCreated, TransactionBroadcasted
- Aggregates: DepositTransaction, MonitoredAddress, TransactionRequest
- Infrastructure: Prisma ORM, Redis cache, Kafka messaging, EVM blockchain adapters
- Application services: AddressDerivation, DepositDetection, BalanceQuery
- API: Health, Balance, Internal controllers with Swagger documentation
- Deployment: Docker, docker-compose, deploy.sh, health-check scripts

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 20:54:58 -08:00
hailin 6150617c14 docs: update blockchain-service guide with address derivation responsibilities
- Add public key → address derivation as primary responsibility
- Add AddressDerivationAdapter for EVM/Cosmos address derivation
- Add WalletAddressCreated event definition
- Add MPC event consumption (mpc.KeygenCompleted)
- Add MpcKeygenCompletedHandler for processing keygen events
- Add section 17: MPC integration event flow with diagrams
- Update document version to 1.2.0

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 20:02:50 -08:00
hailin 747e4ae8ef refactor(mpc-system): migrate to party-driven architecture with PartyID-based routing
- Remove Address field from PartyEndpoint (parties connect to router themselves)
- Update K8s Discovery to only manage PartyID and Role labels
- Add Party registration and SessionEvent protobuf definitions
- Implement PartyRegistry and SessionEventBroadcaster domain logic
- Add RegisterParty and SubscribeSessionEvents gRPC handlers
- Prepare infrastructure for party-driven MPC coordination

This is the first phase of migrating from coordinator-driven to party-driven
architecture following international MPC system design patterns.
2025-12-05 08:11:28 -08:00
Developer cd4fba96ed docs(blockchain-service): 完善架构设计以兼容其他微服务
- 添加 modules/ 分层模块文件结构 (api/application/domain/infrastructure)
- 抽取 AggregateRoot 聚合根基类,统一领域事件管理
- 补充 BlockNumber、TxHash 值对象的完整定义
- 添加值对象导出索引文件
- 新增第16章架构兼容性说明:
  - 与其他服务的架构对比表
  - 依赖倒置原则和六边形架构端口适配器说明
  - 命名约定规范
  - Symbol Token 注入规范
- 更新文档版本至 1.1.0

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 20:44:24 -08:00
Developer 84d619edf9 docs(blockchain-service): 添加区块链服务开发指南
- 定义 blockchain-service 领域边界和职责
- 设计 DDD + 六边形架构目录结构
- 设计 Prisma 数据模型 (MonitoredAddress, DepositTransaction, BlockCheckpoint, TransactionRequest)
- 设计领域层 (聚合根、值对象、领域事件、仓储接口)
- 设计基础设施层 (EVM Provider、事件监听器、区块扫描器、地址缓存)
- 设计应用层 (充值检测服务、余额查询服务)
- 定义 Kafka 事件和消费者
- 配置 Docker 部署和 Kong 路由
- 制定从 identity-service 迁移计划

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 20:23:56 -08:00