diff --git a/contracts/ibc-callbacks/schema/ibc-callbacks.json b/contracts/ibc-callbacks/schema/ibc-callbacks.json index 1b78d6f77f..1916115d15 100644 --- a/contracts/ibc-callbacks/schema/ibc-callbacks.json +++ b/contracts/ibc-callbacks/schema/ibc-callbacks.json @@ -154,7 +154,7 @@ "additionalProperties": false }, "IbcDestinationChainCallbackMsg": { - "description": "The message type of the IBC destination chain callback.\n\nThe IBC destination chain callback is needed for cases where someone triggers the sending of an IBC packet through some other message (i.e. not through [`IbcMsg::SendPacket`]) and your contract needs to know that it received this. The callback is called after the packet was successfully acknowledged on the destination chain. A prominent example is the [`IbcMsg::Transfer`] message. Without callbacks, you cannot know that someone sent you IBC coins.\n\nNote that there are some prerequisites that need to be fulfilled to receive source chain callbacks: - The contract must implement the `ibc_destination_chain_callback` entrypoint. - The module that receives the packet must be wrapped by an `IBCMiddleware` (i.e. the destination chain needs to support callbacks for the message you are being sent). - You have to add json-encoded [`IbcCallbackData`] to a specific field of the message. For `IbcMsg::Transfer`, this is the `memo` field.", + "description": "The message type of the IBC destination chain callback.\n\nThe IBC destination chain callback is needed for cases where someone triggers the sending of an IBC packet through some other message (i.e. not through [`IbcMsg::SendPacket`]) and your contract needs to know that it received this. A prominent example is the [`IbcMsg::Transfer`] message. Without callbacks, you cannot know that someone sent you IBC coins.\n\nThe callback is called after the packet was acknowledged on the destination chain, as follows: - If the acknowledgement is synchronous (i.e. returned immediately when the packet is received), the callback is called only if the acknowledgement was successful. - If the acknowledgement is asynchronous (i.e. written later using `WriteAcknowledgement`), the callback is called regardless of the success of the acknowledgement.\n\nNote that there are some prerequisites that need to be fulfilled to receive source chain callbacks: - The contract must implement the `ibc_destination_chain_callback` entrypoint. - The module that receives the packet must be wrapped by an `IBCMiddleware` (i.e. the destination chain needs to support callbacks for the message you are being sent). - You have to add json-encoded [`IbcCallbackData`] to a specific field of the message. For `IbcMsg::Transfer`, this is the `memo` field.", "type": "object", "required": [ "ack", @@ -162,7 +162,7 @@ ], "properties": { "ack": { - "$ref": "#/definitions/IbcAcknowledgement" + "$ref": "#/definitions/IbcFullAcknowledgement" }, "packet": { "$ref": "#/definitions/IbcPacket" @@ -186,6 +186,29 @@ }, "additionalProperties": false }, + "IbcFullAcknowledgement": { + "description": "The acknowledgement written by the module on the destination chain. It is different from the [`IbcAcknowledgement`] as it can be unsuccessful.", + "type": "object", + "required": [ + "data", + "success" + ], + "properties": { + "data": { + "description": "The acknowledgement data returned by the module.", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "success": { + "description": "Whether the acknowledgement was successful or not.", + "type": "boolean" + } + }, + "additionalProperties": false + }, "IbcPacket": { "type": "object", "required": [ diff --git a/contracts/ibc-callbacks/schema/raw/response_to_callback_stats.json b/contracts/ibc-callbacks/schema/raw/response_to_callback_stats.json index 1fa32554c4..e1ed218865 100644 --- a/contracts/ibc-callbacks/schema/raw/response_to_callback_stats.json +++ b/contracts/ibc-callbacks/schema/raw/response_to_callback_stats.json @@ -51,7 +51,7 @@ "additionalProperties": false }, "IbcDestinationChainCallbackMsg": { - "description": "The message type of the IBC destination chain callback.\n\nThe IBC destination chain callback is needed for cases where someone triggers the sending of an IBC packet through some other message (i.e. not through [`IbcMsg::SendPacket`]) and your contract needs to know that it received this. The callback is called after the packet was successfully acknowledged on the destination chain. A prominent example is the [`IbcMsg::Transfer`] message. Without callbacks, you cannot know that someone sent you IBC coins.\n\nNote that there are some prerequisites that need to be fulfilled to receive source chain callbacks: - The contract must implement the `ibc_destination_chain_callback` entrypoint. - The module that receives the packet must be wrapped by an `IBCMiddleware` (i.e. the destination chain needs to support callbacks for the message you are being sent). - You have to add json-encoded [`IbcCallbackData`] to a specific field of the message. For `IbcMsg::Transfer`, this is the `memo` field.", + "description": "The message type of the IBC destination chain callback.\n\nThe IBC destination chain callback is needed for cases where someone triggers the sending of an IBC packet through some other message (i.e. not through [`IbcMsg::SendPacket`]) and your contract needs to know that it received this. A prominent example is the [`IbcMsg::Transfer`] message. Without callbacks, you cannot know that someone sent you IBC coins.\n\nThe callback is called after the packet was acknowledged on the destination chain, as follows: - If the acknowledgement is synchronous (i.e. returned immediately when the packet is received), the callback is called only if the acknowledgement was successful. - If the acknowledgement is asynchronous (i.e. written later using `WriteAcknowledgement`), the callback is called regardless of the success of the acknowledgement.\n\nNote that there are some prerequisites that need to be fulfilled to receive source chain callbacks: - The contract must implement the `ibc_destination_chain_callback` entrypoint. - The module that receives the packet must be wrapped by an `IBCMiddleware` (i.e. the destination chain needs to support callbacks for the message you are being sent). - You have to add json-encoded [`IbcCallbackData`] to a specific field of the message. For `IbcMsg::Transfer`, this is the `memo` field.", "type": "object", "required": [ "ack", @@ -59,7 +59,7 @@ ], "properties": { "ack": { - "$ref": "#/definitions/IbcAcknowledgement" + "$ref": "#/definitions/IbcFullAcknowledgement" }, "packet": { "$ref": "#/definitions/IbcPacket" @@ -83,6 +83,29 @@ }, "additionalProperties": false }, + "IbcFullAcknowledgement": { + "description": "The acknowledgement written by the module on the destination chain. It is different from the [`IbcAcknowledgement`] as it can be unsuccessful.", + "type": "object", + "required": [ + "data", + "success" + ], + "properties": { + "data": { + "description": "The acknowledgement data returned by the module.", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "success": { + "description": "Whether the acknowledgement was successful or not.", + "type": "boolean" + } + }, + "additionalProperties": false + }, "IbcPacket": { "type": "object", "required": [ diff --git a/packages/std/src/ibc/callbacks.rs b/packages/std/src/ibc/callbacks.rs index 6f42d8e118..52383b8d43 100644 --- a/packages/std/src/ibc/callbacks.rs +++ b/packages/std/src/ibc/callbacks.rs @@ -1,10 +1,11 @@ //! This module contains types for the IBC callbacks defined in //! [ADR-8](https://github.com/cosmos/ibc-go/blob/main/docs/architecture/adr-008-app-caller-cbs.md). +use cosmwasm_core::Binary; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use crate::{Addr, IbcAcknowledgement, IbcPacket, IbcPacketAckMsg, IbcPacketTimeoutMsg, Uint64}; +use crate::{Addr, IbcPacket, IbcPacketAckMsg, IbcPacketTimeoutMsg, Uint64}; /// This is just a type representing the data that has to be sent with the IBC message to receive /// callbacks. It should be serialized to JSON and sent with the IBC message. @@ -117,10 +118,15 @@ pub enum IbcSourceChainCallbackMsg { /// The IBC destination chain callback is needed for cases where someone triggers the sending of an /// IBC packet through some other message (i.e. not through [`IbcMsg::SendPacket`]) and /// your contract needs to know that it received this. -/// The callback is called after the packet was successfully acknowledged on the destination chain. /// A prominent example is the [`IbcMsg::Transfer`] message. Without callbacks, you cannot know /// that someone sent you IBC coins. /// +/// The callback is called after the packet was acknowledged on the destination chain, as follows: +/// - If the acknowledgement is synchronous (i.e. returned immediately when the packet is received), +/// the callback is called only if the acknowledgement was successful. +/// - If the acknowledgement is asynchronous (i.e. written later using `WriteAcknowledgement`), +/// the callback is called regardless of the success of the acknowledgement. +/// /// Note that there are some prerequisites that need to be fulfilled to receive source chain callbacks: /// - The contract must implement the `ibc_destination_chain_callback` entrypoint. /// - The module that receives the packet must be wrapped by an `IBCMiddleware` @@ -130,7 +136,17 @@ pub enum IbcSourceChainCallbackMsg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct IbcDestinationChainCallbackMsg { pub packet: IbcPacket, - pub ack: IbcAcknowledgement, + pub ack: IbcFullAcknowledgement, +} + +/// The acknowledgement written by the module on the destination chain. +/// It is different from the [`IbcAcknowledgement`] as it can be unsuccessful. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +pub struct IbcFullAcknowledgement { + /// The acknowledgement data returned by the module. + pub data: Binary, + /// Whether the acknowledgement was successful or not. + pub success: bool, } #[cfg(test)] diff --git a/packages/std/src/lib.rs b/packages/std/src/lib.rs index 634414b54b..01b923fc06 100644 --- a/packages/std/src/lib.rs +++ b/packages/std/src/lib.rs @@ -42,9 +42,9 @@ pub use crate::ibc::IbcChannelOpenResponse; pub use crate::ibc::{ Ibc3ChannelOpenResponse, IbcAcknowledgement, IbcBasicResponse, IbcCallbackData, IbcChannel, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcDestinationChainCallbackMsg, - IbcDstCallback, IbcEndpoint, IbcMsg, IbcOrder, IbcPacket, IbcPacketAckMsg, IbcPacketReceiveMsg, - IbcPacketTimeoutMsg, IbcReceiveResponse, IbcSourceChainCallbackMsg, IbcSrcCallback, IbcTimeout, - IbcTimeoutBlock, + IbcDstCallback, IbcEndpoint, IbcFullAcknowledgement, IbcMsg, IbcOrder, IbcPacket, + IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, + IbcSourceChainCallbackMsg, IbcSrcCallback, IbcTimeout, IbcTimeoutBlock, }; #[cfg(feature = "iterator")] pub use crate::iterator::{Order, Record}; diff --git a/packages/vm/testdata/ibc_callbacks.wasm b/packages/vm/testdata/ibc_callbacks.wasm index 1654a20476..66ef1bf4d0 100644 Binary files a/packages/vm/testdata/ibc_callbacks.wasm and b/packages/vm/testdata/ibc_callbacks.wasm differ