Lesson 4 — Chainlink CCIP — the cross-chain rail Tempo uses
Question
Chainlink CCIP (Cross-Chain Interoperability Protocol) is Tempo's stablecoin-payment cross-chain rail. A 12-node decentralised oracle network signs message attestations. Not a light-client bridge, not a multi-sig — a hybrid that trades full trust-minimisation for low latency + chain-agnosticism.
Principle (minimum model)
- CCIP architecture. A 12-node Decentralised Oracle Network (DON) observes messages on the source chain, signs an attestation, and the destination chain's
CCIPReceiververifies the signature. - Trust model. 12 nodes signing → trust the DON. Not a full light client. Not a 1-of-N multi-sig either. M-of-N (e.g. 9-of-12) — a known set of professional operators, slashable on Chainlink staking.
- Two settlement modes. Lock-mint (canonical for cross-chain ERC-20s, source has lock contract / destination has mint contract) and burn-mint (cheaper, no liquidity locked, but every chain needs the mint contract).
- Risk Management Network (RMN). A separate set of nodes that monitor for malicious activity. If the RMN flags a transfer, it's paused until manual review. Defence in depth against the DON.
- Tempo uses CCIP for stablecoin transfers. Specifically chosen because: (1) low latency (~15 min vs 7 days for OP), (2) chain-agnostic (supports Ethereum / Polygon / Arbitrum / etc. with the same API), (3) regulator-friendly (Chainlink Labs is a known entity).
- Trade-off. Lower trust-minimisation than a light client; higher than a 1-of-N multi-sig. Suitable for payment-rail use cases where 15-minute settlement and known operators are acceptable.
CCIPReceivercontract. Destination chains inheritCCIPReceiverand override_ccipReceive— exactly like inheriting Solidity contracts. Boilerplate is small; the receiver pattern is canonical.
Worked example + steps
Chainlink CCIP — the cross-chain rail Tempo uses
A merchant accepts USDC payment in Tempo. Behind the scenes, that USDC must settle on Ethereum (for treasury) and Solana (for DeFi yield) — across three chains, two of which can't speak to each other directly. This cross-chain settlement is not theoretical; Tempo runs it in production today on Chainlink CCIP (Cross-Chain Interoperability Protocol). Not a light client. Not a fork of Wormhole. A production bridge designed for arbitrary chain pairs.
Hyperliquid doesn't use CCIP — they ship their own bridge. But for mppsol and soltempo, CCIP is the operational reality, not a theoretical alternative. Understanding it isn't optional if you're going to architect anything that touches Tempo's payments stack.
1. CCIP's architecture in 60 seconds
flowchart LR
Source["Source chain<br/>(Ethereum)"] -->|user tx| Router["CCIP Router"]
Router -->|emit| OnRamp["OnRamp contract"]
OnRamp -->|message| DON["Decentralized Oracle Network<br/>(commit + execute)"]
DON -->|verify + relay| OffRamp["OffRamp contract"]
OffRamp -->|deliver| Dest["Destination chain<br/>(Tempo)"]
RMN["Risk Management<br/>Network"] -.->|cursing| DON
Two networks of nodes operate the protocol (the first two rows below — Committing DON and Executing DON — together form the DON; the third row, the Risk Management Network, is a separate safety net):
| Network | Role | Trust model |
|---|---|---|
| Committing DON | Aggregate source-chain events into Merkle commitments | M-of-N PoS validators |
| Executing DON | Execute messages on destination chain | Same/different N-of-M |
| Risk Management Network | Veto malicious or sanctioned messages | Separate validator set, off-chain monitoring |
So CCIP is technically a multisig — but a multisig built specifically for cross-chain messaging, with:
- Larger validator sets than typical multisig
- Separate "cursing" / freeze authority (RMN) for emergency
- Token-pool architecture for asset bridges
- Per-chain configurable risk parameters
The committing DON + executing DON could collude to forge messages. The RMN is the backup — if the DON misbehaves, RMN can pause specific lanes. This adds a second layer of defense, but it's still trust-based, not cryptographically trustless.
2. The message format
A CCIP message contains:
struct Any2EVMMessage {
bytes32 messageId; // Unique ID
uint64 sourceChainSelector;
bytes sender; // ABI-encoded sender on source
bytes data; // Arbitrary calldata
EVMTokenAmount[] destTokenAmounts; // Tokens to release on destination
}
Two ways messages are used:
| Use case | What you send | Example |
|---|---|---|
| Data only | data (any calldata) | Generic cross-chain call |
| Tokens | destTokenAmounts | Asset transfer |
| Programmable | Both | Cross-chain swap, settle-and-call |
For soltempo, the use case is tokens + data: send USDC from Ethereum to Tempo, with metadata identifying the merchant settlement.
3. The token pool model
Anyone who used cross-chain DEXes in 2021 remembers the wrapped-token mess: USDC.e on Avalanche, anyUSDC on Fantom, three different "wrapped USDC" representations none of which were the real USDC. CCIP avoids this entirely. Instead of wrapping, it uses token pools — a pool contract on each chain that holds (or mints) the canonical asset:
- A pool contract on each chain holds the asset
- On bridging, source pool locks the asset; destination pool releases
- For burn-mint model: source pool burns; destination pool mints from the same total supply
Tempo's USDC on Ethereum uses burn-mint via CCIP. Source USDC is burned; destination USDC is minted. There's no "USDC.e" — only USDC on different chains. Simpler, and more secure than wrapped tokens.
🔍 Find in repo.
smartcontractkit/ccip— the CCIP contracts. FindTokenPool.sol. What's the inheritance structure? The contract has multiple variants for different token types.
4. The lane model
CCIP supports lanes — directional chain pairs. A lane Ethereum→Tempo is different from Tempo→Ethereum. Each lane has:
- Its own DON committee config
- Its own risk parameters (max throughput, fee)
- Its own token mappings
Lanes are launched per chain pair. CCIP currently supports 30+ chains, so ~900 lanes possible. Each lane has its own deployment cost.
For Tempo: lanes exist for Tempo↔Ethereum and Tempo↔Solana. Bidirectional, both with token + data support.
5. The fee model
CCIP charges fees in:
- Native gas token of source chain (ETH for Ethereum, etc.)
- LINK (Chainlink's token, ~20% discount)
The fee covers:
- Source-chain gas to emit message
- Destination-chain gas to execute message
- DON operating costs
- Risk premium
For soltempo: every settlement costs ~$0.50-$2 in CCIP fees (depending on chain pair). Acceptable for $100+ payments.
6. CCIP vs alternatives
Comparing for merchant-scale payments (Tempo's use case):
| Bridge | Trust model | Fees per msg | Latency | Why for Tempo? |
|---|---|---|---|---|
| CCIP | PoS DON + RMN | $0.50-$2 | ~10 min | Production-ready, Solana support |
| LayerZero | DVN model | $0.30-$1 | ~5 min | Solana support, more flexible |
| Wormhole | 19-of-N guardian multisig | $0.20-$1 | ~2 min | Cheapest, but multisig risk |
| OP Standard | Rollup consensus | ~$0.10 + L1 gas | 7 days | L2 only, not for Tempo |
CCIP wins for Tempo on trust + regulatory — Chainlink is the most established cross-chain infra, has insurance, has institutional integrations. For a payments rail with merchant relationships, this matters.
7. The integration pattern
For your contract (e.g., a soltempo settlement contract on Tempo) to receive CCIP messages:
// Inherit CCIPReceiver
contract SoltempoVault is CCIPReceiver {
function _ccipReceive(Any2EVMMessage memory message) internal override {
// Decode the sender (should be authorized soltempo source contract)
address sourceContract = abi.decode(message.sender, (address));
require(sourceContract == authorizedSource, "unauthorized");
// Decode the payment metadata
PaymentReceipt memory receipt = abi.decode(message.data, (PaymentReceipt));
// Update merchant state with the received USDC
_processSettlement(message.destTokenAmounts, receipt);
}
}
That's the application interface — inherit, override one function, validate the sender, process the message.
For Tempo↔Solana, the destination chain is non-EVM, so the receiver is in Anchor (Rust):
#[program]
mod soltempo_vault {
use ccip_solana::CcipReceiver;
pub fn ccip_receive(ctx: Context<CcipReceive>, message: Any2SVMMessage) -> Result<()> {
// Verify sender
require!(message.sender == authorized_source, ErrorCode::Unauthorized);
// Process settlement
process_settlement(ctx, message)
}
}
Same structure, different language. This is the actual integration soltempo runs.
8. The mppsol architecture
Recall (from the strategy docs): mppsol is a Reth/REVM↔Solana settlement layer. CCIP is the rail.
Merchant payment ──[CCIP]── Solana DeFi ──[CCIP]── Tempo merchant balance
↑ ↓ ↑
Ethereum USDC Yield earned Withdraw on demand
The whole architecture is CCIP-mediated cross-VM message passing. Tempo's bridge layer for merchant ops = CCIP. No alternative was viable at scale.
For settlement-scale: $0.50 on $1M = 0.005% fee. Hugely viable. Throughput: CCIP supports ~10-100 msgs/sec per lane currently, so 1000 simultaneous settlements would queue. Acceptable for non-instant flows; problematic if merchants demand real-time UX.
9. Reading list
- CCIP whitepaper
- CCIP contracts
- CCIP developer docs — integration guide
10. Practice
- Browse the CCIP contracts repo
- Find the
Router.sol— the entry point for users - Trace a message from
ccipSendon source toccipReceiveon destination - Identify the 3 trust boundaries (committing DON, executing DON, RMN)
Final check: in one sentence, why is CCIP the operational choice for Tempo↔Solana even though it's not the most trust-minimized option? If your answer doesn't reference "Solana support + regulatory comfort + production maturity," re-read §6.
Summary (3 lines)
- CCIP = 12-node Decentralised Oracle Network signing message attestations + a separate Risk Management Network for monitoring. Hybrid trust model — more than a multi-sig, less than a light client.
- Two settlement modes (lock-mint / burn-mint). Tempo chose CCIP for stablecoin transfers because of ~15-min latency, chain-agnosticism, and regulator-friendly known operators.
CCIPReceiveris the canonical receiver-side inheritance pattern. Trade-off: trust the DON for speed. Next lesson reads Wormhole + IBC for the multi-chain message protocols.