- ADR
- ADR-020: Cross-Chain Transfers
Status
In ProgressOverview
Types of Blockchains
- Int3face Chain - Bridge blockchain that connects all other blockchains.
- IBC-Connected Chain - Blockchain connected to Int3face Chain via IBC protocol.
- Bitfrost-Connected Chain - Blockchain connected to Int3face Chain via the custom off-chain Bi[t]frost protocol. We can refer here two types of chains in sort of asset origination:
- Native - Native for the asset; as example, Dogecoin for DOGE or Solana for SOL. Asset is presented as a native token on the chain.
- Non-Native - Not native for the asset; as example, Solana for DOGE or Solana for TON. Asset is presented as a self-deployed smart contract on the chain.
Bridging Routes
Int3face as Bridge
| Route | Description | Example |
|---|---|---|
| Bitfrost → Int3face → IBC | Transfer of assets from a Bitfrost-connected chain to an IBC chain via the Int3face chain. | Transfer of DOGE from Dogecoin to Osmosis. |
| IBC → Int3face → Bitfrost | Transfer of assets from an IBC-connected chain to a Bitfrost-connected chain via the Int3face chain. | Transfer of DOGE from Osmosis to Dogecoin. |
| Bitfrost → Int3face → Bitfrost | Transfer of assets from a Bitfrost-connected to a Bitfrost-connected chain via the Int3face chain. | Transfer of DOGE from Dogecoin to Solana. |
| IBC → Int3face → IBC | Transfer of assets from an IBC-connected chain to an IBC-connected chain via the Int3face chain. | Transfer of DOGE from Osmosis to CosmosHub. |
Int3face as Target|Source
| Route | Description | Example |
|---|---|---|
| IBC → Int3face | Transfer of assets from a IBC-connected chain to the Int3face chain. | Transfer of DOGE from Osmosis to Int3face Chain. |
| Int3face → IBC | Transfer of assets from the Int3face chain to an IBC-connected chain. | Transfer of DOGE from Int3face Chain to Osmosis. |
| Bitfrost → Int3face | Transfer of assets from a Bitfrost-connected chain to the Int3face chain. | Transfer of DOGE from Dogecoin to Int3face Chain. |
| Int3face → Bitfrost | Transfer of assets from the Int3face chain to a Bitfrost-connected chain. | Transfer of DOGE from Int3face Chain to Solana. |
Technical Outline
Int3face Bridge utilizes two protocols to facilitate cross-chain transfers:- IBC Protocol - Inter-Blockchain Communication protocol that allows the transfer of assets between two Cosmos-compatible chains.
- Bi[t]frost Protocol - Custom off-chain protocol that allows the transfer of assets between Non-Cosmos-compatible Chains and Int3face Chain.
IBC Protocol
IBC Protocol is a standard protocol that allows the transfer of assets between two Cosmos-compatible chains. The protocol consists of the following messages to sent and receive packets:MsgRecvPacket
The incoming message that is sent from any IBC-compatible chain (like Osmosis) and received by the Int3face chain. If it contains a valid memo field, the message is processed as cross-chain transfer.MsgTransfer
The outgoing message that is sent by the Int3face chain to any IBC-compatible blockchain (like Osmosis). It contains the memo field with the information about the cross-chain transfer.IBC Middleware
We have a custom middleware to process the incoming & outgoing IBC packets. It makes two important tasks:- validation of incoming packets with memo field and creation of outbound transfers directly in the Int3face x/bridge module.
- finalization of the outgoing transfers sent via IBC.
Bi[t]frost Protocol
Bi[t]frost Protocol is a custom off-chain protocol that allows the transfer of assets between Non-Cosmos-compatible Chains and Int3face Chain. The protocol is fully-decentralized and relies on the TSS as well as Threshold Voting mechanism to process the cross-chain transfers.MsgInboundTransfer
The message is actually a vote posted by the Int3face chain Observers to process the incoming transfer. When observers witness the deposit on the vault address they construct and broadcast Tx to vote to mint the tokens on the Int3face chain. When the threshold of votes is reached, the tokens are minted and the transfer is considered as finalized.MsgInboundTransferRetry
The message can be sent by any user to retry the failed inbound transfer. The message is observed and processed by the Observers to retry the transfer. Each observer will try to find the transfer on the external chain and vote to mint the tokens on the Int3face chain sending MsgInboundTransfer again. Inbound is retriable when received via:- BITFROST - YES
- IBC - NO
MsgInboundTransferPushBack
The message is a vote on designated Inbound Transfer to push it back. The message is constructed and broadcasted by the Observers to Int3face chain to push back the transfer in case of invalid memo or impossibility to process the inbound.MsgInboundTransferRefunded
The message is a vote on designated Inbound Transfer to refund it. The message is constructed and broadcasted by the Observers to Int3face chain to refund the transfer. As soon as the threshold of votes is reached, the transfer is considered as refunded.MsgInboundTransferRefundFailed
The message is a vote on designated Inbound Transfer to mark it as refund failed. The message is constructed and broadcasted by the Observers to Int3face chain to mark the transfer as refund failed if the refund is not possible. As soon as the threshold of votes is reached, the transfer is considered as refund failed.MsgOutboundTransfer
The message can be sent by any Int3face account, and it’s not a cross-chain actually, because it’s a message to burn the tokens on the Int3face chain from the account of sender. The message is observed and processed by the Observers to construct and broadcast the transfer on the destination chain.MsgOutboundTransferRetry
The message can be sent by any user to retry the failed outbound transfer. The message is observed and processed by the Observers to retry the transfer. Each observer will try to find the transfer on the destination chain and if transfer is not found, observer will broadcast the transfer again and vote to finalize the transfer sending MsgOutboundTransferFinalized again. Outbound is retriable in case of sent via:- BITFROST - YES
- IBC - YES
MsgOutboundTransferFinalized
The message is a vote on designated Outbound Transfer to finalize it. The message is constructed and broadcasted by the Observers to Int3face chain to finalize the transfer once the broadcasted transfer is confirmed on the destination chain. As soon as the threshold of votes is reached, the transfer is considered as finalized.MsgOutboundTransferFailed
The message is a vote on designated Outbound Transfer to mark it as failed. The message is constructed and broadcasted by the Observers to Int3face chain to mark the transfer as failed if the broadcasted transfer is not confirmed on the destination chain. As soon as the threshold of votes is reached, the transfer is considered as failed.Int3face Bridge State & Params
Int3face Bridge (x/bridge module) contains the two main structures stored in the state to process cross-chain transfers:Bridge: Params
Int3face bridge module (x/bridge) has configured assets inside the module params. Query - You can query all bridge params via:Bridge: Inbound Transfers
Structure to store the information about the inbound transfers. It`s created after the first vote on the MsgInboundTransfer and contains the information about the votes and finalization status. Key - The key of the inbound transfer is a hash of the external transaction ID and the external chain height. Bitfrost Inbound: Key = sha256(external_id + external_height) IBC Inbound: Key = sha256(source_channel + destination_channel + sequence) Query - You can query inbound transfers via: Bitfrost Inbound:Bridge: Outbound Transfers
Structure to store the information about the outbound transfers. It`s created after the first vote on the MsgOutboundTransfer and contains the information about the votes and finalization status. Key - The key of the outbound transfer is a hash of the int3face transaction where the outbound transfer was created. OutboundTransferKey = sha256(int3face-tx-hash) ⚠️ Important Note: We are relaying on only one outbound transfer per int3face transaction. If we have multiple outbound transfers in one transaction, first finalized transfer will overwrite the others. Query - You can query outbound transfers via:Bitfrost Observer: Points of reaction
Bitfrost observer constantly scans and monitors the Int3face chain blocks for the events related to transfers and reacts on the following Messages:| Message Type | Target Action | Conditions | Processing |
|---|---|---|---|
| MsgOutboundTransfer | OUTBOUND_TRANSFER | Always | Create and broadcast the withdrawal transaction on the destination chain. |
| MsgInboundTransfer | OUTBOUND_TRANSFER | Inbound transfer is finalized and destination_chain is not int3face. | Create and broadcast the withdrawal transaction on the destination chain. |
| MsgRecvPacket | OUTBOUND_TRANSFER | Packet is received via IBC | Create and broadcast the withdrawal transaction on the destination chain. |
| MsgInboundTransferPushBack | REFUND | Inbound transfer is refunding (enough votes to push back) | Create and broadcast the withdrawal transaction on the source chain. |
| MsgOutboundTransferFailed | REFUND | Outbound transfer is failed, route is refundable, and refund_on_failure is true | Create and broadcast the withdrawal transaction on the source chain. |
| MsgInboundTransferRetry | INBOUND_TRANSFER | Inbound transfer is not finalized or refunded, execution_period is gone, and grace period is active | Create and broadcast the MsgInboundTransfer message again to vote on the transfer finalization. |
| MsgOutboundTransferRetry | OUTBOUND_TRANSFER | Outbound transfer is not finalized or refunded, execution_period is gone, and grace period is active | Create and broadcast the withdrawal transaction on the destination chain. |
Bridging Implementation
Bitfrost -> Int3face -> IBC
1. Inbound Transfer Processing
-
Inbound Transfer Initiation:
- User Action:
Deposits tokens to a UTXO Vault address or a Smart Contract address on the source chain. - Observers:
Witness the deposit transaction and submit votes via the MsgInboundTransfer to mint/unlock the corresponding tokens on the Int3face chain. - Status Update:
The transfer is marked as PROCESSING once the inbound transfer is created.
- User Action:
-
Finalization of Inbound Transfer
- Threshold Achievement:
Once the required number of votes is reached, the InboundTransfer status updates to FINALIZED. - Token Minting/Unlock:
Tokens are minted/unlocked on the Int3face chain vault address.
- Threshold Achievement:

2. Outbound Transfer Processing
- Outbound Transfer Initiation:
- Bridge Module Action:
After the Inbound Transfer is FINALIZED, the bridge module triggers a MsgTransfer to send tokens to the IBC-connected chain. This includes a designated memo field (IBCOutboundMemo: { OutboundTxHash, IsRefund }). - Status Update:
The outbound transfer is created in the x/bridge module with the status PROCESSING.
- Bridge Module Action:
- Finalization of Outbound Transfer
- Acknowledgement Receipt:
Upon receiving the IBC transfer acknowledgement, the OutboundTransfer status updates to FINALIZED.
- Acknowledgement Receipt:

3. PushBack and Refund Mechanisms
-
PushBack for Inbound Transfers:
- Invalid Memo Handling:
If an inbound transfer has an invalid memo, Observers send a MsgInboundTransferPushBack message to return the transfer to the sender. - Status Update:
Once the push-back vote threshold is met, the status changes to REFUNDING. - Refund Process:
- Success:
Observers send MsgInboundTransferRefunded to mark as REFUNDED. - Failure:
Observers send MsgInboundTransferRefundFailed to mark as REFUND_FAILED.
- Success:
- Invalid Memo Handling:
-
Refund for Outbound/Inbound Transfers:
- Failure Handling:
If an OutboundTransfer fails (due to timeout or acknowledgement failure) and is refundable with the
refund_on_failureflag enabled, tokens are unlocked on the Int3face chain. - Status Update:
- The Outbound transfer is marked as REFUNDED.
- The Inbound transfer is marked as REFUNDING.
- Refund Process:
- Success:
Observers send MsgInboundTransferRefunded to mark the InboundTransfer as REFUNDED. - Failure:
Observers send MsgInboundTransferRefundFailed to mark the InboundTransfer as REFUND_FAILED.
- Success:
- Failure Handling:
If an OutboundTransfer fails (due to timeout or acknowledgement failure) and is refundable with the

4. Retry Mechanisms
-
Inbound Transfer Retry:
- Eligibility:
Transfer finalized on external (source) chain. Transfer can be retried if not FINALIZED or REFUNDED, and the execution period has elapsed with an active grace period. - User Action:
Sends MsgInboundTransferRetry. - Observer Action:
Votes to mint tokens again on the Int3face chain. - Finalization:
Upon reaching the vote threshold, the status updates to FINALIZED.
- Eligibility:
-
Inbound Refund Retry:
- Eligibility:
Applicable if the status is not FINALIZED or REFUNDED, and within the grace period. - User Action:
Retries using the TxHash from MsgInboundTransferRefundFailed or MsgInboundTransferPushBack. - Observer Action:
Witnesses MsgOutboundTransferRetry on the Int3face chain and initiates a refund transaction. - Refund Process:
- Success:
Marks as REFUNDED. - Failure:
Marks as REFUND_FAILED.
- Success:
- Eligibility:
-
Outbound Transfer Retry:
- Eligibility:
Transfer can be retried if not FINALIZED or REFUNDED and within the grace period. - User Action:
Sends MsgOutboundTransferRetry. - Bridge Module Action:
Initiates another IBC transfer. - Finalization:
Upon acknowledgement, status updates to FINALIZED; otherwise, marked as FAILED.
- Eligibility:

IBC -> Int3face -> Bitfrost
1. Inbound Transfer Processing
- Inbound Transfer Initiation & Finalization:
- IBC Packet Processing:
User sends an IBC packet with the designated memo field. - Int3face Node Action:
Processes the IBC packet and creates the InboundTransfer in the x/bridge module. - Status Update:
Once transfer is created, the transfer is marked as FINALIZED.
- IBC Packet Processing:

3. Outbound Transfer Processing
- Outbound Transfer Initiation:
- Bridge Module Action:
Once tokens are unlocked, the bridge module creates the OutboundTransfer in the x/bridge module with the status PROCESSING.
- Bridge Module Action:
- Broadcast and Feedback
- Observer Broadcasting:
Observers witness the OutboundTransfer and then create and broadcast withdrawal transactions to send the tokens to the destination chain. - Feedback Collection:
- Success:
Observers send MsgOutboundTransferFinalized to finalize the OutboundTransfer. - Failure:
Observers send MsgOutboundTransferFailed to mark the OutboundTransfer as failed.
- Success:
- Observer Broadcasting:

3. PushBack and Refund Mechanism
-
PushBack for Inbound Transfers:
- Invalid Memo Handling:
If the receiver is the Int3face vault address and the memo is invalid, the InboundTransfer is NOT CREATED an IBC packet pushed back to the sender via IBC protocol.
- Invalid Memo Handling:
-
Refund for Outbound/Inbound Transfers:
- Failure Handling:
If an OutboundTransfer fails (due to withdrawal tx failures) and is refundable with therefund_on_failureflag enabled, tokens are minted back to the Int3face chain. - Status Update:
- The Outbound transfer is marked as REFUNDED.
- The Inbound transfer is marked as REFUNDING.
- Bridge Module Action:
Initiates a refund IBC transaction. - Refund Process:
- Success:
Observers send MsgInboundTransferRefunded to mark the InboundTransfer as REFUNDED. - Failure:
Observers send MsgInboundTransferRefundFailed to mark the InboundTransfer as REFUND_FAILED.
- Success:
- Failure Handling:

4. Retry Mechanisms
-
Outbound Transfer Retry:
- Eligibility:
Transfer can be retried if not FINALIZED or REFUNDED and within the grace period. - User Action:
Sends MsgOutboundTransferRetry using the TxHash from MsgRecvPacket. - Bridge Module Action:
Initiates another Outbound Transfer. - Observer Action:
Witnesses the retry and initiates a refund transaction if the route is refundable. - Finalization: Upon acknowledgement, status updates to FINALIZED; otherwise, marked as FAILED.
- Eligibility:
-
Inbound Refund Retry:
- Eligibility:
Applicable if the status is not FINALIZED or REFUNDED, and within the grace period. - User Action:
Sends MsgOutboundTransferRetry using the TxHash from final MsgOutboundTransferFailed. - Bridge Module Action:
Initiates new IBC refund transaction. - Refund Process:
- Success:
Marks as REFUNDED when the refund is IBC packet acknowledged. - Failure:
Marks as REFUND_FAILED if IBC packet acknowledgment fails or times out.
- Success:
- Eligibility:

Bitfrost -> Int3face -> Bitfrost
1. Inbound Transfer Processing
-
Inbound Transfer Initiation:
- User Action:
Deposits tokens to a Vault address or a Smart Contract address on the Bitfrost chain. - Observers:
Witness the deposit transaction and submit votes via the MsgInboundTransfer to mint/unlock the corresponding tokens on the Int3face chain. - Status Update:
The transfer is marked as PROCESSING once the inbound transfer is created.
- User Action:
-
Finalization of Inbound Transfer:
- Threshold Achievement:
Once the required number of votes is reached, the InboundTransfer status updates to FINALIZED. - Token Unlocking:
Tokens are minted/unlocked on the Int3face chain vault address.
- Threshold Achievement:
2. Outbound Transfer Processing
- Outbound Transfer Initiation:
- Bridge Module Action:
Once tokens are minted/unlocked, the bridge module creates the OutboundTransfer in the x/bridge module with the status PROCESSING.
- Bridge Module Action:
- Broadcast and Feedback
- Observer Broadcasting:
Observers witness the OutboundTransfer and then create and broadcastwithdrawaltransactions to send the tokens to the destination chain. - Feedback Collection:
- Success:
Observers send MsgOutboundTransferFinalized to finalize the OutboundTransfer. - Failure:
Observers send MsgOutboundTransferFailed to mark the OutboundTransfer as failed.
- Success:
- Observer Broadcasting:
3. PushBack and Refund Mechanisms
-
PushBack for Inbound Transfers:
- Invalid Memo Handling:
If an inbound transfer has an invalid memo, Observers send a MsgInboundTransferPushBack message to return the transfer to the sender. - Status Update:
Once the push-back vote threshold is met, the status changes to REFUNDING. - Refund Process:
- Success:
Observers send MsgInboundTransferRefunded to mark as REFUNDED. - Failure:
Observers send MsgInboundTransferRefundFailed to mark as REFUND_FAILED.
- Success:
- Invalid Memo Handling:
-
Refund for Outbound/Inbound Transfers:
- Failure Handling:
If an OutboundTransfer fails (due to timeout or acknowledgement failure) and is refundable with therefund_on_failureflag enabled, tokens are unlocked on the Int3face chain. - Status Update:
- The Outbound transfer is marked as REFUNDED.
- The Inbound transfer is marked as REFUNDING.
- Refund Process:
- Success:
Observers send MsgInboundTransferRefunded to mark the InboundTransfer as REFUNDED. - Failure:
Observers send MsgInboundTransferRefundFailed to mark the InboundTransfer as REFUND_FAILED.
- Success:
- Failure Handling:
4. Retry Mechanisms
-
Inbound Transfer Retry:
- Eligibility:
Transfer can be retried if not FINALIZED or REFUNDED, and the execution period has elapsed with an active grace period. - User Action:
Sends MsgInboundTransferRetry. - Observer Action:
Votes to mint/unlock tokens again on the Int3face chain. - Finalization:
Upon reaching the vote threshold, the status updates to FINALIZED.
- Eligibility:
-
Inbound Refund Retry:
- Eligibility:
Applicable if the status is not FINALIZED or REFUNDED, and the execution period has elapsed with an active grace period. - User Action:
Retries using the TxHash from MsgInboundTransferRefundFailed or MsgInboundTransferPushBack. - Observer Action:
Witnesses MsgOutboundTransferRetry on the Int3face chain and initiates a refund transaction to the source chain. - Refund Process:
- Success:
Marks as REFUNDED. - Failure:
Marks as REFUND_FAILED.
- Success:
- Eligibility:
-
Outbound Transfer Retry:
- Eligibility:
Transfer can be retried if not FINALIZED or REFUNDED and the execution period has elapsed with an active grace period. - User Action:
Sends MsgOutboundTransferRetry. - Observer Action:
Witnesses MsgOutboundTransferRetry on the Int3face chain and initiates a retry transaction to the destination chain. - Retry Process:
- Success:
Marks as FINALIZED. - Failure:
Marks as FAILED.
- Success:
- Eligibility:
IBC -> Int3face -> IBC
1. Inbound Transfer Processing
-
Inbound Transfer Initiation:
- User Action:
Initiates a transfer by sending an IBC packet with the designated memo field (IBCInboundMemo: { SourceChain, DestChain, DestAddress, RefundOnFailure }) from the IBC-connected source chain. - Int3face Node Action:
Processes the incoming IBC packet and creates an InboundTransfer entry in thex/bridgemodule on the Int3face chain. - Status Update:
The transfer is marked as PROCESSING once the InboundTransfer is created.
- User Action:
-
Finalization of Inbound Transfer:
- Threshold Achievement:
Observers submit votes via the MsgInboundTransfer. Once the required number of votes is reached, the InboundTransfer status updates to FINALIZED. - Token Unlocking:
Tokens are unlocked on the Int3face chain vault address, making them available to the user.
- Threshold Achievement:
2. Outbound Transfer Processing
-
Outbound Transfer Initiation:
- Bridge Module Action:
After the Inbound Transfer is FINALIZED, the bridge module triggers a MsgTransfer to send tokens back to the IBC-connected destination chain. This includes a designated memo field (IBCOutboundMemo: { OutboundTxHash, IsRefund }). - Status Update:
The outbound transfer is created in thex/bridgemodule with the status PROCESSING.
- Bridge Module Action:
-
Finalization of Outbound Transfer:
- Acknowledgement Receipt:
Upon receiving the IBC transfer acknowledgement from the destination chain, the OutboundTransfer status updates to FINALIZED.
- Acknowledgement Receipt:
3. PushBack and Refund Mechanisms
-
PushBack for Inbound Transfers:
- Invalid Memo Handling:
If the receiver is the Int3face vault address and the memo is invalid, the InboundTransfer is NOT CREATED an IBC packet pushed back to the sender via IBC protocol.
- Invalid Memo Handling:
-
Refund for Outbound/Inbound Transfers:
- Failure Handling:
If an OutboundTransfer fails (due to timeout or acknowledgement failure) and is refundable with therefund_on_failureflag enabled, tokens are unlocked on the Int3face chain. - Status Update:
- The OutboundTransfer is marked as REFUNDED.
- The InboundTransfer is marked as REFUNDING.
- Refund Process:
- Success:
Observers send MsgInboundTransferRefunded to mark the InboundTransfer as REFUNDED. - Failure:
Observers send MsgInboundTransferRefundFailed to mark the InboundTransfer as REFUND_FAILED.
- Success:
- Failure Handling:
4. Retry Mechanisms
-
Inbound Transfer Retry:
- Eligibility:
Transfer can be retried if it is not FINALIZED or REFUNDED, and the execution period has elapsed with an active grace period. - User Action:
Sends MsgInboundTransferRetry. - Observer Action:
Votes to unlock tokens again on the Int3face chain. - Finalization:
Upon reaching the vote threshold, the status updates to FINALIZED.
- Eligibility:
-
Inbound Refund Retry:
- Eligibility:
Applicable if the status is not FINALIZED or REFUNDED, and within the grace period. - User Action:
Retries using theTxHashfrom MsgInboundTransferRefundFailed or MsgInboundTransferPushBack. - Observer Action:
Witnesses MsgOutboundTransferRetry on the Int3face chain and initiates a refund transaction to the source chain. - Refund Process:
- Success:
Marks as REFUNDED. - Failure:
Marks as REFUND_FAILED.
- Success:
- Eligibility:
-
Outbound Transfer Retry:
- Eligibility:
Transfer can be retried if it is not FINALIZED or REFUNDED, and the execution period has elapsed with an active grace period. - User Action:
Sends MsgOutboundTransferRetry. - Bridge Module Action:
Initiates another IBC transfer to the destination chain. - Finalization:
Upon acknowledgement, status updates to FINALIZED; otherwise, marked as FAILED.
- Eligibility: