An explainer · for everyone · no prior knowledge assumed

The plumbing of CLPR

How a message gets from one blockchain to another with no bridge to trust. The Cross Ledger Protocol, explained from nothing.

Ledger A Ledger B application application verifier trust anchor verifier trust anchor endpoint in the node endpoint a program

Watch all 28 steps →

About 25 minutes, with things to play with Repositories and commits are listed at the end of the page Developer version →

Act I · The problem

Why two ledgers cannot just talk

Know what a ledger is, why two of them cannot see each other, and why the usual fix makes every message only as safe as the party in the middle.

Section 1of 16

A ledger is a shared record

Before cross-ledger anything, one idea has to be solid: what a ledger is. Not the finance kind, the blockchain kind, and the two words are close enough to cause trouble.

A ledger, here, is a shared record that many computers keep identical copies of. Nobody owns it. When someone wants to add a line, every computer gets the proposal, they compare notes, and the line is only written once enough of them agree. The rules for “enough” differ from network to network, but the result is always the same: one more line that every copy has and that nobody can quietly change afterwards.

Simulation

Five copies of one ledger

node 1 node 1 1. Ann → Bo 5 2. Bo → Cy 2 3. Cy → Dee 1 4. Dee → Ann 3 node 2 node 2 1. Ann → Bo 5 2. Bo → Cy 2 3. Cy → Dee 1 4. Dee → Ann 3 node 3 node 3 1. Ann → Bo 5 2. Bo → Cy 2 3. Cy → Dee 1 4. Dee → Ann 3 node 4 node 4 1. Ann → Bo 5 2. Bo → Cy 2 3. Cy → Dee 1 4. Dee → Ann 3 node 5 node 5 1. Ann → Bo 5 2. Bo → Cy 2 3. Cy → Dee 1 4. Dee → Ann 3 Every node keeps an identical copy. No single node is in charge of it.

Wider than a phone; scroll it sideways if you need to.

readyA ledger is a shared record that many computers keep in sync. Press the button to add a line and watch how they agree.

Two consequences matter for everything that follows. First, a sealed line is a fact about the whole network, not about one computer. Second, a network can vouch for a line: its validators can put a joint signature on a short summary of the whole ledger, and anyone who knows the network’s public signing identity can check that signature. A state proof is that signed summary plus the path from the summary down to one particular line. Hold that thought.

Ledger A's state lines 1 … 4,231, all sealed Validators of A many machines, one joint signature Summary one compact digest of the whole ledger Line 4,231 "send 5 to Bo on B" Signature on the summary; checkable against A's public identity State proof the validators' signature + the path to one line one object a stranger can check summarised jointly sign path down to one line Anyone holding A's public identity can check the signature. It takes the validators acting together.
Signature plus path. The validators sign one summary of the whole ledger; the path shows that one particular line is inside that summary. Together they let a stranger check a line without trusting any one computer.

Wider than a phone; scroll it sideways if you need to.

Check yourself: Why can't a single computer change a line that has already been sealed?

Because every other copy still has the original, and the network only trusts what enough copies agree on. One dissenting copy is simply overruled, as the simulation shows when you tick the box.

Section 2of 16

Ledgers cannot see each other

Now take two of these networks. Each is a world of its own. Nothing written in one ledger is visible from inside the other. A program running on Ledger A cannot look up a balance on Ledger B, cannot call a program there, cannot even tell whether Ledger B exists.

Ledger A its own validators, its own ledger program on A "is Bo's payment on B done yet?" Ledger B its own validators, its own ledger program on B "did A really lock those tokens?" look up a balance on B check a line on A no window nothing on A can read B; nothing on B can read A Reachable over the internet is not the same as checkable by every validator.
Two islands, by design. Each ledger only writes what its own validators can check. A program on A cannot read B's ledger, and a line on B says nothing to A. Every cross-ledger idea needs a way across this water that the receiving side can rely on.

Wider than a phone; scroll it sideways if you need to.

That blindness follows from how ledgers work. In general, a ledger only writes a line if every validator can check it on its own. “Go and look at the other network” fails that test: hundreds of machines cannot all look and be sure they saw the same thing at the same moment. So the two islands stay islands.

the same question, sent at the same moment Validator 1 of A asks B: is Bo's payment done? Validator 2 of A asks the same Validator 3 of A asks the same Validator 4 of A asks the same Ledger B answers whoever asks, whenever they ask "done", arrives first "not yet", arrives later nothing arrives "done", arrives last compare notes New line on A: not written the four copies disagree, so nothing is sealed 🔏 seal not lit Sealing needs enough validators to agree, each on its own; "go and look" cannot promise that.
Same question, different answers. Validators seal a line only when they all reach the same result on their own. Asking another network gives each of them a different answer at a different moment, so nothing can be sealed.

Wider than a phone; scroll it sideways if you need to.

But people keep wanting to build things that span them: lock a token on one ledger and issue a matching one on another, let a program on a private network ask a public one to do something, settle a trade whose two legs live on different chains. Every one of those needs a message to cross the water in a way the receiving ledger can rely on.

Section 3of 16

Why a trusted party in the middle is the weak point

The obvious solution is to appoint someone to do the looking. Call them a relayer, an oracle, a committee, a bridge. They watch Ledger A, and when something relevant happens they tell Ledger B, signing the report with a key that Ledger B has been told to trust.

That works, in the sense that messages arrive. The problem is what Ledger B is actually trusting. It is not trusting Ledger A. It is trusting whoever holds that key. If the key is stolen, or the committee members collude, or the program that produces the signature has a bug, Ledger B will accept a message that Ledger A never sent, and it has no way to notice.

Ledger A its own validators, its own sealed lines never asked Middleman relayer, oracle, committee or bridge holds key K A message A never sent "Ann sends 500 to Bo" also signed with K Ledger B on file: "trust key K" B's check signature matches K? yes: accept the only question watches A report, signed with K Ledger B never consults Ledger A, so it cannot tell the two apart. Here, Ledger B is only as safe as key K, whoever holds it today.
Where Ledger B trusts a key, the key is the security. Ledger B checks a signature from the middleman's key, not anything from Ledger A. A stolen key, a colluding committee or a buggy signer produces a report that passes exactly the same check as a true one.

Wider than a phone; scroll it sideways if you need to.

Simulation

Who has to be honest for a message to be safe?

no attack yet
Design:
Ledger A its own validators "Ann sends 5 to Bo on B" Ledger B its own validators waiting… Committee B accepts anything 3 of them sign security = 3 of 5 keys 5

Wider than a phone; scroll it sideways if you need to.

Attack:
Pick a design, then try an attack. The question is always the same: what can a dishonest middleman make Ledger B believe?

Adding more keys raises the price of the attack. It does not change its shape: there is still a party in the middle whose failure Ledger B cannot detect, and every message is exactly as safe as that party. CLPR sets out to remove the party altogether.

Check yourself: In the committee design, what exactly does Ledger B check when a message arrives?

Only that three of the five committee keys signed it. It never sees anything from Ledger A. Whether the committee told the truth is not something Ledger B can find out.

Act II · The idea

Proof instead of trust

Replace the party in the middle with a proof the receiving ledger checks itself, see what that leaves out, and meet everyone a message passes through.

Section 4of 16

What CLPR does instead: proof, not trust

CLPR (“Clipper”, for Cross Ledger PRotocol) starts from the trick in section 1. Ledger A’s validators already sign summaries of their ledger as part of sealing lines. So instead of asking a middleman “what happened on A?”, Ledger B is handed a state proof: typically the validators’ signature on a summary, plus the path from that summary down to the exact line that says “Ann’s program sent this message”. Ledger B checks that the signature really is Ledger A’s, using the signing identity it keeps on file for A. Then it follows the path down to the line. Only when both hold, and its own checks on numbering and hashes pass, does it believe the message.

Ledger A validators jointly sign a summary of their ledger line 4,231 "send 5 to Bo on B" the seal is the validators' signature, not the endpoint's Endpoint carries the proof; hands it in as an ordinary transaction. Holds no key B cares about. Ledger B verifier + trust anchor checks A's identity on file CLPR Service receives the transaction, calls the verifier message accepted a new line on B proof proof calls endpoint's own key: not looked at The endpoint's own key is never part of the check. Only A's validators' signature is.
Check the seal, not the messenger. Ledger B compares the signature on the proof with the signing identity it already holds for Ledger A, then follows the path to the line. Who carried the proof does not enter into it.

Wider than a phone; scroll it sideways if you need to.

The party carrying the proof is still there; CLPR calls it an endpoint: a program that moves messages and their proofs between ledgers. But look at what it can and cannot do. It can deliver, delay, or refuse. It cannot forge a message, because none of its own keys can make Ledger B accept one. It cannot change a message either, because the changed message would no longer match the proof that came with it. Even with dishonest endpoints, no fabricated message can be accepted; whether messages keep arriving at all depends on at least one honest endpoint on each side.

Removing the middleman does not remove trust. It shrinks it to a short list you can read. For its messages to be genuine, an application using a channel trusts its own ledger, the CLPR software on both ledgers, the other ledger’s validators, the application on the other side, and the verifier the channel was created with. That last one deserves attention, because anyone can create a channel with any verifier they like. A channel existing does not mean its verifier is honest. Choosing a channel means choosing to trust its verifier, and applications, and whoever pays for their messages, are expected to check it before using the channel. Endpoints, and the accounts called connectors that pay for messages, are not on the list because they cannot forge anything; but messages only move while at least one honest endpoint on each side carries them and a connector pays.

Your application on Ledger A, the one sending the message trusts The short list what safety rests on; all inspectable Ledger A its own validators CLPR software on A the CLPR Service on your side CLPR software on B the CLPR Service on the other side Ledger B's validators the other ledger's consensus The application on B whoever receives the message The channel's verifier chosen by whoever created the channel the one entry you must check yourself not on the list Endpoint keeps messages moving can delay, cannot forge Connector pays for the message can refuse, cannot forge Narrowed, not removed: endpoints and connectors are off the list; the verifier is on it, unvetted by CLPR.
Trust, narrowed, not removed. Each entry is something you can evaluate before relying on it. Anyone can create a channel with any verifier, so choosing a channel is choosing to trust its verifier.

Wider than a phone; scroll it sideways if you need to.

Check yourself: An endpoint's server is hacked and its private keys are stolen. What can the attacker now make Ledger B believe?

Nothing new. What Ledger B verifies is Ledger A’s validators’ signature, which the attacker does not have. The stolen keys let the attacker spend the endpoint’s prepaid transaction account and stop or slow its deliveries; any other endpoint can take over the delivering.

Section 5of 16

What makes CLPR different

One idea, proof instead of trust, has consequences all over the design. Set beside the usual approaches, they come out as six things CLPR does without.

a network in the middle the ledgers talk directly proofs, not reports a committee's keys Ledger A's own signature checked by Ledger B itself a new token each ledger's own token pays fees, margins and fines pooled liquidity messages, not deposits no pool of user deposits one kind of ledger any ledger can join a Service, endpoints, verifiers an endpoint that forges it can delay, not forge endpoints carry, ledgers check One idea does the most: the receiving ledger checks the sending ledger's own proof.
Six things CLPR does without. No network in the middle, no committee whose keys decide, no new token, no pool of user deposits, no single kind of ledger, and no endpoint key whose theft lets anyone forge a message. Checking the sending ledger's own proof through the channel's verifier removes the middleman and the committee; fees are paid in each ledger's native token, and messages, not assets, move.

Wider than a phone; scroll it sideways if you need to.

The first two are the point of the previous sections: no trusted party sits between the ledgers, and the receiving ledger does its own checking. The next two follow from them. There is no new token, because every fee, margin and fine is paid in a ledger’s native token; and there is no pool of user deposits, because what travels is a message, and the only funds the CLPR Service holds are connectors’ funds and endpoints’ bonds. The fifth is what makes CLPR a pattern rather than a pair of chains: any ledger can join once it has a CLPR Service, endpoints and verifiers for its proofs, and the protocol itself does not change. The sixth is the one to remember when something goes wrong: an endpoint that is hacked, bribed or switched off can delay messages, but it cannot forge or change one.

One more property is easy to miss. If both ledgers are of the kind that keeps working correctly even when some of their own participants misbehave, the messages between them inherit that property, provided the channel’s verifiers are correct and at least one honest endpoint on each side keeps them moving.

Check yourself: A connector, the account that pays for a message, is also an intermediary. Why is it not 'a party in the middle' in the sense that matters?

Because it cannot make either ledger believe anything. A connector approves and pays; it does not carry or verify a message. If it refuses to pay, the message fails with a reply saying so, and nothing false has been accepted anywhere.

Section 6of 16

The cast

Before watching a message travel, meet everyone it will pass through. Each card gives the everyday description first; open it for the precise one.

Application

The program that wants to talk to another ledger. It implements two callbacks: one for when a message arrives, one for when a reply comes back.

as the spec puts it
On EVM: a contract implementing IClprApplication (onClprMessage and onClprResponse) that sends by calling IClprService.sendMessage. Each platform defines its own callback interface.

CLPR Service

The protocol's own part of each ledger. It keeps the outbound queues, checks the proofs, routes messages to applications, and handles the money.

as the spec puts it
The core on-ledger component: single source of truth for all CLPR state, holder of channels, connectors, endpoint manifests and locked funds. Native to the node on Hiero; a smart contract on EVM ledgers.

Channel

A standing agreement between two ledgers to exchange messages, with its own numbered queue in each direction and a fixed way of checking the other side's proofs.

as the spec puts it
An on-ledger entity representing a communication path to one specific peer CLPR Service, bound to one verifier contract for its lifetime. Many channels may exist between the same two ledgers.

Verifier contract

The specialist that knows how to check one particular ledger's signatures and proofs. Each channel picks one when it is created and keeps that address for life, though the code behind it may be upgradeable.

as the spec puts it
A contract implementing verifyConfig and verifyBundle, at an address fixed for the channel's lifetime; it may sit behind an upgradeable proxy. It authenticates state proofs from the peer against the channel's trust anchor and decodes bundle content into the local format.

Trust anchor

Who is allowed to sign for the other ledger right now. Stored per channel and only ever updated by a proof that the previous signers approved the change.

as the spec puts it
Opaque, verifier-defined bytes encoding the peer ledger's current signing authority. For Hiero: the ledger_id. For QBFT, in the specification: the validator set hash, the code hash and the epoch data (the EVM contracts encode a single validator address instead). Rotated only through verifyBundle.

Connector

The account that pays. It approves a message on the sending side and pays for running it on the receiving side. If it breaks that promise, it is fined.

as the spec puts it
An economic entity registered on both ledgers under the same derived id. Authorizes outbound messages, funds inbound execution, and is subject to slashing for connector-attributable failures.

Endpoint

The program that carries messages between ledgers. It watches its own ledger, collects proofs, talks to endpoints on the other side, and submits what it receives as an ordinary transaction. It cannot forge anything.

as the spec puts it
A node running the sync protocol: exchanging bundles with peer endpoints over gRPC, obtaining state proofs, pre-verifying, and submitting bundles. On Hiero every consensus node is one; elsewhere endpoints register and post a bond.

Message

A parcel of bytes plus an address. Three kinds share one queue: data (what applications send), responses (the answer to a data message), and control (protocol housekeeping).

as the spec puts it
ClprMessagePayload: a oneof of ClprMessage (Data), ClprMessageReply (Response) or ClprControlMessage (Control). Every Data Message produces exactly one Response Message, in order.

Bundle

A batch of messages that travels together with one proof covering the last of them.

as the spec puts it
An ordered batch of message payloads plus a state proof over the anchor message. The running hash chain extends the proof to every message in the batch.

State proof

A sealed receipt from a whole network, showing that a specific piece of data really is in its records.

as the spec puts it
A cryptographic proof that specific data exists in a ledger's committed state, verified against the trust anchor. State proofs are CLPR's sole mechanism of cross-ledger trust.

Running hash

A hash of everything ever sent on a channel, updated with each message so that nothing can be inserted, removed or reordered unnoticed.

as the spec puts it
SHA-256(previous_running_hash ‖ serialized_payload) in the specification (the EVM contracts hash the payload first: sha256(previous ‖ sha256(payload))), initialised to 32 zero bytes, kept separately for sent and received messages.

CLPR Service admin

The emergency brake. Can change the ledger's published limits, admit and evict endpoints, and close channels.

as the spec puts it
Exclusively protective authority: configure and close. Cannot create channels, register connectors or take part in economic activity. The network operator or governing body on Hiero; whoever controls the CLPR Service contract on EVM.
Ledger A may sit in the node Application sends, receives Service admin emergency brake CLPR Service · the on-ledger core state lives here Channel queue + running hash Connector locked stake Verifier address + trust anchor address fixed; checks B's proofs Endpoint reads the outbound queue, talks to B's endpoint sends Bundle travels data message reply housekeeping one state proof Ledger B may sit in the node Application receives, replies Service admin emergency brake CLPR Service · the on-ledger core state lives here Channel queue + running hash Connector locked stake Verifier address + trust anchor address fixed; checks A's proofs Endpoint submits it as an ordinary transaction delivers Nothing the endpoint carries is accepted on its word; all of it is checked inside the receiving service.
Three kinds of cast member. State that lives inside a ledger's CLPR Service (each channel with its trust anchor and verifier address, and each connector's registration and locked stake), things that travel (message, bundle, state proof), and the programs around them (an application on each ledger, the endpoint beside both: a separate program on an EVM ledger, part of the node on Hiero, the admin). Nothing the endpoint carries is accepted on its word; it is checked inside the receiving service.

Wider than a phone; scroll it sideways if you need to.

Act III · One message, end to end

The journey, the running hash, the money, the failures

Follow one message there and back, then see what keeps it honest, who pays for it, and what happens when something breaks.

Section 7of 16

The message journey, step by step

Here is the whole thing at once, and it is the heart of this page. On the left, a ledger running the Hiero software. On the right, an EVM ledger whose validators seal blocks by a method called QBFT consensus. An application on the left sends the word “ping” to its twin on the right; the twin sends an answer back. Twenty-eight steps, two proofs, one reply. The switch at the top runs the same trip in the other direction, which proves itself with different cryptography.

Each piece of the diagram lights up as the message reaches it; that is the story.

Simulation

One message, there and back: the 28 steps

step 0 / 28
Two ledgers, their CLPR Services, queues, connectors, verifiers and endpoints, with a message travelling from the left ledger to the right and its reply coming back. Hiero ledger CLPR Service is native to the node Application sends, gets the reply CLPR Service Outbound queue running hash Verifier for QBFT proofs Connector authorizes & pays sync data · trust anchor Endpoint every consensus node consensus · threshold-signed blocks EVM ledger CLPR Service is a smart contract Application receives, answers CLPR Service Verifier for Hiero proofs Outbound queue running hash Connector pays on arrival sync data · trust anchor consensus · QBFT sealed headers Endpoint separate process gRPC JSON-RPC

Wider than a phone; scroll it sideways if you need to.

Before you press play

What you are looking at

Two ledgers. Each has an application, a CLPR Service with an outbound queue, a connector that pays, and a verifier that checks the other ledger's proofs. Endpoints carry messages between them: on the Hiero ledger every consensus node is one; on the EVM ledger it is a separate program. Press Play or step through with Next.

  1. Getting in line
  2. 1sendMessage()
  3. 2channel checks
  4. 3quota
  5. 4authorize()
  6. 5config sync
  7. 6enqueue
  8. Proving it happened
  9. 7TSS signature
  10. 8gRPC open
  11. 9fetch proof
  12. 10gRPC send
  13. 11pre-verify
  14. Crossing
  15. 12submitBundle()
  16. 13verifyBundle()
  17. 14hash chain
  18. 15gas budget
  19. 16onClprMessage()
  20. 17settle gas
  21. 18reply queued
  22. 19BundleProcessed
  23. Coming home
  24. 20QBFT proof
  25. 21gRPC back
  26. 22HAPI submit
  27. 23verify seals
  28. 24verify state
  29. 25ordering
  30. Closing the loop
  31. 26onClprResponse()
  32. 27delivered
  33. 28complete

Three things stand out after watching it. Everything from step 12 to step 19 is a single transaction on the receiving ledger: if verification or the bookkeeping checks fail, none of it lands; if they pass, it lands whole, and an application that fails does not undo it, because the failure becomes the reply. Every data message that is accepted produces exactly one reply, whether the application liked it or not; the reply is what lets the sending ledger tidy its queue and check that answers come back in order. And the two directions prove themselves completely differently, with one joint signature going right and a sealed block header plus a storage proof coming back, under identical rules about numbering, hashing and ordering.

re-checked: 13-14 re-checked: 23-24 Ledger A steps 1-6 one transaction: checks, payer says yes, queue + running hash Endpoints steps 7-11 off-chain: fetch the proof, send the bundle, dry-run Ledger B steps 12-19 one transaction: check the proof, pay the endpoint, run the app, reply Endpoints steps 20-21 off-chain: build the return proof, send it back, dry-run Ledger A steps 22-28 back on chain: check the reply, call the app, delete original Steps 7-11 and 20-21 happen off-chain; nothing counts until 13-14 and 23-24 have checked it.
Three on-chain stretches, two off-chain gaps. Steps 1-6 are one transaction on the sending ledger and steps 12-19 one transaction on the receiving ledger; a bundle that fails its checks is rejected whole, while one message's failure becomes a failure reply. The work in between (7-11, 20-21) happens off-chain: the ledger's validators sign, then an endpoint fetches, carries and dry-runs it, and it is re-checked the moment it comes back on chain.

Wider than a phone; scroll it sideways if you need to.

Check yourself: Which steps could a dishonest endpoint change, and what would happen?

None of them, usefully. Steps 8 to 11 and 20 to 21 are the endpoint’s own work, but everything it produces is checked at steps 13 to 14 and 23 to 24 against signatures it cannot make. A tampered bundle is rejected and the endpoint has paid a transaction fee for nothing.

Section 8of 16

One proof for a whole batch

Step 6 of the journey mentioned a running hash. It is simple and it does a lot of work.

Every message added to a channel’s queue is given the next number in line and a running hash: a hash computed from the previous running hash and the message itself. (A hash is a short digest of some data; change one character of the data and the digest comes out completely different.) Change any message, drop one, or swap two, and every running hash after that point comes out different. The receiving ledger continues the chain from its own last running hash over the new messages it was handed and compares the final value with the one Ledger A’s validators signed. The numbers below are real SHA-256 hashes, computed in your browser.

Simulation

Five messages, one chain of running hashes

chain intact
#messagerunning hash after itproven?check
1 ping … -
2 pay Bo 5 … -
3 config update … -
4 ping … -
5 pay Cy 2 … 🔏 anchor

🔏 anchor: …

Each running hash is computed from the previous running hash and the message. Try changing something and watch where the chain breaks.

This is why an endpoint can carry a batch of, say, forty messages with a proof covering only the last one. The receiver continues the chain from its last stored hash over the new messages it was handed, and if its last running hash matches the proven one, every message in the batch is proven too. The numbering does a second job: the receiver remembers the last number it processed and rejects a bundle whose first message is not the next number, so an old bundle cannot be delivered twice even though its proof is still perfectly valid. The EVM contracts are more lenient here: they skip leading messages they already have instead of rejecting the bundle.

change this one message 1 ping message 2 pay Bo 5 … message 40 the last in the batch H0 32 zero bytes H1 SHA-256(H0‖m1) H2 SHA-256(H1‖m2) … 3 to 39 H40 the anchor Validators' signature covers H40 only signs then H2, H3 … H40 all change, and the signed H40 no longer matches Hn = SHA-256( Hn-1 ‖ message n ), H0 = 32 zero bytes Each running hash folds in the one before it; change anything and the proven last value no longer matches.
A chain, not a list of hashes. Each running hash is SHA-256 of the previous running hash joined to the message, starting from thirty-two zero bytes; the EVM contracts still hash the message first and chain that hash. Only the last one is covered by the validators' signature; because every earlier message feeds into it, that one signature vouches for all forty.

Wider than a phone; scroll it sideways if you need to.

Section 9of 16

Who pays, and who gets paid

Somebody has to pay for all this. Delivering a message means an endpoint submits a transaction on the receiving ledger, and that transaction runs the application there. Submitting that transaction costs a fee, which ledgers call gas; endpoints are not charities.

CLPR introduces no new token. Instead it has a role called the connector: an account that agrees to pay. The same connector is registered on both ledgers under one identity. On the sending side the connector is asked, before the message is even queued, whether it will cover this one. On the receiving side the connector is charged for the gas the application actually used, plus a margin, and the whole amount goes to whoever submitted the bundle. That margin is what makes submitting bundles worth an endpoint’s while.

Ledger A sending side Application wants to send #41 CLPR Service A asks before queuing Connector on A "cover #41?" yes Outbound queue #41 queued 1 send 2 approve? 3 yes, queue it Ledger B receiving side Connector on B charged the gas used plus a margin Endpoint fronts the fee CLPR Service B runs the application Application on B uses some gas 4 submit, pay the fee 5 run 6 charge 7 the whole charge, margin included same identity on both ledgers Approved on the sending side, charged on the receiving side; the whole charge goes to the endpoint.
One connector, two moments. Before a message is queued, the connector on the sending ledger says whether it will cover it. After the message runs, the connector on the receiving ledger is charged the gas used plus a margin, and all of it goes to the endpoint that submitted the bundle. No new token, no treasury.

Wider than a phone; scroll it sideways if you need to.

Simulation

A message arrives on Ledger B. Who pays whom?

SUCCESS

Amounts are in "units" of Ledger B's native token. One unit buys 100,000 gas.

Happy path

charge 4.4 · balance 20

execution cost4 units (the submitter already paid this to Ledger B as the transaction fee)
connector charged4.4 units = 4 × (1 + 10/100)
submitter receives4.4 units, all of it
submitter's net+0.40 units; the margin
balance after15.60 units
reply to Ledger ASUCCESS (or APPLICATION_ERROR if the application reverted; no penalty either way)
back on Ledger Athe reply is delivered to the sending application; the source connector is charged as for any message, and there is no fine
charge = 4 × (1 + 10/100) = 4.4 units The submitter fronted the transaction fee and is repaid with a margin on top. There is no protocol treasury: each charge is paid to whoever submitted the bundle, and when the reply arrives the source connector is charged and the Ledger A submitter paid in the same way. The margin is the profit for whoever runs the endpoint; drag the balance down to see what happens when the promise to pay is broken.

The connector’s approval on the sending side is a promise: my counterpart on the other ledger can pay for this, and I can pay for the reply. A connector locks up a deposit in advance, its stake. If the promise turns out to be false, the reply that comes home says so, and the fine is taken from that stake. Fines escalate, and repeated failures can get a connector banned from the channel, forfeiting whatever stake is left.

Applications choose their connector, and connectors can be as picky as they like: allow-lists, rate limits, charging a fee to the application. Several connectors can serve the same channel, and one operator can run connectors on many channels. Connectors, like applications, are expected to check a channel’s verifier before using it: a bad verifier puts the connector’s locked stake at risk.

send via the CLPR Service, naming the connector Application 1 names connector X Application 2 names connector X Application 3 names connector Y Connector X gate: allow-list, rate limit, fee from the sender service asks: yes or no Connector Y gate: accepts everything Channel 2 its own outbound queue Channel 1 its own outbound queue one operator, a connector each yes: queued two connectors, one channel no: reverts; the sender pays only for the attempt The application picks the connector; the connector decides; only approved messages reach the outbound queue.
Who picks whom. An application names a connector on every send, and the CLPR Service asks it. The connector can refuse, limit or charge; only what it approves is queued. Several connectors can serve one channel, and one operator can run connectors on many.

Wider than a phone; scroll it sideways if you need to.

Check yourself: Who is paid when a message is delivered, and who is not?

Only the account that submitted the bundle on the receiving ledger, and only from the connector. Nothing goes to the sending side for this delivery, and the reply’s trip back is paid the same way, to whoever submits it on Ledger A; there is no protocol treasury, and the endpoint that did the sending work earns nothing directly. Endpoints are expected to prefer partners that bring them messages in return.

Section 10of 16

What can go wrong

A protocol is defined as much by what it does when things go wrong as by what it does when everything works. Pick a failure and see what CLPR does.

Simulation

Pick a failure. What does the protocol do?

ACTIVE
application and connector
endpoints and peer ledger
ordering and limits
trust

The application on the other side crashes

What happensThe bundle still succeeds. The application's revert is caught and the reply carries APPLICATION_ERROR; the EVM contracts also put the revert data in it. Delivery worked; the application simply did not like the message.
Who paysThe connector pays for the gas used, as normal. No fine.
Channel stateACTIVE
Recovers?Nothing to recover. The sending application decides what to do with the error.
case: app · state: ACTIVE · source: design §3.3.3Thirteen cases; pick one above and the card and the state pill follow it.

Notice a pattern. A bundle that fails its checks (its proof, numbering or hashes) is rejected, changing nothing: the channel stays open and the next honest bundle goes through. A failure in a single message, such as an unknown or underfunded connector or an application that errors, becomes a failure reply and the rest of the bundle carries on. One failure is treated as a sign that something is broken rather than a passing glitch: replies arriving out of order. For that one, the channel is paused instead of guessing. Endpoints can only ever cause delay. The only failures that fine anyone are a connector failing to pay for a message as promised: the fine is taken from the connector’s locked stake.

what went wrong what the protocol does Endpoint trouble tampered · replayed · oversized a proof that fails the next honest bundle goes through Bundle rejected, nothing changes channel stays ACTIVE an endpoint can lose the fee it pays to submit Replies out of order the one failure treated as corruption, not noise paused instead of guessing Channel PAUSED no new sends resumes on a correctly ordered bundle Connector's broken promise not registered on the other side out of funds priced, not ignored Fined from locked stake the fine reimburses whoever submitted the bundle Endpoints can only cause delay: with all of them offline, messages wait in the queue. A broken promise costs the connector part of its stake; a rejected bundle costs its submitter.
Reject, pause, or fine. Nearly every failure is answered by rejecting a bundle and changing nothing. One is treated as corruption and pauses the channel; only the connector's failures are fined. With every endpoint offline, nothing is rejected: messages wait in the queue.

Wider than a phone; scroll it sideways if you need to.

Act IV · What you can build

What people build with it

The four patterns the protocol was designed around, the shapes of network that pairs of ledgers can form, and who runs what.

Section 11of 16

Four things people build with it

Everything so far is plumbing. Here is what the design anticipates people building on it; it outlines these patterns only at a high level, and none is specified yet. A message in CLPR is just bytes with an address, and every data message gets exactly one reply (as long as the channel and its endpoints keep working), so the same primitive could serve four quite different jobs.

Remote call application on A calls a proxy a message proxy on B invokes the target target contract does the work the result, later written for asynchronous answers Escrow, mint, burn 1 lock on A assets held in escrow 2 mint on B matching assets issued 3 burn on A if it worked release if it failed needs a common asset standard Atomic swap, N ledgers 1 each gets ready, and says so A B C all ready → all commit the changes land together one fails → all roll back nothing lands anywhere two-phase commit, carried as ordinary messages every ledger must speak the protocol Native Hiero assets Hiero network 1 a token, fungible or not moves by the messaging layer Hiero network 2 the same token, here no contract proxies CLPR-native handling Four patterns, one primitive: a data message that gets exactly one reply.
Four patterns the design outlines on one message primitive. A call to a contract on another ledger, with the result coming back later. Assets locked on one ledger and minted on another, released if the mint fails. Several ledgers changing state together or not at all. And Hiero tokens moving between Hiero networks with no contract proxies in between. All four are just messages with replies.

Wider than a phone; scroll it sideways if you need to.

Remote smart contract call

A contract on one ledger calls a proxy, which records the call. An endpoint carries it across, the proxy on the other ledger invokes the target contract, and the result comes back the same way. Applications have to be written for answers that arrive later, not in the same call.

Escrow, mint, then burn

Assets are locked on the source ledger, then minted on the destination. If minting succeeds the locked assets may be burned; if it fails they are released. Needs atomic semantics and a common asset standard.

N-ledger atomic swap

Several ledgers make state changes tied together by two-phase commit: each enters a ready-or-roll-back state, and if any one fails, all roll back. Every participating ledger must understand the others' commit messages.

Native Hiero asset management

Hiero tokens, fungible and non-fungible, handled across Hiero networks by the messaging layer directly, with no smart-contract proxies in between. The design outlines this in one sentence; it is not yet specified.

When several channels exist between the same two ledgers, for example one per Ethereum commitment level, the application picks one at send time by its own needs: a price feed may accept the risk of a reorganisation for speed, a high-value transfer waits for finality. CLPR imposes no default.

The third pattern is worth watching, because it shows what the protocol does and does not do. Three ledgers are meant to change together or not at all. CLPR carries the messages and a reply for each; the decision to commit or roll back lives in the application that started the swap. The simulation draws one way such an application could use the protocol; the choreography is the site’s illustration, and the pattern itself is only outlined in the design.

Simulation · an illustration

Three ledgers change together, or not at all

idle
Ledger A the swap application starts it, keeps the tally its own change waiting Ledger B its application answers prepare and commit its change waiting Ledger C its application answers prepare and commit its change waiting channel A–B channel A–C

Wider than a phone; scroll it sideways if you need to.

Two-phase commit, carried as ordinary CLPR messages: first "get ready", then "commit" or "roll back". Every data message gets exactly one reply, which is what the tally relies on.
Check yourself: Why must the swap application, and not CLPR, keep the tally of who is ready?

Because CLPR knows nothing about swaps. It knows messages, replies, proofs and payment. Tying three ledgers’ changes together is a meaning the application gives to its messages, and only the application can decide what “everyone is ready” means for it.

Section 12of 16

Shapes of a network

A channel always joins exactly two ledgers. That sounds limiting. It is the opposite: because every pair agrees on its own, with its own queues and a verifier chosen for it on each side, any shape you can draw from pairs is a shape you can build, and the protocol puts no trusted party in the middle of any pair.

channel channel channel channel Ledger B one channel to the hub Ledger C one channel to the hub Ledger D one channel to the hub Ledger E one channel to the hub Hub ledger four channels one application that forwards no channel between B and C: no path, unless the hub's application forwards CLPR knows pairs; shapes are what applications build from them.
A star is four pairs. One ledger holds a channel with each of four others. Every spoke is its own agreement, with a verifier chosen for it on each side and its own queues. CLPR defines channels between two ledgers only: a message from B to C has no path unless an application on the hub receives it and sends it on as a new message of its own.

Wider than a phone; scroll it sideways if you need to.

Ledger A three channels Ledger B three channels Ledger C three channels Ledger D three channels no trusted party in the middle six pairs, a verifier per side Ledger E joining opens a channel to each partner every pair agrees on its own; nobody has to agree for everyone.
A mesh is six pairs. Four ledgers, a channel between every two: six agreements, each with its own queues and a verifier named on each side, and no trusted party in the middle. A fifth ledger joins by opening a channel to each partner it wants; each of those partners gains a channel and a verifier for it, and the channels already there are unchanged.

Wider than a phone; scroll it sideways if you need to.

The one thing to keep straight is that CLPR itself knows only the pairs. Nothing in the protocol forwards a message from one ledger to a third through a second. In the star, a message from one spoke to another has no path, unless an application on the hub receives it and sends a new message of its own to the other spoke, under its own connector and its own channel. That is a perfectly good thing to build; it is an application, not a protocol feature.

Simulation · an illustration

Shapes you can build from pairs

a star
Shape:
Ledger A Ledger B Ledger C Ledger D Ledger E Four channels, each between two ledgers; the hub holds all four.

Wider than a phone; scroll it sideways if you need to.

From:
To:
Pick a shape, then send a message between two ledgers. The question is always: is there a channel between exactly these two?

The pair that matters most to many organisations is a private network and a public one. A ledger that does not want to expose any infrastructure lists its endpoints without an address to dial. Its endpoints then always dial out and are never dialled, and once the connection is open, messages flow both ways over it. That is how a private enterprise network talks to a public one without opening a door.

Private network an enterprise ledger behind its own walls CLPR Service queues, channels, the proofs it checks endpoint listed with no address dials out; is never dialled Public network anyone can reach it CLPR Service queues, channels, the proofs it checks endpoint listed with an address accepts the connection dials out messages both ways A private ledger that publishes no endpoint address only dials out; nobody has an address to call.
Private to public, without opening a door. A private network lists its endpoints without an address to dial. Its endpoints dial out to the public network's endpoints, which are listed with addresses, and messages then flow both ways over that connection. Nothing on the private side has to be reachable from the internet.

Wider than a phone; scroll it sideways if you need to.

Check yourself: Two ledgers both have a channel to the same third ledger. Can one send the other a message?

Not through CLPR alone. There is no channel between them, and CLPR defines channels only between two ledgers. Either they open their own channel, or an application on the third ledger receives the message and sends a new one on, as its own message with its own proof and its own payer.

Section 13of 16

Who runs what

CLPR is operated by people in six roles, and the design has a quiet rule about them: whoever would lose money is whoever does the checking.

one channel a verifier on each side, a queue each way User uses an application Application developer picks the channel and the connector Connector operator a balance to pay, a stake to lose Verifier developer writes the verifier Endpoint operator fronts the fees, earns the margin Service admin adjusts settings, closes channels Whoever would lose money is whoever does the checking.
Six roles around one channel. A user uses an application; its developer picked a channel and a connector; the connector operator put up a balance and a stake; a verifier developer wrote the verifier the channel runs; endpoint operators front the fees and earn the margin; the service admin can configure the ledger, admit endpoints and close channels. Whoever would lose money is whoever does the checking.

Wider than a phone; scroll it sideways if you need to.

RoleWhat they doWhat they risk
End userUses applications. Evaluates an application before using it and watches for degraded service; never touches the protocol directly.Application bugs, poor channel or connector choices, a channel closed while messages are in flight, and finality risk if a verifier accepts proofs below finality. Escrowed assets should be settled before stopping.
Application developerSends messages and handles the responses in callbacks, naming a channel and a connector on every send. Keeps both configurable, watches connector health and channel status, and migrates when a proof format changes.Every cross-ledger payload is untrusted input; payloads sit on chain in plaintext unless the application encrypts them; a compromised verifier can mean direct loss of assets.
Connector operatorOften also creates the channel: deploys a verifier, registers the channel, then registers as a connector on both ledgers. Keeps a balance to pay for execution and a locked stake that covers fines; may run allow-lists and rate limits.An empty balance fails messages and slashes the stake with escalating penalties; a lapsed registration fails them too; removal is blocked while messages are in flight.
Verifier developerAn off-chain role with no protocol identity: writes the contract that checks one ledger's proofs. Ledger implementers, connector operators, application developers with high-value flows and auditors all have reasons to.Proof format changes need new implementations; an upgrade key on a verifier is a single point of compromise; the protocol pays nothing for maintenance.
Endpoint operatorOn Hiero, nothing: every consensus node is an endpoint automatically. Elsewhere, registers with a bond, is admitted by the service admin, serves every channel on the service, and pre-funds the account that submits bundles.Invalid, failed or duplicate submissions cost unreimbursed fees; misbehaviour means eviction, with the bond returned in full.
CLPR Service adminBroad but only protective powers: adjusts the ledger's published limits, admits or evicts endpoints, closes channels and, where the service has a kill switch (the EVM contracts do), turns it on or off. Cannot create channels, register connectors or take part in the economics.Abuse of power, mitigated by governance; inaction, since a compromised channel left open keeps being exploited; and no in-protocol incentive, a known gap between responsibility and motivation.

A few things follow from the table. The admin, the only role with any special power, has the least incentive to watch closely, a known gap between responsibility and motivation. The verifier developer is not registered anywhere in the protocol and holds no stake, yet every channel’s safety rests on the verifier they wrote. And the connector operator is expected to be the careful one, because their locked stake is at risk if the verifier is compromised.

The roles rarely act alone. Four stories show them working together: setting up a new route between two ledgers, upgrading when a ledger changes how its proofs look, responding to a verifier that turns out to be compromised, and a connector withdrawing while messages are still in flight.

Step-through

Four stories: the roles working together

step 0
Story:
End user Application developer Connector operator Verifier developer Endpoint operator CLPR Service admin

Wider than a phone; scroll it sideways if you need to.

Setting up a new cross-ledger route

Before anything happens

Press Next to walk through the 4 steps. The roles that act in each step light up above.

story 1 · step 0Four stories, six roles. Each step names who acts; nobody acts alone for long.
Check yourself: A verifier is found to be compromised. Who acts first, and what is the window of danger?

The verifier developer, by issuing a security advisory; the service admin then closes the affected channels so no new messages are accepted while the ones in flight finish. The window of danger is the time between the vulnerability being discovered and the channels being closed. Then the verifier developer publishes a fix, connector operators open new channels with it, and applications move over.

Act V · The edges, and the lab

Adding ledgers, limits, and where CLPR lives

How a new kind of ledger joins, what CLPR deliberately does not do, and where the code and the people are.

Section 14of 16

Adding a new kind of ledger

CLPR is a pattern, not a pair of chains. Adding a new kind of ledger needs no change to the protocol or to existing implementations; anyone can deploy the new verifier on a ledger it connects to and register a channel there. It needs three things. First, a CLPR Service on the new ledger. Second, endpoints that can build proofs in the new ledger’s format. Third, a pair of verifiers: one runs on the new ledger and checks the existing ledger’s proofs; the other runs on the existing ledger and checks the new ledger’s proofs.

Step-through

Adding a new ledger type

step 0 / 8
New ledger type Hiero network CLPR Service Endpoints Hiero verifier(runs here) Connector Application CLPR Service Endpoints(every node) New-ledger verifier(runs here) Connector Application deployed deployed Channel (verifier addressfixed on each side) endpoint lists,proved on-chain

Wider than a phone; scroll it sideways if you need to.

Before you start

The pattern that makes CLPR extensible

The CLPR Service implementation on existing ledgers does not change when a new one joins; they only gain a verifier and a Channel. The alignment between the new ledger's endpoint (which builds bundles in that ledger's format) and the verifier it ships for other ledgers (which reads that format) is the whole trick.

step 0 / 8 · existing CLPR Services stay as they are

The reason this works is that the CLPR Service never looks inside a proof. It hands the proof to the channel’s verifier without reading it, and gets back a list of checked messages written the same way for every kind of ledger. Whatever the new ledger’s cryptography looks like, it is contained inside its verifier and its endpoints, and the rest of the protocol is untouched.

Today the kinds of ledger with a verifier are these. Two are fully documented and built; the others exist as code without a document, or as a stand-in for testing.

Kind of ledgerWhat its proof isIts CLPR ServiceIts endpointsStatus
Hiero networks: Hedera and private HashSpheres A joint threshold signature by the network's validators over a summary of its state, plus the paths down to each record it proves Built into the consensus node Every consensus node is one documented and built
EVM ledgers running QBFT A block header carrying the validators' seals, plus a proof of the storage slots that hold the data Solidity contracts The endpoint program documented and built
Ethereum mainnet Sync-committee signatures checked by a light client Solidity contracts None: the endpoint program does not support it verifier code only
Sei, a CometBFT network CometBFT validator signatures (Ed25519) Solidity contracts The endpoint program verifier code only
Avalanche Not implemented; a mock verifier stands in Solidity contracts None: the endpoint program does not support it stand-in only

Section 15of 16

What CLPR does not do

A page like this should be as clear about limits as about mechanisms.

Delivery depends on endpoints. If nobody runs an endpoint for a channel, messages sit in the queue. Nothing is lost or faked; nothing moves either.

Nothing is secret. Message contents sit on both ledgers in plain view. The protocol guarantees that a message is authentic and unaltered, not that it is private. Applications that need confidentiality must encrypt before sending; even then, when a message was sent, how big it is and who sent it stay visible.

Authentic is not the same as safe. CLPR proves a message really came from the other ledger. It says nothing about whether the message is sensible. An application must treat everything that arrives from across the water as untrusted input, exactly as it would treat a call from a stranger.

Message from Ledger A contents plus the sender; visible on both ledgers CLPR proves authentic ✓ unaltered ✓ in order ✓ seal plus running hash chain CLPR does not prove private ✗ sensible ✗ honest sender ✗ no check in the protocol Your application treats it as input from a stranger checked not checked delivered your decision Verified: the channel's verifier accepted proof it was sent; whether to act is the application's decision.
What verified does and does not mean. The protocol answers three questions: did this come from Ledger A, was it altered, is it in order. It says nothing about whether the message is private, sensible or sent by someone honest. Those stay with the application, which should treat every arrival as input from a stranger.

Wider than a phone; scroll it sideways if you need to.

A channel is no safer than its verifier. A channel’s safety rests on both ledgers’ consensus, both CLPR Services and its verifier, and its payments on connectors. Of these, the verifier varies most: anyone can create a channel with any verifier, and a verifier behind an upgradeable proxy can have its logic replaced later by whoever holds the upgrade key. The protocol’s own checks catch a verifier bug that garbles messages, because the running hashes will not match; they cannot catch a lying verifier that fabricates messages and matching running hashes. Vetting verifiers, and who can upgrade them, is human work.

the verifier running hash check outcome who catches it Buggy verifier returns garbled messages Running hash check expected ≠ computed does not match Rejected bundle refused The protocol its own checks Lying verifier fabricates messages and matching running hashes Running hash check expected = computed passes, on a lie Accepted the protocol cannot tell A human vetting the verifier before trusting it The running hash chain catches garbled messages; only people catch a verifier that lies.
Buggy versus lying. A verifier bug that garbles messages is caught: the garbled messages do not match the running hashes and the bundle is rejected. A verifier that lies produces running hashes that match its own lies, and nothing in the protocol can tell. Anyone can create a channel with any verifier, so vetting verifiers is human work.

Wider than a phone; scroll it sideways if you need to.

Some ledgers can rewrite recent history. On some networks a block is not final the moment it is made; for a while the network can still drop it and replace it. A verifier that accepts a block that fresh risks a “phantom message”: one delivered on this side whose sending block the source ledger later threw away. How final a block must be is a property of each channel’s verifier, and CLPR does not check it. For anything valuable, use a channel whose verifier accepts finalized blocks only; two channels between the same ledgers can differ.

Ledger A's chain of blocks Two channels into Ledger B block block block finalized cannot be undone block block recent still tentative newest block "send 5 to Bo" a different block, no such line reversed replaced after the fact Channel "fast" verifier accepts the latest block delivered it at once the block is reversed Phantom message on B "send 5 to Bo" ran on Ledger B; the line no longer exists on A Channel "finalized" verifier accepts finalized blocks only still waiting; it never delivers it The verifier sets how final a block must be; anything high-value belongs on a finalized-only channel.
How sure is sure enough. On ledgers where recent blocks can be undone, a verifier that accepts the latest block is fast but can deliver a phantom message. One that accepts finalized blocks only is slower and never delivers one. Two channels between the same ledgers can use different verifiers.

Wider than a phone; scroll it sideways if you need to.

Some things are not settled yet. These are the open questions:

  • Anyone can register a channel claiming any chain id. Channel creation needs nobody's permission, so anyone can construct a ledger configuration with any chain id they like. An application has to check for itself that a channel really leads to the ledger it intends; a channel's existence proves nothing about its peer.
  • Open endpoint registration rests on admin curation. Where anyone can register an endpoint, keeping the list honest rests mainly on the admin admitting each one; the bond adds friction but is not sized against attack costs on any particular chain. Peers should be picked with some randomness so no two endpoints pair up for good. On Hiero the network's own stake-weighted consensus covers this.
  • A verifier behind an upgradeable proxy can change under a channel. The verifier's address is fixed for a channel's life, but the contract at that address may be a proxy whose logic can be replaced without the protocol noticing. The protocol allows it; anyone evaluating a channel should check whether its verifier is a proxy and who holds the upgrade key.
  • How large a connector's stake must be is not yet quantified. A connector's locked stake must cover the worst case: on the receiving side, the cost of running in-flight messages from a connector that has run dry; on the sending side, the fines for failed deliveries. A bond that is too small lets an attacker drain endpoints of more execution cost than the fines can repay. The minimum is a design parameter still to be quantified before production.
  • One connector could fill a shared queue. A single connector could approve enough messages to fill a channel's queue and block everyone else on it. Candidate answers: money escrowed per message and returned when the reply arrives, a per-connector share of the queue, or prices that rise as the queue fills. Unresolved before production.
  • The admin has duties but no reward. The service admin must close a compromised channel promptly and gains nothing in the protocol for doing so: a known gap between responsibility and motivation.

Beyond these, the authors keep a separate list of possible changes they have considered and not decided.

The protocol is young. The initial text is expected to change further to polish out rough edges; its major changes so far are recorded as dated decision records saying what was decided and why.

Section 16of 16

Where CLPR lives, and where this leaves you

CLPR is a set of ideas and also a set of files. Everything the lab publishes about the protocol is one of four kinds of thing. The specification says what must happen. The CLPR Service, the on-ledger part that holds every channel and queue, is built twice: once into Hiero nodes, once as contracts for EVM networks. The verifiers plug into a service. And the endpoint is the program that runs off the ledgers and carries bundles between them.

The specification text: it says what must happen must follow must follow must follow On a ledger Verifiers one per kind of ledger it reads CLPR Service the CLPR Service, built twice Hiero nodes EVM contracts plugs into Off-ledger: a server someone operates Endpoint the endpoint program a program on EVM submits ordinary transactions One text; one CLPR Service built twice; verifiers that plug in; an endpoint that runs off the ledger.
The four kinds of thing. The specification is text. The CLPR Service is built twice, once inside Hiero nodes and once as EVM contracts. Verifiers plug into a service. On an EVM ledger the endpoint is a separate program; on Hiero it is part of the node. Tap the map below for where each lives in code.

Wider than a phone; scroll it sideways if you need to.

Map

Everything CLPR is made of. Tap a piece.

nothing selected
The specification design document · protocol specification · verifier specs (Hiero, QBFT) · decision records Hiero network Applications Connectors CLPR Service · native service channels · queues · connectors · locked funds inside the consensus node, state in the Merkle tree system address 0x…016e Verifiers for peers' proofs (system contract / native) Endpoints · every consensus node fetch state proofs, build bundles EVM ledger (e.g. QBFT) Applications Connectors CLPR Service · Solidity contracts ClprService.sol router → logic modules channels · messaging · bundles · connectors · admin clpr-smart-contracts Verifier contracts: HieroVerifier, QBFTVerifier, … Endpoint · separate Java relay clpr-endpoint · JSON-RPC to the node gRPC sync gRPC sync · one exchange/cycle unproven requests, proven bundles a Channel on each side: same id, own verifier, own queue, own running hash LF Decentralized Trust lab · github.com/LFDT-CLPR clpr-spec · clpr-smart-contracts · clpr-endpoint · governance · .github · Apache-2.0, DCO, Labs charter

Wider than a phone; scroll it sideways if you need to.

The specification

Where: LFDT-CLPR/clpr-spec

The rulebook every other piece must follow. Two documents: a design document that explains the why (trust model, layers, roles, recovery) and a protocol specification that fixes the what (wire formats, state, algorithms, a pseudo-API). Alongside them, one folder per supported proof system saying exactly how that ledger's proofs are built and checked, and the decision records that explain the main changes made to the text.

Pinned: design document · protocol specification · verifiers/ · ADR/ · LICENSE · Labs charter (PDF)

selected: spec · LFDT-CLPR/clpr-spec

The two CLPR Services have no code in common. Both are written to the same text, down to the exact bytes a message is written as and the exact order of the checks, and both must conform to it; the contracts repository keeps a written list of where its code currently differs, and some of those differences are being settled by updating the text.

RepositoryWhat it holds
LFDT-CLPR/clpr-specProtocol specification (clpr-service.md, clpr-service-spec.md), ADRs and verifier documents. The primary source for every protocol claim on both pages.
LFDT-CLPR/clpr-smart-contractsSolidity CLPR Service, logic modules and Verifier contracts for EVM ledgers. Source of the application interfaces and of every pinned code link on the developer page.
LFDT-CLPR/clpr-endpointJava CLPR Endpoint (relay) for EVM ledgers: gRPC sync, proof construction, bundle submission. Source for the endpoint and sync-protocol sections.
LFDT-CLPR/governanceLab governance: LF Decentralized Trust Labs charter, teams and repository permissions. Source for the governance section.
LFDT-CLPR/.githubOrganization profile README: lab scope, terminology, the four layers and the extension process. Source for the 'what CLPR is' framing and the LFDT section.

The ideas come from earlier proposals for cross-ledger communication and from a practical need: Hiero-based networks, public ones such as Hedera and private ones called HashSpheres, needed fast, asynchronous messaging between them that stays correct even when some participants misbehave. Under its agreement with the Hedera Governing Council, Hashgraph wrote the initial text and built initial versions of the three pieces of software above; the endpoint is a prototype. CLPR is now an LF Decentralized Trust lab, part of a Linux Foundation project whose mission is to support development of very early open projects, under the technical oversight of the LF Decentralized Trust’s Technical Advisory Council; the Council undertook to donate the CLPR brand once the lab was accepted. The CLPR Service built into Hiero nodes is specified by HIP-1535, whose status is Approved, and is an opt-in service: networks that do not enable it are unaffected.

If you remember six things, remember these.

  1. A ledger is a shared record many machines keep in sync, and a network can jointly sign a proof that a particular line is in it.
  2. Two ledgers cannot see each other, and the usual fix, a trusted party in the middle, makes every message only as safe as that party.
  3. CLPR replaces the party with a proof: the receiving ledger checks the sending ledger’s own validators’ signature through the channel’s verifier, and trusts that verifier and the CLPR Service on each side to be correct.
  4. Endpoints carry proofs, but nothing they carry is taken on their word. They can delay; they cannot forge. Whether a message is genuine is decided on the ledgers (safety); whether it arrives at all depends on endpoints (liveness).
  5. Messages are numbered and chained into a running hash, so one proof covers a whole batch and nothing can be inserted, dropped, reordered or replayed.
  6. Connectors pay, endpoints are reimbursed with a margin, and a connector that breaks its promise is fined. Every accepted data message gets exactly one reply.
2 a trusted party in the middle not present Ledger A 1 a shared record many machines keep in sync; its validators sign proofs 5 outbound queue: numbered lines, chained by a running hash Endpoint 4 carries the proof, not trusted for safety: can delay, cannot forge Ledger B 3 its CLPR Service has the channel's verifier check A's validators' signature then it runs the program and queues the reply proof proof batch + proof delivers Connector 6 pays on both ledgers; fined if it breaks its promise reimbursed, with a margin exactly one reply per accepted data message Safety lives on the ledgers; liveness depends on endpoints; money comes from connectors.
The six things on one picture. Numbers match the list above: proofs from a ledger's own validators (1, 3) replace a trusted middleman (2); endpoints carry but cannot forge (4); numbered, chained messages let one proof cover a batch (5); connectors pay and endpoints are reimbursed (6).

Wider than a phone; scroll it sideways if you need to.

Repositories and commits

The LFDT-CLPR repositories and commits this explainer describes, as of 2026-11-02.

Four sections contain the site's own illustrations rather than statements about CLPR: section 2, section 3, section 11 and section 12. Everything else describes the commits below.

RepositoryCommitCommittedUsed for
LFDT-CLPR/clpr-spec 945082d 2026-08-31 Protocol specification (clpr-service.md, clpr-service-spec.md), ADRs and verifier documents. The primary source for every protocol claim on both pages.
LFDT-CLPR/clpr-smart-contracts 276c8d5 2026-09-01 Solidity CLPR Service, logic modules and Verifier contracts for EVM ledgers. Source of the application interfaces and of every pinned code link on the developer page.
LFDT-CLPR/clpr-endpoint 2ccd48d 2026-09-01 Java CLPR Endpoint (relay) for EVM ledgers: gRPC sync, proof construction, bundle submission. Source for the endpoint and sync-protocol sections.
LFDT-CLPR/governance 1447ae0 2026-10-28 Lab governance: LF Decentralized Trust Labs charter, teams and repository permissions. Source for the governance section.
LFDT-CLPR/.github 528e9c0 2026-10-28 Organization profile README: lab scope, terminology, the four layers and the extension process. Source for the 'what CLPR is' framing and the LFDT section.