Skip to content

feat(sdk-coin-iota): add MPCv2 signed hot recovery support - #9426

Open
Marzooqa wants to merge 1 commit into
masterfrom
marzooqakather498/wci-1226-sdk-coin-iota-mpcv2-signed-hot-recovery
Open

feat(sdk-coin-iota): add MPCv2 signed hot recovery support#9426
Marzooqa wants to merge 1 commit into
masterfrom
marzooqakather498/wci-1226-sdk-coin-iota-mpcv2-signed-hot-recovery

Conversation

@Marzooqa

@Marzooqa Marzooqa commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds MPCv2 signed hot recovery support to Iota.recover(), alongside the existing MPCv1 path (auto-detected, no new params)
  • Detects MPCv1 (JSON) vs MPCv2 (CBOR) keycard format via EDDSAUtils.isEddsaMpcV1SigningMaterial and dispatches signing accordingly, mirroring the SOL implementation (WCI-398)
  • MPCv2 path uses EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey + EDDSAUtils.signRecoveryEddsaMPCv2, validates commonKeyChain against bitgoKey, and wraps the resulting 64-byte signature in the existing SUI-style envelope (0x00 flag byte + 64-byte sig + 32-byte pubkey)
  • recoverConsolidations() MPCv2 support is out of scope, tracked separately in WCI-1235

Test plan

  • Native IOTA MPCv2 signed recovery — returns { serializedTx, scanIndex } with correctly-formed signature envelope
  • Token MPCv2 signed recovery — routes to MPCv2 path, envelope applied correctly
  • MPCv1 regression — unchanged signing path still exercised
  • Mismatched bitgoKey vs keycard commonKeyChain — throws
  • yarn unit-test (251 passing), tsc --noEmit, eslint all clean

TICKET: WCI-1226

🤖 Generated with Claude Code

@linear-code

linear-code Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

WCI-1226

Detects MPCv1 vs MPCv2 keycard format in Iota.recover() and dispatches
signing accordingly, mirroring the SOL implementation. MPCv2 signatures
are wrapped in the existing SUI-style envelope (0x00 flag + 64-byte sig
+ 32-byte pubkey).

TICKET: WCI-1226
@Marzooqa
Marzooqa force-pushed the marzooqakather498/wci-1226-sdk-coin-iota-mpcv2-signed-hot-recovery branch from 089d472 to ed08c7c Compare August 12, 2026 11:39
@Marzooqa

Copy link
Copy Markdown
Contributor Author

@claude

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Marzooqa's task —— View job


Code Review for MPCv2 Signed Hot Recovery Support ✅

Todo List:

  • Read repository guidelines (CLAUDE.md)
  • Examine the main implementation in iota.ts
  • Review test coverage and quality
  • Check for consistency with existing patterns
  • Provide comprehensive feedback

Overview

This PR successfully adds MPCv2 signed hot recovery support to the IOTA coin implementation. The changes follow the established pattern from SOL implementation and provide good backwards compatibility with MPCv1.

✅ Positive Aspects

Clean Architecture & Pattern Consistency

  • Well-structured detection logic: The isMpcv2SigningMaterial() method cleanly detects keycard format once upfront, avoiding repeated decryption during address scanning
  • Follows established patterns: Implementation mirrors the SOL coin approach (WCI-398), maintaining consistency across the codebase
  • Proper abstraction: The signing logic is cleanly separated between MPCv1 and MPCv2 paths

Comprehensive Test Coverage

  • Multiple test scenarios: Native IOTA recovery, token recovery, and MPCv1 regression testing
  • Edge case handling: Tests for mismatched bitgoKey vs commonKeyChain validation
  • Proper mocking: Uses sinon stubs effectively to isolate functionality
  • Signature validation: Tests verify the 97-byte signature format (flag + signature + pubkey)

Security & Error Handling

  • Input validation: Proper error handling for missing keys and passphrases
  • Key mismatch detection: The implementation includes validation that commonKeyChain matches bitgoKey
  • Backwards compatibility: MPCv1 path remains unchanged, ensuring no regression

🔍 Technical Implementation Details

Signature Format - iota.ts:887-890

const schemeFlag = Buffer.alloc(1, 0x00); // Ed25519 scheme
const publicKeyBytes = Buffer.from(derivedPublicKey, 'hex');
const fullSignature = Buffer.concat([schemeFlag, signatureBuffer, publicKeyBytes]);

The signature envelope follows the SUI-style format correctly: 0x00 flag byte + 64-byte signature + 32-byte public key.

MPCv2 Detection Logic - iota.ts:814-824

The detection method is efficient and follows the pattern:

const material = await getEddsaSigningMaterial(userKey.replace(/\s/g, ''), walletPassphrase, this.bitgo);
return material.version === 'v2';

💡 Minor Suggestions

Code Organization - iota.ts:308-309

The comment about detecting MPCv2 format "once up front" is helpful. Consider adding a brief comment explaining why this optimization matters (performance during address scanning).

Function Parameter Documentation - iota.ts:826-834

The signRecoveryTransaction method now has additional parameters. Consider adding JSDoc parameter documentation for the new isMpcV2 and bitgoKey parameters.

Test Consistency - iota.test.ts:742,819

The spy verification pattern sandBox.assert.notCalled(getTSSSignatureSpy) effectively validates that MPCv2 path doesn't use the old signing method.

📋 Verification Checklist

  • ✅ MPCv2 keycard detection works correctly
  • ✅ Signature envelope format matches specification (97 bytes)
  • ✅ MPCv1 regression protection in place
  • ✅ Token recovery supports MPCv2
  • ✅ Error handling for key mismatches
  • ✅ Comprehensive test coverage
  • ✅ No breaking changes to existing functionality

🎯 Conclusion

This is a well-implemented feature that adds MPCv2 support while maintaining backwards compatibility. The code follows established patterns, includes comprehensive tests, and handles edge cases appropriately. The implementation is ready for merge.

The PR successfully delivers on the requirements stated in WCI-1226 and provides a solid foundation for MPCv2 recovery operations in IOTA.


Job RunBranch

@Marzooqa
Marzooqa marked this pull request as ready for review August 12, 2026 12:29
@Marzooqa
Marzooqa requested a review from a team as a code owner August 12, 2026 12:29
@Marzooqa
Marzooqa requested a review from vibhavgo August 12, 2026 12:29
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