Skip to content

Commit

Permalink
feat: update tx new commands to use Address type
Browse files Browse the repository at this point in the history
Add tests using
  • Loading branch information
willemneal committed Nov 29, 2024
1 parent faebd85 commit 10fb1da
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 50 deletions.
4 changes: 2 additions & 2 deletions FULL_HELP_DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1577,7 +1577,7 @@ Transfers the XLM balance of an account to another account and removes the sourc
* `--hd-path <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 "."
* `--account <ACCOUNT>` — Muxed Account to merge with, e.g. `GBX...`, 'MBX...'
* `--account <ACCOUNT>` — Muxed Account to merge with, e.g. `GBX...`, 'MBX...' or alias



Expand Down Expand Up @@ -1792,7 +1792,7 @@ Allows issuing account to configure authorization and trustline flags to an asse
* `--hd-path <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 "."
* `--trustor <TRUSTOR>` — Account to set trustline flags for
* `--trustor <TRUSTOR>` — Account to set trustline flags for, e.g. `GBX...`, or alias, or muxed account, `M123...``
* `--asset <ASSET>` — Asset to set trustline flags for
* `--set-authorize` — Signifies complete authorization allowing an account to transact freely with the asset to make and receive payments and place orders
* `--set-authorize-to-maintain-liabilities` — Denotes limited authorization that allows an account to maintain current orders but not to otherwise transact with the asset
Expand Down
92 changes: 92 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 @@ -74,6 +74,71 @@ async fn create_account() {
invoke_hello_world(sandbox, &id);
}

#[tokio::test]
async fn create_account_with_alias() {
let sandbox = &TestEnv::new();
sandbox
.new_assert_cmd("keys")
.args(["generate", "--no-fund", "new"])
.assert()
.success();
let test = test_address(sandbox);
let client = soroban_rpc::Client::new(&sandbox.rpc_url).unwrap();
let test_account = client.get_account(&test).await.unwrap();
println!("test account has a balance of {}", test_account.balance);
let starting_balance = ONE_XLM * 100;
sandbox
.new_assert_cmd("tx")
.args([
"new",
"create-account",
"--destination",
"new",
"--starting-balance",
starting_balance.to_string().as_str(),
])
.assert()
.success();
let test_account_after = client.get_account(&test).await.unwrap();
assert!(test_account_after.balance < test_account.balance);
let id = deploy_contract(sandbox, HELLO_WORLD, DeployKind::Normal, Some("new")).await;
println!("{id}");
invoke_hello_world(sandbox, &id);
}

#[tokio::test]
async fn payment_with_alias() {
let sandbox = &TestEnv::new();
let client = soroban_rpc::Client::new(&sandbox.rpc_url).unwrap();
let (test, test1) = setup_accounts(sandbox);
let test_account = client.get_account(&test).await.unwrap();
println!("test account has a balance of {}", test_account.balance);

let before = client.get_account(&test).await.unwrap();
let test1_account_entry_before = client.get_account(&test1).await.unwrap();

sandbox
.new_assert_cmd("tx")
.args([
"new",
"payment",
"--destination",
"test1",
"--amount",
ONE_XLM.to_string().as_str(),
])
.assert()
.success();
let test1_account_entry = client.get_account(&test1).await.unwrap();
assert_eq!(
ONE_XLM,
test1_account_entry.balance - test1_account_entry_before.balance,
"Should have One XLM more"
);
let after = client.get_account(&test).await.unwrap();
assert_eq!(before.balance - 10_000_100, after.balance);
}

#[tokio::test]
async fn payment() {
let sandbox = &TestEnv::new();
Expand Down Expand Up @@ -157,6 +222,33 @@ async fn account_merge() {
assert_eq!(before.balance + before1.balance - fee, after.balance);
}

#[tokio::test]
async fn account_merge_with_alias() {
let sandbox = &TestEnv::new();
let client = soroban_rpc::Client::new(&sandbox.rpc_url).unwrap();
let (test, test1) = setup_accounts(sandbox);
let before = client.get_account(&test).await.unwrap();
let before1 = client.get_account(&test1).await.unwrap();
let fee = 100;
sandbox
.new_assert_cmd("tx")
.args([
"new",
"account-merge",
"--source",
"test1",
"--account",
"test",
"--fee",
fee.to_string().as_str(),
])
.assert()
.success();
let after = client.get_account(&test).await.unwrap();
assert!(client.get_account(&test1).await.is_err());
assert_eq!(before.balance + before1.balance - fee, after.balance);
}

#[tokio::test]
async fn set_trustline_flags() {
let sandbox = &TestEnv::new();
Expand Down
20 changes: 18 additions & 2 deletions cmd/soroban-cli/src/commands/tx/args.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use crate::{
commands::{global, txn_result::TxnEnvelopeResult},
config::{self, data, network, secret},
config::{
self,
address::{self, Address},
data, network, secret,
},
fee,
rpc::{self, Client, GetTransactionResponse},
tx::builder::{self, TxExt},
Expand Down Expand Up @@ -32,6 +36,8 @@ pub enum Error {
Data(#[from] data::Error),
#[error(transparent)]
Xdr(#[from] xdr::Error),
#[error(transparent)]
Address(#[from] address::Error),
}

impl Args {
Expand Down Expand Up @@ -64,7 +70,7 @@ impl Args {
op: impl Into<xdr::OperationBody>,
global_args: &global::Args,
) -> Result<TxnEnvelopeResult<GetTransactionResponse>, Error> {
let tx = self.tx(op.into()).await?;
let tx = self.tx(op).await?;
self.handle_tx(tx, global_args).await
}
pub async fn handle_and_print(
Expand Down Expand Up @@ -104,4 +110,14 @@ impl Args {
pub fn source_account(&self) -> Result<xdr::MuxedAccount, Error> {
Ok(self.config.source_account()?)
}

pub fn reslove_muxed_address(&self, address: &Address) -> Result<xdr::MuxedAccount, Error> {
Ok(address.resolve_muxed_account(&self.config.locator, self.config.hd_path)?)
}

pub fn reslove_account_id(&self, address: &Address) -> Result<xdr::AccountId, Error> {
Ok(address
.resolve_muxed_account(&self.config.locator, self.config.hd_path)?
.account_id())
}
}
2 changes: 2 additions & 0 deletions cmd/soroban-cli/src/commands/tx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ pub enum Error {
Sign(#[from] sign::Error),
#[error(transparent)]
Send(#[from] send::Error),
#[error(transparent)]
Args(#[from] args::Error),
}

impl Cmd {
Expand Down
15 changes: 9 additions & 6 deletions cmd/soroban-cli/src/commands/tx/new/account_merge.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
use clap::{command, Parser};

use crate::{commands::tx, xdr};
use crate::{commands::tx, config::address, xdr};

#[derive(Parser, Debug, Clone)]
#[group(skip)]
pub struct Cmd {
#[command(flatten)]
pub tx: tx::Args,
/// Muxed Account to merge with, e.g. `GBX...`, 'MBX...'
/// Muxed Account to merge with, e.g. `GBX...`, 'MBX...' or alias
#[arg(long)]
pub account: xdr::MuxedAccount,
pub account: address::Address,
}

impl From<&Cmd> for xdr::OperationBody {
fn from(cmd: &Cmd) -> Self {
xdr::OperationBody::AccountMerge(cmd.account.clone())
impl TryFrom<&Cmd> for xdr::OperationBody {
type Error = tx::args::Error;
fn try_from(cmd: &Cmd) -> Result<Self, Self::Error> {
Ok(xdr::OperationBody::AccountMerge(
cmd.tx.reslove_muxed_address(&cmd.account)?,
))
}
}
17 changes: 9 additions & 8 deletions cmd/soroban-cli/src/commands/tx/new/create_account.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clap::{command, Parser};

use crate::{commands::tx, tx::builder, xdr};
use crate::{commands::tx, config::address, xdr};

#[derive(Parser, Debug, Clone)]
#[group(skip)]
Expand All @@ -9,17 +9,18 @@ pub struct Cmd {
pub tx: tx::Args,
/// Account Id to create, e.g. `GBX...`
#[arg(long)]
pub destination: xdr::AccountId,
pub destination: address::Address,
/// Initial balance in stroops of the account, default 1 XLM
#[arg(long, default_value = "10_000_000")]
pub starting_balance: builder::Amount,
}

impl From<&Cmd> for xdr::OperationBody {
fn from(cmd: &Cmd) -> Self {
xdr::OperationBody::CreateAccount(xdr::CreateAccountOp {
destination: cmd.destination.clone(),
starting_balance: cmd.starting_balance.into(),
})
impl TryFrom<&Cmd> for xdr::OperationBody {
type Error = tx::args::Error;
fn try_from(cmd: &Cmd) -> Result<Self, Self::Error> {
Ok(xdr::OperationBody::CreateAccount(xdr::CreateAccountOp {
destination: cmd.tx.reslove_account_id(&cmd.destination)?,
starting_balance: cmd.starting_balance,
}))
}
}
34 changes: 26 additions & 8 deletions cmd/soroban-cli/src/commands/tx/new/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use clap::Parser;
use soroban_sdk::xdr::OperationBody;

use super::global;

Expand Down Expand Up @@ -52,17 +53,34 @@ pub enum Error {
Tx(#[from] super::args::Error),
}

impl TryFrom<&Cmd> for OperationBody {
type Error = super::args::Error;
fn try_from(cmd: &Cmd) -> Result<Self, Self::Error> {
Ok(match cmd {
Cmd::AccountMerge(cmd) => cmd.try_into()?,
Cmd::BumpSequence(cmd) => cmd.into(),
Cmd::ChangeTrust(cmd) => cmd.into(),
Cmd::CreateAccount(cmd) => cmd.try_into()?,
Cmd::ManageData(cmd) => cmd.into(),
Cmd::Payment(cmd) => cmd.try_into()?,
Cmd::SetOptions(cmd) => cmd.try_into()?,
Cmd::SetTrustlineFlags(cmd) => cmd.try_into()?,
})
}
}

impl Cmd {
pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> {
let op = OperationBody::try_from(self)?;
match self {
Cmd::AccountMerge(cmd) => cmd.tx.handle_and_print(cmd, global_args).await,
Cmd::BumpSequence(cmd) => cmd.tx.handle_and_print(cmd, global_args).await,
Cmd::ChangeTrust(cmd) => cmd.tx.handle_and_print(cmd, global_args).await,
Cmd::CreateAccount(cmd) => cmd.tx.handle_and_print(cmd, global_args).await,
Cmd::ManageData(cmd) => cmd.tx.handle_and_print(cmd, global_args).await,
Cmd::Payment(cmd) => cmd.tx.handle_and_print(cmd, global_args).await,
Cmd::SetOptions(cmd) => cmd.tx.handle_and_print(cmd, global_args).await,
Cmd::SetTrustlineFlags(cmd) => cmd.tx.handle_and_print(cmd, global_args).await,
Cmd::AccountMerge(cmd) => cmd.tx.handle_and_print(op, global_args).await,
Cmd::BumpSequence(cmd) => cmd.tx.handle_and_print(op, global_args).await,
Cmd::ChangeTrust(cmd) => cmd.tx.handle_and_print(op, global_args).await,
Cmd::CreateAccount(cmd) => cmd.tx.handle_and_print(op, global_args).await,
Cmd::ManageData(cmd) => cmd.tx.handle_and_print(op, global_args).await,
Cmd::Payment(cmd) => cmd.tx.handle_and_print(op, global_args).await,
Cmd::SetOptions(cmd) => cmd.tx.handle_and_print(op, global_args).await,
Cmd::SetTrustlineFlags(cmd) => cmd.tx.handle_and_print(op, global_args).await,
}?;
Ok(())
}
Expand Down
13 changes: 7 additions & 6 deletions cmd/soroban-cli/src/commands/tx/new/payment.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clap::{command, Parser};

use crate::{commands::tx, tx::builder, xdr};
use crate::{commands::tx, config::address, tx::builder, xdr};

#[derive(Parser, Debug, Clone)]
#[group(skip)]
Expand All @@ -9,7 +9,7 @@ pub struct Cmd {
pub tx: tx::Args,
/// Account to send to, e.g. `GBX...`
#[arg(long)]
pub destination: xdr::MuxedAccount,
pub destination: address::Address,
/// Asset to send, default native, e.i. XLM
#[arg(long, default_value = "native")]
pub asset: builder::Asset,
Expand All @@ -18,10 +18,11 @@ pub struct Cmd {
pub amount: builder::Amount,
}

impl From<&Cmd> for xdr::OperationBody {
fn from(cmd: &Cmd) -> Self {
xdr::OperationBody::Payment(xdr::PaymentOp {
destination: cmd.destination.clone(),
impl TryFrom<&Cmd> for xdr::OperationBody {
type Error = tx::args::Error;
fn try_from(cmd: &Cmd) -> Result<Self, Self::Error> {
Ok(xdr::OperationBody::Payment(xdr::PaymentOp {
destination: cmd.tx.reslove_muxed_address(&cmd.destination)?,
asset: cmd.asset.clone().into(),
amount: cmd.amount.into(),
})
Expand Down
20 changes: 13 additions & 7 deletions cmd/soroban-cli/src/commands/tx/new/set_options.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clap::{command, Parser};

use crate::{commands::tx, xdr};
use crate::{commands::tx, config::address, xdr};

#[derive(Parser, Debug, Clone)]
#[allow(clippy::struct_excessive_bools, clippy::doc_markdown)]
Expand All @@ -10,7 +10,7 @@ pub struct Cmd {
pub tx: tx::Args,
#[arg(long)]
/// Account of the inflation destination.
pub inflation_dest: Option<xdr::AccountId>,
pub inflation_dest: Option<address::Address>,
#[arg(long)]
/// A number from 0-255 (inclusive) representing the weight of the master key. If the weight of the master key is updated to 0, it is effectively disabled.
pub master_weight: Option<u8>,
Expand Down Expand Up @@ -61,8 +61,9 @@ pub struct Cmd {
pub clear_clawback_enabled: bool,
}

impl From<&Cmd> for xdr::OperationBody {
fn from(cmd: &Cmd) -> Self {
impl TryFrom<&Cmd> for xdr::OperationBody {
type Error = tx::args::Error;
fn try_from(cmd: &Cmd) -> Result<Self, Self::Error> {
let mut set_flags = None;
let mut set_flag = |flag: xdr::AccountFlags| {
*set_flags.get_or_insert(0) |= flag as u32;
Expand Down Expand Up @@ -108,8 +109,13 @@ impl From<&Cmd> for xdr::OperationBody {
} else {
None
};
xdr::OperationBody::SetOptions(xdr::SetOptionsOp {
inflation_dest: cmd.inflation_dest.clone().map(Into::into),
let inflation_dest: Option<xdr::AccountId> = cmd
.inflation_dest
.as_ref()
.map(|dest| cmd.tx.reslove_account_id(dest))
.transpose()?;
Ok(xdr::OperationBody::SetOptions(xdr::SetOptionsOp {
inflation_dest,
clear_flags,
set_flags,
master_weight: cmd.master_weight.map(Into::into),
Expand All @@ -118,6 +124,6 @@ impl From<&Cmd> for xdr::OperationBody {
high_threshold: cmd.high_threshold.map(Into::into),
home_domain: cmd.home_domain.clone().map(Into::into),
signer,
})
}))
}
}
Loading

0 comments on commit 10fb1da

Please sign in to comment.