feat(sdk-coin-dot): add MPCv2 support to recoverConsolidations - #9486
Conversation
8564bcd to
5a7c848
Compare
4518235 to
ee14577
Compare
ee14577 to
a08ca3e
Compare
Phase 1 — SummaryThis PR adds MPCv2 support to flowchart TD
A[recoverConsolidations] -->|walletPassphrase && userKey| B[getEddsaSigningMaterial — called ONCE]
A -->|no passphrase| C[signingMaterial = undefined]
B --> D{loop over indexes}
C --> D
D -->|each index| E[recover(recoverParams, signingMaterial)]
E -->|precomputedMaterial != null| F[use precomputedMaterial — skip per-call detection]
E -->|precomputedMaterial == null| G[getEddsaSigningMaterial — standalone path]
F --> H[addRecoverySignature / signEddsaMpcV2RecoveryTx]
G --> H
Phase 2 — Ticket AlignmentTicket: PR title: Phase 3 — Index AnalysisNo new database queries introduced. Phase 4 — Type SafetyTwo double-cast patterns in test code: basecoin as unknown as { getEddsaSigningMaterial: unknown }This appears twice (in the
Phase 5 — MPCv2 Correctness & Test QualityCorrectness
Test Quality
Consistency vs related PRs
SummaryNo blocking issues. The detection-once pattern is implemented correctly and the test suite covers the main paths (MPCv2 signed, MPCv1 regression, unsigned cold path). The small points worth a follow-up:
Generated by [ |
5b6afb7 to
8378a5a
Compare
a08ca3e to
0f0f341
Compare
Detect signing material once in recoverConsolidations() and thread it into each recover() iteration via an optional precomputedMaterial param, avoiding per-address keycard decryption across the scan range. Ticket: WCI-1236
0f0f341 to
39fd5ac
Compare
What
Dot.recoverConsolidations()via the sharedgetEddsaSigningMaterialhelper (from@bitgo/sdk-core, extracted in WCI-1276), instead of decrypting the keycard on every scanned index.recover()call via a newmultisigTypeVersion: 'MPCv2'option onDotRecoveryOptions, sorecover()skips its own per-call detection when the caller already knows the answer.Dot.recover()itself (previously only MPCv1/unsigned-sweep paths existed), using the sharedsignEddsaMpcV2RecoveryTxhelper, gated behind a new privateisMpcv2SigningMaterial()detector for standalonerecover()calls.isMpcv2SigningMaterialcalled exactly zero times insiderecover()whenmultisigTypeVersionis pre-resolved, MPCv1 regression (base address/signing unchanged), and MPCv2 unsigned/cold-path regression (no passphrase →isMpcV2false).Follows the pattern already established and merged for SOL (WCI-496, PR #9116).
Why
recoverConsolidations()scans receive-address indexes and sweeps funds to the base address (index 0) viarecover(). For MPCv2 wallets this was broken in two ways: the base destination address was derived assuming the legacy MPCv1 signing path, and per-index detection running insiderecover()would decrypt the same keycard once per scanned index (wasteful and slow across a 20+ index scan range). This ticket covers the SDK hot signed path only (caller passeswalletPassphrase) — WRW always stripswalletPassphrase, so WRW consolidation is unaffected.Dot.recover()'s own MPCv2 support is otherwise tracked separately in WCI-1227, but implementing it here was necessary forrecoverConsolidations()to have anywhere correct to route MPCv2 signing.Test plan
yarn unit-testinmodules/sdk-coin-dot— 211 passing (9 new MPCv2 tests + 2 new guard-clause tests), 0 failingtsc --build— no errorseslint --quiet .— 0 errorsTicket: WCI-1236