Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(x/wasm): add AllKeys query binding #185

Merged
merged 14 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* (x/warden) [#160](https://github.com/warden-protocol/wardenprotocol/pull/160) Add Osmosis support
* Derive Osmosis addresses from ECDSA_SECP256K1 keys
Pitasi marked this conversation as resolved.
Show resolved Hide resolved
* Extract DataForSigning for Osmosis Amino JSON transactions
* (cosmwasm) [#171](https://github.com/warden-protocol/wardenprotocol/pull/171) Add support for calling warden module from contracts
* (cosmwasm) [#171](https://github.com/warden-protocol/wardenprotocol/pull/171) Add support for executing NewKeyRequest from contracts
* (cosmwasm) [#185](https://github.com/warden-protocol/wardenprotocol/pull/185) Add support for querying AllKeys from contracts
Pitasi marked this conversation as resolved.
Show resolved Hide resolved

### Bug Fixes

Expand All @@ -78,6 +79,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* (ci) [#137](https://github.com/warden-protocol/wardenprotocol/pull/137) Add CodeRabbit configuration file, copied from Cosmos SDK's repo
* (perf) [#138](https://github.com/warden-protocol/wardenprotocol/pull/138) Add benchmarks for most hit queries in `x/warden` and `x/intent` (ActionsByAddress, AllKeys, KeysBySpaceId)
* (chore) [#180](https://github.com/warden-protocol/wardenprotocol/pull/180) Update to use pnpm v9.0.0
* (docs) [#185](https://github.com/warden-protocol/wardenprotocol/pull/185) Add CosmWasm integration related docs.
Pitasi marked this conversation as resolved.
Show resolved Hide resolved

## [v0.2.0](https://github.com/warden-protocol/wardenprotocol/releases/tag/v0.2.0) - 2024-03-26

Expand Down
82 changes: 81 additions & 1 deletion contracts/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,32 @@
# Warden Contracts

This repo contains bindings (with usage examples) for accessing functionality of Warden Protocol blockchain
This repo contains bindings (with usage examples) for accessing core functionality of Warden Protocol blockchain
from CosmWasm contracts.

## Prerequisites

- You need rust to generate schema files.
- You need a Docker to build a contract.
- You need an account in the Warden Protocol blockchain with some balance in order to deploy contracts and perform transactions on it.

## Generate Schema

To generate schema files perform following commands:

```shell
# generate bindings schema
cd packages/bindings
cargo build
cargo run schema

cd ../..

# generate sapmle contract schema
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# generate sapmle contract schema
# generate sample contract schema

cd contracts
cargo build
cargo run schema
```

## Build

```shell
Expand All @@ -11,3 +35,59 @@ docker run --rm -v "$(pwd)":/code \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
cosmwasm/workspace-optimizer:0.13.0
```

After a successful build you'll see a newly generated `sample.wasm` file in the `artifacts` directory.

## Deploy a Contract

We assume that you have a `wardend` executable's directory in your `$PATH` environment variable in order to perform following steps.
Also, your account should be added to the `wardend`'s keychain. Following commands use `alice` name for such account.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is correct. Anyone can request a key from any keychain.


```shell
wardend tx wasm store artifacts/sample.wasm --from alice -y -b sync --chain-id warden --gas 2000000
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
wardend tx wasm store artifacts/sample.wasm --from alice -y -b sync --chain-id warden --gas 2000000
wardend tx wasm store artifacts/sample.wasm --from alice -y --chain-id warden --gas 2000000

deprecated flag

```

Now you should find an id that system assigned to your code.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Now you should find an id that system assigned to your code.
Now you should find the id that the system assigned to your code.

One of the methods to do this is simply list all stored code bundles and find the last one.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
One of the methods to do this is simply list all stored code bundles and find the last one.
One of the methods to do this is to list all stored code bundles and find the last one.

let's avoid terms like "simply" as there's nothing simple about deploying a contract 😛
(https://justsimply.dev/)


```shell
wardend query wasm list-code
```

Let's assume it's 100. Next step is to instantiate our contract using previously deployed code:

```shell
wardend tx wasm instantiate 100 '{}' --from alice --label "Group 1" --no-admin -y --chain-id warden
```

Let's find out address of the newly created contract. The simple way to do it is to query all contracts
with code id that we used previously, and find the last one:

```shell
wardend query wasm list-contract-by-code 100
```

Let's assume its address is `warden1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqtn83hn`
and store it to the `$contract` environment variable for the convenience:

```shell
contract=warden1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqtn83hn
```

Now we are ready to interact with our contract!

# Interacting with Contract

You can query it's state, for example, let's list all existing keys:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct the misuse of "it's" to "its" to use the correct possessive form.

- You can query it's state, for example, let's list all existing keys:
+ You can query its state, for example, let's list all existing keys:

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
You can query it's state, for example, let's list all existing keys:
You can query its state, for example, let's list all existing keys:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can query it's state, for example, let's list all existing keys:
You can query its state, for example, let's list all existing keys:


```shell
wardend query wasm contract-state smart $contract '{ "warden_all_keys": {"pagination":{"limit":0,"reverse":false}, "derive_wallets":[]} }'--chain-id warden
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
wardend query wasm contract-state smart $contract '{ "warden_all_keys": {"pagination":{"limit":0,"reverse":false}, "derive_wallets":[]} }'--chain-id warden
wardend query wasm contract-state smart $contract '{ "warden_all_keys": {"pagination":{"limit":0,"reverse":false}, "derive_wallets":[]} }'

no need for chain id in queries

```

And perform transactions, let's create request for a new key:

```shell
wardend tx wasm execute $contract '{ "new_key_request": { "space_id": 1, "keychain_id": 2, "key_type": 1, "btl": 888, "intent_id": 0 } }' --from alice -y --chain-id warden
```

Note that `space_id` 1 and `keychain_id` 2 should already exist before your transaction.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure the file ends with a newline character to comply with POSIX standards.

7 changes: 7 additions & 0 deletions contracts/contracts/sample/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
# Sample

This is a sample contract which uses bindings for the core Warden Protocol blockchain functionality.

You can deploy it by itself, or you can use it as a starting point for your own contract.

Note that this is a preview, so only limited functionality available right now.
Pitasi marked this conversation as resolved.
Show resolved Hide resolved
The sample contract exposes `NewKeyRequest` transaction and `AllKeys` query, but more on the way!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct the spelling mistake in "more on the way!" to ensure clarity and professionalism in documentation.

- but more on the way!
+ but more features are on the way!

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
The sample contract exposes `NewKeyRequest` transaction and `AllKeys` query, but more on the way!
The sample contract exposes `NewKeyRequest` transaction and `AllKeys` query, but more features are on the way!

3 changes: 2 additions & 1 deletion contracts/contracts/sample/src/bin/schema.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use cosmwasm_schema::write_api;

use sample::msg::{ExecuteMsg};
use sample::msg::{ExecuteMsg, QueryMsg};

fn main() {
write_api! {
execute: ExecuteMsg,
query: QueryMsg
}
}
37 changes: 23 additions & 14 deletions contracts/contracts/sample/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
use cosmwasm_std::{
Addr, Api, DepsMut, Empty, Env, MessageInfo, Response,
StdResult,
};
use cosmwasm_std::{Binary, Deps, DepsMut, Empty, Env, MessageInfo, PageRequest, Response, StdResult, to_json_binary};
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cw2::set_contract_version;

use bindings::msg::{KeyType, WardenMsg};
use bindings::WardenProtocolMsg;
use bindings::{WardenProtocolMsg, WardenProtocolQuery, AllKeysResponse};
use bindings::msg::{WardenMsg};
use bindings::key::{KeyType};
use bindings::querier::WardenQuerier;
use bindings::query::WalletType;

use crate::error::ContractError;
use crate::msg::ExecuteMsg;
use crate::msg::{ExecuteMsg, QueryMsg};

// version info for migration info
const CONTRACT_NAME: &str = "crates.io:wardenprotocol-sample";
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
deps: DepsMut,
deps: DepsMut<WardenProtocolQuery>,
_env: Env,
_info: MessageInfo,
_msg: Empty,
Expand All @@ -27,13 +27,9 @@ pub fn instantiate(
Ok(Response::default())
}

pub fn map_validate(api: &dyn Api, admins: &[String]) -> StdResult<Vec<Addr>> {
admins.iter().map(|addr| api.addr_validate(addr)).collect()
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
deps: DepsMut,
deps: DepsMut<WardenProtocolQuery>,
env: Env,
info: MessageInfo,
msg: ExecuteMsg,
Expand All @@ -44,7 +40,7 @@ pub fn execute(
}

fn execute_new_key_request(
_deps: DepsMut,
_deps: DepsMut<WardenProtocolQuery>,
_env: Env,
_info: MessageInfo,
space_id: u64,
Expand All @@ -65,3 +61,16 @@ fn execute_new_key_request(
.add_attribute("action", "new_key_request");
Ok(res)
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps<WardenProtocolQuery>, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::WardenAllKeys { pagination, derive_wallets } => to_json_binary(&query_warden_all_keys(deps, pagination, derive_wallets)?)
}
}

pub fn query_warden_all_keys(deps: Deps<WardenProtocolQuery>, pagination: PageRequest, derive_wallets: Vec<WalletType>) -> StdResult<AllKeysResponse> {
let querier = WardenQuerier::new(&deps.querier);
let respnose = querier.query_warden_all_keys(pagination, derive_wallets)?;
Ok(respnose)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let respnose = querier.query_warden_all_keys(pagination, derive_wallets)?;
let response = querier.query_warden_all_keys(pagination, derive_wallets)?;

}
14 changes: 12 additions & 2 deletions contracts/contracts/sample/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use cosmwasm_schema::{cw_serde};
use bindings::msg::KeyType;
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::PageRequest;
use bindings::key::KeyType;
use bindings::query::{WalletType};

#[cw_serde]
pub enum ExecuteMsg
Expand All @@ -12,3 +14,11 @@ pub enum ExecuteMsg
intent_id: u64,
},
}

#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg
{
#[returns(bindings::AllKeysResponse)]
WardenAllKeys { pagination: PageRequest, derive_wallets: Vec<WalletType> }
}
8 changes: 8 additions & 0 deletions contracts/packages/bindings/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
# Bindings

This crate provides bindings for the Warden Protocol blockchain core functionality.
You can use it in your own contracts to interact with a Warden Protocol.

Note that this is a preview, so only limited functionality available right now.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure the file ends with a newline character to comply with POSIX standards.

You can execute `NewKeyRequest` and query `AllKeys`, but more on the way!

To start using Warden Protocol from the CosmWasm contracts, please refer to the sample contract.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the missing article "the" before "sample contract" to improve readability and grammatical correctness.

- please refer to sample contract.
+ please refer to the sample contract.

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
To start using Warden Protocol from the CosmWasm contracts, please refer to the sample contract.
To start using Warden Protocol from the CosmWasm contracts, please refer to the sample contract.

12 changes: 11 additions & 1 deletion contracts/packages/bindings/src/bin/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::fs::create_dir_all;

use cosmwasm_schema::{export_schema_with_title, remove_schemas, schema_for};

use bindings::WardenProtocolMsg;
use bindings::{WardenProtocolMsg, WardenProtocolQuery, AllKeysResponse};

fn main() {
let mut out_dir = current_dir().unwrap();
Expand All @@ -16,4 +16,14 @@ fn main() {
&out_dir,
"WardenProtocolMsg",
);
export_schema_with_title(
&schema_for!(WardenProtocolQuery),
&out_dir,
"WardenProtocolQuery",
);
export_schema_with_title(
&schema_for!(AllKeysResponse),
&out_dir,
"AllKeysResponse",
);
}
15 changes: 15 additions & 0 deletions contracts/packages/bindings/src/key.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Binary};

pub type KeyType = i32;

#[cw_serde]
pub struct Key {
id: u64,
space_id: u64,
keychain_id: u64,
#[serde(rename = "type")]
key_type: KeyType,
public_key: Binary,
intent_id: u64,
}
5 changes: 5 additions & 0 deletions contracts/packages/bindings/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
pub mod msg;
pub mod query;
pub mod querier;
pub mod key;

pub use crate::msg::WardenProtocolMsg;
pub use crate::query::{WardenProtocolQuery, AllKeysResponse};
pub use crate::querier::WardenQuerier;
16 changes: 2 additions & 14 deletions contracts/packages/bindings/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{CustomMsg};
use cosmwasm_std::CosmosMsg;
use cosmwasm_std::{CosmosMsg, CustomMsg};
use crate::key::KeyType;

/// WardenMsg is an override of CosmosMsg::Custom to add support for Warden Protocol's custom message types
#[cw_serde]
Expand All @@ -10,18 +10,6 @@ pub enum WardenProtocolMsg {

impl CustomMsg for WardenProtocolMsg {}

#[cw_serde]
pub enum KeyType {
/// The key type is missing.
Unspecified,

/// The key is an ECDSA secp256k1 key.
EcdsaSecp256k1,

/// The key is an EdDSA Ed25519 key.
EddsaEd25519,
}

/// WardenMsg captures all possible messages we can return to Warden Protocol's native warden module
#[cw_serde]
pub enum WardenMsg {
Expand Down
20 changes: 20 additions & 0 deletions contracts/packages/bindings/src/querier.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use cosmwasm_std::{PageRequest, QuerierWrapper, StdResult};

use crate::{AllKeysResponse, WardenProtocolQuery};
use crate::query::{WalletType, WardenQuery};

pub struct WardenQuerier<'a> {
querier: &'a QuerierWrapper<'a, WardenProtocolQuery>,
}

impl<'a> WardenQuerier<'a> {
pub fn new(querier: &'a QuerierWrapper<WardenProtocolQuery>) -> Self {
WardenQuerier { querier }
}

pub fn query_warden_all_keys(&self, pagination: PageRequest, derive_wallets: Vec<WalletType>) -> StdResult<AllKeysResponse> {
let request = WardenProtocolQuery::Warden(WardenQuery::AllKeys { pagination, derive_wallets });
let response = self.querier.query::<AllKeysResponse>(&request.into())?;
Ok(response)
}
}
42 changes: 42 additions & 0 deletions contracts/packages/bindings/src/query.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{CustomQuery, Addr, PageRequest};
use cosmwasm_std::{Binary};
use crate::key::Key;

#[cw_serde]
pub enum WardenProtocolQuery {
Warden(WardenQuery),
}

impl CustomQuery for WardenProtocolQuery {}

#[cw_serde]
pub enum WardenQuery {
AllKeys { pagination: PageRequest, derive_wallets: Vec<WalletType> },
}

pub type WalletType = i32;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made some changes so we don't have "wallets" anymore. This particular case has been replaced by "addresses" (in short: WalletType became AddressType).

Please update all the definitions in this file to reflect the new protobufs.


#[cw_serde]
pub struct PageResponse {
next_key: Option<Binary>,
total: Option<u64>,
}

#[cw_serde]
pub struct WalletKeyResponse {
address: Addr,
#[serde(rename = "type")]
wallet_type: WalletType
}

#[cw_serde]
pub struct QueryKeyResponse {
key: Key,
wallets: Vec<WalletKeyResponse>
}
#[cw_serde]
pub struct AllKeysResponse {
pagination: PageResponse,
keys: Option<QueryKeyResponse>,
}
Loading
Loading