Skip to content

IBC Enabled Solidity

Enabling IBC for Solidity contracts has never been easier. We provide a simple interface for IBC Channel/Packet lifecycle that protocols must implement in order to open channels, send and receive packets.

The interface is following the official IBC ICS26 specification

IIBCModule.sol
pragma solidity ^0.8.23;
import "../../proto/ibc/core/channel/v1/channel.sol";
// IIBCModule defines an interface that implements all the callbacks
// that modules must define as specified in ICS-26
// https://github.com/cosmos/ibc/blob/2921c5cec7b18e4ef77677e16a6b693051ae3b35/spec/core/ics-026-routing-module/README.md
interface IIBCModule {
function onChanOpenInit(
IbcCoreChannelV1GlobalEnums.Order,
string[] calldata connectionHops,
string calldata portId,
string calldata channelId,
IbcCoreChannelV1Counterparty.Data calldata counterparty,
string calldata version
) external;
function onChanOpenTry(
IbcCoreChannelV1GlobalEnums.Order,
string[] calldata connectionHops,
string calldata portId,
string calldata channelId,
IbcCoreChannelV1Counterparty.Data calldata counterparty,
string calldata version,
string calldata counterpartyVersion
) external;
function onChanOpenAck(
string calldata portId,
string calldata channelId,
string calldata counterpartyChannelId,
string calldata counterpartyVersion
) external;
function onChanOpenConfirm(
string calldata portId,
string calldata channelId
) external;
function onChanCloseInit(
string calldata portId,
string calldata channelId
) external;
function onChanCloseConfirm(
string calldata portId,
string calldata channelId
) external;
function onRecvPacket(
IbcCoreChannelV1Packet.Data calldata,
address relayer
) external returns (bytes memory);
function onAcknowledgementPacket(
IbcCoreChannelV1Packet.Data calldata,
bytes calldata acknowledgement,
address relayer
) external;
function onTimeoutPacket(
IbcCoreChannelV1Packet.Data calldata,
address relayer
) external;
}

On top of this interface, we also provide an abstract contract that we recommend to use.

Base.sol
pragma solidity ^0.8.23;
import "../core/05-port/IIBCModule.sol";
library IBCAppLib {
error ErrNotIBC();
}
/**
* @dev Base contract of the IBC App protocol
*/
abstract contract IBCAppBase is IIBCModule {
/**
* @dev Throws if called by any account other than the IBC contract.
*/
modifier onlyIBC() {
_checkIBC();
_;
}
/**
* @dev Returns the address of the IBC contract.
*/
function ibcAddress() public view virtual returns (address);
/**
* @dev Throws if the sender is not the IBC contract.
*/
function _checkIBC() internal view virtual {
if (ibcAddress() != msg.sender) {
revert IBCAppLib.ErrNotIBC();
}
}
/**
* @dev See IIBCModule-onChanOpenInit
*
* NOTE: You should apply an `onlyIBC` modifier to the function if a derived contract overrides it.
*/
function onChanOpenInit(
IbcCoreChannelV1GlobalEnums.Order,
string[] calldata connectionHops,
string calldata portId,
string calldata channelId,
IbcCoreChannelV1Counterparty.Data calldata counterpartyEndpoint,
string calldata version
) external virtual override onlyIBC {}
/**
* @dev See IIBCModule-onChanOpenTry
*
* NOTE: You should apply an `onlyIBC` modifier to the function if a derived contract overrides it.
*/
function onChanOpenTry(
IbcCoreChannelV1GlobalEnums.Order,
string[] calldata connectionHops,
string calldata portId,
string calldata channelId,
IbcCoreChannelV1Counterparty.Data calldata counterpartyEndpoint,
string calldata version,
string calldata counterpartyVersion
) external virtual override onlyIBC {}
/**
* @dev See IIBCModule-onChanOpenAck
*
* NOTE: You should apply an `onlyIBC` modifier to the function if a derived contract overrides it.
*/
function onChanOpenAck(
string calldata portId,
string calldata channelId,
string calldata counterpartyChannelId,
string calldata counterpartyVersion
) external virtual override onlyIBC {}
/**
* @dev See IIBCModule-onChanOpenConfirm
*
* NOTE: You should apply an `onlyIBC` modifier to the function if a derived contract overrides it.
*/
function onChanOpenConfirm(
string calldata portId,
string calldata channelId
) external virtual override onlyIBC {}
/**
* @dev See IIBCModule-onChanCloseInit
*
* NOTE: You should apply an `onlyIBC` modifier to the function if a derived contract overrides it.
*/
function onChanCloseInit(
string calldata portId,
string calldata channelId
) external virtual override onlyIBC {}
/**
* @dev See IIBCModule-onChanCloseConfirm
*
* NOTE: You should apply an `onlyIBC` modifier to the function if a derived contract overrides it.
*/
function onChanCloseConfirm(
string calldata portId,
string calldata channelId
) external virtual override onlyIBC {}
/**
* @dev See IIBCModule-onRecvPacket
*
* NOTE: You should apply an `onlyIBC` modifier to the function if a derived contract overrides it.
*/
function onRecvPacket(
IbcCoreChannelV1Packet.Data calldata packet,
address relayer
)
external
virtual
override
onlyIBC
returns (bytes memory acknowledgement)
{}
/**
* @dev See IIBCModule-onAcknowledgementPacket
*
* NOTE: You should apply an `onlyIBC` modifier to the function if a derived contract overrides it.
*/
function onAcknowledgementPacket(
IbcCoreChannelV1Packet.Data calldata packet,
bytes calldata acknowledgement,
address relayer
) external virtual override onlyIBC {}
/**
* @dev See IIBCModule-onTimeoutPacket
*
* NOTE: You should apply an `onlyIBC` modifier to the function if a derived contract overrides it.
*/
function onTimeoutPacket(
IbcCoreChannelV1Packet.Data calldata packet,
address relayer
) external virtual override onlyIBC {}
}