User says "3-of-5" meaning 3 signers needed.
tss-lib threshold t means t+1 signers required.
Now we store t-1 at session creation (like persistent-only does).
Changes:
- co_managed_handler.go: tssThresholdT = req.ThresholdT - 1
- tss-party/main.go: remove -1 from sign (now consistent with keygen)
BREAKING: Existing co-managed wallets must be regenerated.
ROLLBACK: Revert this commit if signing still fails.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The tss.NewParameters() expects the party count to match the number of
parties in peerCtx. For signing, this should be len(sortedPartyIDs)
(actual signing participants), not thresholdN (original keygen parties).
This fixes the "U doesn't equal T" error in round 9 when doing 3-of-5
co-managed signing with parties at indices 2,3,4.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When switching message/event streams, the old stream's 'end' or 'error'
events could fire after the new stream was created. Since activeMessageSubscription
was already updated to the new session, the old stream's events would
incorrectly trigger reconnection, causing TSS message routing to fail.
Fix:
- Remove event listeners from old stream before canceling
- Use closure to capture current stream reference
- Check if event is from current active stream before triggering reconnect
This fixes the "Not connected" error during co-sign TSS message routing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Keygen/co-keygen: must have exactly N participants joined
- Sign (co-sign/persistent): only check all registered participants joined
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
User says 3-of-5 meaning 3 signers needed, but tss-lib threshold t means t+1 signers.
Pass thresholdT-1 so tss-lib needs (t-1)+1 = t signers, matching user expectation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Reverts e81757ad - the threshold conversion was wrong.
Keygen works with original thresholdT/thresholdN parameters.
The signing issue needs a different fix.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename thresholdT/thresholdN to requiredSigners/totalParties in Create.tsx
- Add parameter conversion in main.ts: threshold_t = requiredSigners - 1
- In tss-lib, threshold t means t+1 parties needed to sign
- For 3-of-5: requiredSigners=3 → threshold_t=2 (t+1=3 signers)
- externalCount = requiredSigners (user parties)
- persistentCount = totalParties - requiredSigners (server parties)
- Backward compatible with legacy thresholdT/thresholdN format
BREAKING: Existing co-managed wallets need re-keygen with new params
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The TSS signing was failing with "U doesn't equal T" error because
tss-party was passing incorrect parameters to tss.NewParameters():
- Was: len(sortedPartyIDs)=3 (signing participants), thresholdT-1=2
- Now: thresholdN=5 (keygen N), thresholdT=3 (keygen T)
This matches how pkg/tss/signing.go creates parameters in server-party,
which uses TotalParties=N and Threshold=T from the original keygen.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add keygenThresholdN to the CreateSignSession response so frontend
can access the original N value from keygen session. This is required
for proper TSS operation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add detailed comments to warn about changes that affect persistent sign flow:
- session_coordinator.go: ValidateSessionCreation now allows T <= count <= N for sign
- mpc_session.go: CanStart/AllPartiesReady now check registered participants, not N
- session_coordinator_client.go: ThresholdN now uses keygenThresholdN instead of len(parties)
Each comment includes:
- Original code behavior
- New code behavior
- How to revert if persistent sign breaks
- Related files list
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change ValidateSessionCreation to accept T <= participantCount <= N for sign sessions
- Co-managed sign uses exactly T parties
- Persistent sign uses T+1 parties
- Both now pass validation with correct keygenThresholdN
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- CanStart(): Check if all registered participants have joined, not based on T/N
- AddParticipant(): Keep N as max limit (API handles T vs T+1 validation)
- AllPartiesReady(): Check all registered participants, not based on T/N
- This approach works for both co-managed (T parties) and persistent (T+1 parties) signing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- For keygen sessions: require all N parties to join before starting
- For sign sessions: require only T parties to join before starting
- This fixes session_started event not being triggered for signing sessions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Modify ValidateSessionCreation to differentiate between keygen and sign sessions
- For keygen: require participantCount == threshold.N() (all parties must participate)
- For sign: require participantCount == threshold.T() (only t parties needed)
- This fixes "session is full" error when creating signing session with 3 parties but n=5
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Query keygen session from mpc_sessions table to get correct threshold_n
- Pass keygenThresholdN to CreateSigningSessionAuto instead of len(parties)
- Return parties list and correct threshold values in GetSignSessionByInviteCode
- This fixes TSS signing failure "U doesn't equal T" caused by mismatched n values
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Problem: Participants joining early only got incomplete participant list
from other_parties (only those who had joined), causing partyIndex mismatch.
Solution:
- Add parties field to SessionInfo (from validateInviteCode response)
- Pass parties to joinSession call from frontend
- Backend joinSession uses params.parties (complete list) instead of
result.other_parties (incomplete list)
- Add debug logging to track participant list state
Now all participants have the complete parties list with correct partyIndex.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add logic in handleCoSignStart to update participants from event.selectedParties
- Fix initiator immediate trigger to use other_parties + self instead of incomplete participants list
- Add debug logging for participant list updates
- Ensures all parties have correct participant list before TSS signing starts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change /sign to /cosign/join so participants use the correct page
with auto-join functionality.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add console.log statements to trace the auto-join logic:
- Log loaded shares with sessionId
- Log auto-select share matching check
- Log auto-join conditions and share match status
- Log validateInviteCode results including joinToken
- Log handleJoinSession parameters
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When multiple sign sessions share the same invite code (due to retries),
the query now:
1. Excludes failed sessions (status != 'failed')
2. Orders by created_at DESC to get the most recent session
3. Limits to 1 result
This prevents participants from seeing an old failed session's status
when they look up the invite code.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The validateSigningSession handler was using parties.length for threshold.n
which returned 0 when parties array was empty. Now correctly uses the
threshold_n value returned from the backend API.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Password is optional - remove the validation that required password
to be non-empty before joining a sign session.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Password field was required to enable the join button, but password
is optional when the share was created without encryption.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add threshold_n to GetSignSessionByInviteCodeResponse interface
- Fix main.ts to use result.threshold_n instead of result.parties?.length
- Add message_hash, joined_count, join_token to GetSignSessionByInviteCode response
- Generate join token for sign session lookup
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add invite_code retrieval in GetSignSessionStatus (backend)
- Add inviteCode to cosign:getSessionStatus response (frontend IPC)
- Add inviteCode to SessionState and display UI in CoSignSession
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fetch keygen session status from backend to get accurate party_index
- Filter out co-managed-party-* (server persistent parties) from signing
- Only temporary/external user parties participate in signing
- For 3-of-5 wallet: 3 user parties sign, 2 co-managed parties are backup only
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use API's participants field instead of parties
- Use API's threshold_t and threshold_n instead of activeCoSignSession
- Show participant status from API response
- Update GetSignSessionStatusResponse interface
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add join_tokens (map[partyID]token) to CreateSignSession response
- Keep join_token for backward compatibility
- Update frontend to use join_tokens[partyId] for initiator auto-join
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
BigInt cannot be serialized by JSON.stringify. Convert gasLimit,
maxFeePerGas, maxPriorityFeePerGas, and value to strings before
storing in sessionStorage.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add complete co-sign functionality for multi-party transaction signing:
Frontend (React):
- CoSignCreate.tsx: Create signing session with share selection
- CoSignJoin.tsx: Join signing session via invite code
- CoSignSession.tsx: Monitor signing progress and results
- Add routes in App.tsx for new pages
Backend (Electron):
- main.ts: Add IPC handlers for co-sign operations
- tss-handler.ts: Add participateSign() for TSS signing
- preload.ts: Expose cosign API to renderer
- account-client.ts: Add sign session API types
TSS Party (Go):
- main.go: Implement 'sign' command for GG20 signing protocol
- integration_test.go: Add comprehensive tests for signing flow
Infrastructure:
- docker-compose.windows.yml: Expose gRPC port 50051
This is a pure additive change that does not affect existing
persistent role keygen/sign functionality.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add KAVA_TESTNET_TX_CONFIG in kava-tx-service.ts
- Add switchNetwork/getNetwork IPC handlers in main.ts
- Add network toggle UI in Settings page
- Show current network (测试网/主网) badge in Layout status bar
- Default to testnet for development
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
listShares returned `participants` but Home.tsx expected `metadata.participants`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Default 64KB buffer was truncating large TSS protocol messages in round 3+
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
session_created event only contains initial co-managed parties,
but session_started event contains ALL participants including
external parties that joined dynamically via invite code.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add new ExecuteWithSessionInfo method to ParticipateKeygenUseCase
for server-party-co-managed to skip duplicate JoinSession call.
- server-party-co-managed already calls JoinSession in session_created phase
- ExecuteWithSessionInfo accepts pre-obtained SessionInfo and skips internal JoinSession
- Refactor common execution logic to private executeWithSessionInfo method
- Update server-party-co-managed to use ExecuteWithSessionInfo on session_started
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create new server-party-co-managed service with two-phase event handling
- Phase 1 (session_created): Store join token and wait
- Phase 2 (session_started): Execute TSS protocol (same timing as service-party-app)
- Add PartyRoleCoManagedPersistent role to isolate from normal keygen/sign
- Update docker-compose.yml with 3 co-managed party instances
- Update deploy.sh service lists
- Modify selectPartiesByCompositionForCoManaged to use new role
This ensures co_managed_keygen sessions use dedicated parties that behave
100% compatible with service-party-app, without affecting existing keygen/sign flows.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Problem:
- co_managed_keygen server-party waits for external party after joining
- No heartbeat sent during wait period (up to 5 minutes)
- session-coordinator has 120 second inactivity timeout
- Server-party marked as timed_out/failed while waiting
Fix:
- Send heartbeat in waitForAllParticipants polling loop
- Add Heartbeat method to MessageRouterClient interface
- Heartbeat every 2 seconds with poll interval
- Heartbeat failure only logs warning, does not block
Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- expires_at 存储为 UTC 时间
- 查询时使用 NOW() AT TIME ZONE 'UTC' 确保时区一致
- 避免因时区差异导致 session 过早被标记为过期
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
api.szaiai.com 被 OSS/CDN 拦截,改用 rwaapi.szaiai.com 直接访问 Kong 网关
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
添加 50051:50051 端口映射,使开发模式与生产模式保持一致
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
将 proto 文件加载改为延迟加载模式,在 connect() 时才加载,
避免模块加载时 app.isPackaged 还未准备好导致的路径错误。
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
bech32 v2.0.0 自带TypeScript类型定义,不需要单独的
@types/bech32 包(该包是针对v1.x版本的)。
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
将testConnection从URL解析改为直接使用host:port格式,
与grpc-client.ts的connect方法保持一致。
地址格式: mpc-grpc.szaiai.com:443 (自动检测TLS)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
添加 ProtoPackage 接口定义 proto 包结构类型,避免类型推断错误
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 新增 tsconfig.electron.json 单独编译 Electron 主进程到 dist-electron/
- 更新 package.json main 入口为 dist-electron/main.js
- 更新 build 脚本先编译 electron 再 vite build
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rewrite build-windows.bat in English to avoid encoding issues
- Remove icon configuration from electron-builder.json (use default)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
将 008_add_co_managed_wallet_fields.up.sql 改为幂等脚本:
- 使用 DO $$ ... IF NOT EXISTS 检查列是否存在再添加
- 使用 CREATE INDEX IF NOT EXISTS 创建索引
- 使用 DROP CONSTRAINT IF EXISTS 删除约束
这确保迁移脚本可以安全地多次执行,不会因列/索引已存在而失败。
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <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>
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>
Update session repository to properly handle delegate_party_id column:
- Add delegate_party_id to Save method INSERT and UPDATE statements
- Add DelegatePartyID field to sessionRow struct
- Update FindByUUID, FindByStatus, FindExpired, FindActive SELECT queries
- Update scanSessions method to scan and pass delegate_party_id
- Remove placeholder empty string, now loads actual value from database
This completes the delegate party functionality by ensuring the delegate party ID
is persisted and retrieved correctly from the database.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add delegate_party_id column to track which party is acting as delegate
(generates and returns user share instead of storing it).
Changes:
- Add delegate_party_id VARCHAR(255) column with default empty string
- Add partial index for faster lookups when delegate party is present
- Include up and down migrations
This fixes the issue where delegate party selection worked but the delegate_party
field was not being returned in API responses due to missing database column.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed critical bug where PartyComposition (persistent/delegate party counts) was being sent
by account-service in gRPC request but was not being extracted and passed to the CreateSession
use case, causing delegate party selection to fail.
Changes:
- Extract PartyComposition from protobuf request and pass to CreateSessionInput
- Add logging for party composition values in gRPC handler
- Return delegate_party_id and selected_parties in CreateSessionResponse
- Load session after creation to get delegate party ID
This fixes the issue where require_delegate=true had no effect and all parties selected
were persistent parties instead of 2 persistent + 1 delegate.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add ACCOUNT_SERVICE_ADDR environment variable pointing to account-service:8080
- Fixes "connection refused" error when session-coordinator tries to auto-create account after keygen
- Session-coordinator can now properly call account service to create account records
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>