/** * @notice Creates and funds an intent in a single transaction * @param intent The complete intent struct to be published and funded * @param allowPartial Whether to allow partial funding * @return intentHash Hash of the created and funded intent * @return vault Address of the created vault */function publishAndFund( Intent calldata intent, bool allowPartial) public payable returns (bytes32 intentHash, address vault);/** * @notice Creates an intent without funding * @param intent The complete intent struct to be published * @return intentHash Hash of the created intent * @return vault Address of the created vault */function publish( Intent calldata intent) public returns (bytes32 intentHash, address vault);/** * @notice Funds an existing intent * @param destination Destination chain ID for the intent * @param routeHash Hash of the route component * @param reward Reward structure containing distribution details * @param allowPartial Whether to allow partial funding * @return intentHash Hash of the funded intent */function fund( uint64 destination, bytes32 routeHash, Reward calldata reward, bool allowPartial) external payable returns (bytes32 intentHash);
// 1. Approve the IntentSource contract to spend your reward tokensIERC20(sourceUsdcAddress).approve(address(intentSource), 1010e6);// 2. Publish and fund the intent(bytes32 intentHash, address vault) = intentSource.publishAndFund( intent, false // Don't allow partial funding);// The intent is now live and solvers can see it
For intents with ETH or native token rewards:
// Define reward with native tokensReward memory reward = Reward({ deadline: deadline, creator: msg.sender, prover: proverAddress, nativeAmount: 0.1 ether, // 0.1 ETH reward tokens: new TokenAmount[](0)});// Publish and fund with ETH(bytes32 intentHash, address vault) = intentSource.publishAndFund{value: 0.1 ether}( intent, false);
For intents with both native and ERC20 rewards:
// Approve ERC20 tokensIERC20(tokenAddress).approve(address(intentSource), rewardAmount);// Publish and fund with both(bytes32 intentHash, address vault) = intentSource.publishAndFund{value: 0.05 ether}( intent, false);
You can also publish an intent first and fund it later:
// 1. Publish without funding(bytes32 intentHash, address vault) = intentSource.publish(intent);// Intent is now published but not funded// Solvers will see it but won't execute until funded// 2. Fund later (by anyone)IERC20(sourceUsdcAddress).approve(address(intentSource), 1010e6);bytes32 routeHash = keccak256(abi.encode(intent.route));intentSource.fund( intent.destination, routeHash, intent.reward, false // allowPartial);
Anyone can fund an intent once it’s published. The reward tokens are held in a deterministic vault contract until the intent is fulfilled.
You can check if an intent has been funded using contracts/IntentSource.sol:
IntentSource.sol
/** * @notice Checks if an intent is completely funded * @param intent Intent to validate * @return True if intent is completely funded, false otherwise */function isIntentFunded(Intent calldata intent) public view returns (bool);/** * @notice Retrieves reward status for a given intent hash * @param intentHash Hash of the intent to query * @return status Current status of the intent */function getRewardStatus(bytes32 intentHash) public view returns (Status status);
Usage:
// Check if intent is fundedbool isFunded = intentSource.isIntentFunded(intent);// Get detailed statusbytes32 intentHash = keccak256( abi.encodePacked( intent.destination, keccak256(abi.encode(intent.route)), keccak256(abi.encode(intent.reward)) ));IIntentSource.Status status = intentSource.getRewardStatus(intentHash);// Status can be: Initial, Funded, Withdrawn, or Refunded
Deadline Management: The route deadline must be before or equal to the reward deadline. Solvers need time to claim rewards after execution.
Sufficient Rewards: Ensure your rewards are attractive enough to incentivize solvers. Consider gas costs on both chains and solver profit margins.
Deterministic Vaults: Reward tokens are stored in deterministic vault contracts created via CREATE2. The vault address is the same across all chains for the same intent hash.
Partial Funding: Set allowPartial = true if you want to fund the intent gradually. This is useful for large intents or when multiple parties contribute to the reward.