fix(sdk-core): pass txParams on EdDSA MPCv2 re-sign and PA paths#9061
fix(sdk-core): pass txParams on EdDSA MPCv2 re-sign and PA paths#9061bitgo-ai-agent-dev[bot] wants to merge 1 commit into
Conversation
83641a6 to
5fe3aca
Compare
5fe3aca to
f2a4114
Compare
danielpeng1
left a comment
There was a problem hiding this comment.
nice work; look into the fix for UI re-sign as well, unless you're planning to do that in a second PR, although it might be easier to reuse something for both paths.
|
@claude review and verify validity of requested changes |
|
Claude finished @danielpeng1's task —— View job Review Analysis - Daniel's Feedback Valid ✅I've analyzed the current PR implementation and Daniel's review feedback. All of Daniel's concerns are technically valid and should be addressed for a complete fix.
Key Issues Identified1. UI Re-sign Path Missing Fix
|
f2a4114 to
d222dd6
Compare
EdDSA MPCv2 verifyTransaction() compares txParams.recipients to parsed tx outputs before MPC signing. On re-sign and pending-approval flows txParams was never derived, causing a "Number of tx outputs does not match number of txParams recipients" error. Add txParamsFromIntent() which maps the persisted IntentRecipient shape on txRequest.intent into the flat ITransactionRecipient shape expected by verifyTransaction callers. Wire it in two places: - recreateTxRequest: derive txParams after fetching the fresh txRequest so PA approve → auto-sign completes correctly. - signTransactionTss: when buildParams is absent (re-sign via signAndSendTxRequest), fetch the txRequest and derive txParams so UI re-sign completes correctly. Existing buildParams / sendMany paths are unchanged; the new derivation only runs when buildParams is not already present. Ticket: WCI-765 Session-Id: 1c44b40e-24c1-49b1-b454-86318c9a44a2 Task-Id: bad80f2c-73b6-4826-a6ee-49cc4344544c
d222dd6 to
ca8ddb4
Compare
danielpeng1
left a comment
There was a problem hiding this comment.
lgtm for both paths 👍
| const intentRecipients = (intent as PopulatedIntent | undefined)?.recipients; | ||
| if (!intentRecipients?.length) { | ||
| return undefined; | ||
| } |
There was a problem hiding this comment.
can this be accessed via type narrowing instead of casting?
There was a problem hiding this comment.
also what if an intent is valid for having no recipients wouldn't this throw downstream during verification?
Summary
EdDSA MPCv2 TSOL signing fails on the pending-approval (PA) path with:
failed to sign transaction Error: Number of tx outputs does not match with number
of txParams recipients
Root cause: eddsaMPCv2.signRequestBase re-verifies the transaction against
txParams.recipients before DSG starts:
Solana's verifyTransaction does a strict length check:
Why ECDSA MPCv2 is unaffected: ETH's verifyTssTransaction gates its strict
recipient checks on txParams.type. Without a type, those checks are skipped and {
recipients: [] } passes silently.
Why EdDSA MPCv1 is unaffected: MPCv1's signRequestBase does not call
verifyTransaction with txParams in normal flows.
Fix
Derive txParams from the persisted txRequest.intent inside recreateTxRequest,
guarded to EdDSA MPCv2 only — matching the pattern established by WCI-505:
Ticket: WCI-765