use super::*; use common_data::{asset::Asset, vault_config::VaultConfig}; use near_sdk::{json_types::Base64VecU8, AccountId}; use near_workspaces::{ network::Sandbox, types::{Gas, NearToken}, Account, Contract, Worker, }; use serde_json::json; use sha2::{Digest, Sha256}; /// Load factory_kernel WASM file pub fn load_factory_kernel_wasm() -> TestResult> { std::fs::read("./target/near/dew_kernel_factory/dew_kernel_factory.wasm").map_err(|_| { "Factory Kernel WASM not found. Run: cd factory_kernel && cargo near build non-reproducible-wasm".into() }) } /// Load factory_vault WASM file pub fn load_factory_vault_wasm() -> TestResult> { std::fs::read("./target/near/dew_vault_factory/dew_vault_factory.wasm").map_err(|_| { "Factory Vault WASM not found. Run: cd factory_vault && cargo near build non-reproducible-wasm".into() }) } /// Load kernel WASM file (dew_finance_contracts - the kernel) pub fn load_kernel_wasm() -> TestResult> { std::fs::read("./target/near/dew_finance_contracts.wasm") .map_err(|_| "Kernel WASM not found. Run: ./build.sh".into()) } /// Load dew_vault WASM file pub fn load_dew_vault_wasm() -> TestResult> { std::fs::read("./target/near/dew_vault/dew_vault.wasm").map_err(|_| { "Dew Vault WASM not found. Run: cd vault && cargo near build non-reproducible-wasm".into() }) } /// Compute SHA256 hash of WASM bytes fn compute_wasm_hash(wasm_bytes: &[u8]) -> Vec { let mut hasher = Sha256::new(); hasher.update(wasm_bytes); hasher.finalize().to_vec() } /// Deploy factory_kernel contract pub async fn deploy_factory_kernel( sandbox: &Worker, owner: &Account, ) -> TestResult { println!("🏗️ Deploying factory_kernel contract..."); let factory_wasm = load_factory_kernel_wasm()?; let factory = owner.deploy(&factory_wasm).await?.into_result()?; // Get the kernel WASM and compute its hash let kernel_wasm = load_kernel_wasm()?; let code_hash = compute_wasm_hash(&kernel_wasm); let code_hash_base64 = Base64VecU8::from(code_hash); // Initialize factory with owner and code hash owner .call(factory.id(), "new") .args_json(json!({ "owner_id": owner.id(), "latest_code_hash": code_hash_base64 })) .gas(Gas::from_tgas(DEFAULT_GAS)) .transact() .await? .into_result()?; println!("Factory Kernel deployed at: {}", factory.id()); Ok(factory) } /// Deploy factory_vault contract pub async fn deploy_factory_vault( sandbox: &Worker, owner: &Account, ) -> TestResult { println!("🏗️ Deploying factory_vault contract..."); let factory_wasm = load_factory_vault_wasm()?; let factory = owner.deploy(&factory_wasm).await?.into_result()?; // Get the vault WASM and compute its hash let vault_wasm = load_dew_vault_wasm()?; let code_hash = compute_wasm_hash(&vault_wasm); let code_hash_base64 = Base64VecU8::from(code_hash); // Initialize factory with owner and code hash owner .call(factory.id(), "new") .args_json(json!({ "owner_id": owner.id(), "latest_code_hash": code_hash_base64 })) .gas(Gas::from_tgas(DEFAULT_GAS)) .transact() .await? .into_result()?; println!("Factory Vault deployed at: {}", factory.id()); Ok(factory) } /// Create kernel via factory pub async fn create_kernel_via_factory( factory: &Contract, caller: &Account, base_asset: Asset, accepted_assets: Vec, extra_decimals: u8, ) -> TestResult { println!("🔧 Creating kernel via factory..."); println!(" Base asset: {}", base_asset); println!(" Accepted assets: {:?}", accepted_assets); // Generate child account ID based on factory let child_id: AccountId = format!("kernel-{}.{}", caller.id(), factory.id()) .parse() .map_err(|e| format!("Invalid child ID: {}", e))?; println!(" Target kernel ID: {}", child_id); // Call factory to create kernel let result = caller .call(factory.id(), "create_kernel") .args_json(json!({ "child_id": child_id, "base_asset": base_asset, "accepted_assets": accepted_assets, "extra_decimals": extra_decimals })) .deposit(NearToken::from_near(5)) // Attach deposit for new account creation .gas(Gas::from_tgas(DEFAULT_GAS)) .transact() .await?; // Check if transaction succeeded result.into_result()?; println!("Kernel created at: {}", child_id); Ok(child_id) } /// Create kernel via factory with custom config /// NOTE: Commented out as KernelConfig no longer exists after architectural refactoring /* pub async fn create_kernel_via_factory_with_config( factory: &Contract, caller: &Account, base_asset: Asset, accepted_assets: Vec, extra_decimals: u8, kernel_config: KernelConfig, ) -> TestResult { println!("🔧 Creating kernel via factory with custom config..."); // Generate child account ID based on factory let child_id: AccountId = format!("kernel-{}.{}", caller.id(), factory.id()) .parse() .map_err(|e| format!("Invalid child ID: {}", e))?; println!(" Target kernel ID: {}", child_id); // Call factory to create kernel with config let result = caller .call(factory.id(), "create_kernel_with_config") .args_json(json!({ "child_id": child_id, "base_asset": base_asset, "accepted_assets": accepted_assets, "extra_decimals": extra_decimals, "kernel_config": kernel_config, "protocol_config": null, "owner": caller.id() })) .deposit(NearToken::from_near(5)) .gas(Gas::from_tgas(DEFAULT_GAS)) .transact() .await?; result.into_result()?; println!("Kernel with config created at: {}", child_id); Ok(child_id) } */ /// Create vault via factory pub async fn create_vault_via_factory( factory: &Contract, caller: &Account, kernel_id: AccountId, base_asset: Asset, accepted_deposit_assets: Vec, available_redeem_assets: Vec, share_token_symbol: String, share_token_name: String, share_token_decimals: u8, ) -> TestResult { println!("💰 Creating vault via factory..."); println!(" Kernel: {}", kernel_id); println!(" Base asset: {}", base_asset); // Generate child account ID based on factory let child_id: AccountId = format!("vault-{}.{}", caller.id(), factory.id()) .parse() .map_err(|e| format!("Invalid child ID: {}", e))?; println!(" Target vault ID: {}", child_id); // Call factory to create vault let result = caller .call(factory.id(), "create_vault") .args_json(json!({ "child_id": child_id, "owner_account_id": kernel_id, "base_asset": base_asset, "accepted_deposit_assets": accepted_deposit_assets, "share_token_symbol": share_token_symbol, "share_token_name": share_token_name, "share_token_decimals": share_token_decimals })) .deposit(NearToken::from_near(5)) // Attach deposit for new account creation .gas(Gas::from_tgas(DEFAULT_GAS)) .transact() .await?; result.into_result()?; println!("Vault created at: {}", child_id); Ok(child_id) } /// Create vault via factory with custom config pub async fn create_vault_via_factory_with_config( factory: &Contract, caller: &Account, kernel_id: AccountId, base_asset: Asset, accepted_deposit_assets: Vec, available_redeem_assets: Vec, share_token_symbol: String, share_token_name: String, share_token_decimals: u8, vault_config: VaultConfig, ) -> TestResult { println!("💰 Creating vault via factory with custom config..."); // Generate child account ID based on factory let child_id: AccountId = format!("vault-{}.{}", caller.id(), factory.id()) .parse() .map_err(|e| format!("Invalid child ID: {}", e))?; println!(" Target vault ID: {}", child_id); // Call factory to create vault with config let result = caller .call(factory.id(), "create_vault_with_config") .args_json(json!({ "child_id": child_id, "owner_account_id": kernel_id, "base_asset": base_asset, "accepted_deposit_assets": accepted_deposit_assets, "available_redeem_assets": available_redeem_assets, "share_token_symbol": share_token_symbol, "share_token_name": share_token_name, "share_token_decimals": share_token_decimals, "vault_config": vault_config })) .deposit(NearToken::from_near(5)) .gas(Gas::from_tgas(DEFAULT_GAS)) .transact() .await?; result.into_result()?; println!("Vault with config created at: {}", child_id); Ok(child_id) }