Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add tx op add #1663

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
375 changes: 308 additions & 67 deletions FULL_HELP_DOCS.md

Large diffs are not rendered by default.

9 changes: 4 additions & 5 deletions cmd/crates/soroban-test/tests/it/integration/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ use soroban_test::AssertExt;
use soroban_test::TestEnv;

fn pubkey_for_identity(sandbox: &TestEnv, name: &str) -> String {
let output = sandbox
sandbox
.new_assert_cmd("keys")
.arg("address")
.arg(name)
.assert()
.stdout_as_str();
return output;
.stdout_as_str()
}

#[tokio::test]
Expand Down Expand Up @@ -61,7 +60,7 @@ async fn overwrite_identity() {
"error: An identity with the name 'test2' already exists",
));

assert_eq!(initial_pubkey, pubkey_for_identity(&sandbox, "test2"));
assert_eq!(initial_pubkey, pubkey_for_identity(sandbox, "test2"));

sandbox
.new_assert_cmd("keys")
Expand All @@ -72,5 +71,5 @@ async fn overwrite_identity() {
.stderr(predicate::str::contains("Overwriting identity 'test2'"))
.success();

assert_ne!(initial_pubkey, pubkey_for_identity(&sandbox, "test2"));
assert_ne!(initial_pubkey, pubkey_for_identity(sandbox, "test2"));
}
98 changes: 98 additions & 0 deletions cmd/crates/soroban-test/tests/it/integration/tx/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use soroban_cli::{
utils::contract_id_hash_from_asset,
xdr::{self, ReadXdr, SequenceNumber},
};
use soroban_rpc::LedgerEntryResult;
use soroban_test::{AssertExt, TestEnv};

use crate::integration::{
Expand Down Expand Up @@ -30,6 +31,20 @@ fn new_account(sandbox: &TestEnv, name: &str) -> String {
.stdout_as_str()
}

fn gen_account_no_fund(sandbox: &TestEnv, name: &str) -> String {
sandbox
.new_assert_cmd("keys")
.args(["generate", "--no-fund", name])
.assert()
.success();
sandbox
.new_assert_cmd("keys")
.args(["address", name])
.assert()
.success()
.stdout_as_str()
}

// returns test and test1 addresses
fn setup_accounts(sandbox: &TestEnv) -> (String, String) {
(test_address(sandbox), new_account(sandbox, "test1"))
Expand Down Expand Up @@ -614,3 +629,86 @@ async fn issue_asset(sandbox: &TestEnv, test: &str, asset: &str, limit: u64, ini
.assert()
.success();
}

#[tokio::test]
async fn multi_create_accounts() {
let sandbox = &TestEnv::new();
let client = soroban_rpc::Client::new(&sandbox.rpc_url).unwrap();
let nums: Vec<u8> = (1..=3).collect();
let mut accounts: Vec<(String, String)> = nums
.iter()
.map(|x| {
let name = format!("test_{x}");
let address = gen_account_no_fund(sandbox, &name);
(name, address)
})
.collect();
let (_, test_99_address) = accounts.pop().unwrap();

let input = sandbox
.new_assert_cmd("tx")
.args([
"new",
"create-account",
"--fee=1000000",
"--build-only",
"--destination",
&test_99_address,
])
.assert()
.success()
.stdout_as_str();

let final_tx = accounts.iter().fold(input, |tx_env, (_, address)| {
sandbox
.new_assert_cmd("tx")
.args(["op", "add", "create-account", "--destination", address])
.write_stdin(tx_env.as_bytes())
.assert()
.success()
.stdout_as_str()
});
let out = sandbox
.new_assert_cmd("tx")
.arg("send")
.write_stdin(
sandbox
.new_assert_cmd("tx")
.arg("sign")
.arg("--sign-with-key=test")
.write_stdin(final_tx.as_bytes())
.assert()
.success()
.stdout_as_str()
.as_bytes(),
)
.assert()
.success()
.stdout_as_str();
println!("{out}");
let keys = accounts
.iter()
.map(|(_, address)| {
xdr::LedgerKey::Account(xdr::LedgerKeyAccount {
account_id: address.parse().unwrap(),
})
})
.collect::<Vec<_>>();

let account = client.get_account(&test_99_address).await.unwrap();
println!("{account:#?}");
let entries = client.get_ledger_entries(&keys).await.unwrap();
println!("{entries:#?}");
entries
.entries
.unwrap()
.iter()
.for_each(|LedgerEntryResult { xdr, .. }| {
let xdr::LedgerEntryData::Account(value) =
xdr::LedgerEntryData::from_xdr_base64(xdr, xdr::Limits::none()).unwrap()
else {
panic!("Expected Account");
};
assert_eq!(value.balance, 10_000_000);
});
}
2 changes: 1 addition & 1 deletion cmd/crates/soroban-test/tests/it/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ mod build;
mod config;
mod help;
mod init;
#[cfg(feature = "it")]
// #[cfg(feature = "it")]
mod integration;
mod plugin;
mod util;
Expand Down
24 changes: 24 additions & 0 deletions cmd/soroban-cli/src/commands/tx/help.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
pub const ACCOUNT_MERGE:&str = "Transfers the XLM balance of an account to another account and removes the source account from the ledger";
pub const BUMP_SEQUENCE: &str = "Bumps forward the sequence number of the source account to the given sequence number, invalidating any transaction with a smaller sequence number";
pub const CHANGE_TRUST: &str = r"Creates, updates, or deletes a trustline
Learn more about trustlines
https://developers.stellar.org/docs/learn/fundamentals/stellar-data-structures/accounts#trustlines";

pub const CREATE_ACCOUNT: &str =
"Creates and funds a new account with the specified starting balance";
pub const MANAGE_DATA: &str = r"Sets, modifies, or deletes a data entry (name/value pair) that is attached to an account
Learn more about entries and subentries:
https://developers.stellar.org/docs/learn/fundamentals/stellar-data-structures/accounts#subentries";
pub const PAYMENT: &str = "Sends an amount in a specific asset to a destination account";
pub const SET_OPTIONS: &str = r"Set option for an account such as flags, inflation destination, signers, home domain, and master key weight
Learn more about flags:
https://developers.stellar.org/docs/learn/glossary#flags
Learn more about the home domain:
https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md
Learn more about signers operations and key weight:
https://developers.stellar.org/docs/learn/encyclopedia/security/signatures-multisig#multisig";
pub const SET_TRUSTLINE_FLAGS: &str = r"Allows issuing account to configure authorization and trustline flags to an asset
The Asset parameter is of the `TrustLineAsset` type. If you are modifying a trustline to a regular asset (i.e. one in a Code:Issuer format), this is equivalent to the Asset type.
If you are modifying a trustline to a pool share, however, this is composed of the liquidity pool's unique ID.
Learn more about flags:
https://developers.stellar.org/docs/learn/glossary#flags";
28 changes: 18 additions & 10 deletions cmd/soroban-cli/src/commands/tx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use super::global;

pub mod args;
pub mod hash;
pub mod help;
pub mod new;
pub mod op;
pub mod send;
pub mod sign;
pub mod simulate;
Expand All @@ -12,17 +14,20 @@ pub use args::Args;

#[derive(Debug, clap::Subcommand)]
pub enum Cmd {
/// Simulate a transaction envelope from stdin
Simulate(simulate::Cmd),
/// Calculate the hash of a transaction envelope from stdin
Hash(hash::Cmd),
/// Sign a transaction envelope appending the signature to the envelope
Sign(sign::Cmd),
/// Send a transaction envelope to the network
Send(send::Cmd),
/// Create a new transaction
#[command(subcommand)]
New(new::Cmd),
/// Manipulate the operations in a transaction, including adding new operations
#[command(subcommand, visible_alias = "op")]
Operation(op::Cmd),
/// Send a transaction envelope to the network
Send(send::Cmd),
/// Sign a transaction envelope appending the signature to the envelope
Sign(sign::Cmd),
/// Simulate a transaction envelope from stdin
Simulate(simulate::Cmd),
}

#[derive(thiserror::Error, Debug)]
Expand All @@ -32,21 +37,24 @@ pub enum Error {
#[error(transparent)]
New(#[from] new::Error),
#[error(transparent)]
Simulate(#[from] simulate::Error),
Op(#[from] op::Error),
#[error(transparent)]
Send(#[from] send::Error),
#[error(transparent)]
Sign(#[from] sign::Error),
#[error(transparent)]
Send(#[from] send::Error),
Simulate(#[from] simulate::Error),
}

impl Cmd {
pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> {
match self {
Cmd::Simulate(cmd) => cmd.run(global_args).await?,
Cmd::Hash(cmd) => cmd.run(global_args)?,
Cmd::New(cmd) => cmd.run(global_args).await?,
Cmd::Sign(cmd) => cmd.run(global_args).await?,
Cmd::Operation(cmd) => cmd.run(global_args)?,
Cmd::Send(cmd) => cmd.run(global_args).await?,
Cmd::Sign(cmd) => cmd.run(global_args).await?,
Cmd::Simulate(cmd) => cmd.run(global_args).await?,
};
Ok(())
}
Expand Down
10 changes: 8 additions & 2 deletions cmd/soroban-cli/src/commands/tx/new/account_merge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ use crate::{commands::tx, xdr};
pub struct Cmd {
#[command(flatten)]
pub tx: tx::Args,
#[clap(flatten)]
pub op: Args,
}

#[derive(Debug, clap::Args, Clone)]
pub struct Args {
/// Muxed Account to merge with, e.g. `GBX...`, 'MBX...'
#[arg(long)]
pub account: xdr::MuxedAccount,
}

impl From<&Cmd> for xdr::OperationBody {
fn from(cmd: &Cmd) -> Self {
impl From<&Args> for xdr::OperationBody {
fn from(cmd: &Args) -> Self {
xdr::OperationBody::AccountMerge(cmd.account.clone())
}
}
10 changes: 8 additions & 2 deletions cmd/soroban-cli/src/commands/tx/new/bump_sequence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ use crate::{commands::tx, xdr};
pub struct Cmd {
#[command(flatten)]
pub tx: tx::Args,
#[clap(flatten)]
pub op: Args,
}

#[derive(Debug, clap::Args, Clone)]
pub struct Args {
/// Sequence number to bump to
#[arg(long)]
pub bump_to: i64,
}

impl From<&Cmd> for xdr::OperationBody {
fn from(cmd: &Cmd) -> Self {
impl From<&Args> for xdr::OperationBody {
fn from(cmd: &Args) -> Self {
xdr::OperationBody::BumpSequence(xdr::BumpSequenceOp {
bump_to: cmd.bump_to.into(),
})
Expand Down
10 changes: 8 additions & 2 deletions cmd/soroban-cli/src/commands/tx/new/change_trust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,21 @@ use crate::{commands::tx, tx::builder, xdr};
pub struct Cmd {
#[command(flatten)]
pub tx: tx::Args,
#[clap(flatten)]
pub op: Args,
}

#[derive(Debug, clap::Args, Clone)]
pub struct Args {
#[arg(long)]
pub line: builder::Asset,
/// Limit for the trust line, 0 to remove the trust line
#[arg(long, default_value = u64::MAX.to_string())]
pub limit: i64,
}

impl From<&Cmd> for xdr::OperationBody {
fn from(cmd: &Cmd) -> Self {
impl From<&Args> for xdr::OperationBody {
fn from(cmd: &Args) -> Self {
let line = match cmd.line.0.clone() {
xdr::Asset::CreditAlphanum4(asset) => xdr::ChangeTrustAsset::CreditAlphanum4(asset),
xdr::Asset::CreditAlphanum12(asset) => xdr::ChangeTrustAsset::CreditAlphanum12(asset),
Expand Down
12 changes: 9 additions & 3 deletions cmd/soroban-cli/src/commands/tx/new/create_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@ use crate::{commands::tx, xdr};
pub struct Cmd {
#[command(flatten)]
pub tx: tx::Args,
#[clap(flatten)]
pub op: Args,
}

#[derive(Debug, clap::Args, Clone)]
pub struct Args {
/// Account Id to create, e.g. `GBX...`
#[arg(long)]
#[arg(long, alias = "dest")]
pub destination: xdr::AccountId,
/// Initial balance in stroops of the account, default 1 XLM
#[arg(long, default_value = "10000000")]
pub starting_balance: i64,
}

impl From<&Cmd> for xdr::OperationBody {
fn from(cmd: &Cmd) -> Self {
impl From<&Args> for xdr::OperationBody {
fn from(cmd: &Args) -> Self {
xdr::OperationBody::CreateAccount(xdr::CreateAccountOp {
destination: cmd.destination.clone(),
starting_balance: cmd.starting_balance,
Expand Down
10 changes: 8 additions & 2 deletions cmd/soroban-cli/src/commands/tx/new/manage_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ use crate::{commands::tx, xdr};
pub struct Cmd {
#[command(flatten)]
pub tx: tx::Args,
#[clap(flatten)]
pub op: Args,
}

#[derive(Debug, clap::Args, Clone)]
pub struct Args {
/// Line to change, either 4 or 12 alphanumeric characters, or "native" if not specified
#[arg(long)]
pub data_name: xdr::StringM<64>,
Expand All @@ -17,8 +23,8 @@ pub struct Cmd {
pub data_value: Option<xdr::BytesM<64>>,
}

impl From<&Cmd> for xdr::OperationBody {
fn from(cmd: &Cmd) -> Self {
impl From<&Args> for xdr::OperationBody {
fn from(cmd: &Args) -> Self {
let data_value = cmd.data_value.clone().map(Into::into);
let data_name = cmd.data_name.clone().into();
xdr::OperationBody::ManageData(xdr::ManageDataOp {
Expand Down
Loading
Loading