Refer to Stateless App Cookbook#Kernel. The intents on EVM chains are EIP191 signed signatures. To construct the message and validate the signed EVM intent, there are two steps:
  1. Get data hash
function getDataHashForUser(
    address user,
    address appAddress,
    bytes calldata intentCalldata
) public view override returns (bytes memory encodedData) {
    encodedData = abi.encode(
        user,
        _nonce[user],
        appAddress,
        keccak256(bytes(intentCalldata))
    );
}
Perform getDataHashByUser() call on any Stateless app to retrieve data hash.
  1. Sign data hash For signing, we will be abiding by the [EIP-191] standard(https://eips.ethereum.org/EIPS/eip-191). This is supported by popular libraries such as ethers and wallets.
Recall the Task structure on Message box,
IMessageBox.sol
struct Task {
    bytes32 appAddress;
    bytes taskCalldata;
    bytes32 user;
    uint256 chainId;
    uint256 vmType; // 1 = EVM | 2 = TON | 3 = SOLANA | etc..
}
After the tasks are created, the serialized EVM message is verified by Skate AVS and then scheduled for execution on EVM periphery contracts.