Skip to content
131 changes: 131 additions & 0 deletions src/backend_task/core/create_asset_lock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
use crate::backend_task::BackendTaskSuccessResult;
use crate::context::AppContext;
use crate::model::wallet::Wallet;
use dash_sdk::dashcore_rpc::RpcApi;
use dash_sdk::dpp::balances::credits::CREDITS_PER_DUFF;
use dash_sdk::dpp::fee::Credits;
use std::sync::{Arc, RwLock};

impl AppContext {
pub fn create_registration_asset_lock(
&self,
wallet: Arc<RwLock<Wallet>>,
amount: Credits,
allow_take_fee_from_amount: bool,
identity_index: u32,
) -> Result<BackendTaskSuccessResult, String> {
// Convert credits to duffs (1 duff = 1000 credits)
let amount_duffs = amount / CREDITS_PER_DUFF;

// Create the asset lock transaction
let (asset_lock_transaction, _private_key, _change_address, used_utxos) = {
let mut wallet_guard = wallet.write().map_err(|e| e.to_string())?;

wallet_guard.registration_asset_lock_transaction(
self.network,
amount_duffs,
allow_take_fee_from_amount,
identity_index,
Some(self),
)?
};

let tx_id = asset_lock_transaction.txid();

// Insert the transaction into waiting for finality
{
let mut proofs = self.transactions_waiting_for_finality.lock().unwrap();
proofs.insert(tx_id, None);
}

// Broadcast the transaction
self.core_client
.read()
.expect("Core client lock was poisoned")
.send_raw_transaction(&asset_lock_transaction)
.map_err(|e| format!("Failed to broadcast asset lock transaction: {}", e))?;

// Update wallet UTXOs
{
let mut wallet_guard = wallet.write().map_err(|e| e.to_string())?;
wallet_guard.utxos.retain(|_, utxo_map| {
utxo_map.retain(|outpoint, _| !used_utxos.contains_key(outpoint));
!utxo_map.is_empty() // Keep addresses that still have UTXOs
});

// Drop used UTXOs from database
for utxo in used_utxos.keys() {
self.db
.drop_utxo(utxo, &self.network.to_string())
.map_err(|e| e.to_string())?;
}
}

Ok(BackendTaskSuccessResult::Message(format!(
"Asset lock transaction broadcast successfully. TX ID: {}",
tx_id
)))
}

pub fn create_top_up_asset_lock(
&self,
wallet: Arc<RwLock<Wallet>>,
amount: Credits,
allow_take_fee_from_amount: bool,
identity_index: u32,
top_up_index: u32,
) -> Result<BackendTaskSuccessResult, String> {
// Convert credits to duffs (1 duff = 1000 credits)
let amount_duffs = amount / CREDITS_PER_DUFF;

// Create the asset lock transaction
let (asset_lock_transaction, _private_key, _change_address, used_utxos) = {
let mut wallet_guard = wallet.write().map_err(|e| e.to_string())?;

wallet_guard.top_up_asset_lock_transaction(
self.network,
amount_duffs,
allow_take_fee_from_amount,
identity_index,
top_up_index,
Some(self),
)?
};

let tx_id = asset_lock_transaction.txid();

// Insert the transaction into waiting for finality
{
let mut proofs = self.transactions_waiting_for_finality.lock().unwrap();
proofs.insert(tx_id, None);
}

// Broadcast the transaction
self.core_client
.read()
.expect("Core client lock was poisoned")
.send_raw_transaction(&asset_lock_transaction)
.map_err(|e| format!("Failed to broadcast asset lock transaction: {}", e))?;

// Update wallet UTXOs
{
let mut wallet_guard = wallet.write().map_err(|e| e.to_string())?;
wallet_guard.utxos.retain(|_, utxo_map| {
utxo_map.retain(|outpoint, _| !used_utxos.contains_key(outpoint));
!utxo_map.is_empty() // Keep addresses that still have UTXOs
});

// Drop used UTXOs from database
for utxo in used_utxos.keys() {
self.db
.drop_utxo(utxo, &self.network.to_string())
.map_err(|e| e.to_string())?;
}
}

Ok(BackendTaskSuccessResult::Message(format!(
"Asset lock transaction broadcast successfully. TX ID: {}",
tx_id
)))
}
}
18 changes: 18 additions & 0 deletions src/backend_task/core/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod create_asset_lock;
mod recover_asset_locks;
mod refresh_single_key_wallet_info;
mod refresh_wallet_info;
Expand All @@ -18,6 +19,7 @@ use dash_sdk::dpp::dashcore::sighash::SighashCache;
use dash_sdk::dpp::dashcore::{
Address, Block, ChainLock, InstantLock, Network, OutPoint, PrivateKey, Transaction, TxOut,
};
use dash_sdk::dpp::fee::Credits;
use dash_sdk::dpp::key_wallet::Network as WalletNetwork;
use dash_sdk::dpp::key_wallet::wallet::managed_wallet_info::ManagedWalletInfo;
use dash_sdk::dpp::key_wallet::wallet::managed_wallet_info::fee::FeeLevel;
Expand Down Expand Up @@ -57,6 +59,8 @@ pub enum CoreTask {
RefreshWalletInfo(Arc<RwLock<Wallet>>, Option<PlatformSyncMode>),
RefreshSingleKeyWalletInfo(Arc<RwLock<SingleKeyWallet>>),
StartDashQT(Network, PathBuf, bool),
CreateRegistrationAssetLock(Arc<RwLock<Wallet>>, Credits, u32), // wallet, amount in credits, identity index
CreateTopUpAssetLock(Arc<RwLock<Wallet>>, Credits, u32, u32), // wallet, amount in credits, identity index, top up index
SendWalletPayment {
wallet: Arc<RwLock<Wallet>>,
request: WalletPaymentRequest,
Expand Down Expand Up @@ -85,6 +89,14 @@ impl PartialEq for CoreTask {
CoreTask::StartDashQT(_, _, _),
CoreTask::StartDashQT(_, _, _)
)
| (
CoreTask::CreateRegistrationAssetLock(_, _, _),
CoreTask::CreateRegistrationAssetLock(_, _, _)
)
| (
CoreTask::CreateTopUpAssetLock(_, _, _, _),
CoreTask::CreateTopUpAssetLock(_, _, _, _)
)
| (
CoreTask::SendWalletPayment { .. },
CoreTask::SendWalletPayment { .. },
Expand Down Expand Up @@ -241,6 +253,12 @@ impl AppContext {
.start_dash_qt(network, custom_dash_qt, overwrite_dash_conf)
.map_err(|e| e.to_string())
.map(|_| BackendTaskSuccessResult::None),
CoreTask::CreateRegistrationAssetLock(wallet, amount, identity_index) => self
.create_registration_asset_lock(wallet, amount, true, identity_index)
.map_err(|e| format!("Error creating asset lock: {}", e)),
CoreTask::CreateTopUpAssetLock(wallet, amount, identity_index, top_up_index) => self
.create_top_up_asset_lock(wallet, amount, true, identity_index, top_up_index)
.map_err(|e| format!("Error creating top up asset lock: {}", e)),
CoreTask::SendWalletPayment { wallet, request } => {
self.send_wallet_payment(wallet, request).await
}
Expand Down
2 changes: 1 addition & 1 deletion src/ui/identities/funding_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::model::wallet::Wallet;
use dash_sdk::dashcore_rpc::dashcore::Address;
use dash_sdk::dpp::dashcore::{OutPoint, TxOut};

#[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
pub enum WalletFundedScreenStep {
ChooseFundingMethod,
WaitingOnFunds,
Expand Down
42 changes: 42 additions & 0 deletions src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ use crate::ui::tools::masternode_list_diff_screen::MasternodeListDiffScreen;
use crate::ui::tools::platform_info_screen::PlatformInfoScreen;
use crate::ui::tools::proof_log_screen::ProofLogScreen;
use crate::ui::tools::proof_visualizer_screen::ProofVisualizerScreen;
use crate::ui::wallets::asset_lock_detail_screen::AssetLockDetailScreen;
use crate::ui::wallets::create_asset_lock_screen::CreateAssetLockScreen;
use crate::ui::wallets::import_mnemonic_screen::ImportMnemonicScreen;
use crate::ui::wallets::send_screen::WalletSendScreen;
use crate::ui::wallets::single_key_send_screen::SingleKeyWalletSendScreen;
Expand Down Expand Up @@ -295,6 +297,10 @@ pub enum ScreenType {
PurchaseTokenScreen(IdentityTokenInfo),
SetTokenPriceScreen(IdentityTokenInfo),

// Wallet screens
AssetLockDetail([u8; 32], usize),
CreateAssetLock(Arc<RwLock<Wallet>>),

// DashPay Screens
DashPayContacts,
DashPayProfile,
Expand All @@ -318,6 +324,10 @@ impl PartialEq for ScreenType {
ScreenType::SingleKeyWalletSendScreen(_),
ScreenType::SingleKeyWalletSendScreen(_),
) => true,
(ScreenType::CreateAssetLock(_), ScreenType::CreateAssetLock(_)) => true,
(ScreenType::AssetLockDetail(a1, a2), ScreenType::AssetLockDetail(b1, b2)) => {
a1 == b1 && a2 == b2
}
(ScreenType::Identities, ScreenType::Identities) => true,
(ScreenType::DPNSActiveContests, ScreenType::DPNSActiveContests) => true,
(ScreenType::DPNSPastContests, ScreenType::DPNSPastContests) => true,
Expand Down Expand Up @@ -604,6 +614,12 @@ impl ScreenType {
ScreenType::SetTokenPriceScreen(identity_token_info) => Screen::SetTokenPriceScreen(
SetTokenPriceScreen::new(identity_token_info.clone(), app_context),
),
ScreenType::AssetLockDetail(wallet_seed_hash, index) => Screen::AssetLockDetailScreen(
AssetLockDetailScreen::new(*wallet_seed_hash, *index, app_context),
),
ScreenType::CreateAssetLock(wallet) => Screen::CreateAssetLockScreen(
CreateAssetLockScreen::new(wallet.clone(), app_context),
),

// DashPay Screens
ScreenType::DashPayContacts => {
Expand Down Expand Up @@ -710,6 +726,8 @@ pub enum Screen {
AddTokenById(AddTokenByIdScreen),
PurchaseTokenScreen(PurchaseTokenScreen),
SetTokenPriceScreen(SetTokenPriceScreen),
AssetLockDetailScreen(AssetLockDetailScreen),
CreateAssetLockScreen(CreateAssetLockScreen),

// DashPay Screens
DashPayScreen(DashPayScreen),
Expand Down Expand Up @@ -786,6 +804,8 @@ impl Screen {
Screen::AddTokenById(screen) => screen.app_context = app_context,
Screen::PurchaseTokenScreen(screen) => screen.app_context = app_context,
Screen::SetTokenPriceScreen(screen) => screen.app_context = app_context,
Screen::AssetLockDetailScreen(screen) => screen.app_context = app_context,
Screen::CreateAssetLockScreen(screen) => screen.app_context = app_context,

// DashPay Screens
Screen::DashPayScreen(screen) => {
Expand Down Expand Up @@ -967,6 +987,12 @@ impl Screen {
Screen::SetTokenPriceScreen(screen) => {
ScreenType::SetTokenPriceScreen(screen.identity_token_info.clone())
}
Screen::AssetLockDetailScreen(screen) => {
ScreenType::AssetLockDetail(screen.wallet_seed_hash, screen.asset_lock_index)
}
Screen::CreateAssetLockScreen(screen) => {
ScreenType::CreateAssetLock(screen.wallet.clone())
}
Screen::TokensScreen(_) => {
// Default fallback for any unmatched TokensScreen variants
ScreenType::TokenBalances
Expand Down Expand Up @@ -1050,6 +1076,8 @@ impl ScreenLike for Screen {
Screen::AddTokenById(screen) => screen.refresh(),
Screen::PurchaseTokenScreen(screen) => screen.refresh(),
Screen::SetTokenPriceScreen(screen) => screen.refresh(),
Screen::AssetLockDetailScreen(screen) => screen.refresh(),
Screen::CreateAssetLockScreen(screen) => screen.refresh(),

// DashPay Screens
Screen::DashPayScreen(screen) => screen.refresh(),
Expand Down Expand Up @@ -1114,6 +1142,8 @@ impl ScreenLike for Screen {
Screen::AddTokenById(screen) => screen.refresh_on_arrival(),
Screen::PurchaseTokenScreen(screen) => screen.refresh_on_arrival(),
Screen::SetTokenPriceScreen(screen) => screen.refresh_on_arrival(),
Screen::AssetLockDetailScreen(screen) => screen.refresh_on_arrival(),
Screen::CreateAssetLockScreen(screen) => screen.refresh_on_arrival(),

// DashPay Screens
Screen::DashPayScreen(screen) => screen.refresh_on_arrival(),
Expand Down Expand Up @@ -1178,6 +1208,8 @@ impl ScreenLike for Screen {
Screen::AddTokenById(screen) => screen.ui(ctx),
Screen::PurchaseTokenScreen(screen) => screen.ui(ctx),
Screen::SetTokenPriceScreen(screen) => screen.ui(ctx),
Screen::AssetLockDetailScreen(screen) => screen.ui(ctx),
Screen::CreateAssetLockScreen(screen) => screen.ui(ctx),

// DashPay Screens
Screen::DashPayScreen(screen) => screen.ui(ctx),
Expand Down Expand Up @@ -1262,6 +1294,8 @@ impl ScreenLike for Screen {
Screen::AddTokenById(screen) => screen.display_message(message, message_type),
Screen::PurchaseTokenScreen(screen) => screen.display_message(message, message_type),
Screen::SetTokenPriceScreen(screen) => screen.display_message(message, message_type),
Screen::AssetLockDetailScreen(screen) => screen.display_message(message, message_type),
Screen::CreateAssetLockScreen(screen) => screen.display_message(message, message_type),

// DashPay Screens
Screen::DashPayScreen(screen) => screen.display_message(message, message_type),
Expand Down Expand Up @@ -1424,6 +1458,12 @@ impl ScreenLike for Screen {
Screen::SetTokenPriceScreen(screen) => {
screen.display_task_result(backend_task_success_result)
}
Screen::AssetLockDetailScreen(screen) => {
screen.display_task_result(backend_task_success_result)
}
Screen::CreateAssetLockScreen(screen) => {
screen.display_task_result(backend_task_success_result)
}

// DashPay Screens
Screen::DashPayScreen(screen) => {
Expand Down Expand Up @@ -1504,6 +1544,8 @@ impl ScreenLike for Screen {
Screen::AddTokenById(screen) => screen.pop_on_success(),
Screen::PurchaseTokenScreen(screen) => screen.pop_on_success(),
Screen::SetTokenPriceScreen(screen) => screen.pop_on_success(),
Screen::AssetLockDetailScreen(screen) => screen.pop_on_success(),
Screen::CreateAssetLockScreen(screen) => screen.pop_on_success(),

// DashPay Screens
Screen::DashPayScreen(screen) => screen.pop_on_success(),
Expand Down
Loading
Loading