Skip to content

Feat/platform wallet#3419

Draft
shumkov wants to merge 172 commits intov3.1-devfrom
feat/platform-wallet
Draft

Feat/platform wallet#3419
shumkov wants to merge 172 commits intov3.1-devfrom
feat/platform-wallet

Conversation

@shumkov
Copy link
Copy Markdown
Collaborator

@shumkov shumkov commented Apr 1, 2026

Issue being fixed or feature implemented

What was done?

How Has This Been Tested?

Breaking Changes

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

QuantumExplorer and others added 30 commits March 5, 2026 14:20
Add DashSync-style identity discovery to PlatformWalletInfo that
scans consecutive DIP-13 authentication key indices and queries
Platform to find registered identities during wallet sync.

New methods:
- discover_identities: gap-limit scan using PublicKeyHash queries
- discover_identities_with_contacts: same + fetches DashPay contacts

Refactors shared key derivation and contact request parsing into
reusable modules used by both discovery and asset lock processing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add [patch] section pointing to local rust-dashcore checkout
- Rename Network::Dash to Network::Mainnet across all packages
  to match the dashcore API change

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Update rust-dashcore rev to 42eb1d69 (Network::Dash→Mainnet, &Wallet fix)
- Add Send+Sync bounds to ContractLookupFn type alias in rs-drive
  (all closures already capture only Send+Sync data; enables tokio::spawn
  compatibility for callers holding ContractLookupFn across await points)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…allets

- PlatformWallet: standalone wallet with CoreWallet, IdentityWallet,
  DashPayWallet, PlatformAddressWallet as stored fields sharing
  Arc<RwLock<ManagedWalletInfo>> and Arc<RwLock<Wallet>>
- PlatformWalletManager: multi-wallet coordinator with SPV adapter
  implementing WalletInterface
- CoreWallet: balance, UTXOs, address generation, transaction history
- IdentityManager: refactored (no sdk field, added last_scanned_index)
- Events: PlatformWalletEvent, SpvEvent, FinalityEvent
- No WalletHandle — PlatformWallet.clone() is cheap (all Arc fields)
- Send+Sync assertions in tests/thread_safety.rs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Module reorganization:
- wallet/core_wallet.rs → wallet/core/wallet.rs
- wallet/identity_wallet.rs → wallet/identity/wallet.rs
- wallet/dashpay_wallet.rs → wallet/dashpay/wallet.rs
- identity_manager/ → wallet/identity/manager.rs (consolidated)
- managed_identity/ → wallet/identity/managed_identity/
- contact_request.rs, established_contact.rs, crypto.rs → wallet/dashpay/

Review fixes:
- Fix coin_type: Devnet/Regtest use 1 (testnet), not 5 (mainnet)
- Fix next_receive/change_address: use account_index with address pools
- Remove unused network param from from_extended_key
- Remove redundant wallet field from PlatformWallet
- Make IdentityManager fields pub(crate)
- Add clone semantics doc, lock ordering comment
- Update PLAN.md paths and PR-1 status

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…alysis

- Add per-address data methods and UI cached snapshot pattern to §1.3.3
- Add asset lock implementation strategy to §1.3.6 (reuse vs port breakdown)
- Add Signer<PlatformAddress> implementation notes to §1.6
- Add IdentitySigner implementation notes to §1.7
- Renumber PR sequence (PR-1 through PR-7)
- Add new PR-2 (CoreWallet Deep Integration) with detailed scope
- Add risks: Wallet/MWI separation, read starvation during block processing,
  non-atomic state updates across structs
- Expand PR-6 (Wallet+MWI merge) with investigation items

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CoreWallet per-address methods:
- CoreAddressInfo, CoreAccountSummary types (wallet/core/types.rs)
- all_address_info(), address_info(), account_summaries(), utxos_by_address()

Signer<PlatformAddress> on PlatformAddressWallet:
- blocking_read() for sync Signer trait with tokio RwLock
- Reverse-maps PlatformAddress → derivation path via platform payment accounts
- Cached network field (no network-guessing fallback)

Asset lock transaction building on CoreWallet:
- build_registration_asset_lock_transaction()
- build_topup_asset_lock_transaction()
- build_asset_lock_transaction() — shared impl with DIP-13 key derivation,
  greedy UTXO selection, two-pass fee calc, AssetLockPayload, P2PKH signing
- AssetLockTransaction error variant

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… payments

CoreWallet per-address methods:
- CoreAddressInfo, CoreAccountSummary types
- all_address_info(), address_info(), account_summaries(), utxos_by_address()

Signer<PlatformAddress> on PlatformAddressWallet:
- Sequential lock acquisition (no dual-lock deadlock window)
- Cached network field

CoreWallet transactions:
- build_registration/topup_asset_lock_transaction() — DIP-9 key derivation,
  UTXO selection, AssetLockPayload, P2PKH signing
- create_registration/topup_asset_lock_proof() — build + broadcast + wait
  via Sdk::wait_for_asset_lock_proof_for_transaction()
- broadcast_transaction() via DAPI
- send_transaction() — full payment flow with correct output-count fee estimation
- Overflow-safe output amount summation

Updated PLAN.md with PR-2 completion status.
Removed old basic_usage example (referenced disabled module).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…entitySigner

IdentitySigner (Signer<IdentityPublicKey>):
- ECDSA, BLS (feature-gated), EdDSA (feature-gated) signing
- DIP-9 authentication key derivation paths
- blocking_read() bridge for sync Signer trait
- Factory: IdentityWallet::signer_for_identity()

IdentityWallet operations (real SDK calls, no TODOs):
- register_identity() — key derivation + put_to_platform_and_wait_for_response
- sync() — gap-limit identity discovery (fully implemented)
- top_up_identity() — TopUpIdentity::top_up_identity + balance update
- withdraw_credits() — WithdrawFromIdentity::withdraw (signer by value)
- transfer_credits() — TransferToIdentity::transfer_credits (signer by value)

Updated PLAN.md with SDK API reference for identity operations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…iew fixes

IdentityWallet (real SDK calls):
- register_identity() with correct 3-component DIP-9 derivation path
- sync() — gap-limit discovery with narrowed lock scope
- top_up_identity(), withdraw_credits(), transfer_credits() — resolve
  identity_index internally from ManagedIdentity (not caller-supplied)

DashPayWallet (simplified API):
- send_contact_request(sender_id, recipient_id) — 2 params, all key
  indices/ECDH/derivation resolved internally
- accept_contact_request(request) — 1 param
- sync_contact_requests(), established_contacts()
- ECDH key type validation, closure parameter validation

IdentitySigner (Signer<IdentityPublicKey>):
- ECDSA/BLS/EdDSA with correct DIP-9 paths
- Private key zeroization via Zeroizing<[u8; 32]>
- pub(crate) visibility for wallet()/identity_index()

Review fixes:
- Derivation path: register_identity now includes key_type' level
- Devnet/Regtest: use testnet derivation path (not error)
- ManagedIdentity.identity_index: u32 (not Option, always required)
- Removed add_identity without index, removed new_with_index
- Contact request: warn+skip on missing properties (not default to 0)
- ECDH: validate encryption key is ECDSA
- eprintln → tracing::warn
- Consolidated redundant lookups and wallet lock acquisitions
- Deleted platform_wallet_info/ (fully replaced by new modules)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PlatformAddressWallet methods:
- sync_balances() — AddressProvider impl with HD gap-limit scanning
- transfer(inputs, outputs) — via Sdk::transfer_address_funds
- withdraw(inputs, output_script, core_fee_per_byte) — via Sdk::withdraw_address_funds
- addresses_with_balances(), total_credits() — cached balance access

Module reorganization:
- platform_address_wallet.rs → platform_addresses/wallet.rs
- PlatformPaymentAddressProvider → platform_addresses/provider.rs

Review fixes:
- Gap limit extends for ANY found address (not just balance > 0)
- Cache removes address when proof returns None
- Log warning on PlatformAddress::from_bytes error
- Provider holds Arc<RwLock<Wallet>> (not clone) for key material safety
- find_private_key returns Zeroizing<[u8; 32]>
- Client-side CoreScript validation (P2PKH/P2SH only)
- Empty-inputs validation on transfer/withdraw

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PR-6 scope: update to latest dashcore v0.42-dev + backport evo-tool fixes.

Key dashcore changes:
- key-wallet-manager merged into key-wallet (crate restructure)
- TransactionContext restructured (BlockInfo, InstantSend variant)
- WalletInterface expanded (mempool, watched_outpoints, IS lock)
- DashSpvClient gained EventHandler generic

Evo-tool backports:
- Mempool support (TransactionStatus, bloom filters, deduplication)
- DAPI error classification
- Key-only address balance display
- DB migration consolidation

Mark PR-1 through PR-5 as complete. Renumber PR-6/7/8.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tten

Architecture diagram: updated with current struct layout (no WalletHandle,
Arc<RwLock<Wallet>>, merged key-wallet-manager, mempool, shielded, tokens)

Updated implementation sections:
- 1.1 Wallet Construction: no wallet field, network cached, balances cache
- 1.2 SDK Integration: full trait inventory (25+ traits across all domains)
- 1.3 Core Wallet: TransactionStatus, broadcast via DAPI, two-pass fee calc
- 1.4 Identity: add_key, top_up_from_addresses, transfer_to_addresses, DPNS
- 1.5 DashPay: simplified 2-param/1-param API, ECDH validation
- 1.6 Platform Addresses: AddressProvider impl, fund_from_asset_lock, gap limit

New sections:
- 1.7 Mempool Support: TransactionStatus lifecycle, SpvWalletAdapter full
  WalletInterface, DashSpvClient EventHandler, bloom filter reconstruction
- 1.8 Token Operations: TokenWallet sub-wallet, transfer/balance/claim/purchase
- 1.9 Shielded Pool: ShieldedWallet with Orchard keys, note/nullifier sync,
  commitment tree, 5 transition types, feature-gated

Renumbered: 1.10 Signing, 1.11 Serialization, 1.12 Sync

PR sequence: 12 PRs (PR-1-5 complete, PR-6-12 planned)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
# Conflicts:
#	Cargo.lock
#	packages/rs-platform-wallet/examples/basic_usage.rs
#	packages/rs-platform-wallet/src/platform_wallet_info/matured_transactions.rs
#	packages/rs-platform-wallet/src/platform_wallet_info/wallet_info_interface.rs
#	packages/rs-platform-wallet/src/platform_wallet_info/wallet_transaction_checker.rs
…Handler

- Add TransactionStatus enum (Unconfirmed → InstantSendLocked → Confirmed → ChainLocked)
  with lifecycle ordering and TransactionStatusChanged event variant
- Implement SpvEventForwarder (dash_spv::EventHandler) forwarding sync, network,
  wallet, and finality events to unified PlatformWalletEvent broadcast channel
- Wire start_spv(config)/stop_spv() on PlatformWalletManager with real
  DashSpvClient<SpvWalletAdapter, PeerNetworkManager, DiskStorageManager> lifecycle
- Enhance SpvWalletAdapter: monitor_revision() for bloom filter staleness,
  process_instant_send_lock() with mark_instant_send_utxos(), populate
  MempoolTransactionResult fields, earliest_required_height from birth height
- Enrich SpvEvent with SyncComplete, PeersUpdated, percentage progress
- Add SpvAlreadyRunning, NoWalletsConfigured, SpvError variants
- Add dash-spv dependency under manager feature gate
- Update PLAN: rewrite PR-6 section, remove cancelled key-wallet-manager crate merge
- Fix Cargo.toml duplicate [workspace.dependencies] from v3.1-dev merge

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- IdentityWallet::update_identity() — add/disable keys via
  IdentityUpdateTransition (nonce lookup, master key signing, broadcast)
- IdentityWallet::top_up_from_addresses() — top up identity by spending
  platform address balances (TopUpIdentityFromAddresses SDK trait)
- IdentityWallet::transfer_credits_to_addresses() — transfer credits from
  identity to multiple platform addresses (TransferToAddresses SDK trait)
- IdentityWallet::register_name() — register DPNS username for an identity
- IdentityWallet::resolve_name() — resolve DPNS name to identity ID
- IdentityWallet::search_names() — search DPNS names by prefix
- PlatformAddressWallet::fund_from_asset_lock() — fund platform addresses
  from Core L1 asset lock (TopUpAddress SDK trait)

All identity fund flows now work: L1→identity, address→identity,
identity→address. Identity keys can be added/disabled. DPNS names
can be registered and resolved.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… tracking

- New TokenWallet sub-wallet on PlatformWallet with registry pattern:
  watch_token/unwatch_token to register tokens for tracking
- sync() queries Platform for balances of all watched tokens across
  all identities, updates local cache
- Balance queries from cache: balance(), balances_for_identity(), all_balances()
- User operations: transfer, purchase, claim
- Admin operations: mint, burn, freeze, unfreeze, set_price
- Shared resolve_identity_and_signer() helper for all token operations
- All operations use SDK builders (TokenTransferTransitionBuilder, etc.)
- Add TokenError variant to PlatformWalletError

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Mark PR-6, PR-7, PR-8 as complete in sequence summary
- Rewrite §1.8 Token Operations with actual implementation:
  per-identity registry, watch/unwatch/sync, balance cache,
  SDK builders for all 8 operations
- Rewrite PR-7 summary with actual delivered methods
- Rewrite PR-8 summary with registry-based design rationale
- Update architecture diagram with TokenWallet fields

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lity events

- CoreWallet: add transaction_statuses map (BTreeMap<Txid, TransactionStatus>)
  with transaction_status(), all_transaction_statuses(), update_transaction_status()
- SpvWalletAdapter: track status on process_block (→ Confirmed),
  process_mempool_transaction (→ Unconfirmed/InstantSendLocked),
  process_instant_send_lock (→ InstantSendLocked); emit
  PlatformWalletEvent::TransactionStatusChanged on transitions
- SpvWalletAdapter: takes platform_event_tx for status change events
- Status updates are monotonic (only forward transitions allowed)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Insert PR-9 (evo-tool integration) immediately after library PRs
  — replace evo-tool backend tasks with platform-wallet calls
  — keep evo-tool SpvManager separate for now
  — detailed migration table for all backend task domains
- Move shielded pool to PR-10 (was PR-9)
- Add PR-11 (SPV migration + AssetLockFinalityEvent) — deferred from PR-6
  — migrate SpvManager to PlatformWalletManager
  — SPV-based finality proof waiting
- Renumber test suite to PR-12, dashcore merge to PR-13, serialization to PR-14
- Mark PR-6 item 4 as deferred to PR-11 with rationale
- Update PR-6 delivered files table with follow-up additions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add TokenWallet as field on PlatformWallet (was separate bracket)
- Add transaction_statuses to CoreWallet struct definition
- Update IdentityManager to Arc<RwLock<IdentityManager>> in struct defs
- Add PR-7 methods to IdentityWallet in architecture diagram
  (update_identity, top_up_from_addresses, DPNS ops)
- Add fund_from_asset_lock to PlatformAddressWallet diagram
- Fix check_core_transaction signature (&Wallet → &mut Wallet)
- Fix PlatformWalletEvent: MempoolTransaction → TransactionStatusChanged
- Fix ShieldedWallet PR reference (PR-9 → PR-10)
- Add IdentityUpdateTransition to SDK operations list
- Add TokenWallet struct definition with watched/balances fields

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- PR-9 now covers ALL domains (tokens, identity, dashpay, core wallet)
- 5 phases: tokens → simple identity → registration/discovery →
  dashpay contacts → core wallet + platform addresses
- Detailed migration tables mapping evo-tool tasks to platform-wallet calls
- Bridge architecture using existing platform_wallet_bridge.rs from PR-1
- Clear separation: what migrates, what stays (SpvManager, DB, UI)
- What gets deleted: direct SDK calls, duplicate crypto code

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add 9 extended token operation methods that accept an external
Signer<IdentityPublicKey> and return full SDK result types. These
are needed by consumers (like evo-tool) that manage their own
identity/signer infrastructure rather than using TokenWallet's
internal resolve_identity_and_signer().

Methods: transfer_with_signer, mint_with_signer, burn_with_signer,
freeze_with_signer, unfreeze_with_signer, set_price_with_signer,
purchase_with_signer, claim_with_signer. Each accepts optional
public_note, group_info, and StateTransitionCreationOptions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add 4 extended identity operation methods that accept an external
Identity + Signer rather than resolving from internal IdentityManager:

- withdraw_credits_with_signer() → Result<u64> (remaining balance)
- transfer_credits_with_signer() → Result<(u64, u64)> (sender/receiver)
- update_identity_with_signer() → Result<StateTransitionProofResult>
- register_name_with_signer() → Result<String> (full domain name)

Needed by evo-tool which manages its own QualifiedIdentity + signer
infrastructure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ull integration

Redraw boundary between platform-wallet and evo-tool. Platform-wallet
should be a complete wallet library that apps can build on, not a thin
SDK wrapper requiring consumers to reimplement protocol-level logic.

Three new library PRs before completing evo-tool integration:

PR-10: Enrich ManagedIdentity
- KeyStorage with PrivateKeyData enum (Clear vs AtWalletDerivationPath)
- IdentityStatus state machine (Unknown → PendingCreation → Active)
- DPNS name association during discovery
- Full key matching (12-key window, ECDSA_HASH160 support)
- Wallet association (seed_hash + wallet_index)

PR-11: Asset lock lifecycle + multi-mode funding
- TrackedAssetLock with AssetLockStatus state machine
- IS→CL fallback (automatic, protocol-level)
- 4 registration modes (UseAssetLock, FundWithWallet, FundWithUtxo, FundFromAddresses)
- 3 top-up modes (UseAssetLock, FundWithWallet, FundWithUtxo)
- UTXO retry on exhaustion

PR-12: DashPay completeness
- DIP-14 256-bit key derivation (ckd_priv_256/ckd_pub_256)
- Contact xpub derivation + account reference (DIP-15)
- Contact payment address derivation + gap limit management
- Payment address registration for SPV detection

PR-13 becomes evo-tool integration Phase 3 using enriched library.
Renumber: shielded → PR-14, SPV migration → PR-15, tests → PR-16,
dashcore merge → PR-17, serialization → PR-18.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
shumkov and others added 30 commits April 7, 2026 01:14
…wallet_and_info

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…anager API

- Rename from_wallet_and_info → new_with_dummy_event (private)
- Rename from_wallet_and_info_with_event_tx → new (the production constructor)
- Add create_wallet_from_seed_bytes() to PlatformWalletManager
  that creates wallets with the shared SPV event channel
- Remove add_wallet() and event_tx() — no longer needed
- Remove from_seed_bytes_with_event_tx — superseded by manager constructor

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…r fields

- Remove duplicated wallets, synced_height, monitor_revision from SpvRuntime
- SpvRuntime holds adapter via Arc<RwLock<SpvWalletAdapter>>, shared with DashSpvClient
- Remove dead platform_event_tx and event_tx fields from SpvWalletAdapter
- monitor_revision is now plain AtomicU64 on adapter (no Arc wrapper)
- SpvRuntime delegates synced_height() and notify_wallets_changed() to adapter
- Adapter created once in new(), not per start() call

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…llet, add PR-27/28 to PLAN

- Move DIP-9 identity auth key derivation from IdentitySigner to
  IdentityWallet as public associated functions
- IdentitySigner and ManagedIdentitySigner now delegate to
  IdentityWallet::derive_identity_key_bytes()
- Add PR-27 (SPV atomics fix) and PR-28 (full SPV replacement) to PLAN.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove FromUtxo from IdentityFunding enum (never implemented)
- Remove FundWithUtxo from IdentityFundingMethod and TopUpFundingMethod
  (evo-tool uses FundWithWallet for QR flow now)
- Remove all match arms and doc references
- Clean up unused Address/TxOut imports

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add broadcast_transaction() — P2P broadcast via DashSpvClient, then
  process in local adapter for immediate wallet update
- Add get_quorum_public_key() — quorum key lookup via SPV masternode state
- Add is_started() — check if SPV client is created
- Add run(config, cancel_token) — start + sync loop until cancelled + cleanup
- Add SpvNotRunning error variant

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…, cleanup

- Add PR-29 (asset lock test coverage) to PLAN.md
- Add doc comments to SpvEventForwarder explaining why it exists
- Remove process_mempool_transaction from broadcast (SPV handles it via bloom filter)
- Minor cleanups in lib.rs, wallet_adapter, changeset traits

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ncState

- Remove `manager` feature flag — SPV/manager code always compiled
- Make key-wallet-manager and dash-spv non-optional dependencies
- Remove all #[cfg(feature = "manager")] guards from events.rs, lib.rs
- Extract synced_height/filter_committed_height/monitor_revision into
  shared SpvSyncState (Arc, no lock) — fixes synced_height() returning 0
  during process_block() when adapter write lock is held
- SpvWalletAdapter and SpvRuntime share Arc<SpvSyncState>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…r handling

- Fix stale broadcast_transaction doc comment (no longer feeds to adapter)
- Fix run() error shadowing — log stop() failures instead of masking
  the actual SPV run result

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…-aware trait

- Change PlatformWalletPersistence trait to &self with wallet_id parameter
  (one persister handles all wallets, can aggregate cross-wallet)
- Move persister from PlatformWallet to PlatformWalletManager
- PlatformWallet holds Arc<dyn Persistence>, calls queue/flush with wallet_id
- create_wallet_from_seed_bytes() now creates, loads state, registers,
  notifies SPV — one call, fully configured, returns Arc<PlatformWallet>
- Remove set_persister() and load_persisted_state() from PlatformWallet
- Remove register_wallet() — registration is internal to create method

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Avoids blocking_write() on tokio RwLock which can deadlock if called
from async context. Uses .write().await instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- queue() → store() (buffer changeset)
- initialize() → load() (load wallet state from storage)
- flush() stays

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…r.rs

WalletPersister wraps Arc<dyn PlatformWalletPersistence> + wallet_id
so callers don't pass wallet_id on every store/flush/load call.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ger (PR-25)

- Add TransactionBroadcaster trait in asset_lock/broadcaster.rs
- DapiBroadcaster implementation (existing DAPI gRPC logic)
- AssetLockManager accepts Arc<dyn TransactionBroadcaster> at construction
- PlatformWallet injects DapiBroadcaster by default
- SPV broadcast can be injected via PlatformWalletManager in the future
- Remove inline DAPI broadcast code from AssetLockManager

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…adcaster

- Move broadcaster.rs from wallet/asset_lock/ to src/ (broadcasting
  is a wallet-level concern, not asset-lock specific)
- Add SpvBroadcaster (delegates to SpvRuntime::broadcast_transaction)
- Remove broadcast_transaction wrapper method from AssetLockManager,
  call self.broadcaster.broadcast() directly

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…(crate)

- Apps should use PlatformWalletManager::broadcast_transaction() or
  AssetLockManager's injected broadcaster, not call SPV directly
- Add broadcast_transaction() convenience method to PlatformWalletManager

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SpvWalletAdapter::subscribe_events() was creating a dead channel
(immediately dropping the sender). The SPV client's event monitor
subscribes to this channel and crashed with "channel closed
unexpectedly". Fix: maintain a live broadcast::Sender<WalletEvent>
on the adapter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…dresses

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ormWalletInfo>

Replace all independent Arc<RwLock<...>> locks in PlatformWallet with
a single Arc<RwLock<PlatformWalletInfo>> per wallet. Sub-wallets
(CoreWallet, IdentityWallet, DashPayWallet, etc.) become facades that
hold the shared lock and manage locking internally.

- Add PlatformWalletInfo struct aggregating all mutable wallet state
- Add WalletCreationOptions struct for create_wallet_from_seed_bytes
- Add birth_height support for SPV filter scan optimization
- Rename field info -> state, getters -> state()/state_mut()/etc.
- Rename WalletInfoWriteGuard -> PlatformWalletInfoWriteGuard
- Update SpvWalletAdapter to use single lock per wallet
- Update example with meaningful API usage
- 76 lib tests pass

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add TransactionBroadcaster to CoreWallet (same pattern as AssetLockManager)
- broadcast_transaction() delegates to broadcaster trait instead of inline DAPI gRPC
- Remove dead methods: next_receive_address_for_account_blocking(),
  next_change_address_for_account_blocking() (0 callers)
- Make next_change_address() pub(crate) (internal only)
- Remove unused consensus import

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use platform_wallet.load_persisted() instead of calling the shared
persister directly with wallet_id. All persistence ops (store, flush,
load) now go through the per-wallet WalletPersister wrapper.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CoreAddressInfo is a UI-only type that doesn't belong in the wallet
library. Move it to dash-evo-tool's platform_wallet_bridge module.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SpvRuntime gains reset_filter_committed_height() so tests can force
a filter rescan when wallet state isn't persisted yet. Also promote
monitored_addresses log to info level for test diagnostics.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…formWallet

State access methods (state, state_mut, state_blocking, try_state,
try_state_mut) are now public on PlatformWallet and pub(crate) on
CoreWallet. External callers use wallet.state() instead of
wallet.core().state(). Sub-wallets remain facades that manage
locking internally.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…nd current status

Add current status section (2026-04-08) reflecting completed locking
refactoring. Add single-lock architecture diagram. Mark old architecture
and struct definitions as outdated. Condense PR history for completed PRs.
Also add TODO notes in CoreWallet and PlatformWallet for future cleanup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add detailed spec for PR-30: replace SpvWalletAdapter, SpvSyncState,
and PlatformWalletInfoWriteGuard with dashcore's WalletManager<T>.
Introduces ManagedWalletState in dashcore, per-wallet Arc<RwLock<T>>
in WalletManager, and BalanceUpdated event-driven balance updates.
Supersedes PR-23 and PR-27. Also update E2E test status to PASS.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PR-20 core API (one-call identity methods + IS→CL fallback) is done in
platform-wallet. PR-21 TransactionBuilder already unified. Remaining
gaps filed as PR-31: switch evo-tool to one-call identity APIs, and
implement asset lock changeset restore (restore_from_changeset_blocking).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…etry path

IdentityFunding needs Clone so evo-tool can retry identity registration
with the same funding method on version-mismatch errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…vWalletAdapter

PR-30 Phase 2: Replace custom SpvWalletAdapter with dashcore's
WalletManager<PlatformWalletInfo> for SPV integration.

Key changes:
- PlatformWalletInfo uses ManagedWalletState<PlatformWalletPersisterBridge>
  for automatic changeset persistence during check_core_transaction (C2)
- Arc<WalletBalance> shared between PlatformWalletInfo and CoreWallet
  for lock-free balance reads; updated via BalanceUpdated events (C1)
- Delete SpvWalletAdapter (~330 lines) — WalletManager implements
  WalletInterface directly
- Delete SpvSyncState (~55 lines) — WalletManager tracks heights
- Delete PlatformWalletInfoWriteGuard — balance via events not Drop
- SpvRuntime holds Arc<RwLock<WalletManager<PlatformWalletInfo>>>
- PlatformWalletManager shares Arc<RwLock<PlatformWalletInfo>> between
  WalletManager (SPV) and PlatformWallet handles (sub-wallets)
- wallets map behind RwLock for interior mutability (&self methods) (W3)
- Trait impls split to platform_wallet_traits.rs (W8)
- Remove dead CoreWallet state accessors (I1)
- PlatformWalletPersisterBridge bridges WalletChangeSet to
  PlatformWalletChangeSet for persistence
- Remove notify_wallets_changed (W5)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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