You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
4.5 KiB
108 lines
4.5 KiB
4 years ago
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||
|
pragma solidity >=0.6.11;
|
||
|
|
||
|
// ============ External Imports ============
|
||
|
import {TypedMemView} from "@summa-tx/memview-sol/contracts/TypedMemView.sol";
|
||
3 years ago
|
import {Router} from "@abacus-network/core/contracts/router/Router.sol";
|
||
|
import {XAppConnectionClient} from "@abacus-network/core/contracts/router/XAppConnectionClient.sol";
|
||
4 years ago
|
// ============ Internal Imports ============
|
||
|
import {Message} from "./MessageTemplate.sol";
|
||
|
|
||
|
/*
|
||
|
============ Overview: Building a xApp ============
|
||
|
To implement a xApp, define the actions you would like to execute across chains.
|
||
|
For each type of action,
|
||
|
- in the xApp Router
|
||
|
- implement a function like doTypeA to initiate the action from one domain to another (add your own parameters and logic)
|
||
|
- implement a corresponding _handle function to receive, parse, and execute this type of message on the remote domain
|
||
|
- add logic to the handle function to route incoming messages to the appropriate _handle function
|
||
|
- in the Message library,
|
||
|
- implement functions to *format* the message to send to the other chain (encodes all necessary information for the action)
|
||
|
- implement functions to *parse* the message once it is received on the other chain (decode all necessary information for the action)
|
||
|
*/
|
||
3 years ago
|
contract RouterTemplate is Router {
|
||
4 years ago
|
// ============ Libraries ============
|
||
|
|
||
|
using TypedMemView for bytes;
|
||
|
using TypedMemView for bytes29;
|
||
|
using Message for bytes29;
|
||
|
|
||
|
// ============ Events ============
|
||
|
|
||
|
event TypeAReceived(uint256 number);
|
||
|
|
||
|
// ============ Constructor ============
|
||
|
|
||
3 years ago
|
constructor(address _xAppConnectionManager) {
|
||
3 years ago
|
__XAppConnectionClient_initialize(_xAppConnectionManager);
|
||
3 years ago
|
}
|
||
4 years ago
|
|
||
|
// ============ Handle message functions ============
|
||
|
|
||
|
/**
|
||
3 years ago
|
* @notice Receive messages sent via Abacus from other remote xApp Routers;
|
||
4 years ago
|
* parse the contents of the message and enact the message's effects on the local chain
|
||
3 years ago
|
* @dev Called by an Abacus Inbox contract while processing a message sent via Abacus
|
||
4 years ago
|
* @param _origin The domain the message is coming from
|
||
|
* @param _sender The address the message is coming from
|
||
|
* @param _message The message in the form of raw bytes
|
||
|
*/
|
||
|
function handle(
|
||
|
uint32 _origin,
|
||
|
bytes32 _sender,
|
||
|
bytes memory _message
|
||
3 years ago
|
) external override onlyInbox onlyRemoteRouter(_origin, _sender) {
|
||
4 years ago
|
bytes29 _msg = _message.ref(0);
|
||
|
// route message to appropriate _handle function
|
||
|
// based on what type of message is encoded
|
||
|
if (_msg.isTypeA()) {
|
||
3 years ago
|
_handleTypeA(_msg);
|
||
|
} else {
|
||
|
// if _message doesn't match any valid actions, revert
|
||
|
require(false, "!valid action");
|
||
4 years ago
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @notice Once the Router has parsed a message in the handle function and determined it is Type A,
|
||
|
* call this internal function to parse specific information from the message,
|
||
|
* and enact the message's action on this chain
|
||
|
* @param _message The message in the form of raw bytes
|
||
|
*/
|
||
3 years ago
|
function _handleTypeA(bytes29 _message) internal {
|
||
4 years ago
|
// parse the information from the message
|
||
|
uint256 _number = _message.number();
|
||
|
// implement the logic for executing the action
|
||
|
// (in this example case, emit an event with the number that was sent)
|
||
|
emit TypeAReceived(_number);
|
||
|
}
|
||
|
|
||
|
// ============ Dispatch message functions ============
|
||
|
|
||
|
/**
|
||
3 years ago
|
* @notice Send a message of "Type A" to a remote xApp Router via Abacus;
|
||
4 years ago
|
* this message is called to take some action in the cross-chain context
|
||
|
* Example message types:
|
||
|
* Sending tokens from this chain to the destination chain;
|
||
|
* params would be the address of the token, the amount of the token to send, and the address of the recipient
|
||
|
* @param _destinationDomain The domain to send the message to
|
||
|
* @param _number Example parameter used in message TypeA - a number to send to another chain
|
||
|
*/
|
||
|
function dispatchTypeA(uint32 _destinationDomain, uint256 _number)
|
||
|
external
|
||
|
{
|
||
|
// get the xApp Router at the destinationDomain
|
||
3 years ago
|
bytes32 _remoteRouterAddress = _mustHaveRemoteRouter(
|
||
|
_destinationDomain
|
||
|
);
|
||
4 years ago
|
// encode a message to send to the remote xApp Router
|
||
|
bytes memory _outboundMessage = Message.formatTypeA(_number);
|
||
|
// send the message to the xApp Router
|
||
3 years ago
|
_outbox().dispatch(
|
||
4 years ago
|
_destinationDomain,
|
||
|
_remoteRouterAddress,
|
||
|
_outboundMessage
|
||
|
);
|
||
|
}
|
||
|
}
|