Skip to content

refactor(utxo-descriptors): make PoX-5 a descriptor extension - #9992

Closed
OttoAllmendinger wants to merge 1 commit into
masterfrom
otto/SI-1971-descriptor-extension
Closed

OttoAllmendinger wants to merge 1 commit into
masterfrom
otto/SI-1971-descriptor-extension

Conversation

@OttoAllmendinger

Copy link
Copy Markdown
Contributor

Description

The generic descriptor wallet flow in @bitgo/abstract-utxo had PoX-5 hardcoded into it: the PoX-5 lockup validators in descriptor/validatePolicy.ts, getPolicyForEnv, the offline vault policy and a direct assertPox5SpendPolicy call in the offline vault sign step. This makes PoX-5 one implementation of a generic descriptor extension instead. No behavior change.

  • @bitgo/utxo-descriptors gets a DescriptorExtension interface for special-purpose descriptors that a descriptor wallet holds next to its regular wallet descriptors: isWalletDescriptor(descriptor, walletKeys) says which descriptors are valid for the wallet keys, and assertSpendPolicy(psbt, descriptorMap) refuses PSBTs that spend the extension's inputs incorrectly (a no-op when none of the inputs belong to it).
  • PoX-5 is pox5.descriptorExtension, next to the existing PoX-5 primitives: the canonical lockup descriptor check (moved from validatePolicy.ts) and the spend policy (moved from abstract-utxo/src/offlineVault/descriptor/pox5.ts to pox5/spendPolicy.ts).
  • @bitgo/abstract-utxo no longer mentions PoX-5 outside descriptor/extensions.ts, which is the one place that registers extensions. The descriptor policy uses getValidatorWalletWithExtensions (the regular Wsh2Of3 descriptors together with any extension's descriptors) and the offline vault sign step uses assertExtensionSpendPolicy. getValidatorPox5Lockup and getValidatorPox5Wallet are replaced by these generic functions.

Design note: the extension interface uses plain Descriptor and wallet key types rather than abstract-utxo's NamedDescriptorNative / DescriptorValidationPolicy, so utxo-descriptors does not need those types moved; abstract-utxo wraps each extension into a DescriptorValidationPolicy (getValidatorExtension).

Follow-ups stacked on this: #9987 (PoX-5 early exit in the extension's spend policy) and #9991 (apply extension spend policies when a hot descriptor wallet signs).

Issue Number

Refs: SI-1971

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

  • modules/utxo-descriptors: new test/unit/pox5/extension.ts (descriptor acceptance and rejection, spend policy delegation); full suite 62 passing at this commit.
  • modules/abstract-utxo: npx mocha --recursive test/unit/transaction test/unit/signTransaction.ts test/unit/offlineVault, 418 passing, including the existing offline vault PoX-5 tests unchanged.

Add a DescriptorExtension interface to @bitgo/utxo-descriptors for special
purpose descriptors that a descriptor wallet holds next to its regular wallet
descriptors: an extension says which descriptors are valid for the wallet keys
and refuses PSBTs that spend its inputs incorrectly. PoX-5 lockups are one
implementation (pox5.descriptorExtension), next to the existing PoX-5
primitives.

abstract-utxo no longer knows about PoX-5. The descriptor policy and the
offline vault sign step go through the registered extensions
(getValidatorWalletWithExtensions, assertExtensionSpendPolicy), and
descriptor/extensions.ts is the one place that lists them. getValidatorPox5Lockup,
getValidatorPox5Wallet and offlineVault/descriptor/pox5 are replaced by the
generic equivalents. No behavior change.

Refs: SI-1971
@linear-code

linear-code Bot commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

SI-1971

@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

@OttoAllmendinger

Copy link
Copy Markdown
Contributor Author

Reverted to the previous structure (PoX-5 stays in abstract-utxo for now); closing.

@OttoAllmendinger
OttoAllmendinger deleted the otto/SI-1971-descriptor-extension branch October 16, 2026 13:18
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.

1 participant