Set up ConceroClient
ConceroClient allows your dApp contracts to send and receive messages from Concero Routers.
1. Install Concero Contracts
First, add the Concero contracts to your project:
npm i @concero/messaging-contracts-v22. Inherit Your Contract 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 to build custom message verification logic.
pragma solidity ^0.8.28;
import {ConceroClient} from "@concero/messaging-contracts-v2/contracts/ConceroClient/ConceroClient.sol";
import {MessageCodec} from "@concero/messaging-contracts-v2/contracts/common/libraries/MessageCodec.sol";
contract YourDapp is ConceroClient {
using MessageCodec for bytes;
constructor(address conceroRouter) ConceroClient(conceroRouter) {}
// Your app must override this function to handle incoming messages
function _conceroReceive(bytes calldata messageReceipt) internal override {
// Decode the message payload
bytes calldata messagePayload = messageReceipt.calldataPayload();
// Use the decoded message payload for your business logic
// (e.g., abi.decode(messagePayload, (uint256, address)))
}
}3. Set up Your Contract
Follow these steps to deploy and configure your DApp contract.
Deploy Your Contract
Use the tool of your choice to deploy your contract (e.g. Foundry or Hardhat).
During deployment, ensure you pass the correct conceroRouter address of a corresponding chain to the constructor.
Allow Relayer Libraries
ConceroClientBase requires you to allowlist the relayer libraries used to submit messages. Call _setIsRelayerLibAllowed(address relayerLib, bool isAllowed) to toggle whether a specific relayer library is trusted.
Allow Verifier Libraries
ConceroClient requires you to allowlist verifier libraries and set the number of required verifications.
- Call
_setIsValidatorAllowed(address validatorLib, bool isAllowed)to allow the specific verifier library you trust. - Also call
_setRequiredValidatorsCount(uint256 count)and setcountto1for now (recommended for simplicity while using one verifier).
Message Lifecycle
1. Message is Received by ConceroRouter
- Relayer EOA delivers the message to ConceroRouter by calling
conceroReceive - ConceroRouter verifies the Relayer's EOA in
RelayerLib - ConceroRouter asserts message verification in
VerifierLib - ConceroRouter passes the message to Client
2. Your Client Verifies Message
ConceroClient validates:
msg.senderis the allowlistedConceroRouterrelayerEOA is allowlisted- Asserts that verifiers are allowlisted and the verification matches the message, by calling
_validateMessageSubmission(checks, libs)
3. Your App Logic Executes
If all checks pass, ConceroClient calls _conceroReceive(receipt).
Decode the payload and run your dApp-specific business logic.