| cip | 45 |
|---|---|
| title | Forwarding Module |
| description | Enable cross-chain token forwarding via Hyperlane warp routes |
| author | Manav Aggarwal (@Manav-Aggarwal) |
| discussions-to | https://forum.celestia.org/t/cip-add-forwarding-module/2218 |
| status | Final |
| type | Standards Track |
| category | Core |
| created | 2026-01-19 |
| requires | CIP-32 |
Abstract
This proposal introduces a forwarding module (x/forwarding) that facilitates cross-chain token transfers through Hyperlane warp routes. Users deposit tokens at deterministically derived forwarding addresses, and relayers permissionlessly execute transfers to pre-committed destinations.
Motivation
Currently, transferring tokens via Hyperlane through Celestia (source chain → Celestia → destination chain) requires users to sign multiple transactions: one on the source chain and another on Celestia to complete the second hop. This module simplifies the experience to a single signature on the source chain. It also enables exchanges to withdraw TIA directly to a user’s destination address on another chain. The design allows anyone to trigger the forwarding permissionlessly while cryptographically guaranteeing tokens can only reach the pre-committed destination. This complements IBC Packet Forward Middleware by providing equivalent functionality for Hyperlane transfers.
Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.
New Module: x/forwarding
The forwarding module enables cross-chain token transfers via Hyperlane warp routes with a single-signature user experience.
Address Derivation
Forwarding addresses are derived deterministically from the destination domain and recipient:
callDigest = sha256(destDomain_32bytes || destRecipient)
salt = sha256(version_byte || callDigest) // version_byte = 0x01
forwardAddr = address.Module("forwarding", salt)[:20]
This produces one unique address per (destDomain, destRecipient) pair. Destination domain IDs are defined in the Hyperlane registry. Supported domains for a specific warp route can be queried via celestia query hyperlane warp-route domains.
Message Types
message MsgForward {
string signer = 1; // Relayer address (pays gas + IGP fees)
string forward_addr = 2; // bech32 forwarding address
uint32 dest_domain = 3; // Hyperlane destination domain ID
string dest_recipient = 4; // 32-byte recipient (hex-encoded)
cosmos.base.v1beta1.Coin max_igp_fee = 5; // Maximum IGP fee relayer will pay per token
}
message MsgForwardResponse {
repeated ForwardingResult results = 1;
}
message ForwardingResult {
string denom = 1; // Token denomination
string amount = 2; // Amount forwarded
string message_id = 3; // Hyperlane message ID (empty if failed)
bool success = 4; // Whether the forward succeeded
string error = 5; // Error message if failed
}
Query Types
message QueryDeriveForwardingAddressRequest {
uint32 dest_domain = 1; // Hyperlane destination domain ID
string dest_recipient = 2; // 32-byte recipient (hex-encoded)
}
message QueryDeriveForwardingAddressResponse {
string address = 1; // Derived forwarding address (bech32)
}
message QueryQuoteForwardingFeeRequest {
uint32 dest_domain = 1; // Destination chain domain ID
}
message QueryQuoteForwardingFeeResponse {
cosmos.base.v1beta1.Coin fee = 1; // Estimated IGP fee for forwarding
}
Fee Handling
Relayers pay both Celestia transaction gas and Hyperlane Interchain Gas Paymaster (IGP) fees:
- Per-Token Charging: Each token forwarded incurs its own IGP fee, capped at the
max_igp_feevalue specified inMsgForward. - Actual vs. Maximum: The actual fee charged is the lesser of
max_igp_feeand the quoted fee from the IGP. - No Refunds: IGP fees are NOT refunded if the warp transfer fails. This incentivizes relayers to check routes before submitting.
- Fee Quoting: Relayers SHOULD query
QuoteForwardingFeebefore submittingMsgForwardto determine the required fee and apply a safety buffer for price fluctuations.
Supported Tokens
| Source | Format | Method |
|---|---|---|
| Warp transfer | hyperlane/{tokenId} | Synthetic transfer |
| CEX (TIA) | utia | Collateral transfer |
Note: Native TIA (utia) uses collateral transfer and is the only token that can be deposited directly from a CEX. TIA bridged from other chains arrives as hyperlane/{tokenId} and uses synthetic transfer.
Multi-Token Handling
The module processes 20 token balances at a time. If more tokens exist at the forwarding address, subsequent MsgForward transactions can process the remaining balances.
Relayers
Relayers are off-chain services that monitor forwarding addresses for deposits and submit MsgForward transactions to trigger the transfer. Relayers pay the Celestia gas and IGP fees. Note: relayers are unincentivized initially (no payment for relaying).
Operational Flow
- Frontend derives the forwarding address using destination domain and recipient
- User transfers tokens to this address
- Relayer detects the deposit and submits
MsgForward - Module validates the address derivation and executes the warp transfer
- Tokens appear at the destination recipient’s address on the target chain
Events
message EventTokenForwarded {
string forward_address = 1;
string denom = 2;
string amount = 3;
string message_id = 4;
bool success = 5;
string error = 6;
}
message EventForwardingComplete {
string forward_address = 1;
uint32 destination_domain = 2;
bytes destination_recipient = 3;
uint32 successful_count = 4;
uint32 failed_count = 5;
}
message EventTokensStuck {
string forward_address = 1;
string denom = 2;
string amount = 3;
string module_account = 4;
string error = 5;
}
Rationale
The forwarding address design cryptographically binds the destination to the address, enabling permissionless execution while guaranteeing funds can only go to the intended recipient.
Backwards Compatibility
This is a consensus-breaking change that requires a network upgrade. However, it is purely additive (new module, new message types) and does not affect existing functionality.
Test Cases
Test cases are available in the reference implementation:
- Integration tests: test/interop/forwarding_integration_test.go
- Address derivation tests: x/forwarding/types/address_test.go
Security Considerations
-
Cryptographic Binding: Forwarding addresses cryptographically commit to specific destinations. Funds deposited at a forwarding address can only be transferred to the pre-committed destination.
-
Permissionless Safety: Anyone can trigger forwarding, but execution is restricted to the pre-committed target. This enables permissionless relaying without risk of fund misdirection.
-
User Error Handling: If a user sends tokens to an incorrect forwarding address (e.g., wrong destination domain or recipient), those tokens become stuck. The user cannot recover them because no one controls the private key for that address. Users MUST verify the forwarding address matches their intended destination before depositing. Note: if tokens are sent to a forwarding address for a destination domain that is not yet live, forwarding can be retried once that domain becomes available.
-
Collision Resistance: Address security is equivalent to standard Cosmos address security (160-bit truncation).
Reference Implementation
The implementation is available at:
Copyright
Copyright and related rights waived via CC0.