Skip to content

feat(sdk-coin-icp): allow account consolidations (CECHO-2439) - #9955

Merged
hitansh-madan merged 2 commits into
masterfrom
hitanshmadan/cecho-2439-icp-allows-consolidations-v2-tests
Oct 15, 2026
Merged

hitansh-madan merged 2 commits into
masterfrom
hitanshmadan/cecho-2439-icp-allows-consolidations-v2-tests

Conversation

@hitansh-madan

@hitansh-madan hitansh-madan commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Problem

sdk-core's account-consolidation entry points throw before doing any work for coins that don't opt in:

  • BaseCoin.allowsAccountConsolidations() defaults to false (modules/sdk-core/src/statics/baseCoin.ts:175)
  • wallet.buildAccountConsolidations, wallet.sendAccountConsolidation, and wallet.sendAccountConsolidations all gate on it and throw "<coin> does not allow account consolidations." (modules/sdk-core/src/bitgo/wallet/wallet.ts:3836,3887,3929)

sdk-coin-icp never overrode it, so consolidating an ICP wallet through the SDK fails before the request ever reaches the wallet platform — blocking the V2 derived-address consolidation flow (funds sitting on m/1..N receive addresses cannot be swept to the root from SDK-driven clients).

Change

  • modules/sdk-coin-icp/src/icp.ts — override allowsAccountConsolidations() to return true (mirrors TON, modules/sdk-coin-ton/src/ton.ts:101). This is the only production change. The wallet platform remains the eligibility gate and enforces V2-wallets-only (CECHO-2443); the SDK flag only stops the unconditional client-side throw.

Tests

isWalletAddress already branches on walletVersion (from #9758): v1 checks the memo-stripped root at index 0, and the v2 path verifies at params.index via verifyMPCWalletAddress → deriveMPCWalletAddress (unhardened m/{index} from the commonKeychain). What was missing was coverage of the V2 contract beyond index 0 — all existing V2 tests used index 0:

  • V2 derived address at index 1 — the fixture derives the index-1 address exactly the way verifyMPCWalletAddress does (new Ecdsa().deriveUnhardened(commonKeychain, 'm/1'), first 33 bytes → utils.getAddressFromPublicKey), so the expected address is traceable rather than a hardcoded literal. It verifies at index: 1 and is rejected at index: 0, proving the index is actually used in verification.
  • V2 memo rejection — rootAddress?memoId=5 is rejected for a V2 wallet; V2 must never accept memo addresses.
  • Builder pass-through — a transfer built without an explicit memo fills metadata.memo with DEFAULT_MEMO (0); the fee operation keeps the bare sender address; and a memo-suffixed recipient (...?memoId=0) survives building verbatim. Builders never strip suffixes — V1 byte-compatibility and wallet-platform recipient matching both rely on that.

V1 describe blocks are untouched.

CECHO-2439

@linear-code

linear-code Bot commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

CECHO-2439

@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ Unit tests are failing on Node 26.x (Current release line, non-blocking). This is not an LTS version yet, so it does not block merge, but it signals an incompatibility to fix before Node 26.x becomes LTS.

View run

Override allowsAccountConsolidations() so sdk-core buildAccountConsolidations
and sendAccountConsolidation(s) no longer throw for ICP. Mirrors TON
(ton.ts:101); the wallet platform remains the eligibility gate
(V2 wallets only).
…HO-2439)

Derive the index-1 address in the V2 verification fixture the same way
verifyMPCWalletAddress does (unhardened m/1, first 33 bytes) and pin
the V2 contract: the derived address verifies at index 1 and is
rejected at index 0; memo-suffixed addresses are rejected for V2
wallets. Builder pass-through: the fee operation keeps the bare sender
address, and a memo-suffixed recipient survives building verbatim.
@hitansh-madan
hitansh-madan force-pushed the hitanshmadan/cecho-2439-icp-allows-consolidations-v2-tests branch from 77215d4 to 46063f9 Compare October 14, 2026 09:52
@hitansh-madan
hitansh-madan marked this pull request as ready for review October 14, 2026 10:14
@hitansh-madan
hitansh-madan requested a review from a team as a code owner October 14, 2026 10:14
@hitansh-madan
hitansh-madan merged commit d199194 into master Oct 15, 2026
39 of 41 checks passed
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.

2 participants