Skip to content

feat(identity): add HD wallet support for SeedIdentity#270

Open
Kukks wants to merge 14 commits intonextfrom
hd-wallet-support
Open

feat(identity): add HD wallet support for SeedIdentity#270
Kukks wants to merge 14 commits intonextfrom
hd-wallet-support

Conversation

@Kukks
Copy link
Copy Markdown
Contributor

@Kukks Kukks commented Jan 30, 2026

Summary

Adds rudimentary HD (Hierarchical Deterministic) wallet support to SeedIdentity, enabling multiple address derivation while maintaining backwards compatibility.

New Methods on SeedIdentity

  • deriveSigningDescriptor(index) - Derive a signing descriptor at a specific index
  • isOurs(descriptor) - Check if a descriptor belongs to this identity
  • signWithDescriptor(descriptor, requests[]) - Batched transaction signing with descriptor-derived key
  • signMessageWithDescriptor(descriptor, message, type?) - Message signing at specific index

New Methods on ReadonlySeedIdentity

  • deriveSigningDescriptor(index) - Derive a signing descriptor at specific index
  • isOurs(descriptor) - Check if a descriptor belongs to this identity
  • xOnlyPublicKeyAtIndex(index) - Get x-only public key at specific index
  • compressedPublicKeyAtIndex(index) - Get compressed public key at specific index

New Types

  • SigningRequest - Interface for batched signing requests with optional input indexes

Key Design Decisions

Decision Choice Rationale
Interface approach Adjacent methods on SeedIdentity Keeps existing Identity interface stable
Index management External (caller manages) Identity stays stateless, no concurrency issues
Ownership matching Strict (fingerprint + xpub) Prevents false positives from different seeds
Descriptor format String Standard format, wallet interoperability
Signing API Batched requests Efficient for signing multiple UTXOs
Backwards compat Index 0 for legacy methods Existing code works unchanged

Test plan

  • Tests for deriveSigningDescriptor at various indexes
  • Tests for isOurs with own/foreign/invalid descriptors
  • Tests for signWithDescriptor error handling
  • Tests for signMessageWithDescriptor with schnorr/ecdsa
  • Tests for ReadonlySeedIdentity HD methods
  • Backwards compatibility tests verifying existing API unchanged
  • TypeScript compiles without errors

Summary by CodeRabbit

Release Notes

  • New Features

    • HD wallet support via BIP39 mnemonics and seed phrases with descriptor-based recovery
    • Contract management system with lifecycle operations, event tracking, and VTXO handling
    • Watch-only wallet functionality for viewing-only operations
    • New contract types: Default and VHTLC with collaborative and unilateral spending paths
    • arkcontract encoding format for sharing contract data
  • Improvements

    • Storage modernization with improved persistence layer
    • Enhanced contract event subscription and monitoring
  • Chores

    • Added HD wallet and contract management dependencies

✏️ Tip: You can customize this high-level summary in your review settings.

Kukks added 5 commits January 30, 2026 14:52
Introduces SeedIdentity and ReadonlySeedIdentity classes that derive
keys using BIP86 (Taproot) paths. This enables users to transition
to HD wallets while maintaining current single-key behavior.

- SeedIdentity.fromMnemonic() with optional passphrase support
- SeedIdentity.fromSeed() for raw 64-byte seeds
- BIP86 derivation: m/86'/{0|1}'/0'/0/0 (mainnet/testnet)
- Descriptor format: tr([fingerprint/path']xpub.../0/*)
- Strict validation requiring /0/* template for HD compatibility
- JSON serialization with xpub validation on restore
- ReadonlySeedIdentity for watch-only functionality
Add rudimentary HD wallet methods to enable multi-address derivation:

SeedIdentity new methods:
- deriveSigningDescriptor(index): derive descriptor at specific index
- isOurs(descriptor): check if descriptor belongs to this identity
- signWithDescriptor(descriptor, requests): batched transaction signing
- signMessageWithDescriptor(descriptor, message): message signing at index

ReadonlySeedIdentity new methods:
- deriveSigningDescriptor(index): derive descriptor at specific index
- isOurs(descriptor): check if descriptor belongs to this identity
- xOnlyPublicKeyAtIndex(index): get x-only pubkey at index
- compressedPublicKeyAtIndex(index): get compressed pubkey at index

New types:
- SigningRequest: interface for batched signing requests

Backwards compatibility maintained - existing methods work at index 0.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 30, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (1)
  • next-version

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • 🔍 Trigger a full review

Walkthrough

This PR refactors wallet storage from StorageAdapter to a repository pattern, introduces comprehensive contract management (ContractManager, ContractWatcher, handlers), adds HD wallet support via SeedIdentity, and implements IndexedDB and in-memory repository backends with migration utilities.

Changes

Cohort / File(s) Summary
Contract Manager & Watcher
src/contracts/contractManager.ts, src/contracts/contractWatcher.ts
Introduces lifecycle management for contracts with VTXO tracking, event subscription, spending path computation, and automatic watcher integration with reconnection/polling resilience.
Contract Handlers & Registry
src/contracts/handlers/default.ts, src/contracts/handlers/vhtlc.ts, src/contracts/handlers/registry.ts, src/contracts/handlers/helpers.ts, src/contracts/handlers/index.ts
Implements DefaultVtxo and VHTLC contract handlers with serialization, path selection, and CSV/CLTV timelock utilities; establishes handler registry.
ArkContract Encoding
src/contracts/arkcontract.ts, src/contracts/types.ts, src/contracts/index.ts
Adds URL-encoded arkcontract format for compact contract representation, with factory methods for contract creation and validation.
IndexedDB Repository Implementation
src/repositories/indexedDB/db.ts, src/repositories/indexedDB/schema.ts, src/repositories/indexedDB/walletRepository.ts, src/repositories/indexedDB/contractRepository.ts
Implements full IndexedDB persistence layer with schema versioning, serialization/deserialization, and reference counting for database handles.
In-Memory Repository Implementation
src/repositories/inMemory/walletRepository.ts, src/repositories/inMemory/contractRepository.ts
Provides ephemeral, instance-scoped repository implementations for testing and temporary storage.
Repository Refactoring & Migration
src/repositories/contractRepository.ts, src/repositories/walletRepository.ts, src/repositories/migrations/walletRepositoryImpl.ts, src/repositories/migrations/contractRepositoryImpl.ts, src/repositories/migrations/fromStorageAdapter.ts, src/repositories/index.ts
Simplifies ContractRepository interface, introduces CommitmentTxRecord type, and adds migration utilities for legacy StorageAdapter data.
HD Wallet & Identity
src/identity/seedIdentity.ts, src/identity/index.ts
Implements BIP39/BIP32-based SeedIdentity and ReadonlySeedIdentity with descriptor support, JSON serialization, and multi-signature modes (Schnorr/ECDSA).
Wallet Integration
src/wallet/wallet.ts, src/wallet/index.ts, src/wallet/vtxo-manager.ts, src/wallet/serviceWorker/wallet.ts, src/wallet/serviceWorker/worker.ts, src/wallet/serviceWorker/request.ts, src/wallet/serviceWorker/response.ts
Integrates contract management into wallet lifecycle, replaces StorageAdapter with StorageConfig, adds getContractManager() API, and introduces contract-related service worker messages.
Storage Adapter Deprecation
src/storage/index.ts, src/storage/asyncStorage.ts, src/storage/fileSystem.ts, src/storage/inMemory.ts, src/storage/localStorage.ts, src/storage/indexedDB.ts
Marks StorageAdapter-based implementations as deprecated with migration guidance; updates IndexedDBStorageAdapter default version.
Documentation & Configuration
.gitignore, CONTRACTS.md, README.md, package.json
Adds contract management documentation, ignores IndexedDB files, adds BIP32/BIP39/indexeddbshim dependencies, expands README with storage/HD wallet/contract examples.
Examples
examples/contract-manager.ts, examples/node/multiple-wallets.ts, examples/spilman.js
Introduces comprehensive contract manager usage example, multi-wallet persistence demo, and updates existing example to use new storage pattern.
Testing Infrastructure
test/contracts.test.ts, test/contracts/handlers.test.ts, test/contracts/helpers.ts, test/contracts/manager.test.ts, test/contracts/watcher.test.ts, test/repositories/contractRepository.test.ts, test/repositories/walletRepository.test.ts, test/seedIdentity.test.ts, test/storage.test.ts, test/polyfill.js, test/e2e/ark.test.ts
Adds comprehensive test suites for contract system, handlers, repositories, HD wallets, and migrations; updates test polyfills for IndexedDB support.
Public API Surface
src/index.ts
Consolidates public exports of ContractManager, ContractWatcher, handlers, arkcontract utilities, new repository implementations, and SeedIdentity classes; removes deprecated WalletRepositoryImpl/ContractRepositoryImpl.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant ContractManager
    participant ContractWatcher
    participant IndexerProvider
    participant WalletRepository

    Client->>ContractManager: create(config)
    ContractManager->>WalletRepository: initialize + load persisted contracts
    ContractManager->>ContractWatcher: start watching
    
    ContractWatcher->>IndexerProvider: subscribeForScripts(scripts)
    IndexerProvider-->>ContractWatcher: subscription established
    
    IndexerProvider-->>ContractWatcher: vtxo_received event
    ContractWatcher->>ContractManager: handleVtxoReceived(contract, vtxos)
    ContractManager->>WalletRepository: saveContract + VTXO cache
    ContractManager-->>Client: emit contractEvent
    
    Client->>ContractManager: getSpendablePaths(options)
    ContractManager-->>Client: return PathSelection[]
Loading
sequenceDiagram
    participant Wallet
    participant ServiceWorkerWallet
    participant Worker
    participant StorageConfig
    participant IndexedDBWalletRepository
    participant IndexedDBContractRepository

    Wallet.create->>ServiceWorkerWallet: create(config with storage)
    ServiceWorkerWallet->>StorageConfig: resolve walletRepository
    StorageConfig->>IndexedDBWalletRepository: instantiate
    ServiceWorkerWallet->>StorageConfig: resolve contractRepository
    StorageConfig->>IndexedDBContractRepository: instantiate
    ServiceWorkerWallet->>Worker: initialize with repositories
    Worker->>IndexedDBWalletRepository: getVtxos, saveVtxos, etc.
    Worker->>IndexedDBContractRepository: getContracts, saveContract, etc.
    ServiceWorkerWallet-->>Wallet: ready with persistent storage
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related issues

Possibly related PRs

  • Contract Manager #251 — Implements the identical Contract Manager feature set, IndexedDB/InMemory repositories, and modifications across the same contract/repository/wallet files.
  • Deprecate StorageAdapter (new) #259 — Modifies the same storage refactoring surface (deprecating StorageAdapter, adding StorageConfig, new repository implementations, and migrateWalletRepository).
  • V8 #166 — Makes overlapping code-level changes to repositories, storage/IndexedDB adapters, and wallet service-worker storage wiring.

Suggested reviewers

  • bordalix
  • pietro909
  • louisinger
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.28% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(identity): add HD wallet support for SeedIdentity' is specific, concise, and directly describes the main feature addition in the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch hd-wallet-support

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Kukks Kukks changed the base branch from master to next January 30, 2026 21:06
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