- 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>
- Add docker-compose.yml for MinIO with auto-initialization
- Add deploy.sh script with comprehensive management commands
- Add nginx reverse proxy configuration for S3 API and console
- Configure default buckets: avatars, documents, resources, backups
- Add CDN caching support for public resources
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
- 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>
- Change avatar_url column from VARCHAR(500) to TEXT
- Remove province_code, city_code, address columns from user_accounts
- Remove idx_province_city index
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- 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>
- 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>
- 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>
- Convert Windows CRLF line endings to Unix LF for all deploy.sh files
- Add executable permission to all deploy.sh scripts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- 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>
- Increase sessionTimeout from 30s to 5 minutes
- Increase heartbeatInterval from 3s to 10s
- Add rebalanceTimeout of 5 minutes
- This prevents consumer from being kicked out during long MPC keygen operations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add BlockchainEventConsumerService to InfrastructureModule
- Add BlockchainWalletHandler and MpcKeygenCompletedHandler to ApplicationModule
- Inject event handlers into UserApplicationService to force NestJS initialization
- This ensures onModuleInit is called for event handlers, enabling Kafka event consumption
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
blockchain-service uses global API prefix, need to include it in URLs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
mpc-account-service expects JWT Bearer tokens, not X-API-Key header.
Added JWT token generation and use MPC_JWT_SECRET env var.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
When mpc-service joins mpc-system network, 'postgres' resolves to mpc-postgres.
Use explicit names (rwa-postgres, rwa-redis, rwa-kafka) to avoid conflicts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Changed MPC URLs from 192.168.1.111 to Docker internal names
- Added mpc-system_mpc-network to mpc-service for cross-network communication
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed from MPC_SYSTEM_URL to MPC_ACCOUNT_SERVICE_URL to match docker-compose config.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Dynamic imports with path aliases (@/domain/events) don't work at runtime.
Changed to static import to fix module resolution error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
SVG avatars can be up to 745+ characters, exceeding the previous 500 char limit.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- 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>
- 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>
- 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>
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>
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>
- 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>
Docker compose healthcheck was using wget which is not installed in the
node:20-slim image. Changed to use curl and corrected endpoint path.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add BlockchainClientService to call blockchain-service /internal/derive-address
- Call derive addresses after keygen completes with MPC public key
- Include derived addresses (BSC, KAVA, DST) in keygen completed event
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 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>
- 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>
The InfrastructureModule was defined inline in app.module.ts, not using
the separate infrastructure.module.ts file. Added MpcEventConsumerService
to the inline module definition.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
Fix bash interpreter error caused by Windows-style CRLF line endings
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.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>
- 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>
- 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>
- Add ioredis dependency for Redis connectivity
- Create Redis service and module with DB 1 configuration
- Implement WalletCacheService for wallet data caching (60s TTL)
- Integrate cache-aside pattern in getMyWallet query
- Add cache invalidation on all wallet mutations:
- handleDeposit, deductForPlanting, addRewards
- claimRewards, settleRewards
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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>
Frontend (account_service.dart):
- Use Android ID instead of random UUID for deviceId
- Add DeviceHardwareInfo class with full hardware details
- Remove provinceCode/cityCode from CreateAccountRequest
- Simplify to: deviceId (required), deviceName (optional JSON), inviterReferralCode (optional)
Backend (identity-service):
- Rename validateDeviceId() to checkDeviceNotRegistered() for clarity
- Rename generateNext() to generateNextUserSequence() for semantics
- Update error message: "该设备已创建过账户"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add modular infrastructure stack with:
- Consul: service discovery and configuration center
- Jaeger: distributed tracing
- Loki + Promtail: log aggregation
- Prometheus: metrics collection with alert rules
- Grafana: unified visualization dashboard
All components are optional and can be enabled on-demand using Docker profiles.
No changes required to existing microservices.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add MPCController with keygen and sign endpoints
- Add MPCCoordinatorService to coordinate with mpc-system
- Add MpcWallet, MpcShare, MpcSession entities for data storage
- Update identity-service mpc-client to call mpc-service
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When signing with a subset of parties (e.g., party-1 and party-3 in 2-of-3),
the TSS library creates a sorted array of party IDs. Messages contain the
original keygen party index, but we need to map it to the sorted array index.
This fixes the 'invalid FromPartyIndex' error when signing with non-consecutive
party indices.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add PartyIndex field to protobuf ParticipantInfo message
- Pass original PartyIndex from account shares to session coordinator
- Use original PartyIndex instead of loop variable when creating participants
- This fixes TSS signing failures when non-consecutive parties are selected
Wait 500ms after subscribing to messages to ensure all parties have
completed subscription before starting TSS protocol. This prevents
broadcast messages from being lost when some parties haven't subscribed yet.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add logging at key points to trace keygen_session_id flow:
- Account Handler: log keygen_session_id when creating signing session
- Session Coordinator: log keygen_session_id in CreateSession and JoinSession
- Message Router: log keygen_session_id when proxying JoinSession
- Server Party: log keygen_session_id when joining session
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
For sign sessions, this column stores the reference to the keygen session
whose key shares should be used for signing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Regenerate protobuf Go code with KeygenSessionId fields
- Session Coordinator correctly parses, stores, and returns keygen_session_id
- Message Router Client parses keygen_session_id in JoinSession response
- participate_signing.go uses keygen_session_id for precise share lookup
- Database schema already includes keygen_session_id column
This fixes the signing issue where wrong keyshares were loaded for multi-account scenarios.
- Add keygen_session_id field to CreateSessionRequest and SessionInfo protobuf
- Modify CreateSigningSessionAuto to accept and pass keygenSessionID
- Update Account Handler to pass account's keygen_session_id when creating signing session
- This enables parties to load the correct keyshare by session ID
TSS threshold semantics: for threshold parameter t, the required number of signers is t+1.
For 2-of-3 with t=2, we need 2+1=3 signers (all parties must participate).
Previous error: 't+1=3 is not satisfied by the key count of 2'
Fix: Changed from selecting t parties to selecting t+1 parties.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
For 2-of-3 threshold signing, only 2 parties should participate in signing, not all 3. This fixes the 'failed to calculate Bob_mid' error that occurred when all parties tried to sign.
Changes:
- Modified CreateSigningSession to select exactly threshold_t parties when no signing config exists
- For 2-of-3: now selects 2 parties instead of all 3
- Added logging to show party selection details
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Only username is required, all other fields (email, phone, public_key, etc.) are now optional.
Changes:
- Modified 001_init_schema.up.sql to remove NOT NULL constraints
- Added partial unique index for email (only for non-NULL values)
- Created migration 006_make_email_optional for existing databases
- Set default status to 'active'
This allows automatic account creation from keygen without requiring user info.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previously, signing incorrectly required all n parties from keygen to participate. For 2-of-3 threshold, it required all 3 parties instead of just 2.
Root cause: tss.NewParameters was using len(currentSigners) instead of the original n from keygen.
Changes:
- Added TotalParties field to SigningConfig to store original n from keygen
- Modified participate_signing.go to read threshold_n from database
- Updated tss.NewParameters to use TotalParties instead of current signer count
- Added logging to show t, n, and current_signers
For 2-of-3: threshold_t=2, threshold_n=3, any 2 parties can now sign.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Created test_signing.go to test MPC signing functionality:
- Generates JWT token for authentication
- Creates SHA-256 hash of test message
- Calls POST /api/v1/mpc/sign API
- Tests signing with persistent parties (non-delegate mode)
Usage: go run test_signing.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added comprehensive debug logging to track message conversion and
party index mapping in keygen protocol:
1. Log party index map construction with all participants
2. Log received MPC messages before conversion
3. Log when messages are dropped due to unknown sender
4. Log successful message conversion and TSS forwarding
5. Show known_parties map when dropping messages
This will help identify why delegate party receives messages but
doesn't process them during keygen.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed the acknowledgment goroutine in GetPendingMessages to use parent
context instead of context.Background(), preventing orphan goroutines
that can't be cancelled.
This completes all context bug fixes:
- server-party-api event handler (commit 450163a)
- server-party event handler (commit 99ff3ac)
- message acknowledgment in SubscribeMessages (commit 450163a)
- message acknowledgment in GetPendingMessages (this commit)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fixed server-party event handler to use parent context with timeout
- Prevents orphan goroutines when session fails or party exits
- Consistent with server-party-api fix
- Fixed delegate party event handler to use parent context with timeout
- Fixed message acknowledgment to use parent context
- Prevents orphan goroutines when session fails or party exits
- Resolves system crash after delegate party failure
Add PARTY_ROLE=delegate environment variable to server-party-api service
to fix nil pointer dereference when determining party role during keygen.
Without this variable, the party defaults to "persistent" role which tries
to access keyShareRepo (nil for delegate parties), causing a panic.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>