Monotonically advance the allocation watermark so the next
getNextSigningDescriptor() skips indices discovered by a restore
scan. Never rewinds: a lower or equal index is a no-op.
An invalid index (non-integer / negative) is ignored (no-op):
persisting it would corrupt lastIndexUsed and make the next
parseSettings() throw, mirroring the validation parseSettings
already enforces.
HD providers participate in receive rotation. The default factory boot (contract-repo lookup → allocate fresh descriptor) is exactly what we want, so this just delegates to WalletReceiveRotator.defaultBoot.
Re-derive the descriptor at the most recently allocated index
WITHOUT advancing — i.e. read the same descriptor
getNextSigningDescriptor last returned. Returns undefined
when no descriptor has ever been allocated on this repo.
Used by the boot path to keep the wallet's display address stable across restarts: when no tagged display contract exists (e.g. a fresh wallet that hasn't rotated yet, or a wallet whose baseline-only repo carries no rotation history), the boot should re-derive the existing index rather than burn a new one.
Allocate the next descriptor and return it. The first call on a fresh wallet returns descriptor at index 0; subsequent calls return 1, 2, 3, ... in order. Each call is atomic with respect to other rotations on the same repo: two concurrent callers can never observe the same index.
Returns true when the given descriptor is derivable from this wallet's
seed. Delegates to the underlying identity, which handles both HD and
simple tr(pubkey) descriptors.
Substitute the wildcard in the identity's account-descriptor template
with a concrete index, going through the descriptors-scure parser
rather than ad-hoc string substitution. The parser's expand({ index })
call validates that the input is a ranged template AND produces a
canonical materialized key expression at the given index.
This is a pure read: it does NOT advance the allocation watermark. Used by restore's gap-scan to peek descriptors at arbitrary indices without side-effects.
Signs a message using the key derived from descriptor.
Signs each request with the key derived from its descriptor. Delegates to the identity's signing primitives — the identity, not the provider, holds the seed.
StaticcreateConstruct an HDDescriptorProvider. No I/O is performed here;
persisted state is read lazily on the first call to
getNextSigningDescriptor. A descriptor-mismatch error surfaces on
first use rather than at boot.
HD-wallet DescriptorProvider that allocates a fresh signing descriptor on every call. The provider holds no notion of "current" — it is a pure rotating allocator. The question of "which descriptor is the wallet currently bound to?" is answered by querying the contract repository for active contracts, not by asking this provider.
State is persisted under
WalletRepository.getWalletState().settings.hdso that no storage-schema migration is required when switching a wallet from single-key to HD. The provider is backed by an HDCapableIdentity, which carries the wildcard account descriptor template (for derivation) and the signing primitives.The read-modify-write of the persisted index runs inside the shared per- repo
updateWalletStatemutex, so twogetNextSigningDescriptorcallers — including those driving separateHDDescriptorProviderinstances on the same repo — can never observe the same index.Example