diff --git a/src/backend_task/platform_info.rs b/src/backend_task/platform_info.rs index 38014eb87..6cbf246f0 100644 --- a/src/backend_task/platform_info.rs +++ b/src/backend_task/platform_info.rs @@ -367,7 +367,16 @@ impl AppContext { PlatformInfoTaskRequestType::CurrentEpochInfo => { match ExtendedEpochInfo::fetch_current(&sdk).await { Ok(epoch_info) => { - let formatted = format_extended_epoch_info(epoch_info, self.network, true); + // Cache the fee multiplier for UI fee estimation + let fee_multiplier = epoch_info.fee_multiplier_permille(); + self.set_fee_multiplier_permille(fee_multiplier); + + let mut formatted = + format_extended_epoch_info(epoch_info, self.network, true); + formatted.push_str(&format!( + "\n\n(Fee multiplier cache updated: {}x)", + fee_multiplier as f64 / 1000.0 + )); Ok(BackendTaskSuccessResult::PlatformInfo( PlatformInfoTaskResult::TextResult(formatted), )) diff --git a/src/context.rs b/src/context.rs index b79984111..cb96b06d6 100644 --- a/src/context.rs +++ b/src/context.rs @@ -6,6 +6,7 @@ use crate::context_provider::Provider as RpcProvider; use crate::context_provider_spv::SpvProvider; use crate::database::Database; use crate::model::contested_name::ContestedName; +use crate::model::fee_estimation::PlatformFeeEstimator; use crate::model::password_info::PasswordInfo; use crate::model::qualified_contract::QualifiedContract; use crate::model::qualified_identity::{DPNSNameInfo, QualifiedIdentity}; @@ -49,7 +50,7 @@ use dash_sdk::query_types::IndexMap; use egui::Context; use rusqlite::Result; use std::collections::{BTreeMap, HashMap}; -use std::sync::atomic::{AtomicBool, AtomicU8, Ordering}; +use std::sync::atomic::{AtomicBool, AtomicU8, AtomicU64, Ordering}; use std::sync::{Arc, Mutex, RwLock, RwLockWriteGuard}; const ANIMATION_REFRESH_TIME: std::time::Duration = std::time::Duration::from_millis(100); @@ -106,6 +107,9 @@ pub struct AppContext { pub(crate) selected_wallet_hash: Mutex>, /// Currently selected single key wallet (persisted across screen navigation) pub(crate) selected_single_key_hash: Mutex>, + /// Cached fee multiplier permille from current epoch (1000 = 1x, 2000 = 2x) + /// Updated when epoch info is fetched from Platform + fee_multiplier_permille: AtomicU64, } impl AppContext { @@ -275,6 +279,9 @@ impl AppContext { pending_wallet_selection: Mutex::new(None), selected_wallet_hash: Mutex::new(selected_wallet_hash), selected_single_key_hash: Mutex::new(selected_single_key_hash), + fee_multiplier_permille: AtomicU64::new( + PlatformFeeEstimator::DEFAULT_FEE_MULTIPLIER_PERMILLE, + ), }; let app_context = Arc::new(app_context); @@ -395,6 +402,24 @@ impl AppContext { } } + /// Get the cached fee multiplier permille (1000 = 1x, 2000 = 2x) + pub fn fee_multiplier_permille(&self) -> u64 { + self.fee_multiplier_permille.load(Ordering::Relaxed) + } + + /// Update the cached fee multiplier from epoch info + pub fn set_fee_multiplier_permille(&self, multiplier: u64) { + self.fee_multiplier_permille + .store(multiplier, Ordering::Relaxed); + } + + /// Get a fee estimator configured with the cached fee multiplier. + /// Use this instead of `PlatformFeeEstimator::new()` to get accurate fee estimates + /// that reflect the current network fee multiplier. + pub fn fee_estimator(&self) -> PlatformFeeEstimator { + PlatformFeeEstimator::with_fee_multiplier(self.fee_multiplier_permille()) + } + pub fn spv_manager(&self) -> &Arc { &self.spv_manager } diff --git a/src/model/fee_estimation.rs b/src/model/fee_estimation.rs index 1f079c5a7..6c5f19e5f 100644 --- a/src/model/fee_estimation.rs +++ b/src/model/fee_estimation.rs @@ -141,6 +141,9 @@ pub struct PlatformFeeEstimator { min_fees: StateTransitionMinFees, storage_fees: StorageFeeConstants, registration_fees: DataContractRegistrationFees, + /// Fee multiplier in permille (1000 = 1x, 2000 = 2x, etc.) + /// This comes from the current epoch's fee_multiplier_permille() + fee_multiplier_permille: u64, } impl Default for PlatformFeeEstimator { @@ -150,11 +153,25 @@ impl Default for PlatformFeeEstimator { } impl PlatformFeeEstimator { + /// Default fee multiplier (1x = 1000 permille) + pub const DEFAULT_FEE_MULTIPLIER_PERMILLE: u64 = 1000; + pub fn new() -> Self { Self { min_fees: StateTransitionMinFees::default(), storage_fees: StorageFeeConstants::default(), registration_fees: DataContractRegistrationFees::default(), + fee_multiplier_permille: Self::DEFAULT_FEE_MULTIPLIER_PERMILLE, + } + } + + /// Create an estimator with a specific fee multiplier (from epoch info) + pub fn with_fee_multiplier(fee_multiplier_permille: u64) -> Self { + Self { + min_fees: StateTransitionMinFees::default(), + storage_fees: StorageFeeConstants::default(), + registration_fees: DataContractRegistrationFees::default(), + fee_multiplier_permille, } } @@ -164,6 +181,19 @@ impl PlatformFeeEstimator { Self::new() } + /// Apply the fee multiplier to a base fee amount. + /// Multiplier is in permille: 1000 = 1x, 1500 = 1.5x, 2000 = 2x + fn apply_multiplier(&self, base_fee: u64) -> u64 { + base_fee + .saturating_mul(self.fee_multiplier_permille) + .saturating_div(1000) + } + + /// Get the current fee multiplier permille + pub fn fee_multiplier_permille(&self) -> u64 { + self.fee_multiplier_permille + } + /// Calculate storage fee for a given number of bytes. /// This is the main cost component for storing data on Platform. pub fn calculate_storage_fee(&self, bytes: usize) -> u64 { @@ -181,36 +211,45 @@ impl PlatformFeeEstimator { (seek_count as u64).saturating_mul(self.storage_fees.storage_seek_cost) } - /// Estimate total storage-based fee for storing data. + /// Calculate total storage-based fee for storing data (without fee multiplier). /// Includes storage, processing, and estimated seek costs. - pub fn estimate_storage_based_fee(&self, bytes: usize, estimated_seeks: usize) -> u64 { + /// This is a building block used by other estimation functions. + fn calculate_storage_based_fee(&self, bytes: usize, estimated_seeks: usize) -> u64 { self.calculate_storage_fee(bytes) .saturating_add(self.calculate_processing_fee(bytes)) .saturating_add(self.calculate_seek_fee(estimated_seeks)) } + /// Estimate total storage-based fee for storing data. + /// Includes storage, processing, and estimated seek costs. + /// Applies the current fee multiplier. + pub fn estimate_storage_based_fee(&self, bytes: usize, estimated_seeks: usize) -> u64 { + self.apply_multiplier(self.calculate_storage_based_fee(bytes, estimated_seeks)) + } + /// Estimate fee for credit transfer between identities pub fn estimate_credit_transfer(&self) -> u64 { - self.min_fees.credit_transfer + self.apply_multiplier(self.min_fees.credit_transfer) } /// Estimate fee for credit transfer to platform addresses pub fn estimate_credit_transfer_to_addresses(&self, output_count: usize) -> u64 { - self.min_fees.credit_transfer_to_addresses.saturating_add( + let base_fee = self.min_fees.credit_transfer_to_addresses.saturating_add( self.min_fees .address_funds_transfer_output_cost .saturating_mul(output_count as u64), - ) + ); + self.apply_multiplier(base_fee) } /// Estimate fee for credit withdrawal to core chain pub fn estimate_credit_withdrawal(&self) -> u64 { - self.min_fees.credit_withdrawal + self.apply_multiplier(self.min_fees.credit_withdrawal) } /// Estimate fee for address-based credit withdrawal pub fn estimate_address_credit_withdrawal(&self) -> u64 { - self.min_fees.address_credit_withdrawal + self.apply_multiplier(self.min_fees.address_credit_withdrawal) } /// Estimate fee for funding a platform address from an asset lock. @@ -229,20 +268,22 @@ impl PlatformFeeEstimator { /// Estimate fee for identity update (adding/disabling keys) pub fn estimate_identity_update(&self) -> u64 { - self.min_fees.identity_update + self.apply_multiplier(self.min_fees.identity_update) } /// Estimate fee for identity creation. /// This includes base cost, asset lock cost, and per-key costs. pub fn estimate_identity_create(&self, key_count: usize) -> u64 { - self.min_fees + let base_fee = self + .min_fees .identity_create_base_cost .saturating_add(self.min_fees.identity_create_asset_lock_cost) .saturating_add( self.min_fees .identity_key_in_creation_cost .saturating_mul(key_count as u64), - ) + ); + self.apply_multiplier(base_fee) } /// Estimate fee for identity creation from addresses (asset lock). @@ -254,7 +295,8 @@ impl PlatformFeeEstimator { key_count: usize, ) -> u64 { let output_count = if has_output { 1 } else { 0 }; - self.min_fees + let base_fee = self + .min_fees .identity_create_base_cost .saturating_add(self.min_fees.address_funding_asset_lock_cost) .saturating_add( @@ -271,22 +313,27 @@ impl PlatformFeeEstimator { self.min_fees .identity_key_in_creation_cost .saturating_mul(key_count as u64), - ) + ); + self.apply_multiplier(base_fee) } /// Estimate fee for identity top-up. /// This includes base cost and asset lock cost. pub fn estimate_identity_topup(&self) -> u64 { - self.min_fees + let base_fee = self + .min_fees .identity_topup_base_cost - .saturating_add(self.min_fees.identity_topup_asset_lock_cost) + .saturating_add(self.min_fees.identity_topup_asset_lock_cost); + self.apply_multiplier(base_fee) } /// Estimate fee for document batch transition pub fn estimate_document_batch(&self, transition_count: usize) -> u64 { - self.min_fees + let base_fee = self + .min_fees .document_batch_sub_transition - .saturating_mul(transition_count.max(1) as u64) + .saturating_mul(transition_count.max(1) as u64); + self.apply_multiplier(base_fee) } /// Estimate fee for document creation with known size. @@ -294,9 +341,11 @@ impl PlatformFeeEstimator { /// Estimated seeks: ~10 for tree traversal and insertion. pub fn estimate_document_create_with_size(&self, document_bytes: usize) -> u64 { const ESTIMATED_SEEKS: usize = 10; - self.min_fees + let base_fee = self + .min_fees .document_batch_sub_transition - .saturating_add(self.estimate_storage_based_fee(document_bytes, ESTIMATED_SEEKS)) + .saturating_add(self.calculate_storage_based_fee(document_bytes, ESTIMATED_SEEKS)); + self.apply_multiplier(base_fee) } /// Estimate fee for document creation (uses default estimate of ~200 bytes). @@ -309,17 +358,21 @@ impl PlatformFeeEstimator { pub fn estimate_document_delete(&self) -> u64 { // Deletion involves seeks but no storage addition const ESTIMATED_SEEKS: usize = 8; - self.min_fees + let base_fee = self + .min_fees .document_batch_sub_transition - .saturating_add(self.calculate_seek_fee(ESTIMATED_SEEKS)) + .saturating_add(self.calculate_seek_fee(ESTIMATED_SEEKS)); + self.apply_multiplier(base_fee) } /// Estimate fee for document replacement with known size. pub fn estimate_document_replace_with_size(&self, document_bytes: usize) -> u64 { const ESTIMATED_SEEKS: usize = 10; - self.min_fees + let base_fee = self + .min_fees .document_batch_sub_transition - .saturating_add(self.estimate_storage_based_fee(document_bytes, ESTIMATED_SEEKS)) + .saturating_add(self.calculate_storage_based_fee(document_bytes, ESTIMATED_SEEKS)); + self.apply_multiplier(base_fee) } /// Estimate fee for document replacement (uses default estimate of ~200 bytes). @@ -332,27 +385,31 @@ impl PlatformFeeEstimator { pub fn estimate_document_transfer(&self) -> u64 { const ESTIMATED_SEEKS: usize = 8; const OWNERSHIP_UPDATE_BYTES: usize = 64; - self.min_fees.document_batch_sub_transition.saturating_add( - self.estimate_storage_based_fee(OWNERSHIP_UPDATE_BYTES, ESTIMATED_SEEKS), - ) + let base_fee = self.min_fees.document_batch_sub_transition.saturating_add( + self.calculate_storage_based_fee(OWNERSHIP_UPDATE_BYTES, ESTIMATED_SEEKS), + ); + self.apply_multiplier(base_fee) } /// Estimate fee for document purchase. pub fn estimate_document_purchase(&self) -> u64 { const ESTIMATED_SEEKS: usize = 10; const PURCHASE_UPDATE_BYTES: usize = 100; - self.min_fees - .document_batch_sub_transition - .saturating_add(self.estimate_storage_based_fee(PURCHASE_UPDATE_BYTES, ESTIMATED_SEEKS)) + let base_fee = self.min_fees.document_batch_sub_transition.saturating_add( + self.calculate_storage_based_fee(PURCHASE_UPDATE_BYTES, ESTIMATED_SEEKS), + ); + self.apply_multiplier(base_fee) } /// Estimate fee for document set price. pub fn estimate_document_set_price(&self) -> u64 { const ESTIMATED_SEEKS: usize = 8; const PRICE_UPDATE_BYTES: usize = 32; - self.min_fees + let base_fee = self + .min_fees .document_batch_sub_transition - .saturating_add(self.estimate_storage_based_fee(PRICE_UPDATE_BYTES, ESTIMATED_SEEKS)) + .saturating_add(self.calculate_storage_based_fee(PRICE_UPDATE_BYTES, ESTIMATED_SEEKS)); + self.apply_multiplier(base_fee) } /// Estimate fee for token transition (mint, burn, transfer, freeze, etc.). @@ -360,9 +417,11 @@ impl PlatformFeeEstimator { pub fn estimate_token_transition(&self) -> u64 { const ESTIMATED_SEEKS: usize = 8; const TOKEN_OP_BYTES: usize = 100; - self.min_fees + let base_fee = self + .min_fees .document_batch_sub_transition - .saturating_add(self.estimate_storage_based_fee(TOKEN_OP_BYTES, ESTIMATED_SEEKS)) + .saturating_add(self.calculate_storage_based_fee(TOKEN_OP_BYTES, ESTIMATED_SEEKS)); + self.apply_multiplier(base_fee) } /// Estimate fee for data contract creation with known size. @@ -370,10 +429,12 @@ impl PlatformFeeEstimator { /// For contracts with tokens, document types, or indexes, use the detailed method. pub fn estimate_contract_create_with_size(&self, contract_bytes: usize) -> u64 { const ESTIMATED_SEEKS: usize = 20; - self.registration_fees + let base_fee = self + .registration_fees .base_contract_registration_fee .saturating_add(self.min_fees.contract_create) - .saturating_add(self.estimate_storage_based_fee(contract_bytes, ESTIMATED_SEEKS)) + .saturating_add(self.calculate_storage_based_fee(contract_bytes, ESTIMATED_SEEKS)); + self.apply_multiplier(base_fee) } /// Estimate fee for data contract creation with detailed component counts. @@ -393,27 +454,27 @@ impl PlatformFeeEstimator { ) -> u64 { const ESTIMATED_SEEKS: usize = 20; - let mut fee = self.registration_fees.base_contract_registration_fee; + let mut base_fee = self.registration_fees.base_contract_registration_fee; // Document type fees - fee = fee.saturating_add( + base_fee = base_fee.saturating_add( self.registration_fees .document_type_registration_fee .saturating_mul(document_type_count as u64), ); // Index fees - fee = fee.saturating_add( + base_fee = base_fee.saturating_add( self.registration_fees .document_type_base_non_unique_index_registration_fee .saturating_mul(non_unique_index_count as u64), ); - fee = fee.saturating_add( + base_fee = base_fee.saturating_add( self.registration_fees .document_type_base_unique_index_registration_fee .saturating_mul(unique_index_count as u64), ); - fee = fee.saturating_add( + base_fee = base_fee.saturating_add( self.registration_fees .document_type_base_contested_index_registration_fee .saturating_mul(contested_index_count as u64), @@ -421,30 +482,32 @@ impl PlatformFeeEstimator { // Token fees if has_token { - fee = fee.saturating_add(self.registration_fees.token_registration_fee); + base_fee = base_fee.saturating_add(self.registration_fees.token_registration_fee); } if has_perpetual_distribution { - fee = fee.saturating_add(self.registration_fees.token_uses_perpetual_distribution_fee); + base_fee = base_fee + .saturating_add(self.registration_fees.token_uses_perpetual_distribution_fee); } if has_pre_programmed_distribution { - fee = fee.saturating_add( + base_fee = base_fee.saturating_add( self.registration_fees .token_uses_pre_programmed_distribution_fee, ); } // Search keyword fees - fee = fee.saturating_add( + base_fee = base_fee.saturating_add( self.registration_fees .search_keyword_fee .saturating_mul(search_keyword_count as u64), ); // Add state transition minimum and storage fees - fee = fee.saturating_add(self.min_fees.contract_create); - fee = fee.saturating_add(self.estimate_storage_based_fee(contract_bytes, ESTIMATED_SEEKS)); + base_fee = base_fee.saturating_add(self.min_fees.contract_create); + base_fee = base_fee + .saturating_add(self.calculate_storage_based_fee(contract_bytes, ESTIMATED_SEEKS)); - fee + self.apply_multiplier(base_fee) } /// Estimate fee for data contract creation (uses base registration fee only). @@ -458,9 +521,11 @@ impl PlatformFeeEstimator { /// Estimate fee for data contract update with known size of changes. pub fn estimate_contract_update_with_size(&self, update_bytes: usize) -> u64 { const ESTIMATED_SEEKS: usize = 15; - self.min_fees + let base_fee = self + .min_fees .contract_update - .saturating_add(self.estimate_storage_based_fee(update_bytes, ESTIMATED_SEEKS)) + .saturating_add(self.calculate_storage_based_fee(update_bytes, ESTIMATED_SEEKS)); + self.apply_multiplier(base_fee) } /// Estimate fee for data contract update (uses default estimate). @@ -475,19 +540,22 @@ impl PlatformFeeEstimator { /// Estimate fee for masternode vote pub fn estimate_masternode_vote(&self) -> u64 { - self.min_fees.masternode_vote + self.apply_multiplier(self.min_fees.masternode_vote) } - /// Estimate fee for address funds transfer + /// Estimate fee for address funds transfer. + /// Applies the current fee multiplier. pub fn estimate_address_funds_transfer(&self, input_count: usize, output_count: usize) -> u64 { - self.min_fees + let base_fee = self + .min_fees .address_funds_transfer_input_cost .saturating_mul(input_count as u64) .saturating_add( self.min_fees .address_funds_transfer_output_cost .saturating_mul(output_count.max(1) as u64), - ) + ); + self.apply_multiplier(base_fee) } /// Get the raw minimum fees structure diff --git a/src/ui/contracts_documents/document_action_screen.rs b/src/ui/contracts_documents/document_action_screen.rs index 33cce0944..5aaab004d 100644 --- a/src/ui/contracts_documents/document_action_screen.rs +++ b/src/ui/contracts_documents/document_action_screen.rs @@ -3,7 +3,7 @@ use crate::backend_task::BackendTaskSuccessResult; use crate::backend_task::FeeResult; use crate::backend_task::{BackendTask, document::DocumentTask}; use crate::context::AppContext; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_contract::QualifiedContract; use crate::model::qualified_identity::QualifiedIdentity; use crate::model::wallet::Wallet; @@ -871,7 +871,7 @@ impl DocumentActionScreen { let mut action = AppAction::None; // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = match self.action_type { DocumentActionType::Create => fee_estimator.estimate_document_create(), DocumentActionType::Delete => fee_estimator.estimate_document_delete(), diff --git a/src/ui/contracts_documents/register_contract_screen.rs b/src/ui/contracts_documents/register_contract_screen.rs index 10bdd2648..7b16edcc8 100644 --- a/src/ui/contracts_documents/register_contract_screen.rs +++ b/src/ui/contracts_documents/register_contract_screen.rs @@ -215,7 +215,9 @@ impl RegisterDataContractScreen { let registration_fee = contract.registration_cost(platform_version).unwrap_or(0); // Add storage and processing fees for the contract data let contract_size = self.contract_json_input.len(); - let storage_fee = crate::model::fee_estimation::PlatformFeeEstimator::new() + let storage_fee = self + .app_context + .fee_estimator() .estimate_storage_based_fee(contract_size, 20); // ~20 seeks for tree operations let estimated_fee = registration_fee.saturating_add(storage_fee); ui.add_space(10.0); diff --git a/src/ui/dashpay/profile_screen.rs b/src/ui/dashpay/profile_screen.rs index 1071b0ea2..b5997aa34 100644 --- a/src/ui/dashpay/profile_screen.rs +++ b/src/ui/dashpay/profile_screen.rs @@ -2,7 +2,7 @@ use crate::app::AppAction; use crate::backend_task::dashpay::DashPayTask; use crate::backend_task::{BackendTask, BackendTaskSuccessResult}; use crate::context::AppContext; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_identity::QualifiedIdentity; use crate::model::wallet::Wallet; use crate::ui::MessageType; @@ -905,7 +905,7 @@ impl ProfileScreen { }); } else { // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); // Profile creation/update is a document operation let estimated_fee = if self.profile.is_some() { fee_estimator.estimate_document_replace() diff --git a/src/ui/identities/add_new_identity_screen/by_platform_address.rs b/src/ui/identities/add_new_identity_screen/by_platform_address.rs index 6f46ee6de..6ef7a3335 100644 --- a/src/ui/identities/add_new_identity_screen/by_platform_address.rs +++ b/src/ui/identities/add_new_identity_screen/by_platform_address.rs @@ -1,6 +1,6 @@ use crate::app::AppAction; use crate::model::amount::Amount; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::ui::components::amount_input::AmountInput; use crate::ui::components::component_trait::{Component, ComponentResponse}; use crate::ui::identities::add_new_identity_screen::{ @@ -197,11 +197,10 @@ impl AddNewIdentityScreen { } else { 0 }; - let estimated_fee = PlatformFeeEstimator::new().estimate_identity_create_from_addresses( - input_count, - false, - key_count, - ); + let estimated_fee = self + .app_context + .fee_estimator() + .estimate_identity_create_from_addresses(input_count, false, key_count); let dark_mode = ui.ctx().style().visuals.dark_mode; egui::Frame::new() .fill(crate::ui::theme::DashColors::surface(dark_mode)) diff --git a/src/ui/identities/add_new_identity_screen/by_using_unused_asset_lock.rs b/src/ui/identities/add_new_identity_screen/by_using_unused_asset_lock.rs index 8e54268d9..faa61f56e 100644 --- a/src/ui/identities/add_new_identity_screen/by_using_unused_asset_lock.rs +++ b/src/ui/identities/add_new_identity_screen/by_using_unused_asset_lock.rs @@ -1,5 +1,5 @@ use crate::app::AppAction; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::ui::identities::add_new_identity_screen::{ AddNewIdentityScreen, FundingMethod, WalletFundedScreenStep, }; @@ -104,7 +104,10 @@ impl AddNewIdentityScreen { // Display estimated fee before action button let key_count = self.identity_keys.keys_input.len() + 1; // +1 for master key - let estimated_fee = PlatformFeeEstimator::new().estimate_identity_create(key_count); + let estimated_fee = self + .app_context + .fee_estimator() + .estimate_identity_create(key_count); ui.add_space(10.0); let dark_mode = ui.ctx().style().visuals.dark_mode; egui::Frame::new() diff --git a/src/ui/identities/add_new_identity_screen/by_using_unused_balance.rs b/src/ui/identities/add_new_identity_screen/by_using_unused_balance.rs index f736eb3dd..e06a0a97c 100644 --- a/src/ui/identities/add_new_identity_screen/by_using_unused_balance.rs +++ b/src/ui/identities/add_new_identity_screen/by_using_unused_balance.rs @@ -1,5 +1,5 @@ use crate::app::AppAction; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::ui::identities::add_new_identity_screen::{ AddNewIdentityScreen, FundingMethod, WalletFundedScreenStep, }; @@ -57,7 +57,10 @@ impl AddNewIdentityScreen { // Display estimated fee before action button let key_count = self.identity_keys.keys_input.len() + 1; // +1 for master key - let estimated_fee = PlatformFeeEstimator::new().estimate_identity_create(key_count); + let estimated_fee = self + .app_context + .fee_estimator() + .estimate_identity_create(key_count); ui.add_space(10.0); let dark_mode = ui.ctx().style().visuals.dark_mode; egui::Frame::new() diff --git a/src/ui/identities/keys/add_key_screen.rs b/src/ui/identities/keys/add_key_screen.rs index 8a6927a25..d284f543a 100644 --- a/src/ui/identities/keys/add_key_screen.rs +++ b/src/ui/identities/keys/add_key_screen.rs @@ -2,7 +2,7 @@ use crate::app::AppAction; use crate::backend_task::identity::IdentityTask; use crate::backend_task::{BackendTask, BackendTaskSuccessResult, FeeResult}; use crate::context::AppContext; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_identity::QualifiedIdentity; use crate::model::qualified_identity::qualified_identity_public_key::QualifiedIdentityPublicKey; use crate::model::wallet::Wallet; @@ -607,7 +607,7 @@ impl ScreenLike for AddKeyScreen { ui.add_space(20.0); // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_identity_update(); let dark_mode = ui.ctx().style().visuals.dark_mode; diff --git a/src/ui/identities/register_dpns_name_screen.rs b/src/ui/identities/register_dpns_name_screen.rs index 86356b2b0..6016a8458 100644 --- a/src/ui/identities/register_dpns_name_screen.rs +++ b/src/ui/identities/register_dpns_name_screen.rs @@ -2,7 +2,7 @@ use crate::app::AppAction; use crate::backend_task::identity::{IdentityTask, RegisterDpnsNameInput}; use crate::backend_task::{BackendTask, BackendTaskSuccessResult, FeeResult}; use crate::context::AppContext; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_identity::QualifiedIdentity; use crate::model::wallet::Wallet; use crate::ui::components::identity_selector::IdentitySelector; @@ -473,7 +473,7 @@ impl ScreenLike for RegisterDpnsNameScreen { ui.add_space(10.0); // Fee estimation - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_document_create(); let dark_mode = ui.ctx().style().visuals.dark_mode; diff --git a/src/ui/identities/top_up_identity_screen/by_platform_address.rs b/src/ui/identities/top_up_identity_screen/by_platform_address.rs index 1a589bd46..90e83820e 100644 --- a/src/ui/identities/top_up_identity_screen/by_platform_address.rs +++ b/src/ui/identities/top_up_identity_screen/by_platform_address.rs @@ -2,7 +2,7 @@ use crate::app::AppAction; use crate::backend_task::BackendTask; use crate::backend_task::identity::IdentityTask; use crate::model::amount::Amount; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::wallet::WalletSeedHash; use crate::ui::components::amount_input::AmountInput; use crate::ui::components::component_trait::{Component, ComponentResponse}; @@ -131,7 +131,7 @@ impl TopUpIdentityScreen { ui.add_space(10.0); // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_identity_topup(); Frame::new() diff --git a/src/ui/identities/top_up_identity_screen/by_using_unused_asset_lock.rs b/src/ui/identities/top_up_identity_screen/by_using_unused_asset_lock.rs index 9d0137023..f6fc658df 100644 --- a/src/ui/identities/top_up_identity_screen/by_using_unused_asset_lock.rs +++ b/src/ui/identities/top_up_identity_screen/by_using_unused_asset_lock.rs @@ -1,5 +1,5 @@ use crate::app::AppAction; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::ui::identities::add_new_identity_screen::FundingMethod; use crate::ui::identities::top_up_identity_screen::{TopUpIdentityScreen, WalletFundedScreenStep}; use crate::ui::theme::DashColors; @@ -95,7 +95,7 @@ impl TopUpIdentityScreen { ui.add_space(10.0); // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_identity_topup(); let dark_mode = ui.ctx().style().visuals.dark_mode; diff --git a/src/ui/identities/top_up_identity_screen/by_using_unused_balance.rs b/src/ui/identities/top_up_identity_screen/by_using_unused_balance.rs index 3cf524855..1bcd0227b 100644 --- a/src/ui/identities/top_up_identity_screen/by_using_unused_balance.rs +++ b/src/ui/identities/top_up_identity_screen/by_using_unused_balance.rs @@ -1,5 +1,5 @@ use crate::app::AppAction; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::ui::identities::add_new_identity_screen::FundingMethod; use crate::ui::identities::top_up_identity_screen::{TopUpIdentityScreen, WalletFundedScreenStep}; use crate::ui::theme::DashColors; @@ -48,7 +48,7 @@ impl TopUpIdentityScreen { }; // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_identity_topup(); let dark_mode = ui.ctx().style().visuals.dark_mode; diff --git a/src/ui/identities/transfer_screen.rs b/src/ui/identities/transfer_screen.rs index 661bfe23a..9d4f35ee9 100644 --- a/src/ui/identities/transfer_screen.rs +++ b/src/ui/identities/transfer_screen.rs @@ -3,7 +3,7 @@ use crate::backend_task::identity::IdentityTask; use crate::backend_task::{BackendTask, BackendTaskSuccessResult, FeeResult}; use crate::context::AppContext; use crate::model::amount::Amount; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_identity::QualifiedIdentity; use crate::model::wallet::Wallet; use crate::ui::components::amount_input::AmountInput; @@ -667,7 +667,7 @@ impl ScreenLike for TransferScreen { ui.add_space(10.0); // Fee estimation - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = match self.destination_type { TransferDestinationType::Identity => fee_estimator.estimate_credit_transfer(), TransferDestinationType::PlatformAddress => { diff --git a/src/ui/identities/withdraw_screen.rs b/src/ui/identities/withdraw_screen.rs index 7cc8bb8c4..1ea5aebee 100644 --- a/src/ui/identities/withdraw_screen.rs +++ b/src/ui/identities/withdraw_screen.rs @@ -3,7 +3,7 @@ use crate::backend_task::identity::IdentityTask; use crate::backend_task::{BackendTask, BackendTaskSuccessResult, FeeResult}; use crate::context::AppContext; use crate::model::amount::Amount; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_identity::encrypted_key_storage::PrivateKeyData; use crate::model::qualified_identity::{IdentityType, PrivateKeyTarget, QualifiedIdentity}; use crate::model::wallet::Wallet; @@ -520,7 +520,7 @@ impl ScreenLike for WithdrawalScreen { ui.add_space(10.0); // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_credit_withdrawal(); let dark_mode = ui.ctx().style().visuals.dark_mode; diff --git a/src/ui/tokens/burn_tokens_screen.rs b/src/ui/tokens/burn_tokens_screen.rs index 8373679f4..f4aaf7dcb 100644 --- a/src/ui/tokens/burn_tokens_screen.rs +++ b/src/ui/tokens/burn_tokens_screen.rs @@ -1,5 +1,5 @@ use crate::backend_task::{BackendTaskSuccessResult, FeeResult}; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::ui::components::amount_input::AmountInput; use crate::ui::components::confirmation_dialog::{ConfirmationDialog, ConfirmationStatus}; use crate::ui::components::left_panel::add_left_panel; @@ -562,7 +562,7 @@ impl ScreenLike for BurnTokensScreen { } // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_document_batch(1); // Token operations are document batch transitions Frame::new() @@ -593,7 +593,7 @@ impl ScreenLike for BurnTokensScreen { ); // Display estimated fee before action button - let estimated_fee = PlatformFeeEstimator::new().estimate_token_transition(); + let estimated_fee = fee_estimator.estimate_token_transition(); ui.add_space(10.0); let dark_mode = ui.ctx().style().visuals.dark_mode; egui::Frame::new() diff --git a/src/ui/tokens/claim_tokens_screen.rs b/src/ui/tokens/claim_tokens_screen.rs index 40d1a8c44..4d95f23d2 100644 --- a/src/ui/tokens/claim_tokens_screen.rs +++ b/src/ui/tokens/claim_tokens_screen.rs @@ -1,5 +1,5 @@ use crate::backend_task::{BackendTaskSuccessResult, FeeResult}; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::ui::components::Component; use crate::ui::components::confirmation_dialog::{ConfirmationDialog, ConfirmationStatus}; use crate::ui::components::left_panel::add_left_panel; @@ -512,7 +512,7 @@ impl ScreenLike for ClaimTokensScreen { } // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_document_batch(1); // Token operations are document batch transitions let dark_mode = ui.ctx().style().visuals.dark_mode; diff --git a/src/ui/tokens/destroy_frozen_funds_screen.rs b/src/ui/tokens/destroy_frozen_funds_screen.rs index 50435ae88..11d5f8784 100644 --- a/src/ui/tokens/destroy_frozen_funds_screen.rs +++ b/src/ui/tokens/destroy_frozen_funds_screen.rs @@ -3,7 +3,7 @@ use crate::app::AppAction; use crate::backend_task::tokens::TokenTask; use crate::backend_task::{BackendTask, BackendTaskSuccessResult, FeeResult}; use crate::context::AppContext; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_identity::QualifiedIdentity; use crate::model::wallet::Wallet; use crate::ui::components::component_trait::Component; @@ -548,7 +548,7 @@ impl ScreenLike for DestroyFrozenFundsScreen { } // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_document_batch(1); // Token operations are document batch transitions Frame::new() diff --git a/src/ui/tokens/direct_token_purchase_screen.rs b/src/ui/tokens/direct_token_purchase_screen.rs index c118995b6..997dc7c76 100644 --- a/src/ui/tokens/direct_token_purchase_screen.rs +++ b/src/ui/tokens/direct_token_purchase_screen.rs @@ -16,7 +16,7 @@ use crate::backend_task::tokens::TokenTask; use crate::backend_task::{BackendTask, BackendTaskSuccessResult, FeeResult}; use crate::context::AppContext; use crate::model::amount::{Amount, DASH_DECIMAL_PLACES}; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::wallet::Wallet; use crate::ui::components::amount_input::AmountInput; use crate::ui::components::confirmation_dialog::{ConfirmationDialog, ConfirmationStatus}; @@ -546,7 +546,7 @@ impl ScreenLike for PurchaseTokenScreen { ui.add_space(10.0); // Display estimated fee before action button - let estimated_fee = PlatformFeeEstimator::new().estimate_token_transition(); + let estimated_fee = self.app_context.fee_estimator().estimate_token_transition(); let dark_mode = ui.ctx().style().visuals.dark_mode; egui::Frame::new() .fill(crate::ui::theme::DashColors::surface(dark_mode)) diff --git a/src/ui/tokens/freeze_tokens_screen.rs b/src/ui/tokens/freeze_tokens_screen.rs index 41d9ca2f3..35ac3d6e4 100644 --- a/src/ui/tokens/freeze_tokens_screen.rs +++ b/src/ui/tokens/freeze_tokens_screen.rs @@ -3,7 +3,7 @@ use crate::app::AppAction; use crate::backend_task::tokens::TokenTask; use crate::backend_task::{BackendTask, BackendTaskSuccessResult, FeeResult}; use crate::context::AppContext; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_identity::QualifiedIdentity; use crate::model::wallet::Wallet; use crate::ui::components::component_trait::Component; @@ -532,7 +532,7 @@ impl ScreenLike for FreezeTokensScreen { } // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_document_batch(1); // Token operations are document batch transitions let dark_mode = ui.ctx().style().visuals.dark_mode; @@ -564,7 +564,7 @@ impl ScreenLike for FreezeTokensScreen { ); // Display estimated fee before action button - let estimated_fee = PlatformFeeEstimator::new().estimate_token_transition(); + let estimated_fee = fee_estimator.estimate_token_transition(); ui.add_space(10.0); let dark_mode = ui.ctx().style().visuals.dark_mode; egui::Frame::new() diff --git a/src/ui/tokens/mint_tokens_screen.rs b/src/ui/tokens/mint_tokens_screen.rs index c6c96ef24..0244d6797 100644 --- a/src/ui/tokens/mint_tokens_screen.rs +++ b/src/ui/tokens/mint_tokens_screen.rs @@ -4,7 +4,7 @@ use crate::backend_task::tokens::TokenTask; use crate::backend_task::{BackendTask, BackendTaskSuccessResult, FeeResult}; use crate::context::AppContext; use crate::model::amount::Amount; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_identity::QualifiedIdentity; use crate::model::wallet::Wallet; use crate::ui::components::amount_input::AmountInput; @@ -611,7 +611,7 @@ impl ScreenLike for MintTokensScreen { } // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_document_batch(1); // Token operations are document batch transitions Frame::new() @@ -642,7 +642,7 @@ impl ScreenLike for MintTokensScreen { ); // Display estimated fee before action button - let estimated_fee = PlatformFeeEstimator::new().estimate_token_transition(); + let estimated_fee = fee_estimator.estimate_token_transition(); ui.add_space(10.0); let dark_mode = ui.ctx().style().visuals.dark_mode; egui::Frame::new() diff --git a/src/ui/tokens/pause_tokens_screen.rs b/src/ui/tokens/pause_tokens_screen.rs index 00a8cd976..c6624398c 100644 --- a/src/ui/tokens/pause_tokens_screen.rs +++ b/src/ui/tokens/pause_tokens_screen.rs @@ -3,7 +3,7 @@ use crate::app::AppAction; use crate::backend_task::tokens::TokenTask; use crate::backend_task::{BackendTask, BackendTaskSuccessResult, FeeResult}; use crate::context::AppContext; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_identity::QualifiedIdentity; use crate::model::wallet::Wallet; use crate::ui::components::Component; @@ -459,7 +459,7 @@ impl ScreenLike for PauseTokensScreen { } // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_document_batch(1); // Token operations are document batch transitions let dark_mode = ui.ctx().style().visuals.dark_mode; diff --git a/src/ui/tokens/resume_tokens_screen.rs b/src/ui/tokens/resume_tokens_screen.rs index f447e6ec7..7e20dac1e 100644 --- a/src/ui/tokens/resume_tokens_screen.rs +++ b/src/ui/tokens/resume_tokens_screen.rs @@ -3,7 +3,7 @@ use crate::app::AppAction; use crate::backend_task::tokens::TokenTask; use crate::backend_task::{BackendTask, BackendTaskSuccessResult, FeeResult}; use crate::context::AppContext; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_identity::QualifiedIdentity; use crate::model::wallet::Wallet; use crate::ui::components::Component; @@ -460,7 +460,7 @@ impl ScreenLike for ResumeTokensScreen { } // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_document_batch(1); // Token operations are document batch transitions let dark_mode = ui.ctx().style().visuals.dark_mode; diff --git a/src/ui/tokens/set_token_price_screen.rs b/src/ui/tokens/set_token_price_screen.rs index b3a25a102..97392675b 100644 --- a/src/ui/tokens/set_token_price_screen.rs +++ b/src/ui/tokens/set_token_price_screen.rs @@ -4,7 +4,7 @@ use crate::backend_task::tokens::TokenTask; use crate::backend_task::{BackendTask, BackendTaskSuccessResult, FeeResult}; use crate::context::AppContext; use crate::model::amount::{Amount, DASH_DECIMAL_PLACES}; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::wallet::Wallet; use crate::ui::components::ComponentResponse; use crate::ui::components::amount_input::AmountInput; @@ -1080,7 +1080,7 @@ impl ScreenLike for SetTokenPriceScreen { }; // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_document_batch(1); // Token operations are document batch transitions let dark_mode = ui.ctx().style().visuals.dark_mode; diff --git a/src/ui/tokens/transfer_tokens_screen.rs b/src/ui/tokens/transfer_tokens_screen.rs index 77f010d71..8fffe040b 100644 --- a/src/ui/tokens/transfer_tokens_screen.rs +++ b/src/ui/tokens/transfer_tokens_screen.rs @@ -3,7 +3,7 @@ use crate::backend_task::tokens::TokenTask; use crate::backend_task::{BackendTask, BackendTaskSuccessResult, FeeResult}; use crate::context::AppContext; use crate::model::amount::Amount; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_identity::QualifiedIdentity; use crate::model::wallet::Wallet; use crate::ui::components::amount_input::AmountInput; @@ -455,7 +455,7 @@ impl ScreenLike for TransferTokensScreen { ui.add_space(10.0); // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_document_batch(1); // Token transfers are document batch transitions Frame::new() diff --git a/src/ui/tokens/unfreeze_tokens_screen.rs b/src/ui/tokens/unfreeze_tokens_screen.rs index 7e211227a..a0b97f777 100644 --- a/src/ui/tokens/unfreeze_tokens_screen.rs +++ b/src/ui/tokens/unfreeze_tokens_screen.rs @@ -3,7 +3,7 @@ use crate::app::AppAction; use crate::backend_task::tokens::TokenTask; use crate::backend_task::{BackendTask, BackendTaskSuccessResult, FeeResult}; use crate::context::AppContext; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_identity::QualifiedIdentity; use crate::model::wallet::Wallet; use crate::ui::components::component_trait::Component; @@ -535,7 +535,7 @@ impl ScreenLike for UnfreezeTokensScreen { } // Fee estimation display - let fee_estimator = PlatformFeeEstimator::new(); + let fee_estimator = self.app_context.fee_estimator(); let estimated_fee = fee_estimator.estimate_document_batch(1); // Token operations are document batch transitions let dark_mode = ui.ctx().style().visuals.dark_mode; diff --git a/src/ui/tokens/update_token_config.rs b/src/ui/tokens/update_token_config.rs index fdf783a3a..2aff65d1c 100644 --- a/src/ui/tokens/update_token_config.rs +++ b/src/ui/tokens/update_token_config.rs @@ -3,7 +3,7 @@ use crate::app::AppAction; use crate::backend_task::tokens::TokenTask; use crate::backend_task::{BackendTask, BackendTaskSuccessResult, FeeResult}; use crate::context::AppContext; -use crate::model::fee_estimation::{PlatformFeeEstimator, format_credits_as_dash}; +use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_identity::QualifiedIdentity; use crate::model::wallet::Wallet; use crate::ui::components::left_panel::add_left_panel; @@ -711,7 +711,7 @@ impl UpdateTokenConfigScreen { } // Display estimated fee before action button - let estimated_fee = PlatformFeeEstimator::new().estimate_token_transition(); + let estimated_fee = self.app_context.fee_estimator().estimate_token_transition(); ui.add_space(10.0); let dark_mode = ui.ctx().style().visuals.dark_mode; egui::Frame::new()