Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 8 additions & 103 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ anyhow = "1.0"
chrono = { version = "0.4", features = ["serde"] }
rand = "0.8"
ed25519-dalek = "=2.0.0"
ureq = { version = "=2.7.1", features = ["json"] }
reqwest = { version = "0.11", features = ["json", "rustls-tls", "blocking"], default-features = false }
reqwest = { version = "0.11", features = ["json", "rustls-tls"], default-features = false }
tokio = { version = "1", features = ["full"] }
ctrlc = "3.4"
clap_complete = "=4.4.10"
Expand Down
6 changes: 3 additions & 3 deletions src/commands/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ async fn monitor_contract(
let mut printed_any = false;

while running.load(Ordering::SeqCst) {
match stream.next_batch() {
match stream.next_batch().await {
Ok(batch) => {
for event in batch {
let as_text = event.value.to_string();
Expand All @@ -178,7 +178,7 @@ async fn monitor_contract(
}
break;
}
stream.sleep();
stream.sleep().await;
}
Err(err) => {
if !follow && !printed_any {
Expand All @@ -188,7 +188,7 @@ async fn monitor_contract(
"Event stream error: {}. Reconnecting with backoff…",
err
));
stream.sleep_backoff();
stream.sleep_backoff().await;
}
}
}
Expand Down
10 changes: 4 additions & 6 deletions src/commands/network.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::utils::{config, print as p};
use crate::utils::{config, http_client, print as p};
use anyhow::Result;
use clap::Subcommand;

Expand Down Expand Up @@ -189,7 +189,8 @@ async fn test_network(network_name: Option<String>) -> Result<()> {
p::info(&format!("Horizon: {}", net_cfg.horizon_url));

// Test Horizon endpoint
match ureq::get(&format!("{}/health", net_cfg.horizon_url)).call() {
let client = http_client::get_client();
match client.get(&format!("{}/health", net_cfg.horizon_url)).send().await {
Ok(_) => {
p::success("✓ Horizon endpoint is reachable");
}
Expand All @@ -208,10 +209,7 @@ async fn test_network(network_name: Option<String>) -> Result<()> {
"params": []
});

match ureq::post(soroban_url)
.set("Content-Type", "application/json")
.send_json(&req)
{
match client.post(soroban_url).json(&req).send().await {
Ok(_) => {
p::success("✓ Soroban RPC endpoint is reachable");
}
Expand Down
29 changes: 15 additions & 14 deletions src/commands/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ pub async fn handle(cmd: NewCommands) -> Result<()> {
force_refresh,
} => {
if let Some(query) = search {
return search_templates(&query);
return search_templates(&query).await;
}
let name = name.ok_or_else(|| {
anyhow::anyhow!("A contract name is required unless --search is used")
})?;
if interactive {
scaffold_contract_interactive(name)
scaffold_contract_interactive(name).await
} else {
scaffold_contract(
name,
Expand All @@ -69,15 +69,15 @@ pub async fn handle(cmd: NewCommands) -> Result<()> {
"none",
true,
force_refresh,
)
).await
}
}
NewCommands::Dapp { name } => scaffold_dapp(name),
}
}

fn search_templates(query: &str) -> Result<()> {
let results = templates::search_templates(query, None)?;
async fn search_templates(query: &str) -> Result<()> {
let results = templates::search_templates(query, None).await?;
p::header(&format!("Template search results for '{}'", query));

if results.is_empty() {
Expand Down Expand Up @@ -110,7 +110,7 @@ struct ContractOptions {
include_tests: bool,
}

fn scaffold_contract_interactive(default_name: String) -> Result<()> {
async fn scaffold_contract_interactive(default_name: String) -> Result<()> {
let theme = ColorfulTheme::default();

println!();
Expand Down Expand Up @@ -197,9 +197,10 @@ fn scaffold_contract_interactive(default_name: String) -> Result<()> {
opts.include_tests,
false, // interactive path never force-refreshes
)
.await
}

fn scaffold_contract(
async fn scaffold_contract(
name: String,
template: String,
source: &str,
Expand All @@ -220,7 +221,7 @@ fn scaffold_contract(
p::header(&format!("Scaffolding Soroban contract: {}", name));
println!(" Template: {}\n", template.cyan());
// Ensure selected template is compatible with current CLI version
let entry = templates::get_template(&template)?;
let entry = templates::get_template(&template).await?;
match templates::check_template_compatibility(&entry) {
templates::CompatibilityStatus::Compatible => {}
templates::CompatibilityStatus::TooOld {
Expand Down Expand Up @@ -270,7 +271,7 @@ fn scaffold_contract(
"voting" => voting_template(&name),
"nft" => nft_template(&name),
_ => {
if let Some(custom) = templates::template_source_content(&template, force_refresh)? {
if let Some(custom) = templates::template_source_content(&template, force_refresh).await? {
custom
} else if template == "hello-world" {
hello_world_template(&name, storage, include_tests)
Expand Down Expand Up @@ -964,7 +965,7 @@ Source: `{source}`

// ── Template Marketplace ──────────────────────────────────────────────────────

fn handle_template_search(query: &str, tags: Option<&str>) -> Result<()> {
async fn handle_template_search(query: &str, tags: Option<&str>) -> Result<()> {
p::header("Template Marketplace — Search");
p::kv("Query", query);

Expand All @@ -981,7 +982,7 @@ fn handle_template_search(query: &str, tags: Option<&str>) -> Result<()> {

println!();

let results = templates::search_templates(query, tag_list.as_deref())?;
let results = templates::search_templates(query, tag_list.as_deref()).await?;

if results.is_empty() {
p::info("No templates found matching your search.");
Expand Down Expand Up @@ -1084,11 +1085,11 @@ fn install_step<T>(
}
}

fn scaffold_from_marketplace(name: String, template_name: String) -> Result<()> {
async fn scaffold_from_marketplace(name: String, template_name: String) -> Result<()> {
p::header(&format!("Scaffolding from Marketplace: {}", template_name));

// Get template from registry
let template = templates::get_template(&template_name).with_context(|| {
let template = templates::get_template(&template_name).await.with_context(|| {
format!(
"Template '{}' not found in the registry.\n • List templates with `starforge template list`.\n • Search with `starforge new contract --search {}`.",
template_name, template_name
Expand Down Expand Up @@ -1176,7 +1177,7 @@ fn scaffold_from_marketplace(name: String, template_name: String) -> Result<()>

// Update download count (best-effort; failure here must not roll back a
// successfully installed project).
if let Ok(mut registry) = templates::load_registry() {
if let Ok(mut registry) = templates::load_registry().await {
if let Some(entry) = registry
.templates
.iter_mut()
Expand Down
Loading