From 3044a0e043a6dcf247aa5beaba5bfde4ccd75b10 Mon Sep 17 00:00:00 2001 From: Freddyli7 Date: Fri, 3 Nov 2023 12:17:21 -0400 Subject: [PATCH] add generic type for XCM asset transactor with forwarder traits --- bridge/src/xcm_asset_transactor.rs | 42 +++++++++++++++++++++++------- traits/src/lib.rs | 12 +++++++++ 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/bridge/src/xcm_asset_transactor.rs b/bridge/src/xcm_asset_transactor.rs index db8fcb0..e0ed4d3 100644 --- a/bridge/src/xcm_asset_transactor.rs +++ b/bridge/src/xcm_asset_transactor.rs @@ -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(PhantomData<(CurrencyTransactor, FungiblesTransactor, AssetTypeChecker, Forwarder)>); -impl TransactAsset for XCMAssetTransactor{ +impl TransactAsset for XCMAssetTransactor { // 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 @@ -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 _ => { diff --git a/traits/src/lib.rs b/traits/src/lib.rs index 60ea32c..af38090 100644 --- a/traits/src/lib.rs +++ b/traits/src/lib.rs @@ -61,3 +61,15 @@ pub trait DecimalConverter { /// Sygma relayer will always send asset in 18 decimal fn convert_from(asset: &MultiAsset) -> Option; } + +// 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(); +}