diff --git a/cli/.gitignore b/cli/.gitignore index ea8c4bf..0002bf1 100644 --- a/cli/.gitignore +++ b/cli/.gitignore @@ -1 +1,3 @@ /target +/test-ledger +/dev-tools \ No newline at end of file diff --git a/cli/Cargo.lock b/cli/Cargo.lock index 80d6ff4..6855036 100644 --- a/cli/Cargo.lock +++ b/cli/Cargo.lock @@ -2669,6 +2669,7 @@ dependencies = [ "dirs", "reqwest", "serde", + "solana-sdk", ] [[package]] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 8d71680..633e09e 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -15,4 +15,5 @@ anyhow = "1.0.56" anchor-client = "0.23.0" dirs = "4.0.0" serde = { version = "1.0.136", features = ["derive"] } -reqwest = { version = "0.11.10", features = ["blocking", "json"] } \ No newline at end of file +reqwest = { version = "0.11.10", features = ["blocking", "json"] } +solana-sdk = "1.8.14" \ No newline at end of file diff --git a/cli/src/commands/deploy.rs b/cli/src/commands/deploy.rs index 1656930..fa6caee 100644 --- a/cli/src/commands/deploy.rs +++ b/cli/src/commands/deploy.rs @@ -1,10 +1,15 @@ -use std::io::Error; +use std::{ + fs, + io::Error, + path::Path, + process::{Command, Stdio}, +}; use anchor_client::Cluster; use anyhow::Result; use reqwest::blocking::Client; use serde::Deserialize; -use std::fs; +use solana_sdk::signature::{write_keypair_file, Keypair}; use crate::config::{Config, ConfigOverride}; @@ -22,36 +27,75 @@ const REGISTRY_URL: &str = "https://anchor.projectserum.com/api/v0"; const SERUM_DEX_ID: &str = "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin"; pub fn deploy(cfg_override: &ConfigOverride, cluster: Option) -> Result<()> { - with_config(cfg_override, |_cfg| { - println!("Deploying to: {}", cluster.unwrap().url()); + with_config(cfg_override, |cfg| { + let cluster = cluster.unwrap(); + let cluster_url = cluster.url(); + + let provider_keypair = cfg.provider.wallet.to_string(); let client = Client::new(); - println!("Fetching Artifact..."); - let latest_resp = client - .get(format!("{REGISTRY_URL}/program/{SERUM_DEX_ID}/latest")) - .send()? - .json::>()?; + let program_keypair_path = Path::new("./dev-tools/serum-dex-dev.json"); + let program_artifact_path = Path::new("./dev-tools/serum-dex.so"); - let latest_build_id = latest_resp - .get(0) - .ok_or(Error::new( - std::io::ErrorKind::NotFound, - "No latest build found", - ))? - .id; + // If ./dev-tools does NOT exist + if !Path::exists(Path::new("./dev-tools")) { + println!("Fetching Artifact..."); + let latest_resp = client + .get(format!("{REGISTRY_URL}/program/{SERUM_DEX_ID}/latest")) + .send()? + .json::>()?; - let artifact_path = client - .get(format!("{REGISTRY_URL}/build/{latest_build_id}/artifacts")) - .send()? - .json::()? - .binary; + let latest_build_id = latest_resp + .get(0) + .ok_or(Error::new( + std::io::ErrorKind::NotFound, + "No latest build found", + ))? + .id; - let artifact_bytes = client.get(&artifact_path).send()?.bytes()?; + let artifact_path = client + .get(format!("{REGISTRY_URL}/build/{latest_build_id}/artifacts")) + .send()? + .json::()? + .binary; - fs::write("test.so", artifact_bytes)?; + let artifact_bytes = client.get(&artifact_path).send()?.bytes()?; + + fs::create_dir("./dev-tools")?; + let program_keypair = Keypair::new(); + + fs::write(program_artifact_path, artifact_bytes)?; + write_keypair_file(&program_keypair, program_keypair_path).map_err(|e| { + Error::new( + std::io::ErrorKind::Other, + format!("Failed to write keypair file: {}", e), + ) + })?; + } + + let exit = Command::new("solana") + .arg("program") + .arg("deploy") + .arg("--url") + .arg(cluster_url) + .arg("--keypair") + .arg(provider_keypair) + .arg("--program-id") + .arg(program_keypair_path.to_str().unwrap()) + .arg(program_artifact_path.to_str().unwrap()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .output() + .expect("Must deploy"); + + if !exit.status.success() { + println!("There was a problem deploying: {:?}.", exit); + std::process::exit(exit.status.code().unwrap_or(1)); + } println!("Deploy Successful"); + Ok(()) }) }