From 96b81abdaecf9c76ef52026ace53aa5458d4e52f Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Thu, 16 Nov 2023 11:20:28 -0500 Subject: [PATCH 01/20] feat!: move config commands to top level --- cmd/crates/soroban-test/src/lib.rs | 6 +- cmd/crates/soroban-test/tests/it/config.rs | 38 +-- cmd/soroban-cli/src/commands/config/mod.rs | 19 +- .../commands/contract/bindings/typescript.rs | 6 +- .../src/commands/contract/fetch.rs | 2 +- .../src/commands/contract/invoke.rs | 2 +- cmd/soroban-cli/src/commands/events.rs | 2 +- .../src/commands/{config => }/identity/add.rs | 3 +- .../commands/{config => }/identity/address.rs | 7 +- .../commands/{config => }/identity/fund.rs | 2 +- .../{config => }/identity/generate.rs | 6 +- .../src/commands/{config => }/identity/ls.rs | 3 +- .../src/commands/{config => }/identity/mod.rs | 0 .../src/commands/{config => }/identity/rm.rs | 3 +- .../commands/{config => }/identity/show.rs | 3 +- cmd/soroban-cli/src/commands/mod.rs | 19 +- .../src/commands/{config => }/network/add.rs | 2 +- .../src/commands/{config => }/network/ls.rs | 0 .../src/commands/{config => }/network/mod.rs | 2 +- .../src/commands/{config => }/network/rm.rs | 0 docs/soroban-cli-full-docs.md | 271 +++++++++--------- 21 files changed, 185 insertions(+), 211 deletions(-) rename cmd/soroban-cli/src/commands/{config => }/identity/add.rs (93%) rename cmd/soroban-cli/src/commands/{config => }/identity/address.rs (94%) rename cmd/soroban-cli/src/commands/{config => }/identity/fund.rs (94%) rename cmd/soroban-cli/src/commands/{config => }/identity/generate.rs (96%) rename cmd/soroban-cli/src/commands/{config => }/identity/ls.rs (92%) rename cmd/soroban-cli/src/commands/{config => }/identity/mod.rs (100%) rename cmd/soroban-cli/src/commands/{config => }/identity/rm.rs (92%) rename cmd/soroban-cli/src/commands/{config => }/identity/show.rs (95%) rename cmd/soroban-cli/src/commands/{config => }/network/add.rs (93%) rename cmd/soroban-cli/src/commands/{config => }/network/ls.rs (100%) rename cmd/soroban-cli/src/commands/{config => }/network/mod.rs (99%) rename cmd/soroban-cli/src/commands/{config => }/network/rm.rs (100%) diff --git a/cmd/crates/soroban-test/src/lib.rs b/cmd/crates/soroban-test/src/lib.rs index 8ec628bf7..1b8522da7 100644 --- a/cmd/crates/soroban-test/src/lib.rs +++ b/cmd/crates/soroban-test/src/lib.rs @@ -30,7 +30,7 @@ use assert_fs::{fixture::FixtureError, prelude::PathChild, TempDir}; use fs_extra::dir::CopyOptions; use soroban_cli::{ - commands::{config, contract, contract::invoke, global}, + commands::{config, contract, contract::invoke, global, identity}, CommandParser, Pwd, }; @@ -158,7 +158,7 @@ impl TestEnv { /// Returns the public key corresponding to the test identity's `hd_path` pub fn test_address(&self, hd_path: usize) -> String { - self.cmd::(&format!("--hd-path={hd_path}")) + self.cmd::(&format!("--hd-path={hd_path}")) .public_key() .unwrap() .to_string() @@ -166,7 +166,7 @@ impl TestEnv { /// Returns the private key corresponding to the test identity's `hd_path` pub fn test_show(&self, hd_path: usize) -> String { - self.cmd::(&format!("--hd-path={hd_path}")) + self.cmd::(&format!("--hd-path={hd_path}")) .private_key() .unwrap() .to_string() diff --git a/cmd/crates/soroban-test/tests/it/config.rs b/cmd/crates/soroban-test/tests/it/config.rs index a0a240af1..ab5184ac7 100644 --- a/cmd/crates/soroban-test/tests/it/config.rs +++ b/cmd/crates/soroban-test/tests/it/config.rs @@ -3,7 +3,7 @@ use soroban_test::TestEnv; use std::{fs, path::Path}; use crate::util::{add_identity, add_test_id, SecretKind, DEFAULT_SEED_PHRASE}; -use soroban_cli::commands::config::network; +use soroban_cli::commands::network; const NETWORK_PASSPHRASE: &str = "Local Sandbox Stellar Network ; September 2022"; @@ -32,8 +32,7 @@ fn set_and_remove_network() { // .assert() // .stdout(""); sandbox - .new_assert_cmd("config") - .arg("network") + .new_assert_cmd("network") .arg("ls") .assert() .stdout("\n"); @@ -42,8 +41,7 @@ fn set_and_remove_network() { fn add_network(sandbox: &TestEnv, name: &str) { sandbox - .new_assert_cmd("config") - .arg("network") + .new_assert_cmd("network") .arg("add") .args([ "--rpc-url=https://127.0.0.1", @@ -59,9 +57,8 @@ fn add_network(sandbox: &TestEnv, name: &str) { fn add_network_global(sandbox: &TestEnv, dir: &Path, name: &str) { sandbox - .new_assert_cmd("config") + .new_assert_cmd("network") .env("XDG_CONFIG_HOME", dir.to_str().unwrap()) - .arg("network") .arg("add") .arg("--global") .arg("--rpc-url") @@ -81,18 +78,16 @@ fn set_and_remove_global_network() { add_network_global(&sandbox, &dir, "global"); sandbox - .new_assert_cmd("config") + .new_assert_cmd("network") .env("XDG_CONFIG_HOME", dir.to_str().unwrap()) - .arg("network") .arg("ls") .arg("--global") .assert() .stdout("global\n"); sandbox - .new_assert_cmd("config") + .new_assert_cmd("network") .env("XDG_CONFIG_HOME", dir.to_str().unwrap()) - .arg("network") .arg("rm") .arg("--global") .arg("global") @@ -100,9 +95,8 @@ fn set_and_remove_global_network() { .stdout(""); sandbox - .new_assert_cmd("config") + .new_assert_cmd("network") .env("XDG_CONFIG_HOME", dir.to_str().unwrap()) - .arg("network") .arg("ls") .assert() .stdout("\n"); @@ -150,8 +144,7 @@ fn read_identity() { let ident_dir = dir.join(".soroban/identity"); assert!(ident_dir.exists()); sandbox - .new_assert_cmd("config") - .arg("identity") + .new_assert_cmd("identity") .arg("ls") .assert() .stdout("test_id\n"); @@ -161,8 +154,7 @@ fn read_identity() { fn generate_identity() { let sandbox = TestEnv::default(); sandbox - .new_assert_cmd("config") - .arg("identity") + .new_assert_cmd("identity") .arg("generate") .arg("--seed") .arg("0000000000000000") @@ -172,8 +164,7 @@ fn generate_identity() { .success(); sandbox - .new_assert_cmd("config") - .arg("identity") + .new_assert_cmd("identity") .arg("ls") .assert() .stdout("test\n"); @@ -197,9 +188,8 @@ fn seed_phrase() { ); sandbox - .new_assert_cmd("config") + .new_assert_cmd("id") .current_dir(dir) - .arg("identity") .arg("ls") .assert() .stdout("test_seed\n"); @@ -218,12 +208,11 @@ fn use_env() { let sandbox = TestEnv::default(); sandbox - .new_assert_cmd("config") + .new_assert_cmd("identity") .env( "SOROBAN_SECRET_KEY", "SDIY6AQQ75WMD4W46EYB7O6UYMHOCGQHLAQGQTKHDX4J2DYQCHVCQYFD", ) - .arg("identity") .arg("add") .arg("bob") .assert() @@ -231,8 +220,7 @@ fn use_env() { .success(); sandbox - .new_assert_cmd("config") - .arg("identity") + .new_assert_cmd("identity") .arg("show") .arg("bob") .assert() diff --git a/cmd/soroban-cli/src/commands/config/mod.rs b/cmd/soroban-cli/src/commands/config/mod.rs index f4d8ec554..72c6f8aed 100644 --- a/cmd/soroban-cli/src/commands/config/mod.rs +++ b/cmd/soroban-cli/src/commands/config/mod.rs @@ -7,16 +7,13 @@ use crate::Pwd; use self::{network::Network, secret::Secret}; -pub mod identity; +use super::network; + pub mod locator; -pub mod network; pub mod secret; #[derive(Debug, Parser)] pub enum Cmd { - /// Configure different identities to sign transactions. - #[command(subcommand)] - Identity(identity::Cmd), /// Configure different networks #[command(subcommand)] Network(network::Cmd), @@ -24,8 +21,6 @@ pub enum Cmd { #[derive(thiserror::Error, Debug)] pub enum Error { - #[error(transparent)] - Identity(#[from] identity::Error), #[error(transparent)] Network(#[from] network::Error), #[error(transparent)] @@ -34,16 +29,6 @@ pub enum Error { Config(#[from] locator::Error), } -impl Cmd { - pub async fn run(&self) -> Result<(), Error> { - match &self { - Cmd::Identity(identity) => identity.run().await?, - Cmd::Network(network) => network.run()?, - } - Ok(()) - } -} - #[derive(Debug, clap::Args, Clone, Default)] #[group(skip)] pub struct Args { diff --git a/cmd/soroban-cli/src/commands/contract/bindings/typescript.rs b/cmd/soroban-cli/src/commands/contract/bindings/typescript.rs index 1c39cf2ae..19c7eecd6 100644 --- a/cmd/soroban-cli/src/commands/contract/bindings/typescript.rs +++ b/cmd/soroban-cli/src/commands/contract/bindings/typescript.rs @@ -6,11 +6,9 @@ use soroban_spec_typescript::{self as typescript, boilerplate::Project}; use crate::wasm; use crate::{ commands::{ - config::{ - locator, - network::{self, Network}, - }, + config::locator, contract::{self, fetch}, + network::{self, Network}, }, utils::contract_spec::{self, ContractSpec}, }; diff --git a/cmd/soroban-cli/src/commands/contract/fetch.rs b/cmd/soroban-cli/src/commands/contract/fetch.rs index 9929f3832..61a82fc47 100644 --- a/cmd/soroban-cli/src/commands/contract/fetch.rs +++ b/cmd/soroban-cli/src/commands/contract/fetch.rs @@ -20,7 +20,7 @@ use soroban_spec::read::FromWasmError; use stellar_strkey::DecodeError; use super::super::config::{self, locator}; -use crate::commands::config::network::{self, Network}; +use crate::commands::network::{self, Network}; use crate::{ rpc::{self, Client}, utils, Pwd, diff --git a/cmd/soroban-cli/src/commands/contract/invoke.rs b/cmd/soroban-cli/src/commands/contract/invoke.rs index 2b6322b88..2311c286a 100644 --- a/cmd/soroban-cli/src/commands/contract/invoke.rs +++ b/cmd/soroban-cli/src/commands/contract/invoke.rs @@ -185,7 +185,7 @@ impl Cmd { if let Some(mut val) = matches_.get_raw(&name) { let mut s = val.next().unwrap().to_string_lossy().to_string(); if matches!(i.type_, ScSpecTypeDef::Address) { - let cmd = crate::commands::config::identity::address::Cmd { + let cmd = crate::commands::identity::address::Cmd { name: Some(s.clone()), hd_path: Some(0), locator: self.config.locator.clone(), diff --git a/cmd/soroban-cli/src/commands/events.rs b/cmd/soroban-cli/src/commands/events.rs index 676052053..aa46bbe23 100644 --- a/cmd/soroban-cli/src/commands/events.rs +++ b/cmd/soroban-cli/src/commands/events.rs @@ -3,7 +3,7 @@ use std::io; use soroban_env_host::xdr::{self, Limits, ReadXdr}; -use super::config::{locator, network}; +use super::{config::locator, network}; use crate::{rpc, utils}; #[derive(Parser, Debug, Clone)] diff --git a/cmd/soroban-cli/src/commands/config/identity/add.rs b/cmd/soroban-cli/src/commands/identity/add.rs similarity index 93% rename from cmd/soroban-cli/src/commands/config/identity/add.rs rename to cmd/soroban-cli/src/commands/identity/add.rs index 7cea70fd7..2868c7371 100644 --- a/cmd/soroban-cli/src/commands/config/identity/add.rs +++ b/cmd/soroban-cli/src/commands/identity/add.rs @@ -1,6 +1,7 @@ -use super::super::{locator, secret}; use clap::command; +use super::super::config::{locator, secret}; + #[derive(thiserror::Error, Debug)] pub enum Error { #[error(transparent)] diff --git a/cmd/soroban-cli/src/commands/config/identity/address.rs b/cmd/soroban-cli/src/commands/identity/address.rs similarity index 94% rename from cmd/soroban-cli/src/commands/config/identity/address.rs rename to cmd/soroban-cli/src/commands/identity/address.rs index f965f2d27..cdd318ff1 100644 --- a/cmd/soroban-cli/src/commands/config/identity/address.rs +++ b/cmd/soroban-cli/src/commands/identity/address.rs @@ -1,6 +1,7 @@ -use crate::commands::config::secret::Secret; - -use super::super::{locator, secret}; +use super::super::config::{ + locator, + secret::{self, Secret}, +}; use clap::arg; #[derive(thiserror::Error, Debug)] diff --git a/cmd/soroban-cli/src/commands/config/identity/fund.rs b/cmd/soroban-cli/src/commands/identity/fund.rs similarity index 94% rename from cmd/soroban-cli/src/commands/config/identity/fund.rs rename to cmd/soroban-cli/src/commands/identity/fund.rs index 1f2155b17..b6c088f13 100644 --- a/cmd/soroban-cli/src/commands/config/identity/fund.rs +++ b/cmd/soroban-cli/src/commands/identity/fund.rs @@ -1,6 +1,6 @@ use clap::command; -use crate::commands::config::network; +use crate::commands::network; use super::address; diff --git a/cmd/soroban-cli/src/commands/config/identity/generate.rs b/cmd/soroban-cli/src/commands/identity/generate.rs similarity index 96% rename from cmd/soroban-cli/src/commands/config/identity/generate.rs rename to cmd/soroban-cli/src/commands/identity/generate.rs index 76a6073d8..20277f258 100644 --- a/cmd/soroban-cli/src/commands/config/identity/generate.rs +++ b/cmd/soroban-cli/src/commands/identity/generate.rs @@ -1,7 +1,9 @@ use clap::{arg, command}; -use super::super::{ - locator, network, +use crate::commands::network; + +use super::super::config::{ + locator, secret::{self, Secret}, }; diff --git a/cmd/soroban-cli/src/commands/config/identity/ls.rs b/cmd/soroban-cli/src/commands/identity/ls.rs similarity index 92% rename from cmd/soroban-cli/src/commands/config/identity/ls.rs rename to cmd/soroban-cli/src/commands/identity/ls.rs index 0b866e0ec..a779e7299 100644 --- a/cmd/soroban-cli/src/commands/config/identity/ls.rs +++ b/cmd/soroban-cli/src/commands/identity/ls.rs @@ -1,6 +1,7 @@ -use super::super::locator; use clap::command; +use super::super::config::locator; + #[derive(thiserror::Error, Debug)] pub enum Error { #[error(transparent)] diff --git a/cmd/soroban-cli/src/commands/config/identity/mod.rs b/cmd/soroban-cli/src/commands/identity/mod.rs similarity index 100% rename from cmd/soroban-cli/src/commands/config/identity/mod.rs rename to cmd/soroban-cli/src/commands/identity/mod.rs diff --git a/cmd/soroban-cli/src/commands/config/identity/rm.rs b/cmd/soroban-cli/src/commands/identity/rm.rs similarity index 92% rename from cmd/soroban-cli/src/commands/config/identity/rm.rs rename to cmd/soroban-cli/src/commands/identity/rm.rs index 6018a4ef1..df48108d3 100644 --- a/cmd/soroban-cli/src/commands/config/identity/rm.rs +++ b/cmd/soroban-cli/src/commands/identity/rm.rs @@ -1,6 +1,7 @@ -use super::super::locator; use clap::command; +use super::super::config::locator; + #[derive(thiserror::Error, Debug)] pub enum Error { #[error(transparent)] diff --git a/cmd/soroban-cli/src/commands/config/identity/show.rs b/cmd/soroban-cli/src/commands/identity/show.rs similarity index 95% rename from cmd/soroban-cli/src/commands/config/identity/show.rs rename to cmd/soroban-cli/src/commands/identity/show.rs index 58a9d709d..45afc4436 100644 --- a/cmd/soroban-cli/src/commands/config/identity/show.rs +++ b/cmd/soroban-cli/src/commands/identity/show.rs @@ -1,6 +1,7 @@ -use super::super::{locator, secret}; use clap::arg; +use super::super::config::{locator, secret}; + #[derive(thiserror::Error, Debug)] pub enum Error { #[error(transparent)] diff --git a/cmd/soroban-cli/src/commands/mod.rs b/cmd/soroban-cli/src/commands/mod.rs index 76152261d..7bc87e8b4 100644 --- a/cmd/soroban-cli/src/commands/mod.rs +++ b/cmd/soroban-cli/src/commands/mod.rs @@ -7,7 +7,9 @@ pub mod config; pub mod contract; pub mod events; pub mod global; +pub mod identity; pub mod lab; +pub mod network; pub mod plugin; pub mod version; @@ -90,11 +92,12 @@ impl Root { pub async fn run(&mut self) -> Result<(), Error> { match &mut self.cmd { Cmd::Completion(completion) => completion.run(), - Cmd::Config(config) => config.run().await?, Cmd::Contract(contract) => contract.run(&self.global_args).await?, Cmd::Events(events) => events.run().await?, Cmd::Lab(lab) => lab.run().await?, + Cmd::Network(network) => network.run()?, Cmd::Version(version) => version.run(), + Cmd::Identity(id) => id.run().await?, }; Ok(()) } @@ -116,14 +119,17 @@ pub enum Cmd { /// Tools for smart contract developers #[command(subcommand)] Contract(contract::Cmd), - /// Read and update config - #[command(subcommand)] - Config(config::Cmd), /// Watch the network for contract events Events(events::Cmd), + /// Create and manage identities including keys and addresses + #[command(subcommand, visible_alias = "id")] + Identity(identity::Cmd), /// Experiment with early features and expert tools #[command(subcommand)] Lab(lab::Cmd), + /// Start and configure networks + #[command(subcommand)] + Network(network::Cmd), /// Print version information Version(version::Cmd), } @@ -135,7 +141,8 @@ pub enum Error { Contract(#[from] contract::Error), #[error(transparent)] Events(#[from] events::Error), - + #[error(transparent)] + Identity(#[from] identity::Error), #[error(transparent)] Lab(#[from] lab::Error), #[error(transparent)] @@ -144,4 +151,6 @@ pub enum Error { Clap(#[from] clap::error::Error), #[error(transparent)] Plugin(#[from] plugin::Error), + #[error(transparent)] + Network(#[from] network::Error), } diff --git a/cmd/soroban-cli/src/commands/config/network/add.rs b/cmd/soroban-cli/src/commands/network/add.rs similarity index 93% rename from cmd/soroban-cli/src/commands/config/network/add.rs rename to cmd/soroban-cli/src/commands/network/add.rs index 3ab9a8b17..b6a2ddd38 100644 --- a/cmd/soroban-cli/src/commands/config/network/add.rs +++ b/cmd/soroban-cli/src/commands/network/add.rs @@ -1,4 +1,4 @@ -use super::{super::secret, locator}; +use super::super::config::{locator, secret}; use clap::command; #[derive(thiserror::Error, Debug)] diff --git a/cmd/soroban-cli/src/commands/config/network/ls.rs b/cmd/soroban-cli/src/commands/network/ls.rs similarity index 100% rename from cmd/soroban-cli/src/commands/config/network/ls.rs rename to cmd/soroban-cli/src/commands/network/ls.rs diff --git a/cmd/soroban-cli/src/commands/config/network/mod.rs b/cmd/soroban-cli/src/commands/network/mod.rs similarity index 99% rename from cmd/soroban-cli/src/commands/config/network/mod.rs rename to cmd/soroban-cli/src/commands/network/mod.rs index 59b1d7971..a62536c86 100644 --- a/cmd/soroban-cli/src/commands/config/network/mod.rs +++ b/cmd/soroban-cli/src/commands/network/mod.rs @@ -10,7 +10,7 @@ use crate::{ rpc::{self, Client}, }; -use super::locator; +use super::config::locator; pub mod add; pub mod ls; diff --git a/cmd/soroban-cli/src/commands/config/network/rm.rs b/cmd/soroban-cli/src/commands/network/rm.rs similarity index 100% rename from cmd/soroban-cli/src/commands/config/network/rm.rs rename to cmd/soroban-cli/src/commands/network/rm.rs diff --git a/docs/soroban-cli-full-docs.md b/docs/soroban-cli-full-docs.md index 7be027c82..732819b85 100644 --- a/docs/soroban-cli-full-docs.md +++ b/docs/soroban-cli-full-docs.md @@ -21,20 +21,15 @@ This document contains the help content for the `soroban` command-line program. * [`soroban contract optimize`↴](#soroban-contract-optimize) * [`soroban contract read`↴](#soroban-contract-read) * [`soroban contract restore`↴](#soroban-contract-restore) -* [`soroban config`↴](#soroban-config) -* [`soroban config identity`↴](#soroban-config-identity) -* [`soroban config identity add`↴](#soroban-config-identity-add) -* [`soroban config identity address`↴](#soroban-config-identity-address) -* [`soroban config identity fund`↴](#soroban-config-identity-fund) -* [`soroban config identity generate`↴](#soroban-config-identity-generate) -* [`soroban config identity ls`↴](#soroban-config-identity-ls) -* [`soroban config identity rm`↴](#soroban-config-identity-rm) -* [`soroban config identity show`↴](#soroban-config-identity-show) -* [`soroban config network`↴](#soroban-config-network) -* [`soroban config network add`↴](#soroban-config-network-add) -* [`soroban config network rm`↴](#soroban-config-network-rm) -* [`soroban config network ls`↴](#soroban-config-network-ls) * [`soroban events`↴](#soroban-events) +* [`soroban identity`↴](#soroban-identity) +* [`soroban identity add`↴](#soroban-identity-add) +* [`soroban identity address`↴](#soroban-identity-address) +* [`soroban identity fund`↴](#soroban-identity-fund) +* [`soroban identity generate`↴](#soroban-identity-generate) +* [`soroban identity ls`↴](#soroban-identity-ls) +* [`soroban identity rm`↴](#soroban-identity-rm) +* [`soroban identity show`↴](#soroban-identity-show) * [`soroban lab`↴](#soroban-lab) * [`soroban lab token`↴](#soroban-lab-token) * [`soroban lab token wrap`↴](#soroban-lab-token-wrap) @@ -46,6 +41,10 @@ This document contains the help content for the `soroban` command-line program. * [`soroban lab xdr decode`↴](#soroban-lab-xdr-decode) * [`soroban lab xdr encode`↴](#soroban-lab-xdr-encode) * [`soroban lab xdr version`↴](#soroban-lab-xdr-version) +* [`soroban network`↴](#soroban-network) +* [`soroban network add`↴](#soroban-network-add) +* [`soroban network rm`↴](#soroban-network-rm) +* [`soroban network ls`↴](#soroban-network-ls) * [`soroban version`↴](#soroban-version) ## `soroban` @@ -81,9 +80,10 @@ Full CLI reference: https://github.com/stellar/soroban-tools/tree/main/docs/soro * `completion` — Print shell completion code for the specified shell * `contract` — Tools for smart contract developers -* `config` — Read and update config * `events` — Watch the network for contract events +* `identity` — Create and manage identities including keys and addresses * `lab` — Experiment with early features and expert tools +* `network` — Start and configure networks * `version` — Print version information ###### **Options:** @@ -488,24 +488,52 @@ If no keys are specificed the contract itself is restored. -## `soroban config` +## `soroban events` + +Watch the network for contract events -Read and update config +**Usage:** `soroban events [OPTIONS]` -**Usage:** `soroban config ` +###### **Options:** -###### **Subcommands:** +* `--start-ledger ` — The first ledger sequence number in the range to pull events https://developers.stellar.org/docs/encyclopedia/ledger-headers#ledger-sequence +* `--cursor ` — The cursor corresponding to the start of the event range +* `--output ` — Output formatting options for event stream -* `identity` — Configure different identities to sign transactions -* `network` — Configure different networks + Default value: `pretty` + Possible values: + - `pretty`: + Colorful, human-oriented console output + - `plain`: + Human-oriented console output without colors + - `json`: + JSONified console output +* `-c`, `--count ` — The maximum number of events to display (defer to the server-defined limit) -## `soroban config identity` + Default value: `10` +* `--id ` — A set of (up to 5) contract IDs to filter events on. This parameter can be passed multiple times, e.g. `--id C123.. --id C456..`, or passed with multiple parameters, e.g. `--id C123 C456` +* `--topic ` — A set of (up to 4) topic filters to filter event topics on. A single topic filter can contain 1-4 different segment filters, separated by commas, with an asterisk (* character) indicating a wildcard segment +* `--type ` — Specifies which type of contract events to display -Configure different identities to sign transactions + Default value: `all` -**Usage:** `soroban config identity ` + Possible values: `all`, `contract`, `system` + +* `--global` — Use global config +* `--config-dir ` +* `--rpc-url ` — RPC server endpoint +* `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server +* `--network ` — Name of network to use from config + + + +## `soroban identity` + +Create and manage identities including keys and addresses + +**Usage:** `soroban identity ` ###### **Subcommands:** @@ -519,11 +547,11 @@ Configure different identities to sign transactions -## `soroban config identity add` +## `soroban identity add` Add a new identity (keypair, ledger, macOS keychain) -**Usage:** `soroban config identity add [OPTIONS] ` +**Usage:** `soroban identity add [OPTIONS] ` ###### **Arguments:** @@ -538,11 +566,11 @@ Add a new identity (keypair, ledger, macOS keychain) -## `soroban config identity address` +## `soroban identity address` Given an identity return its address (public key) -**Usage:** `soroban config identity address [OPTIONS] [NAME]` +**Usage:** `soroban identity address [OPTIONS] [NAME]` ###### **Arguments:** @@ -556,11 +584,11 @@ Given an identity return its address (public key) -## `soroban config identity fund` +## `soroban identity fund` Fund an identity on a test network -**Usage:** `soroban config identity fund [OPTIONS] [NAME]` +**Usage:** `soroban identity fund [OPTIONS] [NAME]` ###### **Arguments:** @@ -577,11 +605,11 @@ Fund an identity on a test network -## `soroban config identity generate` +## `soroban identity generate` Generate a new identity with a seed phrase, currently 12 words -**Usage:** `soroban config identity generate [OPTIONS] ` +**Usage:** `soroban identity generate [OPTIONS] ` ###### **Arguments:** @@ -601,11 +629,11 @@ Generate a new identity with a seed phrase, currently 12 words -## `soroban config identity ls` +## `soroban identity ls` List identities -**Usage:** `soroban config identity ls [OPTIONS]` +**Usage:** `soroban identity ls [OPTIONS]` ###### **Options:** @@ -614,11 +642,11 @@ List identities -## `soroban config identity rm` +## `soroban identity rm` Remove an identity -**Usage:** `soroban config identity rm [OPTIONS] ` +**Usage:** `soroban identity rm [OPTIONS] ` ###### **Arguments:** @@ -631,11 +659,11 @@ Remove an identity -## `soroban config identity show` +## `soroban identity show` Given an identity return its private key -**Usage:** `soroban config identity show [OPTIONS] [NAME]` +**Usage:** `soroban identity show [OPTIONS] [NAME]` ###### **Arguments:** @@ -649,111 +677,6 @@ Given an identity return its private key -## `soroban config network` - -Configure different networks - -**Usage:** `soroban config network ` - -###### **Subcommands:** - -* `add` — Add a new network -* `rm` — Remove a network -* `ls` — List networks - - - -## `soroban config network add` - -Add a new network - -**Usage:** `soroban config network add [OPTIONS] --rpc-url --network-passphrase ` - -###### **Arguments:** - -* `` — Name of network - -###### **Options:** - -* `--rpc-url ` — RPC server endpoint -* `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server -* `--global` — Use global config -* `--config-dir ` - - - -## `soroban config network rm` - -Remove a network - -**Usage:** `soroban config network rm [OPTIONS] ` - -###### **Arguments:** - -* `` — Network to remove - -###### **Options:** - -* `--global` — Use global config -* `--config-dir ` - - - -## `soroban config network ls` - -List networks - -**Usage:** `soroban config network ls [OPTIONS]` - -###### **Options:** - -* `--global` — Use global config -* `--config-dir ` -* `-l`, `--long` — Get more info about the networks - - - -## `soroban events` - -Watch the network for contract events - -**Usage:** `soroban events [OPTIONS]` - -###### **Options:** - -* `--start-ledger ` — The first ledger sequence number in the range to pull events https://developers.stellar.org/docs/encyclopedia/ledger-headers#ledger-sequence -* `--cursor ` — The cursor corresponding to the start of the event range -* `--output ` — Output formatting options for event stream - - Default value: `pretty` - - Possible values: - - `pretty`: - Colorful, human-oriented console output - - `plain`: - Human-oriented console output without colors - - `json`: - JSONified console output - -* `-c`, `--count ` — The maximum number of events to display (defer to the server-defined limit) - - Default value: `10` -* `--id ` — A set of (up to 5) contract IDs to filter events on. This parameter can be passed multiple times, e.g. `--id C123.. --id C456..`, or passed with multiple parameters, e.g. `--id C123 C456` -* `--topic ` — A set of (up to 4) topic filters to filter event topics on. A single topic filter can contain 1-4 different segment filters, separated by commas, with an asterisk (* character) indicating a wildcard segment -* `--type ` — Specifies which type of contract events to display - - Default value: `all` - - Possible values: `all`, `contract`, `system` - -* `--global` — Use global config -* `--config-dir ` -* `--rpc-url ` — RPC server endpoint -* `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server -* `--network ` — Name of network to use from config - - - ## `soroban lab` Experiment with early features and expert tools @@ -930,6 +853,70 @@ Decode XDR +## `soroban network` + +Start and configure networks + +**Usage:** `soroban network ` + +###### **Subcommands:** + +* `add` — Add a new network +* `rm` — Remove a network +* `ls` — List networks + + + +## `soroban network add` + +Add a new network + +**Usage:** `soroban network add [OPTIONS] --rpc-url --network-passphrase ` + +###### **Arguments:** + +* `` — Name of network + +###### **Options:** + +* `--rpc-url ` — RPC server endpoint +* `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server +* `--global` — Use global config +* `--config-dir ` + + + +## `soroban network rm` + +Remove a network + +**Usage:** `soroban network rm [OPTIONS] ` + +###### **Arguments:** + +* `` — Network to remove + +###### **Options:** + +* `--global` — Use global config +* `--config-dir ` + + + +## `soroban network ls` + +List networks + +**Usage:** `soroban network ls [OPTIONS]` + +###### **Options:** + +* `--global` — Use global config +* `--config-dir ` +* `-l`, `--long` — Get more info about the networks + + + ## `soroban lab xdr encode` From 27be5794501037c34e90599a402850ecab024c38 Mon Sep 17 00:00:00 2001 From: Elizabeth Engelman <4752801+elizabethengelman@users.noreply.github.com> Date: Wed, 22 Nov 2023 16:47:09 -0500 Subject: [PATCH 02/20] Add long list for identity (#18) * Add list_identities_long in config/locator.rs * Add a long ls option to config identity command * Add -l to docs --- .../src/commands/config/locator.rs | 14 ++++++++++++++ cmd/soroban-cli/src/commands/identity/ls.rs | 19 ++++++++++++++++++- docs/soroban-cli-full-docs.md | 1 + 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/cmd/soroban-cli/src/commands/config/locator.rs b/cmd/soroban-cli/src/commands/config/locator.rs index 2c174a9b2..f065f7260 100644 --- a/cmd/soroban-cli/src/commands/config/locator.rs +++ b/cmd/soroban-cli/src/commands/config/locator.rs @@ -152,6 +152,20 @@ impl Args { .collect()) } + pub fn list_identities_long(&self) -> Result, Error> { + Ok(KeyType::Identity + .list_paths(&self.local_and_global()?) + .into_iter() + .flatten() + .map(|(name, location)| { + let path = match location { + Location::Local(path) | Location::Global(path) => path, + }; + (name, format!("{}", path.display())) + }) + .collect()) + } + pub fn list_networks(&self) -> Result, Error> { Ok(KeyType::Network .list_paths(&self.local_and_global()?) diff --git a/cmd/soroban-cli/src/commands/identity/ls.rs b/cmd/soroban-cli/src/commands/identity/ls.rs index a779e7299..276232a64 100644 --- a/cmd/soroban-cli/src/commands/identity/ls.rs +++ b/cmd/soroban-cli/src/commands/identity/ls.rs @@ -13,11 +13,28 @@ pub enum Error { pub struct Cmd { #[command(flatten)] pub config_locator: locator::Args, + + #[arg(long, short = 'l')] + pub long: bool, } impl Cmd { pub fn run(&self) -> Result<(), Error> { - println!("{}", self.config_locator.list_identities()?.join("\n")); + let res = if self.long { self.ls_l() } else { self.ls() }?.join("\n"); + println!("{res}"); Ok(()) } + + pub fn ls(&self) -> Result, Error> { + Ok(self.config_locator.list_identities()?) + } + + pub fn ls_l(&self) -> Result, Error> { + Ok(self + .config_locator + .list_identities_long()? + .into_iter() + .map(|(name, location)| format!("{location}\nName: {name}\n")) + .collect::>()) + } } diff --git a/docs/soroban-cli-full-docs.md b/docs/soroban-cli-full-docs.md index 732819b85..63701cc15 100644 --- a/docs/soroban-cli-full-docs.md +++ b/docs/soroban-cli-full-docs.md @@ -639,6 +639,7 @@ List identities * `--global` — Use global config * `--config-dir ` +* `-l`, `--long` From 3c1a6915acfd3457fb97a1ad2c16938ad8f95354 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Sat, 25 Nov 2023 18:30:40 -0500 Subject: [PATCH 03/20] fix: cli_test --- cmd/soroban-rpc/internal/test/cli_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/soroban-rpc/internal/test/cli_test.go b/cmd/soroban-rpc/internal/test/cli_test.go index 1cef8e8e9..28eed93e1 100644 --- a/cmd/soroban-rpc/internal/test/cli_test.go +++ b/cmd/soroban-rpc/internal/test/cli_test.go @@ -290,7 +290,7 @@ func runCLICommand(t *testing.T, cmd string) *icmd.Result { } func getCLIDefaultAccount(t *testing.T) string { - return runSuccessfulCLICmd(t, "config identity address --hd-path 0") + return runSuccessfulCLICmd(t, "identity address --hd-path 0") } func NewCLITest(t *testing.T) *Test { From 042562c5fb277c11e0857e533dd54a4028e89327 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Sat, 25 Nov 2023 18:31:40 -0500 Subject: [PATCH 04/20] feat!(CLI) require source account --- cmd/soroban-cli/src/commands/config/mod.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/cmd/soroban-cli/src/commands/config/mod.rs b/cmd/soroban-cli/src/commands/config/mod.rs index 72c6f8aed..eaa63aa58 100644 --- a/cmd/soroban-cli/src/commands/config/mod.rs +++ b/cmd/soroban-cli/src/commands/config/mod.rs @@ -37,7 +37,7 @@ pub struct Args { #[arg(long, visible_alias = "source", env = "SOROBAN_ACCOUNT")] /// Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` - pub source_account: Option, + pub source_account: String, #[arg(long)] /// If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` @@ -49,12 +49,7 @@ pub struct Args { impl Args { pub fn key_pair(&self) -> Result { - let key = if let Some(source_account) = &self.source_account { - self.account(source_account)? - } else { - secret::Secret::test_seed_phrase()? - }; - + let key = self.account(&self.source_account)?; Ok(key.key_pair(self.hd_path)?) } From f10383e4b350c95641de74aad5fd113bda66cbdf Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Sat, 25 Nov 2023 18:34:07 -0500 Subject: [PATCH 05/20] fix(CLI): allow passing both network args and prefer `network` arg --- cmd/soroban-cli/src/commands/config/secret.rs | 8 ++++++++ .../src/commands/identity/generate.rs | 17 ++++++----------- cmd/soroban-cli/src/commands/network/mod.rs | 18 +++++++++--------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/cmd/soroban-cli/src/commands/config/secret.rs b/cmd/soroban-cli/src/commands/config/secret.rs index 7e6f08a90..4684e2a88 100644 --- a/cmd/soroban-cli/src/commands/config/secret.rs +++ b/cmd/soroban-cli/src/commands/config/secret.rs @@ -92,6 +92,14 @@ impl FromStr for Secret { } } +impl From for Secret { + fn from(value: PrivateKey) -> Self { + Secret::SecretKey { + secret_key: value.to_string(), + } + } +} + impl Secret { pub fn private_key(&self, index: Option) -> Result { Ok(match self { diff --git a/cmd/soroban-cli/src/commands/identity/generate.rs b/cmd/soroban-cli/src/commands/identity/generate.rs index 20277f258..0473eb28b 100644 --- a/cmd/soroban-cli/src/commands/identity/generate.rs +++ b/cmd/soroban-cli/src/commands/identity/generate.rs @@ -56,21 +56,16 @@ impl Cmd { Secret::from_seed(self.seed.as_deref()) }?; let secret = if self.as_secret { - let secret = seed_phrase.private_key(self.hd_path)?; - Secret::SecretKey { - secret_key: secret.to_string(), - } + seed_phrase.private_key(self.hd_path)?.into() } else { seed_phrase }; self.config_locator.write_identity(&self.name, &secret)?; - if !self.network.is_no_network() { - let addr = secret.public_key(self.hd_path)?; - let network = self.network.get(&self.config_locator)?; - network.fund_address(&addr).await.unwrap_or_else(|_| { - tracing::warn!("Failed to fund address: {addr} on at {}", network.rpc_url); - }); - } + let addr = secret.public_key(self.hd_path)?; + let network = self.network.get(&self.config_locator)?; + network.fund_address(&addr).await.unwrap_or_else(|_| { + tracing::warn!("Failed to fund address: {addr} on at {}", network.rpc_url); + }); Ok(()) } } diff --git a/cmd/soroban-cli/src/commands/network/mod.rs b/cmd/soroban-cli/src/commands/network/mod.rs index a62536c86..22cba1904 100644 --- a/cmd/soroban-cli/src/commands/network/mod.rs +++ b/cmd/soroban-cli/src/commands/network/mod.rs @@ -40,7 +40,7 @@ pub enum Error { #[error(transparent)] Config(#[from] locator::Error), - #[error("network arg or rpc url and network passphrase are required if using the network")] + #[error("network arg or rpc url and network passphrase are required if using the network")] Network, #[error(transparent)] Rpc(#[from] rpc::Error), @@ -74,6 +74,7 @@ pub struct Args { #[arg( long = "rpc-url", requires = "network_passphrase", + required_unless_present = "network", env = "SOROBAN_RPC_URL", help_heading = HEADING_RPC, )] @@ -82,6 +83,7 @@ pub struct Args { #[arg( long = "network-passphrase", requires = "rpc_url", + required_unless_present = "network", env = "SOROBAN_NETWORK_PASSPHRASE", help_heading = HEADING_RPC, )] @@ -89,8 +91,7 @@ pub struct Args { /// Name of network to use from config #[arg( long, - conflicts_with = "network_passphrase", - conflicts_with = "rpc_url", + required_unless_present = "rpc_url", env = "SOROBAN_NETWORK", help_heading = HEADING_RPC, )] @@ -100,8 +101,11 @@ pub struct Args { impl Args { pub fn get(&self, locator: &locator::Args) -> Result { if let Some(name) = self.network.as_deref() { - Ok(locator.read_network(name)?) - } else if let (Some(rpc_url), Some(network_passphrase)) = + if let Ok(network) = locator.read_network(name) { + return Ok(network); + } + } + if let (Some(rpc_url), Some(network_passphrase)) = (self.rpc_url.clone(), self.network_passphrase.clone()) { Ok(Network { @@ -112,10 +116,6 @@ impl Args { Err(Error::Network) } } - - pub fn is_no_network(&self) -> bool { - self.network.is_none() && self.network_passphrase.is_none() && self.rpc_url.is_none() - } } #[derive(Debug, clap::Args, Serialize, Deserialize, Clone)] From f497347fc0276478eca3137b5e41da5f42a28344 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Sun, 26 Nov 2023 12:12:21 -0500 Subject: [PATCH 06/20] feat(CLI): add --no-fund to generate --- cmd/crates/soroban-test/tests/it/config.rs | 2 ++ cmd/crates/soroban-test/tests/it/util.rs | 12 +++++++++++- .../src/commands/identity/generate.rs | 16 ++++++++++------ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/cmd/crates/soroban-test/tests/it/config.rs b/cmd/crates/soroban-test/tests/it/config.rs index ab5184ac7..40bbdd682 100644 --- a/cmd/crates/soroban-test/tests/it/config.rs +++ b/cmd/crates/soroban-test/tests/it/config.rs @@ -156,6 +156,8 @@ fn generate_identity() { sandbox .new_assert_cmd("identity") .arg("generate") + .arg("--network=futurenet") + .arg("--no-fund") .arg("--seed") .arg("0000000000000000") .arg("test") diff --git a/cmd/crates/soroban-test/tests/it/util.rs b/cmd/crates/soroban-test/tests/it/util.rs index ad5dacc7d..0bff32a8b 100644 --- a/cmd/crates/soroban-test/tests/it/util.rs +++ b/cmd/crates/soroban-test/tests/it/util.rs @@ -52,7 +52,17 @@ pub async fn invoke_custom( arg: &str, wasm: &Path, ) -> Result { - let mut i: contract::invoke::Cmd = sandbox.cmd_arr(&["--id", id, "--", func, arg]); + let mut i: contract::invoke::Cmd = sandbox.cmd_arr(&[ + "--id", + id, + "--network", + "futurenet", + "--source", + "default", + "--", + func, + arg, + ]); i.wasm = Some(wasm.to_path_buf()); i.config.network.network = Some("futurenet".to_owned()); i.invoke(&soroban_cli::commands::global::Args::default()) diff --git a/cmd/soroban-cli/src/commands/identity/generate.rs b/cmd/soroban-cli/src/commands/identity/generate.rs index 0473eb28b..07782b216 100644 --- a/cmd/soroban-cli/src/commands/identity/generate.rs +++ b/cmd/soroban-cli/src/commands/identity/generate.rs @@ -22,7 +22,9 @@ pub enum Error { pub struct Cmd { /// Name of identity pub name: String, - + /// Do not fund address + #[arg(long)] + pub no_fund: bool, /// Optional seed to use when generating seed phrase. /// Random otherwise. #[arg(long, conflicts_with = "default_seed")] @@ -61,11 +63,13 @@ impl Cmd { seed_phrase }; self.config_locator.write_identity(&self.name, &secret)?; - let addr = secret.public_key(self.hd_path)?; - let network = self.network.get(&self.config_locator)?; - network.fund_address(&addr).await.unwrap_or_else(|_| { - tracing::warn!("Failed to fund address: {addr} on at {}", network.rpc_url); - }); + if !self.no_fund { + let addr = secret.public_key(self.hd_path)?; + let network = self.network.get(&self.config_locator)?; + network.fund_address(&addr).await.unwrap_or_else(|_| { + tracing::warn!("Failed to fund address: {addr} on at {}", network.rpc_url); + }); + } Ok(()) } } From bb1b9c6cdc125c04a433c0819cdc71c612672730 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Mon, 27 Nov 2023 14:06:40 -0500 Subject: [PATCH 07/20] feat(CLI)!: rename subcommand 'identity' to 'keys' --- cmd/crates/soroban-test/src/lib.rs | 17 ++++++--- cmd/crates/soroban-test/tests/it/config.rs | 18 +++++----- .../soroban-test/tests/it/hello_world.rs | 12 +------ .../tests/it/integration/hello_world.rs | 4 +-- .../soroban-test/tests/it/integration/util.rs | 4 +-- .../soroban-test/tests/it/integration/wrap.rs | 36 ++++++++++++++----- cmd/crates/soroban-test/tests/it/util.rs | 4 +-- .../src/commands/config/locator.rs | 2 ++ .../src/commands/contract/invoke.rs | 4 +-- .../src/commands/{identity => keys}/add.rs | 0 .../commands/{identity => keys}/address.rs | 25 +++++-------- .../src/commands/{identity => keys}/fund.rs | 0 .../commands/{identity => keys}/generate.rs | 0 .../src/commands/{identity => keys}/ls.rs | 7 +++- .../src/commands/{identity => keys}/mod.rs | 0 .../src/commands/{identity => keys}/rm.rs | 0 .../src/commands/{identity => keys}/show.rs | 12 +++---- cmd/soroban-cli/src/commands/mod.rs | 10 +++--- cmd/soroban-rpc/internal/test/cli_test.go | 3 +- 19 files changed, 86 insertions(+), 72 deletions(-) rename cmd/soroban-cli/src/commands/{identity => keys}/add.rs (100%) rename cmd/soroban-cli/src/commands/{identity => keys}/address.rs (70%) rename cmd/soroban-cli/src/commands/{identity => keys}/fund.rs (100%) rename cmd/soroban-cli/src/commands/{identity => keys}/generate.rs (100%) rename cmd/soroban-cli/src/commands/{identity => keys}/ls.rs (82%) rename cmd/soroban-cli/src/commands/{identity => keys}/mod.rs (100%) rename cmd/soroban-cli/src/commands/{identity => keys}/rm.rs (100%) rename cmd/soroban-cli/src/commands/{identity => keys}/show.rs (78%) diff --git a/cmd/crates/soroban-test/src/lib.rs b/cmd/crates/soroban-test/src/lib.rs index 1b8522da7..bda6ec420 100644 --- a/cmd/crates/soroban-test/src/lib.rs +++ b/cmd/crates/soroban-test/src/lib.rs @@ -30,7 +30,7 @@ use assert_fs::{fixture::FixtureError, prelude::PathChild, TempDir}; use fs_extra::dir::CopyOptions; use soroban_cli::{ - commands::{config, contract, contract::invoke, global, identity}, + commands::{config, contract, contract::invoke, global, keys}, CommandParser, Pwd, }; @@ -82,6 +82,13 @@ impl TestEnv { pub fn new() -> Result { let this = TempDir::new().map(|temp_dir| TestEnv { temp_dir })?; std::env::set_var("XDG_CONFIG_HOME", this.temp_dir.as_os_str()); + this.new_assert_cmd("keys") + .arg("generate") + .arg("test") + .arg("-d") + .arg("--no-fund") + .assert(); + std::env::set_var("SOROBAN_ACCOUNT", "test"); Ok(this) } @@ -156,17 +163,17 @@ impl TestEnv { &self.temp_dir } - /// Returns the public key corresponding to the test identity's `hd_path` + /// Returns the public key corresponding to the test keys's `hd_path` pub fn test_address(&self, hd_path: usize) -> String { - self.cmd::(&format!("--hd-path={hd_path}")) + self.cmd::(&format!("--hd-path={hd_path}")) .public_key() .unwrap() .to_string() } - /// Returns the private key corresponding to the test identity's `hd_path` + /// Returns the private key corresponding to the test keys's `hd_path` pub fn test_show(&self, hd_path: usize) -> String { - self.cmd::(&format!("--hd-path={hd_path}")) + self.cmd::(&format!("--hd-path={hd_path}")) .private_key() .unwrap() .to_string() diff --git a/cmd/crates/soroban-test/tests/it/config.rs b/cmd/crates/soroban-test/tests/it/config.rs index 40bbdd682..fe81a00c5 100644 --- a/cmd/crates/soroban-test/tests/it/config.rs +++ b/cmd/crates/soroban-test/tests/it/config.rs @@ -2,7 +2,7 @@ use assert_fs::TempDir; use soroban_test::TestEnv; use std::{fs, path::Path}; -use crate::util::{add_identity, add_test_id, SecretKind, DEFAULT_SEED_PHRASE}; +use crate::util::{add_key, add_test_id, SecretKind, DEFAULT_SEED_PHRASE}; use soroban_cli::commands::network; const NETWORK_PASSPHRASE: &str = "Local Sandbox Stellar Network ; September 2022"; @@ -137,24 +137,24 @@ fn multiple_networks() { } #[test] -fn read_identity() { +fn read_key() { let sandbox = TestEnv::default(); let dir = sandbox.dir().as_ref(); add_test_id(dir); let ident_dir = dir.join(".soroban/identity"); assert!(ident_dir.exists()); sandbox - .new_assert_cmd("identity") + .new_assert_cmd("keys") .arg("ls") .assert() .stdout("test_id\n"); } #[test] -fn generate_identity() { +fn generate_key() { let sandbox = TestEnv::default(); sandbox - .new_assert_cmd("identity") + .new_assert_cmd("keys") .arg("generate") .arg("--network=futurenet") .arg("--no-fund") @@ -166,7 +166,7 @@ fn generate_identity() { .success(); sandbox - .new_assert_cmd("identity") + .new_assert_cmd("keys") .arg("ls") .assert() .stdout("test\n"); @@ -182,7 +182,7 @@ fn generate_identity() { fn seed_phrase() { let sandbox = TestEnv::default(); let dir = sandbox.dir(); - add_identity( + add_key( dir, "test_seed", SecretKind::Seed, @@ -210,7 +210,7 @@ fn use_env() { let sandbox = TestEnv::default(); sandbox - .new_assert_cmd("identity") + .new_assert_cmd("keys") .env( "SOROBAN_SECRET_KEY", "SDIY6AQQ75WMD4W46EYB7O6UYMHOCGQHLAQGQTKHDX4J2DYQCHVCQYFD", @@ -222,7 +222,7 @@ fn use_env() { .success(); sandbox - .new_assert_cmd("identity") + .new_assert_cmd("keys") .arg("show") .arg("bob") .assert() diff --git a/cmd/crates/soroban-test/tests/it/hello_world.rs b/cmd/crates/soroban-test/tests/it/hello_world.rs index 38b78ee38..4c45403a1 100644 --- a/cmd/crates/soroban-test/tests/it/hello_world.rs +++ b/cmd/crates/soroban-test/tests/it/hello_world.rs @@ -1,7 +1,4 @@ -use soroban_cli::commands::{ - config::identity, - contract::{self, fetch}, -}; +use soroban_cli::commands::contract::{self, fetch}; use soroban_test::TestEnv; use std::path::PathBuf; @@ -11,13 +8,6 @@ use crate::util::{ TEST_SALT, }; - - - - - - - #[tokio::test] async fn fetch() { if !is_rpc() { diff --git a/cmd/crates/soroban-test/tests/it/integration/hello_world.rs b/cmd/crates/soroban-test/tests/it/integration/hello_world.rs index fed4f4493..7714f70dd 100644 --- a/cmd/crates/soroban-test/tests/it/integration/hello_world.rs +++ b/cmd/crates/soroban-test/tests/it/integration/hello_world.rs @@ -1,6 +1,6 @@ use soroban_cli::commands::{ - config::identity, contract::{self, fetch}, + keys, }; use soroban_test::TestEnv; @@ -111,7 +111,7 @@ fn invoke_auth(sandbox: &TestEnv, id: &str) { async fn invoke_auth_with_identity(sandbox: &TestEnv, id: &str) { sandbox - .cmd::("test -d ") + .cmd::("test -d ") .run() .await .unwrap(); diff --git a/cmd/crates/soroban-test/tests/it/integration/util.rs b/cmd/crates/soroban-test/tests/it/integration/util.rs index 4cc41474f..ea27680b7 100644 --- a/cmd/crates/soroban-test/tests/it/integration/util.rs +++ b/cmd/crates/soroban-test/tests/it/integration/util.rs @@ -2,14 +2,14 @@ use soroban_cli::commands::contract; use soroban_test::{TestEnv, Wasm}; use std::{fmt::Display, path::Path}; -use crate::util::{add_identity, SecretKind}; +use crate::util::{add_key, SecretKind}; pub const HELLO_WORLD: &Wasm = &Wasm::Custom("test-wasms", "test_hello_world"); pub const CUSTOM_TYPES: &Wasm = &Wasm::Custom("test-wasms", "test_custom_types"); pub fn add_test_seed(dir: &Path) -> String { let name = "test_seed"; - add_identity( + add_key( dir, name, SecretKind::Seed, diff --git a/cmd/crates/soroban-test/tests/it/integration/wrap.rs b/cmd/crates/soroban-test/tests/it/integration/wrap.rs index f1a453e7a..e8f7aedf3 100644 --- a/cmd/crates/soroban-test/tests/it/integration/wrap.rs +++ b/cmd/crates/soroban-test/tests/it/integration/wrap.rs @@ -1,9 +1,6 @@ use soroban_cli::CommandParser; use soroban_cli::{ - commands::{ - config::{self}, - lab::token::wrap, - }, + commands::{keys, lab::token::wrap}, utils::contract_id_hash_from_asset, }; use soroban_test::TestEnv; @@ -14,14 +11,16 @@ use super::util::network_passphrase; #[ignore] async fn burn() { let sandbox = &TestEnv::default(); - let address = config::identity::address::Cmd::parse("--hd-path=0") + let network_passphrase = network_passphrase().unwrap(); + println!("NETWORK_PASSPHRASE: {network_passphrase:?}"); + let address = keys::address::Cmd::parse("test") .unwrap() .public_key() .unwrap(); let asset = format!("native:{address}"); wrap_cmd(&asset).run().await.unwrap(); let asset = soroban_cli::utils::parsing::parse_asset(&asset).unwrap(); - let hash = contract_id_hash_from_asset(&asset, &network_passphrase().unwrap()).unwrap(); + let hash = contract_id_hash_from_asset(&asset, &network_passphrase).unwrap(); let id = stellar_strkey::Contract(hash.0).to_string(); assert_eq!( "CAMTHSPKXZJIRTUXQP5QWJIFH3XIDMKLFAWVQOFOXPTKAW5GKV37ZC4N", @@ -33,6 +32,7 @@ async fn burn() { .invoke(&[ "--id", &id, + "--source=test", "--", "authorized", "--id", @@ -44,7 +44,16 @@ async fn burn() { assert_eq!( "\"9223372036854775807\"", sandbox - .invoke(&["--id", &id, "--", "balance", "--id", &address.to_string()]) + .invoke(&[ + "--id", + &id, + "--source", + "test", + "--", + "balance", + "--id", + &address.to_string() + ]) .await .unwrap(), ); @@ -55,6 +64,7 @@ async fn burn() { .invoke(&[ "--id", &id, + "--source=test", "--", "burn", "--id", @@ -68,12 +78,20 @@ async fn burn() { assert_eq!( "\"9223372036854775707\"", sandbox - .invoke(&["--id", &id, "--", "balance", "--id", &address.to_string()]) + .invoke(&[ + "--id", + &id, + "--source=test", + "--", + "balance", + "--id", + &address.to_string() + ]) .await .unwrap(), ); } fn wrap_cmd(asset: &str) -> wrap::Cmd { - wrap::Cmd::parse_arg_vec(&[&format!("--asset={asset}")]).unwrap() + wrap::Cmd::parse_arg_vec(&["--source=test", &format!("--asset={asset}")]).unwrap() } diff --git a/cmd/crates/soroban-test/tests/it/util.rs b/cmd/crates/soroban-test/tests/it/util.rs index 0bff32a8b..6d6251012 100644 --- a/cmd/crates/soroban-test/tests/it/util.rs +++ b/cmd/crates/soroban-test/tests/it/util.rs @@ -15,7 +15,7 @@ pub enum SecretKind { } #[allow(clippy::needless_pass_by_value)] -pub fn add_identity(dir: &Path, name: &str, kind: SecretKind, data: &str) { +pub fn add_key(dir: &Path, name: &str, kind: SecretKind, data: &str) { let secret = match kind { SecretKind::Seed => Secret::SeedPhrase { seed_phrase: data.to_string(), @@ -32,7 +32,7 @@ pub fn add_identity(dir: &Path, name: &str, kind: SecretKind, data: &str) { pub fn add_test_id(dir: &Path) -> String { let name = "test_id"; - add_identity( + add_key( dir, name, SecretKind::Key, diff --git a/cmd/soroban-cli/src/commands/config/locator.rs b/cmd/soroban-cli/src/commands/config/locator.rs index f065f7260..2ec449231 100644 --- a/cmd/soroban-cli/src/commands/config/locator.rs +++ b/cmd/soroban-cli/src/commands/config/locator.rs @@ -58,6 +58,8 @@ pub enum Error { ConfigMissing(String, String), #[error(transparent)] String(#[from] std::string::FromUtf8Error), + #[error(transparent)] + Secret(#[from] crate::commands::config::secret::Error), } #[derive(Debug, clap::Args, Default, Clone)] diff --git a/cmd/soroban-cli/src/commands/contract/invoke.rs b/cmd/soroban-cli/src/commands/contract/invoke.rs index 2311c286a..669342b06 100644 --- a/cmd/soroban-cli/src/commands/contract/invoke.rs +++ b/cmd/soroban-cli/src/commands/contract/invoke.rs @@ -185,8 +185,8 @@ impl Cmd { if let Some(mut val) = matches_.get_raw(&name) { let mut s = val.next().unwrap().to_string_lossy().to_string(); if matches!(i.type_, ScSpecTypeDef::Address) { - let cmd = crate::commands::identity::address::Cmd { - name: Some(s.clone()), + let cmd = crate::commands::keys::address::Cmd { + name: s.clone(), hd_path: Some(0), locator: self.config.locator.clone(), }; diff --git a/cmd/soroban-cli/src/commands/identity/add.rs b/cmd/soroban-cli/src/commands/keys/add.rs similarity index 100% rename from cmd/soroban-cli/src/commands/identity/add.rs rename to cmd/soroban-cli/src/commands/keys/add.rs diff --git a/cmd/soroban-cli/src/commands/identity/address.rs b/cmd/soroban-cli/src/commands/keys/address.rs similarity index 70% rename from cmd/soroban-cli/src/commands/identity/address.rs rename to cmd/soroban-cli/src/commands/keys/address.rs index cdd318ff1..d13381b49 100644 --- a/cmd/soroban-cli/src/commands/identity/address.rs +++ b/cmd/soroban-cli/src/commands/keys/address.rs @@ -1,7 +1,6 @@ -use super::super::config::{ - locator, - secret::{self, Secret}, -}; +use crate::commands::config::secret; + +use super::super::config::locator; use clap::arg; #[derive(thiserror::Error, Debug)] @@ -20,7 +19,7 @@ pub enum Error { #[group(skip)] pub struct Cmd { /// Name of identity to lookup, default test identity used if not provided - pub name: Option, + pub name: String, /// If identity is a seed phrase use this hd path, default is 0 #[arg(long)] @@ -37,20 +36,14 @@ impl Cmd { } pub fn private_key(&self) -> Result { - Ok(if let Some(name) = &self.name { - self.locator.read_identity(name)? - } else { - Secret::test_seed_phrase()? - } - .key_pair(self.hd_path)?) + Ok(self + .locator + .read_identity(&self.name)? + .key_pair(self.hd_path)?) } pub fn public_key(&self) -> Result { - if let Some(Ok(key)) = self - .name - .as_deref() - .map(stellar_strkey::ed25519::PublicKey::from_string) - { + if let Ok(key) = stellar_strkey::ed25519::PublicKey::from_string(&self.name) { Ok(key) } else { Ok(stellar_strkey::ed25519::PublicKey::from_payload( diff --git a/cmd/soroban-cli/src/commands/identity/fund.rs b/cmd/soroban-cli/src/commands/keys/fund.rs similarity index 100% rename from cmd/soroban-cli/src/commands/identity/fund.rs rename to cmd/soroban-cli/src/commands/keys/fund.rs diff --git a/cmd/soroban-cli/src/commands/identity/generate.rs b/cmd/soroban-cli/src/commands/keys/generate.rs similarity index 100% rename from cmd/soroban-cli/src/commands/identity/generate.rs rename to cmd/soroban-cli/src/commands/keys/generate.rs diff --git a/cmd/soroban-cli/src/commands/identity/ls.rs b/cmd/soroban-cli/src/commands/keys/ls.rs similarity index 82% rename from cmd/soroban-cli/src/commands/identity/ls.rs rename to cmd/soroban-cli/src/commands/keys/ls.rs index 276232a64..bc46ffcd8 100644 --- a/cmd/soroban-cli/src/commands/identity/ls.rs +++ b/cmd/soroban-cli/src/commands/keys/ls.rs @@ -26,7 +26,12 @@ impl Cmd { } pub fn ls(&self) -> Result, Error> { - Ok(self.config_locator.list_identities()?) + let mut list = self.config_locator.list_identities()?; + let test = "test".to_string(); + if !list.contains(&test) { + list.push(test); + } + Ok(list) } pub fn ls_l(&self) -> Result, Error> { diff --git a/cmd/soroban-cli/src/commands/identity/mod.rs b/cmd/soroban-cli/src/commands/keys/mod.rs similarity index 100% rename from cmd/soroban-cli/src/commands/identity/mod.rs rename to cmd/soroban-cli/src/commands/keys/mod.rs diff --git a/cmd/soroban-cli/src/commands/identity/rm.rs b/cmd/soroban-cli/src/commands/keys/rm.rs similarity index 100% rename from cmd/soroban-cli/src/commands/identity/rm.rs rename to cmd/soroban-cli/src/commands/keys/rm.rs diff --git a/cmd/soroban-cli/src/commands/identity/show.rs b/cmd/soroban-cli/src/commands/keys/show.rs similarity index 78% rename from cmd/soroban-cli/src/commands/identity/show.rs rename to cmd/soroban-cli/src/commands/keys/show.rs index 45afc4436..b99478cbc 100644 --- a/cmd/soroban-cli/src/commands/identity/show.rs +++ b/cmd/soroban-cli/src/commands/keys/show.rs @@ -18,7 +18,7 @@ pub enum Error { #[group(skip)] pub struct Cmd { /// Name of identity to lookup, default is test identity - pub name: Option, + pub name: String, /// If identity is a seed phrase use this hd path, default is 0 #[arg(long)] @@ -35,11 +35,9 @@ impl Cmd { } pub fn private_key(&self) -> Result { - Ok(if let Some(name) = &self.name { - self.locator.read_identity(name)? - } else { - secret::Secret::test_seed_phrase()? - } - .private_key(self.hd_path)?) + Ok(self + .locator + .read_identity(&self.name)? + .private_key(self.hd_path)?) } } diff --git a/cmd/soroban-cli/src/commands/mod.rs b/cmd/soroban-cli/src/commands/mod.rs index 7bc87e8b4..e4d823ce2 100644 --- a/cmd/soroban-cli/src/commands/mod.rs +++ b/cmd/soroban-cli/src/commands/mod.rs @@ -7,7 +7,7 @@ pub mod config; pub mod contract; pub mod events; pub mod global; -pub mod identity; +pub mod keys; pub mod lab; pub mod network; pub mod plugin; @@ -97,7 +97,7 @@ impl Root { Cmd::Lab(lab) => lab.run().await?, Cmd::Network(network) => network.run()?, Cmd::Version(version) => version.run(), - Cmd::Identity(id) => id.run().await?, + Cmd::Keys(id) => id.run().await?, }; Ok(()) } @@ -122,8 +122,8 @@ pub enum Cmd { /// Watch the network for contract events Events(events::Cmd), /// Create and manage identities including keys and addresses - #[command(subcommand, visible_alias = "id")] - Identity(identity::Cmd), + #[command(subcommand)] + Keys(keys::Cmd), /// Experiment with early features and expert tools #[command(subcommand)] Lab(lab::Cmd), @@ -142,7 +142,7 @@ pub enum Error { #[error(transparent)] Events(#[from] events::Error), #[error(transparent)] - Identity(#[from] identity::Error), + Keys(#[from] keys::Error), #[error(transparent)] Lab(#[from] lab::Error), #[error(transparent)] diff --git a/cmd/soroban-rpc/internal/test/cli_test.go b/cmd/soroban-rpc/internal/test/cli_test.go index 28eed93e1..c310d645b 100644 --- a/cmd/soroban-rpc/internal/test/cli_test.go +++ b/cmd/soroban-rpc/internal/test/cli_test.go @@ -285,12 +285,13 @@ func runCLICommand(t *testing.T, cmd string) *icmd.Result { c.Env = append(os.Environ(), fmt.Sprintf("SOROBAN_RPC_URL=http://localhost:%d/", sorobanRPCPort), fmt.Sprintf("SOROBAN_NETWORK_PASSPHRASE=%s", StandaloneNetworkPassphrase), + fmt.Sprintf("SOROBAN_ACCOUNT=%s", "test"), ) return icmd.RunCmd(c) } func getCLIDefaultAccount(t *testing.T) string { - return runSuccessfulCLICmd(t, "identity address --hd-path 0") + return "GDIY6AQQ75WMD4W46EYB7O6UYMHOCGQHLAQGQTKHDX4J2DYQCHVCR4W4" } func NewCLITest(t *testing.T) *Test { From ba13ab7b1b5ada5a6ad3b9b180098274d3ae48e8 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Mon, 27 Nov 2023 14:07:15 -0500 Subject: [PATCH 08/20] fix: clippy --- .../tests/it/integration/custom_types.rs | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/cmd/crates/soroban-test/tests/it/integration/custom_types.rs b/cmd/crates/soroban-test/tests/it/integration/custom_types.rs index 4e36b452c..fda2c1f61 100644 --- a/cmd/crates/soroban-test/tests/it/integration/custom_types.rs +++ b/cmd/crates/soroban-test/tests/it/integration/custom_types.rs @@ -341,8 +341,8 @@ fn boolean(sandbox: &TestEnv, id: &str) { .assert() .success() .stdout( - r#"true -"#, + r"true +", ); } fn boolean_two(sandbox: &TestEnv, id: &str) { @@ -352,8 +352,8 @@ fn boolean_two(sandbox: &TestEnv, id: &str) { .assert() .success() .stdout( - r#"true -"#, + r"true +", ); } @@ -362,8 +362,8 @@ fn boolean_no_flag(sandbox: &TestEnv, id: &str) { .assert() .success() .stdout( - r#"false -"#, + r"false +", ); } @@ -374,8 +374,8 @@ fn boolean_false(sandbox: &TestEnv, id: &str) { .assert() .success() .stdout( - r#"false -"#, + r"false +", ); } @@ -385,15 +385,15 @@ fn boolean_not(sandbox: &TestEnv, id: &str) { .assert() .success() .stdout( - r#"false -"#, + r"false +", ); } fn boolean_not_no_flag(sandbox: &TestEnv, id: &str) { invoke_custom(sandbox, id, "not").assert().success().stdout( - r#"true -"#, + r"true +", ); } @@ -402,8 +402,8 @@ fn option_none(sandbox: &TestEnv, id: &str) { .assert() .success() .stdout( - r#"null -"#, + r"null +", ); } @@ -413,7 +413,7 @@ fn option_some(sandbox: &TestEnv, id: &str) { .assert() .success() .stdout( - r#"1 -"#, + r"1 +", ); } From a3107bb8b7736dc1003512da29d121ce5173a745 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Mon, 27 Nov 2023 14:41:19 -0500 Subject: [PATCH 09/20] fix: generate test account --- cmd/soroban-rpc/internal/test/cli_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/soroban-rpc/internal/test/cli_test.go b/cmd/soroban-rpc/internal/test/cli_test.go index c310d645b..8488ea2e3 100644 --- a/cmd/soroban-rpc/internal/test/cli_test.go +++ b/cmd/soroban-rpc/internal/test/cli_test.go @@ -285,12 +285,13 @@ func runCLICommand(t *testing.T, cmd string) *icmd.Result { c.Env = append(os.Environ(), fmt.Sprintf("SOROBAN_RPC_URL=http://localhost:%d/", sorobanRPCPort), fmt.Sprintf("SOROBAN_NETWORK_PASSPHRASE=%s", StandaloneNetworkPassphrase), - fmt.Sprintf("SOROBAN_ACCOUNT=%s", "test"), + "SOROBAN_ACCOUNT=test", ) return icmd.RunCmd(c) } func getCLIDefaultAccount(t *testing.T) string { + runSuccessfulCLICmd(t, "keys generate -d test --no-fund") return "GDIY6AQQ75WMD4W46EYB7O6UYMHOCGQHLAQGQTKHDX4J2DYQCHVCR4W4" } From 0adc50ca17fb540a9f7cc15f85f315600bf80e34 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Mon, 27 Nov 2023 14:44:13 -0500 Subject: [PATCH 10/20] fix: md-gen --- docs/soroban-cli-full-docs.md | 67 ++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/docs/soroban-cli-full-docs.md b/docs/soroban-cli-full-docs.md index 63701cc15..746433fd2 100644 --- a/docs/soroban-cli-full-docs.md +++ b/docs/soroban-cli-full-docs.md @@ -22,14 +22,14 @@ This document contains the help content for the `soroban` command-line program. * [`soroban contract read`↴](#soroban-contract-read) * [`soroban contract restore`↴](#soroban-contract-restore) * [`soroban events`↴](#soroban-events) -* [`soroban identity`↴](#soroban-identity) -* [`soroban identity add`↴](#soroban-identity-add) -* [`soroban identity address`↴](#soroban-identity-address) -* [`soroban identity fund`↴](#soroban-identity-fund) -* [`soroban identity generate`↴](#soroban-identity-generate) -* [`soroban identity ls`↴](#soroban-identity-ls) -* [`soroban identity rm`↴](#soroban-identity-rm) -* [`soroban identity show`↴](#soroban-identity-show) +* [`soroban keys`↴](#soroban-keys) +* [`soroban keys add`↴](#soroban-keys-add) +* [`soroban keys address`↴](#soroban-keys-address) +* [`soroban keys fund`↴](#soroban-keys-fund) +* [`soroban keys generate`↴](#soroban-keys-generate) +* [`soroban keys ls`↴](#soroban-keys-ls) +* [`soroban keys rm`↴](#soroban-keys-rm) +* [`soroban keys show`↴](#soroban-keys-show) * [`soroban lab`↴](#soroban-lab) * [`soroban lab token`↴](#soroban-lab-token) * [`soroban lab token wrap`↴](#soroban-lab-token-wrap) @@ -81,7 +81,7 @@ Full CLI reference: https://github.com/stellar/soroban-tools/tree/main/docs/soro * `completion` — Print shell completion code for the specified shell * `contract` — Tools for smart contract developers * `events` — Watch the network for contract events -* `identity` — Create and manage identities including keys and addresses +* `keys` — Create and manage identities including keys and addresses * `lab` — Experiment with early features and expert tools * `network` — Start and configure networks * `version` — Print version information @@ -235,7 +235,7 @@ Extend the time to live ledger of a contract-data ledger entry. If no keys are specified the contract itself is extended. -**Usage:** `soroban contract extend [OPTIONS] --ledgers-to-extend --durability ` +**Usage:** `soroban contract extend [OPTIONS] --ledgers-to-extend --durability --source-account ` ###### **Options:** @@ -271,7 +271,7 @@ If no keys are specified the contract itself is extended. Deploy a contract -**Usage:** `soroban contract deploy [OPTIONS] <--wasm |--wasm-hash >` +**Usage:** `soroban contract deploy [OPTIONS] --source-account <--wasm |--wasm-hash >` ###### **Options:** @@ -342,7 +342,7 @@ Inspect a WASM file listing contract functions, meta, etc Install a WASM file to the ledger without creating a contract instance -**Usage:** `soroban contract install [OPTIONS] --wasm ` +**Usage:** `soroban contract install [OPTIONS] --source-account --wasm ` ###### **Options:** @@ -371,7 +371,7 @@ Generates an "implicit CLI" for the specified contract on-the-fly using the cont soroban contract invoke ... -- --help -**Usage:** `soroban contract invoke [OPTIONS] --id [-- ...]` +**Usage:** `soroban contract invoke [OPTIONS] --id --source-account [-- ...]` ###### **Arguments:** @@ -411,7 +411,7 @@ Optimize a WASM file Print the current value of a contract-data ledger entry -**Usage:** `soroban contract read [OPTIONS] --durability ` +**Usage:** `soroban contract read [OPTIONS] --durability --source-account ` ###### **Options:** @@ -456,7 +456,7 @@ Restore an evicted value for a contract-data legder entry. If no keys are specificed the contract itself is restored. -**Usage:** `soroban contract restore [OPTIONS] --durability ` +**Usage:** `soroban contract restore [OPTIONS] --durability --source-account ` ###### **Options:** @@ -529,11 +529,11 @@ Watch the network for contract events -## `soroban identity` +## `soroban keys` Create and manage identities including keys and addresses -**Usage:** `soroban identity ` +**Usage:** `soroban keys ` ###### **Subcommands:** @@ -547,11 +547,11 @@ Create and manage identities including keys and addresses -## `soroban identity add` +## `soroban keys add` Add a new identity (keypair, ledger, macOS keychain) -**Usage:** `soroban identity add [OPTIONS] ` +**Usage:** `soroban keys add [OPTIONS] ` ###### **Arguments:** @@ -566,11 +566,11 @@ Add a new identity (keypair, ledger, macOS keychain) -## `soroban identity address` +## `soroban keys address` Given an identity return its address (public key) -**Usage:** `soroban identity address [OPTIONS] [NAME]` +**Usage:** `soroban keys address [OPTIONS] ` ###### **Arguments:** @@ -584,11 +584,11 @@ Given an identity return its address (public key) -## `soroban identity fund` +## `soroban keys fund` Fund an identity on a test network -**Usage:** `soroban identity fund [OPTIONS] [NAME]` +**Usage:** `soroban keys fund [OPTIONS] ` ###### **Arguments:** @@ -605,11 +605,11 @@ Fund an identity on a test network -## `soroban identity generate` +## `soroban keys generate` Generate a new identity with a seed phrase, currently 12 words -**Usage:** `soroban identity generate [OPTIONS] ` +**Usage:** `soroban keys generate [OPTIONS] ` ###### **Arguments:** @@ -617,6 +617,7 @@ Generate a new identity with a seed phrase, currently 12 words ###### **Options:** +* `--no-fund` — Do not fund address * `--seed ` — Optional seed to use when generating seed phrase. Random otherwise * `-s`, `--as-secret` — Output the generated identity as a secret key * `--global` — Use global config @@ -629,11 +630,11 @@ Generate a new identity with a seed phrase, currently 12 words -## `soroban identity ls` +## `soroban keys ls` List identities -**Usage:** `soroban identity ls [OPTIONS]` +**Usage:** `soroban keys ls [OPTIONS]` ###### **Options:** @@ -643,11 +644,11 @@ List identities -## `soroban identity rm` +## `soroban keys rm` Remove an identity -**Usage:** `soroban identity rm [OPTIONS] ` +**Usage:** `soroban keys rm [OPTIONS] ` ###### **Arguments:** @@ -660,11 +661,11 @@ Remove an identity -## `soroban identity show` +## `soroban keys show` Given an identity return its private key -**Usage:** `soroban identity show [OPTIONS] [NAME]` +**Usage:** `soroban keys show [OPTIONS] ` ###### **Arguments:** @@ -708,7 +709,7 @@ Wrap, create, and manage token contracts Deploy a token contract to wrap an existing Stellar classic asset for smart contract usage -**Usage:** `soroban lab token wrap [OPTIONS] --asset ` +**Usage:** `soroban lab token wrap [OPTIONS] --asset --source-account ` ###### **Options:** @@ -730,7 +731,7 @@ Deploy a token contract to wrap an existing Stellar classic asset for smart cont Compute the expected contract id for the given asset -**Usage:** `soroban lab token id [OPTIONS] --asset ` +**Usage:** `soroban lab token id [OPTIONS] --asset --source-account ` ###### **Options:** From 400f3a338f0b1075301425c6b9e166339e789f86 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Tue, 28 Nov 2023 10:05:07 -0500 Subject: [PATCH 11/20] fix: config tests --- cmd/crates/soroban-test/tests/it/config.rs | 28 +++++----------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/cmd/crates/soroban-test/tests/it/config.rs b/cmd/crates/soroban-test/tests/it/config.rs index fe81a00c5..5912b2cf5 100644 --- a/cmd/crates/soroban-test/tests/it/config.rs +++ b/cmd/crates/soroban-test/tests/it/config.rs @@ -147,7 +147,7 @@ fn read_key() { .new_assert_cmd("keys") .arg("ls") .assert() - .stdout("test_id\n"); + .stdout(predicates::str::contains("test_id\n")); } #[test] @@ -160,7 +160,7 @@ fn generate_key() { .arg("--no-fund") .arg("--seed") .arg("0000000000000000") - .arg("test") + .arg("test_2") .assert() .stdout("") .success(); @@ -169,9 +169,9 @@ fn generate_key() { .new_assert_cmd("keys") .arg("ls") .assert() - .stdout("test\n"); + .stdout(predicates::str::contains("test_2\n")); let file_contents = - fs::read_to_string(sandbox.dir().join(".soroban/identity/test.toml")).unwrap(); + fs::read_to_string(sandbox.dir().join(".soroban/identity/test_2.toml")).unwrap(); assert_eq!( file_contents, format!("seed_phrase = \"{DEFAULT_SEED_PHRASE}\"\n") @@ -190,19 +190,11 @@ fn seed_phrase() { ); sandbox - .new_assert_cmd("id") + .new_assert_cmd("keys") .current_dir(dir) .arg("ls") .assert() - .stdout("test_seed\n"); -} - -#[test] -fn read_address() { - let sandbox = TestEnv::default(); - for hd_path in 0..2 { - test_hd_path(&sandbox, hd_path); - } + .stdout(predicates::str::contains("test_seed\n")); } #[test] @@ -229,11 +221,3 @@ fn use_env() { .success() .stdout("SDIY6AQQ75WMD4W46EYB7O6UYMHOCGQHLAQGQTKHDX4J2DYQCHVCQYFD\n"); } - -fn test_hd_path(sandbox: &TestEnv, hd_path: usize) { - let seed_phrase = sep5::SeedPhrase::from_seed_phrase(DEFAULT_SEED_PHRASE).unwrap(); - let key_pair = seed_phrase.from_path_index(hd_path, None).unwrap(); - let pub_key = key_pair.public().to_string(); - let test_address = sandbox.test_address(hd_path); - assert_eq!(pub_key, test_address); -} From 1e1a003c43debc99726a8c42410440cb4c2e27f3 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Thu, 30 Nov 2023 11:28:39 -0500 Subject: [PATCH 12/20] feat(CLI)!: Add asset & wasm subcommands to deploy --- .../src/commands/contract/deploy.rs | 243 ++---------------- cmd/soroban-cli/src/commands/contract/mod.rs | 3 +- 2 files changed, 17 insertions(+), 229 deletions(-) diff --git a/cmd/soroban-cli/src/commands/contract/deploy.rs b/cmd/soroban-cli/src/commands/contract/deploy.rs index c89654a4d..9baf44590 100644 --- a/cmd/soroban-cli/src/commands/contract/deploy.rs +++ b/cmd/soroban-cli/src/commands/contract/deploy.rs @@ -1,241 +1,28 @@ -use std::array::TryFromSliceError; -use std::fmt::Debug; -use std::num::ParseIntError; - -use clap::{arg, command, Parser}; -use rand::Rng; -use sha2::{Digest, Sha256}; -use soroban_env_host::xdr::Limits; -use soroban_env_host::{ - xdr::{ - AccountId, ContractExecutable, ContractIdPreimage, ContractIdPreimageFromAddress, - CreateContractArgs, Error as XdrError, Hash, HashIdPreimage, HashIdPreimageContractId, - HostFunction, InvokeHostFunctionOp, Memo, MuxedAccount, Operation, OperationBody, - Preconditions, PublicKey, ScAddress, SequenceNumber, Transaction, TransactionExt, Uint256, - VecM, WriteXdr, - }, - HostError, -}; - -use crate::{ - commands::{config, contract::install, HEADING_RPC}, - rpc::{self, Client}, - utils, wasm, -}; - -#[derive(Parser, Debug, Clone)] -#[command(group( - clap::ArgGroup::new("wasm_src") - .required(true) - .args(&["wasm", "wasm_hash"]), -))] -#[group(skip)] -pub struct Cmd { - /// WASM file to deploy - #[arg(long, group = "wasm_src")] - wasm: Option, - /// Hash of the already installed/deployed WASM file - #[arg(long = "wasm-hash", conflicts_with = "wasm", group = "wasm_src")] - wasm_hash: Option, - /// Custom salt 32-byte salt for the token id - #[arg( - long, - help_heading = HEADING_RPC, - )] - salt: Option, - #[command(flatten)] - config: config::Args, - #[command(flatten)] - pub fee: crate::fee::Args, - #[arg(long, short = 'i', default_value = "false")] - /// Whether to ignore safety checks when deploying contracts - pub ignore_checks: bool, +pub mod asset; +pub mod wasm; + +#[derive(Debug, clap::Subcommand)] +pub enum Cmd { + /// Deploy builtin Soroban Asset Contract + Asset(asset::Cmd), + /// Deploy normal Wasm Contract + Wasm(wasm::Cmd), } #[derive(thiserror::Error, Debug)] pub enum Error { #[error(transparent)] - Install(#[from] install::Error), - #[error(transparent)] - Host(#[from] HostError), - #[error("error parsing int: {0}")] - ParseIntError(#[from] ParseIntError), - #[error("internal conversion error: {0}")] - TryFromSliceError(#[from] TryFromSliceError), - #[error("xdr processing error: {0}")] - Xdr(#[from] XdrError), - #[error("jsonrpc error: {0}")] - JsonRpc(#[from] jsonrpsee_core::Error), - #[error("cannot parse salt: {salt}")] - CannotParseSalt { salt: String }, - #[error("cannot parse contract ID {contract_id}: {error}")] - CannotParseContractId { - contract_id: String, - error: stellar_strkey::DecodeError, - }, - #[error("cannot parse WASM hash {wasm_hash}: {error}")] - CannotParseWasmHash { - wasm_hash: String, - error: stellar_strkey::DecodeError, - }, - #[error("Must provide either --wasm or --wash-hash")] - WasmNotProvided, - #[error(transparent)] - Rpc(#[from] rpc::Error), - #[error(transparent)] - Config(#[from] config::Error), - #[error(transparent)] - StrKey(#[from] stellar_strkey::DecodeError), + Asset(#[from] asset::Error), #[error(transparent)] - Infallible(#[from] std::convert::Infallible), + Wasm(#[from] wasm::Error), } impl Cmd { pub async fn run(&self) -> Result<(), Error> { - let res_str = self.run_and_get_contract_id().await?; - println!("{res_str}"); + match &self { + Cmd::Asset(asset) => asset.run().await?, + Cmd::Wasm(wasm) => wasm.run().await?, + } Ok(()) } - - pub async fn run_and_get_contract_id(&self) -> Result { - let wasm_hash = if let Some(wasm) = &self.wasm { - let hash = install::Cmd { - wasm: wasm::Args { wasm: wasm.clone() }, - config: self.config.clone(), - fee: self.fee.clone(), - ignore_checks: self.ignore_checks, - } - .run_and_get_hash() - .await?; - hex::encode(hash) - } else { - self.wasm_hash - .as_ref() - .ok_or(Error::WasmNotProvided)? - .to_string() - }; - - let hash = Hash(utils::contract_id_from_str(&wasm_hash).map_err(|e| { - Error::CannotParseWasmHash { - wasm_hash: wasm_hash.clone(), - error: e, - } - })?); - - self.run_against_rpc_server(hash).await - } - - async fn run_against_rpc_server(&self, wasm_hash: Hash) -> Result { - let network = self.config.get_network()?; - let salt: [u8; 32] = match &self.salt { - Some(h) => soroban_spec_tools::utils::padded_hex_from_str(h, 32) - .map_err(|_| Error::CannotParseSalt { salt: h.clone() })? - .try_into() - .map_err(|_| Error::CannotParseSalt { salt: h.clone() })?, - None => rand::thread_rng().gen::<[u8; 32]>(), - }; - - let client = Client::new(&network.rpc_url)?; - client - .verify_network_passphrase(Some(&network.network_passphrase)) - .await?; - let key = self.config.key_pair()?; - - // Get the account sequence number - let public_strkey = - stellar_strkey::ed25519::PublicKey(key.verifying_key().to_bytes()).to_string(); - - let account_details = client.get_account(&public_strkey).await?; - let sequence: i64 = account_details.seq_num.into(); - let (tx, contract_id) = build_create_contract_tx( - wasm_hash, - sequence + 1, - self.fee.fee, - &network.network_passphrase, - salt, - &key, - )?; - client - .prepare_and_send_transaction(&tx, &key, &[], &network.network_passphrase, None, None) - .await?; - Ok(stellar_strkey::Contract(contract_id.0).to_string()) - } -} - -fn build_create_contract_tx( - hash: Hash, - sequence: i64, - fee: u32, - network_passphrase: &str, - salt: [u8; 32], - key: &ed25519_dalek::SigningKey, -) -> Result<(Transaction, Hash), Error> { - let source_account = AccountId(PublicKey::PublicKeyTypeEd25519( - key.verifying_key().to_bytes().into(), - )); - - let contract_id_preimage = ContractIdPreimage::Address(ContractIdPreimageFromAddress { - address: ScAddress::Account(source_account), - salt: Uint256(salt), - }); - let contract_id = get_contract_id(contract_id_preimage.clone(), network_passphrase)?; - - let op = Operation { - source_account: None, - body: OperationBody::InvokeHostFunction(InvokeHostFunctionOp { - host_function: HostFunction::CreateContract(CreateContractArgs { - contract_id_preimage, - executable: ContractExecutable::Wasm(hash), - }), - auth: VecM::default(), - }), - }; - let tx = Transaction { - source_account: MuxedAccount::Ed25519(Uint256(key.verifying_key().to_bytes())), - fee, - seq_num: SequenceNumber(sequence), - cond: Preconditions::None, - memo: Memo::None, - operations: vec![op].try_into()?, - ext: TransactionExt::V0, - }; - - Ok((tx, Hash(contract_id.into()))) -} - -fn get_contract_id( - contract_id_preimage: ContractIdPreimage, - network_passphrase: &str, -) -> Result { - let network_id = Hash(Sha256::digest(network_passphrase.as_bytes()).into()); - let preimage = HashIdPreimage::ContractId(HashIdPreimageContractId { - network_id, - contract_id_preimage, - }); - let preimage_xdr = preimage.to_xdr(Limits::none())?; - Ok(Hash(Sha256::digest(preimage_xdr).into())) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_build_create_contract() { - let hash = hex::decode("0000000000000000000000000000000000000000000000000000000000000000") - .unwrap() - .try_into() - .unwrap(); - let result = build_create_contract_tx( - Hash(hash), - 300, - 1, - "Public Global Stellar Network ; September 2015", - [0u8; 32], - &utils::parse_secret_key("SBFGFF27Y64ZUGFAIG5AMJGQODZZKV2YQKAVUUN4HNE24XZXD2OEUVUP") - .unwrap(), - ); - - assert!(result.is_ok()); - } } diff --git a/cmd/soroban-cli/src/commands/contract/mod.rs b/cmd/soroban-cli/src/commands/contract/mod.rs index c10c31502..d94e8da5b 100644 --- a/cmd/soroban-cli/src/commands/contract/mod.rs +++ b/cmd/soroban-cli/src/commands/contract/mod.rs @@ -25,7 +25,8 @@ pub enum Cmd { /// If no keys are specified the contract itself is extended. Extend(extend::Cmd), - /// Deploy a contract + /// Deploy a contract or Soroban Asset Contract + #[command(subcommand)] Deploy(deploy::Cmd), /// Fetch a contract's Wasm binary From 5eb2089c5cbd85cac65beffc412f2f18d6e81615 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Wed, 3 Jan 2024 16:22:40 -0500 Subject: [PATCH 13/20] feat: add back previous commands with deprecation warning --- .../fixtures/test-wasms/swap/src/test.rs | 6 +- .../fixtures/test-wasms/token/src/test.rs | 34 +- .../soroban-test/tests/it/integration/util.rs | 1 + .../soroban-test/tests/it/integration/wrap.rs | 6 +- cmd/crates/soroban-test/tests/it/lab.rs | 27 -- cmd/crates/soroban-test/tests/it/main.rs | 1 - cmd/soroban-cli/src/commands/config/mod.rs | 7 +- .../wrap.rs => contract/deploy/asset.rs} | 15 - .../src/commands/contract/deploy/wasm.rs | 228 ++++++++++ cmd/soroban-cli/src/commands/contract/id.rs | 28 ++ .../{lab/token/id.rs => contract/id/asset.rs} | 0 .../src/commands/contract/id/wasm.rs | 72 +++ cmd/soroban-cli/src/commands/contract/mod.rs | 8 + cmd/soroban-cli/src/commands/lab/mod.rs | 5 +- cmd/soroban-cli/src/commands/lab/token/mod.rs | 14 +- cmd/soroban-cli/src/commands/mod.rs | 4 + cmd/soroban-rpc/internal/test/cli_test.go | 20 +- docs/soroban-cli-full-docs.md | 421 ++++++++++++++++-- 18 files changed, 766 insertions(+), 131 deletions(-) delete mode 100644 cmd/crates/soroban-test/tests/it/lab.rs rename cmd/soroban-cli/src/commands/{lab/token/wrap.rs => contract/deploy/asset.rs} (92%) create mode 100644 cmd/soroban-cli/src/commands/contract/deploy/wasm.rs create mode 100644 cmd/soroban-cli/src/commands/contract/id.rs rename cmd/soroban-cli/src/commands/{lab/token/id.rs => contract/id/asset.rs} (100%) create mode 100644 cmd/soroban-cli/src/commands/contract/id/wasm.rs diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/src/test.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/src/test.rs index 4f3845331..cf7929ef3 100644 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/src/test.rs +++ b/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/src/test.rs @@ -27,10 +27,10 @@ fn test_atomic_swap() { let env = Env::default(); env.mock_all_auths(); - let a = Address::random(&env); - let b = Address::random(&env); + let a = Address::generate(&env); + let b = Address::generate(&env); - let token_admin = Address::random(&env); + let token_admin = Address::generate(&env); let (token_a, token_a_admin) = create_token_contract(&env, &token_admin); let (token_b, token_b_admin) = create_token_contract(&env, &token_admin); diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/test.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/test.rs index 9aae46eba..dbdb17a33 100644 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/test.rs +++ b/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/test.rs @@ -19,11 +19,11 @@ fn test() { let e = Env::default(); e.mock_all_auths(); - let admin1 = Address::random(&e); - let admin2 = Address::random(&e); - let user1 = Address::random(&e); - let user2 = Address::random(&e); - let user3 = Address::random(&e); + let admin1 = Address::generate(&e); + let admin2 = Address::generate(&e); + let user1 = Address::generate(&e); + let user2 = Address::generate(&e); + let user3 = Address::generate(&e); let token = create_token(&e, &admin1); token.mint(&user1, &1000); @@ -142,9 +142,9 @@ fn test_burn() { let e = Env::default(); e.mock_all_auths(); - let admin = Address::random(&e); - let user1 = Address::random(&e); - let user2 = Address::random(&e); + let admin = Address::generate(&e); + let user1 = Address::generate(&e); + let user2 = Address::generate(&e); let token = create_token(&e, &admin); token.mint(&user1, &1000); @@ -199,9 +199,9 @@ fn transfer_insufficient_balance() { let e = Env::default(); e.mock_all_auths(); - let admin = Address::random(&e); - let user1 = Address::random(&e); - let user2 = Address::random(&e); + let admin = Address::generate(&e); + let user1 = Address::generate(&e); + let user2 = Address::generate(&e); let token = create_token(&e, &admin); token.mint(&user1, &1000); @@ -216,10 +216,10 @@ fn transfer_from_insufficient_allowance() { let e = Env::default(); e.mock_all_auths(); - let admin = Address::random(&e); - let user1 = Address::random(&e); - let user2 = Address::random(&e); - let user3 = Address::random(&e); + let admin = Address::generate(&e); + let user1 = Address::generate(&e); + let user2 = Address::generate(&e); + let user3 = Address::generate(&e); let token = create_token(&e, &admin); token.mint(&user1, &1000); @@ -235,7 +235,7 @@ fn transfer_from_insufficient_allowance() { #[should_panic(expected = "already initialized")] fn initialize_already_initialized() { let e = Env::default(); - let admin = Address::random(&e); + let admin = Address::generate(&e); let token = create_token(&e, &admin); token.initialize(&admin, &10, &"name".into_val(&e), &"symbol".into_val(&e)); @@ -245,7 +245,7 @@ fn initialize_already_initialized() { #[should_panic(expected = "Decimal must fit in a u8")] fn decimal_is_over_max() { let e = Env::default(); - let admin = Address::random(&e); + let admin = Address::generate(&e); let token = TokenClient::new(&e, &e.register_contract(None, Token {})); token.initialize( &admin, diff --git a/cmd/crates/soroban-test/tests/it/integration/util.rs b/cmd/crates/soroban-test/tests/it/integration/util.rs index ea27680b7..3a8fba8c7 100644 --- a/cmd/crates/soroban-test/tests/it/integration/util.rs +++ b/cmd/crates/soroban-test/tests/it/integration/util.rs @@ -77,6 +77,7 @@ pub fn deploy_contract(sandbox: &TestEnv, wasm: &Wasm) -> String { sandbox .new_assert_cmd("contract") .arg("deploy") + .arg("wasm") .arg("--wasm-hash") .arg(&format!("{hash}")) .arg("--salt") diff --git a/cmd/crates/soroban-test/tests/it/integration/wrap.rs b/cmd/crates/soroban-test/tests/it/integration/wrap.rs index e8f7aedf3..a69e70c7c 100644 --- a/cmd/crates/soroban-test/tests/it/integration/wrap.rs +++ b/cmd/crates/soroban-test/tests/it/integration/wrap.rs @@ -1,6 +1,6 @@ use soroban_cli::CommandParser; use soroban_cli::{ - commands::{keys, lab::token::wrap}, + commands::{contract::deploy::asset, keys}, utils::contract_id_hash_from_asset, }; use soroban_test::TestEnv; @@ -92,6 +92,6 @@ async fn burn() { ); } -fn wrap_cmd(asset: &str) -> wrap::Cmd { - wrap::Cmd::parse_arg_vec(&["--source=test", &format!("--asset={asset}")]).unwrap() +fn wrap_cmd(asset: &str) -> asset::Cmd { + asset::Cmd::parse_arg_vec(&["--source=test", &format!("--asset={asset}")]).unwrap() } diff --git a/cmd/crates/soroban-test/tests/it/lab.rs b/cmd/crates/soroban-test/tests/it/lab.rs deleted file mode 100644 index 85d8dc650..000000000 --- a/cmd/crates/soroban-test/tests/it/lab.rs +++ /dev/null @@ -1,27 +0,0 @@ -use soroban_test::TestEnv; -use std::path::PathBuf; - -#[test] -#[cfg_attr(target_os = "windows", ignore)] -fn lab_xdr_decode() { - let sandbox = TestEnv::default(); - let cargo_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let ref_xdr_filename = cargo_dir.join("tests/it/lab_test_transaction_envelope.txt"); - let ref_xdr = std::fs::read_to_string(ref_xdr_filename.clone()).unwrap(); - - let cmd = sandbox - .new_assert_cmd("lab") - .arg("xdr") - .arg("dec") - .arg("--type") - .arg("TransactionEnvelope") - .arg("--xdr") - .arg("AAAAAgAAAABzdv3ojkzWHMD7KUoXhrPx0GH18vHKV0ZfqpMiEblG1gAAAGQAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAADRjwIQ/2zB8tzxMB+71MMO4RoHWCBoTUcd+J0PEBHqKAAAAOjUpRAAAAAAAAAAAAERuUbWAAAAQKAEpum2TGh/P2K0/eOxeXw1eGEG5fl/Ft2a/j7YUN+H3XNjkFAfYnJvfpmvTsNYqPsoHKufgRpDmJuAhd0xJgk=") - .assert() - .success(); - let stdout = String::from_utf8(cmd.get_output().clone().stdout).unwrap(); - if ref_xdr.is_empty() { - std::fs::write(ref_xdr_filename, stdout.clone()).unwrap(); - } - assert_eq!(stdout, ref_xdr); -} diff --git a/cmd/crates/soroban-test/tests/it/main.rs b/cmd/crates/soroban-test/tests/it/main.rs index 3077d2fa0..a6b18cb22 100644 --- a/cmd/crates/soroban-test/tests/it/main.rs +++ b/cmd/crates/soroban-test/tests/it/main.rs @@ -3,7 +3,6 @@ mod config; mod help; #[cfg(feature = "integration")] mod integration; -mod lab; mod plugin; mod util; mod version; diff --git a/cmd/soroban-cli/src/commands/config/mod.rs b/cmd/soroban-cli/src/commands/config/mod.rs index eaa63aa58..1d0cd8678 100644 --- a/cmd/soroban-cli/src/commands/config/mod.rs +++ b/cmd/soroban-cli/src/commands/config/mod.rs @@ -7,16 +7,19 @@ use crate::Pwd; use self::{network::Network, secret::Secret}; -use super::network; +use super::{keys, network}; pub mod locator; pub mod secret; #[derive(Debug, Parser)] pub enum Cmd { - /// Configure different networks + /// Configure different networks. Depraecated, use `soroban network` instead. #[command(subcommand)] Network(network::Cmd), + /// Identity management. Deprecated use `soroban keys` instead. + #[command(subcommand)] + Identity(keys::Cmd), } #[derive(thiserror::Error, Debug)] diff --git a/cmd/soroban-cli/src/commands/lab/token/wrap.rs b/cmd/soroban-cli/src/commands/contract/deploy/asset.rs similarity index 92% rename from cmd/soroban-cli/src/commands/lab/token/wrap.rs rename to cmd/soroban-cli/src/commands/contract/deploy/asset.rs index 2b6f4dd4f..c10bf8164 100644 --- a/cmd/soroban-cli/src/commands/lab/token/wrap.rs +++ b/cmd/soroban-cli/src/commands/contract/deploy/asset.rs @@ -99,21 +99,6 @@ impl Cmd { } } -/// # Errors -/// -/// Might return an error -pub fn vec_to_hash(res: &ScVal) -> Result { - if let ScVal::Address(ScAddress::Contract(res_contract)) = &res { - let mut hash_bytes: [u8; 32] = [0; 32]; - for (i, b) in res_contract.0.iter().enumerate() { - hash_bytes[i] = *b; - } - Ok(Hash(hash_bytes)) - } else { - Err(XdrError::Invalid) - } -} - fn build_wrap_token_tx( asset: &Asset, contract_id: &Hash, diff --git a/cmd/soroban-cli/src/commands/contract/deploy/wasm.rs b/cmd/soroban-cli/src/commands/contract/deploy/wasm.rs new file mode 100644 index 000000000..76c130173 --- /dev/null +++ b/cmd/soroban-cli/src/commands/contract/deploy/wasm.rs @@ -0,0 +1,228 @@ +use std::array::TryFromSliceError; +use std::fmt::Debug; +use std::num::ParseIntError; + +use clap::{arg, command, Parser}; +use rand::Rng; +use soroban_env_host::{ + xdr::{ + AccountId, ContractExecutable, ContractIdPreimage, ContractIdPreimageFromAddress, + CreateContractArgs, Error as XdrError, Hash, HostFunction, InvokeHostFunctionOp, Memo, + MuxedAccount, Operation, OperationBody, Preconditions, PublicKey, ScAddress, + SequenceNumber, Transaction, TransactionExt, Uint256, VecM, + }, + HostError, +}; + +use crate::commands::contract::{self, id::wasm::get_contract_id}; +use crate::{ + commands::{config, contract::install, HEADING_RPC}, + rpc::{self, Client}, + utils, wasm, +}; + +#[derive(Parser, Debug, Clone)] +#[command(group( + clap::ArgGroup::new("wasm_src") + .required(true) + .args(&["wasm", "wasm_hash"]), +))] +#[group(skip)] +pub struct Cmd { + /// WASM file to deploy + #[arg(long, group = "wasm_src")] + wasm: Option, + /// Hash of the already installed/deployed WASM file + #[arg(long = "wasm-hash", conflicts_with = "wasm", group = "wasm_src")] + wasm_hash: Option, + /// Custom salt 32-byte salt for the token id + #[arg( + long, + help_heading = HEADING_RPC, + )] + salt: Option, + #[command(flatten)] + config: config::Args, + #[command(flatten)] + pub fee: crate::fee::Args, + #[arg(long, short = 'i', default_value = "false")] + /// Whether to ignore safety checks when deploying contracts + pub ignore_checks: bool, +} + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + Install(#[from] install::Error), + #[error(transparent)] + Host(#[from] HostError), + #[error("error parsing int: {0}")] + ParseIntError(#[from] ParseIntError), + #[error("internal conversion error: {0}")] + TryFromSliceError(#[from] TryFromSliceError), + #[error("xdr processing error: {0}")] + Xdr(#[from] XdrError), + #[error("jsonrpc error: {0}")] + JsonRpc(#[from] jsonrpsee_core::Error), + #[error("cannot parse salt: {salt}")] + CannotParseSalt { salt: String }, + #[error("cannot parse contract ID {contract_id}: {error}")] + CannotParseContractId { + contract_id: String, + error: stellar_strkey::DecodeError, + }, + #[error("cannot parse WASM hash {wasm_hash}: {error}")] + CannotParseWasmHash { + wasm_hash: String, + error: stellar_strkey::DecodeError, + }, + #[error("Must provide either --wasm or --wash-hash")] + WasmNotProvided, + #[error(transparent)] + Rpc(#[from] rpc::Error), + #[error(transparent)] + Config(#[from] config::Error), + #[error(transparent)] + StrKey(#[from] stellar_strkey::DecodeError), + #[error(transparent)] + Infallible(#[from] std::convert::Infallible), + #[error(transparent)] + WasmId(#[from] contract::id::wasm::Error), +} + +impl Cmd { + pub async fn run(&self) -> Result<(), Error> { + let res_str = self.run_and_get_contract_id().await?; + println!("{res_str}"); + Ok(()) + } + + pub async fn run_and_get_contract_id(&self) -> Result { + let wasm_hash = if let Some(wasm) = &self.wasm { + let hash = install::Cmd { + wasm: wasm::Args { wasm: wasm.clone() }, + config: self.config.clone(), + fee: self.fee.clone(), + ignore_checks: self.ignore_checks, + } + .run_and_get_hash() + .await?; + hex::encode(hash) + } else { + self.wasm_hash + .as_ref() + .ok_or(Error::WasmNotProvided)? + .to_string() + }; + + let hash = Hash(utils::contract_id_from_str(&wasm_hash).map_err(|e| { + Error::CannotParseWasmHash { + wasm_hash: wasm_hash.clone(), + error: e, + } + })?); + + self.run_against_rpc_server(hash).await + } + + async fn run_against_rpc_server(&self, wasm_hash: Hash) -> Result { + let network = self.config.get_network()?; + let salt: [u8; 32] = match &self.salt { + Some(h) => soroban_spec_tools::utils::padded_hex_from_str(h, 32) + .map_err(|_| Error::CannotParseSalt { salt: h.clone() })? + .try_into() + .map_err(|_| Error::CannotParseSalt { salt: h.clone() })?, + None => rand::thread_rng().gen::<[u8; 32]>(), + }; + + let client = Client::new(&network.rpc_url)?; + client + .verify_network_passphrase(Some(&network.network_passphrase)) + .await?; + let key = self.config.key_pair()?; + + // Get the account sequence number + let public_strkey = + stellar_strkey::ed25519::PublicKey(key.verifying_key().to_bytes()).to_string(); + + let account_details = client.get_account(&public_strkey).await?; + let sequence: i64 = account_details.seq_num.into(); + let (tx, contract_id) = build_create_contract_tx( + wasm_hash, + sequence + 1, + self.fee.fee, + &network.network_passphrase, + salt, + &key, + )?; + client + .prepare_and_send_transaction(&tx, &key, &[], &network.network_passphrase, None, None) + .await?; + Ok(stellar_strkey::Contract(contract_id.0).to_string()) + } +} + +fn build_create_contract_tx( + hash: Hash, + sequence: i64, + fee: u32, + network_passphrase: &str, + salt: [u8; 32], + key: &ed25519_dalek::SigningKey, +) -> Result<(Transaction, Hash), Error> { + let source_account = AccountId(PublicKey::PublicKeyTypeEd25519( + key.verifying_key().to_bytes().into(), + )); + + let contract_id_preimage = ContractIdPreimage::Address(ContractIdPreimageFromAddress { + address: ScAddress::Account(source_account), + salt: Uint256(salt), + }); + let contract_id = get_contract_id(contract_id_preimage.clone(), network_passphrase)?; + + let op = Operation { + source_account: None, + body: OperationBody::InvokeHostFunction(InvokeHostFunctionOp { + host_function: HostFunction::CreateContract(CreateContractArgs { + contract_id_preimage, + executable: ContractExecutable::Wasm(hash), + }), + auth: VecM::default(), + }), + }; + let tx = Transaction { + source_account: MuxedAccount::Ed25519(Uint256(key.verifying_key().to_bytes())), + fee, + seq_num: SequenceNumber(sequence), + cond: Preconditions::None, + memo: Memo::None, + operations: vec![op].try_into()?, + ext: TransactionExt::V0, + }; + + Ok((tx, Hash(contract_id.into()))) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_build_create_contract() { + let hash = hex::decode("0000000000000000000000000000000000000000000000000000000000000000") + .unwrap() + .try_into() + .unwrap(); + let result = build_create_contract_tx( + Hash(hash), + 300, + 1, + "Public Global Stellar Network ; September 2015", + [0u8; 32], + &utils::parse_secret_key("SBFGFF27Y64ZUGFAIG5AMJGQODZZKV2YQKAVUUN4HNE24XZXD2OEUVUP") + .unwrap(), + ); + + assert!(result.is_ok()); + } +} diff --git a/cmd/soroban-cli/src/commands/contract/id.rs b/cmd/soroban-cli/src/commands/contract/id.rs new file mode 100644 index 000000000..bb8744d51 --- /dev/null +++ b/cmd/soroban-cli/src/commands/contract/id.rs @@ -0,0 +1,28 @@ +pub mod asset; +pub mod wasm; + +#[derive(Debug, clap::Subcommand)] +pub enum Cmd { + /// Deploy builtin Soroban Asset Contract + Asset(asset::Cmd), + /// Deploy normal Wasm Contract + Wasm(wasm::Cmd), +} + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + Asset(#[from] asset::Error), + #[error(transparent)] + Wasm(#[from] wasm::Error), +} + +impl Cmd { + pub fn run(&self) -> Result<(), Error> { + match &self { + Cmd::Asset(asset) => asset.run()?, + Cmd::Wasm(wasm) => wasm.run()?, + } + Ok(()) + } +} diff --git a/cmd/soroban-cli/src/commands/lab/token/id.rs b/cmd/soroban-cli/src/commands/contract/id/asset.rs similarity index 100% rename from cmd/soroban-cli/src/commands/lab/token/id.rs rename to cmd/soroban-cli/src/commands/contract/id/asset.rs diff --git a/cmd/soroban-cli/src/commands/contract/id/wasm.rs b/cmd/soroban-cli/src/commands/contract/id/wasm.rs new file mode 100644 index 000000000..4097e7bbf --- /dev/null +++ b/cmd/soroban-cli/src/commands/contract/id/wasm.rs @@ -0,0 +1,72 @@ +use clap::{arg, command, Parser}; +use sha2::{Digest, Sha256}; +use soroban_env_host::xdr::{ + self, AccountId, ContractIdPreimage, ContractIdPreimageFromAddress, Hash, HashIdPreimage, + HashIdPreimageContractId, Limits, PublicKey, ScAddress, Uint256, WriteXdr, +}; + +use crate::commands::config; + +#[derive(Parser, Debug, Clone)] +#[group(skip)] +pub struct Cmd { + /// ID of the Soroban contract + #[arg(long)] + pub salt: String, + + #[command(flatten)] + pub config: config::Args, +} +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + ParseError(#[from] crate::utils::parsing::Error), + #[error(transparent)] + ConfigError(#[from] crate::commands::config::Error), + #[error(transparent)] + Xdr(#[from] xdr::Error), + #[error("cannot parse salt {0}")] + CannotParseSalt(String), +} +impl Cmd { + pub fn run(&self) -> Result<(), Error> { + let salt: [u8; 32] = soroban_spec_tools::utils::padded_hex_from_str(&self.salt, 32) + .map_err(|_| Error::CannotParseSalt(self.salt.clone()))? + .try_into() + .map_err(|_| Error::CannotParseSalt(self.salt.clone()))?; + let contract_id_preimage = + contract_preimage(&self.config.key_pair()?.verifying_key(), salt); + let contract_id = get_contract_id( + contract_id_preimage.clone(), + &self.config.get_network()?.network_passphrase, + )?; + let strkey_contract_id = stellar_strkey::Contract(contract_id.0).to_string(); + println!("{strkey_contract_id}"); + Ok(()) + } +} + +pub fn contract_preimage(key: &ed25519_dalek::VerifyingKey, salt: [u8; 32]) -> ContractIdPreimage { + let source_account = AccountId(PublicKey::PublicKeyTypeEd25519(key.to_bytes().into())); + ContractIdPreimage::Address(ContractIdPreimageFromAddress { + address: ScAddress::Account(source_account), + salt: Uint256(salt), + }) +} + +pub fn get_contract_id( + contract_id_preimage: ContractIdPreimage, + network_passphrase: &str, +) -> Result { + let network_id = Hash( + Sha256::digest(network_passphrase.as_bytes()) + .try_into() + .unwrap(), + ); + let preimage = HashIdPreimage::ContractId(HashIdPreimageContractId { + network_id, + contract_id_preimage, + }); + let preimage_xdr = preimage.to_xdr(Limits::none())?; + Ok(Hash(Sha256::digest(preimage_xdr).into())) +} diff --git a/cmd/soroban-cli/src/commands/contract/mod.rs b/cmd/soroban-cli/src/commands/contract/mod.rs index d94e8da5b..db450f611 100644 --- a/cmd/soroban-cli/src/commands/contract/mod.rs +++ b/cmd/soroban-cli/src/commands/contract/mod.rs @@ -3,6 +3,7 @@ pub mod build; pub mod deploy; pub mod extend; pub mod fetch; +pub mod id; pub mod inspect; pub mod install; pub mod invoke; @@ -32,6 +33,10 @@ pub enum Cmd { /// Fetch a contract's Wasm binary Fetch(fetch::Cmd), + /// Generate the contract id for a given contract or asset + #[command(subcommand)] + Id(id::Cmd), + /// Inspect a WASM file listing contract functions, meta, etc Inspect(inspect::Cmd), @@ -76,6 +81,8 @@ pub enum Error { #[error(transparent)] Fetch(#[from] fetch::Error), + #[error(transparent)] + Id(#[from] id::Error), #[error(transparent)] Inspect(#[from] inspect::Error), @@ -103,6 +110,7 @@ impl Cmd { Cmd::Build(build) => build.run()?, Cmd::Extend(extend) => extend.run().await?, Cmd::Deploy(deploy) => deploy.run().await?, + Cmd::Id(id) => id.run()?, Cmd::Inspect(inspect) => inspect.run()?, Cmd::Install(install) => install.run().await?, Cmd::Invoke(invoke) => invoke.run(global_args).await?, diff --git a/cmd/soroban-cli/src/commands/lab/mod.rs b/cmd/soroban-cli/src/commands/lab/mod.rs index 96d64094d..f405efe6d 100644 --- a/cmd/soroban-cli/src/commands/lab/mod.rs +++ b/cmd/soroban-cli/src/commands/lab/mod.rs @@ -1,4 +1,5 @@ use clap::Subcommand; +use stellar_xdr::cli as xdr; pub mod token; @@ -8,7 +9,7 @@ pub enum Cmd { Token(token::Root), /// Decode xdr - Xdr(stellar_xdr::cli::Root), + Xdr(xdr::Root), } #[derive(thiserror::Error, Debug)] @@ -16,7 +17,7 @@ pub enum Error { #[error(transparent)] Token(#[from] token::Error), #[error(transparent)] - Xdr(#[from] stellar_xdr::cli::Error), + Xdr(#[from] xdr::Error), } impl Cmd { diff --git a/cmd/soroban-cli/src/commands/lab/token/mod.rs b/cmd/soroban-cli/src/commands/lab/token/mod.rs index ab6eb7117..bd7eacf36 100644 --- a/cmd/soroban-cli/src/commands/lab/token/mod.rs +++ b/cmd/soroban-cli/src/commands/lab/token/mod.rs @@ -1,10 +1,8 @@ use std::fmt::Debug; +use crate::commands::contract::{deploy, id}; use clap::{Parser, Subcommand}; -pub mod id; -pub mod wrap; - #[derive(Parser, Debug)] pub struct Root { #[clap(subcommand)] @@ -14,17 +12,19 @@ pub struct Root { #[derive(Subcommand, Debug)] enum Cmd { /// Deploy a token contract to wrap an existing Stellar classic asset for smart contract usage - Wrap(wrap::Cmd), + /// Deprecated, use `soroban contract deploy asset` instead + Wrap(deploy::asset::Cmd), /// Compute the expected contract id for the given asset - Id(id::Cmd), + /// Deprecated, use `soroban contract id asset` instead + Id(id::asset::Cmd), } #[derive(thiserror::Error, Debug)] pub enum Error { #[error(transparent)] - Wrap(#[from] wrap::Error), + Wrap(#[from] deploy::asset::Error), #[error(transparent)] - Id(#[from] id::Error), + Id(#[from] id::asset::Error), } impl Root { diff --git a/cmd/soroban-cli/src/commands/mod.rs b/cmd/soroban-cli/src/commands/mod.rs index e4d823ce2..0179d6a91 100644 --- a/cmd/soroban-cli/src/commands/mod.rs +++ b/cmd/soroban-cli/src/commands/mod.rs @@ -98,6 +98,7 @@ impl Root { Cmd::Network(network) => network.run()?, Cmd::Version(version) => version.run(), Cmd::Keys(id) => id.run().await?, + Cmd::Config(_) => todo!(), }; Ok(()) } @@ -116,6 +117,9 @@ pub enum Cmd { /// Print shell completion code for the specified shell. #[command(long_about = completion::LONG_ABOUT)] Completion(completion::Cmd), + /// Deprecated, use `soroban keys` and `soroban network` instead + #[command(subcommand)] + Config(config::Cmd), /// Tools for smart contract developers #[command(subcommand)] Contract(contract::Cmd), diff --git a/cmd/soroban-rpc/internal/test/cli_test.go b/cmd/soroban-rpc/internal/test/cli_test.go index 8488ea2e3..fbffc660b 100644 --- a/cmd/soroban-rpc/internal/test/cli_test.go +++ b/cmd/soroban-rpc/internal/test/cli_test.go @@ -51,7 +51,7 @@ func TestCLIWrapCustom(t *testing.T) { it := NewCLITest(t) assetCode := "deadbeef" issuerAccount := getCLIDefaultAccount(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("lab token wrap --asset=%s:%s", assetCode, issuerAccount)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy asset --asset=%s:%s", assetCode, issuerAccount)) require.Equal(t, "true", runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id=%s -- authorized --id=%s", strkeyContractID, issuerAccount))) asset := txnbuild.CreditAsset{ Code: assetCode, @@ -65,7 +65,7 @@ func TestCLIWrapCustom(t *testing.T) { func TestCLIWrapNative(t *testing.T) { NewCLITest(t) testAccount := getCLIDefaultAccount(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("lab token wrap --asset=native:%s", testAccount)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy asset --asset=native:%s", testAccount)) require.Equal(t, "CAMTHSPKXZJIRTUXQP5QWJIFH3XIDMKLFAWVQOFOXPTKAW5GKV37ZC4N", strkeyContractID) require.Equal(t, "true", runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id=%s -- authorized --id=%s", strkeyContractID, testAccount))) require.Equal(t, "\"9223372036854775807\"", runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id=%s -- balance --id %s", strkeyContractID, testAccount))) @@ -84,13 +84,13 @@ func TestCLIContractInstallAndDeploy(t *testing.T) { runSuccessfulCLICmd(t, fmt.Sprintf("contract install --wasm %s --ignore-checks", helloWorldContractPath)) wasm := getHelloWorldContract(t) contractHash := xdr.Hash(sha256.Sum256(wasm)) - output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt %s --wasm-hash %s --ignore-checks", hex.EncodeToString(testSalt[:]), contractHash.HexString())) + output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt %s --wasm-hash %s --ignore-checks", hex.EncodeToString(testSalt[:]), contractHash.HexString())) outputsContractIDInLastLine(t, output) } func TestCLIContractDeploy(t *testing.T) { NewCLITest(t) - output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt %s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt %s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) outputsContractIDInLastLine(t, output) } @@ -110,14 +110,14 @@ func outputsContractIDInLastLine(t *testing.T, output string) { func TestCLIContractDeployAndInvoke(t *testing.T) { NewCLITest(t) - contractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + contractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) output := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- hello --world=world", contractID)) require.Contains(t, output, `["Hello","world"]`) } func TestCLIRestorePreamble(t *testing.T) { test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) require.Equal(t, "1", count) count = runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) @@ -135,7 +135,7 @@ func TestCLIRestorePreamble(t *testing.T) { func TestCLIExtend(t *testing.T) { test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) require.Equal(t, "1", count) @@ -159,7 +159,7 @@ func TestCLIExtend(t *testing.T) { } func TestCLIExtendTooLow(t *testing.T) { test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) require.Equal(t, "1", count) @@ -181,7 +181,7 @@ func TestCLIExtendTooLow(t *testing.T) { func TestCLIExtendTooHigh(t *testing.T) { test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) require.Equal(t, "1", count) @@ -200,7 +200,7 @@ func TestCLIExtendTooHigh(t *testing.T) { func TestCLIRestore(t *testing.T) { test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) require.Equal(t, "1", count) diff --git a/docs/soroban-cli-full-docs.md b/docs/soroban-cli-full-docs.md index 746433fd2..44ab4e1b9 100644 --- a/docs/soroban-cli-full-docs.md +++ b/docs/soroban-cli-full-docs.md @@ -6,6 +6,19 @@ This document contains the help content for the `soroban` command-line program. * [`soroban`↴](#soroban) * [`soroban completion`↴](#soroban-completion) +* [`soroban config`↴](#soroban-config) +* [`soroban config network`↴](#soroban-config-network) +* [`soroban config network add`↴](#soroban-config-network-add) +* [`soroban config network rm`↴](#soroban-config-network-rm) +* [`soroban config network ls`↴](#soroban-config-network-ls) +* [`soroban config identity`↴](#soroban-config-identity) +* [`soroban config identity add`↴](#soroban-config-identity-add) +* [`soroban config identity address`↴](#soroban-config-identity-address) +* [`soroban config identity fund`↴](#soroban-config-identity-fund) +* [`soroban config identity generate`↴](#soroban-config-identity-generate) +* [`soroban config identity ls`↴](#soroban-config-identity-ls) +* [`soroban config identity rm`↴](#soroban-config-identity-rm) +* [`soroban config identity show`↴](#soroban-config-identity-show) * [`soroban contract`↴](#soroban-contract) * [`soroban contract bindings`↴](#soroban-contract-bindings) * [`soroban contract bindings json`↴](#soroban-contract-bindings-json) @@ -14,7 +27,12 @@ This document contains the help content for the `soroban` command-line program. * [`soroban contract build`↴](#soroban-contract-build) * [`soroban contract extend`↴](#soroban-contract-extend) * [`soroban contract deploy`↴](#soroban-contract-deploy) +* [`soroban contract deploy asset`↴](#soroban-contract-deploy-asset) +* [`soroban contract deploy wasm`↴](#soroban-contract-deploy-wasm) * [`soroban contract fetch`↴](#soroban-contract-fetch) +* [`soroban contract id`↴](#soroban-contract-id) +* [`soroban contract id asset`↴](#soroban-contract-id-asset) +* [`soroban contract id wasm`↴](#soroban-contract-id-wasm) * [`soroban contract inspect`↴](#soroban-contract-inspect) * [`soroban contract install`↴](#soroban-contract-install) * [`soroban contract invoke`↴](#soroban-contract-invoke) @@ -79,6 +97,7 @@ Full CLI reference: https://github.com/stellar/soroban-tools/tree/main/docs/soro ###### **Subcommands:** * `completion` — Print shell completion code for the specified shell +* `config` — Deprecated, use `soroban keys` and `soroban network` instead * `contract` — Tools for smart contract developers * `events` — Watch the network for contract events * `keys` — Create and manage identities including keys and addresses @@ -122,6 +141,233 @@ To enable autocomplete permanently, run: +## `soroban config` + +Deprecated, use `soroban keys` and `soroban network` instead + +**Usage:** `soroban config ` + +###### **Subcommands:** + +* `network` — Configure different networks. Depraecated, use `soroban network` instead +* `identity` — Identity management. Deprecated use `soroban keys` instead + + + +## `soroban config network` + +Configure different networks. Depraecated, use `soroban network` instead + +**Usage:** `soroban config network ` + +###### **Subcommands:** + +* `add` — Add a new network +* `rm` — Remove a network +* `ls` — List networks + + + +## `soroban config network add` + +Add a new network + +**Usage:** `soroban config network add [OPTIONS] --rpc-url --network-passphrase ` + +###### **Arguments:** + +* `` — Name of network + +###### **Options:** + +* `--rpc-url ` — RPC server endpoint +* `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server +* `--global` — Use global config +* `--config-dir ` + + + +## `soroban config network rm` + +Remove a network + +**Usage:** `soroban config network rm [OPTIONS] ` + +###### **Arguments:** + +* `` — Network to remove + +###### **Options:** + +* `--global` — Use global config +* `--config-dir ` + + + +## `soroban config network ls` + +List networks + +**Usage:** `soroban config network ls [OPTIONS]` + +###### **Options:** + +* `--global` — Use global config +* `--config-dir ` +* `-l`, `--long` — Get more info about the networks + + + +## `soroban config identity` + +Identity management. Deprecated use `soroban keys` instead + +**Usage:** `soroban config identity ` + +###### **Subcommands:** + +* `add` — Add a new identity (keypair, ledger, macOS keychain) +* `address` — Given an identity return its address (public key) +* `fund` — Fund an identity on a test network +* `generate` — Generate a new identity with a seed phrase, currently 12 words +* `ls` — List identities +* `rm` — Remove an identity +* `show` — Given an identity return its private key + + + +## `soroban config identity add` + +Add a new identity (keypair, ledger, macOS keychain) + +**Usage:** `soroban config identity add [OPTIONS] ` + +###### **Arguments:** + +* `` — Name of identity + +###### **Options:** + +* `--secret-key` — Add using secret_key Can provide with SOROBAN_SECRET_KEY +* `--seed-phrase` — Add using 12 word seed phrase to generate secret_key +* `--global` — Use global config +* `--config-dir ` + + + +## `soroban config identity address` + +Given an identity return its address (public key) + +**Usage:** `soroban config identity address [OPTIONS] ` + +###### **Arguments:** + +* `` — Name of identity to lookup, default test identity used if not provided + +###### **Options:** + +* `--hd-path ` — If identity is a seed phrase use this hd path, default is 0 +* `--global` — Use global config +* `--config-dir ` + + + +## `soroban config identity fund` + +Fund an identity on a test network + +**Usage:** `soroban config identity fund [OPTIONS] ` + +###### **Arguments:** + +* `` — Name of identity to lookup, default test identity used if not provided + +###### **Options:** + +* `--rpc-url ` — RPC server endpoint +* `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server +* `--network ` — Name of network to use from config +* `--hd-path ` — If identity is a seed phrase use this hd path, default is 0 +* `--global` — Use global config +* `--config-dir ` + + + +## `soroban config identity generate` + +Generate a new identity with a seed phrase, currently 12 words + +**Usage:** `soroban config identity generate [OPTIONS] ` + +###### **Arguments:** + +* `` — Name of identity + +###### **Options:** + +* `--no-fund` — Do not fund address +* `--seed ` — Optional seed to use when generating seed phrase. Random otherwise +* `-s`, `--as-secret` — Output the generated identity as a secret key +* `--global` — Use global config +* `--config-dir ` +* `--hd-path ` — When generating a secret key, which hd_path should be used from the original seed_phrase +* `-d`, `--default-seed` — Generate the default seed phrase. Useful for testing. Equivalent to --seed 0000000000000000 +* `--rpc-url ` — RPC server endpoint +* `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server +* `--network ` — Name of network to use from config + + + +## `soroban config identity ls` + +List identities + +**Usage:** `soroban config identity ls [OPTIONS]` + +###### **Options:** + +* `--global` — Use global config +* `--config-dir ` +* `-l`, `--long` + + + +## `soroban config identity rm` + +Remove an identity + +**Usage:** `soroban config identity rm [OPTIONS] ` + +###### **Arguments:** + +* `` — Identity to remove + +###### **Options:** + +* `--global` — Use global config +* `--config-dir ` + + + +## `soroban config identity show` + +Given an identity return its private key + +**Usage:** `soroban config identity show [OPTIONS] ` + +###### **Arguments:** + +* `` — Name of identity to lookup, default is test identity + +###### **Options:** + +* `--hd-path ` — If identity is a seed phrase use this hd path, default is 0 +* `--global` — Use global config +* `--config-dir ` + + + ## `soroban contract` Tools for smart contract developers @@ -133,8 +379,9 @@ Tools for smart contract developers * `bindings` — Generate code client bindings for a contract * `build` — Build a contract from source * `extend` — Extend the time to live ledger of a contract-data ledger entry -* `deploy` — Deploy a contract +* `deploy` — Deploy a contract or Soroban Asset Contract * `fetch` — Fetch a contract's Wasm binary +* `id` — Generate the contract id for a given contract or asset * `inspect` — Inspect a WASM file listing contract functions, meta, etc * `install` — Install a WASM file to the ledger without creating a contract instance * `invoke` — Invoke a contract function @@ -269,9 +516,44 @@ If no keys are specified the contract itself is extended. ## `soroban contract deploy` -Deploy a contract +Deploy a contract or Soroban Asset Contract + +**Usage:** `soroban contract deploy ` + +###### **Subcommands:** + +* `asset` — Deploy builtin Soroban Asset Contract +* `wasm` — Deploy normal Wasm Contract + + + +## `soroban contract deploy asset` + +Deploy builtin Soroban Asset Contract + +**Usage:** `soroban contract deploy asset [OPTIONS] --asset --source-account ` + +###### **Options:** + +* `--asset ` — ID of the Stellar classic asset to wrap, e.g. "USDC:G...5" +* `--rpc-url ` — RPC server endpoint +* `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server +* `--network ` — Name of network to use from config +* `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` +* `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` +* `--global` — Use global config +* `--config-dir ` +* `--fee ` — fee amount for transaction, in stroops. 1 stroop = 0.0000001 xlm + + Default value: `100` + + -**Usage:** `soroban contract deploy [OPTIONS] --source-account <--wasm |--wasm-hash >` +## `soroban contract deploy wasm` + +Deploy normal Wasm Contract + +**Usage:** `soroban contract deploy wasm [OPTIONS] --source-account <--wasm |--wasm-hash >` ###### **Options:** @@ -312,6 +594,57 @@ Fetch a contract's Wasm binary +## `soroban contract id` + +Generate the contract id for a given contract or asset + +**Usage:** `soroban contract id ` + +###### **Subcommands:** + +* `asset` — Deploy builtin Soroban Asset Contract +* `wasm` — Deploy normal Wasm Contract + + + +## `soroban contract id asset` + +Deploy builtin Soroban Asset Contract + +**Usage:** `soroban contract id asset [OPTIONS] --asset --source-account ` + +###### **Options:** + +* `--asset ` — ID of the Stellar classic asset to wrap, e.g. "USDC:G...5" +* `--rpc-url ` — RPC server endpoint +* `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server +* `--network ` — Name of network to use from config +* `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` +* `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` +* `--global` — Use global config +* `--config-dir ` + + + +## `soroban contract id wasm` + +Deploy normal Wasm Contract + +**Usage:** `soroban contract id wasm [OPTIONS] --salt --source-account ` + +###### **Options:** + +* `--salt ` — ID of the Soroban contract +* `--rpc-url ` — RPC server endpoint +* `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server +* `--network ` — Name of network to use from config +* `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` +* `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` +* `--global` — Use global config +* `--config-dir ` + + + ## `soroban contract inspect` Inspect a WASM file listing contract functions, meta, etc @@ -700,14 +1033,14 @@ Wrap, create, and manage token contracts ###### **Subcommands:** -* `wrap` — Deploy a token contract to wrap an existing Stellar classic asset for smart contract usage -* `id` — Compute the expected contract id for the given asset +* `wrap` — Deploy a token contract to wrap an existing Stellar classic asset for smart contract usage Deprecated, use `soroban contract deploy asset` instead +* `id` — Compute the expected contract id for the given asset Deprecated, use `soroban contract id asset` instead ## `soroban lab token wrap` -Deploy a token contract to wrap an existing Stellar classic asset for smart contract usage +Deploy a token contract to wrap an existing Stellar classic asset for smart contract usage Deprecated, use `soroban contract deploy asset` instead **Usage:** `soroban lab token wrap [OPTIONS] --asset --source-account ` @@ -729,7 +1062,7 @@ Deploy a token contract to wrap an existing Stellar classic asset for smart cont ## `soroban lab token id` -Compute the expected contract id for the given asset +Compute the expected contract id for the given asset Deprecated, use `soroban contract id asset` instead **Usage:** `soroban lab token id [OPTIONS] --asset --source-account ` @@ -855,6 +1188,43 @@ Decode XDR + +## `soroban lab xdr encode` + +Encode XDR + +**Usage:** `soroban lab xdr encode [OPTIONS] --type [FILES]...` + +###### **Arguments:** + +* `` — Files to encode, or stdin if omitted + +###### **Options:** + +* `--type ` — XDR type to encode +* `--input ` + + Default value: `json` + + Possible values: `json` + +* `--output ` + + Default value: `single-base64` + + Possible values: `single`, `single-base64` + + + + +## `soroban lab xdr version` + +Print version information + +**Usage:** `soroban lab xdr version` + + + ## `soroban network` Start and configure networks @@ -919,43 +1289,6 @@ List networks - -## `soroban lab xdr encode` - -Encode XDR - -**Usage:** `soroban lab xdr encode [OPTIONS] --type [FILES]...` - -###### **Arguments:** - -* `` — Files to encode, or stdin if omitted - -###### **Options:** - -* `--type ` — XDR type to encode -* `--input ` - - Default value: `json` - - Possible values: `json` - -* `--output ` - - Default value: `single-base64` - - Possible values: `single`, `single-base64` - - - - -## `soroban lab xdr version` - -Print version information - -**Usage:** `soroban lab xdr version` - - - ## `soroban version` Print version information From 02184ef6b6624dae6eacffd80235b52e1af8ad17 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Wed, 3 Jan 2024 16:34:28 -0500 Subject: [PATCH 14/20] fix: clippy --- cmd/soroban-cli/src/commands/contract/id/wasm.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cmd/soroban-cli/src/commands/contract/id/wasm.rs b/cmd/soroban-cli/src/commands/contract/id/wasm.rs index 4097e7bbf..9c02f07d2 100644 --- a/cmd/soroban-cli/src/commands/contract/id/wasm.rs +++ b/cmd/soroban-cli/src/commands/contract/id/wasm.rs @@ -58,11 +58,7 @@ pub fn get_contract_id( contract_id_preimage: ContractIdPreimage, network_passphrase: &str, ) -> Result { - let network_id = Hash( - Sha256::digest(network_passphrase.as_bytes()) - .try_into() - .unwrap(), - ); + let network_id = Hash(Sha256::digest(network_passphrase.as_bytes()).into()); let preimage = HashIdPreimage::ContractId(HashIdPreimageContractId { network_id, contract_id_preimage, From 89604a0e86a46a49acc6f497fe908e8201cae318 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Wed, 3 Jan 2024 19:44:30 -0500 Subject: [PATCH 15/20] fix: add back run to config --- cmd/soroban-cli/src/commands/config/mod.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/cmd/soroban-cli/src/commands/config/mod.rs b/cmd/soroban-cli/src/commands/config/mod.rs index 1d0cd8678..be76e77f9 100644 --- a/cmd/soroban-cli/src/commands/config/mod.rs +++ b/cmd/soroban-cli/src/commands/config/mod.rs @@ -17,13 +17,15 @@ pub enum Cmd { /// Configure different networks. Depraecated, use `soroban network` instead. #[command(subcommand)] Network(network::Cmd), - /// Identity management. Deprecated use `soroban keys` instead. + /// Identity management. Deprecated, use `soroban keys` instead. #[command(subcommand)] Identity(keys::Cmd), } #[derive(thiserror::Error, Debug)] pub enum Error { + #[error(transparent)] + Identity(#[from] keys::Error), #[error(transparent)] Network(#[from] network::Error), #[error(transparent)] @@ -32,6 +34,16 @@ pub enum Error { Config(#[from] locator::Error), } +impl Cmd { + pub async fn run(&self) -> Result<(), Error> { + match &self { + Cmd::Identity(identity) => identity.run().await?, + Cmd::Network(network) => network.run()?, + } + Ok(()) + } +} + #[derive(Debug, clap::Args, Clone, Default)] #[group(skip)] pub struct Args { From cde35b78e2570be973fa592bc568b1dbbffcd0a4 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Thu, 4 Jan 2024 15:27:57 -0500 Subject: [PATCH 16/20] fix: docs and go integration test increase max diff --- docs/soroban-cli-full-docs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/soroban-cli-full-docs.md b/docs/soroban-cli-full-docs.md index 44ab4e1b9..7018c2472 100644 --- a/docs/soroban-cli-full-docs.md +++ b/docs/soroban-cli-full-docs.md @@ -150,7 +150,7 @@ Deprecated, use `soroban keys` and `soroban network` instead ###### **Subcommands:** * `network` — Configure different networks. Depraecated, use `soroban network` instead -* `identity` — Identity management. Deprecated use `soroban keys` instead +* `identity` — Identity management. Deprecated, use `soroban keys` instead @@ -220,7 +220,7 @@ List networks ## `soroban config identity` -Identity management. Deprecated use `soroban keys` instead +Identity management. Deprecated, use `soroban keys` instead **Usage:** `soroban config identity ` From 2226d12a4cd56918723266f1ce8b554ae28dc305 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Fri, 5 Jan 2024 12:13:32 -0500 Subject: [PATCH 17/20] fix: add `contract asset` subcommand and revert deploy so non-breaking Also upped another fudge value. Seems a big difference. --- .../src/commands/contract/asset.rs | 27 +++++ cmd/soroban-cli/src/commands/contract/mod.rs | 15 ++- cmd/soroban-rpc/internal/test/cli_test.go | 20 ++-- docs/soroban-cli-full-docs.md | 101 +++++++++++------- 4 files changed, 109 insertions(+), 54 deletions(-) create mode 100644 cmd/soroban-cli/src/commands/contract/asset.rs diff --git a/cmd/soroban-cli/src/commands/contract/asset.rs b/cmd/soroban-cli/src/commands/contract/asset.rs new file mode 100644 index 000000000..ad7be0207 --- /dev/null +++ b/cmd/soroban-cli/src/commands/contract/asset.rs @@ -0,0 +1,27 @@ +use super::{deploy, id}; + +#[derive(Debug, clap::Subcommand)] +pub enum Cmd { + /// Get Id of builtin Soroban Asset Contract. Deprecated, use `soroban contract id asset` instead + Id(id::asset::Cmd), + /// Deploy builtin Soroban Asset Contract + Deploy(deploy::asset::Cmd), +} + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + Id(#[from] id::asset::Error), + #[error(transparent)] + Deploy(#[from] deploy::asset::Error), +} + +impl Cmd { + pub async fn run(&self) -> Result<(), Error> { + match &self { + Cmd::Id(id) => id.run()?, + Cmd::Deploy(asset) => asset.run().await?, + } + Ok(()) + } +} diff --git a/cmd/soroban-cli/src/commands/contract/mod.rs b/cmd/soroban-cli/src/commands/contract/mod.rs index db450f611..35be97a70 100644 --- a/cmd/soroban-cli/src/commands/contract/mod.rs +++ b/cmd/soroban-cli/src/commands/contract/mod.rs @@ -1,3 +1,4 @@ +pub mod asset; pub mod bindings; pub mod build; pub mod deploy; @@ -15,6 +16,9 @@ use crate::commands::global; #[derive(Debug, clap::Subcommand)] pub enum Cmd { + /// Utilities to deploy a Stellar Asset Contract or get its id + #[command(subcommand)] + Asset(asset::Cmd), /// Generate code client bindings for a contract #[command(subcommand)] Bindings(bindings::Cmd), @@ -26,9 +30,8 @@ pub enum Cmd { /// If no keys are specified the contract itself is extended. Extend(extend::Cmd), - /// Deploy a contract or Soroban Asset Contract - #[command(subcommand)] - Deploy(deploy::Cmd), + /// Deploy a wasm contract + Deploy(deploy::wasm::Cmd), /// Fetch a contract's Wasm binary Fetch(fetch::Cmd), @@ -67,6 +70,9 @@ pub enum Cmd { #[derive(thiserror::Error, Debug)] pub enum Error { + #[error(transparent)] + Asset(#[from] asset::Error), + #[error(transparent)] Bindings(#[from] bindings::Error), @@ -77,7 +83,7 @@ pub enum Error { Extend(#[from] extend::Error), #[error(transparent)] - Deploy(#[from] deploy::Error), + Deploy(#[from] deploy::wasm::Error), #[error(transparent)] Fetch(#[from] fetch::Error), @@ -106,6 +112,7 @@ pub enum Error { impl Cmd { pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> { match &self { + Cmd::Asset(asset) => asset.run().await?, Cmd::Bindings(bindings) => bindings.run().await?, Cmd::Build(build) => build.run()?, Cmd::Extend(extend) => extend.run().await?, diff --git a/cmd/soroban-rpc/internal/test/cli_test.go b/cmd/soroban-rpc/internal/test/cli_test.go index fbffc660b..997372ed8 100644 --- a/cmd/soroban-rpc/internal/test/cli_test.go +++ b/cmd/soroban-rpc/internal/test/cli_test.go @@ -51,7 +51,7 @@ func TestCLIWrapCustom(t *testing.T) { it := NewCLITest(t) assetCode := "deadbeef" issuerAccount := getCLIDefaultAccount(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy asset --asset=%s:%s", assetCode, issuerAccount)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract asset deploy --asset=%s:%s", assetCode, issuerAccount)) require.Equal(t, "true", runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id=%s -- authorized --id=%s", strkeyContractID, issuerAccount))) asset := txnbuild.CreditAsset{ Code: assetCode, @@ -65,7 +65,7 @@ func TestCLIWrapCustom(t *testing.T) { func TestCLIWrapNative(t *testing.T) { NewCLITest(t) testAccount := getCLIDefaultAccount(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy asset --asset=native:%s", testAccount)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract asset deploy --asset=native:%s", testAccount)) require.Equal(t, "CAMTHSPKXZJIRTUXQP5QWJIFH3XIDMKLFAWVQOFOXPTKAW5GKV37ZC4N", strkeyContractID) require.Equal(t, "true", runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id=%s -- authorized --id=%s", strkeyContractID, testAccount))) require.Equal(t, "\"9223372036854775807\"", runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id=%s -- balance --id %s", strkeyContractID, testAccount))) @@ -84,13 +84,13 @@ func TestCLIContractInstallAndDeploy(t *testing.T) { runSuccessfulCLICmd(t, fmt.Sprintf("contract install --wasm %s --ignore-checks", helloWorldContractPath)) wasm := getHelloWorldContract(t) contractHash := xdr.Hash(sha256.Sum256(wasm)) - output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt %s --wasm-hash %s --ignore-checks", hex.EncodeToString(testSalt[:]), contractHash.HexString())) + output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt %s --wasm-hash %s --ignore-checks", hex.EncodeToString(testSalt[:]), contractHash.HexString())) outputsContractIDInLastLine(t, output) } func TestCLIContractDeploy(t *testing.T) { NewCLITest(t) - output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt %s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt %s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) outputsContractIDInLastLine(t, output) } @@ -110,14 +110,14 @@ func outputsContractIDInLastLine(t *testing.T, output string) { func TestCLIContractDeployAndInvoke(t *testing.T) { NewCLITest(t) - contractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + contractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) output := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- hello --world=world", contractID)) require.Contains(t, output, `["Hello","world"]`) } func TestCLIRestorePreamble(t *testing.T) { test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) require.Equal(t, "1", count) count = runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) @@ -135,7 +135,7 @@ func TestCLIRestorePreamble(t *testing.T) { func TestCLIExtend(t *testing.T) { test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) require.Equal(t, "1", count) @@ -159,7 +159,7 @@ func TestCLIExtend(t *testing.T) { } func TestCLIExtendTooLow(t *testing.T) { test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) require.Equal(t, "1", count) @@ -181,7 +181,7 @@ func TestCLIExtendTooLow(t *testing.T) { func TestCLIExtendTooHigh(t *testing.T) { test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) require.Equal(t, "1", count) @@ -200,7 +200,7 @@ func TestCLIExtendTooHigh(t *testing.T) { func TestCLIRestore(t *testing.T) { test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy wasm --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) + strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) require.Equal(t, "1", count) diff --git a/docs/soroban-cli-full-docs.md b/docs/soroban-cli-full-docs.md index 7018c2472..0e65fd630 100644 --- a/docs/soroban-cli-full-docs.md +++ b/docs/soroban-cli-full-docs.md @@ -20,6 +20,9 @@ This document contains the help content for the `soroban` command-line program. * [`soroban config identity rm`↴](#soroban-config-identity-rm) * [`soroban config identity show`↴](#soroban-config-identity-show) * [`soroban contract`↴](#soroban-contract) +* [`soroban contract asset`↴](#soroban-contract-asset) +* [`soroban contract asset id`↴](#soroban-contract-asset-id) +* [`soroban contract asset deploy`↴](#soroban-contract-asset-deploy) * [`soroban contract bindings`↴](#soroban-contract-bindings) * [`soroban contract bindings json`↴](#soroban-contract-bindings-json) * [`soroban contract bindings rust`↴](#soroban-contract-bindings-rust) @@ -27,8 +30,6 @@ This document contains the help content for the `soroban` command-line program. * [`soroban contract build`↴](#soroban-contract-build) * [`soroban contract extend`↴](#soroban-contract-extend) * [`soroban contract deploy`↴](#soroban-contract-deploy) -* [`soroban contract deploy asset`↴](#soroban-contract-deploy-asset) -* [`soroban contract deploy wasm`↴](#soroban-contract-deploy-wasm) * [`soroban contract fetch`↴](#soroban-contract-fetch) * [`soroban contract id`↴](#soroban-contract-id) * [`soroban contract id asset`↴](#soroban-contract-id-asset) @@ -376,10 +377,11 @@ Tools for smart contract developers ###### **Subcommands:** +* `asset` — Utilities to deploy a Stellar Asset Contract or get its id * `bindings` — Generate code client bindings for a contract * `build` — Build a contract from source * `extend` — Extend the time to live ledger of a contract-data ledger entry -* `deploy` — Deploy a contract or Soroban Asset Contract +* `deploy` — Deploy a wasm contract * `fetch` — Fetch a contract's Wasm binary * `id` — Generate the contract id for a given contract or asset * `inspect` — Inspect a WASM file listing contract functions, meta, etc @@ -391,6 +393,60 @@ Tools for smart contract developers +## `soroban contract asset` + +Utilities to deploy a Stellar Asset Contract or get its id + +**Usage:** `soroban contract asset ` + +###### **Subcommands:** + +* `id` — Get Id of builtin Soroban Asset Contract. Deprecated, use `soroban contract id asset` instead +* `deploy` — Deploy builtin Soroban Asset Contract + + + +## `soroban contract asset id` + +Get Id of builtin Soroban Asset Contract. Deprecated, use `soroban contract id asset` instead + +**Usage:** `soroban contract asset id [OPTIONS] --asset --source-account ` + +###### **Options:** + +* `--asset ` — ID of the Stellar classic asset to wrap, e.g. "USDC:G...5" +* `--rpc-url ` — RPC server endpoint +* `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server +* `--network ` — Name of network to use from config +* `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` +* `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` +* `--global` — Use global config +* `--config-dir ` + + + +## `soroban contract asset deploy` + +Deploy builtin Soroban Asset Contract + +**Usage:** `soroban contract asset deploy [OPTIONS] --asset --source-account ` + +###### **Options:** + +* `--asset ` — ID of the Stellar classic asset to wrap, e.g. "USDC:G...5" +* `--rpc-url ` — RPC server endpoint +* `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server +* `--network ` — Name of network to use from config +* `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` +* `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` +* `--global` — Use global config +* `--config-dir ` +* `--fee ` — fee amount for transaction, in stroops. 1 stroop = 0.0000001 xlm + + Default value: `100` + + + ## `soroban contract bindings` Generate code client bindings for a contract @@ -516,44 +572,9 @@ If no keys are specified the contract itself is extended. ## `soroban contract deploy` -Deploy a contract or Soroban Asset Contract - -**Usage:** `soroban contract deploy ` - -###### **Subcommands:** - -* `asset` — Deploy builtin Soroban Asset Contract -* `wasm` — Deploy normal Wasm Contract - - - -## `soroban contract deploy asset` - -Deploy builtin Soroban Asset Contract - -**Usage:** `soroban contract deploy asset [OPTIONS] --asset --source-account ` - -###### **Options:** - -* `--asset ` — ID of the Stellar classic asset to wrap, e.g. "USDC:G...5" -* `--rpc-url ` — RPC server endpoint -* `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server -* `--network ` — Name of network to use from config -* `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` -* `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` -* `--global` — Use global config -* `--config-dir ` -* `--fee ` — fee amount for transaction, in stroops. 1 stroop = 0.0000001 xlm - - Default value: `100` - - - -## `soroban contract deploy wasm` - -Deploy normal Wasm Contract +Deploy a wasm contract -**Usage:** `soroban contract deploy wasm [OPTIONS] --source-account <--wasm |--wasm-hash >` +**Usage:** `soroban contract deploy [OPTIONS] --source-account <--wasm |--wasm-hash >` ###### **Options:** From a3758978ac223243965860ac1e7b26ebdd0e83d0 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Fri, 5 Jan 2024 13:47:29 -0500 Subject: [PATCH 18/20] fix: remove wasm subcommand from tests --- cmd/crates/soroban-test/tests/it/integration/util.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/crates/soroban-test/tests/it/integration/util.rs b/cmd/crates/soroban-test/tests/it/integration/util.rs index 3a8fba8c7..ea27680b7 100644 --- a/cmd/crates/soroban-test/tests/it/integration/util.rs +++ b/cmd/crates/soroban-test/tests/it/integration/util.rs @@ -77,7 +77,6 @@ pub fn deploy_contract(sandbox: &TestEnv, wasm: &Wasm) -> String { sandbox .new_assert_cmd("contract") .arg("deploy") - .arg("wasm") .arg("--wasm-hash") .arg(&format!("{hash}")) .arg("--salt") From 6842a5acd560fb1cc1c4ae121df168016234d273 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Fri, 5 Jan 2024 14:32:54 -0500 Subject: [PATCH 19/20] fix: add back run for original config command --- cmd/soroban-cli/src/commands/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/soroban-cli/src/commands/mod.rs b/cmd/soroban-cli/src/commands/mod.rs index 0179d6a91..952869af3 100644 --- a/cmd/soroban-cli/src/commands/mod.rs +++ b/cmd/soroban-cli/src/commands/mod.rs @@ -98,7 +98,7 @@ impl Root { Cmd::Network(network) => network.run()?, Cmd::Version(version) => version.run(), Cmd::Keys(id) => id.run().await?, - Cmd::Config(_) => todo!(), + Cmd::Config(c) => c.run().await?, }; Ok(()) } From bb13b9c075b5b0c946152f21eda9457f64f240d6 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Tue, 9 Jan 2024 14:13:33 -0500 Subject: [PATCH 20/20] fix: improve docs --- .../src/commands/config/locator.rs | 1 + docs/soroban-cli-full-docs.md | 74 +++++++++---------- 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/cmd/soroban-cli/src/commands/config/locator.rs b/cmd/soroban-cli/src/commands/config/locator.rs index 2ec449231..2688b043f 100644 --- a/cmd/soroban-cli/src/commands/config/locator.rs +++ b/cmd/soroban-cli/src/commands/config/locator.rs @@ -69,6 +69,7 @@ pub struct Args { #[arg(long)] pub global: bool, + /// Location of config directory, default is "." #[arg(long, help_heading = "TESTING_OPTIONS")] pub config_dir: Option, } diff --git a/docs/soroban-cli-full-docs.md b/docs/soroban-cli-full-docs.md index 0e65fd630..3546594c6 100644 --- a/docs/soroban-cli-full-docs.md +++ b/docs/soroban-cli-full-docs.md @@ -109,7 +109,7 @@ Full CLI reference: https://github.com/stellar/soroban-tools/tree/main/docs/soro ###### **Options:** * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `-f`, `--filter-logs ` — Filter logs output. To turn on "soroban_cli::log::footprint=debug" or off "=off". Can also use env var `RUST_LOG` * `-q`, `--quiet` — Do not write logs to stderr including `INFO` * `-v`, `--verbose` — Log DEBUG events @@ -184,7 +184,7 @@ Add a new network * `--rpc-url ` — RPC server endpoint * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -201,7 +201,7 @@ Remove a network ###### **Options:** * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -214,7 +214,7 @@ List networks ###### **Options:** * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `-l`, `--long` — Get more info about the networks @@ -252,7 +252,7 @@ Add a new identity (keypair, ledger, macOS keychain) * `--secret-key` — Add using secret_key Can provide with SOROBAN_SECRET_KEY * `--seed-phrase` — Add using 12 word seed phrase to generate secret_key * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -270,7 +270,7 @@ Given an identity return its address (public key) * `--hd-path ` — If identity is a seed phrase use this hd path, default is 0 * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -291,7 +291,7 @@ Fund an identity on a test network * `--network ` — Name of network to use from config * `--hd-path ` — If identity is a seed phrase use this hd path, default is 0 * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -311,7 +311,7 @@ Generate a new identity with a seed phrase, currently 12 words * `--seed ` — Optional seed to use when generating seed phrase. Random otherwise * `-s`, `--as-secret` — Output the generated identity as a secret key * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `--hd-path ` — When generating a secret key, which hd_path should be used from the original seed_phrase * `-d`, `--default-seed` — Generate the default seed phrase. Useful for testing. Equivalent to --seed 0000000000000000 * `--rpc-url ` — RPC server endpoint @@ -329,7 +329,7 @@ List identities ###### **Options:** * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `-l`, `--long` @@ -347,7 +347,7 @@ Remove an identity ###### **Options:** * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -365,7 +365,7 @@ Given an identity return its private key * `--hd-path ` — If identity is a seed phrase use this hd path, default is 0 * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -421,7 +421,7 @@ Get Id of builtin Soroban Asset Contract. Deprecated, use `soroban contract id a * `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` * `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -440,7 +440,7 @@ Deploy builtin Soroban Asset Contract * `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` * `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `--fee ` — fee amount for transaction, in stroops. 1 stroop = 0.0000001 xlm Default value: `100` @@ -498,7 +498,7 @@ Generate a TypeScript / JavaScript package * `--overwrite` — Whether to overwrite output directory if it already exists * `--contract-id ` — The contract ID/address on the network * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `--rpc-url ` — RPC server endpoint * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config @@ -563,7 +563,7 @@ If no keys are specified the contract itself is extended. * `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` * `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `--fee ` — fee amount for transaction, in stroops. 1 stroop = 0.0000001 xlm Default value: `100` @@ -587,7 +587,7 @@ Deploy a wasm contract * `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` * `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `--fee ` — fee amount for transaction, in stroops. 1 stroop = 0.0000001 xlm Default value: `100` @@ -608,7 +608,7 @@ Fetch a contract's Wasm binary * `--id ` — Contract ID to fetch * `-o`, `--out-file ` — Where to write output otherwise stdout is used * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `--rpc-url ` — RPC server endpoint * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config @@ -643,7 +643,7 @@ Deploy builtin Soroban Asset Contract * `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` * `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -662,7 +662,7 @@ Deploy normal Wasm Contract * `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` * `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -688,7 +688,7 @@ Inspect a WASM file listing contract functions, meta, etc Pretty print of contract spec entries * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -706,7 +706,7 @@ Install a WASM file to the ledger without creating a contract instance * `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` * `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `--fee ` — fee amount for transaction, in stroops. 1 stroop = 0.0000001 xlm Default value: `100` @@ -741,7 +741,7 @@ soroban contract invoke ... -- --help * `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` * `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `--fee ` — fee amount for transaction, in stroops. 1 stroop = 0.0000001 xlm Default value: `100` @@ -800,7 +800,7 @@ Print the current value of a contract-data ledger entry * `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` * `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -835,7 +835,7 @@ If no keys are specificed the contract itself is restored. * `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` * `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `--fee ` — fee amount for transaction, in stroops. 1 stroop = 0.0000001 xlm Default value: `100` @@ -876,7 +876,7 @@ Watch the network for contract events Possible values: `all`, `contract`, `system` * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `--rpc-url ` — RPC server endpoint * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config @@ -916,7 +916,7 @@ Add a new identity (keypair, ledger, macOS keychain) * `--secret-key` — Add using secret_key Can provide with SOROBAN_SECRET_KEY * `--seed-phrase` — Add using 12 word seed phrase to generate secret_key * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -934,7 +934,7 @@ Given an identity return its address (public key) * `--hd-path ` — If identity is a seed phrase use this hd path, default is 0 * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -955,7 +955,7 @@ Fund an identity on a test network * `--network ` — Name of network to use from config * `--hd-path ` — If identity is a seed phrase use this hd path, default is 0 * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -975,7 +975,7 @@ Generate a new identity with a seed phrase, currently 12 words * `--seed ` — Optional seed to use when generating seed phrase. Random otherwise * `-s`, `--as-secret` — Output the generated identity as a secret key * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `--hd-path ` — When generating a secret key, which hd_path should be used from the original seed_phrase * `-d`, `--default-seed` — Generate the default seed phrase. Useful for testing. Equivalent to --seed 0000000000000000 * `--rpc-url ` — RPC server endpoint @@ -993,7 +993,7 @@ List identities ###### **Options:** * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `-l`, `--long` @@ -1011,7 +1011,7 @@ Remove an identity ###### **Options:** * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -1029,7 +1029,7 @@ Given an identity return its private key * `--hd-path ` — If identity is a seed phrase use this hd path, default is 0 * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -1074,7 +1074,7 @@ Deploy a token contract to wrap an existing Stellar classic asset for smart cont * `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` * `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `--fee ` — fee amount for transaction, in stroops. 1 stroop = 0.0000001 xlm Default value: `100` @@ -1096,7 +1096,7 @@ Compute the expected contract id for the given asset Deprecated, use `soroban co * `--source-account ` — Account that signs the final transaction. Alias `source`. Can be an identity (--source alice), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). Default: `identity generate --default-seed` * `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -1275,7 +1275,7 @@ Add a new network * `--rpc-url ` — RPC server endpoint * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -1292,7 +1292,7 @@ Remove a network ###### **Options:** * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." @@ -1305,7 +1305,7 @@ List networks ###### **Options:** * `--global` — Use global config -* `--config-dir ` +* `--config-dir ` — Location of config directory, default is "." * `-l`, `--long` — Get more info about the networks