Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
1 change: 0 additions & 1 deletion dash-spv/tests/dashd_sync/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use dash_spv::network::NetworkEvent;
use dash_spv::sync::{ProgressPercentage, SyncEvent, SyncProgress, SyncState};
use dash_spv::test_utils::DashCoreNode;
use dashcore::Txid;
use key_wallet::managed_account::managed_account_trait::ManagedAccountTrait;
use key_wallet::transaction_checking::TransactionContext;
use key_wallet::wallet::managed_wallet_info::wallet_info_interface::WalletInfoInterface;
use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo;
Expand Down
8 changes: 4 additions & 4 deletions key-wallet-ffi/FFI_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,14 +233,14 @@ Functions: 108
| `managed_core_account_free_transactions` | Free transactions array returned by managed_core_account_get_transactions ... | managed_account |
| `managed_core_account_get_account_type` | Get the account type of a managed account # Safety - `account` must be a... | managed_account |
| `managed_core_account_get_address_pool` | Get an address pool from a managed account by type This function returns... | managed_account |
| `managed_core_account_get_balance` | Get the balance of a managed account # Safety - `account` must be a valid... | managed_account |
| `managed_core_account_get_balance` | Get the balance of a managed account | managed_account |
| `managed_core_account_get_external_address_pool` | Get the external address pool from a managed account This function returns... | managed_account |
| `managed_core_account_get_index` | Get the account index from a managed account Returns the primary account... | managed_account |
| `managed_core_account_get_internal_address_pool` | Get the internal address pool from a managed account This function returns... | managed_account |
| `managed_core_account_get_network` | Get the network of a managed account # Safety - `account` must be a valid... | managed_account |
| `managed_core_account_get_transaction_count` | Get the number of transactions in a managed account Only available with the... | managed_account |
| `managed_core_account_get_transactions` | Get all transactions from a managed account Returns an array of... | managed_account |
| `managed_core_account_get_utxo_count` | Get the number of UTXOs in a managed account # Safety - `account` must be... | managed_account |
| `managed_core_account_get_utxo_count` | Get the number of UTXOs in a managed account | managed_account |
| `managed_platform_account_free` | Free a managed platform account handle # Safety - `account` must be a... | managed_account |
| `managed_platform_account_get_account_index` | Get the account index of a managed platform account # Safety - `account`... | managed_account |
| `managed_platform_account_get_address_pool` | Get the address pool from a managed platform account Platform accounts only... | managed_account |
Expand Down Expand Up @@ -3095,7 +3095,7 @@ managed_core_account_get_balance(account: *const FFIManagedCoreAccount, balance_
```

**Description:**
Get the balance of a managed account # Safety - `account` must be a valid pointer to an FFIManagedCoreAccount instance - `balance_out` must be a valid pointer to an FFIBalance structure
Get the balance of a managed account. Returns `false` (and leaves `balance_out` untouched) when the handle wraps a keys-only account (identity / asset-lock / provider) — those don't track per-account balances. Use [`managed_core_account_get_account_type`] to disambiguate, or only call this for funds-bearing accounts. # Safety - `account` must be a valid pointer to an FFIManagedCoreAccount instance - `balance_out` must be a valid pointer to an FFIBalance structure

**Safety:**
- `account` must be a valid pointer to an FFIManagedCoreAccount instance - `balance_out` must be a valid pointer to an FFIBalance structure
Expand Down Expand Up @@ -3207,7 +3207,7 @@ managed_core_account_get_utxo_count(account: *const FFIManagedCoreAccount,) -> c
```

**Description:**
Get the number of UTXOs in a managed account # Safety - `account` must be a valid pointer to an FFIManagedCoreAccount instance
Get the number of UTXOs in a managed account. Always returns 0 for keys-only accounts (identity / asset-lock / provider), which do not track per-account UTXOs. # Safety - `account` must be a valid pointer to an FFIManagedCoreAccount instance

**Safety:**
- `account` must be a valid pointer to an FFIManagedCoreAccount instance
Expand Down
104 changes: 67 additions & 37 deletions key-wallet-ffi/src/address_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,58 +16,74 @@ use key_wallet::managed_account::address_pool::{
AddressInfo, AddressPool, KeySource, PublicKeyType,
};
use key_wallet::managed_account::managed_account_trait::ManagedAccountTrait;
use key_wallet::managed_account::ManagedCoreFundsAccount;
use key_wallet::managed_account::{ManagedAccountRef, ManagedAccountRefMut};
use key_wallet::AccountType;

// Helper functions to get managed accounts by type
// Helper functions to get managed accounts by type. Identity / asset-lock /
// provider variants are stored as keys-only accounts; Standard / CoinJoin
// stay funds-bearing. The returned [`ManagedAccountRef`] enum exposes the
// shared trait surface (address pools, managed type, network) used here
// without forcing callers to dispatch on the variant.
fn get_managed_account_by_type<'a>(
collection: &'a ManagedAccountCollection,
account_type: &AccountType,
) -> Option<&'a ManagedCoreFundsAccount> {
) -> Option<ManagedAccountRef<'a>> {
match account_type {
AccountType::Standard {
index,
standard_account_type,
} => match standard_account_type {
key_wallet::account::StandardAccountType::BIP44Account => {
collection.standard_bip44_accounts.get(index)
collection.standard_bip44_accounts.get(index).map(ManagedAccountRef::Funds)
}
key_wallet::account::StandardAccountType::BIP32Account => {
collection.standard_bip32_accounts.get(index)
collection.standard_bip32_accounts.get(index).map(ManagedAccountRef::Funds)
}
},
AccountType::CoinJoin {
index,
} => collection.coinjoin_accounts.get(index),
AccountType::IdentityRegistration => collection.identity_registration.as_ref(),
} => collection.coinjoin_accounts.get(index).map(ManagedAccountRef::Funds),
AccountType::IdentityRegistration => {
collection.identity_registration.as_ref().map(ManagedAccountRef::Keys)
}
AccountType::IdentityTopUp {
registration_index,
} => collection.identity_topup.get(registration_index),
} => collection.identity_topup.get(registration_index).map(ManagedAccountRef::Keys),
AccountType::IdentityTopUpNotBoundToIdentity => {
collection.identity_topup_not_bound.as_ref()
collection.identity_topup_not_bound.as_ref().map(ManagedAccountRef::Keys)
}
AccountType::IdentityInvitation => {
collection.identity_invitation.as_ref().map(ManagedAccountRef::Keys)
}
AccountType::AssetLockAddressTopUp => {
collection.asset_lock_address_topup.as_ref().map(ManagedAccountRef::Keys)
}
AccountType::IdentityInvitation => collection.identity_invitation.as_ref(),
AccountType::AssetLockAddressTopUp => collection.asset_lock_address_topup.as_ref(),
AccountType::AssetLockShieldedAddressTopUp => {
collection.asset_lock_shielded_address_topup.as_ref()
collection.asset_lock_shielded_address_topup.as_ref().map(ManagedAccountRef::Keys)
}
AccountType::ProviderVotingKeys => {
collection.provider_voting_keys.as_ref().map(ManagedAccountRef::Keys)
}
AccountType::ProviderOwnerKeys => {
collection.provider_owner_keys.as_ref().map(ManagedAccountRef::Keys)
}
AccountType::ProviderOperatorKeys => {
collection.provider_operator_keys.as_ref().map(ManagedAccountRef::Keys)
}
AccountType::ProviderPlatformKeys => {
collection.provider_platform_keys.as_ref().map(ManagedAccountRef::Keys)
}
AccountType::ProviderVotingKeys => collection.provider_voting_keys.as_ref(),
AccountType::ProviderOwnerKeys => collection.provider_owner_keys.as_ref(),
AccountType::ProviderOperatorKeys => collection.provider_operator_keys.as_ref(),
AccountType::ProviderPlatformKeys => collection.provider_platform_keys.as_ref(),
AccountType::DashpayReceivingFunds {
..
}
| AccountType::DashpayExternalAccount {
..
} => {
// DashPay managed accounts are not currently persisted in ManagedAccountCollection
None
}
AccountType::PlatformPayment {
| AccountType::PlatformPayment {
..
} => {
// Platform Payment accounts are not currently persisted in ManagedAccountCollection
// DashPay and Platform Payment accounts are not reachable through
// this address-pool helper.
None
}
}
Expand All @@ -76,38 +92,52 @@ fn get_managed_account_by_type<'a>(
fn get_managed_account_by_type_mut<'a>(
collection: &'a mut ManagedAccountCollection,
account_type: &AccountType,
) -> Option<&'a mut ManagedCoreFundsAccount> {
) -> Option<ManagedAccountRefMut<'a>> {
match account_type {
AccountType::Standard {
index,
standard_account_type,
} => match standard_account_type {
key_wallet::account::StandardAccountType::BIP44Account => {
collection.standard_bip44_accounts.get_mut(index)
collection.standard_bip44_accounts.get_mut(index).map(ManagedAccountRefMut::Funds)
}
key_wallet::account::StandardAccountType::BIP32Account => {
collection.standard_bip32_accounts.get_mut(index)
collection.standard_bip32_accounts.get_mut(index).map(ManagedAccountRefMut::Funds)
}
},
AccountType::CoinJoin {
index,
} => collection.coinjoin_accounts.get_mut(index),
AccountType::IdentityRegistration => collection.identity_registration.as_mut(),
} => collection.coinjoin_accounts.get_mut(index).map(ManagedAccountRefMut::Funds),
AccountType::IdentityRegistration => {
collection.identity_registration.as_mut().map(ManagedAccountRefMut::Keys)
}
AccountType::IdentityTopUp {
registration_index,
} => collection.identity_topup.get_mut(registration_index),
} => collection.identity_topup.get_mut(registration_index).map(ManagedAccountRefMut::Keys),
AccountType::IdentityTopUpNotBoundToIdentity => {
collection.identity_topup_not_bound.as_mut()
collection.identity_topup_not_bound.as_mut().map(ManagedAccountRefMut::Keys)
}
AccountType::IdentityInvitation => {
collection.identity_invitation.as_mut().map(ManagedAccountRefMut::Keys)
}
AccountType::AssetLockAddressTopUp => {
collection.asset_lock_address_topup.as_mut().map(ManagedAccountRefMut::Keys)
}
AccountType::IdentityInvitation => collection.identity_invitation.as_mut(),
AccountType::AssetLockAddressTopUp => collection.asset_lock_address_topup.as_mut(),
AccountType::AssetLockShieldedAddressTopUp => {
collection.asset_lock_shielded_address_topup.as_mut()
collection.asset_lock_shielded_address_topup.as_mut().map(ManagedAccountRefMut::Keys)
}
AccountType::ProviderVotingKeys => {
collection.provider_voting_keys.as_mut().map(ManagedAccountRefMut::Keys)
}
AccountType::ProviderOwnerKeys => {
collection.provider_owner_keys.as_mut().map(ManagedAccountRefMut::Keys)
}
AccountType::ProviderOperatorKeys => {
collection.provider_operator_keys.as_mut().map(ManagedAccountRefMut::Keys)
}
AccountType::ProviderPlatformKeys => {
collection.provider_platform_keys.as_mut().map(ManagedAccountRefMut::Keys)
}
AccountType::ProviderVotingKeys => collection.provider_voting_keys.as_mut(),
AccountType::ProviderOwnerKeys => collection.provider_owner_keys.as_mut(),
AccountType::ProviderOperatorKeys => collection.provider_operator_keys.as_mut(),
AccountType::ProviderPlatformKeys => collection.provider_platform_keys.as_mut(),
AccountType::DashpayReceivingFunds {
..
}
Expand Down Expand Up @@ -384,7 +414,7 @@ pub unsafe extern "C" fn managed_wallet_set_gap_limit(
let account_type_rust = account_type.to_account_type(account_index);

// Get the specific managed account
let managed_account = unwrap_or_return!(
let mut managed_account = unwrap_or_return!(
get_managed_account_by_type_mut(&mut managed_wallet.accounts, &account_type_rust),
error
);
Expand Down Expand Up @@ -471,7 +501,7 @@ pub unsafe extern "C" fn managed_wallet_generate_addresses_to_index(
let key_source = KeySource::Public(xpub);

// Get the specific managed account
let managed_account = unwrap_or_return!(
let mut managed_account = unwrap_or_return!(
get_managed_account_by_type_mut(&mut managed_wallet.accounts, &account_type_rust),
error
);
Expand Down
Loading
Loading