diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9b8b1327eb..28dd093ff0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,8 +12,10 @@ and this project adheres to
 
 - cosmwasm-schema: The schema export now doesn't overwrite existing
   `additionalProperties` values anymore ([#2310])
+- cosmwasm-std: Added new `EurekaMsg` and `CosmosMsg::Eureka` variant ([#2340])
 
 [#2310]: https://github.com/CosmWasm/cosmwasm/pull/2310
+[#2340]: https://github.com/CosmWasm/cosmwasm/pull/2340
 
 ## [2.2.0] - 2024-12-17
 
diff --git a/contracts/ibc-reflect-send/schema/ibc-reflect-send.json b/contracts/ibc-reflect-send/schema/ibc-reflect-send.json
index 3c91ffab8e..20780b05b7 100644
--- a/contracts/ibc-reflect-send/schema/ibc-reflect-send.json
+++ b/contracts/ibc-reflect-send/schema/ibc-reflect-send.json
@@ -305,6 +305,18 @@
               }
             },
             "additionalProperties": false
+          },
+          {
+            "type": "object",
+            "required": [
+              "eureka"
+            ],
+            "properties": {
+              "eureka": {
+                "$ref": "#/definitions/EurekaMsg"
+              }
+            },
+            "additionalProperties": false
           }
         ]
       },
@@ -364,6 +376,78 @@
         "type": "object",
         "additionalProperties": false
       },
+      "EurekaMsg": {
+        "description": "These are messages in the IBC lifecycle using the new Eureka approach. Only usable by IBC-enabled contracts",
+        "oneOf": [
+          {
+            "description": "Sends an IBC packet with given payloads over the existing channel.",
+            "type": "object",
+            "required": [
+              "send_packet"
+            ],
+            "properties": {
+              "send_packet": {
+                "type": "object",
+                "required": [
+                  "channel_id",
+                  "payloads",
+                  "timeout"
+                ],
+                "properties": {
+                  "channel_id": {
+                    "description": "existing channel to send the tokens over",
+                    "type": "string"
+                  },
+                  "payloads": {
+                    "type": "array",
+                    "items": {
+                      "$ref": "#/definitions/EurekaPayload"
+                    }
+                  },
+                  "timeout": {
+                    "$ref": "#/definitions/Timestamp"
+                  }
+                },
+                "additionalProperties": false
+              }
+            },
+            "additionalProperties": false
+          }
+        ]
+      },
+      "EurekaPayload": {
+        "description": "Payload value should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.",
+        "type": "object",
+        "required": [
+          "destination_port",
+          "encoding",
+          "value",
+          "version"
+        ],
+        "properties": {
+          "destination_port": {
+            "description": "The port id on the chain where the packet is sent to (external chain).",
+            "type": "string"
+          },
+          "encoding": {
+            "description": "Encoding used to serialize the [EurekaPayload::value].",
+            "type": "string"
+          },
+          "value": {
+            "description": "Encoded payload data.",
+            "allOf": [
+              {
+                "$ref": "#/definitions/Binary"
+              }
+            ]
+          },
+          "version": {
+            "description": "Version of the receiving contract.",
+            "type": "string"
+          }
+        },
+        "additionalProperties": false
+      },
       "GovMsg": {
         "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ #     HexBinary, #     Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, #     Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result<Response, StdError> { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, option: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ #     HexBinary, #     Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, #     Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result<Response, StdError> { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```",
         "oneOf": [
diff --git a/contracts/ibc-reflect-send/schema/ibc/packet_msg.json b/contracts/ibc-reflect-send/schema/ibc/packet_msg.json
index 974ced2dc5..d8dffd2c17 100644
--- a/contracts/ibc-reflect-send/schema/ibc/packet_msg.json
+++ b/contracts/ibc-reflect-send/schema/ibc/packet_msg.json
@@ -246,6 +246,18 @@
             }
           },
           "additionalProperties": false
+        },
+        {
+          "type": "object",
+          "required": [
+            "eureka"
+          ],
+          "properties": {
+            "eureka": {
+              "$ref": "#/definitions/EurekaMsg"
+            }
+          },
+          "additionalProperties": false
         }
       ]
     },
@@ -305,6 +317,78 @@
       "type": "object",
       "additionalProperties": false
     },
+    "EurekaMsg": {
+      "description": "These are messages in the IBC lifecycle using the new Eureka approach. Only usable by IBC-enabled contracts",
+      "oneOf": [
+        {
+          "description": "Sends an IBC packet with given payloads over the existing channel.",
+          "type": "object",
+          "required": [
+            "send_packet"
+          ],
+          "properties": {
+            "send_packet": {
+              "type": "object",
+              "required": [
+                "channel_id",
+                "payloads",
+                "timeout"
+              ],
+              "properties": {
+                "channel_id": {
+                  "description": "existing channel to send the tokens over",
+                  "type": "string"
+                },
+                "payloads": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/definitions/EurekaPayload"
+                  }
+                },
+                "timeout": {
+                  "$ref": "#/definitions/Timestamp"
+                }
+              },
+              "additionalProperties": false
+            }
+          },
+          "additionalProperties": false
+        }
+      ]
+    },
+    "EurekaPayload": {
+      "description": "Payload value should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.",
+      "type": "object",
+      "required": [
+        "destination_port",
+        "encoding",
+        "value",
+        "version"
+      ],
+      "properties": {
+        "destination_port": {
+          "description": "The port id on the chain where the packet is sent to (external chain).",
+          "type": "string"
+        },
+        "encoding": {
+          "description": "Encoding used to serialize the [EurekaPayload::value].",
+          "type": "string"
+        },
+        "value": {
+          "description": "Encoded payload data.",
+          "allOf": [
+            {
+              "$ref": "#/definitions/Binary"
+            }
+          ]
+        },
+        "version": {
+          "description": "Version of the receiving contract.",
+          "type": "string"
+        }
+      },
+      "additionalProperties": false
+    },
     "GovMsg": {
       "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ #     HexBinary, #     Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, #     Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result<Response, StdError> { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, option: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ #     HexBinary, #     Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, #     Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result<Response, StdError> { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```",
       "oneOf": [
diff --git a/contracts/ibc-reflect-send/schema/raw/execute.json b/contracts/ibc-reflect-send/schema/raw/execute.json
index 8841eded49..74ddd32026 100644
--- a/contracts/ibc-reflect-send/schema/raw/execute.json
+++ b/contracts/ibc-reflect-send/schema/raw/execute.json
@@ -294,6 +294,18 @@
             }
           },
           "additionalProperties": false
+        },
+        {
+          "type": "object",
+          "required": [
+            "eureka"
+          ],
+          "properties": {
+            "eureka": {
+              "$ref": "#/definitions/EurekaMsg"
+            }
+          },
+          "additionalProperties": false
         }
       ]
     },
@@ -353,6 +365,78 @@
       "type": "object",
       "additionalProperties": false
     },
+    "EurekaMsg": {
+      "description": "These are messages in the IBC lifecycle using the new Eureka approach. Only usable by IBC-enabled contracts",
+      "oneOf": [
+        {
+          "description": "Sends an IBC packet with given payloads over the existing channel.",
+          "type": "object",
+          "required": [
+            "send_packet"
+          ],
+          "properties": {
+            "send_packet": {
+              "type": "object",
+              "required": [
+                "channel_id",
+                "payloads",
+                "timeout"
+              ],
+              "properties": {
+                "channel_id": {
+                  "description": "existing channel to send the tokens over",
+                  "type": "string"
+                },
+                "payloads": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/definitions/EurekaPayload"
+                  }
+                },
+                "timeout": {
+                  "$ref": "#/definitions/Timestamp"
+                }
+              },
+              "additionalProperties": false
+            }
+          },
+          "additionalProperties": false
+        }
+      ]
+    },
+    "EurekaPayload": {
+      "description": "Payload value should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.",
+      "type": "object",
+      "required": [
+        "destination_port",
+        "encoding",
+        "value",
+        "version"
+      ],
+      "properties": {
+        "destination_port": {
+          "description": "The port id on the chain where the packet is sent to (external chain).",
+          "type": "string"
+        },
+        "encoding": {
+          "description": "Encoding used to serialize the [EurekaPayload::value].",
+          "type": "string"
+        },
+        "value": {
+          "description": "Encoded payload data.",
+          "allOf": [
+            {
+              "$ref": "#/definitions/Binary"
+            }
+          ]
+        },
+        "version": {
+          "description": "Version of the receiving contract.",
+          "type": "string"
+        }
+      },
+      "additionalProperties": false
+    },
     "GovMsg": {
       "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ #     HexBinary, #     Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, #     Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result<Response, StdError> { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, option: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ #     HexBinary, #     Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, #     Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result<Response, StdError> { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```",
       "oneOf": [
diff --git a/contracts/ibc-reflect/schema/ibc/packet_msg.json b/contracts/ibc-reflect/schema/ibc/packet_msg.json
index eec0371bd4..84a3308aeb 100644
--- a/contracts/ibc-reflect/schema/ibc/packet_msg.json
+++ b/contracts/ibc-reflect/schema/ibc/packet_msg.json
@@ -322,6 +322,18 @@
             }
           },
           "additionalProperties": false
+        },
+        {
+          "type": "object",
+          "required": [
+            "eureka"
+          ],
+          "properties": {
+            "eureka": {
+              "$ref": "#/definitions/EurekaMsg"
+            }
+          },
+          "additionalProperties": false
         }
       ]
     },
@@ -334,6 +346,78 @@
       "type": "object",
       "additionalProperties": false
     },
+    "EurekaMsg": {
+      "description": "These are messages in the IBC lifecycle using the new Eureka approach. Only usable by IBC-enabled contracts",
+      "oneOf": [
+        {
+          "description": "Sends an IBC packet with given payloads over the existing channel.",
+          "type": "object",
+          "required": [
+            "send_packet"
+          ],
+          "properties": {
+            "send_packet": {
+              "type": "object",
+              "required": [
+                "channel_id",
+                "payloads",
+                "timeout"
+              ],
+              "properties": {
+                "channel_id": {
+                  "description": "existing channel to send the tokens over",
+                  "type": "string"
+                },
+                "payloads": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/definitions/EurekaPayload"
+                  }
+                },
+                "timeout": {
+                  "$ref": "#/definitions/Timestamp"
+                }
+              },
+              "additionalProperties": false
+            }
+          },
+          "additionalProperties": false
+        }
+      ]
+    },
+    "EurekaPayload": {
+      "description": "Payload value should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.",
+      "type": "object",
+      "required": [
+        "destination_port",
+        "encoding",
+        "value",
+        "version"
+      ],
+      "properties": {
+        "destination_port": {
+          "description": "The port id on the chain where the packet is sent to (external chain).",
+          "type": "string"
+        },
+        "encoding": {
+          "description": "Encoding used to serialize the [EurekaPayload::value].",
+          "type": "string"
+        },
+        "value": {
+          "description": "Encoded payload data.",
+          "allOf": [
+            {
+              "$ref": "#/definitions/Binary"
+            }
+          ]
+        },
+        "version": {
+          "description": "Version of the receiving contract.",
+          "type": "string"
+        }
+      },
+      "additionalProperties": false
+    },
     "GovMsg": {
       "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ #     HexBinary, #     Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, #     Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result<Response, StdError> { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, option: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ #     HexBinary, #     Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, #     Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result<Response, StdError> { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```",
       "oneOf": [
diff --git a/contracts/reflect/schema/raw/execute.json b/contracts/reflect/schema/raw/execute.json
index 60689b4e44..c10c85b84f 100644
--- a/contracts/reflect/schema/raw/execute.json
+++ b/contracts/reflect/schema/raw/execute.json
@@ -294,6 +294,18 @@
             }
           },
           "additionalProperties": false
+        },
+        {
+          "type": "object",
+          "required": [
+            "eureka"
+          ],
+          "properties": {
+            "eureka": {
+              "$ref": "#/definitions/EurekaMsg"
+            }
+          },
+          "additionalProperties": false
         }
       ]
     },
@@ -407,6 +419,78 @@
         }
       ]
     },
+    "EurekaMsg": {
+      "description": "These are messages in the IBC lifecycle using the new Eureka approach. Only usable by IBC-enabled contracts",
+      "oneOf": [
+        {
+          "description": "Sends an IBC packet with given payloads over the existing channel.",
+          "type": "object",
+          "required": [
+            "send_packet"
+          ],
+          "properties": {
+            "send_packet": {
+              "type": "object",
+              "required": [
+                "channel_id",
+                "payloads",
+                "timeout"
+              ],
+              "properties": {
+                "channel_id": {
+                  "description": "existing channel to send the tokens over",
+                  "type": "string"
+                },
+                "payloads": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/definitions/EurekaPayload"
+                  }
+                },
+                "timeout": {
+                  "$ref": "#/definitions/Timestamp"
+                }
+              },
+              "additionalProperties": false
+            }
+          },
+          "additionalProperties": false
+        }
+      ]
+    },
+    "EurekaPayload": {
+      "description": "Payload value should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.",
+      "type": "object",
+      "required": [
+        "destination_port",
+        "encoding",
+        "value",
+        "version"
+      ],
+      "properties": {
+        "destination_port": {
+          "description": "The port id on the chain where the packet is sent to (external chain).",
+          "type": "string"
+        },
+        "encoding": {
+          "description": "Encoding used to serialize the [EurekaPayload::value].",
+          "type": "string"
+        },
+        "value": {
+          "description": "Encoded payload data.",
+          "allOf": [
+            {
+              "$ref": "#/definitions/Binary"
+            }
+          ]
+        },
+        "version": {
+          "description": "Version of the receiving contract.",
+          "type": "string"
+        }
+      },
+      "additionalProperties": false
+    },
     "GovMsg": {
       "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ #     HexBinary, #     Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, #     Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result<Response, StdError> { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, option: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ #     HexBinary, #     Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, #     Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result<Response, StdError> { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```",
       "oneOf": [
diff --git a/contracts/reflect/schema/reflect.json b/contracts/reflect/schema/reflect.json
index 9a4c0e5364..56a789bf6d 100644
--- a/contracts/reflect/schema/reflect.json
+++ b/contracts/reflect/schema/reflect.json
@@ -304,6 +304,18 @@
               }
             },
             "additionalProperties": false
+          },
+          {
+            "type": "object",
+            "required": [
+              "eureka"
+            ],
+            "properties": {
+              "eureka": {
+                "$ref": "#/definitions/EurekaMsg"
+              }
+            },
+            "additionalProperties": false
           }
         ]
       },
@@ -417,6 +429,78 @@
           }
         ]
       },
+      "EurekaMsg": {
+        "description": "These are messages in the IBC lifecycle using the new Eureka approach. Only usable by IBC-enabled contracts",
+        "oneOf": [
+          {
+            "description": "Sends an IBC packet with given payloads over the existing channel.",
+            "type": "object",
+            "required": [
+              "send_packet"
+            ],
+            "properties": {
+              "send_packet": {
+                "type": "object",
+                "required": [
+                  "channel_id",
+                  "payloads",
+                  "timeout"
+                ],
+                "properties": {
+                  "channel_id": {
+                    "description": "existing channel to send the tokens over",
+                    "type": "string"
+                  },
+                  "payloads": {
+                    "type": "array",
+                    "items": {
+                      "$ref": "#/definitions/EurekaPayload"
+                    }
+                  },
+                  "timeout": {
+                    "$ref": "#/definitions/Timestamp"
+                  }
+                },
+                "additionalProperties": false
+              }
+            },
+            "additionalProperties": false
+          }
+        ]
+      },
+      "EurekaPayload": {
+        "description": "Payload value should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.",
+        "type": "object",
+        "required": [
+          "destination_port",
+          "encoding",
+          "value",
+          "version"
+        ],
+        "properties": {
+          "destination_port": {
+            "description": "The port id on the chain where the packet is sent to (external chain).",
+            "type": "string"
+          },
+          "encoding": {
+            "description": "Encoding used to serialize the [EurekaPayload::value].",
+            "type": "string"
+          },
+          "value": {
+            "description": "Encoded payload data.",
+            "allOf": [
+              {
+                "$ref": "#/definitions/Binary"
+              }
+            ]
+          },
+          "version": {
+            "description": "Version of the receiving contract.",
+            "type": "string"
+          }
+        },
+        "additionalProperties": false
+      },
       "GovMsg": {
         "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ #     HexBinary, #     Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, #     Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result<Response, StdError> { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, option: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ #     HexBinary, #     Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, #     Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result<Response, StdError> { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```",
         "oneOf": [
diff --git a/packages/std/src/eureka.rs b/packages/std/src/eureka.rs
new file mode 100644
index 0000000000..14c1e916e3
--- /dev/null
+++ b/packages/std/src/eureka.rs
@@ -0,0 +1,53 @@
+use schemars::JsonSchema;
+use serde::{Deserialize, Serialize};
+
+use crate::{Binary, Timestamp};
+
+/// Payload value should be encoded in a format defined by the channel version,
+/// and the module on the other side should know how to parse this.
+#[non_exhaustive]
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
+#[serde(rename_all = "snake_case")]
+pub struct EurekaPayload {
+    /// The port id on the chain where the packet is sent to (external chain).
+    pub destination_port: String,
+    /// Version of the receiving contract.
+    pub version: String,
+    /// Encoding used to serialize the [EurekaPayload::value].
+    pub encoding: String,
+    /// Encoded payload data.
+    pub value: Binary,
+}
+
+/// These are messages in the IBC lifecycle using the new Eureka approach. Only usable by IBC-enabled contracts
+#[non_exhaustive]
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
+#[serde(rename_all = "snake_case")]
+pub enum EurekaMsg {
+    /// Sends an IBC packet with given payloads over the existing channel.
+    SendPacket {
+        /// existing channel to send the tokens over
+        channel_id: String,
+        timeout: Timestamp,
+        payloads: Vec<EurekaPayload>,
+    },
+}
+
+#[cfg(test)]
+mod tests {
+    use serde_json::to_string;
+
+    use crate::EurekaPayload;
+
+    #[test]
+    fn eureka_payload_serialize() {
+        let packet = EurekaPayload {
+            destination_port: "receiving-contract-port".to_string(),
+            version: "v1".to_string(),
+            encoding: "json".to_string(),
+            value: b"foo".into(),
+        };
+        let expected = r#"{"destination_port":"receiving-contract-port","version":"v1","encoding":"json","value":"Zm9v"}"#;
+        assert_eq!(to_string(&packet).unwrap(), expected);
+    }
+}
diff --git a/packages/std/src/lib.rs b/packages/std/src/lib.rs
index eede5242a0..df970fa6eb 100644
--- a/packages/std/src/lib.rs
+++ b/packages/std/src/lib.rs
@@ -21,6 +21,7 @@ mod conversion;
 mod deps;
 mod encoding;
 mod errors;
+mod eureka;
 mod forward_ref;
 mod hex_binary;
 mod ibc;
@@ -65,6 +66,7 @@ pub use crate::errors::{
     RecoverPubkeyError, RoundDownOverflowError, RoundUpOverflowError, StdError, StdResult,
     SystemError, VerificationError,
 };
+pub use crate::eureka::{EurekaMsg, EurekaPayload};
 pub use crate::hex_binary::HexBinary;
 pub use crate::ibc::IbcChannelOpenResponse;
 pub use crate::ibc::{
diff --git a/packages/std/src/results/cosmos_msg.rs b/packages/std/src/results/cosmos_msg.rs
index 92af1d7b6f..7ee12c33ed 100644
--- a/packages/std/src/results/cosmos_msg.rs
+++ b/packages/std/src/results/cosmos_msg.rs
@@ -6,6 +6,7 @@ use schemars::JsonSchema;
 use serde::{Deserialize, Serialize};
 
 use crate::coin::Coin;
+use crate::eureka::EurekaMsg;
 #[cfg(feature = "stargate")]
 use crate::ibc::IbcMsg;
 use crate::prelude::*;
@@ -84,6 +85,7 @@ pub enum CosmosMsg<T = Empty> {
     Wasm(WasmMsg),
     #[cfg(feature = "stargate")]
     Gov(GovMsg),
+    Eureka(EurekaMsg),
 }
 
 impl<T> CosmosMsg<T> {
@@ -108,6 +110,7 @@ impl<T> CosmosMsg<T> {
             CosmosMsg::Wasm(msg) => CosmosMsg::Wasm(msg),
             #[cfg(feature = "stargate")]
             CosmosMsg::Gov(msg) => CosmosMsg::Gov(msg),
+            CosmosMsg::Eureka(msg) => CosmosMsg::Eureka(msg),
         })
     }
 }
@@ -485,6 +488,12 @@ impl<T> From<GovMsg> for CosmosMsg<T> {
     }
 }
 
+impl<T> From<EurekaMsg> for CosmosMsg<T> {
+    fn from(msg: EurekaMsg) -> Self {
+        CosmosMsg::Eureka(msg)
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;