Skip to content

WCI-494: [sdk-coin-sol] MPCv2 recoverCloseATA and signAndGenerateBroadcastableTransaction#9060

Open
vibhavgo wants to merge 1 commit into
masterfrom
WCI-494/sdk-coin-sol
Open

WCI-494: [sdk-coin-sol] MPCv2 recoverCloseATA and signAndGenerateBroadcastableTransaction#9060
vibhavgo wants to merge 1 commit into
masterfrom
WCI-494/sdk-coin-sol

Conversation

@vibhavgo

@vibhavgo vibhavgo commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds MPCv2 support to recoverCloseATA and signAndGenerateBroadcastableTransaction in sol.ts. Previously these methods were MPCv1-only — MPCv2 wallets used the wrong address derivation (MPC.deriveUnhardened vs deriveUnhardenedMps) and wrong signing material format (JSON vs CBOR reduced key shares).

Ticket: WCI-494

Changes

  • Extract isMpcv2SigningMaterial() helper in sol.ts to detect MPCv2 keycards without ESM-incompatible stubs
  • Update recoverCloseATA to derive the authority address using deriveUnhardenedMps when keycard is MPCv2
  • Update signAndGenerateBroadcastableTransaction to accept isMpcV2 flag and branch between MPS DSG (MPCv2) and TSS (MPCv1) signing paths
  • Add MPCv2 unit tests for recoverCloseATA (no token balance, token balance present, bitgoKey mismatch) and signAndGenerateBroadcastableTransaction using real DKG key shares generated in a before() hook
  • Remove unused EDDSAUtils import (was only needed for the now-replaced stub-based detection)

Test Plan

  • All 602 existing unit tests pass
  • New MPCv2 tests use MPSUtil.generateEdDsaDKGKeyShares() for real key material — no stubs on ESM-incompatible modules
  • MPCv1 regression validated via getTSSSignature spy on existing recoverCloseATA and signAndGenerateBroadcastableTransaction tests

CLOSES TICKET: WCI-494

@linear-code

linear-code Bot commented Jun 18, 2026

Copy link
Copy Markdown

WCI-494

@vibhavgo vibhavgo marked this pull request as ready for review June 18, 2026 11:17
@vibhavgo vibhavgo requested a review from a team as a code owner June 18, 2026 11:17
Base automatically changed from WCI-398/sdk-coin-sol to master June 22, 2026 13:25
recoverCloseATA and signAndGenerateBroadcastableTransaction were
MPCv1-only. MPCv2 wallets used the wrong derivation path (MPC.deriveUnhardened
vs deriveUnhardenedMps) and wrong signing material format (JSON vs CBOR).

Route signing through MPS DSG protocol when keycard contains MPCv2 reduced
key shares, preserving the MPCv1 path unchanged.

Ticket: WCI-494
@vibhavgo vibhavgo force-pushed the WCI-494/sdk-coin-sol branch from e180d62 to ef08f7e Compare June 22, 2026 17:09
@vibhavgo

Copy link
Copy Markdown
Contributor Author

@claude

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Claude finished @vibhavgo's task —— View job


I'll analyze this and get back to you.

@vibhavgo

Copy link
Copy Markdown
Contributor Author

@claude

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Claude finished @vibhavgo's task —— View job


Code Review Analysis

Reviewing PR changes for MPCv2 support in Solana coin implementation.

Todo List:

  • Read and analyze sol.ts implementation changes
  • Review test file changes and coverage
  • Check for security considerations and best practices
  • Validate MPCv2 integration approach
  • Provide comprehensive review feedback

Review Summary

This PR successfully adds MPCv2 support to recoverCloseATA and signAndGenerateBroadcastableTransaction methods in the Solana coin implementation. The changes are well-structured and maintain backward compatibility with MPCv1 wallets.

Key Changes Analysis

1. Helper Function Extraction

  • Location: sol.ts:1949-1977
  • Change: Extracted isMpcv2SigningMaterial() helper to detect MPCv2 keycards
  • Benefits:
    • Eliminates code duplication across methods
    • Avoids ESM-incompatible stubs by using EDDSAUtils.isEddsaMpcV1SigningMaterial()
    • Clean separation of concerns

2. Address Derivation Fix

  • Location: sol.ts:1529-1535 in recoverCloseATA
  • Issue Fixed: MPCv2 wallets were using wrong derivation method
  • Solution: Branch between deriveUnhardenedMps() (MPCv2) and MPC.deriveUnhardened() (MPCv1)
  • Impact: Ensures correct address generation for both wallet types

3. Signing Method Consolidation

  • Location: New addRecoverySignature() method at sol.ts:1881-1947
  • Improvement: Consolidated duplicate signing logic from both methods
  • Benefits:
    • DRY principle adherence
    • Consistent error handling
    • Proper MPCv2 vs MPCv1 branching

4. Method Signature Updates

  • signAndGenerateBroadcastableTransaction: Added isMpcV2 parameter with default false
  • Type Safety: Updated from any to TransactionBuilder type
  • Backward Compatibility: Default parameter ensures existing calls work unchanged

Security Considerations ✅

Keychain Validation

  • Location: sol.ts:1934-1936
  • Proper validation that commonKeyChain from MPCv2 keycard matches the provided bitgoKey
  • Prevents keychain mismatch attacks

Error Handling

  • Comprehensive error wrapping for decryption failures
  • Clear error messages for debugging without exposing sensitive data
  • Proper assertion usage with meaningful error messages

Key Material Handling

  • No sensitive key material is logged or exposed
  • Proper cleanup and scoping of cryptographic operations
  • Uses established BitGo patterns for key decryption

Test Coverage Analysis ✅

Comprehensive MPCv2 Testing

  • Real Key Generation: Uses MPSUtil.generateEdDsaDKGKeyShares() for authentic test scenarios
  • Multiple Test Cases: No token balance, token balance present, keychain mismatch scenarios
  • Regression Testing: MPCv1 tests enhanced with getTSSSignature spies to ensure no breaking changes

Test Quality

  • Before Hook Setup: Proper DKG key share generation ensures realistic testing
  • Error Case Coverage: Tests keychain mismatch scenarios
  • Integration Testing: Full end-to-end recovery flow testing

Code Quality Assessment ✅

Strengths

  1. Clean Refactoring: Excellent extraction of common functionality
  2. Type Safety: Improved type annotations throughout
  3. Error Handling: Comprehensive and user-friendly error messages
  4. Documentation: Clear inline comments explaining MPCv1 vs MPCv2 differences
  5. Backward Compatibility: Zero breaking changes for existing functionality

Minor Suggestions

  1. Import Organization: Consider grouping imports by source (lines 13-63)
  2. Method Documentation: The new isMpcv2SigningMaterial() method could benefit from JSDoc comments explaining its purpose and return behavior

Architectural Impact ✅

Design Patterns

  • Follows established BitGo patterns for MPC version detection
  • Consistent with other coin implementations' MPCv2 support
  • Maintains the existing recovery flow architecture

Performance

  • No performance regressions introduced
  • Efficient early detection of MPC version prevents unnecessary operations
  • Proper error short-circuiting

Final Assessment

✅ APPROVE - This is a high-quality implementation that:

  1. Correctly implements MPCv2 support with proper address derivation and signing
  2. Maintains full backward compatibility with existing MPCv1 wallets
  3. Follows security best practices with proper validation and error handling
  4. Includes comprehensive test coverage using real cryptographic materials
  5. Improves code quality through refactoring and type safety enhancements

The PR successfully addresses the stated requirements and maintains the high code quality standards expected in the BitGoJS codebase.


Job Run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant