Skip to content

Commit

Permalink
add generic type for XCM asset transactor with forwarder traits
Browse files Browse the repository at this point in the history
  • Loading branch information
freddyli7 committed Nov 3, 2023
1 parent 568c5ae commit 3044a0e
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 10 deletions.
42 changes: 32 additions & 10 deletions bridge/src/xcm_asset_transactor.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use xcm::latest::{Junctions, MultiAsset, MultiLocation, XcmContext};
use xcm::prelude::{GeneralKey, X3};
use xcm::v3::Junction::Parachain;
use core::marker::PhantomData;
use xcm::latest::{Junction, MultiAsset, MultiLocation, XcmContext};
use sygma_traits::{AssetTypeIdentifier, TransactorForwarder};
use xcm::prelude::*;
use xcm_executor::{traits::TransactAsset};

pub struct XCMAssetTransactor;
pub struct XCMAssetTransactor<CurrencyTransactor, FungiblesTransactor, AssetTypeChecker, Forwarder>(PhantomData<(CurrencyTransactor, FungiblesTransactor, AssetTypeChecker, Forwarder)>);

impl TransactAsset for XCMAssetTransactor{
impl<CurrencyTransactor: TransactAsset, FungiblesTransactor: TransactAsset, AssetTypeChecker: AssetTypeIdentifier, Forwarder: TransactorForwarder> TransactAsset for XCMAssetTransactor<CurrencyTransactor, FungiblesTransactor, AssetTypeChecker, Forwarder> {
// deposit_asset implements the TransactAsset deposit_asset method and contains the logic to classify
// the asset recipient location:
// 1. recipient is on the local parachain
Expand All @@ -15,23 +16,44 @@ impl TransactAsset for XCMAssetTransactor{
match (who.parents, who.interior) {
// 1. recipient is the local parachain
(0, None) => {
// TODO: check if the asset is native or foreign, and call the corresponding deposit_asset()
// check if the asset is native or foreign, and call the corresponding deposit_asset()
if AssetTypeChecker::is_native_asset(what) {
CurrencyTransactor::deposit_asset(what, who, context)?;
} else {
FungiblesTransactor::deposit_asset(what, who, context)?
}
}
// 2. recipient is remote parachain
// trying to eliminate the forward logic here by adding the XCM handler pallet as one of the generic type for XCMAssetTransactor
(1, Some(Parachain(_))) => {
// TODO: call the xcm handler pallet to construct the xcm message (evm to remote parachain route)
// xcm message must have a sender(origin), so a tmp account derived from pallet would be used
let tmp_account = MultiLocation::new(0, X1(GeneralKey {length: 8, data: [2u8; 32]})).into_account();

// check if the asset is native or foreign, and call the corresponding deposit_asset(), recipient will be the derived tmp account
// xcm message execution
if AssetTypeChecker::is_native_asset(what) {
CurrencyTransactor::deposit_asset(what, &Junction::AccountId32 { network: None, id: tmp_account }.into(), context)?;
} else {
FungiblesTransactor::deposit_asset(what, &Junction::AccountId32 { network: None, id: tmp_account }.into(), context)?
}

// trying to eliminate the forward logic here by adding the XCM handler pallet as one of the generic type for XCMAssetTransactor
// TODO: call the xcm handler pallet to construct the xcm message and execute it(to other remote parachain route)
Forwarder::xcm_transactor_forwarder()
}
// 3. recipient is on non-substrate chain(evm, cosmos, etc.), will forward to sygma bridge pallet
// TODO: the junctions below is just an temporary example, will change it to proper sygma bridge standard, see the link below:
// (https://www.notion.so/chainsafe/Sygma-as-an-Independent-pallet-c481f00ccff84ff49ce917c8b2feacda?pvs=4#6e51e6632e254b9b9a01444ef7297969)
(0, &X3(Parachain(_), GeneralKey{length: 8, data: [1u8, 32]}, GeneralKey {length:8, data: [2u8, 32]})) => {
// TODO: check if the asset is native or foreign, and deposit the asset to a tmp account first
// TODO: call deposit() extrisic in sygmaBrdige pallet
// check if the asset is native or foreign, and deposit the asset to a tmp account first
let tmp_account = MultiLocation::new(0, X1(GeneralKey {length: 8, data: [2u8; 32]})).into_account();
if AssetTypeChecker::is_native_asset(what) {
CurrencyTransactor::deposit_asset(what, &Junction::AccountId32 { network: None, id: tmp_account }.into(), context)?;
} else {
FungiblesTransactor::deposit_asset(what, &Junction::AccountId32 { network: None, id: tmp_account }.into(), context)?
}

// TODO: call deposit() extrisic in sygmaBrdige pallet. Sygma bridge pallet should also be in the PhantomData type
Forwarder::other_world_transactor_forwarder()
}
// Other destination multilocation not supported, return Err
_ => {
Expand Down
12 changes: 12 additions & 0 deletions traits/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,15 @@ pub trait DecimalConverter {
/// Sygma relayer will always send asset in 18 decimal
fn convert_from(asset: &MultiAsset) -> Option<MultiAsset>;
}

// TODO: implement this method for local mock and standalone use
// when integrating with parachain, parachain team can implement their own version
pub trait AssetTypeIdentifier {
fn is_native_asset(asset: &MultiAsset) -> bool;
}

// TODO: implement these methods
pub trait TransactorForwarder {
fn xcm_transactor_forwarder();
fn other_world_transactor_forwarder();
}

0 comments on commit 3044a0e

Please sign in to comment.