Skip to content

fix(abstract-utxo): add PoX-5 lockup validator to descriptor policy - #9964

Closed
ralph-bitgo[bot] wants to merge 1 commit into
masterfrom
WAL-2156-pox5-offlinevault-late-exit-pt1
Closed

ralph-bitgo[bot] wants to merge 1 commit into
masterfrom
WAL-2156-pox5-offlinevault-late-exit-pt1

Conversation

@ralph-bitgo

@ralph-bitgo ralph-bitgo Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Description

Summary: add a PoX-5 lockup descriptor validator to the @bitgo/abstract-utxo descriptor policy and make the template validators fail closed instead of throwing.

Motivation and context: the offline vault descriptor policy only knows the 2-of-3 templates, and its template validators throw while probing a descriptor they cannot parse. A custodial PoX-5 staking wallet's descriptor group (named external, internal and the canonical pox5-lockup-u<unlockHeight>-<hash>) therefore fails policy validation before any explanation or signature is produced — which is why the Offline Vault Console cannot explain or co-sign a custodial PoX-5 late exit and custodial unstake validation is blocked (WAL-2156; WAL-2144 matrix, SI-1191 unstake rollout).

What changed:

  • getValidatorPox5Lockup(templateNames): accepts a PoX-5 staking descriptor group — at least one canonical lockup (pox5.parsePox5LockupDescriptor from @bitgo/utxo-descriptors, already a dependency) whose staker keys match the wallet key triple, with the remaining descriptors matching the wallet templates (e.g. the wallet's external/internal descriptors). Malformed, foreign-key and non-canonical lockups are rejected.
  • getPolicyForEnv (prod/adminProd) gains the same PoX-5 group alternative.
  • Template validators now return false for descriptors they cannot parse instead of throwing, so some([...]) falls through to the next validator.

Issue Number

WAL-2156

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

  • @bitgo/abstract-utxo unit tests: mocha --recursive test/unit/ — 1660 passing on this branch.
  • New PoX-5 lockup descriptor policy unit tests: wallet descriptors mixed with a canonical lockup accepted by the PoX-5 validator and by getPolicyForEnv('prod'); negatives for foreign staker keys, malformed (multi(3, ...)) and non-canonical (wsh(pk(...))) lockups, and groups without a lockup; template validators return false instead of throwing on the lockup descriptor.
  • Existing assertDescriptorPolicy tests unchanged — mixed template groups are still rejected.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • My code compiles correctly for both Node and Browser environments
  • I have commented my code, particularly in hard-to-understand areas
  • My commits follow Conventional Commits and I have properly described any BREAKING CHANGES
  • The ticket or github issue was included in the commit message as a reference
  • I have made corresponding changes to the documentation and on any new/updated functions and/or methods - jsdoc
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Stack

This PR is part 1 of 2 in a stack. Review and merge in order:

  1. fix(abstract-utxo): add PoX-5 lockup validator to descriptor policy #9964 — descriptor policy: PoX-5 lockup validator (base: master) ← you are here
  2. fix(abstract-utxo): explain and half-sign PoX-5 late exits in offlineVault #9965 — offlineVault: explain + half-sign PoX-5 late exits (base: WAL-2156-pox5-offlinevault-late-exit-pt1)

A custodial PoX-5 staking wallet's descriptor group (external,
internal and the pox5-lockup descriptor) cannot pass descriptor
policy validation: the template validators only know the 2-of-3
templates and throw while probing the lockup descriptor instead of
failing closed. This blocks offline vault explanation and signing of
custodial PoX-5 late exits (WAL-2156).

- add getValidatorPox5Lockup: accepts a PoX-5 staking descriptor
  group — at least one canonical lockup (parsePox5LockupDescriptor)
  whose staker keys match the wallet key triple, with the remaining
  descriptors matching the wallet templates. Malformed, foreign-key
  and non-canonical lockups are rejected.
- add the PoX-5 group alternative to getPolicyForEnv (prod/adminProd).
- make template validators return false for descriptors they cannot
  parse instead of throwing, so some([...]) falls through to the next
  validator.

Ticket: WAL-2156
Session-Id: 0b46844d-1e64-4dae-af4a-42bb86eedda7
Task-Id: c6ecab00-ae0e-49dc-a2c0-a08cfb1522ec
@linear-code

linear-code Bot commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

WAL-2156

@github-actions

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

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