#![allow(clippy::field_reassign_with_default)]
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::pubkey_to_account;
use cosmwasm_std::{Binary, CanonicalAddr, HumanAddr, Uint128};
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct Permit<Permission: Permissions = TokenPermissions> {
#[serde(bound = "")]
pub params: PermitParams<Permission>,
pub signature: PermitSignature,
}
impl<Permission: Permissions> Permit<Permission> {
pub fn check_token(&self, token: &HumanAddr) -> bool {
self.params.allowed_tokens.contains(token)
}
pub fn check_permission(&self, permission: &Permission) -> bool {
self.params.permissions.contains(permission)
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct PermitParams<Permission: Permissions = TokenPermissions> {
pub allowed_tokens: Vec<HumanAddr>,
pub permit_name: String,
pub chain_id: String,
#[serde(bound = "")]
pub permissions: Vec<Permission>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct PermitSignature {
pub pub_key: PubKey,
pub signature: Binary,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct PubKey {
pub r#type: String,
pub value: Binary,
}
impl PubKey {
pub fn canonical_address(&self) -> CanonicalAddr {
pubkey_to_account(&self.value)
}
}
#[remain::sorted]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct SignedPermit<Permission: Permissions = TokenPermissions> {
pub account_number: Uint128,
pub chain_id: String,
pub fee: Fee,
pub memo: String,
#[serde(bound = "")]
pub msgs: Vec<PermitMsg<Permission>>,
pub sequence: Uint128,
}
impl<Permission: Permissions> SignedPermit<Permission> {
pub fn from_params(params: &PermitParams<Permission>) -> Self {
Self {
account_number: Uint128::zero(),
chain_id: params.chain_id.clone(),
fee: Fee::new(),
memo: String::new(),
msgs: vec![PermitMsg::from_content(PermitContent::from_params(params))],
sequence: Uint128::zero(),
}
}
}
#[remain::sorted]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct Fee {
pub amount: Vec<Coin>,
pub gas: Uint128,
}
impl Fee {
pub fn new() -> Self {
Self {
amount: vec![Coin::new()],
gas: Uint128(1),
}
}
}
impl Default for Fee {
fn default() -> Self {
Self::new()
}
}
#[remain::sorted]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct Coin {
pub amount: Uint128,
pub denom: String,
}
impl Coin {
pub fn new() -> Self {
Self {
amount: Uint128::zero(),
denom: "uscrt".to_string(),
}
}
}
impl Default for Coin {
fn default() -> Self {
Self::new()
}
}
#[remain::sorted]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct PermitMsg<Permission: Permissions = TokenPermissions> {
pub r#type: String,
#[serde(bound = "")]
pub value: PermitContent<Permission>,
}
impl<Permission: Permissions> PermitMsg<Permission> {
pub fn from_content(content: PermitContent<Permission>) -> Self {
Self {
r#type: "query_permit".to_string(),
value: content,
}
}
}
#[remain::sorted]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct PermitContent<Permission: Permissions = TokenPermissions> {
pub allowed_tokens: Vec<HumanAddr>,
#[serde(bound = "")]
pub permissions: Vec<Permission>,
pub permit_name: String,
}
impl<Permission: Permissions> PermitContent<Permission> {
pub fn from_params(params: &PermitParams<Permission>) -> Self {
Self {
allowed_tokens: params.allowed_tokens.clone(),
permit_name: params.permit_name.clone(),
permissions: params.permissions.clone(),
}
}
}
pub trait Permissions:
Clone + PartialEq + Serialize + for<'d> Deserialize<'d> + JsonSchema
{
}
impl<T> Permissions for T where
T: Clone + PartialEq + Serialize + for<'d> Deserialize<'d> + JsonSchema
{
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum TokenPermissions {
Allowance,
Balance,
History,
Owner,
}