diff --git a/.cspell/custom-dictionary.txt b/.cspell/custom-dictionary.txt index 0eeeded..7770ba4 100644 --- a/.cspell/custom-dictionary.txt +++ b/.cspell/custom-dictionary.txt @@ -1,5 +1,6 @@ # Custom Dictionary Words Aptos +CCTP Devnet hashv idls diff --git a/README.md b/README.md index f374743..4361b54 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,23 @@ uint32 payloadLen // Length of the payload bytes payload // The full payload, the keccak of which was sent to `endpoint.sendMessage` ``` +##### NTT v1 Request + +```solidity +bytes4 prefix = "ERN1" // 4-byte prefix for this struct +uint16 srcChain +bytes32 srcManager +bytes32 messageId +``` + +##### CCTP v1 Request + +```solidity +bytes4 prefix = "ERC1" // 4-byte prefix for this struct +uint32 sourceDomain +uint64 nonce +``` + #### Relay Instructions ##### Gas Instruction diff --git a/evm/README.md b/evm/README.md index 3c78b80..c172d3f 100644 --- a/evm/README.md +++ b/evm/README.md @@ -46,6 +46,54 @@ executor.requestExecution{value: executionAmount}( +#### Example v1 NTT Request + + + +```solidity +import "example-messaging-executor/evm/src/interfaces/IExecutor.sol"; +import "example-messaging-executor/evm/src/libraries/ExecutorMessages.sol"; +... +uint64 msgId = nttm.transfer{value: msg.value - executorArgs.value}( + amount, recipientChain, recipientAddress, refundAddress, shouldQueue, encodedInstructions +); + +executor.requestExecution{value: executorArgs.value}( + recipientChain, + nttm.getPeer(recipientChain).peerAddress, + executorArgs.refundAddress, + executorArgs.signedQuote, + ExecutorMessages.makeNTTv1Request( + chainId, bytes32(uint256(uint160(address(nttm)))), bytes32(uint256(msgId)) + ), + executorArgs.instructions +); +``` + + + +#### Example v1 CCTP Request + + + +```solidity +import "example-messaging-executor/evm/src/interfaces/IExecutor.sol"; +import "example-messaging-executor/evm/src/libraries/ExecutorMessages.sol"; +... +uint64 nonce = circleTokenMessenger.depositForBurn(amount, destinationDomain, mintRecipient, burnToken); + +executor.requestExecution{value: executorArgs.value}( + 0, + bytes32(0), + executorArgs.refundAddress, + executorArgs.signedQuote, + ExecutorMessages.makeCCTPv1Request(sourceDomain, nonce), + executorArgs.instructions +); +``` + + + ### Execution Support #### v1 VAA Execution @@ -56,6 +104,22 @@ Your contract must implement the following function. function receiveMessage(bytes calldata encodedTransferMessage) public payable ``` +#### v1 NTT Execution + +The NTT Transceiver contract implements the following function. + +```solidity +function receiveMessage(bytes memory encodedMessage) external +``` + +#### v1 CCTP Execution + +The Circle Message Transmitter contract implements the following function. + +```solidity +function receiveMessage(bytes calldata message,bytes calldata attestation) external override whenNotPaused returns (bool success) +``` + ## Executor Development ### Testing diff --git a/evm/src/libraries/ExecutorMessages.sol b/evm/src/libraries/ExecutorMessages.sol index 3fa35a2..9784d2d 100644 --- a/evm/src/libraries/ExecutorMessages.sol +++ b/evm/src/libraries/ExecutorMessages.sol @@ -5,6 +5,7 @@ library ExecutorMessages { bytes4 private constant REQ_MM = "ERM1"; bytes4 private constant REQ_VAA_V1 = "ERV1"; bytes4 private constant REQ_NTT_V1 = "ERN1"; + bytes4 private constant REQ_CCTP_V1 = "ERC1"; /// @notice Payload length will not fit in a uint32. /// @dev Selector: 492f620d. @@ -54,4 +55,12 @@ library ExecutorMessages { { return abi.encodePacked(REQ_NTT_V1, srcChain, srcManager, messageId); } + + /// @notice Encodes a version 1 CCTP request payload. + /// @param sourceDomain The source chain for the CCTP transfer. + /// @param nonce The nonce of the CCTP transfer. + /// @return bytes The encoded request. + function makeCCTPv1Request(uint32 sourceDomain, uint64 nonce) internal pure returns (bytes memory) { + return abi.encodePacked(REQ_CCTP_V1, sourceDomain, nonce); + } } diff --git a/evm/test/ExecutorMessages.t.sol b/evm/test/ExecutorMessages.t.sol index 33508c3..b0d59df 100644 --- a/evm/test/ExecutorMessages.t.sol +++ b/evm/test/ExecutorMessages.t.sol @@ -38,4 +38,12 @@ contract ExecutorMessagesTest is Test { bytes memory buf = ExecutorMessages.makeNTTv1Request(srcChain, srcManager, messageId); assertEq(keccak256(expected), keccak256(buf)); } + + function test_makeCCTPv1Request() public pure { + uint32 srcDomain = 7; + uint64 nonce = 42; + bytes memory expected = abi.encodePacked("ERC1", srcDomain, nonce); + bytes memory buf = ExecutorMessages.makeCCTPv1Request(srcDomain, nonce); + assertEq(keccak256(expected), keccak256(buf)); + } }