ability to bond as nominator from wallet tab
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
This commit is contained in:
parent
105ca64dc6
commit
13295288ce
@ -2,7 +2,7 @@
|
|||||||
name = "ghost-eye"
|
name = "ghost-eye"
|
||||||
authors = ["str3tch <stretch@ghostchain.io>"]
|
authors = ["str3tch <stretch@ghostchain.io>"]
|
||||||
description = "Application for interacting with Casper/Ghost nodes that are exposing RPC only to the localhost"
|
description = "Application for interacting with Casper/Ghost nodes that are exposing RPC only to the localhost"
|
||||||
version = "0.3.47"
|
version = "0.3.48"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
homepage = "https://git.ghostchain.io/ghostchain"
|
homepage = "https://git.ghostchain.io/ghostchain"
|
||||||
repository = "https://git.ghostchain.io/ghostchain/ghost-eye"
|
repository = "https://git.ghostchain.io/ghostchain/ghost-eye"
|
||||||
|
@ -51,8 +51,8 @@ pub enum Action {
|
|||||||
StoreRotatedKeys(String),
|
StoreRotatedKeys(String),
|
||||||
|
|
||||||
TransferBalance(String, [u8; 32], u128),
|
TransferBalance(String, [u8; 32], u128),
|
||||||
BondValidatorExtraFrom([u8; 32], u128),
|
BondValidatorExtraFrom([u8; 32], u128, ActionTarget),
|
||||||
BondValidatorFrom([u8; 32], u128),
|
BondValidatorFrom([u8; 32], u128, ActionTarget),
|
||||||
PayoutStakers([u8; 32], [u8; 32], u32),
|
PayoutStakers([u8; 32], [u8; 32], u32),
|
||||||
SetSessionKeys([u8; 32], String),
|
SetSessionKeys([u8; 32], String),
|
||||||
ValidateFrom([u8; 32], u32),
|
ValidateFrom([u8; 32], u32),
|
||||||
|
@ -71,10 +71,11 @@ impl BondPopup {
|
|||||||
match str_amount.parse::<f64>() {
|
match str_amount.parse::<f64>() {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
let amount = (value * 1_000_000_000_000_000_000.0) as u128;
|
let amount = (value * 1_000_000_000_000_000_000.0) as u128;
|
||||||
|
let log_target = ActionTarget::ValidatorLog;
|
||||||
let _ = if self.is_bonded {
|
let _ = if self.is_bonded {
|
||||||
network_tx.send(Action::BondValidatorExtraFrom(self.stash_secret_seed, amount))
|
network_tx.send(Action::BondValidatorExtraFrom(self.stash_secret_seed, amount, log_target))
|
||||||
} else {
|
} else {
|
||||||
network_tx.send(Action::BondValidatorFrom(self.stash_secret_seed, amount))
|
network_tx.send(Action::BondValidatorFrom(self.stash_secret_seed, amount, log_target))
|
||||||
};
|
};
|
||||||
if let Some(action_tx) = &self.action_tx {
|
if let Some(action_tx) = &self.action_tx {
|
||||||
let _ = action_tx.send(Action::ClosePopup);
|
let _ = action_tx.send(Action::ClosePopup);
|
||||||
|
@ -90,7 +90,9 @@ impl Accounts {
|
|||||||
let used_seed = self.wallet_keys[index].seed.clone();
|
let used_seed = self.wallet_keys[index].seed.clone();
|
||||||
let account_id = self.wallet_keys[index].account_id;
|
let account_id = self.wallet_keys[index].account_id;
|
||||||
if let Some(action_tx) = &self.action_tx {
|
if let Some(action_tx) = &self.action_tx {
|
||||||
let _ = action_tx.send(Action::UsedAccount(account_id, used_seed.clone()));
|
let _ = action_tx.send(Action::UsedAccount(
|
||||||
|
account_id,
|
||||||
|
used_seed.clone()));
|
||||||
}
|
}
|
||||||
self.set_sender_nonce(index);
|
self.set_sender_nonce(index);
|
||||||
}
|
}
|
||||||
|
203
src/components/wallet/bond_popup.rs
Normal file
203
src/components/wallet/bond_popup.rs
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind};
|
||||||
|
use color_eyre::Result;
|
||||||
|
use ratatui::{
|
||||||
|
layout::{Position, Alignment, Constraint, Flex, Layout, Rect},
|
||||||
|
widgets::{Block, Clear, Paragraph},
|
||||||
|
Frame
|
||||||
|
};
|
||||||
|
use tokio::sync::mpsc::UnboundedSender;
|
||||||
|
use std::sync::mpsc::Sender;
|
||||||
|
|
||||||
|
use super::{Component, PartialComponent, CurrentTab};
|
||||||
|
use crate::{
|
||||||
|
action::Action,
|
||||||
|
config::Config,
|
||||||
|
palette::StylePalette,
|
||||||
|
types::{ActionLevel, ActionTarget},
|
||||||
|
widgets::{Input, InputRequest},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct BondPopup {
|
||||||
|
is_active: bool,
|
||||||
|
action_tx: Option<UnboundedSender<Action>>,
|
||||||
|
network_tx: Option<Sender<Action>>,
|
||||||
|
account_secret_seed: [u8; 32],
|
||||||
|
account_id: [u8; 32],
|
||||||
|
minimal_bond: u128,
|
||||||
|
is_bonded: bool,
|
||||||
|
amount: Input,
|
||||||
|
palette: StylePalette
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BondPopup {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BondPopup {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
is_active: false,
|
||||||
|
account_secret_seed: [0u8; 32],
|
||||||
|
account_id: [0u8; 32],
|
||||||
|
action_tx: None,
|
||||||
|
network_tx: None,
|
||||||
|
minimal_bond: 0u128,
|
||||||
|
is_bonded: false,
|
||||||
|
amount: Input::new(String::new()),
|
||||||
|
palette: StylePalette::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BondPopup {
|
||||||
|
fn log_event(&mut self, message: String, level: ActionLevel) {
|
||||||
|
if let Some(action_tx) = &self.action_tx {
|
||||||
|
let _ = action_tx.send(
|
||||||
|
Action::EventLog(message, level, ActionTarget::WalletLog));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_used_account(&mut self, account_id: [u8; 32], secret_seed_str: String) {
|
||||||
|
let secret_seed: [u8; 32] = hex::decode(secret_seed_str)
|
||||||
|
.expect("stored seed is valid hex string; qed")
|
||||||
|
.as_slice()
|
||||||
|
.try_into()
|
||||||
|
.expect("stored seed is valid length; qed");
|
||||||
|
self.account_id = account_id;
|
||||||
|
self.account_secret_seed = secret_seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn submit_message(&mut self) {
|
||||||
|
if let Some(network_tx) = &self.network_tx {
|
||||||
|
let str_amount = self.amount.value();
|
||||||
|
let str_amount = if str_amount.starts_with('.') {
|
||||||
|
&format!("0{}", str_amount)[..]
|
||||||
|
} else {
|
||||||
|
str_amount
|
||||||
|
};
|
||||||
|
match str_amount.parse::<f64>() {
|
||||||
|
Ok(value) => {
|
||||||
|
let amount = (value * 1_000_000_000_000_000_000.0) as u128;
|
||||||
|
let log_target = ActionTarget::WalletLog;
|
||||||
|
let _ = if self.is_bonded {
|
||||||
|
network_tx.send(Action::BondValidatorExtraFrom(self.account_secret_seed, amount, log_target))
|
||||||
|
} else {
|
||||||
|
network_tx.send(Action::BondValidatorFrom(self.account_secret_seed, amount, log_target))
|
||||||
|
};
|
||||||
|
if let Some(action_tx) = &self.action_tx {
|
||||||
|
let _ = action_tx.send(Action::ClosePopup);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(err) => self.log_event(
|
||||||
|
format!("invalid amount, error: {err}"), ActionLevel::Error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enter_char(&mut self, new_char: char) {
|
||||||
|
let is_separator_needed = !self.amount.value().contains('.') && new_char == '.';
|
||||||
|
if new_char.is_digit(10) || is_separator_needed {
|
||||||
|
let _ = self.amount.handle(InputRequest::InsertChar(new_char));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_char(&mut self) {
|
||||||
|
let _ = self.amount.handle(InputRequest::DeletePrevChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_cursor_right(&mut self) {
|
||||||
|
let _ = self.amount.handle(InputRequest::GoToNextChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_cursor_left(&mut self) {
|
||||||
|
let _ = self.amount.handle(InputRequest::GoToPrevChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialComponent for BondPopup {
|
||||||
|
fn set_active(&mut self, current_tab: CurrentTab) {
|
||||||
|
match current_tab {
|
||||||
|
CurrentTab::BondPopup => self.is_active = true,
|
||||||
|
_ => {
|
||||||
|
self.is_active = false;
|
||||||
|
self.amount = Input::new(String::new());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Component for BondPopup {
|
||||||
|
fn register_network_handler(&mut self, tx: Sender<Action>) -> Result<()> {
|
||||||
|
self.network_tx = Some(tx);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register_action_handler(&mut self, tx: UnboundedSender<Action>) -> Result<()> {
|
||||||
|
self.action_tx = Some(tx);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register_config_handler(&mut self, config: Config) -> Result<()> {
|
||||||
|
if let Some(style) = config.styles.get(&crate::app::Mode::Wallet) {
|
||||||
|
self.palette.with_normal_style(style.get("normal_style").copied());
|
||||||
|
self.palette.with_normal_border_style(style.get("normal_border_style").copied());
|
||||||
|
self.palette.with_normal_title_style(style.get("normal_title_style").copied());
|
||||||
|
self.palette.with_popup_style(style.get("popup_style").copied());
|
||||||
|
self.palette.with_popup_title_style(style.get("popup_title_style").copied());
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn handle_key_event(&mut self, key: KeyEvent) -> Result<Option<Action>> {
|
||||||
|
if self.is_active && key.kind == KeyEventKind::Press {
|
||||||
|
match key.code {
|
||||||
|
KeyCode::Enter => self.submit_message(),
|
||||||
|
KeyCode::Char(to_insert) => self.enter_char(to_insert),
|
||||||
|
KeyCode::Backspace => self.delete_char(),
|
||||||
|
KeyCode::Left => self.move_cursor_left(),
|
||||||
|
KeyCode::Right => self.move_cursor_right(),
|
||||||
|
KeyCode::Esc => self.is_active = false,
|
||||||
|
_ => {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, action: Action) -> Result<Option<Action>> {
|
||||||
|
match action {
|
||||||
|
Action::SetIsBonded(is_bonded, account_id) if self.account_id == account_id =>
|
||||||
|
self.is_bonded = is_bonded,
|
||||||
|
Action::UsedAccount(account_id, secret_seed) => self.update_used_account(account_id, secret_seed),
|
||||||
|
Action::SetMinValidatorBond(minimal_bond) => self.minimal_bond = minimal_bond,
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(&mut self, frame: &mut Frame, area: Rect) -> Result<()> {
|
||||||
|
if self.is_active {
|
||||||
|
let (border_style, border_type) = self.palette.create_popup_style();
|
||||||
|
let input = Paragraph::new(self.amount.value())
|
||||||
|
.block(Block::bordered()
|
||||||
|
.border_style(border_style)
|
||||||
|
.border_type(border_type)
|
||||||
|
.title_style(self.palette.create_popup_title_style())
|
||||||
|
.title_alignment(Alignment::Right)
|
||||||
|
.title(format!("Staking bond amount")));
|
||||||
|
let v = Layout::vertical([Constraint::Max(3)]).flex(Flex::Center);
|
||||||
|
let h = Layout::horizontal([Constraint::Max(50)]).flex(Flex::Center);
|
||||||
|
let [area] = v.areas(area);
|
||||||
|
let [area] = h.areas(area);
|
||||||
|
|
||||||
|
frame.render_widget(Clear, area);
|
||||||
|
frame.render_widget(input, area);
|
||||||
|
frame.set_cursor_position(Position::new(
|
||||||
|
area.x + self.amount.cursor() as u16 + 1,
|
||||||
|
area.y + 1
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,7 @@ mod add_address_book_record;
|
|||||||
mod rename_address_book_record;
|
mod rename_address_book_record;
|
||||||
mod details;
|
mod details;
|
||||||
mod staking_ledger;
|
mod staking_ledger;
|
||||||
|
mod bond_popup;
|
||||||
|
|
||||||
use balance::Balance;
|
use balance::Balance;
|
||||||
use transfer::Transfer;
|
use transfer::Transfer;
|
||||||
@ -33,6 +34,7 @@ use add_address_book_record::AddAddressBookRecord;
|
|||||||
use rename_address_book_record::RenameAddressBookRecord;
|
use rename_address_book_record::RenameAddressBookRecord;
|
||||||
use details::AccountDetails;
|
use details::AccountDetails;
|
||||||
use staking_ledger::StakingLedger;
|
use staking_ledger::StakingLedger;
|
||||||
|
use bond_popup::BondPopup;
|
||||||
|
|
||||||
use super::Component;
|
use super::Component;
|
||||||
use crate::{action::Action, app::Mode, config::Config};
|
use crate::{action::Action, app::Mode, config::Config};
|
||||||
@ -49,6 +51,7 @@ pub enum CurrentTab {
|
|||||||
RenameAddressBookRecord,
|
RenameAddressBookRecord,
|
||||||
Transfer,
|
Transfer,
|
||||||
AccountDetails,
|
AccountDetails,
|
||||||
|
BondPopup,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PartialComponent: Component {
|
pub trait PartialComponent: Component {
|
||||||
@ -81,6 +84,7 @@ impl Default for Wallet {
|
|||||||
Box::new(RenameAddressBookRecord::default()),
|
Box::new(RenameAddressBookRecord::default()),
|
||||||
Box::new(Transfer::default()),
|
Box::new(Transfer::default()),
|
||||||
Box::new(AccountDetails::default()),
|
Box::new(AccountDetails::default()),
|
||||||
|
Box::new(BondPopup::default()),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,6 +141,7 @@ impl Component for Wallet {
|
|||||||
CurrentTab::RenameAddressBookRecord |
|
CurrentTab::RenameAddressBookRecord |
|
||||||
CurrentTab::Transfer |
|
CurrentTab::Transfer |
|
||||||
CurrentTab::AccountDetails |
|
CurrentTab::AccountDetails |
|
||||||
|
CurrentTab::BondPopup |
|
||||||
CurrentTab::AddAddressBookRecord => match key.code {
|
CurrentTab::AddAddressBookRecord => match key.code {
|
||||||
KeyCode::Esc => {
|
KeyCode::Esc => {
|
||||||
self.current_tab = self.previous_tab;
|
self.current_tab = self.previous_tab;
|
||||||
@ -180,6 +185,13 @@ impl Component for Wallet {
|
|||||||
component.set_active(self.current_tab.clone());
|
component.set_active(self.current_tab.clone());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
KeyCode::Char('B') => {
|
||||||
|
self.previous_tab = self.current_tab;
|
||||||
|
self.current_tab = CurrentTab::BondPopup;
|
||||||
|
for component in self.components.iter_mut() {
|
||||||
|
component.set_active(self.current_tab.clone());
|
||||||
|
}
|
||||||
|
},
|
||||||
KeyCode::Char('l') | KeyCode::Right => {
|
KeyCode::Char('l') | KeyCode::Right => {
|
||||||
self.move_right();
|
self.move_right();
|
||||||
for component in self.components.iter_mut() {
|
for component in self.components.iter_mut() {
|
||||||
@ -213,7 +225,7 @@ impl Component for Wallet {
|
|||||||
self.previous_tab = self.current_tab;
|
self.previous_tab = self.current_tab;
|
||||||
self.current_tab = CurrentTab::Accounts;
|
self.current_tab = CurrentTab::Accounts;
|
||||||
},
|
},
|
||||||
Action::UpdateAddressBookRecord(_) | Action::NewAddressBookRecord(_, _) | Action::ClosePopup => {
|
Action::UpdateAddressBookRecord(_) | Action::NewAddressBookRecord(_, _) => {
|
||||||
self.previous_tab = self.current_tab;
|
self.previous_tab = self.current_tab;
|
||||||
self.current_tab = CurrentTab::AddressBook;
|
self.current_tab = CurrentTab::AddressBook;
|
||||||
},
|
},
|
||||||
@ -233,6 +245,9 @@ impl Component for Wallet {
|
|||||||
self.previous_tab = self.current_tab;
|
self.previous_tab = self.current_tab;
|
||||||
self.current_tab = CurrentTab::AccountDetails;
|
self.current_tab = CurrentTab::AccountDetails;
|
||||||
},
|
},
|
||||||
|
Action::ClosePopup => {
|
||||||
|
self.current_tab = self.previous_tab;
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
for component in self.components.iter_mut() {
|
for component in self.components.iter_mut() {
|
||||||
|
@ -283,7 +283,7 @@ impl Network {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Action::BondValidatorExtraFrom(sender, amount) => {
|
Action::BondValidatorExtraFrom(sender, amount, log_target) => {
|
||||||
let sender_str = hex::encode(sender);
|
let sender_str = hex::encode(sender);
|
||||||
let maybe_nonce = self.senders.get_mut(&sender_str);
|
let maybe_nonce = self.senders.get_mut(&sender_str);
|
||||||
|
|
||||||
@ -293,16 +293,17 @@ impl Network {
|
|||||||
&sender,
|
&sender,
|
||||||
&amount,
|
&amount,
|
||||||
maybe_nonce,
|
maybe_nonce,
|
||||||
|
log_target,
|
||||||
).await {
|
).await {
|
||||||
self.transactions_to_watch.push(TxToWatch {
|
self.transactions_to_watch.push(TxToWatch {
|
||||||
tx_progress,
|
tx_progress,
|
||||||
sender: sender_str,
|
sender: sender_str,
|
||||||
target: ActionTarget::ValidatorLog,
|
target: log_target,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Action::BondValidatorFrom(sender, amount) => {
|
Action::BondValidatorFrom(sender, amount, log_target) => {
|
||||||
let sender_str = hex::encode(sender);
|
let sender_str = hex::encode(sender);
|
||||||
let maybe_nonce = self.senders.get_mut(&sender_str);
|
let maybe_nonce = self.senders.get_mut(&sender_str);
|
||||||
if let Ok(tx_progress) = predefined_txs::bond(
|
if let Ok(tx_progress) = predefined_txs::bond(
|
||||||
@ -311,11 +312,12 @@ impl Network {
|
|||||||
&sender,
|
&sender,
|
||||||
&amount,
|
&amount,
|
||||||
maybe_nonce,
|
maybe_nonce,
|
||||||
|
log_target,
|
||||||
).await {
|
).await {
|
||||||
self.transactions_to_watch.push(TxToWatch {
|
self.transactions_to_watch.push(TxToWatch {
|
||||||
tx_progress,
|
tx_progress,
|
||||||
sender: sender_str,
|
sender: sender_str,
|
||||||
target: ActionTarget::ValidatorLog,
|
target: log_target,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -40,6 +40,7 @@ pub async fn bond_extra(
|
|||||||
sender: &[u8; 32],
|
sender: &[u8; 32],
|
||||||
amount: &u128,
|
amount: &u128,
|
||||||
maybe_nonce: Option<&mut u32>,
|
maybe_nonce: Option<&mut u32>,
|
||||||
|
log_target: ActionTarget,
|
||||||
) -> Result<TxProgress<CasperConfig, OnlineClient<CasperConfig>>> {
|
) -> Result<TxProgress<CasperConfig, OnlineClient<CasperConfig>>> {
|
||||||
let bond_extra_tx = casper_network::tx().staking().bond_extra(*amount);
|
let bond_extra_tx = casper_network::tx().staking().bond_extra(*amount);
|
||||||
inner_sign_and_submit_then_watch(
|
inner_sign_and_submit_then_watch(
|
||||||
@ -49,7 +50,7 @@ pub async fn bond_extra(
|
|||||||
maybe_nonce,
|
maybe_nonce,
|
||||||
Box::new(bond_extra_tx),
|
Box::new(bond_extra_tx),
|
||||||
"bond extra",
|
"bond extra",
|
||||||
ActionTarget::ValidatorLog,
|
log_target,
|
||||||
).await
|
).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +60,7 @@ pub async fn bond(
|
|||||||
sender: &[u8; 32],
|
sender: &[u8; 32],
|
||||||
amount: &u128,
|
amount: &u128,
|
||||||
maybe_nonce: Option<&mut u32>,
|
maybe_nonce: Option<&mut u32>,
|
||||||
|
log_target: ActionTarget,
|
||||||
) -> Result<TxProgress<CasperConfig, OnlineClient<CasperConfig>>> {
|
) -> Result<TxProgress<CasperConfig, OnlineClient<CasperConfig>>> {
|
||||||
// auto-stake everything by now
|
// auto-stake everything by now
|
||||||
let reward_destination = casper_network::runtime_types::pallet_staking::RewardDestination::Staked;
|
let reward_destination = casper_network::runtime_types::pallet_staking::RewardDestination::Staked;
|
||||||
@ -70,7 +72,7 @@ pub async fn bond(
|
|||||||
maybe_nonce,
|
maybe_nonce,
|
||||||
Box::new(bond_tx),
|
Box::new(bond_tx),
|
||||||
"bond",
|
"bond",
|
||||||
ActionTarget::ValidatorLog,
|
log_target,
|
||||||
).await
|
).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ pub enum ActionLevel {
|
|||||||
Error,
|
Error,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Eq, Display, Serialize, Deserialize)]
|
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Display, Serialize, Deserialize)]
|
||||||
pub enum ActionTarget {
|
pub enum ActionTarget {
|
||||||
#[default]
|
#[default]
|
||||||
WalletLog,
|
WalletLog,
|
||||||
|
@ -16,3 +16,4 @@ pub use peer::PeerInformation;
|
|||||||
pub use session::SessionKeyInfo;
|
pub use session::SessionKeyInfo;
|
||||||
pub use nominator::Nominator;
|
pub use nominator::Nominator;
|
||||||
pub use staking::UnlockChunk;
|
pub use staking::UnlockChunk;
|
||||||
|
pub use staking::RewardDestination;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use codec::Decode;
|
use codec::Decode;
|
||||||
|
use strum::Display;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Decode)]
|
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Decode)]
|
||||||
@ -6,3 +7,11 @@ pub struct UnlockChunk {
|
|||||||
pub value: u128,
|
pub value: u128,
|
||||||
pub era: u32,
|
pub era: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, PartialEq, Eq, Display, Serialize, Deserialize)]
|
||||||
|
pub enum RewardDestination {
|
||||||
|
#[default]
|
||||||
|
Staked,
|
||||||
|
Stash,
|
||||||
|
Account(String),
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user