diff --git a/crates/bin/pcli/src/command/tx.rs b/crates/bin/pcli/src/command/tx.rs index 8582e7faf1..90c49d523d 100644 --- a/crates/bin/pcli/src/command/tx.rs +++ b/crates/bin/pcli/src/command/tx.rs @@ -954,15 +954,22 @@ impl TxCmd { tracing::info!(?order); let source = AddressIndex::new(order.source()); - let position = order.as_position(&asset_cache, OsRng)?; - tracing::info!(?position); - - println!("Position id: {}", position.id()); + let positions = order.as_position(&asset_cache, OsRng)?; + tracing::info!(?positions); + for position in &positions { + println!("Position id: {}", position.id()); + } - let plan = Planner::new(OsRng) + let mut planner = Planner::new(OsRng); + planner .set_gas_prices(gas_prices) - .set_fee_tier(order.fee_tier().into()) - .position_open(position) + .set_fee_tier(order.fee_tier().into()); + + for position in positions { + planner.position_open(position); + } + + let plan = planner .plan( app.view .as_mut() @@ -970,6 +977,7 @@ impl TxCmd { source, ) .await?; + app.build_and_submit_transaction(plan).await?; } TxCmd::Withdraw { diff --git a/crates/bin/pcli/src/command/tx/liquidity_position.rs b/crates/bin/pcli/src/command/tx/liquidity_position.rs index ef2daa52fc..cf2cbb97ef 100644 --- a/crates/bin/pcli/src/command/tx/liquidity_position.rs +++ b/crates/bin/pcli/src/command/tx/liquidity_position.rs @@ -104,6 +104,9 @@ pub enum OrderCmd { /// The selected fee tier to multiply the fee amount by. #[clap(short, long, default_value_t)] fee_tier: FeeTier, + /// Duplicate the order for the given number of times. + #[clap(short, long, default_value = "1")] + num_copies: u32, }, Sell { /// The desired sale, formatted as a string, e.g. `100penumbra@1.2gm` would attempt @@ -121,6 +124,9 @@ pub enum OrderCmd { /// The selected fee tier to multiply the fee amount by. #[clap(short, long, default_value_t)] fee_tier: FeeTier, + /// Duplicate the order for the given number of times. + #[clap(short, long, default_value = "1")] + num_copies: u32, }, } @@ -146,30 +152,49 @@ impl OrderCmd { } } - pub fn as_position( + pub fn num_copies(&self) -> u32 { + match self { + OrderCmd::Buy { num_copies, .. } => *num_copies, + OrderCmd::Sell { num_copies, .. } => *num_copies, + } + } + + pub fn as_position( &self, // Preserved since we'll need it after denom metadata refactor _asset_cache: &asset::Cache, - rng: R, - ) -> Result { - let mut position = match self { + mut rng: impl CryptoRngCore, + ) -> Result> { + let positions = match self { OrderCmd::Buy { buy_order, .. } => { tracing::info!(?buy_order, "parsing buy order"); let order = BuyOrder::parse_str(buy_order)?; - order.into_position(rng) + let mut positions = Vec::new(); + for _ in 0..self.num_copies() { + let mut position = order.into_position(&mut rng); + if self.is_auto_closing() { + position.close_on_fill = true; + } + positions.push(position); + } + positions } OrderCmd::Sell { sell_order, .. } => { tracing::info!(?sell_order, "parsing sell order"); let order = SellOrder::parse_str(sell_order)?; - order.into_position(rng) + let mut positions = Vec::new(); + + for _ in 0..self.num_copies() { + let mut position = order.into_position(&mut rng); + if self.is_auto_closing() { + position.close_on_fill = true; + } + positions.push(position); + } + positions } }; - tracing::info!(?position); - - if self.is_auto_closing() { - position.close_on_fill = true; - } - Ok(position) + Ok(positions) } }