use crate::*; use near_sdk::{Gas, NearToken, Promise}; impl Contract { /// Update the policy change control settings pub fn internal_update_policy_change_control(&mut self, new_control: ChangeControl) { self.policy_change_control = new_control; } /// Get an active policy by ID, activating pending policy if ready pub fn internal_get_active_policy(&mut self, policy_id: &str) -> Option { let policy_key = policy_id.to_string(); // Check if there's a pending policy ready to activate if let Some(pending) = self.kernel_state.pending_policies.get(&policy_key) { if (env::block_timestamp() as u128) >= pending.activation_time.0 { // Activate pending policy self.kernel_state .policies .insert(policy_key.clone(), pending.clone()); self.kernel_state.pending_policies.remove(&policy_key); } } self.kernel_state.policies.get(&policy_key).cloned() } /// Get effective policy values without activation (for immutable access) pub fn get_effective_policy(&self, policy_id: &str) -> Option { let policy_key = policy_id.to_string(); // Check if there's a pending policy ready to activate if let Some(pending) = self.kernel_state.pending_policies.get(&policy_key) { if (env::block_timestamp() as u128) >= pending.activation_time.0 { return Some(pending.clone()); } } self.kernel_state.policies.get(&policy_key).cloned() } /// Get time elapsed since vault was created pub fn internal_get_time_since_created(&self) -> u128 { let current_time = env::block_timestamp(); (current_time as u128) .checked_sub(self.created_at.0) .expect("Clock error: current time is before vault created_at timestamp") } pub fn internal_initialize_vault(&mut self) { // Create individual policies for each vault configuration method // All policies start with owner role and vote count 1 let method_names = [ "grant_role", "revoke_role", "upsert_policy", "update_policy_change_control", "cancel_pending_policy", "force_activate_policy", "acquire_lock", "release_lock", "force_release_lock", "force_complete_pending_action", "batch_update_policies", "store_data", "batch_store_data", "delete_uploaded_contract", "deploy_uploaded_contract", ]; for method_name in method_names.iter() { let policy = Policy { id: method_name.to_string(), description: Some(format!("Policy for {} function", method_name)), required_role: "owner".to_string(), required_vote_count: 1, policy_type: PolicyType::KernelConfiguration, policy_details: permission::PolicyDetails::KernelConfiguration, activation_time: U128(0), // Immediately active proposal_expiry_time_nanosec: U128(DEFAULT_PROPOSAL_EXPIRY_TIME_NS), required_pending_actions: vec![], }; self.kernel_state .policies .insert(method_name.to_string(), policy); } } // ==================== Data Storage Functions ==================== /// Internal method to store a single key-value pair in data storage /// This method is protected by the proposal system pub fn internal_store_data(&mut self, key: String, value: String) { self.kernel_state.data_storage.insert(key, value); } /// Internal method to store multiple key-value pairs in data storage /// This method is protected by the proposal system pub fn internal_batch_store_data(&mut self, keys: Vec, values: Vec) { assert_eq!( keys.len(), values.len(), "Keys and values vectors must have the same length" ); for (key, value) in keys.into_iter().zip(values.into_iter()) { self.kernel_state.data_storage.insert(key, value); } } /// Delete staged contract code (Owner only) pub fn internal_delete_uploaded_contract(&mut self, code_hash: String) { require!( self.staged_code_hash.as_deref() == Some(&code_hash), "Uploaded contract code hash does not match" ); self.staged_wasm.set(None); self.staged_code_hash = None; } /// Deploy staged contract code and run migrate (Owner only) pub fn internal_deploy_uploaded_contract(&mut self, code_hash: String) -> Promise { require!( self.staged_code_hash.as_deref() == Some(&code_hash), "Uploaded contract code hash does not match" ); let code = self .staged_wasm .get() .clone() .expect("No uploaded contract code"); Promise::new(env::current_account_id()) .deploy_contract(code.clone()) .function_call( "migrate".to_string(), Vec::new(), NearToken::from_near(0), Gas::from_tgas(100), ) .as_return() } }