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: improve asset parsing to use named keys as issuer #1762

Open
wants to merge 84 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
d33a9fc
feat: Add new `Key` type; allowing public keys to be named keys
willemneal Nov 5, 2024
2aec046
fix: lookup first before parsing raw key
willemneal Nov 12, 2024
52bd5e8
fix: docs
willemneal Nov 14, 2024
8f96343
fix: clippy
willemneal Nov 14, 2024
0cc57fe
feat: update tx new commands to use Address type
willemneal Nov 26, 2024
31cde54
fix: rebase issue
willemneal Nov 29, 2024
e5f0e5d
Merge branch 'main' into feat/muxed_keys
willemneal Nov 30, 2024
a86a98f
Update cmd/soroban-cli/src/config/key.rs
willemneal Dec 2, 2024
a64aae5
Merge branch 'main' into feat/muxed_keys
willemneal Dec 2, 2024
b36db49
fix: PR review
willemneal Dec 2, 2024
8c06970
feat: initial work into system keychain
willemneal Nov 5, 2024
883cb8c
chore: clean up
willemneal Nov 5, 2024
eb70734
Add KeyName struct in address
elizabethengelman Dec 2, 2024
d4e2500
Add Secret::Keychain
elizabethengelman Nov 14, 2024
3ee20b8
keys generate: allow for generating keys that are stored in keychain
elizabethengelman Nov 18, 2024
1a24c00
keys generate: Namespace keychain entry to identity name
elizabethengelman Nov 18, 2024
4a0c900
keys generate: don't allow 'keychain:' as a key name
elizabethengelman Nov 20, 2024
755c318
keys address: use keychain entry in secret to get the pub key
elizabethengelman Nov 20, 2024
dd07bf7
tx sign: allow a keychain identity sign a tx
elizabethengelman Nov 21, 2024
f042d19
Cleanup
elizabethengelman Nov 21, 2024
9cf5916
Use keyring mock for generate tests
elizabethengelman Nov 22, 2024
cd515d3
Refactor keyring: add keyring entry as StellarEntry field
elizabethengelman Nov 25, 2024
276558d
Add tests for keyring
elizabethengelman Nov 25, 2024
20c651b
Update config/secret tests
elizabethengelman Nov 25, 2024
66d1bfc
Cleanup
elizabethengelman Nov 25, 2024
8b9763e
Rename keychain arg to secure_store in generate
elizabethengelman Nov 25, 2024
fdefa2a
Rename Secret::Keychain to Secret::SecureStore
elizabethengelman Nov 25, 2024
36559ea
Rename SignerKind::Keychain to SignerKind::SecureStore
elizabethengelman Nov 25, 2024
f98b709
Use print for new fns in generate
elizabethengelman Dec 2, 2024
0f3106b
Return error when trying to get Secure Store secret
elizabethengelman Dec 2, 2024
e120595
Cleanup tests
elizabethengelman Dec 2, 2024
c4d6f99
Merge branch 'main' into feat/os_keychain
elizabethengelman Dec 2, 2024
c7e2cbc
Merge branch 'main' into feat/os_keychain
elizabethengelman Dec 3, 2024
57ba3a4
Install libdbus for rpc-tests and bindings-ts workflows
elizabethengelman Dec 3, 2024
0814e4b
Update generated docs
elizabethengelman Dec 3, 2024
74fa05b
Install libdbus for binaries workflow when target aarch64-unknown-lin…
elizabethengelman Dec 3, 2024
7ff1f6a
Clippy
elizabethengelman Dec 3, 2024
f263d8d
Install libdbus for rust workflow
elizabethengelman Dec 3, 2024
e2b7342
Install libdbus-1-dev in binaries workflow for build step
elizabethengelman Dec 3, 2024
f952c10
Merge branch 'main' into feat/muxed_keys
willemneal Dec 3, 2024
dabbb27
Impl Display for KeyName
elizabethengelman Dec 3, 2024
d9131b4
Use resolve_muxed_account in resolve_secret
elizabethengelman Dec 3, 2024
3ad6b9b
Use resolve_muxed_account to get public key
elizabethengelman Dec 3, 2024
9d02b01
Clippy
elizabethengelman Dec 3, 2024
4bddd24
Merge branch 'main' into feat/os_keychain
elizabethengelman Dec 3, 2024
a72276d
fix: Sign tx hash instead of tx env with keychain
elizabethengelman Dec 4, 2024
ed81494
Merge branch 'main' into feat/muxed_keys
willemneal Dec 5, 2024
9226b1b
fix: fmt
willemneal Dec 5, 2024
3a25564
fix: update to work with `op add`
willemneal Dec 5, 2024
5f55e7c
fix: simplify op::add::args::Args
willemneal Dec 5, 2024
0e7f08f
fix: remove untagged and use rename to keep same serialized output
willemneal Dec 5, 2024
aa8bb16
fix: docs and clippy in tests
willemneal Dec 5, 2024
65284cc
Merge branch 'main' into feat/os_keychain
elizabethengelman Dec 5, 2024
e9f86e7
Merge branch 'main' into feat/os_keychain
elizabethengelman Dec 9, 2024
4288630
Remove unused bin/secret
elizabethengelman Dec 9, 2024
6661b42
Merge branch 'main' into feat/os_keychain
elizabethengelman Dec 12, 2024
b2120d2
Merge branch 'main' into feat/os_keychain
elizabethengelman Dec 13, 2024
64cd37b
Apply suggestions from code review
willemneal Dec 13, 2024
732e7f4
Merge branch 'main' into feat/muxed_keys
willemneal Dec 13, 2024
d4ba93d
Update cmd/soroban-cli/src/config/locator.rs
willemneal Dec 13, 2024
318f579
fix: refactor with renames from PR
willemneal Dec 13, 2024
60c9d49
Merge branch 'main' into feat/muxed_keys
willemneal Dec 16, 2024
24e7b59
Merge branch 'main' into feat/os_keychain
elizabethengelman Dec 17, 2024
cfdb324
Merge branch 'main' into feat/os_keychain
elizabethengelman Dec 18, 2024
8e158a1
Merge branch 'main' into feat/os_keychain
willemneal Dec 19, 2024
d776f2d
Merge remote-tracking branch 'origin/main' into feat/muxed_keys
willemneal Dec 20, 2024
06932dc
Merge remote-tracking branch 'origin/main' into feat/muxed_keys
willemneal Dec 20, 2024
2241352
Merge remote-tracking branch 'origin/main' into feat/os_keychain
willemneal Dec 20, 2024
03b84e8
Merge remote-tracking branch 'origin/main' into feat/os_keychain
elizabethengelman Dec 20, 2024
24269ce
Fix after merging with main
elizabethengelman Dec 20, 2024
e95fa3a
Apply suggestion from code review
elizabethengelman Dec 20, 2024
95d8b32
Limit key name length
elizabethengelman Dec 23, 2024
01c8753
Update public_key to work with secure storage keys
elizabethengelman Dec 23, 2024
6404da6
Merge remote-tracking branch 'origin/main' into feat/os_keychain
willemneal Jan 6, 2025
085317f
fix(address): remove private key function & use unresolved Address
willemneal Jan 6, 2025
aecc5ac
feat: store seedphrase instead of private key
willemneal Jan 7, 2025
63f247e
fix: clean up
willemneal Jan 7, 2025
73eead7
Merge branch 'feat/os_keychain' into feat/muxed_keys
willemneal Jan 7, 2025
c305d9d
Merge branch 'main' into feat/muxed_keys
elizabethengelman Jan 9, 2025
ed797e0
fix: wait to lookup muxed account
willemneal Jan 9, 2025
70240b2
Merge branch 'main' into feat/muxed_keys
willemneal Jan 9, 2025
5391d3d
Merge remote-tracking branch 'origin/main' into feat/muxed_keys
willemneal Jan 14, 2025
dc66e45
feat: improve asset parsing to use named keys as issuer
willemneal Nov 29, 2024
4dd01eb
fix: add test and fix others
willemneal Nov 29, 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
1,721 changes: 960 additions & 761 deletions Cargo.lock

Large diffs are not rendered by default.

141 changes: 123 additions & 18 deletions FULL_HELP_DOCS.md

Large diffs are not rendered by default.

117 changes: 109 additions & 8 deletions cmd/crates/soroban-test/tests/it/integration/tx/operations.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use soroban_cli::{
config::locator,
tx::{builder, ONE_XLM},
utils::contract_id_hash_from_asset,
xdr::{self, ReadXdr, SequenceNumber},
Expand Down Expand Up @@ -89,6 +90,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 = sandbox.client();
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 = sandbox.client();
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 @@ -172,23 +238,54 @@ 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 = sandbox.client();
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();
let (test, issuer) = setup_accounts(sandbox);
let asset = format!("usdc:{issuer}");
issue_asset(sandbox, &test, &asset, 100_000, 100).await;
let (test, test1) = setup_accounts(sandbox);
let asset = "usdc:test1";
issue_asset(sandbox, &test, asset, 100_000, 100).await;
sandbox
.new_assert_cmd("contract")
.arg("asset")
.arg("deploy")
.arg("--asset")
.arg(&asset)
.arg(asset)
.assert()
.success();
let id = contract_id_hash_from_asset(
asset.parse::<builder::Asset>().unwrap(),
&sandbox.network.network_passphrase,
&format!("usdc:{test1}")
.parse::<builder::Asset>()
.unwrap()
.resolve(&locator::Args::default())
.unwrap(),
&sandbox.network_passphrase,
);
// sandbox
// .new_assert_cmd("contract")
Expand Down Expand Up @@ -450,8 +547,12 @@ async fn change_trust() {

// wrap_cmd(&asset).run().await.unwrap();
let id = contract_id_hash_from_asset(
asset.parse::<builder::Asset>().unwrap(),
&sandbox.network.network_passphrase,
&asset
.parse::<builder::Asset>()
.unwrap()
.resolve(&locator::Args::default())
.unwrap(),
&sandbox.network_passphrase,
);
sandbox
.new_assert_cmd("contract")
Expand Down
14 changes: 8 additions & 6 deletions cmd/crates/soroban-test/tests/it/integration/wrap.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use soroban_cli::{tx::builder, utils::contract_id_hash_from_asset};
use soroban_cli::{config::locator, tx::builder, utils::contract_id_hash_from_asset};
use soroban_test::{AssertExt, TestEnv, LOCAL_NETWORK_PASSPHRASE};

#[tokio::test]
Expand All @@ -12,21 +12,23 @@ async fn burn() {
.arg("test")
.assert()
.stdout_as_str();
let asset = format!("native:{address}");
let asset = "native";
sandbox
.new_assert_cmd("contract")
.arg("asset")
.arg("deploy")
.arg("--source=test")
.arg("--asset")
.arg(&asset)
.arg(asset)
.assert()
.success();
// wrap_cmd(&asset).run().await.unwrap();
let asset: builder::Asset = asset.parse().unwrap();
let asset = asset
.parse::<builder::Asset>()
.unwrap()
.resolve(&locator::Args::default())
.unwrap();
let hash = contract_id_hash_from_asset(&asset, &network_passphrase);
let id = stellar_strkey::Contract(hash.0).to_string();
println!("{id}, {address}");
sandbox
.new_assert_cmd("contract")
.args([
Expand Down
1 change: 1 addition & 0 deletions cmd/soroban-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ wasm-gen = "0.1.4"
zeroize = "1.8.1"
keyring = { version = "3", features = ["apple-native", "windows-native", "sync-secret-service"] }
whoami = "1.5.2"
serde_with = "3.11.0"


[build-dependencies]
Expand Down
8 changes: 7 additions & 1 deletion cmd/soroban-cli/src/commands/contract/arg_parsing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,5 +269,11 @@ fn resolve_address(addr_or_alias: &str, config: &config::Args) -> Result<String,
}

fn resolve_signer(addr_or_alias: &str, config: &config::Args) -> Option<SigningKey> {
config.locator.key(addr_or_alias).ok()?.key_pair(None).ok()
config
.locator
.read_key(addr_or_alias)
.ok()?
.private_key(None)
.ok()
.map(|pk| SigningKey::from_bytes(&pk.0))
}
6 changes: 4 additions & 2 deletions cmd/soroban-cli/src/commands/contract/deploy/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ pub enum Error {
#[error(transparent)]
Builder(#[from] builder::Error),
#[error(transparent)]
Asset(#[from] builder::asset::Error),
#[error(transparent)]
Locator(#[from] locator::Error),
}

Expand Down Expand Up @@ -107,7 +109,7 @@ impl NetworkRunnable for Cmd {
) -> Result<Self::Result, Error> {
let config = config.unwrap_or(&self.config);
// Parse asset
let asset = &self.asset;
let asset = self.asset.resolve(&config.locator)?;

let network = config.get_network()?;
let client = network.rpc_client()?;
Expand All @@ -122,7 +124,7 @@ impl NetworkRunnable for Cmd {
.await?;
let sequence: i64 = account_details.seq_num.into();
let network_passphrase = &network.network_passphrase;
let contract_id = contract_id_hash_from_asset(asset, network_passphrase);
let contract_id = contract_id_hash_from_asset(&asset, network_passphrase);
let tx = build_wrap_token_tx(
asset,
&contract_id,
Expand Down
7 changes: 6 additions & 1 deletion cmd/soroban-cli/src/commands/contract/id/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub enum Error {
ConfigError(#[from] config::Error),
#[error(transparent)]
Xdr(#[from] crate::xdr::Error),
#[error(transparent)]
Asset(#[from] builder::asset::Error),
}
impl Cmd {
pub fn run(&self) -> Result<(), Error> {
Expand All @@ -30,7 +32,10 @@ impl Cmd {

pub fn contract_address(&self) -> Result<stellar_strkey::Contract, Error> {
let network = self.config.get_network()?;
let contract_id = contract_id_hash_from_asset(&self.asset, &network.network_passphrase);
let contract_id = contract_id_hash_from_asset(
&self.asset.resolve(&self.config.locator)?,
&network.network_passphrase,
);
Ok(stellar_strkey::Contract(contract_id.0))
}
}
17 changes: 13 additions & 4 deletions cmd/soroban-cli/src/commands/keys/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ use clap::command;

use crate::{
commands::global,
config::{address::KeyName, locator, secret},
config::{address::KeyName, key, locator, secret},
print::Print,
};

#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Secret(#[from] secret::Error),

#[error(transparent)]
Key(#[from] key::Error),
#[error(transparent)]
Config(#[from] locator::Error),
}
Expand All @@ -26,13 +27,21 @@ pub struct Cmd {

#[command(flatten)]
pub config_locator: locator::Args,

/// Add a public key, ed25519, or muxed account, e.g. G1.., M2..
#[arg(long, conflicts_with = "seed_phrase", conflicts_with = "secret_key")]
pub public_key: Option<String>,
}

impl Cmd {
pub fn run(&self, global_args: &global::Args) -> Result<(), Error> {
let key = if let Some(key) = self.public_key.as_ref() {
key.parse()?
} else {
self.secrets.read_secret()?.into()
};
let print = Print::new(global_args.quiet);
let secret = self.secrets.read_secret()?;
let path = self.config_locator.write_identity(&self.name, &secret)?;
let path = self.config_locator.write_key(&self.name, &key)?;
print.checkln(format!("Key saved with alias {:?} in {path:?}", self.name));
Ok(())
}
Expand Down
9 changes: 5 additions & 4 deletions cmd/soroban-cli/src/commands/keys/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use super::super::config::{
locator, network,
secret::{self, Secret},
};

use crate::{
commands::global,
config::address::KeyName,
Expand Down Expand Up @@ -178,7 +179,7 @@ impl Cmd {

#[cfg(test)]
mod tests {
use crate::config::{address::KeyName, secret::Secret};
use crate::config::{address::KeyName, key::Key, secret::Secret};
use keyring::{mock, set_default_credential_builder};

fn set_up_test() -> (super::locator::Args, super::Cmd) {
Expand Down Expand Up @@ -220,7 +221,7 @@ mod tests {
let result = cmd.run(&global_args).await;
assert!(result.is_ok());
let identity = test_locator.read_identity("test_name").unwrap();
assert!(matches!(identity, Secret::SeedPhrase { .. }));
assert!(matches!(identity, Key::Secret(Secret::SeedPhrase { .. })));
}

#[tokio::test]
Expand All @@ -232,7 +233,7 @@ mod tests {
let result = cmd.run(&global_args).await;
assert!(result.is_ok());
let identity = test_locator.read_identity("test_name").unwrap();
assert!(matches!(identity, Secret::SecretKey { .. }));
assert!(matches!(identity, Key::Secret(Secret::SecretKey { .. })));
}

#[tokio::test]
Expand All @@ -245,6 +246,6 @@ mod tests {
let result = cmd.run(&global_args).await;
assert!(result.is_ok());
let identity = test_locator.read_identity("test_name").unwrap();
assert!(matches!(identity, Secret::SecureStore { .. }));
assert!(matches!(identity, Key::Secret(Secret::SecureStore { .. })));
}
}
7 changes: 2 additions & 5 deletions cmd/soroban-cli/src/commands/keys/secret.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
use clap::arg;

use crate::config::{locator, secret};
use crate::config::{key, locator};

#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Config(#[from] locator::Error),

#[error(transparent)]
Secret(#[from] secret::Error),

#[error(transparent)]
StrKey(#[from] stellar_strkey::DecodeError),
Key(#[from] key::Error),
}

#[derive(Debug, clap::Parser, Clone)]
Expand Down
4 changes: 3 additions & 1 deletion cmd/soroban-cli/src/commands/snapshot/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,9 @@ impl Cmd {
get_name_from_stellar_asset_contract_storage(storage)
{
let asset: builder::Asset = name.parse()?;
if let Some(issuer) = match asset.into() {
if let Some(issuer) = match asset
.resolve(&global_args.locator)?
{
Asset::Native => None,
Asset::CreditAlphanum4(a4) => Some(a4.issuer),
Asset::CreditAlphanum12(a12) => Some(a12.issuer),
Expand Down
Loading
Loading