Documentation Index
Fetch the complete documentation index at: https://eco.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
ERC-7683 is the standard for cross-chain order protocols. Eco Routes implements this standard interface through two core contracts that handle the intent lifecycle across chains.
Architecture
Origin Chain: OriginSettler handles intent creation, signature verification, and fund escrow
Destination Chain: DestinationSettler manages intent fulfillment and proof generation
OriginSettler
Entry point for creating cross-chain intents on source chains. Implements EIP-712 signature verification with domain name “EcoPortal” and version “1”.
open()
Creates an intent directly on-chain with atomic funding.
function open(OnchainCrossChainOrder calldata order) external payable
Process:
- Validates
orderDataType matches ORDER_DATA_TYPEHASH
- Decodes
OrderData from the order
- Calls
_publishAndFund() to create intent and transfer funds
- Emits
Open event with resolved order details
openFor()
Creates a gasless intent on behalf of a user using EIP-712 signatures.
function openFor(
GaslessCrossChainOrder calldata order,
bytes calldata signature,
bytes calldata /* originFillerData */
) external payable
Security Validations:
block.timestamp <= order.openDeadline
order.originSettler == address(this)
order.originChainId == block.chainid
orderDataType matches ORDER_DATA_TYPEHASH
- Signature verification via
_validateOrderSig()
Replay Protection: Built into _publishAndFund() through vault state checking (Initial, Funded, Withdrawn, Refunded).
Resolution Functions
Convert Eco-specific order data into ERC-7683 compliant format:
function resolve(OnchainCrossChainOrder calldata order)
public view returns (ResolvedCrossChainOrder memory)
function resolveFor(GaslessCrossChainOrder calldata order, bytes calldata)
public view returns (ResolvedCrossChainOrder memory)
Resolution Process:
- Converts
Reward structure into Output[] array (rewards + native ETH if present)
- Calculates
routeHash, rewardHash, and intentHash
- Creates
FillInstruction with encoded (route, rewardHash) as originData
Key Mappings:
user: orderData.reward.creator
originChainId: block.chainid
fillDeadline: orderData.routeDeadline
orderId: intentHash
minReceived: Reward outputs with origin chain IDs
fillInstructions[0].destinationSettler: orderData.routePortal
EIP-712 Signature
GaslessCrossChainOrder TypeHash:
keccak256(
"GaslessCrossChainOrder(address originSettler,address user,uint256 nonce,uint256 originChainId,uint32 openDeadline,uint32 fillDeadline,bytes32 orderDataType,bytes32 orderDataHash)"
)
Verification recovers signer using ECDSA and compares with order.user.
Abstract Method
function _publishAndFund(
uint64 destination,
bytes memory route,
Reward memory reward,
bool allowPartial,
address funder
) internal virtual returns (bytes32 intentHash, address vault);
Implementations handle vault creation, fund transfers, state checking, and excess ETH returns.
DestinationSettler
Handles intent fulfillment on destination chains.
fill()
Executes a cross-chain order on the destination.
function fill(
bytes32 orderId,
bytes calldata originData,
bytes calldata fillerData
) external payable
Parameters:
orderId: Intent hash from origin chain
originData: Encoded (bytes route, bytes32 rewardHash)
fillerData: Encoded (address prover, uint64 source, bytes32 claimant, bytes proverData)
Execution:
- Decodes
originData to extract route and rewardHash
- Emits
OrderFilled(orderId, msg.sender)
- Decodes
fillerData for prover details
- Calls
fulfillAndProve() with decoded parameters
Abstract Method
function fulfillAndProve(
bytes32 intentHash,
Route memory route,
bytes32 rewardHash,
bytes32 claimant,
address prover,
uint64 source,
bytes memory data
) public payable virtual returns (bytes[] memory);
Implementations execute route instructions and initiate proof generation atomically.
Data Types
OnchainCrossChainOrder
struct OnchainCrossChainOrder {
uint32 fillDeadline;
bytes32 orderDataType;
bytes orderData; // ABI-encoded OrderData
}
GaslessCrossChainOrder
struct GaslessCrossChainOrder {
address originSettler;
address user;
uint256 nonce;
uint256 originChainId;
uint32 openDeadline;
uint32 fillDeadline;
bytes32 orderDataType;
bytes orderData; // ABI-encoded OrderData
}
OrderData
struct OrderData {
uint64 destination;
bytes route;
Reward reward;
uint256 maxSpent;
address routePortal;
uint256 routeDeadline;
}
ResolvedCrossChainOrder
struct ResolvedCrossChainOrder {
address user;
uint256 originChainId;
uint32 openDeadline;
uint32 fillDeadline;
bytes32 orderId;
uint256 maxSpent;
Output[] minReceived;
FillInstruction[] fillInstructions;
}
Output
struct Output {
bytes32 token; // Address as bytes32, zero for native
uint256 amount;
bytes32 recipient; // Zero address in Eco's model
uint256 chainId;
}
FillInstruction
struct FillInstruction {
uint64 destinationChainId;
address destinationSettler;
bytes originData; // Encoded (route, rewardHash)
}
Integration Examples
Creating Direct Intent
OnchainCrossChainOrder memory order = OnchainCrossChainOrder({
fillDeadline: uint32(block.timestamp + 1 hours),
orderDataType: ORDER_DATA_TYPEHASH,
orderData: abi.encode(OrderData({
destination: 42161,
route: encodedRoute,
reward: rewardStruct,
maxSpent: 1000000,
routePortal: portalAddress,
routeDeadline: block.timestamp + 1 hours
}))
});
originSettler.open{value: fundingAmount}(order);
Creating Gasless Intent
// Off-chain: User signs EIP-712 message
bytes32 structHash = keccak256(abi.encode(
GASLESS_CROSSCHAIN_ORDER_TYPEHASH,
order.originSettler,
order.user,
order.nonce,
order.originChainId,
order.openDeadline,
order.fillDeadline,
order.orderDataType,
keccak256(order.orderData)
));
bytes32 digest = keccak256(abi.encodePacked(
"\x19\x01",
domainSeparator,
structHash
));
// On-chain: Solver submits
originSettler.openFor(order, signature, "");
Fulfilling Intent
bytes memory originData = abi.encode(route, rewardHash);
bytes memory fillerData = abi.encode(
proverAddress,
sourceChainId,
claimantBytes32,
proverSpecificData
);
destinationSettler.fill{value: executionValue}(
orderId,
originData,
fillerData
);
Error Handling
TypeSignatureMismatch(): OrderDataType doesn’t match ORDER_DATA_TYPEHASH
OpenDeadlinePassed(): Current time exceeds opening deadline
InvalidOriginSettler(): Order specifies wrong settler address
InvalidOriginChainId(): Order targets different chain
InvalidSignature(): Signature verification failed
Eco-Specific Implementation Notes
- Recipient Field:
Output.recipient always zero address; actual claimant specified in fillerData at fulfillment
- ChainId Semantics:
minReceived outputs use origin chainId (rewards claimed on source chain)
- FillInstruction.originData: Contains
(route, rewardHash) tuple instead of complete intent
- Single Fill: Each order has exactly one fill instruction