Skip to content

Commit

Permalink
feat: allow source account to be a public key
Browse files Browse the repository at this point in the history
Currently this would fail if not `--build-only` since we rely on source account being a reference to a private key or seed. However, this is will be useful for `--sign-with-lab` which users will likely copy their public keys from their wallet to use on the CLI.
  • Loading branch information
willemneal committed Sep 24, 2024
1 parent ac5cc57 commit 137e209
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 43 deletions.
9 changes: 4 additions & 5 deletions cmd/soroban-cli/src/commands/contract/deploy/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,10 @@ impl NetworkRunnable for Cmd {
client
.verify_network_passphrase(Some(&network.network_passphrase))
.await?;
let key = config.key_pair()?;
let key = config.source_account()?;

// Get the account sequence number
let public_strkey =
stellar_strkey::ed25519::PublicKey(key.verifying_key().to_bytes()).to_string();
let public_strkey = key.to_string();
// TODO: use symbols for the method names (both here and in serve)
let account_details = client.get_account(&public_strkey).await?;
let sequence: i64 = account_details.seq_num.into();
Expand Down Expand Up @@ -141,7 +140,7 @@ fn build_wrap_token_tx(
sequence: i64,
fee: u32,
_network_passphrase: &str,
key: &ed25519_dalek::SigningKey,
key: &stellar_strkey::ed25519::PublicKey,
) -> Result<Transaction, Error> {
let contract = ScAddress::Contract(contract_id.clone());
let mut read_write = vec![
Expand Down Expand Up @@ -180,7 +179,7 @@ fn build_wrap_token_tx(
};

Ok(Transaction {
source_account: MuxedAccount::Ed25519(Uint256(key.verifying_key().to_bytes())),
source_account: MuxedAccount::Ed25519(Uint256(key.0)),
fee,
seq_num: SequenceNumber(sequence),
cond: Preconditions::None,
Expand Down
22 changes: 11 additions & 11 deletions cmd/soroban-cli/src/commands/contract/deploy/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,10 @@ impl NetworkRunnable for Cmd {
client
.verify_network_passphrase(Some(&network.network_passphrase))
.await?;
let key = config.key_pair()?;
let key = config.source_account()?;

// Get the account sequence number
let public_strkey =
stellar_strkey::ed25519::PublicKey(key.verifying_key().to_bytes()).to_string();

let public_strkey = key.to_string();
let account_details = client.get_account(&public_strkey).await?;
let sequence: i64 = account_details.seq_num.into();
let (txn, contract_id) = build_create_contract_tx(
Expand Down Expand Up @@ -274,11 +272,9 @@ fn build_create_contract_tx(
fee: u32,
network_passphrase: &str,
salt: [u8; 32],
key: &ed25519_dalek::SigningKey,
key: &stellar_strkey::ed25519::PublicKey,
) -> Result<(Transaction, Hash), Error> {
let source_account = AccountId(PublicKey::PublicKeyTypeEd25519(
key.verifying_key().to_bytes().into(),
));
let source_account = AccountId(PublicKey::PublicKeyTypeEd25519(key.0.into()));

let contract_id_preimage = ContractIdPreimage::Address(ContractIdPreimageFromAddress {
address: ScAddress::Account(source_account),
Expand All @@ -297,7 +293,7 @@ fn build_create_contract_tx(
}),
};
let tx = Transaction {
source_account: MuxedAccount::Ed25519(Uint256(key.verifying_key().to_bytes())),
source_account: MuxedAccount::Ed25519(Uint256(key.0)),
fee,
seq_num: SequenceNumber(sequence),
cond: Preconditions::None,
Expand Down Expand Up @@ -325,8 +321,12 @@ mod tests {
1,
"Public Global Stellar Network ; September 2015",
[0u8; 32],
&utils::parse_secret_key("SBFGFF27Y64ZUGFAIG5AMJGQODZZKV2YQKAVUUN4HNE24XZXD2OEUVUP")
.unwrap(),
&stellar_strkey::ed25519::PublicKey(
utils::parse_secret_key("SBFGFF27Y64ZUGFAIG5AMJGQODZZKV2YQKAVUUN4HNE24XZXD2OEUVUP")
.unwrap()
.verifying_key()
.to_bytes(),
),
);

assert!(result.is_ok());
Expand Down
8 changes: 3 additions & 5 deletions cmd/soroban-cli/src/commands/contract/extend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,15 @@ impl NetworkRunnable for Cmd {
tracing::trace!(?network);
let keys = self.key.parse_keys(&config.locator, &network)?;
let client = Client::new(&network.rpc_url)?;
let key = config.key_pair()?;
let key = config.source_account()?;
let extend_to = self.ledgers_to_extend();

// 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 account_details = client.get_account(&key.to_string()).await?;
let sequence: i64 = account_details.seq_num.into();

let tx = Transaction {
source_account: MuxedAccount::Ed25519(Uint256(key.verifying_key().to_bytes())),
source_account: MuxedAccount::Ed25519(Uint256(key.0)),
fee: self.fee.fee,
seq_num: SequenceNumber(sequence + 1),
cond: Preconditions::None,
Expand Down
27 changes: 14 additions & 13 deletions cmd/soroban-cli/src/commands/contract/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,14 @@ impl NetworkRunnable for Cmd {
}
}

let key = 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 source_account = config.source_account()?;

let account_details = client.get_account(&source_account.to_string()).await?;
let sequence: i64 = account_details.seq_num.into();

let (tx_without_preflight, hash) =
build_install_contract_code_tx(&contract, sequence + 1, self.fee.fee, &key)?;
build_install_contract_code_tx(&contract, sequence + 1, self.fee.fee, &source_account)?;

if self.fee.build_only {
return Ok(TxnResult::Txn(tx_without_preflight));
Expand Down Expand Up @@ -255,22 +253,20 @@ pub(crate) fn build_install_contract_code_tx(
source_code: &[u8],
sequence: i64,
fee: u32,
key: &ed25519_dalek::SigningKey,
key: &stellar_strkey::ed25519::PublicKey,
) -> Result<(Transaction, Hash), XdrError> {
let hash = utils::contract_hash(source_code)?;

let op = Operation {
source_account: Some(MuxedAccount::Ed25519(Uint256(
key.verifying_key().to_bytes(),
))),
source_account: Some(MuxedAccount::Ed25519(Uint256(key.0))),
body: OperationBody::InvokeHostFunction(InvokeHostFunctionOp {
host_function: HostFunction::UploadContractWasm(source_code.try_into()?),
auth: VecM::default(),
}),
};

let tx = Transaction {
source_account: MuxedAccount::Ed25519(Uint256(key.verifying_key().to_bytes())),
source_account: MuxedAccount::Ed25519(Uint256(key.0)),
fee,
seq_num: SequenceNumber(sequence),
cond: Preconditions::None,
Expand All @@ -292,8 +288,13 @@ mod tests {
b"foo",
300,
1,
&utils::parse_secret_key("SBFGFF27Y64ZUGFAIG5AMJGQODZZKV2YQKAVUUN4HNE24XZXD2OEUVUP")
.unwrap(),
&stellar_strkey::ed25519::PublicKey::from_payload(
utils::parse_secret_key("SBFGFF27Y64ZUGFAIG5AMJGQODZZKV2YQKAVUUN4HNE24XZXD2OEUVUP")
.unwrap()
.verifying_key()
.as_bytes(),
)
.unwrap(),
);

assert!(result.is_ok());
Expand Down
8 changes: 3 additions & 5 deletions cmd/soroban-cli/src/commands/contract/invoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,12 +216,10 @@ impl NetworkRunnable for Cmd {
client
.verify_network_passphrase(Some(&network.network_passphrase))
.await?;
let key = config.key_pair()?;

// Get the account sequence number
let public_strkey =
stellar_strkey::ed25519::PublicKey(key.verifying_key().to_bytes()).to_string();
client.get_account(&public_strkey).await?
client
.get_account(&config.source_account()?.to_string())
.await?
};
let sequence: i64 = account_details.seq_num.into();
let AccountId(PublicKey::PublicKeyTypeEd25519(account_id)) = account_details.account_id;
Expand Down
7 changes: 3 additions & 4 deletions cmd/soroban-cli/src/commands/contract/restore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,15 @@ impl NetworkRunnable for Cmd {
tracing::trace!(?network);
let entry_keys = self.key.parse_keys(&config.locator, &network)?;
let client = Client::new(&network.rpc_url)?;
let key = config.key_pair()?;
let key = config.source_account()?;

// Get the account sequence number
let public_strkey =
stellar_strkey::ed25519::PublicKey(key.verifying_key().to_bytes()).to_string();
let public_strkey = key.to_string();
let account_details = client.get_account(&public_strkey).await?;
let sequence: i64 = account_details.seq_num.into();

let tx = Transaction {
source_account: MuxedAccount::Ed25519(Uint256(key.verifying_key().to_bytes())),
source_account: MuxedAccount::Ed25519(Uint256(key.0)),
fee: self.fee.fee,
seq_num: SequenceNumber(sequence + 1),
cond: Preconditions::None,
Expand Down
14 changes: 14 additions & 0 deletions cmd/soroban-cli/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ pub enum Error {
Rpc(#[from] soroban_rpc::Error),
#[error(transparent)]
Signer(#[from] signer::Error),
#[error(transparent)]
StellarStrkey(#[from] stellar_strkey::DecodeError),
}

#[derive(Debug, clap::Args, Clone, Default)]
Expand All @@ -55,6 +57,18 @@ pub struct Args {
}

impl Args {
pub fn source_account(&self) -> Result<stellar_strkey::ed25519::PublicKey, Error> {
if let Ok(secret) = self.locator.read_identity(&self.source_account) {
Ok(stellar_strkey::ed25519::PublicKey(
secret.key_pair(self.hd_path)?.verifying_key().to_bytes(),
))
} else {
Ok(stellar_strkey::ed25519::PublicKey::from_string(
&self.source_account,
)?)
}
}

pub fn key_pair(&self) -> Result<ed25519_dalek::SigningKey, Error> {
let key = self.account(&self.source_account)?;
Ok(key.key_pair(self.hd_path)?)
Expand Down

0 comments on commit 137e209

Please sign in to comment.