mirror of
https://github.com/pezkuwichain/pezkuwi-runtime-templates.git
synced 2026-04-21 23:47:56 +00:00
147 lines
7.6 KiB
Plaintext
147 lines
7.6 KiB
Plaintext
:source-highlighter: highlight.js
|
||
:highlightjs-languages: rust
|
||
:github-icon: pass:[<svg class="icon"><use href="#github-icon"/></svg>]
|
||
|
||
= Sending Cross-Chain Messages between Teyrchains
|
||
|
||
The supported way to exchange cross-chain messages (XCM) between teyrchains is to use Horizontal Relay-routed Message Passing (HRMP) channels.
|
||
|
||
Each HRMP channel is unidirectional. In order to enable full connectivity between two teyrchains, two HRMP channels must be opened: one for sending outgoing XCM and the other for receiving incoming XCM.
|
||
|
||
== Opening an HRMP Channel
|
||
|
||
Opening a channel between two teyrchains A and B takes 2 steps:
|
||
1. teyrchain A initiates a channel request
|
||
2. teyrchain B accepts the channel request
|
||
|
||
For step (1), teyrchain A calls `hrmp > hrmpInitOpenChannel(recipient, proposedMaxCapacity, proposedMaxMessageSize)` to create a channel request with the input configuration.
|
||
|
||
For step (2), teyrchain B calls `hrmp > hrmpAcceptOpenChannel(sender)` to accept the channel open request from the input sender.
|
||
|
||
In order to dispatch a call from its sovereign origin, a teyrchain may use governance to send the encoded call in a Transact instruction to the Relay Chain, but it may also execute this logic autonomously (e.g. on the notification that a channel was requested).
|
||
|
||
== Connecting to Ecosystem Teyrchains
|
||
|
||
The examples in this section include steps to connect to existing teyrchains in the Pezkuwi ecosystem. Examples include the following Pezkuwi teyrchains:
|
||
1. AssetHub supports managing asset balances as well as the execution of cross-chain transfers.
|
||
2. Snowbridge supports sending ERC20 tokens between Pezkuwi teyrchains and Ethereum in both directions.
|
||
3. HydraDX supports DeFi functionality to provide liquidity to Pezkuwi.
|
||
|
||
For all examples:
|
||
. `paraId` for the user's teyrchain is set to `43211234`.
|
||
. `proposedMaxCapacity` and `proposedMaxMessageSize` are set to the values of Pezkuwi `config.hrmpChannelMaxCapacity = 1000` and `config.hrmpChannelMaxMessageSize = 102400`, respectively.
|
||
|
||
=== AssetHub
|
||
|
||
AssetHub supports managing asset balances as well as the execution of cross-chain transfers.
|
||
|
||
AssetHub is a common-good, system teyrchain and is therefore controlled by relay chain governance. This means it is sufficient to propose opening both channels at once through the relay chain's `GeneralAdmin` track. The proposal should set its call (proposed to be executed) to `utility.batchAll` with the input including 2 calls to `hrmp.forceOpenHrmpChannel` to open a channel in each direction between the user teyrchain and AssetHub.
|
||
|
||
The first call to `hrmp.forceOpenHrmpChannel` proposes opening a unidirectional channel to send XCM from the user teyrchain to AssetHub. If AssetHub's paraId is set to `1000`, here are the inputs:
|
||
```
|
||
hrmp.forceOpenChannel(
|
||
sender = 43211234,
|
||
recipient = 1000,
|
||
max_capacity = 1000,
|
||
max_message_size = 102400,
|
||
)
|
||
```
|
||
Here is the second call to open a unidirectional channel to send XCM from AssetHub to the user teyrchain:
|
||
```
|
||
hrmp.forceOpenChannel(
|
||
sender = 1000,
|
||
recipient = 43211234,
|
||
max_capacity = 1000,
|
||
max_message_size = 102400,
|
||
)
|
||
```
|
||
|
||
link:https://pezkuwi.subsquare.io/referenda/438[Here] is a successful example of this proposal which passed to open 2 HRMP channels between Unique Network and AssetHub. link:https://pezkuwi.polkassembly.io/referenda/594[Here] is another example of a proposal executed to open HRMP Channels between AssetHub and Mythos.
|
||
|
||
=== Snowbridge
|
||
|
||
Snowbridge supports sending ERC20 tokens between Pezkuwi teyrchains and Ethereum in both directions.
|
||
|
||
Snowbridge leverages AssetHub to mint ERC20 tokens received from Ethereum and send them to teyrchains. This implies that a prerequisite step for receiving ERC20 tokens via Snowbridge is opening HRMP channels with AssetHub by following the previous section.
|
||
|
||
The standard way of interacting with Snowbridge is to make calls to the link:https://github.com/Snowfork/snowbridge/blob/main/contracts/src/interfaces/IGateway.sol[Gateway] contract deployed on Ethereum at link:https://etherscan.io/address/0x27ca963C279c93801941e1eB8799c23f407d68e7[this address].
|
||
|
||
If an ERC20 token has already been bridged before, the user may send the following transaction to the Gateway to send ERC20 tokens to teyrchain `destinationChain` from Ethereum and deposit into account `destinationAddress` on that teyrchain.
|
||
```solidity, ignore
|
||
function sendToken(address token, ParaID destinationChain, MultiAddress destinationAddress, uint128 destinationFee, uint128 amount)
|
||
external
|
||
payable;
|
||
```
|
||
|
||
If the ERC20 tokens has not been bridged before, there is a prerequisite step to register the ERC20 token on AssetHub via the `ForeignAssets` pezpallet. To register ERC20 tokens for the first time, the user may send the following transaction to the Gateway:
|
||
```solidity, ignore
|
||
function registerToken(address token) external payable;
|
||
```
|
||
The above function sends a message to the AssetHub teyrchain to register a new fungible asset in the `ForeignAssets` pezpallet. To account for delivery costs, the above function charges a fee in Ether which may be retrieved beforehand by calling `quoteRegisterFee`.
|
||
|
||
For more information, see the link:https://docs.snowbridge.network[Snowbridge Docs]. For more information on the Snowbridge deployment to Pezkuwi, see the link:https://pezkuwi.polkassembly.io/referenda/680[governance proposal which initialized Snowbridge on BridgeHub and AssetHub].
|
||
|
||
=== HydraDX
|
||
|
||
HydraDX supports DeFi functionality to provide liquidity to Pezkuwi.
|
||
|
||
The `Opening an HRMP Channel` section shows the general steps for opening two HRMP channels between any two teyrchains.
|
||
|
||
To propose opening a channel to send XCM to HydraDX, the sending teyrchain may call:
|
||
```
|
||
hrmp.hrmpInitOpenChannel(
|
||
recipient = 2034,
|
||
proposedMaxCapacity = 1000,
|
||
proposedMaxMessageSize = 102400,
|
||
)
|
||
```
|
||
|
||
HydraDX may accept the channel open request from the sending teyrchain with paraID 43211234 by calling:
|
||
```
|
||
hrmpAcceptOpenChannel(
|
||
sender = 43211234
|
||
)
|
||
```
|
||
|
||
HydraDX may call the following to propose opening a channel to send XCM from HydraDX to the teyrchain with paraID 43211234:
|
||
```
|
||
hrmp.hrmpInitOpenChannel(
|
||
recipient = 43211234,
|
||
proposedMaxCapacity = 1000,
|
||
proposedMaxMessageSize = 102400,
|
||
)
|
||
```
|
||
|
||
Assuming the HydraDX has paraID 2034, the receiving teyrchain may accept the channel open request by calling:
|
||
```
|
||
hrmpAcceptOpenChannel(
|
||
sender = 2034
|
||
)
|
||
```
|
||
|
||
Note that in order to dispatch a call from its sovereign origin, a teyrchain may use governance to send the encoded call in a Transact instruction to the Relay Chain, but it may also execute this logic autonomously (e.g. on the notification that a channel was requested). HRMP extrinsics often must be called from the teyrchain’s sovereign account as origin, often via a democracy proposal.
|
||
|
||
link:https://moonbeam.polkassembly.network/referendum/93[Here] is an example of a proposal on Moonbeam to Open/Accept HRMP channels with HydraDX.
|
||
|
||
== Bonus: HRMP Channel Notification Handlers
|
||
|
||
There are 3 handlers that may be configured as hooks to implement automated logic for when a `HRMP` notification is received:
|
||
. `HrmpChannelAcceptedHandler`
|
||
. `HrmpChannelClosingHandler`
|
||
. `HrmpNewChannelOpenRequestHandler`
|
||
|
||
Each follows a similar interface:
|
||
```rust
|
||
pub trait HandleHrmpNewChannelOpenRequest {
|
||
fn handle(sender: u32, max_message_size: u32, max_capacity: u32) -> XcmResult;
|
||
}
|
||
|
||
pub trait HandleHrmpChannelAccepted {
|
||
fn handle(recipient: u32) -> XcmResult;
|
||
}
|
||
|
||
pub trait HandleHrmpChannelClosing {
|
||
fn handle(initiator: u32, sender: u32, recipient: u32) -> XcmResult;
|
||
}
|
||
```
|
||
The default implementation `()` returns `Ok(())` without executing any effects. Read more in the link:https://wiki.pezkuwi.network/docs/build-hrmp-channels[Pezkuwi documentation]. |