# Concero Docs > Build the next big thing on Concero. ## Concero V2 Scalability ### The Interoperability Challenge The blockchain ecosystem is experiencing exponential growth in the number of networks, driven by advancements in blockchain development frameworks and rollup-as-a-service platforms. While launching new blockchains has become significantly more accessible, cross-chain connectivity solutions haven't evolved at the same pace, creating an expanding "interoperability gap." ![Blockchain Growth Projection](/images/concero-blockchains-projection.png) *Figure 1 – Projection showing the growing gap between the number of blockchains and the cumulative integrations supported by leading interoperability protocols.* ### Traditional Integration Limitations Conventional interoperability protocols face significant scaling challenges: #### 1. High Integration Costs * Engineering and audit costs typically range from **$100,000 to $250,000** per blockchain integration * Integration processes often take months to complete * Each new chain requires custom development work #### 2. Infrastructure Overhead * Most protocols require dedicated validator infrastructure for each new chain * Validators must run full nodes or light clients for every supported blockchain * Monthly infrastructure costs scale linearly with chain count * Some protocols inflate token supply to compensate validators for additional chains #### 3. Manual Configuration * Relayers require manual configuration for each new network * Limited automation in the onboarding process * Complex coordination between protocol teams and chain developers ### Concero V2's Scalable Architecture Concero V2 fundamentally reimagines interoperability as a universal utility that should be frictionless, low-cost, and available by default. This is achieved through several architectural innovations: #### Zero-Node Integration Model Unlike traditional protocols that require dedicated nodes for each blockchain, Concero V2 leverages existing public RPC endpoints through its **Trusted RPC Registry**. This eliminates the need for deploying new infrastructure when onboarding chains: * **Open-source registry**: Chain integrations happen through simple pull requests to the [Trusted RPC Registry](http://github.com/concero/v2-networks) * **Verification process**: RPC endpoints undergo validation before being approved * **Instant availability**: Once merged, chains become immediately available to the entire network #### Auto-Discovery Architecture Concero V2's relayer network features an auto-discovery mechanism that eliminates manual configuration: 1. New chains added to the registry are automatically detected by relayers 2. Relayers dynamically update their service capabilities 3. No downtime or manual coordination required 4. Seamless integration without service interruptions #### Economic Security at Scale Instead of requiring dedicated security for each chain, Concero V2 employs a unified security model: * **Symbiotic integration**: Relayers stake through the [Symbiotic](https://docs.symbiotic.fi) protocol to secure their operations * **Chain-agnostic security**: A single stake secures relayer operations across all supported chains * **Slashing mechanisms**: Incorrect behavior results in stake slashing, ensuring economic alignment * **Security that scales**: The security model remains constant regardless of how many chains are onboarded #### Streamlined Transaction Flow Concero V2's architecture maintains consistent performance regardless of how many chains are supported: 1. User initiates a cross-chain message on the source chain 2. Relayers detect the event and forward it to the Arbitrum-based Concero Verifier 3. Chainlink Functions validates the transaction presence on the source chain 4. Validation report is generated and sent back to the relayer 5. Relayer delivers the validated message to the destination chain 6. Destination chain verifies the report and processes the message This process remains constant regardless of which chains are involved, providing predictable performance across the entire ecosystem. ### Cost-Effective Scaling Concero V2 transforms the economics of cross-chain interoperability: #### Minimal Integration Costs * **$0 onboarding fee**: No six-figure integration costs * **$0.01 per message**: Fixed, predictable pricing model * **No inflation**: Protocol doesn't require token inflation to support more chains #### Fixed Infrastructure Requirements * **No additional nodes**: Adding chains doesn't increase infrastructure requirements * **Leverages existing infrastructure**: Uses established RPC providers * **Consistent operational costs**: Cost structure remains stable regardless of chain count ### Protocol Comparisons | Feature | Concero V2 | Traditional Interoperability Protocols | | --------------------- | ------------------------------------ | -------------------------------------- | | Chain Onboarding | Pull request to open-source registry | Custom integration process | | Integration Cost | $0 | $100k-$250k | | Time to Integrate | Hours/Days | Weeks/Months | | Node Requirements | Zero new nodes | Full/light nodes for each chain | | Relayer Configuration | Automatic | Manual | | Security Scaling | Fixed cost regardless of chain count | Cost scales with chain count | | Message Fee | $0.01 (fixed) | Variable, typically higher | ### The Future of Interoperability as a Utility Concero V2's architecture aligns with the vision of interoperability as a public good, similar to internet protocols like HTTP and SMTP. As blockchain deployment continues to commoditize, Concero provides the foundation for: 1. **Permissionless integration**: Any chain with public RPC endpoints can be integrated 2. **Seamless connectivity**: New chains are automatically connected to the entire ecosystem 3. **Consistent user experience**: End users experience reliable cross-chain messaging regardless of destination 4. **Future-proof scalability**: Architecture designed to support thousands of blockchains By transforming interoperability from a premium service to a universal utility, Concero V2 paves the way for a truly interconnected blockchain ecosystem capable of supporting the next generation of decentralized applications across thousands of specialized chains. ## Chainlink CRE as verifier Concero uses **Chainlink Runtime Environment (CRE)** to run its own message validation logic in a secure and decentralized way. This setup allows us to define custom off-chain verifiers that execute inside Chainlink’s Decentralized Oracle Network (DON) — providing both **customization** and **trust minimization**. ### What is the Concero Verifier? The **Concero Verifier** is a validator module built specifically for CRE. It is written and maintained by the Concero team and runs within Chainlink nodes in a hardened JS runtime. It is used as a part of the **Validation Stack** in Concero Messaging. Unlike general-purpose JavaScript or external oracles, the Concero Verifier: * Has native understanding of Concero message formats * Supports proof generation and verification logic specific to the protocol * Uses multiple RPCs to fetch and verify data from source chains * Aggregates results into signed **validation reports** ### Why CRE? Chainlink CRE provides a secure and reproducible off-chain execution layer with: * **Decentralized execution**: Verifiers run across DON nodes with threshold signature output * **Isolation**: Secure JS runtime separate from EVM logic * **Reliability**: Multi-RPC resolution and retries across nodes * **Consensus**: Reports require a quorum of node signatures to be accepted on-chain ### How it works 1. A Concero-integrated dApp emits a message on the source chain. 2. A relayer picks up the message and sees that it uses the **Concero Verifier** module. 3. The relayer calls into Chainlink CRE, which triggers the verifier on multiple DON nodes. 4. Each node: * Queries source chain RPCs * Finds the emitted message * Validates its content and metadata * Signs the result 5. The DON aggregates these signatures into a report and returns it to the relayer. 6. The relayer submits the report on the destination chain, where the Concero Router verifies it on-chain and executes the message. ### When to use The Concero Verifier in CRE is ideal for: * Applications requiring **off-chain verification with on-chain enforcement** * Teams that trust Chainlink’s DON as execution layer but want **full control over the validation logic** * Use cases that need **secure access to source chain state** without light clients ### Composable & Optional The Concero Verifier is one of many modules you can include in your message’s validation stack. It can be used alone or combined with other strategies like signature attestations, receipt proofs, or bonded relayers. ## Infrastructure Deployment Pipeline This page outlines the process followed by the Concero Team to deploy infrastructure on a new network. The pipeline ensures seamless integration of a new chain into the Concero ecosystem, including network configuration, contract deployment, and off-chain synchronization. The deployment process consists of the following sequential steps: *** #### 1. Chain Provides Gas Funding The target blockchain supplies initial gas funds to the Concero deployer and operator addresses. This enables them to execute transactions on the new network. *** #### 2. Registering the Network in [`@concero/v2-networks`](https://github.com/concero/v2-networks) The new blockchain network must be registered in the public GitHub repository [`@concero/v2-networks`](https://github.com/concero/v2-networks). This configuration enables Concero tooling and services to recognize and interact with the chain. > **This step can be completed by the chain team themselves.** > Please follow the instructions in the official guide: [Add Your Network](https://docs.concero.io/get-started/add-your-network) *** #### 3. Adding RPC Endpoints to [`@concero/rpcs`](https://github.com/concero/rpcs) RPC endpoints must be submitted to the [`@concero/rpcs`](https://github.com/concero/rpcs) repository so that verifier and operators can communicate with the new chain. > **Chain teams can also submit this information directly.** > Detailed steps are provided in the [Add Your Network](https://docs.concero.io/get-started/add-your-network) documentation. *** #### 4. Deployment of `PriceFeeds` The Concero Team deploys the `PriceFeeds` contract to the new chain, initializing it with the appropriate gas price parameters based on current market conditions. *** #### 5. Automatic Off-Chain Updater Integration The off-chain PriceFeeds updater service automatically discovers the new chain, loads the RPC endpoints and PriceFeeds deployment, and begins updating price data for the new network. No manual configuration is needed after contract deployment. *** #### 6. Deployment of `ConceroRouter` The team deploys the `ConceroRouter` contract to the new chain. During initialization: * All remote chains in the router are marked with `isChainSupported = false` * No cross-chain routing is yet enabled *** #### 7. Automatic Router Monitoring by Operator > *Operators will automatically detect and begin monitoring the newly deployed ConceroRouter.* However, cross-chain events will not yet be emitted because all remote chains are still marked as unsupported (`isChainSupported = false`). *** #### 8. CLF Verifier Module Update The Concero Team updates the Chainlink Functions (CLF) verifier module: * **Adding RPC endpoints** for the new network so CLF jobs can interact with it reliably * Registers the address of the new `ConceroRouter` > *(This process will soon be automated and fetched directly from Git.)* *** #### 9. Enable Cross-Chain Support Finally, the Concero Team enables full routing support by: * Setting `isChainSupported = true` on **all** remote routers for the new chain * Updating the **new ConceroRouter** to support all existing chains At this point, the new blockchain becomes a fully integrated part of the Concero network and can begin sending and receiving cross-chain messages. ## Concero V2 Relayers In **Concero V2**, relayers are **opt-in and per-message**. There is **no global relayer registration** and no “join/leave” flow. A relayer becomes usable as soon as it: 1. **deploys its own relayer contract** (a `relayerLib` that follows `IRelayerLib`), and 2. users **explicitly select it** in their message request. If a user doesn’t point to your relayer, you will never see (or be responsible for) their messages. > **Current status:** at the moment there is only **one relayer in production: `concero`**. ### Key idea: relayer = chosen `relayerLib` Concero’s router treats the relayer as a **contract address** (`messageRequest.relayerLib`) that defines two things: * **Pricing**: how much native fee is required to deliver a message (`IRelayerLib.getFee`) * **Authorization**: who is allowed to submit messages on behalf of that relayer (`IRelayerLib.validate`) So the network doesn’t maintain a “relayer set”. **Users pick the relayer by picking the relayer’s `relayerLib` address.** ### Relayer responsibilities (V2) If users select your relayer (`relayerLib`) you’re expected to: 1. **Monitor `ConceroMessageSent`** for your `relayerLib` 2. **Build a destination submission**: * gather validator proofs (`validations`) corresponding to the message’s validators * call `submitMessage(...)` on the destination router 3. **Maintain uptime + gas** on destination chains (and any infra needed to source proofs) 4. **Handle failed deliveries**: * resubmit if appropriate, * or use retry flow when a submission is marked retryable ### Notes for integrators * The router does **not** enforce “at least N validators must pass” at the protocol level; it forwards `validationChecks` to the receiver. Your receiver contract can decide what it requires. * If a user selects a relayer that is down, **no one else will deliver** unless that relayer resumes (because the authorization policy is defined by the chosen `relayerLib`). So relayer choice is a real trust/availability decision. *** ## Concero Motherboard Architecture ### Introduction Concero Motherboard is an open, modular messaging protocol enabling secure and scalable any-to-any network communication across EVM-compatible blockchains. It allows **any participant to act as a message relayer or validator**, providing a permissionless foundation for cross-chain interoperability. Concero V2 moves beyond fixed infrastructure and introduces **application-defined trust models**, letting developers select the exact validation logic that matches their use case. ### Key Shifts in V2 Concero V2 represents a paradigm shift from pre-configured bridging infrastructure to a **flexible, public messaging layer**: * **Permissionless architecture**: Anyone can run a relayer, contribute validation, or build custom delivery logic. * **Pluggable security stack**: Applications choose how strict or lightweight their security needs to be. * **Decentralized RPC sourcing**: Validation can be performed using multiple independent RPC endpoints. * **No centralized routing**: Messages are routed and validated by open actors, not hardcoded components. ### Message Lifecycle in V2 1. **Message creation** A message is emitted by a Concero-integrated smart contract on the source chain. The message includes metadata defining the required validation logic and delivery strategy. 2. **Relayer engagement** A relayer — optionally specified by the message sender — picks up the message from the source chain. This relayer acts as a delivery orchestrator but remains untrusted, since all validation is subject to verification on-chain. 3. **Off-chain validation orchestration** The relayer executes the specified *Validation Stack* **off-chain**, which may include: * Waiting for the required number of block confirmations or finality * Querying multiple RPC endpoints to verify chain state consistency * Invoking validator libraries or services to produce cryptographic proofs or attestations The relayer collects the necessary off-chain validation artifacts according to the rules defined by the application. 4. **Message delivery with proofs** Once the validation rules are satisfied, the relayer packages the message along with its corresponding proofs and submits them to the destination chain’s **Concero Router**. The router contract performs **on-chain verification** of the proofs, ensuring the message is authentic and valid. 5. **Execution** If the proofs are valid and meet the required security policy, the message is accepted and executed by the target application. ### Modular Components Concero V2 is composed of decoupled, reusable modules: * **Concero Router** — Entry point for incoming validated messages. * **Validator Libraries** — Modular validation logic that can be extended per application. * **Relayers** — Stateless agents that fetch, prove, and deliver messages. Each module can evolve independently, and developers may substitute custom logic where needed. ### Trust Flexibility = Broader Use Cases The modularity and openness of Concero V2 enable diverse use cases: * **DeFi protocols** enforcing strong finality with light client proofs * **Games** favoring low-latency, optimistic delivery * **Governance bridges** requiring multi-source agreement * **DAOs** using bonded relayers or slashable actors Concero V2 is an open interoperability protocol where security is a choice, not a constraint. ## What is Concero? Concero is an open, permissionless messaging protocol that enables secure, cross-chain communication. Originally conceived as a tightly integrated system, Concero has evolved into a fully decentralized platform where **any participant** can **deliver and validate messages** between supported networks. ### Why Concero? * **Open participation** — Anyone can run a relayer or validator node without permission or registration. * **Secure by design** — Messages are validated by a network of independent actors, ensuring tamper-resistance and fault tolerance. * **Cross-chain compatibility** — Concero connects multiple blockchains through a unified interface. * **Composable architecture** — Developers can integrate Concero at different levels: infrastructure, protocol, or application layer. ### How it works Concero is built around the concept of **flexible message security** — empowering applications to define their own trust and validation assumptions. Every message passing through Concero can be independently configured with a **custom security stack**, giving developers granular control over how messages are validated and accepted. #### Key features of Concero Messaging: * **Customizable block confirmations** Each message can specify its own finality rules. Applications may require a certain number of block confirmations (e.g. 6 on Ethereum, 12 on Polygon), or rely on native chain finality mechanisms like BFT consensus or finalized checkpoints. * **Multi-RPC verification** You can specify one or more RPC endpoints from which block headers and proofs must be fetched and cross-validated. This protects against reliance on a single RPC provider and improves fault tolerance. * **Validator diversity** Messages can be verified using one or more pluggable validator libraries — from simple block hash matching to full signature-based verification or even light clients. Validators are fully modular. * **App-defined quorum rules** Applications can define their own consensus logic — such as "at least 2 of 3 trusted validators must agree", or "at least 5 unique relayers must independently verify this message". Concero does not enforce a single trust model. Instead, it provides the primitives — validators, codecs, relayers, and message rules — allowing developers to assemble the security architecture that matches their risk profile and application needs. ### Use cases * Decentralized applications that need secure cross-chain function calls * Token bridging protocols requiring trust-minimized relaying * Oracle networks for cross-chain data feeds Concero is not a service — it's a **protocol** that anyone can run and extend. ## Enabling a New Class of Applications Concero is more than a messaging protocol, it is a foundational layer designed to unlock a new generation of sophisticated cross-chain applications. By removing critical limitations around data capacity and chain restrictions, Concero provides developers with the tools to build solutions that were previously not technically feasible. ![Concero's Applications Possibilities](/images/concero-v2-use-cases.png) The protocol's high-throughput messaging and adaptable security architecture support a broad spectrum of advanced use cases, but not limited to: * **Next-Generation DeFi:** Developers can create truly unified financial applications. This includes building multi-chain lending and borrowing platforms, executing atomic flash loans across disparate networks, and creating complex strategies that leverage liquidity from the entire blockchain ecosystem as if it were one. * **NFTs and Interoperable Metaverses:** Concero's ability to transmit up to 1.875 MB of data per message is transformative for digital assets. It enables large-scale NFT migrations that preserve full metadata and ownership history, which is a crucial feature for high-value collections. This also lays the groundwork for seamless metaverse experiences where assets and identities operate consistently across different virtual worlds. * **Decentralised Governance (DAOs):** The protocol allows for the implementation of reliable and multi-chain governance systems. DAOs can coordinate proposals, manage treasuries, and synchronise operations across their entire ecosystem, ensuring that decisions are executed securely and reliably on all relevant chains. * **Enterprise and Institutional Systems:** For use cases that demand high security and regulatory compliance, Concero's flexible security model is ideal. Developers can implement additional validation layers to build secure supply chain logistics, coordinate between private and public ledgers, and create other enterprise-grade solutions with tailored security guarantees. These initial use cases are just the beginning. As the foundational middleware for a borderless ecosystem, Concero offers developers significant freedom to architect the future of interoperable applications. ## Revolutionising Cross-Chain Security: The Dual-Layer Breakthrough Existing cross-chain communication protocols have historically been trapped between two imperfect approaches. * Pure cryptographic methods offer rigorous verification but suffer from prohibitive computational costs. * Conversely, economic security models rely on financial incentives but remain vulnerable to centralisation risks and potential coordinated attacks. Concero V2 introduces an innovative hybrid framework that go beyond these limitations by inventive combining cryptographic verification and economic accountability. This dual-layer approach creates a self-reinforcing security ecosystem where technological and economic mechanisms work in perfect synchronisation. ![Concero's Dual-Layer Security](/images/concero-v2-dual-layer-security.png) ### Cryptographic Layer: The Chainlink Functions Advantage At the core of the first security layer lies Chainlink Functions, a decentralised compute network that generates robust and tamper-proof cryptographic proofs. Unlike traditional single-point verification methods, this layer leverages a Decentralised Oracle Network (DON) consisting of four independent nodes. Each node independently validates transaction data, ensuring that consensus can only be reached through rigorous, multi-node verification. The verification process is meticulously designed. When a transaction is initiated, the system performs multiple security checks: * Signature recovery to confirm node authenticity * Consensus validation requiring at least three independent node contributions * Hash verification to ensure data integrity during transmission ### Economic Security Layer: Symbiotic's Innovative Restaking The second layer, implemented through Symbiotic's restaking infrastructure, introduces an economic security paradigm that transforms potential vulnerabilities into strengths. The protocol's slashing mechanism is particularly innovative. By requiring operators to stake significant economic collateral, Concero V2 creates a self-regulating ecosystem where operators are financially incentivised to maintain uptime, with slashing penalties applied only if they fail to post timely reports to the destination chain. Moreover, the challenge period has been dramatically reduced from traditional week-long windows to a mere 10-20 seconds, enabling unprecedented capital efficiency. ## Why Choose Concero? Choosing the right interoperability protocol is a critical decision for any cross-chain application. Concero is engineered to be the definitive solution for developers by providing a superior foundation built on three core pillars: security, efficiency, and universal connectivity. ### A Principled Approach to Security ![Concero's Security Model for Message Verification](/images/concero-v2-message-verification.png) In the world of interoperability, security cannot be an afterthought, it must be the architectural foundation. Concero is built on a dual-layer security model that combines cryptographic verification with economic accountability. This synergistic approach creates a self-regulating ecosystem where the cost and complexity of an attack far exceed any potential gain. By eliminating single points of failure, Concero guarantees the integrity and authenticity of messages, allowing developers to build with confidence. ### Seamless and Efficient Integration ![Concero's Integration Process](/images/concero-v2-time-cost.png) Concero dramatically reduces the technical and financial overhead associated with cross-chain development. Our innovative verification mechanism removes the need for costly and complex light client or full node infrastructure. This enables developers to achieve cross-chain integration with minimal effort and at no additional cost. This allows teams to focus resources on their core product and accelerate their time to market. ### A Framework for Universal Connectivity ![Concero's Universal Connectivity](/images/concero-v2-unlimited-chains.png) By design, Concero's modular architecture supports any blockchain, which allows applications to operate beyond the constraints of a limited ecosystem. The protocol decouples message propagation from validation, creating a universal framework that can connect to any network, regardless of its underlying design. This provides immediate support for EVM-compatible chains and Layer 2 solutions, with a clear path to integrating non-EVM chains, ensuring your application is ready for the future of a multi-chain world. ## Add Your Network :::steps #### Fund Concero wallets & operators with gas To enable Concero's cross-chain messaging protocol to operate on your network, fund the following addresses with corresponding gas amounts: | Address | Type | Amount to send | | ------------------------------------------ | ---------------- | -------------- | | 0xDddDDb8a8E41C194ac6542a0Ad7bA663A72741E0 | Testnet Deployer | 0.1 ETH | | 0xddDd5f804B9D293dce8819d232e8D76381605a62 | Mainnet Deployer | 0.1 ETH | | 0xeee38505c47acba0c866df7265bd3e25da596b27 | Operator | 0.01 ETH | #### Create a pull request to the Concero v2-networks repository After funding the operators, submit your network configuration through a pull request to [Concero v2-networks repository](https://github.com/concero/v2-networks): 1. Fork the [v2-networks repository](https://github.com/concero/v2-networks) 2. Create a new branch named `add-[YOUR_NETWORK_NAME]` 3. Follow the PR guidelines in the [README.md](https://github.com/concero/v2-networks/blob/master/README.md) 4. Submit a pull request, so the Concero team can review your submission. We may request changes or additional information before merging your network into the repository. ::: ## Receive a Message On the **destination chain**, your contract receives Concero messages through `conceroReceive(...)`, which is called by the **ConceroRouter** after the relayer submits the message and validators are checked. Concero provides two base contracts to make this safe and consistent: * **`ConceroClientBase`**: minimal base that enforces *router-only calls*, *allowed relayer libs*, and lets you define your own validator policy. * **`ConceroClient`**: an opinionated base that enforces a *strict consensus policy* (all required validators must approve + allowlist). You implement hooks depending on which base you use: 1. If you inherit `ConceroClientBase`, implement `_validateMessageSubmission(...)` for your security policy. 2. Implement `_conceroReceive(messageReceipt)` for your application logic (decode the receipt and use the payload). ### What gets called on the destination chain #### External entrypoint (called by the router) ```solidity function conceroReceive( bytes calldata messageReceipt, bool[] calldata validationChecks, address[] calldata validatorLibs, address relayerLib ) external; ``` You generally **do not override** this in app code. `ConceroClientBase` already implements it and performs critical checks before calling your internal hook. ### Built-in safety checks (ConceroClientBase) `ConceroClientBase.conceroReceive(...)` enforces: #### 1) Only the trusted router can deliver ```solidity require(msg.sender == i_conceroRouter, InvalidConceroRouter(msg.sender)); ``` This prevents anyone else from spoofing deliveries. #### 2) Only allowed relayer libs can be used ```solidity require(s_conceroClient.isRelayerLibAllowed[relayerLib], UnauthorizedRelayerLib(relayerLib)); ``` Even if a user chose some `relayerLib` on the source chain, **your app decides** which relayer libs it accepts on the destination chain. #### 3) Your validator policy must pass ```solidity _validateMessageSubmission(validationChecks, validatorLibs); ``` #### 4) Then your business logic runs ```solidity _conceroReceive(messageReceipt); ``` ### Choosing a validation policy #### Option A — Use `ConceroClient` (strict consensus) `ConceroClient` requires: * `requiredValidatorsCount` is set (> 0) * `validationChecks.length == validatorLibs.length == requiredValidatorsCount` * **every** `validationChecks[i]` is `true` * every `validatorLibs[i]` is allowlisted (`isValidatorAllowed[validatorLibs[i]] == true`) This is the safest default if you want a simple rule: *exactly N validators, all must approve*. #### Option B — Implement your own policy in `ConceroClientBase` For example: * “2 of 3 validators must approve” * “validator A required, plus at least one of B,C” * “accept if ANY validator approves” (not recommended, but possible) ### How to read message data Your app logic receives a single `bytes calldata messageReceipt`. Use `MessageCodec` helpers to decode what you need. Common fields: ```solidity uint24 srcChainSelector = messageReceipt.srcChainSelector(); uint256 nonce = messageReceipt.nonce(); (address srcSender, uint64 srcBlockConfirmations) = messageReceipt.evmSrcChainData(); (address receiver, uint32 gasLimit) = messageReceipt.evmDstChainData(); bytes memory relayerConfig = messageReceipt.relayerConfig(); bytes memory payload = messageReceipt.payload(); ``` ### Example: Minimal receiver using `ConceroClient` + decoding payload This example: * accepts deliveries only from the trusted router, * allows only a specific `relayerLib`, * requires strict validator consensus (via `ConceroClient`), * decodes the source sender and payload. ```solidity // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.28; import {ConceroClient} from "@concero/contracts/ConceroClient/ConceroClient.sol"; import {MessageCodec} from "@concero/contracts/common/libraries/MessageCodec.sol"; contract MessageReceiver is ConceroClient { using MessageCodec for bytes; event ConceroMessageAccepted( bytes32 indexed messageId, uint24 indexed srcChainSelector, address indexed srcSender, bytes payload ); constructor(address conceroRouter) ConceroClient(conceroRouter) {} /// @dev Your app logic: decode receipt + handle payload function _conceroReceive(bytes calldata messageReceipt) internal override { // Identify the message bytes32 messageId = keccak256(messageReceipt); uint24 srcChainSelector = messageReceipt.srcChainSelector(); // EVM source sender (packed address + confirmations in srcChainData) (address srcSender, ) = messageReceipt.evmSrcChainData(); // The actual delivered bytes for your app bytes calldata payload = messageReceipt.calldataPayload(); // Your checks / routing / decoding go here: // e.g. (uint256 amount, address to) = abi.decode(payload, (uint256, address)); emit ConceroMessageAccepted(messageId, srcChainSelector, srcSender, payload); } } ``` ## Send a Cross-Chain Message :::note Before sending a message, make sure you deploy and configure your contract with ConceroClient. See [Set up ConceroClient](/integrate-concero/set-up-conceroclient). ::: ### Quick start ```solidity pragma solidity ^0.8.28; import {ConceroClient} from "@concero/contracts/ConceroClient/ConceroClient.sol"; import {IConceroRouter} from "@concero/contracts/interfaces/IConceroRouter.sol"; import {MessageCodec} from "@concero/contracts/common/libraries/MessageCodec.sol"; contract YourDapp is ConceroClient { constructor(address conceroRouter) ConceroClient(conceroRouter) {} function sendMessage( uint24 dstChainSelector, address receiverOnDst, uint32 gasLimitOnDst, address relayerLib, bytes calldata relayerConfig, // can be empty address[] calldata validatorLibs, bytes[] calldata validatorConfigs, // can be empty string calldata text ) external payable returns (bytes32 messageId) { IConceroRouter router = IConceroRouter(i_conceroRouter); // 1) Build destination chain data for EVM: receiver (20 bytes) + gasLimit (uint32) bytes memory dstChainData = MessageCodec.encodeEvmDstChainData(receiverOnDst, gasLimitOnDst); // 2) Build MessageRequest (fields aligned with your MessageCodec) IConceroRouter.MessageRequest memory req = IConceroRouter.MessageRequest({ dstChainSelector: dstChainSelector, srcBlockConfirmations: 0, // set if you use it feeToken: address(0), // native fees relayerLib: relayerLib, // per-message relayer selection validatorLibs: validatorLibs, validatorConfigs: validatorConfigs, relayerConfig: relayerConfig, dstChainData: dstChainData, payload: bytes(text) }); // 3) Quote total fee (relayer + validators), then send uint256 fee = router.getMessageFee(req); messageId = router.conceroSend{value: fee}(req); } /// @dev Required by ConceroClient. Implement destination-side message handling here. function _conceroReceive(bytes calldata) internal override {} } ``` *** ### `MessageRequest` Your request is the single source of truth for pricing, receipt packing, relayer selection, and validator setup. At minimum (based on current packing logic) the router expects fields equivalent to: ```solidity struct MessageRequest { /// @notice Which chain the message should be delivered to. /// @dev Concero uses chain selectors (not chain IDs) to route delivery. uint24 dstChainSelector; /// @notice How many source-chain block confirmations you want to wait for before the message /// is considered safe enough to deliver (reorg protection). /// @dev Set based on your security needs: higher confirmations = safer, but slower delivery. uint64 srcBlockConfirmations; /// @notice Which token you pay fees in. /// @dev Use address(0) for native; ERC20 support depends on selected relayer/validator libs. address feeToken; /// @notice The relayer module you want to deliver this message. /// @dev This is a per-message choice. If the user selects a relayer, only that relayer /// (per its own rules) is expected/allowed to submit the delivery. address relayerLib; /// @notice Which validator modules you want to use to attest/verify this message. /// @dev You choose the security model per message by choosing the validator libs. address[] validatorLibs; /// @notice Configuration for each validator module. /// @dev One config per validator lib (must match validatorLibs length). /// Typical examples: validator gas limits, thresholds, or other validator-specific params. bytes[] validatorConfigs; /// @notice Relayer-specific configuration for this message. /// @dev Optional opaque bytes interpreted only by the chosen relayer implementation. /// Examples: service tier, delivery options, custom routing hints (depends on relayer). bytes relayerConfig; /// @notice Destination-specific execution parameters. /// @dev For EVM destinations this defines: /// - who should be called on the destination (receiver) /// - how much gas to give that call (gasLimit) /// This is what makes the message actually executable on the target chain. bytes dstChainData; /// @notice The message data that will be delivered to the destination chain. /// @dev This is arbitrary bytes. Concero does not impose a format here: /// - it can be raw bytes (e.g. "hello") /// - it can be an ABI-encoded struct /// - it can be a custom serialization your app understands /// The destination-side receiver decides how to interpret it. bytes payload; } ``` ### Quote the fee Call `getMessageFee(req)` before sending, then pass the returned value as `msg.value` when paying in native. ```solidity function getMessageFee( MessageRequest calldata messageRequest ) external view returns (uint256 totalFee); ``` What’s inside: * **relayer fee** (computed by the chosen `relayerLib`) * **+ validator fees** (computed by validator libs) *** ### Send the message ```solidity function conceroSend( MessageRequest calldata messageRequest ) external payable returns (bytes32 messageId); ``` The router builds a packed receipt via `MessageCodec.toMessageReceiptBytes(...)` and returns `messageId = keccak256(messageReceipt)`. *** ### Events to index #### `ConceroMessageSent` Emitted on the source chain; relayers watch this and pick messages where `relayerLib == theirRelayerLib`. ```solidity event ConceroMessageSent( bytes32 indexed messageId, bytes messageReceipt, address[] validatorLibs, address relayerLib ); ``` ### EVM destination chain data Concero’s canonical EVM dstChainData format is: * `[0:20] receiver (address)` * `[20:24] dstGasLimit (uint32)` Use: ```solidity bytes memory dstChainData = MessageCodec.encodeEvmDstChainData(receiver, gasLimit); ``` And to decode (off-chain or in contracts that need it): ```solidity (address r, uint32 gl) = MessageCodec.decodeEvmDstChainData(dstChainData); ``` import { Mermaid } from '../../components/Mermaid' ## Set up ConceroClient ConceroClient allows your dApp contracts to send and receive messages from Concero Routers. The permissionless nature of Concero means *anyone* can send messages to your contracts. And if your contract is not configured to allowlist certain trusted relayers or verifiers, this will most certainly lead to an attack. Therefore, it's crucial to set up and configure your client to work correctly and securely. Luckily, this is easy to do. ### 1. Install Contracts First, add the Concero contracts to your project: ```bash npm install @concero/contracts ``` ### 2. Inherit from ConceroClient To make things easier, we recommend that your dApp contract inherits from `ConceroClient`. There's always an option to go lower level and inherit straight from `ConceroClientBase` – this will allow to build custom message verification logic. :::note View the full source code for `ConceroClient.sol` on [GitHub](https://github.com/concero/messaging-contracts-v2/blob/master/contracts/ConceroClient/ConceroClient.sol). ::: ```solidity pragma solidity ^0.8.28; // @concero/contracts/ConceroClient/ConceroClient.sol abstract contract ConceroClient is ConceroClientBase { constructor(address conceroRouter) ConceroClientBase(conceroRouter) {} } import {ConceroClient} from "@concero/contracts/ConceroClient/ConceroClient.sol"; import {MessageCodec} from "@concero/contracts/common/libraries/MessageCodec.sol"; contract YourDapp is ConceroClient { using MessageCodec for bytes; constructor(address conceroRouter) ConceroClient(conceroRouter) {} /// @dev This internal hook is where your business logic goes. function _conceroReceive(bytes calldata messageReceipt) internal override { // Decode the payload bytes calldata payload = messageReceipt.calldataPayload(); // Use the decoded message payload for your business logic // (e.g., abi.decode(payload, (uint256, address))) } } ``` ### 3. Set up your Concero Client After developing your contract, follow these steps to deploy and configure it. :::info Find the list of Concero Router, Verifier and Relayer addresses on the [Supported Networks](/integrate-concero/supported-networks) page. ::: :::steps #### Deploy your contract Deploy your contract to the destination chain. During deployment, ensure you pass the correct `conceroRouter` address for that specific chain to the constructor. #### Allow Relayer Libraries `ConceroClientBase` requires you to allowlist the relayer libraries used to submit messages. Use **`_setIsRelayerLibAllowed(address relayerLib, bool isAllowed)`** to toggle whether a specific relayer library is trusted. #### Allow Validator Libraries `ConceroClient` requires you to allowlist validator libraries that verify the message authenticity. Use **`_setIsValidatorAllowed(address validatorLib, bool isAllowed)`** to toggle whether a specific validator library is trusted. #### Set Required Validator Count You must specify how many validator signatures are required for a message to be considered valid by your contract. Use **`_setRequiredValidatorsCount(uint256 count)`** to set the exact number of validator approvals needed. ::: ### Message Lifecycle The following diagram illustrates how a message flows from the `ConceroRouter` to your application logic, including the internal security checks performed by `ConceroClient`. >Client: conceroReceive(receipt, checks, libs, relayer) activate Client Note over Client: [1] SECURITY CHECKS Client-->>Client: Authenticate msg.sender == ConceroRouter Client-->>Client: Ensure relayerLib is in allowlist Note over Client: [2] VERIFICATION Client->>Client: _validateMessageSubmission(checks, libs) Note over Client: Ensure all required verifier
signatures are valid and are coming from allowlisted verifiers Note over Client: [3] APPLICATION LOGIC Client->>Client: _conceroReceive(receipt) Note over Client: Decode payload and execute your
business logic deactivate Client `} /> import { SupportedNetworks } from '../../components/SupportedNetworks.tsx'; ## Tracking a message Track messages sent through Concero’s messaging protocol and obtain detailed status, origin, destination, and transaction information. ### Endpoint & Method * **Method:** `GET` * **URL:** `https://api.v2.concero.io/api/v1/scan/tx` ### Query Parameters | Parameter | Type | Description | Required/Optional | | ----------- | ------ | ----------------------------------------------- | ----------------- | | `messageId` | string | Unique identifier of the message | Optional | | `srcHash` | string | Source chain transaction hash | Optional | | `dstHash` | string | Destination chain transaction hash | Optional | | `sender` | string | Address of the message sender | Optional | | `receiver` | string | Address of the message recipient | Optional | | `take` | number | Number of messages to return (pagination limit) | Optional | | `skip` | number | Number of messages to skip (pagination offset) | Optional | > **Note:** One of `messageId`, `srcHash`, `dstHash`, `sender`, or receiver must be provided. Use `take` and `skip` for pagination control. ### Response Structure The API response includes: * **`code`** — API response status (`ok` or error codes) * **`payload.transactions`** — Array of matched message transactions * **`payload.pagination`** — Pagination information (`take` and `skip`) ### Example #### Request Below is an example demonstrating how to make a request to the Concero API to track a specific message by its `messageId`. The request uses the GET method with the `messageId` and pagination options as query parameters. ```shell curl -X 'GET' \ 'https://api.v2.concero.io/api/v1/scan/tx?&messageId=0xfff31ff0333baba7b54da7710edfc2fb7b645e95e57ebb44cfe06a505c0410f6&take=1&skip=0' \ -H 'accept: application/json' ``` #### Response Following the request example is a sample JSON response showing the structure of the data returned by the API. This response includes transaction details such as the message status, token transfers, source and destination chain information, and pagination metadata. ```json { "code": "ok", "payload": { "transactions": [ { "type": "lbf", "id": "0xfff31ff0333baba7b54da7710edfc2fb7b645e95e57ebb44cfe06a505c0410f6", "status": "success", "isFinalityRequired": false, "dstChainGasLimit": "0", "messagePayload": "0x0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000239d5b78680e9ad600ab41e56508670ba9e78f51000000000000000000000000239d5b78680e9ad600ab41e56508670ba9e78f5100000000000000000000000000000000000000000000000000000000000f187b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000", "from": { "chain": { "id": 421614, "selector": 421614, "name": "Arbitrum Sepolia" }, "token": { "name": "USD Coin", "symbol": "USDC.e", "address": "0xefc3ac3bcb37f0f26efde1e1b06609bdff690604", "decimals": 6, "priceUsd": 1, "amount": 0.99 }, "address": "0x239d5b78680e9ad600ab41e56508670ba9e78f51", "hash": "0xeda4c75e41b6f1bea80a9fb116e67f6e99518b4eb7fccf1587348eac00a49791", "timestamp": 1758708525 }, "to": { "chain": { "id": 43113, "selector": 43113, "name": "Avalanche Fuji" }, "token": { "name": "USD Coin", "symbol": "USDC.e", "address": "0x855f39baacaf30d7de448542316a889ee4db4ddb", "decimals": 6, "priceUsd": 1, "amount": 0.989307 }, "address": "0x239d5b78680e9ad600ab41e56508670ba9e78f51", "hash": "0x4c321b5b88eed8d38baeb1c81527758b2bdfb562e6ea94cb0ca6251f657442f4", "timestamp": 1758708536 } } ], "pagination": { "skip": 0, "take": 1 } } } ```