rwda ui implementation
This commit is contained in:
691
actix_mvc_app/src/controllers/asset.rs
Normal file
691
actix_mvc_app/src/controllers/asset.rs
Normal file
@@ -0,0 +1,691 @@
|
||||
use actix_web::{web, HttpResponse, Result};
|
||||
use tera::{Context, Tera};
|
||||
use chrono::{Utc, Duration};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::models::asset::{Asset, AssetType, AssetStatus, BlockchainInfo, ValuationPoint, AssetTransaction, AssetStatistics};
|
||||
use crate::utils::render_template;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct AssetForm {
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub asset_type: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct ValuationForm {
|
||||
pub value: f64,
|
||||
pub currency: String,
|
||||
pub source: String,
|
||||
pub notes: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct TransactionForm {
|
||||
pub transaction_type: String,
|
||||
pub from_address: Option<String>,
|
||||
pub to_address: Option<String>,
|
||||
pub amount: Option<f64>,
|
||||
pub currency: Option<String>,
|
||||
pub transaction_hash: Option<String>,
|
||||
pub notes: Option<String>,
|
||||
}
|
||||
|
||||
pub struct AssetController;
|
||||
|
||||
impl AssetController {
|
||||
// Display the assets dashboard
|
||||
pub async fn index(tmpl: web::Data<Tera>) -> Result<HttpResponse> {
|
||||
let mut context = Context::new();
|
||||
|
||||
println!("DEBUG: Starting assets dashboard rendering");
|
||||
|
||||
let assets = Self::get_mock_assets();
|
||||
println!("DEBUG: Generated {} mock assets", assets.len());
|
||||
|
||||
let stats = AssetStatistics::new(&assets);
|
||||
println!("DEBUG: Generated asset statistics: {:?}", stats);
|
||||
|
||||
// Add active_page for navigation highlighting
|
||||
context.insert("active_page", &"assets");
|
||||
|
||||
// Add stats
|
||||
context.insert("stats", &serde_json::to_value(stats).unwrap());
|
||||
println!("DEBUG: Added stats to context");
|
||||
|
||||
// Add recent assets
|
||||
let recent_assets: Vec<serde_json::Map<String, serde_json::Value>> = assets
|
||||
.iter()
|
||||
.take(5)
|
||||
.map(|a| Self::asset_to_json(a))
|
||||
.collect();
|
||||
|
||||
context.insert("recent_assets", &recent_assets);
|
||||
|
||||
// Add assets by type
|
||||
let asset_types = vec![
|
||||
AssetType::NFT,
|
||||
AssetType::Token,
|
||||
AssetType::RealEstate,
|
||||
AssetType::Commodity,
|
||||
AssetType::Share,
|
||||
AssetType::Bond,
|
||||
AssetType::IntellectualProperty,
|
||||
AssetType::Other,
|
||||
];
|
||||
|
||||
let assets_by_type: Vec<serde_json::Map<String, serde_json::Value>> = asset_types
|
||||
.iter()
|
||||
.map(|asset_type| {
|
||||
let mut map = serde_json::Map::new();
|
||||
let type_str = asset_type.as_str();
|
||||
let count = assets.iter().filter(|a| a.asset_type == *asset_type).count();
|
||||
|
||||
map.insert("type".to_string(), serde_json::Value::String(type_str.to_string()));
|
||||
map.insert("count".to_string(), serde_json::Value::Number(serde_json::Number::from(count)));
|
||||
|
||||
map
|
||||
})
|
||||
.collect();
|
||||
|
||||
context.insert("assets_by_type", &assets_by_type);
|
||||
|
||||
println!("DEBUG: Rendering assets dashboard template");
|
||||
let response = render_template(&tmpl, "assets/index.html", &context);
|
||||
println!("DEBUG: Finished rendering assets dashboard template");
|
||||
response
|
||||
}
|
||||
|
||||
// Display the list of all assets
|
||||
pub async fn list(tmpl: web::Data<Tera>) -> Result<HttpResponse> {
|
||||
let mut context = Context::new();
|
||||
|
||||
println!("DEBUG: Starting assets list rendering");
|
||||
|
||||
let assets = Self::get_mock_assets();
|
||||
println!("DEBUG: Generated {} mock assets", assets.len());
|
||||
|
||||
let assets_data: Vec<serde_json::Map<String, serde_json::Value>> = assets
|
||||
.iter()
|
||||
.map(|a| Self::asset_to_json(a))
|
||||
.collect();
|
||||
|
||||
// Add active_page for navigation highlighting
|
||||
context.insert("active_page", &"assets");
|
||||
|
||||
context.insert("assets", &assets_data);
|
||||
context.insert("filter", &"all");
|
||||
|
||||
println!("DEBUG: Rendering assets list template");
|
||||
let response = render_template(&tmpl, "assets/list.html", &context);
|
||||
println!("DEBUG: Finished rendering assets list template");
|
||||
response
|
||||
}
|
||||
|
||||
// Display the list of user's assets
|
||||
pub async fn my_assets(tmpl: web::Data<Tera>) -> Result<HttpResponse> {
|
||||
let mut context = Context::new();
|
||||
|
||||
println!("DEBUG: Starting my assets rendering");
|
||||
|
||||
let assets = Self::get_mock_assets();
|
||||
println!("DEBUG: Generated {} mock assets", assets.len());
|
||||
|
||||
let assets_data: Vec<serde_json::Map<String, serde_json::Value>> = assets
|
||||
.iter()
|
||||
.map(|a| Self::asset_to_json(a))
|
||||
.collect();
|
||||
|
||||
// Add active_page for navigation highlighting
|
||||
context.insert("active_page", &"assets");
|
||||
|
||||
context.insert("assets", &assets_data);
|
||||
|
||||
println!("DEBUG: Rendering my assets template");
|
||||
let response = render_template(&tmpl, "assets/my_assets.html", &context);
|
||||
println!("DEBUG: Finished rendering my assets template");
|
||||
response
|
||||
}
|
||||
|
||||
// Display a specific asset
|
||||
pub async fn detail(tmpl: web::Data<Tera>, path: web::Path<String>) -> Result<HttpResponse> {
|
||||
let asset_id = path.into_inner();
|
||||
let mut context = Context::new();
|
||||
|
||||
println!("DEBUG: Starting asset detail rendering");
|
||||
|
||||
// Add active_page for navigation highlighting
|
||||
context.insert("active_page", &"assets");
|
||||
|
||||
// Find the asset by ID
|
||||
let assets = Self::get_mock_assets();
|
||||
let asset = assets.iter().find(|a| a.id == asset_id);
|
||||
|
||||
match asset {
|
||||
Some(asset) => {
|
||||
println!("DEBUG: Found asset with ID {}", asset_id);
|
||||
|
||||
// Convert asset to JSON
|
||||
let asset_json = Self::asset_to_json(asset);
|
||||
|
||||
context.insert("asset", &asset_json);
|
||||
|
||||
// Add valuation history for chart
|
||||
let valuation_history: Vec<serde_json::Map<String, serde_json::Value>> = asset
|
||||
.sorted_valuation_history()
|
||||
.iter()
|
||||
.map(|v| {
|
||||
let mut map = serde_json::Map::new();
|
||||
map.insert("date".to_string(), serde_json::Value::String(v.date.format("%Y-%m-%d").to_string()));
|
||||
map.insert("value".to_string(), serde_json::Value::Number(serde_json::Number::from_f64(v.value).unwrap()));
|
||||
map.insert("currency".to_string(), serde_json::Value::String(v.currency.clone()));
|
||||
map
|
||||
})
|
||||
.collect();
|
||||
|
||||
context.insert("valuation_history", &valuation_history);
|
||||
|
||||
println!("DEBUG: Rendering asset detail template");
|
||||
let response = render_template(&tmpl, "assets/detail.html", &context);
|
||||
println!("DEBUG: Finished rendering asset detail template");
|
||||
response
|
||||
},
|
||||
None => {
|
||||
println!("DEBUG: Asset not found with ID {}", asset_id);
|
||||
Ok(HttpResponse::NotFound().finish())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Display the create asset form
|
||||
pub async fn create_form(tmpl: web::Data<Tera>) -> Result<HttpResponse> {
|
||||
let mut context = Context::new();
|
||||
|
||||
println!("DEBUG: Starting create asset form rendering");
|
||||
|
||||
// Add active_page for navigation highlighting
|
||||
context.insert("active_page", &"assets");
|
||||
|
||||
// Add asset types for dropdown
|
||||
let asset_types = vec![
|
||||
("NFT", "NFT"),
|
||||
("Token", "Token"),
|
||||
("RealEstate", "Real Estate"),
|
||||
("Commodity", "Commodity"),
|
||||
("Share", "Share"),
|
||||
("Bond", "Bond"),
|
||||
("IntellectualProperty", "Intellectual Property"),
|
||||
("Other", "Other")
|
||||
];
|
||||
|
||||
context.insert("asset_types", &asset_types);
|
||||
|
||||
println!("DEBUG: Rendering create asset form template");
|
||||
let response = render_template(&tmpl, "assets/create.html", &context);
|
||||
println!("DEBUG: Finished rendering create asset form template");
|
||||
response
|
||||
}
|
||||
|
||||
// Process the create asset form
|
||||
pub async fn create(
|
||||
_tmpl: web::Data<Tera>,
|
||||
_form: web::Form<AssetForm>,
|
||||
) -> Result<HttpResponse> {
|
||||
println!("DEBUG: Processing create asset form");
|
||||
|
||||
// In a real application, we would save the asset to the database
|
||||
// For now, we'll just redirect to the assets list
|
||||
|
||||
Ok(HttpResponse::Found().append_header(("Location", "/assets")).finish())
|
||||
}
|
||||
|
||||
// Add a valuation to an asset
|
||||
pub async fn add_valuation(
|
||||
_tmpl: web::Data<Tera>,
|
||||
path: web::Path<String>,
|
||||
_form: web::Form<ValuationForm>,
|
||||
) -> Result<HttpResponse> {
|
||||
let asset_id = path.into_inner();
|
||||
|
||||
println!("DEBUG: Adding valuation to asset with ID {}", asset_id);
|
||||
|
||||
// In a real application, we would update the asset in the database
|
||||
// For now, we'll just redirect to the asset detail page
|
||||
|
||||
Ok(HttpResponse::Found().append_header(("Location", format!("/assets/{}", asset_id))).finish())
|
||||
}
|
||||
|
||||
// Add a transaction to an asset
|
||||
pub async fn add_transaction(
|
||||
_tmpl: web::Data<Tera>,
|
||||
path: web::Path<String>,
|
||||
_form: web::Form<TransactionForm>,
|
||||
) -> Result<HttpResponse> {
|
||||
let asset_id = path.into_inner();
|
||||
|
||||
println!("DEBUG: Adding transaction to asset with ID {}", asset_id);
|
||||
|
||||
// In a real application, we would update the asset in the database
|
||||
// For now, we'll just redirect to the asset detail page
|
||||
|
||||
Ok(HttpResponse::Found().append_header(("Location", format!("/assets/{}", asset_id))).finish())
|
||||
}
|
||||
|
||||
// Update the status of an asset
|
||||
pub async fn update_status(
|
||||
_tmpl: web::Data<Tera>,
|
||||
path: web::Path<(String, String)>,
|
||||
) -> Result<HttpResponse> {
|
||||
let (asset_id, _status) = path.into_inner();
|
||||
|
||||
println!("DEBUG: Updating status of asset with ID {}", asset_id);
|
||||
|
||||
// In a real application, we would update the asset in the database
|
||||
// For now, we'll just redirect to the asset detail page
|
||||
|
||||
Ok(HttpResponse::Found().append_header(("Location", format!("/assets/{}", asset_id))).finish())
|
||||
}
|
||||
|
||||
// Test method to render a simple test page
|
||||
pub async fn test(tmpl: web::Data<Tera>) -> Result<HttpResponse> {
|
||||
println!("DEBUG: Starting test page rendering");
|
||||
|
||||
let mut context = Context::new();
|
||||
|
||||
let assets = Self::get_mock_assets();
|
||||
println!("DEBUG: Generated {} mock assets for test", assets.len());
|
||||
|
||||
let stats = AssetStatistics::new(&assets);
|
||||
println!("DEBUG: Generated asset statistics for test: {:?}", stats);
|
||||
|
||||
// Add active_page for navigation highlighting
|
||||
context.insert("active_page", &"assets");
|
||||
|
||||
// Add stats
|
||||
context.insert("stats", &serde_json::to_value(stats).unwrap());
|
||||
println!("DEBUG: Added stats to context for test");
|
||||
|
||||
// Add recent assets
|
||||
let recent_assets: Vec<serde_json::Map<String, serde_json::Value>> = assets
|
||||
.iter()
|
||||
.take(5)
|
||||
.map(|a| Self::asset_to_json(a))
|
||||
.collect();
|
||||
|
||||
context.insert("recent_assets", &recent_assets);
|
||||
|
||||
println!("DEBUG: Rendering test_base.html with full context");
|
||||
let response = render_template(&tmpl, "test_base.html", &context);
|
||||
println!("DEBUG: Finished rendering test_base.html");
|
||||
response
|
||||
}
|
||||
|
||||
// Helper method to convert Asset to a JSON object for templates
|
||||
fn asset_to_json(asset: &Asset) -> serde_json::Map<String, serde_json::Value> {
|
||||
let mut map = serde_json::Map::new();
|
||||
|
||||
map.insert("id".to_string(), serde_json::Value::String(asset.id.clone()));
|
||||
map.insert("name".to_string(), serde_json::Value::String(asset.name.clone()));
|
||||
map.insert("description".to_string(), serde_json::Value::String(asset.description.clone()));
|
||||
map.insert("asset_type".to_string(), serde_json::Value::String(asset.asset_type.as_str().to_string()));
|
||||
map.insert("status".to_string(), serde_json::Value::String(asset.status.as_str().to_string()));
|
||||
map.insert("owner_id".to_string(), serde_json::Value::String(asset.owner_id.clone()));
|
||||
map.insert("owner_name".to_string(), serde_json::Value::String(asset.owner_name.clone()));
|
||||
map.insert("created_at".to_string(), serde_json::Value::String(asset.created_at.format("%Y-%m-%d").to_string()));
|
||||
map.insert("updated_at".to_string(), serde_json::Value::String(asset.updated_at.format("%Y-%m-%d").to_string()));
|
||||
|
||||
// Add current valuation if available
|
||||
if let Some(current_valuation) = asset.current_valuation {
|
||||
map.insert("current_valuation".to_string(), serde_json::Value::Number(serde_json::Number::from_f64(current_valuation).unwrap()));
|
||||
|
||||
if let Some(valuation_currency) = &asset.valuation_currency {
|
||||
map.insert("valuation_currency".to_string(), serde_json::Value::String(valuation_currency.clone()));
|
||||
}
|
||||
|
||||
if let Some(valuation_date) = asset.valuation_date {
|
||||
map.insert("valuation_date".to_string(), serde_json::Value::String(valuation_date.format("%Y-%m-%d").to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
// Add blockchain info if available
|
||||
if let Some(blockchain_info) = &asset.blockchain_info {
|
||||
let mut blockchain_map = serde_json::Map::new();
|
||||
blockchain_map.insert("blockchain".to_string(), serde_json::Value::String(blockchain_info.blockchain.clone()));
|
||||
blockchain_map.insert("token_id".to_string(), serde_json::Value::String(blockchain_info.token_id.clone()));
|
||||
blockchain_map.insert("contract_address".to_string(), serde_json::Value::String(blockchain_info.contract_address.clone()));
|
||||
blockchain_map.insert("owner_address".to_string(), serde_json::Value::String(blockchain_info.owner_address.clone()));
|
||||
|
||||
if let Some(transaction_hash) = &blockchain_info.transaction_hash {
|
||||
blockchain_map.insert("transaction_hash".to_string(), serde_json::Value::String(transaction_hash.clone()));
|
||||
}
|
||||
|
||||
if let Some(block_number) = blockchain_info.block_number {
|
||||
blockchain_map.insert("block_number".to_string(), serde_json::Value::Number(serde_json::Number::from(block_number)));
|
||||
}
|
||||
|
||||
if let Some(timestamp) = blockchain_info.timestamp {
|
||||
blockchain_map.insert("timestamp".to_string(), serde_json::Value::String(timestamp.format("%Y-%m-%d").to_string()));
|
||||
}
|
||||
|
||||
map.insert("blockchain_info".to_string(), serde_json::Value::Object(blockchain_map));
|
||||
}
|
||||
|
||||
// Add valuation history
|
||||
let valuation_history: Vec<serde_json::Value> = asset.valuation_history.iter()
|
||||
.map(|v| {
|
||||
let mut valuation_map = serde_json::Map::new();
|
||||
valuation_map.insert("id".to_string(), serde_json::Value::String(v.id.clone()));
|
||||
valuation_map.insert("date".to_string(), serde_json::Value::String(v.date.format("%Y-%m-%d").to_string()));
|
||||
valuation_map.insert("value".to_string(), serde_json::Value::Number(serde_json::Number::from_f64(v.value).unwrap()));
|
||||
valuation_map.insert("currency".to_string(), serde_json::Value::String(v.currency.clone()));
|
||||
valuation_map.insert("source".to_string(), serde_json::Value::String(v.source.clone()));
|
||||
|
||||
if let Some(notes) = &v.notes {
|
||||
valuation_map.insert("notes".to_string(), serde_json::Value::String(notes.clone()));
|
||||
}
|
||||
|
||||
serde_json::Value::Object(valuation_map)
|
||||
})
|
||||
.collect();
|
||||
|
||||
map.insert("valuation_history".to_string(), serde_json::Value::Array(valuation_history));
|
||||
|
||||
// Add transaction history
|
||||
let transaction_history: Vec<serde_json::Value> = asset.transaction_history.iter()
|
||||
.map(|t| {
|
||||
let mut transaction_map = serde_json::Map::new();
|
||||
transaction_map.insert("id".to_string(), serde_json::Value::String(t.id.clone()));
|
||||
transaction_map.insert("transaction_type".to_string(), serde_json::Value::String(t.transaction_type.clone()));
|
||||
transaction_map.insert("date".to_string(), serde_json::Value::String(t.date.format("%Y-%m-%d").to_string()));
|
||||
|
||||
if let Some(from_address) = &t.from_address {
|
||||
transaction_map.insert("from_address".to_string(), serde_json::Value::String(from_address.clone()));
|
||||
}
|
||||
|
||||
if let Some(to_address) = &t.to_address {
|
||||
transaction_map.insert("to_address".to_string(), serde_json::Value::String(to_address.clone()));
|
||||
}
|
||||
|
||||
if let Some(amount) = t.amount {
|
||||
transaction_map.insert("amount".to_string(), serde_json::Value::Number(serde_json::Number::from_f64(amount).unwrap()));
|
||||
}
|
||||
|
||||
if let Some(currency) = &t.currency {
|
||||
transaction_map.insert("currency".to_string(), serde_json::Value::String(currency.clone()));
|
||||
}
|
||||
|
||||
if let Some(transaction_hash) = &t.transaction_hash {
|
||||
transaction_map.insert("transaction_hash".to_string(), serde_json::Value::String(transaction_hash.clone()));
|
||||
}
|
||||
|
||||
if let Some(notes) = &t.notes {
|
||||
transaction_map.insert("notes".to_string(), serde_json::Value::String(notes.clone()));
|
||||
}
|
||||
|
||||
serde_json::Value::Object(transaction_map)
|
||||
})
|
||||
.collect();
|
||||
|
||||
map.insert("transaction_history".to_string(), serde_json::Value::Array(transaction_history));
|
||||
|
||||
// Add image URL if available
|
||||
if let Some(image_url) = &asset.image_url {
|
||||
map.insert("image_url".to_string(), serde_json::Value::String(image_url.clone()));
|
||||
}
|
||||
|
||||
// Add external URL if available
|
||||
if let Some(external_url) = &asset.external_url {
|
||||
map.insert("external_url".to_string(), serde_json::Value::String(external_url.clone()));
|
||||
}
|
||||
|
||||
map
|
||||
}
|
||||
|
||||
// Generate mock assets for testing
|
||||
fn get_mock_assets() -> Vec<Asset> {
|
||||
let now = Utc::now();
|
||||
let mut assets = Vec::new();
|
||||
|
||||
// Create NFT asset
|
||||
let mut nft = Asset {
|
||||
id: "asset-nft12345".to_string(),
|
||||
name: "CryptoKitty #12345".to_string(),
|
||||
description: "A unique digital cat collectible".to_string(),
|
||||
asset_type: AssetType::NFT,
|
||||
status: AssetStatus::Active,
|
||||
owner_id: "user-123".to_string(),
|
||||
owner_name: "John Doe".to_string(),
|
||||
created_at: now - Duration::days(30),
|
||||
updated_at: now,
|
||||
blockchain_info: None,
|
||||
current_valuation: Some(600.0),
|
||||
valuation_currency: Some("USD".to_string()),
|
||||
valuation_date: Some(now - Duration::days(1)),
|
||||
valuation_history: Vec::new(),
|
||||
transaction_history: Vec::new(),
|
||||
metadata: serde_json::json!({}),
|
||||
image_url: Some("https://example.com/cryptokitty12345.png".to_string()),
|
||||
external_url: Some("https://www.cryptokitties.co/kitty/12345".to_string()),
|
||||
};
|
||||
|
||||
nft.add_blockchain_info(BlockchainInfo {
|
||||
blockchain: "Ethereum".to_string(),
|
||||
token_id: "12345".to_string(),
|
||||
contract_address: "0x06012c8cf97BEaD5deAe237070F9587f8E7A266d".to_string(),
|
||||
owner_address: "0xb794f5ea0ba39494ce839613fffba74279579268".to_string(),
|
||||
transaction_hash: Some("0x123456789abcdef123456789abcdef123456789abcdef123456789abcdef1234".to_string()),
|
||||
block_number: Some(12345678),
|
||||
timestamp: Some(now - Duration::days(30)),
|
||||
});
|
||||
|
||||
nft.add_valuation(500.0, "USD", "OpenSea", Some("Initial valuation".to_string()));
|
||||
nft.add_valuation(550.0, "USD", "OpenSea", Some("Market increase".to_string()));
|
||||
nft.add_valuation(600.0, "USD", "OpenSea", None);
|
||||
|
||||
nft.add_transaction(
|
||||
"Purchase",
|
||||
Some("0xa1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2".to_string()),
|
||||
Some("0xb794f5ea0ba39494ce839613fffba74279579268".to_string()),
|
||||
Some(500.0),
|
||||
Some("USD".to_string()),
|
||||
Some("0x123456789abcdef123456789abcdef123456789abcdef123456789abcdef1234".to_string()),
|
||||
None,
|
||||
);
|
||||
|
||||
assets.push(nft);
|
||||
|
||||
// Create Real Estate asset
|
||||
let mut real_estate = Asset {
|
||||
id: "asset-realestate789".to_string(),
|
||||
name: "Apartment 123, New York".to_string(),
|
||||
description: "A luxury apartment in downtown Manhattan".to_string(),
|
||||
asset_type: AssetType::RealEstate,
|
||||
status: AssetStatus::Active,
|
||||
owner_id: "user-456".to_string(),
|
||||
owner_name: "Jane Smith".to_string(),
|
||||
created_at: now - Duration::days(60),
|
||||
updated_at: now,
|
||||
blockchain_info: None,
|
||||
current_valuation: Some(1050000.0),
|
||||
valuation_currency: Some("USD".to_string()),
|
||||
valuation_date: Some(now - Duration::days(5)),
|
||||
valuation_history: Vec::new(),
|
||||
transaction_history: Vec::new(),
|
||||
metadata: serde_json::json!({}),
|
||||
image_url: Some("https://example.com/apartment123.jpg".to_string()),
|
||||
external_url: None,
|
||||
};
|
||||
|
||||
real_estate.add_blockchain_info(BlockchainInfo {
|
||||
blockchain: "Ethereum".to_string(),
|
||||
token_id: "RE789".to_string(),
|
||||
contract_address: "0x123456789abcdef123456789abcdef12345678ab".to_string(),
|
||||
owner_address: "0xc3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4".to_string(),
|
||||
transaction_hash: Some("0xabcdef123456789abcdef123456789abcdef123456789abcdef123456789abcd".to_string()),
|
||||
block_number: Some(9876543),
|
||||
timestamp: Some(now - Duration::days(60)),
|
||||
});
|
||||
|
||||
real_estate.add_valuation(1000000.0, "USD", "Property Appraisal", Some("Initial valuation".to_string()));
|
||||
real_estate.add_valuation(1050000.0, "USD", "Property Appraisal", Some("Annual update".to_string()));
|
||||
|
||||
real_estate.add_transaction(
|
||||
"Tokenization",
|
||||
None,
|
||||
Some("0xc3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4".to_string()),
|
||||
Some(1000000.0),
|
||||
Some("USD".to_string()),
|
||||
Some("0xabcdef123456789abcdef123456789abcdef123456789abcdef123456789abcd".to_string()),
|
||||
Some("Initial tokenization of property".to_string()),
|
||||
);
|
||||
|
||||
assets.push(real_estate);
|
||||
|
||||
// Create Token asset
|
||||
let mut token = Asset {
|
||||
id: "asset-token456".to_string(),
|
||||
name: "OurWorld Token".to_string(),
|
||||
description: "Utility token for the OurWorld platform".to_string(),
|
||||
asset_type: AssetType::Token,
|
||||
status: AssetStatus::Active,
|
||||
owner_id: "user-789".to_string(),
|
||||
owner_name: "Alice Johnson".to_string(),
|
||||
created_at: now - Duration::days(90),
|
||||
updated_at: now,
|
||||
blockchain_info: None,
|
||||
current_valuation: Some(110000.0),
|
||||
valuation_currency: Some("TFT".to_string()),
|
||||
valuation_date: Some(now - Duration::days(2)),
|
||||
valuation_history: Vec::new(),
|
||||
transaction_history: Vec::new(),
|
||||
metadata: serde_json::json!({}),
|
||||
image_url: Some("https://example.com/ourworld_token.png".to_string()),
|
||||
external_url: Some("https://ourworld.tf/token".to_string()),
|
||||
};
|
||||
|
||||
token.add_blockchain_info(BlockchainInfo {
|
||||
blockchain: "ThreeFold".to_string(),
|
||||
token_id: "TFT".to_string(),
|
||||
contract_address: "0xf6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1".to_string(),
|
||||
owner_address: "0xe5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6".to_string(),
|
||||
transaction_hash: None,
|
||||
block_number: None,
|
||||
timestamp: Some(now - Duration::days(90)),
|
||||
});
|
||||
|
||||
token.add_valuation(100000.0, "TFT", "ThreeFold Exchange", None);
|
||||
token.add_valuation(120000.0, "TFT", "ThreeFold Exchange", None);
|
||||
token.add_valuation(110000.0, "TFT", "ThreeFold Exchange", None);
|
||||
|
||||
token.add_transaction(
|
||||
"Transfer",
|
||||
Some("0xd4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5".to_string()),
|
||||
Some("0xe5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6".to_string()),
|
||||
Some(100000.0),
|
||||
Some("TFT".to_string()),
|
||||
None,
|
||||
Some("Initial allocation".to_string()),
|
||||
);
|
||||
|
||||
assets.push(token);
|
||||
|
||||
// Create Intellectual Property asset
|
||||
let mut ip = Asset {
|
||||
id: "asset-ip987654".to_string(),
|
||||
name: "Patent #987654".to_string(),
|
||||
description: "A patent for a new renewable energy technology".to_string(),
|
||||
asset_type: AssetType::IntellectualProperty,
|
||||
status: AssetStatus::Active,
|
||||
owner_id: "user-321".to_string(),
|
||||
owner_name: "Bob Williams".to_string(),
|
||||
created_at: now - Duration::days(120),
|
||||
updated_at: now,
|
||||
blockchain_info: None,
|
||||
current_valuation: Some(300000.0),
|
||||
valuation_currency: Some("USD".to_string()),
|
||||
valuation_date: Some(now - Duration::days(10)),
|
||||
valuation_history: Vec::new(),
|
||||
transaction_history: Vec::new(),
|
||||
metadata: serde_json::json!({}),
|
||||
image_url: None,
|
||||
external_url: None,
|
||||
};
|
||||
|
||||
ip.add_blockchain_info(BlockchainInfo {
|
||||
blockchain: "Polygon".to_string(),
|
||||
token_id: "IP987654".to_string(),
|
||||
contract_address: "0x2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3".to_string(),
|
||||
owner_address: "0x4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f".to_string(),
|
||||
transaction_hash: Some("0x56789abcdef123456789abcdef123456789abcdef123456789abcdef12345678".to_string()),
|
||||
block_number: Some(5432109),
|
||||
timestamp: Some(now - Duration::days(120)),
|
||||
});
|
||||
|
||||
ip.add_valuation(250000.0, "USD", "Patent Valuation Service", Some("Initial valuation".to_string()));
|
||||
ip.add_valuation(300000.0, "USD", "Patent Valuation Service", Some("After successful testing".to_string()));
|
||||
|
||||
ip.add_transaction(
|
||||
"Licensing",
|
||||
Some("0x4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f".to_string()),
|
||||
Some("0x5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a".to_string()),
|
||||
Some(50000.0),
|
||||
Some("USD".to_string()),
|
||||
Some("0x6789abcdef123456789abcdef123456789abcdef123456789abcdef123456789".to_string()),
|
||||
Some("Annual licensing fee".to_string()),
|
||||
);
|
||||
|
||||
assets.push(ip);
|
||||
|
||||
// Create Share asset
|
||||
let mut share = Asset {
|
||||
id: "asset-share123".to_string(),
|
||||
name: "OurWorld Inc. Shares".to_string(),
|
||||
description: "Equity shares in OurWorld Inc.".to_string(),
|
||||
asset_type: AssetType::Share,
|
||||
status: AssetStatus::Active,
|
||||
owner_id: "user-654".to_string(),
|
||||
owner_name: "Charlie Brown".to_string(),
|
||||
created_at: now - Duration::days(150),
|
||||
updated_at: now,
|
||||
blockchain_info: None,
|
||||
current_valuation: Some(1300.0),
|
||||
valuation_currency: Some("USD".to_string()),
|
||||
valuation_date: Some(now - Duration::days(3)),
|
||||
valuation_history: Vec::new(),
|
||||
transaction_history: Vec::new(),
|
||||
metadata: serde_json::json!({}),
|
||||
image_url: None,
|
||||
external_url: Some("https://ourworld.tf/shares".to_string()),
|
||||
};
|
||||
|
||||
share.add_blockchain_info(BlockchainInfo {
|
||||
blockchain: "Ethereum".to_string(),
|
||||
token_id: "OWSHARE".to_string(),
|
||||
contract_address: "0x3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4".to_string(),
|
||||
owner_address: "0x6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b".to_string(),
|
||||
transaction_hash: Some("0x789abcdef123456789abcdef123456789abcdef123456789abcdef123456789a".to_string()),
|
||||
block_number: Some(7654321),
|
||||
timestamp: Some(now - Duration::days(150)),
|
||||
});
|
||||
|
||||
share.add_valuation(1000.0, "USD", "Stock Exchange", None);
|
||||
share.add_valuation(1200.0, "USD", "Stock Exchange", None);
|
||||
share.add_valuation(1150.0, "USD", "Stock Exchange", None);
|
||||
share.add_valuation(1300.0, "USD", "Stock Exchange", None);
|
||||
|
||||
share.add_transaction(
|
||||
"Purchase",
|
||||
Some("0x7b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c".to_string()),
|
||||
Some("0x6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b".to_string()),
|
||||
Some(1000.0),
|
||||
Some("USD".to_string()),
|
||||
Some("0x89abcdef123456789abcdef123456789abcdef123456789abcdef123456789ab".to_string()),
|
||||
None,
|
||||
);
|
||||
|
||||
assets.push(share);
|
||||
|
||||
assets
|
||||
}
|
||||
}
|
@@ -6,5 +6,6 @@ pub mod calendar;
|
||||
pub mod governance;
|
||||
pub mod flow;
|
||||
pub mod contract;
|
||||
pub mod asset;
|
||||
|
||||
// Re-export controllers for easier imports
|
||||
|
Reference in New Issue
Block a user