Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
67d5ada
refactor(platform-wallet): remove transfer_with_change_address and Fe…
llbartekll Sep 9, 2026
6d17933
refactor(platform-wallet): remove DashpayAddressMatch and the match_i…
llbartekll Sep 9, 2026
a4a85c6
refactor(platform-wallet): remove uncalled public DashPay API
llbartekll Sep 9, 2026
17a4591
refactor(platform-wallet): remove PrivateKeyData/KeyStorage and a ves…
llbartekll Sep 9, 2026
7efe35b
refactor(platform-wallet): remove dead broadcast paths and DapiBroadc…
llbartekll Sep 9, 2026
fc56d5b
refactor(platform-wallet): remove six never-constructed PlatformWalle…
llbartekll Sep 9, 2026
0f0ca28
refactor(platform-wallet): remove top_up.rs and its uncalled convenie…
llbartekll Sep 9, 2026
cc92cdb
refactor(platform-wallet): remove list_tracked_locks_blocking
llbartekll Sep 9, 2026
572f2e8
refactor(platform-wallet): remove ManagedIdentity freshness helpers a…
llbartekll Sep 9, 2026
a27d4a0
refactor(platform-wallet): remove six uncalled IdentityWallet methods
llbartekll Sep 9, 2026
6328352
refactor(platform-wallet): drop dead auto-accept and contact-address …
llbartekll Sep 9, 2026
e91e177
refactor(platform-wallet): remove operations::shield and the Selectio…
llbartekll Sep 9, 2026
8703d0f
refactor(platform-wallet): remove dead items in the shielded layer
llbartekll Sep 9, 2026
6810971
refactor(platform-wallet): remove dead SpvRuntime methods and narrow …
llbartekll Sep 9, 2026
f1973ca
Merge branch 'v4.2-dev' into refactor/wallet-dead-code-rust-core
lklimek Sep 9, 2026
150e7de
fix(platform-wallet): retarget the from_restore_failure test off the …
llbartekll Sep 9, 2026
65b81f5
refactor(platform-wallet): hold event handlers in a plain Vec
llbartekll Sep 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/rs-platform-wallet-ffi/src/memory_explorer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::handle::*;
use crate::types::*;
use crate::{check_ptr, unwrap_option_or_return};
use dpp::identity::accessors::IdentityGettersV0;
use platform_wallet::wallet::identity::state::managed_identity::IdentityStatus;
use platform_wallet::IdentityStatus;

/// Per-wallet snapshot returned by [`platform_wallet_get_in_memory_summary`].
#[repr(C)]
Expand Down
2 changes: 1 addition & 1 deletion packages/rs-platform-wallet/examples/basic_usage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

// --- Asset locks ---
let asset_locks = wallet.asset_locks();
let tracked = asset_locks.list_tracked_locks_blocking();
let tracked = asset_locks.list_tracked_locks().await;
println!("Tracked asset locks: {}", tracked.len());

Ok(())
Expand Down
67 changes: 8 additions & 59 deletions packages/rs-platform-wallet/src/broadcaster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
//! subset of peers while withheld from the rest, and a withheld peer
//! announcing the txid back, an InstantSend lock, or a confirmation proves
//! the network accepted it. Trustless; no DAPI involvement.
//! - [`DapiBroadcaster`] (fallback for wallets without an SPV runtime):
//! submission via DAPI's gRPC endpoint, with every failure conservatively
//! classified as [`BroadcastError::MaybeSent`].
//!
//! A broadcaster whose transport returns before the transaction reaches a
//! mempool would need every failure conservatively classified as
//! [`BroadcastError::MaybeSent`]; the pending-spend fence below is written so
//! such a transport stays safe.

use std::sync::Arc;
use std::time::Duration;
Expand All @@ -26,8 +28,7 @@ use crate::spv::SpvRuntime;
/// never entered the network or its acceptance remains unknown.
///
/// The classification decides whether the transaction's reserved inputs are
/// safe to release for an immediate retry (see
/// `wallet::reservations::broadcast_releasing_on_rejection`).
/// safe to release for an immediate retry.
#[derive(Debug, thiserror::Error)]
pub enum BroadcastError {
/// The network definitively did not take the transaction — a rejection
Expand Down Expand Up @@ -94,65 +95,13 @@ pub trait TransactionBroadcaster: Send + Sync + 'static {
/// with no ceiling there is a deadlock, not a delay.
///
/// The default is "always ready" — correct for any broadcaster with no
/// startup phase of its own, such as [`DapiBroadcaster`], whose gRPC
/// requests carry their own connection handling.
/// startup phase of its own, such as one whose requests carry their own
/// connection handling.
async fn wait_until_ready(&self, _timeout: Duration) -> bool {
true
}
}

/// Broadcasts transactions via Platform's DAPI gRPC endpoint.
///
/// Used by default when no SPV runtime is available.
pub struct DapiBroadcaster {
sdk: Arc<dash_sdk::Sdk>,
}

impl DapiBroadcaster {
pub fn new(sdk: Arc<dash_sdk::Sdk>) -> Self {
Self { sdk }
}
}

#[async_trait]
impl TransactionBroadcaster for DapiBroadcaster {
async fn broadcast(&self, transaction: &Transaction) -> Result<Txid, BroadcastError> {
use dash_sdk::dapi_client::{DapiRequestExecutor, IntoInner, RequestSettings};
use dash_sdk::dapi_grpc::core::v0::BroadcastTransactionRequest;
use dashcore::consensus;

let tx_bytes = consensus::serialize(transaction);

let request = BroadcastTransactionRequest {
transaction: tx_bytes,
allow_high_fees: false,
bypass_limits: false,
};

// Every DAPI failure is classified `MaybeSent`: `sdk.execute` retries
// across nodes internally (RequestSettings::default()), so the error
// surfaced here is only the *last* attempt's — an earlier attempt may
// have delivered the transaction even though the response was lost
// (the classic shape being a node that accepts the tx while its gRPC
// response times out, followed by a retry that fails differently).
// Distinguishing a genuinely pre-send rejection would require
// disabling the internal retries and inspecting transport errors;
// until then the conservative classification keeps reserved inputs
// safe from double-spends at the cost of holding them for the
// reservation TTL.
let _response = self
.sdk
.execute(request, RequestSettings::default())
.await
.into_inner()
.map_err(|e| BroadcastError::MaybeSent {
reason: format!("DAPI broadcast failed: {}", e),
})?;

Ok(transaction.txid())
}
}

/// The SPV broadcast channel: send through P2P peers and await dash-spv's
/// network-acceptance verdict (rust-dashcore#913).
#[async_trait]
Expand Down
10 changes: 5 additions & 5 deletions packages/rs-platform-wallet/src/changeset/changeset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ use key_wallet::wallet::managed_wallet_info::asset_lock_builder::AssetLockFundin
use crate::wallet::asset_lock::tracked::AssetLockStatus;

use crate::changeset::merge::Merge;
use crate::wallet::identity::state::managed_identity::{
BlockTime, DpnsNameInfo, IdentityStatus, ManagedIdentity,
};
use crate::wallet::identity::state::managed_identity::ManagedIdentity;
use crate::wallet::identity::types::block_time::BlockTime;
use crate::wallet::identity::types::identity_status::{DpnsNameInfo, IdentityStatus};
use crate::wallet::identity::{
ContactProfileEntry, ContactRequest, DashPayProfile, EstablishedContact, PaymentEntry,
};
Expand Down Expand Up @@ -749,7 +749,7 @@ impl Merge for CoreChangeSet {
///
/// Carries the per-identity scalars (id / balance / revision + wallet
/// metadata) but NOT the DPP `public_keys` map or the private
/// `KeyStorage`. Keys live in the sibling [`IdentityKeysChangeSet`]
/// key storage. Keys live in the sibling [`IdentityKeysChangeSet`]
/// keyed by `(identity_id, key_id)` so that a simple scalar mutation
/// (e.g. a balance refresh) serializes only the scalar fields without
/// re-serializing every public-key byte and private-key data blob.
Expand Down Expand Up @@ -1128,7 +1128,7 @@ pub struct ContactChangeSet {
pub removed_sent: BTreeSet<SentContactRequestKey>,
/// Incoming contact requests keyed by (owner ← sender).
pub incoming_requests: BTreeMap<ReceivedContactRequestKey, ContactRequestEntry>,
/// Incoming requests explicitly removed (e.g. `remove_incoming_contact_request`).
/// Incoming requests explicitly removed (e.g. by `ignore_sender`).
pub removed_incoming: BTreeSet<ReceivedContactRequestKey>,
/// Newly established contacts keyed by (owner, contact). The full
/// [`EstablishedContact`] is carried so the apply path can rebuild
Expand Down
63 changes: 0 additions & 63 deletions packages/rs-platform-wallet/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use dpp::prelude::{AddressNonce, CoreBlockHeight};
use key_wallet::account::StandardAccountType;
use key_wallet::wallet::managed_wallet_info::asset_lock_builder::AssetLockFundingType;
use key_wallet::wallet::managed_wallet_info::transaction_building::AccountTypePreference;
use key_wallet::Network;

/// Errors that can occur in platform wallet operations
#[derive(Debug, thiserror::Error)]
Expand Down Expand Up @@ -61,9 +60,6 @@ pub enum PlatformWalletError {
#[error("Identity not found: {0}")]
IdentityNotFound(Identifier),

#[error("No primary identity set")]
NoPrimaryIdentity,

#[error("Invalid identity data: {0}")]
InvalidIdentityData(String),

Expand Down Expand Up @@ -111,26 +107,6 @@ pub enum PlatformWalletError {
source: Box<dash_sdk::Error>,
},

#[error(
"DashPay receiving account already exists for identity {identity} with contact {contact} on network {network:?} (account index {account_index})"
)]
DashpayReceivingAccountAlreadyExists {
identity: Identifier,
contact: Identifier,
network: Network,
account_index: u32,
},

#[error(
"DashPay external account already exists for identity {identity} with contact {contact} on network {network:?} (account index {account_index})"
)]
DashpayExternalAccountAlreadyExists {
identity: Identifier,
contact: Identifier,
network: Network,
account_index: u32,
},

#[error("Asset lock transaction failed: {0}")]
AssetLockTransaction(String),

Expand Down Expand Up @@ -717,19 +693,6 @@ pub enum PlatformWalletError {
min_input_amount: Credits,
},

#[error(
"change output amount {change_amount} is below the protocol per-output \
minimum {min_output_amount}; raise the input sum or drop the change \
address so the residual would exceed the minimum"
)]
ChangeBelowMinimumOutput {
/// `Σ inputs − Σ user_outputs` — the residual that would have been
/// routed to the change output.
change_amount: Credits,
/// Per-output minimum from the active platform version.
min_output_amount: Credits,
},

#[error("input sum overflow: caller-supplied input balances exceed u64::MAX")]
InputSumOverflow,

Expand All @@ -739,9 +702,6 @@ pub enum PlatformWalletError {
#[error("Key derivation failed: {0}")]
KeyDerivation(String),

#[error("Wallet is locked — unlock it before performing this operation")]
WalletLocked,

#[error(
"Signer does not bind to wallet {wallet_id}: it derives a different \
BIP44 account-0 xpub (refusing to sign with the wrong seed)"
Expand Down Expand Up @@ -794,9 +754,6 @@ pub enum PlatformWalletError {
#[error("SPV is already running — stop it before starting again")]
SpvAlreadyRunning,

#[error("No wallets configured — add a wallet before starting SPV")]
NoWalletsConfigured,

#[error("SPV error: {0}")]
SpvError(String),

Expand All @@ -812,9 +769,6 @@ pub enum PlatformWalletError {
/// unproven locks share that key.
FinalityTimeout(dashcore::OutPoint),

#[error("Asset lock proof expired (IS proof too old, CL not yet available): {0}")]
AssetLockExpired(String),

#[error("Asset lock transaction not chain-locked, cannot fall back to CL proof: {0}")]
AssetLockNotChainLocked(String),

Expand Down Expand Up @@ -1010,23 +964,6 @@ pub fn is_instant_lock_proof_invalid(error: &dash_sdk::Error) -> bool {
)
}

/// Check whether a platform-wallet error represents a *Core-side*
/// InstantSend lock timeout (the asset-lock manager waited the full
/// timeout for an IS-lock proof and never observed one).
///
/// Companion to [`is_instant_lock_proof_invalid`] (which detects
/// **Platform-side** rejection of an IS proof after one was obtained).
/// Both surfaces trigger the same fallback path in the registration /
/// top-up flow: upgrade the asset-lock to a ChainLock proof and retry.
///
/// The IS-timeout shape comes from
/// [`AssetLockManager::wait_for_proof`](crate::wallet::asset_lock::manager::AssetLockManager),
/// which emits `PlatformWalletError::FinalityTimeout(Txid)` when the
/// 300-second IS deadline elapses.
pub fn is_instant_lock_timeout(error: &PlatformWalletError) -> bool {
matches!(error, PlatformWalletError::FinalityTimeout(_))
}

/// Extract the `InvalidAssetLockProofCoreChainHeightError` (DPP
/// consensus code 10506) from an SDK error if Platform rejected a
/// ChainLock asset-lock proof because Platform's
Expand Down
Loading
Loading