Skip to content

Commit

Permalink
refactor query min ibc fee helper. improve comments
Browse files Browse the repository at this point in the history
  • Loading branch information
NeverHappened committed Oct 28, 2024
1 parent 7d44584 commit 67f20b6
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 100 deletions.
49 changes: 2 additions & 47 deletions contracts/ibc_transfer/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ use cosmwasm_std::{
StdResult, SubMsg,
};
use cw2::set_contract_version;
use neutron_sdk::interchain_txs::helpers::decode_message_response;
use neutron_sdk::interchain_txs::helpers::{decode_message_response, query_denom_min_ibc_fee};
use neutron_sdk::sudo::msg::{RequestPacket, TransferSudoMsg};
use neutron_std::types::cosmos::base::v1beta1::Coin as SDKCoin;
use neutron_std::types::neutron::feerefunder::{Fee, FeerefunderQuerier};
use neutron_std::types::neutron::transfer::{MsgTransfer, MsgTransferResponse};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -141,7 +140,7 @@ fn execute_send(
) -> StdResult<Response> {
// contract must pay for relaying of acknowledgements
// See more info here: https://docs.neutron.org/neutron/feerefunder/overview
let fee = min_ntrn_ibc_fee(query_min_fee(deps.as_ref())?);
let fee = query_denom_min_ibc_fee(deps.as_ref(), FEE_DENOM)?;
let msg1 = MsgTransfer {
source_port: "transfer".to_string(),
source_channel: channel.clone(),
Expand Down Expand Up @@ -270,47 +269,3 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult<Response
deps.api.debug("WASMDEBUG: migrate");
Ok(Response::default())
}

fn query_min_fee(deps: Deps) -> StdResult<Fee> {
let querier = FeerefunderQuerier::new(&deps.querier);
let params = querier.params()?;
let params_inner = params
.params
.ok_or_else(|| StdError::generic_err("no params found for feerefunder"))?;
let min_fee = params_inner
.min_fee
.ok_or_else(|| StdError::generic_err("no minimum fee param for feerefunder"))?;

Ok(min_fee)
}

fn min_ntrn_ibc_fee(fee: Fee) -> Fee {
Fee {
recv_fee: fee
.recv_fee
.iter()
.map(|r| SDKCoin {
denom: r.denom.to_string(),
amount: r.amount.clone(),
})
.collect(),
ack_fee: fee
.ack_fee
.iter()
.map(|r| SDKCoin {
denom: r.denom.to_string(),
amount: r.amount.clone(),
})
.filter(|a| a.denom == FEE_DENOM)
.collect(),
timeout_fee: fee
.timeout_fee
.iter()
.map(|r| SDKCoin {
denom: r.denom.to_string(),
amount: r.amount.clone(),
})
.filter(|a| a.denom == FEE_DENOM)
.collect(),
}
}
54 changes: 5 additions & 49 deletions contracts/neutron_interchain_txs/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ use cosmwasm_std::{
Response, StdError, StdResult, SubMsg,
};
use cw2::set_contract_version;
use neutron_sdk::interchain_txs::helpers::{register_interchain_account, submit_tx};
use neutron_sdk::interchain_txs::helpers::{
query_denom_min_ibc_fee, register_interchain_account, submit_tx,
};
use neutron_sdk::{
interchain_txs::helpers::{decode_message_response, get_port_id},
interchain_txs::v047::helpers::decode_acknowledgement_response,
sudo::msg::{RequestPacket, SudoMsg},
NeutronError, NeutronResult,
};
use neutron_std::shim::Timestamp;
use neutron_std::types::cosmos::base::v1beta1::Coin as SDKCoin;
use neutron_std::types::cosmos::base::v1beta1::Coin;
use neutron_std::types::cosmos::staking::v1beta1::{
MsgDelegate, MsgDelegateResponse, MsgUndelegate, MsgUndelegateResponse,
};
use neutron_std::types::ibc::core::channel::v1::Order;
use neutron_std::types::neutron::feerefunder::{Fee, FeerefunderQuerier};
use neutron_std::types::neutron::interchaintxs::v1::{InterchaintxsQuerier, MsgSubmitTxResponse};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -222,7 +222,7 @@ fn execute_delegate(
) -> NeutronResult<Response> {
// contract must pay for relaying of acknowledgements
// See more info here: https://docs.neutron.org/neutron/feerefunder/overview
let fee = min_ntrn_ibc_fee(query_min_fee(deps.as_ref())?);
let fee = query_denom_min_ibc_fee(deps.as_ref(), FEE_DENOM)?;
let (delegator, connection_id) = get_ica(deps.as_ref(), &env, &interchain_account_id)?;
let delegate_msg = MsgDelegate {
delegator_address: delegator,
Expand Down Expand Up @@ -281,7 +281,7 @@ fn execute_undelegate(
) -> NeutronResult<Response> {
// contract must pay for relaying of acknowledgements
// See more info here: https://docs.neutron.org/neutron/feerefunder/overview
let fee = min_ntrn_ibc_fee(query_min_fee(deps.as_ref())?);
let fee = query_denom_min_ibc_fee(deps.as_ref(), FEE_DENOM)?;
let (delegator, connection_id) = get_ica(deps.as_ref(), &env, &interchain_account_id)?;
let delegate_msg = MsgUndelegate {
delegator_address: delegator,
Expand Down Expand Up @@ -629,47 +629,3 @@ pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> StdResult<Response> {
))),
}
}

fn min_ntrn_ibc_fee(fee: Fee) -> Fee {
Fee {
recv_fee: fee
.recv_fee
.iter()
.map(|r| SDKCoin {
denom: r.denom.to_string(),
amount: r.amount.clone(),
})
.collect(),
ack_fee: fee
.ack_fee
.iter()
.map(|r| SDKCoin {
denom: r.denom.to_string(),
amount: r.amount.clone(),
})
.filter(|a| a.denom == FEE_DENOM)
.collect(),
timeout_fee: fee
.timeout_fee
.iter()
.map(|r| SDKCoin {
denom: r.denom.to_string(),
amount: r.amount.clone(),
})
.filter(|a| a.denom == FEE_DENOM)
.collect(),
}
}

fn query_min_fee(deps: Deps) -> StdResult<Fee> {
let querier = FeerefunderQuerier::new(&deps.querier);
let params = querier.params()?;
let params_inner = params
.params
.ok_or_else(|| StdError::generic_err("no params found for feerefunder"))?;
let min_fee = params_inner
.min_fee
.ok_or_else(|| StdError::generic_err("no minimum fee param for feerefunder"))?;

Ok(min_fee)
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub fn new_register_balances_query_msg(

/// Creates a message to register an Interchain Query to get balance of account on remote chain for a particular denom
///
/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message.
/// * **connection_id** is an IBC connection identifier between Neutron and remote chain;
/// * **addr** address of an account on remote chain for which you want to get balances;
/// * **denom** denomination of the coin for which you want to get balance;
Expand All @@ -60,6 +61,7 @@ pub fn new_register_balance_query_msg(

/// Creates a message to register an Interchain Query to get total supply on remote chain for particular denom
///
/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message.
/// * **connection_id** is an IBC connection identifier between Neutron and remote chain;
/// * **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.
Expand Down Expand Up @@ -92,6 +94,7 @@ pub fn new_register_bank_total_supply_query_msg(

/// Creates a message to register an Interchain Query to get fee pool on remote chain from distribution module
///
/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message.
/// * **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(
Expand All @@ -114,6 +117,7 @@ pub fn new_register_distribution_fee_pool_query_msg(

/// Creates a message to register an Interchain Query to get governance proposals on remote chain
///
/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message.
/// * **connection_id** is an IBC connection identifier between Neutron and remote chain;
/// * **proposals_ids** is a list of proposals ids from remote chain.
/// * **update_period** is used to say how often the query must be updated.
Expand All @@ -135,6 +139,7 @@ pub fn new_register_gov_proposals_query_msg(

/// Creates a message to update an Interchain Query to get governance proposals on remote chain
///
/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message.
/// * **query_id** is an IBC connection identifier between Neutron and remote chain;
/// * **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.
Expand All @@ -151,6 +156,7 @@ pub fn update_gov_proposals_query_msg(

/// Creates a message to register an Interchain Query to get governance proposals votes on the remote chain
///
/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message.
/// * **connection_id** is an IBC connection identifier between Neutron and remote chain;
/// * **proposals_ids** is a list of proposals ids from remote chain.
/// * **voters** is a list of voter to get voting info from remote chain.
Expand All @@ -174,6 +180,7 @@ pub fn new_register_gov_proposals_voters_votes_query_msg(

/// Creates a message to update an Interchain Query to get governance proposals votes on the remote chain
///
/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message.
/// * **query_id** is an IBC connection identifier between Neutron and remote chain;
/// * **proposals_ids** is a list of proposals ids from remote chain.
/// * **voters** is a list of voter to get voting info from remote chain.
Expand All @@ -192,6 +199,7 @@ pub fn update_gov_proposals_votes_query_msg(

/// Creates a message to register an Interchain Query to get validator info on remote chain
///
/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message.
/// * **connection_id** is an IBC connection identifier between Neutron and remote chain;
/// * **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.
Expand Down Expand Up @@ -224,6 +232,7 @@ pub fn new_register_staking_validators_query_msg(

/// Creates a message to register an Interchain Query to get validators signing infos on remote chain
///
/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message.
/// * **connection_id** is an IBC connection identifier between Neutron and remote chain;
/// * **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.
Expand Down Expand Up @@ -256,6 +265,7 @@ pub fn new_register_validators_signing_infos_query_msg(

/// Creates a message to register an Interchain Query to get delegations of particular delegator on remote chain.
///
/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message.
/// * **connection_id** is an IBC connection identifier between Neutron and remote chain;
/// * **delegator** is an address of an account on remote chain for which you want to get list of delegations;
/// * **validators** is a list of validators addresses for which you want to get delegations from particular **delegator**;
Expand Down Expand Up @@ -307,6 +317,7 @@ pub fn new_register_delegator_delegations_query_msg(

/// Creates a message to register an Interchain Query to get unbonding delegations of particular delegator on remote chain.
///
/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message.
/// * **connection_id** is an IBC connection identifier between Neutron and remote chain;
/// * **delegator** is an address of an account on remote chain for which you want to get list of unbonding delegations;
/// * **validators** is a list of validators addresses for which you want to get unbonding delegations from particular **delegator**;
Expand Down Expand Up @@ -344,6 +355,7 @@ pub fn new_register_delegator_unbonding_delegations_query_msg(
/// Creates a message to register an Interchain Query to get wasm contract store on remote chain
/// from **wasm** module
///
/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message.
/// * **connection_id** is an IBC connection identifier between Neutron and remote chain;
/// * **contract_address** is an address of a contract on a remote chain;
/// * **key** is a wasm contract store key;
Expand Down Expand Up @@ -379,6 +391,7 @@ pub fn new_register_wasm_contract_store_query_msg(

/// Creates a message to register an Interchain Query to get transfer events to a recipient on a remote chain.
///
/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message.
/// * **connection_id** is an IBC connection identifier between Neutron and remote chain;
/// * **recipient** is an address of an account on remote chain for which you want to get list of transfer transactions;
/// * **update_period** is used to say how often the query must be updated.
Expand Down
52 changes: 48 additions & 4 deletions packages/neutron-sdk/src/interchain_txs/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use cosmos_sdk_proto::traits::Message;
use cosmwasm_std::{Addr, CosmosMsg, StdError, StdResult};
use cosmwasm_std::{Addr, CosmosMsg, Deps, StdError, StdResult};
use neutron_std::shim::Any;
use neutron_std::types::cosmos::base::v1beta1::Coin;
use neutron_std::types::ibc::core::channel::v1::Order;
use neutron_std::types::neutron::feerefunder::Fee;
use neutron_std::types::neutron::feerefunder::{Fee, FeerefunderQuerier};
use neutron_std::types::neutron::interchaintxs::v1::{MsgRegisterInterchainAccount, MsgSubmitTx};

/// Decodes protobuf any item into T structure
Expand All @@ -27,7 +27,8 @@ pub fn get_port_id<R: AsRef<str>>(contract_address: R, interchain_account_id: R)
+ interchain_account_id.as_ref()
}

/// Basic helper to define a register interchain account message:
/// Basic helper to define a register interchain account message.
///
/// * **contract** is a contract that registers ICA. Must be the contract address that sends this message.
/// * **connection_id** is an IBC connection identifier between Neutron and remote chain;
/// * **interchain_account_id** is an identifier of your new interchain account. Can be any string.
Expand All @@ -49,7 +50,8 @@ pub fn register_interchain_account(
.into()
}

/// Basic helper to define a submit tx message:
/// Basic helper to define a submit tx message.
///
/// * **contract** is a contract that is sending the message
/// * **connection_id** is an IBC connection identifier between Neutron and remote chain;
/// * **interchain_account_id** is an identifier of your interchain account from which you want to execute msgs;
Expand Down Expand Up @@ -77,3 +79,45 @@ pub fn submit_tx(
}
.into()
}

/// Queries chain for minimum fee for given denom. Returns Err if not found.
///
/// * **deps** is contract `Deps`
/// * **denom** is a denom which can be used. Function will return Err if denom is not in a list of fee denoms.
pub fn query_denom_min_ibc_fee(deps: Deps, denom: &str) -> StdResult<Fee> {
let fee = query_min_fee(deps)?;
Ok(Fee {
recv_fee: fee_with_denom(fee.recv_fee, denom)?,
ack_fee: fee_with_denom(fee.ack_fee, denom)?,
timeout_fee: fee_with_denom(fee.timeout_fee, denom)?,
})
}

/// Queries chain for all possible minimal fee. Each fee in Vec is a different denom.
///
/// * **deps** is contract `Deps`
pub fn query_min_fee(deps: Deps) -> StdResult<Fee> {
let querier = FeerefunderQuerier::new(&deps.querier);
let params = querier.params()?;
let params_inner = params
.params
.ok_or_else(|| StdError::generic_err("no params found for feerefunder"))?;
let min_fee = params_inner
.min_fee
.ok_or_else(|| StdError::generic_err("no minimum fee param for feerefunder"))?;

Ok(min_fee)
}

fn fee_with_denom(fee: Vec<Coin>, denom: &str) -> StdResult<Vec<Coin>> {
Ok(vec![fee
.iter()
.find(|a| a.denom == denom)
.map(|r| Coin {
denom: r.denom.to_string(),
amount: r.amount.clone(),
})
.ok_or_else(|| {
StdError::not_found(format!("cannot find fee for denom {}", denom))
})?])
}

0 comments on commit 67f20b6

Please sign in to comment.