Repository navigation
Conversation
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
|
|
ad82f84 to
0184678
Compare
ReviewThe fix is targeted and sensible. Skipping the auto recreate-and-sign for message-only approvals matches the root cause. The assert hardening turns a Must fix: internal information in comments
Suggestions
Good practices
No security or cryptographic concerns: no change to signing inputs, key handling or derivation. |
0184678 to
6b43c46
Compare
postApprove() unconditionally ran the TSS recreate-and-sign flow for TRANSACTION_REQUEST_FULL approvals, which reads transactions[0].unsignedTx. Message-only txRequests have an empty transactions array, so this crashed. postApprove() now returns early when the approval's intent is a message-sign intent (signMessage / signTypedStructuredData), leaving the message to be signed separately via signAndSendMessageTxRequest. Also hardens the ecdsa signTxRequest assertions to check length > 0 instead of truthiness (an empty array is truthy), and types the transactionRequestFull info field on PendingApprovalInfo. Refs: DEFI-961
6b43c46 to
f6e054b
Compare
Problem
Approving a message-sign pending approval (WalletConnect
personal_sign/ EIP-712eth_signTypedData_v4) crashes the SDK with:The crash is invisible to the PA approval itself — the server-side PUT succeeds (the txRequest moves to
pendingDelivery), but the SDK'spostApprove()unconditionally runs the TSS recreate-and-sign flow forTRANSACTION_REQUEST_FULLPAs, which readstxRequest.transactions[0].unsignedTx.serializedTxHexviarecreateAndSignTSSTransaction→tssUtils.recreateTxRequest→signTxRequest. Message-only txRequests have an emptytransactionsarray (truthy, so the assert passes), makingtransactions[0]undefined and the.unsignedTxread a TypeError.Users see a scary "contact support@bitgo.com" error on a successful approval, then have to re-sign from the request's activity detail (which works because the sign path uses
signAndSendMessageTxRequest— the retail fix in bitgo-retail #10649).Reproduced in prod by emerick (Oct 27) on the retail Tasks page.
Root cause
PendingApproval.postApprove()had no check for message-only requests:The TSS signer's
ecdsa.tsassert checks truthiness (txRequest.transactions || txRequest.unsignedTxs) — an empty array is truthy, sotransactions[0]is undefined.Fix
postApprove()guard — newisMessageSigningRequest()helper reads the PA's echoedinfo.transactionRequestFull.intent.intentTypeand returns early forsignMessage/signTypedStructuredData, skipping the auto recreate-and-sign. The message is signed separately viasignAndSendMessageTxRequestonce the approval resolves.signTxRequestsites changed from truthiness tolength > 0, turning any future empty-array crash into a clear assertion error.PendingApprovalInfonow declarestransactionRequestFullwithintent, so the guard compiles without casts.Testing
modules/bitgo/test/v2/unit/pendingApproval.ts:signMessageintent → auto-sign skipped ✅signTypedStructuredDataintent → auto-sign skipped ✅paymentintent → auto-sign still runs (no false positive) ✅tsc --buildcleanAfter merge
Retail bumps its
@bitgo-beta/sdk-corepin — no retail code change needed (theApprovalApproveForm/useUpdatePendingApprovalMutationpath is correct; the fix is entirely SDK-side).Related