Commit Graph

107 Commits

Author SHA1 Message Date
hailin 9b9612bd5f feat(token): add Green Points (绿积分) ERC-20 token support
Add support for the dUSDT token "绿积分" (Green Points) on both Android
and Electron applications:

Android changes:
- Add TokenType enum and GreenPointsToken config in Models.kt
- Implement ERC-20 balance fetching and transfer encoding in TssRepository
- Update TransactionUtils with ERC-20 transfer support
- Add dual balance display (KAVA + 绿积分) in WalletsScreen
- Add token type selector in TransferScreen

Electron changes:
- Add TokenType and GREEN_POINTS_TOKEN config in transaction.ts
- Implement fetchGreenPointsBalance and ERC-20 transfer encoding
- Update Home.tsx with dual balance display and token selector
- Add token selector styles in Home.module.css

Token contract: 0xA9F3A35dBa8699c8C681D8db03F0c1A8CEB9D7c3 (Kava mainnet)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 03:01:05 -08:00
hailin 2365a50b1b feat(tss): add real-time round progress from msg.Type() parsing
Extract current round number from tss-lib message type string using
regex pattern `Round(\d+)`. This enables real-time progress updates
(1/4, 2/4... for keygen, 1/9, 2/9... for signing) instead of only
showing completion status.

Changes across all three platforms:
- tss-wasm/main.go: Add extractRoundFromMessageType() and call
  OnProgress with parsed round on each outgoing message
- service-party-android/tsslib/tsslib.go: Same implementation for
  Android gomobile binding
- service-party-app/tss-party/main.go: Same implementation for
  Electron subprocess, with isKeygen parameter to distinguish
  keygen (4 rounds) vs signing (9 rounds)

Safe fallback: Returns 0 if parsing fails, which doesn't affect
protocol execution - only UI display.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 22:41:51 -08:00
hailin ad79679ee2 feat(ui): add QR code display for invite code in signing session
Android TransferScreen:
- Add QR code display above invite code text
- Import QRCodeWriter and related components
- Add generateInviteQRCode helper function
- Update hint text to mention scanning

Electron CoSignSession:
- Import QRCodeSVG from qrcode.react
- Add QR code above invite code text with proper styling
- Center QR code and update hint text

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 18:37:18 -08:00
hailin 7346b3518a fix(electron): auto-navigate to home after keygen completion
Previously, after keygen completed, the Session page would just update the
status to 'completed' but not navigate away. Users had to manually click
the "Return Home" button. This could result in a white screen if the button
wasn't visible or clickable.

Now the page auto-navigates to home after 2 seconds, giving users time to
see the completion status and public key before redirecting.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 10:22:42 -08:00
hailin 444b720f8d feat(android): strengthen gRPC connection reliability
Major improvements to Android gRPC client:
- Add automatic reconnection with exponential backoff (1s to 30s)
- Add heartbeat mechanism with failure detection (30s interval, 3 failures trigger reconnect)
- Add stream version tracking to filter stale callbacks
- Add channel state monitoring (every 5s)
- Add per-call deadline instead of one-time deadline for stubs
- Add SharedFlow for connection events (Connected, Disconnected, Reconnecting, Reconnected, PendingMessages)
- Add callback exception handling for robustness
- Add stream recovery after reconnection via callback mechanism

TssRepository changes:
- Save message routing params for recovery after reconnect
- Expose grpcConnectionEvents SharedFlow for UI notifications
- Auto-restore event subscriptions after reconnection

Other changes:
- Add QR code to Electron Create page for mobile scanning
- Auto version increment from version.properties
- SettingsScreen shows BuildConfig version info
- CreateWalletScreen tracks hasEnteredSession state

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 06:44:42 -08:00
hailin f7de1e8d09 fix(electron): fix wallet detail modal buttons
1. Copy address button:
   - Changed from alert() to visual feedback (shows "✓ 已复制")
   - Feedback auto-hides after 2 seconds

2. Explorer link button:
   - Was hardcoded to testnet (true)
   - Now uses getCurrentNetwork() to determine correct explorer URL
   - Links to kavascan.com for mainnet, testnet.kavascan.com for testnet

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 03:29:54 -08:00
hailin 77bbb43eb5 fix(electron): sync network status display with Settings in real-time
Previously, the network badge (testnet/mainnet) in Layout sidebar only
loaded once on mount and didn't update when user changed network in
Settings page.

Changes:
- Layout.tsx: Read network from localStorage first (consistent with
  transaction.ts), then fallback to Electron API
- Layout.tsx: Listen for 'storage' event (cross-tab) and custom
  'kava-network-change' event (same-tab) to update display
- Settings.tsx: Dispatch custom event when switching networks so
  Layout can update immediately

Android app doesn't have this issue - it uses StateFlow which
automatically triggers re-renders when settings change.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 03:24:19 -08:00
hailin fd5f4d10ed fix(transfer): MAX button now deducts gas fee from balance
Both Electron and Android apps now calculate the maximum transferable
amount by subtracting estimated gas fees from the balance:

Electron (Home.tsx):
- Added calculateMaxAmount() async function that fetches gas price
- Uses 21000 gas limit for simple transfers
- Shows loading state while calculating

Android (TransferScreen.kt):
- Added calculateMaxTransferAmount() in TransactionUtils
- Uses coroutine to fetch gas price asynchronously
- Shows "..." while calculating, falls back to balance on error

Both implementations:
- Add 10% buffer to gas price for safety
- Round down to 6 decimal places
- Show error if balance insufficient for gas

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 03:08:01 -08:00
hailin 7f66ed0ebe fix(electron): sync network setting to localStorage when switching networks
The network toggle in Settings was saving to database via electron API
but getCurrentNetwork() in transaction.ts reads from localStorage.
This caused the balance display to use wrong RPC endpoint after switching.

Now syncs to localStorage when switching networks to ensure consistency.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 02:58:02 -08:00
hailin 5f484f6579 fix(electron): use dynamic network config for balance queries
Previously Home.tsx hardcoded testnet RPC for balance queries.
Now uses getCurrentRpcUrl() to respect user's network setting.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 02:46:39 -08:00
hailin 7b6d6de801 feat(android): add Android TSS Party app with full API implementation
Major changes:
- Add complete Android app (service-party-android) with Jetpack Compose UI
- Implement real account-service API calls for keygen and sign sessions:
  - POST /api/v1/co-managed/sessions (create keygen session)
  - GET /api/v1/co-managed/sessions/by-invite-code/{code} (validate invite)
  - POST /api/v1/co-managed/sessions/{id}/join (join keygen session)
  - POST /api/v1/co-managed/sign (create sign session)
  - GET /api/v1/co-managed/sign/by-invite-code/{code} (validate sign invite)
  - POST /api/v1/co-managed/sign/{id}/join (join sign session)
- Add QR code generation and scanning for session invites
- Remove password requirement (use empty string)
- Add floating action button for wallet creation
- Add network type aware explorer links (mainnet/testnet)

Network configuration:
- Change default network to Kava mainnet for both Electron and Android apps
- Electron: main.ts, transaction.ts, Settings.tsx, Layout.tsx
- Android: Models.kt (NetworkType.MAINNET default)

Features:
- Full TSS keygen and sign protocol via gomobile bindings
- gRPC message routing for multi-party communication
- Cross-platform compatibility with service-party-app (Electron)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 23:27:29 -08:00
hailin ff995a827b fix(grpc-client): add connection check and better error handling in subscribeMessages
Additional safeguards to prevent "CANCELLED: Cancelled on client" error:

1. Add `this.connected` check at the start of subscribeMessages()
2. Set messageStream to null after canceling old stream
3. Wrap new stream creation in try-catch to handle creation errors
4. Add logging for ignored cancel errors

These changes ensure that:
- subscribeMessages won't proceed if connection is lost
- Old stream is fully cleaned up before creating new one
- Errors during stream creation are properly caught and logged

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 13:09:45 -08:00
hailin 66a718ea72 fix(electron): properly cleanup gRPC message stream after keygen/sign
Root cause: After keygen/sign completion, the gRPC message stream was not
unsubscribed. On the second operation, prepareForSign/prepareForKeygen
would try to cancel the stale stream, causing "CANCELLED: Cancelled on client".

Changes in tss-handler.ts:
- Add grpcClient.unsubscribeMessages() in all cleanup paths:
  - participateKeygen close handler
  - participateKeygen error handler
  - participateSign close handler
  - participateSign error handler
  - cancel() method
- Reset sessionId and partyId in all cleanup paths

Changes in main.ts:
- Add reconnection logic in app 'activate' event for macOS

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 13:07:43 -08:00
hailin d051178801 fix(electron): add gRPC connection check before subscribing to messages
The app was crashing with "CANCELLED: Cancelled on client" error when
opening the app a second time. This happened because:

1. When window was reopened, old gRPC streams were in cancelled state
2. prepareForSign/prepareForKeygen tried to subscribe on cancelled streams
3. The error was unhandled and crashed the app

Changes:
- Add isConnected() check in prepareForSign() and prepareForKeygen()
- Throw meaningful error when gRPC client is not connected
- Wrap all prepareFor* calls in try-catch in main.ts
- Return user-friendly error message instead of crashing

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 13:04:19 -08:00
hailin c0229a1139 fix(transaction): use eth_gasPrice RPC for Legacy transaction gas estimation
- Changed getGasPrice() to use eth_gasPrice RPC method instead of calculating
  from baseFeePerGas (which is for EIP-1559 transactions)
- Added 10% buffer to gas price to ensure transaction gets included
- Updated Home.tsx to use gasPrice instead of maxFeePerGas for display

KAVA doesn't support EIP-1559, so we must use Legacy (Type 0) transactions
with gasPrice from eth_gasPrice RPC.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 12:48:41 -08:00
hailin 0f8e9cf228 fix(transaction): use Legacy (Type 0) transaction format for KAVA
KAVA EVM does not support EIP-1559 dynamic fee transactions.
Changed from EIP-1559 (Type 2) to Legacy (Type 0) format:

- prepareTransaction: Use [nonce, gasPrice, gasLimit, to, value, data, chainId, 0, 0]
- finalizeTransaction: Use EIP-155 v calculation (chainId * 2 + 35 + recoveryId)
- Remove type prefix (0x02) as Legacy transactions don't need it
- Update Home.tsx and CoSignSession.tsx to use gasPrice instead of maxFeePerGas

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 12:45:38 -08:00
hailin d18733deb1 fix(tss-party): include recovery ID in signature output for EVM transactions
The signature was 64 bytes (r + s) but EVM transactions need 65 bytes (r + s + v).
Now the recovery ID is appended to the signature so the frontend can correctly
parse and broadcast the transaction.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 12:37:53 -08:00
hailin b5512d421c fix(tss): convert threshold to tss-lib format (threshold-1) in all keygen and signing
TSS-lib convention: threshold=t means (t+1) signers required.
User expectation: "2-of-3" means 2 signers needed.

Before this fix:
- Keygen used thresholdT directly (e.g., 2)
- TSS-lib interpreted as needing 3 signers (2+1)
- 2-of-3 wallet was actually 3-of-3!

After this fix:
- Both keygen and signing use (thresholdT-1)
- For 2-of-3: tss-lib threshold=1, needs 1+1=2 signers ✓

Files changed:
- tss-party/main.go: keygen and signing both use thresholdT-1
- tss-wasm/main.go: keygen and signing both use thresholdT-1
- pkg/tss/keygen.go: uses config.Threshold-1
- pkg/tss/signing.go: uses config.Threshold-1

BREAKING CHANGE: Existing wallets created before this fix used wrong
threshold and need to be regenerated. New wallets will work correctly.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 12:19:58 -08:00
hailin 51c0f59924 fix(tss): remove threshold-1 in signing to match keygen exactly
The signing code was using thresholdT-1 while keygen was using thresholdT,
causing Lagrange coefficient mismatch and "U doesn't equal T" error in round 9.

Root cause: commit d0c504dc added -1 to signing threshold to "match user expectation",
but this broke the keygen/sign consistency that TSS-lib requires.

Changes:
- tss-party/main.go: Sign now uses thresholdT (same as keygen)
- pkg/tss/signing.go: Add logging, emphasize threshold must match keygen
- tss-wasm/main.go: Add comment about threshold consistency

NOTE: This fix maintains backward compatibility with existing wallets.
No wallet regeneration is needed.

ROLLBACK: If this causes issues, revert to commit before this one.
Previous signing threshold was thresholdT-1 (commit d0c504dc).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 12:08:40 -08:00
hailin 4a00c8066a fix(tss-party): fix debug logging slice bounds error
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 11:46:46 -08:00
hailin 7a82a56ae5 debug(tss-party): add detailed key matching logs
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 11:41:41 -08:00
hailin 3564f30f27 debug(tss-party): add logging for BuildLocalSaveDataSubset
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 11:35:56 -08:00
hailin 7ab28dced0 fix(tss): use BuildLocalSaveDataSubset for threshold signing with party subsets
When signing with fewer parties than keygen (e.g., 2-of-3 signing with only 2 parties),
the TSS-lib requires filtered save data containing only the participating parties.

Without this fix, signing fails with "U doesn't equal T" error because:
- Keygen creates save data for all N parties (e.g., 3 parties with indices 0, 1, 2)
- Sign uses only T parties (e.g., 2 parties with indices 1, 2)
- TSS-lib internal index validation fails due to mismatch

Changes:
- pkg/tss/signing.go: Use len(sortedPartyIDs) for partyCount and call BuildLocalSaveDataSubset
- tss-party/main.go: Add BuildLocalSaveDataSubset call for Electron app
- tss-wasm/main.go: Add BuildLocalSaveDataSubset call for WASM builds

This fix is backward compatible - when all parties participate, the subset equals the original data.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 11:25:22 -08:00
hailin 24ff1409d0 Revert "fix(co-keygen): convert threshold at storage time to match tss-lib convention"
This reverts commit 4dcc7d37ba.
2025-12-31 10:24:25 -08:00
hailin 4dcc7d37ba fix(co-keygen): convert threshold at storage time to match tss-lib convention
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>
2025-12-31 10:14:21 -08:00
hailin b876c9dfba fix(co-sign): use actual signer count instead of keygen N in NewParameters
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>
2025-12-31 09:06:59 -08:00
hailin b231667aba fix(grpc): prevent stream race condition from triggering reconnection
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>
2025-12-31 08:57:44 -08:00
hailin d0c504dcf3 fix(co-sign): adjust threshold for tss-lib (t-1) to match user expectation
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>
2025-12-31 08:19:27 -08:00
hailin 54121fa494 revert: undo incorrect threshold conversion that broke keygen
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>
2025-12-31 07:58:36 -08:00
hailin e81757ad83 fix(co-sign): convert user-friendly threshold to tss-lib format
- 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>
2025-12-31 07:44:17 -08:00
hailin ca69ebc839 fix(co-sign): use keygen N and T for TSS signing parameters
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>
2025-12-31 07:01:59 -08:00
hailin e284a46e83 fix(co-sign): pass complete parties list to joinSession
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>
2025-12-31 04:34:48 -08:00
hailin 8193549aba fix(co-sign): update participants list from session_started event
- 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>
2025-12-31 04:13:29 -08:00
hailin 742419c0bf fix(layout): change sidebar sign link to new CoSignJoin page
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>
2025-12-31 03:53:51 -08:00
hailin da189ca3d4 feat(co-sign): add debug logs for auto-join flow in CoSignJoin
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>
2025-12-31 03:33:10 -08:00
hailin 138650d943 fix(sign): use threshold_n from API response instead of parties.length
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>
2025-12-31 02:07:05 -08:00
hailin 9f898ccf44 fix(sign): remove password validation check in handleJoinSigning
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>
2025-12-31 01:58:29 -08:00
hailin 227d04bde3 fix(sign): make password optional for joining sign session
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>
2025-12-31 01:49:56 -08:00
hailin c1e32a8c04 fix(co-sign): fix threshold_n display and add missing fields in GetSignSessionByInviteCode
- 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>
2025-12-31 01:47:08 -08:00
hailin 4d65b8dd83 feat(co-sign): add invite code display in CoSignSession page
- 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>
2025-12-31 01:37:11 -08:00
hailin ebbc483b35 fix(co-sign): use keygen session participants with correct party_index for signing
- 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>
2025-12-31 01:12:07 -08:00
hailin 4089b9da6c fix(service-party-app): use API response for co-sign session status display
- 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>
2025-12-30 20:17:14 -08:00
hailin c1e749e532 fix(co-sign): return join_tokens map for initiator auto-join
- 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>
2025-12-30 19:54:20 -08:00
hailin b688b0176e fix(service-party-app): serialize BigInt to string for sessionStorage
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>
2025-12-30 19:16:38 -08:00
hailin 879fc3a816 feat(service-party-app): add transfer functionality with co-sign integration
Add complete KAVA transfer feature to the wallet home page:

Frontend (React):
- Home.tsx: Add transfer modal with address/amount input, transaction
  confirmation, and co-sign session initiation
- Home.module.css: Transfer modal styles (form, confirm, error states)
- CoSignSession.tsx: Add transaction broadcast after signing completion,
  with block explorer link

Utils:
- transaction.ts: EIP-1559 transaction building, RLP encoding, Keccak-256
  hashing, nonce/gas fetching, transaction broadcast via JSON-RPC

Flow: Wallet -> Transfer Modal -> Prepare TX -> Confirm -> Co-Sign ->
      Sign Session -> Broadcast -> Block Explorer

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 19:08:03 -08:00
hailin ebea74e57b feat(service-party-app): implement co-sign multi-party signing
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>
2025-12-30 18:36:11 -08:00
hailin 7696f663a5 fix(service-party-app): add 'kava' to LogSource type
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 10:34:57 -08:00
hailin ae936e8a87 feat(service-party-app): add Kava network switch (mainnet/testnet)
- 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>
2025-12-30 10:31:27 -08:00
hailin 9015888b23 fix(service-party-app): fix participants display in Home page
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>
2025-12-30 10:07:11 -08:00
hailin f849a2a9fd fix(tss-party): increase stdin buffer to 1MB for large TSS messages
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>
2025-12-30 09:57:04 -08:00