Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
2068bdb
feat(swift-sdk): wallet memory explorer + persistor UTXO/sync load (#…
QuantumExplorer May 4, 2026
5e50a0b
fix(rs-platform-wallet): exclude output addresses from auto_select_in…
lklimek May 4, 2026
55ad8f9
fix(rs-platform-wallet): defensive checked arithmetic on Credits in t…
lklimek May 4, 2026
f54ca47
refactor(rs-platform-wallet): collapse estimate_fee_for_inputs_pub wr…
lklimek May 4, 2026
8f6702d
test(rs-platform-wallet): tighten non_fee_target_below_min_input_redi…
lklimek May 4, 2026
f09840a
feat(rs-platform-wallet): typed OnlyOutputAddressesFunded error [CMT-…
lklimek May 4, 2026
07b56d7
fix(rs-platform-wallet): make update_sync_state monotonic per field […
lklimek May 4, 2026
99dcafc
fix(rs-platform-wallet-ffi): map ArithmeticOverflow / OnlyOutputAddre…
lklimek May 4, 2026
952e605
chore(rs-platform-wallet): drop useless vec! in detect_only_output_ad…
lklimek May 4, 2026
c89f0ed
chore(rs-platform-wallet-ffi): replace matches!(_, Err(_)) with is_er…
lklimek May 4, 2026
923992a
Merge branch 'v3.1-dev' into fix/rs-platform-wallet-auto-select-inputs
lklimek May 4, 2026
81af562
Merge branch 'fix/rs-platform-wallet-auto-select-inputs' into fix/rs-…
lklimek May 4, 2026
930c18a
Merge remote-tracking branch 'origin/feat/rs-platform-wallet-e2e' int…
lklimek May 4, 2026
f95b81d
Merge remote-tracking branch 'origin/feat/rs-platform-wallet-e2e' int…
lklimek May 4, 2026
85cfeb3
chore(rs-platform-wallet): fix macOS clippy lints in manager/accessor…
lklimek May 4, 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
25 changes: 13 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 9 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ members = [
]

[workspace.dependencies]
dashcore = { git = "https://github.com/dashpay/rust-dashcore", rev = "ca507a92967ab4ab60dd681de1f736f8cc1d129f" }
dash-network-seeds = { git = "https://github.com/dashpay/rust-dashcore", rev = "ca507a92967ab4ab60dd681de1f736f8cc1d129f" }
dash-spv = { git = "https://github.com/dashpay/rust-dashcore", rev = "ca507a92967ab4ab60dd681de1f736f8cc1d129f" }
dash-spv-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "ca507a92967ab4ab60dd681de1f736f8cc1d129f" }
key-wallet = { git = "https://github.com/dashpay/rust-dashcore", rev = "ca507a92967ab4ab60dd681de1f736f8cc1d129f" }
key-wallet-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "ca507a92967ab4ab60dd681de1f736f8cc1d129f" }
key-wallet-manager = { git = "https://github.com/dashpay/rust-dashcore", rev = "ca507a92967ab4ab60dd681de1f736f8cc1d129f" }
dash-network = { git = "https://github.com/dashpay/rust-dashcore", rev = "ca507a92967ab4ab60dd681de1f736f8cc1d129f" }
dashcore-rpc = { git = "https://github.com/dashpay/rust-dashcore", rev = "ca507a92967ab4ab60dd681de1f736f8cc1d129f" }
dashcore = { git = "https://github.com/dashpay/rust-dashcore", rev = "e2e8fcf852130383b5922d3c2d907dda334296ee" }
dash-network-seeds = { git = "https://github.com/dashpay/rust-dashcore", rev = "e2e8fcf852130383b5922d3c2d907dda334296ee" }
dash-spv = { git = "https://github.com/dashpay/rust-dashcore", rev = "e2e8fcf852130383b5922d3c2d907dda334296ee" }
dash-spv-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "e2e8fcf852130383b5922d3c2d907dda334296ee" }
key-wallet = { git = "https://github.com/dashpay/rust-dashcore", rev = "e2e8fcf852130383b5922d3c2d907dda334296ee" }
key-wallet-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "e2e8fcf852130383b5922d3c2d907dda334296ee" }
key-wallet-manager = { git = "https://github.com/dashpay/rust-dashcore", rev = "e2e8fcf852130383b5922d3c2d907dda334296ee" }
dash-network = { git = "https://github.com/dashpay/rust-dashcore", rev = "e2e8fcf852130383b5922d3c2d907dda334296ee" }
dashcore-rpc = { git = "https://github.com/dashpay/rust-dashcore", rev = "e2e8fcf852130383b5922d3c2d907dda334296ee" }

# Optimize heavy crypto crates even in dev/test builds so that
# Halo 2 proof generation and verification run at near-release speed.
Expand Down
5 changes: 5 additions & 0 deletions packages/rs-platform-wallet-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ bincode = { version = "=2.0.1" }
# Hex used for error diagnostics that include a wallet_id.
hex = "0.4"

# Persistence loader emits structured warnings for skipped /
# corrupt rows so operators can detect snapshot drift without a
# native debugger attached.
tracing = "0.1"

# anyhow surfaces from `KeyType::try_from` / `Purpose::try_from`
# / `SecurityLevel::try_from` in dpp; we need the From impl in
# `error.rs` so `unwrap_result_or_return!` can absorb it.
Expand Down
168 changes: 166 additions & 2 deletions packages/rs-platform-wallet-ffi/src/core_wallet_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,12 @@ fn account_index_of(at: &key_wallet::account::AccountType) -> u32 {
}

/// Per-account balance entry returned by the query FFI. Carries the
/// same `AccountTypeTagFFI` discriminants as `AccountSpecFFI` plus
/// four balance fields from `WalletCoreBalance`.
/// same `AccountTypeTagFFI` discriminants as `AccountSpecFFI`, the four
/// balance fields from `WalletCoreBalance`, and address-pool key-usage
/// totals (`keys_used` / `keys_total`) summed across every pool on the
/// account. The pool counts are meaningful for both funds and keys
/// variants; the explorer surfaces them as the headline number on
/// keys-only rows where balance reads zero by construction.
#[repr(C)]
pub struct AccountBalanceEntryFFI {
pub type_tag: crate::wallet_restore_types::AccountTypeTagFFI,
Expand All @@ -377,6 +381,166 @@ pub struct AccountBalanceEntryFFI {
pub unconfirmed: u64,
pub immature: u64,
pub locked: u64,
pub keys_used: u32,
pub keys_total: u32,
}

// ---------------------------------------------------------------------------
// Diagnostic snapshot FFI types
// ---------------------------------------------------------------------------
//
// All structs here are read-only diagnostic surfaces consumed by the
// iOS memory explorer. Each struct mirrors a `*Snapshot` type in
// `platform-wallet`'s `manager::accessors` module 1:1.

/// Snapshot of [`PlatformAddressSyncManager`] configuration / last-pass
/// timestamp. `last_event_wallet_count` was dropped — it aliased
/// `watch_list_size` and rendering it as an independent field invited
/// confused interpretation.
#[repr(C)]
pub struct PlatformAddressSyncConfigFFI {
pub interval_seconds: u64,
pub watch_list_size: usize,
pub last_event_unix_seconds: u64,
}

/// Snapshot of [`IdentitySyncManager`] configuration / queue depth.
#[repr(C)]
pub struct IdentitySyncConfigFFI {
pub interval_seconds: u64,
pub queue_depth: usize,
}

/// Per-wallet core SPV state.
#[repr(C)]
pub struct CoreWalletStateFFI {
pub synced_height: u32,
pub last_processed_height: u32,
pub monitor_revision: u64,
}

/// Per-wallet identity scan state.
#[repr(C)]
pub struct IdentityWalletStateFFI {
pub last_scanned_index: u32,
pub scan_pending: bool,
}

/// Per-wallet platform address provider state.
#[repr(C)]
pub struct PlatformAddressProviderStateFFI {
pub initialized: bool,
pub accounts_watched: usize,
pub found_count: usize,
pub known_balances_count: usize,
pub watermark_height: u32,
}

// `WalletInfoMetadataFFI` was removed in lockstep with the explorer's
// "PlatformWalletInfo Metadata" section — every meaningful field
// duplicated `CoreWalletStateFFI` or had nothing populating it.

/// One row of the tracked-asset-lock list.
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct TrackedAssetLockEntryFFI {
pub outpoint_txid: [u8; 32],
pub outpoint_vout: u32,
/// 0=IdentityRegistration, 1=IdentityTopUp, 2=IdentityTopUpNotBound,
/// 3=IdentityInvitation, 4=AssetLockAddressTopUp,
/// 5=AssetLockShieldedAddressTopUp.
pub lock_type: u8,
/// 0=Built, 1=Broadcast, 2=InstantSendLocked, 3=ChainLocked.
pub status: u8,
pub registration_index: u32,
pub instant_lock_present: bool,
pub chain_lock_height: u32,
}

/// Snapshot of the per-account metadata for one account. Strings are
/// Per-account metadata snapshot.
///
/// `is_watch_only` and `custom_name` were dropped in lockstep with
/// upstream removing both fields from `ManagedCoreFundsAccount` /
/// `ManagedCoreKeysAccount`. Watch-only is now wallet-level (read off
/// `Wallet.wallet_type`); `AccountMetadata` no longer exists. The
/// struct is now plain-data — no heap-owned fields, no paired free fn
/// strictly required (kept as a stable no-op).
#[repr(C)]
pub struct AccountMetadataFFI {
pub total_transactions: u64,
pub total_utxos: u64,
pub monitor_revision: u64,
}

/// One address row inside [`AccountAddressPoolEntryFFI`]. The pool's
/// own free fn walks the nested array and reclaims it.
///
/// `address` is a heap-owned NUL-terminated UTF-8 string;
/// `public_key_bytes` is a heap-owned byte buffer (`null` +
/// `public_key_bytes_len = 0` when the pool entry didn't retain the
/// derivation source). Both are freed by the parent pool's free fn.
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct AddressInfoFFI {
pub pubkey_hash: [u8; 20],
pub address_index: u32,
pub is_used: bool,
/// `last_used_height` is reserved on the FFI — upstream
/// `AddressInfo` doesn't currently track per-address height. Set
/// to `0`; will be populated when upstream gains the field.
pub last_used_height: u32,
pub address: *mut c_char,
pub public_key_bytes: *mut u8,
pub public_key_bytes_len: usize,
}

/// One pool-level entry inside the per-account address pool snapshot.
/// `addresses` is a heap-owned slice of `AddressInfoFFI`, freed by the
/// paired free fn (which walks every pool first).
#[repr(C)]
pub struct AccountAddressPoolEntryFFI {
/// 0=External, 1=Internal, 2=Absent, 3=AbsentHardened.
pub pool_type: u8,
pub gap_limit: u32,
/// `i64`-encoded; `-1` signals "no addresses used yet".
pub last_used_index: i64,
pub addresses: *mut AddressInfoFFI,
pub addresses_count: usize,
}

/// One UTXO row in the per-account drill-down. `script_pubkey` is
/// heap-owned and freed by the paired free fn.
#[repr(C)]
pub struct AccountUtxoEntryFFI {
pub outpoint_txid: [u8; 32],
pub outpoint_vout: u32,
pub value_duffs: u64,
pub script_pubkey: *mut u8,
pub script_pubkey_len: usize,
pub height: u32,
pub is_locked: bool,
}

/// One transaction row in the per-account paginated drill-down.
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct AccountTransactionEntryFFI {
pub txid: [u8; 32],
pub height: u32,
pub timestamp: u64,
pub value_delta_duffs: i64,
pub fee_duffs: u64,
pub is_coinbase: bool,
}

/// One row of the wallet-bound identity list (registration index +
/// identity id).
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct WalletIdentityRowFFI {
pub registration_index: u32,
pub identity_id: [u8; 32],
}

/// Subset of [`crate::wallet_restore_types::AccountSpecFFI`] carrying
Expand Down
Loading
Loading