Skip to content

Conversation

@pauldelucia
Copy link
Member

@pauldelucia pauldelucia commented Dec 2, 2025

Summary

  • Implements DIP-0017 (Platform Payment Addresses HD Derivation) and DIP-0018 (Platform Payment Address Encodings)
  • Adds support for Platform Payment addresses with distinct 'D'/'d' (P2PKH) and 'P'/'p' (P2SH) prefixes
  • Platform Payment addresses are for Platform-side value transfers only and are NOT used in Core chain transactions

Changes

dashcore crate

  • Added Platform address version byte constants (0x1e, 0x5a, 0x38, 0x75)
  • Added PlatformP2pkh and PlatformP2sh variants to AddressType enum
  • Added PlatformPubkeyHash and PlatformScriptHash variants to Payload enum
  • Implemented Base58Check encoding/decoding for Platform addresses
  • Added is_platform() method to Address type
  • Added DIP-18 test vectors

key-wallet crate

  • Added FEATURE_PURPOSE_PLATFORM_PAYMENT = 17 constant (DIP-9 feature index)
  • Added PlatformPayment to DerivationPathReference enum
  • Added Platform Payment derivation path definitions (m/9'/coin_type'/17'/account'/key_class'/index)
  • Added PlatformPayment variant to AccountType and ManagedAccountType enums
  • Added new_platform() constructor to AddressPool for Platform address generation
  • Platform addresses are excluded from Core chain transaction checking (per DIP-17 security requirement)

key-wallet-ffi crate

  • Added PlatformPayment to FFIAccountType enum
  • Updated all match statements to handle new variant

Summary by CodeRabbit

  • New Features

    • Added support for Platform Payment addresses (DIP-17/DIP-18): Platform P2PKH and P2SH, display/QR, parsing, and network-specific prefixes.
    • Wallet support for PlatformPayment accounts: creation, address pools, derivation, and transaction matching (treated as non-Core spendable).
  • Tests

    • Added extensive tests for platform address derivation, encoding/decoding, parsing, and round-trip validation on mainnet/testnet.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 2, 2025

Walkthrough

Adds DIP-17/DIP-18 Platform Payment support across crates: new platform address types and prefixes, address encoding/decoding, derivation paths, account types and storage, managed address pools, transaction-checking hooks, FFI bindings, and tests for mainnet/testnet vectors.

Changes

Cohort / File(s) Summary
Core Address Types & Constants
dash/src/address.rs, dash/src/blockdata/constants.rs
Added PlatformP2pkh / PlatformP2sh AddressType variants and PlatformPubkeyHash / PlatformScriptHash payloads; constructors, is_platform(), encoding/decoding (bech32/base58) including platform prefixes; bincode mappings for new types; added platform prefix constants for mainnet/testnet; extended address logic and tests.
Account Type & Derivation Paths
key-wallet/src/account/account_type.rs, key-wallet/src/dip9.rs
Added AccountType::PlatformPayment { account, key_class }; derivation reference PlatformPayment, FEATURE_PURPOSE_PLATFORM_PAYMENT constant, and platform root DerivationPath constants; derivation_path and index handling for PlatformPayment.
Account Collection & Storage
key-wallet/src/account/account_collection.rs
Introduced PlatformPaymentAccountKey and platform_payment_accounts: BTreeMap<...>; integrated insertion, lookup, contains, and aggregation for PlatformPayment accounts.
Managed Accounts & Address Pools
key-wallet/src/managed_account/address_pool.rs, key-wallet/src/managed_account/managed_account_type.rs, key-wallet/src/managed_account/managed_account_collection.rs
Added AddressPool::new_platform and is_platform(); ManagedAccountType::PlatformPayment variant with AddressPool; create/insert/convert logic to build platform pools and managed account entries.
Managed Account Routing & Helpers
key-wallet/src/managed_account/mod.rs, key-wallet/src/wallet/helper.rs
Extended address-pool routing and next-address logic to include PlatformPayment (mirrors DashpayExternalAccount behavior); wallet helper returns None for extended public key for PlatformPayment.
Transaction Checking & Routing
key-wallet/src/transaction_checking/account_checker.rs, key-wallet/src/transaction_checking/transaction_router/mod.rs, key-wallet/src/transaction_checking/wallet_checker.rs
Added AccountTypeMatch::PlatformPayment and AccountTypeToCheck::PlatformPayment; propagated involved_addresses and account_index accessors; ManagedAccountCollection check and wallet checker treat PlatformPayment as platform-only (no Core script matches / no wallet modifications).
FFI Types & Bindings
key-wallet-ffi/include/key_wallet_ffi.h, key-wallet-ffi/src/types.rs
Added PLATFORM_PAYMENT = 13 to FFIAccountType; conversions to/from internal account types updated (conversion path for PlatformPayment; to_account_type panics for unsupported indices).
FFI Account & Address Resolution
key-wallet-ffi/src/address_pool.rs, key-wallet-ffi/src/managed_account.rs, key-wallet-ffi/src/transaction_checking.rs
Explicitly treat PlatformPayment as unsupported/persistent in managed lookup (return None) in pool/managed_account paths; expose PlatformPayment addresses in Single pool where applicable; added PlatformPayment branch in transaction-match conversion (account_type 13, empty internal counts).
Tests
key-wallet/tests/derivation_tests.rs, dash/src/address.rs tests
Added extensive DIP-17/DIP-18 test vectors and round-trip tests for platform P2PKH/P2SH on mainnet and testnet, including key_class variants and generation-from-seed validations.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • Heterogeneous changes across 15+ files spanning address encoding, derivation paths, account storage, managed collections, transaction checking, and FFI.
  • Areas needing focused review:
    • Address encoding/decoding and prefix handling in dash/src/address.rs
    • Derivation path construction and hardened/index logic in key-wallet/src/dip9.rs and account_type.rs
    • Managed account creation and AddressPool::new_platform usage in managed_account modules
    • FFI conversions and panic paths in key-wallet-ffi/src/types.rs
    • Transaction-checking assumptions that PlatformPayment is platform-only (no Core script handling)
    • New test vectors correctness and coverage

"I nibble at code with whiskers bright,
Platform hops in by moonlit night,
Paths and prefixes I gently sow,
Addresses bloom where test-vectors go,
A tiny rabbit cheers the new byte-light." 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: implementation of DIP-17/DIP-18 Platform Payment Addresses, which is the primary objective across all modified files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/platform-addresses

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9f8a29c and 4f3bf50.

📒 Files selected for processing (4)
  • key-wallet/src/account/account_collection.rs (9 hunks)
  • key-wallet/src/account/account_type.rs (5 hunks)
  • key-wallet/src/transaction_checking/account_checker.rs (6 hunks)
  • key-wallet/tests/derivation_tests.rs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.rs: Never hardcode network parameters, addresses, or keys in Rust code
Use proper error types with thiserror crate and propagate errors appropriately in Rust code
Use tokio runtime for async operations in Rust code
Use conditional compilation with feature flags for optional features
Write unit tests for new functionality in Rust
Format Rust code with cargo fmt before committing
Ensure clippy passes with all warnings as errors on all Rust code

**/*.rs: Each crate keeps sources in src/; unit tests live alongside code with #[cfg(test)]
Maintain MSRV of 1.89 for Rust code
Format Rust code with rustfmt (see rustfmt.toml); run cargo fmt --all before commits
Lint Rust code with clippy; avoid unwrap()/expect() in library code; use error types (e.g., thiserror)
Use snake_case for function and variable names in Rust
Use UpperCamelCase for types and traits in Rust
Use SCREAMING_SNAKE_CASE for constants in Rust
Follow mixed editions (2021/2024) and crate-specific idioms; prefer async via tokio where applicable
Unit tests should be placed near code with descriptive names (e.g., test_parse_address_mainnet)
Use #[ignore] for network-dependent or long-running tests; run with -- --ignored flag
Never commit secrets or real keys; avoid logging sensitive data in Rust code
Keep test vectors deterministic in Rust test code

Files:

  • key-wallet/tests/derivation_tests.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
**/tests/**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

**/tests/**/*.rs: Write integration tests for network operations in Rust
Test both mainnet and testnet configurations
Use proptest for property-based testing where appropriate in Rust

Integration tests use tests/ directory (e.g., rpc-integration-test)

Files:

  • key-wallet/tests/derivation_tests.rs
key-wallet/**/tests/**/*.rs

📄 CodeRabbit inference engine (key-wallet/CLAUDE.md)

key-wallet/**/tests/**/*.rs: Use deterministic test vectors with fixed seeds and known test vectors in unit tests for key derivation, mnemonic generation, and address generation to ensure reproducibility
Organize tests by functionality: BIP32 key derivation, mnemonic generation/validation, address generation/validation, path derivation, and PSBT serialization in separate test files

Files:

  • key-wallet/tests/derivation_tests.rs
key-wallet/**/*.rs

📄 CodeRabbit inference engine (key-wallet/CLAUDE.md)

key-wallet/**/*.rs: Never panic in library code; use Result<T> for all fallible operations with custom Error type variants and provide context in error messages
Use ? operator for error propagation in Rust code to maintain clean error handling patterns

Files:

  • key-wallet/tests/derivation_tests.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
key-wallet/**/{account,managed_account}/**/*.rs

📄 CodeRabbit inference engine (key-wallet/CLAUDE.md)

key-wallet/**/{account,managed_account}/**/*.rs: Separate immutable and mutable concerns: Use Account for immutable identity information (keys, derivation paths) and ManagedAccount for mutable state (address pools, metadata, balances)
Use strongly typed enum-based system for AccountType with specific variants (Standard, Identity, Masternode, etc.) to provide compile-time safety for different account purposes

Files:

  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
key-wallet/**/{bip32,derivation,account}/**/*.rs

📄 CodeRabbit inference engine (key-wallet/CLAUDE.md)

Use ExtendedPubKey and ExtendedPrivKey from the BIP32 implementation for key derivation; avoid direct private key exposure or serialization in logs

Files:

  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
key-wallet/**/{wallet,account,managed_account,address_pool}/**/*.rs

📄 CodeRabbit inference engine (key-wallet/CLAUDE.md)

Always validate network consistency: use the account's network type when creating addresses and assert that operations use the expected network to prevent mainnet/testnet mixing

Files:

  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
key-wallet/**/{wallet,account,managed_account}/**/*.rs

📄 CodeRabbit inference engine (key-wallet/CLAUDE.md)

key-wallet/**/{wallet,account,managed_account}/**/*.rs: Use BTreeMap for ordered data structures (accounts, transactions) and HashMap for quick lookups (address to index mapping) to optimize data structure performance
Clearly separate watch-only wallets from full wallets using the wallet type system; never attempt signing operations on watch-only accounts and validate external signatures match expected pubkeys

Files:

  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
key-wallet/**/transaction_checking/**/*.rs

📄 CodeRabbit inference engine (key-wallet/CLAUDE.md)

key-wallet/**/transaction_checking/**/*.rs: Use TransactionRouter::classify_transaction() to determine transaction type and get_relevant_account_types() to avoid checking all accounts for every transaction; route CoinJoin and other specialized transactions only to relevant account types
In SPV sync integration, use wallet_info.check_transaction() with appropriate TransactionContext and update wallet state atomically only when is_relevant flag is true

Files:

  • key-wallet/src/transaction_checking/account_checker.rs
🧠 Learnings (22)
📓 Common learnings
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Keep test vectors updated with Dash Core, monitor for new DIPs affecting wallet structure, maintain backward compatibility for serialized wallets, and update derivation paths for Platform features
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Support future enhancements: prepare architecture for Schnorr/Taproot support, descriptor wallets, native multisig account types, and Lightning Network payment channel key management
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{bip32,derivation,account}/**/*.rs : Use `ExtendedPubKey` and `ExtendedPrivKey` from the BIP32 implementation for key derivation; avoid direct private key exposure or serialization in logs
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/address_pool/**/*.rs : Support multiple `KeySource` variants (Private, Public, NoKeySource) in address pool initialization to enable both full wallets and watch-only wallets with the same interface
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/address_pool/**/*.rs : Pre-generate addresses in batches (typically 20-100) and store in address pools; only derive on-demand when pool is exhausted to optimize performance and memory usage
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/address_pool/**/*.rs : Implement staged gap limit management using `GapLimitStage` structure with tracking of last_used_index and used_indices HashSet to enable efficient address discovery without loading entire address chains into memory
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{wallet,account,managed_account,address_pool}/**/*.rs : Always validate network consistency: use the account's network type when creating addresses and assert that operations use the expected network to prevent mainnet/testnet mixing
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-01T08:01:18.174Z
Learning: Organize workspace with crates: `dash`, `hashes`, `internals`, `dash-network`, `dash-spv`, `key-wallet`, `rpc-*`, utilities (`fuzz`, `test-utils`), and FFI crates (`*-ffi`)
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{account,managed_account}/**/*.rs : Use strongly typed enum-based system for `AccountType` with specific variants (Standard, Identity, Masternode, etc.) to provide compile-time safety for different account purposes
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/tests/**/*.rs : Organize tests by functionality: BIP32 key derivation, mnemonic generation/validation, address generation/validation, path derivation, and PSBT serialization in separate test files

Applied to files:

  • key-wallet/tests/derivation_tests.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Keep test vectors updated with Dash Core, monitor for new DIPs affecting wallet structure, maintain backward compatibility for serialized wallets, and update derivation paths for Platform features

Applied to files:

  • key-wallet/tests/derivation_tests.rs
  • key-wallet/src/account/account_type.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{bip32,derivation,account}/**/*.rs : Use `ExtendedPubKey` and `ExtendedPrivKey` from the BIP32 implementation for key derivation; avoid direct private key exposure or serialization in logs

Applied to files:

  • key-wallet/tests/derivation_tests.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/tests/**/*.rs : Use deterministic test vectors with fixed seeds and known test vectors in unit tests for key derivation, mnemonic generation, and address generation to ensure reproducibility

Applied to files:

  • key-wallet/tests/derivation_tests.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{bip32,derivation}/**/*.rs : Cache intermediate derivation results and use hardened derivation only when required; batch derive child keys when possible to optimize derivation performance

Applied to files:

  • key-wallet/tests/derivation_tests.rs
  • key-wallet/src/account/account_type.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/address_pool/**/*.rs : Support multiple `KeySource` variants (Private, Public, NoKeySource) in address pool initialization to enable both full wallets and watch-only wallets with the same interface

Applied to files:

  • key-wallet/tests/derivation_tests.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
📚 Learning: 2025-12-01T08:00:17.379Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:17.379Z
Learning: Applies to dash-spv/tests/**/*.rs : Add integration tests in the `tests/` directory for comprehensive test suites

Applied to files:

  • key-wallet/tests/derivation_tests.rs
📚 Learning: 2025-12-01T08:00:17.379Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:17.379Z
Learning: Applies to dash-spv/src/**/*.rs : Add comprehensive unit tests in-module for individual components

Applied to files:

  • key-wallet/tests/derivation_tests.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/address_pool/**/*.rs : Pre-generate addresses in batches (typically 20-100) and store in address pools; only derive on-demand when pool is exhausted to optimize performance and memory usage

Applied to files:

  • key-wallet/tests/derivation_tests.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{wallet,account,managed_account,address_pool}/**/*.rs : Always validate network consistency: use the account's network type when creating addresses and assert that operations use the expected network to prevent mainnet/testnet mixing

Applied to files:

  • key-wallet/tests/derivation_tests.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
📚 Learning: 2025-06-15T16:42:18.187Z
Learnt from: QuantumExplorer
Repo: dashpay/rust-dashcore PR: 74
File: key-wallet-ffi/src/lib_tests.rs:41-48
Timestamp: 2025-06-15T16:42:18.187Z
Learning: In key-wallet-ffi, the HDWallet::derive_xpriv method returns Result<String, KeyWalletError>, not an ExtPrivKey wrapper. When unwrapped, it yields a String that can have .is_empty() called on it.

Applied to files:

  • key-wallet/tests/derivation_tests.rs
📚 Learning: 2025-12-01T08:00:17.379Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:17.379Z
Learning: Applies to dash-spv/tests/**/*.rs : Add real network tests with live Dash Core node integration that gracefully handle node unavailability

Applied to files:

  • key-wallet/tests/derivation_tests.rs
📚 Learning: 2025-12-01T07:59:46.015Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-01T07:59:46.015Z
Learning: Applies to **/tests/**/*.rs : Test both mainnet and testnet configurations

Applied to files:

  • key-wallet/tests/derivation_tests.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{account,managed_account}/**/*.rs : Use strongly typed enum-based system for `AccountType` with specific variants (Standard, Identity, Masternode, etc.) to provide compile-time safety for different account purposes

Applied to files:

  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{account,managed_account}/**/*.rs : Separate immutable and mutable concerns: Use `Account` for immutable identity information (keys, derivation paths) and `ManagedAccount` for mutable state (address pools, metadata, balances)

Applied to files:

  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{wallet,account,managed_account}/**/*.rs : Clearly separate watch-only wallets from full wallets using the wallet type system; never attempt signing operations on watch-only accounts and validate external signatures match expected pubkeys

Applied to files:

  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/transaction_checking/**/*.rs : Use `TransactionRouter::classify_transaction()` to determine transaction type and `get_relevant_account_types()` to avoid checking all accounts for every transaction; route CoinJoin and other specialized transactions only to relevant account types

Applied to files:

  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/managed_account/**/*.rs : Implement atomic state updates in ManagedAccount: when processing transactions, update address usage state, UTXO set, transaction history, and balance calculations together to maintain consistency

Applied to files:

  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Support future enhancements: prepare architecture for Schnorr/Taproot support, descriptor wallets, native multisig account types, and Lightning Network payment channel key management

Applied to files:

  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{wallet,account,managed_account}/**/*.rs : Use BTreeMap for ordered data structures (accounts, transactions) and HashMap for quick lookups (address to index mapping) to optimize data structure performance

Applied to files:

  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/transaction_checking/**/*.rs : In SPV sync integration, use `wallet_info.check_transaction()` with appropriate `TransactionContext` and update wallet state atomically only when `is_relevant` flag is true

Applied to files:

  • key-wallet/src/transaction_checking/account_checker.rs
🧬 Code graph analysis (2)
key-wallet/tests/derivation_tests.rs (2)
key-wallet/src/derivation.rs (4)
  • new (64-69)
  • new (161-166)
  • new (200-209)
  • new (366-372)
dash/src/address.rs (2)
  • new (479-499)
  • new (1136-1144)
key-wallet/src/account/account_type.rs (1)
key-wallet/src/transaction_checking/transaction_router/mod.rs (2)
  • from (187-237)
  • from (241-291)
🪛 GitHub Actions: Pre-commit Checks
key-wallet/tests/derivation_tests.rs

[error] 129-129: Siz should be Six or Size (typo) in test comment or expected address


[error] 176-176: Siz should be Six or Size (typo) in test expected address

🪛 Gitleaks (8.30.0)
key-wallet/tests/derivation_tests.rs

[high] 126-126: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 150-150: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 218-218: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 242-242: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 294-294: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 318-318: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: RPC Tests (stable, true)
  • GitHub Check: SPV Components Tests
  • GitHub Check: Key Wallet Components Tests
  • GitHub Check: Core Components Tests
🔇 Additional comments (26)
key-wallet/src/account/account_type.rs (5)

86-95: Well-documented PlatformPayment variant.

The new PlatformPayment variant is properly documented with the DIP-17 path structure and includes an important security warning about not using Platform addresses in Core chain transactions. The field names (account, key_class) align with DIP-17 terminology.


129-131: Consistent mapping to AccountTypeToCheck.

The From<AccountType> implementation correctly maps PlatformPayment to AccountTypeToCheck::PlatformPayment, consistent with the patterns established for other account types and matching the relevant code snippets from transaction_router/mod.rs.


156-159: Correct index extraction for PlatformPayment.

Returns the account field as the index, which aligns with how other indexed account types expose their primary index. This maintains consistency with the index() method's documented behavior.


228-230: Correct derivation path reference mapping.

Maps to DerivationPathReference::PlatformPayment as expected per DIP-17 integration.


413-436: DIP-17 derivation path correctly constructed.

The path construction follows DIP-17: m/9'/coin_type'/17'/account'/key_class' with:

  • Platform root path from constants (network-specific)
  • Hardened account' and key_class' components
  • Leaf index (non-hardened) added during address generation as noted in the comment

The error handling for unsupported networks is consistent with other identity/platform account types.

key-wallet/tests/derivation_tests.rs (6)

3-3: Required import for HASH160 verification.

The Hash trait import enables calling to_byte_array() on the pubkey hash for hex encoding verification against test vectors.


114-129: Comprehensive DIP-17/DIP-18 test documentation.

Excellent documentation header explaining the test suite purpose, mnemonic, and passphrase. The test vector comments clearly document expected values at each derivation stage, enabling easy verification against the DIP specifications.


130-179: Thorough mainnet test vector verification.

This test validates the complete DIP-17 derivation and DIP-18 encoding pipeline:

  1. Seed derivation from mnemonic
  2. Path derivation (m/9'/5'/17'/0'/0'/0)
  3. Private key validation
  4. Public key derivation and validation
  5. HASH160 computation
  6. Platform P2PKH address encoding

The static analysis warnings about "Generic API Key" on lines 126, 150 are false positives - these are deterministic test vector values derived from the well-known "abandon" mnemonic, not real secrets. Based on coding guidelines, test vectors should be deterministic with fixed seeds.


181-214: Testnet address encoding verification.

Correctly tests testnet-specific behavior:

  • Uses coin_type = 1' (testnet) in path
  • Creates HDWallet with Network::Testnet
  • Verifies DIP-18 testnet address encoding (dSqV2... lowercase 'd' prefix)

216-289: Index 1 derivation test with full validation.

Tests non-zero leaf index (/1 instead of /0) for both networks. Validates all intermediate values and final addresses, ensuring index incrementing works correctly in the derivation path.

The Gitleaks warnings on lines 218, 242 are false positives for the same reason as vector 1.


291-365: Non-default key_class test vector.

Important test case validating key_class' = 1' instead of the default 0'. This ensures the key_class component is properly incorporated into the derivation path and produces distinct keys/addresses.

The Gitleaks warnings on lines 294, 318 are false positives - these are test vectors.

key-wallet/src/transaction_checking/account_checker.rs (6)

106-112: PlatformPayment variant correctly captures DIP-17 account structure.

The variant includes account_index and key_class to fully identify the Platform Payment account, along with involved_addresses for any matched addresses. The documentation note about Platform addresses not being used in Core chain transactions is important context.


169-173: Consistent address extraction for PlatformPayment.

Follows the same pattern as DashpayReceivingFunds and DashpayExternalAccount for single-pool account types.


203-207: Correct account_index accessor for PlatformPayment.

Returns the account_index field, consistent with other indexed account types.


254-256: Consistent routing type conversion.

Maps to AccountTypeToCheck::PlatformPayment as expected.


387-392: Correct: PlatformPayment returns empty matches for Core transactions.

This correctly implements the DIP-17 security requirement that Platform Payment addresses are NOT used in Core chain transactions. The transaction router will never find matches for this account type when scanning Core transactions, which is the intended behavior.


648-656: Consider if this code path is reachable for PlatformPayment accounts.

While check_account_type (line 387-392) returns an empty Vec for PlatformPayment, this branch in check_transaction_for_match still constructs a PlatformPayment match. This path would only be reached if check_transaction_for_match is called directly (bypassing check_account_type).

Is there a scenario where Platform Payment accounts are checked for transaction matches outside the normal routing? If not, this branch may be unreachable dead code. If there is such a scenario, consider adding a comment explaining when this path is used.

key-wallet/src/account/account_collection.rs (9)

31-40: Well-structured PlatformPaymentAccountKey.

The key struct follows the same pattern as DashpayAccountKey with appropriate derives for ordering (required for BTreeMap keys), serialization, and encoding. The field documentation clarifies the hardened nature of both components.


75-76: New collection for Platform Payment accounts.

Uses BTreeMap as per coding guidelines for ordered data structures.


98-98: Correct initialization in new().

Platform payment accounts map is properly initialized as empty.


174-183: Correct insert logic for PlatformPayment.

Constructs the PlatformPaymentAccountKey from account and key_class fields and inserts into the correct map.


267-276: Correct contains check for PlatformPayment.

Follows the same pattern as DashpayReceivingFunds for key construction and lookup.


330-339: Correct account_of_type lookup for PlatformPayment.

Follows the same pattern as other account type lookups.


393-402: Correct mutable accessor for PlatformPayment.

Follows the same pattern as account_of_type.


439-442: Platform payment accounts included in all_accounts().

Correctly extends the result with platform_payment_accounts values.


479-482: Platform payment accounts included in all_accounts_mut().

Correctly extends the mutable result with platform_payment_accounts values.


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.

@pauldelucia pauldelucia changed the title Feat/platform addresses feat(key-wallet): Implement DIP17/DIP18 Platform Payment Addresses Dec 2, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
key-wallet/src/account/account_collection.rs (2)

553-576: is_empty() missing check for platform_payment_accounts.

The is_empty() method doesn't include a check for platform_payment_accounts.is_empty(), which means it will incorrectly return true if only PlatformPayment accounts exist.

         && self.provider_owner_keys.is_none();
 
     #[cfg(feature = "bls")]
     {
         is_empty = is_empty && self.provider_operator_keys.is_none();
     }
 
     #[cfg(feature = "eddsa")]
     {
         is_empty = is_empty && self.provider_platform_keys.is_none();
     }
 
+    is_empty = is_empty
+        && self.dashpay_receival_accounts.is_empty()
+        && self.dashpay_external_accounts.is_empty()
+        && self.platform_payment_accounts.is_empty();
+
     is_empty

Note: dashpay_receival_accounts and dashpay_external_accounts also appear to be missing from the is_empty() check.


579-597: clear() missing cleanup for several account maps.

The clear() method doesn't clear dashpay_receival_accounts, dashpay_external_accounts, or the new platform_payment_accounts, which could leave stale data after clearing.

     pub fn clear(&mut self) {
         self.standard_bip44_accounts.clear();
         self.standard_bip32_accounts.clear();
         self.coinjoin_accounts.clear();
         self.identity_registration = None;
         self.identity_topup.clear();
         self.identity_topup_not_bound = None;
         self.identity_invitation = None;
         self.provider_voting_keys = None;
         self.provider_owner_keys = None;
         #[cfg(feature = "bls")]
         {
             self.provider_operator_keys = None;
         }
         #[cfg(feature = "eddsa")]
         {
             self.provider_platform_keys = None;
         }
+        self.dashpay_receival_accounts.clear();
+        self.dashpay_external_accounts.clear();
+        self.platform_payment_accounts.clear();
     }
🧹 Nitpick comments (4)
key-wallet-ffi/src/transaction_checking.rs (1)

458-478: PlatformPayment mapping into FFITransactionCheckResult is correct

The AccountTypeMatch::PlatformPayment arm correctly:

  • propagates account_index, received, and sent,
  • derives external_addresses_count/has_external_addresses from involved_addresses,
  • sets account_type to 13 in line with FFIAccountType::PLATFORM_PAYMENT.

This mirrors DashPay handling and keeps FFI in sync with the new account type, while remaining defensive about platform addresses not being used on Core chain.

If you ever touch this area again, consider defining a shared Rust FFIAccountType enum or constants instead of raw integers (0–13) to avoid accidental drift with the generated C header.

key-wallet/src/managed_account/address_pool.rs (1)

397-418: Platform address pool support is correct; consider tightening PlatformP2sh handling

  • new_platform cleanly reuses new_without_generation, flips address_type to PlatformP2pkh, and optionally pre‑generates up to the gap limit when a key source is available, matching the existing pool semantics but with DIP‑18 address types.
  • is_platform gives a simple, type‑level way to gate Platform pools (e.g., exclude them from Core‑chain transaction checking), which aligns with the DIP‑17 requirement that Platform addresses not be used on Core.
  • Extending generate_address_at_index to call Address::platform_p2pkh for AddressType::PlatformP2pkh is exactly what we want for Platform payment addresses.

The only nuance is the AddressType::PlatformP2sh branch currently defaulting to platform_p2pkh, which is safe but potentially surprising if anyone later assumes genuine P2SH semantics.

Consider, when you need stricter behavior, returning a dedicated error for AddressType::PlatformP2sh in this context (e.g., “PlatformP2sh generation not supported in AddressPool; script required”) instead of silently mapping it to P2PKH. That keeps library code non‑panicking per guidelines while making any misuse explicit.

Also applies to: 425-428, 513-519

key-wallet/src/managed_account/managed_account_collection.rs (1)

730-777: all_accounts() does not include platform_payment_accounts.

The all_accounts() method returns all accounts but does not include platform_payment_accounts. Similarly, all_accounts_mut() (lines 781-828), is_empty() (lines 856-870), and clear() (lines 873-887) also omit this field.

This may be intentional to exclude Platform accounts from Core wallet operations, but could cause issues if these methods are used for wallet-wide operations like serialization or total balance calculation.

If Platform accounts should be accessible via these methods, add them:

 // In all_accounts()
 accounts.extend(self.dashpay_receival_accounts.values());
 accounts.extend(self.dashpay_external_accounts.values());
+accounts.extend(self.platform_payment_accounts.values());

 accounts

 // In is_empty()
 && self.dashpay_receival_accounts.is_empty()
 && self.dashpay_external_accounts.is_empty()
+&& self.platform_payment_accounts.is_empty()

 // In clear()
 self.dashpay_receival_accounts.clear();
 self.dashpay_external_accounts.clear();
+self.platform_payment_accounts.clear();
dash/src/address.rs (1)

535-548: Potential risk: Platform addresses can generate Core-compatible scripts.

The script_pubkey() method generates equivalent P2PKH/P2SH scripts for Platform addresses. While documented with a warning, this could lead to accidental fund loss if a developer calls script_pubkey() on a Platform address and uses it in a Core transaction.

Consider returning an error or a distinct script type for Platform addresses to prevent accidental misuse:

/// Generates a script pubkey spending to this [Payload].
///
/// Note: For Platform addresses, this generates the equivalent Core chain script,
/// but Platform addresses should NOT be used in Core chain transactions.
/// Consider using `script_pubkey_checked()` which returns an error for Platform addresses.
pub fn script_pubkey(&self) -> ScriptBuf {
    // ... existing implementation
}

/// Generates a script pubkey, returning an error for Platform addresses.
pub fn script_pubkey_checked(&self) -> Result<ScriptBuf, Error> {
    if self.is_platform() {
        return Err(Error::PlatformAddressNotForCore);
    }
    Ok(self.script_pubkey())
}

Alternatively, add a runtime check or logging when script_pubkey() is called on Platform addresses to help catch misuse during development.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e24799d and 9f8a29c.

📒 Files selected for processing (19)
  • dash/src/address.rs (17 hunks)
  • dash/src/blockdata/constants.rs (1 hunks)
  • key-wallet-ffi/include/key_wallet_ffi.h (1 hunks)
  • key-wallet-ffi/src/address_pool.rs (2 hunks)
  • key-wallet-ffi/src/managed_account.rs (3 hunks)
  • key-wallet-ffi/src/transaction_checking.rs (1 hunks)
  • key-wallet-ffi/src/types.rs (3 hunks)
  • key-wallet/src/account/account_collection.rs (9 hunks)
  • key-wallet/src/account/account_type.rs (5 hunks)
  • key-wallet/src/dip9.rs (3 hunks)
  • key-wallet/src/managed_account/address_pool.rs (2 hunks)
  • key-wallet/src/managed_account/managed_account_collection.rs (7 hunks)
  • key-wallet/src/managed_account/managed_account_type.rs (6 hunks)
  • key-wallet/src/managed_account/mod.rs (4 hunks)
  • key-wallet/src/transaction_checking/account_checker.rs (6 hunks)
  • key-wallet/src/transaction_checking/transaction_router/mod.rs (3 hunks)
  • key-wallet/src/transaction_checking/wallet_checker.rs (1 hunks)
  • key-wallet/src/wallet/helper.rs (1 hunks)
  • key-wallet/tests/derivation_tests.rs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (11)
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.rs: Never hardcode network parameters, addresses, or keys in Rust code
Use proper error types with thiserror crate and propagate errors appropriately in Rust code
Use tokio runtime for async operations in Rust code
Use conditional compilation with feature flags for optional features
Write unit tests for new functionality in Rust
Format Rust code with cargo fmt before committing
Ensure clippy passes with all warnings as errors on all Rust code

**/*.rs: Each crate keeps sources in src/; unit tests live alongside code with #[cfg(test)]
Maintain MSRV of 1.89 for Rust code
Format Rust code with rustfmt (see rustfmt.toml); run cargo fmt --all before commits
Lint Rust code with clippy; avoid unwrap()/expect() in library code; use error types (e.g., thiserror)
Use snake_case for function and variable names in Rust
Use UpperCamelCase for types and traits in Rust
Use SCREAMING_SNAKE_CASE for constants in Rust
Follow mixed editions (2021/2024) and crate-specific idioms; prefer async via tokio where applicable
Unit tests should be placed near code with descriptive names (e.g., test_parse_address_mainnet)
Use #[ignore] for network-dependent or long-running tests; run with -- --ignored flag
Never commit secrets or real keys; avoid logging sensitive data in Rust code
Keep test vectors deterministic in Rust test code

Files:

  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet/src/dip9.rs
  • key-wallet/src/wallet/helper.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet-ffi/src/address_pool.rs
  • key-wallet-ffi/src/types.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/transaction_router/mod.rs
  • key-wallet-ffi/src/managed_account.rs
  • dash/src/blockdata/constants.rs
  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet/tests/derivation_tests.rs
  • key-wallet-ffi/src/transaction_checking.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
  • dash/src/address.rs
key-wallet/**/transaction_checking/**/*.rs

📄 CodeRabbit inference engine (key-wallet/CLAUDE.md)

key-wallet/**/transaction_checking/**/*.rs: Use TransactionRouter::classify_transaction() to determine transaction type and get_relevant_account_types() to avoid checking all accounts for every transaction; route CoinJoin and other specialized transactions only to relevant account types
In SPV sync integration, use wallet_info.check_transaction() with appropriate TransactionContext and update wallet state atomically only when is_relevant flag is true

Files:

  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet/src/transaction_checking/transaction_router/mod.rs
  • key-wallet/src/transaction_checking/account_checker.rs
key-wallet/**/*.rs

📄 CodeRabbit inference engine (key-wallet/CLAUDE.md)

key-wallet/**/*.rs: Never panic in library code; use Result<T> for all fallible operations with custom Error type variants and provide context in error messages
Use ? operator for error propagation in Rust code to maintain clean error handling patterns

Files:

  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet/src/dip9.rs
  • key-wallet/src/wallet/helper.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/transaction_router/mod.rs
  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet/tests/derivation_tests.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
key-wallet/**/{wallet,account,managed_account,address_pool}/**/*.rs

📄 CodeRabbit inference engine (key-wallet/CLAUDE.md)

Always validate network consistency: use the account's network type when creating addresses and assert that operations use the expected network to prevent mainnet/testnet mixing

Files:

  • key-wallet/src/wallet/helper.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
key-wallet/**/{wallet,account,managed_account}/**/*.rs

📄 CodeRabbit inference engine (key-wallet/CLAUDE.md)

key-wallet/**/{wallet,account,managed_account}/**/*.rs: Use BTreeMap for ordered data structures (accounts, transactions) and HashMap for quick lookups (address to index mapping) to optimize data structure performance
Clearly separate watch-only wallets from full wallets using the wallet type system; never attempt signing operations on watch-only accounts and validate external signatures match expected pubkeys

Files:

  • key-wallet/src/wallet/helper.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
key-wallet/**/{account,managed_account}/**/*.rs

📄 CodeRabbit inference engine (key-wallet/CLAUDE.md)

key-wallet/**/{account,managed_account}/**/*.rs: Separate immutable and mutable concerns: Use Account for immutable identity information (keys, derivation paths) and ManagedAccount for mutable state (address pools, metadata, balances)
Use strongly typed enum-based system for AccountType with specific variants (Standard, Identity, Masternode, etc.) to provide compile-time safety for different account purposes

Files:

  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
key-wallet/**/{bip32,derivation,account}/**/*.rs

📄 CodeRabbit inference engine (key-wallet/CLAUDE.md)

Use ExtendedPubKey and ExtendedPrivKey from the BIP32 implementation for key derivation; avoid direct private key exposure or serialization in logs

Files:

  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
**/*-ffi/src/**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

Careful handling of memory safety at FFI boundaries in Rust code

Files:

  • key-wallet-ffi/src/address_pool.rs
  • key-wallet-ffi/src/types.rs
  • key-wallet-ffi/src/managed_account.rs
  • key-wallet-ffi/src/transaction_checking.rs
key-wallet/**/managed_account/**/*.rs

📄 CodeRabbit inference engine (key-wallet/CLAUDE.md)

Implement atomic state updates in ManagedAccount: when processing transactions, update address usage state, UTXO set, transaction history, and balance calculations together to maintain consistency

Files:

  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
**/tests/**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

**/tests/**/*.rs: Write integration tests for network operations in Rust
Test both mainnet and testnet configurations
Use proptest for property-based testing where appropriate in Rust

Integration tests use tests/ directory (e.g., rpc-integration-test)

Files:

  • key-wallet/tests/derivation_tests.rs
key-wallet/**/tests/**/*.rs

📄 CodeRabbit inference engine (key-wallet/CLAUDE.md)

key-wallet/**/tests/**/*.rs: Use deterministic test vectors with fixed seeds and known test vectors in unit tests for key derivation, mnemonic generation, and address generation to ensure reproducibility
Organize tests by functionality: BIP32 key derivation, mnemonic generation/validation, address generation/validation, path derivation, and PSBT serialization in separate test files

Files:

  • key-wallet/tests/derivation_tests.rs
🧠 Learnings (32)
📓 Common learnings
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Keep test vectors updated with Dash Core, monitor for new DIPs affecting wallet structure, maintain backward compatibility for serialized wallets, and update derivation paths for Platform features
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Support future enhancements: prepare architecture for Schnorr/Taproot support, descriptor wallets, native multisig account types, and Lightning Network payment channel key management
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{bip32,derivation,account}/**/*.rs : Use `ExtendedPubKey` and `ExtendedPrivKey` from the BIP32 implementation for key derivation; avoid direct private key exposure or serialization in logs
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/address_pool/**/*.rs : Support multiple `KeySource` variants (Private, Public, NoKeySource) in address pool initialization to enable both full wallets and watch-only wallets with the same interface
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:17.379Z
Learning: Applies to dash-spv/src/wallet/**/*.rs : Implement wallet functionality with UTXO tracking, balance calculation with confirmation states, and transaction processing
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-01T08:01:18.174Z
Learning: Organize workspace with crates: `dash`, `hashes`, `internals`, `dash-network`, `dash-spv`, `key-wallet`, `rpc-*`, utilities (`fuzz`, `test-utils`), and FFI crates (`*-ffi`)
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: swift-dash-core-sdk/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:50.618Z
Learning: Applies to swift-dash-core-sdk/**/*.rs : Implement new FFI functions in Rust with `#[no_mangle] extern "C"` annotation in dash-spv-ffi
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{account,managed_account}/**/*.rs : Use strongly typed enum-based system for `AccountType` with specific variants (Standard, Identity, Masternode, etc.) to provide compile-time safety for different account purposes
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{wallet,account,managed_account}/**/*.rs : Clearly separate watch-only wallets from full wallets using the wallet type system; never attempt signing operations on watch-only accounts and validate external signatures match expected pubkeys
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/transaction_checking/**/*.rs : Use `TransactionRouter::classify_transaction()` to determine transaction type and `get_relevant_account_types()` to avoid checking all accounts for every transaction; route CoinJoin and other specialized transactions only to relevant account types

Applied to files:

  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet/src/wallet/helper.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet-ffi/src/types.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/transaction_router/mod.rs
  • key-wallet-ffi/src/managed_account.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet-ffi/src/transaction_checking.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{wallet,account,managed_account}/**/*.rs : Clearly separate watch-only wallets from full wallets using the wallet type system; never attempt signing operations on watch-only accounts and validate external signatures match expected pubkeys

Applied to files:

  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet/src/dip9.rs
  • key-wallet/src/wallet/helper.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet-ffi/src/address_pool.rs
  • key-wallet-ffi/src/types.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/transaction_router/mod.rs
  • key-wallet-ffi/src/managed_account.rs
  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet-ffi/src/transaction_checking.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{account,managed_account}/**/*.rs : Use strongly typed enum-based system for `AccountType` with specific variants (Standard, Identity, Masternode, etc.) to provide compile-time safety for different account purposes

Applied to files:

  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet-ffi/include/key_wallet_ffi.h
  • key-wallet/src/dip9.rs
  • key-wallet/src/wallet/helper.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet-ffi/src/address_pool.rs
  • key-wallet-ffi/src/types.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/transaction_router/mod.rs
  • key-wallet-ffi/src/managed_account.rs
  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet-ffi/src/transaction_checking.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
  • dash/src/address.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{wallet,account,managed_account,address_pool}/**/*.rs : Always validate network consistency: use the account's network type when creating addresses and assert that operations use the expected network to prevent mainnet/testnet mixing

Applied to files:

  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet-ffi/src/address_pool.rs
  • key-wallet-ffi/src/types.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/transaction_router/mod.rs
  • key-wallet-ffi/src/managed_account.rs
  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet/tests/derivation_tests.rs
  • key-wallet-ffi/src/transaction_checking.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
  • dash/src/address.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/transaction_checking/**/*.rs : In SPV sync integration, use `wallet_info.check_transaction()` with appropriate `TransactionContext` and update wallet state atomically only when `is_relevant` flag is true

Applied to files:

  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet-ffi/src/transaction_checking.rs
  • key-wallet/src/transaction_checking/account_checker.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/managed_account/**/*.rs : Implement atomic state updates in ManagedAccount: when processing transactions, update address usage state, UTXO set, transaction history, and balance calculations together to maintain consistency

Applied to files:

  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet-ffi/src/address_pool.rs
  • key-wallet-ffi/src/types.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/transaction_router/mod.rs
  • key-wallet-ffi/src/managed_account.rs
  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet-ffi/src/transaction_checking.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{account,managed_account}/**/*.rs : Separate immutable and mutable concerns: Use `Account` for immutable identity information (keys, derivation paths) and `ManagedAccount` for mutable state (address pools, metadata, balances)

Applied to files:

  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet/src/wallet/helper.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet-ffi/src/address_pool.rs
  • key-wallet-ffi/src/types.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/transaction_router/mod.rs
  • key-wallet-ffi/src/managed_account.rs
  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet-ffi/src/transaction_checking.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
📚 Learning: 2025-12-01T08:00:17.379Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:17.379Z
Learning: Applies to dash-spv/src/wallet/**/*.rs : Implement wallet functionality with UTXO tracking, balance calculation with confirmation states, and transaction processing

Applied to files:

  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet/src/transaction_checking/transaction_router/mod.rs
  • key-wallet-ffi/src/transaction_checking.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{bip32,derivation,account}/**/*.rs : Use `ExtendedPubKey` and `ExtendedPrivKey` from the BIP32 implementation for key derivation; avoid direct private key exposure or serialization in logs

Applied to files:

  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet/src/dip9.rs
  • key-wallet/src/wallet/helper.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet-ffi/src/address_pool.rs
  • key-wallet-ffi/src/types.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/transaction_router/mod.rs
  • key-wallet-ffi/src/managed_account.rs
  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet/tests/derivation_tests.rs
  • key-wallet-ffi/src/transaction_checking.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
  • dash/src/address.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{wallet,account,managed_account}/**/*.rs : Use BTreeMap for ordered data structures (accounts, transactions) and HashMap for quick lookups (address to index mapping) to optimize data structure performance

Applied to files:

  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet-ffi/src/address_pool.rs
  • key-wallet-ffi/src/types.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/transaction_router/mod.rs
  • key-wallet-ffi/src/managed_account.rs
  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet-ffi/src/transaction_checking.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Keep test vectors updated with Dash Core, monitor for new DIPs affecting wallet structure, maintain backward compatibility for serialized wallets, and update derivation paths for Platform features

Applied to files:

  • key-wallet/src/dip9.rs
  • dash/src/blockdata/constants.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet/tests/derivation_tests.rs
  • dash/src/address.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/{bip32,derivation}/**/*.rs : Cache intermediate derivation results and use hardened derivation only when required; batch derive child keys when possible to optimize derivation performance

Applied to files:

  • key-wallet/src/dip9.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet/tests/derivation_tests.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/address_pool/**/*.rs : Support multiple `KeySource` variants (Private, Public, NoKeySource) in address pool initialization to enable both full wallets and watch-only wallets with the same interface

Applied to files:

  • key-wallet/src/dip9.rs
  • key-wallet/src/wallet/helper.rs
  • key-wallet/src/account/account_type.rs
  • key-wallet-ffi/src/address_pool.rs
  • key-wallet-ffi/src/types.rs
  • key-wallet/src/account/account_collection.rs
  • key-wallet/src/transaction_checking/transaction_router/mod.rs
  • key-wallet-ffi/src/managed_account.rs
  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet/tests/derivation_tests.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
  • key-wallet/src/transaction_checking/account_checker.rs
  • dash/src/address.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/tests/**/*.rs : Organize tests by functionality: BIP32 key derivation, mnemonic generation/validation, address generation/validation, path derivation, and PSBT serialization in separate test files

Applied to files:

  • key-wallet/src/dip9.rs
  • key-wallet/tests/derivation_tests.rs
  • dash/src/address.rs
📚 Learning: 2025-06-15T15:31:44.136Z
Learnt from: QuantumExplorer
Repo: dashpay/rust-dashcore PR: 74
File: key-wallet/src/address.rs:30-40
Timestamp: 2025-06-15T15:31:44.136Z
Learning: In the key-wallet crate, QuantumExplorer prefers keeping wildcard arms that default unknown Network variants to testnet prefixes rather than using exhaustive matches or panics. This fallback behavior is intentional.

Applied to files:

  • key-wallet/src/wallet/helper.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/*.rs : Never panic in library code; use `Result<T>` for all fallible operations with custom `Error` type variants and provide context in error messages

Applied to files:

  • key-wallet/src/wallet/helper.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Support future enhancements: prepare architecture for Schnorr/Taproot support, descriptor wallets, native multisig account types, and Lightning Network payment channel key management

Applied to files:

  • key-wallet/src/account/account_type.rs
  • key-wallet/src/account/account_collection.rs
  • dash/src/address.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/address_pool/**/*.rs : Implement staged gap limit management using `GapLimitStage` structure with tracking of last_used_index and used_indices HashSet to enable efficient address discovery without loading entire address chains into memory

Applied to files:

  • key-wallet-ffi/src/address_pool.rs
  • key-wallet-ffi/src/managed_account.rs
  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
  • dash/src/address.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/address_pool/**/*.rs : Pre-generate addresses in batches (typically 20-100) and store in address pools; only derive on-demand when pool is exhausted to optimize performance and memory usage

Applied to files:

  • key-wallet-ffi/src/address_pool.rs
  • key-wallet-ffi/src/managed_account.rs
  • key-wallet/src/managed_account/mod.rs
  • key-wallet/src/managed_account/managed_account_type.rs
  • key-wallet/src/managed_account/address_pool.rs
  • key-wallet/tests/derivation_tests.rs
  • dash/src/address.rs
📚 Learning: 2025-06-15T16:42:18.187Z
Learnt from: QuantumExplorer
Repo: dashpay/rust-dashcore PR: 74
File: key-wallet-ffi/src/lib_tests.rs:41-48
Timestamp: 2025-06-15T16:42:18.187Z
Learning: In key-wallet-ffi, the HDWallet::derive_xpriv method returns Result<String, KeyWalletError>, not an ExtPrivKey wrapper. When unwrapped, it yields a String that can have .is_empty() called on it.

Applied to files:

  • key-wallet-ffi/src/types.rs
  • key-wallet/tests/derivation_tests.rs
📚 Learning: 2025-12-01T08:00:50.618Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: swift-dash-core-sdk/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:50.618Z
Learning: Applies to swift-dash-core-sdk/**/*.rs : Implement new FFI functions in Rust with `#[no_mangle] extern "C"` annotation in dash-spv-ffi

Applied to files:

  • dash/src/blockdata/constants.rs
  • dash/src/address.rs
📚 Learning: 2025-06-26T15:47:37.438Z
Learnt from: DCG-Claude
Repo: dashpay/rust-dashcore PR: 0
File: :0-0
Timestamp: 2025-06-26T15:47:37.438Z
Learning: Transaction IDs (txids) and block hashes in Dash are always 32 bytes and should be passed as fixed-size byte arrays in FFI interfaces, not as C strings, to avoid inefficiency and encoding issues.

Applied to files:

  • dash/src/blockdata/constants.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Maintain Minimum Supported Rust Version (MSRV) of 1.89; ensure compatibility with Dash Core versions 0.18.0 - 0.21.0

Applied to files:

  • dash/src/blockdata/constants.rs
📚 Learning: 2025-12-01T08:00:37.919Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:37.919Z
Learning: Applies to key-wallet/**/tests/**/*.rs : Use deterministic test vectors with fixed seeds and known test vectors in unit tests for key derivation, mnemonic generation, and address generation to ensure reproducibility

Applied to files:

  • key-wallet/tests/derivation_tests.rs
📚 Learning: 2025-12-01T08:00:17.379Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:17.379Z
Learning: Applies to dash-spv/tests/**/*.rs : Add integration tests in the `tests/` directory for comprehensive test suites

Applied to files:

  • key-wallet/tests/derivation_tests.rs
  • dash/src/address.rs
📚 Learning: 2025-12-01T08:00:17.379Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:17.379Z
Learning: Applies to dash-spv/src/**/*.rs : Add comprehensive unit tests in-module for individual components

Applied to files:

  • key-wallet/tests/derivation_tests.rs
  • dash/src/address.rs
📚 Learning: 2025-12-01T08:00:17.379Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:17.379Z
Learning: Applies to dash-spv/tests/**/*.rs : Add real network tests with live Dash Core node integration that gracefully handle node unavailability

Applied to files:

  • key-wallet/tests/derivation_tests.rs
  • dash/src/address.rs
📚 Learning: 2025-12-01T07:59:46.015Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-01T07:59:46.015Z
Learning: Applies to **/tests/**/*.rs : Test both mainnet and testnet configurations

Applied to files:

  • key-wallet/tests/derivation_tests.rs
  • dash/src/address.rs
📚 Learning: 2025-12-01T08:00:17.379Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-01T08:00:17.379Z
Learning: Follow a layered architecture with clear separation of concerns: `client/`, `network/`, `storage/`, `sync/`, `validation/`, `wallet/`, `types.rs`, and `error.rs`

Applied to files:

  • key-wallet/src/managed_account/managed_account_collection.rs
📚 Learning: 2025-12-01T08:01:18.174Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-01T08:01:18.174Z
Learning: Organize workspace with crates: `dash`, `hashes`, `internals`, `dash-network`, `dash-spv`, `key-wallet`, `rpc-*`, utilities (`fuzz`, `test-utils`), and FFI crates (`*-ffi`)

Applied to files:

  • dash/src/address.rs
📚 Learning: 2025-12-01T08:01:18.174Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-01T08:01:18.174Z
Learning: Applies to **/*.rs : Unit tests should be placed near code with descriptive names (e.g., `test_parse_address_mainnet`)

Applied to files:

  • dash/src/address.rs
🧬 Code graph analysis (7)
key-wallet/src/account/account_type.rs (1)
key-wallet/src/transaction_checking/transaction_router/mod.rs (2)
  • from (187-237)
  • from (241-291)
key-wallet-ffi/src/types.rs (1)
key-wallet/src/derivation.rs (1)
  • account (224-227)
key-wallet/src/managed_account/managed_account_type.rs (2)
key-wallet/src/managed_account/address_pool.rs (3)
  • network (1135-1138)
  • new_platform (402-418)
  • key_source (1153-1156)
key-wallet/src/bip32.rs (1)
  • master (1302-1304)
key-wallet/tests/derivation_tests.rs (2)
key-wallet/src/derivation.rs (5)
  • from_seed (72-75)
  • new (64-69)
  • new (161-166)
  • new (200-209)
  • new (366-372)
dash/src/address.rs (7)
  • from_str (225-236)
  • from_str (294-297)
  • from_str (1493-1572)
  • encode (949-954)
  • encode (985-990)
  • new (479-499)
  • new (1136-1144)
key-wallet-ffi/src/transaction_checking.rs (1)
key-wallet/src/transaction_checking/account_checker.rs (1)
  • account_index (178-210)
key-wallet/src/managed_account/managed_account_collection.rs (2)
key-wallet/src/account/account_collection.rs (1)
  • new (81-100)
key-wallet/src/managed_account/address_pool.rs (6)
  • new (357-372)
  • new (1094-1104)
  • new_platform (402-418)
  • base_path (1107-1110)
  • network (1135-1138)
  • key_source (1153-1156)
key-wallet/src/transaction_checking/account_checker.rs (2)
key-wallet/src/managed_account/managed_account_collection.rs (1)
  • new (58-75)
key-wallet/src/managed_account/mod.rs (1)
  • new (63-73)
🪛 Gitleaks (8.30.0)
key-wallet/tests/derivation_tests.rs

[high] 126-126: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 227-227: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 310-310: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: RPC Tests (stable, true)
  • GitHub Check: Core Components Tests
  • GitHub Check: SPV Components Tests
  • GitHub Check: fuzz (dash_deserialize_witness)
  • GitHub Check: fuzz (dash_deserialize_script)
  • GitHub Check: fuzz (hashes_sha256)
  • GitHub Check: fuzz (hashes_json)
  • GitHub Check: fuzz (hashes_sha1)
  • GitHub Check: fuzz (hashes_ripemd160)
  • GitHub Check: fuzz (hashes_sha512)
  • GitHub Check: Pre-commit (ubuntu-latest)
  • GitHub Check: fuzz (hashes_sha512_256)
  • GitHub Check: fuzz (dash_deser_net_msg)
  • GitHub Check: fuzz (dash_deserialize_block)
  • GitHub Check: fuzz (hashes_cbor)
  • GitHub Check: fuzz (dash_outpoint_string)
  • GitHub Check: fuzz (dash_deserialize_amount)
  • GitHub Check: fuzz (dash_deserialize_address)
  • GitHub Check: fuzz (dash_script_bytes_to_asm_fmt)
  • GitHub Check: Pre-commit (macos-latest)
🔇 Additional comments (34)
key-wallet/src/wallet/helper.rs (1)

876-880: LGTM! Correct handling of PlatformPayment account type.

The implementation correctly returns None for PlatformPayment accounts, consistent with DIP-17/DIP-18 requirements that Platform Payment addresses are not used for Core chain transactions. This prevents xpub retrieval through this helper for platform-side-only account types.

key-wallet/src/managed_account/mod.rs (1)

247-251: LGTM! Consistent integration of PlatformPayment across address pool methods.

PlatformPayment is correctly grouped with DashpayExternalAccount in all address pool management methods (get_next_address_index, next_address, next_address_with_info, and gap_limit). This maintains consistent behavior for single-pool account types and properly integrates the new variant into the existing address generation and gap limit management flows.

Also applies to: 499-503, 588-592, 817-821

key-wallet/src/transaction_checking/wallet_checker.rs (1)

144-150: LGTM! Appropriate defensive handling for PlatformPayment.

The implementation correctly returns None for PlatformPayment accounts with clear documentation that this branch should never be reached by design. Per DIP-17/DIP-18, Platform Payment addresses are not used in Core chain transactions, so preventing any state updates here is correct. This represents good defensive programming for exhaustive pattern matching.

key-wallet-ffi/src/address_pool.rs (1)

62-67: LGTM! Correct FFI handling for PlatformPayment accounts.

Both helper functions properly handle PlatformPayment by returning None, consistent with the architecture where Platform Payment accounts are not persisted in ManagedAccountCollection. This aligns with DashPay account handling and correctly prevents retrieval of platform-side-only accounts through the FFI boundary.

Also applies to: 111-116

key-wallet-ffi/include/key_wallet_ffi.h (1)

95-99: FFIAccountType extension for PlatformPayment looks consistent

PLATFORM_PAYMENT = 13 cleanly extends the existing 0–12 range and matches the Rust-side mapping in transaction_checking.rs. No behavioral concerns as long as cbindgen and all FFI consumers (Swift, etc.) are regenerated/updated together.

Please confirm that all language bindings consuming FFIAccountType have been re-generated or updated so they see the new PLATFORM_PAYMENT case.

key-wallet/tests/derivation_tests.rs (1)

114-388: DIP‑17/DIP‑18 platform payment test vectors are thorough and deterministic

The new tests validate full paths (including non‑default key_class'), private keys, compressed pubkeys, HASH160, and final PlatformP2PKH encodings on both mainnet and testnet, all derived from a fixed mnemonic. This gives strong regression coverage for the DIP‑17 derivation scheme and DIP‑18 Base58 encodings and matches the deterministic‑vector guidance for key-wallet tests.

dash/src/blockdata/constants.rs (1)

58-71: DIP‑18 platform prefix constants are well‑placed and consistent

Defining PLATFORM_P2PKH_PREFIX_* and PLATFORM_P2SH_PREFIX_* here, alongside the existing pubkey/script prefixes, keeps all Base58 version bytes centralized. The values and doc comments align with the DIP‑18 handling in dash::address and the new platform address tests.

key-wallet/src/transaction_checking/transaction_router/mod.rs (2)

181-183: Correct exclusion from Core chain transaction checking.

The PlatformPayment variant is properly documented as not being checked for Core chain transactions, aligning with the DIP-17 security requirement. The get_relevant_account_types() method correctly excludes PlatformPayment from all transaction type checks (lines 72-128), which is the intended behavior per the PR objectives.


233-235: Consistent conversion implementations for PlatformPayment.

Both From<ManagedAccountType> and From<&ManagedAccountType> implementations correctly map PlatformPayment to AccountTypeToCheck::PlatformPayment, maintaining consistency with other account type conversions.

Also applies to: 287-289

key-wallet/src/dip9.rs (3)

30-30: PlatformPayment derivation reference correctly positioned.

The PlatformPayment = 16 variant is properly sequenced within the DerivationPathReference enum, maintaining the established pattern for new references.


382-419: Platform Payment root paths correctly implement DIP-17 structure.

The root paths (m/9'/5'/17' for mainnet, m/9'/1'/17' for testnet) correctly use:

  • Hardened FEATURE_PURPOSE (9')
  • Hardened coin type (5' for mainnet, 1' for testnet)
  • Hardened FEATURE_PURPOSE_PLATFORM_PAYMENT (17')

The CLEAR_FUNDS path type is appropriate for payment addresses, consistent with other payment-related paths like DashPay.


135-136: DIP-17 feature index constant is correctly defined.

The FEATURE_PURPOSE_PLATFORM_PAYMENT = 17 constant aligns with DIP-17 HD derivation specifications. Test vectors in key-wallet/tests/derivation_tests.rs confirm the constant's correctness with validated derivation paths (m/9'/5'/17'/0'/0'/0) and expected addresses.

key-wallet-ffi/src/types.rs (2)

269-270: FFI enum variant correctly added for PlatformPayment.

The PlatformPayment = 13 variant is properly sequenced and the doc comment correctly references DIP-17/DIP-18 with the derivation path structure.


424-427: Correct extraction of PlatformPayment fields for FFI.

The from_account_type implementation correctly maps account to the primary index and key_class to the optional secondary index, following the established tuple return pattern.

key-wallet-ffi/src/managed_account.rs (3)

533-535: Correct FFI type mapping for PlatformPayment.

The managed_account_get_account_type function correctly maps AccountType::PlatformPayment to FFIAccountType::PlatformPayment, maintaining consistency with other account type conversions.


1019-1022: PlatformPayment correctly exposed via Single address pool.

The managed_account_get_address_pool function correctly handles PlatformPayment by returning its addresses field when FFIAddressPoolType::Single is requested, consistent with other non-standard account types like CoinJoin and Identity accounts.


181-183: PlatformPayment correctly excluded from generic account lookup.

Returning None for PlatformPayment is consistent with how DashpayReceivingFunds and DashpayExternalAccount are handled. This follows the established pattern where account types requiring dedicated handling return None from the generic lookup function.

Currently, no dedicated retrieval function exists for PlatformPayment accounts (unlike the dedicated managed_wallet_get_dashpay_receiving_account and managed_wallet_get_dashpay_external_account functions). If FFI callers need direct access to PlatformPayment accounts, consider adding a similar dedicated function for consistency and completeness.

key-wallet/src/account/account_type.rs (3)

86-95: Well-documented PlatformPayment variant with security warning.

The PlatformPayment variant is properly documented with:

  • DIP-17 reference and path structure
  • DIP-18 encoding format note ("D"/"d" prefix)
  • Critical warning that Platform addresses must not be used in Core chain transactions

The account and key_class fields with their documentation align with DIP-17 path structure.


156-159: Correct primary index extraction for PlatformPayment.

Returning Some(*account) as the primary index is appropriate since account represents the account-level index in the derivation path, similar to how other account types expose their primary index.


413-437: DIP-17 Platform Payment derivation path implementation is correct.

The code correctly implements the DIP-17 path structure (m/9'/coin_type'/17'/account'/key_class') using network-appropriate root path constants and appending hardened indices. Restricting support to Mainnet and Testnet is intentional—no constants are defined in dip9.rs for Regtest/Devnet. This aligns with the design of other Platform-related variants (Masternode, Platform), which similarly support only Mainnet and Testnet.

key-wallet/src/account/account_collection.rs (4)

31-40: Clean key structure for PlatformPayment accounts.

The PlatformPaymentAccountKey struct correctly models the composite key with account and key_class fields, properly deriving necessary traits including Ord for BTreeMap compatibility. The doc comment references DIP-17.


75-76: Consistent storage pattern for PlatformPayment accounts.

Using BTreeMap<PlatformPaymentAccountKey, Account> follows the established pattern for account types with composite keys (like DashPay accounts). Initialization in new() is correct.

Also applies to: 98-98


174-183: Complete CRUD implementation for PlatformPayment.

The insert(), contains_account_type(), account_of_type(), and account_of_type_mut() methods all correctly handle PlatformPayment by constructing the composite key and delegating to the platform_payment_accounts map.

Also applies to: 267-276, 330-336, 390-396


433-435: Aggregation methods include PlatformPayment accounts.

Both all_accounts() and all_accounts_mut() correctly extend their results with platform_payment_accounts.values(), ensuring PlatformPayment accounts are included in collection-wide operations.

Also applies to: 473-475

key-wallet/src/transaction_checking/account_checker.rs (4)

106-112: Well-structured PlatformPayment variant with clear documentation.

The PlatformPayment variant correctly captures account_index, key_class, and involved_addresses, matching the DIP-17 derivation path structure. The doc comment clearly warns that Platform addresses are not used in Core chain transactions.


387-392: Correct enforcement of DIP-17 security requirement.

Returning an empty Vec for AccountTypeToCheck::PlatformPayment correctly implements the DIP-17 mandate that Platform Payment addresses must not be used in Core chain transactions. The comment clearly explains this design decision.


648-654: PlatformPayment match arm correctly extracts account and key_class.

The match arm properly destructures ManagedAccountType::PlatformPayment and constructs the corresponding AccountTypeMatch::PlatformPayment with the correct field mappings.


914-994: find_address_account does not check platform_payment_accounts.

This method searches for addresses across account types but does not include platform_payment_accounts. This is likely intentional per DIP-17 (Platform addresses shouldn't appear in Core transactions), but if Platform addresses should be discoverable for other purposes (e.g., wallet display), this method may need updating in the future.

Confirm this omission is intentional. If Platform addresses should be findable via this method for non-transaction purposes, consider adding:

// Check Platform Payment accounts
for ((account, key_class), account_obj) in &collection.platform_payment_accounts {
    if account_obj.contains_address(address) {
        return Some((AccountTypeToCheck::PlatformPayment, Some(*account)));
    }
}
key-wallet/src/managed_account/managed_account_type.rs (1)

107-118: Clear and well-documented PlatformPayment variant.

The variant definition includes:

  • DIP-17 derivation path in the doc comment
  • DIP-18 encoding format note
  • Critical warning about not using in Core chain transactions
  • Appropriate fields matching the derivation path structure
key-wallet/src/managed_account/managed_account_collection.rs (2)

52-53: Platform payment accounts field follows established patterns.

The platform_payment_accounts field uses BTreeMap<PlatformPaymentAccountKey, ManagedAccount> consistent with other keyed account collections like dashpay_receival_accounts. This follows the coding guideline to use BTreeMap for ordered data structures.

Also applies to: 73-73


607-624: Consistent Platform account creation in factory method.

The create_managed_account_from_account_type correctly uses AddressPool::new_platform() for Platform Payment accounts, ensuring addresses are generated with the correct PlatformP2pkh address type.

dash/src/address.rs (3)

201-206: Platform address types clearly documented with usage warning.

The PlatformP2pkh and PlatformP2sh variants include clear doc comments explaining they are for Dash Platform only and MUST NOT be used in Core chain transactions. This is critical for preventing fund loss.


2296-2422: Comprehensive DIP-18 test coverage.

The tests cover:

  • Mainnet and testnet P2PKH Platform addresses with DIP-18 vectors
  • Multiple test vectors for different HASH160 values
  • P2SH Platform addresses
  • Round-trip parsing verification
  • Distinction between Platform and Core addresses
  • is_platform() flag verification

This provides strong confidence in the DIP-18 implementation correctness.


1005-1006: bincode serialization uses sequential integer values.

Values 5 and 6 are assigned for PlatformP2pkh and PlatformP2sh respectively, continuing the sequence from P2tr = 4. This maintains backward compatibility for existing serialized data.

Also applies to: 1024-1025

Comment on lines +1551 to +1567
// DIP-18: Platform address prefixes
PLATFORM_P2PKH_PREFIX_MAIN => (
Network::Dash,
Payload::PlatformPubkeyHash(PubkeyHash::from_slice(&data[1..]).unwrap()),
),
PLATFORM_P2SH_PREFIX_MAIN => (
Network::Dash,
Payload::PlatformScriptHash(ScriptHash::from_slice(&data[1..]).unwrap()),
),
PLATFORM_P2PKH_PREFIX_TEST => (
Network::Testnet,
Payload::PlatformPubkeyHash(PubkeyHash::from_slice(&data[1..]).unwrap()),
),
PLATFORM_P2SH_PREFIX_TEST => (
Network::Testnet,
Payload::PlatformScriptHash(ScriptHash::from_slice(&data[1..]).unwrap()),
),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check platform prefix constant values in constants.rs
rg -n "PLATFORM_P2PKH_PREFIX_MAIN|PLATFORM_P2PKH_PREFIX_TEST|PLATFORM_P2SH_PREFIX_MAIN|PLATFORM_P2SH_PREFIX_TEST" dash/src/blockdata/constants.rs

Repository: dashpay/rust-dashcore

Length of output: 263


🏁 Script executed:

#!/bin/bash
# Check the context around the parsing code and verify it's in library code
# Also check if from_slice can fail
head -20 dash/src/address.rs | head -5
echo "---"
# Check the from_slice implementations
rg -A 5 "impl.*from_slice" dash/src/ | head -50

Repository: dashpay/rust-dashcore

Length of output: 219


🏁 Script executed:

#!/bin/bash
# Check if from_slice implementations can fail (return Result/Option)
rg -B 2 -A 8 "fn from_slice" dash/src/address.rs | head -40

Repository: dashpay/rust-dashcore

Length of output: 47


🏁 Script executed:

#!/bin/bash
# Verify the exact code lines to confirm unwrap() usage
sed -n '1551,1567p' dash/src/address.rs

Repository: dashpay/rust-dashcore

Length of output: 837


Replace unwrap() calls with proper error handling in library code.

The DIP-18 prefix constant mappings are correct (0x1e, 0x38, 0x5a, 0x75 match their respective payload types). However, all four from_slice() calls use .unwrap(), which violates the coding guideline prohibiting unwrap()/expect() in library code. Replace with a proper error type propagation using ? operator or explicit error handling.

🤖 Prompt for AI Agents
In dash/src/address.rs around lines 1551–1567, the match arms call
PubkeyHash::from_slice(...) and ScriptHash::from_slice(...) and then .unwrap(),
which is prohibited in library code; replace each .unwrap() with proper error
propagation (use ? or map_err to convert the slice failure into the function's
error type), update the surrounding function signature/return type if needed to
return a Result, and ensure you construct/propagate a meaningful Address error
variant (or existing error type) so invalid slice parsing returns Err instead of
panicking.

Comment on lines +332 to +339
FFIAccountType::PlatformPayment => {
panic!(
"FFIAccountType::PlatformPayment cannot be converted to AccountType \
without account and key_class indices. The FFI API does not yet \
support passing these values. This is a programming error - \
Platform Payment account creation must use a different API path."
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's look at the actual context around the lines mentioned
cd key-wallet-ffi && head -n 350 src/types.rs | tail -n 50

Repository: dashpay/rust-dashcore

Length of output: 3078


🏁 Script executed:

# Check for the claimed pattern at lines 316-331
cd key-wallet-ffi && sed -n '316,339p' src/types.rs

Repository: dashpay/rust-dashcore

Length of output: 1479


🏁 Script executed:

# Search for existing tests related to PlatformPayment or panic behavior in to_account_type
rg -n "PlatformPayment|to_account_type" key-wallet-ffi/src/ --type rs -A 3 -B 1

Repository: dashpay/rust-dashcore

Length of output: 91


🏁 Script executed:

# Check if there's a test directory and what tests exist
find key-wallet-ffi -type f -name "*.rs" | head -20

Repository: dashpay/rust-dashcore

Length of output: 755


🏁 Script executed:

# Search for tests related to to_account_type or PlatformPayment
rg -n "to_account_type|PlatformPayment" key-wallet-ffi/src --type rust -A 2 -B 1

Repository: dashpay/rust-dashcore

Length of output: 8832


🏁 Script executed:

# Check if there's a types_tests.rs file
find key-wallet-ffi -name "*types*" -o -name "*test*"

Repository: dashpay/rust-dashcore

Length of output: 1144


🏁 Script executed:

# Look at the lib.rs or lib_tests.rs to understand test organization
head -n 50 key-wallet-ffi/src/lib_tests.rs

Repository: dashpay/rust-dashcore

Length of output: 1889


🏁 Script executed:

# Check if there's an error module in this FFI crate
cat key-wallet-ffi/src/error.rs | head -n 100

Repository: dashpay/rust-dashcore

Length of output: 2627


🏁 Script executed:

# Look at the full context of the to_account_type function
rg -B 20 "fn to_account_type" key-wallet-ffi/src/types.rs

Repository: dashpay/rust-dashcore

Length of output: 1053


🏁 Script executed:

# Search for any tests related to PlatformPayment panic
rg -n "test.*platform.*payment|platform.*payment.*panic" key-wallet-ffi/src/types.rs -i

Repository: dashpay/rust-dashcore

Length of output: 47


🏁 Script executed:

# Check the full test section in types.rs to see all tests
sed -n '436,495p' key-wallet-ffi/src/types.rs

Repository: dashpay/rust-dashcore

Length of output: 2497


🏁 Script executed:

# Check if to_account_type is documented anywhere about when it panics
rg -B 10 "pub fn to_account_type" key-wallet-ffi/src/types.rs | head -30

Repository: dashpay/rust-dashcore

Length of output: 563


🏁 Script executed:

# Verify the usage pattern - does PlatformPayment ever get passed to to_account_type in normal code flow?
rg "FFIAccountType::PlatformPayment.*to_account_type|to_account_type.*PlatformPayment" key-wallet-ffi/src

Repository: dashpay/rust-dashcore

Length of output: 47


Add test for PlatformPayment panic behavior to match existing DashPay tests.

The panic for PlatformPayment in to_account_type() follows the established pattern for account types that cannot be converted due to FFI API limitations (DashpayReceivingFunds and DashpayExternalAccount both panic for similar reasons). However, unlike those types which have explicit panic tests (test_dashpay_receiving_funds_to_account_type_panics, test_dashpay_external_account_to_account_type_panics), there is no corresponding test for PlatformPayment. Add a #[should_panic] test at lines 449-452 to verify the panic occurs when attempting to convert FFIAccountType::PlatformPayment to AccountType, similar to the DashPay test pattern.

🤖 Prompt for AI Agents
In key-wallet-ffi/src/types.rs around lines 332 and add test at lines 449-452:
the FFIAccountType::PlatformPayment arm panics when converting to AccountType
but there's no unit test asserting this behavior; add a new #[test] with
#[should_panic] at the indicated lines that constructs
FFIAccountType::PlatformPayment and calls to_account_type() (mirroring the
existing DashPay panic tests) to verify the panic occurs.

Comment on lines +679 to +700
AccountType::PlatformPayment {
account,
key_class,
} => {
// DIP-17: m/9'/coin_type'/17'/account'/key_class'/index
// The leaf index is non-hardened
let path = account_type
.derivation_path(network)
.unwrap_or_else(|_| DerivationPath::master());
let pool = AddressPool::new_platform(
path,
crate::managed_account::address_pool::AddressPoolType::Absent,
DEFAULT_SPECIAL_GAP_LIMIT, // DIP-17 recommends gap limit of 20
network,
key_source,
)?;
Ok(Self::PlatformPayment {
account,
key_class,
addresses: pool,
})
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

rg -n "DEFAULT_SPECIAL_GAP_LIMIT" key-wallet/src/

Repository: dashpay/rust-dashcore

Length of output: 2323


🏁 Script executed:

rg -n "fn new_platform" key-wallet/src/managed_account/address_pool/

Repository: dashpay/rust-dashcore

Length of output: 149


🏁 Script executed:

rg -n "AddressType::PlatformP2pkh" key-wallet/src/managed_account/address_pool/

Repository: dashpay/rust-dashcore

Length of output: 149


🏁 Script executed:

fd "address_pool" key-wallet/src/ -type f

Repository: dashpay/rust-dashcore

Length of output: 235


🏁 Script executed:

rg -n "pub const DEFAULT_SPECIAL_GAP_LIMIT" key-wallet/src/gap_limit.rs -A 2

Repository: dashpay/rust-dashcore

Length of output: 218


🏁 Script executed:

rg -n "impl AddressPool" key-wallet/src/ -A 5

Repository: dashpay/rust-dashcore

Length of output: 1068


🏁 Script executed:

rg -n "fn new_platform" key-wallet/src/managed_account/address_pool.rs -A 15

Repository: dashpay/rust-dashcore

Length of output: 710


🏁 Script executed:

rg -n "DIP-17\|DIP17" key-wallet/src/ -B 2 -A 2

Repository: dashpay/rust-dashcore

Length of output: 47


🏁 Script executed:

rg -n "PlatformP2pkh" key-wallet/src/managed_account/address_pool.rs

Repository: dashpay/rust-dashcore

Length of output: 322


Incorrect gap limit for Platform addresses.

While the implementation correctly uses AddressPool::new_platform() and sets AddressType::PlatformP2pkh, there is a discrepancy: the code uses DEFAULT_SPECIAL_GAP_LIMIT (which is set to 5 in key-wallet/src/gap_limit.rs:23), but the inline comment states "DIP-17 recommends gap limit of 20". The actual gap limit used is 5, not 20.

Either DEFAULT_SPECIAL_GAP_LIMIT should be updated to 20 to match the DIP-17 recommendation, or the comment should be corrected to reflect the actual intended value.

🤖 Prompt for AI Agents
In key-wallet/src/managed_account/managed_account_type.rs around lines 679 to
700, the code uses DEFAULT_SPECIAL_GAP_LIMIT (currently 5) while the comment
claims DIP-17 recommends 20; fix by making the implementation and comment
consistent: either change the call to AddressPool::new_platform to pass 20
explicitly or (preferable) update DEFAULT_SPECIAL_GAP_LIMIT in
key-wallet/src/gap_limit.rs to 20 and keep the comment as-is, then run
tests/formatting to ensure no other code relies on the old value.

@xdustinface
Copy link
Collaborator

Just reopening to trigger CI after pre-commit fix.

@xdustinface xdustinface closed this Dec 2, 2025
@xdustinface xdustinface reopened this Dec 2, 2025
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.

3 participants