From 551af4c12ec434b64afc71bf65fb9e052bd0fef0 Mon Sep 17 00:00:00 2001 From: Nam Chu Hoai Date: Wed, 23 Nov 2022 20:26:29 -0500 Subject: [PATCH] Support ICA/IQS functions without Call struct (#1307) * Support ICA/IQS functions without Call struct * Fix --- .../middleware/InterchainAccountRouter.sol | 10 ++++++++++ .../middleware/InterchainQueryRouter.sol | 20 +++++++++++++++++++ .../mock/MockInterchainAccountRouter.sol | 18 +++++++++++++++-- .../interfaces/IInterchainAccountRouter.sol | 6 ++++++ .../interfaces/IInterchainQueryRouter.sol | 7 +++++++ .../src/middleware/accounts.hardhat-test.ts | 4 +++- 6 files changed, 62 insertions(+), 3 deletions(-) diff --git a/solidity/contracts/middleware/InterchainAccountRouter.sol b/solidity/contracts/middleware/InterchainAccountRouter.sol index 448c7c5a3..1e4798d75 100644 --- a/solidity/contracts/middleware/InterchainAccountRouter.sol +++ b/solidity/contracts/middleware/InterchainAccountRouter.sol @@ -44,6 +44,16 @@ contract InterchainAccountRouter is Router, IInterchainAccountRouter { return _dispatch(_destinationDomain, abi.encode(msg.sender, calls)); } + function dispatch( + uint32 _destinationDomain, + address target, + bytes calldata data + ) external returns (uint256) { + Call[] memory calls = new Call[](1); + calls[0] = Call({to: target, data: data}); + return _dispatch(_destinationDomain, abi.encode(msg.sender, calls)); + } + function getInterchainAccount(uint32 _origin, address _sender) public view diff --git a/solidity/contracts/middleware/InterchainQueryRouter.sol b/solidity/contracts/middleware/InterchainQueryRouter.sol index e732719d4..49dabe5c1 100644 --- a/solidity/contracts/middleware/InterchainQueryRouter.sol +++ b/solidity/contracts/middleware/InterchainQueryRouter.sol @@ -43,6 +43,26 @@ contract InterchainQueryRouter is _setInterchainGasPaymaster(_interchainGasPaymaster); } + /** + * @param _destinationDomain Domain of destination chain + * @param target The address of the contract to query on destination chain. + * @param queryData The calldata of the view call to make on the destination chain. + * @param callback Callback function selector on `msg.sender` and optionally abi-encoded prefix arguments. + */ + function query( + uint32 _destinationDomain, + address target, + bytes calldata queryData, + bytes calldata callback + ) external returns (uint256 leafIndex) { + // TODO: fix this ugly arrayification + Call[] memory calls = new Call[](1); + calls[0] = Call({to: target, data: queryData}); + bytes[] memory callbacks = new bytes[](1); + callbacks[0] = callback; + leafIndex = query(_destinationDomain, calls, callbacks); + } + /** * @param _destinationDomain Domain of destination chain * @param call Call (to and data packed struct) to be made on destination chain. diff --git a/solidity/contracts/mock/MockInterchainAccountRouter.sol b/solidity/contracts/mock/MockInterchainAccountRouter.sol index 974614a96..dfd475063 100644 --- a/solidity/contracts/mock/MockInterchainAccountRouter.sol +++ b/solidity/contracts/mock/MockInterchainAccountRouter.sol @@ -38,10 +38,24 @@ contract MockInterchainAccountRouter is IInterchainAccountRouter { originDomain = _originDomain; } - function dispatch(uint32, Call[] calldata calls) - external + function dispatch(uint32 _destinationDomain, Call[] calldata calls) + public returns (uint256) { + return _dispatch(_destinationDomain, calls); + } + + function dispatch( + uint32 _destinationDomain, + address target, + bytes calldata data + ) external returns (uint256) { + Call[] memory calls = new Call[](1); + calls[0] = Call({to: target, data: data}); + return _dispatch(_destinationDomain, calls); + } + + function _dispatch(uint32, Call[] memory calls) internal returns (uint256) { pendingCalls[totalCalls] = PendingCall( originDomain, msg.sender, diff --git a/solidity/interfaces/IInterchainAccountRouter.sol b/solidity/interfaces/IInterchainAccountRouter.sol index c162c9be7..da24042bb 100644 --- a/solidity/interfaces/IInterchainAccountRouter.sol +++ b/solidity/interfaces/IInterchainAccountRouter.sol @@ -8,6 +8,12 @@ interface IInterchainAccountRouter { external returns (uint256); + function dispatch( + uint32 _destinationDomain, + address target, + bytes calldata data + ) external returns (uint256); + function getInterchainAccount(uint32 _originDomain, address _sender) external view diff --git a/solidity/interfaces/IInterchainQueryRouter.sol b/solidity/interfaces/IInterchainQueryRouter.sol index 490e23283..8954c815d 100644 --- a/solidity/interfaces/IInterchainQueryRouter.sol +++ b/solidity/interfaces/IInterchainQueryRouter.sol @@ -4,6 +4,13 @@ pragma solidity >=0.6.11; import {Call} from "../contracts/Call.sol"; interface IInterchainQueryRouter { + function query( + uint32 _destinationDomain, + address target, + bytes calldata queryData, + bytes calldata callback + ) external returns (uint256); + function query( uint32 _destinationDomain, Call calldata call, diff --git a/typescript/sdk/src/middleware/accounts.hardhat-test.ts b/typescript/sdk/src/middleware/accounts.hardhat-test.ts index 2726902d4..e3b6a9966 100644 --- a/typescript/sdk/src/middleware/accounts.hardhat-test.ts +++ b/typescript/sdk/src/middleware/accounts.hardhat-test.ts @@ -67,7 +67,9 @@ describe('InterchainAccountRouter', async () => { localDomain, signer.address, ); - await local.dispatch(remoteDomain, [{ to: recipient.address, data }]); + await local['dispatch(uint32,(address,bytes)[])'](remoteDomain, [ + { to: recipient.address, data }, + ]); await coreApp.processMessages(); expect(await recipient.lastCallMessage()).to.eql(fooMessage); expect(await recipient.lastCaller()).to.eql(icaAddress);