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
28 changes: 17 additions & 11 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,22 @@ impl AppState {

let settings = db.get_settings().expect("expected to get settings");

let mainnet_app_context = match AppContext::new(Network::Dash, db.clone()) {
Some(context) => context,
None => {
eprintln!(
"Error: Failed to create the AppContext. Expected Dash config for mainnet."
);
std::process::exit(1);
}
};
let testnet_app_context = AppContext::new(Network::Testnet, db.clone());
let password_info = settings
.clone()
.map(|(_, _, password_info)| password_info)
.flatten();

let mainnet_app_context =
match AppContext::new(Network::Dash, db.clone(), password_info.clone()) {
Some(context) => context,
None => {
eprintln!(
"Error: Failed to create the AppContext. Expected Dash config for mainnet."
);
std::process::exit(1);
}
};
let testnet_app_context = AppContext::new(Network::Testnet, db.clone(), password_info);

let mut identities_screen = IdentitiesScreen::new(&mainnet_app_context);
let mut dpns_active_contests_screen =
Expand All @@ -153,7 +159,7 @@ impl AppState {

let mut chosen_network = Network::Dash;

if let Some((network, screen_type)) = settings {
if let Some((network, screen_type, password_info)) = settings {
selected_main_screen = screen_type;
chosen_network = network;
if chosen_network == Network::Testnet && testnet_app_context.is_some() {
Expand Down
2 changes: 1 addition & 1 deletion src/app_dir.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use directories::ProjectDirs;
use std::fs;
use std::path::{Path, PathBuf};
use std::path::PathBuf;

const QUALIFIER: &str = ""; // Typically empty on macOS and Linux
const ORGANIZATION: &str = "";
Expand Down
27 changes: 16 additions & 11 deletions src/backend_task/identity/add_key_to_identity.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use super::BackendTaskSuccessResult;
use crate::context::AppContext;
use crate::model::qualified_identity::EncryptedPrivateKeyTarget::PrivateKeyOnMainIdentity;
use crate::model::qualified_identity::qualified_identity_public_key::QualifiedIdentityPublicKey;
use crate::model::qualified_identity::PrivateKeyTarget::PrivateKeyOnMainIdentity;
use crate::model::qualified_identity::QualifiedIdentity;
use dash_sdk::dpp::identity::accessors::{IdentityGettersV0, IdentitySettersV0};
use dash_sdk::dpp::identity::identity_public_key::accessors::v0::{
Expand All @@ -10,17 +12,15 @@ use dash_sdk::dpp::state_transition::identity_update_transition::methods::Identi
use dash_sdk::dpp::state_transition::identity_update_transition::IdentityUpdateTransition;
use dash_sdk::dpp::state_transition::proof_result::StateTransitionProofResult;
use dash_sdk::platform::transition::broadcast::BroadcastStateTransition;
use dash_sdk::platform::{Fetch, Identity, IdentityPublicKey};
use dash_sdk::platform::{Fetch, Identity};
use dash_sdk::Sdk;

use super::BackendTaskSuccessResult;

impl AppContext {
pub(super) async fn add_key_to_identity(
&self,
sdk: &Sdk,
mut qualified_identity: QualifiedIdentity,
mut public_key_to_add: IdentityPublicKey,
mut public_key_to_add: QualifiedIdentityPublicKey,
private_key: [u8; 32],
) -> Result<BackendTaskSuccessResult, String> {
let new_identity_nonce = sdk
Expand All @@ -30,22 +30,27 @@ impl AppContext {
let Some(master_key) = qualified_identity.can_sign_with_master_key() else {
return Err("Master key not found".to_string());
};
let master_key_id = master_key.id();
let master_key_id = master_key.identity_public_key.id();
let identity = Identity::fetch_by_identifier(sdk, qualified_identity.identity.id())
.await
.map_err(|e| format!("Fetch nonce error: {}", e))?
.unwrap();
qualified_identity.identity = identity;
qualified_identity.identity.bump_revision();
public_key_to_add.set_id(qualified_identity.identity.get_public_key_max_id() + 1);
qualified_identity.encrypted_private_keys.insert(
(PrivateKeyOnMainIdentity, public_key_to_add.id()),
(public_key_to_add.clone(), private_key.clone()),
public_key_to_add
.identity_public_key
.set_id(qualified_identity.identity.get_public_key_max_id() + 1);
qualified_identity.private_keys.insert_non_encrypted(
(
PrivateKeyOnMainIdentity,
public_key_to_add.identity_public_key.id(),
),
(public_key_to_add.clone(), private_key),
);
let state_transition = IdentityUpdateTransition::try_from_identity_with_signer(
&qualified_identity.identity,
&master_key_id,
vec![public_key_to_add.clone()],
vec![public_key_to_add.identity_public_key.clone()],
vec![],
new_identity_nonce,
UserFeeIncrease::default(),
Expand Down
146 changes: 117 additions & 29 deletions src/backend_task/identity/load_identity.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
use super::BackendTaskSuccessResult;
use crate::backend_task::identity::{verify_key_input, IdentityInputToLoad};
use crate::context::AppContext;
use crate::model::qualified_identity::EncryptedPrivateKeyTarget::{
use crate::model::qualified_identity::encrypted_key_storage::PrivateKeyData;
use crate::model::qualified_identity::qualified_identity_public_key::QualifiedIdentityPublicKey;
use crate::model::qualified_identity::PrivateKeyTarget::{
self, PrivateKeyOnMainIdentity, PrivateKeyOnVoterIdentity,
};
use crate::model::qualified_identity::{DPNSNameInfo, IdentityType, QualifiedIdentity};
use dash_sdk::dashcore_rpc::dashcore::key::Secp256k1;
use dash_sdk::dashcore_rpc::dashcore::PrivateKey;
use dash_sdk::dpp::dashcore::hashes::Hash;
use dash_sdk::dpp::document::DocumentV0Getters;
use dash_sdk::dpp::identifier::MasternodeIdentifiers;
use dash_sdk::dpp::identity::accessors::IdentityGettersV0;
use dash_sdk::dpp::identity::identity_public_key::accessors::v0::IdentityPublicKeyGettersV0;
use dash_sdk::dpp::identity::{KeyType, SecurityLevel};
use dash_sdk::dpp::platform_value::string_encoding::Encoding;
use dash_sdk::dpp::platform_value::Value;
use dash_sdk::drive::query::{WhereClause, WhereOperator};
use dash_sdk::platform::{Document, DocumentQuery, Fetch, FetchMany, Identifier, Identity};
use dash_sdk::Sdk;
use std::collections::BTreeMap;

use super::BackendTaskSuccessResult;
use egui::ahash::HashMap;
use std::collections::{BTreeMap, HashSet};

impl AppContext {
pub(super) async fn load_identity(
Expand Down Expand Up @@ -61,13 +65,25 @@ impl AppContext {

let mut encrypted_private_keys = BTreeMap::new();

let wallets = self.wallets.read().unwrap().clone();

if identity_type != IdentityType::User && owner_private_key_bytes.is_some() {
let owner_private_key_bytes = owner_private_key_bytes.unwrap();
let key =
self.verify_owner_key_exists_on_identity(&identity, &owner_private_key_bytes)?;
let key_id = key.id();
let qualified_key =
QualifiedIdentityPublicKey::from_identity_public_key_with_wallets_check(
key,
self.network,
wallets.as_slice(),
);
encrypted_private_keys.insert(
(PrivateKeyOnMainIdentity, key.id()),
(key.clone(), owner_private_key_bytes),
(PrivateKeyOnMainIdentity, key_id),
(
qualified_key,
PrivateKeyData::Clear(owner_private_key_bytes),
),
);
}

Expand All @@ -77,9 +93,19 @@ impl AppContext {
&identity,
&payout_address_private_key_bytes,
)?;
let key_id = key.id();
let qualified_key =
QualifiedIdentityPublicKey::from_identity_public_key_with_wallets_check(
key,
self.network,
wallets.as_slice(),
);
encrypted_private_keys.insert(
(PrivateKeyOnMainIdentity, key.id()),
(key.clone(), payout_address_private_key_bytes),
(PrivateKeyOnMainIdentity, key_id),
(
qualified_key,
PrivateKeyData::Clear(payout_address_private_key_bytes),
),
);
}

Expand Down Expand Up @@ -108,9 +134,18 @@ impl AppContext {
&voter_identity,
&voting_private_key_bytes,
)?;
let qualified_key =
QualifiedIdentityPublicKey::from_identity_public_key_with_wallets_check(
key.clone(),
self.network,
wallets.as_slice(),
);
encrypted_private_keys.insert(
(PrivateKeyOnVoterIdentity, key.id()),
(key.clone(), voting_private_key_bytes),
(
qualified_key,
PrivateKeyData::Clear(voting_private_key_bytes),
),
);
Some((voter_identity, key))
} else {
Expand All @@ -121,25 +156,78 @@ impl AppContext {
};

if identity_type == IdentityType::User {
for (i, private_key_input) in keys_input.into_iter().enumerate() {
let key_id = i as u32;
let public_key = match identity.public_keys().get(&key_id) {
Some(key) => key,
None => return Err("No public key matching key id {key_id}".to_string()),
};
let private_key_bytes = match verify_key_input(
private_key_input,
&public_key.key_type().to_string(),
)? {
Some(bytes) => bytes,
None => {
return Err("Private key input length is 0 for key id {key_id}".to_string())
}
};
encrypted_private_keys.insert(
(EncryptedPrivateKeyTarget::PrivateKeyOnMainIdentity, key_id),
(public_key.clone(), private_key_bytes),
);
let input_private_keys = keys_input
.into_iter()
.filter_map(|key_string| {
Some(
verify_key_input(key_string, "User Key")
.transpose()?
.and_then(|sk| {
PrivateKey::from_slice(sk.as_slice(), self.network)
.map_err(|e| e.to_string())
}),
)
})
.collect::<Result<Vec<PrivateKey>, String>>()?;

let secp = Secp256k1::new();
let (public_key_lookup, public_key_hash_lookup): (
HashMap<Vec<u8>, [u8; 32]>,
HashMap<[u8; 20], [u8; 32]>,
) = input_private_keys
.into_iter()
.map(|private_key| {
let public_key = private_key.public_key(&secp);
let public_key_bytes = public_key.to_bytes();
let pub_key_hash = public_key.pubkey_hash().to_byte_array();
(
(public_key_bytes, private_key.inner.secret_bytes()),
(pub_key_hash, private_key.inner.secret_bytes()),
)
})
.unzip();

for (&key_id, public_key) in identity.public_keys().iter() {
let qualified_key =
QualifiedIdentityPublicKey::from_identity_public_key_with_wallets_check(
public_key.clone(),
self.network,
wallets.as_slice(),
);

if let Some(wallet_derivation_path) =
qualified_key.in_wallet_at_derivation_path.clone()
{
encrypted_private_keys.insert(
(PrivateKeyTarget::PrivateKeyOnMainIdentity, key_id),
(
qualified_key,
PrivateKeyData::AtWalletDerivationPath(wallet_derivation_path),
),
);
} else if let Some(private_key_bytes) =
public_key_lookup.get(public_key.data().0.as_slice())
{
let private_data = match public_key.security_level() {
SecurityLevel::MEDIUM => PrivateKeyData::AlwaysClear(*private_key_bytes),
_ => PrivateKeyData::Clear(*private_key_bytes),
};
encrypted_private_keys.insert(
(PrivateKeyTarget::PrivateKeyOnMainIdentity, key_id),
(qualified_key, private_data),
);
} else if let Some(private_key_bytes) =
public_key_hash_lookup.get(public_key.data().0.as_slice())
{
let private_data = match public_key.security_level() {
SecurityLevel::MEDIUM => PrivateKeyData::AlwaysClear(*private_key_bytes),
_ => PrivateKeyData::Clear(*private_key_bytes),
};
encrypted_private_keys.insert(
(PrivateKeyTarget::PrivateKeyOnMainIdentity, key_id),
(qualified_key, private_data),
);
}
}
}

Expand Down Expand Up @@ -198,7 +286,7 @@ impl AppContext {
} else {
Some(alias_input)
},
encrypted_private_keys,
private_keys: encrypted_private_keys.into(),
dpns_names: maybe_owned_dpns_names,
};

Expand Down
Loading