Skip to content

Commit 7965f52

Browse files
committed
Sign Soroban auth entries from Ledger identities.
1 parent 630619d commit 7965f52

9 files changed

Lines changed: 144 additions & 86 deletions

File tree

cmd/soroban-cli/src/commands/contract/arg_parsing.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,25 +93,25 @@ fn running_cmd() -> String {
9393
format!("{} --", args.join(" "))
9494
}
9595

96-
pub async fn build_host_function_parameters(
96+
pub fn build_host_function_parameters(
9797
contract_id: &stellar_strkey::Contract,
9898
slop: &[OsString],
9999
spec_entries: &[ScSpecEntry],
100100
config: &config::Args,
101101
) -> Result<HostFunctionParameters, Error> {
102-
build_host_function_parameters_with_filter(contract_id, slop, spec_entries, config, true).await
102+
build_host_function_parameters_with_filter(contract_id, slop, spec_entries, config, true)
103103
}
104104

105-
pub async fn build_constructor_parameters(
105+
pub fn build_constructor_parameters(
106106
contract_id: &stellar_strkey::Contract,
107107
slop: &[OsString],
108108
spec_entries: &[ScSpecEntry],
109109
config: &config::Args,
110110
) -> Result<HostFunctionParameters, Error> {
111-
build_host_function_parameters_with_filter(contract_id, slop, spec_entries, config, false).await
111+
build_host_function_parameters_with_filter(contract_id, slop, spec_entries, config, false)
112112
}
113113

114-
async fn build_host_function_parameters_with_filter(
114+
fn build_host_function_parameters_with_filter(
115115
contract_id: &stellar_strkey::Contract,
116116
slop: &[OsString],
117117
spec_entries: &[ScSpecEntry],
@@ -122,7 +122,7 @@ async fn build_host_function_parameters_with_filter(
122122
let cmd = build_clap_command(&spec, filter_constructor)?;
123123
let (function, matches_) = parse_command_matches(cmd, slop)?;
124124
let func = get_function_spec(&spec, &function)?;
125-
let (parsed_args, signers) = parse_function_arguments(&func, &matches_, &spec, config).await?;
125+
let (parsed_args, signers) = parse_function_arguments(&func, &matches_, &spec, config)?;
126126
let invoke_args = build_invoke_contract_args(contract_id, &function, parsed_args)?;
127127

128128
Ok((function, spec, invoke_args, signers))
@@ -187,7 +187,7 @@ fn get_function_spec(spec: &Spec, function: &str) -> Result<ScSpecFunctionV0, Er
187187
})
188188
}
189189

190-
async fn parse_function_arguments(
190+
fn parse_function_arguments(
191191
func: &ScSpecFunctionV0,
192192
matches_: &clap::ArgMatches,
193193
spec: &Spec,
@@ -197,13 +197,13 @@ async fn parse_function_arguments(
197197
let mut signers = Vec::<Signer>::new();
198198

199199
for i in func.inputs.iter() {
200-
parse_single_argument(i, matches_, spec, config, &mut signers, &mut parsed_args).await?;
200+
parse_single_argument(i, matches_, spec, config, &mut signers, &mut parsed_args)?;
201201
}
202202

203203
Ok((parsed_args, signers))
204204
}
205205

206-
async fn parse_single_argument(
206+
fn parse_single_argument(
207207
input: &stellar_xdr::curr::ScSpecFunctionInputV0,
208208
matches_: &clap::ArgMatches,
209209
spec: &Spec,
@@ -234,7 +234,7 @@ async fn parse_single_argument(
234234
ScSpecTypeDef::Address | ScSpecTypeDef::MuxedAddress
235235
) {
236236
let trimmed_s = s.trim_matches('"');
237-
if let Some(signer) = resolve_signer(trimmed_s, config).await {
237+
if let Some(signer) = resolve_signer(trimmed_s, config) {
238238
signers.push(signer);
239239
}
240240
}
@@ -464,10 +464,10 @@ fn resolve_address(addr_or_alias: &str, config: &config::Args) -> Result<String,
464464
Ok(account)
465465
}
466466

467-
async fn resolve_signer(addr_or_alias: &str, config: &config::Args) -> Option<Signer> {
467+
fn resolve_signer(addr_or_alias: &str, config: &config::Args) -> Option<Signer> {
468468
let secret = config.locator.get_secret_key(addr_or_alias).ok()?;
469469
let print = Print::new(false);
470-
let signer = secret.signer(config.hd_path(), print).await.ok()?;
470+
let signer = secret.signer(config.hd_path(), print).ok()?;
471471
Some(signer)
472472
}
473473

cmd/soroban-cli/src/commands/contract/deploy/wasm.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,7 @@ impl Cmd {
384384
&slop,
385385
&entries,
386386
config,
387-
)
388-
.await?
387+
)?
389388
.2,
390389
)
391390
}

cmd/soroban-cli/src/commands/contract/invoke.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ impl Cmd {
269269

270270
if let Some(spec_entries) = &spec_entries {
271271
// For testing wasm arg parsing
272-
build_host_function_parameters(&contract_id, &self.slop, spec_entries, config).await?;
272+
build_host_function_parameters(&contract_id, &self.slop, spec_entries, config)?;
273273
}
274274

275275
let client = network.rpc_client()?;
@@ -294,7 +294,7 @@ impl Cmd {
294294
.map_err(Error::from)?;
295295

296296
let params =
297-
build_host_function_parameters(&contract_id, &self.slop, &spec_entries, config).await?;
297+
build_host_function_parameters(&contract_id, &self.slop, &spec_entries, config)?;
298298

299299
let (function, spec, host_function_params, signers) = params;
300300

cmd/soroban-cli/src/commands/message/sign.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,11 @@ impl Cmd {
8080
let secret = self
8181
.locator
8282
.get_secret_key_with_hd_path(key_or_name, self.hd_path)?;
83-
let signer = secret.signer(self.hd_path, print.clone()).await?;
83+
let signer = secret.signer(self.hd_path, print.clone())?;
8484
let public_key = signer.get_public_key()?;
8585

8686
// Encode signature as base64
87-
let signature_base64 = sep_53_sign(&message_bytes, signer)?;
87+
let signature_base64 = sep_53_sign(&message_bytes, signer).await?;
8888

8989
print.infoln(format!("Signer: {public_key}"));
9090
println!("{signature_base64}");
@@ -121,14 +121,14 @@ impl Cmd {
121121
/// Sign the given message bytes with the provided signer, returning the base64-encoded signature.
122122
///
123123
/// Expects the message bytes to be the raw message (without SEP-53 prefix).
124-
fn sep_53_sign(message_bytes: &[u8], signer: Signer) -> Result<String, Error> {
124+
async fn sep_53_sign(message_bytes: &[u8], signer: Signer) -> Result<String, Error> {
125125
// Create SEP-53 payload
126126
let mut payload = Vec::with_capacity(SEP53_PREFIX.len() + message_bytes.len());
127127
payload.extend_from_slice(SEP53_PREFIX.as_bytes());
128128
payload.extend_from_slice(message_bytes);
129129
let hash: [u8; 32] = Sha256::digest(&payload).into();
130130

131-
let signature = signer.sign_payload(hash)?;
131+
let signature = signer.sign_payload(hash).await?;
132132

133133
Ok(BASE64.encode(signature.to_bytes()))
134134
}
@@ -172,8 +172,8 @@ mod tests {
172172
}
173173
}
174174

175-
#[test]
176-
fn test_sign_simple() {
175+
#[tokio::test]
176+
async fn test_sign_simple() {
177177
// SEP-53 - test case 1
178178
let message = "Hello, World!".to_string();
179179
let expected_signature = "fO5dbYhXUhBMhe6kId/cuVq/AfEnHRHEvsP8vXh03M1uLpi5e46yO2Q8rEBzu3feXQewcQE5GArp88u6ePK6BA==";
@@ -189,13 +189,13 @@ mod tests {
189189
let signer = build_signer_for_test_key();
190190

191191
let message_bytes = cmd.get_message_bytes().unwrap();
192-
let signature_base64 = sep_53_sign(&message_bytes, signer).unwrap();
192+
let signature_base64 = sep_53_sign(&message_bytes, signer).await.unwrap();
193193

194194
assert_eq!(signature_base64, expected_signature);
195195
}
196196

197-
#[test]
198-
fn test_sign_japanese() {
197+
#[tokio::test]
198+
async fn test_sign_japanese() {
199199
// SEP-53 - test case 2
200200
let message = "こんにちは、世界!".to_string();
201201
let expected_signature = "CDU265Xs8y3OWbB/56H9jPgUss5G9A0qFuTqH2zs2YDgTm+++dIfmAEceFqB7bhfN3am59lCtDXrCtwH2k1GBA==";
@@ -211,13 +211,13 @@ mod tests {
211211
let signer = build_signer_for_test_key();
212212

213213
let message_bytes = cmd.get_message_bytes().unwrap();
214-
let signature_base64 = sep_53_sign(&message_bytes, signer).unwrap();
214+
let signature_base64 = sep_53_sign(&message_bytes, signer).await.unwrap();
215215

216216
assert_eq!(signature_base64, expected_signature);
217217
}
218218

219-
#[test]
220-
fn test_sign_base64() {
219+
#[tokio::test]
220+
async fn test_sign_base64() {
221221
// SEP-53 - test case 3
222222
let message = "2zZDP1sa1BVBfLP7TeeMk3sUbaxAkUhBhDiNdrksaFo=".to_string();
223223
let expected_signature = "VA1+7hefNwv2NKScH6n+Sljj15kLAge+M2wE7fzFOf+L0MMbssA1mwfJZRyyrhBORQRle10X1Dxpx+UOI4EbDQ==";
@@ -233,7 +233,7 @@ mod tests {
233233
let signer = build_signer_for_test_key();
234234

235235
let message_bytes = cmd.get_message_bytes().unwrap();
236-
let signature_base64 = sep_53_sign(&message_bytes, signer).unwrap();
236+
let signature_base64 = sep_53_sign(&message_bytes, signer).await.unwrap();
237237

238238
assert_eq!(signature_base64, expected_signature);
239239
}

cmd/soroban-cli/src/config/mod.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,10 @@ impl Args {
143143
let client = network.rpc_client()?;
144144
let latest_ledger = client.get_latest_ledger().await?.sequence;
145145
let seq_num = latest_ledger + 60; // ~ 5 min
146-
Ok(signer::sign_soroban_authorizations(
147-
tx,
148-
signers,
149-
seq_num,
150-
&network.network_passphrase,
151-
)?)
146+
Ok(
147+
signer::sign_soroban_authorizations(tx, signers, seq_num, &network.network_passphrase)
148+
.await?,
149+
)
152150
}
153151

154152
pub fn get_network(&self) -> Result<Network, Error> {

cmd/soroban-cli/src/config/secret.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use stellar_strkey::ed25519::{PrivateKey, PublicKey};
66

77
use crate::{
88
print::Print,
9-
signer::{self, ledger, secure_store, LocalKey, SecureStoreEntry, Signer, SignerKind},
9+
signer::{
10+
self, ledger::LedgerEntry, secure_store, LocalKey, SecureStoreEntry, Signer, SignerKind,
11+
},
1012
utils,
1113
};
1214

@@ -207,22 +209,25 @@ impl Secret {
207209
}
208210
}
209211

210-
pub async fn signer(&self, hd_path: Option<usize>, print: Print) -> Result<Signer, Error> {
212+
pub fn signer(&self, hd_path: Option<usize>, print: Print) -> Result<Signer, Error> {
211213
let kind = match self {
212214
Secret::SecretKey { .. } | Secret::SeedPhrase { .. } => {
213215
let key = self.key_pair(hd_path)?;
214216
SignerKind::Local(LocalKey { key })
215217
}
216218
Secret::Ledger {
217219
hardware: HardwareKind::Ledger,
220+
public_key,
218221
hd_path: cached_hd_path,
219-
..
220222
} => {
221223
let effective = hd_path.or(*cached_hd_path).unwrap_or_default();
222224
let hd_path: u32 = effective
223225
.try_into()
224226
.map_err(|_| Error::HdPathOutOfRange(effective))?;
225-
SignerKind::Ledger(ledger::new(hd_path).await?)
227+
SignerKind::Ledger(LedgerEntry {
228+
hd_path,
229+
public_key: Some(PublicKey::from_string(public_key)?),
230+
})
226231
}
227232
Secret::SecureStore {
228233
entry_name,

cmd/soroban-cli/src/config/sign_with.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
config::UnresolvedMuxedAccount,
33
print::Print,
4-
signer::{self, ledger, Signer, SignerKind},
4+
signer::{self, ledger::LedgerEntry, Signer, SignerKind},
55
xdr::{self, TransactionEnvelope},
66
};
77

@@ -76,15 +76,16 @@ impl Args {
7676
print,
7777
}
7878
} else if self.sign_with_ledger {
79-
let ledger = ledger::new(
80-
self.hd_path
81-
.unwrap_or_default()
82-
.try_into()
83-
.unwrap_or_default(),
84-
)
85-
.await?;
79+
let hd_path = self
80+
.hd_path
81+
.unwrap_or_default()
82+
.try_into()
83+
.unwrap_or_default();
8684
Signer {
87-
kind: SignerKind::Ledger(ledger),
85+
kind: SignerKind::Ledger(LedgerEntry {
86+
hd_path,
87+
public_key: None,
88+
}),
8889
print,
8990
}
9091
} else {
@@ -98,7 +99,7 @@ impl Args {
9899
};
99100

100101
let secret = locator.get_secret_key_with_hd_path(key_or_name, self.hd_path)?;
101-
secret.signer(self.hd_path, print).await?
102+
secret.signer(self.hd_path, print)?
102103
};
103104
Ok(signer.sign_tx_env(tx, network).await?)
104105
}

0 commit comments

Comments
 (0)