Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 8 additions & 0 deletions key-wallet-ffi/include/key_wallet_ffi.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ typedef enum {
Platform Payment address (DIP-17) - Path: m/9'/5'/17'/account'/key_class'/index
*/
PLATFORM_PAYMENT = 13,
/*
Asset lock address top-up funding (subfeature 4)
*/
ASSET_LOCK_ADDRESS_TOP_UP = 14,
/*
Asset lock shielded address top-up funding (subfeature 5)
*/
ASSET_LOCK_SHIELDED_ADDRESS_TOP_UP = 15,
} FFIAccountType;

/*
Expand Down
22 changes: 22 additions & 0 deletions key-wallet-ffi/src/address_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ fn get_managed_account_by_type<'a>(
collection.identity_topup_not_bound.as_ref()
}
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()
}
AccountType::ProviderVotingKeys => collection.provider_voting_keys.as_ref(),
AccountType::ProviderOwnerKeys => collection.provider_owner_keys.as_ref(),
AccountType::ProviderOperatorKeys => collection.provider_operator_keys.as_ref(),
Expand Down Expand Up @@ -94,6 +98,10 @@ fn get_managed_account_by_type_mut<'a>(
collection.identity_topup_not_bound.as_mut()
}
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()
}
AccountType::ProviderVotingKeys => collection.provider_voting_keys.as_mut(),
AccountType::ProviderOwnerKeys => collection.provider_owner_keys.as_mut(),
AccountType::ProviderOperatorKeys => collection.provider_operator_keys.as_mut(),
Expand Down Expand Up @@ -738,6 +746,20 @@ pub unsafe extern "C" fn managed_wallet_mark_address_used(
}
}
}
if !found {
if let Some(account) = &mut collection.asset_lock_address_topup {
if account.mark_address_used(&address) {
found = true;
}
}
}
if !found {
if let Some(account) = &mut collection.asset_lock_shielded_address_topup {
if account.mark_address_used(&address) {
found = true;
}
}
}
if !found {
if let Some(account) = &mut collection.provider_voting_keys {
if account.mark_address_used(&address) {
Expand Down
14 changes: 14 additions & 0 deletions key-wallet-ffi/src/managed_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,12 @@ pub unsafe extern "C" fn managed_wallet_get_account(
managed_collection.identity_topup_not_bound.as_ref()
}
AccountType::IdentityInvitation => managed_collection.identity_invitation.as_ref(),
AccountType::AssetLockAddressTopUp => {
managed_collection.asset_lock_address_topup.as_ref()
}
AccountType::AssetLockShieldedAddressTopUp => {
managed_collection.asset_lock_shielded_address_topup.as_ref()
}
AccountType::ProviderVotingKeys => managed_collection.provider_voting_keys.as_ref(),
AccountType::ProviderOwnerKeys => managed_collection.provider_owner_keys.as_ref(),
AccountType::ProviderOperatorKeys => managed_collection.provider_operator_keys.as_ref(),
Expand Down Expand Up @@ -555,6 +561,8 @@ pub unsafe extern "C" fn managed_core_account_get_account_type(
FFIAccountType::IdentityTopUpNotBoundToIdentity
}
AccountType::IdentityInvitation => FFIAccountType::IdentityInvitation,
AccountType::AssetLockAddressTopUp => FFIAccountType::AssetLockAddressTopUp,
AccountType::AssetLockShieldedAddressTopUp => FFIAccountType::AssetLockShieldedAddressTopUp,
AccountType::ProviderVotingKeys => FFIAccountType::ProviderVotingKeys,
AccountType::ProviderOwnerKeys => FFIAccountType::ProviderOwnerKeys,
AccountType::ProviderOperatorKeys => FFIAccountType::ProviderOperatorKeys,
Expand Down Expand Up @@ -1025,6 +1033,12 @@ pub unsafe extern "C" fn managed_core_account_get_address_pool(
ManagedAccountType::IdentityInvitation {
addresses,
} => addresses,
ManagedAccountType::AssetLockAddressTopUp {
addresses,
} => addresses,
ManagedAccountType::AssetLockShieldedAddressTopUp {
addresses,
} => addresses,
ManagedAccountType::ProviderVotingKeys {
addresses,
} => addresses,
Expand Down
34 changes: 34 additions & 0 deletions key-wallet-ffi/src/transaction_checking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,40 @@ pub unsafe extern "C" fn managed_wallet_check_transaction(
ffi_accounts.push(ffi_match);
continue;
}
CoreAccountTypeMatch::AssetLockAddressTopUp {
involved_addresses,
} => {
let ffi_match = FFIAccountMatch {
account_type: 14, // AssetLockAddressTopUp
account_index: 0,
registration_index: 0,
received: account_match.received,
sent: account_match.sent,
external_addresses_count: involved_addresses.len() as c_uint,
internal_addresses_count: 0,
has_external_addresses: !involved_addresses.is_empty(),
has_internal_addresses: false,
};
ffi_accounts.push(ffi_match);
continue;
}
CoreAccountTypeMatch::AssetLockShieldedAddressTopUp {
involved_addresses,
} => {
let ffi_match = FFIAccountMatch {
account_type: 15, // AssetLockShieldedAddressTopUp
account_index: 0,
registration_index: 0,
received: account_match.received,
sent: account_match.sent,
external_addresses_count: involved_addresses.len() as c_uint,
internal_addresses_count: 0,
has_external_addresses: !involved_addresses.is_empty(),
has_internal_addresses: false,
};
ffi_accounts.push(ffi_match);
continue;
}
CoreAccountTypeMatch::ProviderVotingKeys {
involved_addresses,
} => {
Expand Down
14 changes: 14 additions & 0 deletions key-wallet-ffi/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ pub enum FFIAccountType {
DashpayExternalAccount = 12,
/// Platform Payment address (DIP-17) - Path: m/9'/5'/17'/account'/key_class'/index
PlatformPayment = 13,
/// Asset lock address top-up funding (subfeature 4)
AssetLockAddressTopUp = 14,
/// Asset lock shielded address top-up funding (subfeature 5)
AssetLockShieldedAddressTopUp = 15,
}

impl FFIAccountType {
Expand Down Expand Up @@ -220,6 +224,10 @@ impl FFIAccountType {
key_wallet::AccountType::IdentityTopUpNotBoundToIdentity
}
FFIAccountType::IdentityInvitation => key_wallet::AccountType::IdentityInvitation,
FFIAccountType::AssetLockAddressTopUp => key_wallet::AccountType::AssetLockAddressTopUp,
FFIAccountType::AssetLockShieldedAddressTopUp => {
key_wallet::AccountType::AssetLockShieldedAddressTopUp
}
FFIAccountType::ProviderVotingKeys => key_wallet::AccountType::ProviderVotingKeys,
FFIAccountType::ProviderOwnerKeys => key_wallet::AccountType::ProviderOwnerKeys,
FFIAccountType::ProviderOperatorKeys => key_wallet::AccountType::ProviderOperatorKeys,
Expand Down Expand Up @@ -299,6 +307,12 @@ impl FFIAccountType {
key_wallet::AccountType::IdentityInvitation => {
(FFIAccountType::IdentityInvitation, 0, None)
}
key_wallet::AccountType::AssetLockAddressTopUp => {
(FFIAccountType::AssetLockAddressTopUp, 0, None)
}
key_wallet::AccountType::AssetLockShieldedAddressTopUp => {
(FFIAccountType::AssetLockShieldedAddressTopUp, 0, None)
}
key_wallet::AccountType::ProviderVotingKeys => {
(FFIAccountType::ProviderVotingKeys, 0, None)
}
Expand Down
4 changes: 2 additions & 2 deletions key-wallet-manager/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ fn test_account_management() {
);
assert!(result.is_ok());

// Get accounts from wallet - Default creates 9 accounts (including PlatformPayment), plus the one we added
// Get accounts from wallet - Default creates 11 accounts (including PlatformPayment), plus the one we added
let accounts = manager.get_accounts(&wallet_id);
assert!(accounts.is_ok());
assert_eq!(accounts.unwrap().len(), 10); // 9 from Default + 1 we added
assert_eq!(accounts.unwrap().len(), 12); // 11 from Default + 1 we added
}

#[test]
Expand Down
44 changes: 44 additions & 0 deletions key-wallet/src/account/account_collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ pub struct AccountCollection {
pub identity_topup_not_bound: Option<Account>,
/// Identity invitation account (optional)
pub identity_invitation: Option<Account>,
/// Asset lock address top-up account (optional)
pub asset_lock_address_topup: Option<Account>,
/// Asset lock shielded address top-up account (optional)
pub asset_lock_shielded_address_topup: Option<Account>,
/// Provider voting keys (optional)
pub provider_voting_keys: Option<Account>,
/// Provider owner keys (optional)
Expand Down Expand Up @@ -87,6 +91,8 @@ impl AccountCollection {
identity_topup: BTreeMap::new(),
identity_topup_not_bound: None,
identity_invitation: None,
asset_lock_address_topup: None,
asset_lock_shielded_address_topup: None,
provider_voting_keys: None,
provider_owner_keys: None,
#[cfg(feature = "bls")]
Expand Down Expand Up @@ -135,6 +141,12 @@ impl AccountCollection {
AccountType::IdentityInvitation => {
self.identity_invitation = Some(account);
}
AccountType::AssetLockAddressTopUp => {
self.asset_lock_address_topup = Some(account);
}
AccountType::AssetLockShieldedAddressTopUp => {
self.asset_lock_shielded_address_topup = Some(account);
}
AccountType::ProviderVotingKeys => {
self.provider_voting_keys = Some(account);
}
Expand Down Expand Up @@ -230,6 +242,10 @@ impl AccountCollection {
} => self.identity_topup.contains_key(registration_index),
AccountType::IdentityTopUpNotBoundToIdentity => self.identity_topup_not_bound.is_some(),
AccountType::IdentityInvitation => self.identity_invitation.is_some(),
AccountType::AssetLockAddressTopUp => self.asset_lock_address_topup.is_some(),
AccountType::AssetLockShieldedAddressTopUp => {
self.asset_lock_shielded_address_topup.is_some()
}
AccountType::ProviderVotingKeys => self.provider_voting_keys.is_some(),
AccountType::ProviderOwnerKeys => self.provider_owner_keys.is_some(),
#[cfg(feature = "bls")]
Expand Down Expand Up @@ -299,6 +315,10 @@ impl AccountCollection {
} => self.identity_topup.get(&registration_index),
AccountType::IdentityTopUpNotBoundToIdentity => self.identity_topup_not_bound.as_ref(),
AccountType::IdentityInvitation => self.identity_invitation.as_ref(),
AccountType::AssetLockAddressTopUp => self.asset_lock_address_topup.as_ref(),
AccountType::AssetLockShieldedAddressTopUp => {
self.asset_lock_shielded_address_topup.as_ref()
}
AccountType::ProviderVotingKeys => self.provider_voting_keys.as_ref(),
AccountType::ProviderOwnerKeys => self.provider_owner_keys.as_ref(),
AccountType::ProviderOperatorKeys => None, // BLSAccount, use bls_account_of_type
Expand Down Expand Up @@ -362,6 +382,10 @@ impl AccountCollection {
} => self.identity_topup.get_mut(&registration_index),
AccountType::IdentityTopUpNotBoundToIdentity => self.identity_topup_not_bound.as_mut(),
AccountType::IdentityInvitation => self.identity_invitation.as_mut(),
AccountType::AssetLockAddressTopUp => self.asset_lock_address_topup.as_mut(),
AccountType::AssetLockShieldedAddressTopUp => {
self.asset_lock_shielded_address_topup.as_mut()
}
AccountType::ProviderVotingKeys => self.provider_voting_keys.as_mut(),
AccountType::ProviderOwnerKeys => self.provider_owner_keys.as_mut(),
AccountType::ProviderOperatorKeys => None, // BLSAccount, use bls_account_of_type_mut
Expand Down Expand Up @@ -425,6 +449,14 @@ impl AccountCollection {
accounts.push(account);
}

if let Some(account) = &self.asset_lock_address_topup {
accounts.push(account);
}

if let Some(account) = &self.asset_lock_shielded_address_topup {
accounts.push(account);
}

if let Some(account) = &self.provider_voting_keys {
accounts.push(account);
}
Expand Down Expand Up @@ -465,6 +497,14 @@ impl AccountCollection {
accounts.push(account);
}

if let Some(account) = &mut self.asset_lock_address_topup {
accounts.push(account);
}

if let Some(account) = &mut self.asset_lock_shielded_address_topup {
accounts.push(account);
}

if let Some(account) = &mut self.provider_voting_keys {
accounts.push(account);
}
Expand Down Expand Up @@ -565,6 +605,8 @@ impl AccountCollection {
&& self.identity_topup.is_empty()
&& self.identity_topup_not_bound.is_none()
&& self.identity_invitation.is_none()
&& self.asset_lock_address_topup.is_none()
&& self.asset_lock_shielded_address_topup.is_none()
&& self.provider_voting_keys.is_none()
&& self.provider_owner_keys.is_none();

Expand All @@ -590,6 +632,8 @@ impl AccountCollection {
self.identity_topup.clear();
self.identity_topup_not_bound = None;
self.identity_invitation = None;
self.asset_lock_address_topup = None;
self.asset_lock_shielded_address_topup = None;
self.provider_voting_keys = None;
self.provider_owner_keys = None;
#[cfg(feature = "bls")]
Expand Down
44 changes: 44 additions & 0 deletions key-wallet/src/account/account_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ pub enum AccountType {
IdentityTopUpNotBoundToIdentity,
/// Identity invitation funding
IdentityInvitation,
/// Asset lock address top-up funding (subfeature 4)
/// Path: m/9'/coinType'/5'/4'/index'
AssetLockAddressTopUp,
/// Asset lock shielded address top-up funding (subfeature 5)
/// Path: m/9'/coinType'/5'/5'/index'
AssetLockShieldedAddressTopUp,
/// Provider voting keys (DIP-3)
/// Path: `m/9'/5'/3'/1'/[key_index]`
ProviderVotingKeys,
Expand Down Expand Up @@ -119,6 +125,10 @@ impl TryFrom<AccountType> for AccountTypeToCheck {
Ok(AccountTypeToCheck::IdentityTopUpNotBound)
}
AccountType::IdentityInvitation => Ok(AccountTypeToCheck::IdentityInvitation),
AccountType::AssetLockAddressTopUp => Ok(AccountTypeToCheck::AssetLockAddressTopUp),
AccountType::AssetLockShieldedAddressTopUp => {
Ok(AccountTypeToCheck::AssetLockShieldedAddressTopUp)
}
AccountType::ProviderVotingKeys => Ok(AccountTypeToCheck::ProviderVotingKeys),
AccountType::ProviderOwnerKeys => Ok(AccountTypeToCheck::ProviderOwnerKeys),
AccountType::ProviderOperatorKeys => Ok(AccountTypeToCheck::ProviderOperatorKeys),
Expand Down Expand Up @@ -170,6 +180,8 @@ impl AccountType {
}
| Self::IdentityTopUpNotBoundToIdentity
| Self::IdentityInvitation
| Self::AssetLockAddressTopUp
| Self::AssetLockShieldedAddressTopUp
| Self::ProviderVotingKeys
| Self::ProviderOwnerKeys
| Self::ProviderOperatorKeys
Expand Down Expand Up @@ -213,6 +225,12 @@ impl AccountType {
Self::IdentityInvitation {
..
} => DerivationPathReference::BlockchainIdentityCreditInvitationFunding,
Self::AssetLockAddressTopUp {
..
} => DerivationPathReference::BlockchainAssetLockAddressTopupFunding,
Self::AssetLockShieldedAddressTopUp {
..
} => DerivationPathReference::BlockchainAssetLockShieldedAddressTopupFunding,
Self::ProviderVotingKeys {
..
} => DerivationPathReference::ProviderVotingKeys,
Expand Down Expand Up @@ -334,6 +352,32 @@ impl AccountType {
_ => Err(crate::error::Error::InvalidNetwork),
}
}
Self::AssetLockAddressTopUp => {
// Base path without index - actual key index added when deriving
match network {
Network::Dash => {
Ok(DerivationPath::from(crate::dip9::ASSET_LOCK_ADDRESS_TOPUP_PATH_MAINNET))
}
Network::Testnet | Network::Devnet | Network::Regtest => {
Ok(DerivationPath::from(crate::dip9::ASSET_LOCK_ADDRESS_TOPUP_PATH_TESTNET))
}
_ => Err(crate::error::Error::InvalidNetwork),
}
}
Self::AssetLockShieldedAddressTopUp => {
// Base path without index - actual key index added when deriving
match network {
Network::Dash => Ok(DerivationPath::from(
crate::dip9::ASSET_LOCK_SHIELDED_ADDRESS_TOPUP_PATH_MAINNET,
)),
Network::Testnet | Network::Devnet | Network::Regtest => {
Ok(DerivationPath::from(
crate::dip9::ASSET_LOCK_SHIELDED_ADDRESS_TOPUP_PATH_TESTNET,
))
}
_ => Err(crate::error::Error::InvalidNetwork),
}
}
Self::ProviderVotingKeys => {
// DIP-3: m/9'/5'/3'/1' (base path, actual key index added when deriving)
Ok(DerivationPath::from(vec![
Expand Down
Loading
Loading