Skip to content

Commit

Permalink
test: Generic cw1-whitelist example (#404)
Browse files Browse the repository at this point in the history
Part of #399.

Makes generic the contracts cw1-whitelist and cw1-subkeys on the
examples. The latter depends on the former.

---------

Co-authored-by: Jan Woźniak <[email protected]>
  • Loading branch information
abefernan and jawoznia authored Aug 7, 2024
1 parent 0bf0a22 commit 4c5a678
Show file tree
Hide file tree
Showing 22 changed files with 149 additions and 141 deletions.
1 change: 0 additions & 1 deletion examples/contracts/custom/src/cw1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ impl Cw1 for CustomContract {
type Error = StdError;
type ExecC = Empty;
type QueryC = Empty;
type CosmosCustomMsg = Empty;

fn execute(&self, _ctx: ExecCtx, _msgs: Vec<CosmosMsg>) -> StdResult<Response> {
Ok(Response::new())
Expand Down
6 changes: 3 additions & 3 deletions examples/contracts/cw1-subkeys/src/bin/schema.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use cosmwasm_schema::write_api;

use cosmwasm_std::Empty;
use cw1_subkeys::contract::sv::{ContractExecMsg, ContractQueryMsg, InstantiateMsg};

#[cfg(not(tarpaulin_include))]
fn main() {
write_api! {
instantiate: InstantiateMsg,
execute: ContractExecMsg,
query: ContractQueryMsg,
execute: ContractExecMsg<Empty, Empty>,
query: ContractQueryMsg<Empty, Empty>,
}
}
47 changes: 26 additions & 21 deletions examples/contracts/cw1-subkeys/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use cosmwasm_std::{
ensure, ensure_ne, Addr, BankMsg, Coin, CosmosMsg, Deps, DistributionMsg, Env, Order, Response,
StakingMsg, StdResult,
ensure, ensure_ne, Addr, BankMsg, Coin, CosmosMsg, Deps, DistributionMsg, Empty, Env, Order,
Response, StakingMsg, StdResult,
};
use cw1_whitelist::contract::Cw1WhitelistContract;
use cw2::set_contract_version;
use cw_storage_plus::{Bound, Map};
use cw_utils::Expiration;
use sylvia::types::{ExecCtx, InstantiateCtx, QueryCtx};
use sylvia::types::{CustomMsg, CustomQuery, ExecCtx, InstantiateCtx, QueryCtx};
use sylvia::{contract, schemars};

#[cfg(not(feature = "library"))]
Expand All @@ -25,18 +25,23 @@ pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
const MAX_LIMIT: u32 = 30;
const DEFAULT_LIMIT: u32 = 10;

pub struct Cw1SubkeysContract {
pub(crate) whitelist: Cw1WhitelistContract,
pub struct Cw1SubkeysContract<E, Q> {
pub(crate) whitelist: Cw1WhitelistContract<E, Q>,
pub(crate) permissions: Map<&'static Addr, Permissions>,
pub(crate) allowances: Map<&'static Addr, Allowance>,
}

#[cfg_attr(not(feature = "library"), entry_points)]
#[cfg_attr(not(feature = "library"), entry_points(generics<Empty, Empty>))]
#[contract]
#[sv::error(ContractError)]
#[sv::messages(cw1 as Cw1)]
#[sv::messages(whitelist as Whitelist)]
impl Cw1SubkeysContract {
#[sv::custom(msg=E, query=Q)]
impl<E, Q> Cw1SubkeysContract<E, Q>
where
E: CustomMsg + 'static,
Q: CustomQuery + 'static,
{
pub const fn new() -> Self {
Self {
whitelist: Cw1WhitelistContract::new(),
Expand All @@ -48,10 +53,10 @@ impl Cw1SubkeysContract {
#[sv::msg(instantiate)]
pub fn instantiate(
&self,
mut ctx: InstantiateCtx,
mut ctx: InstantiateCtx<Q>,
admins: Vec<String>,
mutable: bool,
) -> Result<Response, ContractError> {
) -> Result<Response<E>, ContractError> {
let result = self.whitelist.instantiate(ctx.branch(), admins, mutable)?;
set_contract_version(ctx.deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
Ok(result)
Expand All @@ -60,11 +65,11 @@ impl Cw1SubkeysContract {
#[sv::msg(exec)]
pub fn increase_allowance(
&self,
ctx: ExecCtx,
ctx: ExecCtx<Q>,
spender: String,
amount: Coin,
expires: Option<Expiration>,
) -> Result<Response, ContractError> {
) -> Result<Response<E>, ContractError> {
ensure!(
self.whitelist.is_admin(ctx.deps.as_ref(), &ctx.info.sender),
ContractError::Unauthorized
Expand Down Expand Up @@ -110,11 +115,11 @@ impl Cw1SubkeysContract {
#[sv::msg(exec)]
pub fn decrease_allowance(
&self,
ctx: ExecCtx,
ctx: ExecCtx<Q>,
spender: String,
amount: Coin,
expires: Option<Expiration>,
) -> Result<Response, ContractError> {
) -> Result<Response<E>, ContractError> {
ensure!(
self.whitelist.is_admin(ctx.deps.as_ref(), &ctx.info.sender),
ContractError::Unauthorized
Expand Down Expand Up @@ -161,10 +166,10 @@ impl Cw1SubkeysContract {
#[sv::msg(exec)]
pub fn set_permissions(
&self,
ctx: ExecCtx,
ctx: ExecCtx<Q>,
spender: String,
permissions: Permissions,
) -> Result<Response, ContractError> {
) -> Result<Response<E>, ContractError> {
ensure!(
self.whitelist.is_admin(ctx.deps.as_ref(), &ctx.info.sender),
ContractError::Unauthorized
Expand All @@ -184,7 +189,7 @@ impl Cw1SubkeysContract {
}

#[sv::msg(query)]
pub fn allowance(&self, ctx: QueryCtx, spender: String) -> StdResult<Allowance> {
pub fn allowance(&self, ctx: QueryCtx<Q>, spender: String) -> StdResult<Allowance> {
// we can use unchecked here as it is a query - bad value means a miss, we never write it
let spender = Addr::unchecked(spender);
let allow = self
Expand All @@ -197,7 +202,7 @@ impl Cw1SubkeysContract {
}

#[sv::msg(query)]
pub fn permissions(&self, ctx: QueryCtx, spender: String) -> StdResult<Permissions> {
pub fn permissions(&self, ctx: QueryCtx<Q>, spender: String) -> StdResult<Permissions> {
let spender = Addr::unchecked(spender);
let permissions = self
.permissions
Expand All @@ -210,7 +215,7 @@ impl Cw1SubkeysContract {
#[sv::msg(query)]
pub fn all_allowances(
&self,
ctx: QueryCtx,
ctx: QueryCtx<Q>,
start_after: Option<String>,
limit: Option<u32>,
) -> StdResult<AllAllowancesResponse> {
Expand Down Expand Up @@ -246,7 +251,7 @@ impl Cw1SubkeysContract {
#[sv::msg(query)]
pub fn all_permissions(
&self,
ctx: QueryCtx,
ctx: QueryCtx<Q>,
start_after: Option<String>,
limit: Option<u32>,
) -> StdResult<AllPermissionsResponse> {
Expand All @@ -272,10 +277,10 @@ impl Cw1SubkeysContract {

pub fn is_authorized(
&self,
deps: Deps,
deps: Deps<Q>,
env: &Env,
sender: &Addr,
msg: &CosmosMsg,
msg: &CosmosMsg<E>,
) -> StdResult<bool> {
if self.whitelist.is_admin(deps, sender) {
return Ok(true);
Expand Down
25 changes: 14 additions & 11 deletions examples/contracts/cw1-subkeys/src/cw1.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
use cosmwasm_std::{ensure, Addr, Empty, Response, StdResult};
use cosmwasm_std::{ensure, Addr, CosmosMsg, Response, StdResult};
use cw1::{CanExecuteResp, Cw1};
use sylvia::types::{ExecCtx, QueryCtx};
use sylvia::types::{CustomMsg, CustomQuery, ExecCtx, QueryCtx};

use crate::contract::Cw1SubkeysContract;
use crate::error::ContractError;

impl Cw1 for Cw1SubkeysContract {
impl<E, Q> Cw1 for Cw1SubkeysContract<E, Q>
where
E: CustomMsg + 'static,
Q: CustomQuery + 'static,
{
type Error = ContractError;
type ExecC = Empty;
type QueryC = Empty;
type CosmosCustomMsg = Empty;
type ExecC = E;
type QueryC = Q;

fn execute(
&self,
ctx: ExecCtx,
msgs: Vec<cosmwasm_std::CosmosMsg>,
) -> Result<cosmwasm_std::Response, Self::Error> {
ctx: ExecCtx<Self::QueryC>,
msgs: Vec<CosmosMsg<Self::ExecC>>,
) -> Result<Response<Self::ExecC>, Self::Error> {
let authorized: StdResult<_> = msgs.iter().try_fold(true, |acc, msg| {
Ok(acc & self.is_authorized(ctx.deps.as_ref(), &ctx.env, &ctx.info.sender, msg)?)
});
Expand All @@ -31,9 +34,9 @@ impl Cw1 for Cw1SubkeysContract {

fn can_execute(
&self,
ctx: QueryCtx,
ctx: QueryCtx<Self::QueryC>,
sender: String,
msg: cosmwasm_std::CosmosMsg,
msg: CosmosMsg<Self::ExecC>,
) -> StdResult<CanExecuteResp> {
let sender = Addr::unchecked(sender);

Expand Down
24 changes: 16 additions & 8 deletions examples/contracts/cw1-subkeys/src/whitelist.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
use cosmwasm_std::{Empty, Response, StdResult};
use sylvia::types::{ExecCtx, QueryCtx};
use cosmwasm_std::{Response, StdResult};
use sylvia::types::{CustomMsg, CustomQuery, ExecCtx, QueryCtx};
use whitelist::responses::AdminListResponse;
use whitelist::Whitelist;

use crate::contract::Cw1SubkeysContract;
use crate::error::ContractError;

impl Whitelist for Cw1SubkeysContract {
impl<E, Q> Whitelist for Cw1SubkeysContract<E, Q>
where
E: CustomMsg + 'static,
Q: CustomQuery + 'static,
{
type Error = ContractError;
type ExecC = Empty;
type QueryC = Empty;
type ExecC = E;
type QueryC = Q;

fn freeze(&self, ctx: ExecCtx) -> Result<Response, Self::Error> {
fn freeze(&self, ctx: ExecCtx<Self::QueryC>) -> Result<Response<Self::ExecC>, Self::Error> {
self.whitelist.freeze(ctx).map_err(From::from)
}

fn update_admins(&self, ctx: ExecCtx, admins: Vec<String>) -> Result<Response, Self::Error> {
fn update_admins(
&self,
ctx: ExecCtx<Self::QueryC>,
admins: Vec<String>,
) -> Result<Response<Self::ExecC>, Self::Error> {
self.whitelist
.update_admins(ctx, admins)
.map_err(From::from)
}

fn admin_list(&self, ctx: QueryCtx) -> StdResult<AdminListResponse> {
fn admin_list(&self, ctx: QueryCtx<Self::QueryC>) -> StdResult<AdminListResponse> {
self.whitelist.admin_list(ctx)
}
}
6 changes: 3 additions & 3 deletions examples/contracts/cw1-whitelist/src/bin/schema.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use cosmwasm_schema::write_api;

use cosmwasm_std::Empty;
use cw1_whitelist::contract::sv::{ContractExecMsg, ContractQueryMsg, InstantiateMsg};

#[cfg(not(tarpaulin_include))]
fn main() {
write_api! {
instantiate: InstantiateMsg,
execute: ContractExecMsg,
query: ContractQueryMsg,
execute: ContractExecMsg<Empty, Empty>,
query: ContractQueryMsg<Empty, Empty>,
}
}
Loading

0 comments on commit 4c5a678

Please sign in to comment.