use crate::adapters::eris::ErisHub;
use crate::helpers::time::Time;
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::{Addr, Binary, Decimal, Empty, QuerierWrapper, StdResult, Uint128};
use cw20::{Cw20ReceiveMsg, Expiration};
#[allow(unused_imports)]
use cw721::{
AllNftInfoResponse, ApprovalResponse, ApprovalsResponse, ContractInfoResponse, NftInfoResponse,
NumTokensResponse, OperatorsResponse, OwnerOfResponse, TokensResponse,
};
#[allow(unused_imports)]
use cw721_base::MinterResponse;
use cw721_base::QueryMsg as CW721QueryMsg;
use cw721_base::{state::TokenInfo, ExecuteMsg as CW721ExecuteMsg};
use cw_address_like::AddressLike;
use cw_asset::{Asset, AssetInfoBase};
use std::fmt;
#[cw_serde]
pub struct InstantiateMsg {
pub global_config_addr: String,
pub deposit_assets: Vec<DepositAsset<String>>,
}
#[cw_serde]
pub struct DepositAsset<T: AddressLike> {
pub info: AssetInfoBase<T>,
pub config: AssetInfoConfig,
}
#[cw_serde]
pub enum ExecuteMsg {
CreateLock {
time: Option<u64>,
recipient: Option<String>,
},
MergeLock {
token_id: String,
token_id_add: String,
},
SplitLock {
token_id: String,
amount: Uint128,
recipient: Option<String>,
},
ExtendLockTime {
time: u64,
token_id: String,
},
ExtendLockAmount {
token_id: String,
},
LockPermanent {
token_id: String,
},
UnlockPermanent {
token_id: String,
},
Withdraw {
token_id: String,
},
Receive(Cw20ReceiveMsg),
UpdateBlacklist {
append_addrs: Option<Vec<String>>,
remove_addrs: Option<Vec<String>>,
},
UpdateConfig {
append_deposit_assets: Option<Vec<DepositAsset<String>>>,
push_update_contracts: Option<Vec<String>>,
decommissioned: Option<bool>,
},
TransferNft {
recipient: String,
token_id: String,
},
SendNft {
contract: String,
token_id: String,
msg: Binary,
},
Burn {
token_id: String,
},
Approve {
spender: String,
token_id: String,
expires: Option<Expiration>,
},
Revoke {
spender: String,
token_id: String,
},
ApproveAll {
operator: String,
expires: Option<Expiration>,
},
RevokeAll {
operator: String,
},
}
#[cw_serde]
pub enum ReceiveMsg {
ExtendLockAmount {
token_id: String,
},
CreateLock {
time: Option<u64>,
recipient: Option<String>,
},
}
pub type VeNftCollection<'a> = cw721_base::Cw721Contract<'a, Extension, Empty, Empty, Empty>;
pub type VeNftInfo = TokenInfo<Metadata>;
#[cw_serde]
pub struct Trait {
pub display_type: Option<String>,
pub trait_type: String,
pub value: String,
}
pub type Extension = Metadata;
#[cw_serde]
pub struct Metadata {
pub image: Option<String>,
pub description: Option<String>,
pub name: Option<String>,
pub attributes: Option<Vec<Trait>>,
}
impl From<ExecuteMsg> for CW721ExecuteMsg<Metadata, Empty> {
fn from(msg: ExecuteMsg) -> CW721ExecuteMsg<Metadata, Empty> {
match msg {
ExecuteMsg::Approve {
spender,
token_id,
expires,
} => CW721ExecuteMsg::Approve {
spender,
token_id,
expires,
},
ExecuteMsg::Revoke {
spender,
token_id,
} => CW721ExecuteMsg::Revoke {
spender,
token_id,
},
ExecuteMsg::ApproveAll {
operator,
expires,
} => CW721ExecuteMsg::ApproveAll {
operator,
expires,
},
ExecuteMsg::RevokeAll {
operator,
} => CW721ExecuteMsg::RevokeAll {
operator,
},
_ => panic!("cannot covert {:?} to CW721ExecuteMsg", msg),
}
}
}
#[cw_serde]
pub enum BlacklistedVotersResponse {
VotersBlacklisted {},
VotersNotBlacklisted {
voter: String,
},
}
impl fmt::Display for BlacklistedVotersResponse {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
BlacklistedVotersResponse::VotersBlacklisted {} => write!(f, "Voters are blacklisted!"),
BlacklistedVotersResponse::VotersNotBlacklisted {
voter,
} => {
write!(f, "Voter is not blacklisted: {}", voter)
},
}
}
}
#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg {
#[returns(Vec<Addr>)]
BlacklistedVoters {
start_after: Option<String>,
limit: Option<u32>,
},
#[returns(VotingPowerResponse)]
TotalVamp {
time: Option<Time>,
},
#[returns(VotingPowerFixedResponse)]
TotalFixed {
time: Option<Time>,
},
#[returns(VotingPowerResponse)]
LockVamp {
token_id: String,
time: Option<Time>,
},
#[returns(LockInfoResponse)]
LockInfo {
token_id: String,
time: Option<Time>,
},
#[returns(Config)]
Config {},
#[returns(NftInfoResponse<Extension>)]
NftInfo {
token_id: String,
},
#[returns(AllNftInfoResponse<Extension>)]
AllNftInfo {
token_id: String,
include_expired: Option<bool>,
},
#[returns(OwnerOfResponse)]
OwnerOf {
token_id: String,
include_expired: Option<bool>,
},
#[returns(ApprovalResponse)]
Approval {
token_id: String,
spender: String,
include_expired: Option<bool>,
},
#[returns(ApprovalsResponse)]
Approvals {
token_id: String,
include_expired: Option<bool>,
},
#[returns(OperatorsResponse)]
AllOperators {
owner: String,
include_expired: Option<bool>,
start_after: Option<String>,
limit: Option<u32>,
},
#[returns(NumTokensResponse)]
NumTokens {},
#[returns(ContractInfoResponse)]
ContractInfo {},
#[returns(TokensResponse)]
Tokens {
owner: String,
start_after: Option<String>,
limit: Option<u32>,
},
#[returns(TokensResponse)]
AllTokens {
start_after: Option<String>,
limit: Option<u32>,
},
#[returns(MinterResponse)]
Minter {},
}
impl From<QueryMsg> for CW721QueryMsg<Empty> {
fn from(msg: QueryMsg) -> CW721QueryMsg<Empty> {
match msg {
QueryMsg::OwnerOf {
token_id,
include_expired,
} => CW721QueryMsg::OwnerOf {
token_id,
include_expired,
},
QueryMsg::Approval {
token_id,
spender,
include_expired,
} => CW721QueryMsg::Approval {
token_id,
spender,
include_expired,
},
QueryMsg::Approvals {
token_id,
include_expired,
} => CW721QueryMsg::Approvals {
token_id,
include_expired,
},
QueryMsg::AllOperators {
owner,
include_expired,
start_after,
limit,
} => CW721QueryMsg::AllOperators {
owner,
include_expired,
start_after,
limit,
},
QueryMsg::NumTokens {} => CW721QueryMsg::NumTokens {},
QueryMsg::ContractInfo {} => CW721QueryMsg::ContractInfo {},
QueryMsg::NftInfo {
token_id,
} => CW721QueryMsg::NftInfo {
token_id,
},
QueryMsg::AllNftInfo {
token_id,
include_expired,
} => CW721QueryMsg::AllNftInfo {
token_id,
include_expired,
},
QueryMsg::Tokens {
owner,
start_after,
limit,
} => CW721QueryMsg::Tokens {
owner,
start_after,
limit,
},
QueryMsg::AllTokens {
start_after,
limit,
} => CW721QueryMsg::AllTokens {
start_after,
limit,
},
QueryMsg::Minter {} => CW721QueryMsg::Minter {},
_ => panic!("cannot covert {:?} to CW721QueryMsg", msg),
}
}
}
#[cw_serde]
pub struct VotingPowerResponse {
pub fixed: Uint128,
pub voting_power: Uint128,
pub vp: Uint128,
}
#[cw_serde]
pub struct VotingPowerFixedResponse {
pub fixed: Uint128,
}
#[cw_serde]
pub struct LockInfoResponse {
pub owner: Addr,
pub from_period: u64,
pub asset: Asset,
pub underlying_amount: Uint128,
pub coefficient: Decimal,
pub start: u64,
pub end: End,
pub slope: Uint128,
pub fixed_amount: Uint128,
pub voting_power: Uint128,
}
impl LockInfoResponse {
pub fn has_vp(&self) -> bool {
!self.fixed_amount.is_zero() || !self.voting_power.is_zero()
}
pub fn end_string(&self) -> String {
self.end.to_string()
}
}
#[cw_serde]
pub enum End {
Permanent,
Period(u64),
}
impl fmt::Display for End {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
End::Permanent => fmt.write_str("permanent")?,
End::Period(period) => fmt.write_str(&period.to_string())?,
}
Ok(())
}
}
#[cw_serde]
pub struct Config {
pub global_config_addr: Addr,
pub deposit_assets: Vec<DepositAsset<Addr>>,
pub push_update_contracts: Vec<Addr>,
pub decommissioned: Option<bool>,
}
#[cw_serde]
pub enum AssetInfoConfig {
Default,
ExchangeRate {
contract: Addr,
},
}
impl AssetInfoConfig {
pub fn get_exchange_rate(&self, querier: &QuerierWrapper) -> StdResult<Option<Decimal>> {
match self {
AssetInfoConfig::Default => Ok(None),
AssetInfoConfig::ExchangeRate {
contract,
} => Ok(Some(ErisHub(contract).query_exchange_rate(querier)?)),
}
}
pub fn get_underlying_amount(
&self,
querier: &QuerierWrapper,
amount: Uint128,
) -> StdResult<Uint128> {
Ok(self.get_exchange_rate(querier)?.map_or(amount, |e| e * amount))
}
}
#[cw_serde]
pub struct MigrateMsg {}