- Add ShareForUser field to ParticipateKeygenOutput
- Implement role-based share handling (persistent/delegate/temporary)
- Add in-memory share cache with 15-minute TTL for delegate parties
- Add GET /api/v1/sessions/:session_id/user-share endpoint for one-time share retrieval
- Shares from delegate parties are NOT saved to database
- Add comprehensive Delegate Party implementation guide
This implements hybrid custody model similar to Fireblocks and ZenGo:
- Persistent parties: shares stored in server database
- Delegate parties: shares returned to user, deleted from memory after retrieval
🤖 Generated with Claude Code
- 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.
Implement Solution 1 (Party Role Labels) to differentiate between persistent
and delegate parties, with strict security guarantees for MPC threshold systems.
Key Features:
- PartyRole enum: persistent, delegate, temporary
- K8s pod labels (party-role) for role identification
- Role-based party filtering and selection
- Strict persistent-only default policy (no fallback)
- Optional PartyComposition for custom party requirements
Security Guarantees:
- Default: MUST use persistent parties (store shares in database)
- Fail fast with clear error if insufficient persistent parties
- No silent fallback to mixed/delegate parties
- Empty PartyComposition validation prevents accidental bypass
- MPC system compatibility maintained
Implementation:
1. Added PartyRole type with persistent/delegate/temporary constants
2. Extended PartyEndpoint with Role field
3. K8s party discovery extracts role from pod labels (defaults to persistent)
4. Session creation logic with strict persistent requirement
5. PartyComposition support for explicit mixed-role sessions
6. K8s deployment files with party-role labels
Files Modified:
- services/session-coordinator/application/ports/output/party_pool_port.go
- services/session-coordinator/infrastructure/k8s/party_discovery.go
- services/session-coordinator/application/ports/input/session_management_port.go
- services/session-coordinator/application/use_cases/create_session.go
- k8s/server-party-deployment.yaml (persistent role)
Files Added:
- k8s/server-party-api-deployment.yaml (delegate role)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added Kubernetes client-go v0.29.0 dependencies via go mod tidy.
Required for dynamic party pool service discovery feature.
Dependencies added:
- k8s.io/apimachinery v0.29.0
- k8s.io/client-go v0.29.0
- google.golang.org/protobuf v1.31.0
- Related indirect dependencies (go-logr, gnostic-models, etc.)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major architectural refactoring to align with international MPC standards
and enable horizontal scalability.
## Core Changes
### 1. DeviceInfo Made Optional
- Modified DeviceInfo.Validate() to allow empty device information
- Aligns with international MPC protocol standards
- MPC protocol layer should not mandate device-specific metadata
- Location: services/session-coordinator/domain/entities/device_info.go
### 2. Kubernetes Party Discovery Service
- Created infrastructure/k8s/party_discovery.go (220 lines)
- Implements dynamic service discovery via Kubernetes API
- Supports in-cluster config and kubeconfig fallback
- Auto-refreshes party list every 30s (configurable)
- Health-aware selection (only ready pods)
- Uses pod names as unique party IDs
### 3. Party Pool Architecture
- Defined PartyPoolPort interface for abstraction
- CreateSessionUseCase now supports automatic party selection
- When no participants specified, selects from K8s pool
- Graceful fallback to dynamic join mode if discovery fails
- Location: services/session-coordinator/application/ports/output/party_pool_port.go
### 4. Integration Updates
- Modified CreateSessionUseCase to inject partyPool
- Updated session-coordinator main.go to initialize K8s discovery
- gRPC handler already supports optional participants
- Added k8s client-go dependencies (v0.29.0) to go.mod
## Kubernetes Deployment
### New K8s Manifests
- k8s/namespace.yaml: mpc-system namespace
- k8s/configmap.yaml: shared configuration
- k8s/secrets-example.yaml: secrets template
- k8s/server-party-deployment.yaml: scalable party pool (3+ replicas)
- k8s/session-coordinator-deployment.yaml: coordinator with RBAC
- k8s/README.md: comprehensive deployment guide
### RBAC Configuration
- ServiceAccount for session-coordinator
- Role with pods/services get/list/watch permissions
- RoleBinding to grant discovery capabilities
## Key Features
✅ Dynamic service discovery via Kubernetes API
✅ Horizontal scaling (kubectl scale deployment)
✅ No hardcoded party IDs
✅ Health-aware party selection
✅ Graceful degradation when K8s unavailable
✅ MPC protocol compliance (optional DeviceInfo)
## Deployment Modes
### Docker Compose (Existing)
- Fixed 3 parties (server-party-1/2/3)
- Quick setup for development
- Backward compatible
### Kubernetes (New)
- Dynamic party pool
- Auto-discovery and scaling
- Production-ready
## Documentation
- Updated main README.md with deployment options
- Added architecture diagram showing scalable party pool
- Created comprehensive k8s/README.md with:
- Quick start guide
- Scaling instructions
- Troubleshooting section
- RBAC configuration details
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes:
- Modified CreateAccountRequest to make email optional (omitempty)
- Changed Account.Email from string to *string pointer type
- Updated PostgreSQL repository to handle nullable email with sql.NullString
- Username remains required and auto-generated by identity-service
This supports anonymous account creation without requiring email registration.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added comprehensive documentation for MPC system integration:
- MPC_INTEGRATION_GUIDE.md: Complete integration guide for backend developers
* System architecture explanation
* Service responsibilities and relationships
* Standard MPC session types (keygen/sign/recovery)
* Integration examples (Go/Python/HTTP)
* Troubleshooting guide
- VERIFICATION_REPORT.md: System verification report
* Service health status checks
* API functionality verification
* E2E test issue analysis
* System maturity assessment
- test_real_scenario.sh: Real scenario test script
* Automated verification workflow
* Keygen session creation test
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Simplified participant list handling in JoinSession client
- Added debug logging for party_index conversion in gRPC messages
- Removed redundant party filtering logic
- Added detailed logging to trace protobuf field values
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added debug logging to track participant details including party_index in:
- account service MPC keygen handler
- session coordinator gRPC client
- session coordinator gRPC handler
This helps debug the party index assignment issue where all parties
were receiving index 0 instead of unique indices (0, 1, 2).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update account_handler to use real gRPC calls instead of placeholders
- Add sessionCoordinatorClient field to AccountHTTPHandler
- Modify CreateKeygenSession to call session coordinator via gRPC
- Modify CreateSigningSession to call session coordinator via gRPC
- Modify GetSessionStatus to query real session data via gRPC
- Update main.go to initialize and pass sessionCoordinatorClient
- Remove separate mpc_handler.go (consolidated into account_handler)
- Regenerate protobuf files with gRPC service definitions
- Add proper imports for context, time, and grpc adapter
All MPC endpoints now create real sessions with JWT tokens and
can query actual session status from the session coordinator service.
Tested end-to-end: keygen session creation and status query working.
- Add SessionCoordinatorClient gRPC adapter with connection retry logic
- Implement MPCHandler with real gRPC calls to session-coordinator
- Replace placeholder implementation with actual session creation
- Add keygen and signing session endpoints with proper validation
- Include comprehensive implementation summary documentation
This enables account-service to create real MPC sessions via gRPC
instead of returning mock data. Requires main.go integration to activate.
- Add retry mechanism for PostgreSQL connections (10 retries, 2s base delay)
- Add retry mechanism for RabbitMQ connections (10 retries, 2s base delay)
- Add retry mechanism for Redis connections (10 retries, 2s base delay)
- Use exponential backoff: delay increases with each retry attempt
- Log detailed retry information (attempt number, max retries, errors)
- Redis continues without cache if all retries fail (non-critical)
- Database and RabbitMQ return error after all retries (critical)
This resolves startup failures when dependent services are slow to initialize,
particularly RabbitMQ which may pass health checks but not be fully ready.
- Add mkdir commands to create output directories
- Add paths=source_relative options for go_out and go-grpc_out
- This ensures *_grpc.pb.go files are generated correctly
- Fixes session-coordinator and message-router startup failures
Related: MPC services were failing to start due to missing gRPC service interface files
- Change Host header from $host to $http_host for correct host forwarding
- Add X-Forwarded-Host and X-Forwarded-Port headers
- Add Origin header ($scheme://$host) critical for Grafana 10+ CORS validation
- Disable proxy buffering for better real-time updates
- Update README with manual Nginx configuration update instructions for existing installations
Resolves 'origin not allowed' error when accessing Grafana through Nginx reverse proxy with SSL.
- Added critical warning about GRAFANA_ROOT_URL matching actual access URL
- Documented common "origin not allowed" error and its cause
- Provided clear examples for local vs production deployment
- Added security tip for generating Grafana password
This fixes the 403 Forbidden error when accessing Grafana via domain
while GRAFANA_ROOT_URL is set to localhost.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added Kong database configuration section to README.md
- Documented that Kong database username and database name are hardcoded as 'kong'
- Clarified that only password is configurable via KONG_PG_PASSWORD
- Added security warnings about changing password in production
- Updated .env.example with detailed comments about Kong database config
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Created .env.example files with comprehensive security warnings
- Removed hardcoded IP addresses and credentials from docker-compose files
- Made database passwords mandatory (fail-fast on missing config)
- Removed Chinese mirror sources from all Dockerfiles
- Enhanced deploy.sh scripts with .env validation and auto-creation
- Added comprehensive README.md deployment guides
- Changed ALLOWED_IPS default to enable cross-server deployment
- Updated all docker-compose files to use environment variables
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
将 `import WebSocket from 'ws'` 改为 `import * as WebSocket from 'ws'`
以兼容 CommonJS 模块系统
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>