Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
317 changes: 308 additions & 9 deletions dash/src/address.rs

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions dash/src/blockdata/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,21 @@ pub const PUBKEY_ADDRESS_PREFIX_TEST: u8 = 140;
/// Test (testnet, devnet, regtest) script address prefix.
pub const SCRIPT_ADDRESS_PREFIX_TEST: u8 = 19;
// 0x13

// DIP-18: Platform Payment Address Prefixes
/// Platform payment P2PKH address prefix (mainnet) - produces 'D' prefix.
pub const PLATFORM_P2PKH_PREFIX_MAIN: u8 = 30;
// 0x1e
/// Platform payment P2PKH address prefix (testnet/devnet/regtest) - produces 'd' prefix.
pub const PLATFORM_P2PKH_PREFIX_TEST: u8 = 90;
// 0x5a
/// Platform payment P2SH address prefix (mainnet) - produces 'P' prefix.
pub const PLATFORM_P2SH_PREFIX_MAIN: u8 = 56;
// 0x38
/// Platform payment P2SH address prefix (testnet/devnet/regtest) - produces 'p' prefix.
pub const PLATFORM_P2SH_PREFIX_TEST: u8 = 117;
// 0x75

/// The maximum allowed script size.
pub const MAX_SCRIPT_ELEMENT_SIZE: usize = 520;
/// How many blocks between halvings.
Expand Down
4 changes: 4 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,10 @@ typedef enum {
PROVIDER_PLATFORM_KEYS = 10,
DASHPAY_RECEIVING_FUNDS = 11,
DASHPAY_EXTERNAL_ACCOUNT = 12,
/*
Platform Payment address (DIP17/DIP18) - Path: m/9'/5'/17'/account'/key_class'/index
Comment thread
pauldelucia marked this conversation as resolved.
Outdated
*/
PLATFORM_PAYMENT = 13,
} FFIAccountType;

/*
Expand Down
12 changes: 12 additions & 0 deletions key-wallet-ffi/src/address_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ fn get_managed_account_by_type<'a>(
// DashPay managed accounts are not currently persisted in ManagedAccountCollection
None
}
AccountType::PlatformPayment {
..
} => {
// Platform Payment accounts are not currently persisted in ManagedAccountCollection
None
}
}
}

Expand Down Expand Up @@ -102,6 +108,12 @@ fn get_managed_account_by_type_mut<'a>(
// DashPay managed accounts are not currently persisted in ManagedAccountCollection
None
}
AccountType::PlatformPayment {
..
} => {
// Platform Payment accounts are not currently persisted in ManagedAccountCollection
None
}
}
}

Expand Down
10 changes: 10 additions & 0 deletions key-wallet-ffi/src/managed_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ pub unsafe extern "C" fn managed_wallet_get_account(
AccountType::DashpayExternalAccount {
..
} => None,
AccountType::PlatformPayment {
..
} => None,
};

match managed_account {
Expand Down Expand Up @@ -527,6 +530,9 @@ pub unsafe extern "C" fn managed_account_get_account_type(
AccountType::DashpayExternalAccount {
..
} => FFIAccountType::DashpayExternalAccount,
AccountType::PlatformPayment {
..
} => FFIAccountType::PlatformPayment,
}
}

Expand Down Expand Up @@ -1010,6 +1016,10 @@ pub unsafe extern "C" fn managed_account_get_address_pool(
addresses,
..
} => addresses,
ManagedAccountType::PlatformPayment {
addresses,
..
} => addresses,
};

let ffi_pool = FFIAddressPool {
Expand Down
21 changes: 21 additions & 0 deletions key-wallet-ffi/src/transaction_checking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,27 @@ pub unsafe extern "C" fn managed_wallet_check_transaction(
ffi_accounts.push(ffi_match);
continue;
}
AccountTypeMatch::PlatformPayment {
account_index,
involved_addresses,
..
} => {
// Note: Platform Payment addresses are NOT used in Core chain transactions
// per DIP17/DIP18. This branch should never be reached in practice.
let ffi_match = FFIAccountMatch {
account_type: 13, // PlatformPayment
account_index: *account_index,
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;
}
}
}

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 @@ -266,6 +266,8 @@ pub enum FFIAccountType {
ProviderPlatformKeys = 10,
DashpayReceivingFunds = 11,
DashpayExternalAccount = 12,
/// Platform Payment address (DIP17/DIP18) - Path: m/9'/5'/17'/account'/key_class'/index
PlatformPayment = 13,
}

impl FFIAccountType {
Expand Down Expand Up @@ -327,6 +329,14 @@ impl FFIAccountType {
DashPay account creation must use a different API path."
);
}
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."
);
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
}

Expand Down Expand Up @@ -411,6 +421,10 @@ impl FFIAccountType {
&friend_identity_id[..8]
);
}
key_wallet::AccountType::PlatformPayment {
account,
key_class,
} => (FFIAccountType::PlatformPayment, *account, Some(*key_class)),
}
}
}
Expand Down
62 changes: 62 additions & 0 deletions key-wallet/src/account/account_collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ pub struct DashpayAccountKey {
pub friend_identity_id: DashpayContactIdentityId,
}

/// Key for Platform Payment accounts (DIP-17)
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "bincode", derive(Encode, Decode))]
pub struct PlatformPaymentAccountKey {
/// Account index (hardened)
pub account: u32,
/// Key class (hardened)
pub key_class: u32,
}

/// Collection of accounts organized by type
#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
Expand Down Expand Up @@ -61,6 +72,8 @@ pub struct AccountCollection {
pub dashpay_receival_accounts: BTreeMap<DashpayAccountKey, Account>,
/// DashPay external (watch-only) accounts
pub dashpay_external_accounts: BTreeMap<DashpayAccountKey, Account>,
/// Platform Payment accounts (DIP-17)
pub platform_payment_accounts: BTreeMap<PlatformPaymentAccountKey, Account>,
}

impl AccountCollection {
Expand All @@ -82,6 +95,7 @@ impl AccountCollection {
provider_platform_keys: None,
dashpay_receival_accounts: BTreeMap::new(),
dashpay_external_accounts: BTreeMap::new(),
platform_payment_accounts: BTreeMap::new(),
}
}

Expand Down Expand Up @@ -157,6 +171,16 @@ impl AccountCollection {
};
self.dashpay_external_accounts.insert(key, account);
}
AccountType::PlatformPayment {
account: acc_index,
key_class,
} => {
let key = PlatformPaymentAccountKey {
account: *acc_index,
key_class: *key_class,
};
self.platform_payment_accounts.insert(key, account);
}
}
Ok(())
}
Expand Down Expand Up @@ -240,6 +264,16 @@ impl AccountCollection {
};
self.dashpay_external_accounts.contains_key(&key)
}
AccountType::PlatformPayment {
account,
key_class,
} => {
let key = PlatformPaymentAccountKey {
account: *account,
key_class: *key_class,
};
self.platform_payment_accounts.contains_key(&key)
}
}
}

Expand Down Expand Up @@ -293,6 +327,16 @@ impl AccountCollection {
};
self.dashpay_external_accounts.get(&key)
}
AccountType::PlatformPayment {
account,
key_class,
} => {
let key = PlatformPaymentAccountKey {
account,
key_class,
};
self.platform_payment_accounts.get(&key)
}
}
}

Expand Down Expand Up @@ -346,6 +390,16 @@ impl AccountCollection {
};
self.dashpay_external_accounts.get_mut(&key)
}
AccountType::PlatformPayment {
account,
key_class,
} => {
let key = PlatformPaymentAccountKey {
account,
key_class,
};
self.platform_payment_accounts.get_mut(&key)
}
}
}

Expand Down Expand Up @@ -382,6 +436,10 @@ impl AccountCollection {
// Note: provider_operator_keys (BLS) and provider_platform_keys (EdDSA) are excluded
// Use specific methods to access them

accounts.extend(self.dashpay_receival_accounts.values());
accounts.extend(self.dashpay_external_accounts.values());
accounts.extend(self.platform_payment_accounts.values());

accounts
}

Expand Down Expand Up @@ -418,6 +476,10 @@ impl AccountCollection {
// Note: provider_operator_keys (BLS) and provider_platform_keys (EdDSA) are excluded
// Use specific methods to access them

accounts.extend(self.dashpay_receival_accounts.values_mut());
accounts.extend(self.dashpay_external_accounts.values_mut());
accounts.extend(self.platform_payment_accounts.values_mut());

accounts
}

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 @@ -83,6 +83,16 @@ pub enum AccountType {
/// Our contact's identity id (32 bytes)
friend_identity_id: [u8; 32],
},
/// Platform Payment account (DIP-17)
/// Path: m/9'/coin_type'/17'/account'/key_class'/index
/// These addresses are encoded with DIP-18 format ("D"/"d" prefix for P2PKH).
/// **Warning**: Platform addresses MUST NOT be used in Core chain transactions.
PlatformPayment {
/// Account index (hardened) - default 0'
account: u32,
/// Key class (hardened) - default 0', 1' reserved for change-like segregation
key_class: u32,
},
}

impl From<AccountType> for AccountTypeToCheck {
Expand Down Expand Up @@ -116,6 +126,9 @@ impl From<AccountType> for AccountTypeToCheck {
AccountType::DashpayExternalAccount {
..
} => AccountTypeToCheck::DashpayExternalAccount,
AccountType::PlatformPayment {
..
} => AccountTypeToCheck::PlatformPayment,
}
}
}
Expand All @@ -140,6 +153,10 @@ impl AccountType {
index,
..
} => Some(*index),
Self::PlatformPayment {
account,
..
} => Some(*account),
// Identity and provider types don't have account indices
Self::IdentityRegistration
| Self::IdentityTopUp {
Expand Down Expand Up @@ -208,6 +225,9 @@ impl AccountType {
Self::DashpayExternalAccount {
..
} => DerivationPathReference::ContactBasedFundsExternal,
Self::PlatformPayment {
..
} => DerivationPathReference::PlatformPayment,
}
}

Expand Down Expand Up @@ -392,6 +412,30 @@ impl AccountType {
});
Ok(path)
}
Self::PlatformPayment {
account,
key_class,
} => {
// DIP-17: m/9'/coin_type'/17'/account'/key_class'
// The leaf index is non-hardened and appended during address generation
let mut path = match network {
Network::Dash => {
DerivationPath::from(crate::dip9::PLATFORM_PAYMENT_ROOT_PATH_MAINNET)
}
Network::Testnet => {
DerivationPath::from(crate::dip9::PLATFORM_PAYMENT_ROOT_PATH_TESTNET)
}
_ => return Err(crate::error::Error::InvalidNetwork),
};
path.push(
ChildNumber::from_hardened_idx(*account).map_err(crate::error::Error::Bip32)?,
);
path.push(
ChildNumber::from_hardened_idx(*key_class)
.map_err(crate::error::Error::Bip32)?,
);
Ok(path)
}
}
}
}
Loading