Skip to main content

outlayer_cli/commands/
versions.rs

1use anyhow::Result;
2use serde_json::json;
3
4use crate::config::{self, NetworkConfig, ProjectConfig};
5use crate::near::{ContractCaller, NearClient};
6
7/// `outlayer versions` — list project versions
8pub async fn list(network: &NetworkConfig, project_config: &ProjectConfig) -> Result<()> {
9    let near = NearClient::new(network);
10
11    let project_id = format!(
12        "{}/{}",
13        project_config.project.owner, project_config.project.name
14    );
15
16    let versions = near.list_versions(&project_id, None, Some(50)).await?;
17
18    if versions.is_empty() {
19        eprintln!("No versions found for {project_id}");
20        return Ok(());
21    }
22
23    println!(
24        "{:<12} {:<50} {:<8}",
25        "VERSION", "SOURCE", "STATUS"
26    );
27
28    for v in &versions {
29        let version_key = &v.wasm_hash;
30        let short_key = if version_key.len() > 10 {
31            &version_key[..10]
32        } else {
33            version_key
34        };
35
36        let source_str = format_source(&v.source);
37        let status = if v.is_active { "active" } else { "---" };
38
39        println!("{:<12} {:<50} {:<8}", short_key, source_str, status);
40    }
41
42    Ok(())
43}
44
45/// `outlayer versions activate <version_key>` — switch active version
46pub async fn activate(
47    network: &NetworkConfig,
48    project_config: &ProjectConfig,
49    version_key: &str,
50) -> Result<()> {
51    let creds = config::load_credentials(network)?;
52
53    let caller = ContractCaller::from_credentials(&creds, network)?;
54    let gas = 30_000_000_000_000u64; // 30 TGas
55
56    caller
57        .call_contract(
58            "set_active_version",
59            json!({
60                "project_name": project_config.project.name,
61                "version_key": version_key,
62            }),
63            gas,
64            0,
65        )
66        .await?;
67
68    eprintln!("Activated version: {version_key}");
69    Ok(())
70}
71
72/// `outlayer versions remove <version_key>` — remove a version
73pub async fn remove(
74    network: &NetworkConfig,
75    project_config: &ProjectConfig,
76    version_key: &str,
77) -> Result<()> {
78    let creds = config::load_credentials(network)?;
79
80    let caller = ContractCaller::from_credentials(&creds, network)?;
81    let gas = 30_000_000_000_000u64; // 30 TGas
82
83    caller
84        .call_contract(
85            "remove_version",
86            json!({
87                "project_name": project_config.project.name,
88                "version_key": version_key,
89            }),
90            gas,
91            0,
92        )
93        .await?;
94
95    eprintln!("Removed version: {version_key}");
96    Ok(())
97}
98
99fn format_source(source: &serde_json::Value) -> String {
100    if let Some(obj) = source.as_object() {
101        if let Some(github) = obj.get("GitHub") {
102            let repo = github
103                .get("repo")
104                .and_then(|v| v.as_str())
105                .unwrap_or("?");
106            let commit = github
107                .get("commit")
108                .and_then(|v| v.as_str())
109                .unwrap_or("?");
110            let short_commit = if commit.len() > 7 {
111                &commit[..7]
112            } else {
113                commit
114            };
115            return format!("github:{repo}@{short_commit}");
116        }
117        if let Some(wasm) = obj.get("WasmUrl") {
118            let url = wasm.get("url").and_then(|v| v.as_str()).unwrap_or("?");
119            return format!("wasm:{url}");
120        }
121    }
122    source.to_string()
123}