From e6ff565f9c88b1a5301de3052e5261c8f749cec0 Mon Sep 17 00:00:00 2001 From: Support Bot Date: Thu, 25 Jun 2026 12:22:04 +0000 Subject: [PATCH] fix(sdk-coin-ada): align isUnsignedSweep in recoverConsolidations with recover recoverConsolidations was checking !userKey && !backupKey && !walletPassphrase to determine whether to treat results as unsigned sweep, while recover() uses only !walletPassphrase. This mismatch meant that providing userKey/backupKey without walletPassphrase would cause recoverConsolidations to expect MPCTx but receive MPCSweepTxs from recover(), silently mangling the return value. Align recoverConsolidations to use !walletPassphrase exclusively, matching the semantics established in recover(). Ticket: COINS-557 Session-Id: c754900c-a984-4fd8-baf3-5fca5a865e3b Task-Id: f9217dca-41de-4d55-a229-617279774136 --- modules/sdk-coin-ada/src/ada.ts | 2 +- modules/sdk-coin-ada/test/unit/ada.ts | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/sdk-coin-ada/src/ada.ts b/modules/sdk-coin-ada/src/ada.ts index 265dcb3e1b..8f2056f232 100644 --- a/modules/sdk-coin-ada/src/ada.ts +++ b/modules/sdk-coin-ada/src/ada.ts @@ -558,7 +558,7 @@ export class Ada extends BaseCoin { * @param {string} [params.endingScanIndex] - receive address index to end scanning at. default to startingScanIndex + 20 (exclusive). */ async recoverConsolidations(params: MPCConsolidationRecoveryOptions): Promise { - const isUnsignedSweep = !params.userKey && !params.backupKey && !params.walletPassphrase; + const isUnsignedSweep = !params.walletPassphrase; const startIdx = params.startingScanIndex || 1; const endIdx = params.endingScanIndex || startIdx + DEFAULT_SCAN_FACTOR; diff --git a/modules/sdk-coin-ada/test/unit/ada.ts b/modules/sdk-coin-ada/test/unit/ada.ts index 8061937fa1..3a3862504e 100644 --- a/modules/sdk-coin-ada/test/unit/ada.ts +++ b/modules/sdk-coin-ada/test/unit/ada.ts @@ -1189,6 +1189,24 @@ describe('ADA', function () { res.should.not.be.empty(); res.transactions.length.should.equal(2); }); + + it('should treat as unsigned sweep when walletPassphrase is absent even if keys are provided', async function () { + // recover() determines isUnsignedSweep solely from !walletPassphrase. + // recoverConsolidations must use the same signal so result handling is consistent. + // Providing userKey/backupKey without walletPassphrase must still produce an unsigned sweep + // (MPCSweepTxs), not silently mangle the result by treating it as a signed MPCTxs. + const res = await basecoin.recoverConsolidations({ + userKey: consolidationWrwUser.userKey, + backupKey: consolidationWrwUser.backupKey, + bitgoKey: consolidationWrwUser.bitgoKey, + // walletPassphrase intentionally omitted + startingScanIndex: 1, + endingScanIndex: 4, + }); + res.should.not.be.empty(); + // unsigned sweep returns MPCSweepTxs shape with txRequests + res.txRequests.length.should.equal(2); + }); }); describe('Recover Transactions Failure:', () => {