use crate::{rpc::Request, Api};
use ac_compose_macros::compose_extrinsic;
use ac_primitives::{
config::Config, CallIndex, ExtrinsicParams, RewardDestination, SignExtrinsic,
UncheckedExtrinsic,
};
use codec::{Compact, Decode, Encode};
const STAKING_MODULE: &str = "Staking";
const BOND: &str = "bond";
const BOND_EXTRA: &str = "bond_extra";
const UNBOND: &str = "unbond";
const REBOND: &str = "rebond";
const WITHDRAW_UNBONDED: &str = "withdraw_unbonded";
const NOMINATE: &str = "nominate";
const CHILL: &str = "chill";
const SET_CONTROLLER: &str = "set_controller";
const PAYOUT_STAKERS: &str = "payout_stakers";
const FORCE_NEW_ERA: &str = "force_new_era";
const FORCE_NEW_ERA_ALWAYS: &str = "force_new_era_always";
const FORCE_NO_ERA: &str = "force_no_era";
const SET_PAYEE: &str = "set_payee";
const SET_VALIDATOR_COUNT: &str = "set_validator_count";
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
pub struct PayoutStakers<AccountId> {
pub validator_stash: AccountId,
pub era: u32,
}
pub type BondCall<Address, Balance> =
(CallIndex, Address, Compact<Balance>, RewardDestination<Address>);
pub type BondExtraCall<Balance> = (CallIndex, Compact<Balance>);
pub type UnbondCall<Balance> = (CallIndex, Compact<Balance>);
pub type RebondCall<Balance> = (CallIndex, Compact<Balance>);
pub type WithdrawUnbondedCall = (CallIndex, u32);
pub type NominateCall<Address> = (CallIndex, Vec<Address>);
pub type ChillCall = CallIndex;
pub type SetControllerCall<Address> = (CallIndex, Address);
pub type PayoutStakersCall<AccountId> = (CallIndex, PayoutStakers<AccountId>);
pub type ForceNewEraCall = CallIndex;
pub type ForceNewEraAlwaysCall = CallIndex;
pub type ForceNoEraCall = CallIndex;
pub type SetPayeeCall<Address> = (CallIndex, Address);
pub type SetValidatorCountCall = (CallIndex, u32);
#[maybe_async::maybe_async(?Send)]
pub trait StakingExtrinsics {
type Balance;
type RewardDestination;
type AccountId;
type Address;
type Extrinsic<Call>;
#[allow(clippy::type_complexity)]
async fn staking_bond(
&self,
controller: Self::Address,
value: Self::Balance,
payee: Self::RewardDestination,
) -> Option<Self::Extrinsic<BondCall<Self::Address, Self::Balance>>>;
async fn staking_bond_extra(
&self,
value: Self::Balance,
) -> Option<Self::Extrinsic<BondExtraCall<Self::Balance>>>;
async fn staking_unbond(
&self,
value: Self::Balance,
) -> Option<Self::Extrinsic<UnbondCall<Self::Balance>>>;
async fn staking_rebond(
&self,
value: Self::Balance,
) -> Option<Self::Extrinsic<RebondCall<Self::Balance>>>;
async fn staking_withdraw_unbonded(
&self,
num_slashing_spans: u32,
) -> Option<Self::Extrinsic<WithdrawUnbondedCall>>;
async fn staking_nominate(
&self,
targets: Vec<Self::Address>,
) -> Option<Self::Extrinsic<NominateCall<Self::Address>>>;
async fn staking_chill(&self) -> Option<Self::Extrinsic<ChillCall>>;
async fn staking_set_controller(
&self,
controller: Self::Address,
) -> Option<Self::Extrinsic<SetControllerCall<Self::Address>>>;
async fn payout_stakers(
&self,
era: u32,
account: Self::AccountId,
) -> Option<Self::Extrinsic<PayoutStakersCall<Self::AccountId>>>;
async fn force_new_era(&self) -> Option<Self::Extrinsic<ForceNewEraCall>>;
async fn force_new_era_always(&self) -> Option<Self::Extrinsic<ForceNewEraAlwaysCall>>;
async fn force_no_era(&self) -> Option<Self::Extrinsic<ForceNewEraAlwaysCall>>;
async fn set_payee(
&self,
payee: Self::Address,
) -> Option<Self::Extrinsic<SetPayeeCall<Self::Address>>>;
async fn set_validator_count(
&self,
count: u32,
) -> Option<Self::Extrinsic<SetValidatorCountCall>>;
}
#[maybe_async::maybe_async(?Send)]
impl<T, Client> StakingExtrinsics for Api<T, Client>
where
T: Config,
Client: Request,
Compact<T::StakingBalance>: Encode,
{
type Balance = T::StakingBalance;
type RewardDestination = RewardDestination<Self::Address>;
type AccountId = T::AccountId;
type Address = <T::ExtrinsicSigner as SignExtrinsic<T::AccountId>>::ExtrinsicAddress;
type Extrinsic<Call> = UncheckedExtrinsic<
Self::Address,
Call,
<T::ExtrinsicSigner as SignExtrinsic<T::AccountId>>::Signature,
<T::ExtrinsicParams as ExtrinsicParams<T::Index, T::Hash>>::TxExtension,
>;
async fn staking_bond(
&self,
controller: Self::Address,
value: Self::Balance,
payee: Self::RewardDestination,
) -> Option<Self::Extrinsic<BondCall<Self::Address, Self::Balance>>> {
compose_extrinsic!(self, STAKING_MODULE, BOND, controller, Compact(value), payee)
}
async fn staking_bond_extra(
&self,
value: Self::Balance,
) -> Option<Self::Extrinsic<BondExtraCall<Self::Balance>>> {
compose_extrinsic!(self, STAKING_MODULE, BOND_EXTRA, Compact(value))
}
async fn staking_unbond(
&self,
value: Self::Balance,
) -> Option<Self::Extrinsic<UnbondCall<Self::Balance>>> {
compose_extrinsic!(self, STAKING_MODULE, UNBOND, Compact(value))
}
async fn staking_rebond(
&self,
value: Self::Balance,
) -> Option<Self::Extrinsic<RebondCall<Self::Balance>>> {
compose_extrinsic!(self, STAKING_MODULE, REBOND, Compact(value))
}
async fn staking_withdraw_unbonded(
&self,
num_slashing_spans: u32,
) -> Option<Self::Extrinsic<WithdrawUnbondedCall>> {
compose_extrinsic!(self, STAKING_MODULE, WITHDRAW_UNBONDED, num_slashing_spans)
}
async fn staking_nominate(
&self,
targets: Vec<Self::Address>,
) -> Option<Self::Extrinsic<NominateCall<Self::Address>>> {
compose_extrinsic!(self, STAKING_MODULE, NOMINATE, targets)
}
async fn staking_chill(&self) -> Option<Self::Extrinsic<ChillCall>> {
compose_extrinsic!(self, STAKING_MODULE, CHILL)
}
async fn staking_set_controller(
&self,
controller: Self::Address,
) -> Option<Self::Extrinsic<SetControllerCall<Self::Address>>> {
compose_extrinsic!(self, STAKING_MODULE, SET_CONTROLLER, controller)
}
async fn payout_stakers(
&self,
era: u32,
account: Self::AccountId,
) -> Option<Self::Extrinsic<PayoutStakersCall<Self::AccountId>>> {
let value = PayoutStakers { validator_stash: account, era };
compose_extrinsic!(self, STAKING_MODULE, PAYOUT_STAKERS, value)
}
async fn force_new_era(&self) -> Option<Self::Extrinsic<ForceNewEraCall>> {
compose_extrinsic!(self, STAKING_MODULE, FORCE_NEW_ERA)
}
async fn force_new_era_always(&self) -> Option<Self::Extrinsic<ForceNewEraAlwaysCall>> {
compose_extrinsic!(self, STAKING_MODULE, FORCE_NEW_ERA_ALWAYS)
}
async fn force_no_era(&self) -> Option<Self::Extrinsic<ForceNewEraAlwaysCall>> {
compose_extrinsic!(self, STAKING_MODULE, FORCE_NO_ERA)
}
async fn set_payee(
&self,
payee: Self::Address,
) -> Option<Self::Extrinsic<SetPayeeCall<Self::Address>>> {
compose_extrinsic!(self, STAKING_MODULE, SET_PAYEE, payee)
}
async fn set_validator_count(
&self,
count: u32,
) -> Option<Self::Extrinsic<SetValidatorCountCall>> {
compose_extrinsic!(self, STAKING_MODULE, SET_VALIDATOR_COUNT, count)
}
}