FABRKNT
Cross-Chain Bridges — From CCIP to Light Clients
Reading Real Bridges
Lesson 4 of 7·CONTENT18 min45 XP

Treat this page as a workbench, not a blog post. The goal is to extract a reusable mental model from the source and carry it into the rest of the Fabrknt stack.

Course
Cross-Chain Bridges — From CCIP to Light Clients
Lesson role
CONTENT
Sequence
4 / 7

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 CCIPReceiver verifies 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.
  • CCIPReceiver contract. Destination chains inherit CCIPReceiver and 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):

NetworkRoleTrust model
Committing DONAggregate source-chain events into Merkle commitmentsM-of-N PoS validators
Executing DONExecute messages on destination chainSame/different N-of-M
Risk Management NetworkVeto malicious or sanctioned messagesSeparate 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 caseWhat you sendExample
Data onlydata (any calldata)Generic cross-chain call
TokensdestTokenAmountsAsset transfer
ProgrammableBothCross-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. Find TokenPool.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):

BridgeTrust modelFees per msgLatencyWhy for Tempo?
CCIPPoS DON + RMN$0.50-$2~10 minProduction-ready, Solana support
LayerZeroDVN model$0.30-$1~5 minSolana support, more flexible
Wormhole19-of-N guardian multisig$0.20-$1~2 minCheapest, but multisig risk
OP StandardRollup consensus~$0.10 + L1 gas7 daysL2 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

10. Practice

  1. Browse the CCIP contracts repo
  2. Find the Router.sol — the entry point for users
  3. Trace a message from ccipSend on source to ccipReceive on destination
  4. 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.
  • CCIPReceiver is the canonical receiver-side inheritance pattern. Trade-off: trust the DON for speed. Next lesson reads Wormhole + IBC for the multi-chain message protocols.