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

Merged
merged 26 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
060076a
feat: add `tx add-op`
willemneal Oct 8, 2024
547c0f5
Update cmd/soroban-cli/src/commands/tx/xdr.rs
willemneal Oct 9, 2024
152a4ea
Merge remote-tracking branch 'origin/main' into feat/tx_add_op
willemneal Oct 9, 2024
8487dca
fix: apply suggestions including `tx add-op` to `tx op add`
willemneal Oct 9, 2024
bbbc417
Merge remote-tracking branch 'origin/main' into feat/tx_add_op
willemneal Oct 10, 2024
114f6cb
Merge remote-tracking branch 'origin/main' into feat/tx_add_op
willemneal Oct 21, 2024
cd367cf
Merge branch 'main' into feat/tx_add_op
willemneal Oct 28, 2024
33cd44f
fix: tests
willemneal Oct 28, 2024
0e47dd6
Merge remote-tracking branch 'origin/main' into feat/tx_add_op
willemneal Oct 28, 2024
079f652
Merge remote-tracking branch 'origin/main' into feat/tx_add_op
willemneal Oct 31, 2024
8655551
fix: test
willemneal Oct 31, 2024
8961a42
Merge branch 'main' into feat/tx_add_op
janewang Nov 5, 2024
d573daf
Merge branch 'main' into feat/tx_add_op
leighmcculloch Nov 6, 2024
93f25a3
Merge branch 'main' into feat/tx_add_op
willemneal Nov 11, 2024
ff613e4
Merge branch 'main' into feat/tx_add_op
willemneal Nov 12, 2024
de39614
fix: clippy
willemneal Nov 12, 2024
2a25835
Merge branch 'main' into feat/tx_add_op
willemneal Nov 12, 2024
e39f2b8
Merge branch 'main' into feat/tx_add_op
willemneal Nov 14, 2024
6813ab4
Merge branch 'main' into feat/tx_add_op
willemneal Nov 15, 2024
92c22a2
Merge `main` into `feat/tx_add_op`
willemneal Nov 16, 2024
fc767d6
Merge branch 'main' into feat/tx_add_op
leighmcculloch Nov 25, 2024
7a27cef
fix: clippy and docs
willemneal Nov 25, 2024
0f41acd
Merge branch 'main' into feat/tx_add_op
willemneal Nov 26, 2024
fe4f6a1
Merge branch 'main' into feat/tx_add_op
willemneal Dec 3, 2024
b6fd9d5
fix: docs
willemneal Dec 3, 2024
2ec4daf
Merge branch 'main' into feat/tx_add_op
leighmcculloch Dec 4, 2024
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
247 changes: 238 additions & 9 deletions FULL_HELP_DOCS.md

Large diffs are not rendered by default.

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 @@ -2,6 +2,7 @@ use soroban_cli::{
tx::{builder, ONE_XLM},
utils::contract_id_hash_from_asset,
};
use soroban_rpc::LedgerEntryResult;
use soroban_sdk::xdr::{self, ReadXdr, SequenceNumber};
use soroban_test::{AssertExt, TestEnv};

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(["add-op", "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
14 changes: 14 additions & 0 deletions cmd/soroban-cli/src/commands/tx/add_op/account_merge.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use clap::{command, Parser};

use std::fmt::Debug;

use super::super::new;

#[derive(Parser, Debug, Clone)]
#[group(skip)]
pub struct Cmd {
#[command(flatten)]
pub args: super::args::Args,
#[command(flatten)]
pub op: new::account_merge::Args,
}
46 changes: 46 additions & 0 deletions cmd/soroban-cli/src/commands/tx/add_op/args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use super::super::xdr::add_op;
use crate::{
config::{address, locator},
xdr,
};

#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Address(#[from] address::Error),
#[error(transparent)]
TxXdr(#[from] super::super::xdr::Error),
}

#[derive(Debug, clap::Args, Clone)]
#[group(skip)]
pub struct Args {
#[clap(flatten)]
pub locator: locator::Args,
/// Source account used for the operation
#[arg(
long,
visible_alias = "op-source",
env = "STELLAR_OPERATION_SOURCE_ACCOUNT"
)]
pub operation_source_account: Option<address::Address>,
willemneal marked this conversation as resolved.
Show resolved Hide resolved
}

impl Args {
pub fn add_op(
&self,
op_body: impl Into<xdr::OperationBody>,
tx_env: xdr::TransactionEnvelope,
) -> Result<xdr::TransactionEnvelope, Error> {
let source_account = self
.operation_source_account
.as_ref()
.map(|a| a.resolve_muxed_account(&self.locator, None))
.transpose()?;
let op = xdr::Operation {
source_account,
body: op_body.into(),
};
Ok(add_op(tx_env, op)?)
}
}
14 changes: 14 additions & 0 deletions cmd/soroban-cli/src/commands/tx/add_op/bump_sequence.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use clap::{command, Parser};

use std::fmt::Debug;

use super::super::new;

#[derive(Parser, Debug, Clone)]
#[group(skip)]
pub struct Cmd {
#[command(flatten)]
pub args: super::args::Args,
#[command(flatten)]
pub op: new::bump_sequence::Args,
}
14 changes: 14 additions & 0 deletions cmd/soroban-cli/src/commands/tx/add_op/change_trust.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use clap::{command, Parser};

use std::fmt::Debug;

use super::super::new;

#[derive(Parser, Debug, Clone)]
#[group(skip)]
pub struct Cmd {
#[command(flatten)]
pub args: super::args::Args,
#[command(flatten)]
pub op: new::change_trust::Args,
}
14 changes: 14 additions & 0 deletions cmd/soroban-cli/src/commands/tx/add_op/create_account.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use clap::{command, Parser};

use std::fmt::Debug;

use super::super::new;

#[derive(Parser, Debug, Clone)]
#[group(skip)]
pub struct Cmd {
#[command(flatten)]
pub args: super::args::Args,
#[command(flatten)]
pub op: new::create_account::Args,
}
14 changes: 14 additions & 0 deletions cmd/soroban-cli/src/commands/tx/add_op/manage_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use clap::{command, Parser};

use std::fmt::Debug;

use super::super::new;

#[derive(Parser, Debug, Clone)]
#[group(skip)]
pub struct Cmd {
#[command(flatten)]
pub args: super::args::Args,
#[command(flatten)]
pub op: new::manage_data::Args,
}
63 changes: 63 additions & 0 deletions cmd/soroban-cli/src/commands/tx/add_op/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use clap::Parser;

use super::{global, xdr::tx_envelope_from_stdin};
use crate::xdr::WriteXdr;

mod account_merge;
mod args;
mod bump_sequence;
mod change_trust;
mod create_account;
mod manage_data;
mod payment;
mod set_options;
mod set_trustline_flags;

#[derive(Debug, Parser)]
#[allow(clippy::doc_markdown)]
pub enum Cmd {
#[command(about = super::help::ACCOUNT_MERGE)]
AccountMerge(account_merge::Cmd),
#[command(about = super::help::BUMP_SEQUENCE)]
BumpSequence(bump_sequence::Cmd),
#[command(about = super::help::CHANGE_TRUST)]
ChangeTrust(change_trust::Cmd),
#[command(about = super::help::CREATE_ACCOUNT)]
CreateAccount(create_account::Cmd),
#[command(about = super::help::MANAGE_DATA)]
ManageData(manage_data::Cmd),
#[command(about = super::help::PAYMENT)]
Payment(payment::Cmd),
#[command(about = super::help::SET_OPTIONS)]
SetOptions(set_options::Cmd),
#[command(about = super::help::SET_TRUSTLINE_FLAGS)]
SetTrustlineFlags(set_trustline_flags::Cmd),
}

#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Args(#[from] args::Error),
#[error(transparent)]
TxXdr(#[from] super::xdr::Error),
#[error(transparent)]
Xdr(#[from] crate::xdr::Error),
}

impl Cmd {
pub fn run(&self, _: &global::Args) -> Result<(), Error> {
let tx_env = tx_envelope_from_stdin()?;
let res = match self {
Cmd::AccountMerge(cmd) => cmd.args.add_op(&cmd.op, tx_env),
Cmd::BumpSequence(cmd) => cmd.args.add_op(&cmd.op, tx_env),
Cmd::ChangeTrust(cmd) => cmd.args.add_op(&cmd.op, tx_env),
Cmd::CreateAccount(cmd) => cmd.args.add_op(&cmd.op, tx_env),
Cmd::ManageData(cmd) => cmd.args.add_op(&cmd.op, tx_env),
Cmd::Payment(cmd) => cmd.args.add_op(&cmd.op, tx_env),
Cmd::SetOptions(cmd) => cmd.args.add_op(&cmd.op, tx_env),
Cmd::SetTrustlineFlags(cmd) => cmd.args.add_op(&cmd.op, tx_env),
}?;
println!("{}", res.to_xdr_base64(crate::xdr::Limits::none())?);
Ok(())
}
}
14 changes: 14 additions & 0 deletions cmd/soroban-cli/src/commands/tx/add_op/payment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use clap::{command, Parser};

use std::fmt::Debug;

use super::super::new;

#[derive(Parser, Debug, Clone)]
#[group(skip)]
pub struct Cmd {
#[command(flatten)]
pub args: super::args::Args,
#[command(flatten)]
pub op: new::payment::Args,
}
14 changes: 14 additions & 0 deletions cmd/soroban-cli/src/commands/tx/add_op/set_options.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use clap::{command, Parser};

use std::fmt::Debug;

use super::super::new;

#[derive(Parser, Debug, Clone)]
#[group(skip)]
pub struct Cmd {
#[command(flatten)]
pub args: super::args::Args,
#[command(flatten)]
pub op: new::set_options::Args,
}
14 changes: 14 additions & 0 deletions cmd/soroban-cli/src/commands/tx/add_op/set_trustline_flags.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use clap::{command, Parser};

use std::fmt::Debug;

use super::super::new;

#[derive(Parser, Debug, Clone)]
#[group(skip)]
pub struct Cmd {
#[command(flatten)]
pub args: super::args::Args,
#[command(flatten)]
pub op: new::set_trustline_flags::Args,
}
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";
Loading
Loading