Contracts: make_outputs takes nanogrin amounts (Vec<u64>), not a string

OutputSelectionArgs.make_outputs was a comma-separated grin string parsed inside
libwallet via amount_from_hr_string. Move that parsing to the CLI boundary and
carry explicit nanogrin u64 amounts through the API and Context instead:
- OutputSelectionArgs.make_outputs: Option<String> -> Option<Vec<u64>>;
  output_amounts() becomes a plain accessor, num_custom_outputs() uses len().
- The CLI (wallet_args) parses grin -> nanogrin per amount; ContractNewArgs and
  ContractSetupArgs carry Vec<u64> and copy it through.
- Update the two tests that supplied make_outputs as a string.

Addresses PR #754 review (types.rs, wallet_args.rs).
This commit is contained in:
jwinterm
2026-06-10 14:18:50 -04:00
parent 3fba1319fb
commit f13ea7f01f
5 changed files with 33 additions and 45 deletions
+1 -1
View File
@@ -545,7 +545,7 @@ mod tests {
net_change: Some(-2_000_000_000),
selection_args: OutputSelectionArgs {
// there is no abc5 input
make_outputs: Some(String::from("1,3")),
make_outputs: Some(vec![1_000_000_000, 3_000_000_000]),
..Default::default()
},
..Default::default()
+8 -23
View File
@@ -25,9 +25,9 @@ pub struct OutputSelectionArgs {
pub min_input_confirmation: u64,
/// Which inputs we want to use - default to payjoin if available with Some("any")
pub use_inputs: Option<String>,
/// Change output specification (comma separated amounts which don't include fee subtraction)
/// e.g. "3,1,4,0,0" describes 5 outputs two of which hold 0 value
pub make_outputs: Option<String>,
/// Change output specification: explicit output amounts in nanogrin, not including
/// fee subtraction. e.g. [3, 1, 4, 0, 0] describes 5 outputs, two of which hold 0 value.
pub make_outputs: Option<Vec<u64>>,
}
impl OutputSelectionArgs {
@@ -48,34 +48,19 @@ impl OutputSelectionArgs {
None
}
}
/// Returns the outputs we have to create
// TODO: move consensus code outside of here. Consider turning make_outputs to Vec<u64>
/// Returns the output amounts (nanogrin) we have to create. Amounts arrive already
/// parsed by the caller (e.g. the CLI), so this is just an accessor.
pub fn output_amounts(&self) -> Result<Vec<u64>, Error> {
match self.make_outputs.as_ref() {
Some(s) => s
.split(",")
.map(|amt| {
// Exact decimal parsing (integer nanogrin), not f64.
crate::grin_core::core::amount_from_hr_string(amt).map_err(|e| {
Error::GenericError(format!("Invalid output amount '{}': {}", amt, e))
})
})
.collect(),
None => Ok(vec![]),
}
Ok(self.make_outputs.clone().unwrap_or_default())
}
/// Returns the sum of our output amounts
pub fn sum_output_amounts(&self) -> Result<u64, Error> {
Ok(self.output_amounts()?.iter().sum())
}
/// Returns the number of custom outputs (count only; does not parse the amounts)
/// Returns the number of custom outputs
pub fn num_custom_outputs(&self) -> usize {
self.make_outputs
.as_ref()
.map(|s| s.split(",").count())
.unwrap_or(0)
self.make_outputs.as_ref().map(|v| v.len()).unwrap_or(0)
}
}
impl Default for OutputSelectionArgs {