diff --git a/contracts/neutron_interchain_queries/Cargo.toml b/contracts/neutron_interchain_queries/Cargo.toml index 5682a1a8..5fed4a16 100644 --- a/contracts/neutron_interchain_queries/Cargo.toml +++ b/contracts/neutron_interchain_queries/Cargo.toml @@ -27,6 +27,8 @@ cw-storage-plus = { workspace = true } serde-json-wasm = { workspace = true } prost-types = { workspace = true } cosmwasm-schema = { workspace = true } +# TODO: use workspace everywhere? +neutron-std = "4.2.2-rc" [dev-dependencies] base64 = { workspace = true } diff --git a/contracts/neutron_interchain_queries/src/contract.rs b/contracts/neutron_interchain_queries/src/contract.rs index bcf79580..6ed83501 100644 --- a/contracts/neutron_interchain_queries/src/contract.rs +++ b/contracts/neutron_interchain_queries/src/contract.rs @@ -1,16 +1,18 @@ use cosmos_sdk_proto::cosmos::bank::v1beta1::MsgSend; use cosmos_sdk_proto::cosmos::tx::v1beta1::{TxBody, TxRaw}; use cosmos_sdk_proto::traits::Message; -use cosmwasm_std::{entry_point, to_json_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, Uint128}; +use cosmwasm_std::{entry_point, to_json_binary, Addr, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, Uint128}; use cw2::set_contract_version; use neutron_sdk::interchain_queries::v047::register_queries::new_register_validators_signing_infos_query_msg; +use neutron_std::types::neutron::interchainqueries::{InterchainqueriesQuerier, RegisteredQuery, QueryResult, KvKey}; +// TODO: fix name +use neutron_sdk::interchain_queries::v045::register_queries::{update_interchain_query as helpers_update_interchain_query, remove_interchain_query as helpers_remove_interchain_query}; use crate::msg::{ Cw20BalanceResponse, ExecuteMsg, GetRecipientTxsResponse, InstantiateMsg, MigrateMsg, QueryMsg, }; use crate::state::{Transfer, RECIPIENT_TXS, TRANSFERS}; -use neutron_sdk::bindings::msg::NeutronMsg; -use neutron_sdk::bindings::types::{Height, KVKey}; +use neutron_sdk::bindings::types::Height; use neutron_sdk::interchain_queries::v047::queries::{ query_balance, query_bank_total, query_delegations, query_distribution_fee_pool, query_government_proposals, query_staking_validators, query_unbonding_delegations, @@ -70,31 +72,31 @@ pub fn execute( addr, denoms, update_period, - } => register_balances_query(connection_id, addr, denoms, update_period), + } => register_balances_query(env.contract.address, connection_id, addr, denoms, update_period), ExecuteMsg::RegisterBankTotalSupplyQuery { connection_id, denoms, update_period, - } => register_bank_total_supply_query(connection_id, denoms, update_period), + } => register_bank_total_supply_query(env.contract.address, connection_id, denoms, update_period), ExecuteMsg::RegisterDistributionFeePoolQuery { connection_id, update_period, - } => register_distribution_fee_pool_query(connection_id, update_period), + } => register_distribution_fee_pool_query(env.contract.address, connection_id, update_period), ExecuteMsg::RegisterGovernmentProposalsQuery { connection_id, proposals_ids, update_period, - } => register_gov_proposal_query(connection_id, proposals_ids, update_period), + } => register_gov_proposal_query(env.contract.address, connection_id, proposals_ids, update_period), ExecuteMsg::RegisterStakingValidatorsQuery { connection_id, validators, update_period, - } => register_staking_validators_query(connection_id, validators, update_period), + } => register_staking_validators_query(env.contract.address, connection_id, validators, update_period), ExecuteMsg::RegisterValidatorsSigningInfosQuery { connection_id, validators, update_period, - } => register_validators_signing_infos_query(connection_id, validators, update_period), + } => register_validators_signing_infos_query(env.contract.address, connection_id, validators, update_period), ExecuteMsg::RegisterDelegatorDelegationsQuery { connection_id, delegator, @@ -107,6 +109,7 @@ pub fn execute( validators, update_period, } => register_unbonding_delegations_query( + env.contract.address, connection_id, delegator, validators, @@ -117,13 +120,14 @@ pub fn execute( recipient, update_period, min_height, - } => register_transfers_query(connection_id, recipient, update_period, min_height), + } => register_transfers_query(env.contract.address, connection_id, recipient, update_period, min_height), ExecuteMsg::RegisterCw20BalanceQuery { connection_id, update_period, cw20_contract_address, account_address, } => register_cw20_balance_query( + env.contract.address, connection_id, update_period, cw20_contract_address, @@ -134,68 +138,74 @@ pub fn execute( new_keys, new_update_period, new_recipient, - } => update_interchain_query(query_id, new_keys, new_update_period, new_recipient), - ExecuteMsg::RemoveInterchainQuery { query_id } => remove_interchain_query(query_id), + } => update_interchain_query(env.contract.address, query_id, new_keys, new_update_period, new_recipient), + ExecuteMsg::RemoveInterchainQuery { query_id } => remove_interchain_query(env.contract.address, query_id), } } pub fn register_balances_query( + contract: Addr, connection_id: String, addr: String, denoms: Vec, update_period: u64, ) -> NeutronResult { - let msg = new_register_balances_query_msg(connection_id, addr, denoms, update_period)?; + let msg = new_register_balances_query_msg(contract, connection_id, addr, denoms, update_period)?; Ok(Response::new().add_message(msg)) } pub fn register_bank_total_supply_query( + contract: Addr, connection_id: String, denoms: Vec, update_period: u64, ) -> NeutronResult { - let msg = new_register_bank_total_supply_query_msg(connection_id, denoms, update_period)?; + let msg = new_register_bank_total_supply_query_msg(contract, connection_id, denoms, update_period)?; Ok(Response::new().add_message(msg)) } pub fn register_distribution_fee_pool_query( + contract: Addr, connection_id: String, update_period: u64, ) -> NeutronResult { - let msg = new_register_distribution_fee_pool_query_msg(connection_id, update_period)?; + let msg = new_register_distribution_fee_pool_query_msg(contract, connection_id, update_period)?; Ok(Response::new().add_message(msg)) } pub fn register_gov_proposal_query( + contract: Addr, connection_id: String, proposals_ids: Vec, update_period: u64, ) -> NeutronResult { - let msg = new_register_gov_proposals_query_msg(connection_id, proposals_ids, update_period)?; + let msg = new_register_gov_proposals_query_msg(contract, connection_id, proposals_ids, update_period)?; Ok(Response::new().add_message(msg)) } pub fn register_staking_validators_query( + contract: Addr, connection_id: String, validators: Vec, update_period: u64, ) -> NeutronResult { - let msg = new_register_staking_validators_query_msg(connection_id, validators, update_period)?; + let msg = new_register_staking_validators_query_msg(contract, connection_id, validators, update_period)?; Ok(Response::new().add_message(msg)) } pub fn register_validators_signing_infos_query( + contract: Addr, connection_id: String, validators: Vec, update_period: u64, ) -> NeutronResult { let msg = - new_register_validators_signing_infos_query_msg(connection_id, validators, update_period)?; + new_register_validators_signing_infos_query_msg(contract, connection_id, validators, update_period)?; Ok(Response::new().add_message(msg)) } @@ -219,12 +229,14 @@ pub fn register_delegations_query( } pub fn register_unbonding_delegations_query( + contract: Addr, connection_id: String, delegator: String, validators: Vec, update_period: u64, ) -> NeutronResult { let msg = new_register_delegator_unbonding_delegations_query_msg( + contract, connection_id, delegator, validators, @@ -235,18 +247,20 @@ pub fn register_unbonding_delegations_query( } pub fn register_transfers_query( + contract: Addr, connection_id: String, recipient: String, update_period: u64, min_height: Option, ) -> NeutronResult { let msg = - new_register_transfers_query_msg(connection_id, recipient, update_period, min_height)?; + new_register_transfers_query_msg(contract, connection_id, recipient, update_period, min_height)?; Ok(Response::new().add_message(msg)) } pub fn register_cw20_balance_query( + contract: Addr, connection_id: String, update_period: u64, cw20_contract_address: String, @@ -259,6 +273,7 @@ pub fn register_cw20_balance_query( storage_key.extend_from_slice(account_address.as_bytes()); let msg = new_register_wasm_contract_store_query_msg( + contract, connection_id, cw20_contract_address, &storage_key, @@ -269,11 +284,12 @@ pub fn register_cw20_balance_query( } pub fn update_interchain_query( + contract: Addr, query_id: u64, - new_keys: Option>, - new_update_period: Option, + new_keys: Vec, + new_update_period: u64, new_recipient: Option, -) -> NeutronResult { +) -> NeutronResult> { let new_filter = new_recipient.map(|recipient| { vec![TransactionFilterItem { field: RECIPIENT_FIELD.to_string(), @@ -283,12 +299,12 @@ pub fn update_interchain_query( }); let update_msg = - NeutronMsg::update_interchain_query(query_id, new_keys, new_update_period, new_filter)?; + helpers_update_interchain_query(contract, query_id, new_keys, new_update_period, new_filter)?; Ok(Response::new().add_message(update_msg)) } -pub fn remove_interchain_query(query_id: u64) -> NeutronResult { - let remove_msg = NeutronMsg::remove_interchain_query(query_id); +pub fn remove_interchain_query(contract: Addr, query_id: u64) -> NeutronResult> { + let remove_msg = helpers_remove_interchain_query(contract, query_id); Ok(Response::new().add_message(remove_msg)) } @@ -328,7 +344,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> NeutronResult { } } -fn query_recipient_txs(deps: Deps, recipient: String) -> NeutronResult { +fn query_recipient_txs(deps: Deps, recipient: String) -> NeutronResult { let txs = RECIPIENT_TXS .load(deps.storage, &recipient) .unwrap_or_default(); @@ -336,13 +352,13 @@ fn query_recipient_txs(deps: Deps, recipient: String) -> NeutronRe } pub fn query_cw20_balance( - deps: Deps, + deps: Deps, _env: Env, registered_query_id: u64, ) -> NeutronResult { let registered_query = get_registered_query(deps, registered_query_id)?; - check_query_type(registered_query.registered_query.query_type, QueryType::KV)?; + check_query_type(registered_query.query_type, QueryType::KV)?; let balance: Uint128 = query_kv_result(deps, registered_query_id)?; Ok(Cw20BalanceResponse { balance }) @@ -355,7 +371,7 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult, env: Env, msg: SudoMsg) -> NeutronResult { +pub fn sudo(deps: DepsMut, env: Env, msg: SudoMsg) -> NeutronResult { match msg { // For handling tx query result SudoMsg::TxQueryResult { @@ -373,7 +389,7 @@ pub fn sudo(deps: DepsMut, env: Env, msg: SudoMsg) -> NeutronResul /// sudo_check_tx_query_result is an example callback for transaction query results that stores the /// deposits received as a result on the registered query in the contract's state. pub fn sudo_tx_query_result( - deps: DepsMut, + deps: DepsMut, _env: Env, query_id: u64, _height: Height, @@ -384,9 +400,9 @@ pub fn sudo_tx_query_result( let body: TxBody = TxBody::decode(tx.body_bytes.as_slice())?; // Get the registered query by ID and retrieve the raw query string - let registered_query: QueryRegisteredQueryResponse = + let registered_query: RegisteredQuery = get_registered_query(deps.as_ref(), query_id)?; - let transactions_filter = registered_query.registered_query.transactions_filter; + let transactions_filter = registered_query.transactions_filter; #[allow(clippy::match_single_binding)] // Depending of the query type, check the transaction data to see whether is satisfies @@ -394,7 +410,8 @@ pub fn sudo_tx_query_result( // all submitted results will be treated as valid. // // TODO: come up with solution to determine transactions filter type - match registered_query.registered_query.query_type { + // TODO: fix this? + match registered_query.query_type { _ => { // For transfer queries, query data looks like `[{"field:"transfer.recipient", "op":"eq", "value":"some_address"}]` let query_data: Vec = @@ -491,7 +508,7 @@ fn check_deposits_size(deposits: &Vec) -> StdResult<()> { /// sudo_kv_query_result is the contract's callback for KV query results. Note that only the query /// id is provided, so you need to read the query result from the state. pub fn sudo_kv_query_result( - deps: DepsMut, + deps: DepsMut, _env: Env, query_id: u64, ) -> NeutronResult { diff --git a/contracts/neutron_interchain_queries/src/msg.rs b/contracts/neutron_interchain_queries/src/msg.rs index 6f6b5cb6..86eb7041 100644 --- a/contracts/neutron_interchain_queries/src/msg.rs +++ b/contracts/neutron_interchain_queries/src/msg.rs @@ -1,5 +1,6 @@ use crate::state::Transfer; use cosmwasm_std::Uint128; +use neutron_std::types::neutron::interchainqueries::KvKey; use neutron_sdk::bindings::types::KVKey; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -66,8 +67,8 @@ pub enum ExecuteMsg { }, UpdateInterchainQuery { query_id: u64, - new_keys: Option>, - new_update_period: Option, + new_keys: Vec, + new_update_period: u64, new_recipient: Option, }, RemoveInterchainQuery { diff --git a/packages/neutron-sdk/src/bindings/types.rs b/packages/neutron-sdk/src/bindings/types.rs index 2dec2b2b..791731d7 100644 --- a/packages/neutron-sdk/src/bindings/types.rs +++ b/packages/neutron-sdk/src/bindings/types.rs @@ -22,39 +22,39 @@ pub fn decode_hex(s: &str) -> Option> { .collect() } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub struct RegisteredQuery { - /// The unique id of the registered query. - pub id: u64, - /// The address that registered the query. - pub owner: String, - /// The KV-storage keys for which we want to get values from remote chain - pub keys: Vec, - /// The query type identifier (i.e. 'kv' or 'tx' for now) - pub query_type: QueryType, - /// The filter for transaction search ICQ - pub transactions_filter: String, - /// The IBC connection ID for getting ConsensusState to verify proofs. - pub connection_id: String, - /// Parameter that defines how often the query must be updated. - pub update_period: u64, - /// The local chain last block height when the query result was updated. - #[serde(default)] - pub last_submitted_result_local_height: u64, - /// The remote chain last block height when the query result was updated. - #[serde(default)] - pub last_submitted_result_remote_height: Height, - /// Amount of coins deposited for the query. - #[serde(default)] - pub deposit: Vec, - /// Timeout before query becomes available for everybody to remove. - #[serde(default)] - pub submit_timeout: u64, - /// The local chain height when the query was registered. - #[serde(default)] - pub registered_at_height: u64, -} +// #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +// #[serde(rename_all = "snake_case")] +// pub struct RegisteredQuery { +// /// The unique id of the registered query. +// pub id: u64, +// /// The address that registered the query. +// pub owner: String, +// /// The KV-storage keys for which we want to get values from remote chain +// pub keys: Vec, +// /// The query type identifier (i.e. 'kv' or 'tx' for now) +// pub query_type: QueryType, +// /// The filter for transaction search ICQ +// pub transactions_filter: String, +// /// The IBC connection ID for getting ConsensusState to verify proofs. +// pub connection_id: String, +// /// Parameter that defines how often the query must be updated. +// pub update_period: u64, +// /// The local chain last block height when the query result was updated. +// #[serde(default)] +// pub last_submitted_result_local_height: u64, +// /// The remote chain last block height when the query result was updated. +// #[serde(default)] +// pub last_submitted_result_remote_height: Height, +// /// Amount of coins deposited for the query. +// #[serde(default)] +// pub deposit: Vec, +// /// Timeout before query becomes available for everybody to remove. +// #[serde(default)] +// pub submit_timeout: u64, +// /// The local chain height when the query was registered. +// #[serde(default)] +// pub registered_at_height: u64, +// } #[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -182,72 +182,72 @@ impl ProtobufAny { const KV_PATH_KEY_DELIMITER: &str = "/"; const KV_KEYS_DELIMITER: &str = ","; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -/// Describes a KV key for which you want to get value from the storage on remote chain -pub struct KVKey { - /// **path** is a path to the storage (storage prefix) where you want to read value by key (usually name of cosmos-packages module: 'staking', 'bank', etc.) - pub path: String, - - /// **key** is a key you want to read from the storage - pub key: Binary, -} - -impl KVKey { - /// Creates KVKey from string - /// Returns None on failure - pub fn from_string>(s: S) -> Option { - let split: Vec<&str> = s.as_ref().split(KV_PATH_KEY_DELIMITER).collect(); - if split.len() < 2 { - return None; - } - - Some(KVKey { - path: split[0].to_string(), - key: Binary::new(decode_hex(split[1])?), - }) - } -} - -#[allow(clippy::from_over_into)] -impl Into for &KVKey { - fn into(self) -> String { - let mut s = String::with_capacity( - self.path.len() + KV_PATH_KEY_DELIMITER.len() + self.key.len() * 2, - ); - - s.push_str(&self.path); - s.push_str(KV_PATH_KEY_DELIMITER); - s.push_str(&encode_hex(&self.key)); - - s - } -} - -/// KVKeys describes vec of KVKey structures -pub struct KVKeys(pub Vec); - -impl KVKeys { - /// Creates KVKeys from string - /// Returns None on failure - pub fn from_string>(s: S) -> Option { - let split = s.as_ref().split(KV_KEYS_DELIMITER); - - Some(KVKeys( - split - .map(KVKey::from_string) - .collect::>>()?, - )) - } -} - -#[allow(clippy::from_over_into)] -impl Into for KVKeys { - fn into(self) -> String { - self.0 - .iter() - .map(|kv| kv.into()) - .collect::>() - .join(KV_KEYS_DELIMITER) - } -} +// #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +// #[serde(rename_all = "snake_case")] +// /// Describes a KV key for which you want to get value from the storage on remote chain +// pub struct KVKey { +// /// **path** is a path to the storage (storage prefix) where you want to read value by key (usually name of cosmos-packages module: 'staking', 'bank', etc.) +// pub path: String, +// +// /// **key** is a key you want to read from the storage +// pub key: Binary, +// } +// +// impl KVKey { +// /// Creates KVKey from string +// /// Returns None on failure +// pub fn from_string>(s: S) -> Option { +// let split: Vec<&str> = s.as_ref().split(KV_PATH_KEY_DELIMITER).collect(); +// if split.len() < 2 { +// return None; +// } +// +// Some(KVKey { +// path: split[0].to_string(), +// key: Binary::new(decode_hex(split[1])?), +// }) +// } +// } +// +// #[allow(clippy::from_over_into)] +// impl Into for &KVKey { +// fn into(self) -> String { +// let mut s = String::with_capacity( +// self.path.len() + KV_PATH_KEY_DELIMITER.len() + self.key.len() * 2, +// ); +// +// s.push_str(&self.path); +// s.push_str(KV_PATH_KEY_DELIMITER); +// s.push_str(&encode_hex(&self.key)); +// +// s +// } +// } +// +// /// KVKeys describes vec of KVKey structures +// pub struct KVKeys(pub Vec); +// +// impl KVKeys { +// /// Creates KVKeys from string +// /// Returns None on failure +// pub fn from_string>(s: S) -> Option { +// let split = s.as_ref().split(KV_KEYS_DELIMITER); +// +// Some(KVKeys( +// split +// .map(KVKey::from_string) +// .collect::>>()?, +// )) +// } +// } +// +// #[allow(clippy::from_over_into)] +// impl Into for KVKeys { +// fn into(self) -> String { +// self.0 +// .iter() +// .map(|kv| kv.into()) +// .collect::>() +// .join(KV_KEYS_DELIMITER) +// } +// } diff --git a/packages/neutron-sdk/src/interchain_queries/queries.rs b/packages/neutron-sdk/src/interchain_queries/queries.rs index d77fea89..12843210 100644 --- a/packages/neutron-sdk/src/interchain_queries/queries.rs +++ b/packages/neutron-sdk/src/interchain_queries/queries.rs @@ -2,7 +2,7 @@ use crate::errors::error::NeutronResult; use crate::interchain_queries::types::{KVReconstruct, QueryType}; use crate::NeutronError; use cosmwasm_std::{Deps, StdError}; -use neutron_std::types::neutron::interchainqueries::{InterchainqueriesQuerier, QueryRegisteredQueryResultResponse, QueryRegisteredQueryResponse, RegisteredQuery, QueryResult}; +use neutron_std::types::neutron::interchainqueries::{InterchainqueriesQuerier, RegisteredQuery, QueryResult}; /// Checks **actual** query type is **expected** query type pub fn check_query_type(actual: String, expected: QueryType) -> NeutronResult<()> { diff --git a/packages/neutron-sdk/src/interchain_queries/types.rs b/packages/neutron-sdk/src/interchain_queries/types.rs index d4a0c3f2..5e854d82 100644 --- a/packages/neutron-sdk/src/interchain_queries/types.rs +++ b/packages/neutron-sdk/src/interchain_queries/types.rs @@ -1,8 +1,9 @@ use crate::{ - bindings::types::{KVKey, StorageValue}, + bindings::types::{StorageValue}, errors::error::NeutronResult, }; use cosmwasm_std::{from_json, StdError, Uint128}; +use neutron_std::types::neutron::interchainqueries::KvKey; use schemars::{JsonSchema, _serde_json::Value}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -92,7 +93,7 @@ impl Into for QueryType { pub enum QueryPayload { /// **kv** is an interchain query type to query KV values from remote chain /// payload is kvkeys - KV(Vec), + KV(Vec), /// **tx** is an interchain query type to query transactions from remote chain /// payload is transactions filter diff --git a/packages/neutron-sdk/src/interchain_queries/v045/helpers.rs b/packages/neutron-sdk/src/interchain_queries/v045/helpers.rs index 9306c743..e4c8cc92 100644 --- a/packages/neutron-sdk/src/interchain_queries/v045/helpers.rs +++ b/packages/neutron-sdk/src/interchain_queries/v045/helpers.rs @@ -1,4 +1,3 @@ -use crate::bindings::types::KVKey; use crate::errors::error::NeutronResult; use crate::interchain_queries::helpers::{decode_and_convert, length_prefix}; use crate::interchain_queries::types::AddressBytes; @@ -11,7 +10,7 @@ use crate::NeutronError; use cosmos_sdk_proto::cosmos::staking::v1beta1::Commission as ValidatorCommission; use cosmwasm_std::{Binary, Decimal, Uint128}; use std::str::{from_utf8, FromStr}; - +use neutron_std::types::neutron::interchainqueries::KvKey; use super::types::{GOV_STORE_KEY, VOTES_KEY_PREFIX}; /// Creates KV key to get **module** param by **key** @@ -50,16 +49,16 @@ pub fn create_account_denom_balance_key, S: AsRef>( /// /// * **addr** address of an account on remote chain for which you want to get balances; /// * **denoms** denominations of the coins for which you want to get balance; -pub fn create_balances_query_keys(addr: String, denoms: Vec) -> NeutronResult> { +pub fn create_balances_query_keys(addr: String, denoms: Vec) -> NeutronResult> { let converted_addr_bytes = decode_and_convert(addr.as_str())?; - let mut kv_keys: Vec = Vec::with_capacity(denoms.len()); + let mut kv_keys: Vec = Vec::with_capacity(denoms.len()); for denom in denoms { let balance_key = create_account_denom_balance_key(&converted_addr_bytes, denom)?; - let kv_key = KVKey { + let kv_key = KvKey { path: BANK_STORE_KEY.to_string(), - key: Binary::new(balance_key), + key: balance_key, }; kv_keys.push(kv_key) @@ -236,13 +235,13 @@ pub fn create_gov_proposal_key(proposal_id: u64) -> NeutronResult> { } /// Creates Cosmos-SDK storage keys for list of proposals -pub fn create_gov_proposal_keys(proposals_ids: Vec) -> NeutronResult> { - let mut kv_keys: Vec = Vec::with_capacity(proposals_ids.len()); +pub fn create_gov_proposal_keys(proposals_ids: Vec) -> NeutronResult> { + let mut kv_keys: Vec = Vec::with_capacity(proposals_ids.len()); for id in proposals_ids { - let kv_key = KVKey { + let kv_key = KvKey { path: GOV_STORE_KEY.to_string(), - key: Binary::new(create_gov_proposal_key(id)?), + key: create_gov_proposal_key(id)?, }; kv_keys.push(kv_key) @@ -276,19 +275,19 @@ pub fn create_gov_proposal_voter_votes_key>( pub fn create_gov_proposals_voters_votes_keys( proposals_ids: Vec, voters: Vec, -) -> NeutronResult> { - let mut kv_keys: Vec = Vec::with_capacity(voters.len() * proposals_ids.len()); +) -> NeutronResult> { + let mut kv_keys: Vec = Vec::with_capacity(voters.len() * proposals_ids.len()); for voter in voters { let voter_addr = decode_and_convert(&voter)?; for proposal_id in proposals_ids.clone() { - let kv_key = KVKey { + let kv_key = KvKey { path: GOV_STORE_KEY.to_string(), - key: Binary::new(create_gov_proposal_voter_votes_key( + key: create_gov_proposal_voter_votes_key( proposal_id, &voter_addr, - )?), + )?, }; kv_keys.push(kv_key) diff --git a/packages/neutron-sdk/src/interchain_queries/v045/register_queries.rs b/packages/neutron-sdk/src/interchain_queries/v045/register_queries.rs index d379e5a8..2a184e6a 100644 --- a/packages/neutron-sdk/src/interchain_queries/v045/register_queries.rs +++ b/packages/neutron-sdk/src/interchain_queries/v045/register_queries.rs @@ -1,12 +1,9 @@ -use crate::interchain_queries::types::{ - QueryPayload, TransactionFilterItem, TransactionFilterOp, TransactionFilterValue, -}; +use crate::interchain_queries::types::{QueryPayload, QueryType, TransactionFilterItem, TransactionFilterOp, TransactionFilterValue}; use crate::interchain_queries::v045::types::{ BANK_STORE_KEY, DISTRIBUTION_STORE_KEY, HEIGHT_FIELD, KEY_BOND_DENOM, PARAMS_STORE_KEY, RECIPIENT_FIELD, SLASHING_STORE_KEY, STAKING_STORE_KEY, WASM_STORE_KEY, }; use crate::{ - bindings::{msg::NeutronMsg, types::KVKey}, errors::error::NeutronResult, interchain_queries::helpers::decode_and_convert, interchain_queries::v045::helpers::{ @@ -16,7 +13,9 @@ use crate::{ create_validator_signing_info_key, create_wasm_contract_store_key, }, }; -use cosmwasm_std::Binary; +use cosmwasm_std::{Addr, Binary, CosmosMsg, StdError}; +use neutron_std::types::neutron::interchainqueries::{KvKey, MsgRegisterInterchainQuery, MsgRemoveInterchainQueryRequest, MsgUpdateInterchainQueryRequest}; +use serde_json_wasm::to_string; /// Creates a message to register an Interchain Query to get balance of account on remote chain for list of denoms /// @@ -25,13 +24,14 @@ use cosmwasm_std::Binary; /// * **denoms** denominations of the coins for which you want to get balance; /// * **update_period** is used to say how often the query must be updated. pub fn new_register_balances_query_msg( + contract: Addr, connection_id: String, addr: String, denoms: Vec, update_period: u64, -) -> NeutronResult { +) -> NeutronResult> { let kv_keys = create_balances_query_keys(addr, denoms)?; - NeutronMsg::register_interchain_query(QueryPayload::KV(kv_keys), connection_id, update_period) + register_interchain_query(contract, QueryPayload::KV(kv_keys), connection_id, update_period) } /// Creates a message to register an Interchain Query to get balance of account on remote chain for a particular denom @@ -42,12 +42,13 @@ pub fn new_register_balances_query_msg( /// * **update_period** is used to say how often the query must be updated. #[deprecated(note = "Please use new_register_balances_query_msg instead")] pub fn new_register_balance_query_msg( + contract: Addr, connection_id: String, addr: String, denom: String, update_period: u64, -) -> NeutronResult { - new_register_balances_query_msg(connection_id, addr, vec![denom], update_period) +) -> NeutronResult> { + new_register_balances_query_msg(contract, connection_id, addr, vec![denom], update_period) } /// Creates a message to register an Interchain Query to get total supply on remote chain for particular denom @@ -56,24 +57,25 @@ pub fn new_register_balance_query_msg( /// * **denom** denomination of the coin for which you want to get total supply; /// * **update_period** is used to say how often the query must be updated. pub fn new_register_bank_total_supply_query_msg( + contract: Addr, connection_id: String, denoms: Vec, update_period: u64, -) -> NeutronResult { - let mut kv_keys: Vec = Vec::with_capacity(denoms.len()); +) -> NeutronResult> { + let mut kv_keys: Vec = Vec::with_capacity(denoms.len()); for denom in denoms { let supply_key = create_total_denom_key(denom)?; - let kv_key = KVKey { + let kv_key = KvKey { path: BANK_STORE_KEY.to_string(), - key: Binary::new(supply_key), + key: supply_key, }; kv_keys.push(kv_key) } - NeutronMsg::register_interchain_query(QueryPayload::KV(kv_keys), connection_id, update_period) + register_interchain_query(contract, QueryPayload::KV(kv_keys), connection_id, update_period) } /// Creates a message to register an Interchain Query to get fee pool on remote chain from distribution module @@ -81,15 +83,17 @@ pub fn new_register_bank_total_supply_query_msg( /// * **connection_id** is an IBC connection identifier between Neutron and remote chain; /// * **update_period** is used to say how often the query must be updated. pub fn new_register_distribution_fee_pool_query_msg( + contract: Addr, connection_id: String, update_period: u64, -) -> NeutronResult { - let kv_key = KVKey { +) -> NeutronResult> { + let kv_key = KvKey { path: DISTRIBUTION_STORE_KEY.to_string(), - key: Binary::new(create_fee_pool_key()?), + key: create_fee_pool_key()?, }; - NeutronMsg::register_interchain_query( + register_interchain_query( + contract, QueryPayload::KV(vec![kv_key]), connection_id, update_period, @@ -102,13 +106,14 @@ pub fn new_register_distribution_fee_pool_query_msg( /// * **proposals_ids** is a list of proposals ids from remote chain. /// * **update_period** is used to say how often the query must be updated. pub fn new_register_gov_proposals_query_msg( + contract: Addr, connection_id: String, proposals_ids: Vec, update_period: u64, -) -> NeutronResult { +) -> NeutronResult> { let kv_keys = create_gov_proposal_keys(proposals_ids)?; - NeutronMsg::register_interchain_query(QueryPayload::KV(kv_keys), connection_id, update_period) + register_interchain_query(contract, QueryPayload::KV(kv_keys), connection_id, update_period) } /// Creates a message to update an Interchain Query to get governance proposals on remote chain @@ -117,13 +122,14 @@ pub fn new_register_gov_proposals_query_msg( /// * **proposals_ids** is a list of proposals ids from remote chain. /// * **new_update_period** is used to update period of how often the query must be updated. pub fn update_gov_proposals_query_msg( + contract: Addr, query_id: u64, proposals_ids: Vec, - new_update_period: Option, -) -> NeutronResult { + new_update_period: u64, +) -> NeutronResult> { let kv_keys = create_gov_proposal_keys(proposals_ids)?; - NeutronMsg::update_interchain_query(query_id, Some(kv_keys), new_update_period, None) + update_interchain_query(contract, query_id, kv_keys, new_update_period, None) } /// Creates a message to register an Interchain Query to get governance proposals votes on the remote chain @@ -133,14 +139,15 @@ pub fn update_gov_proposals_query_msg( /// * **voters** is a list of voter to get voting info from remote chain. /// * **update_period** is used to say how often the query must be updated. pub fn new_register_gov_proposals_voters_votes_query_msg( + contract: Addr, connection_id: String, proposals_ids: Vec, voters: Vec, update_period: u64, -) -> NeutronResult { +) -> NeutronResult> { let kv_keys = create_gov_proposals_voters_votes_keys(proposals_ids, voters)?; - NeutronMsg::register_interchain_query(QueryPayload::KV(kv_keys), connection_id, update_period) + register_interchain_query(contract, QueryPayload::KV(kv_keys), connection_id, update_period) } /// Creates a message to update an Interchain Query to get governance proposals votes on the remote chain @@ -150,14 +157,15 @@ pub fn new_register_gov_proposals_voters_votes_query_msg( /// * **voters** is a list of voter to get voting info from remote chain. /// * **new_update_period** is used to update period of how often the query must be updated. pub fn update_gov_proposals_votes_query_msg( + contract: Addr, query_id: u64, proposals_ids: Vec, voters: Vec, - new_update_period: Option, -) -> NeutronResult { + new_update_period: u64, +) -> NeutronResult> { let kv_keys = create_gov_proposals_voters_votes_keys(proposals_ids, voters)?; - NeutronMsg::update_interchain_query(query_id, Some(kv_keys), new_update_period, None) + update_interchain_query(contract, query_id, kv_keys, new_update_period, None) } /// Creates a message to register an Interchain Query to get validator info on remote chain @@ -166,24 +174,25 @@ pub fn update_gov_proposals_votes_query_msg( /// * **validator** is an validator operator address of an account on remote chain for which you want to get rewards ; /// * **update_period** is used to say how often the query must be updated. pub fn new_register_staking_validators_query_msg( + contract: Addr, connection_id: String, validators: Vec, update_period: u64, -) -> NeutronResult { - let mut kv_keys: Vec = Vec::with_capacity(validators.len()); +) -> NeutronResult> { + let mut kv_keys: Vec = Vec::with_capacity(validators.len()); for validator in validators { let val_addr = decode_and_convert(&validator)?; - let kv_key = KVKey { + let kv_key = KvKey { path: STAKING_STORE_KEY.to_string(), - key: Binary::new(create_validator_key(&val_addr)?), + key: create_validator_key(&val_addr)?, }; kv_keys.push(kv_key) } - NeutronMsg::register_interchain_query(QueryPayload::KV(kv_keys), connection_id, update_period) + register_interchain_query(contract, QueryPayload::KV(kv_keys), connection_id, update_period) } /// Creates a message to register an Interchain Query to get validators signing infos on remote chain @@ -192,24 +201,25 @@ pub fn new_register_staking_validators_query_msg( /// * **validators** is an list of validators valcons addresses of an account on remote chain for which you want to get rewards ; /// * **update_period** is used to say how often the query must be updated. pub fn new_register_validators_signing_infos_query_msg( + contract: Addr, connection_id: String, validators: Vec, update_period: u64, -) -> NeutronResult { - let mut kv_keys: Vec = Vec::with_capacity(validators.len()); +) -> NeutronResult> { + let mut kv_keys: Vec = Vec::with_capacity(validators.len()); for validator in validators { let valcons_addr = decode_and_convert(&validator)?; - let kv_key = KVKey { + let kv_key = KvKey { path: SLASHING_STORE_KEY.to_string(), - key: Binary::new(create_validator_signing_info_key(&valcons_addr)?), + key: create_validator_signing_info_key(&valcons_addr)?, }; kv_keys.push(kv_key) } - NeutronMsg::register_interchain_query(QueryPayload::KV(kv_keys), connection_id, update_period) + register_interchain_query(contract, QueryPayload::KV(kv_keys), connection_id, update_period) } /// Creates a message to register an Interchain Query to get delegations of particular delegator on remote chain. @@ -219,42 +229,43 @@ pub fn new_register_validators_signing_infos_query_msg( /// * **validators** is a list of validators addresses for which you want to get delegations from particular **delegator**; /// * **update_period** is used to say how often the query must be updated. pub fn new_register_delegator_delegations_query_msg( + contract: Addr, connection_id: String, delegator: String, validators: Vec, update_period: u64, -) -> NeutronResult { +) -> NeutronResult> { let delegator_addr = decode_and_convert(&delegator)?; // Allocate memory for such KV keys as: // * staking module params to get staking denomination // * validators structures to calculate amount of delegated tokens // * delegations structures to get info about delegations itself - let mut keys: Vec = Vec::with_capacity(validators.len() * 2 + 1); + let mut keys: Vec = Vec::with_capacity(validators.len() * 2 + 1); // create KV key to get BondDenom from staking module params - keys.push(KVKey { + keys.push(KvKey { path: PARAMS_STORE_KEY.to_string(), - key: Binary::new(create_params_store_key(STAKING_STORE_KEY, KEY_BOND_DENOM)), + key: create_params_store_key(STAKING_STORE_KEY, KEY_BOND_DENOM), }); for v in validators { let val_addr = decode_and_convert(&v)?; // create delegation key to get delegation structure - keys.push(KVKey { + keys.push(KvKey { path: STAKING_STORE_KEY.to_string(), - key: Binary::new(create_delegation_key(&delegator_addr, &val_addr)?), + key: create_delegation_key(&delegator_addr, &val_addr)?, }); // create validator key to get validator structure - keys.push(KVKey { + keys.push(KvKey { path: STAKING_STORE_KEY.to_string(), - key: Binary::new(create_validator_key(&val_addr)?), + key: create_validator_key(&val_addr)?, }) } - NeutronMsg::register_interchain_query(QueryPayload::KV(keys), connection_id, update_period) + register_interchain_query(contract, QueryPayload::KV(keys), connection_id, update_period) } /// Creates a message to register an Interchain Query to get unbonding delegations of particular delegator on remote chain. @@ -264,27 +275,28 @@ pub fn new_register_delegator_delegations_query_msg( /// * **validators** is a list of validators addresses for which you want to get unbonding delegations from particular **delegator**; /// * **update_period** is used to say how often the query must be updated. pub fn new_register_delegator_unbonding_delegations_query_msg( + contract: Addr, connection_id: String, delegator: String, validators: Vec, update_period: u64, -) -> NeutronResult { +) -> NeutronResult> { let delegator_addr = decode_and_convert(&delegator)?; // Allocate memory, one KV key per validator - let mut keys: Vec = Vec::with_capacity(validators.len()); + let mut keys: Vec = Vec::with_capacity(validators.len()); for v in validators { let val_addr = decode_and_convert(&v)?; // create unbonding delegation key to get unbonding delegation structure - keys.push(KVKey { + keys.push(KvKey { path: STAKING_STORE_KEY.to_string(), - key: Binary::new(create_unbonding_delegation_key(&delegator_addr, &val_addr)?), + key: create_unbonding_delegation_key(&delegator_addr, &val_addr)?, }) } - NeutronMsg::register_interchain_query(QueryPayload::KV(keys), connection_id, update_period) + register_interchain_query(contract, QueryPayload::KV(keys), connection_id, update_period) } /// Creates a message to register an Interchain Query to get wasm contract store on remote chain @@ -301,20 +313,22 @@ pub fn new_register_delegator_unbonding_delegations_query_msg( /// just by looking it. One could pipe this string into `| xxd -r -p | hexdump -C` and examine /// its contents. pub fn new_register_wasm_contract_store_query_msg( + contract: Addr, connection_id: String, contract_address: String, key: impl AsRef<[u8]>, update_period: u64, -) -> NeutronResult { +) -> NeutronResult> { let converted_addr_bytes = decode_and_convert(contract_address.as_str())?; let wasm_key = create_wasm_contract_store_key(converted_addr_bytes, key.as_ref())?; - let kv_key = KVKey { + let kv_key = KvKey { path: WASM_STORE_KEY.to_string(), - key: Binary::new(wasm_key), + key: wasm_key, }; - NeutronMsg::register_interchain_query( + register_interchain_query( + contract, QueryPayload::KV(vec![kv_key]), connection_id, update_period, @@ -328,11 +342,12 @@ pub fn new_register_wasm_contract_store_query_msg( /// * **update_period** is used to say how often the query must be updated. /// * **min_height** is used to set min height for query (by default = 0). pub fn new_register_transfers_query_msg( + contract: Addr, connection_id: String, recipient: String, update_period: u64, min_height: Option, -) -> NeutronResult { +) -> NeutronResult> { let mut query_data = vec![TransactionFilterItem { field: RECIPIENT_FIELD.to_string(), op: TransactionFilterOp::Eq, @@ -346,9 +361,75 @@ pub fn new_register_transfers_query_msg( }) } - NeutronMsg::register_interchain_query( + register_interchain_query( + contract, QueryPayload::TX(query_data), connection_id, update_period, ) } + +/// Basic helper to define a register interchain query message: +/// * **query** is a query type identifier ('tx' or 'kv' for now) with a payload: +/// - when the query enum is 'kv' then payload is the KV-storage keys for which we want to get +/// values from remote chain; +/// - when the query enum is 'tx' then payload is the filters for transaction search ICQ, +/// maximum allowed number of filters is 32. +/// * **connection_id** is an IBC connection identifier between Neutron and remote chain; +/// * **update_period** is used to say how often (in neutron blocks) the query must be updated. +fn register_interchain_query(contract: Addr, query: QueryPayload, connection_id: String, update_period: u64) -> NeutronResult> { + Ok(match query { + QueryPayload::KV(keys) => MsgRegisterInterchainQuery{ + sender: contract.to_string(), + query_type: QueryType::KV.to_string(), + keys, + transactions_filter: String::new(), + connection_id, + update_period, + }, + QueryPayload::TX(transactions_filters) => MsgRegisterInterchainQuery { + sender: contract.to_string(), + query_type: QueryType::TX.into(), + keys: vec![], + transactions_filter: to_string(&transactions_filters) + .map_err(|e| StdError::generic_err(e.to_string()))?, + connection_id, + update_period, + }, + }) +} + +/// Basic helper to define a update interchain query message: +/// * **query_id** is ID of the query we want to update; +/// * **new_keys** is encoded keys to query; +/// * **new_update_period** is used to say how often (in neutron blocks) the query must be updated. +pub fn update_interchain_query( + contract: Addr, + query_id: u64, + new_keys: Vec, + new_update_period: u64, + new_transactions_filter: Option>, +) -> NeutronResult> { + Ok(MsgUpdateInterchainQueryRequest { + sender: contract.to_string(), + query_id, + new_keys, + new_update_period, + new_transactions_filter: match new_transactions_filter { + Some(filters) => { + to_string(&filters).map_err(|e| StdError::generic_err(e.to_string()))? + } + // TODO: check if passing empty string is correct + None => "".to_string(), + }, + }) +} + +/// Basic helper to define a remove interchain query message: +/// * **query_id** is ID of the query we want to remove. +pub fn remove_interchain_query(contract: Addr, query_id: u64)-> NeutronResult> { + Ok(MsgRemoveInterchainQueryRequest { + sender: contract.to_string(), + query_id, + }) +}