From 4a72ef13a473c54880a05fc4654981a6b52c98ff Mon Sep 17 00:00:00 2001 From: cor Date: Thu, 20 Feb 2025 14:01:54 +0000 Subject: [PATCH 1/2] feat(cw20-multibalance): init --- Cargo.lock | 11 ++++++ Cargo.toml | 2 +- cosmwasm/cosmwasm.nix | 5 +++ cosmwasm/cw20-multibalance/Cargo.toml | 25 ++++++++++++ cosmwasm/cw20-multibalance/src/contract.rs | 46 ++++++++++++++++++++++ cosmwasm/cw20-multibalance/src/lib.rs | 9 +++++ 6 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 cosmwasm/cw20-multibalance/Cargo.toml create mode 100644 cosmwasm/cw20-multibalance/src/contract.rs create mode 100644 cosmwasm/cw20-multibalance/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index eec91612a5..24e7747f4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4214,6 +4214,17 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "cw20-multibalance" +version = "0.0.0" +dependencies = [ + "cosmwasm-schema 1.5.8", + "cosmwasm-std 1.5.8", + "cw-storage-plus 1.2.0", + "ethabi", + "thiserror 1.0.69", +] + [[package]] name = "cw20-token-minter" version = "0.0.0" diff --git a/Cargo.toml b/Cargo.toml index 105fca8e83..f8a982b8b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ members = [ "cosmwasm/ibc-union/app/ucs03-zkgm", "cosmwasm/ucs02-nft", "cosmwasm/multicall", - + "cosmwasm/cw20-multibalance", "cosmwasm/ibc-union/core", "cosmwasm/ibc-union/core/msg", "cosmwasm/ibc-union/core/light-client-interface", diff --git a/cosmwasm/cosmwasm.nix b/cosmwasm/cosmwasm.nix index 93804ce9d2..4260e3060f 100644 --- a/cosmwasm/cosmwasm.nix +++ b/cosmwasm/cosmwasm.nix @@ -432,6 +432,10 @@ crateDirFromRoot = "cosmwasm/cw20-base"; }; + cw20-multibalance = crane.buildWasmContract { + crateDirFromRoot = "cosmwasm/cw20-multibalance"; + }; + ibc-union = crane.buildWasmContract { crateDirFromRoot = "cosmwasm/ibc-union/core"; }; @@ -515,6 +519,7 @@ # native-token-minter cw20-token-minter ibc-union + cw20-multibalance multicall ; cosmwasm-scripts = diff --git a/cosmwasm/cw20-multibalance/Cargo.toml b/cosmwasm/cw20-multibalance/Cargo.toml new file mode 100644 index 0000000000..0e55b7fa56 --- /dev/null +++ b/cosmwasm/cw20-multibalance/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "cw20-multibalance" +version = "0.0.0" + +authors = { workspace = true } +edition = { workspace = true } +license-file = { workspace = true } +publish = { workspace = true } +repository = { workspace = true } + +[lints] +workspace = true + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +library = [] + +[dependencies] +cosmwasm-schema = { version = "1.5" } +cosmwasm-std = { version = "1.5.4", features = ["stargate"] } +cw-storage-plus = { version = "1.2" } +ethabi = { workspace = true } +thiserror = { workspace = true } diff --git a/cosmwasm/cw20-multibalance/src/contract.rs b/cosmwasm/cw20-multibalance/src/contract.rs new file mode 100644 index 0000000000..e6f2f7e77b --- /dev/null +++ b/cosmwasm/cw20-multibalance/src/contract.rs @@ -0,0 +1,46 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{ + to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, +}; + +use crate::ContractError; + +#[cw_serde] +struct InstantiateMsg {} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + _deps: DepsMut, + _env: Env, + _info: MessageInfo, + _msg: InstantiateMsg, +) -> Result { + Ok(Response::default()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(_deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { + match msg { + QueryMsg::Balances { + address: _, + tokens: _, + } => to_json_binary::>>(&vec![]), // TODO: insert responses + } +} + +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + #[returns(BalancesResponse)] + Balances { + address: String, + tokens: Vec, + }, +} + +#[cw_serde] +pub struct BalancesResponse { + pub balances: Vec>, +} diff --git a/cosmwasm/cw20-multibalance/src/lib.rs b/cosmwasm/cw20-multibalance/src/lib.rs new file mode 100644 index 0000000000..6579d5f816 --- /dev/null +++ b/cosmwasm/cw20-multibalance/src/lib.rs @@ -0,0 +1,9 @@ +pub mod contract; +use cosmwasm_std::StdError; +use thiserror::Error; + +#[derive(Error, Debug, PartialEq)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), +} From fcb35e73f32be073a3b210a35a252f8659da2310 Mon Sep 17 00:00:00 2001 From: cor Date: Thu, 20 Feb 2025 14:52:39 +0000 Subject: [PATCH 2/2] feat(cw20-multibalance): fetch balances --- Cargo.lock | 8 ++--- cosmwasm/cw20-multibalance/Cargo.toml | 8 ++--- cosmwasm/cw20-multibalance/src/contract.rs | 40 +++++++++++++++++----- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 24e7747f4a..8de07e9b47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4218,10 +4218,10 @@ dependencies = [ name = "cw20-multibalance" version = "0.0.0" dependencies = [ - "cosmwasm-schema 1.5.8", - "cosmwasm-std 1.5.8", - "cw-storage-plus 1.2.0", - "ethabi", + "cosmwasm-schema 2.1.4", + "cosmwasm-std 2.1.4", + "cw-storage-plus 2.0.0", + "cw20", "thiserror 1.0.69", ] diff --git a/cosmwasm/cw20-multibalance/Cargo.toml b/cosmwasm/cw20-multibalance/Cargo.toml index 0e55b7fa56..04e261d9c9 100644 --- a/cosmwasm/cw20-multibalance/Cargo.toml +++ b/cosmwasm/cw20-multibalance/Cargo.toml @@ -18,8 +18,8 @@ crate-type = ["cdylib", "rlib"] library = [] [dependencies] -cosmwasm-schema = { version = "1.5" } -cosmwasm-std = { version = "1.5.4", features = ["stargate"] } -cw-storage-plus = { version = "1.2" } -ethabi = { workspace = true } +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true, features = ["stargate"] } +cw20 = { version = "2.0" } +cw-storage-plus = { workspace = true } thiserror = { workspace = true } diff --git a/cosmwasm/cw20-multibalance/src/contract.rs b/cosmwasm/cw20-multibalance/src/contract.rs index e6f2f7e77b..124063e369 100644 --- a/cosmwasm/cw20-multibalance/src/contract.rs +++ b/cosmwasm/cw20-multibalance/src/contract.rs @@ -2,13 +2,15 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, + to_json_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, QueryRequest, Response, + StdResult, Uint128, WasmQuery, }; +use cw20::Cw20QueryMsg; use crate::ContractError; #[cw_serde] -struct InstantiateMsg {} +pub struct InstantiateMsg {} #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( @@ -21,12 +23,15 @@ pub fn instantiate( } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(_deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Balances { - address: _, - tokens: _, - } => to_json_binary::>>(&vec![]), // TODO: insert responses + QueryMsg::Balances { address, tokens } => { + let balances = tokens + .iter() + .map(|token| query_cw20_balance(deps, token, &address).ok()) + .collect(); + to_json_binary(&BalancesResponse { balances }) + } } } @@ -42,5 +47,24 @@ pub enum QueryMsg { #[cw_serde] pub struct BalancesResponse { - pub balances: Vec>, + pub balances: Vec>, // None if contract is invalid or no balance exists +} + +#[cw_serde] +pub struct BalanceResponse { + pub balance: Uint128, +} + +fn query_cw20_balance(deps: Deps, cw20_contract: &str, address: &str) -> StdResult { + let contract_addr = Addr::unchecked(cw20_contract); + let query_msg = cosmwasm_std::to_json_binary(&Cw20QueryMsg::Balance { + address: address.to_string(), + })?; + + let res: BalanceResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: contract_addr.to_string(), + msg: query_msg, + }))?; + + Ok(res.balance) }