Skip to content

Commit

Permalink
rusk-wallet: add support for stake owner
Browse files Browse the repository at this point in the history
  • Loading branch information
herr-seppia committed Dec 17, 2024
1 parent 14b7f75 commit 38e3441
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 13 deletions.
15 changes: 13 additions & 2 deletions rusk-wallet/src/bin/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ pub(crate) enum Command {
#[arg(long)]
address: Option<Address>,

/// Owner of the stake [default: same Public address of the stake]
#[arg(long)]
owner: Option<Address>,

/// Amount of DUSK to stake
#[arg(short, long)]
amt: Dusk,
Expand Down Expand Up @@ -393,21 +397,28 @@ impl Command {
}
Command::Stake {
address,
owner,
amt,
gas_limit,
gas_price,
} => {
let address = address.unwrap_or(wallet.default_address());
let addr_idx = wallet.find_index(&address)?;
let owner_idx =
owner.map(|owner| wallet.find_index(&owner)).transpose()?;

let gas = Gas::new(gas_limit).with_price(gas_price);
let tx = match address {
Address::Shielded(_) => {
wallet.sync().await?;
wallet.phoenix_stake(addr_idx, amt, gas).await
wallet
.phoenix_stake(addr_idx, owner_idx, amt, gas)
.await
}
Address::Public(_) => {
wallet.moonlight_stake(addr_idx, amt, gas).await
wallet
.moonlight_stake(addr_idx, owner_idx, amt, gas)
.await
}
}?;

Expand Down
3 changes: 3 additions & 0 deletions rusk-wallet/src/bin/interactive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,15 +373,18 @@ fn confirm(cmd: &Command, wallet: &Wallet<WalletFile>) -> anyhow::Result<bool> {
}
Command::Stake {
address,
owner,
amt,
gas_limit,
gas_price,
} => {
let sender = address.as_ref().ok_or(Error::BadAddress)?;
let max_fee = gas_limit * gas_price;
let stake_to = wallet.public_address(wallet.find_index(sender)?)?;
let owner = owner.as_ref().unwrap_or(&stake_to);
println!(" > Pay with {}", sender.preview());
println!(" > Stake to {}", stake_to.preview());
println!(" > Stake owner {}", owner.preview());
println!(" > Amount to stake = {} DUSK", amt);
println!(" > Max fee = {} DUSK", Dusk::from(max_fee));
if let Address::Public(_) = sender {
Expand Down
23 changes: 22 additions & 1 deletion rusk-wallet/src/bin/interactive/command_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rusk_wallet::gas::{
DEFAULT_PRICE, GAS_PER_DEPLOY_BYTE, MIN_PRICE_DEPLOYMENT,
};
use rusk_wallet::{
Address, Wallet, MAX_CONTRACT_INIT_ARG_SIZE, MAX_FUNCTION_NAME_SIZE,
Address, Error, Wallet, MAX_CONTRACT_INIT_ARG_SIZE, MAX_FUNCTION_NAME_SIZE,
};

use super::ProfileOp;
Expand Down Expand Up @@ -162,8 +162,29 @@ pub(crate) async fn online(

let mempool_gas_prices = wallet.get_mempool_gas_prices().await?;

let stake_idx = wallet
.find_index(&addr)
.expect("index to exists in interactive mode");
let stake_pk = wallet
.public_key(stake_idx)
.expect("public key to exists in interactive mode");

let owner = match wallet.find_stake_owner_account(stake_pk).await {
Ok(account) => account,
Err(Error::NotStaked) => {
let choices = wallet
.profiles()
.iter()
.map(|p| Address::Public(p.public_addr))
.collect();
prompt::request_address(stake_idx, choices)?
}
e => e?,
};

ProfileOp::Run(Box::new(Command::Stake {
address: Some(addr),
owner: Some(owner),
amt: prompt::request_stake_token_amt(balance)?,
gas_limit: prompt::request_gas_limit(gas::DEFAULT_LIMIT_CALL)?,
gas_price: prompt::request_gas_price(
Expand Down
13 changes: 13 additions & 0 deletions rusk-wallet/src/bin/io/prompt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,19 @@ pub(crate) fn request_transaction_model() -> anyhow::Result<TransactionModel> {
)
}

/// Request transaction model to use
pub(crate) fn request_address(
current_idx: u8,
choices: Vec<Address>,
) -> anyhow::Result<Address> {
Ok(Select::new(
"Please select the moonlight address to use as stake owner",
choices,
)
.with_starting_cursor(current_idx as usize)
.prompt()?)
}

/// Request contract WASM file location
pub(crate) fn request_contract_code() -> anyhow::Result<PathBuf> {
let validator = |path_str: &str| {
Expand Down
28 changes: 28 additions & 0 deletions rusk-wallet/src/clients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::sync::{Arc, Mutex};

use dusk_bytes::Serializable;
use execution_core::signatures::bls::PublicKey as BlsPublicKey;
use execution_core::stake::{StakeFundOwner, StakeKeys};
use execution_core::transfer::moonlight::AccountData;
use execution_core::transfer::phoenix::{Note, NoteLeaf, Prove};
use execution_core::transfer::Transaction;
Expand Down Expand Up @@ -322,6 +323,33 @@ impl State {
Ok(stake_data)
}

/// Get the stake owner of a given stake account.
pub(crate) async fn fetch_stake_owner(
&self,
pk: &BlsPublicKey,
) -> Result<Option<StakeFundOwner>, Error> {
let status = self.status;
status("Fetching stake owner...");

// the target type of the deserialization has to match the return type
// of the contract-query
let stake_keys: Option<StakeKeys> = rkyv::from_bytes(
&self
.client
.contract_query::<_, _, 1024>(
STAKE_CONTRACT,
"get_stake_keys",
pk,
)
.await?,
)
.map_err(|_| Error::Rkyv)?;

let stake_owner = stake_keys.map(|keys| keys.owner);

Ok(stake_owner)
}

pub(crate) fn store(&self) -> &LocalStore {
&self.store
}
Expand Down
Loading

0 comments on commit 38e3441

Please sign in to comment.