sv::override_entry_point
attribute
Use sv::override_entry_point
if you want to define an entry point of your contract yourself. This
way, the sv::entry_points
macro won't generate it for you. The entry point will
also be used as a dispatch method in the MultiTest
helpers generated by the contract
macro.
Use this attribute if you provide some custom logic in the entry points. Otherwise, the
MultiTest
helpers won't cover that logic, and thus you will miss the
coverage.
Macros
List of macros supporting the sv::override_entry_point
attribute:
Usage
use self::sv::ContractExecMsg;
pub mod entrypoints {
use super::*;
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: ContractExecMsg,
) -> StdResult<Response> {
msg.dispatch(&CounterContract, (deps, env, info))
}
}
pub struct CounterContract;
#[cw_serde]
pub struct SomeResponse;
#[cfg_attr(feature = "library", sylvia::entry_points)]
#[contract]
#[sv::override_entry_point(exec=entrypoints::execute(ContractExecMsg))]
impl CounterContract {
pub const fn new() -> Self {
Self
}
#[sv::msg(instantiate)]
fn instantiate(&self, ctx: InstantiateCtx) -> StdResult<Response> {
Ok(Response::new())
}
}
First, the sv::override_entry_point
attribute expects the entry point type to override. Supported
types are:
instantiate
exec
query
sudo
migrate
reply
Next, we have to provide the path to the new entry point method prefixed with the =
character.
Lastly, this attribute expects the message type the entry point expects. This allows customization of the message used by the contract. If, for example your contract functionality would be extended by another contract stored as its field, it would be possible to wrap both contract messages and use that in the entry point.
An example of such an approach:
use self::sv::ContractExecMsg;
pub mod entrypoints {
use sylvia::cw_std::{entry_point, DepsMut, Env, MessageInfo};
use super::*;
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: WrapperExecMsg,
) -> StdResult<Response> {
msg.dispatch(&CounterContract, (deps, env, info).into())
}
}
/// ExecMsg from an external contract
#[cw_serde]
pub enum ExternalExecMsg {
MsgVariant {},
}
/// Wrapper around local and external contracts ExecMsgs
#[cw_serde]
pub enum WrapperExecMsg {
Local(ContractExecMsg),
External(ExternalExecMsg),
}
/// Custom dispatch to local or external contract
impl WrapperExecMsg {
pub fn dispatch(&self, contract: &CounterContract, ctx: ExecCtx) -> StdResult<Response> {
match self {
WrapperExecMsg::Local(_) => todo!(),
WrapperExecMsg::External(_) => todo!(),
}
}
}
pub struct CounterContract;
#[cw_serde]
pub struct SomeResponse;
#[contract]
#[sv::override_entry_point(exec=entrypoints::execute(WrapperExecMsg))]
impl CounterContract {
pub const fn new() -> Self {
Self
}
#[sv::msg(instantiate)]
fn instantiate(&self, ctx: InstantiateCtx) -> StdResult<Response> {
Ok(Response::new())
}
}